Ответы:
Взгляните на новые типы пространственных данных, которые были представлены в SQL Server 2008. Они предназначены для такого рода задач и делают индексацию и запросы намного проще и эффективнее.
Больше информации:
Честное предупреждение! Прежде чем следовать совету по использованию типа GEOGRAPHY, убедитесь, что вы не планируете использовать Linq или Entity Framework для доступа к данным, потому что он не поддерживается (по состоянию на ноябрь 2010 г.), и вам будет грустно!
Обновление июль 2017 г.
Для тех, кто читает этот ответ сейчас, он устарел, поскольку относится к устаревшему стеку технологий. См. Комментарии для более подробной информации.
Я не знаю ответа для SQL Server, но ...
В MySQL сохраните его какFLOAT( 10, 6 )
Это официальная рекомендация из документации для разработчиков Google .
CREATE TABLE `coords` (
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;
lat
и lng
превосходят по производительности georgraphy
даже с индексами высокой плотности в SQL 2014. Например: найти все точки внутри прямоугольника. Только я не уверен, я вижу, что в Google Maps теперь используется 7 вместо 6 цифр?
Как я это делаю: я сохраняю широту и долготу, а затем у меня есть третий столбец, который является автоматически производным типом географии первых двух столбцов. Таблица выглядит так:
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)))
)
Это дает вам гибкость пространственных запросов в столбце geoPoint, и вы также можете извлекать значения широты и долготы по мере необходимости для отображения или извлечения для целей csv.
Point
вместо STGeomFromText
. Например: [geography]::Point([Latitude], [Longitude], 4326)
.
Ненавижу противоречить тем, кто сказал: «Вот новый тип, давайте воспользуемся им». Новые пространственные типы SQL Server 2008 имеют некоторые преимущества, а именно эффективность, однако вы не можете слепо сказать, что всегда используйте этот тип. Это действительно зависит от более серьезных проблем с картиной.
Например, интеграция. Этот тип имеет эквивалентный тип в .Net - но как насчет взаимодействия? А как насчет поддержки или расширения старых версий .Net? Как насчет того, чтобы раскрыть этот тип на уровне сервиса для других платформ? Что насчет нормализации данных - может быть, вас интересуют широта или долгота как отдельные части информации. Возможно, вы уже написали сложную бизнес-логику для обработки долгого и долгого времени.
Я не говорю, что вам не следует использовать пространственный тип - во многих случаях вам нужно. Я просто говорю, что вам следует задать еще несколько критических вопросов, прежде чем идти по этому пути. Чтобы я мог наиболее точно ответить на ваш вопрос, мне нужно было больше узнать о вашей конкретной ситуации.
Хранение long / lat отдельно или в пространственном типе - оба жизнеспособных решения, и одно может быть предпочтительнее другого в зависимости от ваших собственных обстоятельств.
Что вы хотите сделать, так это сохранить широту и долготу как новый пространственный тип SQL2008 -> GEOGRAPHY.
Вот скриншот стола, который у меня есть.
альтернативный текст http://img20.imageshack.us/img20/6839/zipcodetable.png
В этой таблице у нас есть два поля, в которых хранятся географические данные.
Основная причина, по которой вы хотите сохранить его в базе данных как тип GEOGRAPHY, заключается в том, чтобы вы могли затем использовать все методы SPATIAL из него -> например. Точка в поли, расстояние между двумя точками и т. Д.
Кстати, мы также используем Google Maps API для получения данных о широте и долготе и сохранения их в нашей базе данных Sql 2008, поэтому этот метод действительно работает.
SQL Server поддерживает пространственную информацию. Вы можете увидеть больше на http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx .
В качестве альтернативы вы можете сохранить информацию в виде двух основных полей, обычно float является стандартным типом данных, сообщаемым большинством устройств и достаточно точным в пределах одного-двух дюймов - более чем достаточно для Google Maps.
ПРИМЕЧАНИЕ . Это недавний ответ, основанный на последних обновлениях стека SQL Server и .NET.
широта и долгота из карт Google должны храниться как данные Point (обратите внимание на заглавную букву P) на сервере SQL в соответствии с типом данных geography.
Предполагая, что ваши текущие данные хранятся в таблице Sample
как varchar под столбцами, lat
и lon
запрос ниже поможет вам преобразовать в географию
alter table Sample add latlong geography
go
update Sample set latlong= geography::Point(lat,lon,4326)
go
PS: В следующий раз, когда вы сделаете выбор в этой таблице с географическими данными, помимо вкладки «Результаты» и «Сообщения», вы также получите вкладку «Пространственные результаты», как показано ниже, для визуализации.
Если вы используете Entity Framework 5 <, вы можете использовать DbGeography
. Пример из 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
То, с чем я боролся, когда я начал использовать, DbGeography
было coordinateSystemId
. См. Ответ ниже, где вы найдете прекрасное объяснение и исходный код приведенного ниже кода.
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);
}
}
Если вы просто собираетесь подставить его в URL-адрес, я полагаю, подойдет одно поле, поэтому вы можете сформировать URL-адрес, например
http://maps.google.co.uk/maps?q=12.345678,12.345678&z=6
но поскольку это два фрагмента данных, я бы сохранил их в отдельных полях
Сохраните оба объекта как float и используйте в них уникальные ключевые слова. I.em
create table coordinates(
coord_uid counter primary key,
latitude float,
longitude float,
constraint la_long unique(latitude, longitude)
);
House A
, и переедет в него House B
. Вскоре Боб не сможет сохранить свой адрес (местоположение), потому что Алиса еще не обновила свой адрес - или никогда не обновит.