maplibre-gl 6.2.0 → 6.4.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/dist/maplibre-gl-dev.mjs +1108 -427
- package/dist/maplibre-gl-dev.mjs.map +1 -1
- package/dist/maplibre-gl-shared-dev.mjs +359 -291
- 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 +23 -49
- 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 +467 -151
- package/dist/maplibre-gl.mjs +49 -49
- package/dist/maplibre-gl.mjs.map +1 -1
- package/package.json +12 -22
- package/src/data/bucket/fill_extrusion_bucket.ts +1 -13
- package/src/data/bucket/round_polygon_corners.test.ts +84 -36
- package/src/data/bucket/round_polygon_corners.ts +90 -39
- package/src/data/extent_bounds.ts +28 -1
- package/src/data/feature_index.bench.ts +21 -0
- package/src/data/segment.test.ts +2 -2
- package/src/geo/edge_insets.test.ts +1 -1
- package/src/geo/lng_lat.test.ts +7 -7
- package/src/geo/lng_lat_bounds.test.ts +4 -4
- package/src/geo/mercator_coordinate.test.ts +2 -2
- package/src/geo/projection/camera_helper.ts +5 -0
- package/src/geo/projection/globe_transform.test.ts +154 -1
- package/src/geo/projection/globe_transform.ts +7 -3
- package/src/geo/projection/globe_utils.ts +189 -2
- package/src/geo/projection/mercator_camera_helper.ts +1 -1
- package/src/geo/projection/mercator_transform.ts +21 -5
- package/src/geo/projection/vertical_perspective_camera_helper.test.ts +24 -0
- package/src/geo/projection/vertical_perspective_camera_helper.ts +71 -41
- package/src/geo/projection/vertical_perspective_transform.ts +7 -1
- package/src/geo/transform_interface.ts +13 -1
- package/src/index.ts +7 -2
- package/src/render/image_atlas.test.ts +180 -0
- package/src/render/image_atlas.ts +52 -6
- package/src/render/image_manager.test.ts +111 -0
- package/src/render/image_manager.ts +143 -144
- package/src/render/painter.ts +6 -14
- package/src/render/pattern_atlas.test.ts +131 -0
- package/src/render/pattern_atlas.ts +144 -0
- package/src/render/update_pattern_positions_in_program.test.ts +1 -1
- package/src/shaders/glsl/_prelude.vertex.glsl +10 -11
- package/src/shaders/glsl/_prelude.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/circle.vertex.glsl +4 -4
- package/src/shaders/glsl/circle.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/color_relief.fragment.glsl +1 -2
- package/src/shaders/glsl/color_relief.fragment.glsl.g.ts +1 -1
- package/src/shaders/glsl/fill_extrusion.vertex.glsl +3 -3
- package/src/shaders/glsl/fill_extrusion.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/fill_extrusion_pattern.vertex.glsl +5 -5
- package/src/shaders/glsl/fill_extrusion_pattern.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/heatmap.vertex.glsl +4 -4
- package/src/shaders/glsl/heatmap.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/hillshade_prepare.fragment.glsl +12 -12
- package/src/shaders/glsl/hillshade_prepare.fragment.glsl.g.ts +1 -1
- package/src/shaders/glsl/line.vertex.glsl +7 -7
- package/src/shaders/glsl/line.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_gradient.vertex.glsl +6 -6
- package/src/shaders/glsl/line_gradient.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_gradient_sdf.vertex.glsl +7 -7
- package/src/shaders/glsl/line_gradient_sdf.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_pattern.vertex.glsl +7 -7
- package/src/shaders/glsl/line_pattern.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/line_sdf.vertex.glsl +7 -7
- package/src/shaders/glsl/line_sdf.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/raster.fragment.glsl +4 -4
- package/src/shaders/glsl/raster.fragment.glsl.g.ts +1 -1
- package/src/shaders/glsl/raster.vertex.glsl +11 -6
- package/src/shaders/glsl/raster.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/symbol_icon.vertex.glsl +5 -5
- package/src/shaders/glsl/symbol_icon.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/symbol_sdf.vertex.glsl +5 -5
- package/src/shaders/glsl/symbol_sdf.vertex.glsl.g.ts +1 -1
- package/src/shaders/glsl/symbol_text_and_icon.vertex.glsl +6 -6
- package/src/shaders/glsl/symbol_text_and_icon.vertex.glsl.g.ts +1 -1
- package/src/source/canvas_source.test.ts +31 -0
- package/src/source/canvas_source.ts +2 -1
- package/src/source/geojson_worker_source.test.ts +88 -0
- package/src/source/geojson_worker_source.ts +22 -39
- package/src/source/image_source.test.ts +246 -38
- package/src/source/image_source.ts +132 -19
- package/src/source/raster_dem_tile_source.test.ts +37 -3
- package/src/source/raster_dem_tile_source.ts +1 -2
- package/src/source/raster_dem_tile_worker_source.test.ts +1 -1
- package/src/source/raster_tile_source.test.ts +5 -26
- package/src/source/raster_tile_source.ts +4 -3
- package/src/source/vector_tile_worker_source.test.ts +94 -2
- package/src/source/vector_tile_worker_source.ts +18 -27
- package/src/source/video_source.test.ts +12 -8
- package/src/source/worker_tile.bench.ts +10 -0
- package/src/source/worker_tile.ts +0 -3
- package/src/style/create_style_layer.bench.ts +15 -0
- package/src/style/properties.bench.ts +81 -0
- package/src/style/style.test.ts +75 -10
- package/src/style/style.ts +37 -64
- package/src/style/style_image.ts +67 -9
- package/src/style/style_layer.bench.ts +65 -0
- package/src/style/style_layer.test.ts +1 -1
- package/src/style/style_layer.ts +2 -2
- package/src/style/validate_style.bench.ts +11 -0
- package/src/style/validate_style.test.ts +2 -2
- package/src/symbol/anchor.test.ts +2 -2
- package/src/symbol/collision_index.bench.ts +116 -0
- package/src/symbol/cross_tile_symbol_index.bench.ts +49 -0
- package/src/symbol/cross_tile_symbol_index.test.ts +31 -0
- package/src/symbol/cross_tile_symbol_index.ts +67 -37
- package/src/symbol/shaping.test.ts +2 -1
- package/src/symbol/symbol_layout.bench.ts +30 -0
- package/src/tile/tile_id.test.ts +1 -1
- package/src/tile/tile_manager.test.ts +69 -1
- package/src/tile/tile_manager.ts +16 -11
- package/src/ui/control/fullscreen_control.test.ts +10 -10
- package/src/ui/control/geolocate_control.test.ts +3 -5
- package/src/ui/control/globe_control.test.ts +6 -6
- package/src/ui/events.ts +1 -1
- package/src/ui/handler/scroll_zoom.test.ts +50 -0
- package/src/ui/handler/two_fingers_touch.test.ts +17 -6
- package/src/ui/handler_inertia.test.ts +91 -0
- package/src/ui/handler_inertia.ts +65 -14
- package/src/ui/handler_manager.test.ts +243 -3
- package/src/ui/handler_manager.ts +79 -16
- package/src/ui/map.ts +17 -3
- package/src/ui/map_tests/map_cross_window.test.ts +2 -2
- package/src/ui/map_tests/map_events.test.ts +3 -3
- package/src/ui/map_tests/map_images.test.ts +55 -0
- package/src/ui/map_tests/map_style.test.ts +9 -8
- package/src/ui/map_tests/map_webgl.test.ts +30 -0
- package/src/ui/marker.test.ts +177 -42
- package/src/ui/marker.ts +120 -10
- package/src/ui/popup.test.ts +14 -14
- package/src/util/evented.test.ts +33 -28
- package/src/util/evented.ts +69 -43
- package/src/util/image_request.ts +31 -1
- package/src/util/test/null_gl.ts +10 -0
- package/src/util/test/util.ts +2 -1
- package/src/util/util.test.ts +1 -1
- package/src/util/web_worker_transfer.test.ts +5 -5
- package/src/webgl/context.ts +20 -0
- package/src/webgl/draw/draw_background.ts +1 -1
- package/src/webgl/draw/draw_raster.ts +11 -6
- package/src/webgl/program/pattern.ts +3 -3
- package/src/webgl/program/raster_program.ts +11 -0
- package/src/webgl/program.ts +31 -16
- package/src/webgl/texture.test.ts +16 -1
- package/src/webgl/texture.ts +3 -0
- package/src/webgl/vertex_buffer.test.ts +17 -2
- package/src/webgl/vertex_buffer.ts +24 -13
package/dist/maplibre-gl-dev.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MapLibre GL JS
|
|
3
|
-
* @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v6.
|
|
3
|
+
* @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v6.4.0/LICENSE.txt
|
|
4
4
|
*/
|
|
5
|
-
import { $ as tileCoordinatesToMercatorCoordinates, $n as
|
|
5
|
+
import { $ as tileCoordinatesToMercatorCoordinates, $n as deepEqual, $r as mul, $t as TRANSITION_SUFFIX, A as evaluateSizeForFeature, Ai as perspective, An as getVideo, Ar as remapSaturate, At as toEvaluationFeature, Bi as invert, Br as wrap, Bt as SegmentVector, C as isCustomStyleLayer, Ci as equals, Cn as Event, Cr as nextPowerOfTwo, Ct as HEATMAP_FULL_RENDER_FBO_KEY, D as SymbolBucket, Di as invert$1, Dn as getArrayBuffer, Dr as radiansToDegrees, Dt as RGBAImage, E as isSymbolStyleLayer, Ei as identity, En as GLOBAL_DISPATCHER_ID, Er as pointPlaneSignedDistance, Et as AlphaImage, F as ImagePosition, Fi as translate, Fn as removeProtocol, Fr as subscribe, Ft as Uniform4f, G as isFillExtrusionStyleLayer, Gn as bezier, Gr as length, Gt as PosArray, H as isLineStyleLayer, Hi as isOffscreenCanvasDistorted, Hn as angleToRotateBetweenVectors2D, Hr as pixelsToTileUnits, Ht as CollisionCircleLayoutArray, I as potpack, Ii as create$4, In as config, Ir as threePlaneIntersection, It as UniformColor, J as cameraDirectionFromPitchBearing, Jn as createIdentityMat4f32, Jr as zero, Jt as TriangleIndexArray, Kn as clamp, Kr as scale$1, Kt as QuadTriangleArray, L as isStyleImageWebGLData, Li as fromRotation, Ln as AbortError, Lr as translatePosition, Lt as UniformColorArray, Mi as rotateY$1, Mn as sameOrigin, Mr as rollPitchBearingToQuat, Mt as Uniform1i, N as getAnchorAlignment, Ni as rotateZ, Nn as addProtocol, Nr as scaleZoom, Nt as Uniform2f, O as addDynamicAttributes, Oi as multiply, On as getJSON, Or as rayPlaneIntersection, Ot as isCircleStyleLayer, Pi as scale, Pn as getProtocol, Pr as sphericalToCartesian, Pt as Uniform3f, Q as projectToWorldCoordinates, Qn as createVec4f64, Qr as slerp, Qt as Properties, R as renderStyleImage, Ri as create$2, Rn as isAbortError, Rr as uniqueId, Rt as UniformFloatArray, S as createStyleLayer, Si as create$1, Sn as ErrorEvent, Sr as mod, St as isHillshadeStyleLayer, T as isBackgroundStyleLayer, Ti as fromScaling, Tn as AJAXError, Tr as pick, Tt as renderColorRamp, Ui as offscreenCanvasSupported, Un as arrayBufferToImage, Ur as EXTENT, Ut as LineStripIndexArray, V as collisionCircleLayout, Vi as rotate, Vn as MAX_VALID_LATITUDE, Vr as zoomScale, Vt as CollisionBoxArray, Wi as Point, Wn as arrayBufferToImageBitmap, Wr as create$3, Wt as Pos3dArray, X as getMercatorHorizon, Xn as createMat4f64, Xr as fromValues, Xt as isRasterStyleLayer, Y as cameraMercatorCoordinateFromCenterAndRotation, Yn as createIdentityMat4f64, Yr as fromEuler, Yt as createLayout, Z as maxMercatorHorizonAngle, Zn as createVec3f64, Zr as multiply$1, Zt as DataConstantProperty, _ as UnwrappedTileID, _i as transformMat4$1, _n as emptyStyle, _r as isTouchableEvent, _t as SubdivisionGranularityExpression, a as clipLine, ai as dot, ar as evaluateZoomSnap, at as mercatorXfromLng, b as isInBoundsForZoomLngLat, bi as clone$1, bn as interpolateFactory, br as lerp, ci as negate, cn as validateAndEmit, cr as findLineIntersection, ct as LngLat, di as rotateY, dn as Color, dr as getEdgeTiles, dt as EXTENT_BOUNDS, ei as scale$3, en as Transitionable, er as defaultEasing, et as unprojectFromWorldCoordinates, f as GEOJSON_TILE_LAYER_NAME, fi as rotateZ$1, fn as ProjectionDefinition, ft as Bounds, g as OverscaledTileID, gi as transformMat3, gn as diff, gr as isSafari, gt as SOUTH_POLE_Y, h as CanonicalTileID, hi as sub, hn as derefLayers, hr as isPointableEvent, ht as NORTH_POLE_Y, ii as cross, in as ZoomHistory, ir as ensureError, it as lngFromMercatorX, j as evaluateSizeForZoom, ji as rotateX, jn as makeRequest, jr as rollPitchBearingEqual, jt as Uniform1f, k as getOverlapMode, ki as ortho, kn as getReferrer, kr as readImageUsingVideoFrame, kt as polygonIntersectsPolygon, li as normalize, ln as validateStyle, lr as getAABB, lt as earthRadius, mi as scaleAndAdd, mr as isImageBitmap, ni as add, nr as differenceOfAnglesDegrees, nt as altitudeFromMercatorZ, oi as len, on as SPEC_SOURCE_TYPES, or as extend, ot as mercatorYfromLat, pi as scale$2, pn as ValidationError, pr as getRollPitchBearing, pt as isFillStyleLayer, q as calculateTileMatrix, qn as clone$2, qr as sqrLen, qt as RasterBoundsArray, r as TextAnchorEnum, ri as clone, rn as codePointUsesLocalIdeographFontFamily, rr as distanceOfAnglesRadians, rt as latFromMercatorY, s as TileCache, si as length$1, sn as emitValidationErrors, sr as filterObject, st as mercatorZfromAltitude, t as getAnchorJustification, ti as transformMat4, tn as EvaluationParameters, tr as degreesToRadians, tt as MercatorCoordinate, u as GeoJSONFeature, ui as rotateX$1, un as validateStyleAndEmit, ur as getAngleDelta, v as calculateTileKey, vi as transformQuat, vn as featureFilter, vr as isTouchableOrPointableType, vt as SubdivisionGranularitySetting, w as validateCustomStyleLayer, wi as exactEquals, wn as Evented, wr as parseCacheControl, wt as isHeatmapStyleLayer, x as Actor, xi as copy, xn as latest, xr as mapObject, xt as Texture, y as compareTileId, yi as zero$1, yr as isWorker, yt as isColorReliefStyleLayer, z as parseGlyphPbf, zi as determinant, zn as throwIfAborted, zr as warnOnce, zt as UniformMatrix4f } from "./maplibre-gl-shared-dev.mjs";
|
|
6
6
|
//#region package.json
|
|
7
|
-
var version$2 = "6.
|
|
7
|
+
var version$2 = "6.4.0";
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/util/browser.ts
|
|
10
10
|
let linkEl;
|
|
@@ -326,6 +326,12 @@ let ImageRequest;
|
|
|
326
326
|
for (const key of Object.keys(throttleControlCallbacks)) if (throttleControlCallbacks[key]()) return true;
|
|
327
327
|
return false;
|
|
328
328
|
};
|
|
329
|
+
async function transformAndGetImage(requestManager, url, resourceType, abortController, supportImageRefresh = true, imageBitmapOptions) {
|
|
330
|
+
const requestParameters = await requestManager.transformRequest(url, resourceType);
|
|
331
|
+
throwIfAborted(abortController.signal);
|
|
332
|
+
return ImageRequest.getImage(requestParameters, abortController, supportImageRefresh, imageBitmapOptions);
|
|
333
|
+
}
|
|
334
|
+
_ImageRequest.transformAndGetImage = transformAndGetImage;
|
|
329
335
|
_ImageRequest.getImage = (requestParameters, abortController, supportImageRefresh = true, imageBitmapOptions) => {
|
|
330
336
|
return new Promise((resolve, reject) => {
|
|
331
337
|
requestParameters.headers ||= {};
|
|
@@ -754,51 +760,25 @@ async function doOnceCompleted(jsonsMap, imagesMap) {
|
|
|
754
760
|
//#endregion
|
|
755
761
|
//#region src/render/image_manager.ts
|
|
756
762
|
/**
|
|
757
|
-
*
|
|
758
|
-
*
|
|
759
|
-
*
|
|
760
|
-
* correct behavior of GL_LINEAR texture sampling mode.
|
|
761
|
-
*/
|
|
762
|
-
const padding = 1;
|
|
763
|
-
/**
|
|
764
|
-
* ImageManager does three things:
|
|
765
|
-
*
|
|
766
|
-
* 1. Tracks requests for icon images from tile workers and sends responses when the requests are fulfilled.
|
|
767
|
-
* 2. Builds a texture atlas for pattern images.
|
|
768
|
-
* 3. Rerenders renderable images once per frame
|
|
769
|
-
*
|
|
770
|
-
* These are disparate responsibilities and should eventually be handled by different classes. When we implement
|
|
771
|
-
* data-driven support for `*-pattern`, we'll likely use per-bucket pattern atlases, and that would be a good time
|
|
772
|
-
* to refactor this.
|
|
763
|
+
* Owns every image of the style - the ones the sprites bring in as well as the ones added at
|
|
764
|
+
* runtime - and tracks requests for them from the tile workers, sending responses when the
|
|
765
|
+
* requests are fulfilled.
|
|
773
766
|
*/
|
|
774
767
|
var ImageManager = class extends Evented {
|
|
775
768
|
constructor() {
|
|
776
769
|
super();
|
|
777
770
|
this.images = {};
|
|
778
|
-
this.
|
|
779
|
-
this.callbackDispatchedThisFrame = {};
|
|
771
|
+
this.updateVersion = 0;
|
|
780
772
|
this.loaded = false;
|
|
781
773
|
this.requestors = [];
|
|
782
774
|
this.missingImageResolver = null;
|
|
783
|
-
this.
|
|
784
|
-
this.
|
|
785
|
-
|
|
786
|
-
height: 1
|
|
787
|
-
});
|
|
788
|
-
this.dirty = true;
|
|
775
|
+
this._spriteImagesIds = {};
|
|
776
|
+
this._imagesIds = null;
|
|
777
|
+
this._renderCallbacksDispatchedThisFrame = {};
|
|
789
778
|
}
|
|
790
779
|
destroy() {
|
|
791
|
-
if (this.atlasTexture) {
|
|
792
|
-
this.atlasTexture.destroy();
|
|
793
|
-
this.atlasTexture = null;
|
|
794
|
-
}
|
|
795
780
|
for (const id of Object.keys(this.images)) this.removeImage(id);
|
|
796
|
-
this.
|
|
797
|
-
this.atlasImage = new RGBAImage({
|
|
798
|
-
width: 1,
|
|
799
|
-
height: 1
|
|
800
|
-
});
|
|
801
|
-
this.dirty = true;
|
|
781
|
+
this._spriteImagesIds = {};
|
|
802
782
|
}
|
|
803
783
|
isLoaded() {
|
|
804
784
|
return this.loaded;
|
|
@@ -825,7 +805,11 @@ var ImageManager = class extends Evented {
|
|
|
825
805
|
}
|
|
826
806
|
addImage(id, image) {
|
|
827
807
|
if (this.images[id]) throw new Error(`Image id ${id} already exist, use updateImage instead`);
|
|
828
|
-
if (this._validate(id, image))
|
|
808
|
+
if (this._validate(id, image)) {
|
|
809
|
+
this.images[id] = image;
|
|
810
|
+
this._imagesIds = null;
|
|
811
|
+
if (image.isWebGLImage) this.updateImage(id, image, false);
|
|
812
|
+
}
|
|
829
813
|
}
|
|
830
814
|
_validate(id, image) {
|
|
831
815
|
let valid = true;
|
|
@@ -866,21 +850,97 @@ var ImageManager = class extends Evented {
|
|
|
866
850
|
if (content[2] < content[0]) return false;
|
|
867
851
|
return content[3] >= content[1];
|
|
868
852
|
}
|
|
853
|
+
/**
|
|
854
|
+
* Replaces an image that is already known under this id, bumping its version so that the
|
|
855
|
+
* atlases holding it notice.
|
|
856
|
+
*
|
|
857
|
+
* The old record is read directly rather than through {@link ImageManager.getImage}, which
|
|
858
|
+
* would force a synchronous decode of the sprite data of the very image being replaced. Its
|
|
859
|
+
* size therefore comes from whichever of the two the pixels are still in, since an image that
|
|
860
|
+
* came from a sprite and was never rendered has not been decoded yet, and its version is
|
|
861
|
+
* defaulted, since images start out without one.
|
|
862
|
+
*
|
|
863
|
+
* @param validate - whether to reject an image of a different size than the one it replaces
|
|
864
|
+
*/
|
|
869
865
|
updateImage(id, image, validate = true) {
|
|
870
|
-
const oldImage = this.
|
|
871
|
-
if (validate
|
|
872
|
-
|
|
866
|
+
const oldImage = this.images[id];
|
|
867
|
+
if (validate) {
|
|
868
|
+
const oldData = oldImage.data || oldImage.spriteData;
|
|
869
|
+
if (oldData.width !== image.data.width || oldData.height !== image.data.height) throw new Error(`size mismatch between old image (${oldData.width}x${oldData.height}) and new image (${image.data.width}x${image.data.height}).`);
|
|
870
|
+
}
|
|
871
|
+
image.version = (oldImage.version ?? 0) + 1;
|
|
873
872
|
this.images[id] = image;
|
|
874
|
-
this.
|
|
873
|
+
this.updateVersion++;
|
|
875
874
|
}
|
|
876
875
|
removeImage(id) {
|
|
877
876
|
const image = this.images[id];
|
|
877
|
+
if (!image) return;
|
|
878
878
|
delete this.images[id];
|
|
879
|
-
|
|
879
|
+
this._imagesIds = null;
|
|
880
880
|
if (image.userImage?.onRemove) image.userImage.onRemove();
|
|
881
881
|
}
|
|
882
|
+
/**
|
|
883
|
+
* @returns the ids of every image currently held, sprite images and runtime ones alike. The
|
|
884
|
+
* returned array is shared between callers and must not be modified.
|
|
885
|
+
*/
|
|
882
886
|
listImages() {
|
|
883
|
-
|
|
887
|
+
this._imagesIds ??= Object.keys(this.images);
|
|
888
|
+
return this._imagesIds;
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Images of the `default` sprite keep their plain id, the ones of any other sprite are
|
|
892
|
+
* namespaced by their sprite's id.
|
|
893
|
+
*/
|
|
894
|
+
_getSpriteImageId(spriteId, imageId) {
|
|
895
|
+
return spriteId === "default" ? imageId : `${spriteId}:${imageId}`;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Takes over the images of a single sprite: adds the new ones, updates the ones that are
|
|
899
|
+
* already known, and removes the ones that a previous load of this same sprite had brought in
|
|
900
|
+
* but that are not part of it anymore.
|
|
901
|
+
*
|
|
902
|
+
* @param spriteId - the id of the sprite the images belong to
|
|
903
|
+
* @param images - the sprite's images, keyed by their id within the sprite
|
|
904
|
+
* @returns the ids of the images that this sprite now provides, and the ids of the ones that
|
|
905
|
+
* were removed because they are no longer part of it
|
|
906
|
+
*/
|
|
907
|
+
setSpriteImages(spriteId, images) {
|
|
908
|
+
const previousIds = this._spriteImagesIds[spriteId] ?? [];
|
|
909
|
+
const loaded = [];
|
|
910
|
+
for (const id in images) {
|
|
911
|
+
const imageId = this._getSpriteImageId(spriteId, id);
|
|
912
|
+
loaded.push(imageId);
|
|
913
|
+
if (imageId in this.images) this.updateImage(imageId, images[id], false);
|
|
914
|
+
else this.addImage(imageId, images[id]);
|
|
915
|
+
}
|
|
916
|
+
const loadedIds = new Set(loaded);
|
|
917
|
+
const removed = previousIds.filter((imageId) => !loadedIds.has(imageId));
|
|
918
|
+
for (const imageId of removed) this.removeImage(imageId);
|
|
919
|
+
this._spriteImagesIds[spriteId] = loaded;
|
|
920
|
+
return {
|
|
921
|
+
loaded,
|
|
922
|
+
removed
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Removes all the images a single sprite has brought in.
|
|
927
|
+
* @returns the ids of the removed images
|
|
928
|
+
*/
|
|
929
|
+
removeSpriteImages(spriteId) {
|
|
930
|
+
const removed = this._spriteImagesIds[spriteId] ?? [];
|
|
931
|
+
for (const imageId of removed) this.removeImage(imageId);
|
|
932
|
+
delete this._spriteImagesIds[spriteId];
|
|
933
|
+
return removed;
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* Removes the images of every sprite, leaving the images added at runtime alone.
|
|
937
|
+
* @returns the ids of the removed images
|
|
938
|
+
*/
|
|
939
|
+
removeAllSpriteImages() {
|
|
940
|
+
const removed = Object.values(this._spriteImagesIds).flat();
|
|
941
|
+
for (const imageId of removed) this.removeImage(imageId);
|
|
942
|
+
this._spriteImagesIds = {};
|
|
943
|
+
return removed;
|
|
884
944
|
}
|
|
885
945
|
setMissingImageResolver(resolver) {
|
|
886
946
|
this.missingImageResolver = resolver;
|
|
@@ -901,7 +961,7 @@ var ImageManager = class extends Evented {
|
|
|
901
961
|
async _getImagesForIds(ids) {
|
|
902
962
|
const unresolvedIds = new Set(ids.filter((id) => !this.getImage(id)));
|
|
903
963
|
const resolver = this.missingImageResolver;
|
|
904
|
-
if (resolver) await Promise.
|
|
964
|
+
if (resolver) await Promise.allSettled(Array.from(unresolvedIds, (id) => resolver(id)));
|
|
905
965
|
const response = {};
|
|
906
966
|
for (const id of ids) {
|
|
907
967
|
const image = this.getImage(id);
|
|
@@ -917,7 +977,8 @@ var ImageManager = class extends Evented {
|
|
|
917
977
|
content: image.content,
|
|
918
978
|
textFitWidth: image.textFitWidth,
|
|
919
979
|
textFitHeight: image.textFitHeight,
|
|
920
|
-
hasRenderCallback: Boolean(image.userImage?.render)
|
|
980
|
+
hasRenderCallback: Boolean(image.userImage?.render),
|
|
981
|
+
isWebGLImage: image.isWebGLImage
|
|
921
982
|
};
|
|
922
983
|
}
|
|
923
984
|
}
|
|
@@ -927,57 +988,126 @@ var ImageManager = class extends Evented {
|
|
|
927
988
|
}
|
|
928
989
|
return response;
|
|
929
990
|
}
|
|
991
|
+
beginFrame() {
|
|
992
|
+
this._renderCallbacksDispatchedThisFrame = {};
|
|
993
|
+
}
|
|
994
|
+
/**
|
|
995
|
+
* Re-renders the images among `ids` that were added with a `render` callback (see
|
|
996
|
+
* `StyleImageInterface`), at most once per frame each.
|
|
997
|
+
*/
|
|
998
|
+
dispatchRenderCallbacks(ids) {
|
|
999
|
+
for (const id of ids) {
|
|
1000
|
+
if (this._renderCallbacksDispatchedThisFrame[id]) continue;
|
|
1001
|
+
this._renderCallbacksDispatchedThisFrame[id] = true;
|
|
1002
|
+
const image = this.getImage(id);
|
|
1003
|
+
if (!image) warnOnce(`Image with ID: "${id}" was not found`);
|
|
1004
|
+
if (renderStyleImage(image)) this.updateImage(id, image);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
cloneImages() {
|
|
1008
|
+
const clonedImages = {};
|
|
1009
|
+
for (const id in this.images) {
|
|
1010
|
+
const image = this.images[id];
|
|
1011
|
+
clonedImages[id] = {
|
|
1012
|
+
...image,
|
|
1013
|
+
data: image.data ? image.data.clone() : null
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
return clonedImages;
|
|
1017
|
+
}
|
|
1018
|
+
};
|
|
1019
|
+
//#endregion
|
|
1020
|
+
//#region src/render/pattern_atlas.ts
|
|
1021
|
+
/**
|
|
1022
|
+
* When copied into the atlas texture, pattern images are padded by one pixel on each side with a
|
|
1023
|
+
* copy of the image data wrapped from the opposite side. This ensures the correct behavior of
|
|
1024
|
+
* GL_LINEAR texture sampling mode.
|
|
1025
|
+
*/
|
|
1026
|
+
const PADDING = 1;
|
|
1027
|
+
/**
|
|
1028
|
+
* A texture atlas of the pattern images that are drawn without a tile's own {@link ImageAtlas},
|
|
1029
|
+
* i.e. `background-pattern`. Entries are packed on demand and re-packed whenever one of them is
|
|
1030
|
+
* added or changes, which is rare enough for the repacking cost not to matter.
|
|
1031
|
+
*/
|
|
1032
|
+
var PatternAtlas = class {
|
|
1033
|
+
constructor(imageManager) {
|
|
1034
|
+
this._imageManager = imageManager;
|
|
1035
|
+
this._entries = {};
|
|
1036
|
+
this._image = new RGBAImage({
|
|
1037
|
+
width: 1,
|
|
1038
|
+
height: 1
|
|
1039
|
+
});
|
|
1040
|
+
this._dirty = true;
|
|
1041
|
+
}
|
|
1042
|
+
destroy() {
|
|
1043
|
+
if (this._texture) {
|
|
1044
|
+
this._texture.destroy();
|
|
1045
|
+
this._texture = null;
|
|
1046
|
+
}
|
|
1047
|
+
this._entries = {};
|
|
1048
|
+
this._image = new RGBAImage({
|
|
1049
|
+
width: 1,
|
|
1050
|
+
height: 1
|
|
1051
|
+
});
|
|
1052
|
+
this._dirty = true;
|
|
1053
|
+
}
|
|
930
1054
|
getPixelSize() {
|
|
931
|
-
const { width, height } = this.
|
|
1055
|
+
const { width, height } = this._image;
|
|
932
1056
|
return {
|
|
933
1057
|
width,
|
|
934
1058
|
height
|
|
935
1059
|
};
|
|
936
1060
|
}
|
|
1061
|
+
/**
|
|
1062
|
+
* @returns the position of the pattern within the atlas, or `null` if there is no such image
|
|
1063
|
+
*/
|
|
937
1064
|
getPattern(id) {
|
|
938
|
-
const
|
|
939
|
-
const image = this.getImage(id);
|
|
1065
|
+
const image = this._imageManager.getImage(id);
|
|
940
1066
|
if (!image) return null;
|
|
941
|
-
|
|
942
|
-
if (
|
|
1067
|
+
const entry = this._entries[id];
|
|
1068
|
+
if (entry?.image !== image) {
|
|
943
1069
|
const bin = {
|
|
944
1070
|
w: image.data.width + 2,
|
|
945
1071
|
h: image.data.height + 2,
|
|
946
1072
|
x: 0,
|
|
947
1073
|
y: 0
|
|
948
1074
|
};
|
|
949
|
-
|
|
950
|
-
this.patterns[id] = {
|
|
1075
|
+
this._entries[id] = {
|
|
951
1076
|
bin,
|
|
952
|
-
position
|
|
1077
|
+
position: new ImagePosition(bin, image),
|
|
1078
|
+
image
|
|
953
1079
|
};
|
|
954
|
-
} else
|
|
955
|
-
|
|
956
|
-
|
|
1080
|
+
} else if (entry.position.version !== image.version) entry.position.version = image.version;
|
|
1081
|
+
else return entry.position;
|
|
1082
|
+
this._update();
|
|
1083
|
+
return this._entries[id].position;
|
|
957
1084
|
}
|
|
958
1085
|
bind(context) {
|
|
959
1086
|
const gl = context.gl;
|
|
960
|
-
if (!this.
|
|
961
|
-
|
|
962
|
-
this.
|
|
963
|
-
|
|
1087
|
+
if (!this._texture) {
|
|
1088
|
+
this._texture = new Texture(context, this._image, gl.RGBA);
|
|
1089
|
+
this._dirty = false;
|
|
1090
|
+
} else if (this._dirty) {
|
|
1091
|
+
this._texture.update(this._image);
|
|
1092
|
+
this._dirty = false;
|
|
964
1093
|
}
|
|
965
|
-
this.
|
|
1094
|
+
this._texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
|
|
966
1095
|
}
|
|
967
|
-
|
|
1096
|
+
_update() {
|
|
1097
|
+
for (const id in this._entries) if (!this._imageManager.getImage(id)) delete this._entries[id];
|
|
968
1098
|
const bins = [];
|
|
969
|
-
for (const id in this.
|
|
1099
|
+
for (const id in this._entries) bins.push(this._entries[id].bin);
|
|
970
1100
|
const { w, h } = potpack(bins);
|
|
971
|
-
const dst = this.
|
|
1101
|
+
const dst = this._image;
|
|
972
1102
|
dst.resize({
|
|
973
1103
|
width: w || 1,
|
|
974
1104
|
height: h || 1
|
|
975
1105
|
});
|
|
976
|
-
for (const id in this.
|
|
977
|
-
const { bin } = this.
|
|
978
|
-
const x = bin.x +
|
|
979
|
-
const y = bin.y +
|
|
980
|
-
const src = this.
|
|
1106
|
+
for (const id in this._entries) {
|
|
1107
|
+
const { bin } = this._entries[id];
|
|
1108
|
+
const x = bin.x + PADDING;
|
|
1109
|
+
const y = bin.y + PADDING;
|
|
1110
|
+
const src = this._entries[id].image.data;
|
|
981
1111
|
const w = src.width;
|
|
982
1112
|
const h = src.height;
|
|
983
1113
|
RGBAImage.copy(src, dst, {
|
|
@@ -1031,30 +1161,7 @@ var ImageManager = class extends Evented {
|
|
|
1031
1161
|
height: h
|
|
1032
1162
|
});
|
|
1033
1163
|
}
|
|
1034
|
-
this.
|
|
1035
|
-
}
|
|
1036
|
-
beginFrame() {
|
|
1037
|
-
this.callbackDispatchedThisFrame = {};
|
|
1038
|
-
}
|
|
1039
|
-
dispatchRenderCallbacks(ids) {
|
|
1040
|
-
for (const id of ids) {
|
|
1041
|
-
if (this.callbackDispatchedThisFrame[id]) continue;
|
|
1042
|
-
this.callbackDispatchedThisFrame[id] = true;
|
|
1043
|
-
const image = this.getImage(id);
|
|
1044
|
-
if (!image) warnOnce(`Image with ID: "${id}" was not found`);
|
|
1045
|
-
if (renderStyleImage(image)) this.updateImage(id, image);
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
cloneImages() {
|
|
1049
|
-
const clonedImages = {};
|
|
1050
|
-
for (const id in this.images) {
|
|
1051
|
-
const image = this.images[id];
|
|
1052
|
-
clonedImages[id] = {
|
|
1053
|
-
...image,
|
|
1054
|
-
data: image.data ? image.data.clone() : null
|
|
1055
|
-
};
|
|
1056
|
-
}
|
|
1057
|
-
return clonedImages;
|
|
1164
|
+
this._dirty = true;
|
|
1058
1165
|
}
|
|
1059
1166
|
};
|
|
1060
1167
|
//#endregion
|
|
@@ -1814,10 +1921,12 @@ function prewarm() {
|
|
|
1814
1921
|
*/
|
|
1815
1922
|
function clearPrewarmedResources() {
|
|
1816
1923
|
const pool = globalWorkerPool;
|
|
1817
|
-
if (pool)
|
|
1818
|
-
pool.
|
|
1819
|
-
|
|
1820
|
-
|
|
1924
|
+
if (pool) {
|
|
1925
|
+
if (pool.isPreloaded() && pool.numActive() === 1) {
|
|
1926
|
+
pool.release(PRELOAD_POOL_ID);
|
|
1927
|
+
globalWorkerPool = null;
|
|
1928
|
+
} else console.warn("Could not clear WebWorkers since there are active Map instances that still reference it. The pre-warmed WebWorker pool can only be cleared when all map instances have been removed with map.remove()");
|
|
1929
|
+
}
|
|
1821
1930
|
}
|
|
1822
1931
|
//#endregion
|
|
1823
1932
|
//#region src/util/dispatcher.ts
|
|
@@ -2090,8 +2199,10 @@ var LngLatBounds = class LngLatBounds {
|
|
|
2090
2199
|
*/
|
|
2091
2200
|
constructor(sw, ne) {
|
|
2092
2201
|
if (!sw) {} else if (ne) this.setSouthWest(sw).setNorthEast(ne);
|
|
2093
|
-
else if (Array.isArray(sw))
|
|
2094
|
-
|
|
2202
|
+
else if (Array.isArray(sw)) {
|
|
2203
|
+
if (sw.length === 4) this.setSouthWest([sw[0], sw[1]]).setNorthEast([sw[2], sw[3]]);
|
|
2204
|
+
else this.setSouthWest(sw[0]).setNorthEast(sw[1]);
|
|
2205
|
+
}
|
|
2095
2206
|
}
|
|
2096
2207
|
/**
|
|
2097
2208
|
* Set the northeast corner of the bounding box
|
|
@@ -2127,14 +2238,15 @@ var LngLatBounds = class LngLatBounds {
|
|
|
2127
2238
|
ne2 = obj._ne;
|
|
2128
2239
|
if (!sw2 || !ne2) return this;
|
|
2129
2240
|
} else {
|
|
2130
|
-
if (Array.isArray(obj))
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2241
|
+
if (Array.isArray(obj)) {
|
|
2242
|
+
if (obj.length === 4 || obj.every(Array.isArray)) {
|
|
2243
|
+
const lngLatBoundsObj = obj;
|
|
2244
|
+
return this.extend(LngLatBounds.convert(lngLatBoundsObj));
|
|
2245
|
+
} else {
|
|
2246
|
+
const lngLatObj = obj;
|
|
2247
|
+
return this.extend(LngLat.convert(lngLatObj));
|
|
2248
|
+
}
|
|
2249
|
+
} else if (obj && ("lng" in obj || "lon" in obj) && "lat" in obj) return this.extend(LngLat.convert(obj));
|
|
2138
2250
|
return this;
|
|
2139
2251
|
}
|
|
2140
2252
|
if (!sw && !ne) {
|
|
@@ -2781,10 +2893,9 @@ var RasterTileSource = class extends Evented {
|
|
|
2781
2893
|
const url = tile.tileID.canonical.url(this.tiles, this.map.getPixelRatio(), this.scheme);
|
|
2782
2894
|
const premultiply = this._premultiplyAlpha;
|
|
2783
2895
|
const imageBitmapOptions = premultiply ? void 0 : { premultiplyAlpha: "none" };
|
|
2784
|
-
const request = await this.map._requestManager.transformRequest(url, "Tile");
|
|
2785
2896
|
tile.abortController = new AbortController();
|
|
2786
2897
|
try {
|
|
2787
|
-
const response = await ImageRequest.
|
|
2898
|
+
const response = await ImageRequest.transformAndGetImage(this.map._requestManager, url, "Tile", tile.abortController, this.map._refreshExpiredTiles, imageBitmapOptions);
|
|
2788
2899
|
delete tile.abortController;
|
|
2789
2900
|
if (tile.aborted) {
|
|
2790
2901
|
tile.state = "unloaded";
|
|
@@ -2866,11 +2977,10 @@ var RasterDEMTileSource = class extends RasterTileSource {
|
|
|
2866
2977
|
}
|
|
2867
2978
|
async loadTile(tile) {
|
|
2868
2979
|
const url = tile.tileID.canonical.url(this.tiles, this.map.getPixelRatio(), this.scheme);
|
|
2869
|
-
const request = await this.map._requestManager.transformRequest(url, "Tile");
|
|
2870
2980
|
tile.neighboringTiles = this._getNeighboringTiles(tile.tileID);
|
|
2871
2981
|
tile.abortController = new AbortController();
|
|
2872
2982
|
try {
|
|
2873
|
-
const response = await ImageRequest.
|
|
2983
|
+
const response = await ImageRequest.transformAndGetImage(this.map._requestManager, url, "Tile", tile.abortController, this.map._refreshExpiredTiles, { colorSpaceConversion: "none" });
|
|
2874
2984
|
delete tile.abortController;
|
|
2875
2985
|
if (tile.aborted) {
|
|
2876
2986
|
tile.state = "unloaded";
|
|
@@ -3697,6 +3807,76 @@ var GeoJSONSource = class extends Evented {
|
|
|
3697
3807
|
}
|
|
3698
3808
|
};
|
|
3699
3809
|
//#endregion
|
|
3810
|
+
//#region src/webgl/program/raster_program.ts
|
|
3811
|
+
/**
|
|
3812
|
+
* Affine texture coordinates represented as a homogeneous transform.
|
|
3813
|
+
*/
|
|
3814
|
+
const identityPerspectiveTransform = [
|
|
3815
|
+
0,
|
|
3816
|
+
0,
|
|
3817
|
+
1
|
|
3818
|
+
];
|
|
3819
|
+
const rasterUniforms = (context, locations) => ({
|
|
3820
|
+
"u_tl_parent": new Uniform2f(context, locations.u_tl_parent),
|
|
3821
|
+
"u_scale_parent": new Uniform1f(context, locations.u_scale_parent),
|
|
3822
|
+
"u_buffer_scale": new Uniform1f(context, locations.u_buffer_scale),
|
|
3823
|
+
"u_perspective_transform": new Uniform3f(context, locations.u_perspective_transform),
|
|
3824
|
+
"u_fade_t": new Uniform1f(context, locations.u_fade_t),
|
|
3825
|
+
"u_opacity": new Uniform1f(context, locations.u_opacity),
|
|
3826
|
+
"u_image0": new Uniform1i(context, locations.u_image0),
|
|
3827
|
+
"u_image1": new Uniform1i(context, locations.u_image1),
|
|
3828
|
+
"u_brightness_low": new Uniform1f(context, locations.u_brightness_low),
|
|
3829
|
+
"u_brightness_high": new Uniform1f(context, locations.u_brightness_high),
|
|
3830
|
+
"u_saturation_factor": new Uniform1f(context, locations.u_saturation_factor),
|
|
3831
|
+
"u_contrast_factor": new Uniform1f(context, locations.u_contrast_factor),
|
|
3832
|
+
"u_spin_weights": new Uniform3f(context, locations.u_spin_weights),
|
|
3833
|
+
"u_coords_top": new Uniform4f(context, locations.u_coords_top),
|
|
3834
|
+
"u_coords_bottom": new Uniform4f(context, locations.u_coords_bottom)
|
|
3835
|
+
});
|
|
3836
|
+
const rasterUniformValues = (parentTL, parentScaleBy, fade, layer, cornerCoords, perspectiveTransform) => ({
|
|
3837
|
+
"u_tl_parent": parentTL,
|
|
3838
|
+
"u_scale_parent": parentScaleBy,
|
|
3839
|
+
"u_buffer_scale": 1,
|
|
3840
|
+
"u_perspective_transform": perspectiveTransform,
|
|
3841
|
+
"u_fade_t": fade.mix,
|
|
3842
|
+
"u_opacity": fade.opacity * layer.paint.get("raster-opacity"),
|
|
3843
|
+
"u_image0": 0,
|
|
3844
|
+
"u_image1": 1,
|
|
3845
|
+
"u_brightness_low": layer.paint.get("raster-brightness-min"),
|
|
3846
|
+
"u_brightness_high": layer.paint.get("raster-brightness-max"),
|
|
3847
|
+
"u_saturation_factor": saturationFactor(layer.paint.get("raster-saturation")),
|
|
3848
|
+
"u_contrast_factor": contrastFactor(layer.paint.get("raster-contrast")),
|
|
3849
|
+
"u_spin_weights": spinWeights(layer.paint.get("raster-hue-rotate")),
|
|
3850
|
+
"u_coords_top": [
|
|
3851
|
+
cornerCoords[0].x,
|
|
3852
|
+
cornerCoords[0].y,
|
|
3853
|
+
cornerCoords[1].x,
|
|
3854
|
+
cornerCoords[1].y
|
|
3855
|
+
],
|
|
3856
|
+
"u_coords_bottom": [
|
|
3857
|
+
cornerCoords[3].x,
|
|
3858
|
+
cornerCoords[3].y,
|
|
3859
|
+
cornerCoords[2].x,
|
|
3860
|
+
cornerCoords[2].y
|
|
3861
|
+
]
|
|
3862
|
+
});
|
|
3863
|
+
function spinWeights(angle) {
|
|
3864
|
+
angle *= Math.PI / 180;
|
|
3865
|
+
const s = Math.sin(angle);
|
|
3866
|
+
const c = Math.cos(angle);
|
|
3867
|
+
return [
|
|
3868
|
+
(2 * c + 1) / 3,
|
|
3869
|
+
(-Math.sqrt(3) * s - c + 1) / 3,
|
|
3870
|
+
(Math.sqrt(3) * s - c + 1) / 3
|
|
3871
|
+
];
|
|
3872
|
+
}
|
|
3873
|
+
function contrastFactor(contrast) {
|
|
3874
|
+
return contrast > 0 ? 1 / (1 - contrast) : 1 + contrast;
|
|
3875
|
+
}
|
|
3876
|
+
function saturationFactor(saturation) {
|
|
3877
|
+
return saturation > 0 ? 1 - 1 / (1.001 - saturation) : -saturation;
|
|
3878
|
+
}
|
|
3879
|
+
//#endregion
|
|
3700
3880
|
//#region src/source/image_source.ts
|
|
3701
3881
|
/**
|
|
3702
3882
|
* A data source containing an image.
|
|
@@ -3749,7 +3929,9 @@ var ImageSource = class extends Evented {
|
|
|
3749
3929
|
/** @internal */
|
|
3750
3930
|
constructor(id, options, dispatcher, eventedParent) {
|
|
3751
3931
|
super();
|
|
3932
|
+
this.perspectiveTransform = identityPerspectiveTransform;
|
|
3752
3933
|
this.flippedWindingOrder = false;
|
|
3934
|
+
this._imageDirty = false;
|
|
3753
3935
|
this.id = id;
|
|
3754
3936
|
this.dispatcher = dispatcher;
|
|
3755
3937
|
this.coordinates = options.coordinates;
|
|
@@ -3766,21 +3948,21 @@ var ImageSource = class extends Evented {
|
|
|
3766
3948
|
this._loaded = false;
|
|
3767
3949
|
this.fire(new MapSourceDataEvent("dataloading"));
|
|
3768
3950
|
this.url = this.options.url;
|
|
3769
|
-
|
|
3770
|
-
this._request = new AbortController();
|
|
3951
|
+
this._abortController = new AbortController();
|
|
3771
3952
|
try {
|
|
3772
|
-
const image = await ImageRequest.
|
|
3773
|
-
this.
|
|
3953
|
+
const image = await ImageRequest.transformAndGetImage(this.map._requestManager, this.url, "Image", this._abortController);
|
|
3954
|
+
this._abortController = null;
|
|
3774
3955
|
this._loaded = true;
|
|
3775
3956
|
if (image?.data) {
|
|
3776
|
-
this.image
|
|
3957
|
+
this._setImage(image.data);
|
|
3777
3958
|
if (newCoordinates) this.coordinates = newCoordinates;
|
|
3778
3959
|
this._finishLoading();
|
|
3779
3960
|
}
|
|
3780
3961
|
} catch (err) {
|
|
3781
|
-
|
|
3962
|
+
if (isAbortError(err)) return;
|
|
3963
|
+
this._abortController = null;
|
|
3782
3964
|
this._loaded = true;
|
|
3783
|
-
|
|
3965
|
+
this.fire(new ErrorEvent(ensureError(err)));
|
|
3784
3966
|
}
|
|
3785
3967
|
}
|
|
3786
3968
|
loaded() {
|
|
@@ -3797,23 +3979,32 @@ var ImageSource = class extends Evented {
|
|
|
3797
3979
|
* @param options - The options object.
|
|
3798
3980
|
*/
|
|
3799
3981
|
updateImage(options) {
|
|
3800
|
-
if (this.
|
|
3801
|
-
this.
|
|
3802
|
-
this.
|
|
3982
|
+
if (this._abortController) {
|
|
3983
|
+
this._abortController.abort();
|
|
3984
|
+
this._abortController = null;
|
|
3803
3985
|
}
|
|
3804
3986
|
if ("image" in options) {
|
|
3805
3987
|
this._loaded = true;
|
|
3806
|
-
this.
|
|
3988
|
+
this._setImage(options.image);
|
|
3807
3989
|
if (options.coordinates) this.coordinates = options.coordinates;
|
|
3808
|
-
this.texture = null;
|
|
3809
3990
|
this._finishLoading();
|
|
3810
3991
|
return this;
|
|
3811
3992
|
}
|
|
3812
3993
|
if (!options.url) return this;
|
|
3813
3994
|
this.options.url = options.url;
|
|
3814
|
-
this.load(options.coordinates)
|
|
3995
|
+
this.load(options.coordinates);
|
|
3815
3996
|
return this;
|
|
3816
3997
|
}
|
|
3998
|
+
/** Loaded tiles hold `this.texture`, so the wrapper has to outlive the images in it. */
|
|
3999
|
+
_setImage(image) {
|
|
4000
|
+
this.image = image;
|
|
4001
|
+
this._imageDirty = true;
|
|
4002
|
+
}
|
|
4003
|
+
/** Teardown only: dropping the reference alone leaves the allocation to the GC. */
|
|
4004
|
+
_disposeTexture() {
|
|
4005
|
+
this.texture?.destroy();
|
|
4006
|
+
this.texture = null;
|
|
4007
|
+
}
|
|
3817
4008
|
_finishLoading() {
|
|
3818
4009
|
if (this.map) {
|
|
3819
4010
|
this.setCoordinates(this.coordinates);
|
|
@@ -3825,10 +4016,13 @@ var ImageSource = class extends Evented {
|
|
|
3825
4016
|
this.load();
|
|
3826
4017
|
}
|
|
3827
4018
|
onRemove() {
|
|
3828
|
-
if (this.
|
|
3829
|
-
this.
|
|
3830
|
-
this.
|
|
4019
|
+
if (this._abortController) {
|
|
4020
|
+
this._abortController.abort();
|
|
4021
|
+
this._abortController = null;
|
|
3831
4022
|
}
|
|
4023
|
+
this._disposeTexture();
|
|
4024
|
+
this.image = null;
|
|
4025
|
+
this.tiles = {};
|
|
3832
4026
|
}
|
|
3833
4027
|
/**
|
|
3834
4028
|
* Sets the image's coordinates and re-renders the map.
|
|
@@ -3845,6 +4039,7 @@ var ImageSource = class extends Evented {
|
|
|
3845
4039
|
this.terrainTileRanges = this._getOverlappingTileRanges(cornerCoords);
|
|
3846
4040
|
this.minzoom = this.maxzoom = this.tileID.z;
|
|
3847
4041
|
this.tileCoords = cornerCoords.map((coord) => this.tileID.getTilePoint(coord)._round());
|
|
4042
|
+
this.perspectiveTransform = calculateRasterPerspectiveTransform(this.tileCoords);
|
|
3848
4043
|
this.flippedWindingOrder = hasWrongWindingOrder(this.tileCoords);
|
|
3849
4044
|
this.fire(new MapSourceDataEvent("data", { sourceDataType: "content" }));
|
|
3850
4045
|
return this;
|
|
@@ -3856,7 +4051,11 @@ var ImageSource = class extends Evented {
|
|
|
3856
4051
|
if (!this.texture) {
|
|
3857
4052
|
this.texture = new Texture(context, this.image, gl.RGBA);
|
|
3858
4053
|
this.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
|
|
4054
|
+
} else if (this._imageDirty) {
|
|
4055
|
+
this.texture.update(this.image);
|
|
4056
|
+
this.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
|
|
3859
4057
|
}
|
|
4058
|
+
this._imageDirty = false;
|
|
3860
4059
|
let newTilesLoaded = false;
|
|
3861
4060
|
for (const w in this.tiles) {
|
|
3862
4061
|
const tile = this.tiles[w];
|
|
@@ -3938,6 +4137,83 @@ function hasWrongWindingOrder(coords) {
|
|
|
3938
4137
|
const e1x = coords[2].x - coords[0].x;
|
|
3939
4138
|
return e0x * (coords[2].y - coords[0].y) - e0y * e1x < 0;
|
|
3940
4139
|
}
|
|
4140
|
+
const perspectiveEpsilon = Number.EPSILON;
|
|
4141
|
+
const perspectiveErrorFactor = 8;
|
|
4142
|
+
/**
|
|
4143
|
+
* Calculates the inverse-homography denominator used to sample non-affine
|
|
4144
|
+
* image-source texture coordinates. Image source tile coordinates are rounded
|
|
4145
|
+
* to integers before this runs, so singularity checks use exact zero or
|
|
4146
|
+
* Number.EPSILON scaled to the corner denominators.
|
|
4147
|
+
*
|
|
4148
|
+
* Based on Paul S. Heckbert, "Fundamentals of Texture Mapping and Image
|
|
4149
|
+
* Warping", UCB/CSD-89-516, 1989, section 2.2.3 and appendix A.2.
|
|
4150
|
+
*
|
|
4151
|
+
* @see https://www2.eecs.berkeley.edu/Pubs/TechRpts/1989/5504.html
|
|
4152
|
+
* @see https://www.cs.cmu.edu/~ph/texfund/texfund.pdf
|
|
4153
|
+
*/
|
|
4154
|
+
function calculateRasterPerspectiveTransform(cornerCoords) {
|
|
4155
|
+
if (isParallelogram(cornerCoords)) return identityPerspectiveTransform;
|
|
4156
|
+
const [topLeft, topRight, bottomRight, bottomLeft] = cornerCoords;
|
|
4157
|
+
const sx = topLeft.x - topRight.x + bottomRight.x - bottomLeft.x;
|
|
4158
|
+
const sy = topLeft.y - topRight.y + bottomRight.y - bottomLeft.y;
|
|
4159
|
+
const dx1 = topRight.x - bottomRight.x;
|
|
4160
|
+
const dy1 = topRight.y - bottomRight.y;
|
|
4161
|
+
const dx2 = bottomLeft.x - bottomRight.x;
|
|
4162
|
+
const dy2 = bottomLeft.y - bottomRight.y;
|
|
4163
|
+
const determinant$1 = determinant([
|
|
4164
|
+
dx1,
|
|
4165
|
+
dy1,
|
|
4166
|
+
dx2,
|
|
4167
|
+
dy2
|
|
4168
|
+
]);
|
|
4169
|
+
if (Math.abs(determinant$1) < perspectiveEpsilon) return identityPerspectiveTransform;
|
|
4170
|
+
const perspectiveX = (sx * dy2 - dx2 * sy) / determinant$1;
|
|
4171
|
+
const perspectiveY = (dx1 * sy - sx * dy1) / determinant$1;
|
|
4172
|
+
const forwardDenominators = [
|
|
4173
|
+
1,
|
|
4174
|
+
1 + perspectiveX,
|
|
4175
|
+
1 + perspectiveX + perspectiveY,
|
|
4176
|
+
1 + perspectiveY
|
|
4177
|
+
];
|
|
4178
|
+
const forwardDenominatorScale = Math.max(...forwardDenominators.map((value) => Math.abs(value)));
|
|
4179
|
+
const hasInvalidForwardDenominator = forwardDenominators.some((value) => !Number.isFinite(value) || value <= perspectiveErrorFactor * perspectiveEpsilon * forwardDenominatorScale);
|
|
4180
|
+
if (!Number.isFinite(forwardDenominatorScale) || forwardDenominatorScale === 0 || hasInvalidForwardDenominator) return identityPerspectiveTransform;
|
|
4181
|
+
const a = topRight.x - topLeft.x + perspectiveX * topRight.x;
|
|
4182
|
+
const b = bottomLeft.x - topLeft.x + perspectiveY * bottomLeft.x;
|
|
4183
|
+
const d = topRight.y - topLeft.y + perspectiveX * topRight.y;
|
|
4184
|
+
const e = bottomLeft.y - topLeft.y + perspectiveY * bottomLeft.y;
|
|
4185
|
+
const inverseDenominator = [
|
|
4186
|
+
0,
|
|
4187
|
+
0,
|
|
4188
|
+
0
|
|
4189
|
+
];
|
|
4190
|
+
cross(inverseDenominator, [
|
|
4191
|
+
a,
|
|
4192
|
+
d,
|
|
4193
|
+
perspectiveX
|
|
4194
|
+
], [
|
|
4195
|
+
b,
|
|
4196
|
+
e,
|
|
4197
|
+
perspectiveY
|
|
4198
|
+
]);
|
|
4199
|
+
const normalizationScale = Math.max(...inverseDenominator.map((value) => Math.abs(value)));
|
|
4200
|
+
const cornerDenominators = cornerCoords.map(({ x, y }) => dot(inverseDenominator, [
|
|
4201
|
+
x,
|
|
4202
|
+
y,
|
|
4203
|
+
1
|
|
4204
|
+
]));
|
|
4205
|
+
const cornerDenominatorErrors = cornerCoords.map(({ x, y }) => perspectiveErrorFactor * perspectiveEpsilon * (Math.abs(inverseDenominator[0] * x) + Math.abs(inverseDenominator[1] * y) + Math.abs(inverseDenominator[2])));
|
|
4206
|
+
const denominatorScale = Math.max(...cornerDenominators.map((value) => Math.abs(value)));
|
|
4207
|
+
const denominatorSign = Math.sign(cornerDenominators[0]);
|
|
4208
|
+
const hasInvalidDenominator = cornerDenominators.some((value, index) => !Number.isFinite(value) || Math.abs(value) <= Math.max(perspectiveEpsilon * denominatorScale, cornerDenominatorErrors[index]) || Math.sign(value) !== denominatorSign);
|
|
4209
|
+
if (!Number.isFinite(normalizationScale) || normalizationScale === 0 || !Number.isFinite(denominatorScale) || denominatorScale === 0 || hasInvalidDenominator) return identityPerspectiveTransform;
|
|
4210
|
+
const transform = inverseDenominator.map((value) => value / normalizationScale);
|
|
4211
|
+
return transform.every(Number.isFinite) ? transform : identityPerspectiveTransform;
|
|
4212
|
+
}
|
|
4213
|
+
function isParallelogram(cornerCoords) {
|
|
4214
|
+
const [tl, tr, br, bl] = cornerCoords;
|
|
4215
|
+
return Math.abs(tl.x + br.x - tr.x - bl.x) < perspectiveEpsilon && Math.abs(tl.y + br.y - tr.y - bl.y) < perspectiveEpsilon;
|
|
4216
|
+
}
|
|
3941
4217
|
//#endregion
|
|
3942
4218
|
//#region src/source/video_source.ts
|
|
3943
4219
|
/**
|
|
@@ -4176,7 +4452,8 @@ var CanvasSource = class extends ImageSource {
|
|
|
4176
4452
|
}
|
|
4177
4453
|
}
|
|
4178
4454
|
onRemove() {
|
|
4179
|
-
this.
|
|
4455
|
+
this._playing = false;
|
|
4456
|
+
super.onRemove();
|
|
4180
4457
|
}
|
|
4181
4458
|
prepare() {
|
|
4182
4459
|
let resize = false;
|
|
@@ -4319,11 +4596,12 @@ var RTLMainThreadPlugin = class extends Evented {
|
|
|
4319
4596
|
if (this.url) throw new Error("setRTLTextPlugin cannot be called multiple times.");
|
|
4320
4597
|
this.url = browser.resolveURL(url);
|
|
4321
4598
|
if (!this.url) throw new Error(`requested url ${url} is invalid`);
|
|
4322
|
-
if (this.status === "unavailable")
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4599
|
+
if (this.status === "unavailable") {
|
|
4600
|
+
if (deferred) {
|
|
4601
|
+
this.status = "deferred";
|
|
4602
|
+
this._syncState(this.status);
|
|
4603
|
+
} else return this._requestImport();
|
|
4604
|
+
} else if (this.status === "requested") return this._requestImport();
|
|
4327
4605
|
}
|
|
4328
4606
|
/** Send a message to worker which will import the RTL plugin script */
|
|
4329
4607
|
async _requestImport() {
|
|
@@ -4604,8 +4882,10 @@ var Tile = class {
|
|
|
4604
4882
|
}
|
|
4605
4883
|
}
|
|
4606
4884
|
getExpiryTimeout() {
|
|
4607
|
-
if (this.expirationTime)
|
|
4608
|
-
|
|
4885
|
+
if (this.expirationTime) {
|
|
4886
|
+
if (this.expiredRequestCount) return 1e3 * (1 << Math.min(this.expiredRequestCount - 1, 31));
|
|
4887
|
+
else return Math.min(this.expirationTime - (/* @__PURE__ */ new Date()).getTime(), Math.pow(2, 31) - 1);
|
|
4888
|
+
}
|
|
4609
4889
|
}
|
|
4610
4890
|
setFeatureState(states, painter, revision) {
|
|
4611
4891
|
if (!this.latestFeatureIndex?.rawTileData || Object.keys(states).length === 0) return;
|
|
@@ -4702,11 +4982,12 @@ var SourceFeatureState = class {
|
|
|
4702
4982
|
this.deletedStates[sourceLayer][feature] ||= {};
|
|
4703
4983
|
this.deletedStates[sourceLayer][feature][key] = null;
|
|
4704
4984
|
}
|
|
4705
|
-
} else if (featureId !== void 0)
|
|
4706
|
-
this.
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4985
|
+
} else if (featureId !== void 0) {
|
|
4986
|
+
if (this.stateChanges[sourceLayer]?.[feature]) {
|
|
4987
|
+
this.deletedStates[sourceLayer][feature] = {};
|
|
4988
|
+
for (key in this.stateChanges[sourceLayer][feature]) this.deletedStates[sourceLayer][feature][key] = null;
|
|
4989
|
+
} else this.deletedStates[sourceLayer][feature] = null;
|
|
4990
|
+
} else this.deletedStates[sourceLayer] = null;
|
|
4710
4991
|
}
|
|
4711
4992
|
getState(sourceLayer, featureId) {
|
|
4712
4993
|
const feature = String(featureId);
|
|
@@ -4960,12 +5241,6 @@ function coveringTiles(transform, options) {
|
|
|
4960
5241
|
return result.sort((a, b) => a.distanceSq - b.distanceSq).map((a) => a.tileID);
|
|
4961
5242
|
}
|
|
4962
5243
|
//#endregion
|
|
4963
|
-
//#region src/data/extent_bounds.ts
|
|
4964
|
-
/**
|
|
4965
|
-
* The bounding box covering the entire extent of a tile.
|
|
4966
|
-
*/
|
|
4967
|
-
const EXTENT_BOUNDS = Bounds.fromPoints([new Point(0, 0), new Point(EXTENT, EXTENT)]);
|
|
4968
|
-
//#endregion
|
|
4969
5244
|
//#region src/tile/tile_manager_raster.ts
|
|
4970
5245
|
function isRasterType(type) {
|
|
4971
5246
|
return type === "raster" || type === "image" || type === "video";
|
|
@@ -5283,10 +5558,10 @@ var TileManager = class TileManager extends Evented {
|
|
|
5283
5558
|
if (shouldReload) this.reload();
|
|
5284
5559
|
if (this.transform) this.update(this.transform, this.terrain);
|
|
5285
5560
|
}
|
|
5286
|
-
async _loadTile(tile, id, state) {
|
|
5561
|
+
async _loadTile(tile, id, state, hadData) {
|
|
5287
5562
|
try {
|
|
5288
5563
|
const result = await this._source.loadTile(tile);
|
|
5289
|
-
this._tileLoaded(tile, id, state, result);
|
|
5564
|
+
this._tileLoaded(tile, id, state, hadData, result);
|
|
5290
5565
|
} catch (err) {
|
|
5291
5566
|
tile.state = "errored";
|
|
5292
5567
|
if (err.status !== 404) this._source.fire(new ErrorEvent(ensureError(err), { tile }));
|
|
@@ -5352,12 +5627,15 @@ var TileManager = class TileManager extends Evented {
|
|
|
5352
5627
|
async _reloadTile(id, state) {
|
|
5353
5628
|
const tile = this._inViewTiles.getTileById(id);
|
|
5354
5629
|
if (!tile) return;
|
|
5630
|
+
const hadData = tile.hasData();
|
|
5355
5631
|
if (tile.state !== "loading") tile.state = state;
|
|
5356
|
-
await this._loadTile(tile, id, state);
|
|
5632
|
+
await this._loadTile(tile, id, state, hadData);
|
|
5357
5633
|
}
|
|
5358
|
-
_tileLoaded(tile, id, previousState, result) {
|
|
5359
|
-
|
|
5360
|
-
|
|
5634
|
+
_tileLoaded(tile, id, previousState, hadData, result) {
|
|
5635
|
+
if (!hadData) {
|
|
5636
|
+
tile.timeAdded = now();
|
|
5637
|
+
if (tile.selfFading) tile.fadeEndTime = tile.timeAdded + this._rasterFadeDuration;
|
|
5638
|
+
}
|
|
5361
5639
|
if (previousState === "expired") tile.refreshedUponExpiration = true;
|
|
5362
5640
|
this._setTileReloadTimer(id, tile);
|
|
5363
5641
|
if (result?.unmodified) return;
|
|
@@ -5608,7 +5886,7 @@ var TileManager = class TileManager extends Evented {
|
|
|
5608
5886
|
const cached = tile;
|
|
5609
5887
|
if (!tile) {
|
|
5610
5888
|
tile = new Tile(tileID, this._source.tileSize * tileID.overscaleFactor());
|
|
5611
|
-
this._loadTile(tile, tileID.key, tile.state);
|
|
5889
|
+
this._loadTile(tile, tileID.key, tile.state, false);
|
|
5612
5890
|
}
|
|
5613
5891
|
tile.uses++;
|
|
5614
5892
|
this._inViewTiles.setTile(tileID.key, tile);
|
|
@@ -7390,8 +7668,10 @@ var Placement = class {
|
|
|
7390
7668
|
else if (!iconWithoutText) placeIcon &&= placeText;
|
|
7391
7669
|
const hasTextBox = placeText && placedGlyphBoxes.placeable;
|
|
7392
7670
|
const hasIconBox = placeIcon && placedIconBoxes.placeable;
|
|
7393
|
-
if (hasTextBox)
|
|
7394
|
-
|
|
7671
|
+
if (hasTextBox) {
|
|
7672
|
+
if (placedVerticalText && placedVerticalText.placeable && verticalTextFeatureIndex) this.collisionIndex.insertCollisionBox(placedGlyphBoxes.box, textOverlapMode, layout.get("text-ignore-placement"), bucket.bucketInstanceId, verticalTextFeatureIndex, collisionGroup.ID);
|
|
7673
|
+
else this.collisionIndex.insertCollisionBox(placedGlyphBoxes.box, textOverlapMode, layout.get("text-ignore-placement"), bucket.bucketInstanceId, textFeatureIndex, collisionGroup.ID);
|
|
7674
|
+
}
|
|
7395
7675
|
if (hasIconBox) this.collisionIndex.insertCollisionBox(placedIconBoxes.box, iconOverlapMode, layout.get("icon-ignore-placement"), bucket.bucketInstanceId, iconFeatureIndex, collisionGroup.ID);
|
|
7396
7676
|
if (placedGlyphCircles) {
|
|
7397
7677
|
if (placeText) this.collisionIndex.insertCollisionCircles(placedGlyphCircles.circles, textOverlapMode, layout.get("text-ignore-placement"), bucket.bucketInstanceId, textFeatureIndex, collisionGroup.ID);
|
|
@@ -7460,8 +7740,10 @@ var Placement = class {
|
|
|
7460
7740
|
symbolInstance.rightJustifiedTextSymbolIndex,
|
|
7461
7741
|
symbolInstance.verticalPlacedTextSymbolIndex
|
|
7462
7742
|
];
|
|
7463
|
-
for (const index of indexes) if (index >= 0)
|
|
7464
|
-
|
|
7743
|
+
for (const index of indexes) if (index >= 0) {
|
|
7744
|
+
if (autoIndex >= 0 && index !== autoIndex) bucket.text.placedSymbolArray.get(index).crossTileID = 0;
|
|
7745
|
+
else bucket.text.placedSymbolArray.get(index).crossTileID = symbolInstance.crossTileID;
|
|
7746
|
+
}
|
|
7465
7747
|
}
|
|
7466
7748
|
markUsedOrientation(bucket, orientation, symbolInstance) {
|
|
7467
7749
|
const horizontal = orientation === 1 || orientation === 3 ? orientation : 0;
|
|
@@ -8100,24 +8382,54 @@ var TileLayerIndex = class {
|
|
|
8100
8382
|
const entry = this._symbolsByKey[symbolInstance.key];
|
|
8101
8383
|
if (!entry) continue;
|
|
8102
8384
|
const scaledSymbolCoord = this.getScaledCoordinates(symbolInstance, newTileID);
|
|
8103
|
-
if (entry.index)
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8385
|
+
if (entry.index) this.findMatchesForIndexedEntry(entry, symbolInstance, scaledSymbolCoord, tolerance, zoomCrossTileIDs);
|
|
8386
|
+
else if (entry.positions) this.findMatchesForNonIndexedEntry(entry, symbolInstance, scaledSymbolCoord, tolerance, zoomCrossTileIDs);
|
|
8387
|
+
}
|
|
8388
|
+
}
|
|
8389
|
+
/**
|
|
8390
|
+
* Matches a symbol instance against an entry backed by a KDBush spatial index
|
|
8391
|
+
* (used for keys with more than {@link KDBUSH_THRESHHOLD} symbols).
|
|
8392
|
+
*
|
|
8393
|
+
* Matches any symbol with the same key whose coordinates are within one grid
|
|
8394
|
+
* unit (with a 4px grid, this covers a 12px by 12px area). The lowest-index
|
|
8395
|
+
* unclaimed candidate is claimed in a single pass rather than sorting the
|
|
8396
|
+
* whole result set on every query: `range()` can return many candidates where
|
|
8397
|
+
* symbols are coincident (e.g. stacked point markers), so a per-query sort
|
|
8398
|
+
* would dominate placement cost on dense layers.
|
|
8399
|
+
*
|
|
8400
|
+
* Once a symbol is marked duplicate against a parent symbol, no other symbol
|
|
8401
|
+
* at the same zoom level may duplicate against the same parent (see issue #5993).
|
|
8402
|
+
*/
|
|
8403
|
+
findMatchesForIndexedEntry(entry, symbolInstance, scaledSymbolCoord, tolerance, zoomCrossTileIDs) {
|
|
8404
|
+
const indexes = entry.index.range(scaledSymbolCoord.x - tolerance, scaledSymbolCoord.y - tolerance, scaledSymbolCoord.x + tolerance, scaledSymbolCoord.y + tolerance);
|
|
8405
|
+
let bestIndex = Infinity;
|
|
8406
|
+
for (const candidate of indexes) if (candidate < bestIndex && !zoomCrossTileIDs[entry.crossTileIDs[candidate]]) bestIndex = candidate;
|
|
8407
|
+
if (bestIndex !== Infinity) {
|
|
8408
|
+
const crossTileID = entry.crossTileIDs[bestIndex];
|
|
8409
|
+
zoomCrossTileIDs[crossTileID] = true;
|
|
8410
|
+
symbolInstance.crossTileID = crossTileID;
|
|
8411
|
+
}
|
|
8412
|
+
}
|
|
8413
|
+
/**
|
|
8414
|
+
* Matches a symbol instance against an entry that stores its positions as a
|
|
8415
|
+
* plain array (used for keys with at most {@link KDBUSH_THRESHHOLD} symbols).
|
|
8416
|
+
*
|
|
8417
|
+
* Matches any symbol with the same key whose coordinates are within one grid
|
|
8418
|
+
* unit (with a 4px grid, this covers a 12px by 12px area). Positions are
|
|
8419
|
+
* stored in symbol-instance order, so the first unclaimed match is also the
|
|
8420
|
+
* lowest-index one.
|
|
8421
|
+
*
|
|
8422
|
+
* Once a symbol is marked duplicate against a parent symbol, no other symbol
|
|
8423
|
+
* at the same zoom level may duplicate against the same parent (see issue #5993).
|
|
8424
|
+
*/
|
|
8425
|
+
findMatchesForNonIndexedEntry(entry, symbolInstance, scaledSymbolCoord, tolerance, zoomCrossTileIDs) {
|
|
8426
|
+
for (let i = 0; i < entry.positions.length; i++) {
|
|
8427
|
+
const thisTileSymbol = entry.positions[i];
|
|
8428
|
+
const crossTileID = entry.crossTileIDs[i];
|
|
8429
|
+
if (Math.abs(thisTileSymbol.x - scaledSymbolCoord.x) <= tolerance && Math.abs(thisTileSymbol.y - scaledSymbolCoord.y) <= tolerance && !zoomCrossTileIDs[crossTileID]) {
|
|
8430
|
+
zoomCrossTileIDs[crossTileID] = true;
|
|
8431
|
+
symbolInstance.crossTileID = crossTileID;
|
|
8432
|
+
break;
|
|
8121
8433
|
}
|
|
8122
8434
|
}
|
|
8123
8435
|
}
|
|
@@ -8154,8 +8466,10 @@ var CrossTileSymbolLayerIndex = class {
|
|
|
8154
8466
|
this.lng = lng;
|
|
8155
8467
|
}
|
|
8156
8468
|
addBucket(tileID, bucket, crossTileIDs) {
|
|
8157
|
-
if (this.indexes[tileID.overscaledZ]?.[tileID.key])
|
|
8158
|
-
|
|
8469
|
+
if (this.indexes[tileID.overscaledZ]?.[tileID.key]) {
|
|
8470
|
+
if (this.indexes[tileID.overscaledZ][tileID.key].bucketInstanceId === bucket.bucketInstanceId) return false;
|
|
8471
|
+
else this.removeBucketCrossTileIDs(tileID.overscaledZ, this.indexes[tileID.overscaledZ][tileID.key]);
|
|
8472
|
+
}
|
|
8159
8473
|
for (let i = 0; i < bucket.symbolInstances.length; i++) {
|
|
8160
8474
|
const symbolInstance = bucket.symbolInstances.get(i);
|
|
8161
8475
|
symbolInstance.crossTileID = 0;
|
|
@@ -8237,7 +8551,7 @@ var CrossTileSymbolIndex = class {
|
|
|
8237
8551
|
var _prelude_fragment_glsl_g_default = "#ifdef GL_ES\nprecision mediump float;\n#else\n#if !defined(lowp)\n#define lowp\n#endif\n#if !defined(mediump)\n#define mediump\n#endif\n#if !defined(highp)\n#define highp\n#endif\n#endif\nout highp vec4 fragColor;";
|
|
8238
8552
|
//#endregion
|
|
8239
8553
|
//#region src/shaders/glsl/_prelude.vertex.glsl.g.ts
|
|
8240
|
-
var _prelude_vertex_glsl_g_default = "#ifdef GL_ES\nprecision highp float;\n#else\n#if !defined(lowp)\n#define lowp\n#endif\n#if !defined(mediump)\n#define mediump\n#endif\n#if !defined(highp)\n#define highp\n#endif\n#endif\nvec2 unpack_float(const float packedValue) {int packedIntValue=int(packedValue);int v0=packedIntValue/256;return vec2(v0,packedIntValue-v0*256);}vec2 unpack_opacity(const
|
|
8554
|
+
var _prelude_vertex_glsl_g_default = "#ifdef GL_ES\nprecision highp float;\n#else\n#if !defined(lowp)\n#define lowp\n#endif\n#if !defined(mediump)\n#define mediump\n#endif\n#if !defined(highp)\n#define highp\n#endif\n#endif\nvec2 unpack_float(const float packedValue) {int packedIntValue=int(packedValue);int v0=packedIntValue/256;return vec2(v0,packedIntValue-v0*256);}vec2 unpack_opacity(const uint packedOpacity) {return vec2(float(packedOpacity >> 1u)/127.0,float(packedOpacity & 1u));}vec4 decode_color(const vec2 encodedColor) {return vec4(unpack_float(encodedColor[0])/255.0,unpack_float(encodedColor[1])/255.0\n);}float unpack_mix_vec2(const vec2 packedValue,const float t) {return mix(packedValue[0],packedValue[1],t);}vec4 unpack_mix_color(const vec4 packedColors,const float t) {vec4 minColor=decode_color(vec2(packedColors[0],packedColors[1]));vec4 maxColor=decode_color(vec2(packedColors[2],packedColors[3]));return mix(minColor,maxColor,t);}vec2 get_pattern_pos(const vec2 pixel_coord_upper,const vec2 pixel_coord_lower,const vec2 pattern_size,const float tile_units_to_pixels,const vec2 pos) {vec2 offset=mod(mod(mod(pixel_coord_upper,pattern_size)*256.0,pattern_size)*256.0+pixel_coord_lower,pattern_size);return (tile_units_to_pixels*pos+offset)/pattern_size;}mat3 rotationMatrixFromAxisAngle(vec3 u,float angle) {float c=cos(angle);float s=sin(angle);float c2=1.0-c;return mat3(u.x*u.x*c2+ c,u.x*u.y*c2-u.z*s,u.x*u.z*c2+u.y*s,u.y*u.x*c2+u.z*s,u.y*u.y*c2+ c,u.y*u.z*c2-u.x*s,u.z*u.x*c2-u.y*s,u.z*u.y*c2+u.x*s,u.z*u.z*c2+ c\n);}\n#ifdef TERRAIN3D\nuniform sampler2D u_terrain;uniform float u_terrain_dim;uniform mat4 u_terrain_matrix;uniform vec4 u_terrain_unpack;uniform float u_terrain_exaggeration;uniform highp sampler2D u_depth;\n#endif\nconst highp vec4 bitSh=vec4(256.*256.*256.,256.*256.,256.,1.);const highp vec4 bitShifts=vec4(1.)/bitSh;highp float unpack(highp vec4 color) {return dot(color,bitShifts);}highp float depthOpacity(vec3 frag) {\n#ifdef TERRAIN3D\nhighp float d=unpack(texture(u_depth,frag.xy*0.5+0.5))+0.0001-frag.z;return 1.0-max(0.0,min(1.0,-d*500.0));\n#else\nreturn 1.0;\n#endif\n}float calculate_visibility(vec4 pos) {\n#ifdef TERRAIN3D\nvec3 frag=pos.xyz/pos.w;highp float d=depthOpacity(frag);if (d > 0.95) return 1.0;return (d+depthOpacity(frag+vec3(0.0,0.01,0.0)))/2.0;\n#else\nreturn 1.0;\n#endif\n}float ele(ivec2 pos) {\n#ifdef TERRAIN3D\nvec4 rgb=(texelFetch(u_terrain,pos,0)*255.0)*u_terrain_unpack;return rgb.r+rgb.g+rgb.b-u_terrain_unpack.a;\n#else\nreturn 0.0;\n#endif\n}float get_elevation(vec2 pos) {\n#ifdef TERRAIN3D\n#ifdef GLOBE\nif ((pos.y <-32767.5) || (pos.y > 32766.5)) {return 0.0;}\n#endif\nvec2 coord=(u_terrain_matrix*vec4(pos,0.0,1.0)).xy*u_terrain_dim+1.0;vec2 f=fract(coord);ivec2 c=ivec2(floor(coord));ivec2 hi=textureSize(u_terrain,0)-1;float tl=ele(clamp(c,ivec2(0),hi));float tr=ele(clamp(c+ivec2(1,0),ivec2(0),hi));float bl=ele(clamp(c+ivec2(0,1),ivec2(0),hi));float br=ele(clamp(c+ivec2(1,1),ivec2(0),hi));float elevation=mix(mix(tl,tr,f.x),mix(bl,br,f.x),f.y);return elevation*u_terrain_exaggeration;\n#else\nreturn 0.0;\n#endif\n}const float PI=3.141592653589793;uniform mat4 u_projection_matrix;";
|
|
8241
8555
|
//#endregion
|
|
8242
8556
|
//#region src/shaders/glsl/background.fragment.glsl.g.ts
|
|
8243
8557
|
var background_fragment_glsl_g_default = "uniform vec4 u_color;uniform float u_opacity;void main() {fragColor=u_color*u_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}";
|
|
@@ -8255,7 +8569,7 @@ var background_pattern_vertex_glsl_g_default = "uniform vec2 u_pattern_size_a;un
|
|
|
8255
8569
|
var circle_fragment_glsl_g_default = "in vec3 v_data;flat in float v_visibility;\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define mediump float radius\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define highp vec4 stroke_color\n#pragma maplibre: define mediump float stroke_width\n#pragma maplibre: define lowp float stroke_opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize mediump float radius\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize highp vec4 stroke_color\n#pragma maplibre: initialize mediump float stroke_width\n#pragma maplibre: initialize lowp float stroke_opacity\nvec2 extrude=v_data.xy;float extrude_length=length(extrude);float antialiased_blur=v_data.z;float opacity_t=smoothstep(0.0,antialiased_blur,extrude_length-1.0);float color_t=stroke_width < 0.01 ? 0.0 : smoothstep(antialiased_blur,0.0,extrude_length-radius/(radius+stroke_width));fragColor=v_visibility*opacity_t*mix(color*opacity,stroke_color*stroke_opacity,color_t);const float epsilon=0.5/255.0;if (fragColor.r < epsilon && fragColor.g < epsilon && fragColor.b < epsilon && fragColor.a < epsilon) {discard;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}";
|
|
8256
8570
|
//#endregion
|
|
8257
8571
|
//#region src/shaders/glsl/circle.vertex.glsl.g.ts
|
|
8258
|
-
var circle_vertex_glsl_g_default = "uniform bool u_scale_with_map;uniform bool u_pitch_with_map;uniform vec2 u_extrude_scale;uniform highp float u_globe_extrude_scale;uniform lowp float u_device_pixel_ratio;uniform highp float u_camera_to_center_distance;uniform vec2 u_translate;layout(location=0) in
|
|
8572
|
+
var circle_vertex_glsl_g_default = "uniform bool u_scale_with_map;uniform bool u_pitch_with_map;uniform vec2 u_extrude_scale;uniform highp float u_globe_extrude_scale;uniform lowp float u_device_pixel_ratio;uniform highp float u_camera_to_center_distance;uniform vec2 u_translate;layout(location=0) in ivec2 a_pos;out vec3 v_data;flat out float v_visibility;\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define mediump float radius\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define highp vec4 stroke_color\n#pragma maplibre: define mediump float stroke_width\n#pragma maplibre: define lowp float stroke_opacity\nvoid main(void) {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize mediump float radius\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize highp vec4 stroke_color\n#pragma maplibre: initialize mediump float stroke_width\n#pragma maplibre: initialize lowp float stroke_opacity\nivec2 pos_raw=a_pos+32768;vec2 extrude=vec2(pos_raw & 7)/7.0*2.0-1.0;vec2 circle_center=vec2(pos_raw >> 3)+u_translate;float ele=get_elevation(circle_center);v_visibility=calculate_visibility(projectTileWithElevation(circle_center,ele));if (u_pitch_with_map) {\n#ifdef GLOBE\nvec3 center_vector=projectToSphere(circle_center);\n#endif\nfloat angle_scale=u_globe_extrude_scale;vec2 corner_position=circle_center;if (u_scale_with_map) {angle_scale*=(radius+stroke_width);corner_position+=extrude*u_extrude_scale*(radius+stroke_width);} else {\n#ifdef GLOBE\nvec4 projected_center=interpolateProjection(circle_center,center_vector,ele);\n#else\nvec4 projected_center=projectTileWithElevation(circle_center,ele);\n#endif\ncorner_position+=extrude*u_extrude_scale*(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);angle_scale*=(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);}\n#ifdef GLOBE\nvec2 angles=extrude*angle_scale;vec3 corner_vector=globeRotateVector(center_vector,angles);gl_Position=interpolateProjection(corner_position,corner_vector,ele);\n#else\ngl_Position=projectTileWithElevation(corner_position,ele);\n#endif\n} else {gl_Position=projectTileWithElevation(circle_center,ele);if (gl_Position.z/gl_Position.w > 1.0) {gl_Position.xy=vec2(10000.0);}if (u_scale_with_map) {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*u_camera_to_center_distance;} else {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*gl_Position.w;}}float antialiasblur=-max(1.0/u_device_pixel_ratio/(radius+stroke_width),blur);v_data=vec3(extrude.x,extrude.y,antialiasblur);}";
|
|
8259
8573
|
//#endregion
|
|
8260
8574
|
//#region src/shaders/glsl/clipping_mask.fragment.glsl.g.ts
|
|
8261
8575
|
var clipping_mask_fragment_glsl_g_default = "void main() {fragColor=vec4(1.0);}";
|
|
@@ -8269,31 +8583,31 @@ const shaders = {
|
|
|
8269
8583
|
backgroundPattern: prepare(background_pattern_fragment_glsl_g_default, background_pattern_vertex_glsl_g_default),
|
|
8270
8584
|
circle: prepare(circle_fragment_glsl_g_default, circle_vertex_glsl_g_default),
|
|
8271
8585
|
clippingMask: prepare(clipping_mask_fragment_glsl_g_default, "layout(location=0) in vec2 a_pos;void main() {gl_Position=projectTile(a_pos);}"),
|
|
8272
|
-
heatmap: prepare("uniform highp float u_intensity;in vec2 v_extrude;\n#pragma maplibre: define highp float weight\n#define GAUSS_COEF 0.3989422804014327\nvoid main() {\n#pragma maplibre: initialize highp float weight\nfloat d=-0.5*3.0*3.0*dot(v_extrude,v_extrude);float val=weight*u_intensity*GAUSS_COEF*exp(d);fragColor=vec4(val,1.0,1.0,1.0);\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform float u_extrude_scale;uniform float u_opacity;uniform float u_intensity;uniform highp float u_globe_extrude_scale;layout(location=0) in
|
|
8586
|
+
heatmap: prepare("uniform highp float u_intensity;in vec2 v_extrude;\n#pragma maplibre: define highp float weight\n#define GAUSS_COEF 0.3989422804014327\nvoid main() {\n#pragma maplibre: initialize highp float weight\nfloat d=-0.5*3.0*3.0*dot(v_extrude,v_extrude);float val=weight*u_intensity*GAUSS_COEF*exp(d);fragColor=vec4(val,1.0,1.0,1.0);\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform float u_extrude_scale;uniform float u_opacity;uniform float u_intensity;uniform highp float u_globe_extrude_scale;layout(location=0) in ivec2 a_pos;out vec2 v_extrude;\n#pragma maplibre: define highp float weight\n#pragma maplibre: define mediump float radius\nconst highp float ZERO=1.0/255.0/16.0;\n#define GAUSS_COEF 0.3989422804014327\nvoid main(void) {\n#pragma maplibre: initialize highp float weight\n#pragma maplibre: initialize mediump float radius\nivec2 pos_raw=a_pos+32768;vec2 unscaled_extrude=vec2(pos_raw & 7)/7.0*2.0-1.0;float S=sqrt(-2.0*log(ZERO/weight/u_intensity/GAUSS_COEF))/3.0;v_extrude=S*unscaled_extrude;vec2 extrude=v_extrude*radius*u_extrude_scale;vec2 circle_center=vec2(pos_raw >> 3);\n#ifdef GLOBE\nvec2 angles=v_extrude*radius*u_globe_extrude_scale;vec3 center_vector=projectToSphere(circle_center);vec3 corner_vector=globeRotateVector(center_vector,angles);gl_Position=interpolateProjection(circle_center+extrude,corner_vector,0.0);\n#else\ngl_Position=projectTileFor3D(circle_center+extrude,get_elevation(circle_center));\n#endif\n}"),
|
|
8273
8587
|
heatmapTexture: prepare("uniform sampler2D u_image;uniform sampler2D u_color_ramp;uniform float u_opacity;in vec2 v_pos;void main() {float t=texture(u_image,v_pos).r;vec4 color=texture(u_color_ramp,vec2(t,0.5));fragColor=color*u_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(0.0);\n#endif\n}", "uniform mat4 u_matrix;uniform vec2 u_world;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos*u_world,0,1);v_pos.x=a_pos.x;v_pos.y=1.0-a_pos.y;}"),
|
|
8274
8588
|
collisionBox: prepare("flat in float v_placed;flat in float v_notUsed;void main() {float alpha=0.5;fragColor=vec4(1.0,0.0,0.0,1.0)*alpha;if (v_placed > 0.5) {fragColor=vec4(0.0,0.0,1.0,0.5)*alpha;}if (v_notUsed > 0.5) {fragColor*=.1;}}", "layout(location=0) in vec2 a_anchor_pos;layout(location=1) in vec2 a_placed;layout(location=2) in vec2 a_box_real;uniform vec2 u_pixel_extrude_scale;flat out float v_placed;flat out float v_notUsed;void main() {gl_Position=projectTileWithElevation(a_anchor_pos,get_elevation(a_anchor_pos));gl_Position.xy=((a_box_real+0.5)*u_pixel_extrude_scale*2.0-1.0)*vec2(1.0,-1.0)*gl_Position.w;if (gl_Position.z/gl_Position.w < 1.1) {gl_Position.z=0.5;}v_placed=a_placed.x;v_notUsed=a_placed.y;}"),
|
|
8275
8589
|
collisionCircle: prepare("flat in float v_radius;in vec2 v_extrude;flat in float v_collision;void main() {float alpha=0.5;float stroke_radius=0.9;float distance_to_center=length(v_extrude);float distance_to_edge=abs(distance_to_center-v_radius);float opacity_t=smoothstep(-stroke_radius,0.0,-distance_to_edge);vec4 color=mix(vec4(0.0,0.0,1.0,0.5),vec4(1.0,0.0,0.0,1.0),v_collision);fragColor=color*alpha*opacity_t;}", "layout(location=0) in vec2 a_pos;layout(location=1) in float a_radius;layout(location=2) in vec2 a_flags;uniform vec2 u_viewport_size;flat out float v_radius;out vec2 v_extrude;flat out float v_collision;void main() {float radius=a_radius;float collision=a_flags.x;float vertexIdx=a_flags.y;vec2 quadVertexOffset=vec2(mix(-1.0,1.0,float(vertexIdx >=2.0)),mix(-1.0,1.0,float(vertexIdx >=1.0 && vertexIdx <=2.0)));vec2 quadVertexExtent=quadVertexOffset*radius;float padding_factor=1.2;v_radius=radius;v_extrude=quadVertexExtent*padding_factor;v_collision=collision;gl_Position=vec4((a_pos/u_viewport_size*2.0-1.0)*vec2(1.0,-1.0),0.0,1.0)+vec4(quadVertexExtent*padding_factor/u_viewport_size*2.0,0.0,0.0);}"),
|
|
8276
|
-
colorRelief: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform sampler2D u_image;uniform vec4 u_unpack;uniform sampler2D u_elevation_stops;uniform sampler2D u_color_stops;uniform int u_color_ramp_size;uniform float u_opacity;in vec2 v_pos;float getElevation(vec2 coord) {vec4 data=texture(u_image,coord)*255.0;data.a=-1.0;return dot(data,u_unpack);}float getElevationStop(int stop) {
|
|
8590
|
+
colorRelief: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform sampler2D u_image;uniform vec4 u_unpack;uniform sampler2D u_elevation_stops;uniform sampler2D u_color_stops;uniform int u_color_ramp_size;uniform float u_opacity;in vec2 v_pos;float getElevation(vec2 coord) {vec4 data=texture(u_image,coord)*255.0;data.a=-1.0;return dot(data,u_unpack);}float getElevationStop(int stop) {vec4 data=texelFetch(u_elevation_stops,ivec2(stop,0),0)*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {float el=getElevation(v_pos);int r=(u_color_ramp_size-1);int l=0;float el_l=getElevationStop(l);float el_r=getElevationStop(r);while(r-l > 1){int m=(r+l)/2;float el_m=getElevationStop(m);if(el < el_m){r=m;el_r=el_m;}else\n{l=m;el_l=el_m;}}float x=(float(l)+(el-el_l)/(el_r-el_l)+0.5)/float(u_color_ramp_size);fragColor=u_opacity*texture(u_color_stops,vec2(x,0));\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_dimension;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_pos/8192.0)*scale+epsilon;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}"),
|
|
8277
8591
|
debug: prepare("uniform highp vec4 u_color;uniform sampler2D u_overlay;in vec2 v_uv;void main() {vec4 overlay_color=texture(u_overlay,v_uv);fragColor=mix(u_color,overlay_color,overlay_color.a);}", "layout(location=0) in vec2 a_pos;out vec2 v_uv;uniform float u_overlay_scale;void main() {v_uv=a_pos/8192.0;gl_Position=projectTileWithElevation(a_pos*u_overlay_scale,get_elevation(a_pos));}"),
|
|
8278
8592
|
depth: prepare(clipping_mask_fragment_glsl_g_default, "layout(location=0) in vec2 a_pos;void main() {\n#ifdef GLOBE\ngl_Position=projectTileFor3D(a_pos,0.0);\n#else\ngl_Position=u_projection_matrix*vec4(a_pos,0.0,1.0);\n#endif\n}"),
|
|
8279
8593
|
fill: prepare("#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float opacity\nfragColor=color*opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float opacity\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}gl_Position=projectTile(a_pos+u_fill_translate,a_pos);}"),
|
|
8280
8594
|
fillOutline: prepare("in vec2 v_pos;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 outline_color\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 outline_color\n#pragma maplibre: initialize lowp float opacity\nfloat dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);fragColor=outline_color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_world;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define highp vec4 outline_color\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 outline_color\n#pragma maplibre: initialize lowp float opacity\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}gl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n}"),
|
|
8281
8595
|
fillOutlinePattern: prepare("uniform vec2 u_texsize;uniform sampler2D u_image;uniform float u_fade;in vec2 v_pos_a;in vec2 v_pos_b;in vec2 v_pos;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);float dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);fragColor=mix(color1,color2,u_fade)*alpha*opacity;\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_world;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;out vec2 v_pos;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n}"),
|
|
8282
8596
|
fillPattern: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);fragColor=mix(color1,color2,u_fade)*opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileZoomRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileZoomRatio,a_pos);}"),
|
|
8283
|
-
fillExtrusion: prepare("in vec4 v_color;void main() {fragColor=v_color;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;layout(location=1) in
|
|
8284
|
-
fillExtrusionPattern: prepare("uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;in vec4 v_lighting;\n#pragma maplibre: define lowp float base\n#pragma maplibre: define lowp float height\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float base\n#pragma maplibre: initialize lowp float height\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);vec4 mixedColor=mix(color1,color2,u_fade);fragColor=mixedColor*v_lighting;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_height_factor;uniform vec3 u_scale;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;layout(location=0) in vec2 a_pos;layout(location=1) in
|
|
8285
|
-
hillshadePrepare: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_dimension;uniform float u_zoom;uniform vec4 u_unpack;float getElevation(
|
|
8597
|
+
fillExtrusion: prepare("in vec4 v_color;void main() {fragColor=v_color;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;layout(location=1) in ivec4 a_normal_ed;\n#ifdef TERRAIN3D\nlayout(location=2) in vec2 a_centroid;\n#endif\nout vec4 v_color;\n#pragma maplibre: define highp float base\n#pragma maplibre: define highp float height\n#pragma maplibre: define highp vec4 color\nvoid main() {\n#pragma maplibre: initialize highp float base\n#pragma maplibre: initialize highp float height\n#pragma maplibre: initialize highp vec4 color\nvec3 normal=vec3(a_normal_ed.xyz);\n#ifdef TERRAIN3D\nfloat height_terrain3d_offset=get_elevation(a_centroid);float base_terrain3d_offset=height_terrain3d_offset-(base > 0.0 ? 0.0 : 10.0);\n#else\nfloat height_terrain3d_offset=0.0;float base_terrain3d_offset=0.0;\n#endif\nbase=max(0.0,base)+base_terrain3d_offset;height=max(0.0,height)+height_terrain3d_offset;float t=float(a_normal_ed.x & 1);float elevation=t > 0.0 ? height : base;vec2 posInTile=a_pos+u_fill_translate;\n#ifdef GLOBE\nvec3 spherePos=projectToSphere(posInTile,a_pos);gl_Position=interpolateProjectionFor3D(posInTile,spherePos,elevation);\n#else\ngl_Position=u_projection_matrix*vec4(posInTile,elevation,1.0);\n#endif\nfloat colorvalue=color.r*0.2126+color.g*0.7152+color.b*0.0722;v_color=vec4(0.0,0.0,0.0,1.0);vec4 ambientlight=vec4(0.03,0.03,0.03,1.0);color+=ambientlight;vec3 normalForLighting=normal/16384.0;float directional=clamp(dot(normalForLighting,u_lightpos),0.0,1.0);\n#ifdef GLOBE\nmat3 rotMatrix=globeGetRotationMatrix(spherePos);normalForLighting=rotMatrix*normalForLighting;directional=mix(directional,clamp(dot(normalForLighting,u_lightpos_globe),0.0,1.0),u_projection_transition);\n#endif\ndirectional=mix((1.0-u_lightintensity),max((1.0-colorvalue+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_color.r+=clamp(color.r*directional*u_lightcolor.r,mix(0.0,0.3,1.0-u_lightcolor.r),1.0);v_color.g+=clamp(color.g*directional*u_lightcolor.g,mix(0.0,0.3,1.0-u_lightcolor.g),1.0);v_color.b+=clamp(color.b*directional*u_lightcolor.b,mix(0.0,0.3,1.0-u_lightcolor.b),1.0);v_color*=u_opacity;}"),
|
|
8598
|
+
fillExtrusionPattern: prepare("uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;in vec4 v_lighting;\n#pragma maplibre: define lowp float base\n#pragma maplibre: define lowp float height\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float base\n#pragma maplibre: initialize lowp float height\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);vec4 mixedColor=mix(color1,color2,u_fade);fragColor=mixedColor*v_lighting;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_height_factor;uniform vec3 u_scale;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;layout(location=0) in vec2 a_pos;layout(location=1) in ivec4 a_normal_ed;\n#ifdef TERRAIN3D\nlayout(location=2) in vec2 a_centroid;\n#endif\n#ifdef GLOBE\nout vec3 v_sphere_pos;\n#endif\nout vec2 v_pos_a;out vec2 v_pos_b;out vec4 v_lighting;\n#pragma maplibre: define lowp float base\n#pragma maplibre: define lowp float height\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float base\n#pragma maplibre: initialize lowp float height\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec3 normal=vec3(a_normal_ed.xyz);float edgedistance=float(a_normal_ed.w);vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;\n#ifdef TERRAIN3D\nfloat height_terrain3d_offset=get_elevation(a_centroid);float base_terrain3d_offset=height_terrain3d_offset-(base > 0.0 ? 0.0 : 10.0);\n#else\nfloat height_terrain3d_offset=0.0;float base_terrain3d_offset=0.0;\n#endif\nbase=max(0.0,base)+base_terrain3d_offset;height=max(0.0,height)+height_terrain3d_offset;float t=float(a_normal_ed.x & 1);float elevation=t > 0.0 ? height : base;vec2 posInTile=a_pos+u_fill_translate;\n#ifdef GLOBE\nvec3 spherePos=projectToSphere(posInTile,a_pos);vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);v_sphere_pos=elevatedPos;gl_Position=interpolateProjectionFor3D(posInTile,spherePos,elevation);\n#else\ngl_Position=u_projection_matrix*vec4(posInTile,elevation,1.0);\n#endif\nvec2 pos=a_normal_ed.x==1 && a_normal_ed.y==0 && a_normal_ed.z==16384\n? a_pos\n: vec2(edgedistance,elevation*u_height_factor);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,pos);v_lighting=vec4(0.0,0.0,0.0,1.0);float directional=clamp(dot(normal/16383.0,u_lightpos),0.0,1.0);directional=mix((1.0-u_lightintensity),max((0.5+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_lighting.rgb+=clamp(directional*u_lightcolor,mix(vec3(0.0),vec3(0.3),1.0-u_lightcolor),vec3(1.0));v_lighting*=u_opacity;}"),
|
|
8599
|
+
hillshadePrepare: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_dimension;uniform float u_zoom;uniform vec4 u_unpack;float getElevation(ivec2 texel) {vec4 data=texelFetch(u_image,texel,0)*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {ivec2 pos=ivec2(gl_FragCoord.xy)+ivec2(1);float tileSize=u_dimension.x-2.0;float a=getElevation(pos+ivec2(-1,-1));float b=getElevation(pos+ivec2(0,-1));float c=getElevation(pos+ivec2(1,-1));float d=getElevation(pos+ivec2(-1,0));float e=getElevation(pos);float f=getElevation(pos+ivec2(1,0));float g=getElevation(pos+ivec2(-1,1));float h=getElevation(pos+ivec2(0,1));float i=getElevation(pos+ivec2(1,1));float exaggerationFactor=u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;float exaggeration=u_zoom < 15.0 ? (u_zoom-15.0)*exaggerationFactor : 0.0;vec2 deriv=vec2((c+f+f+i)-(a+d+d+g),(g+h+h+i)-(a+b+b+c))*tileSize/pow(2.0,exaggeration+(28.2562-u_zoom));fragColor=clamp(vec4(deriv.x/8.0+0.5,deriv.y/8.0+0.5,1.0,1.0),0.0,1.0);\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform mat4 u_matrix;uniform vec2 u_dimension;layout(location=0) in vec2 a_pos;layout(location=1) in vec2 a_texture_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_texture_pos/8192.0)*scale+epsilon;}"),
|
|
8286
8600
|
hillshade: prepare("uniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_latrange;uniform float u_exaggeration;uniform vec4 u_accent;uniform int u_method;uniform float u_altitudes[NUM_ILLUMINATION_SOURCES];uniform float u_azimuths[NUM_ILLUMINATION_SOURCES];uniform vec4 u_shadows[NUM_ILLUMINATION_SOURCES];uniform vec4 u_highlights[NUM_ILLUMINATION_SOURCES];\n#define PI 3.141592653589793\n#define STANDARD 0\n#define COMBINED 1\n#define IGOR 2\n#define MULTIDIRECTIONAL 3\n#define BASIC 4\nfloat get_aspect(vec2 deriv){return deriv.x !=0.0 ? atan(deriv.y,-deriv.x) : PI/2.0*(deriv.y > 0.0 ? 1.0 :-1.0);}void igor_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float aspect=get_aspect(deriv);float azimuth=u_azimuths[0]+PI;float slope_stength=atan(length(deriv))*2.0/PI;float aspect_strength=1.0-abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);float shadow_strength=slope_stength*aspect_strength;float highlight_strength=slope_stength*(1.0-aspect_strength);fragColor=u_shadows[0]*shadow_strength+u_highlights[0]*highlight_strength;}void standard_hillshade(vec2 deriv){float azimuth=u_azimuths[0]+PI;float slope=atan(0.625*length(deriv));float aspect=get_aspect(deriv);float intensity=u_exaggeration;float base=1.875-intensity*1.75;float maxValue=0.5*PI;float scaledSlope=intensity !=0.5 ? ((pow(base,slope)-1.0)/(pow(base,maxValue)-1.0))*maxValue : slope;float accent=cos(scaledSlope);vec4 accent_color=(1.0-accent)*u_accent*clamp(intensity*2.0,0.0,1.0);float shade=abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);vec4 shade_color=mix(u_shadows[0],u_highlights[0],shade)*sin(scaledSlope)*clamp(intensity*2.0,0.0,1.0);fragColor=accent_color*(1.0-shade_color.a)+shade_color;}void basic_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor=u_highlights[0]*(2.0*shade-1.0);}else\n{fragColor=u_shadows[0]*(1.0-2.0*shade);}}void multidirectional_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;fragColor=vec4(0,0,0,0);for(int i=0; i < NUM_ILLUMINATION_SOURCES; i++){float cos_alt=cos(u_altitudes[i]);float sin_alt=sin(u_altitudes[i]);float cos_az=-cos(u_azimuths[i]);float sin_az=-sin(u_azimuths[i]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor+=u_highlights[i]*(2.0*shade-1.0)/float(NUM_ILLUMINATION_SOURCES);}else\n{fragColor+=u_shadows[i]*(1.0-2.0*shade)/float(NUM_ILLUMINATION_SOURCES);}}}void combined_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=acos((sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv)));cang=clamp(cang,0.0,PI/2.0);float shade=cang*atan(length(deriv))*4.0/PI/PI;float highlight=(PI/2.0-cang)*atan(length(deriv))*4.0/PI/PI;fragColor=u_shadows[0]*shade+u_highlights[0]*highlight;}void main() {vec4 pixel=texture(u_image,v_pos);float scaleFactor=cos(radians((u_latrange[0]-u_latrange[1])*(1.0-v_pos.y)+u_latrange[1]));vec2 deriv=((pixel.rg*8.0)-4.0)/scaleFactor;if (u_method==BASIC) {basic_hillshade(deriv);} else if (u_method==COMBINED) {combined_hillshade(deriv);} else if (u_method==IGOR) {igor_hillshade(deriv);} else if (u_method==MULTIDIRECTIONAL) {multidirectional_hillshade(deriv);} else if (u_method==STANDARD) {standard_hillshade(deriv);} else {standard_hillshade(deriv);}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform mat4 u_matrix;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);v_pos=a_pos/8192.0;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}"),
|
|
8287
|
-
line: prepare("uniform lowp float u_device_pixel_ratio;flat in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\nlayout(location=0) in
|
|
8288
|
-
lineGradient: prepare("uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;flat in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;in highp vec2 v_uv;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\nlayout(location=0) in
|
|
8289
|
-
linePattern: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform lowp float u_device_pixel_ratio;uniform vec2 u_texsize;uniform float u_fade;uniform mediump vec3 u_scale;uniform sampler2D u_image;in vec2 v_normal;flat in vec2 v_width2;in float v_linesofar;in float v_gamma_scale;flat in float v_width;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;vec2 pattern_size_a=vec2(display_size_a.x*fromScale/tileZoomRatio,display_size_a.y);vec2 pattern_size_b=vec2(display_size_b.x*toScale/tileZoomRatio,display_size_b.y);float aspect_a=display_size_a.y/v_width;float aspect_b=display_size_b.y/v_width;float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float x_a=mod(v_linesofar/pattern_size_a.x*aspect_a,1.0);float x_b=mod(v_linesofar/pattern_size_b.x*aspect_b,1.0);float y=0.5*v_normal.y+0.5;vec2 texel_size=1.0/u_texsize;vec2 pos_a=mix(pattern_tl_a*texel_size-texel_size,pattern_br_a*texel_size+texel_size,vec2(x_a,y));vec2 pos_b=mix(pattern_tl_b*texel_size-texel_size,pattern_br_b*texel_size+texel_size,vec2(x_b,y));vec4 color=mix(texture(u_image,pos_a),texture(u_image,pos_b),u_fade);fragColor=color*alpha*opacity;\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in
|
|
8290
|
-
lineSDF: prepare("uniform lowp float u_device_pixel_ratio;uniform lowp float u_lineatlas_width;uniform sampler2D u_image;uniform float u_mix;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float sdfdist_a=texture(u_image,v_tex_a).a;float sdfdist_b=texture(u_image,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0/u_device_pixel_ratio)/min(dasharray_from.w,dasharray_to.w);alpha*=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in
|
|
8291
|
-
lineGradientSDF: prepare("uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;uniform sampler2D u_image_dash;uniform float u_mix;uniform lowp float u_lineatlas_width;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;in highp vec2 v_uv;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);float sdfdist_a=texture(u_image_dash,v_tex_a).a;float sdfdist_b=texture(u_image_dash,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0)/min(dasharray_from.w,dasharray_to.w);float dash_alpha=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*dash_alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in
|
|
8601
|
+
line: prepare("uniform lowp float u_device_pixel_ratio;flat in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform vec2 u_units_to_pixels;uniform lowp float u_device_pixel_ratio;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp float v_linesofar;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);v_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*2.0;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nv_width2=vec2(outset,inset);}"),
|
|
8602
|
+
lineGradient: prepare("uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;flat in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;in highp vec2 v_uv;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;layout(location=2) in float a_uv_x;layout(location=3) in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);highp float texel_height=1.0/u_image_height;highp float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nv_width2=vec2(outset,inset);}"),
|
|
8603
|
+
linePattern: prepare("#ifdef GL_ES\nprecision highp float;\n#endif\nuniform lowp float u_device_pixel_ratio;uniform vec2 u_texsize;uniform float u_fade;uniform mediump vec3 u_scale;uniform sampler2D u_image;in vec2 v_normal;flat in vec2 v_width2;in float v_linesofar;in float v_gamma_scale;flat in float v_width;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\nclipAntimeridian();vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;vec2 pattern_size_a=vec2(display_size_a.x*fromScale/tileZoomRatio,display_size_a.y);vec2 pattern_size_b=vec2(display_size_b.x*toScale/tileZoomRatio,display_size_b.y);float aspect_a=display_size_a.y/v_width;float aspect_b=display_size_b.y/v_width;float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float x_a=mod(v_linesofar/pattern_size_a.x*aspect_a,1.0);float x_b=mod(v_linesofar/pattern_size_b.x*aspect_b,1.0);float y=0.5*v_normal.y+0.5;vec2 texel_size=1.0/u_texsize;vec2 pos_a=mix(pattern_tl_a*texel_size-texel_size,pattern_br_a*texel_size+texel_size,vec2(x_a,y));vec2 pos_b=mix(pattern_tl_b*texel_size-texel_size,pattern_br_b*texel_size+texel_size,vec2(x_b,y));vec4 color=mix(texture(u_image,pos_a),texture(u_image,pos_b),u_fade);fragColor=color*alpha*opacity;\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform vec2 u_units_to_pixels;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;out vec2 v_normal;flat out vec2 v_width2;out float v_linesofar;out float v_gamma_scale;flat out float v_width;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define lowp vec4 pattern_from\n#pragma maplibre: define lowp vec4 pattern_to\n#pragma maplibre: define lowp float pixel_ratio_from\n#pragma maplibre: define lowp float pixel_ratio_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 pattern_from\n#pragma maplibre: initialize mediump vec4 pattern_to\n#pragma maplibre: initialize lowp float pixel_ratio_from\n#pragma maplibre: initialize lowp float pixel_ratio_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nv_linesofar=a_linesofar;v_width2=vec2(outset,inset);v_width=floorwidth;}"),
|
|
8604
|
+
lineSDF: prepare("uniform lowp float u_device_pixel_ratio;uniform lowp float u_lineatlas_width;uniform sampler2D u_image;uniform float u_mix;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float sdfdist_a=texture(u_image,v_tex_a).a;float sdfdist_b=texture(u_image,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0/u_device_pixel_ratio)/min(dasharray_from.w,dasharray_to.w);alpha*=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;flat out vec2 v_width2;out vec2 v_tex_a;out vec2 v_tex_b;out float v_gamma_scale;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nfloat u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}"),
|
|
8605
|
+
lineGradientSDF: prepare("uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;uniform sampler2D u_image_dash;uniform float u_mix;uniform lowp float u_lineatlas_width;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;in highp vec2 v_uv;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);float sdfdist_a=texture(u_image_dash,v_tex_a).a;float sdfdist_b=texture(u_image_dash,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0)/min(dasharray_from.w,dasharray_to.w);float dash_alpha=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*dash_alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;layout(location=2) in float a_uv_x;layout(location=3) in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv;out vec2 v_tex_a;out vec2 v_tex_b;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;float texel_height=1.0/u_image_height;float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nfloat u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}"),
|
|
8292
8606
|
layerOpacity: prepare("uniform sampler2D u_image;uniform float u_opacity;in vec2 v_pos;void main() {fragColor=texture(u_image,v_pos)*u_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(0.0);\n#endif\n}", "layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=vec4(a_pos.x*2.0-1.0,1.0-a_pos.y*2.0,0.0,1.0);v_pos.x=a_pos.x;v_pos.y=1.0-a_pos.y;}"),
|
|
8293
|
-
raster: prepare("uniform float u_fade_t;uniform float u_opacity;uniform sampler2D u_image0;uniform sampler2D u_image1;in
|
|
8294
|
-
symbolIcon: prepare("uniform sampler2D u_texture;in vec2 v_tex;flat in float v_total_opacity;void main() {fragColor=texture(u_texture,v_tex)*v_total_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in
|
|
8295
|
-
symbolSDF: prepare("#define SDF_PX 8.0\nuniform bool u_is_halo;uniform bool u_is_plain;uniform sampler2D u_texture;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;uniform bool u_is_text;in vec2 v_data0;in vec3 v_data1;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nfloat EDGE_GAMMA=0.105/u_device_pixel_ratio;vec2 tex=v_data0.xy;float gamma_scale=v_data1.x;float size=v_data1.y;float total_opacity=v_data1[2];float fontScale=u_is_text ? size/24.0 : size;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float inner_edge=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out_text,color_alpha_out_halo;if (u_is_plain){highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(inner_edge-gamma_scaled,inner_edge+gamma_scaled,dist);color_alpha_out_text=total_opacity*alpha*fill_color;}if (u_is_halo) {float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);float inner_edge_halo=inner_edge+gamma_halo*gamma_scale;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(inner_edge_halo-gamma_scaled_halo,inner_edge_halo+gamma_scaled_halo,dist);highp float halo_edge=(6.0-halo_width/fontScale)/SDF_PX;alpha_halo= min(smoothstep(halo_edge-gamma_scaled_halo,halo_edge+gamma_scaled_halo,dist),1.0-alpha_halo);color_alpha_out_halo=total_opacity*alpha_halo*halo_color;}if (u_is_plain && u_is_halo) {fragColor=color_alpha_out_text+(1.-color_alpha_out_text.a)*color_alpha_out_halo;} else if (u_is_halo){fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out_text;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in
|
|
8296
|
-
symbolTextAndIcon: prepare("#define SDF_PX 8.0\n#define SDF 1.0\n#define ICON 0.0\nuniform bool u_is_halo;uniform bool u_is_text;uniform sampler2D u_texture;uniform sampler2D u_texture_icon;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;in vec4 v_data0;in vec3 v_data1;flat in float v_is_sdf;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nfloat total_opacity=v_data1[2];if (v_is_sdf==ICON) {vec2 tex_icon=v_data0.zw;fragColor=texture(u_texture_icon,tex_icon)*total_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\nreturn;}vec2 tex=v_data0.xy;float EDGE_GAMMA=0.105/u_device_pixel_ratio;float gamma_scale=v_data1.x;float size=v_data1.y;float fontScale=size/24.0;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out,color_alpha_out_halo;if (u_is_text) {highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);color_alpha_out=fill_color*(alpha*total_opacity);}if (u_is_halo) {highp float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);lowp float buff_halo=(6.0-halo_width/fontScale)/SDF_PX;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(buff_halo-gamma_scaled_halo,buff_halo+gamma_scaled_halo,dist);color_alpha_out_halo=halo_color*(alpha_halo*total_opacity);}if (u_is_text && u_is_halo) {fragColor=color_alpha_out+(1.-color_alpha_out.a)*color_alpha_out_halo;} else if (u_is_halo) {fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in
|
|
8607
|
+
raster: prepare("uniform float u_fade_t;uniform float u_opacity;uniform sampler2D u_image0;uniform sampler2D u_image1;in vec3 v_pos0;in vec3 v_pos1;uniform float u_brightness_low;uniform float u_brightness_high;uniform float u_saturation_factor;uniform float u_contrast_factor;uniform vec3 u_spin_weights;void main() {vec4 color0=texture(u_image0,v_pos0.xy/v_pos0.z);vec4 color1=texture(u_image1,v_pos1.xy/v_pos1.z);if (color0.a > 0.0) {color0.rgb=color0.rgb/color0.a;}if (color1.a > 0.0) {color1.rgb=color1.rgb/color1.a;}vec4 color=mix(color0,color1,u_fade_t);color.a*=u_opacity;vec3 rgb=color.rgb;rgb=vec3(dot(rgb,u_spin_weights.xyz),dot(rgb,u_spin_weights.zxy),dot(rgb,u_spin_weights.yzx));float average=(color.r+color.g+color.b)/3.0;rgb+=(average-rgb)*u_saturation_factor;rgb=(rgb-0.5)*u_contrast_factor+0.5;vec3 u_high_vec=vec3(u_brightness_low,u_brightness_low,u_brightness_low);vec3 u_low_vec=vec3(u_brightness_high,u_brightness_high,u_brightness_high);fragColor=vec4(mix(u_high_vec,u_low_vec,rgb)*color.a,color.a);\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_tl_parent;uniform float u_scale_parent;uniform float u_buffer_scale;uniform vec3 u_perspective_transform;uniform vec4 u_coords_top;uniform vec4 u_coords_bottom;layout(location=0) in vec2 a_pos;out vec3 v_pos0;out vec3 v_pos1;void main() {vec2 fractionalPos=a_pos/8192.0;vec2 position=mix(mix(u_coords_top.xy,u_coords_top.zw,fractionalPos.x),mix(u_coords_bottom.xy,u_coords_bottom.zw,fractionalPos.x),fractionalPos.y);gl_Position=projectTile(position,position);vec2 texturePos=((fractionalPos-0.5)/u_buffer_scale)+0.5;\n#ifdef GLOBE\nif (a_pos.y <-32767.5) {texturePos.y=0.0;}if (a_pos.y > 32766.5) {texturePos.y=1.0;}\n#endif\nfloat perspectiveRatio=dot(u_perspective_transform,vec3(position,1.0));v_pos0=vec3(texturePos*perspectiveRatio,perspectiveRatio);vec2 parentPos=(texturePos*u_scale_parent)+u_tl_parent;v_pos1=vec3(parentPos*perspectiveRatio,perspectiveRatio);}"),
|
|
8608
|
+
symbolIcon: prepare("uniform sampler2D u_texture;in vec2 v_tex;flat in float v_total_opacity;void main() {fragColor=texture(u_texture,v_tex)*v_total_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec4 a_pixeloffset;layout(location=3) in vec3 a_projected_pos;layout(location=4) in uint a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform highp float u_camera_to_center_distance;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform float u_fade_change;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform vec2 u_texsize;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;out vec2 v_tex;flat out float v_total_opacity;\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);vec2 a_pxoffset=a_pixeloffset.xy;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float visibility=calculate_visibility(projectedPoint);v_total_opacity=opacity*max(0.0,min(visibility,fade_opacity[0]+fade_change));if (v_total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset/16.0)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}gl_Position=finalPos;v_tex=a_tex/u_texsize;}"),
|
|
8609
|
+
symbolSDF: prepare("#define SDF_PX 8.0\nuniform bool u_is_halo;uniform bool u_is_plain;uniform sampler2D u_texture;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;uniform bool u_is_text;in vec2 v_data0;in vec3 v_data1;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nfloat EDGE_GAMMA=0.105/u_device_pixel_ratio;vec2 tex=v_data0.xy;float gamma_scale=v_data1.x;float size=v_data1.y;float total_opacity=v_data1[2];float fontScale=u_is_text ? size/24.0 : size;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float inner_edge=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out_text,color_alpha_out_halo;if (u_is_plain){highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(inner_edge-gamma_scaled,inner_edge+gamma_scaled,dist);color_alpha_out_text=total_opacity*alpha*fill_color;}if (u_is_halo) {float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);float inner_edge_halo=inner_edge+gamma_halo*gamma_scale;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(inner_edge_halo-gamma_scaled_halo,inner_edge_halo+gamma_scaled_halo,dist);highp float halo_edge=(6.0-halo_width/fontScale)/SDF_PX;alpha_halo= min(smoothstep(halo_edge-gamma_scaled_halo,halo_edge+gamma_scaled_halo,dist),1.0-alpha_halo);color_alpha_out_halo=total_opacity*alpha_halo*halo_color;}if (u_is_plain && u_is_halo) {fragColor=color_alpha_out_text+(1.-color_alpha_out_text.a)*color_alpha_out_halo;} else if (u_is_halo){fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out_text;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec4 a_pixeloffset;layout(location=3) in vec3 a_projected_pos;layout(location=4) in uint a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;out vec2 v_data0;out vec3 v_data1;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);vec2 a_pxoffset=a_pixeloffset.xy/16.0;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));float total_opacity=opacity*interpolated_fade_opacity;if (total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;v_data0=a_tex/u_texsize;v_data1=vec3(gamma_scale,size,total_opacity);}"),
|
|
8610
|
+
symbolTextAndIcon: prepare("#define SDF_PX 8.0\n#define SDF 1.0\n#define ICON 0.0\nuniform bool u_is_halo;uniform bool u_is_text;uniform sampler2D u_texture;uniform sampler2D u_texture_icon;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;in vec4 v_data0;in vec3 v_data1;flat in float v_is_sdf;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nfloat total_opacity=v_data1[2];if (v_is_sdf==ICON) {vec2 tex_icon=v_data0.zw;fragColor=texture(u_texture_icon,tex_icon)*total_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\nreturn;}vec2 tex=v_data0.xy;float EDGE_GAMMA=0.105/u_device_pixel_ratio;float gamma_scale=v_data1.x;float size=v_data1.y;float fontScale=size/24.0;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out,color_alpha_out_halo;if (u_is_text) {highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);color_alpha_out=fill_color*(alpha*total_opacity);}if (u_is_halo) {highp float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);lowp float buff_halo=(6.0-halo_width/fontScale)/SDF_PX;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(buff_halo-gamma_scaled_halo,buff_halo+gamma_scaled_halo,dist);color_alpha_out_halo=halo_color*(alpha_halo*total_opacity);}if (u_is_text && u_is_halo) {fragColor=color_alpha_out+(1.-color_alpha_out.a)*color_alpha_out_halo;} else if (u_is_halo) {fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec3 a_projected_pos;layout(location=3) in uint a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_texsize_icon;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;out vec4 v_data0;out vec3 v_data1;flat out float v_is_sdf;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);float is_sdf=float(a_data.z & 1u);float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));float total_opacity=opacity*interpolated_fade_opacity;if (total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=size/24.0;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map && !u_is_along_line) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;v_data0.xy=a_tex/u_texsize;v_data0.zw=a_tex/u_texsize_icon;v_data1=vec3(gamma_scale,size,total_opacity);v_is_sdf=is_sdf;}"),
|
|
8297
8611
|
terrain: prepare("uniform sampler2D u_texture;uniform vec4 u_fog_color;uniform vec4 u_horizon_color;uniform float u_fog_ground_blend;uniform float u_fog_ground_blend_opacity;uniform float u_horizon_fog_blend;uniform bool u_is_globe_mode;in vec2 v_texture_pos;in float v_fog_depth;const float gamma=2.2;vec4 gammaToLinear(vec4 color) {return pow(color,vec4(gamma));}vec4 linearToGamma(vec4 color) {return pow(color,vec4(1.0/gamma));}void main() {vec4 surface_color=texture(u_texture,vec2(v_texture_pos.x,1.0-v_texture_pos.y));if (!u_is_globe_mode && u_fog_ground_blend_opacity > 0.0 && v_fog_depth > u_fog_ground_blend) {vec4 surface_color_linear=gammaToLinear(surface_color);float blend_color=smoothstep(0.0,1.0,max((v_fog_depth-u_horizon_fog_blend)/(1.0-u_horizon_fog_blend),0.0));vec4 fog_horizon_color_linear=mix(gammaToLinear(u_fog_color),gammaToLinear(u_horizon_color),blend_color);float factor_fog=max(v_fog_depth-u_fog_ground_blend,0.0)/(1.0-u_fog_ground_blend);fragColor=linearToGamma(mix(surface_color_linear,fog_horizon_color_linear,pow(factor_fog,2.0)*u_fog_ground_blend_opacity));} else {fragColor=surface_color;}}", "layout(location=0) in vec3 a_pos3d;uniform mat4 u_fog_matrix;uniform float u_ele_delta;out vec2 v_texture_pos;out float v_fog_depth;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;v_texture_pos=a_pos3d.xy/8192.0;gl_Position=projectTileFor3D(a_pos3d.xy,ele-ele_delta);vec4 pos=u_fog_matrix*vec4(a_pos3d.xy,ele,1.0);v_fog_depth=pos.z/pos.w*0.5+0.5;}"),
|
|
8298
8612
|
terrainDepth: prepare("in float v_depth;const highp vec4 bitSh=vec4(256.*256.*256.,256.*256.,256.,1.);const highp vec4 bitMsk=vec4(0.,vec3(1./256.0));highp vec4 pack(highp float value) {highp vec4 comp=fract(value*bitSh);comp-=comp.xxyz*bitMsk;return comp;}void main() {fragColor=pack(v_depth);}", "layout(location=0) in vec3 a_pos3d;uniform float u_ele_delta;out float v_depth;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;gl_Position=projectTileFor3D(a_pos3d.xy,ele-ele_delta);v_depth=gl_Position.z/gl_Position.w;}"),
|
|
8299
8613
|
terrainCoords: prepare("precision mediump float;uniform sampler2D u_texture;uniform float u_terrain_coords_id;in vec2 v_texture_pos;void main() {vec4 rgba=texture(u_texture,v_texture_pos);fragColor=vec4(rgba.r,rgba.g,rgba.b,u_terrain_coords_id);}", "layout(location=0) in vec3 a_pos3d;uniform float u_ele_delta;out vec2 v_texture_pos;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;v_texture_pos=a_pos3d.xy/8192.0;gl_Position=projectTileFor3D(a_pos3d.xy,ele-ele_delta);}"),
|
|
@@ -8327,7 +8641,8 @@ uniform ${precision} ${type} u_${name};
|
|
|
8327
8641
|
vertexSource = vertexSource.replace(re, (match, operation, precision, type, name) => {
|
|
8328
8642
|
const attrType = type === "float" ? "vec2" : "vec4";
|
|
8329
8643
|
const unpackType = name.match(/color/) ? "color" : attrType;
|
|
8330
|
-
if (fragmentPragmas[name])
|
|
8644
|
+
if (fragmentPragmas[name]) {
|
|
8645
|
+
if (operation === "define") return `
|
|
8331
8646
|
#ifndef HAS_UNIFORM_u_${name}
|
|
8332
8647
|
uniform lowp float u_${name}_t;
|
|
8333
8648
|
layout(location = ${locationCounter++}) in ${precision} ${attrType} a_${name};
|
|
@@ -8336,21 +8651,21 @@ out ${precision} ${type} ${name};
|
|
|
8336
8651
|
uniform ${precision} ${type} u_${name};
|
|
8337
8652
|
#endif
|
|
8338
8653
|
`;
|
|
8339
|
-
|
|
8654
|
+
else if (unpackType === "vec4") return `
|
|
8340
8655
|
#ifndef HAS_UNIFORM_u_${name}
|
|
8341
8656
|
${name} = a_${name};
|
|
8342
8657
|
#else
|
|
8343
8658
|
${precision} ${type} ${name} = u_${name};
|
|
8344
8659
|
#endif
|
|
8345
8660
|
`;
|
|
8346
|
-
|
|
8661
|
+
else return `
|
|
8347
8662
|
#ifndef HAS_UNIFORM_u_${name}
|
|
8348
8663
|
${name} = unpack_mix_${unpackType}(a_${name}, u_${name}_t);
|
|
8349
8664
|
#else
|
|
8350
8665
|
${precision} ${type} ${name} = u_${name};
|
|
8351
8666
|
#endif
|
|
8352
8667
|
`;
|
|
8353
|
-
else if (operation === "define") return `
|
|
8668
|
+
} else if (operation === "define") return `
|
|
8354
8669
|
#ifndef HAS_UNIFORM_u_${name}
|
|
8355
8670
|
uniform lowp float u_${name}_t;
|
|
8356
8671
|
layout(location = ${locationCounter++}) in ${precision} ${attrType} a_${name};
|
|
@@ -9736,10 +10051,18 @@ var MercatorTransform = class MercatorTransform {
|
|
|
9736
10051
|
const elevation = terrain ? terrain.getElevationForLngLatZoom(center, this._helper._tileZoom) : 0;
|
|
9737
10052
|
this._helper.recalculateZoomAndCenter(elevation);
|
|
9738
10053
|
}
|
|
9739
|
-
|
|
9740
|
-
|
|
10054
|
+
/**
|
|
10055
|
+
* Moves the center so that `lnglat`, on the ground at `elevation` meters, renders
|
|
10056
|
+
* at the screen `point`. Both rays are cast through the same inverse pixel matrix
|
|
10057
|
+
* so its inversion error cancels out of their difference; the current-center ray
|
|
10058
|
+
* must be intersected at the center's own elevation (z=0) — intersecting it with
|
|
10059
|
+
* the elevated plane would land `(elevation - centerElevation)·tan(pitch)` away
|
|
10060
|
+
* from the center and make repeated calls drift.
|
|
10061
|
+
*/
|
|
10062
|
+
setLocationAtPoint(lnglat, point, elevation = this.elevation) {
|
|
10063
|
+
const z = elevation - this.elevation;
|
|
9741
10064
|
const a = this.screenPointToMercatorCoordinateAtZ(point, z);
|
|
9742
|
-
const b = this.screenPointToMercatorCoordinateAtZ(this.centerPoint,
|
|
10065
|
+
const b = this.screenPointToMercatorCoordinateAtZ(this.centerPoint, 0);
|
|
9743
10066
|
const loc = MercatorCoordinate.fromLngLat(lnglat);
|
|
9744
10067
|
const newCenter = new MercatorCoordinate(loc.x - (a.x - b.x), loc.y - (a.y - b.y));
|
|
9745
10068
|
this.setCenter(newCenter?.toLngLat());
|
|
@@ -9751,6 +10074,9 @@ var MercatorTransform = class MercatorTransform {
|
|
|
9751
10074
|
screenPointToLocation(p, terrain) {
|
|
9752
10075
|
return this.screenPointToMercatorCoordinate(p, terrain)?.toLngLat();
|
|
9753
10076
|
}
|
|
10077
|
+
screenPointToLocationAtElevation(p, elevation) {
|
|
10078
|
+
return this.screenPointToMercatorCoordinateAtZ(p, elevation - this.elevation)?.toLngLat();
|
|
10079
|
+
}
|
|
9754
10080
|
screenPointToMercatorCoordinate(p, terrain) {
|
|
9755
10081
|
if (terrain) {
|
|
9756
10082
|
const coordinate = terrain.pointCoordinate(p);
|
|
@@ -9758,8 +10084,12 @@ var MercatorTransform = class MercatorTransform {
|
|
|
9758
10084
|
}
|
|
9759
10085
|
return this.screenPointToMercatorCoordinateAtZ(p);
|
|
9760
10086
|
}
|
|
9761
|
-
|
|
9762
|
-
|
|
10087
|
+
/**
|
|
10088
|
+
* Intersects the ray through a screen point with the horizontal plane at `z`,
|
|
10089
|
+
* given in meters relative to the plane at the center's elevation (not mercator units).
|
|
10090
|
+
*/
|
|
10091
|
+
screenPointToMercatorCoordinateAtZ(p, z) {
|
|
10092
|
+
const targetZ = z ? z : 0;
|
|
9763
10093
|
const coord0 = [
|
|
9764
10094
|
p.x,
|
|
9765
10095
|
p.y,
|
|
@@ -10118,21 +10448,22 @@ function cameraBoundsWarning() {
|
|
|
10118
10448
|
* Set a transform's rotation to a value interpolated between startEulerAngles and endEulerAngles
|
|
10119
10449
|
*/
|
|
10120
10450
|
function updateRotation(args) {
|
|
10121
|
-
if (args.useSlerp)
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
|
|
10129
|
-
|
|
10451
|
+
if (args.useSlerp) {
|
|
10452
|
+
if (args.k < 1) {
|
|
10453
|
+
const startRotation = rollPitchBearingToQuat(args.startEulerAngles.roll, args.startEulerAngles.pitch, args.startEulerAngles.bearing);
|
|
10454
|
+
const endRotation = rollPitchBearingToQuat(args.endEulerAngles.roll, args.endEulerAngles.pitch, args.endEulerAngles.bearing);
|
|
10455
|
+
const rotation = /* @__PURE__ */ new Float64Array(4);
|
|
10456
|
+
slerp(rotation, startRotation, endRotation, args.k);
|
|
10457
|
+
const eulerAngles = getRollPitchBearing(rotation);
|
|
10458
|
+
args.tr.setRoll(eulerAngles.roll);
|
|
10459
|
+
args.tr.setPitch(eulerAngles.pitch);
|
|
10460
|
+
args.tr.setBearing(eulerAngles.bearing);
|
|
10461
|
+
} else {
|
|
10462
|
+
args.tr.setRoll(args.endEulerAngles.roll);
|
|
10463
|
+
args.tr.setPitch(args.endEulerAngles.pitch);
|
|
10464
|
+
args.tr.setBearing(args.endEulerAngles.bearing);
|
|
10465
|
+
}
|
|
10130
10466
|
} else {
|
|
10131
|
-
args.tr.setRoll(args.endEulerAngles.roll);
|
|
10132
|
-
args.tr.setPitch(args.endEulerAngles.pitch);
|
|
10133
|
-
args.tr.setBearing(args.endEulerAngles.bearing);
|
|
10134
|
-
}
|
|
10135
|
-
else {
|
|
10136
10467
|
args.tr.setRoll(interpolateFactory.number(args.startEulerAngles.roll, args.endEulerAngles.roll, args.k));
|
|
10137
10468
|
args.tr.setPitch(interpolateFactory.number(args.startEulerAngles.pitch, args.endEulerAngles.pitch, args.k));
|
|
10138
10469
|
args.tr.setBearing(interpolateFactory.number(args.startEulerAngles.bearing, args.endEulerAngles.bearing, args.k));
|
|
@@ -10197,7 +10528,7 @@ var MercatorCameraHelper = class {
|
|
|
10197
10528
|
}
|
|
10198
10529
|
handleMapControlsPan(deltas, tr, preZoomAroundLoc) {
|
|
10199
10530
|
if (deltas.around.distSqr(tr.centerPoint) < .01) return;
|
|
10200
|
-
tr.setLocationAtPoint(preZoomAroundLoc, deltas.around);
|
|
10531
|
+
tr.setLocationAtPoint(preZoomAroundLoc, deltas.around, deltas.aroundElevation);
|
|
10201
10532
|
}
|
|
10202
10533
|
cameraForBoxAndBearing(options, padding, bounds, bearing, tr) {
|
|
10203
10534
|
return cameraForBoxAndBearing(options, padding, bounds, bearing, tr);
|
|
@@ -10613,6 +10944,145 @@ function sphereSurfacePointToCoordinates(surface) {
|
|
|
10613
10944
|
} else return new LngLat(0, latDegrees);
|
|
10614
10945
|
}
|
|
10615
10946
|
/**
|
|
10947
|
+
* Returns the globe orientation quaternion for the given map center and bearing.
|
|
10948
|
+
* The inverse of {@link lngLatBearingFromOrientation}.
|
|
10949
|
+
*/
|
|
10950
|
+
function orientationFromLngLatBearing(lngLat, bearing) {
|
|
10951
|
+
return fromEuler(createVec4f64(), -lngLat.lng, -lngLat.lat, bearing);
|
|
10952
|
+
}
|
|
10953
|
+
/**
|
|
10954
|
+
* Given a globe orientation quaternion, returns the corresponding map center and bearing.
|
|
10955
|
+
* The inverse of {@link orientationFromLngLatBearing}.
|
|
10956
|
+
*/
|
|
10957
|
+
function lngLatBearingFromOrientation(q) {
|
|
10958
|
+
const x = q[0], y = q[1], z = q[2], w = q[3];
|
|
10959
|
+
return {
|
|
10960
|
+
lng: -Math.atan2(2 * (w * x + y * z), 1 - 2 * (x * x + y * y)) * 180 / Math.PI,
|
|
10961
|
+
lat: -Math.asin(clamp(2 * (w * y - z * x), -1, 1)) * 180 / Math.PI,
|
|
10962
|
+
bearing: Math.atan2(2 * (w * z + x * y), 1 - 2 * (y * y + z * z)) * 180 / Math.PI
|
|
10963
|
+
};
|
|
10964
|
+
}
|
|
10965
|
+
/** Kept just below a half turn so the center cannot land exactly on the far side of the globe. */
|
|
10966
|
+
const PAN_MAX_ANGLE = Math.PI * .98;
|
|
10967
|
+
/**
|
|
10968
|
+
* Returns the point on the globe that a drag towards `point` should aim at.
|
|
10969
|
+
*
|
|
10970
|
+
* Exact tracking breaks down at the silhouette: the ray meets the globe at `asin(D sin a) - a`,
|
|
10971
|
+
* whose slope runs away to infinity as the ray goes tangent, and past it there is no intersection
|
|
10972
|
+
* at all. So the exact curve is left {@link PAN_FALLOFF_BAND} early and continued with a hyperbola
|
|
10973
|
+
* matching it in value and slope, easing off and saturating short of the far side. Bell's virtual
|
|
10974
|
+
* trackball takes the same idea of easing a sphere into a hyperbola before the rim, though it fits
|
|
10975
|
+
* the curve differently: SGI's `trackball.c`, described in Henriksen, Sporring and Hornbæk,
|
|
10976
|
+
* "Virtual Trackballs Revisited", IEEE TVCG 10(2):206-216, 2004.
|
|
10977
|
+
*
|
|
10978
|
+
* The angle comes from atan2, so a ray pointing away from the globe is a wide angle the falloff
|
|
10979
|
+
* saturates rather than a case to reject.
|
|
10980
|
+
* @param tr - The transform being dragged.
|
|
10981
|
+
* @param point - The cursor position.
|
|
10982
|
+
*/
|
|
10983
|
+
function panSurfaceLocation(tr, point) {
|
|
10984
|
+
const origin = tr.cameraPosition;
|
|
10985
|
+
const distance = length$1(origin);
|
|
10986
|
+
if (distance <= 1) return tr.screenPointToLocation(point);
|
|
10987
|
+
const u = createVec3f64();
|
|
10988
|
+
normalize(u, origin);
|
|
10989
|
+
const direction = tr.getRayDirectionFromPixel(point);
|
|
10990
|
+
const c = -dot(direction, u);
|
|
10991
|
+
const lateral = createVec3f64();
|
|
10992
|
+
scaleAndAdd(lateral, direction, u, c);
|
|
10993
|
+
const s = length$1(lateral);
|
|
10994
|
+
if (s < 1e-9) return tr.screenPointToLocation(point);
|
|
10995
|
+
const angle = Math.atan2(s, c);
|
|
10996
|
+
const handoverAngle = Math.asin(1 / distance) * .9;
|
|
10997
|
+
if (angle < handoverAngle) return tr.screenPointToLocation(point);
|
|
10998
|
+
const sinHandover = distance * Math.sin(handoverAngle);
|
|
10999
|
+
const targetAtHandover = Math.asin(clamp(sinHandover, -1, 1)) - handoverAngle;
|
|
11000
|
+
const slopeAtHandover = distance * Math.cos(handoverAngle) / Math.sqrt(Math.max(1 - sinHandover * sinHandover, 1e-12)) - 1;
|
|
11001
|
+
const room = PAN_MAX_ANGLE - targetAtHandover;
|
|
11002
|
+
const excess = angle - handoverAngle;
|
|
11003
|
+
const target = targetAtHandover + room * (slopeAtHandover * excess) / (room + slopeAtHandover * excess);
|
|
11004
|
+
const e = createVec3f64();
|
|
11005
|
+
scale$2(e, lateral, 1 / s);
|
|
11006
|
+
const surface = createVec3f64();
|
|
11007
|
+
scale$2(surface, u, Math.cos(clamp(target, 0, PAN_MAX_ANGLE)));
|
|
11008
|
+
scaleAndAdd(surface, surface, e, Math.sin(clamp(target, 0, PAN_MAX_ANGLE)));
|
|
11009
|
+
normalize(surface, surface);
|
|
11010
|
+
return sphereSurfacePointToCoordinates(surface);
|
|
11011
|
+
}
|
|
11012
|
+
/**
|
|
11013
|
+
* Rotates the globe so that the given location appears at the given screen point, by composing
|
|
11014
|
+
* versors, the unit quaternions that represent rotations. Unlike the bearing-preserving
|
|
11015
|
+
* {@link ITransform.setLocationAtPoint}, this stays smooth near and across the poles, and keeps
|
|
11016
|
+
* panning once the cursor leaves the globe.
|
|
11017
|
+
*
|
|
11018
|
+
* Note: the delta rotation's axis is in the surface-vector frame of
|
|
11019
|
+
* {@link angularCoordinatesToSurfaceVector}, while the orientation quaternion uses the Euler frame
|
|
11020
|
+
* of {@link orientationFromLngLatBearing}, hence the component swizzle where they combine. Zoom is
|
|
11021
|
+
* adjusted to keep the planet the same size, as `setLocationAtPoint` does.
|
|
11022
|
+
* @param tr - The transform to rotate.
|
|
11023
|
+
* @param lnglat - The location to bring under `point`.
|
|
11024
|
+
* @param point - The screen point that `lnglat` should appear at.
|
|
11025
|
+
* @param panDelta - The drag's pixel delta. Used to re-derive the previous cursor location through
|
|
11026
|
+
* {@link panSurfaceLocation}, since both ends of the rotation must come from the same mapping.
|
|
11027
|
+
* @param fixedBearing - Applies the swing only, keeping the bearing fixed, which is what dragging
|
|
11028
|
+
* the globe does. Pass `false` to apply the twist about the view axis as well, so that the grabbed
|
|
11029
|
+
* location tracks the cursor exactly and the bearing drifts with it.
|
|
11030
|
+
*/
|
|
11031
|
+
function versorSetLocationAtPoint(tr, lnglat, point, panDelta, fixedBearing = true) {
|
|
11032
|
+
const pointLngLat = panSurfaceLocation(tr, point);
|
|
11033
|
+
let sourceLngLat = lnglat;
|
|
11034
|
+
if (panDelta) sourceLngLat = panSurfaceLocation(tr, point.sub(panDelta));
|
|
11035
|
+
else if (!tr.isPointOnMapSurface(point)) return;
|
|
11036
|
+
const vecToPixelCurrent = angularCoordinatesToSurfaceVector(pointLngLat);
|
|
11037
|
+
const vecToTarget = angularCoordinatesToSurfaceVector(sourceLngLat);
|
|
11038
|
+
const centerQuat = orientationFromLngLatBearing(tr.center, tr.bearing);
|
|
11039
|
+
const w = cross(createVec3f64(), vecToTarget, vecToPixelCurrent);
|
|
11040
|
+
const l = Math.sqrt(dot(w, w));
|
|
11041
|
+
const t = Math.acos(clamp(dot(vecToTarget, vecToPixelCurrent), -1, 1)) / 2;
|
|
11042
|
+
const s = Math.sin(t);
|
|
11043
|
+
const delta = l ? fromValues(w[1] / l * s, -w[0] / l * s, w[2] / l * s, Math.cos(t)) : fromValues(0, 0, 0, 1);
|
|
11044
|
+
const { lng: newCenterLng, lat: newCenterLat, bearing: newBearing } = lngLatBearingFromOrientation(multiply$1(createVec4f64(), centerQuat, delta));
|
|
11045
|
+
const oldLat = tr.center.lat;
|
|
11046
|
+
const finalLat = clamp(newCenterLat, -90, 90);
|
|
11047
|
+
const finalLng = fixedBearing ? fixedBearingLongitude(tr, point, panDelta, newCenterLng) : newCenterLng;
|
|
11048
|
+
tr.setCenter(new LngLat(wrap(finalLng, -180, 180), finalLat));
|
|
11049
|
+
if (!fixedBearing) tr.setBearing(newBearing);
|
|
11050
|
+
tr.setZoom(tr.zoom + getZoomAdjustment(oldLat, tr.center.lat));
|
|
11051
|
+
}
|
|
11052
|
+
/**
|
|
11053
|
+
* Returns the center longitude for a bearing-preserving drag.
|
|
11054
|
+
*
|
|
11055
|
+
* The swing longitude becomes ill-conditioned near the pole and the grabbed location slips away
|
|
11056
|
+
* from the cursor, so within the last ~12 degrees of latitude the cursor is treated as turning a
|
|
11057
|
+
* dial around the pole, blended in with a smoothstep anchored on {@link MAX_VALID_LATITUDE}, the
|
|
11058
|
+
* highest latitude the center can reach. The sweep comes from the raw pixel delta rather than a
|
|
11059
|
+
* round-tripped previous cursor position, which would lose its sign to cancellation at the pole,
|
|
11060
|
+
* and is damped within {@link DIAL_MIN_RADIUS_PIXELS} so it eases to nothing there instead of
|
|
11061
|
+
* being dropped, which would leave a spot where the drag could not move at all.
|
|
11062
|
+
* @param tr - The transform being dragged.
|
|
11063
|
+
* @param point - The cursor position.
|
|
11064
|
+
* @param panDelta - The drag's pixel delta, or undefined to use the swing longitude only.
|
|
11065
|
+
* @param newCenterLng - The swing target longitude.
|
|
11066
|
+
* @returns the center longitude to apply.
|
|
11067
|
+
*/
|
|
11068
|
+
function fixedBearingLongitude(tr, point, panDelta, newCenterLng) {
|
|
11069
|
+
const oldLng = tr.center.lng;
|
|
11070
|
+
const oldLat = tr.center.lat;
|
|
11071
|
+
const poleLat = oldLat >= 0 ? 90 : -90;
|
|
11072
|
+
const polePoint = tr.locationToScreenPoint(new LngLat(0, poleLat));
|
|
11073
|
+
const rx = point.x - polePoint.x, ry = point.y - polePoint.y;
|
|
11074
|
+
const r2 = rx * rx + ry * ry;
|
|
11075
|
+
const tRamp = clamp(1 - (MAX_VALID_LATITUDE - Math.abs(oldLat)) / 12, 0, 1);
|
|
11076
|
+
const dial = tRamp * tRamp * (3 - 2 * tRamp);
|
|
11077
|
+
const dLngSwing = mod(newCenterLng - oldLng + 180, 360) - 180;
|
|
11078
|
+
let dLngDial = 0;
|
|
11079
|
+
if (dial > 0 && panDelta) {
|
|
11080
|
+
const dTheta = (rx * panDelta.y - ry * panDelta.x) / Math.max(r2, 400);
|
|
11081
|
+
dLngDial = (poleLat > 0 ? 1 : -1) * dTheta * 180 / Math.PI;
|
|
11082
|
+
}
|
|
11083
|
+
return oldLng + (1 - dial) * dLngSwing + dial * dLngDial;
|
|
11084
|
+
}
|
|
11085
|
+
/**
|
|
10616
11086
|
* Given a normalized horizon plane in Ax+By+Cz+D=0 format, compute the center and radius of
|
|
10617
11087
|
* the circle in that plain that contains the entire visible portion of the unit sphere from horizon
|
|
10618
11088
|
* to horizon.
|
|
@@ -11674,7 +12144,7 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
|
|
|
11674
12144
|
* Note: automatically adjusts zoom to keep planet size consistent
|
|
11675
12145
|
* (same size before and after a {@link setLocationAtPoint} call).
|
|
11676
12146
|
*/
|
|
11677
|
-
setLocationAtPoint(lnglat, point) {
|
|
12147
|
+
setLocationAtPoint(lnglat, point, _elevation) {
|
|
11678
12148
|
const vecToPixelCurrent = angularCoordinatesToSurfaceVector(this.unprojectScreenPoint(point));
|
|
11679
12149
|
const vecToTarget = angularCoordinatesToSurfaceVector(lnglat);
|
|
11680
12150
|
const zero = createVec3f64();
|
|
@@ -11756,6 +12226,9 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
|
|
|
11756
12226
|
screenPointToLocation(p, terrain) {
|
|
11757
12227
|
return this.screenPointToMercatorCoordinate(p, terrain)?.toLngLat();
|
|
11758
12228
|
}
|
|
12229
|
+
screenPointToLocationAtElevation(p, _elevation) {
|
|
12230
|
+
return this.screenPointToLocation(p);
|
|
12231
|
+
}
|
|
11759
12232
|
isPointOnMapSurface(p, _terrain) {
|
|
11760
12233
|
const rayOrigin = this._cameraPosition;
|
|
11761
12234
|
const rayDirection = this.getRayDirectionFromPixel(p);
|
|
@@ -12236,13 +12709,13 @@ var GlobeTransform = class GlobeTransform {
|
|
|
12236
12709
|
* Note: automatically adjusts zoom to keep planet size consistent
|
|
12237
12710
|
* (same size before and after a {@link setLocationAtPoint} call).
|
|
12238
12711
|
*/
|
|
12239
|
-
setLocationAtPoint(lnglat, point) {
|
|
12712
|
+
setLocationAtPoint(lnglat, point, elevation) {
|
|
12240
12713
|
if (!this.isGlobeRendering) {
|
|
12241
|
-
this._mercatorTransform.setLocationAtPoint(lnglat, point);
|
|
12714
|
+
this._mercatorTransform.setLocationAtPoint(lnglat, point, elevation);
|
|
12242
12715
|
this.apply(this._mercatorTransform, false);
|
|
12243
12716
|
return;
|
|
12244
12717
|
}
|
|
12245
|
-
this._verticalPerspectiveTransform.setLocationAtPoint(lnglat, point);
|
|
12718
|
+
this._verticalPerspectiveTransform.setLocationAtPoint(lnglat, point, elevation);
|
|
12246
12719
|
this.apply(this._verticalPerspectiveTransform, false);
|
|
12247
12720
|
}
|
|
12248
12721
|
locationToScreenPoint(lnglat, terrain) {
|
|
@@ -12254,6 +12727,9 @@ var GlobeTransform = class GlobeTransform {
|
|
|
12254
12727
|
screenPointToLocation(p, terrain) {
|
|
12255
12728
|
return this.currentTransform.screenPointToLocation(p, terrain);
|
|
12256
12729
|
}
|
|
12730
|
+
screenPointToLocationAtElevation(p, elevation) {
|
|
12731
|
+
return this.currentTransform.screenPointToLocationAtElevation(p, elevation);
|
|
12732
|
+
}
|
|
12257
12733
|
isPointOnMapSurface(p, terrain) {
|
|
12258
12734
|
return this.currentTransform.isPointOnMapSurface(p, terrain);
|
|
12259
12735
|
}
|
|
@@ -12277,6 +12753,35 @@ var GlobeTransform = class GlobeTransform {
|
|
|
12277
12753
|
//#endregion
|
|
12278
12754
|
//#region src/geo/projection/vertical_perspective_camera_helper.ts
|
|
12279
12755
|
/**
|
|
12756
|
+
* Zoom movement slowing starts when the mouse ray passes further than this above the planet surface,
|
|
12757
|
+
* so a cursor off the globe does not move the map unnaturally. Globe radius is 1, so 0.3 is ~2000 km.
|
|
12758
|
+
*/
|
|
12759
|
+
const RAY_SURFACE_DISTANCE_FOR_SLOWING_START = .3;
|
|
12760
|
+
/** How sharply zoom movement slows as the mouse ray rises above the planet surface. Lower is more gradual. */
|
|
12761
|
+
const SLOWING_MULTIPLIER = .5;
|
|
12762
|
+
/** Longitude difference between zoom location and map center at which the blend from exact to heuristic zooming starts, in degrees. */
|
|
12763
|
+
const INTERPOLATE_TO_HEURISTIC_START_LNG = 45;
|
|
12764
|
+
/** Longitude difference at which the blend to heuristic zooming is complete, in degrees. */
|
|
12765
|
+
const INTERPOLATE_TO_HEURISTIC_END_LNG = 85;
|
|
12766
|
+
/** Exponent applied to the blend factor: below 1, so the blend leans towards heuristic zooming and flattens as it completes. */
|
|
12767
|
+
const INTERPOLATE_TO_HEURISTIC_EXPONENT = .25;
|
|
12768
|
+
/**
|
|
12769
|
+
* Distance of the mouse ray from the globe center at which the blend from exact to heuristic zooming
|
|
12770
|
+
* starts. Globe radius is 1, so 1 is a ray grazing the horizon.
|
|
12771
|
+
*/
|
|
12772
|
+
const INTERPOLATE_TO_HEURISTIC_START_HORIZON = .95;
|
|
12773
|
+
/** Ray distance at which the blend to heuristic zooming is complete. */
|
|
12774
|
+
const INTERPOLATE_TO_HEURISTIC_END_HORIZON = .999;
|
|
12775
|
+
/**
|
|
12776
|
+
* Globe radius relative to the smaller viewport dimension below which zoom movement near the horizon
|
|
12777
|
+
* starts being inhibited, avoiding unnatural movements when the map is zoomed out a lot.
|
|
12778
|
+
*/
|
|
12779
|
+
const SLOWING_RADIUS_START = .9;
|
|
12780
|
+
/** Globe radius relative to the smaller viewport dimension at which that inhibition is at full strength. */
|
|
12781
|
+
const SLOWING_RADIUS_STOP = .5;
|
|
12782
|
+
/** Fraction of the zoom movement that remains once the globe has shrunk to `SLOWING_RADIUS_STOP`. */
|
|
12783
|
+
const SLOWING_RADIUS_SLOW_FACTOR = .25;
|
|
12784
|
+
/**
|
|
12280
12785
|
* @internal
|
|
12281
12786
|
*/
|
|
12282
12787
|
var VerticalPerspectiveCameraHelper = class VerticalPerspectiveCameraHelper {
|
|
@@ -12291,6 +12796,13 @@ var VerticalPerspectiveCameraHelper = class VerticalPerspectiveCameraHelper {
|
|
|
12291
12796
|
easingOffset: new Point(0, 0)
|
|
12292
12797
|
};
|
|
12293
12798
|
}
|
|
12799
|
+
/**
|
|
12800
|
+
* Zooms around the pointer.
|
|
12801
|
+
*
|
|
12802
|
+
* `setLocationAtPoint` is exact but degenerates when called repeatedly for a
|
|
12803
|
+
* location whose longitude is far from the center's, or one near the horizon,
|
|
12804
|
+
* so those cases blend towards a heuristic.
|
|
12805
|
+
*/
|
|
12294
12806
|
handleMapControlsRollPitchBearingZoom(deltas, tr) {
|
|
12295
12807
|
const zoomPixel = deltas.around;
|
|
12296
12808
|
const zoomLoc = tr.screenPointToLocation(zoomPixel);
|
|
@@ -12301,16 +12813,6 @@ var VerticalPerspectiveCameraHelper = class VerticalPerspectiveCameraHelper {
|
|
|
12301
12813
|
if (deltas.zoomDelta) tr.setZoom(tr.zoom + deltas.zoomDelta);
|
|
12302
12814
|
const actualZoomDelta = tr.zoom - oldZoomPreZoomDelta;
|
|
12303
12815
|
if (actualZoomDelta === 0) return;
|
|
12304
|
-
const raySurfaceDistanceForSlowingStart = .3;
|
|
12305
|
-
const slowingMultiplier = .5;
|
|
12306
|
-
const interpolateToHeuristicStartLng = 45;
|
|
12307
|
-
const interpolateToHeuristicEndLng = 85;
|
|
12308
|
-
const interpolateToHeuristicExponent = .25;
|
|
12309
|
-
const interpolateToHeuristicStartRadius = .75;
|
|
12310
|
-
const interpolateToHeuristicEndRadius = .35;
|
|
12311
|
-
const slowingRadiusStart = .9;
|
|
12312
|
-
const slowingRadiusStop = .5;
|
|
12313
|
-
const slowingRadiusSlowFactor = .25;
|
|
12314
12816
|
const dLngRaw = differenceOfAnglesDegrees(tr.center.lng, zoomLoc.lng);
|
|
12315
12817
|
const dLng = dLngRaw / (Math.abs(dLngRaw / 180) + 1);
|
|
12316
12818
|
const dLat = differenceOfAnglesDegrees(tr.center.lat, zoomLoc.lat);
|
|
@@ -12323,30 +12825,37 @@ var VerticalPerspectiveCameraHelper = class VerticalPerspectiveCameraHelper {
|
|
|
12323
12825
|
rayDirection[1] * distanceToClosestPoint,
|
|
12324
12826
|
rayDirection[2] * distanceToClosestPoint
|
|
12325
12827
|
]);
|
|
12326
|
-
const
|
|
12327
|
-
const
|
|
12828
|
+
const rayDistanceFromGlobeCenter = length$1(closestPoint);
|
|
12829
|
+
const distanceFromSurface = rayDistanceFromGlobeCenter - 1;
|
|
12830
|
+
const distanceFactor = Math.exp(-Math.max(distanceFromSurface - RAY_SURFACE_DISTANCE_FOR_SLOWING_START, 0) * SLOWING_MULTIPLIER);
|
|
12831
|
+
const interpolationFactorHorizon = remapSaturate(rayDistanceFromGlobeCenter, INTERPOLATE_TO_HEURISTIC_START_HORIZON, INTERPOLATE_TO_HEURISTIC_END_HORIZON, 0, 1);
|
|
12328
12832
|
const radius = getGlobeRadiusPixels(tr.worldSize, tr.center.lat) / Math.min(tr.width, tr.height);
|
|
12329
|
-
const radiusFactor = remapSaturate(radius,
|
|
12330
|
-
const
|
|
12833
|
+
const radiusFactor = remapSaturate(radius, SLOWING_RADIUS_START, SLOWING_RADIUS_STOP, 1, SLOWING_RADIUS_SLOW_FACTOR);
|
|
12834
|
+
const slowingFactor = Math.min(distanceFactor, lerp(1, radiusFactor, interpolationFactorHorizon));
|
|
12835
|
+
const factor = (1 - zoomScale(-actualZoomDelta)) * slowingFactor;
|
|
12331
12836
|
const oldCenterLat = tr.center.lat;
|
|
12332
12837
|
const oldZoom = tr.zoom;
|
|
12333
12838
|
const heuristicCenter = new LngLat(tr.center.lng + dLng * factor, clamp(tr.center.lat + dLat * factor, -MAX_VALID_LATITUDE, MAX_VALID_LATITUDE));
|
|
12334
12839
|
tr.setLocationAtPoint(zoomLoc, zoomPixel);
|
|
12335
12840
|
const exactCenter = tr.center;
|
|
12336
|
-
const interpolationFactorLongitude = remapSaturate(Math.abs(dLngRaw),
|
|
12337
|
-
const
|
|
12338
|
-
const heuristicFactor = Math.pow(Math.max(interpolationFactorLongitude, interpolationFactorRadius), interpolateToHeuristicExponent);
|
|
12841
|
+
const interpolationFactorLongitude = remapSaturate(Math.abs(dLngRaw), INTERPOLATE_TO_HEURISTIC_START_LNG, INTERPOLATE_TO_HEURISTIC_END_LNG, 0, 1);
|
|
12842
|
+
const heuristicFactor = Math.pow(Math.max(interpolationFactorLongitude, interpolationFactorHorizon), INTERPOLATE_TO_HEURISTIC_EXPONENT);
|
|
12339
12843
|
const lngExactToHeuristic = differenceOfAnglesDegrees(exactCenter.lng, heuristicCenter.lng);
|
|
12340
12844
|
const latExactToHeuristic = differenceOfAnglesDegrees(exactCenter.lat, heuristicCenter.lat);
|
|
12341
12845
|
tr.setCenter(new LngLat(exactCenter.lng + lngExactToHeuristic * heuristicFactor, exactCenter.lat + latExactToHeuristic * heuristicFactor).wrap());
|
|
12342
12846
|
tr.setZoom(oldZoom + getZoomAdjustment(oldCenterLat, tr.center.lat));
|
|
12343
12847
|
}
|
|
12344
|
-
|
|
12848
|
+
/**
|
|
12849
|
+
* Pans the globe by rotating it with a single quaternion that brings the grabbed location back
|
|
12850
|
+
* under the cursor. This stays consistent near and across the poles, where the previous
|
|
12851
|
+
* bearing-preserving mapping inverted and stalled (#5296).
|
|
12852
|
+
* @param deltas - The deltas accumulated for this frame.
|
|
12853
|
+
* @param tr - The transform to pan.
|
|
12854
|
+
* @param preZoomAroundLoc - The location that was under the cursor before this frame.
|
|
12855
|
+
*/
|
|
12856
|
+
handleMapControlsPan(deltas, tr, preZoomAroundLoc) {
|
|
12345
12857
|
if (!deltas.panDelta) return;
|
|
12346
|
-
|
|
12347
|
-
const oldZoom = tr.zoom;
|
|
12348
|
-
tr.setCenter(computeGlobePanCenter(deltas.panDelta, tr).wrap());
|
|
12349
|
-
tr.setZoom(oldZoom + getZoomAdjustment(oldLat, tr.center.lat));
|
|
12858
|
+
versorSetLocationAtPoint(tr, preZoomAroundLoc, deltas.around, deltas.panDelta);
|
|
12350
12859
|
}
|
|
12351
12860
|
cameraForBoxAndBearing(options, padding, bounds, bearing, tr) {
|
|
12352
12861
|
const result = cameraForBoxAndBearing(options, padding, bounds, bearing, tr);
|
|
@@ -12679,6 +13188,7 @@ var Style = class extends Evented {
|
|
|
12679
13188
|
this.imageManager = new ImageManager();
|
|
12680
13189
|
this.imageManager.setEventedParent(this);
|
|
12681
13190
|
this.imageManager.setMissingImageResolver(map._missingStyleImageResolver);
|
|
13191
|
+
this.patternAtlas = new PatternAtlas(this.imageManager);
|
|
12682
13192
|
const glyphLang = map._container?.lang || typeof document !== "undefined" && document.documentElement?.lang || void 0;
|
|
12683
13193
|
this.glyphManager = new GlyphManager(map._requestManager, options.localIdeographFontFamily, glyphLang);
|
|
12684
13194
|
this.lineAtlas = new LineAtlas(256, 512);
|
|
@@ -12700,12 +13210,10 @@ var Style = class extends Evented {
|
|
|
12700
13210
|
});
|
|
12701
13211
|
}
|
|
12702
13212
|
_setInitialValues() {
|
|
12703
|
-
this._spritesImagesIds = {};
|
|
12704
13213
|
this._layers = {};
|
|
12705
13214
|
this._order = [];
|
|
12706
13215
|
this.tileManagers = {};
|
|
12707
13216
|
this.zoomHistory = new ZoomHistory();
|
|
12708
|
-
this._availableImages = [];
|
|
12709
13217
|
this._imagesListDirty = false;
|
|
12710
13218
|
this._globalState = {};
|
|
12711
13219
|
this._serializedLayers = {};
|
|
@@ -12843,48 +13351,33 @@ var Style = class extends Evented {
|
|
|
12843
13351
|
}
|
|
12844
13352
|
}
|
|
12845
13353
|
}
|
|
12846
|
-
_loadSprite(sprite, isUpdate = false, completion = void 0) {
|
|
13354
|
+
async _loadSprite(sprite, isUpdate = false, completion = void 0) {
|
|
12847
13355
|
this.imageManager.setLoaded(false);
|
|
12848
13356
|
const abortController = new AbortController();
|
|
12849
13357
|
this._spriteRequest = abortController;
|
|
12850
13358
|
let err;
|
|
12851
|
-
|
|
12852
|
-
this.
|
|
12853
|
-
if (images)
|
|
12854
|
-
|
|
12855
|
-
const
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
this._changedImages[id] = true;
|
|
12859
|
-
}
|
|
12860
|
-
for (const id in images[spriteId]) {
|
|
12861
|
-
const imageId = spriteId === "default" ? id : `${spriteId}:${id}`;
|
|
12862
|
-
this._spritesImagesIds[spriteId].push(imageId);
|
|
12863
|
-
if (imageId in this.imageManager.images) this.imageManager.updateImage(imageId, images[spriteId][id], false);
|
|
12864
|
-
else this.imageManager.addImage(imageId, images[spriteId][id]);
|
|
12865
|
-
if (isUpdate) this._changedImages[imageId] = true;
|
|
12866
|
-
}
|
|
13359
|
+
try {
|
|
13360
|
+
const images = await loadSprite(sprite, this.map._requestManager, this.map.getPixelRatio(), abortController);
|
|
13361
|
+
if (!images) return;
|
|
13362
|
+
for (const spriteId in images) {
|
|
13363
|
+
const { loaded, removed } = this.imageManager.setSpriteImages(spriteId, images[spriteId]);
|
|
13364
|
+
this._markImagesChanged(removed);
|
|
13365
|
+
if (isUpdate) this._markImagesChanged(loaded);
|
|
12867
13366
|
}
|
|
12868
|
-
}
|
|
12869
|
-
this._spriteRequest = null;
|
|
13367
|
+
} catch (error) {
|
|
12870
13368
|
err = error;
|
|
12871
13369
|
if (!abortController.signal.aborted) this.fire(new ErrorEvent(err));
|
|
12872
|
-
}
|
|
13370
|
+
} finally {
|
|
13371
|
+
this._spriteRequest = null;
|
|
12873
13372
|
this.imageManager.setLoaded(true);
|
|
12874
|
-
this._availableImages = this.imageManager.listImages();
|
|
12875
13373
|
if (isUpdate) this._changed = true;
|
|
12876
|
-
this.dispatcher.broadcast("SI", this.
|
|
13374
|
+
this.dispatcher.broadcast("SI", this.imageManager.listImages());
|
|
12877
13375
|
this.fire(new MapStyleDataEvent("data"));
|
|
12878
|
-
|
|
12879
|
-
}
|
|
13376
|
+
completion?.(err);
|
|
13377
|
+
}
|
|
12880
13378
|
}
|
|
12881
13379
|
_unloadSprite() {
|
|
12882
|
-
|
|
12883
|
-
this.imageManager.removeImage(id);
|
|
12884
|
-
this._changedImages[id] = true;
|
|
12885
|
-
}
|
|
12886
|
-
this._spritesImagesIds = {};
|
|
12887
|
-
this._availableImages = this.imageManager.listImages();
|
|
13380
|
+
this._markImagesChanged(this.imageManager.removeAllSpriteImages());
|
|
12888
13381
|
this._imagesListDirty = true;
|
|
12889
13382
|
this._changed = true;
|
|
12890
13383
|
this.fire(new MapStyleDataEvent("data"));
|
|
@@ -12956,7 +13449,7 @@ var Style = class extends Evented {
|
|
|
12956
13449
|
const changed = this._changed;
|
|
12957
13450
|
if (changed) {
|
|
12958
13451
|
if (this._imagesListDirty) {
|
|
12959
|
-
this.dispatcher.broadcast("SI", this.
|
|
13452
|
+
this.dispatcher.broadcast("SI", this.imageManager.listImages());
|
|
12960
13453
|
this._imagesListDirty = false;
|
|
12961
13454
|
}
|
|
12962
13455
|
const updatedIds = Object.keys(this._updatedLayers);
|
|
@@ -12981,9 +13474,10 @@ var Style = class extends Evented {
|
|
|
12981
13474
|
managersUsedBefore[id] = tileManager.used;
|
|
12982
13475
|
tileManager.used = false;
|
|
12983
13476
|
}
|
|
13477
|
+
const availableImages = this.imageManager.listImages();
|
|
12984
13478
|
for (const layerId of this._order) {
|
|
12985
13479
|
const layer = this._layers[layerId];
|
|
12986
|
-
layer.recalculate(parameters,
|
|
13480
|
+
layer.recalculate(parameters, availableImages);
|
|
12987
13481
|
if (!layer.isHidden(parameters.zoom) && layer.source) this.tileManagers[layer.source].used = true;
|
|
12988
13482
|
}
|
|
12989
13483
|
for (const id in managersUsedBefore) {
|
|
@@ -13145,8 +13639,14 @@ var Style = class extends Evented {
|
|
|
13145
13639
|
this.imageManager.removeImage(id);
|
|
13146
13640
|
this._afterImageUpdated(id);
|
|
13147
13641
|
}
|
|
13642
|
+
/**
|
|
13643
|
+
* Queues the tiles that depend on these images to be reloaded on the next update, which is
|
|
13644
|
+
* needed whenever an image appears, disappears or changes size.
|
|
13645
|
+
*/
|
|
13646
|
+
_markImagesChanged(ids) {
|
|
13647
|
+
for (const id of ids) this._changedImages[id] = true;
|
|
13648
|
+
}
|
|
13148
13649
|
_afterImageUpdated(id) {
|
|
13149
|
-
this._availableImages = this.imageManager.listImages();
|
|
13150
13650
|
this._changedImages[id] = true;
|
|
13151
13651
|
this._imagesListDirty = true;
|
|
13152
13652
|
this._changed = true;
|
|
@@ -13579,7 +14079,7 @@ var Style = class extends Evented {
|
|
|
13579
14079
|
}
|
|
13580
14080
|
}
|
|
13581
14081
|
const sourceResults = [];
|
|
13582
|
-
params.availableImages = this.
|
|
14082
|
+
params.availableImages = this.imageManager.listImages();
|
|
13583
14083
|
const serializedLayers = this._serializedAllLayers();
|
|
13584
14084
|
const layersAsSet = params.layers instanceof Set ? params.layers : Array.isArray(params.layers) ? new Set(params.layers) : null;
|
|
13585
14085
|
const paramsStrict = {
|
|
@@ -13816,14 +14316,10 @@ var Style = class extends Evented {
|
|
|
13816
14316
|
this.fire(new ErrorEvent(/* @__PURE__ */ new Error(`Sprite "${id}" doesn't exists on this map.`)));
|
|
13817
14317
|
return;
|
|
13818
14318
|
}
|
|
13819
|
-
|
|
13820
|
-
|
|
13821
|
-
this._changedImages[imageId] = true;
|
|
13822
|
-
}
|
|
14319
|
+
const changedImages = this.imageManager.removeSpriteImages(id);
|
|
14320
|
+
this._markImagesChanged(changedImages);
|
|
13823
14321
|
internalSpriteRepresentation.splice(internalSpriteRepresentation.findIndex((sprite) => sprite.id === id), 1);
|
|
13824
14322
|
this.stylesheet.sprite = internalSpriteRepresentation.length > 0 ? internalSpriteRepresentation : void 0;
|
|
13825
|
-
delete this._spritesImagesIds[id];
|
|
13826
|
-
this._availableImages = this.imageManager.listImages();
|
|
13827
14323
|
this._imagesListDirty = true;
|
|
13828
14324
|
this._changed = true;
|
|
13829
14325
|
this.fire(new MapStyleDataEvent("data"));
|
|
@@ -13878,8 +14374,7 @@ var Style = class extends Evented {
|
|
|
13878
14374
|
if (this.imageManager) {
|
|
13879
14375
|
this.imageManager.setEventedParent(null);
|
|
13880
14376
|
this.imageManager.destroy();
|
|
13881
|
-
this.
|
|
13882
|
-
this._spritesImagesIds = {};
|
|
14377
|
+
this.patternAtlas.destroy();
|
|
13883
14378
|
}
|
|
13884
14379
|
if (this.glyphManager) this.glyphManager.destroy();
|
|
13885
14380
|
for (const layerId in this._layers) {
|
|
@@ -14061,6 +14556,25 @@ function getTokenizedAttributesAndUniforms(array) {
|
|
|
14061
14556
|
}
|
|
14062
14557
|
return result;
|
|
14063
14558
|
}
|
|
14559
|
+
function getIntegerAttributeNames(gl, program) {
|
|
14560
|
+
const integerTypes = /* @__PURE__ */ new Set([
|
|
14561
|
+
gl.INT,
|
|
14562
|
+
gl.INT_VEC2,
|
|
14563
|
+
gl.INT_VEC3,
|
|
14564
|
+
gl.INT_VEC4,
|
|
14565
|
+
gl.UNSIGNED_INT,
|
|
14566
|
+
gl.UNSIGNED_INT_VEC2,
|
|
14567
|
+
gl.UNSIGNED_INT_VEC3,
|
|
14568
|
+
gl.UNSIGNED_INT_VEC4
|
|
14569
|
+
]);
|
|
14570
|
+
const names = /* @__PURE__ */ new Set();
|
|
14571
|
+
const numActiveAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
|
|
14572
|
+
for (let i = 0; i < numActiveAttributes; i++) {
|
|
14573
|
+
const attribute = gl.getActiveAttrib(program, i);
|
|
14574
|
+
if (attribute && integerTypes.has(attribute.type)) names.add(attribute.name);
|
|
14575
|
+
}
|
|
14576
|
+
return names;
|
|
14577
|
+
}
|
|
14064
14578
|
/**
|
|
14065
14579
|
* @internal
|
|
14066
14580
|
* A webgl program to execute in the GPU space
|
|
@@ -14108,14 +14622,17 @@ var Program = class {
|
|
|
14108
14622
|
this.attributes = {};
|
|
14109
14623
|
const uniformLocations = {};
|
|
14110
14624
|
this.numAttributes = allAttrInfo.length;
|
|
14111
|
-
for (let i = 0; i < this.numAttributes; i++) if (allAttrInfo[i]) this.attributes[allAttrInfo[i]] = i;
|
|
14112
14625
|
gl.linkProgram(this.program);
|
|
14113
|
-
for (const name in this.attributes) {
|
|
14114
|
-
const actual = gl.getAttribLocation(this.program, name);
|
|
14115
|
-
if (actual >= 0) this.attributes[name] = actual;
|
|
14116
|
-
else delete this.attributes[name];
|
|
14117
|
-
}
|
|
14118
14626
|
if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) throw new Error(`Program failed to link: ${gl.getProgramInfoLog(this.program)}`);
|
|
14627
|
+
const integerAttributeNames = getIntegerAttributeNames(gl, this.program);
|
|
14628
|
+
for (const name of allAttrInfo) {
|
|
14629
|
+
if (!name) continue;
|
|
14630
|
+
const location = gl.getAttribLocation(this.program, name);
|
|
14631
|
+
if (location >= 0) this.attributes[name] = {
|
|
14632
|
+
location,
|
|
14633
|
+
isInteger: integerAttributeNames.has(name)
|
|
14634
|
+
};
|
|
14635
|
+
}
|
|
14119
14636
|
gl.deleteShader(vertexShader);
|
|
14120
14637
|
gl.deleteShader(fragmentShader);
|
|
14121
14638
|
for (const uniform of allUniformsInfo) if (uniform && !uniformLocations[uniform]) {
|
|
@@ -14188,9 +14705,9 @@ function patternUniformValues(crossfade, painter, tile) {
|
|
|
14188
14705
|
};
|
|
14189
14706
|
}
|
|
14190
14707
|
function bgPatternUniformValues(image, crossfade, painter, tile) {
|
|
14191
|
-
const imagePosA = painter.
|
|
14192
|
-
const imagePosB = painter.
|
|
14193
|
-
const { width, height } = painter.
|
|
14708
|
+
const imagePosA = painter.patternAtlas.getPattern(image.from.toString());
|
|
14709
|
+
const imagePosB = painter.patternAtlas.getPattern(image.to.toString());
|
|
14710
|
+
const { width, height } = painter.patternAtlas.getPixelSize();
|
|
14194
14711
|
const numTiles = Math.pow(2, tile.tileID.overscaledZ);
|
|
14195
14712
|
const tileSizeAtNearestZoom = tile.tileSize * Math.pow(2, painter.transform.tileZoom) / numTiles;
|
|
14196
14713
|
const pixelX = tileSizeAtNearestZoom * (tile.tileID.canonical.x + tile.tileID.wrap * numTiles);
|
|
@@ -14615,66 +15132,6 @@ const layerOpacityUniformValues = (opacity, textureUnit) => ({
|
|
|
14615
15132
|
"u_opacity": opacity
|
|
14616
15133
|
});
|
|
14617
15134
|
//#endregion
|
|
14618
|
-
//#region src/webgl/program/raster_program.ts
|
|
14619
|
-
const rasterUniforms = (context, locations) => ({
|
|
14620
|
-
"u_tl_parent": new Uniform2f(context, locations.u_tl_parent),
|
|
14621
|
-
"u_scale_parent": new Uniform1f(context, locations.u_scale_parent),
|
|
14622
|
-
"u_buffer_scale": new Uniform1f(context, locations.u_buffer_scale),
|
|
14623
|
-
"u_fade_t": new Uniform1f(context, locations.u_fade_t),
|
|
14624
|
-
"u_opacity": new Uniform1f(context, locations.u_opacity),
|
|
14625
|
-
"u_image0": new Uniform1i(context, locations.u_image0),
|
|
14626
|
-
"u_image1": new Uniform1i(context, locations.u_image1),
|
|
14627
|
-
"u_brightness_low": new Uniform1f(context, locations.u_brightness_low),
|
|
14628
|
-
"u_brightness_high": new Uniform1f(context, locations.u_brightness_high),
|
|
14629
|
-
"u_saturation_factor": new Uniform1f(context, locations.u_saturation_factor),
|
|
14630
|
-
"u_contrast_factor": new Uniform1f(context, locations.u_contrast_factor),
|
|
14631
|
-
"u_spin_weights": new Uniform3f(context, locations.u_spin_weights),
|
|
14632
|
-
"u_coords_top": new Uniform4f(context, locations.u_coords_top),
|
|
14633
|
-
"u_coords_bottom": new Uniform4f(context, locations.u_coords_bottom)
|
|
14634
|
-
});
|
|
14635
|
-
const rasterUniformValues = (parentTL, parentScaleBy, fade, layer, cornerCoords) => ({
|
|
14636
|
-
"u_tl_parent": parentTL,
|
|
14637
|
-
"u_scale_parent": parentScaleBy,
|
|
14638
|
-
"u_buffer_scale": 1,
|
|
14639
|
-
"u_fade_t": fade.mix,
|
|
14640
|
-
"u_opacity": fade.opacity * layer.paint.get("raster-opacity"),
|
|
14641
|
-
"u_image0": 0,
|
|
14642
|
-
"u_image1": 1,
|
|
14643
|
-
"u_brightness_low": layer.paint.get("raster-brightness-min"),
|
|
14644
|
-
"u_brightness_high": layer.paint.get("raster-brightness-max"),
|
|
14645
|
-
"u_saturation_factor": saturationFactor(layer.paint.get("raster-saturation")),
|
|
14646
|
-
"u_contrast_factor": contrastFactor(layer.paint.get("raster-contrast")),
|
|
14647
|
-
"u_spin_weights": spinWeights(layer.paint.get("raster-hue-rotate")),
|
|
14648
|
-
"u_coords_top": [
|
|
14649
|
-
cornerCoords[0].x,
|
|
14650
|
-
cornerCoords[0].y,
|
|
14651
|
-
cornerCoords[1].x,
|
|
14652
|
-
cornerCoords[1].y
|
|
14653
|
-
],
|
|
14654
|
-
"u_coords_bottom": [
|
|
14655
|
-
cornerCoords[3].x,
|
|
14656
|
-
cornerCoords[3].y,
|
|
14657
|
-
cornerCoords[2].x,
|
|
14658
|
-
cornerCoords[2].y
|
|
14659
|
-
]
|
|
14660
|
-
});
|
|
14661
|
-
function spinWeights(angle) {
|
|
14662
|
-
angle *= Math.PI / 180;
|
|
14663
|
-
const s = Math.sin(angle);
|
|
14664
|
-
const c = Math.cos(angle);
|
|
14665
|
-
return [
|
|
14666
|
-
(2 * c + 1) / 3,
|
|
14667
|
-
(-Math.sqrt(3) * s - c + 1) / 3,
|
|
14668
|
-
(Math.sqrt(3) * s - c + 1) / 3
|
|
14669
|
-
];
|
|
14670
|
-
}
|
|
14671
|
-
function contrastFactor(contrast) {
|
|
14672
|
-
return contrast > 0 ? 1 / (1 - contrast) : 1 + contrast;
|
|
14673
|
-
}
|
|
14674
|
-
function saturationFactor(saturation) {
|
|
14675
|
-
return saturation > 0 ? 1 - 1 / (1.001 - saturation) : -saturation;
|
|
14676
|
-
}
|
|
14677
|
-
//#endregion
|
|
14678
15135
|
//#region src/webgl/program/symbol_program.ts
|
|
14679
15136
|
const symbolIconUniforms = (context, locations) => ({
|
|
14680
15137
|
"u_is_size_zoom_constant": new Uniform1i(context, locations.u_is_size_zoom_constant),
|
|
@@ -14983,8 +15440,8 @@ var VertexBuffer = class {
|
|
|
14983
15440
|
}
|
|
14984
15441
|
enableAttributes(gl, program) {
|
|
14985
15442
|
for (const member of this.attributes) {
|
|
14986
|
-
const
|
|
14987
|
-
if (
|
|
15443
|
+
const attribute = program.attributes[member.name];
|
|
15444
|
+
if (attribute !== void 0) gl.enableVertexAttribArray(attribute.location);
|
|
14988
15445
|
}
|
|
14989
15446
|
}
|
|
14990
15447
|
/**
|
|
@@ -14995,8 +15452,12 @@ var VertexBuffer = class {
|
|
|
14995
15452
|
*/
|
|
14996
15453
|
setVertexAttribPointers(gl, program, vertexOffset) {
|
|
14997
15454
|
for (const member of this.attributes) {
|
|
14998
|
-
const
|
|
14999
|
-
if (
|
|
15455
|
+
const attribute = program.attributes[member.name];
|
|
15456
|
+
if (attribute !== void 0) {
|
|
15457
|
+
const offset = member.offset + this.itemSize * (vertexOffset || 0);
|
|
15458
|
+
if (attribute.isInteger) gl.vertexAttribIPointer(attribute.location, member.components, gl[AttributeType[member.type]], this.itemSize, offset);
|
|
15459
|
+
else gl.vertexAttribPointer(attribute.location, member.components, gl[AttributeType[member.type]], false, this.itemSize, offset);
|
|
15460
|
+
}
|
|
15000
15461
|
}
|
|
15001
15462
|
}
|
|
15002
15463
|
/**
|
|
@@ -15624,6 +16085,24 @@ var Context = class {
|
|
|
15624
16085
|
this.pixelStoreUnpackPremultiplyAlpha.dirty = true;
|
|
15625
16086
|
this.pixelStoreUnpackFlipY.dirty = true;
|
|
15626
16087
|
}
|
|
16088
|
+
/**
|
|
16089
|
+
* Reset some GL state to default values before handing users the raw context, as we do for
|
|
16090
|
+
* custom layers and WebGL style images, to avoid hard-to-debug bugs in their code.
|
|
16091
|
+
*
|
|
16092
|
+
* MapLibre restores all of its own state afterwards, so the only state worth resetting first
|
|
16093
|
+
* is state users would be surprised to find dirty: `CULL_FACE`, `TEXTURE0` and the three
|
|
16094
|
+
* `UNPACK_` settings, whose defaults are meaningful enough that most code assumes them.
|
|
16095
|
+
* The vertex array is unbound rather than reset, so that MapLibre never has to track it and
|
|
16096
|
+
* a user's `vertexAttribPointer` calls cannot land on one of ours.
|
|
16097
|
+
*/
|
|
16098
|
+
setCustomLayerDefaults() {
|
|
16099
|
+
this.unbindVAO();
|
|
16100
|
+
this.cullFace.setDefault();
|
|
16101
|
+
this.activeTexture.setDefault();
|
|
16102
|
+
this.pixelStoreUnpack.setDefault();
|
|
16103
|
+
this.pixelStoreUnpackPremultiplyAlpha.setDefault();
|
|
16104
|
+
this.pixelStoreUnpackFlipY.setDefault();
|
|
16105
|
+
}
|
|
15627
16106
|
createIndexBuffer(array, dynamicDraw) {
|
|
15628
16107
|
return new IndexBuffer(this, array, dynamicDraw);
|
|
15629
16108
|
}
|
|
@@ -16032,9 +16511,10 @@ function drawLayerSymbols(painter, tileManager, layer, coords, isText, translate
|
|
|
16032
16511
|
const uLabelPlaneMatrix = alongLine || shaderVariableAnchor ? identityMat4 : combinedLabelPlaneMatrix;
|
|
16033
16512
|
const hasHalo = isSDF && layer.paint.get(isText ? "text-halo-width" : "icon-halo-width").constantOr(1) !== 0;
|
|
16034
16513
|
let uniformValues;
|
|
16035
|
-
if (isSDF)
|
|
16036
|
-
|
|
16037
|
-
|
|
16514
|
+
if (isSDF) {
|
|
16515
|
+
if (!bucket.iconsInText) uniformValues = symbolSDFUniformValues(sizeData.kind, size, rotateInShader, pitchWithMap, alongLine, shaderVariableAnchor, painter, uLabelPlaneMatrix, glCoordMatrixForShader, translation, isText, texSize, hasHalo, pitchedTextRescaling, isOffset);
|
|
16516
|
+
else uniformValues = symbolTextAndIconUniformValues(sizeData.kind, size, rotateInShader, pitchWithMap, alongLine, shaderVariableAnchor, painter, uLabelPlaneMatrix, glCoordMatrixForShader, translation, texSize, texSizeIcon, pitchedTextRescaling, isOffset);
|
|
16517
|
+
} else uniformValues = symbolIconUniformValues(sizeData.kind, size, rotateInShader, pitchWithMap, alongLine, shaderVariableAnchor, painter, uLabelPlaneMatrix, glCoordMatrixForShader, translation, isText, texSize, pitchedTextRescaling, isOffset);
|
|
16038
16518
|
const state = {
|
|
16039
16519
|
program,
|
|
16040
16520
|
buffers,
|
|
@@ -16719,13 +17199,15 @@ function drawHillshade(painter, tileManager, layer, tileIDs, renderOptions) {
|
|
|
16719
17199
|
painter.width,
|
|
16720
17200
|
painter.height
|
|
16721
17201
|
]);
|
|
16722
|
-
} else if (painter.renderPass === "translucent")
|
|
16723
|
-
|
|
16724
|
-
|
|
16725
|
-
|
|
16726
|
-
|
|
16727
|
-
|
|
16728
|
-
|
|
17202
|
+
} else if (painter.renderPass === "translucent") {
|
|
17203
|
+
if (useSubdivision) {
|
|
17204
|
+
const [stencilBorderless, stencilBorders, coords] = painter.stencilConfigForOverlapTwoPass(tileIDs);
|
|
17205
|
+
renderHillshade(painter, tileManager, layer, coords, stencilBorderless, depthMode, colorMode, false, isRenderingToTexture);
|
|
17206
|
+
renderHillshade(painter, tileManager, layer, coords, stencilBorders, depthMode, colorMode, true, isRenderingToTexture);
|
|
17207
|
+
} else {
|
|
17208
|
+
const [stencil, coords] = painter.getStencilConfigForOverlapAndUpdateStencilID(tileIDs);
|
|
17209
|
+
renderHillshade(painter, tileManager, layer, coords, stencil, depthMode, colorMode, false, isRenderingToTexture);
|
|
17210
|
+
}
|
|
16729
17211
|
}
|
|
16730
17212
|
}
|
|
16731
17213
|
function renderHillshade(painter, tileManager, layer, coords, stencilModes, depthMode, colorMode, useBorder, isRenderingToTexture) {
|
|
@@ -16882,17 +17364,17 @@ function drawRaster(painter, tileManager, layer, tileIDs, renderOptions) {
|
|
|
16882
17364
|
const { isRenderingToTexture } = renderOptions;
|
|
16883
17365
|
const source = tileManager.getSource();
|
|
16884
17366
|
const useSubdivision = painter.style.projection.useSubdivision;
|
|
16885
|
-
if (source instanceof ImageSource) drawTiles(painter, tileManager, layer, tileIDs, null, false, false, source.tileCoords, source.flippedWindingOrder, isRenderingToTexture);
|
|
17367
|
+
if (source instanceof ImageSource) drawTiles(painter, tileManager, layer, tileIDs, null, false, false, source.tileCoords, source.perspectiveTransform, source.flippedWindingOrder, isRenderingToTexture);
|
|
16886
17368
|
else if (useSubdivision) {
|
|
16887
17369
|
const [stencilBorderless, stencilBorders, coords] = painter.stencilConfigForOverlapTwoPass(tileIDs);
|
|
16888
|
-
drawTiles(painter, tileManager, layer, coords, stencilBorderless, false, true, cornerCoords, false, isRenderingToTexture);
|
|
16889
|
-
drawTiles(painter, tileManager, layer, coords, stencilBorders, true, true, cornerCoords, false, isRenderingToTexture);
|
|
17370
|
+
drawTiles(painter, tileManager, layer, coords, stencilBorderless, false, true, cornerCoords, identityPerspectiveTransform, false, isRenderingToTexture);
|
|
17371
|
+
drawTiles(painter, tileManager, layer, coords, stencilBorders, true, true, cornerCoords, identityPerspectiveTransform, false, isRenderingToTexture);
|
|
16890
17372
|
} else {
|
|
16891
17373
|
const [stencil, coords] = painter.getStencilConfigForOverlapAndUpdateStencilID(tileIDs);
|
|
16892
|
-
drawTiles(painter, tileManager, layer, coords, stencil, false, true, cornerCoords, false, isRenderingToTexture);
|
|
17374
|
+
drawTiles(painter, tileManager, layer, coords, stencil, false, true, cornerCoords, identityPerspectiveTransform, false, isRenderingToTexture);
|
|
16893
17375
|
}
|
|
16894
17376
|
}
|
|
16895
|
-
function drawTiles(painter, tileManager, layer, coords, stencilModes, useBorder, allowPoles, corners, flipCullfaceMode = false, isRenderingToTexture = false) {
|
|
17377
|
+
function drawTiles(painter, tileManager, layer, coords, stencilModes, useBorder, allowPoles, corners, perspectiveTransform, flipCullfaceMode = false, isRenderingToTexture = false) {
|
|
16896
17378
|
const minTileZ = coords[coords.length - 1].overscaledZ;
|
|
16897
17379
|
const context = painter.context;
|
|
16898
17380
|
const gl = context.gl;
|
|
@@ -16925,7 +17407,7 @@ function drawTiles(painter, tileManager, layer, coords, stencilModes, useBorder,
|
|
|
16925
17407
|
applyGlobeMatrix: !isRenderingToTexture,
|
|
16926
17408
|
applyTerrainMatrix: true
|
|
16927
17409
|
});
|
|
16928
|
-
const uniformValues = rasterUniformValues(parentTopLeft, parentScaleBy, fadeValues.fadeMix, layer, corners);
|
|
17410
|
+
const uniformValues = rasterUniformValues(parentTopLeft, parentScaleBy, fadeValues.fadeMix, layer, corners, perspectiveTransform);
|
|
16929
17411
|
const mesh = projection.getMeshFromTileID(context, coord.canonical, useBorder, allowPoles, "raster");
|
|
16930
17412
|
const stencilMode = stencilModes ? stencilModes[coord.overscaledZ] : StencilMode.disabled;
|
|
16931
17413
|
program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, flipCullfaceMode ? CullFaceMode.frontCCW : CullFaceMode.backCCW, uniformValues, terrainData, projectionData, layer.id, mesh.vertexBuffer, mesh.indexBuffer, mesh.segments);
|
|
@@ -17028,7 +17510,7 @@ function drawBackground(painter, tileManager, layer, coords, renderOptions) {
|
|
|
17028
17510
|
});
|
|
17029
17511
|
if (image) {
|
|
17030
17512
|
context.activeTexture.set(gl.TEXTURE0);
|
|
17031
|
-
painter.
|
|
17513
|
+
painter.patternAtlas.bind(painter.context);
|
|
17032
17514
|
}
|
|
17033
17515
|
const crossfade = layer.getCrossfadeParameters();
|
|
17034
17516
|
for (const tileID of tileIDs) {
|
|
@@ -17709,6 +18191,7 @@ var Painter = class Painter {
|
|
|
17709
18191
|
this.options = options;
|
|
17710
18192
|
this.lineAtlas = style.lineAtlas;
|
|
17711
18193
|
this.imageManager = style.imageManager;
|
|
18194
|
+
this.patternAtlas = style.patternAtlas;
|
|
17712
18195
|
this.glyphManager = style.glyphManager;
|
|
17713
18196
|
this.symbolFadeChange = style.placement.symbolFadeChange(now());
|
|
17714
18197
|
this.imageManager.beginFrame();
|
|
@@ -17916,8 +18399,8 @@ var Painter = class Painter {
|
|
|
17916
18399
|
isPatternMissing(image) {
|
|
17917
18400
|
if (!image) return false;
|
|
17918
18401
|
if (!image.from || !image.to) return true;
|
|
17919
|
-
const imagePosA = this.
|
|
17920
|
-
const imagePosB = this.
|
|
18402
|
+
const imagePosA = this.patternAtlas.getPattern(image.from.toString());
|
|
18403
|
+
const imagePosB = this.patternAtlas.getPattern(image.to.toString());
|
|
17921
18404
|
return !imagePosA || !imagePosB;
|
|
17922
18405
|
}
|
|
17923
18406
|
/**
|
|
@@ -17945,12 +18428,7 @@ var Painter = class Painter {
|
|
|
17945
18428
|
return this.cache[key];
|
|
17946
18429
|
}
|
|
17947
18430
|
setCustomLayerDefaults() {
|
|
17948
|
-
this.context.
|
|
17949
|
-
this.context.cullFace.setDefault();
|
|
17950
|
-
this.context.activeTexture.setDefault();
|
|
17951
|
-
this.context.pixelStoreUnpack.setDefault();
|
|
17952
|
-
this.context.pixelStoreUnpackPremultiplyAlpha.setDefault();
|
|
17953
|
-
this.context.pixelStoreUnpackFlipY.setDefault();
|
|
18431
|
+
this.context.setCustomLayerDefaults();
|
|
17954
18432
|
}
|
|
17955
18433
|
setBaseState() {
|
|
17956
18434
|
const gl = this.context.gl;
|
|
@@ -18105,7 +18583,7 @@ var Hash = class {
|
|
|
18105
18583
|
location = location.replace("&&", "&");
|
|
18106
18584
|
window.history.replaceState(window.history.state, null, location);
|
|
18107
18585
|
};
|
|
18108
|
-
this._updateHash = throttle(this._updateHashUnthrottled,
|
|
18586
|
+
this._updateHash = throttle(this._updateHashUnthrottled, 300);
|
|
18109
18587
|
this._hashName = hashName && encodeURIComponent(hashName);
|
|
18110
18588
|
}
|
|
18111
18589
|
/**
|
|
@@ -18183,6 +18661,14 @@ const defaultRollInertiaOptions = extend({
|
|
|
18183
18661
|
deceleration: 1e3,
|
|
18184
18662
|
maxSpeed: 360
|
|
18185
18663
|
}, defaultInertiaOptions);
|
|
18664
|
+
/**
|
|
18665
|
+
* The maximum age of a recorded gesture update, in milliseconds.
|
|
18666
|
+
*/
|
|
18667
|
+
const BUFFER_CUTOFF = 160;
|
|
18668
|
+
/**
|
|
18669
|
+
* The time window the gesture velocity is measured over, in milliseconds.
|
|
18670
|
+
*/
|
|
18671
|
+
const VELOCITY_WINDOW = 60;
|
|
18186
18672
|
var HandlerInertia = class {
|
|
18187
18673
|
constructor(map) {
|
|
18188
18674
|
this._map = map;
|
|
@@ -18199,12 +18685,41 @@ var HandlerInertia = class {
|
|
|
18199
18685
|
});
|
|
18200
18686
|
}
|
|
18201
18687
|
_drainInertiaBuffer() {
|
|
18202
|
-
const inertia = this._inertiaBuffer, currentTime = now()
|
|
18203
|
-
while (inertia.length > 0 && currentTime - inertia[0].time >
|
|
18688
|
+
const inertia = this._inertiaBuffer, currentTime = now();
|
|
18689
|
+
while (inertia.length > 0 && currentTime - inertia[0].time > BUFFER_CUTOFF) inertia.shift();
|
|
18690
|
+
}
|
|
18691
|
+
/**
|
|
18692
|
+
* Returns the entries the velocity is measured from: everything recorded within
|
|
18693
|
+
* {@link VELOCITY_WINDOW} before now, but never fewer than the last two, so that
|
|
18694
|
+
* inertia also works below two recorded updates per window.
|
|
18695
|
+
*/
|
|
18696
|
+
_getVelocityEntries() {
|
|
18697
|
+
const inertia = this._inertiaBuffer;
|
|
18698
|
+
const windowStart = now() - VELOCITY_WINDOW;
|
|
18699
|
+
let firstIndex = Math.max(0, inertia.length - 2);
|
|
18700
|
+
while (firstIndex > 0 && inertia[firstIndex - 1].time >= windowStart) firstIndex--;
|
|
18701
|
+
return inertia.slice(firstIndex);
|
|
18204
18702
|
}
|
|
18703
|
+
/**
|
|
18704
|
+
* Returns the ease which continues the gesture that has just ended.
|
|
18705
|
+
*
|
|
18706
|
+
* The velocity is measured over the time up to the release and not up to the last
|
|
18707
|
+
* recorded movement, so that a gesture held still before being released has a lower
|
|
18708
|
+
* velocity, down to no inertia at all. The delta of an entry happened before it was
|
|
18709
|
+
* recorded, so the first entry only marks the start of the measured interval; anchors
|
|
18710
|
+
* are the exception, as they describe the state at the moment of their entry.
|
|
18711
|
+
*
|
|
18712
|
+
* @param panInertiaOptions - overrides for the pan inertia defaults
|
|
18713
|
+
* @returns the ease options, or `undefined` when the measured interval holds no
|
|
18714
|
+
* movement, which terrain gestures produce by recording updates without any delta
|
|
18715
|
+
*/
|
|
18205
18716
|
_onMoveEnd(panInertiaOptions) {
|
|
18206
18717
|
this._drainInertiaBuffer();
|
|
18207
|
-
|
|
18718
|
+
const entries = this._getVelocityEntries();
|
|
18719
|
+
if (entries.length < 2) {
|
|
18720
|
+
this.clear();
|
|
18721
|
+
return;
|
|
18722
|
+
}
|
|
18208
18723
|
const deltas = {
|
|
18209
18724
|
zoom: 0,
|
|
18210
18725
|
bearing: 0,
|
|
@@ -18214,16 +18729,22 @@ var HandlerInertia = class {
|
|
|
18214
18729
|
pinchAround: void 0,
|
|
18215
18730
|
around: void 0
|
|
18216
18731
|
};
|
|
18217
|
-
for (const { settings } of
|
|
18732
|
+
for (const { settings } of entries) {
|
|
18733
|
+
if (settings.around) deltas.around = settings.around;
|
|
18734
|
+
if (settings.pinchAround) deltas.pinchAround = settings.pinchAround;
|
|
18735
|
+
}
|
|
18736
|
+
for (const { settings } of entries.slice(1)) {
|
|
18218
18737
|
deltas.zoom += settings.zoomDelta || 0;
|
|
18219
18738
|
deltas.bearing += settings.bearingDelta || 0;
|
|
18220
18739
|
deltas.pitch += settings.pitchDelta || 0;
|
|
18221
18740
|
deltas.roll += settings.rollDelta || 0;
|
|
18222
18741
|
if (settings.panDelta) deltas.pan._add(settings.panDelta);
|
|
18223
|
-
if (settings.around) deltas.around = settings.around;
|
|
18224
|
-
if (settings.pinchAround) deltas.pinchAround = settings.pinchAround;
|
|
18225
18742
|
}
|
|
18226
|
-
|
|
18743
|
+
if (!deltas.pan.mag() && !deltas.zoom && !deltas.bearing && !deltas.pitch && !deltas.roll) {
|
|
18744
|
+
this.clear();
|
|
18745
|
+
return;
|
|
18746
|
+
}
|
|
18747
|
+
const duration = now() - entries[0].time;
|
|
18227
18748
|
const easeOptions = {};
|
|
18228
18749
|
if (deltas.pan.mag()) {
|
|
18229
18750
|
const result = calculateEasing(deltas.pan.mag(), duration, extend({}, defaultPanInertiaOptions, panInertiaOptions || {}));
|
|
@@ -20142,6 +20663,11 @@ var TransformProvider = class {
|
|
|
20142
20663
|
//#endregion
|
|
20143
20664
|
//#region src/ui/handler_manager.ts
|
|
20144
20665
|
const isMoving = (p) => p.zoom || p.drag || p.roll || p.pitch || p.rotate;
|
|
20666
|
+
/**
|
|
20667
|
+
* A terrain gesture's anchor plane must stay below this fraction of the camera's
|
|
20668
|
+
* altitude over the center-elevation plane, or the ray-plane solve degenerates.
|
|
20669
|
+
*/
|
|
20670
|
+
const TERRAIN_ANCHOR_MAX_CAMERA_ALTITUDE_FRACTION = .9;
|
|
20145
20671
|
var RenderFrameEvent = class extends Event {};
|
|
20146
20672
|
function hasChange(result) {
|
|
20147
20673
|
return result.panDelta?.mag() || result.zoomDelta || result.bearingDelta || result.pitchDelta || result.rollDelta;
|
|
@@ -20162,6 +20688,7 @@ var HandlerManager = class {
|
|
|
20162
20688
|
return this._el?.ownerDocument?.defaultView || window;
|
|
20163
20689
|
}
|
|
20164
20690
|
constructor(map, camera, options) {
|
|
20691
|
+
this._terrainGestureAnchorElevation = null;
|
|
20165
20692
|
this.handleWindowEvent = (e) => {
|
|
20166
20693
|
this.handleEvent(e, `${e.type}Window`);
|
|
20167
20694
|
};
|
|
@@ -20459,20 +20986,20 @@ var HandlerManager = class {
|
|
|
20459
20986
|
return;
|
|
20460
20987
|
}
|
|
20461
20988
|
this._camera.stop(true);
|
|
20462
|
-
|
|
20463
|
-
|
|
20464
|
-
|
|
20465
|
-
if (terrain && !tr.isPointOnMapSurface(around)) around = tr.centerPoint;
|
|
20989
|
+
const { panDelta, zoomDelta, bearingDelta, pitchDelta, rollDelta } = combinedResult;
|
|
20990
|
+
let { around, aroundOnSurface } = this._resolveAround(combinedResult, terrain, tr);
|
|
20991
|
+
const aroundElevation = terrain ? this._terrainGestureElevation(terrain, around, aroundOnSurface, tr, combinedEventsInProgress) : void 0;
|
|
20466
20992
|
const deltasForHelper = {
|
|
20467
20993
|
panDelta,
|
|
20468
20994
|
zoomDelta,
|
|
20469
20995
|
rollDelta,
|
|
20470
20996
|
pitchDelta,
|
|
20471
20997
|
bearingDelta,
|
|
20472
|
-
around
|
|
20998
|
+
around,
|
|
20999
|
+
aroundElevation
|
|
20473
21000
|
};
|
|
20474
21001
|
if (this._camera.cameraHelper.useGlobeControls && !tr.isPointOnMapSurface(around)) around = tr.centerPoint;
|
|
20475
|
-
const preZoomAroundLoc =
|
|
21002
|
+
const preZoomAroundLoc = this._computePreZoomAroundLoc(tr, around, panDelta, aroundElevation);
|
|
20476
21003
|
this._handleMapControls({
|
|
20477
21004
|
terrain,
|
|
20478
21005
|
tr,
|
|
@@ -20486,6 +21013,54 @@ var HandlerManager = class {
|
|
|
20486
21013
|
if (!combinedResult.noInertia) this._inertia.record(combinedResult);
|
|
20487
21014
|
this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true);
|
|
20488
21015
|
}
|
|
21016
|
+
/**
|
|
21017
|
+
* The gesture's anchor point: the pinch midpoint when pinching, otherwise the
|
|
21018
|
+
* pan's anchor, clamped to the center point when it does not lie on the map.
|
|
21019
|
+
*/
|
|
21020
|
+
_resolveAround(combinedResult, terrain, tr) {
|
|
21021
|
+
let around = combinedResult.pinchAround !== void 0 ? combinedResult.pinchAround : combinedResult.around;
|
|
21022
|
+
around ||= this._camera.transform.centerPoint;
|
|
21023
|
+
if (terrain && !tr.isPointOnMapSurface(around)) return {
|
|
21024
|
+
around: tr.centerPoint,
|
|
21025
|
+
aroundOnSurface: false
|
|
21026
|
+
};
|
|
21027
|
+
return {
|
|
21028
|
+
around,
|
|
21029
|
+
aroundOnSurface: true
|
|
21030
|
+
};
|
|
21031
|
+
}
|
|
21032
|
+
/**
|
|
21033
|
+
* The elevation of the plane a terrain gesture is solved on: the elevation of the
|
|
21034
|
+
* terrain point grabbed at gesture start, captured here on the gesture's first
|
|
21035
|
+
* frame. Undefined means the gesture is solved at the center's elevation instead —
|
|
21036
|
+
* when the grabbed terrain is not loaded, the anchor is the center point (a
|
|
21037
|
+
* center-point anchor is skipped by the camera helper and would lose the pan), or
|
|
21038
|
+
* the anchor plane is too close to the camera for a stable ray-plane solve.
|
|
21039
|
+
*/
|
|
21040
|
+
_terrainGestureElevation(terrain, around, aroundOnSurface, tr, combinedEventsInProgress) {
|
|
21041
|
+
if (!aroundOnSurface) return;
|
|
21042
|
+
if (!this._terrainMovement && (combinedEventsInProgress.drag || combinedEventsInProgress.zoom)) {
|
|
21043
|
+
const anchor = terrain.pointCoordinate(around);
|
|
21044
|
+
this._terrainGestureAnchorElevation = anchor ? anchor.z : null;
|
|
21045
|
+
}
|
|
21046
|
+
if (this._terrainGestureAnchorElevation === null) return;
|
|
21047
|
+
const elevation = this._terrainGestureAnchorElevation;
|
|
21048
|
+
if (around.distSqr(tr.centerPoint) < .01) return;
|
|
21049
|
+
if (elevation - tr.elevation >= TERRAIN_ANCHOR_MAX_CAMERA_ALTITUDE_FRACTION * (tr.getCameraAltitude() - tr.elevation)) return;
|
|
21050
|
+
return elevation;
|
|
21051
|
+
}
|
|
21052
|
+
/**
|
|
21053
|
+
* The location that was under `around` before this frame's deltas — the point the
|
|
21054
|
+
* camera helper re-anchors after zooming — solved at `aroundElevation` when a
|
|
21055
|
+
* terrain gesture provides one. When rotating about the center point, the
|
|
21056
|
+
* transform's center is used directly to avoid numerical issues near the horizon.
|
|
21057
|
+
*/
|
|
21058
|
+
_computePreZoomAroundLoc(tr, around, panDelta, aroundElevation) {
|
|
21059
|
+
if (around.distSqr(tr.centerPoint) < .01) return tr.center;
|
|
21060
|
+
const aroundPreviousPoint = panDelta ? around.sub(panDelta) : around;
|
|
21061
|
+
if (aroundElevation !== void 0) return tr.screenPointToLocationAtElevation(aroundPreviousPoint, aroundElevation);
|
|
21062
|
+
return tr.screenPointToLocation(aroundPreviousPoint);
|
|
21063
|
+
}
|
|
20489
21064
|
_handleMapControls({ terrain, tr, deltasForHelper, preZoomAroundLoc, combinedEventsInProgress, panDelta }) {
|
|
20490
21065
|
const cameraHelper = this._camera.cameraHelper;
|
|
20491
21066
|
cameraHelper.handleMapControlsRollPitchBearingZoom(deltasForHelper, tr);
|
|
@@ -20507,7 +21082,7 @@ var HandlerManager = class {
|
|
|
20507
21082
|
cameraHelper.handleMapControlsPan(deltasForHelper, tr, preZoomAroundLoc);
|
|
20508
21083
|
return;
|
|
20509
21084
|
}
|
|
20510
|
-
if (combinedEventsInProgress.drag && this._terrainMovement && panDelta) {
|
|
21085
|
+
if (deltasForHelper.aroundElevation === void 0 && combinedEventsInProgress.drag && this._terrainMovement && panDelta) {
|
|
20511
21086
|
tr.setCenter(tr.screenPointToLocation(tr.centerPoint.sub(panDelta)));
|
|
20512
21087
|
return;
|
|
20513
21088
|
}
|
|
@@ -20545,6 +21120,7 @@ var HandlerManager = class {
|
|
|
20545
21120
|
if (finishedMoving && this._terrainMovement) {
|
|
20546
21121
|
this._camera.elevationFreeze = false;
|
|
20547
21122
|
this._terrainMovement = false;
|
|
21123
|
+
this._terrainGestureAnchorElevation = null;
|
|
20548
21124
|
const tr = this._camera.getTransformForUpdate();
|
|
20549
21125
|
if (this._map.getCenterClampedToGround()) tr.recalculateZoomAndCenter(this._map.terrain);
|
|
20550
21126
|
this._camera.applyUpdatedTransform(tr);
|
|
@@ -21220,12 +21796,14 @@ var AttributionControl = class {
|
|
|
21220
21796
|
*/
|
|
21221
21797
|
constructor(options = defaultAttributionControlOptions) {
|
|
21222
21798
|
this._toggleAttribution = () => {
|
|
21223
|
-
if (this._container.classList.contains("maplibregl-compact"))
|
|
21224
|
-
this._container.
|
|
21225
|
-
|
|
21226
|
-
|
|
21227
|
-
|
|
21228
|
-
|
|
21799
|
+
if (this._container.classList.contains("maplibregl-compact")) {
|
|
21800
|
+
if (this._container.classList.contains("maplibregl-compact-show")) {
|
|
21801
|
+
this._container.setAttribute("open", "");
|
|
21802
|
+
this._container.classList.remove("maplibregl-compact-show");
|
|
21803
|
+
} else {
|
|
21804
|
+
this._container.classList.add("maplibregl-compact-show");
|
|
21805
|
+
this._container.removeAttribute("open");
|
|
21806
|
+
}
|
|
21229
21807
|
}
|
|
21230
21808
|
};
|
|
21231
21809
|
this._updateData = (e) => {
|
|
@@ -21850,8 +22428,10 @@ var Terrain = class {
|
|
|
21850
22428
|
if (cachedMatrix) return cachedMatrix;
|
|
21851
22429
|
const maxzoom = this.tileManager.getSource().maxzoom;
|
|
21852
22430
|
let dz = tileID.canonical.z - sourceTile.tileID.canonical.z;
|
|
21853
|
-
if (tileID.overscaledZ > tileID.canonical.z)
|
|
21854
|
-
|
|
22431
|
+
if (tileID.overscaledZ > tileID.canonical.z) {
|
|
22432
|
+
if (tileID.canonical.z >= maxzoom) dz = tileID.canonical.z - maxzoom;
|
|
22433
|
+
else warnOnce("cannot calculate elevation if elevation maxzoom > source.maxzoom");
|
|
22434
|
+
}
|
|
21855
22435
|
const dx = tileID.canonical.x - (tileID.canonical.x >> dz << dz);
|
|
21856
22436
|
const dy = tileID.canonical.y - (tileID.canonical.y >> dz << dz);
|
|
21857
22437
|
const demMatrix = fromScaling(/* @__PURE__ */ new Float64Array(16), [
|
|
@@ -22424,7 +23004,13 @@ var Map$1 = class extends Evented {
|
|
|
22424
23004
|
};
|
|
22425
23005
|
this._contextRestored = (event) => {
|
|
22426
23006
|
if (this._lostContextStyle.style) this.setStyle(this._lostContextStyle.style, { diff: false });
|
|
22427
|
-
if (this._lostContextStyle.images && this.style)
|
|
23007
|
+
if (this._lostContextStyle.images && this.style) {
|
|
23008
|
+
this.style.imageManager.images = this._lostContextStyle.images;
|
|
23009
|
+
for (const id in this._lostContextStyle.images) {
|
|
23010
|
+
const image = this._lostContextStyle.images[id];
|
|
23011
|
+
if (image.isWebGLImage) this.style.imageManager.updateImage(id, image, false);
|
|
23012
|
+
}
|
|
23013
|
+
}
|
|
22428
23014
|
this._lostContextStyle = {
|
|
22429
23015
|
style: null,
|
|
22430
23016
|
images: null
|
|
@@ -22606,8 +23192,10 @@ var Map$1 = class extends Evented {
|
|
|
22606
23192
|
* @see [Display map navigation controls](https://maplibre.org/maplibre-gl-js/docs/examples/display-map-navigation-controls/)
|
|
22607
23193
|
*/
|
|
22608
23194
|
addControl(control, position) {
|
|
22609
|
-
if (position === void 0)
|
|
22610
|
-
|
|
23195
|
+
if (position === void 0) {
|
|
23196
|
+
if (control.getDefaultPosition) position = control.getDefaultPosition();
|
|
23197
|
+
else position = "top-right";
|
|
23198
|
+
}
|
|
22611
23199
|
if (!control?.onAdd) return this.fire(new ErrorEvent(/* @__PURE__ */ new Error("Invalid argument to map.addControl(). Argument must be a control with onAdd and onRemove methods.")));
|
|
22612
23200
|
const controlElement = control.onAdd(this);
|
|
22613
23201
|
this._controls.push(control);
|
|
@@ -24501,8 +25089,12 @@ var Map$1 = class extends Evented {
|
|
|
24501
25089
|
} else {
|
|
24502
25090
|
const { width, height, data } = image;
|
|
24503
25091
|
const userImage = image;
|
|
25092
|
+
const isWebGLImage = isStyleImageWebGLData(userImage.data);
|
|
24504
25093
|
return {
|
|
24505
|
-
data: new RGBAImage({
|
|
25094
|
+
data: isWebGLImage ? new RGBAImage({
|
|
25095
|
+
width,
|
|
25096
|
+
height
|
|
25097
|
+
}) : new RGBAImage({
|
|
24506
25098
|
width,
|
|
24507
25099
|
height
|
|
24508
25100
|
}, new Uint8Array(data)),
|
|
@@ -24514,6 +25106,7 @@ var Map$1 = class extends Evented {
|
|
|
24514
25106
|
textFitHeight,
|
|
24515
25107
|
sdf,
|
|
24516
25108
|
version,
|
|
25109
|
+
isWebGLImage,
|
|
24517
25110
|
userImage
|
|
24518
25111
|
};
|
|
24519
25112
|
}
|
|
@@ -24544,8 +25137,12 @@ var Map$1 = class extends Evented {
|
|
|
24544
25137
|
const { width, height, data } = image instanceof HTMLImageElement || isImageBitmap(image) ? browser.getImageData(image) : image;
|
|
24545
25138
|
if (width === void 0 || height === void 0) return this.fire(new ErrorEvent(/* @__PURE__ */ new Error("Invalid arguments to map.updateImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, or object with `width`, `height`, and `data` properties with the same format as `ImageData`")));
|
|
24546
25139
|
if (width !== existingImage.data.width || height !== existingImage.data.height) return this.fire(new ErrorEvent(/* @__PURE__ */ new Error("The width and height of the updated image must be that same as the previous version of the image")));
|
|
24547
|
-
|
|
24548
|
-
existingImage.
|
|
25140
|
+
existingImage.isWebGLImage = isStyleImageWebGLData(data);
|
|
25141
|
+
if (existingImage.isWebGLImage) existingImage.userImage = image;
|
|
25142
|
+
else {
|
|
25143
|
+
const copy = !(image instanceof HTMLImageElement || isImageBitmap(image));
|
|
25144
|
+
existingImage.data.replace(data, copy);
|
|
25145
|
+
}
|
|
24549
25146
|
this.style.updateImage(id, existingImage);
|
|
24550
25147
|
return this;
|
|
24551
25148
|
}
|
|
@@ -25901,6 +26498,17 @@ function applyAnchorClass(element, anchor, prefix) {
|
|
|
25901
26498
|
//#endregion
|
|
25902
26499
|
//#region src/ui/marker.ts
|
|
25903
26500
|
/**
|
|
26501
|
+
* Screen-pixel deltas applied when a focused draggable marker is moved with the arrow keys.
|
|
26502
|
+
*/
|
|
26503
|
+
const ARROW_KEY_DELTAS = {
|
|
26504
|
+
ArrowLeft: [-1, 0],
|
|
26505
|
+
ArrowRight: [1, 0],
|
|
26506
|
+
ArrowUp: [0, -1],
|
|
26507
|
+
ArrowDown: [0, 1]
|
|
26508
|
+
};
|
|
26509
|
+
const KEYBOARD_DRAG_SMALL_STEP = 1;
|
|
26510
|
+
const KEYBOARD_DRAG_LARGE_STEP = 10;
|
|
26511
|
+
/**
|
|
25904
26512
|
* The event class for marker drag events (`dragstart`, `drag` and `dragend`).
|
|
25905
26513
|
*
|
|
25906
26514
|
* @group Event Related
|
|
@@ -25975,6 +26583,30 @@ var Marker = class extends Evented {
|
|
|
25975
26583
|
this._onKeyPress = (e) => {
|
|
25976
26584
|
if (e.code === "Space" || e.code === "Enter") this.togglePopup();
|
|
25977
26585
|
};
|
|
26586
|
+
this._onKeyDown = (e) => {
|
|
26587
|
+
if (!this._defaultMarker || !this._draggable || !this._map || !this._lngLat) return;
|
|
26588
|
+
if (e.composedPath()[0] !== this._element) return;
|
|
26589
|
+
if (e.altKey || e.ctrlKey || e.metaKey) return;
|
|
26590
|
+
const delta = ARROW_KEY_DELTAS[e.key];
|
|
26591
|
+
if (!delta) return;
|
|
26592
|
+
e.preventDefault();
|
|
26593
|
+
e.stopPropagation();
|
|
26594
|
+
const step = e.shiftKey ? KEYBOARD_DRAG_LARGE_STEP : KEYBOARD_DRAG_SMALL_STEP;
|
|
26595
|
+
const pos = this._map.project(this._lngLat);
|
|
26596
|
+
this.setLngLat(this._map.unproject(new Point(pos.x + delta[0] * step, pos.y + delta[1] * step)));
|
|
26597
|
+
if (!this._keyboardDragActive) {
|
|
26598
|
+
this._keyboardDragActive = true;
|
|
26599
|
+
this.fire(new MarkerDragEvent("dragstart"));
|
|
26600
|
+
}
|
|
26601
|
+
this.fire(new MarkerDragEvent("drag"));
|
|
26602
|
+
};
|
|
26603
|
+
this._onKeyUp = (e) => {
|
|
26604
|
+
if (!ARROW_KEY_DELTAS[e.key]) return;
|
|
26605
|
+
this._endKeyboardDrag();
|
|
26606
|
+
};
|
|
26607
|
+
this._onBlur = () => {
|
|
26608
|
+
this._endKeyboardDrag();
|
|
26609
|
+
};
|
|
25978
26610
|
this._onMapClick = (e) => {
|
|
25979
26611
|
const targetElement = e.originalEvent.target;
|
|
25980
26612
|
const element = this._element;
|
|
@@ -26045,6 +26677,8 @@ var Marker = class extends Evented {
|
|
|
26045
26677
|
this._subpixelPositioning = options?.subpixelPositioning || false;
|
|
26046
26678
|
this._isDragging = false;
|
|
26047
26679
|
this._roleManaged = false;
|
|
26680
|
+
this._tabIndexManaged = false;
|
|
26681
|
+
this._keyboardDragActive = false;
|
|
26048
26682
|
this._state = "inactive";
|
|
26049
26683
|
this._rotation = options?.rotation || 0;
|
|
26050
26684
|
this._rotationAlignment = options?.rotationAlignment || "auto";
|
|
@@ -26220,6 +26854,11 @@ var Marker = class extends Evented {
|
|
|
26220
26854
|
delete this._map;
|
|
26221
26855
|
}
|
|
26222
26856
|
this._element.removeEventListener("click", this._onClick);
|
|
26857
|
+
this._element.removeEventListener("keydown", this._onKeyDown);
|
|
26858
|
+
this._element.removeEventListener("keyup", this._onKeyUp);
|
|
26859
|
+
this._element.removeEventListener("blur", this._onBlur);
|
|
26860
|
+
this._element.removeEventListener("keypress", this._onKeyPress);
|
|
26861
|
+
this._keyboardDragActive = false;
|
|
26223
26862
|
this._element.remove();
|
|
26224
26863
|
if (this._popup) this._popup.remove();
|
|
26225
26864
|
return this;
|
|
@@ -26289,7 +26928,6 @@ var Marker = class extends Evented {
|
|
|
26289
26928
|
this._popup.remove();
|
|
26290
26929
|
this._popup = null;
|
|
26291
26930
|
this._element.removeEventListener("keypress", this._onKeyPress);
|
|
26292
|
-
if (!this._originalTabIndex) this._element.removeAttribute("tabindex");
|
|
26293
26931
|
}
|
|
26294
26932
|
if (popup) {
|
|
26295
26933
|
if (!("offset" in popup.options)) {
|
|
@@ -26307,10 +26945,9 @@ var Marker = class extends Evented {
|
|
|
26307
26945
|
} : this._offset;
|
|
26308
26946
|
}
|
|
26309
26947
|
this._popup = popup;
|
|
26310
|
-
this._originalTabIndex = this._element.getAttribute("tabindex");
|
|
26311
|
-
if (!this._originalTabIndex) this._element.setAttribute("tabindex", "0");
|
|
26312
26948
|
this._element.addEventListener("keypress", this._onKeyPress);
|
|
26313
26949
|
}
|
|
26950
|
+
this._updateTabIndex();
|
|
26314
26951
|
this._updateAccessibilityRole();
|
|
26315
26952
|
return this;
|
|
26316
26953
|
}
|
|
@@ -26329,6 +26966,12 @@ var Marker = class extends Evented {
|
|
|
26329
26966
|
this._subpixelPositioning = value;
|
|
26330
26967
|
return this;
|
|
26331
26968
|
}
|
|
26969
|
+
_endKeyboardDrag() {
|
|
26970
|
+
if (this._keyboardDragActive) {
|
|
26971
|
+
this._keyboardDragActive = false;
|
|
26972
|
+
this.fire(new MarkerDragEvent("dragend"));
|
|
26973
|
+
}
|
|
26974
|
+
}
|
|
26332
26975
|
/**
|
|
26333
26976
|
* Returns the {@link Popup} instance that is bound to the {@link Marker}.
|
|
26334
26977
|
* @returns popup
|
|
@@ -26465,19 +27108,37 @@ var Marker = class extends Evented {
|
|
|
26465
27108
|
return this._element.classList.toggle(className);
|
|
26466
27109
|
}
|
|
26467
27110
|
/**
|
|
26468
|
-
* Sets the `draggable` property and functionality of the marker
|
|
27111
|
+
* Sets the `draggable` property and functionality of the marker.
|
|
27112
|
+
* A draggable default marker is also keyboard focusable and movable with the
|
|
27113
|
+
* arrow keys (see {@link MarkerOptions.draggable}); custom marker elements keep
|
|
27114
|
+
* their focusability and keyboard behavior application-owned.
|
|
26469
27115
|
* @param shouldBeDraggable - Turns drag functionality on/off
|
|
26470
27116
|
*/
|
|
26471
27117
|
setDraggable(shouldBeDraggable) {
|
|
26472
27118
|
this._draggable = !!shouldBeDraggable;
|
|
26473
27119
|
this._element.classList.toggle("maplibregl-marker-draggable", this._draggable);
|
|
26474
|
-
if (this._map)
|
|
26475
|
-
|
|
26476
|
-
|
|
26477
|
-
|
|
26478
|
-
|
|
26479
|
-
|
|
27120
|
+
if (this._map) {
|
|
27121
|
+
if (shouldBeDraggable) {
|
|
27122
|
+
this._map.on("mousedown", this._addDragHandler);
|
|
27123
|
+
this._map.on("touchstart", this._addDragHandler);
|
|
27124
|
+
} else {
|
|
27125
|
+
this._map.off("mousedown", this._addDragHandler);
|
|
27126
|
+
this._map.off("touchstart", this._addDragHandler);
|
|
27127
|
+
}
|
|
27128
|
+
}
|
|
27129
|
+
if (this._defaultMarker) {
|
|
27130
|
+
if (this._draggable) {
|
|
27131
|
+
this._element.addEventListener("keydown", this._onKeyDown);
|
|
27132
|
+
this._element.addEventListener("keyup", this._onKeyUp);
|
|
27133
|
+
this._element.addEventListener("blur", this._onBlur);
|
|
27134
|
+
} else {
|
|
27135
|
+
this._element.removeEventListener("keydown", this._onKeyDown);
|
|
27136
|
+
this._element.removeEventListener("keyup", this._onKeyUp);
|
|
27137
|
+
this._element.removeEventListener("blur", this._onBlur);
|
|
27138
|
+
this._endKeyboardDrag();
|
|
27139
|
+
}
|
|
26480
27140
|
}
|
|
27141
|
+
this._updateTabIndex();
|
|
26481
27142
|
this._updateAccessibilityRole();
|
|
26482
27143
|
return this;
|
|
26483
27144
|
}
|
|
@@ -26489,6 +27150,24 @@ var Marker = class extends Evented {
|
|
|
26489
27150
|
return this._draggable;
|
|
26490
27151
|
}
|
|
26491
27152
|
/**
|
|
27153
|
+
* Keep the marker element focusable while it has built-in keyboard behavior.
|
|
27154
|
+
* A popup makes any marker element interactive; dragging only manages
|
|
27155
|
+
* focusability for the default marker so custom elements stay
|
|
27156
|
+
* application-owned (#7790). A tabindex supplied by the application is
|
|
27157
|
+
* never added, changed, or removed here.
|
|
27158
|
+
*/
|
|
27159
|
+
_updateTabIndex() {
|
|
27160
|
+
if (!!this._popup || this._defaultMarker && this._draggable) {
|
|
27161
|
+
if (!this._element.hasAttribute("tabindex")) {
|
|
27162
|
+
this._element.setAttribute("tabindex", "0");
|
|
27163
|
+
this._tabIndexManaged = true;
|
|
27164
|
+
}
|
|
27165
|
+
} else if (this._tabIndexManaged) {
|
|
27166
|
+
if (this._element.getAttribute("tabindex") === "0") this._element.removeAttribute("tabindex");
|
|
27167
|
+
this._tabIndexManaged = false;
|
|
27168
|
+
}
|
|
27169
|
+
}
|
|
27170
|
+
/**
|
|
26492
27171
|
* Keep the default marker role aligned with interactivity.
|
|
26493
27172
|
* Default markers need a role because `aria-label` is set in {@link Marker.addTo}.
|
|
26494
27173
|
* Non-interactive markers use `role=img`; interactive ones (draggable or with a popup) use `role=button`.
|
|
@@ -27238,8 +27917,10 @@ var FullscreenControl = class extends Evented {
|
|
|
27238
27917
|
};
|
|
27239
27918
|
this._fullscreen = false;
|
|
27240
27919
|
this._pseudo = options.pseudo ?? false;
|
|
27241
|
-
if (options?.container)
|
|
27242
|
-
|
|
27920
|
+
if (options?.container) {
|
|
27921
|
+
if (options.container instanceof HTMLElement) this._container = options.container;
|
|
27922
|
+
else warnOnce("Full screen control 'container' must be a DOM element.");
|
|
27923
|
+
}
|
|
27243
27924
|
if ("onfullscreenchange" in document) this._fullscreenchange = "fullscreenchange";
|
|
27244
27925
|
else if ("onmozfullscreenchange" in document) this._fullscreenchange = "mozfullscreenchange";
|
|
27245
27926
|
else if ("onwebkitfullscreenchange" in document) this._fullscreenchange = "webkitfullscreenchange";
|