Software gvSIG OA Digital Edition 2010 have tools topology for finding pseudo nodes in linear geometry. I set cluster tolerance 0.00002 and maximum number of errors -10000 for 20000 link count linear geometry. But unsuccessful result.

Are there any solutions that find pseudo nodes in free GIS software?

I need to layer pseudo nodes (one solution to this problem - to use tools topology of ArcInfo, but priority for me is to use free software). Linear geometry created several users in QGIS 1.8.0 in PostGIS (v. 2.0.1) database.

Add new image: 12 linear features with three pseudo nodes in A (line 4/5), B (line 6/7), C (line 9/10). Pseudo nodes should be points instead - two linear features with intersection in one point (node) should be one linear feature (line 4/5 - line 4, ...).

Is it possible to make a request in PostGIS, which will result in a layer of pseudo nodes?

Add new image of examples pseudo nodes: if I receive for linear layer point layer pseudo nodes (blue rects) I corrected following errors in linear layer: A - add missing geometry, B - snapped line in intersection, C - remove pseudo node.

enter image description here

enter image description here

enter image description here

  • 2
    In GRASS exist command rmdangle, but in result shp-file without pseudo nodes. In result should be shp-file (or another) of pseudo nodes (like gvSIG OA Digital Edition 2010) Aug 16, 2012 at 7:58
  • Do you use PostGIS 2.0? If yes, give a try to Is_Valid and Makevalid functions. Aug 16, 2012 at 9:19
  • Yes, I use PostGIS 2.0. How I should use these functions for searching pseudo nodes? Is it possible to find them with "PgQuery for QGIS"? Aug 16, 2012 at 13:31
  • yes, you can use them within QGIS in any tool that allows you to run a PostGIS query, like for example DB Manager (that supports syntax highlighting and auto completion). Aug 16, 2012 at 15:42
  • the red point in the second picture is an intersection of two valid geometries..right?
    – vinayan
    Aug 16, 2012 at 16:25

6 Answers 6


Here a generic soluion, that you can impĺement with PostGIS or any other OGC-compliant software.

NOTE: as I say before, a key concept in FOSS and GIS is standardization: the best solutions adopt standards, like OGC ones.

Your problem is to "find pseudo nodes"... But I think that it is a little more, "find non-pseudo nodes and join lines of pseudo nodes". My solution can be used for both.

OGC standards offer:

  • ST_Boundary(geom): to detect the nodes of the lines

  • ST_Dump(geom): to put each single node in a SQL table record.

  • ST_DWithin, ST_Equals, ST_SnapToGrid, ST_Snap can be used for change tolerance. I am using ST_DWithin.

We can suppose that your main problem can be specified with these objects and properties,

  • there are only line segments (of a table linesegment), represented by a LINESTRING geometry... I not tested with MULTILNE, if you have geometrytype=MULTIPOINT, you can split and cast MULTILINEs with ST_Dump and ST_LineMerge;

  • each line segment have a (geometry ID) gid and a (color ID) idline.

So, the first step is to obtain the nodes that comes from joining lines,

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 (
      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;

NOTE: using caches because they are faster than views. Use "EXPLAIN SELECT ..." to check CPU time, it can take a long time.

Here cycles and continuous (same color) lines are detected as ncolors=1 points, and the pseudo nodes by ncolors=2 points, so, you have a layer with that points.

Your table of "good nodes" is with the original "bounding points" and without "pseudo nodes".

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 ... 
  • Thank you for solution! I try run query (in pgAdmin) but I receive exception: "function array_distinct(integer[]) not exist". What am I doing wrong? Dec 10, 2012 at 11:17
  • Sorry, not cited array_distinct function is from a postgres.cz library. Any other errors, please report, I can add more explanations here. Dec 10, 2012 at 12:45
  • I added array_distinct function. In database linear layer have "the_geom" geometry column name (instead "geom" in query). I replace "geom" to "the_geom" for "ST_Boundary(the_geom)" after run query I receive message "column "geom" not exist" in "as colors, geom FROM" place. I replace "as colors, geom FROM" to "as colors, the_geom FROM", but I again receive message "column "the_geom" not exist". Dec 10, 2012 at 13:43
  • Ok, changed (see edited answer) geom to the_geom. (ST_Dump(x)) stay as geom, is not a database attribute. Dec 10, 2012 at 15:51
  • Thanks! Query works. I replaced ST_DWithin on ST_equals and for ST_Buffer give 0.00002 DD tolerance. In result I received correct nodes (where in one node intersects 3 and more linear features). I want receive result where in one node intersects 2 linear features (FROM vw_joinnodes_full WHERE ncolors=2;), but received point layer where in one node intersects 2 and more linear features. How receive result where in one node intersects only 2 linear features? Dec 11, 2012 at 10:50

Refractions Research has made a Line Cleaner tool that seems to do what you want.

Line Cleaner cleanses networks by simplifying complex, cyclical, very short and zero-length geometries, and removing pseudo-nodes and insignificant vertexes. Most significantly, in the cleansing phase, it is able to ensure that feature matches can be considered automatically

enter image description here

The source code can be found at GitHub.

  • Thank you for the answer. But as a result of errors pseudo node needs a point layer. These errors must be corrected manually by users, as there are times when in one node should intersects three lines, but one of the lines skipped or not snapped to the vertex. Oct 10, 2012 at 5:55
  • This looks like it should work. Having difficulty understanding exactly what you're trying to say here. "as a result of errors pseudo node needs a point layer" I don't understand what you mean by this. Do you need a point layer with points snapped to the end of each line for this to work?
    – Rayner
    Oct 10, 2012 at 10:27
  • @Rayner, add new image of examples pseudo nodes (3): if I receive for linear layer point layer pseudo nodes (blue rects) I fix manually (not automatically) next errors in linear layer: A - add missing geometry, B - snapped line in intersection, C - remove pseudo node. If I'm fix automatically pseudo nodes I left errors in A, B places. Oct 10, 2012 at 12:02
  • Okay, I understand B and C. When you say "A - add missing geometry" what does that mean? Is there a point that needs to be added where the 2 lines meet?
    – Rayner
    Oct 10, 2012 at 13:33
  • @Rayner, it's means what in 'A' should be added linear feature (street/road according to imagery). In А - node was prepared to add new geometry according to imagery, but geometry not added (use layer pseudo nodes I find not painted geometry) Oct 10, 2012 at 14:08

Non-Free solution: FME + MRF + SmartCleaner transformer

Free solution GRASS v.clean (Latest QGIS 1.8.0 with GRASS tools is easiest way to use it) and other topology cleaning tools

  • QGIS 1.8.0. Install SEXTANTE plugin in C:\Program Files\Quantum GIS Lisboa\apps\qgis\python\plugins directory (1.0.7). Load linear shp-file in QGIS project (CRS layer and project WGS1984, 'on the fly' transformation on). Then I apply 'Define GRASS region on canvas' (GRASS commands - Tools) and run command v.clean - rmdangle (Thershold=0, enter dir/name for output vector/errors). After run process receive Error 'Could not load layer: D:/error.shp Check the SEXTANTE log to look errors'. In TOC added new layer, layer with errors not loaded. Oct 10, 2012 at 12:26
  • 1
    In GRASS exist command v.build.polylines - I receive one from two lines who intersects in one vertex (deleted pseudo node), but this command I not find in SEXTANTE plugin Oct 10, 2012 at 12:49
  • @simplexio Can you please suggest which option of v.clean can be used to identify the pseudo-nodes
    – osmjit
    May 9, 2017 at 7:42

Here are steps to Find your pseudo nodes using OpenJump a free GIS.
QGIS and gvSIG have the Sextante Plugin, so these same steps should work their too,
the Spatial Join might be slightly different.
I used version 1.2 for testing.

-- save the Line endpoints
Sextante toolbox, Topology, Extract endpoints of lines -> endpt_0

-- unsplit your lines
Sextante toolbox, Tools for line layers, Join adjacent lines

-- save the Unsplit line endpoints
Sextante toolbox, Topology, extract end points of line -> endpt_1

-- the end points removed by "Join adjacent lines" are pseudo nodes

Tools, Queries, Spatial Query,
Source layer "endpt_0"
Relation "Intersects"
Mask layer "endpt_1"

enable or click Complement Result

  • Thanks for the answer! I'am try make theses steps in QGIS Sextante, but I don't find "Extract endpoints of lines" and "Join adjacent lines" commands there. It is possible add in QGIS Sextante (in gvSIG 1.12 theses commands exist) or command v.build.polylines? Dec 10, 2012 at 11:00
  • I just installed the QGIS sextante plugin. I do not see the full functions either, many are missing. It should be easy to test the steps in gvSIG on a shapefile.
    – klewis
    Dec 10, 2012 at 18:42
  • I've just verified the above workflow in gvSIG and it works fine. I've substituted the final step with other two toolbox geoprocesses: first, the gvSIG "Spatial Join", second the "Filter vector layer" using DIST > 0 as expression. Furthermore, all the geoprocesses can be chained together in a SEXTANTE model in order to create a new tool, e.g. "Find pseudonodes". Aug 30, 2017 at 14:43

Solution for finding pseudo nodes (and other topology rules) available in QGIS 1.9.0 master (2.0) - plugin "Topology Checker". Links: Topology Checker plugin on YouTube, Topology Checker plugin on GitHub


With PostGIS, you can use a modified version of the query to find dangles discussed in this topic, as pseudonodes are nodes that intercept 2 linestrings and dangles are nodes that intercept 1 linestring.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.