LoginSignup
0
0

More than 3 years have passed since last update.

開始点、終了点を指定してラインを分割する(始点終点が逆だった場合)

Posted at

開始点、終了点を指定してラインを分割する の追加情報ですが。

先の例では、分割対象のラインの向きと同じ順番で分割点を指定しました。
当然分割された線も分割対象のラインと同じ向きになりました。

では、分割対象のラインの向きとは逆の順序で分割する始点終点を指定したらどうなるでしょう?

結果は次の図のようになります。

image.png

  • 分割対象のライン:グレー、始点:黒マーカー
  • 分割点:始点-赤マーカー(大)、終点-赤マーカー(小)
  • 分割されたライン:青、始点:青マーカー

ということで、 「分割点の順番に関係なく、分割されたラインは元のラインと同じ向きになる」 が正解でした。

分割開始点と分割されたラインの始点は常に近接しているとは限らない、という事に注意が必要です。

以下、コードです。

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": []
      }
    }
  ]
};

let marker;

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',
    'paint': {
      'line-color': '#0000FF',
      'line-opacity': 0.3,
      'line-width': 12,
    }
  });

  const el = document.createElement('img');
  el.src =  'https://img.icons8.com/material/32/000000/marker--v1.png';
  new mapboxgl.Marker(el)
    .setLngLat(routeSource.data.geometry.coordinates[0])
    .addTo(map);

  const fromPoint = [-122.490, 37.832];
  const toPoint   = [-122.483, 37.831];

  const elFrom = document.createElement('img');
  elFrom.src = 'https://img.icons8.com/material/32/FF0000/marker--v1.png';
  new mapboxgl.Marker(elFrom)
    .setLngLat(fromPoint)
    .addTo(map);

  const elTo = document.createElement('img');
  elTo.src =  'https://img.icons8.com/material/16/FF0000/marker--v1.png';
  new mapboxgl.Marker(elTo)
    .setLngLat(toPoint)
    .addTo(map);

  const slicedLine = turf.lineSlice(
    fromPoint, 
    toPoint, 
    routeSource.data);
  lineSource.setData(slicedLine);

  if (marker != null) {
    marker.remove();
  }

  const elSplitted = document.createElement('img');
  elSplitted.src =  'https://img.icons8.com/material/32/0000FF/marker--v1.png';
  marker = new mapboxgl.Marker(elSplitted)
    .setLngLat(slicedLine.geometry.coordinates[0])
    .addTo(map);
});

参考

0
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
0
0