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
|