Höhenbestimmung über Höhenlinien

Hallo Forum,

zum Umfeld meiner Frage: Ich zeichne meine Radtouren mit einem GARMIN Geko 201 GPS Empfänger auf. Dabei sind die Höhenangaben leider nicht sonderlich genau (sehr stark von den Empfangsbedingungen abhängig).
Ich habe bereits eine PostGIS DB mit Höhenlinie (Multiline String) der NASA SRTM2 Daten nach der folgenden Anleitung (Link: Contours - OpenStreetMap)

Jetzt habe ich folgende Idee, ich möchte gerne für jeden GPS Messpunkt die richtige Höhe aus diesen Höhenlinien durch Interpolation bestimmen.

Dazu meine Frage: Gibt es in PostGIS bereits eine Funktion, die für eine beliebige Koordinate die benachbarten Höhenlinien bestimmt und per Interpolation (linear genügt vollkommen) die Höhen bestimmt? Wenn nicht, wie würdet ihr vorgehen.

Gruß, Torsten

PS: Wer meine bisherigen Artikel gelesen hat, weiss das ich einen Denkanstoß suche und meine Ergebnisse hier präsentieren werde…

Hallo!
Du könntest sicher was mit st_distance zusmmenbasteln, das dir die nächstgelegenen Höhenlinien. AFAIR gibt es auch eine Funktion, die einem die kürzeste Distanz zwischen zwei Geometrien bestimmt. Ich hab grad die Doku nicht zur Hand.
Allerdings sind die SRTM-Daten auch nicht sooo höhengenau, ich hatte da auch schon Abweichungen von >9m bezogen auf DGPS im cm-Bereich und terrestrischer Einmessung. Besser als das normale GPS sind sie aber allemal.

Gruß Uwe

Hallo Gisman,

an der Funktion st_distance bin ich auch gerade dran. Da die SRTM Daten im 30m Raster vorliegen ist mir die Ungenauigkeit bewusst. (Wobei die Höhenlinien im 10Hm Abstand berechnet sind)
Die errechneten Werte sind aber immer noch wesentlich besser als die meisten Messergebnisse (in der Höhe) meines GPS Empfängers…
Das von dir vorgeschlagene “Rastern” auf die 10m Höhenlinien gefällt mir trotzdem nicht, damit würde ich z.B. bei sehr flachen Strecken einen deutlichen Stufeneffekt in das Höhenprofil bekommen.
Somit ist es mir eigentlich lieber die beiden benachbarten Höhenlinien zu finden (vereinfacht gesagt links und rechts vom Messpunkt) und über eine Linie (Interpolation) die “Zwischenhöhe” zu bestimmen. Die Bestimmung der Zwischenhöhe kann auch gerne außerhalb der DB geschehen, ich kann Programmieren :wink:
Nur die Klammer im letzen Satz beschreibt mein Problem. Mit st_distance finde ich die nächste Höhenlinen. Die “zweitnächste” Höhenlinie muss aber nicht die Höhen gegenüber der ersten Höhenlinie (von Messpunkt aus betrachtet) definieren.

Gruß, Torsten

Hm, klar, rastern meint ich gar nicht. Aber die Höhen sind ja eh konstant, da reicht ja dann das finden. Ich bin grad wohl ein bisschen 3D :wink:
Eventuell könntest du rechts und links über die Winkeldistanz zwischenden Normalen auf die Höhenlinien unterscheiden. Also >90° = andere Seite. Nur so eine Idee…

Gruß Uwe

Hallo Gisman,

danke für den Tipp.

Den werde ich jetzt weiter verfolgen. Erstmal habe ich mir ein SQL Statement zum Suchen der nächsten Höhenlinien um eine gegebene Koordinate (Punkt) zusammengestellt.

select gid, height, way, ST_Distance(ST_GeometryFromText('POINT(7.182338 50.648059)', 4326), way) as distance
  from contours 
  where ST_DWithin(ST_GeometryFromText('POINT(7.182338 50.648059)', 4326), way, 0.005)
  order by distance

Läst sich bestimmt noch optimieren aber so bekomme ich, in Abhängigkeit des Distanzfaktors in ST_DWithin() [0.005], eine kleinere Menge der benachbarten Höhenlinien. Jetzt ist die Bestimmung der Winkeldistanz nach deinen Vorschlag das nächste Thema.

Gruß, Torsten

Hallo Forum,

nach einer etwas längeren Pause bin ich mal wieder dazu gekommen mich mit dem Thema zu beschäftigen.

Eine gut Angeregung fand ich im Thread http://www.pg-forum.de/postgis/2961-distanzberechnung.html.

Zur Interpolation der Höhe eines einzelnen Messpunkt gehe ich aktuell wie folgt vor:

  1. Bestimmung der Höhenlinien in einen definierten Puffer um den Messpunkt.
  2. Berechnung des auf der Höhenline zum Messpunkt nächsten Punkt (ST_Line_Interpolate_Point).
  3. Berechnung einer Schnittlinie durch die im Punkt 2 bestimmten Messpunkte aller Höhenlinien aus Punkt 1. (Hierbei entsteht allerdings das Problem der Sortierung.)
  4. Berechnung des zum Messpunkt nächsten Punkt auf der Schnittlinie.
  5. Ableiten der Höhe des Punktes aus Punkt 4.

Nach diesen Schritten entsteht das folgende SQL Statement:
(Kann mir mal einer sagen, wie ich die Darstellung des SQL Statements breiter bekommen?)

-- Interpolation der Höhe zum übergebenen Messpunkt (GPS Trackpoint) anhand der SRTM Höhenlinien
SELECT ST_Z(ST_Line_Interpolate_Point(interpolateLine.line, ST_Line_Locate_Point(interpolateLine.line, ST_GeometryFromText('POINT(10.445718 50.7201761)', 4326))))
FROM (
       -- SubSelect berechnet die Schnittline die durch den jeweiligen, auf der Höhenlinien berechneten Punkt führt
    SELECT St_MakeLine(interpolatePoint.point) as line
    FROM (
        -- Berechnet auf jeder Höhenlinie den zum übergebenen Messpunkt nächsten Punkt (ST_Line_Interpolate_Point)
        SELECT ST_SetSRID(ST_MakePoint( X(interpolateContourLinePoint.point), Y(interpolateContourLinePoint.point), interpolateContourLinePoint.height), 4326) as point
        FROM ( 
            -- 
            SELECT ST_Line_Interpolate_Point(contourLines.way, ST_Line_Locate_Point(contourLines.way, point)) as point, contourLines.height as height
            FROM ( 
                -- Sucht alle Höhenlinien, die in einen übergebenen Bereich (Puffer = 0.02) um den Messpunkt liegen
                SELECT height, 
                       ST_Distance(ST_GeometryFromText('POINT(10.445718 50.7201761)', 4326), way) as distance, 
                       -- Tabelle contours enthält MULTILINES -> Umwandlung nach LINE
                       linemerge(way) as way
                FROM contours
                WHERE ST_DWithin(ST_GeometryFromText('POINT(10.445718 50.7201761)', 4326), way, 0.02)
            ) as contourLines,
              ST_GeometryFromText('POINT(10.445718 50.7201761)', 4326) as point
        ) as interpolateContourLinePoint
    ) as interpolatePoint
) as interpolateLine

Ich habe allerdings noch ein Problem mit der Sortierung der gefunden Höhenlinien, welches die folgende Abbildung verdeutlicht.

Die gefundenen Höhenlinien werden wie sie aus der Datenbank kommen einfach miteinander verbunden. Ich benötige aber eine Sortierung so das benachbarte Höhenlinien miteinander verbunden werden.

Hat jemand eine Idee? Ich komme hier gedanklich einfach nicht weiter. Ein einfaches ORDER BY distance reicht nicht.

Gruß, Torsten