Skip to content

Commit

Permalink
Remove geo_query and use explicit queries instead now transformations…
Browse files Browse the repository at this point in the history
… are no longer needed
  • Loading branch information
margrietpalm committed Dec 23, 2024
1 parent 5857b60 commit d2d3b5b
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 69 deletions.
24 changes: 0 additions & 24 deletions threedi_modelchecker/checks/geo_query.py

This file was deleted.

12 changes: 6 additions & 6 deletions threedi_modelchecker/checks/location.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from typing import List, NamedTuple

from geoalchemy2.functions import ST_Distance
from sqlalchemy import func
from sqlalchemy.orm import aliased, Session
from threedi_schema.domain import models

from threedi_modelchecker.checks.base import BaseCheck
from threedi_modelchecker.checks.geo_query import distance


class PointLocationCheck(BaseCheck):
Expand All @@ -32,7 +32,7 @@ def get_invalid(self, session):
self.ref_table,
self.ref_table.id == self.ref_column,
)
.filter(distance(self.column, self.ref_table.geom) > self.max_distance)
.filter(ST_Distance(self.column, self.ref_table.geom) > self.max_distance)
.all()
)

Expand Down Expand Up @@ -75,10 +75,10 @@ def get_invalid(self, session: Session) -> List[NamedTuple]:
start_point = func.ST_PointN(self.column, 1)
end_point = func.ST_PointN(self.column, func.ST_NPoints(self.column))

start_ok = distance(start_point, start_node.geom) <= tol
end_ok = distance(end_point, end_node.geom) <= tol
start_ok_if_reversed = distance(end_point, start_node.geom) <= tol
end_ok_if_reversed = distance(start_point, end_node.geom) <= tol
start_ok = ST_Distance(start_point, start_node.geom) <= tol
end_ok = ST_Distance(end_point, end_node.geom) <= tol
start_ok_if_reversed = ST_Distance(end_point, start_node.geom) <= tol
end_ok_if_reversed = ST_Distance(start_point, end_node.geom) <= tol
return (
self.to_check(session)
.join(start_node, start_node.id == self.ref_column_start)
Expand Down
18 changes: 8 additions & 10 deletions threedi_modelchecker/checks/other.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from dataclasses import dataclass
from typing import List, Literal, NamedTuple

from geoalchemy2.functions import ST_Distance, ST_Length
from sqlalchemy import (
and_,
case,
Expand All @@ -19,7 +20,6 @@

from .base import BaseCheck, CheckLevel
from .cross_section_definitions import cross_section_configuration_for_record
from .geo_query import distance, length, transform


class CorrectAggregationSettingsExist(BaseCheck):
Expand Down Expand Up @@ -290,7 +290,7 @@ def get_invalid(self, session):
self.to_check(session)
.join(start_node, start_node.id == self.start_node)
.join(end_node, end_node.id == self.end_node)
.filter(distance(start_node.geom, end_node.geom) < self.min_distance)
.filter(ST_Distance(start_node.geom, end_node.geom) < self.min_distance)
)
return list(q.with_session(session).all())

Expand Down Expand Up @@ -548,10 +548,10 @@ def get_invalid(self, session: Session) -> List[NamedTuple]:
linestring = models.Channel.geom
tol = self.min_distance
breach_point = func.Line_Locate_Point(
transform(linestring), transform(func.ST_PointN(self.column, 1))
linestring, func.ST_PointN(self.column, 1)
)
dist_1 = breach_point * length(linestring)
dist_2 = (1 - breach_point) * length(linestring)
dist_1 = breach_point * ST_Length(linestring)
dist_2 = (1 - breach_point) * ST_Length(linestring)
return (
self.to_check(session)
.join(models.Channel, self.table.c.channel_id == models.Channel.id)
Expand All @@ -577,10 +577,8 @@ def get_invalid(self, session: Session) -> List[NamedTuple]:

# First fetch the position of each potential breach per channel
def get_position(point, linestring):
breach_point = func.Line_Locate_Point(
transform(linestring), transform(func.ST_PointN(point, 1))
)
return (breach_point * length(linestring)).label("position")
breach_point = func.Line_Locate_Point(linestring, func.ST_PointN(point, 1))
return (breach_point * ST_Length(linestring)).label("position")

potential_breaches = sorted(
session.query(self.table, get_position(self.column, models.Channel.geom))
Expand Down Expand Up @@ -776,7 +774,7 @@ def get_invalid(self, session: Session) -> List[NamedTuple]:
self.table.c.id,
self.table.c.area,
self.table.c.geom,
func.ST_Area(transform(self.table.c.geom)).label("calculated_area"),
func.ST_Area(self.table.c.geom).label("calculated_area"),
).subquery()
return (
session.query(all_results)
Expand Down
12 changes: 6 additions & 6 deletions threedi_modelchecker/config.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from typing import List

from geoalchemy2 import functions as geo_func
from sqlalchemy import and_, func, or_, true
from sqlalchemy.orm import Query
from threedi_schema import constants, models
from threedi_schema.beta_features import BETA_COLUMNS, BETA_VALUES

from .checks import geo_query
from .checks.base import (
AllEqualCheck,
BaseCheck,
Expand Down Expand Up @@ -1068,7 +1068,7 @@ def is_none_or_empty(col):
error_code=202,
level=CheckLevel.WARNING,
column=table.id,
invalid=Query(table).filter(geo_query.length(table.geom) < 5),
invalid=Query(table).filter(geo_func.ST_Length(table.geom) < 5),
message=f"The length of {table.__tablename__} is very short (< 5 m). A length of at least 5.0 m is recommended to avoid timestep reduction.",
)
for table in [models.Channel, models.Culvert]
Expand Down Expand Up @@ -1369,8 +1369,8 @@ def is_none_or_empty(col):
invalid=Query(models.ExchangeLine)
.join(models.Channel, models.Channel.id == models.ExchangeLine.channel_id)
.filter(
geo_query.length(models.ExchangeLine.geom)
< (0.8 * geo_query.length(models.Channel.geom))
geo_func.ST_Length(models.ExchangeLine.geom)
< (0.8 * geo_func.ST_Length(models.Channel.geom))
),
message=(
"exchange_line.geom should not be significantly shorter than its "
Expand All @@ -1384,7 +1384,7 @@ def is_none_or_empty(col):
invalid=Query(models.ExchangeLine)
.join(models.Channel, models.Channel.id == models.ExchangeLine.channel_id)
.filter(
geo_query.distance(models.ExchangeLine.geom, models.Channel.geom) > 500.0
geo_func.ST_Distance(models.ExchangeLine.geom, models.Channel.geom) > 500.0
),
message=("exchange_line.geom is far (> 500 m) from its corresponding channel"),
),
Expand Down Expand Up @@ -1455,7 +1455,7 @@ def is_none_or_empty(col):
invalid=Query(models.PotentialBreach)
.join(models.Channel, models.Channel.id == models.PotentialBreach.channel_id)
.filter(
geo_query.distance(
geo_func.ST_Distance(
func.PointN(models.PotentialBreach.geom, 1), models.Channel.geom
)
> TOLERANCE_M
Expand Down
23 changes: 0 additions & 23 deletions threedi_modelchecker/tests/test_checks_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from sqlalchemy.orm import Query
from threedi_schema import constants, custom_types, models

from threedi_modelchecker.checks import geo_query
from threedi_modelchecker.checks.base import (
_sqlalchemy_to_sqlite_types,
AllEqualCheck,
Expand Down Expand Up @@ -529,28 +528,6 @@ def test_global_settings_use_1d_flow_and_no_1d_elements(session):
assert len(errors) == 0


def test_length_geom_linestring(session):
# TODO: reconsider this check because it tests geo_query.length,
# not query_check so this should not be here!
factories.ModelSettingsFactory()
x, y = [
float(coord)
for coord in factories.DEFAULT_LINE.split("(")[1].split(",")[0].split()
]
short_line = f"SRID=28992;LINESTRING({x} {y}, {x + 0.03} {y + 0.03})"
channel_too_short = factories.ChannelFactory(geom=short_line)
factories.ChannelFactory(geom=factories.DEFAULT_LINE)
q = Query(models.Channel).filter(geo_query.length(models.Channel.geom) < 0.05)
check_length_linestring = QueryCheck(
column=models.Channel.geom,
invalid=q,
message="Length of the channel is too short, should be at least 0.05m",
)
errors = check_length_linestring.get_invalid(session)
assert len(errors) == 1
assert errors[0].id == channel_too_short.id


@pytest.mark.parametrize(
"min_value,max_value,left_inclusive,right_inclusive",
[
Expand Down

0 comments on commit d2d3b5b

Please sign in to comment.