tsinghua-fib-lab / DRL-urban-planning

A deep reinforcement learning (DRL) based approach for spatial layout of land use and roads in urban communities. (Nature Computational Science)
https://rdcu.be/dlRPZ
MIT License
159 stars 33 forks source link

ValueError: Unknown hostname when initializing Config #7

Closed WilliamTianYe closed 5 months ago

WilliamTianYe commented 6 months ago

I’m really sorry; it might be due to my limited computer skills that I couldn’t solve this problem.

I am encountering a ValueError when trying to run the code on a cloud server. The get_file_path function in the codebase does not recognize the hostname of my cloud server environment, which leads to an exception. I have tried adding my server's hostname to the function, but the error persists.

Issue Description

When attempting to run the load_yaml function on a cloud server, the get_file_path function raises a ValueError due to an unrecognized hostname.

Environment

Could you please clarify what the correct root_dir setting should be in this situation?

Additionally, it appears that I was missing the urban_planning.train and urban_planning.eval modules, which are crucial to my current work. I have perused the repository but seem to be at a loss as to their location.

I apologize if the answers to these queries are obvious or if I have overlooked any details in the documentation. Your assistance would be greatly appreciated in helping me navigate these issues.

DavyMorgan commented 6 months ago

Thanks for pointing this out. The hostname is used for internal development only and I have updated it in this commit #(https://github.com/tsinghua-fib-lab/DRL-urban-planning/commit/5fc114100528eab66e11d58bb49cd400672dbf84). Now you don't need to specify the hostname anymore.

WilliamTianYe commented 6 months ago

/Thank you! I set the address in the code as follows:

sys.path.append('/root/DRL/DRL-urban-planning')
home_dir= '/root/DRL/DRL-urban-planning'
root_dir = '/root/DRL/DRL-urban-planning/urban_planning/cfg/test_data/real/dhm'

When I run the following code block:

id = 'dhm'
seed = 666
temp = False
cfg = Config(id, seed, temp, root_dir)
env = CityEnv(cfg)

Return an error message, the error message is as follows:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [14], in <cell line: 5>()
      3 temp = False
      4 cfg = Config(id, seed, temp, root_dir)
----> 5 env = CityEnv(cfg)

File ~/DRL/DRL-urban-planning/urban_planning/envs/city.py:130, in CityEnv.__init__(self, cfg, is_eval, reward_info_fn)
    128 self._frozen = False
    129 self._action_history = []
--> 130 self._plc = PlanClient(cfg.objectives_plan, cfg.init_plan)
    132 self._reward_info_fn = partial(reward_info_fn,
    133                                road_network_weight=cfg.reward_specs.get('road_network_weight', 1.0),
    134                                life_circle_weight=cfg.reward_specs.get('life_circle_weight', 1.0),
    135                                greenness_weight=cfg.reward_specs.get('greenness_weight', 1.0),
    136                                concept_weight=cfg.reward_specs.get('concept_weight', 0.0),
    137                                weight_by_area=cfg.reward_specs.get('weight_by_area', False))
    139 self._all_stages = ['land_use', 'road', 'done']

File ~/DRL/DRL-urban-planning/urban_planning/envs/plan_client.py:51, in PlanClient.__init__(self, objectives_plan_file, init_plan_file)
     49 self.init_objectives()
     50 self.init_constraints()
---> 51 self.restore_plan()

File ~/DRL/DRL-urban-planning/urban_planning/envs/plan_client.py:141, in PlanClient.restore_plan(self)
    139 self._initial_gdf = self.init_plan['gdf']
    140 self._gdf = copy.deepcopy(self._initial_gdf)
--> 141 self._add_domain_features()
    142 self._load_concept(self.init_plan.get('concept', list()))
    143 self._rule_constraints = self.init_plan.get('rule_constraints', False)

File ~/DRL/DRL-urban-planning/urban_planning/envs/plan_client.py:129, in PlanClient._add_domain_features(self)
    127 def _add_domain_features(self) -> None:
    128     """Adds domain features to the gdf."""
--> 129     self._gdf['rect'] = momepy.Rectangularity(self._gdf[self._gdf.geom_type == 'Polygon']).series
    130     self._gdf['eqi'] = momepy.EquivalentRectangularIndex(self._gdf[self._gdf.geom_type == 'Polygon']).series
    131     self._gdf['sc'] = momepy.SquareCompactness(self._gdf[self._gdf.geom_type == 'Polygon']).series

File ~/miniconda3/lib/python3.8/site-packages/momepy/shape.py:720, in Rectangularity.__init__(self, gdf, areas)
    718     areas = "mm_a"
    719 self.areas = gdf[areas]
--> 720 mrr = shapely.minimum_rotated_rectangle(gdf.geometry.array)
    721 mrr_area = shapely.area(mrr)
    722 self.series = gdf[areas] / mrr_area

File ~/miniconda3/lib/python3.8/site-packages/shapely/constructive.py:1034, in oriented_envelope(geometry, **kwargs)
   1032 else:
   1033     f = _oriented_envelope_geos
-> 1034 return f(geometry, **kwargs)

File ~/miniconda3/lib/python3.8/site-packages/shapely/algorithms/_oriented_envelope.py:22, in _oriented_envelope_min_area(geometry, **kwargs)
     20 if not hasattr(geometry, "geom_type"):
     21     return np.array([_oriented_envelope_min_area(g) for g in geometry])
---> 22 if geometry.is_empty:
     23     return shapely.from_wkt("POLYGON EMPTY")
     25 # first compute the convex hull

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

This error message indicates that when attempting to calculate the minimum rotated rectangle (oriented envelope) of a geometric object, the value of geometry.is_empty is an array rather than a single boolean. The is_empty attribute should be used to check if a single Shapely geometric object is empty, but here it appears that an array of multiple geometric objects from a GeoDataFrame is being passed.

How can I fix it? Thanks again!

DavyMorgan commented 6 months ago

/Thank you! I set the address in the code as follows:

sys.path.append('/root/DRL/DRL-urban-planning')
home_dir= '/root/DRL/DRL-urban-planning'
root_dir = '/root/DRL/DRL-urban-planning/urban_planning/cfg/test_data/real/dhm'

When I run the following code block:

id = 'dhm'
seed = 666
temp = False
cfg = Config(id, seed, temp, root_dir)
env = CityEnv(cfg)

Return an error message, the error message is as follows:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [14], in <cell line: 5>()
      3 temp = False
      4 cfg = Config(id, seed, temp, root_dir)
----> 5 env = CityEnv(cfg)

File ~/DRL/DRL-urban-planning/urban_planning/envs/city.py:130, in CityEnv.__init__(self, cfg, is_eval, reward_info_fn)
    128 self._frozen = False
    129 self._action_history = []
--> 130 self._plc = PlanClient(cfg.objectives_plan, cfg.init_plan)
    132 self._reward_info_fn = partial(reward_info_fn,
    133                                road_network_weight=cfg.reward_specs.get('road_network_weight', 1.0),
    134                                life_circle_weight=cfg.reward_specs.get('life_circle_weight', 1.0),
    135                                greenness_weight=cfg.reward_specs.get('greenness_weight', 1.0),
    136                                concept_weight=cfg.reward_specs.get('concept_weight', 0.0),
    137                                weight_by_area=cfg.reward_specs.get('weight_by_area', False))
    139 self._all_stages = ['land_use', 'road', 'done']

File ~/DRL/DRL-urban-planning/urban_planning/envs/plan_client.py:51, in PlanClient.__init__(self, objectives_plan_file, init_plan_file)
     49 self.init_objectives()
     50 self.init_constraints()
---> 51 self.restore_plan()

File ~/DRL/DRL-urban-planning/urban_planning/envs/plan_client.py:141, in PlanClient.restore_plan(self)
    139 self._initial_gdf = self.init_plan['gdf']
    140 self._gdf = copy.deepcopy(self._initial_gdf)
--> 141 self._add_domain_features()
    142 self._load_concept(self.init_plan.get('concept', list()))
    143 self._rule_constraints = self.init_plan.get('rule_constraints', False)

File ~/DRL/DRL-urban-planning/urban_planning/envs/plan_client.py:129, in PlanClient._add_domain_features(self)
    127 def _add_domain_features(self) -> None:
    128     """Adds domain features to the gdf."""
--> 129     self._gdf['rect'] = momepy.Rectangularity(self._gdf[self._gdf.geom_type == 'Polygon']).series
    130     self._gdf['eqi'] = momepy.EquivalentRectangularIndex(self._gdf[self._gdf.geom_type == 'Polygon']).series
    131     self._gdf['sc'] = momepy.SquareCompactness(self._gdf[self._gdf.geom_type == 'Polygon']).series

File ~/miniconda3/lib/python3.8/site-packages/momepy/shape.py:720, in Rectangularity.__init__(self, gdf, areas)
    718     areas = "mm_a"
    719 self.areas = gdf[areas]
--> 720 mrr = shapely.minimum_rotated_rectangle(gdf.geometry.array)
    721 mrr_area = shapely.area(mrr)
    722 self.series = gdf[areas] / mrr_area

File ~/miniconda3/lib/python3.8/site-packages/shapely/constructive.py:1034, in oriented_envelope(geometry, **kwargs)
   1032 else:
   1033     f = _oriented_envelope_geos
-> 1034 return f(geometry, **kwargs)

File ~/miniconda3/lib/python3.8/site-packages/shapely/algorithms/_oriented_envelope.py:22, in _oriented_envelope_min_area(geometry, **kwargs)
     20 if not hasattr(geometry, "geom_type"):
     21     return np.array([_oriented_envelope_min_area(g) for g in geometry])
---> 22 if geometry.is_empty:
     23     return shapely.from_wkt("POLYGON EMPTY")
     25 # first compute the convex hull

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

This error message indicates that when attempting to calculate the minimum rotated rectangle (oriented envelope) of a geometric object, the value of geometry.is_empty is an array rather than a single boolean. The is_empty attribute should be used to check if a single Shapely geometric object is empty, but here it appears that an array of multiple geometric objects from a GeoDataFrame is being passed.

How can I fix it? Thanks again!

I haven't met this error before. Can you provide the package version numbers? Please first check whether the package version numbers match the specified ones in requirements.txt.

In addition, it seems like the gdf contains certain multi-polygons?

WilliamTianYe commented 6 months ago

Thanks for your advice!

I have carefully checked all package version numbers, and they all meet the requirements specified in requirements.txt.

Additionally, I have not uploaded any of my own files and have used only the default existing files. I think the issue stems from my not correctly setting up the various file paths, as the paths in the demo.ipynb file are all the local addresses you used and have not yet been converted to the relative addresses after the upload. Could you please help me confirm if my setup of these paths is correct?

sys.path.append('/root/DRL/DRL-urban-planning')
home_dir= '/root/DRL/DRL-urban-planning'
root_dir = '/root/DRL/DRL-urban-planning/urban_planning/cfg/test_data/real/dhm'
DavyMorgan commented 6 months ago

home_dir is not used in the code, thus you can safely remove it and I think you can use the following paths:

sys.path.append('/root/DRL/DRL-urban-planning')
root_dir = '/root/DRL'
WilliamTianYe commented 6 months ago

Thank you for your help. I have updated the file paths as suggested. However, when I run the code block mentioned earlier:

id = 'dhm'
seed = 666
temp = False
cfg = Config(id, seed, temp, root_dir)
env = CityEnv(cfg)

I am still getting the same error message as before.

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [3], in <cell line: 5>()
      3 temp = False
      4 cfg = Config(id, seed, temp, root_dir)
----> 5 env = CityEnv(cfg)

File ~/DRL/DRL-urban-planning/urban_planning/envs/city.py:130, in CityEnv.__init__(self, cfg, is_eval, reward_info_fn)
    128 self._frozen = False
    129 self._action_history = []
--> 130 self._plc = PlanClient(cfg.objectives_plan, cfg.init_plan)
    132 self._reward_info_fn = partial(reward_info_fn,
    133                                road_network_weight=cfg.reward_specs.get('road_network_weight', 1.0),
    134                                life_circle_weight=cfg.reward_specs.get('life_circle_weight', 1.0),
    135                                greenness_weight=cfg.reward_specs.get('greenness_weight', 1.0),
    136                                concept_weight=cfg.reward_specs.get('concept_weight', 0.0),
    137                                weight_by_area=cfg.reward_specs.get('weight_by_area', False))
    139 self._all_stages = ['land_use', 'road', 'done']

File ~/DRL/DRL-urban-planning/urban_planning/envs/plan_client.py:51, in PlanClient.__init__(self, objectives_plan_file, init_plan_file)
     49 self.init_objectives()
     50 self.init_constraints()
---> 51 self.restore_plan()

File ~/DRL/DRL-urban-planning/urban_planning/envs/plan_client.py:141, in PlanClient.restore_plan(self)
    139 self._initial_gdf = self.init_plan['gdf']
    140 self._gdf = copy.deepcopy(self._initial_gdf)
--> 141 self._add_domain_features()
    142 self._load_concept(self.init_plan.get('concept', list()))
    143 self._rule_constraints = self.init_plan.get('rule_constraints', False)

File ~/DRL/DRL-urban-planning/urban_planning/envs/plan_client.py:129, in PlanClient._add_domain_features(self)
    127 def _add_domain_features(self) -> None:
    128     """Adds domain features to the gdf."""
--> 129     self._gdf['rect'] = momepy.Rectangularity(self._gdf[self._gdf.geom_type == 'Polygon']).series
    130     self._gdf['eqi'] = momepy.EquivalentRectangularIndex(self._gdf[self._gdf.geom_type == 'Polygon']).series
    131     self._gdf['sc'] = momepy.SquareCompactness(self._gdf[self._gdf.geom_type == 'Polygon']).series

File ~/miniconda3/lib/python3.8/site-packages/momepy/shape.py:720, in Rectangularity.__init__(self, gdf, areas)
    718     areas = "mm_a"
    719 self.areas = gdf[areas]
--> 720 mrr = shapely.minimum_rotated_rectangle(gdf.geometry.array)
    721 mrr_area = shapely.area(mrr)
    722 self.series = gdf[areas] / mrr_area

File ~/miniconda3/lib/python3.8/site-packages/shapely/constructive.py:1034, in oriented_envelope(geometry, **kwargs)
   1032 else:
   1033     f = _oriented_envelope_geos
-> 1034 return f(geometry, **kwargs)

File ~/miniconda3/lib/python3.8/site-packages/shapely/algorithms/_oriented_envelope.py:22, in _oriented_envelope_min_area(geometry, **kwargs)
     20 if not hasattr(geometry, "geom_type"):
     21     return np.array([_oriented_envelope_min_area(g) for g in geometry])
---> 22 if geometry.is_empty:
     23     return shapely.from_wkt("POLYGON EMPTY")
     25 # first compute the convex hull

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

image

DavyMorgan commented 5 months ago

I rerun the demo script and I can successfully load the plan. I guess it might be due to some package mismatch issues. Here I list my version numbers for the most critical packages:

>>> shapely.__version__
'1.8.4'
>>> geopandas.__version__
'0.11.1'
>>> libpysal.__version__
'4.6.2'
>>> momepy.__version__
'0.5.3'

Could you please use the same version of packages and give it another try?

WilliamTianYe commented 5 months ago

Thank you! After ensuring that I was using same of packages, the error longer.