From 23b2368feddf374d8d817eeca2d1fd595a2f09cf Mon Sep 17 00:00:00 2001 From: hu de yi Date: Thu, 24 Oct 2024 11:23:42 +0800 Subject: [PATCH] fix Marker rotate Not effective when textPlacement/markerPlacement (#2441) * fix Marker rotate Not effective when textPlacement/markerPlacement * spec * updates --- .../symbolizers/ImageMarkerSymbolizer.ts | 5 +- .../geometry/symbolizers/PointSymbolizer.ts | 4 + .../symbolizers/TextMarkerSymbolizer.ts | 5 +- .../symbolizers/VectorMarkerSymbolizer.ts | 10 +- test/core/ResourceProxySpec.js | 3 + test/geometry/LineStringSpec.js | 119 +++++++++++++++++- test/resources/arrow.png | Bin 0 -> 273 bytes 7 files changed, 137 insertions(+), 9 deletions(-) create mode 100644 test/resources/arrow.png diff --git a/src/renderer/geometry/symbolizers/ImageMarkerSymbolizer.ts b/src/renderer/geometry/symbolizers/ImageMarkerSymbolizer.ts index dd82bb46de..9831b26319 100644 --- a/src/renderer/geometry/symbolizers/ImageMarkerSymbolizer.ts +++ b/src/renderer/geometry/symbolizers/ImageMarkerSymbolizer.ts @@ -74,13 +74,13 @@ export default class ImageMarkerSymbolizer extends PointSymbolizer { TEMP_SIZE.width = width; TEMP_SIZE.height = height; const alignPoint = getAlignPoint(TEMP_SIZE, style['markerHorizontalAlignment'], style['markerVerticalAlignment']); + this.rotations = []; for (let i = 0, len = cookedPoints.length; i < len; i++) { let p = cookedPoints[i]; // //for debug // ctx.fillStyle = 'red'; // ctx.fillRect(p.x - 2, p.y - 160, 4, 4); - // const origin = this._rotate(ctx, p, this._getRotationAt(i)); - const origin = this.getRotation() ? this._rotate(ctx, p, this._getRotationAt(i)) : null; + const origin = this._rotate(ctx, p, this._getRotationAt(i)); let extent: PointExtent; if (origin) { //坐标对应的像素点 @@ -89,6 +89,7 @@ export default class ImageMarkerSymbolizer extends PointSymbolizer { const rad = this._getRotationAt(i); extent = getMarkerRotationExtent(TEMP_EXTENT, rad, width, height, p, alignPoint); extent._add(pixel); + this.rotations.push(rad); } const x = p.x + alignPoint.x, y = p.y + alignPoint.y; diff --git a/src/renderer/geometry/symbolizers/PointSymbolizer.ts b/src/renderer/geometry/symbolizers/PointSymbolizer.ts index fbd6a46793..b8de9d3a47 100644 --- a/src/renderer/geometry/symbolizers/PointSymbolizer.ts +++ b/src/renderer/geometry/symbolizers/PointSymbolizer.ts @@ -29,11 +29,13 @@ abstract class PointSymbolizer extends CanvasSymbolizer { symbol: any; geometry: Geometry; painter: Painter; + rotations: Array; constructor(symbol: any, geometry: Geometry, painter: Painter) { super(); this.symbol = symbol; this.geometry = geometry; this.painter = painter; + this.rotations = []; } get2DExtent(): PointExtent { @@ -130,10 +132,12 @@ abstract class PointSymbolizer extends CanvasSymbolizer { //@internal _getRotationAt(i: number): number { + //from style let r = this.getRotation(); if (!r) { r = 0; } + //from markerPlacement ,textPlacement const rotations = this._getRenderPoints()[1]; if (!rotations || !rotations[i]) { return r; diff --git a/src/renderer/geometry/symbolizers/TextMarkerSymbolizer.ts b/src/renderer/geometry/symbolizers/TextMarkerSymbolizer.ts index 3dea1c824a..12817c838e 100644 --- a/src/renderer/geometry/symbolizers/TextMarkerSymbolizer.ts +++ b/src/renderer/geometry/symbolizers/TextMarkerSymbolizer.ts @@ -63,10 +63,10 @@ export default class TextMarkerSymbolizer extends PointSymbolizer { this.prepareCanvas(ctx, strokeAndFill, resources); Canvas.prepareCanvasFont(ctx, style); const textHaloRadius = style.textHaloRadius || 0; + this.rotations = []; for (let i = 0, len = cookedPoints.length; i < len; i++) { let p = cookedPoints[i]; - // const origin = this._rotate(ctx, p, this._getRotationAt(i)); - const origin = this.getRotation() ? this._rotate(ctx, p, this._getRotationAt(i)) : null; + const origin = this._rotate(ctx, p, this._getRotationAt(i)); let extent: PointExtent; if (origin) { //坐标对应的像素点 @@ -77,6 +77,7 @@ export default class TextMarkerSymbolizer extends PointSymbolizer { const alignPoint = getAlignPoint(textDesc.size, style['textHorizontalAlignment'], style['textVerticalAlignment']); extent = getMarkerRotationExtent(TEMP_EXTENT, rad, width, height, p, alignPoint); extent._add(pixel); + this.rotations.push(rad); } const bbox = Canvas.text(ctx, textContent, p, style, textDesc); if (origin) { diff --git a/src/renderer/geometry/symbolizers/VectorMarkerSymbolizer.ts b/src/renderer/geometry/symbolizers/VectorMarkerSymbolizer.ts index 330750ebe6..06062abad6 100644 --- a/src/renderer/geometry/symbolizers/VectorMarkerSymbolizer.ts +++ b/src/renderer/geometry/symbolizers/VectorMarkerSymbolizer.ts @@ -78,15 +78,16 @@ export default class VectorMarkerSymbolizer extends PointSymbolizer { let point = cookedPoints[i]; const size = calVectorMarkerSize(MARKER_SIZE, this.style); const [width, height] = size; - // const origin = this._rotate(ctx, point, this._getRotationAt(i)); + const origin = this._rotate(ctx, point, this._getRotationAt(i)); + this.rotations = []; let extent: PointExtent; - const origin = this.getRotation() ? this._rotate(ctx, point, this._getRotationAt(i)) : null; if (origin) { const pixel = point.sub(origin); point = origin; const rad = this._getRotationAt(i); extent = getMarkerRotationExtent(TEMP_EXTENT, rad, width, height, point, DEFAULT_ANCHOR); extent._add(pixel); + this.rotations.push(rad); } this._drawVectorMarker(ctx, point, resources); @@ -111,8 +112,8 @@ export default class VectorMarkerSymbolizer extends PointSymbolizer { const anchor = getVectorMarkerAnchor(this.style, image.width, image.height); for (let i = cookedPoints.length - 1; i >= 0; i--) { let point = cookedPoints[i]; - // const origin = this._rotate(ctx, point, this._getRotationAt(i)); - const origin = this.getRotation() ? this._rotate(ctx, point, this._getRotationAt(i)) : null; + const origin = this._rotate(ctx, point, this._getRotationAt(i)); + this.rotations = []; let extent: PointExtent; if (origin) { //坐标对应的像素点 @@ -121,6 +122,7 @@ export default class VectorMarkerSymbolizer extends PointSymbolizer { const rad = this._getRotationAt(i); extent = getMarkerRotationExtent(TEMP_EXTENT, rad, image.width, image.height, point, anchor); extent._add(pixel); + this.rotations.push(rad); } const x = point.x + anchor.x, y = point.y + anchor.y; Canvas.image(ctx, image, x, y); diff --git a/test/core/ResourceProxySpec.js b/test/core/ResourceProxySpec.js index de050495e1..bc27dd1f7a 100644 --- a/test/core/ResourceProxySpec.js +++ b/test/core/ResourceProxySpec.js @@ -7,6 +7,9 @@ describe('ResourceProxy.Spec', function () { ResourceProxy.proxy['/geojson/'] = { target: `${MTKHOST}/geojson/` } + ResourceProxy.proxy['/resources/'] = { + target: `${hostUrl}/` + } ResourceProxy.origin['https://www.abc.com/'] = { target: `${MTKHOST}/` } diff --git a/test/geometry/LineStringSpec.js b/test/geometry/LineStringSpec.js index 117db6d86e..014cc80cf4 100644 --- a/test/geometry/LineStringSpec.js +++ b/test/geometry/LineStringSpec.js @@ -5,6 +5,75 @@ describe('Geometry.LineString', function () { var center = new maptalks.Coordinate(118.846825, 32.046534); var layer; + function getLineCoordinates() { + return [ + [ + 120.61225798855435, + 31.182050959259158 + ], + [ + 120.61296882457759, + 31.180502956281003 + ], + [ + 120.61345348550253, + 31.178719957200855 + ], + [ + 120.61354234000555, + 31.176992212883675 + ], + [ + 120.61343733013837, + 31.175789684232683 + ], + [ + 120.61305767908061, + 31.17428304632554 + ], + [ + 120.61212066795895, + 31.172278766086123 + ], + [ + 120.61136944352529, + 31.170972505445064 + ], + [ + 120.61023049035157, + 31.168712424644156 + ], + [ + 120.60917231399878, + 31.166479937150513 + ], + [ + 120.60837262347263, + 31.164579171038184 + ], + [ + 120.60768602049563, + 31.16311382713033 + ], + [ + 120.60683786387699, + 31.161005627505375 + ], + [ + 120.60644205745484, + 31.160079387264744 + ], + [ + 120.60547273560496, + 31.157950382837186 + ], + [ + 120.6051334729575, + 31.157058675212028 + ] + ]; + } + beforeEach(function () { var setups = COMMON_CREATE_MAP(center, null, { width: 400, @@ -97,7 +166,6 @@ describe('Geometry.LineString', function () { describe('creation', function () { - it('normal constructor', function () { var points = [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]; var polyline = new maptalks.LineString(points); @@ -633,4 +701,53 @@ describe('Geometry.LineString', function () { }); + describe('#2440 symbol textPlacement/markerPlacement marker should rotate', function () { + it('#2440 textPlacement=line ', function (done) { + + layer.clear(); + const line = new maptalks.LineString(getLineCoordinates(), { + symbol: { + lineWidth: 16, + lineColor: 'black', + textName: '苏州湾大道', + // // textPlacement?: 'point' | 'vertex' | 'line' | 'vertex-first' | 'vertex-last'; + textPlacement: 'line', + textFill: 'yellow' + } + }).addTo(layer); + + map.setView({ + "center": [120.61702517, 31.17030688], "zoom": 14.838606578929996, "pitch": 0.20000000000003001, "bearing": -3 + }); + + + setTimeout(() => { + expect(line._getPainter().symbolizers[0].rotations.length).to.be.above(0); + done(); + }, 1000); + }); + + it('#2440 markerPlacement=line ', function (done) { + layer.clear(); + var base64 = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; + const line = new maptalks.LineString(getLineCoordinates(), { + symbol: { + lineWidth: 16, + lineColor: 'black', + markerFile: '/resources/arrow.png', + markerPlacement: 'line', + markerVerticalAlignment: 'middle' + } + }).addTo(layer); + map.setView({ + "center": [120.61702517, 31.17030688], "zoom": 14.838606578929996, "pitch": 0.20000000000003001, "bearing": -3 + }); + + setTimeout(() => { + expect(line._getPainter().symbolizers[0].rotations.length).to.be.above(0); + done(); + }, 1000); + }); + }); + }); diff --git a/test/resources/arrow.png b/test/resources/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..03f15bc2998e4aaf78aa1e89356de9c499411cee GIT binary patch literal 273 zcmV+s0q*{ZP)Px#%Sl8*R9Hvt*4+()KoA7r*&ZY@2+7$Ac48;SO0W|t#RSm@Y=L0TC^5$Sd6~VJ zqk;Ku*zBDk@h6G%kpZ~@S_4D1I*3S9_T$bs=rq8sF3tcN0GF~Kw=M(?a5rl+Pg5I0 z&;a(tF$gLk20;ge5Gnv4LJi