我现在正在执行 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:lat
和 geo: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
BIND
s using thest_distance()
function to theWHERE
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
orst_point(?long, ?lat)
but they are not delivered unlessbif:st_within
specifies a radius of21
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()
usesst_distance()
, so given that thesrid
is4326
(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 thest_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 thest_distance()
function (here calculated from?coordinates
, but you could also use the more complex construction based on?long
and?lat
), and not the malfunctioningst_within()
.
关于Sparql 查询几何做奇怪的事情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51704720/