def test_png_8(): drv = gdal.GetDriverByName('PNG') ds_src = gdal.Open('data/idat_broken.png') md = ds_src.GetMetadata() assert not md, 'metadata list not expected' # Number of bands has been preserved assert ds_src.RasterCount == 4, 'wrong number of bands' # No reading is performed, so we expect valid reference b = ds_src.GetRasterBand(1) assert b is not None, 'band 1 is missing' # We're not interested in returned value but internal state of GDAL. gdal.PushErrorHandler('CPLQuietErrorHandler') b.ComputeBandStats() err = gdal.GetLastErrorNo() gdal.PopErrorHandler() assert err != 0, 'error condition expected' gdal.PushErrorHandler('CPLQuietErrorHandler') ds_dst = drv.CreateCopy('tmp/idat_broken.png', ds_src) err = gdal.GetLastErrorNo() gdal.PopErrorHandler() ds_src = None assert err != 0, 'error condition expected' assert ds_dst is None, 'dataset not expected' os.remove('tmp/idat_broken.png')
def getStatisticsWithProgress(self, gdalband, localdata=None): """ Helper method. Just quickly returns the stats if they are easily available from GDAL. Calculates them using the supplied progress if not. If localdata is not None, statistics are calulated using the data in this numpy array. """ if localdata is None: # calculate stats for whole image gdal.ErrorReset() # allow approxstats stats = gdalband.GetStatistics(1, 0) if stats == [0, 0, 0, -1] or gdal.GetLastErrorNo() != gdal.CE_None: # need to actually calculate them gdal.ErrorReset() self.newProgress.emit("Calculating Statistics...") # TODO: find a way of ignoring NaNs # When calculating stats on the fly, use approxstats (much faster) # A workaround for broken progress support in GDAL 2.2.0 # see https://trac.osgeo.org/gdal/ticket/6927 if gdal.__version__ == '2.2.0': stats = gdalband.ComputeStatistics(True) else: stats = gdalband.ComputeStatistics(True, GDALProgressFunc, self) self.endProgress.emit() if (stats == [0, 0, 0, -1] or gdal.GetLastErrorNo() != gdal.CE_None): msg = 'unable to calculate statistics' raise viewererrors.StatisticsError(msg) else: # local - using numpy - make sure float not 1-d array for json # ignore NANs minval = float(numpy.nanmin(localdata)) maxval = float(numpy.nanmax(localdata)) mean = float(numpy.nanmean(localdata)) stddev = float(numpy.nanstd(localdata)) stats = [minval, maxval, mean, stddev] # inf and NaNs really stuff things up # must be a better way, but GDAL doesn't seem to have # an option to ignore NaNs and numpy still returns Infs. # Make some numbers up. if not numpy.isfinite(stats[0]): stats[0] = 0.0 if not numpy.isfinite(stats[1]): stats[1] = 10.0 if not numpy.isfinite(stats[2]): stats[2] = 5.0 if not numpy.isfinite(stats[3]): stats[3] = 1.0 return stats
def png_8(): drv = gdal.GetDriverByName( 'PNG' ) ds_src = gdal.Open( 'data/idat_broken.png' ) md = ds_src.GetMetadata() if len(md) > 0: gdaltest.post_reason('metadata list not expected') return 'fail' # Number of bands has been preserved if ds_src.RasterCount != 4: gdaltest.post_reason('wrong number of bands') return 'fail' # No reading is performed, so we expect valid reference b = ds_src.GetRasterBand(1) if b is None: gdaltest.post_reason('band 1 is missing') return 'fail' # We're not interested in returned value but internal state of GDAL. gdal.PushErrorHandler( 'CPLQuietErrorHandler' ) b.ComputeBandStats() err = gdal.GetLastErrorNo() gdal.PopErrorHandler() if err == 0: gdaltest.post_reason('error condition expected') return 'fail' gdal.PushErrorHandler( 'CPLQuietErrorHandler' ) ds_dst = drv.CreateCopy( 'tmp/idat_broken.png', ds_src ) err = gdal.GetLastErrorNo() gdal.PopErrorHandler() ds_src = None if err == 0: gdaltest.post_reason('error condition expected') return 'fail' if ds_dst is not None: gdaltest.post_reason('dataset not expected') return 'fail' os.remove( 'tmp/idat_broken.png' ) return 'success'
def compute_density(mt_p, aoi_p): logger.debug('Computing density...') aoi = gpd.read_file(aoi_p) if len(aoi) == 1: geom_area = aoi.geometry.area else: logger.warning( 'Multiple features found in AOI provided. Using first for density calculation.' ) geom_area = aoi.geometry.area[0] ds = gdal.Open(mt_p) b = ds.GetRasterBand(1) gtf = ds.GetGeoTransform() matchtag_res_x = gtf[1] matchtag_res_y = gtf[5] matchtag_ndv = b.GetNoDataValue() data = b.ReadAsArray() err = gdal.GetLastErrorNo() if err != 0: raise RuntimeError("Matchtag dataset read error: {}, {}".format( gdal.GetLastErrorMsg(), mt_p)) else: data_pixel_count = np.count_nonzero(data != matchtag_ndv) data_area = abs(data_pixel_count * matchtag_res_x * matchtag_res_y) density = data_area / geom_area data = None ds = None return round(density, 2)
def test_ogr2ogr_lib_21(): src_ds = gdal.GetDriverByName('Memory').Create('', 0, 0, 0) lyr = src_ds.CreateLayer('layer') lyr.CreateField(ogr.FieldDefn('foo')) lyr.CreateField(ogr.FieldDefn('bar')) f = ogr.Feature(lyr.GetLayerDefn()) f['foo'] = 'bar' f['bar'] = 'foo' lyr.CreateFeature(f) ds = gdal.VectorTranslate('', src_ds, format='Memory') with gdaltest.error_handler(): gdal.VectorTranslate(ds, src_ds, accessMode='append', selectFields=['foo']) ds = None f.Destroy() src_ds = None if gdal.GetLastErrorNo() != gdalconst.CPLE_IllegalArg: gdaltest.post_reason( 'expected use of -select and -append together to be invalid') return 'fail' return 'success'
def SafeGetStatistics(band, approxok, force): """Retrieve statistics form a GDAL raster band in a safe way. If it is not possible to get statistics (e.g. because the force flag is set to false and statistics are not available, or because the approxok is set and there are too many nodata elements in the raster band) then a tuple of four None is returned. :param approxok: if True statistics may be computed based on overviews or a subset of all tiles :param force: if False statistics will only be returned if it can be done without rescanning the image .. note:: in order to check errors due to nodata values the GDAL internal error status is reset. .. important:: this function only works for versions of GDAL in which gdal.Band.GetStatistics correctly reset the return values: 1.6.4 <= GDAL < 1.7.0 and GDAL > 1.7.2 (see `ticket #3572`_ on `GDAL Trac`_. .. _`ticket #3572`: http://trac.osgeo.org/gdal/ticket/3572 .. _`GDAL Trac`: http://trac.osgeo.org/gdal """ if force is False and not HAS_GETSTATS_FORCE_BUG: raise RuntimeError('it is not safe to use gada.Band.GetStatistics ' 'with the "force" parameter set to false with this ' 'version of GDAL (%s)' % gdal.VersionInfo()) gdal.ErrorReset() stats = band.GetStatistics(approxok, force) if stats == [0, 0, 0, -1] or gdal.GetLastErrorNo() != 0: stats = (None, None, None, None) gdal.ErrorReset() if Statistics: stats = Statistics(*stats) return stats
def raise_last_error() -> None: e = gdal.GetLastErrorNo() if e == gdal.CPLE_None: return EClass = CPLE_TO_PYE.get(e) or RuntimeError ex = EClass(gdal.GetLastErrorMsg()) if isinstance(ex, OSError): (msg, ) = ex.args if "No such file or directory" in msg: ex = FileNotFoundError(msg) elif "Permission denied" in msg: ex = PermissionError(msg) ex.strerror = msg raise ex
def __init__(self, msg=None): ''' For raising GDAL related errors @type msg: C{str} @param msg: Initial message to include with GDAL the error message @return None ''' errtype = { gdal.CE_None: 'None', gdal.CE_Debug: 'Debug', gdal.CE_Warning: 'Warning', gdal.CE_Failure: 'Failure', gdal.CE_Fatal: 'Fatal' } self.errmsg = gdal.GetLastErrorMsg().replace('\n', ' ') self.errnum = gdal.GetLastErrorNo() self.errtyp = errtype.get(gdal.GetLastErrorType(), 'None') gdal.ErrorReset() if msg: self.errmsg = '\n'.join([msg, self.errmsg]) Exception.__init__(self, self.errmsg, self.errnum, self.errtyp)
def __init__(self, msg=None, *args, **kwargs): ''' For raising GDAL related errors @type msg: C{str} @param msg: Initial message to include with GDAL the error message @return None @todo: GDAL now has a UseExceptions method, should this class go away? ''' errtype = { gdal.CE_None: 'gdal.CE_None', gdal.CE_Debug: 'gdal.CE_Debug', gdal.CE_Warning: 'gdal.CE_Warning', gdal.CE_Failure: 'gdal.CE_Failure', gdal.CE_Fatal: 'gdal.CE_Fatal' } self.errmsg = gdal.GetLastErrorMsg().replace('\n', ' ') self.errnum = gdal.GetLastErrorNo() self.errtyp = errtype.get(gdal.GetLastErrorType(), 'None') gdal.ErrorReset() if msg: self.errmsg = '\n'.join([msg, self.errmsg]) Exception.__init__(self, (self.errmsg, self.errnum, self.errtyp))
def SafeGetStatistics(band, approx_ok=False, force=True): '''Safe replacement of gdal.Band.GetSrtatistics. The standard version of GetSrtatistics not always allows to know whenever statistics have beed actually computed or not (e.g. "force" flag set to False and no statistics available). This function gracefully handles this case an also cases in which an error happend during statistics computation (e.g. to many nodata values). :param band: GDAL raster band :param approx_ok: if approximate statistics are sufficient, the approx_ok flag can be set to True in which case overviews, or a subset of image tiles may be used in computing the statistics (default: False) :param force: if force is False results will only be returned if it can be done quickly (ie. without scanning the data). If force is False and results cannot be returned efficiently, the function will return four None instead of actual statistics values. Dafault: True. :returns: a tuple containing (min, max, mean, stddev) if statistics can be retriewed according to the input flags. A tuple of four None if statistics are not available or can't be computer according to input flags or if some error occurs during computation. ''' # @NOTE: the band.GetStatistics method called with the second argument # set to False (no image rescanning) has been fixed in # r19666_ (1.6 branch) and r19665_ (1.7 branch) # see `ticket #3572` on `GDAL Trac`_. # # .. _r19666: http://trac.osgeo.org/gdal/changeset/19666 # .. _r19665: http://trac.osgeo.org/gdal/changeset/19665 # .. _`ticket #3572`: http://trac.osgeo.org/gdal/ticket/3572 # .. _`GDAL Trac`: http://trac.osgeo.org/gdal stats = (None, None, None, None) if approx_ok and not SAFE_GDAL_STATS: stats = GetCachedStatistics(band) if None in stats: if not force and not SAFE_GDAL_STATS: raise ValueError('unable to retrieve statistics in a safe way.') gdal.ErrorReset() stats = band.GetStatistics(approx_ok, force) if (gdal.GetLastErrorNo() == 1) and (gdal.GetLastErrorType() == 3): stats = (None, None, None, None) gdal.ErrorReset() elif SAFE_GDAL_STATS and stats == [0, 0, 0, -1]: stats = (None, None, None, None) return stats