Bottom Page

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
 Finding nearest point of a Multidigraph in Python 3.7
#1
I have two point layers, one with bus stops and train stations, and another with playground centrepoints.
From QGIS I created a cleaned up network containing roads and footpaths, which I have converted to a multidigraph in Python. This so I can loop through each bus/train station and find the network to the playground point, if there is one.

The problem is trying to get the closest edge node to the playground spits out an error.

path = "C:\\........\\Footpath_Roads_Extended_Python.shp"
def read_multi_shp(path): #create multidigraph
    """
    copied from read_shp, but allowing MultiDiGraph instead.
    """
    try:
        from osgeo import ogr
    except ImportError:
        raise ImportError("read_shp requires OGR: http://www.gdal.org/")

    net = nx.MultiDiGraph()

    def getfieldinfo(lyr, feature, flds):
            f = feature
            return [f.GetField(f.GetFieldIndex(x)) for x in flds]

    def addlyr(lyr, fields):
        for findex in range(lyr.GetFeatureCount()):
            f = lyr.GetFeature(findex)
            flddata = getfieldinfo(lyr, f, fields)
            g = f.geometry()
            attributes = dict(zip(fields, flddata))
            attributes["ShpName"] = lyr.GetName()
            if g.GetGeometryType() == 1:  # point
                net.add_node((g.GetPoint_2D(0)), attributes)
            if g.GetGeometryType() == 2:  # linestring
                attributes["Wkb"] = g.ExportToWkb()
                attributes["Wkt"] = g.ExportToWkt()
                attributes["Json"] = g.ExportToJson()
                last = g.GetPointCount() - 1
                net.add_edge(g.GetPoint_2D(0), g.GetPoint_2D(last), attr_dict=attributes)

    if isinstance(path, str):
        shp = ogr.Open(path)
        lyrcount = shp.GetLayerCount()
        for lyrindex in range(lyrcount):
            lyr = shp.GetLayerByIndex(lyrindex)
            flds = [x.GetName() for x in lyr.schema]
            addlyr(lyr, flds)
	
    return net

H=read_multi_shp(path)

PTV_Playground_Shortest_Path_300_400 = []
while i < len(PTV_Playground_Joined_initial): #loop through playgrounds and find nearest path node

	orig_xy = (df.loc[i,"PTV_N"], "-"+df.loc[i,"PTV_E"])

	target_xy = (df.loc[i,"Playgroun1"], df.loc[i,"Playground"])
	
	orig_node = ox.get_nearest_node(H, orig_xy, method='euclidean') #H seems to cause the error.................
The error I receive is

Traceback (most recent call last):
  File "C:\Users\geogjo\Desktop\PythonTraining\Network_Analysis_Test.py", line 100, in <module>
    orig_node = ox.get_nearest_node(H, orig_xy, method='euclidean')
  File "C:\Users\geogjo\AppData\Local\Continuum\anaconda3\lib\site-packages\osmnx\utils.py", line 461, in get_nearest_node
    coords = [[node, data['x'], data['y']] for node, data in G.nodes(data=True)]
  File "C:\Users\geogjo\AppData\Local\Continuum\anaconda3\lib\site-packages\osmnx\utils.py", line 461, in <listcomp>
    coords = [[node, data['x'], data['y']] for node, data in G.nodes(data=True)]
KeyError: 'x'
I snapped all linework to itself to keep it as simple as possible. When I test the type it says it's a multidigraph.
Yes you can use QGIS shortest path tools but only if you have one end point or one start point. This has many start and end points so I will be looping through each.
Quote
#2
The error tells you that there is no key 'x' in data which you get from G.nodes()
So i would look what i get back from G.nodes()
Quote
#3
When I print the multi-digraph that is being passed into this function it looks like the following...

[(327688.2817133684, 5739552.011543424), (341508.08128750307, 5767378.745506252), (341481.1308291708, 5767277.219589586), (341364.9730373633, 5767271.420884848), (341364.8637279594, 5767271.415428021), (341374.82312183146, 5767212.4025153965) etc.....

Does this look correct. The error is coming from utils.
Quote
#4
I can´t tell you, i don´t know.
You are calling ox.get_nearest_node(H, orig_xy, method='euclidean') and then you get the error.

So either parameter H, which comes from H = read_multi_shp(path)
or orig_xy which comes from orig_xy = (df.loc[i, "PTV_N"], "-" + df.loc[i, "PTV_E"]) is faulty.
I would guess it´s the building of orig_xy, are you sure about the part above marked red?
Quote
#5
It is coming from H. It looks like I need to add keys for X and Y with the corresponding values. At the moment it is just coordinates i.e. (1,2) without a key value, whereas I think it should be (X:1, Y:2). How can I do that in a multidigraph created from a shp?
Quote
#6
H = [(1,2), (2,3), (1,3), (3,2), (3,4)]

new_H = {'x': [], 'y': []}
for x, y in H:
    new_H['x'].append(x)
    new_H['y'].append(y)

print(new_H)

# {'x': [1, 2, 1, 3, 3], 'y': [2, 3, 3, 2, 4]}
Quote

Top Page

Possibly Related Threads...
Thread Author Replies Views Last Post
  connecting the first point to the last point Matplotlib omar_mohsen 0 88 Jan-15-2020, 01:23 PM
Last Post: omar_mohsen
  finding the closest floating point number in a list Skaperen 17 872 Sep-19-2019, 10:39 PM
Last Post: Skaperen
  finding the next higher representable floating point value Skaperen 0 437 Sep-13-2019, 11:16 PM
Last Post: Skaperen
  find nearest number d3fi 7 543 Aug-26-2019, 09:32 PM
Last Post: ichabod801
  finding 2 max values in an array in python Akankshha 11 1,754 Oct-18-2018, 09:16 AM
Last Post: perfringo
  Trouble finding Python code Larz60+ 5 1,698 Jun-02-2017, 01:30 PM
Last Post: sparkz_alot

Forum Jump:


Users browsing this thread: 1 Guest(s)