threedi-modelchecker 2.7.1.dev0__tar.gz → 2.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/CHANGES.rst +9 -1
- {threedi-modelchecker-2.7.1.dev0/threedi_modelchecker.egg-info → threedi_modelchecker-2.7.2}/PKG-INFO +2 -2
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/pyproject.toml +1 -1
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/__init__.py +1 -1
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/checks/geo_query.py +1 -1
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/checks/other.py +34 -65
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/checks/raster.py +11 -15
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/config.py +486 -275
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/model_checks.py +0 -1
- threedi_modelchecker-2.7.2/threedi_modelchecker/tests/data/empty.gpkg +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/factories.py +34 -31
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/test_checks_base.py +124 -43
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/test_checks_factories.py +1 -1
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/test_checks_other.py +14 -76
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/test_checks_raster.py +54 -56
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2/threedi_modelchecker.egg-info}/PKG-INFO +2 -2
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker.egg-info/requires.txt +1 -1
- threedi-modelchecker-2.7.1.dev0/threedi_modelchecker/tests/data/empty.gpkg +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/LICENSE +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/MANIFEST.in +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/README.rst +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/setup.cfg +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/checks/__init__.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/checks/base.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/checks/cross_section_definitions.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/checks/factories.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/checks/timeseries.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/exporters.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/interfaces/__init__.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/interfaces/raster_interface.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/interfaces/raster_interface_gdal.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/interfaces/raster_interface_rasterio.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/scripts.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/__init__.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/conftest.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/data/__init__.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/test_checks_cross_section_definitions.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/test_checks_timeseries.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/test_exporters.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/tests/test_model_checks.py +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker.egg-info/SOURCES.txt +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker.egg-info/dependency_links.txt +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker.egg-info/entry_points.txt +0 -0
- {threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker.egg-info/top_level.txt +0 -0
|
@@ -2,8 +2,15 @@ Changelog of threedi-modelchecker
|
|
|
2
2
|
=================================
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
2.7.
|
|
5
|
+
2.7.2 (2024-04-23)
|
|
6
6
|
------------------
|
|
7
|
+
|
|
8
|
+
- Fix bug with check 183
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
2.7.1 (2024-04-22)
|
|
12
|
+
------------------
|
|
13
|
+
|
|
7
14
|
- Add info check 1406 to inform the user if a raster is not compressed.
|
|
8
15
|
- Add check 799 to warn if raster friction pixels are < 1 while Chezy friction is selected
|
|
9
16
|
- Change error message for check 1500
|
|
@@ -11,6 +18,7 @@ Changelog of threedi-modelchecker
|
|
|
11
18
|
|
|
12
19
|
2.7.0 (2024-03-12)
|
|
13
20
|
------------------
|
|
21
|
+
|
|
14
22
|
- Support geopackage
|
|
15
23
|
- Support changes in threedi-schema (0.220) needed for geopackage support
|
|
16
24
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: threedi-modelchecker
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.2
|
|
4
4
|
Summary: Checks validity of a 3Di schematisation
|
|
5
5
|
Author-email: Nelen & Schuurmans <info@nelen-schuurmans.nl>
|
|
6
6
|
License: MIT
|
|
@@ -15,7 +15,7 @@ License-File: LICENSE
|
|
|
15
15
|
Requires-Dist: Click
|
|
16
16
|
Requires-Dist: GeoAlchemy2!=0.11.*,>=0.9
|
|
17
17
|
Requires-Dist: SQLAlchemy>=1.4
|
|
18
|
-
Requires-Dist: threedi-schema==0.
|
|
18
|
+
Requires-Dist: threedi-schema==0.220.*
|
|
19
19
|
Provides-Extra: rasterio
|
|
20
20
|
Requires-Dist: rasterio>=1.3; extra == "rasterio"
|
|
21
21
|
Provides-Extra: test
|
|
@@ -8,7 +8,7 @@ DEFAULT_EPSG = 28992
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def epsg_code_query():
|
|
11
|
-
epsg_code = Query(models.
|
|
11
|
+
epsg_code = Query(models.GlobalSetting.epsg_code).limit(1).scalar_subquery()
|
|
12
12
|
return func.coalesce(epsg_code, literal(DEFAULT_EPSG)).label("epsg_code")
|
|
13
13
|
|
|
14
14
|
|
{threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/checks/other.py
RENAMED
|
@@ -10,6 +10,15 @@ from .base import BaseCheck, CheckLevel
|
|
|
10
10
|
from .cross_section_definitions import cross_section_configuration
|
|
11
11
|
from .geo_query import distance, length, transform
|
|
12
12
|
|
|
13
|
+
# Use these to make checks only work on the first global settings entry:
|
|
14
|
+
first_setting = (
|
|
15
|
+
Query(models.GlobalSetting.id)
|
|
16
|
+
.order_by(models.GlobalSetting.id)
|
|
17
|
+
.limit(1)
|
|
18
|
+
.scalar_subquery()
|
|
19
|
+
)
|
|
20
|
+
first_setting_filter = models.GlobalSetting.id == first_setting
|
|
21
|
+
|
|
13
22
|
|
|
14
23
|
class CorrectAggregationSettingsExist(BaseCheck):
|
|
15
24
|
"""Check if aggregation settings are correctly filled with aggregation_method and flow_variable as required"""
|
|
@@ -21,24 +30,30 @@ class CorrectAggregationSettingsExist(BaseCheck):
|
|
|
21
30
|
*args,
|
|
22
31
|
**kwargs,
|
|
23
32
|
):
|
|
24
|
-
super().__init__(column=models.
|
|
33
|
+
super().__init__(column=models.GlobalSetting.id, *args, **kwargs)
|
|
25
34
|
self.aggregation_method = aggregation_method.value
|
|
26
35
|
self.flow_variable = flow_variable.value
|
|
27
36
|
|
|
28
37
|
def get_invalid(self, session: Session) -> List[NamedTuple]:
|
|
29
|
-
global_settings = self.to_check(session)
|
|
38
|
+
global_settings = self.to_check(session).filter(first_setting_filter)
|
|
30
39
|
correctly_defined = session.execute(
|
|
31
|
-
select(models.AggregationSettings)
|
|
40
|
+
select(models.AggregationSettings)
|
|
41
|
+
.filter(
|
|
32
42
|
models.AggregationSettings.aggregation_method
|
|
33
43
|
== self.aggregation_method,
|
|
34
44
|
models.AggregationSettings.flow_variable == self.flow_variable,
|
|
35
45
|
)
|
|
46
|
+
.filter(
|
|
47
|
+
models.AggregationSettings.global_settings_id
|
|
48
|
+
== global_settings.subquery().c.id
|
|
49
|
+
)
|
|
36
50
|
).all()
|
|
51
|
+
|
|
37
52
|
return global_settings.all() if len(correctly_defined) == 0 else []
|
|
38
53
|
|
|
39
54
|
def description(self) -> str:
|
|
40
55
|
return (
|
|
41
|
-
"To use the water balance tool,
|
|
56
|
+
"To use the water balance tool, v2_aggregation_settings should have a row where "
|
|
42
57
|
f"aggregation_method is {self.aggregation_method} and flow_variable is {self.flow_variable}."
|
|
43
58
|
)
|
|
44
59
|
|
|
@@ -229,14 +244,12 @@ class Use0DFlowCheck(BaseCheck):
|
|
|
229
244
|
"""
|
|
230
245
|
|
|
231
246
|
def __init__(self, *args, **kwargs):
|
|
232
|
-
super().__init__(
|
|
233
|
-
column=models.SimulationTemplateSettings.use_0d_inflow, *args, **kwargs
|
|
234
|
-
)
|
|
247
|
+
super().__init__(column=models.GlobalSetting.use_0d_inflow, *args, **kwargs)
|
|
235
248
|
|
|
236
249
|
def to_check(self, session):
|
|
237
250
|
"""Return a Query object on which this check is applied"""
|
|
238
|
-
return session.query(models.
|
|
239
|
-
models.
|
|
251
|
+
return session.query(models.GlobalSetting).filter(
|
|
252
|
+
models.GlobalSetting.use_0d_inflow != 0
|
|
240
253
|
)
|
|
241
254
|
|
|
242
255
|
def get_invalid(self, session):
|
|
@@ -288,7 +301,7 @@ class ConnectionNodes(BaseCheck):
|
|
|
288
301
|
class ConnectionNodesLength(BaseCheck):
|
|
289
302
|
"""Check that the distance between `start_node` and `end_node` is at least
|
|
290
303
|
`min_distance`. The coords will be transformed into (the first entry) of
|
|
291
|
-
|
|
304
|
+
GlobalSettings.epsg_code.
|
|
292
305
|
"""
|
|
293
306
|
|
|
294
307
|
def __init__(
|
|
@@ -456,7 +469,7 @@ class ChannelManholeLevelCheck(BaseCheck):
|
|
|
456
469
|
|
|
457
470
|
class OpenChannelsWithNestedNewton(BaseCheck):
|
|
458
471
|
"""Checks whether the model has any closed cross-section in use when the
|
|
459
|
-
NumericalSettings.
|
|
472
|
+
NumericalSettings.use_of_nested_newton is turned off.
|
|
460
473
|
|
|
461
474
|
See https://github.com/nens/threeditoolbox/issues/522
|
|
462
475
|
"""
|
|
@@ -466,7 +479,7 @@ class OpenChannelsWithNestedNewton(BaseCheck):
|
|
|
466
479
|
column=models.CrossSectionDefinition.id,
|
|
467
480
|
level=level,
|
|
468
481
|
filters=Query(models.NumericalSettings)
|
|
469
|
-
.filter(models.NumericalSettings.
|
|
482
|
+
.filter(models.NumericalSettings.use_of_nested_newton == 0)
|
|
470
483
|
.exists(),
|
|
471
484
|
*args,
|
|
472
485
|
**kwargs,
|
|
@@ -519,8 +532,8 @@ class OpenChannelsWithNestedNewton(BaseCheck):
|
|
|
519
532
|
def description(self) -> str:
|
|
520
533
|
return (
|
|
521
534
|
f"{self.column_name} has a closed cross section definition while "
|
|
522
|
-
f"NumericalSettings.
|
|
523
|
-
f"This gives convergence issues. We recommend setting
|
|
535
|
+
f"NumericalSettings.use_of_nested_newton is switched off. "
|
|
536
|
+
f"This gives convergence issues. We recommend setting use_of_nested_newton = 1."
|
|
524
537
|
)
|
|
525
538
|
|
|
526
539
|
|
|
@@ -718,8 +731,7 @@ class PumpStorageTimestepCheck(BaseCheck):
|
|
|
718
731
|
.filter(
|
|
719
732
|
(models.ConnectionNode.storage_area != None)
|
|
720
733
|
& (
|
|
721
|
-
(
|
|
722
|
-
# calculate how many seconds the pumpstation takes to empty its storage: (storage * height)/pump capacity
|
|
734
|
+
( # calculate how many seconds the pumpstation takes to empty its storage: (storage * height)/pump capacity
|
|
723
735
|
(
|
|
724
736
|
# Arithmetic operations on None return None, so without this
|
|
725
737
|
# conditional type cast, no invalid results would be returned
|
|
@@ -732,7 +744,9 @@ class PumpStorageTimestepCheck(BaseCheck):
|
|
|
732
744
|
)
|
|
733
745
|
)
|
|
734
746
|
/ (models.Pumpstation.capacity / 1000)
|
|
735
|
-
< Query(models.
|
|
747
|
+
< Query(models.GlobalSetting.sim_time_step)
|
|
748
|
+
.filter(first_setting_filter)
|
|
749
|
+
.scalar_subquery()
|
|
736
750
|
)
|
|
737
751
|
)
|
|
738
752
|
.all()
|
|
@@ -805,7 +819,7 @@ class InflowNoFeaturesCheck(BaseCheck):
|
|
|
805
819
|
"""Check that the surface table in the global use_0d_inflow setting contains at least 1 feature."""
|
|
806
820
|
|
|
807
821
|
def __init__(self, *args, surface_table, condition=True, **kwargs):
|
|
808
|
-
super().__init__(*args, column=models.
|
|
822
|
+
super().__init__(*args, column=models.GlobalSetting.id, **kwargs)
|
|
809
823
|
self.surface_table = surface_table
|
|
810
824
|
self.condition = condition
|
|
811
825
|
|
|
@@ -814,13 +828,13 @@ class InflowNoFeaturesCheck(BaseCheck):
|
|
|
814
828
|
select(func.count(self.surface_table.id))
|
|
815
829
|
).scalar()
|
|
816
830
|
return (
|
|
817
|
-
session.query(models.
|
|
831
|
+
session.query(models.GlobalSetting)
|
|
818
832
|
.filter(self.condition, surface_table_length == 0)
|
|
819
833
|
.all()
|
|
820
834
|
)
|
|
821
835
|
|
|
822
836
|
def description(self) -> str:
|
|
823
|
-
return f"
|
|
837
|
+
return f"v2_global_settings.use_0d_inflow is set to use {self.surface_table.__tablename__}, but {self.surface_table.__tablename__} does not contain any features."
|
|
824
838
|
|
|
825
839
|
|
|
826
840
|
class NodeSurfaceConnectionsCheck(BaseCheck):
|
|
@@ -1068,48 +1082,3 @@ class AllPresentVariableVegetationParameters(AllPresent):
|
|
|
1068
1082
|
)
|
|
1069
1083
|
)
|
|
1070
1084
|
)
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
class UsedSettingsPresentCheck(BaseCheck):
|
|
1074
|
-
def __init__(
|
|
1075
|
-
self,
|
|
1076
|
-
column,
|
|
1077
|
-
settings_table,
|
|
1078
|
-
filters=None,
|
|
1079
|
-
level=CheckLevel.ERROR,
|
|
1080
|
-
error_code=0,
|
|
1081
|
-
):
|
|
1082
|
-
super().__init__(column, filters, level, error_code)
|
|
1083
|
-
self.settings_table = settings_table
|
|
1084
|
-
|
|
1085
|
-
def get_invalid(self, session: Session) -> List[NamedTuple]:
|
|
1086
|
-
# more than 1 row should be caught by another check
|
|
1087
|
-
all_results = self.to_check(session).filter(self.column == True).all()
|
|
1088
|
-
use_cols = len(all_results) > 0
|
|
1089
|
-
if use_cols and session.query(self.settings_table).count() == 0:
|
|
1090
|
-
return all_results
|
|
1091
|
-
return []
|
|
1092
|
-
|
|
1093
|
-
def description(self) -> str:
|
|
1094
|
-
return f"{self.column_name} in {self.table.name} is set to True but {self.settings_table.__tablename__} is empty"
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
class MaxOneRecordCheck(BaseCheck):
|
|
1098
|
-
def __init__(self, column, filters=None, level=CheckLevel.ERROR, error_code=0):
|
|
1099
|
-
super().__init__(column, filters, level, error_code)
|
|
1100
|
-
self.observed_length = 0
|
|
1101
|
-
|
|
1102
|
-
def get_invalid(self, session: Session) -> List[NamedTuple]:
|
|
1103
|
-
# return mock list in case the table is empty when it shouldn't be
|
|
1104
|
-
all_results = self.to_check(session).all()
|
|
1105
|
-
self.observed_length = len(all_results)
|
|
1106
|
-
if self.observed_length > 1:
|
|
1107
|
-
return all_results if self.observed_length > 0 else ["foo"]
|
|
1108
|
-
else:
|
|
1109
|
-
return []
|
|
1110
|
-
|
|
1111
|
-
def description(self) -> str:
|
|
1112
|
-
return (
|
|
1113
|
-
f"{self.table.name} has {self.observed_length} rows, "
|
|
1114
|
-
f"but should have at most 1 row."
|
|
1115
|
-
)
|
{threedi-modelchecker-2.7.1.dev0 → threedi_modelchecker-2.7.2}/threedi_modelchecker/checks/raster.py
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from math import isclose
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import Optional, Set, Type
|
|
5
5
|
|
|
6
6
|
from threedi_schema import models
|
|
7
7
|
|
|
@@ -22,7 +22,7 @@ class Context:
|
|
|
22
22
|
|
|
23
23
|
@dataclass
|
|
24
24
|
class ServerContext(Context):
|
|
25
|
-
available_rasters:
|
|
25
|
+
available_rasters: Set[str]
|
|
26
26
|
raster_interface: Type[RasterInterface] = GDALRasterInterface
|
|
27
27
|
|
|
28
28
|
|
|
@@ -68,9 +68,7 @@ class BaseRasterCheck(BaseCheck):
|
|
|
68
68
|
]
|
|
69
69
|
|
|
70
70
|
def get_path_local(self, record, context: LocalContext) -> Optional[str]:
|
|
71
|
-
abs_path = context.base_path.
|
|
72
|
-
"rasters", getattr(record, self.column.name)
|
|
73
|
-
)
|
|
71
|
+
abs_path = context.base_path / getattr(record, self.column.name)
|
|
74
72
|
if abs_path.exists():
|
|
75
73
|
return str(abs_path)
|
|
76
74
|
|
|
@@ -161,7 +159,7 @@ class RasterHasMatchingEPSGCheck(BaseRasterCheck):
|
|
|
161
159
|
"""Check whether a raster's EPSG code matches the EPSG code in the global settings for the SQLite."""
|
|
162
160
|
|
|
163
161
|
def get_invalid(self, session):
|
|
164
|
-
epsg_code_query = session.query(models.
|
|
162
|
+
epsg_code_query = session.query(models.GlobalSetting.epsg_code).first()
|
|
165
163
|
if epsg_code_query is not None:
|
|
166
164
|
self.epsg_code = epsg_code_query[0]
|
|
167
165
|
else:
|
|
@@ -177,7 +175,7 @@ class RasterHasMatchingEPSGCheck(BaseRasterCheck):
|
|
|
177
175
|
return raster.epsg_code == self.epsg_code
|
|
178
176
|
|
|
179
177
|
def description(self):
|
|
180
|
-
return f"The file in {self.column_name} has no EPSG code or the EPSG code does not match does not match
|
|
178
|
+
return f"The file in {self.column_name} has no EPSG code or the EPSG code does not match does not match v2_global_settings.epsg_code"
|
|
181
179
|
|
|
182
180
|
|
|
183
181
|
class RasterSquareCellsCheck(BaseRasterCheck):
|
|
@@ -204,11 +202,9 @@ class RasterGridSizeCheck(BaseRasterCheck):
|
|
|
204
202
|
"""Check whether the global settings' grid size is an even multiple of a raster's cell size (at least 2x)."""
|
|
205
203
|
|
|
206
204
|
def get_invalid(self, session):
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if minimum_cell_size_query is not None:
|
|
211
|
-
self.minimum_cell_size = minimum_cell_size_query[0]
|
|
205
|
+
grid_space_query = session.query(models.GlobalSetting.grid_space).first()
|
|
206
|
+
if grid_space_query is not None:
|
|
207
|
+
self.grid_space = grid_space_query[0]
|
|
212
208
|
else:
|
|
213
209
|
return []
|
|
214
210
|
return super().get_invalid(session)
|
|
@@ -221,17 +217,17 @@ class RasterGridSizeCheck(BaseRasterCheck):
|
|
|
221
217
|
try:
|
|
222
218
|
return (
|
|
223
219
|
isclose(
|
|
224
|
-
a=((self.
|
|
220
|
+
a=((self.grid_space / raster.pixel_size[0]) % 2),
|
|
225
221
|
b=0,
|
|
226
222
|
rel_tol=1e-09,
|
|
227
223
|
)
|
|
228
|
-
) and (self.
|
|
224
|
+
) and (self.grid_space >= (2 * raster.pixel_size[0]))
|
|
229
225
|
# if one of the fields is a NoneType it will be caught elsewhere
|
|
230
226
|
except TypeError:
|
|
231
227
|
return True
|
|
232
228
|
|
|
233
229
|
def description(self):
|
|
234
|
-
return "
|
|
230
|
+
return "v2_global_settings.grid_space is not a positive even multiple of the raster cell size."
|
|
235
231
|
|
|
236
232
|
|
|
237
233
|
class RasterPixelCountCheck(BaseRasterCheck):
|