【问题标题】:SQL Network Length Calculation Lon/LatSQL 网络长度计算 Lon/Lat
【发布时间】:2020-09-07 18:51:30
【问题描述】:

我目前有一个包含 openstreetmap 数据的 Azure postgresql 数据库,我想知道是否有一个 SQL 查询可以通过使用方式使用的节点的纬度/经度来获取方式的总距离。

我希望 SQL 查询返回 way_id 和距离。

我目前的方法是使用 C# 将所有路径和所有节点下载到字典中(它们的 id 是关键)。然后我遍历所有方式,将属于该方式的所有节点分组,然后使用它们的纬度/经度(值除以 10000000)来计算距离。这部分作为例外工作,而是在服务器上完成。

我尝试的 SQL 如下,但我坚持根据纬度/经度计算单程的总距离。

更新: Postgis 扩展已安装。

SELECT current_ways.id as wId, node_id, (CAST(latitude as float)) / 10000000 as lat, (CAST(longitude as float)) / 10000000 as lon FROM public.current_ways
JOIN current_way_nodes as cwn ON current_ways.id = cwn.way_id
JOIN current_nodes as cn ON cwn.node_id = cn.id

*output*
wId node_id latitude    longitude
2   1312575 51.4761127  -3.1888786
2   1312574 51.4759647  -3.1874216
2   1312573 51.4759207  -3.1870016
2   1213756 51.4758761  -3.1865223
3   ....

*desired_output*
way_id  length
2   x.xxx
3   ...

**Tables**
current_nodes
    id
    latitude
    longitude

current_ways
    id

current_way_nodes
    way_id
    node_id
    sequence_id         

【问题讨论】:

  • C# 方法也是错误的。与其自己动手,不如使用像 NetTopologySuite/ProjNet4GeoAPI 这样的空间库来处理投影、空间参考系统等。没有这个,你计算的距离将是错误的。 EF Core 使用 NetTopologySuite 从 PostgreSQL 和 SQL Server 加载空间数据。
  • 数据库本身的空间支持由 PostGIS 扩展添加
  • grouping all the nodes that belong to that way and then use their lat/longs to calculate the distance 听起来您将线(线串)存储为单个点,而不是使用空间库和系统理解的a standardized form。空间库可以直接告诉您线串的长度。更高级的功能可以告诉您多条线是否相交,或者哪些是最近的线等
  • 感谢您的回复。 C# 方法工作正常。您必须将这些值除以 10000000 以获得真实值,然后使用一些复杂的数学来获得真实距离。更多的是在服务器上进行。
  • 我已经更新了 SQL 和结果,因为另一个 SO 主题显示了如何计算值。再次感谢。

标签: sql postgresql geospatial postgis openstreetmap


【解决方案1】:

如果您的表中也有 geometry 会更简单,即实际点而不是坐标,或者更好的是实际线。

话虽如此,这里有一个查询来获取您要查找的内容:

SELECT w.way_id,
    ST_Length( -- compute the length
      ST_MAKELINE( --of a new line
        ST_SetSRID( --made of an aggregation of NEW points
          ST_MAKEPOINT((CAST(longitude as float)) / 10000000,(CAST(latitude as float)) / 10000000), --created using the long/lat from your text fields
        4326)  -- specify the projection 
       ORDER BY w.sequence_id -- order the points using the given sequence
       )::geography --cast to geography so the output length will be in meters and not in degrees
    ) as length_m
FROM current_way_nodes w
    JOIN current_nodes n ON w.node_id = n.node_id
GROUP BY w.way_id;

【讨论】:

  • 我将“JOIN current_nodes n ON w.node_id = n.node_id”更改为“JOIN current_nodes n ON w.node_id = n.id”,效果很好!谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-04-04
  • 2018-09-05
  • 1970-01-01
  • 2013-01-26
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 2019-02-04
相关资源
最近更新 更多