sql >> データベース >  >> RDS >> Sqlserver

空間を使用して郵便番号の半径を検索するにはどうすればよいですか?

    それで、Phil の提案を使用して、空間を使用してこれの多くを書き直しました。これはうまくいきました.NET4.5、EF5 +、およびSQLサーバーが必要です(2008年以降だと思います)。 EF6 + Sql Server 2012 を使用しています。

    セットアップ

    最初のステップは Geography を追加することでした データベースへの列 EventListings テーブル (右クリック -> デザイン)。私は自分の場所に名前を付けました:

    次に、データベース ファーストで EDM を使用しているため、作成した新しいフィールドを使用するようにモデルを更新する必要がありました。次に、Geography を double に変換できないというエラーを受け取ったので、それを修正するために、エンティティで Location プロパティを選択し、そのプロパティに移動して、そのタイプを double から Geography に変更しました。 :

    半径内でのクエリと場所によるイベントの追加

    あとは、次のようにエンティティ コレクションにクエリを実行するだけです:

     var events = EventRepository.EventListings
                                 .Where(x => x.Location.Distance(originCoordinates) * 0.00062 <= radiusParam); 
    

    Distance 拡張メソッドは、現在のオブジェクトから、渡された「他の」オブジェクトまでの距離を取得します。この他のオブジェクトは DbGeography 型です。 .静的メソッドを呼び出すだけで、これらの子犬の 1 つが作成され、経度と緯度がポイントとして渡されます。

    DBGeography originCoordinates = DBGeography.fromText("Point(" + originLongitude + " " + originLatitude + ")");
    

    これは、originCoordinates を作成した方法ではありません。すべての郵便番号とその緯度と経度のリストを含む別のデータベースをダウンロードしました。タイプ Geography の列を追加しました それにも。この回答の最後にその方法を示します。次に、zipcode コンテキストをクエリして、ZipCode テーブルの Location フィールドから DbGeography オブジェクトを取得しました。

    ユーザーが郵便番号だけでなく、より具体的な起点を求めている場合は、Google Maps API (より具体的には GeoCode) を呼び出し、Web サービスを介してユーザー固有の住所の緯度と経度を取得し、DBGeography オブジェクトを作成します。応答の緯度と経度の値。

    イベントを作成するときも Google API を使用します。エンティティを EF に追加する前に、このように場所変数を設定しました:

    someEventEntity.Location = DBGeography.fromText("Point(" + longitudeFromGoogle+ " " + latitudeFromGoogle + ")");
    

    その他のヒント、コツ、トラブルシューティング

    Distance Extension Method の入手方法

    拡張メソッド Distance を取得するには プロジェクトへの参照を追加する必要があります:System.Data.Entity その後、using:using System.Data.Entity.Spatial; を追加する必要があります。 あなたのクラスに。

    Distance 拡張メソッドはメートル単位で距離を返します (変更できると思いますが、これがデフォルトです)。ここでは、半径パラメーターがマイル単位だったので、計算して変換しました。

    注意 :DBGeography があります System.Data.Spatial のクラス .これは間違っています それは私にはうまくいきません。インターネットで見つけた多くの例で、これが使用されていました。

    緯度/経度を地理列に変換する方法

    だから、あなたが私のように、すべての Latitude を含む郵便番号データベースをダウンロードしたとします。 &Longitude 列を調べた後、地理列がないことに気付きました...これが役立つかもしれません:

    1) テーブルに Location 列を追加します。タイプを地理に設定します。

    2) 次の sql を実行します

    UPDATE [ZipCodes]
    SET Location = geography::STPointFromText('POINT(' + CAST([Longitude] AS VARCHAR(20)) + ' ' + CAST([Latitude] AS VARCHAR(20)) + ')', 4326)
    

    地理アイテムの詳細を表示する方法

    そのため、いくつかの DbGeography 項目を挿入した後に Sql Server Management Studio で EventListings テーブルをクエリすると、Location が表示されます。 列には、0x1234513462346 のような 16 進値が保持されます。正しい値が挿入されていることを確認したい場合、これはあまり役に立ちません。

    このフィールドの緯度と経度を実際に表示するには、次のようにクエリする必要があります:

    SELECT Location.Lat Latitude, Location.Long Longitude
    FROM [EventListings]
    



    1. SQL ServerのNEWID()とNEWSEQUENTIALID():違いは何ですか?

    2. PDOPHPは連想配列からDBに挿入します

    3. 最終日に基づいてレコードを選択します

    4. Oracleはエラー時にトランザクションをロールバックしますか?