geoai-py 0.3.2__tar.gz → 0.3.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 (77) hide show
  1. {geoai_py-0.3.2 → geoai_py-0.3.3}/PKG-INFO +11 -4
  2. {geoai_py-0.3.2 → geoai_py-0.3.3}/README.md +9 -3
  3. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/building_footprints_usa.ipynb +4 -3
  4. geoai_py-0.3.3/docs/examples/geometric_properties.ipynb +199 -0
  5. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/index.md +9 -3
  6. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai/__init__.py +1 -1
  7. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai/extract.py +38 -17
  8. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai/geoai.py +0 -1
  9. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai/preprocess.py +20 -6
  10. geoai_py-0.3.3/geoai/utils.py +4951 -0
  11. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai_py.egg-info/PKG-INFO +11 -4
  12. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai_py.egg-info/SOURCES.txt +1 -1
  13. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai_py.egg-info/requires.txt +1 -0
  14. {geoai_py-0.3.2 → geoai_py-0.3.3}/mkdocs.yml +1 -1
  15. {geoai_py-0.3.2 → geoai_py-0.3.3}/pyproject.toml +2 -2
  16. {geoai_py-0.3.2 → geoai_py-0.3.3}/requirements.txt +1 -0
  17. geoai_py-0.3.2/docs/preprocess.md +0 -3
  18. geoai_py-0.3.2/geoai/utils.py +0 -1176
  19. {geoai_py-0.3.2 → geoai_py-0.3.3}/.editorconfig +0 -0
  20. {geoai_py-0.3.2 → geoai_py-0.3.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  21. {geoai_py-0.3.2 → geoai_py-0.3.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  22. {geoai_py-0.3.2 → geoai_py-0.3.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  23. {geoai_py-0.3.2 → geoai_py-0.3.3}/.github/dependabot.yml +0 -0
  24. {geoai_py-0.3.2 → geoai_py-0.3.3}/.github/workflows/docs-build.yml +0 -0
  25. {geoai_py-0.3.2 → geoai_py-0.3.3}/.github/workflows/docs.yml +0 -0
  26. {geoai_py-0.3.2 → geoai_py-0.3.3}/.github/workflows/macos.yml +0 -0
  27. {geoai_py-0.3.2 → geoai_py-0.3.3}/.github/workflows/pypi.yml +0 -0
  28. {geoai_py-0.3.2 → geoai_py-0.3.3}/.github/workflows/ubuntu.yml +0 -0
  29. {geoai_py-0.3.2 → geoai_py-0.3.3}/.github/workflows/windows.yml +0 -0
  30. {geoai_py-0.3.2 → geoai_py-0.3.3}/.gitignore +0 -0
  31. {geoai_py-0.3.2 → geoai_py-0.3.3}/.pre-commit-config.yaml +0 -0
  32. {geoai_py-0.3.2 → geoai_py-0.3.3}/LICENSE +0 -0
  33. {geoai_py-0.3.2 → geoai_py-0.3.3}/MANIFEST.in +0 -0
  34. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/CNAME +0 -0
  35. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/changelog.md +0 -0
  36. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/contributing.md +0 -0
  37. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/download.md +0 -0
  38. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/building_regularization.ipynb +0 -0
  39. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/data_visualization.ipynb +0 -0
  40. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/dataviz/lidar_viz.ipynb +0 -0
  41. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/dataviz/raster_viz.ipynb +0 -0
  42. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/dataviz/vector_viz.ipynb +0 -0
  43. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/download_data.ipynb +0 -0
  44. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/image_chips.ipynb +0 -0
  45. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/jupytext.toml +0 -0
  46. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/rastervision/semantic_segmentation.ipynb +0 -0
  47. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/arcgis.ipynb +0 -0
  48. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/automatic_mask_generator.ipynb +0 -0
  49. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/automatic_mask_generator_hq.ipynb +0 -0
  50. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/box_prompts.ipynb +0 -0
  51. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/fast_sam.ipynb +0 -0
  52. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/input_prompts.ipynb +0 -0
  53. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/input_prompts_hq.ipynb +0 -0
  54. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/maxar_open_data.ipynb +0 -0
  55. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/satellite-predictor.ipynb +0 -0
  56. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/satellite.ipynb +0 -0
  57. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/swimming_pools.ipynb +0 -0
  58. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/text_prompts.ipynb +0 -0
  59. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/samgeo/text_prompts_batch.ipynb +0 -0
  60. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/examples/view_metadata.ipynb +0 -0
  61. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/extract.md +0 -0
  62. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/faq.md +0 -0
  63. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/geoai.md +0 -0
  64. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/installation.md +0 -0
  65. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/overrides/main.html +0 -0
  66. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/segmentation.md +0 -0
  67. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/usage.md +0 -0
  68. {geoai_py-0.3.2 → geoai_py-0.3.3}/docs/utils.md +0 -0
  69. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai/download.py +0 -0
  70. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai/segmentation.py +0 -0
  71. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai_py.egg-info/dependency_links.txt +0 -0
  72. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai_py.egg-info/entry_points.txt +0 -0
  73. {geoai_py-0.3.2 → geoai_py-0.3.3}/geoai_py.egg-info/top_level.txt +0 -0
  74. {geoai_py-0.3.2 → geoai_py-0.3.3}/requirements_docs.txt +0 -0
  75. {geoai_py-0.3.2 → geoai_py-0.3.3}/setup.cfg +0 -0
  76. {geoai_py-0.3.2 → geoai_py-0.3.3}/tests/__init__.py +0 -0
  77. {geoai_py-0.3.2 → geoai_py-0.3.3}/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.2
3
+ Version: 0.3.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
@@ -30,6 +30,7 @@ Requires-Dist: planetary-computer
30
30
  Requires-Dist: pystac-client
31
31
  Requires-Dist: rasterio
32
32
  Requires-Dist: rioxarray
33
+ Requires-Dist: scikit-image
33
34
  Requires-Dist: scikit-learn
34
35
  Requires-Dist: torch
35
36
  Requires-Dist: torchgeo
@@ -49,9 +50,9 @@ Requires-Dist: geoai[download]; extra == "all"
49
50
  [![image](https://static.pepy.tech/badge/geoai-py)](https://pepy.tech/project/geoai-py)
50
51
  [![image](https://img.shields.io/conda/vn/conda-forge/geoai.svg)](https://anaconda.org/conda-forge/geoai)
51
52
  [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/geoai.svg)](https://anaconda.org/conda-forge/geoai)
52
- [![Conda Recipe](https://img.shields.io/badge/recipe-geoai-green.svg)](https://github.com/conda-forge/geoai-py-feedstock)
53
+ [![Conda Recipe](https://img.shields.io/badge/recipe-geoai-green.svg)](https://github.com/giswqs/geoai-py-feedstock)
53
54
  [![image](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
54
- [![image](https://img.shields.io/badge/YouTube-Channel-red)](https://youtube.com/@giswqs)
55
+ [![image](https://img.shields.io/badge/YouTube-Tutorials-red)](https://bit.ly/GeoAI-Tutorials)
55
56
 
56
57
  **A powerful Python package for integrating Artificial Intelligence with geospatial data analysis and visualization**
57
58
 
@@ -85,7 +86,7 @@ GeoAI bridges the gap between AI and geospatial analysis, providing tools for pr
85
86
  - Integration with Meta's Segment Anything Model (SAM) for automatic feature extraction
86
87
  - Specialized segmentation algorithms optimized for satellite and aerial imagery
87
88
  - Streamlined workflows for segmenting buildings, roads, vegetation, and water bodies
88
- - Export capabilities to standard geospatial formats (GeoJSON, Shapefile, GeoPackage)
89
+ - Export capabilities to standard geospatial formats (GeoJSON, Shapefile, GeoPackage, GeoParquet)
89
90
 
90
91
  ### 🔍 Image Classification
91
92
 
@@ -130,6 +131,12 @@ Comprehensive documentation is available at [https://geoai.gishub.org](https://g
130
131
  - Explanation of algorithms and models
131
132
  - Best practices for geospatial AI
132
133
 
134
+ ## 📺 Video Tutorials
135
+
136
+ Check out our [YouTube channel](https://bit.ly/GeoAI-Tutorials) for video tutorials on using GeoAI for geospatial data analysis and visualization.
137
+
138
+ [![cover](https://github.com/user-attachments/assets/3cde9547-ab62-4d70-b23a-3e5ed27c7407)](https://bit.ly/GeoAI-Tutorials)
139
+
133
140
  ## 🤝 Contributing
134
141
 
135
142
  We welcome contributions of all kinds! See our [contributing guide](https://geoai.gishub.org/contributing) for ways to get started.
@@ -4,9 +4,9 @@
4
4
  [![image](https://static.pepy.tech/badge/geoai-py)](https://pepy.tech/project/geoai-py)
5
5
  [![image](https://img.shields.io/conda/vn/conda-forge/geoai.svg)](https://anaconda.org/conda-forge/geoai)
6
6
  [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/geoai.svg)](https://anaconda.org/conda-forge/geoai)
7
- [![Conda Recipe](https://img.shields.io/badge/recipe-geoai-green.svg)](https://github.com/conda-forge/geoai-py-feedstock)
7
+ [![Conda Recipe](https://img.shields.io/badge/recipe-geoai-green.svg)](https://github.com/giswqs/geoai-py-feedstock)
8
8
  [![image](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
- [![image](https://img.shields.io/badge/YouTube-Channel-red)](https://youtube.com/@giswqs)
9
+ [![image](https://img.shields.io/badge/YouTube-Tutorials-red)](https://bit.ly/GeoAI-Tutorials)
10
10
 
11
11
  **A powerful Python package for integrating Artificial Intelligence with geospatial data analysis and visualization**
12
12
 
@@ -40,7 +40,7 @@ GeoAI bridges the gap between AI and geospatial analysis, providing tools for pr
40
40
  - Integration with Meta's Segment Anything Model (SAM) for automatic feature extraction
41
41
  - Specialized segmentation algorithms optimized for satellite and aerial imagery
42
42
  - Streamlined workflows for segmenting buildings, roads, vegetation, and water bodies
43
- - Export capabilities to standard geospatial formats (GeoJSON, Shapefile, GeoPackage)
43
+ - Export capabilities to standard geospatial formats (GeoJSON, Shapefile, GeoPackage, GeoParquet)
44
44
 
45
45
  ### 🔍 Image Classification
46
46
 
@@ -85,6 +85,12 @@ Comprehensive documentation is available at [https://geoai.gishub.org](https://g
85
85
  - Explanation of algorithms and models
86
86
  - Best practices for geospatial AI
87
87
 
88
+ ## 📺 Video Tutorials
89
+
90
+ Check out our [YouTube channel](https://bit.ly/GeoAI-Tutorials) for video tutorials on using GeoAI for geospatial data analysis and visualization.
91
+
92
+ [![cover](https://github.com/user-attachments/assets/3cde9547-ab62-4d70-b23a-3e5ed27c7407)](https://bit.ly/GeoAI-Tutorials)
93
+
88
94
  ## 🤝 Contributing
89
95
 
90
96
  We welcome contributions of all kinds! See our [contributing guide](https://geoai.gishub.org/contributing) for ways to get started.
@@ -156,7 +156,8 @@
156
156
  " confidence_threshold=0.5,\n",
157
157
  " overlap=0.25,\n",
158
158
  " nms_iou_threshold=0.5,\n",
159
- " small_building_area=100,\n",
159
+ " min_object_area=100,\n",
160
+ " max_object_area=None,\n",
160
161
  " mask_threshold=0.5,\n",
161
162
  " simplify_tolerance=1.0,\n",
162
163
  ")"
@@ -256,7 +257,7 @@
256
257
  ],
257
258
  "metadata": {
258
259
  "kernelspec": {
259
- "display_name": "torch",
260
+ "display_name": "geo",
260
261
  "language": "python",
261
262
  "name": "python3"
262
263
  },
@@ -270,7 +271,7 @@
270
271
  "name": "python",
271
272
  "nbconvert_exporter": "python",
272
273
  "pygments_lexer": "ipython3",
273
- "version": "3.11.8"
274
+ "version": "3.12.2"
274
275
  }
275
276
  },
276
277
  "nbformat": 4,
@@ -0,0 +1,199 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Geometric Properties\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/geometric_properties.ipynb)\n",
10
+ "\n",
11
+ "This notebook demonstrates how to calculate geometric properties of objects in a vector dataset and filter out unwanted objects based on these properties.\n",
12
+ "\n",
13
+ "## Install package\n",
14
+ "To use the `geoai-py` package, ensure it is installed in your environment. Uncomment the command below if needed."
15
+ ]
16
+ },
17
+ {
18
+ "cell_type": "code",
19
+ "execution_count": null,
20
+ "metadata": {},
21
+ "outputs": [],
22
+ "source": [
23
+ "# %pip install geoai-py"
24
+ ]
25
+ },
26
+ {
27
+ "cell_type": "markdown",
28
+ "metadata": {},
29
+ "source": [
30
+ "## Import package"
31
+ ]
32
+ },
33
+ {
34
+ "cell_type": "code",
35
+ "execution_count": null,
36
+ "metadata": {},
37
+ "outputs": [],
38
+ "source": [
39
+ "import geoai"
40
+ ]
41
+ },
42
+ {
43
+ "cell_type": "markdown",
44
+ "metadata": {},
45
+ "source": [
46
+ "## Load data"
47
+ ]
48
+ },
49
+ {
50
+ "cell_type": "code",
51
+ "execution_count": null,
52
+ "metadata": {},
53
+ "outputs": [],
54
+ "source": [
55
+ "vector_url = \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/naip_buildings_masks.geojson\"\n",
56
+ "raster_url = (\n",
57
+ " \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/naip_train.tif\"\n",
58
+ ")"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": null,
64
+ "metadata": {},
65
+ "outputs": [],
66
+ "source": [
67
+ "gdf = geoai.read_vector(vector_url)"
68
+ ]
69
+ },
70
+ {
71
+ "cell_type": "code",
72
+ "execution_count": null,
73
+ "metadata": {},
74
+ "outputs": [],
75
+ "source": [
76
+ "gdf.head()"
77
+ ]
78
+ },
79
+ {
80
+ "cell_type": "markdown",
81
+ "metadata": {},
82
+ "source": [
83
+ "## Visualize data"
84
+ ]
85
+ },
86
+ {
87
+ "cell_type": "code",
88
+ "execution_count": null,
89
+ "metadata": {},
90
+ "outputs": [],
91
+ "source": [
92
+ "geoai.view_vector_interactive(gdf, column=\"confidence\", tiles=raster_url)"
93
+ ]
94
+ },
95
+ {
96
+ "cell_type": "markdown",
97
+ "metadata": {},
98
+ "source": [
99
+ "## Add geometric properties"
100
+ ]
101
+ },
102
+ {
103
+ "cell_type": "code",
104
+ "execution_count": null,
105
+ "metadata": {},
106
+ "outputs": [],
107
+ "source": [
108
+ "gdf_props = geoai.add_geometric_properties(gdf, area_unit=\"m2\", length_unit=\"m\")"
109
+ ]
110
+ },
111
+ {
112
+ "cell_type": "code",
113
+ "execution_count": null,
114
+ "metadata": {},
115
+ "outputs": [],
116
+ "source": [
117
+ "gdf_props.head()"
118
+ ]
119
+ },
120
+ {
121
+ "cell_type": "markdown",
122
+ "metadata": {},
123
+ "source": [
124
+ "## Visualize geometric properties"
125
+ ]
126
+ },
127
+ {
128
+ "cell_type": "code",
129
+ "execution_count": null,
130
+ "metadata": {},
131
+ "outputs": [],
132
+ "source": [
133
+ "geoai.view_vector_interactive(gdf_props, column=\"area_m2\", tiles=raster_url)"
134
+ ]
135
+ },
136
+ {
137
+ "cell_type": "code",
138
+ "execution_count": null,
139
+ "metadata": {},
140
+ "outputs": [],
141
+ "source": [
142
+ "geoai.view_vector_interactive(gdf_props, column=\"elongation\", tiles=raster_url)"
143
+ ]
144
+ },
145
+ {
146
+ "cell_type": "markdown",
147
+ "metadata": {},
148
+ "source": [
149
+ "## Filter objects based on geometric properties"
150
+ ]
151
+ },
152
+ {
153
+ "cell_type": "code",
154
+ "execution_count": null,
155
+ "metadata": {},
156
+ "outputs": [],
157
+ "source": [
158
+ "gdf_filtered = gdf_props[(gdf_props[\"area_m2\"] < 2000) & (gdf_props[\"elongation\"] < 5)]"
159
+ ]
160
+ },
161
+ {
162
+ "cell_type": "markdown",
163
+ "metadata": {},
164
+ "source": [
165
+ "## Visualize filtered objects"
166
+ ]
167
+ },
168
+ {
169
+ "cell_type": "code",
170
+ "execution_count": null,
171
+ "metadata": {},
172
+ "outputs": [],
173
+ "source": [
174
+ "geoai.view_vector_interactive(gdf_filtered, column=\"elongation\", tiles=raster_url)"
175
+ ]
176
+ }
177
+ ],
178
+ "metadata": {
179
+ "kernelspec": {
180
+ "display_name": "geo",
181
+ "language": "python",
182
+ "name": "python3"
183
+ },
184
+ "language_info": {
185
+ "codemirror_mode": {
186
+ "name": "ipython",
187
+ "version": 3
188
+ },
189
+ "file_extension": ".py",
190
+ "mimetype": "text/x-python",
191
+ "name": "python",
192
+ "nbconvert_exporter": "python",
193
+ "pygments_lexer": "ipython3",
194
+ "version": "3.12.2"
195
+ }
196
+ },
197
+ "nbformat": 4,
198
+ "nbformat_minor": 2
199
+ }
@@ -4,9 +4,9 @@
4
4
  [![image](https://static.pepy.tech/badge/geoai-py)](https://pepy.tech/project/geoai-py)
5
5
  [![image](https://img.shields.io/conda/vn/conda-forge/geoai.svg)](https://anaconda.org/conda-forge/geoai)
6
6
  [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/geoai.svg)](https://anaconda.org/conda-forge/geoai)
7
- [![Conda Recipe](https://img.shields.io/badge/recipe-geoai-green.svg)](https://github.com/conda-forge/geoai-py-feedstock)
7
+ [![Conda Recipe](https://img.shields.io/badge/recipe-geoai-green.svg)](https://github.com/giswqs/geoai-py-feedstock)
8
8
  [![image](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
- [![image](https://img.shields.io/badge/YouTube-Channel-red)](https://youtube.com/@giswqs)
9
+ [![image](https://img.shields.io/badge/YouTube-Tutorials-red)](https://bit.ly/GeoAI-Tutorials)
10
10
 
11
11
  **A powerful Python package for integrating Artificial Intelligence with geospatial data analysis and visualization**
12
12
 
@@ -40,7 +40,7 @@ GeoAI bridges the gap between AI and geospatial analysis, providing tools for pr
40
40
  - Integration with Meta's Segment Anything Model (SAM) for automatic feature extraction
41
41
  - Specialized segmentation algorithms optimized for satellite and aerial imagery
42
42
  - Streamlined workflows for segmenting buildings, roads, vegetation, and water bodies
43
- - Export capabilities to standard geospatial formats (GeoJSON, Shapefile, GeoPackage)
43
+ - Export capabilities to standard geospatial formats (GeoJSON, Shapefile, GeoPackage, GeoParquet)
44
44
 
45
45
  ### 🔍 Image Classification
46
46
 
@@ -85,6 +85,12 @@ Comprehensive documentation is available at [https://geoai.gishub.org](https://g
85
85
  - Explanation of algorithms and models
86
86
  - Best practices for geospatial AI
87
87
 
88
+ ## 📺 Video Tutorials
89
+
90
+ Check out our [YouTube channel](https://bit.ly/GeoAI-Tutorials) for video tutorials on using GeoAI for geospatial data analysis and visualization.
91
+
92
+ [![cover](https://github.com/user-attachments/assets/3cde9547-ab62-4d70-b23a-3e5ed27c7407)](https://bit.ly/GeoAI-Tutorials)
93
+
88
94
  ## 🤝 Contributing
89
95
 
90
96
  We welcome contributions of all kinds! See our [contributing guide](https://geoai.gishub.org/contributing) for ways to get started.
@@ -2,7 +2,7 @@
2
2
 
3
3
  __author__ = """Qiusheng Wu"""
4
4
  __email__ = "giswqs@gmail.com"
5
- __version__ = "0.3.2"
5
+ __version__ = "0.3.3"
6
6
 
7
7
 
8
8
  import os
@@ -13,7 +13,7 @@ import rasterio
13
13
  from rasterio.windows import Window
14
14
  from rasterio.features import shapes
15
15
  from huggingface_hub import hf_hub_download
16
- from .preprocess import get_raster_stats
16
+ from .utils import get_raster_stats
17
17
 
18
18
  try:
19
19
  from torchgeo.datasets import NonGeoDataset
@@ -196,7 +196,8 @@ class ObjectDetector:
196
196
  self.overlap = 0.25 # Default overlap between tiles
197
197
  self.confidence_threshold = 0.5 # Default confidence threshold
198
198
  self.nms_iou_threshold = 0.5 # IoU threshold for non-maximum suppression
199
- self.small_object_area = 100 # Minimum area in pixels to keep an object
199
+ self.min_object_area = 100 # Minimum area in pixels to keep an object
200
+ self.max_object_area = None # Maximum area in pixels to keep an object
200
201
  self.mask_threshold = 0.5 # Threshold for mask binarization
201
202
  self.simplify_tolerance = 1.0 # Tolerance for polygon simplification
202
203
 
@@ -326,7 +327,8 @@ class ObjectDetector:
326
327
  **kwargs: Optional parameters:
327
328
  simplify_tolerance: Tolerance for polygon simplification
328
329
  mask_threshold: Threshold for mask binarization
329
- small_object_area: Minimum area in pixels to keep an object
330
+ min_object_area: Minimum area in pixels to keep an object
331
+ max_object_area: Maximum area in pixels to keep an object
330
332
 
331
333
  Returns:
332
334
  List of polygons as lists of (x, y) coordinates
@@ -335,7 +337,8 @@ class ObjectDetector:
335
337
  # Get parameters from kwargs or use instance defaults
336
338
  simplify_tolerance = kwargs.get("simplify_tolerance", self.simplify_tolerance)
337
339
  mask_threshold = kwargs.get("mask_threshold", self.mask_threshold)
338
- small_object_area = kwargs.get("small_object_area", self.small_object_area)
340
+ min_object_area = kwargs.get("min_object_area", self.min_object_area)
341
+ max_object_area = kwargs.get("max_object_area", self.max_object_area)
339
342
 
340
343
  # Ensure binary mask
341
344
  mask = (mask > mask_threshold).astype(np.uint8)
@@ -351,7 +354,14 @@ class ObjectDetector:
351
354
  polygons = []
352
355
  for contour in contours:
353
356
  # Filter out too small contours
354
- if contour.shape[0] < 3 or cv2.contourArea(contour) < small_object_area:
357
+ if contour.shape[0] < 3 or cv2.contourArea(contour) < min_object_area:
358
+ continue
359
+
360
+ # Filter out too large contours
361
+ if (
362
+ max_object_area is not None
363
+ and cv2.contourArea(contour) > max_object_area
364
+ ):
355
365
  continue
356
366
 
357
367
  # Simplify contour if it has many points
@@ -491,7 +501,8 @@ class ObjectDetector:
491
501
  output_path=None,
492
502
  simplify_tolerance=None,
493
503
  mask_threshold=None,
494
- small_object_area=None,
504
+ min_object_area=None,
505
+ max_object_area=None,
495
506
  nms_iou_threshold=None,
496
507
  regularize=True,
497
508
  angle_threshold=15,
@@ -505,7 +516,8 @@ class ObjectDetector:
505
516
  output_path: Path to save the output GeoJSON (default: mask_path with .geojson extension)
506
517
  simplify_tolerance: Tolerance for polygon simplification (default: self.simplify_tolerance)
507
518
  mask_threshold: Threshold for mask binarization (default: self.mask_threshold)
508
- small_object_area: Minimum area in pixels to keep an object (default: self.small_object_area)
519
+ min_object_area: Minimum area in pixels to keep an object (default: self.min_object_area)
520
+ max_object_area: Minimum area in pixels to keep an object (default: self.max_object_area)
509
521
  nms_iou_threshold: IoU threshold for non-maximum suppression (default: self.nms_iou_threshold)
510
522
  regularize: Whether to regularize objects to right angles (default: True)
511
523
  angle_threshold: Maximum deviation from 90 degrees for regularization (default: 15)
@@ -523,10 +535,11 @@ class ObjectDetector:
523
535
  mask_threshold = (
524
536
  mask_threshold if mask_threshold is not None else self.mask_threshold
525
537
  )
526
- small_object_area = (
527
- small_object_area
528
- if small_object_area is not None
529
- else self.small_object_area
538
+ min_object_area = (
539
+ min_object_area if min_object_area is not None else self.min_object_area
540
+ )
541
+ max_object_area = (
542
+ max_object_area if max_object_area is not None else self.max_object_area
530
543
  )
531
544
  nms_iou_threshold = (
532
545
  nms_iou_threshold
@@ -540,7 +553,8 @@ class ObjectDetector:
540
553
 
541
554
  print(f"Converting mask to GeoJSON with parameters:")
542
555
  print(f"- Mask threshold: {mask_threshold}")
543
- print(f"- Min object area: {small_object_area}")
556
+ print(f"- Min object area: {min_object_area}")
557
+ print(f"- Max object area: {max_object_area}")
544
558
  print(f"- Simplify tolerance: {simplify_tolerance}")
545
559
  print(f"- NMS IoU threshold: {nms_iou_threshold}")
546
560
  print(f"- Regularize objects: {regularize}")
@@ -586,7 +600,11 @@ class ObjectDetector:
586
600
  area = stats[i, cv2.CC_STAT_AREA]
587
601
 
588
602
  # Skip if too small
589
- if area < small_object_area:
603
+ if area < min_object_area:
604
+ continue
605
+
606
+ # Skip if too large
607
+ if max_object_area is not None and area > max_object_area:
590
608
  continue
591
609
 
592
610
  # Create a mask for this object
@@ -710,7 +728,7 @@ class ObjectDetector:
710
728
  chip_size: Size of image chips for processing (height, width)
711
729
  nms_iou_threshold: IoU threshold for non-maximum suppression (0.0-1.0)
712
730
  mask_threshold: Threshold for mask binarization (0.0-1.0)
713
- small_object_area: Minimum area in pixels to keep an object
731
+ min_object_area: Minimum area in pixels to keep an object
714
732
  simplify_tolerance: Tolerance for polygon simplification
715
733
 
716
734
  Returns:
@@ -724,7 +742,8 @@ class ObjectDetector:
724
742
  chip_size = kwargs.get("chip_size", self.chip_size)
725
743
  nms_iou_threshold = kwargs.get("nms_iou_threshold", self.nms_iou_threshold)
726
744
  mask_threshold = kwargs.get("mask_threshold", self.mask_threshold)
727
- small_object_area = kwargs.get("small_object_area", self.small_object_area)
745
+ min_object_area = kwargs.get("min_object_area", self.min_object_area)
746
+ max_object_area = kwargs.get("max_object_area", self.max_object_area)
728
747
  simplify_tolerance = kwargs.get("simplify_tolerance", self.simplify_tolerance)
729
748
 
730
749
  # Print parameters being used
@@ -734,7 +753,8 @@ class ObjectDetector:
734
753
  print(f"- Chip size: {chip_size}")
735
754
  print(f"- NMS IoU threshold: {nms_iou_threshold}")
736
755
  print(f"- Mask threshold: {mask_threshold}")
737
- print(f"- Min object area: {small_object_area}")
756
+ print(f"- Min object area: {min_object_area}")
757
+ print(f"- Max object area: {max_object_area}")
738
758
  print(f"- Simplify tolerance: {simplify_tolerance}")
739
759
  print(f"- Filter edge objects: {filter_edges}")
740
760
  if filter_edges:
@@ -865,7 +885,8 @@ class ObjectDetector:
865
885
  binary_mask,
866
886
  simplify_tolerance=simplify_tolerance,
867
887
  mask_threshold=mask_threshold,
868
- small_object_area=small_object_area,
888
+ min_object_area=min_object_area,
889
+ max_object_area=max_object_area,
869
890
  )
870
891
 
871
892
  # Skip if no valid polygons
@@ -1,5 +1,4 @@
1
1
  """Main module."""
2
2
 
3
3
  from .utils import *
4
- from .preprocess import *
5
4
  from .extract import *
@@ -288,7 +288,11 @@ def get_vector_info(vector_path):
288
288
  dict: Dictionary containing the basic information about the vector dataset
289
289
  """
290
290
  # Open the vector dataset
291
- gdf = gpd.read_file(vector_path)
291
+ gdf = (
292
+ gpd.read_parquet(vector_path)
293
+ if vector_path.endswith(".parquet")
294
+ else gpd.read_file(vector_path)
295
+ )
292
296
 
293
297
  # Get basic metadata
294
298
  info = {
@@ -359,7 +363,11 @@ def print_vector_info(vector_path, show_preview=True, figsize=(10, 8)):
359
363
 
360
364
  # Show a preview if requested
361
365
  if show_preview:
362
- gdf = gpd.read_file(vector_path)
366
+ gdf = (
367
+ gpd.read_parquet(vector_path)
368
+ if vector_path.endswith(".parquet")
369
+ else gpd.read_file(vector_path)
370
+ )
363
371
  fig, ax = plt.subplots(figsize=figsize)
364
372
  gdf.plot(ax=ax, cmap="viridis")
365
373
  ax.set_title(f"Preview: {vector_path}")
@@ -2813,7 +2821,8 @@ def masks_to_vector(
2813
2821
  output_path=None,
2814
2822
  simplify_tolerance=1.0,
2815
2823
  mask_threshold=0.5,
2816
- min_area=100,
2824
+ min_object_area=100,
2825
+ max_object_area=None,
2817
2826
  nms_iou_threshold=0.5,
2818
2827
  ):
2819
2828
  """
@@ -2824,7 +2833,8 @@ def masks_to_vector(
2824
2833
  output_path: Path to save the output GeoJSON (default: mask_path with .geojson extension)
2825
2834
  simplify_tolerance: Tolerance for polygon simplification (default: self.simplify_tolerance)
2826
2835
  mask_threshold: Threshold for mask binarization (default: self.mask_threshold)
2827
- min_area: Minimum area in pixels to keep a building (default: self.small_building_area)
2836
+ min_object_area: Minimum area in pixels to keep a building (default: self.min_object_area)
2837
+ max_object_area: Maximum area in pixels to keep a building (default: self.max_object_area)
2828
2838
  nms_iou_threshold: IoU threshold for non-maximum suppression (default: self.nms_iou_threshold)
2829
2839
 
2830
2840
  Returns:
@@ -2836,7 +2846,7 @@ def masks_to_vector(
2836
2846
 
2837
2847
  print(f"Converting mask to GeoJSON with parameters:")
2838
2848
  print(f"- Mask threshold: {mask_threshold}")
2839
- print(f"- Min building area: {min_area}")
2849
+ print(f"- Min building area: {min_object_area}")
2840
2850
  print(f"- Simplify tolerance: {simplify_tolerance}")
2841
2851
  print(f"- NMS IoU threshold: {nms_iou_threshold}")
2842
2852
 
@@ -2876,7 +2886,11 @@ def masks_to_vector(
2876
2886
  area = stats[i, cv2.CC_STAT_AREA]
2877
2887
 
2878
2888
  # Skip if too small
2879
- if area < min_area:
2889
+ if area < min_object_area:
2890
+ continue
2891
+
2892
+ # Skip if too large
2893
+ if max_object_area is not None and area > max_object_area:
2880
2894
  continue
2881
2895
 
2882
2896
  # Create a mask for this building