In this article I am going to show you how you can easily integrate google maps in your expo react native project with just 3 libraries from google nom package.
What is Google Map?
Google Maps is a web service that provides detailed information about geographical regions and sites worldwide. In addition to conventional road maps, Google Maps offers aerial and satellite views of many locations. In some cities, Google Maps offers street views comprising photographs taken from vehicles.
If you're looking at building apps that are in the logistics, food delivery or ride hailing business, then having a google maps feature is highly needed for geolocation and tracking .
Now that we grasped what Google map is, let's get into the code proper.
First you want to start a new expo project using the command as follow;
npx create-expo-app GooglemapProject && cd GooglemapProject
Once your expo project is created cd into the project folder and run the command to start the project on your emulator or physical device.
Use the command to run your project on android emulator or physical device.
yarn android
This command will open the metro for the project, if you have a expo installed in your physical device, simply scan with your phone camera and viola! Your project will load in your device.
For ios device, se the command to run your project on android emulator or physical device.
yarn ios
This command will open the metro for the project, if you have a expo installed in your physical device, simply scan with your phone camera and viola! Your project will load in your device.
Okay! Now that we have our project running, let's begin implementing the google maps.
So to begin, we are going to using just 3 libraries from google npm package. Which are;
react-native-google-places-autocomplete
react-native-maps-directions
react-native-maps
so install these packages using yarn or npm
yarn add react-native-google-places-autocomplete react-native-maps-directions
Now that we have installed these packages, import the 2 packages into your app.js file as follow
import {
StyleSheet,View,Dimensions,Text,TouchableOpacity,
} from "react-native";
import MapView, { Marker, PROVIDER_GOOGLE } from "react-native-maps";
import { GooglePlacesAutocomplete } from "react-native-google-places-autocomplete";
import MapViewDirections from "react-native-maps-directions";
Then are going to create a child component that will contain the GooglePlacesAutocomplete component. Let's the component InputAutoComplete
Inside this component we are using the GooglePlacesAutocomplete we imported to auto complete places which user type in the input,
function InputAutoComplete({ label, placeholder, onPlaceSelected }) {
return (
<>
<Text>{label}</Text>
<GooglePlacesAutocomplete
placeholder={placeholder || ""}
fetchDetails
onPress={(data, details = null) => {
onPlaceSelected(details);
}}
query={{
key: "YOUR API KEY",
language: "en",
}}
/>
</>
);
}
The InputAutoComplete component accepts 3 props from the parent and they are label, placeholder, onPlaceSelected.
Alright!, now let's move over to the parent component and include the child component and also use the MapView import to show the UI for the map.
We are go to declare some constant which the MapView will require as initial region.
const { width, height } = Dimensions.get("window");
const ASPECT_RATIO = width / height;
const LATITUDE_DELTA = 0.02;
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO;
const INITIAL_POSITION = {
latitude: 40.76711,
longitude: -73.979704,
latitude_delta: LATITUDE_DELTA,
longitude_delta: LONGITUDE_DELTA,
};
export default function App() {
const [origin, setOrigin] = useState(null);
const [destination, setDestination] = useState(null);
const [showDirection, setShowDirection] = useState(false);
const mapRef = useRef(null);
const moveto = async (position) => {
const camera = await mapRef.current?.getCamera();
if (camera) {
camera.center = position;
mapRef.current?.animateCamera(camera, { duration: 1000 });
}
};
const edgePaddingValue = 120;
const edgePadding = {
top: edgePaddingValue,
right: edgePaddingValue,
bottom: edgePaddingValue,
left: edgePaddingValue,
};
const traceRoute = () => {
if (origin && destination) {
setShowDirection(true);
mapRef.current?.fitToCoordinates([origin, destination], { edgePadding });
}
};
const onPlaceSelected = (details, flag) => {
const set = flag === "origin" ? setOrigin : setDestination;
const position = {
latitude: details?.geometry.location.lat || 0,
longitude: details?.geometry.location.lng || 0,
};
set(position);
moveto(position);
};
return (
<View>
<MapView
ref={mapRef}
provider={PROVIDER_GOOGLE}
initialRegion={INITIAL_POSITION}
>
{origin && <Marker coordinate={origin} />}
{destination && <Marker coordinate={destination} />}
{origin && destination && showDirection && (
<MapViewDirections
origin={origin}
destination={destination}
apikey={"YOUR API KEY"}
strokeColor="red"
strokeWidth={4}
/>
)}
</MapView>
<View>
<InputAutoComplete
label="Origin"
onPlaceSelected={(details) => {
onPlaceSelected(details, "origin");
}}
/>
<InputAutoComplete
label="Destination"
onPlaceSelected={(details) => {
onPlaceSelected(details, "destination");
}}
/>
<TouchableOpacity onPress={() => traceRoute()}>
<Text>Trace route</Text>
</TouchableOpacity>
</View>
</View>
);
}
So we are wrapping all component with the MapView which takes 3 props.
In closing we created 2 InputAutoComplete that accepts the origin and destination address, which sets the input when onPress.
A Marker is set when the origin or destination position is set using setOrigin and setDestination in the onPlaceSelect function.
So let's run the project and see the result.
I hope I'm able to help with this article. Thank you.
Top comments (0)