Skip to content

fix Vector Marker getFixedExtent #2512

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions packages/maptalks/src/core/util/draw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { isGradient } from './style';
import { isNumber } from './common';
import Canvas from '../Canvas';
import { ResourceCache } from '../../renderer/layer/CanvasRenderer'
import { BBOX } from './bbox';

export function drawImageMarker(ctx: CanvasRenderingContext2D, image, point, symbol) {
let w = symbol && symbol['markerWidth'];
Expand All @@ -22,7 +23,7 @@ export function getImage(resources: ResourceCache, url: string) {
return img || null;
}

export function drawVectorMarker(ctx: CanvasRenderingContext2D, point, symbol, resources: ResourceCache) {
export function drawVectorMarker(ctx: CanvasRenderingContext2D, point, symbol, resources: ResourceCache, bbox?: BBOX) {
const strokeAndFill = translateMarkerLineAndFill(symbol);
const style = symbol,
markerType = style['markerType'].toLowerCase(),
Expand All @@ -44,7 +45,8 @@ export function drawVectorMarker(ctx: CanvasRenderingContext2D, point, symbol, r

const width = style['markerWidth'],
height = style['markerHeight'],
hLineWidth = style['markerLineWidth'] / 2;
lineWidth = style['markerLineWidth'] || 0,
hLineWidth = lineWidth / 2;
if (markerType === 'ellipse') {
//ellipse default
Canvas.ellipse(ctx, point, width / 2, height / 2, height / 2, lineOpacity, fillOpacity);
Expand Down Expand Up @@ -85,6 +87,14 @@ export function drawVectorMarker(ctx: CanvasRenderingContext2D, point, symbol, r
} else {
throw new Error('unsupported markerType: ' + markerType);
}
if (bbox) {
//record marker bbox if need
const { x, y } = point;
bbox[0] = x - width / 2 - lineWidth;
bbox[1] = y - height / 2 - lineWidth;
bbox[2] = x + width / 2 + lineWidth;
bbox[3] = y + height / 2 + lineWidth;
}
return ctx.canvas;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import { Geometry } from '../../../geometry';
import Painter from '../Painter';
import { Extent } from '../../../geo';
import { ResourceCache } from '../../layer/CanvasRenderer';
import { getDefaultBBOX, resetBBOX } from '../../../core/util/bbox';

const MARKER_SIZE: [number, number] = [0, 0];
const TEMP_EXTENT = new PointExtent();
const DEFAULT_ANCHOR = new Point(0, 0);
const TEMP_BBOX = getDefaultBBOX();

export default class VectorMarkerSymbolizer extends PointSymbolizer {
//@internal
Expand Down Expand Up @@ -66,14 +68,16 @@ export default class VectorMarkerSymbolizer extends PointSymbolizer {
this.geometry.getLayer().getMask() === this.geometry ||
this._dynamic ||
this.geometry.getLayer().options['cacheVectorOnCanvas'] === false) {
this._drawMarkers(ctx, cookedPoints, resources);
//动态样式或者不缓存,function-type style, or not cache vector on canvas
this._drawMarkersWithDynamic(ctx, cookedPoints, resources);
} else {
this._drawMarkersWithCache(ctx, cookedPoints, resources);
}
}

//rename to _drawMarkersWithDynamic
//@internal
_drawMarkers(ctx: CanvasRenderingContext2D, cookedPoints: any[], resources: ResourceCache) {
_drawMarkersWithDynamic(ctx: CanvasRenderingContext2D, cookedPoints: any[], resources: ResourceCache) {
for (let i = cookedPoints.length - 1; i >= 0; i--) {
let point = cookedPoints[i];
const size = calVectorMarkerSize(MARKER_SIZE, this.style);
Expand All @@ -90,13 +94,17 @@ export default class VectorMarkerSymbolizer extends PointSymbolizer {
this.rotations.push(rad);
}

this._drawVectorMarker(ctx, point, resources);
const bbox = this._drawVectorMarker(ctx, point, resources);
if (origin) {
ctx.restore();
this._setBBOX(ctx, extent.xmin, extent.ymin, extent.xmax, extent.ymax);
} else {
const { x, y } = point;
this._setBBOX(ctx, x, y, x + width, y + height);
if (bbox) {
this._setBBOX(ctx, bbox[0], bbox[1], bbox[2], bbox[3]);
} else {
const { x, y } = point;
this._setBBOX(ctx, x, y, x + width, y + height);
}
}
}
}
Expand Down Expand Up @@ -203,15 +211,21 @@ export default class VectorMarkerSymbolizer extends PointSymbolizer {

//@internal
_drawVectorMarker(ctx: CanvasRenderingContext2D, point: Point, resources: ResourceCache) {
drawVectorMarker(ctx, point, this.style, resources);
resetBBOX(TEMP_BBOX);
drawVectorMarker(ctx, point, this.style, resources, TEMP_BBOX);
return TEMP_BBOX;
}

getFixedExtent(): PointExtent {
const isDynamic = this.isDynamicSize();
const w = this.style.markerWidth;
const h = this.style.markerHeight;
// const isDynamic = this.isDynamicSize();
// const w = this.style.markerWidth;
// const h = this.style.markerHeight;
// this._fixedExtent = this._fixedExtent || new PointExtent();
// return getVectorMarkerFixedExtent(this._fixedExtent, this.style, isDynamic ? [128, 128 * (w === 0 ? 1 : h / w)] : null);

this._fixedExtent = this._fixedExtent || new PointExtent();
return getVectorMarkerFixedExtent(this._fixedExtent, this.style, isDynamic ? [128, 128 * (w === 0 ? 1 : h / w)] : null);
return getVectorMarkerFixedExtent(this._fixedExtent, this.style, null);

}

translate(): any {
Expand Down
68 changes: 68 additions & 0 deletions packages/maptalks/test/geometry/MarkerSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,74 @@ describe('Geometry.Marker', function () {
.addTo(map);

});

it('#2511 vector marker with function-type getFixedExtent', function (done) {
map.config('zoomAnimation', false);
var marker = new maptalks.Marker(map.getCenter(), {
properties: { name: '1111' },
// symbol: {
// markerType: "ellipse",
// markerWidth: 50,
// markerHeight: 50
// },
symbol: [
{
markerType: "ellipse",
// markerWidth: 50,
// markerHeight: 50,
markerWidth: {
stops: [
[1, 10],
[17, 60],
],
},
markerHeight: {
stops: [
[1, 10],
[17, 60],
],
},
markerDy: {
stops: [
[1, -2],
[17, -80],
],
},
markerFill: {
type: "radial",
colorStops: [
[0.0, "rgba(216,115,149,0)"],
[0.5, "rgba(216,115,149,0.7)"],
[1.0, "rgba(216,115,149,1)"],
],
},
markerLineWidth: 1,
},

]
});
var layer = new maptalks.VectorLayer('id', { 'drawImmediate': true }).addTo(map);
layer.addGeometry([marker]);

setTimeout(() => {
const extent = marker._getPainter().getFixedExtent();
const { xmin, ymin, xmax, ymax } = extent;
expect(Math.floor(xmin)).to.be.eql(-31);
// eslint-disable-next-line no-undef
if (isWindows()) {
expect(Math.floor(xmax)).to.be.eql(29);
expect(Math.floor(ymin)).to.be.eql(-105);
expect(Math.floor(ymax)).to.be.eql(-46);
} else {
expect(Math.floor(xmax)).to.be.eql(31);
expect(Math.floor(ymin)).to.be.eql(-111);
expect(Math.floor(ymax)).to.be.eql(-49);
}
done();
}, 1000);


});
});

describe('marker rotation', function () {
Expand Down