Skip to content

Commit

Permalink
Started
Browse files Browse the repository at this point in the history
Finished
  • Loading branch information
Alex-NRCan committed Feb 27, 2024
1 parent 1c0e857 commit 2e99570
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 31 deletions.
14 changes: 10 additions & 4 deletions packages/geoview-core/public/templates/sandbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ <h4 id="HLCONF1">Sanbox Map</h4>
<a class="ref-link" href="#top">Top</a>
</div>
<div id="mapSection">
<div id="sandboxMap" class="" data-lang="en"></div>
<div id="sandboxMap"></div>
</div>
<p>This map loads it's configurations from the text area.</p>
<hr />
Expand Down Expand Up @@ -194,11 +194,17 @@ <h4 id="HLCONF1">Sanbox Map</h4>
// 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 (fix react warning)
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===================================================================================================
Expand Down
2 changes: 1 addition & 1 deletion packages/geoview-core/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ async function renderMap(mapElement: Element): Promise<void> {
reactRoot[mapId] = createRoot(mapElement!);
addReloadListener(mapId);

// TODO: Refactor #1810 - Activate <React.StrictMode>
// TODO: Refactor #1810 - Activate <React.StrictMode> here or in app-start.tsx?
reactRoot[mapId].render(<AppStart mapFeaturesConfig={configObj} />);
// reactRoot[mapId].render(
// <React.StrictMode>
Expand Down
13 changes: 12 additions & 1 deletion packages/geoview-core/src/core/app-start.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,19 @@ 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(() => {
// If it's a static map, disable the click/hover listeners
if (mapFeaturesConfig.map.interaction === 'static') {
// No listeners
api.getFeatureInfoLayerSet(mapId).disableClickListener();
api.getFeatureInfoLayerSet(mapId).disableHoverListener();
}
});
});

// TODO: Refactor #1810 - Activate <React.StrictMode> here or in app.tsx?
return (
<I18nextProvider i18n={i18nInstance}>
<MapContext.Provider value={mapContextValue}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,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] = {};

Expand Down Expand Up @@ -1038,7 +1038,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'));

Expand Down
92 changes: 69 additions & 23 deletions packages/geoview-core/src/geo/map/map-viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,36 +187,82 @@ 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
*/
mapReady(): void {
mapReady(): Promise<void> {
// 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].allLayerStatusAreIn(['processed', 'error', 'loaded']);
logger.logTraceDetailed('map-viewer.mapReady? geoview layer ready?', geoviewLayerId, layerIsReady);
allGeoviewLayerReady &&= layerIsReady;
return new Promise<void>((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].allLayerStatusAreIn(['processed', 'error', 'loaded']);
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);
});
}

/**
* Function called to monitor when the layers result sets are actually ready
*/
layerResultSetReady(): Promise<void> {
// Start another interval checker
return new Promise<void>((resolve) => {
const layersInterval = setInterval(() => {
// 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).resultsSet;
const layerResultSetReady = Object.keys(resultSet).includes(layerPath);
if (!layerResultSetReady) {
logger.logTraceDetailed('map-viewer.mapReady? layer set not ready, waiting...', layerPath);
allGood = false;
}
});
if (allGeoviewLayerReady) {

// If all good
if (allGood) {
// Clear interval
clearInterval(layersInterval);

// How many layers resultset?
const resultSetCount = Object.keys(api.getFeatureInfoLayerSet(this.mapId).resultsSet).length;

// 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);
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);
}, 250);
});
}

/**
Expand Down

0 comments on commit 2e99570

Please sign in to comment.