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

Gorden Kock
Administrator
Beitragsanzahl: 77

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…