/* * Copyright (c) 2012 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * HUMBOLDT EU Integrated Project #030962 * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.io.gml.writer.internal; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.net.URI; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.xml.namespace.QName; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.LinearRing; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.geom.MultiPoint; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; import eu.esdihumboldt.hale.common.core.io.IOProviderConfigurationException; import eu.esdihumboldt.hale.common.core.io.Value; import eu.esdihumboldt.hale.common.core.io.report.IOReport; import eu.esdihumboldt.hale.common.core.io.supplier.DefaultInputSupplier; import eu.esdihumboldt.hale.common.core.io.supplier.FileIOSupplier; import eu.esdihumboldt.hale.common.core.io.supplier.Locatable; import eu.esdihumboldt.hale.common.instance.geometry.GeometryUtil; import eu.esdihumboldt.hale.common.instance.io.GeoInstanceWriter; import eu.esdihumboldt.hale.common.instance.io.InstanceReader; import eu.esdihumboldt.hale.common.instance.io.InstanceWriter; import eu.esdihumboldt.hale.common.instance.io.util.EnumWindingOrderTypes; import eu.esdihumboldt.hale.common.instance.model.Instance; import eu.esdihumboldt.hale.common.instance.model.InstanceCollection; import eu.esdihumboldt.hale.common.instance.model.MutableGroup; import eu.esdihumboldt.hale.common.instance.model.MutableInstance; import eu.esdihumboldt.hale.common.instance.model.ResourceIterator; import eu.esdihumboldt.hale.common.instance.model.impl.DefaultGroup; import eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstance; import eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstanceCollection; import eu.esdihumboldt.hale.common.schema.geometry.GeometryProperty; import eu.esdihumboldt.hale.common.schema.model.ChildDefinition; import eu.esdihumboldt.hale.common.schema.model.DefinitionGroup; import eu.esdihumboldt.hale.common.schema.model.Schema; import eu.esdihumboldt.hale.common.schema.model.impl.DefaultSchemaSpace; import eu.esdihumboldt.hale.common.test.TestUtil; import eu.esdihumboldt.hale.io.gml.reader.internal.GmlInstanceReader; import eu.esdihumboldt.hale.io.gml.writer.GmlInstanceWriter; import eu.esdihumboldt.hale.io.gml.writer.internal.geometry.GeometryConverterRegistry; import eu.esdihumboldt.hale.io.gml.writer.internal.geometry.GeometryConverterRegistry.ConversionLadder; import eu.esdihumboldt.hale.io.xml.validator.XmlInstanceValidator; import eu.esdihumboldt.hale.io.xsd.model.XmlElement; import eu.esdihumboldt.hale.io.xsd.model.XmlIndex; import eu.esdihumboldt.hale.io.xsd.reader.XmlSchemaReader; import eu.esdihumboldt.util.geometry.WindingOrder; /** * Tests for {@link StreamGmlWriter}. * * @author Simon Templer * @partner 01 / Fraunhofer Institute for Computer Graphics Research */ @SuppressWarnings("restriction") public class StreamGmlWriterTest { /** * Property path for the geometry property */ private static final List<QName> GEOMETRY_PROPERTY = Arrays .asList(new QName("eu:esdihumboldt:hale:test", "geometry")); /** * If temporary files shall be deleted */ private static final boolean DEL_TEMP_FILES = true; private static final String DEF_SRS_NAME = "EPSG:31467"; //$NON-NLS-1$ /** * The geometry factory */ private static final GeometryFactory geomFactory = new GeometryFactory(); // /** // * Test writing a simple feature from a simple schema (Watercourses VA) // * // * @throws Exception if any error occurs // */ // @Test // public void testFillWrite_WatercourseVA() throws Exception { // Map<List<String>, Object> values = new HashMap<List<String>, Object>(); // // // create the geometry //// MultiLineString mls = geomFactory.createMultiLineString( //// new LineString[]{createLineString(0.0), createLineString(1.0), //// createLineString(2.0)}); // //XXX for some reason the MultiLineString is converted to a LineString when set a value -> so we are using a LineString instead to allow value comparison // LineString mls = createLineString(0.0); // // values.put(Arrays.asList("LENGTH"), Double.valueOf(10.2)); //$NON-NLS-1$ // values.put(Arrays.asList("NAME"), "Test"); //$NON-NLS-1$ //$NON-NLS-2$ // values.put(Arrays.asList("the_geom"), mls); //$NON-NLS-1$ // // Report report = fillFeatureTest("Watercourses_VA", //$NON-NLS-1$ // getClass().getResource("/data/sample_wva/wfs_va.xsd").toURI(), //$NON-NLS-1$ // values, "fillWrite_WVA", "EPSG:31251"); //$NON-NLS-1$ //$NON-NLS-2$ // // assertTrue("Expected GML output to be valid", report.isValid()); //$NON-NLS-1$ // } /** * Test writing a {@link Point} to a GML 2 geometry type * * @throws Exception if an error occurs */ @Ignore // GML 2 stuff currently not working (because of unrelated schemas) @Test public void testGeometry_2_Point() throws Exception { // create the geometry Point point = createPoint(10.0); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, point); // $NON-NLS-1$ IOReport report = fillFeatureTest("Test", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml2.xsd").toURI(), //$NON-NLS-1$ values, "geometry_2_Point", DEF_SRS_NAME); //$NON-NLS-1$ assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link Point} to a GML 3.2 geometry primitive type * * @throws Exception if an error occurs */ @Test public void testGeometryPrimitive_32_Point() throws Exception { // create the geometry Point point = createPoint(10.0); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, point); // $NON-NLS-1$ IOReport report = fillFeatureTest("PrimitiveTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryPrimitive_32_Point", DEF_SRS_NAME); //$NON-NLS-1$ assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link Point} to a GML 3.2 geometry aggregate type * * @throws Exception if an error occurs */ @Test public void testGeometryAggregate_32_Point() throws Exception { // create the geometry Point point = createPoint(10.0); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, point); // $NON-NLS-1$ IOReport report = fillFeatureTest("AggregateTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryAggregate_32_Point", DEF_SRS_NAME); //$NON-NLS-1$ assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link MultiPoint} to a GML 2 geometry type * * @throws Exception if an error occurs */ @Ignore // GML 2 stuff currently not working (because of unrelated schemas) @Test public void testGeometry_2_MultiPoint() throws Exception { // create the geometry MultiPoint mp = geomFactory.createMultiPoint( new Point[] { createPoint(0.0), createPoint(1.0), createPoint(2.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mp); // $NON-NLS-1$ IOReport report = fillFeatureTest("Test", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml2.xsd").toURI(), //$NON-NLS-1$ values, "geometry_2_MultiPoint", DEF_SRS_NAME); //$NON-NLS-1$ assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link MultiPoint} to a GML 3.2 geometry aggregate type * * @throws Exception if an error occurs */ @Test public void testGeometryAggregate_32_MultiPoint() throws Exception { // create the geometry MultiPoint mp = geomFactory.createMultiPoint( new Point[] { createPoint(0.0), createPoint(1.0), createPoint(2.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mp); // $NON-NLS-1$ IOReport report = fillFeatureTest("AggregateTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryAggregate_32_MultiPoint", DEF_SRS_NAME, //$NON-NLS-1$ true, false); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } // TODO test with a type that references a gmlAbstractGeometry element /** * Create a point * * @param x the x ordinate * * @return a point */ private Point createPoint(double x) { return geomFactory.createPoint(new Coordinate(x, x + 1)); } /** * Test writing a {@link Polygon} to a GML 2 geometry type * * @throws Exception if an error occurs */ @Ignore // GML 2 stuff currently not working (because of unrelated schemas) @Test public void testGeometry_2_Polygon() throws Exception { // create the geometry Polygon polygon = createPolygon(0.0); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, polygon); // $NON-NLS-1$ IOReport report = fillFeatureTest("Test", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml2.xsd").toURI(), //$NON-NLS-1$ values, "geometry_2_Polygon", DEF_SRS_NAME); //$NON-NLS-1$ assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link Polygon} to a GML 3.0 geometry primitive type * * @throws Exception if an error occurs */ @Ignore // deactivated test because schema is invalid (according to xerces) @Test public void testGeometryPrimitive_3_Polygon() throws Exception { // create the geometry Polygon polygon = createPolygon(0.0); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, polygon); IOReport report = fillFeatureTest("PrimitiveTest", getClass().getResource("/data/geom_schema/geom-gml3.xsd").toURI(), values, "geometryPrimitive_3_Polygon", DEF_SRS_NAME); assertTrue("Expected GML output to be valid", report.isSuccess()); } /** * Test writing a {@link Polygon} to a GML 3.1 geometry primitive type * * @throws Exception if an error occurs */ // @Ignore // loading Polygons not yet supported @Test public void testGeometryPrimitive_31_Polygon() throws Exception { // create the geometry Polygon polygon = createPolygon(0.0); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, polygon); // $NON-NLS-1$ IOReport report = fillFeatureTest("PrimitiveTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml31.xsd").toURI(), //$NON-NLS-1$ values, "geometryPrimitive_31_Polygon", DEF_SRS_NAME, //$NON-NLS-1$ true, false); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link Polygon} to a GML 3.2 geometry primitive type * * @throws Exception if an error occurs */ // @Ignore // loading Polygons not yet supported @Test public void testGeometryPrimitive_32_Polygon() throws Exception { // create the geometry Polygon polygon = createPolygon(0.0); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, polygon); // $NON-NLS-1$ IOReport report = fillFeatureTest("PrimitiveTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryPrimitive_32_Polygon", DEF_SRS_NAME, //$NON-NLS-1$ true, false); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Create a polygon * * @param offset the offset along both axes * * @return the created polygon */ private Polygon createPolygon(double offset) { LinearRing shell = geomFactory.createLinearRing(new Coordinate[] { new Coordinate(-1.0 + offset, offset), new Coordinate(offset, 1.0 + offset), new Coordinate(1.0 + offset, offset), new Coordinate(offset, -1.0 + offset), new Coordinate(-1.0 + offset, offset) }); return geomFactory.createPolygon(shell, null); } /** * Test writing a {@link LineString} to a GML 2 geometry type * * @throws Exception if an error occurs */ @Ignore // GML 2 stuff currently not working (because of unrelated schemas) @Test public void testGeometry_2_LineString() throws Exception { // create the geometry LineString lineString = createLineString(0.0); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, lineString); // $NON-NLS-1$ IOReport report = fillFeatureTest("Test", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml2.xsd").toURI(), //$NON-NLS-1$ values, "geometry_2_LineString", DEF_SRS_NAME); //$NON-NLS-1$ assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link LineString} to a GML 3.2 geometry primitive type * * @throws Exception if an error occurs */ @Test public void testGeometryPrimitive_32_LineString() throws Exception { // create the geometry LineString lineString = createLineString(0.0); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, lineString); // $NON-NLS-1$ IOReport report = fillFeatureTest("PrimitiveTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryPrimitive_32_LineString", DEF_SRS_NAME, //$NON-NLS-1$ true, false); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link LineString} to a GML 3.2 geometry aggregate type * * @throws Exception if an error occurs */ @Test public void testGeometryAggregate_32_LineString() throws Exception { // create the geometry LineString lineString = createLineString(0.0); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, lineString); // $NON-NLS-1$ IOReport report = fillFeatureTest("AggregateTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryAggregate_32_LineString", DEF_SRS_NAME, //$NON-NLS-1$ true, false); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Create a line string geometry * * @param offset the line y-offset * * @return the line string */ public static LineString createLineString(double offset) { return geomFactory.createLineString(new Coordinate[] { new Coordinate(0.0, offset), new Coordinate(1.0, 1.0 + offset), new Coordinate(2.0, 2.0 + offset), new Coordinate(3.0, 1.0 + offset), new Coordinate(4.0, offset) }); } /** * Create a curve. * * @return the line string */ public static MultiLineString createCurve() { LineString ls1 = geomFactory.createLineString(new Coordinate[] { new Coordinate(0.0, 0.0), new Coordinate(1.0, 1.0), new Coordinate(2.0, 2.0), new Coordinate(3.0, 3.0), new Coordinate(4.0, 4.0) }); LineString ls2 = geomFactory.createLineString(new Coordinate[] { new Coordinate(4.0, 4.0), new Coordinate(5.0, 3.0), new Coordinate(6.0, 2.0), new Coordinate(7.0, 1.0), new Coordinate(8.0, 0.0) }); return geomFactory.createMultiLineString(new LineString[] { ls1, ls2 }); } /** * Test writing a {@link MultiLineString} to a GML 2 geometry type * * @throws Exception if an error occurs */ @Ignore // GML 2 stuff currently not working (because of unrelated schemas) @Test public void testGeometry_2_MultiLineString() throws Exception { // create the geometry MultiLineString mls = geomFactory.createMultiLineString(new LineString[] { createLineString(0.0), createLineString(1.0), createLineString(2.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mls); // $NON-NLS-1$ IOReport report = fillFeatureTest("Test", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml2.xsd").toURI(), //$NON-NLS-1$ values, "geometry_2_MultiLineString", DEF_SRS_NAME); //$NON-NLS-1$ assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link MultiLineString} to a GML 3.2 geometry primitive * type * * @throws Exception if an error occurs */ @Test public void testGeometryPrimitive_32_MultiLineString() throws Exception { // create the geometry MultiLineString mls = geomFactory.createMultiLineString(new LineString[] { createLineString(0.0), createLineString(1.0), createLineString(2.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mls); // $NON-NLS-1$ fillFeatureTest("PrimitiveTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryPrimitive_32_MultiLineString", DEF_SRS_NAME, //$NON-NLS-1$ true, true); // writing should have failed because the MLS is not a curve } /** * Test writing a {@link MultiLineString} to a GML 3.2 geometry primitive * type * * @throws Exception if an error occurs */ @Test public void testGeometryPrimitive_32_MultiLineString_Curve1() throws Exception { // create the geometry MultiLineString mls = geomFactory .createMultiLineString(new LineString[] { createLineString(0.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mls); // $NON-NLS-1$ IOReport report = fillFeatureTest("PrimitiveTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryPrimitive_32_MultiLineString", DEF_SRS_NAME, //$NON-NLS-1$ true, false); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link MultiLineString} to a GML 3.2 geometry primitive * type * * @throws Exception if an error occurs */ @Test public void testGeometryPrimitive_32_MultiLineString_Curve2() throws Exception { // create the geometry MultiLineString mls = createCurve(); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mls); // $NON-NLS-1$ IOReport report = fillFeatureTest("PrimitiveTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryPrimitive_32_MultiLineString", DEF_SRS_NAME, //$NON-NLS-1$ true, false); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link MultiLineString} to a GML 3.2 geometry aggregate * type * * @throws Exception if an error occurs */ @Test public void testGeometryAggregate_32_MultiLineString() throws Exception { // create the geometry MultiLineString mls = geomFactory.createMultiLineString(new LineString[] { createLineString(0.0), createLineString(1.0), createLineString(2.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mls); // $NON-NLS-1$ IOReport report = fillFeatureTest("AggregateTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryAggregate_32_MultiLineString", DEF_SRS_NAME, //$NON-NLS-1$ true, false); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link MultiPolygon} to a GML 2 geometry type * * @throws Exception if an error occurs */ @Ignore // GML 2 stuff currently not working (because of unrelated schemas) @Test public void testGeometry_2_MultiPolygon() throws Exception { // create the geometry MultiPolygon mp = geomFactory.createMultiPolygon( new Polygon[] { createPolygon(0.0), createPolygon(1.0), createPolygon(-1.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mp); // $NON-NLS-1$ IOReport report = fillFeatureTest("Test", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml2.xsd").toURI(), //$NON-NLS-1$ values, "geometry_2_MultiPolygon", DEF_SRS_NAME); //$NON-NLS-1$ assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link MultiPolygon} to a GML 3.2 geometry primitive type * * @throws Exception if an error occurs */ @Test public void testGeometryPrimitive_32_MultiPolygon() throws Exception { // create the geometry MultiPolygon mp = geomFactory.createMultiPolygon( new Polygon[] { createPolygon(0.0), createPolygon(1.0), createPolygon(-1.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mp); // $NON-NLS-1$ IOReport report = fillFeatureTest("PrimitiveTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryPrimitive_32_MultiPolygon", DEF_SRS_NAME, //$NON-NLS-1$ true, false); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link MultiPolygon} to a GML 3.2 geometry aggregate type * * @throws Exception if an error occurs */ @Test public void testGeometryAggregate_32_MultiPolygon() throws Exception { // create the geometry MultiPolygon mp = geomFactory.createMultiPolygon( new Polygon[] { createPolygon(0.0), createPolygon(1.0), createPolygon(-1.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mp); // $NON-NLS-1$ IOReport report = fillFeatureTest("AggregateTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryAggregate_32_MultiPolygon", DEF_SRS_NAME, //$NON-NLS-1$ true, false); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link MultiPolygon} to a GML 3.2 geometry primitive type * with Winding Order in CounterClockWise * * @throws Exception if an error occurs */ @Test public void testGeometryPrimitive_32_MultiPolygon_WindingOrder_CCW() throws Exception { // create the geometry MultiPolygon mp = geomFactory.createMultiPolygon( new Polygon[] { createPolygon(0.0), createPolygon(1.0), createPolygon(-1.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mp); // $NON-NLS-1$ IOReport report = fillFeatureTest("AggregateTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryAggregate_32_MultiPolygon", DEF_SRS_NAME, //$NON-NLS-1$ false, false, EnumWindingOrderTypes.counterClockwise); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link MultiPolygon} to a GML 3.2 geometry primitive type * with Winding Order in ClockWise * * @throws Exception if an error occurs */ @Test public void testGeometryPrimitive_32_MultiPolygon_WindingOrder_CW() throws Exception { // create the geometry MultiPolygon mp = geomFactory.createMultiPolygon( new Polygon[] { createPolygon(0.0), createPolygon(1.0), createPolygon(-1.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mp); // $NON-NLS-1$ IOReport report = fillFeatureTest("AggregateTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryPrimitive_32_MultiPolygon", DEF_SRS_NAME, //$NON-NLS-1$ false, false, EnumWindingOrderTypes.clockwise); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Test writing a {@link MultiPolygon} to a GML 3.2 geometry primitive type * with Winding Order in ClockWise * * @throws Exception if an error occurs */ @Test public void testGeometryPrimitive_32_MultiPolygon_WindingOrder() throws Exception { // create the geometry MultiPolygon mp = geomFactory.createMultiPolygon( new Polygon[] { createPolygon(0.0), createPolygon(1.0), createPolygon(-1.0) }); Map<List<QName>, Object> values = new HashMap<List<QName>, Object>(); values.put(GEOMETRY_PROPERTY, mp); // $NON-NLS-1$ IOReport report = fillFeatureTest("AggregateTest", //$NON-NLS-1$ getClass().getResource("/data/geom_schema/geom-gml32.xsd").toURI(), //$NON-NLS-1$ values, "geometryPrimitive_32_MultiPolygon", DEF_SRS_NAME, //$NON-NLS-1$ false, false, EnumWindingOrderTypes.noChanges); assertTrue("Expected GML output to be valid", report.isSuccess()); //$NON-NLS-1$ } /** * Create a feature, fill it with values, write it as GML, validate the GML * and load the GML file again to compare the loaded values with the ones * that were written * * @param elementName the element name of the feature type to use, if * <code>null</code> a random element will be used * @param targetSchema the schema to use, the first element will be used for * the type of the feature * @param values the values to set on the feature * @param testName the name of the test * @param srsName the SRS name * @return the validation report * @throws Exception if any error occurs */ private IOReport fillFeatureTest(String elementName, URI targetSchema, Map<List<QName>, Object> values, String testName, String srsName) throws Exception { return fillFeatureTest(elementName, targetSchema, values, testName, srsName, false, false); } /** * Create a feature, fill it with values, write it as GML, validate the GML * and load the GML file again to compare the loaded values with the ones * that were written * * @param elementName the element name of the feature type to use, if * <code>null</code> a random element will be used * @param targetSchema the schema to use, the first element will be used for * the type of the feature * @param values the values to set on the feature * @param testName the name of the test * @param srsName the SRS name * @param skipValueTest if the check for equality shall be skipped * @param expectWriteFail if the GML writing is expected to fail * @return the validation report or the GML writing report if writing * expected to fail * @throws Exception if any error occurs */ private IOReport fillFeatureTest(String elementName, URI targetSchema, Map<List<QName>, Object> values, String testName, String srsName, boolean skipValueTest, boolean expectWriteFail) throws Exception { return fillFeatureTest(elementName, targetSchema, values, testName, srsName, skipValueTest, expectWriteFail, null); } /** * Create a feature, fill it with values, write it as GML, validate the GML * and load the GML file again to compare the loaded values with the ones * that were written * * @param elementName the element name of the feature type to use, if * <code>null</code> a random element will be used * @param targetSchema the schema to use, the first element will be used for * the type of the feature * @param values the values to set on the feature * @param testName the name of the test * @param srsName the SRS name * @param skipValueTest if the check for equality shall be skipped * @param expectWriteFail if the GML writing is expected to fail * @param windingOrderParam winding order parameter or <code>null</code> * @return the validation report or the GML writing report if writing * expected to fail * @throws Exception if any error occurs */ private IOReport fillFeatureTest(String elementName, URI targetSchema, Map<List<QName>, Object> values, String testName, String srsName, boolean skipValueTest, boolean expectWriteFail, EnumWindingOrderTypes windingOrderParam) throws Exception { // load the sample schema XmlSchemaReader reader = new XmlSchemaReader(); reader.setSharedTypes(null); reader.setSource(new DefaultInputSupplier(targetSchema)); IOReport schemaReport = reader.execute(null); assertTrue(schemaReport.isSuccess()); XmlIndex schema = reader.getSchema(); XmlElement element = null; if (elementName == null) { element = schema.getElements().values().iterator().next(); if (element == null) { fail("No element found in the schema"); //$NON-NLS-1$ } } else { for (XmlElement candidate : schema.getElements().values()) { if (candidate.getName().getLocalPart().equals(elementName)) { element = candidate; break; } } if (element == null) { fail("Element " + elementName + " not found in the schema"); //$NON-NLS-1$ //$NON-NLS-2$ } } if (element == null) { throw new IllegalStateException(); } // create feature MutableInstance feature = new DefaultInstance(element.getType(), null); // set some values for (Entry<List<QName>, Object> entry : values.entrySet()) { MutableGroup parent = feature; List<QName> properties = entry.getKey(); for (int i = 0; i < properties.size() - 1; i++) { QName propertyName = properties.get(i); DefinitionGroup def = parent.getDefinition(); Object[] vals = parent.getProperty(propertyName); if (vals != null && vals.length > 0) { Object value = vals[0]; if (value instanceof MutableGroup) { parent = (MutableGroup) value; } else { MutableGroup child; ChildDefinition<?> childDef = def.getChild(propertyName); if (childDef.asProperty() != null || value != null) { // create instance child = new DefaultInstance(childDef.asProperty().getPropertyType(), null); } else { // create group child = new DefaultGroup(childDef.asGroup()); } if (value != null) { // wrap value ((MutableInstance) child).setValue(value); } parent = child; } } } parent.addProperty(properties.get(properties.size() - 1), entry.getValue()); } InstanceCollection instances = new DefaultInstanceCollection( Collections.singleton(feature)); // write to file InstanceWriter writer = new GmlInstanceWriter(); if (windingOrderParam != null) { writer.setParameter(GeoInstanceWriter.PARAM_UNIFY_WINDING_ORDER, Value.of(windingOrderParam)); } writer.setInstances(instances); DefaultSchemaSpace schemaSpace = new DefaultSchemaSpace(); schemaSpace.addSchema(schema); writer.setTargetSchema(schemaSpace); File outFile = File.createTempFile(testName, ".gml"); //$NON-NLS-1$ writer.setTarget(new FileIOSupplier(outFile)); if (windingOrderParam != null && windingOrderParam == EnumWindingOrderTypes.counterClockwise) { assertTrue(writer.getParameter(GeoInstanceWriter.PARAM_UNIFY_WINDING_ORDER) .as(EnumWindingOrderTypes.class) == EnumWindingOrderTypes.counterClockwise); } IOReport report = writer.execute(null); // new LogProgressIndicator()); if (expectWriteFail) { assertFalse("Writing the GML output should not be successful", report.isSuccess()); return report; } else { assertTrue("Writing the GML output not successful", report.isSuccess()); } List<? extends Locatable> validationSchemas = writer.getValidationSchemas(); System.out.println(outFile.getAbsolutePath()); System.out.println(targetSchema.toString()); // if (!DEL_TEMP_FILES && Desktop.isDesktopSupported()) { // Desktop.getDesktop().open(outFile); // } IOReport valReport = validate(outFile.toURI(), validationSchemas); // load file InstanceCollection loaded = loadGML(outFile.toURI(), schema); ResourceIterator<Instance> it = loaded.iterator(); try { assertTrue(it.hasNext()); if (!skipValueTest) { Instance l = it.next(); // test values for (Entry<List<QName>, Object> entry : values.entrySet()) { // XXX conversion? Object expected = entry.getValue(); // String propertyPath = Joiner.on('.').join(Collections2.transform(entry.getKey(), new Function<QName, String>() { // // @Override // public String apply(QName input) { // return input.toString(); // } // })); // Collection<Object> propValues = PropertyResolver.getValues( // l, propertyPath, true); // assertEquals(1, propValues.size()); // Object value = propValues.iterator().next(); Collection<GeometryProperty<?>> geoms = GeometryUtil.getAllGeometries(l); assertEquals(1, geoms.size()); Object value = geoms.iterator().next().getGeometry(); if (expected instanceof Geometry && value instanceof Geometry) { if (windingOrderParam == null || windingOrderParam == EnumWindingOrderTypes.noChanges) { matchGeometries((Geometry) expected, (Geometry) value); } // Winding Order Test. if (windingOrderParam != null) { if (windingOrderParam == EnumWindingOrderTypes.counterClockwise) { assertTrue(((Geometry) expected) .getNumGeometries() == ((Geometry) value) .getNumGeometries()); assertTrue(WindingOrder.isCounterClockwise((Geometry) value)); } else if (windingOrderParam == EnumWindingOrderTypes.clockwise) { assertFalse(WindingOrder.isCounterClockwise((Geometry) value)); } else { assertTrue(WindingOrder .isCounterClockwise((Geometry) value) == WindingOrder .isCounterClockwise((Geometry) expected)); } } else { // TODO check winding order is CCW if (value instanceof Polygon || value instanceof MultiPolygon) assertTrue(WindingOrder.isCounterClockwise((Geometry) value)); } } else { assertEquals(expected.toString(), value.toString()); } } assertFalse(it.hasNext()); } } finally { it.close(); } if (DEL_TEMP_FILES) { outFile.deleteOnExit(); } return valReport; } /** * Let the test fail if the given geometries don't match * * @param expected the expected geometry * @param value the geometry value */ public static void matchGeometries(Geometry expected, Geometry value) { if (expected.toString().equals(value.toString())) { // direct match return; } // check match for all no-loss conversions on value ConversionLadder ladder = GeometryConverterRegistry.getInstance().createNoLossLadder(value); while (ladder.hasNext()) { Geometry converted = ladder.next(); if (expected.toString().equals(converted.toString())) { // match return; } } assertEquals("Geometry not compatible to expected geometry", expected.toString(), //$NON-NLS-1$ value.toString()); } /** * Load GML from a file. * * @param sourceData the GML file * @param schema the schema location * @return the features * @throws IOException if loading the file fails * @throws IOProviderConfigurationException if the instance reader is not * configured correctly */ public static InstanceCollection loadGML(URI sourceData, Schema schema) throws IOException, IOProviderConfigurationException { InstanceReader instanceReader = new GmlInstanceReader(); instanceReader.setSource(new DefaultInputSupplier(sourceData)); instanceReader.setSourceSchema(schema); IOReport instanceReport = instanceReader.execute(null); assertTrue(instanceReport.isSuccess()); return instanceReader.getInstances(); } /** * Validate an XML file against the given schemas. * * @param xmlLocation the location of the XML file * @param validationSchemas schemas needed for validation * @return the validation report * @throws IOProviderConfigurationException if the validator is not * configured correctly * @throws IOException if I/O operations fail */ public static IOReport validate(URI xmlLocation, List<? extends Locatable> validationSchemas) throws IOProviderConfigurationException, IOException { XmlInstanceValidator validator = new XmlInstanceValidator(); validator.setSchemas(validationSchemas.toArray(new Locatable[validationSchemas.size()])); validator.setSource(new DefaultInputSupplier(xmlLocation)); return validator.execute(null); } /** * Prepare the conversion service */ @BeforeClass public static void initAll() { TestUtil.startConversionService(); } }