From 811c1302415d33813b57a51f76995bf5c7182314 Mon Sep 17 00:00:00 2001 From: changqing Date: Tue, 15 Dec 2020 15:38:23 +0800 Subject: [PATCH 1/4] Implement custom circle render --- src/ol/render/canvas/Builder.js | 20 ++++++++++++++++++++ src/ol/render/canvas/Executor.js | 8 +++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/ol/render/canvas/Builder.js b/src/ol/render/canvas/Builder.js index 1b710a74a9..8b1b0c53e3 100644 --- a/src/ol/render/canvas/Builder.js +++ b/src/ol/render/canvas/Builder.js @@ -345,6 +345,26 @@ class CanvasBuilder extends VectorContext { geometry, renderer, ]); + } else if (type == GeometryType.CIRCLE) { + const flatCoordinates = geometry.getFlatCoordinates(); + this.appendFlatLineCoordinates( + flatCoordinates, + 0, + flatCoordinates.length, + stride, + false, + false + ); + builderEnd = this.coordinates.length; + this.instructions.push([ + CanvasInstruction.CUSTOM, + builderBegin, + builderEnd, + geometry, + renderer, + undefined, + 4, + ]); } this.endGeometry(feature); } diff --git a/src/ol/render/canvas/Executor.js b/src/ol/render/canvas/Executor.js index 058961edaf..bf7b6c465b 100644 --- a/src/ol/render/canvas/Executor.js +++ b/src/ol/render/canvas/Executor.js @@ -731,6 +731,7 @@ class Executor { const geometry = /** @type {import("../../geom/SimpleGeometry.js").default} */ (instruction[3]); const renderer = instruction[4]; const fn = instruction.length == 6 ? instruction[5] : undefined; + const coordsLength = instruction.length >= 7 ? instruction[6] : 2; state.geometry = geometry; state.feature = feature; if (!(i in coordinateCache)) { @@ -740,9 +741,10 @@ class Executor { if (fn) { fn(pixelCoordinates, d, dd, 2, coords); } else { - coords[0] = pixelCoordinates[d]; - coords[1] = pixelCoordinates[d + 1]; - coords.length = 2; + for (let index = 0; index < coordsLength; index++) { + coords[index] = pixelCoordinates[d + index]; + } + coords.length = coordsLength; } renderer(coords, state); ++i; From 3393de3c5460e0a9411bbcff4d363905b280be3f Mon Sep 17 00:00:00 2001 From: changqing Date: Tue, 15 Dec 2020 15:38:48 +0800 Subject: [PATCH 2/4] Custom circle render example --- examples/custom-circle-render.html | 9 ++++ examples/custom-circle-render.js | 66 ++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 examples/custom-circle-render.html create mode 100644 examples/custom-circle-render.js diff --git a/examples/custom-circle-render.html b/examples/custom-circle-render.html new file mode 100644 index 0000000000..f0ed7ad7c0 --- /dev/null +++ b/examples/custom-circle-render.html @@ -0,0 +1,9 @@ +--- +layout: example.html +title: Custom Circle Render +shortdesc: Example of a custom circle render. +docs: > + This example demonstrates the use of 'ol/style/Style' render option function to render circle feature. +tags: "circle, feature, vector, render, custom" +--- +
diff --git a/examples/custom-circle-render.js b/examples/custom-circle-render.js new file mode 100644 index 0000000000..57c7bf4026 --- /dev/null +++ b/examples/custom-circle-render.js @@ -0,0 +1,66 @@ +import Feature from '../src/ol/Feature.js'; +import Map from '../src/ol/Map.js'; +import View from '../src/ol/View.js'; +import {Circle} from '../src/ol/geom.js'; +import {OSM, Vector as VectorSource} from '../src/ol/source.js'; +import {Style} from '../src/ol/style.js'; +import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; + +const circleFeature = new Feature({ + geometry: new Circle([12127398.797692968, 4063894.123105166], 50), +}); +circleFeature.setStyle( + new Style({ + renderer(coordinate, state) { + // eslint-disable-next-line no-console + console.log('This circle is rendered by the code below.', Date.now()); + const [x, y, x1, y1] = coordinate; + const ctx = state.context; + const dx = x1 - x; + const dy = y1 - y; + const radius = Math.sqrt(dx * dx + dy * dy); + + const innerRadius = 0; + const outerRadius = radius * 1.4; + + const gradient = ctx.createRadialGradient( + x, + y, + innerRadius, + x, + y, + outerRadius + ); + gradient.addColorStop(0, 'rgba(255,0,0,0)'); + gradient.addColorStop(0.6, 'rgba(255,0,0,0.2)'); + gradient.addColorStop(1, 'rgba(255,0,0,0.8)'); + ctx.beginPath(); + ctx.arc(x, y, radius, 0, 2 * Math.PI, true); + ctx.fillStyle = gradient; + ctx.fill(); + + ctx.arc(x, y, radius, 0, 2 * Math.PI, true); + ctx.strokeStyle = 'rgba(255,0,0,1)'; + ctx.stroke(); + }, + }) +); + +new Map({ + layers: [ + new TileLayer({ + source: new OSM(), + visible: true, + }), + new VectorLayer({ + source: new VectorSource({ + features: [circleFeature], + }), + }), + ], + target: 'map', + view: new View({ + center: [12127398.797692968, 4063894.123105166], + zoom: 19, + }), +}); From c4f5709349201e3fb6086446b5678f5b3e50d5f5 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Fri, 18 Dec 2020 23:27:11 +0100 Subject: [PATCH 3/4] Simplify custom circle rendering --- examples/custom-circle-render.js | 4 ++-- src/ol/render/canvas/Builder.js | 25 ++++--------------------- src/ol/render/canvas/Executor.js | 8 +++----- 3 files changed, 9 insertions(+), 28 deletions(-) diff --git a/examples/custom-circle-render.js b/examples/custom-circle-render.js index 57c7bf4026..06b1802cfe 100644 --- a/examples/custom-circle-render.js +++ b/examples/custom-circle-render.js @@ -11,10 +11,10 @@ const circleFeature = new Feature({ }); circleFeature.setStyle( new Style({ - renderer(coordinate, state) { + renderer(coordinates, state) { // eslint-disable-next-line no-console console.log('This circle is rendered by the code below.', Date.now()); - const [x, y, x1, y1] = coordinate; + const [[x, y], [x1, y1]] = coordinates; const ctx = state.context; const dx = x1 - x; const dy = y1 - y; diff --git a/src/ol/render/canvas/Builder.js b/src/ol/render/canvas/Builder.js index 8b1b0c53e3..215917d532 100644 --- a/src/ol/render/canvas/Builder.js +++ b/src/ol/render/canvas/Builder.js @@ -303,7 +303,10 @@ class CanvasBuilder extends VectorContext { renderer, inflateCoordinatesArray, ]); - } else if (type == GeometryType.LINE_STRING) { + } else if ( + type == GeometryType.LINE_STRING || + type == GeometryType.CIRCLE + ) { flatCoordinates = geometry.getFlatCoordinates(); builderEnd = this.appendFlatLineCoordinates( flatCoordinates, @@ -345,26 +348,6 @@ class CanvasBuilder extends VectorContext { geometry, renderer, ]); - } else if (type == GeometryType.CIRCLE) { - const flatCoordinates = geometry.getFlatCoordinates(); - this.appendFlatLineCoordinates( - flatCoordinates, - 0, - flatCoordinates.length, - stride, - false, - false - ); - builderEnd = this.coordinates.length; - this.instructions.push([ - CanvasInstruction.CUSTOM, - builderBegin, - builderEnd, - geometry, - renderer, - undefined, - 4, - ]); } this.endGeometry(feature); } diff --git a/src/ol/render/canvas/Executor.js b/src/ol/render/canvas/Executor.js index bf7b6c465b..058961edaf 100644 --- a/src/ol/render/canvas/Executor.js +++ b/src/ol/render/canvas/Executor.js @@ -731,7 +731,6 @@ class Executor { const geometry = /** @type {import("../../geom/SimpleGeometry.js").default} */ (instruction[3]); const renderer = instruction[4]; const fn = instruction.length == 6 ? instruction[5] : undefined; - const coordsLength = instruction.length >= 7 ? instruction[6] : 2; state.geometry = geometry; state.feature = feature; if (!(i in coordinateCache)) { @@ -741,10 +740,9 @@ class Executor { if (fn) { fn(pixelCoordinates, d, dd, 2, coords); } else { - for (let index = 0; index < coordsLength; index++) { - coords[index] = pixelCoordinates[d + index]; - } - coords.length = coordsLength; + coords[0] = pixelCoordinates[d]; + coords[1] = pixelCoordinates[d + 1]; + coords.length = 2; } renderer(coords, state); ++i; From 6a7472617f8b99800d714599a9748554ffd48154 Mon Sep 17 00:00:00 2001 From: changqing Date: Sat, 19 Dec 2020 21:42:58 +0800 Subject: [PATCH 4/4] Remove the console.log from the custom circle render example --- examples/custom-circle-render.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/custom-circle-render.js b/examples/custom-circle-render.js index 06b1802cfe..974c8ffdda 100644 --- a/examples/custom-circle-render.js +++ b/examples/custom-circle-render.js @@ -12,8 +12,6 @@ const circleFeature = new Feature({ circleFeature.setStyle( new Style({ renderer(coordinates, state) { - // eslint-disable-next-line no-console - console.log('This circle is rendered by the code below.', Date.now()); const [[x, y], [x1, y1]] = coordinates; const ctx = state.context; const dx = x1 - x;