GeoJSON-Datenfunktionen

Die Spezifikation GeoJson definiert die Struktur und den Inhalt von JSON-Objekten, die geografische Formen auf der Erde darstellen sollen (genannte Geometrien). Gemäß der Spezifikation GeoJson muss ein JSON-Objekt zwei Felder enthalten, die als Typ und Koordinaten bezeichnet werden, wobei der Wert des Typfeldes die Art der Geometrie angibt und der Wert der Koordinaten ein Array sein muss, dessen Elemente die geometrische Form definieren.

Alle Arten von Geometrien werden in Form einer Reihe von Positionen angegeben. Für Strings und Polygone wird die tatsächliche geometrische Form jedoch durch die Linien gebildet, die ihre Positionen verbinden. Die Spezifikation GeoJson definiert eine Linie zwischen zwei Punkten als Geraden, der die Punkte im (flachen) kartesischen Koordinatensystem verbindet, deren horizontale und vertikale Achsen der Längen- bzw. Breitengrad sind.

Es gibt verschiedene integrierte Funktionen, die JSON-Objekte als Geometrien interpretieren und das Durchsuchen der Zeilen mit Geometrien ermöglichen, die bestimmte Bedingungen erfüllen.

Um den Beispielen zu folgen, erstellen Sie mit dem erweiterten DDL-Eingabemodus eine Tabelle über die OCI-Konsole. Die DDL-Anweisung ist unten angegeben.
CREATE TABLE IF NOT EXISTS PointsOfInterest (
    id INTEGER, poi JSON, 
PRIMARY KEY(id));

Die Schritte zum Erstellen einer Tabelle mit einer DDL-Anweisung finden Sie unter Singleton-Tabelle erstellen: Advanced DDL Input Mode.

Um Daten in die von der OCI-Konsole erstellte Tabelle zu laden, klicken Sie auf den Tabellennamen. Die Details der Tabelle werden angezeigt. Klicken Sie auf Daten hochladen. Klicken Sie auf Datei zum Hochladen auswählen, und geben Sie die JSON-Datei an, die hochgeladen werden soll. Sie können die DDL- und JSON-Datei für die Daten GeoJSON hier herunterladen.

geo_inside

Legt Geometrien innerhalb einer begrenzenden GeoJSON-Geometrie fest.
boolean geo_inside(any*, any*)
  • Der erste Parameter any* kann ein beliebiges geometrisches Objekt sein.
  • Der zweite Parameter any* muss ein Polygon sein.

Die Funktion bestimmt, ob die Geometrie, auf die der erste Parameter zeigt, vollständig im Polygon enthalten ist, auf das der zweite Parameter zeigt.

Wenn einer der beiden Parameter kein einzelnes gültiges Geometrieobjekt zurückgibt und es zur Kompilierungszeit erkannt werden kann, löst die Funktion einen Fehler aus.

Das Laufzeitverhalten ist wie folgt:
  • Gibt "false" zurück, wenn ein Parameter 0 oder mehr als 1 Element zurückgibt.
  • Gibt NULL zurück, wenn ein Parameter NULL zurückgibt.
  • Gibt "false" zurück, wenn ein Parameter (zur Laufzeit) ein Element zurückgibt, das kein gültiges Geometrieobjekt ist.
  • Gibt "false" zurück, wenn der zweite Parameter ein Geometrieobjekt zurückgibt, das kein Polygon ist.
  • Wenn beide Parameter jeweils ein einzelnes Geometrieobjekt zurückgeben und die zweite Geometrie ein Polygon ist.
    • Es wird wahr zurückgegeben, wenn die erste Geometrie vollständig im zweiten Polygon enthalten ist, d.h. alle ihre Punkte gehören zum Inneren des Polygons.
    • Andernfalls wird "false" zurückgegeben.

Hinweis:

Das Innere eines Polygons besteht aus allen Punkten im Polygonbereich, mit Ausnahme der Punkte im linearen Ring, die die Begrenzung des Polygons definieren.
Beispiel: Suchen Sie nach Naturparks in Nordkalifornien.
SELECT t.poi.name AS park_name, 
t.poi.address.street AS park_location
FROM PointsOfInterest t
WHERE t.poi.kind = "nature park"
AND geo_inside(t.poi.location,
              { "type" : "polygon",
                "coordinates": [[
                  [-120.1135253906249, 36.99816565700228],
                  [-119.0972900390625, 37.391981943533544],
                  [-119.2840576171875, 37.97451499202459],
                  [-120.2069091796874, 38.035112420612975],
                  [-122.3822021484375, 37.74031329210266],
                  [-122.2283935546875, 37.15156050223665],
                  [-121.5362548828124, 36.85325222344018],
                  [-120.1135253906249, 36.99816565700228]
                ]]
             });
Erklärung:
  • Sie fragen die Tabelle PointsOfInterest ab, um die Zeilen für Naturpark zu filtern.
  • Sie geben ein Polygon als zweiten Parameter für die Funktion geo_inside an.
  • Die Koordinaten des von Ihnen angegebenen Polygons entsprechen den Koordinaten des nördlichen Teils des Bundesstaates Kalifornien in den USA.
  • Die Funktion geo_inside gibt nur Zeilen zurück, wenn der Standort des Naturparks vollständig in den angegebenen Standortpunkten enthalten ist.
Ergebnis:
{"park_name":"portola redwoods state park",
"park_location":"15000 Skyline Blvd"}

geo_intersect

Bestimmt Geometrien, die sich mit einer GeoJSON-Geometrie überschneiden.
boolean geo_intersect(any*, any*)

Der erste und der zweite Parameter any* können ein beliebiges geometrisches Objekt sein.

Die Funktion bestimmt, ob zwei Geometrien, die als Parameter angegeben werden, Punkte gemeinsam haben. Wenn einer der beiden Parameter kein einzelnes gültiges Geometrieobjekt zurückgibt und es zur Kompilierungszeit erkannt werden kann, löst die Funktion einen Fehler aus.

Das Laufzeitverhalten ist wie folgt:
  • Gibt "false" zurück, wenn ein Parameter 0 oder mehr als 1 Element zurückgibt.
  • Gibt NULL zurück, wenn ein Parameter NULL zurückgibt.
  • Gibt "false" zurück, wenn ein Parameter (zur Laufzeit) ein Element zurückgibt, das kein gültiges Geometrieobjekt ist.

Wenn beide Parameter jeweils ein einzelnes Geometrieobjekt zurückgeben, gibt die Funktion "true" zurück, wenn die 2 Geometrien Punkte gemeinsam haben; andernfalls "false".

Beispiel: Texas erwägt die Regulierung des Zugangs zur unterirdischen Wasserversorgung. Ein Aquifer ist eine unterirdische Schicht aus wasserhaltigem, durchlässigem Gestein, Steinbrüchen oder nicht konsolidierten Materialien. Die Regierung will neue Vorschriften für Standorte erlassen, die einem Aquifer sehr nahe stehen.

Die Koordinaten des Aquifers wurden bereits kartiert. Sie möchten alle Bezirke im Bundesstaat Texas kennen, die sich mit diesem Aquifer überschneiden, damit Sie die Bezirksregierung für jedes betroffene Land über die Teilnahme an Gesprächen über die neuen Vorschriften informieren können.
SELECT t.poi.county AS County_needs_regulation,
t.poi.contact AS Contact_phone
FROM PointsOfInterest t WHERE
geo_intersect(
    t.poi.location,
    { 

     "type" : "polygon",
      "coordinates": [
          [
            [-97.668457031249, 29.34387539941801],
            [-95.207519531258, 29.19053283229458],
            [-92.900390625653, 30.37287518811801],
            [-94.636230468752, 32.21280106801518],
            [-97.778320312522, 32.45415593941475],
            [-99.799804687541, 31.18460913574325],
            [-97.668457031249, 29.34387539941801]
          ]
        ]
    }
);
Erklärung:
  • Die obige Abfrage ruft die Orte ab, die sich mit der Position des Aquifers schneiden. Das heißt, wenn die Standortkoordinaten Punkte mit der Lage des Aquifers gemeinsam haben.
  • Mit geo_intersect können Sie prüfen, ob die Koordinaten des Standorts Punkte aufweisen, die mit den angegebenen Koordinaten des Aquifers übereinstimmen.
Ergebnis:
{"County_needs_regulation":"Tarrant","Contact_phone":"469 745 5687"}
{"County_needs_regulation":"Kinga","Contact_phone":"469 384 7612"}

geo_distance

Bestimmt den Abstand zwischen zwei räumlichen Objekten.
double geo_distance(any*, any*)

Der erste und der zweite Parameter any* können ein beliebiges geometrisches Objekt sein.

Die Funktion gibt den geodätischen Abstand zwischen den beiden Eingabegeometrien zurück. Der zurückgegebene Abstand ist der Mindestabstand zwischen den Abständen eines beliebigen Punktpaares, bei dem der erste Punkt zur ersten Geometrie und der zweite Punkt zur zweiten Geometrie gehört. Zwischen zwei solchen Punkten ist ihr Abstand die Länge der geodätischen Linie, welche die Punkte verbindet.

Übersicht über die geodätische Linie

Eine geodätische Linie zwischen 2 Punkten ist die kürzeste Linie, die zwischen den 2 Punkten auf der ellipsoiden Oberfläche der Erde gezogen werden kann. Für eine vereinfachte, aber illustrativere Definition, nehmen Sie für einen Moment an, dass die Erdoberfläche eine Kugel ist. Dann ist die geodätische Linie zwischen zwei Punkten auf der Erde der kleine Bogen zwischen den beiden Punkten auf dem großen Kreis, der den Punkten entspricht, d.h. dem Kreis, der durch den Schnittpunkt der Kugel und der Ebene gebildet wird, die durch den Mittelpunkt der Erde und die beiden Punkte definiert ist.

Die folgende Abbildung zeigt den Unterschied zwischen den geodätischen und geraden Linien zwischen Los Angeles und London.


Wenn einer der beiden Parameter kein einzelnes gültiges Geometrieobjekt zurückgibt und es zur Kompilierungszeit erkannt werden kann, löst die Funktion einen Fehler aus.

Das Laufzeitverhalten ist wie folgt:
  • Gibt -1 zurück, wenn ein Parameter null oder mehr als 1 Artikel zurückgibt.
  • Gibt NULL zurück, wenn ein Parameter NULL zurückgibt.
  • Gibt -1 zurück, wenn einer der Parameter kein Geometrieobjekt ist.
Andernfalls gibt die Funktion den geodätischen Abstand in Metern zwischen den 2 Eingabegeometrien zurück.

Hinweis:

Die Ergebnisse werden aufsteigend nach Entfernung sortiert (die kürzeste Entfernung wird zuerst angezeigt).
Beispiel: Wie weit ist das nächste Restaurant vom angegebenen Standort entfernt?
SELECT 
t.poi.name AS restaurant_name,
t.poi.address.street AS street_name,
geo_distance(
    t.poi.location,
    { 
       "type" : "point",
       "coordinates": [-121.94034576416016,37.2812239247177]
    }
) AS distance_in_meters
FROM PointsOfInterest t
WHERE t.poi.kind = "restaurant" ;
Erklärung:
  • Sie fragen die Tabelle PointsOfInterest ab, um die Zeilen für Restaurant zu filtern.
  • Sie geben den richtigen Standortpunkt an und bestimmen den Abstand mit der Funktion geo_distance.
Ergebnis:
{"restaurant_name":"Coach Sports Bar & Grill","street_name":"80 Edward St","distance_in_meters":799.2645323337218}
{"restaurant_name":"Ricos Taco","street_name":"80 East Boulevard St","distance_in_meters":976.5361117138553}
{"restaurant_name":"Effie's Restaurant and Bar","street_name":"80 Woodeard St","distance_in_meters":2891.0508307646282}    

Die Entfernung zwischen dem aktuellen Standort und dem nächsten Restaurant beträgt 799 Meter.

geo_within_distance

Bestimmt räumliche Objekte in der Nähe eines Punktes.
boolean geo_within_distance(any*, any*,double)

Der erste und der zweite Parameter any* können ein beliebiges geometrisches Objekt sein.

Die Funktion bestimmt, ob die erste Geometrie in einem Abstand von N Metern zur zweiten Geometrie liegt.

Wenn einer der beiden Parameter kein einzelnes gültiges Geometrieobjekt zurückgibt und es zur Kompilierungszeit erkannt werden kann, löst die Funktion einen Fehler aus.

Das Laufzeitverhalten ist wie folgt:
  • Gibt "false" zurück, wenn ein Parameter 0 oder mehr als 1 Element zurückgibt.
  • Gibt NULL zurück, wenn einer der ersten beiden Parameter NULL zurückgibt.
  • Gibt "false" zurück, wenn einer der ersten beiden Parameter ein Element zurückgibt, das kein gültiges Geometrieobjekt ist.

Wenn beide Parameter jeweils ein einzelnes Geometrieobjekt zurückgeben, wird "true" zurückgegeben, wenn sich die erste Geometrie in einem Abstand von N Metern zur zweiten Geometrie befindet, wobei "N" die vom dritten Parameter zurückgegebene Zahl ist, andernfalls "false". Der Abstand zwischen 2 Geometrien ist als der Mindestabstand zwischen den Abständen eines beliebigen Punktpaares definiert, bei dem der erste Punkt zur ersten Geometrie und der zweite Punkt zur zweiten Geometrie gehört. Wenn N eine negative Zahl ist, wird sie auf 0 gesetzt.

Beispiel: Ist dort in den nächsten 5 km ein Rathaus? Wie weit ist es?
SELECT t.poi.address.street AS city_hall_address,
geo_distance(
    t.poi.location,
    { 
        "type" : "point",
        "coordinates" : [-120.653828125,38.85682013474361]
    }

) AS distance_in_meters
FROM PointsOfInterest t
WHERE t.poi.kind = "city hall" AND
geo_within_distance( 
    t.poi.location,
    { 
        "type" : "point",
        "coordinates" : [-120.653828125,38.85682013474361]
    },
    5000
);
Erklärung:
  • Sie fragen die Tabelle PointsOfInterest ab, um die Zeilen für die Stadthalle zu filtern.
  • Mit der Funktion geo_within_distance können Sie das Rathaus innerhalb von 5 km (5000m) des angegebenen Standorts filtern.
  • Sie können auch die tatsächliche Entfernung zwischen Ihrem Standort und dem Rathaus mit der Funktion geo_distance abrufen.
Ergebnis:
{"city_hall_address":"70 North 1st street","distance_in_meters":1736.0144040331768}

Das Rathaus ist 1736 m (1,73 km) vom aktuellen Standort entfernt.

geo_near

Bestimmt räumliche Objekte in der Nähe eines Punktes.
boolean geo_near(any*, any*, double)

Der erste und der zweite Parameter any* können ein beliebiges geometrisches Objekt sein.

Die Funktion bestimmt, ob die erste Geometrie in einem Abstand von N Metern zur zweiten Geometrie liegt.

Wenn einer der beiden Parameter kein einzelnes gültiges Geometrieobjekt zurückgibt und es zur Kompilierungszeit erkannt werden kann, löst die Funktion einen Fehler aus.

Das Laufzeitverhalten ist wie folgt:
  • Gibt "false" zurück, wenn ein Parameter 0 oder mehr als 1 Element zurückgibt.
  • Gibt NULL zurück, wenn einer der ersten beiden Parameter NULL zurückgibt.
  • Gibt "false" zurück, wenn einer der ersten beiden Parameter ein Element zurückgibt, das kein gültiges Geometrieobjekt ist.
Wenn schließlich beide der ersten beiden Parameter jeweils ein einzelnes Geometrieobjekt zurückgeben, wird "true" zurückgegeben, wenn sich die erste Geometrie in einem Abstand von N Metern zur zweiten Geometrie befindet, wobei N die vom dritten Parameter zurückgegebene Zahl ist; andernfalls "false".

Hinweis:

geo_near wird intern in geo_within_distance plus eine (implizite) Reihenfolge um den Abstand zwischen den beiden Geometrien konvertiert. Wenn die Abfrage jedoch bereits eine (explizite) Sortierung aufweist, wird keine Sortierung nach Entfernung ausgeführt. Die Funktion geo_near kann nur in der WHERE-Klausel angezeigt werden, wobei sie ein Prädikat der obersten Ebene sein muss, d.h. nicht unter einem OR- oder NOT-Operator verschachtelt sein muss.
Beispiel 1: Gibt es ein Krankenhaus innerhalb von 3 km vom angegebenen Standort?
SELECT 
t.poi.name AS hospital_name,
t.poi.address.street AS hospital_address
FROM PointsOfInterest t
WHERE t.poi.kind = "hospital" 
AND
geo_near( 
    t.poi.location,
    {"type" : "point",
     "coordinates" : [-122.03493933105469,37.32949164059004]  
    },
    3000
);
Erklärung:
  • Sie fragen die Tabelle PointsOfInterest ab, um die Zeilen für Krankenhaus zu filtern.
  • Mit der Funktion geo_near können Sie Krankenhäuser innerhalb von 3000m des angegebenen Standorts filtern.
Ergebnis:
{"hospital_name":"St. Marthas hospital","hospital_address":"18000 West Blvd"}
{"hospital_name":"Memorial hospital","hospital_address":"10500 South St"}
Beispiel 2: Wie weit ist eine Tankstelle innerhalb der nächsten Meile vom angegebenen Standort entfernt?
SELECT 
t.poi.address.street AS gas_station_address,
geo_distance(
    t.poi.location,
    { 
        "type" : "point",
        "coordinates" : [-121.90768646240233,37.292081740702365] 
    }
) AS distance_in_meters
FROM PointsOfInterest t
WHERE t.poi.kind = "gas station" AND
geo_near( 
    t.poi.location,
    { 
        "type" : "point",
        "coordinates" : [-121.90768646240233,37.292081740702365]
    },
    1600
);
Erklärung:
  • Sie fragen die Tabelle PointsOfInterest ab, um die Zeilen für die Tankstelle zu filtern.
  • Mit der Funktion geo_near können Sie Tankstellen innerhalb einer Meile (1600m) des angegebenen Standorts filtern.
  • Sie können auch den tatsächlichen Abstand zwischen Ihrem Standort und der Tankstelle mit der Funktion geo_distance abrufen.
Ergebnis:
{"gas_station_address":"33 North Avenue","distance_in_meters":886.7004173859665}

Die tatsächliche Entfernung zur nächsten Tankstelle innerhalb der nächsten Meile ist 886m.

geo_is_geometry

Validiert ein räumliches Objekt.
boolean geo_is_geometry(any*)

Der Parameter any* kann ein beliebiges geometrisches Objekt sein.

Die Funktion bestimmt, ob die angegebene Eingabe ein gültiges Geometrieobjekt ist.
  • Gibt "false" zurück, wenn der Parameter null oder mehr als 1 Artikel zurückgibt.
  • Gibt NULL zurück, wenn der Parameter NULL zurückgibt.
  • Gibt "true" zurück, wenn die Eingabe ein einzelnes gültiges Geometrieobjekt ist. Sonst ist er False.
Beispiel: Legen Sie fest, ob der Standort, der auf die Halle verweist, ein gültiges geometrisches Objekt ist.
SELECT geo_is_geometry(t.poi.location) AS city_hall
FROM PointsOfInterest t
WHERE t.poi.kind = "city hall" 

Erläuterung: Mit der Funktion geo_is_geometry bestimmen Sie, ob eine bestimmte Position ein gültiges geometrisches Objekt ist.

Ergebnis:
{ "city_hall" : true}