geoai-py 0.4.2__py2.py3-none-any.whl → 0.5.0__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 +6 -1
- geoai/classify.py +933 -0
- geoai/download.py +257 -114
- geoai/extract.py +153 -46
- geoai/geoai.py +14 -0
- geoai/utils.py +162 -0
- {geoai_py-0.4.2.dist-info → geoai_py-0.5.0.dist-info}/METADATA +1 -1
- geoai_py-0.5.0.dist-info/RECORD +16 -0
- {geoai_py-0.4.2.dist-info → geoai_py-0.5.0.dist-info}/WHEEL +1 -1
- geoai_py-0.4.2.dist-info/RECORD +0 -15
- {geoai_py-0.4.2.dist-info → geoai_py-0.5.0.dist-info}/entry_points.txt +0 -0
- {geoai_py-0.4.2.dist-info → geoai_py-0.5.0.dist-info}/licenses/LICENSE +0 -0
- {geoai_py-0.4.2.dist-info → geoai_py-0.5.0.dist-info}/top_level.txt +0 -0
geoai/extract.py
CHANGED
|
@@ -19,6 +19,7 @@ from torchvision.models.detection import (
|
|
|
19
19
|
maskrcnn_resnet50_fpn,
|
|
20
20
|
)
|
|
21
21
|
from tqdm import tqdm
|
|
22
|
+
import time
|
|
22
23
|
|
|
23
24
|
# Local Imports
|
|
24
25
|
from .utils import get_raster_stats
|
|
@@ -2117,6 +2118,7 @@ class ObjectDetector:
|
|
|
2117
2118
|
confidence_threshold=0.5,
|
|
2118
2119
|
min_object_area=100,
|
|
2119
2120
|
max_object_area=None,
|
|
2121
|
+
n_workers=None,
|
|
2120
2122
|
**kwargs,
|
|
2121
2123
|
):
|
|
2122
2124
|
"""
|
|
@@ -2128,14 +2130,103 @@ class ObjectDetector:
|
|
|
2128
2130
|
confidence_threshold: Minimum confidence score (0.0-1.0). Default: 0.5
|
|
2129
2131
|
min_object_area: Minimum area in pixels to keep an object. Default: 100
|
|
2130
2132
|
max_object_area: Maximum area in pixels to keep an object. Default: None
|
|
2133
|
+
n_workers: int, default=None
|
|
2134
|
+
The number of worker threads to use.
|
|
2135
|
+
"None" means single-threaded processing.
|
|
2136
|
+
"-1" means using all available CPU processors.
|
|
2137
|
+
Positive integer means using that specific number of threads.
|
|
2131
2138
|
**kwargs: Additional parameters
|
|
2132
2139
|
|
|
2133
2140
|
Returns:
|
|
2134
2141
|
GeoDataFrame with car detections and confidence values
|
|
2135
2142
|
"""
|
|
2136
2143
|
|
|
2144
|
+
def _process_single_component(
|
|
2145
|
+
component_mask,
|
|
2146
|
+
conf_data,
|
|
2147
|
+
transform,
|
|
2148
|
+
confidence_threshold,
|
|
2149
|
+
min_object_area,
|
|
2150
|
+
max_object_area,
|
|
2151
|
+
):
|
|
2152
|
+
# Get confidence value
|
|
2153
|
+
conf_region = conf_data[component_mask > 0]
|
|
2154
|
+
if len(conf_region) > 0:
|
|
2155
|
+
confidence = np.mean(conf_region) / 255.0
|
|
2156
|
+
else:
|
|
2157
|
+
confidence = 0.0
|
|
2158
|
+
|
|
2159
|
+
# Skip if confidence is below threshold
|
|
2160
|
+
if confidence < confidence_threshold:
|
|
2161
|
+
return None
|
|
2162
|
+
|
|
2163
|
+
# Find contours
|
|
2164
|
+
contours, _ = cv2.findContours(
|
|
2165
|
+
component_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
|
|
2166
|
+
)
|
|
2167
|
+
|
|
2168
|
+
results = []
|
|
2169
|
+
|
|
2170
|
+
for contour in contours:
|
|
2171
|
+
# Filter by size
|
|
2172
|
+
area = cv2.contourArea(contour)
|
|
2173
|
+
if area < min_object_area:
|
|
2174
|
+
continue
|
|
2175
|
+
|
|
2176
|
+
if max_object_area is not None and area > max_object_area:
|
|
2177
|
+
continue
|
|
2178
|
+
|
|
2179
|
+
# Get minimum area rectangle
|
|
2180
|
+
rect = cv2.minAreaRect(contour)
|
|
2181
|
+
box_points = cv2.boxPoints(rect)
|
|
2182
|
+
|
|
2183
|
+
# Convert to geographic coordinates
|
|
2184
|
+
geo_points = []
|
|
2185
|
+
for x, y in box_points:
|
|
2186
|
+
gx, gy = transform * (x, y)
|
|
2187
|
+
geo_points.append((gx, gy))
|
|
2188
|
+
|
|
2189
|
+
# Create polygon
|
|
2190
|
+
poly = Polygon(geo_points)
|
|
2191
|
+
results.append((poly, confidence, area))
|
|
2192
|
+
|
|
2193
|
+
return results
|
|
2194
|
+
|
|
2195
|
+
import concurrent.futures
|
|
2196
|
+
from functools import partial
|
|
2197
|
+
|
|
2198
|
+
def process_component(args):
|
|
2199
|
+
"""
|
|
2200
|
+
Helper function to process a single component
|
|
2201
|
+
"""
|
|
2202
|
+
(
|
|
2203
|
+
label,
|
|
2204
|
+
labeled_mask,
|
|
2205
|
+
conf_data,
|
|
2206
|
+
transform,
|
|
2207
|
+
confidence_threshold,
|
|
2208
|
+
min_object_area,
|
|
2209
|
+
max_object_area,
|
|
2210
|
+
) = args
|
|
2211
|
+
|
|
2212
|
+
# Create mask for this component
|
|
2213
|
+
component_mask = (labeled_mask == label).astype(np.uint8)
|
|
2214
|
+
|
|
2215
|
+
return _process_single_component(
|
|
2216
|
+
component_mask,
|
|
2217
|
+
conf_data,
|
|
2218
|
+
transform,
|
|
2219
|
+
confidence_threshold,
|
|
2220
|
+
min_object_area,
|
|
2221
|
+
max_object_area,
|
|
2222
|
+
)
|
|
2223
|
+
|
|
2224
|
+
start_time = time.time()
|
|
2137
2225
|
print(f"Processing masks from: {masks_path}")
|
|
2138
2226
|
|
|
2227
|
+
if n_workers == -1:
|
|
2228
|
+
n_workers = os.cpu_count()
|
|
2229
|
+
|
|
2139
2230
|
with rasterio.open(masks_path) as src:
|
|
2140
2231
|
# Read mask and confidence bands
|
|
2141
2232
|
mask_data = src.read(1)
|
|
@@ -2155,56 +2246,68 @@ class ObjectDetector:
|
|
|
2155
2246
|
confidences = []
|
|
2156
2247
|
pixels = []
|
|
2157
2248
|
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
component_mask = (labeled_mask == label).astype(np.uint8)
|
|
2162
|
-
|
|
2163
|
-
# Get confidence value (mean of non-zero values in this region)
|
|
2164
|
-
conf_region = conf_data[component_mask > 0]
|
|
2165
|
-
if len(conf_region) > 0:
|
|
2166
|
-
confidence = (
|
|
2167
|
-
np.mean(conf_region) / 255.0
|
|
2168
|
-
) # Convert back to 0-1 range
|
|
2169
|
-
else:
|
|
2170
|
-
confidence = 0.0
|
|
2171
|
-
|
|
2172
|
-
# Skip if confidence is below threshold
|
|
2173
|
-
if confidence < confidence_threshold:
|
|
2174
|
-
continue
|
|
2175
|
-
|
|
2176
|
-
# Find contours
|
|
2177
|
-
contours, _ = cv2.findContours(
|
|
2178
|
-
component_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
|
|
2249
|
+
if n_workers is None or n_workers == 1:
|
|
2250
|
+
print(
|
|
2251
|
+
"Using single-threaded processing, you can speed up processing by setting n_workers > 1"
|
|
2179
2252
|
)
|
|
2253
|
+
# Add progress bar
|
|
2254
|
+
for label in tqdm(
|
|
2255
|
+
range(1, num_features + 1), desc="Processing components"
|
|
2256
|
+
):
|
|
2257
|
+
# Create mask for this component
|
|
2258
|
+
component_mask = (labeled_mask == label).astype(np.uint8)
|
|
2259
|
+
|
|
2260
|
+
result = _process_single_component(
|
|
2261
|
+
component_mask,
|
|
2262
|
+
conf_data,
|
|
2263
|
+
transform,
|
|
2264
|
+
confidence_threshold,
|
|
2265
|
+
min_object_area,
|
|
2266
|
+
max_object_area,
|
|
2267
|
+
)
|
|
2180
2268
|
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
if max_object_area is not None:
|
|
2188
|
-
if area > max_object_area:
|
|
2189
|
-
continue
|
|
2190
|
-
|
|
2191
|
-
# Get minimum area rectangle
|
|
2192
|
-
rect = cv2.minAreaRect(contour)
|
|
2193
|
-
box_points = cv2.boxPoints(rect)
|
|
2269
|
+
if result:
|
|
2270
|
+
for poly, confidence, area in result:
|
|
2271
|
+
# Add to lists
|
|
2272
|
+
polygons.append(poly)
|
|
2273
|
+
confidences.append(confidence)
|
|
2274
|
+
pixels.append(area)
|
|
2194
2275
|
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2276
|
+
else:
|
|
2277
|
+
# Process components in parallel
|
|
2278
|
+
print(f"Using {n_workers} workers for parallel processing")
|
|
2279
|
+
|
|
2280
|
+
process_args = [
|
|
2281
|
+
(
|
|
2282
|
+
label,
|
|
2283
|
+
labeled_mask,
|
|
2284
|
+
conf_data,
|
|
2285
|
+
transform,
|
|
2286
|
+
confidence_threshold,
|
|
2287
|
+
min_object_area,
|
|
2288
|
+
max_object_area,
|
|
2289
|
+
)
|
|
2290
|
+
for label in range(1, num_features + 1)
|
|
2291
|
+
]
|
|
2292
|
+
|
|
2293
|
+
with concurrent.futures.ThreadPoolExecutor(
|
|
2294
|
+
max_workers=n_workers
|
|
2295
|
+
) as executor:
|
|
2296
|
+
results = list(
|
|
2297
|
+
tqdm(
|
|
2298
|
+
executor.map(process_component, process_args),
|
|
2299
|
+
total=num_features,
|
|
2300
|
+
desc="Processing components",
|
|
2301
|
+
)
|
|
2302
|
+
)
|
|
2203
2303
|
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2304
|
+
for result in results:
|
|
2305
|
+
if result:
|
|
2306
|
+
for poly, confidence, area in result:
|
|
2307
|
+
# Add to lists
|
|
2308
|
+
polygons.append(poly)
|
|
2309
|
+
confidences.append(confidence)
|
|
2310
|
+
pixels.append(area)
|
|
2208
2311
|
|
|
2209
2312
|
# Create GeoDataFrame
|
|
2210
2313
|
if polygons:
|
|
@@ -2223,8 +2326,12 @@ class ObjectDetector:
|
|
|
2223
2326
|
gdf.to_file(output_path, driver="GeoJSON")
|
|
2224
2327
|
print(f"Saved {len(gdf)} objects with confidence to {output_path}")
|
|
2225
2328
|
|
|
2329
|
+
end_time = time.time()
|
|
2330
|
+
print(f"Total processing time: {end_time - start_time:.2f} seconds")
|
|
2226
2331
|
return gdf
|
|
2227
2332
|
else:
|
|
2333
|
+
end_time = time.time()
|
|
2334
|
+
print(f"Total processing time: {end_time - start_time:.2f} seconds")
|
|
2228
2335
|
print("No valid polygons found")
|
|
2229
2336
|
return None
|
|
2230
2337
|
|
geoai/geoai.py
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
"""Main module."""
|
|
2
2
|
|
|
3
|
+
import leafmap
|
|
4
|
+
|
|
3
5
|
from .download import (
|
|
4
6
|
download_naip,
|
|
5
7
|
download_overture_buildings,
|
|
6
8
|
download_pc_stac_item,
|
|
7
9
|
pc_collection_list,
|
|
10
|
+
pc_item_asset_list,
|
|
8
11
|
pc_stac_search,
|
|
9
12
|
pc_stac_download,
|
|
13
|
+
read_pc_item_asset,
|
|
14
|
+
view_pc_item,
|
|
10
15
|
)
|
|
16
|
+
from .classify import train_classifier, classify_image, classify_images
|
|
11
17
|
from .extract import *
|
|
12
18
|
from .hf import *
|
|
13
19
|
from .segment import *
|
|
14
20
|
from .train import object_detection, train_MaskRCNN_model
|
|
15
21
|
from .utils import *
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Map(leafmap.Map):
|
|
25
|
+
"""A subclass of leafmap.Map for GeoAI applications."""
|
|
26
|
+
|
|
27
|
+
def __init__(self, *args, **kwargs):
|
|
28
|
+
"""Initialize the Map class."""
|
|
29
|
+
super().__init__(*args, **kwargs)
|
geoai/utils.py
CHANGED
|
@@ -6053,3 +6053,165 @@ def try_common_architectures(state_dict):
|
|
|
6053
6053
|
|
|
6054
6054
|
except Exception as e:
|
|
6055
6055
|
print(f"- {name}: Failed to load - {str(e)}")
|
|
6056
|
+
|
|
6057
|
+
|
|
6058
|
+
def mosaic_geotiffs(input_dir, output_file, mask_file=None):
|
|
6059
|
+
"""Create a mosaic from all GeoTIFF files as a Cloud Optimized GeoTIFF (COG).
|
|
6060
|
+
|
|
6061
|
+
This function identifies all GeoTIFF files in the specified directory,
|
|
6062
|
+
creates a seamless mosaic with proper handling of nodata values, and saves
|
|
6063
|
+
as a Cloud Optimized GeoTIFF format. If a mask file is provided, the output
|
|
6064
|
+
will be clipped to the extent of the mask.
|
|
6065
|
+
|
|
6066
|
+
Args:
|
|
6067
|
+
input_dir (str): Path to the directory containing GeoTIFF files.
|
|
6068
|
+
output_file (str): Path to the output Cloud Optimized GeoTIFF file.
|
|
6069
|
+
mask_file (str, optional): Path to a mask file to clip the output.
|
|
6070
|
+
If provided, the output will be clipped to the extent of this mask.
|
|
6071
|
+
Defaults to None.
|
|
6072
|
+
|
|
6073
|
+
Returns:
|
|
6074
|
+
bool: True if the mosaic was created successfully, False otherwise.
|
|
6075
|
+
|
|
6076
|
+
Examples:
|
|
6077
|
+
>>> mosaic_geotiffs('naip', 'merged_naip.tif')
|
|
6078
|
+
True
|
|
6079
|
+
>>> mosaic_geotiffs('naip', 'merged_naip.tif', 'boundary.tif')
|
|
6080
|
+
True
|
|
6081
|
+
"""
|
|
6082
|
+
import glob
|
|
6083
|
+
from osgeo import gdal
|
|
6084
|
+
|
|
6085
|
+
gdal.UseExceptions()
|
|
6086
|
+
# Get all tif files in the directory
|
|
6087
|
+
tif_files = glob.glob(os.path.join(input_dir, "*.tif"))
|
|
6088
|
+
|
|
6089
|
+
if not tif_files:
|
|
6090
|
+
print("No GeoTIFF files found in the specified directory.")
|
|
6091
|
+
return False
|
|
6092
|
+
|
|
6093
|
+
# Analyze the first input file to determine compression and nodata settings
|
|
6094
|
+
ds = gdal.Open(tif_files[0])
|
|
6095
|
+
if ds is None:
|
|
6096
|
+
print(f"Unable to open {tif_files[0]}")
|
|
6097
|
+
return False
|
|
6098
|
+
|
|
6099
|
+
# Get driver metadata from the first file
|
|
6100
|
+
driver = ds.GetDriver()
|
|
6101
|
+
creation_options = []
|
|
6102
|
+
|
|
6103
|
+
# Check compression type
|
|
6104
|
+
metadata = ds.GetMetadata("IMAGE_STRUCTURE")
|
|
6105
|
+
if "COMPRESSION" in metadata:
|
|
6106
|
+
compression = metadata["COMPRESSION"]
|
|
6107
|
+
creation_options.append(f"COMPRESS={compression}")
|
|
6108
|
+
else:
|
|
6109
|
+
# Default compression if none detected
|
|
6110
|
+
creation_options.append("COMPRESS=LZW")
|
|
6111
|
+
|
|
6112
|
+
# Add COG-specific creation options
|
|
6113
|
+
creation_options.extend(["TILED=YES", "BLOCKXSIZE=512", "BLOCKYSIZE=512"])
|
|
6114
|
+
|
|
6115
|
+
# Check for nodata value in the first band of the first file
|
|
6116
|
+
band = ds.GetRasterBand(1)
|
|
6117
|
+
has_nodata = band.GetNoDataValue() is not None
|
|
6118
|
+
nodata_value = band.GetNoDataValue() if has_nodata else None
|
|
6119
|
+
|
|
6120
|
+
# Close the dataset
|
|
6121
|
+
ds = None
|
|
6122
|
+
|
|
6123
|
+
# Create a temporary VRT (Virtual Dataset)
|
|
6124
|
+
vrt_path = os.path.join(input_dir, "temp_mosaic.vrt")
|
|
6125
|
+
|
|
6126
|
+
# Build VRT from input files with proper nodata handling
|
|
6127
|
+
vrt_options = gdal.BuildVRTOptions(
|
|
6128
|
+
resampleAlg="nearest",
|
|
6129
|
+
srcNodata=nodata_value if has_nodata else None,
|
|
6130
|
+
VRTNodata=nodata_value if has_nodata else None,
|
|
6131
|
+
)
|
|
6132
|
+
vrt_dataset = gdal.BuildVRT(vrt_path, tif_files, options=vrt_options)
|
|
6133
|
+
|
|
6134
|
+
# Close the VRT dataset to flush it to disk
|
|
6135
|
+
vrt_dataset = None
|
|
6136
|
+
|
|
6137
|
+
# Create temp mosaic
|
|
6138
|
+
temp_mosaic = output_file + ".temp.tif"
|
|
6139
|
+
|
|
6140
|
+
# Convert VRT to GeoTIFF with the same compression as input
|
|
6141
|
+
translate_options = gdal.TranslateOptions(
|
|
6142
|
+
format="GTiff",
|
|
6143
|
+
creationOptions=creation_options,
|
|
6144
|
+
noData=nodata_value if has_nodata else None,
|
|
6145
|
+
)
|
|
6146
|
+
gdal.Translate(temp_mosaic, vrt_path, options=translate_options)
|
|
6147
|
+
|
|
6148
|
+
# Apply mask if provided
|
|
6149
|
+
if mask_file and os.path.exists(mask_file):
|
|
6150
|
+
print(f"Clipping mosaic to mask: {mask_file}")
|
|
6151
|
+
|
|
6152
|
+
# Create a temporary clipped file
|
|
6153
|
+
clipped_mosaic = output_file + ".clipped.tif"
|
|
6154
|
+
|
|
6155
|
+
# Open mask file
|
|
6156
|
+
mask_ds = gdal.Open(mask_file)
|
|
6157
|
+
if mask_ds is None:
|
|
6158
|
+
print(f"Unable to open mask file: {mask_file}")
|
|
6159
|
+
# Continue without clipping
|
|
6160
|
+
else:
|
|
6161
|
+
# Get mask extent
|
|
6162
|
+
mask_geotransform = mask_ds.GetGeoTransform()
|
|
6163
|
+
mask_projection = mask_ds.GetProjection()
|
|
6164
|
+
mask_ulx = mask_geotransform[0]
|
|
6165
|
+
mask_uly = mask_geotransform[3]
|
|
6166
|
+
mask_lrx = mask_ulx + (mask_geotransform[1] * mask_ds.RasterXSize)
|
|
6167
|
+
mask_lry = mask_uly + (mask_geotransform[5] * mask_ds.RasterYSize)
|
|
6168
|
+
|
|
6169
|
+
# Close mask dataset
|
|
6170
|
+
mask_ds = None
|
|
6171
|
+
|
|
6172
|
+
# Use warp options to clip
|
|
6173
|
+
warp_options = gdal.WarpOptions(
|
|
6174
|
+
format="GTiff",
|
|
6175
|
+
outputBounds=[mask_ulx, mask_lry, mask_lrx, mask_uly],
|
|
6176
|
+
dstSRS=mask_projection,
|
|
6177
|
+
creationOptions=creation_options,
|
|
6178
|
+
srcNodata=nodata_value if has_nodata else None,
|
|
6179
|
+
dstNodata=nodata_value if has_nodata else None,
|
|
6180
|
+
)
|
|
6181
|
+
|
|
6182
|
+
# Apply clipping
|
|
6183
|
+
gdal.Warp(clipped_mosaic, temp_mosaic, options=warp_options)
|
|
6184
|
+
|
|
6185
|
+
# Remove the unclipped temp mosaic and use the clipped one
|
|
6186
|
+
os.remove(temp_mosaic)
|
|
6187
|
+
temp_mosaic = clipped_mosaic
|
|
6188
|
+
|
|
6189
|
+
# Create internal overviews for the temp mosaic
|
|
6190
|
+
ds = gdal.Open(temp_mosaic, gdal.GA_Update)
|
|
6191
|
+
overview_list = [2, 4, 8, 16, 32]
|
|
6192
|
+
ds.BuildOverviews("NEAREST", overview_list)
|
|
6193
|
+
ds = None # Close the dataset to ensure overviews are written
|
|
6194
|
+
|
|
6195
|
+
# Convert the temp mosaic to a proper COG
|
|
6196
|
+
cog_options = gdal.TranslateOptions(
|
|
6197
|
+
format="GTiff",
|
|
6198
|
+
creationOptions=[
|
|
6199
|
+
"TILED=YES",
|
|
6200
|
+
"COPY_SRC_OVERVIEWS=YES",
|
|
6201
|
+
"COMPRESS=DEFLATE",
|
|
6202
|
+
"PREDICTOR=2",
|
|
6203
|
+
"BLOCKXSIZE=512",
|
|
6204
|
+
"BLOCKYSIZE=512",
|
|
6205
|
+
],
|
|
6206
|
+
noData=nodata_value if has_nodata else None,
|
|
6207
|
+
)
|
|
6208
|
+
gdal.Translate(output_file, temp_mosaic, options=cog_options)
|
|
6209
|
+
|
|
6210
|
+
# Clean up temporary files
|
|
6211
|
+
if os.path.exists(vrt_path):
|
|
6212
|
+
os.remove(vrt_path)
|
|
6213
|
+
if os.path.exists(temp_mosaic):
|
|
6214
|
+
os.remove(temp_mosaic)
|
|
6215
|
+
|
|
6216
|
+
print(f"Cloud Optimized GeoTIFF mosaic created successfully: {output_file}")
|
|
6217
|
+
return True
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
geoai/__init__.py,sha256=jGJl23LMoJDPdWTrlWAPxXK8cjwWllGQcFQ5IJOJ0s0,3765
|
|
2
|
+
geoai/classify.py,sha256=_e-193QzAx3pIxUflPIsIs1qZevQx5ADu7i3bOL1G70,35055
|
|
3
|
+
geoai/download.py,sha256=lJ1GsJOZsKc2i6_dQyPV-XXIXmlADOpmSBo-wha4DEU,40892
|
|
4
|
+
geoai/extract.py,sha256=GocJufMmrwEWxNBL1J91EXXHL8AKcO8m_lmtUF5AKPw,119102
|
|
5
|
+
geoai/geoai.py,sha256=5zXt7WQ0FbiksXKQ9fBNnfa9dhJ3QVd8LXicMxyynTg,698
|
|
6
|
+
geoai/hf.py,sha256=mLKGxEAS5eHkxZLwuLpYc1o7e3-7QIXdBv-QUY-RkFk,17072
|
|
7
|
+
geoai/segment.py,sha256=g3YW17ftr--CKq6VB32TJEPY8owGQ7uQ0sg_tUT2ooE,13681
|
|
8
|
+
geoai/segmentation.py,sha256=AtPzCvguHAEeuyXafa4bzMFATvltEYcah1B8ZMfkM_s,11373
|
|
9
|
+
geoai/train.py,sha256=-l2j1leTxDnFDLaBslu1q6CobXjm3LEdiQwUWOU8P6M,40088
|
|
10
|
+
geoai/utils.py,sha256=xxhIkNFFtv-s_tzrlAyD4qIOaxo2JtKJEzG6vFgA5y8,238737
|
|
11
|
+
geoai_py-0.5.0.dist-info/licenses/LICENSE,sha256=vN2L5U7cZ6ZkOHFmc8WiGlsogWsZc5dllMeNxnKVOZg,1070
|
|
12
|
+
geoai_py-0.5.0.dist-info/METADATA,sha256=tzHz2Q1iTpCO25T8W3N2RtyaHdwdb9umS9YIgCciFdo,6049
|
|
13
|
+
geoai_py-0.5.0.dist-info/WHEEL,sha256=MAQBAzGbXNI3bUmkDsiV_duv8i-gcdnLzw7cfUFwqhU,109
|
|
14
|
+
geoai_py-0.5.0.dist-info/entry_points.txt,sha256=uGp3Az3HURIsRHP9v-ys0hIbUuBBNUfXv6VbYHIXeg4,41
|
|
15
|
+
geoai_py-0.5.0.dist-info/top_level.txt,sha256=1YkCUWu-ii-0qIex7kbwAvfei-gos9ycyDyUCJPNWHY,6
|
|
16
|
+
geoai_py-0.5.0.dist-info/RECORD,,
|
geoai_py-0.4.2.dist-info/RECORD
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
geoai/__init__.py,sha256=kHB6b3uOdCoxMpIpfpXtPxg-KJQVsKJveb8zTw5Mxzs,3592
|
|
2
|
-
geoai/download.py,sha256=SE81OrhH2XSH02xtAXQyh5ltBqA8K7ksGT1Lm6SMqx8,37593
|
|
3
|
-
geoai/extract.py,sha256=bR8TkUXncW0rinsBO5oxlVFGsSVoj6xnm5xdDc-J1Xk,115490
|
|
4
|
-
geoai/geoai.py,sha256=qY1HWmJQ0ZgIPtlgWd4gpuCGw6dovdg8D5pAtHqfr8U,334
|
|
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=-l2j1leTxDnFDLaBslu1q6CobXjm3LEdiQwUWOU8P6M,40088
|
|
9
|
-
geoai/utils.py,sha256=Wg9jbMBKUZSGUmU8Vkp6v19QcDNg5KmcyZxuHqJvgnc,233016
|
|
10
|
-
geoai_py-0.4.2.dist-info/licenses/LICENSE,sha256=vN2L5U7cZ6ZkOHFmc8WiGlsogWsZc5dllMeNxnKVOZg,1070
|
|
11
|
-
geoai_py-0.4.2.dist-info/METADATA,sha256=Sc6m-MyCti-_Dnan5wp6GIy88LwuBAF_IYrFF34SRJE,6049
|
|
12
|
-
geoai_py-0.4.2.dist-info/WHEEL,sha256=9bhjOwO--Rs91xaPcBdlYFUmIudhuXqFlPriQeYQITw,109
|
|
13
|
-
geoai_py-0.4.2.dist-info/entry_points.txt,sha256=uGp3Az3HURIsRHP9v-ys0hIbUuBBNUfXv6VbYHIXeg4,41
|
|
14
|
-
geoai_py-0.4.2.dist-info/top_level.txt,sha256=1YkCUWu-ii-0qIex7kbwAvfei-gos9ycyDyUCJPNWHY,6
|
|
15
|
-
geoai_py-0.4.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|