[postgis-users] Closing polylines

Nicolas Ribot nicolas.ribot at gmail.com
Thu May 17 03:07:34 PDT 2012


Hi George,

Beside the st_polygonize function I used yesterday, I made some other tests
based on the previous code I sent, here are some remarks concerning this
code:

First, as I understand your data, they are coming from a shapefile format
in which each feature is a simple line.
Maybe a loading with shp2pgsql created multilinestrings out of your
linestrings.
You can check if the contour data are indeed simple lines by running:

select count(distinct st_numgeometries(geom)) from seg;

If its returns 1, then all your segments are simple.

That may explain why all "path" values in the seg table are equal to 1. The
purpose of this column is to contain one distinct value for each segment
composing a contour line.

So first, based on your seg table, I updated the path value to generate
unique value for each segment (I could have used the sid column in your
data as it seems to represent a unique identifier for a row, but I kept
"path" to keep in line with the code)

update seg set path = p
from (
      select gid, row_number() over (partition by elev) as p from seg
) as foo where foo.gid = seg.gid;

Then, based on the particular topology of this dataset, where segments
composing contour lines are touching each other, I modified a bit the query
I sent previously:
To recall, this query creates a table listing, for each segment, the 2
other closest segments:

create table tmp as (
with closest as (
select s1.elev as elev, s1.path as path, s2.path as closest,
s2.geom,
row_number() over (
partition by s1.elev, s1.path
order by s1.elev, s1.path,
st_distance(st_collect(st_startpoint(s1.geom), st_endpoint(s1.geom)),
st_collect(st_startpoint(s2.geom), st_endpoint(s2.geom)))) as r
from seg s1, seg s2
where s1.elev = s2.elev
and s1.path <> s2.path
) select distinct * from closest
where r < 3
);

The main difference is that it uses row_number() instead of rank() window
function: as segments are touching, distance returns 0 for 2 segments, so
the rank is 1 for both of them.
row_number will give us a unique value in all the cases (touches, or just
close segments).

I also had to slightly change the st_makeClosedLine to also cope with
touching segments. I still have one bug, but I will send you the new
version when I find it.

It should then be able to handle cases where lines are not ordered, are
touching each other or have gaps between the (whatever the points
orientation is).

I'll keep you posted.

Nicolas


On 17 May 2012 09:41, georgew <gws293 at hotmail.com> wrote:

> Nicolas, your code is really magic in the way it closes those segments even
> though they are in random sequence! I am beginning to think that I am going
> to need a combination of all the solutions proposed above to cover all the
> various contour scenarios, including those with gaps, without gaps, open
> against one map edge or multiple edges, fully enclosed with all segments
> already in sequence or in random sequence and/or with inverse point order.
> Brent, your links and examples may well be another strategy, I have a lot
> to
> learn, but I will start by trying to adapt your script.
> All this is going to take me a bit of time to evaluate, but with your help
> so far I am way ahead of where I was a week ago.
> Thanks again, I will not fail to take up your offer of help if I get
> stuck!.
> George
>
> --
> View this message in context:
> http://postgis.17.n6.nabble.com/Closing-polylines-tp4971098p4991411.html
> Sent from the PostGIS - User mailing list archive at Nabble.com.
> _______________________________________________
> postgis-users mailing list
> postgis-users at postgis.refractions.net
> http://postgis.refractions.net/mailman/listinfo/postgis-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20120517/9803b2ce/attachment.html>


More information about the postgis-users mailing list