माता-पिता बहुभुज चौराहों के माध्यम से पुनरावर्ती लूप कैसे प्राप्त करें बिना ओवरलैप के सबसे छोटे (बच्चे) बहुभुज प्राप्त करें?


11

मैं कुछ दिनों के लिए एक समस्या से जूझ रहा हूं और महसूस किया है कि जब पोस्टजीआईएस (v2.5) में विषय के चौराहों पर बहुत से लोग फंस जाते हैं। इसलिए मैंने अधिक विस्तृत और सामान्य, सामान्य प्रश्न पूछने का फैसला किया।

मेरे पास निम्न तालिका है:

DROP TABLE IF EXISTS tbl_foo;
CREATE TABLE tbl_foo (
    id bigint NOT NULL,
    geom public.geometry(MultiPolygon, 4326),
    att_category character varying(15),
    att_value integer
);
INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES 
    (1, ST_SetSRID('MULTIPOLYGON (((0 6, 0 12, 8 9, 0 6)))'::geometry,4326) , 'cat1', 2 );
INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES 
    (2, ST_SetSRID('MULTIPOLYGON (((5 0, 5 12, 9 12, 9 0, 5 0)))'::geometry,4326), 'cat1', 1 );
INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES 
    (3, ST_SetSRID('MULTIPOLYGON (((4 4, 3 8, 4 12, 7 14,10 12, 11 8, 10 4, 4 4)))'::geometry,4326) , 'cat2', 5 );

यह इस तरह दिख रहा है:

शुरू

मैं माता-पिता बहुभुज के प्रतिच्छेदन के आधार पर सभी बच्चे बहुभुज प्राप्त करना चाहता हूं। परिणाम के लिए, यह अपेक्षित होगा:

  • बच्चा उन दोनों के बीच कोई अतिच्छादन नहीं करता है।
  • एक कॉलम जिसमें उनके मूल बहुभुजों के मूल्य का योग होता है,
  • एक श्रेणी के मूल बहुभुजों की गिनती वाला एक स्तंभ
  • एक कॉलम जिसमें अन्य श्रेणी की गिनती होती है
  • निम्नलिखित नियम के आधार पर, बाल बहुभुज की श्रेणी वाला एक स्तंभ: -अगर सभी माता-पिता बहुभुज एक वर्ग से हैं, तो बाल बहुभुज में भी यह वर्ग होता है। एल्स, बाल बहुभुज की श्रेणी तीसरी श्रेणी है।

तो ऐसा लगेगा:

उत्पादन

तो, अंत में, उत्पादन उत्पन्न तालिका (इस उदाहरण के लिए) 7 पंक्तियाँ (सभी 7, गैर अतिव्यापी, बच्चे बहुभुज), के स्तंभों से युक्त होगा category, sum_value, ct_overlap_cat1,ct_overlap_cat2

निम्नलिखित कोड मैंने शुरू किया, मुझे व्यक्तिगत चौराहे देता है, एक माता-पिता की दूसरे के साथ तुलना करता है।

SELECT
(ST_Dump(
    ST_SymDifference(a.geom, b.geom) 
)).geom
FROM tbl_foo a, tbl_foo b
WHERE a.ID < b.ID AND ST_INTERSECTS(a.geom, b.geom)
UNION ALL
SELECT
ST_Intersection(a.geom, b.geom) as geom
FROM tbl_foo a, tbl_foo b
WHERE a.ID < b.ID AND ST_INTERSECTS(a.geom, b.geom);

इस उल्लिखित कोड के परिणाम के माध्यम से मैं कैसे पुनरावृत्ति कर सकता हूं, कि, ओवरलैप बहुभुजों की संख्या से स्वतंत्र मुझे हमेशा अपना 'सबसे छोटा' (बच्चा) बहुभुज (छवि 2) मिलता है।

जवाबों:


8

इसे इस्तेमाल करे:

इस लिंक से PostGIS Addons डाउनलोड करें: https://github.com/pedrogit/postgisaddons

ST_SplitAgg () फ़ंक्शन प्राप्त करने के लिए postgis_addons.sql फ़ाइल चलाकर इंस्टॉल करें।

Postgis_addons_test.sql फ़ाइल चलाकर परीक्षण करें।

यहाँ आपकी क्वेरी है:

WITH  result_table AS (
    WITH  parts AS (
      SELECT a.att_value val,
             CASE WHEN a.att_category = 'cat1' THEN 1 ELSE 0 END cat1,
             CASE WHEN a.att_category = 'cat2' THEN 1 ELSE 0 END cat2,
             unnest(ST_SplitAgg(a.geom, b.geom, 0.00001)) geom
      FROM tbl_foo a,
           tbl_foo b
      WHERE ST_Equals(a.geom, b.geom) OR
            ST_Contains(a.geom, b.geom) OR
            ST_Contains(b.geom, a.geom) OR
            ST_Overlaps(a.geom, b.geom)
      GROUP BY a.id, a.att_category , ST_AsEWKB(a.geom), val
    )
    SELECT CASE WHEN sum(cat2) = 0 THEN 'cat1'
                WHEN sum(cat1) = 0 THEN 'cat2'
                ELSE 'cat3'
           END category, 
           sum(val*1.0) sum_value, 
           sum(cat1) ct_overlap_cat1, 
           sum(cat2) ct_overlap_cat2, 
           ST_Union(geom) geom
    FROM parts
    GROUP BY ST_Area(geom)
)
SELECT category, sum_value, ct_overlap_cat1, ct_overlap_cat2,
(ST_Dump(result_table.geom)).geom as geom
FROM result_table

मैंने पहले भी आपके addons git रेपो को देखा है। इंस्पिरेशनल सामान।
जॉन पॉवेल

वाह बढ़िया उपाय। आपने इस ऐडोन को बनाने के लिए बहुत ही बढ़िया काम किया। इससे पहले कि मैं यह जवाब देने के लिए क्लिक करूं, मैं सिर्फ एक चीज के बारे में सुनिश्चित कर पाऊंगा जो मुझे परेशान कर रही है। आपके द्वारा प्रदत्त कोड को चलाने पर, 'बहुभुज 5' (प्रश्न का दूसरा आंकड़ा) किसी अन्य बहुभुज ('ct_overlap_cat2 = 1'; 'ct_overlap_cat2 = 0') के साथ ओवरलैप को पहचानता नहीं है। इसलिए, यह बहुभुज 'cat3' और 'sum = 7' के बजाय 'cat1' और 'sum = 2' के रूप में वर्गीकृत होता है। मुझे इस छोटे से मुद्दे पर बहस करने में थोड़ी कठिनाई हो रही है। क्या तुम मेरी मदद कर सकते हो?
मैट_जीओ

1
इस समाधान के साथ एकमात्र समस्या यह है कि केस स्टेटमेंट हार्ड कोडित हैं। सिद्धांत रूप में, यह संभवत: श्रेणियों की एक मनमानी को संभालने में सक्षम होना चाहिए।
जॉन पॉवेल

@Matt_Geo मुझे परिणामी तालिका में 6 बहुभुज मिलते हैं। त्रिभुज बहुभुज तीन में विभाजित हो जाते हैं। एक राशि = 2 के साथ, एक राशि के साथ = 7 और एक राशि के साथ = 8 अपनी इच्छा के अनुसार।
पियरे रेसीन

1
यदि आप ST_Centroid (geom) को ST_Area (geom) से बदल दें तो क्या होगा?
पियरे रासीन

1

मुझे लगता है कि यदि आप बहुभुज के बजाय बहुभुज ज्यामिति प्रकार का उपयोग करते हैं तो सब कुछ ठीक हो जाएगा:

DROP TABLE IF EXISTS tbl_foo;
CREATE TABLE tbl_foo (
    id bigint NOT NULL,
    geom public.geometry(Polygon, 4326),
    att_category character varying(15),
    att_value integer
);

INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES 
    (1, ST_SetSRID('POLYGON ((0 6, 0 12, 8 9, 0 6))'::geometry,4326) , 'cat1', 2 );
INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES 
    (2, ST_SetSRID('POLYGON ((5 0, 5 12, 9 12, 9 0, 5 0))'::geometry,4326), 'cat1', 1 );
INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES 
    (3, ST_SetSRID('POLYGON ((4 4, 3 8, 4 12, 7 14,10 12, 11 8, 10 4, 4 4))'::geometry,4326) , 'cat2', 5 );

परिणाम 9 प्रविष्टियां हैं जो आपके द्वारा दिए गए उदाहरण में विभिन्न चौराहे विकल्पों के अनुरूप हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.