จุดสุ่มตัวอย่างตามแนวชายฝั่งที่มีการพันเสาด้วย PostGIS


11

ฉันกำลังทำงานที่ต้องให้ฉันได้รับคะแนนตัวอย่างทุก ๆ 1,000 กม. ตามแนวชายฝั่งและพบปัญหากับแอนตาร์กติกา จากสิ่งที่ฉันสามารถบอกได้ดูเหมือนว่าจะมีปัญหากับการใช้รูปทรงเรขาคณิตในฟังก์ชั่นเมื่อฉันคิดว่าควรจะใช้ภูมิศาสตร์สำหรับการดำเนินการนี้

การใช้ฟังก์ชั่นจากคำถามที่คล้ายกันอย่างนี้ผลลัพธ์ไม่ดีผมก็สามารถที่จะผลิตผลที่มีลักษณะเช่นนี้

อย่างที่คุณเห็นST_AddMeasure()และST_LocateAlong()ไม่ดูเหมือนว่าจะรักษารูปทรงกลมซึ่งส่งผลให้มีหลายจุดที่อยู่บนขั้วโลกใต้ มีการเพิ่มจุดบนคลิปตามบรรทัดวันที่ (ด้านซ้าย) ตามเอกสารของทั้งสองฟังก์ชั่นสามารถใช้รูปทรงเรขาคณิตเท่านั้น

รหัสที่ใช้ในการสร้างรูปหลายเหลี่ยมและจุดสามารถพบได้ที่นี่แต่นี่คือ SQL ที่ใช้ในการสร้างคะแนน:

CREATE TABLE atest AS WITH line AS 
  (SELECT
      id,
      ST_ExteriorRing((ST_Dump(geom)).geom) AS geom
    FROM line_sample_test),
linemeasure AS
    (SELECT
        ST_AddMeasure(line.geom, 0, (ST_Length(line.geom))::int) AS linem,
    generate_series(0, (ST_Length(line.geom))::int, 10) AS i
FROM line),

geometries AS (
    SELECT
        i,
        ST_LocateAlong(linem, i) AS geom 
    FROM linemeasure)

SELECT
    * from geometries;

ฉันจะสร้างคะแนนได้ทุก ๆ 1,000 กม. ตามแนวชายฝั่งนี้ได้อย่างไร


คุณลอง ST_Segmentize แล้วหรือยัง นอกจากนี้ยังสามารถทำงานกับรูปทรงเรขาคณิตได้ แต่อย่างน้อยดูเหมือนว่าจะเป็นวิธีที่รวดเร็วกว่าในการสร้างคะแนน อย่างไรก็ตามทำไมไม่เพียงแค่ลบคะแนนที่เสา? ดูเหมือนว่ามีผลข้างเคียงของการฉายที่ใช้แล้วมากกว่าข้อบกพร่อง
lynxlynxlynx

5
จากภาพของคุณดูเหมือนว่าคุณมีรูปทรงเรขาคณิตของคุณใน EPSG: 4326 แอนตาร์กติกาเหมาะกว่าการฉายภาพโดยใช้ขั้วโลกเช่น EPSG: 3031 ถึงแม้ว่ามันจะดูเหมือนว่าคุณอาจต้องจัดการกับเส้นตัดไปที่เสาและด้านหลังตามแนวเส้นวันที่
Toby Speight

คำตอบ:


3

ตามที่แนะนำในหนึ่งในความคิดเห็นฉันจะเปลี่ยนเรขาคณิตอินพุตเป็นภาพโปรเจคเทอร์กราฟิก

นอกจากนี้คุณจะต้องใช้ST_Bufferมัน (จำนวน0) เพื่อกำจัดเส้นตัดที่เกิดขึ้น

ดังนั้นจะได้รับผลลัพธ์ที่คุณต้องการ:

-- ST_Transform(geom,3031) reprojects to south polar stereographic,
-- in meters.  ST_Buffer(...) doesn't change the shape, but removes
-- the cut line to the pole (at 180 degrees).
WITH line AS (
    SELECT ST_ExteriorRing(
        ST_Buffer(ST_Transform(geom, 3031), 0)
    ) AS geom
    FROM line_sample_test
),

-- This just generates a table of numbers.  In this case, from 0
-- to the geometry length, counting by 1,000,000 (1000 km).
linemeasure AS (
    SELECT generate_series(0, ST_Length(geom)::int, 1000000) AS i
    FROM line
),

-- Convert those values to a fraction of the overall length (for
-- use as input to ST_LineInterpolatePoint)
linefraction AS (
    SELECT i / ST_Length(geom) AS fraction
    FROM line, linemeasure
),

-- Do the interpolation
geometries AS (
    SELECT ST_LineInterpolatePoint(l.geom, lf.fraction) AS geom
    FROM linefraction lf, line l
),

-- Convert back to EPSG:4326 (i.e. lat/lon coords)
geometries_4326 AS (
    SELECT ST_Transform(geom, 4326) AS geom FROM geometries
)
SELECT * FROM geometries_4326

โปรดทราบว่าแบบสอบถามนี้ไม่คิดว่ามีเพียงหนึ่งแถวในline_sample_testตารางดังนั้นปรับแต่งตามความจำเป็นสำหรับข้อมูลอินพุตจริงของคุณ


ฉันไม่รู้ST_Buffer(geom, 0)เคล็ดลับในการกำจัดเส้นแบ่ง - นั่นมีประโยชน์!
Toby Speight
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.