org.geotools.feature,
org.geotools.map,
org.geotools.map.event,
+ org.geotools.styling,
org.opengis.feature,
org.opengis.feature.simple,
org.opengis.feature.type,
}
@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);
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,
org.geotools.map,
org.geotools.renderer,
org.geotools.renderer.lite,
+ org.geotools.styling,
org.geotools.swing,
org.geotools.swing.event,
org.geotools.swing.tool,
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);
}
@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);
}
}
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
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;
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();
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);
return control;
}
+ public GeoJcrMapper getGeoJcrMapper() {
+ return geoJcrMapper;
+ }
+
}
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();
public void removeMapViewerListener(MapViewerListener listener);
+ public void setAreaOfInterest(ReferencedEnvelope areaOfInterest);
+
+ public void setStyle(String layerId, Object style);
+
+ public GeoJcrMapper getGeoJcrMapper();
}
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;
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);
}
}
}
--- /dev/null
+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);
+ }
+ }
+}