Каков наилучший способ хранения координат (долгота / широта из карт Google) в SQL Server? - PullRequest
99 голосов
/ 16 февраля 2009

Я разрабатываю таблицу в SQL Server 2008, в которой будет храниться список пользователей и координаты Карт Google (долгота и широта).

Мне понадобятся два поля или это можно сделать с 1?

Какой тип данных (или наиболее распространенный) используется для хранения данных такого типа?

Ответы [ 11 ]

62 голосов
/ 14 ноября 2010

Справедливое предупреждение! Прежде чем воспользоваться советом по использованию типа GEOGRAPHY, убедитесь, что вы не планируете использовать Linq или Entity Framework для доступа к данным, поскольку они не поддерживаются (по состоянию на ноябрь 2010 г.), и вы будет грустно!

Обновление июль 2017

Для тех, кто читает этот ответ сейчас, он устарел, поскольку относится к стеку технологий с задним числом. Смотрите комментарии для более подробной информации.

52 голосов
/ 16 февраля 2009

Взгляните на новые пространственные типы данных, представленные в SQL Server 2008. Они предназначены для решения таких задач и делают индексирование и запросы намного проще и эффективнее.

Дополнительная информация:

29 голосов
/ 20 мая 2009

Я не знаю ответа для SQL Server, но ...

В MySQL сохранить как FLOAT( 10, 6 )

Это официальная рекомендация из документации разработчика Google .

CREATE TABLE `coords` (
  `lat` FLOAT( 10, 6 ) NOT NULL ,
  `lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;
21 голосов
/ 04 марта 2011

Я ненавижу противоречить тем, кто сказал: «Вот новый тип, давайте его использовать». Новые пространственные типы SQL Server 2008 имеют свои плюсы - а именно, эффективность, однако нельзя сказать, что всегда используйте этот тип. Это действительно зависит от некоторых проблем с изображением.

Как пример, интеграция. Этот тип имеет эквивалентный тип в .Net - но как насчет взаимодействия? Как насчет поддержки или расширения старых версий .Net? Как насчет предоставления этого типа через уровень сервиса другим платформам? А как насчет нормализации данных - может быть, вы заинтересованы в последних или в качестве отдельных частей информации. Возможно, вы уже написали сложную бизнес-логику для обработки long / lat.

Я не говорю, что вы не должны использовать пространственный тип - во многих случаях вы должны. Я просто говорю, что вы должны задать несколько более важных вопросов, прежде чем идти по этому пути. Чтобы я мог ответить на ваш вопрос наиболее точно, мне нужно знать больше о вашей конкретной ситуации.

Хранение long / lat отдельно или в пространственном типе - оба жизнеспособных решения, и одно может быть предпочтительнее другого в зависимости от ваших собственных обстоятельств.

18 голосов
/ 24 сентября 2014

Как я это делаю: я сохраняю широта и долгота , а затем у меня есть третий столбец, который является автоматически полученным типом географии первых двух столбцов. Таблица выглядит так:

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.

15 голосов
/ 10 ноября 2009

То, что вы хотите сделать, это сохранить широту и долготу как новый пространственный тип SQL2008 -> GEOGRAPHY.

Вот скриншот стола, который у меня есть.

альтернативный текст http://img20.imageshack.us/img20/6839/zipcodetable.png

В этой таблице у нас есть два поля, в которых хранятся географические данные.

  • Граница: это многоугольник, который является границей почтового индекса
  • CentrePoint: это точка широты / долготы, которая представляет визуальную среднюю точку этого многоугольника.

Основная причина, по которой вы хотите сохранить его в базе данных как тип GEOGRAPHY, заключается в том, что вы можете использовать все методы SPATIAL -> например. Точка в Поли, Расстояние между двумя точками и т. Д.

Кстати, мы также используем Google Maps API для извлечения данных по широте и долготе и сохраняем их в нашей базе данных Sql 2008 - так что этот метод работает.

11 голосов
/ 16 февраля 2009

SQL Server поддерживает пространственную информацию. Вы можете увидеть больше на http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx.

В качестве альтернативы вы можете хранить информацию в виде двух основных полей, обычно число с плавающей запятой является стандартным типом данных, сообщаемым большинством устройств, и является достаточно точным в течение одного-двух дюймов - более чем достаточно для Google Maps.

1 голос
/ 09 декабря 2017

ПРИМЕЧАНИЕ : это недавний ответ, основанный на последних обновлениях SQL-сервера, стека .NET

широта и долгота от Google Maps должны храниться в виде данных точек (примечание P) на сервере SQL под типом данных географии.

Предполагая, что ваши текущие данные хранятся в таблице 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

0 голосов
/ 11 марта 2018

Если вы используете Entity Framework 5 <, вы можете использовать <code>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);
    }
}

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

0 голосов
/ 16 февраля 2009

Хранить как float и использовать уникальные ключевые слова в них. I.em

create table coordinates(
coord_uid counter primary key,
latitude float,
longitude float,
constraint la_long unique(latitude, longitude)
);
...