or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdcrs.mddata-types.mddataset-io.mdfeatures.mdindex.mdprocessing.mdtransformations.mdwindowing.md

transformations.mddocs/

0

# Transformations

1

2

Affine transformations for converting between pixel and geographic coordinates. Supports creating transforms from bounds, origins, ground control points, and provides coordinate conversion utilities.

3

4

## Capabilities

5

6

### Affine Transformation Matrix

7

8

The core transformation class from the `affine` library, integrated into rasterio for geospatial coordinate transformations.

9

10

```python { .api }

11

class Affine:

12

"""6-parameter affine transformation matrix."""

13

14

def __init__(self, a, b, c, d, e, f):

15

"""

16

Initialize affine transformation.

17

18

Parameters (coefficients for the transformation):

19

- a (float): x-scale factor

20

- b (float): x-shear factor

21

- c (float): x-translation

22

- d (float): y-shear factor

23

- e (float): y-scale factor

24

- f (float): y-translation

25

26

Transformation: x' = a*x + b*y + c, y' = d*x + e*y + f

27

"""

28

29

# Properties

30

a: float # x-scale

31

b: float # x-shear

32

c: float # x-translation

33

d: float # y-shear

34

e: float # y-scale

35

f: float # y-translation

36

37

@classmethod

38

def identity(cls):

39

"""Create identity transformation."""

40

41

@classmethod

42

def translation(cls, x, y):

43

"""Create translation transformation."""

44

45

@classmethod

46

def scale(cls, x, y=None):

47

"""Create scaling transformation."""

48

49

@classmethod

50

def rotation(cls, angle):

51

"""Create rotation transformation."""

52

53

def __mul__(self, other):

54

"""Compose with another transformation."""

55

56

def __invert__(self):

57

"""Get inverse transformation."""

58

59

def determinant(self):

60

"""Calculate transformation determinant."""

61

62

def is_identity(self):

63

"""Test if identity transformation."""

64

65

def is_conformal(self):

66

"""Test if conformal (preserves angles)."""

67

68

def is_orthonormal(self):

69

"""Test if orthonormal (preserves distances and angles)."""

70

71

def is_rectilinear(self):

72

"""Test if rectilinear (axes aligned)."""

73

```

74

75

### Transform Creation Functions

76

77

Utilities for creating affine transformations from various geographic parameters.

78

79

```python { .api }

80

def from_bounds(west, south, east, north, width, height):

81

"""

82

Create transform from geographic bounds and raster dimensions.

83

84

Parameters:

85

- west (float): Left (minimum x) coordinate

86

- south (float): Bottom (minimum y) coordinate

87

- east (float): Right (maximum x) coordinate

88

- north (float): Top (maximum y) coordinate

89

- width (int): Raster width in pixels

90

- height (int): Raster height in pixels

91

92

Returns:

93

Affine: Transformation matrix

94

"""

95

96

def from_origin(west, north, xsize, ysize):

97

"""

98

Create transform from origin point and pixel sizes.

99

100

Parameters:

101

- west (float): Left (minimum x) coordinate

102

- north (float): Top (maximum y) coordinate

103

- xsize (float): Pixel width (x-direction)

104

- ysize (float): Pixel height (y-direction, usually negative)

105

106

Returns:

107

Affine: Transformation matrix

108

"""

109

110

def from_gcps(gcps):

111

"""

112

Create transform from ground control points.

113

114

Parameters:

115

- gcps (sequence): Ground control points as (row, col, x, y) tuples

116

117

Returns:

118

Affine: Transformation matrix

119

"""

120

```

121

122

Usage examples:

123

124

```python

125

from rasterio.transform import from_bounds, from_origin, Affine

126

127

# Create transform from bounds

128

transform = from_bounds(-180, -90, 180, 90, 360, 180)

129

print(transform) # Affine(1.0, 0.0, -180.0, 0.0, -1.0, 90.0)

130

131

# Create transform from origin and pixel size

132

transform = from_origin(-180, 90, 1.0, -1.0) # 1-degree pixels

133

134

# Create transform from ground control points

135

gcps = [

136

(0, 0, -180, 90), # top-left

137

(0, 360, 180, 90), # top-right

138

(180, 0, -180, -90), # bottom-left

139

(180, 360, 180, -90) # bottom-right

140

]

141

transform = from_gcps(gcps)

142

143

# Manual transform creation

144

transform = Affine(1.0, 0.0, -180.0, # x-scale, x-shear, x-offset

145

0.0, -1.0, 90.0) # y-shear, y-scale, y-offset

146

```

147

148

### Coordinate Conversion

149

150

Functions for converting between pixel and geographic coordinate systems.

151

152

```python { .api }

153

def xy(transform, rows, cols, offset='center'):

154

"""

155

Convert pixel coordinates to geographic coordinates.

156

157

Parameters:

158

- transform (Affine): Geospatial transformation

159

- rows (array-like): Row coordinates (y-axis, 0-based)

160

- cols (array-like): Column coordinates (x-axis, 0-based)

161

- offset (str): Pixel offset ('center', 'ul', 'ur', 'll', 'lr')

162

163

Returns:

164

tuple: (x_coords, y_coords) in geographic space

165

"""

166

167

def rowcol(transform, xs, ys, op=math.floor, precision=None):

168

"""

169

Convert geographic coordinates to pixel coordinates.

170

171

Parameters:

172

- transform (Affine): Geospatial transformation

173

- xs (array-like): X coordinates in geographic space

174

- ys (array-like): Y coordinates in geographic space

175

- op (callable): Rounding operation (math.floor, math.ceil, round)

176

- precision (int): Decimal places for rounding

177

178

Returns:

179

tuple: (rows, cols) in pixel space

180

"""

181

```

182

183

Usage examples:

184

185

```python

186

import rasterio

187

from rasterio.transform import xy, rowcol

188

import numpy as np

189

190

# Load dataset with transform

191

with rasterio.open('example.tif') as dataset:

192

transform = dataset.transform

193

194

# Convert pixel coordinates to geographic

195

rows, cols = np.array([100, 200]), np.array([150, 250])

196

x_coords, y_coords = xy(transform, rows, cols)

197

print(f"Geographic coords: {list(zip(x_coords, y_coords))}")

198

199

# Convert geographic coordinates to pixels

200

x_geo, y_geo = [-120.5, -119.8], [45.2, 44.9]

201

pixel_rows, pixel_cols = rowcol(transform, x_geo, y_geo)

202

print(f"Pixel coords: {list(zip(pixel_rows, pixel_cols))}")

203

204

# Different pixel offset options

205

x_center, y_center = xy(transform, [100], [150], offset='center')

206

x_corner, y_corner = xy(transform, [100], [150], offset='ul') # upper-left

207

```

208

209

### Bounds and Array Operations

210

211

Utilities for calculating bounds and working with transformed arrays.

212

213

```python { .api }

214

def array_bounds(height, width, transform):

215

"""

216

Calculate geographic bounds of raster array.

217

218

Parameters:

219

- height (int): Array height in pixels

220

- width (int): Array width in pixels

221

- transform (Affine): Geospatial transformation

222

223

Returns:

224

BoundingBox: Geographic bounds (west, south, east, north)

225

"""

226

227

def guard_transform(transform):

228

"""

229

Validate transformation matrix.

230

231

Parameters:

232

- transform (Affine): Transformation to validate

233

234

Returns:

235

Affine: Validated transformation

236

237

Raises:

238

TransformError: If transform is invalid

239

"""

240

```

241

242

Usage examples:

243

244

```python

245

from rasterio.transform import array_bounds, guard_transform

246

247

# Calculate bounds from array dimensions

248

height, width = 1000, 2000

249

transform = from_bounds(-180, -90, 180, 90, width, height)

250

bounds = array_bounds(height, width, transform)

251

print(f"Bounds: {bounds}") # BoundingBox(left=-180, bottom=-90, right=180, top=90)

252

253

# Validate transformation

254

try:

255

valid_transform = guard_transform(transform)

256

except TransformError as e:

257

print(f"Invalid transform: {e}")

258

```

259

260

### Specialized Transformations

261

262

Advanced transformation operations for specific use cases.

263

264

```python { .api }

265

def tasseledcap(array, coeffs):

266

"""

267

Apply Tasseled Cap transformation to multispectral data.

268

269

Parameters:

270

- array (numpy.ndarray): Input multispectral array

271

- coeffs (numpy.ndarray): Transformation coefficients

272

273

Returns:

274

numpy.ndarray: Transformed array

275

"""

276

```

277

278

Usage example:

279

280

```python

281

# Landsat Tasseled Cap transformation

282

landsat_coeffs = np.array([

283

[0.3037, 0.2793, 0.4743, 0.5585, 0.5082, 0.1863], # Brightness

284

[-0.2848, -0.2435, -0.5436, 0.7243, 0.0840, -0.1800], # Greenness

285

[0.1509, 0.1973, 0.3279, 0.3406, -0.7112, -0.4572] # Wetness

286

])

287

288

# Apply transformation to 6-band Landsat data

289

transformed = tasseledcap(landsat_bands, landsat_coeffs)

290

```

291

292

### Transform Error Handling

293

294

Transformation operations can raise specific exceptions for invalid matrices or operations:

295

296

```python { .api }

297

class TransformError(RasterioError):

298

"""Transformation related errors."""

299

```

300

301

Common error scenarios:

302

303

```python

304

from rasterio.errors import TransformError

305

306

try:

307

# Invalid transformation matrix (zero determinant)

308

invalid_transform = Affine(0, 0, 0, 0, 0, 0)

309

guard_transform(invalid_transform)

310

except TransformError as e:

311

print(f"Invalid transform: {e}")

312

313

# Check transform validity

314

if transform.determinant() == 0:

315

raise TransformError("Singular transformation matrix")

316

```