কোন ওভারল্যাপ ছাড়াই ক্ষুদ্রতম (শিশু) বহুভুজ পেতে পিতা-মাতার বহুভুজ ছেদগুলিতে পুনরাবৃত্তভাবে কীভাবে লুপ করবেন?


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

এটা চেষ্টা কর:

এই লিঙ্কটি থেকে পোস্টজিআইএস অ্যাডনসগুলি ডাউনলোড করুন: 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

আমি আগে আপনার অ্যাডন গিট রেপো দেখেছি। অনুপ্রেরণাদি স্টাফ।
জন পাওয়েল

বাহ দুর্দান্ত সমাধান। আপনি এই অ্যাডনগুলি তৈরির জন্য খুব সুন্দর একটি কাজ করেছেন। আমি এই উত্তরটি দেওয়ার জন্য ক্লিক করার আগে, আমি কেবল একটি জিনিস যা আমাকে বাগিয়ে দিচ্ছে তা নিশ্চিত করার জন্য about আপনার প্রদত্ত কোডটি চালনা করে 'বহুভুজ 5' (প্রশ্নের দ্বিতীয় চিত্রের) মনে হয় না যে ওভারল্যাপটি অন্য বহুভুজ ('ct_overlap_cat2 = 1'; 'ct_overlap_cat2 = 0') এর সাথে ওভারল্যাপটি স্বীকৃতি দেয়। সুতরাং, এই বহুভুজটি 'cat3' এবং 'যোগ = 7' এর পরিবর্তে 'cat1' এবং 'যোগ = 2' হিসাবে শ্রেণিবদ্ধ হয়। আমি এই সামান্য সমস্যাটি ডিবাগ করতে কিছুটা সমস্যার মুখোমুখি। তুমি কি আমাকে সাহায্য করবে?
ম্যাট_জিও

1
এই সমাধানটির সাথে একমাত্র সমস্যা হ'ল কেস স্টেটমেন্টগুলি হার্ড কোডড। নীতিগতভাবে, এটি সম্ভবত একটি স্বেচ্ছাসেবী সংখ্যক বিভাগ পরিচালনা করতে সক্ষম হওয়া উচিত।
জন পাওয়েল

@ ম্যাট_জিও আমি ফলস্বরূপ সারণিতে poly টি বহুভুজ পাই। ত্রিভুজ বহুভুজটি তিন ভাগে বিভক্ত হয়ে যায়। সমষ্টি = ২, একটি যোগফল = and এবং আপনার ইচ্ছাকৃত চিত্র হিসাবে যোগফলের সাথে একটি = 8।
পিয়েরে র্যাসিন

1
আপনি যদি ST_Creroid (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 টি এন্ট্রি যা আপনার দেওয়া উদাহরণটিতে বিভিন্ন ছেদ বিকল্পগুলির সাথে সামঞ্জস্য করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.