From cf102c7443edc9d2e45f22504e6e1269ce23b516 Mon Sep 17 00:00:00 2001 From: hu de yi Date: Wed, 19 Jun 2024 10:19:57 +0800 Subject: [PATCH] Geometry fire positionchange when altitude update (#2355) * Geometry fire positionchange when altitude update * fix infowindow position error when owner altitude change * spec * updates * clear geometry altitude cache when layer enableAltitude change * spec * updates * fix lint --- src/geometry/Geometry.ts | 7 +++++- src/layer/VectorLayer.ts | 12 ++++++++++ src/ui/UIComponent.ts | 20 +++++++++++++++- test/geometry/GeometryAltitudeSpec.js | 34 +++++++++++++++++++++++++++ test/geometry/TextBoxSpec.js | 8 ++++++- 5 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/geometry/Geometry.ts b/src/geometry/Geometry.ts index 70c7144d08..920f3ae21e 100644 --- a/src/geometry/Geometry.ts +++ b/src/geometry/Geometry.ts @@ -1700,7 +1700,7 @@ export class Geometry extends JSONAble(Eventable(Handlerable(Class))) { const layerOpts = layer.options; const layerAltitude = layer.getAltitude ? layer.getAltitude() : 0; const enableAltitude = layerOpts['enableAltitude']; - if (!enableAltitude) { + if (!enableAltitude && (layer as any).isVectorLayer) { return layerAltitude; } const altitudeProperty = getAltitudeProperty(layer); @@ -1779,6 +1779,7 @@ export class Geometry extends JSONAble(Eventable(Handlerable(Class))) { } } this._clearAltitudeCache(); + this.onPositionChanged(); return this; } @@ -1834,6 +1835,10 @@ export type GeometryOptionsType = { function getAltitudeProperty(layer: OverlayLayer): string { let altitudeProperty = 'altitude'; if (layer) { + //only VectorLayer support properties.altitude + if (!(layer as any).isVectorLayer) { + return null; + } const layerOpts = layer.options; altitudeProperty = layerOpts['altitudeProperty']; } diff --git a/src/layer/VectorLayer.ts b/src/layer/VectorLayer.ts index 2b9178b580..4f99e42b09 100644 --- a/src/layer/VectorLayer.ts +++ b/src/layer/VectorLayer.ts @@ -82,6 +82,7 @@ const options: VectorLayerOptionsType = { class VectorLayer extends OverlayLayer { options: VectorLayerOptionsType; + isVectorLayer: boolean; /** * @param id - layer's id * @param geometries=null - geometries to add @@ -91,10 +92,21 @@ class VectorLayer extends OverlayLayer { */ constructor(id: string, geometries: VectorLayerOptionsType | Array, options?: VectorLayerOptionsType) { super(id, geometries, options); + this.isVectorLayer = true; } onConfig(conf: Record) { super.onConfig(conf); + if (!isNil(conf['enableAltitude'])) { + const geos = this.getGeometries() || []; + for (let i = 0, len = geos.length; i < len; i++) { + const geo = geos[i]; + if (geo) { + geo._clearAltitudeCache(); + geo.fire('positionchange'); + } + } + } if (conf['enableAltitude'] || conf['drawAltitude'] || conf['altitudeProperty']) { const renderer = this.getRenderer(); if (renderer && renderer.setToRedraw) { diff --git a/src/ui/UIComponent.ts b/src/ui/UIComponent.ts index a1f51ad990..55a5a93000 100644 --- a/src/ui/UIComponent.ts +++ b/src/ui/UIComponent.ts @@ -574,6 +574,16 @@ class UIComponent extends Eventable(Class) { altitude = 0; } } + if (this._owner.getLayer) { + const layer = (this._owner as Geometry).getLayer(); + //VectorLayer + if (layer && (layer as any).isVectorLayer) { + altitude = (this._owner as Geometry)._getAltitude() as number || 0; + if (!isNumber(altitude)) { + altitude = 0; + } + } + } const alt = this._meterToPoint(this._coordinate, altitude); return this.getMap().coordToViewPoint(this._coordinate, undefined, alt) ._add(this.options['dx'], this.options['dy']); @@ -820,7 +830,15 @@ class UIComponent extends Eventable(Class) { onGeometryPositionChange(param) { if (this._owner && this.isVisible()) { this._showBySymbolChange = true; - this.show(param['target'].getCenter()); + const target = param.target; + const center = target.getCenter(); + if (target._getAltitude) { + const altitude = target._getAltitude(); + if (isNumber(altitude)) { + center.z = altitude; + } + } + this.show(center); delete this._showBySymbolChange; } } diff --git a/test/geometry/GeometryAltitudeSpec.js b/test/geometry/GeometryAltitudeSpec.js index 47132aa53d..61d289e5b3 100644 --- a/test/geometry/GeometryAltitudeSpec.js +++ b/test/geometry/GeometryAltitudeSpec.js @@ -455,4 +455,38 @@ describe('Geometry.Altitude', function () { }, 100); }); + it('#2354 fire positionchange event when altitude update', function (done) { + map.addLayer(layer); + const point = new maptalks.Marker(map.getCenter()).addTo(layer); + + setTimeout(() => { + var spy = sinon.spy(); + point.on('positionchange', spy); + point.setAltitude(100); + setTimeout(() => { + expect(spy.called).to.be.ok(); + done(); + }, 100); + + }, 100); + }); + + it('#2354 fire positionchange event when layer enableAltitude change', function (done) { + map.addLayer(layer); + const point = new maptalks.Marker(map.getCenter()).addTo(layer); + + setTimeout(() => { + var spy = sinon.spy(); + point.on('positionchange', spy); + layer.config({ enableAltitude: false }); + setTimeout(() => { + expect(spy.called).to.be.ok(); + expect(point._minAlt).to.be.equal(undefined); + expect(point._maxAlt).to.be.equal(undefined); + done(); + }, 100); + + }, 100); + }); + }); diff --git a/test/geometry/TextBoxSpec.js b/test/geometry/TextBoxSpec.js index 12d9a35f85..fb41150091 100644 --- a/test/geometry/TextBoxSpec.js +++ b/test/geometry/TextBoxSpec.js @@ -199,7 +199,13 @@ describe('Geometry.TextBox', function () { layer = new maptalks.VectorLayer('id', { 'drawImmediate': true }); map.addLayer(layer); layer.addGeometry(vector); - expect(layer).to.be.painted(100 / 2 - padding[0] - 2, 0); + var parser = new UAParser(); + var result = parser.getOS(); + if (result.name && result.name.toLowerCase().indexOf('windows') > -1) { + expect(layer).to.be.painted(100 / 2 - padding[0] - 4, 0); + } else { + expect(layer).to.be.painted(100 / 2 - padding[0] - 2, 0); + } expect(layer).not.to.be.painted(100 / 2 - padding[0] + 1, 0); expect(layer).not.to.be.painted(0, 0); });