Kapitel 18. Raumbezogene Erweiterungen in MySQL
Zurück |  | Weiter

## Kapitel 18. Raumbezogene Erweiterungen in MySQL

Mit den raumbezogenen Erweiterungen von MySQL lassen sich geographische Features erstellen, speichern und analysieren. Diese Features stehen für `MyISAM`-, `InnoDB`-, `NDB`-, `BDB`- und `ARCHIVE`-Tabellen zur Verfügung. (Da jedoch die `ARCHIVE`-Engine keine Indizes unterstützt, können raumbezogene Spalten in `ARCHIVE` nicht indiziert werden. Auch in MySQL Cluster sind keine Indizes auf raumbezogenen Spalten möglich.

Dieses Kapitel behandelt folgende Themen:

- Grundlagen der raumbezogenen Erweiterungen im Geodatenmodell OpenGIS

- Datenformate zur Darstellung raumbezogener Daten

- Wie raumbezogene Daten in MySQL verwendet werden

- Indizierung raumbezogener Daten

- MySQLs Abweichungen von der OpenGIS-Spezifikation

Mehr zum Thema

- Das Open Geospatial Consortium veröffentlicht das OpenGIS® Simple Features Specifications For SQL: ein Dokument, das mehrere Konzepte vorstellt, wie ein auf SQL basierendes relationales Datenbanksystem auch raumbezogene Daten unterstützen könnte. Diese Spezifikation finden Sie auf der Website des OGC unter http://www.opengis.org/docs/99-049.pdf.

- Wenn Sie Fragen oder sonstige Anliegen hinsichtlich der raumbezogenen Erweiterungen zu MySQL haben, können Sie diese im GIS-Forum zur Diskussion stellen: http://forums.mysql.com/list.php?23.

## 18.1. Einführung in die raumbezogenen Funktionen von MySQL

MySQL implementiert raumbezogene Erweiterungen nach der Spezifikation des Open Geospatial Consortium (OGC). Dabei handelt es sich um ein internationales Konsortium von mehr als 250 Unternehmen, Behörden und Universitäten, die alle an der Entwicklung von öffentlich zugänglichen, konzeptionellen Lösungen für alle Arten von Programmen arbeiten, welche mit der Verwaltung raumbezogener Daten zu tun haben. Das OGC betreibt eine Website unter http://www.opengis.org/.

Im Jahre 1997 veröffentlichte das Open Geospatial Consortium die OpenGIS® Simple Features Specifications For SQL, ein Dokument, das mehrere Konzepte vorstellt, wie ein SQL-RDBMS raumbezogene Daten unterstützen könnte. Diese Spezifikation finden Sie auf der Website des OGC unter http://www.opengis.org/docs/99-049.pdf. Sie enthält wichtige Zusatzinformationen zu diesem Kapitel.

MySQL implementiert einen Teil der vom OGC empfohlenen SQL with Geometry Types-Umgebung. Gemeint ist damit eine SQL-Umgebung, die um eine Reihe von geometrischen Typen erweitert wurde. Eine SQL-Spalte, die einen geometrischen Wert hat, wird als Spalte geometrischen Typs implementiert. Die Spezifikation beschreibt eine Reihe von geometrischen Typen für SQL sowie Funktionen, die mit diesen Typen arbeiten können, um geometrische Werte zu erzeugen und zu analysieren.

Ein geographisches Feature ist irgendetwas, das irgendwo auf der Welt einen Standort hat. Hierzu gehören:

- ein Gegenstand, wie zum Beispiel ein Berg, ein Teich oder eine Stadt

- ein Raum, wie beispielsweise ein Postleitzahlengebiet oder die Tropen

- ein klar definierter Ort, wie zum Beispiel eine Straßenkreuzung als der Schnittpunkt zweier Straßen

In manchen Dokumenten werden geographische Features als geospatiale Features bezeichnet.

Auch das Wort Geometrie bezeichnet ein geographisches Feature. Ursprünglich wurde der Begriff Geometrie für die Vermessung der Erde verwendet. Eine weitere Bedeutung bekam das Wort in der Kartographie, wo es die geometrischen Merkmale bezeichnet, die Kartographen für ihr Abbild der Welt verwenden.

Im vorliegenden Kapitel werden die Begriffe geographisches Feature, geospatiales Feature, Feature und Geometrie synonym eingesetzt. Am häufigsten verwenden wir das Wort Geometrie im Sinne von einem Punkt oder einer Menge von Punkten, die irgendetwas auf der Welt darstellen, das sich an einem Ort befindet.

## 18.2. Das OpenGIS-Geometriemodell

Die Geometrietypen, die das OGC in seiner SQL with Geometry Types-Umgebung vorschlägt, beruhen auf dem OpenGIS Geometry Model. In diesem Modell hat jedes geometrische Objekt folgende allgemeine Eigenschaften:

- Es ist verbunden mit einem Georeferenzsystem, welches den Koordinatenraum beschreibt, in dem das Objekt definiert ist.

- Es gehört zu einer Geometrieklasse.

### 18.2.1. Hierarchie der Geometrieklassen

Die Geometrieklassen definieren folgende Hierarchie:

- `Geometry` (nichtinstanziierbar)

  - `Point` (instanziierbar)

  - `Curve` (nichtinstanziierbar)

    - `LineString` (instanziierbar)

      - `Line`

      - `LinearRing`

  - `Surface` (nichtinstanziierbar)

    - `Polygon` (instanziierbar)

  - `GeometryCollection` (instanziierbar)

    - `MultiPoint` (instanziierbar)

    - `MultiCurve` (nichtinstanziierbar)

      - `MultiLineString` (instanziierbar)

    - `MultiSurface` (nichtinstanziierbar)

      - `MultiPolygon` (instanziierbar)

Von nichtinstanziierbaren Klassen können keine Objekte erzeugt werden, von instanziierbaren Klassen hingegen sehr wohl. Alle Klassen haben Eigenschaften und instanziierbare Klassen können darüber hinaus Zusicherungen machen (Regeln, nach denen gültige Klasseninstanzen definiert sind).

`Geometry` ist die abstrakte Basisklasse. Die instanziierbaren Unterklassen von `Geometry` dürfen nur null-, eins- und zweidimensionale geometrische Objekte haben, die in einem zweidimensionalen Koordinatenraum vorkommen. Alle instanziierbaren Geometrieklassen sind so definiert, dass gültige Instanzen dieser Klassen topologisch geschlossen sein müssen (d. h., in allen definierten Geometrien ist ihre jeweilige Grenze enthalten).

Die Basisklasse `Geometry` hat die Unterklassen `Point`, `Curve`, `Surface` und `GeometryCollection`:

- `Point` stellt nulldimensionale Objekte dar.

- `Curve` stellt eindimensionale Objekte dar und hat die Unterklasse `LineString`, die ihrerseits die Unterklassen `Line` und `LinearRing` hat.

- `Surface` ist für zweidimensionale Objekte da und hat die Unterklasse `Polygon`.

- `GeometryCollection` besitzt die spezialisierten null-, eins- und zweidimensionalen Collection-Klassen namens `MultiPoint`, `MultiLineString` und `MultiPolygon` zur Modellierung von Geometrien aus `Points`, `LineStrings` oder `Polygons`. `MultiCurve` und `MultiSurface` sind abstrakte Oberklassen, die Collection-Interfaces für den Umgang mit `Curves` und `Surfaces` realisieren.

`Geometry`, `Curve`, `Surface`, `MultiCurve` und `MultiSurface` sind nichtinstanziierbare Klassen. Sie definieren eine Menge von gemeinsamen Methoden für ihre Unterklassen und sind dazu da, erweitert zu werden.

`Point`, `LineString`, `Polygon`, `GeometryCollection`, `MultiPoint`, `MultiLineString` und `MultiPolygon` sind instanziierbare Klassen.

### 18.2.2. Die Klasse `Geometry`

`Geometry` ist die Wurzelklasse der Hierarchie. Sie ist eine nichtinstanziierbare Klasse, besitzt jedoch eine Reihe von Eigenschaften, die alle Klassen gemeinsam haben, welche aus einer Unterklasse von `Geometry` erzeugt wurden. Diese Eigenschaften werden in der folgenden Liste aufgeführt. Bestimmte Unterklassen haben ihre eigenen, ganz speziellen Eigenschaften, die weiter unten beschrieben werden.

Geometrie-Eigenschaften

Ein Geometriewert hat folgende Eigenschaften:

- Den Typ. Jeder Geometriewert gehört zu einer der instanziierbaren Klassen der Hierarchie.

- Seinen SRID (Spatial Reference Identifier). Dieser Wert steht für das Georeferenzsystem, welches den Koordinatenraum beschreibt, in dem das Geometrieobjekt definiert ist.

  In MySQL ist der SRID-Wert ein einfacher Integer, der mit dem Geometriewert verbunden ist. Allen Berechnungen liegt die euklidische (planare) Geometrie zugrunde.

- Seine Koordinaten in seinem Georeferenzsystem, dargestellt als Zahlen mit doppelter Genauigkeit (8 Byte). Alle nichtleeren Geometrien enthalten mindestens ein Koordinatenpaar (x,y). Leere Geometrien enthalten keine Koordinaten.

  Koordinaten hängen mit dem SRID zusammen. So kann zum Beispiel in unterschiedlichen Koordinatensystemen der Abstand zwischen zwei Objekten verschieden sein, selbst dann, wenn die Objekte dieselben Koordinaten haben, da der Abstand in einem planaren Koordinatensystem und der Abstand in einem geozentrischen System (die Koordinaten auf der Erdoberfläche) zwei verschiedene Dinge sind.

- Seinen Innenbereich, seine Grenze und seinen Außenbereich.

  Jede Geometrie hat irgendeine Position im Raum. Der Außenbereich ist der Raum, welcher nicht von der Geometrie belegt wird, und der Innenbereich der Raum, der von ihr bedeckt ist. Die Grenze ist die Schnittstelle zwischen Innenbereich und Außenbereich der Geometrie.

- Sein MBR (Minimum Bounding Rectangle, dt.: kleinstes einschließendes Rechteck), auch Envelope genannt. Dies ist die begrenzende Geometrie, die durch die kleinsten und größten (x,y)-Koordinaten gebildet wird:

      ((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))

- Ob der Wert einfach (simple) oder nicht einfach (non-simple) ist. Geometriewerte der Typen `LineString`, `MultiPoint` und `MultiLineString` sind entweder einfach oder nicht einfach. Jeder Typ hat seine eigenen Zusicherungen darüber, ob er einfach oder nicht einfach ist.

- Ob der Wert geschlossen oder nicht geschlossen ist. Geometriewerte der Typen (`LineString`, `MultiString`) sind entweder geschlossen oder nicht geschlossen. Jeder Typ hat seine eigenen Zusicherungen darüber, ob er geschlossen oder nicht geschlossen ist.

- Ob der Wert leer oder nichtleer ist. Eine Geometrie ist leer, wenn sie keine Punkte enthält. Außenbereich, Innenbereich und Grenze einer leeren Geometrie sind nicht definiert (d. h., sie werden durch einen `NULL`-Wert dargestellt). Eine leere Geometrie ist per Definition immer einfach und hat die Fläche 0.

- Seine Dimension. Eine Geometrie kann die Dimension –1, 0, 1 oder 2 haben:

  - –1 für eine leere Geometrie.

  - 0 für eine Geometrie ohne Länge und ohne Fläche.

  - 1 für eine Geometrie mit einer von null verschiedenen Länge und der Fläche null.

  - 2 für eine Geometrie mit einer von null verschiedenen Fläche.

  `Point`-Objekte haben die Dimension null. `LineString`-Objekte haben die Dimension 1. `Polygon`-Objekte haben die Dimension 2. `MultiPoint`-, `MultiLineString`- und `MultiPolygon`-Objekte haben dieselben Dimensionen wie die Elemente, aus denen sie bestehen.

### 18.2.3. Die Klasse `Point`

Ein `Point` ist eine Geometrie, die einen einzigen Punkt im Koordinatenraum darstellt.

Beispiele für `Point`

- Stellen Sie sich eine Weltkarte in großem Maßstab mit vielen Städten vor. Die Städte könnte man mit `Point`-Objekten darstellen.

- Auf einem Stadtplan könnte ein `Point`-Objekt eine Bushaltestelle darstellen.

Eigenschaften von `Point`

- Wert der x-Koordinate.

- Wert der y-Koordinate.

- Ein `Point` ist als eine nulldimensionale Geometrie definiert.

- Die Grenze eines `Point`s ist die leere Menge.

### 18.2.4. Die Klasse `Curve`

Eine `Curve` ist eine eindimensionale Geometrie, die in der Regel durch eine Abfolge von Punkten dargestellt wird. Spezielle Unterklassen von `Curve` definieren die Art der Interpolation zwischen den Punkten. `Curve` ist eine nichtinstanziierbare Klasse.

Eigenschaften von `Curve`

- Eine `Curve` hat die Koordinaten ihrer Punkte.

- Eine `Curve` ist als eindimensionale Geometrie definiert.

- Eine `Curve` ist einfach, wenn sie nicht zweimal durch denselben Punkt geht.

- Eine `Curve` ist geschlossen, wenn ihr Anfangs- gleich ihrem Endpunkt ist.

- Die Grenze einer geschlossenen `Curve` ist leer.

- Die Grenze einer nicht geschlossenen `Curve` besteht aus ihren beiden Endpunkten.

- Eine `Curve`, die einfach und geschlossen ist, ist ein `LinearRing`.

### 18.2.5. Die Klasse `LineString`

Ein `LineString` ist eine `Curve` mit linearer Interpolation zwischen den Punkten.

Beispiele für `LineString`

- Auf einer Weltkarte könnten `LineString`-Objekte Flüsse darstellen.

- Auf einem Stadtplan könnten `LineString`-Objekte Straßen darstellen.

Eigenschaften von `LineString`

- Ein `LineString` hat Segmentkoordinaten, die durch jeweils aufeinander folgende Punktpaare definiert sind.

- Ein `LineString` ist eine `Line`, wenn er aus genau zwei Punkten besteht.

- Ein `LineString` ist ein `LinearRing`, wenn er sowohl geschlossen als auch einfach ist.

### 18.2.6. Die Klasse `Surface`

Eine `Surface` ist eine zweidimensionale Geometrie. Sie ist eine nichtinstanziierbare Klasse. Ihre einzige instanziierbare Unterklasse ist `Polygon`.

Eigenschaften von `Surface`

- Eine `Surface` ist als zweidimensionale Geometrie definiert.

- Die OpenGIS-Spezifikation definiert eine einfache `Surface` als eine Geometrie, die aus einem einzelnen „Patch“ besteht, zu dem eine einzige Außengrenze und null oder mehr Innengrenzen gehören.

- Die Grenze einer einfachen `Surface` ist die Menge der geschlossenen Kurven, die ihrer Außen- und Innengrenze entsprechen.

### 18.2.7. Die Klasse `Polygon`

Ein `Polygon` ist eine planare `Surface`, die eine mehrseitige Geometrie darstellt. Sie ist definiert durch eine einzige Außengrenze und null oder mehr Innengrenzen, wobei jede Innengrenze ein Loch im `Polygon` darstellt.

Beispiele für `Polygon`

- Auf einer Regionalkarte könnten `Polygon`-Objekte Wälder, Landkreise usw. darstellen.

Zusicherungen von `Polygon`

- Die Grenze eines `Polygon` besteht aus einer Menge von `LinearRing`-Objekten (d. h. `LineString`-Objekten, die sowohl einfach als auch geschlossen sind), die seine Außen- und seine Innengrenze bilden.

- Ein `Polygon` wird nicht von Ringen geschnitten. Ringe können in der Grenze eines `Polygon` zwar einen `Point` berühren, aber nur als Tangente.

- Ein `Polygon` hat keine geschnittenen Linien, Zacken (Spikes) oder Lücken (Punctures).

- Der Innenbereich eines `Polygon` ist eine Menge verbundener Punkte.

- Ein `Polygon` kann Löcher haben. Der Außenbereich eines `Polygon` mit Löchern ist unzusammenhängend. Jedes Loch definiert einen zusammenhängenden Bestandteil des Außenbereichs.

Aufgrund dieser Zusicherungen ist ein `Polygon` eine einfache Geometrie.

### 18.2.8. Die Klasse `GeometryCollection`

Eine `GeometryCollection` ist eine Sammlung aus einer oder mehreren Geometrien beliebiger Klassen.

Alle Elemente einer `GeometryCollection` müssen dasselbe Georeferenzsystem (also dasselbe Koordinatensystem) haben. Andere Beschränkungen für die Elemente einer `GeometryCollection` gibt es nicht, auch wenn die in den folgenden Abschnitten vorgestellten Unterklassen von `GeometryCollection` nicht alles aufnehmen. Folgende Einschränkungen können für Mitglieder dieser Klasse gelten:

- Einschränkung des Elementtyps (so kann zum Beispiel ein `MultiPoint` nur `Point`-Elemente enthalten)

- Einschränkung der Dimensionen

- Einschränkung der räumlichen Überschneidung von Elementen

### 18.2.9. Die Klasse `MultiPoint`

Ein `MultiPoint` ist eine Ansammlung von `Point`-Geometrien. Die Punkte sind nicht verbunden oder geordnet.

Beispiele für `MultiPoint`

- Auf einer Weltkarte könnte ein `MultiPoint` eine Kette kleiner Inseln darstellen.

- Auf einem Stadtplan könnte ein `MultiPoint` Fahrkartenverkaufsstellen darstellen.

Eigenschaften von `MultiPoint`

- Ein `MultiPoint` ist eine nulldimensionale Geometrie.

- Ein `MultiPoint` ist einfach, wenn keine zwei seiner `Point`-Werte gleich sind (dieselben Koordinatenwerte haben).

- Die Grenze eines `MultiPoint` ist die leere Menge.

### 18.2.10. Die Klasse `MultiCurve`

Eine `MultiCurve` ist eine Ansammlung von `Curve`-Geometrien. `MultiCurve` ist eine nichtinstanziierbare Klasse.

Eigenschaften von `MultiCurve`

- Eine `MultiCurve` ist eine eindimensionale Geometrie.

- Eine `MultiCurve` ist genau dann einfach, wenn alle ihre Elemente einfach sind. Die einzigen Überschneidungen von zwei Elementen können an Punkten auftreten, die auf den Grenzen beider Elemente liegen.

- Eine `MultiCurve`-Grenze erhalten Sie durch Anwendung der „Mod 2 Union Rule“ (auch „Ungleich-Gleich-Regel“ genannt): Ein Punkt liegt auf der Grenze einer `MultiCurve`, wenn er auf den Grenzen einer ungeraden Anzahl von `MultiCurve`-Elementen liegt.

- Eine `MultiCurve` ist geschlossen, wenn alle ihre Elemente geschlossen sind.

- Die Grenze einer geschlossenen `MultiCurve` ist immer leer.

### 18.2.11. Die Klasse `MultiLineString`

Ein `MultiLineString` ist eine Ansammlung von `MultiCurve`-Geometrien, die aus `LineString`-Elementen besteht.

Beispiele für `MultiLineString`

- Auf einer Regionalkarte könnte ein `MultiLineString` ein Flusssystem oder ein Straßennetz darstellen.

### 18.2.12. Die Klasse `MultiSurface`

Eine `MultiSurface` ist eine Ansammlung von Geometrien, die aus Oberflächenelementen besteht. `MultiSurface` ist eine nichtinstanziierbare Klasse. Ihre einzige instanziierbare Unterklasse ist `MultiPolygon`.

Zusicherungen von `MultiSurface`

- Der Innenbereich von zwei `MultiSurface`-Oberflächen darf sich nicht überschneiden.

- Die Grenzen von zwei `MultiSurface`-Elementen dürfen sich höchstens an einer endlichen Anzahl von Punkten überschneiden.

### 18.2.13. Die Klasse `MultiPolygon`

Ein `MultiPolygon` ist ein `MultiSurface`-Objekt, das aus `Polygon`-Elementen besteht.

Beispiele für `MultiPolygon`

- Auf einer Regionalkarte könnte ein `MultiPolygon` eine Seenplatte darstellen.

Zusicherungen für`MultiPolygon`

- Ein `MultiPolygon` hat keine zwei `Polygon`-Elemente, deren Innenbereiche sich überschneiden.

- Ein `MultiPolygon` hat keine zwei `Polygon`-Elemente, die sich überschneiden (diese Überschneidung wurde auch bereits durch die vorige Zusicherung untersagt) oder sich an einer unendlichen Anzahl von Punkten berühren.

- Ein `MultiPolygon` darf keine geschnittenen Linien, Zacken oder Lücken haben. Ein `MultiPolygon` ist eine regelmäßige, geschlossene Punktmenge.

- Ein `MultiPolygon` mit mehreren `Polygon`en hat einen unzusammenhängenden Innenbereich. Die Anzahl der zusammenhängenden Bestandteile des Innenbereichs eines `MultiPolygon` ist gleich der Anzahl seiner `Polygon`e.

Eigenschaften von `MultiPolygon`

- Ein `MultiPolygon` ist eine zweidimensionale Geometrie.

- Die Grenze eines `MultiPolygon` besteht aus einer Menge von geschlossenen Kurven (`LineString`-Werten), die den Grenzen seiner `Polygon`-Elemente entsprechen.

- Jede `Curve` auf der Grenze des `MultiPolygon` liegt auf der Grenze von genau einem `Polygon`-Element.

- Jede `Curve` auf der Grenze eines `Polygon`-Elements liegt auf der Grenze des `MultiPolygon`.

## 18.3. Unterstützte raumbezogene Datenformate

Dieser Abschnitt beschreibt die raumbezogenen Standarddatenformate, mit denen Geometrieobjekte in Datenbankanfragen dargestellt werden. Diese sind:

- Well-Known Text(WKT)-Format

- Well-Known Binary(WKB)-Format

Intern speichert MySQL Geometriewerte in einem Format, das weder WKT noch WKB gleicht.

### 18.3.1. Well-Known Text(WKT)-Format

Die Well-Known Text(WKT)-Darstellung von Geometrien wurde geschaffen, um Geometriedaten in ASCII-Format austauschen zu können.

Beispiele für WKT-Darstellung von Geometrieobjekten:

- Ein `Point`:

      POINT(15 20)

  Beachten Sie, dass Punktkoordinaten ohne Komma dazwischen angegeben werden.

- Ein `LineString` mit vier Punkten:

      LINESTRING(0 0, 10 10, 20 25, 50 60)

  Beachten Sie, dass zwischen den Punktkoordinatenpaaren jeweils ein Komma steht.

- Ein `Polygon` mit einem äußeren und einem inneren Ring:

      POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))

- Ein `MultiPoint` mit drei `Point`-Werten:

      MULTIPOINT(0 0, 20 20, 60 60)

- Ein `MultiLineString` mit zwei `LineString`-Werten:

      MULTILINESTRING((10 10, 20 20), (15 15, 30 15))

- Ein `MultiPolygon` mit zwei `Polygon`-Werten:

      MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))

- Eine `GeometryCollection`, die aus zwei `Point`-Werten und einem `LineString` besteht:

      GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))

Eine Backus-Naur-Grammatik mit den formalen Produktionsregeln zum Schreiben von WKT-Werten finden Sie in der OpenGIS-Spezifikation, auf die zu Beginn dieses Kapitels bereits verwiesen wurde.

### 18.3.2. Well-Known Binary(WKB)-Format

Die Well-Known Binary(WKB)-Darstellung für Geometriewerte ist in der OpenGIS-Spezifikation sowie im ISO-Standard SQL/MM Part 3: Spatial definiert.

Mit der WKB-Darstellung werden Geometriedaten als Binärströme übermittelt. Diese sind `BLOB`-Werte, die geometrische WKB-Informationen enthalten.

WKB verwendet Ein-Byte-Integer ohne Vorzeichen, Vier-Byte-Integer ohne Vorzeichen und Acht-Byte-Zahlen mit doppelter Genauigkeit (IEEE 754 format). Ein Byte sind acht Bits.

So besteht beispielsweise ein WKB-Wert, der `POINT(1 1)` darstellt, aus der folgenden Reihe von 21 Byte (hier jeweils durch zwei Hexadezimalziffern dargestellt):

    0101000000000000000000F03F000000000000F03F

Diese Folge lässt sich in folgende Bestandteile zerlegen:

    Byte order : 01
    WKB type   : 01000000
    X          : 000000000000F03F
    Y          : 000000000000F03F

Die Bestandteile werden folgendermaßen dargestellt:

- Die Byte-Reihenfolge kann 0 (Little-Endian-Speicherung) oder 1 (Big-Endian-Speicherung) sein. Diese Byte-Reihenfolgen bezeichnet man auch als Network Data Representation (NDR) bzw. External Data Representation (XDR).

- Der WKB-Typ ist ein Code, der den Geometrietyp angibt. Seine Werte von 1 bis 7 bedeuten `Point`, `LineString`, `Polygon`, `MultiPoint`, `MultiLineString`, `MultiPolygon` und `GeometryCollection`.

- Ein `Point`-Wert hat x- und y-Koordinaten, die jeweils als Wert mit doppelter Genauigkeit dargestellt sind.

Die WKB-Werte für komplexere Geometriewerte werden durch komplexere Datenstrukturen dargestellt. Diese sind in der OpenGIS-Spezifikation genauer beschrieben.

## 18.4. Erzeugen einer MySQL-Datenbank mit raumbezogenen Werten

Der folgende Abschnitt beschreibt die Datentypen für raumbezogene Daten in MySQL und die Funktionen zur Erstellung und Abfrage raumbezogener Werte.

### 18.4.1. Raumbezogene Datentypen in MySQL

Die Datentypen von MySQL entsprechen den Klassen von OpenGIS. Einige dieser Typen speichern einzelne Geometriewerte:

- `GEOMETRY`

- `POINT`

- `LINESTRING`

- `POLYGON`

`GEOMETRY` kann Geometriewerte jeden Typs speichern. Die anderen Einzelwerttypen (`POINT`, `LINESTRING` und `POLYGON`) können nur Werte eines bestimmten Geometrietyps aufnehmen.

Die anderen Datentypen speichern Sammlungen von Werten:

- `MULTIPOINT`

- `MULTILINESTRING`

- `MULTIPOLYGON`

- `GEOMETRYCOLLECTION`

`GEOMETRYCOLLECTION` kann eine Ansammlung von Objekten beliebigen Typs speichern. Die anderen Collection-Typen (`MULTIPOINT`, `MULTILINESTRING`, `MULTIPOLYGON` und `GEOMETRYCOLLECTION`) können nur Werte eines bestimmten Geometrietyps aufnehmen.

### 18.4.2. Erzeugung raumbezogener Werte

Dieser Abschnitt beschreibt, wie raumbezogene Werte mithilfe der Well-Known Text- und Well-Known Binary-Funktionen des OpenGIS-Standards und mit MySQL-spezifischen Funktionen erzeugt werden.

#### 18.4.2.1. Erzeugung von Geometriewerten mit WKT-Funktionen

MySQL stellt eine Reihe von Funktionen zur Verfügung, die als Eingabeparameter eine Well-Known Text-Darstellung und optional einen Georeferenzsystembezeichner (Spatial Reference System Identifier, SRID) annehmen und die entsprechende Geometrie zurückliefern.

`GeomFromText()` nimmt einen WKT eines beliebigen Geometrietyps als erstes Argument entgegen. Eine Implementierung stellt auch typspezifische Konstruktorfunktionen zur Erzeugung von Geometriewerten jedes Geometrietyps zur Verfügung.

- `GeomCollFromText(`wkt`[,`srid`])`, `GeometryCollectionFromText(`wkt`[,`srid`])`

  Erzeugt einen `GEOMETRYCOLLECTION`-Wert anhand seiner WKT-Darstellung und seines SRID.

- `GeomFromText(`wkt`[,`srid`])`, `GeometryFromText(`wkt`[,`srid`])`

  Erzeugt einen Geometriewert irgendeines Typs anhand seiner WKT-Darstellung und seines SRID.

- `LineFromText(`wkt`[,`srid`])`, `LineStringFromText(`wkt`[,`srid`])`

  Erzeugt einen `LINESTRING`-Wert anhand seiner WKT-Darstellung und seines SRID.

- `MLineFromText(`wkt`[,`srid`])`, `MultiLineStringFromText(`wkt`[,`srid`])`

  Erzeugt einen `MULTILINESTRING`-Wert anhand seiner WKT-Darstellung und seines SRID.

- `MPointFromText(`wkt`[,`srid`])`, `MultiPointFromText(`wkt`[,`srid`])`

  Erzeugt einen `MULTIPOINT`-Wert anhand seiner WKT-Darstellung und seines SRID.

- `MPolyFromText(`wkt`[,`srid`])`, `MultiPolygonFromText(`wkt`[,`srid`])`

  Erzeugt einen `MULTIPOLYGON`-Wert anhand seiner WKT-Darstellung und seines SRID.

- `PointFromText(`wkt`[,`srid`])`

  Erzeugt einen `POINT`-Wert anhand seiner WKT-Darstellung und seines SRID.

- `PolyFromText(`wkt`[,`srid`])`, `PolygonFromText(`wkt`[,`srid`])`

  Erzeugt einen `POLYGON`-Wert anhand seiner WKT-Darstellung und seines SRID.

Die OpenGIS-Spezifikation definiert auch die folgenden optionalen Funktionen, die MySQL nicht implementiert. Diese Funktionen erzeugen `Polygon`- oder `MultiPolygon`-Werte anhand der WKT-Darstellung einer Sammlung von Ringen oder geschlossenen `LineString`-Werten. Diese Werte können sich schneiden.

- `BdMPolyFromText(`wkt`,`srid`)`

  Erzeugt einen `MultiPolygon`-Wert aus einem `MultiLineString`-Wert im WKT-Format, der eine beliebige Sammlung geschlossener `LineString`-Werte enthält.

- `BdPolyFromText(`wkt`,`srid`)`

  Erzeugt einen `Polygon`-Wert aus einem `MultiLineString`-Wert im WKT-Format, der eine beliebige Sammlung geschlossener `LineString`-Werte enthält.

#### 18.4.2.2. Erzeugung von Geometriewerten mit WKB-Funktionen

MySQL kennt Funktionen, die als Eingabeparameter einen `BLOB` annehmen, welcher eine Well-Known Binary-Darstellung und optional auch einen Georeferenzsystembezeichner (SRID) entgegennehmen. Sie geben die entsprechende Geometrie zurück.

`GeomFromWKB()` nimmt eine WKB eines beliebigen Geometrietyps als erstes Argument entgegen. Es gibt auch eine Implementierung für typspezifische Konstruktionsfunktionen, die Geometriewerte der einzelnen Geometrietypen erzeugen.

- `GeomCollFromWKB(`wkb`[,`srid`])`, `GeometryCollectionFromWKB(`wkb`[,`srid`])`

  Erzeugt einen `GEOMETRYCOLLECTION`-Wert anhand seiner WKB-Darstellung und seines SRID.

- `GeomFromWKB(`wkb`[,`srid`])`, `GeometryFromWKB(`wkb`[,`srid`])`

  Erzeugt einen Geometriewert beliebigen Typs anhand seiner WKB-Darstellung und seines SRID.

- `LineFromWKB(`wkb`[,`srid`])`, `LineStringFromWKB(`wkb`[,`srid`])`

  Erzeugt einen `LINESTRING`-Wert anhand seiner WKB-Darstellung und seines SRID.

- `MLineFromWKB(`wkb`[,`srid`])`, `MultiLineStringFromWKB(`wkb`[,`srid`])`

  Erzeugt einen `MULTILINESTRING`-Wert anhand seiner WKB-Darstellung und seines SRID.

- `MPointFromWKB(`wkb`[,`srid`])`, `MultiPointFromWKB(`wkb`[,`srid`])`

  Erzeugt einen `MULTIPOINT`-Wert anhand seiner WKB-Darstellung und seines SRID.

- `MPolyFromWKB(`wkb`[,`srid`])`, `MultiPolygonFromWKB(`wkb`[,`srid`])`

  Erzeugt einen `MULTIPOLYGON`-Wert anhand seiner WKB-Darstellung und seines SRID.

- `PointFromWKB(`wkb`[,`srid`])`

  Erzeugt einen `POINT`-Wert anhand seiner WKB-Darstellung und seines SRID.

- `PolyFromWKB(`wkb`[,`srid`])`, `PolygonFromWKB(`wkb`[,`srid`])`

  Erzeugt einen `POLYGON`-Wert anhand seiner WKB-Darstellung und seines SRID.

Die OpenGIS-Spezifikation beschreibt überdies optionale Funktionen zur Erstellung von `Polygon`- oder `MultiPolygon`-Werten anhand der WKB-Darstellung einer Ansammlung von Ringen oder geschlossenen `LineString`-Werten. Diese Werte dürfen sich schneiden. MySQL implementiert diese Funktionen nicht:

- `BdMPolyFromWKB(`wkb`,`srid`)`

  Erzeugt einen `MultiPolygon`-Wert aus einem `MultiLineString`-Wert im WKB-Format, der eine willkürliche Sammlung geschlossener `LineString`-Werte enthält.

- `BdPolyFromWKB(`wkb`,`srid`)`

  Erzeugt einen `Polygon`-Wert aus einem `MultiLineString`-Wert im WKB-Format, der eine willkürliche Sammlung geschlossener `LineString`-Werte enthält.

#### 18.4.2.3. Erzeugung von Geometriewerten mit MySQL-spezifischen Funktionen

MySQL stellt einige nichtstandardmäßige Funktionen zur Erstellung von WKB-Darstellungen aus Geometriewerten zur Vefügung. Die Funktionen in diesem Abschnitt sind MySQL-Erweiterungen zur OpenGIS-Spezifikation. Die Ergebnisse dieser Funktionen sind `BLOB`-Werte, die WKB-Darstellungen von Geometriewerten ohne SRID enthalten. Die Ergebnisse dieser Funktionen lassen sich als erstes Argument einer beliebigen Funktion der Funktionsfamilie `GeomFromWKB()` einsetzen.

- `GeometryCollection(`g1`,`g2`,...)`

  Erzeugt eine WKB-`GeometryCollection`. Ist eines der Argumente keine wohlgeformte WKB-Darstellung einer Geometrie, ist der Rückgabewert `NULL`.

- `LineString(`pt1`,`pt2`,...)`

  Erzeugt einen WKB-`LineString`-Wert aus mehreren WKB-`Point`-Argumenten. Ist eines der Argumente kein WKB-`Point`, ist der Rückgabewert `NULL`. Ist die Anzahl der `Point`-Argumente kleiner als zwei, ist der Rückgabewert `NULL`.

- `MultiLineString(`ls1`,`ls2`,...)`

  Erzeugt einen WKB-`MultiLineString`-Wert aus WKB-`LineString`-Argumenten. Ist eines der Argumente kein WKB-`LineString`, ist der Rückgabewert `NULL`.

- `MultiPoint(`pt1`,`pt2`,...)`

  Erzeugt einen WKB-`MultiPoint`-Wert aus WKB-`Point`-Argumenten. Ist eines der Argumente kein WKB-`Point`, ist der Rückgabewert `NULL`.

- `MultiPolygon(`poly1`,`poly2`,...)`

  Erzeugt einen WKB-`MultiPolygon`-Wert aus einer Menge von WKB-`Polygon`-Argumenten. Ist eines der Argumente kein WKB-`Polygon`, ist der Rückgabewert `NULL`.

- `Point(`x`,`y`)`

  Erzeugt einen WKB-`Point` anhand seiner Koordinaten.

- `Polygon(`ls1`,`ls2`,...)`

  Erzeugt einen WKB-`Polygon`-Wert aus einer Anzahl von WKB-`LineString`-Argumenten. Wenn eines der Argumente nicht die WKB-Darstellung eines `LinearRing`s ist (d. h. kein geschlossener und einfacher `LineString`), dann ist der Rückgabewert `NULL`.

### 18.4.3. Erzeugung raumbezogener Spalten

MySQL kennt eine standardisierte Möglichkeit, raumbezogene Spalten für Geometrietypen anzulegen, beispielsweise mit `CREATE TABLE` oder `ALTER TABLE`. Gegenwärtig werden raumbezogene Spalten für `MyISAM`-, `InnoDB`-, `NDB`-, `BDB`- und `ARCHIVE`-Tabellen unterstützt. Bitte lesen Sie auch die Anmerkungen über raumbezogene Indizes unter Abschnitt 18.6.1, „Erzeugung raumbezogener Indizes“.

- Um eine Tabelle mit einer raumbezogenen Spalte anzulegen, verwenden Sie die `CREATE TABLE`-Anweisung:

      CREATE TABLE geom (g GEOMETRY);

- Mit `ALTER TABLE` können Sie raumbezogene Spalten in eine vorhandene Tabelle einfügen oder aus ihr löschen:

      ALTER TABLE geom ADD pt POINT;
      ALTER TABLE geom DROP pt;

### 18.4.4. Füllen raumbezogener Spalten

Nachdem Sie raumbezogene Spalten eingerichtet haben, können Sie raumbezogene Daten hineinschreiben.

Die Werte sollten in einem internen Geometrieformat gespeichert werden, aber sie können aus dem Well-Known Text(WKT)- oder Well-Known Binary(WKB)-Format in dieses Format konvertiert werden. Die folgenden Beispiele zeigen, wie man Geometriewerte in eine Tabelle einfügt, indem man WKT-Werte in ein internes Geometrieformat konvertiert:

- Die Konvertierung wird direkt in der `INSERT`-Anweisung ausgeführt:

      INSERT INTO geom VALUES (GeomFromText('POINT(1 1)'));

      SET @g = 'POINT(1 1)';
      INSERT INTO geom VALUES (GeomFromText(@g));

- Die Konvertierung findet vor dem `INSERT` statt:

      SET @g = GeomFromText('POINT(1 1)');
      INSERT INTO geom VALUES (@g);

Die folgenden Beispiele fügen komplexere Geometrien in eine Tabelle ein:

    SET @g = 'LINESTRING(0 0,1 1,2 2)';
    INSERT INTO geom VALUES (GeomFromText(@g));

    SET @g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';
    INSERT INTO geom VALUES (GeomFromText(@g));

    SET @g =
    'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
    INSERT INTO geom VALUES (GeomFromText(@g));

In diesen Beispielen wurden die Geometriewerte immer mit `GeomFromText()` erzeugt. Sie können jedoch auch typspezifische Funktionen benutzen:

    SET @g = 'POINT(1 1)';
    INSERT INTO geom VALUES (PointFromText(@g));

    SET @g = 'LINESTRING(0 0,1 1,2 2)';
    INSERT INTO geom VALUES (LineStringFromText(@g));

    SET @g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';
    INSERT INTO geom VALUES (PolygonFromText(@g));

    SET @g =
    'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
    INSERT INTO geom VALUES (GeomCollFromText(@g));

Wenn eine Clientanwendung WKB-Darstellungen von Geometriewerten benutzen will, ist sie selbst dafür verantwortlich, wohlgeformte WKB-Daten in Anfragen an den Server zu senden. Diese Anforderung lässt sich allerdings auf mehrere Arten erfüllen. Zum Beispiel:

- Indem man einen `POINT(1 1)`-Wert mit der Syntax eines Hexadezimal-Literals sendet:

      mysql> INSERT INTO geom VALUES
          -> (GeomFromWKB(0x0101000000000000000000F03F000000000000F03F));

- Eine ODBC-Anwendung kann eine WKB-Darstellung senden, indem sie sie an einen Platzhalter mit einem Argument vom Typ `BLOB` bindet:

      INSERT INTO geom VALUES (GeomFromWKB(?))

  Andere Programmierschnittstellen können ähnliche Platzhaltermechanismen zur Verfügung stellen.

- In einem C-Programm können Sie einen Binärwert durch `mysql_real_escape_string()` mit Escape-Zeichen versehen und das Ergebnis in einen Abfragestring laden, der an den Server geschickt wird. Siehe hierzu Abschnitt 24.2.3.52, „`mysql_real_escape_string()`“.

### 18.4.5. Abfragen raumbezogener Daten

In einer Tabelle gespeicherte Geometriewerte können im internen Format abgefragt werden. Sie können sie jedoch auch in das WKT- oder WKB-Format konvertieren.

- Raumbezogene Daten im internen Format abrufen:

  Der Abruf von Geometriewerten im internen Format kann nützlich sein, wenn diese Daten zwischen Tabellen übertragen werden sollen:

      CREATE TABLE geom2 (g GEOMETRY) SELECT g FROM geom;

- Raumbezogene Daten im WKT-Format abrufen:

  Die Funktion `AsText()` konvertiert eine Geometrie aus einem internen Format in einen WKT-String.

      SELECT AsText(g) FROM geom;

- Raumbezogene Daten im WKB-Format abrufen:

  Die Funktion `AsBinary()` konvertiert eine Geometrie aus dem internen Format in einen `BLOB`, der den WKB-Wert enthält.

      SELECT AsBinary(g) FROM geom;

## 18.5. Analyse raumbezogener Informationen

Nachdem Sie die raumbezogenen Spalten mit Werten gefüllt haben, können diese abgefragt und analysiert werden. MySQL kennt eine Reihe von Funktionen, um diverse Operationen auf raumbezogenen Daten durchzuführen. Diese Funktionen lassen sich nach den jeweiligen Operationen, die sie ausführen, in vier große Kategorien einteilen:

- Funktionen, die Geometrien zwischen verschiedenen Formaten konvertieren

- Funktionen, die Zugriff auf qualitative oder quantitative Eigenschaften einer Geometrie geben

- Funktionen, die Beziehungen zwischen zwei Geometrien beschreiben

- Funktionen, die aus vorhandenen Geometrien neue erzeugen

Funktionen zur Analyse raumbezogener Daten können in vielen Zusammenhängen eingesetzt werden:

- in einem interaktiven SQL-Programm wie beispielsweise mysql oder MySQL Query Browser

- in Anwendungsprogrammen, die in irgendeiner Sprache mit MySQL-Client-API geschrieben sind

### 18.5.1. Umwandlungsfunktionen für das Geometrieformat

MySQL unterstützt die folgenden Funktionen zur Konvertierung von Geometriewerten zwischen einem internen Format und dem WKT- oder WKB-Format:

- `AsBinary(`g`)`

  Konvertiert einen Wert aus einem internen Geometrieformat in seine WKB-Darstellung und gibt das binäre Ergebnis zurück.

      SELECT AsBinary(g) FROM geom;

- `AsText(`g`)`

  Konvertiert einen Wert aus einem internen Geometrieformat in seine WKT-Darstellung und gibt den Ergebnisstring zurück.

      mysql> SET @g = 'LineString(1 1,2 2,3 3)';
      mysql> SELECT AsText(GeomFromText(@g));
      +--------------------------+
      | AsText(GeomFromText(@g)) |
      +--------------------------+
      | LINESTRING(1 1,2 2,3 3)  |
      +--------------------------+

- `GeomFromText(`wkt`[,`srid`])`

  Konvertiert einen String-Wert aus seiner WKT-Darstellung in ein internes Geometrieformat und gibt das Ergebnis zurück. Es werden auch einige typspezifische Funktionen unterstützt, wie beispielsweise `PointFromText()` und `LineFromText()`. Siehe Abschnitt 18.4.2.1, „Erzeugung von Geometriewerten mit WKT-Funktionen“.

- `GeomFromWKB(`wkb`[,`srid`])`

  Konvertiert einen Binärwert von seiner WKB-Darstellung in ein internes Geometrieformat und gibt das Ergebnis zurück. Es werden auch einige typspezifische Funktionen unterstützt, wie beispielsweise `PointFromWKB()` und `LineFromWKB()`. Siehe Abschnitt 18.4.2.2, „Erzeugung von Geometriewerten mit WKB-Funktionen“.

### 18.5.2. `Geometry`-Funktionen

Jede Funktion dieser Gruppe nimmt einen Geometriewert als Argument entgegen und gibt eine quantitative oder qualitative Eigenschaft der Geometrie zurück. Manche Funktionen schränken den Typ ihres Arguments ein. Solche Funktionen geben `NULL` zurück, wenn das Argument den verkehrten Geometrietyp hat. So liefert beispielsweise `Area()` den Wert `NULL`, wenn der Objekttyp weder `Polygon` noch `MultiPolygon` ist.

#### 18.5.2.1. Allgemeine Geometriefunktionen

Die im vorliegenden Abschnitt aufgeführten Funktionen schränken den Typ ihres Arguments nicht ein. Sie nehmen Geometriewerte jedes Typs entgegen.

- `Dimension(`g`)`

  Gibt die inhärente Dimension des Geometriewerts `g` zurück. Das Ergebnis kann –1, 0, 1 oder 2 sein. Was diese Werte bedeuten, lesen Sie in Abschnitt 18.2.2, „Die Klasse `Geometry`“.

      mysql> SELECT Dimension(GeomFromText('LineString(1 1,2 2)'));
      +------------------------------------------------+
      | Dimension(GeomFromText('LineString(1 1,2 2)')) |
      +------------------------------------------------+
      |                                              1 |
      +------------------------------------------------+

- `Envelope(`g`)`

  Gibt das Minimum Bounding Rectangle (MBR) des Geometriewerts `g` zurück. Das Ergebnis wird als `Polygon`-Wert geliefert.

  Das Polygon ist durch die Eckpunkte seines Begrenzungskastens definiert:

      POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))

      mysql> SELECT AsText(Envelope(GeomFromText('LineString(1 1,2 2)')));
      +-------------------------------------------------------+
      | AsText(Envelope(GeomFromText('LineString(1 1,2 2)'))) |
      +-------------------------------------------------------+
      | POLYGON((1 1,2 1,2 2,1 2,1 1))                        |
      +-------------------------------------------------------+

- `GeometryType(`g`)`

  Liefert den Namen des Geometrietyps, zu welchem das betreffende Geometrieobjekt `g` gehört, als String zurück. Es ist der Name einer instanziierbaren Unterklasse von `Geometry`.

      mysql> SELECT GeometryType(GeomFromText('POINT(1 1)'));
      +------------------------------------------+
      | GeometryType(GeomFromText('POINT(1 1)')) |
      +------------------------------------------+
      | POINT                                    |
      +------------------------------------------+

- `SRID(`g`)`

  Liefert die Integer-Kennung des Georeferenzsystems des Geometriewerts `g`.

  In MySQL ist der SRID-Wert ein einfacher Integer, der mit dem Geometriewert verbunden ist. Alle Berechnungen werden auf der Grundlage der euklidischen (planaren) Geometrie ausgeführt.

      mysql> SELECT SRID(GeomFromText('LineString(1 1,2 2)',101));
      +-----------------------------------------------+
      | SRID(GeomFromText('LineString(1 1,2 2)',101)) |
      +-----------------------------------------------+
      |                                           101 |
      +-----------------------------------------------+

Die OpenGIS-Spezifikation definiert außerdem folgende Funktionen, die von MySQL nicht implementiert werden:

- `Boundary(`g`)`

  Gibt eine Geometrie zurück, die der Abschluss der kombinatorischen Grenze des Geometriewerts `g` ist.

- `IsEmpty(`g`)`

  Liefert 1, wenn der Geometriewert `g` die leere Geometrie ist, 0, wenn er nichtleer ist, und –1, wenn das Argument `NULL` ist. Eine leere Geometrie ist die leere Punktmenge.

- `IsSimple(`g`)`

  Zurzeit ist diese noch ein Platzhalter und sollte nicht benutzt werden. Wenn sie implementiert ist, wird sie das im nächsten Absatz beschriebene Verhalten haben.

  Liefert 1, wenn der Geometriewert `g` keine anormalen geometrischen Punkte hat, indem er sich beispielsweise selbst schneidet oder tangiert. `IsSimple()` gibt 0 zurück, wenn das Argument nicht einfach ist, und –1, wenn es `NULL` ist.

  In den Beschreibungen der instanziierbaren geometrischen Klassen weiter oben in diesem Kapitel werden auch die konkreten Bedingungen genannt, unter denen eine Instanz der betreffenden Klasse als nichteinfach gilt. (Siehe Abschnitt 18.2.1, „Hierarchie der Geometrieklassen“.)

#### 18.5.2.2. `Point`-Funktionen

Ein `Point` besteht aus einer x- und einer y-Koordinate, die Sie mit den folgenden Funktionen beschaffen können:

- `X(`p`)`

  Gibt die x-Koordinate des Punkts `p` als Zahl mit doppelter Genauigkeit zurück.

      mysql> SET @pt = 'Point(56.7 53.34)';
      mysql> SELECT X(GeomFromText(@pt));
      +----------------------+
      | X(GeomFromText(@pt)) |
      +----------------------+
      |                 56.7 |
      +----------------------+

- `Y(`p`)`

  Gibt die y-Koordinate des Punkts `p` als Zahl mit doppelter Genauigkeit zurück.

      mysql> SET @pt = 'Point(56.7 53.34)';
      mysql> SELECT Y(GeomFromText(@pt));
      +----------------------+
      | Y(GeomFromText(@pt)) |
      +----------------------+
      |                53.34 |
      +----------------------+

#### 18.5.2.3. `LineString`-Funktionen

Ein `LineString` besteht aus `Point`-Werten. Sie können bestimmte Punkte eines `LineString` extrahieren, die Anzahl seiner Punkte abfragen oder seine Länge ermitteln.

- `EndPoint(`ls`)`

  Gibt den `Point` zurück, der der Endpunkt des `LineString`-Werts `ls` ist.

      mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
      mysql> SELECT AsText(EndPoint(GeomFromText(@ls)));
      +-------------------------------------+
      | AsText(EndPoint(GeomFromText(@ls))) |
      +-------------------------------------+
      | POINT(3 3)                          |
      +-------------------------------------+

- `GLength(`ls`)`

  Liefert die Länge des `LineString`-Werts `ls` in seinem zugehörigen Georeferenzsystem als Zahl mit doppelter Genauigkeit.

      mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
      mysql> SELECT GLength(GeomFromText(@ls));
      +----------------------------+
      | GLength(GeomFromText(@ls)) |
      +----------------------------+
      |            2.8284271247462 |
      +----------------------------+

  Der Name der Funktion `GLength()` ist ein nichtstandardmäßiger Name. Sie entspricht der OpenGIS-Funktion `Length()`.

- `NumPoints(`ls`)`

  Liefert die Anzahl der `Point`-Objekte im `LineString`-Wert `ls`.

      mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
      mysql> SELECT NumPoints(GeomFromText(@ls));
      +------------------------------+
      | NumPoints(GeomFromText(@ls)) |
      +------------------------------+
      |                            3 |
      +------------------------------+

- `PointN(`ls`,`N`)`

  Liefert den `N`-ten `Point` im `Linestring`-Wert `ls`. Die Punkte werden beginnend mit 1 nummeriert.

      mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
      mysql> SELECT AsText(PointN(GeomFromText(@ls),2));
      +-------------------------------------+
      | AsText(PointN(GeomFromText(@ls),2)) |
      +-------------------------------------+
      | POINT(2 2)                          |
      +-------------------------------------+

- `StartPoint(`ls`)`

  Gibt den `Point` zurück, der der Anfangspunkt des `LineString`-Werts `ls` ist.

      mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
      mysql> SELECT AsText(StartPoint(GeomFromText(@ls)));
      +---------------------------------------+
      | AsText(StartPoint(GeomFromText(@ls))) |
      +---------------------------------------+
      | POINT(1 1)                            |
      +---------------------------------------+

Die OpenGIS-Spezifikation definiert darüber hinaus die folgende von MySQL nicht implementierte Funktion:

- `IsRing(`ls`)`

  Gibt 1 zurück, wenn der `LineString`-Wert `ls` geschlossen ist (d. h., wenn sein `StartPoint()` und `EndPoint()` denselben Wert haben) und er gleichzeitig einfach ist (denselben Punkt nicht mehrmals berührt). Gibt 0 zurück, wenn `ls` kein Ring ist, und –1, wenn er `NULL` ist.

#### 18.5.2.4. `MultiLineString`-Funktionen

- `GLength(`mls`)`

  Gibt die Länge des `MultiLineString`-Werts `mls` als Zahl mit doppelter Genauigkeit zurück. Die Länge von `mls` ist gleich der Summe der Längen seiner Elemente.

      mysql> SET @mls = 'MultiLineString((1 1,2 2,3 3),(4 4,5 5))';
      mysql> SELECT GLength(GeomFromText(@mls));
      +-----------------------------+
      | GLength(GeomFromText(@mls)) |
      +-----------------------------+
      |             4.2426406871193 |
      +-----------------------------+

  `GLength()` ist ein nichtstandardmäßiger Name. Die Funktion entspricht der OpenGIS-Funktion `Length()`.

- `IsClosed(`mls`)`

  Gibt 1 zurück, wenn der `MultiLineString`-Wert `mls` geschlossen ist (d. h., wenn `StartPoint()` und `EndPoint()` für jeden `LineString` in `mls` gleich sind). Gibt 0 zurück, wenn `mls` nicht geschlossen ist, und –1, wenn er `NULL` ist.

      mysql> SET @mls = 'MultiLineString((1 1,2 2,3 3),(4 4,5 5))';
      mysql> SELECT IsClosed(GeomFromText(@mls));
      +------------------------------+
      | IsClosed(GeomFromText(@mls)) |
      +------------------------------+
      |                            0 |
      +------------------------------+

#### 18.5.2.5. `Polygon`-Funktionen

- `Area(`poly`)`

  Gibt die Fläche des `Polygon`-Werts `poly`, gemessen in seinem Georeferenzsystem, als Zahl mit doppelter Genauigkeit zurück.

      mysql> SET @poly = 'Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))';
      mysql> SELECT Area(GeomFromText(@poly));
      +---------------------------+
      | Area(GeomFromText(@poly)) |
      +---------------------------+
      |                         4 |
      +---------------------------+

- `ExteriorRing(`poly`)`

  Gibt den äußeren Ring des `Polygon`-Werts `poly` als `LineString` zurück.

      mysql> SET @poly =
          -> 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
      mysql> SELECT AsText(ExteriorRing(GeomFromText(@poly)));
      +-------------------------------------------+
      | AsText(ExteriorRing(GeomFromText(@poly))) |
      +-------------------------------------------+
      | LINESTRING(0 0,0 3,3 3,3 0,0 0)           |
      +-------------------------------------------+

- `InteriorRingN(`poly`,`N`)`

  Gibt den `N`-ten inneren Ring des `Polygon`-Werts `poly` als `LineString` zurück. Die Ringe werden beginnend mit 1 nummeriert.

      mysql> SET @poly =
          -> 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
      mysql> SELECT AsText(InteriorRingN(GeomFromText(@poly),1));
      +----------------------------------------------+
      | AsText(InteriorRingN(GeomFromText(@poly),1)) |
      +----------------------------------------------+
      | LINESTRING(1 1,1 2,2 2,2 1,1 1)              |
      +----------------------------------------------+

- `NumInteriorRings(`poly`)`

  Gibt die Anzahl der inneren Ringe des `Polygon`-Werts `poly` zurück.

      mysql> SET @poly =
          -> 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
      mysql> SELECT NumInteriorRings(GeomFromText(@poly));
      +---------------------------------------+
      | NumInteriorRings(GeomFromText(@poly)) |
      +---------------------------------------+
      |                                     1 |
      +---------------------------------------+

#### 18.5.2.6. `MultiPolygon`-Funktionen

- `Area(`mpoly`)`

  Gibt die Fläche des `MultiPolygon`-Werts `mpoly`, gemessen in seinem Georeferenzsystem, als Zahl mit doppelter Genauigkeit zurück.

      mysql> SET @mpoly =
          -> 'MultiPolygon(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))';
      mysql> SELECT Area(GeomFromText(@mpoly));
      +----------------------------+
      | Area(GeomFromText(@mpoly)) |
      +----------------------------+
      |                          8 |
      +----------------------------+

Die OpenGIS-Spezifikation definiert auch die folgenden von MySQL nicht implementierten Funktionen:

- `Centroid(`mpoly`)`

  Gibt den mathematischen Schwerpunkt des `MultiPolygon`-Werts `mpoly` als `Point` zurück. Es ist nicht garantiert, dass das Ergebnis auf dem `MultiPolygon` liegt.

- `PointOnSurface(`mpoly`)`

  Gibt einen `Point`-Wert zurück, der unter Garantie auf dem `MultiPolygon`-Wert `mpoly` liegt.

#### 18.5.2.7. `GeometryCollection`-Funktionen

- `GeometryN(`gc`,`N`)`

  Gibt die `N`-te Geometrie im `GeometryCollection`-Wert des `gc`-Werts zurück. Die Geometrien werden beginnend mit 1 nummeriert.

      mysql> SET @gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';
      mysql> SELECT AsText(GeometryN(GeomFromText(@gc),1));
      +----------------------------------------+
      | AsText(GeometryN(GeomFromText(@gc),1)) |
      +----------------------------------------+
      | POINT(1 1)                             |
      +----------------------------------------+

- `NumGeometries(`gc`)`

  Gibt die Anzahl der Geometrien im `GeometryCollection`-Wert `gc` zurück.

      mysql> SET @gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';
      mysql> SELECT NumGeometries(GeomFromText(@gc));
      +----------------------------------+
      | NumGeometries(GeomFromText(@gc)) |
      +----------------------------------+
      |                                2 |
      +----------------------------------+

### 18.5.3. Funktionen, die neue geometrische Objekte aus bestehenden erzeugen

#### 18.5.3.1. Geometriefunktionen, die neue Geometrien erzeugen

In Abschnitt 18.5.2, „`Geometry`-Funktionen“, werden mehrere Funktionen beschrieben, die aus vorhandenen Geometrien neue erstellen. Dort können Sie die Beschreibungen folgender Funktionen nachlesen:

- `Envelope(`g`)`

- `StartPoint(`ls`)`

- `EndPoint(`ls`)`

- `PointN(`ls`,`N`)`

- `ExteriorRing(`poly`)`

- `InteriorRingN(`poly`,`N`)`

- `GeometryN(`gc`,`N`)`

#### 18.5.3.2. Raumbezogene Operatoren

OpenGIS stellt auch noch einige weitere Funktionen vor, die Geometrien erzeugen können. Diese sind so entworfen, dass sie raumbezogene Operatoren implementieren.

Diese Funktionen sind in MySQL nicht implementiert, könnten aber in zukünftigen Releases einbezogen werden.

- `Buffer(`g`,`d`)`

  Gibt eine Geometrie zurück, die alle Punkte darstellt, deren Abstand vom Geometriewert `g` kleiner oder gleich dem Abstand von `d` ist.

- `ConvexHull(`g`)`

  Gibt eine Geometrie zurück, die die konvexe Hülle des Geometriewerts `g` darstellt.

- `Difference(`g1`,`g2`)`

  Gibt eine Geometrie zurück, die die Differenz zwischen den Punktmengen der Geometriewerte `g1` und `g2` angibt.

- `Intersection(`g1`,`g2`)`

  Gibt eine Geometrie zurück, die die Schnittmenge der Punktmengen der Geometriewerte `g1` und `g2` darstellt.

- `SymDifference(`g1`,`g2`)`

  Gibt eine Geometrie zurück, die die symmetrische Punktmengendifferenz zwischen den Geometriewerten `g1` und `g2` darstellt.

- `Union(`g1`,`g2`)`

  Gibt eine Geometrie zurück, die die Vereinigungsmenge der Punktmengen der Geometriewerte `g1` und `g2` darstellt.

### 18.5.4. Funktionen zum Testen raumbezogener Beziehungen zwischen geometrischen Objekten

Die Funktionen in diesen Abschnitten nehmen zwei Geometrien als Eingabeparameter und liefern eine qualitative oder quantitative Beziehung zwischen diesen zurück.

### 18.5.5. Relationen auf geometrischen Minimal Bounding Rectangles (MBRs)

MySQL kennt mehrere Funktionen, um Beziehungen zwischen den kleinsten begrenzenden Rechtecken (Minimal Bounding Rectangles, MBRs) zweier Geometrien `g1` und `g2` zu testen. Der Rückgabewert 1 bedeutet wahr (true) und 0 bedeutet falsch (false).

- `MBRContains(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob das Minimum Bounding Rectangle von `g1` das Minimum Bounding Rectangle von `g2` enthält oder nicht.

      mysql> SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
      mysql> SET @g2 = GeomFromText('Point(1 1)');
      mysql> SELECT MBRContains(@g1,@g2), MBRContains(@g2,@g1);
      ----------------------+----------------------+
      | MBRContains(@g1,@g2) | MBRContains(@g2,@g1) |
      +----------------------+----------------------+
      |                    1 |                    0 |
      +----------------------+----------------------+

- `MBRDisjoint(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob die Minimum Bounding Rectangles der beiden Geometrien `g1` und `g2` disjunkt sind (sich nicht überschneiden) oder nicht.

- `MBREqual(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob die Minimum Bounding Rectangles der beiden Geometrien `g1` und `g2` gleich sind oder nicht.

- `MBRIntersects(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob die Minimum Bounding Rectangles der beiden Geometrien `g1` und `g2` sich schneiden oder nicht.

- `MBROverlaps(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob die Minimum Bounding Rectangles der beiden Geometrien `g1` und `g2` sich überlappen oder nicht.

- `MBRTouches(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob die Minimum Bounding Rectangles der beiden Geometrien `g1` und `g2` sich berühren oder nicht.

- `MBRWithin(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob das Minimum Bounding Rectangle von `g1` innerhalb des Minimum Bounding Rectangles von `g2` liegt.

      mysql> SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
      mysql> SET @g2 = GeomFromText('Polygon((0 0,0 5,5 5,5 0,0 0))');
      mysql> SELECT MBRWithin(@g1,@g2), MBRWithin(@g2,@g1);
      +--------------------+--------------------+
      | MBRWithin(@g1,@g2) | MBRWithin(@g2,@g1) |
      +--------------------+--------------------+
      |                  1 |                  0 |
      +--------------------+--------------------+

### 18.5.6. Funktionen, die raumbezogene Beziehungen zwischen Geometrien überprüfen

Die OpenGIS-Spezifikation definiert die folgenden Funktionen, um die Beziehungen zwischen zwei Geometriewerten `g1` und `g2` zu testen.

MySQL implementiert diese Funktionen zurzeit noch nicht entsprechend der Spezifikation. Die, die implementiert werden, geben dasselbe Ergebnis wie die entsprechenden MBR-basierten Funktionen zurück. Dazu gehören neben `Distance()` und `Related()` auch die anderen Funktionen der folgenden Liste.

Diese Funktionen könnten in zukünftigen Releases auch mit voller anstatt nur mit MBR-basierter Unterstützung für raumbezogene Analyse implementiert werden.

Der Rückgabewert 1 bedeutet wahr (true) und 0 bedeutet falsch (false).

- `Contains(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob `g1` `g2` vollständig enthält oder nicht.

- `Crosses(`g1`,`g2`)`

  Gibt 1 zurück, wenn `g1` `g2` räumlich kreuzt. Gibt `NULL` zurück, wenn `g1` ein `Polygon` oder `MultiPolygon` ist oder wenn `g2` ein `Point` oder ein `MultiPoint` ist. Gibt ansonsten 0 zurück.

  Mit räumlich kreuzen ist eine räumliche Beziehung zwischen zwei Geometrien gemeint, die folgende Eigenschaften besitzt:

  - Die beiden Geometrien schneiden sich.

  - Ihre Überschneidung hat eine Geometrie zum Ergebnis, deren Dimension um eins kleiner ist als die maximale Dimension der beiden Geometrien.

  - Ihre Schnittmenge ist mit keiner der beiden Geometrien identisch.

- `Disjoint(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob `g1` räumlich disjunkt von `g2` ist (sich nicht überschneidet) oder nicht.

- `Distance(`g1`,`g2`)`

  Liefert den kürzesten Abstand zwischen zwei Punkten der beiden Geometrien als Zahl mit doppelter Genauigkeit.

- `Equals(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob `g1` und `g2` räumlich gleich sind oder nicht.

- `Intersects(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob `g1` sich räumlich mit `g2` überschneidet oder nicht.

- `Overlaps(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob `g1` sich räumlich mit `g2` überlappt oder nicht. Von räumlich überlappen spricht man, wenn sich zwei Geometrien schneiden und ihre Schnittmenge eine Geometrie ergibt, die nicht gleich einer der beiden gegebenen Geometrien ist, aber dieselbe Dimension hat.

- `Related(`g1`,`g2`,`pattern_matrix`)`

  Gibt 1 oder 0 zurück, je nachdem, ob die räumliche Beziehung, die durch `pattern_matrix` vorgegeben ist, zwischen `g1` und `g2` existiert oder nicht. Gibt –1 zurück, wenn die Argumente `NULL` sind. Die Mustermatrix (`pattern_matrix`) ist ein String. Ihre Spezifikation wird hier notiert werden, wenn die Funktion implementiert wurde.

- `Touches(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob `g1` `g2` räumlich berührt oder nicht. Von einer räumlichen Berührung zweier Geometrien spricht man, wenn ihre Innenbereiche sich nicht schneiden, aber die Grenze der einen entweder die Grenze oder den Innenbereich der anderen schneidet.

- `Within(`g1`,`g2`)`

  Gibt 1 oder 0 zurück, je nachdem, ob `g1` räumlich innerhalb von `g2` liegt oder nicht.

## 18.6. Optimierung der raumbezogenen Analyse

Suchoperationen in nichtraumbezogenen Datenbanken lassen sich mit Indizes optimieren. Dies gilt ebenso für raumbezogene Datenbanken. Es wurden bereits viele mehrdimensionale Indexmethoden entworfen, um auch die Suche nach raumbezogenen Daten zu optimieren. Die typischsten Methoden sind:

- Punktabfragen, die alle Objekte suchen, welche einen gegebenen Punkt enthalten.

- Bereichsabfragen, die alle Objekte suchen, welche einen gegebenen Bereich überlappen.

MySQL verwendet R-Trees mit quadratischem Split zum Indizieren raumbezogener Spalten. Ein raumbezogener Index wird anhand des MBRs einer Geometrie erstellt. Für die meisten Geometrien ist das MBR das kleinste die Geometrie umschließende Rechteck. Für einen horizontalen oder vertikalen Linestring ist das MBR ein auf eine Linie zusammengeschnurrtes Rechteck. Für einen Punkt ist das MBR ein Rechteck, das auf den Punkt zusammengeschrumpft ist.

Es ist auch möglich, normale Indizes auf raumbezogenen Spalten anzulegen. Hierzu müssen Sie einem (nichtraumbezogenen) Index auf einer raumbezogenen Spalte (ausgenommen `POINT`-Spalten) ein Präfix geben.

### 18.6.1. Erzeugung raumbezogener Indizes

MySQL kann raumbezogene Indizes mit einer ähnlichen Syntax anlegen, wie sie auch für normale Indizes verwendet wird, allerdings erweitert um das Schlüsselwort `SPATIAL`. Zurzeit müssen raumbezogene Spalten, die indiziert werden, als `NOT NULL` deklariert werden. Die folgenden Beispiele zeigen, wie man raumbezogene Indizes anlegen kann:

- Mit `CREATE TABLE`:

      CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g));

- Mit `ALTER TABLE`:

      ALTER TABLE geom ADD SPATIAL INDEX(g);

- Mit `CREATE INDEX`:

      CREATE SPATIAL INDEX sp_index ON geom (g);

Auf `MyISAM`-Tabellen legt `SPATIAL INDEX` einen R-Tree-Index an, aber auf Tabellen mit anderen Speicher-Engines, die raumbezogene Indizierung unterstützen, erzeugt `SPATIAL INDEX` einen B-Tree-Index. Ein B-Tree-Index auf raumbezogenen Werten ist nützlich für das Nachschlagen konkreter Werte, aber nicht für Bereichsscans.

Gelöscht werden raumbezogene Indizes mit `ALTER TABLE` oder `DROP INDEX`:

- Mit `ALTER TABLE`:

      ALTER TABLE geom DROP INDEX g;

- Mit `DROP INDEX`:

      DROP INDEX sp_index ON geom;

Beispiel: Angenommen, eine Tabelle namens `geom` enthält mehr als 32.000 Geometrien, die alle in der Spalte `g` vom Typ `GEOMETRY` gespeichert sind. Die Tabelle hat außerdem eine `AUTO_INCREMENT`-Spalte namens `fid` zum Speichern der Objekt-IDs.

    mysql> DESCRIBE geom;
    +-------+----------+------+-----+---------+----------------+
    | Field | Type     | Null | Key | Default | Extra          |
    +-------+----------+------+-----+---------+----------------+
    | fid   | int(11)  |      | PRI | NULL    | auto_increment |
    | g     | geometry |      |     |         |                |
    +-------+----------+------+-----+---------+----------------+
    2 rows in set (0.00 sec)

    mysql> SELECT COUNT(*) FROM geom;
    +----------+
    | count(*) |
    +----------+
    |    32376 |
    +----------+
    1 row in set (0.00 sec)

Mti folgender Anweisung definieren Sie einen raumbezogenen Index auf der Spalte `g`:

    mysql> ALTER TABLE geom ADD SPATIAL INDEX(g);
    Query OK, 32376 rows affected (4.05 sec)
    Records: 32376  Duplicates: 0  Warnings: 0

### 18.6.2. Verwendung eines raumbezogenen Indizes

Der Optimierer untersucht, ob die verfügbaren raumbezogenen Indizes für Suchoperationen im Rahmen von Anfragen zu gebrauchen sind, die eine Funktion wie `MBRContains()` oder `MBRWithin()` in der `WHERE`-Klausel haben. Die folgende Anfrage findet alle Objekte, die sich im gegebenen Rechteck befinden:

    mysql> SET @poly =
        -> 'Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))';
    mysql> SELECT fid,AsText(g) FROM geom WHERE
        -> MBRContains(GeomFromText(@poly),g);
    +-----+---------------------------------------------------------------+
    | fid | AsText(g)                                                     |
    +-----+---------------------------------------------------------------+
    |  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30 ... |
    |  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8, ... |
    |  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4, ... |
    |  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4, ... |
    |  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882. ... |
    |  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4, ... |
    | 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946. ... |
    |   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136. ... |
    |   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136, ... |
    |   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,3016 ... |
    |   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30 ... |
    |   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4, ... |
    |   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,3024 ... |
    |   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8, ... |
    |  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6, ... |
    |  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2, ... |
    |  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,3011 ... |
    | 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30 ... |
    | 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30 ... |
    | 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4, ... |
    +-----+---------------------------------------------------------------+
    20 rows in set (0.00 sec)

Mit `EXPLAIN` können Sie prüfen, wie diese Anfrage ausgeführt wird (die Spalte `id` wurde entfernt, damit die Ausgabe besser auf die Seite passt):

    mysql> SET @poly =
        -> 'Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))';
    mysql> EXPLAIN SELECT fid,AsText(g) FROM geom WHERE
        -> MBRContains(GeomFromText(@poly),g)\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: geom
             type: range
    possible_keys: g
              key: g
          key_len: 32
              ref: NULL
             rows: 50
            Extra: Using where
    1 row in set (0.00 sec)

So prüfen Sie, was ohne raumbezogenen Index passieren würde:

    mysql> SET @poly =
        -> 'Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))';
    mysql> EXPLAIN SELECT fid,AsText(g) FROM g IGNORE INDEX (g) WHERE
        -> MBRContains(GeomFromText(@poly),g)\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: geom
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 32376
            Extra: Using where
    1 row in set (0.00 sec)

Wenn Sie die `SELECT`-Anweisung ohne den raumbezogenen Index ausführen, erhalten Sie zwar dasselbe Ergebnis, aber die Ausführungszeit verlängert sich von 0,00 auf 0,46 Sekunden:

    mysql> SET @poly =
        -> 'Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))';
    mysql> SELECT fid,AsText(g) FROM geom IGNORE INDEX (g) WHERE
        -> MBRContains(GeomFromText(@poly),g);
    +-----+---------------------------------------------------------------+
    | fid | AsText(g)                                                     |
    +-----+---------------------------------------------------------------+
    |   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136. ... |
    |   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136, ... |
    |   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,3016 ... |
    |   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30 ... |
    |   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4, ... |
    |   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,3024 ... |
    |   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8, ... |
    |  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6, ... |
    |  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2, ... |
    |  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,3011 ... |
    |  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30 ... |
    |  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8, ... |
    |  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4, ... |
    |  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4, ... |
    |  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882. ... |
    |  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4, ... |
    | 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30 ... |
    | 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30 ... |
    | 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4, ... |
    | 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946. ... |
    +-----+---------------------------------------------------------------+
    20 rows in set (0.46 sec)

In künftigen Releases könnten raumbezogene Indizes vielleicht auch zur Optimierung anderer Funktionen genutzt werden. Siehe Abschnitt 18.5.4, „Funktionen zum Testen raumbezogener Beziehungen zwischen geometrischen Objekten“.

## 18.7. MySQL-Konformität und Kompatibilität

Folgende GIS-Features werden von MySQL noch nicht implementiert:

- Zusätzliche Metadaten-Views

  Die OpenGIS-Spezifikationen empfehlen mehrere zusätzliche Views für Metadaten, beispielsweise eine System-View namens `GEOMETRY_COLUMNS` mit einer Beschreibung der Geometriespalten, wobei für jede Geometriespalte der Datenbank eine Zeile angezeigt wird.

- Die OpenGIS-Funktion `Length()` für `LineString` und `MultiLineString` muss in MySQL zurzeit noch unter dem Namen `GLength()` aufgerufen werden.

  Das Problem besteht darin, dass es eine SQL-Funktion namens `Length()` gibt, die die Länge von String-Werten berechnet, und dass es manchmal nicht zu unterscheiden ist, ob diese Funktion nun im Zusammenhang mit Text oder mit raumbezogenen Daten aufgerufen wird. Wir werden dies entweder auf irgendeine Weise lösen oder einen anderen Namen für die Funktion finden.

Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.

Zurück |  | Weiter
Kapitel 17. Partitionierung | Zum Anfang | Kapitel 19. Gespeicherte Prozeduren und Funktionen