forked from mapbox/mapbox-gl-js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbucket.js
132 lines (118 loc) · 4.65 KB
/
bucket.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// @flow
import type {CollisionBoxArray} from './array_types.js';
import type Style from '../style/style.js';
import type {TypedStyleLayer} from '../style/style_layer/typed_style_layer.js';
import type FeatureIndex from './feature_index.js';
import type Context from '../gl/context.js';
import type {FeatureStates} from '../source/source_state.js';
import type {SpritePositions} from '../util/image.js';
import type LineAtlas from '../render/line_atlas.js';
import type {CanonicalTileID} from '../source/tile_id.js';
import type {TileTransform} from '../geo/projection/tile_transform.js';
import type Point from '@mapbox/point-geometry';
import type {ProjectionSpecification} from '../style-spec/types.js';
import type {IVectorTileFeature, IVectorTileLayer} from '@mapbox/vector-tile';
export type BucketParameters<Layer: TypedStyleLayer> = {
index: number,
layers: Array<Layer>,
zoom: number,
canonical: CanonicalTileID,
pixelRatio: number,
overscaling: number,
collisionBoxArray: CollisionBoxArray,
sourceLayerIndex: number,
sourceID: string,
projection: ProjectionSpecification
}
export type PopulateParameters = {
featureIndex: FeatureIndex,
iconDependencies: {},
patternDependencies: {},
glyphDependencies: {},
availableImages: Array<string>,
lineAtlas: LineAtlas,
brightness: ?number,
}
export type IndexedFeature = {
feature: IVectorTileFeature,
id: number | string | void,
index: number,
sourceLayerIndex: number,
}
export type BucketFeature = {|
index: number,
sourceLayerIndex: number,
geometry: Array<Array<Point>>,
properties: Object,
type: 1 | 2 | 3,
id?: any,
+patterns: {[_: string]: string},
sortKey?: number
|};
/**
* The `Bucket` interface is the single point of knowledge about turning vector
* tiles into WebGL buffers.
*
* `Bucket` is an abstract interface. An implementation exists for each style layer type.
* Create a bucket via the `StyleLayer#createBucket` method.
*
* The concrete bucket types, using layout options from the style layer,
* transform feature geometries into vertex and index data for use by the
* vertex shader. They also (via `ProgramConfiguration`) use feature
* properties and the zoom level to populate the attributes needed for
* data-driven styling.
*
* Buckets are designed to be built on a worker thread and then serialized and
* transferred back to the main thread for rendering. On the worker side, a
* bucket's vertex, index, and attribute data is stored in `bucket.arrays:
* ArrayGroup`. When a bucket's data is serialized and sent back to the main
* thread, is gets deserialized (using `new Bucket(serializedBucketData)`, with
* the array data now stored in `bucket.buffers: BufferGroup`. BufferGroups
* hold the same data as ArrayGroups, but are tuned for consumption by WebGL.
*
* @private
*/
export interface Bucket {
layerIds: Array<string>;
hasPattern: boolean;
+layers: Array<any>;
+stateDependentLayers: Array<any>;
+stateDependentLayerIds: Array<string>;
populate(features: Array<IndexedFeature>, options: PopulateParameters, canonical: CanonicalTileID, tileTransform: TileTransform): void;
update(states: FeatureStates, vtLayer: IVectorTileLayer, availableImages: Array<string>, imagePositions: SpritePositions, brightness: ?number): void;
isEmpty(): boolean;
upload(context: Context): void;
uploadPending(): boolean;
/**
* Release the WebGL resources associated with the buffers. Note that because
* buckets are shared between layers having the same layout properties, they
* must be destroyed in groups (all buckets for a tile, or all symbol buckets).
*
* @private
*/
destroy(): void;
}
export function deserialize(input: Array<Bucket>, style: Style): {[_: string]: Bucket} {
const output = {};
// Guard against the case where the map's style has been set to null while
// this bucket has been parsing.
if (!style) return output;
for (const bucket of input) {
const layers = bucket.layerIds
.map((id) => style.getLayer(id))
.filter(Boolean);
if (layers.length === 0) {
continue;
}
// look up StyleLayer objects from layer ids (since we don't
// want to waste time serializing/copying them from the worker)
(bucket: any).layers = layers;
if ((bucket: any).stateDependentLayerIds) {
(bucket: any).stateDependentLayers = (bucket: any).stateDependentLayerIds.map((lId) => layers.filter((l) => l.id === lId)[0]);
}
for (const layer of layers) {
output[layer.fqid] = bucket;
}
}
return output;
}