Mapboxの非表示シンボルを扱う (2. Featureの解決編)
2022-09-16 (2022-09-24 更新)
Mapbox GL JSの画面上で別のシンボルに隠されたシンボルを扱うユーティリティライブラリを開発中です。 これはライブラリの開発過程を紹介するシリーズのブログ投稿第2弾です。
背景
このシリーズの前回の投稿で、以下の疑問が残りました。
TileとSymbolBucketはどうやって取得するのか?- 再計算した衝突ボックスとシンボルのFeatureをどうやって対応づけるのか?
このブログ投稿では上記の疑問に答え、前回のブログ投稿で見落としていたアイコンの大きさを計算する方法についてもカバーします。
このライブラリはhttps://github.com/codemonger-io/mapbox-collision-boxesで手に入ります。
Mapbox GL JS (mapbox-gl-js)のバージョン2.9.2*を分析しました。
* このブログを書いている段階で最新バージョンは2.10.0でしたが、一貫性を保つためにバージョン2.9.2で続けます。
TileとSymbolBucketを取得する
前回のブログ投稿で、どのシンボルを画面に表示するかを決定するのにPlacement#placeLayerBucketPartが重要な役割を果たしていることがわかりました。
このメソッドがどのように呼び出されているかを調べれば、TileとSymbolBucketをどうやって取得するかがわかるかもしれません。
SymbolBucketを解決する
LayerPlacement#continuePlacementはPlacement#placeLayerBucketPartを繰り返し呼び出します(style/pauseable_placement.js#L50-L57)。
while this._currentPartIndex < bucketParts.length
Placement#getBucketPartsによって作成されるbucketPartsの各要素は処理の対象となるSymbolBucketを提供します(BucketPart#parameters → TileLayerParameters#bucket)。
Placement#getBucketPartsは当該メソッド3番目の引数のTileからSymbolBucketを取り出します(symbol/placement.js#L233-L234)。
results: Array<BucketPart>, styleLayer: StyleLayer, tile: Tile, sortAcrossTiles: boolean
つまり、StyleLayerとTileがあれば、SymbolBucketも手に入ります。
StyleLayerとTileを解決する
LayerPlacement#continuePlacementはPlacement#getBucketPartsを繰り返し呼び出します(style/pauseable_placement.js#L35-L43)。
while this._currentTileIndex < tiles.length
上記スニペットのtilesとstyleLayerはLayerPlacement#continuePlacementに対する引数です。
PauseablePlacement#continuePlacementはLayerPlacement#continuePlacementを繰り返し呼び出します(style/pauseable_placement.js#L97-L123, layerTiles[layer.source] → tiles, layer → styleLayer)。
while this._currentPlacementIndex >= 0
以下の条件判定(style/pauseable_placement.js#L101)からわかるとおり、PausePlacement#continuePlacementはLayerPlacement#continuePlacementを"Symbol"レイヤーにのみ適用します。
if layer.type === 'symbol' &&
上記スニペットのorder, layers, layerTilesはPauseablePlacement#continuePlacementに対する引数です。
Style#_updatePlacementはPauseablePlacement#continuePlacementを呼び出します(style/style.js#L1740)。
this._order, this._layers, layerTiles;
Style#_updatePlacementはstyle/style.js#L1696-L1712でlayerTilesを用意しています。
;
for of this._order
ということで上記コードを真似すれば、与えたレイヤーIDに対応するStyleLayerとすべてのTileを取得することができます。
レイヤーのTileとSymbolBucketをリストする
まとめると、指定したレイヤーのTileとSymbolBucketをリストするコードのアウトラインは以下のようになります。
// 仮定 map: mapboxgl.Map, layerId: string
;
;
;
;
for of layerTiles
追加のチェックを含む完成したコードは私のGitHubレポジトリにあります。
シンボルのFeatureを解決する
前回の投稿で、FeatureIndexはシンボルのFeatureを解決する上で重要であることに軽く触れました。
Map#queryRenderedFeaturesを調べることでそれがわかりました。
概要:Map#queryRenderedFeaturesがどのように機能するか
Map#queryRenderedFeaturesはStyle#queryRenderedFeaturesを呼び出します(ui/map.js#L1719)。
return geometry, options, this.transform;
Style#queryRenderedFeaturesはqueryRenderedSymbolsを呼び出します(style/style.js#L1384-L1391)。
this._layers,
this._serializedLayers,
this,
queryGeometryStruct.screenGeometry,
params,
this.placement.collisionIndex,
this.placement.retainedQueryData
queyrRenderedSymbolsはFeatureIndex#lookupSymbolFeaturesを呼び出し、シンボルに対応するFeatureを取得します(source/query_features.js#L95-L103)。
;
FeatureIndex#lookupSymbolFeaturesは最初のパラメータrenderedSymbols[queryData.bucketInstanceId]に対応するGeoJSON形式のFeatureを解決し、読み込みます。
なので、FeatureIndex#lookupSymbolFeaturesに適切なパラメータを与えることでFeatureを解決することができます。
FeatureIndex#lookupSymbolFeaturesに対するパラメータを用意する
FeatureIndex#lookupSymbolFeaturesの呼び出し結果(source/query_features.js#L95-L103)を再現するには以下のパラメータを提供する必要があります。
ちなみに最初のパラメータrenderedSymbols[queryData.bucketInstanceId]を再現する必要はありません。なぜならSymbolBucketで特定のバウンディングボックスと重なるFeatureではなくすべてのFeatureが必要だからです。
このパラメータをどのように置き換えるかについては節「SymbolBucketのすべてのFeatureのインデックスをリストする」を参照ください。
パラメータ: queryData
queryDataはループ変数でRetainedQueryDataが代入されます(source/query_features.js#L94-L132)。
for of bucketQueryData
bucketQueryDataはRetainedQueryDataの配列でsource/query_features.js#L88-L92で初期化されます。
;
for of renderedSymbolsNumber
sortTilesIn;
retainedQueryDataはPlacement#retainedQueryDataです。
queryRenderedSymbolsはrenderedSymbolsを初期化します(source/query_features.js#L87)。
;
CollisionIndex#queryRenderedSymbolsはbucketInstanceIdをSymbolBucket内でそのbucketInstanceIdに対応し指定のバウンディングボックスと重なるFeatureのインデックス列にマップするオブジェクトを返します。
表示されているシンボルのみを扱うのでライブラリではCollisionIndex#queryRenderedSymbolsは使いません。
SymbolBucketのリストは持っているので、各SymbolBucket#bucketInstanceIdに対応するRetainedQueryDataをPlacement#retainedQueryDataから得ることができます。
// 仮定 placement: Placement, bucket: SymbolBucket
;
パラメータ: serializedLayers
このパラメータはStyle#_serializedLayersです。
パラメータ: params.filter
Map#queryRenderedFeaturesはデフォルトで空のオブジェクトをStyle#queryRenderedFeaturesのparams引数に指定します(options → params, ui/map.js#L1716-L1719)。
options = options ||;
geometry = geometry ||;
return geometry, options, this.transform;
なのでこのパラメータはundefinedでよいです。
パラメータ: params.layers
params.filterと同様に、このパラメータもundefinedでよいです。
パラメータ: params.availableImages
Style#queryRenderedFeaturesはStyle#_availableImagesをこのパラメータに指定しています(style/style.js#L1354)。
params.availableImages = this._availableImages;
パラメータ: styleLayers
このパラメータはStyle#_layersです。
SymbolBucketのすべてのFeatureのインデックスをリストする
FeatureIndex#lookupSymbolFeaturesが最初の引数(symbolFeatureIndexes)として受け取るFeatureのインデックスとは何でしょうか?
CollisionIndex#queryRenderedSymbolsは使いませんが、それが何をしているのかを調べればFeatureIndex#lookupSymbolFeaturesの正しい入力を理解するのに役立つはずです。
この後に続く分析は大変なので先に結論からお伝えします。
SymbolBucketのすべてのFeatureのインデックスをリストするには、SymbolBucket#symbolInstancesのすべての要素からfeatureIndexプロパティを取り出す、もしくはSymbolBucket#collisionArraysのすべての要素からiconFeatureIndexプロパティを取り出します。
// 仮定 bucket: SymbolBucket
// SymbolBucket#symbolInstancesは通常の配列ではないので注意
for ; i < bucket.symbolInstances.length; ++i>
Featureを衝突ボックスに対応づけるのは単純です。なぜなら上記コードのfeatureIndexはbucket.collisionArrays[i](衝突ボックス再計算のためのパラメータ)に対応しているからです。
この節の残りは次の節「アイコンの大きさを計算する」まで飛ばして構いません。
CollisionIndex#queryRenderedSymbolsは何をしているのか?
CollisionIndex#queryRenderedSymbolsはGridIndex#queryを呼び出し、指定したバウンディングボックスと重なるFeatureをリストします(symbol/collision_index.js#L360-L361)。
minX, minY, maxX, maxY;
それからfeaturesのすべての要素をsymbol/collision_index.js#L366-L396のループで処理します。
for of features
CollisionIndex#queryRenderedSymbolsは最終的に上記コードで更新されたresultを返します。
ではGridIndex#queryが返すfeaturesとは何でしょうか?
GridIndex#queryは指定したバウンディングボックスと重なるGridItemの配列を返します。
GridIndex#queryはこれらのGridItemをGridIndexがFeatureキーと一緒に格納しているボックスとサークルの情報(GridIndex#bboxes, GridIndex#circles, GridIndex#boxKeys, GridIndex#circleKeys)から構築します。
ということで、GridIndex#boxKeys(サークルのことは忘れましょう)の起源を追跡すれば、SymbolBucketのすべてのFeatureのインデックスを取得する方法がわかるはずです。
GridIndex#boxKeysの起源
GridIndex#insertはGridIndex#boxKeysにkeyを追加します(symbol/grid_index.js#L73)。
key;
CollisionIndex#insertCollisionBoxがkeyを用意しGridIndex#insertに渡します(symbol/collision_index.js#L401-L406)。
collisionBox: Array<number>, ignorePlacement: boolean, bucketInstanceId: number, featureIndex: number, collisionGroupID: number
ここで上記スニペットのkeyを構成するfeatureIndexの起源に関心が移ります。
featureIndexの起源
シンボルのアイコンに絞ると、Placement#placeLayerBucketPart.placeSymbol (placeSymbol)はsymbol/placement.js#L748-L749でCollisionIndex#insertCollisionBoxを呼び出しています。
placedIconBoxes.box, 'icon-ignore-placement',
bucket.bucketInstanceId, iconFeatureIndex, collisionGroup.ID;
placeSymbolはsymbol/placement.js#L698でiconFeatureIndexを設定しています。
iconFeatureIndex = collisionArrays.iconFeatureIndex;
collisionArraysはCollisionArraysでありplaceSymbolの3番目の引数です。
今度はCollisionArraysの起源を追いかけます。
Placement#placeLayerBucketPartはplaceSymbolをsymbol/placement.js#L791またはsymbol/placement.js#L795で呼び出しています。
symbolIndex, symbolIndex, bucket.collisionArrays;
i, i, bucket.collisionArrays;
よってCollisionArraysはSymbolBucket#collisionArraysの要素です。
Placement#placeLayerBucketPartはSymbolBucket#deserializeCollisionBoxesを呼び出してSymbolBucket#collisionArraysを初期化して埋めます(symbol/placement.js#L432)。
collisionBoxArray;
SymbolBucket#deserializeCollisionBoxesはCollisionArrays#iconFeatureIndexを実際に設定するSymbolBucket#_deserializeCollisionBoxesForSymbolを呼び出します(data/bucket/symbol_bucket.js#L962-L968)。
for ; k < iconEndIndex; k++
ではSymbolBucket#deserializeCollisionBoxesに与えるcollisionBoxArrayとは何者でしょうか(symbol/placement.js#L432)?
collisionBoxArrayの起源
collisionBoxArrayはTileLayerParametersに含まれており、Placement#getBucketPartsはそれをTile#collisionBoxArrayから取得します(symbol/placement.js#L242)。
;
Tile#loadVectorDataはTile#collisionBoxArrayを設定します(source/tile.js#L245)。
this.collisionBoxArray = data.collisionBoxArray;
Tile#loadVectorDataはsource/geojson_source.js#L372とsource/vector_tile_source.js#L320で呼び出されています。
data, this.map.painter, message === 'reloadTile';
data, this.map.painter;
上記呼び出しはVectorTileWorkerSource#loadTileもしくはVectorTileWorkerSource#reloadTileの結果として発生します。
VectorTileWorkerSource#loadTileとVectorTileWorkerSource#reloadTileのいずれも生のVector Tileデータを解析するのにWorkerTile#parseを呼び出します。
WorkerTile#parseは解析したデータをsource/worker_tile.js#L261-L272で出力します。
null, ;
上記コードのcollisionBoxArray (=WorkerTile#collisionBoxArray)は結果的にTile#collisionBoxArrayになります。
シンボルのアイコンに絞ると、WorkerTile#parseはsource/worker_tile.js#L239-L248でperformSymbolLayoutを呼び出し、WorkerTile#collisionBoxArrayを更新します。
bucket,
glyphMap,
glyphAtlas.positions,
iconMap,
imageAtlas.iconPositions,
this.showCollisionBoxes,
availableImages,
this.tileID.canonical,
this.tileZoom,
this.projection;
このコンテキストではbucketはSymbolBucketであり、またSymbolBucket#collisionBoxArrayはBucketを生成する関数(source/worker_tile.js#L155-L168)に与えられるWorkerTile#collisionBoxArrayを指していることにご注意ください。
;
performSymbolLayoutはbucket内のFeatureをリストし、symbol/symbol_layout.js#L322でaddFeatureを呼び出します。
bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon, availableImages, canonical, projection;
addFeature(正確にはその内部関数addSymbolAtAnchor)はaddSymbolを呼び出します(symbol/symbol_layout.js#L438-L442)。
bucket, anchor, globe, line, shapedTextOrientations, shapedIcon, imageMap, verticallyShapedIcon, bucket.layers,
bucket.collisionBoxArray, feature.index, feature.sourceLayerIndex,
bucket.index, textPadding, textAlongLine, textOffset,
iconBoxScale, iconPadding, iconAlongLine, iconOffset,
feature, sizes, isSDFIcon, availableImages, canonical;
シンボルのアイコンに絞ると、addSymbolはsymbol/symbol_layout.js#L731でevaluateBoxCollisionFeatureを呼び出します。
iconBoxIndex = collisionBoxArray, collisionFeatureAnchor, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedIcon, iconPadding, iconRotate;
evaluateBoxCollisionFeatureはcollisionBoxArrayに要素を追加します(symbol/symbol_layout.js#L634)。
projectedAnchor.x, projectedAnchor.y, projectedAnchor.z, tileAnchor.x, tileAnchor.y, x1, y1, x2, y2, padding, featureIndex, sourceLayerIndex, bucketIndex;
ここでcollisionBoxArrayはWorkerTile#collisionBoxArrayと同一であることにご注意ください。
SymbolBucket#symbolInstances vs SymbolBucket#collisionArrays
行symbol/placement.js#L791と行symbol/placement.js#L795によれば、SymbolBucket#symbolInstancesの要素はSymbolBucket#collisionArraysの要素に対応しています。
symbolIndex, symbolIndex, bucket.collisionArrays;
i, i, bucket.collisionArrays;
addSymbolはsymbol/symbol_layout.js#L854-L884でSymbolBucket#symbolInstancesにも要素を追加しています。
projectedAnchor.x,
projectedAnchor.y,
projectedAnchor.z,
anchor.x,
anchor.y,
placedTextSymbolIndices.right >= 0 ? placedTextSymbolIndices.right : -1,
placedTextSymbolIndices.center >= 0 ? placedTextSymbolIndices.center : -1,
placedTextSymbolIndices.left >= 0 ? placedTextSymbolIndices.left : -1,
placedTextSymbolIndices.vertical >= 0 ? placedTextSymbolIndices.vertical : -1,
placedIconSymbolIndex,
verticalPlacedIconSymbolIndex,
key,
textBoxIndex !== undefined ? textBoxIndex : bucket.collisionBoxArray.length,
textBoxIndex !== undefined ? textBoxIndex + 1 : bucket.collisionBoxArray.length,
verticalTextBoxIndex !== undefined ? verticalTextBoxIndex : bucket.collisionBoxArray.length,
verticalTextBoxIndex !== undefined ? verticalTextBoxIndex + 1 : bucket.collisionBoxArray.length,
iconBoxIndex !== undefined ? iconBoxIndex : bucket.collisionBoxArray.length,
iconBoxIndex !== undefined ? iconBoxIndex + 1 : bucket.collisionBoxArray.length,
verticalIconBoxIndex ? verticalIconBoxIndex : bucket.collisionBoxArray.length,
verticalIconBoxIndex ? verticalIconBoxIndex + 1 : bucket.collisionBoxArray.length,
featureIndex,
numHorizontalGlyphVertices,
numVerticalGlyphVertices,
numIconVertices,
numVerticalIconVertices,
useRuntimeCollisionCircles,
0,
textOffset0,
textOffset1,
collisionCircleDiameter;
つまり、SymbolBucket#symbolInstancesとSymbolBucket#collisionArraysの対応する要素は、それぞれ featureIndexとiconFeatureIndexに全く同じFeatureのインデックスを持っています。
FeatureIndex#lookupSymbolFeaturesは何をしているのか?
FeatureIndex#lookupSymbolFeaturesは実際には何をしているのでしょうか?
SymbolBucket#symbolInstancesから取り出したFeatureのインデックス(featureIndex)を最初の引数(symbolFeatureIndexes)に指定するのは理にかなっているでしょうか?
FeatureIndex#lookupSymbolFeaturesはFeatureIndex#loadMatchingFeatureを繰り返し呼び出しています(data/feature_index.js#L257-L272, symbolFeatureIndex → featureIndexData.featureIndex)。
for of symbolFeatureIndexes
FeatureIndex#loadMatchingFeatureはfeatureIndexをdata/feature_index.js#L188-L190でFeatureを読み込むのに使っています。
;
;
;
一方で、performSymbolLayoutはSymbolBucket#features内のFeatureを列挙し、ひとつずつaddFeatureに渡しています(symbol/symbol_layout.js#L197-L324)。
for of bucket.features
ではSymbolBucket#featuresはどこから来るのでしょうか?
SymbolBucket#populateがSymbolBucket#featuresを初期化して埋めています(data/bucket/symbol_bucket.js#L475-L626)。
features: Array<IndexedFeature>, options: PopulateParameters, canonical: CanonicalTileID, tileTransform: TileTransform
WorkerTile#parseはBucketを生成した直後にSymbolBucket#populateを呼び出しています(source/worker_tile.js#L171)。
features, options, this.tileID.canonical, this.tileTransform;
そしてWorkerTile#parseは最初の引数のfeaturesをsource/worker_tile.js#L137-L142で用意しています。
;
for ; index < sourceLayer.length; index++
ということで上記コード内のindexは最終的に他のFeatureに関する情報と併せてSymbolBucket#symbolInstancesのfeatureIndexとなります。
よって SymbolBucket#symbolInstancesのfeatureIndexプロパティはFeatureIndex#lookupSymbolFeaturesの最初の引数symbolFeatureIndexesと整合性がとれていることがわかりました。
アイコンの大きさを計算する
前回の投稿で、アイコンのscaleパラメータを再現できると結論づけました。
しかし、partiallyEvaluatedIconSizeを計算するためのevaluateSizeForZoom関数がmapbox-gl-jsからエクスポートされていないことに後から気づきました。
ということでライブラリを実装するためにはmapbox-gl-jsからevaluateSizeForZoomの複製を作成しなければなりませんでした。
evaluateSizeForZoomが機能するために、以下の型や関数も複製しなければなりませんでした。
SizeDataInterpolatedSizeInterpolationTypeinterpolationFactorexponentialInterpolationinterpolateclamp
複製したものは私のGitHubレポジトリにあります。
まとめ
このブログ投稿では、TileとSymbolBucketをリストし、シンボルのFeatureを解決する方法を示しました。
最終的なループは以下のようになります。
// 仮定 map: mapboxgl.Map, layerId: string
;
;
;
;
for of layerTiles
またアイコンのサイズを計算する方法もカバーしました。
ライブラリを実装している途中、mapbox-gl-jsの内部タイプが利用できないというTypeScript特有の課題に直面しました。
今後のブログ投稿で、その課題にどう対処したかを共有するつもりです。
私のGitHubレポジトリでライブラリもご確認ください!
補足
ソースコードレファレンス
Map
Map#queryRenderedFeatures
このメソッドはMap#queryRenderedFeatures APIを実装します。
Style
Style#_layers
_layers: ;
Style#_serializedLayers
_serializedLayers: ;
Style#_availableImages
_availableImages: Array<string>;
Style#queryRenderedFeatures
定義: style/style.js#L1330-L1396
query_features.queryRenderedSymbols
定義: source/query_features.js#L79-L149
Style#_updatePlacement
定義: src/style/style.js#L1692-L1766
このメソッドはPauseablePlacement#continuePlacementを呼び出します。
Tile
Tile#tileID
tileID: OverscaledTileID;
Tile#collisionBoxArray
collisionBoxArray: ?CollisionBoxArray;
Tile#loadVectorData
VectorTileWorkerSource
定義: source/vector_tile_worker_source.js#L140-L309
VectorTileWorkerSource#loadTile
定義: source/vector_tile_worker_source.js#L177-L238
このメソッドはWorkerスレッドで実行されます。
VectorTileWorkerSource#reloadTile
定義: source/vector_tile_worker_source.js#L244-L275
このメソッドはWorkerスレッドで実行されます。
WorkerTile
定義: source/worker_tile.js#L36-L277
WorkerTile#collisionBoxArray
collisionBoxArray: CollisionBoxArray;
WorkerTile#parse
定義: source/worker_tile.js#L83-L276
symbol_layout.performSymbolLayout
定義: symbol/symbol_layout.js#L152-L329
WorkerTile#parseはこの関数を呼び出します(source/worker_tile.js#L239-L248)。
bucket,
glyphMap,
glyphAtlas.positions,
iconMap,
imageAtlas.iconPositions,
this.showCollisionBoxes,
availableImages,
this.tileID.canonical,
this.tileZoom,
this.projection;
symbol_layout.addFeature
定義: symbol/symbol_layout.js#L367-L500
シンボルのアイコンに絞ると、symbol_layout.performSymbolLayoutはsymbol/symbol_layout.js#L322でこの関数を呼び出します。
bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon, availableImages, canonical, projection;
symbol_layout.addSymbol
定義: symbol/symbol_layout.js#L657-L885
この関数はSymbolBucket#symbolInstancesを更新します(symbol/symbol_layout.js#L854-L884)。
projectedAnchor.x,
projectedAnchor.y,
projectedAnchor.z,
anchor.x,
anchor.y,
placedTextSymbolIndices.right >= 0 ? placedTextSymbolIndices.right : -1,
placedTextSymbolIndices.center >= 0 ? placedTextSymbolIndices.center : -1,
placedTextSymbolIndices.left >= 0 ? placedTextSymbolIndices.left : -1,
placedTextSymbolIndices.vertical >= 0 ? placedTextSymbolIndices.vertical : -1,
placedIconSymbolIndex,
verticalPlacedIconSymbolIndex,
key,
textBoxIndex !== undefined ? textBoxIndex : bucket.collisionBoxArray.length,
textBoxIndex !== undefined ? textBoxIndex + 1 : bucket.collisionBoxArray.length,
verticalTextBoxIndex !== undefined ? verticalTextBoxIndex : bucket.collisionBoxArray.length,
verticalTextBoxIndex !== undefined ? verticalTextBoxIndex + 1 : bucket.collisionBoxArray.length,
iconBoxIndex !== undefined ? iconBoxIndex : bucket.collisionBoxArray.length,
iconBoxIndex !== undefined ? iconBoxIndex + 1 : bucket.collisionBoxArray.length,
verticalIconBoxIndex ? verticalIconBoxIndex : bucket.collisionBoxArray.length,
verticalIconBoxIndex ? verticalIconBoxIndex + 1 : bucket.collisionBoxArray.length,
featureIndex,
numHorizontalGlyphVertices,
numVerticalGlyphVertices,
numIconVertices,
numVerticalIconVertices,
useRuntimeCollisionCircles,
0,
textOffset0,
textOffset1,
collisionCircleDiameter;
symbol_layout.addFeatureの内部関数addSymbolAtAnchorがこの関数を呼び出します(symbol/symbol_layout.js#L438-L442)。
bucket, anchor, globe, line, shapedTextOrientations, shapedIcon, imageMap, verticallyShapedIcon, bucket.layers,
bucket.collisionBoxArray, feature.index, feature.sourceLayerIndex,
bucket.index, textPadding, textAlongLine, textOffset,
iconBoxScale, iconPadding, iconAlongLine, iconOffset,
feature, sizes, isSDFIcon, availableImages, canonical;
symbol_layout.evaluateBoxCollisionFeature
定義: symbol/symbol_layout.js#L580-L637
この関数はcollisionBoxArrayを更新します(symbol/symbol_layout.js#L634)。
projectedAnchor.x, projectedAnchor.y, projectedAnchor.z, tileAnchor.x, tileAnchor.y, x1, y1, x2, y2, padding, featureIndex, sourceLayerIndex, bucketIndex;
シンボルのアイコンに絞ると、symbol_layout.addSymbolはsymbol/symbol_layout.js#L731でこの関数を呼び出します。
iconBoxIndex = collisionBoxArray, collisionFeatureAnchor, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedIcon, iconPadding, iconRotate;
StyleLayer
定義: style/style_layer.js#L39-L323
SymbolBucket
定義: data/bucket/symbol_bucket.js#L352-L1119
SymbolBucket#bucketInstanceId
定義: data/bucket/symbol_bucket.js#L368
bucketInstanceId: number;
SymbolBucket#features
定義: data/bucket/symbol_bucket.js#L378
features: Array<SymbolFeature>;
SymbolBucket#collisionArrays
定義t: data/bucket/symbol_bucket.js#L380
collisionArrays: Array<CollisionArrays>;
このプロパティの要素はSymbolBucket#symbolInstancesの要素に対応します。
SymbolBucket#deserializeCollisionBoxesはこのプロパティを初期化して埋めます。
SymbolBucket#symbolInstances
定義: data/bucket/symbol_bucket.js#L379
symbolInstances: SymbolInstanceArray;
このプロパティの要素はSymbolBucket#collisionArraysの要素に対応します。
SymbolBucket#collisionBoxArray
定義: data/bucket/symbol_bucket.js#L356
SymbolBucket#populate
定義: data/bucket/symbol_bucket.js#L475-L626
SymbolBucket#deserializeCollisionBoxes
定義: data/bucket/symbol_bucket.js#L979-L995
このメソッドはSymbolBucket#collisionArraysを初期化して埋めます。
SymbolBucket#_deserializeCollisionBoxesForSymbol
定義: data/bucket/symbol_bucket.js#L943-L977
FeatureIndex
定義: data/feature_index.js#L54-L312
FeatureIndex#lookupSymbolFeatures
定義: data/feature_index.js#L244-L274
このメソッドはFeatureIndex#loadMatchingFeatureを呼び出します(data/feature_index.js#L258-L270)。
result, ,
filter,
filterLayerIDs,
availableImages,
styleLayers,
serializedLayers
;
FeatureIndex#loadMatchingFeature
定義: data/feature_index.js#L172-L240
このメソッドはシンボルのFeature(GeoJSON形式)をVector Tileデータから読み込みます。
CollisionIndex
定義: symbol/collision_index.js#L64-L465
CollisionIndex#queryRenderedSymbols
定義: symbol/collision_index.js#L341-L399
CollisionIndex#insertCollisionBox
定義: symbol/collision_index.js#L401-L406
collisionBox: Array<number>, ignorePlacement: boolean, bucketInstanceId: number, featureIndex: number, collisionGroupID: number
GridIndex
定義: symbol/grid_index.js#L24-L341
GridIndex#bboxes
bboxes: Array<number>;
GridIndex#boxKeysもご覧ください。
GridIndex#boxKeys
boxKeys: Array<any>;
このプロパティはGridIndex#bboxes内の同じインデックスにあるボックスに対応するFeatureのキーを格納します。
GridIndex#insertはこのプロパティを更新します。
GridIndex#circles
circles: Array<number>;
GridIndex#circleKeysもご覧ください。
GridIndex#circleKeys
circleKeys: Array<any>;
このプロパティはGridIndex#circles内の同じインデックスにあるサークルに対応するFeatureのキーを格納します。
GridIndex#insert
定義: symbol/grid_index.js#L71-L78
このメソッドは指定したkeyをGridIndex#boxKeysに追加します(symbol/grid_index.js#L73)。
key;
GridIndex#query
定義: symbol/grid_index.js#L163-L165
x1: number, y1: number, x2: number, y2: number, predicate?: any: Array<GridItem>
GridIndex#_queryもご覧ください。
GridIndex#_query
定義: symbol/grid_index.js#L98-L137
このメソッドはGridIndex#_forEachCellを呼び出します(symbol/grid_index.js#L134)。
x1, y1, x2, y2, this._queryCell, result, queryArgs, predicate;
GridIndex#_forEachCell
定義: symbol/grid_index.js#L291-L303
x1: number, y1: number, x2: number, y2: number, fn: any, arg1: any, arg2?: any, predicate?: any
このメソッドは指定したバウンディングボックスと重なるすべてのセルにfnを適用します。
GridIndex#queryのコンテキストでは、fnはGridIndex#_queryCellです。
GridIndex#_queryCell
定義: symbol/grid_index.js#L175-L240
このメソッドは指定したセルで指定したバウンディングボックスと重なるボックスとサークルを集めます。
GridItem
定義: symbol/grid_index.js#L3-L9
;
Placement
定義: symbol/placement.js#L192-L1184
Placement#retainedQueryData
retainedQueryData: ;
RetainedQueryDataもご覧ください。
Placement#getBucketParts
定義: symbol/placement.js#L233-L333
LayerPlacement#continuePlacementはこのメソッドを呼び出します(style/pauseable_placement.js#L37)。
bucketParts, styleLayer, tile, this._sortAcrossTiles;
前回のブログ投稿の関連する節もご覧ください。
Placement#placeLayerBucketPart
定義: symbol/placement.js#L386-L808
LayerPlacement#continuePlacementはこのメソッドを呼び出します(style/pauseable_placement.js#L52)。
bucketPart, this._seenCrossTileIDs, showCollisionBoxes, bucketPart.symbolInstanceStart === 0;
前回のブログ投稿の関連する節もご覧ください。
Placement#placeLayerBucketPart.placeSymbol
定義: symbol/placement.js#L439-L784
RetainedQueryData
定義: symbol/placement.js#L87-L105
BucketPart
定義: symbol/placement.js#L183-L188
;
TileLayerParametersもご覧ください。
TileLayerParameters
定義: symbol/placement.js#L169-L181
;
PauseablePlacement
定義: style/pauseable_placement.js#L62-L132
PauseablePlacement#continuePlacement
定義: style/pauseable_placement.js#L89-L126
このメソッドはLayerPlacement#continuePlacementを呼び出します。
Style#_updatePlacementはこのメソッドを呼び出します(style/style.js#L1740)。
this._order, this._layers, layerTiles;
LayerPlacement
定義: style/pauseable_placement.js#L15-L60
LayerPlacement#continuePlacement
定義: style/pauseable_placement.js#L32-L59
このメソッドは以下を呼び出します。
PauseablePlacement#continuePlacementはこのメソッドを呼び出します(style/pauseable_placement.js#L109)。
;
symbol_size.SizeData
定義: symbol/symbol_size.js#L15-L32
;
symbol_size.InterpolatedSize
定義: symbol/symbol_size.js#L34-L37
;
symbol_size.evaluateSizeForZoom
定義: symbol/symbol_size.js#L92-L118
interpolate.InterpolationType
定義: style-spec/expression/definitions/interpolate.js#L17-L20
;
Interpolate.interpolationFactor
定義: style-spec/expression/definitions/interpolate.js#L45-L57
interpolate.exponentialInterpolation
定義: style-spec/expression/definitions/interpolate.js#L255-L266
util.interpolate
定義: style-spec/util/interpolate.js#L5-L7
util.clamp
SymbolInstanceArray
定義: data/array_types.js#L1188-L1198
この配列の各要素はSymbolInstanceStructです。
SymbolInstanceStruct
定義: data/array_types.js#L1146-L1179
CollisionArrays
定義: data/bucket/symbol_bucket.js#L90-L99
;