পোস্টজিআইএসে বহুভুজ বৈশিষ্ট্যের মধ্যে পার্থক্যটি দেখতে লাইনগুলি কীভাবে তৈরি করবেন?


15

আমি polygon_bকিছু বহুভুজ বৈশিষ্ট্য সহ একটি পোস্টজিআইএস টেবিল করেছি । এখানে একটি টেবিল polygon_aরয়েছে যাতে polygon_bসামান্য পরিবর্তন সহ একই বহুভুজ রয়েছে । বহুভুজ বৈশিষ্ট্যের মধ্যে পার্থক্যটি দেখতে এখন আমি লাইন তৈরি করতে চাই।

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

আমি মনে করি এটি ST_ExteriorRingএবং ST_Differenceকাজটি করবে তবে যেখানে ক্লজটি বেশ কঠিন বলে মনে হচ্ছে।

CREATE VIEW line_difference AS SELECT
row_number() over() AS gid,
g.geom::geometry(LineString, yourSRID) AS geom
FROM 
    (SELECT
    (ST_Dump(COALESCE(ST_Difference(ST_ExteriorRing(polygon_a.geom), ST_ExteriorRing(polygon_b.geom))))).geom AS geom
    FROM polygon_a, polygon_b
    WHERE 
    -- ?
    ) AS g;

আমাকে কি কেউ সাহায্য করতে পারবেন?

সম্পাদনা 1

'টিলার' পোস্ট হিসাবে আমি চেষ্টা করেছি ST_Overlaps(polygon_a.geom, polygon_b.geom) AND NOT ST_Touches(polygon_a.geom, polygon_b.geom)তবে ফলাফলটি আশানুরূপ হয়নি as

CREATE VIEW line_difference AS SELECT
row_number() over() AS gid,
g.geom::geometry(LineString, your_SRID) AS geom
FROM 
    (SELECT
    (ST_Dump(COALESCE(ST_Difference(ST_ExteriorRing(polygon_a.geom), ST_ExteriorRing(polygon_b.geom))))).geom AS geom
    FROM polygon_a, polygon_b
    WHERE 
    ST_Overlaps(polygon_a.geom, polygon_b.geom) AND NOT ST_Touches(polygon_a.geom, polygon_b.geom))
     AS g;

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

সম্পাদনা 2

workupload.com/file/J0WBvRBb (উদাহরণস্বরূপ ডেটাসেট)


আমি ST_Differences ব্যবহার করার আগে বহুভুজগুলিকে মাল্টিলিনে পরিণত করার চেষ্টা করেছি, তবে ফলাফল এখনও অদ্ভুত।

CREATE VIEW multiline_a AS SELECT
row_number() over() as gid,
ST_Union(ST_ExteriorRIng(polygon_a.geom))::geometry(multilinestring, 4326) AS geom
FROM
polygon_a;

CREATE VIEW multiline_b AS SELECT
row_number() over() as gid,
ST_Union(ST_ExteriorRIng(polygon_b.geom))::geometry(multilinestring, 4326) AS geom
FROM
polygon_b;

CREATE VIEW line_difference AS SELECT
row_number() over() as gid,
g.geom
FROM
    (SELECT
    (ST_Dump(COALESCE(ST_Difference(multiline_a.geom, multiline_b.geom)))).geom::geometry(linestring, 4326) AS geom
    FROM
    multiline_a, multiline_b)
As g;

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


টপোলজি প্রশ্নের মতো দেখতে আরও বেশি লাগে। আপনি বিভাগগুলি সনাক্ত করতে চান যা অন্যান্য স্তর দ্বারা আচ্ছাদিত নয়। আমি পোস্টজিআইএস টপোলজির সাথে খুব বেশি কাজ করি নি এবং আপনাকে সরাসরি উত্তর দিতে পারি না তবে আমি আপনাকে আরও এদিকে নজর দেওয়ার পরামর্শ দিচ্ছি।
থমাস

আকর্ষণীয়, আপনার কাছে ডাউনলোডের জন্য ডেটাसेट রয়েছে?
হাকফিন

উত্তর:


10

এখানে কয়েকটি নতুন কৌশল ব্যবহার করা হচ্ছে:

  • EXCEPTউভয়টি সারণী থেকে একই রকমের জ্যামিতিগুলি সরাতে যাতে আমরা প্রতিটি টেবিলে ( A_onlyএবং B_only) স্বতন্ত্র জ্যামিতিগুলিতে কেবল মনোনিবেশ করতে পারি ।
  • ST_Snap ওভারলে অপারেটরদের জন্য সঠিক নোডিং পেতে।
  • পার্থক্যগুলি দেখানোর জন্য দুটি জ্যামিতি সেটগুলির মধ্যে প্রতিসারণের পার্থক্যST_SymDifference খুঁজে পেতে ওভারলে অপারেটরটি ব্যবহার করুন । আপডেট : এই উদাহরণের জন্য একই ফলাফল দেখায়। তারা কী পায় তা দেখতে আপনি কোনও ফাংশন চেষ্টা করতে পারেন।ST_Difference

এটি আপনার প্রত্যাশা অনুযায়ী পাওয়া উচিত:

-- CREATE OR REPLACE VIEW polygon_SymDifference AS
SELECT row_number() OVER () rn, *
FROM (
  SELECT (ST_Dump(ST_SymDifference(ST_Snap(A, B, tol), ST_Snap(B, A, tol)))).*
  FROM (
    SELECT ST_Union(DISTINCT A_only.geom) A, ST_Union(DISTINCT B_only.geom) B, 1e-5 tol
    FROM (
      SELECT ST_Boundary(geom) geom FROM polygon_a
      EXCEPT SELECT ST_Boundary(geom) geom FROM polygon_b
    ) A_only,
    (
      SELECT ST_Boundary(geom) geom FROM polygon_b
      EXCEPT SELECT ST_Boundary(geom) geom FROM polygon_a
    ) B_only
  ) s
) s;

 rn |                                        geom
----+-------------------------------------------------------------------------------------
  1 | LINESTRING(206.234028204842 -92.0360704110685,219.846021625456 -92.5340701703592)
  2 | LINESTRING(18.556700448873 -36.4496098325257,44.44438533894 -40.5104231486146)
  3 | LINESTRING(-131.974995802602 -38.6145334122719,-114.067738329597 -39.0215165366584)
(3 rows)

তিন লাইন


এই উত্তরটি আরও কিছুটা আনপ্যাক করার জন্য, প্রথম ধাপটি ST_Boundaryকেবল বহির্মুখী নয়, প্রতিটি বহুভুজের সীমানা পায়। উদাহরণস্বরূপ, যদি গর্ত থাকে তবে এগুলি সীমানা দ্বারা চিহ্নিত করা হত।

EXCEPTদফা A থেকে জ্যামিতি যে বি অংশ মুছে ফেলার জন্য ব্যবহার করা হয়, এবং B থেকে সারি যে উ অংশ এই সারি যে শুধুমাত্র একটি অংশ সংখ্যা, এবং B শুধুমাত্র অংশ হ্রাস করা হয়। উদাহরণস্বরূপ, A_only পেতে:

SELECT ST_Boundary(geom) geom FROM polygon_a
EXCEPT SELECT ST_Boundary(geom) geom FROM polygon_b

এখানে A_only এর 6 টি সারি এবং B_only এর 3 সারি রয়েছে: A_only B_only

এর পরে, ST_Union(DISTINCT A_only.geom)একক জ্যামিতিতে লাইনওয়ার্ক একত্রিত করতে ব্যবহৃত হয়, সাধারণত একটি মাল্টিলাইনস্ট্রিং।

এক জ্যামিতি থেকে অন্য জ্যামিতি নোড স্ন্যাপ করতে ST_Snap ব্যবহার করা হয়। উদাহরণস্বরূপ ST_Snap(A, B, tol), এ জ্যামিতিটি নেবে, এবং বি জ্যামিতি থেকে আরও নোড যুক্ত করবে বা তাদের বি জ্যামিতিতে স্থানান্তরিত করবে, যদি তারা tolদূরত্বে থাকে। এই ফাংশনগুলি ব্যবহার করার জন্য সম্ভবত বেশ কয়েকটি উপায় রয়েছে তবে ধারণাটি হ'ল প্রতিটি জ্যামিতি থেকে একে অপরের সাথে যথাযথ স্থানাঙ্কগুলি পান। সুতরাং বিস্ফোরণের পরে দুটি জ্যামিতি এর মতো দেখতে:

ছিটকে গেল বি ছিটকে গেল

এবং পার্থক্য দেখানোর জন্য, আপনি হয় ST_SymDifferenceবা ব্যবহার করতে বেছে নিতে পারেন ST_Difference। তারা উভয়ই এই উদাহরণের জন্য একই ফলাফল দেখায়।


চমৎকার উত্তর. আমি আপনার মধ্যস্থতাকারী প্রশ্নের ফলাফলগুলি ভিজ্যুয়ালাইজ করতে কী ব্যবহার করেছি তা অবাক করেছিলাম। এটি তাত্ক্ষণিকভাবে কুইগিসের মতো লাগেনি, এবং আমি সম্ভবত এটি এমন কিছু যা সামান্য দ্রুত সরবরাহ করে?
রোপারম্যাপস

1
জ্যামিতিগুলি দেখতে এবং প্রক্রিয়া করার জন্য আমি জেটিএস টেস্টবিল্ডার ব্যবহার করি। এটি জিওওএস এবং শেপিলির সম্পর্কিত জ্যামিতি ইঞ্জিন, তবে একটি জাভা ভিত্তিক জিইউআই রয়েছে।
মাইক টি

'লাইনরেস্টিং' এর মধ্যে নন-নোড মোড়কে উপেক্ষা / এড়িয়ে যাওয়ার কোনও উপায় আছে কি? সমস্ত ইনপুট বহুভুজগুলি ঠিক আছে (কিউজিআইএস জ্যামিতি পরীক্ষকের সাথে পরীক্ষিত)।
eclipsed_by_the_moon

1
'ST_Boundary (geom, 0.001)' 'ST_Boundary (geom)' এর পরিবর্তে সমস্যা সমাধান করে।
eclipsed_by_the_moon

6

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

নোড বহুভুজ A

বহু ক

"বিভিন্ন" বিভাগের বহুভুজ বি এর নোড

সেগ ডিফ

দুর্ভাগ্যক্রমে এটি কেবলমাত্র বিভাগের কাঠামোর মধ্যে পার্থক্য দেখায়, তবে আমি আশা করি এটি একটি প্রাথমিক পয়েন্ট এবং এটি এর মতো কাজ করে:

ডাউনলোড এবং আনজিপ প্রক্রিয়া শেষে আমি কমান্ডগুলি সহ ডেবিয়ান লিনাক্স জেসির অধীনে পোস্টগ্রিএসএসকিউএল 9.46, পোস্টজিআইএস ২.১ ব্যবহার করে ডেটা সেট আমদানি করেছি।

$ createdb gis-se
$ psql gis-se < /usr/share/postgis-2.1/postgis.sql
$ psql gis-se < /usr/share/postgis-2.1/spatial_ref_sys.sql
$ shp2pgsql -S polygon_a | psql gis-se
$ shp2pgsql -S polygon_b | psql gis-se

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

এই সংশ্লিষ্ট জিআইএস-দঃপূঃ পোস্টে , আমি সেগমেন্ট টেবিল মধ্যে উভয় বহুভুজ পচা segments_aএবংsegments_b

-- Segments of the polygon A
CREATE VIEW segments_a AS SELECT sp, ep
FROM
   -- extract the endpoints for every 2-point line segment for each linestring
   (SELECT
      ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
      ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) as ep
    FROM
    -- extract the individual linestrings
     (SELECT (ST_Dump(ST_Boundary(geom))).geom
      FROM polygon_a
     ) AS linestrings
    -- be sure that nothing is scrambled
    ORDER BY sp, ep
) AS segments;

সেগমেন্ট টেবিল বহুভুজ A:

SELECT 
  st_astext(sp) AS sp, 
  st_astext(ep) AS ep 
FROM segments_a 
LIMIT 3;
                    sp                     |                 ep
-------------------------------------------+--------------------------------------------
POINT(-292.268907321861 95.0342877387557)  | POINT(-287.118411917425 99.4165242769195)
POINT(-287.118411917425 99.4165242769195)  | POINT(-264.62129248575 93.2470010145007)
POINT(-277.459563916327 -44.5629543976138) | POINT(-292.268907321861 95.03428773875

একই পদ্ধতি বহুভুজ বিতে প্রয়োগ করা হয়েছিল to

-- Segments of the polygon B
CREATE VIEW segments_b AS SELECT sp, ep
FROM
   -- extract the endpoints for every 2-point line segment for each linestring
   (SELECT
      ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
      ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) as ep
    FROM
    -- extract the individual linestrings
     (SELECT (ST_Dump(ST_Boundary(geom))).geom
      FROM polygon_b
     ) AS linestrings
    -- be sure that nothing is scrambled
    ORDER BY sp, ep
) AS segments;

সেগমেন্ট টেবিল বহুভুজ বি

SELECT
  st_astext(sp) AS sp, 
  st_astext(ep) AS ep 
FROM segments_b 
LIMIT 3;
                    sp                     |                    ep
-------------------------------------------+-------------------------------------------
POINT(-292.268907321861 95.0342877387557)  | POINT(-287.118411917425 99.4165242769195)
POINT(-287.118411917425 99.4165242769195)  | POINT(-264.62129248575 93.2470010145007)
POINT(-277.459563916327 -44.5629543976138) | POINT(-292.268907321861 95.0342877387557)
...                        

আমি নামের একটি পার্থক্য টেবিল ভিউ তৈরি করতে পারি segments_diff_{a,b}। পার্থক্যটি সেগমেন্ট সেট এ এবং বিতে বাছাই করা শুরু বা শেষ পয়েন্টগুলির অজানা দ্বারা দেওয়া হয়েছে A

CREATE VIEW segments_diff_a AS
SELECT st_makeline(b.sp, b.ep) as geom
FROM segments_b as b
LEFT JOIN segments_a as a ON (a.sp=b.sp and a.ep = b.ep)
-- filter segments without corresponding stuff in polygon A
WHERE a.sp IS NULL;

segs ভিন্ন হয় খ

এবং পরিপূরক স্টাফ:

CREATE VIEW segments_diff_b AS
SELECT st_makeline(a.sp, a.ep) as geom
FROM segments_a as a
LEFT JOIN segments_b as b ON (a.sp=b.sp and a.ep = b.ep)
-- filter segments without corresponding stuff in polygon B
WHERE b.sp IS NULL;

segs পৃথক a

উপসংহার: লাল তীরের সাহায্যে চিহ্নিত ছোট্ট ছোট্ট অংশগুলির জন্য উপযুক্ত ফলাফল পেতে, উভয় বহুভুজের নোড স্ট্রাকচারের সমান এবং নোড স্তরের একটি ছেদ পদক্ষেপ থাকতে হবে (বি-তে বহুভুজ A এর শীর্ষবৃত্ত সন্নিবেশ করানো) প্রয়োজনীয়। ছেদটি দ্বারা করা যেতে পারে:

CREATE VIEW segments_bi AS 
SELECT distinct sp, ep
FROM (
 SELECT
      ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
      ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) as ep
 FROM (
   SELECT st_difference(b.seg, a.seg) as geom FROM 
      segments_diff_a as a, segments_diff_b as b 
      WHERE st_intersects(a.seg, b.seg)
    ) as cut
  ) as segments
  WHERE sp IS NOT NULL AND ep IS NOT NULL
ORDER BY sp, ep;

তবে অদ্ভুত ফলাফল সহ ...

সংস্করণ কাটা


আপনার প্রচেষ্টার জন্য ধন্যবাদ। ঠিক আছে, ফলাফল অদ্ভুত। আমি কেবল আশ্চর্যই হই যে এস এস হাউসডর্ফডিলেন্স () যদি প্রশ্নের উত্তর দিতে সহায়তা করতে পারে: gis.stackexchange.com/questions/180593/…
চন্দ্র সমুদ্র

এইচ, st_haudorffdistance আপনাকে একটি অনুরূপতার পরিমাপ দেয় যা চেয়েছিল অংশগুলিতে নয় (লাল তীরটি নির্দেশ করছে)।
হাকফিন

এটি কেবল একটি ধারণা, উভয় টেবিলের জ্যামিতির তুলনা করতে ST_HausdorffDistance ব্যবহার করা যেতে পারে। বহুভুজগুলি স্থানিকভাবে সমান না হলেও আমি লাইন তৈরি করেছি to আমি শুধু এটি কিভাবে জানি না।
চন্দ্র সমুদ্র

এটি যথাযথতা এবং টপোলজির বিষয় বলে মনে হচ্ছে ( gis.stackexchange.com/a/182838/26213 এবং webhelp.esri.com/arcgisdesktop/9.2/… )
হাকফিন

1

উদাহরণটি দেখলে, পরিবর্তনটি বোঝায় যে নতুন সারণীর বৈশিষ্ট্যগুলি পরিবর্তিত হয়েছে সেগুলি পুরানো সারণির বৈশিষ্ট্যগুলি সর্বদা ওভারল্যাপিং হবে। সুতরাং আপনার সাথে সম্পন্ন করা হবে

ST_ ওভারল্যাপস (জিওমা, জিওম্ব) এবং! এস 07 টিউচস (জিওমা, জিওম্ব)

স্পর্শগুলিতে অবহেলা হ'ল কারণ কেবল যদি তাদের সীমানা একই উল্লম্ব অবস্থানগুলি ভাগ করে তবে বৈশিষ্ট্যগুলি ওভারল্যাপ হয়।

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