-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexport_utils.py
More file actions
135 lines (114 loc) · 3.78 KB
/
export_utils.py
File metadata and controls
135 lines (114 loc) · 3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
"""
Export utilities – GeoTIFF, Shapefile, and CSV export helpers
for saving GEE results locally via geemap.
"""
import os
import ee
import geemap
import pandas as pd
import config as cfg
def ensure_output_dir(subdir=None):
"""Create output directory if it doesn't exist."""
path = cfg.OUTPUT_DIR
if subdir:
path = os.path.join(path, subdir)
os.makedirs(path, exist_ok=True)
return path
def _default_region():
"""Get default export region based on scope."""
if cfg.SCOPE == "national":
from data_acquisition import get_country_boundary
return get_country_boundary()
b = cfg.STUDY_AREA_BOUNDS
return ee.Geometry.Rectangle([b["west"], b["south"], b["east"], b["north"]])
def export_geotiff(image, filename, region=None, scale=None, subdir=None):
"""
Export an ee.Image as a GeoTIFF using geemap.
"""
if region is None:
region = _default_region()
if scale is None:
scale = cfg.EXPORT_SCALE
out_dir = ensure_output_dir(subdir)
filepath = os.path.join(out_dir, filename)
geemap.ee_export_image(
image,
filename=filepath,
scale=scale,
region=region,
crs=cfg.EXPORT_CRS,
file_per_band=False,
)
print(f" Exported GeoTIFF: {filepath}")
return filepath
def export_to_drive(image, description, folder="bd_gis_exports",
region=None, scale=None):
"""
Export an ee.Image to Google Drive (for large exports that
exceed geemap's direct download limit).
"""
if region is None:
region = _default_region()
if scale is None:
scale = cfg.EXPORT_SCALE
task = ee.batch.Export.image.toDrive(
image=image,
description=description,
folder=folder,
region=region,
scale=scale,
crs=cfg.EXPORT_CRS,
maxPixels=cfg.MAX_PIXELS,
)
task.start()
print(f" Started Drive export: {description} (task ID: {task.id})")
return task
def export_shapefile(fc, filename, subdir=None):
"""Export an ee.FeatureCollection as a Shapefile."""
out_dir = ensure_output_dir(subdir)
filepath = os.path.join(out_dir, filename)
geemap.ee_export_vector(fc, filename=filepath)
print(f" Exported Shapefile: {filepath}")
return filepath
def export_csv(data, filename, subdir=None):
"""
Export a list of dicts or pandas DataFrame to CSV.
Handles ee.Number values by calling getInfo().
"""
out_dir = ensure_output_dir(subdir)
filepath = os.path.join(out_dir, filename)
if isinstance(data, pd.DataFrame):
df = data
else:
# Resolve ee.Number values
resolved = []
for row in data:
resolved_row = {}
for k, v in row.items():
if isinstance(v, ee.Number):
try:
resolved_row[k] = v.getInfo()
except Exception:
resolved_row[k] = None
elif isinstance(v, ee.ComputedObject):
try:
resolved_row[k] = v.getInfo()
except Exception:
resolved_row[k] = None
else:
resolved_row[k] = v
resolved.append(resolved_row)
df = pd.DataFrame(resolved)
df.to_csv(filepath, index=False)
print(f" Exported CSV: {filepath}")
return filepath
def export_fc_to_csv(fc, filename, subdir=None):
"""Export ee.FeatureCollection properties to CSV."""
out_dir = ensure_output_dir(subdir)
filepath = os.path.join(out_dir, filename)
features = fc.getInfo()["features"]
rows = [f["properties"] for f in features]
df = pd.DataFrame(rows)
df.to_csv(filepath, index=False)
print(f" Exported FC CSV: {filepath}")
return filepath