geoai-py 0.18.0__py2.py3-none-any.whl → 0.18.2__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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  __author__ = """Qiusheng Wu"""
4
4
  __email__ = "giswqs@gmail.com"
5
- __version__ = "0.18.0"
5
+ __version__ = "0.18.2"
6
6
 
7
7
 
8
8
  import os
geoai/train.py CHANGED
@@ -2015,17 +2015,39 @@ def get_semantic_transform(train: bool) -> Any:
2015
2015
  """
2016
2016
  Get transforms for semantic segmentation data augmentation.
2017
2017
 
2018
+ This function returns default data augmentation transforms for training
2019
+ semantic segmentation models. The transforms include geometric transformations
2020
+ (horizontal/vertical flips, rotations) and photometric adjustments (brightness,
2021
+ contrast) that are commonly used in remote sensing tasks.
2022
+
2018
2023
  Args:
2019
2024
  train (bool): Whether to include training-specific transforms.
2025
+ If True, applies augmentations (flips, rotations, brightness/contrast adjustments).
2026
+ If False, only converts to tensor (for validation).
2020
2027
 
2021
2028
  Returns:
2022
2029
  SemanticTransforms: Composed transforms.
2030
+
2031
+ Example:
2032
+ >>> train_transform = get_semantic_transform(train=True)
2033
+ >>> val_transform = get_semantic_transform(train=False)
2023
2034
  """
2024
2035
  transforms = []
2025
2036
  transforms.append(SemanticToTensor())
2026
2037
 
2027
2038
  if train:
2039
+ # Geometric transforms - preserve spatial structure
2028
2040
  transforms.append(SemanticRandomHorizontalFlip(0.5))
2041
+ transforms.append(SemanticRandomVerticalFlip(0.5))
2042
+ transforms.append(SemanticRandomRotation90(0.5))
2043
+
2044
+ # Photometric transforms - improve model robustness
2045
+ transforms.append(
2046
+ SemanticBrightnessAdjustment(brightness_range=(0.8, 1.2), prob=0.5)
2047
+ )
2048
+ transforms.append(
2049
+ SemanticContrastAdjustment(contrast_range=(0.8, 1.2), prob=0.5)
2050
+ )
2029
2051
 
2030
2052
  return SemanticTransforms(transforms)
2031
2053
 
geoai/utils.py CHANGED
@@ -64,7 +64,7 @@ def view_raster(
64
64
  client_args: Optional[Dict] = {"cors_all": False},
65
65
  basemap: Optional[str] = "OpenStreetMap",
66
66
  basemap_args: Optional[Dict] = None,
67
- backend: Optional[str] = "ipyleaflet",
67
+ backend: Optional[str] = "folium",
68
68
  **kwargs: Any,
69
69
  ) -> Any:
70
70
  """
@@ -87,7 +87,7 @@ def view_raster(
87
87
  client_args (Optional[Dict], optional): Additional arguments for the client. Defaults to {"cors_all": False}.
88
88
  basemap (Optional[str], optional): The basemap to use. Defaults to "OpenStreetMap".
89
89
  basemap_args (Optional[Dict], optional): Additional arguments for the basemap. Defaults to None.
90
- backend (Optional[str], optional): The backend to use. Defaults to "ipyleaflet".
90
+ backend (Optional[str], optional): The backend to use. Defaults to "folium".
91
91
  **kwargs (Any): Additional keyword arguments.
92
92
 
93
93
  Returns:
@@ -123,26 +123,39 @@ def view_raster(
123
123
  if isinstance(source, dict):
124
124
  source = dict_to_image(source)
125
125
 
126
- if (
127
- isinstance(source, str)
128
- and source.lower().endswith(".tif")
129
- and source.startswith("http")
130
- ):
131
- if indexes is not None:
132
- kwargs["bidx"] = indexes
133
- if colormap is not None:
134
- kwargs["colormap_name"] = colormap
135
- if attribution is None:
136
- attribution = "TiTiler"
137
-
138
- m.add_cog_layer(
139
- source,
140
- name=layer_name,
141
- opacity=opacity,
142
- attribution=attribution,
143
- zoom_to_layer=zoom_to_layer,
144
- **kwargs,
145
- )
126
+ if isinstance(source, str) and source.startswith("http"):
127
+ if backend == "folium":
128
+
129
+ m.add_geotiff(
130
+ url=source,
131
+ name=layer_name,
132
+ opacity=opacity,
133
+ attribution=attribution,
134
+ fit_bounds=zoom_to_layer,
135
+ palette=colormap,
136
+ vmin=vmin,
137
+ vmax=vmax,
138
+ **kwargs,
139
+ )
140
+ m.add_layer_control()
141
+ m.add_opacity_control()
142
+
143
+ else:
144
+ if indexes is not None:
145
+ kwargs["bidx"] = indexes
146
+ if colormap is not None:
147
+ kwargs["colormap_name"] = colormap
148
+ if attribution is None:
149
+ attribution = "TiTiler"
150
+
151
+ m.add_cog_layer(
152
+ source,
153
+ name=layer_name,
154
+ opacity=opacity,
155
+ attribution=attribution,
156
+ zoom_to_layer=zoom_to_layer,
157
+ **kwargs,
158
+ )
146
159
  else:
147
160
  m.add_raster(
148
161
  source=source,
@@ -1081,8 +1094,9 @@ def view_vector(
1081
1094
 
1082
1095
  def view_vector_interactive(
1083
1096
  vector_data: Union[str, gpd.GeoDataFrame],
1084
- layer_name: str = "Vector Layer",
1097
+ layer_name: str = "Vector",
1085
1098
  tiles_args: Optional[Dict] = None,
1099
+ opacity: float = 0.7,
1086
1100
  **kwargs: Any,
1087
1101
  ) -> Any:
1088
1102
  """
@@ -1097,6 +1111,7 @@ def view_vector_interactive(
1097
1111
  layer_name (str, optional): The name of the layer. Defaults to "Vector Layer".
1098
1112
  tiles_args (dict, optional): Additional arguments for the localtileserver client.
1099
1113
  get_folium_tile_layer function. Defaults to None.
1114
+ opacity (float, optional): The opacity of the layer. Defaults to 0.7.
1100
1115
  **kwargs: Additional keyword arguments to pass to GeoDataFrame.explore() function.
1101
1116
  See https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoDataFrame.explore.html
1102
1117
 
@@ -1111,9 +1126,8 @@ def view_vector_interactive(
1111
1126
  >>> roads = gpd.read_file("roads.shp")
1112
1127
  >>> view_vector_interactive(roads, figsize=(12, 8))
1113
1128
  """
1114
- import folium
1115
- import folium.plugins as plugins
1116
- from leafmap import cog_tile
1129
+
1130
+ from leafmap.foliumap import Map
1117
1131
  from localtileserver import TileClient, get_folium_tile_layer
1118
1132
 
1119
1133
  google_tiles = {
@@ -1148,6 +1162,8 @@ def view_vector_interactive(
1148
1162
  basemap_layer_name = None
1149
1163
  raster_layer = None
1150
1164
 
1165
+ m = Map()
1166
+
1151
1167
  if "tiles" in kwargs and isinstance(kwargs["tiles"], str):
1152
1168
  if kwargs["tiles"].title() in google_tiles:
1153
1169
  basemap_layer_name = google_tiles[kwargs["tiles"].title()]["name"]
@@ -1158,14 +1174,17 @@ def view_vector_interactive(
1158
1174
  tiles_args = {}
1159
1175
  if kwargs["tiles"].lower().startswith("http"):
1160
1176
  basemap_layer_name = "Remote Raster"
1161
- kwargs["tiles"] = cog_tile(kwargs["tiles"], **tiles_args)
1162
- kwargs["attr"] = "TiTiler"
1177
+ m.add_geotiff(kwargs["tiles"], name=basemap_layer_name, **tiles_args)
1163
1178
  else:
1164
1179
  basemap_layer_name = "Local Raster"
1165
1180
  client = TileClient(kwargs["tiles"])
1166
1181
  raster_layer = get_folium_tile_layer(client, **tiles_args)
1167
- kwargs["tiles"] = raster_layer.tiles
1168
- kwargs["attr"] = "localtileserver"
1182
+ m.add_tile_layer(
1183
+ raster_layer.tiles,
1184
+ name=basemap_layer_name,
1185
+ attribution="localtileserver",
1186
+ **tiles_args,
1187
+ )
1169
1188
 
1170
1189
  if "max_zoom" not in kwargs:
1171
1190
  kwargs["max_zoom"] = 30
@@ -1180,23 +1199,18 @@ def view_vector_interactive(
1180
1199
  if not isinstance(vector_data, gpd.GeoDataFrame):
1181
1200
  raise TypeError("Input data must be a GeoDataFrame")
1182
1201
 
1183
- layer_control = kwargs.pop("layer_control", True)
1184
- fullscreen_control = kwargs.pop("fullscreen_control", True)
1185
-
1186
- m = vector_data.explore(**kwargs)
1202
+ if "column" in kwargs:
1203
+ if "legend_position" not in kwargs:
1204
+ kwargs["legend_position"] = "bottomleft"
1205
+ if "cmap" not in kwargs:
1206
+ kwargs["cmap"] = "viridis"
1207
+ m.add_data(vector_data, layer_name=layer_name, opacity=opacity, **kwargs)
1187
1208
 
1188
- # Change the layer name
1189
- for layer in m._children.values():
1190
- if isinstance(layer, folium.GeoJson):
1191
- layer.layer_name = layer_name
1192
- if isinstance(layer, folium.TileLayer) and basemap_layer_name:
1193
- layer.layer_name = basemap_layer_name
1194
-
1195
- if layer_control:
1196
- m.add_child(folium.LayerControl())
1209
+ else:
1210
+ m.add_gdf(vector_data, layer_name=layer_name, opacity=opacity, **kwargs)
1197
1211
 
1198
- if fullscreen_control:
1199
- plugins.Fullscreen().add_to(m)
1212
+ m.add_layer_control()
1213
+ m.add_opacity_control()
1200
1214
 
1201
1215
  return m
1202
1216
 
@@ -2990,6 +3004,82 @@ def batch_vector_to_raster(
2990
3004
  return output_files
2991
3005
 
2992
3006
 
3007
+ def get_default_augmentation_transforms(
3008
+ tile_size: int = 256,
3009
+ include_normalize: bool = False,
3010
+ mean: Tuple[float, float, float] = (0.485, 0.456, 0.406),
3011
+ std: Tuple[float, float, float] = (0.229, 0.224, 0.225),
3012
+ ) -> Any:
3013
+ """
3014
+ Get default data augmentation transforms for geospatial imagery using albumentations.
3015
+
3016
+ This function returns a composition of augmentation transforms commonly used
3017
+ for remote sensing and geospatial data. The transforms include geometric
3018
+ transformations (flips, rotations) and photometric adjustments (brightness,
3019
+ contrast, saturation).
3020
+
3021
+ Args:
3022
+ tile_size (int): Target size for tiles. Defaults to 256.
3023
+ include_normalize (bool): Whether to include normalization transform.
3024
+ Defaults to False. Set to True if using for training with pretrained models.
3025
+ mean (tuple): Mean values for normalization (RGB). Defaults to ImageNet values.
3026
+ std (tuple): Standard deviation for normalization (RGB). Defaults to ImageNet values.
3027
+
3028
+ Returns:
3029
+ albumentations.Compose: A composition of augmentation transforms.
3030
+
3031
+ Example:
3032
+ >>> import albumentations as A
3033
+ >>> # Get default transforms
3034
+ >>> transform = get_default_augmentation_transforms()
3035
+ >>> # Apply to image and mask
3036
+ >>> augmented = transform(image=image, mask=mask)
3037
+ >>> aug_image = augmented['image']
3038
+ >>> aug_mask = augmented['mask']
3039
+ """
3040
+ try:
3041
+ import albumentations as A
3042
+ except ImportError:
3043
+ raise ImportError(
3044
+ "albumentations is required for data augmentation. "
3045
+ "Install it with: pip install albumentations"
3046
+ )
3047
+
3048
+ transforms_list = [
3049
+ # Geometric transforms
3050
+ A.HorizontalFlip(p=0.5),
3051
+ A.VerticalFlip(p=0.5),
3052
+ A.RandomRotate90(p=0.5),
3053
+ A.ShiftScaleRotate(
3054
+ shift_limit=0.1,
3055
+ scale_limit=0.1,
3056
+ rotate_limit=45,
3057
+ border_mode=0,
3058
+ p=0.5,
3059
+ ),
3060
+ # Photometric transforms
3061
+ A.RandomBrightnessContrast(
3062
+ brightness_limit=0.2,
3063
+ contrast_limit=0.2,
3064
+ p=0.5,
3065
+ ),
3066
+ A.HueSaturationValue(
3067
+ hue_shift_limit=10,
3068
+ sat_shift_limit=20,
3069
+ val_shift_limit=10,
3070
+ p=0.3,
3071
+ ),
3072
+ A.GaussNoise(var_limit=(10.0, 50.0), p=0.2),
3073
+ A.GaussianBlur(blur_limit=(3, 5), p=0.2),
3074
+ ]
3075
+
3076
+ # Add normalization if requested
3077
+ if include_normalize:
3078
+ transforms_list.append(A.Normalize(mean=mean, std=std))
3079
+
3080
+ return A.Compose(transforms_list)
3081
+
3082
+
2993
3083
  def export_geotiff_tiles(
2994
3084
  in_raster,
2995
3085
  out_folder,
@@ -3004,6 +3094,9 @@ def export_geotiff_tiles(
3004
3094
  create_overview=False,
3005
3095
  skip_empty_tiles=False,
3006
3096
  metadata_format="PASCAL_VOC",
3097
+ apply_augmentation=False,
3098
+ augmentation_count=3,
3099
+ augmentation_transforms=None,
3007
3100
  ):
3008
3101
  """
3009
3102
  Export georeferenced GeoTIFF tiles and labels from raster and classification data.
@@ -3023,12 +3116,54 @@ def export_geotiff_tiles(
3023
3116
  create_overview (bool): Whether to create an overview image of all tiles
3024
3117
  skip_empty_tiles (bool): If True, skip tiles with no features
3025
3118
  metadata_format (str): Output metadata format (PASCAL_VOC, COCO, YOLO). Default: PASCAL_VOC
3119
+ apply_augmentation (bool): If True, generate augmented versions of each tile.
3120
+ This will create multiple variants of each tile using data augmentation techniques.
3121
+ Defaults to False.
3122
+ augmentation_count (int): Number of augmented versions to generate per tile
3123
+ (only used if apply_augmentation=True). Defaults to 3.
3124
+ augmentation_transforms (albumentations.Compose, optional): Custom augmentation transforms.
3125
+ If None and apply_augmentation=True, uses default transforms from
3126
+ get_default_augmentation_transforms(). Should be an albumentations.Compose object.
3127
+ Defaults to None.
3128
+
3129
+ Returns:
3130
+ None: Tiles and labels are saved to out_folder.
3131
+
3132
+ Example:
3133
+ >>> # Export tiles without augmentation
3134
+ >>> export_geotiff_tiles('image.tif', 'output/', 'labels.tif')
3135
+ >>>
3136
+ >>> # Export tiles with default augmentation (3 augmented versions per tile)
3137
+ >>> export_geotiff_tiles('image.tif', 'output/', 'labels.tif',
3138
+ ... apply_augmentation=True)
3139
+ >>>
3140
+ >>> # Export with custom augmentation
3141
+ >>> import albumentations as A
3142
+ >>> custom_transform = A.Compose([
3143
+ ... A.HorizontalFlip(p=0.5),
3144
+ ... A.RandomBrightnessContrast(p=0.5),
3145
+ ... ])
3146
+ >>> export_geotiff_tiles('image.tif', 'output/', 'labels.tif',
3147
+ ... apply_augmentation=True,
3148
+ ... augmentation_count=5,
3149
+ ... augmentation_transforms=custom_transform)
3026
3150
  """
3027
3151
 
3028
3152
  import logging
3029
3153
 
3030
3154
  logging.getLogger("rasterio").setLevel(logging.ERROR)
3031
3155
 
3156
+ # Initialize augmentation transforms if needed
3157
+ if apply_augmentation:
3158
+ if augmentation_transforms is None:
3159
+ augmentation_transforms = get_default_augmentation_transforms(
3160
+ tile_size=tile_size
3161
+ )
3162
+ if not quiet:
3163
+ print(
3164
+ f"Data augmentation enabled: generating {augmentation_count} augmented versions per tile"
3165
+ )
3166
+
3032
3167
  # Create output directories
3033
3168
  os.makedirs(out_folder, exist_ok=True)
3034
3169
  image_dir = os.path.join(out_folder, "images")
@@ -3360,53 +3495,134 @@ def export_geotiff_tiles(
3360
3495
  # Read image data
3361
3496
  image_data = src.read(window=window)
3362
3497
 
3363
- # Export image as GeoTIFF
3364
- image_path = os.path.join(image_dir, f"tile_{tile_index:06d}.tif")
3498
+ # Helper function to save a single tile (original or augmented)
3499
+ def save_tile(
3500
+ img_data,
3501
+ lbl_mask,
3502
+ tile_id,
3503
+ img_profile,
3504
+ window_trans,
3505
+ is_augmented=False,
3506
+ ):
3507
+ """Save a single image and label tile."""
3508
+ # Export image as GeoTIFF
3509
+ image_path = os.path.join(image_dir, f"tile_{tile_id:06d}.tif")
3365
3510
 
3366
- # Create profile for image GeoTIFF
3367
- image_profile = src.profile.copy()
3368
- image_profile.update(
3369
- {
3370
- "height": tile_size,
3371
- "width": tile_size,
3372
- "count": image_data.shape[0],
3373
- "transform": window_transform,
3374
- }
3511
+ # Update profile
3512
+ img_profile_copy = img_profile.copy()
3513
+ img_profile_copy.update(
3514
+ {
3515
+ "height": tile_size,
3516
+ "width": tile_size,
3517
+ "count": img_data.shape[0],
3518
+ "transform": window_trans,
3519
+ }
3520
+ )
3521
+
3522
+ # Save image as GeoTIFF
3523
+ try:
3524
+ with rasterio.open(image_path, "w", **img_profile_copy) as dst:
3525
+ dst.write(img_data)
3526
+ stats["total_tiles"] += 1
3527
+ except Exception as e:
3528
+ pbar.write(f"ERROR saving image GeoTIFF: {e}")
3529
+ stats["errors"] += 1
3530
+ return
3531
+
3532
+ # Export label as GeoTIFF (only if class data provided)
3533
+ if in_class_data is not None:
3534
+ # Create profile for label GeoTIFF
3535
+ label_profile = {
3536
+ "driver": "GTiff",
3537
+ "height": tile_size,
3538
+ "width": tile_size,
3539
+ "count": 1,
3540
+ "dtype": "uint8",
3541
+ "crs": src.crs,
3542
+ "transform": window_trans,
3543
+ }
3544
+
3545
+ label_path = os.path.join(label_dir, f"tile_{tile_id:06d}.tif")
3546
+ try:
3547
+ with rasterio.open(label_path, "w", **label_profile) as dst:
3548
+ dst.write(lbl_mask.astype(np.uint8), 1)
3549
+
3550
+ if not is_augmented and np.any(lbl_mask > 0):
3551
+ stats["tiles_with_features"] += 1
3552
+ stats["feature_pixels"] += np.count_nonzero(lbl_mask)
3553
+ except Exception as e:
3554
+ pbar.write(f"ERROR saving label GeoTIFF: {e}")
3555
+ stats["errors"] += 1
3556
+
3557
+ # Save original tile
3558
+ save_tile(
3559
+ image_data,
3560
+ label_mask,
3561
+ tile_index,
3562
+ src.profile,
3563
+ window_transform,
3564
+ is_augmented=False,
3375
3565
  )
3376
3566
 
3377
- # Save image as GeoTIFF
3378
- try:
3379
- with rasterio.open(image_path, "w", **image_profile) as dst:
3380
- dst.write(image_data)
3381
- stats["total_tiles"] += 1
3382
- except Exception as e:
3383
- pbar.write(f"ERROR saving image GeoTIFF: {e}")
3384
- stats["errors"] += 1
3567
+ # Generate and save augmented tiles if enabled
3568
+ if apply_augmentation:
3569
+ for aug_idx in range(augmentation_count):
3570
+ # Prepare image for augmentation (convert from CHW to HWC)
3571
+ img_for_aug = np.transpose(image_data, (1, 2, 0))
3572
+
3573
+ # Ensure uint8 data type for albumentations
3574
+ # Albumentations expects uint8 for most transforms
3575
+ if not np.issubdtype(img_for_aug.dtype, np.uint8):
3576
+ # If image is float, scale to 0-255 and convert to uint8
3577
+ if np.issubdtype(img_for_aug.dtype, np.floating):
3578
+ img_for_aug = (
3579
+ (img_for_aug * 255).clip(0, 255).astype(np.uint8)
3580
+ )
3581
+ else:
3582
+ img_for_aug = img_for_aug.astype(np.uint8)
3385
3583
 
3386
- # Export label as GeoTIFF (only if class data provided)
3387
- if in_class_data is not None:
3388
- # Create profile for label GeoTIFF
3389
- label_profile = {
3390
- "driver": "GTiff",
3391
- "height": tile_size,
3392
- "width": tile_size,
3393
- "count": 1,
3394
- "dtype": "uint8",
3395
- "crs": src.crs,
3396
- "transform": window_transform,
3397
- }
3584
+ # Apply augmentation
3585
+ try:
3586
+ if in_class_data is not None:
3587
+ # Augment both image and mask
3588
+ augmented = augmentation_transforms(
3589
+ image=img_for_aug, mask=label_mask
3590
+ )
3591
+ aug_image = augmented["image"]
3592
+ aug_mask = augmented["mask"]
3593
+ else:
3594
+ # Augment only image
3595
+ augmented = augmentation_transforms(image=img_for_aug)
3596
+ aug_image = augmented["image"]
3597
+ aug_mask = label_mask
3398
3598
 
3399
- label_path = os.path.join(label_dir, f"tile_{tile_index:06d}.tif")
3400
- try:
3401
- with rasterio.open(label_path, "w", **label_profile) as dst:
3402
- dst.write(label_mask.astype(np.uint8), 1)
3599
+ # Convert back from HWC to CHW
3600
+ aug_image = np.transpose(aug_image, (2, 0, 1))
3403
3601
 
3404
- if has_features:
3405
- stats["tiles_with_features"] += 1
3406
- stats["feature_pixels"] += np.count_nonzero(label_mask)
3407
- except Exception as e:
3408
- pbar.write(f"ERROR saving label GeoTIFF: {e}")
3409
- stats["errors"] += 1
3602
+ # Ensure correct dtype for saving
3603
+ aug_image = aug_image.astype(image_data.dtype)
3604
+
3605
+ # Generate unique tile ID for augmented version
3606
+ # Use a collision-free numbering scheme: (tile_index * (augmentation_count + 1)) + aug_idx + 1
3607
+ aug_tile_id = (
3608
+ (tile_index * (augmentation_count + 1)) + aug_idx + 1
3609
+ )
3610
+
3611
+ # Save augmented tile
3612
+ save_tile(
3613
+ aug_image,
3614
+ aug_mask,
3615
+ aug_tile_id,
3616
+ src.profile,
3617
+ window_transform,
3618
+ is_augmented=True,
3619
+ )
3620
+
3621
+ except Exception as e:
3622
+ pbar.write(
3623
+ f"ERROR applying augmentation {aug_idx} to tile {tile_index}: {e}"
3624
+ )
3625
+ stats["errors"] += 1
3410
3626
 
3411
3627
  # Create annotations for object detection if using vector class data
3412
3628
  if (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geoai-py
3
- Version: 0.18.0
3
+ Version: 0.18.2
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
@@ -24,7 +24,7 @@ Requires-Dist: ever-beta
24
24
  Requires-Dist: geopandas
25
25
  Requires-Dist: huggingface_hub
26
26
  Requires-Dist: jupyter-server-proxy
27
- Requires-Dist: leafmap
27
+ Requires-Dist: leafmap>=0.57.1
28
28
  Requires-Dist: localtileserver
29
29
  Requires-Dist: mapclassify
30
30
  Requires-Dist: maplibre
@@ -1,4 +1,4 @@
1
- geoai/__init__.py,sha256=9wW42cjIMMY_ec5s-DOO04XgQHXVre8CisL72wvJCIU,4620
1
+ geoai/__init__.py,sha256=2-Zd8r21PkzvPRpTIE45FtTyJNURGvSNOBlbr_2o9P8,4620
2
2
  geoai/change_detection.py,sha256=pdQofnPRiwoES8vMln2vHghRnpeTdsmqLir74dnqZYU,60389
3
3
  geoai/classify.py,sha256=0DcComVR6vKU4qWtH2oHVeXc7ZTcV0mFvdXRtlNmolo,35637
4
4
  geoai/detectron2.py,sha256=dOOFM9M9-6PV8q2A4-mnIPrz7yTo-MpEvDiAW34nl0w,14610
@@ -13,8 +13,8 @@ geoai/segment.py,sha256=yBGTxA-ti8lBpk7WVaBOp6yP23HkaulKJQk88acrmZ0,43788
13
13
  geoai/segmentation.py,sha256=7yEzBSKCyHW1dNssoK0rdvhxi2IXsIQIFSga817KdI4,11535
14
14
  geoai/timm_segment.py,sha256=GfvWmxT6t1S99-iZOf8PlsCkwodIUyrt0AwO_j6dCjE,38470
15
15
  geoai/timm_train.py,sha256=y_Sm9Fwe7bTsHEKdtPee5rGY7s01CbkAZKP1TwUDXlU,20551
16
- geoai/train.py,sha256=Ef-lCCQvaMWl3wvhi-IYYi9sdR4YBqMt9QkfiRAUlkQ,174762
17
- geoai/utils.py,sha256=AUdVj1tt864UFxJtsatpUmXRV9-Lw4f4tbdyjqj0c3c,360240
16
+ geoai/train.py,sha256=NtT5EDoHEQKFUcAdEy4zVkGsJU8pqzk8H9alfR90BSY,175838
17
+ geoai/utils.py,sha256=2G3PeXTiTTqF6FzG9z3NX8q5PrxMZcUoBkQFKK4BW-k,369320
18
18
  geoai/agents/__init__.py,sha256=5xtb_dGpI26nPFcAm8Dj7O4bLskqr1xTw2BRQqbgH4w,285
19
19
  geoai/agents/catalog_models.py,sha256=19E-PiE7FvpGEiOi4gDMKPf257FOhLseuVGWJbOjrDs,2089
20
20
  geoai/agents/catalog_tools.py,sha256=psVw7-di65hhnJUFqWXFoOkbGaG2_sHrQhA5vdXp3x4,33597
@@ -25,9 +25,9 @@ geoai/agents/stac_tools.py,sha256=ILUg2xFRXVZ9WHOfPeJBvPSFT7lRsPLnGMZhnpDZ1co,16
25
25
  geoai/tools/__init__.py,sha256=McC49tQjxrTha1TS69IeM3rRvqVQP3H1NdAZPZPpKEI,1683
26
26
  geoai/tools/cloudmask.py,sha256=qzvqVa8FAEgd8mePXBaV5Ptx4fHhwfS1BsYL0JAZBjM,14500
27
27
  geoai/tools/multiclean.py,sha256=TVwmWgeQyGIyUuCe10b6pGCtgIl8TkZmcgVXPimn9uM,11949
28
- geoai_py-0.18.0.dist-info/licenses/LICENSE,sha256=TlBm8mRusRVB9yF2NTg-STcb71v69-XZaKaPdshqP2I,1074
29
- geoai_py-0.18.0.dist-info/METADATA,sha256=iqGhGU99OgqXBXfMF5r4GfyrByGQFFzx3PHBOAxxYG0,11255
30
- geoai_py-0.18.0.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
31
- geoai_py-0.18.0.dist-info/entry_points.txt,sha256=uGp3Az3HURIsRHP9v-ys0hIbUuBBNUfXv6VbYHIXeg4,41
32
- geoai_py-0.18.0.dist-info/top_level.txt,sha256=1YkCUWu-ii-0qIex7kbwAvfei-gos9ycyDyUCJPNWHY,6
33
- geoai_py-0.18.0.dist-info/RECORD,,
28
+ geoai_py-0.18.2.dist-info/licenses/LICENSE,sha256=TlBm8mRusRVB9yF2NTg-STcb71v69-XZaKaPdshqP2I,1074
29
+ geoai_py-0.18.2.dist-info/METADATA,sha256=FwfNDx3eGYkSzZB5xz2x_-g8SZAy5iu4Wdzl1KcBRGw,11263
30
+ geoai_py-0.18.2.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
31
+ geoai_py-0.18.2.dist-info/entry_points.txt,sha256=uGp3Az3HURIsRHP9v-ys0hIbUuBBNUfXv6VbYHIXeg4,41
32
+ geoai_py-0.18.2.dist-info/top_level.txt,sha256=1YkCUWu-ii-0qIex7kbwAvfei-gos9ycyDyUCJPNWHY,6
33
+ geoai_py-0.18.2.dist-info/RECORD,,