maplibre-gl 2.2.0-pre.3 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -14
- package/build/generate-debug-index-file.ts +19 -0
- package/build/generate-style-code.ts +6 -1
- package/build/generate-style-spec.ts +151 -35
- package/build/generate-typings.ts +1 -1
- package/build/rollup_plugins.ts +4 -1
- package/dist/maplibre-gl-csp-worker.js +1 -1
- package/dist/maplibre-gl-csp-worker.js.map +1 -1
- package/dist/maplibre-gl-csp.js +1 -1
- package/dist/maplibre-gl-csp.js.map +1 -1
- package/dist/maplibre-gl-dev.js +364 -3124
- package/dist/maplibre-gl.css +1 -1
- package/dist/maplibre-gl.d.ts +439 -151
- package/dist/maplibre-gl.js +4 -4
- package/dist/maplibre-gl.js.map +1 -1
- package/package.json +68 -65
- package/src/css/maplibre-gl.css +39 -32
- package/src/data/bucket/fill_bucket.test.ts +1 -0
- package/src/data/bucket/symbol_bucket.test.ts +2 -0
- package/src/data/evaluation_feature.ts +1 -1
- package/src/data/program_configuration.ts +2 -2
- package/src/geo/transform.ts +4 -4
- package/src/gl/vertex_buffer.ts +4 -4
- package/src/index.ts +1 -1
- package/src/render/image_atlas.ts +1 -0
- package/src/render/image_manager.ts +1 -0
- package/src/render/program/debug_program.ts +1 -1
- package/src/render/render_to_texture.ts +3 -0
- package/src/render/terrain.ts +21 -21
- package/src/shaders/README.md +2 -2
- package/src/source/geojson_worker_source.test.ts +2 -2
- package/src/source/geojson_wrapper.test.ts +1 -1
- package/src/source/image_source.test.ts +8 -8
- package/src/source/image_source.ts +1 -1
- package/src/source/raster_tile_source.test.ts +1 -1
- package/src/source/source_cache.test.ts +12 -12
- package/src/source/source_cache.ts +1 -1
- package/src/source/terrain_source_cache.ts +3 -3
- package/src/source/vector_tile_source.test.ts +1 -1
- package/src/source/vector_tile_worker_source.test.ts +1 -1
- package/src/source/video_source.test.ts +2 -2
- package/src/source/worker.ts +2 -4
- package/src/style/light.test.ts +1 -1
- package/src/style/style.test.ts +3 -3
- package/src/style/style.ts +2 -2
- package/src/style/style_layer/background_style_layer_properties.g.ts +1 -0
- package/src/style/style_layer/circle_style_layer_properties.g.ts +1 -0
- package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +1 -0
- package/src/style/style_layer/fill_style_layer_properties.g.ts +1 -0
- package/src/style/style_layer/heatmap_style_layer_properties.g.ts +1 -0
- package/src/style/style_layer/hillshade_style_layer_properties.g.ts +1 -0
- package/src/style/style_layer/line_style_layer_properties.g.ts +1 -0
- package/src/style/style_layer/raster_style_layer_properties.g.ts +1 -0
- package/src/style/style_layer/symbol_style_layer.ts +16 -1
- package/src/style/style_layer/symbol_style_layer_properties.g.ts +4 -3
- package/src/style-spec/CHANGELOG.md +5 -0
- package/src/style-spec/composite.test.ts +2 -0
- package/src/style-spec/diff.test.ts +3 -3
- package/src/style-spec/empty.ts +3 -2
- package/src/style-spec/expression/definitions/coercion.ts +13 -2
- package/src/style-spec/expression/definitions/interpolate.ts +1 -0
- package/src/style-spec/expression/expression.test.ts +1 -1
- package/src/style-spec/expression/expression.ts +3 -0
- package/src/style-spec/expression/index.ts +8 -2
- package/src/style-spec/expression/parsing_context.ts +2 -0
- package/src/style-spec/expression/types.ts +6 -1
- package/src/style-spec/expression/values.ts +9 -4
- package/src/style-spec/feature_filter/convert.ts +65 -65
- package/src/style-spec/feature_filter/feature_filter.test.ts +45 -4
- package/src/style-spec/feature_filter/index.ts +2 -1
- package/src/style-spec/function/index.test.ts +117 -1
- package/src/style-spec/function/index.ts +24 -12
- package/src/style-spec/migrate/expressions.ts +1 -1
- package/src/style-spec/migrate/v8.test.ts +2 -0
- package/src/style-spec/migrate/v9.test.ts +6 -4
- package/src/style-spec/migrate.test.ts +3 -1
- package/src/style-spec/package.json +1 -1
- package/src/style-spec/reference/latest.ts +2 -2
- package/src/style-spec/reference/v8.json +9 -6
- package/src/style-spec/style-spec.test.ts +2 -1
- package/src/style-spec/style-spec.ts +18 -9
- package/src/style-spec/types.g.ts +152 -36
- package/src/style-spec/util/interpolate.test.ts +5 -0
- package/src/style-spec/util/interpolate.ts +12 -0
- package/src/style-spec/util/padding.test.ts +27 -0
- package/src/style-spec/util/padding.ts +64 -0
- package/src/style-spec/validate/validate.ts +3 -1
- package/src/style-spec/validate/validate_padding.test.ts +82 -0
- package/src/style-spec/validate/validate_padding.ts +36 -0
- package/src/style-spec/validate_style.ts +1 -1
- package/src/symbol/check_max_angle.test.ts +5 -5
- package/src/symbol/collision_feature.test.ts +22 -5
- package/src/symbol/collision_feature.ts +7 -5
- package/src/symbol/collision_index.ts +1 -1
- package/src/symbol/get_anchors.test.ts +4 -4
- package/src/symbol/projection.ts +1 -1
- package/src/symbol/quads.test.ts +1 -1
- package/src/symbol/shaping.ts +10 -10
- package/src/symbol/symbol_layout.ts +5 -4
- package/src/symbol/symbol_style_layer.test.ts +1 -1
- package/src/ui/camera.test.ts +11 -11
- package/src/ui/control/geolocate_control.ts +1 -1
- package/src/ui/control/terrain_control.ts +4 -4
- package/src/ui/handler/cooperative_gestures.test.ts +167 -0
- package/src/ui/handler/drag_pan.test.ts +2 -1
- package/src/ui/handler/scroll_zoom.ts +7 -0
- package/src/ui/handler/touch_pan.ts +22 -2
- package/src/ui/handler/touch_zoom_rotate.ts +18 -1
- package/src/ui/handler_manager.ts +2 -2
- package/src/ui/map.test.ts +16 -16
- package/src/ui/map.ts +76 -8
- package/src/ui/map_events.test.ts +33 -32
- package/src/ui/popup.test.ts +2 -2
- package/src/util/ajax.test.ts +5 -5
- package/src/util/ajax.ts +1 -1
- package/src/util/classify_rings.test.ts +27 -27
- package/src/util/primitives.ts +4 -4
- package/src/util/resolve_tokens.test.ts +1 -1
- package/src/util/tile_request_cache.test.ts +5 -5
- package/src/util/util.test.ts +5 -5
- package/src/util/util.ts +2 -3
|
@@ -79,7 +79,7 @@ describe('RasterTileSource', () => {
|
|
|
79
79
|
|
|
80
80
|
source.on('data', (e) => {
|
|
81
81
|
if (e.sourceDataType === 'metadata') {
|
|
82
|
-
expect(source.tileBounds.bounds).toEqual({_sw:{lng: -47, lat: -7}, _ne:{lng: -45, lat: 90}});
|
|
82
|
+
expect(source.tileBounds.bounds).toEqual({_sw: {lng: -47, lat: -7}, _ne: {lng: -45, lat: 90}});
|
|
83
83
|
done();
|
|
84
84
|
}
|
|
85
85
|
});
|
|
@@ -485,7 +485,7 @@ describe('SourceCache / Source lifecycle', () => {
|
|
|
485
485
|
transform.resize(511, 511);
|
|
486
486
|
transform.zoom = 0;
|
|
487
487
|
|
|
488
|
-
const expected = [
|
|
488
|
+
const expected = [new OverscaledTileID(0, 0, 0, 0, 0).key, new OverscaledTileID(0, 0, 0, 0, 0).key];
|
|
489
489
|
expect.assertions(expected.length);
|
|
490
490
|
|
|
491
491
|
const sourceCache = createSourceCache({
|
|
@@ -1054,9 +1054,9 @@ describe('SourceCache#_updateRetainedTiles', () => {
|
|
|
1054
1054
|
|
|
1055
1055
|
expect(retained).toEqual({
|
|
1056
1056
|
// parent of ideal tile 0/0/0
|
|
1057
|
-
'000'
|
|
1057
|
+
'000': new OverscaledTileID(0, 0, 0, 0, 0),
|
|
1058
1058
|
// ideal tile id 1/0/1
|
|
1059
|
-
'211'
|
|
1059
|
+
'211': new OverscaledTileID(1, 0, 1, 0, 1)
|
|
1060
1060
|
});
|
|
1061
1061
|
|
|
1062
1062
|
addTileSpy.mockClear();
|
|
@@ -1069,7 +1069,7 @@ describe('SourceCache#_updateRetainedTiles', () => {
|
|
|
1069
1069
|
expect(getTileSpy).not.toHaveBeenCalled();
|
|
1070
1070
|
expect(retainedLoaded).toEqual({
|
|
1071
1071
|
// only ideal tile retained
|
|
1072
|
-
'211'
|
|
1072
|
+
'211': new OverscaledTileID(1, 0, 1, 0, 1)
|
|
1073
1073
|
});
|
|
1074
1074
|
});
|
|
1075
1075
|
|
|
@@ -1119,9 +1119,9 @@ describe('SourceCache#_updateRetainedTiles', () => {
|
|
|
1119
1119
|
expect(retained).toEqual({
|
|
1120
1120
|
// parent of ideal tile (0, 0, 0) (only partially covered by loaded child
|
|
1121
1121
|
// tiles, so we still need to load the parent)
|
|
1122
|
-
'000'
|
|
1122
|
+
'000': new OverscaledTileID(0, 0, 0, 0, 0),
|
|
1123
1123
|
// ideal tile id (1, 0, 0)
|
|
1124
|
-
'011'
|
|
1124
|
+
'011': new OverscaledTileID(1, 0, 1, 0, 0),
|
|
1125
1125
|
// loaded child tile (2, 0, 0)
|
|
1126
1126
|
'022': new OverscaledTileID(2, 0, 2, 0, 0)
|
|
1127
1127
|
});
|
|
@@ -1134,9 +1134,9 @@ describe('SourceCache#_updateRetainedTiles', () => {
|
|
|
1134
1134
|
expect(retained).toEqual({
|
|
1135
1135
|
// parent of ideal tile (0, 0, 0) (only partially covered by loaded child
|
|
1136
1136
|
// tiles, so we still need to load the parent)
|
|
1137
|
-
'000'
|
|
1137
|
+
'000': new OverscaledTileID(0, 0, 0, 0, 0),
|
|
1138
1138
|
// ideal tile id (1, 0, 0)
|
|
1139
|
-
'011'
|
|
1139
|
+
'011': new OverscaledTileID(1, 0, 1, 0, 0)
|
|
1140
1140
|
});
|
|
1141
1141
|
|
|
1142
1142
|
});
|
|
@@ -1163,7 +1163,7 @@ describe('SourceCache#_updateRetainedTiles', () => {
|
|
|
1163
1163
|
|
|
1164
1164
|
expect(retained).toEqual({
|
|
1165
1165
|
// ideal tile id (2, 0, 0)
|
|
1166
|
-
'022'
|
|
1166
|
+
'022': new OverscaledTileID(2, 0, 2, 0, 0)
|
|
1167
1167
|
});
|
|
1168
1168
|
|
|
1169
1169
|
});
|
|
@@ -1191,7 +1191,7 @@ describe('SourceCache#_updateRetainedTiles', () => {
|
|
|
1191
1191
|
|
|
1192
1192
|
expect(retained).toEqual({
|
|
1193
1193
|
// ideal tile id (2, 0, 0)
|
|
1194
|
-
'022'
|
|
1194
|
+
'022': new OverscaledTileID(2, 0, 2, 0, 0)
|
|
1195
1195
|
});
|
|
1196
1196
|
|
|
1197
1197
|
});
|
|
@@ -1352,7 +1352,7 @@ describe('SourceCache#tilesIn', () => {
|
|
|
1352
1352
|
expect(tiles[0].tile.tileID.key).toBe('011');
|
|
1353
1353
|
expect(tiles[0].tile.tileSize).toBe(512);
|
|
1354
1354
|
expect(tiles[0].scale).toBe(1);
|
|
1355
|
-
expect(round(tiles[0].queryGeometry)).toEqual([{x: 4096, y: 4050}, {x:12288, y: 8146}]);
|
|
1355
|
+
expect(round(tiles[0].queryGeometry)).toEqual([{x: 4096, y: 4050}, {x: 12288, y: 8146}]);
|
|
1356
1356
|
|
|
1357
1357
|
expect(tiles[1].tile.tileID.key).toBe('111');
|
|
1358
1358
|
expect(tiles[1].tile.tileSize).toBe(512);
|
|
@@ -1404,7 +1404,7 @@ describe('SourceCache#tilesIn', () => {
|
|
|
1404
1404
|
expect(tiles[0].tile.tileID.key).toBe('012');
|
|
1405
1405
|
expect(tiles[0].tile.tileSize).toBe(1024);
|
|
1406
1406
|
expect(tiles[0].scale).toBe(1);
|
|
1407
|
-
expect(round(tiles[0].queryGeometry)).toEqual([{x: 4096, y: 4050}, {x:12288, y: 8146}]);
|
|
1407
|
+
expect(round(tiles[0].queryGeometry)).toEqual([{x: 4096, y: 4050}, {x: 12288, y: 8146}]);
|
|
1408
1408
|
|
|
1409
1409
|
expect(tiles[1].tile.tileID.key).toBe('112');
|
|
1410
1410
|
expect(tiles[1].tile.tileSize).toBe(1024);
|
|
@@ -492,7 +492,7 @@ class SourceCache extends Evented {
|
|
|
492
492
|
* are inside the viewport.
|
|
493
493
|
* @private
|
|
494
494
|
*/
|
|
495
|
-
update(transform: Transform, terrain
|
|
495
|
+
update(transform: Transform, terrain?: Terrain) {
|
|
496
496
|
this.transform = transform;
|
|
497
497
|
this.terrain = terrain;
|
|
498
498
|
if (!this._sourceLoaded || this._paused) { return; }
|
|
@@ -133,11 +133,11 @@ export default class TerrainSourceCache extends Evented {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
/**
|
|
136
|
-
*
|
|
136
|
+
* Searches for the corresponding current renderable terrain-tiles
|
|
137
137
|
* @param {OverscaledTileID} tileID - the tile to look for
|
|
138
|
-
* @returns {
|
|
138
|
+
* @returns {Record<string, OverscaledTileID>} - the tiles that were found
|
|
139
139
|
*/
|
|
140
|
-
getTerrainCoords(tileID: OverscaledTileID):
|
|
140
|
+
getTerrainCoords(tileID: OverscaledTileID): Record<string, OverscaledTileID> {
|
|
141
141
|
const coords = {};
|
|
142
142
|
for (const key of this._renderableTilesKeys) {
|
|
143
143
|
const _tileID = this._tiles[key].tileID;
|
|
@@ -253,7 +253,7 @@ describe('VectorTileSource', () => {
|
|
|
253
253
|
|
|
254
254
|
source.on('data', (e) => {
|
|
255
255
|
if (e.sourceDataType === 'metadata') {
|
|
256
|
-
expect(source.tileBounds.bounds).toEqual({_sw:{lng: -47, lat: -7}, _ne:{lng: -45, lat: 90}});
|
|
256
|
+
expect(source.tileBounds.bounds).toEqual({_sw: {lng: -47, lat: -7}, _ne: {lng: -45, lat: 90}});
|
|
257
257
|
done();
|
|
258
258
|
}
|
|
259
259
|
});
|
|
@@ -236,7 +236,7 @@ describe('vector tile worker source', () => {
|
|
|
236
236
|
|
|
237
237
|
const source = new VectorTileWorkerSource(actor, layerIndex, [], loadVectorData);
|
|
238
238
|
|
|
239
|
-
window.performance.getEntriesByName = jest.fn().mockReturnValue([
|
|
239
|
+
window.performance.getEntriesByName = jest.fn().mockReturnValue([exampleResourceTiming]);
|
|
240
240
|
|
|
241
241
|
source.loadTile({
|
|
242
242
|
source: 'source',
|
|
@@ -19,7 +19,7 @@ describe('VideoSource', () => {
|
|
|
19
19
|
// Attribution File:Volcano Lava Sample.webm: U.S. Geological Survey (USGS), Public domain, via Wikimedia Commons
|
|
20
20
|
const source = createSource({
|
|
21
21
|
type: 'video',
|
|
22
|
-
urls
|
|
22
|
+
urls: ['cropped.mp4', 'https://upload.wikimedia.org/wikipedia/commons/2/22/Volcano_Lava_Sample.webm'],
|
|
23
23
|
coordinates: [
|
|
24
24
|
[-76.54, 39.18],
|
|
25
25
|
[-76.52, 39.18],
|
|
@@ -50,7 +50,7 @@ describe('VideoSource', () => {
|
|
|
50
50
|
const source = createSource({
|
|
51
51
|
type: 'video',
|
|
52
52
|
video: el,
|
|
53
|
-
urls
|
|
53
|
+
urls: ['cropped.mp4', 'https://upload.wikimedia.org/wikipedia/commons/2/22/Volcano_Lava_Sample.webm'],
|
|
54
54
|
coordinates: [
|
|
55
55
|
[-76.54, 39.18],
|
|
56
56
|
[-76.52, 39.18],
|
package/src/source/worker.ts
CHANGED
|
@@ -7,6 +7,7 @@ import GeoJSONWorkerSource from './geojson_worker_source';
|
|
|
7
7
|
import assert from 'assert';
|
|
8
8
|
import {plugin as globalRTLTextPlugin} from './rtl_text_plugin';
|
|
9
9
|
import {enforceCacheSizeLimit} from '../util/tile_request_cache';
|
|
10
|
+
import {isWorker} from '../util/util';
|
|
10
11
|
|
|
11
12
|
import type {
|
|
12
13
|
WorkerSource,
|
|
@@ -267,9 +268,6 @@ export default class Worker {
|
|
|
267
268
|
}
|
|
268
269
|
}
|
|
269
270
|
|
|
270
|
-
|
|
271
|
-
if (typeof WorkerGlobalScope !== 'undefined' &&
|
|
272
|
-
typeof self !== 'undefined' &&
|
|
273
|
-
self instanceof WorkerGlobalScope) {
|
|
271
|
+
if (isWorker()) {
|
|
274
272
|
(self as any).worker = new Worker(self as any);
|
|
275
273
|
}
|
package/src/style/light.test.ts
CHANGED
|
@@ -77,7 +77,7 @@ describe('Light#setLight', () => {
|
|
|
77
77
|
const light = new Light({});
|
|
78
78
|
|
|
79
79
|
const lightSpy = jest.spyOn(light, '_validate');
|
|
80
|
-
light.setLight({color: [999]}, {validate: false});
|
|
80
|
+
light.setLight({color: [999]} as any, {validate: false});
|
|
81
81
|
light.updateTransitions({transition: false} as any as TransitionParameters);
|
|
82
82
|
light.recalculate({zoom: 16, zoomHistory: {}, now: 10} as EvaluationParameters);
|
|
83
83
|
|
package/src/style/style.test.ts
CHANGED
|
@@ -883,7 +883,7 @@ describe('Style#addLayer', () => {
|
|
|
883
883
|
'type': 'geojson',
|
|
884
884
|
'data': {
|
|
885
885
|
'type': 'Point',
|
|
886
|
-
'coordinates': [
|
|
886
|
+
'coordinates': [0, 0]
|
|
887
887
|
}
|
|
888
888
|
};
|
|
889
889
|
const layer = {id: 'inline-source-layer', type: 'circle', source} as any as LayerSpecification;
|
|
@@ -1901,7 +1901,7 @@ describe('Style#queryRenderedFeatures', () => {
|
|
|
1901
1901
|
errors++;
|
|
1902
1902
|
}
|
|
1903
1903
|
});
|
|
1904
|
-
style.queryRenderedFeatures([{x: 0, y: 0}], {layers:'string'}, transform);
|
|
1904
|
+
style.queryRenderedFeatures([{x: 0, y: 0}], {layers: 'string'}, transform);
|
|
1905
1905
|
expect(errors).toBe(1);
|
|
1906
1906
|
});
|
|
1907
1907
|
|
|
@@ -1939,7 +1939,7 @@ describe('Style#queryRenderedFeatures', () => {
|
|
|
1939
1939
|
jest.spyOn(style, 'fire').mockImplementation((event) => {
|
|
1940
1940
|
if (event['error'] && event['error'].message.includes('does not exist in the map\'s style and cannot be queried for features.')) errors++;
|
|
1941
1941
|
});
|
|
1942
|
-
const results = style.queryRenderedFeatures([{x: 0, y: 0}], {layers:['merp']}, transform);
|
|
1942
|
+
const results = style.queryRenderedFeatures([{x: 0, y: 0}], {layers: ['merp']}, transform);
|
|
1943
1943
|
expect(errors).toBe(1);
|
|
1944
1944
|
expect(results).toHaveLength(0);
|
|
1945
1945
|
});
|
package/src/style/style.ts
CHANGED
|
@@ -441,7 +441,7 @@ class Style extends Evented {
|
|
|
441
441
|
for (const sourceId in sourcesUsedBefore) {
|
|
442
442
|
const sourceCache = this.sourceCaches[sourceId];
|
|
443
443
|
if (sourcesUsedBefore[sourceId] !== sourceCache.used) {
|
|
444
|
-
sourceCache.fire(new Event('data', {sourceDataType: 'visibility', dataType:'source', sourceId}));
|
|
444
|
+
sourceCache.fire(new Event('data', {sourceDataType: 'visibility', dataType: 'source', sourceId}));
|
|
445
445
|
}
|
|
446
446
|
}
|
|
447
447
|
|
|
@@ -663,7 +663,7 @@ class Style extends Evented {
|
|
|
663
663
|
const sourceCache = this.sourceCaches[id];
|
|
664
664
|
delete this.sourceCaches[id];
|
|
665
665
|
delete this._updatedSources[id];
|
|
666
|
-
sourceCache.fire(new Event('data', {sourceDataType: 'metadata', dataType:'source', sourceId: id}));
|
|
666
|
+
sourceCache.fire(new Event('data', {sourceDataType: 'metadata', dataType: 'source', sourceId: id}));
|
|
667
667
|
sourceCache.setEventedParent(null);
|
|
668
668
|
sourceCache.onRemove(this.map);
|
|
669
669
|
this._changed = true;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import StyleLayer from '../style_layer';
|
|
2
2
|
|
|
3
3
|
import assert from 'assert';
|
|
4
|
-
import SymbolBucket from '../../data/bucket/symbol_bucket';
|
|
4
|
+
import SymbolBucket, {SymbolFeature} from '../../data/bucket/symbol_bucket';
|
|
5
5
|
import resolveTokens from '../../util/resolve_tokens';
|
|
6
6
|
import properties, {SymbolLayoutPropsPossiblyEvaluated, SymbolPaintPropsPossiblyEvaluated} from './symbol_style_layer_properties.g';
|
|
7
7
|
|
|
@@ -204,4 +204,19 @@ export function getOverlapMode(layout: PossiblyEvaluated<SymbolLayoutProps, Symb
|
|
|
204
204
|
return result;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
+
export type SymbolPadding = [number, number, number, number];
|
|
208
|
+
|
|
209
|
+
export function getIconPadding(layout: PossiblyEvaluated<SymbolLayoutProps, SymbolLayoutPropsPossiblyEvaluated>, feature: SymbolFeature, canonical: CanonicalTileID, pixelRatio = 1): SymbolPadding {
|
|
210
|
+
// Support text-padding in addition to icon-padding? Unclear how to apply asymmetric text-padding to the radius for collision circles.
|
|
211
|
+
const result = layout.get('icon-padding').evaluate(feature, {}, canonical);
|
|
212
|
+
const values = result && result.values;
|
|
213
|
+
|
|
214
|
+
return [
|
|
215
|
+
values[0] * pixelRatio,
|
|
216
|
+
values[1] * pixelRatio,
|
|
217
|
+
values[2] * pixelRatio,
|
|
218
|
+
values[3] * pixelRatio,
|
|
219
|
+
];
|
|
220
|
+
}
|
|
221
|
+
|
|
207
222
|
export default SymbolStyleLayer;
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from '../properties';
|
|
16
16
|
|
|
17
17
|
import type Color from '../../style-spec/util/color';
|
|
18
|
+
import type Padding from '../../style-spec/util/padding';
|
|
18
19
|
|
|
19
20
|
import type Formatted from '../../style-spec/expression/types/formatted';
|
|
20
21
|
|
|
@@ -41,7 +42,7 @@ export type SymbolLayoutProps = {
|
|
|
41
42
|
"icon-text-fit-padding": DataConstantProperty<[number, number, number, number]>,
|
|
42
43
|
"icon-image": DataDrivenProperty<ResolvedImage>,
|
|
43
44
|
"icon-rotate": DataDrivenProperty<number>,
|
|
44
|
-
"icon-padding":
|
|
45
|
+
"icon-padding": DataDrivenProperty<Padding>,
|
|
45
46
|
"icon-keep-upright": DataConstantProperty<boolean>,
|
|
46
47
|
"icon-offset": DataDrivenProperty<[number, number]>,
|
|
47
48
|
"icon-anchor": DataDrivenProperty<"center" | "left" | "right" | "top" | "bottom" | "top-left" | "top-right" | "bottom-left" | "bottom-right">,
|
|
@@ -87,7 +88,7 @@ export type SymbolLayoutPropsPossiblyEvaluated = {
|
|
|
87
88
|
"icon-text-fit-padding": [number, number, number, number],
|
|
88
89
|
"icon-image": PossiblyEvaluatedPropertyValue<ResolvedImage>,
|
|
89
90
|
"icon-rotate": PossiblyEvaluatedPropertyValue<number>,
|
|
90
|
-
"icon-padding":
|
|
91
|
+
"icon-padding": PossiblyEvaluatedPropertyValue<Padding>,
|
|
91
92
|
"icon-keep-upright": boolean,
|
|
92
93
|
"icon-offset": PossiblyEvaluatedPropertyValue<[number, number]>,
|
|
93
94
|
"icon-anchor": PossiblyEvaluatedPropertyValue<"center" | "left" | "right" | "top" | "bottom" | "top-left" | "top-right" | "bottom-left" | "bottom-right">,
|
|
@@ -133,7 +134,7 @@ const layout: Properties<SymbolLayoutProps> = new Properties({
|
|
|
133
134
|
"icon-text-fit-padding": new DataConstantProperty(styleSpec["layout_symbol"]["icon-text-fit-padding"] as any as StylePropertySpecification),
|
|
134
135
|
"icon-image": new DataDrivenProperty(styleSpec["layout_symbol"]["icon-image"] as any as StylePropertySpecification),
|
|
135
136
|
"icon-rotate": new DataDrivenProperty(styleSpec["layout_symbol"]["icon-rotate"] as any as StylePropertySpecification),
|
|
136
|
-
"icon-padding": new
|
|
137
|
+
"icon-padding": new DataDrivenProperty(styleSpec["layout_symbol"]["icon-padding"] as any as StylePropertySpecification),
|
|
137
138
|
"icon-keep-upright": new DataConstantProperty(styleSpec["layout_symbol"]["icon-keep-upright"] as any as StylePropertySpecification),
|
|
138
139
|
"icon-offset": new DataDrivenProperty(styleSpec["layout_symbol"]["icon-offset"] as any as StylePropertySpecification),
|
|
139
140
|
"icon-anchor": new DataDrivenProperty(styleSpec["layout_symbol"]["icon-anchor"] as any as StylePropertySpecification),
|
|
@@ -88,7 +88,7 @@ test('diff', () => {
|
|
|
88
88
|
}, {
|
|
89
89
|
layers: [{id: 'a', filter: ['==', 'foo', 'baz']}]
|
|
90
90
|
})).toEqual([
|
|
91
|
-
{command: 'setFilter', args: ['a', [
|
|
91
|
+
{command: 'setFilter', args: ['a', ['==', 'foo', 'baz']]}
|
|
92
92
|
]);
|
|
93
93
|
|
|
94
94
|
expect(diffStyles({
|
|
@@ -329,9 +329,9 @@ test('diff', () => {
|
|
|
329
329
|
]);
|
|
330
330
|
|
|
331
331
|
expect(diffStyles({
|
|
332
|
-
layers: [
|
|
332
|
+
layers: [{id: 'a', source: 'source-one'}]
|
|
333
333
|
}, {
|
|
334
|
-
layers: [
|
|
334
|
+
layers: [{id: 'a', source: 'source-two'}]
|
|
335
335
|
})).toEqual([
|
|
336
336
|
{command: 'removeLayer', args: ['a']},
|
|
337
337
|
{command: 'addLayer', args: [{id: 'a', source: 'source-two'}, undefined]}
|
package/src/style-spec/empty.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import latest from './reference/latest';
|
|
2
|
+
import {StyleSpecification} from './types.g';
|
|
2
3
|
|
|
3
|
-
export default function emptyStyle() {
|
|
4
|
+
export default function emptyStyle(): StyleSpecification {
|
|
4
5
|
const style = {};
|
|
5
6
|
|
|
6
7
|
const version = latest['$version'];
|
|
@@ -25,5 +26,5 @@ export default function emptyStyle() {
|
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
return style;
|
|
29
|
+
return style as StyleSpecification;
|
|
29
30
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'assert';
|
|
2
2
|
|
|
3
3
|
import {BooleanType, ColorType, NumberType, StringType, ValueType} from '../types';
|
|
4
|
-
import {Color, toString as valueToString, validateRGBA} from '../values';
|
|
4
|
+
import {Color, Padding, toString as valueToString, validateRGBA} from '../values';
|
|
5
5
|
import RuntimeError from '../runtime_error';
|
|
6
6
|
import Formatted from '../types/formatted';
|
|
7
7
|
import ResolvedImage from '../types/resolved_image';
|
|
@@ -81,7 +81,18 @@ class Coercion implements Expression {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
throw new RuntimeError(error || `Could not parse color from value '${typeof input === 'string' ? input :
|
|
84
|
+
throw new RuntimeError(error || `Could not parse color from value '${typeof input === 'string' ? input : JSON.stringify(input)}'`);
|
|
85
|
+
} else if (this.type.kind === 'padding') {
|
|
86
|
+
let input;
|
|
87
|
+
for (const arg of this.args) {
|
|
88
|
+
input = arg.evaluate(ctx);
|
|
89
|
+
|
|
90
|
+
const pad = Padding.parse(input);
|
|
91
|
+
if (pad) {
|
|
92
|
+
return pad;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
throw new RuntimeError(`Could not parse padding from value '${typeof input === 'string' ? input : JSON.stringify(input)}'`);
|
|
85
96
|
} else if (this.type.kind === 'number') {
|
|
86
97
|
let value = null;
|
|
87
98
|
for (const arg of this.args) {
|
|
@@ -40,7 +40,7 @@ describe('createPropertyExpression', () => {
|
|
|
40
40
|
|
|
41
41
|
describe('evaluate expression', () => {
|
|
42
42
|
test('warns and falls back to default for invalid enum values', () => {
|
|
43
|
-
const {value} = createPropertyExpression([
|
|
43
|
+
const {value} = createPropertyExpression(['get', 'x'], {
|
|
44
44
|
type: 'enum',
|
|
45
45
|
values: {a: {}, b: {}, c: {}},
|
|
46
46
|
default: 'a',
|
|
@@ -2,6 +2,9 @@ import type {Type} from './types';
|
|
|
2
2
|
import type ParsingContext from './parsing_context';
|
|
3
3
|
import type EvaluationContext from './evaluation_context';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Expression
|
|
7
|
+
*/
|
|
5
8
|
export interface Expression {
|
|
6
9
|
readonly type: Type;
|
|
7
10
|
evaluate(ctx: EvaluationContext): any;
|
|
@@ -379,8 +379,10 @@ export function normalizePropertyExpression<T>(
|
|
|
379
379
|
|
|
380
380
|
} else {
|
|
381
381
|
let constant: any = value;
|
|
382
|
-
if (
|
|
382
|
+
if (specification.type === 'color' && typeof value === 'string') {
|
|
383
383
|
constant = Color.parse(value);
|
|
384
|
+
} else if (specification.type === 'padding' && (typeof value === 'number' || Array.isArray(value))) {
|
|
385
|
+
constant = Padding.parse(value as (number | number[]));
|
|
384
386
|
}
|
|
385
387
|
return {
|
|
386
388
|
kind: 'constant',
|
|
@@ -430,7 +432,8 @@ function findZoomCurve(expression: Expression): Step | Interpolate | ParsingErro
|
|
|
430
432
|
return result;
|
|
431
433
|
}
|
|
432
434
|
|
|
433
|
-
import {ColorType, StringType, NumberType, BooleanType, ValueType, FormattedType, ResolvedImageType, array} from './types';
|
|
435
|
+
import {ColorType, StringType, NumberType, BooleanType, ValueType, FormattedType, PaddingType, ResolvedImageType, array} from './types';
|
|
436
|
+
import Padding from '../util/padding';
|
|
434
437
|
|
|
435
438
|
function getExpectedType(spec: StylePropertySpecification): Type {
|
|
436
439
|
const types = {
|
|
@@ -440,6 +443,7 @@ function getExpectedType(spec: StylePropertySpecification): Type {
|
|
|
440
443
|
enum: StringType,
|
|
441
444
|
boolean: BooleanType,
|
|
442
445
|
formatted: FormattedType,
|
|
446
|
+
padding: PaddingType,
|
|
443
447
|
resolvedImage: ResolvedImageType
|
|
444
448
|
};
|
|
445
449
|
|
|
@@ -458,6 +462,8 @@ function getDefaultValue(spec: StylePropertySpecification): Value {
|
|
|
458
462
|
return new Color(0, 0, 0, 0);
|
|
459
463
|
} else if (spec.type === 'color') {
|
|
460
464
|
return Color.parse(spec.default) || null;
|
|
465
|
+
} else if (spec.type === 'padding') {
|
|
466
|
+
return Padding.parse(spec.default) || null;
|
|
461
467
|
} else if (spec.default === undefined) {
|
|
462
468
|
return null;
|
|
463
469
|
} else {
|
|
@@ -120,6 +120,8 @@ class ParsingContext {
|
|
|
120
120
|
parsed = annotate(parsed, expected, options.typeAnnotation || 'assert');
|
|
121
121
|
} else if ((expected.kind === 'color' || expected.kind === 'formatted' || expected.kind === 'resolvedImage') && (actual.kind === 'value' || actual.kind === 'string')) {
|
|
122
122
|
parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce');
|
|
123
|
+
} else if (expected.kind === 'padding' && (actual.kind === 'value' || actual.kind === 'number' || actual.kind === 'array')) {
|
|
124
|
+
parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce');
|
|
123
125
|
} else if (this.checkSubtype(expected, actual)) {
|
|
124
126
|
return null;
|
|
125
127
|
}
|
|
@@ -28,6 +28,9 @@ export type CollatorTypeT = {
|
|
|
28
28
|
export type FormattedTypeT = {
|
|
29
29
|
kind: 'formatted';
|
|
30
30
|
};
|
|
31
|
+
export type PaddingTypeT = {
|
|
32
|
+
kind: 'padding';
|
|
33
|
+
};
|
|
31
34
|
export type ResolvedImageTypeT = {
|
|
32
35
|
kind: 'resolvedImage';
|
|
33
36
|
};
|
|
@@ -35,7 +38,7 @@ export type ResolvedImageTypeT = {
|
|
|
35
38
|
export type EvaluationKind = 'constant' | 'source' | 'camera' | 'composite';
|
|
36
39
|
|
|
37
40
|
export type Type = NullTypeT | NumberTypeT | StringTypeT | BooleanTypeT | ColorTypeT | ObjectTypeT | ValueTypeT | // eslint-disable-line no-use-before-define
|
|
38
|
-
ArrayType | ErrorTypeT | CollatorTypeT | FormattedTypeT | ResolvedImageTypeT;
|
|
41
|
+
ArrayType | ErrorTypeT | CollatorTypeT | FormattedTypeT | PaddingTypeT | ResolvedImageTypeT;
|
|
39
42
|
|
|
40
43
|
export type ArrayType = {
|
|
41
44
|
kind: 'array';
|
|
@@ -55,6 +58,7 @@ export const ValueType = {kind: 'value'} as ValueTypeT;
|
|
|
55
58
|
export const ErrorType = {kind: 'error'} as ErrorTypeT;
|
|
56
59
|
export const CollatorType = {kind: 'collator'} as CollatorTypeT;
|
|
57
60
|
export const FormattedType = {kind: 'formatted'} as FormattedTypeT;
|
|
61
|
+
export const PaddingType = {kind: 'padding'} as PaddingTypeT;
|
|
58
62
|
export const ResolvedImageType = {kind: 'resolvedImage'} as ResolvedImageTypeT;
|
|
59
63
|
|
|
60
64
|
export function array(itemType: Type, N?: number | null): ArrayType {
|
|
@@ -85,6 +89,7 @@ const valueMemberTypes = [
|
|
|
85
89
|
FormattedType,
|
|
86
90
|
ObjectType,
|
|
87
91
|
array(ValueType),
|
|
92
|
+
PaddingType,
|
|
88
93
|
ResolvedImageType
|
|
89
94
|
];
|
|
90
95
|
|
|
@@ -3,8 +3,9 @@ import assert from 'assert';
|
|
|
3
3
|
import Color from '../util/color';
|
|
4
4
|
import Collator from './types/collator';
|
|
5
5
|
import Formatted from './types/formatted';
|
|
6
|
+
import Padding from '../util/padding';
|
|
6
7
|
import ResolvedImage from './types/resolved_image';
|
|
7
|
-
import {NullType, NumberType, StringType, BooleanType, ColorType, ObjectType, ValueType, CollatorType, FormattedType, ResolvedImageType, array} from './types';
|
|
8
|
+
import {NullType, NumberType, StringType, BooleanType, ColorType, ObjectType, ValueType, CollatorType, FormattedType, ResolvedImageType, array, PaddingType} from './types';
|
|
8
9
|
|
|
9
10
|
import type {Type} from './types';
|
|
10
11
|
|
|
@@ -27,7 +28,7 @@ export function validateRGBA(r: unknown, g: unknown, b: unknown, a?: unknown): s
|
|
|
27
28
|
return null;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
export type Value = null | string | boolean | number | Color | Collator | Formatted | ResolvedImage | ReadonlyArray<Value> | {
|
|
31
|
+
export type Value = null | string | boolean | number | Color | Collator | Formatted | Padding | ResolvedImage | ReadonlyArray<Value> | {
|
|
31
32
|
readonly [x: string]: Value;
|
|
32
33
|
};
|
|
33
34
|
|
|
@@ -46,6 +47,8 @@ export function isValue(mixed: unknown): boolean {
|
|
|
46
47
|
return true;
|
|
47
48
|
} else if (mixed instanceof Formatted) {
|
|
48
49
|
return true;
|
|
50
|
+
} else if (mixed instanceof Padding) {
|
|
51
|
+
return true;
|
|
49
52
|
} else if (mixed instanceof ResolvedImage) {
|
|
50
53
|
return true;
|
|
51
54
|
} else if (Array.isArray(mixed)) {
|
|
@@ -82,6 +85,8 @@ export function typeOf(value: Value): Type {
|
|
|
82
85
|
return CollatorType;
|
|
83
86
|
} else if (value instanceof Formatted) {
|
|
84
87
|
return FormattedType;
|
|
88
|
+
} else if (value instanceof Padding) {
|
|
89
|
+
return PaddingType;
|
|
85
90
|
} else if (value instanceof ResolvedImage) {
|
|
86
91
|
return ResolvedImageType;
|
|
87
92
|
} else if (Array.isArray(value)) {
|
|
@@ -113,11 +118,11 @@ export function toString(value: Value) {
|
|
|
113
118
|
return '';
|
|
114
119
|
} else if (type === 'string' || type === 'number' || type === 'boolean') {
|
|
115
120
|
return String(value);
|
|
116
|
-
} else if (value instanceof Color || value instanceof Formatted || value instanceof ResolvedImage) {
|
|
121
|
+
} else if (value instanceof Color || value instanceof Formatted || value instanceof Padding || value instanceof ResolvedImage) {
|
|
117
122
|
return value.toString();
|
|
118
123
|
} else {
|
|
119
124
|
return JSON.stringify(value);
|
|
120
125
|
}
|
|
121
126
|
}
|
|
122
127
|
|
|
123
|
-
export {Color, Collator};
|
|
128
|
+
export {Color, Collator, Padding};
|