Try this Tim. Comments welcome. Not all *that* easy to edit for different drawings (and their columns), I'm afraid. If this was a major problem then the edits could, with a bit of work, be scripted. This is not as fast as Topology Overlay--on my laptop and with your test data, 2.6s versus 0.7s for the real thing. (But my first working version took 47s, so I'm not completely unhappy.) If you have a large drawing you probably don't want a straight SELECT query, but an INSERT INTO query. Let me know if you need help with that. At first I coudn't work out why I got a resut with 420 objects, versus the 329 objects returned by Tpology Overlay. But then I noticed you have set location precision to 1m, and my initial queries were using maximum precision. The query below uses location precision internally (and sets the source precision for a linked drawing, via the OPTIONS clause), and produces the same result as Topology Overlay. This was an interesting exercise thanks. OPTIONS COORDSYS("OD" AS COMPONENT), PRECISION("OD" AS COMPONENT); SELECT [ID], [Season], [Intensity], [Disturbance Type], [Age], [dist_id], [THEME1], [THEME2], [THEME3], [BU], [Y01], [Y02], [Part] FROM (SELECT [ID], [Season], [Intensity], [Disturbance Type], [Age], [dist_id], [THEME1], [THEME2], [THEME3], [BU], [Y01], [Y02], [Type], CASE [Type] WHEN "intersection" THEN CASE WHEN [Mask A] IS NULL THEN NULL -- No intersection between this data area and any overlay mask ELSE ClipIntersect([ID], [Mask A]) -- using epsilon END WHEN "exclusion" THEN CASE WHEN MAX([Mask B]) IS NULL THEN Geom([ID]) -- No intersection between this data area and any overlay mask ELSE ClipSubtract([ID], UnionAll([Mask B])) -- with epsilon -- NULL if this data area is completely covered by overlay masks END END AS [Part] FROM (SELECT [Data].[ID], --[Data].[Geom (I)]), [Data].[Season], [Data].[Intensity], [Data].[Disturbance Type], [Data].[Age], [Data].[dist_id], -- Must list source columns explicitly, -- if not here then at least in the GROUP BY [Operation].[Type], CASE [Operation].[Type] WHEN "intersection" THEN [Overlay].[ID] -- [Geom (I)] WHEN "exclusion" THEN NULL END AS [Mask A], -- One reference to this overlay mask for the intersection operation -- Used individually, for ClipIntersect -- For exclusion substitute NULL (ignored in grouping) CASE [Operation].[Type] WHEN "exclusion" THEN [Overlay].[ID] -- [Geom (I)] WHEN "intersection" THEN NULL END AS [Mask B], -- A second reference to this overlay mask for the exclusion operation -- Used after grouping, for ClipSubtract -- For intersection substitute NULL (ignored in grouping) IIf([Operation].[Type] = "intersection", [Overlay].[THEME1], NULL) AS [THEME1], IIf([Operation].[Type] = "intersection", [Overlay].[THEME2], NULL) AS [THEME2], IIf([Operation].[Type] = "intersection", [Overlay].[THEME3], NULL) AS [THEME3], IIf([Operation].[Type] = "intersection", [Overlay].[BU], NULL) AS [BU], IIf([Operation].[Type] = "intersection", [Overlay].[Y01], NULL) AS [Y01], IIf([Operation].[Type] = "intersection", [Overlay].[Y02], NULL) AS [Y02] -- Overlay attributes are included for the intersection operation only -- For exclusion substitute NULL (ignored in grouping) FROM [OD] AS [Data] LEFT JOIN [SC] AS [Overlay] ON Touches([Data].[ID], [Overlay].[Geom (I)]) -- with epsilon AND NOT Adjacent([Data].[ID], [Overlay].[Geom (I)]) -- with epsilon CROSS JOIN (VALUES ("intersection"), ("exclusion") NAMES ([Type])) AS [Operation] ) GROUP BY [ID], [Season], [Intensity], [Disturbance Type], [Age], [dist_id], --[Geom (I)], [THEME1], [THEME2], [THEME3], [BU], [Y01], [Y02], [Type], [Mask A] -- Grouping by Mask A to give a separate row for each intersection -- Not grouping by Mask B because we combine these copies of the masks for exclusion ) AS [T] WHERE [Part] IS NOT NULL ; [Code tidied slightly just after posting. No functional changes.] Attachments: Identity overlay SQL.txt
|