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

Feature/86 read and stack multiple surroundings layers #89

Merged
merged 22 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
030e13e
feature: expand surrounding logic with railway/water
ArdtK Oct 17, 2023
ba113ca
Merge branch 'test/81-definition-of-testcases' into feature/86-read-a…
ArdtK Oct 17, 2023
a27613e
fix: correct storing surrounding types
ArdtK Oct 18, 2023
81052ae
fix: rename building vars to surroundings
ArdtK Oct 18, 2023
4a154a4
fix: remove duplicate surroundings; add location overlay
ArdtK Oct 18, 2023
cbf030a
Merge branch 'master' into feature/86-read-and-stack-multiple-surroun…
ArdtK Oct 18, 2023
4c86eb2
fix: use config flags to determine which surroundings are applied
ArdtK Oct 19, 2023
93bf808
Merge branch 'master' into feature/86-read-and-stack-multiple-surroun…
ArdtK Oct 19, 2023
0a3e79d
fix: corrected error check
ArdtK Oct 19, 2023
151b171
test: get acceptance test to work
ArdtK Oct 19, 2023
4396cc6
test: fix unittest
ArdtK Oct 19, 2023
61f3f3b
test: get unittest to work
ArdtK Oct 20, 2023
f0b289a
Merge branch 'master' into feature/86-read-and-stack-multiple-surroun…
ArdtK Oct 20, 2023
6b37498
test: get unittest to work
ArdtK Oct 20, 2023
fb07983
fix: improve determining safe locations
ArdtK Oct 20, 2023
7fdc28b
fix: processed review comments
ArdtK Oct 20, 2023
bf1f3d7
test: fix unittest due to deepcopy change of objects
ArdtK Oct 20, 2023
9e7191e
test: revert deepcopy changes as location objects are referenced to
ArdtK Oct 20, 2023
1af5226
Merge branch 'master' into feature/86-read-and-stack-multiple-surroun…
ArdtK Oct 23, 2023
3e514a6
fix: redo deepcopy change
ArdtK Oct 23, 2023
dc254e2
fix: redo deepcopy change
ArdtK Oct 23, 2023
30cb1ae
Merge branch 'feature/86-read-and-stack-multiple-surroundings-layers'…
ArdtK Oct 23, 2023
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
4 changes: 2 additions & 2 deletions docs/reference/koswat_docstrings/dike/surroundings.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

::: koswat.dike.surroundings.koswat_surroundings_protocol

## Buildings polderside
::: koswat.dike.surroundings.buildings_polderside.koswat_buildings_polderside
## Surroundings polderside
::: koswat.dike.surroundings.surroundings_polderside.koswat_surroundings_polderside

## Point
::: koswat.dike.surroundings.point.point_surroundings
Expand Down
20 changes: 10 additions & 10 deletions koswat/configuration/io/csv/koswat_surroundings_csv_fom.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ def is_valid(self) -> bool:

class KoswatTrajectSurroundingsWrapperCsvFom(KoswatCsvFomProtocol):
traject: str
buldings_polderside: KoswatTrajectSurroundingsCsvFom
buildings_polderside: KoswatTrajectSurroundingsCsvFom
buildings_dikeside: KoswatTrajectSurroundingsCsvFom

platform_polderside: KoswatTrajectSurroundingsCsvFom
platform_dikeside: KoswatTrajectSurroundingsCsvFom
railways_polderside: KoswatTrajectSurroundingsCsvFom
railways_dikeside: KoswatTrajectSurroundingsCsvFom

water_polderside: KoswatTrajectSurroundingsCsvFom
water_dikeside: KoswatTrajectSurroundingsCsvFom
waters_polderside: KoswatTrajectSurroundingsCsvFom
waters_dikeside: KoswatTrajectSurroundingsCsvFom

roads_class_2_polderside: KoswatTrajectSurroundingsCsvFom
roads_class_7_polderside: KoswatTrajectSurroundingsCsvFom
Expand All @@ -43,12 +43,12 @@ class KoswatTrajectSurroundingsWrapperCsvFom(KoswatCsvFomProtocol):

def __init__(self) -> None:
self.traject = ""
self.buldings_polderside = None
self.buildings_polderside = None
self.buildings_dikeside = None
self.platform_polderside = None
self.platform_dikeside = None
self.water_polderside = None
self.water_dikeside = None
self.railways_polderside = None
self.railways_dikeside = None
self.waters_polderside = None
self.waters_dikeside = None
self.roads_class_2_polderside = None
self.roads_class_7_polderside = None
self.roads_class_24_polderside = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def _build_point_surroundings(
traject_order=entry[0],
section=entry[1],
location=(float(entry[2]), float(entry[3])),
distance_to_buildings=[
distance_to_surroundings=[
distances_list[e_idx]
for e_idx, e_val in enumerate(entry[4:])
if e_val == "1"
Expand Down
11 changes: 7 additions & 4 deletions koswat/configuration/io/koswat_run_settings_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
from typing import Any, List

from koswat.configuration.io.ini import KoswatGeneralIniFom
from koswat.configuration.io.ini.koswat_general_ini_fom import DikeProfileSectionFom
from koswat.configuration.io.ini.koswat_general_ini_fom import (
DikeProfileSectionFom,
SurroundingsSectionFom,
)
from koswat.configuration.io.ini.koswat_scenario_list_ini_dir_reader import (
KoswatSectionScenarioListIniDirReader,
)
Expand Down Expand Up @@ -64,7 +67,7 @@ def import_from(self, from_path: Path) -> KoswatRunSettings:
)

_surroundings_fom = self._import_surroundings(
_general_settings.surroundings_section.surroundings_database_dir,
_general_settings.surroundings_section,
_general_settings.analyse_section_fom.dike_section_location_shp_file,
[_s.scenario_dike_section for _s in _scenario_fom_list],
)
Expand Down Expand Up @@ -227,12 +230,12 @@ def _import_scenario_fom_list(
return _reader.read(scenario_dir)

def _import_surroundings(
self, surroundings_dir: Path, traject_shp_file: Path, dike_selections: List[str]
self, surroundings_section: SurroundingsSectionFom, traject_shp_file: Path, dike_selections: List[str]
ArdtK marked this conversation as resolved.
Show resolved Hide resolved
) -> Any:
_importer = KoswatSurroundingsImporter()
_importer.traject_loc_shp_file = traject_shp_file
_importer.selected_locations = dike_selections
return _importer.import_from(surroundings_dir)
return _importer.import_from(surroundings_section)

def _get_koswat_scenario(
self, fom_scenario: SectionScenarioFom, base_profile: KoswatProfileBase
Expand Down
17 changes: 10 additions & 7 deletions koswat/configuration/io/koswat_surroundings_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from koswat.configuration.io.csv.koswat_surroundings_csv_reader import (
KoswatSurroundingsCsvReader,
)
from koswat.configuration.io.ini.koswat_general_ini_fom import SurroundingsSectionFom
from koswat.configuration.io.shp.koswat_dike_locations_shp_fom import (
KoswatDikeLocationsShpFom,
)
Expand Down Expand Up @@ -37,7 +38,8 @@ def _get_dike_locations_shp_fom(self) -> List[KoswatDikeLocationsShpFom]:
_reader.selected_locations = self.selected_locations
return _reader.read(self.traject_loc_shp_file)

def import_from(self, from_path: Path) -> List[SurroundingsWrapper]:
def import_from(self, surroundings_section: SurroundingsSectionFom) -> List[SurroundingsWrapper]:
from_path = surroundings_section.surroundings_database_dir
if not isinstance(from_path, Path):
raise ValueError("No surroundings csv directory path given.")
if not isinstance(self.traject_loc_shp_file, Path):
Expand All @@ -63,6 +65,7 @@ def import_from(self, from_path: Path) -> List[SurroundingsWrapper]:
_builder = SurroundingsWrapperBuilder()
_builder.trajects_fom = _location
_builder.surroundings_fom = _surroudings_fom
_builder.surroundings_section = surroundings_section
try:
_surroundings_wrappers.append(_builder.build())
except Exception as e_info:
Expand All @@ -77,12 +80,12 @@ def import_from(self, from_path: Path) -> List[SurroundingsWrapper]:
def _map_surrounding_type(self, surrounding_type: str) -> str:
_normalized = surrounding_type.lower().strip()
_translations = dict(
bebouwing_binnendijks="buldings_polderside",
bebouwing_binnendijks="buildings_polderside",
bebouwing_buitendijks="buildings_dikeside",
spoor_binnendijks="platform_polderside",
spoor_buitendijks="platform_dikeside",
water_binnendijks="water_polderside",
water_buitendijks="water_dikeside",
spoor_binnendijks="railways_polderside",
spoor_buitendijks="railways_dikeside",
water_binnendijks="waters_polderside",
water_buitendijks="waters_dikeside",
wegen_binnendijks_klasse2="roads_class_2_polderside",
wegen_binnendijks_klasse7="roads_class_7_polderside",
wegen_binnendijks_klasse24="roads_class_24_polderside",
Expand All @@ -95,7 +98,7 @@ def _map_surrounding_type(self, surrounding_type: str) -> str:
wegen_buitendijks_klasseonbekend="roads_class_unknown_dikeside",
)
_translation = _translations.get(_normalized, None)
if not _translations:
if not _translation:
_error = "No mapping found for {}".format(surrounding_type)
logging.error(_error)
raise ValueError(_error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from koswat.cost_report.cost_report_protocol import CostReportProtocol
from koswat.cost_report.profile.profile_cost_report import ProfileCostReport
from koswat.dike.surroundings.buildings_polderside.koswat_buildings_polderside import (
from koswat.dike.surroundings.surroundings_polderside.koswat_surroundings_polderside import (
PointSurroundings,
)

Expand Down
12 changes: 6 additions & 6 deletions koswat/dike/surroundings/point/point_surroundings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ class PointSurroundings:
section: str
traject_order: int
location: Point
distance_to_buildings: List[float]
distance_to_surroundings: List[float]

def __init__(self) -> None:
self.section = ""
self.location = None
self.traject_order = -1
self.distance_to_buildings = []
self.distance_to_surroundings = []

@property
def closest_building(self) -> float:
def closest_surrounding(self) -> float:
"""
Distance to the closest building. When no buildings are given the value will be `NaN` (Not A Number), so that the value 0 is reserved for buildings at distance 0.
Distance to the closest surrounding (building/railway/water). When no surroundings are given the value will be `NaN` (Not A Number), so that the value 0 is reserved for buildings at distance 0.

Returns:
float: Distance to the closest building.
float: Distance to the closest surrounding.
"""
return min(self.distance_to_buildings, default=math.nan)
return min(self.distance_to_surroundings, default=math.nan)
4 changes: 2 additions & 2 deletions koswat/dike/surroundings/point/point_surroundings_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def build(self) -> PointSurroundings:
_point.section = self.point_surroundings_data.get("section", "")
_point.traject_order = self.point_surroundings_data.get("traject_order", -1)
_point.location = Point(self.point_surroundings_data["location"])
_point.distance_to_buildings = self.point_surroundings_data.get(
"distance_to_buildings", []
_point.distance_to_surroundings = self.point_surroundings_data.get(
"distance_to_surroundings", []
)
return _point
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,44 @@
from koswat.dike.surroundings.point.point_surroundings import PointSurroundings


class KoswatBuildingsPolderside(KoswatSurroundingsProtocol):
class KoswatSurroundingsPolderside(KoswatSurroundingsProtocol):
points: List[PointSurroundings]

def __init__(self) -> None:
self.points = []

@property
def conflicting_points(self) -> List[PointSurroundings]:
return [_cf for _cf in self.points if any(_cf.distance_to_buildings)]
return [_cf for _cf in self.points if any(_cf.distance_to_surroundings)]

def get_classify_surroundings(self) -> Dict[float, List[PointSurroundings]]:
"""
Gets all the `points` in a dictionary indexed by their closest distance to a building.
Gets all the `points` in a dictionary indexed by their closest distance to a surrounding.

Returns:
Dict[float, List[PointSurroundings]]: Keys represent distance to a building, values are the points matching that criteria.
Dict[float, List[PointSurroundings]]: Keys represent distance to a surrounding, values are the points matching that criteria.
"""
if not self.points:
return {}
_surroundings_dict = defaultdict(list)
for ps in self.points:
_surroundings_dict[ps.closest_building].append(ps.location)
_surroundings_dict[ps.closest_surrounding].append(ps.location)
return _surroundings_dict

def get_locations_after_distance(self, distance: float) -> List[Point]:
"""
Gets all points which do not contain any building between their position and a radius of `distance` meters.
Gets all points which do not contain any surrounding between their position and a radius of `distance` meters.

Args:
distance (float): Radius from a coordinate where to check for buildings.
distance (float): Radius from a coordinate where to check for surroundings.

Returns:
List[Point]: List of points which do not contain any building for the provided distance.
List[Point]: List of points which do not contain any surroundings for the provided distance.
"""

def is_at_safe_distance(point_surroundings: PointSurroundings) -> bool:
if not point_surroundings.distance_to_buildings:
if not point_surroundings.distance_to_surroundings:
return True
return distance < point_surroundings.distance_to_buildings[0]
return distance < point_surroundings.distance_to_surroundings[0]

return list(filter(is_at_safe_distance, self.points))
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
)
from koswat.configuration.io.shp import KoswatDikeLocationsShpFom
from koswat.core.protocols import BuilderProtocol
from koswat.dike.surroundings.buildings_polderside.koswat_buildings_polderside import (
KoswatBuildingsPolderside,
from koswat.dike.surroundings.surroundings_polderside.koswat_surroundings_polderside import (
KoswatSurroundingsPolderside,
PointSurroundings,
)


class KoswatBuildingsPoldersideBuilder(BuilderProtocol):
class KoswatSurroundingsPoldersideBuilder(BuilderProtocol):
koswat_shp_fom: KoswatDikeLocationsShpFom
koswat_csv_fom: KoswatTrajectSurroundingsCsvFom

Expand All @@ -40,14 +40,14 @@ def _get_polderside_points(
]
return self.koswat_csv_fom.points_surroundings_list[start_idx : (end_idx + 1)]

def build(self) -> KoswatBuildingsPolderside:
def build(self) -> KoswatSurroundingsPolderside:
if not self.koswat_shp_fom or not self.koswat_csv_fom:
raise ValueError("FileObjectModel for both CSV and SHP should be provided.")

start_idx = self._find_polderside_point_idx(self.koswat_shp_fom.initial_point)
end_idx = self._find_polderside_point_idx(self.koswat_shp_fom.end_point)

_kbp = KoswatBuildingsPolderside()
_kbp = KoswatSurroundingsPolderside()
_kbp.points = self._get_polderside_points(start_idx, end_idx)

return _kbp
Loading