2010-01-09 6 views
10

Ich versuche, eine Abfrage zu erstellen, aber ich habe einige Schwierigkeiten.SQL Server Geography Datentyp am nächsten Punkt in Zeile

Ich habe eine SQL Server 2008-Datenbank mit einer Tabelle, die unter anderem ein geografisches Feld enthält, das Straßensegmente beschreibt. (Diese Daten wurden aus TIGER/Liniendaten aus der US-Volkszählung importiert.)

Ich habe einen anderen Fixpunkt, der den Standort eines Benutzers beschreibt. Ich möchte zu diesem Zeitpunkt das nächste Straßensegment in der Datenbank finden, aber ich kann nicht herausfinden, wie dies zu erreichen ist. Außerdem möchte ich den nächsten Punkt in diesem Segment zum Benutzerstandortpunkt finden. Dies ist, was ich in meiner Abfrage auswählen und zurückgeben möchte.

Hat jemand Erfahrung mit der Geografie/Geometrie-Funktionalität, die mir helfen kann?

Danke!

+0

Vielleicht möchten Sie einige Feldtyp Informationen hinzuzufügen. Zum Beispiel haben Sie einen festen Punkt, um den Standort des Benutzers zu beschreiben, ist dies ein Längen- und Breitengrad-Koordinatenpaar? Ich habe Erfahrung mit den Geographiefunktionen, aber benötige mehr Details ... – Sparky

+0

Ich stelle dieses von meiner Anwendung zur Verfügung, also gebe ich ein Argument ein. Mir geht es ziemlich gut, was auch immer Datentyp ist notwendig. –

Antwort

18

Sie Ihre Objekte in einer GEOGRAPHY Spalte speichern können und eine SPATIAL INDEX über erstellen diese Spalte.

Leider implementiert SQL Server räumlichen Indizes durch die Oberfläche Fliesen und in einer Ebene B-Tree Index den Kachel-IDs zu speichern, so Klar ORDER BY STDistance wird nicht funktionieren (gut, funktioniert es wird aber den Index nicht verwendet werden).

Stattdessen werden Sie eine Abfrage wie diese machen müssen:

DECLARE @mypoint GEOGRAPHY 
SET @mypoint = geography::STGeomFromText('POINT(@mylat, @mylon)', 4326); 

WITH num (distance) AS 
     (
     SELECT 1000 
     UNION ALL 
     SELECT distance + 1000 
     FROM num 
     WHERE distance <= 50000 
     ) 
SELECT TOP 1 m.* 
FROM num 
CROSS APPLY 
     (
     SELECT TOP 1 * 
     FROM mytable 
     WHERE myroad.STDistance(@mypoint) <= distance 
     ORDER BY 
       STDistance(@mypoint) 
     ) m 

Auf diese Weise werden SQL Server erste Suche Straßen innerhalb 1 Kilometer von Ihrem Punkt, dann innerhalb 2 Kilometer usw. jedes Mal Verwenden des Indexes.

Update:

Wenn Sie mehrere Punkte in einer Tabelle und wollen den nächsten Punkt für jeden von ihnen finden:

WITH num (distance) AS 
     (
     SELECT 1000 
     UNION ALL 
     SELECT distance + 1000 
     FROM num 
     WHERE distance <= 50000 
     ) 
SELECT mp.mypoint, m.* 
FROM @mypoints mp 
CROSS APPLY 
     (
     SELECT TOP 1 m.* 
     FROM num 
     CROSS APPLY 
       (
       SELECT TOP 1 * 
       FROM mytable 
       WHERE myroad.STDistance(@mypoint) <= distance 
       ORDER BY 
         STDistance(@mypoint) 
       ) m 
     ) m 
+2

Die beste Antwort, die ich je bei StackOverflow gefunden habe. Danke, dass Sie mich wissen lassen, dass ich nicht nur 'ORDER BY' bin, was wahrscheinlich die Umsetzung wäre. –

+0

@Pure: nur quer anwenden meine Abfrage auf '@ mypoints' – Quassnoi

+0

hi. Ich bin mir nicht sicher, ob @Pure Krome es herausgefunden hat, aber ich kann es nicht verstehen. * Übernehmen Sie meine Abfrage auf @ myPoints * ?? Ich verstehe es nicht :(Können Sie bitte Ihre Antwort aktualisieren, bitte ??? – RPM1984