diff --git a/docs/app/event/LegendsLayerSet/LegendsLayerSet-event-managment.md b/docs/app/event/LegendsLayerSet/LegendsLayerSet-event-managment.md index 8bc737521f9..2b39d9060ff 100644 --- a/docs/app/event/LegendsLayerSet/LegendsLayerSet-event-managment.md +++ b/docs/app/event/LegendsLayerSet/LegendsLayerSet-event-managment.md @@ -20,7 +20,7 @@ The `layerPath` parameter is used to link the legend to the layer entry configur The class can be instantiated using the constructor or the create method. At creation time, the constructor instantiates a `LayerSet` object which will send a `LAYER_SET.REQUEST_LAYER_INVENTORY` event using a `mapId/LayerSetId` handler in order to get the list of all the layerPaths existing on the map. Throughout its existence, the `LegendsLayerSet` instance listens, through its `LayerSet` property, to the `LAYER_SET.LAYER_REGISTRATION` events that are emitted when a layer is created/destroyed on the map or in response to the inventory request to update its `ResultSet` property. It also listens to the `GET_LEGENDS.LEGEND_INFO` event. This listener receives the legend information returned by the layer's `getLegend` call and store it in the `LayerSet`. If all the registered layers have their legend information, a `GET_LEGENDS.LEGENDS_LAYERSET_UPDATED` event is triggered with a `mapId/LayerSetId` handler. -When created, the `LegendsLayerSet` is in a idle state. To start it, the instance listens to a `GET_LEGENDS.TRIGGER` event. This event is only listen once and when it is received, a `LAYER_SET.UPDATED` listener is attached to the instance to wait for `LayerSet` modifications. Then, a `GET_LEGENDS.QUERY_LEGEND` event will be emited to all undefined legend of the `LayerSet` to obtain the legends. +When the `LegendsLayerSet` is created, a `LAYER_SET.UPDATED` listener is attached to the instance to wait for `LayerSet` modifications. Then, a `GET_LEGENDS.QUERY_LEGEND` event will be emited to all undefined legend of the `LayerSet` to obtain the legends. The `LAYER_SET.UPDATED` listener will catch layer add/remove applied to the map. If a layer is added, a `GET_LEGENDS.QUERY_LEGEND` event will be emited for it and when all the registered layers have received their legend information, a `GET_LEGENDS.LEGENDS_LAYERSET_UPDATED` event is emited using the `mapId/LayerSetId` as handler. The `GET_LEGENDS.LEGENDS_LAYERSET_UPDATED` event is also emited when a layer is removed from the map to signal that a legend has been removed. diff --git a/packages/geoview-core/public/css/style.css b/packages/geoview-core/public/css/style.css index 30a9e5225e0..af11cc4f975 100644 --- a/packages/geoview-core/public/css/style.css +++ b/packages/geoview-core/public/css/style.css @@ -152,3 +152,32 @@ td { text-align: center; font-size: smaller; } + +table.info, th.info, td.info, th.infoCol1, td.infoCol1 { + border: 1px solid black; +} +th.info, td.info, th.infoCol1, td.infoCol1 { + padding: 15px; + width: 15%; +} +th.info, th.infoCol1, td.infoCol1 { + text-align: left; + font-weight: bold; + font-size: 15px; +} + +table.state { + font-family: arial, sans-serif; + border-collapse: collapse; + width: 100%; +} + +td.state, th.state { + border: 1px solid #dddddd; + text-align: left; + padding: 8px; +} + +table.state { + display: flex; +} diff --git a/packages/geoview-core/public/templates/codedoc.js b/packages/geoview-core/public/templates/codedoc.js index 9dacae4e61f..c536d023c97 100644 --- a/packages/geoview-core/public/templates/codedoc.js +++ b/packages/geoview-core/public/templates/codedoc.js @@ -69,15 +69,14 @@ function createCollapsible() { let i; for (i = 0; i < coll.length; i++) { + const content = coll[i].nextElementSibling; + if (coll[i].classList.contains('active')) content.style.display = 'block'; + else content.style.display = 'none'; // eslint-disable-next-line func-names coll[i].addEventListener('click', function () { this.classList.toggle('active'); - const content = this.nextElementSibling; - if (content.style.display === 'block') { - content.style.display = 'none'; - } else { - content.style.display = 'block'; - } + if (this.classList.contains('active')) content.style.display = 'block'; + else content.style.display = 'none'; }); } } @@ -112,6 +111,7 @@ function wireLogs(api, mapId, logsDomId) { (payload) => { // Log the event addLog(logsDomId, payload.event); + // eslint-disable-next-line no-console console.log(payload); }, mapId diff --git a/packages/geoview-core/public/templates/layers/esri-dynamic.html b/packages/geoview-core/public/templates/layers/esri-dynamic.html index 86556ee8757..7930fc65216 100644 --- a/packages/geoview-core/public/templates/layers/esri-dynamic.html +++ b/packages/geoview-core/public/templates/layers/esri-dynamic.html @@ -66,9 +66,10 @@

ESRI Dynamic Layers

1. Many ESRI Dynamic Layers with legend settings in the config

-  
(undefined)
Top
+ +

     
1. Many ESRI Dynamic Layers with legend settings in the configGet Legend

     
-    
Click on feature on the map
+
Click on feature on the map
+ +
Comming soon!


@@ -507,9 +510,10 @@ 

1. Many ESRI Dynamic Layers with legend settings in the config

2. Date filtering using time zone changed and non ISO date format

-  
(undefined)
Top
+ +

     
2. Date filtering using time zone changed and non ISO date format

     
-    
Click on feature on the map
+
Click on feature on the map
+ +
Comming soon!


@@ -566,9 +572,10 @@ 

2. Date filtering using time zone changed and non ISO date format

3. Date filtering using ISO UTC dates

-  
(undefined)
Top
+ +

     
3. Date filtering using ISO UTC dates


     
-    
Click on feature on the map
+
Click on feature on the map
+ +
Comming soon!


@@ -630,16 +639,9 @@ 

3. Date filtering using ISO UTC dates

console.log(`api is ready for ${mapId}`); if (mapId === 'allMaps') { - //create snippets - createCodeSnippet(); - createConfigSnippet(); - createTableOfFilter('LYR1'); createTableOfFilter('LYR2'); createTableOfFilter('LYR3'); - cgpv.api.event.emit({ handlerName: 'LYR1/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); - cgpv.api.event.emit({ handlerName: 'LYR2/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); - cgpv.api.event.emit({ handlerName: 'LYR3/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); const field2 = cgpv.api.maps.LYR2.layer.geoviewLayers['historical-flood'].layerTemporalDimension['historical-flood/0'].field; const LYR2_FILTERS = [`${field2} >= date '01/01/2018 05:00:00' and ${field2} <= date '12/31/2019 19:00:00-05:00'`, @@ -702,103 +704,70 @@

3. Date filtering using ISO UTC dates

cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR1', 'ResultSetId1', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR1', 'ResultSetId1', resultSets, queryType); }, - 'LYR1/$FeatureInfoLayerSet$' + 'LYR1/FeatureInfoLayerSet' ); - const LegendsLayerSet1 = cgpv.api.getLegendsLayerSet('LYR1'); cgpv.api.event.on( cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, (payload) => { const { resultSets } = payload; displayLegend('LegendsId1', resultSets); }, - 'LYR1/$LegendsLayerSet$' + 'LYR1/LegendsLayerSet' ); + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); + // LYR2 =================================================================================================================== const featureInfoLayerSet2 = cgpv.api.getFeatureInfoLayerSet('LYR2'); cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR2', 'ResultSetId2', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR2', 'ResultSetId2', resultSets, queryType); }, - 'LYR2/$FeatureInfoLayerSet$' + 'LYR2/FeatureInfoLayerSet' ); - const LegendsLayerSet2 = cgpv.api.getLegendsLayerSet('LYR2'); cgpv.api.event.on( cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, (payload) => { const { resultSets } = payload; displayLegend('LegendsId2', resultSets); }, - 'LYR2/$LegendsLayerSet$' + 'LYR2/LegendsLayerSet' ); + listenToLegendLayerSetChanges('HLYR2-state', 'LYR2/LegendsLayerSet'); + // LYR3 =================================================================================================================== const featureInfoLayerSet3 = cgpv.api.getFeatureInfoLayerSet('LYR3'); cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR3', 'ResultSetId3', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR3', 'ResultSetId3', resultSets, queryType); }, - 'LYR3/$FeatureInfoLayerSet$' + 'LYR3/FeatureInfoLayerSet' ); - const LegendsLayerSet3 = cgpv.api.getLegendsLayerSet('LYR3'); cgpv.api.event.on( cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, (payload) => { const { resultSets } = payload; displayLegend('LegendsId3', resultSets); }, - 'LYR3/$LegendsLayerSet$' + 'LYR3/LegendsLayerSet' ); - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR1-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR1').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR1.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250) - - window.setInterval(() => { - const displayField2 = document.getElementById('HLYR2-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR2').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR2.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField2.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField2.textContent = '(undefined)'; - }, 250) - - window.setInterval(() => { - const displayField3 = document.getElementById('HLYR3-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR3').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR3.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField3.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)';; - } else displayField3.textContent = '(undefined)'; - }, 250) + listenToLegendLayerSetChanges('HLYR3-state', 'LYR3/LegendsLayerSet'); + //create snippets + createCodeSnippet(); + createConfigSnippet(); diff --git a/packages/geoview-core/public/templates/layers/esri-feature.html b/packages/geoview-core/public/templates/layers/esri-feature.html index 014f3bc1467..e1e2c0035fa 100644 --- a/packages/geoview-core/public/templates/layers/esri-feature.html +++ b/packages/geoview-core/public/templates/layers/esri-feature.html @@ -66,9 +66,10 @@

ESRI Feature Layers

1. Many Esri Feature Layers

-  
(undefined)
Top
+ +

     
1. Many Esri Feature Layers

     
-    
Click on feature on the map
+
Click on feature on the map
+ +

     

This map has a wms layer added from configuration.

@@ -151,9 +154,10 @@

1. Many Esri Feature Layers

2. Date filtering using time zone changed and non ISO date format

-  
(undefined)
Top
+ +

     
2. Date filtering using time zone changed and non ISO date format

     
-    
Click on feature on the map
+
Click on feature on the map
+ +

     

@@ -210,9 +216,10 @@ 

2. Date filtering using time zone changed and non ISO date format

3. Date filtering using ISO UTC dates

-  
(undefined)
Top
+ +

     
3. Date filtering using ISO UTC dates


     
-    
Click on feature on the map
+
Click on feature on the map
+ +

     

@@ -274,16 +283,9 @@ 

3. Date filtering using ISO UTC dates

console.log(`api is ready for ${mapId}`); if (mapId === 'allMaps') { - //create snippets - createCodeSnippet(); - createConfigSnippet(); - createTableOfFilter('LYR1'); createTableOfFilter('LYR2'); createTableOfFilter('LYR3'); - cgpv.api.event.emit({ handlerName: 'LYR1/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); - cgpv.api.event.emit({ handlerName: 'LYR2/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); - cgpv.api.event.emit({ handlerName: 'LYR3/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); const field2 = cgpv.api.maps.LYR2.layer.geoviewLayers['historical-flood'].layerTemporalDimension['historical-flood/0'].field; const LYR2_FILTERS = [`${field2} >= date '01/01/2018 05:00:00' and ${field2} <= date '12/31/2019 19:00:00-05:00'`, @@ -342,107 +344,86 @@

3. Date filtering using ISO UTC dates

}); // LYR1 =================================================================================================================== - const featureInfoLayerSet1 = cgpv.api.getFeatureInfoLayerSet('LYR1'); + const getAllFeatureInfo1 = document.getElementById('AllFeatureInfo1'); + getAllFeatureInfo1.addEventListener('click', function (e) { + cgpv.api.event.emit({ event: 'map/get_all_features', handlerName: 'LYR1' }); + }); + cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR1', 'ResultSetId1', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR1', 'ResultSetId1', resultSets, queryType); }, - 'LYR1/$FeatureInfoLayerSet$' + 'LYR1/FeatureInfoLayerSet' ); - const LegendsLayerSet1 = cgpv.api.getLegendsLayerSet('LYR1'); cgpv.api.event.on( cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, (payload) => { const { resultSets } = payload; displayLegend('LegendsId1', resultSets); }, - 'LYR1/$LegendsLayerSet$' + 'LYR1/LegendsLayerSet' ); + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); + // LYR2 =================================================================================================================== - const featureInfoLayerSet2 = cgpv.api.getFeatureInfoLayerSet('LYR2'); + const getAllFeatureInfo2 = document.getElementById('AllFeatureInfo2'); + getAllFeatureInfo2.addEventListener('click', function (e) { + cgpv.api.event.emit({ event: 'map/get_all_features', handlerName: 'LYR2' }); + }); + cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR2', 'ResultSetId2', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR2', 'ResultSetId2', resultSets, queryType); }, - 'LYR2/$FeatureInfoLayerSet$' + 'LYR2/FeatureInfoLayerSet' ); - const LegendsLayerSet2 = cgpv.api.getLegendsLayerSet('LYR2'); cgpv.api.event.on( cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, (payload) => { const { resultSets } = payload; displayLegend('LegendsId2', resultSets); }, - 'LYR2/$LegendsLayerSet$' + 'LYR2/LegendsLayerSet' ); + listenToLegendLayerSetChanges('HLYR2-state', 'LYR2/LegendsLayerSet'); + // LYR3 =================================================================================================================== - const featureInfoLayerSet3 = cgpv.api.getFeatureInfoLayerSet('LYR3'); + const getAllFeatureInfo3 = document.getElementById('AllFeatureInfo3'); + getAllFeatureInfo3.addEventListener('click', function (e) { + cgpv.api.event.emit({ event: 'map/get_all_features', handlerName: 'LYR3' }); + }); + cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR3', 'ResultSetId3', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR3', 'ResultSetId3', resultSets, queryType); }, - 'LYR3/$FeatureInfoLayerSet$' + 'LYR3/FeatureInfoLayerSet' ); - const LegendsLayerSet3 = cgpv.api.getLegendsLayerSet('LYR3'); cgpv.api.event.on( cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, (payload) => { const { resultSets } = payload; displayLegend('LegendsId3', resultSets); }, - 'LYR3/$LegendsLayerSet$' + 'LYR3/LegendsLayerSet' ); - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR1-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR1').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR1.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250) - - window.setInterval(() => { - const displayField2 = document.getElementById('HLYR2-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR2').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR2.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField2.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField2.textContent = '(undefined)'; - }, 250) - - window.setInterval(() => { - const displayField3 = document.getElementById('HLYR3-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR3').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR3.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField3.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField3.textContent = '(undefined)'; - }, 250) + listenToLegendLayerSetChanges('HLYR3-state', 'LYR3/LegendsLayerSet'); + //create snippets + createCodeSnippet(); + createConfigSnippet(); diff --git a/packages/geoview-core/public/templates/layers/geocore.html b/packages/geoview-core/public/templates/layers/geocore.html index b79b468e397..cccb295608b 100644 --- a/packages/geoview-core/public/templates/layers/geocore.html +++ b/packages/geoview-core/public/templates/layers/geocore.html @@ -64,9 +64,10 @@

Geocore Layers

1. Many GeoCore Layers

-  
(undefined)
Top
+ +

     
1. Many GeoCore Layers

     
-    
Click on feature on the map
+
Click on feature on the map

This map has a wms layer added from configuration.

@@ -167,13 +168,7 @@

1. Many GeoCore Layers

cgpv.init(function (mapId) { console.log(`api is ready for ${mapId}`); - if (mapId === 'allMaps') { - //create snippets - createCodeSnippet(); - createConfigSnippet(); - - createTableOfFilter('LYR1'); - cgpv.api.event.emit({ handlerName: 'LYR1/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); + if (mapId === 'allMaps') { createTableOfFilter('LYR1'); } }); @@ -182,10 +177,10 @@

1. Many GeoCore Layers

cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR1', 'ResultSetId1', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR1', 'ResultSetId1', resultSets, queryType); }, - 'LYR1/$FeatureInfoLayerSet$' + 'LYR1/FeatureInfoLayerSet' ); const LegendsLayerSet1 = cgpv.api.getLegendsLayerSet('LYR1'); @@ -195,22 +190,12 @@

1. Many GeoCore Layers

const { resultSets } = payload; displayLegend('LegendsId1', resultSets); }, - 'LYR1/$LegendsLayerSet$' + 'LYR1/LegendsLayerSet' ); - - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR1-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR1').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR1.layer.geoviewLayers[layerId.split('/')[0]].geoviewLayerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250) - + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); + //create snippets + createCodeSnippet(); + createConfigSnippet(); diff --git a/packages/geoview-core/public/templates/layers/geojson.html b/packages/geoview-core/public/templates/layers/geojson.html index e2dae44c41e..b4b9f50848b 100644 --- a/packages/geoview-core/public/templates/layers/geojson.html +++ b/packages/geoview-core/public/templates/layers/geojson.html @@ -64,9 +64,10 @@

GeoJSON Layers

1. Many GeoJSON Layers

-  
(undefined)
Top
+ +

     
1. Many GeoJSON Layers -
Click on feature on the map
+
Click on feature on the map
+ +

     

This map has a wms layer added from configuration.

@@ -157,12 +160,7 @@

1. Many GeoJSON Layers

console.log(`api is ready for ${mapId}`); if (mapId === 'allMaps') { - //create snippets - createCodeSnippet(); - createConfigSnippet(); - createTableOfFilter('LYR1'); - cgpv.api.event.emit({ handlerName: 'LYR1/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); } }); @@ -226,14 +224,18 @@

1. Many GeoJSON Layers

}); // LYR1 =================================================================================================================== - const featureInfoLayerSet = cgpv.api.getFeatureInfoLayerSet('LYR1'); + const getAllFeatureInfo1 = document.getElementById('AllFeatureInfo1'); + getAllFeatureInfo1.addEventListener('click', function (e) { + cgpv.api.event.emit({ event: 'map/get_all_features', handlerName: 'LYR1' }); + }); + cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR1', 'ResultSetId1', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR1', 'ResultSetId1', resultSets, queryType); }, - 'LYR1/$FeatureInfoLayerSet$' + 'LYR1/FeatureInfoLayerSet' ); const LegendLayerSet = cgpv.api.getLegendsLayerSet('LYR1'); @@ -243,22 +245,13 @@

1. Many GeoJSON Layers

const { resultSets } = payload; displayLegend('LegendsId1', resultSets); }, - 'LYR1/$LegendsLayerSet$' + 'LYR1/LegendsLayerSet' ); - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR1-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR1').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR1.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250) - + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); + //create snippets + createCodeSnippet(); + createConfigSnippet(); diff --git a/packages/geoview-core/public/templates/layers/geopackage.html b/packages/geoview-core/public/templates/layers/geopackage.html index 9ee5986a427..d8565942c98 100644 --- a/packages/geoview-core/public/templates/layers/geopackage.html +++ b/packages/geoview-core/public/templates/layers/geopackage.html @@ -69,9 +69,10 @@

Geopackage Layers

1. GeoPackage Layers

-  
(undefined)
Top
+ +

     
1. GeoPackage Layers

     
-    
Click on feature on the map
+
Click on feature on the map
+ +

     

2. Multiple GeoPackage Layers - one with multiple layers

-  
(undefined)
Top
+ +

     
2. Multiple GeoPackage Layers - one with multiple layers console.log(`api is ready for ${mapId}`); if (mapId === 'allMaps') { - //create snippets - createCodeSnippet(); - createConfigSnippet(); - createTableOfFilter('LYR1'); - cgpv.api.event.emit({ handlerName: 'LYR1/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); } }); // LYR1 =================================================================================================================== - const featureInfoLayerSet1 = cgpv.api.getFeatureInfoLayerSet('LYR1'); + const getAllFeatureInfo1 = document.getElementById('AllFeatureInfo1'); + getAllFeatureInfo1.addEventListener('click', function (e) { + cgpv.api.event.emit({ event: 'map/get_all_features', handlerName: 'LYR1' }); + }); + cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR1', 'ResultSetId1', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR1', 'ResultSetId1', resultSets, queryType); }, - 'LYR1/$FeatureInfoLayerSet$' + 'LYR1/FeatureInfoLayerSet' ); const LegendsLayerSet1 = cgpv.api.getLegendsLayerSet('LYR1'); @@ -227,35 +230,15 @@

2. Multiple GeoPackage Layers - one with multiple layers

const { resultSets } = payload; displayLegend('LegendsId1', resultSets); }, - 'LYR1/$LegendsLayerSet$' + 'LYR1/LegendsLayerSet' ); - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR1-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR1').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR1.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250) - - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR2-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR2').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR2.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250) + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); + listenToLegendLayerSetChanges('HLYR2-state', 'LYR2/LegendsLayerSet'); + //create snippets + createCodeSnippet(); + createConfigSnippet(); diff --git a/packages/geoview-core/public/templates/layers/image-static.html b/packages/geoview-core/public/templates/layers/image-static.html index 4fe4fa7c884..29a5163ad9f 100644 --- a/packages/geoview-core/public/templates/layers/image-static.html +++ b/packages/geoview-core/public/templates/layers/image-static.html @@ -64,9 +64,10 @@

Static Image Layers

1. Static Image Layers

-  
(undefined)
Top
+ +

     
1. Static Image Layers // initialize cgpv and api events, a callback is optional, used if calling api's after the rendering is ready cgpv.init(function (mapId) { console.log(`api is ready for ${mapId}`); - - if (mapId === 'allMaps') { - //create snippets - createCodeSnippet(); - createConfigSnippet(); - - cgpv.api.event.emit({ handlerName: 'LYR1/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); - } }); // LYR1 =================================================================================================================== @@ -154,22 +147,13 @@

1. Static Image Layers

const { resultSets } = payload; displayLegend('LegendsId1', resultSets); }, - 'LYR1/$LegendsLayerSet$' + 'LYR1/LegendsLayerSet' ); - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR1-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR1').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR1.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250) - + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); + //create snippets + createCodeSnippet(); + createConfigSnippet(); diff --git a/packages/geoview-core/public/templates/layers/layerlib.js b/packages/geoview-core/public/templates/layers/layerlib.js index 4f08935fda2..51bfa6916e8 100644 --- a/packages/geoview-core/public/templates/layers/layerlib.js +++ b/packages/geoview-core/public/templates/layers/layerlib.js @@ -1,5 +1,25 @@ /* eslint-disable no-undef */ /* eslint-disable @typescript-eslint/no-unused-vars */ +// ========================================================================================================================== +function listenToLegendLayerSetChanges(elementId, handlerName) { + cgpv.api.event.on( + cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, + (payload) => { + const outputHeader = + ''; + const displayField = document.getElementById(elementId); + const { resultSets } = payload; + const output = Object.keys(resultSets).reduce((outputValue, layerPath) => { + const layerName = resultSets[layerPath]?.layerName?.en || resultSets[layerPath]?.layerName?.fr || ''; + const { layerPhase, layerStatus } = resultSets[layerPath]; + return `${outputValue}`; + }, outputHeader); + displayField.innerHTML = output && output !== outputHeader ? `${output}
NamePhaseStatus
${layerName}${layerPhase}${layerStatus}
` : ''; + }, + handlerName + ); +} + // ========================================================================================================================== const addBoundsPolygon = (mapId, bbox) => { const newBbox = cgpv.api.maps[mapId].transformAndDensifyExtent(bbox, `EPSG:${cgpv.api.maps[mapId].currentProjection}`, `EPSG:4326`); @@ -17,17 +37,18 @@ const addBoundsPolygon = (mapId, bbox) => { }); }; -const createInfoTable = (mapId, resultSetsId, resultSets) => { - const infoTable = document.getElementById(resultSetsId); +// ========================================================================================================================== +const createInfoTable = (mapId, resultSetsId, resultSets, queryType) => { + const infoTable = document.getElementById(`${resultSetsId}-${queryType}`); infoTable.textContent = ''; - const oldContent = document.getElementById(`layer${mapId.slice(-1)}-info`); + const oldContent = document.getElementById(`layer${mapId.slice(-1)}-${queryType}-info`); if (oldContent) oldContent.remove(); const content = document.createElement('div'); - content.id = `layer${mapId.slice(-1)}-info`; + content.id = `layer${mapId.slice(-1)}-${queryType}-info`; infoTable.appendChild(content); Object.keys(resultSets).forEach((layerPath) => { const activeResultSet = resultSets[layerPath]; - const layerData = activeResultSet.data; + const layerData = activeResultSet.data[queryType]; // Header of the layer const infoH1 = document.createElement('h1'); @@ -173,6 +194,7 @@ const createTableOfFilter = (mapId) => { tableElement.style.width = '100%'; tableElement.border = '1px solid black'; mapButtonsDiv.appendChild(tableElement); + if (!cgpv.api.maps?.[mapId]?.layer?.geoviewLayers) return; Object.keys(cgpv.api.maps[mapId].layer.geoviewLayers).forEach((geoviewLayerId) => { const geoviewLayer = cgpv.api.maps[mapId].layer.geoviewLayers[geoviewLayerId]; Object.keys(cgpv.api.maps[mapId].layer.registeredLayers).forEach((layerPath) => { @@ -439,32 +461,28 @@ function displayLegend(layerSetId, resultSets) { let createHeader = true; Object.keys(resultSets).forEach((layerPath) => { const activeResultSet = resultSets[layerPath]; - if (activeResultSet.layerStatus !== 'processed' || !activeResultSet?.data?.legend) { - if (createHeader) { - createHeader = false; - const tableRow1 = document.createElement('tr'); - table.appendChild(tableRow1); - addHeader('Layer Path', tableRow1); - addHeader('Status', tableRow1); - } + if (createHeader) { + createHeader = false; + const tableRow1 = document.createElement('tr'); + table.appendChild(tableRow1); + addHeader('Layer Path', tableRow1); + addHeader('Status/Label', tableRow1); + addHeader('Symbology', tableRow1); + } + if (!activeResultSet?.data?.legend) { const tableRow = document.createElement('tr'); addData(layerPath, tableRow); - let legendValue = activeResultSet.data === undefined && activeResultSet.layerStatus === 'processed' ? '(waiting for legend)' : ''; - legendValue = activeResultSet.data === null && activeResultSet.layerStatus === 'processed' ? '(legend fetch error)' : legendValue; - legendValue = - activeResultSet.data && !activeResultSet.data.legend && activeResultSet.layerStatus === 'processed' ? '(no legend)' : legendValue; - addData(`${activeResultSet.layerStatus} ${legendValue}`, tableRow); + let legendValue = ''; + if (activeResultSet.data === undefined) legendValue = '(waiting for legend)'; + if (activeResultSet.data === null) legendValue = '(legend fetch error)'; + if (activeResultSet.data && !activeResultSet.data.legend && activeResultSet.layerStatus === 'loaded') legendValue = '(no legend)'; + addData(activeResultSet.layerStatus, tableRow); + addData(legendValue, tableRow); table.appendChild(tableRow); } else if (activeResultSet.data?.type === 'ogcWms' || activeResultSet.data?.type === 'imageStatic') { - if (createHeader) { - createHeader = false; - const tableRow1 = document.createElement('tr'); - table.appendChild(tableRow1); - addHeader('Layer Path', tableRow1); - addHeader('Symbology', tableRow1); - } const tableRow = document.createElement('tr'); addData(activeResultSet.data.layerPath, tableRow); + addData(activeResultSet.layerStatus, tableRow); addData(activeResultSet.data.legend, tableRow); table.appendChild(tableRow); } else { @@ -475,14 +493,6 @@ function displayLegend(layerSetId, resultSets) { addData(canvas, tableRow); table.appendChild(tableRow); }; - if (createHeader) { - createHeader = false; - const tableRow1 = document.createElement('tr'); - table.appendChild(tableRow1); - addHeader('Layer Path', tableRow1); - addHeader('Label', tableRow1); - addHeader('Symbology', tableRow1); - } if (activeResultSet.data?.legend) { Object.keys(activeResultSet.data.legend).forEach((geometryKey) => { if (geometryKey) { diff --git a/packages/geoview-core/public/templates/layers/ogc-feature.html b/packages/geoview-core/public/templates/layers/ogc-feature.html index c9d7d4c5a4f..710bc951768 100644 --- a/packages/geoview-core/public/templates/layers/ogc-feature.html +++ b/packages/geoview-core/public/templates/layers/ogc-feature.html @@ -64,9 +64,10 @@

OGC Feature API Layers

1. OGC Feature API Layers

-  
(undefined)
Top
+ +

     
1. OGC Feature API Layers

     
-    
Click on feature on the map
+
Click on feature on the map
+ +

     

This map has a wms layer added from configuration.

@@ -132,49 +135,37 @@

1. OGC Feature API Layers

console.log(`api is ready for ${mapId}`); if (mapId === 'allMaps') { - //create snippets - createCodeSnippet(); - createConfigSnippet(); - createTableOfFilter('LYR1'); - cgpv.api.event.emit({ handlerName: 'LYR1/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); } }); // LYR1 =================================================================================================================== - const featureInfoLayerSet1 = cgpv.api.getFeatureInfoLayerSet('LYR1'); + const getAllFeatureInfo1 = document.getElementById('AllFeatureInfo1'); + getAllFeatureInfo1.addEventListener('click', function (e) { + cgpv.api.event.emit({ event: 'map/get_all_features', handlerName: 'LYR1' }); + }); + cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR1', 'ResultSetId1', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR1', 'ResultSetId1', resultSets, queryType); }, - 'LYR1/$FeatureInfoLayerSet$' + 'LYR1/FeatureInfoLayerSet' ); - const LegendsLayerSet1 = cgpv.api.getLegendsLayerSet('LYR1'); cgpv.api.event.on( cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, (payload) => { const { resultSets } = payload; displayLegend('LegendsId1', resultSets); }, - 'LYR1/$LegendsLayerSet$' + 'LYR1/LegendsLayerSet' ); - - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR1-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR1').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR1.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250) - + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); + //create snippets + createCodeSnippet(); + createConfigSnippet(); diff --git a/packages/geoview-core/public/templates/layers/vector-tiles.html b/packages/geoview-core/public/templates/layers/vector-tiles.html index 07cb767f920..60b7c9bb885 100644 --- a/packages/geoview-core/public/templates/layers/vector-tiles.html +++ b/packages/geoview-core/public/templates/layers/vector-tiles.html @@ -52,9 +52,10 @@

Vector Tiles Layers

1. Vector Tiles Layers (3978)

-  
(undefined)
Top
+ +

     
1. Vector Tiles Layers (3978)

2. Vector Tiles Layers (3857)

-  
(undefined)
Top
+ +

     
2. Vector Tiles Layers (3857)

3. Vector Tiles olms library no GeoView

-  
(undefined)
Top
+ +

     

This map has a Vector Tiles layer added from olms library automatically. No GeoView map involves and vector tile layers sources projection 3857 by default. This needs investigation


@@ -182,10 +185,6 @@

3. Vector Tiles olms library no GeoView

console.log(`api is ready for ${mapId}`); if (mapId === 'allMaps') { - //create snippets - createCodeSnippet(); - createConfigSnippet(); - setTimeout(() => cgpv.api.maps['LYR1'].layer.geoviewLayers['vectorTilesLYR1'].addVectorTileLayer(), 2000); setStyle = (proj) => { @@ -194,47 +193,12 @@

3. Vector Tiles olms library no GeoView

} }); - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR1-state'); - const geoviewLayers = cgpv.api.maps?.LYR1?.layer?.registeredLayers; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = geoviewLayers[layerId].layerName?.en ? geoviewLayers[layerId].layerName?.en : layerId; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250) - - window.setInterval(() => { - const displayField2 = document.getElementById('HLYR2-state'); - const geoviewLayers = cgpv.api.maps?.LYR2?.layer?.registeredLayers; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = geoviewLayers[layerId].layerName?.en ? geoviewLayers[layerId].layerName?.en : layerId; - const {layerPhase} = geoviewLayers[layerId]; - const {layerStatus} = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField2.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField2.textContent = '(undefined)'; - }, 250) - - window.setInterval(() => { - const displayField3 = document.getElementById('HLYR3-state'); - const geoviewLayers = cgpv.api.maps?.LYR3?.layer?.registeredLayers; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = geoviewLayers[layerId].layerName?.en ? geoviewLayers[layerId].layerName?.en : layerId; - const {layerPhase} = geoviewLayers[layerId]; - const {layerStatus} = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField3.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField3.textContent = '(undefined)'; - }, 250) - + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); + listenToLegendLayerSetChanges('HLYR2-state', 'LYR2/LegendsLayerSet'); + listenToLegendLayerSetChanges('HLYR3-state', 'LYR3/LegendsLayerSet'); + //create snippets + createCodeSnippet(); + createConfigSnippet(); diff --git a/packages/geoview-core/public/templates/layers/wfs.html b/packages/geoview-core/public/templates/layers/wfs.html index 9bcc2f0cd3d..8c661517ffa 100644 --- a/packages/geoview-core/public/templates/layers/wfs.html +++ b/packages/geoview-core/public/templates/layers/wfs.html @@ -13,20 +13,6 @@ - @@ -64,9 +50,10 @@

WFS Layers

1. WFS Layers

-  
(undefined)
Top
+ +

     
1. WFS Layers

     
-    
Click on feature on the map
+
Click on feature on the map
+ +

     

This map has a wfs layer added from configuration.

@@ -143,9 +132,10 @@

1. WFS Layers

2. WFS Layers using bbox strategy

-  
(undefined)
Top
+ +

     
2. WFS Layers using bbox strategy

     
-    
Click on feature on the map
+
Click on feature on the map
+ +

     

This map has a wfs layer added from configuration.

@@ -210,87 +202,69 @@

2. WFS Layers using bbox strategy

// initialize cgpv and api events, a callback is optional, used if calling api's after the rendering is ready cgpv.init(function (mapId) { console.log(`api is ready for ${mapId}`); - if (mapId === 'LYR1') { - //create snippets - createCodeSnippet(); - createConfigSnippet(); - createTableOfFilter('LYR1'); + } + + if (mapId === 'LYR2') { createTableOfFilter('LYR2'); - cgpv.api.event.emit({ handlerName: 'LYR1/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); - cgpv.api.event.emit({ handlerName: 'LYR2/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); } }); - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR1-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR1').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR1.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250) - - window.setInterval(() => { - const displayField2 = document.getElementById('HLYR2-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR2').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = cgpv.api.maps.LYR2.layer.registeredLayers[layerId].layerName.en; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField2.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField2.textContent = '(undefined)'; - }, 250) - // LYR1 =================================================================================================================== - const featureInfoLayerSet1 = cgpv.api.getFeatureInfoLayerSet('LYR1'); + const getAllFeatureInfo1 = document.getElementById('AllFeatureInfo1'); + getAllFeatureInfo1.addEventListener('click', function (e) { + cgpv.api.event.emit({ event: 'map/get_all_features', handlerName: 'LYR1' }); + }); + cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR1', 'ResultSetId1', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR1', 'ResultSetId1', resultSets, queryType); }, - 'LYR1/$FeatureInfoLayerSet$' + 'LYR1/FeatureInfoLayerSet' ); - const LegendsLayerSet1 = cgpv.api.getLegendsLayerSet('LYR1'); cgpv.api.event.on( cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, (payload) => { const { resultSets } = payload; displayLegend('LegendsId1', resultSets); }, - 'LYR1/$LegendsLayerSet$' + 'LYR1/LegendsLayerSet' ); + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); + // LYR2 =================================================================================================================== - const featureInfoLayerSet2 = cgpv.api.getFeatureInfoLayerSet('LYR2'); + const getAllFeatureInfo2 = document.getElementById('AllFeatureInfo2'); + getAllFeatureInfo2.addEventListener('click', function (e) { + cgpv.api.event.emit({ event: 'map/get_all_features', handlerName: 'LYR2' }); + }); + cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR2', 'ResultSetId2', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR2', 'ResultSetId2', resultSets, queryType); }, - 'LYR2/$FeatureInfoLayerSet$' + 'LYR2/FeatureInfoLayerSet' ); - const LegendsLayerSet2 = cgpv.api.getLegendsLayerSet('LYR2'); cgpv.api.event.on( cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, (payload) => { const { resultSets } = payload; displayLegend('LegendsId2', resultSets); }, - 'LYR2/$LegendsLayerSet$' + 'LYR2/LegendsLayerSet' ); + listenToLegendLayerSetChanges('HLYR2-state', 'LYR2/LegendsLayerSet'); + //create snippets + createCodeSnippet(); + createConfigSnippet(); diff --git a/packages/geoview-core/public/templates/layers/wms.html b/packages/geoview-core/public/templates/layers/wms.html index 6f8d731ddcf..fa66f1eb289 100644 --- a/packages/geoview-core/public/templates/layers/wms.html +++ b/packages/geoview-core/public/templates/layers/wms.html @@ -75,10 +75,10 @@

WMS Layers

1. Many WMS Layers

-   -
(undefined)
Top
+ +

     
     
(undefined)

     
-    
Click on feature on the map
+
Click on feature on the map

This map has a wms layer added from configuration.

@@ -189,10 +189,10 @@
(undefined)

2. All Styles of a WMS Layer

-   -
(undefined)
Top
+ +

     
(undefined)

     
-    
Click on feature on the map
+
Click on feature on the map

This map has a wms layer added from configuration.

@@ -375,10 +375,10 @@
(undefined)

3. All Styles of a WMS Layer

-   -
(undefined)
Top
+ +

     
(undefined)

     
-    
Click on feature on the map
+
Click on feature on the map

This map has a wms layer added from configuration.

@@ -434,10 +434,10 @@
(undefined)

4. Automatic group creation from metadata information

-   -
(undefined)
Top
+ +

     
(undefined) console.log(`api is ready for ${mapId}`); if (mapId === 'allMaps') { - //create snippets - createCodeSnippet(); - createConfigSnippet(); - createTableOfFilter('LYR1'); createTableOfFilter('LYR2'); createTableOfFilter('LYR4'); @@ -526,106 +522,6 @@
(undefined)
} }, 1000); - //LYR1 =================================================================================================================== - const featureInfoLayerSet1 = cgpv.api.getFeatureInfoLayerSet('LYR1'); - cgpv.api.event.on( - cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, - (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR1', 'ResultSetId1', resultSets); - }, - 'LYR1/$FeatureInfoLayerSet$' - ); - - const LegendsLayerSet1 = cgpv.api.getLegendsLayerSet('LYR1'); - cgpv.api.event.on( - cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, - (payload) => { - const { resultSets } = payload; - displayLegend('LegendsId1', resultSets); - }, - 'LYR1/$LegendsLayerSet$' - ); - // The GET_LEGENDS.TRIGGER event must be triggered after the GET_LEGENDS.LEGENDS_LAYERSET_UPDATED listener is created - cgpv.api.event.emit({ handlerName: 'LYR1/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); - - // ======================================================================================================================== - // Test a refresh WMS from projection change - var testRefreshBtn = document.getElementsByClassName('test-refresh-WMS-btn')[0]; - testRefreshBtn.addEventListener('click', function (e) { - cgpv.api.event.emit( - cgpv.types.mapViewProjectionPayload(cgpv.api.eventNames.MAP.EVENT_MAP_VIEW_PROJECTION_CHANGE, 'LYR1', 3978) - ); - }); - - // LYR2 =================================================================================================================== - const featureInfoLayerSet2 = cgpv.api.getFeatureInfoLayerSet('LYR2'); - cgpv.api.event.on( - cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, - (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR2', 'ResultSetId2', resultSets); - }, - 'LYR2/$FeatureInfoLayerSet$' - ); - - const LegendsLayerSet2 = cgpv.api.getLegendsLayerSet('LYR2'); - cgpv.api.event.on( - cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, - (payload) => { - const { resultSets } = payload; - displayLegend('LegendsId2', resultSets); - }, - 'LYR2/$LegendsLayerSet$' - ); - // The GET_LEGENDS.TRIGGER event must be triggered after the GET_LEGENDS.LEGENDS_LAYERSET_UPDATED listener is created - cgpv.api.event.emit({ handlerName: 'LYR2/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); - - // LYR3 =================================================================================================================== - const featureInfoLayerSet3 = cgpv.api.getFeatureInfoLayerSet('LYR3'); - cgpv.api.event.on( - cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, - (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR3', 'ResultSetId3', resultSets); - }, - 'LYR3/$FeatureInfoLayerSet$' - ); - - const LegendsLayerSet3 = cgpv.api.getLegendsLayerSet('LYR3'); - cgpv.api.event.on( - cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, - (payload) => { - const { resultSets } = payload; - displayLegend('LegendsId3', resultSets); - }, - 'LYR3/$LegendsLayerSet$' - ); - // The GET_LEGENDS.TRIGGER event must be triggered after the GET_LEGENDS.LEGENDS_LAYERSET_UPDATED listener is created - cgpv.api.event.emit({ handlerName: 'LYR3/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); - - //LYR4 =================================================================================================================== - const LegendsLayerSet4 = cgpv.api.getLegendsLayerSet('LYR4', 'LegendsId4'); - cgpv.api.event.on( - cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, - (payload) => { - const { resultSets } = payload; - displayLegend('LegendsId4', resultSets); - }, - 'LYR4/$LegendsLayerSet$' - ); - // The GET_LEGENDS.TRIGGER event must be triggered after the GET_LEGENDS.LEGENDS_LAYERSET_UPDATED listener is created - cgpv.api.event.emit({ handlerName: 'LYR4/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); - - // ======================================================================================================================== - // Test a refresh WMS from projection change - var testRefreshBtn = document.getElementsByClassName('test-refresh-WMS-btn')[0]; - testRefreshBtn.addEventListener('click', function (e) { - cgpv.api.event.emit( - cgpv.types.mapViewProjectionPayload(cgpv.api.eventNames.MAP.EVENT_MAP_VIEW_PROJECTION_CHANGE, 'LYR1', 3978) - ); - }); - // ======================================================================================================================== // Cycle through the temporal data let i = 0; @@ -659,73 +555,108 @@
(undefined)
} }); + //LYR1 =================================================================================================================== + const featureInfoLayerSet1 = cgpv.api.getFeatureInfoLayerSet('LYR1'); + cgpv.api.event.on( + cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, + (payload) => { + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR1', 'ResultSetId1', resultSets, queryType); + }, + 'LYR1/FeatureInfoLayerSet' + ); + + const LegendsLayerSet1 = cgpv.api.getLegendsLayerSet('LYR1'); + cgpv.api.event.on( + cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, + (payload) => { + const { resultSets } = payload; + displayLegend('LegendsId1', resultSets); + }, + 'LYR1/LegendsLayerSet' + ); + // ======================================================================================================================== - // Display layer state - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR1-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR1').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - const numberOfErrors = cgpv.api.maps?.LYR1?.layer?.geoviewLayers[layerId.split('/')[0]].countErrorStatus(); - let errorIndicator = ''; - if (numberOfErrors) errorIndicator = numberOfErrors === 1 ? ' (1 error)' : ` (${numberOfErrors} errors)`; - return `${outputValue}${ - layerId.split('/')[layerId.split('/').length - 1] - } - status: ${layerStatus}, phase: ${layerPhase}${errorIndicator}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250); + // Test a refresh WMS from projection change + var testRefreshBtn = document.getElementsByClassName('test-refresh-WMS-btn')[0]; + testRefreshBtn.addEventListener('click', function (e) { + cgpv.api.event.emit( + cgpv.types.mapViewProjectionPayload(cgpv.api.eventNames.MAP.EVENT_MAP_VIEW_PROJECTION_CHANGE, 'LYR1', 3978) + ); + }); - window.setInterval(() => { - const displayField2 = document.getElementById('HLYR2-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR2').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - const numberOfErrors = cgpv.api.maps?.LYR2?.layer?.geoviewLayers[layerId.split('/')[0]].countErrorStatus(); - let errorIndicator = ''; - if (numberOfErrors) errorIndicator = numberOfErrors === 1 ? ' (1 error)' : ` (${numberOfErrors} errors)`; - return `${outputValue}${ - layerId.split('/')[layerId.split('/').length - 1] - } - status: ${layerStatus}, phase: ${layerPhase}${errorIndicator}, `; - }, '('); - displayField2.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField2.textContent = '(undefined)'; - }, 250); + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); - window.setInterval(() => { - const displayField3 = document.getElementById('HLYR3-state'); - const geoviewLayers = cgpv.api.getFeatureInfoLayerSet('LYR3').resultSets; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - const numberOfErrors = cgpv.api.maps?.LYR3?.layer?.geoviewLayers[layerId.split('/')[0]].countErrorStatus(); - let errorIndicator = ''; - if (numberOfErrors) errorIndicator = numberOfErrors === 1 ? ' (1 error)' : ` (${numberOfErrors} errors)`; - return `${outputValue}${ - layerId.split('/')[layerId.split('/').length - 1] - } - status: ${layerStatus}, phase: ${layerPhase}${errorIndicator}, `; - }, '('); - displayField3.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField3.textContent = '(undefined)'; - }, 250); + // LYR2 =================================================================================================================== + const featureInfoLayerSet2 = cgpv.api.getFeatureInfoLayerSet('LYR2'); + cgpv.api.event.on( + cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, + (payload) => { + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR2', 'ResultSetId2', resultSets, queryType); + }, + 'LYR2/FeatureInfoLayerSet' + ); + + const LegendsLayerSet2 = cgpv.api.getLegendsLayerSet('LYR2'); + cgpv.api.event.on( + cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, + (payload) => { + const { resultSets } = payload; + displayLegend('LegendsId2', resultSets); + }, + 'LYR2/LegendsLayerSet' + ); - window.setInterval(() => { - const displayField4 = document.getElementById('HLYR4-state'); - const geoviewLayers = cgpv.api.maps?.LYR4?.layer?.geoviewLayers; - if (geoviewLayers) { - const output = Object.keys(cgpv.api.maps?.LYR4?.layer?.geoviewLayers).reduce((outputValue, layerId) => { - const stateValue = cgpv.api.maps?.LYR4?.layer?.geoviewLayers[layerId].layerPhase; - const numberOfErrors = cgpv.api.maps?.LYR4?.layer?.geoviewLayers[layerId].countErrorStatus(); - let errorIndicator = ''; - if (numberOfErrors) errorIndicator = numberOfErrors === 1 ? ' (1 error)' : ` (${numberOfErrors} errors)`; - return `${outputValue}${layerId}: ${stateValue}${errorIndicator}, `; - }, '('); - displayField4.textContent = output ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField4.textContent = '(undefined)'; - }, 250); + listenToLegendLayerSetChanges('HLYR2-state', 'LYR2/LegendsLayerSet'); + + // LYR3 =================================================================================================================== + const featureInfoLayerSet3 = cgpv.api.getFeatureInfoLayerSet('LYR3'); + cgpv.api.event.on( + cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, + (payload) => { + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR3', 'ResultSetId3', resultSets, queryType); + }, + 'LYR3/FeatureInfoLayerSet' + ); + + const LegendsLayerSet3 = cgpv.api.getLegendsLayerSet('LYR3'); + cgpv.api.event.on( + cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, + (payload) => { + const { resultSets } = payload; + displayLegend('LegendsId3', resultSets); + }, + 'LYR3/LegendsLayerSet' + ); + + listenToLegendLayerSetChanges('HLYR3-state', 'LYR3/LegendsLayerSet'); + + //LYR4 =================================================================================================================== + const LegendsLayerSet4 = cgpv.api.getLegendsLayerSet('LYR4', 'LegendsId4'); + cgpv.api.event.on( + cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, + (payload) => { + const { resultSets } = payload; + displayLegend('LegendsId4', resultSets); + }, + 'LYR4/LegendsLayerSet' + ); + + listenToLegendLayerSetChanges('HLYR4-state', 'LYR4/LegendsLayerSet'); + + // ======================================================================================================================== + // Test a refresh WMS from projection change + var testRefreshBtn = document.getElementsByClassName('test-refresh-WMS-btn')[0]; + testRefreshBtn.addEventListener('click', function (e) { + cgpv.api.event.emit( + cgpv.types.mapViewProjectionPayload(cgpv.api.eventNames.MAP.EVENT_MAP_VIEW_PROJECTION_CHANGE, 'LYR1', 3978) + ); + }); + //create snippets + createCodeSnippet(); + createConfigSnippet(); diff --git a/packages/geoview-core/public/templates/layers/xyz.html b/packages/geoview-core/public/templates/layers/xyz.html index 41967bbe61e..158e00dc03c 100644 --- a/packages/geoview-core/public/templates/layers/xyz.html +++ b/packages/geoview-core/public/templates/layers/xyz.html @@ -50,9 +50,10 @@

XYZ Layers

1. XYZ Tiles Layers

-  
(undefined)
Top
+ +

     
1. XYZ Tiles Layers // initialize cgpv and api events, a callback is optional, used if calling api's after the rendering is ready cgpv.init(function (mapId) { console.log(`api is ready for ${mapId}`); - - if (mapId === 'allMaps') { - //create snippets - createCodeSnippet(); - createConfigSnippet(); - - } }); - window.setInterval(() => { - const displayField1 = document.getElementById('HLYR1-state'); - const geoviewLayers = cgpv.api.maps?.LYR1?.layer?.registeredLayers; - if (geoviewLayers) { - const output = Object.keys(geoviewLayers).reduce((outputValue, layerId) => { - const layerName = geoviewLayers[layerId].layerName?.en ? geoviewLayers[layerId].layerName?.en : layerId; - const { layerPhase, layerStatus } = geoviewLayers[layerId]; - return `${outputValue}${layerName} - status: ${layerStatus}, phase: ${layerPhase}, `; - }, '('); - displayField1.textContent = output && output !== '(' ? `${output.slice(0, -2)})` : '(undefined)'; - } else displayField1.textContent = '(undefined)'; - }, 250) - + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); + //create snippets + createCodeSnippet(); + createConfigSnippet(); diff --git a/packages/geoview-core/public/templates/pygeoapi-processes.html b/packages/geoview-core/public/templates/pygeoapi-processes.html index ac8b7e2a08f..2624ea2c420 100644 --- a/packages/geoview-core/public/templates/pygeoapi-processes.html +++ b/packages/geoview-core/public/templates/pygeoapi-processes.html @@ -515,7 +515,7 @@

GeoJSON Layer

const { layerSetId, resultSets } = payload; createInfoTable('LYR5', 'geoJsonResultSetId', resultSets); }, - 'LYR5/$FeatureInfoLayerSet$' + 'LYR5/FeatureInfoLayerSet' ); const LegendsGeoJsonLayerSet = cgpv.api.getLegendsLayerSet('LYR5'); @@ -525,7 +525,7 @@

GeoJSON Layer

const { resultSets } = payload; displayLegend('geojsonLegendsId', resultSets); }, - 'LYR5/$LegendsLayerSet$' + 'LYR5/LegendsLayerSet' ); // ========================================================================================================================== @@ -657,7 +657,6 @@

GeoJSON Layer

createConfigSnippet(); createTableOfFilter('LYR5'); - cgpv.api.event.emit({ handlerName: 'LYR5/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); }); // GeoMetButton============================================================================================================ diff --git a/packages/geoview-core/public/templates/raw-feature-info-1.html b/packages/geoview-core/public/templates/raw-feature-info-1.html index 21fe6a0d573..26fc380f36e 100644 --- a/packages/geoview-core/public/templates/raw-feature-info-1.html +++ b/packages/geoview-core/public/templates/raw-feature-info-1.html @@ -284,7 +284,7 @@

1. Basic Map

Top // root.render(detailsResult); // }, - // 'LYR2/$FeatureInfoLayerSet$' + // 'LYR2/FeatureInfoLayerSet' // ); //create snippets diff --git a/packages/geoview-core/public/templates/test.html b/packages/geoview-core/public/templates/test.html index 50ed804d148..43e32da7e83 100644 --- a/packages/geoview-core/public/templates/test.html +++ b/packages/geoview-core/public/templates/test.html @@ -59,7 +59,8 @@

WMS Layers

1. Many WMS Layers

Top
-
+ +

     
1. Many WMS Layers

     
-    
Click on feature on the map
+
Click on feature on the map

This map has a wms layer added from configuration.

@@ -186,10 +187,10 @@

1. Many WMS Layers

cgpv.api.event.on( cgpv.api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, (payload) => { - const { layerSetId, resultSets } = payload; - createInfoTable('LYR1', 'ResultSetId1', resultSets); + const { layerSetId, resultSets, queryType } = payload; + createInfoTable('LYR1', 'ResultSetId1', resultSets, queryType); }, - 'LYR1/$FeatureInfoLayerSet$' + 'LYR1/FeatureInfoLayerSet' ); // ======================================================================================================================== @@ -217,52 +218,7 @@

1. Many WMS Layers

} }); - console.log('Begin monitoring'); - const LegendsLayerSet1 = cgpv.api.getLegendsLayerSet('LYR1'); - cgpv.api.event.on( - cgpv.api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, - (payload) => { - const { resultSets } = payload; - displayLegend('LegendsId1', resultSets); - - const displayField1 = document.getElementById('HLYR1-state'); - if (resultSets) { - const oldData = document.getElementById(`HLYR1-state-data`); - if (oldData) oldData.parentNode.removeChild(oldData); - const data = document.createElement('div'); - data.id = `HLYR1-state-data`; - displayField1.appendChild(data); - - Object.keys(resultSets).forEach((key) => { - const addToTable = (field, value, table) => { - const tableRow = document.createElement('tr'); - table.appendChild(tableRow); - let tableData = document.createElement('td'); - tableData.style = 'width:50%'; - tableData.innerText = field - tableRow.appendChild(tableData); - tableData = document.createElement('td'); - tableData.style = 'width:50%'; - tableData.innerText = value; - tableRow.appendChild(tableData); - } - const h4 = document.createElement('h4'); - h4.innerText = key; - data.appendChild(h4); - const table = document.createElement('table'); - table.border = '1'; - table.style = 'width:50%'; - data.appendChild(table); - addToTable('Layer Name', resultSets[key].layerName?.en, table); - addToTable('Layer Status', resultSets[key].layerStatus, table); - addToTable('Layer Phase', resultSets[key].layerPhase, table); - }); - } - }, - 'LYR1/$LegendsLayerSet$' - ); - // The GET_LEGENDS.TRIGGER event must be triggered after the GET_LEGENDS.LEGENDS_LAYERSET_UPDATED listener is created - cgpv.api.event.emit({ handlerName: 'LYR1/$LegendsLayerSet$', event: cgpv.api.eventNames.GET_LEGENDS.TRIGGER }); + listenToLegendLayerSetChanges('HLYR1-state', 'LYR1/LegendsLayerSet'); diff --git a/packages/geoview-core/src/api/api.ts b/packages/geoview-core/src/api/api.ts index e123bda832d..b393e64547d 100644 --- a/packages/geoview-core/src/api/api.ts +++ b/packages/geoview-core/src/api/api.ts @@ -3,7 +3,7 @@ import { Event } from './events/event'; import { Projection, PROJECTION_NAMES } from '@/geo/projection/projection'; -import { MapViewer } from '@/geo/map/map'; +import { MapViewer } from '@/geo/map/map-viewer'; import { Plugin } from './plugin/plugin'; import { GeoUtilities } from '@/geo/utils/utilities'; diff --git a/packages/geoview-core/src/api/events/constants/app-bar.ts b/packages/geoview-core/src/api/events/constants/app-bar-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/app-bar.ts rename to packages/geoview-core/src/api/events/constants/app-bar-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/attribution.ts b/packages/geoview-core/src/api/events/constants/attribution-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/attribution.ts rename to packages/geoview-core/src/api/events/constants/attribution-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/basemap.ts b/packages/geoview-core/src/api/events/constants/basemap-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/basemap.ts rename to packages/geoview-core/src/api/events/constants/basemap-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/drawer.ts b/packages/geoview-core/src/api/events/constants/drawer-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/drawer.ts rename to packages/geoview-core/src/api/events/constants/drawer-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/feature-highlight.ts b/packages/geoview-core/src/api/events/constants/feature-highlight-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/feature-highlight.ts rename to packages/geoview-core/src/api/events/constants/feature-highlight-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/footer-bar.ts b/packages/geoview-core/src/api/events/constants/footer-bar-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/footer-bar.ts rename to packages/geoview-core/src/api/events/constants/footer-bar-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/footer-tabs.ts b/packages/geoview-core/src/api/events/constants/footer-tabs-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/footer-tabs.ts rename to packages/geoview-core/src/api/events/constants/footer-tabs-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/geolocator.ts b/packages/geoview-core/src/api/events/constants/geolocator-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/geolocator.ts rename to packages/geoview-core/src/api/events/constants/geolocator-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/geometry.ts b/packages/geoview-core/src/api/events/constants/geometry-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/geometry.ts rename to packages/geoview-core/src/api/events/constants/geometry-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/get-feature-info.ts b/packages/geoview-core/src/api/events/constants/get-feature-info-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/get-feature-info.ts rename to packages/geoview-core/src/api/events/constants/get-feature-info-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/get-legends.ts b/packages/geoview-core/src/api/events/constants/get-legends-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/get-legends.ts rename to packages/geoview-core/src/api/events/constants/get-legends-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/index.ts b/packages/geoview-core/src/api/events/constants/index.ts index 80801601cb4..26cb569031d 100644 --- a/packages/geoview-core/src/api/events/constants/index.ts +++ b/packages/geoview-core/src/api/events/constants/index.ts @@ -1,23 +1,23 @@ -export * from './app-bar'; -export * from './attribution'; -export * from './basemap'; -export * from './drawer'; -export * from './feature-highlight'; -export * from './footer-bar'; -export * from './footer-tabs'; -export * from './geolocator'; -export * from './get-feature-info'; -export * from './get-legends'; -export * from './interaction'; -export * from './layer-set'; -export * from './layer'; -export * from './map'; -export * from './marker-icon'; -export * from './modal'; -export * from './nav-bar'; -export * from './notifications'; -export * from './overview-map'; -export * from './panel'; -export * from './slider'; -export * from './snackbar'; -export * from './geometry'; +export * from './app-bar-constants'; +export * from './attribution-constants'; +export * from './basemap-constants'; +export * from './drawer-constants'; +export * from './feature-highlight-constants'; +export * from './footer-bar-constants'; +export * from './footer-tabs-constants'; +export * from './geolocator-constants'; +export * from './get-feature-info-constants'; +export * from './get-legends-constants'; +export * from './interaction-constants'; +export * from './layer-set-constants'; +export * from './layer-constants'; +export * from './map-constants'; +export * from './marker-icon-constants'; +export * from './modal-constants'; +export * from './nav-bar-constants'; +export * from './notifications-constants'; +export * from './overview-map-constants'; +export * from './panel-constants'; +export * from './slider-constants'; +export * from './snackbar-constants'; +export * from './geometry-constants'; diff --git a/packages/geoview-core/src/api/events/constants/interaction.ts b/packages/geoview-core/src/api/events/constants/interaction-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/interaction.ts rename to packages/geoview-core/src/api/events/constants/interaction-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/layer.ts b/packages/geoview-core/src/api/events/constants/layer-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/layer.ts rename to packages/geoview-core/src/api/events/constants/layer-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/layer-set.ts b/packages/geoview-core/src/api/events/constants/layer-set-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/layer-set.ts rename to packages/geoview-core/src/api/events/constants/layer-set-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/map.ts b/packages/geoview-core/src/api/events/constants/map-constants.ts similarity index 90% rename from packages/geoview-core/src/api/events/constants/map.ts rename to packages/geoview-core/src/api/events/constants/map-constants.ts index 4939a9f0fb6..59f53f81de2 100644 --- a/packages/geoview-core/src/api/events/constants/map.ts +++ b/packages/geoview-core/src/api/events/constants/map-constants.ts @@ -8,70 +8,76 @@ import { EventStringId } from '../event-types'; // TODO: repair map event as some of them does not exist on OL.... i.e. zoomend, OL uses change:moveend or change:resollution on view object /** Valid keys for the MAP category */ export type MapEventKey = + | 'EVENT_MAP_ADD_COMPONENT' + | 'EVENT_MAP_CROSSHAIR_ENTER' + | 'EVENT_MAP_FIX_NORTH' + | 'EVENT_MAP_GET_ALL_FEATURES' + | 'EVENT_MAP_IN_KEYFOCUS' | 'EVENT_MAP_LOADED' - | 'EVENT_MAP_RELOAD' | 'EVENT_MAP_MOVE_END' - | 'EVENT_MAP_SINGLE_CLICK' | 'EVENT_MAP_POINTER_MOVE' - | 'EVENT_MAP_ZOOM_END' - | 'EVENT_MAP_ADD_COMPONENT' + | 'EVENT_MAP_RELOAD' | 'EVENT_MAP_REMOVE_COMPONENT' - | 'EVENT_MAP_IN_KEYFOCUS' - | 'EVENT_MAP_CROSSHAIR_ENTER' + | 'EVENT_MAP_SINGLE_CLICK' | 'EVENT_MAP_VIEW_PROJECTION_CHANGE' - | 'EVENT_MAP_FIX_NORTH'; + | 'EVENT_MAP_ZOOM_END'; /** Record that associates MAP's event keys to their event string id */ export const MAP: Record = { /** - * Event triggered when map is loaded and api ready + * Event triggered when a user wants to add a component */ - EVENT_MAP_LOADED: 'map/loaded', + EVENT_MAP_ADD_COMPONENT: 'map/add_component', /** - * Event triggered to reload the map + * Event triggered to crosshair enable and enter pressed */ - EVENT_MAP_RELOAD: 'map/reload', + EVENT_MAP_CROSSHAIR_ENTER: 'map/crosshair_enter', /** - * Event triggered when a user stops moving the map + * Event triggered when user fix north to stay straight */ - EVENT_MAP_MOVE_END: 'map/moveend', + EVENT_MAP_FIX_NORTH: 'map/fix_north', /** - * Event triggered when a user does a true single click with no dragging and no double click. Note that this event is delayed by 250 ms to ensure that it is not a double click + * Event triggered when a user needs to get all features information for a map */ - EVENT_MAP_SINGLE_CLICK: 'map/singleclick', + EVENT_MAP_GET_ALL_FEATURES: 'map/get_all_features', /** - * Event triggered when a user does a pointer move + * Event triggered when a user focus the map with keyboard (WCAG) */ - EVENT_MAP_POINTER_MOVE: 'map/pointermove', + EVENT_MAP_IN_KEYFOCUS: 'map/inkeyfocus', /** - * Event triggered when a user stops zooming the map + * Event triggered when map is loaded and api ready */ - EVENT_MAP_ZOOM_END: 'map/zoomend', + EVENT_MAP_LOADED: 'map/loaded', /** - * Event triggered when a user wants to add a component + * Event triggered when a user stops moving the map */ - EVENT_MAP_ADD_COMPONENT: 'map/add_component', + EVENT_MAP_MOVE_END: 'map/moveend', /** - * Event triggered when a user wants to remove a component + * Event triggered when a user does a pointer move */ - EVENT_MAP_REMOVE_COMPONENT: 'map/remove_component', + EVENT_MAP_POINTER_MOVE: 'map/pointermove', /** - * Event triggered when a user focus the map with keyboard (WCAG) + * Event triggered to reload the map */ - EVENT_MAP_IN_KEYFOCUS: 'map/inkeyfocus', + EVENT_MAP_RELOAD: 'map/reload', /** - * Event triggered to crosshair enable and enter pressed + * Event triggered when a user wants to remove a component */ - EVENT_MAP_CROSSHAIR_ENTER: 'map/crosshair_enter', + EVENT_MAP_REMOVE_COMPONENT: 'map/remove_component', + + /** + * Event triggered when a user does a true single click with no dragging and no double click. Note that this event is delayed by 250 ms to ensure that it is not a double click + */ + EVENT_MAP_SINGLE_CLICK: 'map/singleclick', /** * Event triggered to change map view projection @@ -79,7 +85,7 @@ export const MAP: Record = { EVENT_MAP_VIEW_PROJECTION_CHANGE: 'map/view_projection_change', /** - * Event triggered when user fix north to stay straight + * Event triggered when a user stops zooming the map */ - EVENT_MAP_FIX_NORTH: 'map/fix_north', + EVENT_MAP_ZOOM_END: 'map/zoomend', }; diff --git a/packages/geoview-core/src/api/events/constants/marker-icon.ts b/packages/geoview-core/src/api/events/constants/marker-icon-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/marker-icon.ts rename to packages/geoview-core/src/api/events/constants/marker-icon-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/modal.ts b/packages/geoview-core/src/api/events/constants/modal-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/modal.ts rename to packages/geoview-core/src/api/events/constants/modal-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/nav-bar.ts b/packages/geoview-core/src/api/events/constants/nav-bar-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/nav-bar.ts rename to packages/geoview-core/src/api/events/constants/nav-bar-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/notifications.ts b/packages/geoview-core/src/api/events/constants/notifications-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/notifications.ts rename to packages/geoview-core/src/api/events/constants/notifications-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/overview-map.ts b/packages/geoview-core/src/api/events/constants/overview-map-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/overview-map.ts rename to packages/geoview-core/src/api/events/constants/overview-map-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/panel.ts b/packages/geoview-core/src/api/events/constants/panel-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/panel.ts rename to packages/geoview-core/src/api/events/constants/panel-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/slider.ts b/packages/geoview-core/src/api/events/constants/slider-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/slider.ts rename to packages/geoview-core/src/api/events/constants/slider-constants.ts diff --git a/packages/geoview-core/src/api/events/constants/snackbar.ts b/packages/geoview-core/src/api/events/constants/snackbar-constants.ts similarity index 100% rename from packages/geoview-core/src/api/events/constants/snackbar.ts rename to packages/geoview-core/src/api/events/constants/snackbar-constants.ts diff --git a/packages/geoview-core/src/api/events/event-types.ts b/packages/geoview-core/src/api/events/event-types.ts index 5beb5a988dd..af069bab4f3 100644 --- a/packages/geoview-core/src/api/events/event-types.ts +++ b/packages/geoview-core/src/api/events/event-types.ts @@ -1,26 +1,26 @@ -import { APPBAR } from './constants/app-bar'; -import { ATTRIBUTION } from './constants/attribution'; -import { BASEMAP } from './constants/basemap'; -import { DRAWER } from './constants/drawer'; -import { FOOTERBAR } from './constants/footer-bar'; -import { FOOTER_TABS } from './constants/footer-tabs'; -import { GET_FEATURE_INFO } from './constants/get-feature-info'; -import { GET_LEGENDS } from './constants/get-legends'; -import { GEOMETRY } from './constants/geometry'; -import { GEOLOCATOR } from './constants/geolocator'; -import { INTERACTION } from './constants/interaction'; -import { LAYER_SET } from './constants/layer-set'; -import { LAYER } from './constants/layer'; -import { MAP } from './constants/map'; -import { MARKER_ICON } from './constants/marker-icon'; -import { FEATURE_HIGHLIGHT } from './constants/feature-highlight'; -import { MODAL } from './constants/modal'; -import { NAVBAR } from './constants/nav-bar'; -import { NOTIFICATIONS } from './constants/notifications'; -import { OVERVIEW_MAP } from './constants/overview-map'; -import { PANEL } from './constants/panel'; -import { SLIDER } from './constants/slider'; -import { SNACKBAR } from './constants/snackbar'; +import { APPBAR } from './constants/app-bar-constants'; +import { ATTRIBUTION } from './constants/attribution-constants'; +import { BASEMAP } from './constants/basemap-constants'; +import { DRAWER } from './constants/drawer-constants'; +import { FOOTERBAR } from './constants/footer-bar-constants'; +import { FOOTER_TABS } from './constants/footer-tabs-constants'; +import { GET_FEATURE_INFO } from './constants/get-feature-info-constants'; +import { GET_LEGENDS } from './constants/get-legends-constants'; +import { GEOMETRY } from './constants/geometry-constants'; +import { GEOLOCATOR } from './constants/geolocator-constants'; +import { INTERACTION } from './constants/interaction-constants'; +import { LAYER_SET } from './constants/layer-set-constants'; +import { LAYER } from './constants/layer-constants'; +import { MAP } from './constants/map-constants'; +import { MARKER_ICON } from './constants/marker-icon-constants'; +import { FEATURE_HIGHLIGHT } from './constants/feature-highlight-constants'; +import { MODAL } from './constants/modal-constants'; +import { NAVBAR } from './constants/nav-bar-constants'; +import { NOTIFICATIONS } from './constants/notifications-constants'; +import { OVERVIEW_MAP } from './constants/overview-map-constants'; +import { PANEL } from './constants/panel-constants'; +import { SLIDER } from './constants/slider-constants'; +import { SNACKBAR } from './constants/snackbar-constants'; /** * constant contains event names @@ -103,13 +103,14 @@ export type EventStringId = | 'map/crosshair_enable_disable' | 'map/crosshair_enter' | 'map/fix_north' + | 'map/get_all_features' | 'map/inkeyfocus' | 'map/loaded' | 'map/moveend' + | 'map/pointermove' | 'map/reload' | 'map/remove_component' | 'map/singleclick' - | 'map/pointermove' | 'map/view_projection_change' | 'map/zoomend' | 'marker_icon/hide' diff --git a/packages/geoview-core/src/api/events/event.ts b/packages/geoview-core/src/api/events/event.ts index f084bd162cb..9108da6c3d0 100644 --- a/packages/geoview-core/src/api/events/event.ts +++ b/packages/geoview-core/src/api/events/event.ts @@ -83,11 +83,21 @@ export class Event { * Unregister all events whose handler names start with the string passed in parameter. * * @param {string} handlerNamePrefix the handler name prefix for which you need to unregister from the event + * @param {string} eventTypeToKeep the handler name prefix composed of handlerNamePrefix/eventTypeToKeep to keep */ - offAll = (handlerNamePrefix: string): void => { + offAll = (handlerNamePrefix: string, eventTypeToKeep?: string): void => { (Object.keys(this.eventEmitter._events) as EventStringId[]).forEach((eventNameId) => { if (eventNameId.startsWith(handlerNamePrefix)) { - this.off(eventNameId); + if (eventTypeToKeep) { + if (Array.isArray(eventTypeToKeep)) { + if ( + !eventTypeToKeep.find((eventType: string) => { + return eventNameId.startsWith(`${handlerNamePrefix}/${eventType}`); + }) + ) + this.off(eventNameId); + } else if (!eventNameId.startsWith(`${handlerNamePrefix}/${eventTypeToKeep}`)) this.off(eventNameId); + } else this.off(eventNameId); } }); }; diff --git a/packages/geoview-core/src/api/events/payloads/get-feature-info-payload.ts b/packages/geoview-core/src/api/events/payloads/get-feature-info-payload.ts index c06e4806552..488e2dd8665 100644 --- a/packages/geoview-core/src/api/events/payloads/get-feature-info-payload.ts +++ b/packages/geoview-core/src/api/events/payloads/get-feature-info-payload.ts @@ -19,7 +19,17 @@ const validEvents: EventStringId[] = [ EVENT_NAMES.GET_FEATURE_INFO.QUERY_RESULT, ]; -export type TypeQueryType = 'at pixel' | 'at coordinate' | 'at long lat' | 'using a bounding box' | 'using a polygon'; +export type TypeQueryType = 'at_pixel' | 'at_coordinate' | 'at_long_lat' | 'using_a_bounding_box' | 'using_a_polygon' | 'all'; +export const ArrayOfQueryTypes: TypeQueryType[] = [ + 'at_pixel', + 'at_coordinate', + 'at_long_lat', + 'using_a_bounding_box', + 'using_a_polygon', + 'all', +]; + +export type TypeLocation = null | Pixel | Coordinate | Coordinate[]; export type codeValueEntryType = { name: string; @@ -60,12 +70,17 @@ export type TypeFeatureInfoEntry = { nameField: string | null; }; -export type TypeArrayOfFeatureInfoEntries = TypeFeatureInfoEntry[]; +export type TypeArrayOfFeatureInfoEntries = TypeFeatureInfoEntry[] | undefined | null; + +export type TypeFeatureInfoByQueryTypes = { + [K in TypeQueryType]?: TypeArrayOfFeatureInfoEntries; +}; + export type TypeFeatureInfoResultSets = { [layerPath: string]: { layerStatus: TypeLayerStatus; layerPhase: string; - data: TypeArrayOfFeatureInfoEntries | undefined | null; + data: TypeFeatureInfoByQueryTypes; }; }; @@ -87,10 +102,10 @@ export const payloadIsQueryLayer = (verifyIfPayload: PayloadBaseClass): verifyIf export interface TypeQueryLayerPayload extends GetFeatureInfoPayload { // The query type to perform queryType: TypeQueryType; - // the location to query - location: Pixel | Coordinate | Coordinate[]; - // know if is a click or hover query - isHover: boolean; + // the location to query, null is used when queryType is all + location?: TypeLocation; + // know if is a click or hover query, null is used when queryType is all + isHover?: boolean | null; } /** @@ -121,8 +136,11 @@ export const payloadIsHoverQueryDone = (verifyIfPayload: PayloadBaseClass): veri * Additional attributes needed to define a GetFeatureInfoPayload */ export interface TypeAllQueriesDonePayload extends GetFeatureInfoPayload { + // The query type that was performed + queryType: TypeQueryType; // The layer set identifier layerSetId: string; + // the resultSets that contains the query results resultSets: TypeFeatureInfoResultSets; } @@ -144,10 +162,12 @@ export const payloadIsQueryResult = (verifyIfPayload: PayloadBaseClass): verifyI export interface TypeQueryResultPayload extends GetFeatureInfoPayload { // the layer path used by the query layerPath: string; + // the type of query to perform + queryType: TypeQueryType; // the resultset of the query arrayOfRecords: TypeArrayOfFeatureInfoEntries; // know if is a click or hover query - isHover: boolean; + isHover?: boolean | null; } /** @@ -184,17 +204,17 @@ export class GetFeatureInfoPayload extends PayloadBaseClass { * Static method used to create a "get feature info" payload that will run a query on all layers in the set. * * @param {string | null} handlerName the handler Name - * @param {TypeQueryType} queryType the query type to perform - * @param {Pixel | Coordinate | Coordinate[]} location the location to query - * @param {boolean} isHover the type of query + * @param {TypeQueryType} queryType the query's type to perform + * @param {TypeLocation} location the location to query + * @param {boolean | null} isHover the type of query * * @returns {TypeQueryLayerPayload} the queryLayerPayload object created */ static createQueryLayerPayload = ( handlerName: string, queryType: TypeQueryType, - location: Pixel | Coordinate | Coordinate[], - isHover: boolean + location?: TypeLocation, + isHover?: boolean | null ): TypeQueryLayerPayload => { const queryLayerPayload = new GetFeatureInfoPayload(EVENT_NAMES.GET_FEATURE_INFO.QUERY_LAYER, handlerName) as TypeQueryLayerPayload; queryLayerPayload.queryType = queryType; @@ -207,6 +227,7 @@ export class GetFeatureInfoPayload extends PayloadBaseClass { * Static method used to create an "all queries done" payload. * * @param {string | null} handlerName the handler Name + * @param {TypeQueryType} queryType the query's type done * @param {string} layerSetId the layer set identifier * @param {TypeFeatureInfoResultSets} resultSets the result set for the query * @@ -214,6 +235,7 @@ export class GetFeatureInfoPayload extends PayloadBaseClass { */ static createAllQueriesDonePayload = ( handlerName: string, + queryType: TypeQueryType, layerSetId: string, resultSets: TypeFeatureInfoResultSets ): TypeAllQueriesDonePayload => { @@ -221,6 +243,7 @@ export class GetFeatureInfoPayload extends PayloadBaseClass { EVENT_NAMES.GET_FEATURE_INFO.ALL_QUERIES_DONE, handlerName ) as TypeAllQueriesDonePayload; + allQueriesDonePayload.queryType = queryType; allQueriesDonePayload.layerSetId = layerSetId; allQueriesDonePayload.resultSets = resultSets; return allQueriesDonePayload; @@ -230,6 +253,7 @@ export class GetFeatureInfoPayload extends PayloadBaseClass { * Static method used to create an "hover query done" payload. * * @param {string | null} handlerName the handler Name + * @param {TypeQueryType} queryType the resultset query type * @param {string} layerSetId the layer set identifier * @param {TypeFeatureInfoResultSets} resultSets the result set for the query * @@ -237,6 +261,7 @@ export class GetFeatureInfoPayload extends PayloadBaseClass { */ static createHoverQueryDonePayload = ( handlerName: string, + queryType: TypeQueryType, layerSetId: string, resultSets: TypeFeatureInfoResultSets ): TypeAllQueriesDonePayload => { @@ -244,6 +269,7 @@ export class GetFeatureInfoPayload extends PayloadBaseClass { EVENT_NAMES.GET_FEATURE_INFO.HOVER_QUERY_DONE, handlerName ) as TypeAllQueriesDonePayload; + hoverQueryDonePayload.queryType = queryType; hoverQueryDonePayload.layerSetId = layerSetId; hoverQueryDonePayload.resultSets = resultSets; return hoverQueryDonePayload; @@ -254,19 +280,22 @@ export class GetFeatureInfoPayload extends PayloadBaseClass { * * @param {string | null} handlerName the handler Name * @param {string} layerPath the layer path + * @param {TypeQueryType} queryType the resultset query type * @param {TypeArrayOfFeatureInfoEntries} arrayOfRecords the resultset of the get feature info query - * @param {boolean} isHover the type of query + * @param {boolean | null} isHover the type of query * * @returns {TypeQueryResultPayload} the queryResultPayload object created */ static createQueryResultPayload = ( handlerName: string, layerPath: string, + queryType: TypeQueryType, arrayOfRecords: TypeArrayOfFeatureInfoEntries, - isHover: boolean + isHover?: boolean | null ): TypeQueryResultPayload => { const queryResultPayload = new GetFeatureInfoPayload(EVENT_NAMES.GET_FEATURE_INFO.QUERY_RESULT, handlerName) as TypeQueryResultPayload; queryResultPayload.layerPath = layerPath; + queryResultPayload.queryType = queryType; queryResultPayload.arrayOfRecords = arrayOfRecords; queryResultPayload.isHover = isHover; return queryResultPayload; diff --git a/packages/geoview-core/src/api/events/payloads/get-legends-payload.ts b/packages/geoview-core/src/api/events/payloads/get-legends-payload.ts index d5769ae7fbe..723e5328ddc 100644 --- a/packages/geoview-core/src/api/events/payloads/get-legends-payload.ts +++ b/packages/geoview-core/src/api/events/payloads/get-legends-payload.ts @@ -9,7 +9,6 @@ const validEvents: EventStringId[] = [ EVENT_NAMES.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, EVENT_NAMES.GET_LEGENDS.LEGEND_INFO, EVENT_NAMES.GET_LEGENDS.QUERY_LEGEND, - EVENT_NAMES.GET_LEGENDS.TRIGGER, ]; /** The legend resultset type associate a layer path to a legend object. The undefined value indicate that the get legend query @@ -87,18 +86,6 @@ export interface TypeQueryLegendPayload extends GetLegendsPayload { layerPath: string; } -/** - * type guard function that redefines a PayloadBaseClass as a TypeTriggerLegendsPayload - * if the event attribute of the verifyIfPayload parameter is valid. The type ascention - * applies only to the true block of the if clause. - * - * @param {PayloadBaseClass} verifyIfPayload object to test in order to determine if the type ascention is valid - * @returns {boolean} returns true if the payload is valid - */ -export const payloadIsTriggerLegend = (verifyIfPayload: PayloadBaseClass): verifyIfPayload is TypeTriggerLegendsPayload => { - return verifyIfPayload?.event === EVENT_NAMES.GET_LEGENDS.TRIGGER; -}; - /** * Additional attributes needed to define a TypeTriggerLegendsPayload */ @@ -183,17 +170,4 @@ export class GetLegendsPayload extends PayloadBaseClass { queryLayerPayload.layerPath = layerPath; return queryLayerPayload; }; - - /** - * Static method used to create a get legends payload that will trigger the get legends event processing to continuously keep - * the legends layer up to date. - * - * @param {string | null} handlerName the handler Name - * - * @returns {TypeTriggerLegendsPayload} the triggerLegendsPayload object created - */ - static createTriggerLegendPayload = (handlerName: string): TypeTriggerLegendsPayload => { - const triggerLegendsPayload = new GetLegendsPayload(EVENT_NAMES.GET_LEGENDS.TRIGGER, handlerName) as TypeTriggerLegendsPayload; - return triggerLegendsPayload; - }; } diff --git a/packages/geoview-core/src/api/plugin/plugin.ts b/packages/geoview-core/src/api/plugin/plugin.ts index 8c4a7a9c9a2..da3b4c8e527 100644 --- a/packages/geoview-core/src/api/plugin/plugin.ts +++ b/packages/geoview-core/src/api/plugin/plugin.ts @@ -8,7 +8,7 @@ import Ajv from 'ajv'; import makeStyles from '@mui/styles/makeStyles'; import { showError } from '@/core/utils/utilities'; -import { MapViewer } from '@/geo/map/map'; +import { MapViewer } from '@/geo/map/map-viewer'; import { api } from '@/app'; import { AbstractPlugin } from './abstract-plugin'; diff --git a/packages/geoview-core/src/app.tsx b/packages/geoview-core/src/app.tsx index 819ba371a2a..9ea09da6895 100644 --- a/packages/geoview-core/src/app.tsx +++ b/packages/geoview-core/src/app.tsx @@ -23,6 +23,8 @@ import { getValidConfigFromString } from '@/core/utils/utilities'; import { Config } from '@/core/utils/config/config'; import { payloadIsAmapFeaturesConfig } from '@/api/events/payloads'; import { addGeoViewStore } from '@/core/stores/stores-managers'; +import { LegendsLayerSet } from '@/geo/utils/legends-layer-set'; +import { FeatureInfoLayerSet } from '@/geo/utils/feature-info-layer-set'; // The next export allow to import the cgpv-types from 'geoview-core' from outside of the geoview-core package. export * from './core/types/cgpv-types'; @@ -36,55 +38,54 @@ const reactRoot: Record = {}; * all changes made to the map are applied. */ export function addReloadListener(mapId: string) { - api.event.on( - EVENT_NAMES.MAP.EVENT_MAP_RELOAD, - (payload) => { - if (payloadIsAmapFeaturesConfig(payload)) { - const { mapFeaturesConfig } = payload; - if (mapFeaturesConfig) { - if (api.maps[mapId].layer) api.maps[mapId].layer.removeAllGeoviewLayers(); - // unsubscribe from all remaining events registered on this map - api.event.offAll(mapId); - - // unload all loaded plugins on the map - api.plugin.removePlugins(mapId); - - // get the map container - const map = document.getElementById(mapId); - - if (map) { - // remove the dom element (remove rendered map) - if (reactRoot[mapId] !== null) reactRoot[mapId].unmount(); - - // recreate the map - crate e new div and remove the active one - const newDiv = document.createElement('div'); - newDiv.setAttribute('id', mapId); - newDiv.setAttribute('class', 'llwp-map'); - map!.parentNode!.insertBefore(newDiv, map); - map.remove(); - - // create the new root - const newRoot = document.getElementById(mapId); - reactRoot[mapId] = createRoot(newRoot!); - - // delete the map instance from the maps array - delete api.maps[mapId]; - - // delete plugins that were loaded on the map - delete api.plugin.plugins[mapId]; - - // set plugin's loaded to false - api.plugin.pluginsLoaded = false; - - addReloadListener(mapId); - // re-render map with updated config keeping previous values if unchanged - reactRoot[mapId].render(); - } + const reloadHandler = (payload: types.PayloadBaseClass) => { + if (payloadIsAmapFeaturesConfig(payload)) { + const { mapFeaturesConfig } = payload; + if (mapFeaturesConfig) { + if (api.maps[mapId]?.layer) api.maps[mapId].layer.removeAllGeoviewLayers(); + // unsubscribe from all remaining events registered on this map + api.event.offAll(mapId); + LegendsLayerSet.delete(mapId); + FeatureInfoLayerSet.delete(mapId); + + // unload all loaded plugins on the map + api.plugin.removePlugins(mapId); + + // get the map container + const map = document.getElementById(mapId); + + if (map) { + // remove the dom element (remove rendered map) + if (reactRoot[mapId] !== null) reactRoot[mapId].unmount(); + + // recreate the map - crate e new div and remove the active one + const newDiv = document.createElement('div'); + newDiv.setAttribute('id', mapId); + newDiv.setAttribute('class', 'llwp-map'); + map!.parentNode!.insertBefore(newDiv, map); + map.remove(); + + // create the new root + const newRoot = document.getElementById(mapId); + reactRoot[mapId] = createRoot(newRoot!); + + // delete the map instance from the maps array + delete api.maps[mapId]; + + // delete plugins that were loaded on the map + delete api.plugin.plugins[mapId]; + + // set plugin's loaded to false + api.plugin.pluginsLoaded = false; + + addReloadListener(mapId); + // re-render map with updated config keeping previous values if unchanged + reactRoot[mapId].render(); } } - }, - `${mapId}/delete_old_map` - ); + } + }; + api.event.on(EVENT_NAMES.MAP.EVENT_MAP_RELOAD, reloadHandler, `${mapId}/delete_old_map`); } /** @@ -134,9 +135,9 @@ async function init(callback: () => void) { if (configObj) { addGeoViewStore(configObj); // render the map with the config - reactRoot[configObj.mapId!] = createRoot(mapElement!); - addReloadListener(configObj.mapId!); - reactRoot[configObj.mapId!].render(); + reactRoot[configObj.mapId] = createRoot(mapElement!); + addReloadListener(configObj.mapId); + reactRoot[configObj.mapId].render(); } } } diff --git a/packages/geoview-core/src/core/app-start.tsx b/packages/geoview-core/src/core/app-start.tsx index de2f495a8d4..604864f1087 100644 --- a/packages/geoview-core/src/core/app-start.tsx +++ b/packages/geoview-core/src/core/app-start.tsx @@ -7,11 +7,11 @@ import { I18nextProvider } from 'react-i18next'; import { ThemeProvider, Theme, StyledEngineProvider } from '@mui/material/styles'; import CssBaseline from '@mui/material/CssBaseline'; -import { Shell } from './containers/shell'; -import { getTheme, cgpvTheme } from '../ui/style/theme'; -import { MapViewer } from '@/geo/map/map'; -import { TypeMapFeaturesConfig } from './types/global-types'; -import { TypeInteraction } from '../app'; +import { Shell } from '@/core/containers/shell'; +import { getTheme, cgpvTheme } from '@/ui/style/theme'; +import { MapViewer } from '@/geo/map/map-viewer'; +import { TypeMapFeaturesConfig } from '@/core/types/global-types'; +import { api, TypeInteraction } from '@/app'; declare module '@mui/styles/defaultTheme' { // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -61,9 +61,8 @@ function AppStart(props: AppStartProps): JSX.Element { fallbackLng: mapFeaturesConfig.displayLanguage, }); - // create a new map instance - // eslint-disable-next-line no-new - new MapViewer(mapFeaturesConfig, i18nInstance); + // create a new map viewer instance and add it to the api + api.maps[mapFeaturesConfig.mapId] = new MapViewer(mapFeaturesConfig, i18nInstance); return ( diff --git a/packages/geoview-core/src/core/components/click-marker/click-marker.tsx b/packages/geoview-core/src/core/components/click-marker/click-marker.tsx index 9566aa97421..4f427087dd0 100644 --- a/packages/geoview-core/src/core/components/click-marker/click-marker.tsx +++ b/packages/geoview-core/src/core/components/click-marker/click-marker.tsx @@ -309,11 +309,11 @@ export function ClickMarker(): JSX.Element { const allQueriesDoneListenerFunction = (payload: PayloadBaseClass) => { if (payloadIsAllQueriesDone(payload)) { - const { resultSets } = payload; + const { queryType, resultSets } = payload; let feature: TypeFeatureInfoEntry | undefined; Object.keys(resultSets).every((layerPath) => { - const features = resultSets[layerPath]!.layerStatus === 'error' ? null : resultSets[layerPath]!.data; + const features = resultSets[layerPath]!.layerStatus === 'error' ? null : resultSets[layerPath]!.data[queryType]; if (features && features.length > 0 && features[0].geoviewLayerType !== 'ogcWms') { [feature] = features; return false; @@ -358,7 +358,7 @@ export function ClickMarker(): JSX.Element { } ); - api.event.on(EVENT_NAMES.GET_FEATURE_INFO.ALL_QUERIES_DONE, allQueriesDoneListenerFunction, `${mapId}/$FeatureInfoLayerSet$`); + api.event.on(EVENT_NAMES.GET_FEATURE_INFO.ALL_QUERIES_DONE, allQueriesDoneListenerFunction, `${mapId}/FeatureInfoLayerSet`); api.event.on(EVENT_NAMES.MARKER_ICON.EVENT_MARKER_ICON_SHOW, eventMarkerIconShowListenerFunction, mapId); api.event.on(EVENT_NAMES.MARKER_ICON.EVENT_MARKER_ICON_HIDE, eventMarkerIconHideListenerFunction, mapId); api.event.on(EVENT_NAMES.FEATURE_HIGHLIGHT.EVENT_HIGHLIGHT_FEATURE, highlightCallbackFunction, mapId); diff --git a/packages/geoview-core/src/core/components/data-table/data-table-api.ts b/packages/geoview-core/src/core/components/data-table/data-table-api.ts index 5f2d7c43740..56b763b2a12 100644 --- a/packages/geoview-core/src/core/components/data-table/data-table-api.ts +++ b/packages/geoview-core/src/core/components/data-table/data-table-api.ts @@ -1,14 +1,7 @@ import { createElement, ReactElement } from 'react'; import DataTable, { DataTableData } from './data-table'; -import { - AbstractGeoViewVector, - api, - TypeListOfLayerEntryConfig, - isVectorLayer, - TypeArrayOfFeatureInfoEntries, - TypeFieldEntry, -} from '@/app'; +import { api, TypeListOfLayerEntryConfig, isVectorLayer, TypeArrayOfFeatureInfoEntries, TypeFieldEntry } from '@/app'; import MapDataTable from './map-data-table'; import { Datapanel } from './data-panel'; @@ -71,7 +64,7 @@ export class DataTableApi { */ buildFeatureRows = (arrayOfFeatureInfoEntries: TypeArrayOfFeatureInfoEntries) => { - const features = arrayOfFeatureInfoEntries.map((feature) => { + const features = arrayOfFeatureInfoEntries!.map((feature) => { return { ...feature, rows: Object.keys(feature.fieldInfo).reduce((acc, curr) => { @@ -83,7 +76,7 @@ export class DataTableApi { }; }); - const columns = arrayOfFeatureInfoEntries.reduce((acc, curr) => { + const columns = arrayOfFeatureInfoEntries!.reduce((acc, curr) => { const keys = Object.keys(curr.fieldInfo); keys.forEach((key) => { @@ -112,15 +105,12 @@ export class DataTableApi { const { currentProjection } = api.maps[this.mapId]; const projectionConfig = api.projection.projections[currentProjection]; - if ( - geoviewLayerInstance.listOfLayerEntryConfig.length > 0 && - (geoviewLayerInstance as AbstractGeoViewVector).getAllFeatureInfo !== undefined - ) { + if (geoviewLayerInstance.listOfLayerEntryConfig.length > 0) { const groupLayerKeys = this.getGroupKeys(geoviewLayerInstance.listOfLayerEntryConfig, layerId, []); if (isVectorLayer(geoviewLayerInstance)) { const requests = groupLayerKeys.map((groupLayerKey) => { - return (geoviewLayerInstance as AbstractGeoViewVector)?.getAllFeatureInfo(groupLayerKey); + return geoviewLayerInstance.getFeatureInfo('all', groupLayerKey); }); const response = await Promise.allSettled(requests); @@ -151,10 +141,7 @@ export class DataTableApi { geoLayers.forEach((layerId: string) => { const geoviewLayerInstance = api.maps[this.mapId].layer.geoviewLayers[layerId]; - if ( - geoviewLayerInstance.listOfLayerEntryConfig.length > 0 && - (geoviewLayerInstance as AbstractGeoViewVector).getAllFeatureInfo !== undefined - ) { + if (geoviewLayerInstance.listOfLayerEntryConfig.length > 0) { const groupLayerKeys = this.getGroupKeys(geoviewLayerInstance.listOfLayerEntryConfig, layerId, []); layerKeys = [...layerKeys, ...groupLayerKeys]; layerIds = [...layerIds, ...groupLayerKeys.fill(layerId)]; @@ -164,7 +151,7 @@ export class DataTableApi { const requests = layerKeys.map((layerKey, index) => { const layerId = layerIds[index]; const geoviewLayerInstance = api.maps[this.mapId].layer.geoviewLayers[layerId]; - return (geoviewLayerInstance as AbstractGeoViewVector)?.getAllFeatureInfo(layerKey); + return geoviewLayerInstance.getFeatureInfo('all', layerKey); }); const response = await Promise.allSettled(requests); diff --git a/packages/geoview-core/src/core/components/details-1/details.tsx b/packages/geoview-core/src/core/components/details-1/details.tsx index 6987a7a46c6..6fde782aa20 100644 --- a/packages/geoview-core/src/core/components/details-1/details.tsx +++ b/packages/geoview-core/src/core/components/details-1/details.tsx @@ -10,7 +10,7 @@ export interface TypeDetailsProps { export interface TypeLayerData { layerPath: string; layerName: string; - features: TypeArrayOfFeatureInfoEntries; + features: Exclude; } export type TypeArrayOfLayerData = TypeLayerData[]; diff --git a/packages/geoview-core/src/core/components/details-1/feature-info-new.tsx b/packages/geoview-core/src/core/components/details-1/feature-info-new.tsx index da5001bf6df..7cdd7645b8c 100644 --- a/packages/geoview-core/src/core/components/details-1/feature-info-new.tsx +++ b/packages/geoview-core/src/core/components/details-1/feature-info-new.tsx @@ -22,7 +22,10 @@ export interface TypeFeatureInfoProps { features: TypeArrayOfFeatureInfoEntries; currentFeatureIndex: number; onClearCheckboxes: () => void; - onFeatureNavigateChange: (checkedFeatures: TypeArrayOfFeatureInfoEntries, currentFeature: TypeFeatureInfoEntry) => void; + onFeatureNavigateChange: ( + checkedFeatures: Exclude, + currentFeature: TypeFeatureInfoEntry + ) => void; setDisableClearAllBtn: (isDisabled: boolean) => void; selectedFeatures?: MutableRefObject; clearAllCheckboxes?: boolean; @@ -47,8 +50,8 @@ export function FeatureInfo({ const { t } = useTranslation(); const theme = useTheme(); const [checked, setChecked] = useState(false); - const [checkedFeatures, setCheckedFeatures] = useState([]); - const feature = features[currentFeatureIndex]; + const [checkedFeatures, setCheckedFeatures] = useState>([]); + const feature = features![currentFeatureIndex]; const featureUid = getUid(feature.geometry); const featureIconSrc = feature.featureIcon.toDataURL(); const nameFieldValue = feature.fieldInfo[feature.nameField!]!.value as string; diff --git a/packages/geoview-core/src/core/components/details-1/layers-list-footer.tsx b/packages/geoview-core/src/core/components/details-1/layers-list-footer.tsx index 9d94e27ae6d..0e7a2f1ae8f 100644 --- a/packages/geoview-core/src/core/components/details-1/layers-list-footer.tsx +++ b/packages/geoview-core/src/core/components/details-1/layers-list-footer.tsx @@ -88,7 +88,10 @@ export function LayersListFooter(props: TypeLayersListProps): JSX.Element { setIsClearAllCheckboxes(true); }; - const allUncheckedFeatures = (checkedFeatures: TypeArrayOfFeatureInfoEntries, allFeatures: TypeArrayOfFeatureInfoEntries) => { + const allUncheckedFeatures = ( + checkedFeatures: Exclude, + allFeatures: Exclude + ) => { const uncheckedFeatures = allFeatures.filter( (feature) => !checkedFeatures.some( @@ -98,7 +101,10 @@ export function LayersListFooter(props: TypeLayersListProps): JSX.Element { return uncheckedFeatures; }; - const handleFeatureNavigateChange = (checkedFeatures: TypeArrayOfFeatureInfoEntries, currentFeature: TypeFeatureInfoEntry) => { + const handleFeatureNavigateChange = ( + checkedFeatures: Exclude, + currentFeature: TypeFeatureInfoEntry + ) => { // remove the highlight for unchecked feature arrayOfLayerData.forEach((layer: TypeLayerData) => { const getAllUnCheckedFeatures = allUncheckedFeatures(checkedFeatures, layer.features); diff --git a/packages/geoview-core/src/core/components/details/details.tsx b/packages/geoview-core/src/core/components/details/details.tsx index 69313583543..05ba6521e60 100644 --- a/packages/geoview-core/src/core/components/details/details.tsx +++ b/packages/geoview-core/src/core/components/details/details.tsx @@ -18,7 +18,7 @@ export interface TypeDetailsProps { export interface TypeLayerData { layerPath: string; layerName: string; - features: TypeArrayOfFeatureInfoEntries; + features: Exclude; } export type TypeArrayOfLayerData = TypeLayerData[]; diff --git a/packages/geoview-core/src/core/components/hover-tooltip/hover-tooltip.tsx b/packages/geoview-core/src/core/components/hover-tooltip/hover-tooltip.tsx index 429b8b85833..4d48f1fce82 100644 --- a/packages/geoview-core/src/core/components/hover-tooltip/hover-tooltip.tsx +++ b/packages/geoview-core/src/core/components/hover-tooltip/hover-tooltip.tsx @@ -64,18 +64,18 @@ export function HoverTooltip(): JSX.Element { const hoverQueryDoneListenerFunction = (payload: PayloadBaseClass) => { if (payloadIsHoverQueryDone(payload)) { - const { resultSets } = payload; + const { queryType, resultSets } = payload; // eslint-disable-next-line no-restricted-syntax for (const [, value] of Object.entries(resultSets)) { // if there is a result and layer is not ogcWms, and it is not selected, show tooltip if ( - value?.data && - value!.data.length > 0 && - value!.data[0].geoviewLayerType !== 'ogcWms' && - !(selectedFeature.current && getUid(value!.data[0].geometry) === getUid(selectedFeature.current?.geometry)) + value?.data?.[queryType] && + value!.data[queryType]!.length > 0 && + value!.data[queryType]![0].geoviewLayerType !== 'ogcWms' && + !(selectedFeature.current && getUid(value!.data[queryType]![0].geometry) === getUid(selectedFeature.current?.geometry)) ) { - const item = value!.data[0]; + const item = value!.data[queryType]![0]; const nameField = item.nameField || Object.entries(item.fieldInfo)[0][0]; const field = item.fieldInfo[nameField]; setTooltipValue(field!.value as string | ''); @@ -89,9 +89,9 @@ export function HoverTooltip(): JSX.Element { const allQueriesDoneListenerFunciton = (payload: PayloadBaseClass) => { if (payloadIsAllQueriesDone(payload)) { - const { resultSets } = payload; + const { queryType, resultSets } = payload; Object.keys(resultSets).every((layerPath) => { - const features = resultSets[layerPath]!.data; + const features = resultSets[layerPath]!.data[queryType]; if (features && features.length > 0 && features[0].geoviewLayerType !== 'ogcWms') { [selectedFeature.current] = features; return false; @@ -127,10 +127,10 @@ export function HoverTooltip(): JSX.Element { ); // listen to hover query done event - api.event.on(EVENT_NAMES.GET_FEATURE_INFO.HOVER_QUERY_DONE, hoverQueryDoneListenerFunction, `${mapId}/$FeatureInfoLayerSet$`); + api.event.on(EVENT_NAMES.GET_FEATURE_INFO.HOVER_QUERY_DONE, hoverQueryDoneListenerFunction, `${mapId}/FeatureInfoLayerSet`); // Get a feature when it is selected - api.event.on(EVENT_NAMES.GET_FEATURE_INFO.ALL_QUERIES_DONE, allQueriesDoneListenerFunciton, `${mapId}/$FeatureInfoLayerSet$`); + api.event.on(EVENT_NAMES.GET_FEATURE_INFO.ALL_QUERIES_DONE, allQueriesDoneListenerFunciton, `${mapId}/FeatureInfoLayerSet`); return () => { api.event.off(EVENT_NAMES.GET_FEATURE_INFO.HOVER_QUERY_DONE, mapId, hoverQueryDoneListenerFunction); diff --git a/packages/geoview-core/src/core/components/legend-2/legend-api.ts b/packages/geoview-core/src/core/components/legend-2/legend-api.ts index 178dee7ab53..e18e2a8f0f6 100644 --- a/packages/geoview-core/src/core/components/legend-2/legend-api.ts +++ b/packages/geoview-core/src/core/components/legend-2/legend-api.ts @@ -42,7 +42,6 @@ export class Legend2Api { */ createLegend = (props: TypeLegendProps) => { // const { layerIds, isRemoveable, canSetOpacity, expandAll, hideAll } = props; - // api.event.emit({ handlerName: `${this.mapId}/$LegendsLayerSet$`, event: api.eventNames.GET_LEGENDS.TRIGGER }); // const legendItems = layerIds.map((layerId) => { // const geoviewLayerInstance = api.maps[this.mapId].layer.geoviewLayers[layerId]; // if (geoviewLayerInstance) { diff --git a/packages/geoview-core/src/core/components/legend-2/legend-icon-list.tsx b/packages/geoview-core/src/core/components/legend-2/legend-icon-list.tsx index 0ac4be6e962..3e65d9ce995 100644 --- a/packages/geoview-core/src/core/components/legend-2/legend-icon-list.tsx +++ b/packages/geoview-core/src/core/components/legend-2/legend-icon-list.tsx @@ -165,6 +165,7 @@ export function LegendIconList(props: TypeLegendIconListProps): JSX.Element { mapId, ]); + // eslint-disable-next-line no-console console.log('Check Count', countChildren); return ( diff --git a/packages/geoview-core/src/core/components/legend-2/legend.tsx b/packages/geoview-core/src/core/components/legend-2/legend.tsx index a609b1bb004..77a91fe9c46 100644 --- a/packages/geoview-core/src/core/components/legend-2/legend.tsx +++ b/packages/geoview-core/src/core/components/legend-2/legend.tsx @@ -19,7 +19,6 @@ const Item = styled('div')(({ theme }) => ({ export function Legend2(props: LegendItemsDetailsProps): JSX.Element { const { layerIds, isRemoveable, canSetOpacity, expandAll, hideAll, mapId } = props; - api.event.emit({ handlerName: `${mapId}/$LegendsLayerSet$`, event: api.eventNames.GET_LEGENDS.TRIGGER }); const { t } = useTranslation(); diff --git a/packages/geoview-core/src/core/components/legend/legend-api.ts b/packages/geoview-core/src/core/components/legend/legend-api.ts index b403264410b..03c5bfa2e6f 100644 --- a/packages/geoview-core/src/core/components/legend/legend-api.ts +++ b/packages/geoview-core/src/core/components/legend/legend-api.ts @@ -39,7 +39,6 @@ export class LegendApi { */ createLegend = (props: TypeLegendProps) => { const { layerIds, isRemoveable, canSetOpacity, expandAll, hideAll } = props; - api.event.emit({ handlerName: `${this.mapId}/$LegendsLayerSet$`, event: api.eventNames.GET_LEGENDS.TRIGGER }); const legendItems = layerIds.map((layerId) => { const geoviewLayerInstance = api.maps[this.mapId].layer.geoviewLayers[layerId]; if (geoviewLayerInstance) { diff --git a/packages/geoview-core/src/core/components/map/map.tsx b/packages/geoview-core/src/core/components/map/map.tsx index 6523756a79a..a9749bf8979 100644 --- a/packages/geoview-core/src/core/components/map/map.tsx +++ b/packages/geoview-core/src/core/components/map/map.tsx @@ -29,7 +29,7 @@ import { addNotificationWarning, disableScrolling, generateId } from '@/core/uti import { api, inKeyfocusPayload } from '@/app'; import { EVENT_NAMES } from '@/api/events/event-types'; -import { MapViewer } from '@/geo/map/map'; +import { MapViewer } from '@/geo/map/map-viewer'; import { payloadIsABasemapLayerArray, payloadIsAMapViewProjection, PayloadBaseClass } from '@/api/events/payloads'; import { TypeMapFeaturesConfig } from '../../types/global-types'; diff --git a/packages/geoview-core/src/core/types/global-types.ts b/packages/geoview-core/src/core/types/global-types.ts index 20c2b9cf402..3e3cb32019c 100644 --- a/packages/geoview-core/src/core/types/global-types.ts +++ b/packages/geoview-core/src/core/types/global-types.ts @@ -52,7 +52,7 @@ export { AbstractPlugin } from '@/api/plugin/abstract-plugin'; */ export interface TypeMapFeaturesConfig extends TypeMapFeaturesInstance { /** This attribute is not part of the schema. It is placed here to keep the 'id' attribute of the HTML div of the map. */ - mapId?: string; + mapId: string; /** This attribute is not part of the schema. It is placed here to keep the 'data-lang' attribute of the HTML div of the map. */ displayLanguage?: TypeDisplayLanguage; /** If true, the ready callback 'cgpv.init(mapId)' is called with the mapId as a parameter when the map is ready */ diff --git a/packages/geoview-core/src/core/utils/config/config-validation.ts b/packages/geoview-core/src/core/utils/config/config-validation.ts index 7729a166f65..7cb5cecd1e3 100644 --- a/packages/geoview-core/src/core/utils/config/config-validation.ts +++ b/packages/geoview-core/src/core/utils/config/config-validation.ts @@ -64,6 +64,7 @@ export class ConfigValidation { /** default configuration if provided configuration is missing or wrong */ private _defaultMapFeaturesConfig: TypeMapFeaturesConfig = { + mapId: '', map: { interaction: 'dynamic', viewSettings: { @@ -128,6 +129,7 @@ export class ConfigValidation { */ constructor() { this._mapId = generateId(); + this._defaultMapFeaturesConfig.mapId = this.mapId; this._displayLanguage = this._defaultMapFeaturesConfig.displayLanguage!; this._triggerReadyCallback = this._defaultMapFeaturesConfig.triggerReadyCallback!; } @@ -156,6 +158,7 @@ export class ConfigValidation { */ set mapId(mapId: string) { this._mapId = mapId; + this._defaultMapFeaturesConfig.mapId = this.mapId; } /** *************************************************************************************************************************** @@ -864,6 +867,7 @@ export class ConfigValidation { // recreate the prop object to remove unwanted items and check if same as original. Log the modifications const validMapFeaturesConfig: TypeMapFeaturesConfig = { + mapId: this.mapId, map: { basemapOptions, viewSettings: { diff --git a/packages/geoview-core/src/core/utils/config/reader/url-config-reader.ts b/packages/geoview-core/src/core/utils/config/reader/url-config-reader.ts index e45357e5ad9..6ecdbc13534 100644 --- a/packages/geoview-core/src/core/utils/config/reader/url-config-reader.ts +++ b/packages/geoview-core/src/core/utils/config/reader/url-config-reader.ts @@ -149,6 +149,7 @@ export class URLmapConfigReader { } mapConfig = { + mapId, map: { interaction: urlParams.i as TypeInteraction, viewSettings: { diff --git a/packages/geoview-core/src/core/utils/utilities.ts b/packages/geoview-core/src/core/utils/utilities.ts index e71c11c57ce..a619c9df3d8 100644 --- a/packages/geoview-core/src/core/utils/utilities.ts +++ b/packages/geoview-core/src/core/utils/utilities.ts @@ -345,15 +345,13 @@ export function removeCommentsFromJSON(config: string): string { * @returns {any} cleaned and parsed config object */ export function parseJSONConfig(configObjStr: string): any { - return JSON.parse( - configObjStr - // remove CR and LF from the map config - .replace(/(\r\n|\n|\r)/gm, '') - // replace apostrophes not preceded by a backslash with quotes - .replace(/(? { + api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, layerConfig, layerPhase)); + }); + } + } + + /** *************************************************************************************************************************** + * Change the layer status property and emit an event to update existing layer sets. + * + * @param {TypeLayerStatus} layerStatus The value to assign to the layer status property. + * @param {TypeLayerEntryConfig} layerEntryConfig The layer configuration affected by the change. + */ + changeLayerStatus(layerStatus: TypeLayerStatus, layerEntryConfig: TypeLayerEntryConfig) { + (layerEntryConfig as TypeBaseLayerEntryConfig).layerStatus = layerStatus; + api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerEntryConfig, layerStatus!)); + if (layerStatus === 'processed') this.changeLayerPhase(layerStatus, layerEntryConfig); + } + /** *************************************************************************************************************************** * Process recursively the list of layer entries to see if all of them are processed. * @@ -420,16 +451,13 @@ export abstract class AbstractGeoViewLayer { if (listOfLayerEntryConfig.length === 1) if (layerEntryIsGroupLayer(listOfLayerEntryConfig[0])) this.registerAllLayersToLayerSets(listOfLayerEntryConfig[0].listOfLayerEntryConfig!); - else { - this.registerToLayerSets(listOfLayerEntryConfig[0] as TypeBaseLayerEntryConfig); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, listOfLayerEntryConfig[0], 'newInstance')); - } + else this.registerToLayerSets(listOfLayerEntryConfig[0] as TypeBaseLayerEntryConfig); else if (listOfLayerEntryConfig.length > 0) listOfLayerEntryConfig.forEach((layerEntryConfig) => { if (layerEntryIsGroupLayer(layerEntryConfig)) this.registerAllLayersToLayerSets(layerEntryConfig.listOfLayerEntryConfig!); else { this.registerToLayerSets(layerEntryConfig as TypeBaseLayerEntryConfig); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, layerEntryConfig, 'newInstance')); + this.changeLayerPhase('newInstance', layerEntryConfig); } }); } @@ -454,7 +482,7 @@ export abstract class AbstractGeoViewLayer { */ createGeoViewLayers(): Promise { const promisedExecution = new Promise((resolve) => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'createGeoViewLayers')); + this.changeLayerPhase('createGeoViewLayers'); if (this.gvLayers === null) { this.getAdditionalServiceDefinition() .then(() => { @@ -487,9 +515,7 @@ export abstract class AbstractGeoViewLayer { * If the GeoView layer does not have a service definition, this method does nothing. */ protected getAdditionalServiceDefinition(): Promise { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'getAdditionalServiceDefinition') - ); + this.changeLayerPhase('getAdditionalServiceDefinition'); const promisedExecution = new Promise((resolve) => { this.getServiceMetadata().then(() => { if (this.listOfLayerEntryConfig.length) { @@ -508,7 +534,7 @@ export abstract class AbstractGeoViewLayer { * @returns {Promise} A promise that the execution is completed. */ protected getServiceMetadata(): Promise { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'getServiceMetadata')); + this.changeLayerPhase('getServiceMetadata'); const promisedExecution = new Promise((resolve) => { const metadataUrl = getLocalizedValue(this.metadataAccessPath, this.mapId); if (metadataUrl) { @@ -550,9 +576,7 @@ export abstract class AbstractGeoViewLayer { protected processListOfLayerEntryMetadata( listOfLayerEntryConfig: TypeListOfLayerEntryConfig = this.listOfLayerEntryConfig ): Promise { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'processListOfLayerEntryMetadata') - ); + this.changeLayerPhase('processListOfLayerEntryMetadata'); const promisedListOfLayerEntryProcessed = new Promise((resolve) => { const promisedAllLayerDone: Promise[] = []; listOfLayerEntryConfig.forEach((layerEntryConfig: TypeLayerEntryConfig) => { @@ -614,7 +638,7 @@ export abstract class AbstractGeoViewLayer { listOfLayerEntryConfig: TypeListOfLayerEntryConfig, layerGroup?: LayerGroup ): Promise { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'processListOfLayerEntryConfig')); + this.changeLayerPhase('processListOfLayerEntryConfig'); const promisedListOfLayerEntryProcessed = new Promise((resolve) => { if (listOfLayerEntryConfig.length === 1) { if (layerEntryIsGroupLayer(listOfLayerEntryConfig[0])) { @@ -657,22 +681,14 @@ export abstract class AbstractGeoViewLayer { baseLayer.setVisible(true); this.registerToLayerSets(listOfLayerEntryConfig[0] as TypeBaseLayerEntryConfig); if (layerGroup) layerGroup.getLayers().push(baseLayer); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload( - this.mapId, - Layer.getLayerPath(listOfLayerEntryConfig[0]), - 'processed' - ) - ); + this.changeLayerStatus('processed', listOfLayerEntryConfig[0]); resolve(layerGroup || baseLayer); } else { this.layerLoadError.push({ layer: Layer.getLayerPath(listOfLayerEntryConfig[0]), consoleMessage: `Unable to create layer ${Layer.getLayerPath(listOfLayerEntryConfig[0])} on map ${this.mapId}`, }); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(listOfLayerEntryConfig[0]), 'error') - ); + this.changeLayerStatus('error', listOfLayerEntryConfig[0]); resolve(null); } }); @@ -723,13 +739,7 @@ export abstract class AbstractGeoViewLayer { if (!layerEntryIsGroupLayer(listOfLayerEntryConfig[i])) { this.registerToLayerSets(baseLayer.get('layerEntryConfig') as TypeBaseLayerEntryConfig); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload( - this.mapId, - Layer.getLayerPath(listOfLayerEntryConfig[i]), - 'processed' - ) - ); + this.changeLayerStatus('processed', listOfLayerEntryConfig[i]); } layerGroup!.getLayers().push(baseLayer); } @@ -740,9 +750,7 @@ export abstract class AbstractGeoViewLayer { layerEntryIsGroupLayer(listOfLayerEntryConfig[i]) ? 'group' : '' } layer ${Layer.getLayerPath(listOfLayerEntryConfig[i])} on map ${this.mapId}`, }); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(listOfLayerEntryConfig[i]), 'error') - ); + this.changeLayerStatus('error', listOfLayerEntryConfig[i]); } }); resolve(layerGroup!); @@ -769,16 +777,16 @@ export abstract class AbstractGeoViewLayer { /** *************************************************************************************************************************** * Return feature information for the layer specified. If layerPathOrConfig is undefined, this.activeLayer is used. * - * @param {Pixel | Coordinate | Coordinate[]} location A pixel, a coordinate or a polygon that will be used by the query. + * @param {TypeQueryType} queryType The type of query to perform. * @param {string | TypeLayerEntryConfig | null} layerPathOrConfig Optional layer path or configuration. - * @param {TypeQueryType} queryType Optional query type, default value is 'at pixel'. + * @param {TypeLocation} location An optionsl pixel, coordinate or polygon that will be used by the query. * * @returns {Promise} The feature info table. */ getFeatureInfo( - location: Pixel | Coordinate | Coordinate[], + queryType: TypeQueryType, layerPathOrConfig: string | TypeLayerEntryConfig | null = this.activeLayer, - queryType: TypeQueryType = 'at pixel' + location: TypeLocation = null ): Promise { const queryResult = new Promise((resolve) => { const layerConfig = ( @@ -787,19 +795,22 @@ export abstract class AbstractGeoViewLayer { if (!layerConfig || !layerConfig.source?.featureInfo?.queryable) resolve([]); switch (queryType) { - case 'at pixel': + case 'all': + this.getAllFeatureInfo(layerConfig!).then((featureInfoResult) => resolve(featureInfoResult)); + break; + case 'at_pixel': this.getFeatureInfoAtPixel(location as Pixel, layerConfig!).then((featureInfoResult) => resolve(featureInfoResult)); break; - case 'at coordinate': + case 'at_coordinate': this.getFeatureInfoAtCoordinate(location as Coordinate, layerConfig!).then((featureInfoResult) => resolve(featureInfoResult)); break; - case 'at long lat': + case 'at_long_lat': this.getFeatureInfoAtLongLat(location as Coordinate, layerConfig!).then((featureInfoResult) => resolve(featureInfoResult)); break; - case 'using a bounding box': + case 'using_a_bounding_box': this.getFeatureInfoUsingBBox(location as Coordinate[], layerConfig!).then((featureInfoResult) => resolve(featureInfoResult)); break; - case 'using a polygon': + case 'using_a_polygon': this.getFeatureInfoUsingPolygon(location as Coordinate[], layerConfig!).then((featureInfoResult) => resolve(featureInfoResult)); break; default: @@ -811,6 +822,22 @@ export abstract class AbstractGeoViewLayer { return queryResult; } + /** *************************************************************************************************************************** + * Return feature information for all the features on a layer. Returns an empty array [] when the layer is + * not queryable. + * + * @param {TypeLayerEntryConfig} layerConfig The layer configuration. + * + * @returns {Promise} The feature info table. + */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + protected getAllFeatureInfo(layerConfig: TypeLayerEntryConfig): Promise { + const promisedQueryResult = new Promise((resolve) => { + resolve([]); + }); + return promisedQueryResult; + } + /** *************************************************************************************************************************** * Return feature information for all the features around the provided Pixel. Returns an empty array [] when the layer is * not queryable. @@ -905,34 +932,6 @@ export abstract class AbstractGeoViewLayer { const layerPath = Layer.getLayerPath(layerEntryConfig); if (!this.registerToLayerSetListenerFunctions[layerPath]) this.registerToLayerSetListenerFunctions[layerPath] = {}; - if (!this.registerToLayerSetListenerFunctions[layerPath].updateLayerStatus) { - this.registerToLayerSetListenerFunctions[layerPath].updateLayerStatus = (layerUpdatedPayload) => { - if (payloadIsLayerSetUpdated(layerUpdatedPayload) && layerUpdatedPayload.resultSets[layerPath]) { - layerUpdatedPayload.resultSets[layerPath].layerName = layerEntryConfig.layerName; - layerEntryConfig.layerStatus = layerUpdatedPayload.resultSets[layerPath].layerStatus; - } - }; - api.event.on( - EVENT_NAMES.LAYER_SET.UPDATED, - this.registerToLayerSetListenerFunctions[layerPath].updateLayerStatus!, - `${this.mapId}/$LegendsLayerSet$/${layerPath}/status` - ); - } - - if (!this.registerToLayerSetListenerFunctions[layerPath].updateLayerPhase) { - this.registerToLayerSetListenerFunctions[layerPath].updateLayerPhase = (layerUpdatedPayload) => { - if (payloadIsLayerSetUpdated(layerUpdatedPayload)) { - if (layerUpdatedPayload.resultSets[layerPath]) layerEntryConfig.layerPhase = layerUpdatedPayload.resultSets[layerPath].layerPhase; - if (layerUpdatedPayload.layerPath !== layerPath) this.layerPhase = layerUpdatedPayload.resultSets[layerPath].layerPhase; - } - }; - api.event.on( - EVENT_NAMES.LAYER_SET.UPDATED, - this.registerToLayerSetListenerFunctions[layerPath].updateLayerPhase!, - `${this.mapId}/$LegendsLayerSet$/${layerPath}/phase` - ); - } - if (!this.registerToLayerSetListenerFunctions[layerPath].requestLayerInventory) { // Listen to events that request a layer inventory and emit a register payload event. // This will register all existing layers to a newly created layer set. @@ -972,8 +971,8 @@ export abstract class AbstractGeoViewLayer { this.registerToLayerSetListenerFunctions[layerPath].queryLayer = (payload) => { if (payloadIsQueryLayer(payload)) { const { queryType, location, isHover } = payload; - this.getFeatureInfo(location, layerPath, queryType).then((queryResult) => { - api.event.emit(GetFeatureInfoPayload.createQueryResultPayload(this.mapId, layerPath, queryResult, isHover)); + this.getFeatureInfo(queryType, layerPath, location).then((queryResult) => { + api.event.emit(GetFeatureInfoPayload.createQueryResultPayload(this.mapId, layerPath, queryType, queryResult, isHover)); }); } }; @@ -995,24 +994,6 @@ export abstract class AbstractGeoViewLayer { const layerPath = Layer.getLayerPath(layerEntryConfig); api.event.emit(LayerSetPayload.createLayerRegistrationPayload(this.mapId, layerPath, 'remove')); - if (this.registerToLayerSetListenerFunctions[layerPath].updateLayerStatus) { - api.event.off( - EVENT_NAMES.LAYER_SET.UPDATED, - `${this.mapId}/$LegendsLayerSet$/${layerPath}/status`, - this.registerToLayerSetListenerFunctions[layerPath].updateLayerStatus - ); - delete this.registerToLayerSetListenerFunctions[layerPath].updateLayerStatus; - } - - if (this.registerToLayerSetListenerFunctions[layerPath].updateLayerPhase) { - api.event.off( - EVENT_NAMES.LAYER_SET.UPDATED, - `${this.mapId}/$LegendsLayerSet$/${layerPath}/phase`, - this.registerToLayerSetListenerFunctions[layerPath].updateLayerPhase - ); - delete this.registerToLayerSetListenerFunctions[layerPath].updateLayerPhase; - } - if (this.registerToLayerSetListenerFunctions[layerPath].requestLayerInventory) { api.event.off( EVENT_NAMES.LAYER_SET.REQUEST_LAYER_INVENTORY, diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/esri-layer-common.ts b/packages/geoview-core/src/geo/layer/geoview-layers/esri-layer-common.ts index 7f720697725..d910cb91d14 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/esri-layer-common.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/esri-layer-common.ts @@ -29,7 +29,7 @@ import { codedValueType, rangeDomainType, LayerSetPayload } from '@/api/events/p * @returns {Promise} A promise that the execution is completed. */ export function commonGetServiceMetadata(this: EsriDynamic | EsriFeature, resolve: (value: void | PromiseLike) => void) { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'getServiceMetadata')); + this.changeLayerPhase('getServiceMetadata'); const metadataUrl = getLocalizedValue(this.metadataAccessPath, this.mapId); if (metadataUrl) { getXMLHttpRequest(`${metadataUrl}?f=json`) @@ -59,7 +59,7 @@ export function commonGetServiceMetadata(this: EsriDynamic | EsriFeature, resolv * @param {TypeListOfLayerEntryConfig} listOfLayerEntryConfig The list of layer entries configuration to validate. */ export function commonValidateListOfLayerEntryConfig(this: EsriDynamic | EsriFeature, listOfLayerEntryConfig: TypeListOfLayerEntryConfig) { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'validateListOfLayerEntryConfig')); + this.changeLayerPhase('validateListOfLayerEntryConfig'); listOfLayerEntryConfig.forEach((layerEntryConfig: TypeLayerEntryConfig) => { const layerPath = Layer.getLayerPath(layerEntryConfig); if (layerEntryIsGroupLayer(layerEntryConfig)) { @@ -69,12 +69,12 @@ export function commonValidateListOfLayerEntryConfig(this: EsriDynamic | EsriFea layer: layerPath, consoleMessage: `Empty layer group (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } } - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'loading')); + this.changeLayerStatus('loading', layerEntryConfig); let esriIndex = Number(layerEntryConfig.layerId); if (Number.isNaN(esriIndex)) { @@ -82,7 +82,7 @@ export function commonValidateListOfLayerEntryConfig(this: EsriDynamic | EsriFea layer: layerPath, consoleMessage: `ESRI layerId must be a number (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } @@ -95,7 +95,7 @@ export function commonValidateListOfLayerEntryConfig(this: EsriDynamic | EsriFea layer: layerPath, consoleMessage: `ESRI layerId not found (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } @@ -129,7 +129,7 @@ export function commonValidateListOfLayerEntryConfig(this: EsriDynamic | EsriFea } if (this.esriChildHasDetectedAnError(layerEntryConfig, esriIndex)) { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/raster/abstract-geoview-raster.ts b/packages/geoview-core/src/geo/layer/geoview-layers/raster/abstract-geoview-raster.ts index bb9488b0cb0..a4b02d65657 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/raster/abstract-geoview-raster.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/raster/abstract-geoview-raster.ts @@ -39,11 +39,11 @@ export abstract class AbstractGeoViewRaster extends AbstractGeoViewLayer { addLoadendListener(layerEntryConfig: TypeLayerEntryConfig, layerType: 'tile' | 'image'): void { let loadErrorHandler: () => void; const loadEndHandler = () => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerEntryConfig, 'loaded')); + this.changeLayerStatus('loaded', layerEntryConfig); layerEntryConfig.gvLayer!.get('source').un(`${layerType}loaderror`, loadErrorHandler); }; loadErrorHandler = () => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerEntryConfig, 'error')); + this.changeLayerStatus('error', layerEntryConfig); layerEntryConfig.gvLayer!.get('source').un(`${layerType}loadend`, loadEndHandler); }; diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-dynamic.ts b/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-dynamic.ts index 22645ed77c9..be95265894c 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-dynamic.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-dynamic.ts @@ -255,7 +255,7 @@ export class EsriDynamic extends AbstractGeoViewRaster { */ processOneLayerEntry(layerEntryConfig: TypeEsriDynamicLayerEntryConfig): Promise { const promisedVectorLayer = new Promise((resolve) => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, layerEntryConfig, 'processOneLayerEntry')); + this.changeLayerPhase('processOneLayerEntry', layerEntryConfig); const sourceOptions: SourceOptions = {}; sourceOptions.attributions = [(this.metadata!.copyrightText ? this.metadata!.copyrightText : '') as string]; sourceOptions.url = getLocalizedValue(layerEntryConfig.source.dataAccessPath!, this.mapId); diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/raster/image-static.ts b/packages/geoview-core/src/geo/layer/geoview-layers/raster/image-static.ts index efcb1664ffc..b6ff9b9034e 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/raster/image-static.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/raster/image-static.ts @@ -95,7 +95,7 @@ export class ImageStatic extends AbstractGeoViewRaster { * @returns {Promise} A promise that the execution is completed. */ protected getServiceMetadata(): Promise { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'getServiceMetadata')); + this.changeLayerPhase('getServiceMetadata'); const promisedExecution = new Promise((resolve) => { resolve(); }); @@ -198,9 +198,7 @@ export class ImageStatic extends AbstractGeoViewRaster { * @returns {TypeListOfLayerEntryConfig} A new list of layer entries configuration with deleted error layers. */ protected validateListOfLayerEntryConfig(listOfLayerEntryConfig: TypeListOfLayerEntryConfig) { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'validateListOfLayerEntryConfig') - ); + this.changeLayerPhase('validateListOfLayerEntryConfig'); listOfLayerEntryConfig.forEach((layerEntryConfig: TypeLayerEntryConfig) => { const layerPath = Layer.getLayerPath(layerEntryConfig); if (layerEntryIsGroupLayer(layerEntryConfig)) { @@ -210,12 +208,12 @@ export class ImageStatic extends AbstractGeoViewRaster { layer: layerPath, consoleMessage: `Empty layer group (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } } - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'loading')); + this.changeLayerStatus('loading', layerEntryConfig); // When no metadata are provided, all layers are considered valid. if (!this.metadata) return; @@ -230,7 +228,7 @@ export class ImageStatic extends AbstractGeoViewRaster { layer: layerPath, consoleMessage: `GeoJSON layer not found (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } return; @@ -251,7 +249,7 @@ export class ImageStatic extends AbstractGeoViewRaster { */ processOneLayerEntry(layerEntryConfig: TypeImageStaticLayerEntryConfig): Promise { const promisedVectorLayer = new Promise((resolve) => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, layerEntryConfig, 'processOneLayerEntry')); + this.changeLayerPhase('processOneLayerEntry', layerEntryConfig); if (!layerEntryConfig.source.extent) throw new Error('Parameter extent is not defined in source element of layerEntryConfig.'); const sourceOptions: SourceOptions = { diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/raster/vector-tiles.ts b/packages/geoview-core/src/geo/layer/geoview-layers/raster/vector-tiles.ts index 984a390f91e..acf889050a2 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/raster/vector-tiles.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/raster/vector-tiles.ts @@ -131,9 +131,7 @@ export class VectorTiles extends AbstractGeoViewRaster { * @param {TypeListOfLayerEntryConfig} listOfLayerEntryConfig The list of layer entries configuration to validate. */ protected validateListOfLayerEntryConfig(listOfLayerEntryConfig: TypeListOfLayerEntryConfig) { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'validateListOfLayerEntryConfig') - ); + this.changeLayerPhase('validateListOfLayerEntryConfig'); listOfLayerEntryConfig.forEach((layerEntryConfig: TypeLayerEntryConfig) => { const layerPath = Layer.getLayerPath(layerEntryConfig); if (layerEntryIsGroupLayer(layerEntryConfig)) { @@ -143,13 +141,12 @@ export class VectorTiles extends AbstractGeoViewRaster { layer: layerPath, consoleMessage: `Empty layer group (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } } - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'loading')); - + this.changeLayerStatus('loading', layerEntryConfig); // When no metadata are provided, all layers are considered valid. if (!this.metadata) return; @@ -171,7 +168,7 @@ export class VectorTiles extends AbstractGeoViewRaster { */ processOneLayerEntry(layerEntryConfig: TypeVectorTilesLayerEntryConfig): Promise { const promisedVectorLayer = new Promise((resolve) => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, layerEntryConfig, 'processOneLayerEntry')); + this.changeLayerPhase('processOneLayerEntry', layerEntryConfig); const sourceOptions: SourceOptions = { url: getLocalizedValue(layerEntryConfig.source.dataAccessPath, this.mapId), }; diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/raster/wms.ts b/packages/geoview-core/src/geo/layer/geoview-layers/raster/wms.ts index 38445f998ee..78c9c098df3 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/raster/wms.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/raster/wms.ts @@ -114,7 +114,7 @@ export class WMS extends AbstractGeoViewRaster { * @returns {Promise} A promise that the execution is completed. */ protected getServiceMetadata(): Promise { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'getServiceMetadata')); + this.changeLayerPhase('getServiceMetadata'); const promisedExecution = new Promise((resolve) => { const metadataUrl = getLocalizedValue(this.metadataAccessPath, this.mapId); if (metadataUrl) { @@ -135,15 +135,11 @@ export class WMS extends AbstractGeoViewRaster { this.processMetadataInheritance(); resolve(); } else { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(layersToQuery[0]), 'error') - ); + this.changeLayerStatus('error', layersToQuery[0]); } }) .catch((reason) => { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(layersToQuery[0]), 'error') - ); + this.changeLayerStatus('error', layersToQuery[0]); }); } else { // Uses GetCapabilities to get the metadata. However, to allow geomet metadata to be retrieved using the non-standard @@ -168,16 +164,11 @@ export class WMS extends AbstractGeoViewRaster { Promise.all(promisedArrayOfMetadata) .then((arrayOfMetadata) => { for (i = 0; i < arrayOfMetadata.length && !arrayOfMetadata[i]?.Capability; i++) - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(layersToQuery[i]), 'error') - ); + this.changeLayerStatus('error', layersToQuery[i]); this.metadata = i < arrayOfMetadata.length ? arrayOfMetadata[i] : null; if (this.metadata) { for (i++; i < arrayOfMetadata.length; i++) { - if (!arrayOfMetadata[i]?.Capability) - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(layersToQuery[i]), 'error') - ); + if (!arrayOfMetadata[i]?.Capability) this.changeLayerStatus('error', layersToQuery[i]); else if (!this.getLayerMetadataEntry(layersToQuery[i].layerId)) { const metadataLayerPathToAdd = this.getMetadataLayerPath( layersToQuery[i].layerId, @@ -238,7 +229,7 @@ export class WMS extends AbstractGeoViewRaster { * @returns {Promise} A promise that the execution is completed. */ private getXmlServiceMetadata(metadataUrl: string): Promise { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'getXmlServiceMetadata')); + this.changeLayerPhase('getXmlServiceMetadata'); const promisedExecution = new Promise((resolve) => { const parser = new WMSCapabilities(); fetch(metadataUrl) @@ -408,9 +399,7 @@ export class WMS extends AbstractGeoViewRaster { * @param {TypeListOfLayerEntryConfig} listOfLayerEntryConfig The list of layer entries configuration to validate. */ protected validateListOfLayerEntryConfig(listOfLayerEntryConfig: TypeListOfLayerEntryConfig) { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'validateListOfLayerEntryConfig') - ); + this.changeLayerPhase('validateListOfLayerEntryConfig'); listOfLayerEntryConfig.forEach((layerEntryConfig: TypeLayerEntryConfig) => { const layerPath = Layer.getLayerPath(layerEntryConfig); if (layerEntryIsGroupLayer(layerEntryConfig)) { @@ -420,13 +409,13 @@ export class WMS extends AbstractGeoViewRaster { layer: layerPath, consoleMessage: `Empty layer group (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); } return; } if ((layerEntryConfig as TypeBaseLayerEntryConfig).layerStatus !== 'error') { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'loading')); + this.changeLayerStatus('loading', layerEntryConfig); const layerFound = this.getLayerMetadataEntry(layerEntryConfig.layerId); if (!layerFound) { @@ -434,7 +423,7 @@ export class WMS extends AbstractGeoViewRaster { layer: layerPath, consoleMessage: `Layer metadata not found (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } @@ -524,7 +513,7 @@ export class WMS extends AbstractGeoViewRaster { */ processOneLayerEntry(layerEntryConfig: TypeBaseLayerEntryConfig): Promise { const promisedVectorLayer = new Promise((resolve) => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, layerEntryConfig, 'processOneLayerEntry')); + this.changeLayerPhase('processOneLayerEntry', layerEntryConfig); if (geoviewEntryIsWMS(layerEntryConfig)) { const layerCapabilities = this.getLayerMetadataEntry(layerEntryConfig.layerId); if (layerCapabilities) { diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/raster/xyz-tiles.ts b/packages/geoview-core/src/geo/layer/geoview-layers/raster/xyz-tiles.ts index f3e4079b0e9..88a82a60e77 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/raster/xyz-tiles.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/raster/xyz-tiles.ts @@ -132,9 +132,7 @@ export class XYZTiles extends AbstractGeoViewRaster { * @param {TypeListOfLayerEntryConfig} listOfLayerEntryConfig The list of layer entries configuration to validate. */ protected validateListOfLayerEntryConfig(listOfLayerEntryConfig: TypeListOfLayerEntryConfig) { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'validateListOfLayerEntryConfig') - ); + this.changeLayerPhase('validateListOfLayerEntryConfig'); listOfLayerEntryConfig.forEach((layerEntryConfig: TypeLayerEntryConfig) => { const layerPath = Layer.getLayerPath(layerEntryConfig); if (layerEntryIsGroupLayer(layerEntryConfig)) { @@ -144,12 +142,12 @@ export class XYZTiles extends AbstractGeoViewRaster { layer: layerPath, consoleMessage: `Empty layer group (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } } - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'loading')); + this.changeLayerStatus('loading', layerEntryConfig); // When no metadata are provided, all layers are considered valid. if (!this.metadata) return; @@ -164,7 +162,7 @@ export class XYZTiles extends AbstractGeoViewRaster { layer: layerPath, consoleMessage: `XYZ layer not found (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } return; @@ -185,7 +183,7 @@ export class XYZTiles extends AbstractGeoViewRaster { */ processOneLayerEntry(layerEntryConfig: TypeXYZTilesLayerEntryConfig): Promise { const promisedVectorLayer = new Promise((resolve) => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, layerEntryConfig, 'processOneLayerEntry')); + this.changeLayerPhase('processOneLayerEntry', layerEntryConfig); const sourceOptions: SourceOptions = { url: getLocalizedValue(layerEntryConfig.source.dataAccessPath, this.mapId), }; diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/vector/abstract-geoview-vector.ts b/packages/geoview-core/src/geo/layer/geoview-layers/vector/abstract-geoview-vector.ts index 3e27891df14..52c72a352f6 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/vector/abstract-geoview-vector.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/vector/abstract-geoview-vector.ts @@ -24,7 +24,7 @@ import { } from '@/geo/map/map-schema-types'; import { api } from '@/app'; import { getLocalizedValue } from '@/core/utils/utilities'; -import { LayerSetPayload, TypeArrayOfFeatureInfoEntries } from '@/api/events/payloads'; +import { TypeArrayOfFeatureInfoEntries } from '@/api/events/payloads'; import { NodeType } from '@/geo/renderer/geoview-renderer-types'; /* ******************************************************************************************************************************* @@ -71,7 +71,7 @@ export abstract class AbstractGeoViewVector extends AbstractGeoViewLayer { protected processOneLayerEntry(layerEntryConfig: TypeBaseLayerEntryConfig): Promise { layerEntryConfig.layerPhase = 'processOneLayerEntry'; const promisedVectorLayer = new Promise((resolve) => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, layerEntryConfig, 'processOneLayerEntry')); + this.changeLayerPhase('processOneLayerEntry', layerEntryConfig); const vectorSource = this.createVectorSource(layerEntryConfig); const vectorLayer = this.createVectorLayer(layerEntryConfig as TypeVectorLayerEntryConfig, vectorSource); resolve(vectorLayer); @@ -172,11 +172,11 @@ export abstract class AbstractGeoViewVector extends AbstractGeoViewLayer { let featuresLoadErrorHandler: () => void; const featuresLoadEndHandler = () => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerEntryConfig, 'loaded')); + this.changeLayerStatus('loaded', layerEntryConfig); vectorSource.un('featuresloaderror', featuresLoadErrorHandler); }; featuresLoadErrorHandler = () => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerEntryConfig, 'error')); + this.changeLayerStatus('error', layerEntryConfig); vectorSource.un('featuresloadend', featuresLoadEndHandler); }; @@ -262,20 +262,17 @@ export abstract class AbstractGeoViewVector extends AbstractGeoViewLayer { /** *************************************************************************************************************************** * Return feature information for all the features stored in the layer. * - * @param {string | TypeLayerEntryConfig | null} layerPathOrConfig Optional layer path or configuration. + * @param {TypeLayerEntryConfig} layerEntryConfig The layer configuration. * * @returns {TypeArrayOfFeatureInfoEntries} The feature info table. */ - getAllFeatureInfo( - layerPathOrConfig: string | TypeLayerEntryConfig | null | undefined = this.activeLayer - ): Promise { + protected getAllFeatureInfo(layerEntryConfig: TypeLayerEntryConfig): Promise { const promisedQueryResult = new Promise((resolve) => { - const layerConfig = typeof layerPathOrConfig === 'string' ? this.getLayerConfig(layerPathOrConfig) : layerPathOrConfig; - if (!layerConfig?.gvLayer) resolve([]); + if (!layerEntryConfig?.gvLayer) resolve([]); else this.formatFeatureInfoResult( - (layerConfig.gvLayer as VectorLayer>).getSource()!.getFeatures(), - layerConfig as TypeVectorLayerEntryConfig + (layerEntryConfig.gvLayer as VectorLayer>).getSource()!.getFeatures(), + layerEntryConfig as TypeVectorLayerEntryConfig ).then((arrayOfFeatureInfoEntries) => { resolve(arrayOfFeatureInfoEntries); }); diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/vector/geojson.ts b/packages/geoview-core/src/geo/layer/geoview-layers/vector/geojson.ts index 9f007444c94..739e8b9f59a 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/vector/geojson.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/vector/geojson.ts @@ -24,7 +24,6 @@ import { getLocalizedValue } from '@/core/utils/utilities'; import { Cast, toJsonObject } from '@/core/types/global-types'; import { api } from '@/app'; import { Layer } from '../../layer'; -import { LayerSetPayload } from '@/api/events/payloads'; export interface TypeSourceGeoJSONInitialConfig extends Omit { format: 'GeoJSON'; @@ -122,9 +121,7 @@ export class GeoJSON extends AbstractGeoViewVector { * @param {TypeListOfLayerEntryConfig} listOfLayerEntryConfig The list of layer entries configuration to validate. */ protected validateListOfLayerEntryConfig(listOfLayerEntryConfig: TypeListOfLayerEntryConfig) { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'validateListOfLayerEntryConfig') - ); + this.changeLayerPhase('validateListOfLayerEntryConfig'); listOfLayerEntryConfig.forEach((layerEntryConfig: TypeLayerEntryConfig) => { const layerPath = Layer.getLayerPath(layerEntryConfig); if (layerEntryIsGroupLayer(layerEntryConfig)) { @@ -134,12 +131,12 @@ export class GeoJSON extends AbstractGeoViewVector { layer: layerPath, consoleMessage: `Empty layer group (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); } return; } - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'loading')); + this.changeLayerStatus('loading', layerEntryConfig); // When no metadata are provided, all layers are considered valid. if (!this.metadata) return; @@ -157,7 +154,7 @@ export class GeoJSON extends AbstractGeoViewVector { layer: layerPath, consoleMessage: `GeoJSON layer not found (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } return; diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/vector/geopackage.ts b/packages/geoview-core/src/geo/layer/geoview-layers/vector/geopackage.ts index 0c6854daa50..7c31f7afce9 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/vector/geopackage.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/vector/geopackage.ts @@ -38,7 +38,6 @@ import { getLocalizedValue } from '@/core/utils/utilities'; import { api } from '@/app'; import { Layer } from '../../layer'; -import { LayerSetPayload } from '@/api/events/payloads'; export interface TypeSourceGeoPackageInitialConfig extends TypeVectorSourceInitialConfig { format: 'GeoPackage'; @@ -138,7 +137,7 @@ export class GeoPackage extends AbstractGeoViewVector { * @returns {Promise} A promise that the execution is completed. */ protected getServiceMetadata(): Promise { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'getServiceMetadata')); + this.changeLayerPhase('getServiceMetadata'); const promisedExecution = new Promise((resolve) => { resolve(); }); @@ -152,9 +151,7 @@ export class GeoPackage extends AbstractGeoViewVector { * @param {TypeListOfLayerEntryConfig} listOfLayerEntryConfig The list of layer entries configuration to validate. */ protected validateListOfLayerEntryConfig(listOfLayerEntryConfig: TypeListOfLayerEntryConfig) { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'validateListOfLayerEntryConfig') - ); + this.changeLayerPhase('validateListOfLayerEntryConfig'); return listOfLayerEntryConfig.forEach((layerEntryConfig: TypeLayerEntryConfig) => { const layerPath = Layer.getLayerPath(layerEntryConfig); if (layerEntryIsGroupLayer(layerEntryConfig)) { @@ -164,12 +161,12 @@ export class GeoPackage extends AbstractGeoViewVector { layer: layerPath, consoleMessage: `Empty layer group (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } } - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'loading')); + this.changeLayerStatus('loading', layerEntryConfig); // When no metadata are provided, all layers are considered valid. if (!this.metadata) return; @@ -183,7 +180,7 @@ export class GeoPackage extends AbstractGeoViewVector { layer: layerPath, consoleMessage: `GeoPackage feature layer not found (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } @@ -228,7 +225,7 @@ export class GeoPackage extends AbstractGeoViewVector { listOfLayerEntryConfig: TypeListOfLayerEntryConfig, layerGroup?: LayerGroup ): Promise { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'processListOfLayerEntryConfig')); + this.changeLayerPhase('processListOfLayerEntryConfig'); const promisedListOfLayerEntryProcessed = new Promise((resolve) => { // Single group layer handled recursively if (listOfLayerEntryConfig.length === 1 && layerEntryIsGroupLayer(listOfLayerEntryConfig[0])) { @@ -268,17 +265,13 @@ export class GeoPackage extends AbstractGeoViewVector { this.processOneGeopackage(layerEntryConfig as TypeBaseLayerEntryConfig).then((layers) => { if (layers) { layerGroup!.getLayers().push(layers); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(layerEntryConfig), 'processed') - ); + this.changeLayerStatus('processed', layerEntryConfig); } else { this.layerLoadError.push({ layer: Layer.getLayerPath(listOfLayerEntryConfig[0]), consoleMessage: `Unable to create layer ${Layer.getLayerPath(layerEntryConfig)} on map ${this.mapId}`, }); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(layerEntryConfig), 'error') - ); + this.changeLayerStatus('error', layerEntryConfig); } }); } @@ -288,18 +281,14 @@ export class GeoPackage extends AbstractGeoViewVector { } else { this.processOneGeopackage(listOfLayerEntryConfig[0] as TypeBaseLayerEntryConfig, layerGroup).then((layer) => { if (layer) { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(listOfLayerEntryConfig[0]), 'processed') - ); + this.changeLayerStatus('processed', listOfLayerEntryConfig[0]); resolve(layer); } else { this.layerLoadError.push({ layer: Layer.getLayerPath(listOfLayerEntryConfig[0]), consoleMessage: `Unable to create layer ${Layer.getLayerPath(listOfLayerEntryConfig[0])} on map ${this.mapId}`, }); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(listOfLayerEntryConfig[0]), 'error') - ); + this.changeLayerStatus('error', listOfLayerEntryConfig[0]); } }); } @@ -414,15 +403,11 @@ export class GeoPackage extends AbstractGeoViewVector { let featuresLoadErrorHandler: () => void; const featuresLoadEndHandler = () => { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(layerEntryConfig), 'loaded') - ); + this.changeLayerStatus('loaded', layerEntryConfig); vectorSource.un('featuresloaderror', featuresLoadErrorHandler); }; featuresLoadErrorHandler = () => { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(layerEntryConfig), 'error') - ); + this.changeLayerStatus('error', layerEntryConfig); vectorSource.un('featuresloadend', featuresLoadEndHandler); }; @@ -602,11 +587,11 @@ export class GeoPackage extends AbstractGeoViewVector { let loadErrorHandler: () => void; const loadEndHandler = () => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerEntryConfig, 'loaded')); + this.changeLayerStatus('loaded', layerEntryConfig); source.un('featuresloaderror', loadErrorHandler); }; loadErrorHandler = () => { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerEntryConfig, 'error')); + this.changeLayerStatus('error', layerEntryConfig); source.un('featuresloadend', loadEndHandler); }; @@ -614,7 +599,7 @@ export class GeoPackage extends AbstractGeoViewVector { source.once('featuresloaderror', loadErrorHandler); const vectorLayer = this.createVectorLayer(layerEntryConfig as TypeVectorLayerEntryConfig, source); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(layerEntryConfig), 'processed')); + this.changeLayerStatus('processed', layerEntryConfig); resolve(vectorLayer); }); @@ -645,13 +630,7 @@ export class GeoPackage extends AbstractGeoViewVector { baseLayer.setVisible(false); if (!layerGroup) layerGroup = this.createLayerGroup(unclusteredLayerConfig.parentLayerConfig as TypeLayerEntryConfig); layerGroup.getLayers().push(baseLayer); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload( - this.mapId, - Layer.getLayerPath(unclusteredLayerConfig), - 'processed' - ) - ); + this.changeLayerStatus('processed', unclusteredLayerConfig); } }); @@ -661,9 +640,7 @@ export class GeoPackage extends AbstractGeoViewVector { this.processOneGeopackageLayer(layerEntryConfig, layers[0], slds).then((baseLayer) => { if (baseLayer) { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(layerEntryConfig), 'processed') - ); + this.changeLayerStatus('processed', layerEntryConfig); if (layerGroup) layerGroup.getLayers().push(baseLayer); resolve(layerGroup || baseLayer); } else { @@ -671,9 +648,7 @@ export class GeoPackage extends AbstractGeoViewVector { layer: Layer.getLayerPath(layerEntryConfig), consoleMessage: `Unable to create layer ${Layer.getLayerPath(layerEntryConfig)} on map ${this.mapId}`, }); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(layerEntryConfig), 'error') - ); + this.changeLayerStatus('error', layerEntryConfig); resolve(null); } }); @@ -695,13 +670,7 @@ export class GeoPackage extends AbstractGeoViewVector { if (baseLayer) { baseLayer.setVisible(false); newLayerGroup.getLayers().push(baseLayer); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload( - this.mapId, - Layer.getLayerPath(unclusteredLayerConfig), - 'processed' - ) - ); + this.changeLayerStatus('processed', unclusteredLayerConfig); } }); @@ -713,17 +682,13 @@ export class GeoPackage extends AbstractGeoViewVector { if (baseLayer) { (layerEntryConfig as unknown as TypeLayerGroupEntryConfig).listOfLayerEntryConfig!.push(newLayerEntryConfig); newLayerGroup.getLayers().push(baseLayer); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(newLayerEntryConfig), 'processed') - ); + this.changeLayerStatus('processed', newLayerEntryConfig); } else { this.layerLoadError.push({ layer: Layer.getLayerPath(layerEntryConfig), consoleMessage: `Unable to create layer ${Layer.getLayerPath(layerEntryConfig)} on map ${this.mapId}`, }); - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, Layer.getLayerPath(newLayerEntryConfig), 'error') - ); + this.changeLayerStatus('error', newLayerEntryConfig); resolve(null); } }); diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/vector/ogc-feature.ts b/packages/geoview-core/src/geo/layer/geoview-layers/vector/ogc-feature.ts index a768a6a8820..90ee400a9ac 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/vector/ogc-feature.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/vector/ogc-feature.ts @@ -25,7 +25,6 @@ import { import { getLocalizedValue } from '@/core/utils/utilities'; import { api } from '@/app'; import { Layer } from '../../layer'; -import { LayerSetPayload } from '@/api/events/payloads'; export interface TypeSourceOgcFeatureInitialConfig extends TypeVectorSourceInitialConfig { format: 'featureAPI'; @@ -129,7 +128,7 @@ export class OgcFeature extends AbstractGeoViewVector { * @returns {Promise} A promise that the execution is completed. */ protected getServiceMetadata(): Promise { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'getServiceMetadata')); + this.changeLayerPhase('getServiceMetadata'); const promisedExecution = new Promise((resolve) => { const metadataUrl = getLocalizedValue(this.metadataAccessPath, this.mapId); if (metadataUrl) { @@ -157,9 +156,7 @@ export class OgcFeature extends AbstractGeoViewVector { * @param {TypeListOfLayerEntryConfig} listOfLayerEntryConfig The list of layer entries configuration to validate. */ protected validateListOfLayerEntryConfig(listOfLayerEntryConfig: TypeListOfLayerEntryConfig) { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'validateListOfLayerEntryConfig') - ); + this.changeLayerPhase('validateListOfLayerEntryConfig'); listOfLayerEntryConfig.forEach((layerEntryConfig: TypeLayerEntryConfig) => { const layerPath = Layer.getLayerPath(layerEntryConfig); if (layerEntryIsGroupLayer(layerEntryConfig)) { @@ -169,12 +166,12 @@ export class OgcFeature extends AbstractGeoViewVector { layer: layerPath, consoleMessage: `Empty layer group (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } } - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'loading')); + this.changeLayerStatus('loading', layerEntryConfig); // Note that the code assumes ogc-feature collections does not contains metadata layer group. If you need layer group, // you can define them in the configuration section. @@ -185,7 +182,7 @@ export class OgcFeature extends AbstractGeoViewVector { layer: layerPath, consoleMessage: `OGC feature layer not found (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/vector/wfs.ts b/packages/geoview-core/src/geo/layer/geoview-layers/vector/wfs.ts index 910b897ff42..3c52d330bef 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/vector/wfs.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/vector/wfs.ts @@ -24,7 +24,6 @@ import { import { getLocalizedValue, getXMLHttpRequest, xmlToJson, findPropertyNameByRegex } from '@/core/utils/utilities'; import { api } from '@/app'; import { Layer } from '../../layer'; -import { LayerSetPayload } from '@/api/events/payloads'; export interface TypeSourceWFSVectorInitialConfig extends TypeVectorSourceInitialConfig { format: 'WFS'; @@ -125,7 +124,7 @@ export class WFS extends AbstractGeoViewVector { * @returns {Promise} A promise that the execution is completed. */ protected getServiceMetadata(): Promise { - api.event.emit(LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'getServiceMetadata')); + this.changeLayerPhase('getServiceMetadata'); const promisedExecution = new Promise((resolve) => { let metadataUrl = getLocalizedValue(this.metadataAccessPath, this.mapId) as string; @@ -168,9 +167,7 @@ export class WFS extends AbstractGeoViewVector { * @param {TypeListOfLayerEntryConfig} listOfLayerEntryConfig The list of layer entries configuration to validate. */ protected validateListOfLayerEntryConfig(listOfLayerEntryConfig: TypeListOfLayerEntryConfig) { - api.event.emit( - LayerSetPayload.createLayerSetChangeLayerPhasePayload(this.mapId, this.geoviewLayerId, 'validateListOfLayerEntryConfig') - ); + this.changeLayerPhase('validateListOfLayerEntryConfig'); listOfLayerEntryConfig.forEach((layerEntryConfig: TypeLayerEntryConfig) => { const layerPath = Layer.getLayerPath(layerEntryConfig); if (layerEntryIsGroupLayer(layerEntryConfig)) { @@ -180,12 +177,12 @@ export class WFS extends AbstractGeoViewVector { layer: layerPath, consoleMessage: `Empty layer group (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } } - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'loading')); + this.changeLayerStatus('loading', layerEntryConfig); // Note that the code assumes wfs feature type list does not contains metadata layer group. If you need layer group, // you can define them in the configuration section. @@ -205,7 +202,7 @@ export class WFS extends AbstractGeoViewVector { layer: layerPath, consoleMessage: `WFS feature layer not found (mapId: ${this.mapId}, layerPath: ${layerPath})`, }); - api.event.emit(LayerSetPayload.createLayerSetChangeLayerStatusPayload(this.mapId, layerPath, 'error')); + this.changeLayerStatus('error', layerEntryConfig); return; } diff --git a/packages/geoview-core/src/geo/layer/layer.ts b/packages/geoview-core/src/geo/layer/layer.ts index 204c9dcde92..15e355ea5fd 100644 --- a/packages/geoview-core/src/geo/layer/layer.ts +++ b/packages/geoview-core/src/geo/layer/layer.ts @@ -268,7 +268,7 @@ export class Layer { const layerPath = Layer.getLayerPath(layerEntryConfig); if (this.registeredLayers[layerPath]) return false; this.registeredLayers[layerPath] = layerEntryConfig; - (this.registeredLayers[layerPath] as TypeBaseLayerEntryConfig).layerStatus = 'newInstance'; + this.geoviewLayers[layerPath.split('/')[0]].changeLayerStatus('newInstance', layerEntryConfig); return true; } diff --git a/packages/geoview-core/src/geo/map/map-schema-types.ts b/packages/geoview-core/src/geo/map/map-schema-types.ts index 1056fd24832..80a397532c7 100644 --- a/packages/geoview-core/src/geo/map/map-schema-types.ts +++ b/packages/geoview-core/src/geo/map/map-schema-types.ts @@ -615,7 +615,7 @@ export const layerEntryIsGeocore = (verifyIfLayer: TypeLayerEntryConfig): verify /** ****************************************************************************************************************************** * Valid values for the LayerStatus property */ -export type TypeLayerStatus = 'newInstance' | 'loading' | 'processed' | 'loaded' | 'error' | undefined; +export type TypeLayerStatus = 'newInstance' | 'loading' | 'processed' | 'loaded' | 'error'; /** ****************************************************************************************************************************** * Base type used to define a GeoView layer to display on the map. diff --git a/packages/geoview-core/src/geo/map/map.ts b/packages/geoview-core/src/geo/map/map-viewer.ts similarity index 99% rename from packages/geoview-core/src/geo/map/map.ts rename to packages/geoview-core/src/geo/map/map-viewer.ts index 07601b522d3..62adc55ebb4 100644 --- a/packages/geoview-core/src/geo/map/map.ts +++ b/packages/geoview-core/src/geo/map/map-viewer.ts @@ -142,13 +142,8 @@ export class MapViewer { * @param {i18n} i18instance language instance */ constructor(mapFeaturesConfig: TypeMapFeaturesConfig, i18instance: i18n) { - this.mapId = mapFeaturesConfig.mapId!; - - // add map viewer instance to api - api.maps[this.mapId] = this; - + this.mapId = mapFeaturesConfig.mapId; this.mapFeaturesConfig = mapFeaturesConfig; - this.displayLanguage = mapFeaturesConfig.displayLanguage!; this.currentProjection = mapFeaturesConfig.map.viewSettings.projection; this.i18nInstance = i18instance; diff --git a/packages/geoview-core/src/geo/utils/feature-info-layer-set.ts b/packages/geoview-core/src/geo/utils/feature-info-layer-set.ts index aaf033d39dd..41a75587b41 100644 --- a/packages/geoview-core/src/geo/utils/feature-info-layer-set.ts +++ b/packages/geoview-core/src/geo/utils/feature-info-layer-set.ts @@ -8,6 +8,7 @@ import { TypeFeatureInfoResultSets, payloadIsAMapMouseEvent, payloadIsALngLat, + ArrayOfQueryTypes, } from '@/api/events/payloads'; import { api } from '@/app'; import { LayerSet } from './layer-set'; @@ -40,6 +41,7 @@ export class FeatureInfoLayerSet { * */ private constructor(mapId: string) { + // This function determines whether a layer can be registered. const registrationConditionFunction = (layerPath: string): boolean => { const layerEntryConfig = api.maps[this.mapId].layer.registeredLayers[layerPath]; if (layerEntryConfig?.source) { @@ -47,8 +49,23 @@ export class FeatureInfoLayerSet { } return false; }; + + // This function is used to initialise the date property of the layer path entry. + const registrationUserDataInitialisation = (layerPath: string) => { + this.resultSets[layerPath].data = {}; + ArrayOfQueryTypes.forEach((property) => { + this.resultSets[layerPath].data[property] = undefined; + }); + }; + this.mapId = mapId; - this.layerSet = new LayerSet(mapId, `${mapId}/$FeatureInfoLayerSet$`, this.resultSets, registrationConditionFunction); + this.layerSet = new LayerSet( + mapId, + `${mapId}/FeatureInfoLayerSet`, + this.resultSets, + registrationConditionFunction, + registrationUserDataInitialisation + ); // Listen to "map click"-"crosshair enter" and send a query layers event to queryable layers. These layers will return a result set of features. api.event.on( @@ -56,9 +73,9 @@ export class FeatureInfoLayerSet { (payload) => { if (payloadIsAMapMouseEvent(payload)) { Object.keys(this.resultSets).forEach((layerPath) => { - this.resultSets[layerPath].data = undefined; + this.resultSets[layerPath].data.at_long_lat = undefined; }); - api.event.emit(GetFeatureInfoPayload.createQueryLayerPayload(this.mapId, 'at long lat', payload.coordinates.lnglat, false)); + api.event.emit(GetFeatureInfoPayload.createQueryLayerPayload(this.mapId, 'at_long_lat', payload.coordinates.lnglat, false)); } }, this.mapId @@ -69,9 +86,9 @@ export class FeatureInfoLayerSet { (payload) => { if (payloadIsALngLat(payload)) { Object.keys(this.resultSets).forEach((layerPath) => { - this.resultSets[layerPath].data = undefined; + this.resultSets[layerPath].data.at_long_lat = undefined; }); - api.event.emit(GetFeatureInfoPayload.createQueryLayerPayload(this.mapId, 'at long lat', payload.lnglat, false)); + api.event.emit(GetFeatureInfoPayload.createQueryLayerPayload(this.mapId, 'at_long_lat', payload.lnglat, false)); } }, this.mapId @@ -82,34 +99,55 @@ export class FeatureInfoLayerSet { debounce((payload) => { if (payloadIsAMapMouseEvent(payload)) { Object.keys(this.resultSets).forEach((layerPath) => { - this.resultSets[layerPath].data = undefined; + this.resultSets[layerPath].data.at_pixel = undefined; }); - api.event.emit(GetFeatureInfoPayload.createQueryLayerPayload(this.mapId, 'at pixel', payload.coordinates.pixel, true)); + api.event.emit(GetFeatureInfoPayload.createQueryLayerPayload(this.mapId, 'at_pixel', payload.coordinates.pixel, true)); } }, 750), this.mapId ); + api.event.on( + EVENT_NAMES.MAP.EVENT_MAP_GET_ALL_FEATURES, + () => { + Object.keys(this.resultSets).forEach((layerPath) => { + this.resultSets[layerPath].data.all = undefined; + }); + api.event.emit(GetFeatureInfoPayload.createQueryLayerPayload(this.mapId, 'all')); + }, + this.mapId + ); + api.event.on( EVENT_NAMES.GET_FEATURE_INFO.QUERY_RESULT, (payload) => { if (payloadIsQueryResult(payload)) { - const { layerPath, arrayOfRecords, isHover } = payload; + const { layerPath, queryType, arrayOfRecords, isHover } = payload; if (layerPath in this.resultSets) { - this.resultSets[layerPath].data = arrayOfRecords; + this.resultSets[layerPath].data[queryType] = arrayOfRecords; } const allDone = Object.keys(this.resultSets).reduce((doneFlag, layerPathToTest) => { - return doneFlag && this.resultSets[layerPathToTest].data !== undefined; + return doneFlag && this.resultSets[layerPathToTest].data[queryType] !== undefined; }, true); if (allDone && !isHover) { api.event.emit( - GetFeatureInfoPayload.createAllQueriesDonePayload(`${this.layerSet.layerSetId}`, this.layerSet.layerSetId, this.resultSets) + GetFeatureInfoPayload.createAllQueriesDonePayload( + `${this.layerSet.layerSetId}`, + queryType, + this.layerSet.layerSetId, + this.resultSets + ) ); } else if (allDone && isHover) { api.event.emit( - GetFeatureInfoPayload.createHoverQueryDonePayload(`${this.layerSet.layerSetId}`, this.layerSet.layerSetId, this.resultSets) + GetFeatureInfoPayload.createHoverQueryDonePayload( + `${this.layerSet.layerSetId}`, + queryType, + this.layerSet.layerSetId, + this.resultSets + ) ); } } @@ -131,4 +169,13 @@ export class FeatureInfoLayerSet { FeatureInfoLayerSet.featureInfoLayerSetInstance[mapId] = new FeatureInfoLayerSet(mapId); return FeatureInfoLayerSet.featureInfoLayerSetInstance[mapId]; } + + /** + * Function used to delete a FeatureInfoLayerSet object associated to a mapId. + * + * @param {string} mapId The map identifier the layer set belongs to. + */ + static delete(mapId: string) { + if (FeatureInfoLayerSet.featureInfoLayerSetInstance[mapId]) delete FeatureInfoLayerSet.featureInfoLayerSetInstance[mapId]; + } } diff --git a/packages/geoview-core/src/geo/utils/layer-set.ts b/packages/geoview-core/src/geo/utils/layer-set.ts index 1d67ff1ade8..6922d03646f 100644 --- a/packages/geoview-core/src/geo/utils/layer-set.ts +++ b/packages/geoview-core/src/geo/utils/layer-set.ts @@ -31,6 +31,9 @@ export class LayerSet { /** Function used to determine if the layerPath can be added to the layer set. */ registrationConditionFunction: (layerPath: string) => boolean; + /** Function used to initialise the data property of the layer path entry. */ + registrationUserDataInitialisation?: (layerPath: string) => void; + /** *************************************************************************************************************************** * The class constructor that instanciate a set of layer. * @@ -38,28 +41,35 @@ export class LayerSet { * @param {string} layerSetIdentifier The layer set identifier. * @param {TypeResultSets} resultSets An object that will contain the result sets indexed using the layer path. * @param {(layerPath: string) => boolean} registrationConditionFunction A function to decide if the layer can be added. + * @param {(layerPath: string) => void} registrationUserDataInitialisation A function to initialise the data property of the layer path entry. */ constructor( mapId: string, layerSetIdentifier: string, resultSets: TypeResultSets, - registrationConditionFunction: (layerPath: string) => boolean + registrationConditionFunction: (layerPath: string) => boolean, + registrationUserDataInitialisation?: (layerPath: string) => void ) { this.mapId = mapId; this.layerSetId = layerSetIdentifier; this.resultSets = resultSets; this.registrationConditionFunction = registrationConditionFunction; + this.registrationUserDataInitialisation = registrationUserDataInitialisation; const changeLayerStatusListenerFunctions = (payload: PayloadBaseClass) => { if (payloadIsLayerSetChangeLayerStatus(payload)) { const { layerPath, layerStatus } = payload; if (this.resultSets[layerPath]) { - this.resultSets[layerPath].layerStatus = layerStatus; - if (layerStatus === 'processed') this.resultSets[layerPath].layerPhase = layerStatus; - api.event.emit( - LayerSetPayload.createLayerSetUpdatedPayload(`${this.layerSetId}/${layerPath}/status`, this.resultSets, layerPath) - ); - api.event.emit(LayerSetPayload.createLayerSetUpdatedPayload(this.layerSetId, this.resultSets, layerPath)); + if (this.resultSets[layerPath].layerStatus !== layerStatus) { + this.resultSets[layerPath].layerStatus = layerStatus; + api.event.emit(LayerSetPayload.createLayerSetUpdatedPayload(this.layerSetId, this.resultSets, layerPath)); + if (this.layerSetId === `${mapId}/LegendsLayerSet`) + // LegendLayerSet is the absolute reference for finding out whether a layer has been loaded or is in error. Then, every + // time we modify a layerSet in the Legend family, we have to inform the system that a change has occurred. + api.event.emit( + LayerSetPayload.createLayerSetUpdatedPayload(`${mapId}/LegendsLayerSetStatusOrPhaseChanged`, this.resultSets, layerPath) + ); + } } } }; @@ -69,19 +79,14 @@ export class LayerSet { if (payloadIsLayerSetChangeLayerPhase(payload)) { const { layerPath, layerPhase } = payload; if (this.resultSets[layerPath] && this.resultSets[layerPath].layerStatus !== 'error') { - this.resultSets[layerPath].layerPhase = layerPhase; - api.event.emit(LayerSetPayload.createLayerSetUpdatedPayload(`${this.layerSetId}/${layerPath}/phase`, this.resultSets, layerPath)); - api.event.emit(LayerSetPayload.createLayerSetUpdatedPayload(this.layerSetId, this.resultSets, layerPath)); - } else { - Object.keys(this.resultSets).forEach((aLayerPath) => { - if (aLayerPath.startsWith(layerPath) && this.resultSets[aLayerPath].layerStatus !== 'error') { - this.resultSets[aLayerPath].layerPhase = layerPhase; + if (this.resultSets[layerPath].layerPhase !== layerPhase) { + this.resultSets[layerPath].layerPhase = layerPhase; + api.event.emit(LayerSetPayload.createLayerSetUpdatedPayload(this.layerSetId, this.resultSets, layerPath)); + if (this.layerSetId === `${mapId}/LegendsLayerSet`) api.event.emit( - LayerSetPayload.createLayerSetUpdatedPayload(`${this.layerSetId}/${aLayerPath}/phase`, this.resultSets, layerPath) + LayerSetPayload.createLayerSetUpdatedPayload(`${mapId}/LegendsLayerSetStatusOrPhaseChanged`, this.resultSets, layerPath) ); - api.event.emit(LayerSetPayload.createLayerSetUpdatedPayload(this.layerSetId, this.resultSets, layerPath)); - } - }); + } } } }; @@ -102,7 +107,12 @@ export class LayerSet { layerPhase: 'newInstance', layerName: api.maps[this.mapId].layer.registeredLayers[layerPath].layerName, }; + if (this.registrationUserDataInitialisation) this.registrationUserDataInitialisation(layerPath); api.event.emit(LayerSetPayload.createLayerSetUpdatedPayload(this.layerSetId, this.resultSets, layerPath)); + if (this.layerSetId === `${mapId}/LegendsLayerSet`) + api.event.emit( + LayerSetPayload.createLayerSetUpdatedPayload(`${mapId}/LegendsLayerSetStatusOrPhaseChanged`, this.resultSets, layerPath) + ); } else if (action === 'remove' && layerPath in this.resultSets) { delete this.resultSets[layerPath]; api.event.emit(LayerSetPayload.createLayerSetUpdatedPayload(this.layerSetId, this.resultSets, layerPath)); diff --git a/packages/geoview-core/src/geo/utils/legends-layer-set.ts b/packages/geoview-core/src/geo/utils/legends-layer-set.ts index 40949bd9803..c8ef444920f 100644 --- a/packages/geoview-core/src/geo/utils/legends-layer-set.ts +++ b/packages/geoview-core/src/geo/utils/legends-layer-set.ts @@ -1,12 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { EVENT_NAMES } from '@/api/events/event-types'; -import { - GetLegendsPayload, - payloadIsLegendInfo, - payloadIsTriggerLegend, - TypeLegendResultSets, - payloadIsLayerSetUpdated, -} from '@/api/events/payloads'; +import { GetLegendsPayload, payloadIsLegendInfo, TypeLegendResultSets, payloadIsLayerSetUpdated } from '@/api/events/payloads'; import { api } from '@/app'; import { LayerSet } from './layer-set'; @@ -42,7 +36,18 @@ export class LegendsLayerSet { return true; }; this.mapId = mapId; - this.layerSet = new LayerSet(mapId, `${mapId}/$LegendsLayerSet$`, this.resultSets, registrationConditionFunction); + this.layerSet = new LayerSet(mapId, `${mapId}/LegendsLayerSet`, this.resultSets, registrationConditionFunction); + + api.event.on( + EVENT_NAMES.LAYER_SET.UPDATED, + (layerUpdatedPayload) => { + if (payloadIsLayerSetUpdated(layerUpdatedPayload)) { + const { resultSets } = layerUpdatedPayload; + api.event.emit(GetLegendsPayload.createLegendsLayersetUpdatedPayload(`${this.mapId}/LegendsLayerSet`, resultSets)); + } + }, + `${mapId}/LegendsLayerSetStatusOrPhaseChanged` + ); // This listener receives the legend information returned by the layer's getLegend call and store it in the resultSets. // Every time a registered layer changes, an EVENT_NAMES.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED event is triggered. @@ -53,42 +58,32 @@ export class LegendsLayerSet { const { layerPath, legendInfo } = payload; if (layerPath in this.resultSets) { this.resultSets[layerPath].data = legendInfo; - api.event.emit(GetLegendsPayload.createLegendsLayersetUpdatedPayload(`${this.mapId}/$LegendsLayerSet$`, this.resultSets)); + api.event.emit(GetLegendsPayload.createLegendsLayersetUpdatedPayload(`${this.mapId}/LegendsLayerSet`, this.resultSets)); } } }, this.mapId ); - // This listener reacts to EVENT_NAMES.GET_LEGENDS.TRIGGER events. It first queries the legend of all known layers. - // Then, it activates a listener to query the layers added afterwards or to delete the legends of the deleted layers. - api.event.once( - EVENT_NAMES.GET_LEGENDS.TRIGGER, - (payload) => { - if (payloadIsTriggerLegend(payload)) { - const queryUndefinedLegend = () => { - Object.keys(this.resultSets).forEach((layerPath) => { - if (this.resultSets[layerPath]?.layerStatus === 'processed' && this.resultSets[layerPath].data === undefined) - api.event.emit(GetLegendsPayload.createQueryLegendPayload(`${this.mapId}/${layerPath}`, layerPath)); - }); - }; - - api.event.on( - EVENT_NAMES.LAYER_SET.UPDATED, - (layerUpdatedPayload) => { - if (payloadIsLayerSetUpdated(layerUpdatedPayload)) { - queryUndefinedLegend(); - api.event.emit(GetLegendsPayload.createLegendsLayersetUpdatedPayload(`${this.mapId}/$LegendsLayerSet$`, this.resultSets)); - } - }, - `${mapId}/$LegendsLayerSet$` - ); + // First queries the legend of all known layers. Then, activate a listener to query the layers added afterwards or to delete the + // legends of the deleted layers. + const queryUndefinedLegend = () => { + Object.keys(this.resultSets).forEach((layerPath) => { + if (this.resultSets[layerPath]?.layerStatus === 'processed' && this.resultSets[layerPath].data === undefined) + api.event.emit(GetLegendsPayload.createQueryLegendPayload(`${this.mapId}/${layerPath}`, layerPath)); + }); + }; + queryUndefinedLegend(); + api.event.on( + EVENT_NAMES.LAYER_SET.UPDATED, + (layerUpdatedPayload) => { + if (payloadIsLayerSetUpdated(layerUpdatedPayload)) { queryUndefinedLegend(); - api.event.emit(GetLegendsPayload.createLegendsLayersetUpdatedPayload(`${this.mapId}/$LegendsLayerSet$`, this.resultSets)); + api.event.emit(GetLegendsPayload.createLegendsLayersetUpdatedPayload(`${this.mapId}/LegendsLayerSet`, this.resultSets)); } }, - `${mapId}/$LegendsLayerSet$` + `${mapId}/LegendsLayerSet` ); } @@ -104,4 +99,13 @@ export class LegendsLayerSet { if (!LegendsLayerSet.legendsLayerSetInstance[mapId]) LegendsLayerSet.legendsLayerSetInstance[mapId] = new LegendsLayerSet(mapId); return LegendsLayerSet.legendsLayerSetInstance[mapId]; } + + /** + * Function used to delete a LegendsLayerSet object associated to a mapId. + * + * @param {string} mapId The map identifier the layer set belongs to. + */ + static delete(mapId: string) { + if (LegendsLayerSet.legendsLayerSetInstance[mapId]) delete LegendsLayerSet.legendsLayerSetInstance[mapId]; + } } diff --git a/packages/geoview-core/src/ui/modal/modal-model.ts b/packages/geoview-core/src/ui/modal/modal-model.ts index 188dbe77e0b..e3542eaaee0 100644 --- a/packages/geoview-core/src/ui/modal/modal-model.ts +++ b/packages/geoview-core/src/ui/modal/modal-model.ts @@ -22,7 +22,7 @@ export class ModalModel { active?: boolean; - mapId?: string; + mapId!: string; width?: string | number; @@ -43,7 +43,7 @@ export class ModalModel { open = (): void => { this.active = true; - api.event.emit(modalPayload(EVENT_NAMES.MODAL.EVENT_MODAL_OPEN, this.mapId!, this.modalModelId!, true)); + api.event.emit(modalPayload(EVENT_NAMES.MODAL.EVENT_MODAL_OPEN, this.mapId, this.modalModelId!, true)); }; /** @@ -52,7 +52,7 @@ export class ModalModel { close = (): void => { this.active = false; - api.event.emit(modalPayload(EVENT_NAMES.MODAL.EVENT_MODAL_CLOSE, this.mapId!, this.modalModelId!, false)); + api.event.emit(modalPayload(EVENT_NAMES.MODAL.EVENT_MODAL_CLOSE, this.mapId, this.modalModelId!, false)); }; /** @@ -139,6 +139,6 @@ export class ModalModel { * to update the modal as soon as a change is made to any content */ reRender = (): void => { - api.event.emit(modalPayload(EVENT_NAMES.MODAL.EVENT_MODAL_UPDATE, this.mapId!, this.modalModelId!)); + api.event.emit(modalPayload(EVENT_NAMES.MODAL.EVENT_MODAL_UPDATE, this.mapId, this.modalModelId!)); }; } diff --git a/packages/geoview-details-panel/src/details-item.tsx b/packages/geoview-details-panel/src/details-item.tsx index a5d71112d05..610eb7a7cfd 100644 --- a/packages/geoview-details-panel/src/details-item.tsx +++ b/packages/geoview-details-panel/src/details-item.tsx @@ -73,7 +73,7 @@ export function DetailsItem({ mapId, buttonId }: Props): JSX.Element { useEffect(() => { // create the listener to return the details - api.event.on(api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, allQueriesDoneListenerFunction, `${mapId}/$FeatureInfoLayerSet$`); + api.event.on(api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, allQueriesDoneListenerFunction, `${mapId}/FeatureInfoLayerSet`); // get click info. api.event.on(api.eventNames.MAP.EVENT_MAP_SINGLE_CLICK, eventMapSingleClickListenerFunction, mapId); diff --git a/packages/geoview-footer-panel/src/data-table.tsx b/packages/geoview-footer-panel/src/data-table.tsx index d9b3e548aef..72823457eaa 100644 --- a/packages/geoview-footer-panel/src/data-table.tsx +++ b/packages/geoview-footer-panel/src/data-table.tsx @@ -42,6 +42,7 @@ export function DataTable({ mapId }: DataTableProps) { return () => { api.event.off(api.eventNames.MAP.EVENT_MAP_LOADED, mapId, getDataTable); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return
{table}
; diff --git a/packages/geoview-footer-panel/src/details-item.tsx b/packages/geoview-footer-panel/src/details-item.tsx index a3904d7b722..2591f1e9ec7 100644 --- a/packages/geoview-footer-panel/src/details-item.tsx +++ b/packages/geoview-footer-panel/src/details-item.tsx @@ -66,7 +66,7 @@ export function DetailsItem({ mapId }: Props): JSX.Element { useEffect(() => { // create the listener to return the details - api.event.on(api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, allQueriesDoneListenerFunction, `${mapId}/$FeatureInfoLayerSet$`); + api.event.on(api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, allQueriesDoneListenerFunction, `${mapId}/FeatureInfoLayerSet`); api.event.on(api.eventNames.MAP.EVENT_MAP_SINGLE_CLICK, eventMapSingleClickListenerFunction, mapId); return () => { api.event.off(api.eventNames.GET_FEATURE_INFO.ALL_QUERIES_DONE, mapId, allQueriesDoneListenerFunction); diff --git a/packages/geoview-footer-panel/src/index.tsx b/packages/geoview-footer-panel/src/index.tsx index a1d20c469d1..63aead0deda 100644 --- a/packages/geoview-footer-panel/src/index.tsx +++ b/packages/geoview-footer-panel/src/index.tsx @@ -131,7 +131,7 @@ class FooterPanelPlugin extends AbstractPlugin { } } }, - `${mapId}/$FeatureInfoLayerSet$` + `${mapId}/FeatureInfoLayerSet` ); } diff --git a/packages/geoview-layers-panel/src/panel-content.tsx b/packages/geoview-layers-panel/src/panel-content.tsx index eab3e0dbd38..7af08e8dc9c 100644 --- a/packages/geoview-layers-panel/src/panel-content.tsx +++ b/packages/geoview-layers-panel/src/panel-content.tsx @@ -95,7 +95,7 @@ function PanelContent(props: TypePanelContentProps): JSX.Element { useEffect(() => { api.event.on(api.eventNames.MAP.EVENT_MAP_LOADED, updateLayers, mapId); - api.event.on(api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, updateLayers, `${mapId}/$LegendsLayerSet$`); + api.event.on(api.eventNames.GET_LEGENDS.LEGENDS_LAYERSET_UPDATED, updateLayers, `${mapId}/LegendsLayerSet`); return () => { api.event.off(api.eventNames.MAP.EVENT_MAP_LOADED, mapId, updateLayers); diff --git a/packages/geoview-swiper/src/swiper.tsx b/packages/geoview-swiper/src/swiper.tsx index be35a6c229c..b892e870d30 100644 --- a/packages/geoview-swiper/src/swiper.tsx +++ b/packages/geoview-swiper/src/swiper.tsx @@ -295,7 +295,7 @@ export function Swiper(props: SwiperProps): JSX.Element { } } }; - api.event.on(EVENT_NAMES.LAYER_SET.UPDATED, layerSetUpdatedHandler, `${mapId}/$LegendsLayerSet$`); + api.event.on(EVENT_NAMES.LAYER_SET.UPDATED, layerSetUpdatedHandler, `${mapId}/LegendsLayerSet`); return () => { api.event.off(EVENT_NAMES.LAYER_SET.UPDATED, mapId, layerSetUpdatedHandler); };