0

我只是在玩 JOSM 生成的我所在地区的数据集。我使用 Osmosis 将它移到了带有 0.6 API 方案的 mySQL DB 中,现在我正在拼命尝试以下操作:

我想得到一个城市的所有街道。AFAIK OSM 数据中没有标签/关系来确定这一点,所以我尝试使用邻近搜索来获取代表市中心的节点周围半径内的所有节点。

大多数时候我都在看这里的方法

我得到的是以下 SQL 代码,它应该让我在 id 为 36187002 且半径为 10 公里的节点周围获得最近的 100 个节点。

set @nodeid = 36187002;
set @dist = 10;
select longitude, latitude into @mylon, @mylat from nodes where id=@nodeid limit 1;


SELECT id, ( 6371 * acos( cos( radians(@mylon) ) * cos( radians( latitude ) ) * 
cos( radians(  longitude ) - radians(@mylat) ) + sin( radians(@mylon) ) * sin( radians( latitude ) ) ) ) 
AS distance
FROM nodes HAVING distance < @dist ORDER BY distance LIMIT 0 , 100;

嗯..它不起作用。:( 我想主要问题是 OSM 纬度/经度乘以 10.000.000,我不知道如何更正此函数以使其工作。

有什么想法吗?非常欢迎所有解决方案/替代方案!

4

2 回答 2

0

为表示为double数据类型的纬度和经度向表中添加额外的列可能会更快(因此三角函数有机会) - 您可能想要更进一步并将 xaxis、yaxis 和 zaxis 预先计算为列(再次,存储为double)

因此,您的新列是松散的(您可能需要根据需要添加数据类型转换):

XAxis   = cos(radians(Latitude / 10000000)) * cos(radians(Longitude / 10000000))
YAxis   = cos(radians(Latitude / 10000000)) * sin(radians(Longitude / 10000000))
ZAxis   = sin(radians(Latitude / 10000000))

然后,您的邻近搜索变为:

set @nodeid = 36187002;
set @dist = 10;
SELECT XAxis, YAxis, ZAxis
INTO @CntXAxis, @CntYAxis, @CntZAxis
FROM nodes
WHERE id=@nodeid limit 1;

SELECT id, ( 6371 * acos(
             CASE
                WHEN nodes.XAxis * @CntXAxis
              + nodes.YAxis * @CntYAxis
              + nodes.ZAxis * @CntZAxis > 1.0 THEN 1.0
              ELSE  nodes.XAxis * @CntXAxis
              + nodes.YAxis * @CntYAxis
              + nodes.ZAxis * @CntZAxis 
             END
           ) AS Distance
FROM nodes 
HAVING Distance < @dist 
ORDER BY distance LIMIT 0 , 100;
于 2010-07-07T16:26:52.647 回答
0

我稍微修改了查询,它可以工作。这是我的代码:

    set @nodeid = 122317;
    set @dist = 10;
    select lon, lat into @mylon, @mylat from nodes where id=@nodeid limit 1;

    SELECT id, ( 6371 * acos(
    sin(radians(@mylat)) * sin(radians(lat)) +
    cos(radians(@mylat)) * cos( radians(lat)) * 
    cos(radians(lon) - radians(@mylon)) 
    )) 
    AS distance
    FROM nodes having distance <@dist

我从德国维基百科得到了公式,效果很好。我有一些 ruby​​ 代码拳头,但它也可以用作 sql 查询。

为了选择一些特殊的节点,我添加了这个

(select nodes.id,lat,lon,k,v from nodes join node_tags on nodes.id=node_tags.id where k='public_transport') as stations

作为 FROM 条件来指定节点的标签。(当然,它会更改上面代码中对stations.lat/stations.log 的lat/log 访问。

于 2012-07-03T17:42:38.233 回答