/* * */ package org.gcube.portlets.user.geoportaldataviewer.client; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.gcube.application.geoportalcommon.shared.gis.BoundsMap; import org.gcube.application.geoportalcommon.shared.products.BaseConcessioneDV; import org.gcube.application.geoportalcommon.shared.products.content.WorkspaceContentDV; import org.gcube.application.geoportalcommon.shared.products.model.LayerConcessioneDV; import org.gcube.application.geoportalcommon.shared.products.model.UploadedImageDV; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants.LayerType; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants.MAP_PROJECTION; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants.MapEventType; import org.gcube.portlets.user.geoportaldataviewer.client.events.QueryDataEvent; import org.gcube.portlets.user.geoportaldataviewer.client.events.QueryDataEventHandler; import org.gcube.portlets.user.geoportaldataviewer.client.events.application.ShowDetailsEvent; import org.gcube.portlets.user.geoportaldataviewer.client.events.application.ZoomOutOverMinimumEvent; import org.gcube.portlets.user.geoportaldataviewer.client.events.application.ZoomOutOverMinimumEventHandler; import org.gcube.portlets.user.geoportaldataviewer.client.events.layers.AddedLayerToMapEvent; import org.gcube.portlets.user.geoportaldataviewer.client.events.layers.AddedLayerToMapEventHandler; 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.gis.OpenLayerMap; import org.gcube.portlets.user.geoportaldataviewer.client.ui.ModalWindow; import org.gcube.portlets.user.geoportaldataviewer.client.util.StringUtil; import org.gcube.portlets.user.geoportaldataviewer.client.util.URLUtil; import org.gcube.portlets.user.geoportaldataviewer.shared.GeoNaSpatialQueryResult; import org.gcube.portlets.user.geoportaldataviewer.shared.cl.document.materialization.GCubeSDILayerDV; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.GeoQuery; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.IndexLayer; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerItem; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerObject; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerObject.LayerObjectType; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wfs.FeatureRow; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wms.GeoInformationForWMSRequest; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wms.ZAxis; import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.Heading; import com.github.gwtbootstrap.client.ui.Label; import com.github.gwtbootstrap.client.ui.constants.ButtonType; 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; import com.google.gwt.dom.client.Style.Unit; 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.json.client.JSONArray; import com.google.gwt.json.client.JSONParser; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.EventListener; import com.google.gwt.user.client.Random; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; 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.ScrollPanel; import com.google.gwt.user.client.ui.VerticalPanel; import ol.Coordinate; import ol.Extent; import ol.OLFactory; import ol.format.GeoJson; import ol.geom.Geometry; /** * The Class LayerManager. * * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) * * Oct 27, 2020 */ public class LayerManager { /** The ol map. */ private OpenLayerMap olMap; private HandlerManager layerManagerBus = new HandlerManager(""); private HandlerManager applicationBus; private org.gcube.application.geoportalcommon.shared.LayerItem baseLayerFromISProfile; private OverlayLayerManager overlayLayerManager; /** * Instantiates a new layer manager. * * @param applicationBus the application bus */ public LayerManager(HandlerManager applicationBus) { this.applicationBus = applicationBus; overlayLayerManager = new OverlayLayerManager(applicationBus); bindEvents(); } /** * Bind events. */ private void bindEvents() { // TODO Manage QueryDataEvent // layerManagerBus.addHandler(QueryDataEvent.TYPE, new QueryDataEventHandler() { // // @Override // public void onQueryInteraction(final QueryDataEvent queryEvent) { // // GeoportalDataViewerConstants.print("fired QueryDataEvent: // // "+queryEvent.toString()); // // if (queryEvent.getGeoQuery() != null) { // GeoQuery selectDataInfo = queryEvent.getGeoQuery(); // String mongoItemId = queryEvent.getMongoItemId(); // // GWT.log("(" + selectDataInfo.getX1() + "," + selectDataInfo.getY1() + ")(" + selectDataInfo.getX2() // + "," + selectDataInfo.getY2() + ")"); // // BoundsMap mapBBOX = new BoundsMap(); // double minX = queryEvent.getGeoQuery().getX1(); // double minY = queryEvent.getGeoQuery().getY1(); // Coordinate centerCoordinate = new Coordinate(minX, minY); // centerCoordinate = olMap.transform(centerCoordinate, MAP_PROJECTION.EPSG_3857.getName(), // MAP_PROJECTION.EPSG_4326.getName()); // mapBBOX.setLowerLeftX(centerCoordinate.getX()); // mapBBOX.setLowerLeftY(centerCoordinate.getY()); // //// double maxX = olMap.getExtent().getUpperRightX(); //// double maxY = olMap.getExtent().getUpperRightY(); // double maxX = queryEvent.getGeoQuery().getX2(); // double maxY = queryEvent.getGeoQuery().getY2(); // centerCoordinate = new Coordinate(maxX, maxY); // centerCoordinate = olMap.transform(centerCoordinate, MAP_PROJECTION.EPSG_3857.getName(), // MAP_PROJECTION.EPSG_4326.getName()); // mapBBOX.setUpperRightX(centerCoordinate.getX()); // mapBBOX.setUpperRightY(centerCoordinate.getY()); // // mapBBOX.setCrs(MAP_PROJECTION.EPSG_4326.getName()); // // GWT.log("Bounds is: " + mapBBOX); // GWT.log("MAX_WFS_FEATURES is: " + GeoportalDataViewerConstants.MAX_WFS_FEATURES); // // GeoportalDataViewerConstants.print("calling getDataResult"); // // List listLO = new ArrayList(); // // for querying base layers // listLO.addAll(mapBaseLayerObjects.values()); // // // for querying detail layers only in this case // if (olMap.getCurrentResolution() < OLMapManager.LAYER_DETAIL_MAX_RESOLUTION) { // Collection collLO = mapDetailLayerObjects.values(); // listLO.addAll(collLO); // // ArrayList layerVisibility = new ArrayList(collLO.size()); // layerVisibility.addAll(collLO); // //Managing layer visibility. If a layer is not visible has to be not queryable // for (LayerObject layerObject : layerVisibility) { // String layerName = layerObject.getLayerItem().getName(); // boolean isLayerVisible = olMap.isLayerVisible(layerName); // if(!isLayerVisible) { // GWT.log("From querying removing layername: "+layerName + ", it is not visible"); // listLO.remove(layerObject); // } //// else { //// ExtentWrapped layerExtent = olMap.getSourceExtentForLayer(layerName); //// if(layerExtent!=null) { //// ExtentWrapped centerQueryPoint = new ExtentWrapped(minX, minY, maxX,maxY); //// //// boolean contains = layerExtent.containsExtent(centerQueryPoint); //// GWT.log("layer: "+layerName + " contains the queried BBOX: "+contains); //// } //// } //// // } // } // // GeoportalDataViewerServiceAsync.Util.getInstance().getDataResult(listLO, olMap.getProjectionCode(), // mapBBOX, GeoportalDataViewerConstants.MAX_WFS_FEATURES, olMap.getCurrentZoomLevel(), // new AsyncCallback>() { // // @Override // public void onFailure(Throwable caught) { // // GeoportalDataViewerConstants.print("on Failure DataResult: // // "+caught.getMessage()); // } // // @Override // public void onSuccess(List listGeonaDataObjects) { // // GWT.log("GeoNaDataObject's is/are " + listGeonaDataObjects.size()); // // GWT.log("GeoNaDataObject's: " + listGeonaDataObjects); // // GeoportalDataViewerConstants.print("GeoNaDataObject's: // // "+listGeonaDataObjects); // // if (listGeonaDataObjects == null || listGeonaDataObjects.isEmpty()) // return; // // FeatureRow feature = null; // // MapEventType sourceEvent = queryEvent.getSourceMapEventType(); // // // TODO SWTCH FOR EARCH ITEM TYPE // for (GeoNaSpatialQueryResult geoNaDataObject : listGeonaDataObjects) { // List features = geoNaDataObject.getFeatures(); // // GWT.log("GeoNaDataObject Source layer item name: " // + geoNaDataObject.getSourceLayerObject().getLayerItem().getName()); // // // USING ONLY THE FIRST FEATURE IN THE LIST // if (features != null && features.size() > 0) { // String theProductId = null; // // I need to show exactly the feature with produc_id == recordId // if (mongoItemId != null) { // for (FeatureRow fRow : features) { // List productIdLst = fRow.getMapProperties() // .get("product_id"); // theProductId = productIdLst.get(0); // try { // // long productId = Long.parseLong(thePID); // if (theProductId == mongoItemId) { // feature = fRow; // GWT.log("Found recorId == product_id with id: " // + theProductId); // break; // } // } catch (Exception e) { // // TODO: handle exception // } // } // } // // // If mongoItemId not passed, I'm using the first feature returned // if (mongoItemId == null) { // feature = features.get(0); // List productIdLst = feature.getMapProperties() // .get("product_id"); // if (productIdLst == null) { // // in this case the feature/s returned is/are a (detail) layer/s // // belonging // // to a record/concessione (not centroid layer), // // so calling show popuup info on detail layers if the // // following events are true. // if (sourceEvent.equals(MapEventType.MOUSE_CLICK) && olMap // .getCurrentZoomLevel() > OLMapManager.QUERY_MIN_ZOOM_LEVEL) { // // // Here I need to pass only the visible layers // showPopupInfoForLayer(listGeonaDataObjects, // queryEvent.getQueryClickExtent()); // } // return; // } // theProductId = productIdLst.get(0); // } else { // // the recordId to show has been passed but not found into list of // // FeatureRow // if (feature == null) { // return; // } // } // // GWT.log("the product id is: " + theProductId); // // Displaying popup info for centroid layer // if (sourceEvent.equals(MapEventType.MOUSE_CLICK) // || sourceEvent.equals(MapEventType.ADDED_CENTROID_LAYER_TO_MAP)) { // showPopupInfoForCentroidLayer(geoNaDataObject, feature, // queryEvent.getQueryClickExtent().getCenter()); // } // // // //TODO LOAD LAYERS FOM BBOX // GWT.log("TODO LAOD LAYERS" ); // // // //// // retrieving and showing WMS layers of a concessione if the ZOOM level is > //// // QUERY_MIN_ZOOM_LEVEL //// if (olMap.getCurrentZoomLevel() > OLMapManager.QUERY_MIN_ZOOM_LEVEL) { //// GeoportalDataViewerServiceAsync.Util.getInstance().getLayersForId( //// "concessione", theProductId, //// new AsyncCallback>() { //// //// @Override //// public void onFailure(Throwable caught) { //// // TODO Auto-generated method stub //// //// } //// //// @Override //// public void onSuccess(List result) { //// //// for (LayerConcessioneDV layer : result) { //// GWT.log("Adding layer: " + layer.getLayerName()); //// addLayer("concessione", layer.getLayerName(), //// layer.getLayerName(), layer.getWmsLink(), //// false, false, layer.getLayerUUID(), true, //// OLMapManager.LAYER_DETAIL_MIN_RESOLUTION, //// OLMapManager.LAYER_DETAIL_MAX_RESOLUTION, //// layer.getRefersTo()); //// } //// //// } //// }); //// } else { //// // removing all WMS detail layers if the ZOOM level is < //// // QUERY_MIN_ZOOM_LEVEL //// removeAllDetailLayers(); //// } // // // } // } // } // }); // } // } // }); layerManagerBus.addHandler(AddedLayerToMapEvent.TYPE, new AddedLayerToMapEventHandler() { @Override public void onLayerRendered(AddedLayerToMapEvent addedLayerToMapEvent) { GWT.log("Fired into layerManagerBus " + addedLayerToMapEvent); applicationBus.fireEvent(addedLayerToMapEvent); } }); layerManagerBus.addHandler(ZoomOutOverMinimumEvent.TYPE, new ZoomOutOverMinimumEventHandler() { @Override public void onZoomOut(ZoomOutOverMinimumEvent zoomOutEvent) { GWT.log("Fired into layerManagerBus " + zoomOutEvent); removeAllDetailLayers(); applicationBus.fireEvent(zoomOutEvent); } }); } /** * Removes the all detail layers. */ public void removeAllDetailLayers() { // TODO GWT.log("TODO : Implenent clear layers"); // REMOVE FROM MAP // olMap.removeAllDetailLayers(); // // // REMOVE FROM MANAGER // overlayLayerManager.resetLayers(); // // // REMOVE FROM STATUS // mapDetailLayerObjects.clear(); } /** * Parses the geona references. * * @param itemType the item type * @param fRow the f row * @return the show details event */ private ShowDetailsEvent parseGeonaReferences(String itemType, FeatureRow fRow) { if (fRow == null) return null; List productIds = fRow.getMapProperties().get("product_id"); if (productIds != null && productIds.size() > 0) { String productId = productIds.get(0); String itemName = "Dettagli Prodotto"; List listName = fRow.getMapProperties().get("nome"); if (listName != null && listName.size() > 0) { itemName = listName.get(0); } return new ShowDetailsEvent(itemType, productId, itemName, fRow); } return null; } // ******************************** LAYERS Management public void addLayer(LayerObject object) { GWT.log("Layers management : Add layer "+object); switch(object.getType()) { case BASE_LAYER : { GWT.log("ERROR : cannot add base layers "); break; } case GENERIC_LAYER :{ GWT.log("SUPPORT TO EXTERNAL LAYERS TO BE IMPLEMENTED"); break; } case PROJECT_LAYER : { // Add TO MAP olMap.addWMSDetailLayer(object.getLayerItem()); // ADD TO MAP MANAGER PANEL getOverlayLayerManager().addLayerItem(object); // ADD TO STATUS GeoportalDataViewer.getStatus().addOpenedProjectLayer(object.getUcid(), object.getProjectId(), object); break; } case INDEX_LAYER :{ // Add TO MAP olMap.addWMSDetailLayer(object.getLayerItem()); // ADD TO MAP MANAGER PANEL getOverlayLayerManager().addLayerItem(object); // ADD TO STATUS GeoportalDataViewer.getStatus().addOpenedIndex(object.getUcid(), object); break; } } } // /** // * Adds the layer. // * // * @param geonaItemType the geona item type // * @param layerTitle the layer title // * @param layerName the layer name // * @param wmsLink the wms link // * @param isBase the is base // * @param displayInLayerSwitcher the display in layer switcher // * @param UUID the uuid // * @param asDetailLayer the as detail layer // * @param minResolution the min resolution // * @param maxResolution the max resolution // * @param refersToBaseConcessione the refers to base concessione // */ // public void addLayer(final String geonaItemType, final String layerTitle, final String layerName, // final String wmsLink, final boolean isBase, final boolean displayInLayerSwitcher, final String UUID, // final boolean asDetailLayer, Double minResolution, Double maxResolution, // BaseConcessioneDV refersToBaseConcessione) { // //// final LayoutContainer westPanel = (LayoutContainer) layersPanel.getParent(); //// //// if(layersPanel.getLayerItems().size()==0) //// westPanel.mask("Adding..."+layerName, "x-mask-loading"); //// else //// layersPanel.mask("Adding..."+layerName, "x-mask-loading"); // // final LayerType featureType = isBase ? LayerType.RASTER_BASELAYER : LayerType.FEATURE_TYPE; //// Info.display("Adding Layer", layerName); // // if (wmsLink == null || wmsLink.isEmpty()) { // GeoportalDataViewerConstants.printJs("Skipping add layer for wmsLink as null or empty"); // return; // } // // GeoportalDataViewerServiceAsync.Util.getInstance().parseWmsRequest(wmsLink, layerName, // new AsyncCallback() { // // @Override // public void onFailure(Throwable caught) { // // Window.alert(caught.getMessage()); // } // // @Override // public void onSuccess(GeoInformationForWMSRequest geoInfoWMS) { // // GWT.log("Parsed WMS Request returned: " + geoInfoWMS); // // ddLayerByWms(featureType, layerTitle, result.getLayerName(), // // result.getWmsRequest(), result.getBaseWmsServiceHost(), true, isBase, // // displayInLayerSwitcher, (ArrayList) // // result.getStyles().getGeoStyles(), result.getWmsRequest(), false, // // result.getMapWMSNoStandard(), result.isNcWMS(), UUID, result.getZAxis()); // // LayerItem layerItem = toLayerItem(featureType, layerTitle, geoInfoWMS.getLayerName(), // geoInfoWMS.getWmsRequest(), geoInfoWMS.getBaseWmsServiceHost(), true, isBase, // displayInLayerSwitcher, (ArrayList) geoInfoWMS.getStyles().getGeoStyles(), // geoInfoWMS.getWmsRequest(), false, geoInfoWMS.getMapWMSNoStandard(), // geoInfoWMS.isNcWMS(), UUID, geoInfoWMS.getZAxis(), minResolution, maxResolution); // // LayerObject lo = new LayerObject(); // lo.setLayerItem(layerItem); // lo.setItemType(geonaItemType); // lo.setSourceConcessione(refersToBaseConcessione); // // String key = layerItem.getName(); // should be unique // // layerObjects.put(key, lo); // // if (!asDetailLayer) { // // is a base layer // LayerObject blo = mapBaseLayerObjects.get(key); // if (blo == null) { // olMap.addWMSLayer(layerItem); // mapBaseLayerObjects.put(key, lo); // } else { // GWT.log("Skipping base layer " + key + " already added to Map"); // } // } else { // LayerObject dlo = mapDetailLayerObjects.get(key); // if (dlo == null) { // mapDetailLayerObjects.put(key, lo); // olMap.addWMSDetailLayer(layerItem); // overlayLayerManager.addLayerItem(lo); // //overlayLayerManager.show(); // } else { // GWT.log("Skipping detail layer " + key + " already added to Map"); // } // } // } // }); // } /** * Show popup info for layer. * * @param listGeoNaDataObject the list geo na data object * @param queryClick the query click */ public void showPopupInfoForLayer(List listGeoNaDataObject, ExtentWrapped queryClick) { ScrollPanel scrollPanel = new ScrollPanel(); final FlowPanel flowPanel = new FlowPanel(); flowPanel.getElement().getStyle().setProperty("maxHeight", "600px"); scrollPanel.add(flowPanel); List