maplibre-gl 2.2.0-pre.2 → 2.2.0
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 -8
- 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/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 +1317 -4304
- package/dist/maplibre-gl.css +1 -1
- package/dist/maplibre-gl.d.ts +443 -145
- package/dist/maplibre-gl.js +4 -4
- package/dist/maplibre-gl.js.map +1 -1
- package/package.json +70 -67
- package/src/css/maplibre-gl.css +48 -32
- package/src/data/bucket/fill_bucket.test.ts +1 -0
- package/src/data/bucket/symbol_bucket.test.ts +2 -0
- package/src/data/bucket/symbol_bucket.ts +1 -1
- package/src/data/evaluation_feature.ts +1 -1
- package/src/data/program_configuration.ts +2 -2
- package/src/geo/transform.test.ts +34 -1
- package/src/geo/transform.ts +25 -15
- package/src/gl/vertex_buffer.ts +4 -4
- package/src/index.ts +1 -1
- package/src/render/draw_debug.ts +1 -1
- package/src/render/draw_symbol.test.ts +2 -23
- package/src/render/draw_terrain.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.test.ts +119 -17
- package/src/render/terrain.ts +39 -21
- package/src/shaders/README.md +2 -2
- package/src/shaders/shaders.ts +3 -1
- 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/load_tilejson.ts +6 -1
- package/src/source/pixels_to_tile_units.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.test.ts +17 -2
- package/src/source/terrain_source_cache.ts +16 -12
- 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/style/light.test.ts +1 -1
- package/src/style/load_sprite.ts +1 -1
- package/src/style/parse_glyph_pbf.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/composite.ts +3 -2
- package/src/style-spec/diff.test.ts +3 -3
- package/src/style-spec/empty.ts +3 -2
- package/src/style-spec/expression/compound_expression.ts +0 -4
- package/src/style-spec/expression/definitions/assertion.ts +0 -18
- package/src/style-spec/expression/definitions/at.ts +0 -4
- package/src/style-spec/expression/definitions/case.ts +0 -6
- package/src/style-spec/expression/definitions/coalesce.ts +0 -6
- package/src/style-spec/expression/definitions/coercion.ts +13 -18
- package/src/style-spec/expression/definitions/collator.ts +0 -10
- package/src/style-spec/expression/definitions/comparison.ts +0 -6
- package/src/style-spec/expression/definitions/format.ts +0 -19
- package/src/style-spec/expression/definitions/image.ts +0 -4
- package/src/style-spec/expression/definitions/in.ts +0 -4
- package/src/style-spec/expression/definitions/index_of.ts +0 -8
- package/src/style-spec/expression/definitions/interpolate.ts +1 -25
- package/src/style-spec/expression/definitions/length.ts +0 -6
- package/src/style-spec/expression/definitions/let.ts +0 -9
- package/src/style-spec/expression/definitions/literal.ts +1 -23
- package/src/style-spec/expression/definitions/match.ts +0 -41
- package/src/style-spec/expression/definitions/number_format.ts +0 -17
- package/src/style-spec/expression/definitions/slice.ts +0 -8
- package/src/style-spec/expression/definitions/step.ts +0 -11
- package/src/style-spec/expression/definitions/var.ts +0 -4
- package/src/style-spec/expression/definitions/within.ts +0 -5
- package/src/style-spec/expression/expression.test.ts +1 -1
- package/src/style-spec/expression/expression.ts +3 -3
- 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/formatted.ts +0 -23
- package/src/style-spec/expression/types/resolved_image.ts +0 -4
- 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 +2 -2
- package/src/style-spec/migrate/v8.test.ts +2 -0
- package/src/style-spec/migrate/v8.ts +8 -7
- package/src/style-spec/migrate/v9.test.ts +6 -4
- package/src/style-spec/migrate/v9.ts +3 -2
- package/src/style-spec/migrate.test.ts +3 -1
- package/src/style-spec/migrate.ts +5 -4
- package/src/style-spec/package.json +1 -1
- package/src/style-spec/read_style.ts +2 -1
- package/src/style-spec/reference/latest.ts +1 -1
- 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 +8 -0
- package/src/style-spec/types.g.ts +152 -36
- package/src/style-spec/util/extend.ts +1 -1
- 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/util/ref_properties.ts +2 -1
- package/src/style-spec/validate/validate.ts +3 -1
- package/src/style-spec/validate/validate_expression.ts +2 -1
- package/src/style-spec/validate/validate_function.ts +2 -2
- package/src/style-spec/validate/validate_glyphs_url.ts +1 -1
- package/src/style-spec/validate/validate_object.ts +2 -2
- 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.min.ts +4 -3
- package/src/style-spec/validate_style.ts +4 -3
- 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/{mergelines.test.ts → merge_lines.test.ts} +1 -1
- package/src/symbol/{mergelines.ts → merge_lines.ts} +1 -1
- 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/symbol/transform_text.ts +3 -3
- 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 +17 -17
- 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/find_pole_of_inaccessibility.ts +1 -1
- package/src/util/primitives.ts +4 -4
- package/src/util/resolve_tokens.test.ts +1 -1
- package/src/util/smart_wrap.ts +1 -1
- package/src/util/tile_request_cache.test.ts +5 -5
- package/src/util/util.test.ts +5 -5
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import Point from '@mapbox/point-geometry';
|
|
2
2
|
import {indexTouches} from './handler_util';
|
|
3
|
+
import type Map from '../map';
|
|
4
|
+
import {GestureOptions} from '../map';
|
|
3
5
|
|
|
4
6
|
export default class TouchPanHandler {
|
|
5
7
|
|
|
@@ -11,12 +13,16 @@ export default class TouchPanHandler {
|
|
|
11
13
|
_minTouches: number;
|
|
12
14
|
_clickTolerance: number;
|
|
13
15
|
_sum: Point;
|
|
16
|
+
_map: Map;
|
|
17
|
+
_cancelCooperativeMessage: boolean;
|
|
14
18
|
|
|
15
19
|
constructor(options: {
|
|
16
20
|
clickTolerance: number;
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
cooperativeGestures: boolean | GestureOptions;
|
|
22
|
+
}, map: Map) {
|
|
23
|
+
this._minTouches = options.cooperativeGestures ? 2 : 1;
|
|
19
24
|
this._clickTolerance = options.clickTolerance || 1;
|
|
25
|
+
this._map = map;
|
|
20
26
|
this.reset();
|
|
21
27
|
}
|
|
22
28
|
|
|
@@ -24,6 +30,11 @@ export default class TouchPanHandler {
|
|
|
24
30
|
this._active = false;
|
|
25
31
|
this._touches = {};
|
|
26
32
|
this._sum = new Point(0, 0);
|
|
33
|
+
|
|
34
|
+
// Put a delay on the cooperative gesture message so it's less twitchy
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
this._cancelCooperativeMessage = false;
|
|
37
|
+
}, 200);
|
|
27
38
|
}
|
|
28
39
|
|
|
29
40
|
touchstart(e: TouchEvent, points: Array<Point>, mapTouches: Array<Touch>) {
|
|
@@ -31,6 +42,15 @@ export default class TouchPanHandler {
|
|
|
31
42
|
}
|
|
32
43
|
|
|
33
44
|
touchmove(e: TouchEvent, points: Array<Point>, mapTouches: Array<Touch>) {
|
|
45
|
+
if (this._map._cooperativeGestures) {
|
|
46
|
+
if (this._minTouches === 2 && mapTouches.length < 2 && !this._cancelCooperativeMessage) {
|
|
47
|
+
// If coop gesture enabled, show panning info to user
|
|
48
|
+
this._map._onCooperativeGesture(e, false, mapTouches.length);
|
|
49
|
+
} else if (!this._cancelCooperativeMessage) {
|
|
50
|
+
// If user is successfully navigating, we don't need this warning until the touch resets
|
|
51
|
+
this._cancelCooperativeMessage = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
34
54
|
if (!this._active || mapTouches.length < this._minTouches) return;
|
|
35
55
|
e.preventDefault();
|
|
36
56
|
return this._calculateTransform(e, points, mapTouches);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Point from '@mapbox/point-geometry';
|
|
2
2
|
import DOM from '../../util/dom';
|
|
3
|
+
import type Map from '../map';
|
|
3
4
|
|
|
4
5
|
class TwoTouchHandler {
|
|
5
6
|
|
|
@@ -23,7 +24,6 @@ class TwoTouchHandler {
|
|
|
23
24
|
_move(points: [Point, Point], pinchAround: Point, e: TouchEvent) { return {}; } //eslint-disable-line
|
|
24
25
|
|
|
25
26
|
touchstart(e: TouchEvent, points: Array<Point>, mapTouches: Array<Touch>) {
|
|
26
|
-
//console.log(e.target, e.targetTouches.length ? e.targetTouches[0].target : null);
|
|
27
27
|
//log('touchstart', points, e.target.innerHTML, e.targetTouches.length ? e.targetTouches[0].target.innerHTML: undefined);
|
|
28
28
|
if (this._firstTwoTouches || mapTouches.length < 2) return;
|
|
29
29
|
|
|
@@ -203,6 +203,13 @@ export class TouchPitchHandler extends TwoTouchHandler {
|
|
|
203
203
|
_valid: boolean | void;
|
|
204
204
|
_firstMove: number;
|
|
205
205
|
_lastPoints: [Point, Point];
|
|
206
|
+
_map: Map;
|
|
207
|
+
_currentTouchCount: number;
|
|
208
|
+
|
|
209
|
+
constructor(map: Map) {
|
|
210
|
+
super();
|
|
211
|
+
this._map = map;
|
|
212
|
+
}
|
|
206
213
|
|
|
207
214
|
reset() {
|
|
208
215
|
super.reset();
|
|
@@ -211,6 +218,11 @@ export class TouchPitchHandler extends TwoTouchHandler {
|
|
|
211
218
|
delete this._lastPoints;
|
|
212
219
|
}
|
|
213
220
|
|
|
221
|
+
touchstart(e: TouchEvent, points: Array<Point>, mapTouches: Array<Touch>) {
|
|
222
|
+
super.touchstart(e, points, mapTouches);
|
|
223
|
+
this._currentTouchCount = mapTouches.length;
|
|
224
|
+
}
|
|
225
|
+
|
|
214
226
|
_start(points: [Point, Point]) {
|
|
215
227
|
this._lastPoints = points;
|
|
216
228
|
if (isVertical(points[0].sub(points[1]))) {
|
|
@@ -221,6 +233,11 @@ export class TouchPitchHandler extends TwoTouchHandler {
|
|
|
221
233
|
}
|
|
222
234
|
|
|
223
235
|
_move(points: [Point, Point], center: Point, e: TouchEvent) {
|
|
236
|
+
// If cooperative gestures is enabled, we need a 3-finger minimum for this gesture to register
|
|
237
|
+
if (this._map._cooperativeGestures && this._currentTouchCount < 3) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
224
241
|
const vectorA = points[0].sub(this._lastPoints[0]);
|
|
225
242
|
const vectorB = points[1].sub(this._lastPoints[1]);
|
|
226
243
|
|
|
@@ -195,7 +195,7 @@ class HandlerManager {
|
|
|
195
195
|
const tapDragZoom = new TapDragZoomHandler();
|
|
196
196
|
this._add('tapDragZoom', tapDragZoom);
|
|
197
197
|
|
|
198
|
-
const touchPitch = map.touchPitch = new TouchPitchHandler();
|
|
198
|
+
const touchPitch = map.touchPitch = new TouchPitchHandler(map);
|
|
199
199
|
this._add('touchPitch', touchPitch);
|
|
200
200
|
|
|
201
201
|
const mouseRotate = new MouseRotateHandler(options);
|
|
@@ -205,7 +205,7 @@ class HandlerManager {
|
|
|
205
205
|
this._add('mousePitch', mousePitch, ['mouseRotate']);
|
|
206
206
|
|
|
207
207
|
const mousePan = new MousePanHandler(options);
|
|
208
|
-
const touchPan = new TouchPanHandler(options);
|
|
208
|
+
const touchPan = new TouchPanHandler(options, map);
|
|
209
209
|
map.dragPan = new DragPanHandler(el, mousePan, touchPan);
|
|
210
210
|
this._add('mousePan', mousePan);
|
|
211
211
|
this._add('touchPan', touchPan, ['touchZoom', 'touchRotate']);
|
package/src/ui/map.test.ts
CHANGED
|
@@ -227,7 +227,7 @@ describe('Map', () => {
|
|
|
227
227
|
map.transform.lngRange = [-120, 140];
|
|
228
228
|
map.transform.latRange = [-60, 80];
|
|
229
229
|
map.transform.resize(600, 400);
|
|
230
|
-
expect(map.transform.zoom).toBe(0.
|
|
230
|
+
expect(map.transform.zoom).toBe(0.6983039737971014);
|
|
231
231
|
expect(map.transform.unmodified).toBeTruthy();
|
|
232
232
|
map.setStyle(createStyle());
|
|
233
233
|
map.on('style.load', () => {
|
|
@@ -598,8 +598,8 @@ describe('Map', () => {
|
|
|
598
598
|
expect(parseFloat(map.getBounds().getCenter().lat.toFixed(10))).toBe(0);
|
|
599
599
|
|
|
600
600
|
expect(toFixed(map.getBounds().toArray())).toEqual(toFixed([
|
|
601
|
-
[
|
|
602
|
-
[
|
|
601
|
+
[-70.31249999999976, -57.326521225216965],
|
|
602
|
+
[70.31249999999977, 57.32652122521695]]));
|
|
603
603
|
});
|
|
604
604
|
|
|
605
605
|
test('rotated bounds', () => {
|
|
@@ -631,7 +631,7 @@ describe('Map', () => {
|
|
|
631
631
|
|
|
632
632
|
describe('#setMaxBounds', () => {
|
|
633
633
|
test('constrains map bounds', () => {
|
|
634
|
-
const map = createMap({zoom:0});
|
|
634
|
+
const map = createMap({zoom: 0});
|
|
635
635
|
map.setMaxBounds([[-130.4297, 50.0642], [-61.52344, 24.20688]]);
|
|
636
636
|
expect(
|
|
637
637
|
toFixed([[-130.4297000000, 7.0136641176], [-61.5234400000, 60.2398142283]])
|
|
@@ -639,7 +639,7 @@ describe('Map', () => {
|
|
|
639
639
|
});
|
|
640
640
|
|
|
641
641
|
test('when no argument is passed, map bounds constraints are removed', () => {
|
|
642
|
-
const map = createMap({zoom:0});
|
|
642
|
+
const map = createMap({zoom: 0});
|
|
643
643
|
map.setMaxBounds([[-130.4297, 50.0642], [-61.52344, 24.20688]]);
|
|
644
644
|
expect(
|
|
645
645
|
toFixed([[-166.28906999999964, -27.6835270554], [-25.664070000000066, 73.8248206697]])
|
|
@@ -664,12 +664,12 @@ describe('Map', () => {
|
|
|
664
664
|
|
|
665
665
|
describe('#getMaxBounds', () => {
|
|
666
666
|
test('returns null when no bounds set', () => {
|
|
667
|
-
const map = createMap({zoom:0});
|
|
667
|
+
const map = createMap({zoom: 0});
|
|
668
668
|
expect(map.getMaxBounds()).toBeNull();
|
|
669
669
|
});
|
|
670
670
|
|
|
671
671
|
test('returns bounds', () => {
|
|
672
|
-
const map = createMap({zoom:0});
|
|
672
|
+
const map = createMap({zoom: 0});
|
|
673
673
|
const bounds = [[-130.4297, 50.0642], [-61.52344, 24.20688]] as LngLatBoundsLike;
|
|
674
674
|
map.setMaxBounds(bounds);
|
|
675
675
|
expect(map.getMaxBounds().toArray()).toEqual(bounds);
|
|
@@ -718,14 +718,14 @@ describe('Map', () => {
|
|
|
718
718
|
});
|
|
719
719
|
|
|
720
720
|
test('#setMinZoom', () => {
|
|
721
|
-
const map = createMap({zoom:5});
|
|
721
|
+
const map = createMap({zoom: 5});
|
|
722
722
|
map.setMinZoom(3.5);
|
|
723
723
|
map.setZoom(1);
|
|
724
724
|
expect(map.getZoom()).toBe(3.5);
|
|
725
725
|
});
|
|
726
726
|
|
|
727
727
|
test('unset minZoom', () => {
|
|
728
|
-
const map = createMap({minZoom:5});
|
|
728
|
+
const map = createMap({minZoom: 5});
|
|
729
729
|
map.setMinZoom(null);
|
|
730
730
|
map.setZoom(1);
|
|
731
731
|
expect(map.getZoom()).toBe(1);
|
|
@@ -739,7 +739,7 @@ describe('Map', () => {
|
|
|
739
739
|
});
|
|
740
740
|
|
|
741
741
|
test('ignore minZooms over maxZoom', () => {
|
|
742
|
-
const map = createMap({zoom:2, maxZoom:5});
|
|
742
|
+
const map = createMap({zoom: 2, maxZoom: 5});
|
|
743
743
|
expect(() => {
|
|
744
744
|
map.setMinZoom(6);
|
|
745
745
|
}).toThrow();
|
|
@@ -748,14 +748,14 @@ describe('Map', () => {
|
|
|
748
748
|
});
|
|
749
749
|
|
|
750
750
|
test('#setMaxZoom', () => {
|
|
751
|
-
const map = createMap({zoom:0});
|
|
751
|
+
const map = createMap({zoom: 0});
|
|
752
752
|
map.setMaxZoom(3.5);
|
|
753
753
|
map.setZoom(4);
|
|
754
754
|
expect(map.getZoom()).toBe(3.5);
|
|
755
755
|
});
|
|
756
756
|
|
|
757
757
|
test('unset maxZoom', () => {
|
|
758
|
-
const map = createMap({maxZoom:5});
|
|
758
|
+
const map = createMap({maxZoom: 5});
|
|
759
759
|
map.setMaxZoom(null);
|
|
760
760
|
map.setZoom(6);
|
|
761
761
|
expect(map.getZoom()).toBe(6);
|
|
@@ -769,7 +769,7 @@ describe('Map', () => {
|
|
|
769
769
|
});
|
|
770
770
|
|
|
771
771
|
test('ignore maxZooms over minZoom', () => {
|
|
772
|
-
const map = createMap({minZoom:5});
|
|
772
|
+
const map = createMap({minZoom: 5});
|
|
773
773
|
expect(() => {
|
|
774
774
|
map.setMaxZoom(4);
|
|
775
775
|
}).toThrow();
|
|
@@ -779,13 +779,13 @@ describe('Map', () => {
|
|
|
779
779
|
|
|
780
780
|
test('throw on maxZoom smaller than minZoom at init', () => {
|
|
781
781
|
expect(() => {
|
|
782
|
-
createMap({minZoom:10, maxZoom:5});
|
|
782
|
+
createMap({minZoom: 10, maxZoom: 5});
|
|
783
783
|
}).toThrow(new Error('maxZoom must be greater than or equal to minZoom'));
|
|
784
784
|
});
|
|
785
785
|
|
|
786
786
|
test('throw on maxZoom smaller than minZoom at init with falsey maxZoom', () => {
|
|
787
787
|
expect(() => {
|
|
788
|
-
createMap({minZoom:1, maxZoom:0});
|
|
788
|
+
createMap({minZoom: 1, maxZoom: 0});
|
|
789
789
|
}).toThrow(new Error('maxZoom must be greater than or equal to minZoom'));
|
|
790
790
|
});
|
|
791
791
|
|
|
@@ -827,7 +827,7 @@ describe('Map', () => {
|
|
|
827
827
|
});
|
|
828
828
|
|
|
829
829
|
test('unset maxPitch', () => {
|
|
830
|
-
const map = createMap({maxPitch:10});
|
|
830
|
+
const map = createMap({maxPitch: 10});
|
|
831
831
|
map.setMaxPitch(null);
|
|
832
832
|
map.setPitch(20);
|
|
833
833
|
expect(map.getPitch()).toBe(20);
|
|
@@ -841,7 +841,7 @@ describe('Map', () => {
|
|
|
841
841
|
});
|
|
842
842
|
|
|
843
843
|
test('ignore maxPitchs over minPitch', () => {
|
|
844
|
-
const map = createMap({minPitch:10});
|
|
844
|
+
const map = createMap({minPitch: 10});
|
|
845
845
|
expect(() => {
|
|
846
846
|
map.setMaxPitch(0);
|
|
847
847
|
}).toThrow();
|
package/src/ui/map.ts
CHANGED
|
@@ -59,7 +59,6 @@ import type {ControlPosition, IControl} from './control/control';
|
|
|
59
59
|
import type {MapGeoJSONFeature} from '../util/vectortile_to_geojson';
|
|
60
60
|
|
|
61
61
|
/* eslint-enable no-use-before-define */
|
|
62
|
-
|
|
63
62
|
export type MapOptions = {
|
|
64
63
|
hash?: boolean | string;
|
|
65
64
|
interactive?: boolean;
|
|
@@ -86,6 +85,7 @@ export type MapOptions = {
|
|
|
86
85
|
doubleClickZoom?: boolean;
|
|
87
86
|
touchZoomRotate?: boolean;
|
|
88
87
|
touchPitch?: boolean;
|
|
88
|
+
cooperativeGestures?: boolean | GestureOptions;
|
|
89
89
|
trackResize?: boolean;
|
|
90
90
|
center?: LngLatLike;
|
|
91
91
|
zoom?: number;
|
|
@@ -107,6 +107,12 @@ export type MapOptions = {
|
|
|
107
107
|
pixelRatio?: number;
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
+
export type GestureOptions = {
|
|
111
|
+
windowsHelpText?: string;
|
|
112
|
+
macHelpText?: string;
|
|
113
|
+
mobileHelpText?: string;
|
|
114
|
+
};
|
|
115
|
+
|
|
110
116
|
// See article here: https://medium.com/terria/typescript-transforming-optional-properties-to-required-properties-that-may-be-undefined-7482cb4e1585
|
|
111
117
|
type Complete<T> = {
|
|
112
118
|
[P in keyof Required<T>]: Pick<T, P> extends Required<Pick<T, P>> ? T[P] : (T[P] | undefined);
|
|
@@ -146,6 +152,7 @@ const defaultOptions = {
|
|
|
146
152
|
doubleClickZoom: true,
|
|
147
153
|
touchZoomRotate: true,
|
|
148
154
|
touchPitch: true,
|
|
155
|
+
cooperativeGestures: undefined,
|
|
149
156
|
|
|
150
157
|
bearingSnap: 7,
|
|
151
158
|
clickTolerance: 3,
|
|
@@ -217,6 +224,13 @@ const defaultOptions = {
|
|
|
217
224
|
* @param {boolean} [options.doubleClickZoom=true] If `true`, the "double click to zoom" interaction is enabled (see {@link DoubleClickZoomHandler}).
|
|
218
225
|
* @param {boolean|Object} [options.touchZoomRotate=true] If `true`, the "pinch to rotate and zoom" interaction is enabled. An `Object` value is passed as options to {@link TouchZoomRotateHandler#enable}.
|
|
219
226
|
* @param {boolean|Object} [options.touchPitch=true] If `true`, the "drag to pitch" interaction is enabled. An `Object` value is passed as options to {@link TouchPitchHandler#enable}.
|
|
227
|
+
* @param {boolean|GestureOptions} [options.cooperativeGestures=undefined] If `true` or set to an options object, map is only accessible on desktop while holding Command/Ctrl and only accessible on mobile with two fingers. Interacting with the map using normal gestures will trigger an informational screen. With this option enabled, "drag to pitch" requires a three-finger gesture.
|
|
228
|
+
* A valid options object includes the following properties to customize the text on the informational screen. The values below are the defaults.
|
|
229
|
+
* {
|
|
230
|
+
* windowsHelpText: "Use Ctrl + scroll to zoom the map",
|
|
231
|
+
* macHelpText: "Use ⌘ + scroll to zoom the map",
|
|
232
|
+
* mobileHelpText: "Use two fingers to move the map",
|
|
233
|
+
* }
|
|
220
234
|
* @param {boolean} [options.trackResize=true] If `true`, the map will automatically resize when the browser window resizes.
|
|
221
235
|
* @param {LngLatLike} [options.center=[0, 0]] The initial geographical centerpoint of the map. If `center` is not specified in the constructor options, MapLibre GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `[0, 0]` Note: MapLibre GL uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match GeoJSON.
|
|
222
236
|
* @param {number} [options.zoom=0] The initial zoom level of the map. If `zoom` is not specified in the constructor options, MapLibre GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`.
|
|
@@ -271,6 +285,9 @@ class Map extends Camera {
|
|
|
271
285
|
_controlContainer: HTMLElement;
|
|
272
286
|
_controlPositions: {[_: string]: HTMLElement};
|
|
273
287
|
_interactive: boolean;
|
|
288
|
+
_cooperativeGestures: boolean | GestureOptions;
|
|
289
|
+
_cooperativeGesturesScreen: HTMLElement;
|
|
290
|
+
_metaPress: boolean;
|
|
274
291
|
_showTileBoundaries: boolean;
|
|
275
292
|
_showCollisionBoxes: boolean;
|
|
276
293
|
_showPadding: boolean;
|
|
@@ -381,6 +398,7 @@ class Map extends Camera {
|
|
|
381
398
|
super(transform, {bearingSnap: options.bearingSnap});
|
|
382
399
|
|
|
383
400
|
this._interactive = options.interactive;
|
|
401
|
+
this._cooperativeGestures = options.cooperativeGestures;
|
|
384
402
|
this._maxTileCacheSize = options.maxTileCacheSize;
|
|
385
403
|
this._failIfMajorPerformanceCaveat = options.failIfMajorPerformanceCaveat;
|
|
386
404
|
this._preserveDrawingBuffer = options.preserveDrawingBuffer;
|
|
@@ -446,6 +464,10 @@ class Map extends Camera {
|
|
|
446
464
|
|
|
447
465
|
this.handlers = new HandlerManager(this, options as CompleteMapOptions);
|
|
448
466
|
|
|
467
|
+
if (this._cooperativeGestures) {
|
|
468
|
+
this._setupCooperativeGestures();
|
|
469
|
+
}
|
|
470
|
+
|
|
449
471
|
const hashName = (typeof options.hash === 'string' && options.hash) || undefined;
|
|
450
472
|
this._hash = options.hash && (new Hash(hashName)).addTo(this);
|
|
451
473
|
// don't set position from options if set through hash
|
|
@@ -1039,7 +1061,7 @@ class Map extends Camera {
|
|
|
1039
1061
|
* | [`dataabort`](#map.event:dataabort) | |
|
|
1040
1062
|
* | [`sourcedataabort`](#map.event:sourcedataabort) | |
|
|
1041
1063
|
*
|
|
1042
|
-
* @param {string | Listener}
|
|
1064
|
+
* @param {string | Listener} layer The ID of a style layer or a listener if no ID is provided. Event will only be triggered if its location
|
|
1043
1065
|
* is within a visible feature in this layer. The event will have a `features` property containing
|
|
1044
1066
|
* an array of the matching features. If `layerIdOrListener` is not supplied, the event will not have a `features` property.
|
|
1045
1067
|
* Please note that many event types are not compatible with the optional `layerIdOrListener` parameter.
|
|
@@ -1129,7 +1151,7 @@ class Map extends Camera {
|
|
|
1129
1151
|
* a visible portion of the specified layer from outside that layer or outside the map canvas. `mouseleave`
|
|
1130
1152
|
* and `mouseout` events are triggered when the cursor leaves a visible portion of the specified layer, or leaves
|
|
1131
1153
|
* the map canvas.
|
|
1132
|
-
* @param {string}
|
|
1154
|
+
* @param {string} layer The ID of a style layer or a listener if no ID is provided. Only events whose location is within a visible
|
|
1133
1155
|
* feature in this layer will trigger the listener. The event will have a `features` property containing
|
|
1134
1156
|
* an array of the matching features.
|
|
1135
1157
|
* @param {Function} listener The function to be called when the event is fired.
|
|
@@ -1173,7 +1195,7 @@ class Map extends Camera {
|
|
|
1173
1195
|
* Removes an event listener for layer-specific events previously added with `Map#on`.
|
|
1174
1196
|
*
|
|
1175
1197
|
* @param {string} type The event type previously used to install the listener.
|
|
1176
|
-
* @param {string}
|
|
1198
|
+
* @param {string} layer The layer ID or listener previously used to install the listener.
|
|
1177
1199
|
* @param {Function} listener The function previously installed as a listener.
|
|
1178
1200
|
* @returns {Map} `this`
|
|
1179
1201
|
*/
|
|
@@ -1892,7 +1914,10 @@ class Map extends Camera {
|
|
|
1892
1914
|
* A layer defines how data from a specified source will be styled. Read more about layer types
|
|
1893
1915
|
* and available paint and layout properties in the [MapLibre Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/#layers).
|
|
1894
1916
|
*
|
|
1895
|
-
* @param {
|
|
1917
|
+
* TODO: JSDoc can't pass @param {(LayerSpecification & {source?: string | SourceSpecification}) | CustomLayerInterface} layer The layer to add,
|
|
1918
|
+
* @param {Object} layer
|
|
1919
|
+
* conforming to either the MapLibre Style Specification's [layer definition](https://maplibre.org/maplibre-gl-js-docs/style-spec/#layers) or,
|
|
1920
|
+
* less commonly, the {@link CustomLayerInterface} specification.
|
|
1896
1921
|
* The MapLibre Style Specification's layer definition is appropriate for most layers.
|
|
1897
1922
|
*
|
|
1898
1923
|
* @param {string} layer.id A unique identifer that you define.
|
|
@@ -1900,10 +1925,10 @@ class Map extends Camera {
|
|
|
1900
1925
|
* A list of layer types is available in the [MapLibre Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/layers/#type).
|
|
1901
1926
|
*
|
|
1902
1927
|
* (This can also be `custom`. For more information, see {@link CustomLayerInterface}.)
|
|
1903
|
-
* @param {string |
|
|
1928
|
+
* @param {string | SourceSpecification} [layer.source] The data source for the layer.
|
|
1904
1929
|
* Reference a source that has _already been defined_ using the source's unique id.
|
|
1905
1930
|
* Reference a _new source_ using a source object (as defined in the [MapLibre Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/sources/)) directly.
|
|
1906
|
-
* This is **required** for all `layer.type` options _except_ for `custom`.
|
|
1931
|
+
* This is **required** for all `layer.type` options _except_ for `custom` and `background`.
|
|
1907
1932
|
* @param {string} [layer.sourceLayer] (optional) The name of the source layer within the specified `layer.source` to use for this style layer.
|
|
1908
1933
|
* This is only applicable for vector tile sources and is **required** when `layer.source` is of the type `vector`.
|
|
1909
1934
|
* @param {array} [layer.filter] (optional) An expression specifying conditions on source features.
|
|
@@ -1994,7 +2019,7 @@ class Map extends Camera {
|
|
|
1994
2019
|
* @see [Add a vector tile source](https://maplibre.org/maplibre-gl-js-docs/example/vector-source/)
|
|
1995
2020
|
* @see [Add a WMS source](https://maplibre.org/maplibre-gl-js-docs/example/wms/)
|
|
1996
2021
|
*/
|
|
1997
|
-
addLayer(layer: LayerSpecification | CustomLayerInterface, beforeId?: string) {
|
|
2022
|
+
addLayer(layer: (LayerSpecification & {source?: string | SourceSpecification}) | CustomLayerInterface, beforeId?: string) {
|
|
1998
2023
|
this._lazyInitEmptyStyle();
|
|
1999
2024
|
this.style.addLayer(layer, beforeId);
|
|
2000
2025
|
return this._update(true);
|
|
@@ -2410,6 +2435,35 @@ class Map extends Camera {
|
|
|
2410
2435
|
this._container.addEventListener('scroll', this._onMapScroll, false);
|
|
2411
2436
|
}
|
|
2412
2437
|
|
|
2438
|
+
_setupCooperativeGestures() {
|
|
2439
|
+
const container = this._container;
|
|
2440
|
+
this._metaPress = false;
|
|
2441
|
+
this._cooperativeGesturesScreen = DOM.create('div', 'maplibregl-cooperative-gesture-screen', container);
|
|
2442
|
+
let modifierKeyName = 'Control';
|
|
2443
|
+
let desktopMessage = typeof this._cooperativeGestures !== 'boolean' && this._cooperativeGestures.windowsHelpText ? this._cooperativeGestures.windowsHelpText : 'Use Ctrl + scroll to zoom the map';
|
|
2444
|
+
if (navigator.platform.indexOf('Mac') === 0) {
|
|
2445
|
+
desktopMessage = typeof this._cooperativeGestures !== 'boolean' && this._cooperativeGestures.macHelpText ? this._cooperativeGestures.macHelpText : 'Use ⌘ + scroll to zoom the map';
|
|
2446
|
+
modifierKeyName = 'Meta';
|
|
2447
|
+
}
|
|
2448
|
+
const mobileMessage = typeof this._cooperativeGestures !== 'boolean' && this._cooperativeGestures.mobileHelpText ? this._cooperativeGestures.mobileHelpText : 'Use two fingers to move the map';
|
|
2449
|
+
this._cooperativeGesturesScreen.innerHTML = `
|
|
2450
|
+
<div class="maplibregl-desktop-message">${desktopMessage}</div>
|
|
2451
|
+
<div class="maplibregl-mobile-message">${mobileMessage}</div>
|
|
2452
|
+
`;
|
|
2453
|
+
document.addEventListener('keydown', (event) => {
|
|
2454
|
+
if (event.key === modifierKeyName) this._metaPress = true;
|
|
2455
|
+
});
|
|
2456
|
+
document.addEventListener('keyup', (event) => {
|
|
2457
|
+
if (event.key === modifierKeyName) this._metaPress = false;
|
|
2458
|
+
});
|
|
2459
|
+
// Add event to canvas container since gesture container is pointer-events: none
|
|
2460
|
+
this._canvasContainer.addEventListener('wheel', (e) => {
|
|
2461
|
+
this._onCooperativeGesture(e, this._metaPress, 1);
|
|
2462
|
+
}, false);
|
|
2463
|
+
// Remove the traditional pan classes
|
|
2464
|
+
this._canvasContainer.classList.remove('mapboxgl-touch-drag-pan', 'maplibregl-touch-drag-pan');
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2413
2467
|
_resizeCanvas(width: number, height: number, pixelRatio: number) {
|
|
2414
2468
|
// Request the required canvas size taking the pixelratio into account.
|
|
2415
2469
|
this._canvas.width = pixelRatio * width;
|
|
@@ -2465,6 +2519,17 @@ class Map extends Camera {
|
|
|
2465
2519
|
return false;
|
|
2466
2520
|
}
|
|
2467
2521
|
|
|
2522
|
+
_onCooperativeGesture(event: any, metaPress, touches) {
|
|
2523
|
+
if (!metaPress && touches < 2) {
|
|
2524
|
+
// Alert user how to scroll/pan
|
|
2525
|
+
this._cooperativeGesturesScreen.classList.add('maplibregl-show');
|
|
2526
|
+
setTimeout(() => {
|
|
2527
|
+
this._cooperativeGesturesScreen.classList.remove('maplibregl-show');
|
|
2528
|
+
}, 100);
|
|
2529
|
+
}
|
|
2530
|
+
return false;
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2468
2533
|
/**
|
|
2469
2534
|
* Returns a Boolean indicating whether the map is fully loaded.
|
|
2470
2535
|
*
|
|
@@ -2714,6 +2779,9 @@ class Map extends Camera {
|
|
|
2714
2779
|
this._canvas.removeEventListener('webglcontextlost', this._contextLost, false);
|
|
2715
2780
|
DOM.remove(this._canvasContainer);
|
|
2716
2781
|
DOM.remove(this._controlContainer);
|
|
2782
|
+
if (this._cooperativeGestures) {
|
|
2783
|
+
DOM.remove(this._cooperativeGesturesScreen);
|
|
2784
|
+
}
|
|
2717
2785
|
this._container.classList.remove('maplibregl-map', 'mapboxgl-map');
|
|
2718
2786
|
|
|
2719
2787
|
PerformanceUtils.clearMetrics();
|