/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2011, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.processing.vector.buffer; import org.geotoolkit.process.ProcessException; import org.opengis.util.NoSuchIdentifierException; import java.util.ArrayList; 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 java.util.concurrent.atomic.AtomicInteger; import javax.measure.quantity.Length; import javax.measure.Unit; import org.apache.sis.measure.Units; import org.apache.sis.feature.builder.AttributeRole; import org.apache.sis.feature.builder.FeatureTypeBuilder; import org.apache.sis.internal.feature.AttributeConvention; import org.apache.sis.internal.feature.BiFunction; import org.apache.sis.internal.feature.FeatureLoop; import org.apache.sis.internal.feature.Predicate; import org.geotoolkit.data.FeatureStoreUtilities; import org.geotoolkit.data.FeatureCollection; import org.geotoolkit.data.FeatureIterator; import org.geotoolkit.process.ProcessDescriptor; import org.geotoolkit.process.ProcessFinder; import org.geotoolkit.processing.vector.AbstractProcessTest; import org.apache.sis.referencing.CRS; import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.NoSuchAuthorityCodeException; import org.opengis.util.FactoryException; import org.junit.Test; import static org.junit.Assert.*; import org.opengis.feature.AttributeType; import org.opengis.feature.Feature; import org.opengis.feature.FeatureType; import org.opengis.feature.PropertyType; /** * JUnit test douglas peucker simplification on FeatureCollection * * @author Quentin Boileau * @module */ public class BufferTest extends AbstractProcessTest { private static GeometryFactory geometryFactory; private static FeatureType type; private static final Double distance = new Double(5); public BufferTest() { super("buffer"); } /** * Test Buffer process Tests realized : - Same FeatureType between the output FeatureCollection and a generated * FeatureCollection - Same Features ID - Same FeatureCollection size - Output FeatureCollection geometry contains * input FeatureCollection geometry */ @Test public void testBuffer() throws ProcessException, NoSuchIdentifierException, FactoryException { // Inputs final FeatureCollection featureList = buildFeatureCollectionInput1(); Unit<Length> unit = Units.METRE; // Process ProcessDescriptor desc = ProcessFinder.getProcessDescriptor("vector", "buffer"); ParameterValueGroup in = desc.getInputDescriptor().createValue(); in.parameter("feature_in").setValue(featureList); in.parameter("distance_in").setValue(distance); //in.parameter("unit_in").setValue(unit); in.parameter("lenient_transform_in").setValue(true); org.geotoolkit.process.Process proc = desc.createProcess(in); //Features out final FeatureCollection featureListOut = (FeatureCollection) proc.call().parameter("feature_out").getValue(); //Expected Features out final FeatureCollection featureListResult = buildFeatureCollectionResult(); assertEquals(featureListResult.getFeatureType(), featureListOut.getFeatureType()); assertEquals(featureListResult.getID(), featureListOut.getID()); assertEquals(featureListResult.size(), featureListOut.size()); double precision = 0.01; //geometry out list final FeatureIterator iteratorOut = featureListOut.iterator(); final ArrayList<Geometry> geomsOut = new ArrayList<>(); final AtomicInteger itOut = new AtomicInteger(); while (iteratorOut.hasNext()) { Feature featureOut = iteratorOut.next(); FeatureLoop.loop(featureOut, (Predicate)null, new BiFunction<PropertyType, Object, Object>() { @Override public Object apply(PropertyType t, Object u) { if(t instanceof AttributeType && Geometry.class.isAssignableFrom(((AttributeType)t).getValueClass())){ geomsOut.add(itOut.getAndIncrement(), (Geometry) u); } return u; } }); } //geometry input list final FeatureIterator listIterator = featureList.iterator(); final ArrayList<Geometry> geomsInput = new ArrayList<>(); final AtomicInteger itResult = new AtomicInteger(); while (listIterator.hasNext()) { Feature feature = listIterator.next(); FeatureLoop.loop(feature, (Predicate)null, new BiFunction<PropertyType, Object, Object>() { @Override public Object apply(PropertyType t, Object u) { if(t instanceof AttributeType && Geometry.class.isAssignableFrom(((AttributeType)t).getValueClass())){ geomsInput.add(itResult.getAndIncrement(), (Geometry)u); } return u; } }); } assertEquals(geomsInput.size(), geomsOut.size()); for (int i = 0; i < geomsInput.size(); i++) { Geometry gOut = geomsOut.get(i); Geometry gInput = geomsInput.get(i); assertTrue(gOut.contains(gInput)); } } private static FeatureType createSimpleType() throws NoSuchAuthorityCodeException, FactoryException { final FeatureTypeBuilder ftb = new FeatureTypeBuilder(); ftb.setName("BufferTest"); ftb.addAttribute(String.class).setName(AttributeConvention.IDENTIFIER_PROPERTY); ftb.addAttribute(String.class).setName("name"); ftb.addAttribute(Geometry.class).setName("position").setCRS(CRS.forCode("EPSG:3395")).addRole(AttributeRole.DEFAULT_GEOMETRY); final FeatureType sft = ftb.build(); return sft; } private static FeatureCollection buildFeatureCollectionInput1() throws FactoryException { type = createSimpleType(); final FeatureCollection featureList = FeatureStoreUtilities.collection("", type); geometryFactory = new GeometryFactory(); Feature myFeature1 = type.newInstance(); myFeature1.setPropertyValue("@identifier", "id-01"); myFeature1.setPropertyValue("name", "Point"); myFeature1.setPropertyValue("position", geometryFactory.createPoint(new Coordinate(-10.0, 10.0))); featureList.add(myFeature1); Feature myFeature2 = type.newInstance(); LineString line = geometryFactory.createLineString( new Coordinate[]{ new Coordinate(30.0, 40.0), new Coordinate(50.0, 60.0), new Coordinate(60.0, 50.0), new Coordinate(70.0, 40.0) }); myFeature2.setPropertyValue("@identifier", "id-02"); myFeature2.setPropertyValue("name", "LineString"); myFeature2.setPropertyValue("position", line); featureList.add(myFeature2); Feature myFeature3 = type.newInstance(); LinearRing ring2 = geometryFactory.createLinearRing( new Coordinate[]{ new Coordinate(-10.0, -10.0), new Coordinate(0.0, -30.0), new Coordinate(-20.0, -20.0), new Coordinate(-30.0, 10.0), new Coordinate(-20.0, 30.0), new Coordinate(0.0, 20.0), new Coordinate(10.0, 10.0), new Coordinate(20.0, -20.0), new Coordinate(10.0, -20.0), new Coordinate(-10.0, -10.0) }); myFeature3.setPropertyValue("@identifier", "id-03"); myFeature3.setPropertyValue("name", "Polygone"); myFeature3.setPropertyValue("position", geometryFactory.createPolygon(ring2, null)); featureList.add(myFeature3); return featureList; } private static FeatureCollection buildFeatureCollectionResult() throws FactoryException { type = createSimpleType(); final FeatureCollection featureList = FeatureStoreUtilities.collection("", type); geometryFactory = new GeometryFactory(); Feature myFeature1 = type.newInstance(); myFeature1.setPropertyValue("@identifier", "id-01"); myFeature1.setPropertyValue("name", "Point"); myFeature1.setPropertyValue("position", geometryFactory.createPoint(new Coordinate(-10.0, 10.0)).buffer(distance)); featureList.add(myFeature1); Feature myFeature2 = type.newInstance(); LineString line = geometryFactory.createLineString( new Coordinate[]{ new Coordinate(30.0, 40.0), new Coordinate(50.0, 60.0), new Coordinate(60.0, 50.0), new Coordinate(70.0, 40.0) }); myFeature2.setPropertyValue("@identifier", "id-02"); myFeature2.setPropertyValue("name", "LineString"); myFeature2.setPropertyValue("position", line.buffer(distance)); featureList.add(myFeature2); Feature myFeature3 = type.newInstance(); LinearRing ring2 = geometryFactory.createLinearRing( new Coordinate[]{ new Coordinate(-10.0, -10.0), new Coordinate(0.0, -30.0), new Coordinate(-20.0, -20.0), new Coordinate(-30.0, 10.0), new Coordinate(-20.0, 30.0), new Coordinate(0.0, 20.0), new Coordinate(10.0, 10.0), new Coordinate(20.0, -20.0), new Coordinate(10.0, -20.0), new Coordinate(-10.0, -10.0) }); myFeature3.setPropertyValue("@identifier", "id-03"); myFeature3.setPropertyValue("name", "Polygone"); myFeature3.setPropertyValue("position", geometryFactory.createPolygon(ring2, null).buffer(distance)); featureList.add(myFeature3); return featureList; } }