Dealing with Mapbox hidden symbols (2. Resolving features)
2022-09-16 (Updated on 2022-09-24)
I have been working on a utility library for Mapbox GL JS, that deals with symbols hidden by another symbol on the screen. This is the second blog post of the series that will walk you through the development of the library.
Background
In the last blog post of this series, we left the following questions unanswered.
- How can we obtain
Tile
s andSymbolBucket
s?- How can we associate recalculated collision boxes with symbol features?
This blog post answers the above questions and also covers how to calculate the size of an icon, which I overlooked in the last blog post.
The library is available at https://github.com/codemonger-io/mapbox-collision-boxes.
I have analyzed version 2.9.2* of Mapbox GL JS (mapbox-gl-js
).
* The latest version was 2.10.0 when I was writing this blog post, though I stick to version 2.9.2 for consistency.
Obtaining Tiles and SymbolBuckets
In the last blog post, we have seen Placement#placeLayerBucketPart
plays a crucial role in determining which symbols are to appear on the screen.
If we examine how this method is invoked, we may figure out how to obtain Tile
s and SymbolBucket
s.
Resolving SymbolBucket
LayerPlacement#continuePlacement
repeats calling Placement#placeLayerBucketPart
in style/pauseable_placement.js#L50-L57:
while this._currentPartIndex < bucketParts.length
Each item in bucketParts
that Placement#getBucketParts
creates supplies a SymbolBucket
to be processed (BucketPart#parameters
→ TileLayerParameters#bucket
).
Placement#getBucketParts
extracts a SymbolBucket
from the Tile
given as the third parameter of the method (symbol/placement.js#L233-L234):
results: Array<BucketPart>, styleLayer: StyleLayer, tile: Tile, sortAcrossTiles: boolean
Thus, if we have a StyleLayer
and a Tile
, we can also get a SymbolBucket
.
Resolving StyleLayer and Tile
LayerPlacement#continuePlacement
repeats calling Placement#getBucketParts
in style/pauseable_placement.js#L35-L43:
while this._currentTileIndex < tiles.length
tiles
and styleLayer
in the above snippet are the parameters given to LayerPlacement#continuePlacement
.
PauseablePlacement#continuePlacement
repeats calling LayerPlacement#continuePlacement
in style/pauseable_placement.js#L97-L123 (layerTiles[layer.source]
→ tiles
, and layer
→ styleLayer
):
while this._currentPlacementIndex >= 0
PausePlacement#continuePlacement
applies LayerPlacement#continuePlacement
only to "symbol" layers, as you can see the following condition at style/pauseable_placement.js#L101:
if layer.type === 'symbol' &&
order
, layers
, and layerTiles
in the above snippet are the parameters given to PauseablePlacement#continuePlacement
.
Style#_updatePlacement
calls PauseablePlacement#continuePlacement
at style/style.js#L1740:
this._order, this._layers, layerTiles;
Style#_updatePlacement
prepares layerTiles
in style/style.js#L1696-L1712:
;
for of this._order
So by mocking the above code, we can obtain the StyleLayer
and all the Tile
s corresponding to a given layer ID.
Listing Tiles and SymbolBuckets on a layer
To summarize, the outline of the code to list Tile
s and SymbolBucket
s on a specific layer will be similar to the following,
// suppose we have map: mapboxgl.Map, and layerId: string
;
;
;
;
for of layerTiles
You can find complete code on my GitHub repository that includes additional checks.
Resolving symbol features
In the last blog post, I briefly mentioned that FeatureIndex
is important for resolving symbol features.
I have reasoned it by looking into Map#queryRenderedFeatures
.
Overview of how Map#queryRenderedFeatures works
Map#queryRenderedFeatures
calls Style#queryRenderedFeatures
at ui/map.js#L1719:
return geometry, options, this.transform;
Style#queryRenderedFeatures
calls queryRenderedSymbols
in style/style.js#L1384-L1391:
this._layers,
this._serializedLayers,
this,
queryGeometryStruct.screenGeometry,
params,
this.placement.collisionIndex,
this.placement.retainedQueryData
queyrRenderedSymbols
calls FeatureIndex#lookupSymbolFeatures
in source/query_features.js#L95-L103 to obtain features associated with symbols:
;
FeatureIndex#lookupSymbolFeatures
resolves and loads GeoJSON features associated with the first argument renderedSymbols[queryData.bucketInstanceId]
.
So we can resolve features by supplying proper parameters to FeatureIndex#lookupSymbolFeatures
.
Preparing parameters for FeatureIndex#lookupSymbolFeatures
We have to provide the following parameters to reproduce the results of a FeatureIndex#lookupSymbolFeatures
call in source/query_features.js#L95-L103,
Please note that we do not have to reproduce the first parameter renderedSymbols[queryData.bucketInstanceId]
because we need all the features in a SymbolBucket
rather than features intersecting a specific bounding box.
Please refer to the section "Listing all the feature indices in a SymbolBucket" for how to substitute this parameter.
Parameter: queryData
queryData
is bound to a RetainedQueryData
in the loop in source/query_features.js#L94-L132:
for of bucketQueryData
bucketQueryData
is an array of RetainedQueryData
s and initialized in source/query_features.js#L88-L92:
;
for of renderedSymbolsNumber
sortTilesIn;
retainedQueryData
is Placement#retainedQueryData
.
queryRenderedSymbols
initializes renderedSymbols
at source/query_features.js#L87:
;
CollisionIndex#queryRenderedSymbols
returns an object that maps a bucketInstanceId
to indices of features in the SymbolBucket
associated with the bucketInstanceId
and intersect a given bounding box.
We do not rely on CollisionIndex#queryRenderedSymbols
, because it covers only visible symbols.
Since we have a list of SymbolBucket
s, we can obtain the RetainedQueryData
for each SymbolBucket#bucketInstanceId
through Placement#retainedQueryData
:
// suppose we have placement: Placement, and bucket: SymbolBucket
;
Parameter: serializedLayers
This parameter is Style#_serializedLayers
.
Parameter: params.filter
Map#queryRenderedFeatures
specifies an empty object to the params
parameter of Style#queryRenderedFeatures
by default (options
→ params
in ui/map.js#L1716-L1719):
options = options ||;
geometry = geometry ||;
return geometry, options, this.transform;
So this parameter may be undefined
.
Parameter: params.layers
Like params.filter
, this parameter may be undefined
too.
Parameter: params.availableImages
Style#queryRenderedFeatures
specifies Style#_availableImages
to this parameter at style/style.js#L1354:
params.availableImages = this._availableImages;
Parameter: styleLayers
This parameter is Style#_layers
.
Listing all the feature indices in a SymbolBucket
What are feature indices that FeatureIndex#lookupSymbolFeatures
takes as its first argument (symbolFeatureIndexes
)?
Although we do not use CollisionIndex#queryRenderedSymbols
, seeing what it does should help us to figure out legitimate inputs to FeatureIndex#lookupSymbolFeatures
.
I show you the conclusion first because the following analysis is intensive.
To list all the feature indices in a SymbolBucket
, we can take the featureIndex
property from every item in SymbolBucket#symbolInstances
, or the iconFeatureIndex
property from every item in SymbolBucket#collisionArrays
:
// suppose we have bucket: SymbolBucket
// please note that SymbolBucket#symbolInstances is not an ordinary array
for ; i < bucket.symbolInstances.length; ++i>
Associating the feature with the collision box is straightforward because featureIndex
in the above code corresponds to bucket.collisionArrays[i]
: a parameter for collision box recalculation.
You may skip the rest of this section to the next section "Calculating the size of an icon".
What does CollisionIndex#queryRenderedSymbols do?
CollisionIndex#queryRenderedSymbols
calls GridIndex#query
to list features intersecting a given bounding box in symbol/collision_index.js#L360-L361:
minX, minY, maxX, maxY;
Then it processes every item of features
in the loop in symbol/collision_index.js#L366-L396:
for of features
CollisionIndex#queryRenderedSymbols
eventually returns result
updated in the above code.
So what are features
that GridIndex#query
returns?
GridIndex#query
returns an array of GridItem
s intersecting a given bounding box.
GridIndex#query
constructs these GridItem
s from the information of boxes and circles that GridIndex
stores along with feature keys in GridIndex#bboxes
, GridIndex#circles
, GridIndex#boxKeys
, and GridIndex#circleKeys
.
Thus, if we track down the origin of GridIndex#boxKeys
(let's forget about circles), we should be able to figure out how to get all the feature indices in a SymbolBucket
.
The origin of GridIndex#boxKeys
GridIndex#insert
pushes a key
to GridIndex#boxKeys
at symbol/grid_index.js#L73:
key;
CollisionIndex#insertCollisionBox
defined in symbol/collision_index.js#L401-L406 prepares a key
and passes it to GridIndex#insert
:
collisionBox: Array<number>, ignorePlacement: boolean, bucketInstanceId: number, featureIndex: number, collisionGroupID: number
Now our concern shifts to the origin of featureIndex
that makes up the key
in the above snippet.
The origin of featureIndex
In terms of symbol icons, Placement#placeLayerBucketPart.placeSymbol
(placeSymbol
) calls CollisionIndex#insertCollisionBox
in symbol/placement.js#L748-L749:
placedIconBoxes.box, 'icon-ignore-placement',
bucket.bucketInstanceId, iconFeatureIndex, collisionGroup.ID;
placeSymbol
sets iconFeatureIndex
at symbol/placement.js#L698:
iconFeatureIndex = collisionArrays.iconFeatureIndex;
collisionArrays
is a CollisionArrays
and the third argument of placeSymbol
.
Then we pursue the origin of CollisionArrays
.
Placement#placeLayerBucketPart
calls placeSymbol
at symbol/placement.js#L791 or symbol/placement.js#L795:
symbolIndex, symbolIndex, bucket.collisionArrays;
i, i, bucket.collisionArrays;
So CollisionArrays
is an item of SymbolBucket#collisionArrays
.
Placement#placeLayerBucketPart
calls SymbolBucket#deserializeCollisionBoxes
at symbol/placement.js#L432 to initialize and fill SymbolBucket#collisionArrays
:
collisionBoxArray;
SymbolBucket#deserializeCollisionBoxes
calls SymbolBucket#_deserializeCollisionBoxesForSymbol
that actually sets CollisionArrays#iconFeatureIndex
in data/bucket/symbol_bucket.js#L962-L968:
for ; k < iconEndIndex; k++
So what is collisionBoxArray
given to SymbolBucket#deserializeCollisionBoxes
at symbol/placement.js#L432?
The origin of collisionBoxArray
collisionBoxArray
is included in TileLayerParameters
, and Placement#getBucketParts
obtains it from Tile#collisionBoxArray
at symbol/placement.js#L242:
;
Tile#loadVectorData
sets Tile#collisionBoxArray
at source/tile.js#L245:
this.collisionBoxArray = data.collisionBoxArray;
Tile#loadVectorData
is called at source/geojson_source.js#L372 and source/vector_tile_source.js#L320:
data, this.map.painter, message === 'reloadTile';
data, this.map.painter;
Above calls happen as a result of VectorTileWorkerSource#loadTile
or VectorTileWorkerSource#reloadTile
.
Both VectorTileWorkerSource#loadTile
and VectorTileWorkerSource#reloadTile
call WorkerTile#parse
to parse the raw vector tile data.
WorkerTile#parse
outputs the parsed data in source/worker_tile.js#L261-L272:
null, ;
collisionBoxArray
(=WorkerTile#collisionBoxArray
) in the above code eventually goes to Tile#collisionBoxArray
.
In terms of symbol icons, WorkerTile#parse
calls performSymbolLayout
in source/worker_tile.js#L239-L248 to update WorkerTile#collisionBoxArray
:
bucket,
glyphMap,
glyphAtlas.positions,
iconMap,
imageAtlas.iconPositions,
this.showCollisionBoxes,
availableImages,
this.tileID.canonical,
this.tileZoom,
this.projection;
Please note that bucket
is a SymbolBucket
in this context, and SymbolBucket#collisionBoxArray
points to WorkerTile#collisionBoxArray
as it is given to the bucket creation function in source/worker_tile.js#L155-L168:
;
performSymbolLayout
lists features in bucket
and calls addFeature
at symbol/symbol_layout.js#L322:
bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon, availableImages, canonical, projection;
addFeature
(its internal function addSymbolAtAnchor
) calls addSymbol
in 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;
In terms of symbol icons, addSymbol
calls evaluateBoxCollisionFeature
at symbol/symbol_layout.js#L731:
iconBoxIndex = collisionBoxArray, collisionFeatureAnchor, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedIcon, iconPadding, iconRotate;
evaluateBoxCollisionFeature
appends an item to collisionBoxArray
at symbol/symbol_layout.js#L634:
projectedAnchor.x, projectedAnchor.y, projectedAnchor.z, tileAnchor.x, tileAnchor.y, x1, y1, x2, y2, padding, featureIndex, sourceLayerIndex, bucketIndex;
Please note that collisionBoxArray
here is identical to WorkerTile#collisionBoxArray
.
SymbolBucket#symbolInstances vs SymbolBucket#collisionArrays
According to lines symbol/placement.js#L791 and symbol/placement.js#L795, items of SymbolBucket#symbolInstances
match those of SymbolBucket#collisionArrays
.
symbolIndex, symbolIndex, bucket.collisionArrays;
i, i, bucket.collisionArrays;
And addSymbol
also appends an item to SymbolBucket#symbolInstances
in 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;
Thus, matching items in SymbolBucket#symbolInstances
and SymbolBucket#collisionArrays
have the same feature index featureIndex
and iconFeatureIndex
respectively.
What does FeatureIndex#lookupSymbolFeatures do?
What does FeatureIndex#lookupSymbolFeatures
actually do?
Does it make sense to specify feature indices (featureIndex
) taken from SymbolBucket#symbolInstances
to the first parameter (symbolFeatureIndexes
)?
FeatureIndex#lookupSymbolFeatures
repeats calling FeatureIndex#loadMatchingFeature
in data/feature_index.js#L257-L272 (symbolFeatureIndex
→ featureIndexData.featureIndex
):
for of symbolFeatureIndexes
FeatureIndex#loadMatchingFeature
uses featureIndex
to load the feature in data/feature_index.js#L188-L190:
;
;
;
On the other hand, performSymbolLayout
enumerates features in SymbolBucket#features
and passes them to addFeature
one by one in symbol/symbol_layout.js#L197-L324:
for of bucket.features
So where does SymbolBucket#features
come from?
SymbolBucket#populate
initializes and fills SymbolBucket#features
(data/bucket/symbol_bucket.js#L475-L626):
features: Array<IndexedFeature>, options: PopulateParameters, canonical: CanonicalTileID, tileTransform: TileTransform
WorkerTile#parse
calls SymbolBucket#populate
at source/worker_tile.js#L171 just after creating a bucket:
features, options, this.tileID.canonical, this.tileTransform;
And WorkerTile#parse
prepares the first argument features
in source/worker_tile.js#L137-L142:
;
for ; index < sourceLayer.length; index++
So index
in the above code eventually becomes featureIndex
in SymbolBucket#symbolInstances
along with the other related feature information.
Now we are sure that featureIndex
properties in SymbolBucket#symbolInstances
are consistent with the first parameter symbolFeatureIndexes
of FeatureIndex#lookupSymbolFeatures
.
Calculating the size of an icon
In the last blog post, I concluded that we could reproduce the scale
parameter for icons.
However, I found that the function evaluateSizeForZoom
to calculate partiallyEvaluatedIconSize
was not exported from mapbox-gl-js
afterward.
So I had to clone evaluateSizeForZoom
from mapbox-gl-js
to implement my library.
To make evaluateSizeForZoom
work, I also had to clone the following types and functions,
SizeData
InterpolatedSize
InterpolationType
interpolationFactor
exponentialInterpolation
interpolate
clamp
You can find these clones in my GitHub repository.
Wrap up
In this blog post, I have shown you how to list Tile
s and SymbolBucket
s and resolve symbol features.
The final loops will look like the following:
// suppose we have map: mapboxgl.Map, and layerId: string
;
;
;
;
for of layerTiles
I also have covered how to calculate the size of an icon.
While implementing the library, I faced a TypeScript-specific issue where internal types of mapbox-gl-js
were not available for TypeScript.
In an upcoming blog post, I will share how I have addressed the issue.
Please also check out the library on my GitHub repository!
Appendix
Source code reference
Map
Definition: ui/map.js#L326-L3677
Map#queryRenderedFeatures
Definition: ui/map.js#L1697-L1720
This method implements the Map#queryRenderedFeatures
API.
Style
Definition: style/style.js#L135-L1860
Style#_layers
Definition: style/style.js#L148
_layers: ;
Style#_serializedLayers
Definition: style/style.js#L152
_serializedLayers: ;
Style#_availableImages
Definition: style/style.js#L168
_availableImages: Array<string>;
Style#queryRenderedFeatures
Definition: style/style.js#L1330-L1396
query_features.queryRenderedSymbols
Definition: source/query_features.js#L79-L149
Style#_updatePlacement
Definition: src/style/style.js#L1692-L1766
This method calls PauseablePlacement#continuePlacement
.
Tile
Definition: source/tile.js#L95-L799
Tile#tileID
Definition: source/tile.js#L96
tileID: OverscaledTileID;
Tile#collisionBoxArray
Definition: source/tile.js#L115
collisionBoxArray: ?CollisionBoxArray;
Tile#loadVectorData
Definition: source/tile.js#L221-L290
VectorTileWorkerSource
Definition: source/vector_tile_worker_source.js#L140-L309
VectorTileWorkerSource#loadTile
Definition: source/vector_tile_worker_source.js#L177-L238
This method runs on a worker thread.
VectorTileWorkerSource#reloadTile
Definition: source/vector_tile_worker_source.js#L244-L275
This method runs on a worker thread.
WorkerTile
Definition: source/worker_tile.js#L36-L277
WorkerTile#collisionBoxArray
Definition: source/worker_tile.js#L57
collisionBoxArray: CollisionBoxArray;
WorkerTile#parse
Definition: source/worker_tile.js#L83-L276
symbol_layout.performSymbolLayout
Definition: symbol/symbol_layout.js#L152-L329
WorkerTile#parse
calls this function in 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
Definition: symbol/symbol_layout.js#L367-L500
In terms of symbol icons, symbol_layout.performSymbolLayout
calls this function at symbol/symbol_layout.js#L322:
bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon, availableImages, canonical, projection;
symbol_layout.addSymbol
Definition: symbol/symbol_layout.js#L657-L885
This function updates SymbolBucket#symbolInstances
in 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;
An internal function addSymbolAtAnchor
of symbol_layout.addFeature
calls this function in 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
Definition: symbol/symbol_layout.js#L580-L637
This function updates collisionBoxArray
at symbol/symbol_layout.js#L634:
projectedAnchor.x, projectedAnchor.y, projectedAnchor.z, tileAnchor.x, tileAnchor.y, x1, y1, x2, y2, padding, featureIndex, sourceLayerIndex, bucketIndex;
In terms of symbol icons, symbol_layout.addSymbol
calls this function at symbol/symbol_layout.js#L731:
iconBoxIndex = collisionBoxArray, collisionFeatureAnchor, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedIcon, iconPadding, iconRotate;
StyleLayer
Definition: style/style_layer.js#L39-L323
SymbolBucket
Definition: data/bucket/symbol_bucket.js#L352-L1119
SymbolBucket#bucketInstanceId
Definition: data/bucket/symbol_bucket.js#L368
bucketInstanceId: number;
SymbolBucket#features
Definition: data/bucket/symbol_bucket.js#L378
features: Array<SymbolFeature>;
SymbolBucket#collisionArrays
Definition: data/bucket/symbol_bucket.js#L380
collisionArrays: Array<CollisionArrays>;
Items in this property match those in SymbolBucket#symbolInstances
.
SymbolBucket#deserializeCollisionBoxes
initializes and fills this property.
SymbolBucket#symbolInstances
Definition: data/bucket/symbol_bucket.js#L379
symbolInstances: SymbolInstanceArray;
Items in this property match those in SymbolBucket#collisionArrays
.
SymbolBucket#collisionBoxArray
Definition: data/bucket/symbol_bucket.js#L356
SymbolBucket#populate
Definition: data/bucket/symbol_bucket.js#L475-L626
SymbolBucket#deserializeCollisionBoxes
Definition: data/bucket/symbol_bucket.js#L979-L995
This method initializes and fills SymbolBucket#collisionArrays
.
SymbolBucket#_deserializeCollisionBoxesForSymbol
Definition: data/bucket/symbol_bucket.js#L943-L977
FeatureIndex
Definition: data/feature_index.js#L54-L312
FeatureIndex#lookupSymbolFeatures
Definition: data/feature_index.js#L244-L274
This method calls FeatureIndex#loadMatchingFeature
in data/feature_index.js#L258-L270:
result, ,
filter,
filterLayerIDs,
availableImages,
styleLayers,
serializedLayers
;
FeatureIndex#loadMatchingFeature
Definition: data/feature_index.js#L172-L240
This method loads the GeoJSON feature(s) of a symbol from the vector tile data.
CollisionIndex
Definition: symbol/collision_index.js#L64-L465
CollisionIndex#queryRenderedSymbols
Definition: symbol/collision_index.js#L341-L399
CollisionIndex#insertCollisionBox
Definition: symbol/collision_index.js#L401-L406
collisionBox: Array<number>, ignorePlacement: boolean, bucketInstanceId: number, featureIndex: number, collisionGroupID: number
GridIndex
Definition: symbol/grid_index.js#L24-L341
GridIndex#bboxes
Definition: symbol/grid_index.js#L29
bboxes: Array<number>;
Please see also GridIndex#boxKeys
.
GridIndex#boxKeys
Definition: symbol/grid_index.js#L26
boxKeys: Array<any>;
This property stores the feature key associated with the box at the same index in GridIndex#bboxes
.
GridIndex#insert
updates this property.
GridIndex#circles
Definition: symbol/grid_index.js#L30
circles: Array<number>;
Please see also GridIndex#circleKeys
.
GridIndex#circleKeys
Definition: symbol/grid_index.js#L25
circleKeys: Array<any>;
This property stores the feature key associated with the circle at the same index in GridIndex#circles
.
GridIndex#insert
Definition: symbol/grid_index.js#L71-L78
This method pushes a given key
to GridIndex#boxKeys
at symbol/grid_index.js#L73:
key;
GridIndex#query
Definition: symbol/grid_index.js#L163-L165
x1: number, y1: number, x2: number, y2: number, predicate?: any : Array<GridItem>
Please see also GridIndex#_query
.
GridIndex#_query
Definition: symbol/grid_index.js#L98-L137
This method calls GridIndex#_forEachCell
at symbol/grid_index.js#L134:
x1, y1, x2, y2, this._queryCell, result, queryArgs, predicate;
GridIndex#_forEachCell
Definition: symbol/grid_index.js#L291-L303
x1: number, y1: number, x2: number, y2: number, fn: any, arg1: any, arg2?: any, predicate?: any
This method applies fn
to every cell intersecting a given bounding box.
In the context of GridIndex#query
, fn
is GridIndex#_queryCell
.
GridIndex#_queryCell
Definition: symbol/grid_index.js#L175-L240
This method collects boxes and circles in a specified cell intersecting a given bounding box.
GridItem
Definition: symbol/grid_index.js#L3-L9
;
Placement
Definition: symbol/placement.js#L192-L1184
Placement#retainedQueryData
Definition: symbol/placement.js#L205
retainedQueryData: ;
Please see also RetainedQueryData
.
Placement#getBucketParts
Definition: symbol/placement.js#L233-L333
LayerPlacement#continuePlacement
calls this method at style/pauseable_placement.js#L37:
bucketParts, styleLayer, tile, this._sortAcrossTiles;
Please see also the corresponding section in the previous blog post.
Placement#placeLayerBucketPart
Definition: symbol/placement.js#L386-L808
LayerPlacement#continuePlacement
calls this method at style/pauseable_placement.js#L52:
bucketPart, this._seenCrossTileIDs, showCollisionBoxes, bucketPart.symbolInstanceStart === 0;
Please see also the corresponding section in the previous blog post.
Placement#placeLayerBucketPart.placeSymbol
Definition: symbol/placement.js#L439-L784
RetainedQueryData
Definition: symbol/placement.js#L87-L105
BucketPart
Definition: symbol/placement.js#L183-L188
;
Please see also TileLayerParameters
.
TileLayerParameters
Definition: symbol/placement.js#L169-L181
;
PauseablePlacement
Definition: style/pauseable_placement.js#L62-L132
PauseablePlacement#continuePlacement
Definition: style/pauseable_placement.js#L89-L126
This method calls LayerPlacement#continuePlacement
.
Style#_updatePlacement
calls this method at style/style.js#L1740:
this._order, this._layers, layerTiles;
LayerPlacement
Definition: style/pauseable_placement.js#L15-L60
LayerPlacement#continuePlacement
Definition: style/pauseable_placement.js#L32-L59
This method calls
PauseablePlacement#continuePlacement
calls this method at style/pauseable_placement.js#L109:
;
symbol_size.SizeData
Definition: symbol/symbol_size.js#L15-L32
;
symbol_size.InterpolatedSize
Definition: symbol/symbol_size.js#L34-L37
;
symbol_size.evaluateSizeForZoom
Definition: symbol/symbol_size.js#L92-L118
interpolate.InterpolationType
Definition: style-spec/expression/definitions/interpolate.js#L17-L20
;
Interpolate.interpolationFactor
Definition: style-spec/expression/definitions/interpolate.js#L45-L57
interpolate.exponentialInterpolation
Definition: style-spec/expression/definitions/interpolate.js#L255-L266
util.interpolate
Definition: style-spec/util/interpolate.js#L5-L7
util.clamp
Definition: util/util.js#L211-L213
SymbolInstanceArray
Definition: data/array_types.js#L1188-L1198
Each item in this array is SymbolInstanceStruct
.
SymbolInstanceStruct
Definition: data/array_types.js#L1146-L1179
CollisionArrays
Definition: data/bucket/symbol_bucket.js#L90-L99
;