mardi 15 octobre 2019

Implementing a simple adapter for existing python library

I would like to figure out a way to construct a simple object adapter for the rasterio package.

The problem

Rasterio has no central object (think DataFrame in pandas) upon which all the operations are based. Instead they have a strange interplay of dataset objects which are a file abstraction, numpy arrays and transform objects which provide crucial geospatial metadata about the numpy arrays so that they can be burned to raster datasets.

Many of the functions I construct are based on rasterio and geopandas. For geopandas I have no problem, I usually input and output GeoDataFrame objects and this works fine. With rasterio though, I do not have this luxury since many of the native functions take inconsistent data types. For example, rasterio.warp.reproject takes ndarrays and source/destination transforms to do its work while mask.mask takes a dataset opened in "r" mode.

What if I wanted to mask then reproject? Then I'd have to write a file, re-read it and extract the necessary information to then input the right arguments to the reproject function. I find myself adapting arguments all the time to fit the argument types in rasterio.

Adapter pattern

The adapter pattern requires a Client, Adaptee and Adapter. Here's how I see the roles being separated:

  • Adaptee: These are the set of rasterio functions (for example rasterio.warp.reproject as they expect to receive varying representations of the same object
  • Client: I am guessing that this is the dataset object or a wrapper thereof. I would like to pass only dataset objects to the Adaptee
  • Adapter: object I am trying to construct. Should this contain

And not a mix of both.

Question

rasterio.warp.reproject requires the following arguments (among others):

source=ndarray or band
destination=ndarray or band
src_transform=transform object
src_crs=crs object
dst_transform=transform object
dst_crs=crs object

I would like to adapt this to take in a dataset object and output a dataset object. For this to succeed I will have to insert some pre- and post- logic to work on the input and output dataset objects to get my source bands, crs and transforms. These are contained within the dataset object.

How can I do this within the context of an object adapter pattern (no inheritance)? Thanks for your help.

Aucun commentaire:

Enregistrer un commentaire