ওভারল্যাপিং বৈশিষ্ট্যগুলি সরাতে ST_Differences ব্যবহার করছেন?


11

আমি বহুগুণের একটি সেট (প্রসেসিং.ট্রিমেডপ্যারসেলনিউ) তৈরি করার জন্য এসT_ ডিফারেন্সটি ব্যবহার করার চেষ্টা করছি যা পোস্টগিস ২.১ (এবং পোস্টগ্রিস এসকিউএল ৯.৩) ব্যবহার করে বহুভুজ (টেস্ট.সেসেল_জমেট্রি_1) এর অন্য সেট দ্বারা আচ্ছাদিত কোনও অঞ্চল ধারণ করে না। এখানে আমার জিজ্ঞাসা:

CREATE TABLE processing.trimmedparcelsnew AS
SELECT
    orig.id, ST_Difference(orig.geom, cont.geom) AS difference
FROM 
    test.single_geometry_1 cont,
    test.multi_geometry_1 orig;

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

আমি ফলাফলের একটি ছবি সংযুক্ত করেছি

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


মন্তব্যের পরে, আমি যেখানে একটি ক্লজ যুক্ত করার চেষ্টা করেছি। আমি যে পার্সেলগুলির কোনও ছেদ নেই সেগুলি এবং অন্যান্য পার্সেলগুলির ছেদ করার অঞ্চলগুলি চাই (স্তর পরীক্ষা.সেসেল_জমেট্রি আমার পার্সেলগুলি থেকে অপসারণ করতে চাই দূষিত প্রতিনিধিত্ব করে) want আমি একটি ছেদ করার চেষ্টা করেছি তবে অবশ্যই আমি প্রকৃতপক্ষে নন ছেদগুলি চাই তাই এখন আমি বিচ্ছিন্নতার চেষ্টা করছি। আমি আমার টেবিলেও উত্স যোগ করার চেষ্টা করেছি তবে এসT_Differences ( http://postgis.net/docs/ST_Differences.html ) এর জন্য ডকুমেন্টেশন বলে যে এটি আমার সঠিক জ্যামিতিটি ফিরিয়ে দেয় (জ্যামিতি যে জ্যামিতি A এর সেই অংশকে উপস্থাপন করে যে জ্যামিতি বি দিয়ে ছেদ করে না), তাই আমি কেন আমার টেবিলে আসল বহুভুজটি চাইব তা নিয়ে আমি বিভ্রান্ত। যাইহোক, এখানে আমার সংশোধিত কোড:

CREATE TABLE processing.trimmedparcelsnew AS
SELECT
    orig.id, ST_Difference(orig.geom, cont.geom) AS difference, orig.geom AS geom
FROM 
    test.single_geometry_1 cont,
    test.multi_geometry_1 orig
WHERE ST_Disjoint(orig.geom, cont.geom);

ডাবস্টনের উত্তর অনুসরণ করে আমি এখন চেষ্টা করেছি:

CREATE TABLE processing.parcels_trimmed AS
SELECT id, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom) 
                                         FROM test.single_geometry_1 b
                                         WHERE ST_Intersects(a.geom, b.geom)
                                         AND a.id != b.id)), a.geom)
FROM test.multi_geometry_1 a;

এর ফলাফলটি কেবল পরীক্ষার অনুলিপি। বহু_জুমিত্রি_ _1 যদিও এখন বিভাজন ঘটছে না।

আমি আগের সংস্করণটি চেষ্টা করেছি, তবে আবার কেবল পরীক্ষার একটি অনুলিপি পেয়েছি।

CREATE TABLE processing.parcels_trimmed_no_coalesce AS
SELECT id, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom) 
                                         FROM test.single_geometry_1 b
                                         WHERE ST_Intersects(a.geom, b.geom)
                                         AND a.id != b.id)), a.geom)
FROM test.multi_geometry_1 a;

আমি ভাবতে শুরু করি যে আমি অন্যায় করে চলেছি এমন কিছু আছে কিনা? পরবর্তী বিবৃতিটি হ'ল:

DROP TABLE IF EXISTS processing.parcels_trimmed_no_coalesce;

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

টেবিলটি দেখতে আমি যে বিবৃতিটি ব্যবহার করি তা হ'ল:

SELECT * FROM processing.parcels_trimmed_no_coalesce;

সরলকরণের স্বার্থে আমি এখন এই কোয়েরিটিকে কেবলমাত্রে নামিয়েছি:

SELECT id, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom) 
                                         FROM test.geometriestocutagainst b
                                         WHERE ST_Intersects(a.geom, b.geom)
                                         AND a.id != b.id)), a.geom)
FROM test.geometriestocut a;

এটি এখনও কেবলমাত্র বহুভুজ (test.geometriestocut) এ ফলাফল দেয় যখন পছন্দসই ফলাফলটি টেস্ট.জোমেট্রিস্টোকট্যাগেইনস্টের বিরুদ্ধে মূল ছাঁটাই হয়।


আপনি কোনও WHEREধারা উল্লেখ করেন নি , ফলস্বরূপ সারণিতে আপনার বহুপদী প্রসার থাকতে পারে। কত সারি আছে trimmedparcelsnew?
ভিন্স

যদি তারা কেবল যেখানে ছেদ করে সেখানেই কেবল এই পার্থক্যটি চান, তবে আপনি WHERE ST_Intersects (original.geom, cont.geom) যুক্ত করার চেষ্টা করতে পারেন। অন্যথায়, দুটি বহুভুজের পার্থক্য যা ছেদ করে না, এটি হ'ল মূল বহুভুজ।
জন পাওয়েল 16

নতুন ছাঁটা পার্সেলটিতে 24 টি সারি রয়েছে, আমি পার্থক্যটি চাই না যখন তারা ছেদ না করে, তাই আমি কি সংশোধন করব যে পার্থক্যের পরিবর্তে আমার টেবিলে অরিজ.জম ব্যবহার করা উচিত?
মার্ট

প্রতিটি বৈশিষ্ট্য - একটি অসংলগ্ন করা পরীক্ষা বহুপদী সম্প্রসারণ উত্পাদন করা উচিত চলছে প্রতিটি বৈশিষ্ট্যের জন্য একবার প্রদর্শিত orig যে ওভারল্যাপ না, এবং পার্থক্য হবে না একটি ইনপুট জ্যামিতি পরিবর্তন
ভিন্স

ঠিক আছে স্পষ্টতার জন্য ধন্যবাদ, তবে আমি এখনও নিশ্চিত নই কেন মূল কোডটি কাজ করছে না। যদি ST_Differences (original.geom, cont.geom) এমন একটি জ্যামিতিকে ফেরত দেয় যা খ এর সাথে ছেদ করে না, কেন টেবিলটি বি বি ছেদ না করে এমন জ্যামিতির চেয়ে বিভক্ত জ্যামিতির সমন্বয় করে।
মার্চ

উত্তর:


14

একটি স্ব-যোগ আপনার মধ্যেকার সম্পর্ককে কাজ করার অনুমতি দেয় জোড়া দুই বৈশিষ্ট্য। তবে আমি মনে করি না যে আপনি জোড়ায় আগ্রহী: প্রতিটি বৈশিষ্ট্যের জন্য আপনি সেই বৈশিষ্ট্যটি এবং আপনার ডেটাসেটের অন্যান্য সমস্ত বৈশিষ্ট্যের মধ্যে সম্পর্ককে পরিচালনা করতে চান । আপনি একটি subquery এক্সপ্রেশন দিয়ে এটি সম্পাদন করতে পারেন:

CREATE TABLE parcels_trimmed AS
SELECT id, ST_Difference(geom, (SELECT ST_Union(b.geom) 
                                FROM parcels b
                                WHERE ST_Intersects(a.geom, b.geom)
                                  AND a.id != b.id))
FROM parcels a;

যদিও আপনি ফলাফলগুলিতে কিছু অদ্ভুত দেখতে পাচ্ছেন। কোনও ওভারল্যাপ নেই এমন পার্সেলগুলি পুরোপুরি বাদ দেওয়া হচ্ছে! এটি কারণ ST_Unionএকটি খালি রেকর্ডসেটে সমষ্টি হতে চলেছে NULL, এবং ST_Difference(geom, NULL)তা NULL। এটিকে মসৃণ করতে আপনার একটিতে ST_Differenceকলটি মোড়ানো দরকার COALESCE:

CREATE TABLE parcels_trimmed AS
SELECT id, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom) 
                                         FROM parcels b
                                         WHERE ST_Intersects(a.geom, b.geom)
                                         AND a.id != b.id)), a.geom)
FROM parcels a;

এর অর্থ ST_Differenceহ'ল ফলাফলটি যদি হয় NULLতবে মিলিত অভিব্যক্তি মূল জ্যামিতিতে মূল্যায়ন করবে।

উপরের প্রশ্নটি সম্পূর্ণভাবে আপনার ডোমেন থেকে ওভারল্যাপিং অঞ্চলগুলি সরিয়ে ফেলবে। আপনি যদি পরিবর্তে কোনও বিজয়ী বাছাই করতে চান তবে আপনি a.id < b.idবা অন্য কোনও মানদণ্ডের পরিবর্তে এটি করতে পারেন a.id != b.id


প্রতিক্রিয়াটির জন্য ধন্যবাদ, দুর্ভাগ্যক্রমে আমার পক্ষে এটি কাজ করতে সমস্যা হচ্ছে, পরিবর্তে কেবল মূল বহুভুজ (ক) দিয়ে শেষ করুন। আমি আরও তথ্য দিয়ে আমার প্রশ্ন সম্পাদনা করব। আবার ধন্যবাদ.
মার্ট

2

আপনার মতো সমস্যাও আমার ছিল। আপনি ইতিমধ্যে আপনার সমস্যার সমাধান খুঁজে পেয়েছেন কিনা আমি জানি না, তবে আমি উপরে বর্ণিত উত্তরটি সংশোধন করেছি এবং আমি যা চেয়েছিলাম তা পেয়েছি।

CREATE TABLE parcels_trimmed AS
SELECT id, COALESCE(ST_Difference(geom, (SELECT ST_Collect(b.geom) 
                                         FROM parcels b
                                         WHERE ST_Intersects(a.geom, b.geom)
                                         )), a.geom)
FROM parcels a;

1

আমি থেকে ST_DifferenceAgg () ব্যবহার PostGIS অ্যাডঅনস । আপনাকে দুটি সারণী একসাথে মার্জ করতে হবে, জ্যামিতি কলামে একটি অনন্য শনাক্তকারী এবং একটি সূচক থাকতে হবে। এখানে একটি সংক্ষিপ্ত উদাহরণ:

WITH overlappingtable AS (
  SELECT 1 id, ST_GeomFromText('POLYGON((0 1, 3 2, 3 0, 0 1), (1.5 1.333, 2 1.333, 2 0.666, 1.5 0.666, 1.5 1.333))') geom
  UNION ALL
  SELECT 2 id, ST_GeomFromText('POLYGON((1 1, 3.8 2, 4 0, 1 1))')
  UNION ALL
  SELECT 3 id, ST_GeomFromText('POLYGON((2 1, 4.6 2, 5 0, 2 1))')
  UNION ALL
  SELECT 4 id, ST_GeomFromText('POLYGON((3 1, 5.4 2, 6 0, 3 1))')
  UNION ALL
  SELECT 5 id, ST_GeomFromText('POLYGON((3 1, 5.4 2, 6 0, 3 1))')
)
SELECT a.id, ST_DifferenceAgg(a.geom, b.geom) geom
FROM overlappingtable a,
     overlappingtable b
WHERE a.id = b.id OR -- Make sure to pass at least once the polygon with itself
      ((ST_Contains(a.geom, b.geom) OR -- Select all the containing, contained and overlapping polygons
        ST_Contains(b.geom, a.geom) OR
        ST_Overlaps(a.geom, b.geom)) AND
       (ST_Area(a.geom) < ST_Area(b.geom) OR -- Make sure bigger polygons are removed from smaller ones
        (ST_Area(a.geom) = ST_Area(b.geom) AND -- If areas are equal, arbitrarily remove one from the other but in a determined order so it's not done twice.
         a.id < b.id)))
GROUP BY a.id
HAVING ST_Area(ST_DifferenceAgg(a.geom, b.geom)) > 0 AND NOT ST_IsEmpty(ST_DifferenceAgg(a.geom, b.geom));

এটি ওভারল্যাপিং অংশগুলিকে বৃহত্তম ওভারল্যাপিং বহুভুজের সাথে একীভূত করবে। আপনি যদি ওভারল্যাপিং অংশটি আলাদা করে রাখতে চান তবে ST_splitAgg () উদাহরণটি দেখুন।

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