rename geometries property to geometry_types
This commit is contained in:
parent
214a617e0d
commit
138337f088
|
@ -326,7 +326,7 @@ class VectorInput(FileInput):
|
|||
are allowed). It is assumed that only the first layer is used.
|
||||
|
||||
Attributes:
|
||||
geometries: A set of geometry type(s) that are allowed for this vector
|
||||
geometry_types: A set of geometry type(s) that are allowed for this vector
|
||||
fields: An iterable of `Input`s representing the fields that this
|
||||
vector is expected to have. The `key` of each input must match the
|
||||
corresponding field name.
|
||||
|
@ -337,7 +337,7 @@ class VectorInput(FileInput):
|
|||
specific unit of projection (such as meters) is required, indicate
|
||||
it here.
|
||||
"""
|
||||
geometries: set = dataclasses.field(default_factory=dict)
|
||||
geometry_types: set = dataclasses.field(default_factory=dict)
|
||||
fields: typing.Union[typing.Iterable[Input], None] = None
|
||||
projected: typing.Union[bool, None] = None
|
||||
projection_units: typing.Union[pint.Unit, None] = None
|
||||
|
@ -383,7 +383,7 @@ class VectorInput(FileInput):
|
|||
}
|
||||
|
||||
allowed_geom_types = []
|
||||
for geom in self.geometries:
|
||||
for geom in self.geometry_types:
|
||||
allowed_geom_types += geom_map[geom]
|
||||
|
||||
# NOTE: this only checks the layer geometry type, not the types of the
|
||||
|
@ -393,7 +393,7 @@ class VectorInput(FileInput):
|
|||
# Currently not supporting ogr.wkbUnknown which allows mixed types.
|
||||
layer = gdal_dataset.GetLayer()
|
||||
if layer.GetGeomType() not in allowed_geom_types:
|
||||
return get_message('WRONG_GEOM_TYPE').format(allowed=self.geometries)
|
||||
return get_message('WRONG_GEOM_TYPE').format(allowed=self.geometry_types)
|
||||
|
||||
if self.fields:
|
||||
field_patterns = []
|
||||
|
@ -420,7 +420,7 @@ class RasterOrVectorInput(SingleBandRasterInput, VectorInput):
|
|||
"""An invest model input that can be either a raster or a vector.
|
||||
|
||||
Attributes:
|
||||
geometries: A set of geometry type(s) that are allowed for this vector
|
||||
geometry_types: A set of geometry type(s) that are allowed for this vector
|
||||
fields: An iterable of `Input`s representing the fields that this
|
||||
vector is expected to have. The `key` of each input must match the
|
||||
corresponding field name.
|
||||
|
@ -432,7 +432,7 @@ class RasterOrVectorInput(SingleBandRasterInput, VectorInput):
|
|||
it here.
|
||||
"""
|
||||
band: typing.Union[Input, None] = None
|
||||
geometries: set = dataclasses.field(default_factory=dict)
|
||||
geometry_types: set = dataclasses.field(default_factory=dict)
|
||||
fields: typing.Union[typing.Iterable[Input], None] = None
|
||||
projected: typing.Union[bool, None] = None
|
||||
projection_units: typing.Union[pint.Unit, None] = None
|
||||
|
@ -1037,12 +1037,12 @@ class VectorOutput(Output):
|
|||
are allowed). It is assumed that only the first layer is used.
|
||||
|
||||
Attributes:
|
||||
geometries: A set of geometry type(s) that are produced in this vector
|
||||
geometry_types: A set of geometry type(s) that are produced in this vector
|
||||
fields: An iterable of `Output`s representing the fields created in
|
||||
this vector. The `key` of each input must match the corresponding
|
||||
field name.
|
||||
"""
|
||||
geometries: set = dataclasses.field(default_factory=set)
|
||||
geometry_types: set = dataclasses.field(default_factory=set)
|
||||
fields: typing.Union[typing.Iterable[Output], None] = None
|
||||
|
||||
@dataclasses.dataclass
|
||||
|
@ -1178,7 +1178,7 @@ class ModelSpec:
|
|||
"""Serialize objects that are otherwise not JSON serializeable."""
|
||||
if isinstance(obj, pint.Unit):
|
||||
return format_unit(obj)
|
||||
# Sets are present in 'geometries' attributes of some args
|
||||
# Sets are present in 'geometry_types' attributes of some args
|
||||
# We don't need to worry about deserializing back to a set/array
|
||||
# so casting to string is okay.
|
||||
elif isinstance(obj, set):
|
||||
|
@ -1272,7 +1272,7 @@ def build_input_spec(argkey, arg):
|
|||
elif t == 'vector':
|
||||
return VectorInput(
|
||||
**base_attrs,
|
||||
geometries=arg['geometries'],
|
||||
geometry_types=arg['geometries'],
|
||||
fields=[build_input_spec(key, field_spec)
|
||||
for key, field_spec in arg['fields'].items()],
|
||||
projected=arg.get('projected', None),
|
||||
|
@ -1308,7 +1308,7 @@ def build_input_spec(argkey, arg):
|
|||
elif t == {'raster', 'vector'}:
|
||||
return RasterOrVectorInput(
|
||||
**base_attrs,
|
||||
geometries=arg['geometries'],
|
||||
geometry_types=arg['geometries'],
|
||||
fields=[build_input_spec(key, field_spec)
|
||||
for key, field_spec in arg['fields'].items()],
|
||||
band=build_input_spec('1', arg['bands'][1]),
|
||||
|
@ -1366,7 +1366,7 @@ def build_output_spec(key, spec):
|
|||
elif t == 'vector':
|
||||
return VectorOutput(
|
||||
**base_attrs,
|
||||
geometries=spec['geometries'],
|
||||
geometry_types=spec['geometries'],
|
||||
fields=[build_output_spec(key, field_spec)
|
||||
for key, field_spec in spec['fields'].items()])
|
||||
|
||||
|
@ -1678,7 +1678,7 @@ def serialize_args_spec(spec):
|
|||
"""Serialize objects that are otherwise not JSON serializeable."""
|
||||
if isinstance(obj, pint.Unit):
|
||||
return format_unit(obj)
|
||||
# Sets are present in 'geometries' attributes of some args
|
||||
# Sets are present in 'geometry_types' attributes of some args
|
||||
# We don't need to worry about deserializing back to a set/array
|
||||
# so casting to string is okay.
|
||||
elif isinstance(obj, set):
|
||||
|
@ -1690,7 +1690,7 @@ def serialize_args_spec(spec):
|
|||
return json.dumps(spec, default=fallback_serializer)
|
||||
|
||||
|
||||
# accepted geometries for a vector will be displayed in this order
|
||||
# accepted geometry_types for a vector will be displayed in this order
|
||||
GEOMETRY_ORDER = [
|
||||
'POINT',
|
||||
'MULTIPOINT',
|
||||
|
@ -1721,18 +1721,18 @@ def format_required_string(required):
|
|||
return gettext('conditionally required')
|
||||
|
||||
|
||||
def format_geometries_string(geometries):
|
||||
"""Represent a set of allowed vector geometries as user-friendly text.
|
||||
def format_geometry_types_string(geometry_types):
|
||||
"""Represent a set of allowed vector geometry types as user-friendly text.
|
||||
|
||||
Args:
|
||||
geometries (set(str)): set of geometry names
|
||||
geometry_types (set(str)): set of geometry names
|
||||
|
||||
Returns:
|
||||
string
|
||||
"""
|
||||
# sort the geometries so they always display in a consistent order
|
||||
# sort the geometry types so they always display in a consistent order
|
||||
sorted_geoms = sorted(
|
||||
geometries,
|
||||
geometry_types,
|
||||
key=lambda g: GEOMETRY_ORDER.index(g))
|
||||
return '/'.join(gettext(geom).lower() for geom in sorted_geoms)
|
||||
|
||||
|
@ -1886,7 +1886,7 @@ def describe_arg_from_spec(name, spec):
|
|||
The first line has the arg name, type, required state, description,
|
||||
and units if applicable. Depending on the type, there may be additional
|
||||
lines that are indented, that describe details of the arg such as
|
||||
vector fields and geometries, option_string options, etc.
|
||||
vector fields and geometry types, option_string options, etc.
|
||||
"""
|
||||
type_string = format_type_string(spec.__class__)
|
||||
in_parentheses = [type_string]
|
||||
|
@ -1905,7 +1905,7 @@ def describe_arg_from_spec(name, spec):
|
|||
in_parentheses.append(f'{translated_units}: **{units_string}**')
|
||||
|
||||
if spec.__class__ is VectorInput:
|
||||
in_parentheses.append(format_geometries_string(spec.geometries))
|
||||
in_parentheses.append(format_geometry_types_string(spec.geometry_types))
|
||||
|
||||
# Represent the required state as a string, defaulting to required
|
||||
# It doesn't make sense to include this for boolean checkboxes
|
||||
|
|
|
@ -9,7 +9,7 @@ MODEL_SPEC = spec.ModelSpec(inputs=[
|
|||
spec.FileInput(id='bar'),
|
||||
spec.DirectoryInput(id='data_dir', contents={}),
|
||||
spec.SingleBandRasterInput(id='raster', band=spec.Input()),
|
||||
spec.VectorInput(id='vector', fields={}, geometries={}),
|
||||
spec.VectorInput(id='vector', fields={}, geometry_types={}),
|
||||
spec.CSVInput(id='simple_table'),
|
||||
spec.CSVInput(
|
||||
id='spatial_table',
|
||||
|
@ -18,7 +18,7 @@ MODEL_SPEC = spec.ModelSpec(inputs=[
|
|||
spec.RasterOrVectorInput(
|
||||
id='path',
|
||||
fields={},
|
||||
geometries={'POINT', 'POLYGON'},
|
||||
geometry_types={'POINT', 'POLYGON'},
|
||||
band=spec.NumberInput()
|
||||
)
|
||||
]
|
||||
|
|
|
@ -2,7 +2,7 @@ from natcap.invest import spec
|
|||
|
||||
MODEL_SPEC = spec.ModelSpec(inputs=[
|
||||
spec.VectorInput(
|
||||
id='vector', fields={}, geometries={})],
|
||||
id='vector', fields={}, geometry_types={})],
|
||||
outputs={},
|
||||
model_id='vector_model',
|
||||
model_title='',
|
||||
|
|
|
@ -204,7 +204,7 @@ class ValidateModelSpecs(unittest.TestCase):
|
|||
# vector type should have:
|
||||
# - a fields property that maps each field header to a nested
|
||||
# type dictionary describing the data in that field
|
||||
# - a geometries property: the set of valid geometry types
|
||||
# - a geometry_types property: the set of valid geometry types
|
||||
self.assertTrue(hasattr(output_spec, 'fields'))
|
||||
for field in output_spec.fields:
|
||||
self.validate_output(
|
||||
|
@ -212,8 +212,8 @@ class ValidateModelSpecs(unittest.TestCase):
|
|||
f'{key}.fields.{field}',
|
||||
parent_type=t)
|
||||
|
||||
self.assertTrue(hasattr(output_spec, 'geometries'))
|
||||
self.assertIsInstance(output_spec.geometries, set)
|
||||
self.assertTrue(hasattr(output_spec, 'geometry_types'))
|
||||
self.assertIsInstance(output_spec.geometry_types, set)
|
||||
|
||||
elif t is spec.CSVOutput:
|
||||
# csv type may have a columns property.
|
||||
|
@ -374,7 +374,7 @@ class ValidateModelSpecs(unittest.TestCase):
|
|||
# vector type should have:
|
||||
# - a fields property that maps each field header to a nested
|
||||
# type dictionary describing the data in that field
|
||||
# - a geometries property: the set of valid geometry types
|
||||
# - a geometry_types property: the set of valid geometry types
|
||||
self.assertTrue(hasattr(arg, 'fields'))
|
||||
for field in arg.fields:
|
||||
self.validate_args(
|
||||
|
@ -382,11 +382,11 @@ class ValidateModelSpecs(unittest.TestCase):
|
|||
f'{name}.fields.{field}',
|
||||
parent_type=t)
|
||||
|
||||
self.assertTrue(hasattr(arg, 'geometries'))
|
||||
self.assertIsInstance(arg.geometries, set)
|
||||
self.assertTrue(hasattr(arg, 'geometry_types'))
|
||||
self.assertIsInstance(arg.geometry_types, set)
|
||||
|
||||
attrs.remove('fields')
|
||||
attrs.remove('geometries')
|
||||
attrs.remove('geometry_types')
|
||||
|
||||
# may optionally have a 'projected' attribute that says
|
||||
# whether the vector must be linearly projected
|
||||
|
|
|
@ -171,7 +171,7 @@ class TestDescribeArgFromSpec(unittest.TestCase):
|
|||
def test_vector_spec(self):
|
||||
vector_spec = spec.VectorInput(
|
||||
fields={},
|
||||
geometries={"LINESTRING"},
|
||||
geometry_types={"LINESTRING"},
|
||||
about="Description",
|
||||
name="Bar"
|
||||
)
|
||||
|
@ -193,7 +193,7 @@ class TestDescribeArgFromSpec(unittest.TestCase):
|
|||
about="Average annual precipitation over the area"
|
||||
)
|
||||
],
|
||||
geometries={"POLYGON", "MULTIPOLYGON"},
|
||||
geometry_types={"POLYGON", "MULTIPOLYGON"},
|
||||
about="Description",
|
||||
name="Bar"
|
||||
)
|
||||
|
@ -251,7 +251,7 @@ class TestDescribeArgFromSpec(unittest.TestCase):
|
|||
about="Description",
|
||||
name="Bar",
|
||||
band=spec.IntegerInput(),
|
||||
geometries={"POLYGON"},
|
||||
geometry_types={"POLYGON"},
|
||||
fields={}
|
||||
)
|
||||
out = spec.describe_arg_from_spec(multi_spec.name, multi_spec)
|
||||
|
@ -328,7 +328,7 @@ class TestMetadataFromSpec(unittest.TestCase):
|
|||
id="admin_boundaries.gpkg",
|
||||
about=("A copy of the user's administrative boundaries "
|
||||
"vector with a single layer."),
|
||||
geometries=spec.POLYGONS,
|
||||
geometry_types=spec.POLYGONS,
|
||||
fields=[
|
||||
spec.NumberInput(
|
||||
id="SUP_DEMadm_cap",
|
||||
|
|
|
@ -69,10 +69,10 @@ class UsageLoggingTests(unittest.TestCase):
|
|||
model_id='', model_title='', userguide=None, aliases=None,
|
||||
inputs=[
|
||||
spec.SingleBandRasterInput(id='raster', band=spec.Input()),
|
||||
spec.VectorInput(id='vector', geometries={}, fields={}),
|
||||
spec.VectorInput(id='vector', geometry_types={}, fields={}),
|
||||
spec.StringInput(id='not_a_gis_input'),
|
||||
spec.SingleBandRasterInput(id='blank_raster_path', band=spec.Input()),
|
||||
spec.VectorInput(id='blank_vector_path', geometries={}, fields={})
|
||||
spec.VectorInput(id='blank_vector_path', geometry_types={}, fields={})
|
||||
],
|
||||
outputs={},
|
||||
input_field_order=[],
|
||||
|
|
|
@ -615,7 +615,7 @@ class VectorValidation(unittest.TestCase):
|
|||
|
||||
filepath = os.path.join(self.workspace_dir, 'file.txt')
|
||||
error_msg = VectorInput(
|
||||
geometries={'POINT'}, fields={}).validate(filepath)
|
||||
geometry_types={'POINT'}, fields={}).validate(filepath)
|
||||
self.assertEqual(error_msg, validation.MESSAGES['FILE_NOT_FOUND'])
|
||||
|
||||
def test_invalid_vector(self):
|
||||
|
@ -627,7 +627,7 @@ class VectorValidation(unittest.TestCase):
|
|||
bad_vector.write('not a vector')
|
||||
|
||||
error_msg = VectorInput(
|
||||
geometries={'POINT'}, fields={}).validate(filepath)
|
||||
geometry_types={'POINT'}, fields={}).validate(filepath)
|
||||
self.assertEqual(error_msg, validation.MESSAGES['NOT_GDAL_VECTOR'])
|
||||
|
||||
def test_missing_fieldnames(self):
|
||||
|
@ -655,7 +655,7 @@ class VectorValidation(unittest.TestCase):
|
|||
vector = None
|
||||
|
||||
error_msg = VectorInput(
|
||||
geometries={'POINT'},
|
||||
geometry_types={'POINT'},
|
||||
fields=[
|
||||
Input(id='col_a'),
|
||||
Input(id='col_b'),
|
||||
|
@ -681,14 +681,14 @@ class VectorValidation(unittest.TestCase):
|
|||
vector = None
|
||||
|
||||
error_msg = VectorInput(
|
||||
fields={}, geometries={'POINT'}, projected=True, projection_units=spec.u.foot
|
||||
fields={}, geometry_types={'POINT'}, projected=True, projection_units=spec.u.foot
|
||||
).validate(filepath)
|
||||
expected_msg = validation.MESSAGES['WRONG_PROJECTION_UNIT'].format(
|
||||
unit_a='foot', unit_b='metre')
|
||||
self.assertEqual(error_msg, expected_msg)
|
||||
|
||||
self.assertIsNone(VectorInput(
|
||||
fields={}, geometries={'POINT'}, projected=True, projection_units=spec.u.meter
|
||||
fields={}, geometry_types={'POINT'}, projected=True, projection_units=spec.u.meter
|
||||
).validate(filepath))
|
||||
|
||||
def test_wrong_geom_type(self):
|
||||
|
@ -703,9 +703,9 @@ class VectorValidation(unittest.TestCase):
|
|||
layer = None
|
||||
vector = None
|
||||
self.assertIsNone(VectorInput(
|
||||
geometries={'POLYGON', 'POINT'}, fields=None).validate(filepath))
|
||||
geometry_types={'POLYGON', 'POINT'}, fields=None).validate(filepath))
|
||||
self.assertEqual(
|
||||
VectorInput(fields=None, geometries={'MULTIPOINT'}).validate(filepath),
|
||||
VectorInput(fields=None, geometry_types={'MULTIPOINT'}).validate(filepath),
|
||||
validation.MESSAGES['WRONG_GEOM_TYPE'].format(allowed={'MULTIPOINT'}))
|
||||
|
||||
|
||||
|
@ -1551,7 +1551,7 @@ class TestGetValidatedDataframe(unittest.TestCase):
|
|||
IntegerInput(id='a'),
|
||||
IntegerInput(id='b')
|
||||
],
|
||||
geometries=['POINT']
|
||||
geometry_types=['POINT']
|
||||
)
|
||||
])
|
||||
|
||||
|
@ -1586,7 +1586,7 @@ class TestGetValidatedDataframe(unittest.TestCase):
|
|||
id='col2',
|
||||
band=NumberInput(),
|
||||
fields={},
|
||||
geometries=['POLYGON']
|
||||
geometry_types=['POLYGON']
|
||||
)
|
||||
])
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
|
@ -1777,7 +1777,7 @@ class TestValidationFromSpec(unittest.TestCase):
|
|||
),
|
||||
VectorInput(
|
||||
id="vector",
|
||||
geometries=spec.POINTS,
|
||||
geometry_types=spec.POINTS,
|
||||
fields=[
|
||||
RatioInput(id="field_a"),
|
||||
RatioInput(id="field_b", required="some_number == 2")
|
||||
|
@ -2050,7 +2050,7 @@ class TestValidationFromSpec(unittest.TestCase):
|
|||
VectorInput(
|
||||
id='vector_a',
|
||||
fields={},
|
||||
geometries={'POINT'}
|
||||
geometry_types={'POINT'}
|
||||
)
|
||||
],
|
||||
args_with_spatial_overlap={
|
||||
|
@ -2166,7 +2166,7 @@ class TestValidationFromSpec(unittest.TestCase):
|
|||
id='vector_a',
|
||||
required=False,
|
||||
fields=[],
|
||||
geometries={'POINT'}
|
||||
geometry_types={'POINT'}
|
||||
)
|
||||
],
|
||||
args_with_spatial_overlap={
|
||||
|
|
Loading…
Reference in New Issue