Does "the number of connections upstream" of "pipe segment X" mean the number of pipe segments which touch the start node of the "pipe segment X" at their end nodes?
Â
Â
Really the task is to extract that part of the network upstream of the original segment, after which counting is fairly easy. I think you can do this by NetworkTopologyCounter and leaving out the pipe segment that is being worked on. Then you get a set of networks, one of which will be the part upstream of the original segment.
How to find which network? Well I'd take the start point (or end point depending on the direction) of the original pipe segment, do an overlay, and find out what network ID the line has. A simple test or merge removes all other networks and then a Counter/StatsCounter tells you how many features there are.
So here I have a network of streams. The one marked with a red line is my "pipe segment"...
And here's my workspace:
With this I can isolate the network upstream of the original segment and count that there are 8 line segments.
I'm not sure what counts as a "connection" for you. If it's the number of pipe segments, then this is your answer. If it's a connection at the end of each pipe, then the number of connections is the number of lines plus one. To be absolutely certain you could run it through the TopologyBuilder and count the number of nodes. Or count the number of vertices in a pipe using the VertexCounter.
Anyway, however you want to count, I think the important part is isolating that part of the network, and I think this method will do that fairly well.
Here's my workspace if it's of help. I picked the original segment using a Counter/Tester, but obviously you'd select it using an ID of some sort.
No, it's the number of houses connected to that pipe that I want to keep adding as an attribute.
If I have 2 pipes; one that supplies water to 10 houses and one that supplies water to 100 - all other things being equal - I need to fix the one that supplies 100 houses first.
No, it's the number of houses connected to that pipe that I want to keep adding as an attribute.
If I have 2 pipes; one that supplies water to 10 houses and one that supplies water to 100 - all other things being equal - I need to fix the one that supplies 100 houses first.
Right, so how do you know how many houses connect to a pipe? Is it an attribute on the pipe, or a line that connects pipe to house? So are all line endpoints houses? Or every vertex on the pipe? Or is there a connection point feature? If it's just a pipe with no attributes, no connections to houses, or no junction point features, then I guess all you can do is put a buffer around it and overlay against address points.
Â
Â
Not sure how well, or performant it would be on a real network but.
Assuming your network is something like this, with an attribute with number of houses of that supply pipe.
Extract every start point of network and create line with final end point. Use ShortestPathFinder to get every path from start to finish. LineOnLine Overlayer to find overlapping segments, accumulate your house count into a list, sum the list to find number of houses upstream
count-upstream.fmwt
I think the workflow @egomm suggested (just remove the AttributeCreator_2) would generate your desired result, if the lines form a dendritic network (i.e. not contain a closed circuit).
Â
Alternatively, Python scripting in conjunction with some transformers could be effective. Assuming that all the lines orient to downstream and have a unique ID attribute called "pipe_id":
count-upstream-python.fmwt  (FME 2018.1.0.2)
Â
Â
PythonCaller Script:
Â
import fmeimport fmeobjectsclass UpstreamHousesAccumulator(object):    def __init__(self):        self.idToFeature = {}            def input(self, feature):        id = str(feature.getAttribute('pipe_id'))        feature.removeAttribute('total')        self.idToFeature=id] = feature            def close(self):        for feature in self.idToFeature.values():            self.setTotal(feature)            self.pyoutput(feature)                def setTotal(self, feature):        _, isMissing, _ = feature.getAttributeNullMissingAndType('total')        if isMissing:            n = int(feature.getAttribute('houses'))            upstreamIds = feature.getAttribute('_relationships{}.pipe_id')            if upstreamIds:                for id in upstreamIds:                    upstream = self.idToFeature id]                    self.setTotal(upstream) # recursive call                    n += upstream.getAttribute('total')            feature.setAttribute('total', n)
Not sure how well, or performant it would be on a real network but.
Assuming your network is something like this, with an attribute with number of houses of that supply pipe.
Extract every start point of network and create line with final end point. Use ShortestPathFinder to get every path from start to finish. LineOnLine Overlayer to find overlapping segments, accumulate your house count into a list, sum the list to find number of houses upstream
count-upstream.fmwt
I think the workflow @egomm suggested (just remove the AttributeCreator_2) would generate your desired result, if the lines form a dendritic network (i.e. not contain a closed circuit).
Â
Alternatively, Python scripting in conjunction with some transformers could be effective. Assuming that all the lines orient to downstream and have a unique ID attribute called "pipe_id":
count-upstream-python.fmwt  (FME 2018.1.0.2)
Â
Â
PythonCaller Script:
Â
import fmeimport fmeobjectsclass UpstreamHousesAccumulator(object):    def __init__(self):        self.idToFeature = {}            def input(self, feature):        id = str(feature.getAttribute('pipe_id'))        feature.removeAttribute('total')        self.idToFeature id] = feature            def close(self):        for feature in self.idToFeature.values():            self.setTotal(feature)            self.pyoutput(feature)                def setTotal(self, feature):        _, isMissing, _ = feature.getAttributeNullMissingAndType('total')        if isMissing:            n = int(feature.getAttribute('houses'))            upstreamIds = feature.getAttribute('_relationships{}.pipe_id')            if upstreamIds:                for id in upstreamIds:                    upstream = self.idToFeaturenid]                    self.setTotal(upstream) # recursive call                    n += upstream.getAttribute('total')            feature.setAttribute('total', n)
I think the workflow @egomm suggested (just remove the AttributeCreator_2) would generate your desired result, if the lines form a dendritic network (i.e. not contain a closed circuit).
Â
Alternatively, Python scripting in conjunction with some transformers could be effective. Assuming that all the lines orient to downstream and have a unique ID attribute called "pipe_id":
count-upstream-python.fmwt  (FME 2018.1.0.2)
Â
Â
PythonCaller Script:
Â
import fmeimport fmeobjectsclass UpstreamHousesAccumulator(object):    def __init__(self):        self.idToFeature = {}            def input(self, feature):        id = str(feature.getAttribute('pipe_id'))        feature.removeAttribute('total')        self.idToFeature=id] = feature            def close(self):        for feature in self.idToFeature.values():            self.setTotal(feature)            self.pyoutput(feature)                def setTotal(self, feature):        _, isMissing, _ = feature.getAttributeNullMissingAndType('total')        if isMissing:            n = int(feature.getAttribute('houses'))            upstreamIds = feature.getAttribute('_relationships{}.pipe_id')            if upstreamIds:                for id in upstreamIds:                    upstream = self.idToFeature id]                    self.setTotal(upstream) # recursive call                    n += upstream.getAttribute('total')            feature.setAttribute('total', n)
Another approach, using global variables:Â
count-upstream-variables.fmwt (FME 2018.1.0.2)
I think the workflow @egomm suggested (just remove the AttributeCreator_2) would generate your desired result, if the lines form a dendritic network (i.e. not contain a closed circuit).
Â
Alternatively, Python scripting in conjunction with some transformers could be effective. Assuming that all the lines orient to downstream and have a unique ID attribute called "pipe_id":
count-upstream-python.fmwt  (FME 2018.1.0.2)
Â
Â
PythonCaller Script:
Â
import fmeimport fmeobjectsclass UpstreamHousesAccumulator(object):    def __init__(self):        self.idToFeature = {}            def input(self, feature):        id = str(feature.getAttribute('pipe_id'))        feature.removeAttribute('total')        self.idToFeature=id] = feature            def close(self):        for feature in self.idToFeature.values():            self.setTotal(feature)            self.pyoutput(feature)                def setTotal(self, feature):        _, isMissing, _ = feature.getAttributeNullMissingAndType('total')        if isMissing:            n = int(feature.getAttribute('houses'))            upstreamIds = feature.getAttribute('_relationships{}.pipe_id')            if upstreamIds:                for id in upstreamIds:                    upstream = self.idToFeature id]                    self.setTotal(upstream) # recursive call                    n += upstream.getAttribute('total')            feature.setAttribute('total', n)
Takashi, how would look this python script if the house would have an address, and multiple addresses are associated as a list to each segment. is it possible that the output to be an accumulated list of addresses?
Takashi, how would look this python script if the house would have an address, and multiple addresses are associated as a list to each segment. is it possible that the output to be an accumulated list of addresses?
Hi @cipriancu,
This seems to be an older thread that you've posted to. Would you be open to posting a new question with your scenario for better visibility? You can always link back to this one in your new post. There's been a lot of development in FME since the 2018 version so there might be some new ways to tackle this potentially without using python even. Thanks!