Archiv

Posts Tagged ‘SQL Server 2008’

Nächsten Punkt einer Strecke zu einem anderen Punkt bestimmen mit Microsoft SQL Server 2008

10/04/2009 1 Kommentar

Mit der Einführung des neuen Datentyps „geography“ in Microsoft SQL Server 2008 ist es endlich möglich, Datenbanken mit Geodaten zu füllen und darauf spezifische Queries auszuführen. In meiner Diplomarbeit konnte ich bereits erste Erfahrungen damit sammeln und Abfragen anwenden, die auf bisherigem Wege nur sehr kompliziert und wenig performant zu bewerkstelligen waren.
Skizze - nächster Streckenpunkt
Bei einem Map-Matching-Algorithmus bin ich allerdings auf ein Problem gestoßen. Hierfür war es notwendig, zu einem gegebenen Geodatum (z.B. aktueller Standort) den nächstliegenden Punkt auf einer in der Nähe befindlichen Polyline (z.B. eine Straße) zu bestimmen. Nach einigen Fehlschlägen bin ich mit folgendem Code meiner Stored Procedure der Lösung schon sehr Nahe gekommen:


declare @g geography = geography::STGeomFromText('LINESTRING (13.7294956 51.0171902, 13.7313528 51.0170059, 13.7336699 51.0170137)', 4326)
declare @h geography = geography::STGeomFromText('POINT(13.7313527 51.0170058)', 4326)

select @h.STBuffer(@h.STDistance(@g)).STIntersection(@g).ToString() 

Allerdings bekommt man bei dieser Query immer nur eine „empty geometrycollection“ als Ergebnis. Soll heißen: es wird kein Schnittpunkt gefunden. Glücklicherweise konnte man mir bei Microsoft TechNet helfen. Am wahrscheinlichsten ist hierbei ein schlichter Rundungsfehler schuld. Erhöht man den Buffer um nur ein winziges Mü, erhält man ein Ergebnis. Hier die funktionierende Query:


declare @g geography = geography::STGeomFromText('LINESTRING (13.7294956 51.0171902, 13.7313528 51.0170059, 13.7336699 51.0170137)', 4326)
declare @h geography = geography::STGeomFromText('POINT(13.7313527 51.0170058)', 4326)

select @h.STBuffer(@h.STDistance(@g) + 0.00001).STIntersection(@g).ToString() 

Das Endergebnis wird durch die Erhöhung des Buffers praktisch nicht beeinflusst, da es sich hierbei um einen Wert von 0.00001 Meter handelt.

Advertisements