Segmentierung von Linien in PostGIS

Segmentierung von Linien (LineString) in PostGIS

Für die Verarbeitung von linearen Geometrien kann es notwendig sein, dass diese zerteilt werden. Vorstellbar wäre die teilweise Übertragung zu einem anderen System im Rahmen von Vektordatenrendering oder die Analyse von Segmenten (Kurvenradien).

Lange Streckenzüge wie Küstenlinen, Bahngleise oder Straßen liegen oft in einer Datenbank für Geodaten vor und sollten auch direkt dort segmentiert werden. Postgres in Kombination mit PostGIS ist eine solche Datenbank, die aber leider keine Implementierung zur Segmentierung in fixe Längen mitbringt.

Wir gehen im Folgenden davon aus, dass ein Streckenzug in Segmente gleicher Länge zerteilt werden soll. Grundlage der Implementierung sind die Funktionen ST_Line_Substring (Segmentierung in Anteile der Gesamtlänge) und ST_Length (Ermittlung der Gesamtlänge) für die Verarbeitung von Linen. Problematisch ist hierbei, dass für beliebige Linien weder die Anzahl der Segmente noch die Länge des Endstücks bekannt ist. Beispielsweise entstehen bei der Segmentierung einer 117m langen Strecke in 10m Segmente insgesamt 12 Segmente, davon eins mit einer Länge von nur 7m.

Die nachstehende Funktion zerteilt eine Line in Segement der gegebenen Länge. Die Angabe der Länge erfolgt dabei in den Einheiten des Referenzsystems der Geometrie, also in vielen Referenzsystemen in Metern.

CREATE OR REPLACE FUNCTION split_equal_length(p_geom geometry, p_target_length numeric)  
  RETURNS SETOF geometry AS  
$BODY$  
begin  
    return query select st_line_substring(p_geom, segment_start_fraction, segment_end_fraction)  
    from (  
        select (segment_number-1)\*ordinary_segment_length as segment_start_fraction, case when is_last then 1 else segment_number\*ordinary_segment_length end as segment_end_fraction  
        from (  
            select *, case when last_segment_number=1 then target_length else last_segment_start_fraction/(last_segment_number-1) end as ordinary_segment_length  
            from (  
                select *, is_last and (total_length%target_length>0) as is_short, 1-((total_length-((last_segment_number-1)\*target_length))\*(1/total_length)) as last_segment_start_fraction  
                from (  
                    select *, segment_number=last_segment_number as is_last  
                    from (  
                        select *, generate_series(1, ceil(total_length/target_length)::integer) as segment_number,  
                            ceil(total_length/target_length)::integer as last_segment_number  
                        from (  
                            select st_length(p_geom)::numeric as total_length, p_target_length::numeric as target_length  
                        ) input_data  
                    ) test  
                ) test  
            ) test  
        ) split_parameters  
    ) split_parameters;  
END;  
$BODY$  
  LANGUAGE plpgsql IMMUTABLE STRICT  
  COST 100  
  ROWS 1000;
geschrieben von Friedjoff Trautwein | 7.4.2012
Mehr zum Thema
3 min Lesezeit | Blog

performance.now()

Zwei Frontend-Entwickler von geOps machten sich nach Amsterdam auf, um an der performance.now() teilzunehmen, einer zweitägigen Konferenz mit vierzehn erstklassigen Sessions, die die wichtigsten Erkenntnisse zur Web-Performance von heute behandeln.

weiterlesen
6 min Lesezeit | Blog

Webkarten als PDF exportieren und drucken

Schon seit einiger Zeit bieten einige unserer Apps den Export unserer Karten im PDF-Format. Dieser Artikel stellt unsere Lösungen für diverse Neuerungen dieser Funktion vor.

weiterlesen
9 min Lesezeit | Blog

Snapping stops to vehicle trajectories

How to snap points to a line string in a given order and what it has to do with quality assurance when importing public transport schedules.

weiterlesen
7 min Lesezeit | Blog

Using Redis Subscriptions efficiently in Python

Inspired by the websockets broadcast feature we built a subscription multiplexer for redis subscriptions to subscribe to Redis channels and patterns once for all relevant clients.

weiterlesen
2 min Lesezeit | Blog

GraphQL - Hackathon 2022

Mitglieder des geOps-Entwicklerteams erforschen GraphQL in einem internen Hackathon, um dessen Potenzial für geOps-Projekte zu entdecken.

weiterlesen
2 min Lesezeit | Blog

Von Backend bis Frontend: wir suchen Verstärkung

Wir bieten zwei Stellen als Fullstack- oder Backend-Entwickler:innen für unsere Offices in Freiburg und Olten. Wenn du deine Leidenschaft in einem starken Team einbringen willst, dann solltest du dich bewerben.

weiterlesen

Kontakt

geOps AG
Solothurnerstrasse 235
CH-4600 Olten

fon: +41 61 588 05 05
mail: info@geops.ch
geOps GmbH
Bismarckallee 10
D-79098 Freiburg im Breisgau

fon: +49 761 458 925 0
mail: info@geops.de
Impressum | Datenschutz | Bedingungen