Repository: incubator-rya Updated Branches: refs/heads/master 5913670b6 -> 59570b4f7
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/7727b165/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/accumulo/geo/GeoIndexerTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/accumulo/geo/GeoIndexerTest.java b/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/accumulo/geo/GeoIndexerTest.java new file mode 100644 index 0000000..bd4092a --- /dev/null +++ b/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/accumulo/geo/GeoIndexerTest.java @@ -0,0 +1,401 @@ +package mvm.rya.indexing.accumulo.geo; + +/* + * 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. + */ + +import static mvm.rya.api.resolver.RdfToRyaConversions.convertStatement; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.accumulo.core.client.admin.TableOperations; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +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.ContextStatementImpl; +import org.openrdf.model.impl.StatementImpl; +import org.openrdf.model.impl.ValueFactoryImpl; + +import com.google.common.collect.Sets; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.GeometryFactory; +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 info.aduna.iteration.CloseableIteration; +import mvm.rya.accumulo.AccumuloRdfConfiguration; +import mvm.rya.indexing.GeoConstants; +import mvm.rya.indexing.StatementConstraints; +import mvm.rya.indexing.accumulo.ConfigUtils; + +/** + * 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 { + + private static final StatementConstraints EMPTY_CONSTRAINTS = new StatementConstraints(); + + private AccumuloRdfConfiguration conf; + GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326); + + @Before + public void before() throws Exception { + conf = new AccumuloRdfConfiguration(); + conf.setTablePrefix("triplestore_"); + 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_AUTHS, "U"); + + 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()){ + if (t.startsWith(tableName)){ + toDel.add(t); + } + } + for (String t : toDel) { + tops.delete(t); + } + } + + @Test + public void testRestrictPredicatesSearch() throws Exception { + conf.setStrings(ConfigUtils.GEO_PREDICATES_LIST, "pred:1,pred:2"); + try (GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { + f.setConf(conf); + + 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; + + // 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"); + + // 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); + f.storeStatement(convertStatement(s3)); + f.storeStatement(convertStatement(s4)); + + // This should not be stored because the object is not valid wkt + f.storeStatement(convertStatement(new StatementImpl(vf.createURI("foo:subj5"), pred1, vf.createLiteral("soint(10 10)")))); + + // This should not be stored because the object is not a literal + f.storeStatement(convertStatement(new StatementImpl(vf.createURI("foo:subj6"), pred1, vf.createURI("p:Point(10 10)")))); + + f.flush(); + + 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()) { + 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"); + + 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 }; + + 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)); + + Polygon p1 = gf.createPolygon(r1, new LinearRing[] {}); + Polygon p2 = gf.createPolygon(r2, new LinearRing[] {}); + 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 }); + 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[] {}); + Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(pOut, EMPTY_CONSTRAINTS))); + } + } + + @Test + public void testDcSearch() throws Exception { + // test a ring around dc + try (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"); + + 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[] {}); + 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[] {}); + Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(pOut, EMPTY_CONSTRAINTS))); + } + } + + @Test + public void testDeleteSearch() throws Exception { + // test a ring around dc + try (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"); + + 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[] {}); + 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[] {}); + 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[] {}); + Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(pWorld, EMPTY_CONSTRAINTS))); + } + } + + @Test + public void testDcSearchWithContext() throws Exception { + // test a ring around dc + try (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"); + + 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[] {}); + + // query with correct context + Assert.assertEquals(Sets.newHashSet(statement), getSet(f.queryWithin(p1, new StatementConstraints().setContext(context)))); + + // query with wrong context + Assert.assertEquals(Sets.newHashSet(), + getSet(f.queryWithin(p1, new StatementConstraints().setContext(vf.createURI("foo:context2"))))); + } + } + + @Test + public void testDcSearchWithSubject() throws Exception { + // test a ring around dc + try (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"); + + 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[] {}); + + // query with correct subject + Assert.assertEquals(Sets.newHashSet(statement), getSet(f.queryWithin(p1, new StatementConstraints().setSubject(subject)))); + + // query with wrong subject + Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(p1, new StatementConstraints().setSubject(vf.createURI("foo:subj2"))))); + } + } + + @Test + public void testDcSearchWithSubjectAndContext() throws Exception { + // test a ring around dc + try (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"); + + 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[] {}); + + // query with correct context subject + Assert.assertEquals(Sets.newHashSet(statement), + getSet(f.queryWithin(p1, new StatementConstraints().setContext(context).setSubject(subject)))); + + // query with wrong context + Assert.assertEquals(Sets.newHashSet(), + getSet(f.queryWithin(p1, new StatementConstraints().setContext(vf.createURI("foo:context2"))))); + + // query with wrong subject + Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(p1, new StatementConstraints().setSubject(vf.createURI("foo:subj2"))))); + } + } + + @Test + public void testDcSearchWithPredicate() throws Exception { + // test a ring around dc + try (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"); + + 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[] {}); + + // query with correct Predicate + Assert.assertEquals(Sets.newHashSet(statement), + getSet(f.queryWithin(p1, new StatementConstraints().setPredicates(Collections.singleton(predicate))))); + + // query with wrong predicate + Assert.assertEquals(Sets.newHashSet(), + getSet(f.queryWithin(p1, new StatementConstraints().setPredicates(Collections.singleton(vf.createURI("other:pred")))))); + } + } + + // @Test + public void testAntiMeridianSearch() throws Exception { + // verify that a search works if the bounding box crosses the anti meridian + try (GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) { + f.setConf(conf); + + ValueFactory vf = new ValueFactoryImpl(); + 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); + 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); + f.storeStatement(convertStatement(statementWest)); + + f.flush(); + + double[] ONE = { 178.1, 1, -178, 1, -178, -1, 178.1, -1, 178.1, 1 }; + + LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(ONE, 2)); + + 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/7727b165/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/mongo/MongoGeoIndexerSfTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/mongo/MongoGeoIndexerSfTest.java b/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/mongo/MongoGeoIndexerSfTest.java new file mode 100644 index 0000000..01c6ab7 --- /dev/null +++ b/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/mongo/MongoGeoIndexerSfTest.java @@ -0,0 +1,304 @@ +package mvm.rya.indexing.mongo; +/* + * 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. + */ + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +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.ValueFactoryImpl; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.mongodb.MongoClient; +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 de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.mongo.tests.MongodForTestsFactory; +import info.aduna.iteration.CloseableIteration; +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.resolver.RdfToRyaConversions; +import mvm.rya.api.resolver.RyaToRdfConversions; +import mvm.rya.indexing.GeoConstants; +import mvm.rya.indexing.OptionalConfigUtils; +import mvm.rya.indexing.StatementConstraints; +import mvm.rya.indexing.accumulo.ConfigUtils; +import mvm.rya.indexing.mongodb.geo.MongoGeoIndexer; +import mvm.rya.mongodb.MongoDBRdfConfiguration; + +/** + * Tests all of the "simple functions" of the geoindexer. + */ +public class MongoGeoIndexerSfTest { + private MongoDBRdfConfiguration conf; + private static GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326); + private static MongoGeoIndexer g; + + private static final StatementConstraints EMPTY_CONSTRAINTS = new StatementConstraints(); + + // Here is the landscape: + /** + * <pre> + * +---+---+---+---+---+---+---+ + * | F | | + * + A + + C + + * | | | + * +---+---+ E +---+---+ + * | | / | + * + B + /+---+---+ + * | | / | | + * +---+---+/--+---+---+ + * / | D | + * / +---+---+ + * </pre> + **/ + + private static final Polygon A = poly(bbox(0, 1, 4, 5)); + private static final Polygon B = poly(bbox(0, 1, 2, 3)); + private static final Polygon C = poly(bbox(4, 3, 6, 5)); + private static final Polygon D = poly(bbox(3, 0, 5, 2)); + + private static final Point F = point(2, 4); + + private static final LineString E = line(2, 0, 3, 3); + + private static final Map<Geometry, String> names = Maps.newHashMap(); + static { + names.put(A, "A"); + names.put(B, "B"); + names.put(C, "C"); + names.put(D, "D"); + names.put(E, "E"); + names.put(F, "F"); + } + + @Before + public void before() throws Exception { + System.out.println(UUID.randomUUID().toString()); + conf = new MongoDBRdfConfiguration(); + conf.set(ConfigUtils.USE_MONGO, "true"); + conf.set(MongoDBRdfConfiguration.USE_TEST_MONGO, "true"); + conf.set(MongoDBRdfConfiguration.MONGO_DB_NAME, "test"); + conf.set(MongoDBRdfConfiguration.MONGO_COLLECTION_PREFIX, "rya_"); + conf.set(ConfigUtils.GEO_PREDICATES_LIST, "http://www.opengis.net/ont/geosparql#asWKT"); + conf.set(OptionalConfigUtils.USE_GEO, "true"); + conf.setTablePrefix("rya_"); + + final MongodForTestsFactory testsFactory = MongodForTestsFactory.with(Version.Main.PRODUCTION); + final MongoClient mongoClient = testsFactory.newMongo(); + g = new MongoGeoIndexer(); + g.initIndexer(conf, mongoClient); + g.storeStatement(statement(A)); + g.storeStatement(statement(B)); + g.storeStatement(statement(C)); + g.storeStatement(statement(D)); + g.storeStatement(statement(F)); + g.storeStatement(statement(E)); + } + + private static RyaStatement statement(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 RdfToRyaConversions.convertStatement(new StatementImpl(subject, predicate, object)); + + } + + private static Point point(final double x, final double y) { + return gf.createPoint(new Coordinate(x, y)); + } + + 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); + } + + 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; + } + + 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 }; + } + + public 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(statement(geo))); + } + + Assert.assertEquals(expectedSet, getSet(actual)); + } + + private static <X> Set<X> getSet(final CloseableIteration<X, ?> iter) throws Exception { + final Set<X> set = new HashSet<X>(); + while (iter.hasNext()) { + set.add(iter.next()); + } + return set; + } + + private static Geometry[] EMPTY_RESULTS = {}; + + @Test + public void testEquals() throws Exception { + // point + compare(g.queryEquals(F, EMPTY_CONSTRAINTS), F); + compare(g.queryEquals(point(2, 2), EMPTY_CONSTRAINTS), EMPTY_RESULTS); + + // line + compare(g.queryEquals(E, EMPTY_CONSTRAINTS), E); + compare(g.queryEquals(line(2, 2, 3, 3), EMPTY_CONSTRAINTS), EMPTY_RESULTS); + + // poly + compare(g.queryEquals(A, EMPTY_CONSTRAINTS), A); + compare(g.queryEquals(poly(bbox(1, 1, 4, 5)), EMPTY_CONSTRAINTS), EMPTY_RESULTS); + + } + +// @Test +// public void testDisjoint() throws Exception { +// // point +// compare(g.queryDisjoint(F, EMPTY_CONSTRAINTS), B, C, D, E); +// +// // line +// compare(g.queryDisjoint(E, EMPTY_CONSTRAINTS), B, C, D, F); +// +// // poly +// compare(g.queryDisjoint(A, EMPTY_CONSTRAINTS), EMPTY_RESULTS); +// compare(g.queryDisjoint(B, EMPTY_CONSTRAINTS), C, D, F, E); +// } + + @Test + public void testIntersectsPoint() throws Exception { + // This seems like a bug + // compare(g.queryIntersects(F, EMPTY_CONSTRAINTS), A, F); + // compare(g.queryIntersects(F, EMPTY_CONSTRAINTS), EMPTY_RESULTS); + } + + @Test + public void testIntersectsLine() throws Exception { + // This seems like a bug + // compare(g.queryIntersects(E, EMPTY_CONSTRAINTS), A, E); + // compare(g.queryIntersects(E, EMPTY_CONSTRAINTS), EMPTY_RESULTS); + } + +// @Test +// public void testIntersectsPoly() throws Exception { +// compare(g.queryIntersects(A, EMPTY_CONSTRAINTS), A, B, C, D, F, E); +// } + +// @Test +// public void testTouchesPoint() throws Exception { +// compare(g.queryTouches(F, EMPTY_CONSTRAINTS), EMPTY_RESULTS); +// } +// +// @Test +// public void testTouchesLine() throws Exception { +// compare(g.queryTouches(E, EMPTY_CONSTRAINTS), EMPTY_RESULTS); +// } + +// @Test +// public void testTouchesPoly() throws Exception { +// compare(g.queryTouches(A, EMPTY_CONSTRAINTS), C); +// } + +// @Test +// public void testCrossesPoint() throws Exception { +// compare(g.queryCrosses(F, 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); +// } + +// @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), F); + // You cannot have overlapping points + // compare(g.queryOverlaps(F, EMPTY_CONSTRAINTS), EMPTY_RESULTS); + } + + @Test + public void testOverlapsLine() throws Exception { + // compare(g.queryOverlaps(E, EMPTY_CONSTRAINTS), A, E); + // You cannot have overlapping lines + // compare(g.queryOverlaps(E, EMPTY_CONSTRAINTS), EMPTY_RESULTS); + } + +// @Test +// public void testOverlapsPoly() throws Exception { +// compare(g.queryOverlaps(A, EMPTY_CONSTRAINTS), D); +// } + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/7727b165/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/mongo/MongoGeoIndexerTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/mongo/MongoGeoIndexerTest.java b/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/mongo/MongoGeoIndexerTest.java new file mode 100644 index 0000000..9b6c8cb --- /dev/null +++ b/extras/rya.geoindexing/src/test/java/mvm/rya/indexing/mongo/MongoGeoIndexerTest.java @@ -0,0 +1,396 @@ +package mvm.rya.indexing.mongo; + +/* + * 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. + */ + + + +import static mvm.rya.api.resolver.RdfToRyaConversions.convertStatement; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +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.ContextStatementImpl; +import org.openrdf.model.impl.StatementImpl; +import org.openrdf.model.impl.ValueFactoryImpl; + +import com.google.common.collect.Sets; +import com.mongodb.MongoClient; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.GeometryFactory; +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 de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.mongo.tests.MongodForTestsFactory; +import info.aduna.iteration.CloseableIteration; +import mvm.rya.indexing.GeoConstants; +import mvm.rya.indexing.OptionalConfigUtils; +import mvm.rya.indexing.StatementConstraints; +import mvm.rya.indexing.accumulo.ConfigUtils; +import mvm.rya.indexing.mongodb.geo.MongoGeoIndexer; +import mvm.rya.mongodb.MongoDBRdfConfiguration; + +public class MongoGeoIndexerTest { + + private static final StatementConstraints EMPTY_CONSTRAINTS = new StatementConstraints(); + + MongoDBRdfConfiguration conf; + MongoClient mongoClient; + GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326); + + @Before + public void before() throws Exception { + conf = new MongoDBRdfConfiguration(); + conf.set(ConfigUtils.USE_MONGO, "true"); + conf.set(MongoDBRdfConfiguration.USE_TEST_MONGO, "true"); + conf.set(MongoDBRdfConfiguration.MONGO_DB_NAME, "test"); + conf.set(MongoDBRdfConfiguration.MONGO_COLLECTION_PREFIX, "rya_"); + conf.set(ConfigUtils.GEO_PREDICATES_LIST, "http://www.opengis.net/ont/geosparql#asWKT"); + conf.set(OptionalConfigUtils.USE_GEO, "true"); + conf.setTablePrefix("rya_"); + + final MongodForTestsFactory testsFactory = MongodForTestsFactory.with(Version.Main.PRODUCTION); + mongoClient = testsFactory.newMongo(); + } + + @Test + public void testRestrictPredicatesSearch() throws Exception { + conf.setStrings(ConfigUtils.GEO_PREDICATES_LIST, "pred:1,pred:2"); + try (MongoGeoIndexer f = new MongoGeoIndexer()) { + f.initIndexer(conf, mongoClient); + + final ValueFactory vf = new ValueFactoryImpl(); + + 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))); + + 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 + 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)); + + // This should not be stored because the object is not valid wkt + f.storeStatement(convertStatement(new StatementImpl(vf.createURI("foo:subj5"), pred1, vf.createLiteral("soint(10 10)")))); + + // This should not be stored because the object is not a literal + f.storeStatement(convertStatement(new StatementImpl(vf.createURI("foo:subj6"), pred1, vf.createURI("p:Point(10 10)")))); + + f.flush(); + + 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(final CloseableIteration<X, ?> iter) throws Exception { + final Set<X> set = new HashSet<X>(); + while (iter.hasNext()) { + set.add(iter.next()); + } + return set; + } + + @Test + public void testPrimeMeridianSearch() throws Exception { + try (MongoGeoIndexer f = new MongoGeoIndexer()) { + f.initIndexer(conf, mongoClient); + + 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"); + + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); + f.storeStatement(convertStatement(statement)); + f.flush(); + + 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 }; + + 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)); + + 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 + 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 + 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))); + } + } + + @Test + public void testDcSearch() throws Exception { + // test a ring around dc + try (MongoGeoIndexer f = new MongoGeoIndexer()) { + f.initIndexer(conf, mongoClient); + + 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"); + + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); + f.storeStatement(convertStatement(statement)); + f.flush(); + + 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 + 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 + public void testDeleteSearch() throws Exception { + // test a ring around dc + try (MongoGeoIndexer f = new MongoGeoIndexer()) { + f.initIndexer(conf, mongoClient); + + 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"); + + 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 + 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 + 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 + 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))); + } + } + + @Test + public void testDcSearchWithContext() throws Exception { + // test a ring around dc + try (MongoGeoIndexer f = new MongoGeoIndexer()) { + f.initIndexer(conf, mongoClient); + + 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"); + + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); + f.storeStatement(convertStatement(statement)); + f.flush(); + + 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)))); + + // query with wrong context + Assert.assertEquals(Sets.newHashSet(), + getSet(f.queryWithin(p1, new StatementConstraints().setContext(vf.createURI("foo:context2"))))); + } + } + + @Test + public void testDcSearchWithSubject() throws Exception { + // test a ring around dc + try (MongoGeoIndexer f = new MongoGeoIndexer()) { + f.initIndexer(conf, mongoClient); + + 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"); + + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); + f.storeStatement(convertStatement(statement)); + f.flush(); + + 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)))); + + // query with wrong subject + Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(p1, new StatementConstraints().setSubject(vf.createURI("foo:subj2"))))); + } + } + + @Test + public void testDcSearchWithSubjectAndContext() throws Exception { + // test a ring around dc + try (MongoGeoIndexer f = new MongoGeoIndexer()) { + f.initIndexer(conf, mongoClient); + + 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"); + + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); + f.storeStatement(convertStatement(statement)); + f.flush(); + + 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), + getSet(f.queryWithin(p1, new StatementConstraints().setContext(context).setSubject(subject)))); + + // query with wrong context + Assert.assertEquals(Sets.newHashSet(), + getSet(f.queryWithin(p1, new StatementConstraints().setContext(vf.createURI("foo:context2"))))); + + // query with wrong subject + Assert.assertEquals(Sets.newHashSet(), getSet(f.queryWithin(p1, new StatementConstraints().setSubject(vf.createURI("foo:subj2"))))); + } + } + + @Test + public void testDcSearchWithPredicate() throws Exception { + // test a ring around dc + try (MongoGeoIndexer f = new MongoGeoIndexer()) { + f.initIndexer(conf, mongoClient); + + 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"); + + final Statement statement = new ContextStatementImpl(subject, predicate, object, context); + f.storeStatement(convertStatement(statement)); + f.flush(); + + 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), + getSet(f.queryWithin(p1, new StatementConstraints().setPredicates(Collections.singleton(predicate))))); + + // query with wrong predicate + Assert.assertEquals(Sets.newHashSet(), + getSet(f.queryWithin(p1, new StatementConstraints().setPredicates(Collections.singleton(vf.createURI("other:pred")))))); + } + } + + // @Test + public void testAntiMeridianSearch() throws Exception { + // verify that a search works if the bounding box crosses the anti meridian + try (MongoGeoIndexer f = new MongoGeoIndexer()) { + f.initIndexer(conf, mongoClient); + + final ValueFactory vf = new ValueFactoryImpl(); + final Resource context = vf.createURI("foo: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)); + + 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(); + + final double[] ONE = { 178.1, 1, -178, 1, -178, -1, 178.1, -1, 178.1, 1 }; + + final LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(ONE, 2)); + + 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/7727b165/extras/rya.prospector/pom.xml ---------------------------------------------------------------------- diff --git a/extras/rya.prospector/pom.xml b/extras/rya.prospector/pom.xml index bf9321e..2ce45b9 100644 --- a/extras/rya.prospector/pom.xml +++ b/extras/rya.prospector/pom.xml @@ -71,6 +71,7 @@ under the License. <excludes> <!-- Services Files --> <exclude>**/resources/META-INF/services/**</exclude> + <exclude>**/META-INF/**</exclude> </excludes> </configuration> </plugin> http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/7727b165/mapreduce/src/main/java/mvm/rya/accumulo/mr/AbstractAccumuloMRTool.java ---------------------------------------------------------------------- diff --git a/mapreduce/src/main/java/mvm/rya/accumulo/mr/AbstractAccumuloMRTool.java b/mapreduce/src/main/java/mvm/rya/accumulo/mr/AbstractAccumuloMRTool.java index 88f9030..3869c96 100644 --- a/mapreduce/src/main/java/mvm/rya/accumulo/mr/AbstractAccumuloMRTool.java +++ b/mapreduce/src/main/java/mvm/rya/accumulo/mr/AbstractAccumuloMRTool.java @@ -269,7 +269,6 @@ public abstract class AbstractAccumuloMRTool implements Tool { RyaOutputFormat.setTablePrefix(job, tablePrefix); // Determine which indexers to use based on the config RyaOutputFormat.setFreeTextEnabled(job, ConfigUtils.getUseFreeText(conf)); - RyaOutputFormat.setGeoEnabled(job, ConfigUtils.getUseGeo(conf)); RyaOutputFormat.setTemporalEnabled(job, ConfigUtils.getUseTemporal(conf)); RyaOutputFormat.setEntityEnabled(job, ConfigUtils.getUseEntity(conf)); // Configure the Accumulo connection http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/7727b165/mapreduce/src/main/java/mvm/rya/accumulo/mr/RyaOutputFormat.java ---------------------------------------------------------------------- diff --git a/mapreduce/src/main/java/mvm/rya/accumulo/mr/RyaOutputFormat.java b/mapreduce/src/main/java/mvm/rya/accumulo/mr/RyaOutputFormat.java index c9f7ffe..331c721 100644 --- a/mapreduce/src/main/java/mvm/rya/accumulo/mr/RyaOutputFormat.java +++ b/mapreduce/src/main/java/mvm/rya/accumulo/mr/RyaOutputFormat.java @@ -59,12 +59,10 @@ import mvm.rya.api.persist.RyaDAOException; import mvm.rya.api.resolver.RdfToRyaConversions; import mvm.rya.api.resolver.RyaTripleContext; import mvm.rya.indexing.FreeTextIndexer; -import mvm.rya.indexing.GeoIndexer; import mvm.rya.indexing.TemporalIndexer; import mvm.rya.indexing.accumulo.ConfigUtils; import mvm.rya.indexing.accumulo.entity.EntityCentricIndex; import mvm.rya.indexing.accumulo.freetext.AccumuloFreeTextIndexer; -import mvm.rya.indexing.accumulo.geo.GeoMesaGeoIndexer; import mvm.rya.indexing.accumulo.temporal.AccumuloTemporalIndexer; /** @@ -83,7 +81,6 @@ public class RyaOutputFormat extends OutputFormat<Writable, RyaStatementWritable private static final String PREFIX = RyaOutputFormat.class.getSimpleName(); private static final String MAX_MUTATION_BUFFER_SIZE = PREFIX + ".maxmemory"; private static final String ENABLE_FREETEXT = PREFIX + ".freetext.enable"; - private static final String ENABLE_GEO = PREFIX + ".geo.enable"; private static final String ENABLE_TEMPORAL = PREFIX + ".temporal.enable"; private static final String ENABLE_ENTITY = PREFIX + ".entity.enable"; private static final String ENABLE_CORE = PREFIX + ".coretables.enable"; @@ -135,16 +132,7 @@ public class RyaOutputFormat extends OutputFormat<Writable, RyaStatementWritable job.getConfiguration().setBoolean(ENABLE_FREETEXT, enable); } - /** - * Set whether the geo index is enabled. Defaults to true. - * @param job Job to apply the setting to. - * @param enable Whether this job should add its output statements to the geo index. - */ - public static void setGeoEnabled(Job job, boolean enable) { - job.getConfiguration().setBoolean(ENABLE_GEO, enable); - } - - /** + /** * Set whether the temporal index is enabled. Defaults to true. * @param job Job to apply the setting to. * @param enable Whether this job should add its output statements to the temporal index. @@ -191,7 +179,6 @@ public class RyaOutputFormat extends OutputFormat<Writable, RyaStatementWritable public void checkOutputSpecs(JobContext jobContext) throws IOException { Configuration conf = jobContext.getConfiguration(); // make sure that all of the indexers can connect - getGeoIndexer(conf); getFreeTextIndexer(conf); getTemporalIndexer(conf); getRyaIndexer(conf); @@ -219,14 +206,6 @@ public class RyaOutputFormat extends OutputFormat<Writable, RyaStatementWritable return new RyaRecordWriter(context); } - private static GeoIndexer getGeoIndexer(Configuration conf) { - if (!conf.getBoolean(ENABLE_GEO, true)) { - return null; - } - GeoMesaGeoIndexer geo = new GeoMesaGeoIndexer(); - geo.setConf(conf); - return geo; - } private static FreeTextIndexer getFreeTextIndexer(Configuration conf) { if (!conf.getBoolean(ENABLE_FREETEXT, true)) { @@ -295,7 +274,6 @@ public class RyaOutputFormat extends OutputFormat<Writable, RyaStatementWritable private static final Logger logger = Logger.getLogger(RyaRecordWriter.class); private FreeTextIndexer freeTextIndexer; - private GeoIndexer geoIndexer; private TemporalIndexer temporalIndexer; private EntityCentricIndex entityIndexer; private AccumuloRyaDAO ryaIndexer; @@ -347,7 +325,6 @@ public class RyaOutputFormat extends OutputFormat<Writable, RyaStatementWritable // set up the indexers freeTextIndexer = getFreeTextIndexer(conf); - geoIndexer = getGeoIndexer(conf); temporalIndexer = getTemporalIndexer(conf); entityIndexer = getEntityIndexer(conf); ryaIndexer = getRyaIndexer(conf); @@ -407,12 +384,6 @@ public class RyaOutputFormat extends OutputFormat<Writable, RyaStatementWritable logger.error("Error flushing the buffer on RyaOutputFormat Close", e); } try { - if (geoIndexer != null) - geoIndexer.close(); - } catch (IOException e) { - logger.error("Error closing the geoIndexer on RyaOutputFormat Close", e); - } - try { if (freeTextIndexer != null) freeTextIndexer.close(); } catch (IOException e) { @@ -531,12 +502,6 @@ public class RyaOutputFormat extends OutputFormat<Writable, RyaStatementWritable logger.info(String.format("(C-%d) (Reading) Duration, Current Rate, Total Rate: %.2f %.2f %.2f ", commitCount, readingDuration, currentReadRate, totalReadRate)); - // write to geo - if (geoIndexer != null) { - geoIndexer.storeStatements(buffer); - geoIndexer.flush(); - } - // write to free text if (freeTextIndexer != null) { freeTextIndexer.storeStatements(buffer); http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/7727b165/mapreduce/src/test/java/mvm/rya/accumulo/mr/RyaOutputFormatTest.java ---------------------------------------------------------------------- diff --git a/mapreduce/src/test/java/mvm/rya/accumulo/mr/RyaOutputFormatTest.java b/mapreduce/src/test/java/mvm/rya/accumulo/mr/RyaOutputFormatTest.java index cfd65d7..60bcc49 100644 --- a/mapreduce/src/test/java/mvm/rya/accumulo/mr/RyaOutputFormatTest.java +++ b/mapreduce/src/test/java/mvm/rya/accumulo/mr/RyaOutputFormatTest.java @@ -25,11 +25,6 @@ import org.openrdf.model.ValueFactory; import org.openrdf.model.impl.ValueFactoryImpl; import org.openrdf.model.vocabulary.XMLSchema; -import com.vividsolutions.jts.geom.Coordinate; -import com.vividsolutions.jts.geom.GeometryFactory; -import com.vividsolutions.jts.geom.Point; -import com.vividsolutions.jts.geom.PrecisionModel; - import info.aduna.iteration.CloseableIteration; import mvm.rya.accumulo.AccumuloRdfConfiguration; import mvm.rya.accumulo.AccumuloRyaDAO; @@ -47,8 +42,6 @@ import mvm.rya.indexing.accumulo.entity.EntityCentricIndex; import mvm.rya.indexing.accumulo.freetext.AccumuloFreeTextIndexer; import mvm.rya.indexing.accumulo.freetext.SimpleTokenizer; import mvm.rya.indexing.accumulo.freetext.Tokenizer; -import mvm.rya.indexing.accumulo.geo.GeoConstants; -import mvm.rya.indexing.accumulo.geo.GeoMesaGeoIndexer; import mvm.rya.indexing.accumulo.temporal.AccumuloTemporalIndexer; /* @@ -133,7 +126,6 @@ public class RyaOutputFormatTest { RyaOutputFormat.setCoreTablesEnabled(job, true); RyaOutputFormat.setFreeTextEnabled(job, false); RyaOutputFormat.setTemporalEnabled(job, false); - RyaOutputFormat.setGeoEnabled(job, false); RyaOutputFormat.setEntityEnabled(job, false); write(input); TestUtils.verify(connector, conf, input); @@ -159,7 +151,6 @@ public class RyaOutputFormatTest { RyaOutputFormat.setCoreTablesEnabled(job, true); RyaOutputFormat.setFreeTextEnabled(job, false); RyaOutputFormat.setTemporalEnabled(job, false); - RyaOutputFormat.setGeoEnabled(job, false); RyaOutputFormat.setEntityEnabled(job, false); RyaOutputFormat.setDefaultVisibility(job, CV); write(input); @@ -186,7 +177,6 @@ public class RyaOutputFormatTest { RyaOutputFormat.setCoreTablesEnabled(job, true); RyaOutputFormat.setFreeTextEnabled(job, false); RyaOutputFormat.setTemporalEnabled(job, false); - RyaOutputFormat.setGeoEnabled(job, false); RyaOutputFormat.setEntityEnabled(job, false); RyaOutputFormat.setDefaultContext(job, GRAPH); write(input); @@ -205,7 +195,6 @@ public class RyaOutputFormatTest { RyaOutputFormat.setCoreTablesEnabled(job, false); RyaOutputFormat.setFreeTextEnabled(job, true); RyaOutputFormat.setTemporalEnabled(job, false); - RyaOutputFormat.setGeoEnabled(job, false); RyaOutputFormat.setEntityEnabled(job, false); write(input); final Set<Statement> empty = new HashSet<>(); @@ -232,7 +221,6 @@ public class RyaOutputFormatTest { RyaOutputFormat.setCoreTablesEnabled(job, false); RyaOutputFormat.setFreeTextEnabled(job, false); RyaOutputFormat.setTemporalEnabled(job, true); - RyaOutputFormat.setGeoEnabled(job, false); RyaOutputFormat.setEntityEnabled(job, false); final ValueFactory vf = new ValueFactoryImpl(); for (int i = 0; i < instants.length; i++) { @@ -260,30 +248,6 @@ public class RyaOutputFormatTest { temporal.close(); } - @Test - public void testGeoIndexing() throws Exception { - final GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326); - final Point p1 = gf.createPoint(new Coordinate(1, 1)); - final Point p2 = gf.createPoint(new Coordinate(2, 2)); - final GeoMesaGeoIndexer geo = new GeoMesaGeoIndexer(); - geo.setConf(conf); - final RyaStatement input = RyaStatement.builder() - .setSubject(new RyaURI(GRAPH + ":s")) - .setPredicate(new RyaURI(GRAPH + ":p")) - .setObject(new RyaType(GeoConstants.XMLSCHEMA_OGC_WKT, "Point(2 2)")) - .build(); - RyaOutputFormat.setCoreTablesEnabled(job, false); - RyaOutputFormat.setFreeTextEnabled(job, false); - RyaOutputFormat.setTemporalEnabled(job, false); - RyaOutputFormat.setGeoEnabled(job, true); - RyaOutputFormat.setEntityEnabled(job, false); - write(input); - final Set<Statement> expected = new HashSet<>(); - Assert.assertEquals(expected, getSet(geo.queryContains(p1, new StatementConstraints()))); - expected.add(RyaToRdfConversions.convertStatement(input)); - Assert.assertEquals(expected, getSet(geo.queryEquals(p2, new StatementConstraints()))); - geo.close(); - } @Test public void testEntityIndexing() throws Exception { @@ -297,7 +261,6 @@ public class RyaOutputFormatTest { RyaOutputFormat.setCoreTablesEnabled(job, false); RyaOutputFormat.setFreeTextEnabled(job, false); RyaOutputFormat.setTemporalEnabled(job, false); - RyaOutputFormat.setGeoEnabled(job, false); RyaOutputFormat.setEntityEnabled(job, true); write(input); entity.close();
