Browsing "Older Posts"

Browsing Category "Spatial"

SVG in APEX: Best Practices

Von Tobias Arnhold → 12.21.2016
In the last 8 month I was working on a new version of my SVG (Raphaël) example application. Of course I have a job (freelancer) and I have children. So the time to spend was diminished on only a few hours per week mostly on my way to work.
Some of the results were presented at the Swedish Oracle meetup in Summer '16. But the final application was made for DOAG 2016.

What leads me to an important point. To have the honor to present somewhere means for me also a passion to learn something new, create something new and share it with others to become a better developer. You may think 8 month of free time spend for a simple presentation is stupid but now I'm able to propose new business solutions to my customers which I didn't even thought were so easy to achieve.

And this is not all. One month before DOAG I was talking to a colleague "Sebastian Reinig" from another consulting company (Syntegris). A young men still studying for master grade and with a lot of passion towards Oracle APEX. He explained me that he worked on an APEX project using my former SVG solution from back in '14 and he enhanced my code by adding cool new features. (e.g. drag and drop in the harbor).
I mean those features were fitting perfectly in my example application. So I asked him to join my presentation at DOAG and show others what he was doing. An he did it. He added a new variant of my old example and helped me finishing the application.

That is why we should be presenting somewhere:
To become better by doing something new.
To become better by sharing your ideas with others and even get inspired by their ideas.

The result of this passion is the "SVG in APEX" application.



Download: github.com/tobiasarnhold/svg-in-apex
Example application URL: apex.oracle.com/pls/apex/f?p=SVG_IN_APEX
User: demo
Password: demo

Examples:

 1. Power grid (Great Britain including their main electricity pipelines)



2. Image tag editor




3. Harbor - Edit mask




4. Harbor - Drag and Drop



5. Mapael - Country visualization with edit mask




6. Mapael - Country visualization with canvas spark-line charts




7. Raphaël - Transform, integrate and interact with external SVG file
The application includes several slides describing the way how to transform an SVG file towards Raphaël.





8. SVG.js - Integrate and interact with external SVG files

Oracle APEX Meetup in Stockholm 16.08.

Von Tobias Arnhold → 7.19.2016
In my summer holiday, this year in Stockholm (Sweden), I will make a stop and present two APEX topics in the "Stockholm Oracle Meetup group".

The topics will be:

Working with interactive SVG graphics in APEX 
Adding SVG graphics inside individual business applications is quite in common. Because those graphics can increase the usability and even more important it creates a completely new way to visualize data inside a browser app. In this presentation he will show us how one can integrate SVG charts and how to use the possibilities of SVG elements to make every static image interactive with only a few lines of code.



APEX Dashboard Competition 
At the beginning of the year the German community announced the "APEX Dashboard Competition". The goal was to create a nice looking dashboard application. This presentation will give you an impression about the best 10 applications and their individual solutions.


If you are interested to see what APEX is capable of then join the presentation on meetup.com.
Thanks to Mathias Magnusson for organizing this great event. Hope to meet as much APEX enthusiasts as possible. :)

Oracle Spatial (Teil 4) - Unterschiedliche Koordinaten Punkte zu einer Linie zusammenführen

Von Tobias Arnhold → 6.21.2016
Vor kurzem musste ich Daten aus einer Excel-Liste in das SDO_GEOMETRY Format bringen. Leider hatte die Excelliste einen Haken.

Die Anforderungen:
- Es musste eine Linie (Typ 2002) im GK3 Format (31467) aus VON und NACH Punkten generiert werden.
- Die Excel-Liste hatte die Punkte entweder als GK3 oder als WGS84 Format hinterlegt.

Nach Import der Daten sah meine Quelltabelle dann so aus:


Und hier das Select zur richtigen Transformation der Geo-Daten ins SDO_GEOMETRY Format:
SELECT 
     SDOP.ID,
     SDOP.VON_NAME,
     SDOP.NACH_NAME,

     /* Linie generieren */
     MDSYS.SDO_GEOMETRY(
        2002, /* Linie */
        31467, /* GK3 */
        NULL,
        MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1),
        MDSYS.SDO_ORDINATE_ARRAY(
            SDOP.VON_GEO_GK3.SDO_POINT.X,
            SDOP.VON_GEO_GK3.SDO_POINT.Y,
            SDOP.NACH_GEO_GK3.SDO_POINT.X,
            SDOP.NACH_GEO_GK3.SDO_POINT.Y
        )
     ) AS GEO_GK3,

     /* Entfernung berechnen */
     ROUND(SDO_GEOM.SDO_DISTANCE(
           GEOM1 => SDOP.VON_GEO_GK3,
           GEOM2 => SDOP.NACH_GEO_GK3,
           TOL => 5,
           UNIT => 'unit=KM'
     ),3) ENTFERNUNG
FROM (
      /* Berechnung der SDO Punkte */
      SELECT
        ID,
        VON_NAME,
        NACH_NAME,

        /* VON: Check ob GK3 oder WGS84 und Vereinheitlichung ins GK3 Format*/
        CASE 
         WHEN VON_GK3_X IS NOT NULL 
         THEN
            MDSYS.SDO_GEOMETRY (
                      2001, -- Zweidimensionaler Punkt
                      31467, -- Typ: GK3
                      SDO_POINT_TYPE(
                          X => VON_GK3_X, 
                          Y => VON_GK3_Y,
                          Z => NULL
                      ), 
                      NULL,
                      NULL
            ) 
          ELSE
            SDO_CS.TRANSFORM( 
              MDSYS.SDO_GEOMETRY (
                2001, -- Zweidimensionaler Punkt
                8307, -- Typ: WGS84
                SDO_POINT_TYPE(
                    X => VON_WGS84_X,  -- Längengrad / Longitude / Ost
                    Y => VON_WGS84_Y,  -- Breitengrad / Latitude / Nord
                    Z => NULL
                ), 
                NULL,
                NULL
              ),
             31467 -- Umwandlung in GK3
             )
        END AS VON_GEO_GK3,

        /* NACH: Check ob GK3 oder WGS84 und Vereinheitlichung ins GK3 Format*/
        CASE 
         WHEN NACH_GK3_X IS NOT NULL 
         THEN
            MDSYS.SDO_GEOMETRY (
                      2001, -- Zweidimensionaler Punkt
                      31467, -- Typ: GK3
                      SDO_POINT_TYPE(
                          X => NACH_GK3_X, 
                          Y => NACH_GK3_Y,
                          Z => NULL
                      ), 
                      NULL,
                      NULL
            ) 
          ELSE
            SDO_CS.TRANSFORM( 
              MDSYS.SDO_GEOMETRY (
                2001, -- Zweidimensionaler Punkt
                8307, -- Typ: WGS84
                SDO_POINT_TYPE(
                    X => NACH_WGS84_X,  -- Längengrad / Longitude / Ost
                    Y => NACH_WGS84_Y,  -- Breitengrad / Latitude / Nord
                    Z => NULL
                ), 
                NULL,
                NULL
              ),
             31467 -- Umwandlung in GK3
             )
        END AS NACH_GEO_GK3

      FROM GEO_MEINE_DATEN
) SDOP
Mit dem Ergebnis:

Die besten HowTo's rund um fortgeschrittene SQL-Techniken

Von Tobias Arnhold → 9.25.2015
Im Zuge des aktuellen Community Tips, möchte ich mal eine Liste an HowTo's, Tips und Tricks rund um die verschiedenen aktuellen
SQL-Techniken veröffentlichen. Dabei habe ich mich möglichst auf deutsche Lektüre fokussiert. Am häufigsten habe ich Artikel von Carsten Czarski gefunden, was wohl wenig verwunderlich ist. :)
Die folgenden Links richten sich an jene Entwickler, die mehr als SQL-92 aus Ihrer Oracle Datenbank rausholen möchten.


Analytische SQL-Funktionen
 - Daten zusammenfassen mit Aggregatsfunktionen
 - Mächtige Berichte mit "Analytischen Funktionen"
 - Analytische Funktionen - eine Einführung
 - Analytische Funktionen - Einführung
 - Einsatz analytischer Funktionen
 - Probably the Coolest SQL Feature: Window Functions (Englisch)

Volltextsuche
 - Ähnlichkeitssuche in SQL-Abfragen: Oracle TEXT für alle!
 - Volltextrecherche und mehr: Wozu man Oracle Text nutzen kann
 - Oracle Text - Einführung
 - Ähnlichkeitssuche mit Oracle Text
 - "Unscharfe Suche" in Datenbeständen

Räumliche Abfragen (Geodaten)
 - oracle-spatial.blogspot.de
 - spatialdbadvisor.com (Englisch)
 - SDO_GEOMETRY für Newbies
 - Was kann der Oracle Locator (Englisch)

XML-Funktionen
 - Working with XML files and APEX - Part 1: Upload (Englisch)
 - Working with XML files and APEX - Part 2: Selecting data from XMLType column with XMLTable (Englisch)
 - XML-Dokumente relational aufbereiten: mit SQL!
 - XML-Strukturen analysieren - mit SQL!

JSON-Funktionen
 - APEX_JSON ohne APEX: JSON parsen mit SQL und PL/SQL
 - APEX_JSON ohne APEX: JSON erzeugen mit SQL und PL/SQL

 - Native JSON-Unterstützung in der Oracle-Datenbank 12c (12.1.0.2)
 - Oracle 12.1.0.2 ist da: Ein Einblick in die JSON-Unterstützung
 - Speed Up Your APEX apps with JSON and Mustache.js

SQL Pattern Matching (ab 12.1)
 - Datenmuster finden: SQL Pattern Matching in Oracle12c
 - Oracle12c: Was für SQL- und PL/SQL-Entwickler einfacher wird
 - Pattern Matching (MATCH_RECOGNIZE) in Oracle Database 12c Release 1 (Englisch)

SQL MODEL-Klausel
 - Kalkulationen, Simulationen und mehr - in APEX: SQL MODEL Klausel
 - SQL Model Clause Tutorial (Englisch)
 - Rechnen wie in Excel - in einer SQL-Abfrage
 - SQL Model Clause Tutorial
 - Model Klausel - Der Excel-Killer von Oracle?
 - Forum Lösung - Gantt Chart überschneidende Einträge (Englisch)

Stringverkettungen
 - LISTAGG function in 11g release 2 (Englisch)
 - SQL LISTAGG mit CLOB-Ausgabe - kein VARCHAR2-Limit mehr
 - XML CLOB Trick - Custom CSV Export in APEX


String to Table
 - Split comma delimited strings in a table in Oracle
 - emulating string-to-table functionality using sql
 - When APEX_UTIL.STRING_TO_TABLE is not enough

Ähnlichkeitssuche (Beispiel: Jaro Winkler)
 - UTL_MATCH : String Matching by Testing Levels of Similarity/Difference (Englisch)
 - Oracle UTL_MATCH (Englisch)

Hierarchische Abfragen (CONNECT BY)
 - Treewalking mit SQL (Hierarchische Strukturen) 
 - Oracle: connect by (Hierarchische Queries)
 - Hierarchische Abfragen in Oracle11g Rel2: Recursive WITH clause 

Regular Expressions
 - Reguläre Ausdrücke in der Oracle Datenbank in SQL verwenden
 - Reguläre Ausdrücke ... in der Datenbank!
 - Reguläre Ausdrücke in Application Express 
 - Regular Expressions in Oracle

Kreuztabellen (Pivot / Unpivot)
 - Kreuztabellen in Oracle11g: SQL PIVOT-Klausel
 - Pivoting in 11g - Zeilen zu Spalten
 - pivot and unpivot queries in 11g (Englisch)
 - Dynamic SQL Pivoting – Stealing Anton’s Thunder (Englisch)
 - APEX Beispielanwendung

Zufallszahlen
 - Arbeiten mit DBMS_CRYPTO
 - Generating random numbers and strings in Oracle (Englisch)
 - Oracle DBMS_CRYPTO (Englisch) und Oracle DBMS_RANDOM (Englisch)

Zeilengenerierung
 - Oracle Row Generator Techniques (Englisch)

Oracle Spatial (Teil 2) - Füllen der USER_SDO_GEOM_METADATA

Von Tobias Arnhold →
Damit Tools wie
  - Oracle Spatial Reader
  - FeatureReader
  - OracleQuerier
  - GeoServer
mit Oracle Spatial Tabellen arbeiten können, müssen diese in einer Meta-Schicht bekannt gemacht werden. Dies ist im Prinzip ganz einfach, denn dazu muss nur die View USER_SDO_GEOM_METADATA gefüllt werden.

Die View beinhaltet die folgenden Spalten:
(
  TABLE_NAME   VARCHAR2(32),
  COLUMN_NAME  VARCHAR2(32),
  DIMINFO      SDO_DIM_ARRAY,
  SRID         NUMBER
);

Um diese richtig zu füllen muss neben Tabelle, Spalte und SRID (Geotyp), auch die Matrix in welchen Bereich sich die Daten befinden hinterlegt werden.

Dies ist relativ einfach über ein SQL Statement abbildbar.

Hierbei beziehe ich mich auf meine Testtabelle aus dem 1. Teil meiner Spatial Posts:
-- Komplette Matrix
INSERT INTO USER_SDO_GEOM_METADATA
VALUES (
  'GV_STANDORT_LAYER2_LIST',
  'GEO_WGS84',
  MDSYS.SDO_DIM_ARRAY( 
    MDSYS.SDO_DIM_ELEMENT('X', -180, 180, 0.5),
    MDSYS.SDO_DIM_ELEMENT('Y', -90, 90, 0.5)
  ),
  8307
);

----------------------------------------------------
-- Insert auf Basis eines vorhandenen Eintrags
INSERT INTO USER_SDO_GEOM_METADATA
(
  TABLE_NAME,
  COLUMN_NAME,
  DIMINFO,
  SRID
)
select 
  'GV_STANDORT_LAYER2_LIST' as TABLE_NAME,
  COLUMN_NAME,
  DIMINFO,
  SRID
from USER_SDO_GEOM_METADATA
WHERE TABLE_NAME = 'GV_STANDORT_LAYER1'

----------------------------------------------------
-- Teilmenge aus Ausgangsdaten
INSERT INTO USER_SDO_GEOM_METADATA 
(
  TABLE_NAME,
  COLUMN_NAME,
  DIMINFO,
  SRID     
)
SELECT
  'MEINE_GEO_DATEN' AS TABLE_NAME,
  'GEO_WGS84' COLUMN_NAME,
  MDSYS.SDO_DIM_ARRAY( 
         MDSYS.SDO_DIM_ELEMENT('X', MINX, MAXX, 0.05), 
         MDSYS.SDO_DIM_ELEMENT('Y', MINY, MAXY, 0.05) 
  ) AS DIMINFO,
  8307  AS SRID -- WGS84
FROM ( 
       SELECT
         TRUNC( MIN( V.X ) - 1,0) AS MINX,
         ROUND( MAX( V.X ) + 1,0) AS MAXX,
         TRUNC( MIN( V.Y ) - 1,0) AS MINY,
         ROUND( MAX( V.Y ) + 1,0) AS MAXY
       FROM (
          SELECT SDO_AGGR_MBR(DS.GEO_WGS84) AS AMBR
          FROM MEINE_GEO_DATEN DS
          --WHERE DS.X_KOORDINATE IS NOT NULL -- Geodaten dürfen nicht leer sein
       ) DA,
       TABLE(MDSYS.SDO_UTIL.GETVERTICES(DA.AMBR)) V
     )

Die Quelle des Teilmenge-Statements stammt von dem Spatial Blog: http://spatialdbadvisor.com/

Wenn Ihr tiefergehendes Wissen zum Thema USER_SDO_GEOM_METADATA sucht, dann schaut euch mal diese Beiträge an:
docs.oracle.com - Geometry Metadata Views
knowledge.safe.com - Adding metadata entries for Oracle spatial tables or views

Ergebnis:

Der hinterlegte Bereich kann nun noch mit den Detaildaten verifiziert werden:
SELECT
  ADRESSE, 
  SDO_GEOM.VALIDATE_GEOMETRY(LAY.GEO_WGS84, MET.DIMINFO)  RESULT
FROM MEINE_GEO_DATEN LAY
CROSS JOIN USER_SDO_GEOM_METADATA MET
WHERE ROWNUM BETWEEN 1 AND 10
Oftmals wird auch ein Spatial-Index zur Datenvisualisierung benötigt:
CREATE INDEX "MEINE_GEO_DATEN_IDX" ON "MEINE_GEO_DATEN" ("GEO_WGS84") 
   INDEXTYPE IS "MDSYS"."SPATIAL_INDEX" ;

Oracle Spatial (Teil 1) - Mein erster Tag

Von Tobias Arnhold → 9.11.2015
Ich habe in der Oracle DB Welt viele Themenkomplexe kennengelernt und mit gearbeitet. Eines ist bisher außen vor geblieben: Oracle Spatial mit dem Datentyp SDO_GEOMETRY

Warum?
Es hat sich wohl einfach noch nicht ergeben.
Aber irgendwann ist ja immer das erste Mal! :)

Heute habe ich die Aufgabe erhalten bestehende Koordinatendaten (X,Y) in das SDO_GEOMETRY Format GK3 zu transformieren.

Was wusste ich bisher?
Der SDO_GEOMETRY Datentyp wird über ein gesondertes Schema bereit gestellt:
MDSYS
Der Datentyp besteht aus X,Y und Z Koordinaten. Außerdem gibt es unterschiedliche Typen: Punkte, Linien, Objekte... Und anscheinend auch unterschiedliche Arten das Koordinatensystem (WGS 84, Gauss-Kruger 3) abzubilden.

Wie war mein Vorgehen um möglichst schnell Wissen zu erlangen?
Ich habe mich mit dem Datentyp auseinander gesetzt und bin dabei auf die genaue Datentyp-Definition gestoßen (Spatial User's Guide and Reference 10gR2 - 2 Spatial Data Types and Metadata):
CREATE TYPE sdo_geometry AS OBJECT (
SDO_GTYPE NUMBER,
SDO_SRID NUMBER,
SDO_POINT SDO_POINT_TYPE,
SDO_ELEM_INFO SDO_ELEM_INFO_ARRAY,
SDO_ORDINATES SDO_ORDINATE_ARRAY
);

Der SDO_GTYPE definiert den Typ des Objekts: Punkt, Linie, Polygon,...
Info: Die folgende Tabelle zeigt die möglichen Typen und beschreibt die genaue Definition: http://docs.oracle.com/cd/B19306_01/appdev.102/b14255/sdo_objrelschema.htm#g1013735

Die SDO_SRID definiert das Koordinatensystem (WGS84, GK3, Arc 1950)
Info: Mit der folgenden Abfrage können Sie die verschiedenen System auslesen:
select srid,cs_name 
from cs_srs 
-- where srid in (31467, 8307, 8199);

Der SDO_POINT definiert die Koordinaten des Objekts.

SDO_ELEM_INFO und SDO_ORDINATES habe ich an meinem ersten Tag mit Oracle Spatial nicht verwendet. :P

Nun stellte sich die Frage, wie ich die Koordinaten aus meiner Testtabelle in den SDO_GEOMETRY Datentyp umwandeln kann? 
Bei der Suche bin ich auf den hervorragenden deutschsprachigen Blog gelandet:
http://oracle-spatial.blogspot.de

Und habe die passenden Antworten in dem Blogpost gefunden:
http://oracle-spatial.blogspot.de/2010/09/gauss-kruger-epsg-oder-nicht-epsg-das.html

Die Antwort war viel einfacher als gedacht:
SELECT 
  ADRESSE,
  GEO_KOORDINATE_X,
  GEO_KOORDINATE_Y,

  SDO_CS.TRANSFORM( 
    MDSYS.SDO_GEOMETRY (
      2001, -- Zweidimensionaler Punkt
      8307, -- Typ: WGS84
      SDO_POINT_TYPE(
          X => TO_NUMBER(GEO_KOORDINATE_X),  -- Längengrad / Longitude / Ost
          Y => TO_NUMBER(GEO_KOORDINATE_Y),  -- Breitengrad / Latitude / Nord
          Z => NULL
      ), 
      NULL,
      NULL
    ),
   31467 -- Umwandlung in GK3
   ) AS GEOMETRY_GK3

FROM MEINE_GEO_DATEN
Da mein Problem gelöst war, konnte ich ja Feierabend machen.
Hmm... woher weiß ich eigentlich, dass die Ergebnisse stimmen?

Hier liefert der SQL Developer die passende Lösung.
Der hat nämlich eine simple Geodatenanzeige integriert.

Außerdem liefert Oracle eine Geodaten-DB zum testen aus:
http://www.oracle.com/technetwork/database/options/spatialandgraph/downloads/navteq-data-download-2577974.html

Diese habe ich zum verifizieren meiner Ergebnisse direkt mal importiert und meine virtuelle Umgebung gesprengt, da die DB über 20GB groß wurde. :)

Dennoch konnte ich ein paar Interessante Tabellen importieren:
 - MAP_WORLD (Länderdarstellung - Flächen)
 - NTC_MAP_POI_CITY_CENTER (Städte mit Einwohnerzahlen - Punkte)

Diese habe ich dann in meine "Grafische Ansicht" integriert:


SELECT - Europa - Länderflächen:
SELECT
  COUNTRY,
  sdo_cs.transform(
    GEOMETRY,
    8307 -- Transformation in WGS84 notwendig
  ) as GEOMETRY FROM MAP_WORLD
where continent = 'Europe';

SELECT - Deutschland - Städte:
SELECT
  GEOMETRY,
  name
FROM NTC_MAP_POI_CITY_CENTER
where population > 30000
and iso_country_code = 'DEU';

SELECT - Meine Objekte:
SELECT
  GEO_WGS84,
  NAME
FROM MEINE_GEO_DATEN;

Und hier das Ergebnis:

Imho:
Innerhalb eines Tages kann man in einem ganz offensichtlich hochkomplexen Themengebiet, doch ganz beachtliche Ergebnisse erzielen.