Startseite Foren Basics oracle-Statement für „zerrissene“ Haltungen?

Ansicht von 3 Beiträgen - 1 bis 3 (von insgesamt 3)
  • Autor
    Beiträge
  • Peter2
    Teilnehmer
    Beitragsanzahl: 8

    Durch Bearbeitungsfehler kommt es immer wieder zu „zerrissenen“ Leitungen. Sie führen nicht aneinanderstossend von „Anfang – 1 – 2 -3 – Ende“, sondern von „Anfang – 1 geometrisches Loch – 2 – 3 – Ende“. Hat jemand ein Rezept, um das in oracle Spatial zu finden?

    Schönen Abend
    Peter

    Gorden Kock
    Administrator
    Beitragsanzahl: 42

    Hallo Peter,

    da bin ich aber beruhigt, dass nach so vielen Jahren endlich jemand auch dieselben Probleme hat. Ich dachte schon, dass wir hier etwas grundsätzlich verkehrt machen. Das Problem mit nicht aneinanderstoßenden Leitungen beschäftigt mich schon viele Jahre und der Support wollte es bisher nicht verstehen (ich hole hier aber nicht so weit aus). Meine begründete Vermutung ist, dass AutoCad die Koordinaten nach dem Splitten und beim Punktfang anders rundet als ORACLE. Ich habe u.a. dafür schon die Toleranz bei der Geometrierundungsregel auf 6 Nachkommastellen gesetzt, damit wir nicht jedes Mal eine Lücke haben, trotzdem kommt es immer wieder vor, sehr zum Leidwesen der Erfasser. Die Lösung ist allerdings alles andere als trivial (jedenfalls, der Weg den ich beschreite, es mag andere geben).

    Die lückenlose Verbindung von Leitungen prüfe ich nur innerhalb des Inspektionsimports ab. Da wir dafür eine eigene Programmierung haben, kann ich dir nur Hinweise geben, wie du das herausbekommst:
    Ich bilde jeweils aus den beteiligten Leitungen ein einziges GEOM über die im anderen Post schon diskutierte Funktionskombi und ermittle daraus den GTYPE, also in etwa so:
    select sdo_aggr_concat_lines(sdo_geom.sdo_arc_densify(GEOM, 0.0005, ‚arc_tolerance=0.0005‘)).sdo_gtype from where .
    Wenn das Ergebnis nicht 2002 ist, also keine Polylinie, sondern z.B. ein Multipolygon mit 2006 dann weißt du immerhin, dass es einen Fehler gibt. Jetzt könntest du zusätzlich per PL/SQL eine Schleife bauen, um alle beteiligten Start- und Endpunkte der Leitungen miteinander zu vergleichen und abzuhaken, ob sie verbunden sind. Über den Leitungsnamen bzw. die Von- und Nach-Knoten kann man das ggf. noch gezielter machen, um nicht alles mit allem zu vergleichen. Für die Koordinatenermittlung und deren Vergleich gibt es Beispiele in der weiter unten aufgeführten PL/SQL-Funktion, die ich für nicht zusammenhängende Einzelsegmente einer einzigen Leitung geschrieben habe.

    Denn wir haben das Problem bereits innerhalb derselben Leitung, wenn sie an der Schachtwand gesplittet ist. Dafür musste ich für dieses Problem ein DataChecker-Statement mit besagter PL/SQL-Funktion einbauen, das ich gerne zur Verfügung stelle. Da wir aber auch ein eigenes Datenmodell für alle Leitungsobjekte haben, wirst du es für deine Belange umschreiben müssen.

    Im DataChecker rufe ich nur eine PL/SQL-Funktion auf:

    select fid from abw_ltg where abw_ltg_richtung(fid) = ‚FALSE‘

    Die Funktion selbst sieht so aus (sie findet Lücken und falsch ausgerichtete Segmente):

    CREATE OR REPLACE
    FUNCTION abw_ltg_richtung(p_fid IN NUMBER) RETURN VARCHAR2
    IS

    a_geom MDSYS.SDO_GEOMETRY;
    l_geom MDSYS.SDO_GEOMETRY;
    e_geom MDSYS.SDO_GEOMETRY;
    a_point MDSYS.SDO_GEOMETRY;
    la_point MDSYS.SDO_GEOMETRY;
    e_point MDSYS.SDO_GEOMETRY;
    le_point MDSYS.SDO_GEOMETRY;
    v_diminfo user_sdo_geom_metadata.diminfo%TYPE;
    anz_l number;
    anz_l_1 number;
    anz_von number;
    anz_geom number;

    BEGIN

    select m.diminfo into v_diminfo
    from user_sdo_geom_metadata m
    where m.table_name = ‚ABW_LTG_L‘;

    select count(*) into anz_l_1
    from abw_ltg_l ll
    where ll.fid_parent = p_fid
    and ll.attribut = 1;

    IF anz_l_1 > 1 then

    return ‚FALSE‘;

    ELSE

    select count(*) into anz_l
    from abw_ltg_l ll
    where ll.fid_parent = p_fid;

    select geom into l_geom
    from abw_ltg_l ll
    where ll.fid_parent = p_fid
    and ll.attribut = 1;

    IF anz_l = 3 THEN — normale Haltung

    select geom into a_geom
    from abw_ltg_l ll
    where ll.fid_parent = p_fid
    and ll.attribut = 2
    and sdo_relate(ll.geom,(select k.geom
    from abw_knt k, abw_ltg l
    where k.fid = l.fid_von
    and l.FID = ll.FID_PARENT),’mask=anyinteract querytype=window‘) =’TRUE‘;

    select geom into e_geom
    from abw_ltg_l ll
    where ll.fid_parent = p_fid
    and ll.attribut = 2
    and sdo_relate(ll.geom,(select k.geom
    from abw_knt k, abw_ltg l
    where k.fid = l.fid_nach
    and l.FID = ll.FID_PARENT),’mask=anyinteract querytype=window‘) =’TRUE‘;

    a_point := sdo_lrs.CONVERT_TO_STD_GEOM(sdo_lrs.GEOM_SEGMENT_END_PT(sdo_lrs.CONVERT_TO_LRS_GEOM(a_geom,v_diminfo)));
    la_point := sdo_lrs.CONVERT_TO_STD_GEOM(sdo_lrs.GEOM_SEGMENT_START_PT(sdo_lrs.CONVERT_TO_LRS_GEOM(l_geom,v_diminfo)));
    le_point := sdo_lrs.CONVERT_TO_STD_GEOM(sdo_lrs.GEOM_SEGMENT_END_PT(sdo_lrs.CONVERT_TO_LRS_GEOM(l_geom,v_diminfo)));
    e_point := sdo_lrs.CONVERT_TO_STD_GEOM(sdo_lrs.GEOM_SEGMENT_START_PT(sdo_lrs.CONVERT_TO_LRS_GEOM(e_geom,v_diminfo)));

    IF round(a_point.SDO_POINT.x,6) = round(la_point.SDO_POINT.x,6) and round(a_point.SDO_POINT.y,6) = round(la_point.SDO_POINT.y,6) –Rundung auf 6 Nachkommastellen für Inspektion wichtig
    and round(le_point.SDO_POINT.x,6) = round(e_point.SDO_POINT.x,6) and round(le_point.SDO_POINT.y,6) = round(e_point.SDO_POINT.y,6) then

    return ‚TRUE‘;

    ELSE

    return ‚FALSE‘;

    END IF;

    ELSIF anz_l = 2 THEN –Zuleitung oder gesplittete Haltung am Schacht

    select count(*) into anz_von
    from abw_ltg_l ll
    where ll.fid_parent = p_fid
    and ll.attribut = 2
    and sdo_relate(ll.geom,(select k.geom
    from abw_knt k, abw_ltg l
    where k.fid = l.fid_von
    and l.FID = ll.FID_PARENT),’mask=anyinteract querytype=window‘) =’TRUE‘;

    IF anz_von > 0 THEN –Netzlinie am Von-Schacht

    select geom into a_geom
    from abw_ltg_l ll
    where ll.fid_parent = p_fid
    and ll.attribut = 2
    and sdo_relate(ll.geom,(select k.geom
    from abw_knt k, abw_ltg l
    where k.fid = l.fid_von
    and l.FID = ll.FID_PARENT),’mask=anyinteract querytype=window‘) =’TRUE‘;

    a_point := sdo_lrs.CONVERT_TO_STD_GEOM(sdo_lrs.GEOM_SEGMENT_END_PT(sdo_lrs.CONVERT_TO_LRS_GEOM(a_geom,v_diminfo)));
    la_point := sdo_lrs.CONVERT_TO_STD_GEOM(sdo_lrs.GEOM_SEGMENT_START_PT(sdo_lrs.CONVERT_TO_LRS_GEOM(l_geom,v_diminfo)));

    IF round(a_point.SDO_POINT.x,6) = round(la_point.SDO_POINT.x,6) and round(a_point.SDO_POINT.y,6) = round(la_point.SDO_POINT.y,6) THEN

    return ‚TRUE‘;

    ELSE

    return ‚FALSE‘;

    END IF;

    ELSE –Netzlinie am Nach-Schacht

    select geom into e_geom
    from abw_ltg_l ll
    where ll.fid_parent = p_fid
    and ll.attribut = 2
    and sdo_relate(ll.geom,(select k.geom
    from abw_knt k, abw_ltg l
    where k.fid = l.fid_nach
    and l.FID = ll.FID_PARENT),’mask=anyinteract querytype=window‘) =’TRUE‘;

    le_point := sdo_lrs.CONVERT_TO_STD_GEOM(sdo_lrs.GEOM_SEGMENT_END_PT(sdo_lrs.CONVERT_TO_LRS_GEOM(l_geom,v_diminfo)));
    e_point := sdo_lrs.CONVERT_TO_STD_GEOM(sdo_lrs.GEOM_SEGMENT_START_PT(sdo_lrs.CONVERT_TO_LRS_GEOM(e_geom,v_diminfo)));
    –raise_application_error(-20000,e_point.SDO_POINT.x||‘-‚||le_point.SDO_POINT.x||‘ – ‚||e_point.SDO_POINT.y||‘-‚||le_point.SDO_POINT.y);

    IF round(e_point.SDO_POINT.x,6) = round(le_point.SDO_POINT.x,6) and round(e_point.SDO_POINT.y,6) = round(le_point.SDO_POINT.y,6) THEN

    return ‚TRUE‘;

    ELSE

    return ‚FALSE‘;

    END IF;

    END IF;

    ELSE –Zwischenleitung ohne Schachtkontakt

    select k.geom into a_point
    from abw_knt k, abw_ltg l
    where k.fid = l.fid_von
    and l.FID = p_fid;

    select k.geom into e_point
    from abw_knt k, abw_ltg l
    where k.fid = l.fid_nach
    and l.FID = p_fid;

    la_point := sdo_lrs.CONVERT_TO_STD_GEOM(sdo_lrs.GEOM_SEGMENT_START_PT(sdo_lrs.CONVERT_TO_LRS_GEOM(l_geom)));
    le_point := sdo_lrs.CONVERT_TO_STD_GEOM(sdo_lrs.GEOM_SEGMENT_END_PT(sdo_lrs.CONVERT_TO_LRS_GEOM(l_geom)));

    IF round(a_point.SDO_POINT.x,6) = round(la_point.SDO_POINT.x,6) and round(a_point.SDO_POINT.y,6) = round(la_point.SDO_POINT.y,6)
    and round(le_point.SDO_POINT.x,6) = round(e_point.SDO_POINT.x,6) and round(le_point.SDO_POINT.y,6) = round(e_point.SDO_POINT.y,6) then

    return ‚TRUE‘;

    ELSE

    return ‚FALSE‘;

    END IF;

    END IF;

    END IF;

    END;
    /

    Ich hoffe, dass du damit etwas anfangen kannst…

    Peter2
    Teilnehmer
    Beitragsanzahl: 8

    Vielen Dank Gorden
    bei uns geht es hier meist gar nicht um Rundungsfehler, sondern um Import- oder Softsplitprobleme, wo dann die Abwasserhaltungen meterlange Löcher haben und dann unsauber (also ohne Geometrie) exportiert werden und erst dann bei der Exportprüfung auffallen.

    Fürs erste bin ich mit deinem Tipp für GTYPE gut versorgt; ich hatte mich gestern in Koordinatenduplikatszählungen usw. verlaufen und habe auch in PL/SQL noch Nachholbedarf. Daher werde ich deine Funktion noch etwas ruhen lassen, aber denke doch, dass auch andere froh darüber sind.

    Danke nochmals und gute Zeit
    Peter

Ansicht von 3 Beiträgen - 1 bis 3 (von insgesamt 3)
  • Du musst angemeldet sein, um auf dieses Thema antworten zu können.