From ce9bf2cb556fe149a18cb5dfb381b137fd565c48 Mon Sep 17 00:00:00 2001
From: Alex <alexandre.roy@nrcan-rncan.gc.ca>
Date: Mon, 12 Feb 2024 16:16:05 -0500
Subject: [PATCH] GeoCore implementation update Add-Layer fix when adding
 GeoCore layer with uuid GeoChart linkage with GeoCore

---
 .../public/configs/sample-config.json         |   2 +-
 .../geoview-core/schema-default-config.json   |   2 +-
 packages/geoview-core/schema.json             |   4 +-
 .../geochart-event-processor.ts               | 100 ++-
 .../map-event-processor.ts                    |  18 +-
 .../core/components/details/details-panel.tsx |  14 +-
 .../add-new-layer/add-new-layer.tsx           |  29 +-
 .../geochart-state.ts                         |  14 +-
 .../core/utils/config/config-validation.ts    |  11 +-
 .../src/core/utils/config/config.ts           |   7 +-
 .../utils/config/reader/div-config-reader.ts  |   7 +-
 .../utils/config/reader/json-config-reader.ts |   7 +-
 .../utils/config/reader/url-config-reader.ts  |  35 +-
 .../utils/config/reader/uuid-config-reader.ts | 568 ++++++++++--------
 packages/geoview-core/src/geo/layer/layer.ts  |  44 +-
 .../src/geo/layer/other/geocore.ts            | 121 +++-
 .../src/geo/map/map-schema-types.ts           |   8 +-
 .../geoview-geochart/src/geochart-panel.tsx   |  10 +-
 .../geoview-geochart/src/geochart-parsing.ts  |   2 +-
 .../geoview-geochart/src/geochart-types.ts    |   2 +-
 packages/geoview-geochart/src/geochart.tsx    |   2 +-
 21 files changed, 608 insertions(+), 399 deletions(-)

diff --git a/packages/geoview-core/public/configs/sample-config.json b/packages/geoview-core/public/configs/sample-config.json
index 9d1aca6286f..86aafc8ddbb 100644
--- a/packages/geoview-core/public/configs/sample-config.json
+++ b/packages/geoview-core/public/configs/sample-config.json
@@ -125,7 +125,7 @@
   },
   "externalPackages": [],
   "serviceUrls": {
-    "keys": "https://geocore.api.geo.ca"
+    "geocoreUrl": "https://geocore.api.geo.ca"
   },
   "suportedLanguages": ["en", "fr"],
   "version": "1.0"
diff --git a/packages/geoview-core/schema-default-config.json b/packages/geoview-core/schema-default-config.json
index cd370d84fa4..3e334e80dbf 100644
--- a/packages/geoview-core/schema-default-config.json
+++ b/packages/geoview-core/schema-default-config.json
@@ -27,7 +27,7 @@
   "corePackages": [],
   "externalPackages": [],
   "serviceUrls": {
-    "keys": "https://geocore.api.geo.ca",
+    "geocoreUrl": "https://geocore.api.geo.ca",
     "geolocator": "https://geolocator.api.geo.ca?keys=geonames,nominatim,locate"
   },
   "suportedLanguages": [
diff --git a/packages/geoview-core/schema.json b/packages/geoview-core/schema.json
index 8d39f24f89b..22e5ade7d49 100644
--- a/packages/geoview-core/schema.json
+++ b/packages/geoview-core/schema.json
@@ -1728,7 +1728,7 @@
       "type": "object",
       "description": "Service endpoint urls",
       "properties": {
-        "keys": {
+        "geocoreUrl": {
           "type": "string",
           "default": "https://geocore.api.geo.ca",
           "description": "Service end point to access API for layers specification (loading and plugins parameters). By default it is GeoCore but can be another endpoint with similar output."
@@ -1742,7 +1742,7 @@
           "description": "Service end point to access geo location of searched value."
         }
       },
-      "required": ["keys"]
+      "required": ["geocoreUrl"]
     },
     "TypeDisplayLanguage": {
       "enum": ["en", "fr"],
diff --git a/packages/geoview-core/src/api/event-processors/event-processor-children/geochart-event-processor.ts b/packages/geoview-core/src/api/event-processors/event-processor-children/geochart-event-processor.ts
index 4856d25e701..a6c4f479a56 100644
--- a/packages/geoview-core/src/api/event-processors/event-processor-children/geochart-event-processor.ts
+++ b/packages/geoview-core/src/api/event-processors/event-processor-children/geochart-event-processor.ts
@@ -1,5 +1,8 @@
-import { TypeArrayOfLayerData, TypeJsonObject } from '@/core/types/global-types';
+import { GeoviewStoreType } from '@/core/stores';
+import { TypeArrayOfLayerData } from '@/core/types/global-types';
 import { GeoChartStoreByLayerPath, IGeochartState } from '@/core/stores/store-interface-and-intial-values/geochart-state';
+import { GeoChartConfig } from '@/core/utils/config/reader/uuid-config-reader';
+import { logger } from '@/core/utils/logger';
 
 import { AbstractEventProcessor, BatchedPropagationLayerDataArrayByMap } from '../abstract-event-processor';
 
@@ -23,6 +26,36 @@ export class GeochartEventProcessor extends AbstractEventProcessor {
   // The longer the delay, the longer it'll take to update the UI. The delay can be bypassed using the layer path bypass method.
   static timeDelayBetweenPropagationsForBatch = 2000;
 
+  /**
+   * Overrides initialization of the GeoChart Event Processor
+   * @param {GeoviewStoreType} store The store associated with the GeoChart Event Processor
+   * @returns An array of the subscriptions callbacks which were created
+   */
+  protected onInitialize(store: GeoviewStoreType): Array<() => void> | void {
+    // Checks for added and removed layers with time dimension
+    const unsubLayerRemoved = store.subscribe(
+      (state) => state.mapState.layerOrder,
+      (cur, prev) => {
+        // Log
+        logger.logTraceCoreStoreSubscription('GEOCHART EVENT PROCESSOR - layerOrder', cur);
+
+        // For each chart config keys
+        Object.keys(store.getState().geochartState.geochartChartsConfig).forEach((chartLayerPath: string) => {
+          // If it was in the layerdata array and is not anymore
+          if (prev.includes(chartLayerPath) && !cur.includes(chartLayerPath)) {
+            // Remove it
+            GeochartEventProcessor.removeGeochartChart(store.getState().mapId, chartLayerPath);
+
+            // Log
+            logger.logDebug('Removed GeoChart configs for layer path:', chartLayerPath);
+          }
+        });
+      }
+    );
+
+    return [unsubLayerRemoved];
+  }
+
   /**
    * Shortcut to get the Geochart state for a given map id
    * @param {string} mapId The mapId
@@ -36,23 +69,21 @@ export class GeochartEventProcessor extends AbstractEventProcessor {
   }
 
   /**
-   * Set the default layers from configuration.
+   * Sets the default layers from configuration.
    * In the store, the GeoChart configurations are stored in an object with layerPath as its property name
    * (to retrieve the configuration per layer faster).
    *
    * @param {string} mapId the map id
-   * @param {TypeJsonObject} charts The array of JSON configuration for geochart
+   * @param {GeoChartConfig[]} charts The array of JSON configuration for GeoChart
    */
-  static setGeochartCharts(mapId: string, charts: TypeJsonObject[]): void {
+  static setGeochartCharts(mapId: string, charts: GeoChartConfig[]): void {
     // The store object representation
     const chartData: GeoChartStoreByLayerPath = {};
 
     // Loop on the charts
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    charts.forEach((chartInfo: any) => {
+    charts.forEach((chartInfo) => {
       // For each layer path
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
-      chartInfo.layers.forEach((layer: any) => {
+      chartInfo.layers.forEach((layer) => {
         // Get the layer path
         const layerPath = layer.layerId;
         chartData[layerPath] = chartInfo;
@@ -61,10 +92,59 @@ export class GeochartEventProcessor extends AbstractEventProcessor {
 
     // set store charts config
     this.getGeochartState(mapId)?.actions.setGeochartCharts(chartData);
+
+    // TODO: Also update the layer array in other store state to inform the later has a geochart attached to it (when code is done over there)
+  }
+
+  /**
+   * Adds a GeoChart Configuration to the specified map id and layer path
+   * @param {string} mapId The map ID
+   * @param {string} layerPath The layer path
+   * @param {GeoChartConfig} chartConfig The Geochart Configuration
+   */
+  static addGeochartChart(mapId: string, layerPath: string, chartConfig: GeoChartConfig): void {
+    // The processor needs an initialized chart store which is only initialized if the Geochart plugin exists.
+    // Therefore, we validate its existence first.
+    if (!this.getGeochartState(mapId)) return;
+
+    // Config to add
+    const toAdd: GeoChartStoreByLayerPath = {};
+    toAdd[layerPath] = chartConfig;
+
+    // Update the layer data array in the store
+    this.getGeochartState(mapId)!.actions.setGeochartCharts({ ...this.getGeochartState(mapId)?.geochartChartsConfig, ...toAdd });
+
+    // TODO: Also update the layer array in other store state to inform the later has a geochart attached to it (when code is done over there)
+  }
+
+  /**
+   * Removes a GeoChart Configuration at the specified map id and layer path
+   * @param {string} mapId The map ID
+   * @param {string} layerPath The layer path
+   */
+  static removeGeochartChart(mapId: string, layerPath: string): void {
+    // The processor needs an initialized chart store which is only initialized if the Geochart plugin exists.
+    // Therefore, we validate its existence first.
+    if (!this.getGeochartState(mapId)) return;
+    if (!this.getGeochartState(mapId)?.geochartChartsConfig) return;
+
+    // Config to remove
+    if (Object.keys(this.getGeochartState(mapId)!.geochartChartsConfig).includes(layerPath)) {
+      // Grab the config
+      const chartConfigs = this.getGeochartState(mapId)!.geochartChartsConfig;
+
+      // Delete the config
+      delete chartConfigs[layerPath];
+
+      // Update the layer data array in the store
+      this.getGeochartState(mapId)!.actions.setGeochartCharts({ ...chartConfigs });
+
+      // TODO: Also update the layer array in other store state to inform the later has a geochart attached to it (when code is done over there)
+    }
   }
 
   /**
-   * Propagate feature info layer sets to the store and the also in a batched manner.
+   * Propagates feature info layer sets to the store and the also in a batched manner.
    * @param {string} mapId The map id
    * @param {string} layerDataArray The layer data array to propagate in the store
    */
@@ -81,7 +161,7 @@ export class GeochartEventProcessor extends AbstractEventProcessor {
   }
 
   /**
-   * Propagate feature info layer sets to the store in a batched manner, every 'timeDelayBetweenPropagationsForBatch' millisecond.
+   * Propagates feature info layer sets to the store in a batched manner, every 'timeDelayBetweenPropagationsForBatch' millisecond.
    * This is used to provide another 'layerDataArray', in the store, which updates less often so that we save a couple 'layerDataArray'
    * update triggers in the components that are listening to the store array.
    * The propagation can be bypassed using the store 'layerDataArrayBatchLayerPathBypass' state which tells the process to
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 c2a4de57328..69de269b8bb 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
@@ -38,7 +38,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
       (cur, prev) => {
         if (cur !== prev) {
           // Log (too annoying, already have trace in EVENT_MAP_LOADED handler that works well)
-          // logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - mapLoaded (changed)', cur);
+          // logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - mapLoaded (changed)', mapId, cur);
 
           api.event.emit(mapPayload(EVENT_NAMES.MAP.EVENT_MAP_LOADED, mapId, store.getState().mapState.mapElement!));
         }
@@ -51,7 +51,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
       (cur, prev) => {
         if (cur !== prev) {
           // Log (too annoying, already have trace in EVENT_MAP_MOVE_END handler that works well)
-          // logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - centerCoordinates (changed)', cur);
+          // logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - centerCoordinates (changed)', mapId, cur);
 
           api.event.emit(lngLatPayload(EVENT_NAMES.MAP.EVENT_MAP_MOVE_END, mapId, cur));
         }
@@ -63,7 +63,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
       (cur, prev) => {
         if (cur! && cur !== prev) {
           // Log (too annoying, already have trace in EVENT_MAP_POINTER_MOVE handler that works well)
-          // logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - pointerPosition (changed)', cur);
+          // logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - pointerPosition (changed)', mapId, cur);
 
           api.event.emit(mapMouseEventPayload(EVENT_NAMES.MAP.EVENT_MAP_POINTER_MOVE, mapId, cur));
         }
@@ -75,7 +75,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
       (cur, prev) => {
         if (cur! && cur !== prev) {
           // Log (this event is raised, and we currently have no handles for it, by design)
-          logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - currentProjection (changed)', cur);
+          logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - currentProjection (changed)', mapId, cur);
 
           api.event.emit(mapViewProjectionPayload(EVENT_NAMES.MAP.EVENT_MAP_VIEW_PROJECTION_CHANGE, mapId, cur!));
         }
@@ -87,7 +87,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
       (cur, prev) => {
         if (cur && cur !== prev) {
           // Log (too annoying, already have trace in EVENT_MAP_SINGLE_CLICK handler that works well)
-          // logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - currentProjection (changed)', cur);
+          // logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - currentProjection (changed)', mapId, cur);
 
           api.event.emit(mapMouseEventPayload(EVENT_NAMES.MAP.EVENT_MAP_SINGLE_CLICK, mapId, cur));
         }
@@ -99,7 +99,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
       (cur, prev) => {
         if (cur! && cur !== prev) {
           // Log
-          logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - zoom (changed)', cur);
+          logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - zoom (changed)', mapId, cur);
 
           api.event.emit(numberPayload(EVENT_NAMES.MAP.EVENT_MAP_ZOOM_END, mapId, cur));
         }
@@ -113,7 +113,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
       (state) => state.mapState.highlightedFeatures,
       (curFeatures, prevFeatures) => {
         // Log
-        logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - highlightedFeatures', curFeatures);
+        logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - highlightedFeatures', mapId, curFeatures);
 
         if (curFeatures.length === 0) api.maps[mapId].layer.featureHighlight.removeHighlight('all');
         else {
@@ -137,7 +137,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
       (state) => state.mapState.selectedFeatures,
       (curFeatures, prevFeatures) => {
         // Log
-        logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - selectedFeatures', curFeatures);
+        logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - selectedFeatures', mapId, curFeatures);
 
         // TODO: on reload, layer object is undefined, need to test for now and solve in #1580
         if (curFeatures.length === 0 && api.maps[mapId].layer !== undefined) api.maps[mapId].layer.featureHighlight.resetAnimation('all');
@@ -162,7 +162,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
       (state) => state.layerState.legendLayers,
       (cur) => {
         // Log
-        logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - legendLayers', cur);
+        logger.logTraceCoreStoreSubscription('MAP EVENT PROCESSOR - legendLayers', mapId, cur);
 
         const orderedLayerPaths = MapEventProcessor.evaluateLayerPathsFromLegendsArray(cur);
         const prevLayerOrder = [...store.getState().mapState.layerOrder];
diff --git a/packages/geoview-core/src/core/components/details/details-panel.tsx b/packages/geoview-core/src/core/components/details/details-panel.tsx
index 1fd554b04e7..b14dda53253 100644
--- a/packages/geoview-core/src/core/components/details/details-panel.tsx
+++ b/packages/geoview-core/src/core/components/details/details-panel.tsx
@@ -65,7 +65,7 @@ export function DetailsPanel(): JSX.Element {
   // #region MAIN HOOKS SECTION ***************************************************************************************
 
   /**
-   * Check if feature is in the store checkedFeatures array
+   * Checks if feature is in the store checkedFeatures array
    *
    * @param {TypeFeatureInfoEntry} feature The feature to check
    * @returns {boolean} true if feature is in checkedFeatures
@@ -83,7 +83,7 @@ export function DetailsPanel(): JSX.Element {
   );
 
   /**
-   * Helper function to clear the highlighed features when they are not checked.
+   * Clears the highlighed features when they are not checked.
    * @param {TypeArrayOfFeatureInfoEntries} arrayToClear The array to clear of the unchecked features
    */
   const clearHighlightsUnchecked = useCallback(
@@ -100,7 +100,7 @@ export function DetailsPanel(): JSX.Element {
   );
 
   /**
-   * Get the label for the number of features of a layer.
+   * Gets the label for the number of features of a layer.
    * @returns string
    */
   const getNumFeaturesLabel = useCallback(
@@ -115,7 +115,7 @@ export function DetailsPanel(): JSX.Element {
   );
 
   /**
-   * Memoize the layers list for the LayerList component and centralizing indexing purposes.
+   * Memoizes the layers list for the LayerList component and centralizing indexing purposes.
    */
   const memoLayersList = useMemo(() => {
     // Log
@@ -140,7 +140,7 @@ export function DetailsPanel(): JSX.Element {
   }, [visibleLayers, arrayOfLayerDataBatch, getNumFeaturesLabel]);
 
   /**
-   * Memoize the selected layer for the LayerList component.
+   * Memoizes the selected layer for the LayerList component.
    */
   const memoLayerSelectedItem = useMemo(() => {
     // Log
@@ -149,7 +149,7 @@ export function DetailsPanel(): JSX.Element {
   }, [memoLayersList, selectedLayerPath]);
 
   /**
-   * Memoize the selected layer data.
+   * Memoizes the selected layer data.
    */
   const memoSelectedLayerData = useMemo(() => {
     // Log
@@ -158,7 +158,7 @@ export function DetailsPanel(): JSX.Element {
   }, [arrayOfLayerDataBatch, selectedLayerPath]);
 
   /**
-   * Memoize the selected layer data features.
+   * Memoizes the selected layer data features.
    */
   const memoSelectedLayerDataFeatures = useMemo(() => {
     // Log
diff --git a/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-new-layer.tsx b/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-new-layer.tsx
index a7056f26d48..8c1d191daf0 100644
--- a/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-new-layer.tsx
+++ b/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-new-layer.tsx
@@ -14,16 +14,13 @@ import {
   TypeEsriFeatureLayerConfig,
   TypeEsriFeatureLayerEntryConfig,
   TypeEsriImageLayerEntryConfig,
-  TypeGeoCoreLayerConfig,
   TypeGeoJSONLayerConfig,
   TypeGeoJSONLayerEntryConfig,
   TypeGeoPackageLayerConfig,
   TypeGeoPackageLayerEntryConfig,
-  TypeGeocoreLayerEntryConfig,
   TypeGeoviewLayerConfig,
   TypeGeoviewLayerType,
   TypeLayerEntryConfig,
-  TypeLayerEntryType,
   TypeListOfGeoviewLayerConfig,
   TypeListOfLayerEntryConfig,
   TypeOgcWmsLayerEntryConfig,
@@ -39,7 +36,7 @@ import { ButtonPropsLayerPanel, SelectChangeEvent, TypeJsonArray, TypeJsonObject
 import { useGeoViewMapId } from '@/core/stores/geoview-store';
 import { createLocalizedString } from '@/core/utils/utilities';
 import { useLayerStoreActions, useLayersList } from '@/core/stores/store-interface-and-intial-values/layer-state';
-import { Cast, Config, api, generateId } from '@/app';
+import { Cast, Config, api } from '@/app';
 import { logger } from '@/core/utils/logger';
 import { EsriImage, TypeEsriImageLayerConfig } from '@/geo/layer/geoview-layers/raster/esri-image';
 
@@ -98,10 +95,10 @@ export function AddNewLayer(): JSX.Element {
   // const acceptedFiles = ["*.json"];
 
   useEffect(() => {
-    // eslint-disable-next-line no-console
-    console.log('layersList ', layersList);
+    // Log
+    logger.logTraceUseEffect('layersList ', layersList);
+
     // setIsLoading(false);
-    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [layersList]);
 
   const sxClasses = {
@@ -413,19 +410,9 @@ export function AddNewLayer(): JSX.Element {
     try {
       const isValid = layerURL.indexOf('/') === -1 && layerURL.replaceAll('-', '').length === 32;
       if (!isValid) throw new Error('err');
-      const geoCoreGeoviewLayerConfig = {
-        geoviewLayerId: generateId(),
-        geoviewLayerType: 'geoCore',
-        listOfLayerEntryConfig: [
-          new TypeGeocoreLayerEntryConfig({
-            schemaTag: 'geoCore' as TypeGeoviewLayerType,
-            entryType: 'geoCore' as TypeLayerEntryType,
-            layerId: layerURL,
-          } as TypeGeocoreLayerEntryConfig),
-        ] as TypeGeocoreLayerEntryConfig[],
-      } as TypeGeoCoreLayerConfig;
+
       const geoCoreGeoviewLayerInstance = new GeoCore(mapId);
-      const layers = await geoCoreGeoviewLayerInstance.createLayers(geoCoreGeoviewLayerConfig);
+      const layers = await geoCoreGeoviewLayerInstance.createLayersFromUUID(layerURL);
       if (layers.length === 1) {
         if (layers[0].length === 1) {
           setLayerName(layers[0][0].geoviewLayerName!.en! as string);
@@ -843,6 +830,10 @@ export function AddNewLayer(): JSX.Element {
         (layerList as TypeListOfGeoviewLayerConfig).forEach((geoviewLayerConfig) => {
           api.maps[mapId].layer.addGeoviewLayer(geoviewLayerConfig);
         });
+      } else if (layerEntries.length > 0) {
+        (layerEntries as TypeListOfGeoviewLayerConfig).forEach((geoviewLayerConfig) => {
+          api.maps[mapId].layer.addGeoviewLayer(geoviewLayerConfig);
+        });
       }
     } else if (geoviewLayerInstance) {
       geoviewLayerInstance.geoviewLayerName = createLocalizedString(layerName);
diff --git a/packages/geoview-core/src/core/stores/store-interface-and-intial-values/geochart-state.ts b/packages/geoview-core/src/core/stores/store-interface-and-intial-values/geochart-state.ts
index 7561bb01d75..17d1952c52f 100644
--- a/packages/geoview-core/src/core/stores/store-interface-and-intial-values/geochart-state.ts
+++ b/packages/geoview-core/src/core/stores/store-interface-and-intial-values/geochart-state.ts
@@ -1,14 +1,14 @@
 import { useStore } from 'zustand';
+import { TypeArrayOfLayerData } from '@/api/events/payloads/get-feature-info-payload';
+import { GeoChartConfig } from '@/core/utils/config/reader/uuid-config-reader';
+
 import { useGeoViewStore } from '../stores-managers';
 import { TypeGetStore, TypeSetStore } from '../geoview-store';
-import { TypeArrayOfLayerData } from '@/api/events/payloads/get-feature-info-payload';
 
 export type GeoChartStoreByLayerPath = {
-  [layerPath: string]: ChartInfo;
+  [layerPath: string]: GeoChartConfig;
 };
 
-export type ChartInfo = unknown; // unknown, because the definition is in the external package
-
 // #region INTERFACES
 
 export interface IGeochartState {
@@ -29,6 +29,12 @@ export interface IGeochartState {
 
 // #endregion INTERFACES
 
+/**
+ * Initializes a Geochart state object.
+ * @param {TypeSetStore} set The store set callback function
+ * @param {TypeSetStore} get The store get callback function
+ * @returns {IGeochartState} The Geochart state object
+ */
 export function initializeGeochartState(set: TypeSetStore, get: TypeGetStore): IGeochartState {
   const init = {
     geochartChartsConfig: {},
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 a0612690ff9..365a0db4cdf 100644
--- a/packages/geoview-core/src/core/utils/config/config-validation.ts
+++ b/packages/geoview-core/src/core/utils/config/config-validation.ts
@@ -65,6 +65,13 @@ export class ConfigValidation {
   /** The language that will be used to display the GeoView layer. */
   private _displayLanguage: TypeDisplayLanguage;
 
+  // TODO: Refactor - Environment - How to edit this configuration easily per environment?
+  /** The default geocore url */
+  static CONFIG_GEOCORE_URL = 'https://geocore-stage.api.geo.ca';
+
+  /** The default geolocator url */
+  static CONFIG_GEOLOCATOR_URL = 'https://geolocator.api.geo.ca?keys=geonames,nominatim,locate';
+
   /** default configuration if provided configuration is missing or wrong */
   private _defaultMapFeaturesConfig: TypeMapFeaturesConfig = {
     mapId: '',
@@ -92,8 +99,8 @@ export class ConfigValidation {
     corePackages: [],
     overviewMap: undefined,
     serviceUrls: {
-      keys: 'https://geocore.api.geo.ca',
-      geolocator: 'https://geolocator.api.geo.ca?keys=geonames,nominatim,locate',
+      geocoreUrl: ConfigValidation.CONFIG_GEOCORE_URL,
+      geolocator: ConfigValidation.CONFIG_GEOLOCATOR_URL,
     },
     displayLanguage: 'en',
     triggerReadyCallback: false,
diff --git a/packages/geoview-core/src/core/utils/config/config.ts b/packages/geoview-core/src/core/utils/config/config.ts
index 756c565a70d..51eea78cdf7 100644
--- a/packages/geoview-core/src/core/utils/config/config.ts
+++ b/packages/geoview-core/src/core/utils/config/config.ts
@@ -8,8 +8,6 @@ import { JsonConfigReader } from './reader/json-config-reader';
 import { URLmapConfigReader } from './reader/url-config-reader';
 import { logger } from '@/core/utils/logger';
 
-export const catalogUrl = 'https://maps.canada.ca/geonetwork/srv/api/v2/docs';
-
 // ******************************************************************************************************************************
 // ******************************************************************************************************************************
 /** *****************************************************************************************************************************
@@ -168,7 +166,10 @@ export class Config {
     const shared = this.mapElement.getAttribute('data-shared');
     if (shared === 'true') {
       // check if config params have been passed
-      const urlParamsConfig = await URLmapConfigReader.getMapFeaturesConfig(this.mapId);
+      const urlParamsConfig = await URLmapConfigReader.getMapFeaturesConfig(
+        this.configValidation.defaultMapFeaturesConfig.serviceUrls.geocoreUrl,
+        this.mapId
+      );
 
       // use the url params config if provided
       if (urlParamsConfig) mapFeaturesConfig = { ...urlParamsConfig };
diff --git a/packages/geoview-core/src/core/utils/config/reader/div-config-reader.ts b/packages/geoview-core/src/core/utils/config/reader/div-config-reader.ts
index 98348b7c488..4d5d9b4937d 100644
--- a/packages/geoview-core/src/core/utils/config/reader/div-config-reader.ts
+++ b/packages/geoview-core/src/core/utils/config/reader/div-config-reader.ts
@@ -3,9 +3,7 @@ import { TypeMapFeaturesConfig } from '@/core/types/global-types';
 import { isJsonString, removeCommentsFromJSON } from '../../utilities';
 import { logger } from '@/core/utils/logger';
 
-// ******************************************************************************************************************************
-// ******************************************************************************************************************************
-/** *****************************************************************************************************************************
+/**
  * A class to read the configuration of the GeoView map features from an online div. The configuration is provided in an HTML div
  * whose class name is "geoview-map". The div tag also has the attributes id to set the map id, data-lang to specify the display
  * language and data-config to provide the map configuration.
@@ -17,9 +15,8 @@ import { logger } from '@/core/utils/logger';
  * @exports
  * @class URLmapConfigReader
  */
-// ******************************************************************************************************************************
 export class InlineDivConfigReader {
-  /** ***************************************************************************************************************************
+  /**
    * Get the config object from inline map element div.
    * @param {string} mapId The ID of the map.
    * @param {Element} mapElement The map element.
diff --git a/packages/geoview-core/src/core/utils/config/reader/json-config-reader.ts b/packages/geoview-core/src/core/utils/config/reader/json-config-reader.ts
index c2118a1656e..7c5301e0545 100644
--- a/packages/geoview-core/src/core/utils/config/reader/json-config-reader.ts
+++ b/packages/geoview-core/src/core/utils/config/reader/json-config-reader.ts
@@ -2,16 +2,13 @@
 import { TypeMapFeaturesConfig } from '@/core/types/global-types';
 import { logger } from '@/core/utils/logger';
 
-// ******************************************************************************************************************************
-// ******************************************************************************************************************************
-/** *****************************************************************************************************************************
+/**
  * A class to process GeoView map features configuration from JSON file.
  * @exports
  * @class URLmapConfigReader
  */
-// ******************************************************************************************************************************
 export class JsonConfigReader {
-  /** ***************************************************************************************************************************
+  /**
    * Get the config object from json file
    * @param {string} mapId the ID of the map.
    * @param {Element} mapElement the map element
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 014df88bc88..b053d734004 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
@@ -9,21 +9,18 @@ import {
   TypeMapComponents,
 } from '@/geo/map/map-schema-types';
 import { Cast, TypeJsonObject, TypeJsonValue, TypeMapFeaturesConfig } from '@/core/types/global-types';
-import { catalogUrl } from '../config';
 import { UUIDmapConfigReader } from './uuid-config-reader';
 import { ConfigValidation } from '../config-validation';
 import { logger } from '../../logger';
+import { getLocalizedMessage, replaceParams, showError } from '@/app';
 
-// ******************************************************************************************************************************
-// ******************************************************************************************************************************
-/** *****************************************************************************************************************************
+/**
  * A class to process GeoView map features configuration from a URL.
  * @exports
  * @class URLmapConfigReader
  */
-// ******************************************************************************************************************************
 export class URLmapConfigReader {
-  /** ***************************************************************************************************************************
+  /**
    * Parse the search parameters passed from a url
    *
    * @param {string} urlPath A url path with parameters "?..."
@@ -49,7 +46,7 @@ export class URLmapConfigReader {
     return obj;
   }
 
-  /** ***************************************************************************************************************************
+  /**
    * Get url parameters from url param search string
    *
    * @param {objStr} objStr the url parameters string
@@ -91,13 +88,13 @@ export class URLmapConfigReader {
     return obj;
   }
 
-  /** ***************************************************************************************************************************
+  /**
    * Get map config from url parameters
    * @param {string} mapId the map ID of the GeoView map.
    *
    * @returns {Promise<TypeMapFeaturesConfig | undefined>} A map features configuration object generated from url parameters
    */
-  static async getMapFeaturesConfig(mapId: string): Promise<TypeMapFeaturesConfig | undefined> {
+  static async getMapFeaturesConfig(baseUrl: string, mapId: string): Promise<TypeMapFeaturesConfig | undefined> {
     // instanciate the configValidation object used to validate map config attributes and define default values.
     const configValidation = new ConfigValidation();
 
@@ -132,9 +129,20 @@ export class URLmapConfigReader {
 
       // get layer information from catalog using their uuid's if any passed from url params
       if (urlParams.keys) {
-        const requestUrl = `${catalogUrl}/${displayLanguage.split('-')[0]}/${urlParams.keys}`;
-        // TODO: issue 1742, list of layers always empty
-        listOfGeoviewLayerConfig = await UUIDmapConfigReader.getGVlayersConfigFromUUID(mapId, requestUrl);
+        try {
+          // Get the layers config
+          const promise = UUIDmapConfigReader.getGVConfigFromUUIDs(
+            baseUrl,
+            displayLanguage.split('-')[0],
+            urlParams.keys.toString().split(',')
+          );
+          listOfGeoviewLayerConfig = (await promise).layers;
+        } catch (error) {
+          // Log
+          logger.logError('Failed to get the GeoView layers from url keys', urlParams.keys, error);
+          const message = replaceParams([error as TypeJsonValue, mapId], getLocalizedMessage(mapId, 'validation.layer.loadfailed'));
+          showError(mapId, message);
+        }
       }
 
       // get core components
@@ -163,6 +171,9 @@ export class URLmapConfigReader {
           listOfGeoviewLayerConfig,
           extraOptions: {},
         },
+        serviceUrls: {
+          geocoreUrl: baseUrl,
+        },
         components,
         corePackages,
         suportedLanguages: ['en', 'fr'],
diff --git a/packages/geoview-core/src/core/utils/config/reader/uuid-config-reader.ts b/packages/geoview-core/src/core/utils/config/reader/uuid-config-reader.ts
index 12bba526874..9b462a9070f 100644
--- a/packages/geoview-core/src/core/utils/config/reader/uuid-config-reader.ts
+++ b/packages/geoview-core/src/core/utils/config/reader/uuid-config-reader.ts
@@ -1,6 +1,6 @@
 import axios, { AxiosResponse } from 'axios';
 
-import { TypeJsonObject, TypeJsonArray, TypeJsonValue } from '@/core/types/global-types';
+import { TypeJsonObject, TypeJsonArray } from '@/core/types/global-types';
 import {
   TypeEsriDynamicLayerEntryConfig,
   TypeImageStaticLayerEntryConfig,
@@ -20,90 +20,87 @@ import { TypeGeoJSONLayerConfig, TypeGeoJSONLayerEntryConfig } from '@/geo/layer
 import { TypeGeoPackageLayerConfig, TypeGeoPackageLayerEntryConfig } from '@/geo/layer/geoview-layers/vector/geopackage';
 import { TypeXYZTilesConfig, TypeXYZTilesLayerEntryConfig } from '@/geo/layer/geoview-layers/raster/xyz-tiles';
 import { TypeVectorTilesConfig, TypeVectorTilesLayerEntryConfig } from '@/geo/layer/geoview-layers/raster/vector-tiles';
-import { showError, replaceParams, getLocalizedMessage, createLocalizedString } from '@/core/utils/utilities';
+import { createLocalizedString } from '@/core/utils/utilities';
 import { logger } from '@/core/utils/logger';
 
-// ******************************************************************************************************************************
-// ******************************************************************************************************************************
-/** *****************************************************************************************************************************
+// The GeoChart Json object coming out of the GeoCore response
+export type GeoChartGeoCoreConfig = TypeJsonObject & {
+  layers: {
+    layerId: string;
+  };
+}; // TypeJsonObject, because the definition is in the external package
+
+// The GeoChart Json object expected by GeoView
+export type GeoChartConfig = TypeJsonObject & {
+  layers: [
+    {
+      layerId: string;
+    }
+  ];
+}; // TypeJsonObject, because the definition is in the external package
+
+// The returned parsed response
+export type UUIDmapConfigReaderResponse = {
+  layers: TypeListOfGeoviewLayerConfig;
+  geocharts?: GeoChartConfig[];
+};
+
+/**
  * A class to generate GeoView layers config from a URL using a UUID.
  * @exports
  * @class UUIDmapConfigReader
  */
-// ******************************************************************************************************************************
 export class UUIDmapConfigReader {
-  /** ***************************************************************************************************************************
-   * Generate layer configs from uuid request result
-   *
+  /**
+   * Reads and parses Layers configs from uuid request result
    * @param {TypeJsonObject} result the uuid request result
    * @returns {TypeListOfGeoviewLayerConfig} layers parsed from uuid result
    */
-  private static getLayerConfigFromResponse(result: AxiosResponse<TypeJsonObject>): TypeListOfGeoviewLayerConfig {
-    const listOfGeoviewLayerConfig: TypeListOfGeoviewLayerConfig = [];
+  private static getLayerConfigFromResponse(result: AxiosResponse<TypeJsonObject>, lang: string): TypeListOfGeoviewLayerConfig {
+    // If invalid response
+    if (!result?.data || !result.data.reponse || !result.data.reponse.rcs || !result.data.reponse.rcs[lang])
+      throw new Error('Invalid response from GeoCore service');
 
-    if (result?.data) {
-      for (let i = 0; i < (result.data as TypeJsonArray).length; i++) {
-        const data = result.data[i];
+    const listOfGeoviewLayerConfig: TypeListOfGeoviewLayerConfig = [];
+    for (let i = 0; i < (result.data.reponse.rcs[lang] as TypeJsonArray).length; i++) {
+      const data = result.data.reponse.rcs[lang][i];
 
-        if (data?.layers && (data.layers as TypeJsonArray).length > 0) {
-          const layer = data.layers[0];
+      if (data?.layers && (data.layers as TypeJsonArray).length > 0) {
+        const layer = data.layers[0];
 
-          if (layer) {
-            const { layerType, layerEntries, name, url, id, serverType } = layer;
+        if (layer) {
+          const { layerType, layerEntries, name, url, id, serverType } = layer;
 
-            const isFeature = (url as string).indexOf('FeatureServer') > -1;
+          const isFeature = (url as string).indexOf('FeatureServer') > -1;
 
-            if (layerType === CONST_LAYER_TYPES.ESRI_DYNAMIC && !isFeature) {
-              const geoviewLayerConfig: TypeEsriDynamicLayerConfig = {
-                geoviewLayerId: `${id}`,
-                geoviewLayerName: createLocalizedString(name as string),
-                metadataAccessPath: createLocalizedString(url as string),
-                geoviewLayerType: 'esriDynamic',
-                listOfLayerEntryConfig: [],
-              };
-              geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeEsriDynamicLayerEntryConfig => {
-                const esriDynamicLayerEntryConfig = new TypeEsriDynamicLayerEntryConfig({
-                  geoviewLayerConfig,
-                  schemaTag: 'esriDynamic',
-                  entryType: 'raster-image',
-                  layerId: `${item.index}`,
-                  source: {
-                    dataAccessPath: createLocalizedString(url as string),
-                  },
-                } as TypeEsriDynamicLayerEntryConfig);
-                return esriDynamicLayerEntryConfig;
-              });
-              listOfGeoviewLayerConfig.push(geoviewLayerConfig);
-            } else if (isFeature) {
-              for (let j = 0; j < (layerEntries as TypeJsonArray).length; j++) {
-                const featureUrl = `${url}/${layerEntries[j].index}`;
-                const geoviewLayerConfig: TypeEsriFeatureLayerConfig = {
-                  geoviewLayerId: `${id}`,
-                  geoviewLayerName: createLocalizedString(name as string),
-                  metadataAccessPath: createLocalizedString(featureUrl),
-                  geoviewLayerType: 'esriFeature',
-                  listOfLayerEntryConfig: [],
-                };
-                geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeEsriFeatureLayerEntryConfig => {
-                  const esriFeatureLayerEntryConfig = new TypeEsriFeatureLayerEntryConfig({
-                    geoviewLayerConfig,
-                    schemaTag: 'esriFeature',
-                    entryType: 'vector',
-                    layerId: `${item.index}`,
-                    source: {
-                      format: 'EsriJSON',
-                      dataAccessPath: createLocalizedString(url as string),
-                    },
-                  } as TypeEsriFeatureLayerEntryConfig);
-                  return esriFeatureLayerEntryConfig;
-                });
-                listOfGeoviewLayerConfig.push(geoviewLayerConfig);
-              }
-            } else if (layerType === CONST_LAYER_TYPES.ESRI_FEATURE) {
+          if (layerType === CONST_LAYER_TYPES.ESRI_DYNAMIC && !isFeature) {
+            const geoviewLayerConfig: TypeEsriDynamicLayerConfig = {
+              geoviewLayerId: `${id}`,
+              geoviewLayerName: createLocalizedString(name as string),
+              metadataAccessPath: createLocalizedString(url as string),
+              geoviewLayerType: 'esriDynamic',
+              listOfLayerEntryConfig: [],
+            };
+            geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeEsriDynamicLayerEntryConfig => {
+              const esriDynamicLayerEntryConfig = new TypeEsriDynamicLayerEntryConfig({
+                geoviewLayerConfig,
+                schemaTag: 'esriDynamic',
+                entryType: 'raster-image',
+                layerId: `${item.index}`,
+                source: {
+                  dataAccessPath: createLocalizedString(url as string),
+                },
+              } as TypeEsriDynamicLayerEntryConfig);
+              return esriDynamicLayerEntryConfig;
+            });
+            listOfGeoviewLayerConfig.push(geoviewLayerConfig);
+          } else if (isFeature) {
+            for (let j = 0; j < (layerEntries as TypeJsonArray).length; j++) {
+              const featureUrl = `${url}/${layerEntries[j].index}`;
               const geoviewLayerConfig: TypeEsriFeatureLayerConfig = {
                 geoviewLayerId: `${id}`,
                 geoviewLayerName: createLocalizedString(name as string),
-                metadataAccessPath: createLocalizedString(url as string),
+                metadataAccessPath: createLocalizedString(featureUrl),
                 geoviewLayerType: 'esriFeature',
                 listOfLayerEntryConfig: [],
               };
@@ -121,209 +118,256 @@ export class UUIDmapConfigReader {
                 return esriFeatureLayerEntryConfig;
               });
               listOfGeoviewLayerConfig.push(geoviewLayerConfig);
-            } else if (layerType === CONST_LAYER_TYPES.WMS) {
-              const geoviewLayerConfig: TypeWMSLayerConfig = {
-                geoviewLayerId: `${id}`,
-                geoviewLayerName: createLocalizedString(name as string),
-                metadataAccessPath: createLocalizedString(url as string),
-                geoviewLayerType: 'ogcWms',
-                listOfLayerEntryConfig: [],
-              };
-              geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeOgcWmsLayerEntryConfig => {
-                const wmsLayerEntryConfig = new TypeOgcWmsLayerEntryConfig({
-                  geoviewLayerConfig,
-                  schemaTag: 'ogcWms',
-                  entryType: 'raster-image',
-                  layerId: `${item.id}`,
-                  source: {
-                    dataAccessPath: createLocalizedString(url as string),
-                    serverType: (serverType === undefined ? 'mapserver' : serverType) as TypeOfServer,
-                  },
-                } as TypeOgcWmsLayerEntryConfig);
-                return wmsLayerEntryConfig;
-              });
-              listOfGeoviewLayerConfig.push(geoviewLayerConfig);
-            } else if (layerType === CONST_LAYER_TYPES.WFS) {
-              const geoviewLayerConfig: TypeWFSLayerConfig = {
-                geoviewLayerId: `${id}`,
-                geoviewLayerName: createLocalizedString(name as string),
-                metadataAccessPath: createLocalizedString(url as string),
-                geoviewLayerType: 'ogcWfs',
-                listOfLayerEntryConfig: [],
-              };
-              geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeWfsLayerEntryConfig => {
-                const wfsLayerEntryConfig = new TypeWfsLayerEntryConfig({
-                  geoviewLayerConfig,
-                  schemaTag: 'ogcWfs',
-                  entryType: 'vector',
-                  layerId: `${item.id}`,
-                  source: {
-                    format: 'WFS',
-                    strategy: 'all',
-                    dataAccessPath: createLocalizedString(url as string),
-                  },
-                } as TypeWfsLayerEntryConfig);
-                return wfsLayerEntryConfig;
-              });
-              listOfGeoviewLayerConfig.push(geoviewLayerConfig);
-            } else if (layerType === CONST_LAYER_TYPES.OGC_FEATURE) {
-              const geoviewLayerConfig: TypeOgcFeatureLayerConfig = {
-                geoviewLayerId: `${id}`,
-                geoviewLayerName: createLocalizedString(name as string),
-                metadataAccessPath: createLocalizedString(url as string),
-                geoviewLayerType: 'ogcFeature',
-                listOfLayerEntryConfig: [],
-              };
-              geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeOgcFeatureLayerEntryConfig => {
-                const ogcFeatureLayerEntryConfig = new TypeOgcFeatureLayerEntryConfig({
-                  geoviewLayerConfig,
-                  schemaTag: 'ogcFeature',
-                  entryType: 'vector',
-                  layerId: `${item.id}`,
-                  source: {
-                    format: 'featureAPI',
-                    dataAccessPath: createLocalizedString(url as string),
-                  },
-                } as TypeOgcFeatureLayerEntryConfig);
-                return ogcFeatureLayerEntryConfig;
-              });
-              listOfGeoviewLayerConfig.push(geoviewLayerConfig);
-            } else if (layerType === CONST_LAYER_TYPES.GEOJSON) {
-              const geoviewLayerConfig: TypeGeoJSONLayerConfig = {
-                geoviewLayerId: `${id}`,
-                geoviewLayerName: createLocalizedString(name as string),
-                metadataAccessPath: createLocalizedString(url as string),
-                geoviewLayerType: 'GeoJSON',
-                listOfLayerEntryConfig: [],
-              };
-              geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeGeoJSONLayerEntryConfig => {
-                const geoJSONLayerEntryConfig = new TypeGeoJSONLayerEntryConfig({
-                  geoviewLayerConfig,
-                  schemaTag: 'GeoJSON',
-                  entryType: 'vector',
-                  layerId: `${item.id}`,
-                  source: {
-                    format: 'GeoJSON',
-                    dataAccessPath: createLocalizedString(url as string),
-                  },
-                } as TypeGeoJSONLayerEntryConfig);
-                return geoJSONLayerEntryConfig;
-              });
-              listOfGeoviewLayerConfig.push(geoviewLayerConfig);
-            } else if (layerType === CONST_LAYER_TYPES.XYZ_TILES) {
-              const geoviewLayerConfig: TypeXYZTilesConfig = {
-                geoviewLayerId: `${id}`,
-                geoviewLayerName: createLocalizedString(name as string),
-                metadataAccessPath: createLocalizedString(url as string),
-                geoviewLayerType: 'xyzTiles',
-                listOfLayerEntryConfig: [],
-              };
-              geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeXYZTilesLayerEntryConfig => {
-                const xyzTilesLayerEntryConfig = new TypeXYZTilesLayerEntryConfig({
-                  geoviewLayerConfig,
-                  schemaTag: 'xyzTiles',
-                  entryType: 'raster-tile',
-                  layerId: `${item.id}`,
-                  source: {
-                    dataAccessPath: createLocalizedString(url as string),
-                  },
-                } as TypeXYZTilesLayerEntryConfig);
-                return xyzTilesLayerEntryConfig;
-              });
-              listOfGeoviewLayerConfig.push(geoviewLayerConfig);
-            } else if (layerType === CONST_LAYER_TYPES.VECTOR_TILES) {
-              const geoviewLayerConfig: TypeVectorTilesConfig = {
-                geoviewLayerId: `${id}`,
-                geoviewLayerName: createLocalizedString(name as string),
-                metadataAccessPath: createLocalizedString(url as string),
-                geoviewLayerType: 'vectorTiles',
-                listOfLayerEntryConfig: [],
-              };
-              geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeVectorTilesLayerEntryConfig => {
-                const vectorTilesLayerEntryConfig = new TypeVectorTilesLayerEntryConfig({
-                  schemaTag: 'vectorTiles',
-                  entryType: 'raster-tile',
-                  layerId: `${item.id}`,
-                  tileGrid: item.tileGrid as unknown as TypeTileGrid,
-                  source: {
-                    dataAccessPath: createLocalizedString(url as string),
-                  },
-                } as TypeVectorTilesLayerEntryConfig);
-                return vectorTilesLayerEntryConfig;
-              });
-              listOfGeoviewLayerConfig.push(geoviewLayerConfig);
-            } else if (layerType === CONST_LAYER_TYPES.GEOPACKAGE) {
-              const geoviewLayerConfig: TypeGeoPackageLayerConfig = {
-                geoviewLayerId: `${id}`,
-                geoviewLayerName: createLocalizedString(name as string),
-                metadataAccessPath: createLocalizedString(url as string),
-                geoviewLayerType: 'GeoPackage',
-                listOfLayerEntryConfig: [],
-              };
-              geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeGeoPackageLayerEntryConfig => {
-                const geoPackageLayerEntryConfig = new TypeGeoPackageLayerEntryConfig({
-                  geoviewLayerConfig,
-                  schemaTag: 'GeoPackage',
-                  entryType: 'vector',
-                  layerId: `${item.id}`,
-                  source: {
-                    format: 'GeoPackage',
-                    dataAccessPath: createLocalizedString(url as string),
-                  },
-                } as TypeGeoPackageLayerEntryConfig);
-                return geoPackageLayerEntryConfig;
-              });
-              listOfGeoviewLayerConfig.push(geoviewLayerConfig);
-            } else if (layerType === CONST_LAYER_TYPES.IMAGE_STATIC) {
-              const geoviewLayerConfig: TypeImageStaticLayerConfig = {
-                geoviewLayerId: `${id}`,
-                geoviewLayerName: createLocalizedString(name as string),
-                metadataAccessPath: createLocalizedString(url as string),
-                geoviewLayerType: 'imageStatic',
-                listOfLayerEntryConfig: [],
-              };
-              geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeImageStaticLayerEntryConfig => {
-                const imageStaticLayerEntryConfig = new TypeImageStaticLayerEntryConfig({
-                  schemaTag: 'imageStatic',
-                  entryType: 'raster-image',
-                  layerId: `${item.id}`,
-                  source: {
-                    dataAccessPath: createLocalizedString(url as string),
-                  },
-                } as TypeImageStaticLayerEntryConfig);
-                return imageStaticLayerEntryConfig;
-              });
-              listOfGeoviewLayerConfig.push(geoviewLayerConfig);
-            } else {
-              // Log
-              logger.logWarning(`Layer type ${layerType} not supported`);
             }
+          } else if (layerType === CONST_LAYER_TYPES.ESRI_FEATURE) {
+            const geoviewLayerConfig: TypeEsriFeatureLayerConfig = {
+              geoviewLayerId: `${id}`,
+              geoviewLayerName: createLocalizedString(name as string),
+              metadataAccessPath: createLocalizedString(url as string),
+              geoviewLayerType: 'esriFeature',
+              listOfLayerEntryConfig: [],
+            };
+            geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeEsriFeatureLayerEntryConfig => {
+              const esriFeatureLayerEntryConfig = new TypeEsriFeatureLayerEntryConfig({
+                geoviewLayerConfig,
+                schemaTag: 'esriFeature',
+                entryType: 'vector',
+                layerId: `${item.index}`,
+                source: {
+                  format: 'EsriJSON',
+                  dataAccessPath: createLocalizedString(url as string),
+                },
+              } as TypeEsriFeatureLayerEntryConfig);
+              return esriFeatureLayerEntryConfig;
+            });
+            listOfGeoviewLayerConfig.push(geoviewLayerConfig);
+          } else if (layerType === CONST_LAYER_TYPES.WMS) {
+            const geoviewLayerConfig: TypeWMSLayerConfig = {
+              geoviewLayerId: `${id}`,
+              geoviewLayerName: createLocalizedString(name as string),
+              metadataAccessPath: createLocalizedString(url as string),
+              geoviewLayerType: 'ogcWms',
+              listOfLayerEntryConfig: [],
+            };
+            geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeOgcWmsLayerEntryConfig => {
+              const wmsLayerEntryConfig = new TypeOgcWmsLayerEntryConfig({
+                geoviewLayerConfig,
+                schemaTag: 'ogcWms',
+                entryType: 'raster-image',
+                layerId: `${item.id}`,
+                source: {
+                  dataAccessPath: createLocalizedString(url as string),
+                  serverType: (serverType === undefined ? 'mapserver' : serverType) as TypeOfServer,
+                },
+              } as TypeOgcWmsLayerEntryConfig);
+              return wmsLayerEntryConfig;
+            });
+            listOfGeoviewLayerConfig.push(geoviewLayerConfig);
+          } else if (layerType === CONST_LAYER_TYPES.WFS) {
+            const geoviewLayerConfig: TypeWFSLayerConfig = {
+              geoviewLayerId: `${id}`,
+              geoviewLayerName: createLocalizedString(name as string),
+              metadataAccessPath: createLocalizedString(url as string),
+              geoviewLayerType: 'ogcWfs',
+              listOfLayerEntryConfig: [],
+            };
+            geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeWfsLayerEntryConfig => {
+              const wfsLayerEntryConfig = new TypeWfsLayerEntryConfig({
+                geoviewLayerConfig,
+                schemaTag: 'ogcWfs',
+                entryType: 'vector',
+                layerId: `${item.id}`,
+                source: {
+                  format: 'WFS',
+                  strategy: 'all',
+                  dataAccessPath: createLocalizedString(url as string),
+                },
+              } as TypeWfsLayerEntryConfig);
+              return wfsLayerEntryConfig;
+            });
+            listOfGeoviewLayerConfig.push(geoviewLayerConfig);
+          } else if (layerType === CONST_LAYER_TYPES.OGC_FEATURE) {
+            const geoviewLayerConfig: TypeOgcFeatureLayerConfig = {
+              geoviewLayerId: `${id}`,
+              geoviewLayerName: createLocalizedString(name as string),
+              metadataAccessPath: createLocalizedString(url as string),
+              geoviewLayerType: 'ogcFeature',
+              listOfLayerEntryConfig: [],
+            };
+            geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeOgcFeatureLayerEntryConfig => {
+              const ogcFeatureLayerEntryConfig = new TypeOgcFeatureLayerEntryConfig({
+                geoviewLayerConfig,
+                schemaTag: 'ogcFeature',
+                entryType: 'vector',
+                layerId: `${item.id}`,
+                source: {
+                  format: 'featureAPI',
+                  dataAccessPath: createLocalizedString(url as string),
+                },
+              } as TypeOgcFeatureLayerEntryConfig);
+              return ogcFeatureLayerEntryConfig;
+            });
+            listOfGeoviewLayerConfig.push(geoviewLayerConfig);
+          } else if (layerType === CONST_LAYER_TYPES.GEOJSON) {
+            const geoviewLayerConfig: TypeGeoJSONLayerConfig = {
+              geoviewLayerId: `${id}`,
+              geoviewLayerName: createLocalizedString(name as string),
+              metadataAccessPath: createLocalizedString(url as string),
+              geoviewLayerType: 'GeoJSON',
+              listOfLayerEntryConfig: [],
+            };
+            geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeGeoJSONLayerEntryConfig => {
+              const geoJSONLayerEntryConfig = new TypeGeoJSONLayerEntryConfig({
+                geoviewLayerConfig,
+                schemaTag: 'GeoJSON',
+                entryType: 'vector',
+                layerId: `${item.id}`,
+                source: {
+                  format: 'GeoJSON',
+                  dataAccessPath: createLocalizedString(url as string),
+                },
+              } as TypeGeoJSONLayerEntryConfig);
+              return geoJSONLayerEntryConfig;
+            });
+            listOfGeoviewLayerConfig.push(geoviewLayerConfig);
+          } else if (layerType === CONST_LAYER_TYPES.XYZ_TILES) {
+            const geoviewLayerConfig: TypeXYZTilesConfig = {
+              geoviewLayerId: `${id}`,
+              geoviewLayerName: createLocalizedString(name as string),
+              metadataAccessPath: createLocalizedString(url as string),
+              geoviewLayerType: 'xyzTiles',
+              listOfLayerEntryConfig: [],
+            };
+            geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeXYZTilesLayerEntryConfig => {
+              const xyzTilesLayerEntryConfig = new TypeXYZTilesLayerEntryConfig({
+                geoviewLayerConfig,
+                schemaTag: 'xyzTiles',
+                entryType: 'raster-tile',
+                layerId: `${item.id}`,
+                source: {
+                  dataAccessPath: createLocalizedString(url as string),
+                },
+              } as TypeXYZTilesLayerEntryConfig);
+              return xyzTilesLayerEntryConfig;
+            });
+            listOfGeoviewLayerConfig.push(geoviewLayerConfig);
+          } else if (layerType === CONST_LAYER_TYPES.VECTOR_TILES) {
+            const geoviewLayerConfig: TypeVectorTilesConfig = {
+              geoviewLayerId: `${id}`,
+              geoviewLayerName: createLocalizedString(name as string),
+              metadataAccessPath: createLocalizedString(url as string),
+              geoviewLayerType: 'vectorTiles',
+              listOfLayerEntryConfig: [],
+            };
+            geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeVectorTilesLayerEntryConfig => {
+              const vectorTilesLayerEntryConfig = new TypeVectorTilesLayerEntryConfig({
+                schemaTag: 'vectorTiles',
+                entryType: 'raster-tile',
+                layerId: `${item.id}`,
+                tileGrid: item.tileGrid as unknown as TypeTileGrid,
+                source: {
+                  dataAccessPath: createLocalizedString(url as string),
+                },
+              } as TypeVectorTilesLayerEntryConfig);
+              return vectorTilesLayerEntryConfig;
+            });
+            listOfGeoviewLayerConfig.push(geoviewLayerConfig);
+          } else if (layerType === CONST_LAYER_TYPES.GEOPACKAGE) {
+            const geoviewLayerConfig: TypeGeoPackageLayerConfig = {
+              geoviewLayerId: `${id}`,
+              geoviewLayerName: createLocalizedString(name as string),
+              metadataAccessPath: createLocalizedString(url as string),
+              geoviewLayerType: 'GeoPackage',
+              listOfLayerEntryConfig: [],
+            };
+            geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeGeoPackageLayerEntryConfig => {
+              const geoPackageLayerEntryConfig = new TypeGeoPackageLayerEntryConfig({
+                geoviewLayerConfig,
+                schemaTag: 'GeoPackage',
+                entryType: 'vector',
+                layerId: `${item.id}`,
+                source: {
+                  format: 'GeoPackage',
+                  dataAccessPath: createLocalizedString(url as string),
+                },
+              } as TypeGeoPackageLayerEntryConfig);
+              return geoPackageLayerEntryConfig;
+            });
+            listOfGeoviewLayerConfig.push(geoviewLayerConfig);
+          } else if (layerType === CONST_LAYER_TYPES.IMAGE_STATIC) {
+            const geoviewLayerConfig: TypeImageStaticLayerConfig = {
+              geoviewLayerId: `${id}`,
+              geoviewLayerName: createLocalizedString(name as string),
+              metadataAccessPath: createLocalizedString(url as string),
+              geoviewLayerType: 'imageStatic',
+              listOfLayerEntryConfig: [],
+            };
+            geoviewLayerConfig.listOfLayerEntryConfig = (layerEntries as TypeJsonArray).map((item): TypeImageStaticLayerEntryConfig => {
+              const imageStaticLayerEntryConfig = new TypeImageStaticLayerEntryConfig({
+                schemaTag: 'imageStatic',
+                entryType: 'raster-image',
+                layerId: `${item.id}`,
+                source: {
+                  dataAccessPath: createLocalizedString(url as string),
+                },
+              } as TypeImageStaticLayerEntryConfig);
+              return imageStaticLayerEntryConfig;
+            });
+            listOfGeoviewLayerConfig.push(geoviewLayerConfig);
+          } else {
+            // Log
+            logger.logWarning(`Layer type ${layerType} not supported`);
           }
         }
       }
     }
-
     return listOfGeoviewLayerConfig;
   }
 
-  /** ***************************************************************************************************************************
-   * Generate GeoView layers config from a URL using a UUID.
-   * @param {string} mapId the ID of the map.
-   * @param {string} requestUrl the URL to request result
-   * @param {Element} mapElement the map element
-   *
-   * @returns {Promise<TypeGeoviewLayerConfig>} layers parsed from uuid result
+  /**
+   * Reads and parses GeoChart configs from uuid request result
+   * @param {AxiosResponse<GeoChartGeoCoreConfig>} result the uuid request result
+   * @param {string} lang the language to use to read results
+   * @returns {GeoChartConfig[]} the list of GeoChart configs
    */
-  static async getGVlayersConfigFromUUID(mapId: string, requestUrl: string): Promise<TypeListOfGeoviewLayerConfig> {
-    try {
-      const result = await axios.get<TypeJsonObject>(requestUrl);
-      return this.getLayerConfigFromResponse(result);
-    } catch (error: unknown) {
-      // Log
-      logger.logError('Failed to get the GeoView layer from UUI', requestUrl, error);
-      const message = replaceParams([error as TypeJsonValue, mapId], getLocalizedMessage(mapId, 'validation.layer.loadfailed'));
-      showError(mapId, message);
-    }
-    return [];
+  private static getGeoChartConfigFromResponse(result: AxiosResponse<GeoChartGeoCoreConfig>, lang: string): GeoChartConfig[] {
+    // If no geochart information
+    if (!result?.data || !result.data.reponse || !result.data.reponse.gcs || !Array.isArray(result.data.reponse.gcs)) return [];
+
+    // Find all Geochart configs
+    const foundConfigs = result.data.reponse.gcs
+      .map((gcs) => gcs?.[lang]?.packages?.geochart as GeoChartGeoCoreConfig)
+      .filter((geochartValue) => !!geochartValue);
+
+    // For each found config, parse
+    const parsedConfigs: GeoChartConfig[] = [];
+    foundConfigs.forEach((foundConfig) => {
+      // Transform GeoChartGeoCoreConfig to GeoChartConfig
+      parsedConfigs.push({ ...(foundConfig as object), layers: [foundConfig.layers] } as GeoChartConfig);
+    });
+
+    // Return all configs
+    return parsedConfigs;
+  }
+
+  /**
+   * Generates GeoView layers and geocharts configurations, from GeoCore API, using a list of UUIDs.
+   * @param {string} baseUrl the base url of GeoCore API
+   * @param {string} lang the language to get the config for
+   * @param {string[]} uuids a list of uuids to get the configurations for
+   * @returns {Promise<UUIDmapConfigReaderResponse>} layers and geocharts read and parsed from uuids results from GeoCore
+   */
+  static async getGVConfigFromUUIDs(baseUrl: string, lang: string, uuids: string[]): Promise<UUIDmapConfigReaderResponse> {
+    // Build the url
+    const url = `${baseUrl}/vcs?lang=${lang}&id=${uuids.toString()}`;
+
+    // Fetch the config
+    const result = await axios.get<GeoChartGeoCoreConfig>(url);
+
+    // Return the parsed response
+    return {
+      layers: this.getLayerConfigFromResponse(result, lang),
+      geocharts: this.getGeoChartConfigFromResponse(result, lang),
+    };
   }
 }
diff --git a/packages/geoview-core/src/geo/layer/layer.ts b/packages/geoview-core/src/geo/layer/layer.ts
index 6c4723be651..3b1a6ec597c 100644
--- a/packages/geoview-core/src/geo/layer/layer.ts
+++ b/packages/geoview-core/src/geo/layer/layer.ts
@@ -80,7 +80,7 @@ export class Layer {
   featureHighlight: FeatureHighlight;
 
   /**
-   * Initialize layer types and listen to add/remove layer events from outside
+   * Initializes layer types and listen to add/remove layer events from outside
    *
    * @param {string} mapId a reference to the map
    */
@@ -189,7 +189,7 @@ export class Layer {
   }
 
   /**
-   * Delete the event handler functions associated to the Layer instance.
+   * Deletes the event handler functions associated to the Layer instance.
    */
   deleteEventHandlerFunctionsOfThisLayerInstance() {
     api.event.off(EVENT_NAMES.LAYER.EVENT_ADD_LAYER, this.mapId, this.eventHandlerFunctions!.addLayer);
@@ -197,7 +197,7 @@ export class Layer {
   }
 
   /**
-   * Load layers that was passed in with the map config
+   * Loads layers that was passed in with the map config
    *
    * @param {TypeGeoviewLayerConfig[]} geoviewLayerConfigs an optional array containing layers passed within the map config
    */
@@ -232,7 +232,7 @@ export class Layer {
   }
 
   /**
-   * Validate the geoview layer configuration array to eliminate duplicate entries and inform the user.
+   * Validates the geoview layer configuration array to eliminate duplicate entries and inform the user.
    * @param {TypeGeoviewLayerConfig[]} geoviewLayerConfigs The geoview layer configurations to validate.
    *
    * @returns {TypeGeoviewLayerConfig} The new configuration with duplicate entries eliminated.
@@ -257,7 +257,7 @@ export class Layer {
   }
 
   /**
-   * Print an error message for the duplicate geoview layer configuration.
+   * Prints an error message for the duplicate geoview layer configuration.
    * @param {TypeGeoviewLayerConfig} geoviewLayerConfig The geoview layer configuration in error.
    */
   private printDuplicateGeoviewLayerConfigError(geoviewLayerConfig: TypeGeoviewLayerConfig) {
@@ -272,7 +272,7 @@ export class Layer {
   }
 
   /**
-   * This method returns the GeoView instance associated to a specific layer path. The first element of the layerPath
+   * Returns the GeoView instance associated to a specific layer path. The first element of the layerPath
    * is the geoviewLayerId.
    * @param {string} layerPath The layer path to the layer's configuration.
    *
@@ -285,7 +285,7 @@ export class Layer {
   }
 
   /**
-   * Method used to verify if a layer is registered. Returns true if registered.
+   * Verifies if a layer is registered. Returns true if registered.
    * @param {TypeLayerEntryConfig} layerConfig The layer configuration to test.
    *
    * @returns {boolean} Returns true if the layer configuration is registered.
@@ -296,7 +296,7 @@ export class Layer {
   }
 
   /**
-   * Add the layer to the map if valid. If not (is a string) emit an error
+   * Adds the layer to the map if valid. If not (is a string) emit an error
    * @param {any} geoviewLayer the layer config
    */
   addToMap(geoviewLayer: AbstractGeoViewLayer): void {
@@ -325,7 +325,7 @@ export class Layer {
   }
 
   /**
-   * Remove a layer from the map using its layer path. The path may point to the root geoview layer
+   * Removes a layer from the map using its layer path. The path may point to the root geoview layer
    * or a sub layer.
    *
    * @param {string} partialLayerPath the path of the layer to be removed
@@ -363,7 +363,7 @@ export class Layer {
   };
 
   /**
-   * Add a layer to the map
+   * Adds a layer to the map
    *
    * @param {TypeGeoviewLayerConfig} geoviewLayerConfig the geoview layer configuration to add
    * @param {TypeListOfLocalizedLanguages} optionalSuportedLanguages an optional list of supported language
@@ -389,7 +389,21 @@ export class Layer {
   };
 
   /**
-   * Remove a geoview layer from the map
+   * Adds a Geoview Layer by GeoCore UUID.
+   * Example: cgpv.api.maps['UIM10'].layer.addGeoviewLayerByGeoCoreUUID('21b821cf-0f1c-40ee-8925-eab12d357668')
+   * @param mapId The map id to add to
+   * @param uuid The GeoCore UUID
+   */
+  addGeoviewLayerByGeoCoreUUID = async (uuid: string): Promise<void> => {
+    const geoCoreGeoviewLayerInstance = new GeoCore(this.mapId);
+    const layers = await geoCoreGeoviewLayerInstance.createLayersFromUUID(uuid);
+    layers[0].forEach((geoviewLayerConfig) => {
+      api.maps[this.mapId].layer.addGeoviewLayer(geoviewLayerConfig);
+    });
+  };
+
+  /**
+   * Removes a geoview layer from the map
    *
    * @param {TypeGeoviewLayerConfig} geoviewLayer the layer configuration to remove
    */
@@ -400,7 +414,7 @@ export class Layer {
   };
 
   /**
-   * Remove all geoview layers from the map
+   * Removes all geoview layers from the map
    */
   removeAllGeoviewLayers = () => {
     Object.keys(this.geoviewLayers).forEach((layerId: string) => {
@@ -411,7 +425,7 @@ export class Layer {
   };
 
   /**
-   * Search for a layer using its id and return the layer data
+   * Searches for a layer using its id and return the layer data
    *
    * @param {string} geoviewLayerId the layer id to look for
    * @returns the found layer data object
@@ -485,7 +499,7 @@ export class Layer {
   };
 
   /**
-   * Highlight layer or sublayer on map
+   * Highlights layer or sublayer on map
    *
    * @param {string} layerPath ID of layer to highlight
    */
@@ -520,7 +534,7 @@ export class Layer {
   }
 
   /**
-   * Remove layer or sublayer highlight
+   * Removes layer or sublayer highlight
    */
   removeHighlightLayer(): void {
     api.maps[this.mapId].layer.featureHighlight.removeBBoxHighlight();
diff --git a/packages/geoview-core/src/geo/layer/other/geocore.ts b/packages/geoview-core/src/geo/layer/other/geocore.ts
index 0a73634a36d..aeeedf23d64 100644
--- a/packages/geoview-core/src/geo/layer/other/geocore.ts
+++ b/packages/geoview-core/src/geo/layer/other/geocore.ts
@@ -1,7 +1,12 @@
-/* eslint-disable no-param-reassign */
 import defaultsDeep from 'lodash/defaultsDeep';
-import { api } from '@/app';
-import { catalogUrl } from '@/core/utils/config/config';
+import { TypeJsonValue, api, generateId, getLocalizedMessage, replaceParams, showError } from '@/app';
+import { UUIDmapConfigReader, UUIDmapConfigReaderResponse } from '@/core/utils/config/reader/uuid-config-reader';
+import { ConfigValidation } from '@/core/utils/config/config-validation';
+import { AppEventProcessor } from '@/api/event-processors/event-processor-children/app-event-processor';
+import { GeochartEventProcessor } from '@/api/event-processors/event-processor-children/geochart-event-processor';
+import { logger } from '@/core/utils/logger';
+import { MapEventProcessor } from '@/api/event-processors/event-processor-children/map-event-processor';
+
 import {
   TypeLayerEntryConfig,
   TypeGeoviewLayerConfig,
@@ -10,11 +15,9 @@ import {
   TypeLocalizedString,
   layerEntryIsGroupLayer,
   TypeListOfLayerEntryConfig,
+  TypeLayerEntryType,
 } from '../../map/map-schema-types';
-import { CONST_LAYER_TYPES } from '../geoview-layers/abstract-geoview-layers';
-import { UUIDmapConfigReader } from '@/core/utils/config/reader/uuid-config-reader';
-import { ConfigValidation } from '@/core/utils/config/config-validation';
-import { AppEventProcessor } from '@/api/event-processors/event-processor-children/app-event-processor';
+import { CONST_LAYER_TYPES, TypeGeoviewLayerType } from '../geoview-layers/abstract-geoview-layers';
 
 export interface TypeGeoCoreLayerConfig extends Omit<TypeGeoviewLayerConfig, 'listOfLayerEntryConfig'> {
   geoviewLayerType: 'geoCore';
@@ -61,7 +64,7 @@ export class GeoCore {
   private configValidation = new ConfigValidation();
 
   /**
-   * Initialize layer
+   * Constructor
    * @param {string} mapId the id of the map
    */
   constructor(mapId: string) {
@@ -69,37 +72,94 @@ export class GeoCore {
   }
 
   /**
-   * Get GeoView layer configurations list from the UUIDs of the list of layer entry configurations.
+   * Builds a Geocore Layer Config from a given UUID
+   * @param {string} uuid the given uuid to build the Geocore Layer Config with
+   * @returns {TypeGeoCoreLayerConfig} the GeoCore Layer Config
+   */
+  static buildGeocoreLayerConfigFromUUID(uuid: string): TypeGeoCoreLayerConfig {
+    return {
+      geoviewLayerId: generateId(),
+      geoviewLayerType: 'geoCore',
+      listOfLayerEntryConfig: [
+        new TypeGeocoreLayerEntryConfig({
+          schemaTag: 'geoCore' as TypeGeoviewLayerType,
+          entryType: 'geoCore' as TypeLayerEntryType,
+          layerId: uuid,
+        } as TypeGeocoreLayerEntryConfig),
+      ] as TypeGeocoreLayerEntryConfig[],
+    } as TypeGeoCoreLayerConfig;
+  }
+
+  /**
+   *  Gets GeoView layer configurations list from the given UUID. Creates the GeoCore Layer Config in the process.
+   *
+   * @param {string} uuid the given uuid to build the Geocore Layer Config with
+   * @returns {Promise<TypeListOfGeoviewLayerConfig[]>} the GeoCore Layer Config promise
+   */
+  createLayersFromUUID(uuid: string): Promise<TypeListOfGeoviewLayerConfig[]> {
+    // Create the config
+    const geocoreConfig = GeoCore.buildGeocoreLayerConfigFromUUID(uuid);
+
+    // Create the layers
+    return this.createLayers(geocoreConfig);
+  }
+
+  /**
+   * Gets GeoView layer configurations list from the UUIDs of the list of layer entry configurations.
    *
    * @param {TypeGeocoreLayerEntryConfig} geocoreLayerConfig the layer configuration
    * @returns {Promise<TypeListOfGeoviewLayerConfig>} list of layer configurations to add to the map
    */
-  createLayers(geocoreLayerConfig: TypeGeoCoreLayerConfig): Promise<TypeListOfGeoviewLayerConfig[]> {
-    const arrayOfListOfGeoviewLayerConfig = new Promise<TypeListOfGeoviewLayerConfig[]>((resolve) => {
-      const url = geocoreLayerConfig.metadataAccessPath || `${catalogUrl}/${api.maps[this.mapId].getDisplayLanguage()}`;
-      const promiseOfLayerConfigs: Promise<TypeListOfGeoviewLayerConfig>[] = [];
-      geocoreLayerConfig.listOfLayerEntryConfig.forEach((layerConfig: TypeLayerEntryConfig) => {
-        const requestUrl = `${url}/${layerConfig.layerId}`;
-        promiseOfLayerConfigs.push(UUIDmapConfigReader.getGVlayersConfigFromUUID(this.mapId, requestUrl));
+  async createLayers(geocoreLayerConfig: TypeGeoCoreLayerConfig): Promise<TypeListOfGeoviewLayerConfig[]> {
+    // Get the map config
+    const mapConfig = MapEventProcessor.getGeoViewMapConfig(this.mapId);
+
+    // For each layer entry config in the list
+    const promiseOfLayerConfigs: Promise<UUIDmapConfigReaderResponse>[] = [];
+    geocoreLayerConfig.listOfLayerEntryConfig.forEach((layerConfig: TypeLayerEntryConfig) => {
+      // Get the language
+      const lang = api.maps[this.mapId].getDisplayLanguage();
+
+      // Generate the url
+      // TODO: Check - Is the metadataAccessPath still used? Because it seems to be incompatible with the rest now?
+      const url = geocoreLayerConfig.metadataAccessPath?.[lang] || `${mapConfig!.serviceUrls.geocoreUrl}`;
+
+      try {
+        // Get the GV config from UUID
+        promiseOfLayerConfigs.push(UUIDmapConfigReader.getGVConfigFromUUIDs(url, lang, [layerConfig.layerId]));
+      } catch (error) {
+        // Log
+        logger.logError('Failed to get the GeoView layer from UUI', layerConfig.layerId, error);
+        const message = replaceParams([error as TypeJsonValue, this.mapId], getLocalizedMessage(this.mapId, 'validation.layer.loadfailed'));
+        showError(this.mapId, message);
+      }
+    });
+
+    // Wait until all configs processed
+    const listOfLayerCreated = await Promise.all(promiseOfLayerConfigs);
+
+    // For each config
+    listOfLayerCreated.forEach((listOfGeoviewLayerConfig, index) => {
+      listOfGeoviewLayerConfig.layers.forEach((geoviewLayerConfig) => {
+        this.copyConfigSettingsOverGeocoreSettings(geocoreLayerConfig.listOfLayerEntryConfig[index], geoviewLayerConfig);
       });
-      Promise.all(promiseOfLayerConfigs).then((listOfLayerCreated) => {
-        listOfLayerCreated.forEach((listOfGeoviewLayerConfig, index) => {
-          listOfGeoviewLayerConfig.forEach((geoviewLayerConfig) => {
-            this.copyConfigSettingsOverGeocoreSettings(geocoreLayerConfig.listOfLayerEntryConfig[index], geoviewLayerConfig);
-          });
-          this.configValidation.validateListOfGeoviewLayerConfig(
-            AppEventProcessor.getSupportedLanguages(this.mapId),
-            listOfGeoviewLayerConfig
-          );
-        });
-        resolve(listOfLayerCreated);
+      this.configValidation.validateListOfGeoviewLayerConfig(
+        AppEventProcessor.getSupportedLanguages(this.mapId),
+        listOfGeoviewLayerConfig.layers
+      );
+
+      // For each found geochart associated with the Geocore UUID
+      listOfGeoviewLayerConfig.geocharts?.forEach((geochartConfig) => {
+        // Add a GeoChart
+        GeochartEventProcessor.addGeochartChart(this.mapId, geochartConfig.layers[0].layerId as string, geochartConfig);
       });
     });
-    return arrayOfListOfGeoviewLayerConfig;
+
+    return listOfLayerCreated.map((config) => config.layers);
   }
 
   /**
-   * Copy the config settings over the geocore values (config values have priority).
+   * Copies the config settings over the geocore values (config values have priority).
    *
    * @param {TypeGeocoreLayerEntryConfig} geocoreLayerEntryConfig The config file settings
    * @param {TypeGeoviewLayerConfig} geoviewLayerConfig The settings returned by the geocore service
@@ -109,6 +169,7 @@ export class GeoCore {
     geoviewLayerConfig: TypeGeoviewLayerConfig
   ) {
     if (geocoreLayerEntryConfig.geocoreLayerName)
+      // eslint-disable-next-line no-param-reassign
       geoviewLayerConfig.geoviewLayerName = {
         ...geocoreLayerEntryConfig.geocoreLayerName,
       } as TypeLocalizedString;
@@ -127,6 +188,7 @@ export class GeoCore {
                 } else
                   throw new Error(`Geocore group id ${layerEntryFromService.layerId} should be defined as a group in the configuration`);
               } else {
+                // eslint-disable-next-line no-param-reassign
                 arrayFromService[i] = defaultsDeep(layerEntryFromConfig, layerEntryFromService);
                 // Force a found property to the layerEntryFromConfig object
                 Object.assign(layerEntryFromConfig, { found: true });
@@ -135,6 +197,7 @@ export class GeoCore {
             }
             return false;
           });
+          // eslint-disable-next-line no-param-reassign
           if (!entryFound) arrayFromService[i].layerId = '';
         });
         for (let i = layerArrayFromService.length - 1; i >= 0; i--)
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 9bc37fed77b..de3114f9b10 100644
--- a/packages/geoview-core/src/geo/map/map-schema-types.ts
+++ b/packages/geoview-core/src/geo/map/map-schema-types.ts
@@ -1489,6 +1489,8 @@ export const VALID_DISPLAY_THEME: TypeDisplayTheme[] = ['dark', 'light', 'geo.ca
 export type TypeMapFeaturesInstance = {
   /** map configuration. */
   map: TypeMapConfig;
+  /** Service URLs. */
+  serviceUrls: TypeServiceUrls;
   /** Display theme, default = geo.ca. */
   theme?: TypeDisplayTheme;
   /** Nav bar properies. */
@@ -1505,9 +1507,6 @@ export type TypeMapFeaturesInstance = {
   corePackages?: TypeMapCorePackages;
   /** List of external packages. */
   externalPackages?: TypeExternalPackages;
-  /** Service URLs. */
-  // ?: Is this attribute realy needed, it is used nowhere in our code. If you delete it, update the doc (docs\app\map-config\README.md)
-  serviceUrls?: TypeServiceUrls;
   /**
    * ISO 639-1 code indicating the languages supported by the configuration file. It will use value(s) provided here to
    * access bilangual configuration nodes. For value(s) provided here, each bilingual configuration node MUST provide a value.
@@ -1712,8 +1711,7 @@ export type TypeServiceUrls = {
    * Service end point to access API for layers specification (loading and plugins parameters). By default it is GeoCore but can
    * be another endpoint with similar output.
    */
-  // ?: key or keys - The description only talk about a single service endpoint and the type is not an array but a string.
-  keys: string;
+  geocoreUrl: string;
   /**
    * An optional proxy to be used for dealing with same-origin issues.  URL must either be a relative path on the same server
    * or an absolute path on a server which sets CORS headers.
diff --git a/packages/geoview-geochart/src/geochart-panel.tsx b/packages/geoview-geochart/src/geochart-panel.tsx
index e9740d32264..258c00eb4fc 100644
--- a/packages/geoview-geochart/src/geochart-panel.tsx
+++ b/packages/geoview-geochart/src/geochart-panel.tsx
@@ -58,7 +58,7 @@ export function GeoChartPanel(props: GeoChartPanelProps): JSX.Element {
   const handleIsEnlargeClicked = useCallback(
     (isEnlarge: boolean) => {
       // Log
-      logger.logTraceUseCallback('GEOCHART-PANEL - is enlarge', isEnlarge);
+      logger.logTraceUseCallback('GEOCHART-PANEL - handleIsEnlargeClicked', isEnlarge);
 
       // We need to redraw when the canvas isn't 'showing' in the DOM and when the user resizes the canvas placeholder.
       cgpv.api.maps[mapId].plugins.geochart.redrawChart();
@@ -67,7 +67,7 @@ export function GeoChartPanel(props: GeoChartPanelProps): JSX.Element {
   );
 
   /**
-   * Get the label for the number of features of a layer.
+   * Gets the label for the number of features of a layer.
    * @returns string
    */
   const getNumFeaturesLabel = useCallback(
@@ -89,7 +89,7 @@ export function GeoChartPanel(props: GeoChartPanelProps): JSX.Element {
   const handleLayerChange = useCallback(
     (layer: LayerListEntry): void => {
       // Log
-      logger.logTraceUseCallback('GEOCHART-PANEL - layer', layer);
+      logger.logTraceUseCallback('GEOCHART-PANEL - handleLayerChange', layer);
 
       // Set the selected layer path in the store which will in turn trigger the store listeners on this component
       setSelectedLayerPath(layer.layerPath);
@@ -100,7 +100,7 @@ export function GeoChartPanel(props: GeoChartPanelProps): JSX.Element {
   // Reacts when the array of layer data updates
   const memoLayersList = useMemo(() => {
     // Log
-    logger.logTraceUseMemo('GEOCHART-PANEL - ArrayOfLayerData', storeArrayOfLayerData);
+    logger.logTraceUseMemo('GEOCHART-PANEL - memoLayersList', storeArrayOfLayerData);
 
     // Set the layers list
     return visibleLayers
@@ -121,7 +121,7 @@ export function GeoChartPanel(props: GeoChartPanelProps): JSX.Element {
   }, [visibleLayers, storeArrayOfLayerData, configObj, getNumFeaturesLabel]);
 
   /**
-   * Memoize the selected layer for the LayerList component.
+   * Memoizes the selected layer for the LayerList component.
    */
   const memoLayerSelectedItem = useMemo(() => {
     // Log
diff --git a/packages/geoview-geochart/src/geochart-parsing.ts b/packages/geoview-geochart/src/geochart-parsing.ts
index b88900a5da2..39e1f04b7e2 100644
--- a/packages/geoview-geochart/src/geochart-parsing.ts
+++ b/packages/geoview-geochart/src/geochart-parsing.ts
@@ -32,7 +32,7 @@ const findLayerConfig = (
       // If still not found
       if (!foundConfigLyr) {
         // Find the config that works with the layer (if any)
-        const layerConfigs = c.layers!.filter((x: GeoViewGeoChartConfigLayer) => {
+        const layerConfigs = c.layers.filter((x: GeoViewGeoChartConfigLayer) => {
           return x.layerId === layerId;
         });
 
diff --git a/packages/geoview-geochart/src/geochart-types.ts b/packages/geoview-geochart/src/geochart-types.ts
index 3111f8c040f..87c3b1ad987 100644
--- a/packages/geoview-geochart/src/geochart-types.ts
+++ b/packages/geoview-geochart/src/geochart-types.ts
@@ -11,7 +11,7 @@ export type PluginGeoChartConfig<TType extends ChartType> = {
  * Definition of options for each type of chart used for by the plugin.
  */
 export type GeoViewGeoChartConfig<TType extends ChartType> = GeoChartConfig<TType> & {
-  layers?: GeoViewGeoChartConfigLayer[];
+  layers: GeoViewGeoChartConfigLayer[];
 };
 
 /**
diff --git a/packages/geoview-geochart/src/geochart.tsx b/packages/geoview-geochart/src/geochart.tsx
index d1acb3e184b..d6585ac66c7 100644
--- a/packages/geoview-geochart/src/geochart.tsx
+++ b/packages/geoview-geochart/src/geochart.tsx
@@ -136,7 +136,7 @@ export function GeoChart(props: GeoChartProps): JSX.Element {
   );
 
   /**
-   * Memoize the fetching of the correct config based on the provided layers array (TypeArrayOfLayerData).
+   * Memoizes the fetching of the correct config based on the provided layers array (TypeArrayOfLayerData).
    */
   const memoAllInfo = useMemo(() => {
     // Find the right config/layer/data for what we want based on the layerDataArray