Solved

Incrementally Z-offset all lines that intersect

  • 10 August 2022
  • 5 replies
  • 7 views

I am attempting to offset all lines that intersect each other by increments of 5. Some lines have duplicate/stacked lines on top of them, as well as standard intersections with other lines. My intent is to assign all lines that intersect a differing offset (which is where the increment of 5 comes into play).

 

I have tried creating a list on the Spatial Relator, but I am not getting my desired results. I don't have any trouble with creating the offsets through the Offsetter or 3D Forcer transformers, but I am stumped on trying to assign all intersecting lines a different offset (so they won't intersect in Z space).

 

I would appreciate any help or ideas that can be passed along, thank you!

icon

Best answer by mark2atsafe 11 August 2022, 20:13

View original

5 replies

Userlevel 4
Badge +25

I've got an idea in my head. It seems offbeat, but I'll try and explain.

 

  1. In an AttributeManager, create an attribute (x). Give it a value 1.
  2. In a second AttributeManager, turn on Enable Adjacent Feature Attributes. Number of Prior Features = 1
  3. Set Substitute Missing, Null and Empty to Default Value, = 0.5
  4. Under x, set the new value to @Value(feature[-1].x)*2 (i.e. double the previous value).

 

That will give you features numbered 1, 2, 4, 8, 16, 32, 64, 128, etc.

 

  1. Add your SpatialRelator and click the option to generate a List. Select x as the value to add to the list.
  2. Add a ListSummer. Use it to create the sum of listname.x

 

If I'm right, at this point, you'll have an attribute called sum that is unique for each group of features that matched in the SpatialRelator. So now we know all intersecting lines have a unique, common value.

 

  1. Add a Counter to give a new _count ID to everything, using Group-By = sum
  2. Add an AttributeManager or ExpressionEvaluator to multiply _count by 5
  3. Use the Offsetter to offset in the Z direction by _count

 

I think that will work. My concerns are...

 

  • If you have a lot of features, that initial doubling of values will be very large, very quick.
  • The SpatialRelator has 2 input ports. Are you directing all features to both ports? Because if the same feature matched to itself, then it could make the ListSummer calculation incorrect. I'm uncertain about that.
  • There might be a much easier method that I just don't see right now!

 

Anyway, I hope this helps!

Userlevel 4
Badge +25

I've got an idea in my head. It seems offbeat, but I'll try and explain.

 

  1. In an AttributeManager, create an attribute (x). Give it a value 1.
  2. In a second AttributeManager, turn on Enable Adjacent Feature Attributes. Number of Prior Features = 1
  3. Set Substitute Missing, Null and Empty to Default Value, = 0.5
  4. Under x, set the new value to @Value(feature[-1].x)*2 (i.e. double the previous value).

 

That will give you features numbered 1, 2, 4, 8, 16, 32, 64, 128, etc.

 

  1. Add your SpatialRelator and click the option to generate a List. Select x as the value to add to the list.
  2. Add a ListSummer. Use it to create the sum of listname.x

 

If I'm right, at this point, you'll have an attribute called sum that is unique for each group of features that matched in the SpatialRelator. So now we know all intersecting lines have a unique, common value.

 

  1. Add a Counter to give a new _count ID to everything, using Group-By = sum
  2. Add an AttributeManager or ExpressionEvaluator to multiply _count by 5
  3. Use the Offsetter to offset in the Z direction by _count

 

I think that will work. My concerns are...

 

  • If you have a lot of features, that initial doubling of values will be very large, very quick.
  • The SpatialRelator has 2 input ports. Are you directing all features to both ports? Because if the same feature matched to itself, then it could make the ListSummer calculation incorrect. I'm uncertain about that.
  • There might be a much easier method that I just don't see right now!

 

Anyway, I hope this helps!

The more I think about that doubling of values, the more I don't like it. Basically, I'm trying to do binary bitwise arithmetic using decimal values. We could try and use a string of binary values and then the ampersand (&) operator in the Arithmetic Editor to do a bitwise AND (instead of the ListSummer). But at that point it's getting so complicated that there has to be a better solution.

The more I think about that doubling of values, the more I don't like it. Basically, I'm trying to do binary bitwise arithmetic using decimal values. We could try and use a string of binary values and then the ampersand (&) operator in the Arithmetic Editor to do a bitwise AND (instead of the ListSummer). But at that point it's getting so complicated that there has to be a better solution.

Hi Mark - thank you for your initial input and idea. A couple things that I wanted to mention: I do have around 400,000 line features to be processed, and I was using the same line feature class as input on both ports of the spatial relator, which would cause the list summer to be incorrect like you mentioned.

 

If nothing else, I am also trying to figure out if I can implement some python to assist in this processing.

 

Thanks again for your thoughts!

Userlevel 4
Badge +25

The more I think about that doubling of values, the more I don't like it. Basically, I'm trying to do binary bitwise arithmetic using decimal values. We could try and use a string of binary values and then the ampersand (&) operator in the Arithmetic Editor to do a bitwise AND (instead of the ListSummer). But at that point it's getting so complicated that there has to be a better solution.

Hi. Yeah, I think the key issue is just identifying which features overlap and in which groups. Sadly the FeatureRelator shares attribute information, but doesn't create any sort of group ID. My long-winded approach is the only way I can think of to create that group ID.

 

OK, here's another option. Run the lines through a Counter transformer (unless each feature already has a unique ID), then an Intersector transformer, then through a NetworkTopologyCalculator. Now you have groups of lines with a unique ID. You then pass that information back to the original feature with a FeatureMerger on the ID number:

 

image 

Now you have a unique ID, you just run it through the part mentioned before:

 

  1. Add a Counter to give a new _count ID to everything, using Group-By = sum
  2. Add an AttributeManager or ExpressionEvaluator to multiply _count by 5
  3. Use the Offsetter to offset in the Z direction by _count

 

Here's a workspace that does that: https://github.com/FMEEvangelist/FMECommunity/raw/main/SupportFiles/OffsetOverlappingLinesVertically.fmwt

 

The only problem I can see is where two features are an identical copy of each other. But you could perhaps check for those before doing this part.

 

This, I think, is a much better solution than yesterday's!

The more I think about that doubling of values, the more I don't like it. Basically, I'm trying to do binary bitwise arithmetic using decimal values. We could try and use a string of binary values and then the ampersand (&) operator in the Arithmetic Editor to do a bitwise AND (instead of the ListSummer). But at that point it's getting so complicated that there has to be a better solution.

Mark - Thank you SO much for your help with this. I have it working exactly as I hoped! I also handled/included the duplicate lines by adding the corresponding network ID through a spatial relator.

Thanks again!

Reply