'react-native-maps' become extremelly slow after some time - react-native

I have a MainPage where runs a MapView from 'react-native-maps'.
It works like a Uber app, the user receves a solicitation and the maps updates with the route. But after some time the map becomes extremelly slow in animations and i dont know why,
this is the code I'm using at the moment.
<MapView
ref={mapRef}
style={styles.mapView}
onMapReady={() => initInfo()}
moveOnMarkerPress={false}
showsTraffic={false}
showsIndoors={false}
showsUserLocation={true}
userLocationPriority="balanced"
followsUserLocation={true}
showsMyLocationButton={false}
showsCompass={false}
region={{
latitude: LocationRef.current.latitude,
longitude: LocationRef.current.longitude,
latitudeDelta: 0,
longitudeDelta: 0.02,
}}
customMapStyle={mapStyle}
>
{MarkersRef.current.length >= 1 ? (
MarkersRef.current.map((marker, index) => {
return (
<Marker
key={index}
coordinate={marker}
title={TitleMarkersRef.current[index]}
>
<Icons name='map-marker' color='#005042' size={25} />
</Marker>
)
})
)
:
null
}
{
(WaypointsToRouteRef.current.length > 2 ? (
<Polyline
coordinates={WaypointsToRouteRef.current}
strokeWidth={4}
strokeColor='#f2ae30' />
) : null)
}
</MapView>

Related

How to display overlay when React Native Map Marker On Pressing

I want to display overlay component when pressing the map marker. When pressing the button, overlay is showing fine. But when pressing the marker, it is not showing. Can someone let me know about how to display overlay when pressing the map marker.
Here is the code.
const toggleOverlay = () => {
setVisible(!visible);
};
return(
<View style={styles.container}>
<MapView style={styles.map}
showsUserLocation={true}
followUserLocation={true}
zoomEnabled={true}
showsMyLocationButton={true}
initialRegion={ mapRegion}
provider = {PROVIDER_GOOGLE}
showsTraffic={true}
>
{
locationPoints? locationPoints.map((point) => (
<Marker
coordinate={{
longitude: parseFloat(point.PointLongitude),
latitude: parseFloat(point.PointLatitude)
}}
title= {point.name}
pinColor={'blue'}
**onPress={() => (toggleOverlay)}**
>
</Marker>
))
: null}
</MapView>
<Button title="Confirm Address"
**onPress={toggleOverlay}** />
<Overlay isVisible={visible} onBackdropPress={toggleOverlay}>
<Text>Your Address</Text>
<View>
<Text>Address</Text>
</View>
</Overlay>
</View>
);
try, maybe it works)
{
locationPoints? locationPoints.map((point) => (
<Marker
coordinate={{
longitude: parseFloat(point.PointLongitude),
latitude: parseFloat(point.PointLatitude)
}}
title= {point.name}
pinColor={'blue'}
onPress={toggleOverlay}
/>
))
: null
}

react native with EXPO MapView.Marker Image not take the exact positon and very slow

I'm trying to display markers with customs icons and images on my MapView.
The problem is that icon and images not showing in the exact coordinate and change on zoom in zoom out. And the second problem is that the MapView becomes very heavy and lag too after drawing of +150 markers.
You can look for some pictures of problem here:
zoom out
zoom in
<MapView style={styles.map}
provider={PROVIDER_GOOGLE}
customMapStyle={mapDarkStyle}
mapType={maptype}
ref={map}
showsCompass={false}
initialRegion={{
latitude: 31.791702,
longitude: -7.09262,
latitudeDelta: 18,
longitudeDelta: 18
}}
>
{ vehicles != null ? vehicles.map(v =><Marker.Animated key={v.id}
coordinate={{
latitude: v.lat,
longitude: v.lng,
}}
tracksViewChanges={false}
ref={(marker)=>v.marker = marker}
onPress={() => {
console.log("marker clicked !");
map?.current?.getCamera().then((cam: Camera) => {
cam.zoom += 14;
cam.center.latitude = v.lat;
cam.center.longitude = v.lng;
map?.current?.animateCamera(cam);
console.log("hollo");
});
}}
>
<View>
{
(v.engine == 0) ?
<OnStop width="25"
height="25" /> : (v.speed == 0) ? <OnPause width="25"
height="25" />
:(v.speed >90) ? <Icon2 name="direction" size={35} color="#dd4f43" style={{textAlign:"center"}} /> :
(v.speed>60) ? <Icon2 name="direction" size={35} style={{textAlign:"center"}} color="#ffcd41" />
: <Icon2 name="direction" size={35} style={{textAlign:"center"}} color="#18a15f" />
}
</View>
</Marker.Animated>
):<View/>
}
</MapView>

latlng cannot be null, a position is required. ReactNative

I'm trying to add markers to my map. I want to have all the location data on a separate file so I'm trying to extract the coordinates from my data.json file. The latlng coordinates are in an array in the json file. Am I using the position attribute incorrectly?
render() {
return (
<View style={styles.container}>
<DestinationButton />
<CurrentLocationButton
cb={() => {
this.centerMap();
}}
/>
<MapView
initialRegion={this.state.region}
showsUserLocation={true}
showsCompass={true}
rotateEnabled={false}
ref={(map) => {
this.map = map;
}}
style={{ flex: 1, zIndex: 0 }}
>
{data.features.map((tc) => (
<Marker
key={tc.properties.NAME}
position={{
lat: tc.geometry.coordinates[1],
lng: tc.geometry.coordinates[0],
}}
/>
))}
</MapView>
</View>
);
}
Seems like you are giving a wrong prop to <Marker/> it should be coordinate instead of position. As per docs: https://github.com/react-native-maps/react-native-maps#rendering-a-list-of-markers-on-a-map
<Marker
key={tc.properties.NAME}
coordinate={{
latitude: tc.geometry.coordinates[1],
longitude: tc.geometry.coordinates[0],
}}
/>

Polyline is not rendering on maps while live reload is enabled

I am using react-native-map package to draw a polyline using coordinates i am receiving in API call. Line is being drawn when HOT reload is enabled on expo but not when LIVE reload is enabled.
I have converted all coordinates to array of objects in following template.
[{latitude:33.00, longitude:-74.00},{latitude:33.10, longitude:-74.02}]
And passed this array to coordinates in MapView.Polyline.
This how i am rendering MapView
<MapView
showsUserLocation
followsUserLocation
style={{ flex: 1 }}
initialRegion={{
latitude: 31.5623499,
longitude: 74.3287183,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}>
{this.state.allPlants.map((item, index) => {
return <MapView.Marker
key={item.id.toString()}
coordinate={{
latitude: item.latitude,
longitude: item.longitude,
}}>
<Image source={item.isDead?require("../../assets/dead_tree.png"):require("../../assets/tree.png")} key={item.id.toString()} /> </MapView.Marker>
})}
<MapView.Polyline
coordinates={this.allCoords}
strokeWidth={6}
strokeColor="red"
fillColor="rgba(100,0,0,0.5)"
/>
</MapView>
And this is how i am creating array of coordinates objects
let tmpArray=[]
if(tmp.length!==0){
for(let i=0; i<tmp.length;i++){
let tmpObj={
latitude:tmp[i].latitude,
longitude:tmp[i].longitude
}
tmpArray.push( tmpObj)
}
}
this.allCoords=tmpArray
It should be able to show polyline as it is already showing on HOT reloading, i don't understand if that is the expected behavior or this is some bug.
I wrapped MapView code into following
<View style={{ flex: 1 }}>
{this.state.isDataFetched && (
<MapView
showsUserLocation
followsUserLocation
style={{ flex: 1 }}
initialRegion={{
latitude: 31.5623499,
longitude: 74.3287183,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}>
{this.state.allPlants.map((item, index) => {
return <MapView.Marker
key={item.id.toString()}
coordinate={{
latitude: item.latitude,
longitude: item.longitude,
}}>
<Image source={item.isDead?require("../../assets/dead_tree.png"):require("../../assets/tree.png")} key={item.id.toString()} /> </MapView.Marker>
})}
<MapView.Polyline
coordinates={this.allCoords}
strokeWidth={6}
strokeColor="red"
fillColor="rgba(100,0,0,0.5)"
/>
</MapView>
)}
</View>
And used this.state.isDataFetched as a flag to condition rendering and it worked as expected.

react native maps marker custom image cannot change from default

I've spent about 5 hours trying to get this to work with many different permutations of code, and then rebuilding. I cannot for the life of me change the default "red pointer" marker as the default marker image in react native maps.
import MapView, { PROVIDER_GOOGLE } from 'react-native-maps';
...
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
ref={ref => {this.map = ref;}}
minZoomLevel={4} // default => 0
maxZoomLevel={10} // default => 20
enableZoomControl={true}
showsUserLocation = {true}
showsMyLocationButton = {true}
zoomEnabled = {true}
initialRegion={{
latitude: 37.600425,
longitude: -122.385861,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}}
>
<MapView.Marker
coordinate={marker.location}
image={require('./images/test.png')} <------ HERE
width={48}
height={48}
/>
</MapView>
The images definitely exist in the right folder, I've tried different image formats png/gif/jpg/svg, I've tried using {{uri:...}} and icon/image, adding and removing width/height attributes. Nothing seems to work. I'm always getting the default red pointer.
Have I missed something obvious?
The project packager/compiler fails when I require an image that doesn't exist, or an unsupported type. It definitely can see the image, but just doesn't do anything with it. Same results on the emulator and on actual device.
image={require('./images/test.png')}
This line just does nothing, as if it's being ignored somehow.
<MapView
provider={PROVIDER_GOOGLE}
style={styles.container}
region={{
latitude: this.state.latitude,
longitude: this.state.longitude,
}}
>
<Marker
coordinate={{
latitude: this.state.latitude,
longitude: this.state.longitude,
}}
description={"This is a marker in React Natve"}
>
<Image source={require('./man_marker.png')} style={{height: 35, width:35 }} />
</Marker>
</MapView>
There are two solutions:
The first solution (recommended)
Resize your marker image with image editor(such as Photoshop,....) and use as icon in marker
To do this, you can make three photos of different sizes (YOUR_MARKER.png , YOUR_MARKER#2x.png , YOUR_MARKER#3x.png) (React Native automatically displays the appropriate item).
This is a good solution if you have a large number of markers.(You can refer here to clarify this)
<Marker
coordinate={ ... }
tracksViewChanges={false}
icon={require('./YOUR_MARKER.png')}
/>
The second solution
As #shubham-raitka said you can use the Image inside the marker
<Marker
coordinate={ ... }
>
<Image source={require('./YOUR_MARKER.png')} style={{height: 35, width:35 }} />
</Marker>
In this case, if your number of markers is high (about 50 or more) the map performance will be very low.Therefore, it is not recommended to use this method
Here's an approach that worked for me in a similar situation: Use Image in place of Marker. Pop-ups work the same as with a marker. If you try this, Image is imported from react-native. The actual image is imported as:
var dotImage = require('./pathToImage.png')
<Marker
coordinate={meter.latlng}
title={"Parking Meter"}
key={idx}
>
<Image
source={dotImage}
style={{height: 6, width: 6}}
/>
</Marker>
The way you give the width and height is a bit strange, please try with this way.
import MapView, { Marker, PROVIDER_GOOGLE } from 'react-native-maps';
const markerImg = require('./images/test.png'); // <-- create a const with the path of the image
<------
------>
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
ref={ref => {this.map = ref;}}
minZoomLevel={4} // default => 0
maxZoomLevel={10} // default => 20
enableZoomControl={true}
showsUserLocation = {true}
showsMyLocationButton = {true}
zoomEnabled = {true}
initialRegion={{
latitude: 37.600425,
longitude: -122.385861,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}}
>
<Marker
image={markerImg} // <----- add this the const with image
onPress={() => this.setState({ marker1: !this.state.marker1 })}
coordinate={{
latitude: 37.600425,
longitude: -122.385861,
}}
centerOffset={{ x: -18, y: -60 }}
anchor={{ x: 0.69, y: 1 }}
/>
</Marker>
</MapView>
I hope it works for you, works for me!
Not enough rep yet to just leave a comment, but the first solution works, I just had to add resizeMode or it cuts off the image if it's bigger.
<Marker
coordinate={ ... }
>
<Image source={require('./YOUR_MARKER.png')} style={{height: 35, width:35, resizeMode:"contain" }} />
</Marker>
<Marker
coordinate={d.driverLocation}
title={d.driverName}
description={d.autoNumber}
onPress={() => console.warn(d.mobaNumbers)}
image={require("../../../assets/bee.png")}
>
</Marker>
Try this it should work
import {Image} from 'react-native';
import MapView, {Marker} from 'react-native-maps';
<MapView
style={styles.mapStyle}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
customMapStyle={mapStyle}>
<Marker
draggable
coordinate={{
latitude: 37.78825,
longitude: -122.4324,
}}
onDragEnd={e => alert(JSON.stringify(e.nativeEvent.coordinate))}
title={'Test Marker'}
description={'This is a description of the marker'}>
<Image
source={require('./assests/custom_marker.png')}
style={{height: 35, width: 35}}
/>
</Marker>
</MapView>