maplibre-gl 6.0.0-19 → 6.0.0-20

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.
Files changed (54) hide show
  1. package/dist/maplibre-gl-dev.mjs +938 -812
  2. package/dist/maplibre-gl-dev.mjs.map +1 -1
  3. package/dist/maplibre-gl-shared-dev.mjs +1 -1
  4. package/dist/maplibre-gl-shared-dev.mjs.map +1 -1
  5. package/dist/maplibre-gl-shared.mjs +1 -1
  6. package/dist/maplibre-gl-shared.mjs.map +1 -1
  7. package/dist/maplibre-gl-worker-dev.mjs +1 -1
  8. package/dist/maplibre-gl-worker.mjs +1 -1
  9. package/dist/maplibre-gl.d.ts +1012 -945
  10. package/dist/maplibre-gl.mjs +4 -4
  11. package/dist/maplibre-gl.mjs.map +1 -1
  12. package/package.json +1 -1
  13. package/src/geo/projection/camera_helper.ts +1 -1
  14. package/src/geo/projection/globe_transform.ts +0 -4
  15. package/src/geo/projection/mercator_camera_helper.ts +11 -12
  16. package/src/geo/projection/mercator_transform.ts +1 -16
  17. package/src/geo/projection/vertical_perspective_camera_helper.ts +8 -12
  18. package/src/geo/projection/vertical_perspective_transform.ts +0 -13
  19. package/src/geo/transform_interface.ts +0 -9
  20. package/src/style/style.ts +1 -1
  21. package/src/style/style_layer/custom_style_layer.ts +1 -1
  22. package/src/ui/camera.test.ts +482 -497
  23. package/src/ui/camera.ts +105 -518
  24. package/src/ui/control/geolocate_control.test.ts +1 -1
  25. package/src/ui/control/navigation_control.test.ts +3 -5
  26. package/src/ui/control/navigation_control.ts +9 -5
  27. package/src/ui/handler/box_zoom.ts +4 -5
  28. package/src/ui/handler/click_zoom.ts +5 -5
  29. package/src/ui/handler/drag_pan.test.ts +1 -1
  30. package/src/ui/handler/drag_rotate.test.ts +1 -1
  31. package/src/ui/handler/keyboard.ts +5 -5
  32. package/src/ui/handler/mouse_rotate.test.ts +2 -2
  33. package/src/ui/handler/scroll_zoom.test.ts +2 -6
  34. package/src/ui/handler/scroll_zoom.ts +4 -5
  35. package/src/ui/handler/tap_drag_zoom.test.ts +1 -1
  36. package/src/ui/handler/tap_zoom.ts +5 -5
  37. package/src/ui/handler/transform-provider.ts +6 -6
  38. package/src/ui/handler/two_fingers_touch.test.ts +5 -5
  39. package/src/ui/handler_inertia.ts +8 -7
  40. package/src/ui/handler_manager.test.ts +17 -17
  41. package/src/ui/handler_manager.ts +27 -20
  42. package/src/ui/map.ts +627 -119
  43. package/src/ui/map_tests/map_animation.test.ts +4 -4
  44. package/src/ui/map_tests/map_calculate_camera_options.test.ts +1 -1
  45. package/src/ui/map_tests/map_query_rendered_features.test.ts +1 -1
  46. package/src/ui/map_tests/map_resize.test.ts +2 -2
  47. package/src/ui/map_tests/map_style.test.ts +21 -21
  48. package/src/ui/map_tests/map_terrain.test.ts +28 -6
  49. package/src/ui/map_tests/map_zoom.test.ts +2 -2
  50. package/src/ui/marker.test.ts +6 -6
  51. package/src/ui/marker.ts +11 -10
  52. package/src/ui/popup.ts +6 -6
  53. package/src/webgl/draw/draw_layer_opacity.ts +4 -0
  54. package/src/webgl/draw/draw_sky.ts +8 -7
@@ -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.0.0-19/LICENSE.txt
3
+ * @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v6.0.0-20/LICENSE.txt
4
4
  */
5
5
  import { $n as findLineIntersection, $r as rotateX$1, $t as validateStyle, A as earthRadius, Ai as isOffscreenCanvasDistorted, Ar as warnOnce, At as SegmentVector, B as evaluateSizeForFeature, Bn as createMat4f64, Br as zero, Bt as isRasterStyleLayer, C as altitudeFromMercatorZ, Ci as scale, Cn as addProtocol, Cr as rollPitchBearingToQuat, Ct as Uniform2f, D as mercatorYfromLat, Di as create$2, Dn as AbortError, Dr as threePlaneIntersection, Dt as UniformColorArray, E as mercatorXfromLng, Ei as fromRotation, En as config, Er as subscribe, Et as UniformColor, F as isBackgroundStyleLayer, Fn as bezier, Fr as create$3, Ft as PosArray, G as ImagePosition, Gn as degreesToRadians, Gr as transformMat4, Gt as EvaluationParameters, Hn as createVec4f64, Hr as slerp, Ht as Properties, I as isSymbolStyleLayer, In as clamp, Ir as length, It as QuadTriangleArray, J as parseGlyphPbf, Jn as easeCubicInOut, Jr as cross, Jt as ZoomHistory, K as potpack, Kn as differenceOfAnglesDegrees, Kr as add, L as SymbolBucket, Ln as clone$2, Lr as scale$1, Lt as RasterBoundsArray, M as createStyleLayer, Mi as Point, Mn as angleToRotateBetweenVectors2D, Mr as zoomScale, Mt as CollisionCircleLayoutArray, N as isCustomStyleLayer, Nn as arrayBufferToImage, Nr as pixelsToTileUnits, Nt as LineStripIndexArray, O as mercatorZfromAltitude, Oi as invert, On as isAbortError, Or as translatePosition, Ot as UniformFloatArray, P as validateCustomStyleLayer, Pn as arrayBufferToImageBitmap, Pr as EXTENT, Pt as Pos3dArray, Qn as filterObject, Qr as normalize, Qt as validateSky, R as addDynamicAttributes, Rn as createIdentityMat4f32, Rr as sqrLen, Rt as TriangleIndexArray, S as MercatorCoordinate, Si as rotateZ, Sn as sameOrigin, Sr as rollPitchBearingEqual, St as Uniform1i, T as lngFromMercatorX, Ti as create$4, Tn as removeProtocol, Tr as sphericalToCartesian, Tt as Uniform4f, U as getAnchorAlignment, Un as deepEqual, Ur as mul, Ut as TRANSITION_SUFFIX, V as evaluateSizeForZoom, Vn as createVec3f64, Vr as fromEuler, Vt as DataConstantProperty, Wn as defaultEasing, Wr as scale$3, Wt as Transitionable, X as collisionCircleLayout, Xn as evaluateZoomSnap, Xr as len, Xt as emitValidationErrors$1, Yn as ensureError, Yr as dot, Z as isLineStyleLayer, Zn as extend, Zr as length$1, Zt as validateLight, _ as OverscaledTileID, _i as multiply, _n as getArrayBuffer, _r as pointPlaneSignedDistance, _t as RGBAImage, a as clipLine, ai as transformMat3, an as diff, ar as isImageBitmap, at as NORTH_POLE_Y, b as compareTileId, bi as rotateX, bn as getVideo, br as readImageUsingVideoFrame, bt as toEvaluationFeature, ci as zero$1, cr as isTouchableEvent, ct as SubdivisionGranularitySetting, di as create$1, dn as v8, dr as lerp, dt as Texture, ei as rotateY, en as Color, er as getAABB, et as isFillExtrusionStyleLayer, f as GEOJSON_TILE_LAYER_NAME, fi as equals, fn as ErrorEvent, fr as mapObject, ft as isHillshadeStyleLayer, g as CanonicalTileID, gi as invert$1, gn as GLOBAL_DISPATCHER_ID, gr as pick, gt as AlphaImage, h as Bounds, hi as identity, hn as AJAXError, hr as parseCacheControl, ht as renderColorRamp, ii as sub, in as derefLayers, ir as getRollPitchBearing, j as Actor, ji as offscreenCanvasSupported, jn as MAX_VALID_LATITUDE, jr as wrap, jt as CollisionBoxArray, k as LngLat, ki as rotate, kn as throwIfAborted, kr as uniqueId, kt as UniformMatrix4f, li as clone$1, ln as interpolateFactory, lr as isTouchableOrPointableType, lt as isColorReliefStyleLayer, mi as fromScaling, mn as Evented, mr as nextPowerOfTwo, mt as isHeatmapStyleLayer, ni as scale$2, nn as ValidationError, nr as getEdgeTiles, oi as transformMat4$1, on as emptyStyle, or as isPointableEvent, ot as SOUTH_POLE_Y, pi as exactEquals, pn as Event, pr as mod, pt as HEATMAP_FULL_RENDER_FBO_KEY, q as renderStyleImage, qn as distanceOfAnglesRadians, qr as clone, qt as codePointUsesLocalIdeographFontFamily, r as TextAnchorEnum, ri as scaleAndAdd, rt as isFillStyleLayer, s as TileCache, si as transformQuat, sn as featureFilter, sr as isSafari, st as SubdivisionGranularityExpression, t as getAnchorJustification, ti as rotateZ$1, tn as ProjectionDefinition, tr as getAngleDelta, u as GeoJSONFeature, ui as copy, un as latest_default, ur as isWorker, v as UnwrappedTileID, vi as ortho, vn as getJSON, vr as radiansToDegrees, vt as isCircleStyleLayer, w as latFromMercatorY, wi as translate, wn as getProtocol, wr as scaleZoom, wt as Uniform3f, x as isInBoundsForZoomLngLat, xi as rotateY$1, xn as makeRequest, xr as remapSaturate, xt as Uniform1f, y as calculateTileKey, yi as perspective, yn as getReferrer, yr as rayPlaneIntersection, yt as polygonIntersectsPolygon, z as getOverlapMode, zn as createIdentityMat4f64, zr as transformMat4$2, zt as createLayout } from "./maplibre-gl-shared-dev.mjs";
6
6
  //#region package.json
7
- var version$2 = "6.0.0-19";
7
+ var version$2 = "6.0.0-20";
8
8
  //#endregion
9
9
  //#region src/util/browser.ts
10
10
  let linkEl;
@@ -4737,18 +4737,18 @@ function getMercatorHorizon(transform) {
4737
4737
  }
4738
4738
  function calculateTileMatrix(unwrappedTileID, worldSize) {
4739
4739
  const canonical = unwrappedTileID.canonical;
4740
- const scale$7 = worldSize / zoomScale(canonical.z);
4740
+ const scale$5 = worldSize / zoomScale(canonical.z);
4741
4741
  const unwrappedX = canonical.x + Math.pow(2, canonical.z) * unwrappedTileID.wrap;
4742
4742
  const worldMatrix = /* @__PURE__ */ new Float64Array(16);
4743
4743
  identity(worldMatrix);
4744
4744
  translate(worldMatrix, worldMatrix, [
4745
- unwrappedX * scale$7,
4746
- canonical.y * scale$7,
4745
+ unwrappedX * scale$5,
4746
+ canonical.y * scale$5,
4747
4747
  0
4748
4748
  ]);
4749
4749
  scale(worldMatrix, worldMatrix, [
4750
- scale$7 / EXTENT,
4751
- scale$7 / EXTENT,
4750
+ scale$5 / EXTENT,
4751
+ scale$5 / EXTENT,
4752
4752
  1
4753
4753
  ]);
4754
4754
  return worldMatrix;
@@ -10049,24 +10049,6 @@ var MercatorTransform = class MercatorTransform {
10049
10049
  populateCache(coords) {
10050
10050
  for (const coord of coords) this.calculatePosMatrix(coord);
10051
10051
  }
10052
- getMatrixForModel(location, altitude) {
10053
- const modelAsMercatorCoordinate = MercatorCoordinate.fromLngLat(location, altitude);
10054
- const scale$5 = modelAsMercatorCoordinate.meterInMercatorCoordinateUnits();
10055
- const m = createIdentityMat4f64();
10056
- translate(m, m, [
10057
- modelAsMercatorCoordinate.x,
10058
- modelAsMercatorCoordinate.y,
10059
- modelAsMercatorCoordinate.z
10060
- ]);
10061
- rotateZ(m, m, Math.PI);
10062
- rotateX(m, m, Math.PI / 2);
10063
- scale(m, m, [
10064
- -scale$5,
10065
- scale$5,
10066
- scale$5
10067
- ]);
10068
- return m;
10069
- }
10070
10052
  getProjectionDataForCustomLayer(applyGlobeMatrix = true) {
10071
10053
  const tileID = new OverscaledTileID(0, 0, 0, 0, 0);
10072
10054
  const rendererProjectionData = this.getProjectionData({
@@ -10075,13 +10057,13 @@ var MercatorTransform = class MercatorTransform {
10075
10057
  });
10076
10058
  const tileMatrix = calculateTileMatrix(tileID, this.worldSize);
10077
10059
  multiply(tileMatrix, this._viewProjMatrix, tileMatrix);
10078
- const scale$6 = [
10060
+ const scale$4 = [
10079
10061
  EXTENT,
10080
10062
  EXTENT,
10081
10063
  this.worldSize / this._helper.pixelsPerMeter
10082
10064
  ];
10083
10065
  const projectionMatrixScaled = createMat4f64();
10084
- scale(projectionMatrixScaled, tileMatrix, scale$6);
10066
+ scale(projectionMatrixScaled, tileMatrix, scale$4);
10085
10067
  return {
10086
10068
  ...rendererProjectionData,
10087
10069
  tileMercatorCoords: [
@@ -10257,20 +10239,19 @@ var MercatorCameraHelper = class {
10257
10239
  const targetCenter = constrained.center;
10258
10240
  const targetZoom = constrained.zoom;
10259
10241
  normalizeCenter(tr, targetCenter);
10260
- const from = projectToWorldCoordinates(tr.worldSize, options.locationAtOffset);
10261
- const delta = projectToWorldCoordinates(tr.worldSize, targetCenter).sub(from);
10242
+ const startWorldSize = tr.worldSize;
10243
+ const from = projectToWorldCoordinates(startWorldSize, options.locationAtOffset);
10244
+ const delta = projectToWorldCoordinates(startWorldSize, targetCenter).sub(from);
10262
10245
  const pixelPathLength = delta.mag();
10263
10246
  const scaleOfZoom = zoomScale(targetZoom - startZoom);
10264
- const optionsMinZoom = typeof options.minZoom !== "undefined";
10265
- let scaleOfMinZoom;
10266
- if (optionsMinZoom) {
10267
- const minZoomPreConstrain = Math.min(+options.minZoom, startZoom, targetZoom);
10268
- const minZoom = tr.applyConstrain(targetCenter, minZoomPreConstrain).zoom;
10269
- scaleOfMinZoom = zoomScale(minZoom - startZoom);
10270
- }
10247
+ const requestedMinZoom = typeof options.minZoom !== "undefined" ? +options.minZoom : tr.minZoom;
10248
+ const effectiveMinZoom = Math.max(requestedMinZoom, tr.minZoom);
10249
+ const minZoomPreConstrain = Math.min(effectiveMinZoom, startZoom, targetZoom);
10250
+ const minZoom = tr.applyConstrain(targetCenter, minZoomPreConstrain).zoom;
10251
+ const scaleOfMinZoom = zoomScale(minZoom - startZoom);
10271
10252
  const easeFunc = (k, scale, centerFactor, pointAtOffset) => {
10272
10253
  tr.setZoom(k === 1 ? targetZoom : startZoom + scaleZoom(scale));
10273
- const newCenter = k === 1 ? targetCenter : unprojectFromWorldCoordinates(tr.worldSize, from.add(delta.mult(centerFactor)).mult(scale));
10254
+ const newCenter = k === 1 ? targetCenter : unprojectFromWorldCoordinates(startWorldSize, from.add(delta.mult(centerFactor)));
10274
10255
  tr.setLocationAtPoint(tr.renderWorldCopies ? newCenter.wrap() : newCenter, pointAtOffset);
10275
10256
  };
10276
10257
  return {
@@ -12146,25 +12127,6 @@ var VerticalPerspectiveTransform = class VerticalPerspectiveTransform {
12146
12127
  const horizonDisk = horizonPlaneToCenterAndRadius(horizonPlane);
12147
12128
  return sphereSurfacePointToCoordinates(clampToSphere(horizonDisk.center, horizonDisk.radius, planeIntersection));
12148
12129
  }
12149
- getMatrixForModel(location, altitude) {
12150
- const lnglat = LngLat.convert(location);
12151
- const scale$4 = 1 / earthRadius;
12152
- const m = createIdentityMat4f64();
12153
- rotateY$1(m, m, lnglat.lng / 180 * Math.PI);
12154
- rotateX(m, m, -lnglat.lat / 180 * Math.PI);
12155
- translate(m, m, [
12156
- 0,
12157
- 0,
12158
- 1 + altitude / earthRadius
12159
- ]);
12160
- rotateX(m, m, Math.PI * .5);
12161
- scale(m, m, [
12162
- scale$4,
12163
- scale$4,
12164
- scale$4
12165
- ]);
12166
- return m;
12167
- }
12168
12130
  getProjectionDataForCustomLayer(applyGlobeMatrix = true) {
12169
12131
  const globeData = this.getProjectionData({
12170
12132
  overscaledTileID: new OverscaledTileID(0, 0, 0, 0, 0),
@@ -12548,9 +12510,6 @@ var GlobeTransform = class GlobeTransform {
12548
12510
  getRayDirectionFromPixel(p) {
12549
12511
  return this._verticalPerspectiveTransform.getRayDirectionFromPixel(p);
12550
12512
  }
12551
- getMatrixForModel(location, altitude) {
12552
- return this.currentTransform.getMatrixForModel(location, altitude);
12553
- }
12554
12513
  getProjectionDataForCustomLayer(applyGlobeMatrix = true) {
12555
12514
  const mercatorData = this._mercatorTransform.getProjectionDataForCustomLayer(applyGlobeMatrix);
12556
12515
  if (!this.isGlobeRendering) return mercatorData;
@@ -12772,13 +12731,10 @@ var VerticalPerspectiveCameraHelper = class VerticalPerspectiveCameraHelper {
12772
12731
  const normalizedStartZoom = startZoom + getZoomAdjustment(startCenter.lat, 0);
12773
12732
  const normalizedTargetZoom = targetZoom + getZoomAdjustment(targetCenter.lat, 0);
12774
12733
  const scaleOfZoom = zoomScale(normalizedTargetZoom - normalizedStartZoom);
12775
- const optionsMinZoom = typeof options.minZoom === "number";
12776
- let scaleOfMinZoom;
12777
- if (optionsMinZoom) {
12778
- const normalizedOptionsMinZoom = +options.minZoom + getZoomAdjustment(targetCenter.lat, 0);
12779
- const minZoomPreConstrain = Math.min(normalizedOptionsMinZoom, normalizedStartZoom, normalizedTargetZoom) + getZoomAdjustment(0, targetCenter.lat);
12780
- scaleOfMinZoom = zoomScale(tr.applyConstrain(targetCenter, minZoomPreConstrain).zoom + getZoomAdjustment(targetCenter.lat, 0) - normalizedStartZoom);
12781
- }
12734
+ const requestedMinZoom = typeof options.minZoom === "number" ? +options.minZoom : tr.minZoom;
12735
+ const normalizedEffectiveMinZoom = Math.max(requestedMinZoom, tr.minZoom) + getZoomAdjustment(targetCenter.lat, 0);
12736
+ const minZoomPreConstrain = Math.min(normalizedEffectiveMinZoom, normalizedStartZoom, normalizedTargetZoom) + getZoomAdjustment(0, targetCenter.lat);
12737
+ const scaleOfMinZoom = zoomScale(tr.applyConstrain(targetCenter, minZoomPreConstrain).zoom + getZoomAdjustment(targetCenter.lat, 0) - normalizedStartZoom);
12782
12738
  const deltaLng = differenceOfAnglesDegrees(startCenter.lng, targetCenter.lng);
12783
12739
  const deltaLat = differenceOfAnglesDegrees(startCenter.lat, targetCenter.lat);
12784
12740
  const easeFunc = (k, scale, centerFactor, _pointAtOffset) => {
@@ -13959,7 +13915,7 @@ var Style = class extends Evented {
13959
13915
  this.sky.updateTransitions(parameters);
13960
13916
  }
13961
13917
  _setProjectionInternal(name) {
13962
- const projectionObjects = createProjectionFromName(name, this.map.transformConstrain);
13918
+ const projectionObjects = createProjectionFromName(name, this.map._camera?.transform.constrainOverride);
13963
13919
  this.projection = projectionObjects.projection;
13964
13920
  this.map.migrateProjection(projectionObjects.transform, projectionObjects.cameraHelper);
13965
13921
  for (const key in this.tileManagers) this.tileManagers[key].reload();
@@ -16612,6 +16568,7 @@ function drawLayerOpacity(painter, opacity, prepareDrawLayerOpacityResult, layer
16612
16568
  context.activeTexture.set(gl.TEXTURE0);
16613
16569
  gl.bindTexture(gl.TEXTURE_2D, painter.layerOpacityFbo.colorAttachment.get());
16614
16570
  painter.useProgram("layerOpacity").draw(context, gl.TRIANGLES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, layerOpacityUniformValues(opacity, 0), null, null, layer.id, painter.viewportBuffer, painter.quadTriangleIndexBuffer, painter.viewportSegments, layer.paint, painter.transform.zoom);
16571
+ painter.currentStencilSource = void 0;
16615
16572
  }
16616
16573
  //#endregion
16617
16574
  //#region src/webgl/draw/draw_line.ts
@@ -17557,7 +17514,7 @@ function getMesh(context, sky) {
17557
17514
  function drawSky(painter, sky) {
17558
17515
  const context = painter.context;
17559
17516
  const gl = context.gl;
17560
- const skyUniforms = skyUniformValues(sky, painter.style.map.transform, painter.pixelRatio);
17517
+ const skyUniforms = skyUniformValues(sky, painter.transform, painter.pixelRatio);
17561
17518
  const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1]);
17562
17519
  const stencilMode = StencilMode.disabled;
17563
17520
  const colorMode = painter.colorModeForRenderPass();
@@ -18452,29 +18409,29 @@ var HandlerInertia = class {
18452
18409
  if (deltas.pan.mag()) {
18453
18410
  const result = calculateEasing(deltas.pan.mag(), duration, extend({}, defaultPanInertiaOptions, panInertiaOptions || {}));
18454
18411
  const finalPan = deltas.pan.mult(result.amount / deltas.pan.mag());
18455
- const computedEaseOptions = this._map.cameraHelper.handlePanInertia(finalPan, this._map.transform);
18412
+ const computedEaseOptions = this._map._camera.cameraHelper.handlePanInertia(finalPan, this._map._camera.transform);
18456
18413
  easeOptions.center = computedEaseOptions.easingCenter;
18457
18414
  easeOptions.offset = computedEaseOptions.easingOffset;
18458
18415
  extendDuration(easeOptions, result);
18459
18416
  }
18460
18417
  if (deltas.zoom) {
18461
18418
  const result = calculateEasing(deltas.zoom, duration, defaultZoomInertiaOptions);
18462
- easeOptions.zoom = evaluateZoomSnap(this._map.transform.zoom + result.amount, this._map.getZoomSnap(), result.amount);
18419
+ easeOptions.zoom = evaluateZoomSnap(this._map.getZoom() + result.amount, this._map.getZoomSnap(), result.amount);
18463
18420
  extendDuration(easeOptions, result);
18464
18421
  }
18465
18422
  if (deltas.bearing) {
18466
18423
  const result = calculateEasing(deltas.bearing, duration, defaultBearingInertiaOptions);
18467
- easeOptions.bearing = this._map.transform.bearing + clamp(result.amount, -179, 179);
18424
+ easeOptions.bearing = this._map.getBearing() + clamp(result.amount, -179, 179);
18468
18425
  extendDuration(easeOptions, result);
18469
18426
  }
18470
18427
  if (deltas.pitch) {
18471
18428
  const result = calculateEasing(deltas.pitch, duration, defaultPitchInertiaOptions);
18472
- easeOptions.pitch = this._map.transform.pitch + result.amount;
18429
+ easeOptions.pitch = this._map.getPitch() + result.amount;
18473
18430
  extendDuration(easeOptions, result);
18474
18431
  }
18475
18432
  if (deltas.roll) {
18476
18433
  const result = calculateEasing(deltas.roll, duration, defaultRollInertiaOptions);
18477
- easeOptions.roll = this._map.transform.roll + clamp(result.amount, -179, 179);
18434
+ easeOptions.roll = this._map.getRoll() + clamp(result.amount, -179, 179);
18478
18435
  extendDuration(easeOptions, result);
18479
18436
  }
18480
18437
  if (easeOptions.zoom || easeOptions.bearing) {
@@ -18597,41 +18554,6 @@ var BlockableMapEventHandler = class {
18597
18554
  disable() {}
18598
18555
  };
18599
18556
  //#endregion
18600
- //#region src/ui/handler/transform-provider.ts
18601
- /**
18602
- * @internal
18603
- * Shared utilities for the Handler classes to access the correct camera state.
18604
- * If Camera.transformCameraUpdate is specified or terrain is enabled, the
18605
- * "desired state" of camera may differ from the state used for rendering. The
18606
- * handlers need the "desired state" to track accumulated changes.
18607
- */
18608
- var TransformProvider = class {
18609
- constructor(map) {
18610
- this._map = map;
18611
- }
18612
- get transform() {
18613
- return this._map._requestedCameraState || this._map.transform;
18614
- }
18615
- get center() {
18616
- return {
18617
- lng: this.transform.center.lng,
18618
- lat: this.transform.center.lat
18619
- };
18620
- }
18621
- get zoom() {
18622
- return this.transform.zoom;
18623
- }
18624
- get pitch() {
18625
- return this.transform.pitch;
18626
- }
18627
- get bearing() {
18628
- return this.transform.bearing;
18629
- }
18630
- unproject(point) {
18631
- return this.transform.screenPointToLocation(Point.convert(point), this._map.terrain);
18632
- }
18633
- };
18634
- //#endregion
18635
18557
  //#region src/ui/handler/box_zoom.ts
18636
18558
  /**
18637
18559
  * The `BoxZoomHandler` allows the user to zoom the map to fit within a bounding box.
@@ -18641,9 +18563,9 @@ var TransformProvider = class {
18641
18563
  */
18642
18564
  var BoxZoomHandler = class {
18643
18565
  /** @internal */
18644
- constructor(map, options) {
18566
+ constructor(map, options, transformProvider) {
18645
18567
  this._map = map;
18646
- this._tr = new TransformProvider(map);
18568
+ this._tr = transformProvider;
18647
18569
  this._el = map.getCanvasContainer();
18648
18570
  this._container = map.getContainer();
18649
18571
  this._clickTolerance = options.clickTolerance || 1;
@@ -18844,8 +18766,8 @@ var TapRecognizer = class {
18844
18766
  * A `TapZoomHandler` allows the user to zoom the map at a point by double tapping
18845
18767
  */
18846
18768
  var TapZoomHandler = class {
18847
- constructor(map) {
18848
- this._tr = new TransformProvider(map);
18769
+ constructor(map, transformProvider) {
18770
+ this._tr = transformProvider;
18849
18771
  this._zoomIn = new TapRecognizer({
18850
18772
  numTouches: 1,
18851
18773
  numTaps: 2
@@ -19476,8 +19398,8 @@ const defaultOptions$5 = {
19476
19398
  */
19477
19399
  var KeyboardHandler = class {
19478
19400
  /** @internal */
19479
- constructor(map) {
19480
- this._tr = new TransformProvider(map);
19401
+ constructor(map, transformProvider) {
19402
+ this._tr = transformProvider;
19481
19403
  const stepOptions = defaultOptions$5;
19482
19404
  this._panStep = stepOptions.panStep;
19483
19405
  this._bearingStep = stepOptions.bearingStep;
@@ -19639,14 +19561,14 @@ const wheelEventTimeDiffAdjustment = 5;
19639
19561
  */
19640
19562
  var ScrollZoomHandler = class {
19641
19563
  /** @internal */
19642
- constructor(map, triggerRenderFrame) {
19564
+ constructor(map, triggerRenderFrame, transformProvider) {
19643
19565
  this._onTimeout = (initialEvent) => {
19644
19566
  this._type = "wheel";
19645
19567
  this._delta -= this._lastValue;
19646
19568
  if (!this._active) this._start(initialEvent);
19647
19569
  };
19648
19570
  this._map = map;
19649
- this._tr = new TransformProvider(map);
19571
+ this._tr = transformProvider;
19650
19572
  this._triggerRenderFrame = triggerRenderFrame;
19651
19573
  this._delta = 0;
19652
19574
  this._defaultZoomRate = defaultZoomRate$1;
@@ -19925,8 +19847,8 @@ var DoubleClickZoomHandler = class {
19925
19847
  */
19926
19848
  var ClickZoomHandler = class {
19927
19849
  /** @internal */
19928
- constructor(map) {
19929
- this._tr = new TransformProvider(map);
19850
+ constructor(map, transformProvider) {
19851
+ this._tr = transformProvider;
19930
19852
  this.reset();
19931
19853
  }
19932
19854
  reset() {
@@ -20362,6 +20284,41 @@ var CooperativeGesturesHandler = class {
20362
20284
  }
20363
20285
  };
20364
20286
  //#endregion
20287
+ //#region src/ui/handler/transform-provider.ts
20288
+ /**
20289
+ * @internal
20290
+ * Shared utilities for the Handler classes to access the correct camera state.
20291
+ * If Camera.transformCameraUpdate is specified or terrain is enabled, the
20292
+ * "desired state" of camera may differ from the state used for rendering. The
20293
+ * handlers need the "desired state" to track accumulated changes.
20294
+ */
20295
+ var TransformProvider = class {
20296
+ constructor(camera) {
20297
+ this._camera = camera;
20298
+ }
20299
+ get transform() {
20300
+ return this._camera._requestedCameraState || this._camera.transform;
20301
+ }
20302
+ get center() {
20303
+ return {
20304
+ lng: this.transform.center.lng,
20305
+ lat: this.transform.center.lat
20306
+ };
20307
+ }
20308
+ get zoom() {
20309
+ return this.transform.zoom;
20310
+ }
20311
+ get pitch() {
20312
+ return this.transform.pitch;
20313
+ }
20314
+ get bearing() {
20315
+ return this.transform.bearing;
20316
+ }
20317
+ unproject(point) {
20318
+ return this.transform.screenPointToLocation(Point.convert(point), this._camera.terrain);
20319
+ }
20320
+ };
20321
+ //#endregion
20365
20322
  //#region src/ui/handler_manager.ts
20366
20323
  const isMoving = (p) => p.zoom || p.drag || p.roll || p.pitch || p.rotate;
20367
20324
  var RenderFrameEvent = class extends Event {};
@@ -20383,7 +20340,7 @@ var HandlerManager = class {
20383
20340
  get _ownerWindow() {
20384
20341
  return this._el?.ownerDocument?.defaultView || window;
20385
20342
  }
20386
- constructor(map, options) {
20343
+ constructor(map, camera, options) {
20387
20344
  this.handleWindowEvent = (e) => {
20388
20345
  this.handleEvent(e, `${e.type}Window`);
20389
20346
  };
@@ -20427,7 +20384,7 @@ var HandlerManager = class {
20427
20384
  ]);
20428
20385
  this._triggerRenderFrame();
20429
20386
  }
20430
- if (Object.keys(activeHandlers).length || hasChange(mergedHandlerResult)) this._map._stop(true);
20387
+ if (Object.keys(activeHandlers).length || hasChange(mergedHandlerResult)) this._camera.stop(true);
20431
20388
  this._updatingCamera = false;
20432
20389
  const { cameraAnimation } = mergedHandlerResult;
20433
20390
  if (cameraAnimation) {
@@ -20438,6 +20395,8 @@ var HandlerManager = class {
20438
20395
  }
20439
20396
  };
20440
20397
  this._map = map;
20398
+ this._camera = camera;
20399
+ this._transformProvider = new TransformProvider(this._camera);
20441
20400
  this._el = this._map.getCanvasContainer();
20442
20401
  this._handlers = [];
20443
20402
  this._handlersById = {};
@@ -20549,14 +20508,14 @@ var HandlerManager = class {
20549
20508
  const map = this._map;
20550
20509
  const el = map.getCanvasContainer();
20551
20510
  this._add("mapEvent", new MapEventHandler(map, options));
20552
- const boxZoom = map.boxZoom = new BoxZoomHandler(map, options);
20511
+ const boxZoom = map.boxZoom = new BoxZoomHandler(map, options, this._transformProvider);
20553
20512
  this._add("boxZoom", boxZoom);
20554
20513
  if (options.interactive && options.boxZoom) boxZoom.enable();
20555
20514
  const cooperativeGestures = map.cooperativeGestures = new CooperativeGesturesHandler(map, options.cooperativeGestures);
20556
20515
  this._add("cooperativeGestures", cooperativeGestures);
20557
20516
  if (options.cooperativeGestures) cooperativeGestures.enable();
20558
- const tapZoom = new TapZoomHandler(map);
20559
- const clickZoom = new ClickZoomHandler(map);
20517
+ const tapZoom = new TapZoomHandler(map, this._transformProvider);
20518
+ const clickZoom = new ClickZoomHandler(map, this._transformProvider);
20560
20519
  map.doubleClickZoom = new DoubleClickZoomHandler(clickZoom, tapZoom);
20561
20520
  this._add("tapZoom", tapZoom);
20562
20521
  this._add("clickZoom", clickZoom);
@@ -20588,10 +20547,10 @@ var HandlerManager = class {
20588
20547
  this._add("touchZoom", touchZoom, ["touchPan", "touchRotate"]);
20589
20548
  if (options.interactive && options.touchZoomRotate) map.touchZoomRotate.enable(options.touchZoomRotate);
20590
20549
  this._add("blockableMapEvent", new BlockableMapEventHandler(map));
20591
- const scrollZoom = map.scrollZoom = new ScrollZoomHandler(map, () => this._triggerRenderFrame());
20550
+ const scrollZoom = map.scrollZoom = new ScrollZoomHandler(map, () => this._triggerRenderFrame(), this._transformProvider);
20592
20551
  this._add("scrollZoom", scrollZoom, ["mousePan"]);
20593
20552
  if (options.interactive && options.scrollZoom) map.scrollZoom.enable(options.scrollZoom);
20594
- const keyboard = map.keyboard = new KeyboardHandler(map);
20553
+ const keyboard = map.keyboard = new KeyboardHandler(map, this._transformProvider);
20595
20554
  this._add("keyboard", keyboard);
20596
20555
  if (options.interactive && options.keyboard) map.keyboard.enable();
20597
20556
  }
@@ -20672,16 +20631,16 @@ var HandlerManager = class {
20672
20631
  }
20673
20632
  _updateMapTransform(combinedResult, combinedEventsInProgress, deactivatedHandlers) {
20674
20633
  const map = this._map;
20675
- const tr = map._getTransformForUpdate();
20634
+ const tr = this._camera.getTransformForUpdate();
20676
20635
  const terrain = map.terrain;
20677
20636
  if (!hasChange(combinedResult) && !(terrain && this._terrainMovement)) {
20678
20637
  this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true);
20679
20638
  return;
20680
20639
  }
20681
- map._stop(true);
20640
+ this._camera.stop(true);
20682
20641
  let { panDelta, zoomDelta, bearingDelta, pitchDelta, rollDelta, around, pinchAround } = combinedResult;
20683
20642
  if (pinchAround !== void 0) around = pinchAround;
20684
- around ||= map.transform.centerPoint;
20643
+ around ||= this._camera.transform.centerPoint;
20685
20644
  if (terrain && !tr.isPointOnMapSurface(around)) around = tr.centerPoint;
20686
20645
  const deltasForHelper = {
20687
20646
  panDelta,
@@ -20691,7 +20650,7 @@ var HandlerManager = class {
20691
20650
  bearingDelta,
20692
20651
  around
20693
20652
  };
20694
- if (this._map.cameraHelper.useGlobeControls && !tr.isPointOnMapSurface(around)) around = tr.centerPoint;
20653
+ if (this._camera.cameraHelper.useGlobeControls && !tr.isPointOnMapSurface(around)) around = tr.centerPoint;
20695
20654
  const preZoomAroundLoc = around.distSqr(tr.centerPoint) < .01 ? tr.center : tr.screenPointToLocation(panDelta ? around.sub(panDelta) : around);
20696
20655
  this._handleMapControls({
20697
20656
  terrain,
@@ -20701,13 +20660,13 @@ var HandlerManager = class {
20701
20660
  combinedEventsInProgress,
20702
20661
  panDelta
20703
20662
  });
20704
- map._applyUpdatedTransform(tr);
20663
+ this._camera.applyUpdatedTransform(tr);
20705
20664
  this._map._update();
20706
20665
  if (!combinedResult.noInertia) this._inertia.record(combinedResult);
20707
20666
  this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true);
20708
20667
  }
20709
20668
  _handleMapControls({ terrain, tr, deltasForHelper, preZoomAroundLoc, combinedEventsInProgress, panDelta }) {
20710
- const cameraHelper = this._map.cameraHelper;
20669
+ const cameraHelper = this._camera.cameraHelper;
20711
20670
  cameraHelper.handleMapControlsRollPitchBearingZoom(deltasForHelper, tr);
20712
20671
  if (!terrain) {
20713
20672
  cameraHelper.handleMapControlsPan(deltasForHelper, tr, preZoomAroundLoc);
@@ -20716,14 +20675,14 @@ var HandlerManager = class {
20716
20675
  if (cameraHelper.useGlobeControls) {
20717
20676
  if (!this._terrainMovement && (combinedEventsInProgress.drag || combinedEventsInProgress.zoom)) {
20718
20677
  this._terrainMovement = true;
20719
- this._map._elevationFreeze = true;
20678
+ this._camera.elevationFreeze = true;
20720
20679
  }
20721
20680
  cameraHelper.handleMapControlsPan(deltasForHelper, tr, preZoomAroundLoc);
20722
20681
  return;
20723
20682
  }
20724
20683
  if (!this._terrainMovement && (combinedEventsInProgress.drag || combinedEventsInProgress.zoom)) {
20725
20684
  this._terrainMovement = true;
20726
- this._map._elevationFreeze = true;
20685
+ this._camera.elevationFreeze = true;
20727
20686
  cameraHelper.handleMapControlsPan(deltasForHelper, tr, preZoomAroundLoc);
20728
20687
  return;
20729
20688
  }
@@ -20763,11 +20722,11 @@ var HandlerManager = class {
20763
20722
  const stillMoving = isMoving(this._eventsInProgress);
20764
20723
  const finishedMoving = (wasMoving || nowMoving) && !stillMoving;
20765
20724
  if (finishedMoving && this._terrainMovement) {
20766
- this._map._elevationFreeze = false;
20725
+ this._camera.elevationFreeze = false;
20767
20726
  this._terrainMovement = false;
20768
- const tr = this._map._getTransformForUpdate();
20727
+ const tr = this._camera.getTransformForUpdate();
20769
20728
  if (this._map.getCenterClampedToGround()) tr.recalculateZoomAndCenter(this._map.terrain);
20770
- this._map._applyUpdatedTransform(tr);
20729
+ this._camera.applyUpdatedTransform(tr);
20771
20730
  }
20772
20731
  if (allowEndAnimation && finishedMoving) {
20773
20732
  this._updatingCamera = true;
@@ -20802,7 +20761,7 @@ var HandlerManager = class {
20802
20761
  //#endregion
20803
20762
  //#region src/ui/camera.ts
20804
20763
  var Camera = class extends Evented {
20805
- constructor(transform, cameraHelper, options) {
20764
+ constructor(options) {
20806
20765
  super();
20807
20766
  this._renderFrameCallback = () => {
20808
20767
  const t = Math.min((now() - this._easeStart) / this._easeOptions.duration, 1);
@@ -20810,244 +20769,80 @@ var Camera = class extends Evented {
20810
20769
  if (t < 1 && this._easeFrameId) this._easeFrameId = this._requestRenderFrame(this._renderFrameCallback);
20811
20770
  else this.stop();
20812
20771
  };
20772
+ this.transform = new MercatorTransform();
20773
+ this.cameraHelper = new MercatorCameraHelper();
20774
+ if (options.minZoom !== void 0) this.transform.setMinZoom(options.minZoom);
20775
+ if (options.maxZoom !== void 0) this.transform.setMaxZoom(options.maxZoom);
20776
+ if (options.minPitch !== void 0) this.transform.setMinPitch(options.minPitch);
20777
+ if (options.maxPitch !== void 0) this.transform.setMaxPitch(options.maxPitch);
20778
+ if (options.renderWorldCopies !== void 0) this.transform.setRenderWorldCopies(options.renderWorldCopies);
20779
+ if (options.transformConstrain !== null) this.transform.setConstrainOverride(options.transformConstrain);
20813
20780
  this._moving = false;
20814
20781
  this._zooming = false;
20815
- this.transform = transform;
20816
20782
  this._bearingSnap = options.bearingSnap;
20817
20783
  this._zoomSnap = options.zoomSnap;
20818
- this.cameraHelper = cameraHelper;
20784
+ this._requestRenderFrame = options.requestRenderFrame;
20785
+ this._cancelRenderFrame = options.cancelRenderFrame;
20786
+ this.terrain = options.terrain;
20787
+ this._centerClampedToGround = options.centerClampedToGround ?? true;
20788
+ this.transformCameraUpdate = options.transformCameraUpdate ?? null;
20789
+ this._stopHandlers = options.stopHandlers ?? (() => {});
20819
20790
  this.on("moveend", () => {
20820
20791
  delete this._requestedCameraState;
20821
20792
  });
20822
20793
  }
20823
- /**
20824
- * @internal
20825
- * Creates a new specialized transform instance from a projection instance and migrates
20826
- * to this new transform, carrying over all the properties of the old transform (center, pitch, etc.).
20827
- * When the style's projection is changed (or first set), this function should be called.
20828
- */
20829
20794
  migrateProjection(newTransform, newCameraHelper) {
20830
20795
  newTransform.apply(this.transform, true);
20831
20796
  this.transform = newTransform;
20832
20797
  this.cameraHelper = newCameraHelper;
20833
20798
  }
20834
- /**
20835
- * Returns the map's geographical centerpoint.
20836
- *
20837
- * @returns The map's geographical centerpoint.
20838
- * @example
20839
- * Return a LngLat object such as `{lng: 0, lat: 0}`
20840
- * ```ts
20841
- * let center = map.getCenter();
20842
- * // access longitude and latitude values directly
20843
- * let {lng, lat} = map.getCenter();
20844
- * ```
20845
- */
20846
20799
  getCenter() {
20847
20800
  return new LngLat(this.transform.center.lng, this.transform.center.lat);
20848
20801
  }
20849
- /**
20850
- * Sets the map's geographical centerpoint. Equivalent to `jumpTo({center: center})`.
20851
- *
20852
- * Triggers the following events: `movestart` and `moveend`.
20853
- *
20854
- * @param center - The centerpoint to set.
20855
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
20856
- * @example
20857
- * ```ts
20858
- * map.setCenter([-74, 38]);
20859
- * ```
20860
- */
20861
20802
  setCenter(center, eventData) {
20862
20803
  return this.jumpTo({ center }, eventData);
20863
20804
  }
20864
- /**
20865
- * Returns the elevation of the map's center point.
20866
- *
20867
- * @returns The elevation of the map's center point, in meters above sea level.
20868
- */
20869
20805
  getCenterElevation() {
20870
20806
  return this.transform.elevation;
20871
20807
  }
20872
- /**
20873
- * Sets the elevation of the map's center point, in meters above sea level. Equivalent to `jumpTo({elevation: elevation})`.
20874
- *
20875
- * Triggers the following events: `movestart` and `moveend`.
20876
- *
20877
- * @param elevation - The elevation to set, in meters above sea level.
20878
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
20879
- */
20880
20808
  setCenterElevation(elevation, eventData) {
20881
20809
  this.jumpTo({ elevation }, eventData);
20882
20810
  return this;
20883
20811
  }
20884
- /**
20885
- * Returns the value of `centerClampedToGround`.
20886
- *
20887
- * If true, the elevation of the center point will automatically be set to the terrain elevation
20888
- * (or zero if terrain is not enabled). If false, the elevation of the center point will default
20889
- * to sea level and will not automatically update. Defaults to true. Needs to be set to false to
20890
- * keep the camera above ground when pitch \> 90 degrees.
20891
- */
20892
20812
  getCenterClampedToGround() {
20893
20813
  return this._centerClampedToGround;
20894
20814
  }
20895
- /**
20896
- * Sets the value of `centerClampedToGround`.
20897
- *
20898
- * If true, the elevation of the center point will automatically be set to the terrain elevation
20899
- * (or zero if terrain is not enabled). If false, the elevation of the center point will default
20900
- * to sea level and will not automatically update. Defaults to true. Needs to be set to false to
20901
- * keep the camera above ground when pitch \> 90 degrees.
20902
- */
20903
20815
  setCenterClampedToGround(centerClampedToGround) {
20904
20816
  this._centerClampedToGround = centerClampedToGround;
20905
20817
  }
20906
- /**
20907
- * Pans the map by the specified offset.
20908
- *
20909
- * Triggers the following events: `movestart` and `moveend`.
20910
- *
20911
- * @param offset - `x` and `y` coordinates by which to pan the map.
20912
- * @param options - Options object
20913
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
20914
- * @see [Navigate the map with game-like controls](https://maplibre.org/maplibre-gl-js/docs/examples/navigate-the-map-with-game-like-controls/)
20915
- */
20916
20818
  panBy(offset, options, eventData) {
20917
20819
  offset = Point.convert(offset).mult(-1);
20918
20820
  return this.panTo(this.transform.center, extend({ offset }, options), eventData);
20919
20821
  }
20920
- /**
20921
- * Pans the map to the specified location with an animated transition.
20922
- *
20923
- * Triggers the following events: `movestart` and `moveend`.
20924
- *
20925
- * @param lnglat - The location to pan the map to.
20926
- * @param options - Options describing the destination and animation of the transition.
20927
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
20928
- * @example
20929
- * ```ts
20930
- * map.panTo([-74, 38]);
20931
- * // Specify that the panTo animation should last 5000 milliseconds.
20932
- * map.panTo([-74, 38], {duration: 5000});
20933
- * ```
20934
- * @see [Update a feature in realtime](https://maplibre.org/maplibre-gl-js/docs/examples/update-a-feature-in-realtime/)
20935
- */
20936
20822
  panTo(lnglat, options, eventData) {
20937
20823
  return this.easeTo(extend({ center: lnglat }, options), eventData);
20938
20824
  }
20939
- /**
20940
- * Returns the map's current zoom level.
20941
- *
20942
- * @returns The map's current zoom level.
20943
- * @example
20944
- * ```ts
20945
- * map.getZoom();
20946
- * ```
20947
- */
20948
20825
  getZoom() {
20949
20826
  return this.transform.zoom;
20950
20827
  }
20951
- /**
20952
- * Sets the map's zoom level. Equivalent to `jumpTo({zoom: zoom})`.
20953
- *
20954
- * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`.
20955
- *
20956
- * @param zoom - The zoom level to set (0-20).
20957
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
20958
- * @example
20959
- * Zoom to the zoom level 5 without an animated transition
20960
- * ```ts
20961
- * map.setZoom(5);
20962
- * ```
20963
- */
20964
20828
  setZoom(zoom, eventData) {
20965
20829
  this.jumpTo({ zoom }, eventData);
20966
20830
  return this;
20967
20831
  }
20968
- /**
20969
- * Zooms the map to the specified zoom level, with an animated transition.
20970
- *
20971
- * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`.
20972
- *
20973
- * @param zoom - The zoom level to transition to.
20974
- * @param options - Options object
20975
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
20976
- * @example
20977
- * ```ts
20978
- * // Zoom to the zoom level 5 without an animated transition
20979
- * map.zoomTo(5);
20980
- * // Zoom to the zoom level 8 with an animated transition
20981
- * map.zoomTo(8, {
20982
- * duration: 2000,
20983
- * offset: [100, 50]
20984
- * });
20985
- * ```
20986
- */
20987
20832
  zoomTo(zoom, options, eventData) {
20988
20833
  return this.easeTo(extend({ zoom }, options), eventData);
20989
20834
  }
20990
- /**
20991
- * Incrementally increases the map's zoom level by 1, first snapping to the nearest `zoomSnap` increment.
20992
- *
20993
- * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`.
20994
- *
20995
- * @param options - Options object
20996
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
20997
- * @example
20998
- * Zoom the map in one level with a custom animation duration
20999
- * ```ts
21000
- * map.zoomIn({duration: 1000});
21001
- * ```
21002
- */
21003
20835
  zoomIn(options, eventData) {
21004
20836
  this.zoomTo(evaluateZoomSnap(this.getZoom() + 1, this._zoomSnap), options, eventData);
21005
20837
  return this;
21006
20838
  }
21007
- /**
21008
- * Decreases the map's zoom level by 1, first snapping to the nearest `zoomSnap` increment.
21009
- *
21010
- * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`.
21011
- *
21012
- * @param options - Options object
21013
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21014
- * @example
21015
- * Zoom the map out one level with a custom animation offset
21016
- * ```ts
21017
- * map.zoomOut({offset: [80, 60]});
21018
- * ```
21019
- */
21020
20839
  zoomOut(options, eventData) {
21021
20840
  this.zoomTo(evaluateZoomSnap(this.getZoom() - 1, this._zoomSnap), options, eventData);
21022
20841
  return this;
21023
20842
  }
21024
- /**
21025
- * Returns the map's current vertical field of view, in degrees.
21026
- *
21027
- * @returns The map's current vertical field of view.
21028
- * @defaultValue 36.87
21029
- * @example
21030
- * ```ts
21031
- * const verticalFieldOfView = map.getVerticalFieldOfView();
21032
- * ```
21033
- */
21034
20843
  getVerticalFieldOfView() {
21035
20844
  return this.transform.fov;
21036
20845
  }
21037
- /**
21038
- * Sets the map's vertical field of view, in degrees.
21039
- *
21040
- * Triggers the following events: `movestart`, `move`, and `moveend`.
21041
- *
21042
- * @param fov - The vertical field of view to set, in degrees (0-180).
21043
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21044
- * @defaultValue 36.87
21045
- * @example
21046
- * Change vertical field of view to 30 degrees
21047
- * ```ts
21048
- * map.setVerticalFieldOfView(30);
21049
- * ```
21050
- */
21051
20846
  setVerticalFieldOfView(fov, eventData) {
21052
20847
  if (fov != this.transform.fov) {
21053
20848
  this.transform.setFov(fov);
@@ -21055,113 +20850,34 @@ var Camera = class extends Evented {
21055
20850
  }
21056
20851
  return this;
21057
20852
  }
21058
- /**
21059
- * Returns the map's current bearing. The bearing is the compass direction that is "up"; for example, a bearing
21060
- * of 90° orients the map so that east is up.
21061
- *
21062
- * @returns The map's current bearing.
21063
- * @see [Navigate the map with game-like controls](https://maplibre.org/maplibre-gl-js/docs/examples/navigate-the-map-with-game-like-controls/)
21064
- */
21065
20853
  getBearing() {
21066
20854
  return this.transform.bearing;
21067
20855
  }
21068
- /**
21069
- * Sets the map's zoom snap level.
21070
- *
21071
- * @param snap - The zoom snap level to set.
21072
- */
21073
20856
  setZoomSnap(snap) {
21074
20857
  this._zoomSnap = snap;
21075
20858
  return this;
21076
20859
  }
21077
- /**
21078
- * Returns the map's current zoom snap level.
21079
- *
21080
- * @returns The map's current zoom snap level.
21081
- */
21082
20860
  getZoomSnap() {
21083
20861
  return this._zoomSnap;
21084
20862
  }
21085
- /**
21086
- * Sets the map's bearing (rotation). The bearing is the compass direction that is "up"; for example, a bearing
21087
- * of 90° orients the map so that east is up.
21088
- *
21089
- * Equivalent to `jumpTo({bearing: bearing})`.
21090
- *
21091
- * Triggers the following events: `movestart`, `moveend`, and `rotate`.
21092
- *
21093
- * @param bearing - The desired bearing.
21094
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21095
- * @example
21096
- * Rotate the map to 90 degrees
21097
- * ```ts
21098
- * map.setBearing(90);
21099
- * ```
21100
- */
21101
20863
  setBearing(bearing, eventData) {
21102
20864
  this.jumpTo({ bearing }, eventData);
21103
20865
  return this;
21104
20866
  }
21105
- /**
21106
- * Returns the current padding applied around the map viewport.
21107
- *
21108
- * @returns The current padding around the map viewport.
21109
- */
21110
20867
  getPadding() {
21111
20868
  return this.transform.padding;
21112
20869
  }
21113
- /**
21114
- * Sets the padding in pixels around the viewport.
21115
- *
21116
- * Equivalent to `jumpTo({padding: padding})`.
21117
- *
21118
- * Triggers the following events: `movestart` and `moveend`.
21119
- *
21120
- * @param padding - The desired padding.
21121
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21122
- * @example
21123
- * Sets a left padding of 300px, and a top padding of 50px
21124
- * ```ts
21125
- * map.setPadding({ left: 300, top: 50 });
21126
- * ```
21127
- */
21128
20870
  setPadding(padding, eventData) {
21129
20871
  this.jumpTo({ padding }, eventData);
21130
20872
  return this;
21131
20873
  }
21132
- /**
21133
- * Rotates the map to the specified bearing, with an animated transition. The bearing is the compass direction
21134
- * that is "up"; for example, a bearing of 90° orients the map so that east is up.
21135
- *
21136
- * Triggers the following events: `movestart`, `moveend`, and `rotate`.
21137
- *
21138
- * @param bearing - The desired bearing.
21139
- * @param options - Options object
21140
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21141
- */
21142
20874
  rotateTo(bearing, options, eventData) {
21143
20875
  return this.easeTo(extend({ bearing }, options), eventData);
21144
20876
  }
21145
- /**
21146
- * Rotates the map so that north is up (0° bearing), with an animated transition.
21147
- *
21148
- * Triggers the following events: `movestart`, `moveend`, and `rotate`.
21149
- *
21150
- * @param options - Options object
21151
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21152
- */
21153
20877
  resetNorth(options, eventData) {
21154
20878
  this.rotateTo(0, extend({ duration: 1e3 }, options), eventData);
21155
20879
  return this;
21156
20880
  }
21157
- /**
21158
- * Rotates and pitches the map so that north is up (0° bearing) and pitch and roll are 0°, with an animated transition.
21159
- *
21160
- * Triggers the following events: `movestart`, `move`, `moveend`, `pitchstart`, `pitch`, `pitchend`, `rollstart`, `roll`, `rollend`, and `rotate`.
21161
- *
21162
- * @param options - Options object
21163
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21164
- */
21165
20881
  resetNorthPitch(options, eventData) {
21166
20882
  this.easeTo(extend({
21167
20883
  bearing: 0,
@@ -21171,75 +20887,24 @@ var Camera = class extends Evented {
21171
20887
  }, options), eventData);
21172
20888
  return this;
21173
20889
  }
21174
- /**
21175
- * Snaps the map so that north is up (0° bearing), if the current bearing is close enough to it (i.e. within the
21176
- * `bearingSnap` threshold).
21177
- *
21178
- * Triggers the following events: `movestart`, `moveend`, and `rotate`.
21179
- *
21180
- * @param options - Options object
21181
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21182
- */
21183
20890
  snapToNorth(options, eventData) {
21184
20891
  if (Math.abs(this.getBearing()) < this._bearingSnap) return this.resetNorth(options, eventData);
21185
20892
  return this;
21186
20893
  }
21187
- /**
21188
- * Returns the map's current pitch (tilt).
21189
- *
21190
- * @returns The map's current pitch, measured in degrees away from the plane of the screen.
21191
- */
21192
20894
  getPitch() {
21193
20895
  return this.transform.pitch;
21194
20896
  }
21195
- /**
21196
- * Sets the map's pitch (tilt). Equivalent to `jumpTo({pitch: pitch})`.
21197
- *
21198
- * Triggers the following events: `movestart`, `moveend`, `pitchstart`, and `pitchend`.
21199
- *
21200
- * @param pitch - The pitch to set, measured in degrees away from the plane of the screen (0-60).
21201
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21202
- */
21203
20897
  setPitch(pitch, eventData) {
21204
20898
  this.jumpTo({ pitch }, eventData);
21205
20899
  return this;
21206
20900
  }
21207
- /**
21208
- * Returns the map's current roll angle.
21209
- *
21210
- * @returns The map's current roll, measured in degrees about the camera boresight.
21211
- */
21212
20901
  getRoll() {
21213
20902
  return this.transform.roll;
21214
20903
  }
21215
- /**
21216
- * Sets the map's roll angle. Equivalent to `jumpTo({roll: roll})`.
21217
- *
21218
- * Triggers the following events: `movestart`, `moveend`, `rollstart`, and `rollend`.
21219
- *
21220
- * @param roll - The roll to set, measured in degrees about the camera boresight
21221
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21222
- */
21223
20904
  setRoll(roll, eventData) {
21224
20905
  this.jumpTo({ roll }, eventData);
21225
20906
  return this;
21226
20907
  }
21227
- /**
21228
- * @param bounds - Calculate the center for these bounds in the viewport and use
21229
- * the highest zoom level up to and including {@link Map.getMaxZoom} that fits
21230
- * in the viewport. LngLatBounds represent a box that is always axis-aligned with bearing 0.
21231
- * Bounds will be taken in `[sw, ne]` order. Southwest point will always be to the left of the northeast point.
21232
- * @param options - Options object
21233
- * @returns If map is able to fit to provided bounds, returns `center`, `zoom`, and `bearing`.
21234
- * If map is unable to fit, method will warn and return undefined.
21235
- * @example
21236
- * ```ts
21237
- * let bbox = [[-79, 43], [-73, 45]];
21238
- * let newCameraTransform = map.cameraForBounds(bbox, {
21239
- * padding: {top: 10, bottom:25, left: 15, right: 5}
21240
- * });
21241
- * ```
21242
- */
21243
20908
  cameraForBounds(bounds, options) {
21244
20909
  bounds = LngLatBounds.convert(bounds).adjustAntiMeridian();
21245
20910
  const bearing = options?.bearing || 0;
@@ -21295,51 +20960,9 @@ var Camera = class extends Evented {
21295
20960
  if (result && this._zoomSnap) result.zoom = evaluateZoomSnap(result.zoom, this._zoomSnap, -1);
21296
20961
  return result;
21297
20962
  }
21298
- /**
21299
- * Pans and zooms the map to contain its visible area within the specified geographical bounds.
21300
- * This function will also reset the map's bearing to 0 if bearing is nonzero.
21301
- *
21302
- * Triggers the following events: `movestart` and `moveend`.
21303
- *
21304
- * @param bounds - Center these bounds in the viewport and use the highest
21305
- * zoom level up to and including {@link Map.getMaxZoom} that fits them in the viewport.
21306
- * Bounds will be taken in `[sw, ne]` order. Southwest point will always be to the left of the northeast point.
21307
- * @param options - Options supports all properties from {@link AnimationOptions} and {@link CameraOptions} in addition to the fields below.
21308
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21309
- * @example
21310
- * ```ts
21311
- * let bbox = [[-79, 43], [-73, 45]];
21312
- * map.fitBounds(bbox, {
21313
- * padding: {top: 10, bottom:25, left: 15, right: 5}
21314
- * });
21315
- * ```
21316
- * @see [Fit a map to a bounding box](https://maplibre.org/maplibre-gl-js/docs/examples/fit-a-map-to-a-bounding-box/)
21317
- */
21318
20963
  fitBounds(bounds, options, eventData) {
21319
20964
  return this._fitInternal(this.cameraForBounds(bounds, options), options, eventData);
21320
20965
  }
21321
- /**
21322
- * Pans, rotates and zooms the map to to fit the box made by points p0 and p1
21323
- * once the map is rotated to the specified bearing. To zoom without rotating,
21324
- * pass in the current map bearing.
21325
- *
21326
- * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend` and `rotate`.
21327
- *
21328
- * @param p0 - First point on screen, in pixel coordinates
21329
- * @param p1 - Second point on screen, in pixel coordinates
21330
- * @param bearing - Desired map bearing at end of animation, in degrees
21331
- * @param options - Options object
21332
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21333
- * @example
21334
- * ```ts
21335
- * let p0 = [220, 400];
21336
- * let p1 = [500, 900];
21337
- * map.fitScreenCoordinates(p0, p1, map.getBearing(), {
21338
- * padding: {top: 10, bottom:25, left: 15, right: 5}
21339
- * });
21340
- * ```
21341
- * @see Used by {@link BoxZoomHandler}
21342
- */
21343
20966
  fitScreenCoordinates(p0, p1, bearing, options, eventData) {
21344
20967
  return this._fitInternal(this._cameraForBoxAndBearing(this.transform.screenPointToLocation(Point.convert(p0)), this.transform.screenPointToLocation(Point.convert(p1)), bearing, options), options, eventData);
21345
20968
  }
@@ -21349,35 +20972,10 @@ var Camera = class extends Evented {
21349
20972
  delete options.padding;
21350
20973
  return options.linear ? this.easeTo(options, eventData) : this.flyTo(options, eventData);
21351
20974
  }
21352
- /**
21353
- * Changes any combination of center, zoom, bearing, pitch, and roll, without
21354
- * an animated transition. The map will retain its current values for any
21355
- * details not specified in `options`.
21356
- *
21357
- * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend`, `pitchstart`,
21358
- * `pitch`, `pitchend`, `rollstart`, `roll`, `rollend` and `rotate`.
21359
- *
21360
- * @param options - Options object
21361
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21362
- * @example
21363
- * ```ts
21364
- * // jump to coordinates at current zoom
21365
- * map.jumpTo({center: [0, 0]});
21366
- * // jump with zoom, pitch, and bearing options
21367
- * map.jumpTo({
21368
- * center: [0, 0],
21369
- * zoom: 8,
21370
- * pitch: 45,
21371
- * bearing: 90
21372
- * });
21373
- * ```
21374
- * @see [Jump to a series of locations](https://maplibre.org/maplibre-gl-js/docs/examples/jump-to-a-series-of-locations/)
21375
- * @see [Update a feature in realtime](https://maplibre.org/maplibre-gl-js/docs/examples/update-a-feature-in-realtime/)
21376
- */
21377
20975
  jumpTo(options, eventData) {
21378
20976
  this.stop();
21379
20977
  if ("zoom" in options && this._zoomSnap) options.zoom = evaluateZoomSnap(options.zoom, this._zoomSnap);
21380
- const tr = this._getTransformForUpdate();
20978
+ const tr = this.getTransformForUpdate();
21381
20979
  let bearingChanged = false, pitchChanged = false;
21382
20980
  let rollChanged = false;
21383
20981
  const oldZoom = tr.zoom;
@@ -21398,7 +20996,7 @@ var Camera = class extends Evented {
21398
20996
  tr.setRoll(+options.roll);
21399
20997
  }
21400
20998
  if (options.padding != null && !tr.isPaddingEqual(options.padding)) tr.setPadding(options.padding);
21401
- this._applyUpdatedTransform(tr);
20999
+ this.applyUpdatedTransform(tr);
21402
21000
  this.fire(new MapMovementEvent("movestart", eventData)).fire(new MapMovementEvent("move", eventData));
21403
21001
  if (zoomChanged) this.fire(new MapMovementEvent("zoomstart", eventData)).fire(new MapMovementEvent("zoom", eventData)).fire(new MapMovementEvent("zoomend", eventData));
21404
21002
  if (bearingChanged) this.fire(new MapMovementEvent("rotatestart", eventData)).fire(new MapMovementEvent("rotate", eventData)).fire(new MapMovementEvent("rotateend", eventData));
@@ -21406,25 +21004,6 @@ var Camera = class extends Evented {
21406
21004
  if (rollChanged) this.fire(new MapMovementEvent("rollstart", eventData)).fire(new MapMovementEvent("roll", eventData)).fire(new MapMovementEvent("rollend", eventData));
21407
21005
  return this.fire(new MapMovementEvent("moveend", eventData));
21408
21006
  }
21409
- /**
21410
- * Given a camera 'from' position and a position to look at (`to`), calculates zoom and camera rotation and returns them as {@link CameraOptions}.
21411
- * @param from - The camera to look from
21412
- * @param altitudeFrom - The altitude of the camera to look from
21413
- * @param to - The center to look at
21414
- * @param altitudeTo - Optional altitude of the center to look at. If none given the ground height will be used.
21415
- * @returns the calculated camera options
21416
- * @example
21417
- * ```ts
21418
- * // Calculate options to look from (1°, 0°, 1000m) to (1°, 1°, 0m)
21419
- * const cameraLngLat = new LngLat(1, 0);
21420
- * const cameraAltitude = 1000;
21421
- * const targetLngLat = new LngLat(1, 1);
21422
- * const targetAltitude = 0;
21423
- * const cameraOptions = map.calculateCameraOptionsFromTo(cameraLngLat, cameraAltitude, targetLngLat, targetAltitude);
21424
- * // Apply calculated options
21425
- * map.jumpTo(cameraOptions);
21426
- * ```
21427
- */
21428
21007
  calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo = 0) {
21429
21008
  const fromMercator = MercatorCoordinate.fromLngLat(from, altitudeFrom);
21430
21009
  const toMercator = MercatorCoordinate.fromLngLat(to, altitudeTo);
@@ -21446,27 +21025,6 @@ var Camera = class extends Evented {
21446
21025
  bearing
21447
21026
  };
21448
21027
  }
21449
- /**
21450
- * Given a camera position and rotation, calculates zoom and center point and returns them as {@link CameraOptions}.
21451
- * @param cameraLngLat - The lng, lat of the camera to look from
21452
- * @param cameraAlt - The altitude of the camera to look from, in meters above sea level
21453
- * @param bearing - Bearing of the camera, in degrees
21454
- * @param pitch - Pitch of the camera, in degrees
21455
- * @param roll - Roll of the camera, in degrees
21456
- * @returns the calculated camera options
21457
- * @example
21458
- * ```ts
21459
- * // Calculate options to look from camera position(1°, 0°, 1000m) with bearing = 90°, pitch = 30°, and roll = 45°
21460
- * const cameraLngLat = new LngLat(1, 0);
21461
- * const cameraAltitude = 1000;
21462
- * const bearing = 90;
21463
- * const pitch = 30;
21464
- * const roll = 45;
21465
- * const cameraOptions = map.calculateCameraOptionsFromCameraLngLatAltRotation(cameraLngLat, cameraAltitude, bearing, pitch, roll);
21466
- * // Apply calculated options
21467
- * map.jumpTo(cameraOptions);
21468
- * ```
21469
- */
21470
21028
  calculateCameraOptionsFromCameraLngLatAltRotation(cameraLngLat, cameraAlt, bearing, pitch, roll) {
21471
21029
  const centerInfo = this.transform.calculateCenterFromCameraLngLatAlt(cameraLngLat, cameraAlt, bearing, pitch);
21472
21030
  return {
@@ -21478,24 +21036,6 @@ var Camera = class extends Evented {
21478
21036
  roll
21479
21037
  };
21480
21038
  }
21481
- /**
21482
- * Changes any combination of `center`, `zoom`, `bearing`, `pitch`, `roll`, and `padding` with an animated transition
21483
- * between old and new values. The map will retain its current values for any
21484
- * details not specified in `options`.
21485
- *
21486
- * !!! note "Reduced Motion"
21487
- * The transition will happen instantly if the user has enabled
21488
- * the `reduced motion` accessibility feature enabled in their operating system,
21489
- * unless `options` includes `essential: true`.
21490
- *
21491
- * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend`, `pitchstart`,
21492
- * `pitch`, `pitchend`, `rollstart`, `roll`, `rollend`, and `rotate`.
21493
- *
21494
- * @param options - Options describing the destination and animation of the transition.
21495
- * Accepts {@link CameraOptions} and {@link AnimationOptions}.
21496
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21497
- * @see [Navigate the map with game-like controls](https://maplibre.org/maplibre-gl-js/docs/examples/navigate-the-map-with-game-like-controls/)
21498
- */
21499
21039
  easeTo(options, eventData) {
21500
21040
  this._stop(false, options.easeId);
21501
21041
  options = extend({
@@ -21505,7 +21045,7 @@ var Camera = class extends Evented {
21505
21045
  }, options);
21506
21046
  if ("zoom" in options && this._zoomSnap) options.zoom = evaluateZoomSnap(options.zoom, this._zoomSnap);
21507
21047
  if (options.animate === false || !options.essential && browser.prefersReducedMotion) options.duration = 0;
21508
- const tr = this._getTransformForUpdate();
21048
+ const tr = this.getTransformForUpdate();
21509
21049
  const startBearing = this.getBearing(), startPitch = tr.pitch, startRoll = tr.roll, bearing = "bearing" in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing, pitch = "pitch" in options ? +options.pitch : startPitch, roll = "roll" in options ? this._normalizeBearing(options.roll, startRoll) : startRoll, padding = "padding" in options ? options.padding : tr.padding;
21510
21050
  const offsetAsPoint = Point.convert(options.offset);
21511
21051
  let around, aroundPoint;
@@ -21543,7 +21083,7 @@ var Camera = class extends Evented {
21543
21083
  this._ease((k) => {
21544
21084
  easeHandler.easeFunc(k);
21545
21085
  if (this.terrain && !options.freezeElevation) this._updateElevation(k);
21546
- this._applyUpdatedTransform(tr);
21086
+ this.applyUpdatedTransform(tr);
21547
21087
  this._fireMoveEvents(eventData);
21548
21088
  }, (interruptingEaseId) => {
21549
21089
  if (this.terrain && options.freezeElevation) this._finalizeElevation();
@@ -21563,7 +21103,7 @@ var Camera = class extends Evented {
21563
21103
  this._elevationCenter = center;
21564
21104
  this._elevationStart = this.transform.elevation;
21565
21105
  this._elevationTarget = this.terrain.getElevationForLngLatZoom(center, this.transform.tileZoom);
21566
- this._elevationFreeze = true;
21106
+ this.elevationFreeze = true;
21567
21107
  }
21568
21108
  _updateElevation(k) {
21569
21109
  if (this._elevationStart === void 0 || this._elevationCenter === void 0) this._prepareElevation(this.transform.center);
@@ -21578,7 +21118,7 @@ var Camera = class extends Evented {
21578
21118
  this.transform.setElevation(interpolateFactory.number(this._elevationStart, this._elevationTarget, k));
21579
21119
  }
21580
21120
  _finalizeElevation() {
21581
- this._elevationFreeze = false;
21121
+ this.elevationFreeze = false;
21582
21122
  if (this.getCenterClampedToGround()) this.transform.recalculateZoomAndCenter(this.terrain);
21583
21123
  }
21584
21124
  /**
@@ -21590,7 +21130,7 @@ var Camera = class extends Evented {
21590
21130
  * It may differ from the state used for rendering (`this.transform`).
21591
21131
  * @returns Transform to apply changes to
21592
21132
  */
21593
- _getTransformForUpdate() {
21133
+ getTransformForUpdate() {
21594
21134
  if (!this.transformCameraUpdate && !this.terrain) return this.transform;
21595
21135
  this._requestedCameraState ||= this.transform.clone();
21596
21136
  return this._requestedCameraState;
@@ -21627,7 +21167,7 @@ var Camera = class extends Evented {
21627
21167
  * If the camera is inside terrain, it gets elevated.
21628
21168
  * Call `transformCameraUpdate` if present, and then apply the "approved" changes.
21629
21169
  */
21630
- _applyUpdatedTransform(tr) {
21170
+ applyUpdatedTransform(tr) {
21631
21171
  const modifiers = [];
21632
21172
  modifiers.push((tr) => this._elevateCameraIfInsideTerrain(tr));
21633
21173
  if (this.transformCameraUpdate) modifiers.push((tr) => this.transformCameraUpdate(tr));
@@ -21672,42 +21212,6 @@ var Camera = class extends Evented {
21672
21212
  if (wasRolling) this.fire(new MapMovementEvent("rollend", eventData));
21673
21213
  this.fire(new MapMovementEvent("moveend", eventData));
21674
21214
  }
21675
- /**
21676
- * Changes any combination of center, zoom, bearing, pitch, and roll, animating the transition along a curve that
21677
- * evokes flight. The animation seamlessly incorporates zooming and panning to help
21678
- * the user maintain her bearings even after traversing a great distance.
21679
- *
21680
- * !!! note "Reduced Motion"
21681
- * The animation will be skipped, and this will behave equivalently to `jumpTo`
21682
- * if the user has the `reduced motion` accessibility feature enabled in their operating system,
21683
- * unless 'options' includes `essential: true`.
21684
- *
21685
- * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend`, `pitchstart`,
21686
- * `pitch`, `pitchend`, `rollstart`, `roll`, `rollend`, and `rotate`.
21687
- *
21688
- * @param options - Options describing the destination and animation of the transition.
21689
- * Accepts {@link CameraOptions}, {@link AnimationOptions},
21690
- * and the following additional options.
21691
- * @param eventData - Additional properties to be added to event objects of events triggered by this method.
21692
- * @example
21693
- * ```ts
21694
- * // fly with default options to null island
21695
- * map.flyTo({center: [0, 0], zoom: 9});
21696
- * // using flyTo options
21697
- * map.flyTo({
21698
- * center: [0, 0],
21699
- * zoom: 9,
21700
- * speed: 0.2,
21701
- * curve: 1,
21702
- * easing(t) {
21703
- * return t;
21704
- * }
21705
- * });
21706
- * ```
21707
- * @see [Fly to a location](https://maplibre.org/maplibre-gl-js/docs/examples/fly-to-a-location/)
21708
- * @see [Slowly fly to a location](https://maplibre.org/maplibre-gl-js/docs/examples/slowly-fly-to-a-location/)
21709
- * @see [Fly to a location based on scroll position](https://maplibre.org/maplibre-gl-js/docs/examples/fly-to-a-location-based-on-scroll-position/)
21710
- */
21711
21215
  flyTo(options, eventData) {
21712
21216
  if (!options.essential && browser.prefersReducedMotion) {
21713
21217
  const coercedOptions = pick(options, [
@@ -21729,7 +21233,7 @@ var Camera = class extends Evented {
21729
21233
  easing: defaultEasing
21730
21234
  }, options);
21731
21235
  if ("zoom" in options && this._zoomSnap) options.zoom = evaluateZoomSnap(options.zoom, this._zoomSnap);
21732
- const tr = this._getTransformForUpdate(), startBearing = tr.bearing, startPitch = tr.pitch, startRoll = tr.roll, startPadding = tr.padding;
21236
+ const tr = this.getTransformForUpdate(), startBearing = tr.bearing, startPitch = tr.pitch, startRoll = tr.roll, startPadding = tr.padding;
21733
21237
  const bearing = "bearing" in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing;
21734
21238
  const pitch = "pitch" in options ? +options.pitch : startPitch;
21735
21239
  const roll = "roll" in options ? this._normalizeBearing(options.roll, startRoll) : startRoll;
@@ -21752,10 +21256,8 @@ var Camera = class extends Evented {
21752
21256
  const w0 = Math.max(tr.width, tr.height);
21753
21257
  const w1 = w0 / flyToHandler.scaleOfZoom;
21754
21258
  const u1 = flyToHandler.pixelPathLength;
21755
- if (typeof flyToHandler.scaleOfMinZoom === "number") {
21756
- const wMax = w0 / flyToHandler.scaleOfMinZoom;
21757
- rho = Math.sqrt(wMax / u1 * 2);
21758
- }
21259
+ const wMax = w0 / flyToHandler.scaleOfMinZoom;
21260
+ rho = Math.min(rho, Math.sqrt(wMax / u1 * 2));
21759
21261
  const rho2 = rho * rho;
21760
21262
  /**
21761
21263
  * rᵢ: Returns the zoom-out factor at one end of the animation.
@@ -21816,7 +21318,7 @@ var Camera = class extends Evented {
21816
21318
  }
21817
21319
  flyToHandler.easeFunc(k, scale, centerFactor, pointAtOffset);
21818
21320
  if (this.terrain && !options.freezeElevation) this._updateElevation(k);
21819
- this._applyUpdatedTransform(tr);
21321
+ this.applyUpdatedTransform(tr);
21820
21322
  this._fireMoveEvents(eventData);
21821
21323
  }, () => {
21822
21324
  if (this.terrain && options.freezeElevation) this._finalizeElevation();
@@ -21827,11 +21329,8 @@ var Camera = class extends Evented {
21827
21329
  isEasing() {
21828
21330
  return !!this._easeFrameId;
21829
21331
  }
21830
- /**
21831
- * Stops any animated transition underway.
21832
- */
21833
- stop() {
21834
- return this._stop();
21332
+ stop(allowGestures) {
21333
+ return this._stop(allowGestures);
21835
21334
  }
21836
21335
  _stop(allowGestures, easeId) {
21837
21336
  if (this._easeFrameId) {
@@ -21844,7 +21343,7 @@ var Camera = class extends Evented {
21844
21343
  delete this._onEaseEnd;
21845
21344
  onEaseEnd.call(this, easeId);
21846
21345
  }
21847
- if (!allowGestures) this.handlers?.stop(false);
21346
+ if (!allowGestures) this._stopHandlers();
21848
21347
  return this;
21849
21348
  }
21850
21349
  _ease(frame, finish, options) {
@@ -21866,17 +21365,14 @@ var Camera = class extends Evented {
21866
21365
  if (Math.abs(bearing + 360 - currentBearing) < diff) bearing += 360;
21867
21366
  return bearing;
21868
21367
  }
21869
- /**
21870
- * Gets the elevation at a given location, in meters above sea level.
21871
- * Returns null if terrain is not enabled.
21872
- * If terrain is enabled with some exaggeration value, the value returned here will be reflective of (multiplied by) that exaggeration value.
21873
- * This method should be used for proper positioning of custom 3d objects, as explained [here](https://maplibre.org/maplibre-gl-js/docs/examples/adding-3d-models-using-threejs-on-terrain/)
21874
- * @param lngLatLike - `[x, y]` or LngLat coordinates of the location
21875
- * @returns elevation in meters
21876
- */
21877
- queryTerrainElevation(lngLatLike) {
21878
- if (!this.terrain) return null;
21879
- return this.terrain.getElevationForLngLat(LngLat.convert(lngLatLike), this.transform);
21368
+ isMoving() {
21369
+ return this._moving;
21370
+ }
21371
+ isZooming() {
21372
+ return this._zooming;
21373
+ }
21374
+ isRotating() {
21375
+ return this._rotating;
21880
21376
  }
21881
21377
  };
21882
21378
  //#endregion
@@ -23033,7 +22529,7 @@ const defaultOptions$4 = {
23033
22529
  * ```
23034
22530
  * @see [Display a map](https://maplibre.org/maplibre-gl-js/docs/examples/display-a-map/)
23035
22531
  */
23036
- var Map$1 = class extends Camera {
22532
+ var Map$1 = class extends Evented {
23037
22533
  /**
23038
22534
  * @internal
23039
22535
  * The window that owns the map container element, for cross-window support.
@@ -23043,30 +22539,7 @@ var Map$1 = class extends Camera {
23043
22539
  return this._container?.ownerDocument?.defaultView || window;
23044
22540
  }
23045
22541
  constructor(options) {
23046
- const resolvedOptions = {
23047
- ...defaultOptions$4,
23048
- ...options,
23049
- canvasContextAttributes: {
23050
- ...defaultOptions$4.canvasContextAttributes,
23051
- ...options.canvasContextAttributes
23052
- }
23053
- };
23054
- if (resolvedOptions.minZoom != null && resolvedOptions.maxZoom != null && resolvedOptions.minZoom > resolvedOptions.maxZoom) throw new Error("maxZoom must be greater than or equal to minZoom");
23055
- if (resolvedOptions.minPitch != null && resolvedOptions.maxPitch != null && resolvedOptions.minPitch > resolvedOptions.maxPitch) throw new Error("maxPitch must be greater than or equal to minPitch");
23056
- if (resolvedOptions.minPitch != null && resolvedOptions.minPitch < defaultMinPitch) throw new Error(`minPitch must be greater than or equal to ${defaultMinPitch}`);
23057
- if (resolvedOptions.maxPitch != null && resolvedOptions.maxPitch > maxPitchThreshold) throw new Error(`maxPitch must be less than or equal to ${maxPitchThreshold}`);
23058
- const transform = new MercatorTransform();
23059
- const cameraHelper = new MercatorCameraHelper();
23060
- if (resolvedOptions.minZoom !== void 0) transform.setMinZoom(resolvedOptions.minZoom);
23061
- if (resolvedOptions.maxZoom !== void 0) transform.setMaxZoom(resolvedOptions.maxZoom);
23062
- if (resolvedOptions.minPitch !== void 0) transform.setMinPitch(resolvedOptions.minPitch);
23063
- if (resolvedOptions.maxPitch !== void 0) transform.setMaxPitch(resolvedOptions.maxPitch);
23064
- if (resolvedOptions.renderWorldCopies !== void 0) transform.setRenderWorldCopies(resolvedOptions.renderWorldCopies);
23065
- if (resolvedOptions.transformConstrain !== null) transform.setConstrainOverride(resolvedOptions.transformConstrain);
23066
- super(transform, cameraHelper, {
23067
- bearingSnap: resolvedOptions.bearingSnap,
23068
- zoomSnap: resolvedOptions.zoomSnap
23069
- });
22542
+ super();
23070
22543
  this._idleTriggered = false;
23071
22544
  this._crossFadingFactor = 1;
23072
22545
  this._renderTaskQueue = new TaskQueue();
@@ -23119,14 +22592,40 @@ var Map$1 = class extends Camera {
23119
22592
  this._onWindowOnline = () => {
23120
22593
  this._update();
23121
22594
  };
22595
+ const resolvedOptions = {
22596
+ ...defaultOptions$4,
22597
+ ...options,
22598
+ canvasContextAttributes: {
22599
+ ...defaultOptions$4.canvasContextAttributes,
22600
+ ...options.canvasContextAttributes
22601
+ }
22602
+ };
22603
+ if (resolvedOptions.minZoom != null && resolvedOptions.maxZoom != null && resolvedOptions.minZoom > resolvedOptions.maxZoom) throw new Error("maxZoom must be greater than or equal to minZoom");
22604
+ if (resolvedOptions.minPitch != null && resolvedOptions.maxPitch != null && resolvedOptions.minPitch > resolvedOptions.maxPitch) throw new Error("maxPitch must be greater than or equal to minPitch");
22605
+ if (resolvedOptions.minPitch != null && resolvedOptions.minPitch < defaultMinPitch) throw new Error(`minPitch must be greater than or equal to ${defaultMinPitch}`);
22606
+ if (resolvedOptions.maxPitch != null && resolvedOptions.maxPitch > maxPitchThreshold) throw new Error(`maxPitch must be less than or equal to ${maxPitchThreshold}`);
22607
+ this._camera = new Camera({
22608
+ minZoom: resolvedOptions.minZoom,
22609
+ maxZoom: resolvedOptions.maxZoom,
22610
+ minPitch: resolvedOptions.minPitch,
22611
+ maxPitch: resolvedOptions.maxPitch,
22612
+ bearingSnap: resolvedOptions.bearingSnap,
22613
+ zoomSnap: resolvedOptions.zoomSnap,
22614
+ renderWorldCopies: resolvedOptions.renderWorldCopies,
22615
+ centerClampedToGround: resolvedOptions.centerClampedToGround,
22616
+ terrain: this.terrain,
22617
+ transformConstrain: resolvedOptions.transformConstrain,
22618
+ requestRenderFrame: (callback) => this._requestRenderFrame(callback),
22619
+ cancelRenderFrame: (id) => this._cancelRenderFrame(id),
22620
+ transformCameraUpdate: resolvedOptions.transformCameraUpdate,
22621
+ stopHandlers: () => this._handlers?.stop(false)
22622
+ });
22623
+ this._camera.setEventedParent(this);
23122
22624
  this._interactive = resolvedOptions.interactive;
23123
22625
  this._maxTileCacheSize = resolvedOptions.maxTileCacheSize;
23124
22626
  this._maxTileCacheZoomLevels = resolvedOptions.maxTileCacheZoomLevels;
23125
22627
  this._canvasContextAttributes = { ...resolvedOptions.canvasContextAttributes };
23126
22628
  this._trackResize = resolvedOptions.trackResize === true;
23127
- this._bearingSnap = resolvedOptions.bearingSnap;
23128
- this._zoomSnap = resolvedOptions.zoomSnap;
23129
- this._centerClampedToGround = resolvedOptions.centerClampedToGround;
23130
22629
  this._terrainSkirtLength = resolvedOptions.terrainSkirtLength;
23131
22630
  this._refreshExpiredTiles = resolvedOptions.refreshExpiredTiles === true;
23132
22631
  this._fadeDuration = resolvedOptions.fadeDuration;
@@ -23140,8 +22639,6 @@ var Map$1 = class extends Camera {
23140
22639
  this._overridePixelRatio = resolvedOptions.pixelRatio;
23141
22640
  this._maxCanvasSize = resolvedOptions.maxCanvasSize;
23142
22641
  this._zoomLevelsToOverscale = resolvedOptions.zoomLevelsToOverscale;
23143
- this.transformCameraUpdate = resolvedOptions.transformCameraUpdate;
23144
- this.transformConstrain = resolvedOptions.transformConstrain;
23145
22642
  this.cancelPendingTileRequestsWhileZooming = resolvedOptions.cancelPendingTileRequestsWhileZooming === true;
23146
22643
  this.setAnisotropicFilterPitch(resolvedOptions.anisotropicFilterPitch);
23147
22644
  if (resolvedOptions.reduceMotion !== void 0) browser.prefersReducedMotion = resolvedOptions.reduceMotion;
@@ -23160,11 +22657,11 @@ var Map$1 = class extends Camera {
23160
22657
  this._update(true);
23161
22658
  });
23162
22659
  this.once("idle", () => this._idleTriggered = true);
22660
+ this._handlers = new HandlerManager(this, this._camera, resolvedOptions);
23163
22661
  if (typeof window !== "undefined") {
23164
22662
  this._ownerWindow.addEventListener("online", this._onWindowOnline, false);
23165
22663
  this._setupResizeObserver();
23166
22664
  }
23167
- this.handlers = new HandlerManager(this, resolvedOptions);
23168
22665
  const hashName = typeof resolvedOptions.hash === "string" && resolvedOptions.hash || void 0;
23169
22666
  this._hash = resolvedOptions.hash ? new Hash(hashName).addTo(this) : void 0;
23170
22667
  if (!this._hash?._onHashChange()) {
@@ -23190,7 +22687,7 @@ var Map$1 = class extends Camera {
23190
22687
  if (resolvedOptions.maplibreLogo) this.addControl(new LogoControl(), resolvedOptions.logoPosition);
23191
22688
  this.on("style.load", () => {
23192
22689
  if (!shouldConstrainUsingMercatorTransform) this._resizeTransform();
23193
- if (this.transform.unmodified) {
22690
+ if (this._camera.transform.unmodified) {
23194
22691
  const coercedOptions = pick(this.style.stylesheet, [
23195
22692
  "center",
23196
22693
  "zoom",
@@ -23222,109 +22719,727 @@ var Map$1 = class extends Camera {
23222
22719
  return this._mapId;
23223
22720
  }
23224
22721
  /**
23225
- * Sets a global state property that can be retrieved with the [`global-state` expression](https://maplibre.org/maplibre-style-spec/expressions/#global-state).
23226
- * If the value is null, it resets the property to its default value defined in the [`state` style property](https://maplibre.org/maplibre-style-spec/root/#state).
23227
- *
23228
- * @param propertyName - The name of the state property to set.
23229
- * @param value - The value of the state property to set.
22722
+ * Sets a global state property that can be retrieved with the [`global-state` expression](https://maplibre.org/maplibre-style-spec/expressions/#global-state).
22723
+ * If the value is null, it resets the property to its default value defined in the [`state` style property](https://maplibre.org/maplibre-style-spec/root/#state).
22724
+ *
22725
+ * @param propertyName - The name of the state property to set.
22726
+ * @param value - The value of the state property to set.
22727
+ */
22728
+ setGlobalStateProperty(propertyName, value) {
22729
+ this.style.setGlobalStateProperty(propertyName, value);
22730
+ return this._update(true);
22731
+ }
22732
+ /**
22733
+ * Returns the global map state
22734
+ *
22735
+ * @returns The map state object.
22736
+ */
22737
+ getGlobalState() {
22738
+ return this.style.getGlobalState();
22739
+ }
22740
+ /**
22741
+ * Adds an {@link IControl} to the map, calling `control.onAdd(this)`.
22742
+ *
22743
+ * An {@link ErrorEvent} will be fired if the control is invalid.
22744
+ *
22745
+ * @param control - The {@link IControl} to add.
22746
+ * @param position - position on the map to which the control will be added.
22747
+ * Valid values are `'top-left'`, `'top-right'`, `'bottom-left'`, and `'bottom-right'`. Defaults to `'top-right'`.
22748
+ * @example
22749
+ * Add zoom and rotation controls to the map.
22750
+ * ```ts
22751
+ * map.addControl(new NavigationControl());
22752
+ * ```
22753
+ * @see [Display map navigation controls](https://maplibre.org/maplibre-gl-js/docs/examples/display-map-navigation-controls/)
22754
+ */
22755
+ addControl(control, position) {
22756
+ if (position === void 0) if (control.getDefaultPosition) position = control.getDefaultPosition();
22757
+ else position = "top-right";
22758
+ 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.")));
22759
+ const controlElement = control.onAdd(this);
22760
+ this._controls.push(control);
22761
+ const positionContainer = this._controlPositions[position];
22762
+ if (position.includes("bottom")) positionContainer.insertBefore(controlElement, positionContainer.firstChild);
22763
+ else positionContainer.appendChild(controlElement);
22764
+ return this;
22765
+ }
22766
+ /**
22767
+ * Removes the control from the map.
22768
+ *
22769
+ * An {@link ErrorEvent} will be fired if the control is invalid.
22770
+ *
22771
+ * @param control - The {@link IControl} to remove.
22772
+ * @example
22773
+ * ```ts
22774
+ * // Define a new navigation control.
22775
+ * let navigation = new NavigationControl();
22776
+ * // Add zoom and rotation controls to the map.
22777
+ * map.addControl(navigation);
22778
+ * // Remove zoom and rotation controls from the map.
22779
+ * map.removeControl(navigation);
22780
+ * ```
22781
+ */
22782
+ removeControl(control) {
22783
+ if (!control?.onRemove) return this.fire(new ErrorEvent(/* @__PURE__ */ new Error("Invalid argument to map.removeControl(). Argument must be a control with onAdd and onRemove methods.")));
22784
+ const ci = this._controls.indexOf(control);
22785
+ if (ci > -1) this._controls.splice(ci, 1);
22786
+ control.onRemove(this);
22787
+ return this;
22788
+ }
22789
+ /**
22790
+ * Checks if a control exists on the map.
22791
+ *
22792
+ * @param control - The {@link IControl} to check.
22793
+ * @returns true if map contains control.
22794
+ * @example
22795
+ * ```ts
22796
+ * // Define a new navigation control.
22797
+ * let navigation = new NavigationControl();
22798
+ * // Add zoom and rotation controls to the map.
22799
+ * map.addControl(navigation);
22800
+ * // Check that the navigation control exists on the map.
22801
+ * map.hasControl(navigation);
22802
+ * ```
22803
+ */
22804
+ hasControl(control) {
22805
+ return this._controls.includes(control);
22806
+ }
22807
+ /**
22808
+ * Returns an array of `OverscaledTileID` objects that cover the current viewport for a given tile size.
22809
+ * This method is useful for determining which tiles are visible in the current viewport.
22810
+ *
22811
+ * @param options - Options for calculating the covering tiles.
22812
+ * @returns An array of `OverscaledTileID` objects.
22813
+ * @example
22814
+ * ```ts
22815
+ * // Get the tiles to cover the view for a 512x512px tile source
22816
+ * const tiles = map.coveringTiles({tileSize: 512});
22817
+ * ```
22818
+ */
22819
+ coveringTiles(options) {
22820
+ return coveringTiles(this._camera.transform, options);
22821
+ }
22822
+ /**
22823
+ * Sets the callback used to defer camera updates or apply arbitrary constraints.
22824
+ * If specified, this Camera instance can be used as a stateless component in React etc.
22825
+ */
22826
+ setTransformCameraUpdate(value) {
22827
+ this._camera.transformCameraUpdate = value;
22828
+ }
22829
+ /**
22830
+ * Returns the map's geographical centerpoint.
22831
+ *
22832
+ * @returns The map's geographical centerpoint.
22833
+ * @example
22834
+ * Return a LngLat object such as `{lng: 0, lat: 0}`
22835
+ * ```ts
22836
+ * let center = map.getCenter();
22837
+ * // access longitude and latitude values directly
22838
+ * let {lng, lat} = map.getCenter();
22839
+ * ```
22840
+ */
22841
+ getCenter() {
22842
+ return new LngLat(this._camera.transform.center.lng, this._camera.transform.center.lat);
22843
+ }
22844
+ /**
22845
+ * Sets the map's geographical centerpoint. Equivalent to `jumpTo({center: center})`.
22846
+ *
22847
+ * Triggers the following events: `movestart` and `moveend`.
22848
+ *
22849
+ * @param center - The centerpoint to set.
22850
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
22851
+ * @example
22852
+ * ```ts
22853
+ * map.setCenter([-74, 38]);
22854
+ * ```
22855
+ */
22856
+ setCenter(center, eventData) {
22857
+ this._camera.setCenter(center, eventData);
22858
+ return this;
22859
+ }
22860
+ /**
22861
+ * Returns the elevation of the map's center point.
22862
+ *
22863
+ * @returns The elevation of the map's center point, in meters above sea level.
22864
+ */
22865
+ getCenterElevation() {
22866
+ return this._camera.transform.elevation;
22867
+ }
22868
+ /**
22869
+ * Sets the elevation of the map's center point, in meters above sea level. Equivalent to `jumpTo({elevation: elevation})`.
22870
+ *
22871
+ * Triggers the following events: `movestart` and `moveend`.
22872
+ *
22873
+ * @param elevation - The elevation to set, in meters above sea level.
22874
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
22875
+ */
22876
+ setCenterElevation(elevation, eventData) {
22877
+ this._camera.setCenterElevation(elevation, eventData);
22878
+ return this;
22879
+ }
22880
+ /**
22881
+ * Sets the value of `centerClampedToGround`.
22882
+ *
22883
+ * If true, the elevation of the center point will automatically be set to the terrain elevation
22884
+ * (or zero if terrain is not enabled). If false, the elevation of the center point will default
22885
+ * to sea level and will not automatically update. Defaults to true. Needs to be set to false to
22886
+ * keep the camera above ground when pitch \> 90 degrees.
22887
+ */
22888
+ setCenterClampedToGround(centerClampedToGround) {
22889
+ this._camera.setCenterClampedToGround(centerClampedToGround);
22890
+ }
22891
+ /**
22892
+ * Pans the map by the specified offset.
22893
+ *
22894
+ * Triggers the following events: `movestart` and `moveend`.
22895
+ *
22896
+ * @param offset - `x` and `y` coordinates by which to pan the map.
22897
+ * @param options - Options object
22898
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
22899
+ * @see [Navigate the map with game-like controls](https://maplibre.org/maplibre-gl-js/docs/examples/navigate-the-map-with-game-like-controls/)
22900
+ */
22901
+ panBy(offset, options, eventData) {
22902
+ this._camera.panBy(offset, options, eventData);
22903
+ return this;
22904
+ }
22905
+ /**
22906
+ * Pans the map to the specified location with an animated transition.
22907
+ *
22908
+ * Triggers the following events: `movestart` and `moveend`.
22909
+ *
22910
+ * @param lnglat - The location to pan the map to.
22911
+ * @param options - Options describing the destination and animation of the transition.
22912
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
22913
+ * @example
22914
+ * ```ts
22915
+ * map.panTo([-74, 38]);
22916
+ * // Specify that the panTo animation should last 5000 milliseconds.
22917
+ * map.panTo([-74, 38], {duration: 5000});
22918
+ * ```
22919
+ * @see [Update a feature in realtime](https://maplibre.org/maplibre-gl-js/docs/examples/update-a-feature-in-realtime/)
22920
+ */
22921
+ panTo(lnglat, options, eventData) {
22922
+ this._camera.panTo(lnglat, options, eventData);
22923
+ return this;
22924
+ }
22925
+ /**
22926
+ * Returns the map's current zoom level.
22927
+ *
22928
+ * @returns The map's current zoom level.
22929
+ * @example
22930
+ * ```ts
22931
+ * map.getZoom();
22932
+ * ```
22933
+ */
22934
+ getZoom() {
22935
+ return this._camera.transform.zoom;
22936
+ }
22937
+ /**
22938
+ * Sets the map's zoom level. Equivalent to `jumpTo({zoom: zoom})`.
22939
+ *
22940
+ * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`.
22941
+ *
22942
+ * @param zoom - The zoom level to set (0-20).
22943
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
22944
+ * @example
22945
+ * Zoom to the zoom level 5 without an animated transition
22946
+ * ```ts
22947
+ * map.setZoom(5);
22948
+ * ```
22949
+ */
22950
+ setZoom(zoom, eventData) {
22951
+ this._camera.setZoom(zoom, eventData);
22952
+ return this;
22953
+ }
22954
+ /**
22955
+ * Zooms the map to the specified zoom level, with an animated transition.
22956
+ *
22957
+ * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`.
22958
+ *
22959
+ * @param zoom - The zoom level to transition to.
22960
+ * @param options - Options object
22961
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
22962
+ * @example
22963
+ * ```ts
22964
+ * // Zoom to the zoom level 5 without an animated transition
22965
+ * map.zoomTo(5);
22966
+ * // Zoom to the zoom level 8 with an animated transition
22967
+ * map.zoomTo(8, {
22968
+ * duration: 2000,
22969
+ * offset: [100, 50]
22970
+ * });
22971
+ * ```
22972
+ */
22973
+ zoomTo(zoom, options, eventData) {
22974
+ this._camera.zoomTo(zoom, options, eventData);
22975
+ return this;
22976
+ }
22977
+ /**
22978
+ * Incrementally increases the map's zoom level by 1, first snapping to the nearest `zoomSnap` increment.
22979
+ *
22980
+ * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`.
22981
+ *
22982
+ * @param options - Options object
22983
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
22984
+ * @example
22985
+ * Zoom the map in one level with a custom animation duration
22986
+ * ```ts
22987
+ * map.zoomIn({duration: 1000});
22988
+ * ```
22989
+ */
22990
+ zoomIn(options, eventData) {
22991
+ this._camera.zoomIn(options, eventData);
22992
+ return this;
22993
+ }
22994
+ /**
22995
+ * Decreases the map's zoom level by 1, first snapping to the nearest `zoomSnap` increment.
22996
+ *
22997
+ * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`.
22998
+ *
22999
+ * @param options - Options object
23000
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23001
+ * @example
23002
+ * Zoom the map out one level with a custom animation offset
23003
+ * ```ts
23004
+ * map.zoomOut({offset: [80, 60]});
23005
+ * ```
23006
+ */
23007
+ zoomOut(options, eventData) {
23008
+ this._camera.zoomOut(options, eventData);
23009
+ return this;
23010
+ }
23011
+ /**
23012
+ * Returns the map's current vertical field of view, in degrees.
23013
+ *
23014
+ * @returns The map's current vertical field of view.
23015
+ * @defaultValue 36.87
23016
+ * @example
23017
+ * ```ts
23018
+ * const verticalFieldOfView = map.getVerticalFieldOfView();
23019
+ * ```
23020
+ */
23021
+ getVerticalFieldOfView() {
23022
+ return this._camera.transform.fov;
23023
+ }
23024
+ /**
23025
+ * Sets the map's vertical field of view, in degrees.
23026
+ *
23027
+ * Triggers the following events: `movestart`, `move`, and `moveend`.
23028
+ *
23029
+ * @param fov - The vertical field of view to set, in degrees (0-180).
23030
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23031
+ * @defaultValue 36.87
23032
+ * @example
23033
+ * Change vertical field of view to 30 degrees
23034
+ * ```ts
23035
+ * map.setVerticalFieldOfView(30);
23036
+ * ```
23037
+ */
23038
+ setVerticalFieldOfView(fov, eventData) {
23039
+ this._camera.setVerticalFieldOfView(fov, eventData);
23040
+ return this;
23041
+ }
23042
+ /**
23043
+ * Returns the map's current bearing. The bearing is the compass direction that is "up"; for example, a bearing
23044
+ * of 90° orients the map so that east is up.
23045
+ *
23046
+ * @returns The map's current bearing.
23047
+ * @see [Navigate the map with game-like controls](https://maplibre.org/maplibre-gl-js/docs/examples/navigate-the-map-with-game-like-controls/)
23048
+ */
23049
+ getBearing() {
23050
+ return this._camera.transform.bearing;
23051
+ }
23052
+ /**
23053
+ * Sets the map's bearing (rotation). The bearing is the compass direction that is "up"; for example, a bearing
23054
+ * of 90° orients the map so that east is up.
23055
+ *
23056
+ * Equivalent to `jumpTo({bearing: bearing})`.
23057
+ *
23058
+ * Triggers the following events: `movestart`, `moveend`, and `rotate`.
23059
+ *
23060
+ * @param bearing - The desired bearing.
23061
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23062
+ * @example
23063
+ * Rotate the map to 90 degrees
23064
+ * ```ts
23065
+ * map.setBearing(90);
23066
+ * ```
23067
+ */
23068
+ setBearing(bearing, eventData) {
23069
+ this._camera.setBearing(bearing, eventData);
23070
+ return this;
23071
+ }
23072
+ /**
23073
+ * Returns the map's current zoom snap level.
23074
+ *
23075
+ * @returns The map's current zoom snap level.
23076
+ */
23077
+ getZoomSnap() {
23078
+ return this._camera.getZoomSnap();
23079
+ }
23080
+ /**
23081
+ * Sets the map's zoom snap level.
23082
+ *
23083
+ * @param snap - The zoom snap level to set.
23084
+ */
23085
+ setZoomSnap(snap) {
23086
+ this._camera.setZoomSnap(snap);
23087
+ return this;
23088
+ }
23089
+ /**
23090
+ * Returns the current padding applied around the map viewport.
23091
+ *
23092
+ * @returns The current padding around the map viewport.
23093
+ */
23094
+ getPadding() {
23095
+ return this._camera.transform.padding;
23096
+ }
23097
+ /**
23098
+ * Sets the padding in pixels around the viewport.
23099
+ *
23100
+ * Equivalent to `jumpTo({padding: padding})`.
23101
+ *
23102
+ * Triggers the following events: `movestart` and `moveend`.
23103
+ *
23104
+ * @param padding - The desired padding.
23105
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23106
+ * @example
23107
+ * Sets a left padding of 300px, and a top padding of 50px
23108
+ * ```ts
23109
+ * map.setPadding({ left: 300, top: 50 });
23110
+ * ```
23111
+ */
23112
+ setPadding(padding, eventData) {
23113
+ this._camera.setPadding(padding, eventData);
23114
+ return this;
23115
+ }
23116
+ /**
23117
+ * Rotates the map to the specified bearing, with an animated transition. The bearing is the compass direction
23118
+ * that is "up"; for example, a bearing of 90° orients the map so that east is up.
23119
+ *
23120
+ * Triggers the following events: `movestart`, `moveend`, and `rotate`.
23121
+ *
23122
+ * @param bearing - The desired bearing.
23123
+ * @param options - Options object
23124
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23125
+ */
23126
+ rotateTo(bearing, options, eventData) {
23127
+ this._camera.rotateTo(bearing, options, eventData);
23128
+ return this;
23129
+ }
23130
+ /**
23131
+ * Rotates the map so that north is up (0° bearing), with an animated transition.
23132
+ *
23133
+ * Triggers the following events: `movestart`, `moveend`, and `rotate`.
23134
+ *
23135
+ * @param options - Options object
23136
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23137
+ */
23138
+ resetNorth(options, eventData) {
23139
+ this._camera.resetNorth(options, eventData);
23140
+ return this;
23141
+ }
23142
+ /**
23143
+ * Rotates and pitches the map so that north is up (0° bearing) and pitch and roll are 0°, with an animated transition.
23144
+ *
23145
+ * Triggers the following events: `movestart`, `move`, `moveend`, `pitchstart`, `pitch`, `pitchend`, `rollstart`, `roll`, `rollend`, and `rotate`.
23146
+ *
23147
+ * @param options - Options object
23148
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23149
+ */
23150
+ resetNorthPitch(options, eventData) {
23151
+ this._camera.resetNorthPitch(options, eventData);
23152
+ return this;
23153
+ }
23154
+ /**
23155
+ * Snaps the map so that north is up (0° bearing), if the current bearing is close enough to it (i.e. within the
23156
+ * `bearingSnap` threshold).
23157
+ *
23158
+ * Triggers the following events: `movestart`, `moveend`, and `rotate`.
23159
+ *
23160
+ * @param options - Options object
23161
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23162
+ */
23163
+ snapToNorth(options, eventData) {
23164
+ this._camera.snapToNorth(options, eventData);
23165
+ return this;
23166
+ }
23167
+ /**
23168
+ * Returns the map's current pitch (tilt).
23169
+ *
23170
+ * @returns The map's current pitch, measured in degrees away from the plane of the screen.
23171
+ */
23172
+ getPitch() {
23173
+ return this._camera.transform.pitch;
23174
+ }
23175
+ /**
23176
+ * Sets the map's pitch (tilt). Equivalent to `jumpTo({pitch: pitch})`.
23177
+ *
23178
+ * Triggers the following events: `movestart`, `moveend`, `pitchstart`, and `pitchend`.
23179
+ *
23180
+ * @param pitch - The pitch to set, measured in degrees away from the plane of the screen (0-60).
23181
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23182
+ */
23183
+ setPitch(pitch, eventData) {
23184
+ this._camera.setPitch(pitch, eventData);
23185
+ return this;
23186
+ }
23187
+ /**
23188
+ * Returns the map's current roll angle.
23189
+ *
23190
+ * @returns The map's current roll, measured in degrees about the camera boresight.
23191
+ */
23192
+ getRoll() {
23193
+ return this._camera.transform.roll;
23194
+ }
23195
+ /**
23196
+ * Sets the map's roll angle. Equivalent to `jumpTo({roll: roll})`.
23197
+ *
23198
+ * Triggers the following events: `movestart`, `moveend`, `rollstart`, and `rollend`.
23199
+ *
23200
+ * @param roll - The roll to set, measured in degrees about the camera boresight
23201
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23202
+ */
23203
+ setRoll(roll, eventData) {
23204
+ this._camera.setRoll(roll, eventData);
23205
+ return this;
23206
+ }
23207
+ /**
23208
+ * @param bounds - Calculate the center for these bounds in the viewport and use
23209
+ * the highest zoom level up to and including {@link Map.getMaxZoom} that fits
23210
+ * in the viewport. LngLatBounds represent a box that is always axis-aligned with bearing 0.
23211
+ * Bounds will be taken in `[sw, ne]` order. Southwest point will always be to the left of the northeast point.
23212
+ * @param options - Options object
23213
+ * @returns If map is able to fit to provided bounds, returns `center`, `zoom`, and `bearing`.
23214
+ * If map is unable to fit, method will warn and return undefined.
23215
+ * @example
23216
+ * ```ts
23217
+ * let bbox = [[-79, 43], [-73, 45]];
23218
+ * let newCameraTransform = map.cameraForBounds(bbox, {
23219
+ * padding: {top: 10, bottom:25, left: 15, right: 5}
23220
+ * });
23221
+ * ```
23230
23222
  */
23231
- setGlobalStateProperty(propertyName, value) {
23232
- this.style.setGlobalStateProperty(propertyName, value);
23233
- return this._update(true);
23223
+ cameraForBounds(bounds, options) {
23224
+ return this._camera.cameraForBounds(bounds, options);
23234
23225
  }
23235
23226
  /**
23236
- * Returns the global map state
23227
+ * Pans and zooms the map to contain its visible area within the specified geographical bounds.
23228
+ * This function will also reset the map's bearing to 0 if bearing is nonzero.
23237
23229
  *
23238
- * @returns The map state object.
23230
+ * Triggers the following events: `movestart` and `moveend`.
23231
+ *
23232
+ * @param bounds - Center these bounds in the viewport and use the highest
23233
+ * zoom level up to and including {@link Map.getMaxZoom} that fits them in the viewport.
23234
+ * Bounds will be taken in `[sw, ne]` order. Southwest point will always be to the left of the northeast point.
23235
+ * @param options - Options supports all properties from {@link AnimationOptions} and {@link CameraOptions} in addition to the fields below.
23236
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23237
+ * @example
23238
+ * ```ts
23239
+ * let bbox = [[-79, 43], [-73, 45]];
23240
+ * map.fitBounds(bbox, {
23241
+ * padding: {top: 10, bottom:25, left: 15, right: 5}
23242
+ * });
23243
+ * ```
23244
+ * @see [Fit a map to a bounding box](https://maplibre.org/maplibre-gl-js/docs/examples/fit-a-map-to-a-bounding-box/)
23239
23245
  */
23240
- getGlobalState() {
23241
- return this.style.getGlobalState();
23246
+ fitBounds(bounds, options, eventData) {
23247
+ this._camera.fitBounds(bounds, options, eventData);
23248
+ return this;
23242
23249
  }
23243
23250
  /**
23244
- * Adds an {@link IControl} to the map, calling `control.onAdd(this)`.
23251
+ * Pans, rotates and zooms the map to to fit the box made by points p0 and p1
23252
+ * once the map is rotated to the specified bearing. To zoom without rotating,
23253
+ * pass in the current map bearing.
23245
23254
  *
23246
- * An {@link ErrorEvent} will be fired if the control is invalid.
23255
+ * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend` and `rotate`.
23247
23256
  *
23248
- * @param control - The {@link IControl} to add.
23249
- * @param position - position on the map to which the control will be added.
23250
- * Valid values are `'top-left'`, `'top-right'`, `'bottom-left'`, and `'bottom-right'`. Defaults to `'top-right'`.
23257
+ * @param p0 - First point on screen, in pixel coordinates
23258
+ * @param p1 - Second point on screen, in pixel coordinates
23259
+ * @param bearing - Desired map bearing at end of animation, in degrees
23260
+ * @param options - Options object
23261
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23251
23262
  * @example
23252
- * Add zoom and rotation controls to the map.
23253
23263
  * ```ts
23254
- * map.addControl(new NavigationControl());
23264
+ * let p0 = [220, 400];
23265
+ * let p1 = [500, 900];
23266
+ * map.fitScreenCoordinates(p0, p1, map.getBearing(), {
23267
+ * padding: {top: 10, bottom:25, left: 15, right: 5}
23268
+ * });
23255
23269
  * ```
23256
- * @see [Display map navigation controls](https://maplibre.org/maplibre-gl-js/docs/examples/display-map-navigation-controls/)
23270
+ * @see Used by {@link BoxZoomHandler}
23257
23271
  */
23258
- addControl(control, position) {
23259
- if (position === void 0) if (control.getDefaultPosition) position = control.getDefaultPosition();
23260
- else position = "top-right";
23261
- 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.")));
23262
- const controlElement = control.onAdd(this);
23263
- this._controls.push(control);
23264
- const positionContainer = this._controlPositions[position];
23265
- if (position.includes("bottom")) positionContainer.insertBefore(controlElement, positionContainer.firstChild);
23266
- else positionContainer.appendChild(controlElement);
23272
+ fitScreenCoordinates(p0, p1, bearing, options, eventData) {
23273
+ this._camera.fitScreenCoordinates(p0, p1, bearing, options, eventData);
23267
23274
  return this;
23268
23275
  }
23269
23276
  /**
23270
- * Removes the control from the map.
23277
+ * Changes any combination of center, zoom, bearing, pitch, and roll, without
23278
+ * an animated transition. The map will retain its current values for any
23279
+ * details not specified in `options`.
23271
23280
  *
23272
- * An {@link ErrorEvent} will be fired if the control is invalid.
23281
+ * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend`, `pitchstart`,
23282
+ * `pitch`, `pitchend`, `rollstart`, `roll`, `rollend` and `rotate`.
23273
23283
  *
23274
- * @param control - The {@link IControl} to remove.
23284
+ * @param options - Options object
23285
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23275
23286
  * @example
23276
23287
  * ```ts
23277
- * // Define a new navigation control.
23278
- * let navigation = new NavigationControl();
23279
- * // Add zoom and rotation controls to the map.
23280
- * map.addControl(navigation);
23281
- * // Remove zoom and rotation controls from the map.
23282
- * map.removeControl(navigation);
23288
+ * // jump to coordinates at current zoom
23289
+ * map.jumpTo({center: [0, 0]});
23290
+ * // jump with zoom, pitch, and bearing options
23291
+ * map.jumpTo({
23292
+ * center: [0, 0],
23293
+ * zoom: 8,
23294
+ * pitch: 45,
23295
+ * bearing: 90
23296
+ * });
23283
23297
  * ```
23298
+ * @see [Jump to a series of locations](https://maplibre.org/maplibre-gl-js/docs/examples/jump-to-a-series-of-locations/)
23299
+ * @see [Update a feature in realtime](https://maplibre.org/maplibre-gl-js/docs/examples/update-a-feature-in-realtime/)
23284
23300
  */
23285
- removeControl(control) {
23286
- if (!control?.onRemove) return this.fire(new ErrorEvent(/* @__PURE__ */ new Error("Invalid argument to map.removeControl(). Argument must be a control with onAdd and onRemove methods.")));
23287
- const ci = this._controls.indexOf(control);
23288
- if (ci > -1) this._controls.splice(ci, 1);
23289
- control.onRemove(this);
23301
+ jumpTo(options, eventData) {
23302
+ this._camera.jumpTo(options, eventData);
23290
23303
  return this;
23291
23304
  }
23292
23305
  /**
23293
- * Checks if a control exists on the map.
23294
- *
23295
- * @param control - The {@link IControl} to check.
23296
- * @returns true if map contains control.
23306
+ * Given a camera position and rotation, calculates zoom and center point and returns them as {@link CameraOptions}.
23307
+ * @param cameraLngLat - The lng, lat of the camera to look from
23308
+ * @param cameraAlt - The altitude of the camera to look from, in meters above sea level
23309
+ * @param bearing - Bearing of the camera, in degrees
23310
+ * @param pitch - Pitch of the camera, in degrees
23311
+ * @param roll - Roll of the camera, in degrees
23312
+ * @returns the calculated camera options
23297
23313
  * @example
23298
23314
  * ```ts
23299
- * // Define a new navigation control.
23300
- * let navigation = new NavigationControl();
23301
- * // Add zoom and rotation controls to the map.
23302
- * map.addControl(navigation);
23303
- * // Check that the navigation control exists on the map.
23304
- * map.hasControl(navigation);
23315
+ * // Calculate options to look from camera position(1°, 0°, 1000m) with bearing = 90°, pitch = 30°, and roll = 45°
23316
+ * const cameraLngLat = new LngLat(1, 0);
23317
+ * const cameraAltitude = 1000;
23318
+ * const bearing = 90;
23319
+ * const pitch = 30;
23320
+ * const roll = 45;
23321
+ * const cameraOptions = map.calculateCameraOptionsFromCameraLngLatAltRotation(cameraLngLat, cameraAltitude, bearing, pitch, roll);
23322
+ * // Apply calculated options
23323
+ * map.jumpTo(cameraOptions);
23305
23324
  * ```
23306
23325
  */
23307
- hasControl(control) {
23308
- return this._controls.includes(control);
23326
+ calculateCameraOptionsFromCameraLngLatAltRotation(cameraLngLat, cameraAlt, bearing, pitch, roll) {
23327
+ return this._camera.calculateCameraOptionsFromCameraLngLatAltRotation(cameraLngLat, cameraAlt, bearing, pitch, roll);
23309
23328
  }
23310
23329
  /**
23311
- * Returns an array of `OverscaledTileID` objects that cover the current viewport for a given tile size.
23312
- * This method is useful for determining which tiles are visible in the current viewport.
23330
+ * Changes any combination of `center`, `zoom`, `bearing`, `pitch`, `roll`, and `padding` with an animated transition
23331
+ * between old and new values. The map will retain its current values for any
23332
+ * details not specified in `options`.
23313
23333
  *
23314
- * @param options - Options for calculating the covering tiles.
23315
- * @returns An array of `OverscaledTileID` objects.
23334
+ * !!! note "Reduced Motion"
23335
+ * The transition will happen instantly if the user has enabled
23336
+ * the `reduced motion` accessibility feature enabled in their operating system,
23337
+ * unless `options` includes `essential: true`.
23338
+ *
23339
+ * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend`, `pitchstart`,
23340
+ * `pitch`, `pitchend`, `rollstart`, `roll`, `rollend`, and `rotate`.
23341
+ *
23342
+ * @param options - Options describing the destination and animation of the transition.
23343
+ * Accepts {@link CameraOptions} and {@link AnimationOptions}.
23344
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23345
+ * @see [Navigate the map with game-like controls](https://maplibre.org/maplibre-gl-js/docs/examples/navigate-the-map-with-game-like-controls/)
23346
+ */
23347
+ easeTo(options, eventData) {
23348
+ this._camera.easeTo(options, eventData);
23349
+ return this;
23350
+ }
23351
+ /**
23352
+ * Changes any combination of center, zoom, bearing, pitch, and roll, animating the transition along a curve that
23353
+ * evokes flight. The animation seamlessly incorporates zooming and panning to help
23354
+ * the user maintain her bearings even after traversing a great distance.
23355
+ *
23356
+ * !!! note "Reduced Motion"
23357
+ * The animation will be skipped, and this will behave equivalently to `jumpTo`
23358
+ * if the user has the `reduced motion` accessibility feature enabled in their operating system,
23359
+ * unless 'options' includes `essential: true`.
23360
+ *
23361
+ * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend`, `pitchstart`,
23362
+ * `pitch`, `pitchend`, `rollstart`, `roll`, `rollend`, and `rotate`.
23363
+ *
23364
+ * @param options - Options describing the destination and animation of the transition.
23365
+ * Accepts {@link CameraOptions}, {@link AnimationOptions},
23366
+ * and the following additional options.
23367
+ * @param eventData - Additional properties to be added to event objects of events triggered by this method.
23316
23368
  * @example
23317
23369
  * ```ts
23318
- * // Get the tiles to cover the view for a 512x512px tile source
23319
- * const tiles = map.coveringTiles({tileSize: 512});
23370
+ * // fly with default options to null island
23371
+ * map.flyTo({center: [0, 0], zoom: 9});
23372
+ * // using flyTo options
23373
+ * map.flyTo({
23374
+ * center: [0, 0],
23375
+ * zoom: 9,
23376
+ * speed: 0.2,
23377
+ * curve: 1,
23378
+ * easing(t) {
23379
+ * return t;
23380
+ * }
23381
+ * });
23320
23382
  * ```
23383
+ * @see [Fly to a location](https://maplibre.org/maplibre-gl-js/docs/examples/fly-to-a-location/)
23384
+ * @see [Slowly fly to a location](https://maplibre.org/maplibre-gl-js/docs/examples/slowly-fly-to-a-location/)
23385
+ * @see [Fly to a location based on scroll position](https://maplibre.org/maplibre-gl-js/docs/examples/fly-to-a-location-based-on-scroll-position/)
23321
23386
  */
23322
- coveringTiles(options) {
23323
- return coveringTiles(this.transform, options);
23387
+ flyTo(options, eventData) {
23388
+ this._camera.flyTo(options, eventData);
23389
+ return this;
23390
+ }
23391
+ /**
23392
+ * Stops any animated transition underway.
23393
+ */
23394
+ stop() {
23395
+ this._camera.stop();
23396
+ return this;
23397
+ }
23398
+ /**
23399
+ * Gets the elevation at a given location, in meters above sea level.
23400
+ * Returns null if terrain is not enabled.
23401
+ * If terrain is enabled with some exaggeration value, the value returned here will be reflective of (multiplied by) that exaggeration value.
23402
+ * This method should be used for proper positioning of custom 3d objects, as explained [here](https://maplibre.org/maplibre-gl-js/docs/examples/adding-3d-models-using-threejs-on-terrain/)
23403
+ * @param lngLatLike - `[x, y]` or LngLat coordinates of the location
23404
+ * @returns elevation in meters
23405
+ */
23406
+ queryTerrainElevation(lngLatLike) {
23407
+ if (!this.terrain) return null;
23408
+ return this.terrain.getElevationForLngLat(LngLat.convert(lngLatLike), this._camera.transform);
23409
+ }
23410
+ /**
23411
+ * Returns the value of `centerClampedToGround`.
23412
+ *
23413
+ * If true, the elevation of the center point will automatically be set to the terrain elevation
23414
+ * (or zero if terrain is not enabled). If false, the elevation of the center point will default
23415
+ * to sea level and will not automatically update. Defaults to true. Needs to be set to false to
23416
+ * keep the camera above ground when pitch \> 90 degrees.
23417
+ */
23418
+ getCenterClampedToGround() {
23419
+ return this._camera.getCenterClampedToGround();
23324
23420
  }
23421
+ /**
23422
+ * Given a camera 'from' position and a position to look at (`to`), calculates zoom and camera rotation and returns them as {@link CameraOptions}.
23423
+ * @param from - The camera to look from
23424
+ * @param altitudeFrom - The altitude of the camera to look from
23425
+ * @param to - The center to look at
23426
+ * @param altitudeTo - Optional altitude of the center to look at. If none given the ground height will be used.
23427
+ * @returns the calculated camera options
23428
+ * @example
23429
+ * ```ts
23430
+ * // Calculate options to look from (1°, 0°, 1000m) to (1°, 1°, 0m)
23431
+ * const cameraLngLat = new LngLat(1, 0);
23432
+ * const cameraAltitude = 1000;
23433
+ * const targetLngLat = new LngLat(1, 1);
23434
+ * const targetAltitude = 0;
23435
+ * const cameraOptions = map.calculateCameraOptionsFromTo(cameraLngLat, cameraAltitude, targetLngLat, targetAltitude);
23436
+ * // Apply calculated options
23437
+ * map.jumpTo(cameraOptions);
23438
+ * ```
23439
+ */
23325
23440
  calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo) {
23326
- if (altitudeTo == null && this.terrain) altitudeTo = this.terrain.getElevationForLngLat(to, this.transform);
23327
- return super.calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo);
23441
+ if (altitudeTo == null && this.terrain) altitudeTo = this.terrain.getElevationForLngLat(to, this._camera.transform);
23442
+ return this._camera.calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo);
23328
23443
  }
23329
23444
  /**
23330
23445
  * Resizes the map according to the dimensions of its
@@ -23349,7 +23464,7 @@ var Map$1 = class extends Camera {
23349
23464
  resize(eventData, constrainTransform = true) {
23350
23465
  if (this._lostContextStyle.style !== null) return this;
23351
23466
  this._resizeInternal(constrainTransform);
23352
- const fireMoving = !this._moving;
23467
+ const fireMoving = !this._camera._moving;
23353
23468
  if (fireMoving) {
23354
23469
  this.stop();
23355
23470
  this.fire(new MapMovementEvent("movestart", eventData)).fire(new MapMovementEvent("move", eventData));
@@ -23386,8 +23501,8 @@ var Map$1 = class extends Camera {
23386
23501
  }
23387
23502
  _resizeTransform(constrainTransform = true) {
23388
23503
  const [width, height] = this._containerDimensions();
23389
- this.transform.resize(width, height, constrainTransform);
23390
- this._requestedCameraState?.resize(width, height, constrainTransform);
23504
+ this._camera.transform.resize(width, height, constrainTransform);
23505
+ this._camera._requestedCameraState?.resize(width, height, constrainTransform);
23391
23506
  }
23392
23507
  /**
23393
23508
  * @internal
@@ -23433,7 +23548,7 @@ var Map$1 = class extends Camera {
23433
23548
  * ```
23434
23549
  */
23435
23550
  getBounds() {
23436
- return this.transform.getBounds();
23551
+ return this._camera.transform.getBounds();
23437
23552
  }
23438
23553
  /**
23439
23554
  * Returns the maximum geographical bounds the map is constrained to, or `null` if none set.
@@ -23444,7 +23559,7 @@ var Map$1 = class extends Camera {
23444
23559
  * ```
23445
23560
  */
23446
23561
  getMaxBounds() {
23447
- return this.transform.getMaxBounds();
23562
+ return this._camera.transform.getMaxBounds();
23448
23563
  }
23449
23564
  /**
23450
23565
  * Sets or clears the map's geographical bounds.
@@ -23468,7 +23583,7 @@ var Map$1 = class extends Camera {
23468
23583
  * ```
23469
23584
  */
23470
23585
  setMaxBounds(bounds) {
23471
- this.transform.setMaxBounds(LngLatBounds.convert(bounds));
23586
+ this._camera.transform.setMaxBounds(LngLatBounds.convert(bounds));
23472
23587
  return this._update();
23473
23588
  }
23474
23589
  /**
@@ -23493,13 +23608,13 @@ var Map$1 = class extends Camera {
23493
23608
  */
23494
23609
  setMinZoom(minZoom) {
23495
23610
  minZoom = minZoom === null || minZoom === void 0 ? defaultMinZoom : minZoom;
23496
- if (minZoom >= defaultMinZoom && minZoom <= this.transform.maxZoom) {
23497
- const zoomBefore = this.transform.zoom;
23498
- const tr = this._getTransformForUpdate();
23611
+ if (minZoom >= defaultMinZoom && minZoom <= this._camera.transform.maxZoom) {
23612
+ const zoomBefore = this._camera.transform.zoom;
23613
+ const tr = this._camera.getTransformForUpdate();
23499
23614
  tr.setMinZoom(minZoom);
23500
- this._applyUpdatedTransform(tr);
23615
+ this._camera.applyUpdatedTransform(tr);
23501
23616
  this._update();
23502
- if (zoomBefore !== this.transform.zoom) this.fire(new MapMovementEvent("zoomstart")).fire(new MapMovementEvent("zoom")).fire(new MapMovementEvent("zoomend")).fire(new MapMovementEvent("movestart")).fire(new MapMovementEvent("move")).fire(new MapMovementEvent("moveend"));
23617
+ if (zoomBefore !== this._camera.transform.zoom) this.fire(new MapMovementEvent("zoomstart")).fire(new MapMovementEvent("zoom")).fire(new MapMovementEvent("zoomend")).fire(new MapMovementEvent("movestart")).fire(new MapMovementEvent("move")).fire(new MapMovementEvent("moveend"));
23503
23618
  return this;
23504
23619
  } else throw new Error(`minZoom must be between ${defaultMinZoom} and the current maxZoom, inclusive`);
23505
23620
  }
@@ -23513,7 +23628,7 @@ var Map$1 = class extends Camera {
23513
23628
  * ```
23514
23629
  */
23515
23630
  getMinZoom() {
23516
- return this.transform.minZoom;
23631
+ return this._camera.transform.minZoom;
23517
23632
  }
23518
23633
  /**
23519
23634
  * Sets or clears the map's maximum zoom level.
@@ -23532,13 +23647,13 @@ var Map$1 = class extends Camera {
23532
23647
  */
23533
23648
  setMaxZoom(maxZoom) {
23534
23649
  maxZoom = maxZoom === null || maxZoom === void 0 ? defaultMaxZoom : maxZoom;
23535
- if (maxZoom >= this.transform.minZoom) {
23536
- const zoomBefore = this.transform.zoom;
23537
- const tr = this._getTransformForUpdate();
23650
+ if (maxZoom >= this._camera.transform.minZoom) {
23651
+ const zoomBefore = this._camera.transform.zoom;
23652
+ const tr = this._camera.getTransformForUpdate();
23538
23653
  tr.setMaxZoom(maxZoom);
23539
- this._applyUpdatedTransform(tr);
23654
+ this._camera.applyUpdatedTransform(tr);
23540
23655
  this._update();
23541
- if (zoomBefore !== this.transform.zoom) this.fire(new MapMovementEvent("zoomstart")).fire(new MapMovementEvent("zoom")).fire(new MapMovementEvent("zoomend")).fire(new MapMovementEvent("movestart")).fire(new MapMovementEvent("move")).fire(new MapMovementEvent("moveend"));
23656
+ if (zoomBefore !== this._camera.transform.zoom) this.fire(new MapMovementEvent("zoomstart")).fire(new MapMovementEvent("zoom")).fire(new MapMovementEvent("zoomend")).fire(new MapMovementEvent("movestart")).fire(new MapMovementEvent("move")).fire(new MapMovementEvent("moveend"));
23542
23657
  return this;
23543
23658
  } else throw new Error("maxZoom must be greater than the current minZoom");
23544
23659
  }
@@ -23552,7 +23667,7 @@ var Map$1 = class extends Camera {
23552
23667
  * ```
23553
23668
  */
23554
23669
  getMaxZoom() {
23555
- return this.transform.maxZoom;
23670
+ return this._camera.transform.maxZoom;
23556
23671
  }
23557
23672
  /**
23558
23673
  * Sets or clears the map's minimum pitch.
@@ -23568,13 +23683,13 @@ var Map$1 = class extends Camera {
23568
23683
  setMinPitch(minPitch) {
23569
23684
  minPitch = minPitch === null || minPitch === void 0 ? defaultMinPitch : minPitch;
23570
23685
  if (minPitch < defaultMinPitch) throw new Error(`minPitch must be greater than or equal to ${defaultMinPitch}`);
23571
- if (minPitch >= defaultMinPitch && minPitch <= this.transform.maxPitch) {
23572
- const pitchBefore = this.transform.pitch;
23573
- const tr = this._getTransformForUpdate();
23686
+ if (minPitch >= defaultMinPitch && minPitch <= this._camera.transform.maxPitch) {
23687
+ const pitchBefore = this._camera.transform.pitch;
23688
+ const tr = this._camera.getTransformForUpdate();
23574
23689
  tr.setMinPitch(minPitch);
23575
- this._applyUpdatedTransform(tr);
23690
+ this._camera.applyUpdatedTransform(tr);
23576
23691
  this._update();
23577
- if (pitchBefore !== this.transform.pitch) this.fire(new MapMovementEvent("pitchstart")).fire(new MapMovementEvent("pitch")).fire(new MapMovementEvent("pitchend")).fire(new MapMovementEvent("movestart")).fire(new MapMovementEvent("move")).fire(new MapMovementEvent("moveend"));
23692
+ if (pitchBefore !== this._camera.transform.pitch) this.fire(new MapMovementEvent("pitchstart")).fire(new MapMovementEvent("pitch")).fire(new MapMovementEvent("pitchend")).fire(new MapMovementEvent("movestart")).fire(new MapMovementEvent("move")).fire(new MapMovementEvent("moveend"));
23578
23693
  return this;
23579
23694
  } else throw new Error(`minPitch must be between ${defaultMinPitch} and the current maxPitch, inclusive`);
23580
23695
  }
@@ -23584,7 +23699,7 @@ var Map$1 = class extends Camera {
23584
23699
  * @returns The minPitch
23585
23700
  */
23586
23701
  getMinPitch() {
23587
- return this.transform.minPitch;
23702
+ return this._camera.transform.minPitch;
23588
23703
  }
23589
23704
  /**
23590
23705
  * Sets or clears the map's maximum pitch.
@@ -23600,13 +23715,13 @@ var Map$1 = class extends Camera {
23600
23715
  setMaxPitch(maxPitch) {
23601
23716
  maxPitch = maxPitch === null || maxPitch === void 0 ? defaultMaxPitch : maxPitch;
23602
23717
  if (maxPitch > maxPitchThreshold) throw new Error(`maxPitch must be less than or equal to ${maxPitchThreshold}`);
23603
- if (maxPitch >= this.transform.minPitch) {
23604
- const pitchBefore = this.transform.pitch;
23605
- const tr = this._getTransformForUpdate();
23718
+ if (maxPitch >= this._camera.transform.minPitch) {
23719
+ const pitchBefore = this._camera.transform.pitch;
23720
+ const tr = this._camera.getTransformForUpdate();
23606
23721
  tr.setMaxPitch(maxPitch);
23607
- this._applyUpdatedTransform(tr);
23722
+ this._camera.applyUpdatedTransform(tr);
23608
23723
  this._update();
23609
- if (pitchBefore !== this.transform.pitch) this.fire(new MapMovementEvent("pitchstart")).fire(new MapMovementEvent("pitch")).fire(new MapMovementEvent("pitchend")).fire(new MapMovementEvent("movestart")).fire(new MapMovementEvent("move")).fire(new MapMovementEvent("moveend"));
23724
+ if (pitchBefore !== this._camera.transform.pitch) this.fire(new MapMovementEvent("pitchstart")).fire(new MapMovementEvent("pitch")).fire(new MapMovementEvent("pitchend")).fire(new MapMovementEvent("movestart")).fire(new MapMovementEvent("move")).fire(new MapMovementEvent("moveend"));
23610
23725
  return this;
23611
23726
  } else throw new Error("maxPitch must be greater than the current minPitch");
23612
23727
  }
@@ -23616,7 +23731,7 @@ var Map$1 = class extends Camera {
23616
23731
  * @returns The maxPitch
23617
23732
  */
23618
23733
  getMaxPitch() {
23619
- return this.transform.maxPitch;
23734
+ return this._camera.transform.maxPitch;
23620
23735
  }
23621
23736
  /**
23622
23737
  * Returns the map's anisotropic filter pitch.
@@ -23667,7 +23782,7 @@ var Map$1 = class extends Camera {
23667
23782
  * @see [Render world copies](https://maplibre.org/maplibre-gl-js/docs/examples/render-world-copies/)
23668
23783
  */
23669
23784
  getRenderWorldCopies() {
23670
- return this.transform.renderWorldCopies;
23785
+ return this._camera.transform.renderWorldCopies;
23671
23786
  }
23672
23787
  /**
23673
23788
  * Sets the state of `renderWorldCopies`.
@@ -23687,7 +23802,7 @@ var Map$1 = class extends Camera {
23687
23802
  * @see [Render world copies](https://maplibre.org/maplibre-gl-js/docs/examples/render-world-copies/)
23688
23803
  */
23689
23804
  setRenderWorldCopies(renderWorldCopies) {
23690
- this.transform.setRenderWorldCopies(renderWorldCopies);
23805
+ this._camera.transform.setRenderWorldCopies(renderWorldCopies);
23691
23806
  return this._update();
23692
23807
  }
23693
23808
  /** Sets or clears the callback overriding how the map constrains the viewport's lnglat and zoom to respect the longitude and latitude bounds.
@@ -23705,7 +23820,7 @@ var Map$1 = class extends Camera {
23705
23820
  * @see [Customize the map transform constrain](https://maplibre.org/maplibre-gl-js/docs/examples/customize-the-map-transform-constrain/)
23706
23821
  */
23707
23822
  setTransformConstrain(constrain) {
23708
- this.transform.setConstrainOverride(constrain);
23823
+ this._camera.transform.setConstrainOverride(constrain);
23709
23824
  return this._update();
23710
23825
  }
23711
23826
  /**
@@ -23721,7 +23836,7 @@ var Map$1 = class extends Camera {
23721
23836
  * ```
23722
23837
  */
23723
23838
  project(lnglat) {
23724
- return this.transform.locationToScreenPoint(LngLat.convert(lnglat), this.style && this.terrain);
23839
+ return this._camera.transform.locationToScreenPoint(LngLat.convert(lnglat), this.style && this.terrain);
23725
23840
  }
23726
23841
  /**
23727
23842
  * Returns a {@link LngLat} representing geographical coordinates that correspond
@@ -23738,7 +23853,7 @@ var Map$1 = class extends Camera {
23738
23853
  * ```
23739
23854
  */
23740
23855
  unproject(point) {
23741
- return this.transform.screenPointToLocation(Point.convert(point), this.terrain);
23856
+ return this._camera.transform.screenPointToLocation(Point.convert(point), this.terrain);
23742
23857
  }
23743
23858
  /**
23744
23859
  * Returns true if the map is panning, zooming, rotating, or pitching due to a camera animation or user gesture.
@@ -23749,7 +23864,7 @@ var Map$1 = class extends Camera {
23749
23864
  * ```
23750
23865
  */
23751
23866
  isMoving() {
23752
- return this._moving || this.handlers?.isMoving();
23867
+ return this._camera.isMoving() || this._handlers?.isMoving() || false;
23753
23868
  }
23754
23869
  /**
23755
23870
  * Returns true if the map is zooming due to a camera animation or user gesture.
@@ -23760,7 +23875,7 @@ var Map$1 = class extends Camera {
23760
23875
  * ```
23761
23876
  */
23762
23877
  isZooming() {
23763
- return this._zooming || this.handlers?.isZooming();
23878
+ return this._camera.isZooming() || this._handlers?.isZooming() || false;
23764
23879
  }
23765
23880
  /**
23766
23881
  * Returns true if the map is rotating due to a camera animation or user gesture.
@@ -23771,7 +23886,7 @@ var Map$1 = class extends Camera {
23771
23886
  * ```
23772
23887
  */
23773
23888
  isRotating() {
23774
- return this._rotating || this.handlers?.isRotating();
23889
+ return this._camera.isRotating() || this._handlers?.isRotating() || false;
23775
23890
  }
23776
23891
  _createDelegatedListener(type, layerIds, listener) {
23777
23892
  if (type === "mouseenter" || type === "mouseover") {
@@ -23969,7 +24084,7 @@ var Map$1 = class extends Camera {
23969
24084
  if (!this.style) return [];
23970
24085
  let queryGeometry;
23971
24086
  const isGeometry = geometryOrOptions instanceof Point || Array.isArray(geometryOrOptions);
23972
- const geometry = isGeometry ? geometryOrOptions : [[0, 0], [this.transform.width, this.transform.height]];
24087
+ const geometry = isGeometry ? geometryOrOptions : [[0, 0], [this._camera.transform.width, this._camera.transform.height]];
23973
24088
  options ||= (isGeometry ? {} : geometryOrOptions) || {};
23974
24089
  if (geometry instanceof Point || typeof geometry[0] === "number") queryGeometry = [Point.convert(geometry)];
23975
24090
  else {
@@ -23983,7 +24098,7 @@ var Map$1 = class extends Camera {
23983
24098
  tl
23984
24099
  ];
23985
24100
  }
23986
- return this.style.queryRenderedFeatures(queryGeometry, options, this.transform);
24101
+ return this.style.queryRenderedFeatures(queryGeometry, options, this._camera.transform);
23987
24102
  }
23988
24103
  /**
23989
24104
  * Returns an array of MapGeoJSONFeature objects
@@ -24290,8 +24405,9 @@ var Map$1 = class extends Camera {
24290
24405
  if (this.terrain) this.terrain.destroy();
24291
24406
  this.terrain = null;
24292
24407
  this.painter.renderToTexture = null;
24293
- this.transform.setMinElevationForCurrentTile(0);
24294
- if (this._centerClampedToGround) this.transform.setElevation(0);
24408
+ this._camera.terrain = null;
24409
+ this._camera.transform.setMinElevationForCurrentTile(0);
24410
+ if (this.getCenterClampedToGround()) this._camera.transform.setElevation(0);
24295
24411
  } else {
24296
24412
  const tileManager = this.style.tileManagers[options.source];
24297
24413
  if (!tileManager) throw new Error(`cannot load terrain, because there exists no source with ID: ${options.source}`);
@@ -24303,14 +24419,15 @@ var Map$1 = class extends Camera {
24303
24419
  }
24304
24420
  this.terrain = new Terrain(this.painter, tileManager, options, this._terrainSkirtLength);
24305
24421
  this.painter.renderToTexture = new RenderToTexture(this.painter, this.terrain);
24306
- this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this.transform.center, this.transform.tileZoom));
24307
- this.transform.setElevation(this.terrain.getElevationForLngLatZoom(this.transform.center, this.transform.tileZoom));
24422
+ this._camera.terrain = this.terrain;
24423
+ this._camera.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this._camera.transform.center, this._camera.transform.tileZoom));
24424
+ this._camera.transform.setElevation(this.terrain.getElevationForLngLatZoom(this._camera.transform.center, this._camera.transform.tileZoom));
24308
24425
  this._terrainDataCallback = (e) => {
24309
24426
  if (e.dataType === "style") this.terrain.tileManager.releaseAllRTT();
24310
24427
  else if (e.dataType === "source" && e.tile) {
24311
- if (e.sourceId === options.source && !this._elevationFreeze) {
24312
- this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this.transform.center, this.transform.tileZoom));
24313
- if (this._centerClampedToGround) this.transform.setElevation(this.terrain.getElevationForLngLatZoom(this.transform.center, this.transform.tileZoom));
24428
+ if (e.sourceId === options.source && !this._camera.elevationFreeze) {
24429
+ this._camera.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this._camera.transform.center, this._camera.transform.tileZoom));
24430
+ if (this.getCenterClampedToGround()) this._camera.transform.setElevation(this.terrain.getElevationForLngLatZoom(this._camera.transform.center, this._camera.transform.tileZoom));
24314
24431
  }
24315
24432
  if (e.source?.type === "image") this.terrain.tileManager.releaseAllRTT();
24316
24433
  else this.terrain.tileManager.releaseRTT(e.tile.tileID);
@@ -25287,10 +25404,16 @@ var Map$1 = class extends Camera {
25287
25404
  this.fire(new ErrorEvent(new GPUInitializationError(attributes, creationEvent)));
25288
25405
  return;
25289
25406
  }
25290
- this.painter = new Painter(gl, this.transform);
25407
+ this.painter = new Painter(gl, this._camera.transform);
25291
25408
  }
25409
+ /**
25410
+ * @internal
25411
+ * Creates a new specialized transform instance from a projection instance and migrates
25412
+ * to this new transform, carrying over all the properties of the old transform (center, pitch, etc.).
25413
+ * When the style's projection is changed (or first set), this function should be called.
25414
+ */
25292
25415
  migrateProjection(newTransform, newCameraHelper) {
25293
- super.migrateProjection(newTransform, newCameraHelper);
25416
+ this._camera.migrateProjection(newTransform, newCameraHelper);
25294
25417
  this.painter.transform = newTransform;
25295
25418
  this.fire(new MapProjectionEvent({ newProjection: this.style.projection.name }));
25296
25419
  }
@@ -25355,7 +25478,7 @@ var Map$1 = class extends Camera {
25355
25478
  let crossFading = false;
25356
25479
  if (this.style && this._styleDirty) {
25357
25480
  this._styleDirty = false;
25358
- const zoom = this.transform.zoom;
25481
+ const zoom = this._camera.transform.zoom;
25359
25482
  const currentTime = now();
25360
25483
  this.style.zoomHistory.update(zoom, currentTime);
25361
25484
  const parameters = new EvaluationParameters(zoom, {
@@ -25372,21 +25495,21 @@ var Map$1 = class extends Camera {
25372
25495
  this.style.update(parameters);
25373
25496
  }
25374
25497
  const globeRenderingChanged = this.style.projection?.transitionState > 0 !== isGlobeRendering;
25375
- this.style.projection?.setErrorQueryLatitudeDegrees(this.transform.center.lat);
25376
- this.transform.setTransitionState(this.style.projection?.transitionState, this.style.projection?.latitudeErrorCorrectionRadians);
25498
+ this.style.projection?.setErrorQueryLatitudeDegrees(this._camera.transform.center.lat);
25499
+ this._camera.transform.setTransitionState(this.style.projection?.transitionState, this.style.projection?.latitudeErrorCorrectionRadians);
25377
25500
  if (this.style && (this._sourcesDirty || globeRenderingChanged)) {
25378
25501
  this._sourcesDirty = false;
25379
- this.style._updateSources(this.transform);
25502
+ this.style._updateSources(this._camera.transform);
25380
25503
  }
25381
25504
  if (this.terrain) {
25382
- this.terrain.tileManager.update(this.transform, this.terrain);
25383
- this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this.transform.center, this.transform.tileZoom));
25384
- if (!this._elevationFreeze && this._centerClampedToGround) this.transform.setElevation(this.terrain.getElevationForLngLatZoom(this.transform.center, this.transform.tileZoom));
25505
+ this.terrain.tileManager.update(this._camera.transform, this.terrain);
25506
+ this._camera.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this._camera.transform.center, this._camera.transform.tileZoom));
25507
+ if (!this._camera.elevationFreeze && this.getCenterClampedToGround()) this._camera.transform.setElevation(this.terrain.getElevationForLngLatZoom(this._camera.transform.center, this._camera.transform.tileZoom));
25385
25508
  } else {
25386
- this.transform.setMinElevationForCurrentTile(0);
25387
- if (this._centerClampedToGround) this.transform.setElevation(0);
25509
+ this._camera.transform.setMinElevationForCurrentTile(0);
25510
+ if (this.getCenterClampedToGround()) this._camera.transform.setElevation(0);
25388
25511
  }
25389
- this._placementDirty = this.style?._updatePlacement(this.transform, this.showCollisionBoxes, fadeDuration, this._crossSourceCollisions, globeRenderingChanged);
25512
+ this._placementDirty = this.style?._updatePlacement(this._camera.transform, this.showCollisionBoxes, fadeDuration, this._crossSourceCollisions, globeRenderingChanged);
25390
25513
  this.painter.render(this.style, {
25391
25514
  showTileBoundaries: this.showTileBoundaries,
25392
25515
  showOverdrawInspector: this._showOverdrawInspector,
@@ -25447,8 +25570,7 @@ var Map$1 = class extends Camera {
25447
25570
  this._renderTaskQueue.clear();
25448
25571
  this._diffStyleRequest?.abort();
25449
25572
  this.painter.destroy();
25450
- this.handlers.destroy();
25451
- delete this.handlers;
25573
+ this._handlers.destroy();
25452
25574
  this.setStyle(null);
25453
25575
  if (typeof window !== "undefined") this._ownerWindow.removeEventListener("online", this._onWindowOnline, false);
25454
25576
  ImageRequest.removeThrottleControl(this._imageQueueHandle);
@@ -25585,7 +25707,7 @@ var Map$1 = class extends Camera {
25585
25707
  * @returns The elevation.
25586
25708
  */
25587
25709
  getCameraTargetElevation() {
25588
- return this.transform.elevation;
25710
+ return this._camera.transform.elevation;
25589
25711
  }
25590
25712
  /**
25591
25713
  * Gets the {@link ProjectionSpecification}.
@@ -25644,19 +25766,23 @@ var NavigationControl = class {
25644
25766
  this._zoomOutButton.setAttribute("aria-disabled", isMin.toString());
25645
25767
  };
25646
25768
  this._rotateCompassArrow = () => {
25769
+ const pitch = this._map.getPitch();
25770
+ const roll = this._map.getRoll();
25771
+ const bearing = this._map.getBearing();
25772
+ const pitchScale = 1 / Math.pow(Math.cos(degreesToRadians(pitch)), .5);
25647
25773
  if (this.options.visualizePitch && this.options.visualizeRoll) {
25648
- this._compassIcon.style.transform = `scale(${1 / Math.pow(Math.cos(this._map.transform.pitchInRadians), .5)}) rotateZ(${-this._map.transform.roll}deg) rotateX(${this._map.transform.pitch}deg) rotateZ(${-this._map.transform.bearing}deg)`;
25774
+ this._compassIcon.style.transform = `scale(${pitchScale}) rotateZ(${-roll}deg) rotateX(${pitch}deg) rotateZ(${-bearing}deg)`;
25649
25775
  return;
25650
25776
  }
25651
25777
  if (this.options.visualizePitch) {
25652
- this._compassIcon.style.transform = `scale(${1 / Math.pow(Math.cos(this._map.transform.pitchInRadians), .5)}) rotateX(${this._map.transform.pitch}deg) rotateZ(${-this._map.transform.bearing}deg)`;
25778
+ this._compassIcon.style.transform = `scale(${pitchScale}) rotateX(${pitch}deg) rotateZ(${-bearing}deg)`;
25653
25779
  return;
25654
25780
  }
25655
25781
  if (this.options.visualizeRoll) {
25656
- this._compassIcon.style.transform = `rotate(${-this._map.transform.bearing - this._map.transform.roll}deg)`;
25782
+ this._compassIcon.style.transform = `rotate(${-bearing - roll}deg)`;
25657
25783
  return;
25658
25784
  }
25659
- this._compassIcon.style.transform = `rotate(${-this._map.transform.bearing}deg)`;
25785
+ this._compassIcon.style.transform = `rotate(${-bearing}deg)`;
25660
25786
  };
25661
25787
  this._setButtonTitle = (button, title) => {
25662
25788
  const str = this._map._getUIString(`NavigationControl.${title}`);
@@ -25966,9 +26092,9 @@ var Marker = class extends Evented {
25966
26092
  if (!this._map) return;
25967
26093
  const isFullyLoaded = this._map.loaded() && !this._map.isMoving();
25968
26094
  if (e?.type === "terrain" || e?.type === "render" && !isFullyLoaded) this._map.once("render", this._update);
25969
- this._lngLat = smartWrap(this._lngLat, this._flatPos, this._map.transform);
26095
+ this._lngLat = smartWrap(this._lngLat, this._flatPos, this._map._camera.transform);
25970
26096
  this._flatPos = this._pos = this._map.project(this._lngLat)._add(this._offset);
25971
- if (this._map.terrain) this._flatPos = this._map.transform.locationToScreenPoint(this._lngLat)._add(this._offset);
26097
+ if (this._map.terrain) this._flatPos = this._map._camera.transform.locationToScreenPoint(this._lngLat)._add(this._offset);
25972
26098
  let rotation = "";
25973
26099
  if (this._rotationAlignment === "viewport" || this._rotationAlignment === "auto") rotation = `rotateZ(${this._rotation}deg)`;
25974
26100
  else if (this._rotationAlignment === "map") rotation = `rotateZ(${this._rotation - this._map.getBearing()}deg)`;
@@ -26351,7 +26477,7 @@ var Marker = class extends Evented {
26351
26477
  }
26352
26478
  _updateOpacity(force = false) {
26353
26479
  const terrain = this._map?.terrain;
26354
- const occluded = this._map.transform.isLocationOccluded(this._lngLat);
26480
+ const occluded = this._map._camera.transform.isLocationOccluded(this._lngLat);
26355
26481
  if (!terrain || occluded) {
26356
26482
  const targetOpacity = occluded ? this._opacityWhenCovered : this._opacity;
26357
26483
  if (this._element.style.opacity !== targetOpacity) {
@@ -26369,18 +26495,18 @@ var Marker = class extends Evented {
26369
26495
  }
26370
26496
  const map = this._map;
26371
26497
  const terrainDistance = map.terrain.depthAtPoint(this._pos);
26372
- const elevation = map.terrain.getElevationForLngLat(this._lngLat, map.transform);
26373
- const markerDistance = map.transform.lngLatToCameraDepth(this._lngLat, elevation);
26498
+ const elevation = map.terrain.getElevationForLngLat(this._lngLat, map._camera.transform);
26499
+ const markerDistance = map._camera.transform.lngLatToCameraDepth(this._lngLat, elevation);
26374
26500
  const forgiveness = .006;
26375
26501
  if (markerDistance - terrainDistance < forgiveness) {
26376
26502
  this._element.style.opacity = this._opacity;
26377
26503
  this._element.classList.remove("maplibregl-marker-covered");
26378
26504
  return;
26379
26505
  }
26380
- const metersToCenter = -this._offset.y / map.transform.pixelsPerMeter;
26506
+ const metersToCenter = -this._offset.y / map._camera.transform.pixelsPerMeter;
26381
26507
  const elevationToCenter = Math.sin(map.getPitch() * Math.PI / 180) * metersToCenter;
26382
26508
  const terrainDistanceCenter = map.terrain.depthAtPoint(new Point(this._pos.x, this._pos.y - this._offset.y));
26383
- const centerIsInvisible = map.transform.lngLatToCameraDepth(this._lngLat, elevation + elevationToCenter) - terrainDistanceCenter > forgiveness;
26509
+ const centerIsInvisible = map._camera.transform.lngLatToCameraDepth(this._lngLat, elevation + elevationToCenter) - terrainDistanceCenter > forgiveness;
26384
26510
  if (this._popup?.isOpen() && centerIsInvisible) this._popup.remove();
26385
26511
  this._element.style.opacity = centerIsInvisible ? this._opacityWhenCovered : this._opacity;
26386
26512
  this._element.classList.toggle("maplibregl-marker-covered", centerIsInvisible);
@@ -27486,7 +27612,7 @@ var Popup = class extends Evented {
27486
27612
  super();
27487
27613
  this._updateOpacity = () => {
27488
27614
  if (this.options.locationOccludedOpacity === void 0) return;
27489
- if (this._map.transform.isLocationOccluded(this.getLngLat())) this._container.style.opacity = `${this.options.locationOccludedOpacity}`;
27615
+ if (this._map._camera.transform.isLocationOccluded(this.getLngLat())) this._container.style.opacity = `${this.options.locationOccludedOpacity}`;
27490
27616
  else this._container.style.opacity = "";
27491
27617
  };
27492
27618
  this.remove = () => {
@@ -27523,12 +27649,12 @@ var Popup = class extends Evented {
27523
27649
  if (this._trackPointer) this._container.classList.add("maplibregl-popup-track-pointer");
27524
27650
  }
27525
27651
  if (this.options.maxWidth && this._container.style.maxWidth !== this.options.maxWidth) this._container.style.maxWidth = this.options.maxWidth;
27526
- this._lngLat = smartWrap(this._lngLat, this._flatPos, this._map.transform, this._trackPointer);
27652
+ this._lngLat = smartWrap(this._lngLat, this._flatPos, this._map._camera.transform, this._trackPointer);
27527
27653
  let cursor;
27528
27654
  if (event && "point" in event && event.point) cursor = event.point;
27529
27655
  if (this._trackPointer && !cursor) return;
27530
27656
  const pos = this._flatPos = this._pos = this._trackPointer && cursor ? cursor : this._map.project(this._lngLat);
27531
- if (this._map.terrain) this._flatPos = this._trackPointer && cursor ? cursor : this._map.transform.locationToScreenPoint(this._lngLat);
27657
+ if (this._map.terrain) this._flatPos = this._trackPointer && cursor ? cursor : this._map._camera.transform.locationToScreenPoint(this._lngLat);
27532
27658
  let anchor = this.options.anchor;
27533
27659
  const offset = normalizeOffset(this.options.offset);
27534
27660
  if (!anchor) {
@@ -27537,10 +27663,10 @@ var Popup = class extends Evented {
27537
27663
  const padding = normalizePadding(this.options.padding);
27538
27664
  let anchorComponents;
27539
27665
  if (pos.y + offset.bottom.y < height + padding.top) anchorComponents = ["top"];
27540
- else if (pos.y > this._map.transform.height - height - padding.bottom) anchorComponents = ["bottom"];
27666
+ else if (pos.y > this._map._camera.transform.height - height - padding.bottom) anchorComponents = ["bottom"];
27541
27667
  else anchorComponents = [];
27542
27668
  if (pos.x < width / 2 + padding.left) anchorComponents.push("left");
27543
- else if (pos.x > this._map.transform.width - width / 2 - padding.right) anchorComponents.push("right");
27669
+ else if (pos.x > this._map._camera.transform.width - width / 2 - padding.right) anchorComponents.push("right");
27544
27670
  if (anchorComponents.length === 0) anchor = "bottom";
27545
27671
  else anchor = anchorComponents.join("-");
27546
27672
  }