maplibre-gl 6.0.0 → 6.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/build/readme.md +0 -2
- package/dist/maplibre-gl-dev.mjs +433 -573
- package/dist/maplibre-gl-dev.mjs.map +1 -1
- package/dist/maplibre-gl-shared-dev.mjs +984 -850
- package/dist/maplibre-gl-shared-dev.mjs.map +1 -1
- package/dist/maplibre-gl-shared.mjs +2 -2
- package/dist/maplibre-gl-shared.mjs.map +1 -1
- package/dist/maplibre-gl-worker-dev.mjs +14 -12
- package/dist/maplibre-gl-worker-dev.mjs.map +1 -1
- package/dist/maplibre-gl-worker.mjs +2 -2
- package/dist/maplibre-gl-worker.mjs.map +1 -1
- package/dist/maplibre-gl.css +1 -1
- package/dist/maplibre-gl.d.ts +119 -42
- package/dist/maplibre-gl.mjs +22 -22
- package/dist/maplibre-gl.mjs.map +1 -1
- package/package.json +20 -22
- package/src/css/maplibre-gl.css +4 -0
- package/src/data/bucket/circle_bucket.ts +3 -2
- package/src/data/bucket/fill_bucket.ts +3 -2
- package/src/data/bucket/fill_extrusion_bucket.test.ts +22 -0
- package/src/data/bucket/fill_extrusion_bucket.ts +17 -4
- package/src/data/bucket/line_bucket.test.ts +5 -5
- package/src/data/bucket/line_bucket.ts +3 -2
- package/src/data/bucket/round_polygon_corners.test.ts +159 -0
- package/src/data/bucket/round_polygon_corners.ts +121 -0
- package/src/data/bucket/symbol_bucket.test.ts +7 -7
- package/src/data/dem_data.test.ts +23 -23
- package/src/data/feature_position_map.test.ts +1 -1
- package/src/data/segment.test.ts +14 -14
- package/src/geo/bounds.test.ts +4 -4
- package/src/geo/lng_lat_bounds.test.ts +1 -1
- package/src/geo/projection/covering_tiles.bench.ts +39 -0
- package/src/geo/projection/covering_tiles.test.ts +3 -7
- package/src/geo/projection/covering_tiles.ts +37 -2
- package/src/geo/projection/globe_covering_tiles_details_provider.ts +4 -4
- package/src/geo/projection/globe_projection.test.ts +2 -2
- package/src/geo/projection/globe_projection.ts +6 -15
- package/src/geo/projection/globe_transform.test.ts +3 -6
- package/src/geo/projection/globe_transform.ts +4 -7
- package/src/geo/projection/mercator_covering_tiles_details_provider.ts +4 -4
- package/src/geo/projection/mercator_projection.ts +1 -13
- package/src/geo/projection/mercator_transform.test.ts +1 -1
- package/src/geo/projection/mercator_transform.ts +2 -1
- package/src/geo/projection/mercator_utils.test.ts +8 -8
- package/src/geo/projection/projection.ts +0 -27
- package/src/geo/projection/projection_data.ts +8 -0
- package/src/geo/projection/projection_factory.ts +3 -3
- package/src/geo/projection/vertical_perspective_projection.ts +3 -60
- package/src/geo/projection/vertical_perspective_transform.ts +16 -23
- package/src/geo/transform_interface.ts +1 -2
- package/src/index.test.ts +7 -12
- package/src/index.ts +4 -2
- package/src/render/glyph_manager.test.ts +7 -22
- package/src/render/painter.test.ts +2 -0
- package/src/render/painter.ts +8 -11
- package/src/render/subdivision.bench.ts +39 -0
- package/src/render/subdivision.test.ts +22 -23
- package/src/render/subdivision.ts +46 -0
- package/src/render/terrain.test.ts +68 -34
- package/src/render/terrain.ts +69 -26
- package/src/shaders/glsl/_projection_globe.fragment.glsl +12 -0
- package/src/shaders/glsl/_projection_globe.fragment.glsl.g.ts +2 -0
- package/src/shaders/glsl/_projection_globe.vertex.glsl +29 -10
- package/src/shaders/glsl/_projection_globe.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/_projection_mercator.fragment.glsl +4 -0
- package/src/shaders/glsl/_projection_mercator.fragment.glsl.g.ts +2 -0
- package/src/shaders/glsl/line.fragment.glsl +2 -0
- package/src/shaders/glsl/line.fragment.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_gradient.fragment.glsl +2 -0
- package/src/shaders/glsl/line_gradient.fragment.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_gradient_sdf.fragment.glsl +2 -0
- package/src/shaders/glsl/line_gradient_sdf.fragment.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_pattern.fragment.glsl +2 -0
- package/src/shaders/glsl/line_pattern.fragment.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_sdf.fragment.glsl +2 -0
- package/src/shaders/glsl/line_sdf.fragment.glsl.g.ts +1 -1
- package/src/shaders/shaders.ts +4 -6
- package/src/source/canvas_source.test.ts +1 -1
- package/src/source/geojson_source.test.ts +32 -4
- package/src/source/geojson_source.ts +41 -0
- package/src/source/geojson_source_diff.test.ts +2 -2
- package/src/source/geojson_worker_source.test.ts +9 -5
- package/src/source/image_source.test.ts +137 -62
- package/src/source/image_source.ts +49 -12
- package/src/source/raster_dem_tile_source.test.ts +2 -2
- package/src/source/raster_tile_source.test.ts +64 -9
- package/src/source/raster_tile_source.ts +2 -1
- package/src/source/rtl_text_plugin_main_thread.test.ts +14 -14
- package/src/source/source.test.ts +8 -8
- package/src/source/vector_tile_source.test.ts +1 -1
- package/src/source/vector_tile_worker_source.test.ts +7 -5
- package/src/source/video_source.test.ts +1 -1
- package/src/source/worker.test.ts +1 -1
- package/src/source/worker_tile.test.ts +10 -8
- package/src/style/light.test.ts +9 -9
- package/src/style/light.ts +3 -3
- package/src/style/load_glyph_range.test.ts +8 -8
- package/src/style/load_sprite.test.ts +1 -1
- package/src/style/properties.test.ts +94 -2
- package/src/style/properties.ts +30 -1
- package/src/style/sky.test.ts +9 -9
- package/src/style/sky.ts +2 -2
- package/src/style/style.test.ts +38 -36
- package/src/style/style.ts +3 -3
- package/src/style/style_layer/color_relief_style_layer.test.ts +1 -1
- package/src/style/style_layer/fill_extrusion_style_layer.ts +6 -3
- package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +14 -1
- package/src/style/style_layer/raster_style_layer.test.ts +2 -2
- package/src/style/style_layer.test.ts +5 -51
- package/src/style/validate_style.test.ts +1 -1
- package/src/symbol/collision_index.test.ts +1 -1
- package/src/symbol/grid_index.test.ts +1 -1
- package/src/tile/terrain_tile_manager.test.ts +2 -2
- package/src/tile/tile_id.test.ts +5 -5
- package/src/tile/tile_manager.test.ts +113 -72
- package/src/tile/tile_manager.ts +2 -2
- package/src/tile/tile_manager_in_view_tiles.test.ts +2 -2
- package/src/ui/camera.test.ts +138 -135
- package/src/ui/control/geolocate_control.test.ts +7 -30
- package/src/ui/handler/dblclick_zoom.test.ts +2 -2
- package/src/ui/handler/mouse.ts +15 -7
- package/src/ui/handler/mouse_handler_interface.test.ts +21 -1
- package/src/ui/handler/scroll_zoom.test.ts +2 -0
- package/src/ui/handler_manager.test.ts +7 -7
- package/src/ui/hash.test.ts +1 -0
- package/src/ui/map.ts +45 -20
- package/src/ui/map_tests/map_basic.test.ts +11 -23
- package/src/ui/map_tests/map_calculate_camera_options.test.ts +6 -6
- package/src/ui/map_tests/map_events.test.ts +5 -7
- package/src/ui/map_tests/map_global_state.test.ts +3 -3
- package/src/ui/map_tests/map_images.test.ts +4 -3
- package/src/ui/map_tests/map_is_moving.test.ts +1 -1
- package/src/ui/map_tests/map_is_rotating.test.ts +1 -1
- package/src/ui/map_tests/map_layer.test.ts +2 -1
- package/src/ui/map_tests/map_options.test.ts +1 -5
- package/src/ui/map_tests/map_pitch.test.ts +6 -6
- package/src/ui/map_tests/map_refresh_tiles.test.ts +2 -2
- package/src/ui/map_tests/map_render.test.ts +1 -1
- package/src/ui/map_tests/map_set_lod_params.test.ts +1 -1
- package/src/ui/map_tests/map_style.test.ts +9 -1
- package/src/ui/map_tests/map_terrain.test.ts +41 -1
- package/src/ui/map_tests/map_zoom.test.ts +15 -15
- package/src/ui/marker.test.ts +71 -14
- package/src/ui/marker.ts +30 -6
- package/src/ui/popup.test.ts +3 -3
- package/src/util/actor.test.ts +6 -6
- package/src/util/ajax.test.ts +27 -39
- package/src/util/browser.test.ts +7 -9
- package/src/util/create_tile_mesh.test.ts +2 -2
- package/src/util/dispatcher.test.ts +1 -1
- package/src/util/evented.test.ts +4 -1
- package/src/util/fast_maths.test.ts +4 -4
- package/src/util/image_request.test.ts +6 -4
- package/src/util/primitives/bounding_volume_cache.ts +3 -1
- package/src/util/struct_array.test.ts +2 -2
- package/src/util/task_queue.test.ts +1 -1
- package/src/util/test/util.ts +1 -0
- package/src/util/time_control.test.ts +2 -2
- package/src/util/transferable_grid_index.test.ts +1 -1
- package/src/util/util.test.ts +27 -13
- package/src/util/verticalize_punctuation.test.ts +4 -4
- package/src/util/web_worker_transfer.test.ts +5 -5
- package/src/webgl/draw/draw_custom.test.ts +13 -13
- package/src/webgl/draw/draw_debug.test.ts +1 -1
- package/src/webgl/draw/draw_fill.test.ts +13 -12
- package/src/webgl/draw/draw_symbol.test.ts +17 -16
- package/src/webgl/program/program_uniforms.ts +0 -3
- package/src/webgl/program/projection_program.ts +12 -10
- package/src/webgl/program/terrain_program.test.ts +2 -2
- package/src/webgl/program.ts +6 -4
- package/src/webgl/render_to_texture.test.ts +5 -5
- package/src/webgl/state.test.ts +1 -1
- package/src/webgl/texture.test.ts +3 -3
- package/src/webgl/vertex_buffer.test.ts +1 -1
- package/build/rolldown_plugins.ts +0 -18
- package/src/geo/projection/globe_projection_error_measurement.ts +0 -229
- package/src/shaders/glsl/projection_error_measurement.fragment.glsl +0 -5
- package/src/shaders/glsl/projection_error_measurement.fragment.glsl.g.ts +0 -2
- package/src/shaders/glsl/projection_error_measurement.vertex.glsl +0 -22
- package/src/shaders/glsl/projection_error_measurement.vertex.glsl.g.ts +0 -2
- package/src/webgl/program/projection_error_measurement_program.ts +0 -23
|
@@ -218,7 +218,7 @@ export class MercatorTransform implements ITransform {
|
|
|
218
218
|
public get autoCalculateNearFarZ(): boolean {
|
|
219
219
|
return this._helper.autoCalculateNearFarZ;
|
|
220
220
|
}
|
|
221
|
-
setTransitionState(_value: number
|
|
221
|
+
setTransitionState(_value: number): void {
|
|
222
222
|
// Do nothing
|
|
223
223
|
}
|
|
224
224
|
//
|
|
@@ -748,6 +748,7 @@ export class MercatorTransform implements ITransform {
|
|
|
748
748
|
clippingPlane: [0, 0, 0, 0],
|
|
749
749
|
projectionTransition: 0.0, // Range 0..1, where 0 is mercator, 1 is another projection, mostly globe.
|
|
750
750
|
fallbackMatrix: mainMatrix,
|
|
751
|
+
clipAntimeridian: false,
|
|
751
752
|
};
|
|
752
753
|
}
|
|
753
754
|
|
|
@@ -58,25 +58,25 @@ describe('mercator utils', () => {
|
|
|
58
58
|
describe('tileCoordinatesToMercatorCoordinates', () => {
|
|
59
59
|
const precisionDigits = 10;
|
|
60
60
|
|
|
61
|
-
test('
|
|
61
|
+
test('0,0', () => {
|
|
62
62
|
const result = tileCoordinatesToMercatorCoordinates(0, 0, new CanonicalTileID(0, 0, 0));
|
|
63
63
|
expect(result.x).toBe(0);
|
|
64
64
|
expect(result.y).toBe(0);
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
-
test('
|
|
67
|
+
test('tile center', () => {
|
|
68
68
|
const result = tileCoordinatesToMercatorCoordinates(EXTENT / 2, EXTENT / 2, new CanonicalTileID(0, 0, 0));
|
|
69
69
|
expect(result.x).toBeCloseTo(0.5, precisionDigits);
|
|
70
70
|
expect(result.y).toBeCloseTo(0.5, precisionDigits);
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
test('
|
|
73
|
+
test('higher zoom 0,0', () => {
|
|
74
74
|
const result = tileCoordinatesToMercatorCoordinates(0, 0, new CanonicalTileID(3, 0, 0));
|
|
75
75
|
expect(result.x).toBe(0);
|
|
76
76
|
expect(result.y).toBe(0);
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
-
test('
|
|
79
|
+
test('higher zoom tile center', () => {
|
|
80
80
|
const result = tileCoordinatesToMercatorCoordinates(EXTENT / 2, EXTENT / 2, new CanonicalTileID(3, 0, 0));
|
|
81
81
|
expect(result.x).toBeCloseTo(1 / 16, precisionDigits);
|
|
82
82
|
expect(result.y).toBeCloseTo(1 / 16, precisionDigits);
|
|
@@ -86,25 +86,25 @@ describe('mercator utils', () => {
|
|
|
86
86
|
describe('tileCoordinatesToLocation', () => {
|
|
87
87
|
const precisionDigits = 5;
|
|
88
88
|
|
|
89
|
-
test('
|
|
89
|
+
test('0,0', () => {
|
|
90
90
|
const result = tileCoordinatesToLocation(0, 0, new CanonicalTileID(0, 0, 0));
|
|
91
91
|
expect(result.lng).toBeCloseTo(-180, precisionDigits);
|
|
92
92
|
expect(result.lat).toBeCloseTo(MAX_VALID_LATITUDE, precisionDigits);
|
|
93
93
|
});
|
|
94
94
|
|
|
95
|
-
test('
|
|
95
|
+
test('tile center', () => {
|
|
96
96
|
const result = tileCoordinatesToLocation(EXTENT / 2, EXTENT / 2, new CanonicalTileID(0, 0, 0));
|
|
97
97
|
expect(result.lng).toBeCloseTo(0, precisionDigits);
|
|
98
98
|
expect(result.lat).toBeCloseTo(0, precisionDigits);
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
test('
|
|
101
|
+
test('higher zoom 0,0', () => {
|
|
102
102
|
const result = tileCoordinatesToLocation(0, 0, new CanonicalTileID(3, 0, 0));
|
|
103
103
|
expect(result.lng).toBeCloseTo(-180, precisionDigits);
|
|
104
104
|
expect(result.lat).toBeCloseTo(MAX_VALID_LATITUDE, precisionDigits);
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
-
test('
|
|
107
|
+
test('higher zoom mercator center', () => {
|
|
108
108
|
const result = tileCoordinatesToLocation(EXTENT, EXTENT, new CanonicalTileID(3, 3, 3));
|
|
109
109
|
expect(result.lng).toBeCloseTo(0, precisionDigits);
|
|
110
110
|
expect(result.lat).toBeCloseTo(0, precisionDigits);
|
|
@@ -2,7 +2,6 @@ import type {CanonicalTileID} from '../../tile/tile_id.ts';
|
|
|
2
2
|
import type {PreparedShader} from '../../shaders/shaders.ts';
|
|
3
3
|
import type {Context} from '../../webgl/context.ts';
|
|
4
4
|
import type {Mesh} from '../../render/mesh.ts';
|
|
5
|
-
import type {Program} from '../../webgl/program.ts';
|
|
6
5
|
import type {SubdivisionGranularitySetting} from '../../render/subdivision_granularity_settings.ts';
|
|
7
6
|
import type {ProjectionSpecification} from '@maplibre/maplibre-gl-style-spec';
|
|
8
7
|
import type {EvaluationParameters} from '../../style/evaluation_parameters.ts';
|
|
@@ -23,14 +22,6 @@ import type {EvaluationParameters} from '../../style/evaluation_parameters.ts';
|
|
|
23
22
|
* - must be explicitly disposed of after usage using the `destroy` function - this allows the implementing class to free any allocated resources
|
|
24
23
|
*/
|
|
25
24
|
|
|
26
|
-
/**
|
|
27
|
-
* @internal
|
|
28
|
-
*/
|
|
29
|
-
export type ProjectionGPUContext = {
|
|
30
|
-
context: Context;
|
|
31
|
-
useProgram: (name: string) => Program<any>;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
25
|
/**
|
|
35
26
|
* @internal
|
|
36
27
|
* Specifies the usage for a square tile mesh:
|
|
@@ -99,24 +90,12 @@ export interface Projection {
|
|
|
99
90
|
*/
|
|
100
91
|
get transitionState(): number;
|
|
101
92
|
|
|
102
|
-
/**
|
|
103
|
-
* @internal
|
|
104
|
-
* Gets the error correction latitude in radians.
|
|
105
|
-
*/
|
|
106
|
-
get latitudeErrorCorrectionRadians(): number;
|
|
107
|
-
|
|
108
93
|
/**
|
|
109
94
|
* @internal
|
|
110
95
|
* Cleans up any resources the projection created, especially GPU buffers.
|
|
111
96
|
*/
|
|
112
97
|
destroy(): void;
|
|
113
98
|
|
|
114
|
-
/**
|
|
115
|
-
* @internal
|
|
116
|
-
* Runs any GPU-side tasks this projection required. Called at the beginning of every frame.
|
|
117
|
-
*/
|
|
118
|
-
updateGPUdependent(renderContext: ProjectionGPUContext): void;
|
|
119
|
-
|
|
120
99
|
/**
|
|
121
100
|
* @internal
|
|
122
101
|
* Returns a subdivided mesh for a given tile ID, covering 0..EXTENT range.
|
|
@@ -140,10 +119,4 @@ export interface Projection {
|
|
|
140
119
|
* Returns true if the projection is currently transitioning between two states.
|
|
141
120
|
*/
|
|
142
121
|
hasTransition(): boolean;
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* @internal
|
|
146
|
-
* Sets the error query latidude in degrees
|
|
147
|
-
*/
|
|
148
|
-
setErrorQueryLatitudeDegrees(value: number): void;
|
|
149
122
|
}
|
|
@@ -60,6 +60,14 @@ export type ProjectionData<MainMatrix extends mat4 = mat4, FallbackMatrix extend
|
|
|
60
60
|
* Uniform name: `u_projection_fallback_matrix`.
|
|
61
61
|
*/
|
|
62
62
|
fallbackMatrix: FallbackMatrix;
|
|
63
|
+
/**
|
|
64
|
+
* Whether line fragments outside the tile's X extent should be discarded: true for the zoom 0 tile under globe projection, false otherwise.
|
|
65
|
+
* The z0 tile covers the whole world, so its buffer wraps around the planet onto the tile itself,
|
|
66
|
+
* drawing geometry near the antimeridian twice. Stencil clipping cannot remove this same-pixel overlap,
|
|
67
|
+
* so lines are clipped in the fragment shader instead (fills are clipped during subdivision).
|
|
68
|
+
* Uniform name: `u_projection_clip_antimeridian`.
|
|
69
|
+
*/
|
|
70
|
+
clipAntimeridian: boolean;
|
|
63
71
|
};
|
|
64
72
|
|
|
65
73
|
/**
|
|
@@ -14,14 +14,14 @@ import type {Projection} from './projection.ts';
|
|
|
14
14
|
import type {ITransform, TransformConstrainFunction} from '../transform_interface.ts';
|
|
15
15
|
import type {ICameraHelper} from './camera_helper.ts';
|
|
16
16
|
|
|
17
|
-
export function createProjectionFromName(name: ProjectionSpecification['type'], transformConstrain
|
|
17
|
+
export function createProjectionFromName(name: ProjectionSpecification['type'], transformConstrain: TransformConstrainFunction | undefined, globalState: Record<string, any>): {
|
|
18
18
|
projection: Projection;
|
|
19
19
|
transform: ITransform;
|
|
20
20
|
cameraHelper: ICameraHelper;
|
|
21
21
|
} {
|
|
22
22
|
const transformOptions = {constrainOverride: transformConstrain};
|
|
23
23
|
if (Array.isArray(name)) {
|
|
24
|
-
const globeProjection = new GlobeProjection({type: name});
|
|
24
|
+
const globeProjection = new GlobeProjection({type: name}, globalState);
|
|
25
25
|
return {
|
|
26
26
|
projection: globeProjection,
|
|
27
27
|
transform: new GlobeTransform(transformOptions),
|
|
@@ -47,7 +47,7 @@ export function createProjectionFromName(name: ProjectionSpecification['type'],
|
|
|
47
47
|
'vertical-perspective',
|
|
48
48
|
12,
|
|
49
49
|
'mercator'
|
|
50
|
-
]});
|
|
50
|
+
]}, {});
|
|
51
51
|
return {
|
|
52
52
|
projection: globeProjection,
|
|
53
53
|
transform: new GlobeTransform(transformOptions),
|
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
import type {Context} from '../../webgl/context.ts';
|
|
2
2
|
import type {CanonicalTileID} from '../../tile/tile_id.ts';
|
|
3
3
|
import {type Mesh} from '../../render/mesh.ts';
|
|
4
|
-
import {now} from '../../util/time_control.ts';
|
|
5
|
-
import {easeCubicInOut, lerp} from '../../util/util.ts';
|
|
6
|
-
import {mercatorYfromLat} from '../mercator_coordinate.ts';
|
|
7
4
|
import {SubdivisionGranularityExpression, SubdivisionGranularitySetting} from '../../render/subdivision_granularity_settings.ts';
|
|
8
|
-
import type {Projection,
|
|
5
|
+
import type {Projection, TileMeshUsage} from './projection.ts';
|
|
9
6
|
import {type PreparedShader, shaders} from '../../shaders/shaders.ts';
|
|
10
|
-
import {ProjectionErrorMeasurement} from './globe_projection_error_measurement.ts';
|
|
11
7
|
import {createTileMeshWithBuffers, type CreateTileMeshOptions} from '../../util/create_tile_mesh.ts';
|
|
12
8
|
import {type EvaluationParameters} from '../../style/evaluation_parameters.ts';
|
|
13
9
|
|
|
14
10
|
export const VerticalPerspectiveShaderDefine = '#define GLOBE';
|
|
15
11
|
export const VerticalPerspectiveShaderVariantKey = 'globe';
|
|
16
12
|
|
|
17
|
-
export const globeConstants = {
|
|
18
|
-
errorTransitionTimeSeconds: 0.5
|
|
19
|
-
};
|
|
20
|
-
|
|
21
13
|
const granularitySettingsGlobe: SubdivisionGranularitySetting = new SubdivisionGranularitySetting({
|
|
22
14
|
fill: new SubdivisionGranularityExpression(128, 2),
|
|
23
15
|
line: new SubdivisionGranularityExpression(512, 0),
|
|
@@ -36,14 +28,6 @@ const granularitySettingsGlobe: SubdivisionGranularitySetting = new SubdivisionG
|
|
|
36
28
|
export class VerticalPerspectiveProjection implements Projection {
|
|
37
29
|
private _tileMeshCache: {[_: string]: Mesh} = {};
|
|
38
30
|
|
|
39
|
-
// GPU atan() error correction
|
|
40
|
-
private _errorMeasurement: ProjectionErrorMeasurement;
|
|
41
|
-
private _errorQueryLatitudeDegrees: number;
|
|
42
|
-
private _errorCorrectionUsable: number = 0.0;
|
|
43
|
-
private _errorMeasurementLastValue: number = 0.0;
|
|
44
|
-
private _errorCorrectionPreviousValue: number = 0.0;
|
|
45
|
-
private _errorMeasurementLastChangeTime: number = -1000.0;
|
|
46
|
-
|
|
47
31
|
get name(): 'vertical-perspective' {
|
|
48
32
|
return 'vertical-perspective';
|
|
49
33
|
}
|
|
@@ -80,39 +64,8 @@ export class VerticalPerspectiveProjection implements Projection {
|
|
|
80
64
|
return true;
|
|
81
65
|
}
|
|
82
66
|
|
|
83
|
-
/**
|
|
84
|
-
* @internal
|
|
85
|
-
* Globe projection periodically measures the error of the GPU's
|
|
86
|
-
* projection from mercator to globe and computes how much to correct
|
|
87
|
-
* the globe's latitude alignment.
|
|
88
|
-
* This stores the correction that should be applied to the projection matrix.
|
|
89
|
-
*/
|
|
90
|
-
get latitudeErrorCorrectionRadians(): number { return this._errorCorrectionUsable; }
|
|
91
|
-
|
|
92
67
|
public destroy(): void {
|
|
93
|
-
|
|
94
|
-
this._errorMeasurement.destroy();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
public updateGPUdependent(renderContext: ProjectionGPUContext): void {
|
|
99
|
-
this._errorMeasurement ||= new ProjectionErrorMeasurement(renderContext);
|
|
100
|
-
const mercatorY = mercatorYfromLat(this._errorQueryLatitudeDegrees);
|
|
101
|
-
const expectedResult = 2.0 * Math.atan(Math.exp(Math.PI - (mercatorY * Math.PI * 2.0))) - Math.PI * 0.5;
|
|
102
|
-
const newValue = this._errorMeasurement.updateErrorLoop(mercatorY, expectedResult);
|
|
103
|
-
|
|
104
|
-
const currentTime = now();
|
|
105
|
-
|
|
106
|
-
if (newValue !== this._errorMeasurementLastValue) {
|
|
107
|
-
this._errorCorrectionPreviousValue = this._errorCorrectionUsable; // store the interpolated value
|
|
108
|
-
this._errorMeasurementLastValue = newValue;
|
|
109
|
-
this._errorMeasurementLastChangeTime = currentTime;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const sinceUpdateSeconds = (currentTime - this._errorMeasurementLastChangeTime) / 1000.0;
|
|
113
|
-
const mix = Math.min(Math.max(sinceUpdateSeconds / globeConstants.errorTransitionTimeSeconds, 0.0), 1.0);
|
|
114
|
-
const newCorrection = -this._errorMeasurementLastValue; // Note the negation
|
|
115
|
-
this._errorCorrectionUsable = lerp(this._errorCorrectionPreviousValue, newCorrection, easeCubicInOut(mix));
|
|
68
|
+
// Do nothing.
|
|
116
69
|
}
|
|
117
70
|
|
|
118
71
|
private _getMeshKey(options: CreateTileMeshOptions): string {
|
|
@@ -150,16 +103,6 @@ export class VerticalPerspectiveProjection implements Projection {
|
|
|
150
103
|
}
|
|
151
104
|
|
|
152
105
|
hasTransition(): boolean {
|
|
153
|
-
|
|
154
|
-
let dirty = false;
|
|
155
|
-
// Error correction transition
|
|
156
|
-
dirty ||= (currentTime - this._errorMeasurementLastChangeTime) / 1000.0 < (globeConstants.errorTransitionTimeSeconds + 0.2);
|
|
157
|
-
// Error correction query in flight
|
|
158
|
-
dirty ||= (this._errorMeasurement?.awaitingQuery);
|
|
159
|
-
return dirty;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
setErrorQueryLatitudeDegrees(value: number): void {
|
|
163
|
-
this._errorQueryLatitudeDegrees = value;
|
|
106
|
+
return false;
|
|
164
107
|
}
|
|
165
108
|
}
|
|
@@ -245,12 +245,11 @@ export class VerticalPerspectiveTransform implements ITransform {
|
|
|
245
245
|
private _cachedFrustum: Frustum;
|
|
246
246
|
private _projectionMatrix: mat4 = createIdentityMat4f64();
|
|
247
247
|
private _globeViewProjMatrix32f: Mat4f32 = createIdentityMat4f32(); // Must be 32 bit floats, otherwise WebGL calls in Chrome get very slow.
|
|
248
|
-
private
|
|
249
|
-
private
|
|
248
|
+
private _globeViewProjMatrixF64: mat4 = createIdentityMat4f64();
|
|
249
|
+
private _globeViewProjMatrixF64Inverted: mat4 = createIdentityMat4f64();
|
|
250
250
|
private _globeProjMatrixInverted: mat4 = createIdentityMat4f64();
|
|
251
251
|
|
|
252
252
|
private _cameraPosition: vec3 = createVec3f64();
|
|
253
|
-
private _globeLatitudeErrorCorrectionRadians: number = 0;
|
|
254
253
|
/**
|
|
255
254
|
* Globe projection can smoothly interpolate between globe view and mercator. This variable controls this interpolation.
|
|
256
255
|
* Value 0 is mercator, value 1 is globe, anything between is an interpolation between the two projections.
|
|
@@ -272,14 +271,13 @@ export class VerticalPerspectiveTransform implements ITransform {
|
|
|
272
271
|
return clone;
|
|
273
272
|
}
|
|
274
273
|
|
|
275
|
-
public apply(that: IReadonlyTransform, constrain: boolean
|
|
276
|
-
this._globeLatitudeErrorCorrectionRadians = globeLatitudeErrorCorrectionRadians || 0;
|
|
274
|
+
public apply(that: IReadonlyTransform, constrain: boolean): void {
|
|
277
275
|
this._helper.apply(that, constrain);
|
|
278
276
|
}
|
|
279
277
|
|
|
280
278
|
public get projectionMatrix(): mat4 { return this._projectionMatrix; }
|
|
281
279
|
|
|
282
|
-
public get modelViewProjectionMatrix(): mat4 { return this.
|
|
280
|
+
public get modelViewProjectionMatrix(): mat4 { return this._globeViewProjMatrixF64; }
|
|
283
281
|
|
|
284
282
|
public get inverseProjectionMatrix(): mat4 { return this._globeProjMatrixInverted; }
|
|
285
283
|
|
|
@@ -306,6 +304,7 @@ export class VerticalPerspectiveTransform implements ITransform {
|
|
|
306
304
|
clippingPlane: this._cachedClippingPlane as [number, number, number, number],
|
|
307
305
|
projectionTransition: applyGlobeMatrix ? 1 : 0,
|
|
308
306
|
fallbackMatrix: this._globeViewProjMatrix32f,
|
|
307
|
+
clipAntimeridian: overscaledTileID?.canonical.z === 0,
|
|
309
308
|
};
|
|
310
309
|
}
|
|
311
310
|
|
|
@@ -427,7 +426,7 @@ export class VerticalPerspectiveTransform implements ITransform {
|
|
|
427
426
|
const elevation = getElevation ? getElevation(x, y) : 0.0;
|
|
428
427
|
const vectorMultiplier = 1.0 + elevation / earthRadius;
|
|
429
428
|
const pos: vec4 = [spherePos[0] * vectorMultiplier, spherePos[1] * vectorMultiplier, spherePos[2] * vectorMultiplier, 1];
|
|
430
|
-
vec4.transformMat4(pos, pos, this.
|
|
429
|
+
vec4.transformMat4(pos, pos, this._globeViewProjMatrixF64);
|
|
431
430
|
|
|
432
431
|
// Also check whether the point projects to the backfacing side of the sphere.
|
|
433
432
|
const plane = this._cachedClippingPlane;
|
|
@@ -451,7 +450,6 @@ export class VerticalPerspectiveTransform implements ITransform {
|
|
|
451
450
|
|
|
452
451
|
// Construct a completely separate matrix for globe view
|
|
453
452
|
const globeMatrix = createMat4f64();
|
|
454
|
-
const globeMatrixUncorrected = createMat4f64();
|
|
455
453
|
if (this._helper.autoCalculateNearFarZ) {
|
|
456
454
|
this._helper._nearZ = 0.5;
|
|
457
455
|
this._helper._farZ = this.cameraToCenterDistance + globeRadiusPixels * 2.0; // just set the far plane far enough - we will calculate our own z in the vertex shader anyway
|
|
@@ -478,19 +476,14 @@ export class VerticalPerspectiveTransform implements ITransform {
|
|
|
478
476
|
scaleVec[1] = globeRadiusPixels;
|
|
479
477
|
scaleVec[2] = globeRadiusPixels;
|
|
480
478
|
|
|
481
|
-
|
|
482
|
-
mat4.rotateX(globeMatrixUncorrected, globeMatrix, this.center.lat * Math.PI / 180.0);
|
|
483
|
-
mat4.rotateY(globeMatrixUncorrected, globeMatrixUncorrected, -this.center.lng * Math.PI / 180.0);
|
|
484
|
-
mat4.scale(globeMatrixUncorrected, globeMatrixUncorrected, scaleVec); // Scale the unit sphere to a sphere with diameter of 1
|
|
485
|
-
this._globeViewProjMatrixNoCorrection = globeMatrixUncorrected;
|
|
486
|
-
|
|
487
|
-
mat4.rotateX(globeMatrix, globeMatrix, this.center.lat * Math.PI / 180.0 - this._globeLatitudeErrorCorrectionRadians);
|
|
479
|
+
mat4.rotateX(globeMatrix, globeMatrix, this.center.lat * Math.PI / 180.0);
|
|
488
480
|
mat4.rotateY(globeMatrix, globeMatrix, -this.center.lng * Math.PI / 180.0);
|
|
489
481
|
mat4.scale(globeMatrix, globeMatrix, scaleVec); // Scale the unit sphere to a sphere with diameter of 1
|
|
482
|
+
this._globeViewProjMatrixF64 = globeMatrix;
|
|
490
483
|
this._globeViewProjMatrix32f = new Float32Array(globeMatrix);
|
|
491
484
|
|
|
492
|
-
this.
|
|
493
|
-
mat4.invert(this.
|
|
485
|
+
this._globeViewProjMatrixF64Inverted = createMat4f64();
|
|
486
|
+
mat4.invert(this._globeViewProjMatrixF64Inverted, globeMatrix);
|
|
494
487
|
|
|
495
488
|
const zero = createVec3f64();
|
|
496
489
|
this._cameraPosition = createVec3f64();
|
|
@@ -504,7 +497,7 @@ export class VerticalPerspectiveTransform implements ITransform {
|
|
|
504
497
|
|
|
505
498
|
this._cachedClippingPlane = this._computeClippingPlane(globeRadiusPixels);
|
|
506
499
|
|
|
507
|
-
const matrix = mat4.clone(this.
|
|
500
|
+
const matrix = mat4.clone(this._globeViewProjMatrixF64Inverted);
|
|
508
501
|
mat4.scale(matrix, matrix, [1, 1, -1]);
|
|
509
502
|
this._cachedFrustum = Frustum.fromInvProjectionMatrix(matrix, 1, 0, this._cachedClippingPlane, true);
|
|
510
503
|
}
|
|
@@ -557,13 +550,13 @@ export class VerticalPerspectiveTransform implements ITransform {
|
|
|
557
550
|
}
|
|
558
551
|
|
|
559
552
|
lngLatToCameraDepth(lngLat: LngLat, elevation: number): number {
|
|
560
|
-
if (!this.
|
|
553
|
+
if (!this._globeViewProjMatrixF64) {
|
|
561
554
|
return 1.0; // _calcMatrices hasn't run yet
|
|
562
555
|
}
|
|
563
556
|
const vec = angularCoordinatesToSurfaceVector(lngLat);
|
|
564
557
|
vec3.scale(vec, vec, (1.0 + elevation / earthRadius));
|
|
565
558
|
const result = createVec4f64();
|
|
566
|
-
vec4.transformMat4(result, [vec[0], vec[1], vec[2], 1], this.
|
|
559
|
+
vec4.transformMat4(result, [vec[0], vec[1], vec[2], 1], this._globeViewProjMatrixF64);
|
|
567
560
|
return result[2] / result[3];
|
|
568
561
|
}
|
|
569
562
|
|
|
@@ -783,7 +776,7 @@ export class VerticalPerspectiveTransform implements ITransform {
|
|
|
783
776
|
*/
|
|
784
777
|
private _projectSurfacePointToScreen(pos: vec3): Point {
|
|
785
778
|
const projected = createVec4f64();
|
|
786
|
-
vec4.transformMat4(projected, [...pos, 1] as vec4, this.
|
|
779
|
+
vec4.transformMat4(projected, [...pos, 1] as vec4, this._globeViewProjMatrixF64);
|
|
787
780
|
projected[0] /= projected[3];
|
|
788
781
|
projected[1] /= projected[3];
|
|
789
782
|
return new Point(
|
|
@@ -826,7 +819,7 @@ export class VerticalPerspectiveTransform implements ITransform {
|
|
|
826
819
|
pos[1] = ((p.y / this.height) * 2.0 - 1.0) * -1.0;
|
|
827
820
|
pos[2] = 1;
|
|
828
821
|
pos[3] = 1;
|
|
829
|
-
vec4.transformMat4(pos, pos, this.
|
|
822
|
+
vec4.transformMat4(pos, pos, this._globeViewProjMatrixF64Inverted);
|
|
830
823
|
pos[0] /= pos[3];
|
|
831
824
|
pos[1] /= pos[3];
|
|
832
825
|
pos[2] /= pos[3];
|
|
@@ -860,7 +853,7 @@ export class VerticalPerspectiveTransform implements ITransform {
|
|
|
860
853
|
}
|
|
861
854
|
|
|
862
855
|
const projected = createVec4f64();
|
|
863
|
-
vec4.transformMat4(projected, [...vec, 1] as vec4, this.
|
|
856
|
+
vec4.transformMat4(projected, [...vec, 1] as vec4, this._globeViewProjMatrixF64);
|
|
864
857
|
projected[0] /= projected[3];
|
|
865
858
|
projected[1] /= projected[3];
|
|
866
859
|
projected[2] /= projected[3];
|
|
@@ -232,9 +232,8 @@ interface ITransformMutators {
|
|
|
232
232
|
* @internal
|
|
233
233
|
* Sets the transform's transition state from one projection to another.
|
|
234
234
|
* @param value - The transition state value.
|
|
235
|
-
* @param error - The error value.
|
|
236
235
|
*/
|
|
237
|
-
setTransitionState(value: number
|
|
236
|
+
setTransitionState(value: number): void;
|
|
238
237
|
}
|
|
239
238
|
|
|
240
239
|
/**
|
package/src/index.test.ts
CHANGED
|
@@ -3,7 +3,6 @@ import {config} from './util/config.ts';
|
|
|
3
3
|
import {addProtocol, getWorkerCount, removeProtocol, getVersion} from './index.ts';
|
|
4
4
|
import {getJSON, getArrayBuffer} from './util/ajax.ts';
|
|
5
5
|
import {ImageRequest} from './util/image_request.ts';
|
|
6
|
-
import {isAbortError} from './util/abort_error.ts';
|
|
7
6
|
|
|
8
7
|
describe('maplibre', () => {
|
|
9
8
|
beforeEach(() => {
|
|
@@ -37,7 +36,7 @@ describe('maplibre', () => {
|
|
|
37
36
|
});
|
|
38
37
|
|
|
39
38
|
test('addProtocol - getJSON', async () => {
|
|
40
|
-
const mockProtocol = vi.fn().
|
|
39
|
+
const mockProtocol = vi.fn().mockResolvedValue({data: {'foo': 'bar'}});
|
|
41
40
|
addProtocol('custom', mockProtocol);
|
|
42
41
|
|
|
43
42
|
const response = await getJSON({url: 'custom://test/url/json'}, new AbortController());
|
|
@@ -46,7 +45,7 @@ describe('maplibre', () => {
|
|
|
46
45
|
});
|
|
47
46
|
|
|
48
47
|
test('addProtocol - getArrayBuffer', async () => {
|
|
49
|
-
const mockProtocol = vi.fn().
|
|
48
|
+
const mockProtocol = vi.fn().mockResolvedValue({data: new ArrayBuffer(1), cacheControl: 'cache-control', expires: 'expires'});
|
|
50
49
|
addProtocol('custom', mockProtocol);
|
|
51
50
|
|
|
52
51
|
const response = await getArrayBuffer({url: 'custom://test/url/getArrayBuffer'}, new AbortController());
|
|
@@ -57,7 +56,7 @@ describe('maplibre', () => {
|
|
|
57
56
|
});
|
|
58
57
|
|
|
59
58
|
test('addProtocol - null response for getArrayBuffer results in empty array buffer', async () => {
|
|
60
|
-
const mockProtocol = vi.fn().
|
|
59
|
+
const mockProtocol = vi.fn().mockResolvedValue({data: null, cacheControl: 'cache-control', expires: 'expires'});
|
|
61
60
|
addProtocol('custom', mockProtocol);
|
|
62
61
|
|
|
63
62
|
const response = await getArrayBuffer({url: 'custom://test/url/getArrayBuffer'}, new AbortController());
|
|
@@ -69,7 +68,7 @@ describe('maplibre', () => {
|
|
|
69
68
|
});
|
|
70
69
|
|
|
71
70
|
test('addProtocol - returning ImageBitmap for getImage', async () => {
|
|
72
|
-
const mockProtocol = vi.fn().
|
|
71
|
+
const mockProtocol = vi.fn().mockResolvedValue({data: new ImageBitmap()});
|
|
73
72
|
addProtocol('custom', mockProtocol);
|
|
74
73
|
|
|
75
74
|
const img = await ImageRequest.getImage({url: 'custom://test/url/getImage'}, new AbortController());
|
|
@@ -78,7 +77,7 @@ describe('maplibre', () => {
|
|
|
78
77
|
});
|
|
79
78
|
|
|
80
79
|
test('addProtocol - returning HTMLImageElement for getImage', async () => {
|
|
81
|
-
const mockProtocol = vi.fn().
|
|
80
|
+
const mockProtocol = vi.fn().mockResolvedValue({data: new Image()});
|
|
82
81
|
addProtocol('custom', mockProtocol);
|
|
83
82
|
|
|
84
83
|
const img = await ImageRequest.getImage({url: 'custom://test/url/getImage'}, new AbortController());
|
|
@@ -88,7 +87,7 @@ describe('maplibre', () => {
|
|
|
88
87
|
|
|
89
88
|
test('addProtocol - error', async () => {
|
|
90
89
|
const mockError = new Error('test error');
|
|
91
|
-
const mockProtocol = vi.fn().
|
|
90
|
+
const mockProtocol = vi.fn().mockRejectedValue(mockError);
|
|
92
91
|
addProtocol('custom', mockProtocol);
|
|
93
92
|
|
|
94
93
|
const successCallback = vi.fn();
|
|
@@ -110,11 +109,7 @@ describe('maplibre', () => {
|
|
|
110
109
|
const abortController = new AbortController();
|
|
111
110
|
const promise = getJSON({url: 'custom://test/url/json'}, abortController);
|
|
112
111
|
abortController.abort();
|
|
113
|
-
|
|
114
|
-
await promise;
|
|
115
|
-
} catch (err) {
|
|
116
|
-
expect(isAbortError(err)).toBeTruthy();
|
|
117
|
-
}
|
|
112
|
+
await promise;
|
|
118
113
|
|
|
119
114
|
expect(cancelCalled).toBeTruthy();
|
|
120
115
|
});
|
package/src/index.ts
CHANGED
|
@@ -22,9 +22,9 @@ import {now, setNow, restoreNow, isTimeFrozen} from './util/time_control.ts';
|
|
|
22
22
|
import {WorkerPool} from './util/worker_pool.ts';
|
|
23
23
|
import {prewarm, clearPrewarmedResources} from './util/global_worker_pool.ts';
|
|
24
24
|
import {AJAXError, type ExpiryData, type GetResourceResponse, type RequestParameters} from './util/ajax.ts';
|
|
25
|
-
import {GeoJSONSource, type SetClusterOptions} from './source/geojson_source.ts';
|
|
25
|
+
import {GeoJSONSource, type GetClusterOptions, type SetClusterOptions} from './source/geojson_source.ts';
|
|
26
26
|
import {CanvasSource, type CanvasSourceSpecification} from './source/canvas_source.ts';
|
|
27
|
-
import {type CanonicalTileRange, type Coordinates, ImageSource, type UpdateImageOptions} from './source/image_source.ts';
|
|
27
|
+
import {type CanonicalTileRange, type Coordinates, type ImageSourceImage, ImageSource, type UpdateImageOptions} from './source/image_source.ts';
|
|
28
28
|
import {RasterDEMTileSource} from './source/raster_dem_tile_source.ts';
|
|
29
29
|
import {RasterTileSource} from './source/raster_tile_source.ts';
|
|
30
30
|
import {VectorTileSource, type LoadTileResult} from './source/vector_tile_source.ts';
|
|
@@ -298,9 +298,11 @@ export {
|
|
|
298
298
|
type Tile,
|
|
299
299
|
type Listener,
|
|
300
300
|
type Coordinates,
|
|
301
|
+
type ImageSourceImage,
|
|
301
302
|
type UpdateImageOptions,
|
|
302
303
|
type DragPanOptions,
|
|
303
304
|
type FullscreenControlOptions,
|
|
305
|
+
type GetClusterOptions,
|
|
304
306
|
type SetClusterOptions,
|
|
305
307
|
type GeoJSONSourceDiff,
|
|
306
308
|
type GeolocateControlOptions,
|
|
@@ -208,9 +208,7 @@ describe('GlyphManager', () => {
|
|
|
208
208
|
test('GlyphManager caches locally generated glyphs', async () => {
|
|
209
209
|
|
|
210
210
|
const manager = createGlyphManager(true, 'sans-serif');
|
|
211
|
-
const drawSpy = GlyphManager.TinySDF.prototype
|
|
212
|
-
return {data: new Uint8ClampedArray(60 * 60)} as any;
|
|
213
|
-
});
|
|
211
|
+
const drawSpy = vi.spyOn(GlyphManager.TinySDF.prototype, 'draw').mockReturnValue({data: new Uint8ClampedArray(60 * 60)} as any);
|
|
214
212
|
|
|
215
213
|
// Katakana letter te
|
|
216
214
|
const returnedGlyphs = await manager.getGlyphs({'Arial Unicode MS': [0x30c6]});
|
|
@@ -220,22 +218,14 @@ describe('GlyphManager', () => {
|
|
|
220
218
|
});
|
|
221
219
|
|
|
222
220
|
test('GlyphManager passes no language to TinySDF by default', async () => {
|
|
223
|
-
const langSpy =
|
|
224
|
-
return {
|
|
225
|
-
draw: () => GLYPHS[0]
|
|
226
|
-
};
|
|
227
|
-
});
|
|
221
|
+
const langSpy = vi.spyOn(GlyphManager, 'TinySDF').mockImplementation(class { draw = () => GLYPHS[0]; });
|
|
228
222
|
const manager = createGlyphManager(true, 'sans-serif');
|
|
229
223
|
await manager.getGlyphs({'Arial Unicode MS': [0x30c6]});
|
|
230
224
|
expect(langSpy).toHaveBeenCalledWith(expect.not.objectContaining({lang: expect.anything()}));
|
|
231
225
|
});
|
|
232
226
|
|
|
233
227
|
test('GlyphManager sets the language on TinySDF', async () => {
|
|
234
|
-
const langSpy =
|
|
235
|
-
return {
|
|
236
|
-
draw: () => GLYPHS[0]
|
|
237
|
-
};
|
|
238
|
-
});
|
|
228
|
+
const langSpy = vi.spyOn(GlyphManager, 'TinySDF').mockImplementation(class { draw = () => GLYPHS[0]; });
|
|
239
229
|
const manager = createGlyphManager(true, 'sans-serif', 'zh');
|
|
240
230
|
await manager.getGlyphs({'Arial Unicode MS': [0x30c6]});
|
|
241
231
|
expect(langSpy).toHaveBeenCalledWith(expect.objectContaining({lang: 'zh'}));
|
|
@@ -244,9 +234,7 @@ describe('GlyphManager', () => {
|
|
|
244
234
|
test('awaits document.fonts.load before instantiating TinySDF', async () => {
|
|
245
235
|
const loadSpy = vi.fn(() => Promise.resolve([]));
|
|
246
236
|
Object.defineProperty(document, 'fonts', {configurable: true, value: {load: loadSpy}});
|
|
247
|
-
const tinySdfSpy =
|
|
248
|
-
return {draw: () => GLYPHS[0]};
|
|
249
|
-
});
|
|
237
|
+
const tinySdfSpy = vi.spyOn(GlyphManager, 'TinySDF').mockImplementation(class { draw = () => GLYPHS[0]; });
|
|
250
238
|
|
|
251
239
|
const manager = createGlyphManager(false, 'sans-serif');
|
|
252
240
|
await manager.getGlyphs({'Arial Unicode MS': [0x41]});
|
|
@@ -257,11 +245,10 @@ describe('GlyphManager', () => {
|
|
|
257
245
|
});
|
|
258
246
|
|
|
259
247
|
test('still instantiates TinySDF when document.fonts.load rejects', async () => {
|
|
248
|
+
vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
260
249
|
const loadSpy = vi.fn(() => Promise.reject(new Error('font not found')));
|
|
261
250
|
Object.defineProperty(document, 'fonts', {configurable: true, value: {load: loadSpy}});
|
|
262
|
-
const tinySdfSpy =
|
|
263
|
-
return {draw: () => GLYPHS[0]};
|
|
264
|
-
});
|
|
251
|
+
const tinySdfSpy = vi.spyOn(GlyphManager, 'TinySDF').mockImplementation(class { draw = () => GLYPHS[0]; });
|
|
265
252
|
|
|
266
253
|
const manager = createGlyphManager(false, 'sans-serif');
|
|
267
254
|
const result = await manager.getGlyphs({'Arial Unicode MS': [0x41]});
|
|
@@ -274,9 +261,7 @@ describe('GlyphManager', () => {
|
|
|
274
261
|
test('memoizes document.fonts.load per fontstack', async () => {
|
|
275
262
|
const loadSpy = vi.fn(() => Promise.resolve([]));
|
|
276
263
|
Object.defineProperty(document, 'fonts', {configurable: true, value: {load: loadSpy}});
|
|
277
|
-
|
|
278
|
-
return {draw: () => GLYPHS[0]};
|
|
279
|
-
});
|
|
264
|
+
vi.spyOn(GlyphManager, 'TinySDF').mockImplementation(class { draw = () => GLYPHS[0]; });
|
|
280
265
|
|
|
281
266
|
const manager = createGlyphManager(false, 'sans-serif');
|
|
282
267
|
await manager.getGlyphs({'Arial Unicode MS': [0x41]});
|
package/src/render/painter.ts
CHANGED
|
@@ -284,6 +284,7 @@ export class Painter {
|
|
|
284
284
|
clippingPlane: [0, 0, 0, 0],
|
|
285
285
|
projectionTransition: 0.0,
|
|
286
286
|
fallbackMatrix: matrix,
|
|
287
|
+
clipAntimeridian: false,
|
|
287
288
|
};
|
|
288
289
|
|
|
289
290
|
// Note: we force a simple mercator projection for the shader, since we want to draw a fullscreen quad.
|
|
@@ -317,12 +318,14 @@ export class Painter {
|
|
|
317
318
|
stencilRefs[tileID.key] = this.nextStencilID++;
|
|
318
319
|
}
|
|
319
320
|
|
|
320
|
-
// A two-pass approach is needed. See comment in draw_raster.ts
|
|
321
|
-
//
|
|
321
|
+
// A two-pass approach is needed for subdivided projections. See comment in draw_raster.ts
|
|
322
|
+
// for more details. In non-subdivided projections the border flag does not change the mesh,
|
|
323
|
+
// so one pass produces the same stencil mask.
|
|
324
|
+
if (this.style.projection.useSubdivision) {
|
|
325
|
+
this._renderTileMasks(stencilRefs, tileIDs, renderToTexture, true);
|
|
326
|
+
}
|
|
322
327
|
|
|
323
|
-
//
|
|
324
|
-
this._renderTileMasks(stencilRefs, tileIDs, renderToTexture, true);
|
|
325
|
-
// Second pass - draw borderless tiles with GL_ALWAYS
|
|
328
|
+
// Final pass - draw borderless tiles with GL_ALWAYS
|
|
326
329
|
this._renderTileMasks(stencilRefs, tileIDs, renderToTexture, false);
|
|
327
330
|
|
|
328
331
|
this._tileClippingMaskIDs = stencilRefs;
|
|
@@ -573,12 +576,6 @@ export class Painter {
|
|
|
573
576
|
this.renderLayer(this, tileManagers[layer.source], layer, coords, renderOptions);
|
|
574
577
|
}
|
|
575
578
|
|
|
576
|
-
// Execute offscreen GPU tasks of the projection manager
|
|
577
|
-
this.style.projection?.updateGPUdependent({
|
|
578
|
-
context: this.context,
|
|
579
|
-
useProgram: (name: string) => this.useProgram(name)
|
|
580
|
-
});
|
|
581
|
-
|
|
582
579
|
// Rebind the main framebuffer now that all offscreen layers have been rendered:
|
|
583
580
|
this.context.viewport.set([0, 0, this.width, this.height]);
|
|
584
581
|
this.context.bindFramebuffer.set(null);
|