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>

Reply via email to