diff --git a/src/core/util/marker.js b/src/core/util/marker.js index b1a29560a..8d6de9ad8 100644 --- a/src/core/util/marker.js +++ b/src/core/util/marker.js @@ -136,6 +136,10 @@ const SIZE = []; export function getVectorMarkerFixedExtent(out, symbol, size) { // const padding = getVectorPadding(symbol) * 2; size = size || calVectorMarkerSize(SIZE, symbol); + if (size && (size[0] === 0 || size[1] === 0)) { + emptyExtent(out); + return out; + } // if (padding) { // size = size.map(d => d - padding); // } @@ -185,6 +189,11 @@ export function calVectorMarkerSize(out, symbol) { const padding = getVectorPadding(symbol); const width = getValueOrDefault(symbol['markerWidth'], DEFAULT_MARKER_SYMBOLS.markerWidth); const height = getValueOrDefault(symbol['markerHeight'], DEFAULT_MARKER_SYMBOLS.markerHeight); + if (width === 0 || height === 0) { + out[0] = 0; + out[1] = 0; + return out; + } const lineWidth = getValueOrDefault(symbol['markerLineWidth'], DEFAULT_MARKER_SYMBOLS.markerLineWidth), shadow = 2 * ((symbol['shadowBlur'] || 0) + Math.max(Math.abs(symbol['shadowOffsetX'] || 0) + Math.abs(symbol['shadowOffsetY'] || 0))), // add some tolerance for shadowOffsetX/Y w = Math.round(width + lineWidth + shadow + padding * 2), @@ -217,6 +226,10 @@ export function getImageMarkerFixedExtent(out, symbol, resources) { height = symbol['markerHeight'] || (img ? img.height : 0); TEMP_SIZE.width = width; TEMP_SIZE.height = height; + if (symbol['markerWidth'] === 0 || symbol['markerHeight'] === 0) { + emptyExtent(out); + return out; + } const alignPoint = getAlignPoint(TEMP_SIZE, symbol['markerHorizontalAlignment'] || 'middle', symbol['markerVerticalAlignment'] || 'top'); return getFixedExtent(out, symbol['markerDx'] || 0, symbol['markerDy'] || 0, getMarkerRotation(symbol), alignPoint, width, height); @@ -225,6 +238,10 @@ export function getImageMarkerFixedExtent(out, symbol, resources) { export function getTextMarkerFixedExtent(out, symbol, textDesc) { const size = textDesc['size']; + if (size && (size.width === 0 || size.height === 0)) { + emptyExtent(out); + return out; + } const alignPoint = getAlignPoint(size, symbol['textHorizontalAlignment'], symbol['textVerticalAlignment']); // if (symbol['textHaloRadius']) { // const r = symbol['textHaloRadius']; @@ -316,3 +333,13 @@ export const DYNAMIC_SYMBOL_PROPS = [ export const SIZE_SYMBOL_PROPS = [ 'textName', 'markerType', 'markerFile', 'textHaloRadius', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY', 'textWrapWidth' ]; + +export function emptyExtent(extent) { + if (!extent) { + return; + } + extent.xmin = Infinity; + extent.ymin = Infinity; + extent.xmax = -Infinity; + extent.ymax = -Infinity; +} diff --git a/src/geometry/Geometry.js b/src/geometry/Geometry.js index 3f2eba08a..ac97aa44a 100644 --- a/src/geometry/Geometry.js +++ b/src/geometry/Geometry.js @@ -31,6 +31,14 @@ const TEMP_POINT0 = new Point(0, 0); const TEMP_EXTENT = new PointExtent(); const TEMP_PROPERTIES = {}; +function validateExtent(extent) { + if (!extent) { + return false; + } + const { xmin, ymin, xmax, ymax } = extent; + return (xmax - xmin > 0 && ymax - ymin > 0); +} + /** * @property {Object} options - geometry options * @property {Boolean} [options.id=null] - id of the geometry @@ -452,7 +460,10 @@ class Geometry extends JSONAble(Eventable(Handlerable(Class))) { extent._combine(groundExtent); } if (extent) { - extent._add(this._getFixedExtent()); + const fixedExtent = this._getFixedExtent(); + if (validateExtent(fixedExtent)) { + extent._add(fixedExtent); + } } const smoothness = this.options['smoothness']; if (smoothness) { diff --git a/test/geometry/MarkerSpec.js b/test/geometry/MarkerSpec.js index 982368fb6..80401b373 100644 --- a/test/geometry/MarkerSpec.js +++ b/test/geometry/MarkerSpec.js @@ -909,4 +909,75 @@ describe('Geometry.Marker', function () { }); done(); }); + + it('#2175 marker ContainerExtent when markerWidth/markerHeight/textSize =0', function (done) { + const imageSymbol = { + markerWidth: 10, + markerHeight: 10, + 'markerFile': 'resources/tile.png', + }; + + const pathSymbol = { + 'markerType': 'path', + 'markerPath': [{ + 'path': 'M8 23l0 0 0 0 0 0 0 0 0 0c-4,-5 -8,-10 -8,-14 0,-5 4,-9 8,-9l0 0 0 0c4,0 8,4 8,9 0,4 -4,9 -8,14z M3,9 a5,5 0,1,0,0,-0.9Z', + 'fill': '#DE3333' + }], + 'markerPathWidth': 16, + 'markerPathHeight': 23, + 'markerWidth': 8, + 'markerHeight': 20, + }; + + const vectorSymbol = { + markerType: 'ellipse', + markerWidth: 10, + markerHeight: 10 + }; + + const textSymbol = { + textSize: 12, + textName: 'hello' + }; + + const symbols = [imageSymbol, pathSymbol, vectorSymbol, textSymbol]; + + let idx = 0; + + function test() { + layer.clear(); + if (idx < symbols.length) { + const symbol = symbols[idx]; + const isText = symbol.textSize !== undefined; + const point = new maptalks.Marker(map.getCenter(), { + symbol: symbol + }) + point.addTo(layer); + setTimeout(() => { + const extent = point.getContainerExtent(); + expect(extent.getWidth()).not.to.be.eql(0); + expect(extent.getHeight()).not.to.be.eql(0); + + if (isText) { + symbol.textSize = 0; + point.setSymbol(symbol) + } else { + symbol.markerWidth = 0; + point.setSymbol(symbol) + } + + setTimeout(() => { + const extent = point.getContainerExtent(); + expect(extent.getWidth()).to.be.eql(0); + expect(extent.getHeight()).to.be.eql(0); + idx++; + test(); + }, 50); + }, 50); + } else { + done(); + } + } + test(); + }); });