geoai-py 0.3.6__py2.py3-none-any.whl → 0.4.1__py2.py3-none-any.whl
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/__init__.py +76 -14
- geoai/download.py +9 -8
- geoai/extract.py +65 -24
- geoai/geoai.py +3 -1
- geoai/hf.py +447 -0
- geoai/segment.py +4 -3
- geoai/segmentation.py +8 -7
- geoai/train.py +1039 -0
- geoai/utils.py +32 -28
- {geoai_py-0.3.6.dist-info → geoai_py-0.4.1.dist-info}/METADATA +3 -8
- geoai_py-0.4.1.dist-info/RECORD +15 -0
- geoai_py-0.3.6.dist-info/RECORD +0 -13
- {geoai_py-0.3.6.dist-info → geoai_py-0.4.1.dist-info}/LICENSE +0 -0
- {geoai_py-0.3.6.dist-info → geoai_py-0.4.1.dist-info}/WHEEL +0 -0
- {geoai_py-0.3.6.dist-info → geoai_py-0.4.1.dist-info}/entry_points.txt +0 -0
- {geoai_py-0.3.6.dist-info → geoai_py-0.4.1.dist-info}/top_level.txt +0 -0
geoai/utils.py
CHANGED
|
@@ -28,25 +28,11 @@ from rasterio import features
|
|
|
28
28
|
from rasterio.plot import show
|
|
29
29
|
from rasterio.windows import Window
|
|
30
30
|
from shapely.affinity import rotate
|
|
31
|
-
from shapely.geometry import
|
|
32
|
-
MultiPolygon,
|
|
33
|
-
Polygon,
|
|
34
|
-
box,
|
|
35
|
-
mapping,
|
|
36
|
-
shape,
|
|
37
|
-
)
|
|
31
|
+
from shapely.geometry import MultiPolygon, Polygon, box, mapping, shape
|
|
38
32
|
from torchvision.transforms import RandomRotation
|
|
39
33
|
from tqdm import tqdm
|
|
40
34
|
|
|
41
35
|
|
|
42
|
-
try:
|
|
43
|
-
from torchgeo.datasets import RasterDataset, unbind_samples
|
|
44
|
-
except ImportError as e:
|
|
45
|
-
raise ImportError(
|
|
46
|
-
"Your torchgeo version is too old. Please upgrade to the latest version using 'pip install -U torchgeo'."
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
|
|
50
36
|
def view_raster(
|
|
51
37
|
source: str,
|
|
52
38
|
indexes: Optional[int] = None,
|
|
@@ -60,7 +46,7 @@ def view_raster(
|
|
|
60
46
|
zoom_to_layer: Optional[bool] = True,
|
|
61
47
|
visible: Optional[bool] = True,
|
|
62
48
|
opacity: Optional[float] = 1.0,
|
|
63
|
-
array_args: Optional[Dict] =
|
|
49
|
+
array_args: Optional[Dict] = None,
|
|
64
50
|
client_args: Optional[Dict] = {"cors_all": False},
|
|
65
51
|
basemap: Optional[str] = "OpenStreetMap",
|
|
66
52
|
basemap_args: Optional[Dict] = None,
|
|
@@ -101,6 +87,9 @@ def view_raster(
|
|
|
101
87
|
if basemap_args is None:
|
|
102
88
|
basemap_args = {}
|
|
103
89
|
|
|
90
|
+
if array_args is None:
|
|
91
|
+
array_args = {}
|
|
92
|
+
|
|
104
93
|
m = leafmap.Map()
|
|
105
94
|
|
|
106
95
|
if isinstance(basemap, str):
|
|
@@ -284,6 +273,14 @@ def plot_batch(
|
|
|
284
273
|
Returns:
|
|
285
274
|
None
|
|
286
275
|
"""
|
|
276
|
+
|
|
277
|
+
try:
|
|
278
|
+
from torchgeo.datasets import unbind_samples
|
|
279
|
+
except ImportError as e:
|
|
280
|
+
raise ImportError(
|
|
281
|
+
"Your torchgeo version is too old. Please upgrade to the latest version using 'pip install -U torchgeo'."
|
|
282
|
+
)
|
|
283
|
+
|
|
287
284
|
# Get the samples and the number of items in the batch
|
|
288
285
|
samples = unbind_samples(batch.copy())
|
|
289
286
|
|
|
@@ -323,9 +320,7 @@ def plot_batch(
|
|
|
323
320
|
)
|
|
324
321
|
|
|
325
322
|
|
|
326
|
-
def calc_stats(
|
|
327
|
-
dataset: RasterDataset, divide_by: float = 1.0
|
|
328
|
-
) -> Tuple[np.ndarray, np.ndarray]:
|
|
323
|
+
def calc_stats(dataset, divide_by: float = 1.0) -> Tuple[np.ndarray, np.ndarray]:
|
|
329
324
|
"""
|
|
330
325
|
Calculate the statistics (mean and std) for the entire dataset.
|
|
331
326
|
|
|
@@ -700,8 +695,8 @@ def view_vector_interactive(
|
|
|
700
695
|
"""
|
|
701
696
|
import folium
|
|
702
697
|
import folium.plugins as plugins
|
|
703
|
-
from localtileserver import get_folium_tile_layer, TileClient
|
|
704
698
|
from leafmap import cog_tile
|
|
699
|
+
from localtileserver import TileClient, get_folium_tile_layer
|
|
705
700
|
|
|
706
701
|
google_tiles = {
|
|
707
702
|
"Roadmap": {
|
|
@@ -803,9 +798,9 @@ def regularization(
|
|
|
803
798
|
Returns:
|
|
804
799
|
GeoDataFrame or list of shapely Polygons with regularized building footprints
|
|
805
800
|
"""
|
|
806
|
-
from shapely.geometry import Polygon, shape
|
|
807
|
-
from shapely.affinity import rotate, translate
|
|
808
801
|
from shapely import wkt
|
|
802
|
+
from shapely.affinity import rotate, translate
|
|
803
|
+
from shapely.geometry import Polygon, shape
|
|
809
804
|
|
|
810
805
|
regularized_buildings = []
|
|
811
806
|
|
|
@@ -924,8 +919,8 @@ def hybrid_regularization(building_polygons):
|
|
|
924
919
|
Returns:
|
|
925
920
|
GeoDataFrame or list of shapely Polygons with regularized building footprints
|
|
926
921
|
"""
|
|
927
|
-
from shapely.geometry import Polygon
|
|
928
922
|
from shapely.affinity import rotate
|
|
923
|
+
from shapely.geometry import Polygon
|
|
929
924
|
|
|
930
925
|
# Use minimum_rotated_rectangle instead of oriented_envelope
|
|
931
926
|
try:
|
|
@@ -1039,8 +1034,8 @@ def adaptive_regularization(
|
|
|
1039
1034
|
Returns:
|
|
1040
1035
|
GeoDataFrame or list of shapely Polygons with regularized building footprints
|
|
1041
1036
|
"""
|
|
1042
|
-
from shapely.geometry import Polygon
|
|
1043
1037
|
from shapely.affinity import rotate
|
|
1038
|
+
from shapely.geometry import Polygon
|
|
1044
1039
|
|
|
1045
1040
|
# Analyze the overall dataset to set appropriate parameters
|
|
1046
1041
|
if is_gdf := isinstance(building_polygons, gpd.GeoDataFrame):
|
|
@@ -2594,6 +2589,8 @@ def export_geotiff_tiles(
|
|
|
2594
2589
|
print(f"\nRaster info for {in_raster}:")
|
|
2595
2590
|
print(f" CRS: {src.crs}")
|
|
2596
2591
|
print(f" Dimensions: {src.width} x {src.height}")
|
|
2592
|
+
print(f" Resolution: {src.res}")
|
|
2593
|
+
print(f" Bands: {src.count}")
|
|
2597
2594
|
print(f" Bounds: {src.bounds}")
|
|
2598
2595
|
|
|
2599
2596
|
# Calculate number of tiles
|
|
@@ -4275,9 +4272,10 @@ def read_vector(source, layer=None, **kwargs):
|
|
|
4275
4272
|
>>> gdf = read_vector("path/to/data.gpkg", layer="layer_name")
|
|
4276
4273
|
"""
|
|
4277
4274
|
|
|
4278
|
-
import fiona
|
|
4279
4275
|
import urllib.parse
|
|
4280
4276
|
|
|
4277
|
+
import fiona
|
|
4278
|
+
|
|
4281
4279
|
# Determine if source is a URL or local file
|
|
4282
4280
|
parsed_url = urllib.parse.urlparse(source)
|
|
4283
4281
|
is_url = parsed_url.scheme in ["http", "https"]
|
|
@@ -4351,6 +4349,7 @@ def read_raster(source, band=None, masked=True, **kwargs):
|
|
|
4351
4349
|
>>> raster = read_raster("path/to/data.tif", masked=False)
|
|
4352
4350
|
"""
|
|
4353
4351
|
import urllib.parse
|
|
4352
|
+
|
|
4354
4353
|
from rasterio.errors import RasterioIOError
|
|
4355
4354
|
|
|
4356
4355
|
# Determine if source is a URL or local file
|
|
@@ -4445,8 +4444,8 @@ def region_groups(
|
|
|
4445
4444
|
Returns:
|
|
4446
4445
|
Union[Tuple[np.ndarray, pd.DataFrame], Tuple[xr.DataArray, pd.DataFrame]]: Labeled image and properties DataFrame.
|
|
4447
4446
|
"""
|
|
4448
|
-
from skimage import measure
|
|
4449
4447
|
import scipy.ndimage as ndi
|
|
4448
|
+
from skimage import measure
|
|
4450
4449
|
|
|
4451
4450
|
if isinstance(image, str):
|
|
4452
4451
|
ds = rxr.open_rasterio(image)
|
|
@@ -5670,11 +5669,14 @@ def orthogonalize(
|
|
|
5670
5669
|
crs = src.crs
|
|
5671
5670
|
|
|
5672
5671
|
# Extract shapes from the raster mask
|
|
5673
|
-
shapes = features.shapes(mask, transform=transform)
|
|
5672
|
+
shapes = list(features.shapes(mask, transform=transform))
|
|
5673
|
+
|
|
5674
|
+
# Initialize progress bar
|
|
5675
|
+
print(f"Processing {len(shapes)} features...")
|
|
5674
5676
|
|
|
5675
5677
|
# Convert shapes to GeoJSON features
|
|
5676
5678
|
features_list = []
|
|
5677
|
-
for shape, value in shapes:
|
|
5679
|
+
for shape, value in tqdm(shapes, desc="Converting features", unit="shape"):
|
|
5678
5680
|
if value > 0: # Only process non-zero values (actual objects)
|
|
5679
5681
|
# Convert GeoJSON geometry to Shapely polygon
|
|
5680
5682
|
polygon = Polygon(shape["coordinates"][0])
|
|
@@ -5814,6 +5816,8 @@ def orthogonalize(
|
|
|
5814
5816
|
|
|
5815
5817
|
# Save to file if output_path is provided
|
|
5816
5818
|
if output_path:
|
|
5819
|
+
print(f"Saving to {output_path}...")
|
|
5817
5820
|
gdf.to_file(output_path)
|
|
5821
|
+
print("Done!")
|
|
5818
5822
|
|
|
5819
5823
|
return gdf
|
|
@@ -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,15 @@
|
|
|
1
|
+
geoai/__init__.py,sha256=lZ5LYzlwjX-TuvVtvuk0TC0le80P83lfUUOXBY0MPoU,3592
|
|
2
|
+
geoai/download.py,sha256=eqMecJqvqyrIVFViNA7pW8a5EIhqYJzRILmxQoFHG2k,13095
|
|
3
|
+
geoai/extract.py,sha256=CCXjUcGC4ZOKOKKjvElp8VFmTz46b0ATvGitbOPgTwE,95506
|
|
4
|
+
geoai/geoai.py,sha256=L1jkozDcjqJXvqT6i8oW04Ix9x4cc2-LNYi9_564ABQ,163
|
|
5
|
+
geoai/hf.py,sha256=mLKGxEAS5eHkxZLwuLpYc1o7e3-7QIXdBv-QUY-RkFk,17072
|
|
6
|
+
geoai/segment.py,sha256=g3YW17ftr--CKq6VB32TJEPY8owGQ7uQ0sg_tUT2ooE,13681
|
|
7
|
+
geoai/segmentation.py,sha256=AtPzCvguHAEeuyXafa4bzMFATvltEYcah1B8ZMfkM_s,11373
|
|
8
|
+
geoai/train.py,sha256=VaeFzIkVUNTdre8ImgUNhmbpA42qijSXaajLpmBF_Ic,36248
|
|
9
|
+
geoai/utils.py,sha256=oBNhk73_Owv-pmaRyBKkq0HinnqnMgP3U5CUAQx6ln0,223700
|
|
10
|
+
geoai_py-0.4.1.dist-info/LICENSE,sha256=vN2L5U7cZ6ZkOHFmc8WiGlsogWsZc5dllMeNxnKVOZg,1070
|
|
11
|
+
geoai_py-0.4.1.dist-info/METADATA,sha256=0JZwrVh1EtR3mJIu8cumnafbCnElW70iBa77hSDwXHk,6078
|
|
12
|
+
geoai_py-0.4.1.dist-info/WHEEL,sha256=SrDKpSbFN1G94qcmBqS9nyHcDMp9cUS9OC06hC0G3G0,109
|
|
13
|
+
geoai_py-0.4.1.dist-info/entry_points.txt,sha256=uGp3Az3HURIsRHP9v-ys0hIbUuBBNUfXv6VbYHIXeg4,41
|
|
14
|
+
geoai_py-0.4.1.dist-info/top_level.txt,sha256=1YkCUWu-ii-0qIex7kbwAvfei-gos9ycyDyUCJPNWHY,6
|
|
15
|
+
geoai_py-0.4.1.dist-info/RECORD,,
|
geoai_py-0.3.6.dist-info/RECORD
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
geoai/__init__.py,sha256=vsoVgC5QbrVHI4xAGVZLh7C1RxBLKFdGk8KubSwKzTE,923
|
|
2
|
-
geoai/download.py,sha256=4GiDmLrp2wKslgfm507WeZrwOdYcMekgQXxWGbl5cBw,13094
|
|
3
|
-
geoai/extract.py,sha256=v_4i_pSQYrdpNZZsGvVaa6Lo0AC7bHUaNp5bs_O4kS4,94255
|
|
4
|
-
geoai/geoai.py,sha256=di-lh7704BpwltR5cxz09AtCx2EaNkvtUJxRakkYPpc,87
|
|
5
|
-
geoai/segment.py,sha256=ULe0Xq2RnA7p6d8vKm0rYqHQW6G_3dOxpd_1W0x9UOU,13680
|
|
6
|
-
geoai/segmentation.py,sha256=Vcymnhwl_xikt4v9x8CYJq_vId9R1gB7-YzLfwg-F9M,11372
|
|
7
|
-
geoai/utils.py,sha256=DKHLLLus-R12pJCFknPvktXbju8nC8SSYcsbDjykovg,223372
|
|
8
|
-
geoai_py-0.3.6.dist-info/LICENSE,sha256=vN2L5U7cZ6ZkOHFmc8WiGlsogWsZc5dllMeNxnKVOZg,1070
|
|
9
|
-
geoai_py-0.3.6.dist-info/METADATA,sha256=wzNDh3GiOtZVzA4QDhuUWc3KTtNVqwvc4rDQSgyfeFc,6297
|
|
10
|
-
geoai_py-0.3.6.dist-info/WHEEL,sha256=SrDKpSbFN1G94qcmBqS9nyHcDMp9cUS9OC06hC0G3G0,109
|
|
11
|
-
geoai_py-0.3.6.dist-info/entry_points.txt,sha256=uGp3Az3HURIsRHP9v-ys0hIbUuBBNUfXv6VbYHIXeg4,41
|
|
12
|
-
geoai_py-0.3.6.dist-info/top_level.txt,sha256=1YkCUWu-ii-0qIex7kbwAvfei-gos9ycyDyUCJPNWHY,6
|
|
13
|
-
geoai_py-0.3.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|