From b9b5783804baadf39e12870e1b4608a7d0a096e7 Mon Sep 17 00:00:00 2001 From: jeronimol Date: Thu, 19 Dec 2024 13:24:38 -0500 Subject: [PATCH 1/3] updated h3 to 4.1.2 --- README.md | 13 +++++++------ urbanpy/geom/geom.py | 12 +++++++----- urbanpy/utils/utils.py | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 8c49937..0aa090a 100644 --- a/README.md +++ b/README.md @@ -48,25 +48,25 @@ $ pip install urbanpy Then use `import urbanpy` in your python scripts to use the library. -If you plan to use the [OSRM Server](http://project-osrm.org/) route or distance matrix calculation functionalities* you must have Docker installed in your system, refer to Docker [Installation](https://www.docker.com/products/docker-desktop). For Windows users, make sure to run the following command in powershell to avoid execution errors. +If you plan to use the [OSRM Server](http://project-osrm.org/) route or distance matrix calculation functionalities\* you must have Docker installed in your system, refer to Docker [Installation](https://www.docker.com/products/docker-desktop). For Windows users, make sure to run the following command in powershell to avoid execution errors. ```powershell Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser ``` - ### Additional Dependecies Notes - It is important to note that for travel time computation, if needed, a method is implements the Open Source Routing Machine (OSRM). This method pulls, extracts and adds graph weights to the downloaded network and runs the routing server. Make sure to have docker installed for the library to work correctly. Also, verify in the docker settings that containers can use the necessary cpu cores and ram memory (it depends in the country size). -- Urbanpy provides a simple approximation with nearest neighbor search using a BallTree and haversine distance, but the difference between real travel time and the approximation may vary from city to city. +- Urbanpy provides a simple approximation with nearest neighbor search using a BallTree and haversine distance, but the difference between real travel time and the approximation may vary from city to city. - Additionally, the use of spatial libraries like osmnx, geopandas and h3 require certain extra packages. Specifically, for rtree (spatial indexing to allow spatial joins) libspatialindex is required. OSMnx and Geopandas requiere GDAL as well. If not handled by installing geopandas's dependencies, installing fiona, pyproj and shapely should satisfy the requirements. Another way to ensure all dependencies are met, installing osmnx via conda should suffice. H3 requires cc, make, and cmake in your $PATH when installing, otherwise installation will not be successful. Please refer to [h3's documentation](https://github.com/uber/h3) for a more -detailed guide on installation options and requirements. + detailed guide on installation options and requirements. # Examples UrbanPy lets you download and visualize city boundaries extremely easy: + ```python import urbanpy as up @@ -77,7 +77,7 @@ boundaries.plot() Since `boundaries` is a GeoDataFrame it can be easily plotted with the method `.plot()`. You can also generate hexagons to fill the city boundaries in a oneliner. ```python -hexs, hexs_centroids = up.geom.gen_hexagons(resolution=9, city=boundaries) +hexes = up.geom.gen_hexagons(resolution=9, city=boundaries) ``` Also check our [example notebooks](https://nbviewer.org/github/EL-BID/urbanpy/tree/master/notebooks/), and if you have examples or visualizations of your own, we encourage you to share contribute. @@ -114,7 +114,7 @@ UrbanPy's original authors are Claudio Ortega ([socials](https://www.linkedin.co [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.** -*Current support is tested on Linux Ubuntu 18.04 & Mac OS Catalina, coming soon we will test and support Windows 10. +\*Current support is tested on Linux Ubuntu 18.04 & Mac OS Catalina, coming soon we will test and support Windows 10. ## Citation @@ -141,6 +141,7 @@ If you use this library or find the documentation useful for your research, plea ## Use Cases + [Urbanpy applied to the education sector in Brasil](https://github.com/EL-BID/IADB-education-1) This repo is for code, documentation, and discussion for work associated with a skills-based volunteering project in collaboration with the IADB and urbanpy. diff --git a/urbanpy/geom/geom.py b/urbanpy/geom/geom.py index 05d1a3d..4fe0abd 100644 --- a/urbanpy/geom/geom.py +++ b/urbanpy/geom/geom.py @@ -1,10 +1,11 @@ import pandas as pd import geopandas as gpd import osmnx as ox -from h3 import h3 +import h3 from rich.progress import track from urbanpy.utils import geo_boundary_to_polygon from typing import Sequence, Union +import shapely __all__ = [ "merge_geom_downloads", @@ -167,11 +168,12 @@ def gen_hexagons(resolution: int, city: gpd.GeoDataFrame) -> gpd.GeoDataFrame: total = len(city_poly) # For rich library to how much progress is needed for _, geo in track(city_poly.iterrows(), total=total): - hexagons = h3.polyfill( - geo["geometry"].__geo_interface__, res=resolution, geo_json_conformant=True - ) + hexagons = h3.geo_to_cells(geo["geometry"], res=resolution) for hexagon in hexagons: - h3_polygons.append(geo_boundary_to_polygon(hexagon)) + lat_lng_points = h3.cell_to_boundary(hexagon) + lng_lat_points = [(lng, lat) for lat, lng in lat_lng_points] + + h3_polygons.append(shapely.Polygon(lng_lat_points)) h3_indexes.append(hexagon) # Create hexagon dataframe diff --git a/urbanpy/utils/utils.py b/urbanpy/utils/utils.py index 71334d8..578ab46 100644 --- a/urbanpy/utils/utils.py +++ b/urbanpy/utils/utils.py @@ -5,7 +5,7 @@ import numpy as np import pandas as pd from geopandas import GeoDataFrame, GeoSeries -from h3 import h3 +import h3 from pandas import DataFrame from shapely.geometry import MultiPolygon, Polygon from shapely.validation import make_valid From 971d8fb8b1bf09352ee248e33fcfc264f86ef3e9 Mon Sep 17 00:00:00 2001 From: jeronimol Date: Thu, 19 Dec 2024 13:34:43 -0500 Subject: [PATCH 2/3] updated requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b86db97..faf618c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,7 +20,7 @@ fonttools==4.53.1 frictionless==5.17.0 geopandas==1.0.1 googlemaps==4.10.0 -h3==3.7.7 +h3==4.1.2 hdx-python-api==6.3.2 hdx-python-country==3.7.7 hdx-python-utilities==3.7.3 From d5e50fe0f60aff010f0220fe3d99675f8e0e3c6a Mon Sep 17 00:00:00 2001 From: jeronimol Date: Thu, 19 Dec 2024 13:47:48 -0500 Subject: [PATCH 3/3] changed h3_to_boundary to cell_to_boundary in utils and downsampling --- urbanpy/geom/geom.py | 2 +- urbanpy/utils/utils.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/urbanpy/geom/geom.py b/urbanpy/geom/geom.py index 4fe0abd..545dd28 100644 --- a/urbanpy/geom/geom.py +++ b/urbanpy/geom/geom.py @@ -343,7 +343,7 @@ def resolution_downsampling( gdf_coarse = gdf.copy() coarse_hex_col = "hex_{}".format(coarse_resolution) gdf_coarse[coarse_hex_col] = gdf_coarse[hex_col].apply( - lambda x: h3.h3_to_parent(x, coarse_resolution) + lambda x: h3.cell_to_parent(x, res=coarse_resolution) ) dfc = gdf_coarse.groupby([coarse_hex_col]).agg(agg).reset_index() gdfc_geometry = dfc[coarse_hex_col].apply(geo_boundary_to_polygon) diff --git a/urbanpy/utils/utils.py b/urbanpy/utils/utils.py index 578ab46..d29e2df 100644 --- a/urbanpy/utils/utils.py +++ b/urbanpy/utils/utils.py @@ -6,6 +6,7 @@ import pandas as pd from geopandas import GeoDataFrame, GeoSeries import h3 +import shapely from pandas import DataFrame from shapely.geometry import MultiPolygon, Polygon from shapely.validation import make_valid @@ -166,9 +167,9 @@ def geo_boundary_to_polygon(x): Polygon representing H3 hexagon area """ - return Polygon( - [bound[::-1] for bound in h3.h3_to_geo_boundary(x)] - ) #  format as x,y (lon, lat) + lat_lng_points = h3.cell_to_boundary(x) + lng_lat_points = [(lng, lat) for lat, lng in lat_lng_points] + return shapely.Polygon(lng_lat_points) #  format as x,y (lon, lat) def create_duration_labels(durations):