添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Hello everybody,

I am trying to clip a raster with a polygon geometry.
I have opened succesfully the raster with rasterio.open() function and provided the polygon coords in a" GeoJSON-like dict or an object that implements the Python geo interface protocol".

However, the next error appears when executing it:
"AttributeError: 'numpy.ndarray' object has no attribute 'transform'"

It comes from the line Lib\site-packages\rasterio\features.py:451 when trying to acces to the dataset attribute 'transform'. Datset is a numpy.ndarray and, since it does not have such attribute, the error appears.

I have created a quick ndarray with numpy to see is normally this object has this attribute, and the same error appears when accessing such attribute, like follows:

>>> import numpy as np
>>> arr = np.array([1, 2, 3, 4, 5])
>>> arr.transform
>>>  "AttributeError: 'numpy.ndarray' object has no attribute 'transform'"

I guess if there is a deprecation error from rasterio then, and maybe numpy has updated the name of its attributes or something similar.

I would be very appreciate if someone could shed some light on this :)

Here I share my code:
--------------------------------------------------
>>>> import rasterio
>>>> import json
>>> import geopandas as gpd
>>>> from rasterio.plot import show
>>>> from rasterio.merge import merge
>>>> from rasterio.mask import mask

>>> corrientes_gdf = gpd.read_file('corrientes.shp')
>>> alos_1 = rasterio.open('data\Layers\ALOS\ALOS-0000000000-0000000000.tif')
>>> alos_2 = rasterio.open('data\Layers\ALOS\ALOS-0000000000-0000046592.tif')
>>> alos = merge([alos_1, alos_2])[0]

>>> coords = [json.loads(corrientes_gdf .to_json())['features'][0]['geometry']]

>>> alos_clip, alos_transform = mask(alos, shapes=corriente_coords, crop=True, nodata=0)

Thank you ver much.
Kind regards,
Miguel GonzálezJ

Well, rasterio.merge returns a numpy array and a transform, not a rasterio.dataset. It's important that mask receives a rasterio.dataset because it needs a transform. And, yeah, numpy arrays aren't geolocated and don't have a geotransform.

There is, however a "dst_path" argument to merge, so you can just:

```
merge([alos_1, alos_2], dst_path='/tmp/merged.tif')
merged = rasterio.open('/tmp/merged.tif')
alos_clip, alos_transform = mask(merged, shapes=coords, crop=True, nodata=0)
```

Or, you could create an in-memory file, fill it with the raster data and use that for mask. Maybe something like this:

```
import io

# other code ...

alos_np, alos_transform = merge([alos_1, alos_2])
profile = {
**alos_1.profile,
'width': alos_np.shape[1],
'height': alos_np.shape[0]
}
fp = io.BytesIO()
with rasterio.open(fp, 'w', **profile) as tif:
tif.write(alos_np)
alos_clip, alos_transform = mask(fp, shapes=coords, crop=True, nodata=0)
```
On Fri, Mar 8, 2024 at 12:53 PM Brandon Victor < interdimensional.cabbage@... > wrote:
Well, rasterio.merge returns a numpy array and a transform, not a rasterio.dataset. It's important that mask receives a rasterio.dataset because it needs a transform. And, yeah, numpy arrays aren't geolocated and don't have a geotransform.

There is, however a "dst_path" argument to merge, so you can just:

```
merge([alos_1, alos_2], dst_path='/tmp/merged.tif')
merged = rasterio.open('/tmp/merged.tif')
alos_clip, alos_transform = mask(merged, shapes=coords, crop=True, nodata=0)
```

Or, you could create an in-memory file, fill it with the raster data and use that for mask. Maybe something like this:

```
import io

# other code ...

alos_np, alos_transform = merge([alos_1, alos_2])
profile = {
**alos_1.profile,
'width': alos_np.shape[1],
'height': alos_np.shape[0]
}
fp = io.BytesIO()
with rasterio.open(fp, 'w', **profile) as tif:
tif.write(alos_np)
alos_clip, alos_transform = mask(fp, shapes=coords, crop=True, nodata=0)
```