Esempio n. 1
0
import vtk
from osgeo import gdal,ogr,osr
import math
import imp
import sys
import xml.etree.ElementTree as ET
import subprocess
import numpy as np
import os
from gdalconst import GA_ReadOnly
import resource

from rasterio.warp import transform
import xarray as xr

gdal.UseExceptions()  # Enable errors

# Print iterations progress
# http://stackoverflow.com/a/34325723/410074
def printProgress(iteration, total, prefix='', suffix='', decimals=2, barLength=100):
    """
    Call in a loop to create terminal progress bar
    @params:
        iterations  - Required  : current iteration (Int)
        total       - Required  : total iterations (Int)
        prefix      - Optional  : prefix string (Str)
        suffix      - Optional  : suffix string (Str)
    """
    filledLength = int(round(barLength * iteration / float(total)))
    percents = round(100.00 * (iteration / float(total)), decimals)
    bar = '#' * filledLength + '-' * (barLength - filledLength)
Esempio n. 2
0
    def __init__(self, source_path, dico_dataset, tipo, txt=""):
        """Uses OGR functions to extract basic informations about
        geographic vector file (handles shapefile or MapInfo tables)
        and store into dictionaries.

        source_path = path to the DXF file
        dico_dataset = dictionary for global informations
        tipo = format
        text = dictionary of text in the selected language
        """
        # handling ogr specific exceptions
        errhandler = gdal_err.handler
        gdal.PushErrorHandler(errhandler)
        gdal.UseExceptions()
        self.alert = 0

        # changing working directory to layer folder
        chdir(path.dirname(source_path))

        # opening DXF
        try:
            # driver_dxf = ogr.GetDriverByName(str("DXF"))
            # dxf = driver_dxf.Open(source_path, 0)
            src = gdal.OpenEx(source_path, 0)
        except Exception as e:
            logging.error(e)
            youtils.erratum(dico_dataset, source_path, "err_corrupt")
            self.alert = self.alert + 1
            return None

        # raising incompatible files
        if not src:
            """ if file is not compatible """
            self.alert += 1
            dico_dataset["err_gdal"] = gdal_err.err_type, gdal_err.err_msg
            youtils.erratum(dico_dataset, source_path, "err_nobjet")
            return None
        else:
            layer = src.GetLayer()  # get the layer
            pass

        # DXF name and parent folder
        try:
            dico_dataset["name"] = path.basename(src.GetName())
            dico_dataset["folder"] = path.dirname(src.GetName())
        except AttributeError as err:
            logger.warning(err)
            dico_dataset["name"] = path.basename(source_path)
            dico_dataset["folder"] = path.dirname(source_path)

        # specific AutoDesk informations
        douxef = dxfgrabber.readfile(source_path)
        dico_dataset["version_code"] = douxef.dxfversion
        # see: http://dxfgrabber.readthedocs.org/en/latest/#Drawing.dxfversion
        if douxef.dxfversion == "AC1009":
            dico_dataset["version_name"] = "AutoCAD R12"
        elif douxef.dxfversion == "AC1015":
            dico_dataset["version_name"] = "AutoCAD R2000"
        elif douxef.dxfversion == "AC1018":
            dico_dataset["version_name"] = "AutoCAD R2004"
        elif douxef.dxfversion == "AC1021":
            dico_dataset["version_name"] = "AutoCAD R2007"
        elif douxef.dxfversion == "AC1024":
            dico_dataset["version_name"] = "AutoCAD R2010"
        elif douxef.dxfversion == "AC1027":
            dico_dataset["version_name"] = "AutoCAD R2013"
        else:
            dico_dataset["version_name"] = "douxef.dxfversion"

        # layers count and names
        dico_dataset["layers_count"] = src.GetLayerCount()
        li_layers_names = []
        li_layers_idx = []
        dico_dataset["layers_names"] = li_layers_names
        dico_dataset["layers_idx"] = li_layers_idx

        # dependencies and total size
        dependencies = youtils.list_dependencies(source_path, "auto")
        dico_dataset["dependencies"] = dependencies
        dico_dataset["total_size"] = youtils.sizeof(source_path, dependencies)
        # global dates
        crea, up = path.getctime(source_path), path.getmtime(source_path)
        dico_dataset["date_crea"] = strftime("%Y/%m/%d", localtime(crea))
        dico_dataset["date_actu"] = strftime("%Y/%m/%d", localtime(up))
        # total fields count
        total_fields = 0
        dico_dataset["total_fields"] = total_fields
        # total objects count
        total_objs = 0
        dico_dataset["total_objs"] = total_objs
        # parsing layers
        for layer_idx in range(src.GetLayerCount()):
            # dictionary where will be stored informations
            dico_layer = OrderedDict()
            dico_layer["src_name"] = dico_dataset.get("name")
            # getting layer object
            layer = src.GetLayerByIndex(layer_idx)
            # layer globals
            li_layers_names.append(layer.GetName())
            dico_layer["title"] = georeader.get_title(layer)
            li_layers_idx.append(layer_idx)
            # features
            layer_feat_count = layer.GetFeatureCount()
            dico_layer["num_obj"] = layer_feat_count
            if layer_feat_count == 0:
                """ if layer doesn't have any object, return an error """
                dico_layer["error"] = "err_nobjet"
                self.alert = self.alert + 1
            else:
                pass

            # fields
            layer_def = layer.GetLayerDefn()
            dico_layer["num_fields"] = layer_def.GetFieldCount()
            dico_layer["fields"] = georeader.get_fields_details(layer_def)

            # geometry type
            dico_layer["type_geom"] = georeader.get_geometry_type(layer)

            # SRS
            srs_details = georeader.get_srs_details(layer, txt)
            dico_layer["srs"] = srs_details[0]
            dico_layer["epsg"] = srs_details[1]
            dico_layer["srs_type"] = srs_details[2]

            # spatial extent
            extent = georeader.get_extent_as_tuple(layer)
            dico_layer["xmin"] = extent[0]
            dico_layer["xmax"] = extent[1]
            dico_layer["ymin"] = extent[2]
            dico_layer["ymax"] = extent[3]

            # storing layer into the GDB dictionary
            dico_dataset["{0}_{1}".format(
                layer_idx, dico_layer.get("title"))] = dico_layer
            # summing fields number
            total_fields += dico_layer.get("num_fields", 0)
            # summing objects number
            total_objs += dico_layer.get("num_obj", 0)
            # deleting dictionary to ensure having cleared space
            del dico_layer

        # storing fileds and objects sum
        dico_dataset["total_fields"] = total_fields
        dico_dataset["total_objs"] = total_objs

        # warnings messages
        if self.alert:
            dico_dataset["err_gdal"] = gdal_err.err_type, gdal_err.err_msg
        else:
            pass

        # clean exit
        del src
Esempio n. 3
0
import cartopy.crs as ccrs
from cartopy.io.srtm import add_shading
from osgeo import gdal, osr
from obspy.geodetics import gps2dist_azimuth
import utm
import time
import shutil
import os
import subprocess
import warnings
from .travel_time import celerity_travel_time, fdtd_travel_time
from .plotting import _plot_geographic_context
from .stack import calculate_semblance
from . import RTMWarning

gdal.UseExceptions()  # Allows for more Pythonic errors from GDAL

MIN_CELERITY = 220  # [m/s] Used for travel time buffer calculation

OUTPUT_DIR = 'rtm_dem'  # Name of directory to place rtm_dem_*.tif files into
# (created in same dir as where function is called)

TMP_TIFF = 'rtm_dem_tmp.tif'  # Filename to use for temporary I/O

# Values in brackets below are latitude, longitude, x_radius, y_radius, spacing
TEMPLATE = 'rtm_dem_{:.4f}_{:.4f}_{}x_{}y_{}m.tif'

NODATA = -9999  # Nodata value to use for output rasters

RESAMPLE_ALG = 'cubicspline'  # Algorithm to use for resampling
# See https://gdal.org/programs/gdalwarp.html#cmdoption-gdalwarp-r
Esempio n. 4
0
def map(ctx, map_type, date, output, root, result, image, date_frmt, ndv,
        gdal_frmt, warn_on_empty, band, coef, after, before, qa, refit_prefix,
        amplitude, predict_proba):
    """
    Map types: coef, predict, class, pheno

    \b
    Map QA flags:
        - 0 => no values
        - 1 => before
        - 2 => after
        - 3 => intersect

    \b
    Examples:
    > yatsm map --coef intercept --coef slope
    ... --band 3 --band 4 --band 5 --ndv -9999
    ... coef 2000-01-01 coef_map.gtif

    \b
    > yatsm map -c intercept -c slope -b 3 -b 4 -b 5 --ndv -9999
    ... coef 2000-01-01 coef_map.gtif

    \b
    > yatsm map --date "%Y-%j" predict 2000-001 prediction.gtif

    \b
    > yatsm map --result "YATSM_new" --after class 2000-01-01 LCmap.gtif

    \b
    Notes:
        - Image predictions will not use categorical information in timeseries
          models.
    """
    from osgeo import gdal

    from ..mapping import (get_classification, get_phenology, get_coefficients,
                           get_prediction)
    from ..utils import write_output

    gdal.AllRegister()
    gdal.UseExceptions()

    if len(band) == 0:
        band = 'all'

    try:
        image_ds = gdal.Open(image, gdal.GA_ReadOnly)
    except RuntimeError as err:
        raise click.ClickException('Could not open example image for reading '
                                   '(%s)' % str(err))

    date = date.toordinal()

    # Append underscore to prefix if not included
    if refit_prefix and not refit_prefix.endswith('_'):
        refit_prefix += '_'

    band_names = None
    if map_type == 'class':
        raster, band_names = get_classification(date,
                                                result,
                                                image_ds,
                                                after=after,
                                                before=before,
                                                qa=qa,
                                                pred_proba=predict_proba,
                                                warn_on_empty=warn_on_empty)
    elif map_type == 'coef':
        raster, band_names = get_coefficients(date,
                                              result,
                                              image_ds,
                                              band,
                                              coef,
                                              prefix=refit_prefix,
                                              amplitude=amplitude,
                                              after=after,
                                              before=before,
                                              qa=qa,
                                              ndv=ndv,
                                              warn_on_empty=warn_on_empty)
    elif map_type == 'predict':
        raster, band_names = get_prediction(date,
                                            result,
                                            image_ds,
                                            band,
                                            prefix=refit_prefix,
                                            after=after,
                                            before=before,
                                            qa=qa,
                                            ndv=ndv,
                                            warn_on_empty=warn_on_empty)
    elif map_type == 'pheno':
        raster, band_names = get_phenology(date,
                                           result,
                                           image_ds,
                                           after=after,
                                           before=before,
                                           qa=qa,
                                           ndv=ndv,
                                           warn_on_empty=warn_on_empty)

    write_output(raster, output, image_ds, gdal_frmt, ndv, band_names)

    image_ds = None
Esempio n. 5
0
def basic_test_11():

    ds = gdal.OpenEx('data/byte.tif')
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx('data/byte.tif', gdal.OF_RASTER)
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx('data/byte.tif', gdal.OF_VECTOR)
    if ds is not None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx('data/byte.tif', gdal.OF_RASTER | gdal.OF_VECTOR)
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx('data/byte.tif', gdal.OF_ALL)
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx('data/byte.tif', gdal.OF_UPDATE)
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx(
        'data/byte.tif', gdal.OF_RASTER | gdal.OF_VECTOR | gdal.OF_UPDATE
        | gdal.OF_VERBOSE_ERROR)
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx('data/byte.tif', allowed_drivers=[])
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx('data/byte.tif', allowed_drivers=['GTiff'])
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx('data/byte.tif', allowed_drivers=['PNG'])
    if ds is not None:
        gdaltest.post_reason('fail')
        return 'fail'

    with gdaltest.error_handler():
        ds = gdal.OpenEx('data/byte.tif', open_options=['FOO'])
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'

    ar_ds = [gdal.OpenEx('data/byte.tif', gdal.OF_SHARED) for i in range(1024)]
    if ar_ds[1023] is None:
        gdaltest.post_reason('fail')
        return 'fail'
    ar_ds = None

    ds = gdal.OpenEx('../ogr/data/poly.shp', gdal.OF_RASTER)
    if ds is not None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx('../ogr/data/poly.shp', gdal.OF_VECTOR)
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'
    if ds.GetLayerCount() != 1:
        gdaltest.post_reason('fail')
        return 'fail'
    if ds.GetLayer(0) is None:
        gdaltest.post_reason('fail')
        return 'fail'
    ds.GetLayer(0).GetMetadata()

    ds = gdal.OpenEx('../ogr/data/poly.shp',
                     allowed_drivers=['ESRI Shapefile'])
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx('../ogr/data/poly.shp', gdal.OF_RASTER | gdal.OF_VECTOR)
    if ds is None:
        gdaltest.post_reason('fail')
        return 'fail'

    ds = gdal.OpenEx('non existing')
    if ds is not None or gdal.GetLastErrorMsg() != '':
        gdaltest.post_reason('fail')
        return 'fail'

    gdal.PushErrorHandler('CPLQuietErrorHandler')
    ds = gdal.OpenEx('non existing', gdal.OF_VERBOSE_ERROR)
    gdal.PopErrorHandler()
    if ds is not None or gdal.GetLastErrorMsg() == '':
        gdaltest.post_reason('fail')
        return 'fail'

    old_use_exceptions_status = gdal.GetUseExceptions()
    gdal.UseExceptions()
    got_exception = False
    try:
        ds = gdal.OpenEx('non existing')
    except:
        got_exception = True
    if old_use_exceptions_status == 0:
        gdal.DontUseExceptions()
    if not got_exception:
        gdaltest.post_reason('fail')
        return 'fail'

    return 'success'
Esempio n. 6
0
    def run(self):

        logging.debug(f' Executing SHP2DB filter with params: {self.params}')

        # In general, we always want errors as exceptions. Having to enable them by hand is a "Python Gotcha" in gdal
        # see: https://trac.osgeo.org/gdal/wiki/PythonGotchas
        gdal.UseExceptions()

        shp_driver = ogr.GetDriverByName("ESRI Shapefile")
        input_data_source = shp_driver.Open(self.get_inputs()[0], 0)
        input_layer = input_data_source.GetLayer()

        # Find out the geometry type of the input to use it in the output
        # I am assuming that the input has at least one feature, and that all features are of the same
        # type (with shapefiles this is always so)
        geometry_type = input_layer.GetGeomType()

        # Warning: the shp format advertises polygons (ogr.wkbPolygon) even when there are multipolygons, and that
        # would make the insertion in PostGIS fail, so we will have to check and "upgrade" them to multipolygons when
        # loading to postgis
        if geometry_type == ogr.wkbPolygon:
            geometry_type = ogr.wkbMultiPolygon

        # If they are defined, they must be a string that can be processed with the Srs class
        if 'input_srs' in self.params:
            input_srs_string = self.params['input_srs']
        else:
            input_srs_string = None

        if 'output_srs' in self.params:
            output_srs_string = self.params['output_srs']
        else:
            output_srs_string = None

        # If input_srs is given use that. Otherwise, take the SRS of the input dataset
        if input_srs_string != None:
            input_srs = osr.SpatialReference()
            input_srs.ImportFromEPSG(
                int(gdtcsrs.Srs(input_srs_string).as_epsg_number()))
        else:
            input_srs = input_layer.GetSpatialRef()

        # If output_srs is given use that. Otherwise, take the same SRS used for the input
        if output_srs_string != None:
            output_srs = osr.SpatialReference()
            output_srs.ImportFromEPSG(
                int(gdtcsrs.Srs(output_srs_string).as_epsg_number()))
        else:
            output_srs = input_srs

        db = gdtcdb.db_factory(self.get_outputs()[0])
        db_connection_string = db.to_ogr_connection_string()
        conn = ogr.Open(db_connection_string)
        # TODO: Consider a mode where OVERWRITE is not always YES?
        output_layer = conn.CreateLayer(self.get_outputs()[0]['db_table'],
                                        output_srs, geometry_type,
                                        ['OVERWRITE=YES'])

        # Create table fields from those in the shapefile
        input_layer_defn = input_layer.GetLayerDefn()
        for i in range(0, input_layer_defn.GetFieldCount()):
            field_defn = input_layer_defn.GetFieldDefn(i)
            output_layer.CreateField(field_defn)

        # Add features from the input layer to the database table (output layer)
        output_layer_defn = output_layer.GetLayerDefn()
        for input_feature in input_layer:
            # Create output Feature
            output_feature = ogr.Feature(output_layer_defn)

            # Add field values from input Layer
            for i in range(0, output_layer_defn.GetFieldCount()):
                output_feature.SetField(
                    output_layer_defn.GetFieldDefn(i).GetNameRef(),
                    input_feature.GetField(i))

            # Set geometry
            geom = input_feature.GetGeometryRef()
            # Upgrade to multipolygon if polygon
            if geom.GetGeometryType() == ogr.wkbPolygon:
                geom = ogr.ForceToMultiPolygon(geom)
            output_feature.SetGeometry(geom.Clone())
            # Add new feature to output Layer
            output_layer.CreateFeature(output_feature)
            output_feature = None

        # This is required to close, and for the output to save, the data sources
        input_data_source = None
        conn = None
Esempio n. 7
0
import json
import logging
import pickle
import numpy as np
from osgeo import gdal
from gdalconst import GA_ReadOnly
from glob import glob
from datetime import datetime, timedelta

import isce
from iscesys.Component.ProductManager import ProductManager as PM

from .utils import get_bperp, gdal_translate, get_geocoded_coords


gdal.UseExceptions() # make GDAL raise python exceptions


log_format = "[%(asctime)s: %(levelname)s/%(name)s/%(funcName)s] %(message)s"
logging.basicConfig(format=log_format, level=logging.INFO)
logger = logging.getLogger(os.path.splitext(os.path.basename(__file__))[0])


DT_RE = re.compile(r'^(\d{4})-(\d{2})-(\d{2})')
S1_RE = re.compile(r'^S1\w$')

PLATFORMS = {
    "S1A": "Sentinel-1A",
    "S1B": "Sentinel-1B",
}
    def loadImgButtClick(self):
        print('loadImgButtClick button pressed')
        self.outputText.insert(tk.END, '\nloadImgButtClick button pressed')
        self.outputText.see(tk.END)
        imgpath = self.requestImgEntryVar.get()
        if len(self.requestImgEntry.get()) != 0:
            # Get file size
            filesize = os.path.getsize(imgpath)
            print('The image filesize is: %f' % filesize)
            self.outputText.insert(tk.END,
                                   '\nThe image filesize is: %f' % filesize)
            if filesize / 1e9 >= 4:
                answer = messagebox.askquestion(
                    "Resize Image",
                    "The current image size is too large to display/process. Do you want to resize image?",
                    icon='warning')
                if answer == 'yes':
                    imgpath = self.resizeImage(imgpath)
                elif answer == 'no':
                    print('Did not compress and display image.')
                    self.outputText.insert(
                        tk.END, '\nDid not compress and display image.')
                    self.outputText.see(tk.END)
                    return

            try:
                if imgpath[-4:] == '.tif':
                    # this allows GDAL to throw Python Exceptions
                    gdal.UseExceptions()

                    try:
                        src_ds = gdal.Open(imgpath)
                    except RuntimeError as e:
                        print('Unable to open ( %s )' % imgpath)
                        mystring = '\nUnable to open ( %s )' % imgpath
                        self.outputText.insert(tk.END, mystring)
                        self.outputText.see(tk.END)
                        print(e)
                        sys.exit(1)

                    try:
                        redband = src_ds.GetRasterBand(
                            1)  # Get the red band raster data out
                        redband = redband.ReadAsArray(
                        )  # Convert the red band data into array
                    except RuntimeError as e:
                        print('Band 1 ( Red ) not found')
                        self.outputText.insert(tk.END,
                                               '\nBand 1 ( Red ) not found')
                        self.outputText.see(tk.END)
                        print(e)
                        sys.exit(1)

                    try:
                        greenband = src_ds.GetRasterBand(
                            2)  # Get the green band raster data out
                        greenband = greenband.ReadAsArray(
                        )  # Convert the green band data into array
                    except RuntimeError as e:
                        print('Band 2 ( Green ) not found')
                        self.outputText.insert(tk.END,
                                               '\nBand 2 ( Green ) not found')
                        self.outputText.see(tk.END)
                        print(e)
                        sys.exit(1)

                    try:
                        blueband = src_ds.GetRasterBand(
                            3)  # Get the blue band raster data out
                        blueband = blueband.ReadAsArray(
                        )  # Convert the blue band data into array
                    except RuntimeError as e:
                        print('Band 3 ( Blue ) not found')
                        self.outputText.insert(tk.END,
                                               '\nBand 3 ( Blue ) not found')
                        self.outputText.see(tk.END)
                        print(e)
                        sys.exit(1)

                    # Show the image in GUI
                    img = Image.open(imgpath)  # Convert the tiff image
                    self.img_copy = img.copy()
                    labelWidth = self.imgPanel.winfo_width(
                    ) - 100  # Get the image panel Width
                    labelHeight = self.imgPanel.winfo_height(
                    ) - 100  # Get the image panel Height
                    maxsize = (
                        labelWidth, labelHeight
                    )  # Create a tuple for the image panel diamensions
                    img = img.resize(
                        maxsize)  # Resize the image to fit the image panel
                    img = ImageTk.PhotoImage(
                        img)  # Convert the image into a tkinker image
                    self.imgPanel.configure(
                        image=img)  # Set the image into the image panel
                    self.imgPanel.image = img  # Set the image into the image panel 2 (MUST DO)
                    self.update()

                elif imgpath[-4:] == '.jpg' or imgpath[
                        -4:] == '.JPG' or imgpath[-4:] == '.png' or imgpath[
                            -4:] == '.PNG':
                    img = Image.open(imgpath)  # Open the image
                    self.img_copy = img.copy()
                    labelWidth = self.imgPanel.winfo_width(
                    )  # Get the image panel Width
                    labelHeight = self.imgPanel.winfo_height(
                    )  # Get the image panel Height
                    maxsize = (
                        labelWidth, labelHeight
                    )  # Create a tuple for the image panel diamensions
                    img = img.resize(
                        maxsize)  # Resize the image to fit the image panel
                    img = ImageTk.PhotoImage(
                        img)  # Convert the image into a tkinker image
                    self.imgPanel.configure(
                        image=img)  # Set the image into the image panel
                    self.imgPanel.image = img  # Set the image into the image panel 2 (MUST DO)

            except Exception as e:
                # logger.error('Unable to load image: ' + str(e))
                print('Unable to load image: ' + str(e))
                mystring = '\nUnable to load image: ' + str(e)
                self.outputText.insert(tk.END, mystring)
                self.outputText.see(tk.END)
                return

        else:
            print('No Image to load')
Esempio n. 9
0
    def __init__(
            self,
            host="localhost",
            port=5432,
            db_name="postgis",
            user="******",
            password="******",
            views_included=1,
            dico_dataset=OrderedDict(),
            txt=dict(),
    ):
        """Uses gdal/ogr functions to extract basic informations about
        geographic file (handles shapefile or MapInfo tables)
        and store into the dictionaries.

        layer = path to the geographic file
        dico_dataset = dictionary for global informations
        dico_fields = dictionary for the fields' informations
        tipo = feature type to read
        text = dictionary of texts to display
        """
        # handling GDAL/OGR specific exceptions
        gdal.AllRegister()
        ogr.UseExceptions()
        gdal.UseExceptions()

        # Creating variables
        self.dico_dataset = dico_dataset
        self.txt = txt
        self.alert = 0
        if views_included:
            gdal.SetConfigOption(str("PG_LIST_ALL_TABLES"), str("YES"))
            logger.info("PostgreSQL views enabled.")
        else:
            gdal.SetConfigOption(str("PG_LIST_ALL_TABLES"), str("NO"))
            logger.info("PostgreSQL views disabled.")

        # connection infos
        self.host = host
        self.port = port
        self.db_name = db_name
        self.user = user
        self.password = password
        self.conn_settings = "PG: host={} port={} dbname={} user={} password={}".format(
            host, port, db_name, user, password)

        # testing connection
        self.conn = self.get_connection()
        if not self.conn:
            self.alert += 1
            youtils.erratum(
                ctner=dico_dataset,
                mess_type=1,
                ds_lyr=self.conn_settings,
                mess="err_connection_failed",
            )
            dico_dataset["err_gdal"] = gdal_err.err_type, gdal_err.err_msg
            return None
        else:
            pass

        # sgbd info
        dico_dataset["sgbd_version"] = self.get_version()
        dico_dataset["sgbd_schemas"] = self.get_schemas()
Esempio n. 10
0
    def _lp_characteristics(self, lp_fn):
        """Get LP characteristics to check.

        :param lp_fn: input lp raster file

        :return dict: lp characteristics
        """
        import numpy as np
        from osgeo import gdal, gdal_array, osr
        from osgeo import gdalconst
        gdal.UseExceptions()

        lp_characteristics = {}

        try:
            ids = gdal.Open(lp_fn, gdalconst.GA_ReadOnly)
            lp_characteristics['read'] = True
        except RuntimeError:
            lp_characteristics['read'] = False
            return lp_characteristics

        # Spatial resolution
        ids = gdal.Open(lp_fn, gdalconst.GA_ReadOnly)
        img_array = ids.ReadAsArray()
        geotransform = list(ids.GetGeoTransform())
        lp_characteristics['xRes'] = abs(geotransform[1])
        lp_characteristics['yRes'] = abs(geotransform[5])

        # Projection
        proj = osr.SpatialReference(wkt=ids.GetProjection())
        map_epsg = (proj.GetAttrValue('AUTHORITY', 1))
        lp_characteristics['epsg'] = map_epsg

        # Coding data type
        map_dtype = gdal_array.GDALTypeCodeToNumericTypeCode(
            ids.GetRasterBand(1).DataType)
        if (map_dtype == np.dtype('uint8')):
            lp_characteristics['dataType'] = 'u8'
        else:
            lp_characteristics['dataType'] = str(ids.GetRasterBand(1).DataType)

        # Map extent in the 'map_epsg'
        ulx, xres, xskew, uly, yskew, yres = ids.GetGeoTransform()
        lrx = ulx + (ids.RasterXSize * xres)
        lry = uly + (ids.RasterYSize * yres)
        lp_characteristics['extentUlLr'] = [ulx, uly, lrx, lry]

        # Do spatial overlay
        aoi_polygon = os.path.join(self.config['map_product']['path'],
                                   self.config['map_product']['map_aoi'])
        coding_val = []
        for prod in self.config['land_product']['product_type']:
            for val in self.config['land_product']['raster_coding'][prod]:
                coding_val.append(
                    self.config['land_product']['raster_coding'][prod][val])
        lp_min = min(coding_val)
        lp_max = max(coding_val)
        unclassifiable = self.config['land_product']['raster_coding'][
            'unclassifiable']
        out_of_aoi = self.config['land_product']['raster_coding']['out_of_aoi']
        lp_characteristics['aoiCoveragePct'] = self._calc_aoiCoveragePct(
            aoi_polygon, lp_fn, lp_min, lp_max, unclassifiable, out_of_aoi)
        # Map format
        raster_format = lp_fn.split('.')[-1]
        if raster_format == 'tif':
            raster_format = "GeoTIFF"
        lp_characteristics['rasterFormat'] = raster_format

        return lp_characteristics
Esempio n. 11
0
def run():
    """
    Run tests of a number of more common output format drivers
    """
    riostestutils.reportStart(TESTNAME)

    usingExceptions = gdal.GetUseExceptions()
    gdal.UseExceptions()

    driverTestList = [
        ('HFA', ['COMPRESS=YES'], '.img'),
        ('GTiff', ['COMPRESS=LZW', 'TILED=YES', 'INTERLEAVE=BAND'], '.tif'),
        ('ENVI', ['INTERLEAVE=BSQ'], ''), ('KEA', [], '.kea')
    ]
    # Remove any which current GDAL not suporting
    driverTestList = [(drvrName, options, suffix)
                      for (drvrName, options, suffix) in driverTestList
                      if gdal.GetDriverByName(drvrName) is not None]
    riostestutils.report(
        TESTNAME,
        'Testing drivers {}'.format(str([d[0] for d in driverTestList])))

    filename = 'test.img'
    riostestutils.genRampImageFile(filename)

    ok = True
    outfileList = []
    errorList = []
    for (drvr, creationOptions, suffix) in driverTestList:
        infiles = applier.FilenameAssociations()
        outfiles = applier.FilenameAssociations()
        infiles.inimg = filename
        outfiles.outimg = "testout" + suffix
        outfileList.append(outfiles.outimg)

        controls = applier.ApplierControls()
        controls.setOutputDriverName(drvr)

        try:
            applier.apply(copyImg, infiles, outfiles, controls=controls)
        except Exception as e:
            ok = False
            errorList.append("{}:{}".format(drvr, str(e)))

    if ok:
        riostestutils.report(TESTNAME, "Passed")
    else:
        riostestutils.report(
            TESTNAME, "Resulted in these apparent errors:\n  {}".format(
                '\n  '.join(errorList)))

    for fn in [filename] + outfileList:
        if os.path.exists(fn):
            drvr = gdal.Open(fn).GetDriver()


#            drvr.Delete(fn)

    if not usingExceptions:
        gdal.DontUseExceptions()

    return ok
Esempio n. 12
0
def Write_Dict_To_Shapefile_osgeo(totalList, shapefileName, EPSG):
    '''
    Adapted from
    https://github.com/GeoscienceAustralia/LidarProcessingScripts/RasterIndexTool_GDAL.py
    This function takes a list of dictionaries where each row in the list
    is a feature consisting of the X/Y geometries in the dictionary for each
    item in the list.

    Arguments:
    totalList     -- List of dictionaries
    shapefileName -- Name of the shapefile to be created/overwritten


    '''
    gdal.UseExceptions()

    shapePath = os.path.join(workspace, shapefileName)

    # Get driver
    driver = ogr.GetDriverByName('ESRI Shapefile')

    # Create shapeData, overwrite the data if it exists
    os.chdir(workspace)
    if os.path.exists(shapefileName):
        print 'Shapefile exists and will be deleted'
        driver.DeleteDataSource(shapePath)
        assert not os.path.exists(shapePath)

    shapeData = driver.CreateDataSource(shapefileName)

    # Create spatialReference for output
    outputspatialRef = osr.SpatialReference()

    # Set coordinate reference system to GDA94/MGA zone 56
    outputspatialRef.ImportFromEPSG(EPSG)

    # Create layer
    layer = shapeData.CreateLayer(shapePath,
                                  srs=outputspatialRef,
                                  geom_type=ogr.wkbPolygon)

    # add fields
    fieldNames = ["Date", "Time"]
    for n in range(0, len(fieldNames)):

        # add short text fields - convoluted method but was more extensive
        # in Jonah's script to capture more fields and various field types.
        if fieldNames[n] in ["Date", "Time"]:
            fieldstring = str(fieldNames[n])
            field_name = ogr.FieldDefn(fieldstring, ogr.OFTString)
            field_name.SetWidth(24)
            layer.CreateField(field_name)

    # Create polyline object
    ring = ogr.Geometry(ogr.wkbLinearRing)
    count = 0
    for entry in totalList:
        logAndprint('Row {0} being processed'.format(count))
        dictCounter = 0
        #        while dictCounter < 10:
        logAndprint('Dictionary count {0}'.format(len(totalList[count])))
        for key, value in totalList[count].iteritems():
            logAndprint('\n{0} row, {1} vertex being created'.format(
                count, dictCounter))
            logAndprint('\tKey: {0}, value: {1}'.format(key, value))
            #        print count
            if dictCounter < 2:
                logAndprint('\tRow passed')
                pass
                dictCounter += 1

            else:
                ring.AddPoint(float(key), float(value))
                logAndprint('\t\t{0} and {1} vertex added to ring'.format(
                    key, value))
                dictCounter += 1

        poly = ogr.Geometry(ogr.wkbPolygon)
        logAndprint('Adding geometry')
        poly.AddGeometry(ring)

        # Create feature
        layerDefinition = layer.GetLayerDefn()
        feature = ogr.Feature(layerDefinition)
        feature.SetGeometry(poly)
        # Set the FID field to the count
        feature.SetFID(count)

        # Calculate fields
        logAndprint('Calculating "Date" & "Time" fields')

        # Date is supplied in YYYY/MM/DD
        date = str(totalList[count].keys()[1].split()[0])
        # For animation in ArcGIS the date needs to be in the form
        # DD/MM/YYYY
        reformattedDate = (date.split('/')[2] + '/' + date.split('/')[1] +
                           '/' + date.split('/')[0])
        logAndprint('reformatted date:' + reformattedDate)
        feature.SetField('Date', str(reformattedDate))
        feature.SetField('Time', str(totalList[count].keys()[1].split()[1]))

        # Save feature
        layer.CreateFeature(feature)

        logAndprint('{0} rows processed'.format(count))
        count += 1

        # Empty the ring otherwise the vertices are accumulatied
        ring.Empty()

    # Cleanup
    poly.Destroy()
    feature.Destroy()

    # Cleanup
    shapeData.Destroy()
    # Return
    return shapePath
Esempio n. 13
0
 def __init__(self):
     # this allows GDAL to throw Python Exceptions
     gdal.UseExceptions()
Esempio n. 14
0
def main():
    gdal.UseExceptions()  # Enable errors

    #####  load user configurable paramters here    #######
    # Check user defined configuraiton file
    if len(sys.argv) == 1:
        print('ERROR: main.py requires one argument [configuration file] (i.e. python main.py vtu2geo_config.py)')
        return

    # Get name of configuration file/module
    configfile = sys.argv[1]

    # Load in configuration file as module
    X = imp.load_source('',configfile)


    # if a 2nd command line argument is present, it is the input_path so use that, otherwise try to use the one from passed script
    input_path = ''
    if len(sys.argv) == 3: # we have a 2nd CLI arg
        input_path = sys.argv[2]
        if hasattr(X,'input_path'):
            print 'Warning: Overwriting script defined input path with CL path'
    elif hasattr(X,'input_path'):
        input_path = X.input_path
    else:
        print('ERROR: No input path. A pvd or vtu file must be specified.')
        exit(-1)

    if os.path.isdir(input_path):
        print('ERROR: Either a pvd or vtu file must be specified.')
        exit(-1)

    variables = X.variables

    parameters = []
    if hasattr(X,'parameters'):
        parameters = X.parameters

    # Check if we want to constrain output to a example geotif
    constrain_flag = False
    if hasattr(X,'constrain_tif_file'):
        constrain_tif_file = X.constrain_tif_file
        var_resample_method = X.var_resample_method
        param_resample_method = X.param_resample_method
        constrain_flag = True

    output_path = input_path[:input_path.rfind('/')+1]

    if hasattr(X,'output_path'):
        output_path = X.output_path

    pixel_size = 10
    if hasattr(X,'pixel_size'):
        pixel_size = X.pixel_size
    else:
        print 'Default pixel size of 10 mx10 m will be used.'

    user_define_extent = False
    if hasattr(X,'user_define_extent'):
        user_define_extent = X.user_define_extent

    #Produces a lat/long regular grid in CF netCDF format instead of the TIF files
    nc_archive = False
    if hasattr(X,'nc_archive'):
        nc_archive = X.nc_archive

    #user defined output EPSG to use instead of the proj4 as defined in the vtu
    out_EPSG = None
    if hasattr(X,'out_EPSG'):
        out_EPSG = X.out_EPSG

    if parameters is not None and nc_archive:
        print('Parameters are ignored when writing the nc archive.')
        parameters = []

    all_touched = True
    if hasattr(X,'all_touched'):
        all_touched = X.all_touched

    #####
    reader = vtk.vtkXMLUnstructuredGridReader()

    # see if we were given a single vtu file or a pvd xml file
    filename, file_extension = os.path.splitext(input_path)
    is_pvd = False
    pvd = [input_path] # if not given a pvd file, make this iterable for the below code
    timesteps=None
    if file_extension == '.pvd':
        print 'Detected pvd file, processing all linked vtu files'
        is_pvd = True
        parse = ET.parse(input_path)
        pvd = parse.findall(".//*[@file]")

        timesteps = parse.findall(".//*[@timestep]")


    # Get info for constrained output extent/resolution if selected
    if constrain_flag :
        ex_ds = gdal.Open(constrain_tif_file,GA_ReadOnly)
        gt = ex_ds.GetGeoTransform()
        pixel_width = np.abs(gt[1])
        pixel_height = np.abs(gt[5])
        # Take extent from user input
        if user_define_extent:
            o_xmin = X.o_xmin
            o_xmax = X.o_xmax
            o_ymin = X.o_ymin
            o_ymax = X.o_ymax
        else: # Get extent for clipping from input tif
            o_xmin = gt[0]
            o_ymax = gt[3]
            o_xmax = o_xmin + gt[1] * ex_ds.RasterXSize
            o_ymin = o_ymax + gt[5] * ex_ds.RasterYSize

        print "Output pixel size is " + str(pixel_width) + " by " + str(pixel_height)
        ex_ds = None

    if constrain_flag:
        print(" Constrain flag currently not supported!")
        return -1


    files_processed=1 # this really should be 1 for useful output

    #information to build up the nc meta data
    nc_rasters = {}
    for v in variables:
        nc_rasters[v]=[]

    nc_time_counter=0
    tifs_to_remove = []
    epoch=np.datetime64(0,'s')

    # if we are loading a pvd, we have access to the timestep information if we want to build
    if is_pvd and timesteps is not None:
        epoch = np.datetime64(int(timesteps[0].get('timestep')),'s')

    dt=1 # model timestep, in seconds

    if timesteps is not None and len(timesteps) > 1:
        dt = int(timesteps[1].get('timestep')) - int(timesteps[0].get('timestep'))


    print('Start epoch: %s, model dt = %i (s)' %(epoch,dt))

    #because of how the netcdf is built we hold a file of file handles before converting. ensure we can do so
    soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
    total_output_files = len(pvd) * (len(variables)+len(parameters))
    if soft < total_output_files or hard < total_output_files:
        print('The users soft or hard file limit is less than the total number of tmp files to be created.')
        print('The system ulimit should be raised to at least ' + total_output_files)
        return -1

    for vtu in pvd:
        path = vtu
        vtu_file = ''
        if is_pvd:
            vtu_file  = vtu.get('file')
            path = input_path[:input_path.rfind('/')+1] + vtu_file
        else:
            base = os.path.basename(path) # since we have a full path to vtu, we need to get just the vtu filename
            vtu_file = os.path.splitext(base)[0] #we strip out vtu later so keep here


        printProgress(files_processed,len(pvd),decimals=0)
        reader.SetFileName(path)

        #shut up a deprecated warning from vtk 8.1
        with stdchannel_redirected(sys.stderr, os.devnull):
            reader.Update()

        mesh = reader.GetOutput()

        #default the pixel size to (min+max)/2
        if not pixel_size:
            area_range = mesh.GetCellData().GetArray('Area').GetRange()
            pixel_size = (math.sqrt(area_range[0]) + math.sqrt(area_range[1]))/2
            pixel_size = int( math.ceil(pixel_size) )

        driver = ogr.GetDriverByName('Memory')
        output_usm = driver.CreateDataSource('out')

        srsin = osr.SpatialReference()

        if not mesh.GetFieldData().HasArray("proj4"):
            print "VTU file does not contain a proj4 field"
            return -1

        vtu_proj4 = mesh.GetFieldData().GetAbstractArray("proj4").GetValue(0)
        srsin.ImportFromProj4(vtu_proj4)

        is_geographic = srsin.IsGeographic()

        #output conic equal area for geotiff
        srsout = osr.SpatialReference()
        srsout.ImportFromProj4(vtu_proj4)

        if out_EPSG:
            srsout.ImportFromEPSG(out_EPSG)

        trans = osr.CoordinateTransformation(srsin,srsout)
        layer = output_usm.CreateLayer('poly', srsout, ogr.wkbPolygon)
        cd = mesh.GetCellData()

        for i in range(0,cd.GetNumberOfArrays()):
            layer.CreateField(ogr.FieldDefn(cd.GetArrayName(i), ogr.OFTReal))

        #build the triangulation geometery
        for i in range(0, mesh.GetNumberOfCells()):
            v0 = mesh.GetCell(i).GetPointId(0)
            v1 = mesh.GetCell(i).GetPointId(1)
            v2 = mesh.GetCell(i).GetPointId(2)

            ring = ogr.Geometry(ogr.wkbLinearRing)
            if is_geographic:
                scale = 100000.  #undo the scaling that CHM does for the paraview output
                ring.AddPoint( mesh.GetPoint(v0)[0] / scale, mesh.GetPoint(v0)[1] / scale)
                ring.AddPoint (mesh.GetPoint(v1)[0]/ scale, mesh.GetPoint(v1)[1]/ scale )
                ring.AddPoint( mesh.GetPoint(v2)[0]/ scale, mesh.GetPoint(v2)[1]/ scale )
                ring.AddPoint( mesh.GetPoint(v0)[0]/ scale, mesh.GetPoint(v0)[1]/ scale ) # add again to complete the ring.
            else:
                ring.AddPoint( mesh.GetPoint(v0)[0], mesh.GetPoint(v0)[1] )
                ring.AddPoint (mesh.GetPoint(v1)[0], mesh.GetPoint(v1)[1] )
                ring.AddPoint( mesh.GetPoint(v2)[0], mesh.GetPoint(v2)[1] )
                ring.AddPoint( mesh.GetPoint(v0)[0], mesh.GetPoint(v0)[1] ) # add again to complete the ring.

            ring.Transform(trans)
            tpoly = ogr.Geometry(ogr.wkbPolygon)
            tpoly.AddGeometry(ring)

            feature = ogr.Feature( layer.GetLayerDefn() )
            feature.SetGeometry(tpoly)

            if variables is None:
                for j in range(0, cd.GetNumberOfArrays()):
                    name = cd.GetArrayName(j)
                    variables.append(name)

            for v in variables:
                try:
                    data = cd.GetArray(v).GetTuple(i)
                    feature.SetField(str(v), float(data[0]))
                except:
                    print "Variable %s not present in mesh" % v
                    return -1


            if parameters is not None:
                for p in parameters:
                    try:
                        data = cd.GetArray(p).GetTuple(i)
                        feature.SetField(str(p), float(data[0]))
                    except:
                        print "Parameter %s not present in mesh" % v
                        return -1
            layer.CreateFeature(feature)

        for var in variables:

            target_fname = os.path.join(output_path,
                                        vtu_file + '_' + var.replace(" ", "_") + str(pixel_size) + 'x' + str(
                                            pixel_size) + '.tif')
            rasterize(layer, srsout, target_fname, pixel_size, var,all_touched)

            if nc_archive:
                df = xr.open_rasterio(target_fname).sel(band=1).drop('band')
                df = df.rename({'x':'lon','y':'lat'})
                df.coords['time']=epoch + nc_time_counter*np.timedelta64(dt,'s') # this will automatically get converted to min or hours in the output nc
                df.name=var
                nc_rasters[var].append(df) # these are lazy loaded at the to netcdf call

                # remove the tifs we produce
                tifs_to_remove.append(target_fname)


            if parameters is not None:
                for p in parameters:
                    target_param_fname = os.path.join(output_path, vtu_file + '_'+ p.replace(" ","_") + str(pixel_size)+'x'+str(pixel_size)+'.tif')
                    rasterize(layer, srsout, target_fname, pixel_size, p,all_touched)

        nc_time_counter += 1
        # we don't need to dump parameters for each timestep as they are currently assumed invariant with time.
        parameters = None

        #no parameters and no variables, just exit at this point
        if not variables and parameters is None:
            break

        files_processed += 1

    if nc_archive:

        datasets = []

        for var, rasters in nc_rasters.iteritems():
            a = xr.concat(rasters,dim='time')
            datasets.append(a.to_dataset())

        arr = xr.merge(datasets)
        print('Writing netCDF file')
        fname=os.path.join(os.path.splitext(input_path)[0]+'.nc')
        arr.to_netcdf(fname,engine='netcdf4')

        for f in tifs_to_remove:
            try:
                os.remove(f)
            except:
                pass
Esempio n. 15
0
from math import pi
from itertools import count
import os
import re
from subprocess import CalledProcessError, check_output, Popen, PIPE
from tempfile import NamedTemporaryFile
from xml.etree import ElementTree

import numpy

from osgeo import gdal, gdalconst, osr
from osgeo.gdalconst import (GA_ReadOnly, GRA_Bilinear, GRA_Cubic,
                             GRA_CubicSpline, GRA_Lanczos,
                             GRA_NearestNeighbour)

gdal.UseExceptions()  # Make GDAL throw exceptions on error
osr.UseExceptions()  # And OSR as well.

from .constants import (EPSG_WEB_MERCATOR, ESRI_102113_PROJ, ESRI_102100_PROJ,
                        GDALTRANSLATE, GDALWARP, TILE_SIDE)
from .exceptions import (GdalError, CalledGdalError, UnalignedInputError,
                         UnknownResamplingMethodError)
from .types import Extents, GdalFormat, XY
from .utils import rmfile

logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())

RESAMPLING_METHODS = {
    GRA_NearestNeighbour: 'near',
    GRA_Bilinear: 'bilinear',
#OutputFolder
outFolder = 'layers'

#Check that the folder exists
if not os.path.exists(outFolder):
    os.makedirs(outFolder)

#os.chdir(outFolder)

#Emtpy the folder
#files = glob.glob(TKoutFolder + '\*')
#for f in files:
#    os.remove(f)

#Make error messages visible
gdal.UseExceptions()  #Fail when can't open!


def gdal_error_handler(err_class, err_num, err_msg):
    errtype = {
        gdal.CE_None: 'None',
        gdal.CE_Debug: 'Debug',
        gdal.CE_Warning: 'Warning',
        gdal.CE_Failure: 'Failure',
        gdal.CE_Fatal: 'Fatal'
    }
    err_msg = err_msg.replace('\n', ' ')
    err_class = errtype.get(err_class, 'None')
    print('Error Number: %s' % (err_num))
    print('Error Type: %s' % (err_class))
    print('Error Message: %s' % (err_msg))
Esempio n. 17
0
def changemap(ctx, map_type, start_date, end_date, output, root, result, image,
              date_frmt, ndv, gdal_frmt, out_date_frmt, warn_on_empty,
              magnitude):
    """
    Examples: TODO
    """
    from osgeo import gdal

    from ..mapping import get_change_date, get_change_num
    from ..utils import write_output

    gdal.AllRegister()
    gdal.UseExceptions()

    gdal_frmt = str(gdal_frmt)  # GDAL GetDriverByName doesn't work on Unicode

    frmt = '%Y%j'
    start_txt, end_txt = start_date.strftime(frmt), end_date.strftime(frmt)
    start_date, end_date = start_date.toordinal(), end_date.toordinal()

    try:
        image_ds = gdal.Open(image, gdal.GA_ReadOnly)
    except:
        logger.error('Could not open example image for reading')
        raise

    if map_type in ('first', 'last'):
        changemap, magnitudemap, magnitude_indices = get_change_date(
            start_date,
            end_date,
            result,
            image_ds,
            first=map_type == 'first',
            out_format=out_date_frmt,
            magnitude=magnitude,
            ndv=ndv,
            pattern='yatsm_r*',
            warn_on_empty=warn_on_empty)

        band_names = ['ChangeDate_s{s}-e{e}'.format(s=start_txt, e=end_txt)]
        write_output(changemap,
                     output,
                     image_ds,
                     gdal_frmt,
                     ndv,
                     band_names=band_names)

        if magnitudemap is not None:
            band_names = ([
                'Magnitude Index {}'.format(i) for i in magnitude_indices
            ])
            name, ext = os.path.splitext(output)
            output = name + '_mag' + ext
            write_output(magnitudemap,
                         output,
                         image_ds,
                         gdal_frmt,
                         ndv,
                         band_names=band_names)

    elif map_type == 'num':
        changemap = get_change_num(start_date,
                                   end_date,
                                   result,
                                   image_ds,
                                   ndv=ndv,
                                   pattern='yatsm_r*',
                                   warn_on_empty=warn_on_empty)

        band_names = ['NumChanges_s{s}-e{e}'.format(s=start_txt, e=end_txt)]
        write_output(changemap,
                     output,
                     image_ds,
                     gdal_frmt,
                     ndv,
                     band_names=band_names)

    image_ds = None
Esempio n. 18
0
def save_geopandas_tofile(inputGeoDataFrame, output_filename, overwrite=True, file_encoding='ascii'):
    """Save a geodataframe to file.
        - adds functionality to asses and rename columns to ESRI compatible 10 alpha-numeric characters.
        - Maps lists and boolean column types to string.

    Args:
        inputGeoDataFrame (geopandas.geodataframe.GeoDataFrame): The Geodataframe to save
        output_filename (str): The output filename
        overwrite (bool):  Overwrite Existing file
        file_encoding (str): encoding type for output file.

    """
    if not isinstance(inputGeoDataFrame, GeoDataFrame):
        raise TypeError('Invalid Type : inputGeodataFrame')

    # if out_shapefilename doesn't include a path then add tempdir as well as overwriting it
    if output_filename is not None and not os.path.isabs(output_filename):
        output_filename = os.path.join(TEMPDIR, output_filename)
        overwrite = True

    if os.path.exists(output_filename) and not overwrite:
        raise IOError('Output file ({}) already exists, and overwrite is false'.format(output_filename))

    if os.path.splitext(output_filename)[-1] != '.shp':
        raise NotImplementedError('Currently only support shapefiles.... ')

    step_time = time.time()
    driver = 'ESRI Shapefile'
    if driver == 'ESRI Shapefile':

        inputGeoDataFrame = inputGeoDataFrame.copy()
        fldProp = get_column_properties(inputGeoDataFrame)

        # get a list of either bool or list columns and convert to string.
        fix_cols = [(key, val['type']) for key, val in fldProp.items() if val['type'] in ['bool', 'list']]
        fix_cols += [(key, val['dtype']) for key, val in fldProp.items() if 'datetime' in val['dtype'].lower()]

        # Convert them to Strings
        for col, col_type in fix_cols:
            LOGGER.info('Converting column {} datatype from {} to str'.format(col, col_type))
            if col_type == 'list':
                inputGeoDataFrame[col] = inputGeoDataFrame[col].apply(lambda x: ",".join(map(str, x)))
            else:
                inputGeoDataFrame[col] = inputGeoDataFrame[col].astype(str)

        # rename columns to alias names. columns must be listed in the same order
        inputGeoDataFrame.columns = [val['shapefile'] for key, val in fldProp.items()]

        '''Saving to file sometimes throws an error similar to
        CPLE_AppDefined in Value xxxx of field Timestamp of feature xxxx not successfully written. Possibly due to too
        larger number with respect to field width. This is a known GDAL Error. The following two lines will hide this
        from the user but may hide other message.
        https://gis.stackexchange.com/a/68042 is also an option that works
        '''

        gdal.UseExceptions()
        gdal.PushErrorHandler('CPLQuietErrorHandler')
        if file_encoding == 'ascii':
            inputGeoDataFrame.to_file(output_filename, driver=driver)
        else:
            inputGeoDataFrame.to_file(output_filename, driver=driver, encoding=file_encoding)

    if config.get_debug_mode():
        LOGGER.info('{:<30} {:<15} {dur}'.format('Saved to file',output_filename,
                                              dur=datetime.timedelta(seconds=time.time() - step_time)))
Esempio n. 19
0
from osgeo import gdal, ogr, osr
from pyproj import Proj, transform, Transformer
import numpy as np
import sys
import importlib
from functools import partial
import itertools
from scipy import ndimage
from os import environ
from concurrent import futures
from tqdm import tqdm
import random
import time
import rasterio as rio

gdal.UseExceptions()  # Enable exception support


def main():
    #######  load user configurable paramters here    #######
    # Check user defined configuration file

    if len(sys.argv) == 1:
        print(
            'ERROR: wind_mapper.py requires one argument [configuration file] (i.e. wind_mapper.py '
            'param_existing_DEM.py)')
        exit(-1)

    # Get name of configuration file/module
    configfile = sys.argv[-1]
Esempio n. 20
0
def readSamples(DB, bands, Field="Class", NODATA=0):
    """
    TBC
    """
    # Initialization
    X, Y, P = [], [], []

    # Use gdal Exceptions
    gdal.UseExceptions()

    # Open DB with OGR
    driverOgr = ogr.GetDriverByName('SQLite')
    vectorIn = driverOgr.Open(DB, gdalconst.GA_ReadOnly)
    layerIn = vectorIn.GetLayer()

    # # Open raster with GDAL
    # rasterIn = gdal.Open(raster,gdalconst.GA_ReadOnly)
    # if rasterIn is None:
    #     print 'Impossible to open '+filename
    #     exit()

    # W,H,D= rasterIn.RasterXSize,rasterIn.RasterYSize,rasterIn.RasterCount
    # GeoTransform = rasterIn.GetGeoTransform()
    # Projection = rasterIn.GetProjection()
    # ox,oy = GeoTransform[0],GeoTransform[3]
    # sx,sy = GeoTransform[1],GeoTransform[5]

    # print "X={},Y={},D={}".format(W,H,D)

    # Iterate over features and store pixels position
    for feat in layerIn:
        geom = feat.GetGeometryRef()
        if feat.GetField("band_0") != NODATA:
            P.append([geom.GetX(), geom.GetY()])
            Y.append(feat.GetField(Field))
            X.append([feat.GetField(b) for b in bands])

        # pi_ = [sp.floor((Xc-ox)/sx).astype(int), sp.floor((Yc-oy)/sy).astype(int)]
        # if (pi_[0]>=0) and (pi_[0]<W) and (pi_[1]>=0) and (pi_[1]<H): # Check if the point is in the image
        #     pi.append(pi_)
        #     y.append(feat.GetField(Field))

    # # Filter NODATA values
    # band = rasterIn.GetRasterBand(1).ReadAsArray()
    # PI,Y=[],[]
    # for y_,pi_ in zip(y,pi):x
    #     if band[pi_[1], pi_[0]] > 0:
    #         PI.append(pi_)
    #         Y.append(y_)
    # del y,pi

    # # Load samples
    # ns = len(Y)
    # X = sp.empty((ns,bands.size))
    # print X.shape
    # for d_ in bands:
    #     print "Bands number {}".format(d_)
    #     band = rasterIn.GetRasterBand(d_+1).ReadAsArray()
    #     for p, pi_ in enumerate(PI):
    #         X[p, d_] = band[pi_[1], pi_[0]]

    return X, Y, P
Esempio n. 21
0
 def _create_base_map(self,):
     '''
     Deal with different types way to define the AOI, if none is specified, then the image bound is used.
     '''
     gdal.UseExceptions()
     ogr.UseExceptions() 
     if self.aoi is not None:
         if os.path.exists(self.aoi):
             try:     
                 g = gdal.Open(self.aoi)
                 #subprocess.call(['gdaltindex', '-f', 'GeoJSON',  '-t_srs', 'EPSG:4326', self.toa_dir + '/AOI.json', self.aoi])
                 geojson = get_boundary(self.aoi)[0]
                 with open(self.toa_dir + '/AOI.json', 'wb') as f:
                     f.write(geojson.encode())
             except:  
                 try: 
                     gr = ogr.Open(self.aoi)
                     l = gr.GetLayer(0)
                     f = l.GetFeature(0)
                     g = f.GetGeometryRef()                                                                                                
                 except:
                     raise IOError('AOI file cannot be opened by gdal, please check it or transform into format can be opened by gdal')
         else:        
             try:     
                 g = ogr.CreateGeometryFromJson(self.aoi)
             except:  
                 try: 
                     g = ogr.CreateGeometryFromGML(self.aoi)
                 except:
                     try:
                         g = ogr.CreateGeometryFromWkt(self.aoi)
                     except:
                         try:
                             g = ogr.CreateGeometryFromWkb(self.aoi)
                         except:
                             raise IOError('The AOI has to be one of GeoJSON, GML, Wkt or Wkb.')
         gjson_str = '''{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":%s}]}'''% g.ExportToJson()
         with open(self.toa_dir + '/AOI.json', 'wb') as f:
             f.write(gjson_str.encode())
     ogr.DontUseExceptions() 
     gdal.DontUseExceptions()
     if not os.path.exists(self.toa_dir + '/AOI.json'):
         #g = gdal.Open(self.toa_bands[0])
         #proj = g.GetProjection()
         #if 'WGS 84' in proj:
         #    subprocess.call(['gdaltindex', '-f', 'GeoJSON', self.toa_dir +'/AOI.json', self.toa_bands[0]])
         #else:
         #    subprocess.call(['gdaltindex', '-f', 'GeoJSON', '-t_srs', 'EPSG:4326', self.toa_dir +'/AOI.json', self.toa_bands[0]])
         if 'WGS 84' in proj:                                           
             #subprocess.call(['gdaltindex', '-f', 'GeoJSON', self.toa_dir +'/AOI.json', self.toa_bands[0]])
             geojson = get_boundary(self.toa_bands[0], to_wgs84 = False)                                                                                             
             with open(self.toa_dir + '/AOI.json', 'wb') as f:          
                 f.write(geojson.encode())                              
         else:                                                          
             #subprocess.call(['gdaltindex', '-f', 'GeoJSON', '-t_srs', 'EPSG:4326', self.toa_dir +'/AOI.json', self.toa_bands[0]])
             geojson = get_boundary(self.toa_bands[0])[0]               
             with open(self.toa_dir + '/AOI.json', 'wb') as f:          
                 f.write(geojson.encode()) 
         self.logger.warning('AOI is not created and full band extend is used')
         self.aoi = self.toa_dir + '/AOI.json'
     else:
         self.aoi = self.toa_dir + '/AOI.json'
def main():

    build_dirs()

    loss_tile_list = [
        '00N_000E', '00N_010E', '00N_010W', '00N_020E', '00N_020W', '00N_030E',
        '00N_030W', '00N_040E', '00N_040W', '00N_050E', '00N_050W', '00N_060E',
        '00N_060W', '00N_070E', '00N_070W', '00N_080E', '00N_080W', '00N_090E',
        '00N_090W', '00N_100E', '00N_100W', '00N_110E', '00N_110W', '00N_120E',
        '00N_120W', '00N_130E', '00N_130W', '00N_140E', '00N_140W', '00N_150E',
        '00N_150W', '00N_160E', '00N_160W', '00N_170E', '00N_170W', '00N_180W',
        '10N_000E', '10N_010E', '10N_010W', '10N_020E', '10N_020W', '10N_030E',
        '10N_030W', '10N_040E', '10N_040W', '10N_050E', '10N_050W', '10N_060E',
        '10N_060W', '10N_070E', '10N_070W', '10N_080E', '10N_080W', '10N_090E',
        '10N_090W', '10N_100E', '10N_100W', '10N_110E', '10N_110W', '10N_120E',
        '10N_120W', '10N_130E', '10N_130W', '10N_140E', '10N_140W', '10N_150E',
        '10N_150W', '10N_160E', '10N_160W', '10N_170E', '10N_170W', '10N_180W',
        '10S_000E', '10S_010E', '10S_010W', '10S_020E', '10S_020W', '10S_030E',
        '10S_030W', '10S_040E', '10S_040W', '10S_050E', '10S_050W', '10S_060E',
        '10S_060W', '10S_070E', '10S_070W', '10S_080E', '10S_080W', '10S_090E',
        '10S_090W', '10S_100E', '10S_100W', '10S_110E', '10S_110W', '10S_120E',
        '10S_120W', '10S_130E', '10S_130W', '10S_140E', '10S_140W', '10S_150E',
        '10S_150W', '10S_160E', '10S_160W', '10S_170E', '10S_170W', '10S_180W',
        '20N_000E', '20N_010E', '20N_010W', '20N_020E', '20N_020W', '20N_030E',
        '20N_030W', '20N_040E', '20N_040W', '20N_050E', '20N_050W', '20N_060E',
        '20N_060W', '20N_070E', '20N_070W', '20N_080E', '20N_080W', '20N_090E',
        '20N_090W', '20N_100E', '20N_100W', '20N_110E', '20N_110W', '20N_120E',
        '20N_120W', '20N_130E', '20N_130W', '20N_140E', '20N_140W', '20N_150E',
        '20N_150W', '20N_160E', '20N_160W', '20N_170E', '20N_170W', '20N_180W',
        '20S_000E', '20S_010E', '20S_010W', '20S_020E', '20S_020W', '20S_030E',
        '20S_030W', '20S_040E', '20S_040W', '20S_050E', '20S_050W', '20S_060E',
        '20S_060W', '20S_070E', '20S_070W', '20S_080E', '20S_080W', '20S_090E',
        '20S_090W', '20S_100E', '20S_100W', '20S_110E', '20S_110W', '20S_120E',
        '20S_120W', '20S_130E', '20S_130W', '20S_140E', '20S_140W', '20S_150E',
        '20S_150W', '20S_160E', '20S_160W', '20S_170E', '20S_170W', '20S_180W',
        '30N_000E', '30N_010E', '30N_010W', '30N_020E', '30N_020W', '30N_030E',
        '30N_030W', '30N_040E', '30N_040W', '30N_050E', '30N_050W', '30N_060E',
        '30N_060W', '30N_070E', '30N_070W', '30N_080E', '30N_080W', '30N_090E',
        '30N_090W', '30N_100E', '30N_100W', '30N_110E', '30N_110W', '30N_120E',
        '30N_120W', '30N_130E', '30N_130W', '30N_140E', '30N_140W', '30N_150E',
        '30N_150W', '30N_160E', '30N_160W', '30N_170E', '30N_170W', '30N_180W',
        '30S_000E', '30S_010E', '30S_010W', '30S_020E', '30S_020W', '30S_030E',
        '30S_030W', '30S_040E', '30S_040W', '30S_050E', '30S_050W', '30S_060E',
        '30S_060W', '30S_070E', '30S_070W', '30S_080E', '30S_080W', '30S_090E',
        '30S_090W', '30S_100E', '30S_100W', '30S_110E', '30S_110W', '30S_120E',
        '30S_120W', '30S_130E', '30S_130W', '30S_140E', '30S_140W', '30S_150E',
        '30S_150W', '30S_160E', '30S_160W', '30S_170E', '30S_170W', '30S_180W',
        '40N_000E', '40N_010E', '40N_010W', '40N_020E', '40N_020W', '40N_030E',
        '40N_030W', '40N_040E', '40N_040W', '40N_050E', '40N_050W', '40N_060E',
        '40N_060W', '40N_070E', '40N_070W', '40N_080E', '40N_080W', '40N_090E',
        '40N_090W', '40N_100E', '40N_100W', '40N_110E', '40N_110W', '40N_120E',
        '40N_120W', '40N_130E', '40N_130W', '40N_140E', '40N_140W', '40N_150E',
        '40N_150W', '40N_160E', '40N_160W', '40N_170E', '40N_170W', '40N_180W',
        '40S_000E', '40S_010E', '40S_010W', '40S_020E', '40S_020W', '40S_030E',
        '40S_030W', '40S_040E', '40S_040W', '40S_050E', '40S_050W', '40S_060E',
        '40S_060W', '40S_070E', '40S_070W', '40S_080E', '40S_080W', '40S_090E',
        '40S_090W', '40S_100E', '40S_100W', '40S_110E', '40S_110W', '40S_120E',
        '40S_120W', '40S_130E', '40S_130W', '40S_140E', '40S_140W', '40S_150E',
        '40S_150W', '40S_160E', '40S_160W', '40S_170E', '40S_170W', '40S_180W',
        '50N_000E', '50N_010E', '50N_010W', '50N_020E', '50N_020W', '50N_030E',
        '50N_030W', '50N_040E', '50N_040W', '50N_050E', '50N_050W', '50N_060E',
        '50N_060W', '50N_070E', '50N_070W', '50N_080E', '50N_080W', '50N_090E',
        '50N_090W', '50N_100E', '50N_100W', '50N_110E', '50N_110W', '50N_120E',
        '50N_120W', '50N_130E', '50N_130W', '50N_140E', '50N_140W', '50N_150E',
        '50N_150W', '50N_160E', '50N_160W', '50N_170E', '50N_170W', '50N_180W',
        '50S_000E', '50S_010E', '50S_010W', '50S_020E', '50S_020W', '50S_030E',
        '50S_030W', '50S_040E', '50S_040W', '50S_050E', '50S_050W', '50S_060E',
        '50S_060W', '50S_070E', '50S_070W', '50S_080E', '50S_080W', '50S_090E',
        '50S_090W', '50S_100E', '50S_100W', '50S_110E', '50S_110W', '50S_120E',
        '50S_120W', '50S_130E', '50S_130W', '50S_140E', '50S_140W', '50S_150E',
        '50S_150W', '50S_160E', '50S_160W', '50S_170E', '50S_170W', '50S_180W',
        '60N_000E', '60N_010E', '60N_010W', '60N_020E', '60N_020W', '60N_030E',
        '60N_030W', '60N_040E', '60N_040W', '60N_050E', '60N_050W', '60N_060E',
        '60N_060W', '60N_070E', '60N_070W', '60N_080E', '60N_080W', '60N_090E',
        '60N_090W', '60N_100E', '60N_100W', '60N_110E', '60N_110W', '60N_120E',
        '60N_120W', '60N_130E', '60N_130W', '60N_140E', '60N_140W', '60N_150E',
        '60N_150W', '60N_160E', '60N_160W', '60N_170E', '60N_170W', '60N_180W',
        '70N_000E', '70N_010E', '70N_010W', '70N_020E', '70N_020W', '70N_030E',
        '70N_030W', '70N_040E', '70N_040W', '70N_050E', '70N_050W', '70N_060E',
        '70N_060W', '70N_070E', '70N_070W', '70N_080E', '70N_080W', '70N_090E',
        '70N_090W', '70N_100E', '70N_100W', '70N_110E', '70N_110W', '70N_120E',
        '70N_120W', '70N_130E', '70N_130W', '70N_140E', '70N_140W', '70N_150E',
        '70N_150W', '70N_160E', '70N_160W', '70N_170E', '70N_170W', '70N_180W',
        '80N_000E', '80N_010E', '80N_010W', '80N_020E', '80N_020W', '80N_030E',
        '80N_030W', '80N_040E', '80N_040W', '80N_050E', '80N_050W', '80N_060E',
        '80N_060W', '80N_070E', '80N_070W', '80N_080E', '80N_080W', '80N_090E',
        '80N_090W', '80N_100E', '80N_100W', '80N_110E', '80N_110W', '80N_120E',
        '80N_120W', '80N_130E', '80N_130W', '80N_140E', '80N_140W', '80N_150E',
        '80N_150W', '80N_160E', '80N_160W', '80N_170E', '80N_170W', '80N_180W'
    ]

    template_url = r'http://glad.geog.umd.edu/Potapov/GFW_2017/tiles_2017/{}.tif'

    s3_output_dir = r's3://gfw2-data/alerts-tsv/loss_2017/'
    local_output_dir = r'/home/ubuntu/output/'

    output = r'/home/ubuntu/data/umd/loss/source/{0}.tif'
    nd_output = r'/home/ubuntu/data/umd/loss/processed/{0}.tif'

    gdal_warp_cmd = ['gdalwarp', '-co', 'COMPRESS=LZW', '-srcnodata', '0']
    gdal_warp_cmd += [
        '-dstnodata', '255', '--config', 'GDAL_CACHEMAX', '5%', '-overwrite'
    ]

    chunk_list = [x for x in chunks(loss_tile_list, 40)][list_index]

    for tile_name in chunk_list:
        url = template_url.format(tile_name)
        outfile = output.format(tile_name)

        cmd = ['wget', '-O', outfile, url]
        subprocess.check_call(cmd)

        gdal.UseExceptions()

        # Source: http://gis.stackexchange.com/questions/90726
        # open raster and choose band to find min, max
        gtif = gdal.Open(outfile)
        srcband = gtif.GetRasterBand(1)

        stats = srcband.GetStatistics(False, True)

        if len(set(stats)) == 1 and int(stats[0]) == 0:
            print 'No Data found for {}, skipping'.format(tile_name)

        else:
            processed_file = nd_output.format(tile_name)
            cmd2 = gdal_warp_cmd + [outfile, processed_file]

            print ' '.join(cmd2)
            subprocess.check_call(cmd2)

            # For the update with 2017 Hansen data (summer 2018), these biomass tiles were used:
            # s3://WHRC-carbon/global_27m_tiles/final_global_27m_tiles/biomass_10x10deg/{}_biomass.tif
            # For the update with 2018 Hansen data, we should use the below biomass tiles, which are v4 from Woods Hole (delivered summer 2018)
            biomass_s3 = r's3://WHRC-carbon/WHRC_V4/Processed/{}_biomass.tif'.format(
                tile_name)
            biomass_local = r'/home/ubuntu/data/emissions/{}.tif'.format(
                tile_name)
            biomass_cmd = ['aws', 's3', 'cp', biomass_s3, biomass_local]

            subprocess.check_call(biomass_cmd)

            extent_url = r'http://commondatastorage.googleapis.com/earthenginepartners-hansen/GFC2015/Hansen_GFC2015_treecover2000_{}.tif'.format(
                tile_name)
            extent_local = r'/home/ubuntu/data/extent2000/{}.tif'.format(
                tile_name)
            subprocess.check_call(['wget', '-O', extent_local, extent_url])

            ras_cwd = r'/home/ubuntu/raster-to-tsv'
            ras_to_vec_cmd = [
                'python', 'write-tsv.py', '--datasets', processed_file,
                extent_local, biomass_local, '--threads', '50', '--prefix',
                tile_name, '--separate', '--local-output-dir',
                local_output_dir, '--csv-process', 'area'
            ]
            subprocess.check_call(ras_to_vec_cmd, cwd=ras_cwd)

            for ras in [processed_file, extent_local, biomass_local]:
                os.remove(ras)

        os.remove(outfile)

        # upload all files in the local output dir
        # should be fast-- wait for all tsvs to finish, then use 64 threads to upload
        # configured using aws configure set default.s3.max_concurrent_requests 64
        cmd = [
            'aws', 's3', 'cp', '--recursive', local_output_dir, s3_output_dir
        ]
        subprocess.check_call(cmd)

        # delete TSVs
        files = glob.glob(local_output_dir + '*')
        for f in files:
            os.remove(f)
Esempio n. 23
0
def resample_geotiff(geotiff, width, outFormat, outFile, use_nn=False):

    # Check output format
    formats = ['GEOTIFF', 'JPEG', 'JPG', 'PNG', 'KML']
    if outFormat.upper() not in formats:
        raise ValueError(
            f'Unknown output format ({outFormat.upper()})! Accepted formats: {formats}'
        )
    if use_nn:
        resampleMethod = GRIORA_NearestNeighbour
    else:
        resampleMethod = GRIORA_Cubic

    # Suppress GDAL warnings
    gdal.UseExceptions()
    gdal.PushErrorHandler('CPLQuietErrorHandler')

    # Extract information from GeoTIFF
    raster = gdal.Open(geotiff)
    bandCount = raster.RasterCount
    band = raster.GetRasterBand(1)
    colorTable = band.GetColorTable()

    # Downsample by multiples of pixel size to avoid interpolation issues
    # (if needed)
    orgExt = os.path.splitext(outFile)[1]
    resampleFile = None
    resampleFile2 = None
    gt = raster.GetGeoTransform()
    cols = raster.RasterXSize
    # rows = raster.RasterYSize
    scale = cols / float(width)
    mult = 2**(math.floor(math.log(scale, 2)) - 1)

    if mult > 1:
        pixelWidth = gt[1] * mult
        pixelHeight = gt[5] * mult
        if outFormat.upper() == 'PNG' and bandCount == 3:
            tmpExt = ('_resamp{0}.png'.format(os.getpid()))
            resampleFile = outFile.replace(orgExt, tmpExt)
            tmpExt2 = ('_resamp2{0}.png'.format(os.getpid()))
            resampleFile2 = outFile.replace(orgExt, tmpExt2)
            gdal.Translate(resampleFile, raster, format='PNG', noData='0 0 0')
            gdal.Translate(resampleFile2,
                           resampleFile,
                           resampleAlg=resampleMethod,
                           format='PNG',
                           xRes=pixelWidth,
                           yRes=pixelHeight,
                           noData="0 0 0")
            raster = gdal.Open(resampleFile2)
        else:
            tmpExt = ('_resamp{0}.tif'.format(os.getpid()))
            resampleFile = outFile.replace(orgExt, tmpExt)
            gdal.Translate(resampleFile,
                           raster,
                           resampleAlg=resampleMethod,
                           xRes=pixelWidth,
                           yRes=pixelHeight,
                           noData="0")
            raster = gdal.Open(resampleFile)

    # Resample image using cubic interpolation
    # Save it in the various image formats
    if outFormat.upper() == 'GEOTIFF':
        gdal.Translate(outFile,
                       raster,
                       resampleAlg=resampleMethod,
                       width=width)
    elif outFormat.upper() == 'JPEG' or outFormat.upper() == 'JPG':
        if colorTable is None:
            gdal.Translate(outFile,
                           raster,
                           format='JPEG',
                           resampleAlg=resampleMethod,
                           width=width)
        else:
            gdal.Translate(outFile,
                           raster,
                           format='JPEG',
                           resampleAlg=resampleMethod,
                           width=width,
                           rgbExpand='RGB')
    elif outFormat.upper() == 'PNG':
        if bandCount == 1:
            gdal.Translate(outFile,
                           raster,
                           format='PNG',
                           resampleAlg=resampleMethod,
                           width=width,
                           noData='0')
        elif bandCount == 3:
            gdal.Translate(outFile,
                           raster,
                           format='PNG',
                           resampleAlg=resampleMethod,
                           width=width,
                           noData='0 0 0')
    elif outFormat.upper() == 'KML':

        # Reproject to geographic coordinates first
        tmpExt = ('_geo{0}.tif'.format(os.getpid()))
        tmpFile = outFile.replace(orgExt, tmpExt)
        rgbFile = None
        if bandCount == 1:
            if colorTable is None:
                gdal.Warp(tmpFile,
                          raster,
                          resampleAlg=GRIORA_Cubic,
                          width=width,
                          srcNodata='0',
                          dstSRS='EPSG:4326',
                          dstAlpha=True)
            else:
                rgbExt = ('_rgb{0}.tif'.format(os.getpid()))
                rgbFile = outFile.replace(orgExt, rgbExt)
                gdal.Translate(rgbFile, raster, rgbExpand='RGBA')
                raster = gdal.Open(rgbFile)
                gdal.Warp(tmpFile,
                          raster,
                          resampleAlg=GRIORA_Cubic,
                          width=width,
                          srcNodata='0',
                          dstSRS='EPSG:4326',
                          dstAlpha=True)
        elif bandCount == 3:
            gdal.Warp(tmpFile,
                      raster,
                      resampleAlg=GRIORA_Cubic,
                      width=width,
                      srcNodata='0 0 0',
                      dstSRS='EPSG:4326',
                      dstAlpha=True)
        raster = None

        # Convert GeoTIFF to PNG - since warp cannot do that in one step
        raster = gdal.Open(tmpFile)
        pngFile = outFile.replace(orgExt, '.png')
        gdal.Translate(pngFile,
                       raster,
                       format='PNG',
                       resampleAlg=resampleMethod)

        # Extract metadata from GeoTIFF to fill into the KML
        gt = raster.GetGeoTransform()
        coordStr = (
            '%.4f,%.4f %.4f,%.4f %.4f,%.4f %.4f,%.4f' %
            (gt[0], gt[3] + raster.RasterYSize * gt[5], gt[0] +
             raster.RasterXSize * gt[1], gt[3] + raster.RasterYSize * gt[5],
             gt[0] + raster.RasterXSize * gt[1], gt[3], gt[0], gt[3]))

        # Take care of namespaces
        prefix = {}
        gx = '{http://www.google.com/kml/ext/2.2}'
        prefix['gx'] = gx
        ns_gx = {'gx': 'http://www.google.com/kml/ext/2.2'}
        ns_main = {None: 'http://www.opengis.net/kml/2.2'}
        ns = dict(list(ns_main.items()) + list(ns_gx.items()))

        # Fill in the tree structure
        kmlFile = outFile.replace(orgExt, '.kml')
        kml = et.Element('kml', nsmap=ns)
        overlay = et.SubElement(kml, 'GroundOverlay')
        et.SubElement(overlay, 'name').text = \
          os.path.basename(kmlFile).replace('.kml', '') + ' overlay'
        icon = et.SubElement(overlay, 'Icon')
        et.SubElement(icon, 'href').text = os.path.basename(pngFile)
        et.SubElement(icon, 'viewBoundScale').text = '0.75'
        latLonQuad = et.SubElement(overlay, '{0}LatLonQuad'.format(gx))
        et.SubElement(latLonQuad, 'coordinates').text = coordStr
        with open(kmlFile, 'wb') as outF:
            outF.write(
                et.tostring(kml,
                            xml_declaration=True,
                            encoding='utf-8',
                            pretty_print=True))

        # Zip PNG and KML together - need to be in the directory where the files are
        # in order to remove any path issues...
        back = os.getcwd()
        path = os.path.dirname(outFile)
        if path != '':
            os.chdir(path)
        zipFile = os.path.basename(outFile.replace(orgExt, '.kmz'))
        zip = zipfile.ZipFile(zipFile, 'w', zipfile.ZIP_DEFLATED)
        zip.write(os.path.basename(kmlFile))
        zip.write(os.path.basename(pngFile))
        zip.close()
        os.chdir(back)

        # Clean up - remove temporary GeoTIFF, KML and PNG
        os.remove(tmpFile)
        os.remove(pngFile)
        os.remove(pngFile + '.aux.xml')
        os.remove(kmlFile)
        if rgbFile is not None:
            os.remove(rgbFile)

    if resampleFile is not None:
        for myfile in glob.glob("{0}*".format(resampleFile)):
            os.remove(myfile)

    if resampleFile2 is not None:
        for myfile in glob.glob("{0}*".format(resampleFile2)):
            os.remove(myfile)
Esempio n. 24
0
def main(image_ws, ini_path, blocksize=2048, smooth_flag=False,
         stats_flag=False, overwrite_flag=False):
    """Prep a Landsat scene for METRIC

    Parameters
    ----------
    image_ws : str
        Landsat scene folder that will be prepped.
    ini_path : str
        File path of the input parameters file.
    blocksize : int, optional
        Size of blocks to process (the default is 2048).
    smooth_flag : bool, optional
        If True, dilate/erode image to remove fringe/edge pixels
        (the default is False).
    stats_flag : bool, optional
        If True, compute raster statistics (the default is True).
    overwrite_flag : bool, optional
        If True, overwrite existing files (the default is False).

    Returns
    -------
    True is successful

    """

    # Open config file
    config = python_common.open_ini(ini_path)

    # Get input parameters
    logging.debug('  Reading Input File')
    calc_refl_toa_flag = python_common.read_param(
        'calc_refl_toa_flag', True, config, 'INPUTS')
    calc_refl_toa_qa_flag = python_common.read_param(
        'calc_refl_toa_qa_flag', True, config, 'INPUTS')
    # calc_refl_sur_ledaps_flag = python_common.read_param(
    #     'calc_refl_sur_ledaps_flag', False, config, 'INPUTS')
    # calc_refl_sur_qa_flag = python_common.read_param(
    #     'calc_refl_sur_qa_flag', False, config, 'INPUTS')
    calc_ts_bt_flag = python_common.read_param(
        'calc_ts_bt_flag', True, config, 'INPUTS')

    # Use QA band to set common area
    # Fmask cloud, shadow, & snow pixels will be removed from common area
    calc_fmask_common_flag = python_common.read_param(
        'calc_fmask_common_flag', True, config, 'INPUTS')
    fmask_buffer_flag = python_common.read_param(
        'fmask_buffer_flag', False, config, 'INPUTS')
    fmask_erode_flag = python_common.read_param(
        'fmask_erode_flag', False, config, 'INPUTS')
    if fmask_erode_flag:
        fmask_erode_cells = int(python_common.read_param(
            'fmask_erode_cells', 10, config, 'INPUTS'))
        if fmask_erode_cells == 0 and fmask_erode_flag:
            fmask_erode_flag = False
    # Number of cells to buffer Fmask clouds
    # For now use the same buffer radius and apply to
    if fmask_buffer_flag:
        fmask_buffer_cells = int(python_common.read_param(
            'fmask_buffer_cells', 25, config, 'INPUTS'))
        if fmask_buffer_cells == 0 and fmask_buffer_flag:
            fmask_buffer_flag = False
    # Include hand made cloud masks
    cloud_mask_flag = python_common.read_param(
        'cloud_mask_flag', False, config, 'INPUTS')
    cloud_mask_ws = ""
    if cloud_mask_flag:
        cloud_mask_ws = config.get('INPUTS', 'cloud_mask_ws')

    # Extract separate Fmask rasters
    calc_fmask_flag = python_common.read_param(
        'calc_fmask_flag', True, config, 'INPUTS')
    calc_fmask_cloud_flag = python_common.read_param(
        'calc_fmask_cloud_flag', True, config, 'INPUTS')
    calc_fmask_snow_flag = python_common.read_param(
        'calc_fmask_snow_flag', True, config, 'INPUTS')
    calc_fmask_water_flag = python_common.read_param(
        'calc_fmask_water_flag', True, config, 'INPUTS')

    # Keep Landsat DN, LEDAPS, and Fmask rasters
    keep_dn_flag = python_common.read_param(
        'keep_dn_flag', True, config, 'INPUTS')
    # keep_sr_flag = python_common.read_param(
    #     'keep_sr_flag', True, config, 'INPUTS')

    # For this to work I would need to pass in the metric input file
    # calc_elev_flag = python_common.read_param(
    #     'calc_elev_flag', False, config, 'INPUTS')
    # calc_landuse_flag = python_common.read_param(
    #     'calc_landuse_flag', False, config, 'INPUTS')

    # calc_acca_cloud_flag = python_common.read_param(
    #     'calc_acca_cloud_flag', True, config, 'INPUTS')
    # calc_acca_snow_flag = python_common.read_param(
    #     'calc_acca_snow_flag', True, config, 'INPUTS')
    # calc_ledaps_dem_land_flag = python_common.read_param(
    #     'calc_ledaps_dem_land_flag', False, config, 'INPUTS')
    # calc_ledaps_veg_flag = python_common.read_param(
    #     'calc_ledaps_veg_flag', False, config, 'INPUTS')
    # calc_ledaps_snow_flag = python_common.read_param(
    #     'calc_ledaps_snow_flag', False, config, 'INPUTS')
    # calc_ledaps_land_flag = python_common.read_param(
    #     'calc_ledaps_land_flag', False, config, 'INPUTS')
    # calc_ledaps_cloud_flag = python_common.read_param(
    #     'calc_ledaps_cloud_flag', False, config, 'INPUTS')

    # Interpolate/clip/project hourly rasters for each Landsat scene
    # calc_metric_flag = python_common.read_param(
    #     'calc_metric_flag', False, config, 'INPUTS')
    calc_metric_ea_flag = python_common.read_param(
        'calc_metric_ea_flag', False, config, 'INPUTS')
    calc_metric_wind_flag = python_common.read_param(
        'calc_metric_wind_flag', False, config, 'INPUTS')
    calc_metric_etr_flag = python_common.read_param(
        'calc_metric_etr_flag', False, config, 'INPUTS')
    calc_metric_tair_flag = python_common.read_param(
        'calc_metric_tair_flag', False, config, 'INPUTS')

    # Interpolate/clip/project AWC and daily ETr/PPT rasters
    # to compute SWB Ke for each Landsat scene
    calc_swb_ke_flag = python_common.read_param(
        'calc_swb_ke_flag', False, config, 'INPUTS')
    if cloud_mask_flag:
        spinup_days = python_common.read_param(
            'swb_spinup_days', 30, config, 'INPUTS')
        min_spinup_days = python_common.read_param(
            'swb_min_spinup_days', 5, config, 'INPUTS')

    # Round ea raster to N digits to save space
    rounding_digits = python_common.read_param(
        'rounding_digits', 3, config, 'INPUTS')

    env = drigo.env
    image = et_image.Image(image_ws, env)
    np.seterr(invalid='ignore', divide='ignore')
    gdal.UseExceptions()

    # Input file paths
    dn_image_dict = et_common.landsat_band_image_dict(
        image.orig_data_ws, image.image_re)

    # # Open METRIC config file
    # if config_file:
    #    logging.info(
    #        log_f.format('METRIC INI File:', os.path.basename(config_file)))
    #    config = configparser.ConfigParser()
    #    try:
    #        config.read(config_file)
    #    except:
    #        logging.error('\nERROR: Config file could not be read, ' +
    #                      'is not an input file, or does not exist\n' +
    #                      'ERROR: config_file = {}\n').format(config_file)
    #        sys.exit()
    #    #  Overwrite
    #    overwrite_flag = read_param('overwrite_flag', True, config)
    #
    #    #  Elevation and landuse parameters/flags from METRIC input file
    #    calc_elev_flag = read_param('save_dem_raster_flag', True, config)
    #    calc_landuse_flag = read_param(
    #        'save_landuse_raster_flag', True, config)
    #    if calc_elev_flag:
    #        elev_pr_path = config.get('INPUTS','dem_raster')
    #    if calc_landuse_flag:
    #        landuse_pr_path = config.get('INPUTS', 'landuse_raster')
    # else:
    #    overwrite_flag = False
    #    calc_elev_flag = False
    #    calc_landuse_flag = False
    #
    # Elev raster must exist
    # if calc_elev_flag and not os.path.isfile(elev_pr_path):
    #    logging.error('\nERROR: Elevation raster {} does not exist\n'.format(
    #        elev_pr_path))
    #    return False
    # Landuse raster must exist
    # if calc_landuse_flag and not os.path.isfile(landuse_pr_path):
    #    logging.error('\nERROR: Landuse raster {} does not exist\n'.format(
    #        landuse_pr_path))
    #    return False

    # Removing ancillary files before checking for inputs
    if os.path.isdir(os.path.join(image.orig_data_ws, 'gap_mask')):
        shutil.rmtree(os.path.join(image.orig_data_ws, 'gap_mask'))
    for item in os.listdir(image.orig_data_ws):
        if (image.type == 'Landsat7' and
            (item.endswith('_B8.TIF') or
             item.endswith('_B6_VCID_2.TIF'))):
            os.remove(os.path.join(image.orig_data_ws, item))
        elif (image.type == 'Landsat8' and
              (item.endswith('_B1.TIF') or
               item.endswith('_B8.TIF') or
               item.endswith('_B9.TIF') or
               item.endswith('_B11.TIF'))):
            os.remove(os.path.join(image.orig_data_ws, item))
        elif (item.endswith('_VER.jpg') or
              item.endswith('_VER.txt') or
              item.endswith('_GCP.txt') or
              item == 'README.GTF'):
            os.remove(os.path.join(image.orig_data_ws, item))

    # Check correction level (image must be L1T to process)
    if image.correction != 'L1TP':
        logging.debug('  Image is not L1TP corrected, skipping')
        return False
        # calc_fmask_common_flag = False
        # calc_refl_toa_flag = False
        # calc_ts_bt_flag = False
        # calc_metric_ea_flag = False
        # calc_metric_wind_flag = False
        # calc_metric_etr_flag = False
        # overwrite_flag = False

    # QA band must exist
    if (calc_fmask_common_flag and image.qa_band not in dn_image_dict.keys()):
        logging.warning(
            ('\nQA band does not exist but calc_fmask_common_flag=True' +
             '\n  Setting calc_fmask_common_flag=False\n  {}').format(
                 os.path.basename(image.qa_input_raster)))
        calc_fmask_common_flag = False
    if cloud_mask_flag and not os.path.isdir(cloud_mask_ws):
        logging.warning(
            ('\ncloud_mask_ws is not a directory but cloud_mask_flag=True.' +
             '\n  Setting cloud_mask_flag=False\n   {}').format(cloud_mask_ws))
        cloud_mask_flag = False

    # Check for Landsat TOA images
    if (calc_refl_toa_flag and
        (set(list(image.band_toa_dict.keys()) + [image.thermal_band, image.qa_band]) !=
            set(dn_image_dict.keys()))):
        logging.warning(
            '\nMissing Landsat images but calc_refl_toa_flag=True' +
            '\n  Setting calc_refl_toa_flag=False')
        calc_refl_toa_flag = False

    # Check for Landsat brightness temperature image
    if calc_ts_bt_flag and image.thermal_band not in dn_image_dict.keys():
        logging.warning(
            '\nThermal band image does not exist but calc_ts_bt_flag=True' +
            '\n  Setting calc_ts_bt_flag=False')
        calc_ts_bt_flag = False
        # DEADBEEF - Should the function return False if Ts doesn't exist?
        # return False

    # Check for METRIC hourly/daily input folders
    if calc_metric_ea_flag:
        metric_ea_input_ws = config.get('INPUTS', 'metric_ea_input_folder')
        if not os.path.isdir(metric_ea_input_ws):
            logging.warning(
                ('\nHourly Ea folder does not exist but calc_metric_ea_flag=True' +
                 '\n  Setting calc_metric_ea_flag=False\n  {}').format(
                     metric_ea_input_ws))
            calc_metric_ea_flag = False
    if calc_metric_wind_flag:
        metric_wind_input_ws = config.get('INPUTS', 'metric_wind_input_folder')
        if not os.path.isdir(metric_wind_input_ws):
            logging.warning(
                ('\nHourly wind folder does not exist but calc_metric_wind_flag=True' +
                 '\n  Setting calc_metric_wind_flag=False\n  {}').format(
                     metric_wind_input_ws))
            calc_metric_wind_flag = False
    if calc_metric_etr_flag:
        metric_etr_input_ws = config.get('INPUTS', 'metric_etr_input_folder')
        if not os.path.isdir(metric_etr_input_ws):
            logging.warning(
                ('\nHourly ETr folder does not exist but calc_metric_etr_flag=True' +
                 '\n  Setting calc_metric_etr_flag=False\n  {}').format(
                     metric_etr_input_ws))
            calc_metric_etr_flag = False
    if calc_metric_tair_flag:
        metric_tair_input_ws = config.get('INPUTS', 'metric_tair_input_folder')
        if not os.path.isdir(metric_tair_input_ws):
            logging.warning(
                ('\nHourly Tair folder does not exist but calc_metric_tair_flag=True' +
                 '\n  Setting calc_metric_tair_flag=False\n  {}').format(
                     metric_tair_input_ws))
            calc_metric_tair_flag = False
    if (calc_metric_ea_flag or calc_metric_wind_flag or
        calc_metric_etr_flag or calc_metric_tair_flag):
        metric_hourly_re = re.compile(config.get('INPUTS', 'metric_hourly_re'))
        metric_daily_re = re.compile(config.get('INPUTS', 'metric_daily_re'))

    if calc_swb_ke_flag:
        awc_input_path = config.get('INPUTS', 'awc_input_path')
        etr_input_ws = config.get('INPUTS', 'etr_input_folder')
        ppt_input_ws = config.get('INPUTS', 'ppt_input_folder')
        etr_input_re = re.compile(config.get('INPUTS', 'etr_input_re'))
        ppt_input_re = re.compile(config.get('INPUTS', 'ppt_input_re'))
        if not os.path.isfile(awc_input_path):
            logging.warning(
                ('\nAWC raster does not exist but calc_swb_ke_flag=True' +
                 '\n  Setting calc_swb_ke_flag=False\n  {}').format(
                     awc_input_path))
            calc_swb_ke_flag = False
        if not os.path.isdir(etr_input_ws):
            logging.warning(
                ('\nDaily ETr folder does not exist but calc_swb_ke_flag=True' +
                 '\n  Setting calc_swb_ke_flag=False\n  {}').format(
                     etr_input_ws))
            calc_swb_ke_flag = False
        if not os.path.isdir(ppt_input_ws):
            logging.warning(
                ('\nDaily PPT folder does not exist but calc_swb_ke_flag=True' +
                 '\n  Setting calc_swb_ke_flag=False\n  {}').format(
                     ppt_input_ws))
            calc_swb_ke_flag = False

    # Build folders for support rasters
    if ((calc_fmask_common_flag or calc_refl_toa_flag or
         # calc_refl_sur_ledaps_flag or
         calc_ts_bt_flag or
         calc_metric_ea_flag or calc_metric_wind_flag or
         calc_metric_etr_flag or calc_metric_tair_flag or
         calc_swb_ke_flag) and
        not os.path.isdir(image.support_ws)):
        os.makedirs(image.support_ws)
    if calc_refl_toa_flag and not os.path.isdir(image.refl_toa_ws):
        os.makedirs(image.refl_toa_ws)
    # if calc_refl_sur_ledaps_flag and not os.path.isdir(image.refl_sur_ws):
    #     os.makedirs(image.refl_sur_ws)

    # Apply overwrite flag
    if overwrite_flag:
        overwrite_list = [
            image.fmask_cloud_raster, image.fmask_snow_raster,
            image.fmask_water_raster
            # image.elev_raster, image.landuse_raster
            # image.common_area_raster
        ]
        for overwrite_path in overwrite_list:
            try:
                python_common.remove_file(image.fmask_cloud_raster)
            except:
                pass

    # Use QA band to build common area rasters
    logging.info('\nCommon Area Raster')
    qa_ds = gdal.Open(dn_image_dict[image.qa_band], 0)
    common_geo = drigo.raster_ds_geo(qa_ds)
    common_extent = drigo.raster_ds_extent(qa_ds)
    common_proj = drigo.raster_ds_proj(qa_ds)
    common_osr = drigo.raster_ds_osr(qa_ds)
    # Initialize common_area as all non-fill QA values
    qa_array = drigo.raster_ds_to_array(qa_ds, return_nodata=False)
    common_array = qa_array != 1
    common_rows, common_cols = common_array.shape
    del qa_ds


    # First try applying user defined cloud masks
    cloud_mask_path = os.path.join(
        cloud_mask_ws, image.folder_id + '_mask.shp')
    if cloud_mask_flag and os.path.isfile(cloud_mask_path):
        logging.info('  Applying cloud mask shapefile')
        feature_path = os.path.join(
            cloud_mask_ws, (image.folder_id + '_mask.shp'))
        logging.info('    {}'.format(feature_path))
        cloud_mask_memory_ds = drigo.polygon_to_raster_ds(
            feature_path, nodata_value=0, burn_value=1,
            output_osr=common_osr, output_cs=30,
            output_extent=common_extent)
        cloud_array = drigo.raster_ds_to_array(
            cloud_mask_memory_ds, return_nodata=False)
        # DEADBEEF - If user sets a cloud mask,
        #   it is probably better than Fmask
        # Eventually change "if" calc_fmask_common_flag: to "elif"
        common_array[cloud_array == 1] = 0
        del cloud_mask_memory_ds, cloud_array

    if calc_fmask_common_flag:
        fmask_array = et_numpy.bqa_fmask_func(qa_array)
        fmask_mask = (fmask_array >= 2) & (fmask_array <= 4)
        if fmask_erode_flag:
            logging.info(
                ('  Eroding and dilating Fmask clouds, shadows, and snow ' +
                 '{} cells\n    to remove errantly masked pixels.').format(
                    fmask_erode_cells))
            fmask_mask = ndimage.binary_erosion(
                fmask_mask, iterations=fmask_erode_cells,
                structure=ndimage.generate_binary_structure(2, 2))
            fmask_mask = ndimage.binary_dilation(
                fmask_mask, iterations=fmask_erode_cells,
                structure=ndimage.generate_binary_structure(2, 2))
        if fmask_buffer_flag:
            logging.info(
                ('  Buffering Fmask clouds, shadows, and snow ' +
                 '{} cells').format(fmask_buffer_cells))
            # Only buffer clouds, shadow, and snow (not water or nodata)
            if fmask_mask is None:
                fmask_mask = (fmask_array >= 2) & (fmask_array <= 4)
            fmask_mask = ndimage.binary_dilation(
                fmask_mask, iterations=fmask_buffer_cells,
                structure=ndimage.generate_binary_structure(2, 2))
        # Reset common_array for buffered cells
        common_array[fmask_mask] = 0
        del fmask_array, fmask_mask

    if common_array is not None:
        # Erode and dilate to remove fringe on edge
        # Default is to not smooth, but user can force smoothing
        if smooth_flag:
            common_array = smooth_func(common_array)
        # Check that there are some cloud free pixels
        if not np.any(common_array):
            logging.error('  ERROR: There are no cloud/snow free pixels')
            return False
        # Always overwrite common area raster
        # if not os.path.isfile(image.common_area_raster):
        drigo.array_to_raster(
            common_array, image.common_area_raster,
            output_geo=common_geo, output_proj=common_proj,
            stats_flag=stats_flag)
        # Print common geo/extent
        logging.debug('  Common geo:      {}'.format(common_geo))
        logging.debug('  Common extent:   {}'.format(common_extent))


    # Extract Fmask components as separate rasters
    if (calc_fmask_flag or calc_fmask_cloud_flag or calc_fmask_snow_flag or
            calc_fmask_water_flag):
        logging.info('\nFmask')
        fmask_array = et_numpy.bqa_fmask_func(qa_array)

        # Save Fmask data as separate rasters
        if (calc_fmask_flag and not os.path.isfile(image.fmask_output_raster)):
            drigo.array_to_raster(
                fmask_array.astype(np.uint8), image.fmask_output_raster,
                output_geo=common_geo, output_proj=common_proj,
                mask_array=None, output_nodata=255, stats_flag=stats_flag)
        if (calc_fmask_cloud_flag and
                not os.path.isfile(image.fmask_cloud_raster)):
            fmask_cloud_array = (fmask_array == 2) | (fmask_array == 4)
            drigo.array_to_raster(
                fmask_cloud_array.astype(np.uint8), image.fmask_cloud_raster,
                output_geo=common_geo, output_proj=common_proj,
                mask_array=None, output_nodata=255, stats_flag=stats_flag)
            del fmask_cloud_array
        if (calc_fmask_snow_flag and
                not os.path.isfile(image.fmask_snow_raster)):
            fmask_snow_array = (fmask_array == 3)
            drigo.array_to_raster(
                fmask_snow_array.astype(np.uint8), image.fmask_snow_raster,
                output_geo=common_geo, output_proj=common_proj,
                mask_array=None, output_nodata=255, stats_flag=stats_flag)
            del fmask_snow_array
        if (calc_fmask_water_flag and
                not os.path.isfile(image.fmask_water_raster)):
            fmask_water_array = (fmask_array == 1)
            drigo.array_to_raster(
                fmask_water_array.astype(np.uint8), image.fmask_water_raster,
                output_geo=common_geo, output_proj=common_proj,
                mask_array=None, output_nodata=255, stats_flag=stats_flag)
            del fmask_water_array
        del fmask_array

    # # Calculate elevation
    # if calc_elev_flag and not os.path.isfile(elev_path):
    #     logging.info('Elevation')
    #     elev_array, elev_nodata = drigo.raster_to_array(
    #         elev_pr_path, 1, common_extent)
    #     drigo.array_to_raster(
    #         elev_array, elev_raster,
    #         output_geo=common_geo, output_proj=env.snap_proj,
    #         mask_array=common_array, stats_flag=stats_flag)
    #     del elev_array, elev_nodata, elev_path
    #
    # # Calculate landuse
    # if calc_landuse_flag and not os.path.isfile(landuse_raster):
    #     logging.info('Landuse')
    #     landuse_array, landuse_nodata = drigo.raster_to_array(
    #         landuse_pr_path, 1, common_extent)
    #     drigo.array_to_raster(
    #         landuse_array, landuse_raster,
    #         output_geo=common_geo, output_proj=env.snap_proj,
    #         mask_array=common_array, stats_flag=stats_flag)
    #     del landuse_array, landuse_nodata, landuse_raster

    # Calculate toa reflectance
    # f32_gtype, f32_nodata = numpy_to_gdal_type(np.float32)
    if calc_refl_toa_flag:
        logging.info('Top-of-Atmosphere Reflectance')
        if os.path.isfile(image.refl_toa_raster) and overwrite_flag:
            logging.debug('  Overwriting: {}'.format(
                image.refl_toa_raster))
            python_common.remove_file(image.refl_toa_raster)
        if not os.path.isfile(image.refl_toa_raster):
            # First build empty composite raster
            drigo.build_empty_raster(
                image.refl_toa_raster, image.band_toa_cnt, np.float32, None,
                env.snap_proj, env.cellsize, common_extent)
            # cos_theta_solar_flt = et_common.cos_theta_solar_func(
            #    image.sun_elevation)

            # Process by block
            logging.info('Processing by block')
            logging.debug('  Mask  cols/rows: {}/{}'.format(
                common_cols, common_rows))
            for b_i, b_j in drigo.block_gen(common_rows, common_cols, blocksize):
                logging.debug('  Block  y: {:5d}  x: {:5d}'.format(b_i, b_j))
                block_data_mask = drigo.array_to_block(
                    common_array, b_i, b_j, blocksize).astype(np.bool)
                block_rows, block_cols = block_data_mask.shape
                block_geo = drigo.array_offset_geo(common_geo, b_j, b_i)
                block_extent = drigo.geo_extent(
                    block_geo, block_rows, block_cols)
                logging.debug('    Block rows: {}  cols: {}'.format(
                    block_rows, block_cols))
                logging.debug('    Block extent: {}'.format(block_extent))
                logging.debug('    Block geo: {}'.format(block_geo))

                # Process each TOA band
                # for band, band_i in sorted(image.band_toa_dict.items()):
                for band, dn_image in sorted(dn_image_dict.items()):
                    if band not in image.band_toa_dict.keys():
                        continue
                    # thermal_band_flag = (band == image.thermal_band)
                    # Set 0 as nodata value
                    drigo.raster_path_set_nodata(dn_image, 0)
                    # Calculate TOA reflectance
                    dn_array, dn_nodata = drigo.raster_to_array(
                        dn_image, 1, block_extent)
                    dn_array = dn_array.astype(np.float64)
                    # dn_array = dn_array.astype(np.float32)
                    dn_array[dn_array == 0] = np.nan
                    #
                    if image.type in ['Landsat4', 'Landsat5', 'Landsat7']:
                        refl_toa_array = et_numpy.l457_refl_toa_band_func(
                            dn_array, image.cos_theta_solar,
                            image.dr, image.esun_dict[band],
                            image.lmin_dict[band], image.lmax_dict[band],
                            image.qcalmin_dict[band], image.qcalmax_dict[band])
                    elif image.type in ['Landsat8']:
                        refl_toa_array = et_numpy.l8_refl_toa_band_func(
                            dn_array, image.cos_theta_solar,
                            image.refl_mult_dict[band],
                            image.refl_add_dict[band])
                    # if (image.type in ['Landsat4', 'Landsat5', 'Landsat7'] and
                    #     not thermal_band_flag):
                    #     refl_toa_array = et_numpy.l457_refl_toa_band_func(
                    #         dn_array, image.cos_theta_solar,
                    #         image.dr, image.esun_dict[band],
                    #         image.lmin_dict[band], image.lmax_dict[band],
                    #         image.qcalmin_dict[band],
                    #         image.qcalmax_dict[band])
                    #         # image.rad_mult_dict[band],
                    #         # image.rad_add_dict[band])
                    # elif (image.type in ['Landsat8'] and
                    #       not thermal_band_flag):
                    #     refl_toa_array = et_numpy.l8_refl_toa_band_func(
                    #         dn_array, image.cos_theta_solar,
                    #         image.refl_mult_dict[band],
                    #         image.refl_add_dict[band])
                    # elif (image.type in ['Landsat4', 'Landsat5', 'Landsat7'] and
                    #       thermal_band_flag):
                    #     refl_toa_array = et_numpy.l457_ts_bt_band_func(
                    #         dn_array,
                    #         image.lmin_dict[band], image.lmax_dict[band],
                    #         image.qcalmin_dict[band],
                    #         image.qcalmax_dict[band],
                    #         # image.rad_mult_dict[band],
                    #         # image.rad_add_dict[band],
                    #         image.k1_dict[band], image.k2_dict[band])
                    # elif (image.type in ['Landsat8'] and
                    #       thermal_band_flag):
                    #     refl_toa_array = et_numpy.l8_ts_bt_band_func(
                    #         dn_array,
                    #         image.rad_mult_dict[band],
                    #         image.rad_add_dict[band],
                    #         image.k1_dict[band], image.k2_dict[band])

                    # refl_toa_array = et_numpy.refl_toa_band_func(
                    #     dn_array, cos_theta_solar_flt,
                    #     image.dr, image.esun_dict[band],
                    #     image.lmin_dict[band], image.lmax_dict[band],
                    #     image.qcalmin_dict[band], image.qcalmax_dict[band],
                    #     thermal_band_flag)
                    drigo.block_to_raster(
                        refl_toa_array.astype(np.float32),
                        image.refl_toa_raster,
                        b_i, b_j, band=image.band_toa_dict[band])
                    # drigo.array_to_comp_raster(
                    #    refl_toa_array.astype(np.float32),
                    #    image.refl_toa_raster,
                    #    image.band_toa_dict[band], common_array)
                    del refl_toa_array, dn_array
            if stats_flag:
                drigo.raster_statistics(image.refl_toa_raster)

        # # Process each TOA band
        # # for band, band_i in sorted(image.band_toa_dict.items()):
        # for band, dn_image in sorted(dn_image_dict.items()):
        #     thermal_band_flag = (band == image.thermal_band)
        #     #  Set 0 as nodata value
        #     drigo.raster_path_set_nodata(dn_image, 0)
        #     #  Calculate TOA reflectance
        #     dn_array, dn_nodata = drigo.raster_to_array(
        #         dn_image, 1, common_extent)
        #     dn_array = dn_array.astype(np.float64)
        #     # dn_array = dn_array.astype(np.float32)
        #     dn_array[dn_array == 0] = np.nan
        #     #
        #     if (image.type in ['Landsat4', 'Landsat5', 'Landsat7'] and
        #         not thermal_band_flag):
        #         refl_toa_array = et_numpy.l457_refl_toa_band_func(
        #             dn_array, image.cos_theta_solar,
        #             image.dr, image.esun_dict[band],
        #             image.lmin_dict[band], image.lmax_dict[band],
        #             image.qcalmin_dict[band], image.qcalmax_dict[band])
        #             # image.rad_mult_dict[band], image.rad_add_dict[band])
        #     elif (image.type in ['Landsat4', 'Landsat5', 'Landsat7'] and
        #           thermal_band_flag):
        #         refl_toa_array = et_numpy.l457_ts_bt_band_func(
        #             dn_array, image.lmin_dict[band], image.lmax_dict[band],
        #             image.qcalmin_dict[band], image.qcalmax_dict[band],
        #             # image.rad_mult_dict[band], image.rad_add_dict[band],
        #             image.k1_dict[band], image.k2_dict[band])
        #     elif (image.type in ['Landsat8'] and
        #           not thermal_band_flag):
        #         refl_toa_array = et_numpy.l8_refl_toa_band_func(
        #             dn_array, image.cos_theta_solar,
        #             image.refl_mult_dict[band], image.refl_add_dict[band])
        #     elif (image.type in ['Landsat8'] and
        #           thermal_band_flag):
        #         refl_toa_array = et_numpy.l8_ts_bt_band_func(
        #             dn_array,
        #             image.rad_mult_dict[band], image.rad_add_dict[band],
        #             image.k1_dict[band], image.k2_dict[band])
        #     # refl_toa_array = et_numpy.refl_toa_band_func(
        #     #     dn_array, cos_theta_solar_flt,
        #     #     image.dr, image.esun_dict[band],
        #     #     image.lmin_dict[band], image.lmax_dict[band],
        #     #     image.qcalmin_dict[band], image.qcalmax_dict[band],
        #     #     thermal_band_flag)
        #     drigo.array_to_comp_raster(
        #         refl_toa_array.astype(np.float32), image.refl_toa_raster,
        #         image.band_toa_dict[band], common_array)
        #     del refl_toa_array, dn_array


    # Calculate brightness temperature
    if calc_ts_bt_flag:
        logging.info('Brightness Temperature')
        if os.path.isfile(image.ts_bt_raster) and overwrite_flag:
            logging.debug('  Overwriting: {}'.format(image.ts_bt_raster))
            python_common.remove_file(image.ts_bt_raster)
        if not os.path.isfile(image.ts_bt_raster):
            band = image.thermal_band
            thermal_dn_path = dn_image_dict[band]
            drigo.raster_path_set_nodata(thermal_dn_path, 0)
            thermal_dn_array, thermal_dn_nodata = drigo.raster_to_array(
                thermal_dn_path, 1, common_extent, return_nodata=True)
            thermal_dn_mask = thermal_dn_array != thermal_dn_nodata
            if image.type in ['Landsat4', 'Landsat5', 'Landsat7']:
                ts_bt_array = et_numpy.l457_ts_bt_band_func(
                    thermal_dn_array,
                    image.lmin_dict[band], image.lmax_dict[band],
                    image.qcalmin_dict[band], image.qcalmax_dict[band],
                    # image.rad_mult_dict[band], image.rad_add_dict[band],
                    image.k1_dict[band], image.k2_dict[band])
            elif image.type in ['Landsat8']:
                ts_bt_array = et_numpy.l8_ts_bt_band_func(
                    thermal_dn_array,
                    image.rad_mult_dict[band], image.rad_add_dict[band],
                    image.k1_dict[band], image.k2_dict[band])
            # thermal_rad_array = et_numpy.refl_toa_band_func(
            #     thermal_dn_array, image.cos_theta_solar,
            #     image.dr, image.esun_dict[band],
            #     image.lmin_dict[band], image.lmax_dict[band],
            #     image.qcalmin_dict[band], image.qcalmax_dict[band],
            #     thermal_band_flag=True)
            # ts_bt_array = et_numpy.ts_bt_func(
            #     thermal_rad_array, image.k1_dict[image.thermal_band],
            #     image.k2_dict[image.thermal_band])
            ts_bt_array[~thermal_dn_mask] = np.nan
            drigo.array_to_raster(
                ts_bt_array, image.ts_bt_raster,
                output_geo=common_geo, output_proj=env.snap_proj,
                # mask_array=common_array,
                stats_flag=stats_flag)
            # del thermal_dn_array, thermal_rad_array
            del thermal_dn_path, thermal_dn_array, ts_bt_array


    # Interpolate/project/clip METRIC hourly/daily rasters
    if (calc_metric_ea_flag or
            calc_metric_wind_flag or
            calc_metric_etr_flag):
        logging.info('METRIC hourly/daily rasters')

        # Get bracketing hours from image acquisition time
        image_prev_dt = image.acq_datetime.replace(
            minute=0, second=0, microsecond=0)
        image_next_dt = image_prev_dt + timedelta(seconds=3600)

        # Get NLDAS properties from one of the images
        input_ws = os.path.join(
            metric_etr_input_ws, str(image_prev_dt.year))
        try:
            input_path = [
                os.path.join(input_ws, file_name)
                for file_name in os.listdir(input_ws)
                for match in [metric_hourly_re.match(file_name)]
                if (match and
                    (image_prev_dt.strftime('%Y%m%d') ==
                     match.group('YYYYMMDD')))][0]
        except IndexError:
            logging.error('  No hourly file for {}'.format(
                image_prev_dt.strftime('%Y-%m-%d %H00')))
            return False
        try:
            input_ds = gdal.Open(input_path)
            input_osr = drigo.raster_ds_osr(input_ds)
            # input_proj = drigo.osr_proj(input_osr)
            input_extent = drigo.raster_ds_extent(input_ds)
            input_cs = drigo.raster_ds_cellsize(input_ds, x_only=True)
            # input_geo = input_extent.geo(input_cs)
            input_x, input_y = input_extent.origin()
            input_ds = None
        except:
            logging.error('  Could not get default input image properties')
            logging.error('    {}'.format(input_path))
            return False

        # Project Landsat scene extent to NLDAS GCS
        common_gcs_osr = common_osr.CloneGeogCS()
        common_gcs_extent = drigo.project_extent(
            common_extent, common_osr, common_gcs_osr,
            cellsize=env.cellsize)
        common_gcs_extent.buffer_extent(0.1)
        common_gcs_extent.adjust_to_snap(
            'EXPAND', input_x, input_y, input_cs)
        # common_gcs_geo = common_gcs_extent.geo(input_cs)

        def metric_weather_func(output_raster, input_ws, input_re,
                                prev_dt, next_dt,
                                resample_method=gdal.GRA_NearestNeighbour,
                                rounding_flag=False):
            """Interpolate/project/clip METRIC hourly rasters"""
            logging.debug('    Output: {}'.format(output_raster))
            if os.path.isfile(output_raster):
                if overwrite_flag:
                    logging.debug('    Overwriting output')
                    python_common.remove_file(output_raster)
                else:
                    logging.debug('    Skipping, file already exists ' +
                                  'and overwrite is False')
                    return False
            prev_ws = os.path.join(input_ws, str(prev_dt.year))
            next_ws = os.path.join(input_ws, str(next_dt.year))

            # Technically previous and next could come from different days
            # or even years, although this won't happen in the U.S.
            try:
                prev_path = [
                    os.path.join(prev_ws, input_name)
                    for input_name in os.listdir(prev_ws)
                    for input_match in [input_re.match(input_name)]
                    if (input_match and
                        (prev_dt.strftime('%Y%m%d') ==
                         input_match.group('YYYYMMDD')))][0]
                logging.debug('    Input prev: {}'.format(prev_path))
            except IndexError:
                logging.error('  No previous hourly file')
                logging.error('    {}'.format(prev_dt))
                return False
            try:
                next_path = [
                    os.path.join(next_ws, input_name)
                    for input_name in os.listdir(next_ws)
                    for input_match in [input_re.match(input_name)]
                    if (input_match and
                        (next_dt.strftime('%Y%m%d') ==
                         input_match.group('YYYYMMDD')))][0]
                logging.debug('    Input next: {}'.format(next_path))
            except IndexError:
                logging.error('  No next hourly file')
                logging.error('    {}'.format(next_dt))
                return False

            # Band numbers are 1's based
            prev_band = int(prev_dt.strftime('%H')) + 1
            next_band = int(next_dt.strftime('%H')) + 1
            logging.debug('    Input prev band: {}'.format(prev_band))
            logging.debug('    Input next band: {}'.format(next_band))

            # Read arrays
            prev_array = drigo.raster_to_array(
                prev_path, band=prev_band, mask_extent=common_gcs_extent,
                return_nodata=False)
            next_array = drigo.raster_to_array(
                next_path, band=next_band, mask_extent=common_gcs_extent,
                return_nodata=False)
            if not np.any(prev_array) or not np.any(next_array):
                logging.warning('\nWARNING: Input NLDAS array is all nodata\n')
                return None

            output_array = hourly_interpolate_func(
                prev_array, next_array,
                prev_dt, next_dt, image.acq_datetime)
            output_array = drigo.project_array(
                output_array, resample_method,
                input_osr, input_cs, common_gcs_extent,
                common_osr, env.cellsize, common_extent, output_nodata=None)
            # Apply common area mask
            output_array[~common_array] = np.nan
            # Reduce the file size by rounding to the nearest n digits
            if rounding_flag:
                output_array = np.around(output_array, rounding_digits)
            # Force output to 32-bit float
            drigo.array_to_raster(
                output_array.astype(np.float32), output_raster,
                output_geo=common_geo, output_proj=common_proj,
                stats_flag=stats_flag)
            del output_array
            return True

        # Ea - Project to Landsat scene after clipping
        if calc_metric_ea_flag:
            logging.info('  Hourly vapor pressure (Ea)')
            metric_weather_func(
                image.metric_ea_raster, metric_ea_input_ws,
                metric_hourly_re, image_prev_dt, image_next_dt,
                gdal.GRA_Bilinear, rounding_flag=True)

        # Wind - Project to Landsat scene after clipping
        if calc_metric_wind_flag:
            logging.info('  Hourly windspeed')
            metric_weather_func(
                image.metric_wind_raster, metric_wind_input_ws,
                metric_hourly_re, image_prev_dt, image_next_dt,
                gdal.GRA_NearestNeighbour, rounding_flag=False)

        # ETr - Project to Landsat scene after clipping
        if calc_metric_etr_flag:
            logging.info('  Hourly reference ET (ETr)')
            metric_weather_func(
                image.metric_etr_raster, metric_etr_input_ws,
                metric_hourly_re, image_prev_dt, image_next_dt,
                gdal.GRA_NearestNeighbour, rounding_flag=False)

        # ETr 24hr - Project to Landsat scene after clipping
        if calc_metric_etr_flag:
            logging.info('  Daily reference ET (ETr)')
            logging.debug('    Output: {}'.format(
                image.metric_etr_24hr_raster))
            if (os.path.isfile(image.metric_etr_24hr_raster) and
                    overwrite_flag):
                logging.debug('    Overwriting output')
                os.remove(image.metric_etr_24hr_raster)
            if not os.path.isfile(image.metric_etr_24hr_raster):
                etr_prev_ws = os.path.join(
                    metric_etr_input_ws, str(image_prev_dt.year))
                try:
                    input_path = [
                        os.path.join(etr_prev_ws, file_name)
                        for file_name in os.listdir(etr_prev_ws)
                        for match in [metric_daily_re.match(file_name)]
                        if (match and
                            (image_prev_dt.strftime('%Y%m%d') ==
                             match.group('YYYYMMDD')))][0]
                    logging.debug('    Input: {}'.format(input_path))
                except IndexError:
                    logging.error('  No daily file for {}'.format(
                        image_prev_dt.strftime('%Y-%m-%d')))
                    return False
                output_array = drigo.raster_to_array(
                    input_path, mask_extent=common_gcs_extent,
                    return_nodata=False)
                output_array = drigo.project_array(
                    output_array, gdal.GRA_NearestNeighbour,
                    input_osr, input_cs, common_gcs_extent,
                    common_osr, env.cellsize, common_extent,
                    output_nodata=None)
                # Apply common area mask
                output_array[~common_array] = np.nan
                # Reduce the file size by rounding to the nearest n digits
                # output_array = np.around(output_array, rounding_digits)
                drigo.array_to_raster(
                    output_array, image.metric_etr_24hr_raster,
                    output_geo=common_geo, output_proj=common_proj,
                    stats_flag=stats_flag)
                del output_array
                del input_path

        # Tair - Project to Landsat scene after clipping
        if calc_metric_tair_flag:
            logging.info('  Hourly air temperature (Tair)')
            metric_weather_func(
                image.metric_tair_raster, metric_tair_input_ws,
                metric_hourly_re, image_prev_dt, image_next_dt,
                gdal.GRA_NearestNeighbour, rounding_flag=False)

        # Cleanup
        del image_prev_dt, image_next_dt

    # Soil Water Balance
    if calc_swb_ke_flag:
        logging.info('Daily soil water balance')

        # Check if output file already exists
        logging.debug('  Ke:  {}'.format(image.ke_raster))
        if os.path.isfile(image.ke_raster):
            if overwrite_flag:
                logging.debug('    Overwriting output')
                python_common.remove_file(image.ke_raster)
            else:
                logging.debug('    Skipping, file already ' +
                              'exists and overwrite is False')
                return False
        ke_array = et_common.raster_swb_func(
            image.acq_datetime, common_osr, env.cellsize, common_extent,
            awc_input_path, etr_input_ws, etr_input_re,
            ppt_input_ws, ppt_input_re,
            spinup_days=spinup_days, min_spinup_days=min_spinup_days)
        # Apply common area mask
        ke_array[~common_array] = np.nan
        # Reduce the file size by rounding to the nearest 2 digits
        np.around(ke_array, 2, out=ke_array)

        # Force output to 32-bit float
        drigo.array_to_raster(
            ke_array.astype(np.float32), image.ke_raster,
            output_geo=common_geo, output_proj=common_proj,
            stats_flag=stats_flag)

    # Remove Landsat TOA rasters
    if not keep_dn_flag:
        for landsat_item in python_common.build_file_list(
                image.orig_data_ws, image.image_re):
            os.remove(os.path.join(image.orig_data_ws, landsat_item))
    return True
Esempio n. 25
0
def test_basic_test_11():

    ds = gdal.OpenEx('data/byte.tif')
    assert ds is not None

    ds = gdal.OpenEx('data/byte.tif', gdal.OF_RASTER)
    assert ds is not None

    ds = gdal.OpenEx('data/byte.tif', gdal.OF_VECTOR)
    assert ds is None

    ds = gdal.OpenEx('data/byte.tif', gdal.OF_RASTER | gdal.OF_VECTOR)
    assert ds is not None

    ds = gdal.OpenEx('data/byte.tif', gdal.OF_ALL)
    assert ds is not None

    ds = gdal.OpenEx('data/byte.tif', gdal.OF_UPDATE)
    assert ds is not None

    ds = gdal.OpenEx(
        'data/byte.tif', gdal.OF_RASTER | gdal.OF_VECTOR | gdal.OF_UPDATE
        | gdal.OF_VERBOSE_ERROR)
    assert ds is not None

    ds = gdal.OpenEx('data/byte.tif', allowed_drivers=[])
    assert ds is not None

    ds = gdal.OpenEx('data/byte.tif', allowed_drivers=['GTiff'])
    assert ds is not None

    ds = gdal.OpenEx('data/byte.tif', allowed_drivers=['PNG'])
    assert ds is None

    with gdaltest.error_handler():
        ds = gdal.OpenEx('data/byte.tif', open_options=['FOO'])
    assert ds is not None

    ar_ds = [gdal.OpenEx('data/byte.tif', gdal.OF_SHARED) for _ in range(1024)]
    assert ar_ds[1023] is not None
    ar_ds = None

    ds = gdal.OpenEx('../ogr/data/poly.shp', gdal.OF_RASTER)
    assert ds is None

    ds = gdal.OpenEx('../ogr/data/poly.shp', gdal.OF_VECTOR)
    assert ds is not None
    assert ds.GetLayerCount() == 1
    assert ds.GetLayer(0) is not None
    ds.GetLayer(0).GetMetadata()

    ds = gdal.OpenEx('../ogr/data/poly.shp',
                     allowed_drivers=['ESRI Shapefile'])
    assert ds is not None

    ds = gdal.OpenEx('../ogr/data/poly.shp', gdal.OF_RASTER | gdal.OF_VECTOR)
    assert ds is not None

    ds = gdal.OpenEx('non existing')
    assert ds is None and gdal.GetLastErrorMsg() == ''

    gdal.PushErrorHandler('CPLQuietErrorHandler')
    ds = gdal.OpenEx('non existing', gdal.OF_VERBOSE_ERROR)
    gdal.PopErrorHandler()
    assert ds is None and gdal.GetLastErrorMsg() != ''

    old_use_exceptions_status = gdal.GetUseExceptions()
    gdal.UseExceptions()
    got_exception = False
    try:
        ds = gdal.OpenEx('non existing')
    except RuntimeError:
        got_exception = True
    if old_use_exceptions_status == 0:
        gdal.DontUseExceptions()
    assert got_exception
Esempio n. 26
0
def convert_raster(
    input_files,
    output_file,
    driver=None,
    access_mode="overwrite",
    creation_options=None,
    band_type=None,
    dst_alpha=None,
    boundary=None,
    src_srs=None,
    dst_srs=None,
    task_uid=None,
    warp_params: dict = None,
    translate_params: dict = None,
    use_translate: bool = False,
    config_options: List[Tuple[str]] = None,
):
    """
    :param warp_params: A dict of options to pass to gdal warp (done first in conversion), overrides other settings.
    :param translate_params: A dict of options to pass to gdal translate (done second in conversion),
        overrides other settings.
    :param input_files: A file or list of files to convert.
    :param output_file: The file to convert.
    :param driver: The file format to convert.
    :param creation_options: Special GDAL options for conversion.
        Search for "gdal driver <format> creation options" creation options for driver specific implementation.
    :param band_type: The GDAL data type (e.g. gdal.GDT_BYTE).
    :param dst_alpha: If including an alpha band in the destination file.
    :param boundary: The boundary to be used for clipping, this must be a file.
    :param src_srs: The srs of the source (e.g. "EPSG:4326")
    :param dst_srs: The srs of the destination (e.g. "EPSG:3857")
    :param task_uid: The eventkit task uid used for tracking the work.
    :param use_translate: Make true if needing to use translate for conversion instead of warp.
    :param config_options: A list of gdal configuration options as a tuple (option, value).
    :return: The output file.
    """
    if not driver:
        raise Exception(
            "Cannot use convert_raster without specififying a gdal driver.")

    if isinstance(input_files, str) and not use_translate:
        input_files = [input_files]
    elif isinstance(input_files, list) and use_translate:
        # If a single file is provided in an array, we can simply pull it out
        if len(input_files) == 1:
            input_files = input_files[0]
        else:
            raise Exception("Cannot use_translate with a list of files.")
    gdal.UseExceptions()
    subtask_percentage = 50 if driver.lower() == "gtiff" else 100
    options = clean_options({
        "callback": progress_callback,
        "callback_data": {
            "task_uid": task_uid,
            "subtask_percentage": subtask_percentage
        },
        "creationOptions": creation_options,
        "format": driver,
    })
    if not warp_params:
        warp_params = clean_options({
            "outputType": band_type,
            "dstAlpha": dst_alpha,
            "srcSRS": src_srs,
            "dstSRS": dst_srs
        })
    if not translate_params:
        translate_params = dict()
    if boundary:
        warp_params.update({"cutlineDSName": boundary, "cropToCutline": True})
    # Keep the name imagery which is used when seeding the geopackages.
    # Needed because arcpy can't change table names.
    if driver.lower() == "gpkg":
        options["creationOptions"] = options.get(
            "creationOptions", []) + ["RASTER_TABLE=imagery"]

    if use_translate:
        logger.info(
            f"calling gdal.Translate('{output_file}', {input_files}'),"
            f"{stringify_params(options)}, {stringify_params(warp_params)},)")
        options.update(translate_params)
        gdal.Translate(output_file, input_files, **options)
    else:
        logger.info(
            f"calling gdal.Warp('{output_file}', [{', '.join(input_files)}],"
            f"{stringify_params(options)}, {stringify_params(warp_params)},)")
        gdal.Warp(output_file, input_files, **options, **warp_params)

    if driver.lower() == "gtiff" or translate_params:
        # No need to compress in memory objects as they will be removed later.
        if "vsimem" in output_file:
            return output_file
        input_file, output_file = get_dataset_names(output_file, output_file)
        if translate_params:
            options.update(translate_params)
        else:
            options.update({
                "creationOptions":
                ["COMPRESS=LZW", "TILED=YES", "BIGTIFF=YES"]
            })

        logger.info(f"calling gdal.Translate('{output_file}', '{input_file}', "
                    f"{stringify_params(options)},)")
        gdal.Translate(output_file, input_file, **options)
    return output_file
Esempio n. 27
0
from osgeo import gdal, ogr, osr, gdal_array  # 地理及遥感数据运算的核心开源库。
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import Qt, QPoint, QPointF, QLine, QLineF, QRect, QRectF, QTime, qrand
from PyQt5.QtGui import QImage, QPixmap, QPainter, QBrush, QPen, QColor, QRadialGradient, QPainterPath, QPicture, \
    QPolygonF, QPolygon
from PyQt5.QtWidgets import QAction, QWidget, QPushButton, QApplication, QMessageBox, QFileDialog, QGraphicsScene, \
    QGraphicsPixmapItem, QGraphicsRectItem, QMainWindow, QGraphicsView, QGraphicsItem, QSizePolicy
# 通过from…import…导入PyQt5中所需的模块,减轻脚本依赖。

from GUI.Main import Ui_MainWindow as GUI0  # 导入界面脚本。
from GUI.SFC1 import sFC
# from GUI.ShowGraphic import myGraphicsScene,myGraphicsView
from GUI.WindowMove import windowMove
from GUI.Size import size

gdal.UseExceptions()  # 抛出gdal异常
gdal.AllRegister()  # gdal库需要注册后使用。
ogr.UseExceptions()  # 抛出异常
ogr.RegisterAll()  # ogr库需要注册后使用。
wholefiletype = ['.jpg', '.jpeg', '.JPG', '.JPEG', '.tif',
                 '.TIF']  # 创建一个数组存储图象格式
currentfiletype = ['.shp', '.txt']  # 创建一个存储矢量文件的数组。


class myGraphicsView(QGraphicsView):
    def __init__(self, parent=None):
        super(myGraphicsView, self).__init__(parent)
        self.setCacheMode(QGraphicsView.CacheBackground)
        self.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
        self.setRenderHint(QPainter.Antialiasing)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
Esempio n. 28
0
def convert_vector(
    input_file,
    output_file,
    driver=None,
    access_mode="overwrite",
    src_srs=None,
    dst_srs=None,
    task_uid=None,
    layers=None,
    layer_name=None,
    boundary=None,
    bbox=None,
    dataset_creation_options=None,
    layer_creation_options=None,
    config_options: List[Tuple[str]] = None,
    distinct_field=None,
):
    """
    :param input_files: A file or list of files to convert.
    :param output_file: The file to convert.
    :param driver: The file format to convert.
    :param creation_options: Special GDAL options for conversion.
        Search for "gdal driver <format> creation options" creation options for driver specific implementation.
    :param access_mode: The access mode for the file (e.g. "append" or "overwrite")
    :param bbox: A bounding box as a list (w,s,e,n) to be used for limiting the AOI that is used during conversion.
    :param boundary: The boundary to be used for clipping.
        This must be a file (i.e. a path as a string) and cannot be used with bbox.
    :param src_srs: The srs of the source (e.g. "EPSG:4326")
    :param dst_srs: The srs of the destination (e.g. "EPSG:3857")
    :param task_uid: The eventkit task uid used for tracking the work.
    :param layers: A list of layers to include for translation.
    :param layer_name: Table name in database for in_dataset
    :param config_options: A list of gdal configuration options as a tuple (option, value).
    :param distinct_field: A field for selecting distinct features to prevent duplicates.
    :return: The output file.
    """
    if isinstance(input_file, str) and access_mode == "append":
        input_file = [input_file]
    elif isinstance(input_file, list) and access_mode == "overwrite":
        # If a single file is provided in an array, we can simply pull it out
        if len(input_file) == 1:
            input_file = input_file[0]
        else:
            raise Exception("Cannot overwrite with a list of files.")
    gdal.UseExceptions()
    options = clean_options({
        "callback":
        progress_callback,
        "callback_data": {
            "task_uid": task_uid
        },
        "datasetCreationOptions":
        dataset_creation_options,
        "layerCreationOptions":
        layer_creation_options,
        "format":
        driver,
        "layers":
        layers,
        "layerName":
        layer_name,
        "srcSRS":
        src_srs,
        "dstSRS":
        dst_srs,
        "accessMode":
        access_mode,
        "reproject":
        src_srs != dst_srs,
        "skipFailures":
        True,
        "spatFilter":
        bbox,
        "options": ["-clipSrc", boundary] if boundary and not bbox else None,
    })
    if "gpkg" in driver.lower():
        options["geometryType"] = ["PROMOTE_TO_MULTI"]
    if config_options:
        for config_option in config_options:
            gdal.SetConfigOption(*config_option)
    if access_mode == "append":
        for _input_file in input_file:
            logger.info(
                f"calling gdal.VectorTranslate('{output_file}', '{_input_file}', {stringify_params(options)})"
            )
            gdal.VectorTranslate(output_file, _input_file, **options)
    else:
        logger.info(
            f"calling gdal.VectorTranslate('{output_file}', '{input_file}', {stringify_params(options)})"
        )
        gdal.VectorTranslate(output_file, input_file, **options)

    if distinct_field:
        logger.error(f"Normalizing features based on field: {distinct_field}")
        table_name = layer_name or os.path.splitext(
            os.path.basename(output_file))[0]
        options[
            "SQLStatement"] = f"SELECT * from '{table_name}' GROUP BY '{distinct_field}'"
        options["SQLDialect"] = "sqlite"
        logger.error(
            f"calling gdal.VectorTranslate('{output_file}', '{output_file}', {stringify_params(options)})"
        )
        gdal.VectorTranslate(output_file, rename_duplicate(output_file),
                             **options)

    return output_file
Esempio n. 29
0
# ============= standard library imports ========================
# import os
# import fiona
# import rasterio
# import rasterio.tools.mask as maskit
# from rasterio import features

#from etrm.raster_tools import convert_raster_to_array
import operator
from osgeo import gdal, gdalnumeric, ogr, osr
from PIL import Image, ImageDraw
from numpy import array, asarray
import os, sys

gdal.UseExceptions()
# ============= local library imports ===========================
"""
This script will be used to:

1) separate out pixels of an image by land use by multiplying pixels by a mask array.



"""


def convert_raster_to_array(input_raster_path, raster=None, band=1):
    """
    Convert .tif raster into a numpy numerical array.
Esempio n. 30
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('dem_path', help='Input DEM file.')
    parser.add_argument('output_path', help='Output path for pixel array.')
    parser.add_argument('--decimation',
                        type=int,
                        help='Optional downsample factor.')
    parser.add_argument('--trim')
    flags = parser.parse_args()

    gdal.UseExceptions()

    print('loading DEM...')
    dem = Dem(flags.dem_path)
    print('x size: ' + str(dem.x_size()))
    print('y size: ' + str(dem.y_size()))

    print()
    print('making master image...')
    t0 = time.time()
    heightmap_data = dem.get_raster_band_array()
    print('assembled master image in {} seconds'.format(time.time() - t0))

    print('filling nans to no-data regions...')
    t0 = time.time()
    heightmap_data[np.where(heightmap_data < -1e30)] = np.nan
    print('filled nans in {} seconds'.format(time.time() - t0))

    # convert to float
    print('converting to 32 bit floats...')
    t0 = time.time()
    heightmap_data = heightmap_data.astype(np.float32)
    print('converted to 32 bit floats in {} seconds'.format(time.time() - t0))

    # trim
    if flags.trim:
        # Expect flags.trim to be a string like '22,2222,44,4444'
        # Parse this into (min_x, max_x, min_y, max_y).
        trim = eval(flags.trim)
        assert len(trim) == 4
        min_x, max_x, min_y, max_y = trim
        heightmap_data[0:min_x, :] = np.nan
        heightmap_data[max_x:-1, :] = np.nan
        heightmap_data[:, 0:min_y] = np.nan
        heightmap_data[:, max_y:-1] = np.nan

        # trim leading and trailing rows/cols that are all nans
        print('trimming nans...')
        t0 = time.time()
        heightmap_data = trim_nans(heightmap_data)
        print('trimming nans took {} s'.format(time.time() - t0))

    # downsample
    if flags.decimation:
        print('decimating...')
        t0 = time.time()
        heightmap_data = heightmap_data[::flags.decimation, ::flags.
                                        decimation] / flags.decimation
        print('decimated in {} seconds'.format(time.time() - t0))

    # normalize image height
    print("Normalizing heightmap...")
    t0 = time.time()
    heightmap_data -= np.nanmin(heightmap_data)
    print("Normalized heightmap in {} seconds.".format(time.time() - t0))

    # write blob
    print(f"Writing image to {flags.output_path}...")
    t0 = time.time()
    _save_image(flags.output_path, heightmap_data)
    print('Wrote heightmap in {} seconds to {}'.format(time.time() - t0,
                                                       flags.output_path))
    print('Dimensions {}, num elements {}'.format(str(heightmap_data.shape),
                                                  heightmap_data.size))