Skip to content

Commit d8b4db1

Browse files
authored
fix Vector Marker getFixedExtent (#2512)
* fix Vector Marker getFixedExtent * spec * update spec * update spec * update spec
1 parent 761d2d7 commit d8b4db1

File tree

3 files changed

+104
-12
lines changed

3 files changed

+104
-12
lines changed

packages/maptalks/src/core/util/draw.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { isGradient } from './style';
44
import { isNumber } from './common';
55
import Canvas from '../Canvas';
66
import { ResourceCache } from '../../renderer/layer/CanvasRenderer'
7+
import { BBOX } from './bbox';
78

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

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

4546
const width = style['markerWidth'],
4647
height = style['markerHeight'],
47-
hLineWidth = style['markerLineWidth'] / 2;
48+
lineWidth = style['markerLineWidth'] || 0,
49+
hLineWidth = lineWidth / 2;
4850
if (markerType === 'ellipse') {
4951
//ellipse default
5052
Canvas.ellipse(ctx, point, width / 2, height / 2, height / 2, lineOpacity, fillOpacity);
@@ -85,6 +87,14 @@ export function drawVectorMarker(ctx: CanvasRenderingContext2D, point, symbol, r
8587
} else {
8688
throw new Error('unsupported markerType: ' + markerType);
8789
}
90+
if (bbox) {
91+
//record marker bbox if need
92+
const { x, y } = point;
93+
bbox[0] = x - width / 2 - lineWidth;
94+
bbox[1] = y - height / 2 - lineWidth;
95+
bbox[2] = x + width / 2 + lineWidth;
96+
bbox[3] = y + height / 2 + lineWidth;
97+
}
8898
return ctx.canvas;
8999
}
90100

packages/maptalks/src/renderer/geometry/symbolizers/VectorMarkerSymbolizer.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ import { Geometry } from '../../../geometry';
1313
import Painter from '../Painter';
1414
import { Extent } from '../../../geo';
1515
import { ResourceCache } from '../../layer/CanvasRenderer';
16+
import { getDefaultBBOX, resetBBOX } from '../../../core/util/bbox';
1617

1718
const MARKER_SIZE: [number, number] = [0, 0];
1819
const TEMP_EXTENT = new PointExtent();
1920
const DEFAULT_ANCHOR = new Point(0, 0);
21+
const TEMP_BBOX = getDefaultBBOX();
2022

2123
export default class VectorMarkerSymbolizer extends PointSymbolizer {
2224
//@internal
@@ -66,14 +68,16 @@ export default class VectorMarkerSymbolizer extends PointSymbolizer {
6668
this.geometry.getLayer().getMask() === this.geometry ||
6769
this._dynamic ||
6870
this.geometry.getLayer().options['cacheVectorOnCanvas'] === false) {
69-
this._drawMarkers(ctx, cookedPoints, resources);
71+
//动态样式或者不缓存,function-type style, or not cache vector on canvas
72+
this._drawMarkersWithDynamic(ctx, cookedPoints, resources);
7073
} else {
7174
this._drawMarkersWithCache(ctx, cookedPoints, resources);
7275
}
7376
}
7477

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

93-
this._drawVectorMarker(ctx, point, resources);
97+
const bbox = this._drawVectorMarker(ctx, point, resources);
9498
if (origin) {
9599
ctx.restore();
96100
this._setBBOX(ctx, extent.xmin, extent.ymin, extent.xmax, extent.ymax);
97101
} else {
98-
const { x, y } = point;
99-
this._setBBOX(ctx, x, y, x + width, y + height);
102+
if (bbox) {
103+
this._setBBOX(ctx, bbox[0], bbox[1], bbox[2], bbox[3]);
104+
} else {
105+
const { x, y } = point;
106+
this._setBBOX(ctx, x, y, x + width, y + height);
107+
}
100108
}
101109
}
102110
}
@@ -203,15 +211,21 @@ export default class VectorMarkerSymbolizer extends PointSymbolizer {
203211

204212
//@internal
205213
_drawVectorMarker(ctx: CanvasRenderingContext2D, point: Point, resources: ResourceCache) {
206-
drawVectorMarker(ctx, point, this.style, resources);
214+
resetBBOX(TEMP_BBOX);
215+
drawVectorMarker(ctx, point, this.style, resources, TEMP_BBOX);
216+
return TEMP_BBOX;
207217
}
208218

209219
getFixedExtent(): PointExtent {
210-
const isDynamic = this.isDynamicSize();
211-
const w = this.style.markerWidth;
212-
const h = this.style.markerHeight;
220+
// const isDynamic = this.isDynamicSize();
221+
// const w = this.style.markerWidth;
222+
// const h = this.style.markerHeight;
223+
// this._fixedExtent = this._fixedExtent || new PointExtent();
224+
// return getVectorMarkerFixedExtent(this._fixedExtent, this.style, isDynamic ? [128, 128 * (w === 0 ? 1 : h / w)] : null);
225+
213226
this._fixedExtent = this._fixedExtent || new PointExtent();
214-
return getVectorMarkerFixedExtent(this._fixedExtent, this.style, isDynamic ? [128, 128 * (w === 0 ? 1 : h / w)] : null);
227+
return getVectorMarkerFixedExtent(this._fixedExtent, this.style, null);
228+
215229
}
216230

217231
translate(): any {

packages/maptalks/test/geometry/MarkerSpec.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,74 @@ describe('Geometry.Marker', function () {
674674
.addTo(map);
675675

676676
});
677+
678+
it('#2511 vector marker with function-type getFixedExtent', function (done) {
679+
map.config('zoomAnimation', false);
680+
var marker = new maptalks.Marker(map.getCenter(), {
681+
properties: { name: '1111' },
682+
// symbol: {
683+
// markerType: "ellipse",
684+
// markerWidth: 50,
685+
// markerHeight: 50
686+
// },
687+
symbol: [
688+
{
689+
markerType: "ellipse",
690+
// markerWidth: 50,
691+
// markerHeight: 50,
692+
markerWidth: {
693+
stops: [
694+
[1, 10],
695+
[17, 60],
696+
],
697+
},
698+
markerHeight: {
699+
stops: [
700+
[1, 10],
701+
[17, 60],
702+
],
703+
},
704+
markerDy: {
705+
stops: [
706+
[1, -2],
707+
[17, -80],
708+
],
709+
},
710+
markerFill: {
711+
type: "radial",
712+
colorStops: [
713+
[0.0, "rgba(216,115,149,0)"],
714+
[0.5, "rgba(216,115,149,0.7)"],
715+
[1.0, "rgba(216,115,149,1)"],
716+
],
717+
},
718+
markerLineWidth: 1,
719+
},
720+
721+
]
722+
});
723+
var layer = new maptalks.VectorLayer('id', { 'drawImmediate': true }).addTo(map);
724+
layer.addGeometry([marker]);
725+
726+
setTimeout(() => {
727+
const extent = marker._getPainter().getFixedExtent();
728+
const { xmin, ymin, xmax, ymax } = extent;
729+
expect(Math.floor(xmin)).to.be.eql(-31);
730+
// eslint-disable-next-line no-undef
731+
if (isWindows()) {
732+
expect(Math.floor(xmax)).to.be.eql(29);
733+
expect(Math.floor(ymin)).to.be.eql(-105);
734+
expect(Math.floor(ymax)).to.be.eql(-46);
735+
} else {
736+
expect(Math.floor(xmax)).to.be.eql(31);
737+
expect(Math.floor(ymin)).to.be.eql(-111);
738+
expect(Math.floor(ymax)).to.be.eql(-49);
739+
}
740+
done();
741+
}, 1000);
742+
743+
744+
});
677745
});
678746

679747
describe('marker rotation', function () {

0 commit comments

Comments
 (0)