sql-server - longitude - stdistance sql server
¿Cuál es la mejor forma de almacenar coordenadas(longitud/latitud, desde Google Maps) en SQL Server? (11)
Estoy diseñando una tabla en SQL Server 2008 que almacenará una lista de usuarios y una coordenada de Google Maps (longitud y latitud).
¿Necesitaré dos campos o puedo hacerlo con 1?
¿Cuál es el mejor (o más común) tipo de datos para usar para almacenar este tipo de datos?
NOTA : Esta es una respuesta reciente basada en el servidor SQL reciente, actualizaciones de pila .NET
latitud y longitud de google Los mapas se deben almacenar como datos de punto (nota P mayúscula) en el servidor SQL bajo el tipo de datos geográficos.
Suponiendo que sus datos actuales se almacenan en una tabla Sample
como varchar bajo las columnas lat
y lon
, la consulta siguiente le ayudará a convertir a la geografía
alter table Sample add latlong geography
go
update Sample set latlong= geography::Point(lat,lon,4326)
go
PD: la próxima vez que selecciones esta tabla con datos geográficos, además de la pestaña Resultados y mensajes, también obtendrás la pestaña de resultados espaciales como se muestra a continuación para la visualización
Almacene ambos como float y use palabras clave únicas en them.i.em
create table coordinates(
coord_uid counter primary key,
latitude float,
longitude float,
constraint la_long unique(latitude, longitude)
);
Eche un vistazo a los nuevos tipos de datos espaciales que se introdujeron en SQL Server 2008. Están diseñados para este tipo de tareas y hacen que la indexación y las consultas sean mucho más fáciles y eficientes.
Más información:
La forma en que lo hago: almaceno la latitud y longitud y luego tengo una tercera columna que es un tipo de geografía derivada automática de las primeras dos columnas. La tabla se ve así:
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)))
)
Esto le brinda la flexibilidad de las consultas espaciales en la columna geoPoint y también puede recuperar los valores de latitud y longitud a medida que los necesita para visualizarlos o extraerlos para fines de CSV.
Lo que quiere hacer es almacenar la Latitud y la Longitud como el nuevo tipo espacial SQL2008 -> GEOGRAFÍA.
Aquí hay una captura de pantalla de una mesa, que tengo.
texto alternativo http://img20.imageshack.us/img20/6839/zipcodetable.png
En esta tabla, tenemos dos campos que almacenan datos de geografía.
- Límite: este es el polígono que es el límite del código postal
- CentrePoint: este es el punto de Latitud / Longitud que representa el punto medio visual de este polígono.
La razón principal por la que desea guardarlo en la base de datos como un tipo de GEOGRAFÍA es para que pueda aprovechar todos los métodos espaciales fuera de él -> por ej. Point in Poly, Distancia entre dos puntos, etc.
Por cierto, también usamos Google Maps API para recuperar datos lat / long y almacenar eso en nuestro DB 2008 Sql - por lo que este método funciona.
Odio ser un contrario a aquellos que dijeron "aquí hay un tipo nuevo, vamos a usarlo". Los nuevos tipos espaciales de SQL Server 2008 tienen algunas ventajas: la eficiencia, sin embargo, no se puede decir a ciegas que siempre se debe usar ese tipo. Realmente depende de algunos problemas de imagen más grandes.
Como ejemplo, integración. Este tipo tiene un tipo equivalente en .Net, pero ¿qué pasa con la interoperabilidad? ¿Qué hay de apoyar o extender versiones anteriores de .Net? ¿Qué hay de exponer este tipo a través de la capa de servicio a otras plataformas? ¿Qué pasa con la normalización de los datos? Tal vez esté interesado en lat o long como piezas de información independientes. Quizás ya hayas escrito una lógica empresarial compleja para manejar long / lat.
No estoy diciendo que no deba usar el tipo espacial, en muchos casos debería hacerlo. Solo digo que deberías hacer algunas preguntas más críticas antes de seguir por ese camino. Para que pueda responder a su pregunta con mayor precisión, necesitaría saber más sobre su situación específica.
Almacenar long / lat por separado o en un tipo espacial son soluciones viables, y una puede ser preferible a la otra dependiendo de sus propias circunstancias.
SQL Server tiene soporte para información espacial relacionada. Puede ver más en http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx .
Alternativamente, puede almacenar la información como dos campos básicos, generalmente un flotante es el tipo de datos estándar reportado por la mayoría de los dispositivos y es lo suficientemente preciso para una pulgada o dos, más que adecuado para Google Maps.
Si está utilizando Entity Framework 5 <puede usar DbGeography
. Ejemplo de 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
Algo con lo que luché entonces comencé a usar DbGeography
era el coordinateSystemId
. Consulte la respuesta a continuación para obtener una explicación excelente y una fuente para el código a continuación.
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://.com/a/25563269/3850405
Si lo va a sustituir en una URL, supongo que un campo lo haría, para que pueda formar una URL como
http://maps.google.co.uk/maps?q=12.345678,12.345678&z=6
pero como son dos datos, los almacenaría en campos separados
No sé la respuesta para SQL Server, pero ...
En MySQL guárdelo como FLOAT( 10, 6 )
Esta es la recomendación oficial de la documentación para desarrolladores de Google .
CREATE TABLE `coords` (
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;
¡Advertencia justa! Antes de seguir el consejo de utilizar el tipo GEOGRAFÍA, asegúrese de no estar pensando en utilizar Linq o Entity Framework para acceder a los datos porque no es compatible (desde noviembre de 2010) y ¡estará triste!
Actualización Jul 2017
Para aquellos que leen esta respuesta ahora, es obsoleta, ya que se refiere a la pila de tecnología retroadaptada. Ver comentarios para más detalles.