|
19 | 19 |
|
20 | 20 | import java.io.IOException;
|
21 | 21 | import java.util.HashSet;
|
| 22 | +import java.util.Iterator; |
22 | 23 | import java.util.Set;
|
| 24 | +import java.util.function.Function; |
23 | 25 |
|
24 | 26 | import org.apache.lucene.analysis.en.EnglishAnalyzer;
|
25 | 27 | import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
|
39 | 41 | import org.eclipse.rdf4j.common.concurrent.locks.Properties;
|
40 | 42 | import org.eclipse.rdf4j.model.IRI;
|
41 | 43 | import org.eclipse.rdf4j.model.Literal;
|
| 44 | +import org.eclipse.rdf4j.model.Model; |
42 | 45 | import org.eclipse.rdf4j.model.Resource;
|
43 | 46 | import org.eclipse.rdf4j.model.Statement;
|
| 47 | +import org.eclipse.rdf4j.model.Value; |
44 | 48 | import org.eclipse.rdf4j.model.ValueFactory;
|
| 49 | +import org.eclipse.rdf4j.model.base.CoreDatatype; |
45 | 50 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
|
| 51 | +import org.eclipse.rdf4j.model.impl.TreeModel; |
| 52 | +import org.eclipse.rdf4j.model.vocabulary.GEO; |
| 53 | +import org.eclipse.rdf4j.model.vocabulary.GEOF; |
| 54 | +import org.eclipse.rdf4j.query.BindingSet; |
| 55 | +import org.eclipse.rdf4j.query.TupleQuery; |
| 56 | +import org.eclipse.rdf4j.query.TupleQueryResult; |
46 | 57 | import org.eclipse.rdf4j.repository.sail.SailRepository;
|
47 | 58 | import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection;
|
| 59 | +import org.eclipse.rdf4j.repository.util.Repositories; |
| 60 | +import org.eclipse.rdf4j.sail.evaluation.TupleFunctionEvaluationMode; |
48 | 61 | import org.eclipse.rdf4j.sail.lucene.LuceneSail;
|
49 | 62 | import org.eclipse.rdf4j.sail.lucene.SearchFields;
|
50 | 63 | import org.eclipse.rdf4j.sail.memory.MemoryStore;
|
@@ -478,4 +491,85 @@ private void assertNoStatement(Statement statement, Document document) {
|
478 | 491 | * for(String notFound : toFind) { assertEquals("Was the expected text value '" + notFound + "' found?", true,
|
479 | 492 | * false); } }
|
480 | 493 | */
|
| 494 | + |
| 495 | + @Test |
| 496 | + public void geoSparqlQueryTest() { |
| 497 | + final String prefix = "http://www.example.org/#"; |
| 498 | + final String prefixes = "PREFIX ex: <" + prefix + ">\n" |
| 499 | + + "PREFIX geof: <" + GEOF.NAMESPACE + ">\n" |
| 500 | + + "PREFIX geo: <" + CoreDatatype.GEO.NAMESPACE + ">\n" |
| 501 | + + "PREFIX uom: <http://www.opengis.net/def/uom/OGC/1.0/>\n"; |
| 502 | + Model data = new TreeModel(); |
| 503 | + |
| 504 | + IRI cp = vf.createIRI(prefix + "cp"); |
| 505 | + IRI bm = vf.createIRI(prefix + "bm"); |
| 506 | + IRI nkv = vf.createIRI(prefix + "nkv"); |
| 507 | + |
| 508 | + data.add(cp, GEO.AS_WKT, vf.createLiteral("Point(4.38436 45.44917)", CoreDatatype.GEO.WKT_LITERAL)); |
| 509 | + data.add(bm, GEO.AS_WKT, vf.createLiteral("Point(4.38311 45.45423)", CoreDatatype.GEO.WKT_LITERAL)); |
| 510 | + data.add(nkv, GEO.AS_WKT, vf.createLiteral("Point(4.87306 45.77903)", CoreDatatype.GEO.WKT_LITERAL)); |
| 511 | + data.add(vf.createIRI(prefix + "arp"), GEO.AS_WKT, |
| 512 | + vf.createLiteral("Point(2.89271 42.69848)", CoreDatatype.GEO.WKT_LITERAL)); |
| 513 | + |
| 514 | + String polyVill = "POLYGON((4.864712 45.784405, 4.883165 45.787756, 4.889946 45.785781, 4.904881 45.767403, 4.900761 45.765487, 4.872093 45.770995, 4.86454 45.770457, 4.858789 45.770277, 4.859905 45.784644, 4.864712 45.784405))"; |
| 515 | + String polySain = "POLYGON((4.380627 45.463983, 4.400539 45.462177, 4.428349 45.436286, 4.399509 45.411346, 4.374447 45.426528, 4.370499 45.450618, 4.380627 45.463983))"; |
| 516 | + |
| 517 | + SailRepository m1 = new SailRepository(new MemoryStore()); |
| 518 | + LuceneSail lc = new LuceneSail(); |
| 519 | + lc.setBaseSail(new MemoryStore()); |
| 520 | + lc.setParameter(LuceneSail.WKT_FIELDS, GEO.AS_WKT.toString()); |
| 521 | + lc.setLuceneIndex(index); |
| 522 | + lc.setEvaluationMode(TupleFunctionEvaluationMode.NATIVE); |
| 523 | + SailRepository m2 = new SailRepository(lc); |
| 524 | + |
| 525 | + // add test data |
| 526 | + Repositories.consume(m1, conn -> conn.add(data)); |
| 527 | + Repositories.consume(m2, conn -> conn.add(data)); |
| 528 | + |
| 529 | + lc.reindex(); |
| 530 | + |
| 531 | + Function<TupleQueryResult, Set<Value>> toval = (res) -> { |
| 532 | + Set<Value> list = new HashSet<>(); |
| 533 | + while (res.hasNext()) { |
| 534 | + BindingSet next = res.next(); |
| 535 | + list.add(next.getValue("v")); |
| 536 | + } |
| 537 | + return list; |
| 538 | + }; |
| 539 | + |
| 540 | + // test queries |
| 541 | + |
| 542 | + String q0 = prefixes |
| 543 | + + "SELECT * {\n" |
| 544 | + + " ?v geo:asWKT ?loc .\n" |
| 545 | + + " FILTER(geof:distance(\"Point(4.386914 45.440637)\"^^geo:wktLiteral, ?loc, uom:metre) < 10000) \n" |
| 546 | + + "}\n"; |
| 547 | + Set<Value> q0ex = Set.of(bm, cp); |
| 548 | + |
| 549 | + String q1 = prefixes |
| 550 | + + "SELECT * {\n" |
| 551 | + + " ?v geo:asWKT ?loc .\n" |
| 552 | + + " FILTER(geof:ehContains(\"" + polySain + "\"^^geo:wktLiteral, ?loc)) \n" |
| 553 | + + "}\n"; |
| 554 | + Set<Value> q1ex = Set.of(bm, cp); |
| 555 | + |
| 556 | + String q2 = prefixes |
| 557 | + + "SELECT * {\n" |
| 558 | + + " ?v geo:asWKT ?loc .\n" |
| 559 | + + " FILTER(geof:ehContains(\"" + polyVill + "\"^^geo:wktLiteral, ?loc)) \n" |
| 560 | + + "}\n"; |
| 561 | + Set<Value> q2ex = Set.of(nkv); |
| 562 | + |
| 563 | + Set<Value> nlcq0 = Repositories.tupleQuery(m1, q0, toval); |
| 564 | + Set<Value> nlcq1 = Repositories.tupleQuery(m1, q1, toval); |
| 565 | + Set<Value> nlcq2 = Repositories.tupleQuery(m1, q2, toval); |
| 566 | + |
| 567 | + assertEquals(q0ex, nlcq0); |
| 568 | + assertEquals(q1ex, nlcq1); |
| 569 | + assertEquals(q2ex, nlcq2); |
| 570 | + |
| 571 | + assertEquals(nlcq0, Repositories.tupleQuery(m2, q0, toval)); |
| 572 | + assertEquals(nlcq1, Repositories.tupleQuery(m2, q1, toval)); |
| 573 | + assertEquals(nlcq2, Repositories.tupleQuery(m2, q2, toval)); |
| 574 | + } |
481 | 575 | }
|
0 commit comments