rasterama 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,488 @@
1
+ Metadata-Version: 2.4
2
+ Name: rasterama
3
+ Version: 0.1.2
4
+ Summary: Headless tile downloader and GeoTIFF/BigTIFF raster stitcher.
5
+ Author: Rasterama Contributors
6
+ Project-URL: Homepage, https://pypi.org/project/rasterama/
7
+ Project-URL: Repository, https://pypi.org/project/rasterama/
8
+ Project-URL: PyMapStitcher Store, https://apps.microsoft.com/search?query=PyMapStitcher
9
+ Project-URL: PyMapStitcher Search, https://apps.microsoft.com/search?query=Py%20Map%20Stitcher
10
+ Keywords: raster,geotiff,bigtiff,tiles,webmercator,gis
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Topic :: Scientific/Engineering :: GIS
18
+ Requires-Python: >=3.9
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: requests>=2.31
21
+ Requires-Dist: Pillow>=10.0
22
+ Requires-Dist: tifffile>=2024.0
23
+ Requires-Dist: numpy>=1.24
24
+ Provides-Extra: cuda
25
+ Requires-Dist: cupy-cuda12x>=13.0; extra == "cuda"
26
+ Provides-Extra: dev
27
+ Requires-Dist: build>=1.0; extra == "dev"
28
+ Requires-Dist: twine>=5.0; extra == "dev"
29
+ Requires-Dist: pytest>=8.0; extra == "dev"
30
+
31
+ # rasterama
32
+
33
+ `rasterama` is a headless Python core package and command-line tool for raster
34
+ map stitching. It downloads XYZ-style map tiles, decodes them, and streams them
35
+ into georeferenced TIFF/BigTIFF output without requiring a GUI.
36
+
37
+ The package was prepared from the reusable non-GUI parts of a PyMapStitcher
38
+ prototype. The PySide/WebEngine user interface is intentionally not included in
39
+ this core package.
40
+
41
+ ## Important usage notice
42
+
43
+ Only use tile servers and map providers where you have permission to download,
44
+ cache, process, and stitch tiles. Many public services restrict automated or
45
+ bulk downloading. `rasterama` is a technical tool; it does not grant rights to
46
+ third-party imagery or map data.
47
+
48
+ ## Related links
49
+
50
+ - PyPI project page after upload: <https://pypi.org/project/rasterama/>
51
+ - TestPyPI project page after test upload: <https://test.pypi.org/project/rasterama/>
52
+ - Microsoft Store search for PyMapStitcher: <https://apps.microsoft.com/search?query=PyMapStitcher>
53
+ - Microsoft Store protocol search: `ms-windows-store://search/?query=PyMapStitcher`
54
+ - Microsoft Store search for "Py Map Stitcher": <https://apps.microsoft.com/search?query=Py%20Map%20Stitcher>
55
+
56
+ Note: at packaging time I could not verify a stable public Microsoft Store
57
+ product-detail URL for PyMapStitcher. The links above intentionally point to
58
+ Microsoft Store search pages, so they stay useful even if the product ID changes.
59
+
60
+ ## Features
61
+
62
+ - Headless operation: no PySide, no Qt, no WebEngine.
63
+ - CLI command `rasterama`.
64
+ - Python API via `import rasterama`.
65
+ - XYZ tile math for Web Mercator tile grids.
66
+ - Bing QuadKey support.
67
+ - URL template expansion for `{x}`, `{y}`, `{z}`, `{q}`, `{quadkey}`, `{s}`,
68
+ `{snum}`, `{rnd}` and legacy NoniMapView-style placeholders.
69
+ - Tile download with retries, timeout, rate limiting, and custom headers.
70
+ - PNG/JPEG tile decoding with Pillow.
71
+ - Direct streaming into GeoTIFF/BigTIFF using `tifffile.memmap`.
72
+ - Embedded EPSG:3857 GeoTIFF tags.
73
+ - Sidecar `.tfw` and `.prj` support for single-tile TIFF export.
74
+ - Optional CUDA/CuPy chunk compositing.
75
+ - Built-in provider presets for common tile URL templates.
76
+
77
+ ## Installation
78
+
79
+ From a local checkout:
80
+
81
+ ```powershell
82
+ pip install .
83
+ ```
84
+
85
+ From a wheel:
86
+
87
+ ```powershell
88
+ pip install .\dist\rasterama-0.1.2-py3-none-any.whl
89
+ ```
90
+
91
+ Optional NVIDIA/CuPy support:
92
+
93
+ ```powershell
94
+ pip install "rasterama[cuda]"
95
+ ```
96
+
97
+ For development and packaging:
98
+
99
+ ```powershell
100
+ pip install "rasterama[dev]"
101
+ ```
102
+
103
+ ## CLI overview
104
+
105
+ After installation the console command is:
106
+
107
+ ```powershell
108
+ rasterama --help
109
+ ```
110
+
111
+ Available subcommands:
112
+
113
+ ```text
114
+ rasterama bounds
115
+ rasterama stitch
116
+ rasterama tile-url
117
+ rasterama tile-tif
118
+ rasterama quadkey
119
+ rasterama presets
120
+ ```
121
+
122
+ ### `rasterama bounds`
123
+
124
+ Estimate the tile range, image dimensions, tile count, and raw TIFF payload size
125
+ for a geographic bounding box.
126
+
127
+ ```powershell
128
+ rasterama bounds --bbox 50.1 8.5 50.2 8.6 --zoom 18
129
+ ```
130
+
131
+ Arguments:
132
+
133
+ - `--bbox SOUTH WEST NORTH EAST`: geographic bounding box in lon/lat degrees.
134
+ - `--zoom Z`: XYZ/Web Mercator zoom level.
135
+ - `--url-template TEMPLATE`: optional template, mostly for consistency.
136
+ - `--preset NAME`: optional preset name.
137
+ - `--json`: print machine-readable JSON.
138
+
139
+ Example JSON output:
140
+
141
+ ```powershell
142
+ rasterama bounds --bbox 50.1 8.5 50.2 8.6 --zoom 18 --json
143
+ ```
144
+
145
+ ### `rasterama stitch`
146
+
147
+ Download tiles and stream them into a georeferenced TIFF/BigTIFF.
148
+
149
+ ```powershell
150
+ rasterama stitch `
151
+ --url-template "https://server.example/{z}/{x}/{y}.png" `
152
+ --bbox 50.1 8.5 50.2 8.6 `
153
+ --zoom 18 `
154
+ --output out.tif
155
+ ```
156
+
157
+ Arguments:
158
+
159
+ - `--bbox SOUTH WEST NORTH EAST`: area to download.
160
+ - `--zoom Z`: XYZ/Web Mercator zoom level.
161
+ - `--output FILE`: output `.tif` or `.tiff` path.
162
+ - `--url-template TEMPLATE`: custom tile URL template.
163
+ - `--preset NAME`: use one of the built-in presets instead of a custom URL.
164
+ - `--workers N`: parallel download workers; default `8`.
165
+ - `--rate-limit-ms N`: delay per request in milliseconds; default `50`.
166
+ - `--retries N`: retries per tile; default `3`.
167
+ - `--timeout N`: HTTP timeout in seconds; default `20`.
168
+ - `--chunk-size N`: chunk width/height in tiles; default `64`.
169
+ - `--header Name=Value`: extra HTTP header; can be repeated.
170
+ - `--cuda`: enable optional CUDA/CuPy stitching.
171
+ - `--cuda-max-chunk-mb N`: max GPU chunk buffer size; default `1024`.
172
+ - `--cuda-boost`: intentionally keep GPU busy with background CUDA work.
173
+ - `--cuda-load-size N`: CUDA boost matrix size; default `1536`.
174
+
175
+ Preset example:
176
+
177
+ ```powershell
178
+ rasterama stitch `
179
+ --preset esri-world-imagery `
180
+ --bbox 50.1 8.5 50.2 8.6 `
181
+ --zoom 18 `
182
+ --output esri_area.tif
183
+ ```
184
+
185
+ Custom headers example:
186
+
187
+ ```powershell
188
+ rasterama stitch `
189
+ --url-template "https://tiles.example.com/{z}/{x}/{y}.png" `
190
+ --bbox 50.1 8.5 50.2 8.6 `
191
+ --zoom 18 `
192
+ --output out.tif `
193
+ --header "Authorization=Bearer YOUR_TOKEN" `
194
+ --header "Referer=https://example.com"
195
+ ```
196
+
197
+ ### `rasterama tile-url`
198
+
199
+ Expand one tile URL template for a concrete `x`, `y`, `z`.
200
+
201
+ ```powershell
202
+ rasterama tile-url --template "https://server.example/{z}/{x}/{y}.png" --x 137261 --y 88677 --z 18
203
+ ```
204
+
205
+ Arguments:
206
+
207
+ - `--template TEMPLATE`: tile URL template.
208
+ - `--preset NAME`: use a built-in preset.
209
+ - `--x X`: tile x coordinate.
210
+ - `--y Y`: tile y coordinate.
211
+ - `--z Z`: tile zoom level.
212
+
213
+ ### `rasterama tile-tif`
214
+
215
+ Download one tile and write it as a georeferenced TIFF with `.tfw` and `.prj`
216
+ sidecar files.
217
+
218
+ ```powershell
219
+ rasterama tile-tif `
220
+ --url-template "https://server.example/{z}/{x}/{y}.png" `
221
+ --x 137261 `
222
+ --y 88677 `
223
+ --z 18 `
224
+ --output tile.tif
225
+ ```
226
+
227
+ Arguments:
228
+
229
+ - `--url-template TEMPLATE`: custom tile URL template.
230
+ - `--preset NAME`: use a built-in preset.
231
+ - `--x X`: tile x coordinate.
232
+ - `--y Y`: tile y coordinate.
233
+ - `--z Z`: tile zoom level.
234
+ - `--output FILE`: output TIFF path.
235
+ - `--rate-limit-ms N`: delay per request in milliseconds.
236
+ - `--retries N`: retries per tile.
237
+ - `--timeout N`: HTTP timeout in seconds.
238
+ - `--header Name=Value`: extra HTTP header; can be repeated.
239
+
240
+ ### `rasterama quadkey`
241
+
242
+ Calculate a Bing QuadKey from `x`, `y`, `z`.
243
+
244
+ ```powershell
245
+ rasterama quadkey --x 3 --y 5 --z 3
246
+ ```
247
+
248
+ ### `rasterama presets`
249
+
250
+ List included provider presets.
251
+
252
+ ```powershell
253
+ rasterama presets
254
+ rasterama presets --verbose
255
+ ```
256
+
257
+ Current preset names:
258
+
259
+ - `custom`
260
+ - `google-satellite`
261
+ - `google-hybrid`
262
+ - `bing-satellite`
263
+ - `bing-hybrid`
264
+ - `esri-world-imagery`
265
+ - `osm-mapnik`
266
+ - `opentopomap`
267
+ - `cartodb-positron`
268
+
269
+ ## URL template placeholders
270
+
271
+ Supported placeholders:
272
+
273
+ - `{x}`: XYZ tile x coordinate.
274
+ - `{y}`: XYZ tile y coordinate.
275
+ - `{z}`: zoom level.
276
+ - `{q}` and `{quadkey}`: Bing QuadKey.
277
+ - `{rnd}`: random integer from `0` to `3`.
278
+ - `{snum}`: subdomain number from `0` to `3`.
279
+ - `{s}`: subdomain letter from `a`, `b`, `c`.
280
+ - `*GMX*`, `*GMY*`, `*ZM1*`, `*IZM*`, `*RND*`, `*LAN*`, `*LAN-LAN*`:
281
+ legacy placeholders used by older map profile formats.
282
+
283
+ ## Python API quickstart
284
+
285
+ ```python
286
+ from pathlib import Path
287
+
288
+ from rasterama import StitchConfig, calculate_plan, stitch_tiles
289
+
290
+ cfg = StitchConfig(
291
+ url_template="https://server.example/{z}/{x}/{y}.png",
292
+ output_file=Path("out.tif"),
293
+ z=18,
294
+ min_lat=50.1,
295
+ min_lon=8.5,
296
+ max_lat=50.2,
297
+ max_lon=8.6,
298
+ workers=8,
299
+ rate_limit_ms=50,
300
+ )
301
+
302
+ plan = calculate_plan(cfg)
303
+ print(plan.total_tiles, plan.width, plan.height)
304
+
305
+ result = stitch_tiles(cfg, log_cb=print)
306
+ print(result.output_file)
307
+ ```
308
+
309
+ ## Public functions and classes
310
+
311
+ The package exports the most common API from `rasterama.__init__`:
312
+
313
+ - `Bounds`
314
+ - `StitchConfig`
315
+ - `StitchResult`
316
+ - `TileJob`
317
+ - `TilePlan`
318
+ - `calculate_plan`
319
+ - `stitch_tiles`
320
+ - `clamp_lat`
321
+ - `expand_url`
322
+ - `lonlat_to_tile`
323
+ - `tile_bounds_for_bbox`
324
+ - `tile_to_lonlat`
325
+ - `tile_to_quadkey`
326
+
327
+ Additional module-level functions:
328
+
329
+ ### `rasterama.tiles`
330
+
331
+ - `clamp_lat(lat)`
332
+ - `lonlat_to_tile(lon, lat, z)`
333
+ - `tile_to_lonlat(x, y, z)`
334
+ - `tile_bounds_for_bbox(min_lat, min_lon, max_lat, max_lon, z)`
335
+ - `tile_to_quadkey(x, y, z)`
336
+ - `expand_url(template, x, y, z)`
337
+ - `project_tiles_dir(output_file)`
338
+ - `project_sqlite_dir(output_file)`
339
+ - `project_single_tiff_dir(output_file)`
340
+ - `safe_cache_path(cache_dir, z, x, y)`
341
+ - `default_tile_tif_dir(output_file, z)`
342
+ - `safe_tile_tif_path(tile_tif_dir, z, x, y)`
343
+
344
+ ### `rasterama.geo`
345
+
346
+ - `lonlat_to_webmercator(lon, lat)`
347
+ - `tile_webmercator_bounds(x, y, z)`
348
+ - `mosaic_webmercator_bounds(x_min, y_min, x_max, y_max, z)`
349
+ - `write_worldfile_and_prj(tif_path, width, height, bounds_3857)`
350
+ - `geotiff_extratags_epsg3857(width, height, bounds_3857)`
351
+
352
+ ### `rasterama.imageops`
353
+
354
+ - `make_blank_tile()`
355
+ - `decode_tile(data)`
356
+ - `tile_bytes_to_numpy_rgb(data)`
357
+ - `save_tile_as_tif(data, out_path, z, x, y)`
358
+
359
+ ### `rasterama.download`
360
+
361
+ - `download_one(job, cfg, stop_event=None)`
362
+
363
+ ### `rasterama.stitch`
364
+
365
+ - `iter_chunks(x_min, y_min, x_max, y_max, chunk_size)`
366
+ - `iter_chunk_jobs(cx0, cy0, cx1, cy1, z, x_min, y_min)`
367
+ - `iter_tile_jobs(x_min, y_min, x_max, y_max, z)`
368
+ - `calculate_plan(cfg)`
369
+ - `stitch_tiles(cfg, progress_cb=None, log_cb=None, stop_event=None)`
370
+
371
+ ### `rasterama.tiff`
372
+
373
+ - `format_bytes(num)`
374
+ - `ensure_enough_disk_space(path, required_bytes, log_cb)`
375
+ - `open_direct_bigtiff(output_file, width, height, bounds_3857, log_cb)`
376
+
377
+ ### `rasterama.cuda`
378
+
379
+ - `init_cupy_cuda(log_cb=None)`
380
+ - `CudaUtilizationBooster`
381
+ - `cuda_preprocess_tile(cp, tile_arr)`
382
+
383
+ ### `rasterama.presets`
384
+
385
+ - `MAP_PRESETS`
386
+ - `preset_url(name)`
387
+
388
+ ### `rasterama.cli`
389
+
390
+ - `build_parser()`
391
+ - `main(argv=None)`
392
+
393
+ ## Data models
394
+
395
+ ### `Bounds`
396
+
397
+ Geographic bounding box in `south`, `west`, `north`, `east` order. Includes
398
+ `from_sequence()` and `validate()`.
399
+
400
+ ### `TileJob`
401
+
402
+ Represents one tile download/write job:
403
+
404
+ - `x`
405
+ - `y`
406
+ - `z`
407
+ - `col`
408
+ - `row`
409
+
410
+ ### `TilePlan`
411
+
412
+ Calculated output plan:
413
+
414
+ - `x_min`, `y_min`, `x_max`, `y_max`
415
+ - `cols`, `rows`
416
+ - `width`, `height`
417
+ - `total_tiles`
418
+ - `raw_bytes`
419
+ - `bounds_3857`
420
+
421
+ ### `StitchConfig`
422
+
423
+ Main runtime configuration:
424
+
425
+ - `url_template`
426
+ - `output_file`
427
+ - `z`
428
+ - `min_lat`, `min_lon`, `max_lat`, `max_lon`
429
+ - `workers`
430
+ - `rate_limit_ms`
431
+ - `retries`
432
+ - `timeout`
433
+ - `headers`
434
+ - `chunk_size`
435
+ - `use_cuda_stitch`
436
+ - `cuda_max_chunk_mb`
437
+ - `cuda_utilization_boost`
438
+ - `cuda_load_matrix_size`
439
+
440
+ ### `StitchResult`
441
+
442
+ Returned by `stitch_tiles()`:
443
+
444
+ - `output_file`
445
+ - `plan`
446
+ - `processed`
447
+ - `errors`
448
+ - `stopped`
449
+ - `pixel_size`
450
+ - `tile_size`
451
+
452
+ ## Build
453
+
454
+ From the project folder:
455
+
456
+ ```powershell
457
+ python -m pip install --upgrade build twine
458
+ python -m build
459
+ python -m twine check dist/*
460
+ ```
461
+
462
+ ## Upload to PyPI
463
+
464
+ Use an API token from PyPI. The username for token-based upload is always
465
+ `__token__`.
466
+
467
+ ```powershell
468
+ $wheel = ".\dist\rasterama-0.1.2-py3-none-any.whl"
469
+ python -m twine check $wheel
470
+ python -m twine upload --username __token__ --password "pypi-YOUR_TOKEN_HERE" $wheel
471
+ ```
472
+
473
+ For a safer PowerShell token prompt, see `README_UPLOAD.txt` in the upload
474
+ bundle generated for this package.
475
+
476
+ ## Current limitations
477
+
478
+ - Output CRS is EPSG:3857 / Web Mercator.
479
+ - The core package does not include the old PySide GUI.
480
+ - There is no persistent resume cache in this first core package release.
481
+ - Missing or failed tiles are counted as errors; successful tiles continue to be
482
+ streamed into the output.
483
+ - Provider presets are convenience templates, not usage permission.
484
+
485
+ ## License
486
+
487
+ Add the final project license before public release if this package will be
488
+ distributed beyond private/internal use.