geoai-py 0.3.6__tar.gz → 0.4.1__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.
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.github/workflows/windows.yml +7 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.gitignore +1 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/PKG-INFO +3 -8
- geoai_py-0.4.1/docs/examples/parking_spot_detection.ipynb +203 -0
- geoai_py-0.4.1/docs/examples/train_object_detection_model.ipynb +259 -0
- geoai_py-0.4.1/docs/hf.md +3 -0
- geoai_py-0.4.1/docs/train.md +3 -0
- geoai_py-0.4.1/geoai/__init__.py +97 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai/download.py +9 -8
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai/extract.py +65 -24
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai/geoai.py +3 -1
- geoai_py-0.4.1/geoai/hf.py +447 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai/segment.py +4 -3
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai/segmentation.py +8 -7
- geoai_py-0.4.1/geoai/train.py +1039 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai/utils.py +32 -28
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai_py.egg-info/PKG-INFO +3 -8
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai_py.egg-info/SOURCES.txt +6 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai_py.egg-info/requires.txt +1 -7
- {geoai_py-0.3.6 → geoai_py-0.4.1}/mkdocs.yml +5 -1
- {geoai_py-0.3.6 → geoai_py-0.4.1}/pyproject.toml +3 -6
- {geoai_py-0.3.6 → geoai_py-0.4.1}/requirements_docs.txt +1 -0
- geoai_py-0.3.6/geoai/__init__.py +0 -35
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.editorconfig +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.github/FUNDING.yml +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.github/dependabot.yml +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.github/workflows/docs-build.yml +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.github/workflows/docs.yml +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.github/workflows/macos.yml +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.github/workflows/pypi.yml +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.github/workflows/ubuntu.yml +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/.pre-commit-config.yaml +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/LICENSE +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/MANIFEST.in +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/README.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/CNAME +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/changelog.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/contributing.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/download.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/_template.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/building_footprints_africa.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/building_footprints_china.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/building_footprints_usa.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/building_regularization.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/car_detection.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/data_visualization.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/dataviz/lidar_viz.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/dataviz/raster_viz.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/dataviz/vector_viz.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/download_data.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/geometric_properties.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/image_chips.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/jupytext.toml +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/rastervision/semantic_segmentation.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/arcgis.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/automatic_mask_generator.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/automatic_mask_generator_hq.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/box_prompts.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/fast_sam.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/input_prompts.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/input_prompts_hq.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/maxar_open_data.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/satellite-predictor.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/satellite.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/swimming_pools.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/text_prompts.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/samgeo/text_prompts_batch.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/ship_detection.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/solar_panel_detection.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/text_prompt_segmentation.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/examples/view_metadata.ipynb +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/extract.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/faq.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/geoai.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/index.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/installation.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/overrides/main.html +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/segment.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/segmentation.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/usage.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/docs/utils.md +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai_py.egg-info/dependency_links.txt +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai_py.egg-info/entry_points.txt +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/geoai_py.egg-info/top_level.txt +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/requirements.txt +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/setup.cfg +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/tests/__init__.py +0 -0
- {geoai_py-0.3.6 → geoai_py-0.4.1}/tests/test_geoai.py +0 -0
|
@@ -28,6 +28,13 @@ jobs:
|
|
|
28
28
|
uv venv --python ${{ matrix.python-version }}
|
|
29
29
|
uv pip install .
|
|
30
30
|
|
|
31
|
+
# - name: Update PROJ data files
|
|
32
|
+
# run: |
|
|
33
|
+
# pip install --upgrade pyproj
|
|
34
|
+
# curl -L -o proj-data.zip https://download.osgeo.org/proj/proj-data-1.9.zip
|
|
35
|
+
# unzip proj-data.zip -d proj-data
|
|
36
|
+
# cp -r proj-data/* $(python -m pyproj -v | grep "PROJ_LIB" | cut -d ' ' -f 2)
|
|
37
|
+
|
|
31
38
|
- name: Test import
|
|
32
39
|
run: |
|
|
33
40
|
uv run python -c "import geoai; print('geoai import successful')"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: geoai-py
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
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
|
|
@@ -36,13 +36,8 @@ Requires-Dist: torch
|
|
|
36
36
|
Requires-Dist: torchgeo
|
|
37
37
|
Requires-Dist: tqdm
|
|
38
38
|
Requires-Dist: transformers
|
|
39
|
-
Provides-Extra:
|
|
40
|
-
Requires-Dist:
|
|
41
|
-
Requires-Dist: planetary_computer; extra == "download"
|
|
42
|
-
Requires-Dist: tqdm; extra == "download"
|
|
43
|
-
Requires-Dist: overturemaps; extra == "download"
|
|
44
|
-
Provides-Extra: all
|
|
45
|
-
Requires-Dist: geoai[download]; extra == "all"
|
|
39
|
+
Provides-Extra: extra
|
|
40
|
+
Requires-Dist: overturemaps; extra == "extra"
|
|
46
41
|
|
|
47
42
|
# GeoAI: Artificial Intelligence for Geospatial Data
|
|
48
43
|
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"metadata": {},
|
|
6
|
+
"source": [
|
|
7
|
+
"# Parking Spot Detection\n",
|
|
8
|
+
"\n",
|
|
9
|
+
"[](https://colab.research.google.com/github/opengeos/geoai/blob/main/docs/examples/parking_spot_detection.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
|
+
"## Download sample data\n",
|
|
45
|
+
"\n",
|
|
46
|
+
"We will download a sample image from Hugging Face Hub to use for parking spot detection. You can find more high-resolution images from [OpenAerialMap](https://openaerialmap.org)."
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"cell_type": "code",
|
|
51
|
+
"execution_count": null,
|
|
52
|
+
"metadata": {},
|
|
53
|
+
"outputs": [],
|
|
54
|
+
"source": [
|
|
55
|
+
"raster_url = (\n",
|
|
56
|
+
" \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/parking_spots.tif\"\n",
|
|
57
|
+
")"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"cell_type": "code",
|
|
62
|
+
"execution_count": null,
|
|
63
|
+
"metadata": {},
|
|
64
|
+
"outputs": [],
|
|
65
|
+
"source": [
|
|
66
|
+
"raster_path = geoai.download_file(raster_url)"
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"cell_type": "markdown",
|
|
71
|
+
"metadata": {},
|
|
72
|
+
"source": [
|
|
73
|
+
"## Visualize the image"
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"cell_type": "code",
|
|
78
|
+
"execution_count": null,
|
|
79
|
+
"metadata": {},
|
|
80
|
+
"outputs": [],
|
|
81
|
+
"source": [
|
|
82
|
+
"geoai.view_raster(raster_url)"
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"cell_type": "markdown",
|
|
87
|
+
"metadata": {},
|
|
88
|
+
"source": [
|
|
89
|
+
"## Initialize the model"
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"cell_type": "code",
|
|
94
|
+
"execution_count": null,
|
|
95
|
+
"metadata": {},
|
|
96
|
+
"outputs": [],
|
|
97
|
+
"source": [
|
|
98
|
+
"detector = geoai.ParkingSplotDetector()"
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"cell_type": "markdown",
|
|
103
|
+
"metadata": {},
|
|
104
|
+
"source": [
|
|
105
|
+
"## Extract parking spots\n",
|
|
106
|
+
"\n",
|
|
107
|
+
"Extract parking spots from the image using the model and save the output image."
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"cell_type": "code",
|
|
112
|
+
"execution_count": null,
|
|
113
|
+
"metadata": {},
|
|
114
|
+
"outputs": [],
|
|
115
|
+
"source": [
|
|
116
|
+
"mask_path = detector.generate_masks(\n",
|
|
117
|
+
" raster_path=raster_path,\n",
|
|
118
|
+
" output_path=\"parking_masks.tif\",\n",
|
|
119
|
+
" confidence_threshold=0.5,\n",
|
|
120
|
+
" mask_threshold=0.5,\n",
|
|
121
|
+
" overlap=0.25,\n",
|
|
122
|
+
" chip_size=(256, 256),\n",
|
|
123
|
+
" min_object_area=10,\n",
|
|
124
|
+
" # max_object_area=5000,\n",
|
|
125
|
+
")"
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"cell_type": "markdown",
|
|
130
|
+
"metadata": {},
|
|
131
|
+
"source": [
|
|
132
|
+
"Convert the image masks to polygons and save the output GeoJSON file."
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"cell_type": "code",
|
|
137
|
+
"execution_count": null,
|
|
138
|
+
"metadata": {},
|
|
139
|
+
"outputs": [],
|
|
140
|
+
"source": [
|
|
141
|
+
"gdf = detector.vectorize_masks(\n",
|
|
142
|
+
" masks_path=\"parking_masks.tif\",\n",
|
|
143
|
+
" output_path=\"parking.geojson\",\n",
|
|
144
|
+
" min_object_area=300,\n",
|
|
145
|
+
" # max_object_area=5000,\n",
|
|
146
|
+
")"
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"cell_type": "markdown",
|
|
151
|
+
"metadata": {},
|
|
152
|
+
"source": [
|
|
153
|
+
"## Add geometric properties"
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"cell_type": "code",
|
|
158
|
+
"execution_count": null,
|
|
159
|
+
"metadata": {},
|
|
160
|
+
"outputs": [],
|
|
161
|
+
"source": [
|
|
162
|
+
"gdf = geoai.add_geometric_properties(gdf)"
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"cell_type": "markdown",
|
|
167
|
+
"metadata": {},
|
|
168
|
+
"source": [
|
|
169
|
+
"## Visualize results"
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"cell_type": "code",
|
|
174
|
+
"execution_count": null,
|
|
175
|
+
"metadata": {},
|
|
176
|
+
"outputs": [],
|
|
177
|
+
"source": [
|
|
178
|
+
"geoai.view_vector_interactive(gdf, column=\"confidence\", tiles=raster_url)"
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
],
|
|
182
|
+
"metadata": {
|
|
183
|
+
"kernelspec": {
|
|
184
|
+
"display_name": "geo",
|
|
185
|
+
"language": "python",
|
|
186
|
+
"name": "python3"
|
|
187
|
+
},
|
|
188
|
+
"language_info": {
|
|
189
|
+
"codemirror_mode": {
|
|
190
|
+
"name": "ipython",
|
|
191
|
+
"version": 3
|
|
192
|
+
},
|
|
193
|
+
"file_extension": ".py",
|
|
194
|
+
"mimetype": "text/x-python",
|
|
195
|
+
"name": "python",
|
|
196
|
+
"nbconvert_exporter": "python",
|
|
197
|
+
"pygments_lexer": "ipython3",
|
|
198
|
+
"version": "3.12.9"
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
"nbformat": 4,
|
|
202
|
+
"nbformat_minor": 2
|
|
203
|
+
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"metadata": {},
|
|
6
|
+
"source": [
|
|
7
|
+
"# Train an Object Detection Model with GeoAI\n",
|
|
8
|
+
"\n",
|
|
9
|
+
"[](https://colab.research.google.com/github/opengeos/geoai/blob/main/docs/examples/train_object_detection_model.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
|
+
"## Download sample data"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"cell_type": "code",
|
|
49
|
+
"execution_count": null,
|
|
50
|
+
"metadata": {},
|
|
51
|
+
"outputs": [],
|
|
52
|
+
"source": [
|
|
53
|
+
"train_raster_url = (\n",
|
|
54
|
+
" \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/naip_train.tif\"\n",
|
|
55
|
+
")\n",
|
|
56
|
+
"train_vector_url = \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/naip_train_buildings.geojson\"\n",
|
|
57
|
+
"test_raster_url = (\n",
|
|
58
|
+
" \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/naip_test.tif\"\n",
|
|
59
|
+
")"
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"cell_type": "code",
|
|
64
|
+
"execution_count": null,
|
|
65
|
+
"metadata": {},
|
|
66
|
+
"outputs": [],
|
|
67
|
+
"source": [
|
|
68
|
+
"train_raster_path = geoai.download_file(train_raster_url)\n",
|
|
69
|
+
"train_vector_path = geoai.download_file(train_vector_url)\n",
|
|
70
|
+
"test_raster_path = geoai.download_file(test_raster_url)"
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"cell_type": "markdown",
|
|
75
|
+
"metadata": {},
|
|
76
|
+
"source": [
|
|
77
|
+
"## Visualize sample data"
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"cell_type": "code",
|
|
82
|
+
"execution_count": null,
|
|
83
|
+
"metadata": {},
|
|
84
|
+
"outputs": [],
|
|
85
|
+
"source": [
|
|
86
|
+
"geoai.view_vector_interactive(train_vector_path, tiles=train_raster_url)"
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"cell_type": "code",
|
|
91
|
+
"execution_count": null,
|
|
92
|
+
"metadata": {},
|
|
93
|
+
"outputs": [],
|
|
94
|
+
"source": [
|
|
95
|
+
"geoai.view_raster(test_raster_url)"
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"cell_type": "markdown",
|
|
100
|
+
"metadata": {},
|
|
101
|
+
"source": [
|
|
102
|
+
"## Create training data"
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"cell_type": "code",
|
|
107
|
+
"execution_count": null,
|
|
108
|
+
"metadata": {},
|
|
109
|
+
"outputs": [],
|
|
110
|
+
"source": [
|
|
111
|
+
"out_folder = \"output\"\n",
|
|
112
|
+
"tiles = geoai.export_geotiff_tiles(\n",
|
|
113
|
+
" in_raster=train_raster_path,\n",
|
|
114
|
+
" out_folder=out_folder,\n",
|
|
115
|
+
" in_class_data=train_vector_path,\n",
|
|
116
|
+
" tile_size=512,\n",
|
|
117
|
+
" stride=256,\n",
|
|
118
|
+
" buffer_radius=0,\n",
|
|
119
|
+
")"
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"cell_type": "markdown",
|
|
124
|
+
"metadata": {},
|
|
125
|
+
"source": [
|
|
126
|
+
"## Train object detection model"
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"cell_type": "code",
|
|
131
|
+
"execution_count": null,
|
|
132
|
+
"metadata": {},
|
|
133
|
+
"outputs": [],
|
|
134
|
+
"source": [
|
|
135
|
+
"geoai.train_MaskRCNN_model(\n",
|
|
136
|
+
" images_dir=f\"{out_folder}/images\",\n",
|
|
137
|
+
" labels_dir=f\"{out_folder}/labels\",\n",
|
|
138
|
+
" output_dir=f\"{out_folder}/models\",\n",
|
|
139
|
+
" num_channels=4,\n",
|
|
140
|
+
" pretrained=True,\n",
|
|
141
|
+
" batch_size=4,\n",
|
|
142
|
+
" num_epochs=10,\n",
|
|
143
|
+
" learning_rate=0.005,\n",
|
|
144
|
+
" val_split=0.2,\n",
|
|
145
|
+
")"
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"cell_type": "markdown",
|
|
150
|
+
"metadata": {},
|
|
151
|
+
"source": [
|
|
152
|
+
"## Run inference"
|
|
153
|
+
]
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"cell_type": "code",
|
|
157
|
+
"execution_count": null,
|
|
158
|
+
"metadata": {},
|
|
159
|
+
"outputs": [],
|
|
160
|
+
"source": [
|
|
161
|
+
"masks_path = \"naip_test_prediction.tif\"\n",
|
|
162
|
+
"model_path = f\"{out_folder}/models/best_model.pth\""
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"cell_type": "code",
|
|
167
|
+
"execution_count": null,
|
|
168
|
+
"metadata": {},
|
|
169
|
+
"outputs": [],
|
|
170
|
+
"source": [
|
|
171
|
+
"geoai.object_detection(\n",
|
|
172
|
+
" test_raster_path,\n",
|
|
173
|
+
" masks_path,\n",
|
|
174
|
+
" model_path,\n",
|
|
175
|
+
" window_size=512,\n",
|
|
176
|
+
" overlap=256,\n",
|
|
177
|
+
" confidence_threshold=0.5,\n",
|
|
178
|
+
" batch_size=4,\n",
|
|
179
|
+
" num_channels=4,\n",
|
|
180
|
+
")"
|
|
181
|
+
]
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"cell_type": "markdown",
|
|
185
|
+
"metadata": {},
|
|
186
|
+
"source": [
|
|
187
|
+
"## Vectorize masks"
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"cell_type": "code",
|
|
192
|
+
"execution_count": null,
|
|
193
|
+
"metadata": {},
|
|
194
|
+
"outputs": [],
|
|
195
|
+
"source": [
|
|
196
|
+
"output_path = \"naip_test_prediction.geojson\"\n",
|
|
197
|
+
"gdf = geoai.orthogonalize(masks_path, output_path, epsilon=2)"
|
|
198
|
+
]
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"cell_type": "markdown",
|
|
202
|
+
"metadata": {},
|
|
203
|
+
"source": [
|
|
204
|
+
"## Visualize results"
|
|
205
|
+
]
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"cell_type": "code",
|
|
209
|
+
"execution_count": null,
|
|
210
|
+
"metadata": {},
|
|
211
|
+
"outputs": [],
|
|
212
|
+
"source": [
|
|
213
|
+
"geoai.view_vector_interactive(output_path, tiles=test_raster_url)"
|
|
214
|
+
]
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"cell_type": "code",
|
|
218
|
+
"execution_count": null,
|
|
219
|
+
"metadata": {},
|
|
220
|
+
"outputs": [],
|
|
221
|
+
"source": [
|
|
222
|
+
"geoai.create_split_map(\n",
|
|
223
|
+
" left_layer=output_path,\n",
|
|
224
|
+
" right_layer=test_raster_url,\n",
|
|
225
|
+
" left_args={\"style\": {\"color\": \"red\", \"fillOpacity\": 0.2}},\n",
|
|
226
|
+
" basemap=test_raster_url,\n",
|
|
227
|
+
")"
|
|
228
|
+
]
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"cell_type": "markdown",
|
|
232
|
+
"metadata": {},
|
|
233
|
+
"source": [
|
|
234
|
+
""
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
],
|
|
238
|
+
"metadata": {
|
|
239
|
+
"kernelspec": {
|
|
240
|
+
"display_name": "geo",
|
|
241
|
+
"language": "python",
|
|
242
|
+
"name": "python3"
|
|
243
|
+
},
|
|
244
|
+
"language_info": {
|
|
245
|
+
"codemirror_mode": {
|
|
246
|
+
"name": "ipython",
|
|
247
|
+
"version": 3
|
|
248
|
+
},
|
|
249
|
+
"file_extension": ".py",
|
|
250
|
+
"mimetype": "text/x-python",
|
|
251
|
+
"name": "python",
|
|
252
|
+
"nbconvert_exporter": "python",
|
|
253
|
+
"pygments_lexer": "ipython3",
|
|
254
|
+
"version": "3.12.9"
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
"nbformat": 4,
|
|
258
|
+
"nbformat_minor": 2
|
|
259
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Top-level package for geoai."""
|
|
2
|
+
|
|
3
|
+
__author__ = """Qiusheng Wu"""
|
|
4
|
+
__email__ = "giswqs@gmail.com"
|
|
5
|
+
__version__ = "0.4.1"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def set_proj_lib_path(verbose=False):
|
|
13
|
+
"""
|
|
14
|
+
Set the PROJ_LIB and GDAL_DATA environment variables based on the current conda environment.
|
|
15
|
+
|
|
16
|
+
This function attempts to locate and set the correct paths for PROJ_LIB and GDAL_DATA
|
|
17
|
+
by checking multiple possible locations within the conda environment structure.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
verbose (bool): If True, print additional information during the process.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
bool: True if both paths were set successfully, False otherwise.
|
|
24
|
+
"""
|
|
25
|
+
try:
|
|
26
|
+
# Get conda environment path
|
|
27
|
+
conda_env_path = os.environ.get("CONDA_PREFIX") or sys.prefix
|
|
28
|
+
|
|
29
|
+
# Define possible paths for PROJ_LIB
|
|
30
|
+
possible_proj_paths = [
|
|
31
|
+
os.path.join(conda_env_path, "share", "proj"),
|
|
32
|
+
os.path.join(conda_env_path, "Library", "share", "proj"),
|
|
33
|
+
os.path.join(conda_env_path, "Library", "share"),
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
# Define possible paths for GDAL_DATA
|
|
37
|
+
possible_gdal_paths = [
|
|
38
|
+
os.path.join(conda_env_path, "share", "gdal"),
|
|
39
|
+
os.path.join(conda_env_path, "Library", "share", "gdal"),
|
|
40
|
+
os.path.join(conda_env_path, "Library", "data", "gdal"),
|
|
41
|
+
os.path.join(conda_env_path, "Library", "share"),
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
# Set PROJ_LIB environment variable
|
|
45
|
+
proj_set = False
|
|
46
|
+
for proj_path in possible_proj_paths:
|
|
47
|
+
if os.path.exists(proj_path) and os.path.isdir(proj_path):
|
|
48
|
+
# Verify it contains projection data
|
|
49
|
+
if os.path.exists(os.path.join(proj_path, "proj.db")):
|
|
50
|
+
os.environ["PROJ_LIB"] = proj_path
|
|
51
|
+
if verbose:
|
|
52
|
+
print(f"PROJ_LIB set to: {proj_path}")
|
|
53
|
+
proj_set = True
|
|
54
|
+
break
|
|
55
|
+
|
|
56
|
+
# Set GDAL_DATA environment variable
|
|
57
|
+
gdal_set = False
|
|
58
|
+
for gdal_path in possible_gdal_paths:
|
|
59
|
+
if os.path.exists(gdal_path) and os.path.isdir(gdal_path):
|
|
60
|
+
# Verify it contains the header.dxf file or other critical GDAL files
|
|
61
|
+
if os.path.exists(
|
|
62
|
+
os.path.join(gdal_path, "header.dxf")
|
|
63
|
+
) or os.path.exists(os.path.join(gdal_path, "gcs.csv")):
|
|
64
|
+
os.environ["GDAL_DATA"] = gdal_path
|
|
65
|
+
if verbose:
|
|
66
|
+
print(f"GDAL_DATA set to: {gdal_path}")
|
|
67
|
+
gdal_set = True
|
|
68
|
+
break
|
|
69
|
+
|
|
70
|
+
# If paths still not found, try a last-resort approach
|
|
71
|
+
if not proj_set or not gdal_set:
|
|
72
|
+
# Try a deep search in the conda environment
|
|
73
|
+
for root, dirs, files in os.walk(conda_env_path):
|
|
74
|
+
if not gdal_set and "header.dxf" in files:
|
|
75
|
+
os.environ["GDAL_DATA"] = root
|
|
76
|
+
if verbose:
|
|
77
|
+
print(f"GDAL_DATA set to: {root} (deep search)")
|
|
78
|
+
gdal_set = True
|
|
79
|
+
|
|
80
|
+
if not proj_set and "proj.db" in files:
|
|
81
|
+
os.environ["PROJ_LIB"] = root
|
|
82
|
+
if verbose:
|
|
83
|
+
print(f"PROJ_LIB set to: {root} (deep search)")
|
|
84
|
+
proj_set = True
|
|
85
|
+
|
|
86
|
+
if proj_set and gdal_set:
|
|
87
|
+
break
|
|
88
|
+
|
|
89
|
+
except Exception as e:
|
|
90
|
+
print(f"Error setting projection library paths: {e}")
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# if ("google.colab" not in sys.modules) and (sys.platform != "windows"):
|
|
95
|
+
# set_proj_lib_path()
|
|
96
|
+
|
|
97
|
+
from .geoai import *
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
"""This module provides functions to download data, including NAIP imagery and building data from Overture Maps."""
|
|
2
2
|
|
|
3
|
+
import logging
|
|
3
4
|
import os
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
|
|
5
|
+
import subprocess
|
|
6
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
7
|
+
|
|
8
|
+
import geopandas as gpd
|
|
7
9
|
import matplotlib.pyplot as plt
|
|
8
|
-
|
|
10
|
+
import numpy as np
|
|
9
11
|
import planetary_computer as pc
|
|
10
|
-
import
|
|
12
|
+
import requests
|
|
13
|
+
import rioxarray
|
|
14
|
+
from pystac_client import Client
|
|
11
15
|
from shapely.geometry import box
|
|
12
16
|
from tqdm import tqdm
|
|
13
|
-
import requests
|
|
14
|
-
import subprocess
|
|
15
|
-
import logging
|
|
16
17
|
|
|
17
18
|
# Configure logging
|
|
18
19
|
logging.basicConfig(
|