Hello again folksOn the previous patches I sent regarding UOM support in 2.6.x, I did not include a UomRescaleStyleVisitor class that we are currently using to scale our styles/symbolizers according to the specified unit of measure.
It is currently in our own library, but if you are interested I guess it would be nice to have in GeoTools itself. Check it out.. (attached file)
Cheers Milton -- Milton Jonathan Grupo GIS e Meio Ambiente Tecgraf/PUC-Rio Tel: +55-21-3527-2502
package org.tecgraf.tdk.style.visitor; import javax.measure.converter.UnitConverter; import javax.measure.quantity.Length; import javax.measure.unit.NonSI; import javax.measure.unit.SI; import javax.measure.unit.Unit; import org.geotools.styling.Graphic; import org.geotools.styling.LineSymbolizer; import org.geotools.styling.PointSymbolizer; import org.geotools.styling.PolygonSymbolizer; import org.geotools.styling.Stroke; import org.geotools.styling.visitor.DuplicatingStyleVisitor; import org.opengis.filter.expression.Expression; /** * Visitor used for rescaling a Style given a map scale (e.g., meters per pixel) * and taking into consideration the Unit of Measure (UOM, e.g., SI.METER, * NonSI.FOOT) of each symbolizer. The resulting Style's Symbolizer sizes will * all be given in PIXELS, so that they can be directly used by a renderer that * is unaware of units of measure or the current map scale. For example, points * with size == 100 meters could be rescaled to 10 pixels for higher levels of * zoom and 2 pixels for a lower level of zoom. * <p> * This visitor extends {...@link DuplicatingStyleVisitor} and as such yields a * copy of the original Style. Usage is simply to call the desired visit() * method and then call getCopy() to retrieve the result. * * @author milton */ public class UomRescaleStyleVisitor extends DuplicatingStyleVisitor { private double _mapScale = 1; /** * Constructor: requires the current mapScale to inform the window to * viewport (world to screen) relation in order to correctly rescale sizes * according to units of measure given in world units (e.g., SI.METER, * NonSI.FOOT, etc). * * @param mapScale The specified map scale, given in pixels per meter. */ public UomRescaleStyleVisitor(double mapScale) { if (mapScale <= 0) throw new IllegalArgumentException("mapScale must be positive."); _mapScale = mapScale; } /** * Used to rescale the provided unscaled value. * * @param unscaled the unscaled value. * @param mapScale the mapScale in pixel per meter. * @param uom the uom that will be used to scale. * @return expr multiplied by the provided scale */ protected Expression rescale(Expression unscaled, double mapScale, Unit<Length> uom) { if (unscaled == null || unscaled.equals(Expression.NIL)) return unscaled; double rescaled = rescale(unscaled.evaluate(null, Double.class), mapScale, uom); return ff.literal(rescaled); } /** * Used to rescale the provided unscaled value. * <p> * We do optimize the case where the provided expression is a literal; no * sense doing a calculation each time if we don't have to. * * @param unscaled the unscaled value. * @param mapScale the mapScale in pixel per meter. * @param uom the uom that will be used to scale. * @return an scaled value. */ protected double rescale(double unscaled, double mapScale, Unit<Length> uom) { // no scaling to do if UOM is PIXEL (or null, which stands for PIXEL as // well) if (uom == null || uom.equals(NonSI.PIXEL)) return unscaled; // computes the scale value for meters given the mapScale double scaledMetersToPixel = unscaled * mapScale; // converts value from meters to given UOM UnitConverter converter = uom.getConverterTo(SI.METER); double rescaled = converter.convert(scaledMetersToPixel); // asserts that the value is at least 1 (pixel size < 1 is invalid) return Math.max(1, rescaled); } @Override public void visit(PointSymbolizer ps) { super.visit(ps); PointSymbolizer copy = (PointSymbolizer) pages.peek(); Graphic copyGraphic = copy.getGraphic(); copyGraphic.setSize(rescale(copyGraphic.getSize(), _mapScale, copy.getUnitOfMeasure())); } @Override public void visit(LineSymbolizer line) { super.visit(line); LineSymbolizer copy = (LineSymbolizer) pages.peek(); Stroke copyStroke = copy.getStroke(); copyStroke.setWidth(rescale(copyStroke.getWidth(), _mapScale, copy.getUnitOfMeasure())); } @Override public void visit(PolygonSymbolizer poly) { super.visit(poly); PolygonSymbolizer copy = (PolygonSymbolizer) pages.peek(); Stroke copyStroke = copy.getStroke(); copyStroke.setWidth(rescale(copyStroke.getWidth(), _mapScale, copy.getUnitOfMeasure())); } }
------------------------------------------------------------------------------ Crystal Reports - New Free Runtime and 30 Day Trial Check out the new simplified licensing option that enables unlimited royalty-free distribution of the report engine for externally facing server and web deployment. http://p.sf.net/sfu/businessobjects
_______________________________________________ Geotools-devel mailing list Geotools-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/geotools-devel