worldbank / GOSTnets

Convenience wrapper for networkx analysis using geospatial information, focusing on OSM
https://worldbank.github.io/GOSTnets/
MIT License
24 stars 15 forks source link

Salting function sucks at creating edges #15

Open andresfchamorro opened 4 years ago

andresfchamorro commented 4 years ago

Our salting function salt_long_lines isn't working properly as noted by @rbanick. I've looked into this and will commit some changes to fix it.

  1. Nodes are salted correctly, but long edges are dropped in the resulting graph, which means that "salted" edges are not being created correctly. The part of the script that re-adds salted edges is in a try statement, so errors in the edge creation / data attribution are not being captured.

  2. The function is also projecting every edge one by one. Fixing that will make it run a lot quicker.

On a related note, I was testing this with a graph with edges that contained lists [] in their wkt attribute. This is a product of the clean network function. Adding rectify geometry after the second custom_simplify should fix this.

rbanick commented 4 years ago

Better AND faster? My hero!

andresfchamorro commented 4 years ago

i pushed some changes, let me know if it fails https://github.com/worldbank/GOSTnets/commit/b54d645499bb9227d474b1f16d20d12b84fd2b72

rbanick commented 4 years ago

I'm now getting the following error when I run gn.salt_long_lines:

TypeError                                 Traceback (most recent call last)
<ipython-input-30-0711ec240991> in <module>
      6                               thresh = 500,
      7                               factor = 1000,
----> 8                               attr_list = ['infra_type','osm_id','Type','iri'])

~\.conda\envs\test\lib\site-packages\gostnets-1.0.1-py3.6.egg\GOSTnets\core.py in salt_long_lines(G, source, target, thresh, factor, attr_list)
   1539 
   1540     G2 = G.copy()
-> 1541     edges = edge_gdf_from_graph(G2, geometry_tag = 'Wkt')
   1542     edges_projected = edges.to_crs(target)
   1543     nodes_projected = node_gdf_from_graph(G).to_crs(target).set_index('node_ID')

~\.conda\envs\test\lib\site-packages\gostnets-1.0.1-py3.6.egg\GOSTnets\core.py in edge_gdf_from_graph(G, crs, attr_list, geometry_tag, xCol, yCol)
    276     edges_df = edges_df[['stnode','endnode',*attr_list,geometry_tag]]
    277     if type(edges_df.iloc[0][geometry_tag]) == str:
--> 278         edges_df[geometry_tag] = edges_df[geometry_tag].apply(loads)
    279     edges_gdf = gpd.GeoDataFrame(edges_df, geometry = geometry_tag, crs = crs)
    280 

~\.conda\envs\test\lib\site-packages\pandas\core\series.py in apply(self, func, convert_dtype, args, **kwds)
   3846             else:
   3847                 values = self.astype(object).values
-> 3848                 mapped = lib.map_infer(values, f, convert=convert_dtype)
   3849 
   3850         if len(mapped) and isinstance(mapped[0], Series):

pandas\_libs\lib.pyx in pandas._libs.lib.map_infer()

~\.conda\envs\test\lib\site-packages\shapely\wkt.py in loads(data)
      8 def loads(data):
      9     """Load a geometry from a WKT string."""
---> 10     return geos.WKTReader(geos.lgeos).read(data)
     11 
     12 def load(fp):

~\.conda\envs\test\lib\site-packages\shapely\geos.py in read(self, text)
    277         """Returns geometry from WKT"""
    278         if not isinstance(text, text_types):
--> 279             raise TypeError("Only str is accepted.")
    280         if sys.version_info[0] >= 3:
    281             text = text.encode()

TypeError: Only str is accepted.

This is after loading in and running gn.clean_network on the latest Bangladesh OSM data, filtered to Cox's Bazar.

andresfchamorro commented 4 years ago

ahh, i thought i had tested this. I made a small change, try now

rbanick commented 4 years ago

It ran for a while, much longer than before, saying...

Identified 5738 unique edge(s) longer than 500. 
Beginning new node creation...

Then it kicked out this error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-0711ec240991> in <module>
      6                               thresh = 500,
      7                               factor = 1000,
----> 8                               attr_list = ['infra_type','osm_id','Type','iri'])

~\.conda\envs\test\lib\site-packages\gostnets-1.0.1-py3.6.egg\GOSTnets\core.py in salt_long_lines(G, source, target, thresh, factor, attr_list)
   1640             result = cut(geom_to_split, (thresh))
   1641 
-> 1642             t_geom = transform(project_UTM_WGS, result[0])
   1643 
   1644             edge_data = {'Wkt' : t_geom,

TypeError: 'NoneType' object is not subscriptable