Skip to content

Instantly share code, notes, and snippets.

@mrchocoborider
Last active July 26, 2018 21:03
Show Gist options
  • Save mrchocoborider/8f5672afa4f577cf788daea89e7f3717 to your computer and use it in GitHub Desktop.
Save mrchocoborider/8f5672afa4f577cf788daea89e7f3717 to your computer and use it in GitHub Desktop.
Sf Parks with proximity detection
license: mit

This is a project I worked on for the Maptime SF Meetup event hosted on June 19th at the MapBox office in San Francisco.

It is based on this tutorial provided by the lovely folks at MapBox.

I used mapbox studio and the geojson provided for the layers and the data, and used the mapbox-gl-js library and turf.js for the interactive funcionality.

Click anywhere on the map and the closest park to your clicked location will be highlighted. You can also click on the parks to see their names.

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Points on a map</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.css' rel='stylesheet' />
<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoibXJjaG9jb2JvcmlkZXIiLCJhIjoiN1ZsaE9KcyJ9._2FgQkxkkcb12TDYflWrFw'; // replace this with your access token
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mrchocoborider/cjikkrpn03lkb2so0gxcxlbu0', // replace this with your style URL
center: [-122.447916, 37.760038],
zoom: 10
});
map.on('load', function() {
// Add a single point to the map
map.addSource('point', {
"type": "geojson",
"data": geojson
});
map.addLayer({
"id": "point",
"type": "circle",
"source": "point",
"paint": {
"circle-radius": 5,
"circle-color": "#3887be",
"circle-opacity": 0
}
});
});
//this will be the data for the point layer
var geojson = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.447916, 37.760038]
}
}]
};
//Intermediate tutorial sample code
map.on('click', function(e) {
var pfeatures = map.queryRenderedFeatures(e.point, {
layers: ['sf-parks']
});
var point = [e.lngLat.lng, e.lngLat.lat];
//let's make a dot at the clicked location!
geojson.features[0].geometry.coordinates = point;
map.getSource('point').setData(geojson);
map.setPaintProperty("point", "circle-opacity", 1);
// if (!pfeatures.length) {
if (pfeatures.length > 0) {
var pfeature = pfeatures[0];
var popup = new mapboxgl.Popup({ offset: [0, -15] })
.setLngLat(pfeature.geometry.coordinates)
.setHTML('<h3>' + pfeature.properties.name + '</h3>')
.setLngLat(pfeature.geometry.coordinates)
.addTo(map);
//console.log('found one');
// if they click on a park, don't put down the location point
map.setPaintProperty("point", "circle-opacity", 0);
}
//Here I'm writing the code for the challenge: Which park is closer to your location
//I'll write a function to check which park is closer to any given point on click
//get all the features to compare to the clicked point
var features = map.queryRenderedFeatures({layers:['sf-parks']});
//loop through the features, get distance from current point to each of them, and see which one is smallest.
var distnames = []
var distances = []
for (var i = 0; i < features.length; i++){
var distance = turf.distance(features[i].geometry.coordinates, point, {units:'miles'});
var ddict = {'name':features[i].properties.name, 'distance':distance}
distnames.push(ddict)
distances.push(distance)
}
//find the shortest distance
var shortest = Math.min(...distances);
//console.log(distances);
console.log(shortest);
//find the name of the park with corresponding shortest distance
//console.log(distnames);
for (var i = 0; i < distnames.length; i++){
if (distnames[i]['distance'] == shortest){
console.log(distnames[i]['name']);
map.setFilter("sf-parks-highlight", ["==", "name", distnames[i]['name']]);
map.setPaintProperty("sf-parks-highlight", "circle-opacity", 1);
//map.setPaintProperty("sf-parks-highlight", "circle-opacity", 1);
}
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment