From 06ae019e3130d0a91be3508c0d140d45e4ff4b22 Mon Sep 17 00:00:00 2001 From: levisweetbreu Date: Wed, 26 Jul 2023 14:13:34 -0500 Subject: [PATCH 1/5] added test_wall_area() --- tests/test_nodes.py | 103 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/tests/test_nodes.py b/tests/test_nodes.py index 53f08ababb..f49e6afc7e 100644 --- a/tests/test_nodes.py +++ b/tests/test_nodes.py @@ -637,6 +637,109 @@ class TestCase: "failed test {} expected {}, actual {}".format(case.name, expected, actual), ) + def test_wall_area(self): + """Test that the function wall_area 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_area_north = Settings.wall_area_north + wall_area_south = Settings.wall_area_south + wall_area_east = Settings.wall_area_east + wall_area_west = Settings.wall_area_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_area_north), + pd.Series([1.0], name=wall_area_east), + pd.Series([1.0], name=wall_area_south), + pd.Series([1.0], name=wall_area_west), + ], + axis=1, + ), + ), + TestCase( + name="triangle", + input=triangle_input, + expected=pd.concat( + [ + pd.Series([0.0], name=wall_area_north), + pd.Series([square_root_one_half], name=wall_area_east), + pd.Series([square_root_one_half], name=wall_area_south), + pd.Series([1.0], name=wall_area_west), + ], + axis=1, + ), + ), + TestCase( + name="eight sided", + input=eight_sided_input, + expected=pd.concat( + [ + pd.Series([6.0], name=wall_area_north), + pd.Series([8.0], name=wall_area_east), + pd.Series([10.0], name=wall_area_south), + pd.Series([12.0], name=wall_area_west), + ], + axis=1, + ), + ), + ] + + for case in testcases: + actual = nodes.wall_area(case.input) + expected = case.expected + pd.testing.assert_frame_equal( + expected, + actual, + "failed test {} expected {}, actual {}".format(case.name, expected, actual), + ) + if __name__ == "__main__": unittest.main() From 9da93043586b5db2c93862cbd92db380ce04bd21 Mon Sep 17 00:00:00 2001 From: levisweetbreu Date: Wed, 26 Jul 2023 14:24:43 -0500 Subject: [PATCH 2/5] changed dtype --- tests/test_nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_nodes.py b/tests/test_nodes.py index f49e6afc7e..e05d0e87d7 100644 --- a/tests/test_nodes.py +++ b/tests/test_nodes.py @@ -708,7 +708,7 @@ class TestCase: input=triangle_input, expected=pd.concat( [ - pd.Series([0.0], name=wall_area_north), + pd.Series([0], name=wall_area_north), pd.Series([square_root_one_half], name=wall_area_east), pd.Series([square_root_one_half], name=wall_area_south), pd.Series([1.0], name=wall_area_west), From 875ce3a74180b2863e88adf2e64cddd52af25642 Mon Sep 17 00:00:00 2001 From: levisweetbreu Date: Thu, 27 Jul 2023 10:51:16 -0500 Subject: [PATCH 3/5] renamed wall_area() to wall_length() --- tests/test_nodes.py | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/test_nodes.py b/tests/test_nodes.py index e05d0e87d7..57662e8baf 100644 --- a/tests/test_nodes.py +++ b/tests/test_nodes.py @@ -637,8 +637,8 @@ class TestCase: "failed test {} expected {}, actual {}".format(case.name, expected, actual), ) - def test_wall_area(self): - """Test that the function wall_area returns the correct wall area.""" + def test_wall_length(self): + """Test that the function wall_length returns the correct wall area.""" north = Settings.north south = Settings.south @@ -649,10 +649,10 @@ def test_wall_area(self): wall_direction = Settings.wall_direction wall_length = Settings.wall_length - wall_area_north = Settings.wall_area_north - wall_area_south = Settings.wall_area_south - wall_area_east = Settings.wall_area_east - wall_area_west = Settings.wall_area_west + 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 @@ -695,10 +695,10 @@ class TestCase: input=square_input, expected=pd.concat( [ - pd.Series([1.0], name=wall_area_north), - pd.Series([1.0], name=wall_area_east), - pd.Series([1.0], name=wall_area_south), - pd.Series([1.0], name=wall_area_west), + 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, ), @@ -708,10 +708,10 @@ class TestCase: input=triangle_input, expected=pd.concat( [ - pd.Series([0], name=wall_area_north), - pd.Series([square_root_one_half], name=wall_area_east), - pd.Series([square_root_one_half], name=wall_area_south), - pd.Series([1.0], name=wall_area_west), + 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, ), @@ -721,10 +721,10 @@ class TestCase: input=eight_sided_input, expected=pd.concat( [ - pd.Series([6.0], name=wall_area_north), - pd.Series([8.0], name=wall_area_east), - pd.Series([10.0], name=wall_area_south), - pd.Series([12.0], name=wall_area_west), + 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, ), @@ -732,7 +732,7 @@ class TestCase: ] for case in testcases: - actual = nodes.wall_area(case.input) + actual = nodes.wall_length(case.input) expected = case.expected pd.testing.assert_frame_equal( expected, From 0452aa2a1063963a21602d85576963f46fcfe86c Mon Sep 17 00:00:00 2001 From: levisweetbreu Date: Thu, 27 Jul 2023 11:22:48 -0500 Subject: [PATCH 4/5] added wall lengths to test_buildings_intersecting_plan_area() --- tests/test_nodes.py | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/tests/test_nodes.py b/tests/test_nodes.py index 57662e8baf..e8b4e47b1f 100644 --- a/tests/test_nodes.py +++ b/tests/test_nodes.py @@ -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)] @@ -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", @@ -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]), @@ -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], @@ -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]), @@ -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], @@ -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( From d4a9b9e32e0cb02c48382a484019862d6eadd5f3 Mon Sep 17 00:00:00 2001 From: levisweetbreu Date: Thu, 27 Jul 2023 16:01:33 -0500 Subject: [PATCH 5/5] added test_frontal_length() --- tests/test_nodes.py | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/test_nodes.py b/tests/test_nodes.py index e8b4e47b1f..6eac56db70 100644 --- a/tests/test_nodes.py +++ b/tests/test_nodes.py @@ -778,6 +778,60 @@ class TestCase: "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()