Multilinestring splitten

Hallo zusammen

Ich habe folgendes Problem:

Ich befülle eine Geometriespalte mit der geometry MULTILINESTRING.
Ich bekomme die Geometrie immer im Format MULTILINESTRING.

Der größte Teil der Daten beinhaltet immer nur einen LINESTRING pro
MULTILINESTRING. Die restlichen Daten haben mehrer LINESTRINGS in dem MULTILINESTRING.

Mein Problem: Ich möchte immer nur einen LINESTRING pro MULTILINESTRING speichern.

Eine Lösung wäre:
Ich schreibe mir ein kleines Java oder C# Programm.
Ich lese die Daten aus, trenne Sie und speichere Sie wieder!
Problem dabei: Ich müsste die Daten aus der PostgreSQL/PostGIS DB auslesen und dann wieder einlesen. Die Daten würden zweimal angefasst werden.

Zweite Lösung:
Das Splitten der Daten auf der Datenbank.
Ich habe an eine Funktion in PL/pgSQL gedacht.

Meine Fragen dazu:


  • Hat jemand eine bessere Idee?
  • Oder soll ich über eine Trigger-Procedur und einen Trigger die Daten beim einlesen sofort trennen?

Beipiels:

aus:
MULTILINESTRING((1 10,2 10),(50 50,10 10))

aus den einem MULTILINESTRING mit zwei LINESTRINGS sollen zwei MULTILINESTRING mit jeweils nur einem LINESTRING werden:
MULTILINESTRING(1 10,2 10)
MULTILINESTRING(50 50,10 10)


mfg
Gregor

Das beste wäre in der Tat eine pgsql-Funktion, die durch das Multi loopt. ich habe neulich sowas ähnliches hier gepostet (macht Punkte aus Linien), das sollte auch dir als Anregung dienen können.

Grüssle Uwe

Hallo

Habe eine Lösung für das Problem gefunden!
Habe mir eine Trigger-Procedur und einen Trigger geschrieben die alles regeln.
(zumindest hoffe ich das)

Trigger-Procedur:

CREATE OR REPLACE FUNCTION inserttrigger()
  RETURNS trigger AS
$BODY$
DECLARE
    _ankommendegeom geometry;
    _anzahlgeom integer;
    _aktuellegeom geometry;
BEGIN
    _ankommendegeom := NEW.geom;
    _anzahlgeom := st_numgeometries(_ankommendegeom);
    
    -- Wenn mehere LINESTRINGS vorhanden sind, dann...
    IF (_anzahlgeom > 1) THEN
        FOR i in 1.. _anzahlgeom LOOP
            _aktuellegeom = st_geometryn(_ankommendegeom, i);
            INSERT INTO mls2(validaet , anzahlgeometrien , anzahlpunkte , einfuegezeit ,geom) VALUES
                (st_isvalid(_aktuellegeom),
                 st_numgeometries(_aktuellegeom),
                 st_numPoints(_aktuellegeom),
                 LOCALTIMESTAMP(0),
                 st_multi(_aktuellegeom)
                 );
             
            
        END LOOP;
        RETURN NULL;
    ELSE
        -- Wenn nur ein LINESTRING vorhanden ist...
        New.einfuegezeit := LOCALTIMESTAMP(0);
        NEW.validaet := st_isvalid(_ankommendegeom);
        NEW.anzahlgeometrien := st_numgeometries(_ankommendegeom);
        NEW.anzahlpunkte := st_numpoints(_ankommendegeom);

        RETURN NEW;
    END IF;
   
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 1000;
ALTER FUNCTION inserttrigger() OWNER TO postgres;

Wie kann ich die Kosten des Triggers berechnen und optimal setzen. Mir ist das noch immer nicht ganz klar?
Im moment stehen die Kosten auf 1000 (COST = 1000).

mfg
Gregor

Du kanst beim Erstellen der Funktion mit angeben, wie “teuer” der Aufruf ist und wieviele Ergebniszeilen voraussichtlich zurückgeliefert werden. Näheres beschreibt die Dokumentation:

PostgreSQL: Documentation: Manuals: PostgreSQL 8.3: CREATE FUNCTION