You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rya.apache.org by dl...@apache.org on 2017/08/30 20:31:39 UTC
[01/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Repository: incubator-rya
Updated Branches:
refs/heads/master d47190b1a -> 9e76b8d7c
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java
deleted file mode 100644
index 4a31599..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
-l * 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.geotemporal.mongo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.rya.api.resolver.RdfToRyaConversions;
-import org.apache.rya.indexing.GeoConstants;
-import org.apache.rya.indexing.IndexingExpr;
-import org.apache.rya.indexing.IndexingFunctionRegistry;
-import org.apache.rya.indexing.IndexingFunctionRegistry.FUNCTION_TYPE;
-import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer.GeoPolicy;
-import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer.TemporalPolicy;
-import org.apache.rya.indexing.geotemporal.GeoTemporalTestBase;
-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.URIImpl;
-import org.openrdf.model.impl.ValueFactoryImpl;
-import org.openrdf.query.algebra.FunctionCall;
-import org.openrdf.query.algebra.StatementPattern;
-import org.openrdf.query.algebra.ValueConstant;
-import org.openrdf.query.algebra.ValueExpr;
-import org.openrdf.query.algebra.Var;
-
-import com.mongodb.DBObject;
-import com.mongodb.util.JSON;
-
-/**
- * Tests The {@link GeoTemporalMongoDBStorageStrategy}, which turns the filters
- * into mongo {@link DBObject}s used to query.
- *
- * This tests also ensures all possible filter functions are accounted for in the test.
- * @see TemporalPolicy Temporal Filter Functions
- * @see GeoPolicy Geo Filter Functions
- */
-public class GeoTemporalMongoDBStorageStrategyTest extends GeoTemporalTestBase {
- private GeoTemporalMongoDBStorageStrategy adapter;
- @Before
- public void setup() {
- adapter = new GeoTemporalMongoDBStorageStrategy();
- }
-
- @Test
- public void emptyFilters_test() throws Exception {
- final List<IndexingExpr> geoFilters = new ArrayList<>();
- final List<IndexingExpr> temporalFilters = new ArrayList<>();
- final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
- final String expectedString =
- "{ }";
- final DBObject expected = (DBObject) JSON.parse(expectedString);
- assertEqualMongo(expected, actual);
- }
-
- @Test
- public void equalsInstantAfterInterval_onlyOneGeo() throws Exception {
- final String query =
- "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
- + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
- + "SELECT ?point ?wkt "
- + "WHERE { "
- + " ?point geo:asWKT ?wkt . "
- + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
- + "}";
- final List<IndexingExpr> geoFilters = new ArrayList<>();
- final List<StatementPattern> sps = getSps(query);
- final List<FunctionCall> filters = getFilters(query);
- for(final FunctionCall filter : filters) {
- //should only be one.
- final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(new URIImpl(filter.getURI()), filter.getArgs());
- final IndexingExpr expr = new IndexingExpr(new URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), filter));
- geoFilters.add(expr);
- }
- final List<IndexingExpr> temporalFilters = new ArrayList<>();
- final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
- final String expectedString =
- "{ "
- + "\"location\" : { "
- + "\"$geoWithin\" : { "
- + "\"$geometry\" : { "
- + "\"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] , "
- + "\"type\" : \"Polygon\""
- + "}"
- + "}"
- + "}"
- + "}";
- final DBObject expected = (DBObject) JSON.parse(expectedString);
- assertEqualMongo(expected, actual);
- }
-
- @Test
- public void equalsInstantAfterInterval_onlyGeos() throws Exception {
-
- /*
- * TODO: change filter functions for coverage
- */
-
-
- final String query =
- "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
- + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
- + "SELECT ?point ?wkt "
- + "WHERE { "
- + " ?point geo:asWKT ?wkt . "
- + " FILTER(geof:sfIntersects(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
- + " FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 -3, -4 -3))\"^^geo:wktLiteral)) "
- + "}";
- final List<IndexingExpr> geoFilters = new ArrayList<>();
- final List<StatementPattern> sps = getSps(query);
- final List<FunctionCall> filters = getFilters(query);
- for(final FunctionCall filter : filters) {
- final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(new URIImpl(filter.getURI()), filter.getArgs());
- final IndexingExpr expr = new IndexingExpr(new URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), filter));
- geoFilters.add(expr);
- }
- final List<IndexingExpr> temporalFilters = new ArrayList<>();
- final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
-
- final String expectedString =
- "{ "
- + "\"$and\" : [ { "
- + "\"location\" : {"
- + " \"coordinates\" : [ [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 2.0 , 3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]] ,"
- + " \"type\" : \"Polygon\""
- + "}"
- + "} , { "
- + "\"location\" : { "
- + "\"$geoIntersects\" : {"
- + " \"$geometry\" : {"
- + " \"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] ,"
- + " \"type\" : \"Polygon\""
- + "}"
- + "}"
- + "}"
- + "}]}";
- final DBObject expected = (DBObject) JSON.parse(expectedString);
- assertEqualMongo(expected, actual);
- }
-
- @Test
- public void equalsInstantAfterInterval_onlyOneTemporal() throws Exception {
- final String query =
- "PREFIX time: <http://www.w3.org/2006/time#> \n"
- + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
- + "SELECT ?event ?time "
- + "WHERE { "
- + " ?event time:atTime ?time . "
- + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) . "
- + "}";
- final List<IndexingExpr> geoFilters = new ArrayList<>();
- final List<IndexingExpr> temporalFilters = new ArrayList<>();
- final List<StatementPattern> sps = getSps(query);
- final List<FunctionCall> filters = getFilters(query);
- for(final FunctionCall filter : filters) {
- //should only be one.
- final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(new URIImpl(filter.getURI()), filter.getArgs());
- final IndexingExpr expr = new IndexingExpr(new URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), filter));
- temporalFilters.add(expr);
- }
- final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
- final String expectedString =
- "{ "
- + "\"instant\" : {"
- + "\"$date\" : \"2015-12-30T12:00:00.000Z\""
- + "}"
- + "}";
- final DBObject expected = (DBObject) JSON.parse(expectedString);
- assertEqualMongo(expected, actual);
- }
-
- @Test
- public void equalsInstantAfterInterval_onlyTemporal() throws Exception {
- final String query =
- "PREFIX time: <http://www.w3.org/2006/time#> \n"
- + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
- + "SELECT ?event ?time "
- + "WHERE { "
- + " ?event time:atTime ?time . "
- + " FILTER(tempo:before(?time, \"2015-12-30T12:00:00Z\")) . "
- + " FILTER(tempo:insideInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
- + "}";
- final List<IndexingExpr> geoFilters = new ArrayList<>();
- final List<IndexingExpr> temporalFilters = new ArrayList<>();
- final List<StatementPattern> sps = getSps(query);
- final List<FunctionCall> filters = getFilters(query);
- for(final FunctionCall filter : filters) {
- final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(new URIImpl(filter.getURI()), filter.getArgs());
- final IndexingExpr expr = new IndexingExpr(new URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), filter));
- temporalFilters.add(expr);
- }
- final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
- final String expectedString =
- "{ "
- + "\"$and\" : [{"
- + "\"instant\" : {"
- + "\"$gt\" : {"
- + "\"$date\" : \"1970-01-01T00:00:00.000Z\""
- + "},"
- + "\"$lt\" : {"
- + "\"$date\" : \"1970-01-01T00:00:01.000Z\""
- + "},"
- + "}}, {"
- + "\"instant\" : {"
- + "\"$lt\" : {"
- + "\"$date\" : \"2015-12-30T12:00:00.000Z\""
- + "}"
- + "}"
- + "}]"
- + "}";
- final DBObject expected = (DBObject) JSON.parse(expectedString);
- assertEqualMongo(expected, actual);
- }
-
- @Test
- public void equalsInstantAfterInterval_GeoTemporalOneEach() throws Exception {
- final String query =
- "PREFIX time: <http://www.w3.org/2006/time#> \n"
- + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
- + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
- + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
- + "SELECT ?event ?time ?point ?wkt "
- + "WHERE { "
- + " ?event time:atTime ?time . "
- + " ?point geo:asWKT ?wkt . "
- + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
- + " FILTER(tempo:after(?time, \"2015-12-30T12:00:00Z\")) "
- + "}";
- final List<IndexingExpr> geoFilters = new ArrayList<>();
- final List<IndexingExpr> temporalFilters = new ArrayList<>();
- final List<StatementPattern> sps = getSps(query);
- final List<FunctionCall> filters = getFilters(query);
- for(final FunctionCall filter : filters) {
- final URI filterURI = new URIImpl(filter.getURI());
- final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, filter.getArgs());
- final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), extractArguments(objVar.getName(), filter));
- if(IndexingFunctionRegistry.getFunctionType(filterURI) == FUNCTION_TYPE.GEO) {
- geoFilters.add(expr);
- } else {
- temporalFilters.add(expr);
- }
- }
- final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
- final String expectedString =
- "{ "
- + "\"$and\" : [ { "
- + "\"location\" : { "
- + "\"$geoWithin\" : { "
- + "\"$geometry\" : { "
- + "\"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] , "
- + "\"type\" : \"Polygon\""
- + "}"
- + "}"
- + "}"
- + "} , { "
- + "\"instant\" : { "
- + "\"$gt\" : { "
- + "\"$date\" : \"2015-12-30T12:00:00.000Z\""
- + "}"
- + "}"
- + "}]"
- + "}";
- final DBObject expected = (DBObject) JSON.parse(expectedString);
- assertEqualMongo(expected, actual);
- }
-
- @Test
- public void equalsInstantAfterInterval_GeoTemporalTwoEach() throws Exception {
- final String query =
- "PREFIX time: <http://www.w3.org/2006/time#> \n"
- + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
- + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
- + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
- + "SELECT ?event ?time ?point ?wkt "
- + "WHERE { "
- + " ?event time:atTime ?time . "
- + " ?point geo:asWKT ?wkt . "
- + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
- + " FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 -3, -4 -3))\"^^geo:wktLiteral)) "
- + " FILTER(tempo:hasEndInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
- + " FILTER(tempo:beforeInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
- + "}";
- final List<IndexingExpr> geoFilters = new ArrayList<>();
- final List<IndexingExpr> temporalFilters = new ArrayList<>();
- final List<StatementPattern> sps = getSps(query);
- final List<FunctionCall> filters = getFilters(query);
- for(final FunctionCall filter : filters) {
- final URI filterURI = new URIImpl(filter.getURI());
- final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, filter.getArgs());
- final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), extractArguments(objVar.getName(), filter));
- if(IndexingFunctionRegistry.getFunctionType(filterURI) == FUNCTION_TYPE.GEO) {
- geoFilters.add(expr);
- } else {
- temporalFilters.add(expr);
- }
- }
- final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
- final String expectedString =
- "{ "
- + "\"$and\" : [ { "
- + "\"$and\" : [ { "
- + "\"location\" : { "
- + "\"coordinates\" : [ [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 2.0 , 3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]] , "
- + "\"type\" : \"Polygon\""
- + "}"
- + "} , { "
- + "\"location\" : { "
- + "\"$geoWithin\" : { "
- + "\"$geometry\" : { "
- + "\"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] , "
- + "\"type\" : \"Polygon\""
- + "}"
- + "}"
- + "}"
- + "}]"
- + "} , { "
- + "\"$and\" : [ { "
- + "\"instant\" : { "
- + "\"$lt\" : { "
- + "\"$date\" : \"1970-01-01T00:00:00.000Z\""
- + "}"
- + "}"
- + "} , { "
- + "\"instant\" : { "
- + "\"$date\" : \"1970-01-01T00:00:01.000Z\""
- + "}"
- + "}]"
- + "}]"
- + "}";
- final DBObject expected = (DBObject) JSON.parse(expectedString);
- assertEqualMongo(expected, actual);
- }
-
- @Test
- public void equalsInstantAfterInterval_GeoTemporalSingleGeoTwoTemporal() throws Exception {
- final String query =
- "PREFIX time: <http://www.w3.org/2006/time#> \n"
- + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
- + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
- + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
- + "SELECT ?event ?time ?point ?wkt "
- + "WHERE { "
- + " ?event time:atTime ?time . "
- + " ?point geo:asWKT ?wkt . "
- + " FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 -3, -4 -3))\"^^geo:wktLiteral)) ."
- + " FILTER(tempo:hasBeginningInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
- + " FILTER(tempo:afterInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\"))"
- + "}";
- final List<IndexingExpr> geoFilters = new ArrayList<>();
- final List<IndexingExpr> temporalFilters = new ArrayList<>();
- final List<StatementPattern> sps = getSps(query);
- final List<FunctionCall> filters = getFilters(query);
- for(final FunctionCall filter : filters) {
- final URI filterURI = new URIImpl(filter.getURI());
- final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, filter.getArgs());
- final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), extractArguments(objVar.getName(), filter));
- if(IndexingFunctionRegistry.getFunctionType(filterURI) == FUNCTION_TYPE.GEO) {
- geoFilters.add(expr);
- } else {
- temporalFilters.add(expr);
- }
- }
- final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
- final String expectedString =
- "{ "
- + "\"$and\" : [ { "
- + "\"location\" : { "
- + "\"coordinates\" : [ [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 2.0 , 3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]] , "
- + "\"type\" : \"Polygon\""
- + "}"
- + "} , { "
- + "\"$and\" : [ { "
- + "\"instant\" : { "
- + "\"$gt\" : { "
- + "\"$date\" : \"1970-01-01T00:00:01.000Z\""
- + "}"
- + "}"
- + "} , { "
- + "\"instant\" : { "
- + "\"$date\" : \"1970-01-01T00:00:00.000Z\""
- + "}"
- + "}]"
- + "}]"
- + "}";
- final DBObject expected = (DBObject) JSON.parse(expectedString);
- assertEqualMongo(expected, actual);
- }
-
- @Test
- public void serializeTest() {
- final ValueFactory vf = new ValueFactoryImpl();
- final Resource subject = vf.createURI("foo:subj");
- final Resource context = vf.createURI("foo:context");
-
- //GEO
- URI predicate = GeoConstants.GEO_AS_WKT;
- Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT);
-
- Statement statement = new ContextStatementImpl(subject, predicate, object, context);
- DBObject actual = adapter.serialize(RdfToRyaConversions.convertStatement(statement));
- String expectedString =
- "{ "
- + "\"_id\" : -852305321 , "
- + "\"location\" : { "
- + "\"coordinates\" : [ -77.03524 , 38.889468] , "
- + "\"type\" : \"Point\""
- + "}"
- + "}";
- DBObject expected = (DBObject) JSON.parse(expectedString);
- assertEqualMongo(expected, actual);
-
- //TIME INSTANT
- predicate = new URIImpl("Property:event:time");
- object = vf.createLiteral("2015-12-30T12:00:00Z");
- statement = new ContextStatementImpl(subject, predicate, object, context);
- actual = adapter.serialize(RdfToRyaConversions.convertStatement(statement));
- expectedString =
- "{"
- +"_id : -852305321, "
- +"time: {"
- + "instant : {"
- +"\"$date\" : \"2015-12-30T12:00:00.000Z\""
- + "}"
- + "}"
- + "}";
- expected = (DBObject) JSON.parse(expectedString);
- assertEqualMongo(expected, actual);
-
- //TIME INTERVAL
- predicate = new URIImpl("Property:circa");
- object = vf.createLiteral("[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]");
- statement = new ContextStatementImpl(subject, predicate, object, context);
- actual = adapter.serialize(RdfToRyaConversions.convertStatement(statement));
- expectedString =
- "{"
- +"_id : -852305321, "
- +"time: {"
- + "start : {"
- +"\"$date\" : \"1970-01-01T00:00:00.000Z\""
- + "},"
- + "end : {"
- +"\"$date\" : \"1970-01-01T00:00:01.000Z\""
- + "}"
- + "}"
- + "}";
- expected = (DBObject) JSON.parse(expectedString);
- assertEqualMongo(expected, actual);
- }
-
- private Value[] extractArguments(final String matchName, final FunctionCall call) {
- final Value args[] = new Value[call.getArgs().size() - 1];
- int argI = 0;
- for (int i = 0; i != call.getArgs().size(); ++i) {
- final ValueExpr arg = call.getArgs().get(i);
- if (argI == i && arg instanceof Var && matchName.equals(((Var)arg).getName())) {
- continue;
- }
- if (arg instanceof ValueConstant) {
- args[argI] = ((ValueConstant)arg).getValue();
- } else if (arg instanceof Var && ((Var)arg).hasValue()) {
- args[argI] = ((Var)arg).getValue();
- } else {
- throw new IllegalArgumentException("Query error: Found " + arg + ", expected a Literal, BNode or URI");
- }
- ++argI;
- }
- return args;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java
deleted file mode 100644
index 5b07460..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/**
- * 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.geotemporal.mongo;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Optional;
-
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.indexing.TemporalInstant;
-import org.apache.rya.indexing.TemporalInstantRfc3339;
-import org.apache.rya.indexing.geotemporal.model.Event;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage.EventAlreadyExistsException;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage.EventStorageException;
-import org.joda.time.DateTime;
-import org.junit.Test;
-
-import com.vividsolutions.jts.geom.Coordinate;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.GeometryFactory;
-import com.vividsolutions.jts.geom.PrecisionModel;
-
-/**
- * Integration tests the methods of {@link MongoEventStorage}.
- */
-public class MongoEventStorageTest extends MongoITBase {
-
- private static final String RYA_INSTANCE_NAME = "testInstance";
- private static final GeometryFactory GF = new GeometryFactory(new PrecisionModel(), 4326);
-
- @Test
- public void create_and_get() throws Exception {
- final Geometry geo = GF.createPoint(new Coordinate(10, 10));
- final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
-
- // An Event that will be stored.
- final Event event = Event.builder()
- .setSubject(new RyaURI("urn:event/001"))
- .setGeometry(geo)
- .setTemporalInstant(instant)
- .build();
-
- // Create it.
- final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
- storage.create(event);
-
- // Get it.
- final Optional<Event> storedEvent = storage.get(new RyaURI("urn:event/001"));
-
- // Verify the correct value was returned.
- assertEquals(event, storedEvent.get());
- }
-
- @Test
- public void can_not_create_with_same_subject() throws Exception {
- final Geometry geo = GF.createPoint(new Coordinate(10, 10));
- final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
-
- // An Event that will be stored.
- final Event event = Event.builder()
- .setSubject(new RyaURI("urn:event/001"))
- .setGeometry(geo)
- .setTemporalInstant(instant)
- .build();
-
- // Create it.
- final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
- storage.create(event);
-
- // Try to create it again. This will fail.
- boolean failed = false;
- try {
- storage.create(event);
- } catch(final EventAlreadyExistsException e) {
- failed = true;
- }
- assertTrue(failed);
- }
-
- @Test
- public void get_noneExisting() throws Exception {
- // Get a Type that hasn't been created.
- final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
- final Optional<Event> storedEvent = storage.get(new RyaURI("urn:event/000"));
-
- // Verify nothing was returned.
- assertFalse(storedEvent.isPresent());
- }
-
- @Test
- public void delete() throws Exception {
- final Geometry geo = GF.createPoint(new Coordinate(10, 10));
- final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
-
- // An Event that will be stored.
- final Event event = Event.builder()
- .setSubject(new RyaURI("urn:event/002"))
- .setGeometry(geo)
- .setTemporalInstant(instant)
- .build();
-
- // Create it.
- final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
- storage.create(event);
-
- // Delete it.
- final boolean deleted = storage.delete( new RyaURI("urn:event/002") );
-
- // Verify a document was deleted.
- assertTrue( deleted );
- }
-
- @Test
- public void delete_nonExisting() throws Exception {
- // Delete an Event that has not been created.
- final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
- final boolean deleted = storage.delete( new RyaURI("urn:event/003") );
-
- // Verify no document was deleted.
- assertFalse( deleted );
- }
-
- @Test
- public void update() throws Exception {
- final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
- final Geometry geo = GF.createPoint(new Coordinate(10, 10));
- TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
-
- // An Event that will be stored.
- final Event event = Event.builder()
- .setSubject(new RyaURI("urn:event/004"))
- .setGeometry(geo)
- .setTemporalInstant(instant)
- .build();
-
- storage.create(event);
-
- // Show Alice was stored.
- Optional<Event> latest = storage.get(new RyaURI("urn:event/004"));
- assertEquals(event, latest.get());
-
- instant = new TemporalInstantRfc3339(DateTime.now());
- // Change Alice's eye color to brown.
- final Event updated = Event.builder(event)
- .setTemporalInstant(instant)
- .build();
-
- storage.update(event, updated);
-
- // Fetch the Alice object and ensure it has the new value.
- latest = storage.get(new RyaURI("urn:event/004"));
-
- assertEquals(updated, latest.get());
- }
-
- @Test(expected = EventStorageException.class)
- public void update_differentSubjects() throws Exception {
- final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
- final Geometry geo = GF.createPoint(new Coordinate(10, 10));
- final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
-
- // Two objects that do not have the same Subjects.
- final Event old = Event.builder()
- .setSubject(new RyaURI("urn:event/001"))
- .setGeometry(geo)
- .setTemporalInstant(instant)
- .build();
-
- final Event updated = Event.builder()
- .setSubject(new RyaURI("urn:event/002"))
- .setGeometry(geo)
- .setTemporalInstant(instant)
- .build();
-
- // The update will fail.
- storage.update(old, updated);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java
deleted file mode 100644
index f2d0868..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * 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.geotemporal.mongo;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Optional;
-
-import org.apache.rya.api.domain.RyaStatement;
-import org.apache.rya.api.resolver.RdfToRyaConversions;
-import org.apache.rya.indexing.GeoConstants;
-import org.apache.rya.indexing.TemporalInstant;
-import org.apache.rya.indexing.geotemporal.model.Event;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage;
-import org.junit.Before;
-import org.junit.Test;
-import org.openrdf.model.Resource;
-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.vividsolutions.jts.geom.Geometry;
-
-/**
- * Integration tests the methods of {@link MongoGeoTemporalIndexer}.
- */
-public class MongoGeoTemporalIndexerIT extends MongoITBase {
- private MongoGeoTemporalIndexer indexer;
-
- @Before
- public void makeTestIndexer() throws Exception {
- indexer = new MongoGeoTemporalIndexer();
- indexer.setConf(conf);
- indexer.init();
- }
-
- @Test
- public void ensureEvent() throws Exception {
- final RyaStatement geoStmnt = statement(point(0, 0));
- final RyaStatement timeStmnt = statement(makeInstant(0));
-
- final EventStorage store = indexer.getEventStorage(conf);
-
- indexer.storeStatement(geoStmnt);
- Optional<Event> evnt = store.get(geoStmnt.getSubject());
- assertTrue(evnt.isPresent());
- Event expected = Event.builder()
- .setSubject(geoStmnt.getSubject())
- .setGeometry(point(0, 0))
- .build();
- assertEquals(expected, evnt.get());
-
- indexer.storeStatement(timeStmnt);
- evnt = store.get(timeStmnt.getSubject());
- assertTrue(evnt.isPresent());
- expected = Event.builder()
- .setSubject(geoStmnt.getSubject())
- .setGeometry(point(0, 0))
- .setTemporalInstant(makeInstant(0))
- .build();
- assertEquals(expected, evnt.get());
-
- indexer.deleteStatement(geoStmnt);
- evnt = store.get(timeStmnt.getSubject());
- assertTrue(evnt.isPresent());
- expected = Event.builder()
- .setSubject(timeStmnt.getSubject())
- .setTemporalInstant(makeInstant(0))
- .build();
- assertEquals(expected, evnt.get());
-
- indexer.deleteStatement(timeStmnt);
- evnt = store.get(timeStmnt.getSubject());
- assertTrue(evnt.isPresent());
- expected = Event.builder()
- .setSubject(timeStmnt.getSubject())
- .build();
- assertEquals(expected, evnt.get());
- }
-
- private static RyaStatement statement(final Geometry geo) {
- final ValueFactory vf = new ValueFactoryImpl();
- final Resource subject = vf.createURI("uri:test");
- 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 RyaStatement statement(final TemporalInstant instant) {
- final ValueFactory vf = new ValueFactoryImpl();
- final Resource subject = vf.createURI("uri:test");
- final URI predicate = vf.createURI("Property:atTime");
- final Value object = vf.createLiteral(instant.toString());
- return RdfToRyaConversions.convertStatement(new StatementImpl(subject, predicate, object));
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java
deleted file mode 100644
index 7488572..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * 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.geotemporal.mongo;
-
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.geotemporal.GeoTemporalTestBase;
-import org.apache.rya.indexing.mongodb.MongoIndexingConfiguration;
-import org.apache.rya.mongodb.MockMongoSingleton;
-import org.junit.After;
-import org.junit.Before;
-
-import com.mongodb.MongoClient;
-
-/**
- * A base class that may be used when implementing Mongo DB integration tests that
- * use the JUnit framework.
- */
-public class MongoITBase extends GeoTemporalTestBase {
-
- private static MongoClient mongoClient = null;
- protected static MongoIndexingConfiguration conf;
-
- @Before
- public void setupTest() throws Exception {
- mongoClient = MockMongoSingleton.getInstance();
- conf = MongoIndexingConfiguration.builder()
- .setMongoCollectionPrefix("test_")
- .setMongoDBName("testDB")
- .build();
- conf.setBoolean(ConfigUtils.USE_MONGO, true);
- conf.setMongoClient(mongoClient);
- }
-
- @After
- public void cleanupTest() {
- // Remove any DBs that were created by the test.
- for(final String dbName : mongoClient.listDatabaseNames()) {
- mongoClient.dropDatabase(dbName);
- }
- }
-
- /**
- * @return A {@link MongoClient} that is connected to the embedded instance of Mongo DB.
- */
- public MongoClient getMongoClient() {
- return mongoClient;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerSfTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerSfTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerSfTest.java
deleted file mode 100644
index d05524f..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerSfTest.java
+++ /dev/null
@@ -1,262 +0,0 @@
-package org.apache.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 org.apache.rya.indexing.GeoIndexingTestUtils.getSet;
-
-import java.util.Map;
-import java.util.Set;
-
-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.OptionalConfigUtils;
-import org.apache.rya.indexing.StatementConstraints;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.geotemporal.mongo.MongoITBase;
-import org.apache.rya.indexing.mongodb.geo.MongoGeoIndexer;
-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.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.GeometryFactory;
-import com.vividsolutions.jts.geom.LineString;
-import com.vividsolutions.jts.geom.Point;
-import com.vividsolutions.jts.geom.Polygon;
-import com.vividsolutions.jts.geom.PrecisionModel;
-
-import info.aduna.iteration.CloseableIteration;
-
-/**
- * Tests all of the "simple functions" of the geoindexer.
- */
-public class MongoGeoIndexerSfTest extends MongoITBase {
- 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 {
- conf.set(ConfigUtils.GEO_PREDICATES_LIST, "http://www.opengis.net/ont/geosparql#asWKT");
- conf.set(OptionalConfigUtils.USE_GEO, "true");
-
- g = new MongoGeoIndexer();
- g.initIndexer(conf, super.getMongoClient());
- 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));
-
- }
-
- 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 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/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerTest.java
deleted file mode 100644
index 3506f5d..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerTest.java
+++ /dev/null
@@ -1,370 +0,0 @@
-package org.apache.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 org.apache.rya.api.resolver.RdfToRyaConversions.convertStatement;
-import static org.apache.rya.indexing.GeoIndexingTestUtils.getSet;
-
-import java.util.Collections;
-import java.util.Set;
-
-import org.apache.rya.indexing.GeoConstants;
-import org.apache.rya.indexing.OptionalConfigUtils;
-import org.apache.rya.indexing.StatementConstraints;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.geotemporal.mongo.MongoITBase;
-import org.apache.rya.indexing.mongodb.geo.MongoGeoIndexer;
-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;
-
-public class MongoGeoIndexerTest extends MongoITBase {
- private static final StatementConstraints EMPTY_CONSTRAINTS = new StatementConstraints();
- GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
-
- @Before
- public void before() throws Exception {
- conf.set(ConfigUtils.GEO_PREDICATES_LIST, "http://www.opengis.net/ont/geosparql#asWKT");
- conf.set(OptionalConfigUtils.USE_GEO, "true");
- }
-
- @Test
- public void testRestrictPredicatesSearch() throws Exception {
- conf.setStrings(ConfigUtils.GEO_PREDICATES_LIST, "pred:1,pred:2");
- try (final MongoGeoIndexer f = new MongoGeoIndexer()) {
- f.initIndexer(conf, super.getMongoClient());
-
- 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));
- }
- }
-
- @Test
- public void testPrimeMeridianSearch() throws Exception {
- try (final MongoGeoIndexer f = new MongoGeoIndexer()) {
- f.initIndexer(conf, super.getMongoClient());
-
- 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
- f.initIndexer(conf, super.getMongoClient());
-
- 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
- f.initIndexer(conf, super.getMongoClient());
-
- 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
- f.initIndexer(conf, super.getMongoClient());
-
- 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
- f.initIndexer(conf, super.getMongoClient());
-
- 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
- f.initIndexer(conf, super.getMongoClient());
-
- 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
- f.initIndexer(conf, super.getMongoClient());
-
- 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
- f.initIndexer(conf, super.getMongoClient());
-
- 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/9e76b8d7/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index fd12a7d..9516b9c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -137,6 +137,7 @@ under the License.
<jcip.version>1.0-1</jcip.version>
<findbugs.plugin.version>3.0.4</findbugs.plugin.version>
<kafka.version>0.10.0.1</kafka.version>
+ <jopt-simple.version>4.9</jopt-simple.version>
<!-- set profile property defaults -->
<skip.rya.it>true</skip.rya.it> <!-- modified by -P enable-it -->
[02/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerTest.java
deleted file mode 100644
index 7c4fa47..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerTest.java
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * 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.api.resolver.RdfToRyaConversions.convertStatement;
-import static org.apache.rya.indexing.GeoIndexingTestUtils.getSet;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-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.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.AfterClass;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-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.google.common.io.Files;
-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 mil.nga.giat.geowave.datastore.accumulo.minicluster.MiniAccumuloClusterFactory;
-
-/**
- * Tests higher level functioning of the geoindexer parse WKT, predicate list,
- * prime and anti meridian, delete, search, context, search with Statement Constraints.
- */
-public class GeoWaveIndexerTest {
-
- private static final StatementConstraints EMPTY_CONSTRAINTS = new StatementConstraints();
-
- private AccumuloRdfConfiguration conf;
- private final GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
-
- 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";
-
- @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);
- }
- }
- }
-
- @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);
- }
- }
-
- @Test
- public void testRestrictPredicatesSearch() throws Exception {
- conf.setStrings(ConfigUtils.GEO_PREDICATES_LIST, "pred:1,pred:2");
- try (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
- f.setConf(conf);
- f.purge(conf);
-
- 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));
- }
- }
-
- @Test
- public void testPrimeMeridianSearch() throws Exception {
- try (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
- f.setConf(conf);
- f.purge(conf);
-
- 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
- f.setConf(conf);
- f.purge(conf);
-
- 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
- f.setConf(conf);
- f.purge(conf);
-
- 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
- final double[] world = { -180, 90, 180, 90, 180, -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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
- f.setConf(conf);
- f.purge(conf);
-
- 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
- f.setConf(conf);
- f.purge(conf);
-
- 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
- f.setConf(conf);
- f.purge(conf);
-
- 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
- f.setConf(conf);
- f.purge(conf);
-
- 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
- f.setConf(conf);
- f.purge(conf);
-
- 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/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java
deleted file mode 100644
index 7151b56..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * 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.geotemporal;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-
-import java.util.List;
-
-import org.apache.rya.indexing.GeoConstants;
-import org.apache.rya.indexing.TemporalInstantRfc3339;
-import org.apache.rya.indexing.external.matching.QuerySegment;
-import org.apache.rya.indexing.geotemporal.GeoTemporalIndexSetProvider;
-import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage;
-import org.junit.Before;
-import org.junit.Test;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.model.ValueFactory;
-import org.openrdf.model.impl.ValueFactoryImpl;
-
-public class GeoTemporalProviderTest extends GeoTemporalTestBase {
- private static final String URI_PROPERTY_AT_TIME = "Property:atTime";
- private GeoTemporalIndexSetProvider provider;
- private EventStorage events;
- @Before
- public void setup() {
- events = mock(EventStorage.class);
- provider = new GeoTemporalIndexSetProvider(events);
- }
-
- /*
- * Simplest Happy Path test
- */
- @Test
- public void twoPatternsTwoFilters_test() throws Exception {
- final ValueFactory vf = new ValueFactoryImpl();
- final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
- final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
- final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
- final String query =
- "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
- "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
- "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
- "SELECT * WHERE { " +
- "?subj <" + tempPred + "> ?time ."+
- "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
- " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
- " FILTER(time:equals(?time, " + temp + ")) . " +
- "}";
- final QuerySegment<EventQueryNode> node = getQueryNode(query);
- final List<EventQueryNode> nodes = provider.getExternalSets(node);
- assertEquals(1, nodes.size());
- }
-
- @Test
- public void onePatternTwoFilters_test() throws Exception {
- final ValueFactory vf = new ValueFactoryImpl();
- final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
- final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
- final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
- final String query =
- "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
- "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
- "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
- "SELECT * WHERE { " +
- "?subj <" + tempPred + "> ?time ."+
- " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
- " FILTER(time:equals(?time, " + temp + ")) . " +
- "}";
- final QuerySegment<EventQueryNode> node = getQueryNode(query);
- final List<EventQueryNode> nodes = provider.getExternalSets(node);
- assertEquals(0, nodes.size());
- }
-
- @Test
- public void twoPatternsOneFilter_test() throws Exception {
- final ValueFactory vf = new ValueFactoryImpl();
- final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
- final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
- final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
- final String query =
- "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
- "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
- "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
- "SELECT * WHERE { " +
- "?subj <" + tempPred + "> ?time ."+
- "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
- " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
- "}";
- final QuerySegment<EventQueryNode> node = getQueryNode(query);
- final List<EventQueryNode> nodes = provider.getExternalSets(node);
- assertEquals(0, nodes.size());
- }
-
- @Test
- public void twoPatternsNoFilter_test() throws Exception {
- final ValueFactory vf = new ValueFactoryImpl();
- final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
- final String query =
- "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
- "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
- "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
- "SELECT * WHERE { " +
- "?subj <" + tempPred + "> ?time ."+
- "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
- "}";
- final QuerySegment<EventQueryNode> node = getQueryNode(query);
- final List<EventQueryNode> nodes = provider.getExternalSets(node);
- assertEquals(0, nodes.size());
- }
-
- @Test
- public void twoPatternsTwoFiltersNotValid_test() throws Exception {
- final ValueFactory vf = new ValueFactoryImpl();
- final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
- final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
- final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
- //Only handles geo and temporal filters
- final String query =
- "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
- "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
- "PREFIX text: <http://rdf.useekm.com/fts#text>" +
- "SELECT * WHERE { " +
- "?subj <" + tempPred + "> ?time ."+
- "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
- " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
- " FILTER(text:equals(?time, " + temp + ")) . " +
- "}";
- final QuerySegment<EventQueryNode> node = getQueryNode(query);
- final List<EventQueryNode> nodes = provider.getExternalSets(node);
- assertEquals(0, nodes.size());
- }
-
- @Test
- public void twoSubjOneFilter_test() throws Exception {
- final ValueFactory vf = new ValueFactoryImpl();
- final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
- final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
- final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
- final String query =
- "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
- "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
- "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
- "SELECT * WHERE { " +
- "?subj <" + tempPred + "> ?time ."+
- "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
- "?subj2 <" + tempPred + "> ?time2 ."+
- "?subj2 <" + GeoConstants.GEO_AS_WKT + "> ?loc2 . " +
- " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
- " FILTER(time:equals(?time, " + temp + ")) . " +
- "}";
- final QuerySegment<EventQueryNode> node = getQueryNode(query);
- final List<EventQueryNode> nodes = provider.getExternalSets(node);
- assertEquals(1, nodes.size());
- }
-
- @Test
- public void twoNode_test() throws Exception {
- final ValueFactory vf = new ValueFactoryImpl();
- final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
- final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
- final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
- final String query =
- "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
- "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
- "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
- "SELECT * WHERE { " +
- "?subj <" + tempPred + "> ?time ."+
- "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
- "?subj2 <" + tempPred + "> ?time2 ."+
- "?subj2 <" + GeoConstants.GEO_AS_WKT + "> ?loc2 . " +
- " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
- " FILTER(time:equals(?time, " + temp + ")) . " +
- " FILTER(geos:sfContains(?loc2, " + geo + ")) . " +
- " FILTER(time:equals(?time2, " + temp + ")) . " +
- "}";
- final QuerySegment<EventQueryNode> node = getQueryNode(query);
- final List<EventQueryNode> nodes = provider.getExternalSets(node);
- assertEquals(2, nodes.size());
- }
-
- @Test
- public void twoSubjectMultiFilter_test() throws Exception {
- final ValueFactory vf = new ValueFactoryImpl();
- final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
- final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
- final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
- final String query =
- "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
- "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
- "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
- "SELECT * WHERE { " +
- "?subj <" + tempPred + "> ?time ."+
- "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
- " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
- " FILTER(time:equals(?time, " + temp + ")) . " +
- " FILTER(geos:sfWithin(?loc, " + geo + ")) . " +
- " FILTER(time:before(?time, " + temp + ")) . " +
- "}";
- final QuerySegment<EventQueryNode> node = getQueryNode(query);
- final List<EventQueryNode> nodes = provider.getExternalSets(node);
- assertEquals(1, nodes.size());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java
deleted file mode 100644
index 6b6bf15..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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.geotemporal;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.rya.indexing.TemporalInstant;
-import org.apache.rya.indexing.TemporalInstantRfc3339;
-import org.apache.rya.indexing.external.matching.QuerySegment;
-import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
-import org.junit.ComparisonFailure;
-import org.mockito.Mockito;
-import org.openrdf.query.algebra.FunctionCall;
-import org.openrdf.query.algebra.QueryModelNode;
-import org.openrdf.query.algebra.StatementPattern;
-import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
-import org.openrdf.query.algebra.helpers.StatementPatternCollector;
-import org.openrdf.query.parser.sparql.SPARQLParser;
-
-import com.vividsolutions.jts.geom.Coordinate;
-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;
-
-public class GeoTemporalTestBase {
- private static final GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
-
- /**
- * Make an uniform instant with given seconds.
- */
- protected static TemporalInstant makeInstant(final int secondsMakeMeUnique) {
- return new TemporalInstantRfc3339(2015, 12, 30, 12, 00, secondsMakeMeUnique);
- }
-
- protected 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;
- }
-
- protected static Point point(final double x, final double y) {
- return gf.createPoint(new Coordinate(x, y));
- }
-
- protected 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);
- }
-
- protected 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 };
- }
-
- protected void assertEqualMongo(final Object expected, final Object actual) throws ComparisonFailure {
- try {
- assertEquals(expected, actual);
- } catch(final Throwable e) {
- throw new ComparisonFailure(e.getMessage(), expected.toString(), actual.toString());
- }
- }
-
- public List<FunctionCall> getFilters(final String query) throws Exception {
- final FunctionCallCollector collector = new FunctionCallCollector();
- new SPARQLParser().parseQuery(query, null).getTupleExpr().visit(collector);
- return collector.getTupleExpr();
- }
-
- public List<StatementPattern> getSps(final String query) throws Exception {
- final StatementPatternCollector collector = new StatementPatternCollector();
- new SPARQLParser().parseQuery(query, null).getTupleExpr().visit(collector);
- return collector.getStatementPatterns();
- }
-
- public QuerySegment<EventQueryNode> getQueryNode(final String query) throws Exception {
- final List<QueryModelNode> exprs = getNodes(query);
- final QuerySegment<EventQueryNode> node = Mockito.mock(QuerySegment.class);
- //provider only cares about Ordered nodes.
- Mockito.when(node.getOrderedNodes()).thenReturn(exprs);
- return node;
- }
-
- private static List<QueryModelNode> getNodes(final String sparql) throws Exception {
- final NodeCollector collector = new NodeCollector();
- new SPARQLParser().parseQuery(sparql, null).getTupleExpr().visit(collector);
- return collector.getTupleExpr();
- }
-
- private static class NodeCollector extends QueryModelVisitorBase<RuntimeException> {
- private final List<QueryModelNode> stPatterns = new ArrayList<>();
-
- public List<QueryModelNode> getTupleExpr() {
- return stPatterns;
- }
-
- @Override
- public void meet(final FunctionCall node) {
- stPatterns.add(node);
- }
-
- @Override
- public void meet(final StatementPattern node) {
- stPatterns.add(node);
- }
- }
-
- private static class FunctionCallCollector extends QueryModelVisitorBase<RuntimeException> {
- private final List<FunctionCall> filters = new ArrayList<>();
-
- public List<FunctionCall> getTupleExpr() {
- return filters;
- }
-
- @Override
- public void meet(final FunctionCall node) {
- filters.add(node);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java
deleted file mode 100644
index e0209e8..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * 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.geotemporal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.indexing.GeoConstants;
-import org.apache.rya.indexing.GeoRyaSailFactory;
-import org.apache.rya.indexing.OptionalConfigUtils;
-import org.apache.rya.indexing.TemporalInstantRfc3339;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.geotemporal.model.Event;
-import org.apache.rya.indexing.geotemporal.mongo.MongoGeoTemporalIndexer;
-import org.apache.rya.indexing.geotemporal.mongo.MongoITBase;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage;
-import org.apache.rya.mongodb.MongoDBRdfConfiguration;
-import org.junit.Before;
-import org.junit.Test;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.model.ValueFactory;
-import org.openrdf.model.impl.ValueFactoryImpl;
-import org.openrdf.query.BindingSet;
-import org.openrdf.query.QueryLanguage;
-import org.openrdf.query.TupleQueryResult;
-import org.openrdf.query.impl.MapBindingSet;
-import org.openrdf.repository.sail.SailRepository;
-import org.openrdf.repository.sail.SailRepositoryConnection;
-import org.openrdf.sail.Sail;
-
-import com.mongodb.MongoClient;
-
-public class MongoGeoTemporalIndexIT extends MongoITBase {
- private static final String URI_PROPERTY_AT_TIME = "Property:atTime";
-
- private static final ValueFactory VF = ValueFactoryImpl.getInstance();
- private MongoDBRdfConfiguration conf;
- private SailRepositoryConnection conn;
- private MongoClient mongoClient;
- private static final AtomicInteger COUNTER = new AtomicInteger(1);
-
- @Before
- public void setUp() throws Exception{
- mongoClient = super.getMongoClient();
- conf = new MongoDBRdfConfiguration();
- conf.set(MongoDBRdfConfiguration.MONGO_DB_NAME, MongoGeoTemporalIndexIT.class.getSimpleName() + "_" + COUNTER.getAndIncrement());
- conf.set(MongoDBRdfConfiguration.MONGO_COLLECTION_PREFIX, "rya");
- conf.set(RdfCloudTripleStoreConfiguration.CONF_TBL_PREFIX, "rya");
- conf.setBoolean(ConfigUtils.USE_MONGO, true);
- conf.setBoolean(OptionalConfigUtils.USE_GEOTEMPORAL, true);
- conf.setMongoClient(mongoClient);
-
- final Sail sail = GeoRyaSailFactory.getInstance(conf);
- conn = new SailRepository(sail).getConnection();
- conn.begin();
-
- addStatements();
- }
-
- @Test
- public void ensureInEventStore_Test() throws Exception {
- final MongoGeoTemporalIndexer indexer = new MongoGeoTemporalIndexer();
- indexer.initIndexer(conf, mongoClient);
-
- final EventStorage events = indexer.getEventStorage(conf);
- final RyaURI subject = new RyaURI("urn:event1");
- final Optional<Event> event = events.get(subject);
- assertTrue(event.isPresent());
- }
-
- @Test
- public void constantSubjQuery_Test() throws Exception {
- final String query =
- "PREFIX time: <http://www.w3.org/2006/time#> \n"
- + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
- + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
- + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
- + "SELECT * "
- + "WHERE { "
- + " <urn:event1> time:atTime ?time . "
- + " <urn:event1> geo:asWKT ?point . "
- + " FILTER(geof:sfWithin(?point, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
- + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
- + "}";
-
- final TupleQueryResult rez = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate();
- final Set<BindingSet> results = new HashSet<>();
- while(rez.hasNext()) {
- final BindingSet bs = rez.next();
- results.add(bs);
- }
- final MapBindingSet expected = new MapBindingSet();
- expected.addBinding("point", VF.createLiteral("POINT (0 0)"));
- expected.addBinding("time", VF.createLiteral("2015-12-30T12:00:00Z"));
-
- assertEquals(1, results.size());
- assertEquals(expected, results.iterator().next());
- }
-
- @Test
- public void variableSubjQuery_Test() throws Exception {
- final String query =
- "PREFIX time: <http://www.w3.org/2006/time#> \n"
- + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
- + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
- + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
- + "SELECT * "
- + "WHERE { "
- + " ?subj time:atTime ?time . "
- + " ?subj geo:asWKT ?point . "
- + " FILTER(geof:sfWithin(?point, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
- + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
- + "}";
-
- final TupleQueryResult rez = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate();
- final List<BindingSet> results = new ArrayList<>();
- while(rez.hasNext()) {
- final BindingSet bs = rez.next();
- results.add(bs);
- }
- final MapBindingSet expected1 = new MapBindingSet();
- expected1.addBinding("point", VF.createLiteral("POINT (0 0)"));
- expected1.addBinding("time", VF.createLiteral("2015-12-30T12:00:00Z"));
-
- final MapBindingSet expected2 = new MapBindingSet();
- expected2.addBinding("point", VF.createLiteral("POINT (1 1)"));
- expected2.addBinding("time", VF.createLiteral("2015-12-30T12:00:00Z"));
-
- assertEquals(2, results.size());
- assertEquals(expected1, results.get(0));
- assertEquals(expected2, results.get(1));
- }
-
- private void addStatements() throws Exception {
- URI subject = VF.createURI("urn:event1");
- final URI predicate = VF.createURI(URI_PROPERTY_AT_TIME);
- Value object = VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
- conn.add(VF.createStatement(subject, predicate, object));
-
- object = VF.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
- conn.add(VF.createStatement(subject, GeoConstants.GEO_AS_WKT, object));
-
- subject = VF.createURI("urn:event2");
- object = VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
- conn.add(VF.createStatement(subject, predicate, object));
-
- object = VF.createLiteral("Point(1 1)", GeoConstants.XMLSCHEMA_OGC_WKT);
- conn.add(VF.createStatement(subject, GeoConstants.GEO_AS_WKT, object));
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java
deleted file mode 100644
index f35eeb7..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/**
- * 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.geotemporal.model;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.indexing.IndexingExpr;
-import org.apache.rya.indexing.IndexingFunctionRegistry;
-import org.apache.rya.indexing.IndexingFunctionRegistry.FUNCTION_TYPE;
-import org.apache.rya.indexing.TemporalInstant;
-import org.apache.rya.indexing.TemporalInstantRfc3339;
-import org.apache.rya.indexing.geotemporal.mongo.MongoEventStorage;
-import org.apache.rya.indexing.geotemporal.mongo.MongoITBase;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage;
-import org.junit.Test;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.model.ValueFactory;
-import org.openrdf.model.impl.URIImpl;
-import org.openrdf.model.impl.ValueFactoryImpl;
-import org.openrdf.query.BindingSet;
-import org.openrdf.query.QueryEvaluationException;
-import org.openrdf.query.algebra.FunctionCall;
-import org.openrdf.query.algebra.StatementPattern;
-import org.openrdf.query.algebra.ValueConstant;
-import org.openrdf.query.algebra.ValueExpr;
-import org.openrdf.query.algebra.Var;
-import org.openrdf.query.impl.MapBindingSet;
-
-import com.vividsolutions.jts.geom.Coordinate;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.GeometryFactory;
-import com.vividsolutions.jts.geom.PrecisionModel;
-
-import info.aduna.iteration.CloseableIteration;
-
-/**
- * Unit tests the methods of {@link EventQueryNode}.
- */
-public class EventQueryNodeTest extends MongoITBase {
- private static final GeometryFactory GF = new GeometryFactory(new PrecisionModel(), 4326);
- private static final ValueFactory VF = ValueFactoryImpl.getInstance();
-
- @Test(expected = IllegalStateException.class)
- public void constructor_differentSubjects() throws Exception {
- final Var geoSubj = new Var("point");
- final Var geoPred = new Var("-const-http://www.opengis.net/ont/geosparql#asWKT", ValueFactoryImpl.getInstance().createURI("http://www.opengis.net/ont/geosparql#asWKT"));
- final Var geoObj = new Var("wkt");
- final StatementPattern geoSP = new StatementPattern(geoSubj, geoPred, geoObj);
-
- final Var timeSubj = new Var("time");
- final Var timePred = new Var("-const-http://www.w3.org/2006/time#inXSDDateTime", ValueFactoryImpl.getInstance().createURI("-const-http://www.w3.org/2006/time#inXSDDateTime"));
- final Var timeObj = new Var("time");
- final StatementPattern timeSP = new StatementPattern(timeSubj, timePred, timeObj);
- // This will fail.
- new EventQueryNode.EventQueryNodeBuilder()
- .setStorage(mock(EventStorage.class))
- .setGeoPattern(geoSP)
- .setTemporalPattern(timeSP)
- .setGeoFilters(new ArrayList<IndexingExpr>())
- .setTemporalFilters(new ArrayList<IndexingExpr>())
- .setUsedFilters(new ArrayList<>())
- .build();
- }
-
- @Test(expected = IllegalStateException.class)
- public void constructor_variablePredicate() throws Exception {
- // A pattern that has a variable for its predicate.
- final Var geoSubj = new Var("point");
- final Var geoPred = new Var("geo");
- final Var geoObj = new Var("wkt");
- final StatementPattern geoSP = new StatementPattern(geoSubj, geoPred, geoObj);
-
- final Var timeSubj = new Var("time");
- final Var timePred = new Var("-const-http://www.w3.org/2006/time#inXSDDateTime", ValueFactoryImpl.getInstance().createURI("-const-http://www.w3.org/2006/time#inXSDDateTime"));
- final Var timeObj = new Var("time");
- final StatementPattern timeSP = new StatementPattern(timeSubj, timePred, timeObj);
- // This will fail.
- new EventQueryNode.EventQueryNodeBuilder()
- .setStorage(mock(EventStorage.class))
- .setGeoPattern(geoSP)
- .setTemporalPattern(timeSP)
- .setGeoFilters(new ArrayList<IndexingExpr>())
- .setTemporalFilters(new ArrayList<IndexingExpr>())
- .setUsedFilters(new ArrayList<>())
- .build();
- }
-
- @Test
- public void evaluate_constantSubject() throws Exception {
- final EventStorage storage = new MongoEventStorage(super.getMongoClient(), "testDB");
- RyaURI subject = new RyaURI("urn:event-1111");
- final Geometry geo = GF.createPoint(new Coordinate(1, 1));
- final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0);
- final Event event = Event.builder()
- .setSubject(subject)
- .setGeometry(geo)
- .setTemporalInstant(temp)
- .build();
-
- subject = new RyaURI("urn:event-2222");
- final Event otherEvent = Event.builder()
- .setSubject(subject)
- .setGeometry(geo)
- .setTemporalInstant(temp)
- .build();
-
- storage.create(event);
- storage.create(otherEvent);
-
- final String query =
- "PREFIX time: <http://www.w3.org/2006/time#> \n"
- + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
- + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
- + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
- + "SELECT ?event ?time ?point ?wkt "
- + "WHERE { "
- + " <urn:event-1111> time:atTime ?time . "
- + " <urn:event-1111> geo:asWKT ?wkt . "
- + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
- + " FILTER(tempo:equals(?time, \"" + temp.toString() + "\")) "
- + "}";
-
- final EventQueryNode node = buildNode(storage, query);
- final CloseableIteration<BindingSet, QueryEvaluationException> rez = node.evaluate(new MapBindingSet());
- final MapBindingSet expected = new MapBindingSet();
- expected.addBinding("wkt", VF.createLiteral("POINT (1 1)"));
- expected.addBinding("time", VF.createLiteral(temp.toString()));
- int count = 0;
- assertTrue(rez.hasNext());
- while(rez.hasNext()) {
- assertEquals(expected, rez.next());
- count++;
- }
- assertEquals(1, count);
- }
-
- @Test
- public void evaluate_variableSubject() throws Exception {
- final EventStorage storage = new MongoEventStorage(super.getMongoClient(), "testDB");
- RyaURI subject = new RyaURI("urn:event-1111");
- Geometry geo = GF.createPoint(new Coordinate(1, 1));
- final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0);
- final Event event = Event.builder()
- .setSubject(subject)
- .setGeometry(geo)
- .setTemporalInstant(temp)
- .build();
-
- subject = new RyaURI("urn:event-2222");
- geo = GF.createPoint(new Coordinate(-1, -1));
- final Event otherEvent = Event.builder()
- .setSubject(subject)
- .setGeometry(geo)
- .setTemporalInstant(temp)
- .build();
-
- storage.create(event);
- storage.create(otherEvent);
-
- final String query =
- "PREFIX time: <http://www.w3.org/2006/time#> \n"
- + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
- + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
- + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
- + "SELECT ?event ?time ?point ?wkt "
- + "WHERE { "
- + " ?event time:atTime ?time . "
- + " ?event geo:asWKT ?wkt . "
- + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
- + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
- + "}";
-
- final EventQueryNode node = buildNode(storage, query);
- final CloseableIteration<BindingSet, QueryEvaluationException> rez = node.evaluate(new MapBindingSet());
- final MapBindingSet expected1 = new MapBindingSet();
- expected1.addBinding("wkt", VF.createLiteral("POINT (1 1)"));
- expected1.addBinding("time", VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
- final MapBindingSet expected2 = new MapBindingSet();
- expected2.addBinding("wkt", VF.createLiteral("POINT (-1 -1)"));
- expected2.addBinding("time", VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
-
- final List<BindingSet> actual = new ArrayList<>();
- while(rez.hasNext()) {
- actual.add(rez.next());
- }
- assertEquals(expected1, actual.get(0));
- assertEquals(expected2, actual.get(1));
- assertEquals(2, actual.size());
- }
-
- @Test
- public void evaluate_variableSubject_existingBindingset() throws Exception {
- final EventStorage storage = new MongoEventStorage(super.getMongoClient(), "testDB");
- RyaURI subject = new RyaURI("urn:event-1111");
- Geometry geo = GF.createPoint(new Coordinate(1, 1));
- final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0);
- final Event event = Event.builder()
- .setSubject(subject)
- .setGeometry(geo)
- .setTemporalInstant(temp)
- .build();
-
- subject = new RyaURI("urn:event-2222");
- geo = GF.createPoint(new Coordinate(-1, -1));
- final Event otherEvent = Event.builder()
- .setSubject(subject)
- .setGeometry(geo)
- .setTemporalInstant(temp)
- .build();
-
- storage.create(event);
- storage.create(otherEvent);
-
- final String query =
- "PREFIX time: <http://www.w3.org/2006/time#> \n"
- + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
- + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
- + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
- + "SELECT ?event ?time ?point ?wkt "
- + "WHERE { "
- + " ?event time:atTime ?time . "
- + " ?event geo:asWKT ?wkt . "
- + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
- + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
- + "}";
-
- final EventQueryNode node = buildNode(storage, query);
- final MapBindingSet existingBindings = new MapBindingSet();
- existingBindings.addBinding("event", VF.createURI("urn:event-2222"));
- final CloseableIteration<BindingSet, QueryEvaluationException> rez = node.evaluate(existingBindings);
- final MapBindingSet expected = new MapBindingSet();
- expected.addBinding("wkt", VF.createLiteral("POINT (-1 -1)"));
- expected.addBinding("time", VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
-
- final List<BindingSet> actual = new ArrayList<>();
- while(rez.hasNext()) {
- actual.add(rez.next());
- }
- assertEquals(1, actual.size());
- assertEquals(expected, actual.get(0));
- }
-
- @Test
- public void evaluate_variableSubject_existingBindingsetWrongFilters() throws Exception {
- final EventStorage storage = new MongoEventStorage(super.getMongoClient(), "testDB");
- RyaURI subject = new RyaURI("urn:event-1111");
- Geometry geo = GF.createPoint(new Coordinate(1, 1));
- final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0);
- final Event event = Event.builder()
- .setSubject(subject)
- .setGeometry(geo)
- .setTemporalInstant(temp)
- .build();
-
- subject = new RyaURI("urn:event-2222");
- geo = GF.createPoint(new Coordinate(-10, -10));
- final Event otherEvent = Event.builder()
- .setSubject(subject)
- .setGeometry(geo)
- .setTemporalInstant(temp)
- .build();
-
- storage.create(event);
- storage.create(otherEvent);
-
- final String query =
- "PREFIX time: <http://www.w3.org/2006/time#> \n"
- + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
- + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
- + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
- + "SELECT ?event ?time ?point ?wkt "
- + "WHERE { "
- + " ?event time:atTime ?time . "
- + " ?event geo:asWKT ?wkt . "
- + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
- + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
- + "}";
-
- final EventQueryNode node = buildNode(storage, query);
- final MapBindingSet existingBindings = new MapBindingSet();
- existingBindings.addBinding("event", VF.createURI("urn:event-2222"));
- final CloseableIteration<BindingSet, QueryEvaluationException> rez = node.evaluate(existingBindings);
- final MapBindingSet expected = new MapBindingSet();
- expected.addBinding("wkt", VF.createLiteral("POINT (-1 -1)"));
- expected.addBinding("time", VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
-
- assertFalse(rez.hasNext());
- }
-
- private EventQueryNode buildNode(final EventStorage store, final String query) throws Exception {
- final List<IndexingExpr> geoFilters = new ArrayList<>();
- final List<IndexingExpr> temporalFilters = new ArrayList<>();
- final List<StatementPattern> sps = getSps(query);
- final List<FunctionCall> filters = getFilters(query);
- for(final FunctionCall filter : filters) {
- final URI filterURI = new URIImpl(filter.getURI());
- final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, filter.getArgs());
- final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), extractArguments(objVar.getName(), filter));
- if(IndexingFunctionRegistry.getFunctionType(filterURI) == FUNCTION_TYPE.GEO) {
- geoFilters.add(expr);
- } else {
- temporalFilters.add(expr);
- }
- }
-
- final StatementPattern geoPattern = sps.get(1);
- final StatementPattern temporalPattern = sps.get(0);
-
- return new EventQueryNode.EventQueryNodeBuilder()
- .setStorage(store)
- .setGeoPattern(geoPattern)
- .setTemporalPattern(temporalPattern)
- .setGeoFilters(geoFilters)
- .setTemporalFilters(temporalFilters)
- .setUsedFilters(filters)
- .build();
- }
-
- private Value[] extractArguments(final String matchName, final FunctionCall call) {
- final Value args[] = new Value[call.getArgs().size() - 1];
- int argI = 0;
- for (int i = 0; i != call.getArgs().size(); ++i) {
- final ValueExpr arg = call.getArgs().get(i);
- if (argI == i && arg instanceof Var && matchName.equals(((Var)arg).getName())) {
- continue;
- }
- if (arg instanceof ValueConstant) {
- args[argI] = ((ValueConstant)arg).getValue();
- } else if (arg instanceof Var && ((Var)arg).hasValue()) {
- args[argI] = ((Var)arg).getValue();
- } else {
- throw new IllegalArgumentException("Query error: Found " + arg + ", expected a Literal, BNode or URI");
- }
- ++argI;
- }
- return args;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java
deleted file mode 100644
index 3f2f9d5..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * 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.geotemporal.mongo;
-
-import static org.junit.Assert.assertEquals;
-
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.indexing.TemporalInstant;
-import org.apache.rya.indexing.TemporalInstantRfc3339;
-import org.apache.rya.indexing.entity.storage.mongo.DocumentConverter.DocumentConverterException;
-import org.apache.rya.indexing.geotemporal.model.Event;
-import org.apache.rya.indexing.geotemporal.mongo.EventDocumentConverter;
-import org.bson.Document;
-import org.joda.time.DateTime;
-import org.junit.Test;
-
-import com.vividsolutions.jts.geom.Coordinate;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.GeometryFactory;
-import com.vividsolutions.jts.geom.PrecisionModel;
-
-/**
- * Tests the methods of {@link EventDocumentConverter}.
- */
-public class EventDocumentConverterTest {
- private static final GeometryFactory GF = new GeometryFactory(new PrecisionModel(), 4326);
-
- @Test
- public void to_and_from_document() throws DocumentConverterException {
- final Geometry geo = GF.createPoint(new Coordinate(10, 10));
- final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
-
- // An Event that will be stored.
- final Event event = Event.builder()
- .setSubject(new RyaURI("urn:event/001"))
- .setGeometry(geo)
- .setTemporalInstant(instant)
- .build();
-
- final Document document = new EventDocumentConverter().toDocument(event);
-
- // Convert the Document back into an Event.
- final Event converted = new EventDocumentConverter().fromDocument(document);
-
- // Ensure the original matches the round trip converted Event.
- assertEquals(event, converted);
- }
-}
\ No newline at end of file
[04/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexer.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexer.java
deleted file mode 100644
index 34df399..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexer.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/**
- * 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.geotemporal.mongo;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import java.io.IOException;
-import java.util.Optional;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.log4j.Logger;
-import org.apache.rya.api.domain.RyaStatement;
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.api.resolver.RyaToRdfConversions;
-import org.apache.rya.indexing.GeoConstants;
-import org.apache.rya.indexing.TemporalInstant;
-import org.apache.rya.indexing.TemporalInstantRfc3339;
-import org.apache.rya.indexing.TemporalInterval;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.accumulo.geo.GeoParseUtils;
-import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer;
-import org.apache.rya.indexing.geotemporal.model.Event;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage;
-import org.apache.rya.indexing.mongodb.AbstractMongoIndexer;
-import org.apache.rya.indexing.mongodb.IndexingException;
-import org.apache.rya.mongodb.MongoConnectorFactory;
-import org.apache.rya.mongodb.MongoDBRdfConfiguration;
-import org.joda.time.DateTime;
-import org.openrdf.model.Statement;
-import org.openrdf.model.URI;
-
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.io.ParseException;
-
-/**
- * Indexer that stores 2 separate statements as one 'Event' entity.
- * <p>
- * The statements are required to have the same subject, one must be
- * a Geo based statement and the other a temporal based statement.
- * <p>
- * This indexer is later used when querying for geo/temporal statements
- * in the format of:
- * <pre>
- * {@code
- * QUERY PARAMS
- * ?SomeSubject geo:predicate ?Location
- * ?SomeSubject time:predicate ?Time
- * Filter(?Location, geoFunction())
- * Filter(?Time, temporalFunction())
- * }
- *
- * The number of filters is not strict, but there must be at least one
- * query pattern for geo and one for temporal as well as at least one
- * filter for each type.
- */
-public class MongoGeoTemporalIndexer extends AbstractMongoIndexer<GeoTemporalMongoDBStorageStrategy> implements GeoTemporalIndexer {
- private static final Logger LOG = Logger.getLogger(MongoGeoTemporalIndexer.class);
- public static final String GEO_TEMPORAL_COLLECTION = "geo_temporal";
-
- private final AtomicReference<MongoDBRdfConfiguration> configuration = new AtomicReference<>();
- private final AtomicReference<EventStorage> events = new AtomicReference<>();
-
- @Override
- public void init() {
- initCore();
- predicates = ConfigUtils.getGeoPredicates(conf);
- predicates.addAll(ConfigUtils.getTemporalPredicates(conf));
- storageStrategy = new GeoTemporalMongoDBStorageStrategy();
- }
-
- @Override
- public void setConf(final Configuration conf) {
- requireNonNull(conf);
- events.set(null);
- events.set(getEventStorage(conf));
- super.conf = conf;
- configuration.set(new MongoDBRdfConfiguration(conf));
- }
-
- @Override
- public void storeStatement(final RyaStatement ryaStatement) throws IOException {
- requireNonNull(ryaStatement);
-
- try {
- updateEvent(ryaStatement.getSubject(), ryaStatement);
- } catch (IndexingException | ParseException e) {
- throw new IOException("Failed to update the Entity index.", e);
- }
- }
-
- @Override
- public void deleteStatement(final RyaStatement statement) throws IOException {
- requireNonNull(statement);
- final RyaURI subject = statement.getSubject();
- try {
- final EventStorage eventStore = events.get();
- checkState(events != null, "Must set this indexers configuration before storing statements.");
-
- new EventUpdater(eventStore).update(subject, old -> {
- final Event.Builder updated;
- if(!old.isPresent()) {
- return Optional.empty();
- } else {
- updated = Event.builder(old.get());
- }
-
- final Event currentEvent = updated.build();
- final URI pred = statement.getObject().getDataType();
- if((pred.equals(GeoConstants.GEO_AS_WKT) || pred.equals(GeoConstants.GEO_AS_GML) ||
- pred.equals(GeoConstants.XMLSCHEMA_OGC_WKT) || pred.equals(GeoConstants.XMLSCHEMA_OGC_GML))
- && currentEvent.getGeometry().isPresent()) {
- //is geo and needs to be removed.
- try {
- if(currentEvent.getGeometry().get().equals(GeoParseUtils.getGeometry(RyaToRdfConversions.convertStatement(statement)))) {
- updated.setGeometry(null);
- }
- } catch (final Exception e) {
- LOG.debug("Unable to parse the stored geometry.");
- }
- } else {
- //is time
- final String dateTime = statement.getObject().getData();
- final Matcher matcher = TemporalInstantRfc3339.PATTERN.matcher(dateTime);
- if (matcher.find()) {
- final TemporalInterval interval = TemporalInstantRfc3339.parseInterval(dateTime);
- if(currentEvent.getInterval().get().equals(interval)) {
- updated.setTemporalInterval(null);
- }
- } else {
- final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.parse(dateTime));
- if(currentEvent.getInstant().get().equals(instant)) {
- updated.setTemporalInstant(null);
- }
- }
- }
- return Optional.of(updated.build());
- });
- } catch (final IndexingException e) {
- throw new IOException("Failed to update the Entity index.", e);
- }
- }
-
- private void updateEvent(final RyaURI subject, final RyaStatement statement) throws IndexingException, ParseException {
- final EventStorage eventStore = events.get();
- checkState(events != null, "Must set this indexers configuration before storing statements.");
-
- new EventUpdater(eventStore).update(subject, old -> {
- final Event.Builder updated;
- if(!old.isPresent()) {
- updated = Event.builder()
- .setSubject(subject);
- } else {
- updated = Event.builder(old.get());
- }
-
- final URI pred = statement.getObject().getDataType();
- if(pred.equals(GeoConstants.GEO_AS_WKT) || pred.equals(GeoConstants.GEO_AS_GML) ||
- pred.equals(GeoConstants.XMLSCHEMA_OGC_WKT) || pred.equals(GeoConstants.XMLSCHEMA_OGC_GML)) {
- //is geo
- try {
- final Statement geoStatement = RyaToRdfConversions.convertStatement(statement);
- final Geometry geometry = GeoParseUtils.getGeometry(geoStatement);
- updated.setGeometry(geometry);
- } catch (final ParseException e) {
- LOG.error(e.getMessage(), e);
- }
- } else {
- //is time
- final String dateTime = statement.getObject().getData();
- final Matcher matcher = TemporalInstantRfc3339.PATTERN.matcher(dateTime);
- if (matcher.find()) {
- final TemporalInterval interval = TemporalInstantRfc3339.parseInterval(dateTime);
- updated.setTemporalInterval(interval);
- } else {
- final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.parse(dateTime));
- updated.setTemporalInstant(instant);
- }
- }
- return Optional.of(updated.build());
- });
- }
-
- @Override
- public String getCollectionName() {
- return ConfigUtils.getTablePrefix(conf) + GEO_TEMPORAL_COLLECTION;
- }
-
- @Override
- public EventStorage getEventStorage(final Configuration conf) {
- requireNonNull(conf);
-
- if(events.get() != null) {
- return events.get();
- }
-
-
- final MongoDBRdfConfiguration mongoConf = new MongoDBRdfConfiguration(conf);
- mongoClient = mongoConf.getMongoClient();
- configuration.set(mongoConf);
- if (mongoClient == null) {
- mongoClient = MongoConnectorFactory.getMongoClient(conf);
- }
- final String ryaInstanceName = mongoConf.getMongoDBName();
- events.set(new MongoEventStorage(mongoClient, ryaInstanceName));
- return events.get();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/storage/EventStorage.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/storage/EventStorage.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/storage/EventStorage.java
deleted file mode 100644
index 47c18a0..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/storage/EventStorage.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * 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.geotemporal.storage;
-
-import java.util.Collection;
-import java.util.Optional;
-
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.indexing.IndexingExpr;
-import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer;
-import org.apache.rya.indexing.geotemporal.model.Event;
-import org.apache.rya.indexing.mongodb.update.RyaObjectStorage;
-
-public interface EventStorage extends RyaObjectStorage<Event> {
- /**
- * Search for {@link Event}s from the storage by its subject.
- * Will query based on present parameters.
- *
- * @param subject - The subject key to find events.
- * @param geoFilters - The geo filters to find Events.
- * @param temporalFilters - The temporal filters to find Events.
- * @return The {@link Event}, if one exists for the subject.
- * @throws ObjectStorageException A problem occurred while fetching the Entity from the storage.
- */
- public Collection<Event> search(final Optional<RyaURI> subject, Optional<Collection<IndexingExpr>> geoFilters, Optional<Collection<IndexingExpr>> temporalFilters) throws ObjectStorageException;
-
- /**
- * Indicates a problem while interacting with an {@link EventStorage}.
- */
- public static class EventStorageException extends ObjectStorageException {
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructs a new exception with the specified detail message. The
- * cause is not initialized, and may subsequently be initialized by
- * a call to {@link #initCause}.
- *
- * @param message the detail message. The detail message is saved for
- * later retrieval by the {@link #getMessage()} method.
- */
- public EventStorageException(final String message) {
- super(message);
- }
-
- /**
- * Constructs a new exception with the specified detail message and
- * cause. <p>Note that the detail message associated with
- * {@code cause} is <i>not</i> automatically incorporated in
- * this exception's detail message.
- *
- * @param message the detail message (which is saved for later retrieval
- * by the {@link #getMessage()} method).
- * @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method). (A <tt>null</tt> value is
- * permitted, and indicates that the cause is nonexistent or
- * unknown.)
- */
- public EventStorageException(final String message, final Throwable cause) {
- super(message, cause);
- }
- }
-
- /**
- * An {@link Event} could not be created because one already exists for the Subject.
- */
- public static class EventAlreadyExistsException extends EventStorageException {
- private static final long serialVersionUID = 1L;
-
- public EventAlreadyExistsException(final String message) {
- super(message);
- }
-
- public EventAlreadyExistsException(final String message, final Throwable cause) {
- super(message, cause);
- }
- }
-
- /**
- * An {@link TypedEvent} could not be updated because the old state does not
- * match the current state.
- */
- public static class StaleUpdateException extends EventStorageException {
- private static final long serialVersionUID = 1L;
-
- public StaleUpdateException(final String message) {
- super(message);
- }
-
- public StaleUpdateException(final String message, final Throwable cause) {
- super(message, cause);
- }
- }
-
- /**
- * A {@link EventFilter} is a translation from an {@link IndexingExpr}
- * to a format the {@link GeoTemporalIndexer} can use to easily determine which
- * filter function is being used.
- *
- * @param T - The type of
- */
- interface EventFilter<T> {
- /**
- * Gets the translated query friendly form of the filter.
- */
- public T getQueryObject();
- }
-
- /**
- * Factory for getting the {@link EventFilter} from an {@link IndexingExpr}.
- */
- interface EventFilterFactory<T> {
- public EventFilter<T> getSearchFunction(final IndexingExpr filter);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/GeoMongoDBStorageStrategy.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/GeoMongoDBStorageStrategy.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/GeoMongoDBStorageStrategy.java
deleted file mode 100644
index 634359f..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/GeoMongoDBStorageStrategy.java
+++ /dev/null
@@ -1,247 +0,0 @@
-package org.apache.rya.indexing.mongodb.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 java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.apache.rya.api.domain.RyaStatement;
-import org.apache.rya.api.resolver.RyaToRdfConversions;
-import org.apache.rya.indexing.accumulo.geo.GeoParseUtils;
-import org.apache.rya.indexing.mongodb.IndexingMongoDBStorageStrategy;
-import org.bson.Document;
-import org.openrdf.model.Statement;
-import org.openrdf.query.MalformedQueryException;
-
-import com.mongodb.BasicDBObject;
-import com.mongodb.BasicDBObjectBuilder;
-import com.mongodb.DBCollection;
-import com.mongodb.DBObject;
-import com.vividsolutions.jts.geom.Coordinate;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.Point;
-import com.vividsolutions.jts.geom.Polygon;
-import com.vividsolutions.jts.io.ParseException;
-import com.vividsolutions.jts.io.WKTReader;
-
-public class GeoMongoDBStorageStrategy extends IndexingMongoDBStorageStrategy {
- private static final Logger LOG = Logger.getLogger(GeoMongoDBStorageStrategy.class);
-
- private static final String GEO = "location";
- public enum GeoQueryType {
- INTERSECTS {
- @Override
- public String getKeyword() {
- return "$geoIntersects";
- }
- }, WITHIN {
- @Override
- public String getKeyword() {
- return "$geoWithin";
- }
- }, EQUALS {
- @Override
- public String getKeyword() {
- return "$near";
- }
- }, NEAR {
- @Override
- public String getKeyword() {
- return "$near";
- }
- };
-
- public abstract String getKeyword();
- }
-
- public static class GeoQuery {
- private final GeoQueryType queryType;
- private final Geometry geo;
-
- private final Double maxDistance;
- private final Double minDistance;
-
- public GeoQuery(final GeoQueryType queryType, final Geometry geo) {
- this(queryType, geo, 0, 0);
- }
-
- public GeoQuery(final GeoQueryType queryType, final Geometry geo, final double maxDistance,
- final double minDistance) {
- this.queryType = queryType;
- this.geo = geo;
- this.maxDistance = maxDistance;
- this.minDistance = minDistance;
- }
-
- public GeoQueryType getQueryType() {
- return queryType;
- }
-
- public Geometry getGeo() {
- return geo;
- }
-
- public Double getMaxDistance() {
- return maxDistance;
- }
-
- public Double getMinDistance() {
- return minDistance;
- }
- }
-
- private final Double maxDistance;
-
- public GeoMongoDBStorageStrategy(final Double maxDistance) {
- this.maxDistance = maxDistance;
- }
-
- @Override
- public void createIndices(final DBCollection coll){
- coll.createIndex(new BasicDBObject(GEO, "2dsphere"));
- }
-
- public DBObject getQuery(final GeoQuery queryObj) throws MalformedQueryException {
- final Geometry geo = queryObj.getGeo();
- final GeoQueryType queryType = queryObj.getQueryType();
- if (queryType == GeoQueryType.WITHIN && !(geo instanceof Polygon)) {
- //They can also be applied to MultiPolygons, but those are not supported either.
- throw new MalformedQueryException("Mongo Within operations can only be performed on Polygons.");
- } else if(queryType == GeoQueryType.NEAR && !(geo instanceof Point)) {
- //They can also be applied to Point, but those are not supported either.
- throw new MalformedQueryException("Mongo near operations can only be performed on Points.");
- }
-
- BasicDBObject query;
- if (queryType.equals(GeoQueryType.EQUALS)){
- if(geo.getNumPoints() == 1) {
- final List circle = new ArrayList();
- circle.add(getPoint(geo));
- circle.add(maxDistance);
- final BasicDBObject polygon = new BasicDBObject("$centerSphere", circle);
- query = new BasicDBObject(GEO, new BasicDBObject(GeoQueryType.WITHIN.getKeyword(), polygon));
- } else {
- query = new BasicDBObject(GEO, getCorrespondingPoints(geo));
- }
- } else if(queryType.equals(GeoQueryType.NEAR)) {
- final BasicDBObject geoDoc = new BasicDBObject("$geometry", getDBPoint(geo));
- if(queryObj.getMaxDistance() != 0) {
- geoDoc.append("$maxDistance", queryObj.getMaxDistance());
- }
-
- if(queryObj.getMinDistance() != 0) {
- geoDoc.append("$minDistance", queryObj.getMinDistance());
- }
- query = new BasicDBObject(GEO, new BasicDBObject(queryType.getKeyword(), geoDoc));
- } else {
- final BasicDBObject geoDoc = new BasicDBObject("$geometry", getCorrespondingPoints(geo));
- query = new BasicDBObject(GEO, new BasicDBObject(queryType.getKeyword(), geoDoc));
- }
-
- return query;
- }
-
- @Override
- public DBObject serialize(final RyaStatement ryaStatement) {
- // if the object is wkt, then try to index it
- // write the statement data to the fields
- try {
- final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
- final Geometry geo = (new WKTReader()).read(GeoParseUtils.getWellKnownText(statement));
- if(geo == null) {
- LOG.error("Failed to parse geo statement: " + statement.toString());
- return null;
- }
- final BasicDBObject base = (BasicDBObject) super.serialize(ryaStatement);
- if (geo.getNumPoints() > 1) {
- base.append(GEO, getCorrespondingPoints(geo));
- } else {
- base.append(GEO, getDBPoint(geo));
- }
- return base;
- } catch(final ParseException e) {
- LOG.error("Could not create geometry for statement " + ryaStatement, e);
- return null;
- }
- }
-
- public Document getCorrespondingPoints(final Geometry geo) {
- //Polygons must be a 3 dimensional array.
-
- //polygons must be a closed loop
- final Document geoDoc = new Document();
- if (geo instanceof Polygon) {
- final Polygon poly = (Polygon) geo;
- final List<List<List<Double>>> DBpoints = new ArrayList<>();
-
- // outer shell of the polygon
- final List<List<Double>> ring = new ArrayList<>();
- for (final Coordinate coord : poly.getExteriorRing().getCoordinates()) {
- ring.add(getPoint(coord));
- }
- DBpoints.add(ring);
-
- // each hold in the polygon
- for (int ii = 0; ii < poly.getNumInteriorRing(); ii++) {
- final List<List<Double>> holeCoords = new ArrayList<>();
- for (final Coordinate coord : poly.getInteriorRingN(ii).getCoordinates()) {
- holeCoords.add(getPoint(coord));
- }
- DBpoints.add(holeCoords);
- }
- geoDoc.append("coordinates", DBpoints)
- .append("type", "Polygon");
- } else {
- final List<List<Double>> points = getPoints(geo);
- geoDoc.append("coordinates", points)
- .append("type", "LineString");
- }
- return geoDoc;
- }
-
- private List<List<Double>> getPoints(final Geometry geo) {
- final List<List<Double>> points = new ArrayList<>();
- for (final Coordinate coord : geo.getCoordinates()) {
- points.add(getPoint(coord));
- }
- return points;
- }
-
- public Document getDBPoint(final Geometry geo) {
- return new Document()
- .append("coordinates", getPoint(geo))
- .append("type", "Point");
- }
-
- private List<Double> getPoint(final Coordinate coord) {
- final List<Double> point = new ArrayList<>();
- point.add(coord.x);
- point.add(coord.y);
- return point;
- }
-
- private List<Double> getPoint(final Geometry geo) {
- final List<Double> point = new ArrayList<>();
- point.add(geo.getCoordinate().x);
- point.add(geo.getCoordinate().y);
- return point;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoIndexer.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoIndexer.java
deleted file mode 100644
index 2abee76..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoIndexer.java
+++ /dev/null
@@ -1,154 +0,0 @@
-package org.apache.rya.indexing.mongodb.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 org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.EQUALS;
-import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.INTERSECTS;
-import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.NEAR;
-import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.WITHIN;
-
-import org.apache.log4j.Logger;
-import org.apache.rya.indexing.GeoIndexer;
-import org.apache.rya.indexing.StatementConstraints;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.accumulo.geo.GeoTupleSet.GeoSearchFunctionFactory.NearQuery;
-import org.apache.rya.indexing.mongodb.AbstractMongoIndexer;
-import org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQuery;
-import org.apache.rya.mongodb.MongoDBRdfConfiguration;
-import org.openrdf.model.Statement;
-import org.openrdf.query.MalformedQueryException;
-import org.openrdf.query.QueryEvaluationException;
-
-import com.mongodb.DBObject;
-import com.vividsolutions.jts.geom.Geometry;
-
-import info.aduna.iteration.CloseableIteration;
-
-public class MongoGeoIndexer extends AbstractMongoIndexer<GeoMongoDBStorageStrategy> implements GeoIndexer {
- private static final String COLLECTION_SUFFIX = "geo";
- private static final Logger logger = Logger.getLogger(MongoGeoIndexer.class);
-
- @Override
- public void init() {
- initCore();
- predicates = ConfigUtils.getGeoPredicates(conf);
- if(predicates.size() == 0) {
- logger.debug("No predicates specified for geo indexing. During insertion, all statements will be attempted to be indexed into the geo indexer.");
- }
- storageStrategy = new GeoMongoDBStorageStrategy(Double.valueOf(conf.get(MongoDBRdfConfiguration.MONGO_GEO_MAXDISTANCE, "1e-10")));
- storageStrategy.createIndices(collection);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryEquals(
- final Geometry query, final StatementConstraints constraints) {
- try {
- final DBObject queryObj = storageStrategy.getQuery(new GeoQuery(EQUALS, query));
- return withConstraints(constraints, queryObj);
- } catch (final MalformedQueryException e) {
- logger.error(e.getMessage(), e);
- return null;
- }
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryDisjoint(
- final Geometry query, final StatementConstraints constraints) {
- throw new UnsupportedOperationException(
- "Disjoint queries are not supported in Mongo DB.");
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryIntersects(
- final Geometry query, final StatementConstraints constraints) {
- try {
- final DBObject queryObj = storageStrategy.getQuery(new GeoQuery(INTERSECTS, query));
- return withConstraints(constraints, queryObj);
- } catch (final MalformedQueryException e) {
- logger.error(e.getMessage(), e);
- return null;
- }
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryTouches(
- final Geometry query, final StatementConstraints constraints) {
- throw new UnsupportedOperationException(
- "Touches queries are not supported in Mongo DB.");
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryCrosses(
- final Geometry query, final StatementConstraints constraints) {
- throw new UnsupportedOperationException(
- "Crosses queries are not supported in Mongo DB.");
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryWithin(
- final Geometry query, final StatementConstraints constraints) {
- try {
- final DBObject queryObj = storageStrategy.getQuery(new GeoQuery(WITHIN, query));
- return withConstraints(constraints, queryObj);
- } catch (final MalformedQueryException e) {
- logger.error(e.getMessage(), e);
- return null;
- }
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryNear(final NearQuery query, final StatementConstraints constraints) {
- double maxDistance = 0;
- double minDistance = 0;
- if (query.getMaxDistance().isPresent()) {
- maxDistance = query.getMaxDistance().get();
- }
-
- if (query.getMinDistance().isPresent()) {
- minDistance = query.getMinDistance().get();
- }
-
- try {
- final DBObject queryObj = storageStrategy.getQuery(new GeoQuery(NEAR, query.getGeometry(), maxDistance, minDistance));
- return withConstraints(constraints, queryObj);
- } catch (final MalformedQueryException e) {
- logger.error(e.getMessage(), e);
- return null;
- }
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryContains(
- final Geometry query, final StatementConstraints constraints) {
- throw new UnsupportedOperationException(
- "Contains queries are not supported in Mongo DB.");
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryOverlaps(
- final Geometry query, final StatementConstraints constraints) {
- throw new UnsupportedOperationException(
- "Overlaps queries are not supported in Mongo DB.");
- }
-
- @Override
- public String getCollectionName() {
- return ConfigUtils.getTablePrefix(conf) + COLLECTION_SUFFIX;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoTupleSet.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoTupleSet.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoTupleSet.java
deleted file mode 100644
index c564d02..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoTupleSet.java
+++ /dev/null
@@ -1,361 +0,0 @@
-package org.apache.rya.indexing.mongodb.geo;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.hadoop.conf.Configuration;
-import org.openrdf.model.Statement;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.query.BindingSet;
-import org.openrdf.query.QueryEvaluationException;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.Maps;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.io.ParseException;
-import com.vividsolutions.jts.io.WKTReader;
-
-/*
- * 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 info.aduna.iteration.CloseableIteration;
-import org.apache.rya.indexing.GeoConstants;
-import org.apache.rya.indexing.GeoIndexer;
-import org.apache.rya.indexing.IndexingExpr;
-import org.apache.rya.indexing.IteratorFactory;
-import org.apache.rya.indexing.SearchFunction;
-import org.apache.rya.indexing.StatementConstraints;
-import org.apache.rya.indexing.accumulo.geo.GeoTupleSet;
-import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
-
-public class MongoGeoTupleSet extends ExternalTupleSet {
-
- private Configuration conf;
- private GeoIndexer geoIndexer;
- private IndexingExpr filterInfo;
-
-
- public MongoGeoTupleSet(IndexingExpr filterInfo, GeoIndexer geoIndexer) {
- this.filterInfo = filterInfo;
- this.geoIndexer = geoIndexer;
- this.conf = geoIndexer.getConf();
- }
-
- @Override
- public Set<String> getBindingNames() {
- return filterInfo.getBindingNames();
- }
-
- public GeoTupleSet clone() {
- return new GeoTupleSet(filterInfo, geoIndexer);
- }
-
- @Override
- public double cardinality() {
- return 0.0; // No idea how the estimate cardinality here.
- }
-
-
- @Override
- public String getSignature() {
- return "(GeoTuple Projection) " + "variables: " + Joiner.on(", ").join(this.getBindingNames()).replaceAll("\\s+", " ");
- }
-
-
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
- if (!(other instanceof MongoGeoTupleSet)) {
- return false;
- }
- MongoGeoTupleSet arg = (MongoGeoTupleSet) other;
- return this.filterInfo.equals(arg.filterInfo);
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31*result + filterInfo.hashCode();
-
- return result;
- }
-
-
-
- /**
- * Returns an iterator over the result set of the contained IndexingExpr.
- * <p>
- * Should be thread-safe (concurrent invocation {@link OfflineIterable} this
- * method can be expected with some query evaluators.
- */
- @Override
- public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(BindingSet bindings)
- throws QueryEvaluationException {
-
-
- URI funcURI = filterInfo.getFunction();
- SearchFunction searchFunction = (new MongoGeoSearchFunctionFactory(conf)).getSearchFunction(funcURI);
- if(filterInfo.getArguments().length > 1) {
- throw new IllegalArgumentException("Index functions do not support more than two arguments.");
- }
-
- String queryText = ((Value) filterInfo.getArguments()[0]).stringValue();
-
- return IteratorFactory.getIterator(filterInfo.getSpConstraint(), bindings, queryText, searchFunction);
- }
-
-
-
- //returns appropriate search function for a given URI
- //search functions used in GeoMesaGeoIndexer to access index
- public class MongoGeoSearchFunctionFactory {
-
- Configuration conf;
-
- private final Map<URI, SearchFunction> SEARCH_FUNCTION_MAP = Maps.newHashMap();
-
- public MongoGeoSearchFunctionFactory(Configuration conf) {
- this.conf = conf;
- }
-
-
- /**
- * Get a {@link GeoSearchFunction} for a given URI.
- *
- * @param searchFunction
- * @return
- */
- public SearchFunction getSearchFunction(final URI searchFunction) {
-
- SearchFunction geoFunc = null;
-
- try {
- geoFunc = getSearchFunctionInternal(searchFunction);
- } catch (QueryEvaluationException e) {
- e.printStackTrace();
- }
-
- return geoFunc;
- }
-
- private SearchFunction getSearchFunctionInternal(final URI searchFunction) throws QueryEvaluationException {
- SearchFunction sf = SEARCH_FUNCTION_MAP.get(searchFunction);
-
- if (sf != null) {
- return sf;
- } else {
- throw new QueryEvaluationException("Unknown Search Function: " + searchFunction.stringValue());
- }
- }
-
- private final SearchFunction GEO_EQUALS = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
- StatementConstraints contraints) throws QueryEvaluationException {
- try {
- WKTReader reader = new WKTReader();
- Geometry geometry = reader.read(queryText);
- CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
- geometry, contraints);
- return statements;
- } catch (ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_EQUALS";
- };
- };
-
- private final SearchFunction GEO_DISJOINT = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
- StatementConstraints contraints) throws QueryEvaluationException {
- try {
- WKTReader reader = new WKTReader();
- Geometry geometry = reader.read(queryText);
- CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
- geometry, contraints);
- return statements;
- } catch (ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_DISJOINT";
- };
- };
-
- private final SearchFunction GEO_INTERSECTS = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
- StatementConstraints contraints) throws QueryEvaluationException {
- try {
- WKTReader reader = new WKTReader();
- Geometry geometry = reader.read(queryText);
- CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
- geometry, contraints);
- return statements;
- } catch (ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_INTERSECTS";
- };
- };
-
- private final SearchFunction GEO_TOUCHES = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
- StatementConstraints contraints) throws QueryEvaluationException {
- try {
- WKTReader reader = new WKTReader();
- Geometry geometry = reader.read(queryText);
- CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
- geometry, contraints);
- return statements;
- } catch (ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_TOUCHES";
- };
- };
-
- private final SearchFunction GEO_CONTAINS = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
- StatementConstraints contraints) throws QueryEvaluationException {
- try {
- WKTReader reader = new WKTReader();
- Geometry geometry = reader.read(queryText);
- CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
- geometry, contraints);
- return statements;
- } catch (ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_CONTAINS";
- };
- };
-
- private final SearchFunction GEO_OVERLAPS = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
- StatementConstraints contraints) throws QueryEvaluationException {
- try {
- WKTReader reader = new WKTReader();
- Geometry geometry = reader.read(queryText);
- CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
- geometry, contraints);
- return statements;
- } catch (ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_OVERLAPS";
- };
- };
-
- private final SearchFunction GEO_CROSSES = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
- StatementConstraints contraints) throws QueryEvaluationException {
- try {
- WKTReader reader = new WKTReader();
- Geometry geometry = reader.read(queryText);
- CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
- geometry, contraints);
- return statements;
- } catch (ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_CROSSES";
- };
- };
-
- private final SearchFunction GEO_WITHIN = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
- StatementConstraints contraints) throws QueryEvaluationException {
- try {
- WKTReader reader = new WKTReader();
- Geometry geometry = reader.read(queryText);
- CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
- geometry, contraints);
- return statements;
- } catch (ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_WITHIN";
- };
- };
-
- {
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_EQUALS, GEO_EQUALS);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_DISJOINT, GEO_DISJOINT);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_INTERSECTS, GEO_INTERSECTS);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_TOUCHES, GEO_TOUCHES);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_CONTAINS, GEO_CONTAINS);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_OVERLAPS, GEO_OVERLAPS);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_CROSSES, GEO_CROSSES);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_WITHIN, GEO_WITHIN);
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/GeoIndexingTestUtils.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/GeoIndexingTestUtils.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/GeoIndexingTestUtils.java
deleted file mode 100644
index b0c636d..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/GeoIndexingTestUtils.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import info.aduna.iteration.CloseableIteration;
-
-/**
- * Utility methods to help test geo indexing methods.
- */
-public final class GeoIndexingTestUtils {
- /**
- * Private constructor to prevent instantiation.
- */
- private GeoIndexingTestUtils () {
- }
-
- /**
- * Generates a set of items from the specified iterator.
- * @param iter a {@link CloseableIteration}.
- * @return the {@link Set} of items from the iterator or an empty set if
- * none were found.
- * @throws Exception
- */
- public static <X> Set<X> getSet(final CloseableIteration<X, ?> iter) throws Exception {
- final Set<X> set = new HashSet<X>();
- while (iter.hasNext()) {
- final X item = iter.next();
- set.add(item);
- }
- return set;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerSfTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerSfTest.java b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerSfTest.java
deleted file mode 100644
index e61ef35..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerSfTest.java
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * 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.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.admin.TableOperations;
-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.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-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.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;
-
-/**
- * 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 GeoIndexerSfTest {
- private static AccumuloRdfConfiguration conf;
- private static GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
- private static GeoMesaGeoIndexer 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();
-
- /**
- * 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_ROUGH_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 GeoIndexerSfTest(final URI schemaToTest, final URI encodeMethod) {
- this.schemaToTest = schemaToTest;
- this.encodeMethod = encodeMethod;
- }
-
- /**
- * Run before each test method.
- * @throws Exception
- */
- @Before
- public void before() throws Exception {
- conf = new AccumuloRdfConfiguration();
- conf.setTablePrefix("triplestore_");
- 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());
-
- 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 GeoMesaGeoIndexer();
- g.setConf(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
- @Ignore
- public void testIntersectsPoint() throws Exception {
- // This seems like a bug
- // scala.MatchError: POINT (2 4) (of class com.vividsolutions.jts.geom.Point)
- // at org.locationtech.geomesa.filter.FilterHelper$.updateToIDLSafeFilter(FilterHelper.scala:53)
- // compare(g.queryIntersects(F, EMPTY_CONSTRAINTS), A, F);
- // compare(g.queryIntersects(F, EMPTY_CONSTRAINTS), EMPTY_RESULTS);
- }
-
- @Ignore
- @Test
- public void testIntersectsLine() throws Exception {
- // This seems like a bug
- // fails with:
- // scala.MatchError: LINESTRING (2 0, 3 3) (of class com.vividsolutions.jts.geom.LineString)
- // at org.locationtech.geomesa.filter.FilterHelper$.updateToIDLSafeFilter(FilterHelper.scala:53)
- //compare(g.queryIntersects(E, EMPTY_CONSTRAINTS), A, E, D);
- //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, 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);
- // bug? java.lang.IllegalStateException: getX called on empty Point
- // compare(g.queryCrosses(point(2, 0), EMPTY_CONSTRAINTS), E);
- }
-
- @Ignore
- @Test
- public void testCrossesLine() throws Exception {
- // fails with:
- // java.lang.IllegalStateException: getX called on empty Point
- // at com.vividsolutions.jts.geom.Point.getX(Point.java:124)
- // at org.locationtech.geomesa.utils.geohash.GeohashUtils$.considerCandidate$1(GeohashUtils.scala:1023)
-
- // 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
- // geomesa bug? scala.MatchError: POINT (2 4) (of class com.vividsolutions.jts.geom.Point)
- // compare(g.queryWithin(F, EMPTY_CONSTRAINTS), F);
-
- // line
- // geomesa bug? scala.MatchError: LINESTRING (2 0, 3 2) (of class com.vividsolutions.jts.geom.LineString)
- // 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);
- }
-
- @Ignore
- @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);
- }
-
- @Ignore
- @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);
- }
-
- @Ignore
- @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);
- }
-
-}
[10/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerSfTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerSfTest.java b/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerSfTest.java
new file mode 100644
index 0000000..0cf2544
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerSfTest.java
@@ -0,0 +1,536 @@
+/*
+ * 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.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), new GmlParser());
+ 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);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerTest.java b/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerTest.java
new file mode 100644
index 0000000..1930a50
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerTest.java
@@ -0,0 +1,447 @@
+/*
+ * 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.api.resolver.RdfToRyaConversions.convertStatement;
+import static org.apache.rya.indexing.GeoIndexingTestUtils.getSet;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+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.indexing.GeoConstants;
+import org.apache.rya.indexing.GeoIndexerType;
+import org.apache.rya.indexing.StatementConstraints;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+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.google.common.io.Files;
+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 mil.nga.giat.geowave.datastore.accumulo.minicluster.MiniAccumuloClusterFactory;
+
+/**
+ * Tests higher level functioning of the geoindexer parse WKT, predicate list,
+ * prime and anti meridian, delete, search, context, search with Statement Constraints.
+ */
+public class GeoWaveIndexerTest {
+
+ private static final StatementConstraints EMPTY_CONSTRAINTS = new StatementConstraints();
+
+ private AccumuloRdfConfiguration conf;
+ private final GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
+
+ 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";
+
+ @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);
+ }
+ }
+ }
+
+ @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);
+ }
+ }
+
+ @Test
+ public void testRestrictPredicatesSearch() throws Exception {
+ conf.setStrings(ConfigUtils.GEO_PREDICATES_LIST, "pred:1,pred:2");
+ try (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
+ f.setConf(conf);
+ f.purge(conf);
+
+ 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));
+ }
+ }
+
+ @Test
+ public void testPrimeMeridianSearch() throws Exception {
+ try (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
+ f.setConf(conf);
+ f.purge(conf);
+
+ 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
+ f.setConf(conf);
+ f.purge(conf);
+
+ 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
+ f.setConf(conf);
+ f.purge(conf);
+
+ 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
+ final double[] world = { -180, 90, 180, 90, 180, -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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
+ f.setConf(conf);
+ f.purge(conf);
+
+ 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
+ f.setConf(conf);
+ f.purge(conf);
+
+ 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
+ f.setConf(conf);
+ f.purge(conf);
+
+ 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
+ f.setConf(conf);
+ f.purge(conf);
+
+ 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 (final GeoWaveGeoIndexer f = new GeoWaveGeoIndexer()) {
+ f.setConf(conf);
+ f.purge(conf);
+
+ 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/9e76b8d7/extras/rya.geoindexing/geo.mongo/pom.xml
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/pom.xml b/extras/rya.geoindexing/geo.mongo/pom.xml
new file mode 100644
index 0000000..f8c4f49
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/pom.xml
@@ -0,0 +1,41 @@
+<?xml version='1.0'?>
+
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.rya</groupId>
+ <artifactId>rya.geoindexing</artifactId>
+ <version>3.2.11-incubating-SNAPSHOT</version>
+ </parent>
+ <artifactId>geo.mongo</artifactId>
+ <name>Apache Rya Geo Indexing using MongoDB</name>
+ <description>Implementation of a geospatial indexing for mongo DB backed Rya</description>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <geotools.version>16.0</geotools.version>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.rya</groupId>
+ <artifactId>geo.common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.geotools.xsd</groupId>
+ <artifactId>gt-xsd-gml3</artifactId>
+ <version>${geotools.version}</version>
+ </dependency>
+
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geoExamples/RyaMongoGeoDirectExample.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geoExamples/RyaMongoGeoDirectExample.java b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geoExamples/RyaMongoGeoDirectExample.java
new file mode 100644
index 0000000..e42ce07
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geoExamples/RyaMongoGeoDirectExample.java
@@ -0,0 +1,238 @@
+package org.apache.rya.indexing.geoExamples;
+/*
+ * 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.io.IOException;
+import java.util.List;
+
+import org.apache.commons.lang.Validate;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.rya.indexing.GeoRyaSailFactory;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.accumulo.geo.OptionalConfigUtils;
+import org.apache.rya.indexing.mongodb.MongoIndexingConfiguration;
+import org.apache.rya.indexing.mongodb.MongoIndexingConfiguration.MongoDBIndexingConfigBuilder;
+import org.apache.rya.mongodb.MockMongoFactory;
+import org.apache.rya.mongodb.MongoConnectorFactory;
+import org.openrdf.model.vocabulary.RDFS;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.QueryEvaluationException;
+import org.openrdf.query.QueryLanguage;
+import org.openrdf.query.QueryResultHandlerException;
+import org.openrdf.query.TupleQuery;
+import org.openrdf.query.TupleQueryResultHandler;
+import org.openrdf.query.TupleQueryResultHandlerException;
+import org.openrdf.query.Update;
+import org.openrdf.query.UpdateExecutionException;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.repository.sail.SailRepositoryConnection;
+import org.openrdf.sail.Sail;
+
+import com.mongodb.MongoClient;
+import com.mongodb.ServerAddress;
+
+public class RyaMongoGeoDirectExample {
+ private static final Logger log = Logger.getLogger(RyaMongoGeoDirectExample.class);
+
+ //
+ // Connection configuration parameters
+ //
+
+ private static final boolean PRINT_QUERIES = true;
+ private static final String MONGO_DB = "rya";
+ private static final String MONGO_COLL_PREFIX = "rya_";
+ private static final boolean USE_MOCK = true;
+ private static final boolean USE_INFER = true;
+ private static final String MONGO_INSTANCE_URL = "localhost";
+ private static final String MONGO_INSTANCE_PORT = "27017";
+
+ public static void main(String[] args) throws Exception {
+ Configuration conf = getConf();
+ conf.setBoolean(ConfigUtils.DISPLAY_QUERY_PLAN, PRINT_QUERIES);
+ conf.setBoolean(OptionalConfigUtils.USE_GEO, true); // Note also the use of "GeoRyaSailFactory" below.
+ conf.setStrings(OptionalConfigUtils.GEO_PREDICATES_LIST, "http://www.opengis.net/ont/geosparql#asWKT"); // Note also the use of "GeoRyaSailFactory" below.
+
+ SailRepository repository = null;
+ SailRepositoryConnection conn = null;
+ try {
+ log.info("Connecting to Indexing Sail Repository.");
+ Sail sail = GeoRyaSailFactory.getInstance(conf);
+ repository = new SailRepository(sail);
+ conn = repository.getConnection();
+
+ long start = System.currentTimeMillis();
+ testAddPointAndWithinSearch(conn); // uses geospatial features
+
+ log.info("TIME: " + (System.currentTimeMillis() - start) / 1000.);
+ } finally {
+ log.info("Shutting down");
+ closeQuietly(conn);
+ closeQuietly(repository);
+ if (mock != null) {
+ mock.shutdown();
+ }
+ MongoConnectorFactory.closeMongoClient();
+ }
+ }
+/**
+ * Try out some geospatial data and queries
+ * @param repository
+ */
+ private static void testAddPointAndWithinSearch(SailRepositoryConnection conn) throws Exception {
+
+ String update = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "INSERT DATA { " //
+ + " <urn:feature> a geo:Feature ; " //
+ + " geo:hasGeometry [ " //
+ + " a geo:Point ; " //
+ + " geo:asWKT \"Point(-77.03524 38.889468)\"^^geo:wktLiteral "//
+ + " ] . " //
+ + "}";
+
+ Update u = conn.prepareUpdate(QueryLanguage.SPARQL, update);
+ u.execute();
+
+ String queryString;
+ TupleQuery tupleQuery;
+ CountingResultHandler tupleHandler;
+
+ // ring containing point
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt " //
+ + "{" //
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-78 39, -77 39, -77 38, -78 38, -78 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("Result count -- ring containing point: " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() >= 1); // may see points from during previous runs
+
+ // ring outside point
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt " //
+ + "{" //
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-77 39, -76 39, -76 38, -77 38, -77 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("Result count -- ring outside point: " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 0);
+ }
+
+ private static void closeQuietly(SailRepository repository) {
+ if (repository != null) {
+ try {
+ repository.shutDown();
+ } catch (RepositoryException e) {
+ // quietly absorb this exception
+ }
+ }
+ }
+
+ private static void closeQuietly(SailRepositoryConnection conn) {
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (RepositoryException e) {
+ // quietly absorb this exception
+ }
+ }
+ }
+
+ private static MockMongoFactory mock = null;
+ private static Configuration getConf() throws IOException {
+
+ MongoDBIndexingConfigBuilder builder = MongoIndexingConfiguration.builder()
+ .setUseMockMongo(USE_MOCK).setUseInference(USE_INFER).setAuths("U");
+
+ if (USE_MOCK) {
+ mock = MockMongoFactory.newFactory();
+ MongoClient c = mock.newMongoClient();
+ ServerAddress address = c.getAddress();
+ String url = address.getHost();
+ String port = Integer.toString(address.getPort());
+ c.close();
+ builder.setMongoHost(url).setMongoPort(port);
+ } else {
+ // User name and password must be filled in:
+ builder = builder.setMongoUser("fill this in")
+ .setMongoPassword("fill this in")
+ .setMongoHost(MONGO_INSTANCE_URL)
+ .setMongoPort(MONGO_INSTANCE_PORT);
+ }
+
+ return builder.setMongoDBName(MONGO_DB)
+ .setMongoCollectionPrefix(MONGO_COLL_PREFIX)
+ .setUseMongoFreetextIndex(true)
+ .setMongoFreeTextPredicates(RDFS.LABEL.stringValue()).build();
+
+ }
+
+
+ private static class CountingResultHandler implements TupleQueryResultHandler {
+ private int count = 0;
+
+ public int getCount() {
+ return count;
+ }
+
+ @Override
+ public void startQueryResult(List<String> arg0) throws TupleQueryResultHandlerException {
+ }
+
+ @Override
+ public void handleSolution(BindingSet arg0) throws TupleQueryResultHandlerException {
+ count++;
+ System.out.println(arg0);
+ }
+
+ @Override
+ public void endQueryResult() throws TupleQueryResultHandlerException {
+ }
+
+ @Override
+ public void handleBoolean(boolean arg0) throws QueryResultHandlerException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void handleLinks(List<String> arg0) throws QueryResultHandlerException {
+ // TODO Auto-generated method stub
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverter.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverter.java b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverter.java
new file mode 100644
index 0000000..926f357
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverter.java
@@ -0,0 +1,171 @@
+/**
+ * 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.geotemporal.mongo;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Date;
+import java.util.List;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.TemporalInterval;
+import org.apache.rya.indexing.entity.storage.mongo.DocumentConverter;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy;
+import org.bson.Document;
+import org.joda.time.DateTime;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateList;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LinearRing;
+
+public class EventDocumentConverter implements DocumentConverter<Event>{
+ public static final String SUBJECT = "_id";
+ public static final String GEO_KEY = "location";
+ public static final String INTERVAL_START = "start";
+ public static final String INTERVAL_END = "end";
+ public static final String INSTANT = "instant";
+
+ private final GeoMongoDBStorageStrategy geoAdapter = new GeoMongoDBStorageStrategy(0.0);
+
+ @Override
+ public Document toDocument(final Event event) {
+ requireNonNull(event);
+
+ final Document doc = new Document();
+ doc.append(SUBJECT, event.getSubject().getData());
+
+ if(event.getGeometry().isPresent()) {
+ if (event.getGeometry().get().getNumPoints() > 1) {
+ doc.append(GEO_KEY, geoAdapter.getCorrespondingPoints(event.getGeometry().get()));
+ } else {
+ doc.append(GEO_KEY, geoAdapter.getDBPoint(event.getGeometry().get()));
+ }
+ }
+ if(event.isInstant()) {
+ if(event.getInstant().isPresent()) {
+ doc.append(INSTANT, event.getInstant().get().getAsDateTime().toDate());
+ }
+ } else {
+ if(event.getInterval().isPresent()) {
+ doc.append(INTERVAL_START, event.getInterval().get().getHasBeginning().getAsDateTime().toDate());
+ doc.append(INTERVAL_END, event.getInterval().get().getHasEnd().getAsDateTime().toDate());
+ }
+ }
+
+ return doc;
+ }
+
+ @Override
+ public Event fromDocument(final Document document) throws DocumentConverterException {
+ requireNonNull(document);
+
+ final boolean isInstant;
+
+ // Preconditions.
+ if(!document.containsKey(SUBJECT)) {
+ throw new DocumentConverterException("Could not convert document '" + document +
+ "' because its '" + SUBJECT + "' field is missing.");
+ }
+
+ if(document.containsKey(INSTANT)) {
+ isInstant = true;
+ } else {
+ isInstant = false;
+ }
+
+ final String subject = document.getString(SUBJECT);
+
+ final Event.Builder builder = new Event.Builder()
+ .setSubject(new RyaURI(subject));
+
+ if(document.containsKey(GEO_KEY)) {
+ final Document geoObj = (Document) document.get(GEO_KEY);
+ final GeometryFactory geoFact = new GeometryFactory();
+ final String typeString = (String) geoObj.get("type");
+ final CoordinateList coords = new CoordinateList();
+ final Geometry geo;
+ if (typeString.equals("Point")) {
+ final List<Double> point = (List<Double>) geoObj.get("coordinates");
+ final Coordinate coord = new Coordinate(point.get(0), point.get(1));
+ geo = geoFact.createPoint(coord);
+ } else if (typeString.equals("LineString")) {
+ final List<List<Double>> pointsList = (List<List<Double>>) geoObj.get("coordinates");
+ for (final List<Double> point : pointsList) {
+ coords.add(new Coordinate(point.get(0), point.get(1)));
+ }
+ geo = geoFact.createLineString(coords.toCoordinateArray());
+ } else {
+ final List<List<List<Double>>> pointsList = (List<List<List<Double>>>) geoObj.get("coordinates");
+ if(pointsList.size() == 1) {
+ final List<List<Double>> poly = pointsList.get(0);
+ for (final List<Double> point : poly) {
+ coords.add(new Coordinate(point.get(0), point.get(1)));
+ }
+ geo = geoFact.createPolygon(coords.toCoordinateArray());
+ } else {
+ final List<List<Double>> first = pointsList.get(0);
+ final CoordinateList shellCoords = new CoordinateList();
+ for (final List<Double> point : pointsList.get(0)) {
+ shellCoords.add(new Coordinate(point.get(0), point.get(1)));
+ }
+ final LinearRing shell = geoFact.createLinearRing(shellCoords.toCoordinateArray());
+
+ final List<List<List<Double>>> holesPoints = pointsList.subList(1, pointsList.size() - 1);
+ final LinearRing[] holes = new LinearRing[holesPoints.size()];
+ for(int ii = 0; ii < holes.length; ii++) {
+ final List<List<Double>> holePoints = holesPoints.get(ii);
+ final CoordinateList shells = new CoordinateList();
+ for (final List<Double> point : pointsList.get(0)) {
+ shells.add(new Coordinate(point.get(0), point.get(1)));
+ }
+ holes[ii] = geoFact.createLinearRing(shells.toCoordinateArray());
+ }
+ geo = geoFact.createPolygon(shell,
+ holes);
+ }
+ }
+ builder.setGeometry(geo);
+ }
+
+ if(isInstant) {
+ //we already know the key exists
+ final Date date = (Date) document.get(INSTANT);
+ final DateTime dt = new DateTime(date.getTime());
+ final TemporalInstant instant = new TemporalInstantRfc3339(dt);
+ builder.setTemporalInstant(instant);
+ } else if(document.containsKey(INTERVAL_START)){
+ Date date = (Date) document.get(INTERVAL_START);
+ DateTime dt = new DateTime(date.getTime());
+ final TemporalInstant begining = new TemporalInstantRfc3339(dt);
+
+ date = (Date) document.get(INTERVAL_END);
+ dt = new DateTime(date.getTime());
+ final TemporalInstant end = new TemporalInstantRfc3339(dt);
+
+ final TemporalInterval interval = new TemporalInterval(begining, end);
+ builder.setTemporalInterval(interval);
+ }
+ return builder.build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventUpdater.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventUpdater.java b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventUpdater.java
new file mode 100644
index 0000000..1c62407
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventUpdater.java
@@ -0,0 +1,85 @@
+/**
+ * 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.geotemporal.mongo;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Optional;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage.EventStorageException;
+import org.apache.rya.indexing.mongodb.update.MongoDocumentUpdater;
+import org.apache.rya.indexing.mongodb.update.RyaObjectStorage.ObjectStorageException;
+
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
+
+/**
+ * Performs update operations over an {@link EventStorage}.
+ */
+@DefaultAnnotation(NonNull.class)
+public class EventUpdater implements MongoDocumentUpdater<RyaURI, Event>{
+ private final EventStorage events;
+
+ /**
+ * Constructs an instance of {@link EventUpdater}
+ *
+ * @param events - The storage this updater operates over. (not null)
+ */
+ public EventUpdater(final EventStorage events) {
+ this.events = requireNonNull(events);
+ }
+
+ @Override
+ public Optional<Event> getOld(final RyaURI key) throws EventStorageException {
+ try {
+ return events.get(key);
+ } catch (final ObjectStorageException e) {
+ throw new EventStorageException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void create(final Event newObj) throws EventStorageException {
+ try {
+ events.create(newObj);
+ } catch (final ObjectStorageException e) {
+ throw new EventStorageException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void update(final Event old, final Event updated) throws EventStorageException {
+ try {
+ events.update(old, updated);
+ } catch (final ObjectStorageException e) {
+ throw new EventStorageException(e.getMessage(), e);
+ }
+ }
+
+ public void delete(final Event event) throws EventStorageException {
+ try {
+ events.delete(event.getSubject());
+ } catch (final ObjectStorageException e) {
+ throw new EventStorageException(e.getMessage(), e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategy.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategy.java b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategy.java
new file mode 100644
index 0000000..7bb1c1f
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategy.java
@@ -0,0 +1,300 @@
+/**
+ * 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.geotemporal.mongo;
+
+import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.EQUALS;
+import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.INTERSECTS;
+import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.WITHIN;
+import static org.apache.rya.indexing.mongodb.temporal.TemporalMongoDBStorageStrategy.INSTANT;
+import static org.apache.rya.indexing.mongodb.temporal.TemporalMongoDBStorageStrategy.INTERVAL_END;
+import static org.apache.rya.indexing.mongodb.temporal.TemporalMongoDBStorageStrategy.INTERVAL_START;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Matcher;
+
+import org.apache.log4j.Logger;
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.resolver.RyaToRdfConversions;
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.IndexingExpr;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.TemporalInterval;
+import org.apache.rya.indexing.accumulo.geo.GeoParseUtils;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexException;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer.GeoPolicy;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer.TemporalPolicy;
+import org.apache.rya.indexing.mongodb.IndexingMongoDBStorageStrategy;
+import org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy;
+import org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQuery;
+import org.apache.rya.indexing.mongodb.geo.GmlParser;
+import org.apache.rya.indexing.mongodb.temporal.TemporalMongoDBStorageStrategy;
+import org.joda.time.DateTime;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.query.MalformedQueryException;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.BasicDBObjectBuilder;
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+import com.mongodb.QueryBuilder;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKTReader;
+
+import jline.internal.Log;
+
+/**
+ * Storage adapter for serializing Geo Temporal statements into mongo objects.
+ * This includes adapting the {@link IndexingExpr}s for the GeoTemporal indexer.
+ */
+public class GeoTemporalMongoDBStorageStrategy extends IndexingMongoDBStorageStrategy {
+ private static final Logger LOG = Logger.getLogger(GeoTemporalMongoDBStorageStrategy.class);
+ private static final String GEO_KEY = "location";
+ private static final String TIME_KEY = "time";
+ private final TemporalMongoDBStorageStrategy temporalStrategy;
+ private final GeoMongoDBStorageStrategy geoStrategy;
+
+ public GeoTemporalMongoDBStorageStrategy() {
+ geoStrategy = new GeoMongoDBStorageStrategy(0.0);
+ temporalStrategy = new TemporalMongoDBStorageStrategy();
+ }
+
+ @Override
+ public void createIndices(final DBCollection coll){
+ coll.createIndex(new BasicDBObject(GEO_KEY, "2dsphere"));
+ coll.createIndex(TIME_KEY);
+ }
+
+ public DBObject getFilterQuery(final Collection<IndexingExpr> geoFilters, final Collection<IndexingExpr> temporalFilters) throws GeoTemporalIndexException {
+ final QueryBuilder builder = QueryBuilder.start();
+
+ if(!geoFilters.isEmpty()) {
+ final DBObject[] geo = getGeoObjs(geoFilters);
+ if(!temporalFilters.isEmpty()) {
+ final DBObject[] temporal = getTemporalObjs(temporalFilters);
+ builder.and(oneOrAnd(geo), oneOrAnd(temporal));
+ return builder.get();
+ } else {
+ return oneOrAnd(geo);
+ }
+ } else if(!temporalFilters.isEmpty()) {
+ final DBObject[] temporal = getTemporalObjs(temporalFilters);
+ return oneOrAnd(temporal);
+ } else {
+ return builder.get();
+ }
+ }
+
+ private DBObject oneOrAnd(final DBObject[] dbos) {
+ if(dbos.length == 1) {
+ return dbos[0];
+ }
+ return QueryBuilder.start()
+ .and(dbos)
+ .get();
+ }
+
+ @Override
+ public DBObject serialize(final RyaStatement ryaStatement) {
+ final BasicDBObjectBuilder builder = BasicDBObjectBuilder.start("_id", ryaStatement.getSubject().hashCode());
+ final URI obj = ryaStatement.getObject().getDataType();
+
+
+ if(obj.equals(GeoConstants.GEO_AS_WKT) || obj.equals(GeoConstants.GEO_AS_GML) ||
+ obj.equals(GeoConstants.XMLSCHEMA_OGC_GML) || obj.equals(GeoConstants.XMLSCHEMA_OGC_WKT)) {
+ try {
+ final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
+ final Geometry geo = GeoParseUtils.getGeometry(statement, new GmlParser());
+ if (geo.getNumPoints() > 1) {
+ builder.add(GEO_KEY, geoStrategy.getCorrespondingPoints(geo));
+ } else {
+ builder.add(GEO_KEY, geoStrategy.getDBPoint(geo));
+ }
+ } catch (final ParseException e) {
+ LOG.error("Could not create geometry for statement " + ryaStatement, e);
+ return null;
+ }
+ } else {
+ builder.add(TIME_KEY, temporalStrategy.getTimeValue(ryaStatement.getObject().getData()));
+ }
+ return builder.get();
+ }
+
+ private DBObject[] getGeoObjs(final Collection<IndexingExpr> geoFilters) {
+ final List<DBObject> objs = new ArrayList<>();
+ geoFilters.forEach(filter -> {
+ final GeoPolicy policy = GeoPolicy.fromURI(filter.getFunction());
+ final WKTReader reader = new WKTReader();
+ final String geoStr = ((Value) filter.getArguments()[0]).stringValue();
+ try {
+ //This method is what is used in the GeoIndexer.
+ final Geometry geo = reader.read(geoStr);
+ objs.add(getGeoObject(geo, policy));
+ } catch (final GeoTemporalIndexException | UnsupportedOperationException | ParseException e) {
+ Log.error("Unable to parse '" + geoStr + "'.", e);
+ }
+ });
+ return objs.toArray(new DBObject[]{});
+ }
+
+ private DBObject[] getTemporalObjs(final Collection<IndexingExpr> temporalFilters) {
+ final List<DBObject> objs = new ArrayList<>();
+ temporalFilters.forEach(filter -> {
+ final TemporalPolicy policy = TemporalPolicy.fromURI(filter.getFunction());
+ final String timeStr = ((Value) filter.getArguments()[0]).stringValue();
+ final Matcher matcher = TemporalInstantRfc3339.PATTERN.matcher(timeStr);
+ if(matcher.find()) {
+ final TemporalInterval interval = TemporalInstantRfc3339.parseInterval(timeStr);
+ if(policy == TemporalPolicy.INSTANT_AFTER_INSTANT ||
+ policy == TemporalPolicy.INSTANT_BEFORE_INSTANT ||
+ policy == TemporalPolicy.INSTANT_EQUALS_INSTANT) {
+ if(interval == null) {
+ Log.error("Cannot perform temporal interval based queries on an instant.");
+ }
+ }
+ objs.add(getTemporalObject(interval, policy));
+ } else {
+ final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.parse(timeStr));
+ if(policy != TemporalPolicy.INSTANT_AFTER_INSTANT &&
+ policy != TemporalPolicy.INSTANT_BEFORE_INSTANT &&
+ policy != TemporalPolicy.INSTANT_EQUALS_INSTANT) {
+ Log.error("Cannot perform temporal instant based queries on an interval.");
+ }
+ objs.add(getTemporalObject(instant, policy));
+ }
+ });
+ return objs.toArray(new DBObject[]{});
+ }
+
+ private DBObject getGeoObject (final Geometry geo, final GeoPolicy policy) throws GeoTemporalIndexException {
+ switch(policy) {
+ case CONTAINS:
+ throw new UnsupportedOperationException("Contains queries are not supported in Mongo DB.");
+ case CROSSES:
+ throw new UnsupportedOperationException("Crosses queries are not supported in Mongo DB.");
+ case DISJOINT:
+ throw new UnsupportedOperationException("Disjoint queries are not supported in Mongo DB.");
+ case EQUALS:
+ try {
+ return geoStrategy.getQuery(new GeoQuery(EQUALS, geo));
+ } catch (final MalformedQueryException e) {
+ throw new GeoTemporalIndexException(e.getMessage(), e);
+ }
+ case INTERSECTS:
+ try {
+ return geoStrategy.getQuery(new GeoQuery(INTERSECTS, geo));
+ } catch (final MalformedQueryException e) {
+ throw new GeoTemporalIndexException(e.getMessage(), e);
+ }
+ case OVERLAPS:
+ throw new UnsupportedOperationException("Overlaps queries are not supported in Mongo DB.");
+ case TOUCHES:
+ throw new UnsupportedOperationException("Touches queries are not supported in Mongo DB.");
+ case WITHIN:
+ try {
+ return geoStrategy.getQuery(new GeoQuery(WITHIN, geo));
+ } catch (final MalformedQueryException e) {
+ throw new GeoTemporalIndexException(e.getMessage(), e);
+ }
+ default:
+ return new BasicDBObject();
+ }
+ }
+
+ private DBObject getTemporalObject(final TemporalInstant instant, final TemporalPolicy policy) {
+ final DBObject temporalObj;
+ switch(policy) {
+ case INSTANT_AFTER_INSTANT:
+ temporalObj = QueryBuilder.start(INSTANT)
+ .greaterThan(instant.getAsDateTime().toDate())
+ .get();
+ break;
+ case INSTANT_BEFORE_INSTANT:
+ temporalObj = QueryBuilder.start(INSTANT)
+ .lessThan(instant.getAsDateTime().toDate())
+ .get();
+ break;
+ case INSTANT_EQUALS_INSTANT:
+ temporalObj = QueryBuilder.start(INSTANT)
+ .is(instant.getAsDateTime().toDate())
+ .get();
+ break;
+ default:
+ temporalObj = new BasicDBObject();
+ }
+ return temporalObj;
+ }
+
+ private DBObject getTemporalObject(final TemporalInterval interval, final TemporalPolicy policy) {
+ final DBObject temporalObj;
+ switch(policy) {
+ case INSTANT_AFTER_INTERVAL:
+ temporalObj = QueryBuilder.start(INSTANT)
+ .greaterThan(interval.getHasEnd().getAsDateTime().toDate())
+ .get();
+ break;
+ case INSTANT_BEFORE_INTERVAL:
+ temporalObj = QueryBuilder.start(INSTANT)
+ .lessThan(interval.getHasBeginning().getAsDateTime().toDate())
+ .get();
+ break;
+ case INSTANT_END_INTERVAL:
+ temporalObj = QueryBuilder.start(INSTANT)
+ .is(interval.getHasEnd().getAsDateTime().toDate())
+ .get();
+ break;
+ case INSTANT_IN_INTERVAL:
+ temporalObj = QueryBuilder.start(INSTANT)
+ .greaterThan(interval.getHasBeginning().getAsDateTime().toDate())
+ .lessThan(interval.getHasEnd().getAsDateTime().toDate())
+ .get();
+ break;
+ case INSTANT_START_INTERVAL:
+ temporalObj = QueryBuilder.start(INSTANT)
+ .is(interval.getHasBeginning().getAsDateTime().toDate())
+ .get();
+ break;
+ case INTERVAL_AFTER:
+ temporalObj = QueryBuilder.start(INTERVAL_START)
+ .greaterThan(interval.getHasEnd().getAsDateTime().toDate())
+ .get();
+ break;
+ case INTERVAL_BEFORE:
+ temporalObj = QueryBuilder.start(INTERVAL_END)
+ .lessThan(interval.getHasBeginning().getAsDateTime().toDate())
+ .get();
+ break;
+ case INTERVAL_EQUALS:
+ temporalObj = QueryBuilder.start(INTERVAL_START)
+ .is(interval.getHasBeginning().getAsDateTime().toDate())
+ .and(INTERVAL_END)
+ .is(interval.getHasEnd().getAsDateTime().toDate())
+ .get();
+ break;
+ default:
+ temporalObj = new BasicDBObject();
+ }
+ return temporalObj;
+ }
+}
[08/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java
new file mode 100644
index 0000000..f35eeb7
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java
@@ -0,0 +1,362 @@
+/**
+ * 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.geotemporal.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.IndexingExpr;
+import org.apache.rya.indexing.IndexingFunctionRegistry;
+import org.apache.rya.indexing.IndexingFunctionRegistry.FUNCTION_TYPE;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.geotemporal.mongo.MongoEventStorage;
+import org.apache.rya.indexing.geotemporal.mongo.MongoITBase;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.junit.Test;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.URIImpl;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.QueryEvaluationException;
+import org.openrdf.query.algebra.FunctionCall;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.ValueConstant;
+import org.openrdf.query.algebra.ValueExpr;
+import org.openrdf.query.algebra.Var;
+import org.openrdf.query.impl.MapBindingSet;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.PrecisionModel;
+
+import info.aduna.iteration.CloseableIteration;
+
+/**
+ * Unit tests the methods of {@link EventQueryNode}.
+ */
+public class EventQueryNodeTest extends MongoITBase {
+ private static final GeometryFactory GF = new GeometryFactory(new PrecisionModel(), 4326);
+ private static final ValueFactory VF = ValueFactoryImpl.getInstance();
+
+ @Test(expected = IllegalStateException.class)
+ public void constructor_differentSubjects() throws Exception {
+ final Var geoSubj = new Var("point");
+ final Var geoPred = new Var("-const-http://www.opengis.net/ont/geosparql#asWKT", ValueFactoryImpl.getInstance().createURI("http://www.opengis.net/ont/geosparql#asWKT"));
+ final Var geoObj = new Var("wkt");
+ final StatementPattern geoSP = new StatementPattern(geoSubj, geoPred, geoObj);
+
+ final Var timeSubj = new Var("time");
+ final Var timePred = new Var("-const-http://www.w3.org/2006/time#inXSDDateTime", ValueFactoryImpl.getInstance().createURI("-const-http://www.w3.org/2006/time#inXSDDateTime"));
+ final Var timeObj = new Var("time");
+ final StatementPattern timeSP = new StatementPattern(timeSubj, timePred, timeObj);
+ // This will fail.
+ new EventQueryNode.EventQueryNodeBuilder()
+ .setStorage(mock(EventStorage.class))
+ .setGeoPattern(geoSP)
+ .setTemporalPattern(timeSP)
+ .setGeoFilters(new ArrayList<IndexingExpr>())
+ .setTemporalFilters(new ArrayList<IndexingExpr>())
+ .setUsedFilters(new ArrayList<>())
+ .build();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void constructor_variablePredicate() throws Exception {
+ // A pattern that has a variable for its predicate.
+ final Var geoSubj = new Var("point");
+ final Var geoPred = new Var("geo");
+ final Var geoObj = new Var("wkt");
+ final StatementPattern geoSP = new StatementPattern(geoSubj, geoPred, geoObj);
+
+ final Var timeSubj = new Var("time");
+ final Var timePred = new Var("-const-http://www.w3.org/2006/time#inXSDDateTime", ValueFactoryImpl.getInstance().createURI("-const-http://www.w3.org/2006/time#inXSDDateTime"));
+ final Var timeObj = new Var("time");
+ final StatementPattern timeSP = new StatementPattern(timeSubj, timePred, timeObj);
+ // This will fail.
+ new EventQueryNode.EventQueryNodeBuilder()
+ .setStorage(mock(EventStorage.class))
+ .setGeoPattern(geoSP)
+ .setTemporalPattern(timeSP)
+ .setGeoFilters(new ArrayList<IndexingExpr>())
+ .setTemporalFilters(new ArrayList<IndexingExpr>())
+ .setUsedFilters(new ArrayList<>())
+ .build();
+ }
+
+ @Test
+ public void evaluate_constantSubject() throws Exception {
+ final EventStorage storage = new MongoEventStorage(super.getMongoClient(), "testDB");
+ RyaURI subject = new RyaURI("urn:event-1111");
+ final Geometry geo = GF.createPoint(new Coordinate(1, 1));
+ final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0);
+ final Event event = Event.builder()
+ .setSubject(subject)
+ .setGeometry(geo)
+ .setTemporalInstant(temp)
+ .build();
+
+ subject = new RyaURI("urn:event-2222");
+ final Event otherEvent = Event.builder()
+ .setSubject(subject)
+ .setGeometry(geo)
+ .setTemporalInstant(temp)
+ .build();
+
+ storage.create(event);
+ storage.create(otherEvent);
+
+ final String query =
+ "PREFIX time: <http://www.w3.org/2006/time#> \n"
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+ + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+ + "SELECT ?event ?time ?point ?wkt "
+ + "WHERE { "
+ + " <urn:event-1111> time:atTime ?time . "
+ + " <urn:event-1111> geo:asWKT ?wkt . "
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
+ + " FILTER(tempo:equals(?time, \"" + temp.toString() + "\")) "
+ + "}";
+
+ final EventQueryNode node = buildNode(storage, query);
+ final CloseableIteration<BindingSet, QueryEvaluationException> rez = node.evaluate(new MapBindingSet());
+ final MapBindingSet expected = new MapBindingSet();
+ expected.addBinding("wkt", VF.createLiteral("POINT (1 1)"));
+ expected.addBinding("time", VF.createLiteral(temp.toString()));
+ int count = 0;
+ assertTrue(rez.hasNext());
+ while(rez.hasNext()) {
+ assertEquals(expected, rez.next());
+ count++;
+ }
+ assertEquals(1, count);
+ }
+
+ @Test
+ public void evaluate_variableSubject() throws Exception {
+ final EventStorage storage = new MongoEventStorage(super.getMongoClient(), "testDB");
+ RyaURI subject = new RyaURI("urn:event-1111");
+ Geometry geo = GF.createPoint(new Coordinate(1, 1));
+ final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0);
+ final Event event = Event.builder()
+ .setSubject(subject)
+ .setGeometry(geo)
+ .setTemporalInstant(temp)
+ .build();
+
+ subject = new RyaURI("urn:event-2222");
+ geo = GF.createPoint(new Coordinate(-1, -1));
+ final Event otherEvent = Event.builder()
+ .setSubject(subject)
+ .setGeometry(geo)
+ .setTemporalInstant(temp)
+ .build();
+
+ storage.create(event);
+ storage.create(otherEvent);
+
+ final String query =
+ "PREFIX time: <http://www.w3.org/2006/time#> \n"
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+ + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+ + "SELECT ?event ?time ?point ?wkt "
+ + "WHERE { "
+ + " ?event time:atTime ?time . "
+ + " ?event geo:asWKT ?wkt . "
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
+ + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
+ + "}";
+
+ final EventQueryNode node = buildNode(storage, query);
+ final CloseableIteration<BindingSet, QueryEvaluationException> rez = node.evaluate(new MapBindingSet());
+ final MapBindingSet expected1 = new MapBindingSet();
+ expected1.addBinding("wkt", VF.createLiteral("POINT (1 1)"));
+ expected1.addBinding("time", VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
+ final MapBindingSet expected2 = new MapBindingSet();
+ expected2.addBinding("wkt", VF.createLiteral("POINT (-1 -1)"));
+ expected2.addBinding("time", VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
+
+ final List<BindingSet> actual = new ArrayList<>();
+ while(rez.hasNext()) {
+ actual.add(rez.next());
+ }
+ assertEquals(expected1, actual.get(0));
+ assertEquals(expected2, actual.get(1));
+ assertEquals(2, actual.size());
+ }
+
+ @Test
+ public void evaluate_variableSubject_existingBindingset() throws Exception {
+ final EventStorage storage = new MongoEventStorage(super.getMongoClient(), "testDB");
+ RyaURI subject = new RyaURI("urn:event-1111");
+ Geometry geo = GF.createPoint(new Coordinate(1, 1));
+ final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0);
+ final Event event = Event.builder()
+ .setSubject(subject)
+ .setGeometry(geo)
+ .setTemporalInstant(temp)
+ .build();
+
+ subject = new RyaURI("urn:event-2222");
+ geo = GF.createPoint(new Coordinate(-1, -1));
+ final Event otherEvent = Event.builder()
+ .setSubject(subject)
+ .setGeometry(geo)
+ .setTemporalInstant(temp)
+ .build();
+
+ storage.create(event);
+ storage.create(otherEvent);
+
+ final String query =
+ "PREFIX time: <http://www.w3.org/2006/time#> \n"
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+ + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+ + "SELECT ?event ?time ?point ?wkt "
+ + "WHERE { "
+ + " ?event time:atTime ?time . "
+ + " ?event geo:asWKT ?wkt . "
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
+ + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
+ + "}";
+
+ final EventQueryNode node = buildNode(storage, query);
+ final MapBindingSet existingBindings = new MapBindingSet();
+ existingBindings.addBinding("event", VF.createURI("urn:event-2222"));
+ final CloseableIteration<BindingSet, QueryEvaluationException> rez = node.evaluate(existingBindings);
+ final MapBindingSet expected = new MapBindingSet();
+ expected.addBinding("wkt", VF.createLiteral("POINT (-1 -1)"));
+ expected.addBinding("time", VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
+
+ final List<BindingSet> actual = new ArrayList<>();
+ while(rez.hasNext()) {
+ actual.add(rez.next());
+ }
+ assertEquals(1, actual.size());
+ assertEquals(expected, actual.get(0));
+ }
+
+ @Test
+ public void evaluate_variableSubject_existingBindingsetWrongFilters() throws Exception {
+ final EventStorage storage = new MongoEventStorage(super.getMongoClient(), "testDB");
+ RyaURI subject = new RyaURI("urn:event-1111");
+ Geometry geo = GF.createPoint(new Coordinate(1, 1));
+ final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0);
+ final Event event = Event.builder()
+ .setSubject(subject)
+ .setGeometry(geo)
+ .setTemporalInstant(temp)
+ .build();
+
+ subject = new RyaURI("urn:event-2222");
+ geo = GF.createPoint(new Coordinate(-10, -10));
+ final Event otherEvent = Event.builder()
+ .setSubject(subject)
+ .setGeometry(geo)
+ .setTemporalInstant(temp)
+ .build();
+
+ storage.create(event);
+ storage.create(otherEvent);
+
+ final String query =
+ "PREFIX time: <http://www.w3.org/2006/time#> \n"
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+ + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+ + "SELECT ?event ?time ?point ?wkt "
+ + "WHERE { "
+ + " ?event time:atTime ?time . "
+ + " ?event geo:asWKT ?wkt . "
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
+ + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
+ + "}";
+
+ final EventQueryNode node = buildNode(storage, query);
+ final MapBindingSet existingBindings = new MapBindingSet();
+ existingBindings.addBinding("event", VF.createURI("urn:event-2222"));
+ final CloseableIteration<BindingSet, QueryEvaluationException> rez = node.evaluate(existingBindings);
+ final MapBindingSet expected = new MapBindingSet();
+ expected.addBinding("wkt", VF.createLiteral("POINT (-1 -1)"));
+ expected.addBinding("time", VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
+
+ assertFalse(rez.hasNext());
+ }
+
+ private EventQueryNode buildNode(final EventStorage store, final String query) throws Exception {
+ final List<IndexingExpr> geoFilters = new ArrayList<>();
+ final List<IndexingExpr> temporalFilters = new ArrayList<>();
+ final List<StatementPattern> sps = getSps(query);
+ final List<FunctionCall> filters = getFilters(query);
+ for(final FunctionCall filter : filters) {
+ final URI filterURI = new URIImpl(filter.getURI());
+ final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, filter.getArgs());
+ final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), extractArguments(objVar.getName(), filter));
+ if(IndexingFunctionRegistry.getFunctionType(filterURI) == FUNCTION_TYPE.GEO) {
+ geoFilters.add(expr);
+ } else {
+ temporalFilters.add(expr);
+ }
+ }
+
+ final StatementPattern geoPattern = sps.get(1);
+ final StatementPattern temporalPattern = sps.get(0);
+
+ return new EventQueryNode.EventQueryNodeBuilder()
+ .setStorage(store)
+ .setGeoPattern(geoPattern)
+ .setTemporalPattern(temporalPattern)
+ .setGeoFilters(geoFilters)
+ .setTemporalFilters(temporalFilters)
+ .setUsedFilters(filters)
+ .build();
+ }
+
+ private Value[] extractArguments(final String matchName, final FunctionCall call) {
+ final Value args[] = new Value[call.getArgs().size() - 1];
+ int argI = 0;
+ for (int i = 0; i != call.getArgs().size(); ++i) {
+ final ValueExpr arg = call.getArgs().get(i);
+ if (argI == i && arg instanceof Var && matchName.equals(((Var)arg).getName())) {
+ continue;
+ }
+ if (arg instanceof ValueConstant) {
+ args[argI] = ((ValueConstant)arg).getValue();
+ } else if (arg instanceof Var && ((Var)arg).hasValue()) {
+ args[argI] = ((Var)arg).getValue();
+ } else {
+ throw new IllegalArgumentException("Query error: Found " + arg + ", expected a Literal, BNode or URI");
+ }
+ ++argI;
+ }
+ return args;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java
new file mode 100644
index 0000000..3f2f9d5
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java
@@ -0,0 +1,64 @@
+/**
+ * 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.geotemporal.mongo;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.entity.storage.mongo.DocumentConverter.DocumentConverterException;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.geotemporal.mongo.EventDocumentConverter;
+import org.bson.Document;
+import org.joda.time.DateTime;
+import org.junit.Test;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.PrecisionModel;
+
+/**
+ * Tests the methods of {@link EventDocumentConverter}.
+ */
+public class EventDocumentConverterTest {
+ private static final GeometryFactory GF = new GeometryFactory(new PrecisionModel(), 4326);
+
+ @Test
+ public void to_and_from_document() throws DocumentConverterException {
+ final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+ final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
+
+ // An Event that will be stored.
+ final Event event = Event.builder()
+ .setSubject(new RyaURI("urn:event/001"))
+ .setGeometry(geo)
+ .setTemporalInstant(instant)
+ .build();
+
+ final Document document = new EventDocumentConverter().toDocument(event);
+
+ // Convert the Document back into an Event.
+ final Event converted = new EventDocumentConverter().fromDocument(document);
+
+ // Ensure the original matches the round trip converted Event.
+ assertEquals(event, converted);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java
new file mode 100644
index 0000000..4a31599
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java
@@ -0,0 +1,490 @@
+/*
+l * 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.geotemporal.mongo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.rya.api.resolver.RdfToRyaConversions;
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.IndexingExpr;
+import org.apache.rya.indexing.IndexingFunctionRegistry;
+import org.apache.rya.indexing.IndexingFunctionRegistry.FUNCTION_TYPE;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer.GeoPolicy;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer.TemporalPolicy;
+import org.apache.rya.indexing.geotemporal.GeoTemporalTestBase;
+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.URIImpl;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.query.algebra.FunctionCall;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.ValueConstant;
+import org.openrdf.query.algebra.ValueExpr;
+import org.openrdf.query.algebra.Var;
+
+import com.mongodb.DBObject;
+import com.mongodb.util.JSON;
+
+/**
+ * Tests The {@link GeoTemporalMongoDBStorageStrategy}, which turns the filters
+ * into mongo {@link DBObject}s used to query.
+ *
+ * This tests also ensures all possible filter functions are accounted for in the test.
+ * @see TemporalPolicy Temporal Filter Functions
+ * @see GeoPolicy Geo Filter Functions
+ */
+public class GeoTemporalMongoDBStorageStrategyTest extends GeoTemporalTestBase {
+ private GeoTemporalMongoDBStorageStrategy adapter;
+ @Before
+ public void setup() {
+ adapter = new GeoTemporalMongoDBStorageStrategy();
+ }
+
+ @Test
+ public void emptyFilters_test() throws Exception {
+ final List<IndexingExpr> geoFilters = new ArrayList<>();
+ final List<IndexingExpr> temporalFilters = new ArrayList<>();
+ final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
+ final String expectedString =
+ "{ }";
+ final DBObject expected = (DBObject) JSON.parse(expectedString);
+ assertEqualMongo(expected, actual);
+ }
+
+ @Test
+ public void equalsInstantAfterInterval_onlyOneGeo() throws Exception {
+ final String query =
+ "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+ + "SELECT ?point ?wkt "
+ + "WHERE { "
+ + " ?point geo:asWKT ?wkt . "
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
+ + "}";
+ final List<IndexingExpr> geoFilters = new ArrayList<>();
+ final List<StatementPattern> sps = getSps(query);
+ final List<FunctionCall> filters = getFilters(query);
+ for(final FunctionCall filter : filters) {
+ //should only be one.
+ final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(new URIImpl(filter.getURI()), filter.getArgs());
+ final IndexingExpr expr = new IndexingExpr(new URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), filter));
+ geoFilters.add(expr);
+ }
+ final List<IndexingExpr> temporalFilters = new ArrayList<>();
+ final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
+ final String expectedString =
+ "{ "
+ + "\"location\" : { "
+ + "\"$geoWithin\" : { "
+ + "\"$geometry\" : { "
+ + "\"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] , "
+ + "\"type\" : \"Polygon\""
+ + "}"
+ + "}"
+ + "}"
+ + "}";
+ final DBObject expected = (DBObject) JSON.parse(expectedString);
+ assertEqualMongo(expected, actual);
+ }
+
+ @Test
+ public void equalsInstantAfterInterval_onlyGeos() throws Exception {
+
+ /*
+ * TODO: change filter functions for coverage
+ */
+
+
+ final String query =
+ "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+ + "SELECT ?point ?wkt "
+ + "WHERE { "
+ + " ?point geo:asWKT ?wkt . "
+ + " FILTER(geof:sfIntersects(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
+ + " FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 -3, -4 -3))\"^^geo:wktLiteral)) "
+ + "}";
+ final List<IndexingExpr> geoFilters = new ArrayList<>();
+ final List<StatementPattern> sps = getSps(query);
+ final List<FunctionCall> filters = getFilters(query);
+ for(final FunctionCall filter : filters) {
+ final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(new URIImpl(filter.getURI()), filter.getArgs());
+ final IndexingExpr expr = new IndexingExpr(new URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), filter));
+ geoFilters.add(expr);
+ }
+ final List<IndexingExpr> temporalFilters = new ArrayList<>();
+ final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
+
+ final String expectedString =
+ "{ "
+ + "\"$and\" : [ { "
+ + "\"location\" : {"
+ + " \"coordinates\" : [ [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 2.0 , 3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]] ,"
+ + " \"type\" : \"Polygon\""
+ + "}"
+ + "} , { "
+ + "\"location\" : { "
+ + "\"$geoIntersects\" : {"
+ + " \"$geometry\" : {"
+ + " \"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] ,"
+ + " \"type\" : \"Polygon\""
+ + "}"
+ + "}"
+ + "}"
+ + "}]}";
+ final DBObject expected = (DBObject) JSON.parse(expectedString);
+ assertEqualMongo(expected, actual);
+ }
+
+ @Test
+ public void equalsInstantAfterInterval_onlyOneTemporal() throws Exception {
+ final String query =
+ "PREFIX time: <http://www.w3.org/2006/time#> \n"
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+ + "SELECT ?event ?time "
+ + "WHERE { "
+ + " ?event time:atTime ?time . "
+ + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) . "
+ + "}";
+ final List<IndexingExpr> geoFilters = new ArrayList<>();
+ final List<IndexingExpr> temporalFilters = new ArrayList<>();
+ final List<StatementPattern> sps = getSps(query);
+ final List<FunctionCall> filters = getFilters(query);
+ for(final FunctionCall filter : filters) {
+ //should only be one.
+ final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(new URIImpl(filter.getURI()), filter.getArgs());
+ final IndexingExpr expr = new IndexingExpr(new URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), filter));
+ temporalFilters.add(expr);
+ }
+ final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
+ final String expectedString =
+ "{ "
+ + "\"instant\" : {"
+ + "\"$date\" : \"2015-12-30T12:00:00.000Z\""
+ + "}"
+ + "}";
+ final DBObject expected = (DBObject) JSON.parse(expectedString);
+ assertEqualMongo(expected, actual);
+ }
+
+ @Test
+ public void equalsInstantAfterInterval_onlyTemporal() throws Exception {
+ final String query =
+ "PREFIX time: <http://www.w3.org/2006/time#> \n"
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+ + "SELECT ?event ?time "
+ + "WHERE { "
+ + " ?event time:atTime ?time . "
+ + " FILTER(tempo:before(?time, \"2015-12-30T12:00:00Z\")) . "
+ + " FILTER(tempo:insideInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
+ + "}";
+ final List<IndexingExpr> geoFilters = new ArrayList<>();
+ final List<IndexingExpr> temporalFilters = new ArrayList<>();
+ final List<StatementPattern> sps = getSps(query);
+ final List<FunctionCall> filters = getFilters(query);
+ for(final FunctionCall filter : filters) {
+ final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(new URIImpl(filter.getURI()), filter.getArgs());
+ final IndexingExpr expr = new IndexingExpr(new URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), filter));
+ temporalFilters.add(expr);
+ }
+ final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
+ final String expectedString =
+ "{ "
+ + "\"$and\" : [{"
+ + "\"instant\" : {"
+ + "\"$gt\" : {"
+ + "\"$date\" : \"1970-01-01T00:00:00.000Z\""
+ + "},"
+ + "\"$lt\" : {"
+ + "\"$date\" : \"1970-01-01T00:00:01.000Z\""
+ + "},"
+ + "}}, {"
+ + "\"instant\" : {"
+ + "\"$lt\" : {"
+ + "\"$date\" : \"2015-12-30T12:00:00.000Z\""
+ + "}"
+ + "}"
+ + "}]"
+ + "}";
+ final DBObject expected = (DBObject) JSON.parse(expectedString);
+ assertEqualMongo(expected, actual);
+ }
+
+ @Test
+ public void equalsInstantAfterInterval_GeoTemporalOneEach() throws Exception {
+ final String query =
+ "PREFIX time: <http://www.w3.org/2006/time#> \n"
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+ + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+ + "SELECT ?event ?time ?point ?wkt "
+ + "WHERE { "
+ + " ?event time:atTime ?time . "
+ + " ?point geo:asWKT ?wkt . "
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
+ + " FILTER(tempo:after(?time, \"2015-12-30T12:00:00Z\")) "
+ + "}";
+ final List<IndexingExpr> geoFilters = new ArrayList<>();
+ final List<IndexingExpr> temporalFilters = new ArrayList<>();
+ final List<StatementPattern> sps = getSps(query);
+ final List<FunctionCall> filters = getFilters(query);
+ for(final FunctionCall filter : filters) {
+ final URI filterURI = new URIImpl(filter.getURI());
+ final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, filter.getArgs());
+ final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), extractArguments(objVar.getName(), filter));
+ if(IndexingFunctionRegistry.getFunctionType(filterURI) == FUNCTION_TYPE.GEO) {
+ geoFilters.add(expr);
+ } else {
+ temporalFilters.add(expr);
+ }
+ }
+ final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
+ final String expectedString =
+ "{ "
+ + "\"$and\" : [ { "
+ + "\"location\" : { "
+ + "\"$geoWithin\" : { "
+ + "\"$geometry\" : { "
+ + "\"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] , "
+ + "\"type\" : \"Polygon\""
+ + "}"
+ + "}"
+ + "}"
+ + "} , { "
+ + "\"instant\" : { "
+ + "\"$gt\" : { "
+ + "\"$date\" : \"2015-12-30T12:00:00.000Z\""
+ + "}"
+ + "}"
+ + "}]"
+ + "}";
+ final DBObject expected = (DBObject) JSON.parse(expectedString);
+ assertEqualMongo(expected, actual);
+ }
+
+ @Test
+ public void equalsInstantAfterInterval_GeoTemporalTwoEach() throws Exception {
+ final String query =
+ "PREFIX time: <http://www.w3.org/2006/time#> \n"
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+ + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+ + "SELECT ?event ?time ?point ?wkt "
+ + "WHERE { "
+ + " ?event time:atTime ?time . "
+ + " ?point geo:asWKT ?wkt . "
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
+ + " FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 -3, -4 -3))\"^^geo:wktLiteral)) "
+ + " FILTER(tempo:hasEndInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
+ + " FILTER(tempo:beforeInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
+ + "}";
+ final List<IndexingExpr> geoFilters = new ArrayList<>();
+ final List<IndexingExpr> temporalFilters = new ArrayList<>();
+ final List<StatementPattern> sps = getSps(query);
+ final List<FunctionCall> filters = getFilters(query);
+ for(final FunctionCall filter : filters) {
+ final URI filterURI = new URIImpl(filter.getURI());
+ final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, filter.getArgs());
+ final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), extractArguments(objVar.getName(), filter));
+ if(IndexingFunctionRegistry.getFunctionType(filterURI) == FUNCTION_TYPE.GEO) {
+ geoFilters.add(expr);
+ } else {
+ temporalFilters.add(expr);
+ }
+ }
+ final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
+ final String expectedString =
+ "{ "
+ + "\"$and\" : [ { "
+ + "\"$and\" : [ { "
+ + "\"location\" : { "
+ + "\"coordinates\" : [ [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 2.0 , 3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]] , "
+ + "\"type\" : \"Polygon\""
+ + "}"
+ + "} , { "
+ + "\"location\" : { "
+ + "\"$geoWithin\" : { "
+ + "\"$geometry\" : { "
+ + "\"coordinates\" : [ [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]] , "
+ + "\"type\" : \"Polygon\""
+ + "}"
+ + "}"
+ + "}"
+ + "}]"
+ + "} , { "
+ + "\"$and\" : [ { "
+ + "\"instant\" : { "
+ + "\"$lt\" : { "
+ + "\"$date\" : \"1970-01-01T00:00:00.000Z\""
+ + "}"
+ + "}"
+ + "} , { "
+ + "\"instant\" : { "
+ + "\"$date\" : \"1970-01-01T00:00:01.000Z\""
+ + "}"
+ + "}]"
+ + "}]"
+ + "}";
+ final DBObject expected = (DBObject) JSON.parse(expectedString);
+ assertEqualMongo(expected, actual);
+ }
+
+ @Test
+ public void equalsInstantAfterInterval_GeoTemporalSingleGeoTwoTemporal() throws Exception {
+ final String query =
+ "PREFIX time: <http://www.w3.org/2006/time#> \n"
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+ + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+ + "SELECT ?event ?time ?point ?wkt "
+ + "WHERE { "
+ + " ?event time:atTime ?time . "
+ + " ?point geo:asWKT ?wkt . "
+ + " FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 -3, -4 -3))\"^^geo:wktLiteral)) ."
+ + " FILTER(tempo:hasBeginningInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
+ + " FILTER(tempo:afterInterval(?time, \"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\"))"
+ + "}";
+ final List<IndexingExpr> geoFilters = new ArrayList<>();
+ final List<IndexingExpr> temporalFilters = new ArrayList<>();
+ final List<StatementPattern> sps = getSps(query);
+ final List<FunctionCall> filters = getFilters(query);
+ for(final FunctionCall filter : filters) {
+ final URI filterURI = new URIImpl(filter.getURI());
+ final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, filter.getArgs());
+ final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), extractArguments(objVar.getName(), filter));
+ if(IndexingFunctionRegistry.getFunctionType(filterURI) == FUNCTION_TYPE.GEO) {
+ geoFilters.add(expr);
+ } else {
+ temporalFilters.add(expr);
+ }
+ }
+ final DBObject actual = adapter.getFilterQuery(geoFilters, temporalFilters);
+ final String expectedString =
+ "{ "
+ + "\"$and\" : [ { "
+ + "\"location\" : { "
+ + "\"coordinates\" : [ [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 2.0 , 3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]] , "
+ + "\"type\" : \"Polygon\""
+ + "}"
+ + "} , { "
+ + "\"$and\" : [ { "
+ + "\"instant\" : { "
+ + "\"$gt\" : { "
+ + "\"$date\" : \"1970-01-01T00:00:01.000Z\""
+ + "}"
+ + "}"
+ + "} , { "
+ + "\"instant\" : { "
+ + "\"$date\" : \"1970-01-01T00:00:00.000Z\""
+ + "}"
+ + "}]"
+ + "}]"
+ + "}";
+ final DBObject expected = (DBObject) JSON.parse(expectedString);
+ assertEqualMongo(expected, actual);
+ }
+
+ @Test
+ public void serializeTest() {
+ final ValueFactory vf = new ValueFactoryImpl();
+ final Resource subject = vf.createURI("foo:subj");
+ final Resource context = vf.createURI("foo:context");
+
+ //GEO
+ URI predicate = GeoConstants.GEO_AS_WKT;
+ Value object = vf.createLiteral("Point(-77.03524 38.889468)", GeoConstants.XMLSCHEMA_OGC_WKT);
+
+ Statement statement = new ContextStatementImpl(subject, predicate, object, context);
+ DBObject actual = adapter.serialize(RdfToRyaConversions.convertStatement(statement));
+ String expectedString =
+ "{ "
+ + "\"_id\" : -852305321 , "
+ + "\"location\" : { "
+ + "\"coordinates\" : [ -77.03524 , 38.889468] , "
+ + "\"type\" : \"Point\""
+ + "}"
+ + "}";
+ DBObject expected = (DBObject) JSON.parse(expectedString);
+ assertEqualMongo(expected, actual);
+
+ //TIME INSTANT
+ predicate = new URIImpl("Property:event:time");
+ object = vf.createLiteral("2015-12-30T12:00:00Z");
+ statement = new ContextStatementImpl(subject, predicate, object, context);
+ actual = adapter.serialize(RdfToRyaConversions.convertStatement(statement));
+ expectedString =
+ "{"
+ +"_id : -852305321, "
+ +"time: {"
+ + "instant : {"
+ +"\"$date\" : \"2015-12-30T12:00:00.000Z\""
+ + "}"
+ + "}"
+ + "}";
+ expected = (DBObject) JSON.parse(expectedString);
+ assertEqualMongo(expected, actual);
+
+ //TIME INTERVAL
+ predicate = new URIImpl("Property:circa");
+ object = vf.createLiteral("[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]");
+ statement = new ContextStatementImpl(subject, predicate, object, context);
+ actual = adapter.serialize(RdfToRyaConversions.convertStatement(statement));
+ expectedString =
+ "{"
+ +"_id : -852305321, "
+ +"time: {"
+ + "start : {"
+ +"\"$date\" : \"1970-01-01T00:00:00.000Z\""
+ + "},"
+ + "end : {"
+ +"\"$date\" : \"1970-01-01T00:00:01.000Z\""
+ + "}"
+ + "}"
+ + "}";
+ expected = (DBObject) JSON.parse(expectedString);
+ assertEqualMongo(expected, actual);
+ }
+
+ private Value[] extractArguments(final String matchName, final FunctionCall call) {
+ final Value args[] = new Value[call.getArgs().size() - 1];
+ int argI = 0;
+ for (int i = 0; i != call.getArgs().size(); ++i) {
+ final ValueExpr arg = call.getArgs().get(i);
+ if (argI == i && arg instanceof Var && matchName.equals(((Var)arg).getName())) {
+ continue;
+ }
+ if (arg instanceof ValueConstant) {
+ args[argI] = ((ValueConstant)arg).getValue();
+ } else if (arg instanceof Var && ((Var)arg).hasValue()) {
+ args[argI] = ((Var)arg).getValue();
+ } else {
+ throw new IllegalArgumentException("Query error: Found " + arg + ", expected a Literal, BNode or URI");
+ }
+ ++argI;
+ }
+ return args;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java
new file mode 100644
index 0000000..5b07460
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java
@@ -0,0 +1,197 @@
+/**
+ * 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.geotemporal.mongo;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Optional;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage.EventAlreadyExistsException;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage.EventStorageException;
+import org.joda.time.DateTime;
+import org.junit.Test;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.PrecisionModel;
+
+/**
+ * Integration tests the methods of {@link MongoEventStorage}.
+ */
+public class MongoEventStorageTest extends MongoITBase {
+
+ private static final String RYA_INSTANCE_NAME = "testInstance";
+ private static final GeometryFactory GF = new GeometryFactory(new PrecisionModel(), 4326);
+
+ @Test
+ public void create_and_get() throws Exception {
+ final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+ final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
+
+ // An Event that will be stored.
+ final Event event = Event.builder()
+ .setSubject(new RyaURI("urn:event/001"))
+ .setGeometry(geo)
+ .setTemporalInstant(instant)
+ .build();
+
+ // Create it.
+ final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+ storage.create(event);
+
+ // Get it.
+ final Optional<Event> storedEvent = storage.get(new RyaURI("urn:event/001"));
+
+ // Verify the correct value was returned.
+ assertEquals(event, storedEvent.get());
+ }
+
+ @Test
+ public void can_not_create_with_same_subject() throws Exception {
+ final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+ final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
+
+ // An Event that will be stored.
+ final Event event = Event.builder()
+ .setSubject(new RyaURI("urn:event/001"))
+ .setGeometry(geo)
+ .setTemporalInstant(instant)
+ .build();
+
+ // Create it.
+ final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+ storage.create(event);
+
+ // Try to create it again. This will fail.
+ boolean failed = false;
+ try {
+ storage.create(event);
+ } catch(final EventAlreadyExistsException e) {
+ failed = true;
+ }
+ assertTrue(failed);
+ }
+
+ @Test
+ public void get_noneExisting() throws Exception {
+ // Get a Type that hasn't been created.
+ final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+ final Optional<Event> storedEvent = storage.get(new RyaURI("urn:event/000"));
+
+ // Verify nothing was returned.
+ assertFalse(storedEvent.isPresent());
+ }
+
+ @Test
+ public void delete() throws Exception {
+ final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+ final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
+
+ // An Event that will be stored.
+ final Event event = Event.builder()
+ .setSubject(new RyaURI("urn:event/002"))
+ .setGeometry(geo)
+ .setTemporalInstant(instant)
+ .build();
+
+ // Create it.
+ final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+ storage.create(event);
+
+ // Delete it.
+ final boolean deleted = storage.delete( new RyaURI("urn:event/002") );
+
+ // Verify a document was deleted.
+ assertTrue( deleted );
+ }
+
+ @Test
+ public void delete_nonExisting() throws Exception {
+ // Delete an Event that has not been created.
+ final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+ final boolean deleted = storage.delete( new RyaURI("urn:event/003") );
+
+ // Verify no document was deleted.
+ assertFalse( deleted );
+ }
+
+ @Test
+ public void update() throws Exception {
+ final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+ final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+ TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
+
+ // An Event that will be stored.
+ final Event event = Event.builder()
+ .setSubject(new RyaURI("urn:event/004"))
+ .setGeometry(geo)
+ .setTemporalInstant(instant)
+ .build();
+
+ storage.create(event);
+
+ // Show Alice was stored.
+ Optional<Event> latest = storage.get(new RyaURI("urn:event/004"));
+ assertEquals(event, latest.get());
+
+ instant = new TemporalInstantRfc3339(DateTime.now());
+ // Change Alice's eye color to brown.
+ final Event updated = Event.builder(event)
+ .setTemporalInstant(instant)
+ .build();
+
+ storage.update(event, updated);
+
+ // Fetch the Alice object and ensure it has the new value.
+ latest = storage.get(new RyaURI("urn:event/004"));
+
+ assertEquals(updated, latest.get());
+ }
+
+ @Test(expected = EventStorageException.class)
+ public void update_differentSubjects() throws Exception {
+ final EventStorage storage = new MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+ final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+ final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
+
+ // Two objects that do not have the same Subjects.
+ final Event old = Event.builder()
+ .setSubject(new RyaURI("urn:event/001"))
+ .setGeometry(geo)
+ .setTemporalInstant(instant)
+ .build();
+
+ final Event updated = Event.builder()
+ .setSubject(new RyaURI("urn:event/002"))
+ .setGeometry(geo)
+ .setTemporalInstant(instant)
+ .build();
+
+ // The update will fail.
+ storage.update(old, updated);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java
new file mode 100644
index 0000000..f2d0868
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java
@@ -0,0 +1,115 @@
+/**
+ * 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.geotemporal.mongo;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Optional;
+
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.resolver.RdfToRyaConversions;
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.model.Resource;
+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.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Integration tests the methods of {@link MongoGeoTemporalIndexer}.
+ */
+public class MongoGeoTemporalIndexerIT extends MongoITBase {
+ private MongoGeoTemporalIndexer indexer;
+
+ @Before
+ public void makeTestIndexer() throws Exception {
+ indexer = new MongoGeoTemporalIndexer();
+ indexer.setConf(conf);
+ indexer.init();
+ }
+
+ @Test
+ public void ensureEvent() throws Exception {
+ final RyaStatement geoStmnt = statement(point(0, 0));
+ final RyaStatement timeStmnt = statement(makeInstant(0));
+
+ final EventStorage store = indexer.getEventStorage(conf);
+
+ indexer.storeStatement(geoStmnt);
+ Optional<Event> evnt = store.get(geoStmnt.getSubject());
+ assertTrue(evnt.isPresent());
+ Event expected = Event.builder()
+ .setSubject(geoStmnt.getSubject())
+ .setGeometry(point(0, 0))
+ .build();
+ assertEquals(expected, evnt.get());
+
+ indexer.storeStatement(timeStmnt);
+ evnt = store.get(timeStmnt.getSubject());
+ assertTrue(evnt.isPresent());
+ expected = Event.builder()
+ .setSubject(geoStmnt.getSubject())
+ .setGeometry(point(0, 0))
+ .setTemporalInstant(makeInstant(0))
+ .build();
+ assertEquals(expected, evnt.get());
+
+ indexer.deleteStatement(geoStmnt);
+ evnt = store.get(timeStmnt.getSubject());
+ assertTrue(evnt.isPresent());
+ expected = Event.builder()
+ .setSubject(timeStmnt.getSubject())
+ .setTemporalInstant(makeInstant(0))
+ .build();
+ assertEquals(expected, evnt.get());
+
+ indexer.deleteStatement(timeStmnt);
+ evnt = store.get(timeStmnt.getSubject());
+ assertTrue(evnt.isPresent());
+ expected = Event.builder()
+ .setSubject(timeStmnt.getSubject())
+ .build();
+ assertEquals(expected, evnt.get());
+ }
+
+ private static RyaStatement statement(final Geometry geo) {
+ final ValueFactory vf = new ValueFactoryImpl();
+ final Resource subject = vf.createURI("uri:test");
+ 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 RyaStatement statement(final TemporalInstant instant) {
+ final ValueFactory vf = new ValueFactoryImpl();
+ final Resource subject = vf.createURI("uri:test");
+ final URI predicate = vf.createURI("Property:atTime");
+ final Value object = vf.createLiteral(instant.toString());
+ return RdfToRyaConversions.convertStatement(new StatementImpl(subject, predicate, object));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java
new file mode 100644
index 0000000..7488572
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java
@@ -0,0 +1,64 @@
+/**
+ * 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.geotemporal.mongo;
+
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.geotemporal.GeoTemporalTestBase;
+import org.apache.rya.indexing.mongodb.MongoIndexingConfiguration;
+import org.apache.rya.mongodb.MockMongoSingleton;
+import org.junit.After;
+import org.junit.Before;
+
+import com.mongodb.MongoClient;
+
+/**
+ * A base class that may be used when implementing Mongo DB integration tests that
+ * use the JUnit framework.
+ */
+public class MongoITBase extends GeoTemporalTestBase {
+
+ private static MongoClient mongoClient = null;
+ protected static MongoIndexingConfiguration conf;
+
+ @Before
+ public void setupTest() throws Exception {
+ mongoClient = MockMongoSingleton.getInstance();
+ conf = MongoIndexingConfiguration.builder()
+ .setMongoCollectionPrefix("test_")
+ .setMongoDBName("testDB")
+ .build();
+ conf.setBoolean(ConfigUtils.USE_MONGO, true);
+ conf.setMongoClient(mongoClient);
+ }
+
+ @After
+ public void cleanupTest() {
+ // Remove any DBs that were created by the test.
+ for(final String dbName : mongoClient.listDatabaseNames()) {
+ mongoClient.dropDatabase(dbName);
+ }
+ }
+
+ /**
+ * @return A {@link MongoClient} that is connected to the embedded instance of Mongo DB.
+ */
+ public MongoClient getMongoClient() {
+ return mongoClient;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerSfTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerSfTest.java b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerSfTest.java
new file mode 100644
index 0000000..57873fd
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerSfTest.java
@@ -0,0 +1,262 @@
+package org.apache.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 org.apache.rya.indexing.GeoIndexingTestUtils.getSet;
+
+import java.util.Map;
+import java.util.Set;
+
+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.StatementConstraints;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.geotemporal.mongo.MongoITBase;
+import org.apache.rya.indexing.accumulo.geo.OptionalConfigUtils;
+import org.apache.rya.indexing.mongodb.geo.MongoGeoIndexer;
+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.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.PrecisionModel;
+
+import info.aduna.iteration.CloseableIteration;
+
+/**
+ * Tests all of the "simple functions" of the geoindexer.
+ */
+public class MongoGeoIndexerSfTest extends MongoITBase {
+ 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 {
+ conf.set(ConfigUtils.GEO_PREDICATES_LIST, "http://www.opengis.net/ont/geosparql#asWKT");
+ conf.set(OptionalConfigUtils.USE_GEO, "true");
+
+ g = new MongoGeoIndexer();
+ g.initIndexer(conf, super.getMongoClient());
+ 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));
+
+ }
+
+ 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 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);
+// }
+
+}
[11/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGeoIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGeoIndexer.java b/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGeoIndexer.java
new file mode 100644
index 0000000..db7af05
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGeoIndexer.java
@@ -0,0 +1,668 @@
+/*
+ * 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 com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Objects.requireNonNull;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.accumulo.core.client.Connector;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.rya.accumulo.experimental.AbstractAccumuloIndexer;
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.resolver.RyaToRdfConversions;
+import org.apache.rya.indexing.GeoIndexer;
+import org.apache.rya.indexing.Md5Hash;
+import org.apache.rya.indexing.StatementConstraints;
+import org.apache.rya.indexing.StatementSerializer;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.accumulo.geo.GeoTupleSet.GeoSearchFunctionFactory.NearQuery;
+import org.geotools.data.DataStore;
+import org.geotools.data.DataUtilities;
+import org.geotools.data.FeatureSource;
+import org.geotools.data.FeatureStore;
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.factory.Hints;
+import org.geotools.feature.DefaultFeatureCollection;
+import org.geotools.feature.SchemaException;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.filter.text.cql2.CQLException;
+import org.geotools.filter.text.ecql.ECQL;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory;
+import org.opengis.filter.identity.Identifier;
+import org.openrdf.model.Literal;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.query.QueryEvaluationException;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.ParseException;
+
+import info.aduna.iteration.CloseableIteration;
+import mil.nga.giat.geowave.adapter.vector.FeatureDataAdapter;
+import mil.nga.giat.geowave.adapter.vector.plugin.GeoWaveGTDataStore;
+import mil.nga.giat.geowave.adapter.vector.plugin.GeoWaveGTDataStoreFactory;
+import mil.nga.giat.geowave.adapter.vector.plugin.GeoWavePluginException;
+import mil.nga.giat.geowave.adapter.vector.query.cql.CQLQuery;
+import mil.nga.giat.geowave.core.geotime.ingest.SpatialDimensionalityTypeProvider;
+import mil.nga.giat.geowave.core.store.CloseableIterator;
+import mil.nga.giat.geowave.core.store.StoreFactoryFamilySpi;
+import mil.nga.giat.geowave.core.store.index.PrimaryIndex;
+import mil.nga.giat.geowave.core.store.memory.MemoryStoreFactoryFamily;
+import mil.nga.giat.geowave.core.store.query.EverythingQuery;
+import mil.nga.giat.geowave.core.store.query.QueryOptions;
+import mil.nga.giat.geowave.datastore.accumulo.AccumuloDataStore;
+import mil.nga.giat.geowave.datastore.accumulo.AccumuloStoreFactoryFamily;
+
+/**
+ * A {@link GeoIndexer} wrapper around a GeoWave {@link AccumuloDataStore}. This class configures and connects to the Datastore, creates the
+ * RDF Feature Type, and interacts with the Datastore.
+ * <p>
+ * Specifically, this class creates a RDF Feature type and stores each RDF Statement as a RDF Feature in the datastore. Each feature
+ * contains the standard set of GeoWave attributes (Geometry, Start Date, and End Date). The GeoWaveGeoIndexer populates the Geometry
+ * attribute by parsing the Well-Known Text contained in the RDF Statement’s object literal value.
+ * <p>
+ * The RDF Feature contains four additional attributes for each component of the RDF Statement. These attributes are:
+ * <p>
+ * <table border="1">
+ * <tr>
+ * <th>Name</th>
+ * <th>Symbol</th>
+ * <th>Type</th>
+ * </tr>
+ * <tr>
+ * <td>Subject Attribute</td>
+ * <td>S</td>
+ * <td>String</td>
+ * </tr>
+ * </tr>
+ * <tr>
+ * <td>Predicate Attribute</td>
+ * <td>P</td>
+ * <td>String</td>
+ * </tr>
+ * </tr>
+ * <tr>
+ * <td>Object Attribute</td>
+ * <td>O</td>
+ * <td>String</td>
+ * </tr>
+ * </tr>
+ * <tr>
+ * <td>Context Attribute</td>
+ * <td>C</td>
+ * <td>String</td>
+ * </tr>
+ * </table>
+ */
+public class GeoWaveGeoIndexer extends AbstractAccumuloIndexer implements GeoIndexer {
+
+ private static final String TABLE_SUFFIX = "geo";
+
+ private static final Logger logger = Logger.getLogger(GeoWaveGeoIndexer.class);
+
+ private static final String FEATURE_NAME = "RDF";
+
+ private static final String SUBJECT_ATTRIBUTE = "S";
+ private static final String PREDICATE_ATTRIBUTE = "P";
+ private static final String OBJECT_ATTRIBUTE = "O";
+ private static final String CONTEXT_ATTRIBUTE = "C";
+ private static final String GEO_ID_ATTRIBUTE = "geo_id";
+ private static final String GEOMETRY_ATTRIBUTE = "geowave_index_geometry";
+
+ private Set<URI> validPredicates;
+ private Configuration conf;
+ private FeatureStore<SimpleFeatureType, SimpleFeature> featureStore;
+ private FeatureSource<SimpleFeatureType, SimpleFeature> featureSource;
+ private SimpleFeatureType featureType;
+ private FeatureDataAdapter featureDataAdapter;
+ private DataStore geoToolsDataStore;
+ private mil.nga.giat.geowave.core.store.DataStore geoWaveDataStore;
+ private final PrimaryIndex index = new SpatialDimensionalityTypeProvider().createPrimaryIndex();
+ private boolean isInit = false;
+
+ //initialization occurs in setConf because index is created using reflection
+ @Override
+ public void setConf(final Configuration conf) {
+ this.conf = conf;
+ if (!isInit) {
+ try {
+ initInternal();
+ isInit = true;
+ } catch (final IOException e) {
+ logger.warn("Unable to initialize index. Throwing Runtime Exception. ", e);
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public Configuration getConf() {
+ return conf;
+ }
+
+ /**
+ * @return the internal GeoTools{@link DataStore} used by the {@link GeoWaveGeoIndexer}.
+ */
+ public DataStore getGeoToolsDataStore() {
+ return geoToolsDataStore;
+ }
+
+ /**
+ * @return the internal GeoWave {@link DataStore} used by the {@link GeoWaveGeoIndexer}.
+ */
+ public mil.nga.giat.geowave.core.store.DataStore getGeoWaveDataStore() {
+ return geoWaveDataStore;
+ }
+
+ private void initInternal() throws IOException {
+ validPredicates = ConfigUtils.getGeoPredicates(conf);
+
+ try {
+ geoToolsDataStore = createDataStore(conf);
+ geoWaveDataStore = ((GeoWaveGTDataStore) geoToolsDataStore).getDataStore();
+ } catch (final GeoWavePluginException e) {
+ logger.error("Failed to create GeoWave data store", e);
+ }
+
+ try {
+ featureType = getStatementFeatureType(geoToolsDataStore);
+ } catch (final IOException | SchemaException e) {
+ throw new IOException(e);
+ }
+
+ featureDataAdapter = new FeatureDataAdapter(featureType);
+
+ featureSource = geoToolsDataStore.getFeatureSource(featureType.getName());
+ if (!(featureSource instanceof FeatureStore)) {
+ throw new IllegalStateException("Could not retrieve feature store");
+ }
+ featureStore = (FeatureStore<SimpleFeatureType, SimpleFeature>) featureSource;
+ }
+
+ public Map<String, Serializable> getParams(final Configuration conf) {
+ // get the configuration parameters
+ final Instance instance = ConfigUtils.getInstance(conf);
+ final String instanceId = instance.getInstanceName();
+ final String zookeepers = instance.getZooKeepers();
+ final String user = ConfigUtils.getUsername(conf);
+ final String password = ConfigUtils.getPassword(conf);
+ final String auths = ConfigUtils.getAuthorizations(conf).toString();
+ final String tableName = getTableName(conf);
+ final String tablePrefix = ConfigUtils.getTablePrefix(conf);
+
+ final Map<String, Serializable> params = new HashMap<>();
+ params.put("zookeeper", zookeepers);
+ params.put("instance", instanceId);
+ params.put("user", user);
+ params.put("password", password);
+ params.put("namespace", tableName);
+ params.put("gwNamespace", tablePrefix + getClass().getSimpleName());
+
+ params.put("Lock Management", LockManagementType.MEMORY.toString());
+ params.put("Authorization Management Provider", AuthorizationManagementProviderType.EMPTY.toString());
+ params.put("Authorization Data URL", null);
+ params.put("Transaction Buffer Size", 10000);
+ params.put("Query Index Strategy", QueryIndexStrategyType.HEURISTIC_MATCH.toString());
+ return params;
+ }
+
+ /**
+ * Creates the {@link DataStore} for the {@link GeoWaveGeoIndexer}.
+ * @param conf the {@link Configuration}.
+ * @return the {@link DataStore}.
+ */
+ public DataStore createDataStore(final Configuration conf) throws IOException, GeoWavePluginException {
+ final Map<String, Serializable> params = getParams(conf);
+ final Instance instance = ConfigUtils.getInstance(conf);
+ final boolean useMock = instance instanceof MockInstance;
+
+ final StoreFactoryFamilySpi storeFactoryFamily;
+ if (useMock) {
+ storeFactoryFamily = new MemoryStoreFactoryFamily();
+ } else {
+ storeFactoryFamily = new AccumuloStoreFactoryFamily();
+ }
+
+ final GeoWaveGTDataStoreFactory geoWaveGTDataStoreFactory = new GeoWaveGTDataStoreFactory(storeFactoryFamily);
+ final DataStore dataStore = geoWaveGTDataStoreFactory.createNewDataStore(params);
+
+ return dataStore;
+ }
+
+ private static SimpleFeatureType getStatementFeatureType(final DataStore dataStore) throws IOException, SchemaException {
+ SimpleFeatureType featureType;
+
+ final String[] datastoreFeatures = dataStore.getTypeNames();
+ if (Arrays.asList(datastoreFeatures).contains(FEATURE_NAME)) {
+ featureType = dataStore.getSchema(FEATURE_NAME);
+ } else {
+ featureType = DataUtilities.createType(FEATURE_NAME,
+ SUBJECT_ATTRIBUTE + ":String," +
+ PREDICATE_ATTRIBUTE + ":String," +
+ OBJECT_ATTRIBUTE + ":String," +
+ CONTEXT_ATTRIBUTE + ":String," +
+ GEOMETRY_ATTRIBUTE + ":Geometry:srid=4326," +
+ GEO_ID_ATTRIBUTE + ":String");
+
+ dataStore.createSchema(featureType);
+ }
+ return featureType;
+ }
+
+ @Override
+ public void storeStatements(final Collection<RyaStatement> ryaStatements) throws IOException {
+ // create a feature collection
+ final DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
+ for (final RyaStatement ryaStatement : ryaStatements) {
+ final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
+ // if the predicate list is empty, accept all predicates.
+ // Otherwise, make sure the predicate is on the "valid" list
+ final boolean isValidPredicate = validPredicates.isEmpty() || validPredicates.contains(statement.getPredicate());
+
+ if (isValidPredicate && (statement.getObject() instanceof Literal)) {
+ try {
+ final SimpleFeature feature = createFeature(featureType, statement);
+ featureCollection.add(feature);
+ } catch (final ParseException e) {
+ logger.warn("Error getting geo from statement: " + statement.toString(), e);
+ }
+ }
+ }
+
+ // write this feature collection to the store
+ if (!featureCollection.isEmpty()) {
+ featureStore.addFeatures(featureCollection);
+ }
+ }
+
+ @Override
+ public void storeStatement(final RyaStatement statement) throws IOException {
+ storeStatements(Collections.singleton(statement));
+ }
+
+ private static SimpleFeature createFeature(final SimpleFeatureType featureType, final Statement statement) throws ParseException {
+ final String subject = StatementSerializer.writeSubject(statement);
+ final String predicate = StatementSerializer.writePredicate(statement);
+ final String object = StatementSerializer.writeObject(statement);
+ final String context = StatementSerializer.writeContext(statement);
+
+ // create the feature
+ final Object[] noValues = {};
+
+ // create the hash
+ final String statementId = Md5Hash.md5Base64(StatementSerializer.writeStatement(statement));
+ final SimpleFeature newFeature = SimpleFeatureBuilder.build(featureType, noValues, statementId);
+
+ // write the statement data to the fields
+ final Geometry geom = GeoParseUtils.getGeometry(statement, new GmlParser());
+ if(geom == null || geom.isEmpty() || !geom.isValid()) {
+ throw new ParseException("Could not create geometry for statement " + statement);
+ }
+ newFeature.setDefaultGeometry(geom);
+
+ newFeature.setAttribute(SUBJECT_ATTRIBUTE, subject);
+ newFeature.setAttribute(PREDICATE_ATTRIBUTE, predicate);
+ newFeature.setAttribute(OBJECT_ATTRIBUTE, object);
+ newFeature.setAttribute(CONTEXT_ATTRIBUTE, context);
+ // GeoWave does not support querying based on a user generated feature ID
+ // So, we create a separate ID attribute that it can query on.
+ newFeature.setAttribute(GEO_ID_ATTRIBUTE, statementId);
+
+ // preserve the ID that we created for this feature
+ // (set the hint to FALSE to have GeoTools generate IDs)
+ newFeature.getUserData().put(Hints.USE_PROVIDED_FID, java.lang.Boolean.TRUE);
+
+ return newFeature;
+ }
+
+ private CloseableIteration<Statement, QueryEvaluationException> performQuery(final String type, final Geometry geometry,
+ final StatementConstraints contraints) {
+ final List<String> filterParms = new ArrayList<String>();
+
+ filterParms.add(type + "(" + GEOMETRY_ATTRIBUTE + ", " + geometry + " )");
+
+ if (contraints.hasSubject()) {
+ filterParms.add("( " + SUBJECT_ATTRIBUTE + "= '" + contraints.getSubject() + "') ");
+ }
+ if (contraints.hasContext()) {
+ filterParms.add("( " + CONTEXT_ATTRIBUTE + "= '" + contraints.getContext() + "') ");
+ }
+ if (contraints.hasPredicates()) {
+ final List<String> predicates = new ArrayList<String>();
+ for (final URI u : contraints.getPredicates()) {
+ predicates.add("( " + PREDICATE_ATTRIBUTE + "= '" + u.stringValue() + "') ");
+ }
+ filterParms.add("(" + StringUtils.join(predicates, " OR ") + ")");
+ }
+
+ final String filterString = StringUtils.join(filterParms, " AND ");
+ logger.info("Performing geowave query : " + filterString);
+
+ return getIteratorWrapper(filterString);
+ }
+
+ private CloseableIteration<Statement, QueryEvaluationException> getIteratorWrapper(final String filterString) {
+
+ return new CloseableIteration<Statement, QueryEvaluationException>() {
+
+ private CloseableIterator<SimpleFeature> featureIterator = null;
+
+ CloseableIterator<SimpleFeature> getIterator() throws QueryEvaluationException {
+ if (featureIterator == null) {
+ Filter cqlFilter;
+ try {
+ cqlFilter = ECQL.toFilter(filterString);
+ } catch (final CQLException e) {
+ logger.error("Error parsing query: " + filterString, e);
+ throw new QueryEvaluationException(e);
+ }
+
+ final CQLQuery cqlQuery = new CQLQuery(null, cqlFilter, featureDataAdapter);
+ final QueryOptions queryOptions = new QueryOptions(featureDataAdapter, index);
+
+ try {
+ featureIterator = geoWaveDataStore.query(queryOptions, cqlQuery);
+ } catch (final Exception e) {
+ logger.error("Error performing query: " + filterString, e);
+ throw new QueryEvaluationException(e);
+ }
+ }
+ return featureIterator;
+ }
+
+ @Override
+ public boolean hasNext() throws QueryEvaluationException {
+ return getIterator().hasNext();
+ }
+
+ @Override
+ public Statement next() throws QueryEvaluationException {
+ final SimpleFeature feature = getIterator().next();
+ final String subjectString = feature.getAttribute(SUBJECT_ATTRIBUTE).toString();
+ final String predicateString = feature.getAttribute(PREDICATE_ATTRIBUTE).toString();
+ final String objectString = feature.getAttribute(OBJECT_ATTRIBUTE).toString();
+ final Object context = feature.getAttribute(CONTEXT_ATTRIBUTE);
+ final String contextString = context != null ? context.toString() : "";
+ final Statement statement = StatementSerializer.readStatement(subjectString, predicateString, objectString, contextString);
+ return statement;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Remove not implemented");
+ }
+
+ @Override
+ public void close() throws QueryEvaluationException {
+ try {
+ getIterator().close();
+ } catch (final IOException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+ };
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryEquals(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("EQUALS", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryDisjoint(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("DISJOINT", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryIntersects(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("INTERSECTS", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryTouches(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("TOUCHES", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryCrosses(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("CROSSES", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryWithin(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("WITHIN", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryContains(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("CONTAINS", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryOverlaps(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("OVERLAPS", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryNear(final NearQuery query,
+ final StatementConstraints contraints) {
+ throw new UnsupportedOperationException("Near queries are not supported in Accumulo.");
+ }
+
+ @Override
+ public Set<URI> getIndexablePredicates() {
+ return validPredicates;
+ }
+
+ @Override
+ public void flush() throws IOException {
+ // TODO cache and flush features instead of writing them one at a time
+ }
+
+ @Override
+ public void close() throws IOException {
+ flush();
+ }
+
+
+ @Override
+ public String getTableName() {
+ return getTableName(conf);
+ }
+
+ /**
+ * Get the Accumulo table that will be used by this index.
+ * @param conf
+ * @return table name guaranteed to be used by instances of this index
+ */
+ public static String getTableName(final Configuration conf) {
+ return makeTableName( ConfigUtils.getTablePrefix(conf) );
+ }
+
+ /**
+ * Make the Accumulo table name used by this indexer for a specific instance of Rya.
+ *
+ * @param ryaInstanceName - The name of the Rya instance the table name is for. (not null)
+ * @return The Accumulo table name used by this indexer for a specific instance of Rya.
+ */
+ public static String makeTableName(final String ryaInstanceName) {
+ requireNonNull(ryaInstanceName);
+ return ryaInstanceName + TABLE_SUFFIX;
+ }
+
+ private void deleteStatements(final Collection<RyaStatement> ryaStatements) throws IOException {
+ // create a feature collection
+ final DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
+
+ for (final RyaStatement ryaStatement : ryaStatements) {
+ final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
+ // if the predicate list is empty, accept all predicates.
+ // Otherwise, make sure the predicate is on the "valid" list
+ final boolean isValidPredicate = validPredicates.isEmpty() || validPredicates.contains(statement.getPredicate());
+
+ if (isValidPredicate && (statement.getObject() instanceof Literal)) {
+ try {
+ final SimpleFeature feature = createFeature(featureType, statement);
+ featureCollection.add(feature);
+ } catch (final ParseException e) {
+ logger.warn("Error getting geo from statement: " + statement.toString(), e);
+ }
+ }
+ }
+
+ // remove this feature collection from the store
+ if (!featureCollection.isEmpty()) {
+ final Set<Identifier> featureIds = new HashSet<Identifier>();
+ final FilterFactory filterFactory = CommonFactoryFinder.getFilterFactory(null);
+ final Set<String> stringIds = DataUtilities.fidSet(featureCollection);
+ for (final String id : stringIds) {
+ featureIds.add(filterFactory.featureId(id));
+ }
+
+ final String filterString = stringIds.stream().collect(Collectors.joining("','", "'", "'"));
+
+ Filter filter = null;
+ try {
+ filter = ECQL.toFilter(GEO_ID_ATTRIBUTE + " IN (" + filterString + ")", filterFactory);
+ } catch (final CQLException e) {
+ logger.error("Unable to generate filter for deleting the statement.", e);
+ }
+
+ featureStore.removeFeatures(filter);
+ }
+ }
+
+
+ @Override
+ public void deleteStatement(final RyaStatement statement) throws IOException {
+ deleteStatements(Collections.singleton(statement));
+ }
+
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public void setConnector(final Connector connector) {
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ @Override
+ public void purge(final RdfCloudTripleStoreConfiguration configuration) {
+ // delete existing data
+ geoWaveDataStore.delete(new QueryOptions(), new EverythingQuery());
+ }
+
+ @Override
+ public void dropAndDestroy() {
+ }
+
+ /**
+ * The list of supported Geo Wave {@code LockingManagementFactory} types.
+ */
+ private static enum LockManagementType {
+ MEMORY("memory");
+
+ private final String name;
+
+ /**
+ * Creates a new {@link LockManagementType}.
+ * @param name the name of the type. (not {@code null})
+ */
+ private LockManagementType(final String name) {
+ this.name = checkNotNull(name);
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ /**
+ * The list of supported Geo Wave {@code AuthorizationFactorySPI } types.
+ */
+ private static enum AuthorizationManagementProviderType {
+ EMPTY("empty"),
+ JSON_FILE("jsonFile");
+
+ private final String name;
+
+ /**
+ * Creates a new {@link AuthorizationManagementProviderType}.
+ * @param name the name of the type. (not {@code null})
+ */
+ private AuthorizationManagementProviderType(final String name) {
+ this.name = checkNotNull(name);
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ /**
+ * The list of supported Geo Wave {@code IndexQueryStrategySPI} types.
+ */
+ private static enum QueryIndexStrategyType {
+ BEST_MATCH("Best Match"),
+ HEURISTIC_MATCH("Heuristic Match"),
+ PRESERVE_LOCALITY("Preserve Locality");
+
+ private final String name;
+
+ /**
+ * Creates a new {@link QueryIndexStrategyType}.
+ * @param name the name of the type. (not {@code null})
+ */
+ private QueryIndexStrategyType(final String name) {
+ this.name = checkNotNull(name);
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/accumulo/geo/GmlParser.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/accumulo/geo/GmlParser.java b/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/accumulo/geo/GmlParser.java
new file mode 100644
index 0000000..af72b3a
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/accumulo/geo/GmlParser.java
@@ -0,0 +1,48 @@
+/*
+ * 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 java.io.IOException;
+import java.io.Reader;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.rya.indexing.accumulo.geo.GeoParseUtils.GmlToGeometryParser;
+import org.geotools.gml3.GMLConfiguration;
+import org.xml.sax.SAXException;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+
+/**
+ * This wraps geotools parser for rya.geoCommon that cannot be dependent on geotools.
+ *
+ */
+public class GmlParser implements GmlToGeometryParser {
+
+ /* (non-Javadoc)
+ * @see org.apache.rya.indexing.accumulo.geo.GeoParseUtils.GmlToGeometryParser#parse(java.io.Reader)
+ */
+ @Override
+ public Geometry parse(Reader reader) throws IOException, SAXException, ParserConfigurationException {
+ final org.geotools.xml.Parser gmlParser = new org.geotools.xml.Parser(new GMLConfiguration());
+ return (Geometry) gmlParser.parse(reader);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/geoExamples/GeowaveDirectExample.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/geoExamples/GeowaveDirectExample.java b/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/geoExamples/GeowaveDirectExample.java
new file mode 100644
index 0000000..33a4bec
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geowave/src/main/java/org/apache/rya/indexing/geoExamples/GeowaveDirectExample.java
@@ -0,0 +1,445 @@
+package org.apache.rya.indexing.geoExamples;
+/*
+ * 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.List;
+import org.apache.commons.lang.Validate;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.rya.indexing.GeoIndexerType;
+import org.apache.rya.indexing.GeoRyaSailFactory;
+import org.apache.rya.indexing.accumulo.AccumuloIndexingConfiguration;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.accumulo.geo.OptionalConfigUtils;
+import org.apache.rya.indexing.external.PrecomputedJoinIndexerConfig;
+import org.apache.rya.indexing.external.PrecomputedJoinIndexerConfig.PrecomputedJoinStorageType;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.QueryEvaluationException;
+import org.openrdf.query.QueryLanguage;
+import org.openrdf.query.QueryResultHandlerException;
+import org.openrdf.query.TupleQuery;
+import org.openrdf.query.TupleQueryResultHandler;
+import org.openrdf.query.TupleQueryResultHandlerException;
+import org.openrdf.query.Update;
+import org.openrdf.query.UpdateExecutionException;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.repository.sail.SailRepositoryConnection;
+import org.openrdf.sail.Sail;
+
+public class GeowaveDirectExample {
+ private static final Logger log = Logger.getLogger(GeowaveDirectExample.class);
+
+ //
+ // Connection configuration parameters
+ //
+
+ private static final boolean USE_MOCK_INSTANCE = true;
+ private static final boolean PRINT_QUERIES = true;
+ private static final String INSTANCE = "instance";
+ private static final String RYA_TABLE_PREFIX = "x_test_triplestore_";
+ private static final String AUTHS = "U";
+
+ public static void main(final String[] args) throws Exception {
+ final Configuration conf = getConf();
+ conf.set(PrecomputedJoinIndexerConfig.PCJ_STORAGE_TYPE, PrecomputedJoinStorageType.ACCUMULO.name());
+ conf.setBoolean(ConfigUtils.DISPLAY_QUERY_PLAN, PRINT_QUERIES);
+ conf.setBoolean(OptionalConfigUtils.USE_GEO, true);
+ conf.setEnum(OptionalConfigUtils.GEO_INDEXER_TYPE, GeoIndexerType.GEO_WAVE);
+
+ log.info("Creating the tables as root.");
+
+ SailRepository repository = null;
+ SailRepositoryConnection conn = null;
+
+ try {
+ log.info("Connecting to Geo Sail Repository.");
+ final Sail extSail = GeoRyaSailFactory.getInstance(conf);
+ repository = new SailRepository(extSail);
+ conn = repository.getConnection();
+
+ final long start = System.currentTimeMillis();
+ log.info("Running SPARQL Example: Add Point and Geo Search with PCJ");
+ testAddPointAndWithinSearchWithPCJ(conn);
+ log.info("Running SPARQL Example: Temporal, Freetext, and Geo Search");
+ testTemporalFreeGeoSearch(conn);
+ log.info("Running SPARQL Example: Geo, Freetext, and PCJ Search");
+ testGeoFreetextWithPCJSearch(conn);
+ log.info("Running SPARQL Example: Delete Geo Data");
+ testDeleteGeoData(conn);
+
+ log.info("TIME: " + (System.currentTimeMillis() - start) / 1000.);
+ } finally {
+ log.info("Shutting down");
+ closeQuietly(conn);
+ closeQuietly(repository);
+ }
+ }
+
+ private static void closeQuietly(final SailRepository repository) {
+ if (repository != null) {
+ try {
+ repository.shutDown();
+ } catch (final RepositoryException e) {
+ // quietly absorb this exception
+ }
+ }
+ }
+
+ private static void closeQuietly(final SailRepositoryConnection conn) {
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (final RepositoryException e) {
+ // quietly absorb this exception
+ }
+ }
+ }
+
+ private static Configuration getConf() {
+
+
+ return AccumuloIndexingConfiguration.builder()
+ .setUseMockAccumulo(USE_MOCK_INSTANCE)
+ .setAuths(AUTHS)
+ .setAccumuloUser("root")
+ .setAccumuloPassword("")
+ .setAccumuloInstance(INSTANCE)
+ .setRyaPrefix(RYA_TABLE_PREFIX)
+ .setUsePcj(true)
+ .setUseAccumuloFreetextIndex(true)
+ .setUseAccumuloTemporalIndex(true)
+ .build();
+
+ }
+
+
+
+ private static void testAddPointAndWithinSearchWithPCJ(
+ final SailRepositoryConnection conn) throws Exception {
+
+ final String update = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "INSERT DATA { " //
+ + " <urn:feature> a geo:Feature ; " //
+ + " geo:hasGeometry [ " //
+ + " a geo:Point ; " //
+ + " geo:asWKT \"Point(-77.03524 38.889468)\"^^geo:wktLiteral "//
+ + " ] . " //
+ + "}";
+
+ final Update u = conn.prepareUpdate(QueryLanguage.SPARQL, update);
+ u.execute();
+
+ String queryString;
+ TupleQuery tupleQuery;
+ CountingResultHandler tupleHandler;
+
+ // point outside search ring
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt " //
+ + "{" //
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-77 39, -76 39, -76 38, -77 38, -77 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("point outside search ring, Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 0);
+ // point inside search ring
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt " // ?e ?l ?o" //
+ + "{" //
+// + " ?feature a ?e . "//
+// + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+// + " ?e <uri:talksTo> ?o . "//
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-78 39, -77 39, -77 38, -78 38, -78 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("point inside search ring, Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 1);
+
+ // point inside search ring with Pre-Computed Join
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt "//?e ?l ?o" //
+ + "{" //
+// + " ?feature a ?e . "//
+// + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+// + " ?e <uri:talksTo> ?o . "//
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-78 39, -77 39, -77 38, -78 38, -78 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("point inside search ring with Pre-Computed Join, Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() >= 1); // may see points from
+ // during previous runs
+
+ // point outside search ring with PCJ
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt "//?e ?l ?o " //
+ + "{" //
+// + " ?feature a ?e . "//
+// + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+// + " ?e <uri:talksTo> ?o . "//
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-77 39, -76 39, -76 38, -77 38, -77 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("point outside search ring with PCJ, Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 0);
+
+ // point inside search ring with different Pre-Computed Join
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point "//?wkt ?e ?c ?l ?o " //
+ + "{" //
+// + " ?e a ?c . "//
+// + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+ //+ " ?e <uri:talksTo> ?o . "//
+ //+ " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-78 39, -77 39, -77 38, -78 38, -78 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("point inside search ring with different Pre-Computed Join, Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 1);
+ }
+
+ private static void testTemporalFreeGeoSearch(
+ final SailRepositoryConnection conn)
+ throws MalformedQueryException, RepositoryException,
+ UpdateExecutionException, TupleQueryResultHandlerException,
+ QueryEvaluationException {
+ // Once upon a time, a meeting happened, in a place and time, attended by 5 paladins and another.
+ final String update = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "PREFIX time: <http://www.w3.org/2006/time#> "//
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> "//
+ + "PREFIX fts: <http://rdf.useekm.com/fts#> "//
+ + "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> "//
+ + "PREFIX ex: <http://example.com/#> "//
+ + "INSERT DATA { " //
+ + " ex:feature719 a geo:Feature ; " //
+ + " geo:hasGeometry [ " //
+ + " a geo:Point ; " //
+ + " geo:asWKT \"Point(-77.03524 38.889468)\"^^geo:wktLiteral "//
+ + " ] . "//
+ + " ex:event719 a time:Instant ;" //
+ + " time:inXSDDateTime '2001-01-01T01:01:04-08:00' ;" // 4 seconds
+ + " ex:locatedAt ex:feature719 ;" //
+ + " ex:attendee ex:person01;" //
+ + " ex:attendee ex:person02;" //
+ + " ex:attendee ex:person03;" //
+ + " ex:attendee [a ex:Person ; rdfs:label 'Paladin Ogier the Dane' ] ;" // Use a blank node instead of person04
+ + " ex:attendee ex:person05;" //
+ + " ex:attendee ex:person06." //
+ + " ex:person01 a ex:Person ;" //
+ + " rdfs:label \"Paladin Fossil\"." //
+ + " ex:person02 a ex:Person ;" //
+ + " rdfs:label \"Paladin Paul Denning\"." //
+ + " ex:person03 a ex:Person ;" //
+ + " rdfs:label 'Paladin Will Travel'." //
+ + " ex:person05 a ex:Person ;" //
+ + " rdfs:label 'Paladin dimethyl disulfide'." //
+ + " ex:person06 a ex:Person ;" //
+ + " rdfs:label 'Ignore me'." //
+ + "" //
+ + "}";
+ final Update u = conn.prepareUpdate(QueryLanguage.SPARQL, update);
+ u.execute();
+
+ String queryString;
+ TupleQuery tupleQuery;
+ CountingResultHandler tupleHandler;
+
+ // Find all events after a time, located in a polygon square, whose attendees have label names beginning with "Pal"
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "PREFIX time: <http://www.w3.org/2006/time#> "//
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> "//
+ + "PREFIX fts: <http://rdf.useekm.com/fts#> "//
+ + "PREFIX ex: <http://example.com/#> "//
+ + "SELECT ?feature ?point ?wkt ?event ?time ?person ?match" //
+ + "{" //
+ + " ?event a time:Instant ; \n"//
+ + " time:inXSDDateTime ?time ; \n"//
+ + " ex:locatedAt ?feature ;" //
+ + " ex:attendee ?person." //
+ + " FILTER(tempo:after(?time, '2001-01-01T01:01:03-08:00') ) \n"// after 3 seconds
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-78 39, -77 39, -77 38, -78 38, -78 39))\"^^geo:wktLiteral)). " //
+ + " ?person a ex:Person . "//
+ + " ?person <http://www.w3.org/2000/01/rdf-schema#label> ?match . "//
+ + " FILTER(fts:text(?match, \"Pal*\")) " //
+ + "}";//
+
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 5 );
+
+ }
+
+ private static void testGeoFreetextWithPCJSearch(
+ final SailRepositoryConnection conn)
+ throws MalformedQueryException, RepositoryException,
+ TupleQueryResultHandlerException, QueryEvaluationException {
+ // ring outside point
+ final String queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX fts: <http://rdf.useekm.com/fts#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt ?e ?c ?l ?o ?person ?match " //
+ + "{" //
+ + " ?person a <http://example.org/ontology/Person> . "//
+ + " ?person <http://www.w3.org/2000/01/rdf-schema#label> ?match . "//
+ + " FILTER(fts:text(?match, \"!alice & hose\")) " //
+ + " ?e a ?c . "//
+ + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+ + " ?e <uri:talksTo> ?o . "//
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-78 39, -77 39, -77 38, -78 38, -78 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+ final TupleQuery tupleQuery = conn.prepareTupleQuery(
+ QueryLanguage.SPARQL, queryString);
+ final CountingResultHandler tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 0);// TODO ==1 some data is missing for this query!
+ }
+
+
+
+ private static void testDeleteGeoData(final SailRepositoryConnection conn)
+ throws Exception {
+ // Delete all stored points
+ final String sparqlDelete = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "DELETE {\n" //
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + "}\n" + "WHERE { \n" + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + "}";//
+
+ final Update deleteUpdate = conn.prepareUpdate(QueryLanguage.SPARQL,
+ sparqlDelete);
+ deleteUpdate.execute();
+
+ String queryString;
+ TupleQuery tupleQuery;
+ CountingResultHandler tupleHandler;
+
+ // Find all stored points
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt " //
+ + "{" //
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + "}";//
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 0);
+ }
+
+ private static class CountingResultHandler implements
+ TupleQueryResultHandler {
+ private int count = 0;
+
+ public int getCount() {
+ return count;
+ }
+
+ public void resetCount() {
+ count = 0;
+ }
+
+ @Override
+ public void startQueryResult(final List<String> arg0)
+ throws TupleQueryResultHandlerException {
+ }
+
+ @Override
+ public void handleSolution(final BindingSet arg0)
+ throws TupleQueryResultHandlerException {
+ count++;
+ System.out.println(arg0);
+ }
+
+ @Override
+ public void endQueryResult() throws TupleQueryResultHandlerException {
+ }
+
+ @Override
+ public void handleBoolean(final boolean arg0)
+ throws QueryResultHandlerException {
+ }
+
+ @Override
+ public void handleLinks(final List<String> arg0)
+ throws QueryResultHandlerException {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveFeatureReaderTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveFeatureReaderTest.java b/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveFeatureReaderTest.java
new file mode 100644
index 0000000..f36a515
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveFeatureReaderTest.java
@@ -0,0 +1,384 @@
+/*
+ * 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.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/9e76b8d7/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGTQueryTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGTQueryTest.java b/extras/rya.geoindexing/geo.geowave/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGTQueryTest.java
new file mode 100644
index 0000000..778b5ef
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geowave/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
[13/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalExternalSetMatcherFactory.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalExternalSetMatcherFactory.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalExternalSetMatcherFactory.java
new file mode 100644
index 0000000..c4a287e
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalExternalSetMatcherFactory.java
@@ -0,0 +1,44 @@
+/**
+ * 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.geotemporal;
+
+import org.apache.rya.indexing.external.matching.AbstractExternalSetMatcherFactory;
+import org.apache.rya.indexing.external.matching.ExternalSetMatcher;
+import org.apache.rya.indexing.external.matching.JoinSegment;
+import org.apache.rya.indexing.external.matching.JoinSegmentMatcher;
+import org.apache.rya.indexing.external.matching.OptionalJoinSegment;
+import org.apache.rya.indexing.external.matching.OptionalJoinSegmentMatcher;
+import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
+
+/**
+ * Factory used to build {@link EntityQueryNodeMatcher}s for the {@link GeoTemporalIndexOptimizer}.
+ *
+ */
+public class GeoTemporalExternalSetMatcherFactory extends AbstractExternalSetMatcherFactory<EventQueryNode> {
+
+ @Override
+ protected ExternalSetMatcher<EventQueryNode> getJoinSegmentMatcher(final JoinSegment<EventQueryNode> segment) {
+ return new JoinSegmentMatcher<EventQueryNode>(segment, new GeoTemporalToSegmentConverter());
+ }
+
+ @Override
+ protected ExternalSetMatcher<EventQueryNode> getOptionalJoinSegmentMatcher(final OptionalJoinSegment<EventQueryNode> segment) {
+ return new OptionalJoinSegmentMatcher<EventQueryNode>(segment, new GeoTemporalToSegmentConverter());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexException.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexException.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexException.java
new file mode 100644
index 0000000..b2d4de5
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexException.java
@@ -0,0 +1,57 @@
+/**
+ * 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.geotemporal;
+
+import org.apache.rya.indexing.entity.model.TypedEntity;
+
+/**
+ * An operation over the {@link TypedEntity} index failed to complete.
+ */
+public class GeoTemporalIndexException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs a new exception with the specified detail message. The
+ * cause is not initialized, and may subsequently be initialized by
+ * a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public GeoTemporalIndexException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * {@code cause} is <i>not</i> automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public GeoTemporalIndexException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexSetProvider.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexSetProvider.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexSetProvider.java
new file mode 100644
index 0000000..bf12f26
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexSetProvider.java
@@ -0,0 +1,239 @@
+/**
+ * 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.geotemporal;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.log4j.Logger;
+import org.apache.rya.indexing.IndexingExpr;
+import org.apache.rya.indexing.IndexingFunctionRegistry;
+import org.apache.rya.indexing.IndexingFunctionRegistry.FUNCTION_TYPE;
+import org.apache.rya.indexing.accumulo.geo.GeoParseUtils;
+import org.apache.rya.indexing.accumulo.geo.GeoTupleSet;
+import org.apache.rya.indexing.external.matching.ExternalSetProvider;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
+import org.apache.rya.indexing.geotemporal.model.EventQueryNode.EventQueryNodeBuilder;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.openrdf.model.URI;
+import org.openrdf.model.impl.URIImpl;
+import org.openrdf.query.algebra.FunctionCall;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.Var;
+import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * Provides {@link GeoTupleSet}s.
+ */
+public class GeoTemporalIndexSetProvider implements ExternalSetProvider<EventQueryNode> {
+ private static final Logger LOG = Logger.getLogger(GeoTemporalIndexSetProvider.class);
+
+ //organzied by object var. Each object is a filter, or set of filters
+ private Multimap<Var, IndexingExpr> filterMap;
+
+ //organzied by subject var. Each subject is a GeoTemporalTupleSet
+ private Multimap<Var, StatementPattern> patternMap;
+
+ //filters that have not been constrained by statement patterns into indexing expressions yet.
+ private Multimap<Var, FunctionCall> unmatchedFilters;
+ //filters that have been used, to be used by the matcher later.
+ private Multimap<Var, FunctionCall> matchedFilters;
+
+ //organzied by object var. Used to find matches between unmatch filters and patterns
+ private Map<Var, StatementPattern> objectPatterns;
+
+
+ private static URI filterURI;
+
+ private final EventStorage eventStorage;
+
+ public GeoTemporalIndexSetProvider(final EventStorage eventStorage) {
+ this.eventStorage = requireNonNull(eventStorage);
+ }
+
+ @Override
+ public List<EventQueryNode> getExternalSets(final QuerySegment<EventQueryNode> node) {
+ filterMap = HashMultimap.create();
+ patternMap = HashMultimap.create();
+ unmatchedFilters = HashMultimap.create();
+ matchedFilters = HashMultimap.create();
+
+ objectPatterns = new HashMap<>();
+ //discover entities
+ buildMaps(node);
+ final List<EventQueryNode> nodes = createNodes();
+
+ return nodes;
+ }
+
+ private List<EventQueryNode> createNodes() {
+ final List<EventQueryNode> nodes = new ArrayList<>();
+ for(final Var subj : patternMap.keySet()) {
+ final EventQueryNode node = getGeoTemporalNode(subj);
+ if(node != null) {
+ nodes.add(node);
+ }
+ }
+ return nodes;
+ }
+
+ private EventQueryNode getGeoTemporalNode(final Var subj) {
+ final Collection<StatementPattern> patterns = patternMap.get(subj);
+ final Collection<FunctionCall> usedFilters = new ArrayList<>();
+ Optional<StatementPattern> geoPattern = Optional.empty();
+ Optional<StatementPattern> temporalPattern = Optional.empty();
+ Optional<Collection<IndexingExpr>> geoFilters = Optional.empty();
+ Optional<Collection<IndexingExpr>> temporalFilters = Optional.empty();
+
+ //should only be 2 patterns.
+ for(final StatementPattern sp : patterns) {
+ final Var obj = sp.getObjectVar();
+
+ ///filter map does not have -const-
+
+
+ if(filterMap.containsKey(obj)) {
+ final Collection<IndexingExpr> filters = filterMap.get(obj);
+ final IndexingFunctionRegistry.FUNCTION_TYPE type = ensureSameType(filters);
+ if(type != null && type == FUNCTION_TYPE.GEO) {
+ geoPattern = Optional.of(sp);
+ geoFilters = Optional.of(filters);
+ usedFilters.addAll(matchedFilters.get(obj));
+ } else if(type != null && type == FUNCTION_TYPE.TEMPORAL) {
+ temporalPattern = Optional.of(sp);
+ temporalFilters = Optional.of(filters);
+ usedFilters.addAll(matchedFilters.get(obj));
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ if(geoFilters.isPresent() && temporalFilters.isPresent() && geoPattern.isPresent() && temporalPattern.isPresent()) {
+ return new EventQueryNodeBuilder()
+ .setStorage(eventStorage)
+ .setGeoPattern(geoPattern.get())
+ .setTemporalPattern(temporalPattern.get())
+ .setGeoFilters(geoFilters.get())
+ .setTemporalFilters(temporalFilters.get())
+ .setUsedFilters(usedFilters)
+ .build();
+ } else {
+ return null;
+ }
+ }
+
+ private static FUNCTION_TYPE ensureSameType(final Collection<IndexingExpr> filters) {
+ FUNCTION_TYPE type = null;
+ for(final IndexingExpr filter : filters) {
+ if(type == null) {
+ type = IndexingFunctionRegistry.getFunctionType(filter.getFunction());
+ } else {
+ if(IndexingFunctionRegistry.getFunctionType(filter.getFunction()) != type) {
+ return null;
+ }
+ }
+ }
+ return type;
+ }
+
+ private void buildMaps(final QuerySegment<EventQueryNode> node) {
+ final List<QueryModelNode> unused = new ArrayList<>();
+ for (final QueryModelNode pattern : node.getOrderedNodes()) {
+ if(pattern instanceof FunctionCall) {
+ discoverFilter((FunctionCall) pattern, unused);
+ }
+ if(pattern instanceof StatementPattern) {
+ discoverPatterns((StatementPattern) pattern, unused);
+ }
+ }
+ }
+
+ private void discoverFilter(final FunctionCall filter, final List<QueryModelNode> unmatched) {
+ try {
+ filter.visit(new FilterVisitor());
+ } catch (final Exception e) {
+ LOG.error("Failed to match the filter object.", e);
+ }
+ }
+
+ private void discoverPatterns(final StatementPattern pattern, final List<QueryModelNode> unmatched) {
+ final Var subj = pattern.getSubjectVar();
+ final Var objVar = pattern.getObjectVar();
+
+ patternMap.put(subj, pattern);
+ objectPatterns.put(objVar, pattern);
+ //check for existing filters.
+ if(unmatchedFilters.containsKey(objVar)) {
+ final Collection<FunctionCall> calls = unmatchedFilters.removeAll(objVar);
+ for(final FunctionCall call : calls) {
+ addFilter(call);
+ matchedFilters.put(objVar, call);
+ }
+ }
+ }
+
+ @Override
+ public Iterator<List<EventQueryNode>> getExternalSetCombos(final QuerySegment<EventQueryNode> segment) {
+ final List<List<EventQueryNode>> comboList = new ArrayList<>();
+ comboList.add(getExternalSets(segment));
+ return comboList.iterator();
+ }
+
+ private void addFilter(final FunctionCall call) {
+ filterURI = new URIImpl(call.getURI());
+ final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, call.getArgs());
+ filterMap.put(objVar, new IndexingExpr(filterURI, objectPatterns.get(objVar), GeoParseUtils.extractArguments(objVar.getName(), call)));
+ }
+
+ /**
+ * Finds the object/function in a Filter. If the associated statement pattern
+ * has been found, creates the {@link IndexingExpr} and adds it to the map.
+ */
+ private class FilterVisitor extends QueryModelVisitorBase<Exception> {
+ @Override
+ public void meet(final FunctionCall call) throws Exception {
+ filterURI = new URIImpl(call.getURI());
+ final FUNCTION_TYPE type = IndexingFunctionRegistry.getFunctionType(filterURI);
+ if(type == FUNCTION_TYPE.GEO || type == FUNCTION_TYPE.TEMPORAL) {
+ final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, call.getArgs());
+ if(objectPatterns.containsKey(objVar)) {
+ filterMap.put(objVar, new IndexingExpr(filterURI, objectPatterns.get(objVar), GeoParseUtils.extractArguments(objVar.getName(), call)));
+ matchedFilters.put(objVar, call);
+ } else {
+ unmatchedFilters.put(objVar, call);
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexer.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexer.java
new file mode 100644
index 0000000..106588b
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexer.java
@@ -0,0 +1,197 @@
+/**
+ * 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.geotemporal;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.rya.api.persist.index.RyaSecondaryIndexer;
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.impl.URIImpl;
+
+/**
+ * A repository to store, index, and retrieve {@link Statement}s based on geotemporal features.
+ */
+public interface GeoTemporalIndexer extends RyaSecondaryIndexer {
+ /**
+ * initialize after setting configuration.
+ */
+ public void init();
+
+ /**
+ * Creates the {@link Eventtorage} that will be used by the indexer.
+ *
+ * @param conf - Indicates how the {@link EventStorage} is initialized. (not null)
+ * @return The {@link EventStorage} that will be used by this indexer.
+ */
+ public abstract EventStorage getEventStorage(final Configuration conf);
+
+ /**
+ * Used to indicate which geo filter functions to use in a query.
+ */
+ public static enum GeoPolicy {
+ /**
+ * The provided geo object equals the geo object where the event took place.
+ */
+ EQUALS(GeoConstants.GEO_SF_EQUALS),
+
+ /**
+ * The provided geo object does not share any space with the event.
+ */
+ DISJOINT(GeoConstants.GEO_SF_DISJOINT),
+
+ /**
+ * The provided geo object shares some amount of space with the event.
+ */
+ INTERSECTS(GeoConstants.GEO_SF_INTERSECTS),
+
+ /**
+ * The provided geo object shares a point with the event, but only on the edge.
+ */
+ TOUCHES(GeoConstants.GEO_SF_TOUCHES),
+
+ /**
+ * The provided geo object shares some, but not all space with the event.
+ */
+ CROSSES(GeoConstants.GEO_SF_CROSSES),
+
+ /**
+ * The provided geo object exists completely within the event.
+ */
+ WITHIN(GeoConstants.GEO_SF_WITHIN),
+
+ /**
+ * The event took place completely within the provided geo object.
+ */
+ CONTAINS(GeoConstants.GEO_SF_CONTAINS),
+
+ /**
+ * The provided geo object has some but not all points in common with the event,
+ * are of the same dimension, and the intersection of the interiors has the
+ * same dimension as the geometries themselves.
+ */
+ OVERLAPS(GeoConstants.GEO_SF_OVERLAPS);
+
+ private final URI uri;
+
+ private GeoPolicy(final URI uri) {
+ this.uri = uri;
+ }
+
+ public URI getURI() {
+ return uri;
+ }
+
+ public static GeoPolicy fromURI(final URI uri) {
+ for(final GeoPolicy policy : GeoPolicy.values()) {
+ if(policy.getURI().equals(uri)) {
+ return policy;
+ }
+ }
+ return null;
+ }
+ }
+
+ static final String TEMPORAL_NS = "tag:rya-rdf.org,2015:temporal#";
+ /**
+ * Used to indicate which temporal filter functions to use in a query.
+ */
+ public enum TemporalPolicy {
+ /**
+ * The provided instant in time equals the instant the event took place.
+ */
+ INSTANT_EQUALS_INSTANT(true, new URIImpl(TEMPORAL_NS+"equals")),
+
+ /**
+ * The provided instant in time was before when the event took place.
+ */
+ INSTANT_BEFORE_INSTANT(true, new URIImpl(TEMPORAL_NS+"before")),
+
+ /**
+ * The provided instant in time was after when the event took place.
+ */
+ INSTANT_AFTER_INSTANT(true, new URIImpl(TEMPORAL_NS+"after")),
+
+ /**
+ * The provided instant in time was before a time period.
+ */
+ INSTANT_BEFORE_INTERVAL(false, new URIImpl(TEMPORAL_NS+"beforeInterval")),
+
+ /**
+ * The provided instant in time took place within a set of time.
+ */
+ INSTANT_IN_INTERVAL(false, new URIImpl(TEMPORAL_NS+"insideInterval")),
+
+ /**
+ * The provided instant in time took place after a time period.
+ */
+ INSTANT_AFTER_INTERVAL(false, new URIImpl(TEMPORAL_NS+"afterInterval")),
+
+ /**
+ * The provided instant in time equals the start of the interval in which the event took place.
+ */
+ INSTANT_START_INTERVAL(false, new URIImpl(TEMPORAL_NS+"hasBeginningInterval")),
+
+ /**
+ * The provided instant in time equals the end of the interval in which the event took place.
+ */
+ INSTANT_END_INTERVAL(false, new URIImpl(TEMPORAL_NS+"hasEndInterval")),
+
+ /**
+ * The provided interval equals the interval in which the event took place.
+ */
+ INTERVAL_EQUALS(false, new URIImpl(TEMPORAL_NS+"intervalEquals")),
+
+ /**
+ * The provided interval is before the interval in which the event took place.
+ */
+ INTERVAL_BEFORE(false, new URIImpl(TEMPORAL_NS+"intervalBefore")),
+
+ /**
+ * The provided interval is after the interval in which the event took place.
+ */
+ INTERVAL_AFTER(false, new URIImpl(TEMPORAL_NS+"intervalAfter"));
+
+ private final boolean isInstant;
+ private final URI uri;
+
+ TemporalPolicy(final boolean isInstant, final URI uri) {
+ this.isInstant = isInstant;
+ this.uri = uri;
+ }
+
+ public boolean isInstant(){
+ return isInstant;
+ }
+
+ public URI getURI() {
+ return uri;
+ }
+
+ public static TemporalPolicy fromURI(final URI uri) {
+ for(final TemporalPolicy policy : TemporalPolicy.values()) {
+ if(policy.getURI().equals(uri)) {
+ return policy;
+ }
+ }
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexerFactory.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexerFactory.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexerFactory.java
new file mode 100644
index 0000000..f4df8bc
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexerFactory.java
@@ -0,0 +1,57 @@
+/**
+ * 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.geotemporal;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.rya.indexing.GeoEnabledFilterFunctionOptimizer;
+import org.apache.rya.indexing.GeoIndexer;
+import org.apache.rya.indexing.GeoIndexerType;
+import org.apache.rya.indexing.GeoTemporalIndexerType;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.apache.rya.mongodb.MongoSecondaryIndex;
+
+/**
+ * Factory for retrieving a {@link GeoTemporalIndexer} based on a provided {@link Configuration}.
+ */
+public class GeoTemporalIndexerFactory {
+ /**
+ * Creates and returns a {@link GeoTemporalIndexer}.
+ * @param conf - The {@link Configuration} to base the {@link GeoTemporalIndexer} on.
+ * @return The created {@link GeoTemporalIndexer}.
+ */
+ public GeoTemporalIndexer getIndexer(final Configuration conf) {
+ if(ConfigUtils.getUseMongo(conf)) {
+ final MongoDBRdfConfiguration config = new MongoDBRdfConfiguration(conf);
+ for(final MongoSecondaryIndex index : config.getAdditionalIndexers()) {
+ if(index instanceof GeoTemporalIndexer) {
+ return (GeoTemporalIndexer) index;
+ }
+ }
+ /* Created a MongoGeoTemporalIndexer */
+ final GeoTemporalIndexer index = GeoEnabledFilterFunctionOptimizer.instantiate(GeoTemporalIndexerType.MONGO_GEO_TEMPORAL.getGeoTemporalIndexerClassString(), GeoTemporalIndexer.class);
+ index.setConf(conf);
+ index.init();
+ return index;
+ } else {
+ //TODO: add Accumulo here.
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalOptimizer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalOptimizer.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalOptimizer.java
new file mode 100644
index 0000000..d626adc
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalOptimizer.java
@@ -0,0 +1,69 @@
+/*
+ * 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.geotemporal;
+
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.rya.indexing.external.matching.AbstractExternalSetOptimizer;
+import org.apache.rya.indexing.external.matching.ExternalSetMatcher;
+import org.apache.rya.indexing.external.matching.ExternalSetProvider;
+import org.apache.rya.indexing.external.matching.QueryNodeListRater;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
+
+import com.google.common.base.Optional;
+
+
+public class GeoTemporalOptimizer extends AbstractExternalSetOptimizer<EventQueryNode> implements Configurable {
+ private static final GeoTemporalExternalSetMatcherFactory MATCHER_FACTORY = new GeoTemporalExternalSetMatcherFactory();
+
+ private GeoTemporalIndexer indexer;
+ private GeoTemporalIndexSetProvider provider;
+ private Configuration conf;
+
+ @Override
+ public void setConf(final Configuration conf) {
+ this.conf = conf;
+ final GeoTemporalIndexerFactory factory = new GeoTemporalIndexerFactory();
+ indexer = factory.getIndexer(conf);
+
+ //conf here does not matter since EventStorage has already been set in the indexer.
+ provider = new GeoTemporalIndexSetProvider(indexer.getEventStorage(conf));
+ }
+
+ @Override
+ public Configuration getConf() {
+ return conf;
+ }
+
+ @Override
+ protected ExternalSetMatcher<EventQueryNode> getMatcher(final QuerySegment<EventQueryNode> segment) {
+ return MATCHER_FACTORY.getMatcher(segment);
+ }
+
+ @Override
+ protected ExternalSetProvider<EventQueryNode> getProvider() {
+ return provider;
+ }
+
+ @Override
+ protected Optional<QueryNodeListRater> getNodeListRater(final QuerySegment<EventQueryNode> segment) {
+ return null;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalToSegmentConverter.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalToSegmentConverter.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalToSegmentConverter.java
new file mode 100644
index 0000000..22bfdb1
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalToSegmentConverter.java
@@ -0,0 +1,51 @@
+/**
+ * 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.geotemporal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.rya.indexing.external.matching.ExternalSetConverter;
+import org.apache.rya.indexing.external.matching.JoinSegment;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
+import org.openrdf.query.algebra.Filter;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.ValueExpr;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Implementation of {@link ExternalSetConverter} to convert {@link EventQueryNode}s
+ * to {@link QuerySegment}s.
+ *
+ */
+public class GeoTemporalToSegmentConverter implements ExternalSetConverter<EventQueryNode> {
+ @Override
+ public QuerySegment<EventQueryNode> setToSegment(final EventQueryNode set) {
+ Preconditions.checkNotNull(set);
+ final Set<QueryModelNode> matched = new HashSet<>(set.getPatterns());
+ matched.addAll(set.getFilters());
+ final List<QueryModelNode> unmatched = new ArrayList<>(set.getPatterns());
+ return new JoinSegment<EventQueryNode>(matched, unmatched, new HashMap<ValueExpr, Filter>());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/model/Event.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/model/Event.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/model/Event.java
new file mode 100644
index 0000000..4c50bfb
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/model/Event.java
@@ -0,0 +1,218 @@
+/**
+ * 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.geotemporal.model;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInterval;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
+
+/**
+ * Query object for a {@link GeoTemporalIndexer}.
+ * Defines a {@link Geometry}, either a {@link TemporalInstant} or
+ * {@link TemporalInterval}, and a triple Subject.
+ */
+public class Event {
+ private final Optional<Geometry> geometry;
+ private final Optional<TemporalInstant> instant;
+ private final Optional<TemporalInterval> interval;
+ private final RyaURI subject;
+
+ private final boolean isInstant;
+
+ /**
+ * Creates a new {@link Event} query object with a {@link TemporalInstant}.
+ * @param geo - The {@link Geometry} to use when querying.
+ * @param instant - The {@link TemporalInstant} to use when querying.
+ * @param subject - The Subject that both statements must have when querying.
+ */
+ private Event(final Geometry geo, final TemporalInstant instant, final RyaURI subject) {
+ this.subject = requireNonNull(subject);
+
+ //these fields are nullable since they are filled field by field.
+ this.instant = Optional.ofNullable(instant);
+ geometry = Optional.ofNullable(geo);
+ isInstant = true;
+ interval = Optional.empty();
+ }
+
+ /**
+ * Creates a new {@link Event} query object with a {@link TemporalInterval}.
+ * @param geo - The {@link Geometry} to use when querying.
+ * @param interval - The {@link TemporalInterval} to use when querying.
+ * @param subject - The Subject that both statements must have when querying.
+ */
+ private Event(final Geometry geo, final TemporalInterval interval, final RyaURI subject) {
+ this.subject = requireNonNull(subject);
+
+ //these fields are nullable since they are filled field by field.
+ this.interval = Optional.ofNullable(interval);
+ geometry = Optional.ofNullable(geo);
+ isInstant = false;
+ instant = Optional.empty();
+ }
+
+ /**
+ * @return Whether or not the query object uses a {@link TemporalInstant}.
+ */
+ public boolean isInstant() {
+ return isInstant;
+ }
+
+ /**
+ * @return The {@link Geometry} to use when querying.
+ */
+ public Optional<Geometry> getGeometry() {
+ return geometry;
+ }
+
+ /**
+ * @return The {@link TemporalInstant} to use when querying.
+ */
+ public Optional<TemporalInstant> getInstant() {
+ return instant;
+ }
+
+ /**
+ * @return The {@link TemporalInterval} to use when querying.
+ */
+ public Optional<TemporalInterval> getInterval() {
+ return interval;
+ }
+
+ /**
+ * @return The statement subject.
+ */
+ public RyaURI getSubject() {
+ return subject;
+ }
+
+ @Override
+ public int hashCode() {
+ if(isInstant) {
+ return Objects.hash(subject, geometry, instant);
+ } else {
+ return Objects.hash(subject, geometry, interval);
+ }
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if(this == o) {
+ return true;
+ }
+ if(o instanceof Event) {
+ final Event event = (Event) o;
+ return Objects.equals(subject, event.subject) &&
+ Objects.equals(isInstant, event.isInstant) &&
+ (isInstant ? Objects.equals(instant, event.instant) : Objects.equals(interval, event.interval));
+ }
+ return false;
+ }
+
+ public static Builder builder(final Event event) {
+ final Builder builder = new Builder()
+ .setSubject(event.getSubject());
+ if(event.getGeometry().isPresent()) {
+ builder.setGeometry(event.getGeometry().get());
+ }
+ if(event.isInstant()) {
+ if(event.getInstant().isPresent()) {
+ builder.setTemporalInstant(event.getInstant().get());
+ }
+ } else {
+ if(event.getInterval().isPresent()) {
+ builder.setTemporalInterval(event.getInterval().get());
+ }
+ }
+ return builder;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builds instances of {@link Event}.
+ */
+ @DefaultAnnotation(NonNull.class)
+ public static class Builder {
+ private RyaURI subject;
+ private Geometry geo;
+ private TemporalInstant instant;
+ private TemporalInterval interval;
+
+ /**
+ * Sets the {@link RyaURI} subject.
+ * @param subject - The subject to key on the event.
+ */
+ public Builder setSubject(final RyaURI subject) {
+ this.subject = subject;
+ return this;
+ }
+
+ /**
+ * Sets the {@link Geometry}.
+ * @param geo - The geometry.
+ */
+ public Builder setGeometry(final Geometry geo) {
+ this.geo = geo;
+ return this;
+ }
+
+ /**
+ * Sets the {@link TemporalInterval}.
+ * @param interval - The interval.
+ */
+ public Builder setTemporalInterval(final TemporalInterval interval) {
+ this.interval = interval;
+ return this;
+ }
+
+ /**
+ * Sets the {@link TemporalInstant}.
+ * @param instant - The instant.
+ */
+ public Builder setTemporalInstant(final TemporalInstant instant) {
+ this.instant = instant;
+ return this;
+ }
+
+ /**
+ * @return The new {@link Event}.
+ */
+ public Event build() {
+ if(instant == null) {
+ return new Event(geo, interval, subject);
+ } else {
+ return new Event(geo, instant, subject);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/model/EventQueryNode.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/model/EventQueryNode.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/model/EventQueryNode.java
new file mode 100644
index 0000000..104fca8
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/model/EventQueryNode.java
@@ -0,0 +1,372 @@
+/*
+ * 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.geotemporal.model;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.IndexingExpr;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.entity.query.EntityQueryNode;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.apache.rya.indexing.mongodb.update.RyaObjectStorage.ObjectStorageException;
+import org.apache.rya.rdftriplestore.evaluation.ExternalBatchingIterator;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.openrdf.model.Value;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.QueryEvaluationException;
+import org.openrdf.query.algebra.FunctionCall;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.Var;
+import org.openrdf.query.algebra.evaluation.impl.ExternalSet;
+import org.openrdf.query.algebra.evaluation.iterator.CollectionIteration;
+import org.openrdf.query.impl.MapBindingSet;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+import info.aduna.iteration.CloseableIteration;
+
+public class EventQueryNode extends ExternalSet implements ExternalBatchingIterator {
+ private final Collection<FunctionCall> usedFilters;
+ private final Collection<IndexingExpr> geoFilters;
+ private final Collection<IndexingExpr> temporalFilters;
+
+ private final StatementPattern geoPattern;
+ private final StatementPattern temporalPattern;
+
+ //Information about the subject of the patterns.
+ private final boolean subjectIsConstant;
+ private final Optional<String> subjectVar;
+ //not final because if the subject is a variable and the evaluate() is
+ // provided a binding set that contains the subject, this optional is used.
+ private Optional<String> subjectConstant;
+
+ //since and EventQueryNode exists in a single segment, all binding names are garunteed to be assured.
+ private final Set<String> bindingNames;
+
+ private Collection<StatementPattern> patterns;
+
+ private final EventStorage eventStore;
+
+ /**
+ * Constructs an instance of {@link EventQueryNode}.
+ * @param usedFilters
+ *
+ * @param type - The type of {@link Event} this node matches. (not null)
+ * @param patterns - The query StatementPatterns that are solved using an
+ * Event of the Type. (not null)
+ * @param entities - The {@link EventStorage} that will be searched to match
+ * {@link BindingSet}s when evaluating a query. (not null)
+ */
+ private EventQueryNode(final EventStorage eventStore, final StatementPattern geoPattern, final StatementPattern temporalPattern, final Collection<IndexingExpr> geoFilters, final Collection<IndexingExpr> temporalFilters, final Collection<FunctionCall> usedFilters) throws IllegalStateException {
+ this.geoPattern = requireNonNull(geoPattern);
+ this.temporalPattern = requireNonNull(temporalPattern);
+ this.geoFilters = requireNonNull(geoFilters);
+ this.temporalFilters = requireNonNull(temporalFilters);
+ this.eventStore = requireNonNull(eventStore);
+ this.usedFilters = requireNonNull(usedFilters);
+ bindingNames = new HashSet<>();
+
+ // Subject based preconditions.
+ verifySameSubjects(getPatterns());
+ // Predicate based preconditions.
+ verifyAllPredicatesAreConstants(getPatterns());
+
+ // The Subject may either be constant or a variable.
+ final Var subject = patterns.iterator().next().getSubjectVar();
+ subjectIsConstant = subject.isConstant();
+ if(subjectIsConstant) {
+ subjectConstant = Optional.of( subject.getValue().toString() );
+ subjectVar = Optional.empty();
+ } else {
+ subjectConstant = Optional.empty();
+ subjectVar = Optional.of( subject.getName() );
+ }
+ }
+
+ @Override
+ public Set<String> getBindingNames() {
+ return bindingNames;
+ }
+
+ @Override
+ public Set<String> getAssuredBindingNames() {
+ return bindingNames;
+ }
+
+ /**
+ * Verify the Subject for all of the patterns is the same.
+ *
+ * @param patterns - The patterns to check.
+ * @throws IllegalStateException If all of the Subjects are not the same.
+ */
+ private static void verifySameSubjects(final Collection<StatementPattern> patterns) throws IllegalStateException {
+ requireNonNull(patterns);
+
+ final Iterator<StatementPattern> it = patterns.iterator();
+ final Var subject = it.next().getSubjectVar();
+
+ while(it.hasNext()) {
+ final StatementPattern pattern = it.next();
+ if(!pattern.getSubjectVar().equals(subject)) {
+ throw new IllegalStateException("At least one of the patterns has a different subject from the others. " +
+ "All subjects must be the same.");
+ }
+ }
+ }
+
+ /**
+ * Verifies all of the Statement Patterns have Constants for their predicates.
+ *
+ * @param patterns - The patterns to check. (not null)
+ * @throws IllegalStateException A pattern has a variable predicate.
+ */
+ private static void verifyAllPredicatesAreConstants(final Collection<StatementPattern> patterns) throws IllegalStateException {
+ requireNonNull(patterns);
+
+ for(final StatementPattern pattern : patterns) {
+ if(!pattern.getPredicateVar().isConstant()) {
+ throw new IllegalStateException("The Predicate of a Statement Pattern must be constant. Pattern: " + pattern);
+ }
+ }
+ }
+
+ @Override
+ public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(final BindingSet bindings) throws QueryEvaluationException {
+ final List<BindingSet> list = new ArrayList<>();
+ try {
+ final Collection<Event> searchEvents;
+ final String subj;
+ //if the provided binding set has the subject already, set it to the constant subject.
+ if(!subjectConstant.isPresent() && bindings.hasBinding(subjectVar.get())) {
+ subjectConstant = Optional.of(bindings.getValue(subjectVar.get()).stringValue());
+ } else if(bindings.size() != 0) {
+ list.add(bindings);
+ }
+
+ // If the subject needs to be filled in, check if the subject variable is in the binding set.
+ if(subjectConstant.isPresent()) {
+ // if it is, fetch that value and then fetch the entity for the subject.
+ subj = subjectConstant.get();
+ searchEvents = eventStore.search(Optional.of(new RyaURI(subj)), Optional.of(geoFilters), Optional.of(temporalFilters));
+ } else {
+ searchEvents = eventStore.search(Optional.empty(), Optional.of(geoFilters), Optional.of(temporalFilters));
+ }
+
+ for(final Event event : searchEvents) {
+ final MapBindingSet resultSet = new MapBindingSet();
+ if(event.getGeometry().isPresent()) {
+ final Geometry geo = event.getGeometry().get();
+ final Value geoValue = ValueFactoryImpl.getInstance().createLiteral(geo.toText());
+ final Var geoObj = geoPattern.getObjectVar();
+ resultSet.addBinding(geoObj.getName(), geoValue);
+ }
+
+ final Value temporalValue;
+ if(event.isInstant() && event.getInstant().isPresent()) {
+ final Optional<TemporalInstant> opt = event.getInstant();
+ DateTime dt = opt.get().getAsDateTime();
+ dt = dt.toDateTime(DateTimeZone.UTC);
+ final String str = dt.toString(TemporalInstantRfc3339.FORMATTER);
+ temporalValue = ValueFactoryImpl.getInstance().createLiteral(str);
+ } else if(event.getInterval().isPresent()) {
+ temporalValue = ValueFactoryImpl.getInstance().createLiteral(event.getInterval().get().getAsPair());
+ } else {
+ temporalValue = null;
+ }
+
+ if(temporalValue != null) {
+ final Var temporalObj = temporalPattern.getObjectVar();
+ resultSet.addBinding(temporalObj.getName(), temporalValue);
+ }
+ list.add(resultSet);
+ }
+ } catch (final ObjectStorageException e) {
+ throw new QueryEvaluationException("Failed to evaluate the binding set", e);
+ }
+ return new CollectionIteration<>(list);
+ }
+
+ public Collection<IndexingExpr> getGeoFilters() {
+ return geoFilters;
+ }
+
+ public Collection<IndexingExpr> getTemporalFilters() {
+ return temporalFilters;
+ }
+
+ public Collection<FunctionCall> getFilters() {
+ return usedFilters;
+ }
+
+ public Collection<StatementPattern> getPatterns() {
+ if(patterns == null) {
+ patterns = new ArrayList<>();
+ patterns.add(geoPattern);
+ patterns.add(temporalPattern);
+ }
+ return patterns;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(subjectIsConstant,
+ subjectVar,
+ geoFilters,
+ temporalFilters,
+ geoPattern,
+ temporalPattern,
+ bindingNames,
+ eventStore);
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ if(other instanceof EventQueryNode) {
+ final EventQueryNode otherNode = (EventQueryNode)other;
+ return new EqualsBuilder()
+ .append(subjectIsConstant, otherNode.subjectIsConstant)
+ .append(subjectVar, otherNode.subjectVar)
+ .append(geoFilters, otherNode.geoFilters)
+ .append(geoPattern, otherNode.geoPattern)
+ .append(temporalFilters, otherNode.temporalFilters)
+ .append(temporalPattern, otherNode.temporalPattern)
+ .append(bindingNames, otherNode.bindingNames)
+ .append(subjectConstant, otherNode.subjectConstant)
+ .isEquals();
+ }
+ return false;
+ }
+
+ @Override
+ public EventQueryNode clone() {
+ return new EventQueryNode(eventStore, geoPattern, temporalPattern, geoFilters, temporalFilters, usedFilters);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Geo Pattern: " + geoPattern.toString());
+ sb.append("\n--Geo Filters--\n");
+ for(final IndexingExpr filter : geoFilters) {
+ sb.append(filter.toString());
+ sb.append("\n");
+ }
+ sb.append("\n-------------------\n");
+ sb.append("Temporal Pattern: " + temporalPattern.toString());
+ sb.append("\n--Temporal Filters--\n");
+ for(final IndexingExpr filter : temporalFilters) {
+ sb.append(filter.toString());
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(final Collection<BindingSet> bindingset)
+ throws QueryEvaluationException {
+ return null;
+ }
+
+ /**
+ * Builder for {@link EventQueryNode}s.
+ */
+ public static class EventQueryNodeBuilder {
+ private EventStorage store;
+ private StatementPattern geoPattern;
+ private StatementPattern temporalPattern;
+ private Collection<IndexingExpr> geoFilters;
+ private Collection<IndexingExpr> temporalFilters;
+ private Collection<FunctionCall> usedFilters;
+
+ /**
+ * @param store - The {@link EventStorage} to use in the {@link EntityQueryNode}
+ * @return - The Builder.
+ */
+ public EventQueryNodeBuilder setStorage(final EventStorage store) {
+ this.store = store;
+ return this;
+ }
+
+ /**
+ * @param geoPattern - The geo {@link StatementPattern} to use in the {@link EntityQueryNode}
+ * @return - The Builder.
+ */
+ public EventQueryNodeBuilder setGeoPattern(final StatementPattern geoPattern) {
+ this.geoPattern = geoPattern;
+ return this;
+ }
+
+ /**
+ * @param temporalPattern - The temporal {@link StatementPattern} to use in the {@link EntityQueryNode}
+ * @return - The Builder.
+ */
+ public EventQueryNodeBuilder setTemporalPattern(final StatementPattern temporalPattern) {
+ this.temporalPattern = temporalPattern;
+ return this;
+ }
+
+ /**
+ * @param geoFilters - The geo filter(s) {@link IndexingExpr} to use in the {@link EntityQueryNode}
+ * @return - The Builder.
+ */
+ public EventQueryNodeBuilder setGeoFilters(final Collection<IndexingExpr> geoFilters) {
+ this.geoFilters = geoFilters;
+ return this;
+ }
+
+ /**
+ * @param temporalFilters - The temporal filter(s) {@link IndexingExpr} to use in the {@link EntityQueryNode}
+ * @return - The Builder.
+ */
+ public EventQueryNodeBuilder setTemporalFilters(final Collection<IndexingExpr> temporalFilters) {
+ this.temporalFilters = temporalFilters;
+ return this;
+ }
+
+ /**
+ * @param usedFilters - The filter(s) used by the {@link EntityQueryNode}
+ * @return - The Builder.
+ */
+ public EventQueryNodeBuilder setUsedFilters(final Collection<FunctionCall> usedFilters) {
+ this.usedFilters = usedFilters;
+ return this;
+ }
+
+ /**
+ * @return The {@link EntityQueryNode} built by the builder.
+ */
+ public EventQueryNode build() {
+ return new EventQueryNode(store, geoPattern, temporalPattern, geoFilters, temporalFilters, usedFilters);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/storage/EventStorage.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/storage/EventStorage.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/storage/EventStorage.java
new file mode 100644
index 0000000..47c18a0
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/geotemporal/storage/EventStorage.java
@@ -0,0 +1,130 @@
+/**
+ * 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.geotemporal.storage;
+
+import java.util.Collection;
+import java.util.Optional;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.IndexingExpr;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.mongodb.update.RyaObjectStorage;
+
+public interface EventStorage extends RyaObjectStorage<Event> {
+ /**
+ * Search for {@link Event}s from the storage by its subject.
+ * Will query based on present parameters.
+ *
+ * @param subject - The subject key to find events.
+ * @param geoFilters - The geo filters to find Events.
+ * @param temporalFilters - The temporal filters to find Events.
+ * @return The {@link Event}, if one exists for the subject.
+ * @throws ObjectStorageException A problem occurred while fetching the Entity from the storage.
+ */
+ public Collection<Event> search(final Optional<RyaURI> subject, Optional<Collection<IndexingExpr>> geoFilters, Optional<Collection<IndexingExpr>> temporalFilters) throws ObjectStorageException;
+
+ /**
+ * Indicates a problem while interacting with an {@link EventStorage}.
+ */
+ public static class EventStorageException extends ObjectStorageException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs a new exception with the specified detail message. The
+ * cause is not initialized, and may subsequently be initialized by
+ * a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public EventStorageException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * {@code cause} is <i>not</i> automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public EventStorageException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+ }
+
+ /**
+ * An {@link Event} could not be created because one already exists for the Subject.
+ */
+ public static class EventAlreadyExistsException extends EventStorageException {
+ private static final long serialVersionUID = 1L;
+
+ public EventAlreadyExistsException(final String message) {
+ super(message);
+ }
+
+ public EventAlreadyExistsException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+ }
+
+ /**
+ * An {@link TypedEvent} could not be updated because the old state does not
+ * match the current state.
+ */
+ public static class StaleUpdateException extends EventStorageException {
+ private static final long serialVersionUID = 1L;
+
+ public StaleUpdateException(final String message) {
+ super(message);
+ }
+
+ public StaleUpdateException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+ }
+
+ /**
+ * A {@link EventFilter} is a translation from an {@link IndexingExpr}
+ * to a format the {@link GeoTemporalIndexer} can use to easily determine which
+ * filter function is being used.
+ *
+ * @param T - The type of
+ */
+ interface EventFilter<T> {
+ /**
+ * Gets the translated query friendly form of the filter.
+ */
+ public T getQueryObject();
+ }
+
+ /**
+ * Factory for getting the {@link EventFilter} from an {@link IndexingExpr}.
+ */
+ interface EventFilterFactory<T> {
+ public EventFilter<T> getSearchFunction(final IndexingExpr filter);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.geomesa/pom.xml
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geomesa/pom.xml b/extras/rya.geoindexing/geo.geomesa/pom.xml
new file mode 100644
index 0000000..ebadd36
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geomesa/pom.xml
@@ -0,0 +1,51 @@
+<?xml version='1.0'?>
+
+<!-- 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. -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.rya</groupId>
+ <artifactId>rya.geoindexing</artifactId>
+ <version>3.2.11-incubating-SNAPSHOT</version>
+ </parent>
+ <artifactId>geo.geomesa</artifactId>
+ <name>Apache Rya Geo Indexing using GeoMesa</name>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <geotools.version>14.3</geotools.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.rya</groupId>
+ <artifactId>geo.common</artifactId>
+ <version>3.2.11-incubating-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.locationtech.geomesa</groupId>
+ <artifactId>geomesa-accumulo-datastore_2.11</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.geotools.xsd</groupId>
+ <artifactId>gt-xsd-gml3</artifactId>
+ <version>${geotools.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.geotools</groupId>
+ <artifactId>gt-api</artifactId>
+ <version>${geotools.version}</version>
+ </dependency>
+ </dependencies>
+ </project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java b/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java
new file mode 100644
index 0000000..02ef5ba
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java
@@ -0,0 +1,519 @@
+/*
+ * 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 java.util.Objects.requireNonNull;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.Connector;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.rya.accumulo.experimental.AbstractAccumuloIndexer;
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.resolver.RyaToRdfConversions;
+import org.apache.rya.indexing.GeoIndexer;
+import org.apache.rya.indexing.Md5Hash;
+import org.apache.rya.indexing.StatementConstraints;
+import org.apache.rya.indexing.StatementSerializer;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.accumulo.geo.GeoTupleSet.GeoSearchFunctionFactory.NearQuery;
+import org.geotools.data.DataStore;
+import org.geotools.data.DataStoreFinder;
+import org.geotools.data.DataUtilities;
+import org.geotools.data.FeatureSource;
+import org.geotools.data.FeatureStore;
+import org.geotools.data.Query;
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.factory.Hints;
+import org.geotools.feature.DefaultFeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.feature.SchemaException;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.filter.text.cql2.CQLException;
+import org.geotools.filter.text.ecql.ECQL;
+import org.locationtech.geomesa.accumulo.index.Constants;
+import org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory;
+import org.opengis.filter.identity.Identifier;
+import org.openrdf.model.Literal;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.query.QueryEvaluationException;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.ParseException;
+
+import info.aduna.iteration.CloseableIteration;
+
+/**
+ * A {@link GeoIndexer} wrapper around a GeoMesa {@link AccumuloDataStore}. This class configures and connects to the Datastore, creates the
+ * RDF Feature Type, and interacts with the Datastore.
+ * <p>
+ * Specifically, this class creates a RDF Feature type and stores each RDF Statement as a RDF Feature in the datastore. Each feature
+ * contains the standard set of GeoMesa attributes (Geometry, Start Date, and End Date). The GeoMesaGeoIndexer populates the Geometry
+ * attribute by parsing the Well-Known Text contained in the RDF Statement’s object literal value.
+ * <p>
+ * The RDF Feature contains four additional attributes for each component of the RDF Statement. These attributes are:
+ * <p>
+ * <table border="1">
+ * <tr>
+ * <th>Name</th>
+ * <th>Symbol</th>
+ * <th>Type</th>
+ * </tr>
+ * <tr>
+ * <td>Subject Attribute</td>
+ * <td>S</td>
+ * <td>String</td>
+ * </tr>
+ * </tr>
+ * <tr>
+ * <td>Predicate Attribute</td>
+ * <td>P</td>
+ * <td>String</td>
+ * </tr>
+ * </tr>
+ * <tr>
+ * <td>Object Attribute</td>
+ * <td>O</td>
+ * <td>String</td>
+ * </tr>
+ * </tr>
+ * <tr>
+ * <td>Context Attribute</td>
+ * <td>C</td>
+ * <td>String</td>
+ * </tr>
+ * </table>
+ */
+public class GeoMesaGeoIndexer extends AbstractAccumuloIndexer implements GeoIndexer {
+
+ private static final String TABLE_SUFFIX = "geo";
+
+ private static final Logger logger = Logger.getLogger(GeoMesaGeoIndexer.class);
+
+ private static final String FEATURE_NAME = "RDF";
+
+ private static final String SUBJECT_ATTRIBUTE = "S";
+ private static final String PREDICATE_ATTRIBUTE = "P";
+ private static final String OBJECT_ATTRIBUTE = "O";
+ private static final String CONTEXT_ATTRIBUTE = "C";
+ private static final String GEOMETRY_ATTRIBUTE = Constants.SF_PROPERTY_GEOMETRY;
+
+ private Set<URI> validPredicates;
+ private Configuration conf;
+ private FeatureStore<SimpleFeatureType, SimpleFeature> featureStore;
+ private FeatureSource<SimpleFeatureType, SimpleFeature> featureSource;
+ private SimpleFeatureType featureType;
+ private boolean isInit = false;
+
+ //initialization occurs in setConf because index is created using reflection
+ @Override
+ public void setConf(final Configuration conf) {
+ this.conf = conf;
+ if (!isInit) {
+ try {
+ initInternal();
+ isInit = true;
+ } catch (final IOException e) {
+ logger.warn("Unable to initialize index. Throwing Runtime Exception. ", e);
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public Configuration getConf() {
+ return conf;
+ }
+
+
+ private void initInternal() throws IOException {
+ validPredicates = ConfigUtils.getGeoPredicates(conf);
+
+ final DataStore dataStore = createDataStore(conf);
+
+ try {
+ featureType = getStatementFeatureType(dataStore);
+ } catch (final IOException | SchemaException e) {
+ throw new IOException(e);
+ }
+
+ featureSource = dataStore.getFeatureSource(featureType.getName());
+ if (!(featureSource instanceof FeatureStore)) {
+ throw new IllegalStateException("Could not retrieve feature store");
+ }
+ featureStore = (FeatureStore<SimpleFeatureType, SimpleFeature>) featureSource;
+ }
+
+ private static DataStore createDataStore(final Configuration conf) throws IOException {
+ // get the configuration parameters
+ final Instance instance = ConfigUtils.getInstance(conf);
+ final boolean useMock = instance instanceof MockInstance;
+ final String instanceId = instance.getInstanceName();
+ final String zookeepers = instance.getZooKeepers();
+ final String user = ConfigUtils.getUsername(conf);
+ final String password = ConfigUtils.getPassword(conf);
+ final String auths = ConfigUtils.getAuthorizations(conf).toString();
+ final String tableName = getTableName(conf);
+ final int numParitions = OptionalConfigUtils.getGeoNumPartitions(conf);
+
+ final String featureSchemaFormat = "%~#s%" + numParitions + "#r%" + FEATURE_NAME
+ + "#cstr%0,3#gh%yyyyMMdd#d::%~#s%3,2#gh::%~#s%#id";
+ // build the map of parameters
+ final Map<String, Serializable> params = new HashMap<String, Serializable>();
+ params.put("instanceId", instanceId);
+ params.put("zookeepers", zookeepers);
+ params.put("user", user);
+ params.put("password", password);
+ params.put("auths", auths);
+ params.put("tableName", tableName);
+ params.put("indexSchemaFormat", featureSchemaFormat);
+ params.put("useMock", Boolean.toString(useMock));
+
+ // fetch the data store from the finder
+ return DataStoreFinder.getDataStore(params);
+ }
+
+ private static SimpleFeatureType getStatementFeatureType(final DataStore dataStore) throws IOException, SchemaException {
+ SimpleFeatureType featureType;
+
+ final String[] datastoreFeatures = dataStore.getTypeNames();
+ if (Arrays.asList(datastoreFeatures).contains(FEATURE_NAME)) {
+ featureType = dataStore.getSchema(FEATURE_NAME);
+ } else {
+ final String featureSchema = SUBJECT_ATTRIBUTE + ":String," //
+ + PREDICATE_ATTRIBUTE + ":String," //
+ + OBJECT_ATTRIBUTE + ":String," //
+ + CONTEXT_ATTRIBUTE + ":String," //
+ + GEOMETRY_ATTRIBUTE + ":Geometry:srid=4326;geomesa.mixed.geometries='true'";
+ featureType = SimpleFeatureTypes.createType(FEATURE_NAME, featureSchema);
+ dataStore.createSchema(featureType);
+ }
+ return featureType;
+ }
+
+ @Override
+ public void storeStatements(final Collection<RyaStatement> ryaStatements) throws IOException {
+ // create a feature collection
+ final DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
+ for (final RyaStatement ryaStatement : ryaStatements) {
+ final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
+ // if the predicate list is empty, accept all predicates.
+ // Otherwise, make sure the predicate is on the "valid" list
+ final boolean isValidPredicate = validPredicates.isEmpty() || validPredicates.contains(statement.getPredicate());
+
+ if (isValidPredicate && (statement.getObject() instanceof Literal)) {
+ try {
+ final SimpleFeature feature = createFeature(featureType, statement);
+ featureCollection.add(feature);
+ } catch (final ParseException e) {
+ logger.warn("Error getting geo from statement: " + statement.toString(), e);
+ }
+ }
+ }
+
+ // write this feature collection to the store
+ if (!featureCollection.isEmpty()) {
+ featureStore.addFeatures(featureCollection);
+ }
+ }
+
+ @Override
+ public void storeStatement(final RyaStatement statement) throws IOException {
+ storeStatements(Collections.singleton(statement));
+ }
+
+ private static SimpleFeature createFeature(final SimpleFeatureType featureType, final Statement statement) throws ParseException {
+ final String subject = StatementSerializer.writeSubject(statement);
+ final String predicate = StatementSerializer.writePredicate(statement);
+ final String object = StatementSerializer.writeObject(statement);
+ final String context = StatementSerializer.writeContext(statement);
+
+ // create the feature
+ final Object[] noValues = {};
+
+ // create the hash
+ final String statementId = Md5Hash.md5Base64(StatementSerializer.writeStatement(statement));
+ final SimpleFeature newFeature = SimpleFeatureBuilder.build(featureType, noValues, statementId);
+
+ // write the statement data to the fields
+ final Geometry geom = GeoParseUtils.getGeometry(statement, new GmlParser());
+ if(geom == null || geom.isEmpty() || !geom.isValid()) {
+ throw new ParseException("Could not create geometry for statement " + statement);
+ }
+ newFeature.setDefaultGeometry(geom);
+
+ newFeature.setAttribute(SUBJECT_ATTRIBUTE, subject);
+ newFeature.setAttribute(PREDICATE_ATTRIBUTE, predicate);
+ newFeature.setAttribute(OBJECT_ATTRIBUTE, object);
+ newFeature.setAttribute(CONTEXT_ATTRIBUTE, context);
+
+ // preserve the ID that we created for this feature
+ // (set the hint to FALSE to have GeoTools generate IDs)
+ newFeature.getUserData().put(Hints.USE_PROVIDED_FID, java.lang.Boolean.TRUE);
+
+ return newFeature;
+ }
+
+ private CloseableIteration<Statement, QueryEvaluationException> performQuery(final String type, final Geometry geometry,
+ final StatementConstraints contraints) {
+ final List<String> filterParms = new ArrayList<String>();
+
+ filterParms.add(type + "(" + GEOMETRY_ATTRIBUTE + ", " + geometry + " )");
+
+ if (contraints.hasSubject()) {
+ filterParms.add("( " + SUBJECT_ATTRIBUTE + "= '" + contraints.getSubject() + "') ");
+ }
+ if (contraints.hasContext()) {
+ filterParms.add("( " + CONTEXT_ATTRIBUTE + "= '" + contraints.getContext() + "') ");
+ }
+ if (contraints.hasPredicates()) {
+ final List<String> predicates = new ArrayList<String>();
+ for (final URI u : contraints.getPredicates()) {
+ predicates.add("( " + PREDICATE_ATTRIBUTE + "= '" + u.stringValue() + "') ");
+ }
+ filterParms.add("(" + StringUtils.join(predicates, " OR ") + ")");
+ }
+
+ final String filterString = StringUtils.join(filterParms, " AND ");
+ logger.info("Performing geomesa query : " + filterString);
+
+ return getIteratorWrapper(filterString);
+ }
+
+ private CloseableIteration<Statement, QueryEvaluationException> getIteratorWrapper(final String filterString) {
+
+ return new CloseableIteration<Statement, QueryEvaluationException>() {
+
+ private FeatureIterator<SimpleFeature> featureIterator = null;
+
+ FeatureIterator<SimpleFeature> getIterator() throws QueryEvaluationException {
+ if (featureIterator == null) {
+ Filter cqlFilter;
+ try {
+ cqlFilter = ECQL.toFilter(filterString);
+ } catch (final CQLException e) {
+ logger.error("Error parsing query: " + filterString, e);
+ throw new QueryEvaluationException(e);
+ }
+
+ final Query query = new Query(featureType.getTypeName(), cqlFilter);
+ try {
+ featureIterator = featureSource.getFeatures(query).features();
+ } catch (final IOException e) {
+ logger.error("Error performing query: " + filterString, e);
+ throw new QueryEvaluationException(e);
+ }
+ }
+ return featureIterator;
+ }
+
+ @Override
+ public boolean hasNext() throws QueryEvaluationException {
+ return getIterator().hasNext();
+ }
+
+ @Override
+ public Statement next() throws QueryEvaluationException {
+ final SimpleFeature feature = getIterator().next();
+ final String subjectString = feature.getAttribute(SUBJECT_ATTRIBUTE).toString();
+ final String predicateString = feature.getAttribute(PREDICATE_ATTRIBUTE).toString();
+ final String objectString = feature.getAttribute(OBJECT_ATTRIBUTE).toString();
+ final String contextString = feature.getAttribute(CONTEXT_ATTRIBUTE).toString();
+ final Statement statement = StatementSerializer.readStatement(subjectString, predicateString, objectString, contextString);
+ return statement;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Remove not implemented");
+ }
+
+ @Override
+ public void close() throws QueryEvaluationException {
+ getIterator().close();
+ }
+ };
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryEquals(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("EQUALS", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryDisjoint(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("DISJOINT", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryIntersects(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("INTERSECTS", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryTouches(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("TOUCHES", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryCrosses(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("CROSSES", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryWithin(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("WITHIN", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryContains(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("CONTAINS", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryOverlaps(final Geometry query, final StatementConstraints contraints) {
+ return performQuery("OVERLAPS", query, contraints);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryNear(final NearQuery query,
+ final StatementConstraints contraints) {
+ throw new UnsupportedOperationException("Near queries are not supported in Accumulo.");
+ }
+
+ @Override
+ public Set<URI> getIndexablePredicates() {
+ return validPredicates;
+ }
+
+ @Override
+ public void flush() throws IOException {
+ // TODO cache and flush features instead of writing them one at a time
+ }
+
+ @Override
+ public void close() throws IOException {
+ flush();
+ }
+
+
+ @Override
+ public String getTableName() {
+ return getTableName(conf);
+ }
+
+ /**
+ * Get the Accumulo table that will be used by this index.
+ * @param conf
+ * @return table name guaranteed to be used by instances of this index
+ */
+ public static String getTableName(final Configuration conf) {
+ return makeTableName( ConfigUtils.getTablePrefix(conf) );
+ }
+
+ /**
+ * Make the Accumulo table name used by this indexer for a specific instance of Rya.
+ *
+ * @param ryaInstanceName - The name of the Rya instance the table name is for. (not null)
+ * @return The Accumulo table name used by this indexer for a specific instance of Rya.
+ */
+ public static String makeTableName(final String ryaInstanceName) {
+ requireNonNull(ryaInstanceName);
+ return ryaInstanceName + TABLE_SUFFIX;
+ }
+
+ private void deleteStatements(final Collection<RyaStatement> ryaStatements) throws IOException {
+ // create a feature collection
+ final DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
+
+ for (final RyaStatement ryaStatement : ryaStatements) {
+ final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
+ // if the predicate list is empty, accept all predicates.
+ // Otherwise, make sure the predicate is on the "valid" list
+ final boolean isValidPredicate = validPredicates.isEmpty() || validPredicates.contains(statement.getPredicate());
+
+ if (isValidPredicate && (statement.getObject() instanceof Literal)) {
+ try {
+ final SimpleFeature feature = createFeature(featureType, statement);
+ featureCollection.add(feature);
+ } catch (final ParseException e) {
+ logger.warn("Error getting geo from statement: " + statement.toString(), e);
+ }
+ }
+ }
+
+ // remove this feature collection from the store
+ if (!featureCollection.isEmpty()) {
+ final Set<Identifier> featureIds = new HashSet<Identifier>();
+ final FilterFactory filterFactory = CommonFactoryFinder.getFilterFactory(null);
+ final Set<String> stringIds = DataUtilities.fidSet(featureCollection);
+ for (final String id : stringIds) {
+ featureIds.add(filterFactory.featureId(id));
+ }
+ final Filter filter = filterFactory.id(featureIds);
+ featureStore.removeFeatures(filter);
+ }
+ }
+
+
+ @Override
+ public void deleteStatement(final RyaStatement statement) throws IOException {
+ deleteStatements(Collections.singleton(statement));
+ }
+
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public void setConnector(final Connector connector) {
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ @Override
+ public void purge(final RdfCloudTripleStoreConfiguration configuration) {
+ }
+
+ @Override
+ public void dropAndDestroy() {
+ }
+}
[05/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexSetProvider.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexSetProvider.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexSetProvider.java
deleted file mode 100644
index bf12f26..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexSetProvider.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/**
- * 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.geotemporal;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-import org.apache.log4j.Logger;
-import org.apache.rya.indexing.IndexingExpr;
-import org.apache.rya.indexing.IndexingFunctionRegistry;
-import org.apache.rya.indexing.IndexingFunctionRegistry.FUNCTION_TYPE;
-import org.apache.rya.indexing.accumulo.geo.GeoParseUtils;
-import org.apache.rya.indexing.accumulo.geo.GeoTupleSet;
-import org.apache.rya.indexing.external.matching.ExternalSetProvider;
-import org.apache.rya.indexing.external.matching.QuerySegment;
-import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
-import org.apache.rya.indexing.geotemporal.model.EventQueryNode.EventQueryNodeBuilder;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage;
-import org.openrdf.model.URI;
-import org.openrdf.model.impl.URIImpl;
-import org.openrdf.query.algebra.FunctionCall;
-import org.openrdf.query.algebra.QueryModelNode;
-import org.openrdf.query.algebra.StatementPattern;
-import org.openrdf.query.algebra.Var;
-import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-
-/**
- * Provides {@link GeoTupleSet}s.
- */
-public class GeoTemporalIndexSetProvider implements ExternalSetProvider<EventQueryNode> {
- private static final Logger LOG = Logger.getLogger(GeoTemporalIndexSetProvider.class);
-
- //organzied by object var. Each object is a filter, or set of filters
- private Multimap<Var, IndexingExpr> filterMap;
-
- //organzied by subject var. Each subject is a GeoTemporalTupleSet
- private Multimap<Var, StatementPattern> patternMap;
-
- //filters that have not been constrained by statement patterns into indexing expressions yet.
- private Multimap<Var, FunctionCall> unmatchedFilters;
- //filters that have been used, to be used by the matcher later.
- private Multimap<Var, FunctionCall> matchedFilters;
-
- //organzied by object var. Used to find matches between unmatch filters and patterns
- private Map<Var, StatementPattern> objectPatterns;
-
-
- private static URI filterURI;
-
- private final EventStorage eventStorage;
-
- public GeoTemporalIndexSetProvider(final EventStorage eventStorage) {
- this.eventStorage = requireNonNull(eventStorage);
- }
-
- @Override
- public List<EventQueryNode> getExternalSets(final QuerySegment<EventQueryNode> node) {
- filterMap = HashMultimap.create();
- patternMap = HashMultimap.create();
- unmatchedFilters = HashMultimap.create();
- matchedFilters = HashMultimap.create();
-
- objectPatterns = new HashMap<>();
- //discover entities
- buildMaps(node);
- final List<EventQueryNode> nodes = createNodes();
-
- return nodes;
- }
-
- private List<EventQueryNode> createNodes() {
- final List<EventQueryNode> nodes = new ArrayList<>();
- for(final Var subj : patternMap.keySet()) {
- final EventQueryNode node = getGeoTemporalNode(subj);
- if(node != null) {
- nodes.add(node);
- }
- }
- return nodes;
- }
-
- private EventQueryNode getGeoTemporalNode(final Var subj) {
- final Collection<StatementPattern> patterns = patternMap.get(subj);
- final Collection<FunctionCall> usedFilters = new ArrayList<>();
- Optional<StatementPattern> geoPattern = Optional.empty();
- Optional<StatementPattern> temporalPattern = Optional.empty();
- Optional<Collection<IndexingExpr>> geoFilters = Optional.empty();
- Optional<Collection<IndexingExpr>> temporalFilters = Optional.empty();
-
- //should only be 2 patterns.
- for(final StatementPattern sp : patterns) {
- final Var obj = sp.getObjectVar();
-
- ///filter map does not have -const-
-
-
- if(filterMap.containsKey(obj)) {
- final Collection<IndexingExpr> filters = filterMap.get(obj);
- final IndexingFunctionRegistry.FUNCTION_TYPE type = ensureSameType(filters);
- if(type != null && type == FUNCTION_TYPE.GEO) {
- geoPattern = Optional.of(sp);
- geoFilters = Optional.of(filters);
- usedFilters.addAll(matchedFilters.get(obj));
- } else if(type != null && type == FUNCTION_TYPE.TEMPORAL) {
- temporalPattern = Optional.of(sp);
- temporalFilters = Optional.of(filters);
- usedFilters.addAll(matchedFilters.get(obj));
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
-
- if(geoFilters.isPresent() && temporalFilters.isPresent() && geoPattern.isPresent() && temporalPattern.isPresent()) {
- return new EventQueryNodeBuilder()
- .setStorage(eventStorage)
- .setGeoPattern(geoPattern.get())
- .setTemporalPattern(temporalPattern.get())
- .setGeoFilters(geoFilters.get())
- .setTemporalFilters(temporalFilters.get())
- .setUsedFilters(usedFilters)
- .build();
- } else {
- return null;
- }
- }
-
- private static FUNCTION_TYPE ensureSameType(final Collection<IndexingExpr> filters) {
- FUNCTION_TYPE type = null;
- for(final IndexingExpr filter : filters) {
- if(type == null) {
- type = IndexingFunctionRegistry.getFunctionType(filter.getFunction());
- } else {
- if(IndexingFunctionRegistry.getFunctionType(filter.getFunction()) != type) {
- return null;
- }
- }
- }
- return type;
- }
-
- private void buildMaps(final QuerySegment<EventQueryNode> node) {
- final List<QueryModelNode> unused = new ArrayList<>();
- for (final QueryModelNode pattern : node.getOrderedNodes()) {
- if(pattern instanceof FunctionCall) {
- discoverFilter((FunctionCall) pattern, unused);
- }
- if(pattern instanceof StatementPattern) {
- discoverPatterns((StatementPattern) pattern, unused);
- }
- }
- }
-
- private void discoverFilter(final FunctionCall filter, final List<QueryModelNode> unmatched) {
- try {
- filter.visit(new FilterVisitor());
- } catch (final Exception e) {
- LOG.error("Failed to match the filter object.", e);
- }
- }
-
- private void discoverPatterns(final StatementPattern pattern, final List<QueryModelNode> unmatched) {
- final Var subj = pattern.getSubjectVar();
- final Var objVar = pattern.getObjectVar();
-
- patternMap.put(subj, pattern);
- objectPatterns.put(objVar, pattern);
- //check for existing filters.
- if(unmatchedFilters.containsKey(objVar)) {
- final Collection<FunctionCall> calls = unmatchedFilters.removeAll(objVar);
- for(final FunctionCall call : calls) {
- addFilter(call);
- matchedFilters.put(objVar, call);
- }
- }
- }
-
- @Override
- public Iterator<List<EventQueryNode>> getExternalSetCombos(final QuerySegment<EventQueryNode> segment) {
- final List<List<EventQueryNode>> comboList = new ArrayList<>();
- comboList.add(getExternalSets(segment));
- return comboList.iterator();
- }
-
- private void addFilter(final FunctionCall call) {
- filterURI = new URIImpl(call.getURI());
- final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, call.getArgs());
- filterMap.put(objVar, new IndexingExpr(filterURI, objectPatterns.get(objVar), GeoParseUtils.extractArguments(objVar.getName(), call)));
- }
-
- /**
- * Finds the object/function in a Filter. If the associated statement pattern
- * has been found, creates the {@link IndexingExpr} and adds it to the map.
- */
- private class FilterVisitor extends QueryModelVisitorBase<Exception> {
- @Override
- public void meet(final FunctionCall call) throws Exception {
- filterURI = new URIImpl(call.getURI());
- final FUNCTION_TYPE type = IndexingFunctionRegistry.getFunctionType(filterURI);
- if(type == FUNCTION_TYPE.GEO || type == FUNCTION_TYPE.TEMPORAL) {
- final Var objVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, call.getArgs());
- if(objectPatterns.containsKey(objVar)) {
- filterMap.put(objVar, new IndexingExpr(filterURI, objectPatterns.get(objVar), GeoParseUtils.extractArguments(objVar.getName(), call)));
- matchedFilters.put(objVar, call);
- } else {
- unmatchedFilters.put(objVar, call);
- }
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexer.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexer.java
deleted file mode 100644
index cbc978b..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexer.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * 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.geotemporal;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.rya.api.persist.index.RyaSecondaryIndexer;
-import org.apache.rya.indexing.GeoConstants;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage;
-import org.openrdf.model.Statement;
-import org.openrdf.model.URI;
-import org.openrdf.model.impl.URIImpl;
-
-/**
- * A repository to store, index, and retrieve {@link Statement}s based on geotemporal features.
- */
-public interface GeoTemporalIndexer extends RyaSecondaryIndexer {
-
- /**
- * Creates the {@link Eventtorage} that will be used by the indexer.
- *
- * @param conf - Indicates how the {@link EventStorage} is initialized. (not null)
- * @return The {@link EventStorage} that will be used by this indexer.
- */
- public abstract EventStorage getEventStorage(final Configuration conf);
-
- /**
- * Used to indicate which geo filter functions to use in a query.
- */
- public static enum GeoPolicy {
- /**
- * The provided geo object equals the geo object where the event took place.
- */
- EQUALS(GeoConstants.GEO_SF_EQUALS),
-
- /**
- * The provided geo object does not share any space with the event.
- */
- DISJOINT(GeoConstants.GEO_SF_DISJOINT),
-
- /**
- * The provided geo object shares some amount of space with the event.
- */
- INTERSECTS(GeoConstants.GEO_SF_INTERSECTS),
-
- /**
- * The provided geo object shares a point with the event, but only on the edge.
- */
- TOUCHES(GeoConstants.GEO_SF_TOUCHES),
-
- /**
- * The provided geo object shares some, but not all space with the event.
- */
- CROSSES(GeoConstants.GEO_SF_CROSSES),
-
- /**
- * The provided geo object exists completely within the event.
- */
- WITHIN(GeoConstants.GEO_SF_WITHIN),
-
- /**
- * The event took place completely within the provided geo object.
- */
- CONTAINS(GeoConstants.GEO_SF_CONTAINS),
-
- /**
- * The provided geo object has some but not all points in common with the event,
- * are of the same dimension, and the intersection of the interiors has the
- * same dimension as the geometries themselves.
- */
- OVERLAPS(GeoConstants.GEO_SF_OVERLAPS);
-
- private final URI uri;
-
- private GeoPolicy(final URI uri) {
- this.uri = uri;
- }
-
- public URI getURI() {
- return uri;
- }
-
- public static GeoPolicy fromURI(final URI uri) {
- for(final GeoPolicy policy : GeoPolicy.values()) {
- if(policy.getURI().equals(uri)) {
- return policy;
- }
- }
- return null;
- }
- }
-
- static final String TEMPORAL_NS = "tag:rya-rdf.org,2015:temporal#";
- /**
- * Used to indicate which temporal filter functions to use in a query.
- */
- public enum TemporalPolicy {
- /**
- * The provided instant in time equals the instant the event took place.
- */
- INSTANT_EQUALS_INSTANT(true, new URIImpl(TEMPORAL_NS+"equals")),
-
- /**
- * The provided instant in time was before when the event took place.
- */
- INSTANT_BEFORE_INSTANT(true, new URIImpl(TEMPORAL_NS+"before")),
-
- /**
- * The provided instant in time was after when the event took place.
- */
- INSTANT_AFTER_INSTANT(true, new URIImpl(TEMPORAL_NS+"after")),
-
- /**
- * The provided instant in time was before a time period.
- */
- INSTANT_BEFORE_INTERVAL(false, new URIImpl(TEMPORAL_NS+"beforeInterval")),
-
- /**
- * The provided instant in time took place within a set of time.
- */
- INSTANT_IN_INTERVAL(false, new URIImpl(TEMPORAL_NS+"insideInterval")),
-
- /**
- * The provided instant in time took place after a time period.
- */
- INSTANT_AFTER_INTERVAL(false, new URIImpl(TEMPORAL_NS+"afterInterval")),
-
- /**
- * The provided instant in time equals the start of the interval in which the event took place.
- */
- INSTANT_START_INTERVAL(false, new URIImpl(TEMPORAL_NS+"hasBeginningInterval")),
-
- /**
- * The provided instant in time equals the end of the interval in which the event took place.
- */
- INSTANT_END_INTERVAL(false, new URIImpl(TEMPORAL_NS+"hasEndInterval")),
-
- /**
- * The provided interval equals the interval in which the event took place.
- */
- INTERVAL_EQUALS(false, new URIImpl(TEMPORAL_NS+"intervalEquals")),
-
- /**
- * The provided interval is before the interval in which the event took place.
- */
- INTERVAL_BEFORE(false, new URIImpl(TEMPORAL_NS+"intervalBefore")),
-
- /**
- * The provided interval is after the interval in which the event took place.
- */
- INTERVAL_AFTER(false, new URIImpl(TEMPORAL_NS+"intervalAfter"));
-
- private final boolean isInstant;
- private final URI uri;
-
- TemporalPolicy(final boolean isInstant, final URI uri) {
- this.isInstant = isInstant;
- this.uri = uri;
- }
-
- public boolean isInstant(){
- return isInstant;
- }
-
- public URI getURI() {
- return uri;
- }
-
- public static TemporalPolicy fromURI(final URI uri) {
- for(final TemporalPolicy policy : TemporalPolicy.values()) {
- if(policy.getURI().equals(uri)) {
- return policy;
- }
- }
- return null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexerFactory.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexerFactory.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexerFactory.java
deleted file mode 100644
index a7ba8fa..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexerFactory.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * 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.geotemporal;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.geotemporal.mongo.MongoGeoTemporalIndexer;
-import org.apache.rya.mongodb.MongoDBRdfConfiguration;
-import org.apache.rya.mongodb.MongoSecondaryIndex;
-
-/**
- * Factory for retrieving a {@link GeoTemporalIndexer} based on a provided {@link Configuration}.
- */
-public class GeoTemporalIndexerFactory {
- /**
- * Creates and returns a {@link GeoTemporalIndexer}.
- * @param conf - The {@link Configuration} to base the {@link GeoTemporalIndexer} on.
- * @return The created {@link GeoTemporalIndexer}.
- */
- public GeoTemporalIndexer getIndexer(final Configuration conf) {
- if(ConfigUtils.getUseMongo(conf)) {
- final MongoDBRdfConfiguration config = new MongoDBRdfConfiguration(conf);
- for(final MongoSecondaryIndex index : config.getAdditionalIndexers()) {
- if(index instanceof GeoTemporalIndexer) {
- return (GeoTemporalIndexer) index;
- }
- }
- final MongoGeoTemporalIndexer index = new MongoGeoTemporalIndexer();
- index.setConf(conf);
- index.init();
- return index;
- } else {
- //TODO: add Accumulo here.
- return null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalOptimizer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalOptimizer.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalOptimizer.java
deleted file mode 100644
index d626adc..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalOptimizer.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.geotemporal;
-
-import org.apache.hadoop.conf.Configurable;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.rya.indexing.external.matching.AbstractExternalSetOptimizer;
-import org.apache.rya.indexing.external.matching.ExternalSetMatcher;
-import org.apache.rya.indexing.external.matching.ExternalSetProvider;
-import org.apache.rya.indexing.external.matching.QueryNodeListRater;
-import org.apache.rya.indexing.external.matching.QuerySegment;
-import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
-
-import com.google.common.base.Optional;
-
-
-public class GeoTemporalOptimizer extends AbstractExternalSetOptimizer<EventQueryNode> implements Configurable {
- private static final GeoTemporalExternalSetMatcherFactory MATCHER_FACTORY = new GeoTemporalExternalSetMatcherFactory();
-
- private GeoTemporalIndexer indexer;
- private GeoTemporalIndexSetProvider provider;
- private Configuration conf;
-
- @Override
- public void setConf(final Configuration conf) {
- this.conf = conf;
- final GeoTemporalIndexerFactory factory = new GeoTemporalIndexerFactory();
- indexer = factory.getIndexer(conf);
-
- //conf here does not matter since EventStorage has already been set in the indexer.
- provider = new GeoTemporalIndexSetProvider(indexer.getEventStorage(conf));
- }
-
- @Override
- public Configuration getConf() {
- return conf;
- }
-
- @Override
- protected ExternalSetMatcher<EventQueryNode> getMatcher(final QuerySegment<EventQueryNode> segment) {
- return MATCHER_FACTORY.getMatcher(segment);
- }
-
- @Override
- protected ExternalSetProvider<EventQueryNode> getProvider() {
- return provider;
- }
-
- @Override
- protected Optional<QueryNodeListRater> getNodeListRater(final QuerySegment<EventQueryNode> segment) {
- return null;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalToSegmentConverter.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalToSegmentConverter.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalToSegmentConverter.java
deleted file mode 100644
index 22bfdb1..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalToSegmentConverter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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.geotemporal;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.rya.indexing.external.matching.ExternalSetConverter;
-import org.apache.rya.indexing.external.matching.JoinSegment;
-import org.apache.rya.indexing.external.matching.QuerySegment;
-import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
-import org.openrdf.query.algebra.Filter;
-import org.openrdf.query.algebra.QueryModelNode;
-import org.openrdf.query.algebra.ValueExpr;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Implementation of {@link ExternalSetConverter} to convert {@link EventQueryNode}s
- * to {@link QuerySegment}s.
- *
- */
-public class GeoTemporalToSegmentConverter implements ExternalSetConverter<EventQueryNode> {
- @Override
- public QuerySegment<EventQueryNode> setToSegment(final EventQueryNode set) {
- Preconditions.checkNotNull(set);
- final Set<QueryModelNode> matched = new HashSet<>(set.getPatterns());
- matched.addAll(set.getFilters());
- final List<QueryModelNode> unmatched = new ArrayList<>(set.getPatterns());
- return new JoinSegment<EventQueryNode>(matched, unmatched, new HashMap<ValueExpr, Filter>());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/model/Event.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/model/Event.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/model/Event.java
deleted file mode 100644
index 4c50bfb..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/model/Event.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/**
- * 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.geotemporal.model;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.Objects;
-import java.util.Optional;
-
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.indexing.TemporalInstant;
-import org.apache.rya.indexing.TemporalInterval;
-import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer;
-
-import com.vividsolutions.jts.geom.Geometry;
-
-import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
-import edu.umd.cs.findbugs.annotations.NonNull;
-
-/**
- * Query object for a {@link GeoTemporalIndexer}.
- * Defines a {@link Geometry}, either a {@link TemporalInstant} or
- * {@link TemporalInterval}, and a triple Subject.
- */
-public class Event {
- private final Optional<Geometry> geometry;
- private final Optional<TemporalInstant> instant;
- private final Optional<TemporalInterval> interval;
- private final RyaURI subject;
-
- private final boolean isInstant;
-
- /**
- * Creates a new {@link Event} query object with a {@link TemporalInstant}.
- * @param geo - The {@link Geometry} to use when querying.
- * @param instant - The {@link TemporalInstant} to use when querying.
- * @param subject - The Subject that both statements must have when querying.
- */
- private Event(final Geometry geo, final TemporalInstant instant, final RyaURI subject) {
- this.subject = requireNonNull(subject);
-
- //these fields are nullable since they are filled field by field.
- this.instant = Optional.ofNullable(instant);
- geometry = Optional.ofNullable(geo);
- isInstant = true;
- interval = Optional.empty();
- }
-
- /**
- * Creates a new {@link Event} query object with a {@link TemporalInterval}.
- * @param geo - The {@link Geometry} to use when querying.
- * @param interval - The {@link TemporalInterval} to use when querying.
- * @param subject - The Subject that both statements must have when querying.
- */
- private Event(final Geometry geo, final TemporalInterval interval, final RyaURI subject) {
- this.subject = requireNonNull(subject);
-
- //these fields are nullable since they are filled field by field.
- this.interval = Optional.ofNullable(interval);
- geometry = Optional.ofNullable(geo);
- isInstant = false;
- instant = Optional.empty();
- }
-
- /**
- * @return Whether or not the query object uses a {@link TemporalInstant}.
- */
- public boolean isInstant() {
- return isInstant;
- }
-
- /**
- * @return The {@link Geometry} to use when querying.
- */
- public Optional<Geometry> getGeometry() {
- return geometry;
- }
-
- /**
- * @return The {@link TemporalInstant} to use when querying.
- */
- public Optional<TemporalInstant> getInstant() {
- return instant;
- }
-
- /**
- * @return The {@link TemporalInterval} to use when querying.
- */
- public Optional<TemporalInterval> getInterval() {
- return interval;
- }
-
- /**
- * @return The statement subject.
- */
- public RyaURI getSubject() {
- return subject;
- }
-
- @Override
- public int hashCode() {
- if(isInstant) {
- return Objects.hash(subject, geometry, instant);
- } else {
- return Objects.hash(subject, geometry, interval);
- }
- }
-
- @Override
- public boolean equals(final Object o) {
- if(this == o) {
- return true;
- }
- if(o instanceof Event) {
- final Event event = (Event) o;
- return Objects.equals(subject, event.subject) &&
- Objects.equals(isInstant, event.isInstant) &&
- (isInstant ? Objects.equals(instant, event.instant) : Objects.equals(interval, event.interval));
- }
- return false;
- }
-
- public static Builder builder(final Event event) {
- final Builder builder = new Builder()
- .setSubject(event.getSubject());
- if(event.getGeometry().isPresent()) {
- builder.setGeometry(event.getGeometry().get());
- }
- if(event.isInstant()) {
- if(event.getInstant().isPresent()) {
- builder.setTemporalInstant(event.getInstant().get());
- }
- } else {
- if(event.getInterval().isPresent()) {
- builder.setTemporalInterval(event.getInterval().get());
- }
- }
- return builder;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Builds instances of {@link Event}.
- */
- @DefaultAnnotation(NonNull.class)
- public static class Builder {
- private RyaURI subject;
- private Geometry geo;
- private TemporalInstant instant;
- private TemporalInterval interval;
-
- /**
- * Sets the {@link RyaURI} subject.
- * @param subject - The subject to key on the event.
- */
- public Builder setSubject(final RyaURI subject) {
- this.subject = subject;
- return this;
- }
-
- /**
- * Sets the {@link Geometry}.
- * @param geo - The geometry.
- */
- public Builder setGeometry(final Geometry geo) {
- this.geo = geo;
- return this;
- }
-
- /**
- * Sets the {@link TemporalInterval}.
- * @param interval - The interval.
- */
- public Builder setTemporalInterval(final TemporalInterval interval) {
- this.interval = interval;
- return this;
- }
-
- /**
- * Sets the {@link TemporalInstant}.
- * @param instant - The instant.
- */
- public Builder setTemporalInstant(final TemporalInstant instant) {
- this.instant = instant;
- return this;
- }
-
- /**
- * @return The new {@link Event}.
- */
- public Event build() {
- if(instant == null) {
- return new Event(geo, interval, subject);
- } else {
- return new Event(geo, instant, subject);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/model/EventQueryNode.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/model/EventQueryNode.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/model/EventQueryNode.java
deleted file mode 100644
index 104fca8..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/model/EventQueryNode.java
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * 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.geotemporal.model;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-
-import org.apache.commons.lang.builder.EqualsBuilder;
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.indexing.IndexingExpr;
-import org.apache.rya.indexing.TemporalInstant;
-import org.apache.rya.indexing.TemporalInstantRfc3339;
-import org.apache.rya.indexing.entity.query.EntityQueryNode;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage;
-import org.apache.rya.indexing.mongodb.update.RyaObjectStorage.ObjectStorageException;
-import org.apache.rya.rdftriplestore.evaluation.ExternalBatchingIterator;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-import org.openrdf.model.Value;
-import org.openrdf.model.impl.ValueFactoryImpl;
-import org.openrdf.query.BindingSet;
-import org.openrdf.query.QueryEvaluationException;
-import org.openrdf.query.algebra.FunctionCall;
-import org.openrdf.query.algebra.StatementPattern;
-import org.openrdf.query.algebra.Var;
-import org.openrdf.query.algebra.evaluation.impl.ExternalSet;
-import org.openrdf.query.algebra.evaluation.iterator.CollectionIteration;
-import org.openrdf.query.impl.MapBindingSet;
-
-import com.vividsolutions.jts.geom.Geometry;
-
-import info.aduna.iteration.CloseableIteration;
-
-public class EventQueryNode extends ExternalSet implements ExternalBatchingIterator {
- private final Collection<FunctionCall> usedFilters;
- private final Collection<IndexingExpr> geoFilters;
- private final Collection<IndexingExpr> temporalFilters;
-
- private final StatementPattern geoPattern;
- private final StatementPattern temporalPattern;
-
- //Information about the subject of the patterns.
- private final boolean subjectIsConstant;
- private final Optional<String> subjectVar;
- //not final because if the subject is a variable and the evaluate() is
- // provided a binding set that contains the subject, this optional is used.
- private Optional<String> subjectConstant;
-
- //since and EventQueryNode exists in a single segment, all binding names are garunteed to be assured.
- private final Set<String> bindingNames;
-
- private Collection<StatementPattern> patterns;
-
- private final EventStorage eventStore;
-
- /**
- * Constructs an instance of {@link EventQueryNode}.
- * @param usedFilters
- *
- * @param type - The type of {@link Event} this node matches. (not null)
- * @param patterns - The query StatementPatterns that are solved using an
- * Event of the Type. (not null)
- * @param entities - The {@link EventStorage} that will be searched to match
- * {@link BindingSet}s when evaluating a query. (not null)
- */
- private EventQueryNode(final EventStorage eventStore, final StatementPattern geoPattern, final StatementPattern temporalPattern, final Collection<IndexingExpr> geoFilters, final Collection<IndexingExpr> temporalFilters, final Collection<FunctionCall> usedFilters) throws IllegalStateException {
- this.geoPattern = requireNonNull(geoPattern);
- this.temporalPattern = requireNonNull(temporalPattern);
- this.geoFilters = requireNonNull(geoFilters);
- this.temporalFilters = requireNonNull(temporalFilters);
- this.eventStore = requireNonNull(eventStore);
- this.usedFilters = requireNonNull(usedFilters);
- bindingNames = new HashSet<>();
-
- // Subject based preconditions.
- verifySameSubjects(getPatterns());
- // Predicate based preconditions.
- verifyAllPredicatesAreConstants(getPatterns());
-
- // The Subject may either be constant or a variable.
- final Var subject = patterns.iterator().next().getSubjectVar();
- subjectIsConstant = subject.isConstant();
- if(subjectIsConstant) {
- subjectConstant = Optional.of( subject.getValue().toString() );
- subjectVar = Optional.empty();
- } else {
- subjectConstant = Optional.empty();
- subjectVar = Optional.of( subject.getName() );
- }
- }
-
- @Override
- public Set<String> getBindingNames() {
- return bindingNames;
- }
-
- @Override
- public Set<String> getAssuredBindingNames() {
- return bindingNames;
- }
-
- /**
- * Verify the Subject for all of the patterns is the same.
- *
- * @param patterns - The patterns to check.
- * @throws IllegalStateException If all of the Subjects are not the same.
- */
- private static void verifySameSubjects(final Collection<StatementPattern> patterns) throws IllegalStateException {
- requireNonNull(patterns);
-
- final Iterator<StatementPattern> it = patterns.iterator();
- final Var subject = it.next().getSubjectVar();
-
- while(it.hasNext()) {
- final StatementPattern pattern = it.next();
- if(!pattern.getSubjectVar().equals(subject)) {
- throw new IllegalStateException("At least one of the patterns has a different subject from the others. " +
- "All subjects must be the same.");
- }
- }
- }
-
- /**
- * Verifies all of the Statement Patterns have Constants for their predicates.
- *
- * @param patterns - The patterns to check. (not null)
- * @throws IllegalStateException A pattern has a variable predicate.
- */
- private static void verifyAllPredicatesAreConstants(final Collection<StatementPattern> patterns) throws IllegalStateException {
- requireNonNull(patterns);
-
- for(final StatementPattern pattern : patterns) {
- if(!pattern.getPredicateVar().isConstant()) {
- throw new IllegalStateException("The Predicate of a Statement Pattern must be constant. Pattern: " + pattern);
- }
- }
- }
-
- @Override
- public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(final BindingSet bindings) throws QueryEvaluationException {
- final List<BindingSet> list = new ArrayList<>();
- try {
- final Collection<Event> searchEvents;
- final String subj;
- //if the provided binding set has the subject already, set it to the constant subject.
- if(!subjectConstant.isPresent() && bindings.hasBinding(subjectVar.get())) {
- subjectConstant = Optional.of(bindings.getValue(subjectVar.get()).stringValue());
- } else if(bindings.size() != 0) {
- list.add(bindings);
- }
-
- // If the subject needs to be filled in, check if the subject variable is in the binding set.
- if(subjectConstant.isPresent()) {
- // if it is, fetch that value and then fetch the entity for the subject.
- subj = subjectConstant.get();
- searchEvents = eventStore.search(Optional.of(new RyaURI(subj)), Optional.of(geoFilters), Optional.of(temporalFilters));
- } else {
- searchEvents = eventStore.search(Optional.empty(), Optional.of(geoFilters), Optional.of(temporalFilters));
- }
-
- for(final Event event : searchEvents) {
- final MapBindingSet resultSet = new MapBindingSet();
- if(event.getGeometry().isPresent()) {
- final Geometry geo = event.getGeometry().get();
- final Value geoValue = ValueFactoryImpl.getInstance().createLiteral(geo.toText());
- final Var geoObj = geoPattern.getObjectVar();
- resultSet.addBinding(geoObj.getName(), geoValue);
- }
-
- final Value temporalValue;
- if(event.isInstant() && event.getInstant().isPresent()) {
- final Optional<TemporalInstant> opt = event.getInstant();
- DateTime dt = opt.get().getAsDateTime();
- dt = dt.toDateTime(DateTimeZone.UTC);
- final String str = dt.toString(TemporalInstantRfc3339.FORMATTER);
- temporalValue = ValueFactoryImpl.getInstance().createLiteral(str);
- } else if(event.getInterval().isPresent()) {
- temporalValue = ValueFactoryImpl.getInstance().createLiteral(event.getInterval().get().getAsPair());
- } else {
- temporalValue = null;
- }
-
- if(temporalValue != null) {
- final Var temporalObj = temporalPattern.getObjectVar();
- resultSet.addBinding(temporalObj.getName(), temporalValue);
- }
- list.add(resultSet);
- }
- } catch (final ObjectStorageException e) {
- throw new QueryEvaluationException("Failed to evaluate the binding set", e);
- }
- return new CollectionIteration<>(list);
- }
-
- public Collection<IndexingExpr> getGeoFilters() {
- return geoFilters;
- }
-
- public Collection<IndexingExpr> getTemporalFilters() {
- return temporalFilters;
- }
-
- public Collection<FunctionCall> getFilters() {
- return usedFilters;
- }
-
- public Collection<StatementPattern> getPatterns() {
- if(patterns == null) {
- patterns = new ArrayList<>();
- patterns.add(geoPattern);
- patterns.add(temporalPattern);
- }
- return patterns;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(subjectIsConstant,
- subjectVar,
- geoFilters,
- temporalFilters,
- geoPattern,
- temporalPattern,
- bindingNames,
- eventStore);
- }
-
- @Override
- public boolean equals(final Object other) {
- if(other instanceof EventQueryNode) {
- final EventQueryNode otherNode = (EventQueryNode)other;
- return new EqualsBuilder()
- .append(subjectIsConstant, otherNode.subjectIsConstant)
- .append(subjectVar, otherNode.subjectVar)
- .append(geoFilters, otherNode.geoFilters)
- .append(geoPattern, otherNode.geoPattern)
- .append(temporalFilters, otherNode.temporalFilters)
- .append(temporalPattern, otherNode.temporalPattern)
- .append(bindingNames, otherNode.bindingNames)
- .append(subjectConstant, otherNode.subjectConstant)
- .isEquals();
- }
- return false;
- }
-
- @Override
- public EventQueryNode clone() {
- return new EventQueryNode(eventStore, geoPattern, temporalPattern, geoFilters, temporalFilters, usedFilters);
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("Geo Pattern: " + geoPattern.toString());
- sb.append("\n--Geo Filters--\n");
- for(final IndexingExpr filter : geoFilters) {
- sb.append(filter.toString());
- sb.append("\n");
- }
- sb.append("\n-------------------\n");
- sb.append("Temporal Pattern: " + temporalPattern.toString());
- sb.append("\n--Temporal Filters--\n");
- for(final IndexingExpr filter : temporalFilters) {
- sb.append(filter.toString());
- sb.append("\n");
- }
- return sb.toString();
- }
-
- @Override
- public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(final Collection<BindingSet> bindingset)
- throws QueryEvaluationException {
- return null;
- }
-
- /**
- * Builder for {@link EventQueryNode}s.
- */
- public static class EventQueryNodeBuilder {
- private EventStorage store;
- private StatementPattern geoPattern;
- private StatementPattern temporalPattern;
- private Collection<IndexingExpr> geoFilters;
- private Collection<IndexingExpr> temporalFilters;
- private Collection<FunctionCall> usedFilters;
-
- /**
- * @param store - The {@link EventStorage} to use in the {@link EntityQueryNode}
- * @return - The Builder.
- */
- public EventQueryNodeBuilder setStorage(final EventStorage store) {
- this.store = store;
- return this;
- }
-
- /**
- * @param geoPattern - The geo {@link StatementPattern} to use in the {@link EntityQueryNode}
- * @return - The Builder.
- */
- public EventQueryNodeBuilder setGeoPattern(final StatementPattern geoPattern) {
- this.geoPattern = geoPattern;
- return this;
- }
-
- /**
- * @param temporalPattern - The temporal {@link StatementPattern} to use in the {@link EntityQueryNode}
- * @return - The Builder.
- */
- public EventQueryNodeBuilder setTemporalPattern(final StatementPattern temporalPattern) {
- this.temporalPattern = temporalPattern;
- return this;
- }
-
- /**
- * @param geoFilters - The geo filter(s) {@link IndexingExpr} to use in the {@link EntityQueryNode}
- * @return - The Builder.
- */
- public EventQueryNodeBuilder setGeoFilters(final Collection<IndexingExpr> geoFilters) {
- this.geoFilters = geoFilters;
- return this;
- }
-
- /**
- * @param temporalFilters - The temporal filter(s) {@link IndexingExpr} to use in the {@link EntityQueryNode}
- * @return - The Builder.
- */
- public EventQueryNodeBuilder setTemporalFilters(final Collection<IndexingExpr> temporalFilters) {
- this.temporalFilters = temporalFilters;
- return this;
- }
-
- /**
- * @param usedFilters - The filter(s) used by the {@link EntityQueryNode}
- * @return - The Builder.
- */
- public EventQueryNodeBuilder setUsedFilters(final Collection<FunctionCall> usedFilters) {
- this.usedFilters = usedFilters;
- return this;
- }
-
- /**
- * @return The {@link EntityQueryNode} built by the builder.
- */
- public EventQueryNode build() {
- return new EventQueryNode(store, geoPattern, temporalPattern, geoFilters, temporalFilters, usedFilters);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverter.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverter.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverter.java
deleted file mode 100644
index 926f357..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverter.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- * 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.geotemporal.mongo;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.Date;
-import java.util.List;
-
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.indexing.TemporalInstant;
-import org.apache.rya.indexing.TemporalInstantRfc3339;
-import org.apache.rya.indexing.TemporalInterval;
-import org.apache.rya.indexing.entity.storage.mongo.DocumentConverter;
-import org.apache.rya.indexing.geotemporal.model.Event;
-import org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy;
-import org.bson.Document;
-import org.joda.time.DateTime;
-
-import com.vividsolutions.jts.geom.Coordinate;
-import com.vividsolutions.jts.geom.CoordinateList;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.GeometryFactory;
-import com.vividsolutions.jts.geom.LinearRing;
-
-public class EventDocumentConverter implements DocumentConverter<Event>{
- public static final String SUBJECT = "_id";
- public static final String GEO_KEY = "location";
- public static final String INTERVAL_START = "start";
- public static final String INTERVAL_END = "end";
- public static final String INSTANT = "instant";
-
- private final GeoMongoDBStorageStrategy geoAdapter = new GeoMongoDBStorageStrategy(0.0);
-
- @Override
- public Document toDocument(final Event event) {
- requireNonNull(event);
-
- final Document doc = new Document();
- doc.append(SUBJECT, event.getSubject().getData());
-
- if(event.getGeometry().isPresent()) {
- if (event.getGeometry().get().getNumPoints() > 1) {
- doc.append(GEO_KEY, geoAdapter.getCorrespondingPoints(event.getGeometry().get()));
- } else {
- doc.append(GEO_KEY, geoAdapter.getDBPoint(event.getGeometry().get()));
- }
- }
- if(event.isInstant()) {
- if(event.getInstant().isPresent()) {
- doc.append(INSTANT, event.getInstant().get().getAsDateTime().toDate());
- }
- } else {
- if(event.getInterval().isPresent()) {
- doc.append(INTERVAL_START, event.getInterval().get().getHasBeginning().getAsDateTime().toDate());
- doc.append(INTERVAL_END, event.getInterval().get().getHasEnd().getAsDateTime().toDate());
- }
- }
-
- return doc;
- }
-
- @Override
- public Event fromDocument(final Document document) throws DocumentConverterException {
- requireNonNull(document);
-
- final boolean isInstant;
-
- // Preconditions.
- if(!document.containsKey(SUBJECT)) {
- throw new DocumentConverterException("Could not convert document '" + document +
- "' because its '" + SUBJECT + "' field is missing.");
- }
-
- if(document.containsKey(INSTANT)) {
- isInstant = true;
- } else {
- isInstant = false;
- }
-
- final String subject = document.getString(SUBJECT);
-
- final Event.Builder builder = new Event.Builder()
- .setSubject(new RyaURI(subject));
-
- if(document.containsKey(GEO_KEY)) {
- final Document geoObj = (Document) document.get(GEO_KEY);
- final GeometryFactory geoFact = new GeometryFactory();
- final String typeString = (String) geoObj.get("type");
- final CoordinateList coords = new CoordinateList();
- final Geometry geo;
- if (typeString.equals("Point")) {
- final List<Double> point = (List<Double>) geoObj.get("coordinates");
- final Coordinate coord = new Coordinate(point.get(0), point.get(1));
- geo = geoFact.createPoint(coord);
- } else if (typeString.equals("LineString")) {
- final List<List<Double>> pointsList = (List<List<Double>>) geoObj.get("coordinates");
- for (final List<Double> point : pointsList) {
- coords.add(new Coordinate(point.get(0), point.get(1)));
- }
- geo = geoFact.createLineString(coords.toCoordinateArray());
- } else {
- final List<List<List<Double>>> pointsList = (List<List<List<Double>>>) geoObj.get("coordinates");
- if(pointsList.size() == 1) {
- final List<List<Double>> poly = pointsList.get(0);
- for (final List<Double> point : poly) {
- coords.add(new Coordinate(point.get(0), point.get(1)));
- }
- geo = geoFact.createPolygon(coords.toCoordinateArray());
- } else {
- final List<List<Double>> first = pointsList.get(0);
- final CoordinateList shellCoords = new CoordinateList();
- for (final List<Double> point : pointsList.get(0)) {
- shellCoords.add(new Coordinate(point.get(0), point.get(1)));
- }
- final LinearRing shell = geoFact.createLinearRing(shellCoords.toCoordinateArray());
-
- final List<List<List<Double>>> holesPoints = pointsList.subList(1, pointsList.size() - 1);
- final LinearRing[] holes = new LinearRing[holesPoints.size()];
- for(int ii = 0; ii < holes.length; ii++) {
- final List<List<Double>> holePoints = holesPoints.get(ii);
- final CoordinateList shells = new CoordinateList();
- for (final List<Double> point : pointsList.get(0)) {
- shells.add(new Coordinate(point.get(0), point.get(1)));
- }
- holes[ii] = geoFact.createLinearRing(shells.toCoordinateArray());
- }
- geo = geoFact.createPolygon(shell,
- holes);
- }
- }
- builder.setGeometry(geo);
- }
-
- if(isInstant) {
- //we already know the key exists
- final Date date = (Date) document.get(INSTANT);
- final DateTime dt = new DateTime(date.getTime());
- final TemporalInstant instant = new TemporalInstantRfc3339(dt);
- builder.setTemporalInstant(instant);
- } else if(document.containsKey(INTERVAL_START)){
- Date date = (Date) document.get(INTERVAL_START);
- DateTime dt = new DateTime(date.getTime());
- final TemporalInstant begining = new TemporalInstantRfc3339(dt);
-
- date = (Date) document.get(INTERVAL_END);
- dt = new DateTime(date.getTime());
- final TemporalInstant end = new TemporalInstantRfc3339(dt);
-
- final TemporalInterval interval = new TemporalInterval(begining, end);
- builder.setTemporalInterval(interval);
- }
- return builder.build();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventUpdater.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventUpdater.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventUpdater.java
deleted file mode 100644
index 1c62407..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/EventUpdater.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * 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.geotemporal.mongo;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.Optional;
-
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.indexing.geotemporal.model.Event;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage.EventStorageException;
-import org.apache.rya.indexing.mongodb.update.MongoDocumentUpdater;
-import org.apache.rya.indexing.mongodb.update.RyaObjectStorage.ObjectStorageException;
-
-import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
-import edu.umd.cs.findbugs.annotations.NonNull;
-
-/**
- * Performs update operations over an {@link EventStorage}.
- */
-@DefaultAnnotation(NonNull.class)
-public class EventUpdater implements MongoDocumentUpdater<RyaURI, Event>{
- private final EventStorage events;
-
- /**
- * Constructs an instance of {@link EventUpdater}
- *
- * @param events - The storage this updater operates over. (not null)
- */
- public EventUpdater(final EventStorage events) {
- this.events = requireNonNull(events);
- }
-
- @Override
- public Optional<Event> getOld(final RyaURI key) throws EventStorageException {
- try {
- return events.get(key);
- } catch (final ObjectStorageException e) {
- throw new EventStorageException(e.getMessage(), e);
- }
- }
-
- @Override
- public void create(final Event newObj) throws EventStorageException {
- try {
- events.create(newObj);
- } catch (final ObjectStorageException e) {
- throw new EventStorageException(e.getMessage(), e);
- }
- }
-
- @Override
- public void update(final Event old, final Event updated) throws EventStorageException {
- try {
- events.update(old, updated);
- } catch (final ObjectStorageException e) {
- throw new EventStorageException(e.getMessage(), e);
- }
- }
-
- public void delete(final Event event) throws EventStorageException {
- try {
- events.delete(event.getSubject());
- } catch (final ObjectStorageException e) {
- throw new EventStorageException(e.getMessage(), e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategy.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategy.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategy.java
deleted file mode 100644
index 6e8ed99..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategy.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/**
- * 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.geotemporal.mongo;
-
-import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.EQUALS;
-import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.INTERSECTS;
-import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.WITHIN;
-import static org.apache.rya.indexing.mongodb.temporal.TemporalMongoDBStorageStrategy.INSTANT;
-import static org.apache.rya.indexing.mongodb.temporal.TemporalMongoDBStorageStrategy.INTERVAL_END;
-import static org.apache.rya.indexing.mongodb.temporal.TemporalMongoDBStorageStrategy.INTERVAL_START;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.regex.Matcher;
-
-import org.apache.log4j.Logger;
-import org.apache.rya.api.domain.RyaStatement;
-import org.apache.rya.api.resolver.RyaToRdfConversions;
-import org.apache.rya.indexing.GeoConstants;
-import org.apache.rya.indexing.IndexingExpr;
-import org.apache.rya.indexing.TemporalInstant;
-import org.apache.rya.indexing.TemporalInstantRfc3339;
-import org.apache.rya.indexing.TemporalInterval;
-import org.apache.rya.indexing.accumulo.geo.GeoParseUtils;
-import org.apache.rya.indexing.geotemporal.GeoTemporalIndexException;
-import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer.GeoPolicy;
-import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer.TemporalPolicy;
-import org.apache.rya.indexing.mongodb.IndexingMongoDBStorageStrategy;
-import org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy;
-import org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQuery;
-import org.apache.rya.indexing.mongodb.temporal.TemporalMongoDBStorageStrategy;
-import org.joda.time.DateTime;
-import org.openrdf.model.Statement;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.query.MalformedQueryException;
-
-import com.mongodb.BasicDBObject;
-import com.mongodb.BasicDBObjectBuilder;
-import com.mongodb.DBCollection;
-import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.io.ParseException;
-import com.vividsolutions.jts.io.WKTReader;
-
-import jline.internal.Log;
-
-/**
- * Storage adapter for serializing Geo Temporal statements into mongo objects.
- * This includes adapting the {@link IndexingExpr}s for the GeoTemporal indexer.
- */
-public class GeoTemporalMongoDBStorageStrategy extends IndexingMongoDBStorageStrategy {
- private static final Logger LOG = Logger.getLogger(GeoTemporalMongoDBStorageStrategy.class);
- private static final String GEO_KEY = "location";
- private static final String TIME_KEY = "time";
- private final TemporalMongoDBStorageStrategy temporalStrategy;
- private final GeoMongoDBStorageStrategy geoStrategy;
-
- public GeoTemporalMongoDBStorageStrategy() {
- geoStrategy = new GeoMongoDBStorageStrategy(0.0);
- temporalStrategy = new TemporalMongoDBStorageStrategy();
- }
-
- @Override
- public void createIndices(final DBCollection coll){
- coll.createIndex(new BasicDBObject(GEO_KEY, "2dsphere"));
- coll.createIndex(TIME_KEY);
- }
-
- public DBObject getFilterQuery(final Collection<IndexingExpr> geoFilters, final Collection<IndexingExpr> temporalFilters) throws GeoTemporalIndexException {
- final QueryBuilder builder = QueryBuilder.start();
-
- if(!geoFilters.isEmpty()) {
- final DBObject[] geo = getGeoObjs(geoFilters);
- if(!temporalFilters.isEmpty()) {
- final DBObject[] temporal = getTemporalObjs(temporalFilters);
- builder.and(oneOrAnd(geo), oneOrAnd(temporal));
- return builder.get();
- } else {
- return oneOrAnd(geo);
- }
- } else if(!temporalFilters.isEmpty()) {
- final DBObject[] temporal = getTemporalObjs(temporalFilters);
- return oneOrAnd(temporal);
- } else {
- return builder.get();
- }
- }
-
- private DBObject oneOrAnd(final DBObject[] dbos) {
- if(dbos.length == 1) {
- return dbos[0];
- }
- return QueryBuilder.start()
- .and(dbos)
- .get();
- }
-
- @Override
- public DBObject serialize(final RyaStatement ryaStatement) {
- final BasicDBObjectBuilder builder = BasicDBObjectBuilder.start("_id", ryaStatement.getSubject().hashCode());
- final URI obj = ryaStatement.getObject().getDataType();
-
-
- if(obj.equals(GeoConstants.GEO_AS_WKT) || obj.equals(GeoConstants.GEO_AS_GML) ||
- obj.equals(GeoConstants.XMLSCHEMA_OGC_GML) || obj.equals(GeoConstants.XMLSCHEMA_OGC_WKT)) {
- try {
- final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
- final Geometry geo = GeoParseUtils.getGeometry(statement);
- if (geo.getNumPoints() > 1) {
- builder.add(GEO_KEY, geoStrategy.getCorrespondingPoints(geo));
- } else {
- builder.add(GEO_KEY, geoStrategy.getDBPoint(geo));
- }
- } catch (final ParseException e) {
- LOG.error("Could not create geometry for statement " + ryaStatement, e);
- return null;
- }
- } else {
- builder.add(TIME_KEY, temporalStrategy.getTimeValue(ryaStatement.getObject().getData()));
- }
- return builder.get();
- }
-
- private DBObject[] getGeoObjs(final Collection<IndexingExpr> geoFilters) {
- final List<DBObject> objs = new ArrayList<>();
- geoFilters.forEach(filter -> {
- final GeoPolicy policy = GeoPolicy.fromURI(filter.getFunction());
- final WKTReader reader = new WKTReader();
- final String geoStr = ((Value) filter.getArguments()[0]).stringValue();
- try {
- //This method is what is used in the GeoIndexer.
- final Geometry geo = reader.read(geoStr);
- objs.add(getGeoObject(geo, policy));
- } catch (final GeoTemporalIndexException | UnsupportedOperationException | ParseException e) {
- Log.error("Unable to parse '" + geoStr + "'.", e);
- }
- });
- return objs.toArray(new DBObject[]{});
- }
-
- private DBObject[] getTemporalObjs(final Collection<IndexingExpr> temporalFilters) {
- final List<DBObject> objs = new ArrayList<>();
- temporalFilters.forEach(filter -> {
- final TemporalPolicy policy = TemporalPolicy.fromURI(filter.getFunction());
- final String timeStr = ((Value) filter.getArguments()[0]).stringValue();
- final Matcher matcher = TemporalInstantRfc3339.PATTERN.matcher(timeStr);
- if(matcher.find()) {
- final TemporalInterval interval = TemporalInstantRfc3339.parseInterval(timeStr);
- if(policy == TemporalPolicy.INSTANT_AFTER_INSTANT ||
- policy == TemporalPolicy.INSTANT_BEFORE_INSTANT ||
- policy == TemporalPolicy.INSTANT_EQUALS_INSTANT) {
- if(interval == null) {
- Log.error("Cannot perform temporal interval based queries on an instant.");
- }
- }
- objs.add(getTemporalObject(interval, policy));
- } else {
- final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.parse(timeStr));
- if(policy != TemporalPolicy.INSTANT_AFTER_INSTANT &&
- policy != TemporalPolicy.INSTANT_BEFORE_INSTANT &&
- policy != TemporalPolicy.INSTANT_EQUALS_INSTANT) {
- Log.error("Cannot perform temporal instant based queries on an interval.");
- }
- objs.add(getTemporalObject(instant, policy));
- }
- });
- return objs.toArray(new DBObject[]{});
- }
-
- private DBObject getGeoObject (final Geometry geo, final GeoPolicy policy) throws GeoTemporalIndexException {
- switch(policy) {
- case CONTAINS:
- throw new UnsupportedOperationException("Contains queries are not supported in Mongo DB.");
- case CROSSES:
- throw new UnsupportedOperationException("Crosses queries are not supported in Mongo DB.");
- case DISJOINT:
- throw new UnsupportedOperationException("Disjoint queries are not supported in Mongo DB.");
- case EQUALS:
- try {
- return geoStrategy.getQuery(new GeoQuery(EQUALS, geo));
- } catch (final MalformedQueryException e) {
- throw new GeoTemporalIndexException(e.getMessage(), e);
- }
- case INTERSECTS:
- try {
- return geoStrategy.getQuery(new GeoQuery(INTERSECTS, geo));
- } catch (final MalformedQueryException e) {
- throw new GeoTemporalIndexException(e.getMessage(), e);
- }
- case OVERLAPS:
- throw new UnsupportedOperationException("Overlaps queries are not supported in Mongo DB.");
- case TOUCHES:
- throw new UnsupportedOperationException("Touches queries are not supported in Mongo DB.");
- case WITHIN:
- try {
- return geoStrategy.getQuery(new GeoQuery(WITHIN, geo));
- } catch (final MalformedQueryException e) {
- throw new GeoTemporalIndexException(e.getMessage(), e);
- }
- default:
- return new BasicDBObject();
- }
- }
-
- private DBObject getTemporalObject(final TemporalInstant instant, final TemporalPolicy policy) {
- final DBObject temporalObj;
- switch(policy) {
- case INSTANT_AFTER_INSTANT:
- temporalObj = QueryBuilder.start(INSTANT)
- .greaterThan(instant.getAsDateTime().toDate())
- .get();
- break;
- case INSTANT_BEFORE_INSTANT:
- temporalObj = QueryBuilder.start(INSTANT)
- .lessThan(instant.getAsDateTime().toDate())
- .get();
- break;
- case INSTANT_EQUALS_INSTANT:
- temporalObj = QueryBuilder.start(INSTANT)
- .is(instant.getAsDateTime().toDate())
- .get();
- break;
- default:
- temporalObj = new BasicDBObject();
- }
- return temporalObj;
- }
-
- private DBObject getTemporalObject(final TemporalInterval interval, final TemporalPolicy policy) {
- final DBObject temporalObj;
- switch(policy) {
- case INSTANT_AFTER_INTERVAL:
- temporalObj = QueryBuilder.start(INSTANT)
- .greaterThan(interval.getHasEnd().getAsDateTime().toDate())
- .get();
- break;
- case INSTANT_BEFORE_INTERVAL:
- temporalObj = QueryBuilder.start(INSTANT)
- .lessThan(interval.getHasBeginning().getAsDateTime().toDate())
- .get();
- break;
- case INSTANT_END_INTERVAL:
- temporalObj = QueryBuilder.start(INSTANT)
- .is(interval.getHasEnd().getAsDateTime().toDate())
- .get();
- break;
- case INSTANT_IN_INTERVAL:
- temporalObj = QueryBuilder.start(INSTANT)
- .greaterThan(interval.getHasBeginning().getAsDateTime().toDate())
- .lessThan(interval.getHasEnd().getAsDateTime().toDate())
- .get();
- break;
- case INSTANT_START_INTERVAL:
- temporalObj = QueryBuilder.start(INSTANT)
- .is(interval.getHasBeginning().getAsDateTime().toDate())
- .get();
- break;
- case INTERVAL_AFTER:
- temporalObj = QueryBuilder.start(INTERVAL_START)
- .greaterThan(interval.getHasEnd().getAsDateTime().toDate())
- .get();
- break;
- case INTERVAL_BEFORE:
- temporalObj = QueryBuilder.start(INTERVAL_END)
- .lessThan(interval.getHasBeginning().getAsDateTime().toDate())
- .get();
- break;
- case INTERVAL_EQUALS:
- temporalObj = QueryBuilder.start(INTERVAL_START)
- .is(interval.getHasBeginning().getAsDateTime().toDate())
- .and(INTERVAL_END)
- .is(interval.getHasEnd().getAsDateTime().toDate())
- .get();
- break;
- default:
- temporalObj = new BasicDBObject();
- }
- return temporalObj;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorage.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorage.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorage.java
deleted file mode 100644
index 9c13c8b..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorage.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * 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.geotemporal.mongo;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.indexing.IndexingExpr;
-import org.apache.rya.indexing.entity.model.TypedEntity;
-import org.apache.rya.indexing.entity.storage.mongo.DocumentConverter.DocumentConverterException;
-import org.apache.rya.indexing.entity.storage.mongo.MongoEntityStorage;
-import org.apache.rya.indexing.geotemporal.GeoTemporalIndexException;
-import org.apache.rya.indexing.geotemporal.model.Event;
-import org.apache.rya.indexing.geotemporal.storage.EventStorage;
-import org.bson.BsonDocument;
-import org.bson.BsonString;
-import org.bson.Document;
-import org.bson.conversions.Bson;
-
-import com.mongodb.BasicDBObjectBuilder;
-import com.mongodb.DBObject;
-import com.mongodb.ErrorCategory;
-import com.mongodb.MongoClient;
-import com.mongodb.MongoException;
-import com.mongodb.client.MongoCollection;
-import com.mongodb.client.MongoCursor;
-import com.mongodb.client.model.Filters;
-
-public class MongoEventStorage implements EventStorage {
-
- protected static final String COLLECTION_NAME = "geotemporal-events";
-
- private static final EventDocumentConverter EVENT_CONVERTER = new EventDocumentConverter();
-
- /**
- * A client connected to the Mongo instance that hosts the Rya instance.
- */
- protected final MongoClient mongo;
-
- /**
- * The name of the Rya instance the {@link TypedEntity}s are for.
- */
- protected final String ryaInstanceName;
-
- /*
- * Used to get the filter query objects.
- */
- private final GeoTemporalMongoDBStorageStrategy queryAdapter;
-
- /**
- * Constructs an instance of {@link MongoEntityStorage}.
- *
- * @param mongo - A client connected to the Mongo instance that hosts the Rya instance. (not null)
- * @param ryaInstanceName - The name of the Rya instance the {@link TypedEntity}s are for. (not null)
- */
- public MongoEventStorage(final MongoClient mongo, final String ryaInstanceName) {
- this.mongo = requireNonNull(mongo);
- this.ryaInstanceName = requireNonNull(ryaInstanceName);
- queryAdapter = new GeoTemporalMongoDBStorageStrategy();
- }
-
- @Override
- public void create(final Event event) throws EventStorageException {
- requireNonNull(event);
-
- try {
- mongo.getDatabase(ryaInstanceName)
- .getCollection(COLLECTION_NAME)
- .insertOne(EVENT_CONVERTER.toDocument(event));
- } catch(final MongoException e) {
- final ErrorCategory category = ErrorCategory.fromErrorCode( e.getCode() );
- if(category == ErrorCategory.DUPLICATE_KEY) {
- throw new EventAlreadyExistsException("Failed to create Event with Subject '" + event.getSubject().getData() + "'.", e);
- }
- throw new EventStorageException("Failed to create Event with Subject '" + event.getSubject().getData() + "'.", e);
- }
- }
-
- @Override
- public Optional<Event> get(final RyaURI subject) throws EventStorageException {
- requireNonNull(subject);
-
- try {
- final Document document = mongo.getDatabase(ryaInstanceName)
- .getCollection(COLLECTION_NAME)
- .find( new BsonDocument(EventDocumentConverter.SUBJECT, new BsonString(subject.getData())) )
- .first();
-
- return document == null ?
- Optional.empty() :
- Optional.of( EVENT_CONVERTER.fromDocument(document) );
-
- } catch(final MongoException | DocumentConverterException e) {
- throw new EventStorageException("Could not get the Event with Subject '" + subject.getData() + "'.", e);
- }
- }
-
- @Override
- public Collection<Event> search(final Optional<RyaURI> subject, final Optional<Collection<IndexingExpr>> geoFilters, final Optional<Collection<IndexingExpr>> temporalFilters) throws EventStorageException {
- requireNonNull(subject);
-
- try {
- final Collection<IndexingExpr> geos = (geoFilters.isPresent() ? geoFilters.get() : new ArrayList<>());
- final Collection<IndexingExpr> tempos = (temporalFilters.isPresent() ? temporalFilters.get() : new ArrayList<>());
- final DBObject filterObj = queryAdapter.getFilterQuery(geos, tempos);
-
- final BasicDBObjectBuilder builder = BasicDBObjectBuilder
- .start(filterObj.toMap());
- if(subject.isPresent()) {
- builder.append(EventDocumentConverter.SUBJECT, subject.get().getData());
- }
- final MongoCursor<Document> results = mongo.getDatabase(ryaInstanceName)
- .getCollection(COLLECTION_NAME)
- .find( BsonDocument.parse(builder.get().toString()) )
- .iterator();
-
- final List<Event> events = new ArrayList<>();
- while(results.hasNext()) {
- events.add(EVENT_CONVERTER.fromDocument(results.next()));
- }
- return events;
- } catch(final MongoException | DocumentConverterException | GeoTemporalIndexException e) {
- throw new EventStorageException("Could not get the Event.", e);
- }
- }
-
- @Override
- public void update(final Event old, final Event updated) throws StaleUpdateException, EventStorageException {
- requireNonNull(old);
- requireNonNull(updated);
-
- // The updated entity must have the same Subject as the one it is replacing.
- if(!old.getSubject().equals(updated.getSubject())) {
- throw new EventStorageException("The old Event and the updated Event must have the same Subject. " +
- "Old Subject: " + old.getSubject().getData() + ", Updated Subject: " + updated.getSubject().getData());
- }
-
- final Set<Bson> filters = new HashSet<>();
-
- // Must match the old entity's Subject.
- filters.add( makeSubjectFilter(old.getSubject()) );
-
- // Do a find and replace.
- final Bson oldEntityFilter = Filters.and(filters);
- final Document updatedDoc = EVENT_CONVERTER.toDocument(updated);
-
- final MongoCollection<Document> collection = mongo.getDatabase(ryaInstanceName).getCollection(COLLECTION_NAME);
- if(collection.findOneAndReplace(oldEntityFilter, updatedDoc) == null) {
- throw new StaleUpdateException("Could not update the Event with Subject '" + updated.getSubject().getData() + ".");
- }
- }
-
- @Override
- public boolean delete(final RyaURI subject) throws EventStorageException {
- requireNonNull(subject);
-
- try {
- final Document deleted = mongo.getDatabase(ryaInstanceName)
- .getCollection(COLLECTION_NAME)
- .findOneAndDelete( makeSubjectFilter(subject) );
-
- return deleted != null;
-
- } catch(final MongoException e) {
- throw new EventStorageException("Could not delete the Event with Subject '" + subject.getData() + "'.", e);
- }
- }
-
- private static Bson makeSubjectFilter(final RyaURI subject) {
- return Filters.eq(EventDocumentConverter.SUBJECT, subject.getData());
- }
-}
[07/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerTest.java b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerTest.java
new file mode 100644
index 0000000..93cabc4
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/mongo/MongoGeoIndexerTest.java
@@ -0,0 +1,370 @@
+package org.apache.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 org.apache.rya.api.resolver.RdfToRyaConversions.convertStatement;
+import static org.apache.rya.indexing.GeoIndexingTestUtils.getSet;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.StatementConstraints;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.geotemporal.mongo.MongoITBase;
+import org.apache.rya.indexing.accumulo.geo.OptionalConfigUtils;
+import org.apache.rya.indexing.mongodb.geo.MongoGeoIndexer;
+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;
+
+public class MongoGeoIndexerTest extends MongoITBase {
+ private static final StatementConstraints EMPTY_CONSTRAINTS = new StatementConstraints();
+ GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
+
+ @Before
+ public void before() throws Exception {
+ conf.set(ConfigUtils.GEO_PREDICATES_LIST, "http://www.opengis.net/ont/geosparql#asWKT");
+ conf.set(OptionalConfigUtils.USE_GEO, "true");
+ }
+
+ @Test
+ public void testRestrictPredicatesSearch() throws Exception {
+ conf.setStrings(ConfigUtils.GEO_PREDICATES_LIST, "pred:1,pred:2");
+ try (final MongoGeoIndexer f = new MongoGeoIndexer()) {
+ f.initIndexer(conf, super.getMongoClient());
+
+ 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));
+ }
+ }
+
+ @Test
+ public void testPrimeMeridianSearch() throws Exception {
+ try (final MongoGeoIndexer f = new MongoGeoIndexer()) {
+ f.initIndexer(conf, super.getMongoClient());
+
+ 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
+ f.initIndexer(conf, super.getMongoClient());
+
+ 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
+ f.initIndexer(conf, super.getMongoClient());
+
+ 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
+ f.initIndexer(conf, super.getMongoClient());
+
+ 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
+ f.initIndexer(conf, super.getMongoClient());
+
+ 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
+ f.initIndexer(conf, super.getMongoClient());
+
+ 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
+ f.initIndexer(conf, super.getMongoClient());
+
+ 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 (final MongoGeoIndexer f = new MongoGeoIndexer()) {
+ f.initIndexer(conf, super.getMongoClient());
+
+ 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/9e76b8d7/extras/rya.geoindexing/pom.xml
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/pom.xml b/extras/rya.geoindexing/pom.xml
index a2127aa..9ba4ed0 100644
--- a/extras/rya.geoindexing/pom.xml
+++ b/extras/rya.geoindexing/pom.xml
@@ -11,27 +11,44 @@
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.rya</groupId>
- <artifactId>rya.extras</artifactId>
- <version>3.2.11-incubating-SNAPSHOT</version>
- </parent>
-
- <artifactId>rya.geoindexing</artifactId>
- <name>Apache Rya Geospatial Secondary Indexing (Optional)</name>
-
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.rya</groupId>
+ <artifactId>rya.extras</artifactId>
+ <version>3.2.11-incubating-SNAPSHOT</version>
+ </parent>
+ <artifactId>rya.geoindexing</artifactId>
+ <packaging>pom</packaging>
+ <name>Apache Rya Geo Indexing Projects</name>
+ <description>This parent has several alternative implementations using different libraries or versions of the same library.
+ Specifically
+ Geomesa depends on geotools v5.1 and
+ GeoWave depends on geotools v6.
+ See the module poms for the actual versions.
+ </description>
+ <modules>
+ <!-- common for all implementations -->
+ <!-- geomesa for accumulo, uses geotools (not compatible with geowave's dependencies) -->
+ <!-- geo wave for accumulo, uses geotools (not compatible with geomesa's dependencies) -->
+ <!-- mongo native geo, not accumulo -->
+ <module>geo.common</module>
+ <module>geo.geomesa</module>
+ <module>geo.geowave</module>
+ <module>geo.mongo</module>
+ </modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <geotools.version>14.3</geotools.version>
</properties>
- <dependencies>
-
- <dependency>
- <groupId>org.apache.accumulo</groupId>
+ <dependencies>
+ <dependency>
+ <groupId>com.vividsolutions</groupId>
+ <artifactId>jts</artifactId>
+ <version>1.13</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.accumulo</groupId>
<artifactId>accumulo-minicluster</artifactId>
<scope>test</scope>
</dependency>
@@ -78,34 +95,16 @@
<artifactId>commons-codec</artifactId>
</dependency>
- <!-- Geo Indexing -->
- <dependency>
- <groupId>org.locationtech.geomesa</groupId>
- <artifactId>geomesa-accumulo-datastore_2.11</artifactId>
- </dependency>
-
- <dependency>
- <groupId>mil.nga.giat</groupId>
- <artifactId>geowave-datastore-accumulo</artifactId>
- <version>${geowave.version}</version>
- </dependency>
-
- <dependency>
- <groupId>mil.nga.giat</groupId>
- <artifactId>geowave-adapter-vector</artifactId>
- <version>${geowave.version}</version>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <scope>test</scope>
- </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.apache.rya</groupId>
<artifactId>accumulo.rya</artifactId>
@@ -118,104 +117,90 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.geotools.xsd</groupId>
- <artifactId>gt-xsd-gml3</artifactId>
- <version>${geotools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.geotools</groupId>
- <artifactId>gt-api</artifactId>
- <version>${geotools.version}</version>
- </dependency>
- <dependency>
- <groupId>com.vividsolutions</groupId>
- <artifactId>jts</artifactId>
- <version>1.13</version>
- </dependency>
</dependencies>
- <build>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.rat</groupId>
- <artifactId>apache-rat-plugin</artifactId>
- <configuration>
- <excludes>
- <!-- RDF data Files -->
- <exclude>**/*.ttl</exclude>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <!-- RDF data Files -->
+ <exclude>**/*.ttl</exclude>
+
+ <!-- Services Files -->
+ <exclude>**/resources/META-INF/services/**</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <shadedArtifactAttached>true</shadedArtifactAttached>
+ <shadedClassifierName>map-reduce</shadedClassifierName>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
+ </transformers>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ <execution>
+ <id>accumulo-server</id>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <shadedArtifactAttached>true</shadedArtifactAttached>
+ <shadedClassifierName>accumulo-server</shadedClassifierName>
+ <artifactSet>
+ <excludes>
+ <exclude>org.locationtech.geomesa:*</exclude>
+ <exclude>mil.nga.giat:*</exclude>
+ <exclude>scala:*</exclude>
+ <exclude>org.apache.accumulo:*</exclude>
+ <exclude>org.apache.thrift:*</exclude>
+ <exclude>org.apache.hadoop:*</exclude>
+ <exclude>org.apache.zookeeper:*</exclude>
+ </excludes>
+ </artifactSet>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
+ </transformers>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
- <!-- Services Files -->
- <exclude>**/resources/META-INF/services/**</exclude>
- </excludes>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>shade</goal>
- </goals>
- <configuration>
- <shadedArtifactAttached>true</shadedArtifactAttached>
- <shadedClassifierName>map-reduce</shadedClassifierName>
- <transformers>
- <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
- </transformers>
- <filters>
- <filter>
- <artifact>*:*</artifact>
- <excludes>
- <exclude>META-INF/*.SF</exclude>
- <exclude>META-INF/*.DSA</exclude>
- <exclude>META-INF/*.RSA</exclude>
- </excludes>
- </filter>
- </filters>
- </configuration>
- </execution>
- <execution>
- <id>accumulo-server</id>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- <configuration>
- <shadedArtifactAttached>true</shadedArtifactAttached>
- <shadedClassifierName>accumulo-server</shadedClassifierName>
- <artifactSet>
- <excludes>
- <exclude>org.locationtech.geomesa:*</exclude>
- <exclude>mil.nga.giat:*</exclude>
- <exclude>scala:*</exclude>
- <exclude>org.apache.accumulo:*</exclude>
- <exclude>org.apache.thrift:*</exclude>
- <exclude>org.apache.hadoop:*</exclude>
- <exclude>org.apache.zookeeper:*</exclude>
- </excludes>
- </artifactSet>
- <transformers>
- <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
- </transformers>
- <filters>
- <filter>
- <artifact>*:*</artifact>
- <excludes>
- <exclude>META-INF/*.SF</exclude>
- <exclude>META-INF/*.DSA</exclude>
- <exclude>META-INF/*.RSA</exclude>
- </excludes>
- </filter>
- </filters>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoEnabledFilterFunctionOptimizer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoEnabledFilterFunctionOptimizer.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoEnabledFilterFunctionOptimizer.java
deleted file mode 100644
index b7c49d8..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoEnabledFilterFunctionOptimizer.java
+++ /dev/null
@@ -1,332 +0,0 @@
-package org.apache.rya.indexing;
-
-/*
- * 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.io.IOException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableExistsException;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.commons.lang.Validate;
-import org.apache.hadoop.conf.Configurable;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.log4j.Logger;
-import org.apache.rya.accumulo.AccumuloRdfConfiguration;
-import org.apache.rya.indexing.IndexingFunctionRegistry.FUNCTION_TYPE;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.accumulo.freetext.AccumuloFreeTextIndexer;
-import org.apache.rya.indexing.accumulo.freetext.FreeTextTupleSet;
-import org.apache.rya.indexing.accumulo.geo.GeoMesaGeoIndexer;
-import org.apache.rya.indexing.accumulo.geo.GeoParseUtils;
-import org.apache.rya.indexing.accumulo.geo.GeoTupleSet;
-import org.apache.rya.indexing.accumulo.temporal.AccumuloTemporalIndexer;
-import org.apache.rya.indexing.mongodb.freetext.MongoFreeTextIndexer;
-import org.apache.rya.indexing.mongodb.geo.MongoGeoIndexer;
-import org.apache.rya.indexing.mongodb.temporal.MongoTemporalIndexer;
-import org.geotools.feature.SchemaException;
-import org.openrdf.model.Resource;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.model.ValueFactory;
-import org.openrdf.model.impl.URIImpl;
-import org.openrdf.model.impl.ValueFactoryImpl;
-import org.openrdf.query.BindingSet;
-import org.openrdf.query.Dataset;
-import org.openrdf.query.algebra.And;
-import org.openrdf.query.algebra.Filter;
-import org.openrdf.query.algebra.FunctionCall;
-import org.openrdf.query.algebra.Join;
-import org.openrdf.query.algebra.LeftJoin;
-import org.openrdf.query.algebra.QueryModelNode;
-import org.openrdf.query.algebra.StatementPattern;
-import org.openrdf.query.algebra.TupleExpr;
-import org.openrdf.query.algebra.ValueConstant;
-import org.openrdf.query.algebra.Var;
-import org.openrdf.query.algebra.evaluation.QueryOptimizer;
-import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
-
-import com.google.common.collect.Lists;
-
-public class GeoEnabledFilterFunctionOptimizer implements QueryOptimizer, Configurable {
- private static final Logger LOG = Logger.getLogger(GeoEnabledFilterFunctionOptimizer.class);
- private final ValueFactory valueFactory = new ValueFactoryImpl();
-
- private Configuration conf;
- private GeoIndexer geoIndexer;
- private FreeTextIndexer freeTextIndexer;
- private TemporalIndexer temporalIndexer;
- private boolean init = false;
-
- public GeoEnabledFilterFunctionOptimizer() {
- }
-
- public GeoEnabledFilterFunctionOptimizer(final AccumuloRdfConfiguration conf) throws AccumuloException, AccumuloSecurityException,
- TableNotFoundException, IOException, SchemaException, TableExistsException, NumberFormatException, UnknownHostException {
- this.conf = conf;
- init();
- }
-
- //setConf initializes FilterFunctionOptimizer so reflection can be used
- //to create optimizer in RdfCloudTripleStoreConnection
- @Override
- public void setConf(final Configuration conf) {
- this.conf = conf;
- //reset the init.
- init = false;
- init();
- }
-
- private synchronized void init() {
- if (!init) {
- if (ConfigUtils.getUseMongo(conf)) {
- geoIndexer = new MongoGeoIndexer();
- geoIndexer.setConf(conf);
- freeTextIndexer = new MongoFreeTextIndexer();
- freeTextIndexer.setConf(conf);
- temporalIndexer = new MongoTemporalIndexer();
- temporalIndexer.setConf(conf);
- } else {
- geoIndexer = new GeoMesaGeoIndexer();
- geoIndexer.setConf(conf);
- freeTextIndexer = new AccumuloFreeTextIndexer();
- freeTextIndexer.setConf(conf);
- temporalIndexer = new AccumuloTemporalIndexer();
- temporalIndexer.setConf(conf);
- }
- init = true;
- }
- }
-
- @Override
- public void optimize(final TupleExpr tupleExpr, final Dataset dataset, final BindingSet bindings) {
- // find variables used in property and resource based searches:
- final SearchVarVisitor searchVars = new SearchVarVisitor();
- tupleExpr.visit(searchVars);
- // rewrites for property searches:
- processPropertySearches(tupleExpr, searchVars.searchProperties);
-
- }
-
-
-
- private void processPropertySearches(final TupleExpr tupleExpr, final Collection<Var> searchProperties) {
- final MatchStatementVisitor matchStatements = new MatchStatementVisitor(searchProperties);
- tupleExpr.visit(matchStatements);
- for (final StatementPattern matchStatement: matchStatements.matchStatements) {
- final Var subject = matchStatement.getSubjectVar();
- if (subject.hasValue() && !(subject.getValue() instanceof Resource)) {
- throw new IllegalArgumentException("Query error: Found " + subject.getValue() + ", expected an URI or BNode");
- }
- Validate.isTrue(subject.hasValue() || subject.getName() != null);
- Validate.isTrue(!matchStatement.getObjectVar().hasValue() && matchStatement.getObjectVar().getName() != null);
- buildQuery(tupleExpr, matchStatement);
- }
- }
-
- private void buildQuery(final TupleExpr tupleExpr, final StatementPattern matchStatement) {
- //If our IndexerExpr (to be) is the rhs-child of LeftJoin, we can safely make that a Join:
- // the IndexerExpr will (currently) not return results that can deliver unbound variables.
- //This optimization should probably be generalized into a LeftJoin -> Join optimizer under certain conditions. Until that
- // has been done, this code path at least takes care of queries generated by OpenSahara SparqTool that filter on OPTIONAL
- // projections. E.g. summary~'full text search' (summary is optional). See #379
- if (matchStatement.getParentNode() instanceof LeftJoin) {
- final LeftJoin leftJoin = (LeftJoin)matchStatement.getParentNode();
- if (leftJoin.getRightArg() == matchStatement && leftJoin.getCondition() == null) {
- matchStatement.getParentNode().replaceWith(new Join(leftJoin.getLeftArg(), leftJoin.getRightArg()));
- }
- }
- final FilterFunction fVisitor = new FilterFunction(matchStatement.getObjectVar().getName());
- tupleExpr.visit(fVisitor);
- final List<IndexingExpr> results = Lists.newArrayList();
- for(int i = 0; i < fVisitor.func.size(); i++){
- results.add(new IndexingExpr(fVisitor.func.get(i), matchStatement, fVisitor.args.get(i)));
- }
- removeMatchedPattern(tupleExpr, matchStatement, new IndexerExprReplacer(results));
- }
-
- //find vars contained in filters
- private static class SearchVarVisitor extends QueryModelVisitorBase<RuntimeException> {
- private final Collection<Var> searchProperties = new ArrayList<Var>();
-
- @Override
- public void meet(final FunctionCall fn) {
- final URI fun = new URIImpl(fn.getURI());
- final Var result = IndexingFunctionRegistry.getResultVarFromFunctionCall(fun, fn.getArgs());
- if (result != null && !searchProperties.contains(result)) {
- searchProperties.add(result);
- }
- }
- }
-
- //find StatementPatterns containing filter variables
- private static class MatchStatementVisitor extends QueryModelVisitorBase<RuntimeException> {
- private final Collection<Var> propertyVars;
- private final Collection<Var> usedVars = new ArrayList<Var>();
- private final List<StatementPattern> matchStatements = new ArrayList<StatementPattern>();
-
- public MatchStatementVisitor(final Collection<Var> propertyVars) {
- this.propertyVars = propertyVars;
- }
-
- @Override public void meet(final StatementPattern statement) {
- final Var object = statement.getObjectVar();
- if (propertyVars.contains(object)) {
- if (usedVars.contains(object)) {
- throw new IllegalArgumentException("Illegal search, variable is used multiple times as object: " + object.getName());
- } else {
- usedVars.add(object);
- matchStatements.add(statement);
- }
- }
- }
- }
-
- private abstract class AbstractEnhanceVisitor extends QueryModelVisitorBase<RuntimeException> {
- final String matchVar;
- List<URI> func = Lists.newArrayList();
- List<Object[]> args = Lists.newArrayList();
-
- public AbstractEnhanceVisitor(final String matchVar) {
- this.matchVar = matchVar;
- }
-
- protected void addFilter(final URI uri, final Object[] values) {
- func.add(uri);
- args.add(values);
- }
- }
-
- //create indexing expression for each filter matching var in filter StatementPattern
- //replace old filter condition with true condition
- private class FilterFunction extends AbstractEnhanceVisitor {
- public FilterFunction(final String matchVar) {
- super(matchVar);
- }
-
- @Override
- public void meet(final FunctionCall call) {
- final URI fnUri = valueFactory.createURI(call.getURI());
- final Var resultVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(fnUri, call.getArgs());
- if (resultVar != null && resultVar.getName().equals(matchVar)) {
- addFilter(valueFactory.createURI(call.getURI()), GeoParseUtils.extractArguments(matchVar, call));
- if (call.getParentNode() instanceof Filter || call.getParentNode() instanceof And || call.getParentNode() instanceof LeftJoin) {
- call.replaceWith(new ValueConstant(valueFactory.createLiteral(true)));
- } else {
- throw new IllegalArgumentException("Query error: Found " + call + " as part of an expression that is too complex");
- }
- }
- }
-
- @Override
- public void meet(final Filter filter) {
- //First visit children, then condition (reverse of default):
- filter.getArg().visit(this);
- filter.getCondition().visit(this);
- }
- }
-
- private void removeMatchedPattern(final TupleExpr tupleExpr, final StatementPattern pattern, final TupleExprReplacer replacer) {
- final List<TupleExpr> indexTuples = replacer.createReplacement(pattern);
- if (indexTuples.size() > 1) {
- final VarExchangeVisitor vev = new VarExchangeVisitor(pattern);
- tupleExpr.visit(vev);
- Join join = new Join(indexTuples.remove(0), indexTuples.remove(0));
- for (final TupleExpr geo : indexTuples) {
- join = new Join(join, geo);
- }
- pattern.replaceWith(join);
- } else if (indexTuples.size() == 1) {
- pattern.replaceWith(indexTuples.get(0));
- pattern.setParentNode(null);
- } else {
- throw new IllegalStateException("Must have at least one replacement for matched StatementPattern.");
- }
- }
-
- private interface TupleExprReplacer {
- List<TupleExpr> createReplacement(TupleExpr org);
- }
-
- //replace each filter pertinent StatementPattern with corresponding index expr
- private class IndexerExprReplacer implements TupleExprReplacer {
- private final List<IndexingExpr> indxExpr;
- private final FUNCTION_TYPE type;
-
- public IndexerExprReplacer(final List<IndexingExpr> indxExpr) {
- this.indxExpr = indxExpr;
- final URI func = indxExpr.get(0).getFunction();
- type = IndexingFunctionRegistry.getFunctionType(func);
- }
-
- @Override
- public List<TupleExpr> createReplacement(final TupleExpr org) {
- final List<TupleExpr> indexTuples = Lists.newArrayList();
- switch (type) {
- case GEO:
- for (final IndexingExpr indx : indxExpr) {
- indexTuples.add(new GeoTupleSet(indx, geoIndexer));
- }
- break;
- case FREETEXT:
- for (final IndexingExpr indx : indxExpr) {
- indexTuples.add(new FreeTextTupleSet(indx, freeTextIndexer));
- }
- break;
- case TEMPORAL:
- for (final IndexingExpr indx : indxExpr) {
- indexTuples.add(new TemporalTupleSet(indx, temporalIndexer));
- }
- break;
- default:
- throw new IllegalArgumentException("Incorrect type!");
- }
- return indexTuples;
- }
- }
-
- private static class VarExchangeVisitor extends QueryModelVisitorBase<RuntimeException> {
- private final StatementPattern exchangeVar;
- public VarExchangeVisitor(final StatementPattern sp) {
- exchangeVar = sp;
- }
-
- @Override
- public void meet(final Join node) {
- final QueryModelNode lNode = node.getLeftArg();
- if (lNode instanceof StatementPattern) {
- exchangeVar.replaceWith(lNode);
- node.setLeftArg(exchangeVar);
- } else {
- super.meet(node);
- }
- }
- }
-
- @Override
- public Configuration getConf() {
- return conf;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoIndexer.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoIndexer.java
deleted file mode 100644
index d091d32..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoIndexer.java
+++ /dev/null
@@ -1,210 +0,0 @@
-package org.apache.rya.indexing;
-
-import org.openrdf.model.Statement;
-import org.openrdf.query.QueryEvaluationException;
-
-import com.vividsolutions.jts.geom.Geometry;
-
-/*
- * 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 info.aduna.iteration.CloseableIteration;
-import org.apache.rya.api.persist.index.RyaSecondaryIndexer;
-import org.apache.rya.indexing.accumulo.geo.GeoTupleSet.GeoSearchFunctionFactory.NearQuery;
-
-/**
- * A repository to store, index, and retrieve {@link Statement}s based on geospatial features.
- */
-public interface GeoIndexer extends RyaSecondaryIndexer {
- /**
- * Returns statements that contain a geometry that is equal to the queried {@link Geometry} and meet the {@link StatementConstraints}.
- *
- * <p>
- * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
- * <ul>
- * <li>
- * "Two geometries are topologically equal if their interiors intersect and no part of the interior or boundary of one geometry intersects the exterior of the other"
- * <li>"A is equal to B if A is within B and A contains B"
- * </ul>
- *
- * @param query
- * the queried geometry
- * @param contraints
- * the {@link StatementConstraints}
- * @return
- */
- public abstract CloseableIteration<Statement, QueryEvaluationException> queryEquals(Geometry query, StatementConstraints contraints);
-
- /**
- * Returns statements that contain a geometry that is disjoint to the queried {@link Geometry} and meet the {@link StatementConstraints}.
- *
- * <p>
- * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
- * <ul>
- * <li>"A and B are disjoint if they have no point in common. They form a set of disconnected geometries."
- * <li>"A and B are disjoint if A does not intersect B"
- * </ul>
- *
- * @param query
- * the queried geometry
- * @param contraints
- * the {@link StatementConstraints}
- * @return
- */
- public abstract CloseableIteration<Statement, QueryEvaluationException> queryDisjoint(Geometry query, StatementConstraints contraints);
-
- /**
- * Returns statements that contain a geometry that Intersects the queried {@link Geometry} and meet the {@link StatementConstraints}.
- *
- * <p>
- * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
- * <ul>
- * <li>"a intersects b: geometries a and b have at least one point in common."
- * <li>"not Disjoint"
- * </ul>
- *
- *
- * @param query
- * the queried geometry
- * @param contraints
- * the {@link StatementConstraints}
- * @return
- */
- public abstract CloseableIteration<Statement, QueryEvaluationException> queryIntersects(Geometry query, StatementConstraints contraints);
-
- /**
- * Returns statements that contain a geometry that Touches the queried {@link Geometry} and meet the {@link StatementConstraints}.
- *
- * <p>
- * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
- * <ul>
- * <li>"a touches b, they have at least one boundary point in common, but no interior points."
- * </ul>
- *
- *
- * @param query
- * the queried geometry
- * @param contraints
- * the {@link StatementConstraints}
- * @return
- */
- public abstract CloseableIteration<Statement, QueryEvaluationException> queryTouches(Geometry query, StatementConstraints contraints);
-
- /**
- * Returns statements that contain a geometry that crosses the queried {@link Geometry} and meet the {@link StatementConstraints}.
- *
- * <p>
- * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
- * <ul>
- * <li>
- * "a crosses b, they have some but not all interior points in common (and the dimension of the intersection is less than that of at least one of them)."
- * </ul>
- *
- * @param query
- * the queried geometry
- * @param contraints
- * the {@link StatementConstraints}
- * @return
- */
- public abstract CloseableIteration<Statement, QueryEvaluationException> queryCrosses(Geometry query, StatementConstraints contraints);
-
- /**
- * Returns statements that contain a geometry that is Within the queried {@link Geometry} and meet the {@link StatementConstraints}.
- *
- * <p>
- * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
- * <ul>
- * <li>"a is within b, a lies in the interior of b"
- * <li>Same as: "Contains(b,a)"
- * </ul>
- *
- *
- * @param query
- * the queried geometry
- * @param contraints
- * the {@link StatementConstraints}
- * @return
- */
- public abstract CloseableIteration<Statement, QueryEvaluationException> queryWithin(Geometry query, StatementConstraints contraints);
-
- /**
- * Returns statements that contain a geometry that Contains the queried {@link Geometry} and meet the {@link StatementConstraints}.
- *
- * <p>
- * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
- * <ul>
- * <li>b is within a. Geometry b lies in the interior of a. Another definition:
- * "a 'contains' b iff no points of b lie in the exterior of a, and at least one point of the interior of b lies in the interior of a"
- * <li>Same: Within(b,a)
- * </ul>
- *
- *
- * @param query
- * the queried geometry
- * @param contraints
- * the {@link StatementConstraints}
- * @return
- */
- public abstract CloseableIteration<Statement, QueryEvaluationException> queryContains(Geometry query, StatementConstraints contraints);
-
- /**
- * Returns statements that contain a geometry that Overlaps the queried {@link Geometry} and meet the {@link StatementConstraints}.
- *
- * <p>
- * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
- * <ul>
- * <li>a crosses b, they have some but not all interior points in common (and the dimension of the intersection is less than that of at
- * least one of them).
- * </ul>
- *
- *
- * @param query
- * the queried geometry
- * @param contraints
- * the {@link StatementConstraints}
- * @return
- */
- public abstract CloseableIteration<Statement, QueryEvaluationException> queryOverlaps(Geometry query, StatementConstraints contraints);
-
- /**
- * Returns statements that contain a geometry that is near the queried {@link Geometry} and meet the {@link StatementConstraints}.
- * <p>
- * A geometry is considered near if it within the min/max distances specified in the provided {@link NearQuery}. This will make a disc (specify max),
- * a donut(specify both), or a spheroid complement disc (specify min)
- * <p>
- * The distances are specified in meters and must be >= 0.
- * <p>
- * To specify max/min distances:
- * <ul>
- * <li>Enter parameters in order MAX, MIN -- Donut</li>
- * <li>Omit the MIN -- Disc</li>
- * <li>Enter 0 for MAX, and Enter parameter for MIN -- Spheroid complement Dist</li>
- * <li>Omit both -- Default max/min [TODO: Find these values]</li>
- * </ul>
- * <p>
- * Note: This query will not fail if the min is greater than the max, it will just return no results.
- *
- * @param query the queried geometry, with Optional min and max distance fields.
- * @param contraints the {@link StatementConstraints}
- * @return
- */
- public abstract CloseableIteration<Statement, QueryEvaluationException> queryNear(NearQuery query, StatementConstraints contraints);
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoIndexerType.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoIndexerType.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoIndexerType.java
deleted file mode 100644
index 1af51b0..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoIndexerType.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.apache.rya.indexing.accumulo.geo.GeoMesaGeoIndexer;
-import org.apache.rya.indexing.accumulo.geo.GeoWaveGeoIndexer;
-import org.apache.rya.indexing.mongodb.geo.MongoGeoIndexer;
-
-/**
- * A list of all the types of Geo indexers supported in Rya.
- */
-public enum GeoIndexerType {
- /**
- * Geo Mesa based indexer.
- */
- GEO_MESA(GeoMesaGeoIndexer.class),
- /**
- * Geo Wave based indexer.
- */
- GEO_WAVE(GeoWaveGeoIndexer.class),
- /**
- * MongoDB based indexer.
- */
- MONGO_DB(MongoGeoIndexer.class);
-
- private Class<? extends GeoIndexer> geoIndexerClass;
-
- /**
- * Creates a new {@link GeoIndexerType}.
- * @param geoIndexerClass the {@link GeoIndexer} {@link Class}.
- * (not {@code null})
- */
- private GeoIndexerType(final Class<? extends GeoIndexer> geoIndexerClass) {
- this.geoIndexerClass = checkNotNull(geoIndexerClass);
- }
-
- /**
- * @return the {@link GeoIndexer} {@link Class}. (not {@code null})
- */
- public Class<? extends GeoIndexer> getGeoIndexerClass() {
- return geoIndexerClass;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoRyaSailFactory.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoRyaSailFactory.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoRyaSailFactory.java
deleted file mode 100644
index 89933df..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/GeoRyaSailFactory.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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;
-
-import static java.util.Objects.requireNonNull;
-
-import java.net.UnknownHostException;
-import java.util.Objects;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.Connector;
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-import org.apache.hadoop.conf.Configuration;
-import org.openrdf.sail.Sail;
-import org.openrdf.sail.SailException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.mongodb.MongoClient;
-
-import org.apache.rya.accumulo.AccumuloRdfConfiguration;
-import org.apache.rya.accumulo.AccumuloRyaDAO;
-import org.apache.rya.accumulo.instance.AccumuloRyaInstanceDetailsRepository;
-import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
-import org.apache.rya.api.instance.RyaDetailsRepository.RyaDetailsRepositoryException;
-import org.apache.rya.api.instance.RyaDetailsToConfiguration;
-import org.apache.rya.api.layout.TablePrefixLayoutStrategy;
-import org.apache.rya.api.persist.RyaDAO;
-import org.apache.rya.api.persist.RyaDAOException;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.mongodb.MongoConnectorFactory;
-import org.apache.rya.mongodb.MongoDBRdfConfiguration;
-import org.apache.rya.mongodb.MongoDBRyaDAO;
-import org.apache.rya.mongodb.instance.MongoRyaInstanceDetailsRepository;
-import org.apache.rya.rdftriplestore.RdfCloudTripleStore;
-import org.apache.rya.rdftriplestore.inference.InferenceEngine;
-import org.apache.rya.rdftriplestore.inference.InferenceEngineException;
-import org.apache.rya.sail.config.RyaSailFactory;
-
-public class GeoRyaSailFactory {
- private static final Logger LOG = LoggerFactory.getLogger(GeoRyaSailFactory.class);
-
- /**
- * Creates an instance of {@link Sail} that is attached to a Rya instance.
- *
- * @param conf - Configures how the Sail object will be constructed. (not null)
- * @return A {@link Sail} object that is backed by a Rya datastore.
- * @throws SailException The object could not be created.
- */
- public static Sail getInstance(final Configuration conf) throws AccumuloException,
- AccumuloSecurityException, RyaDAOException, InferenceEngineException, SailException {
- requireNonNull(conf);
- return getRyaSail(conf);
- }
-
- private static Sail getRyaSail(final Configuration config) throws InferenceEngineException, RyaDAOException, AccumuloException, AccumuloSecurityException, SailException {
- final RdfCloudTripleStore store = new RdfCloudTripleStore();
- final RyaDAO<?> dao;
- final RdfCloudTripleStoreConfiguration rdfConfig;
-
- final String user;
- final String pswd;
- // XXX Should(?) be MongoDBRdfConfiguration.MONGO_COLLECTION_PREFIX inside the if below. RYA-135
- final String ryaInstance = config.get(RdfCloudTripleStoreConfiguration.CONF_TBL_PREFIX);
- Objects.requireNonNull(ryaInstance, "RyaInstance or table prefix is missing from configuration."+RdfCloudTripleStoreConfiguration.CONF_TBL_PREFIX);
-
- if(ConfigUtils.getUseMongo(config)) {
- final MongoDBRdfConfiguration mongoConfig = new MongoDBRdfConfiguration(config);
- rdfConfig = mongoConfig;
- final MongoClient client = MongoConnectorFactory.getMongoClient(config);
- try {
- final MongoRyaInstanceDetailsRepository ryaDetailsRepo = new MongoRyaInstanceDetailsRepository(client, mongoConfig.getCollectionName());
- RyaDetailsToConfiguration.addRyaDetailsToConfiguration(ryaDetailsRepo.getRyaInstanceDetails(), mongoConfig);
- } catch (final RyaDetailsRepositoryException e) {
- LOG.info("Instance does not have a rya details collection, skipping.");
- }
- dao = getMongoDAO((MongoDBRdfConfiguration)rdfConfig, client);
- } else {
- rdfConfig = new AccumuloRdfConfiguration(config);
- user = rdfConfig.get(ConfigUtils.CLOUDBASE_USER);
- pswd = rdfConfig.get(ConfigUtils.CLOUDBASE_PASSWORD);
- Objects.requireNonNull(user, "Accumulo user name is missing from configuration."+ConfigUtils.CLOUDBASE_USER);
- Objects.requireNonNull(pswd, "Accumulo user password is missing from configuration."+ConfigUtils.CLOUDBASE_PASSWORD);
- rdfConfig.setTableLayoutStrategy( new TablePrefixLayoutStrategy(ryaInstance) );
- RyaSailFactory.updateAccumuloConfig((AccumuloRdfConfiguration) rdfConfig, user, pswd, ryaInstance);
- dao = getAccumuloDAO((AccumuloRdfConfiguration)rdfConfig);
- }
- store.setRyaDAO(dao);
- rdfConfig.setTablePrefix(ryaInstance);
-
- if (rdfConfig.isInfer()){
- final InferenceEngine inferenceEngine = new InferenceEngine();
- inferenceEngine.setConf(rdfConfig);
- inferenceEngine.setRyaDAO(dao);
- inferenceEngine.init();
- store.setInferenceEngine(inferenceEngine);
- }
-
- store.initialize();
-
- return store;
- }
-
- private static MongoDBRyaDAO getMongoDAO(final MongoDBRdfConfiguration config, final MongoClient client) throws RyaDAOException {
- MongoDBRyaDAO dao = null;
- OptionalConfigUtils.setIndexers(config);
- if(client != null) {
- dao = new MongoDBRyaDAO(config, client);
- } else {
- try {
- dao = new MongoDBRyaDAO(config);
- } catch (NumberFormatException | UnknownHostException e) {
- throw new RyaDAOException("Unable to connect to mongo at the configured location.", e);
- }
- }
- dao.init();
- return dao;
- }
-
- private static AccumuloRyaDAO getAccumuloDAO(final AccumuloRdfConfiguration config) throws AccumuloException, AccumuloSecurityException, RyaDAOException {
- final Connector connector = ConfigUtils.getConnector(config);
- final AccumuloRyaDAO dao = new AccumuloRyaDAO();
- dao.setConnector(connector);
-
- OptionalConfigUtils.setIndexers(config);
- config.setDisplayQueryPlan(true);
-
- dao.setConf(config);
- dao.init();
- return dao;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/OptionalConfigUtils.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/OptionalConfigUtils.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/OptionalConfigUtils.java
deleted file mode 100644
index 8d4486f..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/OptionalConfigUtils.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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;
-
-import java.util.List;
-import java.util.Set;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.log4j.Logger;
-import org.apache.rya.accumulo.AccumuloRdfConfiguration;
-import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
-import org.apache.rya.api.instance.RyaDetails;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.accumulo.geo.GeoMesaGeoIndexer;
-import org.apache.rya.indexing.geotemporal.GeoTemporalOptimizer;
-import org.apache.rya.indexing.geotemporal.mongo.MongoGeoTemporalIndexer;
-import org.apache.rya.indexing.mongodb.geo.MongoGeoIndexer;
-import org.openrdf.model.URI;
-
-import com.google.common.collect.Lists;
-
-/**
- * A set of configuration utils to read a Hadoop {@link Configuration} object and create Cloudbase/Accumulo objects.
- * Soon will deprecate this class. Use installer for the set methods, use {@link RyaDetails} for the get methods.
- * New code must separate parameters that are set at Rya install time from that which is specific to the client.
- * Also Accumulo index tables are pushed down to the implementation and not configured in conf.
- */
-public class OptionalConfigUtils extends ConfigUtils {
- private static final Logger logger = Logger.getLogger(OptionalConfigUtils.class);
-
-
- public static final String GEO_NUM_PARTITIONS = "sc.geo.numPartitions";
-
- public static final String USE_GEO = "sc.use_geo";
- public static final String USE_GEOTEMPORAL = "sc.use_geotemporal";
- public static final String USE_FREETEXT = "sc.use_freetext";
- public static final String USE_TEMPORAL = "sc.use_temporal";
- public static final String USE_ENTITY = "sc.use_entity";
- public static final String USE_PCJ = "sc.use_pcj";
- public static final String USE_OPTIMAL_PCJ = "sc.use.optimal.pcj";
- public static final String USE_PCJ_UPDATER_INDEX = "sc.use.updater";
- public static final String GEO_PREDICATES_LIST = "sc.geo.predicates";
- public static final String GEO_INDEXER_TYPE = "sc.geo.geo_indexer_type";
-
- public static Set<URI> getGeoPredicates(final Configuration conf) {
- return getPredicates(conf, GEO_PREDICATES_LIST);
- }
-
- public static int getGeoNumPartitions(final Configuration conf) {
- return conf.getInt(GEO_NUM_PARTITIONS, getNumPartitions(conf));
- }
-
- public static boolean getUseGeo(final Configuration conf) {
- return conf.getBoolean(USE_GEO, false);
- }
-
- public static boolean getUseGeoTemporal(final Configuration conf) {
- return conf.getBoolean(USE_GEOTEMPORAL, false);
- }
-
- /**
- * Retrieves the value for the geo indexer type from the config.
- * @param conf the {@link Configuration}.
- * @return the {@link GeoIndexerType} found in the config or
- * {@code null} if it doesn't exist.
- */
- public static GeoIndexerType getGeoIndexerType(final Configuration conf) {
- return conf.getEnum(GEO_INDEXER_TYPE, null);
- }
-
- public static void setIndexers(final RdfCloudTripleStoreConfiguration conf) {
- final List<String> indexList = Lists.newArrayList();
- final List<String> optimizers = Lists.newArrayList();
-
- boolean useFilterIndex = false;
- ConfigUtils.setIndexers(conf);
- final String[] existingIndexers = conf.getStrings(AccumuloRdfConfiguration.CONF_ADDITIONAL_INDEXERS);
- if(existingIndexers != null ) {
- for (final String index : existingIndexers) {
- indexList.add(index);
- }
- for (final String optimizer : conf.getStrings(RdfCloudTripleStoreConfiguration.CONF_OPTIMIZERS)){
- optimizers.add(optimizer);
- }
- }
-
- final GeoIndexerType geoIndexerType = getGeoIndexerType(conf);
-
- if (ConfigUtils.getUseMongo(conf)) {
- if (getUseGeo(conf)) {
- if (geoIndexerType == null) {
- // Default to MongoGeoIndexer if not specified
- indexList.add(MongoGeoIndexer.class.getName());
- } else {
- indexList.add(geoIndexerType.getGeoIndexerClass().getName());
- }
- useFilterIndex = true;
- }
-
- if (getUseGeoTemporal(conf)) {
- indexList.add(MongoGeoTemporalIndexer.class.getName());
- optimizers.add(GeoTemporalOptimizer.class.getName());
- }
- } else {
- if (getUseGeo(conf)) {
- if (geoIndexerType == null) {
- // Default to GeoMesaGeoIndexer if not specified
- indexList.add(GeoMesaGeoIndexer.class.getName());
- } else {
- indexList.add(geoIndexerType.getGeoIndexerClass().getName());
- }
- useFilterIndex = true;
- }
- }
-
- if (useFilterIndex) {
- optimizers.remove(FilterFunctionOptimizer.class.getName());
- optimizers.add(GeoEnabledFilterFunctionOptimizer.class.getName());
- }
-
- conf.setStrings(AccumuloRdfConfiguration.CONF_ADDITIONAL_INDEXERS, indexList.toArray(new String[]{}));
- conf.setStrings(RdfCloudTripleStoreConfiguration.CONF_OPTIMIZERS, optimizers.toArray(new String[]{}));
- }
-}
[03/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/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
deleted file mode 100644
index 708c612..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerTest.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * 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.api.resolver.RdfToRyaConversions.convertStatement;
-import static org.apache.rya.indexing.GeoIndexingTestUtils.getSet;
-
-import java.util.Collections;
-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;
-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;
-
-/**
- * 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;
- private final GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
-
- @Before
- public void before() throws Exception {
- conf = new AccumuloRdfConfiguration();
- conf.setTablePrefix("triplestore_");
- 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());
-
- 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);
- }
- }
-
- @Test
- public void testRestrictPredicatesSearch() throws Exception {
- conf.setStrings(ConfigUtils.GEO_PREDICATES_LIST, "pred:1,pred:2");
- try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
- f.setConf(conf);
-
- 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));
- }
- }
-
- @Test
- public void testPrimeMeridianSearch() throws Exception {
- try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
- f.setConf(conf);
-
- 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
- f.setConf(conf);
-
- 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
- f.setConf(conf);
-
- 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
- f.setConf(conf);
-
- 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
- f.setConf(conf);
-
- 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
- f.setConf(conf);
-
- 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
- f.setConf(conf);
-
- 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
- f.setConf(conf);
-
- 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/9e76b8d7/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
deleted file mode 100644
index e6ff81a..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveFeatureReaderTest.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * 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/9e76b8d7/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
deleted file mode 100644
index 778b5ef..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGTQueryTest.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * 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/9e76b8d7/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
deleted file mode 100644
index e49ac38..0000000
--- a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoWaveIndexerSfTest.java
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * 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);
- }
-
-}
[14/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
RYA-324, RYA-272 Geo refactoring and examples closes #182
Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/9e76b8d7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/9e76b8d7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/9e76b8d7
Branch: refs/heads/master
Commit: 9e76b8d7c716d66192bd2ebe1eb7722c5cd079e1
Parents: d47190b
Author: David Lotts <da...@parsons.com>
Authored: Wed Jun 14 17:50:11 2017 -0400
Committer: David Lotts <da...@parsons.com>
Committed: Wed Aug 30 16:28:37 2017 -0400
----------------------------------------------------------------------
.../api/persist/index/RyaSecondaryIndexer.java | 5 +-
.../accumulo/experimental/AccumuloIndexer.java | 1 -
extras/pom.xml | 1 +
extras/rya.geoindexing/geo.common/pom.xml | 25 +
.../GeoEnabledFilterFunctionOptimizer.java | 353 ++++++++++
.../org/apache/rya/indexing/GeoIndexer.java | 210 ++++++
.../org/apache/rya/indexing/GeoIndexerType.java | 76 +++
.../rya/indexing/GeoIndexingTestUtils.java | 51 ++
.../apache/rya/indexing/GeoRyaSailFactory.java | 151 +++++
.../rya/indexing/GeoTemporalIndexerType.java | 55 ++
.../indexing/accumulo/geo/GeoParseUtils.java | 172 +++++
.../rya/indexing/accumulo/geo/GeoTupleSet.java | 498 ++++++++++++++
.../accumulo/geo/OptionalConfigUtils.java | 149 +++++
.../GeoTemporalExternalSetMatcherFactory.java | 44 ++
.../geotemporal/GeoTemporalIndexException.java | 57 ++
.../GeoTemporalIndexSetProvider.java | 239 +++++++
.../geotemporal/GeoTemporalIndexer.java | 197 ++++++
.../geotemporal/GeoTemporalIndexerFactory.java | 57 ++
.../geotemporal/GeoTemporalOptimizer.java | 69 ++
.../GeoTemporalToSegmentConverter.java | 51 ++
.../rya/indexing/geotemporal/model/Event.java | 218 ++++++
.../geotemporal/model/EventQueryNode.java | 372 +++++++++++
.../geotemporal/storage/EventStorage.java | 130 ++++
extras/rya.geoindexing/geo.geomesa/pom.xml | 51 ++
.../accumulo/geo/GeoMesaGeoIndexer.java | 519 ++++++++++++++
.../rya/indexing/accumulo/geo/GmlParser.java | 48 ++
.../geoExamples/RyaGeoDirectExample.java | 404 +++++++++++
.../indexing/accumulo/geo/GeoIndexerSfTest.java | 520 +++++++++++++++
.../indexing/accumulo/geo/GeoIndexerTest.java | 395 +++++++++++
extras/rya.geoindexing/geo.geowave/pom.xml | 61 ++
.../accumulo/geo/GeoWaveGeoIndexer.java | 668 +++++++++++++++++++
.../rya/indexing/accumulo/geo/GmlParser.java | 48 ++
.../geoExamples/GeowaveDirectExample.java | 445 ++++++++++++
.../accumulo/geo/GeoWaveFeatureReaderTest.java | 384 +++++++++++
.../accumulo/geo/GeoWaveGTQueryTest.java | 254 +++++++
.../accumulo/geo/GeoWaveIndexerSfTest.java | 536 +++++++++++++++
.../accumulo/geo/GeoWaveIndexerTest.java | 447 +++++++++++++
extras/rya.geoindexing/geo.mongo/pom.xml | 41 ++
.../geoExamples/RyaMongoGeoDirectExample.java | 238 +++++++
.../mongo/EventDocumentConverter.java | 171 +++++
.../geotemporal/mongo/EventUpdater.java | 85 +++
.../GeoTemporalMongoDBStorageStrategy.java | 300 +++++++++
.../geotemporal/mongo/MongoEventStorage.java | 195 ++++++
.../mongo/MongoGeoTemporalIndexer.java | 227 +++++++
.../mongodb/geo/GeoMongoDBStorageStrategy.java | 247 +++++++
.../rya/indexing/mongodb/geo/GmlParser.java | 48 ++
.../indexing/mongodb/geo/MongoGeoIndexer.java | 154 +++++
.../indexing/mongodb/geo/MongoGeoTupleSet.java | 361 ++++++++++
.../geotemporal/GeoTemporalProviderTest.java | 222 ++++++
.../geotemporal/GeoTemporalTestBase.java | 140 ++++
.../geotemporal/MongoGeoTemporalIndexIT.java | 176 +++++
.../geotemporal/model/EventQueryNodeTest.java | 362 ++++++++++
.../mongo/EventDocumentConverterTest.java | 64 ++
.../GeoTemporalMongoDBStorageStrategyTest.java | 490 ++++++++++++++
.../mongo/MongoEventStorageTest.java | 197 ++++++
.../mongo/MongoGeoTemporalIndexerIT.java | 115 ++++
.../indexing/geotemporal/mongo/MongoITBase.java | 64 ++
.../indexing/mongo/MongoGeoIndexerSfTest.java | 262 ++++++++
.../rya/indexing/mongo/MongoGeoIndexerTest.java | 370 ++++++++++
extras/rya.geoindexing/pom.xml | 271 ++++----
.../GeoEnabledFilterFunctionOptimizer.java | 332 ---------
.../org/apache/rya/indexing/GeoIndexer.java | 210 ------
.../org/apache/rya/indexing/GeoIndexerType.java | 61 --
.../apache/rya/indexing/GeoRyaSailFactory.java | 150 -----
.../rya/indexing/OptionalConfigUtils.java | 140 ----
.../accumulo/geo/GeoMesaGeoIndexer.java | 520 ---------------
.../indexing/accumulo/geo/GeoParseUtils.java | 148 ----
.../rya/indexing/accumulo/geo/GeoTupleSet.java | 499 --------------
.../accumulo/geo/GeoWaveGeoIndexer.java | 668 -------------------
.../GeoTemporalExternalSetMatcherFactory.java | 44 --
.../geotemporal/GeoTemporalIndexException.java | 57 --
.../GeoTemporalIndexSetProvider.java | 239 -------
.../geotemporal/GeoTemporalIndexer.java | 193 ------
.../geotemporal/GeoTemporalIndexerFactory.java | 53 --
.../geotemporal/GeoTemporalOptimizer.java | 69 --
.../GeoTemporalToSegmentConverter.java | 51 --
.../rya/indexing/geotemporal/model/Event.java | 218 ------
.../geotemporal/model/EventQueryNode.java | 372 -----------
.../mongo/EventDocumentConverter.java | 171 -----
.../geotemporal/mongo/EventUpdater.java | 85 ---
.../GeoTemporalMongoDBStorageStrategy.java | 299 ---------
.../geotemporal/mongo/MongoEventStorage.java | 195 ------
.../mongo/MongoGeoTemporalIndexer.java | 226 -------
.../geotemporal/storage/EventStorage.java | 130 ----
.../mongodb/geo/GeoMongoDBStorageStrategy.java | 247 -------
.../indexing/mongodb/geo/MongoGeoIndexer.java | 154 -----
.../indexing/mongodb/geo/MongoGeoTupleSet.java | 361 ----------
.../rya/indexing/GeoIndexingTestUtils.java | 51 --
.../indexing/accumulo/geo/GeoIndexerSfTest.java | 521 ---------------
.../indexing/accumulo/geo/GeoIndexerTest.java | 396 -----------
.../accumulo/geo/GeoWaveFeatureReaderTest.java | 385 -----------
.../accumulo/geo/GeoWaveGTQueryTest.java | 254 -------
.../accumulo/geo/GeoWaveIndexerSfTest.java | 537 ---------------
.../accumulo/geo/GeoWaveIndexerTest.java | 448 -------------
.../geotemporal/GeoTemporalProviderTest.java | 222 ------
.../geotemporal/GeoTemporalTestBase.java | 140 ----
.../geotemporal/MongoGeoTemporalIndexIT.java | 176 -----
.../geotemporal/model/EventQueryNodeTest.java | 362 ----------
.../mongo/EventDocumentConverterTest.java | 64 --
.../GeoTemporalMongoDBStorageStrategyTest.java | 490 --------------
.../mongo/MongoEventStorageTest.java | 197 ------
.../mongo/MongoGeoTemporalIndexerIT.java | 115 ----
.../indexing/geotemporal/mongo/MongoITBase.java | 64 --
.../indexing/mongo/MongoGeoIndexerSfTest.java | 262 --------
.../rya/indexing/mongo/MongoGeoIndexerTest.java | 370 ----------
pom.xml | 1 +
106 files changed, 12617 insertions(+), 11091 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/common/rya.api/src/main/java/org/apache/rya/api/persist/index/RyaSecondaryIndexer.java
----------------------------------------------------------------------
diff --git a/common/rya.api/src/main/java/org/apache/rya/api/persist/index/RyaSecondaryIndexer.java b/common/rya.api/src/main/java/org/apache/rya/api/persist/index/RyaSecondaryIndexer.java
index e1c1819..ef21f1f 100644
--- a/common/rya.api/src/main/java/org/apache/rya/api/persist/index/RyaSecondaryIndexer.java
+++ b/common/rya.api/src/main/java/org/apache/rya/api/persist/index/RyaSecondaryIndexer.java
@@ -33,7 +33,10 @@ import org.apache.rya.api.domain.RyaStatement;
import org.apache.rya.api.domain.RyaURI;
public interface RyaSecondaryIndexer extends Closeable, Flushable, Configurable {
-
+ /**
+ * initialize after setting configuration.
+ */
+ public void init();
/**
* Returns the table name if the implementation supports it.
* Note that some indexers use multiple tables, this only returns one.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/dao/accumulo.rya/src/main/java/org/apache/rya/accumulo/experimental/AccumuloIndexer.java
----------------------------------------------------------------------
diff --git a/dao/accumulo.rya/src/main/java/org/apache/rya/accumulo/experimental/AccumuloIndexer.java b/dao/accumulo.rya/src/main/java/org/apache/rya/accumulo/experimental/AccumuloIndexer.java
index 3e08ef4..4a164a9 100644
--- a/dao/accumulo.rya/src/main/java/org/apache/rya/accumulo/experimental/AccumuloIndexer.java
+++ b/dao/accumulo.rya/src/main/java/org/apache/rya/accumulo/experimental/AccumuloIndexer.java
@@ -29,7 +29,6 @@ import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
import org.apache.rya.api.persist.index.RyaSecondaryIndexer;
public interface AccumuloIndexer extends RyaSecondaryIndexer {
- public void init();
public void setMultiTableBatchWriter(MultiTableBatchWriter writer) throws IOException;
public void setConnector(Connector connector);
public void destroy();
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/pom.xml
----------------------------------------------------------------------
diff --git a/extras/pom.xml b/extras/pom.xml
index 8823031..82930bc 100644
--- a/extras/pom.xml
+++ b/extras/pom.xml
@@ -45,6 +45,7 @@ under the License.
<module>rya.merger</module>
<module>rya.giraph</module>
<module>rya.benchmark</module>
+ <module>rya.geoindexing</module>
</modules>
<profiles>
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/pom.xml
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/pom.xml b/extras/rya.geoindexing/geo.common/pom.xml
new file mode 100644
index 0000000..6b4b3ca
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/pom.xml
@@ -0,0 +1,25 @@
+<?xml version='1.0'?>
+
+<!-- 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. -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.rya</groupId>
+ <artifactId>rya.geoindexing</artifactId>
+ <version>3.2.11-incubating-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>geo.common</artifactId>
+ <name>Apache Rya Geo Indexing Common Code</name>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoEnabledFilterFunctionOptimizer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoEnabledFilterFunctionOptimizer.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoEnabledFilterFunctionOptimizer.java
new file mode 100644
index 0000000..6ad0edc
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoEnabledFilterFunctionOptimizer.java
@@ -0,0 +1,353 @@
+package org.apache.rya.indexing;
+
+/*
+ * 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.io.IOException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.commons.lang.Validate;
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.rya.accumulo.AccumuloRdfConfiguration;
+import org.apache.rya.indexing.IndexingFunctionRegistry.FUNCTION_TYPE;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.accumulo.freetext.AccumuloFreeTextIndexer;
+import org.apache.rya.indexing.accumulo.freetext.FreeTextTupleSet;
+import org.apache.rya.indexing.accumulo.geo.GeoParseUtils;
+import org.apache.rya.indexing.accumulo.geo.GeoTupleSet;
+import org.apache.rya.indexing.accumulo.geo.OptionalConfigUtils;
+import org.apache.rya.indexing.accumulo.temporal.AccumuloTemporalIndexer;
+import org.apache.rya.indexing.mongodb.freetext.MongoFreeTextIndexer;
+import org.apache.rya.indexing.mongodb.temporal.MongoTemporalIndexer;
+import org.openrdf.model.Resource;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.URIImpl;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.Dataset;
+import org.openrdf.query.algebra.And;
+import org.openrdf.query.algebra.Filter;
+import org.openrdf.query.algebra.FunctionCall;
+import org.openrdf.query.algebra.Join;
+import org.openrdf.query.algebra.LeftJoin;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.algebra.ValueConstant;
+import org.openrdf.query.algebra.Var;
+import org.openrdf.query.algebra.evaluation.QueryOptimizer;
+import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
+
+import com.google.common.collect.Lists;
+
+public class GeoEnabledFilterFunctionOptimizer implements QueryOptimizer, Configurable {
+ private static final Logger LOG = Logger.getLogger(GeoEnabledFilterFunctionOptimizer.class);
+ private final ValueFactory valueFactory = new ValueFactoryImpl();
+
+ private Configuration conf;
+ private GeoIndexer geoIndexer;
+ private FreeTextIndexer freeTextIndexer;
+ private TemporalIndexer temporalIndexer;
+ private boolean init = false;
+
+ public GeoEnabledFilterFunctionOptimizer() {
+ }
+
+ public GeoEnabledFilterFunctionOptimizer(final AccumuloRdfConfiguration conf) throws AccumuloException, AccumuloSecurityException,
+ TableNotFoundException, IOException, TableExistsException, NumberFormatException, UnknownHostException {
+ this.conf = conf;
+ init();
+ }
+
+ //setConf initializes FilterFunctionOptimizer so reflection can be used
+ //to create optimizer in RdfCloudTripleStoreConnection
+ @Override
+ public void setConf(final Configuration conf) {
+ this.conf = conf;
+ //reset the init.
+ init = false;
+ init();
+ }
+ /**
+ * Load instances of the selected indexers. This is tricky because some (geomesa vs geowave) have incompatible dependencies (geotools versions).
+ */
+ private synchronized void init() {
+ if (!init) {
+ if (ConfigUtils.getUseMongo(conf)) {
+ // create a new MongoGeoIndexer() without having it at compile time.
+ geoIndexer = instantiate(GeoIndexerType.MONGO_DB.getGeoIndexerClassString(), GeoIndexer.class);
+ geoIndexer.setConf(conf);
+ freeTextIndexer = new MongoFreeTextIndexer();
+ freeTextIndexer.setConf(conf);
+ temporalIndexer = new MongoTemporalIndexer();
+ temporalIndexer.setConf(conf);
+ } else {
+ GeoIndexerType geoIndexerType = OptionalConfigUtils.getGeoIndexerType(conf);
+ if (geoIndexerType == GeoIndexerType.UNSPECIFIED) {
+ geoIndexer = instantiate(GeoIndexerType.GEO_MESA.getGeoIndexerClassString(), GeoIndexer.class);
+ } else {
+ geoIndexer = instantiate(geoIndexerType.getGeoIndexerClassString(), GeoIndexer.class);
+ }
+ geoIndexer.setConf(conf);
+ freeTextIndexer = new AccumuloFreeTextIndexer();
+ freeTextIndexer.setConf(conf);
+ temporalIndexer = new AccumuloTemporalIndexer();
+ temporalIndexer.setConf(conf);
+ }
+ init = true;
+ }
+ }
+
+
+ @Override
+ public void optimize(final TupleExpr tupleExpr, final Dataset dataset, final BindingSet bindings) {
+ // find variables used in property and resource based searches:
+ final SearchVarVisitor searchVars = new SearchVarVisitor();
+ tupleExpr.visit(searchVars);
+ // rewrites for property searches:
+ processPropertySearches(tupleExpr, searchVars.searchProperties);
+
+ }
+
+ /**
+ * helper to instantiate a class from a string class name.
+ * @param className name of class to instantiate.
+ * @param type base interface that the class immplements
+ * @return the instance.
+ */
+ public static <T> T instantiate(final String className, final Class<T> type){
+ try{
+ return type.cast(Class.forName(className).newInstance());
+ } catch(InstantiationException
+ | IllegalAccessException
+ | ClassNotFoundException e){
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private void processPropertySearches(final TupleExpr tupleExpr, final Collection<Var> searchProperties) {
+ final MatchStatementVisitor matchStatements = new MatchStatementVisitor(searchProperties);
+ tupleExpr.visit(matchStatements);
+ for (final StatementPattern matchStatement: matchStatements.matchStatements) {
+ final Var subject = matchStatement.getSubjectVar();
+ if (subject.hasValue() && !(subject.getValue() instanceof Resource)) {
+ throw new IllegalArgumentException("Query error: Found " + subject.getValue() + ", expected an URI or BNode");
+ }
+ Validate.isTrue(subject.hasValue() || subject.getName() != null);
+ Validate.isTrue(!matchStatement.getObjectVar().hasValue() && matchStatement.getObjectVar().getName() != null);
+ buildQuery(tupleExpr, matchStatement);
+ }
+ }
+
+ private void buildQuery(final TupleExpr tupleExpr, final StatementPattern matchStatement) {
+ //If our IndexerExpr (to be) is the rhs-child of LeftJoin, we can safely make that a Join:
+ // the IndexerExpr will (currently) not return results that can deliver unbound variables.
+ //This optimization should probably be generalized into a LeftJoin -> Join optimizer under certain conditions. Until that
+ // has been done, this code path at least takes care of queries generated by OpenSahara SparqTool that filter on OPTIONAL
+ // projections. E.g. summary~'full text search' (summary is optional). See #379
+ if (matchStatement.getParentNode() instanceof LeftJoin) {
+ final LeftJoin leftJoin = (LeftJoin)matchStatement.getParentNode();
+ if (leftJoin.getRightArg() == matchStatement && leftJoin.getCondition() == null) {
+ matchStatement.getParentNode().replaceWith(new Join(leftJoin.getLeftArg(), leftJoin.getRightArg()));
+ }
+ }
+ final FilterFunction fVisitor = new FilterFunction(matchStatement.getObjectVar().getName());
+ tupleExpr.visit(fVisitor);
+ final List<IndexingExpr> results = Lists.newArrayList();
+ for(int i = 0; i < fVisitor.func.size(); i++){
+ results.add(new IndexingExpr(fVisitor.func.get(i), matchStatement, fVisitor.args.get(i)));
+ }
+ removeMatchedPattern(tupleExpr, matchStatement, new IndexerExprReplacer(results));
+ }
+
+ //find vars contained in filters
+ private static class SearchVarVisitor extends QueryModelVisitorBase<RuntimeException> {
+ private final Collection<Var> searchProperties = new ArrayList<Var>();
+
+ @Override
+ public void meet(final FunctionCall fn) {
+ final URI fun = new URIImpl(fn.getURI());
+ final Var result = IndexingFunctionRegistry.getResultVarFromFunctionCall(fun, fn.getArgs());
+ if (result != null && !searchProperties.contains(result)) {
+ searchProperties.add(result);
+ }
+ }
+ }
+
+ //find StatementPatterns containing filter variables
+ private static class MatchStatementVisitor extends QueryModelVisitorBase<RuntimeException> {
+ private final Collection<Var> propertyVars;
+ private final Collection<Var> usedVars = new ArrayList<Var>();
+ private final List<StatementPattern> matchStatements = new ArrayList<StatementPattern>();
+
+ public MatchStatementVisitor(final Collection<Var> propertyVars) {
+ this.propertyVars = propertyVars;
+ }
+
+ @Override public void meet(final StatementPattern statement) {
+ final Var object = statement.getObjectVar();
+ if (propertyVars.contains(object)) {
+ if (usedVars.contains(object)) {
+ throw new IllegalArgumentException("Illegal search, variable is used multiple times as object: " + object.getName());
+ } else {
+ usedVars.add(object);
+ matchStatements.add(statement);
+ }
+ }
+ }
+ }
+
+ private abstract class AbstractEnhanceVisitor extends QueryModelVisitorBase<RuntimeException> {
+ final String matchVar;
+ List<URI> func = Lists.newArrayList();
+ List<Object[]> args = Lists.newArrayList();
+
+ public AbstractEnhanceVisitor(final String matchVar) {
+ this.matchVar = matchVar;
+ }
+
+ protected void addFilter(final URI uri, final Object[] values) {
+ func.add(uri);
+ args.add(values);
+ }
+ }
+
+ //create indexing expression for each filter matching var in filter StatementPattern
+ //replace old filter condition with true condition
+ private class FilterFunction extends AbstractEnhanceVisitor {
+ public FilterFunction(final String matchVar) {
+ super(matchVar);
+ }
+
+ @Override
+ public void meet(final FunctionCall call) {
+ final URI fnUri = valueFactory.createURI(call.getURI());
+ final Var resultVar = IndexingFunctionRegistry.getResultVarFromFunctionCall(fnUri, call.getArgs());
+ if (resultVar != null && resultVar.getName().equals(matchVar)) {
+ addFilter(valueFactory.createURI(call.getURI()), GeoParseUtils.extractArguments(matchVar, call));
+ if (call.getParentNode() instanceof Filter || call.getParentNode() instanceof And || call.getParentNode() instanceof LeftJoin) {
+ call.replaceWith(new ValueConstant(valueFactory.createLiteral(true)));
+ } else {
+ throw new IllegalArgumentException("Query error: Found " + call + " as part of an expression that is too complex");
+ }
+ }
+ }
+
+ @Override
+ public void meet(final Filter filter) {
+ //First visit children, then condition (reverse of default):
+ filter.getArg().visit(this);
+ filter.getCondition().visit(this);
+ }
+ }
+
+ private void removeMatchedPattern(final TupleExpr tupleExpr, final StatementPattern pattern, final TupleExprReplacer replacer) {
+ final List<TupleExpr> indexTuples = replacer.createReplacement(pattern);
+ if (indexTuples.size() > 1) {
+ final VarExchangeVisitor vev = new VarExchangeVisitor(pattern);
+ tupleExpr.visit(vev);
+ Join join = new Join(indexTuples.remove(0), indexTuples.remove(0));
+ for (final TupleExpr geo : indexTuples) {
+ join = new Join(join, geo);
+ }
+ pattern.replaceWith(join);
+ } else if (indexTuples.size() == 1) {
+ pattern.replaceWith(indexTuples.get(0));
+ pattern.setParentNode(null);
+ } else {
+ throw new IllegalStateException("Must have at least one replacement for matched StatementPattern.");
+ }
+ }
+
+ private interface TupleExprReplacer {
+ List<TupleExpr> createReplacement(TupleExpr org);
+ }
+
+ //replace each filter pertinent StatementPattern with corresponding index expr
+ private class IndexerExprReplacer implements TupleExprReplacer {
+ private final List<IndexingExpr> indxExpr;
+ private final FUNCTION_TYPE type;
+
+ public IndexerExprReplacer(final List<IndexingExpr> indxExpr) {
+ this.indxExpr = indxExpr;
+ final URI func = indxExpr.get(0).getFunction();
+ type = IndexingFunctionRegistry.getFunctionType(func);
+ }
+
+ @Override
+ public List<TupleExpr> createReplacement(final TupleExpr org) {
+ final List<TupleExpr> indexTuples = Lists.newArrayList();
+ switch (type) {
+ case GEO:
+ for (final IndexingExpr indx : indxExpr) {
+ indexTuples.add(new GeoTupleSet(indx, geoIndexer));
+ }
+ break;
+ case FREETEXT:
+ for (final IndexingExpr indx : indxExpr) {
+ indexTuples.add(new FreeTextTupleSet(indx, freeTextIndexer));
+ }
+ break;
+ case TEMPORAL:
+ for (final IndexingExpr indx : indxExpr) {
+ indexTuples.add(new TemporalTupleSet(indx, temporalIndexer));
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Incorrect type!");
+ }
+ return indexTuples;
+ }
+ }
+
+ private static class VarExchangeVisitor extends QueryModelVisitorBase<RuntimeException> {
+ private final StatementPattern exchangeVar;
+ public VarExchangeVisitor(final StatementPattern sp) {
+ exchangeVar = sp;
+ }
+
+ @Override
+ public void meet(final Join node) {
+ final QueryModelNode lNode = node.getLeftArg();
+ if (lNode instanceof StatementPattern) {
+ exchangeVar.replaceWith(lNode);
+ node.setLeftArg(exchangeVar);
+ } else {
+ super.meet(node);
+ }
+ }
+ }
+
+ @Override
+ public Configuration getConf() {
+ return conf;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexer.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexer.java
new file mode 100644
index 0000000..d091d32
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexer.java
@@ -0,0 +1,210 @@
+package org.apache.rya.indexing;
+
+import org.openrdf.model.Statement;
+import org.openrdf.query.QueryEvaluationException;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+/*
+ * 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 info.aduna.iteration.CloseableIteration;
+import org.apache.rya.api.persist.index.RyaSecondaryIndexer;
+import org.apache.rya.indexing.accumulo.geo.GeoTupleSet.GeoSearchFunctionFactory.NearQuery;
+
+/**
+ * A repository to store, index, and retrieve {@link Statement}s based on geospatial features.
+ */
+public interface GeoIndexer extends RyaSecondaryIndexer {
+ /**
+ * Returns statements that contain a geometry that is equal to the queried {@link Geometry} and meet the {@link StatementConstraints}.
+ *
+ * <p>
+ * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
+ * <ul>
+ * <li>
+ * "Two geometries are topologically equal if their interiors intersect and no part of the interior or boundary of one geometry intersects the exterior of the other"
+ * <li>"A is equal to B if A is within B and A contains B"
+ * </ul>
+ *
+ * @param query
+ * the queried geometry
+ * @param contraints
+ * the {@link StatementConstraints}
+ * @return
+ */
+ public abstract CloseableIteration<Statement, QueryEvaluationException> queryEquals(Geometry query, StatementConstraints contraints);
+
+ /**
+ * Returns statements that contain a geometry that is disjoint to the queried {@link Geometry} and meet the {@link StatementConstraints}.
+ *
+ * <p>
+ * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
+ * <ul>
+ * <li>"A and B are disjoint if they have no point in common. They form a set of disconnected geometries."
+ * <li>"A and B are disjoint if A does not intersect B"
+ * </ul>
+ *
+ * @param query
+ * the queried geometry
+ * @param contraints
+ * the {@link StatementConstraints}
+ * @return
+ */
+ public abstract CloseableIteration<Statement, QueryEvaluationException> queryDisjoint(Geometry query, StatementConstraints contraints);
+
+ /**
+ * Returns statements that contain a geometry that Intersects the queried {@link Geometry} and meet the {@link StatementConstraints}.
+ *
+ * <p>
+ * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
+ * <ul>
+ * <li>"a intersects b: geometries a and b have at least one point in common."
+ * <li>"not Disjoint"
+ * </ul>
+ *
+ *
+ * @param query
+ * the queried geometry
+ * @param contraints
+ * the {@link StatementConstraints}
+ * @return
+ */
+ public abstract CloseableIteration<Statement, QueryEvaluationException> queryIntersects(Geometry query, StatementConstraints contraints);
+
+ /**
+ * Returns statements that contain a geometry that Touches the queried {@link Geometry} and meet the {@link StatementConstraints}.
+ *
+ * <p>
+ * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
+ * <ul>
+ * <li>"a touches b, they have at least one boundary point in common, but no interior points."
+ * </ul>
+ *
+ *
+ * @param query
+ * the queried geometry
+ * @param contraints
+ * the {@link StatementConstraints}
+ * @return
+ */
+ public abstract CloseableIteration<Statement, QueryEvaluationException> queryTouches(Geometry query, StatementConstraints contraints);
+
+ /**
+ * Returns statements that contain a geometry that crosses the queried {@link Geometry} and meet the {@link StatementConstraints}.
+ *
+ * <p>
+ * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
+ * <ul>
+ * <li>
+ * "a crosses b, they have some but not all interior points in common (and the dimension of the intersection is less than that of at least one of them)."
+ * </ul>
+ *
+ * @param query
+ * the queried geometry
+ * @param contraints
+ * the {@link StatementConstraints}
+ * @return
+ */
+ public abstract CloseableIteration<Statement, QueryEvaluationException> queryCrosses(Geometry query, StatementConstraints contraints);
+
+ /**
+ * Returns statements that contain a geometry that is Within the queried {@link Geometry} and meet the {@link StatementConstraints}.
+ *
+ * <p>
+ * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
+ * <ul>
+ * <li>"a is within b, a lies in the interior of b"
+ * <li>Same as: "Contains(b,a)"
+ * </ul>
+ *
+ *
+ * @param query
+ * the queried geometry
+ * @param contraints
+ * the {@link StatementConstraints}
+ * @return
+ */
+ public abstract CloseableIteration<Statement, QueryEvaluationException> queryWithin(Geometry query, StatementConstraints contraints);
+
+ /**
+ * Returns statements that contain a geometry that Contains the queried {@link Geometry} and meet the {@link StatementConstraints}.
+ *
+ * <p>
+ * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
+ * <ul>
+ * <li>b is within a. Geometry b lies in the interior of a. Another definition:
+ * "a 'contains' b iff no points of b lie in the exterior of a, and at least one point of the interior of b lies in the interior of a"
+ * <li>Same: Within(b,a)
+ * </ul>
+ *
+ *
+ * @param query
+ * the queried geometry
+ * @param contraints
+ * the {@link StatementConstraints}
+ * @return
+ */
+ public abstract CloseableIteration<Statement, QueryEvaluationException> queryContains(Geometry query, StatementConstraints contraints);
+
+ /**
+ * Returns statements that contain a geometry that Overlaps the queried {@link Geometry} and meet the {@link StatementConstraints}.
+ *
+ * <p>
+ * From Wikipedia (http://en.wikipedia.org/wiki/DE-9IM):
+ * <ul>
+ * <li>a crosses b, they have some but not all interior points in common (and the dimension of the intersection is less than that of at
+ * least one of them).
+ * </ul>
+ *
+ *
+ * @param query
+ * the queried geometry
+ * @param contraints
+ * the {@link StatementConstraints}
+ * @return
+ */
+ public abstract CloseableIteration<Statement, QueryEvaluationException> queryOverlaps(Geometry query, StatementConstraints contraints);
+
+ /**
+ * Returns statements that contain a geometry that is near the queried {@link Geometry} and meet the {@link StatementConstraints}.
+ * <p>
+ * A geometry is considered near if it within the min/max distances specified in the provided {@link NearQuery}. This will make a disc (specify max),
+ * a donut(specify both), or a spheroid complement disc (specify min)
+ * <p>
+ * The distances are specified in meters and must be >= 0.
+ * <p>
+ * To specify max/min distances:
+ * <ul>
+ * <li>Enter parameters in order MAX, MIN -- Donut</li>
+ * <li>Omit the MIN -- Disc</li>
+ * <li>Enter 0 for MAX, and Enter parameter for MIN -- Spheroid complement Dist</li>
+ * <li>Omit both -- Default max/min [TODO: Find these values]</li>
+ * </ul>
+ * <p>
+ * Note: This query will not fail if the min is greater than the max, it will just return no results.
+ *
+ * @param query the queried geometry, with Optional min and max distance fields.
+ * @param contraints the {@link StatementConstraints}
+ * @return
+ */
+ public abstract CloseableIteration<Statement, QueryEvaluationException> queryNear(NearQuery query, StatementConstraints contraints);
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexerType.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexerType.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexerType.java
new file mode 100644
index 0000000..9bb613b
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexerType.java
@@ -0,0 +1,76 @@
+/*
+ * 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;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+
+/**
+ * A list of all the types of Geo indexers supported in Rya.
+ */
+public enum GeoIndexerType {
+ /**
+ * Geo Mesa based indexer.
+ */
+ GEO_MESA("org.apache.rya.indexing.accumulo.geo.GeoMesaGeoIndexer"),
+ /**
+ * Geo Wave based indexer.
+ */
+ GEO_WAVE("org.apache.rya.indexing.accumulo.geo.GeoWaveGeoIndexer"),
+ /**
+ * MongoDB based indexer.
+ */
+ MONGO_DB("org.apache.rya.indexing.mongodb.geo.MongoGeoIndexer"),
+ /**
+ * No mention of a type is specified, so use default.
+ */
+ UNSPECIFIED("no_index_was_configured");
+
+ private String geoIndexerClassString;
+
+ /**
+ * Creates a new {@link GeoIndexerType}.
+ * @param geoIndexerClass the {@link GeoIndexer} {@link Class}.
+ * (not {@code null})
+ */
+ private GeoIndexerType(final String geoIndexerClassString) {
+ this.geoIndexerClassString = checkNotNull(geoIndexerClassString);
+ }
+
+ /**
+ * @return the {@link GeoIndexer} {@link Class}. (not {@code null})
+ */
+ public String getGeoIndexerClassString() {
+
+ return geoIndexerClassString;
+ }
+
+ /**
+ * @return True if the class exists on the classpath.
+ */
+ public boolean isOnClassPath() {
+ try {
+ Class.forName(geoIndexerClassString, false, this.getClass().getClassLoader());
+ return true;
+ } catch (ClassNotFoundException e) {
+ // it does not exist on the classpath
+ return false;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexingTestUtils.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexingTestUtils.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexingTestUtils.java
new file mode 100644
index 0000000..b0c636d
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoIndexingTestUtils.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import info.aduna.iteration.CloseableIteration;
+
+/**
+ * Utility methods to help test geo indexing methods.
+ */
+public final class GeoIndexingTestUtils {
+ /**
+ * Private constructor to prevent instantiation.
+ */
+ private GeoIndexingTestUtils () {
+ }
+
+ /**
+ * Generates a set of items from the specified iterator.
+ * @param iter a {@link CloseableIteration}.
+ * @return the {@link Set} of items from the iterator or an empty set if
+ * none were found.
+ * @throws Exception
+ */
+ public static <X> Set<X> getSet(final CloseableIteration<X, ?> iter) throws Exception {
+ final Set<X> set = new HashSet<X>();
+ while (iter.hasNext()) {
+ final X item = iter.next();
+ set.add(item);
+ }
+ return set;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoRyaSailFactory.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoRyaSailFactory.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoRyaSailFactory.java
new file mode 100644
index 0000000..3c01bf6
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoRyaSailFactory.java
@@ -0,0 +1,151 @@
+/*
+ * 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;
+
+import static java.util.Objects.requireNonNull;
+
+import java.net.UnknownHostException;
+import java.util.Objects;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.Connector;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.hadoop.conf.Configuration;
+import org.openrdf.sail.Sail;
+import org.openrdf.sail.SailException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mongodb.MongoClient;
+
+import org.apache.rya.accumulo.AccumuloRdfConfiguration;
+import org.apache.rya.accumulo.AccumuloRyaDAO;
+import org.apache.rya.accumulo.instance.AccumuloRyaInstanceDetailsRepository;
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.api.instance.RyaDetailsRepository.RyaDetailsRepositoryException;
+import org.apache.rya.api.instance.RyaDetailsToConfiguration;
+import org.apache.rya.api.layout.TablePrefixLayoutStrategy;
+import org.apache.rya.api.persist.RyaDAO;
+import org.apache.rya.api.persist.RyaDAOException;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.accumulo.geo.OptionalConfigUtils;
+import org.apache.rya.mongodb.MongoConnectorFactory;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.apache.rya.mongodb.MongoDBRyaDAO;
+import org.apache.rya.mongodb.instance.MongoRyaInstanceDetailsRepository;
+import org.apache.rya.rdftriplestore.RdfCloudTripleStore;
+import org.apache.rya.rdftriplestore.inference.InferenceEngine;
+import org.apache.rya.rdftriplestore.inference.InferenceEngineException;
+import org.apache.rya.sail.config.RyaSailFactory;
+
+public class GeoRyaSailFactory {
+ private static final Logger LOG = LoggerFactory.getLogger(GeoRyaSailFactory.class);
+
+ /**
+ * Creates an instance of {@link Sail} that is attached to a Rya instance.
+ *
+ * @param conf - Configures how the Sail object will be constructed. (not null)
+ * @return A {@link Sail} object that is backed by a Rya datastore.
+ * @throws SailException The object could not be created.
+ */
+ public static Sail getInstance(final Configuration conf) throws AccumuloException,
+ AccumuloSecurityException, RyaDAOException, InferenceEngineException, SailException {
+ requireNonNull(conf);
+ return getRyaSail(conf);
+ }
+
+ private static Sail getRyaSail(final Configuration config) throws InferenceEngineException, RyaDAOException, AccumuloException, AccumuloSecurityException, SailException {
+ final RdfCloudTripleStore store = new RdfCloudTripleStore();
+ final RyaDAO<?> dao;
+ final RdfCloudTripleStoreConfiguration rdfConfig;
+
+ final String user;
+ final String pswd;
+ // XXX Should(?) be MongoDBRdfConfiguration.MONGO_COLLECTION_PREFIX inside the if below. RYA-135
+ final String ryaInstance = config.get(RdfCloudTripleStoreConfiguration.CONF_TBL_PREFIX);
+ Objects.requireNonNull(ryaInstance, "RyaInstance or table prefix is missing from configuration."+RdfCloudTripleStoreConfiguration.CONF_TBL_PREFIX);
+
+ if(ConfigUtils.getUseMongo(config)) {
+ final MongoDBRdfConfiguration mongoConfig = new MongoDBRdfConfiguration(config);
+ rdfConfig = mongoConfig;
+ final MongoClient client = MongoConnectorFactory.getMongoClient(config);
+ try {
+ final MongoRyaInstanceDetailsRepository ryaDetailsRepo = new MongoRyaInstanceDetailsRepository(client, mongoConfig.getCollectionName());
+ RyaDetailsToConfiguration.addRyaDetailsToConfiguration(ryaDetailsRepo.getRyaInstanceDetails(), mongoConfig);
+ } catch (final RyaDetailsRepositoryException e) {
+ LOG.info("Instance does not have a rya details collection, skipping.");
+ }
+ dao = getMongoDAO((MongoDBRdfConfiguration)rdfConfig, client);
+ } else {
+ rdfConfig = new AccumuloRdfConfiguration(config);
+ user = rdfConfig.get(ConfigUtils.CLOUDBASE_USER);
+ pswd = rdfConfig.get(ConfigUtils.CLOUDBASE_PASSWORD);
+ Objects.requireNonNull(user, "Accumulo user name is missing from configuration."+ConfigUtils.CLOUDBASE_USER);
+ Objects.requireNonNull(pswd, "Accumulo user password is missing from configuration."+ConfigUtils.CLOUDBASE_PASSWORD);
+ rdfConfig.setTableLayoutStrategy( new TablePrefixLayoutStrategy(ryaInstance) );
+ RyaSailFactory.updateAccumuloConfig((AccumuloRdfConfiguration) rdfConfig, user, pswd, ryaInstance);
+ dao = getAccumuloDAO((AccumuloRdfConfiguration)rdfConfig);
+ }
+ store.setRyaDAO(dao);
+ rdfConfig.setTablePrefix(ryaInstance);
+
+ if (rdfConfig.isInfer()){
+ final InferenceEngine inferenceEngine = new InferenceEngine();
+ inferenceEngine.setConf(rdfConfig);
+ inferenceEngine.setRyaDAO(dao);
+ inferenceEngine.init();
+ store.setInferenceEngine(inferenceEngine);
+ }
+
+ store.initialize();
+
+ return store;
+ }
+
+ private static MongoDBRyaDAO getMongoDAO(final MongoDBRdfConfiguration config, final MongoClient client) throws RyaDAOException {
+ MongoDBRyaDAO dao = null;
+ OptionalConfigUtils.setIndexers(config);
+ if(client != null) {
+ dao = new MongoDBRyaDAO(config, client);
+ } else {
+ try {
+ dao = new MongoDBRyaDAO(config);
+ } catch (NumberFormatException | UnknownHostException e) {
+ throw new RyaDAOException("Unable to connect to mongo at the configured location.", e);
+ }
+ }
+ dao.init();
+ return dao;
+ }
+
+ private static AccumuloRyaDAO getAccumuloDAO(final AccumuloRdfConfiguration config) throws AccumuloException, AccumuloSecurityException, RyaDAOException {
+ final Connector connector = ConfigUtils.getConnector(config);
+ final AccumuloRyaDAO dao = new AccumuloRyaDAO();
+ dao.setConnector(connector);
+
+ OptionalConfigUtils.setIndexers(config);
+ config.setDisplayQueryPlan(true);
+
+ dao.setConf(config);
+ dao.init();
+ return dao;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoTemporalIndexerType.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoTemporalIndexerType.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoTemporalIndexerType.java
new file mode 100644
index 0000000..311af93
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/GeoTemporalIndexerType.java
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+
+/**
+ * A list of all the types of Geo indexers supported in Rya.
+ */
+public enum GeoTemporalIndexerType {
+ /**
+ * MongoDB based GeoTemporal index and optimizer go together.
+ */
+ MONGO_GEO_TEMPORAL("org.apache.rya.indexing.geotemporal.mongo.MongoGeoTemporalIndexer"),
+ MONGO_GEO_TEMPORAL_OPTIMIZER("org.apache.rya.indexing.geotemporal.GeoTemporalOptimizer"),
+ /**
+ * No mention of a type is specified, so use default.
+ */
+ UNSPECIFIED("no_index_was_configured");
+ private String geoTemporalIndexerClassString;
+
+ /**
+ * Creates a new {@link GeoTemporalIndexerType}.
+ * @param geoIndexerClass the {@link GeoIndexer} {@link Class}.
+ * (not {@code null})
+ */
+ private GeoTemporalIndexerType(final String geoIndexerClassString) {
+ this.geoTemporalIndexerClassString = checkNotNull(geoIndexerClassString);
+ }
+
+ /**
+ * @return the {@link GeoIndexer} {@link Class}. (not {@code null})
+ */
+ public String getGeoTemporalIndexerClassString() {
+ return geoTemporalIndexerClassString;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoParseUtils.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoParseUtils.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoParseUtils.java
new file mode 100644
index 0000000..779a61e
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoParseUtils.java
@@ -0,0 +1,172 @@
+package org.apache.rya.indexing.accumulo.geo;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+/*
+ * 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 org.apache.log4j.Logger;
+import org.apache.rya.indexing.GeoConstants;
+import org.openrdf.model.Literal;
+import org.openrdf.model.Statement;
+import org.openrdf.model.Value;
+import org.openrdf.query.algebra.FunctionCall;
+import org.openrdf.query.algebra.ValueConstant;
+import org.openrdf.query.algebra.ValueExpr;
+import org.openrdf.query.algebra.Var;
+import org.xml.sax.SAXException;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKTReader;
+
+/**
+ *
+ * parsing RDF oriented gml and well known text (WKT) into a geometry
+ * This is abstract because of its depenendence on geo tools.
+ * Your implementation can use whatever version you like.
+ */
+public class GeoParseUtils {
+ static final Logger logger = Logger.getLogger(GeoParseUtils.class);
+ /**
+ * @deprecated Not needed since geo literals may be WKT or GML.
+ *
+ * This method warns on a condition that must already be tested. Replaced by
+ * {@link #getLiteral(Statement)} and {@link #getGeometry(Statement}
+ * and getLiteral(statement).toString()
+ * and getLiteral(statement).getDatatype()
+ */
+ @Deprecated
+ public static String getWellKnownText(final Statement statement) throws ParseException {
+ final Literal lit = getLiteral(statement);
+ if (!GeoConstants.XMLSCHEMA_OGC_WKT.equals(lit.getDatatype())) {
+ logger.warn("Literal is not of type " + GeoConstants.XMLSCHEMA_OGC_WKT + ": " + statement.toString());
+ }
+ return lit.getLabel().toString();
+ }
+
+ public static Literal getLiteral(final Statement statement) throws ParseException {
+ final org.openrdf.model.Value v = statement.getObject();
+ if (!(v instanceof Literal)) {
+ throw new ParseException("Statement does not contain Literal: " + statement.toString());
+ }
+ final Literal lit = (Literal) v;
+ return lit;
+ }
+
+ /**
+ * Parse GML/wkt literal to Geometry
+ *
+ * @param statement
+ * @return
+ * @throws ParseException
+ * @throws ParserConfigurationException
+ * @throws SAXException
+ * @throws IOException
+ */
+ public static Geometry getGeometry(final Statement statement, GmlToGeometryParser gmlToGeometryParser) throws ParseException {
+ // handle GML or WKT
+ final Literal lit = getLiteral(statement);
+ if (GeoConstants.XMLSCHEMA_OGC_WKT.equals(lit.getDatatype())) {
+ final String wkt = lit.getLabel().toString();
+ return (new WKTReader()).read(wkt);
+ } else if (GeoConstants.XMLSCHEMA_OGC_GML.equals(lit.getDatatype())) {
+ final String gml = lit.getLabel().toString();
+ try {
+ return getGeometryGml(gml, gmlToGeometryParser);
+ } catch (IOException | SAXException | ParserConfigurationException e) {
+ throw new ParseException(e);
+ }
+ } else {
+ throw new ParseException("Literal is unknown geo type, expecting WKT or GML: " + statement.toString());
+ }
+ }
+ /**
+ * Convert GML/XML string into a geometry that can be indexed.
+ * @param gmlString
+ * @return
+ * @throws IOException
+ * @throws SAXException
+ * @throws ParserConfigurationException
+ */
+ public static Geometry getGeometryGml(final String gmlString, final GmlToGeometryParser gmlToGeometryParser) throws IOException, SAXException, ParserConfigurationException {
+ final Reader reader = new StringReader(gmlString);
+ final Geometry geometry = gmlToGeometryParser.parse(reader);
+ // This sometimes gets populated with the SRS/CRS: geometry.getUserData()
+ // Always returns 0 : geometry.getSRID()
+ //TODO geometry.setUserData(some default CRS); OR geometry.setSRID(some default CRS)
+
+ return geometry;
+ }
+
+
+ /**
+ * Extracts the arguments used in a {@link FunctionCall}.
+ * @param matchName - The variable name to match to arguments used in the {@link FunctionCall}.
+ * @param call - The {@link FunctionCall} to match against.
+ * @return - The {@link Value}s matched.
+ */
+ public static Object[] extractArguments(final String matchName, final FunctionCall call) {
+ final Object[] args = new Object[call.getArgs().size() - 1];
+ int argI = 0;
+ for (int i = 0; i != call.getArgs().size(); ++i) {
+ final ValueExpr arg = call.getArgs().get(i);
+ if (argI == i && arg instanceof Var && matchName.equals(((Var)arg).getName())) {
+ continue;
+ }
+ if (arg instanceof ValueConstant) {
+ args[argI] = ((ValueConstant)arg).getValue();
+ } else if (arg instanceof Var && ((Var)arg).hasValue()) {
+ args[argI] = ((Var)arg).getValue();
+ } else {
+ args[argI] = arg;
+ }
+ ++argI;
+ }
+ return args;
+ }
+
+ /**
+ * Wrap the geotools or whatever parser.
+ */
+ public interface GmlToGeometryParser {
+ /**
+ * Implemented code should look like this:
+ * import org.geotools.gml3.GMLConfiguration;
+ * import org.geotools.xml.Parser;
+ * final GmlToGeometryParser gmlParser = new GmlToGeometryParser(new GMLConfiguration()); return (Geometry)
+ * gmlParser.parse(reader);
+ * @param reader
+ * contains the gml to parse. use StringReader to adapt.
+ * @return a JTS geometry
+ * @throws ParserConfigurationException
+ * @throws SAXException
+ * @throws IOException
+ *
+ */
+ public abstract Geometry parse(final Reader reader) throws IOException, SAXException, ParserConfigurationException;
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoTupleSet.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoTupleSet.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoTupleSet.java
new file mode 100644
index 0000000..888c099
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoTupleSet.java
@@ -0,0 +1,498 @@
+package org.apache.rya.indexing.accumulo.geo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.GeoIndexer;
+import org.apache.rya.indexing.IndexingExpr;
+import org.apache.rya.indexing.IteratorFactory;
+import org.apache.rya.indexing.SearchFunction;
+import org.apache.rya.indexing.StatementConstraints;
+import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.QueryEvaluationException;
+import org.openrdf.query.algebra.Var;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Maps;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKTReader;
+
+/*
+ * 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 info.aduna.iteration.CloseableIteration;
+
+//Indexing Node for geo expressions to be inserted into execution plan
+//to delegate geo portion of query to geo index
+public class GeoTupleSet extends ExternalTupleSet {
+ private static final String NEAR_DELIM = "::";
+ private final Configuration conf;
+ private final GeoIndexer geoIndexer;
+ private final IndexingExpr filterInfo;
+
+
+ public GeoTupleSet(final IndexingExpr filterInfo, final GeoIndexer geoIndexer) {
+ this.filterInfo = filterInfo;
+ this.geoIndexer = geoIndexer;
+ conf = geoIndexer.getConf();
+ }
+
+ @Override
+ public Set<String> getBindingNames() {
+ return filterInfo.getBindingNames();
+ }
+
+ @Override
+ public GeoTupleSet clone() {
+ return new GeoTupleSet(filterInfo, geoIndexer);
+ }
+
+ @Override
+ public double cardinality() {
+ return 0.0; // No idea how the estimate cardinality here.
+ }
+
+
+ @Override
+ public String getSignature() {
+ return "(GeoTuple Projection) " + "variables: " + Joiner.on(", ").join(getBindingNames()).replaceAll("\\s+", " ");
+ }
+
+
+
+ @Override
+ public boolean equals(final Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (!(other instanceof GeoTupleSet)) {
+ return false;
+ }
+ final GeoTupleSet arg = (GeoTupleSet) other;
+ return filterInfo.equals(arg.filterInfo);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31*result + filterInfo.hashCode();
+
+ return result;
+ }
+
+
+
+ /**
+ * Returns an iterator over the result set of the contained IndexingExpr.
+ * <p>
+ * Should be thread-safe (concurrent invocation {@link OfflineIterable} this
+ * method can be expected with some query evaluators.
+ */
+ @Override
+ public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(final BindingSet bindings)
+ throws QueryEvaluationException {
+
+ final URI funcURI = filterInfo.getFunction();
+ final SearchFunction searchFunction = new GeoSearchFunctionFactory(conf, geoIndexer).getSearchFunction(funcURI);
+
+ String queryText;
+ Object arg = filterInfo.getArguments()[0];
+ if (arg instanceof Value) {
+ queryText = ((Value) arg).stringValue();
+ } else if (arg instanceof Var) {
+ queryText = bindings.getBinding(((Var) arg).getName()).getValue().stringValue();
+ } else {
+ throw new IllegalArgumentException("Query text was not resolved");
+ }
+
+ if(funcURI.equals(GeoConstants.GEO_SF_NEAR)) {
+ if (filterInfo.getArguments().length > 3) {
+ throw new IllegalArgumentException("Near functions do not support more than four arguments.");
+ }
+
+ final List<String> valueList = new ArrayList<>();
+ for (final Object val : filterInfo.getArguments()) {
+ if (val instanceof Value) {
+ valueList.add(((Value)val).stringValue());
+ } else if (val instanceof Var) {
+ valueList.add(bindings.getBinding(((Var) val).getName()).getValue().stringValue());
+ } else {
+ throw new IllegalArgumentException("Query text was not resolved");
+ }
+ }
+ queryText = String.join(NEAR_DELIM, valueList);
+ } else if (filterInfo.getArguments().length > 1) {
+ throw new IllegalArgumentException("Index functions do not support more than two arguments.");
+ }
+
+ try {
+ final CloseableIteration<BindingSet, QueryEvaluationException> iterrez = IteratorFactory
+ .getIterator(filterInfo.getSpConstraint(), bindings,
+ queryText, searchFunction);
+ return iterrez;
+ } catch (final Exception e) {
+ System.out.println(e.getMessage());
+ throw e;
+ }
+ }
+
+ //returns appropriate search function for a given URI
+ //search functions used in GeoMesaGeoIndexer to access index
+ public static class GeoSearchFunctionFactory {
+
+ Configuration conf;
+
+ private final Map<URI, SearchFunction> SEARCH_FUNCTION_MAP = Maps.newHashMap();
+
+ private final GeoIndexer geoIndexer;
+
+ public GeoSearchFunctionFactory(final Configuration conf, final GeoIndexer geoIndexer) {
+ this.conf = conf;
+ this.geoIndexer = geoIndexer;
+ }
+
+
+ /**
+ * Get a {@link GeoSearchFunction} for a given URI.
+ *
+ * @param searchFunction
+ * @return
+ */
+ public SearchFunction getSearchFunction(final URI searchFunction) {
+
+ SearchFunction geoFunc = null;
+
+ try {
+ geoFunc = getSearchFunctionInternal(searchFunction);
+ } catch (final QueryEvaluationException e) {
+ e.printStackTrace();
+ }
+
+ return geoFunc;
+ }
+
+ private SearchFunction getSearchFunctionInternal(final URI searchFunction) throws QueryEvaluationException {
+ final SearchFunction sf = SEARCH_FUNCTION_MAP.get(searchFunction);
+
+ if (sf != null) {
+ return sf;
+ } else {
+ throw new QueryEvaluationException("Unknown Search Function: " + searchFunction.stringValue());
+ }
+ }
+
+ private final SearchFunction GEO_EQUALS = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
+ final StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ final WKTReader reader = new WKTReader();
+ final Geometry geometry = reader.read(queryText);
+ final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryEquals(
+ geometry, contraints);
+ return statements;
+ } catch (final ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_EQUALS";
+ };
+ };
+
+ private final SearchFunction GEO_DISJOINT = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
+ final StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ final WKTReader reader = new WKTReader();
+ final Geometry geometry = reader.read(queryText);
+ final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryDisjoint(
+ geometry, contraints);
+ return statements;
+ } catch (final ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_DISJOINT";
+ };
+ };
+
+ private final SearchFunction GEO_INTERSECTS = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
+ final StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ final WKTReader reader = new WKTReader();
+ final Geometry geometry = reader.read(queryText);
+ final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryIntersects(
+ geometry, contraints);
+ return statements;
+ } catch (final ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_INTERSECTS";
+ };
+ };
+
+ private final SearchFunction GEO_TOUCHES = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
+ final StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ final WKTReader reader = new WKTReader();
+ final Geometry geometry = reader.read(queryText);
+ final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryTouches(
+ geometry, contraints);
+ return statements;
+ } catch (final ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_TOUCHES";
+ };
+ };
+
+ private final SearchFunction GEO_CONTAINS = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
+ final StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ final WKTReader reader = new WKTReader();
+ final Geometry geometry = reader.read(queryText);
+ final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryContains(
+ geometry, contraints);
+ return statements;
+ } catch (final ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_CONTAINS";
+ };
+ };
+
+ private final SearchFunction GEO_OVERLAPS = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
+ final StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ final WKTReader reader = new WKTReader();
+ final Geometry geometry = reader.read(queryText);
+ final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryOverlaps(
+ geometry, contraints);
+ return statements;
+ } catch (final ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_OVERLAPS";
+ };
+ };
+
+ private final SearchFunction GEO_CROSSES = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
+ final StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ final WKTReader reader = new WKTReader();
+ final Geometry geometry = reader.read(queryText);
+ final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryCrosses(
+ geometry, contraints);
+ return statements;
+ } catch (final ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_CROSSES";
+ };
+ };
+
+ private final SearchFunction GEO_WITHIN = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
+ final StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ final WKTReader reader = new WKTReader();
+ final Geometry geometry = reader.read(queryText);
+ final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
+ geometry, contraints);
+ return statements;
+ } catch (final ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_WITHIN";
+ };
+ };
+
+ private final SearchFunction GEO_NEAR = new SearchFunction() {
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
+ final StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ final String[] args = queryText.split(NEAR_DELIM);
+ Optional<Double> maxDistanceOpt = Optional.empty();
+ Optional<Double> minDistanceOpt = Optional.empty();
+ final String query = args[0];
+
+ for (int ii = 1; ii < args.length; ii++) {
+ String numArg = args[ii];
+
+ // remove pre-padding 0's since NumberUtils.isNumber()
+ // will assume its octal if it starts with a 0.
+ while (numArg.startsWith("0")) {
+ numArg = numArg.substring(1);
+ }
+ // was 0
+ if (numArg.equals("")) {
+ // if max hasn't been set, set it to 0.
+ // Otherwise, min is just ignored.
+ if (!maxDistanceOpt.isPresent()) {
+ maxDistanceOpt = Optional.of(0.0);
+ }
+ } else {
+ if (!maxDistanceOpt.isPresent() && NumberUtils.isNumber(numArg)) {
+ // no variable identifier, going by order.
+ maxDistanceOpt = getDistanceOpt(numArg, "maxDistance");
+ } else if (NumberUtils.isNumber(numArg)) {
+ // no variable identifier, going by order.
+ minDistanceOpt = getDistanceOpt(numArg, "minDistance");
+ } else {
+ throw new IllegalArgumentException(numArg + " is not a valid Near function argument.");
+ }
+ }
+ }
+ final WKTReader reader = new WKTReader();
+ final Geometry geometry = reader.read(query);
+ final NearQuery nearQuery = new NearQuery(maxDistanceOpt, minDistanceOpt, geometry);
+ return geoIndexer.queryNear(nearQuery, contraints);
+ } catch (final ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ private Optional<Double> getDistanceOpt(final String num, final String name) {
+ try {
+ double dist = Double.parseDouble(num);
+ if(dist < 0) {
+ throw new IllegalArgumentException("Value for: " + name + " must be non-negative.");
+ }
+ return Optional.of(Double.parseDouble(num));
+ } catch (final NumberFormatException nfe) {
+ throw new IllegalArgumentException("Value for: " + name + " must be a number.");
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_NEAR";
+ }
+ };
+
+ /**
+ *
+ */
+ public class NearQuery {
+ private final Optional<Double> maxDistanceOpt;
+ private final Optional<Double> minDistanceOpt;
+ private final Geometry geo;
+
+ /**
+ *
+ * @param maxDistance
+ * @param minDistance
+ * @param geo
+ */
+ public NearQuery(final Optional<Double> maxDistance, final Optional<Double> minDistance,
+ final Geometry geo) {
+ maxDistanceOpt = maxDistance;
+ minDistanceOpt = minDistance;
+ this.geo = geo;
+ }
+
+ public Optional<Double> getMaxDistance() {
+ return maxDistanceOpt;
+ }
+
+ public Optional<Double> getMinDistance() {
+ return minDistanceOpt;
+ }
+
+ public Geometry getGeometry() {
+ return geo;
+ }
+ }
+
+ {
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_EQUALS, GEO_EQUALS);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_DISJOINT, GEO_DISJOINT);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_INTERSECTS, GEO_INTERSECTS);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_TOUCHES, GEO_TOUCHES);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_CONTAINS, GEO_CONTAINS);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_OVERLAPS, GEO_OVERLAPS);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_CROSSES, GEO_CROSSES);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_WITHIN, GEO_WITHIN);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_NEAR, GEO_NEAR);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/OptionalConfigUtils.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/OptionalConfigUtils.java b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/OptionalConfigUtils.java
new file mode 100644
index 0000000..bfd39d0
--- /dev/null
+++ b/extras/rya.geoindexing/geo.common/src/main/java/org/apache/rya/indexing/accumulo/geo/OptionalConfigUtils.java
@@ -0,0 +1,149 @@
+/*
+ * 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 java.util.List;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.rya.accumulo.AccumuloRdfConfiguration;
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.api.instance.RyaDetails;
+import org.apache.rya.indexing.FilterFunctionOptimizer;
+import org.apache.rya.indexing.GeoEnabledFilterFunctionOptimizer;
+import org.apache.rya.indexing.GeoIndexerType;
+import org.apache.rya.indexing.GeoTemporalIndexerType;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.geotemporal.GeoTemporalOptimizer;
+import org.openrdf.model.URI;
+
+import com.google.common.collect.Lists;
+
+/**
+ * A set of configuration utils to read a Hadoop {@link Configuration} object and create Cloudbase/Accumulo objects.
+ * Soon will deprecate this class. Use installer for the set methods, use {@link RyaDetails} for the get methods.
+ * New code must separate parameters that are set at Rya install time from that which is specific to the client.
+ * Also Accumulo index tables are pushed down to the implementation and not configured in conf.
+ */
+public class OptionalConfigUtils extends ConfigUtils {
+ private static final Logger logger = Logger.getLogger(OptionalConfigUtils.class);
+
+
+ public static final String GEO_NUM_PARTITIONS = "sc.geo.numPartitions";
+
+ public static final String USE_GEO = "sc.use_geo";
+ public static final String USE_GEOTEMPORAL = "sc.use_geotemporal";
+ public static final String USE_FREETEXT = "sc.use_freetext";
+ public static final String USE_TEMPORAL = "sc.use_temporal";
+ public static final String USE_ENTITY = "sc.use_entity";
+ public static final String USE_PCJ = "sc.use_pcj";
+ public static final String USE_OPTIMAL_PCJ = "sc.use.optimal.pcj";
+ public static final String USE_PCJ_UPDATER_INDEX = "sc.use.updater";
+ public static final String GEO_PREDICATES_LIST = "sc.geo.predicates";
+ public static final String GEO_INDEXER_TYPE = "sc.geo.geo_indexer_type";
+
+ public static Set<URI> getGeoPredicates(final Configuration conf) {
+ return getPredicates(conf, GEO_PREDICATES_LIST);
+ }
+
+ public static int getGeoNumPartitions(final Configuration conf) {
+ return conf.getInt(GEO_NUM_PARTITIONS, getNumPartitions(conf));
+ }
+
+ public static boolean getUseGeo(final Configuration conf) {
+ return conf.getBoolean(USE_GEO, false);
+ }
+
+ public static boolean getUseGeoTemporal(final Configuration conf) {
+ return conf.getBoolean(USE_GEOTEMPORAL, false);
+ }
+
+ /**
+ * Retrieves the value for the geo indexer type from the config.
+ * @param conf the {@link Configuration}.
+ * @return the {@link GeoIndexerType} found in the config or
+ * {@code UNSPECIFIED} if it doesn't exist.
+ */
+ public static GeoIndexerType getGeoIndexerType(final Configuration conf) {
+ String confType[] = conf.getStrings(GEO_INDEXER_TYPE, GeoIndexerType.UNSPECIFIED.name());
+ try {
+ return GeoIndexerType.valueOf(GeoIndexerType.class, confType[0]);
+ } catch (IllegalArgumentException e) {
+ // if none matched, invalid configuration, fail fast.
+ // this is where you can allow putting any classname in the configuration.
+ throw new Error("Configuration contains an unknown GeoIndexerType, found: \""+GEO_INDEXER_TYPE+"\"="+confType[0]);
+ }
+ }
+
+ public static void setIndexers(final RdfCloudTripleStoreConfiguration conf) {
+ final List<String> indexList = Lists.newArrayList();
+ final List<String> optimizers = Lists.newArrayList();
+
+ boolean useFilterIndex = false;
+ ConfigUtils.setIndexers(conf);
+ final String[] existingIndexers = conf.getStrings(AccumuloRdfConfiguration.CONF_ADDITIONAL_INDEXERS);
+ if(existingIndexers != null ) {
+ for (final String index : existingIndexers) {
+ indexList.add(index);
+ }
+ for (final String optimizer : conf.getStrings(RdfCloudTripleStoreConfiguration.CONF_OPTIMIZERS)){
+ optimizers.add(optimizer);
+ }
+ }
+
+ final GeoIndexerType geoIndexerType = getGeoIndexerType(conf);
+
+ if (ConfigUtils.getUseMongo(conf)) {
+ if (getUseGeo(conf)) {
+ if (geoIndexerType == GeoIndexerType.UNSPECIFIED) {
+ // Default to MongoGeoIndexer if not specified
+ indexList.add(GeoIndexerType.MONGO_DB.getGeoIndexerClassString());
+ } else {
+ indexList.add(geoIndexerType.getGeoIndexerClassString());
+ }
+ useFilterIndex = true;
+ }
+
+ if (getUseGeoTemporal(conf)) {
+ indexList.add(GeoTemporalIndexerType.MONGO_GEO_TEMPORAL.getGeoTemporalIndexerClassString());
+ optimizers.add(GeoTemporalIndexerType.MONGO_GEO_TEMPORAL_OPTIMIZER.getGeoTemporalIndexerClassString());
+ }
+ } else {
+ if (getUseGeo(conf)) {
+ if (geoIndexerType == GeoIndexerType.UNSPECIFIED) {
+ // Default to GeoMesaGeoIndexer if not specified
+ indexList.add(GeoIndexerType.GEO_MESA.getGeoIndexerClassString());
+ } else {
+ indexList.add(geoIndexerType.getGeoIndexerClassString());
+ }
+ useFilterIndex = true;
+ }
+ }
+
+ if (useFilterIndex) {
+ optimizers.remove(FilterFunctionOptimizer.class.getName());
+ optimizers.add(GeoEnabledFilterFunctionOptimizer.class.getName());
+ }
+
+ conf.setStrings(AccumuloRdfConfiguration.CONF_ADDITIONAL_INDEXERS, indexList.toArray(new String[]{}));
+ conf.setStrings(RdfCloudTripleStoreConfiguration.CONF_OPTIMIZERS, optimizers.toArray(new String[]{}));
+ }
+}
[12/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/accumulo/geo/GmlParser.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/accumulo/geo/GmlParser.java b/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/accumulo/geo/GmlParser.java
new file mode 100644
index 0000000..af72b3a
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/accumulo/geo/GmlParser.java
@@ -0,0 +1,48 @@
+/*
+ * 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 java.io.IOException;
+import java.io.Reader;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.rya.indexing.accumulo.geo.GeoParseUtils.GmlToGeometryParser;
+import org.geotools.gml3.GMLConfiguration;
+import org.xml.sax.SAXException;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+
+/**
+ * This wraps geotools parser for rya.geoCommon that cannot be dependent on geotools.
+ *
+ */
+public class GmlParser implements GmlToGeometryParser {
+
+ /* (non-Javadoc)
+ * @see org.apache.rya.indexing.accumulo.geo.GeoParseUtils.GmlToGeometryParser#parse(java.io.Reader)
+ */
+ @Override
+ public Geometry parse(Reader reader) throws IOException, SAXException, ParserConfigurationException {
+ final org.geotools.xml.Parser gmlParser = new org.geotools.xml.Parser(new GMLConfiguration());
+ return (Geometry) gmlParser.parse(reader);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/geoExamples/RyaGeoDirectExample.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/geoExamples/RyaGeoDirectExample.java b/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/geoExamples/RyaGeoDirectExample.java
new file mode 100644
index 0000000..664bbee
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geomesa/src/main/java/org/apache/rya/indexing/geoExamples/RyaGeoDirectExample.java
@@ -0,0 +1,404 @@
+package org.apache.rya.indexing.geoExamples;
+/*
+ * 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.List;
+import org.apache.commons.lang.Validate;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.rya.indexing.GeoRyaSailFactory;
+import org.apache.rya.indexing.accumulo.AccumuloIndexingConfiguration;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.accumulo.geo.OptionalConfigUtils;
+import org.apache.rya.indexing.external.PrecomputedJoinIndexerConfig;
+import org.apache.rya.indexing.external.PrecomputedJoinIndexerConfig.PrecomputedJoinStorageType;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.QueryEvaluationException;
+import org.openrdf.query.QueryLanguage;
+import org.openrdf.query.QueryResultHandlerException;
+import org.openrdf.query.TupleQuery;
+import org.openrdf.query.TupleQueryResultHandler;
+import org.openrdf.query.TupleQueryResultHandlerException;
+import org.openrdf.query.Update;
+import org.openrdf.query.UpdateExecutionException;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.repository.sail.SailRepositoryConnection;
+import org.openrdf.sail.Sail;
+
+public class RyaGeoDirectExample {
+ private static final Logger log = Logger.getLogger(RyaGeoDirectExample.class);
+
+ //
+ // Connection configuration parameters
+ //
+
+ private static final boolean USE_MOCK_INSTANCE = true;
+ private static final boolean PRINT_QUERIES = true;
+ private static final String INSTANCE = "instance";
+ private static final String RYA_TABLE_PREFIX = "x_test_triplestore_";
+ private static final String AUTHS = "U";
+
+ public static void main(final String[] args) throws Exception {
+ final Configuration conf = getConf();
+ conf.set(PrecomputedJoinIndexerConfig.PCJ_STORAGE_TYPE, PrecomputedJoinStorageType.ACCUMULO.name());
+ conf.setBoolean(ConfigUtils.DISPLAY_QUERY_PLAN, PRINT_QUERIES);
+ conf.setBoolean(OptionalConfigUtils.USE_GEO, true);
+
+ log.info("Creating the tables as root.");
+
+ SailRepository repository = null;
+ SailRepositoryConnection conn = null;
+
+ try {
+ log.info("Connecting to Geo Sail Repository.");
+ final Sail extSail = GeoRyaSailFactory.getInstance(conf);
+ repository = new SailRepository(extSail);
+ conn = repository.getConnection();
+
+ final long start = System.currentTimeMillis();
+ log.info("Running SPARQL Example: Add Point and Geo Search with PCJ");
+ testAddPointAndWithinSearchWithPCJ(conn);
+ log.info("Running SPARQL Example: Temporal, Freetext, and Geo Search");
+ testTemporalFreeGeoSearch(conn);
+ log.info("Running SPARQL Example: Geo, Freetext, and PCJ Search");
+ testGeoFreetextWithPCJSearch(conn);
+ log.info("Running SPARQL Example: Delete Geo Data");
+ testDeleteGeoData(conn);
+
+ log.info("TIME: " + (System.currentTimeMillis() - start) / 1000.);
+ } finally {
+ log.info("Shutting down");
+ closeQuietly(conn);
+ closeQuietly(repository);
+ }
+ }
+
+ private static void closeQuietly(final SailRepository repository) {
+ if (repository != null) {
+ try {
+ repository.shutDown();
+ } catch (final RepositoryException e) {
+ // quietly absorb this exception
+ }
+ }
+ }
+
+ private static void closeQuietly(final SailRepositoryConnection conn) {
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (final RepositoryException e) {
+ // quietly absorb this exception
+ }
+ }
+ }
+
+ private static Configuration getConf() {
+
+
+ return AccumuloIndexingConfiguration.builder()
+ .setUseMockAccumulo(USE_MOCK_INSTANCE)
+ .setAuths(AUTHS)
+ .setAccumuloUser("root")
+ .setAccumuloPassword("")
+ .setAccumuloInstance(INSTANCE)
+ .setRyaPrefix(RYA_TABLE_PREFIX)
+ .setUsePcj(true)
+ .setUseAccumuloFreetextIndex(true)
+ .setUseAccumuloTemporalIndex(true)
+ .build();
+
+ }
+
+
+
+ private static void testAddPointAndWithinSearchWithPCJ(
+ final SailRepositoryConnection conn) throws Exception {
+
+ final String update = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "INSERT DATA { " //
+ + " <urn:feature> a geo:Feature ; " //
+ + " geo:hasGeometry [ " //
+ + " a geo:Point ; " //
+ + " geo:asWKT \"Point(-77.03524 38.889468)\"^^geo:wktLiteral "//
+ + " ] . " //
+ + "}";
+
+ final Update u = conn.prepareUpdate(QueryLanguage.SPARQL, update);
+ u.execute();
+
+ String queryString;
+ TupleQuery tupleQuery;
+ CountingResultHandler tupleHandler;
+
+ // point outside search ring
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt " //
+ + "{" //
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-77 39, -76 39, -76 38, -77 38, -77 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("point outside search ring, Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 0);
+
+ // point inside search ring
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt " // ?e ?l ?o" //
+ + "{" //
+// + " ?feature a ?e . "//
+// + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+// + " ?e <uri:talksTo> ?o . "//
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-78 39, -77 39, -77 38, -78 38, -78 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("point inside search ring, Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 1);
+
+ // point inside search ring with Pre-Computed Join
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt "//?e ?l ?o" //
+ + "{" //
+// + " ?feature a ?e . "//
+// + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+// + " ?e <uri:talksTo> ?o . "//
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-78 39, -77 39, -77 38, -78 38, -78 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("point inside search ring with Pre-Computed Join, Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() >= 1); // may see points from
+ // during previous runs
+
+ // point outside search ring with PCJ
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt "//?e ?l ?o " //
+ + "{" //
+// + " ?feature a ?e . "//
+// + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+// + " ?e <uri:talksTo> ?o . "//
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-77 39, -76 39, -76 38, -77 38, -77 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("point outside search ring with PCJ, Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 0);
+
+ // point inside search ring with different Pre-Computed Join
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point "//?wkt ?e ?c ?l ?o " //
+ + "{" //
+// + " ?e a ?c . "//
+// + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+ //+ " ?e <uri:talksTo> ?o . "//
+ //+ " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-78 39, -77 39, -77 38, -78 38, -78 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("point inside search ring with different Pre-Computed Join, Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 1);
+ }
+
+ private static void testTemporalFreeGeoSearch(
+ final SailRepositoryConnection conn)
+ throws MalformedQueryException, RepositoryException,
+ UpdateExecutionException, TupleQueryResultHandlerException,
+ QueryEvaluationException {
+
+ String queryString;
+ TupleQuery tupleQuery;
+ CountingResultHandler tupleHandler;
+
+ // ring containing point
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "PREFIX time: <http://www.w3.org/2006/time#> "//
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> "//
+ + "PREFIX fts: <http://rdf.useekm.com/fts#> "//
+ + "SELECT ?feature ?point ?wkt ?event ?time ?person ?match" //
+ + "{" //
+ + " ?event a time:Instant . \n"//
+ + " ?event time:inXSDDateTime ?time . \n"//
+ + " FILTER(tempo:after(?time, '2001-01-01T01:01:03-08:00') ) \n"// after 3 seconds
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-78 39, -77 39, -77 38, -78 38, -78 39))\"^^geo:wktLiteral)). " //
+ + " ?person a <http://example.org/ontology/Person> . "//
+ + " ?person <http://www.w3.org/2000/01/rdf-schema#label> ?match . "//
+ + " FILTER(fts:text(?match, \"pal*\")) " //
+ + "}";//
+
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 0 ); // TODO ==5 some data is missing for this query!
+
+ }
+
+ private static void testGeoFreetextWithPCJSearch(
+ final SailRepositoryConnection conn)
+ throws MalformedQueryException, RepositoryException,
+ TupleQueryResultHandlerException, QueryEvaluationException {
+ // ring outside point
+ final String queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX fts: <http://rdf.useekm.com/fts#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt ?e ?c ?l ?o ?person ?match " //
+ + "{" //
+ + " ?person a <http://example.org/ontology/Person> . "//
+ + " ?person <http://www.w3.org/2000/01/rdf-schema#label> ?match . "//
+ + " FILTER(fts:text(?match, \"!alice & hose\")) " //
+ + " ?e a ?c . "//
+ + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "//
+ + " ?e <uri:talksTo> ?o . "//
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + " FILTER(geof:sfWithin(?wkt, \"POLYGON((-78 39, -77 39, -77 38, -78 38, -78 39))\"^^geo:wktLiteral)) " //
+ + "}";//
+ final TupleQuery tupleQuery = conn.prepareTupleQuery(
+ QueryLanguage.SPARQL, queryString);
+ final CountingResultHandler tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 0);// TODO ==1 some data is missing for this query!
+ }
+
+
+
+ private static void testDeleteGeoData(final SailRepositoryConnection conn)
+ throws Exception {
+ // Delete all stored points
+ final String sparqlDelete = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "DELETE {\n" //
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + "}\n" + "WHERE { \n" + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + "}";//
+
+ final Update deleteUpdate = conn.prepareUpdate(QueryLanguage.SPARQL,
+ sparqlDelete);
+ deleteUpdate.execute();
+
+ String queryString;
+ TupleQuery tupleQuery;
+ CountingResultHandler tupleHandler;
+
+ // Find all stored points
+ queryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#> "//
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/> "//
+ + "SELECT ?feature ?point ?wkt " //
+ + "{" //
+ + " ?feature a geo:Feature . "//
+ + " ?feature geo:hasGeometry ?point . "//
+ + " ?point a geo:Point . "//
+ + " ?point geo:asWKT ?wkt . "//
+ + "}";//
+ tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ tupleHandler = new CountingResultHandler();
+ tupleQuery.evaluate(tupleHandler);
+ log.info("Result count : " + tupleHandler.getCount());
+ Validate.isTrue(tupleHandler.getCount() == 0);
+ }
+
+ private static class CountingResultHandler implements
+ TupleQueryResultHandler {
+ private int count = 0;
+
+ public int getCount() {
+ return count;
+ }
+
+ public void resetCount() {
+ count = 0;
+ }
+
+ @Override
+ public void startQueryResult(final List<String> arg0)
+ throws TupleQueryResultHandlerException {
+ }
+
+ @Override
+ public void handleSolution(final BindingSet arg0)
+ throws TupleQueryResultHandlerException {
+ count++;
+ System.out.println(arg0);
+ }
+
+ @Override
+ public void endQueryResult() throws TupleQueryResultHandlerException {
+ }
+
+ @Override
+ public void handleBoolean(final boolean arg0)
+ throws QueryResultHandlerException {
+ }
+
+ @Override
+ public void handleLinks(final List<String> arg0)
+ throws QueryResultHandlerException {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.geomesa/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerSfTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geomesa/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerSfTest.java b/extras/rya.geoindexing/geo.geomesa/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerSfTest.java
new file mode 100644
index 0000000..4eba96a
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geomesa/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerSfTest.java
@@ -0,0 +1,520 @@
+/*
+ * 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.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.admin.TableOperations;
+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.StatementConstraints;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.geotools.geometry.jts.Geometries;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+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.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;
+
+/**
+ * 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 GeoIndexerSfTest {
+ private static AccumuloRdfConfiguration conf;
+ private static GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
+ private static GeoMesaGeoIndexer 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();
+
+ /**
+ * 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_ROUGH_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 GeoIndexerSfTest(final URI schemaToTest, final URI encodeMethod) {
+ this.schemaToTest = schemaToTest;
+ this.encodeMethod = encodeMethod;
+ }
+
+ /**
+ * Run before each test method.
+ * @throws Exception
+ */
+ @Before
+ public void before() throws Exception {
+ conf = new AccumuloRdfConfiguration();
+ conf.setTablePrefix("triplestore_");
+ 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());
+
+ 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 GeoMesaGeoIndexer();
+ g.setConf(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), new GmlParser());
+ 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
+ @Ignore
+ public void testIntersectsPoint() throws Exception {
+ // This seems like a bug
+ // scala.MatchError: POINT (2 4) (of class com.vividsolutions.jts.geom.Point)
+ // at org.locationtech.geomesa.filter.FilterHelper$.updateToIDLSafeFilter(FilterHelper.scala:53)
+ // compare(g.queryIntersects(F, EMPTY_CONSTRAINTS), A, F);
+ // compare(g.queryIntersects(F, EMPTY_CONSTRAINTS), EMPTY_RESULTS);
+ }
+
+ @Ignore
+ @Test
+ public void testIntersectsLine() throws Exception {
+ // This seems like a bug
+ // fails with:
+ // scala.MatchError: LINESTRING (2 0, 3 3) (of class com.vividsolutions.jts.geom.LineString)
+ // at org.locationtech.geomesa.filter.FilterHelper$.updateToIDLSafeFilter(FilterHelper.scala:53)
+ //compare(g.queryIntersects(E, EMPTY_CONSTRAINTS), A, E, D);
+ //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, 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);
+ // bug? java.lang.IllegalStateException: getX called on empty Point
+ // compare(g.queryCrosses(point(2, 0), EMPTY_CONSTRAINTS), E);
+ }
+
+ @Ignore
+ @Test
+ public void testCrossesLine() throws Exception {
+ // fails with:
+ // java.lang.IllegalStateException: getX called on empty Point
+ // at com.vividsolutions.jts.geom.Point.getX(Point.java:124)
+ // at org.locationtech.geomesa.utils.geohash.GeohashUtils$.considerCandidate$1(GeohashUtils.scala:1023)
+
+ // 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
+ // geomesa bug? scala.MatchError: POINT (2 4) (of class com.vividsolutions.jts.geom.Point)
+ // compare(g.queryWithin(F, EMPTY_CONSTRAINTS), F);
+
+ // line
+ // geomesa bug? scala.MatchError: LINESTRING (2 0, 3 2) (of class com.vividsolutions.jts.geom.LineString)
+ // 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);
+ }
+
+ @Ignore
+ @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);
+ }
+
+ @Ignore
+ @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);
+ }
+
+ @Ignore
+ @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/9e76b8d7/extras/rya.geoindexing/geo.geomesa/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geomesa/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerTest.java b/extras/rya.geoindexing/geo.geomesa/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerTest.java
new file mode 100644
index 0000000..0077c29
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geomesa/src/test/java/org/apache/rya/indexing/accumulo/geo/GeoIndexerTest.java
@@ -0,0 +1,395 @@
+/*
+ * 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.api.resolver.RdfToRyaConversions.convertStatement;
+import static org.apache.rya.indexing.GeoIndexingTestUtils.getSet;
+
+import java.util.Collections;
+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.StatementConstraints;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+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;
+
+/**
+ * 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;
+ private final GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
+
+ @Before
+ public void before() throws Exception {
+ conf = new AccumuloRdfConfiguration();
+ conf.setTablePrefix("triplestore_");
+ 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());
+
+ 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);
+ }
+ }
+
+ @Test
+ public void testRestrictPredicatesSearch() throws Exception {
+ conf.setStrings(ConfigUtils.GEO_PREDICATES_LIST, "pred:1,pred:2");
+ try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
+ f.setConf(conf);
+
+ 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));
+ }
+ }
+
+ @Test
+ public void testPrimeMeridianSearch() throws Exception {
+ try (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
+ f.setConf(conf);
+
+ 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
+ f.setConf(conf);
+
+ 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
+ f.setConf(conf);
+
+ 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
+ f.setConf(conf);
+
+ 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
+ f.setConf(conf);
+
+ 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
+ f.setConf(conf);
+
+ 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
+ f.setConf(conf);
+
+ 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 (final GeoMesaGeoIndexer f = new GeoMesaGeoIndexer()) {
+ f.setConf(conf);
+
+ 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/9e76b8d7/extras/rya.geoindexing/geo.geowave/pom.xml
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.geowave/pom.xml b/extras/rya.geoindexing/geo.geowave/pom.xml
new file mode 100644
index 0000000..92511f3
--- /dev/null
+++ b/extras/rya.geoindexing/geo.geowave/pom.xml
@@ -0,0 +1,61 @@
+<?xml version='1.0'?>
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.rya</groupId>
+ <artifactId>rya.geoindexing</artifactId>
+ <version>3.2.11-incubating-SNAPSHOT</version>
+ </parent>
+ <artifactId>geo.geowave</artifactId>
+ <name>Apache Rya Geo indexing using GeoWave</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <geotools.version>16.0</geotools.version>
+ </properties>
+
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.rya</groupId>
+ <artifactId>geo.common</artifactId>
+ <version>3.2.11-incubating-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>mil.nga.giat</groupId>
+ <artifactId>geowave-datastore-accumulo</artifactId>
+ <version>${geowave.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>mil.nga.giat</groupId>
+ <artifactId>geowave-adapter-vector</artifactId>
+ <version>${geowave.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.geotools.xsd</groupId>
+ <artifactId>gt-xsd-gml3</artifactId>
+ <version>${geotools.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.geotools</groupId>
+ <artifactId>gt-api</artifactId>
+ <version>${geotools.version}</version>
+ </dependency>
+ </dependencies>
+
+ </project>
[09/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorage.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorage.java b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorage.java
new file mode 100644
index 0000000..9c13c8b
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorage.java
@@ -0,0 +1,195 @@
+/**
+ * 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.geotemporal.mongo;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.IndexingExpr;
+import org.apache.rya.indexing.entity.model.TypedEntity;
+import org.apache.rya.indexing.entity.storage.mongo.DocumentConverter.DocumentConverterException;
+import org.apache.rya.indexing.entity.storage.mongo.MongoEntityStorage;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexException;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.bson.BsonDocument;
+import org.bson.BsonString;
+import org.bson.Document;
+import org.bson.conversions.Bson;
+
+import com.mongodb.BasicDBObjectBuilder;
+import com.mongodb.DBObject;
+import com.mongodb.ErrorCategory;
+import com.mongodb.MongoClient;
+import com.mongodb.MongoException;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoCursor;
+import com.mongodb.client.model.Filters;
+
+public class MongoEventStorage implements EventStorage {
+
+ protected static final String COLLECTION_NAME = "geotemporal-events";
+
+ private static final EventDocumentConverter EVENT_CONVERTER = new EventDocumentConverter();
+
+ /**
+ * A client connected to the Mongo instance that hosts the Rya instance.
+ */
+ protected final MongoClient mongo;
+
+ /**
+ * The name of the Rya instance the {@link TypedEntity}s are for.
+ */
+ protected final String ryaInstanceName;
+
+ /*
+ * Used to get the filter query objects.
+ */
+ private final GeoTemporalMongoDBStorageStrategy queryAdapter;
+
+ /**
+ * Constructs an instance of {@link MongoEntityStorage}.
+ *
+ * @param mongo - A client connected to the Mongo instance that hosts the Rya instance. (not null)
+ * @param ryaInstanceName - The name of the Rya instance the {@link TypedEntity}s are for. (not null)
+ */
+ public MongoEventStorage(final MongoClient mongo, final String ryaInstanceName) {
+ this.mongo = requireNonNull(mongo);
+ this.ryaInstanceName = requireNonNull(ryaInstanceName);
+ queryAdapter = new GeoTemporalMongoDBStorageStrategy();
+ }
+
+ @Override
+ public void create(final Event event) throws EventStorageException {
+ requireNonNull(event);
+
+ try {
+ mongo.getDatabase(ryaInstanceName)
+ .getCollection(COLLECTION_NAME)
+ .insertOne(EVENT_CONVERTER.toDocument(event));
+ } catch(final MongoException e) {
+ final ErrorCategory category = ErrorCategory.fromErrorCode( e.getCode() );
+ if(category == ErrorCategory.DUPLICATE_KEY) {
+ throw new EventAlreadyExistsException("Failed to create Event with Subject '" + event.getSubject().getData() + "'.", e);
+ }
+ throw new EventStorageException("Failed to create Event with Subject '" + event.getSubject().getData() + "'.", e);
+ }
+ }
+
+ @Override
+ public Optional<Event> get(final RyaURI subject) throws EventStorageException {
+ requireNonNull(subject);
+
+ try {
+ final Document document = mongo.getDatabase(ryaInstanceName)
+ .getCollection(COLLECTION_NAME)
+ .find( new BsonDocument(EventDocumentConverter.SUBJECT, new BsonString(subject.getData())) )
+ .first();
+
+ return document == null ?
+ Optional.empty() :
+ Optional.of( EVENT_CONVERTER.fromDocument(document) );
+
+ } catch(final MongoException | DocumentConverterException e) {
+ throw new EventStorageException("Could not get the Event with Subject '" + subject.getData() + "'.", e);
+ }
+ }
+
+ @Override
+ public Collection<Event> search(final Optional<RyaURI> subject, final Optional<Collection<IndexingExpr>> geoFilters, final Optional<Collection<IndexingExpr>> temporalFilters) throws EventStorageException {
+ requireNonNull(subject);
+
+ try {
+ final Collection<IndexingExpr> geos = (geoFilters.isPresent() ? geoFilters.get() : new ArrayList<>());
+ final Collection<IndexingExpr> tempos = (temporalFilters.isPresent() ? temporalFilters.get() : new ArrayList<>());
+ final DBObject filterObj = queryAdapter.getFilterQuery(geos, tempos);
+
+ final BasicDBObjectBuilder builder = BasicDBObjectBuilder
+ .start(filterObj.toMap());
+ if(subject.isPresent()) {
+ builder.append(EventDocumentConverter.SUBJECT, subject.get().getData());
+ }
+ final MongoCursor<Document> results = mongo.getDatabase(ryaInstanceName)
+ .getCollection(COLLECTION_NAME)
+ .find( BsonDocument.parse(builder.get().toString()) )
+ .iterator();
+
+ final List<Event> events = new ArrayList<>();
+ while(results.hasNext()) {
+ events.add(EVENT_CONVERTER.fromDocument(results.next()));
+ }
+ return events;
+ } catch(final MongoException | DocumentConverterException | GeoTemporalIndexException e) {
+ throw new EventStorageException("Could not get the Event.", e);
+ }
+ }
+
+ @Override
+ public void update(final Event old, final Event updated) throws StaleUpdateException, EventStorageException {
+ requireNonNull(old);
+ requireNonNull(updated);
+
+ // The updated entity must have the same Subject as the one it is replacing.
+ if(!old.getSubject().equals(updated.getSubject())) {
+ throw new EventStorageException("The old Event and the updated Event must have the same Subject. " +
+ "Old Subject: " + old.getSubject().getData() + ", Updated Subject: " + updated.getSubject().getData());
+ }
+
+ final Set<Bson> filters = new HashSet<>();
+
+ // Must match the old entity's Subject.
+ filters.add( makeSubjectFilter(old.getSubject()) );
+
+ // Do a find and replace.
+ final Bson oldEntityFilter = Filters.and(filters);
+ final Document updatedDoc = EVENT_CONVERTER.toDocument(updated);
+
+ final MongoCollection<Document> collection = mongo.getDatabase(ryaInstanceName).getCollection(COLLECTION_NAME);
+ if(collection.findOneAndReplace(oldEntityFilter, updatedDoc) == null) {
+ throw new StaleUpdateException("Could not update the Event with Subject '" + updated.getSubject().getData() + ".");
+ }
+ }
+
+ @Override
+ public boolean delete(final RyaURI subject) throws EventStorageException {
+ requireNonNull(subject);
+
+ try {
+ final Document deleted = mongo.getDatabase(ryaInstanceName)
+ .getCollection(COLLECTION_NAME)
+ .findOneAndDelete( makeSubjectFilter(subject) );
+
+ return deleted != null;
+
+ } catch(final MongoException e) {
+ throw new EventStorageException("Could not delete the Event with Subject '" + subject.getData() + "'.", e);
+ }
+ }
+
+ private static Bson makeSubjectFilter(final RyaURI subject) {
+ return Filters.eq(EventDocumentConverter.SUBJECT, subject.getData());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexer.java b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexer.java
new file mode 100644
index 0000000..2561c23
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexer.java
@@ -0,0 +1,227 @@
+/**
+ * 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.geotemporal.mongo;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
+import java.io.IOException;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.api.resolver.RyaToRdfConversions;
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.TemporalInterval;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.accumulo.geo.GeoParseUtils;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.apache.rya.indexing.mongodb.AbstractMongoIndexer;
+import org.apache.rya.indexing.mongodb.IndexingException;
+import org.apache.rya.indexing.mongodb.geo.GmlParser;
+import org.apache.rya.mongodb.MongoConnectorFactory;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.joda.time.DateTime;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.ParseException;
+
+/**
+ * Indexer that stores 2 separate statements as one 'Event' entity.
+ * <p>
+ * The statements are required to have the same subject, one must be
+ * a Geo based statement and the other a temporal based statement.
+ * <p>
+ * This indexer is later used when querying for geo/temporal statements
+ * in the format of:
+ * <pre>
+ * {@code
+ * QUERY PARAMS
+ * ?SomeSubject geo:predicate ?Location
+ * ?SomeSubject time:predicate ?Time
+ * Filter(?Location, geoFunction())
+ * Filter(?Time, temporalFunction())
+ * }
+ *
+ * The number of filters is not strict, but there must be at least one
+ * query pattern for geo and one for temporal as well as at least one
+ * filter for each type.
+ */
+public class MongoGeoTemporalIndexer extends AbstractMongoIndexer<GeoTemporalMongoDBStorageStrategy> implements GeoTemporalIndexer {
+ private static final Logger LOG = Logger.getLogger(MongoGeoTemporalIndexer.class);
+ public static final String GEO_TEMPORAL_COLLECTION = "geo_temporal";
+
+ private final AtomicReference<MongoDBRdfConfiguration> configuration = new AtomicReference<>();
+ private final AtomicReference<EventStorage> events = new AtomicReference<>();
+
+ @Override
+ public void init() {
+ initCore();
+ predicates = ConfigUtils.getGeoPredicates(conf);
+ predicates.addAll(ConfigUtils.getTemporalPredicates(conf));
+ storageStrategy = new GeoTemporalMongoDBStorageStrategy();
+ }
+
+ @Override
+ public void setConf(final Configuration conf) {
+ requireNonNull(conf);
+ events.set(null);
+ events.set(getEventStorage(conf));
+ super.conf = conf;
+ configuration.set(new MongoDBRdfConfiguration(conf));
+ }
+
+ @Override
+ public void storeStatement(final RyaStatement ryaStatement) throws IOException {
+ requireNonNull(ryaStatement);
+
+ try {
+ updateEvent(ryaStatement.getSubject(), ryaStatement);
+ } catch (IndexingException | ParseException e) {
+ throw new IOException("Failed to update the Entity index.", e);
+ }
+ }
+
+ @Override
+ public void deleteStatement(final RyaStatement statement) throws IOException {
+ requireNonNull(statement);
+ final RyaURI subject = statement.getSubject();
+ try {
+ final EventStorage eventStore = events.get();
+ checkState(events != null, "Must set this indexers configuration before storing statements.");
+
+ new EventUpdater(eventStore).update(subject, old -> {
+ final Event.Builder updated;
+ if(!old.isPresent()) {
+ return Optional.empty();
+ } else {
+ updated = Event.builder(old.get());
+ }
+
+ final Event currentEvent = updated.build();
+ final URI pred = statement.getObject().getDataType();
+ if((pred.equals(GeoConstants.GEO_AS_WKT) || pred.equals(GeoConstants.GEO_AS_GML) ||
+ pred.equals(GeoConstants.XMLSCHEMA_OGC_WKT) || pred.equals(GeoConstants.XMLSCHEMA_OGC_GML))
+ && currentEvent.getGeometry().isPresent()) {
+ //is geo and needs to be removed.
+ try {
+ if(currentEvent.getGeometry().get().equals(GeoParseUtils.getGeometry(RyaToRdfConversions.convertStatement(statement), new GmlParser()))) {
+ updated.setGeometry(null);
+ }
+ } catch (final Exception e) {
+ LOG.debug("Unable to parse the stored geometry.");
+ }
+ } else {
+ //is time
+ final String dateTime = statement.getObject().getData();
+ final Matcher matcher = TemporalInstantRfc3339.PATTERN.matcher(dateTime);
+ if (matcher.find()) {
+ final TemporalInterval interval = TemporalInstantRfc3339.parseInterval(dateTime);
+ if(currentEvent.getInterval().get().equals(interval)) {
+ updated.setTemporalInterval(null);
+ }
+ } else {
+ final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.parse(dateTime));
+ if(currentEvent.getInstant().get().equals(instant)) {
+ updated.setTemporalInstant(null);
+ }
+ }
+ }
+ return Optional.of(updated.build());
+ });
+ } catch (final IndexingException e) {
+ throw new IOException("Failed to update the Entity index.", e);
+ }
+ }
+
+ private void updateEvent(final RyaURI subject, final RyaStatement statement) throws IndexingException, ParseException {
+ final EventStorage eventStore = events.get();
+ checkState(events != null, "Must set this indexers configuration before storing statements.");
+
+ new EventUpdater(eventStore).update(subject, old -> {
+ final Event.Builder updated;
+ if(!old.isPresent()) {
+ updated = Event.builder()
+ .setSubject(subject);
+ } else {
+ updated = Event.builder(old.get());
+ }
+
+ final URI pred = statement.getObject().getDataType();
+ if(pred.equals(GeoConstants.GEO_AS_WKT) || pred.equals(GeoConstants.GEO_AS_GML) ||
+ pred.equals(GeoConstants.XMLSCHEMA_OGC_WKT) || pred.equals(GeoConstants.XMLSCHEMA_OGC_GML)) {
+ //is geo
+ try {
+ final Statement geoStatement = RyaToRdfConversions.convertStatement(statement);
+ final Geometry geometry = GeoParseUtils.getGeometry(geoStatement, new GmlParser());
+ updated.setGeometry(geometry);
+ } catch (final ParseException e) {
+ LOG.error(e.getMessage(), e);
+ }
+ } else {
+ //is time
+ final String dateTime = statement.getObject().getData();
+ final Matcher matcher = TemporalInstantRfc3339.PATTERN.matcher(dateTime);
+ if (matcher.find()) {
+ final TemporalInterval interval = TemporalInstantRfc3339.parseInterval(dateTime);
+ updated.setTemporalInterval(interval);
+ } else {
+ final TemporalInstant instant = new TemporalInstantRfc3339(DateTime.parse(dateTime));
+ updated.setTemporalInstant(instant);
+ }
+ }
+ return Optional.of(updated.build());
+ });
+ }
+
+ @Override
+ public String getCollectionName() {
+ return ConfigUtils.getTablePrefix(conf) + GEO_TEMPORAL_COLLECTION;
+ }
+
+ @Override
+ public EventStorage getEventStorage(final Configuration conf) {
+ requireNonNull(conf);
+
+ if(events.get() != null) {
+ return events.get();
+ }
+
+
+ final MongoDBRdfConfiguration mongoConf = new MongoDBRdfConfiguration(conf);
+ mongoClient = mongoConf.getMongoClient();
+ configuration.set(mongoConf);
+ if (mongoClient == null) {
+ mongoClient = MongoConnectorFactory.getMongoClient(conf);
+ }
+ final String ryaInstanceName = mongoConf.getMongoDBName();
+ events.set(new MongoEventStorage(mongoClient, ryaInstanceName));
+ return events.get();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/GeoMongoDBStorageStrategy.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/GeoMongoDBStorageStrategy.java b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/GeoMongoDBStorageStrategy.java
new file mode 100644
index 0000000..634359f
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/GeoMongoDBStorageStrategy.java
@@ -0,0 +1,247 @@
+package org.apache.rya.indexing.mongodb.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 java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.resolver.RyaToRdfConversions;
+import org.apache.rya.indexing.accumulo.geo.GeoParseUtils;
+import org.apache.rya.indexing.mongodb.IndexingMongoDBStorageStrategy;
+import org.bson.Document;
+import org.openrdf.model.Statement;
+import org.openrdf.query.MalformedQueryException;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.BasicDBObjectBuilder;
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKTReader;
+
+public class GeoMongoDBStorageStrategy extends IndexingMongoDBStorageStrategy {
+ private static final Logger LOG = Logger.getLogger(GeoMongoDBStorageStrategy.class);
+
+ private static final String GEO = "location";
+ public enum GeoQueryType {
+ INTERSECTS {
+ @Override
+ public String getKeyword() {
+ return "$geoIntersects";
+ }
+ }, WITHIN {
+ @Override
+ public String getKeyword() {
+ return "$geoWithin";
+ }
+ }, EQUALS {
+ @Override
+ public String getKeyword() {
+ return "$near";
+ }
+ }, NEAR {
+ @Override
+ public String getKeyword() {
+ return "$near";
+ }
+ };
+
+ public abstract String getKeyword();
+ }
+
+ public static class GeoQuery {
+ private final GeoQueryType queryType;
+ private final Geometry geo;
+
+ private final Double maxDistance;
+ private final Double minDistance;
+
+ public GeoQuery(final GeoQueryType queryType, final Geometry geo) {
+ this(queryType, geo, 0, 0);
+ }
+
+ public GeoQuery(final GeoQueryType queryType, final Geometry geo, final double maxDistance,
+ final double minDistance) {
+ this.queryType = queryType;
+ this.geo = geo;
+ this.maxDistance = maxDistance;
+ this.minDistance = minDistance;
+ }
+
+ public GeoQueryType getQueryType() {
+ return queryType;
+ }
+
+ public Geometry getGeo() {
+ return geo;
+ }
+
+ public Double getMaxDistance() {
+ return maxDistance;
+ }
+
+ public Double getMinDistance() {
+ return minDistance;
+ }
+ }
+
+ private final Double maxDistance;
+
+ public GeoMongoDBStorageStrategy(final Double maxDistance) {
+ this.maxDistance = maxDistance;
+ }
+
+ @Override
+ public void createIndices(final DBCollection coll){
+ coll.createIndex(new BasicDBObject(GEO, "2dsphere"));
+ }
+
+ public DBObject getQuery(final GeoQuery queryObj) throws MalformedQueryException {
+ final Geometry geo = queryObj.getGeo();
+ final GeoQueryType queryType = queryObj.getQueryType();
+ if (queryType == GeoQueryType.WITHIN && !(geo instanceof Polygon)) {
+ //They can also be applied to MultiPolygons, but those are not supported either.
+ throw new MalformedQueryException("Mongo Within operations can only be performed on Polygons.");
+ } else if(queryType == GeoQueryType.NEAR && !(geo instanceof Point)) {
+ //They can also be applied to Point, but those are not supported either.
+ throw new MalformedQueryException("Mongo near operations can only be performed on Points.");
+ }
+
+ BasicDBObject query;
+ if (queryType.equals(GeoQueryType.EQUALS)){
+ if(geo.getNumPoints() == 1) {
+ final List circle = new ArrayList();
+ circle.add(getPoint(geo));
+ circle.add(maxDistance);
+ final BasicDBObject polygon = new BasicDBObject("$centerSphere", circle);
+ query = new BasicDBObject(GEO, new BasicDBObject(GeoQueryType.WITHIN.getKeyword(), polygon));
+ } else {
+ query = new BasicDBObject(GEO, getCorrespondingPoints(geo));
+ }
+ } else if(queryType.equals(GeoQueryType.NEAR)) {
+ final BasicDBObject geoDoc = new BasicDBObject("$geometry", getDBPoint(geo));
+ if(queryObj.getMaxDistance() != 0) {
+ geoDoc.append("$maxDistance", queryObj.getMaxDistance());
+ }
+
+ if(queryObj.getMinDistance() != 0) {
+ geoDoc.append("$minDistance", queryObj.getMinDistance());
+ }
+ query = new BasicDBObject(GEO, new BasicDBObject(queryType.getKeyword(), geoDoc));
+ } else {
+ final BasicDBObject geoDoc = new BasicDBObject("$geometry", getCorrespondingPoints(geo));
+ query = new BasicDBObject(GEO, new BasicDBObject(queryType.getKeyword(), geoDoc));
+ }
+
+ return query;
+ }
+
+ @Override
+ public DBObject serialize(final RyaStatement ryaStatement) {
+ // if the object is wkt, then try to index it
+ // write the statement data to the fields
+ try {
+ final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
+ final Geometry geo = (new WKTReader()).read(GeoParseUtils.getWellKnownText(statement));
+ if(geo == null) {
+ LOG.error("Failed to parse geo statement: " + statement.toString());
+ return null;
+ }
+ final BasicDBObject base = (BasicDBObject) super.serialize(ryaStatement);
+ if (geo.getNumPoints() > 1) {
+ base.append(GEO, getCorrespondingPoints(geo));
+ } else {
+ base.append(GEO, getDBPoint(geo));
+ }
+ return base;
+ } catch(final ParseException e) {
+ LOG.error("Could not create geometry for statement " + ryaStatement, e);
+ return null;
+ }
+ }
+
+ public Document getCorrespondingPoints(final Geometry geo) {
+ //Polygons must be a 3 dimensional array.
+
+ //polygons must be a closed loop
+ final Document geoDoc = new Document();
+ if (geo instanceof Polygon) {
+ final Polygon poly = (Polygon) geo;
+ final List<List<List<Double>>> DBpoints = new ArrayList<>();
+
+ // outer shell of the polygon
+ final List<List<Double>> ring = new ArrayList<>();
+ for (final Coordinate coord : poly.getExteriorRing().getCoordinates()) {
+ ring.add(getPoint(coord));
+ }
+ DBpoints.add(ring);
+
+ // each hold in the polygon
+ for (int ii = 0; ii < poly.getNumInteriorRing(); ii++) {
+ final List<List<Double>> holeCoords = new ArrayList<>();
+ for (final Coordinate coord : poly.getInteriorRingN(ii).getCoordinates()) {
+ holeCoords.add(getPoint(coord));
+ }
+ DBpoints.add(holeCoords);
+ }
+ geoDoc.append("coordinates", DBpoints)
+ .append("type", "Polygon");
+ } else {
+ final List<List<Double>> points = getPoints(geo);
+ geoDoc.append("coordinates", points)
+ .append("type", "LineString");
+ }
+ return geoDoc;
+ }
+
+ private List<List<Double>> getPoints(final Geometry geo) {
+ final List<List<Double>> points = new ArrayList<>();
+ for (final Coordinate coord : geo.getCoordinates()) {
+ points.add(getPoint(coord));
+ }
+ return points;
+ }
+
+ public Document getDBPoint(final Geometry geo) {
+ return new Document()
+ .append("coordinates", getPoint(geo))
+ .append("type", "Point");
+ }
+
+ private List<Double> getPoint(final Coordinate coord) {
+ final List<Double> point = new ArrayList<>();
+ point.add(coord.x);
+ point.add(coord.y);
+ return point;
+ }
+
+ private List<Double> getPoint(final Geometry geo) {
+ final List<Double> point = new ArrayList<>();
+ point.add(geo.getCoordinate().x);
+ point.add(geo.getCoordinate().y);
+ return point;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/GmlParser.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/GmlParser.java b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/GmlParser.java
new file mode 100644
index 0000000..be5f1bc
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/GmlParser.java
@@ -0,0 +1,48 @@
+/*
+ * 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.mongodb.geo;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.rya.indexing.accumulo.geo.GeoParseUtils.GmlToGeometryParser;
+import org.geotools.gml3.GMLConfiguration;
+import org.xml.sax.SAXException;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+
+/**
+ * This wraps geotools parser for rya.geoCommon that cannot be dependent on geotools.
+ *
+ */
+public class GmlParser implements GmlToGeometryParser {
+
+ /* (non-Javadoc)
+ * @see org.apache.rya.indexing.accumulo.geo.GeoParseUtils.GmlToGeometryParser#parse(java.io.Reader)
+ */
+ @Override
+ public Geometry parse(Reader reader) throws IOException, SAXException, ParserConfigurationException {
+ final org.geotools.xml.Parser gmlParser = new org.geotools.xml.Parser(new GMLConfiguration());
+ return (Geometry) gmlParser.parse(reader);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoIndexer.java b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoIndexer.java
new file mode 100644
index 0000000..2abee76
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoIndexer.java
@@ -0,0 +1,154 @@
+package org.apache.rya.indexing.mongodb.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 org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.EQUALS;
+import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.INTERSECTS;
+import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.NEAR;
+import static org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQueryType.WITHIN;
+
+import org.apache.log4j.Logger;
+import org.apache.rya.indexing.GeoIndexer;
+import org.apache.rya.indexing.StatementConstraints;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.accumulo.geo.GeoTupleSet.GeoSearchFunctionFactory.NearQuery;
+import org.apache.rya.indexing.mongodb.AbstractMongoIndexer;
+import org.apache.rya.indexing.mongodb.geo.GeoMongoDBStorageStrategy.GeoQuery;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.openrdf.model.Statement;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.QueryEvaluationException;
+
+import com.mongodb.DBObject;
+import com.vividsolutions.jts.geom.Geometry;
+
+import info.aduna.iteration.CloseableIteration;
+
+public class MongoGeoIndexer extends AbstractMongoIndexer<GeoMongoDBStorageStrategy> implements GeoIndexer {
+ private static final String COLLECTION_SUFFIX = "geo";
+ private static final Logger logger = Logger.getLogger(MongoGeoIndexer.class);
+
+ @Override
+ public void init() {
+ initCore();
+ predicates = ConfigUtils.getGeoPredicates(conf);
+ if(predicates.size() == 0) {
+ logger.debug("No predicates specified for geo indexing. During insertion, all statements will be attempted to be indexed into the geo indexer.");
+ }
+ storageStrategy = new GeoMongoDBStorageStrategy(Double.valueOf(conf.get(MongoDBRdfConfiguration.MONGO_GEO_MAXDISTANCE, "1e-10")));
+ storageStrategy.createIndices(collection);
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryEquals(
+ final Geometry query, final StatementConstraints constraints) {
+ try {
+ final DBObject queryObj = storageStrategy.getQuery(new GeoQuery(EQUALS, query));
+ return withConstraints(constraints, queryObj);
+ } catch (final MalformedQueryException e) {
+ logger.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryDisjoint(
+ final Geometry query, final StatementConstraints constraints) {
+ throw new UnsupportedOperationException(
+ "Disjoint queries are not supported in Mongo DB.");
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryIntersects(
+ final Geometry query, final StatementConstraints constraints) {
+ try {
+ final DBObject queryObj = storageStrategy.getQuery(new GeoQuery(INTERSECTS, query));
+ return withConstraints(constraints, queryObj);
+ } catch (final MalformedQueryException e) {
+ logger.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryTouches(
+ final Geometry query, final StatementConstraints constraints) {
+ throw new UnsupportedOperationException(
+ "Touches queries are not supported in Mongo DB.");
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryCrosses(
+ final Geometry query, final StatementConstraints constraints) {
+ throw new UnsupportedOperationException(
+ "Crosses queries are not supported in Mongo DB.");
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryWithin(
+ final Geometry query, final StatementConstraints constraints) {
+ try {
+ final DBObject queryObj = storageStrategy.getQuery(new GeoQuery(WITHIN, query));
+ return withConstraints(constraints, queryObj);
+ } catch (final MalformedQueryException e) {
+ logger.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryNear(final NearQuery query, final StatementConstraints constraints) {
+ double maxDistance = 0;
+ double minDistance = 0;
+ if (query.getMaxDistance().isPresent()) {
+ maxDistance = query.getMaxDistance().get();
+ }
+
+ if (query.getMinDistance().isPresent()) {
+ minDistance = query.getMinDistance().get();
+ }
+
+ try {
+ final DBObject queryObj = storageStrategy.getQuery(new GeoQuery(NEAR, query.getGeometry(), maxDistance, minDistance));
+ return withConstraints(constraints, queryObj);
+ } catch (final MalformedQueryException e) {
+ logger.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryContains(
+ final Geometry query, final StatementConstraints constraints) {
+ throw new UnsupportedOperationException(
+ "Contains queries are not supported in Mongo DB.");
+ }
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> queryOverlaps(
+ final Geometry query, final StatementConstraints constraints) {
+ throw new UnsupportedOperationException(
+ "Overlaps queries are not supported in Mongo DB.");
+ }
+
+ @Override
+ public String getCollectionName() {
+ return ConfigUtils.getTablePrefix(conf) + COLLECTION_SUFFIX;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoTupleSet.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoTupleSet.java b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoTupleSet.java
new file mode 100644
index 0000000..c564d02
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/main/java/org/apache/rya/indexing/mongodb/geo/MongoGeoTupleSet.java
@@ -0,0 +1,361 @@
+package org.apache.rya.indexing.mongodb.geo;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.QueryEvaluationException;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Maps;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKTReader;
+
+/*
+ * 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 info.aduna.iteration.CloseableIteration;
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.GeoIndexer;
+import org.apache.rya.indexing.IndexingExpr;
+import org.apache.rya.indexing.IteratorFactory;
+import org.apache.rya.indexing.SearchFunction;
+import org.apache.rya.indexing.StatementConstraints;
+import org.apache.rya.indexing.accumulo.geo.GeoTupleSet;
+import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
+
+public class MongoGeoTupleSet extends ExternalTupleSet {
+
+ private Configuration conf;
+ private GeoIndexer geoIndexer;
+ private IndexingExpr filterInfo;
+
+
+ public MongoGeoTupleSet(IndexingExpr filterInfo, GeoIndexer geoIndexer) {
+ this.filterInfo = filterInfo;
+ this.geoIndexer = geoIndexer;
+ this.conf = geoIndexer.getConf();
+ }
+
+ @Override
+ public Set<String> getBindingNames() {
+ return filterInfo.getBindingNames();
+ }
+
+ public GeoTupleSet clone() {
+ return new GeoTupleSet(filterInfo, geoIndexer);
+ }
+
+ @Override
+ public double cardinality() {
+ return 0.0; // No idea how the estimate cardinality here.
+ }
+
+
+ @Override
+ public String getSignature() {
+ return "(GeoTuple Projection) " + "variables: " + Joiner.on(", ").join(this.getBindingNames()).replaceAll("\\s+", " ");
+ }
+
+
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (!(other instanceof MongoGeoTupleSet)) {
+ return false;
+ }
+ MongoGeoTupleSet arg = (MongoGeoTupleSet) other;
+ return this.filterInfo.equals(arg.filterInfo);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31*result + filterInfo.hashCode();
+
+ return result;
+ }
+
+
+
+ /**
+ * Returns an iterator over the result set of the contained IndexingExpr.
+ * <p>
+ * Should be thread-safe (concurrent invocation {@link OfflineIterable} this
+ * method can be expected with some query evaluators.
+ */
+ @Override
+ public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(BindingSet bindings)
+ throws QueryEvaluationException {
+
+
+ URI funcURI = filterInfo.getFunction();
+ SearchFunction searchFunction = (new MongoGeoSearchFunctionFactory(conf)).getSearchFunction(funcURI);
+ if(filterInfo.getArguments().length > 1) {
+ throw new IllegalArgumentException("Index functions do not support more than two arguments.");
+ }
+
+ String queryText = ((Value) filterInfo.getArguments()[0]).stringValue();
+
+ return IteratorFactory.getIterator(filterInfo.getSpConstraint(), bindings, queryText, searchFunction);
+ }
+
+
+
+ //returns appropriate search function for a given URI
+ //search functions used in GeoMesaGeoIndexer to access index
+ public class MongoGeoSearchFunctionFactory {
+
+ Configuration conf;
+
+ private final Map<URI, SearchFunction> SEARCH_FUNCTION_MAP = Maps.newHashMap();
+
+ public MongoGeoSearchFunctionFactory(Configuration conf) {
+ this.conf = conf;
+ }
+
+
+ /**
+ * Get a {@link GeoSearchFunction} for a given URI.
+ *
+ * @param searchFunction
+ * @return
+ */
+ public SearchFunction getSearchFunction(final URI searchFunction) {
+
+ SearchFunction geoFunc = null;
+
+ try {
+ geoFunc = getSearchFunctionInternal(searchFunction);
+ } catch (QueryEvaluationException e) {
+ e.printStackTrace();
+ }
+
+ return geoFunc;
+ }
+
+ private SearchFunction getSearchFunctionInternal(final URI searchFunction) throws QueryEvaluationException {
+ SearchFunction sf = SEARCH_FUNCTION_MAP.get(searchFunction);
+
+ if (sf != null) {
+ return sf;
+ } else {
+ throw new QueryEvaluationException("Unknown Search Function: " + searchFunction.stringValue());
+ }
+ }
+
+ private final SearchFunction GEO_EQUALS = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
+ StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ WKTReader reader = new WKTReader();
+ Geometry geometry = reader.read(queryText);
+ CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
+ geometry, contraints);
+ return statements;
+ } catch (ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_EQUALS";
+ };
+ };
+
+ private final SearchFunction GEO_DISJOINT = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
+ StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ WKTReader reader = new WKTReader();
+ Geometry geometry = reader.read(queryText);
+ CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
+ geometry, contraints);
+ return statements;
+ } catch (ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_DISJOINT";
+ };
+ };
+
+ private final SearchFunction GEO_INTERSECTS = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
+ StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ WKTReader reader = new WKTReader();
+ Geometry geometry = reader.read(queryText);
+ CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
+ geometry, contraints);
+ return statements;
+ } catch (ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_INTERSECTS";
+ };
+ };
+
+ private final SearchFunction GEO_TOUCHES = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
+ StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ WKTReader reader = new WKTReader();
+ Geometry geometry = reader.read(queryText);
+ CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
+ geometry, contraints);
+ return statements;
+ } catch (ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_TOUCHES";
+ };
+ };
+
+ private final SearchFunction GEO_CONTAINS = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
+ StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ WKTReader reader = new WKTReader();
+ Geometry geometry = reader.read(queryText);
+ CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
+ geometry, contraints);
+ return statements;
+ } catch (ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_CONTAINS";
+ };
+ };
+
+ private final SearchFunction GEO_OVERLAPS = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
+ StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ WKTReader reader = new WKTReader();
+ Geometry geometry = reader.read(queryText);
+ CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
+ geometry, contraints);
+ return statements;
+ } catch (ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_OVERLAPS";
+ };
+ };
+
+ private final SearchFunction GEO_CROSSES = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
+ StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ WKTReader reader = new WKTReader();
+ Geometry geometry = reader.read(queryText);
+ CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
+ geometry, contraints);
+ return statements;
+ } catch (ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_CROSSES";
+ };
+ };
+
+ private final SearchFunction GEO_WITHIN = new SearchFunction() {
+
+ @Override
+ public CloseableIteration<Statement, QueryEvaluationException> performSearch(String queryText,
+ StatementConstraints contraints) throws QueryEvaluationException {
+ try {
+ WKTReader reader = new WKTReader();
+ Geometry geometry = reader.read(queryText);
+ CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
+ geometry, contraints);
+ return statements;
+ } catch (ParseException e) {
+ throw new QueryEvaluationException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "GEO_WITHIN";
+ };
+ };
+
+ {
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_EQUALS, GEO_EQUALS);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_DISJOINT, GEO_DISJOINT);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_INTERSECTS, GEO_INTERSECTS);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_TOUCHES, GEO_TOUCHES);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_CONTAINS, GEO_CONTAINS);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_OVERLAPS, GEO_OVERLAPS);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_CROSSES, GEO_CROSSES);
+ SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_WITHIN, GEO_WITHIN);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java
new file mode 100644
index 0000000..7151b56
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java
@@ -0,0 +1,222 @@
+/*
+ * 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.geotemporal;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import java.util.List;
+
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexSetProvider;
+import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.ValueFactoryImpl;
+
+public class GeoTemporalProviderTest extends GeoTemporalTestBase {
+ private static final String URI_PROPERTY_AT_TIME = "Property:atTime";
+ private GeoTemporalIndexSetProvider provider;
+ private EventStorage events;
+ @Before
+ public void setup() {
+ events = mock(EventStorage.class);
+ provider = new GeoTemporalIndexSetProvider(events);
+ }
+
+ /*
+ * Simplest Happy Path test
+ */
+ @Test
+ public void twoPatternsTwoFilters_test() throws Exception {
+ final ValueFactory vf = new ValueFactoryImpl();
+ final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
+ final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
+ final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+ final String query =
+ "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+ "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+ "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+ "SELECT * WHERE { " +
+ "?subj <" + tempPred + "> ?time ."+
+ "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+ " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+ " FILTER(time:equals(?time, " + temp + ")) . " +
+ "}";
+ final QuerySegment<EventQueryNode> node = getQueryNode(query);
+ final List<EventQueryNode> nodes = provider.getExternalSets(node);
+ assertEquals(1, nodes.size());
+ }
+
+ @Test
+ public void onePatternTwoFilters_test() throws Exception {
+ final ValueFactory vf = new ValueFactoryImpl();
+ final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
+ final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
+ final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+ final String query =
+ "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+ "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+ "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+ "SELECT * WHERE { " +
+ "?subj <" + tempPred + "> ?time ."+
+ " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+ " FILTER(time:equals(?time, " + temp + ")) . " +
+ "}";
+ final QuerySegment<EventQueryNode> node = getQueryNode(query);
+ final List<EventQueryNode> nodes = provider.getExternalSets(node);
+ assertEquals(0, nodes.size());
+ }
+
+ @Test
+ public void twoPatternsOneFilter_test() throws Exception {
+ final ValueFactory vf = new ValueFactoryImpl();
+ final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
+ final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
+ final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+ final String query =
+ "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+ "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+ "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+ "SELECT * WHERE { " +
+ "?subj <" + tempPred + "> ?time ."+
+ "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+ " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+ "}";
+ final QuerySegment<EventQueryNode> node = getQueryNode(query);
+ final List<EventQueryNode> nodes = provider.getExternalSets(node);
+ assertEquals(0, nodes.size());
+ }
+
+ @Test
+ public void twoPatternsNoFilter_test() throws Exception {
+ final ValueFactory vf = new ValueFactoryImpl();
+ final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+ final String query =
+ "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+ "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+ "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+ "SELECT * WHERE { " +
+ "?subj <" + tempPred + "> ?time ."+
+ "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+ "}";
+ final QuerySegment<EventQueryNode> node = getQueryNode(query);
+ final List<EventQueryNode> nodes = provider.getExternalSets(node);
+ assertEquals(0, nodes.size());
+ }
+
+ @Test
+ public void twoPatternsTwoFiltersNotValid_test() throws Exception {
+ final ValueFactory vf = new ValueFactoryImpl();
+ final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
+ final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
+ final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+ //Only handles geo and temporal filters
+ final String query =
+ "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+ "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+ "PREFIX text: <http://rdf.useekm.com/fts#text>" +
+ "SELECT * WHERE { " +
+ "?subj <" + tempPred + "> ?time ."+
+ "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+ " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+ " FILTER(text:equals(?time, " + temp + ")) . " +
+ "}";
+ final QuerySegment<EventQueryNode> node = getQueryNode(query);
+ final List<EventQueryNode> nodes = provider.getExternalSets(node);
+ assertEquals(0, nodes.size());
+ }
+
+ @Test
+ public void twoSubjOneFilter_test() throws Exception {
+ final ValueFactory vf = new ValueFactoryImpl();
+ final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
+ final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
+ final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+ final String query =
+ "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+ "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+ "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+ "SELECT * WHERE { " +
+ "?subj <" + tempPred + "> ?time ."+
+ "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+ "?subj2 <" + tempPred + "> ?time2 ."+
+ "?subj2 <" + GeoConstants.GEO_AS_WKT + "> ?loc2 . " +
+ " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+ " FILTER(time:equals(?time, " + temp + ")) . " +
+ "}";
+ final QuerySegment<EventQueryNode> node = getQueryNode(query);
+ final List<EventQueryNode> nodes = provider.getExternalSets(node);
+ assertEquals(1, nodes.size());
+ }
+
+ @Test
+ public void twoNode_test() throws Exception {
+ final ValueFactory vf = new ValueFactoryImpl();
+ final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
+ final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
+ final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+ final String query =
+ "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+ "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+ "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+ "SELECT * WHERE { " +
+ "?subj <" + tempPred + "> ?time ."+
+ "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+ "?subj2 <" + tempPred + "> ?time2 ."+
+ "?subj2 <" + GeoConstants.GEO_AS_WKT + "> ?loc2 . " +
+ " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+ " FILTER(time:equals(?time, " + temp + ")) . " +
+ " FILTER(geos:sfContains(?loc2, " + geo + ")) . " +
+ " FILTER(time:equals(?time2, " + temp + ")) . " +
+ "}";
+ final QuerySegment<EventQueryNode> node = getQueryNode(query);
+ final List<EventQueryNode> nodes = provider.getExternalSets(node);
+ assertEquals(2, nodes.size());
+ }
+
+ @Test
+ public void twoSubjectMultiFilter_test() throws Exception {
+ final ValueFactory vf = new ValueFactoryImpl();
+ final Value geo = vf.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
+ final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
+ final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+ final String query =
+ "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+ "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+ "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+ "SELECT * WHERE { " +
+ "?subj <" + tempPred + "> ?time ."+
+ "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+ " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+ " FILTER(time:equals(?time, " + temp + ")) . " +
+ " FILTER(geos:sfWithin(?loc, " + geo + ")) . " +
+ " FILTER(time:before(?time, " + temp + ")) . " +
+ "}";
+ final QuerySegment<EventQueryNode> node = getQueryNode(query);
+ final List<EventQueryNode> nodes = provider.getExternalSets(node);
+ assertEquals(1, nodes.size());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java
new file mode 100644
index 0000000..6b6bf15
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java
@@ -0,0 +1,140 @@
+/*
+ * 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.geotemporal;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
+import org.junit.ComparisonFailure;
+import org.mockito.Mockito;
+import org.openrdf.query.algebra.FunctionCall;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
+import org.openrdf.query.algebra.helpers.StatementPatternCollector;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+import com.vividsolutions.jts.geom.Coordinate;
+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;
+
+public class GeoTemporalTestBase {
+ private static final GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
+
+ /**
+ * Make an uniform instant with given seconds.
+ */
+ protected static TemporalInstant makeInstant(final int secondsMakeMeUnique) {
+ return new TemporalInstantRfc3339(2015, 12, 30, 12, 00, secondsMakeMeUnique);
+ }
+
+ protected 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;
+ }
+
+ protected static Point point(final double x, final double y) {
+ return gf.createPoint(new Coordinate(x, y));
+ }
+
+ protected 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);
+ }
+
+ protected 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 };
+ }
+
+ protected void assertEqualMongo(final Object expected, final Object actual) throws ComparisonFailure {
+ try {
+ assertEquals(expected, actual);
+ } catch(final Throwable e) {
+ throw new ComparisonFailure(e.getMessage(), expected.toString(), actual.toString());
+ }
+ }
+
+ public List<FunctionCall> getFilters(final String query) throws Exception {
+ final FunctionCallCollector collector = new FunctionCallCollector();
+ new SPARQLParser().parseQuery(query, null).getTupleExpr().visit(collector);
+ return collector.getTupleExpr();
+ }
+
+ public List<StatementPattern> getSps(final String query) throws Exception {
+ final StatementPatternCollector collector = new StatementPatternCollector();
+ new SPARQLParser().parseQuery(query, null).getTupleExpr().visit(collector);
+ return collector.getStatementPatterns();
+ }
+
+ public QuerySegment<EventQueryNode> getQueryNode(final String query) throws Exception {
+ final List<QueryModelNode> exprs = getNodes(query);
+ final QuerySegment<EventQueryNode> node = Mockito.mock(QuerySegment.class);
+ //provider only cares about Ordered nodes.
+ Mockito.when(node.getOrderedNodes()).thenReturn(exprs);
+ return node;
+ }
+
+ private static List<QueryModelNode> getNodes(final String sparql) throws Exception {
+ final NodeCollector collector = new NodeCollector();
+ new SPARQLParser().parseQuery(sparql, null).getTupleExpr().visit(collector);
+ return collector.getTupleExpr();
+ }
+
+ private static class NodeCollector extends QueryModelVisitorBase<RuntimeException> {
+ private final List<QueryModelNode> stPatterns = new ArrayList<>();
+
+ public List<QueryModelNode> getTupleExpr() {
+ return stPatterns;
+ }
+
+ @Override
+ public void meet(final FunctionCall node) {
+ stPatterns.add(node);
+ }
+
+ @Override
+ public void meet(final StatementPattern node) {
+ stPatterns.add(node);
+ }
+ }
+
+ private static class FunctionCallCollector extends QueryModelVisitorBase<RuntimeException> {
+ private final List<FunctionCall> filters = new ArrayList<>();
+
+ public List<FunctionCall> getTupleExpr() {
+ return filters;
+ }
+
+ @Override
+ public void meet(final FunctionCall node) {
+ filters.add(node);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java
new file mode 100644
index 0000000..ff778ba
--- /dev/null
+++ b/extras/rya.geoindexing/geo.mongo/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java
@@ -0,0 +1,176 @@
+/**
+ * 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.geotemporal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.GeoRyaSailFactory;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.accumulo.geo.OptionalConfigUtils;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.geotemporal.mongo.MongoGeoTemporalIndexer;
+import org.apache.rya.indexing.geotemporal.mongo.MongoITBase;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.QueryLanguage;
+import org.openrdf.query.TupleQueryResult;
+import org.openrdf.query.impl.MapBindingSet;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.repository.sail.SailRepositoryConnection;
+import org.openrdf.sail.Sail;
+
+import com.mongodb.MongoClient;
+
+public class MongoGeoTemporalIndexIT extends MongoITBase {
+ private static final String URI_PROPERTY_AT_TIME = "Property:atTime";
+
+ private static final ValueFactory VF = ValueFactoryImpl.getInstance();
+ private MongoDBRdfConfiguration conf;
+ private SailRepositoryConnection conn;
+ private MongoClient mongoClient;
+ private static final AtomicInteger COUNTER = new AtomicInteger(1);
+
+ @Before
+ public void setUp() throws Exception{
+ mongoClient = super.getMongoClient();
+ conf = new MongoDBRdfConfiguration();
+ conf.set(MongoDBRdfConfiguration.MONGO_DB_NAME, MongoGeoTemporalIndexIT.class.getSimpleName() + "_" + COUNTER.getAndIncrement());
+ conf.set(MongoDBRdfConfiguration.MONGO_COLLECTION_PREFIX, "rya");
+ conf.set(RdfCloudTripleStoreConfiguration.CONF_TBL_PREFIX, "rya");
+ conf.setBoolean(ConfigUtils.USE_MONGO, true);
+ conf.setBoolean(OptionalConfigUtils.USE_GEOTEMPORAL, true);
+ conf.setMongoClient(mongoClient);
+
+ final Sail sail = GeoRyaSailFactory.getInstance(conf);
+ conn = new SailRepository(sail).getConnection();
+ conn.begin();
+
+ addStatements();
+ }
+
+ @Test
+ public void ensureInEventStore_Test() throws Exception {
+ final MongoGeoTemporalIndexer indexer = new MongoGeoTemporalIndexer();
+ indexer.initIndexer(conf, mongoClient);
+
+ final EventStorage events = indexer.getEventStorage(conf);
+ final RyaURI subject = new RyaURI("urn:event1");
+ final Optional<Event> event = events.get(subject);
+ assertTrue(event.isPresent());
+ }
+
+ @Test
+ public void constantSubjQuery_Test() throws Exception {
+ final String query =
+ "PREFIX time: <http://www.w3.org/2006/time#> \n"
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+ + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+ + "SELECT * "
+ + "WHERE { "
+ + " <urn:event1> time:atTime ?time . "
+ + " <urn:event1> geo:asWKT ?point . "
+ + " FILTER(geof:sfWithin(?point, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
+ + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
+ + "}";
+
+ final TupleQueryResult rez = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate();
+ final Set<BindingSet> results = new HashSet<>();
+ while(rez.hasNext()) {
+ final BindingSet bs = rez.next();
+ results.add(bs);
+ }
+ final MapBindingSet expected = new MapBindingSet();
+ expected.addBinding("point", VF.createLiteral("POINT (0 0)"));
+ expected.addBinding("time", VF.createLiteral("2015-12-30T12:00:00Z"));
+
+ assertEquals(1, results.size());
+ assertEquals(expected, results.iterator().next());
+ }
+
+ @Test
+ public void variableSubjQuery_Test() throws Exception {
+ final String query =
+ "PREFIX time: <http://www.w3.org/2006/time#> \n"
+ + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+ + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+ + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+ + "SELECT * "
+ + "WHERE { "
+ + " ?subj time:atTime ?time . "
+ + " ?subj geo:asWKT ?point . "
+ + " FILTER(geof:sfWithin(?point, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
+ + " FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
+ + "}";
+
+ final TupleQueryResult rez = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate();
+ final List<BindingSet> results = new ArrayList<>();
+ while(rez.hasNext()) {
+ final BindingSet bs = rez.next();
+ results.add(bs);
+ }
+ final MapBindingSet expected1 = new MapBindingSet();
+ expected1.addBinding("point", VF.createLiteral("POINT (0 0)"));
+ expected1.addBinding("time", VF.createLiteral("2015-12-30T12:00:00Z"));
+
+ final MapBindingSet expected2 = new MapBindingSet();
+ expected2.addBinding("point", VF.createLiteral("POINT (1 1)"));
+ expected2.addBinding("time", VF.createLiteral("2015-12-30T12:00:00Z"));
+
+ assertEquals(2, results.size());
+ assertEquals(expected1, results.get(0));
+ assertEquals(expected2, results.get(1));
+ }
+
+ private void addStatements() throws Exception {
+ URI subject = VF.createURI("urn:event1");
+ final URI predicate = VF.createURI(URI_PROPERTY_AT_TIME);
+ Value object = VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
+ conn.add(VF.createStatement(subject, predicate, object));
+
+ object = VF.createLiteral("Point(0 0)", GeoConstants.XMLSCHEMA_OGC_WKT);
+ conn.add(VF.createStatement(subject, GeoConstants.GEO_AS_WKT, object));
+
+ subject = VF.createURI("urn:event2");
+ object = VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString());
+ conn.add(VF.createStatement(subject, predicate, object));
+
+ object = VF.createLiteral("Point(1 1)", GeoConstants.XMLSCHEMA_OGC_WKT);
+ conn.add(VF.createStatement(subject, GeoConstants.GEO_AS_WKT, object));
+ }
+}
[06/14] incubator-rya git commit: RYA-324,
RYA-272 Geo refactoring and examples closes #182
Posted by dl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java
deleted file mode 100644
index 12a84fd..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * 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 java.util.Objects.requireNonNull;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.Connector;
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.mock.MockInstance;
-import org.apache.commons.lang.StringUtils;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.log4j.Logger;
-import org.apache.rya.accumulo.experimental.AbstractAccumuloIndexer;
-import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
-import org.apache.rya.api.domain.RyaStatement;
-import org.apache.rya.api.resolver.RyaToRdfConversions;
-import org.apache.rya.indexing.GeoIndexer;
-import org.apache.rya.indexing.Md5Hash;
-import org.apache.rya.indexing.OptionalConfigUtils;
-import org.apache.rya.indexing.StatementConstraints;
-import org.apache.rya.indexing.StatementSerializer;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.accumulo.geo.GeoTupleSet.GeoSearchFunctionFactory.NearQuery;
-import org.geotools.data.DataStore;
-import org.geotools.data.DataStoreFinder;
-import org.geotools.data.DataUtilities;
-import org.geotools.data.FeatureSource;
-import org.geotools.data.FeatureStore;
-import org.geotools.data.Query;
-import org.geotools.factory.CommonFactoryFinder;
-import org.geotools.factory.Hints;
-import org.geotools.feature.DefaultFeatureCollection;
-import org.geotools.feature.FeatureIterator;
-import org.geotools.feature.SchemaException;
-import org.geotools.feature.simple.SimpleFeatureBuilder;
-import org.geotools.filter.text.cql2.CQLException;
-import org.geotools.filter.text.ecql.ECQL;
-import org.locationtech.geomesa.accumulo.index.Constants;
-import org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.feature.simple.SimpleFeatureType;
-import org.opengis.filter.Filter;
-import org.opengis.filter.FilterFactory;
-import org.opengis.filter.identity.Identifier;
-import org.openrdf.model.Literal;
-import org.openrdf.model.Statement;
-import org.openrdf.model.URI;
-import org.openrdf.query.QueryEvaluationException;
-
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.io.ParseException;
-
-import info.aduna.iteration.CloseableIteration;
-
-/**
- * A {@link GeoIndexer} wrapper around a GeoMesa {@link AccumuloDataStore}. This class configures and connects to the Datastore, creates the
- * RDF Feature Type, and interacts with the Datastore.
- * <p>
- * Specifically, this class creates a RDF Feature type and stores each RDF Statement as a RDF Feature in the datastore. Each feature
- * contains the standard set of GeoMesa attributes (Geometry, Start Date, and End Date). The GeoMesaGeoIndexer populates the Geometry
- * attribute by parsing the Well-Known Text contained in the RDF Statement’s object literal value.
- * <p>
- * The RDF Feature contains four additional attributes for each component of the RDF Statement. These attributes are:
- * <p>
- * <table border="1">
- * <tr>
- * <th>Name</th>
- * <th>Symbol</th>
- * <th>Type</th>
- * </tr>
- * <tr>
- * <td>Subject Attribute</td>
- * <td>S</td>
- * <td>String</td>
- * </tr>
- * </tr>
- * <tr>
- * <td>Predicate Attribute</td>
- * <td>P</td>
- * <td>String</td>
- * </tr>
- * </tr>
- * <tr>
- * <td>Object Attribute</td>
- * <td>O</td>
- * <td>String</td>
- * </tr>
- * </tr>
- * <tr>
- * <td>Context Attribute</td>
- * <td>C</td>
- * <td>String</td>
- * </tr>
- * </table>
- */
-public class GeoMesaGeoIndexer extends AbstractAccumuloIndexer implements GeoIndexer {
-
- private static final String TABLE_SUFFIX = "geo";
-
- private static final Logger logger = Logger.getLogger(GeoMesaGeoIndexer.class);
-
- private static final String FEATURE_NAME = "RDF";
-
- private static final String SUBJECT_ATTRIBUTE = "S";
- private static final String PREDICATE_ATTRIBUTE = "P";
- private static final String OBJECT_ATTRIBUTE = "O";
- private static final String CONTEXT_ATTRIBUTE = "C";
- private static final String GEOMETRY_ATTRIBUTE = Constants.SF_PROPERTY_GEOMETRY;
-
- private Set<URI> validPredicates;
- private Configuration conf;
- private FeatureStore<SimpleFeatureType, SimpleFeature> featureStore;
- private FeatureSource<SimpleFeatureType, SimpleFeature> featureSource;
- private SimpleFeatureType featureType;
- private boolean isInit = false;
-
- //initialization occurs in setConf because index is created using reflection
- @Override
- public void setConf(final Configuration conf) {
- this.conf = conf;
- if (!isInit) {
- try {
- initInternal();
- isInit = true;
- } catch (final IOException e) {
- logger.warn("Unable to initialize index. Throwing Runtime Exception. ", e);
- throw new RuntimeException(e);
- }
- }
- }
-
- @Override
- public Configuration getConf() {
- return conf;
- }
-
-
- private void initInternal() throws IOException {
- validPredicates = ConfigUtils.getGeoPredicates(conf);
-
- final DataStore dataStore = createDataStore(conf);
-
- try {
- featureType = getStatementFeatureType(dataStore);
- } catch (final IOException | SchemaException e) {
- throw new IOException(e);
- }
-
- featureSource = dataStore.getFeatureSource(featureType.getName());
- if (!(featureSource instanceof FeatureStore)) {
- throw new IllegalStateException("Could not retrieve feature store");
- }
- featureStore = (FeatureStore<SimpleFeatureType, SimpleFeature>) featureSource;
- }
-
- private static DataStore createDataStore(final Configuration conf) throws IOException {
- // get the configuration parameters
- final Instance instance = ConfigUtils.getInstance(conf);
- final boolean useMock = instance instanceof MockInstance;
- final String instanceId = instance.getInstanceName();
- final String zookeepers = instance.getZooKeepers();
- final String user = ConfigUtils.getUsername(conf);
- final String password = ConfigUtils.getPassword(conf);
- final String auths = ConfigUtils.getAuthorizations(conf).toString();
- final String tableName = getTableName(conf);
- final int numParitions = OptionalConfigUtils.getGeoNumPartitions(conf);
-
- final String featureSchemaFormat = "%~#s%" + numParitions + "#r%" + FEATURE_NAME
- + "#cstr%0,3#gh%yyyyMMdd#d::%~#s%3,2#gh::%~#s%#id";
- // build the map of parameters
- final Map<String, Serializable> params = new HashMap<String, Serializable>();
- params.put("instanceId", instanceId);
- params.put("zookeepers", zookeepers);
- params.put("user", user);
- params.put("password", password);
- params.put("auths", auths);
- params.put("tableName", tableName);
- params.put("indexSchemaFormat", featureSchemaFormat);
- params.put("useMock", Boolean.toString(useMock));
-
- // fetch the data store from the finder
- return DataStoreFinder.getDataStore(params);
- }
-
- private static SimpleFeatureType getStatementFeatureType(final DataStore dataStore) throws IOException, SchemaException {
- SimpleFeatureType featureType;
-
- final String[] datastoreFeatures = dataStore.getTypeNames();
- if (Arrays.asList(datastoreFeatures).contains(FEATURE_NAME)) {
- featureType = dataStore.getSchema(FEATURE_NAME);
- } else {
- final String featureSchema = SUBJECT_ATTRIBUTE + ":String," //
- + PREDICATE_ATTRIBUTE + ":String," //
- + OBJECT_ATTRIBUTE + ":String," //
- + CONTEXT_ATTRIBUTE + ":String," //
- + GEOMETRY_ATTRIBUTE + ":Geometry:srid=4326;geomesa.mixed.geometries='true'";
- featureType = SimpleFeatureTypes.createType(FEATURE_NAME, featureSchema);
- dataStore.createSchema(featureType);
- }
- return featureType;
- }
-
- @Override
- public void storeStatements(final Collection<RyaStatement> ryaStatements) throws IOException {
- // create a feature collection
- final DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
- for (final RyaStatement ryaStatement : ryaStatements) {
- final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
- // if the predicate list is empty, accept all predicates.
- // Otherwise, make sure the predicate is on the "valid" list
- final boolean isValidPredicate = validPredicates.isEmpty() || validPredicates.contains(statement.getPredicate());
-
- if (isValidPredicate && (statement.getObject() instanceof Literal)) {
- try {
- final SimpleFeature feature = createFeature(featureType, statement);
- featureCollection.add(feature);
- } catch (final ParseException e) {
- logger.warn("Error getting geo from statement: " + statement.toString(), e);
- }
- }
- }
-
- // write this feature collection to the store
- if (!featureCollection.isEmpty()) {
- featureStore.addFeatures(featureCollection);
- }
- }
-
- @Override
- public void storeStatement(final RyaStatement statement) throws IOException {
- storeStatements(Collections.singleton(statement));
- }
-
- private static SimpleFeature createFeature(final SimpleFeatureType featureType, final Statement statement) throws ParseException {
- final String subject = StatementSerializer.writeSubject(statement);
- final String predicate = StatementSerializer.writePredicate(statement);
- final String object = StatementSerializer.writeObject(statement);
- final String context = StatementSerializer.writeContext(statement);
-
- // create the feature
- final Object[] noValues = {};
-
- // create the hash
- final String statementId = Md5Hash.md5Base64(StatementSerializer.writeStatement(statement));
- final SimpleFeature newFeature = SimpleFeatureBuilder.build(featureType, noValues, statementId);
-
- // write the statement data to the fields
- final Geometry geom = GeoParseUtils.getGeometry(statement);
- if(geom == null || geom.isEmpty() || !geom.isValid()) {
- throw new ParseException("Could not create geometry for statement " + statement);
- }
- newFeature.setDefaultGeometry(geom);
-
- newFeature.setAttribute(SUBJECT_ATTRIBUTE, subject);
- newFeature.setAttribute(PREDICATE_ATTRIBUTE, predicate);
- newFeature.setAttribute(OBJECT_ATTRIBUTE, object);
- newFeature.setAttribute(CONTEXT_ATTRIBUTE, context);
-
- // preserve the ID that we created for this feature
- // (set the hint to FALSE to have GeoTools generate IDs)
- newFeature.getUserData().put(Hints.USE_PROVIDED_FID, java.lang.Boolean.TRUE);
-
- return newFeature;
- }
-
- private CloseableIteration<Statement, QueryEvaluationException> performQuery(final String type, final Geometry geometry,
- final StatementConstraints contraints) {
- final List<String> filterParms = new ArrayList<String>();
-
- filterParms.add(type + "(" + GEOMETRY_ATTRIBUTE + ", " + geometry + " )");
-
- if (contraints.hasSubject()) {
- filterParms.add("( " + SUBJECT_ATTRIBUTE + "= '" + contraints.getSubject() + "') ");
- }
- if (contraints.hasContext()) {
- filterParms.add("( " + CONTEXT_ATTRIBUTE + "= '" + contraints.getContext() + "') ");
- }
- if (contraints.hasPredicates()) {
- final List<String> predicates = new ArrayList<String>();
- for (final URI u : contraints.getPredicates()) {
- predicates.add("( " + PREDICATE_ATTRIBUTE + "= '" + u.stringValue() + "') ");
- }
- filterParms.add("(" + StringUtils.join(predicates, " OR ") + ")");
- }
-
- final String filterString = StringUtils.join(filterParms, " AND ");
- logger.info("Performing geomesa query : " + filterString);
-
- return getIteratorWrapper(filterString);
- }
-
- private CloseableIteration<Statement, QueryEvaluationException> getIteratorWrapper(final String filterString) {
-
- return new CloseableIteration<Statement, QueryEvaluationException>() {
-
- private FeatureIterator<SimpleFeature> featureIterator = null;
-
- FeatureIterator<SimpleFeature> getIterator() throws QueryEvaluationException {
- if (featureIterator == null) {
- Filter cqlFilter;
- try {
- cqlFilter = ECQL.toFilter(filterString);
- } catch (final CQLException e) {
- logger.error("Error parsing query: " + filterString, e);
- throw new QueryEvaluationException(e);
- }
-
- final Query query = new Query(featureType.getTypeName(), cqlFilter);
- try {
- featureIterator = featureSource.getFeatures(query).features();
- } catch (final IOException e) {
- logger.error("Error performing query: " + filterString, e);
- throw new QueryEvaluationException(e);
- }
- }
- return featureIterator;
- }
-
- @Override
- public boolean hasNext() throws QueryEvaluationException {
- return getIterator().hasNext();
- }
-
- @Override
- public Statement next() throws QueryEvaluationException {
- final SimpleFeature feature = getIterator().next();
- final String subjectString = feature.getAttribute(SUBJECT_ATTRIBUTE).toString();
- final String predicateString = feature.getAttribute(PREDICATE_ATTRIBUTE).toString();
- final String objectString = feature.getAttribute(OBJECT_ATTRIBUTE).toString();
- final String contextString = feature.getAttribute(CONTEXT_ATTRIBUTE).toString();
- final Statement statement = StatementSerializer.readStatement(subjectString, predicateString, objectString, contextString);
- return statement;
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("Remove not implemented");
- }
-
- @Override
- public void close() throws QueryEvaluationException {
- getIterator().close();
- }
- };
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryEquals(final Geometry query, final StatementConstraints contraints) {
- return performQuery("EQUALS", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryDisjoint(final Geometry query, final StatementConstraints contraints) {
- return performQuery("DISJOINT", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryIntersects(final Geometry query, final StatementConstraints contraints) {
- return performQuery("INTERSECTS", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryTouches(final Geometry query, final StatementConstraints contraints) {
- return performQuery("TOUCHES", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryCrosses(final Geometry query, final StatementConstraints contraints) {
- return performQuery("CROSSES", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryWithin(final Geometry query, final StatementConstraints contraints) {
- return performQuery("WITHIN", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryContains(final Geometry query, final StatementConstraints contraints) {
- return performQuery("CONTAINS", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryOverlaps(final Geometry query, final StatementConstraints contraints) {
- return performQuery("OVERLAPS", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryNear(final NearQuery query,
- final StatementConstraints contraints) {
- throw new UnsupportedOperationException("Near queries are not supported in Accumulo.");
- }
-
- @Override
- public Set<URI> getIndexablePredicates() {
- return validPredicates;
- }
-
- @Override
- public void flush() throws IOException {
- // TODO cache and flush features instead of writing them one at a time
- }
-
- @Override
- public void close() throws IOException {
- flush();
- }
-
-
- @Override
- public String getTableName() {
- return getTableName(conf);
- }
-
- /**
- * Get the Accumulo table that will be used by this index.
- * @param conf
- * @return table name guaranteed to be used by instances of this index
- */
- public static String getTableName(final Configuration conf) {
- return makeTableName( ConfigUtils.getTablePrefix(conf) );
- }
-
- /**
- * Make the Accumulo table name used by this indexer for a specific instance of Rya.
- *
- * @param ryaInstanceName - The name of the Rya instance the table name is for. (not null)
- * @return The Accumulo table name used by this indexer for a specific instance of Rya.
- */
- public static String makeTableName(final String ryaInstanceName) {
- requireNonNull(ryaInstanceName);
- return ryaInstanceName + TABLE_SUFFIX;
- }
-
- private void deleteStatements(final Collection<RyaStatement> ryaStatements) throws IOException {
- // create a feature collection
- final DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
-
- for (final RyaStatement ryaStatement : ryaStatements) {
- final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
- // if the predicate list is empty, accept all predicates.
- // Otherwise, make sure the predicate is on the "valid" list
- final boolean isValidPredicate = validPredicates.isEmpty() || validPredicates.contains(statement.getPredicate());
-
- if (isValidPredicate && (statement.getObject() instanceof Literal)) {
- try {
- final SimpleFeature feature = createFeature(featureType, statement);
- featureCollection.add(feature);
- } catch (final ParseException e) {
- logger.warn("Error getting geo from statement: " + statement.toString(), e);
- }
- }
- }
-
- // remove this feature collection from the store
- if (!featureCollection.isEmpty()) {
- final Set<Identifier> featureIds = new HashSet<Identifier>();
- final FilterFactory filterFactory = CommonFactoryFinder.getFilterFactory(null);
- final Set<String> stringIds = DataUtilities.fidSet(featureCollection);
- for (final String id : stringIds) {
- featureIds.add(filterFactory.featureId(id));
- }
- final Filter filter = filterFactory.id(featureIds);
- featureStore.removeFeatures(filter);
- }
- }
-
-
- @Override
- public void deleteStatement(final RyaStatement statement) throws IOException {
- deleteStatements(Collections.singleton(statement));
- }
-
- @Override
- public void init() {
- }
-
- @Override
- public void setConnector(final Connector connector) {
- }
-
- @Override
- public void destroy() {
- }
-
- @Override
- public void purge(final RdfCloudTripleStoreConfiguration configuration) {
- }
-
- @Override
- public void dropAndDestroy() {
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoParseUtils.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoParseUtils.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoParseUtils.java
deleted file mode 100644
index 103b241..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoParseUtils.java
+++ /dev/null
@@ -1,148 +0,0 @@
-package org.apache.rya.indexing.accumulo.geo;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-/*
- * 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 org.apache.log4j.Logger;
-import org.apache.rya.indexing.GeoConstants;
-import org.geotools.gml3.GMLConfiguration;
-import org.geotools.xml.Parser;
-import org.openrdf.model.Literal;
-import org.openrdf.model.Statement;
-import org.openrdf.model.Value;
-import org.openrdf.query.algebra.FunctionCall;
-import org.openrdf.query.algebra.ValueConstant;
-import org.openrdf.query.algebra.ValueExpr;
-import org.openrdf.query.algebra.Var;
-import org.xml.sax.SAXException;
-
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.io.ParseException;
-import com.vividsolutions.jts.io.WKTReader;
-
-public class GeoParseUtils {
- static final Logger logger = Logger.getLogger(GeoParseUtils.class);
- /**
- * @deprecated Not needed since geo literals may be WKT or GML.
- *
- * This method warns on a condition that must already be tested. Replaced by
- * {@link #getLiteral(Statement)} and {@link #getGeometry(Statement}
- * and getLiteral(statement).toString()
- * and getLiteral(statement).getDatatype()
- */
- @Deprecated
- public static String getWellKnownText(final Statement statement) throws ParseException {
- final Literal lit = getLiteral(statement);
- if (!GeoConstants.XMLSCHEMA_OGC_WKT.equals(lit.getDatatype())) {
- logger.warn("Literal is not of type " + GeoConstants.XMLSCHEMA_OGC_WKT + ": " + statement.toString());
- }
- return lit.getLabel().toString();
- }
-
- public static Literal getLiteral(final Statement statement) throws ParseException {
- final org.openrdf.model.Value v = statement.getObject();
- if (!(v instanceof Literal)) {
- throw new ParseException("Statement does not contain Literal: " + statement.toString());
- }
- final Literal lit = (Literal) v;
- return lit;
- }
-
- /**
- * Parse GML/wkt literal to Geometry
- *
- * @param statement
- * @return
- * @throws ParseException
- * @throws ParserConfigurationException
- * @throws SAXException
- * @throws IOException
- */
- public static Geometry getGeometry(final Statement statement) throws ParseException {
- // handle GML or WKT
- final Literal lit = getLiteral(statement);
- if (GeoConstants.XMLSCHEMA_OGC_WKT.equals(lit.getDatatype())) {
- final String wkt = lit.getLabel().toString();
- return (new WKTReader()).read(wkt);
- } else if (GeoConstants.XMLSCHEMA_OGC_GML.equals(lit.getDatatype())) {
- final String gml = lit.getLabel().toString();
- try {
- return getGeometryGml(gml);
- } catch (IOException | SAXException | ParserConfigurationException e) {
- throw new ParseException(e);
- }
- } else {
- throw new ParseException("Literal is unknown geo type, expecting WKT or GML: " + statement.toString());
- }
- }
- /**
- * Convert GML/XML string into a geometry that can be indexed.
- * @param gmlString
- * @return
- * @throws IOException
- * @throws SAXException
- * @throws ParserConfigurationException
- */
- public static Geometry getGeometryGml(final String gmlString) throws IOException, SAXException, ParserConfigurationException {
- final Reader reader = new StringReader(gmlString);
- final GMLConfiguration gmlConfiguration = new GMLConfiguration();
- final Parser gmlParser = new Parser(gmlConfiguration);
- // gmlParser.setStrict(false); // attempt at allowing deprecated elements, but no.
- // gmlParser.setValidating(false);
- final Geometry geometry = (Geometry) gmlParser.parse(reader);
- // This sometimes gets populated with the SRS/CRS: geometry.getUserData()
- // Always returns 0 : geometry.getSRID()
- //TODO geometry.setUserData(some default CRS); OR geometry.setSRID(some default CRS)
-
- return geometry;
- }
-
- /**
- * Extracts the arguments used in a {@link FunctionCall}.
- * @param matchName - The variable name to match to arguments used in the {@link FunctionCall}.
- * @param call - The {@link FunctionCall} to match against.
- * @return - The {@link Value}s matched.
- */
- public static Object[] extractArguments(final String matchName, final FunctionCall call) {
- final Object[] args = new Object[call.getArgs().size() - 1];
- int argI = 0;
- for (int i = 0; i != call.getArgs().size(); ++i) {
- final ValueExpr arg = call.getArgs().get(i);
- if (argI == i && arg instanceof Var && matchName.equals(((Var)arg).getName())) {
- continue;
- }
- if (arg instanceof ValueConstant) {
- args[argI] = ((ValueConstant)arg).getValue();
- } else if (arg instanceof Var && ((Var)arg).hasValue()) {
- args[argI] = ((Var)arg).getValue();
- } else {
- args[argI] = arg;
- }
- ++argI;
- }
- return args;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoTupleSet.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoTupleSet.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoTupleSet.java
deleted file mode 100644
index 8cdeb5c..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoTupleSet.java
+++ /dev/null
@@ -1,499 +0,0 @@
-package org.apache.rya.indexing.accumulo.geo;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-import org.apache.commons.lang3.math.NumberUtils;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.rya.indexing.GeoConstants;
-import org.apache.rya.indexing.GeoIndexer;
-import org.apache.rya.indexing.IndexingExpr;
-import org.apache.rya.indexing.IteratorFactory;
-import org.apache.rya.indexing.SearchFunction;
-import org.apache.rya.indexing.StatementConstraints;
-import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
-import org.openrdf.model.Statement;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.query.BindingSet;
-import org.openrdf.query.QueryEvaluationException;
-import org.openrdf.query.algebra.Var;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.Maps;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.io.ParseException;
-import com.vividsolutions.jts.io.WKTReader;
-
-/*
- * 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 info.aduna.iteration.CloseableIteration;
-import joptsimple.internal.Strings;
-
-//Indexing Node for geo expressions to be inserted into execution plan
-//to delegate geo portion of query to geo index
-public class GeoTupleSet extends ExternalTupleSet {
- private static final String NEAR_DELIM = "::";
- private final Configuration conf;
- private final GeoIndexer geoIndexer;
- private final IndexingExpr filterInfo;
-
-
- public GeoTupleSet(final IndexingExpr filterInfo, final GeoIndexer geoIndexer) {
- this.filterInfo = filterInfo;
- this.geoIndexer = geoIndexer;
- conf = geoIndexer.getConf();
- }
-
- @Override
- public Set<String> getBindingNames() {
- return filterInfo.getBindingNames();
- }
-
- @Override
- public GeoTupleSet clone() {
- return new GeoTupleSet(filterInfo, geoIndexer);
- }
-
- @Override
- public double cardinality() {
- return 0.0; // No idea how the estimate cardinality here.
- }
-
-
- @Override
- public String getSignature() {
- return "(GeoTuple Projection) " + "variables: " + Joiner.on(", ").join(getBindingNames()).replaceAll("\\s+", " ");
- }
-
-
-
- @Override
- public boolean equals(final Object other) {
- if (other == this) {
- return true;
- }
- if (!(other instanceof GeoTupleSet)) {
- return false;
- }
- final GeoTupleSet arg = (GeoTupleSet) other;
- return filterInfo.equals(arg.filterInfo);
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31*result + filterInfo.hashCode();
-
- return result;
- }
-
-
-
- /**
- * Returns an iterator over the result set of the contained IndexingExpr.
- * <p>
- * Should be thread-safe (concurrent invocation {@link OfflineIterable} this
- * method can be expected with some query evaluators.
- */
- @Override
- public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(final BindingSet bindings)
- throws QueryEvaluationException {
-
- final URI funcURI = filterInfo.getFunction();
- final SearchFunction searchFunction = new GeoSearchFunctionFactory(conf, geoIndexer).getSearchFunction(funcURI);
-
- String queryText;
- Object arg = filterInfo.getArguments()[0];
- if (arg instanceof Value) {
- queryText = ((Value) arg).stringValue();
- } else if (arg instanceof Var) {
- queryText = bindings.getBinding(((Var) arg).getName()).getValue().stringValue();
- } else {
- throw new IllegalArgumentException("Query text was not resolved");
- }
-
- if(funcURI.equals(GeoConstants.GEO_SF_NEAR)) {
- if (filterInfo.getArguments().length > 3) {
- throw new IllegalArgumentException("Near functions do not support more than four arguments.");
- }
-
- final List<String> valueList = new ArrayList<>();
- for (final Object val : filterInfo.getArguments()) {
- if (val instanceof Value) {
- valueList.add(((Value)val).stringValue());
- } else if (val instanceof Var) {
- valueList.add(bindings.getBinding(((Var) val).getName()).getValue().stringValue());
- } else {
- throw new IllegalArgumentException("Query text was not resolved");
- }
- }
- queryText = Strings.join(valueList, NEAR_DELIM);
- } else if (filterInfo.getArguments().length > 1) {
- throw new IllegalArgumentException("Index functions do not support more than two arguments.");
- }
-
- try {
- final CloseableIteration<BindingSet, QueryEvaluationException> iterrez = IteratorFactory
- .getIterator(filterInfo.getSpConstraint(), bindings,
- queryText, searchFunction);
- return iterrez;
- } catch (final Exception e) {
- System.out.println(e.getMessage());
- throw e;
- }
- }
-
- //returns appropriate search function for a given URI
- //search functions used in GeoMesaGeoIndexer to access index
- public static class GeoSearchFunctionFactory {
-
- Configuration conf;
-
- private final Map<URI, SearchFunction> SEARCH_FUNCTION_MAP = Maps.newHashMap();
-
- private final GeoIndexer geoIndexer;
-
- public GeoSearchFunctionFactory(final Configuration conf, final GeoIndexer geoIndexer) {
- this.conf = conf;
- this.geoIndexer = geoIndexer;
- }
-
-
- /**
- * Get a {@link GeoSearchFunction} for a given URI.
- *
- * @param searchFunction
- * @return
- */
- public SearchFunction getSearchFunction(final URI searchFunction) {
-
- SearchFunction geoFunc = null;
-
- try {
- geoFunc = getSearchFunctionInternal(searchFunction);
- } catch (final QueryEvaluationException e) {
- e.printStackTrace();
- }
-
- return geoFunc;
- }
-
- private SearchFunction getSearchFunctionInternal(final URI searchFunction) throws QueryEvaluationException {
- final SearchFunction sf = SEARCH_FUNCTION_MAP.get(searchFunction);
-
- if (sf != null) {
- return sf;
- } else {
- throw new QueryEvaluationException("Unknown Search Function: " + searchFunction.stringValue());
- }
- }
-
- private final SearchFunction GEO_EQUALS = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
- final StatementConstraints contraints) throws QueryEvaluationException {
- try {
- final WKTReader reader = new WKTReader();
- final Geometry geometry = reader.read(queryText);
- final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryEquals(
- geometry, contraints);
- return statements;
- } catch (final ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_EQUALS";
- };
- };
-
- private final SearchFunction GEO_DISJOINT = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
- final StatementConstraints contraints) throws QueryEvaluationException {
- try {
- final WKTReader reader = new WKTReader();
- final Geometry geometry = reader.read(queryText);
- final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryDisjoint(
- geometry, contraints);
- return statements;
- } catch (final ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_DISJOINT";
- };
- };
-
- private final SearchFunction GEO_INTERSECTS = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
- final StatementConstraints contraints) throws QueryEvaluationException {
- try {
- final WKTReader reader = new WKTReader();
- final Geometry geometry = reader.read(queryText);
- final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryIntersects(
- geometry, contraints);
- return statements;
- } catch (final ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_INTERSECTS";
- };
- };
-
- private final SearchFunction GEO_TOUCHES = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
- final StatementConstraints contraints) throws QueryEvaluationException {
- try {
- final WKTReader reader = new WKTReader();
- final Geometry geometry = reader.read(queryText);
- final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryTouches(
- geometry, contraints);
- return statements;
- } catch (final ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_TOUCHES";
- };
- };
-
- private final SearchFunction GEO_CONTAINS = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
- final StatementConstraints contraints) throws QueryEvaluationException {
- try {
- final WKTReader reader = new WKTReader();
- final Geometry geometry = reader.read(queryText);
- final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryContains(
- geometry, contraints);
- return statements;
- } catch (final ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_CONTAINS";
- };
- };
-
- private final SearchFunction GEO_OVERLAPS = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
- final StatementConstraints contraints) throws QueryEvaluationException {
- try {
- final WKTReader reader = new WKTReader();
- final Geometry geometry = reader.read(queryText);
- final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryOverlaps(
- geometry, contraints);
- return statements;
- } catch (final ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_OVERLAPS";
- };
- };
-
- private final SearchFunction GEO_CROSSES = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
- final StatementConstraints contraints) throws QueryEvaluationException {
- try {
- final WKTReader reader = new WKTReader();
- final Geometry geometry = reader.read(queryText);
- final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryCrosses(
- geometry, contraints);
- return statements;
- } catch (final ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_CROSSES";
- };
- };
-
- private final SearchFunction GEO_WITHIN = new SearchFunction() {
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
- final StatementConstraints contraints) throws QueryEvaluationException {
- try {
- final WKTReader reader = new WKTReader();
- final Geometry geometry = reader.read(queryText);
- final CloseableIteration<Statement, QueryEvaluationException> statements = geoIndexer.queryWithin(
- geometry, contraints);
- return statements;
- } catch (final ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- @Override
- public String toString() {
- return "GEO_WITHIN";
- };
- };
-
- private final SearchFunction GEO_NEAR = new SearchFunction() {
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String queryText,
- final StatementConstraints contraints) throws QueryEvaluationException {
- try {
- final String[] args = queryText.split(NEAR_DELIM);
- Optional<Double> maxDistanceOpt = Optional.empty();
- Optional<Double> minDistanceOpt = Optional.empty();
- final String query = args[0];
-
- for (int ii = 1; ii < args.length; ii++) {
- String numArg = args[ii];
-
- // remove pre-padding 0's since NumberUtils.isNumber()
- // will assume its octal if it starts with a 0.
- while (numArg.startsWith("0")) {
- numArg = numArg.substring(1);
- }
- // was 0
- if (numArg.equals("")) {
- // if max hasn't been set, set it to 0.
- // Otherwise, min is just ignored.
- if (!maxDistanceOpt.isPresent()) {
- maxDistanceOpt = Optional.of(0.0);
- }
- } else {
- if (!maxDistanceOpt.isPresent() && NumberUtils.isNumber(numArg)) {
- // no variable identifier, going by order.
- maxDistanceOpt = getDistanceOpt(numArg, "maxDistance");
- } else if (NumberUtils.isNumber(numArg)) {
- // no variable identifier, going by order.
- minDistanceOpt = getDistanceOpt(numArg, "minDistance");
- } else {
- throw new IllegalArgumentException(numArg + " is not a valid Near function argument.");
- }
- }
- }
- final WKTReader reader = new WKTReader();
- final Geometry geometry = reader.read(query);
- final NearQuery nearQuery = new NearQuery(maxDistanceOpt, minDistanceOpt, geometry);
- return geoIndexer.queryNear(nearQuery, contraints);
- } catch (final ParseException e) {
- throw new QueryEvaluationException(e);
- }
- }
-
- private Optional<Double> getDistanceOpt(final String num, final String name) {
- try {
- double dist = Double.parseDouble(num);
- if(dist < 0) {
- throw new IllegalArgumentException("Value for: " + name + " must be non-negative.");
- }
- return Optional.of(Double.parseDouble(num));
- } catch (final NumberFormatException nfe) {
- throw new IllegalArgumentException("Value for: " + name + " must be a number.");
- }
- }
-
- @Override
- public String toString() {
- return "GEO_NEAR";
- }
- };
-
- /**
- *
- */
- public class NearQuery {
- private final Optional<Double> maxDistanceOpt;
- private final Optional<Double> minDistanceOpt;
- private final Geometry geo;
-
- /**
- *
- * @param maxDistance
- * @param minDistance
- * @param geo
- */
- public NearQuery(final Optional<Double> maxDistance, final Optional<Double> minDistance,
- final Geometry geo) {
- maxDistanceOpt = maxDistance;
- minDistanceOpt = minDistance;
- this.geo = geo;
- }
-
- public Optional<Double> getMaxDistance() {
- return maxDistanceOpt;
- }
-
- public Optional<Double> getMinDistance() {
- return minDistanceOpt;
- }
-
- public Geometry getGeometry() {
- return geo;
- }
- }
-
- {
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_EQUALS, GEO_EQUALS);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_DISJOINT, GEO_DISJOINT);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_INTERSECTS, GEO_INTERSECTS);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_TOUCHES, GEO_TOUCHES);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_CONTAINS, GEO_CONTAINS);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_OVERLAPS, GEO_OVERLAPS);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_CROSSES, GEO_CROSSES);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_WITHIN, GEO_WITHIN);
- SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_NEAR, GEO_NEAR);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGeoIndexer.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGeoIndexer.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGeoIndexer.java
deleted file mode 100644
index 45a23f9..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/accumulo/geo/GeoWaveGeoIndexer.java
+++ /dev/null
@@ -1,668 +0,0 @@
-/*
- * 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 com.google.common.base.Preconditions.checkNotNull;
-import static java.util.Objects.requireNonNull;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.apache.accumulo.core.client.Connector;
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.mock.MockInstance;
-import org.apache.commons.lang.StringUtils;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.log4j.Logger;
-import org.apache.rya.accumulo.experimental.AbstractAccumuloIndexer;
-import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
-import org.apache.rya.api.domain.RyaStatement;
-import org.apache.rya.api.resolver.RyaToRdfConversions;
-import org.apache.rya.indexing.GeoIndexer;
-import org.apache.rya.indexing.Md5Hash;
-import org.apache.rya.indexing.StatementConstraints;
-import org.apache.rya.indexing.StatementSerializer;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.accumulo.geo.GeoTupleSet.GeoSearchFunctionFactory.NearQuery;
-import org.geotools.data.DataStore;
-import org.geotools.data.DataUtilities;
-import org.geotools.data.FeatureSource;
-import org.geotools.data.FeatureStore;
-import org.geotools.factory.CommonFactoryFinder;
-import org.geotools.factory.Hints;
-import org.geotools.feature.DefaultFeatureCollection;
-import org.geotools.feature.SchemaException;
-import org.geotools.feature.simple.SimpleFeatureBuilder;
-import org.geotools.filter.text.cql2.CQLException;
-import org.geotools.filter.text.ecql.ECQL;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.feature.simple.SimpleFeatureType;
-import org.opengis.filter.Filter;
-import org.opengis.filter.FilterFactory;
-import org.opengis.filter.identity.Identifier;
-import org.openrdf.model.Literal;
-import org.openrdf.model.Statement;
-import org.openrdf.model.URI;
-import org.openrdf.query.QueryEvaluationException;
-
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.io.ParseException;
-
-import info.aduna.iteration.CloseableIteration;
-import mil.nga.giat.geowave.adapter.vector.FeatureDataAdapter;
-import mil.nga.giat.geowave.adapter.vector.plugin.GeoWaveGTDataStore;
-import mil.nga.giat.geowave.adapter.vector.plugin.GeoWaveGTDataStoreFactory;
-import mil.nga.giat.geowave.adapter.vector.plugin.GeoWavePluginException;
-import mil.nga.giat.geowave.adapter.vector.query.cql.CQLQuery;
-import mil.nga.giat.geowave.core.geotime.ingest.SpatialDimensionalityTypeProvider;
-import mil.nga.giat.geowave.core.store.CloseableIterator;
-import mil.nga.giat.geowave.core.store.StoreFactoryFamilySpi;
-import mil.nga.giat.geowave.core.store.index.PrimaryIndex;
-import mil.nga.giat.geowave.core.store.memory.MemoryStoreFactoryFamily;
-import mil.nga.giat.geowave.core.store.query.EverythingQuery;
-import mil.nga.giat.geowave.core.store.query.QueryOptions;
-import mil.nga.giat.geowave.datastore.accumulo.AccumuloDataStore;
-import mil.nga.giat.geowave.datastore.accumulo.AccumuloStoreFactoryFamily;
-
-/**
- * A {@link GeoIndexer} wrapper around a GeoWave {@link AccumuloDataStore}. This class configures and connects to the Datastore, creates the
- * RDF Feature Type, and interacts with the Datastore.
- * <p>
- * Specifically, this class creates a RDF Feature type and stores each RDF Statement as a RDF Feature in the datastore. Each feature
- * contains the standard set of GeoWave attributes (Geometry, Start Date, and End Date). The GeoWaveGeoIndexer populates the Geometry
- * attribute by parsing the Well-Known Text contained in the RDF Statement’s object literal value.
- * <p>
- * The RDF Feature contains four additional attributes for each component of the RDF Statement. These attributes are:
- * <p>
- * <table border="1">
- * <tr>
- * <th>Name</th>
- * <th>Symbol</th>
- * <th>Type</th>
- * </tr>
- * <tr>
- * <td>Subject Attribute</td>
- * <td>S</td>
- * <td>String</td>
- * </tr>
- * </tr>
- * <tr>
- * <td>Predicate Attribute</td>
- * <td>P</td>
- * <td>String</td>
- * </tr>
- * </tr>
- * <tr>
- * <td>Object Attribute</td>
- * <td>O</td>
- * <td>String</td>
- * </tr>
- * </tr>
- * <tr>
- * <td>Context Attribute</td>
- * <td>C</td>
- * <td>String</td>
- * </tr>
- * </table>
- */
-public class GeoWaveGeoIndexer extends AbstractAccumuloIndexer implements GeoIndexer {
-
- private static final String TABLE_SUFFIX = "geo";
-
- private static final Logger logger = Logger.getLogger(GeoWaveGeoIndexer.class);
-
- private static final String FEATURE_NAME = "RDF";
-
- private static final String SUBJECT_ATTRIBUTE = "S";
- private static final String PREDICATE_ATTRIBUTE = "P";
- private static final String OBJECT_ATTRIBUTE = "O";
- private static final String CONTEXT_ATTRIBUTE = "C";
- private static final String GEO_ID_ATTRIBUTE = "geo_id";
- private static final String GEOMETRY_ATTRIBUTE = "geowave_index_geometry";
-
- private Set<URI> validPredicates;
- private Configuration conf;
- private FeatureStore<SimpleFeatureType, SimpleFeature> featureStore;
- private FeatureSource<SimpleFeatureType, SimpleFeature> featureSource;
- private SimpleFeatureType featureType;
- private FeatureDataAdapter featureDataAdapter;
- private DataStore geoToolsDataStore;
- private mil.nga.giat.geowave.core.store.DataStore geoWaveDataStore;
- private final PrimaryIndex index = new SpatialDimensionalityTypeProvider().createPrimaryIndex();
- private boolean isInit = false;
-
- //initialization occurs in setConf because index is created using reflection
- @Override
- public void setConf(final Configuration conf) {
- this.conf = conf;
- if (!isInit) {
- try {
- initInternal();
- isInit = true;
- } catch (final IOException e) {
- logger.warn("Unable to initialize index. Throwing Runtime Exception. ", e);
- throw new RuntimeException(e);
- }
- }
- }
-
- @Override
- public Configuration getConf() {
- return conf;
- }
-
- /**
- * @return the internal GeoTools{@link DataStore} used by the {@link GeoWaveGeoIndexer}.
- */
- public DataStore getGeoToolsDataStore() {
- return geoToolsDataStore;
- }
-
- /**
- * @return the internal GeoWave {@link DataStore} used by the {@link GeoWaveGeoIndexer}.
- */
- public mil.nga.giat.geowave.core.store.DataStore getGeoWaveDataStore() {
- return geoWaveDataStore;
- }
-
- private void initInternal() throws IOException {
- validPredicates = ConfigUtils.getGeoPredicates(conf);
-
- try {
- geoToolsDataStore = createDataStore(conf);
- geoWaveDataStore = ((GeoWaveGTDataStore) geoToolsDataStore).getDataStore();
- } catch (final GeoWavePluginException e) {
- logger.error("Failed to create GeoWave data store", e);
- }
-
- try {
- featureType = getStatementFeatureType(geoToolsDataStore);
- } catch (final IOException | SchemaException e) {
- throw new IOException(e);
- }
-
- featureDataAdapter = new FeatureDataAdapter(featureType);
-
- featureSource = geoToolsDataStore.getFeatureSource(featureType.getName());
- if (!(featureSource instanceof FeatureStore)) {
- throw new IllegalStateException("Could not retrieve feature store");
- }
- featureStore = (FeatureStore<SimpleFeatureType, SimpleFeature>) featureSource;
- }
-
- public Map<String, Serializable> getParams(final Configuration conf) {
- // get the configuration parameters
- final Instance instance = ConfigUtils.getInstance(conf);
- final String instanceId = instance.getInstanceName();
- final String zookeepers = instance.getZooKeepers();
- final String user = ConfigUtils.getUsername(conf);
- final String password = ConfigUtils.getPassword(conf);
- final String auths = ConfigUtils.getAuthorizations(conf).toString();
- final String tableName = getTableName(conf);
- final String tablePrefix = ConfigUtils.getTablePrefix(conf);
-
- final Map<String, Serializable> params = new HashMap<>();
- params.put("zookeeper", zookeepers);
- params.put("instance", instanceId);
- params.put("user", user);
- params.put("password", password);
- params.put("namespace", tableName);
- params.put("gwNamespace", tablePrefix + getClass().getSimpleName());
-
- params.put("Lock Management", LockManagementType.MEMORY.toString());
- params.put("Authorization Management Provider", AuthorizationManagementProviderType.EMPTY.toString());
- params.put("Authorization Data URL", null);
- params.put("Transaction Buffer Size", 10000);
- params.put("Query Index Strategy", QueryIndexStrategyType.HEURISTIC_MATCH.toString());
- return params;
- }
-
- /**
- * Creates the {@link DataStore} for the {@link GeoWaveGeoIndexer}.
- * @param conf the {@link Configuration}.
- * @return the {@link DataStore}.
- */
- public DataStore createDataStore(final Configuration conf) throws IOException, GeoWavePluginException {
- final Map<String, Serializable> params = getParams(conf);
- final Instance instance = ConfigUtils.getInstance(conf);
- final boolean useMock = instance instanceof MockInstance;
-
- final StoreFactoryFamilySpi storeFactoryFamily;
- if (useMock) {
- storeFactoryFamily = new MemoryStoreFactoryFamily();
- } else {
- storeFactoryFamily = new AccumuloStoreFactoryFamily();
- }
-
- final GeoWaveGTDataStoreFactory geoWaveGTDataStoreFactory = new GeoWaveGTDataStoreFactory(storeFactoryFamily);
- final DataStore dataStore = geoWaveGTDataStoreFactory.createNewDataStore(params);
-
- return dataStore;
- }
-
- private static SimpleFeatureType getStatementFeatureType(final DataStore dataStore) throws IOException, SchemaException {
- SimpleFeatureType featureType;
-
- final String[] datastoreFeatures = dataStore.getTypeNames();
- if (Arrays.asList(datastoreFeatures).contains(FEATURE_NAME)) {
- featureType = dataStore.getSchema(FEATURE_NAME);
- } else {
- featureType = DataUtilities.createType(FEATURE_NAME,
- SUBJECT_ATTRIBUTE + ":String," +
- PREDICATE_ATTRIBUTE + ":String," +
- OBJECT_ATTRIBUTE + ":String," +
- CONTEXT_ATTRIBUTE + ":String," +
- GEOMETRY_ATTRIBUTE + ":Geometry:srid=4326," +
- GEO_ID_ATTRIBUTE + ":String");
-
- dataStore.createSchema(featureType);
- }
- return featureType;
- }
-
- @Override
- public void storeStatements(final Collection<RyaStatement> ryaStatements) throws IOException {
- // create a feature collection
- final DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
- for (final RyaStatement ryaStatement : ryaStatements) {
- final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
- // if the predicate list is empty, accept all predicates.
- // Otherwise, make sure the predicate is on the "valid" list
- final boolean isValidPredicate = validPredicates.isEmpty() || validPredicates.contains(statement.getPredicate());
-
- if (isValidPredicate && (statement.getObject() instanceof Literal)) {
- try {
- final SimpleFeature feature = createFeature(featureType, statement);
- featureCollection.add(feature);
- } catch (final ParseException e) {
- logger.warn("Error getting geo from statement: " + statement.toString(), e);
- }
- }
- }
-
- // write this feature collection to the store
- if (!featureCollection.isEmpty()) {
- featureStore.addFeatures(featureCollection);
- }
- }
-
- @Override
- public void storeStatement(final RyaStatement statement) throws IOException {
- storeStatements(Collections.singleton(statement));
- }
-
- private static SimpleFeature createFeature(final SimpleFeatureType featureType, final Statement statement) throws ParseException {
- final String subject = StatementSerializer.writeSubject(statement);
- final String predicate = StatementSerializer.writePredicate(statement);
- final String object = StatementSerializer.writeObject(statement);
- final String context = StatementSerializer.writeContext(statement);
-
- // create the feature
- final Object[] noValues = {};
-
- // create the hash
- final String statementId = Md5Hash.md5Base64(StatementSerializer.writeStatement(statement));
- final SimpleFeature newFeature = SimpleFeatureBuilder.build(featureType, noValues, statementId);
-
- // write the statement data to the fields
- final Geometry geom = GeoParseUtils.getGeometry(statement);
- if(geom == null || geom.isEmpty() || !geom.isValid()) {
- throw new ParseException("Could not create geometry for statement " + statement);
- }
- newFeature.setDefaultGeometry(geom);
-
- newFeature.setAttribute(SUBJECT_ATTRIBUTE, subject);
- newFeature.setAttribute(PREDICATE_ATTRIBUTE, predicate);
- newFeature.setAttribute(OBJECT_ATTRIBUTE, object);
- newFeature.setAttribute(CONTEXT_ATTRIBUTE, context);
- // GeoWave does not support querying based on a user generated feature ID
- // So, we create a separate ID attribute that it can query on.
- newFeature.setAttribute(GEO_ID_ATTRIBUTE, statementId);
-
- // preserve the ID that we created for this feature
- // (set the hint to FALSE to have GeoTools generate IDs)
- newFeature.getUserData().put(Hints.USE_PROVIDED_FID, java.lang.Boolean.TRUE);
-
- return newFeature;
- }
-
- private CloseableIteration<Statement, QueryEvaluationException> performQuery(final String type, final Geometry geometry,
- final StatementConstraints contraints) {
- final List<String> filterParms = new ArrayList<String>();
-
- filterParms.add(type + "(" + GEOMETRY_ATTRIBUTE + ", " + geometry + " )");
-
- if (contraints.hasSubject()) {
- filterParms.add("( " + SUBJECT_ATTRIBUTE + "= '" + contraints.getSubject() + "') ");
- }
- if (contraints.hasContext()) {
- filterParms.add("( " + CONTEXT_ATTRIBUTE + "= '" + contraints.getContext() + "') ");
- }
- if (contraints.hasPredicates()) {
- final List<String> predicates = new ArrayList<String>();
- for (final URI u : contraints.getPredicates()) {
- predicates.add("( " + PREDICATE_ATTRIBUTE + "= '" + u.stringValue() + "') ");
- }
- filterParms.add("(" + StringUtils.join(predicates, " OR ") + ")");
- }
-
- final String filterString = StringUtils.join(filterParms, " AND ");
- logger.info("Performing geowave query : " + filterString);
-
- return getIteratorWrapper(filterString);
- }
-
- private CloseableIteration<Statement, QueryEvaluationException> getIteratorWrapper(final String filterString) {
-
- return new CloseableIteration<Statement, QueryEvaluationException>() {
-
- private CloseableIterator<SimpleFeature> featureIterator = null;
-
- CloseableIterator<SimpleFeature> getIterator() throws QueryEvaluationException {
- if (featureIterator == null) {
- Filter cqlFilter;
- try {
- cqlFilter = ECQL.toFilter(filterString);
- } catch (final CQLException e) {
- logger.error("Error parsing query: " + filterString, e);
- throw new QueryEvaluationException(e);
- }
-
- final CQLQuery cqlQuery = new CQLQuery(null, cqlFilter, featureDataAdapter);
- final QueryOptions queryOptions = new QueryOptions(featureDataAdapter, index);
-
- try {
- featureIterator = geoWaveDataStore.query(queryOptions, cqlQuery);
- } catch (final Exception e) {
- logger.error("Error performing query: " + filterString, e);
- throw new QueryEvaluationException(e);
- }
- }
- return featureIterator;
- }
-
- @Override
- public boolean hasNext() throws QueryEvaluationException {
- return getIterator().hasNext();
- }
-
- @Override
- public Statement next() throws QueryEvaluationException {
- final SimpleFeature feature = getIterator().next();
- final String subjectString = feature.getAttribute(SUBJECT_ATTRIBUTE).toString();
- final String predicateString = feature.getAttribute(PREDICATE_ATTRIBUTE).toString();
- final String objectString = feature.getAttribute(OBJECT_ATTRIBUTE).toString();
- final Object context = feature.getAttribute(CONTEXT_ATTRIBUTE);
- final String contextString = context != null ? context.toString() : "";
- final Statement statement = StatementSerializer.readStatement(subjectString, predicateString, objectString, contextString);
- return statement;
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("Remove not implemented");
- }
-
- @Override
- public void close() throws QueryEvaluationException {
- try {
- getIterator().close();
- } catch (final IOException e) {
- throw new QueryEvaluationException(e);
- }
- }
- };
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryEquals(final Geometry query, final StatementConstraints contraints) {
- return performQuery("EQUALS", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryDisjoint(final Geometry query, final StatementConstraints contraints) {
- return performQuery("DISJOINT", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryIntersects(final Geometry query, final StatementConstraints contraints) {
- return performQuery("INTERSECTS", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryTouches(final Geometry query, final StatementConstraints contraints) {
- return performQuery("TOUCHES", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryCrosses(final Geometry query, final StatementConstraints contraints) {
- return performQuery("CROSSES", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryWithin(final Geometry query, final StatementConstraints contraints) {
- return performQuery("WITHIN", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryContains(final Geometry query, final StatementConstraints contraints) {
- return performQuery("CONTAINS", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryOverlaps(final Geometry query, final StatementConstraints contraints) {
- return performQuery("OVERLAPS", query, contraints);
- }
-
- @Override
- public CloseableIteration<Statement, QueryEvaluationException> queryNear(final NearQuery query,
- final StatementConstraints contraints) {
- throw new UnsupportedOperationException("Near queries are not supported in Accumulo.");
- }
-
- @Override
- public Set<URI> getIndexablePredicates() {
- return validPredicates;
- }
-
- @Override
- public void flush() throws IOException {
- // TODO cache and flush features instead of writing them one at a time
- }
-
- @Override
- public void close() throws IOException {
- flush();
- }
-
-
- @Override
- public String getTableName() {
- return getTableName(conf);
- }
-
- /**
- * Get the Accumulo table that will be used by this index.
- * @param conf
- * @return table name guaranteed to be used by instances of this index
- */
- public static String getTableName(final Configuration conf) {
- return makeTableName( ConfigUtils.getTablePrefix(conf) );
- }
-
- /**
- * Make the Accumulo table name used by this indexer for a specific instance of Rya.
- *
- * @param ryaInstanceName - The name of the Rya instance the table name is for. (not null)
- * @return The Accumulo table name used by this indexer for a specific instance of Rya.
- */
- public static String makeTableName(final String ryaInstanceName) {
- requireNonNull(ryaInstanceName);
- return ryaInstanceName + TABLE_SUFFIX;
- }
-
- private void deleteStatements(final Collection<RyaStatement> ryaStatements) throws IOException {
- // create a feature collection
- final DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
-
- for (final RyaStatement ryaStatement : ryaStatements) {
- final Statement statement = RyaToRdfConversions.convertStatement(ryaStatement);
- // if the predicate list is empty, accept all predicates.
- // Otherwise, make sure the predicate is on the "valid" list
- final boolean isValidPredicate = validPredicates.isEmpty() || validPredicates.contains(statement.getPredicate());
-
- if (isValidPredicate && (statement.getObject() instanceof Literal)) {
- try {
- final SimpleFeature feature = createFeature(featureType, statement);
- featureCollection.add(feature);
- } catch (final ParseException e) {
- logger.warn("Error getting geo from statement: " + statement.toString(), e);
- }
- }
- }
-
- // remove this feature collection from the store
- if (!featureCollection.isEmpty()) {
- final Set<Identifier> featureIds = new HashSet<Identifier>();
- final FilterFactory filterFactory = CommonFactoryFinder.getFilterFactory(null);
- final Set<String> stringIds = DataUtilities.fidSet(featureCollection);
- for (final String id : stringIds) {
- featureIds.add(filterFactory.featureId(id));
- }
-
- final String filterString = stringIds.stream().collect(Collectors.joining("','", "'", "'"));
-
- Filter filter = null;
- try {
- filter = ECQL.toFilter(GEO_ID_ATTRIBUTE + " IN (" + filterString + ")", filterFactory);
- } catch (final CQLException e) {
- logger.error("Unable to generate filter for deleting the statement.", e);
- }
-
- featureStore.removeFeatures(filter);
- }
- }
-
-
- @Override
- public void deleteStatement(final RyaStatement statement) throws IOException {
- deleteStatements(Collections.singleton(statement));
- }
-
- @Override
- public void init() {
- }
-
- @Override
- public void setConnector(final Connector connector) {
- }
-
- @Override
- public void destroy() {
- }
-
- @Override
- public void purge(final RdfCloudTripleStoreConfiguration configuration) {
- // delete existing data
- geoWaveDataStore.delete(new QueryOptions(), new EverythingQuery());
- }
-
- @Override
- public void dropAndDestroy() {
- }
-
- /**
- * The list of supported Geo Wave {@code LockingManagementFactory} types.
- */
- private static enum LockManagementType {
- MEMORY("memory");
-
- private final String name;
-
- /**
- * Creates a new {@link LockManagementType}.
- * @param name the name of the type. (not {@code null})
- */
- private LockManagementType(final String name) {
- this.name = checkNotNull(name);
- }
-
- @Override
- public String toString() {
- return name;
- }
- }
-
- /**
- * The list of supported Geo Wave {@code AuthorizationFactorySPI } types.
- */
- private static enum AuthorizationManagementProviderType {
- EMPTY("empty"),
- JSON_FILE("jsonFile");
-
- private final String name;
-
- /**
- * Creates a new {@link AuthorizationManagementProviderType}.
- * @param name the name of the type. (not {@code null})
- */
- private AuthorizationManagementProviderType(final String name) {
- this.name = checkNotNull(name);
- }
-
- @Override
- public String toString() {
- return name;
- }
- }
-
- /**
- * The list of supported Geo Wave {@code IndexQueryStrategySPI} types.
- */
- private static enum QueryIndexStrategyType {
- BEST_MATCH("Best Match"),
- HEURISTIC_MATCH("Heuristic Match"),
- PRESERVE_LOCALITY("Preserve Locality");
-
- private final String name;
-
- /**
- * Creates a new {@link QueryIndexStrategyType}.
- * @param name the name of the type. (not {@code null})
- */
- private QueryIndexStrategyType(final String name) {
- this.name = checkNotNull(name);
- }
-
- @Override
- public String toString() {
- return name;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalExternalSetMatcherFactory.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalExternalSetMatcherFactory.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalExternalSetMatcherFactory.java
deleted file mode 100644
index c4a287e..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalExternalSetMatcherFactory.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * 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.geotemporal;
-
-import org.apache.rya.indexing.external.matching.AbstractExternalSetMatcherFactory;
-import org.apache.rya.indexing.external.matching.ExternalSetMatcher;
-import org.apache.rya.indexing.external.matching.JoinSegment;
-import org.apache.rya.indexing.external.matching.JoinSegmentMatcher;
-import org.apache.rya.indexing.external.matching.OptionalJoinSegment;
-import org.apache.rya.indexing.external.matching.OptionalJoinSegmentMatcher;
-import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
-
-/**
- * Factory used to build {@link EntityQueryNodeMatcher}s for the {@link GeoTemporalIndexOptimizer}.
- *
- */
-public class GeoTemporalExternalSetMatcherFactory extends AbstractExternalSetMatcherFactory<EventQueryNode> {
-
- @Override
- protected ExternalSetMatcher<EventQueryNode> getJoinSegmentMatcher(final JoinSegment<EventQueryNode> segment) {
- return new JoinSegmentMatcher<EventQueryNode>(segment, new GeoTemporalToSegmentConverter());
- }
-
- @Override
- protected ExternalSetMatcher<EventQueryNode> getOptionalJoinSegmentMatcher(final OptionalJoinSegment<EventQueryNode> segment) {
- return new OptionalJoinSegmentMatcher<EventQueryNode>(segment, new GeoTemporalToSegmentConverter());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e76b8d7/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexException.java
----------------------------------------------------------------------
diff --git a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexException.java b/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexException.java
deleted file mode 100644
index b2d4de5..0000000
--- a/extras/rya.geoindexing/src/main/java/org/apache/rya/indexing/geotemporal/GeoTemporalIndexException.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * 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.geotemporal;
-
-import org.apache.rya.indexing.entity.model.TypedEntity;
-
-/**
- * An operation over the {@link TypedEntity} index failed to complete.
- */
-public class GeoTemporalIndexException extends Exception {
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructs a new exception with the specified detail message. The
- * cause is not initialized, and may subsequently be initialized by
- * a call to {@link #initCause}.
- *
- * @param message the detail message. The detail message is saved for
- * later retrieval by the {@link #getMessage()} method.
- */
- public GeoTemporalIndexException(final String message) {
- super(message);
- }
-
- /**
- * Constructs a new exception with the specified detail message and
- * cause. <p>Note that the detail message associated with
- * {@code cause} is <i>not</i> automatically incorporated in
- * this exception's detail message.
- *
- * @param message the detail message (which is saved for later retrieval
- * by the {@link #getMessage()} method).
- * @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method). (A <tt>null</tt> value is
- * permitted, and indicates that the cause is nonexistent or
- * unknown.)
- */
- public GeoTemporalIndexException(final String message, final Throwable cause) {
- super(message, cause);
- }
-}
\ No newline at end of file