Каков наилучший способ сохранить координаты (долготу / широту, из Google Maps) в SQL Server?

StackOverflow https://stackoverflow.com/questions/551894

Вопрос

Я разрабатываю таблицу в 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: В следующий раз, когда вы сделаете выбор в этой таблице с географическими данными, помимо вкладки "Результаты" и "Сообщения", вы также получите вкладку "Пространственные результаты", как показано ниже для визуализации

SSMS geo results tab

Если вы используете 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);
    }
}

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

Если вы просто собираетесь заменить его в 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)
);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top