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;
/**
* 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;
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");
+
}
/*
* )
*/
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);
}
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());
+
+ }
+
}
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() {
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;
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,
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,
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,
--- /dev/null
+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
+ + " );");
+ }
+}
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;
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;
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);
+
}
/*
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(
vectorLayer.addFeatures(vf);
}
}
- openLayersMap.addLayer(vectorLayer);
+ map.addLayer(vectorLayer);
} catch (IOException e) {
log.error("Cannot add layer " + event.getLayer(), e);
+ } finally {
+ GeoToolsUtils.closeQuietly(featureIterator);
}
}
}
/*
- * 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);
}
}
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;
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;
}
--- /dev/null
+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 + "'})");
+
+ }
+}
--- /dev/null
+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})");
+
+ }
+}
--- /dev/null
+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);
+ }
+
+}
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,
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,
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>
--- /dev/null
+<?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>
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
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>
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
<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>
--- /dev/null
+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;
+ }
+
+ }
+
+}
--- /dev/null
+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);
+ }
+
+ }
+}
@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());
--- /dev/null
+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);
+ }
+
+ }
+}
--- /dev/null
+package org.argeo.geotools;
+
+public interface GeoToolsConstants {
+ public final static String ALIAS_KEY = "alias";
+ public final static String PUBLISHED_FEATURE_SOURCES_KEY = "publishedFeatureSources";
+}
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) {
}
}
}
+
+ 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
+ }
+ }
}
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;
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() {
.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",
}
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 {
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);
// 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();
}
}
- 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) {
--- /dev/null
+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);
+}
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;
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+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);
+ }
+ }
+}
</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>
</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>
<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>
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",
import java.util.StringTokenizer;
import java.util.TreeMap;
+import javax.jcr.Binary;
import javax.jcr.NamespaceRegistry;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
public static String normalize(String name) {
return name.replace(':', '_');
}
+
+ public static void closeQuietly(Binary binary){
+ if(binary==null)
+ return;
+ binary.dispose();
+ }
}
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";
}
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";
}
- 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