[postgis-users] Topology: Simplifying Coastlines with Islands

Sandro Santilli strk at keybit.net
Tue May 29 06:23:06 PDT 2012


On Tue, May 29, 2012 at 02:33:54PM +0200, Michiel J. van Heek wrote:
> Quoting "Michiel J. van Heek" <michielvanheek at nine-e.org>:
> 
> >Quoting Sandro Santilli <strk at keybit.net>:
> >
> >>On Mon, May 28, 2012 at 02:50:43PM +0200, Michiel J. van Heek wrote:
> >>>Quoting Sandro Santilli <strk at keybit.net>:
> >>...
> >>>>How do your country boundaries look now ? :)
> >>>
> >>>They look pretty good. Most remaining trouble edges are relatively
> >>>short. Three long coastlines remain problematic: arctic Canada,
> >>>southern/eastern USA, and Brazil. (Red color in attached
> >>>screenshot.) Probably because they have some quite large islands
> >>>very close to the coastline.
> >>
> >>"Probably" ? Dissipate any dubt, take a closer look !
> >>Pick the Brazil coast, looks interesting.
> >>Zoom in, see the edge which was colliding in the ST_ChangeEdgeGeom
> >>error message.
> >
> >The collisions that struck me this morning: for the US east coast
> >it was Long Island, NY. And for the coast of Brazil it was the
> >island of Afua. But I will take another look, and send you some
> >screen shots tomorrow, when I am at my other computer.
> 
> Hello Sandro,
> 
> I am sure you will like these pictures. :-)

I love them.

> 
> Screenshot.png
>   black: edges that simplified in the first run (tolerance: 0.5 - 0.1)
>   blue: edges that simplified in the second run (tolerance: 0.5 - 0.1)
>   green: edge (southern Vietnam) that simplified in the third run
> (tolerance: 0.5 - 0.1)
>   orange: edges that would not simplify with a tolerance of 0.1 or
> higher (tried 5 runs)
> 
> Screenshot1.png: Long Island, New York (prevents east coast of USA
> from simplifying)
> 
> Screenshot2.png: Afua islands, Brazil
> 
> Screenshot3.png: mouth of the Uruquay River (prevents south coast of
> Uruquay from simplifying)
> 
> I hope these pictures will help you get a better idea of how to
> solve these kind of simplifying challenges.

Yes, ok. It's clear now.

I recon that for long island, splitting the unsimplified edge on
the closest point to the island might make it simplifiable.
Probably a single point is not enough for the Brazil case, but
a recursive approach would find next closest point and succeed.

This is of course the approach which does _not_ change the topology.
Removing the small faces or "inglobating" them would be a different
approach (changing the topology). Let's see it.

> And finally a question about removing islands. I am using the
> procedure below to delete all topography elements that belong to
> faces with a bounding box smaller than a certain area (0.5 in this
> case). Is it correct? Should we add this to PostGIS as a function?

I'll comment inline.

> CREATE TABLE topo_ids_temp AS
> SELECT
>     face_id,
>     edge_id,
>     node_id
> FROM countries_topology_4.face
> INNER JOIN countries_topology_4.edge_data
> ON ((face_id = left_face) OR (face_id = right_face))
> INNER JOIN countries_topology_4.node
> ON (start_node = node_id)
> WHERE (st_area(mbr) < 0.5)
>     AND (start_node = end_node)

Are you limiting the search to only faces with a single edge here ?
Why ? And why would you need to query the "node" table for that ?

>     AND (edge_id NOT IN (
>         SELECT abs_next_left_edge FROM
> countries_topology_4.edge_data WHERE edge_id <> abs_next_left_edge
>         UNION
>         SELECT abs_next_right_edge FROM
> countries_topology_4.edge_data WHERE edge_id <> abs_next_right_edge
>     ));

This part seems to again have to do with not destroying faces defined
by more than one edge ?

> DELETE FROM countries_topology_4.edge_data
> USING topo_ids_temp
> WHERE (countries_topology_4.edge_data.edge_id = topo_ids_temp.edge_id);
> 
> DELETE FROM countries_topology_4.face
> USING topo_ids_temp
> WHERE (countries_topology_4.face.face_id = topo_ids_temp.face_id);
> 
> DELETE FROM countries_topology_4.node
> USING topo_ids_temp
> WHERE (countries_topology_4.node.node_id = topo_ids_temp.node_id);
> 
> DROP TABLE topo_ids_temp;

I can think of a few cases in which the above queries would fail.
Some would be verbose, some might silently break the topology (hopefully not).

Generally, I would advice against editing the primitive tables directly
but rather use existing editing functions.
There's no function to "remove face". ISO doesn't define one.
The closest you have is ST_RemEdgeModFace / ST_RemEdgeNewFaces.
Both would be enough to "remove a face" if you pass them an edge
bounding the face. Both would guard you against removing an edge
or a face which partecipates in the definition of a TopoGeometry.

If you built your topology using toTopoGeom it is very likely that
your islands partecipate in the definition of TopoGeometry objects,
so ST_RemEdge*Face would fail and tell you which TopoGeometry id 
you would be breaking. A "safe" procedure would also include editing
the TopoGeometry object to remove the face from its definition...

Again, there are no editing functions for TopoGeometry objects, but they
would be welcome. I could think of something like:

 TopoGeometry TopoGeom_removeComponent(TopoGeometry, TopoElement)

To use like this:

 UPDATE yourlayer SET topogeom = TopoGeom_removeComponent(
	topogeom,
	ARRAY[face_id, 3] -- not sure about this syntax, oops..
 );

--strk;

  ,------o-. 
  |   __/  |    Delivering high quality PostGIS 2.0 !
  |  / 2.0 |    http://strk.keybit.net - http://vizzuality.com
  `-o------'




More information about the postgis-users mailing list