April 28, 2017

Custom Maps on react-native-maps And react-google-maps

Using Open Data Shapefiles
nyc map
Layouts on New York boroughs (from the app SafeAround)

I recently worked on a React-Native mobile project that shows administrative divisions of countries in a colour depending on its crime rate. I found that many countries and cities provide freely their Geographical Data generated with specialized softwares known as GIS. Digging into data.gouv.fr, the french Open Data website, I bumped into a shapefile describing the french administrative divisions.

Here’s what I learnt that will save you some trial and error time.

What I worked with to render a map easily

I had to show both a map on a mobile and web app. As we developed the mobile app using React Native, we used the airbnb’s component react-native-maps which revealed itself both simple to use and efficient. Here is a sample of a working React Native map component that draws polygons.

import MapView from 'react-native-maps';

export default function Map(props) {
  render() {
    return (
      <MapView>
        {this.state.polygons.map(polygon =>
          (<MapView.Polygon
            key={polygon.id}
            coordinates={polygon.coordinates}
            fillColor='red'
            strokeColor='black'
          />),
        )}
      </MapView>
    );
  }
}

Regarding the React web app, we inserted Google maps using the react-google-maps module. Here are few lines to generate a Google map.

import React from 'react';
import { GoogleMapLoader, GoogleMap, Polygon } from 'react-google-maps';

export default function Map(props) {
  return (
    <GoogleMapLoader
      containerElement={
        <div
          style={{
            height: '400px',
          }}
          {...props.containerProps}
        />
      }
      googleMapElement={
        <GoogleMap>
          {props.polygons.map((polygon, index) => {
              return (
                <Polygon
                  key={index}
                  paths={polygon.coordinates}
                  options={{
                    strokeWeight: 1,
                    fillColor: 'red',
                    fillOpacity: 1,
                    strokeColor: 'black',
                  }}
                />
              );
            })}
        </GoogleMap>
      }
    />
  );
}

nyc map
New York boroughs drawn using react-google-maps (from the app SafeAround)

What is a shapefile?

Shapefile is a commonly used data format, mostly generated by free geographical softwares (known as GIS). ShapeFiles are actually not single files but a collection of many different ones, including generally:

  • .shp : gathers the coordinates of each polygons

  • .dbf : information about the shapes (name, area, …)

  • .prj : describes the projection used (usually, coordinates are not provided using longitude - latitude)

  • .shx : provides an index over shapes to find neighboring shapes

  • .cpg : text encoding used (UTF-8, Latin-1, us-ascii …)

How can I read shapefiles using python?

You need only two libraries : pyshp and dbfread. You can print the data you have been using

import shapefile as shp
from matplotlib import pyplot as p

shp_file_path = ‘MyShapeFile.shp’
my_shapes = shp.Reader(shp_file_path).shapes()
my_shapes_list = list(map(lambda shape: shape.points, my_shapes))
print('Number of shapes : %s' % len(my_shapes_list))

for shape in my_shapes_list:
    longitude, latitude = zip(*shape)
    p.plot(longitude, latitude)
p.show()

For example, printing the USA counties boundaries:

usa counties boundaries

You can then link each shape from the .shp to its metadata provided in the .dbf using the following code. The metadata in the .dbf are listed in the same order as their associated polygons in the .shp file.

from dbfread import DBF

dbf_file_path = 'usaCountiesShapeFile.dbf'
counties_information_list = DBF(dbf_file_path, load=True, 
encoding='utf-8').records
print('first county : %s' % counties_information_list[0])

Why do English coordinates not look like lat/long ?

The standard latitude-longitude coordinates format is called WGS84 (World Geodetic System, created in 1984).

However, you might encounter strange coordinates used in your ShapeFile. Even worse, most projections used are not a linear transformation of the longitude-latitude format!

For example, you can find London wards here, but coordinates are provided using the British National Grid projection : they look like (530000, 180000).  Don’t panic, The GitHub user profLewis provides a python function to help! It converts British National Grid projection (OSGB36) to longitude-latitude coordinates (known as WGS84).

Same thing goes for French coordinates: the administrative sections ‘Iris’ are provided on data.gouv.fr using Lambert93, the official projection in Metropolitan France. Find here a python function to transform Lambert93 coordinates to WGS84.

The United States’ system, GCS_North_American_1983, is a tricky one as it differs from WGS84 by about a meter.

Where can I find the data?

Here are some links to the data I used!

Latitude-Longitude :

British National Grid :

France’s Lambert93 :

If you look for other data, many countries have their own Open Data platform and provide geographical subdivisions! Opendatasoft.com listed 2600+ Open Data sources which you can explore in a map.

Have fun with your maps!

Thanks to Antoine Toubhans, Charles Bochet, and Flavian Hautbois. 

This year NeurIPS is returning to Montreal.

NeurIPS (prev. NIPS) Papers Selection

My favorite research articles from NeurIPS (previously NIPS) 2018.

rboy

Basics in R Programming

You are about to begin a project on R? Before you watch any tutorial, read these basic standards.

logo loopback

Enhance Your Loopback Models with Custom mixins

This article puts light on the very useful mixins option of your model.json declaration file.