MapView.Polyline not working in react-native-web-maps - react-native

In my Android app it drawing the polyline but it not functioning in Web. I could not found any example even in that storybook. but In docs mentioned that it supports polyline.
MyCode
<MapView
provider={this.props.provider}
style={styles.map}
initialRegion={this.state.region}
onPress={e => this.onMapPress(e)}
onLayout={()=>console.log('map on layout')}
ref={(ref) => { this.mapRef = ref }}
onRegionChange={this.onRegionChange}
>
<MapView.Marker
coordinate={
{
latitude: 17.43745,
longitude: 78.48229
}
}
title={'pickup Location'}
/>
<MapView.Marker
coordinate={
{
latitude: 17.4049696,
longitude: 78.4043356
}
}
title={'pickup Location'}
pinColor="green"
/>
<MapView.Polyline coordinates={this.dummyCoords} strokeWidth={2} strokeColor={'rgba(r,g,b,0.5)'} fillColor={'rgba(r,g,b,0.5)'}/>
</MapView>
Can anyone can share example, I'm stuck.

Related

How to make the Marker move smoothly in react-native-maps?

I have an API to get cars's position in react-native-maps.
[
{
"Message": "OK",
"NumberPlate": "*****",
"DeviceID": "60000660",
"DriverName": "",
"DriverLicense": "",
"Date": "08:10:00 - 10/01/2022",
"Lt": "latitude",
"Ln": "longitude",
"Address": "***, ***, ***",
"Angle": 285,
"CarStatus": "parking",
"Speed": 0,
"Acc": "off",
"Oil": 323
},
.....
]
To prevent the server from crashing, I only get data every 15 seconds. And as we all know, my cars will "jump" in maps.
So is there a way to make them move smoothly?
For example they will move straight between 2 points in 15s.
This is my <MapView />
<MapView
ref={mapRef}
style={{width: '100%', height: '100%'}}
initialRegion={{
latitude: mapState.lat,
longitude: mapState.long,
latitudeDelta: 0.01,
longitudeDelta: 0.01,
}}
onPress={() => {
menuRef.current.snapTo(1);
vehiclesRef.current.snapTo(2);
}}
showsUserLocation={true}
showsTraffic={false}
showsMyLocationButton={true}
zoomEnabled={true}>
{CarInfo.map(car => {
return (
<Marker
key={car.DeviceID}
coordinate={{
latitude: car.Lt,
longitude: car.Ln,
}}
onPress={() => vehiclesRef.current.snapTo(1)}>
<Animated.View style={[styles.markerWrap]}>
<Text style={styles.numberPlate} numberOfLines={1}>
{car.NumberPlate}
</Text>
<Animated.Image
source={Car}
style={styles.marker}
resizeMode="cover"
/>
</Animated.View>
</Marker>
);
})}
</MapView>
If you use react-native-maps Marker, you can see this and follow him. It works. If you want show multiple marker and want them move smoothly, you should custom a child component and use I in return(). this is my code:
export default function CarMarker({car, onOpen}) {
const [marker, setMarker] = useState(null);
const [coordinate, setCoordinate] = useState(
new AnimatedRegion({
latitude: car.Lt || INITIAL_LAT,
longitude: car.Ln || INITIAL_LONG,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}),
);
useEffect(() => {
animateMarker();
}, [car]);
const animateMarker = () => {
const newCoordinate = {
latitude: car.Lt,
longitude: car.Ln,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
};
if (Platform.OS === 'android') {
if (marker) {
marker.animateMarkerToCoordinate(newCoordinate, 15000);
}
} else {
coordinate.timing(newCoordinate).start();
}
};
return (
<Marker.Animated
key={car.DeviceID}
ref={marker => {
setMarker(marker);
}}
coordinate={coordinate}
anchor={{x: 0.5, y: 0.5}}
onPress={onOpen}>
<Animated.View style={styles.markerWrap}>
<Text style={styles.numberPlate} numberOfLines={1}>
{car.NumberPlate}
</Text>
<Animated.Image source={Car} style={styles.marker} resizeMode="cover" />
</Animated.View>
</Marker.Animated>
);
}
and this is my <MapView/>
<MapView
ref={mapRef}
style={{width: '100%', height: '100%'}}
initialRegion={{
latitude: mapState.lat,
longitude: mapState.long,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}}
onPress={() => {
menuRef.current.snapTo(1);
vehiclesRef.current.snapTo(2);
}}
showsUserLocation={true}
showsTraffic={false}
showsMyLocationButton={true}
zoomEnabled={true}>
{CarInfo.map(car => {
return (
<CarMarker
key={car.DeviceID}
car={car}
onOpen={() => {
vehiclesRef.current.snapTo(1);
setSelectedVehicle(car);
}}
/>
);
})}
</MapView>

React Native: Marker working statically but not dynamically

I'm trying to showing multiple marker in React Native Mapview. My code
this.state = {
coords: [
{ latitude: 23.759119, longitude: 90.411804 },
{ latitude: 23.759188, longitude: 90.41167 },
{ latitude: 23.759127, longitude: 90.41138 },
{ latitude: 23.759224, longitude: 90.411995 },
{ latitude: 23.7591, longitude: 90.41138 }
]}
It's working when code like as
<Marker coordinate={this.state.coords[0]} />
<Marker coordinate={this.state.coords[1]} />
<Marker coordinate={this.state.coords[2]} />
<Marker coordinate={this.state.coords[3]} />
<Marker coordinate={this.state.coords[4]} />
But not working when code like as
{this.state.coords.map((c, index) => {
<Marker key={index} coordinate={c} />;
})}
I didn't get any error. Also not understood why not working the codes. Anyone can help me?
I got the solution. I've not returning anything. So modify the code like
{this.state.coords.map((c, index) => {
return <Marker key={index} coordinate={c} />;
})}

React native initial region not updating with state

I have below code base
componentDidMount() {
//firebase.firestore().collection('locations').doc('test').set({ test: 'test' })
Geolocation.getCurrentPosition(
(position) => {
if (position) {
this.setState({
region: {
latitude: Number(position.coords.latitude),
longitude: Number(position.coords.longitude),
latitudeDelta: 0.003,
longitudeDelta: 0.003,
},
});
}
alert(JSON.stringify(this.state.region))
},
(error) => alert(JSON.stringify(error)),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000, distanceFilter: 100 }
);
this.unsubscribe = this.locationRef.onSnapshot(this.getCollectionData);
// firebase.firestore().collection("locations").get().then(QuerySnapshot => { });
}
And Map
render() {
return (<View style={{
flex: 1,
flexDirection: 'column',
}}>
<HeaderNavigationBar {...this.props} />
<MapView showsUserLocation={true}
// ref={map => this.map = map}
initialRegion={this.state.region}
style={styles.container}
>
{this.state.AllLocations.map((marker, index) => (
<MapView.Marker key={index}
coordinate={marker.locations.coords}
title={marker.Title}
/>
))}
</MapView>
</View>);
}
componentDidMount is correcty updating the state, but map is not showing correct position,it is taking as it was set in construction
constructor(props) {
super(props);
this.locationRef = firebase.firestore().collection('locations');
this.unsubscribe = null;
this.state = {
isLoading: true,
AllLocations: [],
region: {
latitude: 0,
longitude: 0,
latitudeDelta: 0.003,
longitudeDelta: 0.003,
}
};
}
Please help
thanks
initialRegion is used for the initial render of map.
In your case, You are getting the user location after your map render, Thats the reason its not getting updated.
To counter this there are two ways.
1: use a loading state till you get your use location, and prevent the map render before you get the location.
2: Use region, for example region = {this.state.region}.
<MapView showsUserLocation={true}
// ref={map => this.map = map}
initialRegion={this.state.region}
region={this.state.region}
style={styles.container}
>
{this.state.AllLocations.map((marker, index) => (
<MapView.Marker key={index}
coordinate={marker.locations.coords}
title={marker.Title}
/>
))}
</MapView>
Both will work, it depends on your usecase.
Try this
{this.state.region ? (<MapView
style={[styles.map]}
initialRegion={this.state.region}
region={this.state.region}
provider={PROVIDER_GOOGLE}
>
{this.state.AllLocations.map((marker, index) => (
<MapView.Marker key={index}
coordinate={marker.locations.coords}
title={marker.Title}
/>
))}
</MapView>) : (
<MapView
loadingEnabled={true}
style={styles.map}
showsMyLocationButton={true}
provider={PROVIDER_GOOGLE}
style={[styles.map]}
>
</MapView>
)
}
Set region: null in the constructor it will work

Is it possible to change MapView Market pinColor programatically by clicking any button?

I have implemented a MapView with react-native-maps. I'm trying to change Marker's pinColor by clicking on it.
Note: I have large amounts of markers. So I don't think refreshing all view can be a good solution. I need directly change the selected marker's color.
I didn't find how to do it. I tried below code:
class TestMap extends React.Component {
constructor(props) {
this.state = {
testColor: "#FFFFFF",
userLatitude:0,
userLongitude:0,
data:[]
}
}
render() {
return (
<MapView
provider={PROVIDER_GOOGLE}
showsTraffic={true}
showsBuildings={true}
toolbarEnabled={true}
loadingEnabled={true}
style={styles.map}
initialRegion={{
latitude: this.state.userLatitude,
longitude: this.state.userLongitude,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA
}}
onPoiClick={this.onPoiClick}
showsUserLocation={true}
followsUserLocation={true}
showsMyLocationButton={true}
loadingBackgroundColor="#FEA405"
loadingIndicatorColor="white"
onLongPress={e => this.onMapPress(e)}
enableZoomControl
>
{this.ListMarkers()}
</MapView>
)};
ListMarkers() {
return this.state.data.map((data, i) => {
return (
<Marker
key={i}
onPress={e => this.onPressMarker(e, i, data)}
coordinate={{
longitude: data.LONGITUDE,
latitude: data.LATITUDE
}}
pinColor={this.state.testColor}
/>
)}
)};
onPressMarker(e, index, data) {
this.setState({testColor:"#000000"});
}
}
I expect the color of marker should change after clicking on it but it is not working.
Thanks for your help.
You can set the selected pin in the state and use a different style in that case, if you have some id in your data you can use that value instead of the index:
constructor(props) {
this.state = {
selectedPin: -1,
}
}
ListMarkers = () => {
return this.state.data.map((data, i) => {
return (
<Marker
key={i}
onPress={e => this.onPressMarker(e, i, data)}
coordinate={{
longitude: data.LONGITUDE,
latitude: data.LATITUDE
}}
pinColor={ i === this.state.selectedPin ? '#FF0000' : '#FFFFFF'}
/>
)}
)};
onPressMarker = (e, index, data)=> {
this.setState({selectedPin:index});
}

How to use animateToRegion function in react native maps?

I am using MapView of react-native map clustering and Marker and callout of react-native-maps. I am unable to use animateToRegion.
It shows me this.mapView.animateToRegion is not a function
<MapView
ref={map=>{mapView = map}}
provider='google'
clustering={true}
onClusterPress={this.onPressCluster}
region={this.state.region}
onRegionChange={this.onRegionChange}
onRegionChangeComplete={this.onRegionChangeComplete}
style={styles.map}
showsUserLocation={true}
followUserLocation={true}
zoomEnabled={true}
ScrollEnabled={true}
showsBuildings={true}
showsMyLocationButton={false}/>
animate(){
let r = {
latitude: 42.5,
longitude: 15.2,
latitudeDelta: 7.5,
longitudeDelta: 7.5,
};
this.mapView.root.animateToRegion(r, 2000);
}
render(){
return(
<MapView
ref = {(ref)=>this.mapView=ref}
region={{
latitude: 35.688442,
longitude: 51.403753,
latitudeDelta: 0.5,
longitudeDelta: 0.5,
}}
onPress={()=>this.animate()}
>
...markers...
</MapView>
);
}
clickOnSearchedAddress = (placeId, index, dscrpt) => {
getLatLongFromAddress(placeId).then((response) => {
let r = {
[Constants.KEY_LATITUDE]: response.geometry.location.lat,
[Constants.KEY_LONGITUDE]: response.geometry.location.lng,
latitudeDelta: latitudeDelta,
longitudeDelta: longitudeDelta
}
this.mapView.animateToRegion(r, 1000)
Keyboard.dismiss()
isSetTextProgramatically = true;
this.setState({
search: dscrpt,
searchData: [],
})
}).then((error) => { })
}
<MapView
ref={ref => this.mapView = ref}
provider={PROVIDER_GOOGLE}
style={[styles.map, , { width: this.state.width }]}
initialRegion={region}
onRegionChangeComplete={this.onRegionChange}
showsMyLocationButton={true}
showsCompass={true}
showsUserLocation={true}
onMapReady={() => this.setState({ width: width - 1 })}}
/>
I believe the issue is that the prop is not called ref, but instead mapRef. Pass the ref in there, and it should work.
You would then also have to call it with something like this this.mapView.[current/map]animateToRegion. Just check the mapView object you get.