使用 Apache Jena 进行地理空间查询
Geospatial queries with Apache Jena
我在 Apache Jena 中开始进行地理空间查询时遇到问题。
收到@AndyS 的评论后,我意识到我需要从我的耶拿模型创建一个空间数据集。我仍然得到一个空结果
首先,在我的模型中,我有一组三元组:
<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();
}
但结果集结果为空- results.getRowNumber()
returns 0
我怀疑上面代码的问题是 EntityDefinition entDef
的定义。在 EntityDefinition
的文档中,它声明它期望 entityField 和 geoField 。我试图提供我感兴趣的节点的显式 IRI,前缀类型,例如ssn:Observationvalue 和 geo:location(如评论代码所建议的那样),但到目前为止,这两种解决方案都没有奏效。
有没有人遇到过类似的情况或有任何提示可能出了什么问题?
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 查询开始。
此致
马丁
我在 Apache Jena 中开始进行地理空间查询时遇到问题。
收到@AndyS 的评论后,我意识到我需要从我的耶拿模型创建一个空间数据集。我仍然得到一个空结果
首先,在我的模型中,我有一组三元组:
<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();
}
但结果集结果为空- results.getRowNumber()
returns 0
我怀疑上面代码的问题是 EntityDefinition entDef
的定义。在 EntityDefinition
的文档中,它声明它期望 entityField 和 geoField 。我试图提供我感兴趣的节点的显式 IRI,前缀类型,例如ssn:Observationvalue 和 geo:location(如评论代码所建议的那样),但到目前为止,这两种解决方案都没有奏效。
有没有人遇到过类似的情况或有任何提示可能出了什么问题?
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 查询开始。
此致
马丁