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 latlngoutperform 실제 사례가 있습니다 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로 latlon쿼리 아래 것은, 당신이 지리로 변환 도움이 될 것입니다

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.