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,
},
})
Related
I want to put the values of the longitude and latitude of the initial Region, the longitude and latitude obtained above, but I keep getting errors. What should I do? I don't know how.
"latitude:37,
longitude: 127,"
This part keeps getting errors.
I made
const[la,setLa]=useState("Loading...")
setLa(latitude)
...
initialRegion={{
latitude:Number(la),
then error says latitude:<<'Nan'>>..
I think latitude is string.
How can I change string to number?
import { StatusBar } from "expo-status-bar";
import React from "react";
import * as Location from "expo-location";
import { View, Text, StyleSheet, ScrollView, Dimensions} from "react-native";
import { backgroundColor } from "react-native/Libraries/Components/View/ReactNativeStyleAttributes";
import { useEffect, useState } from "react";
import MapView, { PROVIDER_GOOGLE, Marker }from "react-native-maps";
const { width: SCREEN_WIDTH } = Dimensions.get("window");
export default function App() {
const [city, setCity] = useState("Loading...");
const [la,setLa]=useState("Loading...");
const [location, setLocation] = useState(null);
const [ok, setOk] = useState(true);
const ask = async () => {
const { granted } = await Location.requestForegroundPermissionsAsync();
if (!granted) {
setOk(false);
}
const {
coords: { latitude, longitude },
} = await Location.getCurrentPositionAsync({ accuracy: 5 });
const location = await Location.reverseGeocodeAsync(
{ latitude, longitude },
{ useGoogleMaps: false }
);
setCity(location[0].district)
};
useEffect(() => {
ask();
}, []);
return (
<>
<View style={{flex:0.16,backgroundColor:'white'}}>
<Text style={{fontSize:40,marginTop:55,marginLeft:30}}>{city}</Text>
</View>
<View style={{ flex: 1 }}>
<MapView
style={{ flex: 1 }}
provider={PROVIDER_GOOGLE}
initialRegion={{
latitude:37,
longitude: 127,
latitudeDelta: 0.00922,
longitudeDelta: 0.00321,
}}>
</MapView>
</View>
<StatusBar style="black" />
</>
);
}
const styles = StyleSheet.create({
}
);
Show MapView when location is not null like this.
<View style={{ flex: 1 }}>
yourlatitudelongitudestate && <MapView
style={{ flex: 1, marginTop: 40 }}
initialRegion={{
latitude: latitude,
longitude: longitude ,
latitudeDelta: 0.00922,
longitudeDelta: 0.00321,
}}
/>
</View>
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;
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 am trying to establish a line between two locations in google maps using react-native. But I am getting
Error :
react-native-maps-directions Error on GMAPS route request Unknown
error.
React-native code :
import React , { Component } from 'react';
import { Dimensions, StyleSheet } from 'react-native';
import MapView from 'react-native-maps';
import MapViewDirections from 'react-native-maps-directions';
const GOOGLE_MAPS_APIKEY = "...";
const origin = {latitude: 15.846812, longitude: 80.891340, latitudeDelta: 0.0622, longitudeDelta: 0.0421};
const destination = {latitude: 15.750875, longitude: 81.018389, latitudeDelta: 0.0622, longitudeDelta: 0.0421};
class RNMapsDirectionsExample extends Component{
render(){
return(
console.log('orgin' ,{origin}),
console.log('destination', {destination}),
<MapView initialRegion={
{
latitude: 15.846812,
longitude: 80.891340,
latitudeDelta: 0.0622,
longitudeDelta: 0.0421}
}>
<MapViewDirections
origin={origin}
destination={destination}
apikey={GOOGLE_MAPS_APIKEY}
/>
</MapView>
);
}
}
const styles = StyleSheet.create({
mapContainer: {
width: "100%",
height: 200,
marginTop: 20,
flex:1
},
map: {
width: "100%",
height: "100%",
flex:1
}
});
export default RNMapsDirectionsExample;
Yup found the solution, u guys might be using coordinates for the places where there is no land route.
Like India to Australia.
And please set stroke width and color.