【问题标题】:Finding and Ordering Latitude and Longitude in SQL在 SQL 中查找和排序纬度和经度
【发布时间】:2010-07-16 13:40:12
【问题描述】:

我有一个 SQL 数据库,用于存储来自 iPhone 应用程序的经度和纬度。我需要查询从给定位置开始到另一个最远位置的所有记录。

例如,我有经度 x 和纬度 y。我首先想要所有记录,其经度与 x 最接近,纬度与 y 最接近。我需要从最近到最远的链中的所有记录。位置越远,经纬度的值就会比x和y大。

我希望你明白这一点,我正在等待答案。

【问题讨论】:

    标签: iphone sql gps


    【解决方案1】:

    距离与经纬度不是简单的计算,而是需要球面三角学的。

    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)
    

    所以这个查询

    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    
    

    可能是正确的答案,假设你有一个数学库的能力。

    【讨论】:

    • 您的回答看起来很酷。我数学不太好,但想弄清楚你的问题。你能告诉我为什么你在查询中使用了 Lon/Lat 以外的其他字段吗?
    • 我在上面/下面使用了 Fosco 的基本查询,只是将不同的计算更改为使用球体上的实际距离。您需要一个起点(由 $ID、$LAT 和 $LON 表示)并且我们假设您的点表具有 locID、locName、locDesc、lat 和 lon。您没有提供表定义;如果提供了它,我们会使用一个(提示,提示)。
    【解决方案2】:

    类似于 Fosco,但使用毕达哥拉斯定理:

    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
    

    对于非常大的距离(或远离赤道的位置),您最好使用测地线。

    【讨论】:

      【解决方案3】:

      假设您已经查询了起始位置 lat/lon 和位置 ID...我使用 $LAT、$LON 和 $ID 作为占位符:

      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
      

      希望这会有所帮助...可能不是最优化的方法,但应该非常接近。

      【讨论】:

      • 抱歉,您能解释一下这个查询吗?
      • 它的哪一部分让你感到困惑?内部子查询提取除您要比较的位置之外的所有位置,并从您要比较的位置中减去纬度和经度值。它使用 ABS 函数来获取结果的绝对(非负)值。外部查询只是从按距离排序的内部查询中提取数据。看过之后,我会推荐 Mark Ba​​nnisters 的答案,它使用了更准确的定理。
      【解决方案4】:

      如果您不必处理大距离(请参阅 Adam 的回答),您可以考虑使用 PostgreSQL 的 geometric types 和关联的 functions

      【讨论】:

        【解决方案5】:

        如果您使用的是 Postgresql,请添加 PostGIS 扩展名并查看 ST_Distance_Sphere

        ST_Distance_Sphere — 返回两个 lon/lat 几何图形之间的最小距离(以米为单位)。使用球形地球,半径为 6370986 米。比 ST_Distance_Spheroid 快,但不太准确。 1.5 之前的 PostGIS 版本仅针对点实现。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-09-07
          • 2023-03-13
          • 2018-09-09
          • 2016-05-08
          • 2017-11-10
          • 2021-01-17
          • 1970-01-01
          相关资源
          最近更新 更多