From 3d8f5ced01cc810a4eb34856e35fbcae943bcff1 Mon Sep 17 00:00:00 2001 From: stefano bovio Date: Thu, 28 Oct 2021 11:35:48 +0200 Subject: [PATCH] #553: Restore support of arcgis layers (#554) --- .../client/js/apps/gn-dashboard.js | 100 ++++++------ .../client/js/apps/gn-geostory.js | 95 ++++++------ .../client/js/utils/ResourceUtils.js | 143 +++++++++++------- .../js/utils/__tests__/ResourceUtils-test.js | 20 +++ .../static/mapstore/configs/localConfig.json | 2 +- 5 files changed, 209 insertions(+), 151 deletions(-) diff --git a/geonode_mapstore_client/client/js/apps/gn-dashboard.js b/geonode_mapstore_client/client/js/apps/gn-dashboard.js index 603e5cc56b..ebbbfb081a 100644 --- a/geonode_mapstore_client/client/js/apps/gn-dashboard.js +++ b/geonode_mapstore_client/client/js/apps/gn-dashboard.js @@ -72,61 +72,65 @@ document.addEventListener('DOMContentLoaded', function() { geoNodeConfiguration, pluginsConfigKey, configEpics, + mapType = 'openlayers', onStoreInit, geoNodePageConfig, targetId = 'ms-container', settings } = setupConfiguration({ localConfig, user }); - main({ - targetId, - appComponent: withRoutes(routes)(ConnectedRouter), - pluginsConfig: getPluginsConfiguration(localConfig.plugins, pluginsConfigKey), - loaderComponent: MainLoader, - lazyPlugins: pluginsDefinition.lazyPlugins, - pluginsDef: { - plugins: { - ...pluginsDefinition.plugins - }, - requires: { - ...requires, - ...pluginsDefinition.requires - } - }, - initialState: { - defaultState: { - maptype: { - mapType: 'openlayers' + import('@js/map/' + mapType + '/plugins/ArcGisMapServer') + .then(() => { + main({ + targetId, + appComponent: withRoutes(routes)(ConnectedRouter), + pluginsConfig: getPluginsConfiguration(localConfig.plugins, pluginsConfigKey), + loaderComponent: MainLoader, + lazyPlugins: pluginsDefinition.lazyPlugins, + pluginsDef: { + plugins: { + ...pluginsDefinition.plugins + }, + requires: { + ...requires, + ...pluginsDefinition.requires + } }, - ...securityState - } - }, - themeCfg: null, - appReducers: { - dashboard, - gnresource, - gnsettings, - security, - maptype, - widgets - }, - appEpics: { - ...configEpics, - ...gnresourceEpics - }, - onStoreInit, - geoNodeConfiguration, - initialActions: [ - // add some settings in the global state to make them accessible in the monitor state - // later we could use expression in localConfig - updateGeoNodeSettings.bind(null, settings), - ...(geoNodePageConfig.resourceId !== undefined - ? [ requestResourceConfig.bind(null, ResourceTypes.DASHBOARD, geoNodePageConfig.resourceId, { - readOnly: geoNodePageConfig.isEmbed - }) ] - : []) - ] - }); + initialState: { + defaultState: { + maptype: { + mapType: 'openlayers' + }, + ...securityState + } + }, + themeCfg: null, + appReducers: { + dashboard, + gnresource, + gnsettings, + security, + maptype, + widgets + }, + appEpics: { + ...configEpics, + ...gnresourceEpics + }, + onStoreInit, + geoNodeConfiguration, + initialActions: [ + // add some settings in the global state to make them accessible in the monitor state + // later we could use expression in localConfig + updateGeoNodeSettings.bind(null, settings), + ...(geoNodePageConfig.resourceId !== undefined + ? [ requestResourceConfig.bind(null, ResourceTypes.DASHBOARD, geoNodePageConfig.resourceId, { + readOnly: geoNodePageConfig.isEmbed + }) ] + : []) + ] + }); + }); }); }); diff --git a/geonode_mapstore_client/client/js/apps/gn-geostory.js b/geonode_mapstore_client/client/js/apps/gn-geostory.js index 49f35d954f..17e1c4dc17 100644 --- a/geonode_mapstore_client/client/js/apps/gn-geostory.js +++ b/geonode_mapstore_client/client/js/apps/gn-geostory.js @@ -73,57 +73,62 @@ document.addEventListener('DOMContentLoaded', function() { pluginsConfigKey, geoNodePageConfig, configEpics, + mapType = 'openlayers', onStoreInit, targetId = 'ms-container', settings } = setupConfiguration({ localConfig, user }); - main({ - targetId, - appComponent: withRoutes(routes)(ConnectedRouter), - pluginsConfig: getPluginsConfiguration(localConfig.plugins, pluginsConfigKey), - loaderComponent: MainLoader, - lazyPlugins: pluginsDefinition.lazyPlugins, - pluginsDef: { - plugins: { - ...pluginsDefinition.plugins - }, - requires: { - ...requires, - ...pluginsDefinition.requires - } - }, - initialState: { - defaultState: { - maptype: { - mapType: 'openlayers' + // register custom arcgis layer + import('@js/map/' + mapType + '/plugins/ArcGisMapServer') + .then(() => { + main({ + targetId, + appComponent: withRoutes(routes)(ConnectedRouter), + pluginsConfig: getPluginsConfiguration(localConfig.plugins, pluginsConfigKey), + loaderComponent: MainLoader, + lazyPlugins: pluginsDefinition.lazyPlugins, + pluginsDef: { + plugins: { + ...pluginsDefinition.plugins + }, + requires: { + ...requires, + ...pluginsDefinition.requires + } }, - ...securityState - } - }, - themeCfg: null, - appReducers: { - geostory, - gnresource, - gnsettings, - security, - maptype - }, - appEpics: { - ...configEpics, - ...gnresourceEpics - }, - onStoreInit, - geoNodeConfiguration, - initialActions: [ - // add some settings in the global state to make them accessible in the monitor state - // later we could use expression in localConfig - updateGeoNodeSettings.bind(null, settings), - ...(geoNodePageConfig.resourceId !== undefined - ? [ requestResourceConfig.bind(null, ResourceTypes.GEOSTORY, geoNodePageConfig.resourceId) ] - : []) - ] - }); + initialState: { + defaultState: { + maptype: { + mapType: 'openlayers' + }, + ...securityState + } + }, + themeCfg: null, + appReducers: { + geostory, + gnresource, + gnsettings, + security, + maptype + }, + appEpics: { + ...configEpics, + ...gnresourceEpics + }, + onStoreInit, + geoNodeConfiguration, + initialActions: [ + // add some settings in the global state to make them accessible in the monitor state + // later we could use expression in localConfig + updateGeoNodeSettings.bind(null, settings), + ...(geoNodePageConfig.resourceId !== undefined + ? [ requestResourceConfig.bind(null, ResourceTypes.GEOSTORY, geoNodePageConfig.resourceId) ] + : []) + ] + }); + }); }); }); diff --git a/geonode_mapstore_client/client/js/utils/ResourceUtils.js b/geonode_mapstore_client/client/js/utils/ResourceUtils.js index 69f0114f76..b48ea472d1 100644 --- a/geonode_mapstore_client/client/js/utils/ResourceUtils.js +++ b/geonode_mapstore_client/client/js/utils/ResourceUtils.js @@ -30,6 +30,18 @@ function getExtentFromResource({ ll_bbox_polygon: llBboxPolygon }) { return bbox; } +const GXP_PTYPES = { + 'AUTO': 'gxp_wmscsource', + 'OWS': 'gxp_wmscsource', + 'WMS': 'gxp_wmscsource', + 'WFS': 'gxp_wmscsource', + 'WCS': 'gxp_wmscsource', + 'REST_MAP': 'gxp_arcrestsource', + 'REST_IMG': 'gxp_arcrestsource', + 'HGL': 'gxp_hglsource', + 'GN_WMS': 'gxp_geonodecataloguesource' +}; + /** * convert resource layer configuration to a mapstore layer object * @memberof MenuUtils @@ -47,67 +59,84 @@ export const resourceToLayerConfig = (resource) => { pk, has_time: hasTime, default_style: defaultStyle, - styles + styles, + ptype } = resource; const bbox = getExtentFromResource(resource); + switch (ptype) { + case GXP_PTYPES.REST_MAP: + case GXP_PTYPES.REST_IMG: { + const { url: arcgisUrl } = links.find(({ mime }) => mime === 'text/html') || {}; + return { + perms, + id: uuid(), + pk, + type: 'arcgis', + name: alternate.replace('remoteWorkspace:', ''), + url: arcgisUrl, + ...(bbox && { bbox }), + title, + visibility: true + }; + } + default: + const { url: wfsUrl } = links.find(({ link_type: linkType }) => linkType === 'OGC:WFS') || {}; + const { url: wmsUrl } = links.find(({ link_type: linkType }) => linkType === 'OGC:WMS') || {}; + const { url: wmtsUrl } = links.find(({ link_type: linkType }) => linkType === 'OGC:WMTS') || {}; - const { url: wfsUrl } = links.find(({ link_type: linkType }) => linkType === 'OGC:WFS') || {}; - const { url: wmsUrl } = links.find(({ link_type: linkType }) => linkType === 'OGC:WMS') || {}; - const { url: wmtsUrl } = links.find(({ link_type: linkType }) => linkType === 'OGC:WMTS') || {}; - - const dimensions = [ - ...(hasTime ? [{ - name: 'time', - source: { - type: 'multidim-extension', - url: wmtsUrl || (wmsUrl || '').split('/geoserver/')[0] + '/geoserver/gwc/service/wmts' - } - }] : []) - ]; - - const params = wmsUrl && url.parse(wmsUrl, true).query; - const format = getConfigProp('defaultLayerFormat') || 'image/png'; + const dimensions = [ + ...(hasTime ? [{ + name: 'time', + source: { + type: 'multidim-extension', + url: wmtsUrl || (wmsUrl || '').split('/geoserver/')[0] + '/geoserver/gwc/service/wmts' + } + }] : []) + ]; - return { - perms, - id: uuid(), - pk, - type: 'wms', - name: alternate, - url: wmsUrl || '', - format, - ...(wfsUrl && { - search: { - type: 'wfs', - url: wfsUrl - } - }), - ...(bbox && { bbox }), - ...(template && { - featureInfo: { - format: 'TEMPLATE', - template - } - }), - style: '', - title, - visibility: true, - ...(defaultStyle && { - defaultStyle: { - title: defaultStyle.sld_title, - name: defaultStyle.workspace ? `${defaultStyle.workspace}:${defaultStyle.name}` : defaultStyle.name - } - }), - ...(styles && { - availableStyles: [ ...styles ].map((style) => ({ - title: style.sld_title, - name: style.workspace ? `${style.workspace}:${style.name}` : style.name - })) - }), - ...(params && { params }), - ...(dimensions.length > 0 && ({ dimensions })) - }; + const params = wmsUrl && url.parse(wmsUrl, true).query; + const format = getConfigProp('defaultLayerFormat') || 'image/png'; + return { + perms, + id: uuid(), + pk, + type: 'wms', + name: alternate, + url: wmsUrl || '', + format, + ...(wfsUrl && { + search: { + type: 'wfs', + url: wfsUrl + } + }), + ...(bbox && { bbox }), + ...(template && { + featureInfo: { + format: 'TEMPLATE', + template + } + }), + style: '', + title, + visibility: true, + ...(defaultStyle && { + defaultStyle: { + title: defaultStyle.sld_title, + name: defaultStyle.workspace ? `${defaultStyle.workspace}:${defaultStyle.name}` : defaultStyle.name + } + }), + ...(styles && { + availableStyles: [ ...styles ].map((style) => ({ + title: style.sld_title, + name: style.workspace ? `${style.workspace}:${style.name}` : style.name + })) + }), + ...(params && { params }), + ...(dimensions.length > 0 && ({ dimensions })) + }; + } }; function updateUrlQueryParameter(requestUrl, query) { @@ -216,7 +245,7 @@ export const getResourceTypesInfo = () => ({ })), formatDetailUrl: (resource) => resource?.detail_url && parseDevHostname(resource.detail_url), name: 'Dataset', - formatMetadataUrl: (resource) => (`/datasets/${resource.alternate}/metadata`) + formatMetadataUrl: (resource) => (`/datasets/${resource.store}:${resource.alternate}/metadata`) }, [ResourceTypes.MAP]: { icon: 'map', diff --git a/geonode_mapstore_client/client/js/utils/__tests__/ResourceUtils-test.js b/geonode_mapstore_client/client/js/utils/__tests__/ResourceUtils-test.js index 5d8eef6a29..e57f9caedf 100644 --- a/geonode_mapstore_client/client/js/utils/__tests__/ResourceUtils-test.js +++ b/geonode_mapstore_client/client/js/utils/__tests__/ResourceUtils-test.js @@ -27,4 +27,24 @@ describe('Test Resource Utils', () => { }); expect(newLayer.params).toEqual({ map: 'name', map_resolution: '91' } ); }); + + it('should parse arcgis dataset', () => { + const newLayer = resourceToLayerConfig({ + alternate: 'remoteWorkspace:1', + title: 'Layer title', + perms: [], + links: [{ + extension: 'html', + link_type: 'image', + mime: 'text/html', + name: 'ArcGIS REST ImageServer', + url: 'http://localhost:8080/MapServer' + }], + pk: 1, + ptype: 'gxp_arcrestsource' + }); + expect(newLayer.type).toBe('arcgis'); + expect(newLayer.name).toBe('1'); + expect(newLayer.url).toBe('http://localhost:8080/MapServer'); + }); }); diff --git a/geonode_mapstore_client/client/static/mapstore/configs/localConfig.json b/geonode_mapstore_client/client/static/mapstore/configs/localConfig.json index 4915fd82a4..b4a71276a2 100644 --- a/geonode_mapstore_client/client/static/mapstore/configs/localConfig.json +++ b/geonode_mapstore_client/client/static/mapstore/configs/localConfig.json @@ -818,7 +818,7 @@ "type": "link", "href": "{'#/dataset/' + (state('gnResourceData') || {}).pk + '/edit/data'}", "labelId": "gnviewer.viewData", - "disableIf": "{state('gnResourceData') && state('gnResourceData').subtype === 'raster'}" + "disableIf": "{state('gnResourceData') && (state('gnResourceData').subtype === 'raster' || state('gnResourceData').subtype === 'remote')}" } ] },