2012-08-27 48 views
29

我有一個表geofences,它存儲了多邊形的geometryPostgis幾何邊界上的兩個最近點

我也有一個點A這是幾何內。我需要做的是找到位於多邊形幾何體表面上的點A的兩個最近點。

功能在PostGIS的:

CREATE OR REPLACE FUNCTION accuracyCheck(Polygon geometry 
             ,decimal lat 
             ,decimal lon) 
    RETURNS VARCHAR AS 
$BODY$ 

DECLARE height DECIMAL; 
DECLARE accuracy VARCHAR(250); 

BEGIN 

CREATE TEMPORARY TABLE closePointStorage AS 
SELECT ST_AsText(ST_ClosestPoint(geometry 
           ,ST_GeomFromText('POINT(lat lon)',0) 
           ) 
       ) AS closestPoint 
FROM (
    SELECT ST_GeomFromText(geometry) as geometry 
    FROM gfe_geofences 
    WHERE is_active=true 
    ) As tempName; 

CREATE TEMPORARY TABLE areaStorage ON COMMIT DROP AS 
SELECT ST_Area(ST_GeomFromText('Polygon((23.0808622876029 96.1304006624291 
             ,28.0808622876029 99.1304006624291 
             ,100    200 
             ,23.0808622876029 96.1304006624291 
             ))' 
           ,0) 
      ) AS area; 

CREATE TEMPORARY TABLE distanceStorage ON COMMIT DROP AS 
SELECT ST_Distance(
      ST_GeomFromText('POINT(23.0808622876029 96.1304006624291)',-1) 
     ,ST_GeomFromText('POINT(28.0808622876029 99.1304006624291)',-1) 
     ) AS distance; 

height = (SELECT area FROM areaStorage) 
     /(0.5*(SELECT distance FROM distanceStorage)); 

IF height < (SELECT radius_meters 
      FROM gfe_geofences Where is_active=true) THEN 
    accuracy = "FullConfirm"; 
    RETURN accuracy; 
ELSE 
    accuracy = "PartiallyConfirm"; 
    RETURN accuracy; 
END IF; 

END; 
$BODY$ LANGUAGE plpgsql; 

我只是想找到多邊形形狀的邊界兩分。就像我已經找到一個從查詢:

CREATE TEMPORARY TABLE closePointStorage AS 
SELECT ST_AsText(ST_ClosestPoint(geometry 
           ,ST_GeomFromText('POINT(lat lon)',0) 
           ) 
       ) AS closestPoint 
FROM (
    SELECT ST_GeomFromText(geometry) as geometry 
    FROM gfe_geofences 
    WHERE is_active=true 
    ) 
AS tempName; 

其他然後這一點我必須找到一個更隨距離大於點發現以上,但隨後小點的休息。

+0

double lat1 = Math.toRadians(26.5534d); \t \t double lon1 = Math.toRadians(75.4925d); \t \t double lat2 = Math.toRadians(28.3650d); \t \t double lon2 = Math.toRadians(77.1232d); \t \t double dellat =(lat2 - lat1); \t \t double dellon =(lon2 - lon1); \t \t double R = 6371; \t \t雙A = Math.sin((dellat)/ 2)* Math.sin((dellat)/ 2) \t \t \t \t + Math.cos(LAT1)* Math.cos(LAT2)* Math.sin ((dellon)/ 2) \t \t \t \t * Math.sin((dellon)/ 2); (數學公式2(Math.sqrt(a),Math.sqrt(1-a))); \t \t double d = R * c; System.out.println(「km的距離值=」+ d); –

+0

計算了從A點到幾何點的每個點的循環距離,並找出距離所有點的最小或最小距離。 –

+0

如果您只關心幾何體中的點,而不關心點之間的線段,則可以將多邊形的邊界轉換爲MULTIPOINT,找到最近的點,將其移除,然後找到第二個最近的點。 –

回答

0

使用ST_DumpPoints()轉儲多邊形的點,然後通過ST_Distance選擇該順序爲限制2。

因此,它是像

SELECT * from ST_DumpPoints(poly) order by ST_Distance(A,geom) asc limit 2; 

(假定這是一個內部的選擇,其中多是多邊形,是比較點和GEOM是在該點之一的GEOM列poly被比較)

+0

這當然不會在一條線上選取點,只會選取多邊形定義中的點。如果你可以用距離的平方來排序,它也會更快。 –

0

如果包含線,那麼通常在邊界多邊形上沒有第二近點。就像沒有第二個接近於零的實數一樣。 要麼你只是想考慮在角落的點,就像馬庫斯建議的那樣。 或者你只有一個最近的點。

0

1)一種左場的想法,但找到第二個 - 最接近您的目的地,爲什麼不找到最接近你已經找到的點?

2)或者,更傑曼到您的具體問題,

  • 找到一點有一些合理的範圍之內的點的集合,
  • 發現集合的交集與設定躺在點多邊形邊界(我猜可能是另一個PostGIS的功能;沒有使用postG在一段時間,所以我不知道)

3)到更遠的左場,傾倒你的一些數據集到蒙戈和使用$ near功能... http://docs.mongodb.org/manual/reference/operator/near/

1

我假設你想找到一個通過了問題

distance from line problem

要獲得線點「C」的距離「d」 [A最接近點的多邊形的邊,B] 首先翻譯所有點使A爲0,0

B -= A //vector subtraction 
C -= A 

然後正常化乙所以它是長度爲1。從A 0

len = sqrt(B . B) //dotproduct of two vectors is the length squared 
B /= len //scalar divide by length 

查找長度成直角到C

dotp = B . C //dot product again 
closestPointOnLine = B * dotp //scalar multiply 

現在得到的距離

diff = (C - ClosestPointOnLine) 
d = sqrt(diff . diff) 

不知道如何做,在SQL。你需要爲你的多邊形上的每個邊做上述操作,然後找到最小值'd'。

順便說一句,B和C的叉積的符號現在會告訴你該點是否開啓多邊形的內部或不是

+0

你的算法很好,可以理解,你很努力,我會嘗試在Sql中使用相同的,因爲我的依賴是將這種算法僅在sql中實現。 –