Menemukan node pseudo dalam perangkat lunak GIS gratis?

16

Perangkat lunak gvSIG OA Digital Edition 2010 memiliki topologi alat untuk menemukan node semu dalam geometri linier. Saya menetapkan toleransi kluster 0,00002 dan jumlah kesalahan maksimum -10000 untuk 20000 penghitungan geometri linier. Tetapi hasilnya tidak berhasil.

Apakah ada solusi yang menemukan node semu di perangkat lunak GIS gratis?

Saya perlu lapisan pseudo node (satu solusi untuk masalah ini - untuk menggunakan alat topologi ArcInfo, tetapi prioritas bagi saya adalah menggunakan perangkat lunak gratis). Linear geometry membuat beberapa pengguna dalam QGIS 1.8.0 di database PostGIS (v. 2.0.1).

Tambahkan gambar baru: 12 fitur linier dengan tiga node semu di A (baris 4/5), B (baris 6/7), C (baris 9/10). Node pseudo harus berupa titik - dua fitur linier dengan persimpangan dalam satu titik (node) harus menjadi satu fitur linier (baris 4/5 - baris 4, ...).

Apakah mungkin membuat permintaan di PostGIS, yang akan menghasilkan lapisan pseudo node?

Tambahkan gambar baru dari contoh pseudo node: jika saya menerima untuk layer pseudo node lapisan linier (rect biru) saya diperbaiki kesalahan berikut dalam lapisan linier: A - menambahkan geometri yang hilang, B - memotong garis di persimpangan, C - menghapus pseudo node.

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

HasT
sumber
2
Di GRASS ada perintah rmdangle, tetapi hasilnya shp-file tanpa pseudo node. Hasilnya harus berupa shp-file (atau yang lain) dari node semu (seperti gvSIG OA Digital Edition 2010)
HasT
Apakah Anda menggunakan PostGIS 2.0? Jika ya, coba fungsi Is_Valid dan Makevalid.
Giovanni Manghi
Ya, saya menggunakan PostGIS 2.0. Bagaimana saya harus menggunakan fungsi-fungsi ini untuk mencari node semu? Apakah mungkin menemukan mereka dengan "PgQuery for QGIS"?
HasT
ya, Anda dapat menggunakannya dalam QGIS dalam alat apa pun yang memungkinkan Anda menjalankan kueri PostGIS, seperti misalnya DB Manager (yang mendukung penyorotan sintaksis dan penyelesaian otomatis).
Giovanni Manghi
titik merah pada gambar kedua adalah persimpangan dua geometri yang valid..baik?
vinayan

Jawaban:

8

Di sini soluion generik, yang dapat Anda perbaiki dengan PostGIS atau perangkat lunak lain yang sesuai dengan OGC.

CATATAN: seperti yang saya katakan sebelumnya , konsep kunci dalam FOSS dan GIS adalah standardisasi : solusi terbaik mengadopsi standar, seperti yang OGC .


Masalah Anda adalah untuk "menemukan node semu" ... Tapi saya pikir itu sedikit lebih, "menemukan node non-semu dan bergabung dengan garis-garis node semu". Solusi saya dapat digunakan untuk keduanya.

Standar OGC menawarkan:

  • ST_Boundary (geom) : untuk mendeteksi node dari garis

  • ST_Dump (geom) : untuk menempatkan setiap node dalam catatan tabel SQL.

  • ST_DWithin, ST_Equals, ST_SnapToGrid, ST_Snap dapat digunakan untuk mengubah toleransi. Saya menggunakan ST_DWithin.

Kami dapat menganggap bahwa masalah utama Anda dapat ditentukan dengan objek dan properti ini,

  • hanya ada segmen garis (dari pembagian baris tabel ), yang diwakili oleh geometri LINESTRING ... Saya tidak diuji dengan MULTILNE, jika Anda memiliki geometritip = MULTIPOINT, Anda dapat membagi dan membuat MULTILINE dengan ST_Dump dan ST_LineMerge;

  • setiap segmen garis memiliki (geometri ID) gid dan (ID warna) idline .

Jadi, langkah pertama adalah untuk mendapatkan node yang berasal dari bergabung dengan garis,

CREATE TABLE cache_bounds AS
  SELECT gid as gid_seg, (ST_Dump(ST_Boundary(the_geom))).geom AS the_geom,
         gid as color 
         -- if you not have something for "color label" of lines, use gid.
  FROM linesegment;
ALTER TABLE cache_bounds ADD column gid serial PRIMARY KEY;

CREATE TABLE cache_joinnodes AS
  -- Use your TOLERANCE instead "1" at ST_DWithin and ST_Buffer.
  SELECT *, array_length(colors,1) as ncolors FROM (
   SELECT gid, array_distinct(array_cat(a_colors,b_colors)) as colors, the_geom FROM (
    SELECT 
      a.gid, array_agg(a.color) as a_colors, array_agg(b.color) as b_colors
      , st_buffer(a.the_geom,1) as the_geom -- any one to represent the join point.
    FROM cache_bounds a, cache_bounds b 
    WHERE a.gid>b.gid AND ST_DWithin(a.the_geom,b.the_geom,1)
    -- use ST_equals(a.the_geom,b.the_geom) if no tolerance.
    GROUP BY a.gid, a.the_geom
   ) as t
  ) as t2;

CATATAN: menggunakan cache karena mereka lebih cepat daripada tampilan. Gunakan "EXPLAIN SELECT ..." untuk memeriksa waktu CPU, ini bisa memakan waktu lama.

Di sini siklus dan garis kontinyu (warna yang sama) dideteksi sebagai ncolors=1titik, dan titik semu menurut ncolors=2titik, jadi, Anda memiliki lapisan dengan titik itu.

Tabel "good node" Anda adalah dengan "poin pembatas" asli dan tanpa "pseudo node".

CREATE VIEW vw_joinnodes_full AS
  SELECT b.*, j.ncolors
  FROM cache_joinnodes j INNER JOIN cache_bounds b 
       ON j.gid=b.gid;

CREATE TABLE cache_good_nodes AS
  SELECT *  
  FROM vw_joinnodes_full 
  WHERE ncolors=1 OR ncolors>2;

-- IF NEED ... CREATE VIEW vw_correct_linesegment AS ... 
Peter Krauss
sumber
Terima kasih atas solusinya! Saya mencoba menjalankan kueri (dalam pgAdmin) tetapi saya menerima pengecualian: "function array_distinct (integer []) tidak ada". Apa yang saya lakukan salah?
HasT
Maaf, array_distinctfungsi yang tidak dikutip dari perpustakaan postgres.cz . Kesalahan lainnya, tolong laporkan, saya dapat menambahkan lebih banyak penjelasan di sini.
Peter Krauss
Saya menambahkan fungsi array_distinct. Dalam database linear layer memiliki nama kolom geometri "the_geom" (bukan "geom" dalam kueri). Saya mengganti "geom" menjadi "the_geom" untuk "ST_Boundary (the_geom)" setelah menjalankan kueri, saya menerima pesan "kolom" geom "tidak ada" di "as colors, geom FROM" place. Saya mengganti "sebagai warna, geom DARI" menjadi "sebagai warna, the_geom DARI", tetapi saya kembali menerima pesan "kolom" the_geom "tidak ada".
HasT
Oke, ubah (lihat jawaban yang diedit) geommenjadi the_geom. (ST_Dump (x)) tetap sebagai geom, bukan atribut basis data.
Peter Krauss
Terima kasih! Permintaan bekerja. Saya mengganti ST_DWithin pada ST_equals dan untuk ST_Buffer memberikan toleransi 0,00002 DD. Sebagai hasilnya, saya menerima node yang benar (di mana dalam satu node memotong 3 dan lebih banyak fitur linear). Saya ingin menerima hasil di mana dalam satu node memotong 2 fitur linear (DARI vw_joinnodes_full WHERE ncolors = 2;), tetapi menerima layer titik di mana dalam satu node memotong 2 dan lebih banyak fitur linear. Bagaimana menerima hasil di mana dalam satu simpul hanya memotong 2 fitur linier?
HasT
7

Penelitian Pembiasan telah membuat alat Pembersih Garis yang tampaknya melakukan apa yang Anda inginkan.

Line Cleaner membersihkan jaringan dengan menyederhanakan geometri yang kompleks, siklis, sangat pendek dan panjang nol, dan menghilangkan pseudo-node dan vertex yang tidak signifikan. Paling signifikan, dalam fase pembersihan, ia dapat memastikan bahwa kecocokan fitur dapat dipertimbangkan secara otomatis

masukkan deskripsi gambar di sini

The kode sumber dapat ditemukan di GitHub.

RK
sumber
Terima kasih atas jawabannya. Tetapi sebagai akibat dari kesalahan pseudo node membutuhkan lapisan titik. Kesalahan ini harus dikoreksi secara manual oleh pengguna, karena ada kalanya dalam satu node harus memotong tiga garis, tetapi salah satu garis dilewati atau tidak terpasang ke vertex.
HasT
Ini sepertinya bekerja. Kesulitan memahami apa yang ingin Anda katakan di sini. "sebagai akibat dari kesalahan pseudo node membutuhkan layer titik" Saya tidak mengerti apa yang Anda maksudkan dengan ini. Apakah Anda memerlukan lapisan titik dengan titik-titik yang tersentak di ujung setiap baris agar ini berfungsi?
Rayner
@ Rayner, tambahkan gambar baru dari contoh pseudo node (3): jika saya menerima untuk layer pseudo node lapisan linear (rect biru) saya memperbaiki secara manual (tidak secara otomatis) kesalahan berikutnya dalam lapisan linier: A - tambahkan geometri yang hilang, B - bentak baris di persimpangan, C - menghapus simpul semu. Jika saya memperbaiki secara otomatis node semu saya meninggalkan kesalahan di tempat A, B.
HasT
Oke, saya mengerti B dan C. Ketika Anda mengatakan "A - tambahkan geometri yang hilang" apa artinya itu? Apakah ada poin yang perlu ditambahkan di mana 2 garis bertemu?
Rayner
@Rayner, artinya 'A' harus ditambahkan fitur linear (jalan / jalan menurut gambar). Dalam А - node disiapkan untuk menambahkan geometri baru sesuai dengan citra, tetapi geometri tidak ditambahkan (gunakan layer pseudo node yang saya temukan tidak dicat geometri)
HasT
2

Solusi Non-Gratis: Trafo FME + MRF + SmartCleaner

Solusi gratis GRASS v.clean (QGIS 1.8.0 terbaru dengan alat GRASS adalah cara termudah untuk menggunakannya) dan alat pembersih topologi lainnya

simplexio
sumber
QGIS 1.8.0. Instal plugin SEXTANTE dalam direktori C: \ Program Files \ Quantum GIS Lisboa \ apps \ qgis \ python \ plugins (1.0.7). Muat file shp linier dalam proyek QGIS (layer CRS dan proyek WGS1984, transformasi 'on the fly' aktif). Kemudian saya menerapkan 'Tentukan wilayah GRASS di atas kanvas' (perintah GRASS - Tools) dan jalankan perintah v.clean - rmdangle (Thershold = 0, masukkan dir / nama untuk vektor / kesalahan keluaran). Setelah menjalankan proses, terima Kesalahan 'Tidak dapat memuat lapisan: D: /error.shp Periksa log SEXTANTE untuk melihat kesalahan'. Di TOC menambahkan layer baru, layer dengan kesalahan tidak dimuat.
HasT
1
Di GRASS ada perintah v.build.polylines - Saya menerima satu dari dua baris yang bersinggungan dalam satu vertex (node ​​pseudo yang dihapus), tetapi perintah ini tidak saya temukan di plugin
SEXTANTE
@simplexio Bisakah Anda menyarankan opsi v.clean mana yang dapat digunakan untuk mengidentifikasi pseudo-node
osmjit
2

Berikut adalah langkah-langkah untuk Menemukan node semu Anda menggunakan OpenJump GIS gratis.
QGIS dan gvSIG memiliki Plugin Sextante, jadi langkah-langkah yang sama ini harus bekerja juga,
Spatial Join mungkin sedikit berbeda.
Saya menggunakan versi 1.2 untuk pengujian.

- simpan endpoint
Garis toolbox Sextante, Topologi, Ekstrak titik akhir garis -> endpt_0

- cabut garis garis Anda
Sextante toolbox, Alat untuk lapisan garis, Gabungkan garis yang berdekatan

- simpan titik akhir garis
unsplit Toolbox Sextante, Topologi, ekstrak titik akhir dari line -> endpt_1

- titik akhir yang dihapus oleh "Bergabung dengan garis yang berbatasan" adalah pseudo node

Tools, Query, Query Spatial,
Source layer "endpt_0"
Relation "Intersects"
Lapisan topeng "endpt_1"

mengaktifkan atau klik Hasil Pelengkap

Klewis
sumber
Terima kasih atas jawabannya! Saya mencoba membuat langkah-langkah tesis ini dalam QGIS Sextante, tetapi saya tidak menemukan perintah "Ekstrak titik akhir garis" dan "Gabungkan garis yang berbatasan" di sana. Dimungkinkan menambahkan QGIS Sextante (di gvSIG 1.12 ada perintah ini) atau perintah v.build.polylines?
HasT
Saya baru saja menginstal plugin sextante QGIS. Saya juga tidak melihat fungsi penuh, banyak yang hilang. Seharusnya mudah untuk menguji langkah-langkah di gvSIG pada sebuah shapefile.
klewis
Saya baru saja memverifikasi alur kerja di atas di gvSIG 2.4.0.2834 dan berfungsi dengan baik. Saya telah mengganti langkah terakhir dengan dua geoproses toolbox lainnya: pertama, gvSIG "Spatial Join" , kedua "layer vektor Filter" menggunakan DIST > 0sebagai ekspresi. Selanjutnya, semua geoproses dapat dirantai bersama dalam model SEXTANTE untuk membuat alat baru, misalnya "Temukan pseudonode" .
Antonio Falciano
1

Dengan PostGIS, Anda dapat menggunakan versi kueri yang dimodifikasi untuk menemukan dangles yang dibahas dalam topik ini , karena pseudonode adalah node yang memotong 2 linestrings dan dangles adalah node yang mencegat 1 linestring.

WITH nodes AS 
(SELECT ST_StartPoint(geom) AS pt FROM
linestring_table UNION ALL 
SELECT ST_EndPoint(geom) AS pt FROM
linestring_table) 
SELECT pt FROM nodes
GROUP BY pt HAVING count(*) = 2;
Gauchoguitar10
sumber