Skip to content

Instantly share code, notes, and snippets.

@sethvincent
Last active September 12, 2019 12:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sethvincent/c0d7ba16fe83d87b95b399dffcbb4f1c to your computer and use it in GitHub Desktop.
Save sethvincent/c0d7ba16fe83d87b95b399dffcbb4f1c to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Select features around a clicked point</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.3.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.3.1/mapbox-gl.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script src="/bundle.js"></script>
</body>
</html>
/* eslint-disable */
import nearestPointOnLine from '@turf/nearest-point-on-line';
import distance from '@turf/distance';
import { point } from '@turf/helpers';
mapboxgl.accessToken = 'pk.eyJ1Ijoic2V0aHZpbmNlbnQiLCJhIjoiSXZZXzZnUSJ9.Nr_zKa-4Ztcmc1Ypl0k5nw';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [34.7989131, -19.7768669],
zoom: 6
});
let marker = null;
map.on('load', function() {
map.on('click', function(e) {
console.log('e.point', e.point)
console.log('e.lngLat', e.lngLat)
console.log('e.originalEvent.clientX, e.originalEvent.clientY', e.originalEvent.clientX, e.originalEvent.clientY)
const clickPoint = point([e.lngLat.lng, e.lngLat.lat]);
const bbox = [[e.point.x - 50, e.point.y - 50], [e.point.x + 50, e.point.y + 50]];
let features = map.queryRenderedFeatures(bbox, {
filter: ['==', '$type', 'LineString']
});
features = features.filter((feature) => {
// TODO: better filtering to remove things like admin boundaries
// console.log('feature.properties.clickDistance', feature.properties.clickDistance);
const nearestPoint = nearestPointOnLine(feature, clickPoint);
console.log('nearestPoint', nearestPoint);
feature.properties.clickDistance = distance(clickPoint, nearestPoint);
feature.properties.pointOnLine = nearestPoint;
return feature;
});
features.sort((a, b) => {
return a.properties.clickDistance - b.properties.clickDistance;
});
console.log('features[0]', features[0])
if (features.length) {
drawLine(features[0].geometry);
drawMarker(features[0].properties.pointOnLine.geometry.coordinates)
}
});
function drawLine (geojson) {
const source = map.getSource('nearest-line');
if (!source) {
map.addSource('nearest-line', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [{ type: 'Feature', geometry: geojson }]
}
});
map.addLayer({
id: 'nearest-line',
type: 'line',
source: 'nearest-line',
paint: {
'line-color': 'red',
'line-width': 2.5
}
});
} else {
source.setData({
type: 'FeatureCollection',
features: [{
type: 'Feature',
geometry: geojson
}]
});
}
}
function drawMarker (coord) {
if (!marker) {
marker = new mapboxgl.Marker()
marker
.setLngLat(coord)
.addTo(map)
}
marker
.setLngLat(coord)
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment