ปัญหาในการรับรหัสไปรษณีย์ในรัศมีผ่าน MySQL


9

ฉันมีตารางรหัสไปรษณีย์ซึ่งมี lat lat ตรงกลาง lng สำหรับรหัสไปรษณีย์แต่ละอัน ฉันใช้มันเพื่อรับรายการรหัสไปรษณีย์ภายในรัศมีไมล์ที่กำหนดจากจุดใด ๆ

มันเกิดขึ้นกับฉันว่าเพียงเพราะจุดศูนย์กลางของซิปไม่ได้อยู่ในรัศมีที่กำหนดไม่ได้หมายความว่าซิปนั้นไม่ได้อยู่ในรัศมี

ฉันใช้ทักษะศิลปะขั้นสูงขั้นสูงของฉันเพื่อแสดงจุดที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

  • Blobs Stripy สีเขียวแสดงรหัสไปรษณีย์ A, B และ C

  • รอยเปื้อนสีแดงเป็นศูนย์กลางทางภูมิศาสตร์สำหรับรหัสไปรษณีย์แต่ละอัน

  • จุดสีแดงม่วงคือตำแหน่งเป้าหมายและ ..

  • วงกลมสีน้ำเงินที่เป็นก้อนนั้นมีรัศมี 1 ไมล์จากตำแหน่งเป้าหมาย

หากฉันเรียกใช้แบบสอบถามสำหรับรหัสไปรษณีย์ทั้งหมดที่อยู่ในรัศมี 1 ไมล์จากรอยเปื้อนสีชมพูรหัสไปรษณีย์ B และ C เท่านั้นที่จะถูกส่งคืนเนื่องจากจุดศูนย์กลางสำหรับรหัสไปรษณีย์ A ไม่ได้อยู่ในรัศมีหนึ่งไมล์แม้ว่ารอยเปื้อนสีชมพูจะเกิดขึ้นเอง ชัดเจนในรหัสไปรษณีย์ 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 สำหรับข้อมูลเชิงพื้นที่และจัดการเพื่อแปลงข้อมูลเชิงพื้นที่ของฉันเป็น MySQLได้สำเร็จ ฉันจะเขียนเคียวรีที่คล้ายกันซึ่งใช้คอลัมน์รูปทรงเรขาคณิตแทนที่จะเป็นละติจูดและลองจิจูดได้อย่างไร ฉันใช้ข้อมูล 2 มิติ .. เรขาคณิตเป็นรูปหลายเหลี่ยมและมีหลายรูปแบบเท่านั้น ..

ฉันคิดว่าฉันคิดออก ..

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ในคู่มือผู้พัฒนาOracle® Spatial 11g Release 2 (11.2):

การสืบค้นข้อมูลเชิงพื้นที่

Spatial ใช้โมเดลเคียวรีสองระดับพร้อมกับการดำเนินการตัวกรองหลักและรองเพื่อแก้ไขเคียวรีเชิงพื้นที่และการรวมเชิงพื้นที่ คำสองชั้นแสดงว่ามีการดำเนินการสองอย่างที่แตกต่างกันเพื่อดำเนินการค้นหา หากดำเนินการทั้งสองชุดผลลัพธ์ที่แน่นอนจะถูกส่งคืน

คุณไม่สามารถผนวกชื่อลิงก์ฐานข้อมูล (dblink) ต่อท้ายชื่อของตารางอวกาศในคิวรีได้หากดัชนีอวกาศกำหนดไว้ในตารางนั้น

แบบสอบถามเชิงพื้นที่

ในดัชนี R-tree เชิงพื้นที่แต่ละรูปทรงเรขาคณิตจะแสดงด้วยสี่เหลี่ยมผืนผ้า bounding ขั้นต่ำ (MBR) พิจารณาเลเยอร์ต่อไปนี้ที่มีหลายวัตถุในรูปที่ 1 แต่ละวัตถุมีชื่อกำกับด้วยรูปทรงเรขาคณิต (geom_1 สำหรับสตริงบรรทัด, geom_2 สำหรับรูปหลายเหลี่ยมสี่ด้าน, geom_3 สำหรับรูปหลายเหลี่ยมรูปสามเหลี่ยมและ geom_4 สำหรับรูปวงรี) และ MBR รอบ ๆ วัตถุนั้นแสดงด้วยเส้นประ

รูปที่ 1 รูปทรงเรขาคณิตที่มี MBR

คำอธิบายของ "Figure1 Geometries with MBRs"

แบบสอบถามเชิงพื้นที่ทั่วไปคือการร้องขอวัตถุทั้งหมดที่อยู่ภายในหน้าต่างแบบสอบถามนั่นคือรั้วหรือหน้าต่างที่กำหนด หน้าต่างแบบสอบถามแบบไดนามิกหมายถึงพื้นที่สี่เหลี่ยมที่ไม่ได้กำหนดไว้ในฐานข้อมูล แต่ต้องถูกกำหนดก่อนที่จะใช้ รูปที่ 2 แสดงรูปทรงเรขาคณิตเดียวกันกับในรูปที่ 1 แต่เพิ่มหน้าต่างแบบสอบถามที่แสดงโดยกล่องเส้นประหนา

รูปที่ 2 Layer พร้อม Query Window

คำอธิบายของ "Figure2 Layer with Query Window"

ในรูปที่ 2 หน้าต่างแบบสอบถามครอบคลุมบางส่วนของรูปทรงเรขาคณิต geom_1 และ geom_2 เช่นเดียวกับส่วนหนึ่งของ MBR สำหรับ geom_3 แต่ไม่มีรูปทรงเรขาคณิต geom_3 จริง หน้าต่างแบบสอบถามไม่ครอบคลุมส่วนใด ๆ ของเรขาคณิต geom_4 หรือ MBR

ผู้ประกอบการตัวกรองหลัก

ตัวดำเนินการ SDO_FILTER ใช้ส่วนตัวกรองหลักของกระบวนการสองขั้นตอนที่เกี่ยวข้องในโมเดลการประมวลผลแบบสอบถาม Oracle Spatial ตัวกรองหลักใช้ข้อมูลดัชนีเพื่อพิจารณาว่าชุดของคู่วัตถุที่มีตัวเลือกอาจโต้ตอบกันหรือไม่ ตัวกรองหลักจะตรวจสอบเพื่อดูว่า 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 อย่างใดอย่างหนึ่งหรือทั้งสองอย่าง

ตัวอย่างต่อไปนี้ดำเนินการตัวกรองหลักเท่านั้น (โดยไม่มีการดำเนินการตัวกรองรอง) พวกเขาจะส่งกลับรูปทรงเรขาคณิตทั้งหมดที่แสดงในรูปที่ 2 ที่มี MBR ที่โต้ตอบกับหน้าต่างแบบสอบถาม ผลลัพธ์ของตัวอย่างต่อไปนี้คือรูปทรงเรขาคณิต geom_1, geom_2 และ geom_3

ตัวอย่างที่ 1 ดำเนินการตัวกรองหลักโดยไม่ต้องแทรกหน้าต่างแบบสอบถามลงในตาราง หน้าต่างจะถูกทำดัชนีในหน่วยความจำและประสิทธิภาพจะดีมาก

ตัวอย่างที่ 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';   

ในตัวอย่าง 1, (x1, y1) และ (x2, y2) เป็นมุมล่างซ้ายและขวาบนของหน้าต่างแบบสอบถาม


1
เยี่ยมมาก .. ดังนั้นฉันควรสร้างรูปทรงวงกลมเพื่อแสดงรัศมีแล้วดูว่ารูปหลายเหลี่ยมใดตัดกัน .. น่าสนใจ .. ขอบคุณสำหรับข้อมูล
ฉันปล้ำหมีครั้งเดียว

ใช่ .. ไปที่ ... หวังว่ามันจะทำงานได้ดีสำหรับคุณ
l.lijith

5

ความพยายามใด ๆ ที่จะรวม A อาจรวมถึง D, E, F, G ปัญหาไม่สามารถแก้ไขได้หากไม่มีเส้นทางที่แน่นอนที่กำหนดแต่ละพื้นที่รหัสไปรษณีย์

ค้นหาฐานข้อมูลดังกล่าวจากนั้นสร้างSPATIALดัชนีโดยใช้รูปหลายเหลี่ยมโดยพลการ


ฉันรู้ว่าฉันต้องการข้อมูลเชิงพื้นที่ (และฉันมี แต่มันอยู่ในตาราง Oracle และฉันไม่ได้หาข้อมูลมากเกี่ยวกับวิธีการแปลง) .. ปัญหาคือการหาวิธีการค้นหาข้อมูล
ฉันปล้ำหมีหนึ่งครั้ง

หากคุณพอใจกับประสิทธิภาพของรหัสใหม่นั่นอาจเป็นวิธีที่ดีที่สุด หมายเหตุ: แบบสอบถามจะแสดงระยะทางไปยังทุก ๆ zip ดังนั้นจึงไม่มีโอกาสที่จะเกิดประโยชน์สูงสุด (ฉันจะต้องประหลาดใจถ้าคุณได้รับรหัสที่ดีกว่า.)
ริกเจมส์

นั่นเป็นสิ่งที่ฉันคิดเช่นกัน ฉันจะให้รางวัลแก่คุณก่อนที่มันจะหมดเวลาและคุณจะได้ครึ่งหนึ่งของมันต่อไป .. แค่อยากเห็นคำตอบอื่น ๆ ที่ฉันอาจได้รับก่อน
ฉันปล้ำหมีหนึ่งครั้ง

3

คุณทำผิด ก่อนอื่นถ้าเป็นไปได้ให้ใช้ PostGIS - ซึ่งเป็น RDMBS ชั้นนำที่มีวิธีแก้ปัญหาเชิงพื้นที่

จากนั้นคุณต้องการทำตามขั้นตอนเหล่านี้

  1. ดึงลงZCTA (Zip ตารางรหัสพื้นที่) จากชุดข้อมูล รหัสไปรษณีย์ไม่ทราบแน่นอน รหัสไปรษณีย์มีไว้สำหรับการใช้ภายในโดย USPS เท่านั้น เนื่องจากทุกคนใช้พวกเขารวมถึงรัฐบาลแหล่งข้อมูลที่เชื่อถือได้มากที่สุดอันดับสองกลายเป็นรูปแบบ 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 แทรกสำหรับ Census Shapefile
  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
@iwrestledabearonce คุณสามารถทำทุกสิ่งนี้กับ MySQL 8 เกินไปเพียงแทนST_DWithinด้วยMBRIntersects
อีวานคาร์โรลล์

1
"การเข้าถึงขอบเขตรหัสไปรษณีย์ภายในของ USPS ที่ชำระเงิน"คุณรู้จักชื่อผลิตภัณฑ์นั้นหรือไม่ AFAIK ไม่มีสิ่งนั้น (แม้ว่า USPS จะเสนอผลิตภัณฑ์ข้อมูล 2 รายการและ API บางตัวสำหรับที่อยู่การถอดรหัส)
Evan Carroll

1
ขอบคุณสำหรับการเพิ่มข้อมูลเกี่ยวกับ mysql +1 api ไม่ได้เป็นสาธารณะและไม่มีอยู่ในเว็บไซต์ใด ๆ ในความเป็นจริง URL ปลายทางไม่มีแม้กระทั่งชื่อโดเมนเราขอได้โดยตรงจากที่อยู่ IP อย่างไรก็ตามเพื่อพิสูจน์ว่า api มีอยู่ในรายการในเอกสารนี้ (3 ที่อ้างถึง EDDM เป็นสิ่งที่ฉันหมายถึง) usps.com/business/web-tools-apis/archive/
ฉันต่อสู้กับหมี ครั้งหนึ่ง

1
ดูเหมือนจะถูกต้องตามกฎหมายถ้าคุณดึงจุดปลาย EDDM / SelectZIP ออก นั่นไม่ใช่โฆษณาสำหรับจุดประสงค์นั้น แต่ขอชื่นชมในการค้นหาจุดสิ้นสุดนั้น
Evan Carroll

1

ลองใช้ชุดข้อมูลนี้จากGreatData.com (โปรดทราบว่านี่ไม่ใช่โอเพ่นซอร์ส แต่เป็นบริการแบบชำระเงิน)

พวกเขาใช้ความหนาแน่นของประชากรแทนที่จะเป็นจุดศูนย์กลาง

และวิธีการใช้ชนิดข้อมูลเชิงพื้นที่ของ sql server เพื่อให้ได้ผลลัพธ์ที่ถูกต้องรวดเร็ว

หวังว่านี่จะช่วยได้


ชุดข้อมูลนี้มีให้สำหรับ MySQL หรือใช้กับ SQL Server เท่านั้น
ypercubeᵀᴹ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.