JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.34.0/mapbox-gl.css">
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.34.0/mapbox-gl.js"></script>
<script src="https://d3js.org/d3-collection.v1.min.js"></script>
<script src="https://d3js.org/d3-dispatch.v1.min.js"></script>
<script src="https://d3js.org/d3-dsv.v1.min.js"></script>
<script src="https://d3js.org/d3-request.v1.min.js"></script>
<div id='map'></div>
CSS
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
JavaScript
/* global mapboxgl, d3, geojsonExtent */
mapboxgl.accessToken = 'pk.eyJ1IjoiZ21hY2xlbm5hbiIsImEiOiJSaWVtd2lRIn0.ASYMZE2HhwkAw4Vt7SavEg'
var data
var pending = 2
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v9', // stylesheet location
center: [-76.7, -0.7], // starting position
zoom: 7, // starting zoom
maxBounds: [-87, -9, -70, 6]
}).on('load', done)
d3.json('https://lab.digital-democracy.org/alianza-ceibo-maps/data.json', function (err, _data) {
if (err) return console.error(err)
data = _data['Land Title Area']
done()
})
function done () {
if (--pending > 0) return
var landTitleAreas = prepare(data)
map.addSource('land-title-areas', {
type: 'geojson',
data: landTitleAreas
})
map.addLayer({
id: 'land-title-areas',
type: 'fill',
source: 'land-title-areas',
layout: {},
paint: {
'fill-color': '#088',
'fill-opacity': 0.5
}
})
map.addLayer({
id: 'land-title-areas-highlight',
type: 'fill',
source: 'land-title-areas',
layout: {},
paint: {
'fill-opacity': 1
},
filter: ['==', '_id', '']
})
map.on('mousemove', function (e) {
var areas = map.queryRenderedFeatures(e.point, { layers: ['land-title-areas'] })
if (!areas.length) {
map.getCanvas().style.cursor = ''
map.setFilter('land-title-areas-highlight', ['==', '_id', ''])
return
}
// Change the cursor style as a UI indicator.
map.getCanvas().style.cursor = 'pointer'
map.setFilter('land-title-areas-highlight', ['==', '_id', areas[0].properties._id])
})
}
// Only return features with geometry,
// remote props & add _id prop
function prepare (fc) {
return {
type: 'FeatureCollection',
features: fc.features
.filter(function (f) { return f.geometry })
.map(function (f) {return {
type: 'Feature',
geometry: f.geometry,
properties: {_id: f.id},
id: f.id
...