2017-02-21 6 views
0

Ich versuche, einen REST-Dienst zu erstellen, der eine Liste der nach Entfernung von der Benutzerkoordinate sortierten Orte zurückgibt. Ich habe diese Abfrage mit postgis gefunden:Postgis nächstgelegene Koordinaten

Aber ich bin nicht in der Lage, dies auf meine eigentliche Datenbank anzuwenden. Ich habe eine Tabelle, die diese Spalten enthält:

title, address, description, latitude, longitude 

alle diese Werte als Strings.

Ich werde sehr glücklich sein, wenn mir jemand hilft. Danke!

+0

hast du nicht geom field auf deinem tisch? –

+0

['<->'] (http://postgis.net/docs/geometry_distance_knn.html) * Für PostgreSQL unter 9.5 gibt nur den Schwerpunktabstand der Begrenzungsrahmen und für PostgreSQL 9.5+, gibt die echte KNN-Abstandssuche den wahren Abstand zwischen Geometrien wieder, und Entfernungskugel für Geographien. * – pozs

Antwort

2

Ich weiß nicht warum, aber ORDER BY <-> ist nicht genau. Irgendwann ist der nächste Link auf der 3. Position. Also bekomme ich 101 Element und benutze dann die Distanz, um die nächste auszuwählen.

CREATE OR REPLACE FUNCTION map.get_near_link(
    x numeric, 
    y numeric) 
    RETURNS TABLE(Link_ID int, distance int) AS 
$BODY$ 
DECLARE 
    strPoint text;  
    BEGIN 
    strPoint = 'POINT('|| X || ' ' || Y || ')'; 

    With CTE AS (
     SELECT Link_ID, 
       TRUNC(ST_Distance(ST_GeomFromText(strPoint,4326), geom )*100000)::integer as distance    
     FROM map.vzla_seg S 
     ORDER BY 
       geom <-> ST_GeomFromText(strPoint, 4326) 
     LIMIT 101 
    ) 
    SELECT * 
    FROM CTE 
    ORDER BY distance 
    LIMIT 5 
+0

+1; das ist wirklich nah an dem ["hybrid query" Beispiel in den Dokumenten] (http://postgis.net/docs/geometry_distance_knn.html) über die Handhabung des '<->' Operators vor 9.5. – pozs

+0

Danke @ Pozs. Jetzt weiß ich, warum die 'order <->' nicht genau ist. Weil 'Für PostgreSQL unter 9.5 nur den Schwerpunktabstand von Begrenzungsrahmen angibt und für PostgreSQL 9.5+, gibt die echte KNN-Abstandssuche den wahren Abstand zwischen Geometrien und den Entfernungsbereich für Regionen an. Ich hatte 9.4 bis vor kurzem. –

+0

@pozs Interessant, dass sie die Funktion 'ST_GeomFromText' nicht mehr verwenden. Übergeben Sie die Zeichenfolge einfach an Geometrie. Ich denke, ich werde älter :( –

1

Um PostGIS zu verwenden, müssen Sie die Erweiterung in der Datenbank aktivieren. Im Idealfall führen Sie einfach den Befehl CREATE EXTENSION postgis; aus und es funktioniert. HINWEIS Form der Installationsseite: Installieren Sie es nicht in der Datenbank namens Postgres. Für weitere Informationen besuchen Sie die site.

eine Geometriespalte Hinzufügen zu Ihrem Tisch (räumliche Daten können in dieser Art von Spalten gespeichert werden):

SELECT AddGeometryColumn(
    'your_schema', 
    'your_table', 
    'geom', -- name of the column 
    4326,  -- SRID, for GPS coordinates you can use this, for more information https://en.wikipedia.org/wiki/Spatial_reference_system 
    'POINT', -- type of geometry eg. POINT, POLYGON etc. 
    2   -- number of dimension (2 xy - 3 xyz) 
); 

UPDATE yourtable t SET t.geom = ST_SetSRID(ST_MakePoint(t.x, t.y), 4326) 
-- the x and y is the latitude and longitude 

Jetzt können Sie räumliche Abfragen auf dem Tisch wie folgt verwenden:

SELECT 
    * 
FROM 
    your_table 
ORDER BY 
    your_table.geom <-> ST_SetSRID(ST_MakePoint(x, y), 4326) 
LIMIT 5; 

HINWEIS: wie andere erwähnt, unten PostgreSQL 9.5 < -> ist nicht immer zuverlässig.

+0

Sehr thx Sie hat mir sehr geholfen ich einige Verbesserungen auf Abfrage gemacht Was Sie denken, tun:..!. SELECT *, ST_Distance_Sphere (ST_MakePoint (Längengrad Grad, Breitengrad), ST_MakePoint (-46,4890173, -23,5185825)) als Abstand VON myTable ORDER BY Abstand LIMIT 5; ' – aKANJ

+0

Ja das' ST_Distance_Sphere' bietet Ihnen eine gute Lösung (wenn Sie nicht sehr genaue Entfernungen brauchen) .Leider habe ich in meiner Antwort vergessen zu erwähnen, dass der 'ST_Distance' oder der' <->' keine gute Methode ist, Entfernungen zu messen, wenn Sie die SRID 4326 verwenden. – banazs