Opened 6 years ago

Closed 6 years ago

#1955 closed defect (fixed)

Exception when 2 edges passed to ST_ModEdgeHeal() that are attached to the same 2 nodes

Reported by: wimned Owned by: strk
Priority: medium Milestone: PostGIS 2.0.2
Component: topology Version: 2.0.x
Keywords: Cc:

Description

exception: 'SQL/MM Spatial exception - other edges connected (ie: 3)' raised when following code is executed:

CREATE OR REPLACE FUNCTION testerror1()
 returns void as
$$
    declare geom0 geometry;
    declare geom1 geometry;
    declare node_rec RECORD;
begin
    raise notice 'version: %', postgis_full_version();
    
    perform CreateTopology('wimpy', 4326);

    geom0 = ST_GeometryFromText(
        'POLYGON((0 0,0 1,1 1,1 0,0 0))',4326);

    geom1 = ST_GeometryFromText(
        'POLYGON((2 0,1 1,3 1,3 0,2 0))',4326);


    perform topogeo_AddPolygon('wimpy', geom0);
    perform topogeo_AddPolygon('wimpy', geom1);
    for node_rec in select node_id from node
    loop
        perform cleanse_node(node_rec.node_id);
    end loop;
END
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION cleanse_node(passed_node_id integer)
  returns void AS
$$
  DECLARE edge_rec RECORD;
  DECLARE edge0 integer;
  DECLARE edge1 integer;
  DECLARE count integer;
BEGIN
    --raise notice 'check node %', passed_node_id;
    edge0 = 0;
    edge1 = 0;
    count = 0;
    for edge_rec in
         ( select t.edge from 
            GetNodeEdges('wimpy', passed_node_id) as t(seq,edge))
    loop
        if count = 0
        then
            edge0 = abs(edge_rec.edge);
        end if;
        if count = 1
        then
            edge1 = abs(edge_rec.edge);
        end if;
        count = count + 1;
    end loop;
    if count = 2 and edge0 != edge1
    then
        raise notice 'remove node %', passed_node_id;
        perform ST_ModEdgeHeal('wimpy', edge0, edge1);
    end if;
END
$$

The node at (1 1) is chosen, while the one at (0 0) has to be removed.

Attachments (1)

removenode.jpg (6.6 KB) - added by wimned 6 years ago.

Download all attachments as: .zip

Change History (9)

comment:1 Changed 6 years ago by strk

This is tricky, why do you think "the other node" should be removed ? Shouldn't _both_ nodes be removed instead ? I'm afraid the SQL/MM document doesn't have any prescription about this.

comment:2 Changed 6 years ago by strk

attaching an image would help me understanding the issue

Changed 6 years ago by wimned

Attachment: removenode.jpg added

comment:3 Changed 6 years ago by wimned

Node 1 is to be removed, edges 1 and 2 are passed to ST_ModEdgeHeal().

The exception is raised when ST_ModEdgeHeal wants to remove node 3

Currently I'm working around by skipping the situations where 2 edges are atached to the same nodes.

btw i'm using version: POSTGIS="2.1.0SVN r10156" GEOS="3.3.4-CAPI-1.7.3" PROJ="Rel. 4.7.1, 23 September 2009" LIBXML="2.7.8" TOPOLOGY

comment:4 Changed 6 years ago by strk

Status: newassigned

Ok so 2 edges share _both_ nodes, but one of the node is also shared by another edge. What to do seems unambiguous, so this is a valid enhancement request.

I'm adding a testcase, and interesting enough the healing works IFF the first node checked is only shared by the two edges

comment:5 Changed 6 years ago by strk

I suspect there's another case which isn't tested: 2 edges both having a single, common, node.

comment:6 Changed 6 years ago by strk

Ah, forget it, the "closed edge" case is handled by refusing to heal it with anything.

comment:7 Changed 6 years ago by strk

ST_NewEdgeHeal is also affected

comment:8 Changed 6 years ago by strk

Milestone: PostGIS 2.1.0PostGIS 2.0.2
Resolution: fixed
Status: assignedclosed
Version: trunk2.0.x

Fixed by r10188 in 2.0 branch and r10189 in trunk (although I can't really test trunk due to #1956)

Note: See TracTickets for help on using tickets.