Skip to main content
 首页 » 编程设计

geospatial中使用 FILTER geof :sfContains or geof:sfIntersects or geof:sfOverlaps returns no results when run from Java:JenaParliament 进行 GeoSPARQL 查询

2024年11月01日8qq78292959

我正在使用 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 代码创建/初始化索引?如果是的话怎么办?

请帮忙!!我们将不胜感激。

请您参考如下方法:

为了使空间查询工作,应使用以下代码来初始化模型,使用 JenaParliamentParliament 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,然后注册IndexIndexFactoryIndexManager 一起使用,否则 GeoSPARQL 查询将无法工作。 ARQ 引擎向 IndexManager 请求给定模型/图的索引,以执行 GeoSPARQL 查询/函数。如上所述初始化 Triple Store 后,无需更改调用 SPARQL 查询的代码,就可以无差别地触发 SPARQL/GeoSPARQL 查询。

注意:至于上面提到的sf:function未注册的问题,我想当我们配置Properties.setProperty(Constants.GEOSPARQL_ENABLED, Boolean.TRUE时,这个问题就会得到解决。 toString());。但我对此并不确定。

并且请不要忘记close()模型、图表和索引。