"""TODO missing docstring."""
import os
import ee
from .. import tools
from .._deprecated_utils import makeName
from . import utils
[docs]
def toDrive(
collection,
folder,
namePattern="{id}",
scale=30,
dataType="float",
region=None,
datePattern=None,
extra=None,
verbose=False,
**kwargs
):
"""Upload all images from one collection to Google Drive. You can use.
the same arguments as the original function
ee.batch.export.image.toDrive.
:param collection: Collection to upload
:type collection: ee.ImageCollection
:param folder: Google Drive folder to export the images to
:type folder: str
:param namePattern: pattern for the name.
See geetools.tools.image.make_name function and also
geetools.tools.string.format function
:type namePattern: str
:param scale: scale of the image (side of one pixel). Defaults to 30
(Landsat resolution)
:type scale: int
:param dataType: as downloaded images **must** have the same data type
in all bands, you have to set it here. Can be one of: "float",
"double", "int", "Uint8", "Int8" or a casting function like
*ee.Image.toFloat*
:type dataType: str
:param region: area to upload. Default to the footprint of the first
image in the collection
:type region: ee.Geometry.Rectangle or ee.Feature
:param datePattern: pattern for date if specified in namePattern.
Defaults to 'yyyyMMdd'. See ee.Date.format for more details
:type datePattern: str
:param extra: extra parameters to parse to the name formatter
:type extra: str
:param verbose: print name of each exporting task
:type verbose: bool
:return: list of tasks
:rtype: list
"""
# empty tasks list
tasklist = []
# get region
if region:
region = tools.geometry.getRegion(region)
# Make a list of images
img_list = collection.toList(collection.size())
n = 0
while True:
try:
img = ee.Image(img_list.get(n))
name = makeName(img, namePattern, datePattern, extra)
name = name.getInfo()
description = utils.matchDescription(name)
# convert data type
img = utils.convertDataType(dataType)(img)
if region is None:
region = tools.geometry.getRegion(img)
task = ee.batch.Export.image.toDrive(
image=img,
description=description,
folder=folder,
fileNamePrefix=name,
region=region,
scale=scale,
**kwargs
)
task.start()
if verbose:
print("exporting {} to folder '{}' in GDrive".format(name, folder))
tasklist.append(task)
n += 1
except Exception as e:
error = str(e).split(":")
if error[0] == "List.get":
break
else:
raise e
return tasklist
[docs]
def toCloudStorage(
collection,
bucket,
folder=None,
namePattern="{id}",
region=None,
scale=30,
dataType="float",
datePattern=None,
verbose=False,
extra=None,
**kwargs
):
"""Upload all images from one collection to Google Cloud Storage. You can.
use the same arguments as the original function
ee.batch.export.image.toCloudStorage.
:param collection: Collection to upload
:type collection: ee.ImageCollection
:param bucket: Google Cloud Storage bucket name
:type folder: str
:param folder: Google Cloud Storage prefix to export the images to
:type folder: str
:param namePattern: pattern for the name. See make_name function
:type namePattern: str
:param region: area to upload. default to the footprint of the first
image in the collection
:type region: ee.Geometry.Rectangle or ee.Feature
:param scale: scale of the image (side of one pixel). Defaults to 30
(Landsat resolution)
:type scale: int
:param dataType: as downloaded images **must** have the same data type
in all bands, you have to set it here. Can be one of: "float",
"double", "int", "Uint8", "Int8" or a casting function like
*ee.Image.toFloat*
:type dataType: str
:param datePattern: pattern for date if specified in namePattern.
Defaults to 'yyyyMMdd'
:type datePattern: str
"""
# empty tasks list
tasklist = []
# get region
region = tools.geometry.getRegion(region)
# Make a list of images
img_list = collection.toList(collection.size())
n = 0
while True:
try:
img = ee.Image(img_list.get(n))
name = makeName(img, namePattern, datePattern, extra)
name = name.getInfo()
description = utils.matchDescription(name)
# convert data type
img = utils.convertDataType(dataType)(img)
if folder is not None:
path = folder + "/" + name
else:
path = name
task = ee.batch.Export.image.toCloudStorage(
image=img,
description=description,
bucket=bucket,
path=path,
region=region,
scale=scale,
**kwargs
)
task.start()
tasklist.append(task)
if verbose:
print("adding task {} to list".format(name))
n += 1
except Exception as e:
error = str(e).split(":")
if error[0] == "List.get":
break
else:
raise e
return tasklist
[docs]
def toAsset(
collection,
assetPath,
namePattern=None,
scale=30,
region=None,
create=True,
verbose=False,
datePattern="yyyyMMdd",
extra=None,
**kwargs
):
"""Upload all images from one collection to a Earth Engine Asset.
You can use the same arguments as the original function
ee.batch.export.image.toDrive.
:param collection: Collection to upload
:type collection: ee.ImageCollection
:param assetPath: path of the asset where images will go
:type assetPath: str
:param namePattern: pattern for the name. If None, it uses the position
of the image in the image collection as the name. Otherwise see
geetools.tools.image.make_name function and also
geetools.tools.string.format function
:type namePattern: str
:param region: area to upload. default to the footprint of the first
image in the collection
:type region: ee.Geometry.Rectangle or ee.Feature
:param scale: scale of the image (side of one pixel). Defaults to 30
(Landsat resolution)
:type scale: int
:return: list of tasks
:rtype: list
"""
tasklist = []
if create:
utils.createAssets([assetPath], "ImageCollection", True)
if region:
region = tools.geometry.getRegion(region)
added = False
if namePattern:
imlist = collection.toList(collection.size())
idx = 0
while True:
try:
img = imlist.get(idx)
img = ee.Image(img)
if isinstance(extra, dict):
if added:
extra.pop("position")
if "position" not in extra:
extra["position"] = idx
else:
extra = dict(position=idx)
added = True
name = makeName(img, namePattern, datePattern, extra)
name = name.getInfo()
description = utils.matchDescription(name)
assetId = assetPath + "/" + name
params = dict(image=img, assetId=assetId, description=description, scale=scale)
if region:
params["region"] = region
if kwargs:
params.update(kwargs)
task = ee.batch.Export.image.toAsset(**params)
task.start()
if verbose:
print("Exporting {} to {}".format(name, assetId))
tasklist.append(task)
idx += 1
except Exception as e:
error = str(e).split(":")
if error[0] == "List.get":
break
else:
raise e
else:
size = collection.size().getInfo()
imlist = collection.toList(size)
for idx in range(0, size + 1):
img = imlist.get(idx)
img = ee.Image(img)
name = str(idx)
description = name
assetId = assetPath + "/" + name
if region is None:
region = tools.geometry.getRegion(img)
task = ee.batch.Export.image.toAsset(
image=img,
assetId=assetId,
description=description,
region=region,
scale=scale,
**kwargs
)
task.start()
if verbose:
print("Exporting {} to {}".format(name, assetId))
tasklist.append(task)
return tasklist
[docs]
def qgisCode(collection, visParams=None, name=None, datePattern=None, verbose=False):
"""Missing docstring."""
QGIS_COL_CODE = """names={names}
urls={urls}
for name, url in zip(names, urls):
urlWithParams = "type=xyz&url={{}}".format(url)
rlayer = QgsRasterLayer(urlWithParams, name, "wms")
if rlayer.isValid():
QgsProject.instance().addMapLayer(rlayer)
else:
print("invalid layer")
"""
name = name or "{id}"
names = []
urls = []
i = 0
collist = collection.toList(collection.size())
catch = "List.get: List index must be between"
while True:
try:
img = ee.Image(collist.get(i))
n = makeName(img, name, datePattern).getInfo()
if verbose:
print("processing {}".format(n))
url = tools.image.getTileURL(img, visParams)
names.append(n)
urls.append(url)
i += 1
except Exception as e:
if catch in str(e):
break
else:
raise e
return QGIS_COL_CODE.format(names=names, urls=urls)
[docs]
def toQGIS(
collection,
visParams=None,
name=None,
filename=None,
path=None,
datePattern=None,
replace=True,
verbose=True,
):
"""Download a python file to import from QGIS."""
code = qgisCode(collection, visParams, name, datePattern, verbose)
path = path or os.getcwd()
# Check extension
if filename:
ext = filename.split(".")[-1]
if ext != "py":
filename += ".py"
else:
filename = "qgis2ee"
# add _qgis_ to filename
split = filename.split(".")[:-1]
noext = ".".join(split)
filename = "{}_qgis_".format(noext)
# process
finalpath = os.path.join(path, filename)
finalpath = "{}.py".format(finalpath)
if not os.path.exists(finalpath) or replace:
with open(finalpath, "w+") as thefile:
thefile.write(code)
return thefile
else:
return None