or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

config-utilities.mdcoordinate-systems.mddata-management.mdindex.mdio-operations.mdspatial-operations.md

coordinate-systems.mddocs/

0

# Coordinate Systems

1

2

Comprehensive coordinate reference system (CRS) management including setting, transforming, and reprojecting coordinate systems. These capabilities enable working with geospatial data across different projections and coordinate systems.

3

4

## Capabilities

5

6

### CRS Properties and Access

7

8

Get and set coordinate reference system information for DataArrays and Datasets.

9

10

```python { .api }

11

@property

12

def crs(self) -> Optional[rasterio.crs.CRS]:

13

"""

14

Retrieve projection from xarray Dataset or DataArray.

15

16

Returns:

17

rasterio.crs.CRS or None: The coordinate reference system

18

"""

19

```

20

21

#### Usage Examples

22

23

```python

24

import rioxarray

25

import xarray as xr

26

27

# Open raster with CRS

28

da = rioxarray.open_rasterio('geo_file.tif')

29

print(da.rio.crs) # <rasterio.crs.CRS object>

30

31

# Check if data has CRS

32

if da.rio.crs is not None:

33

print(f"CRS: {da.rio.crs}")

34

else:

35

print("No CRS defined")

36

37

# Get CRS string representation

38

print(da.rio.crs.to_string()) # 'EPSG:4326'

39

```

40

41

### Setting CRS

42

43

Set coordinate reference system without modifying the underlying data coordinates.

44

45

```python { .api }

46

def set_crs(

47

self,

48

input_crs: Any,

49

inplace: bool = True

50

) -> Union[xarray.Dataset, xarray.DataArray]:

51

"""

52

Set the CRS value for the Dataset/DataArray without modifying

53

the dataset/data array.

54

55

Parameters:

56

- input_crs: CRS in various formats (EPSG code, PROJ string, CRS object, etc.)

57

- inplace: If True, modify in place and return None (default: True)

58

59

Returns:

60

Dataset/DataArray with CRS set (if inplace=False)

61

"""

62

```

63

64

#### Usage Examples

65

66

```python

67

import rioxarray

68

69

# Open data without CRS

70

da = rioxarray.open_rasterio('file_no_crs.tif')

71

72

# Set CRS using EPSG code

73

da.rio.set_crs('EPSG:4326')

74

75

# Set CRS using different formats

76

da.rio.set_crs(4326) # EPSG integer

77

da.rio.set_crs('+proj=longlat +datum=WGS84') # PROJ string

78

da.rio.set_crs({'init': 'epsg:4326'}) # Dictionary format

79

80

# Create new object with CRS (inplace=False)

81

da_with_crs = da.rio.set_crs('EPSG:3857', inplace=False)

82

```

83

84

### Writing CRS to File

85

86

Write CRS information to dataset attributes for file output.

87

88

```python { .api }

89

def write_crs(

90

self,

91

input_crs: Optional[Any] = None,

92

grid_mapping_name: Optional[str] = None,

93

inplace: bool = False

94

) -> Union[xarray.Dataset, xarray.DataArray]:

95

"""

96

Write the CRS to the dataset as a coordinate variable.

97

98

Parameters:

99

- input_crs: CRS to write (uses current CRS if None)

100

- grid_mapping_name: Name for grid mapping variable

101

- inplace: If True, modify in place

102

103

Returns:

104

Dataset/DataArray with CRS written to attributes

105

"""

106

```

107

108

#### Usage Examples

109

110

```python

111

import rioxarray

112

113

da = rioxarray.open_rasterio('file.tif')

114

115

# Write current CRS to attributes

116

da_with_attrs = da.rio.write_crs(inplace=False)

117

118

# Write specific CRS

119

da_with_attrs = da.rio.write_crs('EPSG:4326', inplace=False)

120

121

# Custom grid mapping name

122

da_with_attrs = da.rio.write_crs(

123

grid_mapping_name='my_projection',

124

inplace=False

125

)

126

```

127

128

### UTM CRS Estimation

129

130

Automatically estimate the appropriate UTM coordinate system based on data bounds.

131

132

```python { .api }

133

def estimate_utm_crs(self, datum_name: str = "WGS 84") -> rasterio.crs.CRS:

134

"""

135

Returns the estimated UTM CRS based on the bounds of the dataset.

136

137

Parameters:

138

- datum_name: Datum name for UTM CRS (default: "WGS 84")

139

140

Returns:

141

rasterio.crs.CRS: Estimated UTM CRS

142

143

Raises:

144

MissingCRS: If dataset has no CRS defined

145

"""

146

```

147

148

#### Usage Examples

149

150

```python

151

import rioxarray

152

153

# Open geographic data (lat/lon)

154

da = rioxarray.open_rasterio('geographic_data.tif') # EPSG:4326

155

156

# Estimate best UTM zone

157

utm_crs = da.rio.estimate_utm_crs()

158

print(utm_crs) # UTM Zone 33N or similar

159

160

# Estimate with different datum

161

utm_crs = da.rio.estimate_utm_crs(datum_name="NAD83")

162

163

# Use estimated CRS for reprojection

164

reprojected = da.rio.reproject(utm_crs)

165

```

166

167

### Transform Operations

168

169

Get and manipulate the affine transformation matrix that defines the pixel-to-coordinate mapping.

170

171

```python { .api }

172

def transform(self, recalc: bool = False) -> rasterio.Affine:

173

"""

174

Get the affine transformation matrix.

175

176

Parameters:

177

- recalc: Recalculate transform from coordinates (default: False)

178

179

Returns:

180

rasterio.Affine: The affine transformation matrix

181

"""

182

183

def write_transform(self, transform: Optional[rasterio.Affine] = None, inplace: bool = False):

184

"""

185

Write the affine transform to the dataset.

186

187

Parameters:

188

- transform: Affine transform to write (uses current if None)

189

- inplace: If True, modify in place

190

191

Returns:

192

Dataset/DataArray with transform written to attributes

193

"""

194

```

195

196

#### Usage Examples

197

198

```python

199

import rioxarray

200

from rasterio.transform import from_bounds

201

202

da = rioxarray.open_rasterio('file.tif')

203

204

# Get current transform

205

transform = da.rio.transform()

206

print(transform) # Affine transformation matrix

207

208

# Create custom transform

209

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

210

211

# Apply custom transform

212

da_transformed = da.rio.write_transform(new_transform, inplace=False)

213

```

214

215

### Resolution Information

216

217

Get pixel resolution from the affine transformation matrix.

218

219

```python { .api }

220

def resolution(self, recalc: bool = False) -> tuple[float, float]:

221

"""

222

Determine the resolution of the grid.

223

If the transformation has rotation, the sign of the resolution is lost.

224

225

Parameters:

226

- recalc: Recalculate resolution from coordinates (default: False)

227

228

Returns:

229

tuple[float, float]: (x_resolution, y_resolution)

230

"""

231

```

232

233

#### Usage Examples

234

235

```python

236

import rioxarray

237

238

da = rioxarray.open_rasterio('file.tif')

239

240

# Get pixel resolution

241

x_res, y_res = da.rio.resolution()

242

print(f"X resolution: {x_res}, Y resolution: {y_res}")

243

244

# Recalculate from coordinates

245

x_res, y_res = da.rio.resolution(recalc=True)

246

```

247

248

### Bounds Operations

249

250

Get spatial bounds and transform bounds between coordinate systems.

251

252

```python { .api }

253

def bounds(self, recalc: bool = False) -> tuple[float, float, float, float]:

254

"""

255

Get the spatial bounds of the dataset.

256

257

Parameters:

258

- recalc: Recalculate bounds from coordinates (default: False)

259

260

Returns:

261

tuple: (left, bottom, right, top) bounds

262

"""

263

264

def transform_bounds(

265

self,

266

dst_crs: Any,

267

*,

268

densify_pts: int = 21,

269

recalc: bool = False

270

) -> tuple[float, float, float, float]:

271

"""

272

Transform bounds from src_crs to dst_crs.

273

274

Parameters:

275

- dst_crs: Destination CRS

276

- densify_pts: Number of points to use for densification (default: 21)

277

- recalc: Recalculate source bounds (default: False)

278

279

Returns:

280

tuple: Transformed (left, bottom, right, top) bounds

281

"""

282

```

283

284

#### Usage Examples

285

286

```python

287

import rioxarray

288

289

da = rioxarray.open_rasterio('file.tif') # UTM coordinates

290

291

# Get current bounds

292

left, bottom, right, top = da.rio.bounds()

293

print(f"Bounds: {left}, {bottom}, {right}, {top}")

294

295

# Transform bounds to geographic coordinates

296

geo_bounds = da.rio.transform_bounds('EPSG:4326')

297

print(f"Geographic bounds: {geo_bounds}")

298

299

# Transform with more densification points

300

detailed_bounds = da.rio.transform_bounds('EPSG:4326', densify_pts=50)

301

```

302

303

### Grid Mapping Operations

304

305

Write grid mapping information for CF-compliant NetCDF files.

306

307

```python { .api }

308

def write_grid_mapping(

309

self,

310

grid_mapping_name: Optional[str] = None,

311

inplace: bool = False

312

) -> Union[xarray.Dataset, xarray.DataArray]:

313

"""

314

Write the grid mapping to the dataset.

315

316

Parameters:

317

- grid_mapping_name: Name for the grid mapping variable

318

- inplace: If True, modify in place

319

320

Returns:

321

Dataset/DataArray with grid mapping written

322

"""

323

324

def write_coordinate_system(self, inplace: bool = False):

325

"""

326

Write the coordinate system information to the dataset.

327

328

Parameters:

329

- inplace: If True, modify in place

330

331

Returns:

332

Dataset/DataArray with coordinate system information

333

"""

334

```

335

336

#### Usage Examples

337

338

```python

339

import rioxarray

340

341

da = rioxarray.open_rasterio('projected_data.tif')

342

343

# Write grid mapping for CF compliance

344

cf_da = da.rio.write_grid_mapping(inplace=False)

345

346

# Write complete coordinate system

347

coord_da = da.rio.write_coordinate_system(inplace=False)

348

349

# Save as CF-compliant NetCDF

350

cf_da.to_netcdf('cf_compliant.nc')

351

```

352

353

## CRS Utility Functions

354

355

Helper functions for working with coordinate reference systems.

356

357

```python { .api }

358

def crs_from_user_input(crs_input: Any) -> rasterio.crs.CRS:

359

"""

360

Return a rasterio.crs.CRS from user input.

361

362

Handles various CRS input formats and transitions between GDAL versions.

363

364

Parameters:

365

- crs_input: CRS in various formats

366

367

Returns:

368

rasterio.crs.CRS: Standardized CRS object

369

"""

370

```

371

372

#### Usage Examples

373

374

```python

375

from rioxarray.crs import crs_from_user_input

376

377

# Convert various CRS formats to standard CRS object

378

crs1 = crs_from_user_input('EPSG:4326')

379

crs2 = crs_from_user_input(4326)

380

crs3 = crs_from_user_input('+proj=longlat +datum=WGS84')

381

crs4 = crs_from_user_input({'init': 'epsg:4326'})

382

383

# All return equivalent rasterio.crs.CRS objects

384

print(crs1 == crs2 == crs3 == crs4) # True

385

```

386

387

## Common CRS Operations

388

389

### CRS Validation and Conversion

390

```python

391

import rioxarray

392

393

da = rioxarray.open_rasterio('data.tif')

394

395

# Check if CRS is geographic (lat/lon)

396

is_geographic = da.rio.crs.is_geographic

397

print(f"Is geographic: {is_geographic}")

398

399

# Check if CRS is projected

400

is_projected = da.rio.crs.is_projected

401

print(f"Is projected: {is_projected}")

402

403

# Get CRS as different formats

404

epsg_code = da.rio.crs.to_epsg() # EPSG integer or None

405

proj_string = da.rio.crs.to_proj4() # PROJ.4 string

406

wkt = da.rio.crs.to_wkt() # Well-Known Text

407

```

408

409

### Working with Different CRS Formats

410

```python

411

import rioxarray

412

413

da = rioxarray.open_rasterio('file.tif')

414

415

# Set CRS using various input formats

416

da.rio.set_crs('EPSG:4326') # EPSG string

417

da.rio.set_crs(4326) # EPSG integer

418

da.rio.set_crs('+proj=utm +zone=33 +datum=WGS84') # PROJ string

419

da.rio.set_crs({'init': 'epsg:32633'}) # Dictionary

420

421

# Use with CRS objects

422

from rasterio.crs import CRS

423

crs_obj = CRS.from_epsg(4326)

424

da.rio.set_crs(crs_obj)

425

```