PostGIS'deki satırların başlangıç ​​ve bitiş düğümlerini yapıştırma


9

Çizgileri noktalara nasıl yapıştıracağınızı gösteren birçok örnek var, ancak çizgi dizelerinin başlangıç ​​ve bitiş düğümlerini diğer çizgilerin düğümlerine tutturmanın herhangi bir (hızlı!) Yolunu bulamadım.

Esasen postgis (2.0) 'daki katmanımı "temizlemek", neredeyse benzer noktaları birlikte hareket ettirmek ve çizgi dizeleri arasındaki küçük açıklıkları dikmek istiyorum.

Başka bir düğüm eklesem, her iki çizginin ilk / son düğümünü veya her iki noktayı da merkeze taşımamın önemi yoktur.

İki seçenek buldum, ancak ikisinden de nasıl başlayacağından emin değilim:

İkinci seçenek kulağa makul geliyor, ancak bu yöntemin nasıl takip edileceğine dair herhangi bir yardım çok takdir edilecektir.

Yanıtlar:


6

Bahsedilen GRASS araçlarını veya topolojik fonksiyonları kullanmadan bunu çözmeyi başardım.

Temel olarak tüm başlangıç ​​ve bitiş düğümlerini alıyorum, yeni, geçici bir tabloya yerleştiriyorum, etraflarına bir tampon yerleştiriyorum, tampon nesnelerini birleştiriyorum ve her tampondaki bulunan tüm düğümleri tamponun merkezine taşıyorum.

Bu bittiğinde orijinal başlangıç ​​ve bitiş noktalarını yeni konuma taşıyorum.

Beklenenden daha kolay ve hala hızlı, ancak PostGIS'in bunun için bazı yerleşik işlevlere sahip olmasını bekledim - bu daha da hızlı olurdu.

Düzenleme: topluma geri vermek adına, bu benim (oldukça berbat) kodum.

drop table if exists nodes;
drop table if exists nodes2;
drop table if exists buffers;

-- Get Start and End nodes
select ST_StartPoint(wkb_geometry) startnode,  ST_EndPoint(wkb_geometry) endnode,    ogc_fid into nodes  from sourceTable;
-- Combine all nodes into one table for easier queries
select startnode node, ogc_fid into nodes2 from nodes;
insert into nodes2 select endnode node, ogc_fid from nodes;

-- Some indexes to speed everything up
CREATE INDEX nodesstart_idx ON nodes USING gist  (startnode);
CREATE INDEX nodesend_idx ON nodes USING gist  (endnode);
CREATE INDEX nodes2_idx ON nodes2 USING gist  (node);
CREATE INDEX nodes_ogcfid_idx ON nodes USING btree (ogc_fid ASC NULLS LAST);

-- Create buffers, combine them, split combined objects again
select (ST_Dump(ST_Union(ST_Buffer(node, 1)))).geom geom into buffers from nodes2;
CREATE INDEX buffers_idx ON buffers USING gist  (geom);

-- Update start/end nodes table
UPDATE nodes SET startnode = ST_Centroid((select geom from buffers WHERE geom && startnode));
UPDATE nodes SET endnode = ST_Centroid((select geom from buffers WHERE geom && endnode));
-- Update original points
update sourceTable set wkb_geometry = ST_SetPoint(
ST_SetPoint(wkb_geometry, 0, (select startnode from nodes where ogc_fid=sourceTable.ogc_fid)), 
ST_NumPoints(wkb_geometry) - 1, (select endnode from nodes where ogc_fid=sourceTable.ogc_fid));

DROP TABLE nodes;
DROP TABLE nodes2;
DROP TABLE buffers;

Bu cevap, cevabımdaki "topolojik olmayan" öneri gibi görünüyor. Eğer bir oy verin veya cevabı seçtiyseniz kibar olurdu. Toplumu burada besleyenler bunlar :)
katahdin

Haklısın. Cevabınızı iptal ettim ve yanıtımı kodumu içerecek şekilde düzenleyeceğim.
Jelmer Baas

4

İşte üç seçenek. Umarım biri yardımcı olur.

v.clean

QGIS'teki GRASS araçlarını kullanarak, uzamsal bir nesnenin topolojisini temizleyebilirsiniz. Kullanıcı @RK, farklı bir soruya cevap olarak bunun nasıl yapılacağı hakkında iyi bir talimatlar dizisi verir . GRASS'ın sağladığı avantaj, şekil dosyasının topolojisini çıkarmasıdır. Durumunuzun dezavantajı, verilerinizin bir şekil dosyasında olmamasıdır. Tabii ki "PostGIS Katmanı Ekle" aracını kullanarak Postgres'ten verileri bir şekil dosyasına aktarabilirsiniz, ancak bu ekstra bir adımdır.

Topolojik olmayan PostGIS fonksiyonları

PostGIS'te, linestring için bitiş ve başlangıç ​​noktası almak için ST_EndPoint ve ST_StartPoint işlevlerini kullanabilirsiniz. Ardından, ST_DWithi n ve ST_Distance kombinasyonlarını kullanarak , yakındaki bir geometride en yakın başlangıç ​​veya bitiş noktasını bulabilirsiniz. Çok fazla puanınız varsa, ST_DWithin yerinde bir dizine sahip olduğunuzu varsayarak sorguyu çok hızlandırır. Oradan, hangi noktaların değiştirileceğini ve hangilerinin düzeltileceğini tanımlayan bir kural oluşturmanız gerekecektir.

Buradaki avantaj, verilerinizi temizlik için GRASS'a göndermeniz gerekmemesi, ancak dikkat edilmesi gereken bazı tuzaklar var.

Topolojik PostGIS fonksiyonları

Soru PostGIS topolojik fonksiyonlarına atıfta bulundu. Bunlar harika çalışıyor, ancak wiki'nin açıkladığı gibi , kenarları, düğümleri ve yüzleri açıkça tanımlamanız gerekiyor. Topolojiyle ilgili bildiğiniz sorunlar olduğu için bu, veri kümeniz için bir sorun olacaktır.


1

PostGIS'in yapıştırma fonksiyonları vardır .. belki yardımcı olurlar?

ST_Snap: Giriş geometrisinin segmentlerini ve köşelerini referans geometrisinin köşelerine yaslayın.

ST_SnapToGrid: Giriş geometrisinin tüm noktalarını normal bir ızgaraya yaslayın.


1
Teşekkürler, bu işlevlerin farkındayım. ST_Snap TÜM düğümleri yakalar , sadece başlangıç ​​ve bitiş düğümünü istiyorum. ST_SnapToGrid, mevcut tüm geometriyi değiştirdiği ve neredeyse başka bir segmente düştüğü için daha yakın olan düğümleri uzaklaştırma şansına sahip olduğu için gerçekten uygun değil.
Jelmer Baas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.