যে কোনও এবং সমস্ত সংলগ্ন বহুভুজ একত্রিত করুন


22

আমি পার্সেল (বহুভুজ) স্তরে সংলগ্ন পরীক্ষা করতে চাই এবং যদি তারা নির্দিষ্ট মানদণ্ডে (আকার হতে পারে) ফিট করে তবে সেগুলিকে একীভূত করতে চাই। নীচের ছবি অনুসারে, আমি বহুভুজ 1,2,3 এবং 4 একত্রিত করতে চাই, তবে 5 নয়

আমার দুটি সমস্যা আছে:

  1. ST_TOUCHESসত্য যদি সত্যায়িত হয় যদি কেবল কোণগুলি স্পর্শ করে এবং একটি রেখাংশ নেই। আমি মনে করি ভাগ করা লাইন বিভাগগুলি পরীক্ষা করার জন্য আমার ST_RELATE প্রয়োজন।
  2. আদর্শভাবে, আমি সমস্ত সংলগ্ন বহুভুজকে একের সাথে একীভূত করতে চাই, তবে আমি নিশ্চিত না যে কীভাবে দুটি ছাড়িয়ে স্কেল করা যায় - হিসাবে, 1,2,3 এবং 4 (এবং সম্ভবত প্রকৃত তথ্যের উপর আরও বেশি) এক রাউন্ডে মার্জ করুন।

আমার এখন যে কাঠামো রয়েছে তা স্ব-যোগদানের উপর ভিত্তি করে ST_TOUCHES

এখানে চিত্র বর্ণনা লিখুন

খেলনা তথ্য

CREATE TABLE testpoly AS 
SELECT 
1 AS id, ST_PolyFromText('POLYGON ((0 0, 10 0, 10 20, 00 20, 0 0 ))') AS geom UNION SELECT
2 AS id, ST_PolyFromText('POLYGON ((10 0, 20 0, 20 20, 10 20, 10 0 ))') AS geom UNION SELECT
3 AS id, ST_PolyFromText('POLYGON ((10 -20, 20 -20, 20 0, 10 0, 10 -20 ))') AS geom UNION SELECT
4 AS id, ST_PolyFromText('POLYGON ((20 -20, 30 -20, 30 0, 20 0, 20 -20 ))') AS geom  UNION SELECT 
5 AS id, ST_PolyFromText('POLYGON ((30 0, 40 0, 40 20, 30 20, 30 0 ))') AS geom ;

নির্বাচন

SELECT 
    gid, adj_gid,
    st_AStext(st_union(l2.g1,l2.g2)) AS geo_combo
from (
    --level 2
    SELECT
      t1.id AS gid,
      t1.geom AS g1,
      t2.id AS adj_gid,
      t2.geom AS g2
     from
      testpoly  t1,
      testpoly  t2
     where
      ST_Touches( t1.geom, t2.geom ) 
      AND t1.geom && t2.geom 
) 
l2

এখানে ফলাফল:

+-----+---------+-------------------------------------------------------------------------------+
| gid | adj_gid | geo_combo                                                                     |
+-----+---------+-------------------------------------------------------------------------------+
| 1   | 2       | POLYGON((10 0,0 0,0 20,10 20,20 20,20 0,10 0))                                |
+-----+---------+-------------------------------------------------------------------------------+
| 1   | 3       | MULTIPOLYGON(((10 0,0 0,0 20,10 20,10 0)),((10 0,20 0,20 -20,10 -20,10 0)))   |
+-----+---------+-------------------------------------------------------------------------------+
| 2   | 1       | POLYGON((10 20,20 20,20 0,10 0,0 0,0 20,10 20))                               |
+-----+---------+-------------------------------------------------------------------------------+
| 2   | 3       | POLYGON((10 0,10 20,20 20,20 0,20 -20,10 -20,10 0))                           |
+-----+---------+-------------------------------------------------------------------------------+
| 2   | 4       | MULTIPOLYGON(((20 0,10 0,10 20,20 20,20 0)),((20 0,30 0,30 -20,20 -20,20 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 3   | 1       | MULTIPOLYGON(((10 0,20 0,20 -20,10 -20,10 0)),((10 0,0 0,0 20,10 20,10 0)))   |
+-----+---------+-------------------------------------------------------------------------------+
| 3   | 2       | POLYGON((20 0,20 -20,10 -20,10 0,10 20,20 20,20 0))                           |
+-----+---------+-------------------------------------------------------------------------------+
| 3   | 4       | POLYGON((20 -20,10 -20,10 0,20 0,30 0,30 -20,20 -20))                         |
+-----+---------+-------------------------------------------------------------------------------+
| 4   | 2       | MULTIPOLYGON(((20 0,30 0,30 -20,20 -20,20 0)),((20 0,10 0,10 20,20 20,20 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 4   | 3       | POLYGON((20 0,30 0,30 -20,20 -20,10 -20,10 0,20 0))                           |
+-----+---------+-------------------------------------------------------------------------------+
| 4   | 5       | MULTIPOLYGON(((30 0,30 -20,20 -20,20 0,30 0)),((30 0,30 20,40 20,40 0,30 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 5   | 4       | MULTIPOLYGON(((30 0,30 20,40 20,40 0,30 0)),((30 0,30 -20,20 -20,20 0,30 0))) |
+-----+---------+-------------------------------------------------------------------------------+

নোট করুন যে বহুভুজ আইডি = 3 আইডি = 1 এর সাথে একটি পয়েন্ট ভাগ করে এবং তাই ইতিবাচক ফলাফল হিসাবে ফিরে আসে। আমি যদি WHERE ধারাটি পরিবর্তন করি তবে আমি ST_Touches( t1.geom, t2.geom ) AND t1.geom && t2.geom AND ST_Relate(t1.geom, t2.geom ,'T*T***T**');কোনও রেকর্ড পাই না।

  1. সুতরাং প্রথমে , আমি কীভাবে ST_ সম্পর্কিত উল্লেখ করব তা নিশ্চিত করার জন্য যে কোনও লাইন বিভাগ ভাগ করে নেওয়া কেবল পার্সেল বিবেচনা করা হবে।

  2. এবং তারপরে, আমি কীভাবে উপরের কল থেকে ফলাফলগুলি ভেঙে এক রাউন্ডে 1,2,3,4 বহুভুজগুলি একীভূত করব, যখনই 1 থেকে 2 সংলগ্নতা বিপরীত হিসাবে স্বীকৃত হবে?

হালনাগাদ

যদি আমি এই whereশৃঙ্খলে যুক্ত করি তবে আমি কেবল বহুভুজ পেয়েছি এবং মাল্টিপলিজাগন না পেয়ে এইভাবে আমার উদ্দেশ্যে মিথ্যা ধনাত্মকতা ছড়িয়ে দিচ্ছি - কোণার স্পর্শগুলি উপেক্ষা করা হবে।

GeometryType(st_union(t1.geom,t2.geom)) != 'MULTIPOLYGON'

যদিও এটি আদর্শ নয় (আমি বরং টপোলজি চেকগুলি ST_RELATEআরও সাধারণ সমাধান হিসাবে ব্যবহার করব ), এটি এগিয়ে যাওয়ার এক উপায়। তারপরে এগুলি ডি-ডুপিং এবং ইউনিয়ন করার বিষয়টি রয়ে গেছে। সম্ভবত, যদি আমি কেবল বহুভুজ স্পর্শের জন্য একটি ক্রম উত্পন্ন করতে পারি তবে আমি এটিতে মিলিত হতে পারি।

আপডেট দ্বিতীয়

এইটি বহুভুজ ভাগ করে নেওয়ার লাইনগুলি নির্বাচনের জন্য কাজ করছে বলে মনে হচ্ছে (তবে কোণ নয়) এবং এটি উপরের MULTIPOLYGONপরীক্ষার চেয়ে আরও সাধারণ সমাধান । আমার যেখানে এখন ধারাটি দেখতে এটির মতো দেখাচ্ছে:

WHERE
              ST_Touches( t1.geom, t2.geom ) 
              AND t1.geom && t2.geom 

              -- 'overlap' relation
              AND ST_Relate(t1.geom, t2.geom)='FF2F11212') t2 

এখন যা অবশিষ্ট রয়েছে তা কেবল একজোড়া বহুভুজের চেয়ে বেশি কীভাবে একীভূত করা যায় তা নয়, তবে একসাথে মানদণ্ডের সাথে মানিয়ে নেওয়া একটি স্বেচ্ছাসেবী সংখ্যার জন্য।


2
আমি নিশ্চিত এস এস রিলেট সঠিক উপায়। আমি একক পয়েন্ট ছেদগুলি বাদ দেওয়ার জন্য ছেদগুলির দৈর্ঘ্য শূন্যের চেয়ে বেশি ছিল কিনা তা পরীক্ষা করে একই সমস্যা সমাধান করেছি। একটি হ্যাক, কিন্তু কাজ করে।
জন পাওয়েল

যদি গ্রুপ একটি উপায় ছিল একসঙ্গে অ্যারে মধ্যে সংলগ্ন বহুভুজ তারপর আপনি পরিবর্তন করতে পারে ST_IntersectionArray: [ফাংশন] [1] ST_Union [1] এর সাথে কাজ করা gis.stackexchange.com/a/60295/36886
রাফায়েল

2
একত্রে বহুভুজ একসাথে গ্রুপিংয়ের বিষয়ে, আপনি স্থানের পরিবর্তে সংলগ্নতার জন্য পরীক্ষার জন্য এখানে নীচের অংশের ক্লাস্টারিং অ্যালগরিদমটি পরিবর্তন করতে পারেন ( gis.stackexchange.com/a/115715/36886 ) এবং ফলস্বরূপ ক্লাস্টার_আইডিগুলিতে গ্রুপিংয়ের সময় ST_Union ব্যবহার করুন
রাফেল

3
এছাড়াও রয়েছে ST_ClusterIntersectimg যা আপনার প্রয়োজন অনুযায়ী করতে পারে। আপনার পোস্টগ্রিস ২.২ প্রয়োজন
জন পাওয়েল

উত্তর:


3

আমি এই ভেবে সাহায্য করতে পারি না যে আপনার উদাহরণটি আসলে একজন রাস্টার এবং আপনি উল্লেখ করেছেন যে আপনি "নির্দিষ্ট মানদণ্ডের (আকার হতে পারে)" এর ভিত্তিতে মার্জ করতে চান তবে আমি এটিকে রাস্টার রূপান্তর সহ একটি শট দিতে চাই।

আপনার নির্দিষ্ট উদাহরণের জন্য এটি কাজ করবে:

WITH rast AS (
  SELECT 
  ST_UNION(ST_AsRaster(geom,10, 20, '2BUI')) r
  FROM testpoly 
)
,p AS (
    SELECT (ST_DumpAsPolygons(r)).geom FROM rast
)
SELECT t.id,p.* 
FROM p
LEFT JOIN testpoly  t ON ST_Equals(p.geom, t.geom)

যা ঘটে তা হ'ল যেহেতু আপনার বহুভুজগুলি নিখুঁতভাবে সাজানো ঘর রয়েছে তাই তারা দুর্দান্তভাবে একটি রেস্টার (10x20 সেলসাইজ) এ রূপান্তর করবে। ডাম্পস্পলিগনস আপনাকে সমস্ত সংলগ্ন কোষগুলিকে একটিতে মার্জ করে এবং মূল বহুভুজগুলির সাথে তুলনা করে আপনাকে এমনকি মার্জ না করা পলিগুলির জন্য আইডি ফিরে পেতে সক্ষম করতে সহায়তা করবে।

এটি ব্যাখ্যা করে, আমি খুব কৌতূহলী যে এটি কীভাবে স্কেল হবে এবং আপনার ডেটাসেটটি কত বড়: ডি


চতুর ধারণা। এটি খেলনার উদাহরণ, যদিও - আমার আসল তথ্যটি একটি পার্সেল স্তর যা রাস্টারদের কাছে খুব সুন্দরভাবে মানচিত্র তৈরি করবে না।
ako

3

হুডের নীচে একাধিক পাস সহ পদ্ধতিগত স্টাইলে এটি কীভাবে করা যায় তার একটি উদাহরণ এখানে।

CREATE TABLE joined_testpoly AS SELECT array[id] ids, geom FROM testpoly; 

আপনার আরও কলামগুলি বহন করতে সক্ষম হবে এবং LIMIT 1নীচের নির্বাচিতগুলি কীভাবে কাজ করে তা সংশোধন করে যোগদানের জন্য অতিরিক্ত মানদণ্ড প্রয়োগ করতে হবে:

CREATE OR REPLACE FUNCTION reduce_joined_testpoly()
RETURNS void
AS $$
DECLARE
  joined_row joined_testpoly%ROWTYPE;
BEGIN
  LOOP
     SELECT array_cat(a.ids, b.ids), st_union(a.geom, b.geom)
         INTO joined_row 
     FROM joined_testpoly a INNER JOIN joined_testpoly b
           on a.ids != b.ids
              and ST_Touches(a.geom, b.geom) and a.geom && b.geom 
              and ST_Relate(a.geom, b.geom)='FF2F11212'
         LIMIT 1;
     IF NOT FOUND THEN
           EXIT;
     END IF;
     INSERT INTO joined_testpoly VALUES (joined_row.ids, joined_row.geom);
     DELETE FROM joined_testpoly
         WHERE joined_testpoly.ids <@ joined_row.ids 
           AND joined_testpoly.ids != joined_row.ids;
  END LOOP;
  RETURN;
END;
$$ LANGUAGE plpgsql;

জিনিস চালান:

SELECT reduce_joined_testpoly();

যথাযথ ইউনিয়ন, কোনও গুণকোষ নেই:

SELECT ids, st_geometrytype(geom), st_area(geom), st_numgeometries(geom) 
FROM joined_testpoly;
    ids    | st_geometrytype | st_area | st_numgeometries 
-----------+-----------------+---------+------------------
 {5}       | ST_Polygon      |     200 |                1
 {1,2,3,4} | ST_Polygon      |     800 |                1

2

এখানে রেফারেন্সের জন্য আরেকটি (কাজ করছে না) কৌশল রয়েছে (যে আমি একক স্পর্শীকরণের বিষয়টিকে বাদ দিতে পারি না)। এটি আমার অন্যান্য উত্তরের চেয়ে দ্রুত হওয়া উচিত কারণ এটি কেবল 'একটি পাস' নেয়।

SELECT st_numgeometries(g), (SELECT st_union(x.geom) FROM st_dump(g) x GROUP BY g)
FROM (
    SELECT unnest(st_clusterintersecting(geom)) g, id < 100 as other_arbitrary_grouping 
    FROM testpoly
    GROUP BY other_arbitrary_grouping) c;

(যদি কেউ নিজের গ্রুপে আইডি = 5 জ্যামিতি পেতে পারেন তবে অন্য উত্তর সংশোধন করতে এবং পোস্ট করতে নির্দ্বিধায়)

st_containsএইডস ইত্যাদির তালিকা ফিরে পেতে আপনার নীচের উত্তরে বিস্তারিত হিসাবে টেস্টপলির টেবিলে পুনরায় যোগদান করতে হবে : /programming//a/37486732/6691 তবে আমি এটি কাজ করতে পারি না বহুবিধ কারণে কিছু কারণে।


2

আপনার মূল ক্যোয়ারীটি কিছুটা সামঞ্জস্য করে এটিতে এখানে একটি দ্রুত ছুরিকাঘাত:

with gr as (SELECT 
    gid, adj_gid,
    st_AStext(st_union(l2.g1,l2.g2)) AS geo_combo
from (
    --level 2
    SELECT
      t1.id AS gid,
      t1.geom AS g1,
      t2.id AS adj_gid,
      t2.geom AS g2
     from
      testpoly  t1,
      testpoly  t2
     where
      ST_Touches( t1.geom, t2.geom ) 
      AND ST_Relate(t1.geom,t2.geom, '****1****')
      AND t1.geom && t2.geom 
) 
l2) select ST_AsText(st_union(gr.geo_combo)) from gr;

তথ্যসূত্র: https://postgis.net/docs/used_postgis_dbmanagement.html#DE-9IM

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