postgis 中的距離計算


最近在做一個項目,有一個功能想要實現類似於查詢附近的人的功能。由於項目的原因數據庫只能使用 postgresql,空間查詢就使用了 postgis 來實現。

具體業務像這樣:業務需要返回附近距自己 1000 米的人的一個列表,返回列表中要帶上距離,就是說某人距你多少米?

使用定位方式是什么?

我們使用 gps 定位發現定位精度,時間,誤差和抖動都需要發大量的時間去處理。

於是采用了百度的定位 SDK,百度的上面幾處都處理不錯。

有一個小問題,從百度拿到的坐標是 經度和緯度,這個坐標系應該是地理坐標,由於也是使用 gps ,其基礎坐標應該是 wgs84。所以拿到的值應該是:wgs84 + 國家偏移 + 百度偏移 = 百度坐標

后面兩項是沒有太好的辦法解決,我們拿百度坐標與 google 的大致對比了一下,誤差 50 米以內,業務可以接受。

而且這個后面兩項是系統偏移,不是隨機的,這樣的話,計算距離這種相對計算,應該可以消除部分系統偏移的影響。

再說說postgis 計算距離

postgis 是一個地理空間查詢引擎,計算地理距離這很方便。

  1. 開始我們在表中建一列用於存地理類型的 geometry
SELECT AddGeometryColumn ('public','chest','position',4326,'POINT',2, false);
  1. 然后保存的時候,將 經緯度和 經緯度變成 geometry 進行保存,也就是三個字段,其中保存 geometry 是用下面的sql
ST_GeomFromText('POINT(${lng} ${lat})', 4326)

sql 中的 4326 是指的wsg84 的系統。

  1. 然后對保存后的值進行距離查詢,使用 ST_distance 進行,后面有二個坑等着我們:

第一個:geometry 的問題

postgisgeomery 使用 ST_distance 計算出來的單位竟然是弧度,不是 ,找了一段時間問題,發現是沒有使用投影坐標引起的。

於是在計算的時候,先將 變成 投影坐標,再來計算。

ST_Transform(geo, 2346)

這里的 2346中國西安 80 高斯克里格投影的編號,是分帶的,使用的中央經線在南京。

加上這個,我們能正確計算出來距離,也是

然后,一段時間后,把應用發到別的城市,也就是蘇州,出現了問題

第二個: 投影帶號的問題

原因是蘇州不在 2346 中的帶號里面,計算就出錯了!

這樣就有問題了,全國這么多的帶號,不可能寫在程序里,動態計算啊?再說萬一出國了,沒有中國的投影怎么辦?

回頭再去找方案,這個計算距離應該要支持最低就是全國,最好是全世界。

還真找到了,就是 geography

解釋一下: geographygeometry 都是 postgis 中的數據類型,翻繹過來:地理圖形和幾何圖形,用 postgis 的說法就是, geography 就是使用 wgs84 坐標系 的圖形。

postgis 可以直接使用 geography 進行計算,支持全球。於是這個問題,終於有解決方案了,就是把我們的 geometry 轉成 geography ,然后進行距離計算。

下面是我們使用 sql 語句

   select
    (ST_distance(position::geography, ST_GeomFromText('POINT(121 32)', 4326)::geography) as distance
   from chest
   where ST_dwithin(position::geography, ST_GeomFromText('POINT(121 32})', 4326)::geography, 1000)
   orderBy distance desc

其中:position 是我存在數據庫中的字段,使用的是 geometry 的類型, (121,32 )是我輸入的中心點。
::geography 就是postgis 中的 轉換類型語法,把 geometry 轉成 geography,然后計算,這樣全球都能使用。

總結

這些問題的解決,算是把以前的知識在復習了一下。 在項目中,我們也可以直接把坐標存成 geography,使用如下的 sql

ST_GeographyFromText('SRID=4326;POINT(-110 30)')

數據就不用轉來轉去了。

只是項目已有數據,不能這樣做了。

參考文檔

PostGIS-04.md
Geography


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM