From: Mathieu Baudier Date: Sun, 6 Mar 2011 11:17:56 +0000 (+0000) Subject: Improve JCR and GIS X-Git-Tag: argeo-commons-2.1.30~1382 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=477f38e7085ce32c6f09e062cac90f7ba8769698;p=lgpl%2Fargeo-commons.git Improve JCR and GIS git-svn-id: https://svn.argeo.org/commons/trunk@4272 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/ArgeoUiPlugin.java b/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/ArgeoUiPlugin.java index 1561282b6..73fef7812 100644 --- a/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/ArgeoUiPlugin.java +++ b/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/ArgeoUiPlugin.java @@ -16,6 +16,10 @@ 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()); + + } + } diff --git a/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/TreeParent.java b/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/TreeParent.java index 4b6ec53e1..8989d69ad 100644 --- a/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/TreeParent.java +++ b/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/TreeParent.java @@ -20,25 +20,27 @@ import java.util.ArrayList; import java.util.List; public class TreeParent extends TreeObject { - private List children; + private List children; private boolean loaded; public TreeParent(String name) { super(name); - children = new ArrayList(); + children = new ArrayList(); 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; diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/MANIFEST.MF b/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/MANIFEST.MF index 21c08dc92..bc9ca2689 100644 --- a/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/MANIFEST.MF +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/MANIFEST.MF @@ -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 index 000000000..3c201e938 --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/IdentifiedVectorFeature.java @@ -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 + + " );"); + } +} diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/MapContextAdapter.java b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/MapContextAdapter.java index e6d34ef1d..8adf05799 100644 --- a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/MapContextAdapter.java +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/MapContextAdapter.java @@ -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 vectorLayers = Collections + .synchronizedMap(new HashMap()); + private Map> featureSources = Collections + .synchronizedMap(new HashMap>()); public MapContextAdapter(MapContext mapContext, OpenLayersMap openLayersMap) { this.mapContext = mapContext; - this.openLayersMap = openLayersMap; + this.map = openLayersMap; mapContext.addMapLayerListListener(this); HashMap payloadMap = new HashMap(); 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 editPayload = new HashMap(); + 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 selectPayload = new HashMap(); + 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 mapPayload = new HashMap(); + 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 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 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 featureIterator = null; try { FeatureSource featureSource = (FeatureSource) 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 selectPayload = new HashMap(); + 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 featureCollection = featureSource .getFeatures(); - FeatureIterator 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 points = new ArrayList(); 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 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); } } diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapControlCreator.java b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapControlCreator.java index f3972a9f9..c38a7f5b9 100644 --- a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapControlCreator.java +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapControlCreator.java @@ -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 index 000000000..29c4e30fb --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/BingLayer.java @@ -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 index 000000000..e78bd5184 --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/GoogleLayer.java @@ -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 index 000000000..c4b38d7b7 --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/custom/JSON.java @@ -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); + } + +} diff --git a/gis/plugins/org.argeo.gis.ui/META-INF/MANIFEST.MF b/gis/plugins/org.argeo.gis.ui/META-INF/MANIFEST.MF index 24fb318dc..7ca7f527d 100644 --- a/gis/plugins/org.argeo.gis.ui/META-INF/MANIFEST.MF +++ b/gis/plugins/org.argeo.gis.ui/META-INF/MANIFEST.MF @@ -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, diff --git a/gis/plugins/org.argeo.gis.ui/META-INF/spring/commands.xml b/gis/plugins/org.argeo.gis.ui/META-INF/spring/commands.xml index 5a6cc7fcb..52746358d 100644 --- a/gis/plugins/org.argeo.gis.ui/META-INF/spring/commands.xml +++ b/gis/plugins/org.argeo.gis.ui/META-INF/spring/commands.xml @@ -4,8 +4,11 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> - + + + + 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 index 000000000..8b194c0a7 --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui/META-INF/spring/geojcr.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/gis/plugins/org.argeo.gis.ui/META-INF/spring/osgi.xml b/gis/plugins/org.argeo.gis.ui/META-INF/spring/osgi.xml index faf565ddd..711b80acf 100644 --- a/gis/plugins/org.argeo.gis.ui/META-INF/spring/osgi.xml +++ b/gis/plugins/org.argeo.gis.ui/META-INF/spring/osgi.xml @@ -7,6 +7,13 @@ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - + + + + + \ No newline at end of file diff --git a/gis/plugins/org.argeo.gis.ui/META-INF/spring/views.xml b/gis/plugins/org.argeo.gis.ui/META-INF/spring/views.xml index fd995a13b..c75bce9b7 100644 --- a/gis/plugins/org.argeo.gis.ui/META-INF/spring/views.xml +++ b/gis/plugins/org.argeo.gis.ui/META-INF/spring/views.xml @@ -9,9 +9,10 @@ scope="prototype"> - - + + diff --git a/gis/plugins/org.argeo.gis.ui/plugin.xml b/gis/plugins/org.argeo.gis.ui/plugin.xml index 2a712424e..a7d5ed8f7 100644 --- a/gis/plugins/org.argeo.gis.ui/plugin.xml +++ b/gis/plugins/org.argeo.gis.ui/plugin.xml @@ -11,10 +11,10 @@ id="org.argeo.gis.ui.layersView"> + id="org.argeo.gis.ui.featureSourcesView"> + + - + + org.argeo.eclipse.ui 0.2.3-SNAPSHOT + + org.argeo.commons.eclipse + org.argeo.eclipse.ui.jcr + 0.2.3-SNAPSHOT + 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 index 000000000..aeb962a80 --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddFeatureSources.java @@ -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>> featureSources = dialog + .getFeatureSources(); + for (String alias : featureSources.keySet()) { + for (FeatureSource 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>> featureSources = new HashMap>>(); + + 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 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>()); + 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>> getFeatureSources() { + return featureSources; + } + } + + private class DataStoreContentProvider extends AbstractTreeContentProvider { + + @SuppressWarnings("unchecked") + public Object[] getElements(Object inputElement) { + List dataStoreNodes = new ArrayList(); + Map>> featureSources = (Map>>) inputElement; + for (String alias : featureSources.keySet()) { + TreeParent dataStoreNode = new TreeParent(alias); + for (FeatureSource 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 featureSource; + + public FeatureSourceNode(String dataStoreAlias, + FeatureSource featureSource) { + super(featureSource.getName().toString()); + this.dataStoreAlias = dataStoreAlias; + this.featureSource = featureSource; + } + + public String getDataStoreAlias() { + return dataStoreAlias; + } + + public FeatureSource 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 index 000000000..76ea5dd56 --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/FeatureSourcesView.java @@ -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 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); + } + + } +} diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/LayersView.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/LayersView.java index 56fb03fe1..096f03657 100644 --- a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/LayersView.java +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/LayersView.java @@ -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 index 000000000..b04534074 --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/MapsView.java @@ -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 index 000000000..060b80385 --- /dev/null +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsConstants.java @@ -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"; +} diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsUtils.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsUtils.java index 88ab84995..c154f4b97 100644 --- a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsUtils.java +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsUtils.java @@ -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 getFeatureStore( DataStore dataStore, Name name) { @@ -45,4 +61,45 @@ public class GeoToolsUtils { } } } + + public static FilterFactory2 ff() { + return filterFactory; + } + + public static SimpleFeature querySingleFeature( + FeatureSource featureSource, + String featureId) { + Set ids = new HashSet(); + ids.add(ff().featureId(featureId)); + Filter filter = ff().id(ids); + FeatureIterator 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 + } + } } diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrIndex.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrIndex.java index e6afb9430..2f62c8bf7 100644 --- a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrIndex.java +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrIndex.java @@ -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 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 pointsToAdd = FeatureCollections + SimpleFeatureType indexType = getWorkspaceGeoIndex(session + .getWorkspace().getName()); + GeoToolsUtils.createSchemaIfNeeded(dataStore, indexType); + FeatureStore geoJcrIndex = GeoToolsUtils + .getFeatureStore(dataStore, indexType.getName()); + + FeatureCollection toAdd = FeatureCollections .newCollection(); - Set pointsToRemove = new HashSet(); + Set toRemove = new HashSet(); 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 coordinates = new ArrayList(); + // 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 index 000000000..f8fe50288 --- /dev/null +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrMapper.java @@ -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 featureSource, + SimpleFeature feature); + + public Map>> getPossibleFeatureSources(); + + public Node getNode(String dataStoreAlias, + FeatureSource featureSource); + + public FeatureSource getFeatureSource( + Node node); + + public SimpleFeature getFeature(Node node); +} diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrUtils.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrUtils.java index 7b390ca3a..08181759b 100644 --- a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrUtils.java +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrUtils.java @@ -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 index 000000000..a055a4238 --- /dev/null +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/SimpleGeoJcrMapper.java @@ -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 registeredDataStores = Collections + .synchronizedSortedMap(new TreeMap()); + + private Session session; + + public Map>> getPossibleFeatureSources() { + Map>> res = new TreeMap>>(); + dataStores: for (String alias : registeredDataStores.keySet()) { + DataStore dataStore = registeredDataStores.get(alias); + List names; + try { + names = dataStore.getNames(); + } catch (IOException e) { + log.warn("Cannot list features sources of data store " + alias, + e); + continue dataStores; + } + List> lst = new ArrayList>(); + 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 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 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 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 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 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 index 000000000..391f66c59 --- /dev/null +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/jts/jcr/JtsJcrUtils.java @@ -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 wkbWriters = new ThreadLocal(); + private static ThreadLocal wkbReaders = new ThreadLocal() { + 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); + } + } +} diff --git a/security/plugins/org.argeo.security.ui.application/plugin.xml b/security/plugins/org.argeo.security.ui.application/plugin.xml index 654141626..d09ed7536 100644 --- a/security/plugins/org.argeo.security.ui.application/plugin.xml +++ b/security/plugins/org.argeo.security.ui.application/plugin.xml @@ -59,5 +59,17 @@ + + + + + + diff --git a/security/plugins/org.argeo.security.ui.application/pom.xml b/security/plugins/org.argeo.security.ui.application/pom.xml index 1f55666c1..8ce61c242 100644 --- a/security/plugins/org.argeo.security.ui.application/pom.xml +++ b/security/plugins/org.argeo.security.ui.application/pom.xml @@ -86,6 +86,11 @@ + + org.argeo.commons.eclipse + org.argeo.eclipse.ui.rcp + ${version.argeo-commons} + org.argeo.commons.eclipse org.argeo.eclipse.dep.rcp diff --git a/security/plugins/org.argeo.security.ui.rap/pom.xml b/security/plugins/org.argeo.security.ui.rap/pom.xml index b30b8bd2d..a80c02943 100644 --- a/security/plugins/org.argeo.security.ui.rap/pom.xml +++ b/security/plugins/org.argeo.security.ui.rap/pom.xml @@ -69,6 +69,10 @@ org.argeo.commons.eclipse org.argeo.eclipse.dep.rcp + + org.argeo.commons.eclipse + org.argeo.eclipse.ui.rcp + @@ -77,6 +81,11 @@ org.argeo.eclipse.dep.rap ${version.argeo-commons} + + org.argeo.commons.eclipse + org.argeo.eclipse.ui.rap + ${version.argeo-commons} + org.argeo.commons.server org.argeo.server.osgi.webapp diff --git a/server/modules/org.argeo.server.osgi.webapp/META-INF/MANIFEST.MF b/server/modules/org.argeo.server.osgi.webapp/META-INF/MANIFEST.MF index ca03a9268..7687e4f67 100644 --- a/server/modules/org.argeo.server.osgi.webapp/META-INF/MANIFEST.MF +++ b/server/modules/org.argeo.server.osgi.webapp/META-INF/MANIFEST.MF @@ -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", diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java index 59778556a..6afd8e13c 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java @@ -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(); + } } diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java index 3a97f7b76..750c2a594 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java @@ -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"; } diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java index 83ebe6f8b..981caf98a 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java @@ -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"; } diff --git a/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd b/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd index 43e3b574c..cc0a1d16b 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd +++ b/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd @@ -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