it-swarm.com.ru

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

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

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

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

98
Jonathan

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

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

52
Craig Bovis

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

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

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

61
dan90266

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

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

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

CREATE TABLE `coords` (
  `lat` FLOAT( 10, 6 ) NOT NULL ,
  `lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;
28
powtac

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

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

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

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

21
R. Lawson

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

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.

17
jaxxbo

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

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

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

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

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

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

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

15
Pure.Krome

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

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

11
Rosstified

NOTE: это недавний ответ, основанный на последних обновлениях SQL-сервера и стека .NET

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

 SSMS geo results tab

1
DhruvJoshi

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

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

0
Ogglas