def test_multipolygon_infrastructure_landtake(self): site_rect = rect(1, 1, 12, 12) mainsite = SiteNode(site_rect, id="{Main site}") rec, tri = rect(9, 9, 10, 10), [(2, 2), (2, 4), (3, 4)] building = InfrastructureLandtake(rec, tri, parent_site=mainsite, id="{multipolygon building}") coords = list(map(list, building._coords)) expected_coords = [ [(9, 9), (10, 9), (10, 10), (9, 10), (9, 9)], [(2, 2), (2, 4), (3, 4), (2, 2)], ] self.assertEqual(coords, expected_coords) cleaner = builder.recursively_merge_all_subsites(mainsite) msite = cleaner.merged_site() mbuilder = builder.MeshBuilder(msite) alti = mbuilder._build_altimetric_base() bmesh = mbuilder._build_triangulation(alti) mbuilder._compute_informations(bmesh) vertices = [ list(map(bmesh.py_vertex, vertices_groups)) for vertices_groups in mbuilder.vertices_for_feature[building.id] ] assert_array_equal(vertices, expected_coords)
def test_building_outside_landtake(self): # outside landtake InfrastructureLandtake(rect(13, 12, 15, 17), parent_site=self.mainsite, id="{external building}") # intersecting with landtake InfrastructureLandtake(rect(10, 10, 13, 15), parent_site=self.mainsite, id="{intersecting building}") equivalent_site, mesh, feature_by_face = builder.build_altimetry( self.mainsite) # it makes no sense having a site intersecting a building. Make sure # none of these buildings will be taken into account. self.assertEqual(len(equivalent_site.landtakes), 1) self.assertEqual(equivalent_site.landtakes[0].id, '{Building}')
def test_landtake_flood_overwrite_material(self): (border, hole, line) = self.build_simple_scene() pond = self.mesher.insert_polyline( #NB CCW rect(3, 2.5, 4, 3.5), close_it=True, material='water', altitude=0, id='pond') self.mesher.update_info_for_edges() flooder = self.mesher.flood_polygon(mesh.LandtakeFaceFlooder, hole[0], close_it=True, flood_right=True) # hole is CW if runVisualTests: plotter = visu.MeshedCDTPlotter(self.mesher, title=self._testMethodName) plotter.plot_edges() marks = [self.mesher.point_for_face(f) for f in flooder.visited] visu.plot_points_seq(plotter.ax, marks, marker='*') plotter.show() face_in_both, expected_None = self.mesher.locate_point((3.25, 3)) self.assertIsNone(expected_None) self.assertIn(face_in_both, flooder.visited) face_out, expected_None = self.mesher.locate_point((1, 1.25)) self.assertIsNone(expected_None) self.assertNotIn(face_out, flooder.visited)
def test_add_and_clean_material_area(self): overlap_area = MaterialArea(rect(5, 7, 7, 9), material=self.grass, parent_site=self.mainsite, id="{Overlap area}") in_hole_scope_area = MaterialArea(rect(6, 6, 7, 7), material=self.grass, parent_site=self.mainsite, id="{In hole area}") cleaner = SiteNodeGeometryCleaner(self.mainsite) cleaner.process_material_areas() self.assertIn("{Overlap area}", cleaner.erroneous_overlap) self.assertIn("{In hole area}", cleaner.ignored_features) self.assertTrue(cleaner.geom["{Grass area}"].equals( self.grass_area.shape))
def test_merge_subsite_report_errors(self): overlap_area = MaterialArea(rect(5, 5, 7, 7), material=self.grass, parent_site=self.subsite, id="{Overlap area}") cleaner = SiteNodeGeometryCleaner(self.mainsite) with self.assertRaises(InconsistentGeometricModel): cleaner.merge_subsite(self.subsite)
def test_subsite_intersects_with_site(self): self.mainsite.drop_child(self.subsite) subsite = SiteNode(rect(-1, -1, 7, 5), id="{Intersecting subsite}", parent_site=self.mainsite) with self.assertRaises(RuntimeError) as cm: builder.recursively_merge_all_subsites(self.mainsite) self.assertEqual( str(cm.exception), 'SiteNode #{Intersecting subsite} is not strictly ' 'contained in main site')
def test_merge_subsite_material(self): self.subgrass = MaterialArea(rect(6, 7, 7, 8), material=self.grass, id="{Grass in subsite}", parent_site=self.subsite) cleaner = SiteNodeGeometryCleaner(self.mainsite) cleaner.process_all_features() cleaner.merge_subsite(self.subsite) self.assertIn(self.subgrass.id, cleaner.geom) geom, info = cleaner[self.subgrass.id] self.assertEqual(info['material'], self.grass.id)
def test_vertices_by_feature(self): coords = rect(9, 9, 10, 10) self.building = InfrastructureLandtake(coords, parent_site=self.mainsite, id="{some building}") cleaner = builder.recursively_merge_all_subsites(self.mainsite) msite = cleaner.merged_site() mbuilder = builder.MeshBuilder(msite) alti = mbuilder._build_altimetric_base() bmesh = mbuilder._build_triangulation(alti) mbuilder._compute_informations(bmesh) vertices = mbuilder.vertices_for_feature[self.building.id] for i, v in enumerate(vertices): self.assertEquals(v.point(), mesh.to_cgal_point(coords[i % len(coords)]))
def test_sorting_material_area_two_branches(self): site = SiteNode(rect(0, 0, 12, 12), id='{Main site}') cleaner = SiteNodeGeometryCleaner(self.mainsite) cleaner.process_material_areas() self.assertEqual(cleaner.check_issues_with_material_area_order(), [])
class AltimetryDataTC(unittest.TestCase): big_rect_coords = rect(0, 0, 12, 10) level_curve_A_coords = [(0, 0), (2.5, 3.5), (4, 4.0)] level_curve_A = LevelCurve(level_curve_A_coords, altitude=10.0, id="{123456}") level_curve_A_json = ( '{"geometry": {"coordinates": [[[0.0, 0.0], [2.5, 3.5], [4.0, 4.0]]],' ' "type": "MultiLineString"}, "id": "{123456}",' ' "properties": {"altitude": 10.0, "type": "LevelCurve"},' ' "type": "Feature"}') material_area_A_coords = big_rect_coords grass = GroundMaterial("grass") material_area_A = MaterialArea(material_area_A_coords, material=grass, id=None) material_area_A_json = ( '{"geometry": {' '"coordinates": [[[0.0, 0.0], [12.0, 0.0], [12.0, 10.0], [0.0, 10.0]]],' ' "type": "Polygon"},' ' "properties": {"material": "grass", "type": "MaterialArea"},' ' "type": "Feature"}') waterbody_coords = [(3, 3), (5, 4), (3, 5)] subsite_A_coords = [(8.0, 4.0), (8.0, 7.0), (12.0, 7.0)] subsite_A = SiteNode(subsite_A_coords, id='{Sub-site A ID}') level_curve_B_coords = [(8.0, 4.0), (8.0, 7.0), (12.0, 7.0)] def test_LevelCurve_as_json(self): self.assertEqual(self.level_curve_A.as_geojson, self.level_curve_A_json) def test_MaterialArea_as_json(self): self.assertEqual(self.material_area_A.as_geojson, self.material_area_A_json) def test_LevelCurve_as_shape(self): shape = self.level_curve_A.as_shape self.assertTrue( shape.equals(geometry.LineString(self.level_curve_A_coords))) def test_MaterialArea_as_shape(self): shape = geometry.shape(self.material_area_A) self.assertTrue( shape.equals(geometry.Polygon(self.material_area_A_coords))) def test_SiteNode_as_shape(self): shape = geometry.shape(self.subsite_A) self.assertTrue(shape.equals(geometry.Polygon(self.subsite_A_coords))) def test_site_belonging(self): self.assertIsNone(self.subsite_A.parent_site) level_curve_B = LevelCurve(self.level_curve_B_coords, altitude=20.0, parent_site=self.subsite_A, id=None) self.assertIn(level_curve_B, self.subsite_A.children["LevelCurve"]) self.assertEqual(level_curve_B.parent_site_id, "{Sub-site A ID}") def test_parent_site(self): level_curve_B = LevelCurve(self.level_curve_B_coords, altitude=20.0, id=None) self.assertIsNone(self.subsite_A.parent_site) level_curve_B.parent_site = self.subsite_A self.assertIn(level_curve_B, self.subsite_A.children["LevelCurve"]) del level_curve_B.parent_site self.assertNotIn(level_curve_B, self.subsite_A.children['LevelCurve']) def test_cached_shape_property(self): level_curve_B = LevelCurve(self.level_curve_B_coords, altitude=20.0, id=None) self.assertIsNone(level_curve_B._shape) shape = level_curve_B.shape self.assertTrue(shape.equals(level_curve_B.as_shape)) self.assertIs(shape, level_curve_B._shape) def test_polygon_validity(self): poly = PolygonalTympanFeature(self.big_rect_coords, id=None) try: poly.ensure_ok() except InconsistentGeometricModel: self.fail("poly was expected to be valid") coords = self.big_rect_coords[:] coords[1:3] = coords[2:0:-1] poly2 = PolygonalTympanFeature(coords, id="toto") with self.assertRaises(InconsistentGeometricModel) as cm: poly2.ensure_ok() self.assertEqual(cm.exception.ids, ["toto"]) self.assertIn("Self-intersection", str(cm.exception)) def test_polygon_exterior_orientation(self): coords = self.big_rect_coords[:] coords.reverse() # change orientation to CW poly = PolygonalTympanFeature(coords, id=None) self.assertTrue(poly.shape.exterior.is_ccw) def test_WaterBody_initialisation(self): waterbody = WaterBody(self.waterbody_coords, altitude=20, id=None) self.assertEqual(waterbody.altitude, 20.0) self.assertEqual(waterbody.material, MATERIAL_WATER) def test_sitenode_attribution_and_accessors(self): mainsite = SiteNode(self.big_rect_coords, id="{Main site ID}") subsite = SiteNode(self.subsite_A_coords, id="{Subsite ID}", parent_site=mainsite) level_curve_B = LevelCurve(self.level_curve_B_coords, altitude=20.0, parent_site=subsite, id=None) level_curve_A = LevelCurve(self.level_curve_A_coords, altitude=10.0, parent_site=mainsite, id=None) waterbody = WaterBody(self.waterbody_coords, altitude=5, parent_site=mainsite, id=None) vegarea = VegetationArea([(1, 1), (1, 3), (3, 1)], material=GroundMaterial('pine'), height=3, id=None) vegarea.parent_site = mainsite mainsite.add_child(self.material_area_A) self.assertCountEqual(mainsite.level_curves, [level_curve_A, waterbody]) self.assertCountEqual(mainsite.material_areas, [self.material_area_A, waterbody, vegarea]) self.assertCountEqual(mainsite.subsites, [subsite]) self.assertCountEqual(subsite.level_curves, [level_curve_B]) def test_elementary_shapes(self): mainsite = SiteNode(self.big_rect_coords, id="{Main site ID}") mls = MultiLineString([[(0.0, 0.0), (1.0, 0.0)], [(1.0, 1.0), (1.0, 2.0)]]) ls1 = LineString([(0.0, 0.0), (1.0, 0.0)]) ls2 = LineString([(1.0, 1.0), (1.0, 2.0)]) level_curve = LevelCurve(mls, altitude=10.0, parent_site=mainsite, id=None) shapes = elementary_shapes(level_curve.shape) self.assertEqual(len(shapes), 2) for shape in shapes: self.assertTrue(ls1.equals(shape) or ls2.equals(shape))