tilearray 0.1.0__tar.gz → 0.2.0__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.
- {tilearray-0.1.0 → tilearray-0.2.0}/CHANGELOG.md +50 -1
- {tilearray-0.1.0 → tilearray-0.2.0}/PKG-INFO +13 -10
- {tilearray-0.1.0 → tilearray-0.2.0}/README.md +8 -5
- tilearray-0.2.0/docs/_static/guides/how-it-works-05-lazy-compute-cache.png +0 -0
- tilearray-0.2.0/docs/api/index.md +160 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/building-docs.md +15 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/example-sources.md +22 -6
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/guides/ea-lidar.md +6 -5
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/guides/gibs-bluemarble.md +4 -3
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/guides/osm-london.md +9 -5
- tilearray-0.2.0/docs/how-it-works.md +168 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/index.md +1 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/install.md +1 -1
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/quickstart.md +21 -7
- tilearray-0.2.0/docs/roadmap.md +107 -0
- tilearray-0.2.0/docs/troubleshooting.md +123 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/pyproject.toml +19 -6
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/__init__.py +12 -12
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/_version.py +1 -1
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/array.py +492 -47
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/decode.py +21 -16
- tilearray-0.2.0/src/tilearray/error_messages.py +359 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/fetch.py +154 -47
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/fetch_presets.py +19 -1
- tilearray-0.2.0/src/tilearray/progress.py +135 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/service/base.py +68 -32
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/service/config.py +31 -52
- tilearray-0.2.0/src/tilearray/service/http.py +105 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/service/wcs.py +122 -39
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/service/wms.py +8 -6
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/service/wmts.py +50 -25
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/service/xyz.py +5 -4
- tilearray-0.2.0/src/tilearray/tile_errors.py +88 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/tiles.py +41 -2
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/types.py +3 -1
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/conftest.py +4 -0
- tilearray-0.2.0/tests/integration/test_preset_soak.py +267 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_array.py +323 -10
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_compute_with_policy.py +28 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_decode.py +91 -0
- tilearray-0.2.0/tests/unit/test_error_messages_stage_gate.py +259 -0
- tilearray-0.2.0/tests/unit/test_error_taxonomy_boundary.py +140 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_fetch.py +154 -1
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_fetch_presets.py +16 -6
- tilearray-0.2.0/tests/unit/test_progress.py +415 -0
- tilearray-0.2.0/tests/unit/test_public_exports.py +60 -0
- tilearray-0.2.0/tests/unit/test_service_http.py +63 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_service_registry.py +2 -1
- tilearray-0.2.0/tests/unit/test_soft_fail.py +682 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_tiles.py +46 -4
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_types.py +2 -1
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_wcs_service.py +234 -12
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_wms_service.py +2 -1
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_wmts_service.py +39 -0
- tilearray-0.1.0/docs/_static/guides/how-it-works-05-lazy-compute-cache.png +0 -0
- tilearray-0.1.0/docs/api/index.md +0 -107
- tilearray-0.1.0/docs/how-it-works.md +0 -112
- tilearray-0.1.0/docs/troubleshooting.md +0 -51
- {tilearray-0.1.0 → tilearray-0.2.0}/.gitignore +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/.pre-commit-config.yaml +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/CONTRIBUTING.md +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/LICENSE +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/Makefile +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/.gitkeep +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/ea-lidar-elevation.json +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/ea-lidar-elevation.png +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/gibs-bluemarble.json +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/gibs-bluemarble.png +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/how-it-works-01-plan.png +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/how-it-works-02-fetch.png +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/how-it-works-03-decode.png +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/how-it-works-04-mosaic.png +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/how-it-works-06-downstream.png +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/how-it-works-pipeline.png +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/manifest.json +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/osm-london.json +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/guides/osm-london.png +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/logo/tilearray-mark-128.png +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/logo/tilearray-mark-favicon-32.png +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/logo/tilearray-mark-favicon.svg +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/logo/tilearray-mark-on-dark.svg +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_static/logo/tilearray-mark.svg +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/_templates/.gitkeep +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/conf.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/docs/guides/index.md +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/example-sources.md +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/guidelines.md +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/errors.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/pressure.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/py.typed +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/service/__init__.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/src/tilearray/service/requests.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/__init__.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/contract/README.md +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/contract/wcs/cassettes/TestEALidarWCSContract.test_describe_coverage.yaml +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/contract/wcs/cassettes/TestEALidarWCSContract.test_get_capabilities.yaml +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/contract/wcs/cassettes/TestEALidarWCSContract.test_get_coverage.yaml +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/contract/wcs/cassettes/TestUSGS3DEPWCSContract.test_describe_coverage_axis_labels.yaml +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/contract/wcs/cassettes/TestUSGS3DEPWCSContract.test_get_coverage_multipart_geotiff.yaml +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/contract/wcs/test_wcs_contract.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/data/ogc_schema_examples/lidar-composite-digital-terrain-model-dtm-1m.xml +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/data/wcs_fixtures/ea_lidar_describe_coverage.xml +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/data/wcs_fixtures/usgs_3dep_describe_coverage.xml +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/data/wcs_tiles/ea_lidar_64x64.tif +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/integration/test_live_endpoints.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_errors.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_fetch_abort_array.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_fetch_bench.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_pressure.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_service_requests.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tests/unit/test_xyz_service.py +0 -0
- {tilearray-0.1.0 → tilearray-0.2.0}/tox.ini +0 -0
|
@@ -7,6 +7,53 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.0] - 2026-11-03
|
|
11
|
+
|
|
12
|
+
Trustworthy-core release: clean-env GeoTIFF install, analysis-ready mosaic attrs, one preferred compute habit, typed public errors, default tile progress, and actionable stage-gate DX — without holding the cut for multi-AOI orchestration or later uniqueness work.
|
|
13
|
+
|
|
14
|
+
### Documentation
|
|
15
|
+
|
|
16
|
+
- Maintainer stage-gate notebook (`notebooks/stage_gate_0_2.ipynb`) + run notes in `notebooks/README.md`: local editable install → live OSM / EA DSP mosaics → politeness knobs, soft-fail attrs, and a human checklist before the 0.2.0 cut
|
|
17
|
+
- Document private/keyed hosts via existing config `params=` / `headers=` (query keys, legacy username/password query params, Bearer/Basic headers); OS Maps XYZ recipe uses env-backed `params` instead of `?key=` in the URL template; soft-fail still hard-aborts 401 (related #58). Caps credential parity for WCS/WMTS is under Changed (#57)
|
|
18
|
+
- Default tile progress + quiet opt-out documented in how-it-works, troubleshooting (“looks hung”), and API index (#86)
|
|
19
|
+
- Troubleshooting: stage-gate symptom→cause table for wrong format / mistyped URL / bad `coverage_id`, and httpx (not `requests`) wording for caps failures (#88)
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Soft-fail observability: `compute_with_policy` refreshes `attrs["tilearray_tile_errors"]` (`soft_failed`, `aborted`, `examples`) from `FetchProgress` after lazy `create_array` — same counters as the eager `compute=True` path (#73)
|
|
24
|
+
|
|
25
|
+
### Breaking
|
|
26
|
+
|
|
27
|
+
- Removed `WCSConfig.for_ea_dsp` and `XYZConfig.for_openstreetmap`. Protocol configs stay on `from_url`; host politeness comes from `tilearray.fetch_presets` — compose with `WCSConfig.from_url(url, coverage_id, **ea_dsp_fetch_defaults())` and `XYZConfig.from_url(OSM_TILE_TEMPLATE, zoom=…, **osm_fetch_defaults())`. Docs, soak scripts, and tests updated to the compose path (alpha; no deprecation shim).
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- Stage-gate errors are more actionable: unsupported formats list library (and cached DescribeCoverage) MIME values; DescribeCoverage / GetCapabilities / `build_service` messages keep status or httpx type, distinguish DNS vs HTML/login vs unknown CoverageId, and redact secret query keys; soft-fail / 401 hard-abort behaviour unchanged (#88)
|
|
32
|
+
- WCS GeoTIFF decode now uses ``tifffile`` directly (bytes or path); dropped the ``geotiff`` → ``zarr<2.13`` / ``numcodecs<0.16`` pin cage so clean-env installs no longer need that dependency gymnastics. XYZ-without-GDAL posture unchanged (no hard rasterio/GDAL runtime dep) (#53)
|
|
33
|
+
- Public-boundary failures now raise the typed `TileArrayError` hierarchy instead of bare `ValueError` / `RuntimeError`: bad inputs → `ValidationError`, caps/XML parse → `ParseError`, service detection / missing decoder → `ConfigurationError`, WCS/WMTS capabilities HTTP (`httpx`) → `NetworkError`. **Compat:** callers that catch bare `ValueError` for library validation must switch to `TileArrayError` / the specific subclass (or catch both during transition). Pydantic model field checks (`BoundingBox` coordinates, etc.) still surface via pydantic as before (#72)
|
|
34
|
+
- WCS/WMTS capabilities and DescribeCoverage (plus direct `WCSService.get_coverage`) now use sync **httpx** with one shared UA/timeout policy and inherit config `headers`/`params` — private-server credentials reach plan-time GETs the same way they reach tiles. Drops the runtime `requests` dependency (#57)
|
|
35
|
+
- Docs: one compute habit on primary paths — OSM/GIBS guides, how-it-works, troubleshooting, and API index use `compute_with_policy`; `load_array` documented as eager sugar for `create_array(..., compute=True)`; quickstart WMTS honesty note (`WMTSConfig` supported, host guide TBD / #60) (#55)
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- Default tqdm-style tile progress for multi-tile mosaics via existing `on_progress` / `FetchProgress` (scripts + notebooks). Quiet opt-out: `show_progress=False`, `TILEARRAY_PROGRESS=0`, or non-TTY/non-Jupyter display. Custom `on_progress=` still replaces the default bar. Runtime dependency: `tqdm`. No second compute API (#86)
|
|
40
|
+
- Analysis-ready mosaic attrs for xarray/rioxarray handoff: Affine `transform` + `transform_source="mosaic_bbox"`, `band_policy`, and elevation GeoTIFF `nodata`/`_FillValue` (NaN after decode). Documented north-up + optional rioxarray recipe; mosaic CRS remains the request `crs=` (never silently replaced by per-tile GeoTIFF tags) (#54)
|
|
41
|
+
- Large-AOI politeness evidence scaffold (#56): `@pytest.mark.soak` multi-tile cold mosaics under EA DSP + OSM preset ceilings (nightly via `@net`/`@slow`, deselected on PRs); offline fail-loud abort under concurrent pressure; maintainer script `scripts/soak_large_aoi_presets.py` for county-/valley-scale soaks; how-it-works / troubleshooting / building-docs note on nightly vs maintainer split
|
|
42
|
+
- Opt-in plan-time tile error policy for mosaics (`on_tile_error=` / `soft_fail=True`) with library preset `soft_fail_exhausted_tiles`: after retries, soft-fill tile-local exhausted failures (404 / 5xx / transport) as NaN blocks without aborting siblings; auth (401), exhausted 429, decode errors, and soft-fail fraction above `soft_fail_max_fraction` still hard-abort. Default remains hard-fail + `FetchProgress.abort` (#65)
|
|
43
|
+
- Top-level `FetchPolicy` export (`from tilearray import FetchPolicy`) so docs/API reference match `__all__` (#70)
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- Public `__all__` no longer advertises parsers (`WCSParser`, `WMTSParser`), concrete services (`WCSService`, `WMSService`, `WMTSService`, `XYZService`), or `BaseService`. Prefer configs + `create_array`; low-level clients remain importable from `tilearray.service` / submodules during alpha (#70)
|
|
48
|
+
- Mosaic `y`/`x` coordinates are **pixel centers** consistent with `attrs["transform"]` (north-up Affine from planned bbox + shape), instead of edge-span `linspace` endpoints (#54)
|
|
49
|
+
- Docs: `**service_options` key families (fetch / planner / identity) and `max_concurrent*` one-job-per-name map in how-it-works, with API + troubleshooting cross-links — no public signature change (#71)
|
|
50
|
+
|
|
51
|
+
## [0.1.1] - 2026-11-01
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- README header logo uses an absolute HTTPS PNG URL so PyPI / Warehouse renders the mark (relative `docs/_static/...` paths do not resolve in the uploaded long description)
|
|
56
|
+
|
|
10
57
|
## [0.1.0] - 2026-10-31
|
|
11
58
|
|
|
12
59
|
Initial alpha release focused on lazy WCS- and XYZ-backed xarray arrays.
|
|
@@ -63,5 +110,7 @@ Initial alpha release focused on lazy WCS- and XYZ-backed xarray arrays.
|
|
|
63
110
|
- Package renamed from scaffold `ogc-array` to `tilearray`; README, CI, and metadata aligned with shipped API
|
|
64
111
|
- EA Lidar WCS GeoTIFF decode and non-divisible tile resize for native-resolution tiles
|
|
65
112
|
|
|
66
|
-
[Unreleased]: https://github.com/MatthewJWhittle/tilearray/compare/v0.
|
|
113
|
+
[Unreleased]: https://github.com/MatthewJWhittle/tilearray/compare/v0.2.0...HEAD
|
|
114
|
+
[0.2.0]: https://github.com/MatthewJWhittle/tilearray/compare/v0.1.1...v0.2.0
|
|
115
|
+
[0.1.1]: https://github.com/MatthewJWhittle/tilearray/compare/v0.1.0...v0.1.1
|
|
67
116
|
[0.1.0]: https://github.com/MatthewJWhittle/tilearray/releases/tag/v0.1.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tilearray
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: A Python library for loading geospatial data from remote tile servers as xarray objects
|
|
5
5
|
Project-URL: Homepage, https://github.com/MatthewJWhittle/tilearray
|
|
6
6
|
Project-URL: Repository, https://github.com/MatthewJWhittle/tilearray
|
|
@@ -226,17 +226,15 @@ Classifier: Typing :: Typed
|
|
|
226
226
|
Requires-Python: >=3.9
|
|
227
227
|
Requires-Dist: dask>=2024.8.0
|
|
228
228
|
Requires-Dist: eval-type-backport>=0.2.0; python_version < '3.10'
|
|
229
|
-
Requires-Dist: geotiff>=0.2.10
|
|
230
229
|
Requires-Dist: httpx>=0.28.1
|
|
231
|
-
Requires-Dist: numcodecs<0.16,>=0.12.1
|
|
232
230
|
Requires-Dist: numpy>=2.0.2
|
|
233
231
|
Requires-Dist: pillow>=11.3.0
|
|
234
232
|
Requires-Dist: pydantic>=2.12.3
|
|
235
233
|
Requires-Dist: pyproj>=3.6.1
|
|
236
|
-
Requires-Dist: requests>=2.32.5
|
|
237
234
|
Requires-Dist: tenacity>=9.0.0
|
|
235
|
+
Requires-Dist: tifffile>=2024.8.30
|
|
236
|
+
Requires-Dist: tqdm>=4.70.1
|
|
238
237
|
Requires-Dist: xarray>=2024.7.0
|
|
239
|
-
Requires-Dist: zarr<2.13,>=2.12.0
|
|
240
238
|
Provides-Extra: dev
|
|
241
239
|
Requires-Dist: coverage>=7.10.7; extra == 'dev'
|
|
242
240
|
Requires-Dist: hypothesis>=6.141.1; extra == 'dev'
|
|
@@ -253,6 +251,8 @@ Requires-Dist: pytest-xdist>=3.8.0; extra == 'dev'
|
|
|
253
251
|
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
254
252
|
Requires-Dist: respx>=0.22.0; extra == 'dev'
|
|
255
253
|
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
254
|
+
Requires-Dist: types-tqdm>=4.67.3.20260205; (python_version >= '3.10') and extra == 'dev'
|
|
255
|
+
Requires-Dist: vcrpy>=7.0.0; extra == 'dev'
|
|
256
256
|
Provides-Extra: docs
|
|
257
257
|
Requires-Dist: matplotlib>=3.9.0; extra == 'docs'
|
|
258
258
|
Requires-Dist: myst-parser>=3.0.0; extra == 'docs'
|
|
@@ -262,7 +262,7 @@ Requires-Dist: sphinx-design>=0.5.0; extra == 'docs'
|
|
|
262
262
|
Requires-Dist: sphinx>=6.0.0; extra == 'docs'
|
|
263
263
|
Description-Content-Type: text/markdown
|
|
264
264
|
|
|
265
|
-
# <img src="
|
|
265
|
+
# <img src="https://matthewjwhittle.github.io/tilearray/_static/logo/tilearray-mark-128.png" alt="" width="36" height="36"> tilearray
|
|
266
266
|
|
|
267
267
|
tilearray turns remote tile services into **Dask**-backed **xarray** arrays — one `create_array` call for WCS, WMS, WMTS, or XYZ. Shared fetch and decode keep mosaics polite to servers and analysis-ready on a laptop or a larger machine.
|
|
268
268
|
|
|
@@ -298,9 +298,10 @@ Prefer **`compute_with_policy`** over plain `.compute()` so Dask workers match t
|
|
|
298
298
|
|
|
299
299
|
```python
|
|
300
300
|
from tilearray import XYZConfig, compute_with_policy, create_array
|
|
301
|
+
from tilearray.fetch_presets import OSM_TILE_TEMPLATE, osm_fetch_defaults
|
|
301
302
|
from tilearray.types import CRS
|
|
302
303
|
|
|
303
|
-
config = XYZConfig.
|
|
304
|
+
config = XYZConfig.from_url(OSM_TILE_TEMPLATE, zoom=16, **osm_fetch_defaults())
|
|
304
305
|
da = create_array(
|
|
305
306
|
config,
|
|
306
307
|
bbox=(-0.005, 51.495, 0.005, 51.505), # small window near central London
|
|
@@ -317,16 +318,18 @@ Include © OpenStreetMap contributors when displaying map imagery.
|
|
|
317
318
|
|
|
318
319
|
```python
|
|
319
320
|
from tilearray import WCSConfig, compute_with_policy, create_array
|
|
321
|
+
from tilearray.fetch_presets import ea_dsp_fetch_defaults
|
|
320
322
|
from tilearray.types import CRS, Format
|
|
321
323
|
|
|
322
|
-
config = WCSConfig.
|
|
324
|
+
config = WCSConfig.from_url(
|
|
323
325
|
"https://environment.data.gov.uk/spatialdata/"
|
|
324
326
|
"lidar-composite-digital-terrain-model-dtm-1m/wcs",
|
|
325
|
-
|
|
327
|
+
"13787b9a-26a4-4775-8523-806d13af58fc__Lidar_Composite_Elevation_DTM_1m",
|
|
326
328
|
crs=CRS.EPSG_27700,
|
|
327
329
|
output_format=Format.GEOTIFF,
|
|
328
330
|
chunk_size=(800, 800),
|
|
329
331
|
grid_shape=(1, 1),
|
|
332
|
+
**ea_dsp_fetch_defaults(),
|
|
330
333
|
)
|
|
331
334
|
bbox = (431900.0, 382700.0, 432700.0, 383500.0) # British National Grid
|
|
332
335
|
da = create_array(config, bbox, CRS.EPSG_27700)
|
|
@@ -334,7 +337,7 @@ elevation = compute_with_policy(da)
|
|
|
334
337
|
print(elevation.shape, float(elevation.mean()))
|
|
335
338
|
```
|
|
336
339
|
|
|
337
|
-
|
|
340
|
+
EA Lidar fetch defaults (`tilearray.fetch_presets.ea_dsp_fetch_defaults`) cap sustained concurrency at **10** (AIMD ceiling). More hosts, WMS recipes, and polite-use notes live in the [docs](https://matthewjwhittle.github.io/tilearray/). WMTS is supported via `WMTSConfig`; a host guide is still TBD.
|
|
338
341
|
|
|
339
342
|
## Development
|
|
340
343
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# <img src="
|
|
1
|
+
# <img src="https://matthewjwhittle.github.io/tilearray/_static/logo/tilearray-mark-128.png" alt="" width="36" height="36"> tilearray
|
|
2
2
|
|
|
3
3
|
tilearray turns remote tile services into **Dask**-backed **xarray** arrays — one `create_array` call for WCS, WMS, WMTS, or XYZ. Shared fetch and decode keep mosaics polite to servers and analysis-ready on a laptop or a larger machine.
|
|
4
4
|
|
|
@@ -34,9 +34,10 @@ Prefer **`compute_with_policy`** over plain `.compute()` so Dask workers match t
|
|
|
34
34
|
|
|
35
35
|
```python
|
|
36
36
|
from tilearray import XYZConfig, compute_with_policy, create_array
|
|
37
|
+
from tilearray.fetch_presets import OSM_TILE_TEMPLATE, osm_fetch_defaults
|
|
37
38
|
from tilearray.types import CRS
|
|
38
39
|
|
|
39
|
-
config = XYZConfig.
|
|
40
|
+
config = XYZConfig.from_url(OSM_TILE_TEMPLATE, zoom=16, **osm_fetch_defaults())
|
|
40
41
|
da = create_array(
|
|
41
42
|
config,
|
|
42
43
|
bbox=(-0.005, 51.495, 0.005, 51.505), # small window near central London
|
|
@@ -53,16 +54,18 @@ Include © OpenStreetMap contributors when displaying map imagery.
|
|
|
53
54
|
|
|
54
55
|
```python
|
|
55
56
|
from tilearray import WCSConfig, compute_with_policy, create_array
|
|
57
|
+
from tilearray.fetch_presets import ea_dsp_fetch_defaults
|
|
56
58
|
from tilearray.types import CRS, Format
|
|
57
59
|
|
|
58
|
-
config = WCSConfig.
|
|
60
|
+
config = WCSConfig.from_url(
|
|
59
61
|
"https://environment.data.gov.uk/spatialdata/"
|
|
60
62
|
"lidar-composite-digital-terrain-model-dtm-1m/wcs",
|
|
61
|
-
|
|
63
|
+
"13787b9a-26a4-4775-8523-806d13af58fc__Lidar_Composite_Elevation_DTM_1m",
|
|
62
64
|
crs=CRS.EPSG_27700,
|
|
63
65
|
output_format=Format.GEOTIFF,
|
|
64
66
|
chunk_size=(800, 800),
|
|
65
67
|
grid_shape=(1, 1),
|
|
68
|
+
**ea_dsp_fetch_defaults(),
|
|
66
69
|
)
|
|
67
70
|
bbox = (431900.0, 382700.0, 432700.0, 383500.0) # British National Grid
|
|
68
71
|
da = create_array(config, bbox, CRS.EPSG_27700)
|
|
@@ -70,7 +73,7 @@ elevation = compute_with_policy(da)
|
|
|
70
73
|
print(elevation.shape, float(elevation.mean()))
|
|
71
74
|
```
|
|
72
75
|
|
|
73
|
-
|
|
76
|
+
EA Lidar fetch defaults (`tilearray.fetch_presets.ea_dsp_fetch_defaults`) cap sustained concurrency at **10** (AIMD ceiling). More hosts, WMS recipes, and polite-use notes live in the [docs](https://matthewjwhittle.github.io/tilearray/). WMTS is supported via `WMTSConfig`; a host guide is still TBD.
|
|
74
77
|
|
|
75
78
|
## Development
|
|
76
79
|
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# API reference
|
|
2
|
+
|
|
3
|
+
Public entry points for building lazy mosaics, configuring services, and handling failures.
|
|
4
|
+
|
|
5
|
+
## Array
|
|
6
|
+
|
|
7
|
+
```{eval-rst}
|
|
8
|
+
.. currentmodule:: tilearray
|
|
9
|
+
|
|
10
|
+
.. autosummary::
|
|
11
|
+
:toctree: generated
|
|
12
|
+
:nosignatures:
|
|
13
|
+
|
|
14
|
+
create_array
|
|
15
|
+
load_array
|
|
16
|
+
compute_with_policy
|
|
17
|
+
array.compute_thread_pool_size
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`create_array` builds a lazy Dask-backed `xarray.DataArray`. Prefer {py:func}`~tilearray.compute_with_policy` over plain `.compute()` so Dask workers match the fetch ceiling. {py:func}`~tilearray.load_array` is eager sugar (`create_array(..., compute=True)` by default) — useful for tiny windows, not a second primary habit. Pass a service **config** (or URL where supported) as the first argument — not only a bare string for every service type.
|
|
21
|
+
|
|
22
|
+
Multi-tile mosaics attach a default tqdm-style progress bar through `on_progress` during compute. Opt out with `show_progress=False` or `TILEARRAY_PROGRESS=0`; pass a custom `on_progress=` to replace the bar. There is no separate `compute_with_progress` helper — use {py:func}`~tilearray.compute_with_policy` as usual. Details: {doc}`../how-it-works` · {doc}`../troubleshooting`.
|
|
23
|
+
|
|
24
|
+
`**service_options` on `create_array` / `load_array` is one bag with three key families (**fetch** politeness, **planner** geometry, **identity** / protocol). Concurrency names each have one job (`max_concurrent_requests` host ceiling vs `FetchPolicy.max_concurrent` shared gate vs `call_max_concurrent` per-call vs `compute_with_policy(..., max_concurrent=)` Dask workers). Name map: {doc}`../how-it-works`.
|
|
25
|
+
|
|
26
|
+
## Configs
|
|
27
|
+
|
|
28
|
+
```{eval-rst}
|
|
29
|
+
.. currentmodule:: tilearray
|
|
30
|
+
|
|
31
|
+
.. autosummary::
|
|
32
|
+
:toctree: generated
|
|
33
|
+
:nosignatures:
|
|
34
|
+
|
|
35
|
+
ServiceConfig
|
|
36
|
+
WCSConfig
|
|
37
|
+
WMSConfig
|
|
38
|
+
WMTSConfig
|
|
39
|
+
XYZConfig
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Configs stay protocol-shaped (`from_url`, …). Host politeness lives in `tilearray.fetch_presets` — compose rather than a second config habit:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from tilearray import WCSConfig, XYZConfig
|
|
46
|
+
from tilearray.fetch_presets import (
|
|
47
|
+
OSM_TILE_TEMPLATE,
|
|
48
|
+
ea_dsp_fetch_defaults,
|
|
49
|
+
osm_fetch_defaults,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
WCSConfig.from_url(url, coverage_id, **ea_dsp_fetch_defaults())
|
|
53
|
+
XYZConfig.from_url(OSM_TILE_TEMPLATE, zoom=16, **osm_fetch_defaults())
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Custom hosts: `from_url` alone (no preset unpack). `WCSConfig.build_service()` validates coverage via live DescribeCoverage (network on first `create_array` path that needs capabilities, not only at import time).
|
|
57
|
+
|
|
58
|
+
## Fetch presets
|
|
59
|
+
|
|
60
|
+
```{eval-rst}
|
|
61
|
+
.. currentmodule:: tilearray.fetch_presets
|
|
62
|
+
|
|
63
|
+
.. autosummary::
|
|
64
|
+
:toctree: generated
|
|
65
|
+
:nosignatures:
|
|
66
|
+
|
|
67
|
+
ea_dsp_fetch_defaults
|
|
68
|
+
osm_fetch_defaults
|
|
69
|
+
tilearray_user_agent
|
|
70
|
+
OSM_TILE_TEMPLATE
|
|
71
|
+
EA_LIDAR_WCS_URL
|
|
72
|
+
EA_LIDAR_COVERAGE_ID
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Import from `tilearray.fetch_presets` (not re-exported on the package root — keeps host folklore off the primary config surface). Constants such as `EA_LIDAR_BENCH_BBOX` are for tests/benches; prefer the helpers above for callers.
|
|
76
|
+
|
|
77
|
+
## Types
|
|
78
|
+
|
|
79
|
+
```{eval-rst}
|
|
80
|
+
.. currentmodule:: tilearray
|
|
81
|
+
|
|
82
|
+
.. autosummary::
|
|
83
|
+
:toctree: generated
|
|
84
|
+
:nosignatures:
|
|
85
|
+
|
|
86
|
+
types.CRS
|
|
87
|
+
types.Format
|
|
88
|
+
types.BoundingBox
|
|
89
|
+
types.TileRequest
|
|
90
|
+
types.TileResponse
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Errors
|
|
94
|
+
|
|
95
|
+
```{eval-rst}
|
|
96
|
+
.. currentmodule:: tilearray
|
|
97
|
+
|
|
98
|
+
.. autosummary::
|
|
99
|
+
:toctree: generated
|
|
100
|
+
:nosignatures:
|
|
101
|
+
|
|
102
|
+
TileArrayError
|
|
103
|
+
ServiceError
|
|
104
|
+
ValidationError
|
|
105
|
+
NetworkError
|
|
106
|
+
ParseError
|
|
107
|
+
ConfigurationError
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
{py:exc}`NetworkError` means a tile failed after retries — mosaics do not leave silent NaN holes **by default**. Caps/capabilities HTTP failures (WCS/WMTS `requests` paths) also raise {py:exc}`NetworkError`.
|
|
111
|
+
|
|
112
|
+
Prefer catching {py:exc}`TileArrayError` (or a subclass) at public boundaries: bad inputs → {py:exc}`ValidationError`, XML/capabilities parse → {py:exc}`ParseError`, service detection / missing decoder → {py:exc}`ConfigurationError`. Do not rely on bare `ValueError` / `RuntimeError` from library entry points.
|
|
113
|
+
|
|
114
|
+
## Tile errors (opt-in soft-fail)
|
|
115
|
+
|
|
116
|
+
```{eval-rst}
|
|
117
|
+
.. currentmodule:: tilearray
|
|
118
|
+
|
|
119
|
+
.. autosummary::
|
|
120
|
+
:toctree: generated
|
|
121
|
+
:nosignatures:
|
|
122
|
+
|
|
123
|
+
TileErrorAction
|
|
124
|
+
TileErrorContext
|
|
125
|
+
soft_fail_exhausted_tiles
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Pass plan-time ``on_tile_error=`` (or ``soft_fail=True``) into {py:func}`~tilearray.create_array` / {py:func}`~tilearray.load_array`. The library preset {py:func}`~tilearray.soft_fail_exhausted_tiles` soft-fills exhausted tile-local fetch failures (404 / 5xx / transport) as NaN (or ``soft_fill_value``) blocks, keeps retries, hard-fails auth / exhausted 429 / decode errors, and aborts when soft-failed fraction exceeds ``soft_fail_max_fraction``. Default remains hard-fail + sibling abort.
|
|
129
|
+
|
|
130
|
+
## Fetch
|
|
131
|
+
|
|
132
|
+
```{eval-rst}
|
|
133
|
+
.. currentmodule:: tilearray
|
|
134
|
+
|
|
135
|
+
.. autosummary::
|
|
136
|
+
:toctree: generated
|
|
137
|
+
:nosignatures:
|
|
138
|
+
|
|
139
|
+
FetchPolicy
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`FetchPolicy` controls concurrency, retries, timeouts, rate limits, and optional AIMD / circuit-breaker behaviour. Service configs expose the same knobs and build a policy via `.fetch_policy()`. Advanced callers may also import it as `tilearray.fetch.FetchPolicy`.
|
|
143
|
+
|
|
144
|
+
`FetchPolicy.max_concurrent` is the **shared process-gate** ceiling. Per-call politeness is `call_max_concurrent` (or a lower `max_concurrent_requests` override on `create_array`). `compute_with_policy(..., max_concurrent=)` sizes Dask workers only — see {doc}`../how-it-works`.
|
|
145
|
+
|
|
146
|
+
## Registry
|
|
147
|
+
|
|
148
|
+
```{eval-rst}
|
|
149
|
+
.. currentmodule:: tilearray
|
|
150
|
+
|
|
151
|
+
.. autosummary::
|
|
152
|
+
:toctree: generated
|
|
153
|
+
:nosignatures:
|
|
154
|
+
|
|
155
|
+
get_service
|
|
156
|
+
register_service
|
|
157
|
+
detect_service_type
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Concrete service clients and parsers (`WCSService`, `WMSService`, `WMTSService`, `XYZService`, `BaseService`, `WCSParser`, `WMTSParser`) are **not** part of the advertised public surface — import them from `tilearray.service` / `tilearray.service.wcs` (etc.) only if you need low-level access. Prefer configs + `create_array`. Arrays from `create_array` are north-up (row 0 = north). Mosaic attrs include `crs`, Affine `transform` (`transform_source="mosaic_bbox"`), `band_policy`, and elevation `nodata`/`_FillValue` when the format is GeoTIFF — see {doc}`../how-it-works` for the rioxarray handoff.
|
|
@@ -24,6 +24,21 @@ make docs-artifacts
|
|
|
24
24
|
|
|
25
25
|
That rebuilds How it works diagrams (offline) and live usage-guide mosaics (network, polite presets). Commit updated assets when they change.
|
|
26
26
|
|
|
27
|
+
## Politeness soak / large-AOI evidence
|
|
28
|
+
|
|
29
|
+
PR CI stays offline (`not slow and not net`). Live preset soaks are opt-in:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Nightly-scale multi-tile soak (EA + OSM ceilings + fail-loud contract)
|
|
33
|
+
uv run pytest -m soak --timeout=300 --cov-fail-under=0
|
|
34
|
+
|
|
35
|
+
# Maintainer large-AOI soak (hundreds–thousands of tiles; feeds 0.3 evidence)
|
|
36
|
+
uv run python scripts/soak_large_aoi_presets.py --host both --profile medium
|
|
37
|
+
uv run python scripts/soak_large_aoi_presets.py --host ea --profile large
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Design notes live in {doc}`how-it-works` (Politeness evidence). Do not wire large profiles into always-on PR jobs.
|
|
41
|
+
|
|
27
42
|
## First open release checklist (`0.1.0`)
|
|
28
43
|
|
|
29
44
|
Do **not** push the release tag until the items below that need human secrets/clicks are done.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Example sources
|
|
2
2
|
|
|
3
|
-
Public endpoints and thin fetch presets for testing host quirks — **not** a product catalogue. Prefer
|
|
3
|
+
Public endpoints and thin fetch presets for testing host quirks — **not** a product catalogue. Prefer `from_url` + `tilearray.fetch_presets` helpers in {doc}`quickstart` where they apply; use bare `from_url` for everything else. Stay polite: identifiable User-Agent where required, and do not raise concurrency past a host's documented ceiling.
|
|
4
4
|
|
|
5
5
|
## OpenStreetMap raster tiles (XYZ)
|
|
6
6
|
|
|
7
|
-
- Template: `https://tile.openstreetmap.org/{z}/{x}/{y}.png`
|
|
8
|
-
- Prefer `XYZConfig.
|
|
7
|
+
- Template: `https://tile.openstreetmap.org/{z}/{x}/{y}.png` (`OSM_TILE_TEMPLATE`)
|
|
8
|
+
- Prefer `XYZConfig.from_url(OSM_TILE_TEMPLATE, zoom=..., **osm_fetch_defaults())`.
|
|
9
9
|
- OSMF wants an identifiable User-Agent and polite use — the preset applies fixed limits (max 2 in-flight, ~2 req/s, no AIMD).
|
|
10
10
|
- Open data; include © OpenStreetMap contributors when displaying.
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ Public endpoints and thin fetch presets for testing host quirks — **not** a pr
|
|
|
13
13
|
|
|
14
14
|
- URL: `https://environment.data.gov.uk/spatialdata/lidar-composite-digital-terrain-model-dtm-1m/wcs`
|
|
15
15
|
- CoverageId: `13787b9a-26a4-4775-8523-806d13af58fc__Lidar_Composite_Elevation_DTM_1m`
|
|
16
|
-
- Prefer `WCSConfig.
|
|
16
|
+
- Prefer `WCSConfig.from_url(url, coverage_id, **ea_dsp_fetch_defaults())` with this coverage id.
|
|
17
17
|
- The CoverageId comes from GetCapabilities (often `UUID__LayerName`) — never assume the URL path slug is the id.
|
|
18
18
|
- Preset AIMD: start 8, ceiling **10**, floor 4, ×0.75 pressure, sustained-403 circuit breaker. For county-scale cold mosaics, keep `max_concurrent_requests` ≤ **10**.
|
|
19
19
|
|
|
@@ -40,8 +40,24 @@ Public endpoints and thin fetch presets for testing host quirks — **not** a pr
|
|
|
40
40
|
|
|
41
41
|
## OS Maps API ZXY (needs key)
|
|
42
42
|
|
|
43
|
-
- Template: `https://api.os.uk/maps/raster/v1/zxy/Road_3857/{z}/{x}/{y}.png
|
|
44
|
-
-
|
|
43
|
+
- Template (no secret in the URL): `https://api.os.uk/maps/raster/v1/zxy/Road_3857/{z}/{x}/{y}.png`
|
|
44
|
+
- Pass the key via config `params` from the environment — prefer this over `?key=…` in the template:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import os
|
|
48
|
+
from tilearray import XYZConfig, compute_with_policy, create_array
|
|
49
|
+
from tilearray.types import CRS
|
|
50
|
+
|
|
51
|
+
config = XYZConfig.from_url(
|
|
52
|
+
"https://api.os.uk/maps/raster/v1/zxy/Road_3857/{z}/{x}/{y}.png",
|
|
53
|
+
zoom=10,
|
|
54
|
+
params={"key": os.environ["OS_MAPS_API_KEY"]},
|
|
55
|
+
)
|
|
56
|
+
da = create_array(config, bbox=(-0.1, 51.4, 0.0, 51.5), crs=CRS.EPSG_4326)
|
|
57
|
+
arr = compute_with_policy(da)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- Useful for real HTTP 429 throttle behaviour. Attribution required. Do not commit keys. Same `params=` / `headers=` pattern covers other keyed or private tile hosts — see {doc}`troubleshooting`.
|
|
45
61
|
|
|
46
62
|
## Other XYZ (restricted)
|
|
47
63
|
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Fetch a small British National Grid window from the Environment Agency Lidar composite DTM (WCS), plot elevation, and summarise the distribution.
|
|
4
4
|
|
|
5
|
-
Uses `WCSConfig.
|
|
5
|
+
Uses `WCSConfig.from_url(..., **ea_dsp_fetch_defaults())` (AIMD under a hard ceiling, pressure circuit breaker). Keep large cold mosaics at or below the preset ceiling — higher limits can trip gateway pressure.
|
|
6
6
|
|
|
7
7
|
## Code
|
|
8
8
|
|
|
9
9
|
```python
|
|
10
|
-
from tilearray import compute_with_policy, create_array
|
|
11
|
-
from tilearray.
|
|
10
|
+
from tilearray import WCSConfig, compute_with_policy, create_array
|
|
11
|
+
from tilearray.fetch_presets import ea_dsp_fetch_defaults
|
|
12
12
|
from tilearray.types import CRS, Format
|
|
13
13
|
|
|
14
14
|
wcs_url = (
|
|
@@ -19,13 +19,14 @@ coverage_id = (
|
|
|
19
19
|
"13787b9a-26a4-4775-8523-806d13af58fc__Lidar_Composite_Elevation_DTM_1m"
|
|
20
20
|
)
|
|
21
21
|
|
|
22
|
-
config = WCSConfig.
|
|
22
|
+
config = WCSConfig.from_url(
|
|
23
23
|
wcs_url,
|
|
24
|
-
coverage_id
|
|
24
|
+
coverage_id,
|
|
25
25
|
crs=CRS.EPSG_27700,
|
|
26
26
|
output_format=Format.GEOTIFF,
|
|
27
27
|
chunk_size=(64, 64),
|
|
28
28
|
resolution=(1.0, 1.0),
|
|
29
|
+
**ea_dsp_fetch_defaults(),
|
|
29
30
|
)
|
|
30
31
|
|
|
31
32
|
# ~256 m OSGB window
|
|
@@ -5,7 +5,7 @@ Load a small mid-Atlantic window from NASA GIBS as JPEG RGB tiles. Uses `XYZConf
|
|
|
5
5
|
## Code
|
|
6
6
|
|
|
7
7
|
```python
|
|
8
|
-
from tilearray import XYZConfig, create_array
|
|
8
|
+
from tilearray import XYZConfig, compute_with_policy, create_array
|
|
9
9
|
from tilearray.types import CRS, Format
|
|
10
10
|
|
|
11
11
|
template = (
|
|
@@ -27,8 +27,9 @@ config = XYZConfig.from_url(
|
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
bbox = (-40.0, 20.0, -10.0, 45.0)
|
|
30
|
-
da = create_array(config, bbox, CRS.EPSG_4326
|
|
31
|
-
|
|
30
|
+
da = create_array(config, bbox, CRS.EPSG_4326)
|
|
31
|
+
arr = compute_with_policy(da)
|
|
32
|
+
print(arr.shape, arr.dims) # expect (y, x, band) for RGB JPEG
|
|
32
33
|
```
|
|
33
34
|
|
|
34
35
|
## Result
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Load a small slippy-map window, compute it, and plot the mosaic.
|
|
4
4
|
|
|
5
|
-
Uses `XYZConfig.
|
|
5
|
+
Uses `XYZConfig.from_url(OSM_TILE_TEMPLATE, …, **osm_fetch_defaults())` (identifiable User-Agent, max 2 in-flight, ~2 req/s). Include **© OpenStreetMap contributors** when displaying the imagery.
|
|
6
6
|
|
|
7
7
|
```{note}
|
|
8
8
|
OSM raster tiles are often **palette PNGs**, so the mosaic may be single-band (grayscale) today. For a full-colour RGB XYZ example see {doc}`gibs-bluemarble`.
|
|
@@ -11,18 +11,22 @@ OSM raster tiles are often **palette PNGs**, so the mosaic may be single-band (g
|
|
|
11
11
|
## Code
|
|
12
12
|
|
|
13
13
|
```python
|
|
14
|
-
from tilearray import XYZConfig, create_array
|
|
14
|
+
from tilearray import XYZConfig, compute_with_policy, create_array
|
|
15
|
+
from tilearray.fetch_presets import OSM_TILE_TEMPLATE, osm_fetch_defaults
|
|
15
16
|
from tilearray.types import CRS, Format
|
|
16
17
|
|
|
17
|
-
config = XYZConfig.
|
|
18
|
+
config = XYZConfig.from_url(
|
|
19
|
+
OSM_TILE_TEMPLATE,
|
|
18
20
|
zoom=16,
|
|
19
21
|
output_format=Format.PNG,
|
|
20
22
|
chunk_size=(256, 256),
|
|
23
|
+
**osm_fetch_defaults(),
|
|
21
24
|
)
|
|
22
25
|
|
|
23
26
|
bbox = (-0.005, 51.495, 0.005, 51.505) # ~central London
|
|
24
|
-
da = create_array(config, bbox, CRS.EPSG_4326
|
|
25
|
-
|
|
27
|
+
da = create_array(config, bbox, CRS.EPSG_4326)
|
|
28
|
+
arr = compute_with_policy(da)
|
|
29
|
+
print(arr.shape, arr.dims, da.attrs["service_type"])
|
|
26
30
|
```
|
|
27
31
|
|
|
28
32
|
## Result
|