Apache Jena的地理空间查询

时间:2016-03-04 16:46:25

标签: java apache rdf geospatial jena

我在Apache Jena中开始使用地理空间查询时遇到了问题。

收到@AndyS的评论后,我意识到我需要从Jena Model创建一个Spatial数据集。我仍然得到一个空结果

首先,在我的模型中,我有一系列三元组:

<rdf:RDF
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
        xmlns:ssn="http://purl.oclc.org/NET/ssnx/ssn#"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema#" > 
   <ssn:ObservationValue rdf:about="http://example.com/ObservationValues/GasCO/1450439142">
            <geo:location>
              <rdf:Description rdf:about="http://example.com/locations/GasCO/1450439142">
                <geo:lat>35.4</geo:lat>
                <geo:long>32</geo:long>
              </rdf:Description>
            </geo:location>
    <!-- here go more triples -->
    </ssn:ObservationValue>
    </rdf:RDF>

我正在尝试使用以下代码获取ssn:ObservationValue资源:

String queryStr =
    "PREFIX spatial: <http://jena.apache.org/spatial#> " +
    "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> " +
    "PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> " +
    "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> " +
    "PREFIX ssn: <http://purl.oclc.org/NET/ssnx/ssn#>" +
    "SELECT ?loc " +
    "WHERE {?loc spatial:nearby(35.4 32  1000 'km' )}";

    // creating entity definition. Should somehow define the geodata
    //EntityDefinition entDef = new EntityDefinition("ssn:ObservationValue",
    // "geo:location");
    // EntityDefinition entDef = new EntityDefinition(" <http://example.com/ObservationValues/GasCO/1450439142>",
    // "<http://example.com/locations/GasCO/1450439142>");
    EntityDefinition entDef = 
    new EntityDefinition("<http://purl.oclc.org/NET/ssnx/ssn#ObservationValue>",
    "<http://www.w3.org/2003/01/geo/wgs84_pos#location>");

    // Model m is a Jena Model object which contains the data
    Dataset baseDataset = DatasetFactory.create(m);

    try {
            Directory dir = FSDirectory.open( new File("/home/martin/spatial_index"));  
    Dataset spatialDataset = SpatialDatasetFactory.createLucene(baseDataset, dir, entDef); 

            Query query = QueryFactory.create(queryStr) ;
            QueryExecution qexec = QueryExecutionFactory.create(query, spatialDataset);
            ResultSet results = qexec.execSelect() ;
            System.out.println("results.size(): " + results.getRowNumber());
    } catch (IOException e) {
            e.printStackTrace();
    }

但ResultSet结果为空 - results.getRowNumber()返回0

我怀疑上面代码的问题是EntityDefinition entDef的定义。在EntityDefinition的文档中,它声明它需要 entityField geoField 。我试图提供我感兴趣的节点的显式IRI,前缀类型,例如ssn:Observationvalue和geo:location(由注释代码建议),但到目前为止这两种解决方案都没有。

是否有人遇到任何类似的情况或对可能出现的问题有任何暗示?

由于

1 个答案:

答案 0 :(得分:0)

我被Apache Jena邮件列表中的人员引用了spatialindexer.java的源代码。事实证明,我需要手动添加要编入空间索引的三元组。在这里,我提供了索引的源代码。它适用于我 - 上面的SPARQL查询在给定半径内找到三元组。修改后的代码是:

String queryStr =
		"PREFIX spatial: <http://jena.apache.org/spatial#> " +
		"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> " +
		"PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> " +
		"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> " +
		"PREFIX ssn: <http://purl.oclc.org/NET/ssnx/ssn#> " +
		"SELECT ?loc ?lat " +
		"WHERE {?loc spatial:nearby(35.5 32 1000 'km' ) . ?loc geo:lat ?lat}";

Model m = SemanticSensorModel.getIntance().getJenaModel();
EntityDefinition entDef = new EntityDefinition("1", "2");				
Dataset baseDataset = DatasetFactory.create(m);
try {
	Directory dir = FSDirectory.open( new File("/home/martin/spatial_index"));
	Dataset spatialDataset = SpatialDatasetFactory.createLucene(baseDataset, dir, entDef); 
			
	DatasetGraphSpatial dataset = (DatasetGraphSpatial) (spatialDataset.asDatasetGraph());
	SpatialIndex spatialIndex = dataset.getSpatialIndex();
	SpatialIndexContext context = new SpatialIndexContext(spatialIndex);
	spatialIndex.startIndexing();
				
	Iterator<Quad> quadIter = dataset.find(Node.ANY, Node.ANY, Node.ANY, Node.ANY);
	for (; quadIter.hasNext();) {
		Quad quad = quadIter.next();
		context.index(quad.getGraph(), quad.getSubject(), quad.getPredicate(), quad.getObject());
	}
	spatialIndex.finishIndexing();
							
	Query query = QueryFactory.create(queryStr) ;
	QueryExecution qexec = QueryExecutionFactory.create(query, spatialDataset);
	ResultSet results = qexec.execSelect() ;

	for ( ; results.hasNext() ; )
	{
		QuerySolution soln = results.nextSolution() ;
		System.out.println(soln.get("loc").toString() + " " + soln.get("lat").toString());
	}
				
	System.out.println("Done printing results");
} catch (IOException e) {
	e.printStackTrace();
}

注意创建SpatialIndex,并使用startIndexing()/ index()/ finishIndexing()方法。 上面的代码可以作为任何人的起点 想要开始使用Jena的地理空间SPARQL查询。

此致

马丁