SQL Server에서 좌표 (Google지도의 경도 / 위도)를 저장하는 가장 좋은 방법은 무엇입니까?


103

사용자 목록과 Google지도 좌표 (경도 및 위도)를 저장할 테이블을 SQL Server 2008에서 디자인하고 있습니다.

두 개의 필드가 필요합니까, 아니면 1로 할 수 있습니까?

이러한 종류의 데이터를 저장하는 데 가장 적합한 (또는 가장 일반적인) 데이터 유형은 무엇입니까?

답변:



63

공정한 경고! GEOGRAPHY 유형을 사용하라는 조언을 받기 전에 Linq 또는 Entity Framework를 사용하여 데이터에 액세스 할 계획이 없는지 확인하십시오. 2010 년 11 월 현재 지원되지 않으므로 슬프게 될 것입니다!

2017 년 7 월 업데이트

지금이 답변을 읽는 사람들에게는 백 데이트 기술 스택을 참조하므로 더 이상 사용되지 않습니다. 자세한 내용은 주석을 참조하십시오.


1
원래 답변이 게시 된 이후 로 가능한 해결 방법을 논의하는 이 기사 jasonfollas.com/blog/archive/2010/02/14/…을 발견했습니다 .
— Norman H

56
경고는 더 이상 유효하지 않습니다. EF는 이제 지리 유형을 지원합니다.
— Marcelo Mason

1
Nerveless EF는 공간 유형을 지원하고 WCF 데이터 서비스에 대해 다른 유형 세트를 사용하므로 호환되지 않습니다
— abatishchev

1
최대 절전 모드 5 공간은 여전히 ​​예를 들어하지 않습니다 :(
— Eugene

1
공정한 경고는 여전히 Entity Framework Core 2.0을 적용합니다. github.com/aspnet/EntityFrameworkCore/issues/1100
— ono2012

29

SQL Server에 대한 답은 모르지만 ...

에서 의 MySQL 을로 저장FLOAT( 10, 6 )

이것은 Google 개발자 문서 의 공식 권장 사항입니다 .

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

19
질문에는 MySQL이 아니라 SQL Server가 명시되어 있습니다. 그리고 당신은 확실히 위도와 경도만을 가진 테이블을 원하지 않을 것입니다.
— araqnid

2
동의-나쁜 대답. 새로운 GEOGRAPHY 공간 유형을 사용하십시오.
— Pure.Krome 2009


14
정밀도 문제 때문에 float를 사용하지 않을 것입니다. decimal (9,6)을 사용합니다.
— kaptan

SQL 2014에서 고밀도 인덱스를 사용하더라도 where lat및 lngoutperform 실제 사례가 있습니다 georgraphy. 예를 들어, 모든 점 찾기가 직사각형에 속합니다. 확실하지 않습니다. 이제 Google지도에서 6 자리 대신 7 자리를 사용한다는 것을 알 수 있습니다.
— Nenad

22

내가하는 방법 : 위도 와 경도를 저장 한 다음 첫 번째 두 열의 자동 파생 지리 유형 인 세 번째 열이 있습니다. 표는 다음과 같습니다.

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 목적으로 표시하거나 추출하기 위해 필요에 따라 위도 및 경도 값을 검색 할 수도 있습니다.


내가 찾고 있었는지에 대 한 좋은 당신이 트랙 / 라인 아무것도해야합니까
— 애기

시나리오에 따라 작동 할 수있는 또 다른 접근 방식은 long 및 lat을 저장 한 다음 런타임에 즉석에서 geography 개체를 동적으로 만드는 것입니다.
— Zapnologica

1
좋은 생각이지만 누군가의 의도 인 경우 계산 된 열에 공간 인덱스를 만들 수 없습니다.
— hvaughan3

1
@ hvaughan3 영구 계산 열로 만들면 할 수 있다고 생각합니다 .
— NickG

2
감사합니다. 귀하의 답변이 도움이되었습니다. 그러나 . Point대신 사용 하는 것이 더 나을 것이라고 생각합니다 STGeomFromText. 예 : [geography]::Point([Latitude], [Longitude], 4326).
— default.kramer 2016

21

나는 "여기에 새로운 유형이있다, 그것을 사용하자"라고 말하는 사람들과 반대되는 것이 싫다. 새로운 SQL Server 2008 공간 유형에는 몇 가지 장점, 즉 효율성이 있지만 항상 해당 유형을 사용한다고 맹목적으로 말할 수는 없습니다. 그것은 실제로 더 큰 그림 문제에 달려 있습니다.

예를 들어 통합입니다. 이 유형은 .Net에서 동등한 유형을 가지고 있지만 interop은 어떻습니까? .Net의 이전 버전을 지원하거나 확장하는 것은 어떻습니까? 이 유형을 서비스 계층 전체에서 다른 플랫폼에 노출하는 것은 어떻습니까? 데이터 정규화는 어떻습니까-아마도 당신은 위도 또는 경도 독립형 정보에 관심이있을 것입니다. long / lat을 처리하는 복잡한 비즈니스 로직을 이미 작성했을 것입니다.

공간 유형을 사용해서는 안된다는 것이 아닙니다. 많은 경우에 사용해야합니다. 그 길을 가기 전에 좀 더 중요한 질문을해야한다고 말하는 것입니다. 귀하의 질문에 가장 정확하게 대답하려면 귀하의 특정 상황에 대해 더 많이 알아야합니다.

long / lat을 별도로 저장하거나 공간 유형으로 저장하는 것은 모두 실행 가능한 솔루션이며 자신의 상황에 따라 하나가 다른 것보다 선호 될 수 있습니다.


GIS 및 공간 데이터 처리는 최소한 2000 년대 이후로 긴 역사와 표준 텍스트 바이너리 표현을 가지고 있습니다. 공간 유형과 표준 표현을 사용 하지 않으면 언급 한 모든 문제로 끝날 것입니다
— Panagiotis Kanavos 2017

15

원하는 것은 위도와 경도를 새로운 SQL2008 Spatial 유형-> GEOGRAPHY로 저장하는 것입니다.

여기 제가 가지고있는 테이블의 스크린 샷이 있습니다.

대체 텍스트 http://img20.imageshack.us/img20/6839/zipcodetable.png

이 테이블에는 지리 데이터를 저장하는 두 개의 필드가 있습니다.

  • 경계 : 우편 번호 경계인 다각형입니다.
  • CentrePoint :이 다각형의 시각적 중간 지점을 나타내는 위도 / 경도 지점입니다.

GEOGRAPHY 유형으로 데이터베이스에 저장하려는 주된 이유는 모든 SPATIAL 메소드를 활용할 수 있기 때문입니다. Point in Poly, 두 점 사이의 거리 등

BTW, 우리는 또한 Google의 Maps API를 사용하여 위도 / 경도 데이터를 검색하고 Sql 2008 DB에 저장하므로이 방법이 작동합니다.


1
아직 2008 년이 아니라면 SQLCE를 사용한다면 어떻게 될까요? 후자는 GEOGRAPHY 유형을 지원하지 않습니다 ...
— fretje

3
SqlCE 또는 <2008이 이진을 지원하는 경우 결과를 varbinary로 저장 한 다음 공간 도구 라이브러리 dll을 사용하여 .NET 코드에서이 이진 데이터 표현에 대해 공간 계산을 수행 할 수 있습니다. 최선의 해결책은 아니지만 일부 문제에 대한 가능한 해결책 입니다. (SQL 공간에 대한 Nuget .. 해당 dll을 가져옵니다).
— Pure.Krome 2011 년

2
이미지 링크가 깨졌습니다
— Bryan Denny

. 아무것도 imageshack에 대한 urgh :( 덕분에 내가 사용하지 않는 한이 :( imgur.com을 끝까지 년간입니다!
— Pure.Krome

1
-1,이 대답은 이미지 없이는 불완전합니다. 새 이미지 또는 텍스트 표 설명으로 바꾸거나이 답변을 삭제하십시오.
— Ilmari Karonen 16.03.13

11

SQL Server는 공간 관련 정보를 지원합니다. http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx 에서 자세한 내용을 볼 수 있습니다 .

또는 정보를 두 개의 기본 필드로 저장할 수 있습니다. 일반적으로 부동 소수점은 대부분의 장치에서보고하는 표준 데이터 유형이며 Google지도에 적합한 것보다 1 ~ 2 인치 이내로 정확합니다.


2

참고 : 이것은 최근 SQL 서버, .NET 스택 업데이트를 기반으로 한 최근 답변입니다.

구글 맵의 위도와 경도는 지리 데이터 유형으로 SQL 서버에 Point (note capital P) 데이터로 저장되어야합니다.

테이블에 저장된 현재 데이터를 가정 할 Sample열에서 VARCHAR로 lat및 lon쿼리 아래 것은, 당신이 지리로 변환 도움이 될 것입니다

alter table Sample add latlong geography
go
update Sample set latlong= geography::Point(lat,lon,4326)
go

추신 : 다음 번에 결과 및 메시지 탭과는 별도로 지리 데이터로이 테이블을 선택하면 시각화를 위해 아래와 같은 공간 결과 탭도 표시됩니다.

SSMS 지리적 결과 탭


0

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


-4

URL로 대체하려는 경우 한 필드가 가능하다고 가정합니다. 따라서 다음과 같은 URL을 형성 할 수 있습니다.

http://maps.google.co.uk/maps?q=12.345678,12.345678&z=6

하지만 두 개의 데이터이므로 별도의 필드에 저장합니다.


이건 내 사건이야. 좌표를 하나의 필드에만 저장하고 쉼표로 구분해야합니다. TEXT를 필드 유형으로 사용할 수 있다고 생각합니다. 어떻게 생각해?
— Amr

-10

둘 다 float로 저장하고 고유 한 키워드를 사용합니다.

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

위도 및 경도 쌍의 고유 한 세트가 하나만 있는지 확인합니다. 테이블에 {0,0} 좌표를 두 번 저장하고 싶지 않으십니까?
— Graviton

1
이와 같은 별도의 좌표 테이블을 갖고 싶지 않을 것입니다. 특히 고유성 제약 조건으로 인해 참조되지 않은 행을 정리하는 것은 말할 것도없고 두 위치가 동일한 지점을 참조하는 경우를 처리하는 유지 관리 악몽입니다.
— araqnid

2
> 아마도 이와 같은 별도의 좌표 테이블을 갖고 싶지 않을 것입니다.- 전혀 요? 못? 한 필드에 어떻게 저장 하시겠습니까? SQL 2008 Spatial 유형을 사용하지 않는 수백만 명의 사람들은 어떻습니까?
— Sally

2
그러한 제약을 갖는 것은 나쁜 결정입니다. Bob 이 앨리스가 살던 집인에 살고 있고 House A이사 할 것이라고 가정 House B합니다. 곧 Bob은 자신의 주소 (위치)를 저장할 수 없습니다. Alice가 아직 그녀를 업데이트하지 않았거나 절대 업데이트하지 않았기 때문입니다.
— jweyrich

@Sally-그가 말한 것이 아닙니다. 그의 의견을 읽으십시오. 그는 별도의 테이블 에 한 쌍의 값을 저장할 이유가 없어야한다고 말했습니다 . 위도 / 경도를 원래 테이블에 놓고 두 번째 테이블과 모든 JOINS의 오버 헤드를 저장합니다.
— NickG
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.