geoai-py 0.3.4__tar.gz → 0.3.5__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 (78) hide show
  1. {geoai_py-0.3.4 → geoai_py-0.3.5}/PKG-INFO +1 -1
  2. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/_template.ipynb +70 -0
  3. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/car_detection.ipynb +16 -10
  4. geoai_py-0.3.5/docs/examples/ship_detection.ipynb +358 -0
  5. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai/__init__.py +1 -1
  6. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai/extract.py +109 -87
  7. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai/utils.py +2 -0
  8. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai_py.egg-info/PKG-INFO +1 -1
  9. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai_py.egg-info/SOURCES.txt +1 -0
  10. {geoai_py-0.3.4 → geoai_py-0.3.5}/mkdocs.yml +3 -0
  11. {geoai_py-0.3.4 → geoai_py-0.3.5}/pyproject.toml +2 -2
  12. {geoai_py-0.3.4 → geoai_py-0.3.5}/.editorconfig +0 -0
  13. {geoai_py-0.3.4 → geoai_py-0.3.5}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  14. {geoai_py-0.3.4 → geoai_py-0.3.5}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  15. {geoai_py-0.3.4 → geoai_py-0.3.5}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  16. {geoai_py-0.3.4 → geoai_py-0.3.5}/.github/dependabot.yml +0 -0
  17. {geoai_py-0.3.4 → geoai_py-0.3.5}/.github/workflows/docs-build.yml +0 -0
  18. {geoai_py-0.3.4 → geoai_py-0.3.5}/.github/workflows/docs.yml +0 -0
  19. {geoai_py-0.3.4 → geoai_py-0.3.5}/.github/workflows/macos.yml +0 -0
  20. {geoai_py-0.3.4 → geoai_py-0.3.5}/.github/workflows/pypi.yml +0 -0
  21. {geoai_py-0.3.4 → geoai_py-0.3.5}/.github/workflows/ubuntu.yml +0 -0
  22. {geoai_py-0.3.4 → geoai_py-0.3.5}/.github/workflows/windows.yml +0 -0
  23. {geoai_py-0.3.4 → geoai_py-0.3.5}/.gitignore +0 -0
  24. {geoai_py-0.3.4 → geoai_py-0.3.5}/.pre-commit-config.yaml +0 -0
  25. {geoai_py-0.3.4 → geoai_py-0.3.5}/LICENSE +0 -0
  26. {geoai_py-0.3.4 → geoai_py-0.3.5}/MANIFEST.in +0 -0
  27. {geoai_py-0.3.4 → geoai_py-0.3.5}/README.md +0 -0
  28. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/CNAME +0 -0
  29. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/changelog.md +0 -0
  30. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/contributing.md +0 -0
  31. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/download.md +0 -0
  32. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/building_footprints_usa.ipynb +0 -0
  33. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/building_regularization.ipynb +0 -0
  34. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/data_visualization.ipynb +0 -0
  35. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/dataviz/lidar_viz.ipynb +0 -0
  36. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/dataviz/raster_viz.ipynb +0 -0
  37. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/dataviz/vector_viz.ipynb +0 -0
  38. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/download_data.ipynb +0 -0
  39. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/geometric_properties.ipynb +0 -0
  40. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/image_chips.ipynb +0 -0
  41. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/jupytext.toml +0 -0
  42. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/rastervision/semantic_segmentation.ipynb +0 -0
  43. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/arcgis.ipynb +0 -0
  44. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/automatic_mask_generator.ipynb +0 -0
  45. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/automatic_mask_generator_hq.ipynb +0 -0
  46. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/box_prompts.ipynb +0 -0
  47. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/fast_sam.ipynb +0 -0
  48. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/input_prompts.ipynb +0 -0
  49. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/input_prompts_hq.ipynb +0 -0
  50. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/maxar_open_data.ipynb +0 -0
  51. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/satellite-predictor.ipynb +0 -0
  52. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/satellite.ipynb +0 -0
  53. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/swimming_pools.ipynb +0 -0
  54. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/text_prompts.ipynb +0 -0
  55. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/samgeo/text_prompts_batch.ipynb +0 -0
  56. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/examples/view_metadata.ipynb +0 -0
  57. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/extract.md +0 -0
  58. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/faq.md +0 -0
  59. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/geoai.md +0 -0
  60. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/index.md +0 -0
  61. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/installation.md +0 -0
  62. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/overrides/main.html +0 -0
  63. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/segmentation.md +0 -0
  64. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/usage.md +0 -0
  65. {geoai_py-0.3.4 → geoai_py-0.3.5}/docs/utils.md +0 -0
  66. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai/download.py +0 -0
  67. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai/geoai.py +0 -0
  68. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai/preprocess.py +0 -0
  69. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai/segmentation.py +0 -0
  70. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai_py.egg-info/dependency_links.txt +0 -0
  71. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai_py.egg-info/entry_points.txt +0 -0
  72. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai_py.egg-info/requires.txt +0 -0
  73. {geoai_py-0.3.4 → geoai_py-0.3.5}/geoai_py.egg-info/top_level.txt +0 -0
  74. {geoai_py-0.3.4 → geoai_py-0.3.5}/requirements.txt +0 -0
  75. {geoai_py-0.3.4 → geoai_py-0.3.5}/requirements_docs.txt +0 -0
  76. {geoai_py-0.3.4 → geoai_py-0.3.5}/setup.cfg +0 -0
  77. {geoai_py-0.3.4 → geoai_py-0.3.5}/tests/__init__.py +0 -0
  78. {geoai_py-0.3.4 → geoai_py-0.3.5}/tests/test_geoai.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: geoai-py
3
- Version: 0.3.4
3
+ Version: 0.3.5
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,6 +36,76 @@
36
36
  "source": [
37
37
  "import geoai"
38
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
+ },
54
+ {
55
+ "cell_type": "markdown",
56
+ "metadata": {},
57
+ "source": [
58
+ "## Visualize data"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": null,
64
+ "metadata": {},
65
+ "outputs": [],
66
+ "source": []
67
+ },
68
+ {
69
+ "cell_type": "markdown",
70
+ "metadata": {},
71
+ "source": [
72
+ "## Initialize model"
73
+ ]
74
+ },
75
+ {
76
+ "cell_type": "code",
77
+ "execution_count": null,
78
+ "metadata": {},
79
+ "outputs": [],
80
+ "source": []
81
+ },
82
+ {
83
+ "cell_type": "markdown",
84
+ "metadata": {},
85
+ "source": [
86
+ "## Run inference"
87
+ ]
88
+ },
89
+ {
90
+ "cell_type": "code",
91
+ "execution_count": null,
92
+ "metadata": {},
93
+ "outputs": [],
94
+ "source": []
95
+ },
96
+ {
97
+ "cell_type": "markdown",
98
+ "metadata": {},
99
+ "source": [
100
+ "## Visualize results"
101
+ ]
102
+ },
103
+ {
104
+ "cell_type": "code",
105
+ "execution_count": null,
106
+ "metadata": {},
107
+ "outputs": [],
108
+ "source": []
39
109
  }
40
110
  ],
41
111
  "metadata": {
@@ -79,7 +79,7 @@
79
79
  "metadata": {},
80
80
  "outputs": [],
81
81
  "source": [
82
- "# geoai.view_raster(raster_url)"
82
+ "geoai.view_raster(raster_url)"
83
83
  ]
84
84
  },
85
85
  {
@@ -116,9 +116,10 @@
116
116
  "mask_path = detector.generate_masks(\n",
117
117
  " raster_path=raster_path,\n",
118
118
  " output_path=\"cars_masks.tif\",\n",
119
- " confidence_threshold=0.5,\n",
120
- " mask_threshold=0.7,\n",
119
+ " confidence_threshold=0.3,\n",
120
+ " mask_threshold=0.5,\n",
121
121
  " overlap=0.25,\n",
122
+ " chip_size=(400, 400),\n",
122
123
  ")"
123
124
  ]
124
125
  },
@@ -138,12 +139,8 @@
138
139
  "gdf = detector.vectorize_masks(\n",
139
140
  " masks_path=\"cars_masks.tif\",\n",
140
141
  " output_path=\"cars.geojson\",\n",
141
- " mask_threshold=127,\n",
142
142
  " min_object_area=100,\n",
143
143
  " max_object_area=2000,\n",
144
- " erode_kernel_size=3,\n",
145
- " erode_iterations=1,\n",
146
- " use_watershed=True,\n",
147
144
  ")"
148
145
  ]
149
146
  },
@@ -192,7 +189,9 @@
192
189
  "metadata": {},
193
190
  "outputs": [],
194
191
  "source": [
195
- "gdf_filter = gdf[gdf[\"area_m2\"] > 8]"
192
+ "gdf_filter = gdf[\n",
193
+ " (gdf[\"area_m2\"] > 8) & (gdf[\"area_m2\"] < 60) & (gdf[\"minor_length_m\"] > 1)\n",
194
+ "]"
196
195
  ]
197
196
  },
198
197
  {
@@ -228,11 +227,18 @@
228
227
  "source": [
229
228
  "geoai.view_vector_interactive(gdf_filter, tiles=raster_url)"
230
229
  ]
230
+ },
231
+ {
232
+ "cell_type": "markdown",
233
+ "metadata": {},
234
+ "source": [
235
+ "![image](https://github.com/user-attachments/assets/a1e4c871-b152-466a-b902-7c00e62e5444)"
236
+ ]
231
237
  }
232
238
  ],
233
239
  "metadata": {
234
240
  "kernelspec": {
235
- "display_name": "geo",
241
+ "display_name": "torch",
236
242
  "language": "python",
237
243
  "name": "python3"
238
244
  },
@@ -246,7 +252,7 @@
246
252
  "name": "python",
247
253
  "nbconvert_exporter": "python",
248
254
  "pygments_lexer": "ipython3",
249
- "version": "3.12.2"
255
+ "version": "3.11.8"
250
256
  }
251
257
  },
252
258
  "nbformat": 4,
@@ -0,0 +1,358 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Ship Detection\n",
8
+ "\n",
9
+ "This notebook demonstrates how to use the geoai package for ship detection using a pre-trained model. \n",
10
+ "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/opengeos/geoai/blob/main/docs/examples/ship_detection.ipynb)\n",
11
+ "\n",
12
+ "## Install package\n",
13
+ "To use the `geoai-py` package, ensure it is installed in your environment. Uncomment the command below if needed."
14
+ ]
15
+ },
16
+ {
17
+ "cell_type": "code",
18
+ "execution_count": null,
19
+ "metadata": {},
20
+ "outputs": [],
21
+ "source": [
22
+ "# %pip install geoai-py"
23
+ ]
24
+ },
25
+ {
26
+ "cell_type": "markdown",
27
+ "metadata": {},
28
+ "source": [
29
+ "## Import libraries"
30
+ ]
31
+ },
32
+ {
33
+ "cell_type": "code",
34
+ "execution_count": null,
35
+ "metadata": {},
36
+ "outputs": [],
37
+ "source": [
38
+ "import geoai"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "markdown",
43
+ "metadata": {},
44
+ "source": [
45
+ "## Download sample data"
46
+ ]
47
+ },
48
+ {
49
+ "cell_type": "code",
50
+ "execution_count": null,
51
+ "metadata": {},
52
+ "outputs": [],
53
+ "source": [
54
+ "raster_url = (\n",
55
+ " \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/ships_dubai.tif\"\n",
56
+ ")\n",
57
+ "raster_path = geoai.download_file(raster_url, \"ships_dubai.tif\")"
58
+ ]
59
+ },
60
+ {
61
+ "cell_type": "markdown",
62
+ "metadata": {},
63
+ "source": [
64
+ "## Visualize data"
65
+ ]
66
+ },
67
+ {
68
+ "cell_type": "code",
69
+ "execution_count": null,
70
+ "metadata": {},
71
+ "outputs": [],
72
+ "source": [
73
+ "geoai.view_raster(raster_url)"
74
+ ]
75
+ },
76
+ {
77
+ "cell_type": "markdown",
78
+ "metadata": {},
79
+ "source": [
80
+ "## Initialize model"
81
+ ]
82
+ },
83
+ {
84
+ "cell_type": "code",
85
+ "execution_count": null,
86
+ "metadata": {},
87
+ "outputs": [],
88
+ "source": [
89
+ "detector = geoai.ShipDetector()"
90
+ ]
91
+ },
92
+ {
93
+ "cell_type": "markdown",
94
+ "metadata": {},
95
+ "source": [
96
+ "## Generate masks"
97
+ ]
98
+ },
99
+ {
100
+ "cell_type": "code",
101
+ "execution_count": null,
102
+ "metadata": {},
103
+ "outputs": [],
104
+ "source": [
105
+ "output_path = \"ships_dubai_masks.tif\""
106
+ ]
107
+ },
108
+ {
109
+ "cell_type": "code",
110
+ "execution_count": null,
111
+ "metadata": {},
112
+ "outputs": [],
113
+ "source": [
114
+ "masks_path = detector.generate_masks(\n",
115
+ " raster_path,\n",
116
+ " output_path=output_path,\n",
117
+ " confidence_threshold=0.9,\n",
118
+ " mask_threshold=0.7,\n",
119
+ " overlap=0.25,\n",
120
+ " chip_size=(256, 256),\n",
121
+ " batch_size=4,\n",
122
+ ")"
123
+ ]
124
+ },
125
+ {
126
+ "cell_type": "markdown",
127
+ "metadata": {},
128
+ "source": [
129
+ "## Vectorize masks"
130
+ ]
131
+ },
132
+ {
133
+ "cell_type": "code",
134
+ "execution_count": null,
135
+ "metadata": {},
136
+ "outputs": [],
137
+ "source": [
138
+ "gdf = detector.vectorize_masks(\n",
139
+ " output_path,\n",
140
+ " output_path=\"ships_dubai_masks.geojson\",\n",
141
+ " confidence_threshold=0.8,\n",
142
+ " min_object_area=100,\n",
143
+ " max_object_size=10000,\n",
144
+ ")"
145
+ ]
146
+ },
147
+ {
148
+ "cell_type": "markdown",
149
+ "metadata": {},
150
+ "source": [
151
+ "## Visualize initial results"
152
+ ]
153
+ },
154
+ {
155
+ "cell_type": "code",
156
+ "execution_count": null,
157
+ "metadata": {},
158
+ "outputs": [],
159
+ "source": [
160
+ "geoai.view_vector_interactive(gdf, column=\"confidence\", tiles=raster_url)"
161
+ ]
162
+ },
163
+ {
164
+ "cell_type": "markdown",
165
+ "metadata": {},
166
+ "source": [
167
+ "## Calculate geometric properties"
168
+ ]
169
+ },
170
+ {
171
+ "cell_type": "code",
172
+ "execution_count": null,
173
+ "metadata": {},
174
+ "outputs": [],
175
+ "source": [
176
+ "gdf = geoai.add_geometric_properties(gdf)\n",
177
+ "gdf.head()"
178
+ ]
179
+ },
180
+ {
181
+ "cell_type": "code",
182
+ "execution_count": null,
183
+ "metadata": {},
184
+ "outputs": [],
185
+ "source": [
186
+ "geoai.view_vector_interactive(gdf, column=\"confidence\", tiles=raster_url)"
187
+ ]
188
+ },
189
+ {
190
+ "cell_type": "markdown",
191
+ "metadata": {},
192
+ "source": [
193
+ "## Filter results"
194
+ ]
195
+ },
196
+ {
197
+ "cell_type": "code",
198
+ "execution_count": null,
199
+ "metadata": {},
200
+ "outputs": [],
201
+ "source": [
202
+ "m = geoai.view_raster(raster_url, backend=\"ipyleaflet\")\n",
203
+ "m"
204
+ ]
205
+ },
206
+ {
207
+ "cell_type": "markdown",
208
+ "metadata": {},
209
+ "source": [
210
+ "Use the drawing tool to select the area of interest. "
211
+ ]
212
+ },
213
+ {
214
+ "cell_type": "code",
215
+ "execution_count": null,
216
+ "metadata": {},
217
+ "outputs": [],
218
+ "source": [
219
+ "aoi = m.user_rois\n",
220
+ "\n",
221
+ "if aoi is None:\n",
222
+ "\n",
223
+ " aoi = {\n",
224
+ " \"type\": \"FeatureCollection\",\n",
225
+ " \"features\": [\n",
226
+ " {\n",
227
+ " \"type\": \"Feature\",\n",
228
+ " \"properties\": {},\n",
229
+ " \"geometry\": {\n",
230
+ " \"type\": \"Polygon\",\n",
231
+ " \"coordinates\": [\n",
232
+ " [\n",
233
+ " [55.133729, 25.110277],\n",
234
+ " [55.134072, 25.11393],\n",
235
+ " [55.134823, 25.115601],\n",
236
+ " [55.136025, 25.117116],\n",
237
+ " [55.137677, 25.118127],\n",
238
+ " [55.140145, 25.118787],\n",
239
+ " [55.142248, 25.11902],\n",
240
+ " [55.142012, 25.118243],\n",
241
+ " [55.140831, 25.116728],\n",
242
+ " [55.13948, 25.116903],\n",
243
+ " [55.137956, 25.116825],\n",
244
+ " [55.136132, 25.115543],\n",
245
+ " [55.13566, 25.114416],\n",
246
+ " [55.135467, 25.1136],\n",
247
+ " [55.135939, 25.112609],\n",
248
+ " [55.136218, 25.111657],\n",
249
+ " [55.13551, 25.110685],\n",
250
+ " [55.134373, 25.110102],\n",
251
+ " [55.133729, 25.110277],\n",
252
+ " ]\n",
253
+ " ],\n",
254
+ " },\n",
255
+ " }\n",
256
+ " ],\n",
257
+ " }"
258
+ ]
259
+ },
260
+ {
261
+ "cell_type": "code",
262
+ "execution_count": null,
263
+ "metadata": {},
264
+ "outputs": [],
265
+ "source": [
266
+ "import geopandas as gpd"
267
+ ]
268
+ },
269
+ {
270
+ "cell_type": "code",
271
+ "execution_count": null,
272
+ "metadata": {},
273
+ "outputs": [],
274
+ "source": [
275
+ "aoi_gdf = gpd.GeoDataFrame.from_features(aoi[\"features\"], crs=\"EPSG:4326\").to_crs(\n",
276
+ " gdf.crs\n",
277
+ ")"
278
+ ]
279
+ },
280
+ {
281
+ "cell_type": "markdown",
282
+ "metadata": {},
283
+ "source": [
284
+ "Intersect the selected area with the vectorized masks to filter the results."
285
+ ]
286
+ },
287
+ {
288
+ "cell_type": "code",
289
+ "execution_count": null,
290
+ "metadata": {},
291
+ "outputs": [],
292
+ "source": [
293
+ "gdf_filter = gdf[gdf.intersects(aoi_gdf.geometry[0])]\n",
294
+ "gdf_filter.head()"
295
+ ]
296
+ },
297
+ {
298
+ "cell_type": "markdown",
299
+ "metadata": {},
300
+ "source": [
301
+ "## Visualize final results"
302
+ ]
303
+ },
304
+ {
305
+ "cell_type": "code",
306
+ "execution_count": null,
307
+ "metadata": {},
308
+ "outputs": [],
309
+ "source": [
310
+ "geoai.view_vector_interactive(gdf_filter, column=\"confidence\", tiles=raster_url)"
311
+ ]
312
+ },
313
+ {
314
+ "cell_type": "markdown",
315
+ "metadata": {},
316
+ "source": [
317
+ "## Save results"
318
+ ]
319
+ },
320
+ {
321
+ "cell_type": "code",
322
+ "execution_count": null,
323
+ "metadata": {},
324
+ "outputs": [],
325
+ "source": [
326
+ "gdf_filter.to_file(\"ships_dubai.geojson\")"
327
+ ]
328
+ },
329
+ {
330
+ "cell_type": "markdown",
331
+ "metadata": {},
332
+ "source": [
333
+ "![image](https://github.com/user-attachments/assets/80df3827-8453-45b2-af89-21662fdf95a6)"
334
+ ]
335
+ }
336
+ ],
337
+ "metadata": {
338
+ "kernelspec": {
339
+ "display_name": "geo",
340
+ "language": "python",
341
+ "name": "python3"
342
+ },
343
+ "language_info": {
344
+ "codemirror_mode": {
345
+ "name": "ipython",
346
+ "version": 3
347
+ },
348
+ "file_extension": ".py",
349
+ "mimetype": "text/x-python",
350
+ "name": "python",
351
+ "nbconvert_exporter": "python",
352
+ "pygments_lexer": "ipython3",
353
+ "version": "3.12.9"
354
+ }
355
+ },
356
+ "nbformat": 4,
357
+ "nbformat_minor": 2
358
+ }
@@ -2,7 +2,7 @@
2
2
 
3
3
  __author__ = """Qiusheng Wu"""
4
4
  __email__ = "giswqs@gmail.com"
5
- __version__ = "0.3.4"
5
+ __version__ = "0.3.5"
6
6
 
7
7
 
8
8
  import os
@@ -1881,88 +1881,6 @@ class ObjectDetector:
1881
1881
  plt.savefig(sample_output, dpi=300, bbox_inches="tight")
1882
1882
  print(f"Sample visualization saved to {sample_output}")
1883
1883
 
1884
-
1885
- class BuildingFootprintExtractor(ObjectDetector):
1886
- """
1887
- Building footprint extraction using a pre-trained Mask R-CNN model.
1888
-
1889
- This class extends the
1890
- `ObjectDetector` class with additional methods for building footprint extraction."
1891
- """
1892
-
1893
- def __init__(
1894
- self,
1895
- model_path="building_footprints_usa.pth",
1896
- repo_id=None,
1897
- model=None,
1898
- device=None,
1899
- ):
1900
- """
1901
- Initialize the object extractor.
1902
-
1903
- Args:
1904
- model_path: Path to the .pth model file.
1905
- repo_id: Repo ID for loading models from the Hub.
1906
- model: Custom model to use for inference.
1907
- device: Device to use for inference ('cuda:0', 'cpu', etc.).
1908
- """
1909
- super().__init__(
1910
- model_path=model_path, repo_id=repo_id, model=model, device=device
1911
- )
1912
-
1913
- def regularize_buildings(
1914
- self,
1915
- gdf,
1916
- min_area=10,
1917
- angle_threshold=15,
1918
- orthogonality_threshold=0.3,
1919
- rectangularity_threshold=0.7,
1920
- ):
1921
- """
1922
- Regularize building footprints to enforce right angles and rectangular shapes.
1923
-
1924
- Args:
1925
- gdf: GeoDataFrame with building footprints
1926
- min_area: Minimum area in square units to keep a building
1927
- angle_threshold: Maximum deviation from 90 degrees to consider an angle as orthogonal (degrees)
1928
- orthogonality_threshold: Percentage of angles that must be orthogonal for a building to be regularized
1929
- rectangularity_threshold: Minimum area ratio to building's oriented bounding box for rectangular simplification
1930
-
1931
- Returns:
1932
- GeoDataFrame with regularized building footprints
1933
- """
1934
- return self.regularize_objects(
1935
- gdf,
1936
- min_area=min_area,
1937
- angle_threshold=angle_threshold,
1938
- orthogonality_threshold=orthogonality_threshold,
1939
- rectangularity_threshold=rectangularity_threshold,
1940
- )
1941
-
1942
-
1943
- class CarDetector(ObjectDetector):
1944
- """
1945
- Car detection using a pre-trained Mask R-CNN model.
1946
-
1947
- This class extends the `ObjectDetector` class with additional methods for car detection.
1948
- """
1949
-
1950
- def __init__(
1951
- self, model_path="car_detection_usa.pth", repo_id=None, model=None, device=None
1952
- ):
1953
- """
1954
- Initialize the object extractor.
1955
-
1956
- Args:
1957
- model_path: Path to the .pth model file.
1958
- repo_id: Repo ID for loading models from the Hub.
1959
- model: Custom model to use for inference.
1960
- device: Device to use for inference ('cuda:0', 'cpu', etc.).
1961
- """
1962
- super().__init__(
1963
- model_path=model_path, repo_id=repo_id, model=model, device=device
1964
- )
1965
-
1966
1884
  def generate_masks(
1967
1885
  self,
1968
1886
  raster_path,
@@ -1972,6 +1890,7 @@ class CarDetector(ObjectDetector):
1972
1890
  overlap=0.25,
1973
1891
  batch_size=4,
1974
1892
  verbose=False,
1893
+ **kwargs,
1975
1894
  ):
1976
1895
  """
1977
1896
  Save masks with confidence values as a multi-band GeoTIFF.
@@ -1994,6 +1913,8 @@ class CarDetector(ObjectDetector):
1994
1913
  if mask_threshold is None:
1995
1914
  mask_threshold = self.mask_threshold
1996
1915
 
1916
+ chip_size = kwargs.get("chip_size", self.chip_size)
1917
+
1997
1918
  # Default output path
1998
1919
  if output_path is None:
1999
1920
  output_path = os.path.splitext(raster_path)[0] + "_masks_conf.tif"
@@ -2003,7 +1924,7 @@ class CarDetector(ObjectDetector):
2003
1924
  # Create dataset with the specified overlap
2004
1925
  dataset = CustomDataset(
2005
1926
  raster_path=raster_path,
2006
- chip_size=self.chip_size,
1927
+ chip_size=chip_size,
2007
1928
  overlap=overlap,
2008
1929
  verbose=verbose,
2009
1930
  )
@@ -2135,13 +2056,24 @@ class CarDetector(ObjectDetector):
2135
2056
  print(f"Masks with confidence values saved to {output_path}")
2136
2057
  return output_path
2137
2058
 
2138
- def vectorize_masks(self, masks_path, output_path=None, **kwargs):
2059
+ def vectorize_masks(
2060
+ self,
2061
+ masks_path,
2062
+ output_path=None,
2063
+ confidence_threshold=0.5,
2064
+ min_object_area=100,
2065
+ max_object_size=None,
2066
+ **kwargs,
2067
+ ):
2139
2068
  """
2140
2069
  Convert masks with confidence to vector polygons.
2141
2070
 
2142
2071
  Args:
2143
- masks_path: Path to masks GeoTIFF with confidence band
2144
- output_path: Path for output GeoJSON
2072
+ masks_path: Path to masks GeoTIFF with confidence band.
2073
+ output_path: Path for output GeoJSON.
2074
+ confidence_threshold: Minimum confidence score (0.0-1.0). Default: 0.5
2075
+ min_object_area: Minimum area in pixels to keep an object. Default: 100
2076
+ max_object_size: Maximum area in pixels to keep an object. Default: None
2145
2077
  **kwargs: Additional parameters
2146
2078
 
2147
2079
  Returns:
@@ -2182,6 +2114,10 @@ class CarDetector(ObjectDetector):
2182
2114
  else:
2183
2115
  confidence = 0.0
2184
2116
 
2117
+ # Skip if confidence is below threshold
2118
+ if confidence < confidence_threshold:
2119
+ continue
2120
+
2185
2121
  # Find contours
2186
2122
  contours, _ = cv2.findContours(
2187
2123
  component_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
@@ -2190,9 +2126,13 @@ class CarDetector(ObjectDetector):
2190
2126
  for contour in contours:
2191
2127
  # Filter by size
2192
2128
  area = cv2.contourArea(contour)
2193
- if area < kwargs.get("min_object_area", 100):
2129
+ if area < min_object_area:
2194
2130
  continue
2195
2131
 
2132
+ if max_object_size is not None:
2133
+ if area > max_object_size:
2134
+ continue
2135
+
2196
2136
  # Get minimum area rectangle
2197
2137
  rect = cv2.minAreaRect(contour)
2198
2138
  box_points = cv2.boxPoints(rect)
@@ -2232,6 +2172,88 @@ class CarDetector(ObjectDetector):
2232
2172
  return None
2233
2173
 
2234
2174
 
2175
+ class BuildingFootprintExtractor(ObjectDetector):
2176
+ """
2177
+ Building footprint extraction using a pre-trained Mask R-CNN model.
2178
+
2179
+ This class extends the
2180
+ `ObjectDetector` class with additional methods for building footprint extraction."
2181
+ """
2182
+
2183
+ def __init__(
2184
+ self,
2185
+ model_path="building_footprints_usa.pth",
2186
+ repo_id=None,
2187
+ model=None,
2188
+ device=None,
2189
+ ):
2190
+ """
2191
+ Initialize the object extractor.
2192
+
2193
+ Args:
2194
+ model_path: Path to the .pth model file.
2195
+ repo_id: Repo ID for loading models from the Hub.
2196
+ model: Custom model to use for inference.
2197
+ device: Device to use for inference ('cuda:0', 'cpu', etc.).
2198
+ """
2199
+ super().__init__(
2200
+ model_path=model_path, repo_id=repo_id, model=model, device=device
2201
+ )
2202
+
2203
+ def regularize_buildings(
2204
+ self,
2205
+ gdf,
2206
+ min_area=10,
2207
+ angle_threshold=15,
2208
+ orthogonality_threshold=0.3,
2209
+ rectangularity_threshold=0.7,
2210
+ ):
2211
+ """
2212
+ Regularize building footprints to enforce right angles and rectangular shapes.
2213
+
2214
+ Args:
2215
+ gdf: GeoDataFrame with building footprints
2216
+ min_area: Minimum area in square units to keep a building
2217
+ angle_threshold: Maximum deviation from 90 degrees to consider an angle as orthogonal (degrees)
2218
+ orthogonality_threshold: Percentage of angles that must be orthogonal for a building to be regularized
2219
+ rectangularity_threshold: Minimum area ratio to building's oriented bounding box for rectangular simplification
2220
+
2221
+ Returns:
2222
+ GeoDataFrame with regularized building footprints
2223
+ """
2224
+ return self.regularize_objects(
2225
+ gdf,
2226
+ min_area=min_area,
2227
+ angle_threshold=angle_threshold,
2228
+ orthogonality_threshold=orthogonality_threshold,
2229
+ rectangularity_threshold=rectangularity_threshold,
2230
+ )
2231
+
2232
+
2233
+ class CarDetector(ObjectDetector):
2234
+ """
2235
+ Car detection using a pre-trained Mask R-CNN model.
2236
+
2237
+ This class extends the `ObjectDetector` class with additional methods for car detection.
2238
+ """
2239
+
2240
+ def __init__(
2241
+ self, model_path="car_detection_usa.pth", repo_id=None, model=None, device=None
2242
+ ):
2243
+ """
2244
+ Initialize the object extractor.
2245
+
2246
+ Args:
2247
+ model_path: Path to the .pth model file.
2248
+ repo_id: Repo ID for loading models from the Hub.
2249
+ model: Custom model to use for inference.
2250
+ device: Device to use for inference ('cuda:0', 'cpu', etc.).
2251
+ """
2252
+ super().__init__(
2253
+ model_path=model_path, repo_id=repo_id, model=model, device=device
2254
+ )
2255
+
2256
+
2235
2257
  class ShipDetector(ObjectDetector):
2236
2258
  """
2237
2259
  Ship detection using a pre-trained Mask R-CNN model.
@@ -84,6 +84,8 @@ def view_raster(
84
84
 
85
85
  if backend == "folium":
86
86
  import leafmap.foliumap as leafmap
87
+ else:
88
+ import leafmap.leafmap as leafmap
87
89
 
88
90
  m = leafmap.Map(basemap=basemap)
89
91
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: geoai-py
3
- Version: 0.3.4
3
+ Version: 0.3.5
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
@@ -39,6 +39,7 @@ docs/examples/download_data.ipynb
39
39
  docs/examples/geometric_properties.ipynb
40
40
  docs/examples/image_chips.ipynb
41
41
  docs/examples/jupytext.toml
42
+ docs/examples/ship_detection.ipynb
42
43
  docs/examples/view_metadata.ipynb
43
44
  docs/examples/dataviz/lidar_viz.ipynb
44
45
  docs/examples/dataviz/raster_viz.ipynb
@@ -57,6 +57,8 @@ plugins:
57
57
  "examples/samgeo/*.ipynb",
58
58
  "examples/data_visualization.ipynb",
59
59
  "examples/download_data.ipynb",
60
+ "examples/car_detection.ipynb",
61
+ "examples/ship_detection.ipynb",
60
62
  ]
61
63
 
62
64
  markdown_extensions:
@@ -94,6 +96,7 @@ nav:
94
96
  - examples/building_regularization.ipynb
95
97
  - examples/geometric_properties.ipynb
96
98
  - examples/car_detection.ipynb
99
+ - examples/ship_detection.ipynb
97
100
  - examples/data_visualization.ipynb
98
101
  - examples/samgeo/satellite.ipynb
99
102
  - examples/samgeo/automatic_mask_generator.ipynb
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "geoai-py"
3
- version = "0.3.4"
3
+ version = "0.3.5"
4
4
  dynamic = [
5
5
  "dependencies",
6
6
  ]
@@ -47,7 +47,7 @@ universal = true
47
47
 
48
48
 
49
49
  [tool.bumpversion]
50
- current_version = "0.3.4"
50
+ current_version = "0.3.5"
51
51
  commit = true
52
52
  tag = true
53
53
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes