2010-06-06 6 views
0

Je suis juste jouer avec un jeu de données de ma région générée par JOSM. Je me suis déplacé dans un mySQL DB avec le système API 0.6 en utilisant Osmose et maintenant je suis en train désespérément ce qui suit:OpenStreetMap Recherche à proximité en utilisant mySQL

Je veux toutes les rues d'une ville. AFAIK il n'y a pas tag/relation dans les données OSM pour déterminer ce si je l'ai essayé en utilisant une recherche de proximité pour obtenir tous les nœuds dans un rayon autour d'un noeud représentant le centre-ville.

La plupart du temps, je regardais les approches here

Ce que je GOT le code SQL suivant qui devrait me faire les plus proches de 100 nœuds autour du nœud avec id 36187002 et dans un rayon de 10 km.

set @nodeid = 36187002; 
set @dist = 10; 
select longitude, latitude into @mylon, @mylat from nodes where [email protected] 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; 

Eh bien ... cela ne fonctionne pas. :(Je suppose que le problème principal est que les lats OSM/lons sont multipliés par 10.000.000 et je ne sais pas comment je peux corriger cette fonction pour le faire fonctionner

Toutes les idées/solutions possibles

Répondre

0

Il peut être plus rapide d'ajouter des colonnes supplémentaires à votre table pour la latitude et la longitude exprimées comme double (donc les fonctions trigonométriques ont une chance) - vous pouvez aller plus loin et précalculer les xaxis, yaxis et zaxis en tant que colonnes (à nouveau, stockées sous la forme double)

Ainsi, vos nouvelles colonnes ne sont pas complètes (vous devrez peut-être ajouter des conversions de type de données si nécessaire):

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

Ensuite, votre recherche de proximité devient:

set @nodeid = 36187002; 
set @dist = 10; 
SELECT XAxis, YAxis, ZAxis 
INTO @CntXAxis, @CntYAxis, @CntZAxis 
FROM nodes 
WHERE [email protected] 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; 
0

J'ai modifié la requête un peu et cela fonctionne. Voici mon code:

set @nodeid = 122317; 
    set @dist = 10; 
    select lon, lat into @mylon, @mylat from nodes where [email protected] 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 

a la formule Ive du wikipedia allemand et il fonctionne très bien. J'ai eu dans certains poing de code Ruby, mais son travaille aussi comme une requête SQL.

Pour sélectionner certains noeuds spéciaux i a ajouté

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

comme de la condition de préciser les balises des noeuds. (Bien sûr, il modifie l'accès lat/log à stations.lat/stations.log~~V~~3rd dans le code ci-dessus.

Questions connexes