|
|
|
svn_geotools
|
Author: mbedward
Date: 2009-11-04 04:44:13 -0500 (Wed, 04 Nov 2009) New Revision: 34317 Added: branches/2.6.x/demo/example/src/main/java/org/geotools/demo/StyleFunctionLab.java Log: new example showing a filter function used to set fill and stroke colours for features based on a selected feature attribute Added: branches/2.6.x/demo/example/src/main/java/org/geotools/demo/StyleFunctionLab.java =================================================================== --- branches/2.6.x/demo/example/src/main/java/org/geotools/demo/StyleFunctionLab.java (rev 0) +++ branches/2.6.x/demo/example/src/main/java/org/geotools/demo/StyleFunctionLab.java 2009-11-04 09:44:13 UTC (rev 34317) @@ -0,0 +1,238 @@ +/* + * GeoTools - The Open Source Java GIS Tookit + * http://geotools.org + * + * (C) 2006-2008, Open Source Geospatial Foundation (OSGeo) + * + * This file is hereby placed into the Public Domain. This means anyone is + * free to do whatever they wish with this file. Use it well and enjoy! + */ + +package org.geotools.demo; + +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.geom.Polygon; +import java.awt.Color; +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.swing.JOptionPane; +import org.geotools.data.FeatureSource; +import org.geotools.data.FileDataStore; +import org.geotools.data.FileDataStoreFinder; +import org.geotools.factory.CommonFactoryFinder; +import org.geotools.feature.FeatureCollection; +import org.geotools.feature.visitor.UniqueVisitor; +import org.geotools.filter.FunctionExpressionImpl; +import org.geotools.map.DefaultMapContext; +import org.geotools.map.MapContext; +import org.geotools.styling.Fill; +import org.geotools.styling.Graphic; +import org.geotools.styling.Mark; +import org.geotools.styling.SLD; +import org.geotools.styling.Stroke; +import org.geotools.styling.Style; +import org.geotools.styling.StyleFactory; +import org.geotools.styling.Symbolizer; +import org.geotools.swing.JMapFrame; +import org.geotools.swing.data.JFileDataStoreChooser; +import org.opengis.feature.type.FeatureType; +import org.opengis.feature.type.PropertyDescriptor; +import org.opengis.filter.FilterFactory2; +import org.opengis.filter.expression.Expression; + + +public class StyleFunctionLab { + + public static void main(String[] args) throws Exception { + File file = JFileDataStoreChooser.showOpenFile("shp", null); + if (file == null) { + return; + } + + StyleFunctionLab me = new StyleFunctionLab(); + me.displayShapefile(file); + } + + /** + * Display + * @param file + * @throws Exception + */ + private void displayShapefile(File file) throws Exception { + FileDataStore store = FileDataStoreFinder.getDataStore(file); + FeatureSource featureSource = store.getFeatureSource(); + + // Create a map context and add our shapefile to it + MapContext map = new DefaultMapContext(); + map.setTitle("Filter Function Lab"); + + FeatureType type = featureSource.getSchema(); + PropertyDescriptor geomDesc = type.getGeometryDescriptor(); + List<String> attributeNames = new ArrayList<String>(); + for (PropertyDescriptor desc : type.getDescriptors()) { + if (!desc.equals(geomDesc)) { + attributeNames.add(desc.getName().getLocalPart()); + } + } + + Object selection = JOptionPane.showInputDialog(null, + "Unique values of the attribute will be used to create a colour lookup table", + "Select feature attribute", + JOptionPane.PLAIN_MESSAGE, null, + attributeNames.toArray(), null); + + if (selection != null) { + Style style = createStyle(featureSource, (String)selection); + map.addLayer(featureSource, style); + + // Now display the map + JMapFrame.showMap(map); + } + } + + /** + * Create a rendering style to display features from the given feature source + * by matching unique values of the specified feature attribute to colours + * + * @param featureSource the feature source + * @return a new Style instance + */ + private Style createStyle(FeatureSource featureSource, String attributeName) + throws Exception { + + FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null); + StyleFactory sf = CommonFactoryFinder.getStyleFactory(null); + + UniqueColourFunction colourFn = new UniqueColourFunction( + featureSource.getFeatures(), ff.property(attributeName)); + Fill fill = sf.createFill(colourFn); + Stroke stroke = sf.createStroke(colourFn, ff.literal(1.0f)); + + Class<?> geomClass = featureSource.getSchema().getGeometryDescriptor().getType().getBinding(); + Symbolizer sym = null; + if (Polygon.class.isAssignableFrom(geomClass) || + MultiPolygon.class.isAssignableFrom(geomClass)) { + + sym = sf.createPolygonSymbolizer(stroke, fill, null); + + } else if (LineString.class.isAssignableFrom(geomClass) || + MultiLineString.class.isAssignableFrom(geomClass)) { + sym = sf.createLineSymbolizer(stroke, null); + + } else { + Graphic gr = sf.createDefaultGraphic(); + gr.graphicalSymbols().clear(); + Mark mark = sf.getCircleMark(); + mark.setFill(fill); + mark.setStroke(stroke); + gr.graphicalSymbols().add(mark); + gr.setSize(ff.literal(10.0f)); + sym = sf.createPointSymbolizer(gr, null); + } + + Style style = SLD.wrapSymbolizers(sym); + return style; + } + + + /** + * A function to dynamically allocate colours to features. It works with a lookup table + * where the key is a user-specified feature attribute. Colours are generated using + * a simple colour ramp algorithm. + */ + static class UniqueColourFunction extends FunctionExpressionImpl { + + private static final float INITIAL_HUE = 0.1f; + private final FeatureCollection collection; + + Map<Object, Color> lookup; + private int numColours; + + private float hue; + private float hueIncr; + private float saturation = 0.7f; + private float brightness = 0.7f; + + + /** + * Creates an instance of the function for the given feature collection. Features will + * be assigned fill colours by matching the value of the specified feature attribute + * in a lookup table of unique attribute values with associated colours. + * + * @param collection the feature collection + * + * @param colourAttribute a literal expression that specifies the feature attribute + * to use for colour lookup + */ + public UniqueColourFunction(FeatureCollection collection, Expression colourAttribute) { + super("UniqueColour"); + this.collection = collection; + + this.params.add(colourAttribute); + this.fallback = CommonFactoryFinder.getFilterFactory2(null).literal(Color.WHITE); + } + + @Override + public int getArgCount() { + return 1; + } + + /** + * Evalute this function for a given feature and return a + * Color. + * + * @param object the feature for which a colour is being requested + * + * @return the colour for this feature + */ + @Override + public Object evaluate(Object feature) { + if (lookup == null) { + createLookup(); + } + + Object key = ((Expression)params.get(0)).evaluate(feature); + Color color = lookup.get(key); + if (color == null) { + color = addColor(key); + } + + return color; + } + + /** + * Creates the lookup table and initializes variables used in + * colour generation + */ + private void createLookup() { + lookup = new HashMap<Object, Color>(); + try { + UniqueVisitor visitor = new UniqueVisitor((Expression)params.get(0)); + collection.accepts(visitor, null); + numColours = visitor.getUnique().size(); + hue = INITIAL_HUE; + hueIncr = (1.0f - hue) / numColours; + + } catch (Exception ex) { + throw new IllegalStateException("Problem creating colour lookup", ex); + } + } + + /* + * Generates a new colour for the colour ramp and adds it to + * the lookup table + */ + private Color addColor(Object key) { + Color c = new Color(Color.HSBtoRGB(hue, saturation, brightness)); + hue += hueIncr; + lookup.put(key, c); + return c; + } + } +} + ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ GeoTools-commits mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/geotools-commits |
||||||||||||||||
| Free Embeddable Forum Powered by Nabble | Help |