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群を取得します。
これらは元データを参照して行われるので、その場所が描画されているかどうかにかかわらず同じ値を返します。