2012-08-27 8 views
29

geometry poligonunu saklayan bir tablo geofences var.Postgis geometrisinin sınırı üzerinde en yakın iki nokta

Ayrıca geometrinin içinde yer alan bir A noktam var. Yapmam gereken şey, çokgen geometrisinin yüzeyinde duran A noktasından en yakın iki noktayı bulmak. PostGIS içinde

Fonksiyon:

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; 

Sadece poligon geometrisi sınırda iki noktayı bulmak istiyoruz. Tıpkı sorgudan biri bulmuş gibi: Diğer

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; 

sonra ben bu nokta nokta yukarıda bulmak sonra daha büyük ama noktalarının kalanı daha sonra daha küçük bir mesafe ile bir daha bulmak için.

+0

çift lat1 = Math.toRadians (26.5534d); \t \t çift lon1 = Math.toRadians (75.4925d); \t \t çift lat2 = Math.toRadians (28.3650d); \t \t çift lon2 = Math.toRadians (77.1232d); \t \t çift dellatin = (lat2 - lat1); \t \t çift dellon = (lon2 - lon1); \t \t çift R = 6371; \t \t double = 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); \t \t çift c = 2 * (Math.atan2 (Math.sqrt (a) Math.sqrt (1 - a))); \t \t çift d = R * c; \t \t System.out.println ("km olarak mesafe değeri =" + d); –

+0

, nokta A ile geometriden her nokta için ilmek arasındaki mesafeyi hesapladı ve her şeyden en az iki asgari mesafeyi buldu. –

+0

Yalnızca geometride bulunan noktaları değil, noktalar arasındaki çizgi kesimlerini önemsiyorsanız, çokgenin sınırını MULTIPOINT olarak dönüştürebilir, en yakın noktayı bulabilir, kaldırabilir ve ikinci en yakın noktayı bulabilirsiniz. –

cevap

0

Çokgenin noktalarını dökmek için ST_DumpPoints() öğesini kullanın, ardından ST_Distance tarafından A limitine 2. sırayla seçin.

Yani

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

(gibi bir şey bu poli çokgen olduğu bir iç seçme, A karşılaştırmak için noktasıdır ve geom noktaların birinin geom sütun olduğunu varsayar olduğunu karşılaştırıldıkları gibi)

+0

bu, bir satırdaki noktaları değil, yalnızca çokgen tanımındaki noktaları seçmez. Ayrıca, mesafenin karesiyle sipariş ederseniz daha hızlı olurdu. –

0

Hatları dahil ederseniz, genellikle sınır poligonunda ikinci bir en yakın nokta yoktur. Sanki sıfıra en yakın gerçek sayı yokmuş gibi. Ya sadece Markus'un önerdiği gibi köşedeki noktaları dikkate almak istersiniz. Veya sadece en yakın bir noktanız var.

0

1) Soldaki bir alanın türü, ancak hedefinize doğru ikinci - bağlantı noktasını bulmak için, neden bulunduğunuz noktaya en yakın noktayı bulamıyorsunuz?

  • üzerinde bulunan noktalar seti ile bu setin kavşak bulmak

    • noktasının bazı makul aralığında noktalarının kümesini bulmak,

      2) Ya da, belirli soruların daha germaine, poligon sınır;

    3) Daha uzak sol alana, Mongo içine veri kümesi bazı dökümü (başka PostGIS fonksiyonu olabilir tahmin ediyorum bu yüzden emin değilim bir süredir Postg kullanmadım) ve $ near fonksiyonunu kullan ... http://docs.mongodb.org/manual/reference/operator/near/

  • 1

    I söz

    distance from line problem

    hattından alanına 'C' mesafe 'd' elde etmek için, [A noktasına en yakın geçer köşegenin kenarını bulmak istiyoruz varsayarak A, uzunluğu 1 olacak şekilde o B normalize 0,0

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

    üstünde olacak şekilde, B] Öncelikle noktalarını çevirmek.C

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

    dik açıda olan A'dan 0

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

    Bul uzunluğu Şimdi mesafeyi

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

    SQL bunu nasıl emin değilim olsun. Çokgeninizdeki her kenar için yukarıdakileri yapmanız ve daha sonra 'd'

    en küçük değerini bulmanız gerekir. Böylece, B ve C'nin çapraz ürününün işareti şimdi noktanın açık olup olmadığını söyleyecektir. çokgen içi ya da

    +0

    Algo'nuz iyi ve anlaşılabilir, sizin için iyi bir çabadır, Sql'de aynısını kullanmaya çalışacağım çünkü bağımlılığım sadece bu tür bir algoritmanın sql'de uygulanmasını sağlamaktır. –