diff --git a/src/geometry/Geometry.js b/src/geometry/Geometry.js index c4cebaa369..df546a9d4a 100644 --- a/src/geometry/Geometry.js +++ b/src/geometry/Geometry.js @@ -1650,9 +1650,9 @@ function getGeometryCoordinatesAlts(geometry, layerAlt, enableAltitude) { coordinatesHasAlt(coordinates, tempAlts); if (tempAlts.length) { const alts = getCoordinatesAlts(coordinates, layerAlt, enableAltitude); - if (geometry.getShell && Array.isArray(alts[0])) { - return alts[0][0]; - } + // if (geometry.getShell && Array.isArray(alts[0])) { + // return alts; + // } return alts; } } diff --git a/src/map/tool/AreaTool.js b/src/map/tool/AreaTool.js index f1633582f7..38e743d460 100644 --- a/src/map/tool/AreaTool.js +++ b/src/map/tool/AreaTool.js @@ -24,7 +24,7 @@ const options = { 'polygonFill': '#ffffff', 'polygonOpacity': 0.5 }, - 'language' : 'zh-CN' + 'language': 'zh-CN' }; /** @@ -109,11 +109,12 @@ class AreaTool extends DistanceTool { } _msOnDrawVertex(param) { - const prjCoord = this.getMap()._pointToPrj(param['point2d']); - const vertexMarker = new Marker(param['coordinate'], { + // const prjCoord = this.getMap()._pointToPrj(param['point2d']); + const lastCoordinate = this._getLasttCoordinate() || param.coordinate; + const vertexMarker = new Marker(lastCoordinate.copy(), { 'symbol': this.options['vertexSymbol'] }); - vertexMarker._setPrjCoordinates(prjCoord); + // vertexMarker._setPrjCoordinates(prjCoord); this._measure(param['geometry']); this._lastVertex = vertexMarker; this._addVertexMarker(vertexMarker); @@ -125,30 +126,32 @@ class AreaTool extends DistanceTool { if (param['point2d']) { prjCoord = this.getMap()._pointToPrj(param['point2d']); } else { - let prjCoords = param['geometry']._getPrjCoordinates(); + let prjCoords = param['geometry']._getPrjCoordinates() || []; prjCoords = prjCoords.slice(0, prjCoords.length - 1); - param['geometry']._setPrjCoordinates(prjCoords); + // param['geometry']._setPrjCoordinates(prjCoords); prjCoord = prjCoords[prjCoords.length - 1]; } - if (param['geometry']._getPrjCoordinates().length < 3) { + if (param['geometry'].getShell().length < 3) { this._lastMeasure = 0; this._clearMeasureLayers(); return; } const ms = this._measure(param['geometry']); - const projection = this.getMap().getProjection(); - const coord = projection.unproject(prjCoord); - const endLabel = new Label(ms, coord, this.options['labelOptions']) + // const projection = this.getMap().getProjection(); + // const coord = projection.unproject(prjCoord); + const lastCoordinate = this._getLasttCoordinate(); + const endLabel = new Label(ms, lastCoordinate.copy(), this.options['labelOptions']) .addTo(this._measureMarkerLayer); - endLabel._setPrjCoordinates(prjCoord); + // endLabel._setPrjCoordinates(prjCoord); let size = endLabel.getSize(); if (!size) { size = new Size(10, 10); } - this._addClearMarker(coord, prjCoord, size['width']); + this._addClearMarker(lastCoordinate.copy(), prjCoord, size['width']); const geo = param['geometry'].copy(); - geo._setPrjCoordinates(param['geometry']._getPrjCoordinates()); + geo.setCoordinates(param.geometry.getCoordinates()); + // geo._setPrjCoordinates(param['geometry']._getPrjCoordinates()); geo.addTo(this._measureLineLayer); this._lastMeasure = geo.getArea(); } diff --git a/src/map/tool/DistanceTool.js b/src/map/tool/DistanceTool.js index 172bf8e4df..a9cd8d7f40 100644 --- a/src/map/tool/DistanceTool.js +++ b/src/map/tool/DistanceTool.js @@ -244,17 +244,20 @@ class DistanceTool extends DrawTool { _msOnDrawStart(param) { const map = this.getMap(); - const prjCoord = map._pointToPrj(param['point2d']); + // const prjCoord = map._pointToPrj(param['point2d']); const uid = UID(); const layerId = 'distancetool_' + uid; const markerLayerId = 'distancetool_markers_' + uid; const zIndex = this.options.zIndex; + const enableAltitude = this.options.enableAltitude; if (!map.getLayer(layerId)) { this._measureLineLayer = new VectorLayer(layerId, { - zIndex + zIndex, + enableAltitude }).addTo(map); this._measureMarkerLayer = new VectorLayer(markerLayerId, { - zIndex + zIndex, + enableAltitude }).addTo(map); } else { this._measureLineLayer = map.getLayer(layerId); @@ -264,14 +267,15 @@ class DistanceTool extends DrawTool { this._measureLayers.push(this._measureMarkerLayer); this._pushLayers([this._measureLineLayer, this._measureMarkerLayer]); //start marker - const marker = new Marker(param['coordinate'], { + const firstCoordinate = this._getFirstCoordinate() || param.coordinate; + const marker = new Marker(firstCoordinate.copy(), { 'symbol': this.options['vertexSymbol'] }); //调用_setPrjCoordinates主要是为了解决repeatworld下,让它能标注在其他世界的问题 - marker._setPrjCoordinates(prjCoord); + // marker._setPrjCoordinates(prjCoord); const content = this.translator.translate('distancetool.start'); - const startLabel = new Label(content, param['coordinate'], this.options['labelOptions']); - startLabel._setPrjCoordinates(prjCoord); + const startLabel = new Label(content, firstCoordinate.copy(), this.options['labelOptions']); + // startLabel._setPrjCoordinates(prjCoord); this._lastVertex = startLabel; this._addVertexMarker(marker, startLabel); } @@ -288,13 +292,14 @@ class DistanceTool extends DrawTool { this._tailLabel = new Label(ms, param['coordinate'], this.options['labelOptions']) .addTo(this._measureMarkerLayer); } - const prjCoords = this._geometry._getPrjCoordinates(); - const lastCoord = prjCoords[prjCoords.length - 1]; - this._tailMarker.setCoordinates(param['coordinate']); - this._tailMarker._setPrjCoordinates(lastCoord); + // const prjCoords = this._geometry._getPrjCoordinates(); + // const lastCoord = prjCoords[prjCoords.length - 1]; + const lastCoordinate = this._getLasttCoordinate() || param.coordinate; + this._tailMarker.setCoordinates(lastCoordinate.copy()); + // this._tailMarker._setPrjCoordinates(lastCoord); this._tailLabel.setContent(ms); - this._tailLabel.setCoordinates(param['coordinate']); - this._tailLabel._setPrjCoordinates(lastCoord); + this._tailLabel.setCoordinates(lastCoordinate.copy()); + // this._tailLabel._setPrjCoordinates(lastCoord); } _msGetCoordsToMeasure(param) { @@ -302,19 +307,22 @@ class DistanceTool extends DrawTool { } _msOnDrawVertex(param) { - const prjCoords = this._geometry._getPrjCoordinates(); - const lastCoord = prjCoords[prjCoords.length - 1]; + // const prjCoords = this._geometry._getPrjCoordinates(); + // const lastCoord = prjCoords[prjCoords.length - 1]; + + const lastCoordinate = this._getLasttCoordinate() || param.coordinate; + const geometry = param['geometry']; //vertex marker - const marker = new Marker(param['coordinate'], { + const marker = new Marker(lastCoordinate.copy(), { 'symbol': this.options['vertexSymbol'] }); const length = this._measure(geometry); - const vertexLabel = new Label(length, param['coordinate'], this.options['labelOptions']); + const vertexLabel = new Label(length, lastCoordinate.copy(), this.options['labelOptions']); this._addVertexMarker(marker, vertexLabel); - vertexLabel._setPrjCoordinates(lastCoord); - marker._setPrjCoordinates(lastCoord); + // vertexLabel._setPrjCoordinates(lastCoord); + // marker._setPrjCoordinates(lastCoord); this._lastVertex = vertexLabel; } @@ -334,7 +342,7 @@ class DistanceTool extends DrawTool { _msOnDrawEnd(param) { this._clearTailMarker(); - if (param['geometry']._getPrjCoordinates().length < 2) { + if (param['geometry'].getCoordinates().length < 2) { this._lastMeasure = 0; this._clearMeasureLayers(); return; @@ -345,7 +353,10 @@ class DistanceTool extends DrawTool { } this._addClearMarker(this._lastVertex.getCoordinates(), this._lastVertex._getPrjCoordinates(), size['width']); const geo = param['geometry'].copy(); - geo._setPrjCoordinates(param['geometry']._getPrjCoordinates()); + + geo.setCoordinates(param.geometry.getCoordinates()); + + // geo._setPrjCoordinates(param['geometry']._getPrjCoordinates()); geo.addTo(this._measureLineLayer); this._lastMeasure = geo.getLength(); } @@ -380,7 +391,7 @@ class DistanceTool extends DrawTool { return false; }, this); endMarker.addTo(this._measureMarkerLayer); - endMarker._setPrjCoordinates(prjCoord); + // endMarker._setPrjCoordinates(prjCoord); } _clearTailMarker() { @@ -399,6 +410,22 @@ class DistanceTool extends DrawTool { this._measureMarkerLayer.remove(); } + _getFirstCoordinate() { + if (!this._geometry) { + return null; + } + const coordinates = this._geometry.getCoordinates() || []; + return coordinates[0]; + } + + _getLasttCoordinate() { + if (!this._geometry) { + return null; + } + const coordinates = this._geometry.getCoordinates() || []; + return coordinates[coordinates.length - 1]; + } + } DistanceTool.mergeOptions(options); diff --git a/src/map/tool/DrawTool.js b/src/map/tool/DrawTool.js index 72dcfee6b5..ffcf9d1ca6 100644 --- a/src/map/tool/DrawTool.js +++ b/src/map/tool/DrawTool.js @@ -32,7 +32,8 @@ const options = { 'autoPanAtEdge': false, 'ignoreMouseleave': true, 'blockGeometryEvents': false, - 'zIndex': Number.MAX_VALUE + 'zIndex': Number.MAX_VALUE, + 'enableAltitude': true }; const registeredMode = {}; @@ -364,6 +365,7 @@ class DrawTool extends MapTool { * @private */ _clickHandler(event) { + event.enableAltitude = this.options.enableAltitude; const map = this.getMap(); const registerMode = this._getRegisterMode(); // const coordinate = event['coordinate']; @@ -497,6 +499,7 @@ class DrawTool extends MapTool { * @private */ _mouseMoveHandler(event) { + event.enableAltitude = this.options.enableAltitude; const map = this.getMap(); if (!map || map.isInteracting()) { return; @@ -556,6 +559,7 @@ class DrawTool extends MapTool { * @private */ _doubleClickHandler(event) { + event.enableAltitude = this.options.enableAltitude; if (!this._geometry) { return; } diff --git a/src/map/tool/DrawToolRegister.js b/src/map/tool/DrawToolRegister.js index 8590fab86d..9447fe391c 100644 --- a/src/map/tool/DrawToolRegister.js +++ b/src/map/tool/DrawToolRegister.js @@ -12,17 +12,57 @@ import Circle from '../../geometry/Circle'; import Polygon from '../../geometry/Polygon'; import DrawTool from './DrawTool'; +/** + * 当地形存在时就不能通过update prj来控制Geometry的坐标数据了,因为有了地形后prj对应的 + * Coordinate是另外一个Coordinate,如果还是update prj,那么就会导致Geometry的coordinates又变成非地形下的coordinate了 + * 因为prj里没有考虑海拔 + * @param {*} projection + * @param {*} prjCoords + * @param {*} mapEvent + * @returns + */ + +function queryTerrainCoordinates(projection, prjCoords, mapEvent) { + const isArray = Array.isArray(prjCoords); + if (!isArray) { + prjCoords = [prjCoords]; + } + let coordinates; + if (!mapEvent || !mapEvent.target || !mapEvent.target._queryTerrainInfo) { + coordinates = prjCoords.map(c => { + return projection.unproject(c); + }); + return isArray ? coordinates : coordinates[0]; + } + const map = mapEvent.target; + const enableAltitude = mapEvent.enableAltitude; + coordinates = prjCoords.map(c => { + //prj to container point + if (enableAltitude) { + const point = map._prjToContainerPoint(c); + const terrain = map._queryTerrainInfo(point); + if (terrain && terrain.coordinate) { + return terrain.coordinate; + } + } + return projection.unproject(c); + }); + return isArray ? coordinates : coordinates[0]; +} + const circleHooks = { - 'create': function (projection, prjCoord) { - const center = projection.unproject(prjCoord[0]); + 'create': function (projection, prjCoord, mapEvent) { + // const center = projection.unproject(prjCoord[0]); + const center = queryTerrainCoordinates(projection, prjCoord[0], mapEvent); const circle = new Circle(center, 0); - circle._setPrjCoordinates(prjCoord[0]); + // circle._setPrjCoordinates(prjCoord[0]); return circle; }, - 'update': function (projection, prjPath, geometry) { + 'update': function (projection, prjPath, geometry, mapEvent) { const map = geometry.getMap(); const prjCoord = Array.isArray(prjPath) ? prjPath[prjPath.length - 1] : prjPath; - const nextCoord = projection.unproject(prjCoord); + // const nextCoord = projection.unproject(prjCoord); + const nextCoord = queryTerrainCoordinates(projection, prjCoord, mapEvent); const radius = map.computeLength(geometry.getCenter(), nextCoord); geometry.setRadius(radius); }, @@ -41,17 +81,19 @@ DrawTool.registerMode('freeHandCircle', extend({ }, circleHooks)); const ellipseHooks = { - 'create': function (projection, prjCoord) { - const center = projection.unproject(prjCoord[0]); + 'create': function (projection, prjCoord, mapEvent) { + // const center = projection.unproject(prjCoord[0]); + const center = queryTerrainCoordinates(projection, prjCoord[0], mapEvent); const ellipse = new Ellipse(center, 0, 0); - ellipse._setPrjCoordinates(prjCoord[0]); + // ellipse._setPrjCoordinates(prjCoord[0]); return ellipse; }, - 'update': function (projection, prjPath, geometry) { + 'update': function (projection, prjPath, geometry, mapEvent) { const map = geometry.getMap(); const center = geometry.getCenter(); const prjCoord = Array.isArray(prjPath) ? prjPath[prjPath.length - 1] : prjPath; - const nextCoord = projection.unproject(prjCoord); + // const nextCoord = projection.unproject(prjCoord); + const nextCoord = queryTerrainCoordinates(projection, prjCoord, mapEvent); const rx = map.computeLength(center, new Coordinate({ x: nextCoord.x, y: center.y @@ -83,9 +125,9 @@ const rectangleHooks = { rect._firstClick = prjCoords[0]; return rect; }, - 'update': function (projection, prjCoords, geometry, param) { + 'update': function (projection, prjCoords, geometry, mapEvent) { const map = geometry.getMap(); - const containerPoint = param['containerPoint']; + const containerPoint = mapEvent['containerPoint']; const firstClick = map._prjToContainerPoint(geometry._firstClick); const ring = [ [firstClick.x, firstClick.y], @@ -93,8 +135,11 @@ const rectangleHooks = { [containerPoint.x, containerPoint.y], [firstClick.x, containerPoint.y], ]; - geometry.setCoordinates(ring.map(c => map.containerPointToCoord(new Point(c)))); - geometry._setPrjCoordinates(ring.map(c => map._containerPointToPrj(new Point(c)))); + const prjs = ring.map(c => map._containerPointToPrj(new Point(c))); + const coordinates = queryTerrainCoordinates(projection, prjs, mapEvent); + // geometry.setCoordinates(ring.map(c => map.containerPointToCoord(new Point(c)))); + // geometry._setPrjCoordinates(prjs); + geometry.setCoordinates(coordinates); }, 'generate': function (geometry) { return geometry; @@ -113,47 +158,55 @@ DrawTool.registerMode('freeHandRectangle', extend({ DrawTool.registerMode('point', { 'clickLimit': 1, 'action': ['click', 'mousemove'], - 'create': function (projection, prjCoord) { - const center = projection.unproject(prjCoord[0]); + 'create': function (projection, prjCoord, mapEvent) { + // const center = projection.unproject(prjCoord[0]); + const center = queryTerrainCoordinates(projection, prjCoord[0], mapEvent); const marker = new Marker(center); - marker._setPrjCoordinates(prjCoord[0]); + // marker._setPrjCoordinates(prjCoord[0]); return marker; }, 'generate': function (geometry) { return geometry; }, - 'update': function (projection, prjCoord, geometry) { + 'update': function (projection, prjCoord, geometry, mapEvent) { if (Array.isArray(prjCoord)) { prjCoord = prjCoord[prjCoord.length - 1]; } if (!prjCoord) { return geometry; } - const coordinate = projection.unproject(prjCoord); + // const coordinate = projection.unproject(prjCoord); + const coordinate = queryTerrainCoordinates(projection, prjCoord, mapEvent); geometry.setCoordinates(coordinate); return geometry; } }); const polygonHooks = { - 'create': function (projection, prjPath) { - const path = prjPath.map(c => projection.unproject(c)); + 'create': function (projection, prjPath, mapEvent) { + // const path = prjPath.map(c => projection.unproject(c)); + const path = queryTerrainCoordinates(projection, prjPath, mapEvent); const line = new LineString(path); - line._setPrjCoordinates(prjPath); + // line._setPrjCoordinates(prjPath); + line.setCoordinates(path); return line; }, - 'update': function (projection, path, geometry) { + 'update': function (projection, path, geometry, mapEvent) { const symbol = geometry.getSymbol(); let prjCoords; if (Array.isArray(path)) { prjCoords = path; } else { - prjCoords = geometry._getPrjCoordinates(); + // prjCoords = geometry._getPrjCoordinates(); + prjCoords = geometry._drawPrjs || []; prjCoords.push(path); } - const coordinates = prjCoords.map(c => projection.unproject(c)); + geometry._drawPrjs = prjCoords; + // const coordinates = prjCoords.map(c => projection.unproject(c)); + const coordinates = queryTerrainCoordinates(projection, prjCoords, mapEvent); + + // geometry._setPrjCoordinates(prjCoords); geometry.setCoordinates(coordinates); - geometry._setPrjCoordinates(prjCoords); const layer = geometry.getLayer(); if (layer) { let polygon = layer.getGeometryById('polygon'); @@ -170,7 +223,8 @@ const polygonHooks = { polygon.addTo(layer); } if (polygon) { - polygon._setPrjCoordinates(prjCoords); + // polygon._setPrjCoordinates(prjCoords); + polygon.setCoordinates([coordinates]); } } }, @@ -178,7 +232,7 @@ const polygonHooks = { const polygon = new Polygon(geometry.getCoordinates(), { 'symbol': geometry.getSymbol() }); - polygon._setPrjCoordinates(geometry._getPrjCoordinates()); + // polygon._setPrjCoordinates(geometry._getPrjCoordinates()); polygon._projCode = geometry._projCode; return polygon; } @@ -193,23 +247,29 @@ DrawTool.registerMode('freeHandPolygon', extend({ }, polygonHooks)); const lineStringHooks = { - 'create': function (projection, prjPath) { - const path = prjPath.map(c => projection.unproject(c)); + 'create': function (projection, prjPath, mapEvent) { + // const path = prjPath.map(c => projection.unproject(c)); + const path = queryTerrainCoordinates(projection, prjPath, mapEvent); const line = new LineString(path); - line._setPrjCoordinates(prjPath); + // line._setPrjCoordinates(prjPath); + line.setCoordinates(path); return line; }, - 'update': function (projection, prjPath, geometry) { + 'update': function (projection, prjPath, geometry, mapEvent) { let prjCoords; if (Array.isArray(prjPath)) { prjCoords = prjPath; } else { - prjCoords = geometry._getPrjCoordinates(); + // prjCoords = geometry._getPrjCoordinates(); + prjCoords = geometry._drawPrjs || []; prjCoords.push(prjPath); } - const path = prjCoords.map(c => projection.unproject(c)); + // const path = prjCoords.map(c => projection.unproject(c)); + // geometry.setCoordinates(path); + // geometry._setPrjCoordinates(prjCoords); + geometry._drawPrjs = prjCoords; + const path = queryTerrainCoordinates(projection, prjCoords, mapEvent); geometry.setCoordinates(path); - geometry._setPrjCoordinates(prjCoords); }, 'generate': function (geometry) { return geometry; diff --git a/src/renderer/geometry/Painter.js b/src/renderer/geometry/Painter.js index 6aa488705f..b66d57814b 100644 --- a/src/renderer/geometry/Painter.js +++ b/src/renderer/geometry/Painter.js @@ -932,14 +932,21 @@ class Painter extends Class { this.minAltitude = Number.MAX_VALUE; this.maxAltitude = Number.MIN_VALUE; return altitude.map(alt => { - const a = alt; - if (a < this.minAltitude) { - this.minAltitude = a; + const isArray = Array.isArray(alt); + if (!isArray) { + alt = [alt]; } - if (a > this.maxAltitude) { - this.maxAltitude = a; - } - return a; + const result = alt.map(al => { + const a = al; + if (a < this.minAltitude) { + this.minAltitude = a; + } + if (a > this.maxAltitude) { + this.maxAltitude = a; + } + return a; + }); + return isArray ? result : result[0]; }); } else { this.minAltitude = this.maxAltitude = altitude;