web-dev-qa-db-ja.com

MySQLを介して半径でzipを取得する際の問題

各郵便番号の中央の緯度と経度を含む郵便番号の表があります。私はそれを使用して、任意のポイントから半径1マイル以内の郵便番号のリストを取得します。

Zipの中心点が特定の半径内にないからといって、Zip自体が半径内にないということにはならないことに気づきました。

超高度なアートスキルを使用して、ここでポイントを説明しました。

enter image description here

  • 緑のストライプの塊は、郵便番号A、B、Cを表しています。

  • 赤い汚れは各郵便番号の地理的中心です

  • フクシアドットはターゲットの場所です。

  • でこぼこの青い円は、ターゲットの場所から半径1マイルです。

ピンクのスマッジから半径1マイル以内のすべての郵便番号に対してクエリを実行すると、ピンクのスマッジ自体が半径1マイル以内にないため、郵便番号BおよびCのみが返されます。明らかに郵便番号Aにあります。

SELECT *,
        p.distance_unit
                 * DEGREES(ACOS(COS(RADIANS(p.latpoint))
                 * COS(RADIANS(z.y))
                 * COS(RADIANS(p.longpoint) - RADIANS(z.x))
                 + SIN(RADIANS(p.latpoint))
                 * SIN(RADIANS(z.y)))) AS dist
  FROM standard_Zip AS z
  JOIN (   /* these are the query parameters */
        SELECT  $lat  AS latpoint,  $lng AS longpoint,
                $miles AS radius,      69 AS distance_unit
    ) AS p ON 1=1
  WHERE z.y
     BETWEEN p.latpoint  - (p.radius / p.distance_unit)
         AND p.latpoint  + (p.radius / p.distance_unit)
    AND z.x
     BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
         AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
  ORDER BY dist

結果にZip Aを含めるクエリをどのように書くのですか?

必要に応じてテーブルに追加できるZipコードごとに空間/ジオメトリにアクセスできますが、MySQLでこの目的にどのように使用するかわかりません。


編集:空間データのOracleとMySQLのドキュメントを1日読んで、空間データを正常に管理できました 空間データをMySQLに変換します 。緯度と経度の代わりにジオメトリ列を使用する同様のクエリを作成するにはどうすればよいですか? 2Dデータを使用しています。ジオメトリはポリゴンとマルチポリゴンのみです。

私はそれを理解したと思う。

select
  *
from
  (
    select
      MIN(st_distance(geom, POINT(-82.765136, 28.0914015))) * 69 as miles,
      Zip
    from
      Zip_spatial
    group by
      Zip
    order by
      miles asc
  ) d
where
  d.miles < 5

誰かがより良い、より効率的なソリューションを持っている場合に備えて、当面の間、賞金を空けておきます。

『Oracle®Spatial開発者ガイド11gリリース2(11.2)』の Oracleでの空間データのインデックス作成とクエリ

空間データのクエリ

Spatialは、プライマリおよびセカンダリフィルター操作を含む2層クエリモデルを使用して、空間クエリと空間結合を解決します。 2層という用語は、クエリを解決するために2つの異なる操作が実行されることを示します。両方の操作が実行されると、正確な結果セットが返されます。

空間インデックスがテーブルに定義されている場合、クエリ内の空間テーブルの名前にデータベースリンク(dblink)名を追加することはできません。

空間クエリ

空間Rツリーインデックスでは、各ジオメトリはその最小外接長方形(MBR)で表されます。図1のいくつかのオブジェクトを含む次のレイヤーについて考えます。各オブジェクトにはそのジオメトリ名(ラインストリングはgeom_1、4辺のポリゴンはgeom_2、三角形のポリゴンはgeom_3、楕円はgeom_4)でラベルが付けられ、各オブジェクトの周囲のMBRは破線で表されます。

Figure1 Geometries with MBRs

「図1 MBRを含むジオメトリ」の説明

典型的な空間クエリは、クエリウィンドウ内にあるすべてのオブジェクト、つまり定義されたフェンスまたはウィンドウを要求することです。動的クエリウィンドウとは、データベースで定義されていないが、使用する前に定義する必要がある長方形の領域を指します。図2は、図1と同じジオメトリを示していますが、太い点線のボックスで表されるクエリウィンドウが追加されています。

Figure2 Layer with a Query Window

「Figure2 Layer with a Query Window」の説明

図2のクエリウィンドウは、geom_1とgeom_2のジオメトリの一部、およびgeom_3のMBRの一部をカバーしていますが、実際のgeom_3ジオメトリはカバーしていません。クエリウィンドウは、geom_4ジオメトリまたはそのMBRのどの部分もカバーしません。

プライマリフィルター演算子

SDO_FILTER演算子は、Oracle Spatialクエリ処理モデルに含まれる2ステッププロセスのプライマリフィルター部分を実装します。プライマリフィルターは、インデックスデータを使用して、候補オブジェクトのペアのセットが相互作用するかどうかを判断します。具体的には、プライマリフィルターは、オブジェクト自体が相互作用するかどうかではなく、候補オブジェクトのMBRが相互作用するかどうかを確認します。 SDO_FILTER演算子の構文は次のとおりです。

SDO_FILTER(geometry1 SDO_GEOMETRY, geometry2 SDO_GEOMETRY, param VARCHAR2)

上記の構文では:

  • geometry1は、テーブル内のSDO_GEOMETRY型の列です。この列には空間インデックスを付ける必要があります。

  • geometry2は、SDO_GEOMETRY型のオブジェクトです。このオブジェクトは、テーブルからのものである場合とそうでない場合があります。テーブルからのものである場合は、空間的にインデックスが付けられている場合とされていない場合があります。

  • paramは、タイプVARCHAR2のオプションの文字列です。 min_resolutionおよびmax_resolutionキーワードのいずれかまたは両方を指定できます。

次の例は、1次フィルター操作のみを実行します(2次フィルター操作はありません)。これらは、クエリウィンドウとやり取りするMBRを持つ、図2に示すすべてのジオメトリを返します。以下の例の結果は、geomries geom_1、geom_2、geom_3です。

Example1は、クエリウィンドウをテーブルに挿入せずにプライマリフィルター操作を実行します。ウィンドウはメモリ内でインデックスが付けられ、パフォーマンスは非常に良好です。

例1一時クエリウィンドウを持つプライマリフィルター

SELECT A.Feature_ID FROM TARGET A  WHERE sdo_filter(A.shape, SDO_geometry(2003,NULL,NULL,
                                       SDO_elem_info_array(1,1003,3),
                                       SDO_ordinate_array(x1,y1, x2,y2))
                           ) = 'TRUE';   

Example1では、(x1、y1)と(x2、y2)はクエリウィンドウの左下隅と右上隅です。

7
l.lijith

Aを含めようとする試みには、おそらくD、E、F、Gが含まれます。この問題は、各郵便番号領域を定義する正確なパスがなければ解決できません。

そのようなデータベースを見つけ、そのような任意のポリゴンを使用してSPATIALインデックスを構築します。

5
Rick James

あなたはそれを間違っています。まず、可能であれば、PostGISを使用します。これは、空間ソリューションを備えた主要なRDMBSです。

次に、これらの手順に従います。

  1. 国勢調査のTIGERデータセットから ZCTA(郵便番号集計領域) をプルダウンします。郵便番号は実際には特定されていません。正式には、郵便番号はUSPSのみが内部で使用するためのものです。政府を含む誰もがそれらを使用するため、2番目に信頼できるソースはZCTAシェープファイルになりました。
  2. これらのシェープファイルをデータベースにインポートします。PostgreSQLを使用すると、shp2pgsql
  3. インポートしたジオメトリにインデックスを付けます。

    CREATE INDEX ON census_zcta USING Gist (geog);
    ANALYZE census_zcta;
    
  4. シェープファイルに対してポイントオブインタレスト(POI)クエリを実行します。あなたの場合の関心のポイントは入力コードです、これはこのようになります、

    SELECT *
    FROM census_zcta AS zcta
      WHERE ST_Intersects( zcta, ST_MakePoint(long,lat)::geog );
    

ℹ1609.344メートル= 1マイル

MySQL

MySQLを使用すると、

  1. Ogr2ogrを使用して、国勢調査シェープファイルのMySQL挿入ステートメントを出力します。
  2. MBRIntersects を使用して、空間インデックスを利用します。終了クエリは次のようになります

    SELECT *
    FROM zcta
    WHERE MBRIntersects( geom, Point(long,lat) )
      AND ST_Intersects ( geom, Point(long,lat) );
    
3
Evan Carroll

GreatData.com からこのデータセットを確認してください(これはオープンソースではなく有料サービスであることに注意してください)。

Zipの中心ではなく、人口密度を使用します。

また、SQLサーバーの空間データ型を使用して正しい結果をすばやく取得する方法。

お役に立てれば。

1
Matt McDonald