Author: aaime Date: 2012-04-15 17:35:58 -0700 (Sun, 15 Apr 2012) New Revision: 38671 Added: trunk/modules/library/main/src/main/java/org/geotools/filter/function/FilterFunction_minimumDiameter.java trunk/modules/library/main/src/main/java/org/geotools/filter/function/FilterFunction_octagonalEnvelope.java trunk/modules/library/main/src/main/resources/META-INF/services/org.opengis.filter.expression.Function.orig trunk/modules/library/main/src/test/java/org/geotools/filter/function/FilterFunction_minimumDiameterTest.java trunk/modules/library/main/src/test/java/org/geotools/filter/function/FilterFunction_octagonalEnvelopeTest.java Modified: trunk/modules/library/main/src/main/java/org/geotools/filter/function/StaticGeometry.java trunk/modules/library/main/src/main/resources/META-INF/services/org.opengis.filter.expression.Function Log: [GEOT-4099] Octagonal Envelope and Minimum Diameter Filter Functions, patch by Jared Erickson Added: trunk/modules/library/main/src/main/java/org/geotools/filter/function/FilterFunction_minimumDiameter.java =================================================================== --- trunk/modules/library/main/src/main/java/org/geotools/filter/function/FilterFunction_minimumDiameter.java (rev 0) +++ trunk/modules/library/main/src/main/java/org/geotools/filter/function/FilterFunction_minimumDiameter.java 2012-04-16 00:35:58 UTC (rev 38671) @@ -0,0 +1,74 @@ +package org.geotools.filter.function; + +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2005-2008, Open Source Geospatial Foundation (OSGeo) + * + * 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. + */ +import com.vividsolutions.jts.geom.Geometry; +import org.geotools.filter.FunctionExpressionImpl; +import org.geotools.filter.capability.FunctionNameImpl; +import org.opengis.filter.capability.FunctionName; + +/** + * A FilterFunction that expects a Geometry and returns it's minimum diameter. + * @author Jared Erickson + * + * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/library/main/src/main/java/org/geotools/filter/function/FilterFunction_minimumDiameter.java $ + */ +public class FilterFunction_minimumDiameter extends FunctionExpressionImpl { + + /** + * The FunctionName + */ + public static FunctionName NAME = new FunctionNameImpl("minimumdiameter","geometry"); + + /** + * Create a new FilterFunction_minimumDiameter instance + */ + public FilterFunction_minimumDiameter() { + super(NAME); + } + + /** + * Get the number of arguments + * @return The number of arguments + */ + @Override + public int getArgCount() { + return 1; + } + + /** + * Calculate the Geometry's minimum diameter. + * @param feature The feature should be a Geometry + * @return The minimum diameter Geometry + * @throws IllegalArgumentException if the feature is not a Geometry + */ + @Override + public Object evaluate(Object feature) { + Geometry arg0; + + // attempt to get value and perform conversion + try { + arg0 = (Geometry) getExpression(0).evaluate(feature); + } catch (Exception e) { + // probably a type error + throw new IllegalArgumentException( + "Filter Function problem for function minimum diameter argument #0 - expected type Geometry"); + } + + return (StaticGeometry.minimumDiameter(arg0)); + } +} Added: trunk/modules/library/main/src/main/java/org/geotools/filter/function/FilterFunction_octagonalEnvelope.java =================================================================== --- trunk/modules/library/main/src/main/java/org/geotools/filter/function/FilterFunction_octagonalEnvelope.java (rev 0) +++ trunk/modules/library/main/src/main/java/org/geotools/filter/function/FilterFunction_octagonalEnvelope.java 2012-04-16 00:35:58 UTC (rev 38671) @@ -0,0 +1,74 @@ +package org.geotools.filter.function; + +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2005-2008, Open Source Geospatial Foundation (OSGeo) + * + * 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. + */ +import com.vividsolutions.jts.geom.Geometry; +import org.geotools.filter.FunctionExpressionImpl; +import org.geotools.filter.capability.FunctionNameImpl; +import org.opengis.filter.capability.FunctionName; + +/** + * A FilterFunction that expects a Geometry and returns it's octagonal envelope. + * @author Jared Erickson + * + * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/library/main/src/main/java/org/geotools/filter/function/FilterFunction_octagonalEnvelope.java $ + */ +public class FilterFunction_octagonalEnvelope extends FunctionExpressionImpl { + + /** + * The FunctionName + */ + public static FunctionName NAME = new FunctionNameImpl("octagonalenvelope","geometry"); + + /** + * Create a new FilterFunction_octagonalEnvelope instance + */ + public FilterFunction_octagonalEnvelope() { + super(NAME); + } + + /** + * Get the number of arguments + * @return The number of arguments + */ + @Override + public int getArgCount() { + return 1; + } + + /** + * Calculate the Geometry's octagonal envelope. + * @param feature The feature should be a Geometry + * @return The octagonal envelope Geometry + * @throws IllegalArgumentException if the feature is not a Geometry + */ + @Override + public Object evaluate(Object feature) { + Geometry arg0; + + // attempt to get value and perform conversion + try { + arg0 = (Geometry) getExpression(0).evaluate(feature); + } catch (Exception e) { + // probably a type error + throw new IllegalArgumentException( + "Filter Function problem for function octagonal envelope argument #0 - expected type Geometry"); + } + + return (StaticGeometry.octagonalEnvelope(arg0)); + } +} Modified: trunk/modules/library/main/src/main/java/org/geotools/filter/function/StaticGeometry.java =================================================================== --- trunk/modules/library/main/src/main/java/org/geotools/filter/function/StaticGeometry.java 2012-04-16 00:25:15 UTC (rev 38670) +++ trunk/modules/library/main/src/main/java/org/geotools/filter/function/StaticGeometry.java 2012-04-16 00:35:58 UTC (rev 38671) @@ -26,6 +26,7 @@ import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; +import com.vividsolutions.jts.geom.OctagonalEnvelope; import com.vividsolutions.jts.io.WKTReader; @@ -450,6 +451,18 @@ return min.getMinimumRectangle(); } + static public Geometry octagonalEnvelope(Geometry arg0) { + if (arg0 == null) return null; + OctagonalEnvelope env = new OctagonalEnvelope(arg0); + return env.toGeometry(arg0.getFactory()); + } + + static public Geometry minimumDiameter(Geometry arg0) { + if (arg0 == null) return null; + MinimumDiameter minDiameter = new MinimumDiameter(arg0); + return minDiameter.getDiameter(); + } + //-------------------------------------------------------------------------- //JAVA String functions static public String strConcat(String s1,String s2) Modified: trunk/modules/library/main/src/main/resources/META-INF/services/org.opengis.filter.expression.Function =================================================================== --- trunk/modules/library/main/src/main/resources/META-INF/services/org.opengis.filter.expression.Function 2012-04-16 00:25:15 UTC (rev 38670) +++ trunk/modules/library/main/src/main/resources/META-INF/services/org.opengis.filter.expression.Function 2012-04-16 00:35:58 UTC (rev 38671) @@ -70,6 +70,8 @@ org.geotools.filter.function.FilterFunction_minimumCircle org.geotools.filter.function.FilterFunction_minimumRectangle org.geotools.filter.function.FilterFunction_interiorRingN +org.geotools.filter.function.FilterFunction_octagonalEnvelope +org.geotools.filter.function.FilterFunction_minimumDiameter org.geotools.filter.function.FilterFunction_strConcat org.geotools.filter.function.FilterFunction_strEndsWith org.geotools.filter.function.FilterFunction_strStartsWith Copied: trunk/modules/library/main/src/main/resources/META-INF/services/org.opengis.filter.expression.Function.orig (from rev 38668, trunk/modules/library/main/src/main/resources/META-INF/services/org.opengis.filter.expression.Function) =================================================================== --- trunk/modules/library/main/src/main/resources/META-INF/services/org.opengis.filter.expression.Function.orig (rev 0) +++ trunk/modules/library/main/src/main/resources/META-INF/services/org.opengis.filter.expression.Function.orig 2012-04-16 00:35:58 UTC (rev 38671) @@ -0,0 +1,160 @@ +org.geotools.filter.AreaFunction +org.geotools.filter.LengthFunction +org.geotools.filter.function.CategorizeFunction +org.geotools.filter.function.ClassifyFunction +org.geotools.filter.function.EqualIntervalFunction +org.geotools.filter.function.StandardDeviationFunction +org.geotools.filter.function.QuantileFunction +org.geotools.filter.function.UniqueIntervalFunction +org.geotools.filter.function.Collection_AverageFunction +org.geotools.filter.function.Collection_BoundsFunction +org.geotools.filter.function.Collection_CountFunction +org.geotools.filter.function.Collection_MinFunction +org.geotools.filter.function.Collection_MedianFunction +org.geotools.filter.function.Collection_MaxFunction +org.geotools.filter.function.Collection_SumFunction +org.geotools.filter.function.Collection_UniqueFunction +org.geotools.filter.function.EnvFunction +org.geotools.filter.function.FilterFunction_contains +org.geotools.filter.function.FilterFunction_isEmpty +org.geotools.filter.function.FilterFunction_parseDouble +org.geotools.filter.function.FilterFunction_parseInt +org.geotools.filter.function.FilterFunction_parseLong +org.geotools.filter.function.FilterFunction_intersects +org.geotools.filter.function.FilterFunction_isClosed +org.geotools.filter.function.FilterFunction_geomFromWKT +org.geotools.filter.function.FilterFunction_toWKT +org.geotools.filter.function.FilterFunction_geomLength +org.geotools.filter.function.FilterFunction_isValid +org.geotools.filter.function.FilterFunction_geometryType +org.geotools.filter.function.FilterFunction_numPoints +org.geotools.filter.function.FilterFunction_isSimple +org.geotools.filter.function.FilterFunction_distance +org.geotools.filter.function.FilterFunction_isWithinDistance +org.geotools.filter.function.FilterFunction_area +org.geotools.filter.function.FilterFunction_centroid +org.geotools.filter.function.FilterFunction_interiorPoint +org.geotools.filter.function.FilterFunction_dimension +org.geotools.filter.function.FilterFunction_boundary +org.geotools.filter.function.FilterFunction_boundaryDimension +org.geotools.filter.function.FilterFunction_envelope +org.geotools.filter.function.FilterFunction_disjoint +org.geotools.filter.function.FilterFunction_touches +org.geotools.filter.function.FilterFunction_crosses +org.geotools.filter.function.FilterFunction_within +org.geotools.filter.function.FilterFunction_overlaps +org.geotools.filter.function.FilterFunction_relatePattern +org.geotools.filter.function.FilterFunction_relate +org.geotools.filter.function.FilterFunction_bufferWithSegments +org.geotools.filter.function.FilterFunction_buffer +org.geotools.filter.function.FilterFunction_convexHull +org.geotools.filter.function.FilterFunction_intersection +org.geotools.filter.function.FilterFunction_union +org.geotools.filter.function.FilterFunction_difference +org.geotools.filter.function.FilterFunction_symDifference +org.geotools.filter.function.FilterFunction_equalsExactTolerance +org.geotools.filter.function.FilterFunction_equalsExact +org.geotools.filter.function.FilterFunction_numGeometries +org.geotools.filter.function.FilterFunction_getGeometryN +org.geotools.filter.function.FilterFunction_getX +org.geotools.filter.function.FilterFunction_getY +org.geotools.filter.function.FilterFunction_getZ +org.geotools.filter.function.FilterFunction_pointN +org.geotools.filter.function.FilterFunction_startAngle +org.geotools.filter.function.FilterFunction_startPoint +org.geotools.filter.function.FilterFunction_endPoint +org.geotools.filter.function.FilterFunction_endAngle +org.geotools.filter.function.FilterFunction_isRing +org.geotools.filter.function.FilterFunction_exteriorRing +org.geotools.filter.function.FilterFunction_numInteriorRing +org.geotools.filter.function.FilterFunction_minimumCircle +org.geotools.filter.function.FilterFunction_minimumRectangle +org.geotools.filter.function.FilterFunction_interiorRingN +org.geotools.filter.function.FilterFunction_strConcat +org.geotools.filter.function.FilterFunction_strEndsWith +org.geotools.filter.function.FilterFunction_strStartsWith +org.geotools.filter.function.FilterFunction_strCapitalize +org.geotools.filter.function.FilterFunction_strEqualsIgnoreCase +org.geotools.filter.function.FilterFunction_strIndexOf +org.geotools.filter.function.FilterFunction_strLastIndexOf +org.geotools.filter.function.FilterFunction_strLength +org.geotools.filter.function.FilterFunction_strToLowerCase +org.geotools.filter.function.FilterFunction_strToUpperCase +org.geotools.filter.function.FilterFunction_strMatches +org.geotools.filter.function.FilterFunction_strPosition +org.geotools.filter.function.FilterFunction_strReplace +org.geotools.filter.function.FilterFunction_strSubstring +org.geotools.filter.function.FilterFunction_strSubstringStart +org.geotools.filter.function.FilterFunction_strTrim +org.geotools.filter.function.FilterFunction_strTrim2 +org.geotools.filter.function.FilterFunction_parseBoolean +org.geotools.filter.function.FilterFunction_roundDouble +org.geotools.filter.function.FilterFunction_int2ddouble +org.geotools.filter.function.FilterFunction_int2bbool +org.geotools.filter.function.FilterFunction_double2bool +org.geotools.filter.function.FilterFunction_if_then_else +org.geotools.filter.function.FilterFunction_equalTo +org.geotools.filter.function.FilterFunction_notEqualTo +org.geotools.filter.function.FilterFunction_lessThan +org.geotools.filter.function.FilterFunction_greaterThan +org.geotools.filter.function.FilterFunction_greaterEqualThan +org.geotools.filter.function.FilterFunction_lessEqualThan +org.geotools.filter.function.FilterFunction_isLike +org.geotools.filter.function.FilterFunction_isNull +org.geotools.filter.function.FilterFunction_between +org.geotools.filter.function.FilterFunction_not +org.geotools.filter.function.FilterFunction_in2 +org.geotools.filter.function.FilterFunction_in3 +org.geotools.filter.function.FilterFunction_in4 +org.geotools.filter.function.FilterFunction_in5 +org.geotools.filter.function.FilterFunction_in6 +org.geotools.filter.function.FilterFunction_in7 +org.geotools.filter.function.FilterFunction_in8 +org.geotools.filter.function.FilterFunction_in9 +org.geotools.filter.function.FilterFunction_in10 +org.geotools.filter.function.FilterFunction_dateParse +org.geotools.filter.function.FilterFunction_dateFormat +org.geotools.filter.function.FilterFunction_numberFormat +org.geotools.filter.function.FilterFunction_numberFormat2 +org.geotools.filter.function.FilterFunction_Convert +org.geotools.filter.function.FilterFunction_vertices +org.geotools.filter.function.FilterFunction_offset +org.geotools.filter.function.FilterFunction_isometric +org.geotools.filter.function.IDFunction +org.geotools.filter.function.InterpolateFunction +org.geotools.filter.function.RecodeFunction +org.geotools.filter.function.math.FilterFunction_IEEEremainder +org.geotools.filter.function.math.FilterFunction_abs +org.geotools.filter.function.math.FilterFunction_abs_2 +org.geotools.filter.function.math.FilterFunction_abs_3 +org.geotools.filter.function.math.FilterFunction_abs_4 +org.geotools.filter.function.math.FilterFunction_acos +org.geotools.filter.function.math.FilterFunction_asin +org.geotools.filter.function.math.FilterFunction_atan +org.geotools.filter.function.math.FilterFunction_atan2 +org.geotools.filter.function.math.FilterFunction_ceil +org.geotools.filter.function.math.FilterFunction_cos +org.geotools.filter.function.math.FilterFunction_exp +org.geotools.filter.function.math.FilterFunction_floor +org.geotools.filter.function.math.FilterFunction_log +org.geotools.filter.function.math.FilterFunction_max +org.geotools.filter.function.math.FilterFunction_max_2 +org.geotools.filter.function.math.FilterFunction_max_3 +org.geotools.filter.function.math.FilterFunction_max_4 +org.geotools.filter.function.math.FilterFunction_min +org.geotools.filter.function.math.FilterFunction_min_2 +org.geotools.filter.function.math.FilterFunction_min_3 +org.geotools.filter.function.math.FilterFunction_min_4 +org.geotools.filter.function.math.FilterFunction_pow +org.geotools.filter.function.math.FilterFunction_random +org.geotools.filter.function.math.FilterFunction_rint +org.geotools.filter.function.math.FilterFunction_round +org.geotools.filter.function.math.FilterFunction_round_2 +org.geotools.filter.function.math.FilterFunction_sin +org.geotools.filter.function.math.FilterFunction_sqrt +org.geotools.filter.function.math.FilterFunction_tan +org.geotools.filter.function.math.FilterFunction_toDegrees +org.geotools.filter.function.math.FilterFunction_toRadians +org.geotools.filter.function.math.PiFunction +org.geotools.filter.function.string.ConcatenateFunction +org.geotools.filter.function.JenksNaturalBreaksFunction \ No newline at end of file Added: trunk/modules/library/main/src/test/java/org/geotools/filter/function/FilterFunction_minimumDiameterTest.java =================================================================== --- trunk/modules/library/main/src/test/java/org/geotools/filter/function/FilterFunction_minimumDiameterTest.java (rev 0) +++ trunk/modules/library/main/src/test/java/org/geotools/filter/function/FilterFunction_minimumDiameterTest.java 2012-04-16 00:35:58 UTC (rev 38671) @@ -0,0 +1,86 @@ +package org.geotools.filter.function; + +import com.vividsolutions.jts.algorithm.MinimumDiameter; +import static org.junit.Assert.*; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.io.WKTReader; +import org.geotools.data.DataUtilities; +import org.geotools.data.memory.MemoryDataStore; +import org.geotools.data.simple.SimpleFeatureCollection; +import org.geotools.data.simple.SimpleFeatureIterator; +import org.geotools.factory.CommonFactoryFinder; +import org.geotools.factory.GeoTools; +import org.geotools.feature.simple.SimpleFeatureBuilder; +import org.junit.Test; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.filter.FilterFactory2; +import org.opengis.filter.expression.Function; + +/** + * The FilterFunction_minimumDiameter UnitTest + * @author Jared Erickson + */ +public class FilterFunction_minimumDiameterTest { + + /** + * Test of getArgCount method, of class FilterFunction_minimumDiameter. + */ + @Test + public void testGetArgCount() { + FilterFunction_minimumDiameter f = new FilterFunction_minimumDiameter(); + assertEquals(1, f.getArgCount()); + } + + /** + * Test of getName method, of class FilterFunction_minimumDiameter. + */ + @Test + public void getName() { + FilterFunction_minimumDiameter f = new FilterFunction_minimumDiameter(); + assertEquals("minimumdiameter", f.getName()); + } + + /** + * Test of evaluate method, of class FilterFunction_minimumDiameter. + */ + @Test + public void testEvaluate() throws Exception { + + // Create SimpleFeatures + SimpleFeatureType type = DataUtilities.createType("polygons", "id:int,geom:Polygon"); + MemoryDataStore store = new MemoryDataStore(); + store.createSchema(type); + String[] polygons = { + "POLYGON ((1235702.2034807256 707935.1879023351, 1229587.156498981 671715.2942412316, 1242287.6386918353 688649.2704983709, 1245109.9680680253 677359.9529936113, 1247932.297444215 711227.9055078899, 1239935.6975450104 705583.2467555101, 1235702.2034807256 707935.1879023351))", + "POLYGON ((1237113.3681688206 622324.5301579087, 1224883.274205331 586575.0247261701, 1258280.8384902447 589397.3541023601, 1237113.3681688206 622324.5301579087))", + "POLYGON ((1131746.4047910655 718754.1171777296, 1115282.8167632914 681593.4470578962, 1139272.6164609052 679241.5059110713, 1147269.2163601099 707935.1879023351, 1131746.4047910655 718754.1171777296)))" + }; + WKTReader reader = new WKTReader(); + SimpleFeature[] features = new SimpleFeature[polygons.length]; + for (int i = 0; i < polygons.length; i++) { + Geometry polygon = reader.read(polygons[i]); + features[i] = SimpleFeatureBuilder.build(type, new Object[]{i, polygon}, String.valueOf(i)); + } + store.addFeatures(features); + SimpleFeatureCollection featureCollection = store.getFeatureSource("polygons").getFeatures(); + + // Test the Function + FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints()); + Function exp = ff.function("minimumdiameter", ff.property("geom")); + SimpleFeatureIterator iter = featureCollection.features(); + while (iter.hasNext()) { + SimpleFeature feature = iter.next(); + Geometry geom = (Geometry) feature.getDefaultGeometry(); + Geometry minimumDiameter = new MinimumDiameter(geom).getDiameter(); + Object value = exp.evaluate(feature); + assertTrue(value instanceof LineString); + assertTrue(minimumDiameter.equalsExact((Geometry) value, 0.1)); + } + iter.close(); + + // Check for null safeness + assertNull(exp.evaluate(null)); + } +} Added: trunk/modules/library/main/src/test/java/org/geotools/filter/function/FilterFunction_octagonalEnvelopeTest.java =================================================================== --- trunk/modules/library/main/src/test/java/org/geotools/filter/function/FilterFunction_octagonalEnvelopeTest.java (rev 0) +++ trunk/modules/library/main/src/test/java/org/geotools/filter/function/FilterFunction_octagonalEnvelopeTest.java 2012-04-16 00:35:58 UTC (rev 38671) @@ -0,0 +1,86 @@ +package org.geotools.filter.function; + +import static org.junit.Assert.*; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.OctagonalEnvelope; +import com.vividsolutions.jts.geom.Polygon; +import com.vividsolutions.jts.io.WKTReader; +import org.geotools.data.DataUtilities; +import org.geotools.data.memory.MemoryDataStore; +import org.geotools.data.simple.SimpleFeatureCollection; +import org.geotools.data.simple.SimpleFeatureIterator; +import org.geotools.factory.CommonFactoryFinder; +import org.geotools.factory.GeoTools; +import org.geotools.feature.simple.SimpleFeatureBuilder; +import org.junit.Test; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.filter.FilterFactory2; +import org.opengis.filter.expression.Function; + +/** + * The FilterFunction_octagonalEnvelope UnitTest + * @author Jared Erickson + */ +public class FilterFunction_octagonalEnvelopeTest { + + /** + * Test of getArgCount method, of class FilterFunction_octagonalEnvelope. + */ + @Test + public void testGetArgCount() { + FilterFunction_octagonalEnvelope f = new FilterFunction_octagonalEnvelope(); + assertEquals(1, f.getArgCount()); + } + + /** + * Test of getName method, of class FilterFunction_octagonalEnvelope. + */ + @Test + public void getName() { + FilterFunction_octagonalEnvelope f = new FilterFunction_octagonalEnvelope(); + assertEquals("octagonalenvelope", f.getName()); + } + + /** + * Test of evaluate method, of class FilterFunction_octagonalEnvelope. + */ + @Test + public void testEvaluate() throws Exception { + + // Create SimpleFeatures + SimpleFeatureType type = DataUtilities.createType("polygons", "id:int,geom:Polygon"); + MemoryDataStore store = new MemoryDataStore(); + store.createSchema(type); + String[] polygons = { + "POLYGON ((1235702.2034807256 707935.1879023351, 1229587.156498981 671715.2942412316, 1242287.6386918353 688649.2704983709, 1245109.9680680253 677359.9529936113, 1247932.297444215 711227.9055078899, 1239935.6975450104 705583.2467555101, 1235702.2034807256 707935.1879023351))", + "POLYGON ((1237113.3681688206 622324.5301579087, 1224883.274205331 586575.0247261701, 1258280.8384902447 589397.3541023601, 1237113.3681688206 622324.5301579087))", + "POLYGON ((1131746.4047910655 718754.1171777296, 1115282.8167632914 681593.4470578962, 1139272.6164609052 679241.5059110713, 1147269.2163601099 707935.1879023351, 1131746.4047910655 718754.1171777296)))" + }; + WKTReader reader = new WKTReader(); + SimpleFeature[] features = new SimpleFeature[polygons.length]; + for (int i = 0; i < polygons.length; i++) { + Geometry polygon = reader.read(polygons[i]); + features[i] = SimpleFeatureBuilder.build(type, new Object[]{i, polygon}, String.valueOf(i)); + } + store.addFeatures(features); + SimpleFeatureCollection featureCollection = store.getFeatureSource("polygons").getFeatures(); + + // Test the Function + FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints()); + Function exp = ff.function("octagonalenvelope", ff.property("geom")); + SimpleFeatureIterator iter = featureCollection.features(); + while (iter.hasNext()) { + SimpleFeature feature = iter.next(); + Geometry geom = (Geometry) feature.getDefaultGeometry(); + Geometry octagonalEnvelope = new OctagonalEnvelope(geom).toGeometry(geom.getFactory()); + Object value = exp.evaluate(feature); + assertTrue(value instanceof Polygon); + assertTrue(octagonalEnvelope.equalsExact((Geometry) value, 0.1)); + } + iter.close(); + + // Check for null safeness + assertNull(exp.evaluate(null)); + } +} |