簡體   English   中英

為什么 PostGIS 將所有點堆疊在一起? (使用 ST_DWithin 查找半徑 1000m 內的所有結果)

[英]Why is PostGIS stacking all points on top of each other? (Using ST_DWithin to find all results within 1000m radius)

PostGIS/PostgreSQL 的新手...任何幫助將不勝感激!

我在 postgres 數據庫中有兩個表,別名分別為 gas 和 ev。 我正在嘗試選擇一個特定的加油站 (gas.site_id=11949) 並在 1000m 半徑內找到所有 EV/替代燃料充電站。 但是,當我運行以下命令時,PostGIS 會返回許多在地圖中堆疊在一起的 ev 站(請參見屏幕截圖)。

任何人都知道為什么會這樣? 如何讓 PostGIS 可視化指定加油站 1000m 半徑內的點?

with myplace as (
  SELECT gas.geom 
  from nj_gas gas 
  where gas.site_id = 11949 limit 1)
select myplace.*, ev.* 
from alt_fuel ev, myplace 
where ST_DWithin(ev.geom1, myplace.geom, 1000)

在此處輸入圖片說明

函數ST_DWithin不使用geometry類型參數計算以米為單位的距離。

從文檔:

對於幾何:距離以幾何空間參考系統定義的單位指定。 為了使此函數有意義,源幾何圖形必須具有相同的坐標投影,具有相同的 SRID。

因此,如果您想以米為單位計算距離,則必須使用數據類型geography

對於地理單位以米為單位,測量默認為 use_spheroid=true,為了更快檢查,use_spheroid=false 沿球體測量。

話雖如此,您必須轉換幾何的數據類型。 除此之外,您的查詢看起來還不錯-考慮到您的數據是正確的:-)

WITH myplace as (
  SELECT gas.geom 
  FROM nj_gas gas 
  WHERE gas.site_id = 11949 LIMIT 1)
SELECT myplace.*, ev.* 
FROM alt_fuel ev, myplace 
WHERE ST_DWithin(ev.geom1::GEOGRAPHY, myplace.geom::GEOGRAPHY, 1000)

樣本數據:

CREATE TABLE t1 (id INT, geom GEOGRAPHY);
INSERT INTO t1 VALUES (1,'POINT(-4.47 54.22)');

CREATE TABLE t2 (geom GEOGRAPHY);
INSERT INTO t2 VALUES ('POINT(-4.48 54.22)'),('POINT(-4.41 54.18)');

詢問

WITH j AS (
  SELECT geom FROM t1 WHERE id = 1 LIMIT 1)
SELECT ST_AsText(t2.geom) 
FROM j,t2 WHERE ST_DWithin(t2.geom, j.geom, 1000);

     st_astext      
--------------------
 POINT(-4.48 54.22)
(1 Zeile)

您正在交叉加入這些表,並讓 PostgreSQL 在選擇myplace.* & ev.*時返回兩者的笛卡爾積。

因此,雖然myplace只有一行, myplace它的geom將與alt_fuel每一行合並(即結果集將在兩者每種可能組合中包含兩個表的所有列); 由於結果集因此有兩個幾何列,您的客戶端應用程序可能會選擇第一個或名為geom (而不是alt_fuel.geom1 )的列來顯示!

我看不出你對結果集中的myplace.geom感興趣,所以我建議運行

WITH
  myplace as (
    SELECT gas.geom 
    FROM   nj_gas gas 
    WHERE  gas.site_id = 11949
    LIMIT  1
  )

SELECT ev.* 
FROM   alt_fuel AS ev
JOIN   myplace AS mp
  ON   ST_DWithin(ev.geom1, mp.geom, 1000)  -- ST_DWithin(ev.geom1::GEOGRAPHY, mp.geom::GEOGRAPHY, 1000)
;

如果出於某種原因,您還想將myplace.geom與站一起顯示,則必須在myplace上使用SELECT *對上述內容進行UNION[ ALL] 請注意,您還必須在該SELECTalt_fuel.*相同的列列表和結構(相同的數據類型!)(或者更好, UNION[ ALL]另一側)!


請注意@JimJones關於單位的建議 如果您的數據不是在基於的 CRS 中投影的(而是在地理參考系統中;“LonLat”),請使用GEOGRAPHY ST_DWithin轉換讓ST_DWithin將輸入視為(並使用球體代數而不是平面(歐幾里得)進行計算) !

通過使用解決:

WITH
  myplace as (
    SELECT geom as g
    FROM   nj_gas  
    WHERE  site_id = 11949 OR site_id = 11099 OR site_id = 11679 or site_id = 480522
  ), myresults AS (
SELECT ev.* 
FROM   alt_fuel AS ev
JOIN   myplace AS mp
  ON   ST_DWithin(ev.geom, mp.g, 0.1))
select * from myresults```

Thanks so much for your help @ThingumaBob and @JimJones ! Greatly appreciate it.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM