geoai-py 0.9.2__tar.gz → 0.10.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.
Files changed (136) hide show
  1. geoai_py-0.10.0/.dockerignore +20 -0
  2. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/workflows/docker-image.yml +1 -1
  3. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/workflows/docker-publish.yml +1 -1
  4. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/workflows/docs-build.yml +1 -1
  5. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/workflows/docs.yml +1 -1
  6. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/workflows/macos.yml +1 -1
  7. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/workflows/pypi.yml +1 -1
  8. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/workflows/ubuntu.yml +1 -1
  9. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/workflows/windows.yml +1 -1
  10. {geoai_py-0.9.2 → geoai_py-0.10.0}/.pre-commit-config.yaml +1 -1
  11. {geoai_py-0.9.2 → geoai_py-0.10.0}/PKG-INFO +1 -1
  12. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/change_detection.ipynb +3 -0
  13. geoai_py-0.10.0/docs/examples/wetland_dynamics.ipynb +517 -0
  14. geoai_py-0.10.0/docs/workshops/TNView_2025.ipynb +2501 -0
  15. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/__init__.py +1 -1
  16. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/change_detection.py +5 -1
  17. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/train.py +1 -1
  18. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/utils.py +5 -0
  19. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai_py.egg-info/PKG-INFO +1 -1
  20. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai_py.egg-info/SOURCES.txt +3 -0
  21. {geoai_py-0.9.2 → geoai_py-0.10.0}/mkdocs.yml +2 -0
  22. {geoai_py-0.9.2 → geoai_py-0.10.0}/pyproject.toml +2 -2
  23. {geoai_py-0.9.2 → geoai_py-0.10.0}/.editorconfig +0 -0
  24. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/FUNDING.yml +0 -0
  25. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  26. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  27. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  28. {geoai_py-0.9.2 → geoai_py-0.10.0}/.github/dependabot.yml +0 -0
  29. {geoai_py-0.9.2 → geoai_py-0.10.0}/.gitignore +0 -0
  30. {geoai_py-0.9.2 → geoai_py-0.10.0}/Dockerfile +0 -0
  31. {geoai_py-0.9.2 → geoai_py-0.10.0}/LICENSE +0 -0
  32. {geoai_py-0.9.2 → geoai_py-0.10.0}/MANIFEST.in +0 -0
  33. {geoai_py-0.9.2 → geoai_py-0.10.0}/README.md +0 -0
  34. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/CNAME +0 -0
  35. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/assets/logo.ico +0 -0
  36. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/assets/logo.png +0 -0
  37. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/assets/logo_rect.png +0 -0
  38. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/change_detection.md +0 -0
  39. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/changelog.md +0 -0
  40. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/classify.md +0 -0
  41. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/contributing.md +0 -0
  42. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/detectron2.md +0 -0
  43. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/download.md +0 -0
  44. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/_template.ipynb +0 -0
  45. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/batch_segmentation.ipynb +0 -0
  46. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/building_detection_lidar.ipynb +0 -0
  47. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/building_footprints_africa.ipynb +0 -0
  48. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/building_footprints_china.ipynb +0 -0
  49. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/building_footprints_usa.ipynb +0 -0
  50. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/building_regularization.ipynb +0 -0
  51. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/car_detection.ipynb +0 -0
  52. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/create_vector.ipynb +0 -0
  53. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/data_visualization.ipynb +0 -0
  54. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/dataviz/lidar_viz.ipynb +0 -0
  55. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/dataviz/raster_viz.ipynb +0 -0
  56. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/dataviz/vector_viz.ipynb +0 -0
  57. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/download_data.ipynb +0 -0
  58. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/download_naip.ipynb +0 -0
  59. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/download_sentinel2.ipynb +0 -0
  60. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/edit_vector.ipynb +0 -0
  61. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/geometric_properties.ipynb +0 -0
  62. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/globe_projection.ipynb +0 -0
  63. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/grounded_sam.ipynb +0 -0
  64. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/image_chips.ipynb +0 -0
  65. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/image_tiling.ipynb +0 -0
  66. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/instance_segmentation.ipynb +0 -0
  67. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/jupytext.toml +0 -0
  68. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/load_model_checkpoint.ipynb +0 -0
  69. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/parking_spot_detection.ipynb +0 -0
  70. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/planetary_computer.ipynb +0 -0
  71. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/rastervision/semantic_segmentation.ipynb +0 -0
  72. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/regularization.ipynb +0 -0
  73. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/arcgis.ipynb +0 -0
  74. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/automatic_mask_generator.ipynb +0 -0
  75. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/automatic_mask_generator_hq.ipynb +0 -0
  76. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/box_prompts.ipynb +0 -0
  77. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/fast_sam.ipynb +0 -0
  78. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/input_prompts.ipynb +0 -0
  79. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/input_prompts_hq.ipynb +0 -0
  80. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/maxar_open_data.ipynb +0 -0
  81. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/satellite-predictor.ipynb +0 -0
  82. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/satellite.ipynb +0 -0
  83. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/swimming_pools.ipynb +0 -0
  84. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/text_prompts.ipynb +0 -0
  85. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo/text_prompts_batch.ipynb +0 -0
  86. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/samgeo.ipynb +0 -0
  87. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/ship_detection.ipynb +0 -0
  88. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/solar_panel_detection.ipynb +0 -0
  89. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/text_prompt_segmentation.ipynb +0 -0
  90. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/train_building_footprints_usa.ipynb +0 -0
  91. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/train_car_detection.ipynb +0 -0
  92. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/train_landcover_classification.ipynb +0 -0
  93. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/train_object_detection_model.ipynb +0 -0
  94. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/train_segmentation_model.ipynb +0 -0
  95. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/train_ship_detection.ipynb +0 -0
  96. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/train_solar_panel_detection.ipynb +0 -0
  97. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/train_water_detection.ipynb +0 -0
  98. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/view_metadata.ipynb +0 -0
  99. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/water_detection.ipynb +0 -0
  100. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/water_detection_s2.ipynb +0 -0
  101. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/water_dynamics.ipynb +0 -0
  102. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/examples/wetland_mapping.ipynb +0 -0
  103. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/extract.md +0 -0
  104. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/faq.md +0 -0
  105. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/geoai.md +0 -0
  106. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/hf.md +0 -0
  107. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/index.md +0 -0
  108. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/installation.md +0 -0
  109. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/overrides/main.html +0 -0
  110. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/sam.md +0 -0
  111. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/segment.md +0 -0
  112. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/segmentation.md +0 -0
  113. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/train.md +0 -0
  114. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/usage.md +0 -0
  115. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/utils.md +0 -0
  116. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/workshops/AWS_2025.ipynb +0 -0
  117. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/workshops/GeoAI_Workshop_2025.ipynb +0 -0
  118. {geoai_py-0.9.2 → geoai_py-0.10.0}/docs/workshops/jupytext.toml +0 -0
  119. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/classify.py +0 -0
  120. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/detectron2.py +0 -0
  121. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/download.py +0 -0
  122. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/extract.py +0 -0
  123. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/geoai.py +0 -0
  124. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/hf.py +0 -0
  125. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/sam.py +0 -0
  126. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/segment.py +0 -0
  127. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai/segmentation.py +0 -0
  128. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai_py.egg-info/dependency_links.txt +0 -0
  129. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai_py.egg-info/entry_points.txt +0 -0
  130. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai_py.egg-info/requires.txt +0 -0
  131. {geoai_py-0.9.2 → geoai_py-0.10.0}/geoai_py.egg-info/top_level.txt +0 -0
  132. {geoai_py-0.9.2 → geoai_py-0.10.0}/requirements.txt +0 -0
  133. {geoai_py-0.9.2 → geoai_py-0.10.0}/requirements_docs.txt +0 -0
  134. {geoai_py-0.9.2 → geoai_py-0.10.0}/setup.cfg +0 -0
  135. {geoai_py-0.9.2 → geoai_py-0.10.0}/tests/__init__.py +0 -0
  136. {geoai_py-0.9.2 → geoai_py-0.10.0}/tests/test_geoai.py +0 -0
@@ -0,0 +1,20 @@
1
+ # Exclude everything under docs
2
+ docs/*
3
+
4
+ # But keep these two directories
5
+ !docs/notebooks
6
+ !docs/maplibre
7
+
8
+ # Optionally exclude other common files
9
+ .git
10
+ __pycache__/
11
+ *.pyc
12
+ *.pyo
13
+ *.pyd
14
+ *.ipynb_checkpoints
15
+ .env
16
+ .DS_Store
17
+ tests/
18
+ build/
19
+ dist/
20
+ *.egg-info/
@@ -11,6 +11,6 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
 
13
13
  steps:
14
- - uses: actions/checkout@v4
14
+ - uses: actions/checkout@v5
15
15
  - name: Build the Docker image
16
16
  run: docker build . --file Dockerfile --tag ${{ github.repository }}:$(date +%s)
@@ -13,7 +13,7 @@ jobs:
13
13
  contents: read
14
14
  steps:
15
15
  - name: Check out the repo
16
- uses: actions/checkout@v4
16
+ uses: actions/checkout@v5
17
17
 
18
18
  - name: Log in to Docker Hub
19
19
  uses: docker/login-action@v3
@@ -12,7 +12,7 @@ jobs:
12
12
  python-version: ["3.12"]
13
13
 
14
14
  steps:
15
- - uses: actions/checkout@v4
15
+ - uses: actions/checkout@v5
16
16
  with:
17
17
  fetch-depth: 0
18
18
 
@@ -11,7 +11,7 @@ jobs:
11
11
  python-version: ["3.12"]
12
12
 
13
13
  steps:
14
- - uses: actions/checkout@v4
14
+ - uses: actions/checkout@v5
15
15
  with:
16
16
  fetch-depth: 0
17
17
 
@@ -19,7 +19,7 @@ jobs:
19
19
  env:
20
20
  SDKROOT: /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
21
21
  steps:
22
- - uses: actions/checkout@v4
22
+ - uses: actions/checkout@v5
23
23
 
24
24
  - name: Install uv
25
25
  uses: astral-sh/setup-uv@v6
@@ -12,7 +12,7 @@ jobs:
12
12
  runs-on: ubuntu-latest
13
13
 
14
14
  steps:
15
- - uses: actions/checkout@v4
15
+ - uses: actions/checkout@v5
16
16
  - name: Set up Python
17
17
  uses: actions/setup-python@v5
18
18
  with:
@@ -17,7 +17,7 @@ jobs:
17
17
  python-version: ["3.10", "3.11", "3.12"]
18
18
 
19
19
  steps:
20
- - uses: actions/checkout@v4
20
+ - uses: actions/checkout@v5
21
21
 
22
22
  # - name: Install GDAL system dependencies
23
23
  # run: sudo apt-get update && sudo apt-get install -y gdal-bin libgdal-dev
@@ -15,7 +15,7 @@ jobs:
15
15
  python-version: ["3.12"]
16
16
 
17
17
  steps:
18
- - uses: actions/checkout@v4
18
+ - uses: actions/checkout@v5
19
19
 
20
20
  - name: Install uv
21
21
  uses: astral-sh/setup-uv@v6
@@ -1,6 +1,6 @@
1
1
  repos:
2
2
  - repo: https://github.com/pre-commit/pre-commit-hooks
3
- rev: v5.0.0
3
+ rev: v6.0.0
4
4
  hooks:
5
5
  - id: check-toml
6
6
  - id: check-yaml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geoai-py
3
- Version: 0.9.2
3
+ Version: 0.10.0
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
@@ -165,6 +165,9 @@
165
165
  "metadata": {},
166
166
  "outputs": [],
167
167
  "source": [
168
+ "# Make sure model directory exists\n",
169
+ "Path(\"~/.cache/torch/hub/checkpoints/\").expanduser().mkdir(parents=True, exist_ok=True)\n",
170
+ "\n",
168
171
  "# Initialize change detection\n",
169
172
  "detector = geoai.ChangeDetection(sam_model_type=\"vit_h\")\n",
170
173
  "\n",
@@ -0,0 +1,517 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Wetland Mapping with GeoAI\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/wetland_dynamics.ipynb)"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "markdown",
14
+ "metadata": {},
15
+ "source": [
16
+ "## Install packages"
17
+ ]
18
+ },
19
+ {
20
+ "cell_type": "code",
21
+ "execution_count": null,
22
+ "metadata": {},
23
+ "outputs": [],
24
+ "source": [
25
+ "# %pip install geoai-py"
26
+ ]
27
+ },
28
+ {
29
+ "cell_type": "markdown",
30
+ "metadata": {},
31
+ "source": [
32
+ "## Import libraries"
33
+ ]
34
+ },
35
+ {
36
+ "cell_type": "code",
37
+ "execution_count": null,
38
+ "metadata": {},
39
+ "outputs": [],
40
+ "source": [
41
+ "import geoai\n",
42
+ "import leafmap"
43
+ ]
44
+ },
45
+ {
46
+ "cell_type": "markdown",
47
+ "metadata": {},
48
+ "source": [
49
+ "## Create an interactive map"
50
+ ]
51
+ },
52
+ {
53
+ "cell_type": "code",
54
+ "execution_count": null,
55
+ "metadata": {},
56
+ "outputs": [],
57
+ "source": [
58
+ "m = geoai.Map(center=[47.229011, -99.878662], zoom=13)\n",
59
+ "m.add_basemap(\"Esri.WorldImagery\")\n",
60
+ "m"
61
+ ]
62
+ },
63
+ {
64
+ "cell_type": "markdown",
65
+ "metadata": {},
66
+ "source": [
67
+ "## Draw an area of interest"
68
+ ]
69
+ },
70
+ {
71
+ "cell_type": "code",
72
+ "execution_count": null,
73
+ "metadata": {},
74
+ "outputs": [],
75
+ "source": [
76
+ "if m.user_roi is not None:\n",
77
+ " bbox = m.user_roi_bounds()\n",
78
+ "else:\n",
79
+ " bbox = [-99.9057, 47.2143, -99.8686, 47.2419]"
80
+ ]
81
+ },
82
+ {
83
+ "cell_type": "markdown",
84
+ "metadata": {},
85
+ "source": [
86
+ "## Get the year of NWI data"
87
+ ]
88
+ },
89
+ {
90
+ "cell_type": "code",
91
+ "execution_count": null,
92
+ "metadata": {},
93
+ "outputs": [],
94
+ "source": [
95
+ "nwi_year = leafmap.get_nwi_year(bbox=bbox, return_geometry=False)[0]\n",
96
+ "nwi_year"
97
+ ]
98
+ },
99
+ {
100
+ "cell_type": "code",
101
+ "execution_count": null,
102
+ "metadata": {},
103
+ "outputs": [],
104
+ "source": [
105
+ "nwi_year_geom = leafmap.get_nwi_year(bbox=bbox)\n",
106
+ "nwi_year_geom"
107
+ ]
108
+ },
109
+ {
110
+ "cell_type": "code",
111
+ "execution_count": null,
112
+ "metadata": {},
113
+ "outputs": [],
114
+ "source": [
115
+ "m.add_gdf(nwi_year_geom, layer_name=\"NWI Year\")"
116
+ ]
117
+ },
118
+ {
119
+ "cell_type": "markdown",
120
+ "metadata": {},
121
+ "source": [
122
+ "## Search for NAIP images for the corresponding NWI year"
123
+ ]
124
+ },
125
+ {
126
+ "cell_type": "code",
127
+ "execution_count": null,
128
+ "metadata": {},
129
+ "outputs": [],
130
+ "source": [
131
+ "items = geoai.pc_stac_search(\n",
132
+ " collection=\"naip\",\n",
133
+ " bbox=bbox,\n",
134
+ " time_range=f\"{nwi_year}-01-01/{nwi_year}-12-30\",\n",
135
+ ")\n",
136
+ "items"
137
+ ]
138
+ },
139
+ {
140
+ "cell_type": "markdown",
141
+ "metadata": {},
142
+ "source": [
143
+ "## Visualize NAIP images"
144
+ ]
145
+ },
146
+ {
147
+ "cell_type": "code",
148
+ "execution_count": null,
149
+ "metadata": {},
150
+ "outputs": [],
151
+ "source": [
152
+ "geoai.view_pc_items(items=items)"
153
+ ]
154
+ },
155
+ {
156
+ "cell_type": "markdown",
157
+ "metadata": {},
158
+ "source": [
159
+ "## Download NAIP images"
160
+ ]
161
+ },
162
+ {
163
+ "cell_type": "code",
164
+ "execution_count": null,
165
+ "metadata": {},
166
+ "outputs": [],
167
+ "source": [
168
+ "images = geoai.pc_stac_download(items, output_dir=\"naip\", assets=[\"image\"])\n",
169
+ "images"
170
+ ]
171
+ },
172
+ {
173
+ "cell_type": "code",
174
+ "execution_count": null,
175
+ "metadata": {},
176
+ "outputs": [],
177
+ "source": [
178
+ "first_image = list(images.values())[0][\"image\"]\n",
179
+ "first_image"
180
+ ]
181
+ },
182
+ {
183
+ "cell_type": "code",
184
+ "execution_count": null,
185
+ "metadata": {},
186
+ "outputs": [],
187
+ "source": [
188
+ "second_image = list(images.values())[1][\"image\"]\n",
189
+ "second_image"
190
+ ]
191
+ },
192
+ {
193
+ "cell_type": "markdown",
194
+ "metadata": {},
195
+ "source": [
196
+ "## Download NWI data"
197
+ ]
198
+ },
199
+ {
200
+ "cell_type": "code",
201
+ "execution_count": null,
202
+ "metadata": {},
203
+ "outputs": [],
204
+ "source": [
205
+ "image_bbox = leafmap.image_bbox(first_image, to_crs=\"EPSG:4326\")\n",
206
+ "image_bbox"
207
+ ]
208
+ },
209
+ {
210
+ "cell_type": "code",
211
+ "execution_count": null,
212
+ "metadata": {},
213
+ "outputs": [],
214
+ "source": [
215
+ "nwi_gdf = leafmap.get_nwi(\n",
216
+ " geometry=image_bbox, clip=True, add_class=True, output=\"wetlands.geojson\"\n",
217
+ ")\n",
218
+ "nwi_gdf"
219
+ ]
220
+ },
221
+ {
222
+ "cell_type": "code",
223
+ "execution_count": null,
224
+ "metadata": {},
225
+ "outputs": [],
226
+ "source": [
227
+ "wetlands_classes = nwi_gdf[\"WETLAND_TY\"].unique()\n",
228
+ "wetlands_classes"
229
+ ]
230
+ },
231
+ {
232
+ "cell_type": "code",
233
+ "execution_count": null,
234
+ "metadata": {},
235
+ "outputs": [],
236
+ "source": [
237
+ "num_classes = len(wetlands_classes) + 1\n",
238
+ "num_classes"
239
+ ]
240
+ },
241
+ {
242
+ "cell_type": "markdown",
243
+ "metadata": {},
244
+ "source": [
245
+ "## Visualize NWI data"
246
+ ]
247
+ },
248
+ {
249
+ "cell_type": "code",
250
+ "execution_count": null,
251
+ "metadata": {},
252
+ "outputs": [],
253
+ "source": [
254
+ "m.remove_layer(m.layers[-1])\n",
255
+ "m.add_raster(first_image, layer_name=\"NAIP\")\n",
256
+ "m.add_nwi(nwi_gdf, layer_name=\"NWI\")\n",
257
+ "m"
258
+ ]
259
+ },
260
+ {
261
+ "cell_type": "markdown",
262
+ "metadata": {},
263
+ "source": [
264
+ "## Select training and test images"
265
+ ]
266
+ },
267
+ {
268
+ "cell_type": "code",
269
+ "execution_count": null,
270
+ "metadata": {},
271
+ "outputs": [],
272
+ "source": [
273
+ "train_raster_path = first_image\n",
274
+ "test_raster_path = second_image\n",
275
+ "train_vector_path = \"wetlands.geojson\""
276
+ ]
277
+ },
278
+ {
279
+ "cell_type": "code",
280
+ "execution_count": null,
281
+ "metadata": {},
282
+ "outputs": [],
283
+ "source": [
284
+ "geoai.view_vector_interactive(\n",
285
+ " train_vector_path, column=\"WETLAND_TY\", tiles=train_raster_path\n",
286
+ ")"
287
+ ]
288
+ },
289
+ {
290
+ "cell_type": "markdown",
291
+ "metadata": {},
292
+ "source": [
293
+ "## Create image chips for training"
294
+ ]
295
+ },
296
+ {
297
+ "cell_type": "code",
298
+ "execution_count": null,
299
+ "metadata": {},
300
+ "outputs": [],
301
+ "source": [
302
+ "out_folder = \"output\""
303
+ ]
304
+ },
305
+ {
306
+ "cell_type": "code",
307
+ "execution_count": null,
308
+ "metadata": {},
309
+ "outputs": [],
310
+ "source": [
311
+ "tiles = geoai.export_geotiff_tiles(\n",
312
+ " in_raster=train_raster_path,\n",
313
+ " out_folder=out_folder,\n",
314
+ " in_class_data=train_vector_path,\n",
315
+ " tile_size=1024,\n",
316
+ " stride=256,\n",
317
+ " buffer_radius=0,\n",
318
+ ")"
319
+ ]
320
+ },
321
+ {
322
+ "cell_type": "markdown",
323
+ "metadata": {},
324
+ "source": [
325
+ "## Train a segmentation model"
326
+ ]
327
+ },
328
+ {
329
+ "cell_type": "code",
330
+ "execution_count": null,
331
+ "metadata": {},
332
+ "outputs": [],
333
+ "source": [
334
+ "# Train U-Net model\n",
335
+ "geoai.train_segmentation_model(\n",
336
+ " images_dir=f\"{out_folder}/images\",\n",
337
+ " labels_dir=f\"{out_folder}/labels\",\n",
338
+ " output_dir=f\"{out_folder}/unet_models\",\n",
339
+ " architecture=\"unet\",\n",
340
+ " encoder_name=\"resnet34\",\n",
341
+ " encoder_weights=\"imagenet\",\n",
342
+ " num_channels=4,\n",
343
+ " num_classes=num_classes, # background and wetlands classes\n",
344
+ " batch_size=8,\n",
345
+ " num_epochs=50,\n",
346
+ " learning_rate=0.001,\n",
347
+ " val_split=0.2,\n",
348
+ " verbose=True,\n",
349
+ ")"
350
+ ]
351
+ },
352
+ {
353
+ "cell_type": "markdown",
354
+ "metadata": {},
355
+ "source": [
356
+ "## Evaluate the model"
357
+ ]
358
+ },
359
+ {
360
+ "cell_type": "code",
361
+ "execution_count": null,
362
+ "metadata": {},
363
+ "outputs": [],
364
+ "source": [
365
+ "geoai.plot_performance_metrics(\n",
366
+ " history_path=f\"{out_folder}/unet_models/training_history.pth\",\n",
367
+ " figsize=(15, 5),\n",
368
+ " verbose=True,\n",
369
+ ")"
370
+ ]
371
+ },
372
+ {
373
+ "cell_type": "markdown",
374
+ "metadata": {},
375
+ "source": [
376
+ "## Run inference on a single image"
377
+ ]
378
+ },
379
+ {
380
+ "cell_type": "code",
381
+ "execution_count": null,
382
+ "metadata": {},
383
+ "outputs": [],
384
+ "source": [
385
+ "# Define paths\n",
386
+ "masks_path = second_image.replace(\"naip\", \"prediction\")\n",
387
+ "model_path = f\"{out_folder}/unet_models/best_model.pth\""
388
+ ]
389
+ },
390
+ {
391
+ "cell_type": "code",
392
+ "execution_count": null,
393
+ "metadata": {},
394
+ "outputs": [],
395
+ "source": [
396
+ "geoai.semantic_segmentation(\n",
397
+ " input_path=test_raster_path,\n",
398
+ " output_path=masks_path,\n",
399
+ " model_path=model_path,\n",
400
+ " architecture=\"unet\",\n",
401
+ " encoder_name=\"resnet34\",\n",
402
+ " num_channels=4,\n",
403
+ " num_classes=6,\n",
404
+ " window_size=1024,\n",
405
+ " overlap=256,\n",
406
+ " batch_size=4,\n",
407
+ ")"
408
+ ]
409
+ },
410
+ {
411
+ "cell_type": "markdown",
412
+ "metadata": {},
413
+ "source": [
414
+ "## Vectorize the results"
415
+ ]
416
+ },
417
+ {
418
+ "cell_type": "code",
419
+ "execution_count": null,
420
+ "metadata": {},
421
+ "outputs": [],
422
+ "source": [
423
+ "output_path = masks_path.replace(\".tif\", \"_mask.geojson\")\n",
424
+ "gdf = geoai.raster_to_vector(\n",
425
+ " masks_path, output_path, min_area=300, simplify_tolerance=1\n",
426
+ ")"
427
+ ]
428
+ },
429
+ {
430
+ "cell_type": "code",
431
+ "execution_count": null,
432
+ "metadata": {},
433
+ "outputs": [],
434
+ "source": [
435
+ "geoai.view_vector_interactive(output_path, tiles=test_raster_path)"
436
+ ]
437
+ },
438
+ {
439
+ "cell_type": "markdown",
440
+ "metadata": {},
441
+ "source": [
442
+ "## Download more images"
443
+ ]
444
+ },
445
+ {
446
+ "cell_type": "code",
447
+ "execution_count": null,
448
+ "metadata": {},
449
+ "outputs": [],
450
+ "source": [
451
+ "items = geoai.pc_stac_search(\n",
452
+ " collection=\"naip\",\n",
453
+ " bbox=bbox,\n",
454
+ ")\n",
455
+ "items"
456
+ ]
457
+ },
458
+ {
459
+ "cell_type": "code",
460
+ "execution_count": null,
461
+ "metadata": {},
462
+ "outputs": [],
463
+ "source": [
464
+ "images = geoai.pc_stac_download(items, output_dir=\"naip\", assets=[\"image\"])\n",
465
+ "images"
466
+ ]
467
+ },
468
+ {
469
+ "cell_type": "markdown",
470
+ "metadata": {},
471
+ "source": [
472
+ "## Run inference on multiple images"
473
+ ]
474
+ },
475
+ {
476
+ "cell_type": "code",
477
+ "execution_count": null,
478
+ "metadata": {},
479
+ "outputs": [],
480
+ "source": [
481
+ "geoai.semantic_segmentation_batch(\n",
482
+ " input_dir=\"naip\",\n",
483
+ " output_dir=\"prediction\",\n",
484
+ " model_path=model_path,\n",
485
+ " architecture=\"unet\",\n",
486
+ " encoder_name=\"resnet34\",\n",
487
+ " num_channels=4,\n",
488
+ " num_classes=6,\n",
489
+ " window_size=1024,\n",
490
+ " overlap=256,\n",
491
+ " batch_size=4,\n",
492
+ ")"
493
+ ]
494
+ }
495
+ ],
496
+ "metadata": {
497
+ "kernelspec": {
498
+ "display_name": "geo",
499
+ "language": "python",
500
+ "name": "python3"
501
+ },
502
+ "language_info": {
503
+ "codemirror_mode": {
504
+ "name": "ipython",
505
+ "version": 3
506
+ },
507
+ "file_extension": ".py",
508
+ "mimetype": "text/x-python",
509
+ "name": "python",
510
+ "nbconvert_exporter": "python",
511
+ "pygments_lexer": "ipython3",
512
+ "version": "3.12.2"
513
+ }
514
+ },
515
+ "nbformat": 4,
516
+ "nbformat_minor": 2
517
+ }