أكثر

هل يعد عد المضلعات المتداخلة في PostGIS باستخدام ST_Union بطيئًا جدًا؟

هل يعد عد المضلعات المتداخلة في PostGIS باستخدام ST_Union بطيئًا جدًا؟


لدي مجموعة من 1000 مضلع متداخلة وأريد حساب مناطق التداخل. أنا أستخدم إرشادات منشور المدونة هذا لإنشاء خطوط متعددة من 1000 مضلع ، ثم استخدم ملف السطر هذا لإنشاء مضلعات للمناطق المتداخلة ثم عد التداخلات. http://boundlessgeo.com/2014/10/postgis-training-creating-overlays/

يعمل هذا بشكل جيد مع مجموعات البيانات المكونة من 100 مضلع أو أقل ولكنه معلق على أي شيء أكثر من ذلك في الخطوة الأولى. يبدو أن ST_Union هو ما هو بطيء للغاية ، ولكن يبدو أن ST_Collect لا تعمل هنا لأنها تولد خطوطًا متعددة مع عدد أقل بكثير من العقد ولا تنشئ مضلعات غير متداخلة عند استخدامها في الخطوة الثانية. إنه أمر سيء للغاية لأن ST_Collect سريع جدًا - لكنه لا يعطي نفس النتيجة. هل لدى أي شخص أفكار حول كيفية تعديل هذه العملية للعمل بشكل أسرع على مجموعة بيانات من 1000 مضلع؟

الخطوة 1

إنشاء TABLE borderaries_polygons1000 AS SELECT ST_Union (ST_ExternalRing (wkb_geometry)) AS geom FROM polygons1000 ؛

الخطوة 2

إنشاء تسلسل polyseq_polygons1000 ؛ CREATE TABLE polys_polygons1000 AS SELECT nextval ('polyseq_polygons1000') معرف AS ، (ST_Dump (ST_Polygonize (geom))). geom AS geom FROM border_polygons1000 ؛

الخطوه 3

ALTER TABLE polys_polygons1000 أضف عدد الأعمدة الافتراضي 0 ؛ UPDATE polys_polygons1000 مجموعة العد = p.count FROM (عدد التحديد (*) AS count ، p.id AS id FROM polys_polygons1000 p JOIN polygons1000 c ON ST_Contains (c.wkb_geometry، ST_PointOnSurface (p.geom)) GROUP BY p.id p حيث p.id = polys_polygons1000.id ؛

يبدو أنه يمكنك استخدام ST_Node للقيام بذلك بشكل أسرع من ST_Union. لقد استخدمت هذا الاستعلام ، والذي أعتقد أنه يعطي نفس النتيجة:

إنشاء حدود الجدول كما حدد (ST_Dump (ST_Node (ST_Collect (ST_ExternalRing (geom))))). geom AS geom FROM circles ؛

ما أفعله هو جمع الحلقات الخارجية ثم إيماءها برأسها ، مما يقسمها إلى أجزاء فردية ، وتنتهي عند التقاطعات. مع 1000 دائرة ، يكتمل في أقل من دقيقة.

الاستعلام الأخير في الخطوة 3 بطيء أيضًا. لقد سرعته من خلال بناء مؤشرات على الأشكال الهندسية لكلا الجدولين واستخدام مرشح الصندوق المحيط (&&) في جملة ON.

اذا حكمنا من خلال الصورة ، فهي تعمل.

الجواب الأصلي

ربما أسيء الفهم ، لكن إذا كنت تريد فقط حساب التداخلات ، فلماذا تصنع أي أشكال هندسية جديدة؟ يمكنك الحصول على عدد التقاطعات:

حدد عدد (*) من geoms a ، geoms b حيث a.gid 

يتحقق هذا أساسًا من التقاطع بين كل هندسة وكل أشكال هندسية أخرى ، ولكنه يمنع التقاطع من أن يُحسب مرتين (أ && ب ، ولكن ليس ب & & أ). لا يزال n ^ 2 في أسوأ الأحوال ، لكن يجب أن يكون جيدًا. سيستخدم الفهرس.