SQL 2008 Spatial Data Type Geography
Hallo zusammen,
Dass die Ertde keine Scheibe ist, weiss wohl jedes Kind.
Grundlagen
Das Modell der Erde, so wie wir das kennen ist eine Kugel, welche mit Längen und Breitengraden versehen ist.
Auf dieser Flachen Karte wurde zwei Punkten in den USA und England bestimmt. Der kürzeste Weg eine zwei Punkte zu verbinden ist eine Linie.
Schauen wir uns das aus der 3D Projektion an - sieht immer noch nach dem kürzesten Weg aus.
Drehen wir nun das 3D Modell etwas, so sehen wir, dass dies nicht der kürzeste Weg ist.
Der küzreste führt also über Norden. Auf der flachen Karte sieht dies wie ein Umweg aus.
(Die Screenshots habe ich von hier: http://jasonfollas.com/blog/archive/2008/05/16/sql-server-2008-spatial-data-part-7.aspx)
Da die Erde aber keine runde Kugel ist, sondern an den Polen flacher ist, werden Elipsoide und Geoide als Modell verwendet. Für GPS wird meist das WGS 84 Geoidmodell verwendet. Mehr Infos dazu gibt es hier http://www.kowoma.de/gps/geo/mapdatum.htm.
SQL Geographie
Im SQL Server 2008 gibt es nebst dem Datentyp geometry auch den Datentyp geography. Beim Geography Datentyp ist es wichtig, dass man das Map Datum (oder Kartenbezugsystem) angibt. Für WGS 84 ist dies 4326.
Anwenden
/*Add Geodata Colum*/
USE db_icewolf_test
ALTER TABLE tAdressen ADD fGeodata geography NULL;
/*Add Geodata*/
UPDATE tAdressen SET fGeodata = geography::STPointFromText('POINT(7.4831477 46.9473955)', 4326) WHERE fID = 1
/*Select with Geodata*/
SELECT fGeodata FROM dbo.tAdressen WHERE fID = 1
SELECT fGeodata.STAsText() FROM dbo.tAdressen WHERE fID = 1
Der Punkt (7.4831477,46.9473955) wird in der Datenbank aber als 0xE6100000010C5470784144794740EC8C4A45BEEE1D40 abgelegt. Will ich die Längen und Breitengrade wieder haben, so muss ich die Funktion object.STAsText() aufrufen.
Berechnen
Dass man nun mit SQL auch z.B. Distanzen berechnen kann zeigt folgendes Beispiel.
/*BE - ZH*/
DECLARE @g geography
SET @g = geography::STGeomFromText('LINESTRING(7.4481481 46.9479986, 8.5380326 47.3690239)', 4326);
SELECT @g
DECLARE @be geography;
DECLARE @zh geography;
SET @be = geography::STGeomFromText('point(7.4481481 46.9479986)', 4326);
SET @zh = geography::STGeomFromText('point(8.5380326 47.3690239)', 4326);
SELECT @be.STDistance(@zh)
Die Distanz ist also 94'979 Meter also ca. 95 Kilometer. Ich habe das mal mit Google Earth nachgemessen und bin etwa auf das selbe Resultat gekommen.
http://msdn.microsoft.com/en-us/library/cc280766.aspx