I'm working with the nightlights data - 30 arc second grids, spanning -180 to 180 degrees longitude and -65 to 75 degrees latitude. I want to downsample it to 5 arc-min resolution.

Now my question is how to best do it? I'm using rasterio to load the data and looked at this way but it does not work for me as I'm using python 3 and get error - "TypeError: 'float' object cannot be interpreted as an integer" I'm also worried as to how it will impact my coordinate systems etc.

I haven't found anything latest on this yet. What's the best way to go about it?

nlight_path = "./data/nightlights/F182013.v4c_web.stable_lights.avg_vis.tif"
# open raster data
with rio.open(nlight_path) as src:
    nlight = src.read(masked=True, indexes = 1)
    nlight_meta = src.profile
    nlight_extent = rio.plot.plotting_extent(src)

(-180.00416666665, 180.00416522665, -65.00416610665, 75.00416666665)
{'driver': 'GTiff', 'dtype': 'uint8', 'nodata': None, 'width': 43201, 'height': 16801, 'count': 1, 'crs': CRS.from_dict(init='epsg:4326'), 'transform': Affine(0.0083333333, 0.0, -180.00416666665,
       0.0, -0.0083333333, 75.00416666665), 'tiled': False, 'interleave': 'band'}
(16801, 43201)
<class 'numpy.ma.core.MaskedArray'>

Also can I directly do the downsampling on masked array? But then how will it affect the mask?


Edit: See the examples referenced here: https://github.com/mapbox/rasterio/issues/1732

with rasterio.open('image.tif') as dataset:
    data = dataset.read(
        out_shape=(dataset.count, dataset.height // 3.75, dataset.width // 3.75), # Integer division using //

Another simple way to go about it is to use rioxarray. It is a wrapper around rasterio.

Here is an example of what you want to do:

import rioxarray
import xarray

nlight_path = "./data/nightlights/F182013.v4c_web.stable_lights.avg_vis.tif"
rds = xarray.open_rasterio(nlight_path).squeeze().drop("band")

downsampled = rds.rio.reproject(rds.rio.crs, resolution=5.0/60.0)

Also can I directly do the downsampling on masked array?

Pending this PR you will be able to open with masked=True. In xarray, it will convert the value to a float64 and fill the mask with a NaN value. But you can easily convert back with the fillna() and astype() methods.

But then how will it affect the mask?

The mask should be preserved as close as possible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.