Custom Maps on react-native-maps And react-google-maps
Using Open Data Shapefiles
Read the original article on Sicara’s website here.
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>
}
/>
);
}
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 using
import shapefile as shp
from matplotlib import pyplot as pshp_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:
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 :
- New York Boroughs
- New York’s Police precincts
- France cities (or “communes”)
- Paris, Lyon, and Marseille’s districts (or “arrondissements”)
British National Grid :
France’s Lambert93 :
- France’s Iris
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 and let me know if you encounter more challenges!