【问题标题】:PostGis Distance CalculationPostGis距离计算
【发布时间】:2014-08-28 17:48:39
【问题描述】:

我现在正在做一个室内地图导航应用程序,我想做的是在建筑物中建立一个地图点数据库。

我使用的所有坐标均取自谷歌地图(这意味着 EPSG 为 3857)。我现在需要做的是以米为单位的距离以及以米为单位使用 D_Within

当我尝试提取 2 点之间的距离时:

SELECT ST_DISTANCE(
ST_GeomFromText('POINT(' || StartLon || ' ' || StartLat || ')',3857),
ST_GeomFromText('POINT(' || EndLon || ' ' || EndLat || ')',3857))
FROM i3_building.floordata;

对于前 2 行:

Start: 103.776047 1.292149; End: 103.77607 1.292212 (3 meters away)
Start: 103.776070 1.292212; End: 103.77554 1.292406 (50 meters away)

给出的结果是:

2.59422435413724e-005
4.11096095831604e-005

即使它们在 rad 中,第二个结果也只是第一个结果的两倍。所以这让我很困惑。 然后我尝试将其输出为米:

SELECT ST_DISTANCE(
    ST_GeographyFromText('POINT(' || StartLon || ' ' || StartLat || ')'),
    ST_GeographyFromText('POINT(' || EndLon || ' ' || EndLat || ')'))
FROM i3_building.floordata;

相同行给出的结果是:

2.872546829
4.572207435

这也不是我所期望的。 我对 PostGis 和 SRID 不是很熟悉,所以这个问题可能看起来很简单,但请帮帮我,我不知道@@

【问题讨论】:

    标签: postgresql distance postgis srid epsg


    【解决方案1】:

    您的坐标参考系 (CRS) 是 4326,纬度/经度。这是与 Google Maps 混淆的常见来源:3857 是 Google Maps 用于其图块的 CRS,并且是基于球形地球的投影米。添加到 Google 地图中的矢量源(KML 数据、GPS 转储等)往往采用纬度/经度 4326,以度为单位进行测量并即时转换。

    如果您想要两个纬度/经度点之间的距离(以米为单位),请使用ST_Distance_Sphere。例如,对于您的第一组点,

    SELECT ST_Distance_Sphere(ST_MakePoint(103.776047, 1.292149),ST_MakePoint(103.77607, 1.292212));
    

    给出 7.457 米。根据相同的查询,您的第二组点彼此相距 62.74 米。

    注意还有ST_Distance_Spheroid,它采用第三个参数,测量球体,即地球形状的近似值。这可能会更准确,但在小距离内可能并不重要。

    ST_Distance 以投影坐标给出距离,这可能就是插入纬度/经度值得到奇怪结果的原因。

    编辑: 如 cmets 中所述,从 Postgis 2.2 开始,此函数被重命名为 ST_DistanceSphere

    【讨论】:

    • 感谢您的回复。 4326我也试过,但和3857差别不大。第一组的距离是3米,因为在我的办公室里,所以我很了解。我也尝试从这里计算它:boulter.com/gps/distance - 结果相同,3 米。
    • 差别不大是什么意思?我想说 7.45 米和 62.74 是完全不同的。但是,问题在于 st_distance_sphere,因为它采用纬度/经度输入,其中 st_distance 采用投影坐标中的距离。 3857 和 4326 完全不同,分别是米和度,但你必须将它们插入正确的函数才能得到正确的答案:D
    • 不好意思,出去测一测,7米左右比较合适。感谢您的帮助:)
    • @ThomasDang。如果您想要非常准确,请使用 st_distance_spheroid,但 st_distance_sphere 对于小距离应该可以正常工作。我没有意识到马尼拉离赤道这么近。
    • 从 postgis 版本 2.2.0 开始,函数名称“ST_Distance_Sphere”已更改为“ST_DistanceSphere”(下划线已删除)。参考:postgis.net/docs/ST_DistanceSphere.html
    【解决方案2】:

    这是伪代码

    SELECT ST_Distance_Sphere(ST_MakePoint(lng1, lat1),ST_MakePoint(lng2, lat2));
    

    另外,对于球体距离,新函数“ST_DistanceSphere”使用以下

    SELECT ST_DistanceSphere(ST_MakePoint(lng1,lat1),ST_MakePoint(lng2,lat2)) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-17
      • 2014-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      相关资源
      最近更新 更多