web-dev-qa-db-ja.com

SQL Serverに座標(Googleマップの経度/緯度)を保存する最良の方法は何ですか?

ユーザーのリストとGoogleマップの座標(経度と緯度)を格納するSQL Server 2008のテーブルを設計しています。

2つのフィールドが必要ですか、それとも1でできますか?

この種のデータの保存に使用するのに最適な(または最も一般的な)データ型は何ですか?

99
Jonathan

SQL Server 2008で導入された新しいSpatialデータ型をご覧ください。これらのデータ型は、この種のタスク用に設計されており、インデックス作成とクエリをはるかに簡単かつ効率的にします。

詳しくは:

52
Craig Bovis

公正な警告! GEOGRAPHYタイプを使用するアドバイスを受ける前に、LinqまたはEntity Frameworkを使用してデータにアクセスする予定がないことを確認してください(2010年11月現在)悲しい!

2017年7月更新

この答えを今読んでいる人にとって、それは時代遅れの技術スタックを指すので時代遅れです。詳細についてはコメントを参照してください。

62
dan90266

SQL Serverの答えはわかりませんが...

MySQLFLOAT( 10, 6 )として保存します

これは Google開発者向けドキュメント からの公式の推奨事項です。

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

「ここに新しいタイプがあります、それを使ってみよう」と言った人たちに反対するのは嫌いです。新しいSQL Server 2008空間タイプには、いくつかの長所があります。つまり、効率性ですが、盲目的に常にそのタイプを使用するとは言えません。それはいくつかのより大きな画像の問題に本当に依存しています。

例として、統合。このタイプには、.Netに同等のタイプがありますが、相互運用機能はどうですか?古いバージョンの.Netのサポートまたは拡張についてはどうですか?このタイプをサービスレイヤー全体で他のプラットフォームに公開するのはどうですか?データの正規化についてはどうですか-スタンドアロンの情報として緯度経度に興味があるかもしれません。おそらく、長い/遅いを処理するための複雑なビジネスロジックをすでに作成している可能性があります。

空間タイプを使用すべきではないと言っているわけではありません-多くの場合、使用すべきです。その道を進む前に、もっと重要な質問をするべきだと言っています。私があなたの質問に最も正確に答えるためには、あなたの特定の状況についてもっと知る必要があります。

Long/latを別々に、または空間タイプに格納することは、どちらも実行可能なソリューションであり、自分の状況に応じて一方が他方よりも望ましい場合があります。

21
R. Lawson

方法:緯度および経度を保存し、最初の2列の自動派生地理タイプである3番目の列があります。テーブルは次のようになります。

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目的での表示または抽出に必要な緯度と経度の値を取得することもできます。

18
jaxxbo

行うことは、緯度と経度を新しいSQL2008 Spatialタイプ-> GEOGRAPHYとして保存することです。

ここに私が持っているテーブルのスクリーンショットがあります。

alt text http://img20.imageshack.us/img20/6839/zipcodetable.png

このテーブルには、地理データを保存する2つのフィールドがあります。

  • 境界:これは郵便番号の境界であるポリゴンです
  • CentrePoint:これは、このポリゴンの視覚的な中点を表す緯度/経度のポイントです。

GEOGRAPHYタイプとしてデータベースに保存する主な理由は、すべてのSPATIALメソッドを活用できるようにするためです->ポリのポイント、2つのポイント間の距離など.

ところで、GoogleのMaps APIを使用してlat/longデータを取得し、それをSql 2008 DBに保存します。したがって、このメソッドは機能します。

15
Pure.Krome

SQL Serverは、空間関連情報をサポートしています。詳細は http://www.Microsoft.com/sqlserver/2008/en/us/spatial-data.aspx で確認できます。

別の方法として、2つの基本フィールドとして情報を保存できます。通常、フロートはほとんどのデバイスで報告される標準データ型であり、1〜2インチ以内で十分に正確です。

11
Rosstified

[〜#〜] note [〜#〜]:これは、最近のSQLサーバー、.NETスタックの更新に基づいた最近の回答です。

google Mapsの緯度と経度は、地理データタイプでSQLサーバーにポイント(大文字Pに注意)データとして保存する必要があります。

現在のデータがSampleおよびlat列の下のvarcharとしてテーブル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