开发者

Finding and Ordering Latitude and Longitude in SQL

I have a SQL database where I store longit开发者_如何学运维ude and latitude from an iPhone application. I need to query all the records starting from a given location to the other far most location.

For example, I have longitude x and latitude y. I want all the records first whose longitude matches x the most closely and whose latitude matches y the most closely. I need to all the records one by one in the chain from nearest to farthest. The more distant the location, the greater the value of longitude and latitude will be than x and y.

I hope you got the point and I am waiting for the answer.


Distance with latitude and longitude is not a simple calculation, but one requiring spherical trigonometry.

acos(cos(lat1)*cos(lon1)*cos(lat2)*cos(lon2) + 
     cos(lat1)*sin(lon1)*cos(lat2)*sin(lon2) + 
     sin(lat1)*sin(lat2)) * R(adius of the earth)

So this query

select locID, locName, locDesc, lat, lon, locDiffMeters   
from (select locID, locName, locDesc, lat, lon, 
             acos(cos($lat)*cos($lon)*cos(lat)*cos(lon) + 
                  cos($lat)*sin($lon)*cos(lat)*sin(lon) + 
                  sin($lat)*sin(lat) ) * 6,371,000 -- earths radius in meters
               as locDiffMeters
      from locationTable    
    where locID <> $ID    
) a    
order by locDiffMeters    

Is probably the right answer, assuming you have that capable of a math library.


Similar to Fosco, but using Pythagoras' Theorem:

select locID, locName, locDesc, lat, lon, locDiff from
(select locID, locName, locDesc, lat, lon, 
 sqrt((lat - $LAT)*(lat - $LAT) + (lon - $LON)*(lon - $LON)) as locDiff
 from locationTable
 where locID <> $ID) a
order by locDiff

For really large distances (or locations far from the equator) you should ideally use a geodesic.


Assuming that you've queried the start location lat/lon and location ID... I am using $LAT, $LON, and $ID as placeholders:

select locID, locName, locDesc, lat, lon, locDiff
from (
    select locID, locName, locDesc, lat, lon, ABS(lat - $LAT) + ABS(lon - $LON) as locDiff
      from locationTable
    where locID <> $ID
) a
order by locDiff

Hopefully this helps... may not be the most optimized method, but it should be pretty close.


If you don't have to deal with large distances (see Adam's answer), you might consider using PostgreSQL's geometric types and associated functions.


If you're using Postgresql, add the PostGIS extension and check out the ST_Distance_Sphere

ST_Distance_Sphere — Returns minimum distance in meters between two lon/lat geometries. Uses a spherical earth and radius of 6370986 meters. Faster than ST_Distance_Spheroid, but less accurate. PostGIS versions prior to 1.5 only implemented for points.

SELECT round(CAST(ST_Distance_Sphere(ST_Centroid(the_geom), ST_GeomFromText('POINT(-118 38)',4326)) As numeric),2) As dist_meter ...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜