--- /dev/null
+package org.argeo.eclipse.ui;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Tree content provider dealing with tree objects and providing reasonable
+ * defualts.
+ */
+public abstract class AbstractTreeContentProvider implements
+ ITreeContentProvider {
+
+ /** Does nothing */
+ public void dispose() {
+ }
+
+ /** Does nothing */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ public Object[] getChildren(Object element) {
+ if (element instanceof TreeParent) {
+ return ((TreeParent) element).getChildren();
+ }
+ return new Object[0];
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof TreeObject) {
+ return ((TreeObject) element).getParent();
+ }
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ if (element instanceof TreeParent) {
+ return ((TreeParent) element).hasChildren();
+ }
+ return false;
+ }
+
+}
package org.argeo.eclipse.ui;
-public class TreeObject implements Comparable<TreeObject> {
+class TreeObject implements Comparable<TreeObject> {
private String name;
private TreeParent parent;
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Rap
-Bundle-SymbolicName: org.argeo.gis.ui.rap.openlayers
+Bundle-SymbolicName: org.argeo.gis.ui.rap.openlayers;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.argeo.gis.ui.rap.openlayers.GisOpenlayersPlugin
Bundle-Vendor: Argeo
Require-Bundle: org.eclipse.rap.ui,
- org.eclipse.core.runtime
+ org.eclipse.core.runtime,
+ org.polymap.openlayers.rap.widget;bundle-version="[1.0.0,2.0.0)"
Bundle-RequiredExecutionEnvironment: J2SE-1.5
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.gis.ui,
+ org.argeo.gis.ui.editors,
+ org.geotools.data,
+ org.geotools.feature,
+ org.geotools.map,
+ org.geotools.map.event,
+ org.opengis.feature,
+ org.opengis.feature.simple,
+ org.opengis.feature.type,
+ org.polymap.openlayers.rap.widget,
+ org.polymap.openlayers.rap.widget.base,
+ org.polymap.openlayers.rap.widget.base_types,
+ org.polymap.openlayers.rap.widget.controls,
+ org.polymap.openlayers.rap.widget.layers
--- /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="mapControlCreator"
+ class="org.argeo.gis.ui.rap.openlayers.OpenLayersMapControlCreator" />
+
+</beans>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/osgi \r
+ http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+ http://www.springframework.org/schema/beans \r
+ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
+\r
+ <service ref="mapControlCreator" interface="org.argeo.gis.ui.MapControlCreator" />\r
+\r
+</beans:beans>
\ No newline at end of file
source.. = src/main/java/
output.. = target/classes/
bin.includes = META-INF/,\
- .
+ .,\
+ js_lib/
public class GisOpenlayersPlugin extends AbstractUIPlugin {
// The plug-in ID
- public static final String PLUGIN_ID = "org.argeo.gis.ui.rap"; //$NON-NLS-1$
+ public static final String PLUGIN_ID = "org.argeo.gis.ui.rap.openlayers"; //$NON-NLS-1$
// The shared instance
private static GisOpenlayersPlugin plugin;
--- /dev/null
+package org.argeo.gis.ui.rap.openlayers;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.geotools.data.FeatureSource;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.map.MapContext;
+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.polymap.openlayers.rap.widget.base.OpenLayersEventListener;
+import org.polymap.openlayers.rap.widget.base.OpenLayersObject;
+import org.polymap.openlayers.rap.widget.base_types.OpenLayersMap;
+import org.polymap.openlayers.rap.widget.features.VectorFeature;
+import org.polymap.openlayers.rap.widget.geometry.LineStringGeometry;
+import org.polymap.openlayers.rap.widget.geometry.PointGeometry;
+import org.polymap.openlayers.rap.widget.layers.VectorLayer;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.MultiPolygon;
+
+public class MapContextAdapter implements MapLayerListListener,
+ OpenLayersEventListener {
+ private final static Log log = LogFactory.getLog(MapContextAdapter.class);
+
+ private final MapContext mapContext;
+ private final OpenLayersMap openLayersMap;
+
+ public MapContextAdapter(MapContext mapContext, OpenLayersMap openLayersMap) {
+ this.mapContext = mapContext;
+ this.openLayersMap = 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);
+ payloadMap.put("property", "event.property");
+ payloadMap.put("visibility", "event.layer.visibility");
+ this.openLayersMap.events.register(this, "changelayer", payloadMap);
+ }
+
+ /*
+ * MAP CONTEXT
+ */
+
+ @SuppressWarnings("unchecked")
+ public void layerAdded(MapLayerListEvent event) {
+ if (log.isDebugEnabled())
+ log.debug("Map context layer added " + event);
+
+ try {
+ FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) event
+ .getLayer().getFeatureSource();
+
+ VectorLayer vectorLayer = new VectorLayer(featureSource.getName()
+ .toString());
+ FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = featureSource
+ .getFeatures();
+ FeatureIterator<SimpleFeature> fit = featureCollection.features();
+ while (fit.hasNext()) {
+ SimpleFeature feature = fit.next();
+ Geometry geom = (Geometry) feature.getDefaultGeometry();
+ log.debug("Feature " + feature.getID());
+// log.debug(" Geom: " + geom.getClass() + ", centroid="
+// + geom.getCentroid());
+ if (geom instanceof MultiPolygon) {
+ MultiPolygon mp = (MultiPolygon) geom;
+ List<PointGeometry> points = new ArrayList<PointGeometry>();
+ for (Coordinate coo : mp.getCoordinates()) {
+ points.add(new PointGeometry(coo.x, coo.y));
+ }
+ VectorFeature vf = new VectorFeature(
+ new LineStringGeometry(
+ points.toArray(new PointGeometry[points
+ .size()])));
+ vectorLayer.addFeatures(vf);
+ }
+ }
+ openLayersMap.addLayer(vectorLayer);
+ } catch (IOException e) {
+ log.error("Cannot add layer " + event.getLayer(), e);
+ }
+ }
+
+ public void layerRemoved(MapLayerListEvent event) {
+ if (log.isDebugEnabled())
+ log.debug("Map context layer removed " + event);
+ }
+
+ public void layerChanged(MapLayerListEvent event) {
+ if (log.isDebugEnabled())
+ log.debug("Map context layer changed " + event);
+ }
+
+ public void layerMoved(MapLayerListEvent event) {
+ if (log.isDebugEnabled())
+ log.debug("Map context layer moved " + event);
+ }
+
+ /*
+ * 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");
+ VectorLayer edit_layer = new VectorLayer("edit layer");
+ if (payload.get("layername").equals(edit_layer.getName())) {
+ if (visible) {
+
+ } else {
+ }
+ }
+ }
+ } else if (log.isDebugEnabled())
+ log.debug("unknown event " + eventName);
+
+ }
+
+}
--- /dev/null
+package org.argeo.gis.ui.rap.openlayers;
+
+import org.argeo.gis.ui.MapContextProvider;
+import org.argeo.gis.ui.MapControlCreator;
+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.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.PanZoomBarControl;
+import org.polymap.openlayers.rap.widget.controls.ScaleControl;
+import org.polymap.openlayers.rap.widget.layers.OSMLayer;
+import org.polymap.openlayers.rap.widget.layers.WMSLayer;
+
+public class OpenLayersMapControlCreator implements MapControlCreator {
+ public Composite createMapControl(Composite parent,
+ MapContextProvider mapContextProvider) {
+
+ // OpenLayersWidget openLayersWidget = new OpenLayersWidget(parent,
+ // SWT.MULTI | SWT.WRAP, "/js_lib/OpenLayers/OpenLayers.js");
+ OpenLayersWidget openLayersWidget = new OpenLayersWidget(parent,
+ SWT.MULTI | SWT.WRAP);
+ openLayersWidget.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ OpenLayersMap map = openLayersWidget.getMap();
+
+ map.addControl(new LayerSwitcherControl());
+ map.addControl(new MouseDefaultsControl());
+ map.addControl(new KeyboardDefaultsControl());
+ map.addControl(new PanZoomBarControl());
+ map.addControl(new ScaleControl());
+
+// WMSLayer baseLayer = new WMSLayer("argeo_dev",
+// "https://dev.argeo.org/geoserver/wms?",
+// "naturalearth:10m_admin_0_countries");
+
+ OSMLayer baseLayer = new OSMLayer("OSM",
+ "http://tile.openstreetmap.org/${z}/${x}/${y}.png", 19);
+ map.addLayer(baseLayer);
+
+ MapContextAdapter mapContextAdapter = new MapContextAdapter(
+ mapContextProvider.getMapContext(), map);
+ // FIXME: find a better way to register it
+ openLayersWidget.setData(mapContextAdapter);
+ return openLayersWidget;
+ }
+
+}
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Ui
-Bundle-SymbolicName: org.argeo.gis.ui
+Bundle-SymbolicName: org.argeo.gis.ui;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.argeo.gis.ui.GisUiPlugin
Bundle-Vendor: Argeo
org.eclipse.core.runtime
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
+Import-Package: org.apache.commons.logging;version="1.1.1",
+ org.argeo,
+ org.argeo.eclipse.spring,
+ org.argeo.eclipse.ui,
+ org.argeo.eclipse.ui.dialogs,
+ org.geotools.data,
+ org.geotools.map,
+ org.geotools.map.event,
+ org.opengis.feature.simple,
+ org.opengis.feature.type
+Export-Package: org.argeo.gis.ui,
+ org.argeo.gis.ui.commands,
+ org.argeo.gis.ui.editors,
+ org.argeo.gis.ui.views
--- /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="newMap"
+ class="org.argeo.gis.ui.commands.NewMap"
+ scope="prototype">
+ </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="defaultMapEditor" class="org.argeo.gis.ui.editors.DefaultMapEditor"
+ scope="prototype">
+ <property name="mapControlCreator" ref="mapControlCreator" />
+ </bean>
+
+</beans>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/osgi \r
+ http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+ http://www.springframework.org/schema/beans \r
+ 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
+\r
+</beans:beans>
\ No newline at end of file
--- /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="layersView" class="org.argeo.gis.ui.views.LayersView"
+ scope="prototype">
+ </bean>
+
+ <bean id="dataStoresView" class="org.argeo.gis.ui.views.DataStoresView"
+ scope="prototype">
+ <property name="dataStores" ref="dataStores" />
+ </bean>
+
+</beans>
source.. = src/main/java/
output.. = target/classes/
bin.includes = META-INF/,\
- .
+ .,\
+ plugin.xml,\
+ js_lib/,\
+ icons/
--- /dev/null
+argeo.osgi.start=\
+org.springframework.osgi.extender,\
+com.springsource.javax.servlet,\
+org.eclipse.core.runtime,\
+org.eclipse.equinox.common,\
+org.eclipse.equinox.http.jetty,\
+org.eclipse.equinox.http.registry,\
+org.eclipse.equinox.launcher,\
+org.mortbay.jetty.server,\
+org.argeo.security.equinox,\
+org.argeo.security.manager.ldap,\
+org.argeo.security.services,\
+org.argeo.server.ads.server,\
+org.argeo.node.repo.jackrabbit,\
+org.argeo.gis.ui.rap.openlayers,\
+org.argeo.slc.gis.position.backend,\
+
+eclipse.ignoreApp=true
+osgi.noShutdown=true
+
+org.argeo.security.ui.initialPerspective=org.argeo.gis.ui.perspective
+
+log4j.configuration=file:../../log4j.properties
+
+org.eclipse.equinox.http.jetty.log.stderr.threshold=debug
+org.osgi.service.http.port=9090
--- /dev/null
+log4j.rootLogger=INFO, console
+
+## Levels
+log4j.logger.org.argeo=DEBUG
+
+log4j.logger.org.apache.catalina=INFO
+log4j.logger.org.apache.coyote=INFO
+log4j.logger.org.apache.tomcat=INFO
+
+log4j.logger.org.apache.directory.server=INFO
+log4j.logger.org.apache.directory.server.core.partition=ERROR
+log4j.logger.org.apache.directory.server.core.schema.bootstrap.BootstrapAttributeTypeRegistry=ERROR
+
+log4j.logger.org.apache.jackrabbit=INFO
+log4j.logger.org.apache.jackrabbit.core.query.lucene=ERROR
+
+## Appenders
+# console is set to be a ConsoleAppender.
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+
+# console uses PatternLayout.
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c - [%t]%n
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+ <extension
+ point="org.eclipse.ui.views">
+ <view
+ name="Layers"
+ icon="icons/layer_folder.gif"
+ class="org.argeo.eclipse.spring.SpringExtensionFactory"
+ id="org.argeo.gis.ui.layersView">
+ </view>
+ <view
+ name="Data Stores"
+ icon="icons/gis_add_data.gif"
+ class="org.argeo.eclipse.spring.SpringExtensionFactory"
+ id="org.argeo.gis.ui.dataStoresView">
+ </view>
+ </extension>
+ <extension
+ point="org.eclipse.ui.editors">
+ <editor
+ id="org.argeo.gis.ui.defaultMapEditor"
+ class="org.argeo.eclipse.spring.SpringExtensionFactory"
+ default="true"
+ icon="icons/earth_edit.gif"
+ name="Map Editor">
+ </editor>
+ </extension>
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ id="org.argeo.gis.ui.newMap"
+ name="New Map">
+ </command>
+ </extension>
+ <extension
+ point="org.eclipse.ui.menus">
+ <!-- Queries -->
+ <menuContribution
+ locationURI="toolbar:org.argeo.gis.ui.layersView">
+ <command
+ commandId="org.argeo.gis.ui.newMap"
+ disabledIcon="icons/sample.gif"
+ icon="icons/earth_edit.gif"
+ label="New Map"
+ style="push"
+ tooltip="New Map">
+ </command>
+ </menuContribution>
+ </extension>
+ <extension
+ point="org.eclipse.ui.perspectives">
+ <perspective
+ class="org.argeo.gis.ui.GisPerspective"
+ icon="icons/gis.gif"
+ id="org.argeo.gis.ui.perspective"
+ name="GIS">
+ </perspective>
+ </extension>
+ <extension
+ point="org.eclipse.ui.editors">
+ <editor
+ id="org.argeo.gis.ui.defaultMapEditor"
+ class="org.argeo.eclipse.spring.SpringExtensionFactory"
+ default="true"
+ icon="icons/earth_edit.gif"
+ name="Map Editor">
+ </editor>
+ </extension>
+
+</plugin>
--- /dev/null
+package org.argeo.gis.ui;
+
+import org.argeo.gis.ui.views.DataStoresView;
+import org.argeo.gis.ui.views.LayersView;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+public class GisPerspective implements IPerspectiveFactory {
+
+ public void createInitialLayout(IPageLayout layout) {
+ String editorArea = layout.getEditorArea();
+ layout.setEditorAreaVisible(true);
+ layout.setFixed(false);
+
+ IFolderLayout topLeft = layout.createFolder("topLeft",
+ IPageLayout.LEFT, 0.3f, editorArea);
+ topLeft.addView(LayersView.ID);
+ topLeft.addView(DataStoresView.ID);
+ }
+
+}
--- /dev/null
+package org.argeo.gis.ui;
+
+import org.geotools.map.MapContext;
+
+public interface MapContextProvider {
+ public MapContext getMapContext();
+}
--- /dev/null
+package org.argeo.gis.ui;
+
+import org.eclipse.swt.widgets.Composite;
+
+public interface MapControlCreator {
+ /** Creates a map control based on this parent and this map context */
+ public Composite createMapControl(Composite parent,
+ MapContextProvider mapContextProvider);
+}
--- /dev/null
+package org.argeo.gis.ui.commands;
+
+import org.argeo.eclipse.ui.dialogs.Error;
+import org.argeo.gis.ui.editors.DefaultMapEditor;
+import org.argeo.gis.ui.editors.MapEditorInput;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.geotools.map.DefaultMapContext;
+
+/** Opens a new map editor */
+public class AddLayer extends AbstractHandler {
+ private String editorId = DefaultMapEditor.ID;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ try {
+ HandlerUtil
+ .getActiveWorkbenchWindow(event)
+ .getActivePage()
+ .openEditor(new MapEditorInput(new DefaultMapContext()),
+ editorId);
+ } catch (Exception e) {
+ Error.show("Cannot open editor", e);
+ }
+ return null;
+ }
+
+ public void setEditorId(String editorId) {
+ this.editorId = editorId;
+ }
+
+}
--- /dev/null
+package org.argeo.gis.ui.commands;
+
+import org.argeo.eclipse.ui.dialogs.Error;
+import org.argeo.gis.ui.editors.DefaultMapEditor;
+import org.argeo.gis.ui.editors.MapEditorInput;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.geotools.map.DefaultMapContext;
+
+/** Opens a new map editor */
+public class NewMap extends AbstractHandler {
+ private String editorId = DefaultMapEditor.ID;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ try {
+ HandlerUtil
+ .getActiveWorkbenchWindow(event)
+ .getActivePage()
+ .openEditor(new MapEditorInput(new DefaultMapContext()),
+ editorId);
+ } catch (Exception e) {
+ Error.show("Cannot open editor", e);
+ }
+ return null;
+ }
+
+ public void setEditorId(String editorId) {
+ this.editorId = editorId;
+ }
+
+}
--- /dev/null
+package org.argeo.gis.ui.data;
+
+import java.io.IOException;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.TreeParent;
+import org.geotools.data.DataStore;
+import org.opengis.feature.type.Name;
+
+public class DataStoreNode extends TreeParent {
+ private DataStore dataStore;
+
+ public DataStoreNode(DataStore dataStore) {
+ super(dataStore.getInfo().getTitle() != null ? dataStore.getInfo()
+ .getTitle() : dataStore.toString());
+ this.dataStore = dataStore;
+ try {
+ for (Name name : dataStore.getNames()) {
+ addChild(new FeatureNode(dataStore, name));
+ }
+ } catch (IOException e) {
+ throw new ArgeoException("Cannot scan data store", e);
+ }
+ }
+
+ public DataStore getDataStore() {
+ return dataStore;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.gis.ui.data;
+
+import java.io.IOException;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.TreeParent;
+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 FeatureNode extends TreeParent {
+ private final DataStore dataStore;
+ private final Name featureName;
+
+ public FeatureNode(DataStore dataStore, Name name) {
+ super(name.toString());
+ this.dataStore = dataStore;
+ this.featureName = name;
+ }
+
+ public FeatureSource<SimpleFeatureType, SimpleFeature> getFeatureSource() {
+ try {
+ return dataStore.getFeatureSource(featureName);
+ } catch (IOException e) {
+ throw new ArgeoException("Cannot get feature " + featureName
+ + " of " + dataStore, e);
+ }
+ }
+
+ public DataStore getDataStore() {
+ return dataStore;
+ }
+
+ public Name getFeatureName() {
+ return featureName;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.gis.ui.editors;
+
+import org.argeo.gis.ui.MapContextProvider;
+import org.argeo.gis.ui.MapControlCreator;
+import org.argeo.gis.ui.views.LayersView;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.EditorPart;
+import org.geotools.data.FeatureSource;
+import org.geotools.map.MapContext;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+/** A generic map editor */
+public class DefaultMapEditor extends EditorPart implements MapContextProvider {
+ public final static String ID = "org.argeo.gis.ui.defaultMapEditor";
+
+ private MapContext mapContext;
+ private Composite map;
+ private MapControlCreator mapControlCreator;
+
+ @Override
+ public void init(IEditorSite site, IEditorInput input)
+ throws PartInitException {
+ if (input instanceof MapContextProvider) {
+ mapContext = ((MapContextProvider) input).getMapContext();
+ setSite(site);
+ setInput(input);
+ setPartName(input.getName());
+ } else {
+ throw new PartInitException("Support only "
+ + MapContextProvider.class + " inputs");
+ }
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ Composite mapArea = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ mapArea.setLayout(layout);
+ map = mapControlCreator.createMapControl(mapArea, this);
+ }
+
+ public void addLayer(
+ FeatureSource<SimpleFeatureType, SimpleFeature> featureSource) {
+ // TODO: deal with style
+ mapContext.addLayer(featureSource, null);
+ }
+
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ }
+
+ @Override
+ public void doSaveAs() {
+ }
+
+ @Override
+ public boolean isDirty() {
+ return false;
+ }
+
+ @Override
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ @Override
+ public void setFocus() {
+ LayersView layersView = (LayersView) getEditorSite()
+ .getWorkbenchWindow().getActivePage().findView(LayersView.ID);
+ layersView.setMapContext(getMapContext());
+ map.setFocus();
+ }
+
+ public MapContext getMapContext() {
+ return mapContext;
+ }
+
+ public void setMapControlCreator(MapControlCreator mapControlCreator) {
+ this.mapControlCreator = mapControlCreator;
+ }
+
+}
--- /dev/null
+package org.argeo.gis.ui.editors;
+
+import org.argeo.gis.ui.MapContextProvider;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPersistableElement;
+import org.geotools.map.MapContext;
+
+public class MapEditorInput implements IEditorInput, MapContextProvider {
+ private final MapContext mapContext;
+
+ public MapEditorInput(MapContext mapContext) {
+ this.mapContext = mapContext;
+ }
+
+ public MapContext getMapContext() {
+ return mapContext;
+ }
+
+ public String getName() {
+ return mapContext.getTitle() != null ? mapContext.getTitle() : "<new>";
+ }
+
+ public String getToolTipText() {
+ return mapContext.getAbstract() != null ? mapContext.getAbstract()
+ : mapContext.getTitle() != null ? mapContext.getTitle() : "";
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Object getAdapter(Class adapter) {
+ if (MapContext.class.isAssignableFrom(adapter))
+ return mapContext;
+ return null;
+ }
+
+ public boolean exists() {
+ return false;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ return null;
+ }
+
+ public IPersistableElement getPersistable() {
+ return null;
+ }
+
+}
--- /dev/null
+package org.argeo.gis.ui.views;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.argeo.eclipse.ui.AbstractTreeContentProvider;
+import org.argeo.gis.ui.data.DataStoreNode;
+import org.argeo.gis.ui.data.FeatureNode;
+import org.argeo.gis.ui.editors.DefaultMapEditor;
+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.DataStore;
+import org.geotools.data.FeatureSource;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+public class DataStoresView extends ViewPart implements IDoubleClickListener {
+ public final static String ID = "org.argeo.gis.ui.dataStoresView";
+
+ private TreeViewer viewer;
+
+ private List<DataStore> dataStores;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+ viewer.setContentProvider(new DataStoreContentProvider());
+ viewer.setLabelProvider(new DataStoreLabelProvider());
+ viewer.setInput(getViewSite());
+ viewer.addDoubleClickListener(this);
+ }
+
+ public void doubleClick(DoubleClickEvent event) {
+ if (!event.getSelection().isEmpty()) {
+ Iterator<?> it = ((IStructuredSelection) event.getSelection())
+ .iterator();
+ while (it.hasNext()) {
+ Object obj = it.next();
+ if (obj instanceof FeatureNode) {
+ FeatureNode featureNode = (FeatureNode) obj;
+ FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = featureNode
+ .getFeatureSource();
+ IEditorPart ed = getSite().getWorkbenchWindow().getActivePage().getActiveEditor();
+ if(ed instanceof DefaultMapEditor){
+ ((DefaultMapEditor)ed).addLayer(featureSource);
+ }
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public void setFocus() {
+ viewer.getTree().setFocus();
+ }
+
+ public void refresh() {
+ viewer.refresh();
+ }
+
+ public void setDataStores(List<DataStore> dataStores) {
+ this.dataStores = dataStores;
+ }
+
+ private class DataStoreContentProvider extends AbstractTreeContentProvider {
+
+ public Object[] getElements(Object inputElement) {
+ List<DataStoreNode> dataStoreNodes = new ArrayList<DataStoreNode>();
+ // it is better to deal with OSGi reference using and iterator
+ Iterator<DataStore> it = dataStores.iterator();
+ while (it.hasNext())
+ dataStoreNodes.add(new DataStoreNode(it.next()));
+ return dataStoreNodes.toArray();
+ }
+
+ }
+
+ private class DataStoreLabelProvider extends LabelProvider {
+
+ @Override
+ public String getText(Object element) {
+ return super.getText(element);
+ }
+
+ }
+}
--- /dev/null
+package org.argeo.gis.ui.views;
+
+import org.argeo.eclipse.ui.TreeParent;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.part.ViewPart;
+import org.geotools.map.MapContext;
+import org.geotools.map.MapLayer;
+import org.geotools.map.event.MapLayerListEvent;
+import org.geotools.map.event.MapLayerListListener;
+
+public class LayersView extends ViewPart implements MapLayerListListener {
+ public final static String ID = "org.argeo.gis.ui.layersView";
+
+ private TreeViewer viewer;
+
+ private MapContext mapContext;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+ viewer.setContentProvider(new MapContextContentProvider());
+ viewer.setLabelProvider(new MapContextLabelProvider());
+ viewer.setInput(getViewSite());
+ }
+
+ public void setMapContext(MapContext mapContext) {
+ viewer.setInput(mapContext);
+ if (this.mapContext != null) {
+ this.mapContext.removeMapLayerListListener(this);
+ }
+ this.mapContext = mapContext;
+ this.mapContext.addMapLayerListListener(this);
+ }
+
+ /*
+ * MAP LAYER LIST LISTENER
+ */
+ public void layerAdded(MapLayerListEvent event) {
+ viewer.refresh();
+ }
+
+ public void layerRemoved(MapLayerListEvent event) {
+ viewer.refresh();
+ }
+
+ public void layerChanged(MapLayerListEvent event) {
+ viewer.refresh();
+ }
+
+ public void layerMoved(MapLayerListEvent event) {
+ viewer.refresh();
+ }
+
+ /*
+ * VIEW
+ */
+ @Override
+ public void setFocus() {
+ viewer.getTree().setFocus();
+ }
+
+ public void refresh() {
+ viewer.refresh();
+ }
+
+ private class MapContextContentProvider implements ITreeContentProvider {
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof MapContext)
+ return new Object[] { new MapContextNode(
+ (MapContext) inputElement) };
+ else if (inputElement instanceof IViewSite)
+ return new Object[] {};
+ else
+ return getChildren(inputElement);
+ }
+
+ public Object[] getChildren(Object element) {
+ if (element instanceof MapContextNode) {
+ MapContextNode mapContextNode = (MapContextNode) element;
+ return mapContextNode.getMapContext().getLayers();
+ } else if (element instanceof MapLayer) {
+ // MapLayer mapLayer = (MapLayer) element;
+
+ } else if (element instanceof TreeParent) {
+ return ((TreeParent) element).getChildren();
+ }
+ return new Object[0];
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof TreeParent) {
+ return ((TreeParent) element).getParent();
+ }
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ if (element instanceof MapContextNode) {
+ return true;
+ } else if (element instanceof TreeParent) {
+ return ((TreeParent) element).hasChildren();
+ } else if (element instanceof MapLayer) {
+ return false;
+ }
+ return false;
+ }
+
+ }
+
+ private class MapContextLabelProvider extends LabelProvider {
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof MapLayer) {
+ MapLayer mapLayer = (MapLayer) element;
+ String title = mapLayer.getTitle();
+ if (title == null || title.trim().equals(""))
+ title = mapLayer.toString();
+ return title;
+ }
+ return super.getText(element);
+ }
+
+ }
+
+ private class MapContextNode extends TreeParent {
+ private MapContext mapContext;
+
+ public MapContextNode(MapContext mapContext) {
+ super("Map Context");
+ this.mapContext = mapContext;
+ }
+
+ public MapContext getMapContext() {
+ return mapContext;
+ }
+
+ }
+}