Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

開始点、終了点を指定してラインを分割する

指定した緯度経度から最も距離の短い線分上の緯度経度を返す では、「ライン上の点」を描画しましたが、マウス座標に最も近い「ライン上のライン」を描くにはどうしたらよいでしょうか。

こんなやつです。

cap.gif

最も距離の短い線分上の座標を求めて、その点でラインを分割する?
いえ turf.js なら lineSlice で一撃です。

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 lineFeature = {
  type: 'FeatureCollection',
  features: [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type":"LineString",
        "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('lineOnLine', {
    'type': 'geojson',
    'data': lineFeature
  });
  lineSource = map.getSource('lineOnLine');

  map.addLayer({
    'id': 'lineOnLine',
    'type': 'line',
    'source': 'lineOnLine',
    'layout': {
      'line-join': 'round',
      'line-cap': 'round'
    },
    'paint': {
      'line-color': 'red',
      'line-width': 12
    }
  });

  map.on('mousemove', e => {

    const start = routeSource.data.geometry.coordinates[0];
    const end = e.lngLat;
    const slicedLine = turf.lineSlice([start[0], start[1]], end.toArray(), routeSource.data);

    lineSource.setData(slicedLine);
  });

});

使い方は turf.lineSlice(開始座標, 終了座標, ライン) です。
開始座標, 終了座標 はライン上の点である必要はなく、離れた点を指定すると「最も近いライン上の点」が使用されます。
この例では、開始座標はラインの始点に固定し、終了座標をマウス位置の緯度経度とすることで、マウスに追従してラインが伸び縮みさせています。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?