Geopandas与UrbanAccess的OSM下载报错问题求助
UrbanAccess加载OSM数据报错:ValueError: Assigning CRS to a GeoDataFrame without a geometry column
问题详情
- 环境:Python入门学习者,Geopandas 0.12.2,使用UrbanAccess库
- 执行代码:
nodes, edges = urbanaccess.osm.load.ua_network_from_bbox(bbox=bbox, remove_lcn=True)
- 报错堆栈:
C:\Anaconda\lib\site-packages\geopandas\geodataframe.py:202: UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html#attribute-access super().__setattr__(attr, val) --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) C:\Anaconda\lib\site-packages\geopandas\geodataframe.py in crs(self) 430 try: ---> 431 return self.geometry.crs 432 except AttributeError: C:\Anaconda\lib\site-packages\pandas\core\generic.py in __getattr__(self, name) 5574 return self[name] -> 5575 return object.__getattribute__(self, name) 5576 C:\Anaconda\lib\site-packages\geopandas\geodataframe.py in _get_geometry(self) 231 ---> 232 raise AttributeError(msg) 233 return self[self._geometry_column_name] AttributeError: You are calling a geospatial method on the GeoDataFrame, but the active geometry column ('geometry') is not present. There are no existing columns with geometry data type. You can add a geometry column as the active geometry column with df.set_geometry. During handling of the above exception, another exception occurred: AttributeError Traceback (most recent call last) C:\Anaconda\lib\site-packages\pandas\core\generic.py in __setattr__(self, name, value) 5599 try: -> 5600 existing = getattr(self, name) 5601 if isinstance(existing, Index): C:\Anaconda\lib\site-packages\pandas\core\generic.py in __getattr__(self, name) 5574 return self[name] -> 5575 return object.__getattribute__(self, name) 5576 C:\Anaconda\lib\site-packages\geopandas\geodataframe.py in crs(self) 432 except AttributeError: ---> 433 raise AttributeError( 434 "The CRS attribute of a GeoDataFrame without an active " AttributeError: The CRS attribute of a GeoDataFrame without an active geometry column is not defined. Use GeoDataFrame.set_geometry to set the active geometry column. During handling of the above exception, another exception occurred: ValueError Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_19732\129358322.py in <module> ----> 1 nodes, edges = ua.osm.load.ua_network_from_bbox(bbox=bbox, 2 remove_lcn=True) C:\Anaconda\lib\site-packages\urbanaccess\osm\load.py in ua_network_from_bbox(lat_min, lng_min, lat_max, lng_max, bbox, network_type, timeout, memory, max_query_area_size, remove_lcn) 74 two_way = False 75 ---> 76 nodes, edges = network_from_bbox(lat_min=lat_min, lng_min=lng_min, 77 lat_max=lat_max, lng_max=lng_max, 78 bbox=bbox, network_type=network_type, C:\Anaconda\lib\site-packages\osmnet\load.py in network_from_bbox(lat_min, lng_min, lat_max, lng_max, bbox, network_type, two_way, timeout, memory, max_query_area_size, custom_osm_filter) 844 'lat_min, lng_min, lat_max, and lng_max must be floats' 845 ---> 846 nodes, ways, waynodes = ways_in_bbox( 847 lat_min=lat_min, lng_min=lng_min, lat_max=lat_max, lng_max=lng_max, 848 network_type=network_type, timeout=timeout, C:\Anaconda\lib\site-packages\osmnet\load.py in ways_in_bbox(lat_min, lng_min, lat_max, lng_max, network_type, timeout, memory, max_query_area_size, custom_osm_filter) 648 """ 649 return parse_network_osm_query( ---> 650 osm_net_download(lat_max=lat_max, lat_min=lat_min, lng_min=lng_min, 651 lng_max=lng_max, network_type=network_type, 652 timeout=timeout, memory=memory, C:\Anaconda\lib\site-packages\osmnet\load.py in osm_net_download(lat_min, lng_min, lat_max, lng_max, network_type, timeout, memory, max_query_area_size, custom_osm_filter) 135 polygon = Polygon([(lng_max, lat_min), (lng_min, lat_min), 136 (lng_min, lat_max), (lng_max, lat_max)]) ---> 137 geometry_proj, crs_proj = project_geometry(polygon, 138 crs={'init': 'epsg:4326'}) 139 C:\Anaconda\lib\site-packages\osmnet\load.py in project_geometry(geometry, crs, to_latlong) 443 """ 444 gdf = gpd.GeoDataFrame() ---> 445 gdf.crs = crs 446 gdf.name = 'geometry to project' 447 gdf['geometry'] = None C:\Anaconda\lib\site-packages\geopandas\geodataframe.py in __setattr__(self, attr, val) 200 object.__setattr__(self, attr, val) 201 else: ---> 202 super().__setattr__(attr, val) 203 204 def _get_geometry(self): C:\Anaconda\lib\site-packages\pandas\core\generic.py in __setattr__(self, name, value) 5614 stacklevel=find_stack_level(), 5615 ) -> 5616 object.__setattr__(self, name, value) 5617 5618 @final C:\Anaconda\lib\site-packages\geopandas\geodataframe.py in crs(self, value) 441 """Sets the value of the crs""" 442 if self._geometry_column_name not in self: ---> 443 raise ValueError( 444 "Assigning CRS to a GeoDataFrame without a geometry column is not " 445 "supported. Use GeoDataFrame.set_geometry to set the active " ValueError: Assigning CRS to a GeoDataFrame without a geometry column is not supported. Use GeoDataFrame.set_geometry to set the active geometry column.
- 排查动作:移除了之前添加的将int64日期列转为object类型的代码,错误仍未消除。
问题原因
这个错误源于UrbanAccess依赖的osmnet库中的project_geometry函数写法与Geopandas 0.12.2版本不兼容。Geopandas 0.12+版本新增校验规则:必须先给GeoDataFrame添加geometry列,才能设置CRS,但旧版osmnet的代码先创建空GeoDataFrame就直接设置CRS,触发了新版本的限制。
解决方法
方法1:降级Geopandas到兼容版本
将Geopandas降级到0.11.x版本(该版本允许为空GeoDataFrame设置CRS),执行以下命令:
pip install geopandas==0.11.1
方法2:修改osmnet源码(临时修复)
找到Python环境中osmnet/load.py文件,定位到project_geometry函数(约443行),替换原有代码:
原代码:
gdf = gpd.GeoDataFrame() gdf.crs = crs gdf.name = 'geometry to project' gdf['geometry'] = None
修改为:
gdf = gpd.GeoDataFrame({'geometry': [geometry]}) gdf.crs = crs gdf.name = 'geometry to project'
修改后保存文件,重新运行代码即可。
方法3:等待官方更新
若不想修改源码或降级,可关注UrbanAccess或osmnet的官方仓库,等待发布兼容Geopandas 0.12+的版本。
内容的提问来源于stack exchange,提问作者Kloot Zak
相关产品推荐
相关产品推荐

