2012-08-27 5 views
29

Ich habe eine Tabelle geofences, die geometry von Polygon speichert.Zwei nächste Punkte auf der Grenze der Postgis-Geometrie

Ich habe auch einen Punkt A, die in der Geometrie ist. Was ich zu tun habe, ist die beiden nächsten Punkte von Punkt A zu finden, die auf der Oberfläche der Polygongeometrie liegen.

Funktion in 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; 

Ich möchte nur zwei Punkte auf der Grenze der Polygongeometrie zu finden. Genau wie ich habe eine von der Frage gefunden:

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; 

Andere dann diesem Punkt Ich habe noch eine finden, mit Abstand größer ist dann der Punkt oben finden, aber kleiner als die übrigen Punkte.

+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 doppelt lon2 = Math.toRadians (77.1232d); \t \t double dellat = (lat2 - lat1); \t \t Doppeldellon = (lon2 - lon1); \t \t doppelt R = 6371; \t \t Doppel 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); \t \t Doppel-c = 2 * (Math.atan2 (Math.sqrt (a), Math.sqrt (1 - a))); \t \t doppelt d = R * c; \t \t System.out.println ("Wert der Entfernung in km =" + d); –

+0

berechnet die Entfernung in Schleife für jeden Punkt von Geometrie mit Punkt A und finden Sie die beiden kleinsten oder minimalen Abstand von allem. –

+0

Wenn Sie nur die Punkte in der Geometrie und nicht die Liniensegmente zwischen Punkten interessieren, können Sie die Grenze des Polygons in ein MULTIPOINT umwandeln, den nächsten Punkt finden, entfernen und dann den zweitnächsten Punkt finden. –

Antwort

0

Verwenden Sie ST_DumpPoints(), um die Punkte des Polygons auszugeben, und wählen Sie dann aus dieser Reihenfolge mit ST_Distance bis A limit 2.?

So ist es so etwas wie

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

(davon ausgegangen, dass dies eine innere select ist, wo Poly das Polygon ist, A der Punkt, zu vergleichen und geom ist die geom Spalte einer der Punkte in der Poly wird verglichen)

+0

Dies wird natürlich nicht Punkte auf einer Linie auswählen, nur die Punkte in der Polygon-Definition. Auch wäre es schneller, wenn man sie einfach am Quadrat der Entfernung ordern könnte. –

0

Im Allgemeinen gibt es keinen zweiten Punkt auf dem Grenzpolygon, wenn Sie die Linien einschließen. Genau wie es keine echte Nummer gibt, die am nächsten an Null ist. Entweder möchten Sie nur die Punkte an den Ecken berücksichtigen, wie Markus es vorschlägt. Oder Sie haben nur einen nächsten Punkt.

0

1) Art eines Links-Feld-Idee, aber die Sekunde -closest Punkt zu Ihrem Ziel zu finden, warum nicht den nächsten Punkt zu dem Punkt finden, die Sie bereits gefunden?

2) Oder mehr Germaine auf Ihre spezielle Frage,

  • die Menge von Punkten innerhalb eines vernünftigen Bereichs des Punktes finden,
  • den Schnittpunkt dieses Satzes mit dem Satz von Punkten finden, die auf das Polygon Grenze; ​​

3) Noch weiter in die linke Feld, Dump einige Ihrer Daten-Sets in Mongo (die ich eine andere PostGIS Funktion sein bin zu raten, kann nicht PostG in eine Weile so bin ich nicht sicher verwendet) und Verwenden Sie die Funktion $ near ... http://docs.mongodb.org/manual/reference/operator/near/

1

Ich gehe davon aus Sie die Kante des Polygons finden möchten, dass die am nächsten an der betreffenden Stelle geht

distance from line problem

Um den Abstand ‚d‘ von Punkt ‚C‘ aus der Leitung zu erhalten [A , B] zunächst alle Punkte so übersetzen A bei 0,0

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

Dann normalisieren B ist, so dass es der Länge 1 ist.0

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

Suche Länge von A, die erhalten zu C

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

nun der Entfernung im rechten Winkel

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

nicht sicher, wie das in SQL zu tun. Sie müssen das oben für jede Kante auf Ihrem Vieleck tun, und dann finden Sie den kleinsten Wert 'd'

Übrigens wird Ihnen das Zeichen des Kreuzprodukts von B und C jetzt sagen, ob der Punkt eingeschaltet ist das Innere des Polygons oder nicht

+0

Ihr Algo ist gut und verständlich, gute Bemühungen von Ihnen, ich würde versuchen, das gleiche in Sql zu verwenden, weil meine Abhängigkeit ist, dass diese Art von Algorithmus nur in SQL implementiert werden soll. –