Skip to content

Commit 5b8d2e4

Browse files
Merge pull request #64 from gregory-halverson-jpl/main
v1.17.0 docstrings and README
2 parents 3a60e32 + aea3018 commit 5b8d2e4

File tree

6 files changed

+1115
-77
lines changed

6 files changed

+1115
-77
lines changed

README.md

Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,332 @@ raster
9191
```
9292

9393
![png](examples/Opening%20a%20GeoTIFF_3_0.png)
94+
95+
## Usage
96+
97+
### Working with Raster Objects
98+
99+
The `Raster` class is the primary interface for working with raster data. It encapsulates both the data array and its georeferencing information.
100+
101+
#### Opening and Creating Rasters
102+
103+
```python
104+
from rasters import Raster
105+
106+
# Open a raster from file
107+
raster = Raster.open("path/to/file.tif")
108+
109+
# Create a raster from a numpy array and geometry
110+
import numpy as np
111+
from rasters import RasterGrid
112+
113+
data = np.random.rand(100, 100)
114+
geometry = RasterGrid.from_bbox(
115+
xmin=-120, ymin=30, xmax=-110, ymax=40,
116+
cell_size=0.1
117+
)
118+
raster = Raster(data, geometry=geometry)
119+
```
120+
121+
#### Raster Properties
122+
123+
```python
124+
# Access the data array
125+
array = raster.array
126+
127+
# Get dimensions
128+
rows, cols = raster.shape
129+
print(f"Raster size: {rows} rows x {cols} cols")
130+
131+
# Get coordinate reference system
132+
crs = raster.crs
133+
134+
# Get bounding box
135+
bbox = raster.bbox
136+
137+
# Get cell size
138+
cell_size = raster.cell_size
139+
```
140+
141+
#### Raster Operations
142+
143+
```python
144+
# Arithmetic operations
145+
raster_sum = raster1 + raster2
146+
raster_diff = raster1 - raster2
147+
raster_product = raster1 * raster2
148+
raster_quotient = raster1 / raster2
149+
150+
# Comparison operations
151+
mask = raster > 0.5
152+
153+
# Reproject to different coordinate system
154+
reprojected = raster.reproject(crs="EPSG:4326", target_cell_size=0.01)
155+
156+
# Resample to a different geometry
157+
resampled = raster.to_geometry(target_geometry, resampling="bilinear")
158+
159+
# Sample at a point
160+
from rasters import Point
161+
point = Point(-115, 35, crs="EPSG:4326")
162+
value = raster.to_point(point)
163+
```
164+
165+
#### Saving Rasters
166+
167+
```python
168+
# Save as GeoTIFF
169+
raster.to_geotiff("output.tif", compression="deflate")
170+
171+
# Save as Cloud Optimized GeoTIFF (COG)
172+
raster.to_COG("output_cog.tif")
173+
174+
# Save as GeoPackage
175+
raster.to_geopackage("output.gpkg")
176+
```
177+
178+
#### Visualization
179+
180+
```python
181+
# Display in Jupyter notebook (automatic when last line in cell)
182+
raster
183+
184+
# Create a matplotlib figure
185+
fig = raster.imshow(
186+
title="My Raster",
187+
cmap="viridis",
188+
figsize=(10, 8)
189+
)
190+
191+
# Save as image
192+
image = raster.to_pillow(cmap="jet")
193+
image.save("preview.png")
194+
```
195+
196+
### Working with RasterGrid
197+
198+
The `RasterGrid` class represents gridded raster geometry with uniform cell spacing and north-oriented grids.
199+
200+
#### Creating RasterGrid Objects
201+
202+
```python
203+
from rasters import RasterGrid
204+
205+
# From bounding box and cell size
206+
grid = RasterGrid.from_bbox(
207+
xmin=-120, ymin=30, xmax=-110, ymax=40,
208+
cell_size=0.001,
209+
crs="EPSG:4326"
210+
)
211+
212+
# From bounding box and shape
213+
grid = RasterGrid.from_bbox(
214+
xmin=-120, ymin=30, xmax=-110, ymax=40,
215+
shape=(1000, 1000),
216+
crs="EPSG:4326"
217+
)
218+
219+
# From affine transform
220+
from affine import Affine
221+
affine = Affine(0.001, 0, -120, 0, -0.001, 40)
222+
grid = RasterGrid.from_affine(affine, rows=1000, cols=1000, crs="EPSG:4326")
223+
224+
# From coordinate vectors
225+
x_vector = np.linspace(-120, -110, 1000)
226+
y_vector = np.linspace(30, 40, 1000)
227+
grid = RasterGrid.from_vectors(x_vector, y_vector, crs="EPSG:4326")
228+
229+
# From a raster file
230+
grid = RasterGrid.open("path/to/file.tif")
231+
```
232+
233+
#### RasterGrid Properties
234+
235+
```python
236+
# Get grid dimensions
237+
rows = grid.rows
238+
cols = grid.cols
239+
240+
# Get cell size
241+
cell_width = grid.cell_width
242+
cell_height = grid.cell_height
243+
244+
# Get extent
245+
xmin, ymin = grid.xmin, grid.ymin
246+
xmax, ymax = grid.xmax, grid.ymax
247+
width, height = grid.width, grid.height
248+
249+
# Get coordinate arrays
250+
x = grid.x # 2D array of x-coordinates
251+
y = grid.y # 2D array of y-coordinates
252+
253+
# Get coordinate vectors
254+
x_vector = grid.x_vector # 1D array of x-coordinates
255+
y_vector = grid.y_vector # 1D array of y-coordinates
256+
257+
# Get affine transform
258+
affine = grid.affine
259+
```
260+
261+
#### RasterGrid Operations
262+
263+
```python
264+
# Subset to a region
265+
from rasters import BBox
266+
subset_bbox = BBox(-115, 32, -112, 38, crs="EPSG:4326")
267+
subset_grid = grid.subset(subset_bbox)
268+
269+
# Slice using indices
270+
subset_grid = grid[100:200, 150:250]
271+
272+
# Change resolution
273+
rescaled_grid = grid.rescale(cell_size=0.002)
274+
275+
# Buffer the grid
276+
buffered_grid = grid.buffer(pixels=10)
277+
278+
# Shift the grid
279+
shifted_grid = grid.shift_xy(x_shift=100, y_shift=50)
280+
```
281+
282+
### Working with RasterGeolocation
283+
284+
The `RasterGeolocation` class represents swath raster geometry using 2D geolocation arrays, commonly used for satellite swath data.
285+
286+
#### Creating RasterGeolocation Objects
287+
288+
```python
289+
from rasters import RasterGeolocation
290+
import numpy as np
291+
292+
# From x and y coordinate arrays
293+
x_coords = np.random.uniform(-120, -110, (500, 500))
294+
y_coords = np.random.uniform(30, 40, (500, 500))
295+
geolocation = RasterGeolocation(x_coords, y_coords, crs="EPSG:4326")
296+
297+
# From coordinate vectors (creates meshgrid)
298+
x_vector = np.linspace(-120, -110, 500)
299+
y_vector = np.linspace(30, 40, 500)
300+
geolocation = RasterGeolocation.from_vectors(x_vector, y_vector, crs="EPSG:4326")
301+
```
302+
303+
#### RasterGeolocation Properties
304+
305+
```python
306+
# Get dimensions
307+
rows = geolocation.rows
308+
cols = geolocation.cols
309+
310+
# Get coordinate arrays
311+
x = geolocation.x # 2D array of x-coordinates
312+
y = geolocation.y # 2D array of y-coordinates
313+
314+
# Get extent
315+
xmin, ymin = geolocation.x_min, geolocation.y_min
316+
xmax, ymax = geolocation.x_max, geolocation.y_max
317+
318+
# Get cell size (estimated from median distances)
319+
cell_size = geolocation.cell_size
320+
321+
# Get boundary polygon
322+
boundary = geolocation.boundary
323+
```
324+
325+
#### RasterGeolocation Operations
326+
327+
```python
328+
# Index with geometry
329+
from rasters import Polygon
330+
polygon = Polygon([(-115, 32), (-112, 32), (-112, 38), (-115, 38)])
331+
mask = geolocation.index(polygon)
332+
333+
# Generate a regular grid from geolocation
334+
grid = geolocation.grid
335+
336+
# Resize geolocation arrays
337+
resized = geolocation.resize(dimensions=(250, 250))
338+
339+
# Subset to a region
340+
subset = geolocation.subset(polygon)
341+
```
342+
343+
### Working with Points and Vector Geometries
344+
345+
```python
346+
from rasters import Point, Polygon, BBox
347+
348+
# Create a point
349+
point = Point(-115.5, 35.2, crs="EPSG:4326")
350+
351+
# Transform point to different CRS
352+
utm_point = point.to_crs("EPSG:32611")
353+
354+
# Create a polygon
355+
polygon = Polygon([
356+
(-115, 32),
357+
(-112, 32),
358+
(-112, 38),
359+
(-115, 38)
360+
], crs="EPSG:4326")
361+
362+
# Create a bounding box
363+
bbox = BBox(xmin=-120, ymin=30, xmax=-110, ymax=40, crs="EPSG:4326")
364+
365+
# Sample raster at point
366+
value = raster.to_point(point)
367+
368+
# Clip raster to polygon
369+
clipped = raster.subset(polygon)
370+
```
371+
372+
### Advanced Usage
373+
374+
#### Merging Multiple Rasters
375+
376+
```python
377+
# Open multiple rasters
378+
raster1 = Raster.open("tile1.tif")
379+
raster2 = Raster.open("tile2.tif")
380+
raster3 = Raster.open("tile3.tif")
381+
382+
# Merge into a single raster
383+
merged = Raster.merge([raster1, raster2, raster3])
384+
```
385+
386+
#### Resampling with KDTree
387+
388+
```python
389+
from rasters import KDTree
390+
391+
# Create a KDTree for efficient resampling
392+
kd_tree = KDTree(
393+
source_geometry=source_raster.geometry,
394+
target_geometry=target_grid,
395+
radius_of_influence=1000 # meters
396+
)
397+
398+
# Resample using the KDTree
399+
resampled = source_raster.resample(target_grid, kd_tree=kd_tree)
400+
401+
# Save KDTree for reuse
402+
kd_tree.save("kdtree.pkl")
403+
404+
# Load KDTree
405+
kd_tree = KDTree.load("kdtree.pkl")
406+
```
407+
408+
#### Working with Masks
409+
410+
```python
411+
# Create a mask
412+
mask = raster > 0.5
413+
414+
# Apply mask to raster
415+
masked_raster = raster.mask(mask)
416+
417+
# Fill masked values with another raster
418+
filled = raster.fill(fill_raster)
419+
```
94420

95421
## Changelog
96422

debug.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from rasters import RasterGrid
2+
3+
# Define target area
4+
geometry = RasterGrid.from_bbox(
5+
xmin=-118.5, ymin=33.5, xmax=-117.5, ymax=34.5,
6+
cell_size=30, crs="EPSG:4326"
7+
)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "rasters"
7-
version = "1.16.1"
7+
version = "1.17.0"
88
description = "raster processing toolkit"
99
readme = "README.md"
1010
authors = [

0 commit comments

Comments
 (0)