package org.geotools.styling.builder; import static org.junit.Assert.*; import java.awt.Color; import java.util.Arrays; import java.util.List; import javax.measure.unit.SI; import org.geotools.filter.function.RecodeFunction; import org.geotools.styling.LineSymbolizer; import org.geotools.styling.PointPlacement; import org.geotools.styling.Rule; import org.geotools.styling.Style; import org.geotools.styling.TextSymbolizer; import org.junit.Test; import org.opengis.filter.expression.Function; import org.opengis.style.Graphic; import org.opengis.style.GraphicalSymbol; import org.opengis.style.LinePlacement; import org.opengis.style.Mark; /** * * * @source $URL$ */ public class CookbookLineTest extends AbstractStyleTest { @Test public void testSimple() { Style style = new StrokeBuilder().color(Color.BLACK).width(3).buildStyle(); // print(style); // round up the basic elements and check its simple StyleCollector collector = new StyleCollector(); style.accept(collector); assertSimpleStyle(collector); // check the size LineSymbolizer ls = (LineSymbolizer) collector.symbolizers.get(0); assertEquals(3, (int) ls.getStroke().getWidth().evaluate(null, Integer.class)); assertEquals(Color.BLACK, (Color) ls.getStroke().getColor().evaluate(null, Color.class)); } @Test public void testLineWithBorder() { StyleBuilder sb = new StyleBuilder(); sb.featureTypeStyle().rule().line().stroke().colorHex("#333333").width(5) .lineCapName("round"); sb.featureTypeStyle().rule().line().stroke().colorHex("#6699FF").width(3) .lineCapName("round"); Style style = sb.buildStyle(); // print(style); // round up the basic elements and check its simple StyleCollector collector = new StyleCollector(); style.accept(collector); assertEquals(2, collector.featureTypeStyles.size()); assertEquals(2, collector.rules.size()); assertEquals(2, collector.symbolizers.size()); // check the first line LineSymbolizer ls = (LineSymbolizer) collector.symbolizers.get(0); assertEquals(5, (int) ls.getStroke().getWidth().evaluate(null, Integer.class)); assertEquals("#333333", (String) ls.getStroke().getColor().evaluate(null, String.class)); // check the second line ls = (LineSymbolizer) collector.symbolizers.get(1); assertEquals(3, (int) ls.getStroke().getWidth().evaluate(null, Integer.class)); assertEquals("#6699FF", (String) ls.getStroke().getColor().evaluate(null, String.class)); } @Test public void testDashed() { Style style = new StrokeBuilder().color(Color.BLUE).width(3).dashArray(5, 2).buildStyle(); // print(style); // round up the basic elements and check its simple StyleCollector collector = new StyleCollector(); style.accept(collector); assertSimpleStyle(collector); // check the size LineSymbolizer ls = (LineSymbolizer) collector.symbolizers.get(0); assertEquals(3, (int) ls.getStroke().getWidth().evaluate(null, Integer.class)); assertEquals(Color.BLUE, (Color) ls.getStroke().getColor().evaluate(null, Color.class)); assertTrue(Arrays.equals(new float[] { 5, 2 }, ls.getStroke().getDashArray())); } @Test public void testRailroad() { FeatureTypeStyleBuilder fts = new FeatureTypeStyleBuilder(); fts.rule().line().stroke().colorHex("#333333").width(3); fts.rule().line().stroke().graphicStroke().size(12).mark().name("shape://vertline") .stroke().colorHex("#333333").width(1); Style style = fts.buildStyle(); // print(style); // round up the elements and check the basics StyleCollector collector = new StyleCollector(); style.accept(collector); assertEquals(1, collector.featureTypeStyles.size()); assertEquals(2, collector.rules.size()); assertEquals(2, collector.symbolizers.size()); // check the simple line LineSymbolizer ls = (LineSymbolizer) collector.symbolizers.get(0); assertEquals(3, (int) ls.getStroke().getWidth().evaluate(null, Integer.class)); assertEquals("#333333", (String) ls.getStroke().getColor().evaluate(null, String.class)); // check the rail ls = (LineSymbolizer) collector.symbolizers.get(1); Graphic graphic = ls.getStroke().getGraphicStroke(); List<GraphicalSymbol> symbols = graphic.graphicalSymbols(); assertEquals(1, symbols.size()); Mark mark = (Mark) symbols.get(0); assertEquals("shape://vertline", mark.getWellKnownName().evaluate(null)); assertEquals("#333333", mark.getStroke().getColor().evaluate(null, String.class)); assertEquals(1, (int) mark.getStroke().getWidth().evaluate(null, Integer.class)); } @Test public void testSpacedGraphics() { MarkBuilder mb = new StrokeBuilder().dashArray(4, 6).graphicStroke().size(4).mark() .name("circle"); mb.stroke().colorHex("#333333").width(1); mb.fill().colorHex("#666666"); Style style = mb.buildStyle(); // print(style); // round up the basic elements and check its simple StyleCollector collector = new StyleCollector(); style.accept(collector); assertSimpleStyle(collector); // check the dots LineSymbolizer ls = (LineSymbolizer) collector.symbolizers.get(0); assertTrue(Arrays.equals(new float[] { 4, 6 }, ls.getStroke().getDashArray())); Graphic graphic = ls.getStroke().getGraphicStroke(); List<GraphicalSymbol> symbols = graphic.graphicalSymbols(); assertEquals(1, symbols.size()); Mark mark = (Mark) symbols.get(0); assertEquals("circle", mark.getWellKnownName().evaluate(null)); assertEquals("#333333", mark.getStroke().getColor().evaluate(null, String.class)); assertEquals(1, (int) mark.getStroke().getWidth().evaluate(null, Integer.class)); assertEquals("#666666", mark.getFill().getColor().evaluate(null, String.class)); } @Test public void testAlternatingSymbols() { RuleBuilder rb = new RuleBuilder(); rb.line().stroke().color(Color.BLUE).dashArray(10, 10); rb.line().stroke().dashArray(5, 15).dashOffset(7.5).graphicStroke().mark() .name("circle").stroke().colorHex("#000033"); Style style = rb.buildStyle(); // print(style); // round up the elements and check the basics StyleCollector collector = new StyleCollector(); style.accept(collector); assertEquals(1, collector.featureTypeStyles.size()); assertEquals(1, collector.rules.size()); assertEquals(2, collector.symbolizers.size()); // check the line LineSymbolizer ls = (LineSymbolizer) collector.symbolizers.get(0); assertEquals(1, (int) ls.getStroke().getWidth().evaluate(null, Integer.class)); assertEquals(Color.BLUE, (Color) ls.getStroke().getColor().evaluate(null, Color.class)); assertTrue(Arrays.equals(new float[] { 10, 10 }, ls.getStroke().getDashArray())); // check the dots ls = (LineSymbolizer) collector.symbolizers.get(1); assertTrue(Arrays.equals(new float[] { 5, 15 }, ls.getStroke().getDashArray())); assertEquals(7.5, ls.getStroke().getDashOffset().evaluate(null, Double.class), 0.0); Graphic graphic = ls.getStroke().getGraphicStroke(); List<GraphicalSymbol> symbols = graphic.graphicalSymbols(); assertEquals(1, symbols.size()); Mark mark = (Mark) symbols.get(0); assertEquals("circle", mark.getWellKnownName().evaluate(null)); assertEquals("#000033", mark.getStroke().getColor().evaluate(null, String.class)); assertEquals(1, (int) mark.getStroke().getWidth().evaluate(null, Integer.class)); assertNull(mark.getFill()); } @Test public void testLineDefaultLabels() { RuleBuilder rb = new RuleBuilder(); rb.line().stroke().color(Color.RED); rb.text().label("name").fill().color(Color.BLACK); Style style = rb.buildStyle(); // print(style); // round up the elements and check the basics StyleCollector collector = new StyleCollector(); style.accept(collector); assertEquals(1, collector.featureTypeStyles.size()); assertEquals(1, collector.rules.size()); assertEquals(2, collector.symbolizers.size()); TextSymbolizer ps = (TextSymbolizer) collector.symbolizers.get(1); assertEquals(ff.property("name"), ps.getLabel()); assertEquals(Color.BLACK, ps.getFill().getColor().evaluate(null, Color.class)); // placement PointPlacement pp = (PointPlacement) ps.getLabelPlacement(); assertEquals(0, pp.getRotation().evaluate(null, Double.class), 0.0); assertEquals(0., pp.getAnchorPoint().getAnchorPointX().evaluate(null, Double.class), 0); assertEquals(0, pp.getAnchorPoint().getAnchorPointY().evaluate(null, Double.class), 0); } @Test public void testLineOptimizedLabels() { RuleBuilder rb = new RuleBuilder(); rb.line().stroke().color(Color.RED); TextSymbolizerBuilder tsb = rb.text().label("name").option("followLine", true) .option("maxAngleDelta", 90).option("maxDisplacement", 400).option("repeat", 150); tsb.linePlacement(); tsb.fill().color(Color.BLACK); Style style = rb.buildStyle(); // print(style); // round up the elements and check the basics StyleCollector collector = new StyleCollector(); style.accept(collector); assertEquals(1, collector.featureTypeStyles.size()); assertEquals(1, collector.rules.size()); assertEquals(2, collector.symbolizers.size()); TextSymbolizer ts = (TextSymbolizer) collector.symbolizers.get(1); assertEquals(ff.property("name"), ts.getLabel()); assertEquals(Color.BLACK, ts.getFill().getColor().evaluate(null, Color.class)); assertEquals(4, ts.getOptions().size()); // placement assertTrue(ts.getLabelPlacement() instanceof LinePlacement); } @Test public void testAttributeBased() { FeatureTypeStyleBuilder fts = new FeatureTypeStyleBuilder(); fts.rule().filter("type = 'local-road'").line().stroke().colorHex("#009933").width(2); fts.rule().filter("type = 'secondary'").line().stroke().colorHex("#0055CC").width(3); fts.rule().filter("type = 'highway'").line().stroke().colorHex("#FF0000").width(6); Style style = fts.buildStyle(); // print(style); // round up the elements and check the basics StyleCollector collector = new StyleCollector(); style.accept(collector); assertEquals(1, collector.featureTypeStyles.size()); assertEquals(3, collector.rules.size()); assertEquals(3, collector.symbolizers.size()); // check rules assertEquals(ff.equals(ff.property("type"), ff.literal("local-road")), collector.rules.get(0).getFilter()); assertEquals(ff.equals(ff.property("type"), ff.literal("secondary")), collector.rules .get(1).getFilter()); assertEquals(ff.equals(ff.property("type"), ff.literal("highway")), collector.rules.get(2) .getFilter()); // check symbolizers LineSymbolizer ls = (LineSymbolizer) collector.symbolizers.get(0); assertEquals(2, (int) ls.getStroke().getWidth().evaluate(null, Integer.class)); assertEquals("#009933", ls.getStroke().getColor().evaluate(null, String.class)); ls = (LineSymbolizer) collector.symbolizers.get(1); assertEquals(3, (int) ls.getStroke().getWidth().evaluate(null, Integer.class)); assertEquals("#0055CC", ls.getStroke().getColor().evaluate(null, String.class)); ls = (LineSymbolizer) collector.symbolizers.get(2); assertEquals(6, (int) ls.getStroke().getWidth().evaluate(null, Integer.class)); assertEquals("#FF0000", ls.getStroke().getColor().evaluate(null, String.class)); } @Test public void testAttributeBasedRecode() { // this is a case showing that recode/categorize is not always the most compact solution... Function width = ff.function("recode", ff.property("type"), ff.literal("local-road"), ff.literal(2), ff.literal("secondary"), ff.literal(3), ff.literal("highway"), ff.literal(6)); Function color = ff.function("recode", ff.property("type"), ff.literal("local-road"), ff.literal("#009933"), ff.literal("secondary"), ff.literal("#0055CC2"), ff.literal("highway"), ff.literal("#FF0000")); Style style = new LineSymbolizerBuilder().stroke().color(color).width(width).buildStyle(); // print(style); StyleCollector collector = new StyleCollector(); style.accept(collector); assertSimpleStyle(collector); // check the function is there were we expect it LineSymbolizer ls = (LineSymbolizer) collector.symbolizers.get(0); assertTrue(ls.getStroke().getColor() instanceof RecodeFunction); assertTrue(ls.getStroke().getWidth() instanceof RecodeFunction); } @Test public void testZoomBasedLine() { FeatureTypeStyleBuilder fts = new FeatureTypeStyleBuilder(); fts.rule().name("Large").max(180000000).line().stroke().colorHex("#009933").width(6); fts.rule().name("Medium").min(180000000).max(360000000).line().stroke() .colorHex("#009933").width(4); fts.rule().name("Small").min(360000000).line().stroke().colorHex("#009933").width(2); Style style = fts.buildStyle(); // print(style); StyleCollector collector = new StyleCollector(); style.accept(collector); assertEquals(1, collector.featureTypeStyles.size()); assertEquals(3, collector.rules.size()); assertEquals(3, collector.symbolizers.size()); // check rules and styles checkScaleBasedRule(collector.rules.get(0), "Large", 0, 180000000, 6); checkScaleBasedRule(collector.rules.get(1), "Medium", 180000000, 360000000, 4); checkScaleBasedRule(collector.rules.get(2), "Small", 360000000, Double.POSITIVE_INFINITY, 2); } private void checkScaleBasedRule(Rule rule, String name, double minDenominator, double maxDenominator, int size) { assertEquals(name, rule.getName()); assertEquals(minDenominator, rule.getMinScaleDenominator(), 0.0); assertEquals(maxDenominator, rule.getMaxScaleDenominator(), 0.0); assertEquals(1, rule.getSymbolizers().length); LineSymbolizer ls = (LineSymbolizer) rule.getSymbolizers()[0]; assertEquals(size, (int) ls.getStroke().getWidth().evaluate(null, Integer.class)); } @Test public void testUomLine() { Style style = new LineSymbolizerBuilder().uom(SI.METER).stroke().width(50) .colorHex("#009933").buildStyle(); // print(style); StyleCollector collector = new StyleCollector(); style.accept(collector); assertSimpleStyle(collector); LineSymbolizer ls = (LineSymbolizer) collector.symbolizers.get(0); assertEquals(SI.METER, ls.getUnitOfMeasure()); } }