文字で説明するとよくわからないので、インタラクティブに表すと次の図のようなものです。
マウスカーソルの位置に最も近い、線分(LineString)上の点を赤で描画しています。
これは turf.js の nearestPointOnLine
を使用します。
// <script src='https://unpkg.com/@turf/turf/turf.min.js'></script>
const routeSource = {
'type': 'geojson',
'data': {
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'LineString',
'coordinates': [
[-122.48369693756104, 37.83381888486939],
[-122.48356819152832, 37.82954808664175],
[-122.48751640319824, 37.83168351665737],
[-122.49223709106445, 37.83337825839438],
[-122.49378204345702, 37.83368330777276]
]
}
}
};
const pointFeature = {
type: 'FeatureCollection',
features: [
{
"type": "Feature",
"properties": {},
"geometry": {
"type":"Point",
"coordinates": []
}
}
]
};
const map = new mapboxgl.Map({
container: 'map',
center: [-122.486052, 37.830348],
zoom: 15,
style: {
version: 8,
sources: {
OSM: {
type: "raster",
tiles: [
"https://a.tile.openstreetmap.org/{z}/{x}/{y}.png",
],
tileSize: 256,
attribution:
"OpenStreetMap",
},
},
layers: [{
id: "BASEMAP",
type: "raster",
source: "OSM",
minzoom: 0,
maxzoom: 18,
}],
},
});
map.once('load', () => {
map.addSource('route', routeSource);
map.addLayer({
'id': 'route',
'type': 'line',
'source': 'route',
'layout': {
'line-join': 'round',
'line-cap': 'round'
},
'paint': {
'line-color': '#888',
'line-width': 8
}
});
map.addSource('pointOnLine', {
'type': 'geojson',
'data': pointFeature
});
pointSource = map.getSource('pointOnLine');
map.addLayer({
'id': 'pointOnLine',
'source': 'pointOnLine',
'type': 'circle',
'paint': {
'circle-radius': 10,
'circle-color': "red",
'circle-opacity': 0.7,
}
});
map.on('mousemove', e => {
const start = routeSource.data.geometry.coordinates[0];
const nearest = turf.nearestPointOnLine(routeSource.data,
[e.lngLat.lng, e.lngLat.lat], { units: 'kilometers' });
// console.log(nearest);
pointSource.setData(nearest);
});
});
動くサンプルということでだらだらと長いコードになってしまったけれど、重要なのは map.on('mousemove', e => {
のマウスカーソルが移動した時のハンドラです。
nearestPointOnLine(lineStringFeature, [lng, lat], { units: 'kilometers' })
という感じで呼び出します。
返値が 『lineStringFeature
上にある [lng, lat]
から最も近い点』です。
あとはこれを MapBox GL JS を使って描画しています。