Implementing Mapbox On React Native

Implementing Mapbox On React Native

An introduction on implementing Mapbox, a popular location data platform, on your React Native application

Introduction

In this article, we are going to learn the basics of using Mapbox as a tool for integrating maps in React Native. While Google Maps is probably the most famous mapping system, there are various other worthy contenders in the market. What makes Mapbox one of the most prominent players in the field is the fact that it is a location data platform that powers maps and location services used in many popular apps making it one of the best alternatives for Google Maps. In this tutorial, we are going delve step-by-step into creating custom markers, annotations, polylines and polygons using Mapbox.

Let's Get Started

In order to use Mapbox, make sure to sign up for an account here. Click on the "Start mapping for free" button which will navigate you to the sign-up page. But if you already have an account, you can alternatively login with your username or email.

After signing in, you can see the access token in the dashboard screen which you will need to go ahead. Refer to the picture below: Screenshot 2021-06-28 at 6.02.28 PM.png

The next step is to go forward is to create a React Native project using the steps given here.

Adding Mapbox Maps SDK for React Native

  • Now, we are going to set up Mapbox in our React for which we need a @react-native-mapbox-gl/maps npm package which we can install using the command given below:
yarn add @react-native-mapbox-gl/maps
  • Alternatively, you can also use the following command:
npm install @react-native-mapbox-gl/maps --save
  • For iOS, we need to setup the Mapbox manually as part of the installation process. Add these following lines in your iOS podfile to achieve this:
pre_install do |installer|
    $RNMBGL.pre_install(installer)
    ... other pre install hooks
  end

  post_install do |installer|
    $RNMBGL.post_install(installer)
    ... other post install hooks
  end

 pod 'react-native-mapbox-gl', :path => '../node_modules/@react-native-mapbox-gl/maps'
  • Don't forget to run pod install in the iOS directory after installation using the following code:
cd ios && pod install && cd ..

Note: For more information, refer to the guide here.

  • As we proceed to the next step, we will have to change the content within the app.js to remove the default code. Use the following code to do this:
import React, {  useState } from "react";
import { View, StyleSheet, Text,  Image } from "react-native";
import MapboxGL from "@react-native-mapbox-gl/maps";
  • After this, we will have to set the access token on MapboxGL as the Mapbox dashboard already has the default token. Copy and paste the code given below in place of the YOUR_MAPBOX_ACCESS_TOKEN:
MapboxGL.setAccessToken("YOUR_MAPBOX_ACCESS_TOKEN");
  • Next, we are going to create App.js component using functional components as shown below:
const App = () => {
}

export default App;

Adding MapView, Camera and Point Annotation

  • MapView provides an embeddable map interface which you can use to display map information and to manipulate the map contents from your application. You can execute this by centering the map on a given coordinate and specifying the size of the area you want to display as well as the style of the features of the map to fit your application's use case.
  • Meanwhile, Camera is the map's field of view in maps that use Mapbox GL. The camera's viewport is determined by several factors like Center which coordinates the centre of the map and Zoom level which is a number used to determine how close the viewport is to the surface of the maps. For detailed information, refer here .
  • PointAnnotation is used to render the point on a map using certain props. One of the props, namely the coordinate prop( const [coordinates] = useState([longitude,latitude]);), shows us where this point would be located on the map. Use the following code to go ahead:
const App =()=> {
   const [coordinates] = useState([78.9629, 20.5937]);

    return (
     <View style={styles.page}>
        <View style={styles.container}>
          <MapboxGL.MapView style={styles.map}>
            <MapboxGL.Camera
              zoomLevel={4}
              centerCoordinate={coordinates}
            />
            <MapboxGL.PointAnnotation coordinate={coordinates} />
          </MapboxGL.MapView>
        </View>
      </View>
    );
}

const styles = StyleSheet.create({
  page: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#F5FCFF"
  },
  container: {
  height: '100%',
    width: '100%',
    backgroundColor: 'blue',
  },
  map: {
    flex: 1
  }
});

Adding Custom Annotations

You can also add custom annotations in Mapbox which you can use to represent data of points, such as restaurants in a city, bus stops along a route, or earthquake locations. Let's create a function to show our annotation point:

const renderAnnotations = () => {
    return (
      <MapboxGL.PointAnnotation
        key="pointAnnotation"
        id="pointAnnotation"
        coordinate={[74, 27]}
      >
        <View
          style={{
            height: 30,
            width: 30,
            backgroundColor: "red",
            borderRadius: 50,
            borderColor: "#fff",
            borderWidth: 3,
          }}
        />
      </MapboxGL.PointAnnotation>
    );
  };

Next, we have to call this function in the MapView component as shown below:

<View style={styles.page}>
     <View style={styles.container}>
     <MapboxGL.MapView style={styles.map}>
     <MapboxGL.Camera zoomLevel={4} centerCoordinate={coordinates} />
     <MapboxGL.PointAnnotation coordinate={coordinates} />
      <View>{renderAnnotations()}</View>
      </MapboxGL.MapView>
 </View>
</View>

Adding Custom Marker

  • MarkerView provides a simplified way to add map markers. You can use annotations to represent point data, such as restaurants in a city, bus stops along a route, or earthquake locations. Refer to the code below:
 <MapboxGL.MarkerView id={"marker"} coordinate={[72, 23]}>
            <View>
              <View style={styles.markerContainer}>
                <View style={styles.textContainer}>
                  <Text style={styles.text}>{"Gujarat"}</Text>
                </View>
                <Image
                  source={require("./location.jpeg")}
                  style={{
                    width: 20,
                    height: 30,
                    backgroundColor: "red",
                    resizeMode: "cover",
                  }}
                />
              </View>
            </View>
   </MapboxGL.MarkerView>
  • The next step is to add following code in your stylesheet:
markerContainer: {
    alignItems: "center",
    width: 60,
    backgroundColor: "transparent",
    height: 70,
  },
  textContainer: {
    backgroundColor: "white",
    borderRadius: 10,
    flex: 1,
    flexDirection: "row",
    alignItems: "center",
  },
  text: {
    textAlign: "center",
    paddingHorizontal: 5,
    flex: 1,
  },
  • Finally, add the path of your Image tag into the source attribute section to commence adding your marker.

Adding Polylines

Polylines are lines that connects two or more points on a map. The map provided by Mapbox doesn't have a Polyline component by default; but, we can leverage other components to gives us the same result that we derive from the polyline results on Google Maps. To add a polyline on the map, we would be using the ShapeSource and LineLayer components which are provided by Mapbox.

  • ShapeSource is a map content source that supplies vector shapes which can be shown on the map. The shape may be a URL or a GeoJSON object.

  • LineLayer is used to configure the visual appearance of polyline.

To start off, define the route in which you want to add the polyline, whose route should conditionally be a GeoJSON object. I am using useState to store the route in this instance. Refer to the code given below to go ahead.

   const [route, setRoute] = useState({
    type: "FeatureCollection",
    features: [
      {
        type: "Feature",
        properties: {},
        geometry: {
          type: "LineString",
          coordinates: [
            [77.5946, 12.9716],
            [80.2707, 13.0827],
          ],
        },
      },
    ],
  });
  • In the next step, add the following code inside MapboxGL.Camera:
<MapboxGL.ShapeSource id="line1" shape={route}>
    <MapboxGL.LineLayer
      id="linelayer1"
      style={{ lineColor: "red", lineWidth: 5 }}
      />
</MapboxGL.ShapeSource>

Adding Polygons

A polygon is a geospatial feature defined by connected pairs of latitude and longitude coordinates that form an area with at least three sides. You can represent the data of a polygon by using a fill layer or a fill extrusion layer. A FillLayer defines a filled polygon with an optional stroked border. Start off by defining the route in which you want to have polygon and use the code given below:

  const [polygon, setPolygon] = useState({
    type: "Feature",
    geometry: {
      type: "Polygon",
      coordinates: [
        [
          [72.685547, 20.055931],
          [76.640625, 21.207458],
          [76.904297, 17.978733],
          [72.685547, 20.055931],
        ],
      ],
    },
  });
  • In the next step, add the following code inside the MapboxGL.MapView component for the desired results:
<MapboxGL.ShapeSource id="source" shape={polygon}>
          <MapboxGL.FillLayer id="fill" style={{ fillColor: "blue" }} />
           <MapboxGL.LineLayer
            id="line"
            style={{ lineColor: "red", lineWidth: 2 }}
          />
</MapboxGL.ShapeSource>

Results

Following is a pictorial representation of what implementing Mapbox on your iOS and Android application would look like respectively:

Screenshot 2021-07-13 at 3.15.14 PM.png

Wrapping Up

Yeah, that's a wrap! Thank you so much for reading, I hope this article has broadened your horizon about Mapbox and its various components while prompting you to give it a shot. You can find the consolidated code in my GitHub repo:

Click here to see the code