Map using React map gl .

Edison Devadoss
3 min readDec 12, 2019

--

Friends, in this article, I will explain how to integrate map with geojson data using react-map-gl.

map box logo

React map gl using map box API. Map box is like google map. It provides token and uses this token in your code.

Many of the famous organization using map box.

https://www.mapbox.com/showcase/

Once you get token from map box. Then move to code.

Install dependencies

npm install --save react-map-gl d3-array d3-request d3-scale moment

I stored geojson file, in my git. Click here for file.

In that geojson it has the geolocation information of four southern states of India.

Setup

import React, { Component } from 'react';
import { render } from 'react-dom';
import MapGL, { Source, Layer } from 'react-map-gl';
import ControlPanel from './control-panel';
import { dataLayer } from './map-style.js';
import { updatePercentiles } from './utils';
import LegenPanel from './legend-panel';
const MAPBOX_TOKEN = '';export default class App extends Component {
constructor(props) {
super(props)
this.state = {
year: 2015,
week: 1,
month: 1,
data: null,
hoveredFeature: null,
viewport: {
width: '100vm',
height: '100vh',
latitude: 20.5937,
longitude: 78.9626,
zoom: 4.3,
bearing: 0,
pitch: 0
}
};
}
componentDidMount() {
fetch('./data.geojson').then((res) => {
return res.json();
}).then((result) => {
this._loadData(result);
})
})
}_loadData = data => {
updatePercentiles(data, f => f.properties.units[this.state.month]);
this.setState({ data });
};
render() {
const { viewport, data } = this.state;
return (
<div style={{
height: '100%'
}}>
<MapGL {...viewport}
onViewportChange={this._onViewportChange} mapboxApiAccessToken={MAPBOX_TOKEN} onHover={this._onHover}>
<Source type="geojson" data={data}>
<Layer {...dataLayer} />
</Source>
{this._renderTooltip()}
</MapGL>
<ControlPanel containerComponent={this.props.containerComponent} settings={this.state} onChange={this._updateSettings} />
<LegenPanel containerComponent={this.props.containerComponent} />
</div>
);
}
}
export function renderToDom(container) {
render(<App />, container);
}

The above code I mention get geojson data from public folder and I passed to source tag. And pass in in data layer.

<Source type="geojson" data={data}>
<Layer {...dataLayer} />
</Source>

The style for the layer.

export const dataLayer = {
id: 'data',
type: 'fill',
paint: {
'fill-color': {
property: 'value',
stops: [
[0, '#F2F12D'],
[1, '#EED322'],
[2, '#E6B71E'],
[3, '#DA9C20'],
[4, '#CA8323'],
[5, '#B86B25'],
[6, '#A25626'],
[7, '#8B4225'],
[8, '#723122']
]
},
'fill-opacity': 0.8
}
};

It takes style for mark states.

In this example, I have a control panel and legend also.

I changed data using the control panel. In this control panel, I changed for each month.

Control panel style.

import React, { PureComponent } from 'react';
import moment from 'moment';
const defaultContainer = ({ children }) => <div className="control-panel">{children}</div>;export default class ControlPanel extends PureComponent {
render() {
const Container = this.props.containerComponent || defaultContainer;
const { settings } = this.props;
const getDate = (number) => {
let date = moment('2019').add(number - 1, 'months');
return date.format('MMM-YYYY')
}
return (
<Container>
<h3>Events by state</h3>
<p>
Map showing the number of CISF events for the month of
<b>{getDate(settings.month)}</b>. Hover over a state to see details.
</p>
<hr />
<div key={'month'} className="input">
<label>Month</label>
<input type="range" value={settings.month} min={1} max={12} step={1} onChange={evt => this.props.onChange('month', evt.target.value)} />
</div>
</Container>
);
}
}

Legend styles

import React, { PureComponent } from 'react';const defaultContainer = ({ children }) => <div className="legend-panel">{children}</div>;const colors = [
[
0, '#F2F12D'
],
[
1, '#EED322'
],
[
2, '#E6B71E'
],
[
3, '#DA9C20'
],
[
4, '#CA8323'
],
[
5, '#B86B25'
],
[
6, '#A25626'
],
[
7, '#8B4225'
],
[
8, '#723122'
]
]
export default class LegenPanel extends PureComponent {
render() {
const Container = this.props.containerComponent || defaultContainer;
return (
<Container>
<label>Events</label>
{
colors.map((vaue) => {
return (<div key={vaue[0]} className="input">
<label>{vaue[0]}
</label>
<input className="legend-input" type="color" value={vaue[1]} disabled={true}
// onChange={this._onColorChange.bind(this, name)}
/>
</div>
)
})
}
</Container>
);
}
}

Below I attached my code link.

--

--

Edison Devadoss
Edison Devadoss

Written by Edison Devadoss

Software Engineer / Full Stack Developer / JavaScript / React / React Native / Firebase / Node.js / Book Reader

No responses yet