From 2532793ca3959570e36c9b74628ba40b149c8348 Mon Sep 17 00:00:00 2001 From: a-dutremble <106082983+a-dutremble@users.noreply.github.com> Date: Tue, 16 May 2023 16:03:54 +0200 Subject: [PATCH 1/7] feature(Layer): add method to clear cache and update tiles --- src/Core/View.js | 19 +++++++++++++++++++ src/Layer/ColorLayer.js | 10 ++++++++++ src/Layer/FeatureGeometryLayer.js | 10 ++++++++++ src/Layer/Layer.js | 16 ++++++++++++++++ src/Process/FeatureProcessing.js | 4 ++++ src/Process/LayeredMaterialNodeProcessing.js | 12 ++++++++---- 6 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/Core/View.js b/src/Core/View.js index 044bf6b205..7dc24e9f5f 100644 --- a/src/Core/View.js +++ b/src/Core/View.js @@ -449,6 +449,25 @@ class View extends THREE.EventDispatcher { } } + /** + * Redraws some imagery layers from the current layer list when the style has been modified. + * @example + * view.redrawLayer(layers); + * @param {string|Array} layerId The identifier or an array of identifier + */ + redrawLayer(layerId) { + if (!layerId.isArray) { layerId = [layerId]; } + layerId.forEach((layerIds) => { + const layer = this.getLayerById(layerIds); + if (layer) { + layer.invalidateCache(); + this.notifyChange(layer); + } else { + throw new Error(`${layerIds} doesn't exist`); + } + }); + } + /** * Notifies the scene it needs to be updated due to changes exterior to the * scene itself (e.g. camera movement). diff --git a/src/Layer/ColorLayer.js b/src/Layer/ColorLayer.js index 6447b40799..b3365ca235 100644 --- a/src/Layer/ColorLayer.js +++ b/src/Layer/ColorLayer.js @@ -127,6 +127,16 @@ class ColorLayer extends RasterLayer { update(context, layer, node, parent) { return updateLayeredMaterialNodeImagery(context, this, node, parent); } + + invalidateCache() { + this.cache.clear(); + this.parent.level0Nodes.forEach((node0) => { + node0.traverse((tile) => { + tile.layerUpdateState[this.id] = undefined; + tile.redraw = true; + }); + }); + } } export default ColorLayer; diff --git a/src/Layer/FeatureGeometryLayer.js b/src/Layer/FeatureGeometryLayer.js index 1a142eb557..1ba88ee89a 100644 --- a/src/Layer/FeatureGeometryLayer.js +++ b/src/Layer/FeatureGeometryLayer.js @@ -61,6 +61,16 @@ class FeatureGeometryLayer extends GeometryLayer { this.object3d.clear(); } } + + invalidateCache() { + this.cache.clear(); + this.parent.level0Nodes.forEach((node0) => { + node0.traverse((tile) => { + tile.layerUpdateState[this.id] = undefined; + tile.redraw = true; + }); + }); + } } export default FeatureGeometryLayer; diff --git a/src/Layer/Layer.js b/src/Layer/Layer.js index d3e2ef1802..fa4981b0a3 100644 --- a/src/Layer/Layer.js +++ b/src/Layer/Layer.js @@ -262,6 +262,22 @@ class Layer extends THREE.EventDispatcher { delete(clearCache) { console.warn('Function delete doesn\'t exist for this layer'); } + + /** + * Invalidate the cache of this layer. + * Only implemented in {@link ColorLayer} and {@link FeatureGeometryLayer} for the moment. + */ + invalidateCache() { + throw new Error('invalidateCache is not supported yet in this type of layer'); + } + + /** + * Set the style of the layer. + * @param {StyleOptions} style Object containing style parameters. {@link StyleOptions} + */ + setStyle(style) { + this.style = new Style(style); + } } export default Layer; diff --git a/src/Process/FeatureProcessing.js b/src/Process/FeatureProcessing.js index 29d1c9efcb..e23e05a7a0 100644 --- a/src/Process/FeatureProcessing.js +++ b/src/Process/FeatureProcessing.js @@ -17,6 +17,10 @@ export default { return; } + if (node.redraw) { + node.link[this.id] = []; + } + if (node.layerUpdateState[layer.id] === undefined) { node.layerUpdateState[layer.id] = new LayerUpdateState(); } else if (!node.layerUpdateState[layer.id].canTryUpdate()) { diff --git a/src/Process/LayeredMaterialNodeProcessing.js b/src/Process/LayeredMaterialNodeProcessing.js index e53b513111..f90c4b76f4 100644 --- a/src/Process/LayeredMaterialNodeProcessing.js +++ b/src/Process/LayeredMaterialNodeProcessing.js @@ -107,11 +107,15 @@ export function updateLayeredMaterialNodeImagery(context, layer, node, parent) { return; } - if (nodeLayer.level >= extentsDestination[0].zoom) { - // default decision method - node.layerUpdateState[layer.id].noMoreUpdatePossible(); - return; + // During the redraw processing, skip the noMoreUpdatePossible state + if (!node.redraw) { + if (nodeLayer.level >= extentsDestination[0].zoom) { + // default decision method + node.layerUpdateState[layer.id].noMoreUpdatePossible(); + return; + } } + node.redraw = false; // is fetching data from this layer disabled? if (layer.frozen) { From 46e65f088325d4de27e046abe3d2e10b80cda842 Mon Sep 17 00:00:00 2001 From: a-dutremble <106082983+a-dutremble@users.noreply.github.com> Date: Fri, 26 May 2023 11:38:59 +0200 Subject: [PATCH 2/7] example(MiscRedrawLayer): add an example using view.redrawLayer --- examples/misc_redraw_layer.html | 154 ++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 examples/misc_redraw_layer.html diff --git a/examples/misc_redraw_layer.html b/examples/misc_redraw_layer.html new file mode 100644 index 0000000000..a88a6ce1a1 --- /dev/null +++ b/examples/misc_redraw_layer.html @@ -0,0 +1,154 @@ + + + Itowns - Globe + WFS + + + + + + + + + +
+
+ +
+ + + + + + + From e71f2d3b44d45daf81a444be99c3060a1e5ce5c9 Mon Sep 17 00:00:00 2001 From: Aymeric DUTREMBLE Date: Tue, 21 Nov 2023 11:19:16 +0100 Subject: [PATCH 3/7] refactor(test): add new unit test --- test/unit/featuregeometrylayer.js | 7 ++++++- test/unit/layer.js | 35 +++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/test/unit/featuregeometrylayer.js b/test/unit/featuregeometrylayer.js index 84e23dd8e4..d3fc61773c 100644 --- a/test/unit/featuregeometrylayer.js +++ b/test/unit/featuregeometrylayer.js @@ -140,5 +140,10 @@ describe('Layer with Feature process', function () { done(); }).catch(done); }); -}); + it('invalidate cache', function () { + ariege.invalidateCache(); + assert.equal(ariege.parent.level0Nodes[0].redraw, true); + assert.equal(ariege.parent.level0Nodes[0].layerUpdateState[ariege.id], undefined); + }); +}); diff --git a/test/unit/layer.js b/test/unit/layer.js index 1b2c5dd616..c12406bdf8 100644 --- a/test/unit/layer.js +++ b/test/unit/layer.js @@ -1,6 +1,11 @@ import assert from 'assert'; import Layer, { ImageryLayers } from 'Layer/Layer'; import ColorLayer from 'Layer/ColorLayer'; +import GlobeView from 'Core/Prefab/GlobeView'; +import FileSource from 'Source/FileSource'; +import Coordinates from 'Core/Geographic/Coordinates'; +import HttpsProxyAgent from 'https-proxy-agent'; +import Renderer from './bootstrap'; describe('Layer', function () { it('should emit an event on property changed', function () { @@ -67,3 +72,33 @@ describe('ImageryLayers', function () { assert.throws(() => new ColorLayer('id'), /^Error: Layer id needs Source$/); }); }); + +describe('ColorLayer', function () { + const renderer = new Renderer(); + const placement = { coord: new Coordinates('EPSG:4326', 1.5, 43), range: 300000 }; + const viewer = new GlobeView(renderer.domElement, placement, { renderer }); + + const source = new FileSource({ + url: 'https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/09-ariege/departement-09-ariege.geojson', + crs: 'EPSG:4326', + format: 'application/json', + networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, + }); + + const ariege = new ColorLayer('ariege', { + transparent: true, + style: { + fill: { color: 'blue', opacity: 0.8 }, + stroke: { color: 'black', width: 1.0 }, + }, + source, + zoom: { min: 11 }, + }); + viewer.addLayer(ariege); + + it('invalidate cache', function () { + ariege.invalidateCache(); + assert.equal(ariege.parent.level0Nodes[0].redraw, true); + assert.equal(ariege.parent.level0Nodes[0].layerUpdateState[ariege.id], undefined); + }); +}); From e27555ceea145db60a8a20d5f182532705f8e907 Mon Sep 17 00:00:00 2001 From: ftoromanoff Date: Fri, 5 Jan 2024 15:30:00 +0100 Subject: [PATCH 4/7] refactor(Layer): simplification => supp Layer.setStyle() --- examples/misc_redraw_layer.html | 40 ++++++++++++--------------------- src/Layer/Layer.js | 8 ------- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/examples/misc_redraw_layer.html b/examples/misc_redraw_layer.html index a88a6ce1a1..b85255b353 100644 --- a/examples/misc_redraw_layer.html +++ b/examples/misc_redraw_layer.html @@ -13,8 +13,8 @@
@@ -81,7 +81,6 @@ format: 'application/json', }); - // Define the functions that sets the color according to the properties function color1(properties) { if (properties.code_cultu == '28') { return '#FD8A8A'; } @@ -105,33 +104,29 @@ else { return '#E0E0E0'; } } - // Set the two different styles - const style1 = { - fill: { - color: color1, - opacity: 0.8 - }, - stroke: { - color: 'black', - width: 1.0, - }, - }; - - const style2 = { + const color = function (p) { + const styleBox = document.getElementById('styleBox'); + if (styleBox.value === '0') { + return color1(p); + } else if (styleBox.value === '1') { + return color2(p); + } + } + const style = { fill: { - color: color2, + color, opacity: 0.8 }, stroke: { color: 'black', width: 1.0, }, - }; + } // Create the layer where you specified the starting style var wfsAgriLayer = new itowns.ColorLayer('wfsAgri', { transparent: true, - style: style1, + style, source: wfsAgriLayer, zoom: { min: 11 }, }); @@ -139,13 +134,6 @@ // Function that calls the onChange event in the combobox function selectStyle() { - const styleBox = document.getElementById('styleBox'); - const layer = view.getLayerById('wfsAgri'); - if (styleBox.value === 'Style 1') { - layer.setStyle(style1); - } else if (styleBox.value === 'Style 2') { - layer.setStyle(style2); - } view.redrawLayer('wfsAgri'); } diff --git a/src/Layer/Layer.js b/src/Layer/Layer.js index fa4981b0a3..6b0c74a7bf 100644 --- a/src/Layer/Layer.js +++ b/src/Layer/Layer.js @@ -270,14 +270,6 @@ class Layer extends THREE.EventDispatcher { invalidateCache() { throw new Error('invalidateCache is not supported yet in this type of layer'); } - - /** - * Set the style of the layer. - * @param {StyleOptions} style Object containing style parameters. {@link StyleOptions} - */ - setStyle(style) { - this.style = new Style(style); - } } export default Layer; From c62281fffc6b214131d6aa87220f36ae13c5097a Mon Sep 17 00:00:00 2001 From: ftoromanoff Date: Fri, 5 Jan 2024 15:51:28 +0100 Subject: [PATCH 5/7] refactor(example): clean up --- examples/misc_redraw_layer.html | 54 ++++++++++++++------------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/examples/misc_redraw_layer.html b/examples/misc_redraw_layer.html index b85255b353..cf100c0835 100644 --- a/examples/misc_redraw_layer.html +++ b/examples/misc_redraw_layer.html @@ -12,9 +12,9 @@
- + +
@@ -81,35 +81,27 @@ format: 'application/json', }); - // Define the functions that sets the color according to the properties - function color1(properties) { - if (properties.code_cultu == '28') { return '#FD8A8A'; } - else if (properties.code_cultu == '01') { return '#F1F7B5'; } - else if (properties.code_cultu == '02') { return '#A8D1D1'; } - else if (properties.code_cultu == '03') { return '#9EA1D4'; } - else if (properties.code_cultu == '04') { return '#3CA59D'; } - else if (properties.code_cultu == '05') { return '#5A3D55'; } - else if (properties.code_cultu == '18') { return '#A2DE96'; } - else if (properties.code_cultu == '19') { return '#E79C2A'; } - else { return '#E0E0E0'; } - } - - function color2(properties) { - let surf = parseFloat(properties.surf_cultu); - if (surf >=0 && surf < 2.84) { return '#f4cdd7'; } - else if (surf >= 2.84 && surf < 6.19) { return '#e5a4b0'; } - else if (surf >= 6.19 && surf < 10.43) { return '#d47c86'; } - else if (surf >= 10.43 && surf < 15.2) { return '#bf545b'; } - else if (surf > 15.2) { return '#a6292f'; } - else { return '#E0E0E0'; } - } - - const color = function (p) { + // Define the function that sets the color according to the properties and the choosen style. + const color = function (properties) { const styleBox = document.getElementById('styleBox'); - if (styleBox.value === '0') { - return color1(p); - } else if (styleBox.value === '1') { - return color2(p); + if (styleBox.value === 'Type') { + if (properties.code_cultu == '28') { return '#FD8A8A'; } + else if (properties.code_cultu == '01') { return '#F1F7B5'; } + else if (properties.code_cultu == '02') { return '#A8D1D1'; } + else if (properties.code_cultu == '03') { return '#9EA1D4'; } + else if (properties.code_cultu == '04') { return '#3CA59D'; } + else if (properties.code_cultu == '05') { return '#5A3D55'; } + else if (properties.code_cultu == '18') { return '#A2DE96'; } + else if (properties.code_cultu == '19') { return '#E79C2A'; } + else { return '#E0E0E0'; } + } else if (styleBox.value === 'Surface') { + let surf = parseFloat(properties.surf_cultu); + if (surf >=0 && surf < 2.84) { return '#f4cdd7'; } + else if (surf >= 2.84 && surf < 6.19) { return '#e5a4b0'; } + else if (surf >= 6.19 && surf < 10.43) { return '#d47c86'; } + else if (surf >= 10.43 && surf < 15.2) { return '#bf545b'; } + else if (surf > 15.2) { return '#a6292f'; } + else { return '#E0E0E0'; } } } const style = { From b208eb60441f4edaaa3f5027137058b22299b43e Mon Sep 17 00:00:00 2001 From: ftoromanoff Date: Fri, 5 Jan 2024 15:39:04 +0100 Subject: [PATCH 6/7] refactor(test): move test colorLayer to own test file --- test/unit/colorlayer.js | 37 +++++++++++++++++++++++++++++++++++++ test/unit/layer.js | 35 ----------------------------------- 2 files changed, 37 insertions(+), 35 deletions(-) create mode 100644 test/unit/colorlayer.js diff --git a/test/unit/colorlayer.js b/test/unit/colorlayer.js new file mode 100644 index 0000000000..39894c9ddc --- /dev/null +++ b/test/unit/colorlayer.js @@ -0,0 +1,37 @@ +import assert from 'assert'; +import ColorLayer from 'Layer/ColorLayer'; +import GlobeView from 'Core/Prefab/GlobeView'; +import FileSource from 'Source/FileSource'; +import Coordinates from 'Core/Geographic/Coordinates'; +import HttpsProxyAgent from 'https-proxy-agent'; +import Renderer from './bootstrap'; + +describe('ColorLayer', function () { + const renderer = new Renderer(); + const placement = { coord: new Coordinates('EPSG:4326', 1.5, 43), range: 300000 }; + const viewer = new GlobeView(renderer.domElement, placement, { renderer }); + + const source = new FileSource({ + url: 'https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/09-ariege/departement-09-ariege.geojson', + crs: 'EPSG:4326', + format: 'application/json', + networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, + }); + + const ariege = new ColorLayer('ariege', { + transparent: true, + style: { + fill: { color: 'blue', opacity: 0.8 }, + stroke: { color: 'black', width: 1.0 }, + }, + source, + zoom: { min: 11 }, + }); + viewer.addLayer(ariege); + + it('invalidate cache', function () { + ariege.invalidateCache(); + assert.equal(ariege.parent.level0Nodes[0].redraw, true); + assert.equal(ariege.parent.level0Nodes[0].layerUpdateState[ariege.id], undefined); + }); +}); diff --git a/test/unit/layer.js b/test/unit/layer.js index c12406bdf8..1b2c5dd616 100644 --- a/test/unit/layer.js +++ b/test/unit/layer.js @@ -1,11 +1,6 @@ import assert from 'assert'; import Layer, { ImageryLayers } from 'Layer/Layer'; import ColorLayer from 'Layer/ColorLayer'; -import GlobeView from 'Core/Prefab/GlobeView'; -import FileSource from 'Source/FileSource'; -import Coordinates from 'Core/Geographic/Coordinates'; -import HttpsProxyAgent from 'https-proxy-agent'; -import Renderer from './bootstrap'; describe('Layer', function () { it('should emit an event on property changed', function () { @@ -72,33 +67,3 @@ describe('ImageryLayers', function () { assert.throws(() => new ColorLayer('id'), /^Error: Layer id needs Source$/); }); }); - -describe('ColorLayer', function () { - const renderer = new Renderer(); - const placement = { coord: new Coordinates('EPSG:4326', 1.5, 43), range: 300000 }; - const viewer = new GlobeView(renderer.domElement, placement, { renderer }); - - const source = new FileSource({ - url: 'https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/09-ariege/departement-09-ariege.geojson', - crs: 'EPSG:4326', - format: 'application/json', - networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, - }); - - const ariege = new ColorLayer('ariege', { - transparent: true, - style: { - fill: { color: 'blue', opacity: 0.8 }, - stroke: { color: 'black', width: 1.0 }, - }, - source, - zoom: { min: 11 }, - }); - viewer.addLayer(ariege); - - it('invalidate cache', function () { - ariege.invalidateCache(); - assert.equal(ariege.parent.level0Nodes[0].redraw, true); - assert.equal(ariege.parent.level0Nodes[0].layerUpdateState[ariege.id], undefined); - }); -}); From b04d9115176de1b324728fb0f8a0d3c24c761692 Mon Sep 17 00:00:00 2001 From: Vincent JAILLOT Date: Wed, 2 Oct 2024 16:54:23 +0200 Subject: [PATCH 7/7] example(misc_redraw_layer): move geoportail url to geoplateforme url --- examples/misc_redraw_layer.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/misc_redraw_layer.html b/examples/misc_redraw_layer.html index cf100c0835..1361aea018 100644 --- a/examples/misc_redraw_layer.html +++ b/examples/misc_redraw_layer.html @@ -15,7 +15,7 @@ + @@ -24,7 +24,7 @@