From a7680ffb46a2a570b749a89b435b92633c0567ee Mon Sep 17 00:00:00 2001 From: "francesco.mangiacrapa" Date: Wed, 7 Jun 2023 14:26:57 +0200 Subject: [PATCH] Added "Fit map to Extent" facility --- .../client/GeoportalDataViewer.java | 33 ++++---- .../client/events/FitMapToExtentEvent.java | 52 ++++++++++++ .../events/FitMapToExtentEventHandler.java | 20 +++++ .../client/gis/MapUtils.java | 17 +++- .../client/gis/OpenLayerMap.java | 21 +++++ .../client/ui/cms/project/ProjectViewer.java | 2 +- .../CrossFilteringLayerPanel.java | 79 ++++++++++++++++++- 7 files changed, 204 insertions(+), 20 deletions(-) create mode 100644 src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/FitMapToExtentEvent.java create mode 100644 src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/FitMapToExtentEventHandler.java 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 ba0a812..40ff90a 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 @@ -35,6 +35,8 @@ import org.gcube.portlets.user.geoportaldataviewer.client.events.DoActionOnDetai import org.gcube.portlets.user.geoportaldataviewer.client.events.DoActionOnDetailLayersEvent.DO_LAYER_ACTION; import org.gcube.portlets.user.geoportaldataviewer.client.events.DoActionOnDetailLayersEvent.SwapLayer; import org.gcube.portlets.user.geoportaldataviewer.client.events.DoActionOnDetailLayersEventHandler; +import org.gcube.portlets.user.geoportaldataviewer.client.events.FitMapToExtentEvent; +import org.gcube.portlets.user.geoportaldataviewer.client.events.FitMapToExtentEventHandler; 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; @@ -802,8 +804,8 @@ public class GeoportalDataViewer implements EntryPoint { // Showing popup after clicking on map if (showPopupOnCentroiEvent.getProfileID() != null && showPopupOnCentroiEvent.getProjectID() != null) { - Coordinate transfCoord = MapUtils - .geoJSONTToBBoxCenter(showPopupOnCentroiEvent.getSpatialReference(), null, null); + Coordinate transfCoord = MapUtils.geoJSONToBBOXCenter(showPopupOnCentroiEvent.getSpatialReference(), + null, null); performWFSQueryOnCentroid(showPopupOnCentroiEvent.getProjectID(), transfCoord.getX(), transfCoord.getY()); @@ -878,8 +880,8 @@ public class GeoportalDataViewer implements EntryPoint { newCqlFilter = olMapMng.getOLMap().setCQLFilterToWMSLayer(CQL_FACILITY_ORIGIN.SEARCH, layerName, null); } - - GWT.log("New CQL Filter is: "+newCqlFilter); + + GWT.log("New CQL Filter is: " + newCqlFilter); if (layerName != null) layerManager.setCQLForLayerToIndexLayer(layerName, newCqlFilter); @@ -932,6 +934,18 @@ public class GeoportalDataViewer implements EntryPoint { } }); + applicationBus.addHandler(FitMapToExtentEvent.TYPE, new FitMapToExtentEventHandler() { + + @Override + public void onFitToMap(FitMapToExtentEvent fitMapToExtentEvent) { + + if (fitMapToExtentEvent.getExtent() != null) { + olMapMng.getOLMap().fitToExtent(fitMapToExtentEvent.getExtent()); + } + + } + }); + } /** @@ -1052,17 +1066,6 @@ 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); } - */ } } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/FitMapToExtentEvent.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/FitMapToExtentEvent.java new file mode 100644 index 0000000..ea4a128 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/FitMapToExtentEvent.java @@ -0,0 +1,52 @@ +package org.gcube.portlets.user.geoportaldataviewer.client.events; + +import com.google.gwt.event.shared.GwtEvent; + +import ol.Extent; + +/** + * The Class FitMapToExtentEvent. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Jun 6, 2023 + */ +public class FitMapToExtentEvent extends GwtEvent { + public static Type TYPE = new Type(); + private Extent extent; + + /** + * Instantiates a new fit map to extent event. + * + * @param extent the extent + */ + public FitMapToExtentEvent(Extent extent) { + this.extent = extent; + } + + /** + * Gets the associated type. + * + * @return the associated type + */ + @Override + public Type getAssociatedType() { + return TYPE; + } + + /** + * Dispatch. + * + * @param handler the handler + */ + @Override + protected void dispatch(FitMapToExtentEventHandler handler) { + handler.onFitToMap(this); + + } + + public Extent getExtent() { + return extent; + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/FitMapToExtentEventHandler.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/FitMapToExtentEventHandler.java new file mode 100644 index 0000000..a816212 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/events/FitMapToExtentEventHandler.java @@ -0,0 +1,20 @@ +package org.gcube.portlets.user.geoportaldataviewer.client.events; + +import com.google.gwt.event.shared.EventHandler; + +/** + * The Interface FitMapToExtentEventHandler. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Jun 6, 2023 + */ +public interface FitMapToExtentEventHandler extends EventHandler { + + /** + * On fit to map. + * + * @param fitMapToExtentEvent the fit map to extent event + */ + void onFitToMap(FitMapToExtentEvent fitMapToExtentEvent); +} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/MapUtils.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/MapUtils.java index 4940ed0..7862e60 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/MapUtils.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/gis/MapUtils.java @@ -6,6 +6,7 @@ import com.google.gwt.core.client.GWT; import ol.Collection; import ol.Coordinate; +import ol.Extent; import ol.control.Attribution; import ol.control.Control; import ol.control.FullScreen; @@ -55,6 +56,18 @@ public final class MapUtils { return Projection.transform(centerCoordinate, source, target); } + /** + * Transform extent. + * + * @param extent the extent + * @param source the source + * @param target the target + * @return the extent + */ + public static Extent transformExtent(Extent extent, String source, String target) { + return Projection.transformExtent(extent, source, target); + } + /** * Distance between centroid. * @@ -95,14 +108,14 @@ public final class MapUtils { } /** - * Geo JSONT to B box center. + * Geo JSON to B box center. * * @param spatialReference the spatial reference * @param transforFrom the transfor from * @param transformTo the transform to * @return the coordinate */ - public static Coordinate geoJSONTToBBoxCenter(GeoJSON spatialReference, String transforFrom, String transformTo) { + public static Coordinate geoJSONToBBOXCenter(GeoJSON spatialReference, String transforFrom, String transformTo) { try { if (spatialReference != null) { 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 3486357..ef64d80 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 @@ -37,6 +37,7 @@ import ol.Overlay; import ol.OverlayOptions; import ol.Size; import ol.View; +import ol.ViewFitOptions; import ol.ViewOptions; import ol.animation.AnimationOptions; import ol.color.Color; @@ -90,6 +91,13 @@ public abstract class OpenLayerMap { public static final int MAX_ZOOM = 21; + /** + * The Enum CQL_FACILITY_ORIGIN. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Jun 6, 2023 + */ public static enum CQL_FACILITY_ORIGIN { SEARCH, CROSS_FILTERING } @@ -1183,4 +1191,17 @@ public abstract class OpenLayerMap { return map.get((map.keySet().toArray())[index]); } + /** + * Fit to extent. + * + * @param extent the extent + */ + public void fitToExtent(ol.Extent extent) { + ViewFitOptions opt = new ViewFitOptions(); + opt.setMaxZoom(16); + opt.setDuration(SET_CENTER_ANIMATED_DURATION*4); + map.getView().fit(extent, opt); + + } + } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/cms/project/ProjectViewer.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/cms/project/ProjectViewer.java index bdda6f9..50041e7 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/cms/project/ProjectViewer.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/cms/project/ProjectViewer.java @@ -304,7 +304,7 @@ public class ProjectViewer extends Composite { GeoJSON spatialReference = theProjectView.getTheProjectDV().getSpatialReference(); - Coordinate transfCoord = MapUtils.geoJSONTToBBoxCenter(spatialReference, MAP_PROJECTION.EPSG_4326.getName(), + Coordinate transfCoord = MapUtils.geoJSONToBBOXCenter(spatialReference, MAP_PROJECTION.EPSG_4326.getName(), MAP_PROJECTION.EPSG_3857.getName()); if (transfCoord != null) { diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/crossfiltering/CrossFilteringLayerPanel.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/crossfiltering/CrossFilteringLayerPanel.java index f567816..8ae6a78 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/crossfiltering/CrossFilteringLayerPanel.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/crossfiltering/CrossFilteringLayerPanel.java @@ -10,9 +10,13 @@ import org.gcube.application.geoportalcommon.shared.geoportal.config.layers.Cros import org.gcube.application.geoportalcommon.shared.geoportal.config.layers.LayerIDV; import org.gcube.application.geoportalcommon.shared.geoportal.materialization.GCubeSDILayer; import org.gcube.application.geoportalcommon.shared.geoportal.materialization.IndexLayerDV; +import org.gcube.application.geoportalcommon.shared.geoportal.materialization.innerobject.BBOXDV; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants.MAP_PROJECTION; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerServiceAsync; import org.gcube.portlets.user.geoportaldataviewer.client.events.ApplyCQLToLayerOnMapEvent; +import org.gcube.portlets.user.geoportaldataviewer.client.events.FitMapToExtentEvent; +import org.gcube.portlets.user.geoportaldataviewer.client.gis.ExtentWrapped; +import org.gcube.portlets.user.geoportaldataviewer.client.gis.MapUtils; import org.gcube.portlets.user.geoportaldataviewer.client.ui.util.OLGeoJSONUtil; import org.gcube.portlets.user.geoportaldataviewer.client.util.LoaderIcon; import org.gcube.portlets.user.geoportaldataviewer.client.util.URLUtil; @@ -39,16 +43,24 @@ import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.http.client.URL; +import com.google.gwt.json.client.JSONArray; +import com.google.gwt.json.client.JSONObject; +import com.google.gwt.json.client.JSONParser; +import com.google.gwt.json.client.JSONValue; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; 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.HTML; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Widget; import jsinterop.base.JsPropertyMap; +import ol.Coordinate; +import ol.Extent; import ol.Feature; +import ol.OLFactory; /** * The Class CrossFilteringLayerPanel. @@ -461,12 +473,14 @@ public class CrossFilteringLayerPanel extends Composite { @Override public void onSuccess(String response) { Feature[] features = OLGeoJSONUtil.readGeoJsonFeatures(MAP_PROJECTION.EPSG_4326, response); - + if (features != null) { int dataCount = features.length; panelResults.clear(); panelResults.add(new HTML("
")); + + FlexTable flexTable = new FlexTable(); String message = ""; @@ -480,12 +494,73 @@ public class CrossFilteringLayerPanel extends Composite { HTML resultMessage = new HTML(); resultMessage.getElement().addClassName("search_result_msg"); resultMessage.setHTML(message); - panelResults.add(resultMessage); + flexTable.setWidget(0, 0, resultMessage.asWidget()); + panelResults.add(flexTable); + + try { + JSONObject jObject = (JSONObject) JSONParser.parseStrict(response); + JSONArray bbox = (JSONArray) jObject.get("bbox"); + double[] coords = new double[bbox.size()]; + for (int i = 0; i < bbox.size(); i++) { + JSONValue coord = bbox.get(i); + coords[i] = Double.parseDouble(coord.toString()); + } + + //Inverting coordinate to lat/long for EPSG:3857 Pseudo-Mercator + Coordinate lower = OLFactory.createCoordinate(coords[1], coords[0]); + Coordinate lowerCoord = MapUtils.transformCoordiante(lower, MAP_PROJECTION.EPSG_4326.getName(), + MAP_PROJECTION.EPSG_3857.getName()); + + Coordinate upper = OLFactory.createCoordinate(coords[3], coords[2]); + Coordinate upperCoord = MapUtils.transformCoordiante(upper, MAP_PROJECTION.EPSG_4326.getName(), + MAP_PROJECTION.EPSG_3857.getName()); + + final Extent transfExtent = new ExtentWrapped(lowerCoord.getX(), lowerCoord.getY(), upperCoord.getX(), upperCoord.getY()); + GWT.log("Zoom to selected - transf extent: "+transfExtent); + + + Button selectTo = new Button("Zoom to selected"); + selectTo.setType(ButtonType.DEFAULT); + selectTo.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + applicationBus.fireEvent(new FitMapToExtentEvent(transfExtent)); + + } + }); + flexTable.setWidget(1,0,selectTo); + //panelResults.add(selectTo); + + }catch (Exception e) { + // TODO: handle exception + } } + + } }); } + + public static final BBOXDV fromGeoJSON(double[] coords) { + BBOXDV toReturn = new BBOXDV(); + toReturn.setMaxX(coords[0]); + toReturn.setMinY(coords[1]); + + if (coords.length == 6) { + // 3D + toReturn.setMinZ(coords[2]); + toReturn.setMinX(coords[3]); + toReturn.setMaxY(coords[4]); + toReturn.setMaxZ(coords[5]); + } else { + toReturn.setMinX(coords[2]); + toReturn.setMaxY(coords[3]); + } + return toReturn; + } + /** * Load inner level.