[英]Postgis ST_DWithin match a certain radius AND points on the right
[英]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]
; 請注意,您還必須在該SELECT
與alt_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.