geoai-py 0.4.2__tar.gz → 0.4.3__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.
Files changed (101) hide show
  1. {geoai_py-0.4.2 → geoai_py-0.4.3}/.gitignore +1 -0
  2. {geoai_py-0.4.2 → geoai_py-0.4.3}/PKG-INFO +1 -1
  3. geoai_py-0.4.3/docs/examples/planetary_computer.ipynb +338 -0
  4. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai/__init__.py +1 -1
  5. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai/download.py +138 -34
  6. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai/extract.py +153 -46
  7. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai/geoai.py +13 -0
  8. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai_py.egg-info/PKG-INFO +1 -1
  9. {geoai_py-0.4.2 → geoai_py-0.4.3}/pyproject.toml +2 -2
  10. geoai_py-0.4.2/docs/examples/planetary_computer.ipynb +0 -120
  11. {geoai_py-0.4.2 → geoai_py-0.4.3}/.editorconfig +0 -0
  12. {geoai_py-0.4.2 → geoai_py-0.4.3}/.github/FUNDING.yml +0 -0
  13. {geoai_py-0.4.2 → geoai_py-0.4.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  14. {geoai_py-0.4.2 → geoai_py-0.4.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  15. {geoai_py-0.4.2 → geoai_py-0.4.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  16. {geoai_py-0.4.2 → geoai_py-0.4.3}/.github/dependabot.yml +0 -0
  17. {geoai_py-0.4.2 → geoai_py-0.4.3}/.github/workflows/docs-build.yml +0 -0
  18. {geoai_py-0.4.2 → geoai_py-0.4.3}/.github/workflows/docs.yml +0 -0
  19. {geoai_py-0.4.2 → geoai_py-0.4.3}/.github/workflows/macos.yml +0 -0
  20. {geoai_py-0.4.2 → geoai_py-0.4.3}/.github/workflows/pypi.yml +0 -0
  21. {geoai_py-0.4.2 → geoai_py-0.4.3}/.github/workflows/ubuntu.yml +0 -0
  22. {geoai_py-0.4.2 → geoai_py-0.4.3}/.github/workflows/windows.yml +0 -0
  23. {geoai_py-0.4.2 → geoai_py-0.4.3}/.pre-commit-config.yaml +0 -0
  24. {geoai_py-0.4.2 → geoai_py-0.4.3}/LICENSE +0 -0
  25. {geoai_py-0.4.2 → geoai_py-0.4.3}/MANIFEST.in +0 -0
  26. {geoai_py-0.4.2 → geoai_py-0.4.3}/README.md +0 -0
  27. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/CNAME +0 -0
  28. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/assets/logo.ico +0 -0
  29. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/assets/logo.png +0 -0
  30. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/assets/logo_rect.png +0 -0
  31. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/changelog.md +0 -0
  32. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/contributing.md +0 -0
  33. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/download.md +0 -0
  34. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/_template.ipynb +0 -0
  35. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/building_footprints_africa.ipynb +0 -0
  36. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/building_footprints_china.ipynb +0 -0
  37. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/building_footprints_usa.ipynb +0 -0
  38. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/building_regularization.ipynb +0 -0
  39. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/car_detection.ipynb +0 -0
  40. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/data_visualization.ipynb +0 -0
  41. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/dataviz/lidar_viz.ipynb +0 -0
  42. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/dataviz/raster_viz.ipynb +0 -0
  43. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/dataviz/vector_viz.ipynb +0 -0
  44. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/download_data.ipynb +0 -0
  45. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/download_sentinel2.ipynb +0 -0
  46. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/geometric_properties.ipynb +0 -0
  47. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/image_chips.ipynb +0 -0
  48. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/jupytext.toml +0 -0
  49. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/parking_spot_detection.ipynb +0 -0
  50. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/rastervision/semantic_segmentation.ipynb +0 -0
  51. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/arcgis.ipynb +0 -0
  52. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/automatic_mask_generator.ipynb +0 -0
  53. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/automatic_mask_generator_hq.ipynb +0 -0
  54. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/box_prompts.ipynb +0 -0
  55. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/fast_sam.ipynb +0 -0
  56. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/input_prompts.ipynb +0 -0
  57. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/input_prompts_hq.ipynb +0 -0
  58. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/maxar_open_data.ipynb +0 -0
  59. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/satellite-predictor.ipynb +0 -0
  60. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/satellite.ipynb +0 -0
  61. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/swimming_pools.ipynb +0 -0
  62. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/text_prompts.ipynb +0 -0
  63. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/samgeo/text_prompts_batch.ipynb +0 -0
  64. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/ship_detection.ipynb +0 -0
  65. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/solar_panel_detection.ipynb +0 -0
  66. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/text_prompt_segmentation.ipynb +0 -0
  67. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/train_building_footprints_usa.ipynb +0 -0
  68. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/train_car_detection.ipynb +0 -0
  69. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/train_object_detection_model.ipynb +0 -0
  70. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/train_ship_detection.ipynb +0 -0
  71. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/train_solar_panel_detection.ipynb +0 -0
  72. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/view_metadata.ipynb +0 -0
  73. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/examples/wetland_mapping.ipynb +0 -0
  74. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/extract.md +0 -0
  75. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/faq.md +0 -0
  76. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/geoai.md +0 -0
  77. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/hf.md +0 -0
  78. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/index.md +0 -0
  79. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/installation.md +0 -0
  80. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/overrides/main.html +0 -0
  81. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/segment.md +0 -0
  82. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/segmentation.md +0 -0
  83. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/train.md +0 -0
  84. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/usage.md +0 -0
  85. {geoai_py-0.4.2 → geoai_py-0.4.3}/docs/utils.md +0 -0
  86. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai/hf.py +0 -0
  87. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai/segment.py +0 -0
  88. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai/segmentation.py +0 -0
  89. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai/train.py +0 -0
  90. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai/utils.py +0 -0
  91. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai_py.egg-info/SOURCES.txt +0 -0
  92. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai_py.egg-info/dependency_links.txt +0 -0
  93. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai_py.egg-info/entry_points.txt +0 -0
  94. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai_py.egg-info/requires.txt +0 -0
  95. {geoai_py-0.4.2 → geoai_py-0.4.3}/geoai_py.egg-info/top_level.txt +0 -0
  96. {geoai_py-0.4.2 → geoai_py-0.4.3}/mkdocs.yml +0 -0
  97. {geoai_py-0.4.2 → geoai_py-0.4.3}/requirements.txt +0 -0
  98. {geoai_py-0.4.2 → geoai_py-0.4.3}/requirements_docs.txt +0 -0
  99. {geoai_py-0.4.2 → geoai_py-0.4.3}/setup.cfg +0 -0
  100. {geoai_py-0.4.2 → geoai_py-0.4.3}/tests/__init__.py +0 -0
  101. {geoai_py-0.4.2 → geoai_py-0.4.3}/tests/test_geoai.py +0 -0
@@ -14,6 +14,7 @@ docs/examples/*.md
14
14
  *.xml
15
15
  docs/examples/output/
16
16
  docs/examples/*.png
17
+ docs/examples/data/
17
18
  *.pth
18
19
 
19
20
  # Distribution / packaging
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geoai-py
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: A Python package for using Artificial Intelligence (AI) with geospatial data
5
5
  Author-email: Qiusheng Wu <giswqs@gmail.com>
6
6
  License: MIT License
@@ -0,0 +1,338 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Download Data from Planetary Computer\n",
8
+ "\n",
9
+ "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/opengeos/geoai/blob/main/docs/examples/planetary_computer.ipynb)\n",
10
+ "\n",
11
+ "## Install package\n",
12
+ "To use the `geoai-py` package, ensure it is installed in your environment. Uncomment the command below if needed."
13
+ ]
14
+ },
15
+ {
16
+ "cell_type": "code",
17
+ "execution_count": null,
18
+ "metadata": {},
19
+ "outputs": [],
20
+ "source": [
21
+ "# %pip install geoai-py"
22
+ ]
23
+ },
24
+ {
25
+ "cell_type": "markdown",
26
+ "metadata": {},
27
+ "source": [
28
+ "## Import libraries"
29
+ ]
30
+ },
31
+ {
32
+ "cell_type": "code",
33
+ "execution_count": null,
34
+ "metadata": {},
35
+ "outputs": [],
36
+ "source": [
37
+ "import geoai"
38
+ ]
39
+ },
40
+ {
41
+ "cell_type": "markdown",
42
+ "metadata": {},
43
+ "source": [
44
+ "## Retrieve collections"
45
+ ]
46
+ },
47
+ {
48
+ "cell_type": "code",
49
+ "execution_count": null,
50
+ "metadata": {},
51
+ "outputs": [],
52
+ "source": [
53
+ "collections = geoai.pc_collection_list()\n",
54
+ "collections"
55
+ ]
56
+ },
57
+ {
58
+ "cell_type": "markdown",
59
+ "metadata": {},
60
+ "source": [
61
+ "## Search NAIP imagery"
62
+ ]
63
+ },
64
+ {
65
+ "cell_type": "code",
66
+ "execution_count": null,
67
+ "metadata": {},
68
+ "outputs": [],
69
+ "source": [
70
+ "items = geoai.pc_stac_search(\n",
71
+ " collection=\"naip\",\n",
72
+ " bbox=[-76.6657, 39.2648, -76.6478, 39.2724], # Baltimore area\n",
73
+ " time_range=\"2013-01-01/2014-12-31\",\n",
74
+ ")"
75
+ ]
76
+ },
77
+ {
78
+ "cell_type": "code",
79
+ "execution_count": null,
80
+ "metadata": {},
81
+ "outputs": [],
82
+ "source": [
83
+ "items"
84
+ ]
85
+ },
86
+ {
87
+ "cell_type": "markdown",
88
+ "metadata": {},
89
+ "source": [
90
+ "## Visualize NAIP imagery"
91
+ ]
92
+ },
93
+ {
94
+ "cell_type": "code",
95
+ "execution_count": null,
96
+ "metadata": {},
97
+ "outputs": [],
98
+ "source": [
99
+ "geoai.pc_item_asset_list(items[0])"
100
+ ]
101
+ },
102
+ {
103
+ "cell_type": "code",
104
+ "execution_count": null,
105
+ "metadata": {},
106
+ "outputs": [],
107
+ "source": [
108
+ "geoai.view_pc_item(item=items[0])"
109
+ ]
110
+ },
111
+ {
112
+ "cell_type": "markdown",
113
+ "metadata": {},
114
+ "source": [
115
+ "## Download NAIP imagery"
116
+ ]
117
+ },
118
+ {
119
+ "cell_type": "code",
120
+ "execution_count": null,
121
+ "metadata": {},
122
+ "outputs": [],
123
+ "source": [
124
+ "downloaded = geoai.pc_stac_download(\n",
125
+ " items, output_dir=\"data\", assets=[\"image\", \"thumbnail\"]\n",
126
+ ")"
127
+ ]
128
+ },
129
+ {
130
+ "cell_type": "markdown",
131
+ "metadata": {},
132
+ "source": [
133
+ "## Search land cover data"
134
+ ]
135
+ },
136
+ {
137
+ "cell_type": "code",
138
+ "execution_count": null,
139
+ "metadata": {},
140
+ "outputs": [],
141
+ "source": [
142
+ "items = geoai.pc_stac_search(\n",
143
+ " collection=\"chesapeake-lc-13\",\n",
144
+ " bbox=[-76.6657, 39.2648, -76.6478, 39.2724], # Baltimore area\n",
145
+ " time_range=\"2013-01-01/2014-12-31\",\n",
146
+ " max_items=10,\n",
147
+ ")"
148
+ ]
149
+ },
150
+ {
151
+ "cell_type": "code",
152
+ "execution_count": null,
153
+ "metadata": {},
154
+ "outputs": [],
155
+ "source": [
156
+ "items"
157
+ ]
158
+ },
159
+ {
160
+ "cell_type": "markdown",
161
+ "metadata": {},
162
+ "source": [
163
+ "## Visualize land cover data"
164
+ ]
165
+ },
166
+ {
167
+ "cell_type": "code",
168
+ "execution_count": null,
169
+ "metadata": {},
170
+ "outputs": [],
171
+ "source": [
172
+ "geoai.pc_item_asset_list(items[0])"
173
+ ]
174
+ },
175
+ {
176
+ "cell_type": "code",
177
+ "execution_count": null,
178
+ "metadata": {},
179
+ "outputs": [],
180
+ "source": [
181
+ "geoai.view_pc_item(item=items[0], colormap_name=\"tab10\", basemap=\"SATELLITE\")"
182
+ ]
183
+ },
184
+ {
185
+ "cell_type": "markdown",
186
+ "metadata": {},
187
+ "source": [
188
+ "## Download land cover data"
189
+ ]
190
+ },
191
+ {
192
+ "cell_type": "code",
193
+ "execution_count": null,
194
+ "metadata": {},
195
+ "outputs": [],
196
+ "source": [
197
+ "geoai.pc_stac_download(items[0], output_dir=\"data\", assets=[\"data\", \"rendered_preview\"])"
198
+ ]
199
+ },
200
+ {
201
+ "cell_type": "code",
202
+ "execution_count": null,
203
+ "metadata": {},
204
+ "outputs": [],
205
+ "source": [
206
+ "ds = geoai.read_pc_item_asset(items[0], asset=\"data\")"
207
+ ]
208
+ },
209
+ {
210
+ "cell_type": "code",
211
+ "execution_count": null,
212
+ "metadata": {},
213
+ "outputs": [],
214
+ "source": [
215
+ "ds"
216
+ ]
217
+ },
218
+ {
219
+ "cell_type": "markdown",
220
+ "metadata": {},
221
+ "source": [
222
+ "## Search Landsat data"
223
+ ]
224
+ },
225
+ {
226
+ "cell_type": "code",
227
+ "execution_count": null,
228
+ "metadata": {},
229
+ "outputs": [],
230
+ "source": [
231
+ "items = geoai.pc_stac_search(\n",
232
+ " collection=\"landsat-c2-l2\",\n",
233
+ " bbox=[-76.6657, 39.2648, -76.6478, 39.2724], # Baltimore area\n",
234
+ " time_range=\"2024-10-27/2024-12-31\",\n",
235
+ " query={\"eo:cloud_cover\": {\"lt\": 1}},\n",
236
+ " max_items=10,\n",
237
+ ")"
238
+ ]
239
+ },
240
+ {
241
+ "cell_type": "code",
242
+ "execution_count": null,
243
+ "metadata": {},
244
+ "outputs": [],
245
+ "source": [
246
+ "items"
247
+ ]
248
+ },
249
+ {
250
+ "cell_type": "markdown",
251
+ "metadata": {},
252
+ "source": [
253
+ "## Visualize Landsat data"
254
+ ]
255
+ },
256
+ {
257
+ "cell_type": "code",
258
+ "execution_count": null,
259
+ "metadata": {},
260
+ "outputs": [],
261
+ "source": [
262
+ "geoai.pc_item_asset_list(items[0])"
263
+ ]
264
+ },
265
+ {
266
+ "cell_type": "code",
267
+ "execution_count": null,
268
+ "metadata": {},
269
+ "outputs": [],
270
+ "source": [
271
+ "geoai.view_pc_item(item=items[0], assets=[\"red\", \"green\", \"blue\"])"
272
+ ]
273
+ },
274
+ {
275
+ "cell_type": "code",
276
+ "execution_count": null,
277
+ "metadata": {},
278
+ "outputs": [],
279
+ "source": [
280
+ "geoai.view_pc_item(item=items[0], assets=[\"nir08\", \"red\", \"green\"])"
281
+ ]
282
+ },
283
+ {
284
+ "cell_type": "code",
285
+ "execution_count": null,
286
+ "metadata": {},
287
+ "outputs": [],
288
+ "source": [
289
+ "geoai.view_pc_item(\n",
290
+ " item=items[0],\n",
291
+ " expression=\"(nir08-red)/(nir08+red)\",\n",
292
+ " rescale=\"-1,1\",\n",
293
+ " colormap_name=\"greens\",\n",
294
+ " name=\"NDVI Green\",\n",
295
+ ")"
296
+ ]
297
+ },
298
+ {
299
+ "cell_type": "markdown",
300
+ "metadata": {},
301
+ "source": [
302
+ "## Download Landsat data"
303
+ ]
304
+ },
305
+ {
306
+ "cell_type": "code",
307
+ "execution_count": null,
308
+ "metadata": {},
309
+ "outputs": [],
310
+ "source": [
311
+ "geoai.pc_stac_download(\n",
312
+ " items[0], output_dir=\"data\", assets=[\"nir08\", \"red\", \"green\", \"blue\"]\n",
313
+ ")"
314
+ ]
315
+ }
316
+ ],
317
+ "metadata": {
318
+ "kernelspec": {
319
+ "display_name": "geo",
320
+ "language": "python",
321
+ "name": "python3"
322
+ },
323
+ "language_info": {
324
+ "codemirror_mode": {
325
+ "name": "ipython",
326
+ "version": 3
327
+ },
328
+ "file_extension": ".py",
329
+ "mimetype": "text/x-python",
330
+ "name": "python",
331
+ "nbconvert_exporter": "python",
332
+ "pygments_lexer": "ipython3",
333
+ "version": "3.12.9"
334
+ }
335
+ },
336
+ "nbformat": 4,
337
+ "nbformat_minor": 2
338
+ }
@@ -2,7 +2,7 @@
2
2
 
3
3
  __author__ = """Qiusheng Wu"""
4
4
  __email__ = "giswqs@gmail.com"
5
- __version__ = "0.4.2"
5
+ __version__ = "0.4.3"
6
6
 
7
7
 
8
8
  import os
@@ -10,8 +10,9 @@ import matplotlib.pyplot as plt
10
10
  import numpy as np
11
11
  import pandas as pd
12
12
  import planetary_computer as pc
13
+ import pystac
13
14
  import requests
14
- import rioxarray
15
+ import rioxarray as rxr
15
16
  import xarray as xr
16
17
  from pystac_client import Client
17
18
  from shapely.geometry import box
@@ -121,7 +122,7 @@ def download_naip(
121
122
  #
122
123
  else:
123
124
  # Fallback to direct rioxarray opening (less common case)
124
- data = rioxarray.open_rasterio(rgb_asset.href)
125
+ data = rxr.open_rasterio(rgb_asset.href)
125
126
  data.rio.to_raster(output_path)
126
127
 
127
128
  downloaded_files.append(output_path)
@@ -129,7 +130,7 @@ def download_naip(
129
130
 
130
131
  # Optional: Display a preview (uncomment if needed)
131
132
  if preview:
132
- data = rioxarray.open_rasterio(output_path)
133
+ data = rxr.open_rasterio(output_path)
133
134
  preview_raster(data)
134
135
 
135
136
  except Exception as e:
@@ -516,7 +517,7 @@ def download_pc_stac_item(
516
517
  )
517
518
  # Still need to open the file to get the data for merging
518
519
  if merge_bands:
519
- band_data = rioxarray.open_rasterio(file_path)
520
+ band_data = rxr.open_rasterio(file_path)
520
521
  band_data_arrays.append((band, band_data))
521
522
  band_names.append(band)
522
523
  result[band] = file_path
@@ -525,7 +526,7 @@ def download_pc_stac_item(
525
526
  if show_progress and not isinstance(progress_iter, list):
526
527
  progress_iter.set_description(f"Downloading {band}")
527
528
 
528
- band_data = rioxarray.open_rasterio(band_url)
529
+ band_data = rxr.open_rasterio(band_url)
529
530
 
530
531
  # Store the data array for potential merging later
531
532
  if merge_bands:
@@ -866,10 +867,9 @@ def pc_stac_search(
866
867
  def pc_stac_download(
867
868
  items,
868
869
  output_dir=".",
869
- asset_keys=None,
870
+ assets=None,
870
871
  max_workers=4,
871
872
  skip_existing=True,
872
- sign_urls=True,
873
873
  ):
874
874
  """
875
875
  Download assets from STAC items retrieved from the Planetary Computer.
@@ -882,7 +882,7 @@ def pc_stac_download(
882
882
  items (list or pystac.Item): STAC Item object or list of STAC Item objects.
883
883
  output_dir (str, optional): Directory where assets will be saved.
884
884
  Defaults to current directory.
885
- asset_keys (list, optional): List of asset keys to download. If None,
885
+ assets (list, optional): List of asset keys to download. If None,
886
886
  downloads all available assets. Defaults to None.
887
887
  max_workers (int, optional): Maximum number of concurrent download threads.
888
888
  Defaults to 4.
@@ -899,7 +899,7 @@ def pc_stac_download(
899
899
  TypeError: If items is not a STAC Item or list of STAC Items.
900
900
  IOError: If there's an error writing the downloaded assets to disk.
901
901
  """
902
- import pystac
902
+
903
903
  from concurrent.futures import ThreadPoolExecutor, as_completed
904
904
 
905
905
  # Handle single item case
@@ -911,31 +911,13 @@ def pc_stac_download(
911
911
  # Create output directory if it doesn't exist
912
912
  os.makedirs(output_dir, exist_ok=True)
913
913
 
914
- # Function to sign URLs if needed
915
- def get_signed_url(href):
916
- if not sign_urls:
917
- return href
918
-
919
- # Planetary Computer typically requires signing URLs for accessing data
920
- # Check if the URL is from Microsoft Planetary Computer
921
- if "planetarycomputer" in href:
922
- try:
923
- sign_url = "https://planetarycomputer.microsoft.com/api/sas/v1/sign"
924
- response = requests.get(sign_url, params={"href": href})
925
- response.raise_for_status()
926
- return response.json().get("href", href)
927
- except Exception as e:
928
- print(f"Warning: Failed to sign URL {href}: {str(e)}")
929
- return href
930
- return href
931
-
932
914
  # Function to download a single asset
933
915
  def download_asset(item, asset_key, asset):
916
+ item = pc.sign(item)
934
917
  item_id = item.id
935
918
 
936
919
  # Get the asset URL and sign it if needed
937
- asset_url = get_signed_url(asset.href)
938
-
920
+ asset_url = item.assets[asset_key].href
939
921
  # Determine output filename
940
922
  if asset.media_type:
941
923
  # Use appropriate file extension based on media type
@@ -995,13 +977,11 @@ def pc_stac_download(
995
977
  print(f"Processing STAC item: {item_id}")
996
978
 
997
979
  # Determine which assets to download
998
- if asset_keys:
999
- assets_to_download = {
1000
- k: v for k, v in item.assets.items() if k in asset_keys
1001
- }
980
+ if assets:
981
+ assets_to_download = {k: v for k, v in item.assets.items() if k in assets}
1002
982
  if not assets_to_download:
1003
983
  print(
1004
- f"Warning: None of the specified asset keys {asset_keys} found in item {item_id}"
984
+ f"Warning: None of the specified asset keys {assets} found in item {item_id}"
1005
985
  )
1006
986
  print(f"Available asset keys: {list(item.assets.keys())}")
1007
987
  continue
@@ -1038,3 +1018,127 @@ def pc_stac_download(
1038
1018
  print(f"\nDownloaded {total_assets} assets for {len(results)} items")
1039
1019
 
1040
1020
  return results
1021
+
1022
+
1023
+ def pc_item_asset_list(item):
1024
+ """
1025
+ Retrieve the list of asset keys from a STAC item in the Planetary Computer catalog.
1026
+
1027
+ Args:
1028
+ item (str): The URL of the STAC item.
1029
+
1030
+ Returns:
1031
+ list: A list of asset keys available in the signed STAC item.
1032
+ """
1033
+ if isinstance(item, str):
1034
+ item = pystac.Item.from_file(item)
1035
+
1036
+ if not isinstance(item, pystac.Item):
1037
+ raise ValueError("item_url must be a string (URL) or a pystac.Item object")
1038
+
1039
+ return list(item.assets.keys())
1040
+
1041
+
1042
+ def read_pc_item_asset(item, asset, output=None, as_cog=True, **kwargs):
1043
+ """
1044
+ Read a specific asset from a STAC item in the Planetary Computer catalog.
1045
+
1046
+ Args:
1047
+ item (str): The URL of the STAC item.
1048
+ asset (str): The key of the asset to read.
1049
+ output (str, optional): If specified, the path to save the asset as a raster file.
1050
+ as_cog (bool, optional): If True, save the asset as a Cloud Optimized GeoTIFF (COG).
1051
+
1052
+ Returns:
1053
+ xarray.DataArray: The data array for the specified asset.
1054
+ """
1055
+ if isinstance(item, str):
1056
+ item = pystac.Item.from_file(item)
1057
+
1058
+ if not isinstance(item, pystac.Item):
1059
+ raise ValueError("item must be a string (URL) or a pystac.Item object")
1060
+
1061
+ signed_item = pc.sign(item)
1062
+
1063
+ if asset not in signed_item.assets:
1064
+ raise ValueError(
1065
+ f"Asset '{asset}' not found in item '{item.id}'. It has available assets: {list(signed_item.assets.keys())}"
1066
+ )
1067
+
1068
+ asset_url = signed_item.assets[asset].href
1069
+ ds = rxr.open_rasterio(asset_url)
1070
+
1071
+ if as_cog:
1072
+ kwargs["driver"] = "COG" # Ensure the output is a Cloud Optimized GeoTIFF
1073
+
1074
+ if output:
1075
+ print(f"Saving asset '{asset}' to {output}...")
1076
+ ds.rio.to_raster(output, **kwargs)
1077
+ print(f"Asset '{asset}' saved successfully.")
1078
+ return ds
1079
+
1080
+
1081
+ def view_pc_item(
1082
+ url=None,
1083
+ collection=None,
1084
+ item=None,
1085
+ assets=None,
1086
+ bands=None,
1087
+ titiler_endpoint=None,
1088
+ name="STAC Item",
1089
+ attribution="Planetary Computer",
1090
+ opacity=1.0,
1091
+ shown=True,
1092
+ fit_bounds=True,
1093
+ layer_index=None,
1094
+ backend="folium",
1095
+ basemap=None,
1096
+ map_args=None,
1097
+ **kwargs,
1098
+ ):
1099
+
1100
+ if backend == "folium":
1101
+ import leafmap.foliumap as leafmap
1102
+
1103
+ elif backend == "ipyleaflet":
1104
+ import leafmap.leafmap as leafmap
1105
+
1106
+ else:
1107
+ raise ValueError(
1108
+ f"Unsupported backend: {backend}. Supported backends are 'folium' and 'ipyleaflet'."
1109
+ )
1110
+
1111
+ if map_args is None:
1112
+ map_args = {}
1113
+
1114
+ if "draw_control" not in map_args:
1115
+ map_args["draw_control"] = False
1116
+
1117
+ if url is not None:
1118
+
1119
+ item = pystac.Item.from_file(url)
1120
+
1121
+ if isinstance(item, pystac.Item):
1122
+ collection = item.collection_id
1123
+ if assets is None:
1124
+ assets = [list(item.assets.keys())[0]]
1125
+ item = item.id
1126
+
1127
+ m = leafmap.Map(**map_args)
1128
+ if basemap is not None:
1129
+ m.add_basemap(basemap)
1130
+ m.add_stac_layer(
1131
+ collection=collection,
1132
+ item=item,
1133
+ assets=assets,
1134
+ bands=bands,
1135
+ titiler_endpoint=titiler_endpoint,
1136
+ name=name,
1137
+ attribution=attribution,
1138
+ opacity=opacity,
1139
+ shown=shown,
1140
+ fit_bounds=fit_bounds,
1141
+ layer_index=layer_index,
1142
+ **kwargs,
1143
+ )
1144
+ return m