gboeing / osmnx

OSMnx is a Python package to easily download, model, analyze, and visualize street networks and other geospatial features from OpenStreetMap.
https://osmnx.readthedocs.io
MIT License
4.86k stars 826 forks source link

Removal of inner_polygons from outer_polygons (creation of holes), creates maximum one hole. #1098

Closed orrsim closed 9 months ago

orrsim commented 10 months ago

Contributing guidelines

Documentation

Existing issues

What operating system and Python version are you using?

Windows 11 Python 3.12

What OSMnx version are you using?

1.8.0

Environment packages and versions

Package            Version
------------------ ---------
affine             2.4.0
asttokens          2.4.0
attrs              22.2.0
backcall           0.2.0
basemap            1.3.8
basemap-data       1.3.2
beautifulsoup4     4.11.2
branca             0.7.0
Cartopy            0.22.0
certifi            2022.12.7
charset-normalizer 3.0.1
click              8.1.3
click-plugins      1.1.1
cligj              0.7.2
cloudpickle        2.2.1
colorama           0.4.6
comm               0.1.4
contourpy          1.1.1
cycler             0.12.0
debugpy            1.8.0
decorator          5.1.1
executing          2.0.0
Fiona              1.9.1
fonttools          4.43.0
GDAL               3.4.3
geopandas          0.14.0
html5lib           1.1
idna               3.4
ipykernel          6.25.2
ipyleaflet         0.18.0
ipython            8.16.1
ipywidgets         8.1.1
jedi               0.19.1
Jinja2             3.1.2
jupyter_client     8.3.1
jupyter_core       5.3.2
jupyterlab-widgets 3.0.9
kiwisolver         1.4.5
lxml               4.9.2
MarkupSafe         2.1.3
matplotlib         3.7.2
matplotlib-inline  0.1.6
munch              2.5.0
nest-asyncio       1.5.8
networkx           3.1
numpy              1.25.2
osmnx              1.8.0
packaging          23.0
pandas             2.0.3
parso              0.8.3
pickleshare        0.7.5
Pillow             10.0.1
pip                23.3.2
platformdirs       3.11.0
prettymapp         0.2.0
prettymaps         1.0.0
prompt-toolkit     3.0.39
psutil             5.9.5
pure-eval          0.2.2
Pygments           2.16.1
pyparsing          3.0.9
pyproj             3.4.1
PyQt5              5.15.9
PyQt5-Qt5          5.15.2
PyQt5-sip          12.12.2
pyshp              2.3.1
python-dateutil    2.8.2
pytz               2022.7.1
pywin32            306
PyYAML             6.0
pyzmq              25.1.1
rasterio           1.3.9
requests           2.28.2
Rtree              1.0.1
scipy              1.11.4
setuptools         65.5.0
shapely            2.0.1
six                1.16.0
snuggs             1.4.7
soupsieve          2.4
spyder-kernels     2.5.0
stack-data         0.6.3
tornado            6.3.3
traitlets          5.11.2
traittypes         0.2.1
tzdata             2023.3
urllib3            1.26.14
wcwidth            0.2.8
webencodings       0.5.1
widgetsnbextension 4.0.9
xyzservices        2023.10.1

How did you install OSMnx?

Pip

Problem description

Any polygon generated with holes is generated with a maximum of one hole.

I believe this issue is in line 895 of features.py

outer_polygon_diff = outer_polygon.difference(inner_polygon)

Outer_polygon_diff is reset to outer_polygon at the start of each iteration of the inner loop. This means that only the last subtraction will have an effect because each new subtraction is done on the original outer_polygon, not on the result of the previous subtraction.

outer_polygon_diff = outer_polygon_diff.difference(inner_polygon)

Complete minimal reproducible example

import osmnx as ox
print(ox.__version__)
import matplotlib.pyplot as plt

# #Fjora, Norway
# latitude = 60.455759
# longitude = 10.244916

# Thousand Island Lake, California
latitude = 37.720126
longitude =  -119.181986

# Define a bounding box around the location (adjust the distance as needed)
distance = 200  # in meters

ox.settings.log_console = True

water = ox.features_from_point((latitude,longitude),dist=distance, tags={"natural":["water"]})

print(water.type)

polygon = water.geometry

print(polygon.type)

# Checking the number of holes
print("Number of holes:", len(polygon.interiors))

# Plot the areas on top of the graph
ax=water.plot(ec="blue", fc="none", linewidth=1)

# Show the plot
plt.show()
gboeing commented 10 months ago

Thanks @orrsim for opening this!

@AtelierLibre led the development of this functionality: do you have any preliminary insights or suggestions?

gboeing commented 9 months ago

@orrsim for troubleshooting, can you provide the OSM ID of a specific polygon feature that has multiple holes but OSMnx only renders with 1 hole?

orrsim commented 9 months ago

@gboeing some examples are: Thousand Island Lake (207450) Fjorda (175565)

AtelierLibre commented 9 months ago

Hello both, apologies that I wasn't able to look at this over the break, I should be able to put a bit of time against this now.

gboeing commented 9 months ago

Closed by #1104