Skip to content

Commit

Permalink
Merge branch 'feature/nodes' of github.com:IMMM-SFA/naturf into featu…
Browse files Browse the repository at this point in the history
…re/nodes
  • Loading branch information
erexer committed Aug 4, 2023
2 parents 42bbb58 + 867e673 commit ce1f021
Showing 1 changed file with 196 additions and 1 deletion.
197 changes: 196 additions & 1 deletion tests/test_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,11 @@ def test_buildings_intersecting_plan_area(self):
building_area = pd.Series([polygon1.area, polygon2.area])
crs = "epsg:3857"

wall_length_north = pd.Series([1.0, 1.0])
wall_length_east = pd.Series([1.0, 1.0])
wall_length_south = pd.Series([1.0, 1.0])
wall_length_west = pd.Series([1.0, 1.0])

total_plan_area_geometry_no_overlap = pd.Series([polygon1.buffer(1), polygon2.buffer(1)])
total_plan_area_geometry_some_overlap = pd.Series(
[polygon1.buffer(3.5), polygon2.buffer(3.5)]
Expand All @@ -356,10 +361,18 @@ def test_buildings_intersecting_plan_area(self):
"building_area_target": building_area,
"building_geometry": building_geometry,
"building_buffered_target": gpd.GeoSeries(total_plan_area_geometry_no_overlap),
"wall_length_north_target": wall_length_north,
"wall_length_east_target": wall_length_east,
"wall_length_south_target": wall_length_south,
"wall_length_west_target": wall_length_west,
"index_neighbor": building_id,
"building_height_neighbor": building_height,
"building_area_neighbor": building_area,
"building_buffered_neighbor": total_plan_area_geometry_no_overlap,
"wall_length_north_neighbor": wall_length_north,
"wall_length_east_neighbor": wall_length_east,
"wall_length_south_neighbor": wall_length_south,
"wall_length_west_neighbor": wall_length_west,
"building_geometry_neighbor": gpd.GeoSeries(building_geometry),
},
geometry="building_geometry",
Expand Down Expand Up @@ -387,6 +400,10 @@ def test_buildings_intersecting_plan_area(self):
total_plan_area_geometry_some_overlap[1],
]
),
"wall_length_north_target": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_east_target": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_south_target": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_west_target": pd.Series([1.0, 1.0, 1.0, 1.0]),
"index_neighbor": pd.Series([0, 0, 1, 1]),
"building_height_neighbor": pd.Series([5, 5, 10, 10]),
"building_area_neighbor": pd.Series([1.0, 1.0, 1.0, 1.0]),
Expand All @@ -398,6 +415,10 @@ def test_buildings_intersecting_plan_area(self):
total_plan_area_geometry_some_overlap[1],
]
),
"wall_length_north_neighbor": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_east_neighbor": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_south_neighbor": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_west_neighbor": pd.Series([1.0, 1.0, 1.0, 1.0]),
"building_geometry_neighbor": gpd.GeoSeries(
[
building_geometry[0],
Expand Down Expand Up @@ -432,6 +453,10 @@ def test_buildings_intersecting_plan_area(self):
total_plan_area_geometry_total_overlap[1],
]
),
"wall_length_north_target": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_east_target": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_south_target": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_west_target": pd.Series([1.0, 1.0, 1.0, 1.0]),
"index_neighbor": pd.Series([0, 0, 1, 1]),
"building_height_neighbor": pd.Series([5, 5, 10, 10]),
"building_area_neighbor": pd.Series([1.0, 1.0, 1.0, 1.0]),
Expand All @@ -443,6 +468,10 @@ def test_buildings_intersecting_plan_area(self):
total_plan_area_geometry_total_overlap[1],
]
),
"wall_length_north_neighbor": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_east_neighbor": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_south_neighbor": pd.Series([1.0, 1.0, 1.0, 1.0]),
"wall_length_west_neighbor": pd.Series([1.0, 1.0, 1.0, 1.0]),
"building_geometry_neighbor": gpd.GeoSeries(
[
building_geometry[0],
Expand Down Expand Up @@ -481,7 +510,16 @@ class TestCase:

for case in testcases:
actual = nodes.buildings_intersecting_plan_area(
building_id, building_height, building_geometry, building_area, case.input, crs
building_id,
building_height,
building_geometry,
building_area,
case.input,
wall_length_north,
wall_length_east,
wall_length_south,
wall_length_west,
crs,
)
expected = case.expected
pd.testing.assert_frame_equal(
Expand Down Expand Up @@ -637,6 +675,163 @@ class TestCase:
"failed test {} expected {}, actual {}".format(case.name, expected, actual),
)

def test_wall_length(self):
"""Test that the function wall_length returns the correct wall area."""

north = Settings.north
south = Settings.south
east = Settings.east
west = Settings.west

wall_angle = Settings.wall_angle
wall_direction = Settings.wall_direction
wall_length = Settings.wall_length

wall_length_north = Settings.wall_length_north
wall_length_south = Settings.wall_length_south
wall_length_east = Settings.wall_length_east
wall_length_west = Settings.wall_length_west

square_root_one_half = 0.7071067811865476

square_input = pd.concat(
[
pd.Series([[0.0, -90.0, 180.0, 90.0]], name=wall_angle),
pd.Series([[north, east, south, west]], name=wall_direction),
pd.Series([[1.0, 1.0, 1.0, 1.0]], name=wall_length),
],
axis=1,
)
triangle_input = pd.concat(
[
pd.Series([[45.0, 180.0, -90.0]], name=wall_angle),
pd.Series([[west, south, east]], name=wall_direction),
pd.Series([[1.0, square_root_one_half, square_root_one_half]], name=wall_length),
],
axis=1,
)
eight_sided_input = pd.concat(
[
pd.Series([[0.0, -90.0, 180.0, 90.0, -45.0, -135.0, 135.0, 45.0]], name=wall_angle),
pd.Series(
[[north, east, south, west, north, east, south, west]], name=wall_direction
),
pd.Series([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]], name=wall_length),
],
axis=1,
)

@dataclass
class TestCase:
name: str
input: pd.DataFrame
expected: pd.DataFrame

testcases = [
TestCase(
name="square",
input=square_input,
expected=pd.concat(
[
pd.Series([1.0], name=wall_length_north),
pd.Series([1.0], name=wall_length_east),
pd.Series([1.0], name=wall_length_south),
pd.Series([1.0], name=wall_length_west),
],
axis=1,
),
),
TestCase(
name="triangle",
input=triangle_input,
expected=pd.concat(
[
pd.Series([0], name=wall_length_north),
pd.Series([square_root_one_half], name=wall_length_east),
pd.Series([square_root_one_half], name=wall_length_south),
pd.Series([1.0], name=wall_length_west),
],
axis=1,
),
),
TestCase(
name="eight sided",
input=eight_sided_input,
expected=pd.concat(
[
pd.Series([6.0], name=wall_length_north),
pd.Series([8.0], name=wall_length_east),
pd.Series([10.0], name=wall_length_south),
pd.Series([12.0], name=wall_length_west),
],
axis=1,
),
),
]

for case in testcases:
actual = nodes.wall_length(case.input)
expected = case.expected
pd.testing.assert_frame_equal(
expected,
actual,
"failed test {} expected {}, actual {}".format(case.name, expected, actual),
)

def test_frontal_length(self):
"""Test that the function frontal_length returns the correct frontal length."""

polygon1 = Polygon([[0, 0], [0, 1], [1, 1], [1, 0]])
polygon2 = Polygon([[3, 3], [3, 4], [4, 4], [4, 3]])
building_id = pd.Series([0, 1])
building_height = pd.Series([5, 10])
building_geometry = pd.Series([polygon1, polygon2])
building_area = pd.Series([polygon1.area, polygon2.area])
crs = "epsg:3857"

# The wall lengths listed below are the test cases.
# wall_length_north and wall_length_east test that the addition is working correctly.
# wall_length_south tests that addition works correctly when one building does not have a wall facing a given direction.
# wall_length_west tests that addition works correctly when neither building has a wall facing a given direction.

wall_length_north = pd.Series([1.0, 1.0])
wall_length_east = pd.Series([1.0, 3.0])
wall_length_south = pd.Series([0, 1.0])
wall_length_west = pd.Series([0, 0])

frontal_length_north = Settings.frontal_length_north
frontal_length_east = Settings.frontal_length_east
frontal_length_south = Settings.frontal_length_south
frontal_length_west = Settings.frontal_length_west

total_plan_area_geometry = pd.Series([polygon1.buffer(5), polygon2.buffer(5)])

input_gdf = nodes.buildings_intersecting_plan_area(
building_id,
building_height,
building_geometry,
building_area,
total_plan_area_geometry,
wall_length_north,
wall_length_east,
wall_length_south,
wall_length_west,
crs,
)

actual = nodes.frontal_length(input_gdf)
expected = pd.concat(
[
pd.Series([2.0, 2.0], name=frontal_length_north),
pd.Series([4.0, 4.0], name=frontal_length_east),
pd.Series([1.0, 1.0], name=frontal_length_south),
pd.Series([0, 0], name=frontal_length_west),
],
axis=1,
)

pd.testing.assert_frame_equal(expected, actual)


if __name__ == "__main__":
unittest.main()

0 comments on commit ce1f021

Please sign in to comment.