Jüngst habe ich für einen Kollegen einen GPS-Track in die Datenbank geladen. Ich hatte eine .gpx-Datei, die in etwa so aussieht ...
<gpx xmlns="http://www.topografix.com/GPX/1/1" tc2=" ... <trk> <name>2010-11-16T03:46:55Z</name> <trkseg> <trkpt lat="51.4799802" lon="7.9678522"> <ele>270.7484131</ele> <time>2010-11-16T03:46:55Z</time> </trkpt> <trkpt lat="51.4799436" lon="7.9678679"> <ele>264.0192871</ele> <time>2010-11-16T03:47:06Z</time> </trkpt> <trkpt lat="51.4797696" lon="7.9681059"> <ele>264.4998779</ele> <time>2010-11-16T03:47:12Z</time> </trkpt> <trkpt lat="51.4797497" lon="7.9681919"> <ele>264.9805908</ele> <time>2010-11-16T03:47:14Z</time> </trkpt>
Zunächst hatte ich ein wenig nach Converter-Software gegoogelt, wurde jedoch nicht so recht fündig (komische Lizenzbedingungen, keine Konvertierung nach GML oder KML, sondern nur in andere Formate). Da es aber um eine einfach zu verstehende XML-Datei geht, beschloß ich, mir einfach selbst eine Funktion zu schreiben, welche die Arbeit erledigt. Und hier ist sie ...
create or replace function convert_gpx_to_sdo( p_gpxfile in xmltype, p_lrs in number default 0 ) return sdo_geometry is v_ordinates sdo_ordinate_array := sdo_ordinate_array(); v_gtype number; v_cnt pls_integer := 1; v_startts timestamp; v_interval interval day(9) to second; c_gpxns varchar2(200) := 'xmlns="http://www.topografix.com/GPX/1/1"'; begin if p_lrs = 1 then v_gtype := 3302; else v_gtype := 2002; end if; for tp in ( select extractvalue(value(tp), '/trkpt/@lon', c_gpxns) x, extractvalue(value(tp), '/trkpt/@lat', c_gpxns) y, extractvalue(value(tp), '/trkpt/time', c_gpxns) m from table(xmlsequence(extract(p_gpxfile, '//trkpt', c_gpxns))) tp ) loop if v_cnt = 1 then v_startts := to_timestamp(tp.m, 'YYYY-MM-DD"T"HH24:MI:SS"Z"'); end if; if p_lrs = 1 then v_ordinates.extend(3); else v_ordinates.extend(2); end if; v_ordinates(v_cnt) := tp.x; v_cnt := v_cnt + 1; v_ordinates(v_cnt) := tp.y; v_cnt := v_cnt + 1; if p_lrs = 1 then v_interval := to_timestamp(tp.m, 'YYYY-MM-DD"T"HH24:MI:SS"Z"') - v_startts; v_ordinates(v_cnt) := extract(MINUTE from v_interval) + extract(HOUR from v_interval) * 60 + extract(SECOND from v_interval) / 60; v_cnt := v_cnt + 1; end if; end loop; return sdo_geometry(v_gtype, 8307, null, sdo_elem_info_array(1,2,1), v_ordinates); end convert_gpx_to_sdo; / sho err
Die Funktion nimmt das GPX-File (XMLTYPE) als ersten Parameter entgegen. Der zweite Parameter gibt an, ob eine Linear Referencing-Geometrie zurückgegeben werden soll. Wenn ja, werden die Measures in Minuten gespeichert. Gebt hier entweder "1" oder "0" an ... Man könnte hier sicherlich noch mehr machen: die GPX-Dateien enthalten eine Höhenangabe - man könnte also auch 3D-Geometrien bauen ...
Vielleicht jemand diese erste Version brauchen - viel Spaß damit!
Keine Kommentare:
Kommentar veröffentlichen