From de449edc76d3d829428758839bb90a5ebb8ad5a0 Mon Sep 17 00:00:00 2001 From: home-imac Date: Sun, 13 Nov 2022 20:10:42 -0500 Subject: [PATCH 01/15] added geopandas import support --- imports/geometry/gpandas.py | 118 ++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 imports/geometry/gpandas.py diff --git a/imports/geometry/gpandas.py b/imports/geometry/gpandas.py new file mode 100644 index 00000000..ce85d329 --- /dev/null +++ b/imports/geometry/gpandas.py @@ -0,0 +1,118 @@ +""" +gpandas module parses geopandas input table and import the geometry into the city model structure +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2022 Concordia CERC group +Project Coder: Milad Aghamohamadnia --- milad.aghamohamadnia@concordia.ca +""" + +import trimesh.exchange.load +from trimesh import Scene +import trimesh.geometry +from shapely.geometry import Polygon as ShapelyPoly +from shapely.geometry import Point +import trimesh +from pyproj import CRS +from city_model_structure.city import City +from city_model_structure.building import Building +from city_model_structure.building_demand.surface import Surface +from city_model_structure.attributes.polygon import Polygon +import numpy as np + + +class GPandas: + """ + GeoPandas class + """ + def __init__(self, gdataframe, srs_name='EPSG:26911'): + """_summary_ + + Arguments: + gdataframe {Geopandas.Dataframe} -- input geometry data in geopandas table + + Keyword Arguments: + srs_name {str} -- coordinate system of coordinate system (default: {'EPSG:26911'}) + """ + self._srs_name = srs_name + self._city = None + self._scene = gdataframe + self._scene = self._scene.to_crs(self._srs_name) + minx, miny, maxx, maxy = self._scene.total_bounds + self._lower_corner = [minx, miny, 0] + self._upper_corner = [maxx, maxy, 0] + + @property + def scene(self) -> Scene: + """ + Get GeoPandas scene + """ + return self._scene + + @property + def city(self) -> City: + """ + Get city out of a GeoPandas Table + """ + if self._city is None: + self._city = City(self._lower_corner, self._upper_corner, self._srs_name) + for ix, bldg in self._scene.iterrows(): + polygon = bldg['geometry'] + geom = bldg.geom + polygon = ShapelyPoly(geom['coordinates'][0]) + height = float(bldg['height_mean']) + building_mesh = trimesh.creation.extrude_polygon(polygon, height) + trimesh.repair.fill_holes(building_mesh) + trimesh.repair.fix_winding(building_mesh) + year_of_construction = int(bldg['year_built']) + name = str(ix) + lod = 1 + if year_of_construction>2000: + function = 'residential' + else: + function = 'industry' + average_storey_height = 3 + + surfaces = [] + face_normal = building_mesh.face_normals + for ix, face in enumerate(building_mesh.faces): + points = [] + for vertex_index in face: + points.append(building_mesh.vertices[vertex_index]) + solid_polygon = Polygon(points) + perimeter_polygon = solid_polygon + s_type = 'Ground' if face_normal[ix][2]==-1 else ('Roof' if face_normal[ix][2]==1 else 'Wall') + surface = Surface(solid_polygon, perimeter_polygon, surface_type=s_type) + surfaces.append(surface) + building = Building(name, lod, surfaces, year_of_construction, function, self._lower_corner, terrains=None) + self._city.add_city_object(building) + return self._city + + @staticmethod + def resize_polygon(poly, factor=0.10, expand=False): + """ + returns the shapely polygon which is smaller or bigger by passed factor. + + Arguments: + poly {shapely.geometry.Polygon} -- an input geometry in shapely polygon format + + Keyword Arguments: + factor {float} -- factor of expansion (default: {0.10}) + expand {bool} -- If expand = True , then it returns bigger polygon, else smaller (default: {False}) + + Returns: + {shapely.geometry.Polygon} -- output geometry in shapely polygon format + """ + xs = list(poly.exterior.coords.xy[0]) + ys = list(poly.exterior.coords.xy[1]) + x_center = 0.5 * min(xs) + 0.5 * max(xs) + y_center = 0.5 * min(ys) + 0.5 * max(ys) + min_corner = Point(min(xs), min(ys)) + max_corner = Point(max(xs), max(ys)) + center = Point(x_center, y_center) + shrink_distance = center.distance(min_corner)*factor + + if expand: + poly_resized = poly.buffer(shrink_distance) #expand + else: + poly_resized = poly.buffer(-shrink_distance) #shrink + return poly_resized + From 3568255c29da0fdd0706094231e1c66c6b3dad13 Mon Sep 17 00:00:00 2001 From: home-imac Date: Sun, 13 Nov 2022 21:07:04 -0500 Subject: [PATCH 02/15] gpandas added in factory --- imports/geometry_factory.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/imports/geometry_factory.py b/imports/geometry_factory.py index b1ac2f35..825b37de 100644 --- a/imports/geometry_factory.py +++ b/imports/geometry_factory.py @@ -10,6 +10,7 @@ from imports.geometry.citygml import CityGml from imports.geometry.obj import Obj from imports.geometry.osm_subway import OsmSubway from imports.geometry.rhino import Rhino +from imports.geometry.gpandas import GPandas class GeometryFactory: @@ -35,6 +36,15 @@ class GeometryFactory: :return: City """ return Obj(self._path).city + + + @property + def _gpandas(self) -> City: + """ + Enrich the city by using GeoPandas information as data source + :return: City + """ + return GPandas(self._path).city @property def _osm_subway(self) -> City: From fae577deaa5ab9af1421651ff815d80f0871696b Mon Sep 17 00:00:00 2001 From: home-imac Date: Mon, 14 Nov 2022 03:19:04 -0500 Subject: [PATCH 03/15] quick fix for failed archetype search --- imports/construction/us_physics_parameters.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imports/construction/us_physics_parameters.py b/imports/construction/us_physics_parameters.py index 2baa6749..657164bf 100644 --- a/imports/construction/us_physics_parameters.py +++ b/imports/construction/us_physics_parameters.py @@ -74,7 +74,9 @@ class UsPhysicsParameters(NrelPhysicsInterface): if (str(function) == str(building_archetype.function)) and \ (climate_zone == str(building_archetype.climate_zone)): return building_archetype - return None + # Todo: line below is added by Milad as a quick fix for when archetypes search is not found + return building_archetype + # return None @staticmethod def _search_construction_in_archetype(archetype, construction_type): From 7e5ead236345d08e3eb714c712d1d34e6d8cbaa2 Mon Sep 17 00:00:00 2001 From: guille Date: Tue, 15 Nov 2022 11:25:38 -0500 Subject: [PATCH 04/15] small style correction --- imports/geometry/gpandas.py | 197 ++++++++++++++--------------- requirements.txt | 3 +- unittests/test_geometry_factory.py | 12 ++ 3 files changed, 110 insertions(+), 102 deletions(-) diff --git a/imports/geometry/gpandas.py b/imports/geometry/gpandas.py index ce85d329..30658e52 100644 --- a/imports/geometry/gpandas.py +++ b/imports/geometry/gpandas.py @@ -5,114 +5,109 @@ Copyright © 2022 Concordia CERC group Project Coder: Milad Aghamohamadnia --- milad.aghamohamadnia@concordia.ca """ -import trimesh.exchange.load -from trimesh import Scene -import trimesh.geometry -from shapely.geometry import Polygon as ShapelyPoly -from shapely.geometry import Point import trimesh -from pyproj import CRS -from city_model_structure.city import City +import trimesh.exchange.load +import trimesh.geometry +from shapely.geometry import Point +from shapely.geometry import Polygon as ShapelyPoly +from trimesh import Scene + +from city_model_structure.attributes.polygon import Polygon from city_model_structure.building import Building from city_model_structure.building_demand.surface import Surface -from city_model_structure.attributes.polygon import Polygon -import numpy as np +from city_model_structure.city import City + +import helpers.constants as cte class GPandas: + """ + GeoPandas class + """ + + def __init__(self, gdataframe, srs_name='EPSG:26911'): + """_summary_ + Arguments: + gdataframe {Geopandas.Dataframe} -- input geometry data in geopandas table + Keyword Arguments: + srs_name {str} -- coordinate system of coordinate system (default: {'EPSG:26911'}) """ - GeoPandas class + self._srs_name = srs_name + self._city = None + self._scene = gdataframe + self._scene = self._scene.to_crs(self._srs_name) + min_x, min_y, max_x, max_y = self._scene.total_bounds + self._lower_corner = [min_x, min_y, 0] + self._upper_corner = [max_x, max_y, 0] + + @property + def scene(self) -> Scene: """ - def __init__(self, gdataframe, srs_name='EPSG:26911'): - """_summary_ + Get GeoPandas scene + """ + return self._scene - Arguments: - gdataframe {Geopandas.Dataframe} -- input geometry data in geopandas table - - Keyword Arguments: - srs_name {str} -- coordinate system of coordinate system (default: {'EPSG:26911'}) - """ - self._srs_name = srs_name - self._city = None - self._scene = gdataframe - self._scene = self._scene.to_crs(self._srs_name) - minx, miny, maxx, maxy = self._scene.total_bounds - self._lower_corner = [minx, miny, 0] - self._upper_corner = [maxx, maxy, 0] - - @property - def scene(self) -> Scene: - """ - Get GeoPandas scene - """ - return self._scene - - @property - def city(self) -> City: - """ - Get city out of a GeoPandas Table - """ - if self._city is None: - self._city = City(self._lower_corner, self._upper_corner, self._srs_name) - for ix, bldg in self._scene.iterrows(): - polygon = bldg['geometry'] - geom = bldg.geom - polygon = ShapelyPoly(geom['coordinates'][0]) - height = float(bldg['height_mean']) - building_mesh = trimesh.creation.extrude_polygon(polygon, height) - trimesh.repair.fill_holes(building_mesh) - trimesh.repair.fix_winding(building_mesh) - year_of_construction = int(bldg['year_built']) - name = str(ix) - lod = 1 - if year_of_construction>2000: - function = 'residential' - else: - function = 'industry' - average_storey_height = 3 - - surfaces = [] - face_normal = building_mesh.face_normals - for ix, face in enumerate(building_mesh.faces): - points = [] - for vertex_index in face: - points.append(building_mesh.vertices[vertex_index]) - solid_polygon = Polygon(points) - perimeter_polygon = solid_polygon - s_type = 'Ground' if face_normal[ix][2]==-1 else ('Roof' if face_normal[ix][2]==1 else 'Wall') - surface = Surface(solid_polygon, perimeter_polygon, surface_type=s_type) - surfaces.append(surface) - building = Building(name, lod, surfaces, year_of_construction, function, self._lower_corner, terrains=None) - self._city.add_city_object(building) - return self._city - - @staticmethod - def resize_polygon(poly, factor=0.10, expand=False): - """ - returns the shapely polygon which is smaller or bigger by passed factor. - - Arguments: - poly {shapely.geometry.Polygon} -- an input geometry in shapely polygon format - - Keyword Arguments: - factor {float} -- factor of expansion (default: {0.10}) - expand {bool} -- If expand = True , then it returns bigger polygon, else smaller (default: {False}) - - Returns: - {shapely.geometry.Polygon} -- output geometry in shapely polygon format - """ - xs = list(poly.exterior.coords.xy[0]) - ys = list(poly.exterior.coords.xy[1]) - x_center = 0.5 * min(xs) + 0.5 * max(xs) - y_center = 0.5 * min(ys) + 0.5 * max(ys) - min_corner = Point(min(xs), min(ys)) - max_corner = Point(max(xs), max(ys)) - center = Point(x_center, y_center) - shrink_distance = center.distance(min_corner)*factor - - if expand: - poly_resized = poly.buffer(shrink_distance) #expand + @property + def city(self) -> City: + """ + Get city out of a GeoPandas Table + """ + if self._city is None: + self._city = City(self._lower_corner, self._upper_corner, self._srs_name) + for ix, bldg in self._scene.iterrows(): + geom = bldg.geom + polygon = ShapelyPoly(geom['coordinates'][0]) + height = float(bldg['height_mean']) + building_mesh = trimesh.creation.extrude_polygon(polygon, height) + trimesh.repair.fill_holes(building_mesh) + trimesh.repair.fix_winding(building_mesh) + year_of_construction = int(bldg['year_built']) + name = str(ix) + lod = 1 + if year_of_construction > 2000: + function = cte.RESIDENTIAL else: - poly_resized = poly.buffer(-shrink_distance) #shrink - return poly_resized - + function = cte.INDUSTRY + + surfaces = [] + face_normal = building_mesh.face_normals + for ix, face in enumerate(building_mesh.faces): + points = [] + for vertex_index in face: + points.append(building_mesh.vertices[vertex_index]) + solid_polygon = Polygon(points) + perimeter_polygon = solid_polygon + s_type = cte.GROUND if face_normal[ix][2] == -1 else (cte.ROOF if face_normal[ix][2] == 1 else cte.WALL) + surface = Surface(solid_polygon, perimeter_polygon, surface_type=s_type) + surfaces.append(surface) + building = Building(name, lod, surfaces, year_of_construction, function, self._lower_corner, terrains=None) + self._city.add_city_object(building) + return self._city + + @staticmethod + def resize_polygon(poly, factor=0.10, expand=False) -> ShapelyPoly: + """ + returns the shapely polygon which is smaller or bigger by passed factor. + Arguments: + poly {shapely.geometry.Polygon} -- an input geometry in shapely polygon format + + Keyword Arguments: + factor {float} -- factor of expansion (default: {0.10}) + expand {bool} -- If expand = True , then it returns bigger polygon, else smaller (default: {False}) + + Returns: + {shapely.geometry.Polygon} -- output geometry in shapely polygon format + """ + xs = list(poly.exterior.coords.xy[0]) + ys = list(poly.exterior.coords.xy[1]) + x_center = 0.5 * min(xs) + 0.5 * max(xs) + y_center = 0.5 * min(ys) + 0.5 * max(ys) + min_corner = Point(min(xs), min(ys)) + center = Point(x_center, y_center) + shrink_distance = center.distance(min_corner) * factor + + if expand: + poly_resized = poly.buffer(shrink_distance) # expand + else: + poly_resized = poly.buffer(-shrink_distance) # shrink + return poly_resized diff --git a/requirements.txt b/requirements.txt index 5813e91f..30572325 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,4 +15,5 @@ ply rhino3dm==7.7.0 scipy PyYAML -pyecore==0.12.2 \ No newline at end of file +pyecore==0.12.2 +shapely \ No newline at end of file diff --git a/unittests/test_geometry_factory.py b/unittests/test_geometry_factory.py index 5551403c..2b225308 100644 --- a/unittests/test_geometry_factory.py +++ b/unittests/test_geometry_factory.py @@ -147,6 +147,18 @@ class TestGeometryFactory(TestCase): for building in city.buildings: self._check_surfaces(building) + def test_import_geopandas(self): + """ + Test geopandas import + """ + file = 'kelowna.obj' + city = self._get_obj(file) + self.assertIsNotNone(city, 'city is none') + self.assertTrue(len(city.buildings) == 1) + self._check_buildings(city) + for building in city.buildings: + self._check_surfaces(building) + # osm def test_subway(self): """ From d91da411fdb470ed9c2d5db33f5db2bff9fc4b8c Mon Sep 17 00:00:00 2001 From: guille Date: Tue, 15 Nov 2022 11:28:23 -0500 Subject: [PATCH 05/15] variable name correction, it will overwrite index and most likely case bugs in case of more than one scene. --- imports/geometry/gpandas.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imports/geometry/gpandas.py b/imports/geometry/gpandas.py index 30658e52..ac9a0961 100644 --- a/imports/geometry/gpandas.py +++ b/imports/geometry/gpandas.py @@ -54,7 +54,7 @@ class GPandas: """ if self._city is None: self._city = City(self._lower_corner, self._upper_corner, self._srs_name) - for ix, bldg in self._scene.iterrows(): + for scene_index, bldg in self._scene.iterrows(): geom = bldg.geom polygon = ShapelyPoly(geom['coordinates'][0]) height = float(bldg['height_mean']) @@ -62,7 +62,7 @@ class GPandas: trimesh.repair.fill_holes(building_mesh) trimesh.repair.fix_winding(building_mesh) year_of_construction = int(bldg['year_built']) - name = str(ix) + name = str(scene_index) lod = 1 if year_of_construction > 2000: function = cte.RESIDENTIAL @@ -71,13 +71,13 @@ class GPandas: surfaces = [] face_normal = building_mesh.face_normals - for ix, face in enumerate(building_mesh.faces): + for face_index, face in enumerate(building_mesh.faces): points = [] for vertex_index in face: points.append(building_mesh.vertices[vertex_index]) solid_polygon = Polygon(points) perimeter_polygon = solid_polygon - s_type = cte.GROUND if face_normal[ix][2] == -1 else (cte.ROOF if face_normal[ix][2] == 1 else cte.WALL) + s_type = cte.GROUND if face_normal[face_index][2] == -1 else (cte.ROOF if face_normal[face_index][2] == 1 else cte.WALL) surface = Surface(solid_polygon, perimeter_polygon, surface_type=s_type) surfaces.append(surface) building = Building(name, lod, surfaces, year_of_construction, function, self._lower_corner, terrains=None) From a617f598ff733697f786ad8d4be37e8174749a8a Mon Sep 17 00:00:00 2001 From: guille Date: Wed, 16 Nov 2022 16:26:45 -0500 Subject: [PATCH 06/15] Add unit tests and requirements for geopandas factory. Geopandas factory now can receive a geojson file or a pandas data frame by using the optional variable data_frame in the constructor to be consistent with the rest of the factories So from: ConstructionFactory('gpandas', dataframe) to: ConstructionFactory('gpandas, '', dataframe) --- imports/geometry/gpandas.py | 13 +++++++------ imports/geometry_factory.py | 11 +++++++---- requirements.txt | 4 +++- unittests/test_enrichement.py | 2 -- unittests/test_geometry_factory.py | 15 +++++++++++++-- unittests/tests_data/sample.geojson | 18 ++++++++++++++++++ 6 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 unittests/tests_data/sample.geojson diff --git a/imports/geometry/gpandas.py b/imports/geometry/gpandas.py index ac9a0961..5edbe0c6 100644 --- a/imports/geometry/gpandas.py +++ b/imports/geometry/gpandas.py @@ -8,6 +8,8 @@ Project Coder: Milad Aghamohamadnia --- milad.aghamohamadnia@concordia.ca import trimesh import trimesh.exchange.load import trimesh.geometry +import trimesh.creation +import trimesh.repair from shapely.geometry import Point from shapely.geometry import Polygon as ShapelyPoly from trimesh import Scene @@ -25,16 +27,17 @@ class GPandas: GeoPandas class """ - def __init__(self, gdataframe, srs_name='EPSG:26911'): + def __init__(self, dataframe, srs_name='EPSG:26911'): """_summary_ Arguments: - gdataframe {Geopandas.Dataframe} -- input geometry data in geopandas table + dataframe {Geopandas.Dataframe} -- input geometry data in geopandas table Keyword Arguments: srs_name {str} -- coordinate system of coordinate system (default: {'EPSG:26911'}) """ + self._srs_name = srs_name self._city = None - self._scene = gdataframe + self._scene = dataframe self._scene = self._scene.to_crs(self._srs_name) min_x, min_y, max_x, max_y = self._scene.total_bounds self._lower_corner = [min_x, min_y, 0] @@ -70,15 +73,13 @@ class GPandas: function = cte.INDUSTRY surfaces = [] - face_normal = building_mesh.face_normals for face_index, face in enumerate(building_mesh.faces): points = [] for vertex_index in face: points.append(building_mesh.vertices[vertex_index]) solid_polygon = Polygon(points) perimeter_polygon = solid_polygon - s_type = cte.GROUND if face_normal[face_index][2] == -1 else (cte.ROOF if face_normal[face_index][2] == 1 else cte.WALL) - surface = Surface(solid_polygon, perimeter_polygon, surface_type=s_type) + surface = Surface(solid_polygon, perimeter_polygon) surfaces.append(surface) building = Building(name, lod, surfaces, year_of_construction, function, self._lower_corner, terrains=None) self._city.add_city_object(building) diff --git a/imports/geometry_factory.py b/imports/geometry_factory.py index 825b37de..581edece 100644 --- a/imports/geometry_factory.py +++ b/imports/geometry_factory.py @@ -11,15 +11,16 @@ from imports.geometry.obj import Obj from imports.geometry.osm_subway import OsmSubway from imports.geometry.rhino import Rhino from imports.geometry.gpandas import GPandas - +import geopandas class GeometryFactory: """ GeometryFactory class """ - def __init__(self, file_type, path): + def __init__(self, file_type, path, data_frame=None): self._file_type = '_' + file_type.lower() self._path = path + self._data_frame = data_frame @property def _citygml(self) -> City: @@ -44,7 +45,9 @@ class GeometryFactory: Enrich the city by using GeoPandas information as data source :return: City """ - return GPandas(self._path).city + if self._data_frame is None: + self._data_frame = geopandas.read_file(self._path) + return GPandas(self._data_frame).city @property def _osm_subway(self) -> City: @@ -76,4 +79,4 @@ class GeometryFactory: Enrich the city given to the class using the class given handler :return: City """ - return CityGml(self._path).city + return GPandas(geopandas.read_file(self._path)).city diff --git a/requirements.txt b/requirements.txt index 30572325..71e5f372 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,4 +16,6 @@ rhino3dm==7.7.0 scipy PyYAML pyecore==0.12.2 -shapely \ No newline at end of file +shapely +geopandas +triangle \ No newline at end of file diff --git a/unittests/test_enrichement.py b/unittests/test_enrichement.py index 16831dea..6ace72d4 100644 --- a/unittests/test_enrichement.py +++ b/unittests/test_enrichement.py @@ -93,9 +93,7 @@ class TestGeometryFactory(TestCase): _construction_keys = ['nrel'] _usage_keys = ['comnet', 'hft'] for construction_key in _construction_keys: - print('construction key: ', construction_key) for usage_key in _usage_keys: - print('usage key: ', usage_key) # construction factory called first city = self._get_citygml(file) for building in city.buildings: diff --git a/unittests/test_geometry_factory.py b/unittests/test_geometry_factory.py index 2b225308..a35c1d86 100644 --- a/unittests/test_geometry_factory.py +++ b/unittests/test_geometry_factory.py @@ -8,9 +8,11 @@ from pathlib import Path from unittest import TestCase from numpy import inf +from pyproj import Proj, transform from imports.geometry_factory import GeometryFactory from imports.construction_factory import ConstructionFactory +import geopandas class TestGeometryFactory(TestCase): @@ -32,6 +34,12 @@ class TestGeometryFactory(TestCase): self.assertIsNotNone(self._city, 'city is none') return self._city + def _get_geojson(self, file): + file_path = (self._example_path / file).resolve() + self._city = GeometryFactory('gpandas', file_path).city_debug + self.assertIsNotNone(self._city, 'city is none') + return self._city + def _get_obj(self, file): # todo: solve the incongruities between city and city_debug file_path = (self._example_path / file).resolve() @@ -151,13 +159,16 @@ class TestGeometryFactory(TestCase): """ Test geopandas import """ - file = 'kelowna.obj' - city = self._get_obj(file) + file = 'sample.geojson' + city = self._get_geojson(file) self.assertIsNotNone(city, 'city is none') self.assertTrue(len(city.buildings) == 1) self._check_buildings(city) + for building in city.buildings: self._check_surfaces(building) + self.assertEqual(1912.0898135701814, building.volume) + self.assertEqual(146.19493345171213, building.floor_area) # osm def test_subway(self): diff --git a/unittests/tests_data/sample.geojson b/unittests/tests_data/sample.geojson new file mode 100644 index 00000000..254542b3 --- /dev/null +++ b/unittests/tests_data/sample.geojson @@ -0,0 +1,18 @@ +{ "type": "FeatureCollection", + "features": [ + { "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ [[-73.5027962600162, 45.6572759731914], [-73.5027463586105, 45.6572669735158], [-73.5027513584185, 45.6572530729948], [-73.5026715592026, 45.6572412737672], [-73.5026410593539, 45.6573430727752], [-73.5027703584728, 45.6573621728624], [-73.5027962600162, 45.6572759731914]] ] + ] + + }, + "properties": { + "geom": {"type": "Polygon", "crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::4326"}}, "coordinates": [[[3849322.0855625975, 6060583.24800576], [3849326.3956304314, 6060584.796717078], [3849327.0180495544, 6060583.089519385], [3849333.725799462, 6060585.837955164], [3849328.71788522, 6060598.03498192], [3849317.850609142, 6060593.57976506], [3849322.0855625975, 6060583.24800576]]]}, + "height_mean": 13.0790429485, + "year_built": 2000 + } + } + ] + } \ No newline at end of file From 37187b70468094606c0c24989802aca34ab3b498 Mon Sep 17 00:00:00 2001 From: guille Date: Wed, 16 Nov 2022 16:27:34 -0500 Subject: [PATCH 07/15] small style correction --- imports/geometry_factory.py | 1 - 1 file changed, 1 deletion(-) diff --git a/imports/geometry_factory.py b/imports/geometry_factory.py index 581edece..e9daa30b 100644 --- a/imports/geometry_factory.py +++ b/imports/geometry_factory.py @@ -37,7 +37,6 @@ class GeometryFactory: :return: City """ return Obj(self._path).city - @property def _gpandas(self) -> City: From 3b598de4d78382af79cfeb3370fc7ee1c362e11b Mon Sep 17 00:00:00 2001 From: guille Date: Wed, 16 Nov 2022 19:19:52 -0500 Subject: [PATCH 08/15] Add up to 154 vertex per polygon --- exports/formats/idf_files/Energy+.idd | 305 +++++++++++++++++++++++++- 1 file changed, 304 insertions(+), 1 deletion(-) diff --git a/exports/formats/idf_files/Energy+.idd b/exports/formats/idf_files/Energy+.idd index 12d2d762..499e2211 100644 --- a/exports/formats/idf_files/Energy+.idd +++ b/exports/formats/idf_files/Energy+.idd @@ -10881,9 +10881,312 @@ BuildingSurface:Detailed, N361, \field Vertex 120 Y-coordinate \units m \type real - N362; \field Vertex 120 Z-coordinate + N362, \field Vertex 120 Z-coordinate \units m \type real + N363, \field Vertex 121 X-coordinate + \units m + \type real + N364, \field Vertex 121 Y-coordinate + \units m + \type real + N365, \field Vertex 121 Z-coordinate + \units m + \type real + N366, \field Vertex 122 X-coordinate + \units m + \type real + N367, \field Vertex 122 Y-coordinate + \units m + \type real + N368, \field Vertex 122 Z-coordinate + \units m + \type real + N369, \field Vertex 123 X-coordinate + \units m + \type real + N370, \field Vertex 123 Y-coordinate + \units m + \type real + N371, \field Vertex 123 Z-coordinate + \units m + \type real + N372, \field Vertex 124 X-coordinate + \units m + \type real + N373, \field Vertex 124 Y-coordinate + \units m + \type real + N374, \field Vertex 124 Z-coordinate + \units m + \type real + N375, \field Vertex 125 X-coordinate + \units m + \type real + N376, \field Vertex 125 Y-coordinate + \units m + \type real + N377, \field Vertex 125 Z-coordinate + \units m + \type real + N378, \field Vertex 126 X-coordinate + \units m + \type real + N379, \field Vertex 126 Y-coordinate + \units m + \type real + N380, \field Vertex 126 Z-coordinate + \units m + \type real + N381, \field Vertex 127 X-coordinate + \units m + \type real + N382, \field Vertex 127 Y-coordinate + \units m + \type real + N383, \field Vertex 127 Z-coordinate + \units m + \type real + N384, \field Vertex 128 X-coordinate + \units m + \type real + N385, \field Vertex 128 Y-coordinate + \units m + \type real + N386, \field Vertex 128 Z-coordinate + \units m + \type real + N387, \field Vertex 129 X-coordinate + \units m + \type real + N388, \field Vertex 129 Y-coordinate + \units m + \type real + N389, \field Vertex 129 Z-coordinate + \units m + \type real + N390, \field Vertex 130 X-coordinate + \units m + \type real + N391, \field Vertex 130 Y-coordinate + \units m + \type real + N392, \field Vertex 130 Z-coordinate + \units m + \type real + N393, \field Vertex 131 X-coordinate + \units m + \type real + N394, \field Vertex 131 Y-coordinate + \units m + \type real + N395, \field Vertex 131 Z-coordinate + \units m + \type real + N396, \field Vertex 132 X-coordinate + \units m + \type real + N397, \field Vertex 132 Y-coordinate + \units m + \type real + N398, \field Vertex 132 Z-coordinate + \units m + \type real + N399, \field Vertex 133 X-coordinate + \units m + \type real + N400, \field Vertex 133 Y-coordinate + \units m + \type real + N401, \field Vertex 133 Z-coordinate + \units m + \type real + N402, \field Vertex 134 X-coordinate + \units m + \type real + N403, \field Vertex 134 Y-coordinate + \units m + \type real + N404, \field Vertex 134 Z-coordinate + \units m + \type real + N405, \field Vertex 135 X-coordinate + \units m + \type real + N406, \field Vertex 135 Y-coordinate + \units m + \type real + N407, \field Vertex 135 Z-coordinate + \units m + \type real + N408, \field Vertex 136 X-coordinate + \units m + \type real + N409, \field Vertex 136 Y-coordinate + \units m + \type real + N410, \field Vertex 136 Z-coordinate + \units m + \type real + N411, \field Vertex 137 X-coordinate + \units m + \type real + N412, \field Vertex 137 Y-coordinate + \units m + \type real + N413, \field Vertex 137 Z-coordinate + \units m + \type real + N414, \field Vertex 138 X-coordinate + \units m + \type real + N415, \field Vertex 138 Y-coordinate + \units m + \type real + N416, \field Vertex 138 Z-coordinate + \units m + \type real + N417, \field Vertex 139 X-coordinate + \units m + \type real + N418, \field Vertex 139 Y-coordinate + \units m + \type real + N419, \field Vertex 139 Z-coordinate + \units m + \type real + N420, \field Vertex 140 X-coordinate + \units m + \type real + N421, \field Vertex 140 Y-coordinate + \units m + \type real + N422, \field Vertex 140 Z-coordinate + \units m + \type real + N423, \field Vertex 141 X-coordinate + \units m + \type real + N424, \field Vertex 141 Y-coordinate + \units m + \type real + N425, \field Vertex 141 Z-coordinate + \units m + \type real + N426, \field Vertex 142 X-coordinate + \units m + \type real + N427, \field Vertex 142 Y-coordinate + \units m + \type real + N428, \field Vertex 142 Z-coordinate + \units m + \type real + N429, \field Vertex 143 X-coordinate + \units m + \type real + N430, \field Vertex 143 Y-coordinate + \units m + \type real + N431, \field Vertex 143 Z-coordinate + \units m + \type real + N432, \field Vertex 144 X-coordinate + \units m + \type real + N433, \field Vertex 144 Y-coordinate + \units m + \type real + N434, \field Vertex 144 Z-coordinate + \units m + \type real + N435, \field Vertex 145 X-coordinate + \units m + \type real + N436, \field Vertex 145 Y-coordinate + \units m + \type real + N437, \field Vertex 145 Z-coordinate + \units m + \type real + N438, \field Vertex 146 X-coordinate + \units m + \type real + N439, \field Vertex 146 Y-coordinate + \units m + \type real + N440, \field Vertex 146 Z-coordinate + \units m + \type real + N441, \field Vertex 147 X-coordinate + \units m + \type real + N442, \field Vertex 147 Y-coordinate + \units m + \type real + N443, \field Vertex 147 Z-coordinate + \units m + \type real + N444, \field Vertex 148 X-coordinate + \units m + \type real + N445, \field Vertex 148 Y-coordinate + \units m + \type real + N446, \field Vertex 148 Z-coordinate + \units m + \type real + N447, \field Vertex 149 X-coordinate + \units m + \type real + N448, \field Vertex 149 Y-coordinate + \units m + \type real + N449, \field Vertex 149 Z-coordinate + \units m + \type real + N450, \field Vertex 150 X-coordinate + \units m + \type real + N451, \field Vertex 150 Y-coordinate + \units m + \type real + N452, \field Vertex 150 Z-coordinate + \units m + \type real + N453, \field Vertex 151 X-coordinate + \units m + \type real + N454, \field Vertex 151 Y-coordinate + \units m + \type real + N455, \field Vertex 151 Z-coordinate + \units m + \type real + N456, \field Vertex 152 X-coordinate + \units m + \type real + N457, \field Vertex 152 Y-coordinate + \units m + \type real + N458, \field Vertex 152 Z-coordinate + \units m + \type real + N459, \field Vertex 153 X-coordinate + \units m + \type real + N460, \field Vertex 153 Y-coordinate + \units m + \type real + N461, \field Vertex 153 Z-coordinate + \units m + \type real + N462; \field Vertex 154 X-coordinate + \units m + \type real + +Process finished with exit code 0 + Wall:Detailed, \memo Allows for detailed entry of wall heat transfer surfaces. From bacd6bab2043aada40d5d898df6ca4d3748523c5 Mon Sep 17 00:00:00 2001 From: guille Date: Wed, 16 Nov 2022 19:44:59 -0500 Subject: [PATCH 09/15] correct typo --- exports/formats/idf_files/Energy+.idd | 3 --- 1 file changed, 3 deletions(-) diff --git a/exports/formats/idf_files/Energy+.idd b/exports/formats/idf_files/Energy+.idd index 499e2211..3d0a1c3a 100644 --- a/exports/formats/idf_files/Energy+.idd +++ b/exports/formats/idf_files/Energy+.idd @@ -11185,9 +11185,6 @@ BuildingSurface:Detailed, \units m \type real -Process finished with exit code 0 - - Wall:Detailed, \memo Allows for detailed entry of wall heat transfer surfaces. \extensible:3 -- duplicate last set of x,y,z coordinates (last 3 fields), remembering to remove ; from "inner" fields. From b47a21dbfa9417cc5e15819b048acb75e2098324 Mon Sep 17 00:00:00 2001 From: guille Date: Thu, 17 Nov 2022 11:26:18 -0500 Subject: [PATCH 10/15] Remove custom idd --- exports/formats/idf_files/Energy+.idd | 302 +------------------------- 1 file changed, 1 insertion(+), 301 deletions(-) diff --git a/exports/formats/idf_files/Energy+.idd b/exports/formats/idf_files/Energy+.idd index 3d0a1c3a..12d2d762 100644 --- a/exports/formats/idf_files/Energy+.idd +++ b/exports/formats/idf_files/Energy+.idd @@ -10881,307 +10881,7 @@ BuildingSurface:Detailed, N361, \field Vertex 120 Y-coordinate \units m \type real - N362, \field Vertex 120 Z-coordinate - \units m - \type real - N363, \field Vertex 121 X-coordinate - \units m - \type real - N364, \field Vertex 121 Y-coordinate - \units m - \type real - N365, \field Vertex 121 Z-coordinate - \units m - \type real - N366, \field Vertex 122 X-coordinate - \units m - \type real - N367, \field Vertex 122 Y-coordinate - \units m - \type real - N368, \field Vertex 122 Z-coordinate - \units m - \type real - N369, \field Vertex 123 X-coordinate - \units m - \type real - N370, \field Vertex 123 Y-coordinate - \units m - \type real - N371, \field Vertex 123 Z-coordinate - \units m - \type real - N372, \field Vertex 124 X-coordinate - \units m - \type real - N373, \field Vertex 124 Y-coordinate - \units m - \type real - N374, \field Vertex 124 Z-coordinate - \units m - \type real - N375, \field Vertex 125 X-coordinate - \units m - \type real - N376, \field Vertex 125 Y-coordinate - \units m - \type real - N377, \field Vertex 125 Z-coordinate - \units m - \type real - N378, \field Vertex 126 X-coordinate - \units m - \type real - N379, \field Vertex 126 Y-coordinate - \units m - \type real - N380, \field Vertex 126 Z-coordinate - \units m - \type real - N381, \field Vertex 127 X-coordinate - \units m - \type real - N382, \field Vertex 127 Y-coordinate - \units m - \type real - N383, \field Vertex 127 Z-coordinate - \units m - \type real - N384, \field Vertex 128 X-coordinate - \units m - \type real - N385, \field Vertex 128 Y-coordinate - \units m - \type real - N386, \field Vertex 128 Z-coordinate - \units m - \type real - N387, \field Vertex 129 X-coordinate - \units m - \type real - N388, \field Vertex 129 Y-coordinate - \units m - \type real - N389, \field Vertex 129 Z-coordinate - \units m - \type real - N390, \field Vertex 130 X-coordinate - \units m - \type real - N391, \field Vertex 130 Y-coordinate - \units m - \type real - N392, \field Vertex 130 Z-coordinate - \units m - \type real - N393, \field Vertex 131 X-coordinate - \units m - \type real - N394, \field Vertex 131 Y-coordinate - \units m - \type real - N395, \field Vertex 131 Z-coordinate - \units m - \type real - N396, \field Vertex 132 X-coordinate - \units m - \type real - N397, \field Vertex 132 Y-coordinate - \units m - \type real - N398, \field Vertex 132 Z-coordinate - \units m - \type real - N399, \field Vertex 133 X-coordinate - \units m - \type real - N400, \field Vertex 133 Y-coordinate - \units m - \type real - N401, \field Vertex 133 Z-coordinate - \units m - \type real - N402, \field Vertex 134 X-coordinate - \units m - \type real - N403, \field Vertex 134 Y-coordinate - \units m - \type real - N404, \field Vertex 134 Z-coordinate - \units m - \type real - N405, \field Vertex 135 X-coordinate - \units m - \type real - N406, \field Vertex 135 Y-coordinate - \units m - \type real - N407, \field Vertex 135 Z-coordinate - \units m - \type real - N408, \field Vertex 136 X-coordinate - \units m - \type real - N409, \field Vertex 136 Y-coordinate - \units m - \type real - N410, \field Vertex 136 Z-coordinate - \units m - \type real - N411, \field Vertex 137 X-coordinate - \units m - \type real - N412, \field Vertex 137 Y-coordinate - \units m - \type real - N413, \field Vertex 137 Z-coordinate - \units m - \type real - N414, \field Vertex 138 X-coordinate - \units m - \type real - N415, \field Vertex 138 Y-coordinate - \units m - \type real - N416, \field Vertex 138 Z-coordinate - \units m - \type real - N417, \field Vertex 139 X-coordinate - \units m - \type real - N418, \field Vertex 139 Y-coordinate - \units m - \type real - N419, \field Vertex 139 Z-coordinate - \units m - \type real - N420, \field Vertex 140 X-coordinate - \units m - \type real - N421, \field Vertex 140 Y-coordinate - \units m - \type real - N422, \field Vertex 140 Z-coordinate - \units m - \type real - N423, \field Vertex 141 X-coordinate - \units m - \type real - N424, \field Vertex 141 Y-coordinate - \units m - \type real - N425, \field Vertex 141 Z-coordinate - \units m - \type real - N426, \field Vertex 142 X-coordinate - \units m - \type real - N427, \field Vertex 142 Y-coordinate - \units m - \type real - N428, \field Vertex 142 Z-coordinate - \units m - \type real - N429, \field Vertex 143 X-coordinate - \units m - \type real - N430, \field Vertex 143 Y-coordinate - \units m - \type real - N431, \field Vertex 143 Z-coordinate - \units m - \type real - N432, \field Vertex 144 X-coordinate - \units m - \type real - N433, \field Vertex 144 Y-coordinate - \units m - \type real - N434, \field Vertex 144 Z-coordinate - \units m - \type real - N435, \field Vertex 145 X-coordinate - \units m - \type real - N436, \field Vertex 145 Y-coordinate - \units m - \type real - N437, \field Vertex 145 Z-coordinate - \units m - \type real - N438, \field Vertex 146 X-coordinate - \units m - \type real - N439, \field Vertex 146 Y-coordinate - \units m - \type real - N440, \field Vertex 146 Z-coordinate - \units m - \type real - N441, \field Vertex 147 X-coordinate - \units m - \type real - N442, \field Vertex 147 Y-coordinate - \units m - \type real - N443, \field Vertex 147 Z-coordinate - \units m - \type real - N444, \field Vertex 148 X-coordinate - \units m - \type real - N445, \field Vertex 148 Y-coordinate - \units m - \type real - N446, \field Vertex 148 Z-coordinate - \units m - \type real - N447, \field Vertex 149 X-coordinate - \units m - \type real - N448, \field Vertex 149 Y-coordinate - \units m - \type real - N449, \field Vertex 149 Z-coordinate - \units m - \type real - N450, \field Vertex 150 X-coordinate - \units m - \type real - N451, \field Vertex 150 Y-coordinate - \units m - \type real - N452, \field Vertex 150 Z-coordinate - \units m - \type real - N453, \field Vertex 151 X-coordinate - \units m - \type real - N454, \field Vertex 151 Y-coordinate - \units m - \type real - N455, \field Vertex 151 Z-coordinate - \units m - \type real - N456, \field Vertex 152 X-coordinate - \units m - \type real - N457, \field Vertex 152 Y-coordinate - \units m - \type real - N458, \field Vertex 152 Z-coordinate - \units m - \type real - N459, \field Vertex 153 X-coordinate - \units m - \type real - N460, \field Vertex 153 Y-coordinate - \units m - \type real - N461, \field Vertex 153 Z-coordinate - \units m - \type real - N462; \field Vertex 154 X-coordinate + N362; \field Vertex 120 Z-coordinate \units m \type real From 5b99d3b190e3c9b9ea7aa6c213cf10fe9b83ad57 Mon Sep 17 00:00:00 2001 From: home-imac Date: Thu, 17 Nov 2022 17:28:24 -0500 Subject: [PATCH 11/15] ignore __pycache__ --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c1c7f0df..5cb348dd 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /data/energy_systems/heat_pumps/*.csv /data/energy_systems/heat_pumps/*.insel .DS_Store +**/__pycache__/ From c24ad62081bf060532fa26b13c83dddbcaf62186 Mon Sep 17 00:00:00 2001 From: home-imac Date: Fri, 18 Nov 2022 15:36:03 -0500 Subject: [PATCH 12/15] fixed importer and geometr factory issue --- imports/geometry/gpandas.py | 8 ++++---- imports/geometry_factory.py | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/imports/geometry/gpandas.py b/imports/geometry/gpandas.py index 5edbe0c6..d716c8cf 100644 --- a/imports/geometry/gpandas.py +++ b/imports/geometry/gpandas.py @@ -58,10 +58,10 @@ class GPandas: if self._city is None: self._city = City(self._lower_corner, self._upper_corner, self._srs_name) for scene_index, bldg in self._scene.iterrows(): - geom = bldg.geom - polygon = ShapelyPoly(geom['coordinates'][0]) - height = float(bldg['height_mean']) - building_mesh = trimesh.creation.extrude_polygon(polygon, height) + geometry = bldg.geometry + # polygon = ShapelyPoly(geometry['coordinates'][0]) + height = float(bldg['height']) + building_mesh = trimesh.creation.extrude_polygon(geometry, height) trimesh.repair.fill_holes(building_mesh) trimesh.repair.fix_winding(building_mesh) year_of_construction = int(bldg['year_built']) diff --git a/imports/geometry_factory.py b/imports/geometry_factory.py index e9daa30b..eec1e130 100644 --- a/imports/geometry_factory.py +++ b/imports/geometry_factory.py @@ -17,7 +17,7 @@ class GeometryFactory: """ GeometryFactory class """ - def __init__(self, file_type, path, data_frame=None): + def __init__(self, file_type, path=None, data_frame=None): self._file_type = '_' + file_type.lower() self._path = path self._data_frame = data_frame @@ -46,6 +46,7 @@ class GeometryFactory: """ if self._data_frame is None: self._data_frame = geopandas.read_file(self._path) + print( self._data_frame ) return GPandas(self._data_frame).city @property From ac9b51b8b96386e473b00df280b73ec51aa11210 Mon Sep 17 00:00:00 2001 From: Pilar Date: Mon, 21 Nov 2022 11:31:30 -0500 Subject: [PATCH 13/15] Temporary fixed in geopandas importer --- imports/geometry_factory.py | 2 +- unittests/test_geometry_factory.py | 2 +- unittests/tests_data/sample.geojson | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imports/geometry_factory.py b/imports/geometry_factory.py index eec1e130..51683847 100644 --- a/imports/geometry_factory.py +++ b/imports/geometry_factory.py @@ -17,7 +17,7 @@ class GeometryFactory: """ GeometryFactory class """ - def __init__(self, file_type, path=None, data_frame=None): + def __init__(self, file_type, path, data_frame=None): self._file_type = '_' + file_type.lower() self._path = path self._data_frame = data_frame diff --git a/unittests/test_geometry_factory.py b/unittests/test_geometry_factory.py index a35c1d86..dc6381d5 100644 --- a/unittests/test_geometry_factory.py +++ b/unittests/test_geometry_factory.py @@ -36,7 +36,7 @@ class TestGeometryFactory(TestCase): def _get_geojson(self, file): file_path = (self._example_path / file).resolve() - self._city = GeometryFactory('gpandas', file_path).city_debug + self._city = GeometryFactory('gpandas', path=file_path).city self.assertIsNotNone(self._city, 'city is none') return self._city diff --git a/unittests/tests_data/sample.geojson b/unittests/tests_data/sample.geojson index 254542b3..3b1f2eca 100644 --- a/unittests/tests_data/sample.geojson +++ b/unittests/tests_data/sample.geojson @@ -10,7 +10,7 @@ }, "properties": { "geom": {"type": "Polygon", "crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::4326"}}, "coordinates": [[[3849322.0855625975, 6060583.24800576], [3849326.3956304314, 6060584.796717078], [3849327.0180495544, 6060583.089519385], [3849333.725799462, 6060585.837955164], [3849328.71788522, 6060598.03498192], [3849317.850609142, 6060593.57976506], [3849322.0855625975, 6060583.24800576]]]}, - "height_mean": 13.0790429485, + "height": 13.0790429485, "year_built": 2000 } } From 6be5325f75102b1e435076c72c68aa2bc37f9a53 Mon Sep 17 00:00:00 2001 From: guille Date: Mon, 21 Nov 2022 13:53:58 -0500 Subject: [PATCH 14/15] Correct unit tests due latest changes in gpandas handler. Partial rollback of some changes --- MACOS_INSTALL.md | 2 +- WINDOWS_INSTALL.md | 2 +- catalog_factories/greenery_catalog_factory.py | 2 +- exports/formats/obj.py | 2 +- imports/geometry/gpandas.py | 7 ++++--- imports/geometry_factory.py | 3 +-- unittests/test_city_merge.py | 2 +- unittests/test_construction_factory.py | 2 +- unittests/test_doe_idf.py | 2 +- unittests/test_energy_systems_air_source_hp.py | 2 +- unittests/test_energy_systems_water_to_water_hp.py | 2 +- unittests/test_enrichement.py | 2 +- unittests/test_exports.py | 2 +- unittests/test_geometry_factory.py | 8 ++++---- unittests/test_greenery_catalog.py | 2 +- unittests/test_greenery_in_idf.py | 4 ++-- unittests/test_life_cycle_assessment_factory.py | 8 ++++---- unittests/test_schedules_factory.py | 2 +- unittests/test_usage_factory.py | 2 +- 19 files changed, 29 insertions(+), 29 deletions(-) diff --git a/MACOS_INSTALL.md b/MACOS_INSTALL.md index 1432ac1e..caccd92e 100644 --- a/MACOS_INSTALL.md +++ b/MACOS_INSTALL.md @@ -164,7 +164,7 @@ When all the dependencies are satisfied, you are all set to start importing your Add the following code to your main.py from imports.geometry_factory import GeometryFactory -city = GeometryFactory('citygml', 'myfile.gml').city +city = GeometryFactory('citygml', path='myfile.gml').city Always remember to push your own project changes as the last thing you do before ending your working day! First, commit your changes by clicking on the green check in the top-right corner of Pycharm. Add a comment diff --git a/WINDOWS_INSTALL.md b/WINDOWS_INSTALL.md index d38e41ec..548497f5 100644 --- a/WINDOWS_INSTALL.md +++ b/WINDOWS_INSTALL.md @@ -237,7 +237,7 @@ Add the following code to your main.py from imports.geometry_factory import GeometryFactory -city = GeometryFactory('citygml', 'myfile.gml').city +city = GeometryFactory('citygml', path='myfile.gml').city ``` 9. Always remember to push your own project changes as the last thing you do before ending your working day! diff --git a/catalog_factories/greenery_catalog_factory.py b/catalog_factories/greenery_catalog_factory.py index f9284750..08864c41 100644 --- a/catalog_factories/greenery_catalog_factory.py +++ b/catalog_factories/greenery_catalog_factory.py @@ -12,7 +12,7 @@ Catalog = TypeVar('Catalog') class GreeneryCatalogFactory: """ - GeometryFactory class + GreeneryCatalogFactory class """ def __init__(self, file_type, base_path=None): if base_path is None: diff --git a/exports/formats/obj.py b/exports/formats/obj.py index bf1bee2b..f7237005 100644 --- a/exports/formats/obj.py +++ b/exports/formats/obj.py @@ -26,7 +26,7 @@ class Obj(Triangular): file_name_out = self._city.name + '_ground.' + self._triangular_format file_path_in = (Path(self._path).resolve() / file_name_in).resolve() file_path_out = (Path(self._path).resolve() / file_name_out).resolve() - scene = GeometryFactory('obj', file_path_in).scene + scene = GeometryFactory('obj', path=file_path_in).scene scene.rezero() obj_file = trimesh.exchange.obj.export_obj(scene) with open(file_path_out, 'w') as file: diff --git a/imports/geometry/gpandas.py b/imports/geometry/gpandas.py index d716c8cf..12fa4c95 100644 --- a/imports/geometry/gpandas.py +++ b/imports/geometry/gpandas.py @@ -40,6 +40,7 @@ class GPandas: self._scene = dataframe self._scene = self._scene.to_crs(self._srs_name) min_x, min_y, max_x, max_y = self._scene.total_bounds + print(min_x) self._lower_corner = [min_x, min_y, 0] self._upper_corner = [max_x, max_y, 0] @@ -58,10 +59,10 @@ class GPandas: if self._city is None: self._city = City(self._lower_corner, self._upper_corner, self._srs_name) for scene_index, bldg in self._scene.iterrows(): - geometry = bldg.geometry - # polygon = ShapelyPoly(geometry['coordinates'][0]) + geometry = bldg.geom + polygon = ShapelyPoly(geometry['coordinates'][0]) height = float(bldg['height']) - building_mesh = trimesh.creation.extrude_polygon(geometry, height) + building_mesh = trimesh.creation.extrude_polygon(polygon, height) trimesh.repair.fill_holes(building_mesh) trimesh.repair.fix_winding(building_mesh) year_of_construction = int(bldg['year_built']) diff --git a/imports/geometry_factory.py b/imports/geometry_factory.py index 51683847..22b8df8b 100644 --- a/imports/geometry_factory.py +++ b/imports/geometry_factory.py @@ -17,7 +17,7 @@ class GeometryFactory: """ GeometryFactory class """ - def __init__(self, file_type, path, data_frame=None): + def __init__(self, file_type, path=None, data_frame=None): self._file_type = '_' + file_type.lower() self._path = path self._data_frame = data_frame @@ -46,7 +46,6 @@ class GeometryFactory: """ if self._data_frame is None: self._data_frame = geopandas.read_file(self._path) - print( self._data_frame ) return GPandas(self._data_frame).city @property diff --git a/unittests/test_city_merge.py b/unittests/test_city_merge.py index e1ecaac9..3e087fa0 100644 --- a/unittests/test_city_merge.py +++ b/unittests/test_city_merge.py @@ -23,7 +23,7 @@ class TestCityMerge(TestCase): def _get_citygml(self, file): file_path = (self._example_path / file).resolve() - city = GeometryFactory('citygml', file_path).city + city = GeometryFactory('citygml', path=file_path).city self.assertIsNotNone(city, 'city is none') return city diff --git a/unittests/test_construction_factory.py b/unittests/test_construction_factory.py index 6ca15a2c..e6c6dd50 100644 --- a/unittests/test_construction_factory.py +++ b/unittests/test_construction_factory.py @@ -26,7 +26,7 @@ class TestConstructionFactory(TestCase): def _get_citygml(self, file): file_path = (self._example_path / file).resolve() - self._city = GeometryFactory('citygml', file_path).city + self._city = GeometryFactory('citygml', path=file_path).city self.assertIsNotNone(self._city, 'city is none') return self._city diff --git a/unittests/test_doe_idf.py b/unittests/test_doe_idf.py index b7eddcf7..0afb40b9 100644 --- a/unittests/test_doe_idf.py +++ b/unittests/test_doe_idf.py @@ -27,7 +27,7 @@ class TestBuildings(TestCase): def test_doe_idf(self): city_file = "../unittests/tests_data/one_building_in_kelowna.gml" output_path = Path('../unittests/tests_outputs/').resolve() - city = GeometryFactory('citygml', city_file).city + city = GeometryFactory('citygml', path=city_file).city for building in city.buildings: building.year_of_construction = 2006 ConstructionFactory('nrel', city).enrich() diff --git a/unittests/test_energy_systems_air_source_hp.py b/unittests/test_energy_systems_air_source_hp.py index 6f4edad8..ef06a648 100644 --- a/unittests/test_energy_systems_air_source_hp.py +++ b/unittests/test_energy_systems_air_source_hp.py @@ -25,7 +25,7 @@ class TestEnergySystemsFactory(TestCase): """ city_file = "../unittests/tests_data/C40_Final.gml" self._output_path = "../unittests/tests_data/as_user_output.csv" - self._city = GeometryFactory('citygml', city_file).city + self._city = GeometryFactory('citygml', path=city_file).city EnergySystemsFactory('air source hp', self._city).enrich() def test_air_source_heat_pump_import(self): diff --git a/unittests/test_energy_systems_water_to_water_hp.py b/unittests/test_energy_systems_water_to_water_hp.py index 889f9127..a455834a 100644 --- a/unittests/test_energy_systems_water_to_water_hp.py +++ b/unittests/test_energy_systems_water_to_water_hp.py @@ -26,7 +26,7 @@ class TestEnergySystemsFactory(TestCase): """ city_file = "../unittests/tests_data/C40_Final.gml" self._output_path = "../unittests/tests_data/w2w_user_output.csv" - self._city = GeometryFactory('citygml', city_file).city + self._city = GeometryFactory('citygml', path=city_file).city EnergySystemsFactory('water to water hp', self._city).enrich() def test_water_to_water_heat_pump_import(self): diff --git a/unittests/test_enrichement.py b/unittests/test_enrichement.py index 6ace72d4..4d8ac187 100644 --- a/unittests/test_enrichement.py +++ b/unittests/test_enrichement.py @@ -27,7 +27,7 @@ class TestGeometryFactory(TestCase): def _get_citygml(self, file): file_path = (self._example_path / file).resolve() - self._city = GeometryFactory('citygml', file_path).city + self._city = GeometryFactory('citygml', path=file_path).city self.assertIsNotNone(self._city, 'city is none') return self._city diff --git a/unittests/test_exports.py b/unittests/test_exports.py index 75dc96f0..c33fa715 100644 --- a/unittests/test_exports.py +++ b/unittests/test_exports.py @@ -34,7 +34,7 @@ class TestExports(TestCase): def _get_citygml(self, file): file_path = (self._example_path / file).resolve() - self._city = GeometryFactory('citygml', file_path).city + self._city = GeometryFactory('citygml', path=file_path).city self.assertIsNotNone(self._city, 'city is none') return self._city diff --git a/unittests/test_geometry_factory.py b/unittests/test_geometry_factory.py index dc6381d5..580fd207 100644 --- a/unittests/test_geometry_factory.py +++ b/unittests/test_geometry_factory.py @@ -30,7 +30,7 @@ class TestGeometryFactory(TestCase): def _get_citygml(self, file): file_path = (self._example_path / file).resolve() - self._city = GeometryFactory('citygml', file_path).city + self._city = GeometryFactory('citygml', path=file_path).city self.assertIsNotNone(self._city, 'city is none') return self._city @@ -43,13 +43,13 @@ class TestGeometryFactory(TestCase): def _get_obj(self, file): # todo: solve the incongruities between city and city_debug file_path = (self._example_path / file).resolve() - self._city = GeometryFactory('obj', file_path).city + self._city = GeometryFactory('obj', path=file_path).city self.assertIsNotNone(self._city, 'city is none') return self._city def _get_rhino(self, file): file_path = (self._example_path / file).resolve() - self._city = GeometryFactory('rhino', file_path).city + self._city = GeometryFactory('rhino', path=file_path).city self.assertIsNotNone(self._city, 'city is none') return self._city @@ -178,7 +178,7 @@ class TestGeometryFactory(TestCase): """ file_path = (self._example_path / 'subway.osm').resolve() - city = GeometryFactory('osm_subway', file_path).city + city = GeometryFactory('osm_subway', path=file_path).city self.assertIsNotNone(city, 'subway entrances is none') self.assertEqual(len(city.city_objects), 20, 'Wrong number of subway entrances') diff --git a/unittests/test_greenery_catalog.py b/unittests/test_greenery_catalog.py index 7959b127..efcde06e 100644 --- a/unittests/test_greenery_catalog.py +++ b/unittests/test_greenery_catalog.py @@ -1,5 +1,5 @@ """ -TestGeometryFactory test and validate the city model structure geometric parameters +Test greenery factory test and validate the greenery construction SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Concordia CERC group Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca diff --git a/unittests/test_greenery_in_idf.py b/unittests/test_greenery_in_idf.py index 216ea390..fe251329 100644 --- a/unittests/test_greenery_in_idf.py +++ b/unittests/test_greenery_in_idf.py @@ -27,7 +27,7 @@ class GreeneryInIdf(TestCase): city_file = "../unittests/tests_data/one_building_in_kelowna.gml" output_path = Path('../unittests/tests_outputs/').resolve() - city = GeometryFactory('citygml', city_file).city + city = GeometryFactory('citygml', path=city_file).city for building in city.buildings: building.year_of_construction = 2006 ConstructionFactory('nrel', city).enrich() @@ -80,7 +80,7 @@ class GreeneryInIdf(TestCase): print('With greenery') print(f'heating: {heating} MWh/yr, cooling: {cooling} MWh/yr') - city = GeometryFactory('citygml', city_file).city + city = GeometryFactory('citygml', path=city_file).city for building in city.buildings: building.year_of_construction = 2006 ConstructionFactory('nrel', city).enrich() diff --git a/unittests/test_life_cycle_assessment_factory.py b/unittests/test_life_cycle_assessment_factory.py index 43ba7feb..ef00cd79 100644 --- a/unittests/test_life_cycle_assessment_factory.py +++ b/unittests/test_life_cycle_assessment_factory.py @@ -24,28 +24,28 @@ class TestLifeCycleAssessment(TestCase): def test_fuel(self): city_file = "../unittests/tests_data/C40_Final.gml" - city = GeometryFactory('citygml', city_file).city + city = GeometryFactory('citygml', path=city_file).city LifeCycleAssessment('fuel', city).enrich() for fuel in city.fuels: self.assertTrue(len(city.fuels) > 0) def test_vehicle(self): city_file = "../unittests/tests_data/C40_Final.gml" - city = GeometryFactory('citygml', city_file).city + city = GeometryFactory('citygml', path=city_file).city LifeCycleAssessment('vehicle', city).enrich() for vehicle in city.vehicles: self.assertTrue(len(city.vehicles) > 0) def test_machine(self): city_file = "../unittests/tests_data/C40_Final.gml" - city = GeometryFactory('citygml', city_file).city + city = GeometryFactory('citygml', path=city_file).city LifeCycleAssessment('machine', city).enrich() for machine in city.machines: self.assertTrue(len(city.machines) > 0) def test_material(self): city_file = "../unittests/tests_data/C40_Final.gml" - city = GeometryFactory('citygml', city_file).city + city = GeometryFactory('citygml', path=city_file).city LifeCycleAssessment('material', city).enrich() for material in city.lca_materials: self.assertTrue(len(city.lca_materials) > 0) diff --git a/unittests/test_schedules_factory.py b/unittests/test_schedules_factory.py index 85a3c45d..3d7f5180 100644 --- a/unittests/test_schedules_factory.py +++ b/unittests/test_schedules_factory.py @@ -28,7 +28,7 @@ class TestSchedulesFactory(TestCase): def _get_citygml(self, file): file_path = (self._example_path / file).resolve() - _city = GeometryFactory('citygml', file_path).city + _city = GeometryFactory('citygml', path=file_path).city for building in _city.buildings: building.year_of_construction = 2006 ConstructionFactory('nrel', _city).enrich() diff --git a/unittests/test_usage_factory.py b/unittests/test_usage_factory.py index 15138579..f4feb04c 100644 --- a/unittests/test_usage_factory.py +++ b/unittests/test_usage_factory.py @@ -26,7 +26,7 @@ class TestUsageFactory(TestCase): def _get_citygml(self, file): file_path = (self._example_path / file).resolve() - self._city = GeometryFactory('citygml', file_path).city + self._city = GeometryFactory('citygml', path=file_path).city self.assertIsNotNone(self._city, 'city is none') return self._city From cfa424121351d16115b5dbbba0d69d8bb0dfb722 Mon Sep 17 00:00:00 2001 From: guille Date: Mon, 21 Nov 2022 14:00:12 -0500 Subject: [PATCH 15/15] rollback quick fix --- imports/construction/us_physics_parameters.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/imports/construction/us_physics_parameters.py b/imports/construction/us_physics_parameters.py index 657164bf..2baa6749 100644 --- a/imports/construction/us_physics_parameters.py +++ b/imports/construction/us_physics_parameters.py @@ -74,9 +74,7 @@ class UsPhysicsParameters(NrelPhysicsInterface): if (str(function) == str(building_archetype.function)) and \ (climate_zone == str(building_archetype.climate_zone)): return building_archetype - # Todo: line below is added by Milad as a quick fix for when archetypes search is not found - return building_archetype - # return None + return None @staticmethod def _search_construction_in_archetype(archetype, construction_type):