Improve GIS
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 28 May 2011 13:31:33 +0000 (13:31 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 28 May 2011 13:31:33 +0000 (13:31 +0000)
NEW - bug 31: Add Swing based map viewer in RCP
https://bugzilla.argeo.org/show_bug.cgi?id=31

git-svn-id: https://svn.argeo.org/commons/trunk@4542 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/MANIFEST.MF
gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapViewer.java
gis/plugins/org.argeo.gis.ui.rcp.swing/META-INF/MANIFEST.MF
gis/plugins/org.argeo.gis.ui.rcp.swing/src/main/java/org/argeo/gis/ui/rcp/swing/SwingMapViewer.java
gis/plugins/org.argeo.gis.ui/META-INF/MANIFEST.MF
gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/AbstractMapViewer.java
gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapViewer.java
gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/FeatureSourcesView.java
gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/styling/StylingUtils.java [new file with mode: 0644]

index 2c9e381913b1bf73e01f4ee2d70e34eb753a795f..da51ec2bacae6d4bdddc86ad20ada1c56a4b0da2 100644 (file)
@@ -22,6 +22,7 @@ Import-Package: com.vividsolutions.jts.geom;version="1.10.0",
  org.geotools.feature,
  org.geotools.map,
  org.geotools.map.event,
+ org.geotools.styling,
  org.opengis.feature,
  org.opengis.feature.simple,
  org.opengis.feature.type,
index 59d99a41e1d652507e12824b5a9c87d1fe585b34..d542ab10463f710e0ec6ef4294619c0bf0e3c8d2 100644 (file)
@@ -164,11 +164,10 @@ public class OpenLayersMapViewer extends AbstractMapViewer implements
        }
 
        @Override
-       protected void addFeatureSource(String path,
-                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource) {
+       protected void addFeatureSource(String layerId,
+                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource, Object style) {
                FeatureIterator<SimpleFeature> featureIterator = null;
                try {
-                       String layerId = path;
                        VectorLayer vectorLayer = new VectorLayer(featureSource.getName()
                                        .toString());
                        vectorLayer.setObjAttr("id", layerId);
index 4a2380d14b6a183e76c7a1a24b2c9c7437b4452e..ec2f58143b67410214cb27580e591fb45ae32de2 100644 (file)
@@ -7,6 +7,7 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Import-Package: com.vividsolutions.jts.geom;version="1.10.0",
  javax.jcr;version="2.0.0",
  org.argeo.geotools.jcr,
+ org.argeo.geotools.styling,
  org.argeo.gis.ui,
  org.eclipse.swt,
  org.eclipse.swt.awt,
@@ -17,6 +18,7 @@ Import-Package: com.vividsolutions.jts.geom;version="1.10.0",
  org.geotools.map,
  org.geotools.renderer,
  org.geotools.renderer.lite,
+ org.geotools.styling,
  org.geotools.swing,
  org.geotools.swing.event,
  org.geotools.swing.tool,
index dd272b45a695b0f7d4ac908421c8669426b76a53..41c03ab21a63585aee255aea5d1969648d4f84d5 100644 (file)
@@ -2,26 +2,39 @@ package org.argeo.gis.ui.rcp.swing;
 
 import java.awt.Color;
 import java.awt.Frame;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.jcr.Node;
 
 import org.argeo.geotools.jcr.GeoJcrMapper;
+import org.argeo.geotools.styling.StylingUtils;
 import org.argeo.gis.ui.AbstractMapViewer;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.awt.SWT_AWT;
 import org.eclipse.swt.widgets.Composite;
 import org.geotools.data.FeatureSource;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.map.DefaultMapContext;
+import org.geotools.map.DefaultMapLayer;
+import org.geotools.map.MapLayer;
 import org.geotools.renderer.lite.StreamingRenderer;
+import org.geotools.styling.Style;
 import org.geotools.swing.JMapPane;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
 
+/** Map viewer implementation based on GeoTools Swing components. */
 public class SwingMapViewer extends AbstractMapViewer {
        private Composite embedded;
        private JMapPane mapPane;
        private VersatileZoomTool versatileZoomTool;
 
+       private Map<String, MapLayer> mapLayers = Collections
+                       .synchronizedMap(new HashMap<String, MapLayer>());
+
        public SwingMapViewer(Node context, GeoJcrMapper geoJcrMapper,
                        Composite parent) {
                super(context, geoJcrMapper);
@@ -40,11 +53,35 @@ public class SwingMapViewer extends AbstractMapViewer {
        }
 
        @Override
-       protected void addFeatureSource(String path,
-                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource) {
-               // TODO: deal with style and rasters
-               mapPane.getMapContext().addLayer(featureSource, null);
-               mapPane.reset();
+       protected void addFeatureSource(String layerId,
+                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource,
+                       Object style) {
+               if (style == null)
+                       style = StylingUtils.createLineStyle("BLACK", 1);
+
+               MapLayer mapLayer = new DefaultMapLayer(featureSource, (Style) style);
+               addMapLayer(layerId, mapLayer);
+       }
+
+       protected void addMapLayer(String layerId, MapLayer mapLayer) {
+               mapLayers.put(layerId, mapLayer);
+               mapPane.getMapContext().addLayer(mapLayer);
+       }
+
+       public void addLayer(String layerId, Collection<?> collection, Object style) {
+               if (style == null)
+                       style = StylingUtils.createLineStyle("BLACK", 1);
+               MapLayer mapLayer = new DefaultMapLayer(collection, (Style) style);
+               addMapLayer(layerId, mapLayer);
+       }
+
+       public void setStyle(String layerId, Object style) {
+               mapLayers.get(layerId).setStyle((Style) style);
+       }
+
+       public void setAreaOfInterest(ReferencedEnvelope areaOfInterest) {
+               // mapPane.getMapContext().setAreaOfInterest(areaOfInterest);
+               mapPane.setDisplayArea(areaOfInterest);
        }
 
 }
index 3b8758230111cb0af5a7743b57573d1489549ae1..04cf35700989ca9954da9235775458da6bc9579e 100644 (file)
@@ -25,8 +25,10 @@ Import-Package: javax.jcr;version="2.0.0",
  org.eclipse.ui.forms.editor,
  org.eclipse.ui.forms.widgets,
  org.geotools.data,
+ org.geotools.geometry.jts,
  org.geotools.map,
  org.geotools.map.event,
+ org.geotools.styling,
  org.opengis.feature.simple,
  org.opengis.feature.type,
  org.postgresql;resolution:=optional
index d767f22772fb1317431bebfce92696ea8390b3b0..eeb9a21830c9ad51b326485251e2b2c40064c98a 100644 (file)
@@ -18,6 +18,7 @@ import org.argeo.jcr.CollectionNodeIterator;
 import org.argeo.jcr.gis.GisTypes;
 import org.eclipse.swt.widgets.Composite;
 import org.geotools.data.FeatureSource;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
 
@@ -35,8 +36,9 @@ public abstract class AbstractMapViewer implements MapViewer {
        private Set<MapViewerListener> listeners = Collections
                        .synchronizedSet(new HashSet<MapViewerListener>());
 
-       protected abstract void addFeatureSource(String path,
-                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource);
+       protected abstract void addFeatureSource(String layerId,
+                       FeatureSource<SimpleFeatureType, SimpleFeature> featureSource,
+                       Object style);
 
        public AbstractMapViewer(Node context, GeoJcrMapper geoJcrMapper) {
                super();
@@ -44,11 +46,13 @@ public abstract class AbstractMapViewer implements MapViewer {
                this.geoJcrMapper = geoJcrMapper;
        }
 
-       public void addLayer(Node layer) {
+       public void addLayer(Node layer, Object style) {
                try {
                        if (layer.isNodeType(GisTypes.GIS_FEATURE_SOURCE)) {
                                addFeatureSource(layer.getPath(),
-                                               geoJcrMapper.getFeatureSource(layer));
+                                               geoJcrMapper.getFeatureSource(layer), style);
+                       } else {
+                               throw new ArgeoException("Unsupported layer " + layer);
                        }
                } catch (Exception e) {
                        throw new ArgeoException("Cannot add layer " + layer, e);
@@ -103,4 +107,8 @@ public abstract class AbstractMapViewer implements MapViewer {
                return control;
        }
 
+       public GeoJcrMapper getGeoJcrMapper() {
+               return geoJcrMapper;
+       }
+
 }
index 701ef59a27373a86e8f330b06763420522437683..8a56e93c3969ed581bfa102877344dd8ba8bc945 100644 (file)
@@ -1,12 +1,19 @@
 package org.argeo.gis.ui;
 
+import java.util.Collection;
+
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
 
+import org.argeo.geotools.jcr.GeoJcrMapper;
 import org.eclipse.swt.widgets.Composite;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 
+/** Viewer for a map, relying on JCR. */
 public interface MapViewer {
-       public void addLayer(Node layer);
+       public void addLayer(Node layer, Object style);
+
+       public void addLayer(String layerId, Collection<?> collection, Object style);
 
        public NodeIterator getSelectedFeatures();
 
@@ -16,4 +23,9 @@ public interface MapViewer {
 
        public void removeMapViewerListener(MapViewerListener listener);
 
+       public void setAreaOfInterest(ReferencedEnvelope areaOfInterest);
+
+       public void setStyle(String layerId, Object style);
+
+       public GeoJcrMapper getGeoJcrMapper();
 }
index b13daaf839108d6f7091ac47826322a11238ca00..5a22e27e6aac94ba7d5d233453c428d52144e843 100644 (file)
@@ -14,7 +14,6 @@ import org.eclipse.jface.viewers.ColumnLabelProvider;
 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.graphics.Image;
@@ -60,13 +59,13 @@ public class FeatureSourcesView extends ViewPart implements
                                IEditorPart ed = getSite().getWorkbenchWindow().getActivePage()
                                                .getActiveEditor();
                                if (ed instanceof DefaultMapEditor) {
-                                       ((DefaultMapEditor) ed).getMapViewer().addLayer(node);
+                                       ((DefaultMapEditor) ed).getMapViewer().addLayer(node, null);
                                } else if (ed instanceof FormEditor) {
                                        IFormPage activePage = ((FormEditor) ed)
                                                        .getActivePageInstance();
                                        if (activePage instanceof MapFormPage) {
-                                               ((MapFormPage) activePage).getMapViewer()
-                                                               .addLayer(node);
+                                               ((MapFormPage) activePage).getMapViewer().addLayer(
+                                                               node, null);
                                        }
                                }
                        }
diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/styling/StylingUtils.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/styling/StylingUtils.java
new file mode 100644 (file)
index 0000000..a4811ac
--- /dev/null
@@ -0,0 +1,103 @@
+package org.argeo.geotools.styling;
+
+import java.awt.Color;
+
+import org.argeo.ArgeoException;
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.filter.text.cql2.CQL;
+import org.geotools.filter.text.cql2.CQLException;
+import org.geotools.styling.FeatureTypeStyle;
+import org.geotools.styling.LineSymbolizer;
+import org.geotools.styling.Rule;
+import org.geotools.styling.Stroke;
+import org.geotools.styling.Style;
+import org.geotools.styling.StyleFactory;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory;
+
+/** Utilities related to GeoTools styling */
+public class StylingUtils {
+       static StyleFactory styleFactory = CommonFactoryFinder
+                       .getStyleFactory(null);
+       static FilterFactory filterFactory = CommonFactoryFinder
+                       .getFilterFactory(null);
+
+       /**
+        * Style for a line
+        * 
+        * @param color
+        *            the AWT color in upper case
+        * @param width
+        *            the width of the line
+        * @param cqlFilter
+        *            filter in CQL formqt restricting the feqture upon which the
+        *            style will apply
+        */
+       public static Style createLineStyle(String color, Integer width) {
+               Rule rule = styleFactory.createRule();
+               rule.symbolizers().add(createLineSymbolizer(color, width));
+               FeatureTypeStyle fts = styleFactory
+                               .createFeatureTypeStyle(new Rule[] { rule });
+               Style style = styleFactory.createStyle();
+               style.featureTypeStyles().add(fts);
+               return style;
+       }
+
+       public static Style createFilteredLineStyle(String cqlFilter,
+                       String matchedColor, Integer matchedWidth, String unmatchedColor,
+                       Integer unmatchedWidth) {
+               // selection filter
+               Filter filter;
+               try {
+                       filter = CQL.toFilter(cqlFilter);
+               } catch (CQLException e) {
+                       throw new ArgeoException("Cannot parse CQL filter: " + cqlFilter, e);
+               }
+
+               Rule[] rules;
+               // matched
+               Rule ruleMatched = styleFactory.createRule();
+               ruleMatched.symbolizers().add(
+                               createLineSymbolizer(matchedColor, matchedWidth));
+               ruleMatched.setFilter(filter);
+
+               // unmatched
+               if (unmatchedColor != null) {
+                       Rule ruleUnMatched = styleFactory.createRule();
+                       ruleUnMatched.symbolizers().add(
+                                       createLineSymbolizer(unmatchedColor,
+                                                       unmatchedWidth != null ? unmatchedWidth
+                                                                       : matchedWidth));
+                       ruleUnMatched.setFilter(filterFactory.not(filter));
+                       rules = new Rule[] { ruleMatched, ruleUnMatched };
+               } else {
+                       rules = new Rule[] { ruleMatched };
+               }
+
+               FeatureTypeStyle fts = styleFactory.createFeatureTypeStyle(rules);
+               Style style = styleFactory.createStyle();
+               style.featureTypeStyles().add(fts);
+               return style;
+       }
+
+       public static LineSymbolizer createLineSymbolizer(String color,
+                       Integer width) {
+               Stroke stroke = styleFactory.createStroke(
+                               filterFactory.literal(stringToColor(color)),
+                               filterFactory.literal(width));
+               return styleFactory.createLineSymbolizer(stroke, null);
+       }
+
+       /**
+        * Converts a string to a color, using reflection, so that other methods
+        * don't need AWT dependencies in their signature. Package protected and not
+        * public so that it has less impact on the overall signature.
+        */
+       static Color stringToColor(String color) {
+               try {
+                       return (Color) Color.class.getField(color).get(null);
+               } catch (Exception e) {
+                       throw new ArgeoException("Color " + color + " not found", e);
+               }
+       }
+}