From b1aeecf83b9b604bde5c9ee4f41eb9b32fefe7f1 Mon Sep 17 00:00:00 2001 From: fuzhenn Date: Wed, 26 Feb 2025 10:22:22 +0800 Subject: [PATCH 1/4] change meterToGLPoint to altitudeToPoint, add map._queryTerrain, add map.infiniteProjViewMatrix, rename map.getFitZoomForCameraCenterDistance, add map.isDragging --- packages/maptalks/src/layer/tile/TileLayer.ts | 2 +- packages/maptalks/src/map/Map.Camera.ts | 59 ++++++++++++++----- .../maptalks/src/map/Map.CoordTransform.ts | 2 +- packages/maptalks/src/map/Map.ts | 13 ++++ packages/maptalks/src/map/handler/Map.Drag.ts | 2 + packages/maptalks/test/map/MapSpec.js | 7 +++ 6 files changed, 69 insertions(+), 16 deletions(-) diff --git a/packages/maptalks/src/layer/tile/TileLayer.ts b/packages/maptalks/src/layer/tile/TileLayer.ts index 7d5161e7eb..5d3d8b536d 100644 --- a/packages/maptalks/src/layer/tile/TileLayer.ts +++ b/packages/maptalks/src/layer/tile/TileLayer.ts @@ -470,7 +470,7 @@ class TileLayer extends Layer { const sr = this.getSpatialReference(); const maxZoom = Math.min(z, this.getMaxZoom(), this.getMaxAvailableZoom() || Infinity); // @ts-ignore - const projectionView = map.projViewMatrix; + const projectionView = map.infiniteProjViewMatrix; const fullExtent = this._getTileFullExtent(); const offset0 = this._getTileOffset(0); diff --git a/packages/maptalks/src/map/Map.Camera.ts b/packages/maptalks/src/map/Map.Camera.ts index 9525b2f0f5..9db04d2057 100644 --- a/packages/maptalks/src/map/Map.Camera.ts +++ b/packages/maptalks/src/map/Map.Camera.ts @@ -10,9 +10,17 @@ import Browser from '../core/Browser'; declare module "./Map" { export interface Map { + cameraCoordinate: Coordinate; cameraPosition: [number, number, number]; cameraLookAt: [number, number, number]; + cameraNear: number; + camerFar: number; + cameraCenterDistance: number; + cameraZenithDistance: number; + cameraUp: [number, number, number]; + cameraForward: [number, number, number]; projViewMatrix: Matrix4; + infiniteProjViewMatrix: Matrix4; getFov(): number; setFov(fov: number): this; getBearing(): number; @@ -24,16 +32,20 @@ declare module "./Map" { //@internal _setPitch(pitch: number): this; //@internal + _meterToGLPoint: number; + //@internal _calcMatrices(): void; //@internal _containerPointToPoint(p: Point, zoom?: number, out?: Point, height?: number): Point; //@internal _recenterOnTerrain(): void; + //@internal + _setCenterSilently(center: CoordinateLike): void; setCameraMovements(frameOptions: Array, option?: { autoRotate: boolean }); setCameraOrientation(params: MapViewType): this; setCameraPosition(coordinate: Coordinate); getFitZoomForCamera(cameraPosition: [number, number, number], pitch: number); - getFitZoomForAltitude(altitude: number); + getFitZoomForCameraCenterDistance(altitude: number); isTransforming(): boolean; getFrustumAltitude(): number; updateCenterAltitude(); @@ -53,6 +65,8 @@ declare module "./Map" { //@internal _query3DTilesInfo(containerPoint: Point); //@internal + _queryTerrain(coordinate: Coordinate): number; + //@internal _queryTerrainInfo(containerPoint: Point); //@internal queryPrjCoordAtContainerPoint(containerPoint: Point); @@ -419,11 +433,11 @@ Map.include(/** @lends Map.prototype */{ const cameraToCenterDistance = cameraToGroundDistance + centerPointZ; - const zoom = this.getFitZoomForAltitude(cameraToCenterDistance); + const zoom = this.getFitZoomForCameraCenterDistance(cameraToCenterDistance); return { zoom, cameraToGroundDistance }; }, - getFitZoomForAltitude(distance: number) { + getFitZoomForCameraCenterDistance(distance: number) { const ratio = this._getFovRatio(); const scale = distance * ratio * 2 / (this.height || 1) * this.getGLRes(); const resolutions = this._getResolutions(); @@ -699,11 +713,15 @@ Map.include(/** @lends Map.prototype */{ const projMatrix = this.projMatrix || createMat4(); mat4.perspective(projMatrix, fov, w / h, this.cameraNear, farZ); this.projMatrix = projMatrix; + const infiniteProjMatrix = this.infiniteProjMatrix || createMat4(); + mat4.perspective(infiniteProjMatrix, fov, w / h, this.cameraNear, 1e40); + this.infiniteProjMatrix = infiniteProjMatrix; // view matrix this.viewMatrix = mat4.invert(this.viewMatrix || createMat4(), worldMatrix); // matrix for world point => screen point this.projViewMatrix = mat4.multiply(this.projViewMatrix || createMat4(), projMatrix, this.viewMatrix); + this.infiniteProjViewMatrix = mat4.multiply(this.infiniteProjViewMatrix || createMat4(), infiniteProjMatrix, this.viewMatrix); this._calcCascadeMatrixes(); // matrix for screen point => world point this.projViewMatrixInverse = mat4.multiply(this.projViewMatrixInverse || createMat4(), worldMatrix, mat4.invert(m1, projMatrix)); @@ -816,7 +834,7 @@ Map.include(/** @lends Map.prototype */{ return function () { const glRes = this.getGLRes(); if (!this._meterToGLPoint) { - this._meterToGLPoint = this.distanceToPointAtRes(100, 0, glRes).x / 100; + this._meterToGLPoint = this.altitudeToPoint(100, glRes) / 100; } const center2D = this._prjToPointAtRes(this._prjCenter, glRes, TEMP_POINT); @@ -950,14 +968,18 @@ Map.include(/** @lends Map.prototype */{ this.centerAltitude = centerAltitude; // this._setPrjCenter(newPrjCenter); const newCenter = this.pointAtResToCoordinate(center2D, this.getGLRes(), TEMP_COORD); + this._setCenterSilently(newCenter); + if (isNil(queriedAltitude)) { + delete this.centerAltitude; + } + }, + + _setCenterSilently(newCenter: Coordinate) { this._eventSilence = true; this._suppressRecenter = true; this.setCenter(newCenter); delete this._suppressRecenter; delete this._eventSilence; - if (isNil(queriedAltitude)) { - delete this.centerAltitude; - } }, // _adjustZoomOnTerrain() { // const z = this._eventCameraZ; @@ -1004,17 +1026,26 @@ Map.include(/** @lends Map.prototype */{ }, //@internal - _queryTerrainInfo(containerPoint) { + _queryTerrain(coord: Coordinate) { + return this._queryTerrainImp(coord); + }, + + //@internal + _queryTerrainInfo(containerPoint: Point) { + return this._queryTerrainImp(containerPoint); + }, + + //@internal + _queryTerrainImp(coord: Coordinate | Point) { + const isCoordinate = coord instanceof Coordinate; + const fnName = isCoordinate ? 'queryTerrain' : 'queryTerrainAtPoint'; const layers = this._getLayers() || []; for (let i = 0; i < layers.length; i++) { const layer = layers[i]; - if (containerPoint && layer && layer.queryTerrainAtPoint && layer.getTerrainLayer && layer.getTerrainLayer()) { - const coordinate = layer.queryTerrainAtPoint(containerPoint); + if (coord && layer && layer[fnName] && layer.getTerrainLayer && layer.getTerrainLayer()) { + const coordinate = layer[fnName](coord); if (coordinate) { - return { - coordinate, - altitude: coordinate.z - }; + return isCoordinate ? coordinate[0] : { coordinate, altitude: coordinate.z }; } else { break; } diff --git a/packages/maptalks/src/map/Map.CoordTransform.ts b/packages/maptalks/src/map/Map.CoordTransform.ts index e54af1ccd7..2795c2ff02 100644 --- a/packages/maptalks/src/map/Map.CoordTransform.ts +++ b/packages/maptalks/src/map/Map.CoordTransform.ts @@ -137,7 +137,7 @@ declare module "./Map" { * @param [originCenter=null] - optional original coordinate for caculation * @return */ altitudeToPoint(altitude: number, res?: number, originCenter?: Coordinate): number; - pointAtResToAltitude(point: Point, res?: number, originCenter?: Coordinate): number; + pointAtResToAltitude(point: number, res?: number, originCenter?: Coordinate): number; /** * Converts pixel size to geographical distance. * diff --git a/packages/maptalks/src/map/Map.ts b/packages/maptalks/src/map/Map.ts index b6b5fcddc7..73fc8460b3 100644 --- a/packages/maptalks/src/map/Map.ts +++ b/packages/maptalks/src/map/Map.ts @@ -265,6 +265,10 @@ export class Map extends Handlerable(Eventable(Renderable(Class))) { //@internal _moving: boolean; //@internal + _dragging: boolean; + //@internal + _cameraRestricted:boolean; + //@internal _originCenter: Coordinate; //@internal _suppressRecenter: boolean; @@ -292,6 +296,7 @@ export class Map extends Handlerable(Eventable(Renderable(Class))) { attributionControl?: Attribution; + /** * @param {(string|HTMLElement|object)} container - The container to create the map on, can be:
* 1. A HTMLElement container.
@@ -1798,6 +1803,14 @@ export class Map extends Handlerable(Eventable(Renderable(Class))) { return !!this._moving; } + /** + * Whether the map is dragging + * @return {Boolean} + */ + isDragging() { + return !!this._dragging; + } + /** * The callback function when move started * @private diff --git a/packages/maptalks/src/map/handler/Map.Drag.ts b/packages/maptalks/src/map/handler/Map.Drag.ts index b353d5f8b7..e84d86c1c1 100644 --- a/packages/maptalks/src/map/handler/Map.Drag.ts +++ b/packages/maptalks/src/map/handler/Map.Drag.ts @@ -98,6 +98,7 @@ class MapDragHandler extends Handler { //@internal _onDragStart(param) { + this.target._dragging = true; this.startDragTime = now(); if (this._mode === 'move') { this._moveStart(param); @@ -117,6 +118,7 @@ class MapDragHandler extends Handler { //@internal _onDragEnd(param) { + this.target._dragging = false; if (this._mode === 'move') { this._moveEnd(param); } else if (this._mode === 'rotatePitch') { diff --git a/packages/maptalks/test/map/MapSpec.js b/packages/maptalks/test/map/MapSpec.js index dfc36f6de4..cd88e6811b 100644 --- a/packages/maptalks/test/map/MapSpec.js +++ b/packages/maptalks/test/map/MapSpec.js @@ -922,6 +922,13 @@ describe('Map.Spec', function () { map.containerPointToCoord(new maptalks.Point(0, 0)); }); + it('point and altitude conversion', function () { + const res = map.getGLRes(); + const pointValue = map.altitudeToPoint(100, res); + const altitudeValue = map.pointAtResToAltitude(pointValue, res); + expect(altitudeValue).to.be.approx(100, 1e-2); + }); + it('#isOffScreen', function () { expect(map.isOffscreen([0, 0, 10, 10])).not.to.be.ok(); expect(map.isOffscreen(new maptalks.PointExtent(0, 0, 10, 10))).not.to.be.ok(); From d284b5bbe3be9eb3bc96146d66043dd03f77a8e8 Mon Sep 17 00:00:00 2001 From: fuzhenn Date: Wed, 26 Feb 2025 10:28:42 +0800 Subject: [PATCH 2/4] fix build --- packages/maptalks/src/map/Map.Camera.ts | 2 +- packages/maptalks/src/renderer/layer/CanvasRenderer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/maptalks/src/map/Map.Camera.ts b/packages/maptalks/src/map/Map.Camera.ts index 9db04d2057..c2231c8465 100644 --- a/packages/maptalks/src/map/Map.Camera.ts +++ b/packages/maptalks/src/map/Map.Camera.ts @@ -1,6 +1,6 @@ import Map from './Map'; import Point from '../geo/Point'; -import Coordinate from '../geo/Coordinate'; +import Coordinate, { CoordinateLike } from '../geo/Coordinate'; import * as mat4 from '../core/util/mat4'; import { subtract, add, scale, normalize, dot, set, distance, angle, cross } from '../core/util/vec3'; import { clamp, interpolate, isNumber, isNil, wrap, toDegree, toRadian, Matrix4, Vector3 } from '../core/util'; diff --git a/packages/maptalks/src/renderer/layer/CanvasRenderer.ts b/packages/maptalks/src/renderer/layer/CanvasRenderer.ts index 35837c94eb..26e2dcc802 100644 --- a/packages/maptalks/src/renderer/layer/CanvasRenderer.ts +++ b/packages/maptalks/src/renderer/layer/CanvasRenderer.ts @@ -352,7 +352,7 @@ class CanvasRenderer extends LayerAbstractRenderer { * onResize * @param {Object} param event parameters */ - onResize(param: any) { + onResize(_param: any) { delete this._extent2D; this.resizeCanvas(); this.setToRedraw(); From 946e4c17a8cf66d8a2d8ae686ba8f1f599e25a54 Mon Sep 17 00:00:00 2001 From: fuzhenn Date: Wed, 26 Feb 2025 10:31:10 +0800 Subject: [PATCH 3/4] remove abundant LayerIdentifyOptionsType --- packages/maptalks/src/layer/Layer.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/maptalks/src/layer/Layer.ts b/packages/maptalks/src/layer/Layer.ts index 453846e095..45e663a2b9 100644 --- a/packages/maptalks/src/layer/Layer.ts +++ b/packages/maptalks/src/layer/Layer.ts @@ -12,6 +12,7 @@ import type { Marker, MultiPolygon, Polygon } from '../geometry'; import { CommonProjectionType } from '../geo/projection'; import Coordinate from '../geo/Coordinate'; import Point from '../geo/Point'; +import { LayerIdentifyOptionsType } from './OverlayLayer'; /** * 配置项 @@ -927,7 +928,3 @@ export type LayerJSONType = { layers?: Array; } -export type LayerIdentifyOptionsType = { - onlyVisible?: boolean; - tolerance?: number; -} From 260e734a74b288a696897c8cb557d7237b26730b Mon Sep 17 00:00:00 2001 From: fuzhenn Date: Wed, 26 Feb 2025 10:50:35 +0800 Subject: [PATCH 4/4] fix specs --- packages/maptalks/test/layer/TileLayerSpec.js | 2 +- packages/maptalks/test/map/MapCameraSpec.js | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/maptalks/test/layer/TileLayerSpec.js b/packages/maptalks/test/layer/TileLayerSpec.js index 9ec1860103..acafbea575 100644 --- a/packages/maptalks/test/layer/TileLayerSpec.js +++ b/packages/maptalks/test/layer/TileLayerSpec.js @@ -179,7 +179,7 @@ describe('TileLayer', function () { renderer: 'canvas', urlTemplate: '#' }).addTo(map); - expect(tile.getTiles().tileGrids[0].tiles.length).to.be.eql(26); + expect(tile.getTiles().tileGrids[0].tiles.length).to.be.eql(28); }); it('tiles out of extent', function () { diff --git a/packages/maptalks/test/map/MapCameraSpec.js b/packages/maptalks/test/map/MapCameraSpec.js index b503304824..386191cb50 100644 --- a/packages/maptalks/test/map/MapCameraSpec.js +++ b/packages/maptalks/test/map/MapCameraSpec.js @@ -473,8 +473,8 @@ describe('Map.Camera', function () { pitch: 45, bearing: 45, }) - expect(map.getCenter().x).to.be.within(0.07, 0.08); - expect(map.getCenter().y).to.be.within(0.07, 0.08); + expect(map.getCenter().x).to.be.within(0.08, 0.09); + expect(map.getCenter().y).to.be.within(0.08, 0.09); expect(map.getPitch()).to.be.eql(45); expect(map.getBearing()).to.be.eql(45); expect(map.getZoom()).to.be.within(7, 8); @@ -486,8 +486,8 @@ describe('Map.Camera', function () { pitch: 45, bearing: 135, }) - expect(map.getCenter().x).to.be.within(0.07, 0.08); - expect(map.getCenter().y).to.be.within(-0.08, 0.07); + expect(map.getCenter().x).to.be.within(0.08, 0.09); + expect(map.getCenter().y).to.be.within(-0.09, 0.08); expect(map.getPitch()).to.be.eql(45); expect(map.getBearing()).to.be.eql(135); expect(map.getZoom()).to.be.within(7, 8); @@ -499,8 +499,8 @@ describe('Map.Camera', function () { pitch: 45, bearing: -45, }) - expect(map.getCenter().x).to.be.within(-0.08, 0.07); - expect(map.getCenter().y).to.be.within(0.07, 0.08); + expect(map.getCenter().x).to.be.within(-0.09, 0.08); + expect(map.getCenter().y).to.be.within(0.08, 0.09); expect(map.getPitch()).to.be.eql(45); expect(map.getBearing()).to.be.eql(-45); expect(map.getZoom()).to.be.within(7, 8); @@ -512,8 +512,8 @@ describe('Map.Camera', function () { pitch: 45, bearing: -135, }) - expect(map.getCenter().x).to.be.within(-0.08, -0.07); - expect(map.getCenter().y).to.be.within(-0.08, -0.07); + expect(map.getCenter().x).to.be.within(-0.09, -0.08); + expect(map.getCenter().y).to.be.within(-0.09, -0.08); expect(map.getPitch()).to.be.eql(45); expect(map.getBearing()).to.be.eql(-135); expect(map.getZoom()).to.be.within(7, 8); @@ -627,7 +627,7 @@ describe('Map.Camera', function () { map.setPitch(75); map.setBearing(45); // expect(maptalks.Util.join(map.domCssMatrix)).to.be.eql([31.819805153394643, -8.235571585149868, 0.7139488752261732, 0.6830127018922193, 31.819805153394636, 8.23557158514987, -0.7139488752261733, -0.6830127018922194, 0, -43.466662183008076, -0.27054191763364316, -0.25881904510252074, 0, 0, 46.83368719036461, 45].join()); - expect(maptalks.Util.join(map.domCssMatrix)).to.be.eql([31.819805153394643,-8.235571585149868,0.6834126770126959,0.6830127018922193,31.819805153394636,8.23557158514987,-0.683412677012696,-0.6830127018922194,0,-43.466662183008076,-0.2589706106275245,-0.25881904510252074,0,0,44.956019102246906,45].join()); + expect(maptalks.Util.join(map.domCssMatrix)).to.be.eql([31.819805153394643,-8.235571585149868,0.6833747672629105,0.6830127018922193,31.819805153394636,8.23557158514987,-0.6833747672629105,-0.6830127018922194,0,-43.466662183008076,-0.25895624520618993,-0.25881904510252074,0,0,44.9535233858847,45].join()); }); it('setCameraPosition', function() { @@ -637,9 +637,9 @@ describe('Map.Camera', function () { const zoom = map.getZoom(); const pitch = map.getPitch(); const bearing = map.getBearing(); - expect(zoom).to.be.eql(14.899641034986649); - expect(pitch).to.be.eql(85.67228588474566); - expect(bearing).to.be.eql(139.8095157874954); + expect(zoom).to.be.approx(14.785120157908738); + expect(pitch.toFixed(1)).to.be.approx(85.7); + expect(bearing.toFixed(0)).to.be.approx(140); }); });