or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdindex.mdio-utilities.mdpoint-queries.mdzonal-statistics.md

io-utilities.mddocs/

0

# I/O and Data Utilities

1

2

Core input/output utilities and data handling classes that support rasterstats functionality. These utilities handle reading vector data from various sources, managing raster data access, and providing coordinate system transformations.

3

4

## Capabilities

5

6

### Raster Data Access

7

8

The `Raster` class provides unified access to raster data from files or numpy arrays.

9

10

```python { .api }

11

from rasterstats.io import Raster

12

13

class Raster:

14

"""

15

Raster abstraction for data access to 2/3D array-like things.

16

17

Use as a context manager to ensure dataset gets closed properly.

18

19

Parameters:

20

- raster: 2/3D array-like data source (path to raster file or numpy array)

21

- affine: Affine transformation (required if raster is ndarray)

22

- nodata: Override nodata value (default: None)

23

- band: Raster band number, counting from 1 (default: 1)

24

"""

25

26

def __init__(self, raster, affine=None, nodata=None, band=1): ...

27

28

def index(self, x, y):

29

"""

30

Convert (x, y) coordinates in CRS to (row, column) indices.

31

32

Parameters:

33

- x: X coordinate in coordinate reference system

34

- y: Y coordinate in coordinate reference system

35

36

Returns:

37

Tuple of (row, column) indices

38

"""

39

40

def read(self, bounds=None, window=None, masked=False, boundless=True):

41

"""

42

Read data from the raster source.

43

44

Parameters:

45

- bounds: Bounding box (w, s, e, n) (default: None)

46

- window: Rasterio-style window ((row_start, row_stop), (col_start, col_stop)) (default: None)

47

- masked: Return masked numpy array (default: False)

48

- boundless: Allow reading beyond dataset extent (default: True)

49

50

Returns:

51

Raster object with updated affine and array info

52

53

Raises:

54

ValueError if both bounds and window specified or neither specified

55

"""

56

57

# Context manager methods

58

def __enter__(self): ...

59

def __exit__(self, *args): ...

60

```

61

62

### Vector Data Reading

63

64

Functions for reading vector data from various sources including files, GeoJSON, and geometric objects.

65

66

```python { .api }

67

from rasterstats.io import read_features, read_featurecollection

68

69

def read_features(obj, layer=0):

70

"""

71

Read vector features from various input sources.

72

73

Supports:

74

- File paths (Shapefile, GeoJSON, etc.)

75

- GeoJSON strings or dictionaries

76

- Feature collections

77

- Iterables of feature-like objects

78

- Objects with __geo_interface__

79

- WKT/WKB geometry strings/bytes

80

81

Parameters:

82

- obj: Vector data source

83

- layer: Layer index or name for multi-layer sources (default: 0)

84

85

Returns:

86

Iterator yielding GeoJSON-like Feature dictionaries

87

88

Raises:

89

ValueError if object is not a recognized source of features

90

"""

91

92

def read_featurecollection(obj, layer=0):

93

"""

94

Read vector features and return as GeoJSON FeatureCollection.

95

96

Parameters:

97

- obj: Vector data source (same as read_features)

98

- layer: Layer index or name (default: 0)

99

100

Returns:

101

GeoJSON FeatureCollection dictionary with all features loaded

102

"""

103

104

def parse_feature(obj):

105

"""

106

Parse a single object into a GeoJSON-like Feature.

107

108

Attempts to convert various input formats:

109

- Objects with __geo_interface__

110

- WKT/WKB strings/bytes

111

- GeoJSON geometry or feature dictionaries

112

113

Parameters:

114

- obj: Object to parse as feature

115

116

Returns:

117

GeoJSON-like Feature dictionary

118

119

Raises:

120

ValueError if object cannot be parsed as a feature

121

"""

122

```

123

124

### Coordinate and Window Utilities

125

126

Functions for coordinate system transformations and window calculations.

127

128

```python { .api }

129

from rasterstats.io import rowcol, bounds_window, window_bounds

130

131

def rowcol(x, y, affine, op=math.floor):

132

"""

133

Convert x/y coordinates to row/column indices.

134

135

Parameters:

136

- x: X coordinate

137

- y: Y coordinate

138

- affine: Affine transformation

139

- op: Rounding operation function (default: math.floor)

140

141

Returns:

142

Tuple of (row, column) indices

143

"""

144

145

def bounds_window(bounds, affine):

146

"""

147

Create rasterio-style window from bounding box.

148

149

Parameters:

150

- bounds: Bounding box (west, south, east, north)

151

- affine: Affine transformation

152

153

Returns:

154

Window tuple ((row_start, row_stop), (col_start, col_stop))

155

"""

156

157

def window_bounds(window, affine):

158

"""

159

Calculate bounding box from rasterio-style window.

160

161

Parameters:

162

- window: Window tuple ((row_start, row_stop), (col_start, col_stop))

163

- affine: Affine transformation

164

165

Returns:

166

Bounding box tuple (west, south, east, north)

167

"""

168

169

def beyond_extent(window, shape):

170

"""

171

Check if window references pixels beyond raster extent.

172

173

Parameters:

174

- window: Window tuple ((row_start, row_stop), (col_start, col_stop))

175

- shape: Raster shape tuple (height, width)

176

177

Returns:

178

Boolean indicating if window extends beyond raster bounds

179

"""

180

```

181

182

### Array Utilities

183

184

Functions for handling boundless array operations and data access.

185

186

```python { .api }

187

from rasterstats.io import boundless_array

188

189

def boundless_array(arr, window, nodata, masked=False):

190

"""

191

Extract array data for window that may extend beyond array bounds.

192

193

Areas outside the array extent are filled with nodata values.

194

195

Parameters:

196

- arr: Input numpy array (2D or 3D)

197

- window: Window tuple ((row_start, row_stop), (col_start, col_stop))

198

- nodata: Value to use for areas outside array bounds

199

- masked: Return masked array (default: False)

200

201

Returns:

202

Numpy array (optionally masked) with data for requested window

203

204

Raises:

205

ValueError if array is not 2D or 3D

206

"""

207

```

208

209

### Warning Classes

210

211

Custom warning classes for I/O operations.

212

213

```python { .api }

214

from rasterstats.io import NodataWarning

215

216

class NodataWarning(UserWarning):

217

"""

218

Warning raised for nodata handling issues.

219

220

Issued when:

221

- No nodata value is specified and default (-999) is used

222

- Dataset masks are detected and masked reading is automatically enabled

223

"""

224

```

225

226

## Usage Examples

227

228

### Working with Raster Data

229

230

```python

231

from rasterstats.io import Raster

232

from affine import Affine

233

import numpy as np

234

235

# Using file-based raster

236

with Raster("elevation.tif") as rast:

237

# Get pixel indices for coordinates

238

row, col = rast.index(100.5, 200.7)

239

240

# Read full raster

241

full_data = rast.read()

242

243

# Read specific window

244

window = ((10, 50), (20, 60))

245

subset = rast.read(window=window, masked=True)

246

247

# Read by bounding box

248

bounds = (100, 200, 150, 250) # w, s, e, n

249

clipped = rast.read(bounds=bounds, boundless=True)

250

251

# Using numpy array

252

raster_array = np.random.rand(100, 100) * 1000

253

transform = Affine.translation(0, 100) * Affine.scale(1, -1)

254

255

with Raster(raster_array, affine=transform, nodata=-999) as rast:

256

subset = rast.read(bounds=(10, 10, 50, 50))

257

print(f"Shape: {subset.array.shape}")

258

print(f"Affine: {subset.affine}")

259

```

260

261

### Reading Vector Data

262

263

```python

264

from rasterstats.io import read_features, read_featurecollection

265

266

# Read from shapefile

267

features = list(read_features("watersheds.shp"))

268

print(f"Found {len(features)} features")

269

270

# Read from GeoJSON string

271

geojson_str = '''{"type": "Point", "coordinates": [100, 200]}'''

272

point_features = list(read_features(geojson_str))

273

274

# Read from feature collection

275

fc = read_featurecollection("polygons.geojson")

276

print(f"FeatureCollection with {len(fc['features'])} features")

277

278

# Read from list of geometries

279

geometries = [

280

{"type": "Point", "coordinates": [100, 200]},

281

{"type": "Point", "coordinates": [150, 250]}

282

]

283

point_list = list(read_features(geometries))

284

285

# Handle multi-layer sources

286

layers = list(read_features("multilayer.gpkg", layer="roads"))

287

```

288

289

### Coordinate Transformations

290

291

```python

292

from rasterstats.io import rowcol, bounds_window, window_bounds

293

from affine import Affine

294

import math

295

296

# Create sample transform

297

transform = Affine.translation(100, 200) * Affine.scale(1, -1)

298

299

# Convert coordinates to pixel indices

300

row, col = rowcol(105.5, 195.3, transform)

301

print(f"Pixel location: row {row}, col {col}")

302

303

# Using ceiling operation for different rounding

304

row_ceil, col_ceil = rowcol(105.5, 195.3, transform, op=math.ceil)

305

306

# Create window from bounds

307

bounds = (100, 150, 200, 250) # w, s, e, n

308

window = bounds_window(bounds, transform)

309

print(f"Window: {window}")

310

311

# Get bounds back from window

312

calculated_bounds = window_bounds(window, transform)

313

print(f"Bounds: {calculated_bounds}")

314

```

315

316

### Handling Boundless Operations

317

318

```python

319

from rasterstats.io import boundless_array, beyond_extent

320

import numpy as np

321

322

# Create sample array

323

arr = np.random.rand(50, 50) * 100

324

shape = arr.shape

325

326

# Define window that extends beyond array

327

large_window = ((45, 65), (45, 65)) # Extends 15 pixels beyond

328

329

if beyond_extent(large_window, shape):

330

print("Window extends beyond array bounds")

331

332

# Extract data with nodata fill

333

result = boundless_array(arr, large_window, nodata=-999, masked=True)

334

print(f"Result shape: {result.shape}")

335

print(f"Original array shape: {arr.shape}")

336

print(f"Nodata pixels: {(result == -999).sum()}")

337

```

338

339

## Types

340

341

```python { .api }

342

from typing import Union, List, Dict, Any, Optional, Tuple, Iterator

343

from numpy import ndarray

344

from affine import Affine

345

346

# Input types

347

VectorSource = Union[str, Dict, List[Dict], bytes] # Various vector input formats

348

RasterSource = Union[str, ndarray] # File path or numpy array

349

LayerSpec = Union[int, str] # Layer index or name

350

GeometryDict = Dict[str, Any] # GeoJSON geometry dictionary

351

FeatureDict = Dict[str, Any] # GeoJSON feature dictionary

352

353

# Coordinate types

354

Bounds = Tuple[float, float, float, float] # (west, south, east, north)

355

Window = Tuple[Tuple[int, int], Tuple[int, int]] # ((row_start, row_stop), (col_start, col_stop))

356

Coordinates = Tuple[float, float] # (x, y) coordinate pair

357

PixelIndices = Tuple[int, int] # (row, column) indices

358

359

# Array types

360

BoundlessArray = Union[ndarray, np.ma.MaskedArray] # Regular or masked array

361

ArrayShape = Tuple[int, int] # (height, width) for 2D arrays

362

```