[postgis-users] Topology: cannot delete slivers (or gaps)

Guillaume Drolet droletguillaume at gmail.com
Wed Nov 5 08:32:01 PST 2014


Sandro Santilli wrote
>> Except face 0, which is the "universe" face, all the others
>> should be "gaps" in your topology. You can zoom to the face's
>> bounding box ("mbr" field) to take a closer look (do you have qgis
>> set up by now?).
> 
> Ok. I had already looked at some of them but as face-derived geometries
> (using ST_GetFaceGeometry) and not as real faces. As geometries, to me
> they look like polygons and I didn't realize they were in fact holes. See
> this example in QGIS for face_id 2418 turned into a polygon:
> https://dl.dropboxusercontent.com/u/5196336/geomFromFace_id_2418.bmp. Now,
> look at its mbr representation:
> https://dl.dropboxusercontent.com/u/5196336/mbrFace_id_2418.bmp. How do
> you tell it's a hole and not just a regular face?
> 
>> What you could do programmatically is for each face to fetch the list
>> of edges bounding it and pick the face on the other side as a candidate;
>> then for each candidate face you find TopoGeometry objects containing
>> it in their definition and pick one to assign that orphaned face
>> (you could use smaller TopoGeometry, or larger, or whatever).
> 
> Let's try this or face_id 2418 (which is, btw, a meaningful unit and not
> an error...):
/
> SELECT f.face_id, e.edge_id, e.left_face, e.right_face 
> FROM de_20k_topo.face f JOIN 
>      de_20k_topo.edge_data e ON (f.face_id = e.left_face OR
> 	       		         f.face_id = e.right_face)
> WHERE face_id = 2418;
/
> 
*
> face_id, edge_id, left_face, right_face
*
> 2418;2663;2418;950
> 2418;6986;2418;340
> 2418;2672;2418;951
> 2418;2665;2418;344
> 2418;6989;2418;2417
> 
> I pick the first edge (2663) and take it's right_face, 950, as a
> candidate:
/
> SELECT topogeo_id 
> FROM de_20k_topo.relation
> WHERE element_id = 950;
/
> 
*
> topogeo_id
*
> 814
> 
> Only TopoGeom 814 has face_id 950 as one of its elements. Will assign
> face_id 2418
> to this TopoGeom:
/
> INSERT INTO de_20k_topo.relation 
> VALUES (814, 1, 2418, 3);
/
> 
> Then what? Is that it? Does that mean that that big hole 2418 is now
> unioned with face_id 950 (in which case it isn't what I want as it's a
> meaningful ecological unit)?
> 
> 
>> It might be better first to deal with the faces that are associated
>> with multiple TopoGeometry, just to avoid assigning an orphaned face
>> to a TopoGeometry based on it's containing a face which will later
>> be removed from the definition because duplicated.
> 
> Good point.
> 
>> Eh, that part is a still a bit weak in documantation, maybe.
>> A TopoGeometry is a Geometry defined by its components.
> 
>> In your case (areal TopoGeometry objects) it is a (multi)Polygon
>> defined by a set of faces. Note that QGIS is also able to
>> show you the TopoGeometry objects, and lets you edit them "spatially"
>> (less robust than editing them by adding/removing components but with
>> some care easier to use).
> 
>>> In this case, the light grey line is where a single edge should be. Blue
>>> edges 6381
>>> and 6341 should not be there. The light grey line should start from the
>>> node
>>> at the bottom right and connect at its other end somewhere in the middle
>>> of
>>> edge 6340:
> 
>> Uhm, edge identifiers are missing from that dump.
>> I take it 6381 is the lower blue and 6341 the upper blue.
> 
> You're correct here.
> 
>> I suggest you load the TopoGeometry layer with qgis and see for yourself.
> 
> When you say load the TopoGeometry layer, I assume you mean the topogeom
> column I populated with:
/
> UPDATE syshiera.de_20k SET topogeom = toTopoGeom(geom_32198,
> 'de_20k_topo', 1, 2.0)
/
> 
> Right?
> 
> When I load it in QGIS using the PostGIS table loader, I can visualize it
> and see there are holes. E.g.
> https://dl.dropboxusercontent.com/u/5196336/holeInTopogeometry.bmp
> 
>> Unfortunately (that'd be useful to add in qgis) it won't be easy to
>> find TopoGeometry 1546 as extracting the id of a TopoGeometry requires
>> running an expression on the database: id(topogeom).
> 
> I can either
/
> SELECT * 
> FROM syshiera.de_20k
> WHERE id(topogeom) = 1546;
/
> 
> or, as I mentioned before, I can superimpose my 'faces' layer, which I
> derived from de_20k_topo.face
> using ST_GetFaceGeometry, to 'topogeom' to get the topogeo_id. No?
> 
>> You could create a view selecting just that topoGeometry, or a subset
>> of them, or you could just load them all, hoping it won't be too
>> expensive
>> (another spot where qgis support for postgis topology could be improved).
> 
> I agree, just loading the TopoViewer freezes QGIS for a while and I don't
> lack ressources on my machine.
> 
>> Chances are it would be enough to assign face 2227 to the TopoGeometry
>> with id 1546 (likely the one not-assigned). But as face 2227 was not
>> in your initial set (unassigned faces) I guess there's another
>> TopoGeometry
>> which does have 2227 in his definition, but not the one on the right.
>> In that case you have to pick which of the two contending TopoGeometry
>> objects should get face 2227 assigned, before you drop it. Basically,
>> which
>> TopoGeometry will get assigned the space occupied by that face.
> 
> TopoGeometry 1551 has 2227. More explanation about this in my previous
> post and below
> 
>> Given QGIS editing support for TopoGeometry objects you should be able
>> to see all of this by loading the layer and setting 50% transparency.
>> Enabling topological editing and editing those two TopoGeometry objects
>> should help you with manual resolution of this issue.
> 
> Will try this, thanks
> 
>>> Edge 2227 is missing from TopoGeom 1546: Where is it?
> 
>> You meant _face_ 2227.
>> Right, it's not assigned to TopoGeometry 1546,
>> but to another one.
> 
> That's what I meant yes.
> 
>>> So edges 2225 and 2227 are associated with TopoGeom 1551. Will change
>>> that:
> 
>> Again, you mean faces (last number is element_type, 3==face).
>> So TopoGeometry objects 1546 and 1551 overlap, and their intersection
>> is the union of faces 2225 and 2227.
> 
>>> UPDATE de_20k_topo.relation SET topogeo_id = 1546
>>> 	WHERE topogeo_id = 1551 AND element_id = 2227;
> 
>> There's already a record associating face 2227 with TopoGeometry 1546
>> so you don't need another record, just drop the one associating it
>> with TopoGeometry 1551:
> 
> Ok, now I see where you're going..
> 
>>  DELETE FROM de_20k_topo.relation 
>>  WHERE topogeo_id = 1551 AND element_id = 2227;
> 
>>> And then again:
>>> 
>>> /SELECT ST_RemEdgeModFace('de_20k_topo', 6346); /
>>> 
>>> ERROR:  TopoGeom 1551 in layer 1 (syshiera.de_20k.topogeom) cannot be
>>> represented healing faces 2225 and 2227
> 
>> Right, you only resolved the overlap of face 2227, but there's still
>> the overlap of face 2225 :)
> 
>>  DELETE FROM de_20k_topo.relation 
>>  WHERE topogeo_id = 1551 AND element_id = 2225;
> 
> Now it's clearer in my head what I need to do, thanks to you!
> 
>> It looks like you're on the right track so far.
> 
> Will keep trying and I will win. Again, thanks so much for your help.





--
View this message in context: http://postgis.17.x6.nabble.com/Topology-cannot-delete-slivers-or-gaps-tp5007250p5007278.html
Sent from the PostGIS - User mailing list archive at Nabble.com.


More information about the postgis-users mailing list