Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt ConnectionNodeCheck to match projected crs in meters #430

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Changelog of threedi-modelchecker
- Remove checks for model_settings.epsg_code (317 and 318)
- Remove usage of epsg 4326 in the tests because this CRS is no longer valid
- Remove no longer needed transformations
- Change ConnectionNodeCheck (201) to require minimum distance of 10cm


2.15.0 (2025-01-08)
Expand Down
32 changes: 14 additions & 18 deletions threedi_modelchecker/checks/other.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,30 +320,26 @@ def get_invalid(self, session: Session) -> List[NamedTuple]:
distance between all connection nodes.
"""
query = text(
f"""SELECT *
FROM connection_node AS cn1, connection_node AS cn2
WHERE
distance(cn1.geom, cn2.geom) < :min_distance
AND cn1.ROWID != cn2.ROWID
AND cn2.ROWID IN (
SELECT ROWID
FROM SpatialIndex
WHERE (
f_table_name = "connection_node"
AND search_frame = Buffer(cn1.geom, {self.minimum_distance / 2})));
f"""
SELECT *
FROM connection_node AS cn1, connection_node AS cn2
WHERE ST_Distance(cn1.geom, cn2.geom) < {self.minimum_distance}
AND cn1.ROWID != cn2.ROWID
AND cn2.ROWID IN (
SELECT ROWID
FROM SpatialIndex
WHERE (
f_table_name = "connection_node"
AND search_frame = Buffer(cn1.geom, {self.minimum_distance / 2})))
"""
)
results = (
session.connection()
.execute(query, {"min_distance": self.minimum_distance})
.fetchall()
)

results = session.connection().execute(query).fetchall()
return results

def description(self) -> str:

return (
f"The connection_node is within {self.minimum_distance} degrees of "
f"The connection_node is within {self.minimum_distance * 100 } cm of "
f"another connection_node."
)

Expand Down
2 changes: 1 addition & 1 deletion threedi_modelchecker/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,7 @@ def is_none_or_empty(col):

## 020x: Spatial checks

CHECKS += [ConnectionNodesDistance(error_code=201, minimum_distance=0.001)]
CHECKS += [ConnectionNodesDistance(error_code=201, minimum_distance=0.1)]
CHECKS += [
QueryCheck(
error_code=202,
Expand Down
38 changes: 12 additions & 26 deletions threedi_modelchecker/tests/test_checks_other.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from unittest import mock

import pytest
from sqlalchemy import func, select, text
from sqlalchemy.orm import aliased, Query
from sqlalchemy import select, text
from threedi_schema import constants, models, ThreediDatabase
from threedi_schema.beta_features import BETA_COLUMNS, BETA_VALUES

Expand Down Expand Up @@ -224,31 +223,18 @@ def test_channel_manhole_level_check(
assert len(errors) == errors_number


def test_node_distance(session):
con1_too_close = factories.ConnectionNodeFactory(
geom=f"SRID={SRID};POINT(142740 473443)",
)
con2_too_close = factories.ConnectionNodeFactory(
geom=f"SRID={SRID};POINT(142743 473443)",
)
# Good distance
factories.ConnectionNodeFactory(
geom=f"SRID={SRID};POINT(142755 473443)",
)
# sanity check to see the distances between the nodes
node_a = aliased(models.ConnectionNode)
node_b = aliased(models.ConnectionNode)
distances_query = Query(func.ST_Distance(node_a.geom, node_b.geom)).filter(
node_a.id != node_b.id
)
# Shows the distances between all 3 nodes: node 1 and 2 are too close
distances_query.with_session(session).all()
check = ConnectionNodesDistance(minimum_distance=10)
@pytest.mark.parametrize("other_x, valid", [(142740.05, False), (142740.15, True)])
def test_node_distance_alt(session, other_x, valid):
factories.ConnectionNodeFactory(id=0, geom=f"SRID={SRID};POINT(142740 473443)")
factories.ConnectionNodeFactory(id=1, geom=f"SRID={SRID};POINT({other_x} 473443)")
# Note that the test uses plain sqlite, so this needs to be committed
session.commit()
check = ConnectionNodesDistance(minimum_distance=0.1)
invalid = check.get_invalid(session)
assert len(invalid) == 2
invalid_ids = [i.id for i in invalid]
assert con1_too_close.id in invalid_ids
assert con2_too_close.id in invalid_ids
assert (len(invalid) == 0) == valid
# Remove connection nodes
session.query(models.ConnectionNode).delete()
session.commit()


class TestCrossSectionSameConfiguration:
Expand Down
Loading