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