使用mySQL的OpenStreetMap近距离搜索

使用mySQL的OpenStreetMap近距离搜索,mysql,geo,openstreetmap,Mysql,Geo,Openstreetmap,我只是在玩由JOSM生成的我所在区域的数据集。我使用渗透技术将其迁移到具有0.6 API方案的mySQL DB中,现在我正在拼命尝试以下操作: 我想得到一个城市的所有街道。 AFAIK在OSM数据中没有标记/关系来确定这一点,因此我尝试使用邻近搜索来获取代表城市中心的节点周围半径内的所有节点 大部分时间我都在看这些方法 我得到的是下面的SQL代码,它应该可以让我得到id为36187002、半径为10km的节点周围最近的100个节点 set @nodeid = 36187002; set @dis

我只是在玩由JOSM生成的我所在区域的数据集。我使用渗透技术将其迁移到具有0.6 API方案的mySQL DB中,现在我正在拼命尝试以下操作:

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

大部分时间我都在看这些方法

我得到的是下面的SQL代码,它应该可以让我得到id为36187002、半径为10km的节点周围最近的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;
set@nodeid=36187002;
设置@dist=10;
从id=@nodeid limit 1的节点中选择经度、纬度到@mylon、@mylat;
选择id,(6371*acos(弧度(@mylon))*cos(弧度(纬度))*
cos(弧度(经度)-弧度(@mylat))+sin(弧度(@mylon))*sin(弧度(纬度)))
作为距离
距离小于距离顺序的节点的距离限制为0,100;
嗯。。它不起作用(我想主要问题是OSM lats/lons乘以10.000.000,我不知道如何更正此函数以使其工作


对此有什么想法吗?非常欢迎所有解决方案/备选方案!

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

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

然后,您的近距离搜索变成:

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;
set@nodeid=36187002;
设置@dist=10;
选择XAxis、YAxis、ZAxis
进入@CntXAxis、@CntYAxis、@CntZAxis
从节点
其中id=@nodeid limit 1;
选择id(6371*acos)(
案例
当nodes.XAxis*@CntXAxis
+nodes.YAxis*@CntYAxis
+nodes.ZAxis*@CntZAxis>1.0然后1.0
ELSE nodes.XAxis*@CntXAxis
+nodes.YAxis*@CntYAxis
+nodes.ZAxis*@CntZAxis
结束
)作为距离
从节点
有距离的
按距离限制订购0,100;

我对查询做了一些修改,它可以正常工作。 这是我的代码:

    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
作为FROM条件,指定节点的标记。(当然,它会在上面的代码中将lat/log访问更改为stations.lat/stations.log

    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
(select nodes.id,lat,lon,k,v from nodes join node_tags on nodes.id=node_tags.id where k='public_transport') as stations