Merge pull request #1690 from emlys/task/1570
enable gdal.UseExceptions in entrypoints and tests
This commit is contained in:
commit
ec88d787e4
|
@ -48,6 +48,8 @@ Unreleased Changes
|
|||
reflect changes in how InVEST is installed on modern systems, and also to
|
||||
include images of the InVEST workbench instead of just broken links.
|
||||
https://github.com/natcap/invest/issues/1660
|
||||
* natcap.invest now works with (and requires) ``gdal.UseExceptions``. A
|
||||
``FutureWarning`` is raised on import if GDAL exceptions are not enabled.
|
||||
* Workbench
|
||||
* Several small updates to the model input form UI to improve usability
|
||||
and visual consistency (https://github.com/natcap/invest/issues/912).
|
||||
|
|
|
@ -4,8 +4,10 @@ import logging
|
|||
import os
|
||||
import sys
|
||||
from gettext import translation
|
||||
import warnings
|
||||
|
||||
import babel
|
||||
from osgeo import gdal
|
||||
|
||||
LOGGER = logging.getLogger('natcap.invest')
|
||||
LOGGER.addHandler(logging.NullHandler())
|
||||
|
@ -28,6 +30,14 @@ LOCALE_NAME_MAP = {
|
|||
locale: babel.Locale(locale).display_name for locale in LOCALES
|
||||
}
|
||||
|
||||
if not gdal.GetUseExceptions():
|
||||
warnings.warn(('''
|
||||
natcap.invest requires GDAL exceptions to be enabled. You must
|
||||
call gdal.UseExceptions() to avoid unexpected behavior from
|
||||
natcap.invest. A future version will enable exceptions on import.
|
||||
gdal.UseExceptions() affects global state, so this may affect the
|
||||
behavior of other packages.'''), FutureWarning)
|
||||
|
||||
|
||||
def set_locale(locale_code):
|
||||
"""Set the `gettext` attribute of natcap.invest.
|
||||
|
|
|
@ -12,14 +12,15 @@ import sys
|
|||
import textwrap
|
||||
import warnings
|
||||
|
||||
import natcap.invest
|
||||
from natcap.invest import datastack
|
||||
from natcap.invest import model_metadata
|
||||
from natcap.invest import set_locale
|
||||
from natcap.invest import spec_utils
|
||||
from natcap.invest import ui_server
|
||||
from natcap.invest import utils
|
||||
|
||||
from pygeoprocessing.geoprocessing_core import GDALUseExceptions
|
||||
with GDALUseExceptions():
|
||||
import natcap.invest
|
||||
from natcap.invest import datastack
|
||||
from natcap.invest import model_metadata
|
||||
from natcap.invest import set_locale
|
||||
from natcap.invest import spec_utils
|
||||
from natcap.invest import ui_server
|
||||
from natcap.invest import utils
|
||||
|
||||
DEFAULT_EXIT_CODE = 1
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
@ -218,6 +219,7 @@ def main(user_args=None):
|
|||
so models may be run in this way without having GUI packages
|
||||
installed.
|
||||
"""
|
||||
with GDALUseExceptions():
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
'Integrated Valuation of Ecosystem Services and Tradeoffs. '
|
||||
|
|
|
@ -1737,15 +1737,16 @@ def extract_bathymetry_along_ray(
|
|||
iy = int((point.y - bathy_gt[3]) / bathy_gt[5])
|
||||
win_size = 1
|
||||
|
||||
try:
|
||||
value = bathy_band.ReadAsArray(
|
||||
xoff=ix, yoff=iy,
|
||||
win_xsize=win_size, win_ysize=win_size)
|
||||
if value is None:
|
||||
except RuntimeError as ex:
|
||||
location = {'xoff': ix, 'yoff': iy, 'win_xsize': win_size,
|
||||
'win_ysize': win_size}
|
||||
raise ValueError(
|
||||
f'got a {value} when trying to read bathymetry at {location}. '
|
||||
'Does the bathymetry input fully cover the fetch ray area?')
|
||||
f'Failed to read bathymetry at {location}. Does the bathymetry '
|
||||
'input fully cover the fetch ray area?') from ex
|
||||
if bathy_nodata is None or not numpy.isclose(
|
||||
value[0][0], bathy_nodata, equal_nan=True):
|
||||
bathy_values.append(value)
|
||||
|
@ -2468,8 +2469,13 @@ def search_for_vector_habitat(
|
|||
|
||||
geometry = feature.GetGeometryRef()
|
||||
if not geometry.IsValid():
|
||||
try:
|
||||
geometry = geometry.Buffer(0) # sometimes this fixes geometry
|
||||
if geometry is not None: # geometry is None if the buffer failed.
|
||||
except RuntimeError:
|
||||
LOGGER.warning(
|
||||
f"FID {feature.GetFID()} in {habitat_vector_path} has invalid "
|
||||
"geometry and will be excluded")
|
||||
continue
|
||||
clipped_geometry = geometry.Intersection(base_srs_clipping_geom)
|
||||
if not clipped_geometry.IsEmpty():
|
||||
if target_spatial_reference != base_spatial_reference:
|
||||
|
@ -2483,10 +2489,6 @@ def search_for_vector_habitat(
|
|||
shapely_geom = shapely.wkb.loads(
|
||||
bytes(clipped_geometry.ExportToWkb()))
|
||||
shapely_geometry_list.extend(_list_geometry(shapely_geom))
|
||||
else:
|
||||
LOGGER.warning(
|
||||
f"FID {feature.GetFID()} in {habitat_vector_path} has invalid "
|
||||
"geometry and will be excluded")
|
||||
|
||||
if not shapely_geometry_list:
|
||||
LOGGER.warning(f'No valid features exist in {habitat_vector_path}')
|
||||
|
|
|
@ -782,6 +782,7 @@ def _build_spatial_index(
|
|||
# put all the polygons in the kd_tree because it's fast and simple
|
||||
for poly_feature in model_layer:
|
||||
poly_geom = poly_feature.GetGeometryRef()
|
||||
if poly_geom.IsValid():
|
||||
poly_centroid = poly_geom.Centroid()
|
||||
# put in row/col order since rasters are row/col indexed
|
||||
kd_points.append([poly_centroid.GetY(), poly_centroid.GetX()])
|
||||
|
@ -790,6 +791,8 @@ def _build_spatial_index(
|
|||
poly_feature.GetField(feature_id) for feature_id in
|
||||
['theta1', 'theta2', 'theta3']])
|
||||
method_model_parameter.append(poly_feature.GetField('method'))
|
||||
else:
|
||||
LOGGER.warning(f'skipping invalid geometry {poly_geom}')
|
||||
|
||||
method_model_parameter = numpy.array(
|
||||
method_model_parameter, dtype=numpy.int32)
|
||||
|
|
|
@ -1603,26 +1603,18 @@ def _validate_same_projection(base_vector_path, table_path):
|
|||
|
||||
invalid_projections = False
|
||||
for path in data_paths:
|
||||
|
||||
def error_handler(err_level, err_no, err_msg):
|
||||
"""Empty error handler to avoid stderr output."""
|
||||
pass
|
||||
gdal.PushErrorHandler(error_handler)
|
||||
gis_type = pygeoprocessing.get_gis_type(path)
|
||||
if gis_type == pygeoprocessing.UNKNOWN_TYPE:
|
||||
return f"{path} did not load"
|
||||
elif gis_type == pygeoprocessing.RASTER_TYPE:
|
||||
raster = gdal.OpenEx(path, gdal.OF_RASTER)
|
||||
gdal.PopErrorHandler()
|
||||
if raster is not None:
|
||||
projection_as_str = raster.GetProjection()
|
||||
ref = osr.SpatialReference()
|
||||
ref.ImportFromWkt(projection_as_str)
|
||||
raster = None
|
||||
else:
|
||||
vector = gdal.OpenEx(path, gdal.OF_VECTOR)
|
||||
if vector is None:
|
||||
return f"{path} did not load"
|
||||
layer = vector.GetLayer()
|
||||
ref = osr.SpatialReference(layer.GetSpatialRef().ExportToWkt())
|
||||
layer = None
|
||||
vector = None
|
||||
if not base_ref.IsSame(ref):
|
||||
invalid_projections = True
|
||||
if invalid_projections:
|
||||
|
|
|
@ -50,7 +50,9 @@ def _log_gdal_errors(*args, **kwargs):
|
|||
"""Log error messages to osgeo.
|
||||
|
||||
All error messages are logged with reasonable ``logging`` levels based
|
||||
on the GDAL error level.
|
||||
on the GDAL error level. While we are now using ``gdal.UseExceptions()``,
|
||||
we still need this to handle GDAL logging that does not get raised as
|
||||
an exception.
|
||||
|
||||
Note:
|
||||
This function is designed to accept any number of positional and
|
||||
|
|
|
@ -304,19 +304,16 @@ def check_raster(filepath, projected=False, projection_units=None, **kwargs):
|
|||
if file_warning:
|
||||
return file_warning
|
||||
|
||||
gdal.PushErrorHandler('CPLQuietErrorHandler')
|
||||
try:
|
||||
gdal_dataset = gdal.OpenEx(filepath, gdal.OF_RASTER)
|
||||
gdal.PopErrorHandler()
|
||||
|
||||
if gdal_dataset is None:
|
||||
except RuntimeError:
|
||||
return MESSAGES['NOT_GDAL_RASTER']
|
||||
|
||||
# Check that an overview .ovr file wasn't opened.
|
||||
if os.path.splitext(filepath)[1] == '.ovr':
|
||||
return MESSAGES['OVR_FILE']
|
||||
|
||||
srs = osr.SpatialReference()
|
||||
srs.ImportFromWkt(gdal_dataset.GetProjection())
|
||||
|
||||
srs = gdal_dataset.GetSpatialRef()
|
||||
projection_warning = _check_projection(srs, projected, projection_units)
|
||||
if projection_warning:
|
||||
gdal_dataset = None
|
||||
|
@ -378,9 +375,10 @@ def check_vector(filepath, geometries, fields=None, projected=False,
|
|||
if file_warning:
|
||||
return file_warning
|
||||
|
||||
gdal.PushErrorHandler('CPLQuietErrorHandler')
|
||||
try:
|
||||
gdal_dataset = gdal.OpenEx(filepath, gdal.OF_VECTOR)
|
||||
gdal.PopErrorHandler()
|
||||
except RuntimeError:
|
||||
return MESSAGES['NOT_GDAL_VECTOR']
|
||||
|
||||
geom_map = {
|
||||
'POINT': [ogr.wkbPoint, ogr.wkbPointM, ogr.wkbPointZM,
|
||||
|
@ -402,9 +400,6 @@ def check_vector(filepath, geometries, fields=None, projected=False,
|
|||
for geom in geometries:
|
||||
allowed_geom_types += geom_map[geom]
|
||||
|
||||
if gdal_dataset is None:
|
||||
return MESSAGES['NOT_GDAL_VECTOR']
|
||||
|
||||
# NOTE: this only checks the layer geometry type, not the types of the
|
||||
# actual geometries (layer.GetGeometryTypes()). This is probably equivalent
|
||||
# in most cases, and it's more efficient than checking every geometry, but
|
||||
|
|
|
@ -1148,23 +1148,18 @@ def _copy_vector_or_raster(base_file_path, target_file_path):
|
|||
ValueError if the base file can't be opened by GDAL.
|
||||
|
||||
"""
|
||||
# Open the file as raster first
|
||||
gis_type = pygeoprocessing.get_gis_type(base_file_path)
|
||||
if gis_type == pygeoprocessing.RASTER_TYPE:
|
||||
source_dataset = gdal.OpenEx(base_file_path, gdal.OF_RASTER)
|
||||
target_driver_name = _RASTER_DRIVER_NAME
|
||||
if source_dataset is None:
|
||||
# File didn't open as a raster; assume it's a vector
|
||||
elif gis_type == pygeoprocessing.VECTOR_TYPE:
|
||||
source_dataset = gdal.OpenEx(base_file_path, gdal.OF_VECTOR)
|
||||
target_driver_name = _VECTOR_DRIVER_NAME
|
||||
|
||||
# Raise an exception if the file can't be opened by GDAL
|
||||
if source_dataset is None:
|
||||
raise ValueError(
|
||||
'File %s is neither a GDAL-compatible raster nor vector.'
|
||||
% base_file_path)
|
||||
|
||||
else:
|
||||
raise ValueError(f'File {base_file_path} is neither a GDAL-compatible '
|
||||
'raster nor vector.')
|
||||
driver = gdal.GetDriverByName(target_driver_name)
|
||||
driver.CreateCopy(target_file_path, source_dataset)
|
||||
source_dataset = None
|
||||
|
||||
|
||||
def _interpolate_vector_field_onto_raster(
|
||||
|
|
|
@ -1845,7 +1845,7 @@ def _mask_by_distance(base_raster_path, min_dist, max_dist, out_nodata,
|
|||
|
||||
|
||||
def _create_distance_raster(base_raster_path, base_vector_path,
|
||||
target_dist_raster_path, work_dir):
|
||||
target_dist_raster_path, work_dir, where_clause=None):
|
||||
"""Create and rasterize vector onto a raster, and calculate dist transform.
|
||||
|
||||
Create a raster where the pixel values represent the euclidean distance to
|
||||
|
@ -1857,6 +1857,9 @@ def _create_distance_raster(base_raster_path, base_vector_path,
|
|||
base_vector_path (str): path to vector to be rasterized.
|
||||
target_dist_raster_path (str): path to raster with distance transform.
|
||||
work_dir (str): path to create a temp folder for saving files.
|
||||
where_clause (str): If not None, is an SQL query-like string to filter
|
||||
which features are rasterized. This kwarg is passed to
|
||||
``pygeoprocessing.rasterize``.
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
@ -1884,7 +1887,8 @@ def _create_distance_raster(base_raster_path, base_vector_path,
|
|||
base_vector_path,
|
||||
rasterized_raster_path,
|
||||
burn_values=[1],
|
||||
option_list=["ALL_TOUCHED=TRUE"])
|
||||
option_list=["ALL_TOUCHED=TRUE"],
|
||||
where_clause=where_clause)
|
||||
|
||||
# Calculate euclidean distance transform
|
||||
pygeoprocessing.distance_transform_edt(
|
||||
|
@ -2589,67 +2593,25 @@ def _calculate_distances_land_grid(base_point_vector_path, base_raster_path,
|
|||
# A list to hold the land to grid distances in order for each point
|
||||
# features 'L2G' field
|
||||
l2g_dist = []
|
||||
# A list to hold the individual distance transform path's in order
|
||||
# A list to hold the individual distance transform paths in order
|
||||
land_point_dist_raster_path_list = []
|
||||
|
||||
# Get the original layer definition which holds needed attribute values
|
||||
base_layer_defn = base_point_layer.GetLayerDefn()
|
||||
file_ext, driver_name = _get_file_ext_and_driver_name(
|
||||
base_point_vector_path)
|
||||
output_driver = ogr.GetDriverByName(driver_name)
|
||||
single_feature_vector_path = os.path.join(
|
||||
temp_dir, 'single_feature' + file_ext)
|
||||
target_vector = output_driver.CreateDataSource(single_feature_vector_path)
|
||||
|
||||
# Create the new layer for target_vector using same name and
|
||||
# geometry type from base_vector as well as spatial reference
|
||||
target_layer = target_vector.CreateLayer(base_layer_defn.GetName(),
|
||||
base_point_layer.GetSpatialRef(),
|
||||
base_layer_defn.GetGeomType())
|
||||
|
||||
# Get the number of fields in original_layer
|
||||
base_field_count = base_layer_defn.GetFieldCount()
|
||||
|
||||
# For every field, create a duplicate field and add it to the new
|
||||
# shapefiles layer
|
||||
for fld_index in range(base_field_count):
|
||||
base_field = base_layer_defn.GetFieldDefn(fld_index)
|
||||
target_field = ogr.FieldDefn(base_field.GetName(),
|
||||
base_field.GetType())
|
||||
# NOT setting the WIDTH or PRECISION because that seems to be
|
||||
# unneeded and causes interesting OGR conflicts
|
||||
target_layer.CreateField(target_field)
|
||||
|
||||
fid_field = base_point_layer.GetFIDColumn()
|
||||
if not fid_field:
|
||||
fid_field = 'FID'
|
||||
# Create a new shapefile with only one feature to burn onto a raster
|
||||
# in order to get the distance transform based on that one feature
|
||||
for feature_index, point_feature in enumerate(base_point_layer):
|
||||
# Get the point features land to grid value and add it to the list
|
||||
field_index = point_feature.GetFieldIndex('L2G')
|
||||
l2g_dist.append(float(point_feature.GetField(field_index)))
|
||||
l2g_dist.append(float(point_feature.GetField('L2G')))
|
||||
|
||||
# Copy original_datasource's feature and set as new shapes feature
|
||||
output_feature = ogr.Feature(feature_def=target_layer.GetLayerDefn())
|
||||
|
||||
# Since the original feature is of interest add its fields and
|
||||
# Values to the new feature from the intersecting geometries
|
||||
# The False in SetFrom() signifies that the fields must match
|
||||
# exactly
|
||||
output_feature.SetFrom(point_feature, False)
|
||||
target_layer.CreateFeature(output_feature)
|
||||
target_vector.SyncToDisk()
|
||||
target_layer.DeleteFeature(point_feature.GetFID())
|
||||
|
||||
dist_raster_path = os.path.join(temp_dir,
|
||||
'dist_%s.tif' % feature_index)
|
||||
_create_distance_raster(base_raster_path, single_feature_vector_path,
|
||||
dist_raster_path, work_dir)
|
||||
dist_raster_path = os.path.join(temp_dir, f'dist_{feature_index}.tif')
|
||||
_create_distance_raster(
|
||||
base_raster_path, base_point_vector_path, dist_raster_path,
|
||||
work_dir, where_clause=f'{fid_field}={point_feature.GetFID()}')
|
||||
# Add each features distance transform result to list
|
||||
land_point_dist_raster_path_list.append(dist_raster_path)
|
||||
|
||||
target_layer = None
|
||||
target_vector = None
|
||||
base_point_layer = None
|
||||
base_point_vector = None
|
||||
l2g_dist_array = numpy.array(l2g_dist)
|
||||
|
||||
def _min_land_ocean_dist(*grid_distances):
|
||||
|
|
|
@ -6,13 +6,14 @@ import os
|
|||
|
||||
import pandas
|
||||
import numpy
|
||||
from osgeo import gdal
|
||||
import pygeoprocessing
|
||||
|
||||
|
||||
REGRESSION_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data', 'annual_water_yield')
|
||||
SAMPLE_DATA = os.path.join(REGRESSION_DATA, 'input')
|
||||
|
||||
gdal.UseExceptions()
|
||||
|
||||
class AnnualWaterYieldTests(unittest.TestCase):
|
||||
"""Regression Tests for Annual Water Yield Model."""
|
||||
|
|
|
@ -12,6 +12,7 @@ import numpy.random
|
|||
import numpy.testing
|
||||
import pygeoprocessing
|
||||
|
||||
gdal.UseExceptions()
|
||||
|
||||
def make_simple_raster(base_raster_path, fill_val, nodata_val):
|
||||
"""Create a 10x10 raster on designated path with fill value.
|
||||
|
|
|
@ -10,12 +10,13 @@ import json
|
|||
import importlib
|
||||
import uuid
|
||||
|
||||
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
from osgeo import gdal
|
||||
gdal.UseExceptions()
|
||||
|
||||
@contextlib.contextmanager
|
||||
def redirect_stdout():
|
||||
|
|
|
@ -17,6 +17,7 @@ from natcap.invest import validation
|
|||
from osgeo import gdal
|
||||
from osgeo import osr
|
||||
|
||||
gdal.UseExceptions()
|
||||
REGRESSION_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data',
|
||||
'coastal_blue_carbon')
|
||||
|
|
|
@ -20,6 +20,7 @@ from shapely.geometry import MultiPolygon
|
|||
from shapely.geometry import Point
|
||||
from shapely.geometry import Polygon
|
||||
|
||||
gdal.UseExceptions()
|
||||
REGRESSION_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data',
|
||||
'coastal_vulnerability')
|
||||
|
|
|
@ -9,6 +9,7 @@ from osgeo import gdal
|
|||
import pandas
|
||||
import pygeoprocessing
|
||||
|
||||
gdal.UseExceptions()
|
||||
MODEL_DATA_PATH = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data',
|
||||
'crop_production_model', 'model_data')
|
||||
|
|
|
@ -18,6 +18,7 @@ import shapely.geometry
|
|||
from osgeo import gdal
|
||||
from osgeo import ogr
|
||||
|
||||
gdal.UseExceptions()
|
||||
_TEST_FILE_CWD = os.path.dirname(os.path.abspath(__file__))
|
||||
DATA_DIR = os.path.join(_TEST_FILE_CWD,
|
||||
'..', 'data', 'invest-test-data', 'data_stack')
|
||||
|
|
|
@ -19,6 +19,7 @@ from shapely.geometry import box
|
|||
from shapely.geometry import MultiPoint
|
||||
from shapely.geometry import Point
|
||||
|
||||
gdal.UseExceptions()
|
||||
REGRESSION_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data',
|
||||
'delineateit')
|
||||
|
|
|
@ -7,7 +7,7 @@ import os
|
|||
from osgeo import gdal
|
||||
import numpy
|
||||
|
||||
|
||||
gdal.UseExceptions()
|
||||
REGRESSION_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data',
|
||||
'forest_carbon_edge_effect')
|
||||
|
|
|
@ -12,6 +12,7 @@ from osgeo import ogr
|
|||
from osgeo import osr
|
||||
from shapely.geometry import Polygon
|
||||
|
||||
gdal.UseExceptions()
|
||||
|
||||
def make_raster_from_array(
|
||||
base_array, base_raster_path, nodata_val=-1, gdal_type=gdal.GDT_Int32):
|
||||
|
|
|
@ -18,6 +18,7 @@ from osgeo import gdal
|
|||
from osgeo import ogr
|
||||
from osgeo import osr
|
||||
|
||||
gdal.UseExceptions()
|
||||
ORIGIN = (1180000.0, 690000.0)
|
||||
_SRS = osr.SpatialReference()
|
||||
_SRS.ImportFromEPSG(26910) # UTM zone 10N
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
import unittest
|
||||
import os
|
||||
|
||||
from osgeo import gdal
|
||||
gdal.UseExceptions()
|
||||
|
||||
class FileRegistryTests(unittest.TestCase):
|
||||
"""Tests for the InVEST file registry builder."""
|
||||
|
|
|
@ -4,7 +4,9 @@ import unittest
|
|||
|
||||
import pint
|
||||
from natcap.invest.model_metadata import MODEL_METADATA
|
||||
from osgeo import gdal
|
||||
|
||||
gdal.UseExceptions()
|
||||
valid_nested_types = {
|
||||
None: { # if no parent type (arg is top-level), then all types are valid
|
||||
'boolean',
|
||||
|
|
|
@ -12,6 +12,7 @@ from osgeo import gdal
|
|||
from osgeo import ogr
|
||||
from osgeo import osr
|
||||
|
||||
gdal.UseExceptions()
|
||||
REGRESSION_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data', 'ndr')
|
||||
|
||||
|
|
|
@ -7,9 +7,11 @@ import unittest
|
|||
import numpy
|
||||
import pygeoprocessing
|
||||
import shapely.geometry
|
||||
from osgeo import gdal
|
||||
from osgeo import ogr
|
||||
from osgeo import osr
|
||||
|
||||
gdal.UseExceptions()
|
||||
REGRESSION_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data', 'pollination')
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import warnings
|
|||
|
||||
from natcap.invest import utils
|
||||
|
||||
gdal.UseExceptions()
|
||||
Pyro4.config.SERIALIZER = 'marshal' # allow null bytes in strings
|
||||
|
||||
REGRESSION_DATA = os.path.join(
|
||||
|
|
|
@ -9,6 +9,7 @@ import numpy
|
|||
from osgeo import gdal
|
||||
from osgeo import osr
|
||||
|
||||
gdal.UseExceptions()
|
||||
|
||||
class RouteDEMTests(unittest.TestCase):
|
||||
"""Tests for RouteDEM with Pygeoprocessing 1.x routing API."""
|
||||
|
|
|
@ -5,7 +5,9 @@ import shutil
|
|||
import os
|
||||
|
||||
import pandas
|
||||
from osgeo import gdal
|
||||
|
||||
gdal.UseExceptions()
|
||||
TEST_DATA_DIR = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data',
|
||||
'scenario_gen_proximity')
|
||||
|
|
|
@ -14,6 +14,7 @@ from shapely.geometry import LineString
|
|||
from shapely.geometry import Point
|
||||
from shapely.geometry import Polygon
|
||||
|
||||
gdal.UseExceptions()
|
||||
_SRS = osr.SpatialReference()
|
||||
_SRS.ImportFromEPSG(32731) # WGS84 / UTM zone 31s
|
||||
WKT = _SRS.ExportToWkt()
|
||||
|
|
|
@ -9,6 +9,7 @@ import pygeoprocessing
|
|||
from osgeo import gdal
|
||||
from osgeo import osr
|
||||
|
||||
gdal.UseExceptions()
|
||||
REGRESSION_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data', 'sdr')
|
||||
SAMPLE_DATA = os.path.join(REGRESSION_DATA, 'input')
|
||||
|
|
|
@ -10,6 +10,7 @@ from osgeo import gdal
|
|||
from osgeo import ogr
|
||||
from osgeo import osr
|
||||
|
||||
gdal.UseExceptions()
|
||||
REGRESSION_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data',
|
||||
'seasonal_water_yield')
|
||||
|
|
|
@ -2,7 +2,9 @@ import unittest
|
|||
|
||||
from natcap.invest import spec_utils
|
||||
from natcap.invest.unit_registry import u
|
||||
from osgeo import gdal
|
||||
|
||||
gdal.UseExceptions()
|
||||
|
||||
class TestSpecUtils(unittest.TestCase):
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import pygeoprocessing
|
|||
from pygeoprocessing.geoprocessing_core import (
|
||||
DEFAULT_GTIFF_CREATION_TUPLE_OPTIONS as opts_tuple)
|
||||
|
||||
|
||||
gdal.UseExceptions()
|
||||
TEST_DATA = os.path.join(os.path.dirname(
|
||||
__file__), '..', 'data', 'invest-test-data', 'stormwater')
|
||||
|
||||
|
|
|
@ -10,7 +10,9 @@ from unittest.mock import patch
|
|||
from babel.messages import Catalog, mofile
|
||||
import natcap.invest
|
||||
from natcap.invest import validation
|
||||
from osgeo import gdal
|
||||
|
||||
gdal.UseExceptions()
|
||||
TEST_LANG = 'll'
|
||||
|
||||
# assign to local variable so that it won't be changed by translation
|
||||
|
|
|
@ -8,6 +8,7 @@ import numpy
|
|||
import pandas
|
||||
from osgeo import gdal
|
||||
|
||||
gdal.UseExceptions()
|
||||
REGRESSION_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data', 'ucm')
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ from osgeo import gdal
|
|||
from osgeo import ogr
|
||||
from osgeo import osr
|
||||
|
||||
gdal.UseExceptions()
|
||||
|
||||
class UFRMTests(unittest.TestCase):
|
||||
"""Tests for the Urban Flood Risk Mitigation Model."""
|
||||
|
|
|
@ -6,7 +6,9 @@ import unittest
|
|||
from unittest.mock import Mock, patch
|
||||
|
||||
from natcap.invest import ui_server
|
||||
from osgeo import gdal
|
||||
|
||||
gdal.UseExceptions()
|
||||
TEST_DATA_PATH = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data')
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ from osgeo import gdal
|
|||
from osgeo import ogr
|
||||
from osgeo import osr
|
||||
|
||||
gdal.UseExceptions()
|
||||
_DEFAULT_ORIGIN = (444720, 3751320)
|
||||
_DEFAULT_PIXEL_SIZE = (30, -30)
|
||||
_DEFAULT_EPSG = 3116
|
||||
|
|
|
@ -13,6 +13,7 @@ import shapely.geometry
|
|||
import numpy
|
||||
import numpy.testing
|
||||
|
||||
gdal.UseExceptions()
|
||||
|
||||
class UsageLoggingTests(unittest.TestCase):
|
||||
"""Tests for the InVEST usage logging framework."""
|
||||
|
|
|
@ -25,6 +25,7 @@ from osgeo import osr
|
|||
from shapely.geometry import Point
|
||||
from shapely.geometry import Polygon
|
||||
|
||||
gdal.UseExceptions()
|
||||
|
||||
class SuffixUtilsTests(unittest.TestCase):
|
||||
"""Tests for natcap.invest.utils.make_suffix_string."""
|
||||
|
@ -412,17 +413,22 @@ class GDALWarningsLoggingTests(unittest.TestCase):
|
|||
|
||||
logfile = os.path.join(self.workspace, 'logfile.txt')
|
||||
|
||||
# this warning should go to stdout.
|
||||
gdal.Open('this_file_should_not_exist.tif')
|
||||
invalid_polygon = ogr.CreateGeometryFromWkt(
|
||||
'POLYGON ((-20 -20, -16 -20, -20 -16, -16 -16, -20 -20))')
|
||||
|
||||
# This produces a GDAL warning that does not raise an
|
||||
# exception with UseExceptions(). Without capture_gdal_logging,
|
||||
# it will be printed directly to stderr
|
||||
invalid_polygon.IsValid()
|
||||
|
||||
with utils.log_to_file(logfile) as handler:
|
||||
with utils.capture_gdal_logging():
|
||||
# warning should be captured.
|
||||
gdal.Open('file_file_should_also_not_exist.tif')
|
||||
invalid_polygon.IsValid()
|
||||
handler.flush()
|
||||
|
||||
# warning should go to stdout
|
||||
gdal.Open('this_file_should_not_exist.tif')
|
||||
# warning should go to stderr
|
||||
invalid_polygon.IsValid()
|
||||
|
||||
with open(logfile) as opened_logfile:
|
||||
messages = [msg for msg in opened_logfile.read().split('\n')
|
||||
|
@ -499,7 +505,11 @@ class PrepareWorkspaceTests(unittest.TestCase):
|
|||
with utils.prepare_workspace(workspace,
|
||||
'some_model'):
|
||||
warnings.warn('deprecated', UserWarning)
|
||||
gdal.Open('file should not exist')
|
||||
invalid_polygon = ogr.CreateGeometryFromWkt(
|
||||
'POLYGON ((-20 -20, -16 -20, -20 -16, -16 -16, -20 -20))')
|
||||
# This produces a GDAL warning that does not raise an
|
||||
# exception with UseExceptions()
|
||||
invalid_polygon.IsValid()
|
||||
|
||||
self.assertTrue(os.path.exists(workspace))
|
||||
logfile_glob = glob.glob(os.path.join(workspace, '*.txt'))
|
||||
|
@ -509,11 +519,9 @@ class PrepareWorkspaceTests(unittest.TestCase):
|
|||
with open(logfile_glob[0]) as logfile:
|
||||
logfile_text = logfile.read()
|
||||
# all the following strings should be in the logfile.
|
||||
expected_string = (
|
||||
'file should not exist: No such file or directory')
|
||||
self.assertTrue(
|
||||
expected_string in logfile_text) # gdal error captured
|
||||
self.assertEqual(len(re.findall('WARNING', logfile_text)), 1)
|
||||
self.assertTrue( # gdal logging captured
|
||||
'Self-intersection at or near point -18 -18' in logfile_text)
|
||||
self.assertEqual(len(re.findall('WARNING', logfile_text)), 2)
|
||||
self.assertTrue('Elapsed time:' in logfile_text)
|
||||
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ from osgeo import gdal
|
|||
from osgeo import ogr
|
||||
from osgeo import osr
|
||||
|
||||
gdal.UseExceptions()
|
||||
|
||||
class SpatialOverlapTest(unittest.TestCase):
|
||||
"""Test Spatial Overlap."""
|
||||
|
|
|
@ -18,6 +18,7 @@ from shapely.geometry import Point
|
|||
from natcap.invest import utils
|
||||
import pygeoprocessing
|
||||
|
||||
gdal.UseExceptions()
|
||||
REGRESSION_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data', 'wave_energy')
|
||||
SAMPLE_DATA = os.path.join(REGRESSION_DATA, 'input')
|
||||
|
|
|
@ -17,6 +17,7 @@ from osgeo import osr
|
|||
|
||||
import pygeoprocessing
|
||||
|
||||
gdal.UseExceptions()
|
||||
SAMPLE_DATA = os.path.join(
|
||||
os.path.dirname(__file__), '..', 'data', 'invest-test-data', 'wind_energy',
|
||||
'input')
|
||||
|
|
Loading…
Reference in New Issue