001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.styling;
017:
018: import java.awt.Color;
019: import java.io.ByteArrayInputStream;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.net.URL;
023: import java.util.Arrays;
024: import java.util.Set;
025:
026: import junit.framework.Test;
027: import junit.framework.TestCase;
028: import junit.framework.TestSuite;
029:
030: import org.geotools.factory.CommonFactoryFinder;
031: import org.geotools.factory.GeoTools;
032: import org.geotools.test.TestData;
033: import org.opengis.filter.BinaryLogicOperator;
034: import org.opengis.filter.Filter;
035: import org.opengis.filter.FilterFactory;
036: import org.opengis.filter.Id;
037: import org.opengis.filter.Not;
038: import org.opengis.filter.expression.Expression;
039: import org.opengis.filter.expression.Literal;
040: import org.opengis.filter.expression.PropertyName;
041: import org.opengis.filter.spatial.BinarySpatialOperator;
042: import org.opengis.filter.spatial.Disjoint;
043:
044: import com.vividsolutions.jts.geom.Envelope;
045: import com.vividsolutions.jts.geom.Geometry;
046: import com.vividsolutions.jts.geom.Polygon;
047:
048: /**
049: * DOCUMENT ME!
050: *
051: * @author jamesm
052: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/test/java/org/geotools/styling/SLDStyleTest.java $
053: */
054: public class SLDStyleTest extends TestCase {
055: StyleFactory sf = CommonFactoryFinder.getStyleFactory(GeoTools
056: .getDefaultHints());
057: FilterFactory ff = CommonFactoryFinder.getFilterFactory(GeoTools
058: .getDefaultHints());
059: StyleBuilder sb = new StyleBuilder(sf, ff);
060:
061: /**
062: * Creates a new SLDStyleTest object.
063: *
064: * @param testName DOCUMENT ME!
065: */
066: public SLDStyleTest(java.lang.String testName) {
067: super (testName);
068: }
069:
070: /**
071: * DOCUMENT ME!
072: *
073: * @return DOCUMENT ME!
074: */
075: public static Test suite() {
076: TestSuite suite = new TestSuite(SLDStyleTest.class);
077:
078: return suite;
079: }
080:
081: /**
082: * Test of parseStyle method, of class org.geotools.styling.SLDStyle.
083: *
084: * @throws Exception DOCUMENT ME!
085: */
086: public void testParseStyle() throws Exception {
087: //java.net.URL base = getClass().getResource("testData/");
088: // base = getClass().getResource("testData");
089: // base = getClass().getResource("/testData");
090:
091: //java.net.URL surl = new java.net.URL(base + "/test-sld.xml");
092: java.net.URL surl = TestData.getResource(this , "test-sld.xml");
093: SLDParser stylereader = new SLDParser(sf, surl);
094: StyledLayerDescriptor sld = stylereader.parseSLD();
095: assertEquals("My Layer", sld.getName());
096: assertEquals("A layer by me", sld.getTitle());
097: assertEquals("this is a sample layer", sld.getAbstract());
098: assertEquals(1, sld.getStyledLayers().length);
099:
100: UserLayer layer = (UserLayer) sld.getStyledLayers()[0];
101: assertNull(layer.getName());
102: assertEquals(1, layer.getUserStyles().length);
103:
104: Style style = layer.getUserStyles()[0];
105: assertEquals(1, style.getFeatureTypeStyles().length);
106: assertEquals("My User Style", style.getName());
107: assertEquals("A style by me", style.getTitle());
108: assertEquals("this is a sample style", style.getAbstract());
109: assertTrue(style.isDefault());
110:
111: FeatureTypeStyle fts = style.getFeatureTypeStyles()[0];
112: Rule rule = fts.getRules()[0];
113: LineSymbolizer lineSym = (LineSymbolizer) rule.getSymbolizers()[0];
114: assertEquals(4, ((Number) lineSym.getStroke().getWidth()
115: .evaluate(null, Number.class)).intValue());
116: }
117:
118: /**
119: * XML --> SLD --> XML
120: * @throws Exception
121: */
122: public void testSLDParser() throws Exception {
123: java.net.URL surl = TestData.getResource(this ,
124: "example-sld.xml");
125: SLDParser stylereader = new SLDParser(sf, surl);
126: StyledLayerDescriptor sld = stylereader.parseSLD();
127:
128: //convert back to xml again
129: SLDTransformer aTransformer = new SLDTransformer();
130: String xml = aTransformer.transform(sld);
131:
132: assertNotNull(xml);
133: //we're content for the moment if this didn't throw an exception...
134: //TODO: convert the buffer/resource to a string and compare
135: }
136:
137: public void testSLDParserWithWhitespace() throws Exception {
138: java.net.URL surl = TestData
139: .getResource(this , "whitespace.sld");
140: SLDParser stylereader = new SLDParser(sf, surl);
141: StyledLayerDescriptor sld = stylereader.parseSLD();
142:
143: TextSymbolizer ts = (TextSymbolizer) ((NamedLayer) sld
144: .getStyledLayers()[0]).getStyles()[0]
145: .getFeatureTypeStyles()[0].getRules()[0]
146: .getSymbolizers()[0];
147:
148: PropertyName property = (PropertyName) ts.getLabel();
149: assertEquals("testProperty", property.getPropertyName());
150:
151: Expression color = ts.getFill().getColor();
152: assertEquals(Color.BLACK, SLD.color(color));
153: }
154:
155: public void testSLDParserWithhMixedContent() throws Exception {
156: java.net.URL surl = TestData.getResource(this ,
157: "mixedContent.sld");
158: SLDParser stylereader = new SLDParser(sf, surl);
159: StyledLayerDescriptor sld = stylereader.parseSLD();
160:
161: Symbolizer[] symbolizers = ((NamedLayer) sld.getStyledLayers()[0])
162: .getStyles()[0].getFeatureTypeStyles()[0].getRules()[0]
163: .getSymbolizers();
164:
165: PolygonSymbolizer polygon = (PolygonSymbolizer) symbolizers[0];
166: TextSymbolizer text = (TextSymbolizer) symbolizers[1];
167:
168: Expression fill = polygon.getFill().getColor();
169: Expression label = text.getLabel();
170:
171: String fillValue = (String) fill.evaluate(null, String.class);
172: String labelValue = (String) label.evaluate(null, String.class);
173:
174: assertEquals("#96C3F5", fillValue);
175: assertEquals(
176: "this is a prefix; this is an expression; this is a postfix",
177: labelValue);
178: }
179:
180: /**
181: * SLD --> XML --> SLD
182: * @throws Exception
183: */
184: public void testSLDTransformer() throws Exception {
185: //create an SLD
186: StyledLayerDescriptor sld = sf.createStyledLayerDescriptor();
187: StyledLayerDescriptor sld2;
188: sld.setName("SLD Name");
189: sld.setTitle("SLD Title");
190: UserLayer layer = sf.createUserLayer();
191: layer.setName("UserLayer Name");
192:
193: Style style = sf.createStyle();
194: style.setName("Style Name");
195: style.setTitle("Style Title");
196: Rule rule1 = sb.createRule(sb.createLineSymbolizer(
197: new Color(0), 2));
198: // note: symbolizers containing a fill will likely fail, as the SLD
199: // transformation loses a little data (background colour?)
200: FeatureTypeStyle fts1 = sf
201: .createFeatureTypeStyle(new Rule[] { rule1 });
202: fts1
203: .setSemanticTypeIdentifiers(new String[] { "generic:geometry" });
204: style.setFeatureTypeStyles(new FeatureTypeStyle[] { fts1 });
205: layer.setUserStyles(new Style[] { style });
206: sld.setStyledLayers(new UserLayer[] { layer });
207:
208: //convert it to XML
209: SLDTransformer aTransformer = new SLDTransformer();
210: String xml = aTransformer.transform(sld);
211:
212: //back to SLD
213: InputStream is = new ByteArrayInputStream(xml.getBytes("UTF-8"));
214:
215: SLDParser stylereader = new SLDParser(sf, is);
216:
217: sld2 = stylereader.parseSLD();
218: // UNCOMMENT FOR DEBUGGING
219: // assertEquals(SLD.rules(SLD.styles(sld)[0]).length, SLD.rules(SLD.styles(sld2)[0]).length);
220: // for (int i = 0; i < SLD.rules(SLD.styles(sld)[0]).length; i++) {
221: // Rule aRule = SLD.rules(SLD.styles(sld)[0])[i];
222: // Rule bRule = SLD.rules(SLD.styles(sld2)[0])[i];
223: // System.out.println(i+":"+aRule);
224: // Symbolizer[] symb1 = SLD.symbolizers(aRule);
225: // Symbolizer[] symb2 = SLD.symbolizers(bRule);
226: // for (int j = 0; j < symb1.length; j++) {
227: // //symbolizers are equal
228: // assertTrue(symb1[j].equals(symb2[j]));
229: // }
230: // //rules are equal
231: // assertTrue(aRule.equals(bRule));
232: // }
233: // //feature type styles are equal
234: // assertTrue(SLD.featureTypeStyles(sld)[0].equals(SLD.featureTypeStyles(sld2)[0]));
235: // //styles are equal
236: // assertTrue(SLD.styles(sld)[0].equals(SLD.styles(sld2)[0]));
237: // //layers are equal
238: // StyledLayer layer1 = sld.getStyledLayers()[0];
239: // StyledLayer layer2 = sld2.getStyledLayers()[0];
240: // boolean result = layer1.equals(layer2);
241: // assertTrue(result);
242:
243: //everything is equal
244: assertTrue(sld2.equals(sld));
245: }
246:
247: public void testSLDTransformerIndentation() throws Exception {
248: //create a simple object
249: StyledLayerDescriptor sld = sf.createStyledLayerDescriptor();
250: NamedLayer nl = sf.createNamedLayer();
251: nl.setName("named_layer_1");
252: sld.addStyledLayer(nl);
253: //convert it to XML
254: SLDTransformer aTransformer = new SLDTransformer();
255: aTransformer.setIndentation(3); //3 spaces
256: String xml1 = aTransformer.transform(sld);
257: aTransformer.setIndentation(4); //4 spaces
258: String xml2 = aTransformer.transform(sld);
259: //generated xml contains 4 indents, so if indentation is working, the difference should be 4
260: assertEquals(xml1.length() + 4, xml2.length());
261: }
262:
263: public void testParseSLD_NameSpaceAware() throws Exception {
264: URL surl = TestData.getResource(this , "test-ns.sld");
265: StyleFactory factory = CommonFactoryFinder
266: .getStyleFactory(null);
267:
268: SLDParser stylereader = new SLDParser(factory, surl);
269: StyledLayerDescriptor sld = stylereader.parseSLD();
270:
271: assertEquals(1, sld.getStyledLayers().length);
272: FeatureTypeStyle[] fts = SLD.featureTypeStyles(sld);
273: assertEquals(2, fts.length);
274: assertEquals(1, fts[0].getSemanticTypeIdentifiers().length);
275: assertEquals(2, fts[1].getSemanticTypeIdentifiers().length);
276: assertEquals("colorbrewer:default", fts[1]
277: .getSemanticTypeIdentifiers()[1]);
278: }
279:
280: /**
281: * Test of parseSLD method to ensure NamedLayer/Name and
282: * NamedLayer/NamedStyle are parsed correctly
283: *
284: * @throws Exception boom
285: */
286: public void testParseSLDNamedLayersOnly() throws Exception {
287: StyleFactory factory = CommonFactoryFinder
288: .getStyleFactory(null);
289: java.net.URL surl = TestData.getResource(this ,
290: "namedLayers.sld");
291: SLDParser stylereader = new SLDParser(factory, surl);
292:
293: StyledLayerDescriptor sld = stylereader.parseSLD();
294:
295: final int expectedLayerCount = 3;
296: final String[] layerNames = { "Rivers", "Roads", "Houses" };
297: final String[] namedStyleNames = { "CenterLine", "CenterLine",
298: "Outline" };
299: StyledLayer[] layers = sld.getStyledLayers();
300:
301: assertEquals(expectedLayerCount, layers.length);
302:
303: for (int i = 0; i < expectedLayerCount; i++) {
304: assertTrue(layers[i] instanceof NamedLayer);
305: }
306:
307: for (int i = 0; i < expectedLayerCount; i++) {
308: assertEquals(layerNames[i], layers[i].getName());
309: }
310:
311: for (int i = 0; i < expectedLayerCount; i++) {
312: NamedLayer layer = (NamedLayer) layers[i];
313: assertEquals(1, layer.getStyles().length);
314: assertTrue(layer.getStyles()[0] instanceof NamedStyle);
315: assertEquals(namedStyleNames[i], layer.getStyles()[0]
316: .getName());
317: }
318: }
319:
320: /**
321: * Test of parseSLD method to ensure NamedLayer/Name and
322: * NamedLayer/NamedStyle are parsed correctly
323: *
324: * @throws Exception boom
325: */
326: public void testParseSLDNamedAndUserLayers() throws Exception {
327: StyleFactory factory = CommonFactoryFinder
328: .getStyleFactory(null);
329: java.net.URL surl = TestData.getResource(this ,
330: "mixedLayerTypes.sld");
331: SLDParser stylereader = new SLDParser(factory, surl);
332:
333: StyledLayerDescriptor sld = stylereader.parseSLD();
334:
335: final int expectedLayerCount = 4;
336:
337: StyledLayer[] layers = sld.getStyledLayers();
338:
339: assertEquals(expectedLayerCount, layers.length);
340: assertTrue(layers[0] instanceof NamedLayer);
341: assertTrue(layers[1] instanceof UserLayer);
342: assertTrue(layers[2] instanceof NamedLayer);
343: assertTrue(layers[3] instanceof UserLayer);
344: }
345:
346: /**
347: * Verifies that geometry filters inside SLD documents are correctly
348: * parsed.
349: *
350: * @throws IOException boom
351: */
352: public void testParseGeometryFilters() throws IOException {
353: final String TYPE_NAME = "testType";
354: final String GEOMETRY_ATTR = "Polygons";
355: StyleFactory factory = CommonFactoryFinder
356: .getStyleFactory(null);
357: java.net.URL surl = TestData.getResource(this ,
358: "spatialFilter.xml");
359: SLDParser stylereader = new SLDParser(factory, surl);
360:
361: Style[] styles = stylereader.readXML();
362:
363: final int expectedStyleCount = 1;
364: assertEquals(expectedStyleCount, styles.length);
365:
366: Style notDisjoint = styles[0];
367: assertEquals(1, notDisjoint.getFeatureTypeStyles().length);
368:
369: FeatureTypeStyle fts = notDisjoint.getFeatureTypeStyles()[0];
370: assertEquals(TYPE_NAME, fts.getFeatureTypeName());
371: assertEquals(1, fts.getRules().length);
372:
373: Filter filter = fts.getRules()[0].getFilter();
374: assertTrue(filter instanceof Not);
375:
376: BinarySpatialOperator spatialFilter = (BinarySpatialOperator) ((BinaryLogicOperator) filter)
377: .getChildren().get(0);
378: assertTrue(spatialFilter instanceof Disjoint);
379:
380: Expression left = spatialFilter.getExpression1();
381: Expression right = spatialFilter.getExpression2();
382:
383: assertTrue(left instanceof PropertyName);
384:
385: assertTrue(right instanceof Literal);
386: assertTrue(right.evaluate(null) instanceof Geometry);
387:
388: assertEquals(GEOMETRY_ATTR, ((PropertyName) left)
389: .getPropertyName());
390: assertTrue(right.evaluate(null) instanceof Polygon);
391:
392: Envelope bbox = ((Polygon) right.evaluate(null))
393: .getEnvelopeInternal();
394: assertEquals(-10D, bbox.getMinX(), 0);
395: assertEquals(-10D, bbox.getMinY(), 0);
396: assertEquals(10D, bbox.getMaxX(), 0);
397: assertEquals(10D, bbox.getMaxY(), 0);
398: }
399:
400: /**
401: * Verifies that a FID Filter is correctly parsed (GEOT-992).
402: *
403: * @throws IOException boom
404: */
405: public void testParseFidFilter() throws IOException {
406: StyleFactory factory = CommonFactoryFinder
407: .getStyleFactory(null);
408: java.net.URL surl = TestData.getResource(this , "fidFilter.xml");
409: SLDParser stylereader = new SLDParser(factory, surl);
410:
411: Style[] styles = stylereader.readXML();
412:
413: final int expectedStyleCount = 1;
414: assertEquals(expectedStyleCount, styles.length);
415:
416: Style style = styles[0];
417: assertEquals(1, style.getFeatureTypeStyles().length);
418:
419: FeatureTypeStyle fts = style.getFeatureTypeStyles()[0];
420: assertEquals("Feature", fts.getFeatureTypeName());
421: assertEquals(1, fts.getRules().length);
422:
423: Filter filter = fts.getRules()[0].getFilter();
424: assertTrue(filter instanceof Id);
425:
426: Id fidFilter = (Id) filter;
427: Set ids = fidFilter.getIDs();
428: String[] fids = (String[]) ids.toArray(new String[ids.size()]);
429: assertEquals("Wrong number of fids", 5, fids.length);
430:
431: Arrays.sort(fids);
432:
433: assertEquals("fid.0", fids[0]);
434: assertEquals("fid.1", fids[1]);
435: assertEquals("fid.2", fids[2]);
436: assertEquals("fid.3", fids[3]);
437: assertEquals("fid.4", fids[4]);
438: }
439:
440: }
|