React Native Maps onMapReady getMapBoundaries - react-native

I haven't been able to find anything to fix it. I'm using react-native maps
const finalMap = () => {
return(
<SafeAreaView style={styles.authContainerStyles}>
<MapView
style={styles.map}
provider={PROVIDER_GOOGLE}
region={{
latitude: !!userLocation ? userLocation.coords.latitude : 43.60271848664041,
longitude: !!userLocation
? userLocation.coords.longitude
: -116.20149258821509,
latitudeDelta: 0.05,
longitudeDelta: 0.05,
}}
onMapReady = {this.map.getMapBoundaries()}
>

Try the below code or run this Snack here: https://snack.expo.io/Cu5qYmcZm
function Map() {
const [mapRef, updateMapRef] = useState(null);
const getBoundaries = () => {
if (mapRef === null) {
return;
}
mapRef
.getMapBoundaries()
.then((res) => {
console.log(res);
})
.catch((err) => console.log(err));
};
return (
<View>
<MapView
ref={(ref) => updateMapRef(ref)}
onMapReady={() => getBoundaries()}
/>
</View>
);
}
You need to store the ref to the map, so you can refer back to it later (when you check the boundaries). You could also store this in the state. Then after the map is ready, the event is fired and using the ref we can refer back to it and query the info about the boundaries.

Related

How to optimize react native maps performance when using animated marker

I'm trying to optimize react-native-maps perfomance.
This is my customized Marker
export function usePrevious(value) {
const ref = React.useRef();
React.useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
function VehicleMarker({CarSetting, car, onOpen}) {
const [marker, setMarker] = useState(null);
const [CarIcon, setCarIcon] = useState(Car);
const [coordinate] = useState(
new AnimatedRegion({
latitude: car.Lt,
longitude: car.Ln,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}),
);
const [CarType, setCarType] = useState(0);
const [tracksViewChanges, setTracksViewChanges] = useState(false);
const prevCoordinate = usePrevious(coordinate);
useEffect(() => {
if (prevCoordinate !== coordinate) {
setTracksViewChanges(true);
} else {
setTracksViewChanges(false);
}
}, [coordinate]);
useEffect(() => {
animateMarker();
setCarIcon(getCarImage(CarSetting, car));
setCarType(
CarSetting?.find(setting => setting.CarID == car.CarID)?.CarTypeID,
);
}, [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, 5000);
}
} else {
coordinate.timing(newCoordinate).start();
}
};
return (
<Marker.Animated
key={car.CarID}
ref={marker => {
setMarker(marker);
}}
coordinate={coordinate}
onPress={onOpen}
anchor={{x: 0.5, y: 0.5}}
rotation={CarType == 0 ? 360 - car.Angle : 0}
tracksViewChanges={tracksViewChanges}>
<Animated.View style={styles.markerWrap}>
<Animated.Image source={CarIcon} style={styles.marker} />
</Animated.View>
</Marker.Animated>
);
}
I have about 80 vehicles, and half of them are always on the go, I update their coordinate every 15s . And each vehicle have a marker is plates number ( because I don't want it rotates so I clone it into an other component ).
It run smooth with under 30vehicle. But more than 30 it becomes laggy. I can't cluster them because our customer wants to see all of them.
Have any solutions for it?
my solution is reducing the resolution of the image ( to the size I want, in my case is 30x30 px ) and use icon istead of image.
<Marker.Animated
ref={marker => {
setVehicle(marker);
}}
coordinate={coordinate}
onPress={onOpen}
anchor={{x: 0.5, y: 0.5}}
rotation={CarType == 0 ? 360 - car.Angle : 0}
tracksViewChanges={tracksViewChanges}
icon={CarIcon}>
{/* <Animated.View style={styles.markerWrap}>
<Animated.Image source={CarIcon} style={styles.marker} />
</Animated.View> */}
</Marker.Animated>

How to get animateCamera to work in a functional React Native component?

Having some issues with the animateCamera function. I did succeed to get it moving, but it seems to ignore the 'zoom', as well as the 'duration' settings...
const _map = useRef(null);
useEffect(() => {
if (_map.current) {
//prettier-ignore
const newCamera = {center: {...marker}, zoom: 88};
_map.current.animateCamera(newCamera, { duration: 7000 });
}
console.log("type check", typeof marker.longitude);
}, [count]);
//
return (
<View style={styles.container}>
<MapView
style={styles.map}
ref={_map}
region={{
...marker,
latitudeDelta: 0.02663,
longitudeDelta: 0.02001,
}}
camera={{ ...marker, zoom: 17 }}
```

How do you use getMapBoundaries with React Naitve Maps

Currently creating an application for a company. The user of the application is displayed on the map, and their pets are supposed to display on the map as well. In order to do that I need the boundaries of the map. I am using react-native-maps and it as a built function getMapBoundaries. When I use the function I have gotten the following errors
function getMapBoundaries does not exist
And the latest
Cannot set property map of undefined.
Here is what I have
const AppMapView = () => {
const handleRegionChange = async region => {
//I get an error for the statement below
console.log(
await this.map.getMapBoundaries()
.then(response => {
return response
})
)
};
handleRegionChange()
return (
<View style={styles.container}>
<MapView
ref={ref => {
this.map = ref;
}}
>
<Marker
coordinate={...}
>
<Image {...} />
</Marker>
</MapView>
</View>
)
};
export default AppMapView;
A code example would be much appreciated.
If anyone is still searching for the answer, this works:
<MapView
ref={mapView}
onRegionChangeComplete={async (val) => {
console.log(await mapRef.current.getMapBoundaries())
}
>
<Marker
coordinate={...}
>
</Marker>
</MapView>
You can get it from current of the ref
This code works for me:
mapRef = null;
onRegionChangeComplete = async () => {
console.log("onRegionChangeComplete", await this.mapRef.getMapBoundaries());
};
<MapView
ref={(ref) => {
this.mapRef = ref;
}}
onRegionChangeComplete={this.onRegionChangeComplete}
<Marker
coordinate={...}
>
</Marker>
</MapView>

React Native Maps not rerendering Markers on iOS

I am using react native maps for displaying a map in my application, and this map should display markers that are fetched from a database online. When the map is mounted, and after fetching the marker data location points, I am updating a state containing the array of marker points, however, the markers do not get rendered after setting the state. Is there any work around in this? Here's a sample code:
P.S. This only occurs in iOS.
const [markerPoints, setMarkerPoints] = useState([])
useEffect(() => {
getMarkerPoints()
}, [])
const getMarkerPoints = callback => {
axios
.get(
'some end point',
)
.then(res => {
if (res.status === 200) {
setMarkerPoints(res.data.results)
}
})
.catch(error => {
console.log(error)
})
}
const renderMarkers = () => {
return markerPoints.map((place, index) => {
return (
<Marker
key={index}
coordinate={{
latitude: place.geometry.location.lat,
longitude: place.geometry.location.lng,
}}
/>
)
}
}
return (
<MapView
ref={map}
provider={PROVIDER_GOOGLE}
style={styles.map}
region={curRegion}
showsUserLocation={true}
showsMyLocationButton={false}
onRegionChangeComplete={onMapRegionChangeComplete}
customMapStyle={mapStyles}
>
{renderMarkers()}
</MapView>
)

Remove marker from google map in react native

Is possible to remove marker from map view? How to remove marker from google map view. I using "react-native-maps" display google map.
Please Help.
To be able to remove or add markers, you just need to do this
//Note : my map markers is => this.props.markers
componentDidMount() {
this.renderMarkers(this.props.markers)
}
async renderMarkers(mapMarkers) {
let markers = [];
markers = mapMarkers.map(marker => (<Marker
key={marker.code}
coordinate={{latitude: marker.lat, longitude: marker.lng}}
onPress={{}}
/>)
);
this.setState({markers});
}
refreshMarkers() {
this.renderMarkers(this.props.markers).then(() => {
this.forceUpdate();
});
}
render() {
return (
<MapView
ref={(ref) => this.mapView = ref}
style={styles.map}
region={this.props.coordinate}
>
{this.state.markers}
</MapView>
);
}
Here's how I do it.
Essentially, you need to keep an array of markers in the state, then remove the marker you want to delete from the state.
I store the list of markers in the state like so:
this.state = {
markers: [],
};
When you actually create the markers, you pass the index in the function that will remove the marker from the state. In this case onMarkerPress(index)
createMarkers() {
return this.state.markers.map((marker, index) => (
<Marker
draggable
onPress={event => this.onMarkerPress(index)}
key={index}
coordinate={{
latitude: parseFloat(marker.latitude),
longitude: parseFloat(marker.longitude),
}}
/>
));
}
Here's the onMarkerPress function:
onMarkerPress(index) {
this.state.markers.splice(index, 1);
this.setState({markers: this.state.markers});
}
And finally, you map component will look like this:
<MapView
style={styles.map}
mapType={'satellite'}
provider={PROVIDER_GOOGLE}
initialRegion={{
latitude: 45.50235905860018,
longitude: -73.60357092645054,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
onLongPress={e => this.addNewMarker(e)}>
{this.createMarkers()}
</MapView>
And that's it!