In component Description I have a button, when I press the button I send to Map component coordinates of marker:
const onNavigationTap = () => {
navigation.navigate('Map', {
destination: data["data"].coordinates,
});
}
In component Map I have condition:
const mapView = React.createRef();
if (route.params){
mapView.current.animateToRegion({
latitude: route.params.destination.latitude,
longitude: route.params.destination.longitude,
latitudeDelta: 0.4,
longitudeDelta: 0.4,
},1000);
}
return (
<MapView ref={mapView} />
)
So when I open Map I want to show region near marker. I've tried to create a button on Map screen:
<TouchableOpacity style={{
position: 'absolute',
top: '5%',
alignSelf: 'flex-start'
}} onPress={animateMap}><Text>Start</Text></TouchableOpacity>
and then I created function:
const animateMap = () => {
mapView.current.animateToRegion({ // Takes a region object as parameter
latitude: destination.latitude,
longitude: destination.longitude,
latitudeDelta: 0.4,
longitudeDelta: 0.4,
},1000);
}
And this solution with button on Map screen working fine but what I want is to animateToRegion not on button press, but when user opens the Map from Description component. I don't understand why in first case I got Null is not an object(evaluating 'mapView.current.animateToRegion'). Please tell me what should I do if I want to animateToRegion using params that I get from another component?
It seems that the error you got is because mapView.current.animateToRegion is null.
You can follow this sample code and code snippet below on how to achieve your use case:
App.js
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import MapScreen from './Map'
function HomeScreen({ navigation }) {
const onBtnPress = () =>{
navigation.navigate('Maps', {
destination: { latitude: 40.463667, longitude: -3.74922 },
});
}
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={onBtnPress}
/>
</View>
);
}
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Maps" component={MapScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
Map.js
import React, { Component } from 'react';
import { Text, View, StyleSheet, Dimensions } from 'react-native';
import MapView, { Marker, Circle, Polyline } from 'react-native-maps';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
map: {
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
});
function Map (props){
const onMapLoad=()=>{
console.log(this.mapView)
console.log(props.route.params.destination.latitude)
this.mapView.animateToRegion({
latitude: props.route.params.destination.latitude,
longitude: props.route.params.destination.longitude,
latitudeDelta: 0.4,
longitudeDelta: 0.4,
},1000);
}
return (
<View style={styles.container}>
<MapView
ref={(ref) => this.mapView = ref}
style={styles.map}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
onMapReady={onMapLoad}
>
</MapView>
</View>
);
}
export default Map;
Related
first i use react-native-maps to locate the expo app in toronto,and i use react-native-maps-directions to draw route between two location in toronto.MapView component works,but its child component MapViewDirections not working.no error notification.
"react-native-maps": "0.30.2",
"react-native-maps-directions": "1.8.0"
code like below:
import * as React from 'react';
import MapView from 'react-native-maps';
import { StyleSheet, Text, View, Dimensions } from 'react-native';
import { StatusBar } from 'expo-status-bar';
import MapViewDirections from 'react-native-maps-directions';
const LATITUDE = 43.653225;
const LONGITUDE = -79.383186;
export default function App() {
const origin = {latitude: 43.791680, longitude: -79.312770};
const destination = {latitude: 43.785230, longitude: -79.293420};
const GOOGLE_MAPS_APIKEY = 'myapikey';
return (
<View style={styles.container}>
<MapView provider="google"
initialRegion={{
latitude: LATITUDE,
longitude: LONGITUDE,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
style={styles.map} >
<MapViewDirections
origin={origin}
destination={destination}
apikey={GOOGLE_MAPS_APIKEY}
onError={(errorMessage) => {
console.log('GOT AN ERROR');
}}
/>
</MapView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
map: {
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
})
Finally,I found the solution after I check MapViewDirections's source code .MapViewDirections component has very special logic while using,this component constructed with react-native-maps,so it should be work with MapView.And secondly,its state should be shown after re-render,I use usestate to make its state rendered.I paste code here:
import * as React from 'react';
import MapView, { Marker } from 'react-native-maps';
import { StyleSheet, Text, View, Dimensions } from 'react-native';
import { StatusBar } from 'expo-status-bar';
import MapViewDirections from 'react-native-maps-directions';
import { useState } from 'react';
const LATITUDE = 43.653225;
const LONGITUDE = -79.383186;
export default function App() {
const [coordinates] = useState([
{
latitude: 43.791680, longitude: -79.312770,
},
{
latitude: 43.785230, longitude: -79.293420,
},
]);
const origin = {latitude: 43.791680, longitude: -79.312770};
const destination = {latitude: 43.785230, longitude: -79.293420};
const GOOGLE_MAPS_APIKEY = 'AIzaSyBpAexI1D_HPIrR9xz_RqAAKDNlYKmW0Q8';
return (
<View style={styles.container}>
<MapView
style={styles.maps}
initialRegion={{
latitude: coordinates[0].latitude,
longitude: coordinates[0].longitude,
latitudeDelta: 0.0622,
longitudeDelta: 0.0121,
}}>
<MapViewDirections
origin={coordinates[0]}
destination={coordinates[1]}
apikey={GOOGLE_MAPS_APIKEY} // insert your API Key here
strokeWidth={4}
strokeColor="#111111"
/>
<Marker coordinate={coordinates[0]} />
<Marker coordinate={coordinates[1]} />
</MapView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
maps: {
width: Dimensions.get('screen').width,
height: Dimensions.get('screen').height,
},
})
What I'm trying to do is center the screen view to the user location when I press a custom button and not the default button react-native-map offers. I do get the longitude and latitude but I can't seem to figure out:
How to make the custom button call the method to center the view to the coordinates I have
How to center the View all together
import React,{ useState, useEffect} from 'react';
import MapView, {Marker, PROVIDER_GOOGLE} from 'react-native-maps';
import { StyleSheet, Image , Text, View} from 'react-native';
import * as Location from 'expo-location';
import {
LocationView ,
LocationBtn,
} from '../components/styles';
import { MaterialIcons } from '#expo/vector-icons';
const Map = (props) =>{
const [mapRegion, setMapRegion] = useState(null);
useEffect(() => {
(async () => {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
setErrorMsg('Permission to access location was denied');
return;
}
let location = await Location.getCurrentPositionAsync({});
setMapRegion({
longitude: location.coords.longitude,
latitude: location.coords.latitude,
longitudeDelta: 0.0922,
latitudeDelta: 0.0421
});
console.log('location', location)
})();
}, [])
return(
<View style={{ flex: 1}}>
<MapView
region={mapRegion}
provider={PROVIDER_GOOGLE}
style={styles.map}
mapType={props.mapType}
showsUserLocation={true}
showsMyLocationButton={true}
loadingEnabled={true}
initialRegion={mapRegion}
userInterfaceStyle='light'
showsTraffic={true}
>
<Marker
coordinate={mapRegion}
>
<Image source={require('../assets/marker.png')} style={{height: 90, width: 90}} />
</Marker>
</MapView>
<LocationView>
<LocationBtn
>
<MaterialIcons
name="my-location"
size={30}
color="black"
style={{alignSelf: 'center', marginTop: 13}}
/>
</LocationBtn>
</LocationView>
</View>
)
}
const styles = StyleSheet.create({
map: {
height: '100%',
},
})
export default Map;
<View style={{ flex: 1}}>
Please add style justify content and align items.
I am trying to make the map fit and fill the screen
The map just covers some part of the screen, but in this case I would like to have it fill the screen on any android device. I need someone to help.
My source code looks like this.
import React, { Component } from 'react';
import { View, StyleSheet, Text } from 'react-native';
import MapView , {Marker} from 'react-native-maps';
export default class ShowMap extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<View style={styles.container}>
<MapView
style={styles.map}
region={{
latitude: 6.406070,
longitude: 3.407350,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
}}
>
<Marker
coordinate={{ latitude: 6.406070, longitude: 3.407350 }}
title='Emi School of Engineering'
description='This is where the magic happens!'
></Marker >
</MapView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
height: 660,
width: 420,
justifyContent: 'flex-start',
alignItems: 'stretch',
},
map: {
...StyleSheet.absoluteFillObject,
},
});
Looks like there is something i need to do, I am not doing correctly.
you can get the screen height from Dimension Interface provided by react-native and set replace height value from it.
import React, { Component } from 'react';
import { View, StyleSheet, Text, Dimensions } from 'react-native';
import MapView , {Marker} from 'react-native-maps';
//get screen height
const deviceHeight =Dimensions.get("window").height
export default class ShowMap extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<View style={styles.container}>
<MapView
style={styles.map}
region={{
latitude: 6.406070,
longitude: 3.407350,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
}}
>
<Marker
coordinate={{ latitude: 6.406070, longitude: 3.407350 }}
title='Emi School of Engineering'
description='This is where the magic happens!'
></Marker >
</MapView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
height: deviceHeight,
width: 420,
justifyContent: 'flex-start',
alignItems: 'stretch',
},
map: {
...StyleSheet.absoluteFillObject,
},
});
an app I am trying to make involves a portion where nearby markers are fetched from my server.
I am sure that my location hook function works, however, it is not finishing before my API call is made to get markers near that location.
This has confused me for hours, so any help would be greatly appreciated!
import React, { useEffect, useState } from "react";
import MapView, { PROVIDER_GOOGLE, Marker } from "react-native-maps";
import { StyleSheet, View, Dimensions, Platform } from "react-native";
import useLocation from "../hooks/useLocation";
import useApi from "../hooks/useApi";
import couponsInArea from "../api/couponsInArea";
const customData = require("../assets/map_styles/day_map.json");
function MapScreen(props) {
//Here is the location hook
var location = useLocation();
const couponBaseApi = useApi(couponsInArea.getCouponBases);
//Here is the API call that needs the location
useEffect(() => {
if (location) {
couponBaseApi.request(location.latitude, location.longitude);
}
}, []);
return (
<View style={styles.container}>
<MapView
followUserLocation={true}
zoomEnabled={true}
showsUserLocation={true}
style={styles.mapStyle}
provider={PROVIDER_GOOGLE}
customMapStyle={customData}
initialRegion={{
latitude: location.latitude,
longitude: location.longitude,
latitudeDelta: 0.0158,
longitudeDelta: 0.007,
}}
>
{couponBaseApi.data.couponBases.map((report) => (
<Marker
key={report.couponBaseID}
coordinate={{
latitude: report.latitude,
longitude: report.longitude,
}}
></Marker>
))}
</MapView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
mapStyle: {
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
},
});
export default MapScreen;
The solution was that the use effect hook needed to watch for a change on location,
so
useEffect(() => {
if (location) {
couponBaseApi.request(location.latitude, location.longitude);
}
}, [location]);
Thanks everyone!
I need your help to know how to display GPS coordinates in a MapView.
I want to track a person's location from gps coordinates (longitude and latitude).
I tried too much to recover the coordinates in a MapView but I did not arrive to do it, I am blocked.
So, I get the coordinates from a web service and I display them in a TextView.
This is my code:
import React, { Component } from 'react';
import { Constants, Location, Permissions } from 'expo';
import { Card } from 'react-native-paper';
import { Polyline } from 'react-native-maps';
import {
StyleSheet,
Platform,
View,
ActivityIndicator,
FlatList,
Text,
Image,
TouchableOpacity,
Alert,
YellowBox,
AppRegistry,
Button,
} from 'react-native';
export default class gps extends Component {
static navigationOptions = ({ navigation }) => {
return {
title: 'Suivi GPS',
headerStyle: {
backgroundColor: 'transparent',
},
headerTitleStyle: {
fontWeight: 'bold',
color: '#000',
zIndex: 1,
fontSize: 18,
lineHeight: 25,
fontFamily: 'monospace',
},
};
}
state = {
mapRegion: null,
dat: '',
};
GetItem() {}
componentDidMount() {
this.webCall();
}
FlatListItemSeparator = () => {
return (
<View
style={{
height: 0.5,
width: '100%',
backgroundColor: '#000',
}}
/>
); //
};
webCall = () => {
return fetch('http://first-ontheweb.com/onLineSenior/pos.php')
.then(response => response.json())
.then(responseJson => {
this.setState({
isLoading: false,
dataSource: responseJson,
});
})
.catch(error => {
console.error(error);
});
};
render() {
if (this.state.isLoading) {
return (
<View
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" />
</View>
);
}
return (
<View style={styles.map}>
<FlatList
data={this.state.dataSource}
ItemSeparatorComponent={this.FlatListItemSeparator}
renderItem={({ item }) => (
<View>
<Text style={styles.textView}>Longitude :</Text>
<Text style={styles.textView}>{item.longitude}</Text>
<Text style={styles.textView}>Latitude :</Text>
<Text style={styles.textView}>{item.latitude}</Text>
</View>
)}
keyExtractor={(index) => index.toString()}
/>
</View>
);
}
}
const styles = StyleSheet.create({
map: {
...StyleSheet.absoluteFillObject,
},
});
So, I want to display the GPS coordinates in a MapView.
Thanks.
You can do something like this:
first import the mapView:
import MapView from "react-native-maps";
Then:
state = {
focusedLocation: {
latitude: 37.7900352, //or your coordinates
longitude: -122.4013726, //or your coordinates
latitudeDelta: 0.0122,
longitudeDelta:
Dimensions.get("window").width /
Dimensions.get("window").height *
0.0122
}
};
render() {
let marker = null;
if (this.state.locationChosen) {
marker = <MapView.Marker coordinate={this.state.focusedLocation} />;
}
return (
let marker = <MapView.Marker coordinate={this.state.focusedLocation} />;
<View style={styles.container}>
<MapView
initialRegion={this.state.focusedLocation}
style={//map style here}
>
{marker}
</MapView>
</View>
);
}
you need to install react-native-maps package than
import MapView from 'react-native-maps';
Rendering a Map with an initial region
<MapView
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
Using a MapView while controlling the region as state
getInitialState() {
return {
region: {
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
},
};
}
onRegionChange(region) {
this.setState({ region });
}
render() {
return (
<MapView
region={this.state.region}
onRegionChange={this.onRegionChange}
/>
);
}
Rendering a list of markers on a map
import { Marker } from 'react-native-maps';
<MapView
region={this.state.region}
onRegionChange={this.onRegionChange}
>
{this.state.markers.map(marker => (
<Marker
coordinate={marker.latlng}
title={marker.title}
description={marker.description}
/>
))}
</MapView>
you can find more in the documention here.
https://github.com/react-native-community/react-native-maps