]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapViewer.java
Improve GIS
[lgpl/argeo-commons.git] / gis / plugins / org.argeo.gis.ui.rap.openlayers / src / main / java / org / argeo / gis / ui / rap / openlayers / OpenLayersMapViewer.java
diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapViewer.java b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapViewer.java
new file mode 100644 (file)
index 0000000..1228611
--- /dev/null
@@ -0,0 +1,242 @@
+package org.argeo.gis.ui.rap.openlayers;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeSet;
+
+import javax.jcr.Node;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.geotools.GeoToolsUtils;
+import org.argeo.geotools.jcr.GeoJcrMapper;
+import org.argeo.gis.ui.AbstractMapViewer;
+import org.argeo.gis.ui.MapViewerListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.geotools.data.FeatureSource;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.polymap.openlayers.rap.widget.OpenLayersWidget;
+import org.polymap.openlayers.rap.widget.base.OpenLayersEventListener;
+import org.polymap.openlayers.rap.widget.base.OpenLayersObject;
+import org.polymap.openlayers.rap.widget.base_types.OpenLayersMap;
+import org.polymap.openlayers.rap.widget.base_types.Projection;
+import org.polymap.openlayers.rap.widget.controls.KeyboardDefaultsControl;
+import org.polymap.openlayers.rap.widget.controls.LayerSwitcherControl;
+import org.polymap.openlayers.rap.widget.controls.NavigationControl;
+import org.polymap.openlayers.rap.widget.controls.OverviewMapControl;
+import org.polymap.openlayers.rap.widget.controls.PanZoomBarControl;
+import org.polymap.openlayers.rap.widget.controls.ScaleControl;
+import org.polymap.openlayers.rap.widget.controls.SelectFeatureControl;
+import org.polymap.openlayers.rap.widget.features.VectorFeature;
+import org.polymap.openlayers.rap.widget.geometry.LineStringGeometry;
+import org.polymap.openlayers.rap.widget.geometry.PointGeometry;
+import org.polymap.openlayers.rap.widget.layers.OSMLayer;
+import org.polymap.openlayers.rap.widget.layers.VectorLayer;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Point;
+
+public class OpenLayersMapViewer extends AbstractMapViewer implements
+               OpenLayersEventListener {
+       private final static Log log = LogFactory.getLog(OpenLayersMapViewer.class);
+
+       private final OpenLayersMap map;
+
+       private Map<String, VectorLayer> vectorLayers = Collections
+                       .synchronizedMap(new HashMap<String, VectorLayer>());
+       private Map<String, FeatureSource<SimpleFeatureType, SimpleFeature>> featureSources = Collections
+                       .synchronizedMap(new HashMap<String, FeatureSource<SimpleFeatureType, SimpleFeature>>());
+
+       public OpenLayersMapViewer(Node context, GeoJcrMapper geoJcrMapper,
+                       Composite parent) {
+               super(context, geoJcrMapper);
+               createControl(parent);
+
+               this.map = ((OpenLayersWidget) getControl()).getMap();
+
+               // mapContextProvider.getMapContext().addMapLayerListListener(this);
+
+               HashMap<String, String> payloadMap = new HashMap<String, String>();
+               payloadMap.put("layername", "event.layer.name");
+               this.map.events.register(this, "changebaselayer", payloadMap);
+               payloadMap.put("property", "event.property");
+               payloadMap.put("visibility", "event.layer.visibility");
+               this.map.events.register(this, "changelayer", payloadMap);
+
+               // WARNING: registering click events on the map hides other events!!
+               // HashMap<String, String> mapPayload = new HashMap<String, String>();
+               // mapPayload.put("bbox", map.getJSObjRef() + ".getExtent().toBBOX()");
+               // mapPayload.put("lonlat", map.getJSObjRef()
+               // + ".getLonLatFromViewPortPx(event.xy)");
+               // mapPayload.put("x", "event.xy.x");
+               // mapPayload.put("y", "event.xy.y");
+               // mapPayload.put("button", "event.button");
+               // map.events.register(this, "click", mapPayload);
+       }
+
+       protected void createControl(Composite parent) {
+               OpenLayersWidget openLayersWidget = new OpenLayersWidget(parent,
+                               SWT.MULTI | SWT.WRAP);
+               openLayersWidget.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+               OpenLayersMap map = openLayersWidget.getMap();
+               map.setProjection(new Projection("EPSG:900913"));
+               map.setDisplayProjection(new Projection("EPSG:4326"));
+               map.setUnits("m");
+
+               map.addControl(new LayerSwitcherControl());
+               NavigationControl navigationControl = new NavigationControl();
+               navigationControl.setObjAttr("handleRightClicks", true);
+               navigationControl.setObjAttr("zoomBoxEnabled", true);
+               map.addControl(navigationControl);
+               map.addControl(new KeyboardDefaultsControl());
+               map.addControl(new PanZoomBarControl());
+               map.addControl(new ScaleControl());
+
+               // WMSLayer baseLayer = new WMSLayer("argeo_dev",
+               // "https://dev.argeo.org/geoserver/wms?",
+               // "naturalearth:10m_admin_0_countries");
+
+               OSMLayer osmLayer = new OSMLayer("OSM",
+                               "http://tile.openstreetmap.org/${z}/${x}/${y}.png", 19);
+               map.addLayer(osmLayer);
+
+               map.addControl(new OverviewMapControl());
+
+               setControl(openLayersWidget);
+       }
+
+       /*
+        * OPENLAYERS MAP
+        */
+
+       public void process_event(OpenLayersObject source, String eventName,
+                       HashMap<String, String> payload) {
+               if (eventName.equals("beforefeatureadded")) {
+                       if (log.isDebugEnabled())
+                               log.debug("before feature added on layer '"
+                                               + payload.get("layername") + "' x=" + payload.get("x")
+                                               + "' y=" + payload.get("y"));
+               } else if (eventName.equals("afterfeatureadded")) {
+                       if (log.isDebugEnabled())
+                               log.debug("after feature added on layer '"
+                                               + payload.get("layername") + "' x=" + payload.get("x")
+                                               + "' y=" + payload.get("y"));
+               } else if (eventName.equals("featureselected")) {
+                       if (log.isDebugEnabled())
+                               log.debug("feature selected " + payload);
+                       String layerId = payload.get("layerId");
+                       String featureId = payload.get("featureId");
+                       if (!getSelected().containsKey(layerId))
+                               getSelected().put(layerId, new TreeSet<String>());
+                       getSelected().get(layerId).add(featureId);
+
+                       for (MapViewerListener listener : getListeners())
+                               listener.featureSelected(layerId, featureId);
+               } else if (eventName.equals("featureunselected")) {
+                       if (log.isDebugEnabled())
+                               log.debug("feature unselected " + payload);
+                       String layerId = payload.get("layerId");
+                       String featureId = payload.get("featureId");
+                       if (getSelected().containsKey(layerId))
+                               getSelected().get(layerId).remove(featureId);
+                       for (MapViewerListener listener : getListeners())
+                               listener.featureUnselected(layerId, featureId);
+
+               } else if (log.isDebugEnabled())
+                       log.debug("Unknown event '" + eventName + "' from "
+                                       + source.getClass().getName() + " (" + source.getJSObjRef()
+                                       + ")" + " : " + payload);
+
+       }
+
+       @Override
+       protected void addFeatureSource(String path,
+                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource) {
+               FeatureIterator<SimpleFeature> featureIterator = null;
+               try {
+                       String layerId = path;
+                       VectorLayer vectorLayer = new VectorLayer(featureSource.getName()
+                                       .toString());
+                       vectorLayer.setObjAttr("id", layerId);
+                       vectorLayers.put(layerId, vectorLayer);
+                       featureSources.put(layerId, featureSource);
+
+                       // selection
+                       HashMap<String, String> selectPayload = new HashMap<String, String>();
+                       selectPayload.put("featureId", "event.feature.id");
+                       selectPayload.put("geometry", "event.feature.geometry");
+                       selectPayload.put("layerId", "event.feature.layer.id");
+                       vectorLayer.events.register(this, "featureselected", selectPayload);
+
+                       HashMap<String, String> unselectPayload = new HashMap<String, String>();
+                       unselectPayload.put("featureId", "event.feature.id");
+                       unselectPayload.put("geometry", "event.feature.geometry");
+                       unselectPayload.put("layerId", "event.feature.layer.id");
+                       vectorLayer.events.register(this, "featureunselected",
+                                       unselectPayload);
+                       SelectFeatureControl mfc = new SelectFeatureControl(vectorLayer, 0);
+                       // mfc.events.register(this, SelectFeatureControl.EVENT_HIGHLIGHTED,
+                       // unselectPayload);
+                       // mfc.events.register(this,
+                       // SelectFeatureControl.EVENT_UNHIGHLIGHTED,
+                       // unselectPayload);
+                       map.addControl(mfc);
+                       mfc.setMultiple(true);
+                       mfc.setRenderIntent("temporary");
+                       mfc.activate();
+
+                       FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = featureSource
+                                       .getFeatures();
+                       featureIterator = featureCollection.features();
+                       // TODO make this interruptible since it can easily block with huge
+                       // data
+                       while (featureIterator.hasNext()) {
+                               SimpleFeature feature = featureIterator.next();
+                               Geometry geom = (Geometry) feature.getDefaultGeometry();
+                               if (log.isTraceEnabled())
+                                       log.trace("Feature " + feature.getID() + ", "
+                                                       + geom.getClass().getName());
+                               // log.debug("  Geom: " + geom.getClass() + ", centroid="
+                               // + geom.getCentroid());
+                               if (geom instanceof Point) {
+                                       Point mp = (Point) geom;
+                                       PointGeometry pg = new PointGeometry(mp.getX(), mp.getY());
+                                       VectorFeature vf = new VectorFeature(pg);
+                                       vf.setObjAttr("id", feature.getID());
+                                       vectorLayer.addFeatures(vf);
+                               } else if (geom instanceof MultiPolygon) {
+                                       MultiPolygon mp = (MultiPolygon) geom;
+                                       List<PointGeometry> points = new ArrayList<PointGeometry>();
+                                       for (Coordinate coo : mp.getCoordinates()) {
+                                               // if (log.isDebugEnabled())
+                                               // log.debug(" " + coo.x + "," + coo.y);
+                                               points.add(new PointGeometry(coo.x, coo.y));
+                                       }
+                                       VectorFeature vf = new VectorFeature(
+                                                       new LineStringGeometry(
+                                                                       points.toArray(new PointGeometry[points
+                                                                                       .size()])));
+                                       vectorLayer.addFeatures(vf);
+                               }
+                       }
+                       map.addLayer(vectorLayer);
+               } catch (IOException e) {
+                       log.error("Cannot add layer " + featureSource.getName(), e);
+               } finally {
+                       GeoToolsUtils.closeQuietly(featureIterator);
+               }
+
+       }
+}