Improve JCR and GIS
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 6 Mar 2011 11:17:56 +0000 (11:17 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 6 Mar 2011 11:17:56 +0000 (11:17 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@4272 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

35 files changed:
eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/ArgeoUiPlugin.java
eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/TreeParent.java
gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/MANIFEST.MF
gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/IdentifiedVectorFeature.java [new file with mode: 0644]
gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/MapContextAdapter.java
gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapControlCreator.java
gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/BingLayer.java [new file with mode: 0644]
gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/GoogleLayer.java [new file with mode: 0644]
gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/JSON.java [new file with mode: 0644]
gis/plugins/org.argeo.gis.ui/META-INF/MANIFEST.MF
gis/plugins/org.argeo.gis.ui/META-INF/spring/commands.xml
gis/plugins/org.argeo.gis.ui/META-INF/spring/geojcr.xml [new file with mode: 0644]
gis/plugins/org.argeo.gis.ui/META-INF/spring/osgi.xml
gis/plugins/org.argeo.gis.ui/META-INF/spring/views.xml
gis/plugins/org.argeo.gis.ui/plugin.xml
gis/plugins/org.argeo.gis.ui/pom.xml
gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddFeatureSources.java [new file with mode: 0644]
gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/FeatureSourcesView.java [new file with mode: 0644]
gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/LayersView.java
gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/MapsView.java [new file with mode: 0644]
gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsConstants.java [new file with mode: 0644]
gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsUtils.java
gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrIndex.java
gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrMapper.java [new file with mode: 0644]
gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrUtils.java
gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/SimpleGeoJcrMapper.java [new file with mode: 0644]
gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/jts/jcr/JtsJcrUtils.java [new file with mode: 0644]
security/plugins/org.argeo.security.ui.application/plugin.xml
security/plugins/org.argeo.security.ui.application/pom.xml
security/plugins/org.argeo.security.ui.rap/pom.xml
server/modules/org.argeo.server.osgi.webapp/META-INF/MANIFEST.MF
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java
server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd

index 1561282b67a4fc679293e7d948daef4f15a6eef2..73fef7812c5ef1fceb5849014a1494daf89eba5a 100644 (file)
 
 package org.argeo.eclipse.ui;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.core.runtime.ILogListener;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.Bundle;
@@ -24,13 +28,15 @@ import org.osgi.framework.BundleContext;
 /**
  * The activator class controls the plug-in life cycle
  */
-public class ArgeoUiPlugin extends AbstractUIPlugin {
+public class ArgeoUiPlugin extends AbstractUIPlugin implements ILogListener {
 
        // The plug-in ID
        public static final String PLUGIN_ID = "org.argeo.eclipse.ui";
 
        private final static String SPRING_OSGI_EXTENDER = "org.springframework.osgi.extender";
 
+       private final static Log log = LogFactory.getLog(ArgeoUiPlugin.class);
+
        // The shared instance
        private static ArgeoUiPlugin plugin;
 
@@ -54,12 +60,16 @@ public class ArgeoUiPlugin extends AbstractUIPlugin {
                plugin = this;
                bundleContext = context;
 
+               Platform.addLogListener(this);
+               log.debug("Eclipse logging now directed to standard logging");
+
                // Make sure that the Spring OSGi extender is started
                Bundle osgiExtBundle = Platform.getBundle(SPRING_OSGI_EXTENDER);
                if (osgiExtBundle != null)
                        osgiExtBundle.start();
                else
-                       throw new Exception("Spring OSGi Extender not found");
+                       log.error("Spring OSGi Extender not found");
+
        }
 
        /*
@@ -70,6 +80,9 @@ public class ArgeoUiPlugin extends AbstractUIPlugin {
         * )
         */
        public void stop(BundleContext context) throws Exception {
+               Platform.removeLogListener(this);
+               log.debug("Eclipse logging not directed anymore to standard logging");
+
                plugin = null;
                super.stop(context);
        }
@@ -87,4 +100,19 @@ public class ArgeoUiPlugin extends AbstractUIPlugin {
                return bundleContext;
        }
 
+       public void logging(IStatus status, String plugin) {
+               Log pluginLog = LogFactory.getLog(plugin);
+               Integer severity = status.getSeverity();
+               if (severity == IStatus.ERROR)
+                       pluginLog.error(status.getMessage(), status.getException());
+               else if (severity == IStatus.WARNING)
+                       pluginLog.warn(status.getMessage(), status.getException());
+               else if (severity == IStatus.INFO)
+                       pluginLog.info(status.getMessage(), status.getException());
+               else if (severity == IStatus.CANCEL)
+                       if (pluginLog.isDebugEnabled())
+                               pluginLog.debug(status.getMessage(), status.getException());
+
+       }
+
 }
index 4b6ec53e1f0ab5ab426a3d5eacc306576b7d5c32..8989d69ad744c8af5b8f63c435f99637be524b53 100644 (file)
@@ -20,25 +20,27 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class TreeParent extends TreeObject {
-       private List<TreeParent> children;
+       private List<Object> children;
 
        private boolean loaded;
 
        public TreeParent(String name) {
                super(name);
-               children = new ArrayList<TreeParent>();
+               children = new ArrayList<Object>();
                loaded = false;
        }
 
-       public synchronized void addChild(TreeParent child) {
+       public synchronized void addChild(Object child) {
                loaded = true;
                children.add(child);
-               child.setParent(this);
+               if (child instanceof TreeParent)
+                       ((TreeParent) child).setParent(this);
        }
 
-       public synchronized void removeChild(TreeParent child) {
+       public synchronized void removeChild(Object child) {
                children.remove(child);
-               child.setParent(null);
+               if (child instanceof TreeParent)
+                       ((TreeParent) child).setParent(null);
        }
 
        public synchronized void clearChildren() {
@@ -46,17 +48,17 @@ public class TreeParent extends TreeObject {
                children.clear();
        }
 
-       public synchronized TreeParent[] getChildren() {
-               return children.toArray(new TreeParent[children.size()]);
+       public synchronized Object[] getChildren() {
+               return children.toArray(new Object[children.size()]);
        }
 
        public synchronized boolean hasChildren() {
                return children.size() > 0;
        }
 
-       public TreeParent getChildByName(String name) {
-               for (TreeParent child : children) {
-                       if (child.getName().equals(name))
+       public Object getChildByName(String name) {
+               for (Object child : children) {
+                       if (child.toString().equals(name))
                                return child;
                }
                return null;
index 21c08dc92a1e693144151249ab9e282f27860087..bc9ca2689aa606e3a208425164db66de3f258bd1 100644 (file)
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: Rap
 Bundle-SymbolicName: org.argeo.gis.ui.rap.openlayers;singleton:=true
-Bundle-Version: 1.0.0.qualifier
+Bundle-Version: 0.2.3.SNAPSHOT
 Bundle-Activator: org.argeo.gis.ui.rap.openlayers.GisOpenlayersPlugin
 Bundle-Vendor: Argeo
 Require-Bundle: org.eclipse.rap.ui,
@@ -13,6 +13,7 @@ Bundle-ActivationPolicy: lazy
 Import-Package: com.vividsolutions.jts.geom;version="1.10.0",
  org.apache.commons.logging;version="1.1.1",
  org.argeo.eclipse.spring,
+ org.argeo.geotools,
  org.argeo.gis.ui,
  org.argeo.gis.ui.editors,
  org.geotools.data,
@@ -22,6 +23,8 @@ Import-Package: com.vividsolutions.jts.geom;version="1.10.0",
  org.opengis.feature,
  org.opengis.feature.simple,
  org.opengis.feature.type,
+ org.opengis.filter,
+ org.opengis.filter.identity,
  org.polymap.openlayers.rap.widget,
  org.polymap.openlayers.rap.widget.base,
  org.polymap.openlayers.rap.widget.base_types,
diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/IdentifiedVectorFeature.java b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/IdentifiedVectorFeature.java
new file mode 100644 (file)
index 0000000..3c201e9
--- /dev/null
@@ -0,0 +1,16 @@
+package org.argeo.gis.ui.rap.openlayers;
+
+import org.polymap.openlayers.rap.widget.features.Feature;
+import org.polymap.openlayers.rap.widget.geometry.Geometry;
+
+public class IdentifiedVectorFeature extends Feature {
+
+       public IdentifiedVectorFeature(Geometry point, String id) {
+               _create(point.getJSObjRef(), id);
+       }
+
+       private void _create(String js_name, String attrs) {
+               super.create("new OpenLayers.Feature.Vector(" + js_name + "," + attrs
+                               + "                             );");
+       }
+}
index e6d34ef1dcae64cc77210f44b3398d5b1cf56129..8adf05799890e827f321ab917a8f426be9d38d70 100644 (file)
@@ -2,11 +2,19 @@ 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.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.geotools.GeoToolsUtils;
+import org.argeo.gis.ui.rap.openlayers.custom.JSON;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
 import org.geotools.data.FeatureSource;
 import org.geotools.feature.FeatureCollection;
 import org.geotools.feature.FeatureIterator;
@@ -15,9 +23,15 @@ import org.geotools.map.event.MapLayerListEvent;
 import org.geotools.map.event.MapLayerListListener;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.filter.identity.FeatureId;
 import org.polymap.openlayers.rap.widget.base.OpenLayersEventListener;
 import org.polymap.openlayers.rap.widget.base.OpenLayersObject;
+import org.polymap.openlayers.rap.widget.base_types.Bounds;
 import org.polymap.openlayers.rap.widget.base_types.OpenLayersMap;
+import org.polymap.openlayers.rap.widget.controls.EditingToolbarControl;
+import org.polymap.openlayers.rap.widget.controls.SelectFeatureControl;
+import org.polymap.openlayers.rap.widget.controls.SnappingControl;
 import org.polymap.openlayers.rap.widget.features.VectorFeature;
 import org.polymap.openlayers.rap.widget.geometry.LineStringGeometry;
 import org.polymap.openlayers.rap.widget.geometry.PointGeometry;
@@ -26,26 +40,162 @@ 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 MapContextAdapter implements MapLayerListListener,
-               OpenLayersEventListener {
+               OpenLayersEventListener, MouseListener {
        private final static Log log = LogFactory.getLog(MapContextAdapter.class);
 
        private final MapContext mapContext;
-       private final OpenLayersMap openLayersMap;
+       private final OpenLayersMap map;
+
+       // edit
+       private VectorLayer edit_layer;
+       private EditingToolbarControl edit_toolbar;
+       private VectorLayer selectable_boxes_layer;
+
+       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 MapContextAdapter(MapContext mapContext, OpenLayersMap openLayersMap) {
                this.mapContext = mapContext;
-               this.openLayersMap = openLayersMap;
+               this.map = openLayersMap;
 
                mapContext.addMapLayerListListener(this);
 
                HashMap<String, String> payloadMap = new HashMap<String, String>();
                payloadMap.put("layername", "event.layer.name");
-               this.openLayersMap.events.register(this, "changebaselayer", payloadMap);
+               this.map.events.register(this, "changebaselayer", payloadMap);
                payloadMap.put("property", "event.property");
                payloadMap.put("visibility", "event.layer.visibility");
-               this.openLayersMap.events.register(this, "changelayer", payloadMap);
+               this.map.events.register(this, "changelayer", payloadMap);
+
+               // edit
+               HashMap<String, String> editPayload = new HashMap<String, String>();
+               editPayload.put("layername", "event.layer.name");
+               editPayload.put("x", "event.xy.x");
+               editPayload.put("y", "event.xy.y");
+               edit_layer = new VectorLayer("edit layer");
+               edit_layer.events.register(this, "beforefeatureadded", null);
+               edit_layer.events.register(this, "afterfeatureadded", editPayload);
+               this.map.addLayer(edit_layer);
+               edit_layer.setVisibility(false);
+
+               // add vector layer with some boxes to demonstrate the modify feature
+               // feature
+               // selectPayload.put("id", "feature.id");
+               // selectPayload.put("lon", "feature.lonlat.lon");
+               // selectPayload.put("lat", "feature.lonlat.lon");
+               selectable_boxes_layer = new VectorLayer("selectable boxes");
+               HashMap<String, String> selectPayload = new HashMap<String, String>();
+               selectPayload.put("features", selectable_boxes_layer.getJSObjRef()
+                               + ".selectedFeatures[0].id");
+               selectPayload.put("id", "event.feature.id");
+               selectPayload.put("fid", "event.feature.fid");
+               selectPayload.put("geometry", "event.feature.geometry");
+               selectPayload.put("bounds", "event.feature.bounds");
+               selectPayload.put("lonlat", "event.feature.lonlat");
+               selectable_boxes_layer.events.register(this, "featureselected",
+                               selectPayload);
+               // selectable_boxes_layer.events.register(this, "featureunselected",
+               // selectPayload);
+               // selectable_boxes_layer.events.register(this,
+               // SelectFeatureControl.EVENT_HIGHLIGHTED, selectPayload);
+               // selectable_boxes_layer.events.register(this,
+               // SelectFeatureControl.EVENT_SELECTED, null);
+               // selectable_boxes_layer.events.register(this, "featuremodified",
+               // null);
+               map.addLayer(selectable_boxes_layer);
+               VectorFeature vector_feature = new VectorFeature(new Bounds(
+                               -1952081.800054420018569, 1118889.974857959896326,
+                               7124447.410769510082901, 5465442.183322750031948).toGeometry());
+               selectable_boxes_layer.addFeatures(vector_feature);
+               selectable_boxes_layer.setVisibility(false);
+
+               SelectFeatureControl mfc = new SelectFeatureControl(
+                               selectable_boxes_layer, 0);
+               map.addControl(mfc);
+               // mfc.setHighlightOnly(true);
+               mfc.setRenderIntent("temporary");
+               mfc.activate();
+
+               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);
+       }
+
+       /*
+        * OPENLAYERS MAP
+        */
+
+       public void process_event(OpenLayersObject source, String eventName,
+                       HashMap<String, String> payload) {
+               if (log.isDebugEnabled())
+                       log.debug("openlayers event from " + source);
+               if (eventName.equals("changebaselayer")) {
+                       if (log.isDebugEnabled())
+                               log.debug("client changed baselayer to '"
+                                               + payload.get("layername") + "' "
+                                               + payload.get("property"));
+               } else if (eventName.equals("changelayer")) {
+                       if (log.isDebugEnabled())
+                               log.debug("client changed layer '" + payload.get("layername")
+                                               + "' " + payload.get("property") + "' "
+                                               + payload.get("visibility"));
+                       if (payload.get("property").equals("visibility")) {
+                               Boolean visible = payload.get("visibility").equals("true");
+                               if (payload.get("layername").equals(edit_layer.getName())) {
+                                       if (visible) {
+                                               // adding edit control for the vector layer created
+                                               // above
+                                               edit_toolbar = new EditingToolbarControl(edit_layer);
+                                               map.addControl(edit_toolbar);
+                                               VectorLayer[] snapping_layers = { edit_layer,
+                                                               selectable_boxes_layer };
+                                               SnappingControl snap_ctrl = new SnappingControl(
+                                                               edit_layer, snapping_layers, false);
+                                               snap_ctrl.activate();
+                                               map.addControl(snap_ctrl);
+
+                                       } else {
+                                               edit_toolbar.deactivate();
+                                               map.removeControl(edit_toolbar);
+                                       }
+                               }
+                       }
+               } else 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);
+                       VectorLayer layer = (VectorLayer) source;
+                       log.debug(layer.getJSObjRef());
+
+                       String layerId = payload.get("layerId");
+                       String featureId = payload.get("featureId");
+                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = featureSources
+                                       .get(layerId);
+                       SimpleFeature feature = GeoToolsUtils.querySingleFeature(
+                                       featureSource, featureId);
+                       log.debug("Geotools Feature id : " + feature.getID());
+               } else if (log.isDebugEnabled())
+                       log.debug("unknown event " + eventName + " : " + payload);
+
        }
 
        /*
@@ -57,25 +207,56 @@ public class MapContextAdapter implements MapLayerListListener,
                if (log.isDebugEnabled())
                        log.debug("Map context layer added " + event);
 
+               FeatureIterator<SimpleFeature> featureIterator = null;
                try {
                        FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) event
                                        .getLayer().getFeatureSource();
 
-                       VectorLayer vectorLayer = new VectorLayer(featureSource.getName()
-                                       .toString());
+                       String layerName = featureSource.getName().toString();
+                       String layerId = layerName;
+                       VectorLayer vectorLayer = new VectorLayer(layerName);
+                       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);
+                       SelectFeatureControl mfc = new SelectFeatureControl(vectorLayer, 0);
+                       map.addControl(mfc);
+                       mfc.setRenderIntent("temporary");
+                       mfc.activate();
+
                        FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = featureSource
                                        .getFeatures();
-                       FeatureIterator<SimpleFeature> fit = featureCollection.features();
-                       while (fit.hasNext()) {
-                               SimpleFeature feature = fit.next();
+                       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();
-                               log.debug("Feature " + feature.getID());
-//                             log.debug("  Geom: " + geom.getClass() + ", centroid="
-//                                             + geom.getCentroid());
-                               if (geom instanceof MultiPolygon) {
+                               if (log.isDebugEnabled())
+                                       log.debug("Feature " + feature.getID() + ", "
+                                                       + feature.getClass().getName());
+                               // log.debug("  Geom: " + geom.getClass() + ", centroid="
+                               // + geom.getCentroid());
+                               if (geom instanceof Point) {
+                                       Point mp = (Point) geom;
+                                       if (log.isDebugEnabled())
+                                               log.debug(" " + mp.getX() + "," + mp.getY());
+                                       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(
@@ -85,9 +266,11 @@ public class MapContextAdapter implements MapLayerListListener,
                                        vectorLayer.addFeatures(vf);
                                }
                        }
-                       openLayersMap.addLayer(vectorLayer);
+                       map.addLayer(vectorLayer);
                } catch (IOException e) {
                        log.error("Cannot add layer " + event.getLayer(), e);
+               } finally {
+                       GeoToolsUtils.closeQuietly(featureIterator);
                }
        }
 
@@ -107,36 +290,21 @@ public class MapContextAdapter implements MapLayerListListener,
        }
 
        /*
-        * OPENLAYERS MAP
+        * MOUSE LISTENER
         */
-
-       public void process_event(OpenLayersObject source, String eventName,
-                       HashMap<String, String> payload) {
+       public void mouseDoubleClick(MouseEvent e) {
                if (log.isDebugEnabled())
-                       log.debug("openlayers event from" + source);
-               if (eventName.equals("changebaselayer")) {
-                       if (log.isDebugEnabled())
-                               log.debug("client changed baselayer to '"
-                                               + payload.get("layername") + "' "
-                                               + payload.get("property"));
-               } else if (eventName.equals("changelayer")) {
-                       if (log.isDebugEnabled())
-                               log.debug("client changed layer '" + payload.get("layername")
-                                               + "' " + payload.get("property") + "' "
-                                               + payload.get("visibility"));
-                       if (payload.get("property").equals("visibility")) {
-                               Boolean visible = payload.get("visibility").equals("true");
-                               VectorLayer edit_layer = new VectorLayer("edit layer");
-                               if (payload.get("layername").equals(edit_layer.getName())) {
-                                       if (visible) {
+                       log.debug("Mouse double click " + e);
+       }
 
-                                       } else {
-                                       }
-                               }
-                       }
-               } else if (log.isDebugEnabled())
-                       log.debug("unknown event " + eventName);
+       public void mouseDown(MouseEvent e) {
+               if (log.isDebugEnabled())
+                       log.debug("Mouse down " + e);
+       }
 
+       public void mouseUp(MouseEvent e) {
+               if (log.isDebugEnabled())
+                       log.debug("Mouse up " + e);
        }
 
 }
index f3972a9f938ddd9d61ba857233e9bd1d59597692..c38a7f5b9d7f4396b339ff94dba22dcf22624eba 100644 (file)
@@ -2,14 +2,19 @@ package org.argeo.gis.ui.rap.openlayers;
 
 import org.argeo.gis.ui.MapContextProvider;
 import org.argeo.gis.ui.MapControlCreator;
+import org.argeo.gis.ui.rap.openlayers.custom.BingLayer;
+import org.argeo.gis.ui.rap.openlayers.custom.GoogleLayer;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Composite;
 import org.polymap.openlayers.rap.widget.OpenLayersWidget;
 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.MouseDefaultsControl;
+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.layers.OSMLayer;
@@ -26,25 +31,36 @@ public class OpenLayersMapControlCreator implements MapControlCreator {
                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());
-               map.addControl(new MouseDefaultsControl());
+               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");
+               // WMSLayer baseLayer = new WMSLayer("argeo_dev",
+               // "https://dev.argeo.org/geoserver/wms?",
+               // "naturalearth:10m_admin_0_countries");
 
-               OSMLayer baseLayer = new OSMLayer("OSM",
+               OSMLayer osmLayer = new OSMLayer("OSM",
                                "http://tile.openstreetmap.org/${z}/${x}/${y}.png", 19);
-               map.addLayer(baseLayer);
+               map.addLayer(osmLayer);
+
+               map.addControl(new OverviewMapControl());
+
+               // map.addLayer(new BingLayer("Bing Aerial", BingLayer.AERIAL));
 
                MapContextAdapter mapContextAdapter = new MapContextAdapter(
                                mapContextProvider.getMapContext(), map);
                // FIXME: find a better way to register it
                openLayersWidget.setData(mapContextAdapter);
+               // openLayersWidget.addMouseListener(mapContextAdapter);
                return openLayersWidget;
        }
 
diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/BingLayer.java b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/BingLayer.java
new file mode 100644 (file)
index 0000000..29c4e30
--- /dev/null
@@ -0,0 +1,16 @@
+package org.argeo.gis.ui.rap.openlayers.custom;
+
+import org.polymap.openlayers.rap.widget.layers.Layer;
+
+public class BingLayer extends Layer {
+       public final static String ROAD = "Road";
+       public final static String AERIAL = "Aerial";
+       public final static String AERIAL_WITH_LABEL = "AerialWithLabels";
+
+       public BingLayer(String name, String apiKey, String type) {
+               super.setName(name);
+               super.create("new OpenLayers.Layer.Bing({name:'" + name + "', key:'"
+                               + apiKey + "' ,type:'" + type + "'})");
+
+       }
+}
diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/GoogleLayer.java b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/GoogleLayer.java
new file mode 100644 (file)
index 0000000..e78bd51
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.gis.ui.rap.openlayers.custom;
+
+import org.polymap.openlayers.rap.widget.layers.Layer;
+
+public class GoogleLayer extends Layer {
+       public GoogleLayer(String name) {
+               super.setName(name);
+               super.create("new OpenLayers.Layer.Google( '" + name
+                               + "',{'sphericalMercator': true, numZoomLevels: 20})");
+
+       }
+}
diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/JSON.java b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/JSON.java
new file mode 100644 (file)
index 0000000..c4b38d7
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.gis.ui.rap.openlayers.custom;
+
+import org.polymap.openlayers.rap.widget.base.OpenLayersObject;
+
+public class JSON extends OpenLayersObject {
+
+       public JSON() {
+               super.create("new OpenLayers.Format.JSON();");
+               setObjAttr("pretty", true);
+       }
+
+}
index 24fb318dc555b9c431dd53e6aa83579766c8234c..7ca7f527d40b23f2f79eec593ee7982a128b8953 100644 (file)
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: Ui
 Bundle-SymbolicName: org.argeo.gis.ui;singleton:=true
-Bundle-Version: 1.0.0.qualifier
+Bundle-Version: 0.2.3.SNAPSHOT
 Bundle-Activator: org.argeo.gis.ui.GisUiPlugin
 Bundle-Vendor: Argeo
 Require-Bundle: org.eclipse.ui;resolution:=optional,
@@ -10,11 +10,17 @@ Require-Bundle: org.eclipse.ui;resolution:=optional,
  org.eclipse.core.runtime
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Bundle-ActivationPolicy: lazy
-Import-Package: org.apache.commons.logging;version="1.1.1",
+Import-Package: javax.jcr;version="2.0.0",
+ javax.jcr.nodetype;version="2.0.0",
+ org.apache.commons.logging;version="1.1.1",
  org.argeo,
  org.argeo.eclipse.spring,
  org.argeo.eclipse.ui,
  org.argeo.eclipse.ui.dialogs,
+ org.argeo.eclipse.ui.jcr,
+ org.argeo.geotools.jcr,
+ org.argeo.jcr,
+ org.argeo.jcr.gis,
  org.geotools.data,
  org.geotools.map,
  org.geotools.map.event,
index 5a6cc7fcb55e0ddeeeb3ec19f698ecf3c319357a..52746358de38a03d30d30cda68d6beef75435faa 100644 (file)
@@ -4,8 +4,11 @@
        xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd">
 
-       <bean id="newMap"
-               class="org.argeo.gis.ui.commands.NewMap"
+       <bean id="newMap" class="org.argeo.gis.ui.commands.NewMap" scope="prototype">
+       </bean>
+       
+       <bean id="addFeatureSources" class="org.argeo.gis.ui.commands.AddFeatureSources"
                scope="prototype">
+               <property name="geoJcrMapper" ref="geoJcrMapper" />
        </bean>
 </beans>
diff --git a/gis/plugins/org.argeo.gis.ui/META-INF/spring/geojcr.xml b/gis/plugins/org.argeo.gis.ui/META-INF/spring/geojcr.xml
new file mode 100644 (file)
index 0000000..8b194c0
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+       <bean id="geoJcrMapper" class="org.argeo.geotools.jcr.SimpleGeoJcrMapper">
+               <property name="session" ref="jcrSession"/>
+       </bean>
+</beans>
index faf565dddf19e5487ef3878b8c31447c48f8d67d..711b80acf296180687bfb61701e569b8ea8b4a33 100644 (file)
@@ -7,6 +7,13 @@
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
 \r
        <reference id="mapControlCreator" interface="org.argeo.gis.ui.MapControlCreator" />\r
-       <list id="dataStores" interface="org.geotools.data.DataStore" cardinality="0..N"/>\r
+       <list id="dataStores" interface="org.geotools.data.DataStore"\r
+               cardinality="0..N">\r
+               <listener ref="geoJcrMapper" bind-method="register"\r
+                       unbind-method="unregister" />\r
+       </list>\r
+\r
+       <reference id="jcrSession" interface="javax.jcr.Session"\r
+               filter="(argeo.jcr.repository.alias=connect_mideast)" />\r
 \r
 </beans:beans>
\ No newline at end of file
index fd995a13b3fc46485be03462cb02984139086021..c75bce9b7189197c71cedb542e56eebe2f7b69f2 100644 (file)
@@ -9,9 +9,10 @@
                scope="prototype">
        </bean>
 
-       <bean id="dataStoresView" class="org.argeo.gis.ui.views.DataStoresView"
+       <bean id="featureSourcesView" class="org.argeo.gis.ui.views.FeatureSourcesView"
                scope="prototype">
-               <property name="dataStores" ref="dataStores" />
+               <property name="session" ref="jcrSession"/>
+               <property name="geoJcrMapper" ref="geoJcrMapper"/>
        </bean>
 
 </beans>
index 2a712424e110046e0dc1296590023b4a7e3443aa..a7d5ed8f780cdcedbf1fc59156fba0f0f4a250d7 100644 (file)
             id="org.argeo.gis.ui.layersView">
       </view>
       <view
-            name="Data Stores"
+            name="GIS Data"
             icon="icons/gis_add_data.gif"
             class="org.argeo.eclipse.spring.SpringExtensionFactory"
-            id="org.argeo.gis.ui.dataStoresView">
+            id="org.argeo.gis.ui.featureSourcesView">
       </view>
    </extension>
    <extension
             defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
             id="org.argeo.gis.ui.newMap"
             name="New Map">
+       </command>
+               <command
+            defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+            id="org.argeo.gis.ui.addFeatureSources"
+            name="Add Feature Sources">
        </command>
     </extension>
        <extension
          point="org.eclipse.ui.menus">
-        <!-- Queries --> 
                <menuContribution
                 locationURI="toolbar:org.argeo.gis.ui.layersView">
              <command
                   style="push"
                   tooltip="New Map">
             </command>
+             <command
+                  commandId="org.argeo.gis.ui.addFeatureSources"
+                  disabledIcon="icons/sample.gif"
+                  icon="icons/earth_edit.gif"
+                  label="Add Feature Sources"
+                  style="push"
+                  tooltip="Add Feature Sources">
+            </command>
         </menuContribution>
        </extension>
    <extension
index b2d9182dc0f45c02e01d63f1d4dea177199fe0fa..918f911f475b94ec24646fb87d0b524d65467385 100644 (file)
                        <artifactId>org.argeo.eclipse.ui</artifactId>
                        <version>0.2.3-SNAPSHOT</version>
                </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.eclipse</groupId>
+                       <artifactId>org.argeo.eclipse.ui.jcr</artifactId>
+                       <version>0.2.3-SNAPSHOT</version>
+               </dependency>
 
                <!-- RCP only dependency, needed at compile time -->
                <dependency>
diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddFeatureSources.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddFeatureSources.java
new file mode 100644 (file)
index 0000000..aeb962a
--- /dev/null
@@ -0,0 +1,181 @@
+package org.argeo.gis.ui.commands;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.AbstractTreeContentProvider;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.geotools.jcr.GeoJcrMapper;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.geotools.data.FeatureSource;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+public class AddFeatureSources extends AbstractHandler {
+       private GeoJcrMapper geoJcrMapper;
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+               try {
+                       FeatureSourceChooserDialog dialog = new FeatureSourceChooserDialog(
+                                       HandlerUtil.getActiveShell(event));
+                       if (dialog.open() == Dialog.OK) {
+                               Map<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>> featureSources = dialog
+                                               .getFeatureSources();
+                               for (String alias : featureSources.keySet()) {
+                                       for (FeatureSource<SimpleFeatureType, SimpleFeature> fs : featureSources
+                                                       .get(alias)) {
+                                               Node fsNode = geoJcrMapper.getNode(alias, fs);
+                                               try {
+                                                       fsNode.getSession().save();
+                                               } catch (RepositoryException e) {
+                                                       throw new ArgeoException("Cannot save " + fsNode, e);
+                                               }
+                                       }
+                               }
+                       }
+                       return null;
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+                       return null;
+               }
+       }
+
+       public void setGeoJcrMapper(GeoJcrMapper geoJcrMapper) {
+               this.geoJcrMapper = geoJcrMapper;
+       }
+
+       class FeatureSourceChooserDialog extends TitleAreaDialog {
+               private TreeViewer viewer;
+               private Map<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>> featureSources = new HashMap<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>>();
+
+               public FeatureSourceChooserDialog(Shell parentShell) {
+                       super(parentShell);
+               }
+
+               protected Point getInitialSize() {
+                       return new Point(300, 400);
+               }
+
+               protected Control createDialogArea(Composite parent) {
+                       setTitle("Feature Source");
+                       setMessage("Select or or many feature sources to register");
+                       Composite dialogarea = (Composite) super.createDialogArea(parent);
+                       Composite composite = new Composite(dialogarea, SWT.NONE);
+                       composite.setLayout(new GridLayout(1, false));
+                       composite
+                                       .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+                       viewer = new TreeViewer(composite);
+                       viewer.getTree().setLayoutData(
+                                       new GridData(SWT.FILL, SWT.FILL, true, true));
+                       viewer.setContentProvider(new DataStoreContentProvider());
+                       viewer.setLabelProvider(new DataStoreLabelProvider());
+                       viewer.setInput(geoJcrMapper.getPossibleFeatureSources());
+                       parent.pack();
+                       return composite;
+               }
+
+               @SuppressWarnings("unchecked")
+               @Override
+               protected void okPressed() {
+                       Iterator<Object> it = ((IStructuredSelection) viewer.getSelection())
+                                       .iterator();
+                       while (it.hasNext()) {
+                               Object obj = it.next();
+                               if (obj instanceof FeatureSourceNode) {
+                                       FeatureSourceNode fsn = (FeatureSourceNode) obj;
+                                       String alias = fsn.getDataStoreAlias();
+                                       if (!featureSources.containsKey(alias))
+                                               featureSources
+                                                               .put(alias,
+                                                                               new ArrayList<FeatureSource<SimpleFeatureType, SimpleFeature>>());
+                                       featureSources.get(alias).add(fsn.getFeatureSource());
+                               } else {
+                                       // data store node
+                                       String alias = obj.toString();
+                                       featureSources.put(alias, geoJcrMapper
+                                                       .getPossibleFeatureSources().get(alias));
+                               }
+                       }
+                       super.okPressed();
+               }
+
+               public Map<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>> getFeatureSources() {
+                       return featureSources;
+               }
+       }
+
+       private class DataStoreContentProvider extends AbstractTreeContentProvider {
+
+               @SuppressWarnings("unchecked")
+               public Object[] getElements(Object inputElement) {
+                       List<TreeParent> dataStoreNodes = new ArrayList<TreeParent>();
+                       Map<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>> featureSources = (Map<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>>) inputElement;
+                       for (String alias : featureSources.keySet()) {
+                               TreeParent dataStoreNode = new TreeParent(alias);
+                               for (FeatureSource<SimpleFeatureType, SimpleFeature> featureSource : featureSources
+                                               .get(alias)) {
+                                       dataStoreNode.addChild(new FeatureSourceNode(alias,
+                                                       featureSource));
+                               }
+                               dataStoreNodes.add(dataStoreNode);
+                       }
+                       return dataStoreNodes.toArray();
+               }
+
+       }
+
+       private class DataStoreLabelProvider extends LabelProvider {
+
+               @Override
+               public String getText(Object element) {
+                       return super.getText(element);
+               }
+
+       }
+
+       private class FeatureSourceNode extends TreeParent {
+               private final String dataStoreAlias;
+               private final FeatureSource<SimpleFeatureType, SimpleFeature> featureSource;
+
+               public FeatureSourceNode(String dataStoreAlias,
+                               FeatureSource<SimpleFeatureType, SimpleFeature> featureSource) {
+                       super(featureSource.getName().toString());
+                       this.dataStoreAlias = dataStoreAlias;
+                       this.featureSource = featureSource;
+               }
+
+               public String getDataStoreAlias() {
+                       return dataStoreAlias;
+               }
+
+               public FeatureSource<SimpleFeatureType, SimpleFeature> getFeatureSource() {
+                       return featureSource;
+               }
+
+       }
+
+}
diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/FeatureSourcesView.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/FeatureSourcesView.java
new file mode 100644 (file)
index 0000000..76ea5dd
--- /dev/null
@@ -0,0 +1,99 @@
+package org.argeo.gis.ui.views;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.jcr.SimpleNodeContentProvider;
+import org.argeo.geotools.jcr.GeoJcrMapper;
+import org.argeo.gis.ui.editors.DefaultMapEditor;
+import org.argeo.jcr.gis.GisTypes;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.part.ViewPart;
+import org.geotools.data.FeatureSource;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+public class FeatureSourcesView extends ViewPart implements
+               IDoubleClickListener {
+       public final static String ID = "org.argeo.gis.ui.featureSourcesView";
+
+       private String dataStoresBasePath = "/gis/dataStores";
+
+       private Session session;
+
+       private TreeViewer viewer;
+
+       private GeoJcrMapper geoJcrMapper;
+
+       @Override
+       public void createPartControl(Composite parent) {
+               viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+               String[] basePaths = { dataStoresBasePath };
+               viewer.setContentProvider(new SimpleNodeContentProvider(session,
+                               basePaths));
+               viewer.setLabelProvider(new MapsLabelProvider());
+               viewer.setInput(getViewSite());
+               viewer.addDoubleClickListener(this);
+       }
+
+       public void doubleClick(DoubleClickEvent event) {
+               if (!event.getSelection().isEmpty()) {
+                       Object obj = ((IStructuredSelection) event.getSelection())
+                                       .getFirstElement();
+                       if (obj instanceof Node) {
+                               Node node = (Node) obj;
+                               try {
+                                       if (!node.getPrimaryNodeType().isNodeType(
+                                                       GisTypes.GIS_FEATURE_SOURCE))
+                                               return;
+                               } catch (RepositoryException e) {
+                                       throw new ArgeoException("Cannot check type of " + node, e);
+                               }
+                               FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = geoJcrMapper
+                                               .getFeatureSource(node);
+                               IEditorPart ed = getSite().getWorkbenchWindow().getActivePage()
+                                               .getActiveEditor();
+                               if (ed instanceof DefaultMapEditor) {
+                                       ((DefaultMapEditor) ed).addLayer(featureSource);
+                               }
+                       }
+
+               }
+
+       }
+
+       public void setGeoJcrMapper(GeoJcrMapper geoJcrMapper) {
+               this.geoJcrMapper = geoJcrMapper;
+       }
+
+       @Override
+       public void setFocus() {
+               viewer.getTree().setFocus();
+       }
+
+       public void refresh() {
+               viewer.refresh();
+       }
+
+       public void setSession(Session session) {
+               this.session = session;
+       }
+
+       private class MapsLabelProvider extends LabelProvider {
+
+               @Override
+               public String getText(Object element) {
+                       return super.getText(element);
+               }
+
+       }
+}
index 56fb03fe1b11e6c00925331e25ed35de1048d9be..096f036579f3f4b5923bb87e03d4cc536cef16f0 100644 (file)
@@ -23,7 +23,7 @@ public class LayersView extends ViewPart implements MapLayerListListener {
 
        @Override
        public void createPartControl(Composite parent) {
-               viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+               viewer = new TreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
                viewer.setContentProvider(new MapContextContentProvider());
                viewer.setLabelProvider(new MapContextLabelProvider());
                viewer.setInput(getViewSite());
diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/MapsView.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/MapsView.java
new file mode 100644 (file)
index 0000000..b045340
--- /dev/null
@@ -0,0 +1,65 @@
+package org.argeo.gis.ui.views;
+
+import javax.jcr.Node;
+import javax.jcr.Session;
+
+import org.argeo.eclipse.ui.jcr.SimpleNodeContentProvider;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.ViewPart;
+
+public class MapsView extends ViewPart implements IDoubleClickListener {
+       public final static String ID = "org.argeo.gis.ui.mapsView";
+
+       private String mapsBasePath = "/gis/maps";
+
+       private Session session;
+
+       private TreeViewer viewer;
+
+       @Override
+       public void createPartControl(Composite parent) {
+               viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+               String[] basePaths = { mapsBasePath };
+               viewer.setContentProvider(new SimpleNodeContentProvider(session,
+                               basePaths));
+               viewer.setLabelProvider(new MapsLabelProvider());
+               viewer.setInput(getViewSite());
+               viewer.addDoubleClickListener(this);
+       }
+
+       public void doubleClick(DoubleClickEvent event) {
+               if (!event.getSelection().isEmpty()) {
+                       Object obj = ((IStructuredSelection) event.getSelection())
+                                       .getFirstElement();
+                       if (obj instanceof Node) {
+                               Node node = (Node) obj;
+                       }
+
+               }
+
+       }
+
+       @Override
+       public void setFocus() {
+               viewer.getTree().setFocus();
+       }
+
+       public void refresh() {
+               viewer.refresh();
+       }
+
+       private class MapsLabelProvider extends LabelProvider {
+
+               @Override
+               public String getText(Object element) {
+                       return super.getText(element);
+               }
+
+       }
+}
diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsConstants.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsConstants.java
new file mode 100644 (file)
index 0000000..060b803
--- /dev/null
@@ -0,0 +1,6 @@
+package org.argeo.geotools;
+
+public interface GeoToolsConstants {
+       public final static String ALIAS_KEY = "alias";
+       public final static String PUBLISHED_FEATURE_SOURCES_KEY = "publishedFeatureSources";
+}
index 88ab84995621b21abfdac286fab9fc32a4d70847..c154f4b97920d410874d32faa851c0487bf6df14 100644 (file)
@@ -1,18 +1,34 @@
 package org.argeo.geotools;
 
 import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.argeo.ArgeoException;
 import org.geotools.data.DataStore;
 import org.geotools.data.FeatureSource;
 import org.geotools.data.FeatureStore;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.filter.FilterFactoryImpl;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
 import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory2;
+import org.opengis.filter.identity.FeatureId;
 
 /** Utilities related to the GeoTools framework */
 public class GeoToolsUtils {
 
+       private final static Log log = LogFactory.getLog(GeoToolsUtils.class);
+
+       // TODO: use common factory finder?
+       private static FilterFactory2 filterFactory = new FilterFactoryImpl();
+
        /** Opens a read/write feature store */
        public static FeatureStore<SimpleFeatureType, SimpleFeature> getFeatureStore(
                        DataStore dataStore, Name name) {
@@ -45,4 +61,45 @@ public class GeoToolsUtils {
                        }
                }
        }
+
+       public static FilterFactory2 ff() {
+               return filterFactory;
+       }
+
+       public static SimpleFeature querySingleFeature(
+                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource,
+                       String featureId) {
+               Set<FeatureId> ids = new HashSet<FeatureId>();
+               ids.add(ff().featureId(featureId));
+               Filter filter = ff().id(ids);
+               FeatureIterator<SimpleFeature> it = null;
+               try {
+                       it = featureSource.getFeatures(filter).features();
+                       if (!it.hasNext())
+                               return null;
+                       else {
+                               SimpleFeature feature = it.next();
+                               if (it.hasNext())
+                                       log.warn("More than one feature for feature id "
+                                                       + featureId + " in feature source "
+                                                       + featureSource.getName());
+                               return feature;
+                       }
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot extract single feature "
+                                       + featureId + " from feature source "
+                                       + featureSource.getName(), e);
+               } finally {
+                       closeQuietly(it);
+               }
+       }
+
+       public static void closeQuietly(FeatureIterator<?> featureIterator) {
+               if (featureIterator != null)
+                       try {
+                               featureIterator.close();
+                       } catch (Exception e) {
+                               // silent
+                       }
+       }
 }
index e6afb943066585aef8cfe12c8fbe6795547bb4de..2f62c8bf78cb344fc3a091cd94713f1b3f89934e 100644 (file)
@@ -20,6 +20,7 @@ import org.argeo.geotools.GeoToolsUtils;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.jcr.gis.GisNames;
 import org.argeo.jcr.gis.GisTypes;
+import org.argeo.jts.jcr.JtsJcrUtils;
 import org.argeo.security.SystemExecutionService;
 import org.geotools.data.DataStore;
 import org.geotools.data.DefaultTransaction;
@@ -30,66 +31,52 @@ import org.geotools.feature.FeatureCollections;
 import org.geotools.feature.simple.SimpleFeatureBuilder;
 import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
 import org.geotools.filter.FilterFactoryImpl;
-import org.geotools.referencing.CRS;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
 import org.opengis.filter.FilterFactory2;
 import org.opengis.filter.identity.FeatureId;
-import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.operation.MathTransform;
 
-import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
 import com.vividsolutions.jts.geom.GeometryFactory;
 import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
 
 public class GeoJcrIndex implements EventListener {
-       public final static SimpleFeatureType JCR_POINT;
-
-       final static String JCR_POINT_NAME = "JCR_POINT";
+       final static String GEOJCR_INDEX = "GEOJCR_INDEX";
        // PostGIS convention
        final static String DEFAULT_GEOM_NAME = "the_geom";
 
        private final static Log log = LogFactory.getLog(GeoJcrIndex.class);
 
-       static {
+       public static SimpleFeatureType getWorkspaceGeoIndex(String workspaceName) {
                SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
                builder.setNamespaceURI(GisNames.GIS_NAMESPACE);
-               builder.setName(JCR_POINT_NAME);
+               builder.setName(workspaceName.toUpperCase() + "_" + GEOJCR_INDEX);
 
-               builder.setDefaultGeometry(DEFAULT_GEOM_NAME);
-               builder.add(DEFAULT_GEOM_NAME, Point.class);
+               builder.setDefaultGeometry(JcrUtils.normalize(GisNames.GIS_BBOX));
+               builder.add(JcrUtils.normalize(GisNames.GIS_BBOX), Polygon.class);
+               builder.add(JcrUtils.normalize(GisNames.GIS_CENTROID), Point.class);
 
                builder.add(JcrUtils.normalize(Property.JCR_UUID), String.class);
                builder.add(JcrUtils.normalize(Property.JCR_PATH), String.class);
                builder.add(JcrUtils.normalize(Property.JCR_PRIMARY_TYPE), String.class);
-               // mix:created
-               // builder.add(JcrUtils.normalize(Property.JCR_CREATED), Date.class);
-               // builder.add(JcrUtils.normalize(Property.JCR_CREATED_BY),
-               // String.class);
                // mix:lastModified
                builder.add(JcrUtils.normalize(Property.JCR_LAST_MODIFIED), Date.class);
                builder.add(JcrUtils.normalize(Property.JCR_LAST_MODIFIED_BY),
                                String.class);
 
-               JCR_POINT = builder.buildFeatureType();
+               return builder.buildFeatureType();
        }
 
        private DataStore dataStore;
-       private FeatureStore<SimpleFeatureType, SimpleFeature> pointsIndex;
        private Session session;
        private SystemExecutionService systemExecutionService;
 
        // TODO: use common factory finder?
        private FilterFactory2 ff = new FilterFactoryImpl();
 
-       // TODO: use finder?
-       private GeometryFactory geometryFactory = new GeometryFactory();
-
        public void init() {
-               GeoToolsUtils.createSchemaIfNeeded(dataStore, JCR_POINT);
-               pointsIndex = GeoToolsUtils.getFeatureStore(dataStore,
-                               JCR_POINT.getName());
 
                systemExecutionService.executeAsSystem(new Runnable() {
                        public void run() {
@@ -99,7 +86,7 @@ public class GeoJcrIndex implements EventListener {
                                                        .addEventListener(GeoJcrIndex.this,
                                                                        Event.NODE_ADDED | Event.NODE_REMOVED, "/",
                                                                        true, null,
-                                                                       new String[] { GisTypes.GIS_GEOMETRY },
+                                                                       new String[] { GisTypes.GIS_INDEXED },
                                                                        false);
                                } catch (RepositoryException e) {
                                        throw new ArgeoException("Cannot initialize GeoJcr index",
@@ -114,9 +101,15 @@ public class GeoJcrIndex implements EventListener {
        }
 
        public void onEvent(EventIterator events) {
-               FeatureCollection<SimpleFeatureType, SimpleFeature> pointsToAdd = FeatureCollections
+               SimpleFeatureType indexType = getWorkspaceGeoIndex(session
+                               .getWorkspace().getName());
+               GeoToolsUtils.createSchemaIfNeeded(dataStore, indexType);
+               FeatureStore<SimpleFeatureType, SimpleFeature> geoJcrIndex = GeoToolsUtils
+                               .getFeatureStore(dataStore, indexType.getName());
+
+               FeatureCollection<SimpleFeatureType, SimpleFeature> toAdd = FeatureCollections
                                .newCollection();
-               Set<FeatureId> pointsToRemove = new HashSet<FeatureId>();
+               Set<FeatureId> toRemove = new HashSet<FeatureId>();
                while (events.hasNext()) {
                        Event event = events.nextEvent();
                        try {
@@ -124,18 +117,14 @@ public class GeoJcrIndex implements EventListener {
                                if (Event.NODE_ADDED == eventType) {
                                        Node node = session.getNodeByIdentifier(event
                                                        .getIdentifier());
-                                       if (node.isNodeType(GisTypes.GIS_POINT)) {
-                                               Point point = nodeToPoint(node);
-                                               SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(
-                                                               JCR_POINT);
-                                               featureBuilder.set(DEFAULT_GEOM_NAME, point);
-                                               mapNodeToFeature(node, featureBuilder);
-                                               pointsToAdd.add(featureBuilder.buildFeature(node
-                                                               .getIdentifier()));
+                                       if (node.isNodeType(GisTypes.GIS_LOCATED)) {
+                                               SimpleFeature feature = mapNodeToFeature(node,
+                                                               indexType);
+                                               toAdd.add(feature);
                                        }
                                } else if (Event.NODE_REMOVED == eventType) {
                                        String id = event.getIdentifier();
-                                       pointsToRemove.add(ff.featureId(id));
+                                       toRemove.add(ff.featureId(id));
                                }
                        } catch (Exception e) {
                                log.error("Cannot process event " + event, e);
@@ -147,12 +136,12 @@ public class GeoJcrIndex implements EventListener {
                // but we will loose modifications on all nodes if one fails
                try {
                        Transaction transaction = new DefaultTransaction();
-                       pointsIndex.setTransaction(transaction);
+                       geoJcrIndex.setTransaction(transaction);
                        try {
                                // points
-                               pointsIndex.addFeatures(pointsToAdd);
-                               if (pointsToRemove.size() != 0)
-                                       pointsIndex.removeFeatures(ff.id(pointsToRemove));
+                               geoJcrIndex.addFeatures(toAdd);
+                               if (toRemove.size() != 0)
+                                       geoJcrIndex.removeFeatures(ff.id(toRemove));
                                transaction.commit();
                        } catch (Exception e) {
                                transaction.rollback();
@@ -167,55 +156,97 @@ public class GeoJcrIndex implements EventListener {
                }
        }
 
-       protected void mapNodeToFeature(Node node,
-                       SimpleFeatureBuilder featureBuilder) {
+       protected SimpleFeature mapNodeToFeature(Node node, SimpleFeatureType type) {
                try {
-                       featureBuilder.set(JcrUtils.normalize(Property.JCR_UUID),
+                       SimpleFeatureBuilder builder = new SimpleFeatureBuilder(type);
+
+                       Node locatedNode;
+                       if (node.isNodeType(GisTypes.GIS_LOCATED)) {
+                               locatedNode = node;
+                       } else if (node.isNodeType(GisTypes.GIS_INDEXED)) {
+                               locatedNode = findLocatedparent(node);
+                       } else {
+                               throw new ArgeoException("Unsupported node " + node);
+                       }
+
+                       // TODO: reproject to the feature store SRS
+                       Polygon bbox = (Polygon) JtsJcrUtils.readWkb(locatedNode
+                                       .getProperty(GisNames.GIS_BBOX));
+                       builder.set(JcrUtils.normalize(GisNames.GIS_BBOX), bbox);
+                       Polygon centroid = (Polygon) JtsJcrUtils.readWkb(locatedNode
+                                       .getProperty(GisNames.GIS_CENTROID));
+                       builder.set(JcrUtils.normalize(GisNames.GIS_CENTROID), centroid);
+
+                       builder.set(JcrUtils.normalize(Property.JCR_UUID),
                                        node.getIdentifier());
-                       featureBuilder.set(JcrUtils.normalize(Property.JCR_PATH),
-                                       node.getPath());
-                       featureBuilder.set(JcrUtils.normalize(Property.JCR_PRIMARY_TYPE),
-                                       node.getPrimaryNodeType().getName());
+                       builder.set(JcrUtils.normalize(Property.JCR_PATH), node.getPath());
+                       builder.set(JcrUtils.normalize(Property.JCR_PRIMARY_TYPE), node
+                                       .getPrimaryNodeType().getName());
                        if (node.hasProperty(Property.JCR_LAST_MODIFIED))
-                               featureBuilder.set(
-                                               JcrUtils.normalize(Property.JCR_LAST_MODIFIED), node
-                                                               .getProperty(Property.JCR_LAST_MODIFIED)
-                                                               .getDate().getTime());
+                               builder.set(JcrUtils.normalize(Property.JCR_LAST_MODIFIED),
+                                               node.getProperty(Property.JCR_LAST_MODIFIED).getDate()
+                                                               .getTime());
                        if (node.hasProperty(Property.JCR_LAST_MODIFIED_BY))
-                               featureBuilder
-                                               .set(JcrUtils.normalize(Property.JCR_LAST_MODIFIED_BY),
-                                                               node.getProperty(Property.JCR_LAST_MODIFIED_BY)
-                                                                               .getString());
+                               builder.set(JcrUtils.normalize(Property.JCR_LAST_MODIFIED_BY),
+                                               node.getProperty(Property.JCR_LAST_MODIFIED_BY)
+                                                               .getString());
+                       return builder.buildFeature(node.getIdentifier());
                } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot map " + node + " to "
-                                       + featureBuilder.getFeatureType(), e);
+                       throw new ArgeoException("Cannot map " + node + " to " + type, e);
                }
        }
 
-       /** Return the node as a point in the CRS of the related feature store. */
-       protected Point nodeToPoint(Node node) {
-               CoordinateReferenceSystem featureStoreCrs = pointsIndex.getSchema()
-                               .getCoordinateReferenceSystem();
-               DirectPosition nodePosition = GeoJcrUtils.nodeToPosition(node);
-               CoordinateReferenceSystem nodeCrs = nodePosition
-                               .getCoordinateReferenceSystem();
+       protected Node findLocatedparent(Node child) {
+               try {
+                       if (child.getParent().isNodeType(GisTypes.GIS_LOCATED))
+                               return child.getParent();
+                       else
+                               return findLocatedparent(child.getParent());
+               } catch (Exception e) {
+                       // also if child is root node
+                       throw new ArgeoException("Cannot find located parent", e);
+               }
+       }
 
+       /** Returns the node as a point in the CRS of the related feature store. */
+       protected Geometry reproject(CoordinateReferenceSystem crs,
+                       Geometry geometry, CoordinateReferenceSystem targetCrs) {
                // transform if not same CRS
-               DirectPosition targetPosition;
-               if (!featureStoreCrs.getIdentifiers().contains(nodeCrs.getName())) {
-                       MathTransform transform;
-                       try {
-                               transform = CRS.findMathTransform(nodeCrs, featureStoreCrs);
-                               targetPosition = transform.transform(nodePosition, null);
-                       } catch (Exception e) {
-                               throw new ArgeoException("Cannot transform from " + nodeCrs
-                                               + " to " + featureStoreCrs, e);
-                       }
+               // FIXME: there is certainly a more standard way to reproject
+               if (!targetCrs.getIdentifiers().contains(crs.getName())) {
+                       throw new ArgeoException("Reprojection not yet supported");
+                       // MathTransform transform;
+                       // try {
+                       // transform = CRS.findMathTransform(nodeCrs, featureStoreCrs);
+                       // if (geometry instanceof Point) {
+                       // Point point = (Point) geometry;
+                       // DirectPosition2D pos = new DirectPosition2D(nodeCrs,
+                       // point.getX(), point.getY());
+                       // DirectPosition targetPos = transform.transform(pos, null);
+                       // return geometryFactory.createPoint(new Coordinate(targetPos
+                       // .getCoordinate()[0], targetPos.getCoordinate()[1]));
+                       // } else if (geometry instanceof Polygon) {
+                       // Polygon polygon = (Polygon) geometry;
+                       // List<Coordinate> coordinates = new ArrayList<Coordinate>();
+                       // for (Coordinate coo : polygon.getExteriorRing()) {
+                       // DirectPosition pos = new DirectPosition2D(nodeCrs,
+                       // coo.x, coo.y);
+                       // DirectPosition targetPos = transform.transform(pos,
+                       // null);
+                       // // coordinates.add(o)
+                       // }
+                       // LinearRing ring = geometryFactory
+                       // .createLinearRing(coordinates
+                       // .toArray(new Coordinate[coordinates.size()]));
+                       // return geometryFactory.createPolygon(ring, null);
+                       // }
+                       // } catch (Exception e) {
+                       // throw new ArgeoException("Cannot transform from " + nodeCrs
+                       // + " to " + featureStoreCrs, e);
+                       // }
                } else {
-                       targetPosition = nodePosition;
+                       return geometry;
                }
-               double[] coo = targetPosition.getCoordinate();
-               return geometryFactory.createPoint(new Coordinate(coo[0], coo[1]));
        }
 
        public void setDataStore(DataStore dataStore) {
diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrMapper.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrMapper.java
new file mode 100644 (file)
index 0000000..f8fe502
--- /dev/null
@@ -0,0 +1,27 @@
+package org.argeo.geotools.jcr;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+
+import org.geotools.data.FeatureSource;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+public interface GeoJcrMapper {
+       /** Create it if it does not exist */
+       public Node getNode(String dataStoreAlias,
+                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource,
+                       SimpleFeature feature);
+
+       public Map<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>> getPossibleFeatureSources();
+
+       public Node getNode(String dataStoreAlias,
+                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource);
+
+       public FeatureSource<SimpleFeatureType, SimpleFeature> getFeatureSource(
+                       Node node);
+
+       public SimpleFeature getFeature(Node node);
+}
index 7b390ca3ad5f2a29fedf86b1e9e6b7de2c15364e..08181759b9bbbb3225bd49f25c5bb19cec5cc95e 100644 (file)
@@ -69,9 +69,9 @@ public class GeoJcrUtils {
        public static CoordinateReferenceSystem getCoordinateReferenceSystem(
                        Node node) {
                try {
-                       if (!node.isNodeType(GisTypes.GIS_GEOMETRY))
+                       if (!node.isNodeType(GisTypes.GIS_LOCATED))
                                throw new ArgeoException(node + " is not of type "
-                                               + GisTypes.GIS_GEOMETRY);
+                                               + GisTypes.GIS_LOCATED);
                        // Coordinate reference system
                        String srs = node.getProperty(GisNames.GIS_SRS).getString();
                        CoordinateReferenceSystem crs;
diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/SimpleGeoJcrMapper.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/SimpleGeoJcrMapper.java
new file mode 100644 (file)
index 0000000..a055a42
--- /dev/null
@@ -0,0 +1,172 @@
+package org.argeo.geotools.jcr;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.geotools.GeoToolsConstants;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.gis.GisTypes;
+import org.geotools.data.DataStore;
+import org.geotools.data.FeatureSource;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.Name;
+
+public class SimpleGeoJcrMapper implements GeoJcrMapper {
+       private final static Log log = LogFactory.getLog(SimpleGeoJcrMapper.class);
+
+       private String dataStoresBasePath = "/gis/dataStores";
+
+       private Map<String, DataStore> registeredDataStores = Collections
+                       .synchronizedSortedMap(new TreeMap<String, DataStore>());
+
+       private Session session;
+
+       public Map<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>> getPossibleFeatureSources() {
+               Map<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>> res = new TreeMap<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>>();
+               dataStores: for (String alias : registeredDataStores.keySet()) {
+                       DataStore dataStore = registeredDataStores.get(alias);
+                       List<Name> names;
+                       try {
+                               names = dataStore.getNames();
+                       } catch (IOException e) {
+                               log.warn("Cannot list features sources of data store " + alias,
+                                               e);
+                               continue dataStores;
+                       }
+                       List<FeatureSource<SimpleFeatureType, SimpleFeature>> lst = new ArrayList<FeatureSource<SimpleFeatureType, SimpleFeature>>();
+                       for (Name name : names) {
+                               try {
+                                       lst.add(dataStore.getFeatureSource(name));
+                               } catch (IOException e) {
+                                       if (log.isTraceEnabled())
+                                               log.trace("Skipping " + name + " of data store "
+                                                               + alias + " because it is probably"
+                                                               + " not a feature source", e);
+                               }
+                       }
+                       res.put(alias, lst);
+               }
+               return res;
+       }
+
+       public Node getNode(String dataStoreAlias,
+                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource,
+                       SimpleFeature feature) {
+               StringBuffer pathBuf = new StringBuffer(dataStoresBasePath);
+               pathBuf.append('/').append(dataStoreAlias);
+               pathBuf.append('/').append(featureSource.getName());
+
+               // TODO: use centroid or bbox to create some depth
+               // Geometry geometry = (Geometry)feature.getDefaultGeometry();
+               // Point centroid = geometry.getCentroid();
+
+               pathBuf.append('/').append(feature.getID());
+
+               String path = pathBuf.toString();
+               try {
+                       if (session.itemExists(path))
+                               return session.getNode(path);
+                       else
+                               return JcrUtils.mkdirs(session, path);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot get feature node for " + path, e);
+               }
+       }
+
+       protected Node getNode(String dataStoreAlias) {
+               try {
+                       Node dataStores;
+                       if (!session.itemExists(dataStoresBasePath))
+                               dataStores = JcrUtils.mkdirs(session, dataStoresBasePath);
+                       else
+                               dataStores = session.getNode(dataStoresBasePath);
+
+                       Node dataStoreNode;
+                       if (dataStores.hasNode(dataStoreAlias))
+                               dataStoreNode = dataStores.getNode(dataStoreAlias);
+                       else
+                               dataStoreNode = dataStores.addNode(dataStoreAlias,
+                                               GisTypes.GIS_DATA_STORE);
+                       return dataStoreNode;
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot get node for data store "
+                                       + dataStoreAlias, e);
+               }
+       }
+
+       public Node getNode(String dataStoreAlias,
+                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource) {
+               try {
+                       String name = featureSource.getName().toString();
+                       Node dataStoreNode = getNode(dataStoreAlias);
+                       if (dataStoreNode.hasNode(name))
+                               return dataStoreNode.getNode(name);
+                       else
+                               return dataStoreNode.addNode(name, GisTypes.GIS_FEATURE_SOURCE);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException(
+                                       "Cannot get feature source node for data store "
+                                                       + dataStoreAlias + " and feature source "
+                                                       + featureSource.getName(), e);
+               }
+       }
+
+       public FeatureSource<SimpleFeatureType, SimpleFeature> getFeatureSource(
+                       Node node) {
+               try {
+                       Node dataStoreNode = node.getParent();
+                       // TODO: check a dataStore type
+                       if (!registeredDataStores.containsKey(dataStoreNode.getName()))
+                               throw new ArgeoException("No data store registered under "
+                                               + dataStoreNode);
+                       DataStore dataStore = registeredDataStores.get(dataStoreNode.getName());
+                       return dataStore.getFeatureSource(node.getName());
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot find feature source " + node, e);
+               }
+       }
+
+       public SimpleFeature getFeature(Node node) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public void register(DataStore dataStore, Map<String, String> properties) {
+               if (!properties.containsKey(GeoToolsConstants.ALIAS_KEY)) {
+                       log.warn("Cannot register data store " + dataStore
+                                       + " since it has no '" + GeoToolsConstants.ALIAS_KEY
+                                       + "' property");
+                       return;
+               }
+               registeredDataStores.put(properties.get(GeoToolsConstants.ALIAS_KEY),
+                               dataStore);
+       }
+
+       public void unregister(DataStore dataStore, Map<String, String> properties) {
+               if (!properties.containsKey(GeoToolsConstants.ALIAS_KEY)) {
+                       log.warn("Cannot unregister data store " + dataStore
+                                       + " since it has no '" + GeoToolsConstants.ALIAS_KEY
+                                       + "' property");
+                       return;
+               }
+               registeredDataStores
+                               .remove(properties.get(GeoToolsConstants.ALIAS_KEY));
+       }
+
+       public void setSession(Session session) {
+               this.session = session;
+       }
+
+}
diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/jts/jcr/JtsJcrUtils.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/jts/jcr/JtsJcrUtils.java
new file mode 100644 (file)
index 0000000..391f66c
--- /dev/null
@@ -0,0 +1,73 @@
+package org.argeo.jts.jcr;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.jcr.Binary;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.gis.GisNames;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.io.InputStreamInStream;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKBReader;
+import com.vividsolutions.jts.io.WKBWriter;
+
+/** Utilities depending only from the JTS library. */
+public class JtsJcrUtils {
+       private static GeometryFactory geometryFactory = new GeometryFactory();
+       private static ThreadLocal<WKBWriter> wkbWriters = new ThreadLocal<WKBWriter>();
+       private static ThreadLocal<WKBReader> wkbReaders = new ThreadLocal<WKBReader>() {
+               protected WKBReader initialValue() {
+                       return new WKBReader(getGeometryFactory());
+               }
+       };
+
+       public static GeometryFactory getGeometryFactory() {
+               return geometryFactory;
+       }
+
+       public final static Geometry readWkb(Property property) {
+               Binary wkbBinary = null;
+               InputStream in = null;
+               try {
+                       wkbBinary = property.getBinary();
+                       in = wkbBinary.getStream();
+                       WKBReader wkbReader = wkbReaders.get();
+                       return wkbReader.read(new InputStreamInStream(in));
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot read WKB from " + property, e);
+               } finally {
+                       IOUtils.closeQuietly(in);
+                       JcrUtils.closeQuietly(wkbBinary);
+               }
+       }
+
+       public final static void writeWkb(Property property, Geometry geometry) {
+               Binary wkbBinary = null;
+               InputStream in = null;
+               try {
+                       WKBWriter wkbWriter = wkbWriters.get();
+                       byte[] arr = wkbWriter.write(geometry);
+                       in = new ByteArrayInputStream(arr);
+                       wkbBinary = property.getSession().getValueFactory()
+                                       .createBinary(in);
+                       property.setValue(wkbBinary);
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot write WKB to " + property, e);
+               } finally {
+                       IOUtils.closeQuietly(in);
+                       JcrUtils.closeQuietly(wkbBinary);
+               }
+       }
+}
index 654141626a505cbb3fe7cf944e376d267565c9b1..d09ed753683d97cfc697b064e678f76969b9a020 100644 (file)
          </run>
       </application>
    </extension>
+   <extension
+         id="secureWebUi2"
+         name="Argeo Secure Web UI"
+         point="org.eclipse.core.runtime.applications">
+      <application cardinality="singleton-global"
+         thread="main"
+         visible="true">
+         <run
+               class="org.argeo.security.ui.application.SecureRap">
+         </run>
+      </application>
+   </extension>
 
 </plugin>
index 1f55666c11053604ea8d98c1e161da1c898a5bd7..8ce61c2425fefc4da7eb211d731fd6f341f4f472 100644 (file)
                </dependency>
 
                <!-- Argeo Eclipse distribution (common dependencies for both RAP and RCP) -->
+               <dependency>
+                       <groupId>org.argeo.commons.eclipse</groupId>
+                       <artifactId>org.argeo.eclipse.ui.rcp</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
                <dependency>
                        <groupId>org.argeo.commons.eclipse</groupId>
                        <artifactId>org.argeo.eclipse.dep.rcp</artifactId>
index b30b8bd2d76c042504f6714485b56dd7fe382b75..a80c02943c548bec674b74b9d4b442efd078de47 100644 (file)
                                        <groupId>org.argeo.commons.eclipse</groupId>
                                        <artifactId>org.argeo.eclipse.dep.rcp</artifactId>
                                </exclusion>
+                               <exclusion>
+                                       <groupId>org.argeo.commons.eclipse</groupId>
+                                       <artifactId>org.argeo.eclipse.ui.rcp</artifactId>
+                               </exclusion>
                        </exclusions>
                </dependency>
                <!-- RAP -->
                        <artifactId>org.argeo.eclipse.dep.rap</artifactId>
                        <version>${version.argeo-commons}</version>
                </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.eclipse</groupId>
+                       <artifactId>org.argeo.eclipse.ui.rap</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
                <dependency>
                        <groupId>org.argeo.commons.server</groupId>
                        <artifactId>org.argeo.server.osgi.webapp</artifactId>
index ca03a9268e11a5a573a4c7420837dd0ef4d67639..7687e4f67dac63a210e18ad62f4281652a35dd1a 100644 (file)
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: OSGi Webapp
 Bundle-SymbolicName: org.argeo.server.osgi.webapp
-Bundle-Version: 1.0.0.qualifier
+Bundle-Version: 0.2.3.SNAPSHOT
 Bundle-Vendor: Argeo
 Web-ContextPath: org.argeo.osgi.webapp
 Import-Package: org.eclipse.equinox.http.servlet;version="1.1.0",
index 59778556a955d727d6dacb6d11249dbc535ac0a7..6afd8e13c3467175d2f84716714d1a5ed7fb188f 100644 (file)
@@ -27,6 +27,7 @@ import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.TreeMap;
 
+import javax.jcr.Binary;
 import javax.jcr.NamespaceRegistry;
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
@@ -494,4 +495,10 @@ public class JcrUtils {
        public static String normalize(String name) {
                return name.replace(':', '_');
        }
+       
+       public static void closeQuietly(Binary binary){
+               if(binary==null)
+                       return;
+               binary.dispose();
+       }
 }
index 3a97f7b76acb893164af53ae1262f5c371867cb6..750c2a594a71a0bca37deb875fcad2f9cf13530d 100644 (file)
@@ -4,9 +4,15 @@ package org.argeo.jcr.gis;
 public interface GisNames {
        public final static String GIS_NAMESPACE = "http://www.argeo.org/gis";
        public final static String GIS_ = "gis:";
-       
+
        public final static String GIS_SRS = "gis:srs";
+       public final static String GIS_BBOX = "gis:bbox";
+       public final static String GIS_CENTROID = "gis:centroid";
+
        public final static String GIS_X = "gis:x";
        public final static String GIS_Y = "gis:y";
        public final static String GIS_Z = "gis:z";
+
+       public final static String GIS_WKB = "gis:wkb";
+       public final static String GIS_WKT = "gis:wkt";
 }
index 83ebe6f8bec7d468a8fbce3a65545ce281c181e3..981caf98ab37d253e5d00b20cd231c1a9fd9b997 100644 (file)
@@ -4,5 +4,11 @@ package org.argeo.jcr.gis;
 public interface GisTypes {
        public final static String GIS_COORDINATE = "gis:coordinate";
        public final static String GIS_GEOMETRY = "gis:geometry";
+       public final static String GIS_WKT = "gis:wkt";
        public final static String GIS_POINT = "gis:point";
+       public final static String GIS_INDEXED = "gis:indexed";
+       public final static String GIS_LOCATED = "gis:located";
+
+       public final static String GIS_DATA_STORE = "gis:dataStore";
+       public final static String GIS_FEATURE_SOURCE = "gis:featureSource";
 }
index 43e3b574c39c169cf4ac4a9b42245f72dbc761ef..cc0a1d16b4b18768daf163644f1e48fd149e0ebc 100644 (file)
@@ -7,10 +7,34 @@ mixin
 - gis:y (DOUBLE) m
 - gis:z (DOUBLE)
 
-[gis:geometry] > mix:created, mix:lastModified
+// marker any node that is located or has a located parent 
+[gis:indexed] > nt:unstructured, mix:lastModified
 mixin
-// either an EPSG code (EPSG:4326 for WGS 84) or a WKT representation
-- gis:srs (STRING)
 
-[gis:point] > gis:geometry, gis:coordinate
+[gis:located] > gis:indexed
+abstract mixin
+// either an EPSG code (e.g. EPSG:4326 for WGS 84) or a WKT representation
+- gis:srs (STRING) m
+// WKB
+- gis:bbox (BINARY) m
+// WKB
+- gis:centroid (BINARY) m
+// - gis:role (STRING)
+
+[gis:geometry] > nt:unstructured, gis:located
+- gis:wkb (STRING) m
+
+// GEOTOOLS
+[gis:feature] > nt:base
+mixin
+//- gis:relatedNode (REFERENCE) *
+
+[gis:featureSource] > nt:unstructured, mix:title
 mixin
+- gis:type (STRING)
+
+[gis:dataStore] > nt:unstructured, mix:title
+- gis:type (STRING)
++ * (gis:featureSource) *
+
+[gis:relatedFeature] > nt:address, gis:located