Reputation: 1008
I am trying to create a Swiggy/Zomato/FoodPanda like the app, I am trying to get user location or set delivery location on to the map.
The issue is happening on Android.
But I am not experiencing a smoothness when moving marker position, especially when zooming in and zooming out.
Map glitches when trying to move pin marker position
please suggest me for improvement and for to get smoothness experience.
I am trying a lot of logic but not getting any desired performance.
Here is my implemented code,
This is my initial setup on constructor
constructor(props) {
super(props);
this.latDelta = 0.00922 * 1.5;
this.longDelta = 0.00421 * 1.5;
this.state = {
visible: false,
address: {},
lastLat: 24.8076793,
lastLong: 93.9360916,
mapRegion: new AnimatedRegion({
latitude: 24.8076793,
longitude: 93.9360916,
latitudeDelta: this.latDelta,
longitudeDelta: this.longDelta
}),
marker: null,
region: new AnimatedRegion({
latitudeDelta: this.latDelta,
longitudeDelta: this.longDelta,
latitude: 24.8076793,
longitude: 93.9360916
}),
autoGeoMarker: {
latitude: 24.8076793,
longitude: 93.9360916,
autoMapAddress: '',
autoMapArea: ''
},
setGeoMarker: {
latitude: 24.8076793,
longitude: 93.9360916,
setMapAddress: '',
setMapArea: ''
},
mapIndicator: false,
mapAddress: '',
mapArea: '',
//-----
indicator: true,
searchModal: false
};
}
componentDidMount() {
this.getPermissionLocation();
}
Here I am asking for permission
getPermissionLocation = () => {
try {
request(
Platform.select({
android: PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
ios: PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
})
).then(res => {
if (res == 'granted') {
this.setState({
searchModal: false
});
Geolocation.getCurrentPosition(
//Will give you the current location
position => {
let region = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
latitudeDelta: this.latDelta,
longitudeDelta: this.longDelta
};
Alert.alert('', 'Pin Your Delivery point by moving map');
this.setState({
autoGeoMarker: region,
mapIndicator: false,
indicator: false
});
this.onRegionChange(region);
this.getAutoDetectAddress(region.latitude, region.longitude);
},
error => {
//setLocationStatus(error.message);
console.log('error ... 1 ' + error.message);
},
{
enableHighAccuracy: false,
timeout: 30000,
maximumAge: 1000
}
);
} else {
console.log('Location is not enabled');
Alert.alert(
'Enable Your Location:',
'Can not proceed, Please allow your Location permissioin.',
[{ text: 'OK', onPress: () => RNRestart.Restart() }]
);
}
});
} catch (error) {
console.log('location set error:', error);
}
};
//Get Auto Geolocation address
getAutoDetectAddress = (latitude, longitude) => {
Geocoder.from(latitude, longitude)
.then(json => {
let region = {
latitude: latitude,
longitude: longitude,
latitudeDelta: this.latDelta,
longitudeDelta: this.longDelta,
autoMapAddress: json.results[0].formatted_address,
autoMapArea: json.results[0].address_components[1].short_name
};
this.setState({
autoGeoMarker: region
});
})
.catch(error => console.warn(error));
//-----------------------
};
onRegionChange = region => {
this.setState({
region: region,
lastLat: region.latitude,
lastLong: region.longitude
});
this.getAddressInfo(region.latitude, region.longitude);
};
getAddressInfo = (latitude, longitude) => {
Geocoder.from(latitude, longitude)
.then(json => {
this.setState({
mapAddress: json.results[0].formatted_address,
mapArea: json.results[0].address_components[1].short_name
});
let region = {
latitude: json.results[0].geometry.location.lat,
longitude: json.results[0].geometry.location.lng,
latitudeDelta: this.latDelta,
longitudeDelta: this.longDelta,
setMapAddress: json.results[0].formatted_address,
setMapArea: json.results[0].address_components[1].short_name
};
this.setState({
setGeoMarker: region
});
})
.catch(error => console.warn(error));
};
render() {
return this.state.indicator ? (
<View style={{ flex: 1 }}>
<ActivityIndicator size="large" color="#ff6a00" />
</View>
) : (
<View style={{ flex: 1, flexDirection: 'column' }}>
<StatusBar backgroundColor="#ff6a00" />
<View style={styles.map}>
<MapView
style={styles.map}
region={this.state.region}
onRegionChangeComplete={this.onRegionChange}
/>
<View
style={{
flex: 1,
flexDirection: 'row',
alignItems: 'center',
position: 'absolute',
top: '4%',
left: '-3%'
}}
>
<TouchableOpacity
onPress={() => {
{
this.props.navigation.navigate('HomeScreen');
}
}}
>
<Image
style={{ width: 71, height: 51 }}
source={require('../../assets/app/mapback.png')}
/>
</TouchableOpacity>
</View>
<View style={styles.markerFixed}>
<Image style={styles.marker} source={marker} />
</View>
</View>
<View
style={{
flex: 1,
padding: 4,
backgroundColor: '#FFFFFF'
// borderTopColor: 'black',
// borderTopWidth: 1
}}
>
<View
style={{
flex: 1,
flexDirection: 'row',
alignItems: 'center',
marginTop: 15,
marginLeft: 20
}}
>
<View
style={{ flex: 0.8, alignItems: 'center', flexDirection: 'row' }}
>
<Image
style={{ width: 15, height: 20 }}
source={require('../../assets/app/mapmark.png')}
/>
<Text
style={{
fontSize: 18,
marginLeft: 15,
fontFamily: 'Nunito-Black'
}}
>
{this.state.mapArea}
</Text>
</View>
</View>
<Text
style={{
marginTop: 20,
marginLeft: 20,
fontSize: 12,
fontFamily: 'Poppins-Regular'
}}
>
{this.state.mapAddress}
</Text>
</View>
</View>
);
}
here I have doubt where to set these two function properly
this.onRegionChange(region);
this.getAutoDetectAddress(region.latitude, region.longitude);
maybe if these two functions but I am not sure. Where to implement correctly for getting the best performance.
Upvotes: 0
Views: 1391
Reputation: 1008
Map glitches or bouncing (While pinching/zooming in and out) issue were caused by using region={this.state.region}
So, I used initialRegion={this.state.region}
instead of region
Here is the complete example
onChangeValue = region => {
this.setState({
region
});
Geocoder.from(region.latitude, region.longitude)
.then(json => {
this.setState({
mapAddress: json.results[0].formatted_address,
mapArea: json.results[0].address_components[1].short_name
});
let region = {
latitude: json.results[0].geometry.location.lat,
longitude: json.results[0].geometry.location.lng,
latitudeDelta: 0.021,
longitudeDelta: 0.021,
setMapAddress: json.results[0].formatted_address,
setMapArea: json.results[0].address_components[1].short_name
};
this.setState({
setGeoMarker: region
});
// this.map.animateToRegion(region);
})
.catch(error => console.warn(error));
};
...
<MapView
style={{
flex: 1,
height: Dimensions.get('screen').height / 1.5,
position: 'relative',
marginBottom: this.state.marginBottom
}}
showsUserLocation={true}
initialRegion={this.state.region}
// region={this.state.region}
showsMyLocationButton={true}
onRegionChangeComplete={this.onChangeValue}
ref={ref => (this.map = ref)}
/>
<View
style={{
flex: 1,
flexDirection: 'row',
alignItems: 'center',
position: 'absolute',
top: '4%',
left: '-3%'
}}
>
<TouchableOpacity
onPress={() => {
{
this.props.navigation.navigate('MainTabScreen');
this.props.navigation.navigate('HomeScreen');
}
}}
>
{/*<Icon.MaterialIcons name="arrow-back" size={28} color="black" />*/}
<Image
style={{ width: 71, height: 51 }}
source={require('../../assets/app/mapback.png')}
/>
</TouchableOpacity>
</View>
...
Upvotes: 1