As of 2022, does React Native Maps still free, or does go under any list of Google pricing?
I read this line on Reddit but it's 2 years ago
"Embedding Google Maps through react-native-maps does require an API key, but it is at no cost. Can confirm as I have an app at 100K users and haven't paid a dime for maps."
I am not sure if it is still the same.
This is my way of using it:
import { StyleSheet, Text, View, Button } from "react-native";
import MapView, {
PROVIDER_GOOGLE,
MAP_TYPES,
PROVIDER_DEFAULT,
UrlTile,
Marker,
} from "react-native-maps";
import React, { useEffect } from "react";
export default function Home({ navigation }) {
let location = {
latitude: 30.259933,
longitude: 31.412613,
latitudeDelta: 0.009,
longitudeDelta: 0.009,
};
return (
<View style={styles.container}>
<View style={styles.myMap}>
<MapView
style={{ flex: 1 }}
showsUserLocation
PROVIDER_GOOGLE
MAP_TYPES="STANDARD"
>
<Marker
title="Home"
coordinate={{
latitude: location.latitude,
longitude: location.longitude,
}}
/>
</MapView>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#ffd",
alignItems: "center",
justifyContent: "center",
},
myMap: {
flex: 2,
backgroundColor: "white",
width: "100%",
marginTop: 30,
marginBottom: 30,
},
map: {
width: "100%",
height: "100%",
},
});
I need some clarification
See https://developers.google.com/maps/documentation/android-sdk/usage-and-billing#dynamic-maps
If you use a Map ID you will be charged. (This is new functionality)
Related
I am trying to use openstreetmap tile in UrlTile but I am getting duplicate layers, openstreetmap and default google map, how can I remove google map layer?
This is my component:
import { StyleSheet, Text, View, Button } from "react-native";
import MapView, {
PROVIDER_GOOGLE,
MAP_TYPES,
PROVIDER_DEFAULT,
UrlTile,
Marker,
} from "react-native-maps";
import React, { useEffect } from "react";
export default function Home({ navigation }) {
let location = {
latitude: 23.259933,
longitude: 77.412613,
latitudeDelta: 0.009,
longitudeDelta: 0.009,
};
return (
<View style={styles.container}>
<View style={styles.myMap}>
<MapView
region={location}
rotateEnabled={false}
style={{ flex: 1 }}
style={styles.map}
showsUserLocation
>
<UrlTile
urlTemplate="https://a.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png"
maximumZ={19}
/>
<Marker
title="Home"
coordinate={{
latitude: location.latitude,
longitude: location.longitude,
}}
/>
</MapView>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#ffd",
alignItems: "center",
justifyContent: "center",
},
btn1: {
margin: 20,
},
btn2: {
margin: 20,
},
btns: {
flex: 1,
flexDirection: "row",
backgroundColor: "grey",
},
myMap: {
flex: 2,
backgroundColor: "white",
width: "100%",
marginTop: 30,
marginBottom: 30,
},
map: {
width: "100%",
height: "100%",
},
});
Also, when I switch openstreetmap tile with my own MapTiler server tiles it doesn't show anything, just google map
'http://localhost:3650/api/maps/satellite-hybrid/{z}/{x}/{y}.png'
One last thing, I need to know if this going to cost me, I am required to use Google API key to run react-native-maps library, I need some explanation.
Thank you in advance.
have you tried to consult the MapTiler Documentation yet?
There might be some tips to help you:
https://docs.maptiler.com/maplibre-gl-native-android/?_ga=2.172534305.364226297.1644212649-2087445124.1628005081&_gl=1*1hky133*_ga*MjA4NzQ0NTEyNC4xNjI4MDA1MDgx*_ga_K4SXYBF4HT*MTY0NDI0NDA5My4yLjEuMTY0NDI0NTAxMC41Ng..
May I ask if the Google Map is essential? Since you use MapTiler Server, it could be also replaced with a MapTiler Data Layer.
If you are interested in getting to know more, feel free to contact us at support#maptiler.com
Add this to your MapView.
mapType={Platform.OS == "android" ? "none" : "standard"}
or
mapType={Platform.OS == "ios" ? "none" : "standard"}
You can find more info on this page https://github.com/react-native-maps/react-native-maps#tile-overlay-using-local-tiles
react-native: https://github.com/expo/react-native/archive/sdk-42.0.0.tar.gz
react: 16.13.1
react-native-maps: 0.28.0
I want to get markers as a part of the snapshot. When we use takeSnapshot method all markers are ignored.
const snapshot = this.viewRefTest.takeSnapshot({
format: 'png', // image formats: 'png', 'jpg' (default: 'png')
quality: 0.5, // image quality: 0..1 (only relevant for jpg, default: 1)
result: 'file', // result types: 'file', 'base64' (default: 'file')
});
<MapView
ref={(viewRefTest) => {
this.viewRefTest = viewRefTest;
}}
showsUserLocation={true}
followUserLocation={true}>
<MapView.Marker coordinate={item.location}>
<Image
style={{ width: 30, height: 30 }}
source={require('../../assets/images/trophy.png')}
/>
<Callout style={{ width: 250, flexDirection: 'row', alignItems: 'center' }}>
<Text>$23</Text>
<View>
<Text style={{ fontSize: 12 }}>Custom Text!</Text>
</View>
</Callout>
</MapView.Marker>
</MapView>;
Please let me know the possibility of this.
After too many tries & combinations of adding delays, height/width, I was not able to capture custom markers using takeSnapshot method.
As a workaround, I have used captureRef method of react-native-view-shot
https://github.com/gre/react-native-view-shot
const uri = await captureRef(this.viewRefTest, {
format: "png",
quality: 1
})
<MapView
ref={(viewRefTest) => {
this.viewRefTest = viewRefTest;
}}
showsUserLocation={true}
followUserLocation={true}>
<MapView.Marker coordinate={item.location}>
<Image
style={{ width: 30, height: 30 }}
source={require('../../assets/images/trophy.png')}
/>
<Callout style={{ width: 250, flexDirection: 'row', alignItems: 'center' }}>
<Text>$23</Text>
<View>
<Text style={{ fontSize: 12 }}>Custom Text!</Text>
</View>
</Callout>
</MapView.Marker>
</MapView>
CaptureRef Returns a Promise of the image URI. It helps capture a React Native view to an image. We can mention height, width, quality & format for the captured image.
Could you try use width and height?
const snapshot = this.viewRefTest.takeSnapshot({
width: 500,
height: 500,
format: 'png',
quality: 0.5,
result: 'file',
});
snapshot.then((uri) => {
console.log(uri);
});
You can solve that by creating a Snapshot with "react-native-view-shot"
I think this bug depends on when you call this.viewRefTest.takeSnapshot()
You can check in my https://expo.dev/#duongtungls/expo-map-view-example
I think call takeSnapshot just after map mounted won't get marker or map.
If call after callback onMapReady still need wait some hundreds of milisecond to take fully snapshot for both map and marker.
I hope this example code can help you solve problem.
import { StatusBar } from 'expo-status-bar';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import MapView, { Marker } from 'react-native-maps';
import { Ionicons } from '#expo/vector-icons';
export default function App() {
const mapRef = useRef(null);
const [uri, setUri] = useState(null);
const takeSnapshot = useCallback(() => {
if (!mapRef || !mapRef.current) {
return;
}
setTimeout(() => {
const snapshot = mapRef.current.takeSnapshot({
format: 'png', // image formats: 'png', 'jpg' (default: 'png')
quality: 0.5, // image quality: 0..1 (only relevant for jpg, default: 1)
result: 'file', // result types: 'file', 'base64' (default: 'file')
});
snapshot.then((uri) => {
setUri(uri);
});
}, 800); // I add some timeout delay because without delay snapnot won't have map or marker.
}, [mapRef]);
return (
<View style={styles.container}>
{!uri && (
<MapView
ref={mapRef}
style={{
width: '100%',
height: '100%',
}}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
onMapReady={takeSnapshot} // I think need wait for map ready to take snapshot but seem still need wait by setTimeout to get fully snapshot
>
<Marker
coordinate={{
latitude: 37.78825,
longitude: -122.4324,
}}
title={'Test'}
>
<Ionicons name="trophy" size={32} color="red" />
<Text>This is a marker</Text>
</Marker>
</MapView>
)}
{uri && (
<Image
style={{
width: '100%',
height: '100%',
resizeMode: 'contain',
borderColor: 'red',
borderWidth: 10,
}}
source={{
uri,
}}
/>
)}
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Snapshot take after map mounted
Snapshot take after onMapReady and 800ms delay
Best regards,
I would like to add a search bar to my maps screen and then use google to find the location associated with the input text and move the map there.
This is what I have right now:
import React, { Component } from 'react';
import {
View
} from 'react-native';
import { Mapview } from 'expo';
export default class screen extends Component {
constructor(props) {
super(props);
this.state = {
initialRegion: {
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}
};
}
render() {
return (
<View>
<MapView
style={{ flex: 1 }}
initialRegion={this.state.initialRegion}
/>
</View>
)
}
}
I cannot find this feature in the react-native-maps documentation. Is this something I need to build myself?
This answer covers adding a search box onto your map.
As specified in the react-native-maps docs (https://github.com/react-native-maps/react-native-maps#overlaying-other-components-on-the-map) you need to use absolute positioning.
For example the following code:
<MapView loadingEnabled={true} style={styles.map} />
<View style={{ position: 'absolute', top: 10, width: '100%' }}>
<TextInput
style={{
borderRadius: 10,
margin: 10,
color: '#000',
borderColor: '#666',
backgroundColor: '#FFF',
borderWidth: 1,
height: 45,
paddingHorizontal: 10,
fontSize: 18,
}}
placeholder={'Search'}
placeholderTextColor={'#666'}
/>
</View>
Will produce the following layout.
Hi I am new to react native
I have mapview and FlatList in my screen like shown in the below image.
Now I want Mapview to be expanded when i click on it , like the below image
Here is my code
import React, { Component } from 'react';
import MapView, { PROVIDER_GOOGLE, Marker } from 'react-native-maps';
import { View, StyleSheet, Text, TouchableOpacity, Animated, Image } from 'react-native';
import { Actions } from 'react-native-router-flux';
import DoctorsList from './DoctorsList';
import colors from '../styles/colors';
var isHidden = true;
export default class FindDoctorMaps extends Component {
constructor(props) {
super(props);
this.state = {
bounceValue: new Animated.Value(500), //This is the initial position of the subview
buttonText: 'LIST VIEW',
printText: false,
markers: [{
title: 'hello',
coordinates: {
latitude: 17.452,
longitude: 78.3721
},
},
{
title: 'hi',
coordinates: {
latitude: 17.458,
longitude: 78.3731
},
},
{
title: 'gyp',
coordinates: {
latitude: 17.468,
longitude: 78.3631
},
},
{
title: 'nig',
coordinates: {
latitude: 17.568,
longitude: 78.3831
},
},
{
title: 'Yoy',
coordinates: {
latitude: 17.588,
longitude: 78.4831
},
}]
};
}
render() {
return (
<View style={{ flex: 1, backgroundColor: 'white' }} >
<MapView
provider={PROVIDER_GOOGLE}
region={{
latitude: 17.452,
longitude: 78.3721,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
}}
style={styles.map}
showsUserLocation
followUserLocation
showsMyLocationButton
showsCompass
zoomEnabled
>
{this.state.markers.map(marker => (
<MapView.Marker
coordinate={marker.coordinates}
title={marker.title}
onPress={this.onMarkerPress}
/>
))}
</MapView>
<TouchableOpacity style={styles.filterContainer} onPress={Actions.morefilters}>
<View style={styles.filterStyle}>
<Image style={{ margin: 5 }} source={require('../assets/filters_icon.png')} />
<Text style={{ fontSize: 14, color: colors.darkBlue, fontWeight: 'bold', }}> Filters</Text>
</View>
</TouchableOpacity>
<View>
<TouchableOpacity >
<DoctorsList />
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
map: {
height: 200,
},
textViewStyle: {
fontSize: 14,
color: '#00539d',
fontWeight: 'bold',
margin: 20
},
subView: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
backgroundColor: '#FFFFFF',
height: 500,
},
filterContainer: {
top: '20%',
right: 0,
alignSelf: 'flex-end',
position: 'absolute'
},
filterStyle: {
flexDirection: 'row',
backgroundColor: colors.white,
borderRadius: 8,
height: 30,
width: '60%',
alignItems: 'center',
justifyContent: 'center'
}
});
Can any one please help me how to expand Mapview by clicking on it.
or else please share some useful links so that i would be helpful for me
this.state = {
....
showMapFullScreen: false
....
}
render() {
....
<MapView
....
style={height: showMapFullScreen ? "100%" : 200 }
onPress={() => this.setState({ showMapFullScreen : true }) }
....
>
....
<TouchableOpacity
onPress={() => this.setState({ showMapFullScreen : false }) }>
<DoctorsList />
</TouchableOpacity>
.......
}
You can toggle the map height with a flag like shown above. When the user clicks on the map the height becomes full screen when he/she clicks on the list the map's height is reduced and gives space to the list to render.
https://ufile.io/1bdoq
Bug:
Mapview wrapped children components may or may not leave the parent component when app loads.
Simulator:
iOS iPhone 6
xCode 10
Environment :
react-native-cli: 2.0.1
react-native: 0.57.0
"react-native-maps": "^0.22.1",
import React, { Component } from 'react';
import {View, Text, TouchableOpacity} from 'react-native'
import MapView from 'react-native-maps';
import { SearchBar } from 'react-native-elements'
import FontAwesome5 from 'react-native-vector-icons/dist/FontAwesome5'
export default class Search extends Component {
static navigationOptions = {
title: 'Search',
header: null
};
constructor(props){
super(props);
this.state = {
region: {
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
},
}
}
onRegionChange(region) {
this.setState({ region });
}
render(){
return(
<View style={{flex:1}}>
<MapView
style={{flex: 1}}
onRegionChange={(region) => this.onRegionChange(region)}
initialRegion={this.state.region}
>
<SearchBar
containerStyle={{backgroundColor: 'rgba(0,0,0,0)', borderTopWidth: 0, borderBottomWidth: 0, marginLeft: 10, marginRight: 10}}
inputStyle={{backgroundColor: 'white', marginTop: 30}}
icon={{type: 'material', color: '#86939e', name: 'search',style:{marginTop: 22, zIndex: 9999999}}}
lightTheme
/>
<TouchableOpacity style={{ height: 30, width: 150, backgroundColor:'white', justifyContent: 'center', paddingLeft: 10, paddingRight: 10}}>
<Text style={{textAlign: 'center'}}>Current Location</Text>
</TouchableOpacity>
<TouchableOpacity style={{ height: 30, width: 30, backgroundColor:'blue', justifyContent: 'center'}}>
<FontAwesome5 name="location-arrow" size={20} color="white"/>
</TouchableOpacity>
</MapView>
</View>
)
}
}
please close. READ THE DOCS do not wrap your components within the mapview, but put it underneath, and use absolute.