Topics

window_transform doesn't produce accurate coordinate transforms

pranay1117@...
 

Hi, I'm new to rasterio and working with geographical data. So far, it's been a great experience working with this library - but I've run into an issue when working with the Window module. My use case is as follows: 
- I obtain 2 bounding coordinates from the user (top-left and bottom-right) and convert them to (row, col) using `source.index(lon, lat)`.
- I create a window using these bounds and read the dataset from that. Also, I get the appropriate transform for this window.
selected_window = Window.from_slices((row0, row1), (col0, col1))
data = src.read(1, window=selected_window)
affine_transform = src.window_transform(selected_window)

Afterwards, I am using this `data` numpy array to select various points in these bounds and plot them on a map. However, the (lat, long) coordinates obtained using the affine_transform above are not very accurate. When I run the following:
print("Lat/Lon bounds: {}".format(src.window_bounds(selected_window)))
print("Transform at (0,0): {}".format(affine_transform * (0,0)))
r, c = data.shape
print("Transform at {}: {}".format((r-1, c-1), affine_transform * (r-1, c-1)))

The output is as follows:
Source lat/lon bounds: (72.45 20.69, 82.39, 28.78)
Transform at (0,0): (72.42, 28.78)
Transform at (970, 1193): (80.53, 18.841)

As is evident from the output, the latitude must lie between (20.69,28.78) but the transform value 18.841 at (970, 1193) is not in that interval. 

I saw some earlier posts in this group that suggested updating to version 1.1.5. I've done that but the issue persists. 
Any help will be greatly appreciated. Thanks!


Sean Gillies
 

Hi,

On Thu, Jul 23, 2020 at 7:06 AM pranay1117 via groups.io <pranay1117=yahoo.co.in@groups.io> wrote:
Hi, I'm new to rasterio and working with geographical data. So far, it's been a great experience working with this library - but I've run into an issue when working with the Window module. My use case is as follows: 
- I obtain 2 bounding coordinates from the user (top-left and bottom-right) and convert them to (row, col) using `source.index(lon, lat)`.
- I create a window using these bounds and read the dataset from that. Also, I get the appropriate transform for this window.
selected_window = Window.from_slices((row0, row1), (col0, col1))
data = src.read(1, window=selected_window)
affine_transform = src.window_transform(selected_window)

Afterwards, I am using this `data` numpy array to select various points in these bounds and plot them on a map. However, the (lat, long) coordinates obtained using the affine_transform above are not very accurate. When I run the following:
print("Lat/Lon bounds: {}".format(src.window_bounds(selected_window)))
print("Transform at (0,0): {}".format(affine_transform * (0,0)))
r, c = data.shape
print("Transform at {}: {}".format((r-1, c-1), affine_transform * (r-1, c-1)))

The output is as follows:
Source lat/lon bounds: (72.45 20.69, 82.39, 28.78)
Transform at (0,0): (72.42, 28.78)
Transform at (970, 1193): (80.53, 18.841)

As is evident from the output, the latitude must lie between (20.69,28.78) but the transform value 18.841 at (970, 1193) is not in that interval. 

I saw some earlier posts in this group that suggested updating to version 1.1.5. I've done that but the issue persists. 
Any help will be greatly appreciated. Thanks!

Your usage of the affine transform

    affine_transform * (r-1, c-1)

is incorrect. You must swap the order of the tuple indexes to get the correct results because mathematically speaking

    (x', y') = affine_transform * (x, y)

and row is y and column is x. Rasterio has a method that will help keep this straight: https://rasterio.readthedocs.io/en/latest/api/rasterio.transform.html#rasterio.transform.xy.

The ordering of items in (row, col) versus (x, y) is a constant source of confusion. I hope this reply hasn't come too late and that it is useful.

--
Sean Gillies

pranay1117@...
 

Hi Sean, thanks for your reply - that was indeed the source of the issue on my end. I was able to fix it!

--
Best, 
Pranay