From a161ba82d95ea52280bdcd0ce6c20ceefcb0e40e Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Mon, 24 Aug 2020 23:24:27 +0200 Subject: [PATCH 1/4] Remove notes about custom renderer --- examples/vector-label-decluttering.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/vector-label-decluttering.html b/examples/vector-label-decluttering.html index 19ae8ab16a..c453b3a2d2 100644 --- a/examples/vector-label-decluttering.html +++ b/examples/vector-label-decluttering.html @@ -1,11 +1,11 @@ --- layout: example.html title: Vector Label Decluttering -shortdesc: Label decluttering with a custom renderer. +shortdesc: Label decluttering on polygons. resources: - https://cdn.polyfill.io/v2/polyfill.min.js?features=Set" docs: > - Decluttering is used to avoid overlapping labels. The `overflow: true` setting on the text style makes it so labels that do not fit within the bounds of a polygon are also included. + Decluttering is used to avoid overlapping labels. The `overflow: true` setting on the text style makes it so labels that do not fit within the bounds of a polygon are also considered for decluttering. tags: "vector, decluttering, labels" ---
From 9e7bbb0d4ee0be9b66c9a6055b4cf865d1e5715f Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Mon, 24 Aug 2020 23:43:22 +0200 Subject: [PATCH 2/4] Add custom style renderer example --- examples/style-renderer.html | 10 +++++ examples/style-renderer.js | 76 ++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 examples/style-renderer.html create mode 100644 examples/style-renderer.js diff --git a/examples/style-renderer.html b/examples/style-renderer.html new file mode 100644 index 0000000000..aa33f0a455 --- /dev/null +++ b/examples/style-renderer.html @@ -0,0 +1,10 @@ +--- +layout: example.html +title: Style renderer +shortdesc: Example of a style with a custom renderer. +docs: > + A custom style renderer, a prerender event and different global composite operations are used to render the flag of a country as fill for the country shape. +tags: "vector, geojson, style, custom, renderer" +--- +
+
 
diff --git a/examples/style-renderer.js b/examples/style-renderer.js new file mode 100644 index 0000000000..bc857323f5 --- /dev/null +++ b/examples/style-renderer.js @@ -0,0 +1,76 @@ +import GeoJSON from '../src/ol/format/GeoJSON.js'; +import Map from '../src/ol/Map.js'; +import VectorLayer from '../src/ol/layer/Vector.js'; +import VectorSource from '../src/ol/source/Vector.js'; +import View from '../src/ol/View.js'; +import {Fill, Style} from '../src/ol/style.js'; +import {getBottomLeft, getHeight, getWidth} from '../src/ol/extent.js'; +import {toContext} from '../src/ol/render.js'; + +const polygonFill = new Fill(); +const style = new Style({ + renderer: function (pixelCoordinates, state) { + const context = state.context; + const geometry = state.geometry.clone(); + geometry.setCoordinates(pixelCoordinates); + const extent = geometry.getExtent(); + const width = getWidth(extent); + const height = getHeight(extent); + const flag = state.feature.get('flag'); + if (!flag || height < 1 || width < 1) { + return; + } + // Stitch out country shape from the blue canvas + context.globalCompositeOperation = 'destination-out'; + const renderContext = toContext(context, { + pixelRatio: 1, + }); + renderContext.setFillStrokeStyle(polygonFill); + renderContext.drawGeometry(geometry); + const bottomLeft = getBottomLeft(extent); + // Fill transparent country with the flag image + context.globalCompositeOperation = 'destination-over'; + const left = bottomLeft[0]; + const bottom = bottomLeft[1]; + context.drawImage(flag, 2, 12, 60, 40, left, bottom, width, height); + }, +}); + +const vectorLayer = new VectorLayer({ + source: new VectorSource({ + url: + 'https://openlayersbook.github.io/openlayers_book_samples/assets/data/countries.geojson', + format: new GeoJSON(), + }), + style: style, +}); + +// Fill the canvas blue as clip mask for flag images +vectorLayer.on('prerender', function (event) { + const context = event.context; + context.globalCompositeOperation = 'source-over'; + context.fillStyle = 'rgb(152,293,253)'; + context.fillRect(0, 0, context.canvas.width, context.canvas.height); +}); + +// Load country flags and set them as `flag` attribute on the country feature +vectorLayer.getSource().on('addfeature', function (event) { + const feature = event.feature; + const img = new Image(); + img.onload = function () { + feature.set('flag', img); + }; + img.src = + 'https://www.countryflags.io/' + + feature.get('iso_a2').toLowerCase() + + '/flat/64.png'; +}); + +new Map({ + layers: [vectorLayer], + target: 'map', + view: new View({ + center: [0, 0], + zoom: 1, + }), +}); From 6412b040c327e38a9f4e2524d1a798e8a82c0935 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 26 Aug 2020 00:07:24 -0600 Subject: [PATCH 3/4] Use clip path --- examples/style-renderer.css | 3 +++ examples/style-renderer.js | 27 +++++++++++++-------------- 2 files changed, 16 insertions(+), 14 deletions(-) create mode 100644 examples/style-renderer.css diff --git a/examples/style-renderer.css b/examples/style-renderer.css new file mode 100644 index 0000000000..5f29be1fe5 --- /dev/null +++ b/examples/style-renderer.css @@ -0,0 +1,3 @@ +#map { + background: #75d0f0; +} diff --git a/examples/style-renderer.js b/examples/style-renderer.js index bc857323f5..1cbe71ba0e 100644 --- a/examples/style-renderer.js +++ b/examples/style-renderer.js @@ -3,11 +3,15 @@ import Map from '../src/ol/Map.js'; import VectorLayer from '../src/ol/layer/Vector.js'; import VectorSource from '../src/ol/source/Vector.js'; import View from '../src/ol/View.js'; -import {Fill, Style} from '../src/ol/style.js'; +import {Fill, Stroke, Style} from '../src/ol/style.js'; import {getBottomLeft, getHeight, getWidth} from '../src/ol/extent.js'; import {toContext} from '../src/ol/render.js'; -const polygonFill = new Fill(); +const fill = new Fill(); +const stroke = new Stroke({ + color: 'rgba(255,255,255,0.8)', + width: 2, +}); const style = new Style({ renderer: function (pixelCoordinates, state) { const context = state.context; @@ -20,19 +24,22 @@ const style = new Style({ if (!flag || height < 1 || width < 1) { return; } + // Stitch out country shape from the blue canvas - context.globalCompositeOperation = 'destination-out'; + context.save(); const renderContext = toContext(context, { pixelRatio: 1, }); - renderContext.setFillStrokeStyle(polygonFill); + renderContext.setFillStrokeStyle(fill, stroke); renderContext.drawGeometry(geometry); - const bottomLeft = getBottomLeft(extent); + context.clip(); + // Fill transparent country with the flag image - context.globalCompositeOperation = 'destination-over'; + const bottomLeft = getBottomLeft(extent); const left = bottomLeft[0]; const bottom = bottomLeft[1]; context.drawImage(flag, 2, 12, 60, 40, left, bottom, width, height); + context.restore(); }, }); @@ -45,14 +52,6 @@ const vectorLayer = new VectorLayer({ style: style, }); -// Fill the canvas blue as clip mask for flag images -vectorLayer.on('prerender', function (event) { - const context = event.context; - context.globalCompositeOperation = 'source-over'; - context.fillStyle = 'rgb(152,293,253)'; - context.fillRect(0, 0, context.canvas.width, context.canvas.height); -}); - // Load country flags and set them as `flag` attribute on the country feature vectorLayer.getSource().on('addfeature', function (event) { const feature = event.feature; From eb92d0dceedbbabe4fccaf740091c7ec530e41fa Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 26 Aug 2020 09:25:50 +0200 Subject: [PATCH 4/4] Update description --- examples/style-renderer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/style-renderer.html b/examples/style-renderer.html index aa33f0a455..63593eca0f 100644 --- a/examples/style-renderer.html +++ b/examples/style-renderer.html @@ -3,7 +3,7 @@ layout: example.html title: Style renderer shortdesc: Example of a style with a custom renderer. docs: > - A custom style renderer, a prerender event and different global composite operations are used to render the flag of a country as fill for the country shape. + A custom style renderer and a clip path are used to render the flag of a country as fill for the country shape. tags: "vector, geojson, style, custom, renderer" ---