Subscribe to this thread
Home - General / All posts - Select all objects of same geometry - Manifold 8
steveFitz

224 post(s)
#08-Nov-18 00:30

I often work with drawings derived from dwg CAD drawings that include objects of the same geometry such as crosses (survey marks), circles (tree stems), etc. on a number of layers.

My workflow involves flattening the layers to a single drawing from which I hand select all the objects of interest with the same (apparent) geometry. The only thing the objects all share is their actual geometry (not including x, y location).

I often want to remove the survey marks (crosses) of the same geom and put centroids in all circles of the same geom. The circles are not usually polygons so comparing areas is not always possible. The process can be very slow.

Today I tried a query

Select * from [CAD_DWG][GeomD]

Where [CAD_DWG].[Geom (I)] = [GeomD].[Geom (I)]

where CAD_DWG is the flattened dwg and GeomD is a drawing with a single sample of a circle (line) with the geom I'm wanting to select in the CAD_DWG drawing.

The query only selects the single circle in CAD_DWG that I copied for the sample in GeomD, as if the geometry includes the location (?)

Can anyone suggest a way of automating the selection all objects of same geom (e.g. circles of the same size)

tjhb

8,335 post(s)
#08-Nov-18 01:12

The query only selects the single circle in CAD_DWG that I copied for the sample in GeomD, as if the geometry includes the location

That's right, geometry (in this sense) includes location.

Think of the simplest case, the geometry of a point. It is the X, Y vector to the point from the origin of the coordinate system (the notional point at 0, 0).

Different points have different geometry (in this sense), even though they have identical (trivial) geometry in a different mathematical sense.

The same applies for lines and areas (and multipoints). They have coordinates, defined as for points (vectors from the shared origin) plus also topological elements: branch membership and coordinate order.

Can anyone suggest a way of automating the selection all objects of same geom (e.g. circles of the same size)

I think what you need is to select all objects having the same relative geometry, i.e. the same geometry with respect not to the shared origin (the point 0, 0 in the current coordinate system), but with respect to their own, notional origin. That could be, for example, the object centroid, or a corner of its bounding box.

Then it is necessary to translate each object coordinate, by the difference between its X, Y distance from the common origin and its X, Y distance from its own notional origin.

But that is not quite enough, since objects may still differ by their internal topology, i.e. branch membership and coordinate order. So each object to be compared must also be normalized.

All that can be automated yes.

steveFitz

224 post(s)
#08-Nov-18 06:48

Then it is necessary to translate each object coordinate, by the difference between its X, Y distance from the common origin and its X, Y distance from its own notional origin...

Wow! I should have thought of that!

Only kidding.

All that can be automated yes.

But I'm guessing it is not a trivial thing to do.

Thanks for looking at it.

adamw


8,204 post(s)
#08-Nov-18 15:23

Comparing geometry in the general case is not at all simple. Conditions like WHERE [geom1] = [geom2] will only trigger on exact coincidence, and with floating-point values that are being transformed in some way, exact coincidences are rare.

It is tempting to impose some limitations on what geoms could be and how exactly they should be deemed to be the same. Ie, if we are dealing with points, I'd compare distances with some threshold. (If we are dealing with areas and their shape is supposed to matter, then in the general case you'd probably want to subtract them from each other and look at the area of the result - both the area of [area1] subtracted from [area2] and vice versa - if the differences are minor, then areas are considered to be the same. Subtracting geoms right away is usually slow, but we can subtract bounding boxes first and look at the area of that result to speed things up significantly - this modifies the criteria for sameness slightly, but in a mostly desired way.)

When you say 'same geom' in 'I often want to remove the survey marks (crosses) of the same geom and put centroids in all circles of the same geom', what specifically do you mean? Are we talking about two references from different blocks in a CAD file to the exact same metric? That would help, because then we can perhaps rely on the coordinate counts and order being the same. But if we are talking about some shape being copied and pasted over and over, then scaled or otherwise transformed individually, things might be more complex, who knows how much detail is lost during that, need to look at the data.

tjhb

8,335 post(s)
#08-Nov-18 22:41

(If we are dealing with areas and their shape is supposed to matter, then in the general case you'd probably want to subtract them from each other and look at the area of the result - both the area of [area1] subtracted from [area2] and vice versa - if the differences are minor, then areas are considered to be the same. Subtracting geoms right away is usually slow, but we can subtract bounding boxes first and look at the area of that result to speed things up significantly - this modifies the criteria for sameness slightly, but in a mostly desired way.)

If geoms are in different locations, then any of this requires collocating them first, by moving each geom so that (e.g.) the centre of its bounding box, or (better) its weighted centroid, is at a common location (e.g.) 0, 0.

Has anyone any experience using ST_FrechetDistance or ST_HausdorffDistance in PostGIS? Both look promising to me, allowing approximate (and ranked) matches.

adamw


8,204 post(s)
#09-Nov-18 08:29

Hausdorff distance is surely one way to approach similarity - after geoms are co-centered and possibly co-scaled (I am now going to look at the data, CAD blocks might also be rotated relative to each other, that's harder to fix).

steveFitz

224 post(s)
#08-Nov-18 22:46

Thanks Adam.

Yes, I think I'm talking about different blocks to the exact same metric.

I've attached an example of a small area of a CAD plan flattened to a single layer. I had a go at a couple of simple queries that work on coordinate count and bearings within parameters. While this works good enough for this drawing I'm not sure it would work with others.

Attachments:
SelectByGeomExample_M8.map

tjhb

8,335 post(s)
#08-Nov-18 22:52

As well as location, you are also wanting to ignore size??

steveFitz

224 post(s)
#08-Nov-18 23:12

It would be ideal to be able to specify a range of sizes but I would be happy if it were only a given size - as long as it could be changed as needed. Any circle larger than say 2m diam is likely to be a water tank and not a tree. For my work it is not critical that is is 100% accurate.

adamw


8,204 post(s)
#09-Nov-18 08:45

From the first look, it looks like many objects are disjoint (eg, crosses are two crossing lines, not one line with two branches), however, they are already separated pretty nicely by layers, no?

I ran this query:

--SQL9

SELECT [Layer],

  Count(*) AS recs,

  Min(GeomCoordCount([Geom (I)])) AS mincoords,

  Max(GeomCoordCount([Geom (I)])) AS maxcoords

FROM [CAD_DWG Table] GROUP BY [Layer];

...to gauge the general structure, then Alt-clicked into one of the small crosses with a cloud around it, noted that its layer is 'XXXXX123_ 211_Tree_2x01_PT', then went into the Style pane, set line color to use unique values in Layer and set the color for the above layer to blue -- and then all small crosses with clouds, which I would call "same" to each other, lighted up blue because they are in the same layer. Maybe we can just use layers?

adamw


8,204 post(s)
#09-Nov-18 09:03

Oh, just remembered that the thread is for Manifold 8, I did the above in 9, although I hope the idea is clear, one can do the same in 8.

Also, please forgive me for suggesting to look into using layers, maybe that's something you already considered and rejected. It's just that the geometry in the data is disjoint and so it is hard to even begin comparing it because we have to first group it into shapes which make sense to compare. It is one thing to be comparing single-branch circles - and if that's all you want, say so, this is solvable - but disjoint shapes have to be first joined together and it looks to me that figuring out which objects have to be joined into a single shape is half of the answer to which objects are the 'same' by your definition.

steveFitz

224 post(s)
#09-Nov-18 12:22

Thanks again Adam. I can and probably should be doing this stuff in 9 to get the hang of it and start the transition so sql appreciated.

I found that most CAD dwgs I get have the crosses on various layers so not that simple unfortunatly. The crosses are not that important - just cosmetic really. The circles are more important because I need centroid points to accuratly snap my tree inspection record points to while out on site. Sometimes the dwgs come with centroid points which makes life easier.

With regard to the crosses, they are not usually (ever?) visible when viewed in a CAD app so perhaps their is an object property that gets lost on import into Manifold. I'll have to ask a CAD expert.

adamw


8,204 post(s)
#09-Nov-18 14:48

OK.

Here is something I tried for circles:

--SQL8

SELECT *

FROM [CAD_DWG]

WHERE [Coordinates (I)] > 2

 AND IsLine([Geom (I)])

 AND

   Area(ClipSubtract(EnclosingCircle([Geom (I)]), ConvertToArea([Geom (I)]))) /

   Area(EnclosingCircle([Geom (I)])) < 0.01;

The query takes all lines with more than 2 coordinates (just a quick filter to ignore segments, need at least 3 coordinates to be closed, you might want to extend the filter to also check that the geom has a single branch and that the first coordinate of the branch coincides with the last), then computes two geoms: A = same geom but converted to an area and B = enclosing circle (note that B includes A), then computes the area of B - A and if that's close to the area of just B (within 1%), decides that this is a circle.

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