| 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.eclipse.rdf4j.query.BindingSet; |
| import org.eclipse.rdf4j.query.MalformedQueryException; |
| import org.eclipse.rdf4j.query.QueryEvaluationException; |
| import org.eclipse.rdf4j.query.QueryLanguage; |
| import org.eclipse.rdf4j.query.QueryResultHandlerException; |
| import org.eclipse.rdf4j.query.TupleQuery; |
| import org.eclipse.rdf4j.query.TupleQueryResultHandler; |
| import org.eclipse.rdf4j.query.TupleQueryResultHandlerException; |
| import org.eclipse.rdf4j.query.Update; |
| import org.eclipse.rdf4j.query.UpdateExecutionException; |
| import org.eclipse.rdf4j.repository.RepositoryException; |
| import org.eclipse.rdf4j.repository.sail.SailRepository; |
| import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; |
| import org.eclipse.rdf4j.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 { |
| } |
| } |
| } |