LoginSignup
1
0

More than 3 years have passed since last update.

指定した緯度経度から最も距離の短い線分上の緯度経度を返す

Last updated at Posted at 2020-12-01

文字で説明するとよくわからないので、インタラクティブに表すと次の図のようなものです。

cap.gif

マウスカーソルの位置に最も近い、線分(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 を使って描画しています。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0