Respostas:
Dê uma olhada nos novos tipos de dados espaciais que foram introduzidos no SQL Server 2008. Eles são projetados para esse tipo de tarefa e tornam a indexação e a consulta muito mais fáceis e eficientes.
Mais Informações:
Aviso justo! Antes de seguir o conselho para usar o tipo GEOGRAPHY, certifique-se de que não está planejando usar o Linq ou Entity Framework para acessar os dados porque não é compatível (desde novembro de 2010) e você ficará triste!
Atualização em julho de 2017
Para aqueles que estão lendo esta resposta agora, ela é obsoleta no que se refere à pilha de tecnologia retroativa. Veja comentários para mais detalhes.
Não sei a resposta para o SQL Server, mas ...
No MySQL, salve-o comoFLOAT( 10, 6 )
Esta é a recomendação oficial da documentação do desenvolvedor do Google .
CREATE TABLE `coords` (
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;
lat
e lng
superam georgraphy
, mesmo com índices de alta densidade no SQL 2014. Por exemplo: localizar todos os pontos está dentro de um retângulo. Só não tenho certeza, vejo que o Google Maps agora usa 7 em vez de 6 dígitos.
A maneira como eu faço isso: eu armazeno a latitude e a longitude e, em seguida, tenho uma terceira coluna que é um tipo de geografia derivado automaticamente das primeiras duas colunas. A tabela é parecida com esta:
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)))
)
Isso dá a você a flexibilidade de consultas espaciais na coluna geoPoint e você também pode recuperar os valores de latitude e longitude conforme necessário para exibição ou extração para fins de csv.
Point
vez de STGeomFromText
. Por exemplo: [geography]::Point([Latitude], [Longitude], 4326)
.
Eu odeio ser contrária àqueles que dizem "aqui está um novo tipo, vamos usar". Os novos tipos espaciais do SQL Server 2008 têm alguns prós - a saber, eficiência, mas você não pode dizer cegamente sempre use esse tipo. Realmente depende de alguns problemas gerais.
Como exemplo, integração. Este tipo tem um tipo equivalente em .Net - mas e a interoperabilidade? Que tal oferecer suporte ou extensão de versões anteriores do .Net? Que tal expor esse tipo em toda a camada de serviço para outras plataformas? E quanto à normalização de dados - talvez você esteja interessado em informações de longa ou longa duração. Talvez você já tenha escrito uma lógica de negócios complexa para lidar com long / lat.
Não estou dizendo que você não deve usar o tipo espacial - em muitos casos, deve. Só estou dizendo que você deve fazer algumas perguntas mais críticas antes de seguir esse caminho. Para que eu responda à sua pergunta com mais precisão, preciso saber mais sobre sua situação específica.
Armazenar long / lat separadamente ou em um tipo espacial são soluções viáveis, e uma pode ser preferível à outra dependendo de suas próprias circunstâncias.
O que você deseja fazer é armazenar a Latitude e Longitude como o novo tipo Espacial SQL2008 -> GEOGRAFIA.
Aqui está uma captura de tela de uma mesa, que eu tenho.
texto alternativo http://img20.imageshack.us/img20/6839/zipcodetable.png
Nesta tabela, temos dois campos que armazenam dados geográficos.
O principal motivo pelo qual você deseja salvá-lo no banco de dados como um tipo GEOGRAFIA é para que você possa aproveitar todos os métodos ESPACIAIS dele -> por exemplo. Ponto em Poly, Distância entre dois pontos, etc.
A propósito, também usamos a API do Google Maps para recuperar dados lat / long e armazená-los em nosso banco de dados Sql 2008 - portanto, esse método funciona.
O SQL Server oferece suporte para informações relacionadas ao espaço. Você pode ver mais em http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx .
Como alternativa, você pode armazenar as informações como dois campos básicos, geralmente um float é o tipo de dados padrão relatado pela maioria dos dispositivos e é preciso o suficiente para uma polegada ou duas - mais do que adequado para o Google Maps.
OBSERVAÇÃO : Esta é uma resposta recente com base no servidor SQL recente, atualizações de pilha do .NET
latitude e longitude do Google Maps devem ser armazenadas como dados de ponto (observe P maiúsculo) no servidor SQL sob o tipo de dados geográficos.
Assumindo que seus dados atuais estão armazenados em uma tabela Sample
como varchar em colunas lat
e lon
, a consulta abaixo irá ajudá-lo a converter para geografia
alter table Sample add latlong geography
go
update Sample set latlong= geography::Point(lat,lon,4326)
go
PS: Da próxima vez que você fizer uma seleção nesta tabela com dados geográficos, além da guia Resultados e Mensagens, você também obterá a guia Resultados espaciais como abaixo para visualização
Se você estiver usando o Entity Framework 5 <, você pode usar DbGeography
. Exemplo do 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 contra o qual eu lutava quando comecei a usar DbGeography
era o coordinateSystemId
. Veja a resposta abaixo para uma excelente explicação e fonte para o código abaixo.
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);
}
}
Se você for apenas substituí-lo por um URL, suponho que um campo serviria - para que você possa formar um URL como
http://maps.google.co.uk/maps?q=12.345678,12.345678&z=6
mas como são dois dados, eu os armazenaria em campos separados
Armazene ambos como flutuante e use palavras-chave exclusivas neles.i.em
create table coordinates(
coord_uid counter primary key,
latitude float,
longitude float,
constraint la_long unique(latitude, longitude)
);
House A
e se mudará para House B
a casa onde Alice morava. Em breve Bob não poderá mais salvar seu endereço (local), porque Alice ainda não atualizou o dela - ou nunca o fará.