Каков наилучший способ сохранить координаты (долготу / широту, из Google Maps) в SQL Server?
-
23-08-2019 - |
Вопрос
Я разрабатываю таблицу в SQL Server 2008, в которой будет храниться список пользователей и координаты Google Maps (долгота и широта).
Понадобятся ли мне два поля, или это можно сделать с помощью 1?
Какой тип данных лучше всего (или наиболее распространенный) использовать для хранения такого рода данных?
Решение
Взгляните на новые типы пространственных данных, которые были представлены в 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 ;
Я ненавижу быть противником тех, кто сказал: "вот новый тип, давайте его используем".У новых пространственных типов SQL Server 2008 есть некоторые плюсы, а именно эффективность, однако вы не можете слепо утверждать, что всегда используете этот тип.Это действительно зависит от некоторых проблем с более широкой картиной.
В качестве примера можно привести интеграцию.Этот тип имеет эквивалентный тип в .Net - но как насчет взаимодействия?Как насчет поддержки или расширения старых версий .Net?Как насчет предоставления доступа к этому типу на уровне сервиса другим платформам?Как насчет нормализации данных - возможно, вас интересуют lat или long как отдельные фрагменты информации.Возможно, вы уже написали сложную бизнес-логику для обработки long / lat.
Я не говорю, что вам не следует использовать пространственный тип - во многих случаях вам следует.Я просто говорю, что вам следует задать еще несколько важных вопросов, прежде чем идти по этому пути.Чтобы я мог наиболее точно ответить на ваш вопрос, мне нужно было бы знать больше о вашей конкретной ситуации.
Хранение long / lat отдельно или в пространственном типе - оба варианта являются жизнеспособными решениями, и одно может быть предпочтительнее другого в зависимости от ваших собственных обстоятельств.
То, как я это делаю:Я храню широта и долгота и затем у меня есть третий столбец, который является автоматическим производным типом географии из первых двух столбцов.Таблица выглядит следующим образом:
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.
Что вы хотите сделать, это сохранить широту и долготу как новый пространственный тип SQL2008 -> ГЕОГРАФИЯ.
Вот снимок экрана таблицы, который у меня есть.
альтернативный текст http://img20.imageshack.us/img20/6839/zipcodetable.png
В этой таблице у нас есть два поля, в которых хранятся географические данные.
- Граница:это полигон , который является границей почтового индекса
- Центральная точка:это точка широты / долготы, которая представляет визуальную среднюю точку этого многоугольника.
Основная причина, по которой вы хотите сохранить его в базе данных как тип GEOGRAPHY, заключается в том, что затем вы можете использовать все его ПРОСТРАНСТВЕННЫЕ методы -> eg.Точка в Поли, Расстояние между двумя точками и т.д.
Кстати, мы также используем Google Maps API для извлечения широтных / длительных данных и сохранения их в нашей базе данных Sql 2008 - так что этот метод действительно работает.
SQL Server поддерживает информацию, связанную с пространством.Вы можете увидеть больше на http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx.
Альтернативно, вы можете хранить информацию в виде двух базовых полей, обычно float - это стандартный тип данных, отображаемый большинством устройств, и он достаточно точен с точностью до одного-двух дюймов - более чем достаточно для Google Maps.
ПРИМЕЧАНИЕ:Это недавний ответ, основанный на последних обновлениях SQL server, .NET stack
широта и герцеговина с Google Maps должны храниться как данные Point (обратите внимание на заглавную букву P) в SQL server в разделе тип данных 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=против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)
);