Author Topic: Elements contained within a Boundary  (Read 8062 times)

Rik van der Schalie

  • EA User
  • **
  • Posts: 35
  • Karma: +0/-0
    • View Profile
Elements contained within a Boundary
« on: July 30, 2020, 05:15:00 pm »
Enterprise Architect seemingly knows which elements are contained within  a boundary in a diagram; when the boundary is dragged, all elements within are dragged along.
However, when programming against EA, I do not seem to be able to find the Elements contained within a Boundary; the Boundary can be found as a DiagramObject, but the Elements and Connectors collections of the Boundary are both empty, and I cannot glance from the documentation how to find the Elements.

I'd appreciate any hints on how to proceed. T.I.A.

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Elements contained within a Boundary
« Reply #1 on: July 30, 2020, 05:25:15 pm »
Doing it programmatically you have to do geometry (compare coordinates). The UI of EA does that internally.

q.

Rik van der Schalie

  • EA User
  • **
  • Posts: 35
  • Karma: +0/-0
    • View Profile
Re: Elements contained within a Boundary
« Reply #2 on: July 30, 2020, 05:28:12 pm »
Which, of course, is a nightmare for custom boundaries. But thanks for the answer.
Are there any code examples for this?

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Elements contained within a Boundary
« Reply #3 on: July 30, 2020, 05:35:11 pm »
Well, no. Horizontal coordinates go from 0 upwards. Vertical from 0 towards negative. Not difficult, just cumbersome.

q.

Rik van der Schalie

  • EA User
  • **
  • Posts: 35
  • Karma: +0/-0
    • View Profile
Re: Elements contained within a Boundary
« Reply #4 on: July 30, 2020, 05:46:59 pm »
My point is that with a user-defined boundary the shape is not a simple rectangle, so the different edges of the diagram can have different Top, Bottom, Left and Right values. The small Element is not contained within the Boundary, yet according to the simple Top, Bottom, Left and Right values it would appear to be.

_______________
|                          |
|                          |  ______
|                          |  |         |
|                          |  --------
|                          -----------
|                                         |
-------------------------------

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Elements contained within a Boundary
« Reply #5 on: July 30, 2020, 06:09:20 pm »
Well, remember your school geometry. EA's boundaries are always square (even the oval ones).

q.

Rik van der Schalie

  • EA User
  • **
  • Posts: 35
  • Karma: +0/-0
    • View Profile
Re: Elements contained within a Boundary
« Reply #6 on: July 30, 2020, 06:18:32 pm »
That's more than 40 years ago  ::)
I do know that the StyleEx attribute contains the Path, consisting of a list of x-y coordinates of the corner points. The trick is of course to separate the complex shape into a set of simple rectangles.

MichaelJ

  • EA User
  • **
  • Posts: 77
  • Karma: +14/-7
    • View Profile
Re: Elements contained within a Boundary
« Reply #7 on: July 30, 2020, 07:21:34 pm »
Hi rchalie,

Yes, this is a real pain in the butt when working programmatically with diagram objects inside boundaries. Sparx EA ABSOLUTELY can make this easier by utilising the "Parent_ID" (or even introduce a new "Boundary_ID") column in the t_object table. Alas, good user experience is hard to find in the product because it seems "...why click once when a user can click FIVE times to achieve the same outcome? Come on! If it ain't broke (like unsorted lists all over the place)... we ain't gonna fixxy wixxy".
Nevertheless, here's a script I've used to resolve a similar problem. It's based on the same logic I believe the product uses internally to calculate whether or not an element is WITHIN a boundary:


Code: [Select]
        var diagram as EA.Diagram;
        diagram = Repository.GetDiagramByID(diagramID);
       
        var diagramObjects as EA.Collection;
        diagramObjects = diagram.DiagramObjects;

        var loadedElms = [];    // elements contained within a boundary
        var unprocessed = [];
        var boundaries = [];
       
        // iterate all elements on the diagram and find boundaries and non-boundaries
        for(var i = 0; i < diagramObjects.Count; i++) {
            var dob as EA.DiagramObject;
            dob = diagramObjects.GetAt(i);
           
            var currentElement as EA.Element;
            currentElement = Repository.GetElementByID(dob.ElementID);
           
            if (currentElement.Type !== "Boundary"){
                loadedElms.push({ name: currentElement.Name, notes: currentElement.Notes, dob: dob });
                continue;
            }

            boundaries.push(dob);
        }
       
        // we want to sort the elements alphabetically
        loadedElms.sort(sortArray);
       
        // mark all elements as NOT contained in a boundary so later processing will remove them;
        // whatever's left are elements NOT contained by a boundary
        for(var i=0;i<loadedElms.length;i++)
            unprocessed.push(loadedElms[i].dob.ElementID);
       
        for(var i=0;i<boundaries.length;i++){
            var dob = boundaries[i];
           
            var left = dob.left;
            var top = dob.top;
            var right = dob.right;
            var bottom = dob.bottom;
           
            var count = 0;
            var sortedElms = [];
           
            for (var j = 0; j < loadedElms.length; j++) {
                var elm = loadedElms[j];
                if (!elm)
                    continue;
               
                var diagramObject2 = elm.dob;
                   
                if (diagramObject2.left>= left &
                    diagramObject2.top <= top &
                    diagramObject2.right<=right &
                    diagramObject2.bottom >= bottom){
                   
                    sortedElms.push({ name: elm.name, notes: elm.notes });
                    count += 1;
                       
                   // this element is part of this boundary, so ... you know... let's remove it
                    unprocessed[j] = -1;
                }
            }

            if (count){
                // use srotedElms to iterate the elements for THIS boundary                // For exaMple, you could populate a template or do some other processing with the elements inside the boundary
            }
           
            sortedElms= [];
            count = 0;
        }   
« Last Edit: July 30, 2020, 07:26:00 pm by MichaelJ »

Rik van der Schalie

  • EA User
  • **
  • Posts: 35
  • Karma: +0/-0
    • View Profile
Re: Elements contained within a Boundary
« Reply #8 on: July 30, 2020, 08:10:46 pm »
Hi Michael,

Thanks! I'm going to look into this, but my issue is that you work here on the assumption that the boundary is a simple rectangle. My boundary is a user-define boundary, so an irregular shape (with only orthogonal angles). I need a way to separate my irregular boundary in a set of rectangular boundaries, based only on a list of corner points. I cannot make an assumption on where on my user-defined boundary that list starts. I think I cannot even make an assumption on whether the list of corner points is in the clockwise or anti-clockwise direction along the boundary border.
« Last Edit: July 30, 2020, 10:14:39 pm by rchalie »

MichaelJ

  • EA User
  • **
  • Posts: 77
  • Karma: +14/-7
    • View Profile
Re: Elements contained within a Boundary
« Reply #9 on: July 30, 2020, 11:43:57 pm »
...you work here on the assumption that the boundary is a simple rectangle. My boundary is a user-define boundary, so an irregular shape...
Every shape can be broken down into a series of smaller rectangles. If you want to determine whether an element is part of an irregular shape, you'd need to check if an element's "bounding box" is contained fully or partially by one or more of rectangles that make up the irregular shape.

Referring to your earlier post...
...The small Element is not contained within the Boundary, yet according to the simple Top, Bottom, Left and Right values it would appear to be....

_______________
|                          |
|                          |  ______
|                          |  |         |
|                          |  --------
|                          -----------
|                                         |
-------------------------------
Could you please validate inside the t_diagramobjects table that this is indeed the case? Each element on a diagram canvas has the required bounding box dimensions, so if, according to the post above, the small element is *outside* the irregular shape, then the bounding boxes for the irregular shape and the small element contained in t_diagramobjects table will indeed reflect that.

Now, how to go about to determine if the small element is inside an irregular shape with straigh edges?

I see a two-step approach could be helpful:

Step one: break into smaller rectangles
_______________
|                          |
|                          |  ______
|          #1            |  |         |
|                          |  --------
_______________
|------------------------------
|              #2                       |
-------------------------------


Step two: use the script code provided to test if the small element is contained within [#1] or [#2].

« Last Edit: July 30, 2020, 11:46:03 pm by MichaelJ »

Rik van der Schalie

  • EA User
  • **
  • Posts: 35
  • Karma: +0/-0
    • View Profile
Re: Elements contained within a Boundary
« Reply #10 on: July 31, 2020, 12:03:51 am »
The only graphical information I can find about the irregular Boundary is, in the StyleEx atttribute, a Path, consisting of an ordered set of corners of the type "X1:Y1@X2:Y2@X3:Y3@X4:Y4@X5:Y5@X6:Y6" for a boundary with six corners (which could be split up in two rectangles X1:Y1@X2:Y2@X2:Y6@X6:Y6 and X2:Y4@X4:Y4@X5:Y5@Xx:Y5). The issue is of course that an irregular boundary would have to be split up in (N-4)/2 rectangles for N corners, so 6 corners will give two rectangles, 10 corners will give 4 rectangles. The thing is, there are multiple ways of splitting any irregular boundary into rectangles.

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Elements contained within a Boundary
« Reply #11 on: July 31, 2020, 05:16:32 am »
I'm not sure what you think you see there. EA diagram objects are either rectangles or drawn via shape script. From where do you take this path information?

q.

MichaelJ

  • EA User
  • **
  • Posts: 77
  • Karma: +14/-7
    • View Profile
Re: Elements contained within a Boundary
« Reply #12 on: July 31, 2020, 06:38:35 am »
...EA diagram objects are either rectangles or drawn via shape script. From where do you take this path information?
StyleEx is located in the t_object table; ObjectStyle column in the t_diagramobjects table.

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Elements contained within a Boundary
« Reply #13 on: July 31, 2020, 07:47:35 am »
Interesting. How do you define a boundary with, say, L-shape? Is that new with V15?

I skimmed these columns and none has anything like the above path. At least that path must be preprended with some "key=". Which would that be? Path? And how does it interact with shape scripts???

q.
« Last Edit: July 31, 2020, 07:54:54 am by qwerty »

MichaelJ

  • EA User
  • **
  • Posts: 77
  • Karma: +14/-7
    • View Profile
Re: Elements contained within a Boundary
« Reply #14 on: July 31, 2020, 08:38:06 am »
...How do you define a boundary with, say, L-shape? Is that new with V15?...
  • Drag a boundary object onto a diagram canvas
  • Double-click to bring up the properties dialog
  • Select "User Defined - Orthogonal"
  • Randomly click around the border using shift key to create "bends" (I say randomly, because it's tremendously pixel-perfect accuracy that's required)
  • When new "section" has been born, drag it around to create a necessary "L-Shape"
The data is stored in t_object in the StyleEx column. For example, I did an L-Shape and got this data "BT=81;Path=124:-493@505:-493@505:-599@306:-599@306:-747@124:-747;". Then in t_diagramobjects, the ObjectStyle column records this data "DUID=1D9BC707;shape=freestyle;"

...Is that new with V15?...
Yes.

...And how does it interact with shape scripts???...
I'm not sure; I have only worked with rectangular boundaries in scripts. However, rchalie wants to work with L-Shaped boundaries and then calculate while diagram objects are "contained" within it.