Sparql 查询几何做奇怪的事情

标签 sparql dbpedia geo virtuoso

我现在正在执行 Sparql 查询,以查找来自 dbpedia 端点 ( Snorql ) 的给定点的特定半径周围的位置。

我的第一个解决方案(已经在其他一些端点上执行)是这样的:

PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
SELECT *
WHERE {
?resource rdfs:label ?label  .
?resource geo:lat ?lat .
?resource geo:long ?long .
?resource geo:geometry ?coordinates .
FILTER(bif:st_within(?coordinates, bif:st_geomFromText("POINT(10.2788 47.4093)"), 1)) .
FILTER (lang(?label)= "de") .
}

我注意到它没有给我任何结果。然后我用 geo:latgeo:long 中给定的舍入值尝试了同样的操作:

PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
SELECT *
WHERE {
?resource rdfs:label ?label  .
?resource geo:lat ?lat .
?resource geo:long ?long .
?resource geo:geometry ?coordinates .
FILTER(bif:st_within(bif:st_point(?long, ?lat), bif:st_geomFromText("POINT(10.2788 47.4093)"), 1)) .
FILTER (lang(?label)= "de") .
}

现在我得到了 2 个结果。当我将第一个解的半径增加到 21 时,有很多结果,但将其减小到 20 时,没有结果。我在第一个查询中犯了错误吗?

非常感谢, 声波

最佳答案

As I answered on Confluence ...

Interesting!

Your original query (with addition of FROM <http://dbpedia.org> clause) does return the expected results when run against the LOD Cloud Cache, which is now on a somewhat older Virtuoso engine. This looks like a regression in newer versions.

To check things on DBpedia, I started with your query, and added a couple of BINDs using the st_distance() function to the WHERE clause --

BIND ( bif:st_distance ( ?coordinates, bif:st_geomFromText("POINT(10.2788 47.4093)") ) AS ?coord_distance ) . BIND ( bif:st_distance ( bif:st_point(?long, ?lat), bif:st_geomFromText("POINT(10.2788 47.4093)") ) AS ?latlong_distance ) }

I also added a final ORDER BY ?coord_distance to the query.

My results on DBpedia.org/sparql clearly show two entities within your desired radius of 1, and the calculated distances are the same whether based on ?coordinates or st_point(?long, ?lat) but they are not delivered unless bif:st_within specifies a radius of 21 or greater -- and those results include a number of other entities that are within the larger radius.

I've raised this to Virtuoso Development, and it's being tracked internally as bug#18399.

...以及后续...

st_within() uses st_distance(), so given that the srid is 4326 (as is typical for DBpedia geodata), "the haversine function is used to compute a great circle distance in kilometers on Earth." You can divide your distance in meters by 1000 (or multiply it by 0.001) to get the distance in kilometers for use in the st_within() call.

The computing time is dependent on the instance host, other load on the instance, etc. The public DBpedia instance's response time may well be longer than you can tolerate. You can set up your own mirror in a local server or in the cloud (AMIs based on DBpedia 2016-10 Snapshot [current DBpedia.org/sparql], or DBpedia-Live [current live.DBpedia.org/sparql]), which you can put on any AWS instance type -- so you can give it as much processor and/or RAM as you like.

Note that the LOD Cloud Cache instance may be upgraded to a newer Virtuoso engine at any time, so you should not rely on this delivering the desired results via st_within(). A slightly adjusted DBpedia query will deliver what I think you want using only the st_distance() function (here calculated from ?coordinates, but you could also use the more complex construction based on ?long and ?lat), and not the malfunctioning st_within().

关于Sparql 查询几何做奇怪的事情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51704720/

相关文章:

sql - 将SPARQL查询转换为SQL查询

sparql - 查询DBpedia 人类发展指数国家

java - 如何从 DBPedia 获取类别层次结构?

elasticsearch - 将地理边界框扩展 x 英里的计算

rdf - 选择(组合)多个属性值 - SPARQL/RDF

java - Apache Jena - 一次查询得到 3 个相同的结果

sparql - 上传一个大的 TTL 文件到 virtuoso graph

sparql - 为什么 DBpedia 中的同一属性有 2 个不同的词汇表?

通过摘要发现城市中值得注意的旅游目的地的 API

go - 如何使用geo/s2库确定LatLong位于Go中另一个LatLong的半径内?