1
1

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-09-25

mapbox GL JSで、例えば

    map.on('click', 'fillmesh', (e) => {
        const geom = e.features[0].geometry;
          :

のようにすればクリックした要素のgeometry(meshの形)が返ってきます。
ですが、これは表示領域で整形された形であり、元データが下記

const cityMeshAll =
{"type": "FeatureCollection","features":[
{"type":"Feature","properties":{"code":"1208","pref":"北海道","c3":"","c4":"北見市"},"geometry":{"type":"Polygon","coordinates":[[[144.1224,44.1157],[144.1082,44.12],[144.1042,44.1256],[144.0935,44.1271],[144.0821,44.1243],[144.0686,44.1243],[144.0448,44.1274],[143.9832,44.1366],[143.9518,44.1423],[143.9126,44.1505],[143.8392,44.1674],[143.7892,44.1802],[143.7765,44.1847],[143.7757,44.1443],[143.911,44.1259],[143.9506,44.0909],[143.9667,44.0849],[143.9531,44.0659],[143.9464,44.06],[143.9475,44.0528],[143.9537,44.0428],[143.9524,44.0363],[143.9387,44.0307],[143.9338,44.0182],[143.9284,44.0123],[143.9159,44.01],[143.9066,44.0037],[143.9081,44],[143.8994,43.9956],[143.8935,43.9975],[143.889,43.9899],[143.8778,43.9813],[143.8632,43.9769],[143.844,43.9804],[143.8404,43.986],[143.8329,43.9834],[143.8127,43.9876],[143.8032,43.9778],[143.7934,43.9838],[143.7806,43.9753],[143.7851,43.9708],[143.781,43.9626],[143.7715,43.9527],[143.7637,43.9519],[143.7541,43.9568],[143.7467,43.956],[143.7508,43.9439],[143.7498,43.9314],[143.7569,43.9292],[143.7579,43.9202],[143.7382,43.9048],[143.7277,43.9006],[143.7208,43.8884],[143.72,43.8787],[143.7007,43.8754],[143.69,43.8862],[143.6901,43.8916],[143.6814,43.8942],[143.678,43.9046],[143.6699,43.9087],[143.6758,43.92],[143.6663,43.9252],[143.6517,43.9208],[143.646,43.9253],[143.6378,43.942],[143.6297,43.9366],[143.6164,43.9337],[143.606,43.9395],[143.6036,43.9479],[143.5878,43.9469],[143.5904,43.9399],[143.5845,43.9228],[143.5873,43.8964],[143.5835,43.8872],[143.5699,43.8792],[143.5656,43.858],[143.5726,43.8454],[143.5596,43.8401],[143.5537,43.8452],[143.5464,43.8396],[143.529,43.8352],[143.5257,43.8262],[143.5135,43.8143],[143.5057,43.8143],[143.4882,43.8094],[143.4777,43.8147],[143.4716,43.8119],[143.4526,43.8128],[143.4331,43.799],[143.4173,43.7985],[143.3988,43.7953],[143.3769,43.7979],[143.3757,43.791],[143.3617,43.7884],[143.3642,43.7823],[143.3508,43.7737],[143.3394,43.7713],[143.3369,43.7656],[143.3263,43.7642],[143.3185,43.7697],[143.307,43.7595],[143.2891,43.7635],[143.2788,43.7546],[143.2732,43.7541],[143.2697,43.7468],[143.2506,43.7387],[143.2491,43.7329],[143.2557,43.7222],[143.253,43.71],[143.2363,43.7007],[143.226,43.6968],[143.2091,43.7023],[143.1955,43.7003],[143.1817,43.7068],[143.1718,43.7069],[143.1613,43.7063],[143.1467,43.6906],[143.1462,43.6814],[143.1397,43.6777],[143.1417,43.6684],[143.1612,43.6598],[143.1625,43.6526],[143.1704,43.649],[143.1734,43.6376],[143.1558,43.6288],[143.1482,43.6159],[143.1365,43.6079],[143.1363,43.5997],[143.1425,43.5952],[143.1548,43.5915],[143.173,43.5949],[143.1745,43.6009],[143.1872,43.6079],[143.1826,43.6148],[143.1881,43.6244],[143.2088,43.6302],[143.2318,43.6413],[143.255,43.6402],[143.2576,43.6461],[143.2732,43.6463],[143.2818,43.6516],[143.3005,43.6522],[143.3178,43.6447],[143.3302,43.6439],[143.352,43.6384],[143.3554,43.6431],[143.3741,43.648],[143.3776,43.6556],[143.39,43.6554],[143.3937,43.6611],[143.4022,43.6662],[143.4113,43.6673],[143.4208,43.6641],[143.4309,43.6765],[143.4296,43.6878],[143.4366,43.6938],[143.4524,43.6928],[143.4595,43.6993],[143.4748,43.7008],[143.492,43.6988],[143.5081,43.7051],[143.525,43.7059],[143.5221,43.7117],[143.5275,43.7214],[143.5294,43.7371],[143.5347,43.7445],[143.5463,43.741],[143.5868,43.7621],[143.6254,43.7577],[143.6595,43.7759],[143.6735,43.7702],[143.6827,43.7699],[143.6984,43.7775],[143.7962,43.7838],[143.8034,43.7278],[143.7899,43.6996],[143.7909,43.6926],[143.8026,43.6865],[143.8068,43.6759],[143.8165,43.6719],[143.8199,43.6826],[143.8346,43.6944],[143.8419,43.6955],[143.8448,43.7027],[143.8531,43.7039],[143.8572,43.7092],[143.8771,43.7072],[143.8904,43.7016],[143.8982,43.7047],[143.9036,43.7146],[143.9017,43.7186],[143.9073,43.7285],[143.9132,43.7337],[143.9115,43.7396],[143.9192,43.7461],[143.9413,43.7558],[143.9446,43.7604],[143.9396,43.7669],[143.9511,43.7758],[143.9601,43.7659],[143.9726,43.7693],[143.9732,43.7826],[143.9826,43.794],[143.9935,43.8033],[143.9889,43.8114],[143.9927,43.8166],[144.0026,43.8184],[144.004,43.8263],[144.0128,43.838],[144.0116,43.8509],[144.0283,43.8596],[144.0252,43.8653],[144.057,43.8804],[144.0524,43.8878],[144.0465,43.8939],[144.0628,43.9098],[144.0635,43.9217],[144.0474,43.9201],[144.0406,43.9175],[144.0329,43.9248],[144.0293,43.9357],[144.0308,43.9433],[144.0207,43.948],[144.0228,43.9637],[144.0296,43.9647],[144.0484,43.9734],[144.0457,43.9834],[144.0544,43.9894],[144.0467,44.01],[144.0314,44.0154],[144.0366,44.0242],[144.0429,44.025],[144.0496,44.0394],[144.0476,44.0451],[144.0502,44.0547],[144.0459,44.0613],[144.0582,44.0703],[144.0586,44.0763],[144.0743,44.0927],[144.0828,44.0983],[144.0878,44.1096],[144.1018,44.1129],[144.1206,44.1096],[144.1224,44.1157]]]}}

のように定義されていたとしても、必ずしもこの形そのものが返ってくるわけではありません。

また、mapboxには
map.queryRenderedFeatures()
map.querySourceFeatures()
といった、条件に沿ったfeaturesを取得する関数が用意されていますが、これらは描画範囲に依存します。

たとえば、geometryに上記cityMeshAllからデータを直接取得し、

const gasfeatures = map.querySourceFeatures('gasStationSrc', {
    sourceLayer: 'gasStation-point',
    filter:["within", geometry],
});

のようにすればgeometry内にあるgasStation-pointレイヤーのポイント群をすべて取得できそうですが、実際には表示範囲に依存します。
またquerySourceFeatures()はTile単位で返ってくるので、重複を削除する必要もあります。
逆に言えば表示されていないTileに含まれるpointは返ってきません。

描画範囲に依存しない方法はないものかといろいろ調べてみたところ、
turf.js
という素晴らしいライブラりを見つけました。

mapboxにあるような処理は一通り揃っているので、もしかしたらmapbox内部でもこれを使用しているのかもしれません。

html内で

<script src='https://unpkg.com/@turf/turf@6/turf.min.js'></script>

のようにturf.jsを読み込むだけで使用できます。

たとえば、

map.on('click', 'fillmesh', (e) => {
       :
    var code = e.features[0].properties['code'];
    turf.geomEach(cityMeshAll, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {
        if(featureProperties['code']==code){
            g_pointFeatures = turf.pointsWithinPolygon(gasStationAll,currentGeometry);
            return;
        }
    });
       :

のようにするだけで、描画範囲にかかわらず特定geometry内のpoint群を取得することができます。

turf.geomEachはデータ群(ここでは上記cityMeshAll)内にあるすべてのデータを条件(ここでは市町村コード)でチェックします。
条件にあったデータがみつかったら、
turf.pointsWithinPolygonを用いて、見つかったgeometry内にあるpoint群を取得します。
これらは元データを参照して行われるので、その場所が描画されているかどうかにかかわらず同じ値を返します。

image.png
image.png
image.png

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?