Converting raster data to H3

from matplotlib import pyplot
import rasterio
from rasterio.plot import show
import numpy as np
import h3.api.numpy_int as h3
from scipy import ndimage
import geopandas as gpd
from pathlib import Path
import os

# increase the plot size
pyplot.rcParams['figure.dpi'] = 120

project_root = Path(os.environ["PROJECT_ROOT"])

Prepare a dataset using rasterio first

import rasterio
from rasterio.plot import show

src = rasterio.open(project_root / "data/europe-and-north-africa.tif")
print(src.colorinterp)

green = src.read(2)
blue = src.read(3)
print(green.shape)

show(src)
(<ColorInterp.red: 3>, <ColorInterp.green: 4>, <ColorInterp.blue: 5>)
(284, 327)
../_images/raster_1_1.png
<Axes: >

Do some image processing - like this messy extraction of a vegetation mask here:

vegetation_mask = (green < 250) & (blue < 50)
ocean_mask = (green >= 6) & (green <= 14) & (blue >= 47) & (blue <= 54)
vegetation_nodata_value = 0

vegetation = np.full(green.shape, 10, dtype="int8")
vegetation[ocean_mask] = vegetation_nodata_value
vegetation[vegetation_mask] = 20

# smooth a bit to remove single pixels
vegetation = ndimage.gaussian_filter(vegetation, sigma=.7)
vegetation[vegetation <= 5] = vegetation_nodata_value
vegetation[(vegetation > 0) & (vegetation < 15)] = 1
vegetation[vegetation >= 15] = 2
vegetation[ocean_mask] = vegetation_nodata_value

vegetation_plot_args = dict(cmap='Greens', vmin=0, vmax=2)

pyplot.imshow(vegetation, **vegetation_plot_args)
<matplotlib.image.AxesImage at 0x7adf60a40910>
../_images/raster_2_1.png
vegetation
array([[1, 1, 1, ..., 0, 0, 0],
       [1, 1, 1, ..., 0, 0, 0],
       [1, 1, 1, ..., 0, 0, 0],
       ...,
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0]], shape=(284, 327), dtype=int8)

Convert the raster numpy array to H3

Find the closest H3 resolution to use. See also the docstrings of the used functions and of the h3ronpy.raster module.

from h3ronpy.raster import nearest_h3_resolution

h3_res = nearest_h3_resolution(vegetation.shape, src.transform, search_mode="smaller_than_pixel")
print(f"Using H3 resolution {h3_res}")
Using H3 resolution 5

Now we convert the raster directly into a geopandas GeoDataFrame:

from h3ronpy.pandas.raster import raster_to_dataframe

vegetation_h3_df = raster_to_dataframe(
    vegetation,
    src.transform,
    h3_res,
    nodata_value=vegetation_nodata_value,
    compact=True,
    geo=True
)

vegetation_h3_df.plot(column="value", linewidth=0.2, edgecolor="black", **vegetation_plot_args)
pyplot.show()
../_images/raster_5_0.png

Converting H3 cells to raster

import pandas as pd
import pyarrow as pa
from h3ronpy.pandas.raster import rasterize_cells
from rasterio.plot import show

df = pd.read_parquet(project_root / "data/population-841fa8bffffffff.parquet")
size = 1000
nodata_value = -1
array, transform = rasterize_cells(
    pa.array(df["h3index"]),
    pa.array(df["pop_general"].astype("int32")),
    size,
    nodata_value=nodata_value
)

show(array, cmap="viridis", transform=transform, contour=False)
../_images/raster_6_0.png
<Axes: >