diff --git a/packages/geoview-core/public/templates/sandbox.html b/packages/geoview-core/public/templates/sandbox.html
index 758cdef4892..2bd75b87081 100644
--- a/packages/geoview-core/public/templates/sandbox.html
+++ b/packages/geoview-core/public/templates/sandbox.html
@@ -143,7 +143,7 @@
Sanbox Map
Top
This map loads it's configurations from the text area.
@@ -194,11 +194,17 @@ Sanbox Map
// add an event listener when a button is clicked
createMapButton.addEventListener('click', function (e) {
// delete old map
- const mapDiv = cgpv.api.maps['sandboxMap'].remove(false);
- mapDiv.classList.remove('geoview-map');
+ cgpv.api.maps['sandboxMap'].remove(true);
+
+ // create new map in a new dom node
+ const newDiv = document.createElement('div');
+ const a = document.createAttribute("id");
+ a.value = "sandboxMap";
+ newDiv.setAttributeNode(a);
+ document.getElementById('mapSection').appendChild(newDiv);
// create map
- setTimeout(() => cgpv.api.createMapFromConfig('sandboxMap', document.getElementById('configGeoview').value), 1000);
+ setTimeout(() => cgpv.api.createMapFromConfig('sandboxMap', document.getElementById('configGeoview').value), 300);
});
// Editor script section===================================================================================================
diff --git a/packages/geoview-core/src/api/event-processors/event-processor-children/map-event-processor.ts b/packages/geoview-core/src/api/event-processors/event-processor-children/map-event-processor.ts
index dbcdb0d70dc..c1280c151de 100644
--- a/packages/geoview-core/src/api/event-processors/event-processor-children/map-event-processor.ts
+++ b/packages/geoview-core/src/api/event-processors/event-processor-children/map-event-processor.ts
@@ -199,8 +199,13 @@ export class MapEventProcessor extends AbstractEventProcessor {
// TODO: destroy events on map destruction
map.on('change:size', store.getState().mapState.events.onMapChangeSize);
map.on('moveend', store.getState().mapState.events.onMapMoveEnd);
- map.on('pointermove', store.getState().mapState.events.onMapPointerMove);
- map.on('singleclick', store.getState().mapState.events.onMapSingleClick);
+
+ // If not on a static map, wire handlers on pointermove and singleclick
+ if (store.getState().mapState.interaction !== 'static') {
+ map.on('pointermove', store.getState().mapState.events.onMapPointerMove);
+ map.on('singleclick', store.getState().mapState.events.onMapSingleClick);
+ }
+
map.getView().on('change:resolution', store.getState().mapState.events.onMapZoomEnd);
map.getView().on('change:rotation', store.getState().mapState.events.onMapRotation);
diff --git a/packages/geoview-core/src/app.tsx b/packages/geoview-core/src/app.tsx
index dcd5f32b082..a6b437495ff 100644
--- a/packages/geoview-core/src/app.tsx
+++ b/packages/geoview-core/src/app.tsx
@@ -101,7 +101,7 @@ async function renderMap(mapElement: Element): Promise {
reactRoot[mapId] = createRoot(mapElement!);
addReloadListener(mapId);
- // TODO: Refactor #1810 - Activate
+ // TODO: Refactor #1810 - Activate here or in app-start.tsx?
reactRoot[mapId].render();
// reactRoot[mapId].render(
//
diff --git a/packages/geoview-core/src/core/app-start.tsx b/packages/geoview-core/src/core/app-start.tsx
index d1b8550f428..c2cc472bc90 100644
--- a/packages/geoview-core/src/core/app-start.tsx
+++ b/packages/geoview-core/src/core/app-start.tsx
@@ -77,8 +77,14 @@ function AppStart(props: AppStartProps): JSX.Element {
if (!Object.keys(api.maps).includes(mapId)) api.maps[mapId] = new MapViewer(mapFeaturesConfig, i18nInstance);
// Start the process of checking for map readiness
- api.maps[mapId].mapReady();
+ api.maps[mapId].mapReady().then(() => {
+ // Start the process of checking for layers result set readiness
+ api.maps[mapId].layerResultSetReady().then(() => {
+ // Write app-start code logic here to do something when the layers resultset is ready for all layer path
+ });
+ });
+ // TODO: Refactor #1810 - Activate here or in app.tsx?
return (
diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/abstract-geoview-layers.ts b/packages/geoview-core/src/geo/layer/geoview-layers/abstract-geoview-layers.ts
index 983669373bb..3ab7fae7055 100644
--- a/packages/geoview-core/src/geo/layer/geoview-layers/abstract-geoview-layers.ts
+++ b/packages/geoview-core/src/geo/layer/geoview-layers/abstract-geoview-layers.ts
@@ -961,7 +961,7 @@ export abstract class AbstractGeoViewLayer {
*
* @param {TypeBaseLayerEntryConfig} layerConfig The layer config to register.
*/
- registerToLayerSets(layerConfig: TypeBaseLayerEntryConfig) {
+ registerToLayerSets(layerConfig: TypeBaseLayerEntryConfig): void {
const { layerPath } = layerConfig;
if (!this.registerToLayerSetListenerFunctions[layerPath]) this.registerToLayerSetListenerFunctions[layerPath] = {};
@@ -1037,7 +1037,7 @@ export abstract class AbstractGeoViewLayer {
*
* @param {TypeBaseLayerEntryConfig} layerConfig The layer entry to register.
*/
- unregisterFromLayerSets(layerConfig: TypeBaseLayerEntryConfig) {
+ unregisterFromLayerSets(layerConfig: TypeBaseLayerEntryConfig): void {
const { layerPath } = layerConfig;
api.event.emit(LayerSetPayload.createLayerRegistrationPayload(this.mapId, layerPath, 'remove'));
diff --git a/packages/geoview-core/src/geo/map/map-viewer.ts b/packages/geoview-core/src/geo/map/map-viewer.ts
index a61c0195db8..2faeac4767f 100644
--- a/packages/geoview-core/src/geo/map/map-viewer.ts
+++ b/packages/geoview-core/src/geo/map/map-viewer.ts
@@ -219,36 +219,85 @@ export class MapViewer {
}
/**
- * Function called when the map has been rendered and ready to be customized
+ * Function called to monitor when the map is actually ready.
+ * Important: This function is also responsible for calling the MapEventProcessor.setMapLoaded after 1 second has ellapsed.
*/
- mapReady(): void {
+ mapReady(): Promise {
// Log Marker Start
logger.logMarkerStart(`mapReady-${this.mapId}`);
- const layerInterval = setInterval(() => {
- // Log
- logger.logTraceDetailed('map-viewer.mapReady?', this.mapId);
-
- if (this.layer?.geoviewLayers) {
- const { geoviewLayers } = this.layer;
- let allGeoviewLayerReady =
- this.mapFeaturesConfig.map.listOfGeoviewLayerConfig?.length === 0 || Object.keys(geoviewLayers).length !== 0;
- Object.keys(geoviewLayers).forEach((geoviewLayerId) => {
- const layerIsReady = geoviewLayers[geoviewLayerId].allLayerStatusAreGreaterThanOrEqualTo('processed');
- logger.logTraceDetailed('map-viewer.mapReady? geoview layer ready?', geoviewLayerId, layerIsReady);
- allGeoviewLayerReady &&= layerIsReady;
- });
- if (allGeoviewLayerReady) {
- // Log
- logger.logInfo('Map is ready', this.mapId);
- logger.logMarkerCheck(`mapReady-${this.mapId}`, 'for map to be ready');
- // ! We added processed to layers check so this map loaded event is fired faster
- // TODO: solve this without using a timeout...
- setTimeout(() => MapEventProcessor.setMapLoaded(this.mapId), 1000);
- clearInterval(layerInterval);
+ return new Promise((resolve) => {
+ // Start an interval checker
+ const mapInterval = setInterval(() => {
+ if (this.layer?.geoviewLayers) {
+ const { geoviewLayers } = this.layer;
+ let allGeoviewLayerReady =
+ this.mapFeaturesConfig.map.listOfGeoviewLayerConfig?.length === 0 || Object.keys(geoviewLayers).length !== 0;
+ Object.keys(geoviewLayers).forEach((geoviewLayerId) => {
+ const layerIsReady = geoviewLayers[geoviewLayerId].allLayerStatusAreGreaterThanOrEqualTo('processed');
+ if (!layerIsReady) logger.logTraceDetailed('map-viewer.mapReady? geoview layer not ready, waiting...', geoviewLayerId);
+ allGeoviewLayerReady &&= layerIsReady;
+ });
+ if (allGeoviewLayerReady) {
+ // Clear interval
+ clearInterval(mapInterval);
+
+ // Log
+ logger.logInfo('Map is ready', this.mapId);
+ logger.logMarkerCheck(`mapReady-${this.mapId}`, 'for map to be ready');
+
+ // Resolve the promise
+ resolve();
+
+ // ! We added processed to layers check so this map loaded event is fired faster
+ // TODO: solve this without using a timeout...
+ setTimeout(() => MapEventProcessor.setMapLoaded(this.mapId), 1000);
+ }
}
- }
- }, 250);
+ }, 250);
+ });
+ }
+
+ /**
+ * Function called to monitor when the layers result sets are actually ready
+ */
+ layerResultSetReady(): Promise {
+ // Start another interval checker
+ return new Promise((resolve) => {
+ const layersInterval = setInterval(() => {
+ if (api.maps[this.mapId].layer) {
+ // Check if all registered layers have their results set
+ let allGood = true;
+ Object.entries(api.maps[this.mapId].layer.registeredLayers).forEach(([layerPath, registeredLayer]) => {
+ // If not queryable, don't expect a result set
+ if (!registeredLayer.source?.featureInfo?.queryable) return;
+
+ const { resultSet } = api.getFeatureInfoLayerSet(this.mapId);
+ const layerResultSetReady = Object.keys(resultSet).includes(layerPath);
+ if (!layerResultSetReady) {
+ logger.logTraceDetailed('layer resultset not ready, waiting...', layerPath);
+ allGood = false;
+ }
+ });
+
+ // If all good
+ if (allGood) {
+ // Clear interval
+ clearInterval(layersInterval);
+
+ // How many layers resultset?
+ const resultSetCount = Object.keys(api.getFeatureInfoLayerSet(this.mapId).resultSet).length;
+
+ // Log
+ logger.logInfo(`All (${resultSetCount}) Layers ResultSet are ready`, this.mapId);
+ logger.logMarkerCheck(`mapReady-${this.mapId}`, `for all (${resultSetCount}) Layers ResultSet to be ready`);
+
+ // Resolve the promise
+ resolve();
+ }
+ }
+ }, 250);
+ });
}
/**