Reading shapefiles

Downloading the file

First, we will download a sample shape file:

import wget
import zipfile
import os.path

if  not os.path.isfile('data/IPBES_Regions_Subregions2.shp'):
    url = 'https://zenodo.org/record/3928281/files/ipbes_regions_subregions_shape_1.1.zip'
    wget.download(url, 'data/ipbes_regions_subregions_shape_1.1.zip')
    with zipfile.ZipFile("data/ipbes_regions_subregions_shape_1.1.zip","r") as zip_ref:
        zip_ref.extractall("data")

Reading the shapefile

import shapefile as pyshp
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
data = pyshp.Reader('data/IPBES_Regions_Subregions2.shp', encoding='ISO8859-1')
data
shapes = data.shapes()
nshapes = len(shapes)
single = shapes[0]
single.shapeType
single.shapeTypeName
parts = single.parts
parts
points = np.array(single.points)  # npoints, nx, ny
points.shape 
fields = data.fields
fields
records = data.records()
singlerec = records[4]
singlerec
i = 0
for a in records:
    count = a[2]
    if(count == 'France'):
        break
    i += 1
ax = plt.axes(projection=ccrs.PlateCarree())

cmap = plt.cm.jet

# get the shapes and extract the points
single = shapes[i]
points = np.array(single.points)
npoints = len(points)

# get the number of parts
parts = list(single.parts)
nparts = len(parts)

# get the record
singlerec = records[i]
xmin, xmax = points[:, 0].min(), points[:, 0].max()
ymin, ymax = points[:, 1].min(), points[:, 1].max()

if nparts == 1:
    plt.plot(points[:, 0], points[:, 1])
else:
    # if parts does not start with 0:
    # we add 0 at the beginning of the list
    if parts[0] != 0:
        parts = [0] + parts
    # if parts does not end with npoints 
    # it is added at the end.
    if parts[-1] != npoints:
        parts = parts + [npoints]
    nparts = len(parts) - 1
    for p in range(nparts):
        # get the colour
        color = cmap(p / (nparts - 1))
        start = parts[p]
        end = parts[p + 1]
        iii = range(start, end)
        plt.plot(points[iii, 0], points[iii, 1], color=color, transform=ccrs.PlateCarree(), linewidth=2)
#l = ax.add_feature(cfeature.LAND)
#l = ax.add_feature(cfeature.COASTLINE)
ax.set_extent([xmin, xmax, ymin, ymax])
plt.show()