Beispiel #1
0
def test_basic_test_17():

    from osgeo import ogr

    for _ in range(2):
        ogr.UseExceptions()
        gdal.UseExceptions()
        try:
            gdal.Open('do_not_exist')
        except RuntimeError:
            pass
        gdal.DontUseExceptions()
        ogr.DontUseExceptions()
        assert not gdal.GetUseExceptions()
        assert not ogr.GetUseExceptions()

    for _ in range(2):
        ogr.UseExceptions()
        gdal.UseExceptions()
        try:
            gdal.Open('do_not_exist')
        except RuntimeError:
            pass
        flag = False
        try:
            ogr.DontUseExceptions()
            gdal.DontUseExceptions()
            flag = True
        except:
            gdal.DontUseExceptions()
            ogr.DontUseExceptions()
        assert not flag, 'expected failure'
        assert not gdal.GetUseExceptions()
        assert not ogr.GetUseExceptions()
Beispiel #2
0
def test_basic_test_7():
    old_use_exceptions_status = gdal.GetUseExceptions()
    gdal.UseExceptions()
    ret = basic_test_7_internal()
    if old_use_exceptions_status == 0:
        gdal.DontUseExceptions()
    return ret
Beispiel #3
0
    def deleteIfExisting(filename):
        """
        Delete the filename if it already exists.
        If possible, use the appropriate GDAL driver to do so, to ensure
        that any associated files will also be deleted. 

        """
        if os.path.exists(filename):
            # Save the current exception-use state
            usingExceptions = gdal.GetUseExceptions()
            if not usingExceptions:
                gdal.UseExceptions()

            # Try opening it for read, to find out whether it is 
            # a valid GDAL file, and which driver it goes with
            try:
                ds = gdal.Open(str(filename))
            except RuntimeError:
                ds = None

            if ds is not None:
                # It is apparently a valid GDAL file, so get the driver appropriate for it.
                drvr = ds.GetDriver()
                del ds
                # Use this driver to delete the file
                drvr.Delete(filename)
            else:
                # Apparently not a valid GDAL file, for whatever reason, so just remove the file
                # directly. 
                os.remove(filename)

            # Restore exception-use state
            if not usingExceptions:
                gdal.DontUseExceptions()
Beispiel #4
0
def basic_test_17():

    from osgeo import ogr

    for _ in range(2):
        ogr.UseExceptions()
        gdal.UseExceptions()
        try:
            gdal.Open('do_not_exist')
        except RuntimeError:
            pass
        gdal.DontUseExceptions()
        ogr.DontUseExceptions()
        if gdal.GetUseExceptions():
            gdaltest.post_reason('fail')
            return 'fail'
        if ogr.GetUseExceptions():
            gdaltest.post_reason('fail')
            return 'fail'

    for _ in range(2):
        ogr.UseExceptions()
        gdal.UseExceptions()
        try:
            gdal.Open('do_not_exist')
        except RuntimeError:
            pass
        flag = False
        try:
            ogr.DontUseExceptions()
            gdal.DontUseExceptions()
            flag = True
        except:
            gdal.DontUseExceptions()
            ogr.DontUseExceptions()
        if flag:
            gdaltest.post_reason('expected failure')
            return 'fail'
        if gdal.GetUseExceptions():
            gdaltest.post_reason('fail')
            return 'fail'
        if ogr.GetUseExceptions():
            gdaltest.post_reason('fail')
            return 'fail'

    return 'success'
Beispiel #5
0
def vsifile_16():

    old_val = gdal.GetUseExceptions()
    gdal.UseExceptions()
    try:
        gdal.Rename('/tmp/i_dont_exist_vsifile_16.tif', '/tmp/me_neither.tif')
        ret = 'fail'
    except RuntimeError:
        ret = 'success'
    if not old_val:
        gdal.DontUseExceptions()
    return ret
Beispiel #6
0
def has_geos():
    pnt1 = ogr.CreateGeometryFromWkt('POINT(10 20)')
    pnt2 = ogr.CreateGeometryFromWkt('POINT(30 20)')
    ogrex = ogr.GetUseExceptions()
    gdalex = gdal.GetUseExceptions()
    gdal.DontUseExceptions()
    ogr.DontUseExceptions()
    hasgeos = pnt1.Union(pnt2) is not None
    if ogrex:
        ogr.UseExceptions()
    if gdalex:
        gdal.UseExceptions()
    return hasgeos
Beispiel #7
0
def opensAsRaster(filename):
    """
    Return True if filename opens as a GDAL raster, False otherwise
    """
    usingExceptions = False
    if hasattr(gdal, 'GetUseExceptions'):
        usingExceptions = gdal.GetUseExceptions()
    gdal.UseExceptions()
    try:
        ds = gdal.Open(filename)
    except Exception:
        ds = None
    opensOK = (ds is not None)

    if not usingExceptions:
        gdal.DontUseExceptions()
    return opensOK
Beispiel #8
0
def open_ds(ds_path):
    """
    Given a path to a raster or vector dataset, returns an opened GDAL or OGR dataset.
    The caller has the responsibility of closing/deleting the dataset when finished.
    :param ds_path: Path to dataset
    :return: Handle to open dataset
    """

    # TODO: Can be a DB Connection
    # if not os.path.isfile(ds_path):
    #    raise Exception("Could not find file {}".format(ds_path))

    # Attempt to open as gdal dataset (raster)
    use_exceptions = gdal.GetUseExceptions()
    gdal.UseExceptions()

    logger.info("Opening the dataset: {}".format(ds_path))
    try:
        gdal_dataset = gdal.Open(ds_path)
        if gdal_dataset:
            return gdal_dataset
    except RuntimeError as ex:
        if ('not recognized as a supported file format' not in str(ex)) or \
                ('Error browsing database for PostGIS Raster tables' in str(ex)):
            raise ex
    finally:
        if not use_exceptions:
            gdal.DontUseExceptions()

    # Attempt to open as ogr dataset (vector)
    # ogr.UseExceptions doesn't seem to work reliably, so just check for Open returning None
    ogr_dataset = ogr.Open(ds_path)

    if not ogr_dataset:
        logger.debug("Unknown file format: {0}".format(ds_path))
        return None

    return ogr_dataset
Beispiel #9
0
def test_basic_test_17_part_2():

    # For some odd reason, this fails on the Travis CI targets after unrelated
    # changes (https://travis-ci.com/github/OSGeo/gdal/jobs/501940381)
    if gdaltest.skip_on_travis():
        pytest.skip()

    from osgeo import ogr

    for _ in range(2):
        ogr.UseExceptions()
        gdal.UseExceptions()
        flag = False
        try:
            ogr.DontUseExceptions()
            gdal.DontUseExceptions()
            flag = True
        except:
            gdal.DontUseExceptions()
            ogr.DontUseExceptions()
        assert not flag, 'expected failure'
        assert not gdal.GetUseExceptions()
        assert not ogr.GetUseExceptions()
Beispiel #10
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
Beispiel #11
0
def writeColumnToBand(gdalBand,
                      colName,
                      sequence,
                      colType=None,
                      colUsage=gdal.GFU_Generic):
    """
    Given a GDAL band, Writes the data specified in sequence 
    (can be list, tuple or array etc)
    to the named column in the attribute table assocated with the
    gdalBand. colType must be one of gdal.GFT_Integer,gdal.GFT_Real,gdal.GFT_String.
    can specify one of the gdal.GFU_* constants for colUsage - default is 'generic'
    GDAL dataset must have been created, or opened with GA_Update
    """

    if colType is None:
        colType = inferColumnType(sequence)
    if colType is None:
        msg = "Can't infer type of column for sequence of %s" % type(
            sequence[0])
        raise rioserrors.AttributeTableTypeError(msg)

    # check it is acually a valid type
    elif colType not in (gdal.GFT_Integer, gdal.GFT_Real, gdal.GFT_String):
        msg = "coltype must be a valid gdal column type"
        raise rioserrors.AttributeTableTypeError(msg)

    attrTbl = gdalBand.GetDefaultRAT()
    if attrTbl is None:
        # some formats eg ENVI return None
        # here so we need to be able to cope
        attrTbl = gdal.RasterAttributeTable()
        isFileRAT = False
    else:

        isFileRAT = True

        # but if it doesn't support dynamic writing
        # we still ahve to call SetDefaultRAT
        if not attrTbl.ChangesAreWrittenToFile():
            isFileRAT = False

    # We need to ensure colname doesn't already exist
    colExists = False
    for n in range(attrTbl.GetColumnCount()):
        if attrTbl.GetNameOfCol(n) == colName:
            colExists = True
            colNum = n
            break
    if not colExists:
        # preserve usage
        attrTbl.CreateColumn(colName, colType, colUsage)
        colNum = attrTbl.GetColumnCount() - 1

    rowsToAdd = len(sequence)
    # Imagine has trouble if not 256 items for byte
    if gdalBand.DataType == gdal.GDT_Byte:
        rowsToAdd = 256

    # another hack to hide float (0-1) and int (0-255)
    # color table handling.
    # we assume that the column has already been created
    # of the right type appropriate for the format (maybe by calcstats)
    usage = attrTbl.GetUsageOfCol(colNum)
    if (isColorColFromUsage(usage)
            and attrTbl.GetTypeOfCol(colNum) == gdal.GFT_Real
            and colType == gdal.GFT_Integer):
        sequence = numpy.array(sequence, dtype=numpy.float)
        sequence = sequence / 255.0

    attrTbl.SetRowCount(rowsToAdd)
    attrTbl.WriteArray(sequence, colNum)

    if not isFileRAT:
        # assume existing bands re-written
        # Use GDAL's exceptions to trap the error message which arises when
        # writing to a format which does not support it
        usingExceptions = gdal.GetUseExceptions()
        gdal.UseExceptions()
        try:
            gdalBand.SetDefaultRAT(attrTbl)
        except Exception:
            pass
        if not usingExceptions:
            gdal.DontUseExceptions()
Beispiel #12
0
def _RaiseException():
    if gdal.GetUseExceptions():
        _StoreLastException()
        raise RuntimeError(gdal.GetLastErrorMsg())
Beispiel #13
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'
Beispiel #14
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
Beispiel #15
0
def addStatistics(ds, progress, ignore=None, approx_ok=False):
    """
    Calculates statistics and adds them to the image
    
    Uses gdal.Band.ComputeStatistics() for mean, stddev, min and max,
    and gdal.Band.GetHistogram() to do histogram calculation. 
    The median and mode are estimated using the histogram, and so 
    for larger datatypes, they will be approximate only. 
    
    For thematic layers, the histogram is calculated with as many bins 
    as required, for athematic integer and float types, a maximum
    of 256 bins is used. 
    
    """
    progress.setLabelText("Computing Statistics...")
    progress.setProgress(0)
    percent = 0
    percentstep = 100.0 / (ds.RasterCount * 2)  # 2 steps for each layer

    # flush the cache. The ensures that any unwritten data is
    # written to file so we get the right stats. It also
    # makes sure any metdata is written on HFA. This means
    # the LAYER_TYPE setting will be picked up by rat.SetLinearBinning()
    ds.FlushCache()

    for bandnum in range(ds.RasterCount):
        band = ds.GetRasterBand(bandnum + 1)

        # fill in the metadata
        tmpmeta = band.GetMetadata()

        if ignore is not None:
            # tell QGIS that the ignore value was ignored
            band.SetNoDataValue(ignore)
            tmpmeta["STATISTICS_EXCLUDEDVALUES"] = repr(
                ignore)  # doesn't seem to do anything

        # get GDAL to calculate statistics - force recalculation. Trap errors
        useExceptions = gdal.GetUseExceptions()
        gdal.UseExceptions()
        try:
            if approx_ok and "LAYER_TYPE" in tmpmeta and tmpmeta[
                    "LAYER_TYPE"] == "thematic":
                warnings.warn(
                    'WARNING: approx_ok specified for stats but image is thematic (this could be a bad idea)'
                )

            (minval, maxval, meanval,
             stddevval) = band.ComputeStatistics(approx_ok)
        except RuntimeError as e:
            if str(e).endswith(
                    'Failed to compute statistics, no valid pixels found in sampling.'
            ):
                minval = ignore
                maxval = ignore
                meanval = ignore
                stddevval = 0
            else:
                raise e
        if not useExceptions:
            gdal.DontUseExceptions()

        percent = percent + percentstep
        progress.setProgress(percent)

        tmpmeta["STATISTICS_MINIMUM"] = repr(minval)
        tmpmeta["STATISTICS_MAXIMUM"] = repr(maxval)
        tmpmeta["STATISTICS_MEAN"] = repr(meanval)
        tmpmeta["STATISTICS_STDDEV"] = repr(stddevval)
        # because we did at full res - these are the default anyway

        if approx_ok:
            tmpmeta["STATISTICS_APPROXIMATE"] = "YES"
        else:
            tmpmeta["STATISTICS_SKIPFACTORX"] = "1"
            tmpmeta["STATISTICS_SKIPFACTORY"] = "1"

        # create a histogram so we can do the mode and median
        if band.DataType == gdal.GDT_Byte:
            # if byte data use 256 bins and the whole range
            histmin = 0
            histmax = 255
            histstep = 1.0
            histCalcMin = -0.5
            histCalcMax = 255.5
            histnbins = 256
            tmpmeta["STATISTICS_HISTOBINFUNCTION"] = 'direct'
        elif "LAYER_TYPE" in tmpmeta and tmpmeta["LAYER_TYPE"] == 'thematic':
            # all other thematic types a bin per value
            histmin = 0
            histmax = int(numpy.ceil(maxval))
            histstep = 1.0
            histCalcMin = -0.5
            histCalcMax = maxval + 0.5
            histnbins = histmax + 1
            tmpmeta["STATISTICS_HISTOBINFUNCTION"] = 'direct'
        elif band.DataType in gdalLargeIntTypes:
            histrange = int(numpy.ceil(maxval) - numpy.floor(minval)) + 1
            (histmin, histmax) = (minval, maxval)
            if histrange <= 256:
                histnbins = histrange
                histstep = 1.0
                tmpmeta["STATISTICS_HISTOBINFUNCTION"] = 'direct'
                histCalcMin = histmin - 0.5
                histCalcMax = histmax + 0.5
            else:
                histnbins = 256
                tmpmeta["STATISTICS_HISTOBINFUNCTION"] = 'linear'
                histCalcMin = histmin
                histCalcMax = histmax
                histstep = float(histCalcMax - histCalcMin) / histnbins
        elif band.DataType in gdalFloatTypes:
            histnbins = 256
            (histmin, histmax) = (minval, maxval)
            tmpmeta["STATISTICS_HISTOBINFUNCTION"] = 'linear'
            histCalcMin = minval
            histCalcMax = maxval
            histstep = float(histCalcMax - histCalcMin) / histnbins
        # Note that the complex number data types are not handled, as I am not sure
        # what a histogram or a median would mean for such types.

        userdata = ProgressUserData()
        userdata.progress = progress
        userdata.nbands = ds.RasterCount * 2
        userdata.curroffset = percent

        # get histogram and force GDAL to recalculate it
        hist = band.GetHistogram(histCalcMin, histCalcMax, histnbins, False,
                                 approx_ok, progressFunc, userdata)

        # Check if GDAL's histogram code overflowed. This is not a fool-proof test,
        # as some overflows will not result in negative counts.
        histogramOverflow = (min(hist) < 0)

        # we may use this ratObj reference for the colours below also
        # may be None if format does not support RATs
        ratObj = band.GetDefaultRAT()

        if not histogramOverflow:
            # comes back as a list for some reason
            hist = numpy.array(hist)

            # Note that we have explicitly set histstep in each datatype case
            # above. In principle, this can be calculated, as it is done in the
            # float case, but for some of the others we need it to be exactly
            # equal to 1, so we set it explicitly there, to avoid rounding
            # error problems.

            # do the mode - bin with the highest count
            modebin = numpy.argmax(hist)
            modeval = modebin * histstep + histmin
            if band.DataType == gdal.GDT_Float32 or band.DataType == gdal.GDT_Float64:
                tmpmeta["STATISTICS_MODE"] = repr(modeval)
            else:
                tmpmeta["STATISTICS_MODE"] = repr(int(round(modeval)))

            if ratObj is not None:
                histIndx, histNew = findOrCreateColumn(ratObj,
                                                       gdal.GFU_PixelCount,
                                                       "Histogram",
                                                       gdal.GFT_Real)
                # write the hist in a single go
                ratObj.SetRowCount(histnbins)
                ratObj.WriteArray(hist, histIndx)

                ratObj.SetLinearBinning(histmin, (histCalcMax - histCalcMin) /
                                        histnbins)

                # The HFA driver still honours the STATISTICS_HISTOBINVALUES
                # metadata item. If we are recalculating the histogram the old
                # values will be copied across with the metadata so clobber it
                if "STATISTICS_HISTOBINVALUES" in tmpmeta:
                    del tmpmeta["STATISTICS_HISTOBINVALUES"]
            else:
                # old method
                tmpmeta["STATISTICS_HISTOBINVALUES"] = '|'.join(map(
                    repr, hist)) + '|'

                tmpmeta["STATISTICS_HISTOMIN"] = repr(histmin)
                tmpmeta["STATISTICS_HISTOMAX"] = repr(histmax)
                tmpmeta["STATISTICS_HISTONUMBINS"] = repr(histnbins)

            # estimate the median - bin with the middle number
            middlenum = hist.sum() / 2
            gtmiddle = hist.cumsum() >= middlenum
            medianbin = gtmiddle.nonzero()[0][0]
            medianval = medianbin * histstep + histmin
            if band.DataType == gdal.GDT_Float32 or band.DataType == gdal.GDT_Float64:
                tmpmeta["STATISTICS_MEDIAN"] = repr(medianval)
            else:
                tmpmeta["STATISTICS_MEDIAN"] = repr(int(round(medianval)))

        # set the data
        band.SetMetadata(tmpmeta)

        if ratObj is not None and not ratObj.ChangesAreWrittenToFile():
            # For drivers that require the in memory thing
            band.SetDefaultRAT(ratObj)

        percent = percent + percentstep
        progress.setProgress(percent)

        if progress.wasCancelled():
            raise ProcessCancelledError()

    progress.setProgress(100)
Beispiel #16
0
        gdal.SetConfigOption('GDAL_VRT_PYTHON_TRUSTED_MODULES', ','.join(conf))


# Options declaration *************************************************************************** **
_EnvOption = namedtuple('_Option', 'sanitize, set_up, bottom_value')
_OPTIONS = {
    'significant':
    _EnvOption(_sanitize_significant, None, 8.0),
    'default_index_dtype':
    _EnvOption(_sanitize_index_dtype, None, 'int32'),
    'warnings':
    _EnvOption(bool, None, True),
    'allow_complex_footprint':
    _EnvOption(bool, None, False),
    '_osgeo_use_exceptions':
    _EnvOption(bool, _set_up_osgeo_use_exception, gdal.GetUseExceptions()),
    '_gdal_trust_buzzard':
    _EnvOption(bool, _set_up_buzz_trusted, False),

    # 'check_with_invert_proj': _EnvOption(
    #     bool, _set_up_check_with_invert_proj,
    #     gdal.GetConfigOption('CHECK_WITH_INVERT_PROJ') == 'ON'
    # ),
    # 'default_raster_driver': _EnvOption(_sanitize_raster_driver, None, 'GTiff'),
    # 'default_vector_driver': _EnvOption(_sanitize_vector_driver, None, 'ESRI Shapefile'),
    # 'raster_interpolation': _EnvOption(_sanitize_raster_interpolation, None, 'area'),
}


# Storage *************************************************************************************** **
class _GlobalMapStack(object):
Beispiel #17
0
    def resampleToReference(self,
                            ds,
                            nullValList,
                            workingRegion,
                            resamplemethod,
                            tempdir='.',
                            useVRT=False,
                            allowOverviewsGdalwarp=False):
        """
        Resamples any inputs that do not match the reference, to the 
        reference image. 
        
        ds is the GDAL dataset that needs to be resampled.
        nullValList is the list of null values for that dataset.
        workingRegion is a PixelGridDefn
        resamplemethod is a string containing a method supported by gdalwarp.
        
        Returns the new (temporary) resampled dataset instance.
        
        Do not call directly, use resampleAllToReference()
        
        """

        if useVRT:
            ext = '.vrt'
        else:
            # get the driver from the input dataset
            # so we know the default extension, and type
            # for the temporary file.
            driver = ds.GetDriver()
            drivermeta = driver.GetMetadata()

            # temp image file name - based on driver extension
            ext = ''
            if gdal.DMD_EXTENSION in drivermeta:
                ext = '.' + drivermeta[gdal.DMD_EXTENSION]

        (fileh, temp_image) = tempfile.mkstemp(ext, dir=tempdir)
        os.close(fileh)

        overviewLevel = 'NONE'
        if allowOverviewsGdalwarp:
            overviewLevel = 'AUTO'

        if useVRT:
            driverName = 'VRT'
        else:
            driverName = driver.ShortName

        nullValues = self.makeWarpNullOptions(nullValList)

        warpOptions = gdal.WarpOptions(
            overviewLevel=overviewLevel,
            srcSRS=self.specialProjFixes(ds.GetProjection()),
            dstSRS=self.referencePixGrid.projection,
            outputBounds=[
                workingRegion.xMin, workingRegion.yMin, workingRegion.xMax,
                workingRegion.yMax
            ],
            xRes=workingRegion.xRes,
            yRes=workingRegion.yRes,
            format=driverName,
            resampleAlg=resamplemethod,
            srcNodata=nullValues,
            dstNodata=nullValues)

        # delete later - add before the system call as if Ctrl-C is hit
        # control does not always return
        self.filestoremove.append(temp_image)

        usingExceptions = gdal.GetUseExceptions()
        gdal.UseExceptions()
        try:
            newds = gdal.Warp(temp_image, ds, options=warpOptions)
        except Exception as e:
            msg = ("Error while running gdal.Warp(): {}. Try setting the " +
                   "RIOS_NO_VRT_FOR_RESAMPLING environment variable " +
                   "to '1'").format(str(e))
            raise rioserrors.GdalWarpError(msg)
        finally:
            if not usingExceptions:
                gdal.DontUseExceptions()

        # return the new dataset
        return newds
Beispiel #18
0
def writeColumnToBand(gdalBand,
                      colName,
                      sequence,
                      colType=None,
                      colUsage=gdal.GFU_Generic):
    """
    Given a GDAL band, Writes the data specified in sequence 
    (can be list, tuple or array etc)
    to the named column in the attribute table assocated with the
    gdalBand. colType must be one of gdal.GFT_Integer,gdal.GFT_Real,gdal.GFT_String.
    can specify one of the gdal.GFU_* constants for colUsage - default is 'generic'
    GDAL dataset must have been created, or opened with GA_Update
    """

    if colType is None:
        colType = inferColumnType(sequence)
    if colType is None:
        msg = "Can't infer type of column for sequence of %s" % type(
            sequence[0])
        raise rioserrors.AttributeTableTypeError(msg)

    # check it is acually a valid type
    elif colType not in (gdal.GFT_Integer, gdal.GFT_Real, gdal.GFT_String):
        msg = "coltype must be a valid gdal column type"
        raise rioserrors.AttributeTableTypeError(msg)

    # things get a bit weird here as we need different
    # behaviour depending on whether we have an RFC40
    # RAT or not.
    if hasattr(gdal.RasterAttributeTable, "WriteArray"):
        # new behaviour
        attrTbl = gdalBand.GetDefaultRAT()
        if attrTbl is None:
            # some formats eg ENVI return None
            # here so we need to be able to cope
            attrTbl = gdal.RasterAttributeTable()
            isFileRAT = False
        else:

            isFileRAT = True

            # but if it doesn't support dynamic writing
            # we still ahve to call SetDefaultRAT
            if not attrTbl.ChangesAreWrittenToFile():
                isFileRAT = False

    else:
        # old behaviour
        attrTbl = gdal.RasterAttributeTable()
        isFileRAT = False

    # thanks to RFC40 we need to ensure colname doesn't already exist
    colExists = False
    for n in range(attrTbl.GetColumnCount()):
        if attrTbl.GetNameOfCol(n) == colName:
            colExists = True
            colNum = n
            break
    if not colExists:
        # preserve usage
        attrTbl.CreateColumn(colName, colType, colUsage)
        colNum = attrTbl.GetColumnCount() - 1

    rowsToAdd = len(sequence)
    # Imagine has trouble if not 256 items for byte
    if gdalBand.DataType == gdal.GDT_Byte:
        rowsToAdd = 256

    # another hack to hide float (0-1) and int (0-255)
    # color table handling.
    # we assume that the column has already been created
    # of the right type appropriate for the format (maybe by calcstats)
    # Note: this only works post RFC40 when we have an actual reference
    # to the RAT rather than a new one so we can ask GetTypeOfCol
    usage = attrTbl.GetUsageOfCol(colNum)
    if (isColorColFromUsage(usage)
            and attrTbl.GetTypeOfCol(colNum) == gdal.GFT_Real
            and colType == gdal.GFT_Integer):
        sequence = numpy.array(sequence, dtype=numpy.float)
        sequence = sequence / 255.0

    if hasattr(attrTbl, "WriteArray"):
        # if GDAL > 1.10 has these functions
        # thanks to RFC40
        attrTbl.SetRowCount(rowsToAdd)
        attrTbl.WriteArray(sequence, colNum)

    elif HAVE_TURBORAT:
        # use turborat to write values to RAT if available
        if not isinstance(sequence, numpy.ndarray):
            # turborat.writeColumn needs an array
            sequence = numpy.array(sequence)

        # If the dtype of the array is some unicode type, then convert to simple string type,
        # as turborat does not cope with the unicode variant.
        if 'U' in str(sequence.dtype):
            sequence = sequence.astype(numpy.character)

        turborat.writeColumn(attrTbl, colNum, sequence, rowsToAdd)
    else:
        defaultValues = {
            gdal.GFT_Integer: 0,
            gdal.GFT_Real: 0.0,
            gdal.GFT_String: ''
        }

        # go thru and set each value into the RAT
        for rowNum in range(rowsToAdd):
            if rowNum >= len(sequence):
                # they haven't given us enough values - fill in with default
                val = defaultValues[colType]
            else:
                val = sequence[rowNum]

            if colType == gdal.GFT_Integer:
                # appears that swig cannot convert numpy.int64
                # to the int type required by SetValueAsInt
                # so we need to cast.
                # This is a problem as readColumn returns numpy.int64
                # for integer columns.
                # Seems fine converting numpy.float64 to
                # float however for SetValueAsDouble.
                attrTbl.SetValueAsInt(rowNum, colNum, int(val))
            elif colType == gdal.GFT_Real:
                attrTbl.SetValueAsDouble(rowNum, colNum, float(val))
            else:
                attrTbl.SetValueAsString(rowNum, colNum, val)

    if not isFileRAT:
        # assume existing bands re-written
        # Use GDAL's exceptions to trap the error message which arises when
        # writing to a format which does not support it
        usingExceptions = gdal.GetUseExceptions()
        gdal.UseExceptions()
        try:
            gdalBand.SetDefaultRAT(attrTbl)
        except Exception:
            pass
        if not usingExceptions:
            gdal.DontUseExceptions()
Beispiel #19
0
def addStatistics(ds, progress, ignore=None):
    """
    Calculates statistics and adds them to the image
    
    Uses gdal.Band.ComputeStatistics() for mean, stddev, min and max,
    and gdal.Band.GetHistogram() to do histogram calculation. 
    The median and mode are estimated using the histogram, and so 
    for larger datatypes, they will be approximate only. 
    
    For thematic layers, the histogram is calculated with as many bins 
    as required, for athematic integer and float types, a maximum
    of 256 bins is used. 
    
    """
    progress.setLabelText("Computing Statistics...")
    progress.setProgress(0)
    percent = 0
    percentstep = 100.0 / (ds.RasterCount * 2)  # 2 steps for each layer

    for bandnum in range(ds.RasterCount):
        band = ds.GetRasterBand(bandnum + 1)

        # fill in the metadata
        tmpmeta = band.GetMetadata()

        if ignore is not None:
            # tell QGIS that the ignore value was ignored
            band.SetNoDataValue(ignore)
            tmpmeta["STATISTICS_EXCLUDEDVALUES"] = repr(
                ignore)  # doesn't seem to do anything

        # get GDAL to calculate statistics - force recalculation. Trap errors
        useExceptions = gdal.GetUseExceptions()
        gdal.UseExceptions()
        try:
            (minval, maxval, meanval,
             stddevval) = band.ComputeStatistics(False)
        except RuntimeError as e:
            if str(e).endswith(
                    'Failed to compute statistics, no valid pixels found in sampling.'
            ):
                minval = ignore
                maxval = ignore
                meanval = ignore
                stddevval = 0
        if not useExceptions:
            gdal.DontUseExceptions()

        percent = percent + percentstep
        progress.setProgress(percent)

        tmpmeta["STATISTICS_MINIMUM"] = repr(minval)
        tmpmeta["STATISTICS_MAXIMUM"] = repr(maxval)
        tmpmeta["STATISTICS_MEAN"] = repr(meanval)
        tmpmeta["STATISTICS_STDDEV"] = repr(stddevval)
        # because we did at full res - these are the default anyway
        tmpmeta["STATISTICS_SKIPFACTORX"] = "1"
        tmpmeta["STATISTICS_SKIPFACTORY"] = "1"

        # create a histogram so we can do the mode and median
        if band.DataType == gdal.GDT_Byte:
            # if byte data use 256 bins and the whole range
            histmin = 0
            histmax = 255
            histstep = 1.0
            histCalcMin = -0.5
            histCalcMax = 255.5
            histnbins = 256
            tmpmeta["STATISTICS_HISTOBINFUNCTION"] = 'direct'
        elif "LAYER_TYPE" in tmpmeta and tmpmeta["LAYER_TYPE"] == 'thematic':
            # all other thematic types a bin per value
            histmin = 0
            histmax = int(numpy.ceil(maxval))
            histstep = 1.0
            histCalcMin = -0.5
            histCalcMax = maxval + 0.5
            histnbins = histmax + 1
            tmpmeta["STATISTICS_HISTOBINFUNCTION"] = 'direct'
        elif band.DataType in gdalLargeIntTypes:
            histrange = int(numpy.ceil(maxval) - numpy.floor(minval)) + 1
            (histmin, histmax) = (minval, maxval)
            if histrange <= 256:
                histnbins = histrange
                histstep = 1.0
                tmpmeta["STATISTICS_HISTOBINFUNCTION"] = 'direct'
                histCalcMin = histmin - 0.5
                histCalcMax = histmax + 0.5
            else:
                histnbins = 256
                tmpmeta["STATISTICS_HISTOBINFUNCTION"] = 'linear'
                histCalcMin = histmin
                histCalcMax = histmax
                histstep = float(histCalcMax - histCalcMin) / histnbins
        elif band.DataType in gdalFloatTypes:
            histnbins = 256
            (histmin, histmax) = (minval, maxval)
            tmpmeta["STATISTICS_HISTOBINFUNCTION"] = 'linear'
            histCalcMin = minval
            histCalcMax = maxval
            histstep = float(histCalcMax - histCalcMin) / histnbins
        # Note that the complex number data types are not handled, as I am not sure
        # what a histogram or a median would mean for such types.

        userdata = ProgressUserData()
        userdata.progress = progress
        userdata.nbands = ds.RasterCount * 2
        userdata.curroffset = percent

        # get histogram and force GDAL to recalculate it
        hist = band.GetHistogram(histCalcMin, histCalcMax, histnbins, False,
                                 False, progressFunc, userdata)

        # Check if GDAL's histogram code overflowed. This is not a fool-proof test,
        # as some overflows will not result in negative counts.
        histogramOverflow = (min(hist) < 0)

        # we may use this rat reference for the colours below also
        # may be None if format does not support RATs
        rat = band.GetDefaultRAT()

        if not histogramOverflow:
            # comes back as a list for some reason
            hist = numpy.array(hist)

            # Note that we have explicitly set histstep in each datatype case
            # above. In principle, this can be calculated, as it is done in the
            # float case, but for some of the others we need it to be exactly
            # equal to 1, so we set it explicitly there, to avoid rounding
            # error problems.

            # do the mode - bin with the highest count
            modebin = numpy.argmax(hist)
            modeval = modebin * histstep + histmin
            if band.DataType == gdal.GDT_Float32 or band.DataType == gdal.GDT_Float64:
                tmpmeta["STATISTICS_MODE"] = repr(modeval)
            else:
                tmpmeta["STATISTICS_MODE"] = repr(int(round(modeval)))

            tmpmeta["STATISTICS_HISTOMIN"] = repr(histmin)
            tmpmeta["STATISTICS_HISTOMAX"] = repr(histmax)
            tmpmeta["STATISTICS_HISTONUMBINS"] = repr(histnbins)

            if haveRFC40 and rat is not None:
                histIndx, histNew = findOrCreateColumn(rat,
                                                       gdal.GFU_PixelCount,
                                                       "Histogram",
                                                       gdal.GFT_Real)
                # write the hist in a single go
                rat.SetRowCount(histnbins)
                rat.WriteArray(hist, histIndx)

                # The HFA driver still honours the STATISTICS_HISTOBINVALUES
                # metadata item. If we are recalculating the histogram the old
                # values will be copied across with the metadata so clobber it
                if "STATISTICS_HISTOBINVALUES" in tmpmeta:
                    del tmpmeta["STATISTICS_HISTOBINVALUES"]
            else:
                # old method
                tmpmeta["STATISTICS_HISTOBINVALUES"] = '|'.join(map(
                    repr, hist)) + '|'

            # estimate the median - bin with the middle number
            middlenum = hist.sum() / 2
            gtmiddle = hist.cumsum() >= middlenum
            medianbin = gtmiddle.nonzero()[0][0]
            medianval = medianbin * histstep + histmin
            if band.DataType == gdal.GDT_Float32 or band.DataType == gdal.GDT_Float64:
                tmpmeta["STATISTICS_MEDIAN"] = repr(medianval)
            else:
                tmpmeta["STATISTICS_MEDIAN"] = repr(int(round(medianval)))

        # set the data
        band.SetMetadata(tmpmeta)

        # if it is thematic and there is no colour table
        # add one because Imagine fails in weird ways otherwise
        # we make a random colour table to make it obvious
        if "LAYER_TYPE" in tmpmeta and tmpmeta["LAYER_TYPE"] == 'thematic':
            # old way
            if (not haveRFC40 or rat is None) and band.GetColorTable() is None:
                import random  # this also seeds on the time
                colorTable = gdal.ColorTable()
                alpha = 255
                for i in range(histnbins):
                    c1 = int(random.random() * 255)
                    c2 = int(random.random() * 255)
                    c3 = int(random.random() * 255)
                    entry = (c1, c2, c3, alpha)
                    colorTable.SetColorEntry(i, entry)
                #band.SetColorTable(colorTable)
            elif haveRFC40 and rat is not None:
                # check all the columns
                redIdx, redNew = findOrCreateColumn(rat, gdal.GFU_Red, "Red",
                                                    gdal.GFT_Integer)
                greenIdx, greenNew = findOrCreateColumn(
                    rat, gdal.GFU_Green, "Green", gdal.GFT_Integer)
                blueIdx, blueNew = findOrCreateColumn(rat, gdal.GFU_Blue,
                                                      "Blue", gdal.GFT_Integer)
                alphaIdx, alphaNew = findOrCreateColumn(
                    rat, gdal.GFU_Alpha, "Alpha", gdal.GFT_Integer)
                # were any of these not already existing?
                if redNew or greenNew or blueNew or alphaNew:
                    data = numpy.random.randint(0, 256, histnbins)
                    rat.WriteArray(data, redIdx)
                    data = numpy.random.randint(0, 256, histnbins)
                    rat.WriteArray(data, greenIdx)
                    data = numpy.random.randint(0, 256, histnbins)
                    rat.WriteArray(data, blueIdx)
                    data = numpy.empty(histnbins, dtype=numpy.int)
                    data.fill(255)
                    #rat.WriteArray(data, alphaIdx)

        if haveRFC40 and rat is not None and not rat.ChangesAreWrittenToFile():
            # For drivers that require the in memory thing
            band.SetDefaultRAT(rat)

        percent = percent + percentstep
        progress.setProgress(percent)

        if progress.wasCancelled():
            raise ProcessCancelledError()

    progress.setProgress(100)