28. Getting lat,lon from row, column#
Download rowcol2latlon.ipynb from the week5 folder
28.1. Introduction#
The function rowcol2latlon defined below takes the name of a tiffile and a row,column pair
for the raster and returns the latitude and longitude of that pixel. It uses the
pyproj.CRS object to hold the coordinate reference system and the pyproj.Transformer
object to do
the transform.
from pathlib import Path
from pyproj import Transformer, CRS
import rioxarray
data_dir = Path().home() / 'repos/a301/satdata/landsat'
tif_filename = data_dir / 'vancouver' / f"week4_clipped_TIRS2.tif"
print(f"{tif_filename=}")
tif_filename=PosixPath('/Users/phil/repos/a301/satdata/landsat/vancouver/week4_clipped_TIRS2.tif')
28.2. transforming lat/lon to utm#
Here is how we did this using the code from - Zooming an image.
# zone 10 UTM
proj_code = 32610
#
# we want to go from x,y in utm zone 10 to lat,lon
# first, get x,y from lat, lon, the show you can reverse that
#
p_utm = CRS.from_epsg(proj_code)
p_latlon = CRS.from_epsg(4326)
transform = Transformer.from_crs(p_latlon, p_utm)
ubc_lon = -123.2460
ubc_lat = 49.2606
ubc_x, ubc_y = transform.transform(ubc_lat, ubc_lon)
print(f"{ubc_x=:.2f} m, {ubc_y:.2f}")
ubc_x=482101.01 m, 5456455.22
#dir(transform)
transform.description
'UTM zone 10N'
28.3. doing the inverse: utm to lat/lon#
To go the other direction, just reverse the parameters in the Transformer call
# zone 10 UTM
proj_code = 32610
#
# we want to go from x,y in utm zone 10 to lat,lon
# first, get x,y from lat, lon, the show you can reverse that
#
p_utm = CRS.from_epsg(proj_code)
p_latlon = CRS.from_epsg(4326)
transform = Transformer.from_crs(p_utm, p_latlon)
ubc_lat, ubc_lon = transform.transform(ubc_x, ubc_y)
print(f"{ubc_lat=:.2f} m, {ubc_lon=:.2f} m")
ubc_lat=49.26 m, ubc_lon=-123.25 m
28.3.1. wrap this in a function#
Find the lat/lon of the upper left corner with row=0, col=0
def rowcol2latlon(tiffile,row,col):
"""
return the latitude and longitude of a row and column in a geotif
Parameters
----------
tiffile: Path object
path to a clipped tiffile
row: float
row of the pixel
col: float
column of the pixel
Returns
-------
(lon, lat): (float, float)
longitude (deg east) and latitude (deg north) on
a WGS84 datum
"""
has_file = tiffile.exists()
if not has_file:
raise IOError(f"can't find {filename}, something went wrong above")
the_band = rioxarray.open_rasterio(tif_filename,masked=True)
epsg_code = the_band.rio.crs.to_epsg()
p_utm = CRS.from_epsg(epsg_code)
p_latlon = CRS.from_epsg(4326)
affine_transform = the_band.rio.transform()
x, y = affine_transform*(row, col)
crs_transform = Transformer.from_crs(p_utm, p_latlon)
lat, lon = transform.transform(x,y)
return (lon, lat)
lon, lat = rowcol2latlon(tif_filename,0,0)
print(f"{lon=:.1f} deg,{lat=:.1f} deg")
lon=-123.3 deg,lat=49.3 deg
28.4. Two gotchas to watch out for#
Don’t confuse the pyproj transformer.Transform with the affine transform – two completely different things
pyproj has an alternate way of doing coordinate transforms using a Proj object and a transform (lower case t) method. These are in lots of examples on the web, but have been superseded by Transformer.transform