[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