package org.gcube.portlets.user.geoportaldataviewer.client.gis; import java.util.ArrayList; import java.util.LinkedHashMap; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants.MAP_PROJECTION; import org.gcube.portlets.user.geoportaldataviewer.client.events.AddedLayerToMapEvent; import org.gcube.portlets.user.geoportaldataviewer.client.events.AddedLayerToMapEvent.LAYER_TYPE; import org.gcube.portlets.user.geoportaldataviewer.client.events.DoActionOnDetailLayersEvent.SwapLayer; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerItem; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style.Visibility; import com.google.gwt.event.shared.HandlerManager; 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.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import ol.Collection; import ol.Coordinate; import ol.Feature; import ol.FeatureOptions; import ol.Map; import ol.MapBrowserEvent; import ol.MapEvent; import ol.MapOptions; import ol.OLFactory; import ol.Overlay; import ol.OverlayOptions; import ol.Size; import ol.View; import ol.ViewOptions; import ol.control.Attribution; import ol.event.EventListener; import ol.geom.Geometry; import ol.interaction.Draw; import ol.interaction.DrawOptions; import ol.interaction.Extent; import ol.interaction.ExtentOptions; import ol.interaction.Interaction; import ol.interaction.KeyboardPan; import ol.interaction.KeyboardZoom; import ol.layer.Base; import ol.layer.Image; import ol.layer.LayerOptions; import ol.layer.Tile; import ol.layer.VectorLayerOptions; import ol.proj.Projection; import ol.proj.ProjectionOptions; import ol.source.ImageWms; import ol.source.ImageWmsOptions; import ol.source.ImageWmsParams; import ol.source.Osm; import ol.source.Source; import ol.source.Vector; import ol.source.XyzOptions; /** * The Class OpenLayerOSM. * * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) * * Oct 27, 2020 */ public abstract class OpenLayerOSM { public static final int MAX_ZOOM = 21; /** * Click listener. * * @param event the event */ public abstract void clickListener(MapBrowserEvent event); /** * Move end listener. * * @param event the event */ public abstract void moveEndListener(MapEvent event); /** * Move start listener. * * @param event the event */ public abstract void moveStartListener(MapEvent event); /** * Map zoom listener. * * @param event the event */ public abstract void mapZoomListener(MapEvent event); /** * Map zoom end listener. * * @param event the event */ public abstract void mapZoomEndListener(MapEvent event); /** The map. */ private Map map; /** The view. */ private View view; /** The view options. */ private ViewOptions viewOptions = OLFactory.createOptions(); /** The projection options. */ private ProjectionOptions projectionOptions = OLFactory.createOptions(); /** The point draw. */ private Draw queryPoint; private Extent queryBox; /** The popup overlay. */ private Overlay popupOverlay; private HandlerManager eventBus; private boolean isQueryBoxActive; private boolean isQueryPointActive; private LinkedHashMap wmsDetailsLayerMap; private Integer[] wmsDetailsLayerZIndex = new Integer[100]; private LinkedHashMap wmsLayerMap; /** * Instantiates a new open layer OSM. * * @param divTargetId the div target id * @param eventBus the event bus */ /* * (non-Javadoc) * * @see de.desjardins.ol3.demo.client.example.Example#show() */ public OpenLayerOSM(String divTargetId, HandlerManager eventBus) { this.eventBus = eventBus; for (int i = 0; i < 100; i++) { wmsDetailsLayerZIndex[i] = 1000 + i; } // create a OSM-layer XyzOptions xyzOptions = OLFactory.createOptions(); // osmSourceOptions.setCrossOrigin("Anonymous"); // osmSourceOptions.setTileLoadFunction(null); Osm osmSource = new Osm(xyzOptions); LayerOptions osmLayerOptions = OLFactory.createOptions(); osmLayerOptions.setSource(osmSource); Tile osmLayer = new Tile(osmLayerOptions); // create a projection projectionOptions.setCode(MAP_PROJECTION.EPSG_3857.getName()); projectionOptions.setUnits("m"); Projection projection = new Projection(projectionOptions); viewOptions.setProjection(projection); viewOptions.setMaxZoom(MAX_ZOOM); // create a view view = new View(viewOptions); // create the map MapOptions mapOptions = OLFactory.createOptions(); mapOptions.setTarget(divTargetId); mapOptions.setView(view); map = new Map(mapOptions); map.addLayer(osmLayer); // map.addLayer(tileDebugLayer); // add some controls map.addControl(OLFactory.createScaleLine()); MapUtils.addDefaultControls(map.getControls()); Attribution attribution = new Attribution(); attribution.setCollapsed(true); map.addControl(attribution); // add some interactions map.addInteraction(new KeyboardPan()); map.addInteraction(new KeyboardZoom()); bindEvents(); } /** * Bind events. */ private void bindEvents() { map.addClickListener(new EventListener() { @Override public void onEvent(MapBrowserEvent event) { clickListener(event); } }); map.addMoveEndListener(new EventListener() { @Override public void onEvent(MapEvent event) { moveEndListener(event); } }); map.addMoveStartListener(new EventListener() { @Override public void onEvent(MapEvent event) { moveStartListener(event); } }); map.addMapZoomListener(new EventListener() { @Override public void onEvent(MapEvent event) { mapZoomListener(event); } }); map.addMapZoomEndListener(new EventListener() { @Override public void onEvent(MapEvent event) { mapZoomEndListener(event); } }); } /** * Sets the center. * * @param centerCoordinate the new center */ public void setCenter(Coordinate centerCoordinate) { view.setCenter(centerCoordinate); } /** * Sets the center. * * @param zoom the new zoom */ public void setZoom(int zoom) { view.setZoom(zoom); } /** * Show popup. * * @param html the html * @param coordinate the coordinate */ public void showPopup(String html, Coordinate coordinate) { GWT.log("Showing popup on: " + coordinate); // GeoportalDataViewerConstants.print("Showing popup on: "+coordinate); Element elPopup = DOM.getElementById("popup"); elPopup.getStyle().setVisibility(Visibility.VISIBLE); if (popupOverlay == null) { popupOverlay = addOverlay(elPopup); addPopupCloserHandelr(popupOverlay); } Element popContent = DOM.getElementById("popup-content"); popContent.setInnerHTML(html); popupOverlay.setPosition(coordinate); } /** * Hide popup. */ public void hidePopup() { if (popupOverlay != null) { Element elPopup = DOM.getElementById("popup"); elPopup.getStyle().setVisibility(Visibility.HIDDEN); } } /** * Adds the popup closer handelr. * * @param popupOverlay the popup overlay */ private void addPopupCloserHandelr(Overlay popupOverlay) { Element elPopupCloser = DOM.getElementById("popup-closer"); Event.sinkEvents(elPopupCloser, Event.ONCLICK); Event.setEventListener(elPopupCloser, new com.google.gwt.user.client.EventListener() { @Override public void onBrowserEvent(Event event) { if (Event.ONCLICK == event.getTypeInt()) { popupOverlay.setPosition(null); } } }); } /** * Handler popu closer. * * @param divId the div id * @param overlayId the overlay id */ public static native void handlerPopuCloser(String divId, String overlayId) /*-{ var closer = $doc.getElementById(divId); var overlay = $doc.getElementById(overlayId); closer.onclick = function() { overlay.setPosition(undefined); closer.blur(); return false; }; }-*/; /** * Adds the WMS layer. * * @param layerItem the layer item */ public void addWMSLayer(LayerItem layerItem) { if (wmsLayerMap == null) wmsLayerMap = new LinkedHashMap(); String key = layerItem.getName(); Image layer = wmsLayerMap.get(layerItem.getName()); if (layer == null) { 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); // visibleLayerItems map.addLayer(wmsLayer); wmsLayerMap.put(key, wmsLayer); GWT.log("Added WMSLayer for layer: " + layerItem.getName()); eventBus.fireEvent(new AddedLayerToMapEvent(layerItem, LAYER_TYPE.BASE)); } else { GWT.log("The WMS layer with key: " + key + " already exists, skipping"); } } /** * Adds the WMS detail layer. * * @param layerItem the layer item */ public synchronized void addWMSDetailLayer(LayerItem layerItem) { if (wmsDetailsLayerMap == null) wmsDetailsLayerMap = new LinkedHashMap(); String key = layerItem.getName(); Image layer = wmsDetailsLayerMap.get(key); if (layer == null) { GWT.log("The detail 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); wmsLayer.setZIndex(wmsDetailsLayerMap.size() + 1); map.addLayer(wmsLayer); wmsDetailsLayerMap.put(key, wmsLayer); GWT.log("Added WMSDetailLayer 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. */ public void removeAllDetailLayers() { // NOT NEEDED ANYMORE.. I'M USING MIN/MAX LAYER RESOLUTION if (wmsDetailsLayerMap == null) return; GWT.log("Removing layers: " + wmsDetailsLayerMap.keySet() + " from map"); for (String key : wmsDetailsLayerMap.keySet()) { Image layer = wmsDetailsLayerMap.get(key); map.removeLayer(layer); } wmsDetailsLayerMap.clear(); } /** * Adds the vector. * * @param geometry the geometry */ public void addVector(Geometry geometry) { VectorLayerOptions vectorLayerOptions = new VectorLayerOptions(); vectorLayerOptions.setMap(map); // Style style = new Style(); // FillOptions fillOptions = new FillOptions(); // Color color = new Color(0, 0, 255, 1.0); // fillOptions.setColor(color); // Fill fill = new Fill(fillOptions); // style.setFill(fill); FeatureOptions featureOptions = new FeatureOptions(); featureOptions.setGeometry(geometry); Feature feature = OLFactory.createFeature(featureOptions); Vector vectorSource = OLFactory.createVectorSource(); vectorSource.addFeature(feature); vectorLayerOptions.setSource(vectorSource); ol.layer.Vector vector = OLFactory.createVector(vectorLayerOptions); map.addLayer(vector); } /** * Adds the point vector source. * * @return the draw */ public Draw addPointVectorSource() { if (queryPoint == null) initPointInteraction(); map.addInteraction(queryPoint); isQueryPointActive = true; return queryPoint; } /** * Inits the point interaction. */ private void initPointInteraction() { Vector vectorSource = new Vector(); DrawOptions drawOptions = new DrawOptions(); drawOptions.setSource(vectorSource); drawOptions.setType("Point"); drawOptions.setMaxPoints(1); drawOptions.setMinPoints(1); drawOptions.setWrapX(false); queryPoint = new Draw(drawOptions); queryPoint.addChangeListener(new EventListener() { @Override public void onEvent(ol.events.Event event) { GWT.log(event.getType()); } }); } /** * Removes the interaction. * * @param interaction the interaction */ public void removeInteraction(Interaction interaction) { map.removeInteraction(interaction); } /** * Removes the interactions. */ public void removeQueryInteractions() { Collection interactions = map.getInteractions(); if (interactions != null) { map.removeInteraction(queryBox); map.removeInteraction(queryPoint); isQueryBoxActive = false; isQueryPointActive = false; } } /** * Adds the extent interaction. * * @return the extent */ public Extent addExtentInteraction() { ExtentOptions extentOptions = new ExtentOptions(); extentOptions.setWrapX(false); // StyleOptions styleOptions = new StyleOptions(); // styleOptions.setStroke(stroke); // styleOptions.set // extentOptions.setBoxStyle(new ol.style.Style(styleOptions)); queryBox = new Extent(extentOptions); map.addInteraction(queryBox); isQueryBoxActive = true; return queryBox; } /** * Adds the overlay. * * @param element the element * @return the overlay */ public Overlay addOverlay(Element element) { /** * Create an overlay to anchor the popup to the map. */ OverlayOptions overlayOptions = new OverlayOptions(); overlayOptions.setAutoPan(true); Overlay overlay = new Overlay(overlayOptions); overlay.setElement(element); map.addOverlay(overlay); return overlay; } /** * Gets the projection code. * * @return the projection code */ public String getProjectionCode() { return map.getView().getProjection().getCode(); } /** * Gets the current zoom level. * * @return the current zoom level */ public double getCurrentZoomLevel() { return map.getView().getZoom(); } /** * Gets the current zoom level. * * @return the current zoom level */ public double getCurrentResolution() { return map.getView().getResolution(); } /** * Gets the bbox. * * @return the bbox */ public ol.Extent getBBOX() { return getExtent(); } /** * Gets the extent. * * @return the extent */ public ol.Extent getExtent() { return this.map.getView().calculateExtent(map.getSize()); } /** * Transform. * * @param centerCoordinate the center coordinate * @param source the source * @param target the target * @return the coordinate */ public Coordinate transform(Coordinate centerCoordinate, String source, String target) { return Projection.transform(centerCoordinate, source, target); } /** * Checks if is query box active. * * @return true, if is query box active */ public boolean isQueryBoxActive() { return isQueryBoxActive; } /** * Checks if is query point active. * * @return true, if is query point active */ public boolean isQueryPointActive() { return isQueryPointActive; } /** * Gets the size. * * @return the size */ public Size getSize() { return map.getSize(); } /** * Map instancied. * * @return true, if successful */ public boolean mapInstancied() { return this.map != null; } /** * Gets the layers from map. * * @return the layers from map */ public ArrayList getLayersFromMap() { Collection layers = map.getLayers(); ArrayList layerNames = null; if (layers != null) { Base[] layersArr = layers.getArray(); layerNames = new ArrayList(layersArr.length); for (int i = 0; i < layersArr.length; i++) { Base layer = layersArr[i]; if (layer instanceof Image) { Image layerImage = (Image) layer; Source source = layerImage.getSource(); // GeoportalDataViewerConstants.printJsObj(source); String sorceRootObj = GeoportalDataViewerConstants.toJsonObj(source); JSONValue jsonObj = JSONParser.parseStrict(sorceRootObj); // GWT.log("jsonObj: " + jsonObj.toString()); JSONObject jsonSourceObj = (JSONObject) jsonObj; GeoportalDataViewerConstants.printJsObj(jsonSourceObj); JSONObject jsonParamsObj = (JSONObject) jsonSourceObj.get("params_"); // GWT.log("jsonParamsObj is: "+jsonParamsObj); JSONValue jsonLayers = jsonParamsObj.get("LAYERS"); GWT.log("theLayerName name is: " + jsonLayers); layerNames.add(jsonLayers.toString()); JSONObject imagesParamsObj = (JSONObject) jsonSourceObj.get("image_"); JSONArray extent = (JSONArray) imagesParamsObj.get("extent"); GWT.log("extentLayer: " + extent.toString()); } } } return layerNames; } /** * Gets the source extent for layer. * * @param layerName the layer name * @return the source extent for layer */ public ExtentWrapped getSourceExtentForLayer(String layerName) { Collection layers = map.getLayers(); if (layers != null) { Base[] layersArr = layers.getArray(); for (int i = 0; i < layersArr.length; i++) { Base layer = layersArr[i]; if (layer instanceof Image) { Image layerImage = (Image) layer; Source source = layerImage.getSource(); // GeoportalDataViewerConstants.printJsObj(source); String sorceRootObj = GeoportalDataViewerConstants.toJsonObj(source); JSONValue jsonObj = JSONParser.parseStrict(sorceRootObj); // GWT.log("jsonObj: " + jsonObj.toString()); JSONObject jsonSourceObj = (JSONObject) jsonObj; // GeoportalDataViewerConstants.printJsObj(jsonSourceObj); JSONObject jsonParamsObj = (JSONObject) jsonSourceObj.get("params_"); // GWT.log("jsonParamsObj is: "+jsonParamsObj); JSONValue jsonLayers = jsonParamsObj.get("LAYERS"); String layerNameIntoMap = jsonLayers.toString().replaceAll("\"", ""); if (layerName.compareTo(layerNameIntoMap) == 0) { JSONObject imagesParamsObj = (JSONObject) jsonSourceObj.get("image_"); JSONArray extent = (JSONArray) imagesParamsObj.get("extent"); // GWT.log("extentLayer: "+extent.toString()); double minX = Double.parseDouble(extent.get(0).toString()); double minY = Double.parseDouble(extent.get(1).toString()); double maxX = Double.parseDouble(extent.get(2).toString()); double maxY = Double.parseDouble(extent.get(3).toString()); return new ExtentWrapped(minX, minY, maxX, maxY); } } } } return null; } /** * Gets the wms details layer map. * * @return the wms details layer map */ public LinkedHashMap getWmsDetailsLayerMap() { return wmsDetailsLayerMap; } /** * Gets the wms layer map. * * @return the wms layer map */ public LinkedHashMap getWmsLayerMap() { return wmsLayerMap; } /** * Checks if is layer visible. * * @param layerName the layer name * @return true, if is layer visible */ public boolean isLayerVisible(String layerName) { String key = layerName; Image layer = wmsLayerMap.get(key); if (layer != null) return layer.getVisible(); layer = wmsDetailsLayerMap.get(key); if (layer != null) return layer.getVisible(); return false; } /** * Sets the WMS detail layer visible. * * @param layerItem the layer item * @param visible the visible */ public void setWMSDetailLayerVisible(LayerItem layerItem, boolean visible) { String key = layerItem.getName(); Image layer = wmsDetailsLayerMap.get(key); layer.setVisible(visible); } /** * Sets the WMS detail layer opacity. * * @param layerItem the layer item * @param opacity the opacity */ public void setWMSDetailLayerOpacity(LayerItem layerItem, double opacity) { String key = layerItem.getName(); Image layer = wmsDetailsLayerMap.get(key); layer.setOpacity(opacity); } /** * Swap details layers. * * @param layerSource the source index * @param layerTarget the target index */ public void swapDetailsLayers(SwapLayer swapLSource, SwapLayer swapLTarget) { String layerSource = swapLSource.getLayerItem().getName(); String layerTarget = swapLTarget.getLayerItem().getName(); Image layer1 = wmsDetailsLayerMap.get(layerSource); Image layer2 = wmsDetailsLayerMap.get(layerTarget); int zIndexS = swapLSource.getPosition()+1; int zIndexT = swapLTarget.getPosition()+1; GWT.log("new zindex source: "+zIndexS+", new zTarget: "+zIndexT); layer1.setZIndex(zIndexT); layer2.setZIndex(zIndexS); GWT.log("layer1 source: "+layerSource+", new zIndex: "+layer1.getZIndex()); GWT.log("layer1 target: "+layerTarget+", new zIndex: "+layer2.getZIndex()); } /** * Gets the layer by index. * * @param map the map * @param index the index * @return the layer by index */ private Image getLayerByIndex(LinkedHashMap map, int index) { return map.get((map.keySet().toArray())[index]); } }