http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fe6cbccf/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerTest.java index a5dd4c9..708c612 100644 --- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerTest.java +++ b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerTest.java @@ -1,5 +1,3 @@ -package org.apache.rya.indexing.accumulo.geo; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -8,9 +6,9 @@ package org.apache.rya.indexing.accumulo.geo; * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -18,14 +16,21 @@ package org.apache.rya.indexing.accumulo.geo; * specific language governing permissions and limitations * under the License. */ +package org.apache.rya.indexing.accumulo.geo; import static org.apache.rya.api.resolver.RdfToRyaConversions.convertStatement; +import static org.apache.rya.indexing.GeoIndexingTestUtils.getSet; import java.util.Collections; -import java.util.HashSet; import java.util.Set; import org.apache.accumulo.core.client.admin.TableOperations; +import org.apache.rya.accumulo.AccumuloRdfConfiguration; +import org.apache.rya.indexing.GeoConstants; +import org.apache.rya.indexing.GeoIndexerType; +import org.apache.rya.indexing.OptionalConfigUtils; +import org.apache.rya.indexing.StatementConstraints; +import org.apache.rya.indexing.accumulo.ConfigUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -47,14 +52,8 @@ import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.geom.PrecisionModel; import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence; -import info.aduna.iteration.CloseableIteration; -import org.apache.rya.accumulo.AccumuloRdfConfiguration; -import org.apache.rya.indexing.GeoConstants; -import org.apache.rya.indexing.StatementConstraints; -import org.apache.rya.indexing.accumulo.ConfigUtils; - /** - * Tests higher level functioning of the geoindexer parse WKT, predicate list, + * Tests higher level functioning of the geoindexer parse WKT, predicate list, * prime and anti meridian, delete, search, context, search with Statement Constraints. */ public class GeoIndexerTest { @@ -62,27 +61,31 @@ public class GeoIndexerTest { private static final StatementConstraints EMPTY_CONSTRAINTS = new StatementConstraints(); private AccumuloRdfConfiguration conf; - GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326); + private final GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326); @Before public void before() throws Exception { conf = new AccumuloRdfConfiguration(); conf.setTablePrefix("triplestore_"); - String tableName = GeoMesaGeoIndexer.getTableName(conf); + final String tableName = GeoMesaGeoIndexer.getTableName(conf); conf.setBoolean(ConfigUtils.USE_MOCK_INSTANCE, true); conf.set(ConfigUtils.CLOUDBASE_USER, "USERNAME"); conf.set(ConfigUtils.CLOUDBASE_PASSWORD, "PASS"); + conf.set(ConfigUtils.CLOUDBASE_INSTANCE, "INSTANCE"); + conf.set(ConfigUtils.CLOUDBASE_ZOOKEEPERS, "localhost"); conf.set(ConfigUtils.CLOUDBASE_AUTHS, "U"); + conf.set(OptionalConfigUtils.USE_GEO, "true"); + conf.set(OptionalConfigUtils.GEO_INDEXER_TYPE, GeoIndexerType.GEO_MESA.toString()); - TableOperations tops = ConfigUtils.getConnector(conf).tableOperations(); + final TableOperations tops = ConfigUtils.getConnector(conf).tableOperations(); // get all of the table names with the prefix - Set<String> toDel = Sets.newHashSet(); - for (String t : tops.list()){ + final Set<String> toDel = Sets.newHashSet(); + for (final String t : tops.list()){ if (t.startsWith(tableName)){ toDel.add(t); } } - for (String t : toDel) { + for (final String t : toDel) { tops.delete(t); } } @@ -90,25 +93,25 @@ public class GeoIndexerTest { @Test public void testRestrictPredicatesSearch() throws Exception { conf.setStrings(ConfigUtils.GEO_PREDICATES_LIST, "pred:1,pred:2"); - try (GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { + try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { f.setConf(conf); - ValueFactory vf = new ValueFactoryImpl(); + final ValueFactory vf = new ValueFactoryImpl(); - Point point = gf.createPoint(new Coordinate(10, 10)); - Value pointValue = vf.createLiteral("Point(10 10)", GeoConstants.XMLSCHEMA_OGC_WKT); - URI invalidPredicate = GeoConstants.GEO_AS_WKT; + final Point point = gf.createPoint(new Coordinate(10, 10)); + final Value pointValue = vf.createLiteral("Point(10 10)", GeoConstants.XMLSCHEMA_OGC_WKT); + final URI invalidPredicate = GeoConstants.GEO_AS_WKT; // These should not be stored because they are not in the predicate list f.storeStatement(convertStatement(new StatementImpl(vf.createURI("foo:subj1"), invalidPredicate, pointValue))); f.storeStatement(convertStatement(new StatementImpl(vf.createURI("foo:subj2"), invalidPredicate, pointValue))); - URI pred1 = vf.createURI("pred:1"); - URI pred2 = vf.createURI("pred:2"); + final URI pred1 = vf.createURI("pred:1"); + final URI pred2 = vf.createURI("pred:2"); // These should be stored because they are in the predicate list - Statement s3 = new StatementImpl(vf.createURI("foo:subj3"), pred1, pointValue); - Statement s4 = new StatementImpl(vf.createURI("foo:subj4"), pred2, pointValue); + final Statement s3 = new StatementImpl(vf.createURI("foo:subj3"), pred1, pointValue); + final Statement s4 = new StatementImpl(vf.createURI("foo:subj4"), pred2, pointValue); f.storeStatement(convertStatement(s3)); f.storeStatement(convertStatement(s4)); @@ -120,60 +123,52 @@ public class GeoIndexerTest { f.flush(); - Set<Statement> actual = getSet(f.queryEquals(point, EMPTY_CONSTRAINTS)); + final Set<Statement> actual = getSet(f.queryEquals(point, EMPTY_CONSTRAINTS)); Assert.assertEquals(2, actual.size()); Assert.assertTrue(actual.contains(s3)); Assert.assertTrue(actual.contains(s4)); } } - private static <X> Set<X> getSet(CloseableIteration<X, ?> iter) throws Exception { - Set<X> set = new HashSet<X>(); - while (iter.hasNext()) { - set.add(iter.next()); - } - return set; - } - @Test public void testPrimeMeridianSearch() throws Exception { - try (GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { + try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { f.setConf(conf); - ValueFactory vf = new ValueFactoryImpl(); - Resource subject = vf.createURI("foo:subj"); - URI predicate = GeoConstants.GEO_AS_WKT; - Value object = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT); - Resource context = vf.createURI("foo:context"); + final ValueFactory vf = new ValueFactoryImpl(); + final Resource subject = vf.createURI("foo:subj"); + final URI predicate = GeoConstants.GEO_AS_WKT; + final Value object = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT); + final Resource context = vf.createURI("foo:context"); - Statement statement = new ContextStatementImpl(subject, predicate, object, context); + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); f.storeStatement(convertStatement(statement)); f.flush(); - double[] ONE = { 1, 1, -1, 1, -1, -1, 1, -1, 1, 1 }; - double[] TWO = { 2, 2, -2, 2, -2, -2, 2, -2, 2, 2 }; - double[] THREE = { 3, 3, -3, 3, -3, -3, 3, -3, 3, 3 }; + final double[] ONE = { 1, 1, -1, 1, -1, -1, 1, -1, 1, 1 }; + final double[] TWO = { 2, 2, -2, 2, -2, -2, 2, -2, 2, 2 }; + final double[] THREE = { 3, 3, -3, 3, -3, -3, 3, -3, 3, 3 }; - LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(ONE, 2)); - LinearRing r2 = gf.createLinearRing(new PackedCoordinateSequence.Double(TWO, 2)); - LinearRing r3 = gf.createLinearRing(new PackedCoordinateSequence.Double(THREE, 2)); + final LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(ONE, 2)); + final LinearRing r2 = gf.createLinearRing(new PackedCoordinateSequence.Double(TWO, 2)); + final LinearRing r3 = gf.createLinearRing(new PackedCoordinateSequence.Double(THREE, 2)); - Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); - Polygon p2 = gf.createPolygon(r2, new LinearRing[] {}); - Polygon p3 = gf.createPolygon(r3, new LinearRing[] {}); + final Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); + final Polygon p2 = gf.createPolygon(r2, new LinearRing[] {}); + final Polygon p3 = gf.createPolygon(r3, new LinearRing[] {}); Assert.assertEquals(Sets.newHashSet(statement), getSet(f.queryWithin(p1, EMPTY_CONSTRAINTS))); Assert.assertEquals(Sets.newHashSet(statement), getSet(f.queryWithin(p2, EMPTY_CONSTRAINTS))); Assert.assertEquals(Sets.newHashSet(statement), getSet(f.queryWithin(p3, EMPTY_CONSTRAINTS))); // Test a ring with a hole in it - Polygon p3m2 = gf.createPolygon(r3, new LinearRing[] { r2 }); + final Polygon p3m2 = gf.createPolygon(r3, new LinearRing[] { r2 }); Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(p3m2, EMPTY_CONSTRAINTS))); // test a ring outside the point - double[] OUT = { 3, 3, 1, 3, 1, 1, 3, 1, 3, 3 }; - LinearRing rOut = gf.createLinearRing(new PackedCoordinateSequence.Double(OUT, 2)); - Polygon pOut = gf.createPolygon(rOut, new LinearRing[] {}); + final double[] OUT = { 3, 3, 1, 3, 1, 1, 3, 1, 3, 3 }; + final LinearRing rOut = gf.createLinearRing(new PackedCoordinateSequence.Double(OUT, 2)); + final Polygon pOut = gf.createPolygon(rOut, new LinearRing[] {}); Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(pOut, EMPTY_CONSTRAINTS))); } } @@ -181,28 +176,28 @@ public class GeoIndexerTest { @Test public void testDcSearch() throws Exception { // test a ring around dc - try (GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { + try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { f.setConf(conf); - ValueFactory vf = new ValueFactoryImpl(); - Resource subject = vf.createURI("foo:subj"); - URI predicate = GeoConstants.GEO_AS_WKT; - Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); - Resource context = vf.createURI("foo:context"); + final ValueFactory vf = new ValueFactoryImpl(); + final Resource subject = vf.createURI("foo:subj"); + final URI predicate = GeoConstants.GEO_AS_WKT; + final Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); + final Resource context = vf.createURI("foo:context"); - Statement statement = new ContextStatementImpl(subject, predicate, object, context); + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); f.storeStatement(convertStatement(statement)); f.flush(); - double[] IN = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; - LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(IN, 2)); - Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); + final double[] IN = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; + final LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(IN, 2)); + final Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); Assert.assertEquals(Sets.newHashSet(statement), getSet(f.queryWithin(p1, EMPTY_CONSTRAINTS))); // test a ring outside the point - double[] OUT = { -77, 39, -76, 39, -76, 38, -77, 38, -77, 39 }; - LinearRing rOut = gf.createLinearRing(new PackedCoordinateSequence.Double(OUT, 2)); - Polygon pOut = gf.createPolygon(rOut, new LinearRing[] {}); + final double[] OUT = { -77, 39, -76, 39, -76, 38, -77, 38, -77, 39 }; + final LinearRing rOut = gf.createLinearRing(new PackedCoordinateSequence.Double(OUT, 2)); + final Polygon pOut = gf.createPolygon(rOut, new LinearRing[] {}); Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(pOut, EMPTY_CONSTRAINTS))); } } @@ -210,38 +205,38 @@ public class GeoIndexerTest { @Test public void testDeleteSearch() throws Exception { // test a ring around dc - try (GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { + try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { f.setConf(conf); - ValueFactory vf = new ValueFactoryImpl(); - Resource subject = vf.createURI("foo:subj"); - URI predicate = GeoConstants.GEO_AS_WKT; - Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); - Resource context = vf.createURI("foo:context"); + final ValueFactory vf = new ValueFactoryImpl(); + final Resource subject = vf.createURI("foo:subj"); + final URI predicate = GeoConstants.GEO_AS_WKT; + final Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); + final Resource context = vf.createURI("foo:context"); - Statement statement = new ContextStatementImpl(subject, predicate, object, context); + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); f.storeStatement(convertStatement(statement)); f.flush(); f.deleteStatement(convertStatement(statement)); // test a ring that the point would be inside of if not deleted - double[] in = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; - LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(in, 2)); - Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); + final double[] in = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; + final LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(in, 2)); + final Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(p1, EMPTY_CONSTRAINTS))); // test a ring that the point would be outside of if not deleted - double[] out = { -77, 39, -76, 39, -76, 38, -77, 38, -77, 39 }; - LinearRing rOut = gf.createLinearRing(new PackedCoordinateSequence.Double(out, 2)); - Polygon pOut = gf.createPolygon(rOut, new LinearRing[] {}); + final double[] out = { -77, 39, -76, 39, -76, 38, -77, 38, -77, 39 }; + final LinearRing rOut = gf.createLinearRing(new PackedCoordinateSequence.Double(out, 2)); + final Polygon pOut = gf.createPolygon(rOut, new LinearRing[] {}); Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(pOut, EMPTY_CONSTRAINTS))); // test a ring for the whole world and make sure the point is gone // Geomesa is a little sensitive around lon 180, so we only go to 179 - double[] world = { -180, 90, 179, 90, 179, -90, -180, -90, -180, 90 }; - LinearRing rWorld = gf.createLinearRing(new PackedCoordinateSequence.Double(world, 2)); - Polygon pWorld = gf.createPolygon(rWorld, new LinearRing[] {}); + final double[] world = { -180, 90, 179, 90, 179, -90, -180, -90, -180, 90 }; + final LinearRing rWorld = gf.createLinearRing(new PackedCoordinateSequence.Double(world, 2)); + final Polygon pWorld = gf.createPolygon(rWorld, new LinearRing[] {}); Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(pWorld, EMPTY_CONSTRAINTS))); } } @@ -249,22 +244,22 @@ public class GeoIndexerTest { @Test public void testDcSearchWithContext() throws Exception { // test a ring around dc - try (GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { + try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { f.setConf(conf); - ValueFactory vf = new ValueFactoryImpl(); - Resource subject = vf.createURI("foo:subj"); - URI predicate = GeoConstants.GEO_AS_WKT; - Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); - Resource context = vf.createURI("foo:context"); + final ValueFactory vf = new ValueFactoryImpl(); + final Resource subject = vf.createURI("foo:subj"); + final URI predicate = GeoConstants.GEO_AS_WKT; + final Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); + final Resource context = vf.createURI("foo:context"); - Statement statement = new ContextStatementImpl(subject, predicate, object, context); + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); f.storeStatement(convertStatement(statement)); f.flush(); - double[] IN = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; - LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(IN, 2)); - Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); + final double[] IN = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; + final LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(IN, 2)); + final Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); // query with correct context Assert.assertEquals(Sets.newHashSet(statement), getSet(f.queryWithin(p1, new StatementConstraints().setContext(context)))); @@ -278,22 +273,22 @@ public class GeoIndexerTest { @Test public void testDcSearchWithSubject() throws Exception { // test a ring around dc - try (GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { + try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { f.setConf(conf); - ValueFactory vf = new ValueFactoryImpl(); - Resource subject = vf.createURI("foo:subj"); - URI predicate = GeoConstants.GEO_AS_WKT; - Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); - Resource context = vf.createURI("foo:context"); + final ValueFactory vf = new ValueFactoryImpl(); + final Resource subject = vf.createURI("foo:subj"); + final URI predicate = GeoConstants.GEO_AS_WKT; + final Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); + final Resource context = vf.createURI("foo:context"); - Statement statement = new ContextStatementImpl(subject, predicate, object, context); + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); f.storeStatement(convertStatement(statement)); f.flush(); - double[] IN = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; - LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(IN, 2)); - Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); + final double[] IN = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; + final LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(IN, 2)); + final Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); // query with correct subject Assert.assertEquals(Sets.newHashSet(statement), getSet(f.queryWithin(p1, new StatementConstraints().setSubject(subject)))); @@ -306,22 +301,22 @@ public class GeoIndexerTest { @Test public void testDcSearchWithSubjectAndContext() throws Exception { // test a ring around dc - try (GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { + try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { f.setConf(conf); - ValueFactory vf = new ValueFactoryImpl(); - Resource subject = vf.createURI("foo:subj"); - URI predicate = GeoConstants.GEO_AS_WKT; - Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); - Resource context = vf.createURI("foo:context"); + final ValueFactory vf = new ValueFactoryImpl(); + final Resource subject = vf.createURI("foo:subj"); + final URI predicate = GeoConstants.GEO_AS_WKT; + final Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); + final Resource context = vf.createURI("foo:context"); - Statement statement = new ContextStatementImpl(subject, predicate, object, context); + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); f.storeStatement(convertStatement(statement)); f.flush(); - double[] IN = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; - LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(IN, 2)); - Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); + final double[] IN = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; + final LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(IN, 2)); + final Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); // query with correct context subject Assert.assertEquals(Sets.newHashSet(statement), @@ -339,22 +334,22 @@ public class GeoIndexerTest { @Test public void testDcSearchWithPredicate() throws Exception { // test a ring around dc - try (GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { + try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { f.setConf(conf); - ValueFactory vf = new ValueFactoryImpl(); - Resource subject = vf.createURI("foo:subj"); - URI predicate = GeoConstants.GEO_AS_WKT; - Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); - Resource context = vf.createURI("foo:context"); + final ValueFactory vf = new ValueFactoryImpl(); + final Resource subject = vf.createURI("foo:subj"); + final URI predicate = GeoConstants.GEO_AS_WKT; + final Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT); + final Resource context = vf.createURI("foo:context"); - Statement statement = new ContextStatementImpl(subject, predicate, object, context); + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); f.storeStatement(convertStatement(statement)); f.flush(); - double[] IN = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; - LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(IN, 2)); - Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); + final double[] IN = { -78, 39, -77, 39, -77, 38, -78, 38, -78, 39 }; + final LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(IN, 2)); + final Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); // query with correct Predicate Assert.assertEquals(Sets.newHashSet(statement), @@ -369,31 +364,31 @@ public class GeoIndexerTest { // @Test public void testAntiMeridianSearch() throws Exception { // verify that a search works if the bounding box crosses the anti meridian - try (GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { + try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { f.setConf(conf); - ValueFactory vf = new ValueFactoryImpl(); - Resource context = vf.createURI("foo:context"); + final ValueFactory vf = new ValueFactoryImpl(); + final Resource context = vf.createURI("foo:context"); - Resource subjectEast = vf.createURI("foo:subj:east"); - URI predicateEast = GeoConstants.GEO_AS_WKT; - Value objectEast = vf.createLiteral("Point(179 0)", GeoConstants.XMLSCHEMA_OGC_WKT); - Statement statementEast = new ContextStatementImpl(subjectEast, predicateEast, objectEast, context); + final Resource subjectEast = vf.createURI("foo:subj:east"); + final URI predicateEast = GeoConstants.GEO_AS_WKT; + final Value objectEast = vf.createLiteral("Point(179 0)", GeoConstants.XMLSCHEMA_OGC_WKT); + final Statement statementEast = new ContextStatementImpl(subjectEast, predicateEast, objectEast, context); f.storeStatement(convertStatement(statementEast)); - Resource subjectWest = vf.createURI("foo:subj:west"); - URI predicateWest = GeoConstants.GEO_AS_WKT; - Value objectWest = vf.createLiteral("Point(-179 0)", GeoConstants.XMLSCHEMA_OGC_WKT); - Statement statementWest = new ContextStatementImpl(subjectWest, predicateWest, objectWest, context); + final Resource subjectWest = vf.createURI("foo:subj:west"); + final URI predicateWest = GeoConstants.GEO_AS_WKT; + final Value objectWest = vf.createLiteral("Point(-179 0)", GeoConstants.XMLSCHEMA_OGC_WKT); + final Statement statementWest = new ContextStatementImpl(subjectWest, predicateWest, objectWest, context); f.storeStatement(convertStatement(statementWest)); f.flush(); - double[] ONE = { 178.1, 1, -178, 1, -178, -1, 178.1, -1, 178.1, 1 }; + final double[] ONE = { 178.1, 1, -178, 1, -178, -1, 178.1, -1, 178.1, 1 }; - LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(ONE, 2)); + final LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(ONE, 2)); - Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); + final Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); Assert.assertEquals(Sets.newHashSet(statementEast, statementWest), getSet(f.queryWithin(p1, EMPTY_CONSTRAINTS))); }
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fe6cbccf/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveFeatureReaderTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveFeatureReaderTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveFeatureReaderTest.java new file mode 100644 index 0000000..e6ff81a --- /dev/null +++ b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveFeatureReaderTest.java @@ -0,0 +1,385 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.rya.indexing.accumulo.geo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.apache.accumulo.core.client.AccumuloException; +import org.apache.accumulo.core.client.AccumuloSecurityException; +import org.apache.accumulo.core.client.TableNotFoundException; +import org.apache.accumulo.core.client.admin.TableOperations; +import org.apache.rya.accumulo.AccumuloRdfConfiguration; +import org.apache.rya.indexing.GeoIndexerType; +import org.apache.rya.indexing.OptionalConfigUtils; +import org.apache.rya.indexing.accumulo.ConfigUtils; +import org.geotools.data.DataStore; +import org.geotools.data.DataUtilities; +import org.geotools.data.DefaultTransaction; +import org.geotools.data.DelegatingFeatureReader; +import org.geotools.data.FeatureReader; +import org.geotools.data.FeatureWriter; +import org.geotools.data.Query; +import org.geotools.data.Transaction; +import org.geotools.feature.SchemaException; +import org.geotools.feature.visitor.MaxVisitor; +import org.geotools.feature.visitor.MinVisitor; +import org.geotools.filter.FilterFactoryImpl; +import org.geotools.filter.text.cql2.CQLException; +import org.geotools.filter.text.ecql.ECQL; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.filter.Filter; + +import com.google.common.collect.Sets; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.PrecisionModel; + +import mil.nga.giat.geowave.adapter.vector.plugin.GeoWaveFeatureReader; +import mil.nga.giat.geowave.adapter.vector.utils.DateUtilities; + +/** + * Tests the {@link FeatureReader} capabilities within the + * {@link GeoWaveGeoIndexer). + */ +public class GeoWaveFeatureReaderTest { + private DataStore dataStore; + private SimpleFeatureType type; + private final GeometryFactory factory = new GeometryFactory(new PrecisionModel(PrecisionModel.FIXED)); + private Query query = null; + private final List<String> fids = new ArrayList<>(); + private final List<String> pids = new ArrayList<>(); + private Date stime, etime; + + private AccumuloRdfConfiguration conf; + + private void setupConf() throws AccumuloException, AccumuloSecurityException, TableNotFoundException { + conf = new AccumuloRdfConfiguration(); + conf.setTablePrefix("triplestore_"); + final String tableName = GeoWaveGeoIndexer.getTableName(conf); + conf.setBoolean(ConfigUtils.USE_MOCK_INSTANCE, true); + conf.set(ConfigUtils.CLOUDBASE_USER, "USERNAME"); + conf.set(ConfigUtils.CLOUDBASE_PASSWORD, "PASS"); + conf.set(ConfigUtils.CLOUDBASE_INSTANCE, "INSTANCE"); + conf.set(ConfigUtils.CLOUDBASE_ZOOKEEPERS, "localhost"); + conf.set(ConfigUtils.CLOUDBASE_AUTHS, "U"); + conf.set(OptionalConfigUtils.USE_GEO, "true"); + conf.set(OptionalConfigUtils.GEO_INDEXER_TYPE, GeoIndexerType.GEO_WAVE.toString()); + + final TableOperations tops = ConfigUtils.getConnector(conf).tableOperations(); + // get all of the table names with the prefix + final Set<String> toDel = Sets.newHashSet(); + for (final String t : tops.list()) { + if (t.startsWith(tableName)) { + toDel.add(t); + } + } + for (final String t : toDel) { + tops.delete(t); + } + } + + @Before + public void setup() throws SchemaException, CQLException, Exception { + setupConf(); + try (final GeoWaveGeoIndexer indexer = new GeoWaveGeoIndexer()) { + indexer.setConf(conf); + dataStore = indexer.getGeoToolsDataStore(); + // Clear old data + indexer.purge(conf); + + type = DataUtilities.createType( + "GeoWaveFeatureReaderTest", + "geometry:Geometry:srid=4326,start:Date,end:Date,pop:java.lang.Long,pid:String"); + + dataStore.createSchema(type); + + stime = DateUtilities.parseISO("2005-05-15T20:32:56Z"); + etime = DateUtilities.parseISO("2005-05-20T20:32:56Z"); + + final Transaction transaction1 = new DefaultTransaction(); + final FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriter( + type.getTypeName(), + transaction1); + assertFalse(writer.hasNext()); + SimpleFeature newFeature = writer.next(); + newFeature.setAttribute( + "pop", + Long.valueOf(100)); + newFeature.setAttribute( + "pid", + "a" + UUID.randomUUID().toString()); + newFeature.setAttribute( + "start", + stime); + newFeature.setAttribute( + "end", + etime); + newFeature.setAttribute( + "geometry", + factory.createPoint(new Coordinate(27.25, 41.25))); + fids.add(newFeature.getID()); + pids.add(newFeature.getAttribute("pid").toString()); + writer.write(); + newFeature = writer.next(); + newFeature.setAttribute( + "pop", + Long.valueOf(101)); + newFeature.setAttribute( + "pid", + "b" + UUID.randomUUID().toString()); + newFeature.setAttribute( + "start", + etime); + newFeature.setAttribute( + "geometry", + factory.createPoint(new Coordinate(28.25, 41.25))); + fids.add(newFeature.getID()); + pids.add(newFeature.getAttribute("pid").toString()); + writer.write(); + writer.close(); + transaction1.commit(); + transaction1.close(); + + query = new Query( + "GeoWaveFeatureReaderTest", + ECQL.toFilter("IN ('" + fids.get(0) + "')"), + new String[] { + "geometry", + "pid" + }); + } + } + + @After + public void tearDown() { + dataStore.dispose(); + } + + @Test + public void testFID() throws IllegalArgumentException, NoSuchElementException, IOException, CQLException { + final FeatureReader<SimpleFeatureType, SimpleFeature> reader = + dataStore.getFeatureReader(query, Transaction.AUTO_COMMIT); + int count = 0; + while (reader.hasNext()) { + final SimpleFeature feature = reader.next(); + assertTrue(fids.contains(feature.getID())); + count++; + } + assertTrue(count > 0); + } + + @Test + public void testFidFilterQuery() throws IllegalArgumentException, NoSuchElementException, IOException, CQLException { + final String fidsString = fids.stream().collect(Collectors.joining("','", "'", "'")); + final Filter filter = ECQL.toFilter("IN (" + fidsString + ")"); + final Query query = new Query( + "GeoWaveFeatureReaderTest", + filter, + new String[] { + "geometry", + "pid" + }); + final FeatureReader<SimpleFeatureType, SimpleFeature> reader = + dataStore.getFeatureReader(query, Transaction.AUTO_COMMIT); + int count = 0; + while (reader.hasNext()) { + final SimpleFeature feature = reader.next(); + assertTrue(fids.contains(feature.getID())); + count++; + } + assertTrue(count == fids.size()); + } + + @Test + public void testPidFilterQuery() throws IllegalArgumentException, NoSuchElementException, IOException, CQLException { + // Filter it so that it only queries for everything but the first pid. + // There's only 2 pids total so it should just return the second one. + final String pidsString = pids.subList(1, pids.size()).stream().collect(Collectors.joining("','", "'", "'")); + final Filter filter = ECQL.toFilter("pid IN (" + pidsString + ")"); + final Query query = new Query( + "GeoWaveFeatureReaderTest", + filter, + new String[] { + "geometry", + "pid" + }); + final FeatureReader<SimpleFeatureType, SimpleFeature> reader = + dataStore.getFeatureReader(query, Transaction.AUTO_COMMIT); + int count = 0; + while (reader.hasNext()) { + final SimpleFeature feature = reader.next(); + assertTrue(fids.contains(feature.getID())); + count++; + } + assertTrue(count == pids.size() - 1); + } + + + @Test + public void testBBOX() throws IllegalArgumentException, NoSuchElementException, IOException { + final FilterFactoryImpl factory = new FilterFactoryImpl(); + final Query query = new Query( + "GeoWaveFeatureReaderTest", + factory.bbox( + "", + -180, + -90, + 180, + 90, + "EPSG:4326"), + new String[] { + "geometry", + "pid" + }); + + final FeatureReader<SimpleFeatureType, SimpleFeature> reader = + dataStore.getFeatureReader(query, Transaction.AUTO_COMMIT); + int count = 0; + while (reader.hasNext()) { + final SimpleFeature feature = reader.next(); + assertTrue(fids.contains(feature.getID())); + count++; + } + assertTrue(count > 0); + } + + @Test + public void testRangeIndex() throws IllegalArgumentException, NoSuchElementException, IOException { + final FeatureReader<SimpleFeatureType, SimpleFeature> reader = + dataStore.getFeatureReader(query, Transaction.AUTO_COMMIT); + int count = 0; + while (reader.hasNext()) { + final SimpleFeature feature = reader.next(); + assertTrue(fids.contains(feature.getID())); + count++; + } + assertEquals(1, count); + } + + @Test + public void testLike() throws IllegalArgumentException, NoSuchElementException, IOException, CQLException { + final Query query = new Query( + "GeoWaveFeatureReaderTest", + ECQL.toFilter("pid like '" + pids.get( + 0).substring( + 0, + 1) + "%'"), + new String[] { + "geometry", + "pid" + }); + final FeatureReader<SimpleFeatureType, SimpleFeature> reader = + dataStore.getFeatureReader(query, Transaction.AUTO_COMMIT); + int count = 0; + while (reader.hasNext()) { + final SimpleFeature feature = reader.next(); + assertTrue(fids.contains(feature.getID())); + count++; + } + assertEquals(1, count); + } + + @Test + public void testRemoveFeature() throws IllegalArgumentException, NoSuchElementException, IOException, CQLException { + final Query query = new Query( + "GeoWaveFeatureReaderTest", + ECQL.toFilter("pid like '" + pids.get( + 0).substring( + 0, + 1) + "%'"), + new String[] { + "geometry", + "pid" + }); + final FeatureReader<SimpleFeatureType, SimpleFeature> reader = + dataStore.getFeatureReader(query, Transaction.AUTO_COMMIT); + int count = 0; + while (reader.hasNext()) { + final SimpleFeature feature = reader.next(); + assertTrue(fids.contains(feature.getID())); + count++; + } + assertEquals(1, count); + + // Remove + final FeatureWriter<SimpleFeatureType, SimpleFeature> writer = + dataStore.getFeatureWriter(type.getTypeName(), Transaction.AUTO_COMMIT); + try { + while (writer.hasNext()) { + writer.next(); + writer.remove(); + } + } finally { + writer.close(); + } + + // Re-query + final FeatureReader<SimpleFeatureType, SimpleFeature> reader2 = + dataStore.getFeatureReader(query, Transaction.AUTO_COMMIT); + int recount = 0; + while (reader2.hasNext()) { + reader2.next(); + recount++; + } + assertEquals(0, recount); + } + + @Test + public void testMax() throws IllegalArgumentException, NoSuchElementException, IOException { + final FeatureReader<SimpleFeatureType, SimpleFeature> reader = + dataStore.getFeatureReader(query, Transaction.AUTO_COMMIT); + final MaxVisitor visitor = new MaxVisitor("start", type); + unwrapDelegatingFeatureReader(reader).getFeatureCollection().accepts(visitor, null); + assertTrue(visitor.getMax().equals(etime)); + } + + @Test + public void testMin() throws IllegalArgumentException, NoSuchElementException, IOException { + final FeatureReader<SimpleFeatureType, SimpleFeature> reader = + dataStore.getFeatureReader(query, Transaction.AUTO_COMMIT); + final MinVisitor visitor = new MinVisitor("start", type); + unwrapDelegatingFeatureReader(reader).getFeatureCollection().accepts(visitor, null); + assertTrue(visitor.getMin().equals(stime)); + } + + private GeoWaveFeatureReader unwrapDelegatingFeatureReader(final FeatureReader<SimpleFeatureType, SimpleFeature> reader ) { + // GeoTools uses decorator pattern to wrap FeatureReaders + // we need to get down to the inner GeoWaveFeatureReader + FeatureReader<SimpleFeatureType, SimpleFeature> currReader = reader; + while (!(currReader instanceof GeoWaveFeatureReader)) { + currReader = ((DelegatingFeatureReader<SimpleFeatureType, SimpleFeature>) currReader).getDelegate(); + } + return (GeoWaveFeatureReader) currReader; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fe6cbccf/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGTQueryTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGTQueryTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGTQueryTest.java new file mode 100644 index 0000000..778b5ef --- /dev/null +++ b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGTQueryTest.java @@ -0,0 +1,254 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.rya.indexing.accumulo.geo; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.accumulo.core.client.AccumuloException; +import org.apache.accumulo.core.client.AccumuloSecurityException; +import org.apache.accumulo.minicluster.impl.MiniAccumuloClusterImpl; +import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl; +import org.apache.commons.io.FileUtils; +import org.geotools.feature.AttributeTypeBuilder; +import org.geotools.feature.simple.SimpleFeatureBuilder; +import org.geotools.feature.simple.SimpleFeatureTypeBuilder; +import org.geotools.filter.text.cql2.CQLException; +import org.geotools.filter.text.ecql.ECQL; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.filter.Filter; + +import com.google.common.collect.ImmutableMap; +import com.google.common.io.Files; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Envelope; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.Polygon; + +import mil.nga.giat.geowave.adapter.vector.FeatureDataAdapter; +import mil.nga.giat.geowave.adapter.vector.query.cql.CQLQuery; +import mil.nga.giat.geowave.core.geotime.GeometryUtils; +import mil.nga.giat.geowave.core.geotime.ingest.SpatialDimensionalityTypeProvider; +import mil.nga.giat.geowave.core.geotime.store.query.SpatialQuery; +import mil.nga.giat.geowave.core.store.CloseableIterator; +import mil.nga.giat.geowave.core.store.DataStore; +import mil.nga.giat.geowave.core.store.IndexWriter; +import mil.nga.giat.geowave.core.store.index.PrimaryIndex; +import mil.nga.giat.geowave.core.store.query.QueryOptions; +import mil.nga.giat.geowave.datastore.accumulo.AccumuloDataStore; +import mil.nga.giat.geowave.datastore.accumulo.BasicAccumuloOperations; +import mil.nga.giat.geowave.datastore.accumulo.minicluster.MiniAccumuloClusterFactory; + +/** + * This class is intended to provide a self-contained, easy-to-follow example of + * a few GeoTools queries against GeoWave. For simplicity, a MiniAccumuloCluster + * is spun up and a few points from the DC area are ingested (Washington + * Monument, White House, FedEx Field). Two queries are executed against this + * data set. + */ +public class GeoWaveGTQueryTest { + private static File tempAccumuloDir; + private static MiniAccumuloClusterImpl accumulo; + private static DataStore dataStore; + + private static final PrimaryIndex INDEX = new SpatialDimensionalityTypeProvider().createPrimaryIndex(); + + // Points (to be ingested into GeoWave Data Store) + private static final Coordinate WASHINGTON_MONUMENT = new Coordinate(-77.0352, 38.8895); + private static final Coordinate WHITE_HOUSE = new Coordinate(-77.0366, 38.8977); + private static final Coordinate FEDEX_FIELD = new Coordinate(-76.8644, 38.9078); + + // cities used to construct Geometries for queries + private static final Coordinate BALTIMORE = new Coordinate(-76.6167, 39.2833); + private static final Coordinate RICHMOND = new Coordinate(-77.4667, 37.5333); + private static final Coordinate HARRISONBURG = new Coordinate(-78.8689, 38.4496); + + private static final Map<String, Coordinate> CANNED_DATA = ImmutableMap.of( + "Washington Monument", WASHINGTON_MONUMENT, + "White House", WHITE_HOUSE, + "FedEx Field", FEDEX_FIELD + ); + + private static final FeatureDataAdapter ADAPTER = new FeatureDataAdapter(getPointSimpleFeatureType()); + + private static final String ACCUMULO_USER = "root"; + private static final String ACCUMULO_PASSWORD = "password"; + private static final String TABLE_NAMESPACE = ""; + + @BeforeClass + public static void setup() throws AccumuloException, AccumuloSecurityException, IOException, InterruptedException { + tempAccumuloDir = Files.createTempDir(); + + accumulo = MiniAccumuloClusterFactory.newAccumuloCluster( + new MiniAccumuloConfigImpl(tempAccumuloDir, ACCUMULO_PASSWORD), + GeoWaveGTQueryTest.class); + + accumulo.start(); + + dataStore = new AccumuloDataStore( + new BasicAccumuloOperations( + accumulo.getZooKeepers(), + accumulo.getInstanceName(), + ACCUMULO_USER, + ACCUMULO_PASSWORD, + TABLE_NAMESPACE)); + + ingestCannedData(); + } + + private static void ingestCannedData() throws IOException { + final List<SimpleFeature> points = new ArrayList<>(); + + System.out.println("Building SimpleFeatures from canned data set..."); + + for (final Entry<String, Coordinate> entry : CANNED_DATA.entrySet()) { + System.out.println("Added point: " + entry.getKey()); + points.add(buildSimpleFeature(entry.getKey(), entry.getValue())); + } + + System.out.println("Ingesting canned data..."); + + try (final IndexWriter<SimpleFeature> indexWriter = dataStore.createWriter(ADAPTER, INDEX)) { + for (final SimpleFeature sf : points) { + indexWriter.write(sf); + } + } + + System.out.println("Ingest complete."); + } + + @Test + public void executeCQLQueryTest() throws IOException, CQLException { + System.out.println("Executing query, expecting to match two points..."); + + final Filter cqlFilter = ECQL.toFilter("BBOX(geometry,-77.6167,38.6833,-76.6,38.9200) and locationName like 'W%'"); + + final QueryOptions queryOptions = new QueryOptions(ADAPTER, INDEX); + final CQLQuery cqlQuery = new CQLQuery(null, cqlFilter, ADAPTER); + + try (final CloseableIterator<SimpleFeature> iterator = dataStore.query(queryOptions, cqlQuery)) { + int count = 0; + while (iterator.hasNext()) { + System.out.println("Query match: " + iterator.next().getID()); + count++; + } + System.out.println("executeCQLQueryTest count: " + count); + // Should match "Washington Monument" and "White House" + assertEquals(2, count); + } + } + + @Test + public void executeBoundingBoxQueryTest() throws IOException { + System.out.println("Constructing bounding box for the area contained by [Baltimore, MD and Richmond, VA."); + + final Geometry boundingBox = GeometryUtils.GEOMETRY_FACTORY.toGeometry(new Envelope( + BALTIMORE, + RICHMOND)); + + System.out.println("Executing query, expecting to match ALL points..."); + + final QueryOptions queryOptions = new QueryOptions(ADAPTER, INDEX); + final SpatialQuery spatialQuery = new SpatialQuery(boundingBox); + + try (final CloseableIterator<SimpleFeature> iterator = dataStore.query(queryOptions, spatialQuery)) { + int count = 0; + while (iterator.hasNext()) { + System.out.println("Query match: " + iterator.next().getID()); + count++; + } + System.out.println("executeBoundingBoxQueryTest count: " + count); + // Should match "FedEx Field", "Washington Monument", and "White House" + assertEquals(3, count); + } + } + + @Test + public void executePolygonQueryTest() throws IOException { + System.out.println("Constructing polygon for the area contained by [Baltimore, MD; Richmond, VA; Harrisonburg, VA]."); + + final Polygon polygon = GeometryUtils.GEOMETRY_FACTORY.createPolygon(new Coordinate[] { + BALTIMORE, + RICHMOND, + HARRISONBURG, + BALTIMORE + }); + + System.out.println("Executing query, expecting to match ALL points..."); + + final QueryOptions queryOptions = new QueryOptions(ADAPTER, INDEX); + final SpatialQuery spatialQuery = new SpatialQuery(polygon); + + /* + * NOTICE: In this query, the adapter is added to the query options. If + * an index has data from more than one adapter, the data associated + * with a specific adapter can be selected. + */ + try (final CloseableIterator<SimpleFeature> closableIterator = dataStore.query(queryOptions, spatialQuery)) { + int count = 0; + while (closableIterator.hasNext()) { + System.out.println("Query match: " + closableIterator.next().getID()); + count++; + } + System.out.println("executePolygonQueryTest count: " + count); + // Should match "FedEx Field", "Washington Monument", and "White House" + assertEquals(3, count); + } + } + + @AfterClass + public static void cleanup() throws IOException, InterruptedException { + try { + accumulo.stop(); + } finally { + FileUtils.deleteDirectory(tempAccumuloDir); + } + } + + private static SimpleFeatureType getPointSimpleFeatureType() { + final String name = "PointSimpleFeatureType"; + final SimpleFeatureTypeBuilder sftBuilder = new SimpleFeatureTypeBuilder(); + final AttributeTypeBuilder atBuilder = new AttributeTypeBuilder(); + sftBuilder.setName(name); + sftBuilder.add(atBuilder.binding(String.class).nillable(false) + .buildDescriptor("locationName")); + sftBuilder.add(atBuilder.binding(Geometry.class).nillable(false) + .buildDescriptor("geometry")); + + return sftBuilder.buildFeatureType(); + } + + private static SimpleFeature buildSimpleFeature(final String locationName, final Coordinate coordinate) { + final SimpleFeatureBuilder builder = new SimpleFeatureBuilder(getPointSimpleFeatureType()); + builder.set("locationName", locationName); + builder.set("geometry", GeometryUtils.GEOMETRY_FACTORY.createPoint(coordinate)); + + return builder.buildFeature(locationName); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fe6cbccf/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerSfTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerSfTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerSfTest.java new file mode 100644 index 0000000..e49ac38 --- /dev/null +++ b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerSfTest.java @@ -0,0 +1,537 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.rya.indexing.accumulo.geo; + +import static org.apache.rya.indexing.GeoIndexingTestUtils.getSet; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.apache.accumulo.core.client.AccumuloException; +import org.apache.accumulo.core.client.AccumuloSecurityException; +import org.apache.accumulo.core.client.admin.TableOperations; +import org.apache.accumulo.minicluster.impl.MiniAccumuloClusterImpl; +import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl; +import org.apache.commons.io.FileUtils; +import org.apache.rya.accumulo.AccumuloRdfConfiguration; +import org.apache.rya.api.domain.RyaStatement; +import org.apache.rya.api.resolver.RdfToRyaConversions; +import org.apache.rya.api.resolver.RyaToRdfConversions; +import org.apache.rya.indexing.GeoConstants; +import org.apache.rya.indexing.GeoIndexerType; +import org.apache.rya.indexing.OptionalConfigUtils; +import org.apache.rya.indexing.StatementConstraints; +import org.apache.rya.indexing.accumulo.ConfigUtils; +import org.geotools.geometry.jts.Geometries; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.openrdf.model.Resource; +import org.openrdf.model.Statement; +import org.openrdf.model.URI; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.model.impl.StatementImpl; +import org.openrdf.model.impl.URIImpl; +import org.openrdf.model.impl.ValueFactoryImpl; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Sets; +import com.google.common.io.Files; +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.Point; +import com.vividsolutions.jts.geom.Polygon; +import com.vividsolutions.jts.geom.PrecisionModel; +import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.gml2.GMLWriter; + +import info.aduna.iteration.CloseableIteration; +import mil.nga.giat.geowave.datastore.accumulo.minicluster.MiniAccumuloClusterFactory; + +/** + * Tests all of the "simple functions" of the geoindexer specific to GML. + * Parameterized so that each test is run for WKT and for GML. + */ +@RunWith(value = Parameterized.class) +public class GeoWaveIndexerSfTest { + private static AccumuloRdfConfiguration conf; + private static GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326); + private static GeoWaveGeoIndexer g; + + private static final StatementConstraints EMPTY_CONSTRAINTS = new StatementConstraints(); + + // Here is the landscape: + /** + * <pre> + * 2---+---+---+---+---+---+ + * | F |G | + * 1 A o(-1,1) o C | + * | | | + * 0---+---+ +---+---+(3,0) + * | | E | + * -1 B + .---+---+ + * | | /| | | + * -2---+---+-/-+---+ + + * ^ / | D | + * -3 -2 -1 0---1---2 3 4 + * </pre> + **/ + private static final Polygon A = poly(bbox(-3, -2, 1, 2)); + private static final Polygon B = poly(bbox(-3, -2, -1, 0)); + private static final Polygon C = poly(bbox(1, 0, 3, 2)); + private static final Polygon D = poly(bbox(0, -3, 2, -1)); + + private static final Point F = point(-1, 1); + private static final Point G = point(1, 1); + + private static final LineString E = line(-1, -3, 0, -1); + + private static final Map<Geometry, String> NAMES = ImmutableMap.<Geometry, String>builder() + .put(A, "A") + .put(B, "B") + .put(C, "C") + .put(D, "D") + .put(E, "E") + .put(F, "F") + .put(G, "G") + .build(); + + private static File tempAccumuloDir; + private static MiniAccumuloClusterImpl accumulo; + + private static final boolean IS_MOCK = true; + + private static final String ACCUMULO_USER = IS_MOCK ? "username" : "root"; + private static final String ACCUMULO_PASSWORD = "password"; + + /** + * JUnit 4 parameterized iterates thru this list and calls the constructor with each. + * For each test, Call the constructor three times, for WKT and for GML encoding 1, and GML encoding 2 + */ + private static final URI USE_JTS_LIB_ENCODING = new URIImpl("uri:useLib") ; + private static final URI USE_ROUGH_ENCODING = new URIImpl("uri:useRough") ; + + @Parameters + public static Collection<URI[]> constructorData() { + final URI[][] data = new URI[][] { { GeoConstants.XMLSCHEMA_OGC_WKT, USE_JTS_LIB_ENCODING }, { GeoConstants.XMLSCHEMA_OGC_GML, USE_JTS_LIB_ENCODING }, { GeoConstants.XMLSCHEMA_OGC_GML, USE_JTS_LIB_ENCODING } }; + return Arrays.asList(data); + } + + private final URI schemaToTest; + private final URI encodeMethod; + + /** + * Constructor required by JUnit parameterized runner. See {@link #constructorData()} for constructor values. + * @param schemaToTest the schema to test {@link URI}. + * @param encodeMethod the encode method {@link URI}. + */ + public GeoWaveIndexerSfTest(final URI schemaToTest, final URI encodeMethod) { + this.schemaToTest = schemaToTest; + this.encodeMethod = encodeMethod; + } + + @BeforeClass + public static void setup() throws AccumuloException, AccumuloSecurityException, IOException, InterruptedException { + if (!IS_MOCK) { + tempAccumuloDir = Files.createTempDir(); + + accumulo = MiniAccumuloClusterFactory.newAccumuloCluster( + new MiniAccumuloConfigImpl(tempAccumuloDir, ACCUMULO_PASSWORD), + GeoWaveIndexerTest.class); + + accumulo.start(); + } + } + + @AfterClass + public static void cleanup() throws IOException, InterruptedException { + if (!IS_MOCK) { + try { + accumulo.stop(); + } finally { + FileUtils.deleteDirectory(tempAccumuloDir); + } + } + } + + /** + * Run before each test method. + * @throws Exception + */ + @Before + public void before() throws Exception { + conf = new AccumuloRdfConfiguration(); + conf.setTablePrefix("triplestore_"); + final String tableName = GeoWaveGeoIndexer.getTableName(conf); + conf.setBoolean(ConfigUtils.USE_MOCK_INSTANCE, IS_MOCK); + conf.set(ConfigUtils.CLOUDBASE_USER, ACCUMULO_USER); + conf.set(ConfigUtils.CLOUDBASE_PASSWORD, ACCUMULO_PASSWORD); + conf.set(ConfigUtils.CLOUDBASE_INSTANCE, IS_MOCK ? "INSTANCE" : accumulo.getInstanceName()); + conf.set(ConfigUtils.CLOUDBASE_ZOOKEEPERS, IS_MOCK ? "localhost" : accumulo.getZooKeepers()); + conf.set(ConfigUtils.CLOUDBASE_AUTHS, "U"); + conf.set(OptionalConfigUtils.USE_GEO, "true"); + conf.set(OptionalConfigUtils.GEO_INDEXER_TYPE, GeoIndexerType.GEO_WAVE.toString()); + + final TableOperations tops = ConfigUtils.getConnector(conf).tableOperations(); + // get all of the table names with the prefix + final Set<String> toDel = Sets.newHashSet(); + for (final String t : tops.list()) { + if (t.startsWith(tableName)) { + toDel.add(t); + } + } + for (final String t : toDel) { + tops.delete(t); + } + + g = new GeoWaveGeoIndexer(); + g.setConf(conf); + g.purge(conf); + // Convert the statements as schema WKT or GML, then GML has two methods to encode. + g.storeStatement(createRyaStatement(A, schemaToTest, encodeMethod)); + g.storeStatement(createRyaStatement(B, schemaToTest, encodeMethod)); + g.storeStatement(createRyaStatement(C, schemaToTest, encodeMethod)); + g.storeStatement(createRyaStatement(D, schemaToTest, encodeMethod)); + g.storeStatement(createRyaStatement(F, schemaToTest, encodeMethod)); + g.storeStatement(createRyaStatement(E, schemaToTest, encodeMethod)); + g.storeStatement(createRyaStatement(G, schemaToTest, encodeMethod)); + } + + private static RyaStatement createRyaStatement(final Geometry geo, final URI schema, final URI encodingMethod) { + return RdfToRyaConversions.convertStatement(genericStatement(geo,schema,encodingMethod)); + } + + private static Statement genericStatement(final Geometry geo, final URI schema, final URI encodingMethod) { + if (schema.equals(GeoConstants.XMLSCHEMA_OGC_WKT)) { + return genericStatementWkt(geo); + } else if (schema.equals(GeoConstants.XMLSCHEMA_OGC_GML)) { + return genericStatementGml(geo, encodingMethod); + } + throw new Error("schema unsupported: "+schema); + } + + private static Statement genericStatementWkt(final Geometry geo) { + final ValueFactory vf = new ValueFactoryImpl(); + final Resource subject = vf.createURI("uri:" + NAMES.get(geo)); + final URI predicate = GeoConstants.GEO_AS_WKT; + final Value object = vf.createLiteral(geo.toString(), GeoConstants.XMLSCHEMA_OGC_WKT); + return new StatementImpl(subject, predicate, object); + } + + private static Statement genericStatementGml(final Geometry geo, final URI encodingMethod) { + final ValueFactory vf = new ValueFactoryImpl(); + final Resource subject = vf.createURI("uri:" + NAMES.get(geo)); + final URI predicate = GeoConstants.GEO_AS_GML; + + final String gml ; + if (encodingMethod == USE_JTS_LIB_ENCODING) { + gml = geoToGmlUseJtsLib(geo); + } else if (encodingMethod == USE_ROUGH_ENCODING) { + gml = geoToGmlRough(geo); + } + else { + throw new Error("invalid encoding method: "+encodingMethod); + // System.out.println("===created GML===="); + // System.out.println(gml); + // System.out.println("========== GML===="); + } + + final Value object = vf.createLiteral(gml, GeoConstants.XMLSCHEMA_OGC_GML); + return new StatementImpl(subject, predicate, object); + } + + /** + * JTS library conversion from geometry to GML. + * @param geo base Geometry gets delegated + * @return String gml encoding of the geomoetry + */ + private static String geoToGmlUseJtsLib(final Geometry geo) { + final int srid = geo.getSRID(); + final GMLWriter gmlWriter = new GMLWriter(); + gmlWriter.setNamespace(false); + gmlWriter.setPrefix(null); + + if (srid != -1 || srid != 0) { + gmlWriter.setSrsName("EPSG:" + geo.getSRID()); + } + final String gml = gmlWriter.write(geo); + // Hack to replace a gml 2.0 deprecated element in the Polygon. + // It should tolerate this as it does other depreciated elements like <gml:coordinates>. + return gml.replace("outerBoundaryIs", "exterior"); + } + + /** + * Rough conversion from geometry to GML using a template. + * @param geo base Geometry gets delegated + * @return String gml encoding of the gemoetry + */ + private static String geoToGmlRough(final Geometry geo) { + final Geometries theType = org.geotools.geometry.jts.Geometries.get(geo); + switch (theType) { + case POINT: + return geoToGml((Point)geo); + case LINESTRING: + return geoToGml((LineString)geo); + case POLYGON: + return geoToGml((Polygon)geo); + case MULTIPOINT: + case MULTILINESTRING: + case MULTIPOLYGON: + default: + throw new Error("No code to convert to GML for this type: "+theType); + } + } + + private static Point point(final double x, final double y) { + return gf.createPoint(new Coordinate(x, y)); + } + + private static String geoToGml(final Point point) { + //CRS:84 long X,lat Y + //ESPG:4326 lat Y,long X + return "<Point"// + + " srsName='CRS:84'"// TODO: point.getSRID() + + "><pos>"+point.getX()+" "+point.getY()+"</pos> "// assumes Y=lat X=long + + " </Point>"; + } + + private static LineString line(final double x1, final double y1, final double x2, final double y2) { + return new LineString(new PackedCoordinateSequence.Double(new double[] { x1, y1, x2, y2 }, 2), gf); + } + + /** + * convert a lineString geometry to GML + * @param line + * @return String that is XML that is a GMLLiteral of line + */ + private static String geoToGml(final LineString line) { + final StringBuilder coordString = new StringBuilder() ; + for (final Coordinate coor : line.getCoordinates()) { + coordString.append(" ").append(coor.x).append(" ").append(coor.y); //ESPG:4326 lat/long + } + return " <gml:LineString srsName=\"http://www.opengis.net/def/crs/EPSG/0/4326\" xmlns:gml='http://www.opengis.net/gml'>\n" + + "<gml:posList srsDimension=\"2\">"// + + coordString // + + "</gml:posList></gml:LineString >"; + } + + private static Polygon poly(final double[] arr) { + final LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(arr, 2)); + final Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); + return p1; + } + + /** + * convert a Polygon geometry to GML + * @param geometry + * @return String that is XML that is a GMLLiteral of line + */ + private static String geoToGml(final Polygon poly) { + final StringBuilder coordString = new StringBuilder() ; + for (final Coordinate coor : poly.getCoordinates()) { + coordString.append(" ").append(coor.x).append(" ").append(coor.y); //ESPG:4326 lat/long + //with commas: coordString.append(" ").append(coor.x).append(",").append(coor.y); + } + return "<gml:Polygon srsName=\"EPSG:4326\" xmlns:gml='http://www.opengis.net/gml'>\r\n"// + + "<gml:exterior><gml:LinearRing>\r\n"// + + "<gml:posList srsDimension='2'>\r\n" + + coordString + + "</gml:posList>\r\n"// + + "</gml:LinearRing></gml:exterior>\r\n</gml:Polygon>\r\n"; + } + + private static double[] bbox(final double x1, final double y1, final double x2, final double y2) { + return new double[] { x1, y1, x1, y2, x2, y2, x2, y1, x1, y1 }; + } + + private void compare(final CloseableIteration<Statement, ?> actual, final Geometry... expected) throws Exception { + final Set<Statement> expectedSet = Sets.newHashSet(); + for (final Geometry geo : expected) { + expectedSet.add(RyaToRdfConversions.convertStatement(createRyaStatement(geo, this.schemaToTest, encodeMethod))); + } + + Assert.assertEquals(expectedSet, getSet(actual)); + } + + private static final Geometry[] EMPTY_RESULTS = {}; + + @Test + public void testParsePoly() throws Exception { + assertParseable(D); + } + + @Test + public void testParseLine() throws Exception { + assertParseable(E); + } + + @Test + public void testParsePoint() throws Exception { + assertParseable(F); + } + + /** + * Convert Geometry to Wkt|GML (schemaToTest), parse to Geometry, and compare to original. + * @param originalGeom the original {@link Geometry}. + * @throws ParseException + */ + public void assertParseable(final Geometry originalGeom) throws ParseException { + final Geometry parsedGeom = GeoParseUtils.getGeometry(genericStatement(originalGeom,schemaToTest, encodeMethod)); + assertTrue("Parsed should equal original: "+originalGeom+" parsed: "+parsedGeom, originalGeom.equalsNorm(parsedGeom)); + assertEquals( originalGeom, parsedGeom ); //also passes + assertTrue( originalGeom.equalsExact(parsedGeom) ); //also passes + } + + @Test + public void testEquals() throws Exception { + // point + compare(g.queryEquals(F, EMPTY_CONSTRAINTS), F); + compare(g.queryEquals(point(-1, -1), EMPTY_CONSTRAINTS), EMPTY_RESULTS); + + // line + compare(g.queryEquals(E, EMPTY_CONSTRAINTS), E); + compare(g.queryEquals(line(-1, -1, 0, 0), EMPTY_CONSTRAINTS), EMPTY_RESULTS); + + // poly + compare(g.queryEquals(A, EMPTY_CONSTRAINTS), A); + compare(g.queryEquals(poly(bbox(-2, -2, 1, 2)), EMPTY_CONSTRAINTS), EMPTY_RESULTS); + } + + @Test + public void testDisjoint() throws Exception { + // point + compare(g.queryDisjoint(F, EMPTY_CONSTRAINTS), B, C, D, E, G); + + // line + compare(g.queryDisjoint(E, EMPTY_CONSTRAINTS), B, C, F, G); + + // poly + compare(g.queryDisjoint(A, EMPTY_CONSTRAINTS), EMPTY_RESULTS); + compare(g.queryDisjoint(B, EMPTY_CONSTRAINTS), C, D, F, E, G); + } + + @Test + public void testIntersectsPoint() throws Exception { + compare(g.queryIntersects(F, EMPTY_CONSTRAINTS), A, F); + } + + @Test + public void testIntersectsLine() throws Exception { + compare(g.queryIntersects(E, EMPTY_CONSTRAINTS), A, E, D); + } + + @Test + public void testIntersectsPoly() throws Exception { + compare(g.queryIntersects(A, EMPTY_CONSTRAINTS), A, B, C, D, F, E, G); + } + + @Test + public void testTouchesPoint() throws Exception { + compare(g.queryTouches(F, EMPTY_CONSTRAINTS), EMPTY_RESULTS); + compare(g.queryTouches(G, EMPTY_CONSTRAINTS), A, C); + } + + @Test + public void testTouchesLine() throws Exception { + compare(g.queryTouches(E, EMPTY_CONSTRAINTS), D); + } + + @Test + public void testTouchesPoly() throws Exception { + compare(g.queryTouches(A, EMPTY_CONSTRAINTS), C,G); + } + + @Test + public void testCrossesPoint() throws Exception { + compare(g.queryCrosses(F, EMPTY_CONSTRAINTS), EMPTY_RESULTS); + compare(g.queryCrosses(G, EMPTY_CONSTRAINTS), EMPTY_RESULTS); + compare(g.queryCrosses(point(2, 0), EMPTY_CONSTRAINTS), EMPTY_RESULTS); + } + + @Test + public void testCrossesLine() throws Exception { + compare(g.queryCrosses(E, EMPTY_CONSTRAINTS), A); + } + + @Test + public void testCrossesPoly() throws Exception { + compare(g.queryCrosses(A, EMPTY_CONSTRAINTS), E); + compare(g.queryCrosses(poly(bbox(-0.9, -2.9, -0.1, -1.1)), EMPTY_CONSTRAINTS), E); + } + + @Test + public void testWithin() throws Exception { + // point + compare(g.queryWithin(F, EMPTY_CONSTRAINTS), F); + + // line + compare(g.queryWithin(E, EMPTY_CONSTRAINTS), E); + + // poly + compare(g.queryWithin(A, EMPTY_CONSTRAINTS), A, B, F); + } + + @Test + public void testContainsPoint() throws Exception { + compare(g.queryContains(F, EMPTY_CONSTRAINTS), A, F); + } + + @Test + public void testContainsLine() throws Exception { + compare(g.queryContains(E, EMPTY_CONSTRAINTS), E); + } + + @Test + public void testContainsPoly() throws Exception { + compare(g.queryContains(A, EMPTY_CONSTRAINTS), A); + compare(g.queryContains(B, EMPTY_CONSTRAINTS), A, B); + } + + @Test + public void testOverlapsPoint() throws Exception { + compare(g.queryOverlaps(F, EMPTY_CONSTRAINTS), EMPTY_RESULTS); + } + + @Test + public void testOverlapsLine() throws Exception { + compare(g.queryOverlaps(E, EMPTY_CONSTRAINTS), EMPTY_RESULTS); + } + + @Test + public void testOverlapsPoly() throws Exception { + compare(g.queryOverlaps(A, EMPTY_CONSTRAINTS), D); + } + +}
