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


9

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

ジッパーの中心点が特定の半径内にないからといって、ジップ自体が半径内にないということにはならないということが、私に思い浮かんだばかりです。

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

ここに画像の説明を入力してください

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

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

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

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

ピンク色の汚れから半径1マイル以内のすべての郵便番号に対してクエリを実行すると、ピンク色の汚れ自体であっても、郵便番号BとCのみが返されます。郵便番号Aの中心点は半径1マイル以内にないためです。明らかに郵便番号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を含めるクエリを作成するにはどうすればよいですか。

必要に応じてテーブルに追加できる郵便番号ごとに空間/ジオメトリにアクセスできますが、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

誰かがより良い、より効率的なソリューションを持っている場合に備えて、私は今のところバウンティを開いたままにしておきます。

回答:


7

Oracle®Spatial Developer's Guide 11g Release 2(11.2)』のOracleにおける空間データのインデックス作成とクエリから:

空間データのクエリ

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

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

空間クエリ

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

図1 MBRを使用したジオメトリ

「図1 MBRを使用したジオメトリ」の説明

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

図2クエリウィンドウのあるレイヤー

「図2クエリウィンドウのあるレイヤー」の説明

図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に示すすべてのジオメトリを返します。次の例の結果は、ジオメトリ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)はクエリウィンドウの左下隅と右上隅です。


1
いいですね。だから、半径を表すために円のジオメトリを作成し、どのポリゴンが交差するかを確認する必要があります..興味深い.. thxの情報
熊を1度レスリングしました。

ええ..続けて...あなたのためにうまくいくことを願っています。
l.lijith

5

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

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


空間データが必要だとわかっています(それはありますが、Oracleテーブルにあり、変換方法に関する情報があまりありません)。問題は、データのクエリ方法を理解することです。
クマを1回レスリングしました。

新しいコードのパフォーマンスに満足している場合は、おそらくそれが最善です。注:クエリはすべてのzipまでの距離をリストするため、おそらく最適化の可能性はありません。(あなたがより良いコードを手に入れたら私はうれしい驚きをします。)
Rick James

それも私が考えていることです。それがタイムアウトする前に私はあなたに賞金を差し上げます、そしてとにかくあなたはそれの半分を手に入れます...私が最初に得るかもしれない他のどんな反応を見たいだけです。
クマを1回レスリングしました。

3

あなたはそれを間違っています。まず、可能であれば、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 );

9.3 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
1)私はそれを間違っていたことを知っています。それが私が尋ねた理由です。2)私が働いている会社は、USPSの内部郵便番号の境界へのアクセスを支払いました。このプロジェクトではuspsを直接使用しました。3)一般に、OPがまったく異なるツールセットを使用することは適切な答えではないことを示唆しています。
クマを1回レスリングしました。

1
あなたは、MySQL 8とこのようなもののすべてを行うことができます@iwrestledabearonceあまりにもちょうど代わりST_DWithinMBRIntersects
エヴァンキャロル

1
「USPSの内部郵便番号境界への有料アクセス」その製品の名前を知っていますか?私の知る限り、そのようなことはありません。(USPSは2つのデータ製品とアドレスをデコードするためのいくつかのAPIを提供していますが)
Evan Carroll

1
mysqlに関する情報を追加していただきありがとうございます。+1。APIはパブリックではなく、どのWebサイトにもリストされていません。実際、エンドポイントURLにはドメイン名さえありません。IPアドレスから直接要求します。しかし、ただのAPIは、それがこの文書(EDDMを参照してください3は、私が参照してるものです)に記載されて存在することを証明するためにusps.com/business/web-tools-apis/archive/...
私がクマに苦闘しました一度。

1
EDDM / SelectZIPエンドポイントをプルオフする場合、これは実際に正当なように見えます。それはその目的のために宣伝されていませんが、そのエンドポイントを見つけることに賛成です。
エヴァンキャロル

1

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

彼らはジップの中心の代わりに人口密度を使用します。

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

お役に立てれば。


このデータセットはMySQLで利用できますか、それともSQL Serverでのみ利用できますか?
ypercubeᵀᴹ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.