# Making subset of Sentinel-2 with rasterio?

I am looking for a solution to my problem with rasterio. I want to download just a specific part of the image from AWS based on lat lon coordinates. Rasterio offers a great tool (window) although it proivdes just pixel values and not geographycal coordiantes (latlon).

Is there any solution for my problem?

Here is my code:

``````red = 's3://sentinel-s2-l2a/tiles/34/T/DS/2017/10/12/0/R10m/B04.jp2'
nir = 's3://sentinel-s2-l2a/tiles/34/T/DS/2017/10/12/0/R10m/B08.jp2'

bands=[red, nir]
def ndvi_calc(bands):
window = rasterio.windows.Window(100, 100, 100, 100) # How can I set here lat/lon values?
red_band=bands
nir_band=bands
with Session:
with rasterio.open(red) as red_band:
red=red_band.read(1, window=window)
with rasterio.open(nir) as nir_band:
nir=nir_band.read(1, window=window)

ndvi = (nir.astype(float) - red.astype(float)) / (nir+red)
``````

## 1 Answer

You can write a wrapper that uses the dataset crs and transform to convert from geographical to array coordinates

``````import rasterio
from rasterio.windows import Window
from pyproj import Proj
from math import floor, ceil

def longlat2window(lon, lat, dataset):
"""
Args:
lon (tuple): Tuple of min and max lon
lat (tuple): Tuple of min and max lat
dataset: Rasterio dataset

Returns:
rasterio.windows.Window
"""
p = Proj(dataset.crs)
t = dataset.transform
xmin, ymin = p(lon, lat)
xmax, ymax = p(lon, lat)
col_min, row_min = ~t * (xmin, ymin)
col_max, row_max = ~t * (xmax, ymax)
return Window.from_slices(rows=(floor(row_max), ceil(row_min)),
cols=(floor(col_min), ceil(col_max)))

with rasterio.open(file) as src:
window = longlat2window((-99.2, -99.17), (19.40, 19.43), src)
arr = src.read(1, window=window)
``````