Skip to content

Commit 192b4ea

Browse files
authored
GH-4978 Index geosparql points using geo field (#4979)
2 parents 3d218d9 + 2082613 commit 192b4ea

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

core/sail/lucene/src/main/java/org/eclipse/rdf4j/sail/lucene/impl/LuceneDocument.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,12 @@ private void indexShape(Object shape, String field) {
174174
doc.add(f);
175175
}
176176
} else if (shape instanceof double[]) { // WKT:POINT
177-
double point[] = (double[]) shape;
177+
double[] point = (double[]) shape;
178+
179+
for (Field f : LatLonShape.createIndexableFields(GEO_FIELD_PREFIX + field, point[1],
180+
point[0])) {
181+
doc.add(f);
182+
}
178183
doc.add(new LatLonPoint(POINT_FIELD_PREFIX + field, point[1], point[0]));
179184
} else if (shape instanceof Rectangle) { // WKT:ENVELOPE / RECTANGLE
180185
Rectangle box = (Rectangle) shape;

core/sail/lucene/src/test/java/org/eclipse/rdf4j/sail/lucene/impl/LuceneIndexTest.java

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919

2020
import java.io.IOException;
2121
import java.util.HashSet;
22+
import java.util.Iterator;
2223
import java.util.Set;
24+
import java.util.function.Function;
2325

2426
import org.apache.lucene.analysis.en.EnglishAnalyzer;
2527
import org.apache.lucene.analysis.standard.StandardAnalyzer;
@@ -39,12 +41,23 @@
3941
import org.eclipse.rdf4j.common.concurrent.locks.Properties;
4042
import org.eclipse.rdf4j.model.IRI;
4143
import org.eclipse.rdf4j.model.Literal;
44+
import org.eclipse.rdf4j.model.Model;
4245
import org.eclipse.rdf4j.model.Resource;
4346
import org.eclipse.rdf4j.model.Statement;
47+
import org.eclipse.rdf4j.model.Value;
4448
import org.eclipse.rdf4j.model.ValueFactory;
49+
import org.eclipse.rdf4j.model.base.CoreDatatype;
4550
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;
4657
import org.eclipse.rdf4j.repository.sail.SailRepository;
4758
import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection;
59+
import org.eclipse.rdf4j.repository.util.Repositories;
60+
import org.eclipse.rdf4j.sail.evaluation.TupleFunctionEvaluationMode;
4861
import org.eclipse.rdf4j.sail.lucene.LuceneSail;
4962
import org.eclipse.rdf4j.sail.lucene.SearchFields;
5063
import org.eclipse.rdf4j.sail.memory.MemoryStore;
@@ -478,4 +491,85 @@ private void assertNoStatement(Statement statement, Document document) {
478491
* for(String notFound : toFind) { assertEquals("Was the expected text value '" + notFound + "' found?", true,
479492
* false); } }
480493
*/
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+
}
481575
}

0 commit comments

Comments
 (0)