Opened 9 years ago

Closed 9 years ago

#1188 closed task (fixed)

Implement topology.ST_RemEdgeNewFace

Reported by: strk Owned by: strk@…
Priority: medium Milestone: PostGIS 2.0.0
Component: topology Version: master
Keywords: Cc: aperi2007, robe

Description

This is an ISO-SQLMM topological function

Change History (10)

comment:1 Changed 9 years ago by strk

Cc: aperi2007 robe added

I love ISO specs...

Ok, so the spec says that _if_ removing the given edge two faces become a single face, then the function creates a new face and returns its identifier.

... but it doesn't say what does the function return when removing the edge doesn't heal any face ...

I guess we could return the identifier of the face on both sides of the edge being removed, but we could also return null to signal the special case (or how do you tell if what you get back is a _new_ or an existing face?).

Opinions ?

comment:2 Changed 9 years ago by chodgson

In what situations would removing an edge NOT result in merging two faces into a new face? I can only think of two:

1) one of the faces of the original line is the outermost face, boundary face, universal face, whatever you call it... not sure if you actually create a NEW such face or simply merge the existing ones onto it? However I imagine you could return the id of this face, new or not.

2) the edge was dangling into a face (not sure if this is even allowed?) in this case it would have originally had the same face on both sides of the segment... this case I could see possibly returning null.

Forgive my lack of knowledge of the workings of the topology system, but what is expected to be done with the returned face id? Does the model itself automatically update the other edges of the now-merged faces for you, or is this the purpose of returning the id of the newly merged face (so you can manually set the face_ids of the other segments)?. Also, why would you care if the returned ID is newly created or previously existing (assuming the model creates the face and assigns it's id to the necessary edges) - where the segment once was, there is now a face, I think it is always possible to return a single face id as the result? Unless perhaps there is a duplicate edge (if such a thing is allowed)? This would definitely be a case to return null.

comment:3 Changed 9 years ago by strk

2) is allowed

3) the edge was an isolated one, fully into a face or universe

I guess the returned value is to know which face was added (since the function might add a face).

The model automatically update all the other edges and the TopoGeometry objects for you. I like the "where the segment once was, there is now a face" idea. I've actually implemented it that way so far. No duplicated edge is allowed.

All errors raise an exception, btw, so there's no null return semantic so far.

comment:4 Changed 9 years ago by strk

Note that the companion ST_RemEdgeModFace is expected (by spec) to return _nothing_ (as no face is created) but leaves _which_ face to retain/enlarge to implementation specifics. I'd rather also have ST_RemEdgeModFace return "the face flooding the removed edge space" so to at least give the caller a meaningful information.

comment:5 Changed 9 years ago by strk

Resolution: fixed
Status: newclosed

r7858 implements the function, complete with documentation and pretty exaustive regress testing. It uses the "return face flooding removed edge space" semantic.

comment:6 Changed 9 years ago by strk

Resolution: fixed
Status: closedreopened

I reopen to implement an idea of Andrea Peri about return semantic. Given he'd like to distinguish between cases in which a _new_ face is created and cases in which no new face is created, he suggested we return a _negative_ face id when the face covering the space previously taken by the removed edge is an existing face (dangling edge case and universe splitting edge case).

comment:7 Changed 9 years ago by strk

Uhm, was too early for this, we can't return -0 ...

comment:8 Changed 9 years ago by strk

Not giving a sign to face 0 might not be a big problem, on a closer look. The thing is that we can divide the possible outcome of this function into 3 cases:

1) The removed edge is dangling or isolated.

No face is removed and no face is added.

2) The removed edge partecipates in a single ring (universe face on the other side).

Only one face is removed, no face is added.

3) The removed edge splits two faces.

Both faces are removed, a new face is added.

By using -#, 0, +# we could express all of the cases and still return "the id of the face taking up the space previously occupied by the removed edge".

A return > 0 would tell us that a face was created (with the returned id). A return = 0 would tell us that a face was removed A return < 0 would tell us that two faces were removed

To know _which_ faces were removed you'd have to look at left_face and right_face values of the edge _before_ calling the RemEdgeNewFace? function.

comment:9 Changed 9 years ago by strk

Err, a return < 0 would tell us that NO face was created and NO face was removed. Still 0 doesn't tell us whether or not a face was removed (could be an isolated or dangling edge in the universe face).

Thats unfortunate, I tought I had it :-/

comment:10 Changed 9 years ago by strk

Resolution: fixed
Status: reopenedclosed

Well, with r7869 the function will return NULL for cases 1 and 2, that is the cases in which _no_ new face is created.

Note: See TracTickets for help on using tickets.