Search code examples
python-3.8cartopy

cartopy.io.shapereader.natural_earth returns urllib.error.HTTPError: HTTP Error 404: Not Found


I am trying to create a landmask for Norway using cartopy. As I understood it, the following code should be able to do that:

shapefile_norway = 'no_1km_shp'
norway_shp = shpreader.natural_earth(resolution='110m', category='cultural', name=shapefile_norway)
landmask_norway = list(shpreader.Reader(norway_shp).geometries())
print(landmask_norway.ndim)

I got the Norway shapefile here. However, when running the code I get the following error:

.local/lib/python3.8/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/110m_cultural/ne_110m_no_1km_shp.zip
  warnings.warn(f'Downloading: {url}', DownloadWarning)
Traceback (most recent call last):
  File "FireRisk1.py", line 28, in <module>
    norway_shp = shpreader.natural_earth(resolution='110m', category='cultural', name=shapefile_norway)
  File "/cluster/home/elsri/.local/lib/python3.8/site-packages/cartopy/io/shapereader.py", line 283, in natural_earth
    return ne_downloader.path(format_dict)
  File "/cluster/home/elsri/.local/lib/python3.8/site-packages/cartopy/io/__init__.py", line 203, in path
    result_path = self.acquire_resource(target_path, format_dict)
  File "/cluster/home/elsri/.local/lib/python3.8/site-packages/cartopy/io/shapereader.py", line 337, in acquire_resource
    shapefile_online = self._urlopen(url)
  File "/cluster/home/elsri/.local/lib/python3.8/site-packages/cartopy/io/__init__.py", line 242, in _urlopen
    return urlopen(url)
  File "/cluster/software/Python/3.8.2-GCCcore-9.3.0/lib/python3.8/urllib/request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "/cluster/software/Python/3.8.2-GCCcore-9.3.0/lib/python3.8/urllib/request.py", line 531, in open
    response = meth(req, response)
  File "/cluster/software/Python/3.8.2-GCCcore-9.3.0/lib/python3.8/urllib/request.py", line 640, in http_response
    response = self.parent.error(
  File "/cluster/software/Python/3.8.2-GCCcore-9.3.0/lib/python3.8/urllib/request.py", line 569, in error
    return self._call_chain(*args)
  File "/cluster/software/Python/3.8.2-GCCcore-9.3.0/lib/python3.8/urllib/request.py", line 502, in _call_chain
    result = func(*args)
  File "/cluster/software/Python/3.8.2-GCCcore-9.3.0/lib/python3.8/urllib/request.py", line 649, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: Not Found

It seems I get a download warning, after which the code stops. Is there a way for me to get around this warning/error?


Solution

  • The "name" you provide has nothing to do with the "Natural Earth" dataset, so it's expected that this will fail.

    If you already have the shape, you can just specify the filename/path to the shpreader, see the example below.

    import matplotlib.pyplot as plt
    import cartopy.crs as ccrs
    import cartopy.io.shapereader as shpreader
    
    shp = shpreader.Reader("no_100km.shp")
    
    proj = ccrs.epsg(3035)
    
    fig, ax = plt.subplots(
        figsize=(6,10), dpi=96, facecolor="w", 
        subplot_kw=dict(projection=proj),
    )
    
    ax.add_geometries(shp.geometries(), proj, fc='none', ec="C4", lw=1.5)
    
    ax.coastlines(alpha=.2)
    ax.set_extent([0, 25, 53, 87], crs=ccrs.PlateCarree())
    ax.gridlines(draw_labels=True, alpha=.5)
    

    enter image description here