Subscribe to this thread
Home - General / All posts - Expand areas to remove space in between
dumbledown62 post(s)
#11-Sep-14 14:20

I have lots of areas within a drawing, with spaces in between (see attached - but for a much larger area)

Is there a way to expand the areas so that the lines are removed (i.e. the borders of all cells touch eachother)?

It does not need to be accurate - it's just all area has to be accounted for.

This would be awesome

Thanks

Hugh

Attachments:
areas.jpg

adaptagis

633 post(s)
#11-Sep-14 15:31

check manifold help for Buffers and normailze Metric

dumbledown62 post(s)
#11-Sep-14 16:33

Thanks adaptagis,

that's pretty good, but some of the zones lose their definition a bit - I was hoping that just the space in between would change. Maybe that's asking for too much.

Thanks for the 2nd piece of help today!

tjhb
10,094 post(s)
#11-Sep-14 22:28

Can you post some sample data please? I'd like to have a go at this in SQL.

By the way it's also worth trying [All objects] Attach to [All objects] transform*, temporarily adjusting precision for the purpose (see Manual). *Or Attach to Self.

But the finest result can be achieved in custom SQL.

dumbledown62 post(s)
#12-Sep-14 08:47

Thanks tjhb,

I've tried those, and although useful the zones become a bit more distorted than I would like.

Here's my drawing, this would be great.

Really appreciate the offer

Attachments:
zone boundaries.map

tjhb
10,094 post(s)
#12-Sep-14 16:30

Got it, ideal. Thanks very much.

tjhb
10,094 post(s)
#16-Sep-14 09:57

OK try this query.

Choose a threshold which is slightly wider than the maximum width of the open paths ("gaps") you want to fill. The defaut (if you enter nothing) is 100 units.

The target drawing should be called "Drawing" (otherwise edit the query: "Drawing" once and [Drawing] three times).

With your test data, a threshold of 200 is a good start.

After running the query, Union all affected areas, using the GUI transform. (For some workflows it would be good to use a query for this too.)

If you prefer a single combined patch, rather than triangles, adjust the commenting in lines 5 and 6. (The triangles show what's going on better.)

The patch(es) slightly over-fill the open paths (in places).

--OPTIONS COORDSYS("Drawing" AS COMPONENT);

PARAMETERS [Threshold (100)] DOUBLE;

INSERT INTO [Drawing] ([Geom (I)])

SELECT

    [Triangle]

--    UnionAll([Triangle])

FROM

    -- Return a triangulation of the selected boundary points

    -- filtered so that no triangle has a side shorter than the search radius

    (SELECT [Triangle]

    FROM

        (SELECT [Triangle][Side]

        FROM

            (SELECT [Triangle]

            FROM

                (SELECT AllCoords([Point]AS [Points]

                FROM

                    -- Return points on the boundary of one area

                    -- which lie within the search radius of another area

                    (SELECT [Point]

                    FROM

                        -- Split, segmentize and recombine segments of original metrics

                        (SELECT

                            [ID],

                            Normalize(AllBranches([Segmentized])) AS [Line] -- note 1

                        FROM

                            (SELECT 

                                [ID],

                                Segments( -- note 2

                                    [Segment]

                                    Floor(Length([Segment]) / Coalesce([Threshold (100)], 100))

                                    ) AS [Segmentized]

                            FROM [Drawing]

                            SPLIT BY Branches(IntersectLine(ConvertToLine([ID]), ConvertToLine([ID]))) AS [Segment]

                            )

                        GROUP BY [ID]

                        ) AS [T]

                        INNER JOIN

                        [Drawing] AS [D]

                        ON [T].[ID] <> [D].[ID]

                        AND Distance([T].[Line][D].[ID]) < Coalesce([Threshold (100)], 100)

                    SPLIT BY Coords([T].[Line]AS [Point]

                    LEAVING Distance([Point][D].[ID]) < Coalesce([Threshold (100)], 100)

                    )

                )

            SPLIT BY Branches(Triangulation([Points])) AS [Triangle] -- note 3

            )

        SPLIT BY Branches(IntersectLine(ConvertToLine([Triangle]), ConvertToLine([Triangle]))) AS [Side]

        LEAVING Length([Side]) <= Coalesce([Threshold (100)], 100) -- note 4

        )

    GROUP BY [Triangle]

    HAVING COUNT([Side]) = 3 -- note 5

    )

;

-- Notes

-- 1

-- Normalize() combines branches (derived from segments of the original line)

-- so far as possible (without removing redundant coordinates)

-- 2

-- Segmentize the original metric 

-- at roughly the search radius

-- so that the triangulation can cross

-- the maximum path width ("gap") everywhere

-- 3

-- The full triangulation set includes many very large triangles

-- that we don't need or want

-- 4

-- Exclude sides longer than the search radius...

-- 5

-- ...since we only want the triangles with all sides

-- less than or equal to the radius

[Query edited slightly.]

Attachments:
Fill open paths between areas.txt

tjhb
10,094 post(s)
#16-Sep-14 10:20

I said a threshold of 200 was a good start with the test data. A threshold of 500 fills all the open paths.

As you'd expect, the greater the threshold used, the more the ends of the open paths are smoothed--so you might choose a lower threshold and fill remaining holes manually (or by a query).

Timings (Core i7 mobile): threshold 200 -> 35s, 300 -> 37s, 400 -> 39s, 500 -> 42s.

Attachments:
Fill 500 (triangles).png
Fill 500 (union).png
Open paths.png

dumbledown62 post(s)
#16-Sep-14 11:45

Wow,

that is brilliant tjhb.

The final piece in the jigsaw would be to union all the triangles with the nearest areas.

Or if the whole drawing is unioned in a copy, somehow splitting up that drawing proportionally.

Any idea how to do that?

Thanks!

tjhb
10,094 post(s)
#16-Sep-14 13:33

For the first thing, do you mean union each triangle with the single area nearest to it? (That might be quite jagged, though that could be improved upon.) Or with the two (or three) nearest areas--all together?

I don't understand the second thing.

ColinD

2,081 post(s)
#16-Sep-14 21:36

That is a very useful bit of coding Tim. If I am mind reading correctly I think what is being asked for is to close the gap between each polygon by adding half the gap to each, retaining the individual polygons. Possibly a job for Voronoi areas?


Aussie Nature Shots

tjhb
10,094 post(s)
#16-Sep-14 22:26

Ah thanks Colin, that makes perfect sense. I'll have a think.

We may be best to clip all triangles to the open paths ("gaps"), then Union() them, then use triangulation again to find rough centrelines, then do the attribution to nearest. (That would involve Voronoi calculations at least indirectly.)

rk
621 post(s)
#17-Sep-14 10:34

there's an old thread http://www.georeference.org/forum/t58154.11 mentioning voronoi method.

but there is another method to get borders and bounded areas from raster

1. select lagom* border pixels from image (more is not better)

2. copy selected pixels as Table with [X (I)] and [Y (I)] as columns

3. copy Table as Drawing using [X (I)] and [Y (I)]

4. If necessary, reduce the number of points by [Attach to self] and delete duplicates)

5. [Spanning Tree] transform

6. draw some lines - fill the gaps in spanning tree to make cycles (closed areas)

7. [Bounded areas] lines

8. [Normalize topology] areas

*http://en.wikipedia.org/wiki/Lagom

Attachments:
borders_w_spanning_tree.jpg
zone boundaries.map

dumbledown62 post(s)
#17-Sep-14 13:41

Thanks RK,

that's useful, but there are gaps where the spanning tree hasn't completed everywhere, and it is limited to a small area. Also I'm struggling to get the bounded areas.

But, it is a very nice precise solution for a smaller area and I will definitely use it.

Thanks

Hugh

rk
621 post(s)
#17-Sep-14 14:56

there are tricks to close the gaps not by hand.

I can't remember how exactly I did it.

You can try select the leaf-points (at first join lines and then select adjacent points) and use Distance Network transformation on selected points. Something in those lines.

dumbledown62 post(s)
#17-Sep-14 13:05

Thanks Tim again,

that's exactly what I'm after Colin

Manifold User Community Use Agreement Copyright (C) 2007-2021 Manifold Software Limited. All rights reserved.