| /* |
| * 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.mongo; |
| |
| import static org.junit.Assert.assertEquals; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| 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.GeoRyaSailFactory; |
| import org.apache.rya.indexing.accumulo.ConfigUtils; |
| import org.apache.rya.indexing.accumulo.geo.OptionalConfigUtils; |
| import org.apache.rya.mongodb.MongoDBRdfConfiguration; |
| import org.apache.rya.mongodb.MongoRyaITBase; |
| import org.eclipse.rdf4j.model.IRI; |
| import org.eclipse.rdf4j.model.Resource; |
| import org.eclipse.rdf4j.model.Statement; |
| import org.eclipse.rdf4j.model.Value; |
| import org.eclipse.rdf4j.model.ValueFactory; |
| import org.eclipse.rdf4j.model.impl.SimpleValueFactory; |
| 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.TupleQueryResult; |
| import org.eclipse.rdf4j.repository.sail.SailRepository; |
| import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; |
| import org.eclipse.rdf4j.sail.Sail; |
| 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.io.ParseException; |
| import com.vividsolutions.jts.io.WKTReader; |
| import com.vividsolutions.jts.io.WKTWriter; |
| |
| public class MongoGeoIndexerFilterIT extends MongoRyaITBase { |
| private static final GeometryFactory GF = new GeometryFactory(); |
| private static final Geometry WASHINGTON_MONUMENT = GF.createPoint(new Coordinate(38.8895, 77.0353)); |
| private static final Geometry LINCOLN_MEMORIAL = GF.createPoint(new Coordinate(38.8893, 77.0502)); |
| private static final Geometry CAPITAL_BUILDING = GF.createPoint(new Coordinate(38.8899, 77.0091)); |
| private static final Geometry WHITE_HOUSE = GF.createPoint(new Coordinate(38.8977, 77.0365)); |
| |
| @Override |
| public void updateConfiguration(final MongoDBRdfConfiguration conf) { |
| conf.setBoolean(OptionalConfigUtils.USE_GEO, true); |
| conf.set(ConfigUtils.GEO_PREDICATES_LIST, "http://www.opengis.net/ont/geosparql#asWKT"); |
| conf.setBoolean(ConfigUtils.USE_MONGO, true); |
| } |
| |
| @Test |
| public void nearHappyUsesTest() throws Exception { |
| final Sail sail = GeoRyaSailFactory.getInstance(conf); |
| final SailRepositoryConnection conn = new SailRepository(sail).getConnection(); |
| try { |
| populateRya(conn); |
| |
| //Only captial |
| String query = |
| "PREFIX geo: <http://www.opengis.net/ont/geosparql#>\n" |
| + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>\n" |
| + "SELECT * \n" // |
| + "WHERE { \n" |
| + " <urn:geo> geo:asWKT ?point .\n" |
| + " FILTER(geof:sfNear(?point, \"POINT(38.8895 77.0353)\"^^geo:wktLiteral, 0.0, 2000))" |
| + "}"; |
| |
| 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); |
| } |
| assertEquals(1, results.size()); |
| assertEquals(CAPITAL_BUILDING, bindingToGeo(results.get(0))); |
| |
| //all but capital |
| query = |
| "PREFIX geo: <http://www.opengis.net/ont/geosparql#>\n" |
| + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>\n" |
| + "SELECT * \n" // |
| + "WHERE { \n" |
| + " <urn:geo> geo:asWKT ?point .\n" |
| + " FILTER(geof:sfNear(?point, \"POINT(38.8895 77.0353)\"^^geo:wktLiteral, 2000))" |
| + "}"; |
| |
| rez = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); |
| results.clear(); |
| while (rez.hasNext()) { |
| final BindingSet bs = rez.next(); |
| results.add(bs); |
| } |
| assertEquals(3, results.size()); |
| assertEquals(WASHINGTON_MONUMENT, bindingToGeo(results.get(0))); |
| assertEquals(WHITE_HOUSE, bindingToGeo(results.get(1))); |
| assertEquals(LINCOLN_MEMORIAL, bindingToGeo(results.get(2))); |
| |
| // all of them |
| query = |
| "PREFIX geo: <http://www.opengis.net/ont/geosparql#>\n" |
| + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>\n" |
| + "SELECT * \n" // |
| + "WHERE { \n" |
| + " <urn:geo> geo:asWKT ?point .\n" |
| + " FILTER(geof:sfNear(?point, \"POINT(38.8895 77.0353)\"^^geo:wktLiteral, 6000, 000))" |
| + "}"; |
| |
| rez = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); |
| results.clear(); |
| while (rez.hasNext()) { |
| final BindingSet bs = rez.next(); |
| results.add(bs); |
| } |
| assertEquals(4, results.size()); |
| assertEquals(WASHINGTON_MONUMENT, bindingToGeo(results.get(0))); |
| assertEquals(WHITE_HOUSE, bindingToGeo(results.get(1))); |
| assertEquals(LINCOLN_MEMORIAL, bindingToGeo(results.get(2))); |
| assertEquals(CAPITAL_BUILDING, bindingToGeo(results.get(3))); |
| |
| // donut, only 2 |
| query = |
| "PREFIX geo: <http://www.opengis.net/ont/geosparql#>\n" |
| + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>\n" |
| + "SELECT * \n" // |
| + "WHERE { \n" |
| + " <urn:geo> geo:asWKT ?point .\n" |
| + " FILTER(geof:sfNear(?point, \"POINT(38.8895 77.0353)\"^^geo:wktLiteral, 2000, 100))" |
| + "}"; |
| |
| rez = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); |
| results.clear(); |
| while (rez.hasNext()) { |
| final BindingSet bs = rez.next(); |
| results.add(bs); |
| } |
| assertEquals(2, results.size()); |
| assertEquals(WHITE_HOUSE, bindingToGeo(results.get(0))); |
| assertEquals(LINCOLN_MEMORIAL, bindingToGeo(results.get(1))); |
| |
| // all of them |
| query = |
| "PREFIX geo: <http://www.opengis.net/ont/geosparql#>\n" |
| + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>\n" |
| + "SELECT * \n" // |
| + "WHERE { \n" |
| + " <urn:geo> geo:asWKT ?point .\n" |
| + " FILTER(geof:sfNear(?point, \"POINT(38.8895 77.0353)\"^^geo:wktLiteral))" |
| + "}"; |
| rez = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); |
| results.clear(); |
| while (rez.hasNext()) { |
| final BindingSet bs = rez.next(); |
| results.add(bs); |
| } |
| assertEquals(4, results.size()); |
| assertEquals(WASHINGTON_MONUMENT, bindingToGeo(results.get(0))); |
| assertEquals(WHITE_HOUSE, bindingToGeo(results.get(1))); |
| assertEquals(LINCOLN_MEMORIAL, bindingToGeo(results.get(2))); |
| assertEquals(CAPITAL_BUILDING, bindingToGeo(results.get(3))); |
| } finally { |
| conn.close(); |
| sail.shutDown(); |
| } |
| } |
| |
| @Test(expected = MalformedQueryException.class) |
| public void near_invalidDistance() throws Exception { |
| final Sail sail = GeoRyaSailFactory.getInstance(conf); |
| final SailRepositoryConnection conn = new SailRepository(sail).getConnection(); |
| try { |
| populateRya(conn); |
| |
| //Only captial |
| final String query = |
| "PREFIX geo: <http://www.opengis.net/ont/geosparql#>\n" |
| + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>\n" |
| + "SELECT * \n" // |
| + "WHERE { \n" |
| + " <urn:geo> geo:asWKT ?point .\n" |
| + " FILTER(geof:sfNear(?point, \"POINT(38.8895 77.0353)\"^^geo:wktLiteral, distance))" |
| + "}"; |
| |
| conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); |
| } finally { |
| conn.close(); |
| sail.shutDown(); |
| } |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void near_negativeDistance() throws Exception { |
| final Sail sail = GeoRyaSailFactory.getInstance(conf); |
| final SailRepositoryConnection conn = new SailRepository(sail).getConnection(); |
| try { |
| populateRya(conn); |
| |
| //Only captial |
| final String query = |
| "PREFIX geo: <http://www.opengis.net/ont/geosparql#>\n" |
| + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>\n" |
| + "SELECT * \n" // |
| + "WHERE { \n" |
| + " <urn:geo> geo:asWKT ?point .\n" |
| + " FILTER(geof:sfNear(?point, \"POINT(38.8895 77.0353)\"^^geo:wktLiteral, -100))" |
| + "}"; |
| |
| final TupleQueryResult rez = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); |
| while(rez.hasNext()) { |
| rez.next(); |
| } |
| } finally { |
| conn.close(); |
| sail.shutDown(); |
| } |
| } |
| |
| @Test(expected = QueryEvaluationException.class) |
| public void tooManyArgumentsTest() throws Exception { |
| final Sail sail = GeoRyaSailFactory.getInstance(conf); |
| final SailRepositoryConnection conn = new SailRepository(sail).getConnection(); |
| try { |
| populateRya(conn); |
| |
| // Only captial |
| final String query = |
| "PREFIX geo: <http://www.opengis.net/ont/geosparql#>\n" |
| + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>\n" |
| + "SELECT * \n" // |
| + "WHERE { \n" + " <urn:geo> geo:asWKT ?point .\n" |
| + " FILTER(geof:sfNear(?point, \"POINT(38.8895 77.0353)\"^^geo:wktLiteral, 100, 1000, 10))" |
| + "}"; |
| |
| conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(); |
| } finally { |
| conn.close(); |
| sail.shutDown(); |
| } |
| } |
| |
| private void populateRya(final SailRepositoryConnection conn) throws Exception { |
| // geo 2x2 points |
| conn.begin(); |
| RyaStatement stmnt = statement(WASHINGTON_MONUMENT); |
| Statement statement = RyaToRdfConversions.convertStatement(stmnt); |
| conn.add(statement); |
| |
| stmnt = statement(LINCOLN_MEMORIAL); |
| statement = RyaToRdfConversions.convertStatement(stmnt); |
| conn.add(statement); |
| |
| stmnt = statement(CAPITAL_BUILDING); |
| statement = RyaToRdfConversions.convertStatement(stmnt); |
| conn.add(statement); |
| |
| stmnt = statement(WHITE_HOUSE); |
| statement = RyaToRdfConversions.convertStatement(stmnt); |
| conn.add(statement); |
| conn.commit(); |
| } |
| |
| private static Geometry bindingToGeo(final BindingSet bs) throws ParseException { |
| final WKTReader w = new WKTReader(); |
| return w.read(bs.getValue("point").stringValue()); |
| } |
| |
| private static RyaStatement statement(final Geometry geo) { |
| final ValueFactory vf = SimpleValueFactory.getInstance(); |
| final Resource subject = vf.createIRI("urn:geo"); |
| final IRI predicate = GeoConstants.GEO_AS_WKT; |
| final WKTWriter w = new WKTWriter(); |
| final Value object = vf.createLiteral(w.write(geo), GeoConstants.XMLSCHEMA_OGC_WKT); |
| return RdfToRyaConversions.convertStatement(vf.createStatement(subject, predicate, object)); |
| } |
| |
| } |