0

必要性: テーブルの SQL Geography フィールドのコンテンツを SQL Geometry フィールド タイプに変換する SQL ステートメントを探しています。既存のテーブルに追加する新しいテーブル フィールドです。またはより良い解決策、したがって投稿。

理由: ユーザーが挿入した場所の近くの場所の検索を高速化したいと考えています。場所は現在、Lat、Long、および SQLGeography フィールド タイプを持つテーブルに格納されており、Spatial インデックスはこれに基づいています。Geometry 型の計算は Geography 型の計算よりもリソース消費が少ないため、実行速度を優先して精度が低下する可能性があります。私の現在の計算は米国に限定されており、国際的なタイムラインや極を越えることはありません (おそらく将来的には?...)

その他の考慮事項:

  1. 私の場合、ルックアップは距離だけではなく、特定のエリア(近隣または都市)内です。
  2. 計算列を作成しようとしましたが、インデックスを作成するために永続化できません。これは 2012 年に可能と聞きましたが、2008 R2 で作業しています。

環境: VS 2012、ASP.NET 4.0、Entity Framework 5 (新しい地理フィールドを C# に適切にマップしませんが、とにかく SQL 側でのみ使用されるため問題ありません)。

質問:

  1. STDistance ではなく STIntersects を使用しているため、空間インデックス (Location テーブルの Geodata フィールドに基づく) が使用されないということですか?
  2. 「STIntersects」から「STDistance」を使用するように何らかの形で作り直す必要があります(たとえば、近隣や都市など、エリアのサイズによって異なるため、距離は毎回わかりません)

私が見た良い記事:

  1. http://msdn.microsoft.com/en-us/library/ff929109.aspx
  2. 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());
4

1 に答える 1

0

Geography から Geometry への変換は、ここで回答されています: Convert geography to geometry SQL Server 2008R2 基本的に、テキストに変換してからジオメトリに戻します。

交点よりも 2 点間の距離を計算する方が確かに高速ですが (一般に、交点が些細な場合、たとえば線または点のみを含む場合を除きます)、コードでは、ユーザーが多角形に相当するものを入力できるようにしているため、プロパティの場所 (緯度経度) の 1 つがポリゴンまでの距離内にあるかどうかは、最初にポリゴンの重心を取得しない限り、実際には意味がありません。

緯度経度の有効なスキャン範囲に絞り込むために空間インデックスを使用しますが、ほとんどの処理は、ユーザーが指定したポリゴンの境界領域を最初に見つけることです。DB エンジンは、候補ポイントを検索する前に、まずその部分を実行する必要があります。距離はかなり似ていますが、場所が該当するかどうかを確認する領域が事実上円であるため、いくつかの実行ショートカットが必要です。

于 2016-10-05T05:03:56.353 に答える