緯度経度群(LineString)を、一定距離ごとに分割したいというニッチな要求にも応えてくれる turfjs すごい。
例えば、東京-名古屋-大阪 を結ぶ LineString があるとします。
const line = turf.lineString([[139.76, 35.68], [136.90, 35.17], [135.51, 34.68]]);
これを、turf.lineChunk を使って「100km 毎に分割」します。
const chunk = turf.lineChunk(line, 100, { units: 'kilometers' }) as FeatureCollection;
100km ごとに分割された図形群は FeatureCollection
として返却されます。
Feature
型は少々冗長なので、図形の座標群だけ抜き出すと次のように。
[
[
[ 139.76, 35.68 ],
[ 138.67760192668752, 35.49567029653387 ]
],
[
[ 138.67760192668752, 35.49567029653387],
[ 137.60028816204638, 35.30171921680228]
],
[
[ 137.60028816204638, 35.30171921680228 ],
[ 136.9, 35.17 ],
[ 136.54843014074316, 35.04811131423963 ]
],
[
[ 136.54843014074316, 35.04811131423963 ],
[ 135.54211990949918, 34.69156812570359 ]
],
[
[ 135.54211990949918, 34.69156812570359 ],
[ 135.51, 34.68 ]
]
]
東京-名古屋-大阪 のポリラインを 100km ごとに分割したら、5つの LineString になった、ということです。
そして、3つ目の要素は経由地である名古屋の緯度経度を含んでいるため、ここだけ要素数が3になっています。純粋に 100km 間隔のポリラインを得たいならば、先頭の点だけ(終点は末端だけ)を抽出すればよいことになります。
次の例は、東京-名古屋-大阪 のポリラインを 300 等分して、それぞれの標高を取得し、断面図を作る処理です(elevationService
は、地理院地図の標高タイルを使って標高APIを作る を見てね)。
const line = turf.lineString([[139.76, 35.68], [136.90, 35.17], [135.51, 34.68]]);
const len = turf.length(line, { units: 'kilometers' });
const chunk = turf.lineChunk(line, len / 300, { units: 'kilometers' }) as FeatureCollection;
const points = chunk.features.map((f, index) => {
const ln = f.geometry as LineString;
if (index < chunk.features.length - 1) {
return ln.coordinates[0];
} else {
return ln.coordinates.slice(-1)[0];
}
});
const elevations = await this.elevationService.getElevations(
points.map(p => ({ lat: p[1], lng: p[0] }))
);
console.log(`elevations`, JSON.stringify(elevations));
elevations
を EXCEL などを使ってプロットすると、次のようになります。
これは、地理院地図の 断面図作成 を模したものです。
地理院地図を使って、東京-名古屋-大阪の断面図を作ると、次のようになります。
ほぼ同じ見た目を再現できたんじゃあないかと思います。
ちなみに、「ポリラインの開始点から距離 x 進んだ座標(緯度経度)」を得るには、turf.along が便利です。