it-swarm.com.de

Was ist der beste Weg, um Koordinaten (Längengrad/Breitengrad, von Google Maps) in SQL Server zu speichern?

Ich entwerfe eine Tabelle in SQL Server 2008, in der eine Benutzerliste und eine Google Maps-Koordinate (Längengrad und Breitengrad) gespeichert werden.

Benötige ich zwei Felder oder kann ich es mit 1 machen?

Was ist der beste (oder am häufigsten verwendete) Datentyp, um diese Art von Daten zu speichern?

98
Jonathan

Schauen Sie sich die neuen Spatial-Datentypen an, die in SQL Server 2008 eingeführt wurden. Sie wurden für diese Art von Aufgaben entwickelt und machen das Indizieren und Abfragen viel einfacher und effizienter.

Mehr Informationen:

52
Craig Bovis

Faire Warnung! Bevor Sie den Rat zur Verwendung des GEOGRAPHY-Typs befolgen, stellen Sie sicher, dass Sie nicht vorhaben, Linq oder Entity Framework für den Zugriff auf die Daten zu verwenden, da diese nicht unterstützt werden (seit November 2010) und Sie traurig sein werden! 

Update Juli 2017  

Für diejenigen, die diese Antwort jetzt lesen, ist sie veraltet, da sie sich auf den veralteten Technologie-Stack bezieht. Siehe Kommentare für weitere Details.

61
dan90266

Ich kenne die Antwort für SQL Server nicht, aber ...

In MySQL speichern Sie es als FLOAT( 10, 6 ).

Dies ist die offizielle Empfehlung aus der Google-Entwicklerdokumentation .

CREATE TABLE `coords` (
  `lat` FLOAT( 10, 6 ) NOT NULL ,
  `lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;
28
powtac

Ich hasse es, ein Kontrahent gegenüber denen zu sein, die sagten: "Hier ist ein neuer Typ, lasst uns ihn benutzen". Die neuen räumlichen Typen von SQL Server 2008 haben einige Vorteile - nämlich die Effizienz. Sie können jedoch nicht blind sagen, dass Sie immer diesen Typ verwenden. Es hängt wirklich von einigen größeren Fragen ab.

Als Beispiel Integration. Dieser Typ hat in .Net einen gleichwertigen Typ - aber was ist mit Interop? Was ist mit der Unterstützung oder Erweiterung älterer Versionen von .Net? Wie wäre es, wenn Sie diesen Typ auf der gesamten Service-Ebene anderen Plattformen zugänglich machen? Wie sieht es mit der Normalisierung von Daten aus? Vielleicht interessieren Sie sich für lat. Oder als eigenständige Information. Vielleicht haben Sie bereits eine komplexe Geschäftslogik für Long/Lat geschrieben.

Ich sage nicht, dass Sie den räumlichen Typ nicht verwenden sollten - in vielen Fällen sollten Sie das tun. Ich sage nur, Sie sollten ein paar kritischere Fragen stellen, bevor Sie diesen Weg beschreiten. Um Ihre Frage möglichst genau beantworten zu können, müsste ich mehr über Ihre spezifische Situation erfahren.

Das Speichern von Long/Lat separat oder in einem räumlichen Typ ist beides eine praktikable Lösung, und je nach Ihren Umständen kann eine der anderen vorzuziehen sein.

21
R. Lawson

So wie ich es mache: Ich speichere die Breite und Länge und dann habe ich eine dritte Spalte, die einen automatisch abgeleiteten Geographietyp der ersten beiden Spalten darstellt. Die Tabelle sieht so aus:

CREATE TABLE [dbo].[Geopoint]
(
    [GeopointId] BIGINT NOT NULL PRIMARY KEY IDENTITY, 
    [Latitude] float NOT NULL, 
    [Longitude] float NOT NULL, 
    [ts] ROWVERSION NOT NULL, 
    [GeographyPoint]  AS ([geography]::STGeomFromText(((('POINT('+CONVERT([varchar](20),[Longitude]))+' ')+CONVERT([varchar](20),[Latitude]))+')',(4326))) 
)

Dies gibt Ihnen die Flexibilität räumlicher Abfragen in der GeoPoint-Spalte und Sie können auch die Breiten- und Längenwerte abrufen, wenn Sie diese zum Anzeigen oder Extrahieren für CSV-Zwecke benötigen.

17
jaxxbo

Sie möchten Latitude und Longitude unter dem neuen Typ SQL2008 Spatial -> GEOGRAPHY speichern.

Hier ist ein Screenshot eines Tisches, den ich habe.

alt text http://img20.imageshack.us/img20/6839/zipcodetable.png

In dieser Tabelle haben wir zwei Felder, in denen Geografiedaten gespeichert werden.

  • Grenze: Dies ist das Polygon, das die Postleitzahlgrenze ist
  • CentrePoint: Dies ist der Latitude/Longitude-Punkt, der den visuellen Mittelpunkt dieses Polygons darstellt.

Der Hauptgrund, warum Sie es als GEOGRAPHY-Typ in der Datenbank speichern möchten, ist, dass Sie dann alle SPATIAL-Methoden davon nutzen können -> z. Punkt in Poly, Abstand zwischen zwei Punkten usw.

Übrigens verwenden wir auch Google Maps API, um Lat-/Long-Daten abzurufen und diese in unserer SQL 2008-Datenbank zu speichern. Diese Methode funktioniert also.

15
Pure.Krome

SQL Server unterstützt räumlich relevante Informationen. Weitere Informationen finden Sie unter http://www.Microsoft.com/sqlserver/2008/de/us/spatial-data.aspx

Alternativ können Sie die Informationen als zwei grundlegende Felder speichern. In der Regel handelt es sich bei dem Float um den Standarddatentyp, der von den meisten Geräten gemeldet wird, und ist für ein oder zwei Zoll genau genug - mehr als ausreichend für Google Maps. 

11
Rosstified

NOTE: Dies ist eine aktuelle Antwort, die auf aktuellen SQL Server- und .NET-Stack-Updates basiert

latitude und Längengrad von Google Maps sollten als Punktdaten (beachten Sie die Großbuchstaben P) im SQL-Server unter dem geografischen Datentyp gespeichert werden.

Angenommen, Ihre aktuellen Daten werden in einer Tabelle Sample als varchar in den Spalten lat und lon gespeichert. Die folgende Abfrage hilft Ihnen bei der Konvertierung in Geografie

alter table Sample add latlong geography
go
update Sample set latlong= geography::Point(lat,lon,4326)
go

PS: Wenn Sie das nächste Mal eine Auswahl für diese Tabelle mit Geographiedaten vornehmen, erhalten Sie neben der Registerkarte Ergebnisse und Meldungen auch die Registerkarte Ergebnisse der räumlichen Ergebnisse wie unten für die Visualisierung

 SSMS geo results tab

1
DhruvJoshi

Wenn Sie Entity Framework 5 verwenden, können Sie DbGeography verwenden. Beispiel aus MSDN:

public class University  
{ 
    public int UniversityID { get; set; } 
    public string Name { get; set; } 
    public DbGeography Location { get; set; } 
}

public partial class UniversityContext : DbContext 
{ 
    public DbSet<University> Universities { get; set; } 
}

using (var context = new UniversityContext ()) 
{ 
    context.Universities.Add(new University() 
        { 
            Name = "Graphic Design Institute", 
            Location = DbGeography.FromText("POINT(-122.336106 47.605049)"), 
        }); 

    context. Universities.Add(new University() 
        { 
            Name = "School of Fine Art", 
            Location = DbGeography.FromText("POINT(-122.335197 47.646711)"), 
        }); 

    context.SaveChanges(); 

    var myLocation = DbGeography.FromText("POINT(-122.296623 47.640405)"); 

    var university = (from u in context.Universities 
                        orderby u.Location.Distance(myLocation) 
                        select u).FirstOrDefault(); 

    Console.WriteLine( 
        "The closest University to you is: {0}.", 
        university.Name); 
}

https://msdn.Microsoft.com/en-us/library/hh859721(v=vs.113).aspx

Etwas, mit dem ich zu kämpfen hatte, als ich anfing, DbGeography zu verwenden, war die coordinateSystemId. In der Antwort unten finden Sie eine ausgezeichnete Erklärung und Quelle für den Code.

public class GeoHelper
{
    public const int SridGoogleMaps = 4326;
    public const int SridCustomMap = 3857;

    public static DbGeography FromLatLng(double lat, double lng)
    {
        return DbGeography.PointFromText(
            "POINT("
            + lng.ToString() + " "
            + lat.ToString() + ")",
            SridGoogleMaps);
    }
}

https://stackoverflow.com/a/25563269/3850405

0
Ogglas