From 7dc1343f1bf8d66648462cbb710dc131f7e51be7 Mon Sep 17 00:00:00 2001 From: "francesco.mangiacrapa" Date: Mon, 15 May 2023 16:19:40 +0200 Subject: [PATCH] Supported the grouped custom layers [#25110] --- .settings/org.eclipse.wst.common.component | 33 +- CHANGELOG.md | 5 + pom.xml | 4 +- .../client/GeoportalDataViewer.java | 47 ++- .../events/OverlayCustomLayerToMapEvent.java | 92 ++++++ .../OverlayCustomLayerToMapEventHandler.java | 20 ++ .../client/gis/LayerOrder.java | 7 +- .../client/gis/OpenLayerMap.java | 75 ++++- .../client/ui/GeonaDataViewMainPanel.java | 68 ++++- .../client/ui/GeonaDataViewMainPanel.ui.xml | 11 +- .../OverlayCustomLayerPanel.java | 284 ++++++++++++++++++ .../OverlayCustomLayerPanel.ui.xml | 29 ++ .../layercollection/LayerCollectionPanel.java | 3 +- .../client/util/URLUtil.java | 14 + .../GeoportalDataViewerServiceImpl.java | 46 ++- .../shared/ViewerConfiguration.java | 13 + .../shared/gis/DisplayCategory.java | 16 + .../shared/gis/OverlayWMSLayer.java | 13 + 18 files changed, 738 insertions(+), 42 deletions(-) create mode 100644 src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/OverlayCustomLayerToMapEvent.java create mode 100644 src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/OverlayCustomLayerToMapEventHandler.java create mode 100644 src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/customoverlays/OverlayCustomLayerPanel.java create mode 100644 src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/customoverlays/OverlayCustomLayerPanel.ui.xml create mode 100644 src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/gis/DisplayCategory.java create mode 100644 src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/gis/OverlayWMSLayer.java diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 7653269..9957ee3 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,5 +1,6 @@ - + + @@ -79,7 +80,8 @@ - + + @@ -159,7 +161,8 @@ - + + @@ -239,7 +242,8 @@ - + + @@ -319,7 +323,8 @@ - + + @@ -399,7 +404,8 @@ - + + @@ -479,7 +485,11 @@ - + + uses + + + @@ -559,7 +569,8 @@ - + + @@ -639,7 +650,8 @@ - + + @@ -719,7 +731,8 @@ - + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f482f2..11ba5b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v3.5.0-SNAPSHOT] + +- Supported the cross-filtering [#25074] +- Supported the grouped custom layers [#25110] + ## [v3.4.0] - 2023-05-11 - Integrated the geoportal-data-mapper component [#24978] diff --git a/pom.xml b/pom.xml index e918346..1f79fa4 100644 --- a/pom.xml +++ b/pom.xml @@ -14,13 +14,13 @@ org.gcube.portlets.user geoportal-data-viewer-app war - 3.4.0 + 3.5.0-SNAPSHOT GeoPortal Data Viewer App The GeoPortal Data Viewer App is an application to access, discovery and navigate the Geoportal projects/documents by a Web-Map Interface - 2.9.0 + 2.10.0 PRETTY 2.6.2 ${project.build.directory}/${project.build.finalName} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewer.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewer.java index 795b99b..3b6ec72 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewer.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewer.java @@ -30,6 +30,8 @@ import org.gcube.portlets.user.geoportaldataviewer.client.events.DoActionOnDetai import org.gcube.portlets.user.geoportaldataviewer.client.events.DoActionOnDetailLayersEventHandler; import org.gcube.portlets.user.geoportaldataviewer.client.events.MapExtentToEvent; import org.gcube.portlets.user.geoportaldataviewer.client.events.MapExtentToEventHandler; +import org.gcube.portlets.user.geoportaldataviewer.client.events.OverlayCustomLayerToMapEvent; +import org.gcube.portlets.user.geoportaldataviewer.client.events.OverlayCustomLayerToMapEventHandler; import org.gcube.portlets.user.geoportaldataviewer.client.events.QueryDataEvent; import org.gcube.portlets.user.geoportaldataviewer.client.events.SearchPerformedEvent; import org.gcube.portlets.user.geoportaldataviewer.client.events.SearchPerformedEventHandler; @@ -282,6 +284,11 @@ public class GeoportalDataViewer implements EntryPoint { mainPanel.openCollectionMenu(); + GWT.log("LIST CUSTOM LAYERS: " + result.getListCustomLayers()); + if (result.getListCustomLayers() != null && result.getListCustomLayers().size() > 0) { + mainPanel.setCustomLayers(result.getListCustomLayers()); + } + GWT.log("DONE INIT LOAD"); } @@ -672,6 +679,24 @@ public class GeoportalDataViewer implements EntryPoint { } }); + applicationBus.addHandler(OverlayCustomLayerToMapEvent.TYPE, new OverlayCustomLayerToMapEventHandler() { + + @Override + public void onCustomOverlayLayerAction(OverlayCustomLayerToMapEvent customOverLayerToMapEvent) { + + if(customOverLayerToMapEvent.getLayerItem()==null) + return; + + if (customOverLayerToMapEvent.getActionType() + .equals(OverlayCustomLayerToMapEvent.ACTION_TYPE.VISIBILITY)) { + OpenLayerMap olMap = olMapMng.getOLMap(); + olMap.setWMSGroupedCustomLayerVisible(customOverLayerToMapEvent.getLayerItem(), + customOverLayerToMapEvent.isEnabled()); + } + + } + }); + applicationBus.addHandler(ChangeMapLayerEvent.TYPE, new ChangeMapLayerEventHandler() { @Override @@ -911,18 +936,16 @@ public class GeoportalDataViewer implements EntryPoint { GWT.log("features: " + features); olMapMng.getOLMap().addLayerFeaturesAsHighlight(layerItem, features, true); - /* Fit to extent calculating the features extent - if (projectDV != null) { - GeoJSON spatialReference = projectDV.getSpatialReference(); - - GWT.log("spatialReference is: " + spatialReference); - Coordinate transfCoord = MapUtils.geoJSONTToBBoxCenter(spatialReference, MAP_PROJECTION.EPSG_4326.getName(), - MAP_PROJECTION.EPSG_3857.getName()); - GWT.log("transfCoord is: " + transfCoord); - if (transfCoord != null) - olMapMng.getOLMap().setCenter(transfCoord); - } - */ + /* + * Fit to extent calculating the features extent if (projectDV != null) { + * GeoJSON spatialReference = projectDV.getSpatialReference(); + * + * GWT.log("spatialReference is: " + spatialReference); Coordinate transfCoord = + * MapUtils.geoJSONTToBBoxCenter(spatialReference, + * MAP_PROJECTION.EPSG_4326.getName(), MAP_PROJECTION.EPSG_3857.getName()); + * GWT.log("transfCoord is: " + transfCoord); if (transfCoord != null) + * olMapMng.getOLMap().setCenter(transfCoord); } + */ } } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/OverlayCustomLayerToMapEvent.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/OverlayCustomLayerToMapEvent.java new file mode 100644 index 0000000..0923d28 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/OverlayCustomLayerToMapEvent.java @@ -0,0 +1,92 @@ +package org.gcube.portlets.user.geoportaldataviewer.client.events; + +import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerItem; + +import com.google.gwt.event.shared.GwtEvent; + +/** + * The Class OverlayCustomLayerToMapEvent. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * May 15, 2023 + */ +public class OverlayCustomLayerToMapEvent extends GwtEvent { + public static Type TYPE = new Type(); + private LayerItem layerItem; + private ACTION_TYPE actionType; + private boolean enabled; + + /** + * The Enum ACTION_TYPE. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * May 15, 2023 + */ + public enum ACTION_TYPE { + VISIBILITY + } + + /** + * Instantiates a new overlay custom layer to map event. + * + * @param layerItem the layer item + * @param actionType the action type + * @param enabled the enabled + */ + public OverlayCustomLayerToMapEvent(LayerItem layerItem, ACTION_TYPE actionType, boolean enabled) { + this.layerItem = layerItem; + this.actionType = actionType; + this.enabled = enabled; + } + + /** + * Gets the associated type. + * + * @return the associated type + */ + @Override + public Type getAssociatedType() { + return TYPE; + } + + /** + * Dispatch. + * + * @param handler the handler + */ + @Override + protected void dispatch(OverlayCustomLayerToMapEventHandler handler) { + handler.onCustomOverlayLayerAction(this); + + } + + /** + * Gets the layer item. + * + * @return the layer item + */ + public LayerItem getLayerItem() { + return layerItem; + } + + /** + * Gets the action type. + * + * @return the action type + */ + public ACTION_TYPE getActionType() { + return actionType; + } + + /** + * Checks if is enabled. + * + * @return true, if is enabled + */ + public boolean isEnabled() { + return enabled; + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/OverlayCustomLayerToMapEventHandler.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/OverlayCustomLayerToMapEventHandler.java new file mode 100644 index 0000000..6e027b5 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/OverlayCustomLayerToMapEventHandler.java @@ -0,0 +1,20 @@ +package org.gcube.portlets.user.geoportaldataviewer.client.events; + +import com.google.gwt.event.shared.EventHandler; + +/** + * The Interface OverlayCustomLayerToMapEventHandler. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * May 15, 2023 + */ +public interface OverlayCustomLayerToMapEventHandler extends EventHandler { + + /** + * On custom overlay layer action. + * + * @param customOverLayerToMapEvent the custom over layer to map event + */ + void onCustomOverlayLayerAction(OverlayCustomLayerToMapEvent customOverLayerToMapEvent); +} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/LayerOrder.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/LayerOrder.java index 940f016..e5f9bc6 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/LayerOrder.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/LayerOrder.java @@ -19,7 +19,7 @@ public class LayerOrder { * Nov 12, 2021 */ public static enum LAYER_TYPE { - BASE_MAP, BASE_WMS, WMS_DETAIL, VECTOR + BASE_MAP, BASE_WMS, WMS_DETAIL, CUSTOM_WMS_DETAIL, VECTOR } public static final HashMap LAYER_OFFSET = new HashMap(5); @@ -28,8 +28,9 @@ public class LayerOrder { LAYER_OFFSET.put(LAYER_TYPE.BASE_MAP, 0); LAYER_OFFSET.put(LAYER_TYPE.BASE_WMS, 70); - LAYER_OFFSET.put(LAYER_TYPE.WMS_DETAIL, 140); - LAYER_OFFSET.put(LAYER_TYPE.VECTOR, 210); + LAYER_OFFSET.put(LAYER_TYPE.CUSTOM_WMS_DETAIL, 140); + LAYER_OFFSET.put(LAYER_TYPE.WMS_DETAIL, 210); + LAYER_OFFSET.put(LAYER_TYPE.VECTOR, 320); } /** diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/OpenLayerMap.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/OpenLayerMap.java index 2e4a755..28c580e 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/OpenLayerMap.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/OpenLayerMap.java @@ -149,6 +149,8 @@ public abstract class OpenLayerMap { private LinkedHashMap wmsDetailsLayerMap; + private LinkedHashMap wmsGroupedCustomLayerMap; + private LinkedHashMap wmsLayerMap; private LinkedHashMap vectorLayersHighlighted = new LinkedHashMap(); @@ -537,6 +539,57 @@ public abstract class OpenLayerMap { } + /** + * Adds the custom WMS detail layer. + * + * @param layerItem the layer item + */ + public void addGroupedCustomWMSLayer(LayerItem layerItem) { + + if (wmsGroupedCustomLayerMap == null) + wmsGroupedCustomLayerMap = new LinkedHashMap(); + + String key = layerItem.getName(); + + Image layer = wmsGroupedCustomLayerMap.get(key); + + if (layer == null) { + GWT.log("The grouped custom layer with key: " + key + " does not exist, creating and adding it to map"); + ImageWmsParams imageWMSParams = OLFactory.createOptions(); + imageWMSParams.setLayers(layerItem.getName()); + + ImageWmsOptions imageWMSOptions = OLFactory.createOptions(); + imageWMSOptions.setUrl(layerItem.getMapServerHost()); + imageWMSOptions.setParams(imageWMSParams); + // imageWMSOptions.setRatio(1.5f); + + ImageWms imageWMSSource = new ImageWms(imageWMSOptions); + LayerOptions layerOptions = OLFactory.createOptions(); + layerOptions.setSource(imageWMSSource); + + // Settings MIN and MAX Resolution + if (layerItem.getMinResolution() != null) { + layerOptions.setMinResolution(layerItem.getMinResolution()); + } + if (layerItem.getMaxResolution() != null) { + layerOptions.setMaxResolution(layerItem.getMaxResolution()); + } + + Image wmsLayer = new Image(layerOptions); + int zIndex = layerOrder.getOffset(LayerOrder.LAYER_TYPE.CUSTOM_WMS_DETAIL) + wmsGroupedCustomLayerMap.size() + + 1; + wmsLayer.setZIndex(zIndex); + map.addLayer(wmsLayer); + wmsGroupedCustomLayerMap.put(key, wmsLayer); + + GWT.log("Added GroupedCustomWMSLayer for layer name: " + layerItem.getName()); + eventBus.fireEvent(new AddedLayerToMapEvent(layerItem, LAYER_TYPE.OVERLAY)); + } else { + GWT.log("The WMS detail layer with key: " + key + " already exists, skipping"); + } + + } + /** * Removes the all detail layers. * @@ -633,8 +686,8 @@ public abstract class OpenLayerMap { /** * Adds the vector. * - * @param layerItem the layer item - * @param features the features + * @param layerItem the layer item + * @param features the features * @param fitMapToFeaturesExtent the fit map to features extent */ public void addLayerFeaturesAsHighlight(LayerItem layerItem, Feature[] features, boolean fitMapToFeaturesExtent) { @@ -656,7 +709,7 @@ public abstract class OpenLayerMap { @Override public void onEvent(ol.events.Event event) { ol.Extent theExtent = vectorSource.getExtent(); - //GWT.log(theExtent.toString()); + // GWT.log(theExtent.toString()); map.getView().fit(theExtent); } @@ -1050,7 +1103,21 @@ public abstract class OpenLayerMap { public void setWMSDetailLayerOpacity(LayerItem layerItem, double opacity) { String key = layerItem.getName(); Image layer = wmsDetailsLayerMap.get(key); - layer.setOpacity(opacity); + if (layer != null) + layer.setOpacity(opacity); + } + + /** + * Sets the WMS detail layer visible. + * + * @param layerItem the layer item + * @param visible the visible + */ + public void setWMSGroupedCustomLayerVisible(LayerItem layerItem, boolean visible) { + String key = layerItem.getName(); + Image layer = wmsGroupedCustomLayerMap.get(key); + if (layer != null) + layer.setVisible(visible); } /** diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/GeonaDataViewMainPanel.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/GeonaDataViewMainPanel.java index ed89854..0022a81 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/GeonaDataViewMainPanel.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/GeonaDataViewMainPanel.java @@ -9,6 +9,8 @@ import org.gcube.application.geoportalcommon.shared.GeoportalItemReferences; import org.gcube.application.geoportalcommon.shared.SearchingFilter; import org.gcube.application.geoportalcommon.shared.SearchingFilter.ORDER; import org.gcube.application.geoportalcommon.shared.geoportal.config.ItemFieldDV; +import org.gcube.application.geoportalcommon.shared.geoportal.materialization.CustomLayerDV; +import org.gcube.application.geoportalcommon.shared.geoportal.materialization.GroupedCustomLayersDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.UseCaseDescriptorDV; import org.gcube.application.geoportalcommon.shared.geoportal.view.ProjectView; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants; @@ -20,12 +22,15 @@ import org.gcube.portlets.user.geoportaldataviewer.client.gis.OpenLayerMap; import org.gcube.portlets.user.geoportaldataviewer.client.resources.GNAIcons; import org.gcube.portlets.user.geoportaldataviewer.client.resources.GNAImages; import org.gcube.portlets.user.geoportaldataviewer.client.ui.cms.search.SearchFacilityUI; +import org.gcube.portlets.user.geoportaldataviewer.client.ui.customoverlays.OverlayCustomLayerPanel; import org.gcube.portlets.user.geoportaldataviewer.client.ui.layercollection.LayerCollectionPanel; import org.gcube.portlets.user.geoportaldataviewer.client.ui.map.ExtentMapUtil; import org.gcube.portlets.user.geoportaldataviewer.client.ui.map.ExtentMapUtil.Location; +import org.gcube.portlets.user.geoportaldataviewer.client.util.URLUtil; import org.gcube.portlets.user.geoportaldataviewer.shared.GCubeCollection; import org.gcube.portlets.user.geoportaldataviewer.shared.ItemFieldsResponse; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.BaseMapLayer; +import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerItem; import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.CheckBox; @@ -34,6 +39,7 @@ import com.github.gwtbootstrap.client.ui.ListBox; import com.github.gwtbootstrap.client.ui.NavLink; import com.github.gwtbootstrap.client.ui.Paragraph; import com.github.gwtbootstrap.client.ui.constants.IconType; +import com.github.gwtbootstrap.client.ui.constants.LabelType; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; @@ -111,6 +117,12 @@ public class GeonaDataViewMainPanel extends Composite { @UiField DropdownButton openCollectionDropDown; + @UiField + DropdownButton linkCustomOverlayLayers; + + @UiField + HTMLPanel panelCustomOverlayLayers; + @UiField HTMLPanel openCollectionPanel; @@ -173,7 +185,7 @@ public class GeonaDataViewMainPanel extends Composite { extentToEarth.getElement().appendChild(worldImg.getElement()); extentToEarth.setWidth("140px"); - linkMap.setCustomIconStyle(GNAIcons.CustomIconType.MAP.get()); + // linkMap.setCustomIconStyle(GNAIcons.CustomIconType.MAP.get()); linkPresetLocation.setCustomIconStyle(GNAIcons.CustomIconType.PRESET_LOCATION.get()); linkLayers.setCustomIconStyle(GNAIcons.CustomIconType.LAYERS.get()); @@ -185,9 +197,9 @@ public class GeonaDataViewMainPanel extends Composite { initialSortFilter.setOrder(ORDER.ASC); navListSearch.addItem(PLACEHOLDER_SELECT_SEARCH_IN, PLACEHOLDER_SELECT_SEARCH_IN); - + navListSearch.getElement().getFirstChildElement().setAttribute("disabled", "disabled"); - + // List listUCDs = new ArrayList(); // // for (ItemFieldsResponse itemFieldsResponse : itemFieldsReponse) { @@ -216,9 +228,9 @@ public class GeonaDataViewMainPanel extends Composite { String ucdProfileID = navListSearch.getValue(navListSearch.getSelectedIndex()); GWT.log("UCD ProfileID selected: " + ucdProfileID); - + if (ucdProfileID.compareTo(PLACEHOLDER_SELECT_SEARCH_IN) != 0) { - + searchFacilityPanel.clear(); ItemFieldsResponse itemFieldResp = mapItemFieldsForUCD.get(ucdProfileID); @@ -310,6 +322,16 @@ public class GeonaDataViewMainPanel extends Composite { } }, ClickEvent.getType()); + + linkCustomOverlayLayers.addDomHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + // event.preventDefault(); + event.stopPropagation(); + + } + }, ClickEvent.getType()); } /** @@ -608,4 +630,40 @@ public class GeonaDataViewMainPanel extends Composite { } + public void setCustomLayers(List listCustomLayers) { + + if (listCustomLayers == null) + return; + + for (GroupedCustomLayersDV gCustomLayerDV : listCustomLayers) { + if (gCustomLayerDV.getListCustomLayers() != null) { + com.github.gwtbootstrap.client.ui.Label labelGroup = new com.github.gwtbootstrap.client.ui.Label(gCustomLayerDV.getName()); + labelGroup.setType(LabelType.WARNING); + String descr = gCustomLayerDV.getDescription() != null + && !gCustomLayerDV.getDescription().isEmpty() ? gCustomLayerDV.getDescription() + : gCustomLayerDV.getName(); + labelGroup.setTitle(descr); + panelCustomOverlayLayers.add(labelGroup); + for (CustomLayerDV customLayer : gCustomLayerDV.getListCustomLayers()) { + + if(customLayer.isDisplay()) { + LayerItem layerItem = new LayerItem(); + final String mapServerHost = URLUtil.getPathURL(customLayer.getWms_url()); + GWT.log("mapServerHost: " + mapServerHost); + layerItem.setMapServerHost(mapServerHost); + layerItem.setBaseLayer(false); + layerItem.setName(customLayer.getName()); + layerItem.setTitle(customLayer.getTitle()); + layerItem.setWmsLink(customLayer.getWms_url()); + panelCustomOverlayLayers.add(new OverlayCustomLayerPanel(layerItem, applicationBus)); + map.addGroupedCustomWMSLayer(layerItem); + } + } + } + } + + linkCustomOverlayLayers.setVisible(listCustomLayers.size() > 0); + + } + } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/GeonaDataViewMainPanel.ui.xml b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/GeonaDataViewMainPanel.ui.xml index 24aa44d..24a6e0c 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/GeonaDataViewMainPanel.ui.xml +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/GeonaDataViewMainPanel.ui.xml @@ -49,17 +49,22 @@ - + + title="Select the Map" text="Map" ui:field="linkMap" icon="GLOBE"> + + + + diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/customoverlays/OverlayCustomLayerPanel.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/customoverlays/OverlayCustomLayerPanel.java new file mode 100644 index 0000000..5da70d8 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/customoverlays/OverlayCustomLayerPanel.java @@ -0,0 +1,284 @@ +package org.gcube.portlets.user.geoportaldataviewer.client.ui.customoverlays; + +import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerServiceAsync; +import org.gcube.portlets.user.geoportaldataviewer.client.events.OverlayCustomLayerToMapEvent; +import org.gcube.portlets.user.geoportaldataviewer.client.util.URLUtil; +import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerItem; +import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wms.GeoInformationForWMSRequest; + +import com.github.gwtbootstrap.client.ui.Button; +import com.github.gwtbootstrap.client.ui.CheckBox; +import com.github.gwtbootstrap.client.ui.ListBox; +import com.github.gwtbootstrap.client.ui.constants.ButtonType; +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style.FontWeight; +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.dom.client.ErrorEvent; +import com.google.gwt.event.dom.client.ErrorHandler; +import com.google.gwt.event.dom.client.LoadEvent; +import com.google.gwt.event.dom.client.LoadHandler; +import com.google.gwt.event.logical.shared.ValueChangeEvent; +import com.google.gwt.event.logical.shared.ValueChangeHandler; +import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlexTable; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Image; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.ScrollPanel; +import com.google.gwt.user.client.ui.Widget; + +/** + * The Class OverlayCustomLayerPanel. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * May 15, 2023 + */ +public class OverlayCustomLayerPanel extends Composite { + + public static String COLORSCALERANGE = "COLORSCALERANGE"; + + @UiField + HTMLPanel basePanel; + + @UiField + HTMLPanel stylePanel; + + @UiField + HTMLPanel styleListPanel; + + @UiField + Button buttonLegend; + + @UiField + ScrollPanel legendPanel; + + private CheckBox checkbox; + + private GeoInformationForWMSRequest geoInformation; + + private static OverlayCustomLayerPanelUiBinder uiBinder = GWT.create(OverlayCustomLayerPanelUiBinder.class); + + private ListBox listBoxStyles = new ListBox(); + + private HandlerManager applicationBus; + + private LayerItem layerItem; + + /** + * The Interface LayerCollectionPanelUiBinder. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Jan 16, 2023 + */ + interface OverlayCustomLayerPanelUiBinder extends UiBinder { + } + + /** + * Instantiates a new overlay custom layer panel. + * + * @param layerItem the layer item + * @param applicationBus the application bus + */ + public OverlayCustomLayerPanel(LayerItem layerItem, HandlerManager applicationBus) { + initWidget(uiBinder.createAndBindUi(this)); + this.applicationBus = applicationBus; + this.layerItem = layerItem; + + buttonLegend.setType(ButtonType.LINK); + legendPanel.setVisible(false); + + GWT.log("Found available layerItem " + layerItem); + String label = layerItem.getTitle(); + final String layerName = layerItem.getName(); + + checkbox = new CheckBox(label); + checkbox.setId("gcubeCustomLayerSelector_" + layerName); + checkbox.getElement().getStyle().setFontWeight(FontWeight.BOLD); + checkbox.setChecked(true); + + checkbox.addValueChangeHandler(new ValueChangeHandler() { + + @Override + public void onValueChange(ValueChangeEvent event) { + GWT.log("CustomLayer selector flag changed to value : " + event.toDebugString()); + +// String collectionID = ((CheckBox) event.getSource()).getId().replace("gcubeCollectionSelector_", +// ""); + + // GWT.log("Collection ID is : " + collectionID + ", event value: " + + // event.getValue()); + if (event.getValue()) { + // OPEN COLLECTION + applicationBus.fireEvent(new OverlayCustomLayerToMapEvent(layerItem, OverlayCustomLayerToMapEvent.ACTION_TYPE.VISIBILITY, true)); + } else { + // CLOSE COLLECTION + legendPanel.clear(); + legendPanel.setVisible(false); + applicationBus.fireEvent(new OverlayCustomLayerToMapEvent(layerItem, OverlayCustomLayerToMapEvent.ACTION_TYPE.VISIBILITY, false)); + } + } + }); + + basePanel.add(checkbox); + + final String wmsLink = layerItem.getWmsLink(); + GeoportalDataViewerServiceAsync.Util.getInstance().parseWmsRequest(wmsLink, layerName, + new AsyncCallback() { + + @Override + public void onFailure(Throwable caught) { + + Window.alert(caught.getMessage()); + } + + @Override + public void onSuccess(GeoInformationForWMSRequest geoInfoWMS) { + geoInformation = geoInfoWMS; + GWT.log("Parsed WMS Request returned: " + geoInfoWMS); + + if (geoInfoWMS.getStyles() != null && geoInfoWMS.getStyles().getGeoStyles() != null) { + if (geoInfoWMS.getStyles().getGeoStyles().size() > 0) { + stylePanel.setVisible(true); + listBoxStyles.clear(); + for (String styleName : geoInfoWMS.getStyles().getGeoStyles()) { + listBoxStyles.addItem(styleName, styleName); + } + + styleListPanel.add(listBoxStyles); + } + } + + listBoxStyles.addChangeHandler(new ChangeHandler() { + + @Override + public void onChange(ChangeEvent event) { + legendPanel.clear(); + legendPanel.setVisible(false); + } + }); + + + buttonLegend.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + GWT.log("is isToggle: " + buttonLegend.isToggle()); + GWT.log("is isToggled: " + buttonLegend.isToggled()); + if (legendPanel.isVisible()) { + legendPanel.clear(); + legendPanel.setVisible(false); + + } else { + legendPanel.setVisible(true); + loadLegend(wmsLink); + } + + } + }); + + } + }); + + } + + /** + * Gets the checkbox. + * + * @return the checkbox + */ + public CheckBox getCheckbox() { + return checkbox; + } + + /** + * Load legend. + * + * @param wmsLink the wms link + */ + private void loadLegend(String wmsLink) { + + legendPanel.clear(); + String theLayerName = geoInformation.getLayerName(); + final FlexTable flexTable = new FlexTable(); + legendPanel.add(flexTable); + + // Case no style found + if (listBoxStyles.getSelectedValue() == null) { + flexTable.setWidget(0, 0, new HTML("No style found")); + return; + } + + FlowPanel flow = new FlowPanel(); + flow.add(new HTMLPanel("Legend for: " + theLayerName)); + final HorizontalPanel hpLegend = new HorizontalPanel(); + + String url = geoInformation.getBaseWmsServiceHost() + "?service=WMS&" + "version=" + + URLUtil.getValueOfParameter("version", wmsLink) + "&" + "request=GetLegendGraphic&" + "layer=" + + theLayerName; + + String styleName = null; + try { + styleName = listBoxStyles.getSelectedValue(); + } catch (Exception e) { + } + + styleName = styleName != null && !styleName.isEmpty() ? styleName : ""; + + if (!geoInformation.isNcWMS()) { + + url += "&format=image/png" + "&STYLE=" + styleName + + "&LEGEND_OPTIONS=forceRule:True;dx:0.2;dy:0.2;mx:0.2;my:0.2;fontStyle:bold;" + + "borderColor:000000;border:true;fontColor:000000;fontSize:14"; + } else { + + int isNcWmsStyle = styleName.indexOf("/"); + if (isNcWmsStyle != -1) { + styleName = styleName.substring(isNcWmsStyle + 1, styleName.length()); + } + url += "&palette=" + styleName; + if (geoInformation.getMapWMSNoStandard() != null) { + for (String key : geoInformation.getMapWMSNoStandard().keySet()) { // ADDING COLORSCALERANGE? + if (key.compareToIgnoreCase(COLORSCALERANGE) == 0) { + url += "&" + key + "=" + geoInformation.getMapWMSNoStandard().get(key); + break; + } + } + } + } + + GWT.log(url); + flexTable.setStyleName("layer-style-panel-table-legend"); + flexTable.setWidget(0, 0, new Label("Legend")); + final Image legendImage = new Image(url); + legendImage.addLoadHandler(new LoadHandler() { + @Override + public void onLoad(LoadEvent event) { + } + }); + + legendImage.addErrorHandler(new ErrorHandler() { + @Override + public void onError(ErrorEvent event) { + GWT.log("ErrorEvent "); + flexTable.setWidget(0, 1, new HTML("Error on loading the style")); + } + }); + + hpLegend.add(legendImage); + flexTable.setWidget(0, 1, hpLegend); + } + +} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/customoverlays/OverlayCustomLayerPanel.ui.xml b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/customoverlays/OverlayCustomLayerPanel.ui.xml new file mode 100644 index 0000000..bcfa94c --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/customoverlays/OverlayCustomLayerPanel.ui.xml @@ -0,0 +1,29 @@ + + + + .important { + font-weight: bold; + } + + .margin-left-10 { + margin-left: 10px; + } + + + + + + Layer Style + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/layercollection/LayerCollectionPanel.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/layercollection/LayerCollectionPanel.java index 15dcd9d..b8a74ce 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/layercollection/LayerCollectionPanel.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/layercollection/LayerCollectionPanel.java @@ -42,12 +42,13 @@ import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.Widget; + /** * The Class LayerCollectionPanel. * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * - * Jan 16, 2023 + * May 15, 2023 */ public class LayerCollectionPanel extends Composite { diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/util/URLUtil.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/util/URLUtil.java index d79b001..c245173 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/util/URLUtil.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/util/URLUtil.java @@ -35,6 +35,20 @@ public class URLUtil { return value; } + /** + * Gets the path URL. + * + * @param url the url + * @return the path URL + */ + public static String getPathURL(String url) { + int index = url.toLowerCase().indexOf("?"); + if (index > -1) { + return url.substring(0, index); + } else + return null; + } + /** * Adds the parameter to query string. * diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/GeoportalDataViewerServiceImpl.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/GeoportalDataViewerServiceImpl.java index 95855fc..07af62d 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/GeoportalDataViewerServiceImpl.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/GeoportalDataViewerServiceImpl.java @@ -31,6 +31,7 @@ import org.gcube.application.geoportal.common.model.document.identification.Iden import org.gcube.application.geoportal.common.model.document.relationships.Relationship; import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject; import org.gcube.application.geoportal.common.model.rest.QueryRequest; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; import org.gcube.application.geoportal.common.rest.Projects; import org.gcube.application.geoportalcommon.ConvertToDataValueObjectModel; @@ -50,11 +51,13 @@ import org.gcube.application.geoportalcommon.shared.geoportal.ResultDocumentDV; import org.gcube.application.geoportalcommon.shared.geoportal.config.ItemFieldDV; import org.gcube.application.geoportalcommon.shared.geoportal.geojson.GeoJSON; import org.gcube.application.geoportalcommon.shared.geoportal.materialization.GCubeSDIViewerLayerDV; +import org.gcube.application.geoportalcommon.shared.geoportal.materialization.GroupedCustomLayersDV; import org.gcube.application.geoportalcommon.shared.geoportal.materialization.IndexLayerDV; import org.gcube.application.geoportalcommon.shared.geoportal.materialization.innerobject.PayloadDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.IdentificationReferencesTYPE; import org.gcube.application.geoportalcommon.shared.geoportal.project.ProjectDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.TemporalReferenceDV; +import org.gcube.application.geoportalcommon.shared.geoportal.ucd.GEOPORTAL_CONFIGURATION_TYPE; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.GEOPORTAL_DATA_HANDLER; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.HandlerDeclarationDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.UseCaseDescriptorDV; @@ -470,10 +473,23 @@ public class GeoportalDataViewerServiceImpl extends RemoteServiceServlet impleme Projects p = projects(u.getId()).build(); - UseCaseDescriptorDV ucd = ConvertToDataValueObjectModel.toUseCaseDescriptorDV(u, null); + UseCaseDescriptorDV ucdDV = ConvertToDataValueObjectModel.toUseCaseDescriptorDV(u, null); Configuration ucdConfig = p.getConfiguration(); GCubeCollection coll = new GCubeCollection(); - coll.setUcd(ucd); + coll.setUcd(ucdDV); + + // Loading geoportal_grouped_custom_layers if exists + GEOPORTAL_DATA_HANDLER theHandler = GEOPORTAL_DATA_HANDLER.geoportal_grouped_custom_layers; + List handlers = u.getHandlersByType(theHandler.getType()); + + if (handlers != null && handlers.size() > 0) { + // Loading Handler gcube_profiles + HandlerDeclaration handler = handlers.get(0); + List listCustomLayers = getGroupedCustomLayers(u, handler, + GEOPORTAL_DATA_HANDLER.geoportal_grouped_custom_layers); + config.setGroupCustomLayers(listCustomLayers); + } else + LOG.warn("No handler " + theHandler + "found into UCD " + u.getId() + ", continue..."); // TODO TO Check index flag should be in configuration or evaluated according to // user credentials @@ -552,6 +568,32 @@ public class GeoportalDataViewerServiceImpl extends RemoteServiceServlet impleme return null; } + private List getGroupedCustomLayers(UseCaseDescriptor ucd, HandlerDeclaration handler, + GEOPORTAL_DATA_HANDLER geoportalGroupedCustomLayers) { + + List listGroupedCustomLayers = null; + try { + + HandlerDeclarationDV handlerDV = ConvertToDataValueObjectModel.toHandlerDeclarationDV(handler, ucd, + GEOPORTAL_CONFIGURATION_TYPE.grouped_custom_layers); + + if (handler != null) { + ConfigurationDV config = handlerDV.getConfiguration(); + switch (config.getConfigurationType()) { + case grouped_custom_layers: + listGroupedCustomLayers = (List) config.getConfiguration(); + break; + default: + break; + } + + } + } catch (Exception e) { + LOG.error("Error on loading {} config for ucd Id {}. Returning null", geoportalGroupedCustomLayers, ucd.getId()); + } + return listGroupedCustomLayers; + } + /** * Gets the config list of fields for searching. * diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/ViewerConfiguration.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/ViewerConfiguration.java index 30f8430..5fd43e1 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/ViewerConfiguration.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/ViewerConfiguration.java @@ -4,6 +4,7 @@ import java.io.Serializable; import java.util.List; import java.util.Map; +import org.gcube.application.geoportalcommon.shared.geoportal.materialization.GroupedCustomLayersDV; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.BaseMapLayer; public class ViewerConfiguration implements Serializable { @@ -22,6 +23,8 @@ public class ViewerConfiguration implements Serializable { public Map availableCollections; + private List listCustomLayers; + public List getBaseLayers() { return baseLayers; } @@ -37,4 +40,14 @@ public class ViewerConfiguration implements Serializable { public void setAvailableCollections(Map availableCollections) { this.availableCollections = availableCollections; } + + public void setGroupCustomLayers(List listCustomLayers) { + this.listCustomLayers = listCustomLayers; + + } + + public List getListCustomLayers() { + return listCustomLayers; + } + } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/gis/DisplayCategory.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/gis/DisplayCategory.java new file mode 100644 index 0000000..030ab3f --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/gis/DisplayCategory.java @@ -0,0 +1,16 @@ +package org.gcube.portlets.user.geoportaldataviewer.shared.gis; + +import java.io.Serializable; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Data +public class DisplayCategory implements Serializable { + + + String title; + String description; + +} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/gis/OverlayWMSLayer.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/gis/OverlayWMSLayer.java new file mode 100644 index 0000000..6707121 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/shared/gis/OverlayWMSLayer.java @@ -0,0 +1,13 @@ +package org.gcube.portlets.user.geoportaldataviewer.shared.gis; + +import java.util.Map; + +public class OverlayWMSLayer { + + private String title; + private String name; + private String wmsServiceBaseURL; + private boolean display; + private Map mapProperties; + +}