Der geography-Datentyp und warum die Länge einer Linie nicht unbedingt auch die Distanz zwischen deren Endpunkten ist

Seltsamer Titel? Stimmt. Das war aber heute eine Frage in einem Microsoft-Forum. Warum ist die Länge nicht gleich der Distanz zwischen 2 Punkten?

Nun, das stimmt natürlich nicht - zum Glück. Bei der Fehlersuche ist allerdings eine Besonderheit des SQL Servers aufgefallen. Zuerst aber mal ein Beispiel

1
2
3
4
5
6
7
8
9
DECLARE @line geography,
@pointStart geography,
@pointEnd geography
SELECT @line = geography::STGeomFromText('LINESTRING(1 2, 3 4)', 4326),
@pointStart = geography::Point(1, 2, 4326),
@pointEnd = geography::Point(3, 4, 4326)
SELECT @line.STLength() AS Length,
@pointEnd.STDistance(@pointStart) AS Distance

Heraus kommen die Werte

LengthDistance
313588,386985478313705,435222058

Doch warum sollte hier ein Unterschied bestehen… STLength() gibt die Länge des LINESTRINGs zurück und STDistance() berechnet die Distanz zwischen 2 Punkten. Wie bereits vorweggenommen ist das Ergebnis so an sich also falsch - trotzdem ist es so, dass der SQL Server korrekt rechnet. Bleibt als einzige Fehlerquelle also nur noch der Code selbst übrig…

Laut MSDN-Referenz zu geography::Point werden 3 Parameter erwartet: Latitude, Longitude und die SRID. Die Funktion geography::STGeomFromText interpretiert die Angaben aber anders herum. Um genauer zu sein in der Reihenfolge Longitude (geographischer Länge) und danach Latitude (geographischer Breite).

Und das war auch schon das ganze Geheimnis ;)
Warum geography::Point hier die Werte anders herum erwartet ist mir ein Rätsel und wird es wohl auch bleiben - die Reihenfolge wie sie geography::STGeomFromText interpretiert entspricht den Vorgaben der OGC und erscheinen damit in allen möglichen Bereichen eben in dieser Reihenfolge (und damit u.a. auch in GML).

Wie dem auch sei. Es ist alles noch korrekt - man muss nur dran denken ;)