必要性: テーブルの SQL Geography フィールドのコンテンツを SQL Geometry フィールド タイプに変換する SQL ステートメントを探しています。既存のテーブルに追加する新しいテーブル フィールドです。またはより良い解決策、したがって投稿。
理由: ユーザーが挿入した場所の近くの場所の検索を高速化したいと考えています。場所は現在、Lat、Long、および SQLGeography フィールド タイプを持つテーブルに格納されており、Spatial インデックスはこれに基づいています。Geometry 型の計算は Geography 型の計算よりもリソース消費が少ないため、実行速度を優先して精度が低下する可能性があります。私の現在の計算は米国に限定されており、国際的なタイムラインや極を越えることはありません (おそらく将来的には?...)
その他の考慮事項:
- 私の場合、ルックアップは距離だけではなく、特定のエリア(近隣または都市)内です。
- 計算列を作成しようとしましたが、インデックスを作成するために永続化できません。これは 2012 年に可能と聞きましたが、2008 R2 で作業しています。
環境: VS 2012、ASP.NET 4.0、Entity Framework 5 (新しい地理フィールドを C# に適切にマップしませんが、とにかく SQL 側でのみ使用されるため問題ありません)。
質問:
- STDistance ではなく STIntersects を使用しているため、空間インデックス (Location テーブルの Geodata フィールドに基づく) が使用されないということですか?
- 「STIntersects」から「STDistance」を使用するように何らかの形で作り直す必要があります(たとえば、近隣や都市など、エリアのサイズによって異なるため、距離は毎回わかりません)
私が見た良い記事:
- http://msdn.microsoft.com/en-us/library/ff929109.aspx
- http://workshops.opengeo.org/postgis-intro/geography.html
SQL クエリからの抜粋:
...
SELECT @bounds = 'POLYGON(('...'))';
SELECT @location = geography::Parse(@bounds);
...
SELECT p.ID
FROM Property p
INNER JOIN Location l WITH(INDEX(SPATIAL_Location)) ON p.LocationID = l.ID
WHERE
...
AND (l.Geodata.STIntersects(@location) = 1
AND l.Geodata.STDifference(@location).STIsEmpty() = 1)
...
ORDER BY
...
l.Geodata.STDistance(@location.EnvelopeCenter());