0

JOSM によって生成された自分の地域のデータセットをいじっているだけです。Osmosisを使用して0.6 APIスキームでmySQL DBに移動しましたが、今は必死に次のことを試しています:

都市のすべての通りを取得したい。私の知る限り、OSM データにはこれを判断するためのタグ/関係がないため、近接検索を使用して、市内中心部を表すノードの周囲の半径内にあるすべてのノードを取得してみました。

ほとんどの場合、ここでアプローチを見ました

私が得たのは、ID 36187002 のノードの周囲で半径 10 km 以内の最も近い 100 個のノードを取得する次の SQL コードです。

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 lats/lons が 10.000.000 で乗算されることであり、この関数を機能させるためにどのように修正すればよいかわかりません。

これについてのアイデアはありますか?すべてのソリューション/代替手段は大歓迎です!

4

2 に答える 2

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

ドイツ語版ウィキペディアから数式を入手しましたが、正常に機能します。私はいくつかのルビーコードの拳を持っていましたが、それはsql-queryとしても機能します。

いくつかの特別なノードを選択するために、これを追加しました

(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 に答える
0

データ型として表される緯度と経度のテーブルに追加の列を追加する方が速い場合がありますdouble(したがって、三角関数は可能性があります)。さらに進んで、x 軸、y 軸、および z 軸を列として事前計算することをお勧めします (ここでも、として保存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 に答える