1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Mapbox GL JS 円をつなぐ線を得る

Last updated at Posted at 2022-10-02

とあるハッカソンで、台風の進路を投票で決めるというジョークアプリを作成しました。
image.png
動画

アプリ製作にはmapboxを用い、補助としてTurf.jsを使用しました。
Turf.js、めちゃめちゃ便利でmapboxでの開発速度が爆上がりしたのですが、
さすがに「円のリストをつなぐ線を引く」といった関数まではなかったので用意しました。
Turf.jsを利用しているのでとても簡単に実装できています。

// get 2vertices line array from circle array
// in:[{coord:[lng,lat],radius:r},{coord:[lng,lat],radius:r},{},...]
// out [lineStringGeojson,lineStringGeojson,...]
getEmvelopeLineArrayFromCirclleArray = function(_circleArray){
    var outArr=[];
    if(_circleArray.length > 1){
        for(var i=0;i<_circleArray.length-1;++i){
            // 1番目の円の中心
            var pt0 = turf.point(_circleArray[i+0].coord);
            // 2番目の円の中心
            var pt1 = turf.point(_circleArray[i+1].coord);
            // 直線pt0-pt1の角度
            var ang = turf.rhumbBearing(pt0,pt1, {units: 'kilometers'});
            var pos0a = turf.rhumbDestination(pt0,_circleArray[i+0].radius,ang-90, {units: 'kilometers'}); // pt0から、直線pt0-pt1に垂直で、距離が1番目の円の半径である場所
            var pos0b = turf.rhumbDestination(pt0,_circleArray[i+0].radius,ang+90, {units: 'kilometers'}); // pt0から、直線pt0-pt1に垂直で、距離が1番目の円の半径である場所(反対側)
            var pos1a = turf.rhumbDestination(pt1,_circleArray[i+1].radius,ang-90, {units: 'kilometers'}); // pt0から、直線pt0-pt1に垂直で、距離が2番目の円の半径である場所
            var pos1b = turf.rhumbDestination(pt1,_circleArray[i+1].radius,ang+90, {units: 'kilometers'}); // pt0から、直線pt0-pt1に垂直で、距離が2番目の円の半径である場所(反対側)
            outArr.push(turf.lineString([pos0a.geometry.coordinates,pos1a.geometry.coordinates])); // 直線geojsonを作成してpush
            outArr.push(turf.lineString([pos0b.geometry.coordinates,pos1b.geometry.coordinates]));
        }
    }
    return outArr;
}

円のリストを渡すと頂点数2のLineリストが返ってくるので、

var LineArr = getEmvelopeLineArrayFromCirclleArray(tmpCircleArr);
if (!map.getSource('multiLineEmvSrc')){
    map.addSource('multiLineEmvSrc', {
        'type': 'geojson',
        'data': {'type': 'FeatureCollection', 'features': LineArr}
    });
}
if (!map.getLayer('multiLineEmv')){
    map.addLayer({
        'id':'multiLineEmv',
        'type':'line',
        'source':'multiLineEmvSrc',
        'layout': {},
        'paint': {
            'line-color': '#fff',
            'line-width': 1,
            'line-opacity': 0.5
        }
    });
}

のようにaddSource()/addLayer()してあげると円を結ぶ線を引いてくれます。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?