我正在使用 Jena、JenaParliament、Parliamnet 对 Parliment RDF 存储使用 GeoSPARQL 查询。简单的 SPARQL 查询工作正常,但是当我使用一些 GeoSPARQL 查询时,例如
SELECT * WHERE {?bGeom geo:asWKT ?bWKT . FILTER (geof:sfIntersects(?bWKT, "Polygon((1 0, 1 1, 0 1, 1 0))"^^sf:wktLiteral))}
SELECT * WHERE {?bGeom geo:asWKT ?bWKT . FILTER (geof:sfOverlaps(?bWKT, "Polygon((1 0, 1 1, 0 1, 1 0))"^^sf:wktLiteral))}
SELECT * WHERE {?bGeom geo:asWKT ?bWKT . FILTER (geof:sfTouches(?bWKT, "Polygon((1 0, 1 1, 0 1, 1 0))"^^sf:wktLiteral))}
SELECT * WHERE {?bGeom geo:asWKT ?bWKT . FILTER (geof:sfCrosses(?bWKT, "Polygon((0 0, 1 0, 0 1, 0 0))"^^sf:wktLiteral))}
输出是一个空的ResultSet
(空白表),带有运行时警告:
WARN [main] (E_Function.java:70) - URI <http://www.opengis.net/def/function/geosparql/sfIntersects> has no registered function factory.
其他 geof:sfFunction
也会获得相同的警告和结果。我已经在 http://localhost:8080/parliament/sparql
使用 SPARQL Endpoit 在 PARLIMENT QUICK START 发行版上尝试了相同的查询,并且在 Jetty 服务器上运行时返回有效的输出。
用于从 java 触发 GeoSPARQL 查询的代码与《Parliament User Guide.pdf》中所示的代码相同,如下所示:
void useParliamentModel(){
Model kbModel = createParliamentModel();
FileManager.get().readModel( kbModel, "Path to source owl/rdf file");
String sparqlQueryString = "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
"PREFIX geof: <http://www.opengis.net/def/function/geosparql/>" +
"PREFIX sf: <http://www.opengis.net/ont/sf#>"+
"PREFIX afn: <http://jena.hpl.hp.com/ARQ/function#>"+
"PREFIX fn: <http://www.w3.org/2005/xpath-functions#>"+
"PREFIX gml: <http://www.opengis.net/ont/gml#>"+
"PREFIX j.0:<http://www.opengis.net/def/geosparql/#>"+
"PREFIX my:<http://example.org/ApplicationSchema#>"+
//"SELECT * WHERE {?s ?o my:PlaceOfInterest}"; ------->>>> THIS QUERY RUNS FINE
"SELECT * WHERE {?bGeom geo:asWKT ?bWKT . FILTER (geof:sfIntersects(?bWKT, \"Polygon((1 0, 1 1, 0 1, 1 0))\"^^sf:wktLiteral))}"; //give Waring No result
//"SELECT * WHERE {?bGeom geo:asWKT ?bWKT . FILTER (geof:sfOverlaps(?bWKT, \"Polygon((1 0, 1 1, 0 1, 1 0))\"^^sf:wktLiteral))}"; //give Waring No result
//"SELECT * WHERE {<http://example.org/ApplicationSchema#F> ?s ?o }"; //-------->>> This Query runs Fine
//"SELECT ?f WHERE { my:A my:hasExactGeometry ?aGeom . ?aGeom geo:asWKT ?aWKT . ?f my:hasExactGeometry ?fGeom . ?fGeom geo:asWKT ?fWKT . FILTER (geof:sfContains(?aWKT, ?fWKT) && !sameTerm(?aGeom, ?fGeom))}"; /// return a blank table
String r;
try{
QueryExecution qexec = QueryExecutionFactory.create(sparqlQueryString, kbModel);
ResultSet results = qexec.execSelect();
r = printResultsWithResultSetFormatter(results, SparqlQuery.OutputType.TEXT);
}
finally
{
if (kbModel != null && !kbModel.isClosed())
{
kbModel.close();
kbModel = null;
}
}
System.out.println("Query Results are: \n----------\n"+ r);
}
此外:根据我的观察,我们需要为在indexes.jsp 页面使用Parliament QuickStart Distribution 时插入的数据集创建索引。在触发任何 geoSparql 查询之前,我们是否需要从 java 代码创建/初始化索引?如果是的话怎么办?
请帮忙!!我们将不胜感激。
请您参考如下方法:
为了使空间查询工作,应使用以下代码来初始化模型,使用 JenaParliament
和 Parliament
JAVA API:
public static void initializeJPStore(){
KbGraph graph;
KbGraphStore graphStore;
SpatialIndexFactory spatialIndexFactory;
SpatialIndex spatialIndex;
boolean createIndex = true;
spatialIndexFactory = new SpatialIndexFactory();
Properties properties = new Properties();
properties.setProperty(Constants.GEOMETRY_INDEX_TYPE, Constants.GEOMETRY_INDEX_RTREE);
properties.setProperty(Constants.GEOSPARQL_ENABLED, Boolean.TRUE.toString());
spatialIndexFactory.configure(properties);
IndexFactoryRegistry.getInstance().register(spatialIndexFactory);
graph = KbGraphFactory.createDefaultGraph(); //Dir path taken from ParliamentConfig.txt
graphStore = new KbGraphStore(graph);
graphStore.initialize();
if (createIndex) {
spatialIndex = spatialIndexFactory.createIndex(graph, null);
IndexManager.getInstance().register(graph, null, spatialIndexFactory, spatialIndex);
graphStore.setIndexingEnabled(KbGraphStore.DEFAULT_GRAPH_NODE, true);
}
Model model = ModelFactory.createModelForGraph(graph);
OntModel ontModel= ModelToOntModel(model);
FileManager.get().readModel(ontModel, "Path/to/Source RDF/OWL file");
//System.out.println(IndexManager.getInstance().getIndexes(graph).get(0).size()); to keep a check of IndexSize
}
根据我的观察和实验:您必须创建索引
,将它们注册到IndexFactory
,然后注册Index
和IndexFactory
与 IndexManager
一起使用,否则 GeoSPARQL 查询将无法工作。 ARQ 引擎向 IndexManager
请求给定模型/图的索引,以执行 GeoSPARQL 查询/函数。如上所述初始化 Triple Store 后,无需更改调用 SPARQL 查询的代码,就可以无差别地触发 SPARQL/GeoSPARQL 查询。
注意:至于上面提到的sf:function
未注册的问题,我想当我们配置Properties.setProperty(Constants.GEOSPARQL_ENABLED, Boolean.TRUE时,这个问题就会得到解决。 toString());
。但我对此并不确定。
并且请不要忘记close()
模型、图表和索引。