How to Draw Directions Route on a Map in React Native

Today we’re going to draw directions route on a map in React Native, showcasing the path between two different locations. We’re going to make use of react-native-maps which is a powerful library, allowing us to draw polylines between multiple coordinates. We are also going to use Google Directions API, in order to fetch precise directions routes between two coordinates.

It is important to note that the react-native-maps library as of the time of this writing only officially supports the polyline module on the latest React Native version due to the increasing changes in the React Native ecosystem that are not easy to keep up with.

Installation

Let’s install and configure this library. Depending on your preferred package manager, simply run:

npm install react-native-maps --save-exact

or

yarn add react-native-maps -E

Pro Tip: The -E flag installs the exact latest version of this library

Setup

iOS

cd ios
pod install

Get a Google API key from your Google Console. You can learn how to obtain the Google API Key step by step in our User Location tutorial. Once you have the API key, edit your AppDelegate.m file:

+ #import <GoogleMaps/GoogleMaps.h>

@implementation AppDelegate
...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
+  [GMSServices provideAPIKey:@"_YOUR_API_KEY_"]; // add this line using the api key obtained from Google Console
...

Add the following to your Podfile above the use_native_modules! function and run pod install in the ios folder:

# React Native Maps dependencies
rn_maps_path = '../node_modules/react-native-maps'
pod 'react-native-google-maps', :path => rn_maps_path
pod 'GoogleMaps'
pod 'Google-Maps-iOS-Utils'

Android

If you’ve defined project-wide properties (recommended!) in your root build.gradle, this library will detect the presence of the following properties:

buildscript {...}
allprojects {...}

/**
 + Project-wide Gradle configuration properties
 */
ext {
    compileSdkVersion   = xxx
    targetSdkVersion    = xxx
    buildToolsVersion   = "xxx"
    minSdkVersion       = xxx
    supportLibVersion   = "xxx"
    playServicesVersion = "17.0.0" // or get latest version
    androidMapsUtilsVersion = "xxx"
}

or you could do

buildscript {
    ext {
        buildToolsVersion = "xxx"
        minSdkVersion = xxx
        compileSdkVersion = xxx
        targetSdkVersion = xxx
        supportLibVersion = "xxx"
        playServicesVersion = "17.0.0" // or find latest version
        androidMapsUtilsVersion = "xxx"
    }
}
...

If you do not have project-wide properties defined and have a different play-services version than the one included in this library, use the following instead (switch 17.0.0 and/or 17.2.1 for the desired versions):

...
dependencies {
   ...
   implementation(project(':react-native-maps')){
       exclude group: 'com.google.android.gms', module: 'play-services-base'
       exclude group: 'com.google.android.gms', module: 'play-services-maps'
   }
   implementation 'com.google.android.gms:play-services-base:17.2.1'
   implementation 'com.google.android.gms:play-services-maps:17.0.0'
}

Finally, you have to add your already retrieved Google API Key to the AndroidManifest.xml:

<application>
   <!-- You will only need to add this meta-data tag, but make sure it's a child of application -->
   <meta-data
     android:name="com.google.android.geo.API_KEY"
     android:value="Your Google maps API Key Here"/>
  
   <!-- You will also only need to add this uses-library tag -->
   <uses-library android:name="org.apache.http.legacy" android:required="false"/>
</application>

Usage

The basic usage of this library is as follows:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React from 'react';
import {StyleSheet, View, Dimensions} from 'react-native';

import MapView from 'react-native-maps';

const App = () => {
  return (
    <View style={styles.container}>
      <MapView
        style={styles.maps}
        initialRegion={{
          latitude: 48.864716,
          longitude: 2.349014,
          latitudeDelta: 0.0622,
          longitudeDelta: 0.0121,
        }}/>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  maps: {
    width: Dimensions.get('screen').width,
    height: Dimensions.get('screen').height,
  },
});

export default App;

This snippet of code renders a basic map that centers on Paris, France. It’s just the bare map as we can see below but we will add the functionality to render a line showing a direction between two locations.

To achieve the goal of this article, we have to take a look at an element named Polyline, provided by react-native-maps which draws the directions route between two points on the map.

const App = () => {
  const [coordinates] = useState([
    {
      latitude: 48.8587741,
      longitude: 2.2069771,
    },
    {
      latitude: 48.8323785,
      longitude: 2.3361663,
    },
  ]);

  return (
    <View style={styles.container}>
      <MapView
        style={styles.maps}
        initialRegion={{
          latitude: coordinates[0].latitude, 
          longitude: coordinates[0].longitude,
          latitudeDelta: 0.0622,
          longitudeDelta: 0.0121,
        }}>
        <Marker coordinate={coordinates[0]} />
        <Marker coordinate={coordinates[1]} />
        <Polyline
          coordinates={coordinates}
          strokeColor="#000" // fallback for when `strokeColors` is not supported by the map-provider
          strokeColors={['#7F0000']}
          strokeWidth={6}
        />
      </MapView>
    </View>
  );
};

As we can see in the screenshot below it just displays a straight line between the two markers on the map and this is not helpful for our purpose because it does not show us the path between the two locations.

To solve this issue, we have to use an external library react-native-maps-directions to help us draw the correct directions route between our two desired locations. This library makes use the of the Google Directions API, which is a REST endpoint provided by Google, which you can query to get the directions routes between two coordinates with a simple HTTP call.

const App = () => {
  const [coordinates] = useState([
    {
      latitude: 48.8587741,
      longitude: 2.2069771,
    },
    {
      latitude: 48.8323785,
      longitude: 2.3361663,
    },
  ]);

  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_API_KEY} // insert your API Key here
          strokeWidth={4}
          strokeColor="#111111"
        />
        <Marker coordinate={coordinates[0]} />
        <Marker coordinate={coordinates[1]} />
      </MapView>
    </View>
  );
};

With that we would have achieved our goal.

Conclusion

If you have followed closely you would have been able to render directions on a React Native map. But take note that you should enable Directions API for the directions to be rendered and Google Maps for Android  if you are testing for Android or Google Maps API for iOS if you’re testing for iOS.

We were able to draw the directions route between two given locations on a map in React Native, by using a maps library as well as the Google Directions API endpoint.

If you found this React Native tutorial useful, please spread the word by sharing it with your community. Cheers!

The post How to Draw Directions Route on a Map in React Native appeared first on instamobile.