Question

How to retrieve path from point A to point B (geometry)


Hello, before writing a Python script, I'd like to know if there is a way to retrieve the lines between a point A and a point B using classic transofrmers?

 


10 replies

Userlevel 6
Badge +32

Like the LineBuilder transformer?

Userlevel 2
Badge +19

Check is the ShrotestPathFinder transformer works for you: https://www.safe.com/transformers/shortest-path-finder/

Sorry, I wasn't very clear. These are the lines I wish to keep knowing each id_ext_A matches id_ext_B of the previous line. Is it clear ?

 

image

Userlevel 5
Badge +25

Sorry, I wasn't very clear. These are the lines I wish to keep knowing each id_ext_A matches id_ext_B of the previous line. Is it clear ?

 

image

Yes, in an AttributeManager you can enable "adjacent features", giving you access to the attributes of e.g. the previous feature. You can create a new attribute, fill it with the value of the previous feature's ID_EXT_B and then use a TestFilter to see if it matches ID_EXT_A.

Yes, in an AttributeManager you can enable "adjacent features", giving you access to the attributes of e.g. the previous feature. You can create a new attribute, fill it with the value of the previous feature's ID_EXT_B and then use a TestFilter to see if it matches ID_EXT_A.

I didn't know this option, thanks! Although, the snapshot i showed you is 4 lines part of around 30, so I don't see how I can manage to only keep these lines using this method ?

Badge +20

Put X and Y values in attributes and send everything to both ports of a FeatureMerger set up with Accumulation Mode: Merge Supplier and Conflict Resolution: Use Supplier. You can even generate a list if this doesn't bring X and Y from joined features.

Join on ID_EXT_A to ID_EXT_B.

Send merged port to a VertexCreator with mode Add Point and X and Y to X and Y attributes.

Put X and Y values in attributes and send everything to both ports of a FeatureMerger set up with Accumulation Mode: Merge Supplier and Conflict Resolution: Use Supplier. You can even generate a list if this doesn't bring X and Y from joined features.

Join on ID_EXT_A to ID_EXT_B.

Send merged port to a VertexCreator with mode Add Point and X and Y to X and Y attributes.

Thanks for your answer. I'm not sure to understand what you mean by putting X and Y values in attributes. The geometries are lines, so doing the following doesn't seem to be the right way since it'll only take one end right ?

 

image

Following my question, I am trying to use loops for it, but it seems to block.

 

As a reminder my data is as follows:

ID_ELEMENT ID_EXT_A ID_EXT_B

4 A B

6 B C1

7 B C2

11 C2 D1

13 C1 D2

14 D2 E

 

I know my last point is E, so I need to climb my way back to A. Leaving me with the path: E -> D2 -> C1 -> B -> A

I am very new to FME and I obviously keep my developer's background, so I am trying to loop: here is what I did:

 

imageI put the previous node's ID in the variable. And each time it runs though, i check for the line where ID_EXT_A = Variable.

 

Maybe you see what I am doing wrong ?

Userlevel 4
Badge +36

UPDATE: this is only a partial solution; see my complete solution in the post below.

Your question reminded me of a 'Tree Data Structure', with nodes and links. I thought it might be possible to let FME make a graphical representation of this tree, and to process this information to create longer lines over the pseudo nodes (nodes that connect only 2 links), while keeping the node names.

This worked, in a workspace without loops.

My results stop or start at node B, as that node has more than 2 links.

lines_from_node_codes_resultslines_from_node_codes_workspaceSee the attached workspace.

Userlevel 4
Badge +36

A new day, a new idea.

You can 'hide' the loop in a recursive SQL query in an InlineQuerier, working back from the end nodes, and only keeping the paths that begin at a starting point.

determine_paths_with_SQL 

This works with paths of all depths, with more than one starting point in your data set, and even with paths that split and rejoin.

 

The magic occurs in the InlineQuerier:

WITH RECURSIVE Links_CTE(ID_EXT_A,Path) AS
    (
        -- initial select statement to get started
        -- this is only executed once
        -- in this case we are starting at the end nodes and working back
        SELECT "ID_EXT_A","ID_EXT_A"||','||"ID_EXT_B" FROM "Links" WHERE "EndNode" = 'Yes'
 
        -- merge those results with the following query
        UNION ALL
 
        -- recursive select statement
        -- executed repeatedly until there are no more results
        SELECT "Links"."ID_EXT_A","Links"."ID_EXT_A"||','||"Links_CTE"."Path"
            FROM "Links"
            JOIN "Links_CTE" ON "Links"."ID_EXT_B"= "Links_CTE"."ID_EXT_A"
    )
 
    -- now query the Links_CTE to produce results
    SELECT "Path" from "Links_CTE" where "ID_EXT_A" in (select "ID_EXT_A" from "Links" where "StartNode" = 'Yes')

Also see the attached workspace.

Reply