การเติบโตรูปทรงเรขาคณิตของ PostGIS เป็นเปอร์เซ็นต์


10

ฉันกำลังมองหาวิธีเพิ่มบัฟเฟอร์รอบ ๆ เรขาคณิตของ PostGIS แต่ขนาดของบัฟเฟอร์ควรขึ้นอยู่กับขนาดของเรขาคณิต นั่นคือฉันต้องการให้แต่ละเรขาคณิตขยายใหญ่ขึ้นโดยพูดว่า 5%

แนวคิดคือฉันกำลังมองหารูปทรงเรขาคณิตที่ตัดกัน แต่อาจมีข้อผิดพลาดสูงถึง 5% ที่เกี่ยวข้องกับแต่ละรูปแบบที่ฉันต้องการนำมาพิจารณา

ใครรู้วิธีที่ดีที่สุดในการทำเช่นนี้?

ฐานข้อมูลมีจำนวนล้านแถวดังนั้นฉันต้องการให้มันเร็วพอสมควร


2
5% ของอะไร สมมติว่าคุณใช้รูปหลายเหลี่ยมมันคือ 5% ของความกว้างที่ยิ่งใหญ่ที่สุดความกว้างที่แคบที่สุดกล่องขอบเขตระยะทางของจุดยอดจากเซนทรอยด์ ... หากคุณกำลังพูดถึงจุดหรือเส้นแล้วมันก็ทำให้รู้สึกน้อยลง!
MerseyViking

ฉันเดาว่าระยะทางจุดยอด - เซนทรอยด์ - หรืออาจเพิ่มขึ้น 5% ในพื้นที่ก็จะโอเค การเพิ่มกล่องขอบให้ถูกต้องถ้าปรับขนาดเรขาคณิตแล้วเติมช่องว่างนั้น รูปทรงเรขาคณิตทั้งหมดเป็นรูปหลายเหลี่ยมปิด (ส่วนใหญ่เป็นรูปสี่เหลี่ยมจัตุรัส)
James Baker

คำตอบ:


8

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

นี่คือวิธีการให้เหตุผล:

  • เมื่อรูปร่างไม่ซับซ้อนเกินไป - โดยเฉพาะอย่างยิ่งถ้าเป็นรูปร่างนูน - การบัฟเฟอร์จะให้ผลลัพธ์เทียบเท่ากับการลดขนาดรูปร่างรอบจุดศูนย์กลาง (มันเป็นสิ่งสำคัญที่จะเข้าใจแม้ว่าการบัฟเฟอร์นั้นไม่เทียบเท่า rescaling สำหรับรูปร่างใด ๆ นอกเหนือจากดิสก์สำหรับรูปร่างเว้าบาง ๆ "บัฟเฟอร์" ที่คำนวณโดยใช้การปรับขนาดจริงอาจไม่รวมถึงส่วนของรูปร่างเดิมเองดังนั้นในที่สุด เราจะคำนวณบัฟเฟอร์ของรูปร่าง แต่จะใช้การประมาณความเท่ากันนี้เป็นฮิวริสติกในการประมาณจำนวนบัฟเฟอร์)

  • หากพื้นที่บัฟเฟอร์มากกว่า 5% ดังนั้นปริมาณการลดขนาดจึงควรเป็น sqrt (1 + 5/100) ซึ่งใกล้เคียงกับ 1.025: นั่นคือเราควรขยายรูปร่าง 2.5% ในทุกทิศทาง .

  • ถ้าเราคิดว่ารูปร่างมีเส้นผ่านศูนย์กลาง (เท่ากับระยะทางทั่วไป) รัศมีของมันจะเพิ่มขึ้น 2.5% นั่นเท่ากับ 2.5% / 2 = 1.25% ของเส้นผ่านศูนย์กลาง

  • เราสามารถประมาณเส้นผ่านศูนย์กลางทั่วไปจากกล่อง จำกัด รูปร่าง ใช้พูดความหมายด้านคณิตศาสตร์หรือเรขาคณิตของความยาวด้านข้างของกล่อง

สิ่งนี้แนะนำเวิร์กโฟลว์ต่อไปนี้:

  1. รับกล่องขอบเขตของรูปร่าง

  2. ให้eเป็นค่าเฉลี่ยของความยาวด้านข้างของกล่อง

  3. บัฟเฟอร์รูปร่าง 1.25% ของe ; นั่นคือโดย (5/100) / 4 * อีเมล

เนื่องจากขั้นตอนที่ 1 และ 2 จำเป็นต้องมีการคำนวณน้อยมากจึงเป็นวิธีแก้ปัญหาที่รวดเร็วที่สุด ในการตรวจสอบความถูกต้องคุณสามารถ (แน่นอน) คำนวณพื้นที่ของรูปร่างที่บัฟเฟอร์แล้วเปรียบเทียบกับพื้นที่เดิมเพื่อดูว่าพวกมันมาใกล้มากขึ้นถึง 5% ที่ต้องการหรือไม่ บางครั้งพื้นที่บัฟเฟอร์จะยิ่งใหญ่กว่า 5% แต่ควรหายากว่ามีพื้นที่น้อยกว่าและเป็นไปไม่ได้ที่พวกเขาจะชื่นชมน้อยลง

ตัวอย่าง

เป็นการตรวจสอบและภาพประกอบลองพิจารณารูปร่างที่เรียบง่าย

  1. ดิสก์รัศมีRมีกรอบกับด้านของความยาว 2 R สูตรของเราคำนวณE = (5/100) / 4 * 2 * R = R / 40 รูปร่างบัฟเฟอร์เห็นได้ชัดว่าเป็นศูนย์กลางของดิสก์รัศมีR + R / 40 = 1.025 R พื้นที่เก่าคือ pi * r ^ 2 ในขณะที่พื้นที่ใหม่คือ pi * (1.025 r ) ^ 2 = pi * 1.0506 * r ^ 2 ซึ่งมากกว่า 5.06%

  2. รูปสี่เหลี่ยมผืนผ้าที่มีด้านขนานกับแกนพิกัดของความยาวrและsให้e = ( r + s ) / 2 พื้นที่เพิ่มเติมจากการบัฟเฟอร์สี่เหลี่ยมผืนผ้ามาจากสี่เหลี่ยมมุมฉากสี่มุม (5/100) / 4 e = e / 80 = ( r + s ) / 160 ที่มีขอบด้านข้างบวกกับวงกลมสี่ส่วนสี่ของรัศมีe / 80 ที่มุม ละเลยวงกลมไตรมาสซึ่งจะมีขนาดเล็กเมื่อเทียบกับพื้นที่อื่น ๆ พื้นที่ใหม่ทั้งหมดเท่ากับ

    2 ( r + s ) * ( r + s ) / 160 = ( r ^ 2 + s ^ 2 + 2 r * s ) / 80

    เมื่อRและsไม่ได้แตกต่างกันเกินไปเราสามารถคิดR ^ 2 + s ^ 2 จะอยู่ที่ประมาณ 2 R * s การประมาณนี้ทำให้พื้นที่ใหม่ทั้งหมดเป็น 4 r * s / 80 = 5% ของพื้นที่ดั้งเดิมของr * sตามที่ตั้งใจไว้


4

คุณต้องการใช้การผสมผสานระหว่าง ST_Scale ( http://postgis.net/docs/ST_Scale.html ) และ ST_Translate ( http://postgis.net/docs/ST_Translate.html ) ฉันคิดว่า เรามีตัวอย่างนี้ใน PostGIS ในการดำเนินการและคล้ายกันในบทที่ 8 หากคุณไม่มีหนังสือคุณสามารถดาวน์โหลดรหัสสำหรับบทนั้นได้ที่นี่:

http://www.postgis.us/chapter_08

ตัวอย่างจากหนังสือดูตัวอย่าง 8.26:

    -- Listing 8.26 Combining Scale and Translation to maintain centroid
    SELECT xfactor, yfactor, 
       ST_Translate(ST_Scale(hex.the_geom, xfactor, yfactor), 
       ST_X(ST_Centroid(the_geom))*(1 - xfactor), 
       ST_Y(ST_Centroid(the_geom))*(1 - yfactor) ) As scaled_geometry
    FROM 
 ( SELECT ST_GeomFromText('POLYGON((0 0,64 64,64 128,0 192,-64 128,-64 64,0 0))') As the_geom)  As hex
    CROSS JOIN (SELECT x*0.5 As xfactor 
        FROM generate_series(1,4) As x) As xf
    CROSS JOIN (SELECT y*0.5 As yfactor
        FROM generate_series(1,4) As y) As yf;

โรงงาน ตอนนี้ดูเหมือนว่าจะมีST_Transscaleแต่อย่างใดฉันไม่สามารถคิดวิธีการทำงานที่ ...
n1000

0

มันช้าไปงานปาร์ตี้ แต่เมื่อเร็ว ๆ นี้ฉันได้พัฒนาฟังก์ชั่น PostGIS แบบกำหนดเองที่ทำสิ่งนี้และลดขนาดถ้าจำเป็น:

ST_Dilate

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