forked from s_ranjbar/city_retrofit
Add code comment to the classes and improve overall quality
This commit is contained in:
parent
de16e01677
commit
22dc10c532
|
@ -49,8 +49,8 @@ class CityObject:
|
|||
# for lod under 4 is just one thermal zone
|
||||
self._thermal_zones.append(ThermalZone(self.surfaces))
|
||||
|
||||
for t in self._thermal_zones:
|
||||
t.bounded = [ThermalBoundary(s, [t]) for s in t.surfaces]
|
||||
for t_zones in self._thermal_zones:
|
||||
t_zones.bounded = [ThermalBoundary(s, [t_zones]) for s in t_zones.surfaces]
|
||||
surface_id = 0
|
||||
for surface in self._surfaces:
|
||||
surface.lower_corner = self._lower_corner
|
||||
|
|
|
@ -24,7 +24,7 @@ class Polyhedron:
|
|||
|
||||
def _position_of(self, point):
|
||||
vertices = self.vertices
|
||||
for i in range(len(vertices)):
|
||||
for i in enumerate(vertices):
|
||||
if self._geometry.almost_equal(vertices[i], point):
|
||||
return i
|
||||
return -1
|
||||
|
@ -37,16 +37,16 @@ class Polyhedron:
|
|||
"""
|
||||
if self._vertices is None:
|
||||
vertices, self._vertices = [], []
|
||||
[vertices.extend(s.points) for s in self._surfaces]
|
||||
for v1 in vertices:
|
||||
_ = [vertices.extend(s.points) for s in self._surfaces]
|
||||
for vertex_1 in vertices:
|
||||
found = False
|
||||
for v2 in self._vertices:
|
||||
for vertex_2 in self._vertices:
|
||||
found = False
|
||||
if self._geometry.almost_equal(v1, v2):
|
||||
if self._geometry.almost_equal(vertex_1, vertex_2):
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
self._vertices.append(v1)
|
||||
self._vertices.append(vertex_1)
|
||||
self._vertices = np.asarray(self._vertices)
|
||||
return self._vertices
|
||||
|
||||
|
@ -58,11 +58,11 @@ class Polyhedron:
|
|||
"""
|
||||
if self._faces is None:
|
||||
self._faces = []
|
||||
for s in self._surfaces:
|
||||
for surface in self._surfaces:
|
||||
face = []
|
||||
points = s.points
|
||||
for p in points:
|
||||
face.append(self._position_of(p))
|
||||
points = surface.points
|
||||
for point in points:
|
||||
face.append(self._position_of(point))
|
||||
self._faces.append(face)
|
||||
self._faces = np.asarray(self._faces)
|
||||
return self._faces
|
||||
|
@ -71,9 +71,9 @@ class Polyhedron:
|
|||
def _polyhedron_mesh(self):
|
||||
if self._mesh is None:
|
||||
self._mesh = stl.mesh.Mesh(np.zeros(self.faces.shape[0], dtype=stl.mesh.Mesh.dtype))
|
||||
for i, f in enumerate(self.faces):
|
||||
for i, faces in enumerate(self.faces):
|
||||
for j in range(3):
|
||||
self._mesh.vectors[i][j] = self.vertices[f[j], :]
|
||||
self._mesh.vectors[i][j] = self.vertices[faces[j], :]
|
||||
return self._mesh
|
||||
|
||||
@property
|
||||
|
@ -83,7 +83,7 @@ class Polyhedron:
|
|||
:return: float
|
||||
"""
|
||||
if self._volume is None:
|
||||
self._volume, cog, inertia = self._polyhedron_mesh.get_mass_properties()
|
||||
self._volume, _, _ = self._polyhedron_mesh.get_mass_properties()
|
||||
return self._volume
|
||||
|
||||
@property
|
||||
|
|
|
@ -11,6 +11,9 @@ from typing import Union
|
|||
|
||||
|
||||
class Surface:
|
||||
"""
|
||||
Surface class
|
||||
"""
|
||||
def __init__(self, coordinates, surface_type=None, name=None, swr='0.2', remove_last=True, is_projected=False):
|
||||
self._coordinates = coordinates
|
||||
self._type = surface_type
|
||||
|
@ -42,25 +45,48 @@ class Surface:
|
|||
self._ground_coordinates = (self.min_x, self.min_y, self.min_z)
|
||||
|
||||
def parent(self, parent, surface_id):
|
||||
"""
|
||||
Assign a city object as surface parent and a surface id
|
||||
:param parent: CityObject
|
||||
:param surface_id: str
|
||||
:return: None
|
||||
"""
|
||||
self._parent = parent
|
||||
self._name = str(surface_id)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Surface name
|
||||
:return: str
|
||||
"""
|
||||
if self._name is None:
|
||||
raise Exception('surface has no name')
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def swr(self):
|
||||
"""
|
||||
Get surface short wave reflectance
|
||||
:return: float
|
||||
"""
|
||||
return self._swr
|
||||
|
||||
@swr.setter
|
||||
def swr(self, value):
|
||||
"""
|
||||
Set surface short wave reflectance
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._swr = value
|
||||
|
||||
@property
|
||||
def points(self) -> np.ndarray:
|
||||
"""
|
||||
Surface point matrix
|
||||
:return: np.ndarray
|
||||
"""
|
||||
if self._points is None:
|
||||
self._points = np.fromstring(self._coordinates, dtype=float, sep=' ')
|
||||
self._points = Geometry.to_points_matrix(self._points, self._remove_last)
|
||||
|
@ -83,24 +109,40 @@ class Surface:
|
|||
|
||||
@property
|
||||
def min_x(self):
|
||||
"""
|
||||
Surface minimal x value
|
||||
:return: float
|
||||
"""
|
||||
if self._min_x is None:
|
||||
self._min_x = self._min_coord('x')
|
||||
return self._min_x
|
||||
|
||||
@property
|
||||
def min_y(self):
|
||||
"""
|
||||
Surface minimal y value
|
||||
:return: float
|
||||
"""
|
||||
if self._min_y is None:
|
||||
self._min_y = self._min_coord('y')
|
||||
return self._min_y
|
||||
|
||||
@property
|
||||
def min_z(self):
|
||||
"""
|
||||
Surface minimal z value
|
||||
:return: float
|
||||
"""
|
||||
if self._min_z is None:
|
||||
self._min_z = self._min_coord('z')
|
||||
return self._min_z
|
||||
|
||||
@property
|
||||
def ground_points(self) -> np.ndarray:
|
||||
"""
|
||||
Surface grounded points matrix
|
||||
:return: np.ndarray
|
||||
"""
|
||||
if self._ground_points is None:
|
||||
coordinates = ''
|
||||
for point in self.points:
|
||||
|
@ -116,13 +158,21 @@ class Surface:
|
|||
|
||||
@property
|
||||
def points_list(self) -> np.ndarray:
|
||||
"""
|
||||
Surface point list
|
||||
:return: np.ndarray
|
||||
"""
|
||||
if self._points_list is None:
|
||||
s = self.points
|
||||
self._points_list = np.reshape(s, len(s) * 3)
|
||||
return self._points_list
|
||||
|
||||
@property
|
||||
def polygon(self) -> pn.Polygon:
|
||||
def polygon(self) -> Union[pn.Polygon, None]:
|
||||
"""
|
||||
Surface polygon
|
||||
:return: None or pyny3d.Polygon
|
||||
"""
|
||||
if self._polygon is None:
|
||||
try:
|
||||
self._polygon = pn.Polygon(self.points)
|
||||
|
@ -133,6 +183,10 @@ class Surface:
|
|||
|
||||
@property
|
||||
def ground_polygon(self) -> Union[pn.Polygon, None]:
|
||||
"""
|
||||
Surface grounded polygon
|
||||
:return: None or pyny3d.Polygon
|
||||
"""
|
||||
if self._ground_polygon is None:
|
||||
try:
|
||||
self._ground_polygon = pn.Polygon(self.ground_points)
|
||||
|
@ -143,6 +197,10 @@ class Surface:
|
|||
|
||||
@property
|
||||
def area(self):
|
||||
"""
|
||||
Surface area in square meters
|
||||
:return: float
|
||||
"""
|
||||
if self._area is None:
|
||||
self._area = self.polygon.get_area()
|
||||
return self._area
|
||||
|
@ -164,12 +222,20 @@ class Surface:
|
|||
|
||||
@property
|
||||
def area_above_ground(self):
|
||||
"""
|
||||
Surface area above ground in square meters
|
||||
:return: float
|
||||
"""
|
||||
if self._area_above_ground is None:
|
||||
self._area_above_ground = self.area - self.area_below_ground
|
||||
return self._area_above_ground
|
||||
|
||||
@property
|
||||
def area_below_ground(self):
|
||||
"""
|
||||
Surface area below ground in square meters
|
||||
:return: float
|
||||
"""
|
||||
if self._area_below_ground is None:
|
||||
self._area_below_ground = 0.0
|
||||
if self._is_terrain:
|
||||
|
@ -178,6 +244,10 @@ class Surface:
|
|||
|
||||
@property
|
||||
def normal(self) -> np.ndarray:
|
||||
"""
|
||||
Surface normal vector
|
||||
:return: np.ndarray
|
||||
"""
|
||||
if self._normal is None:
|
||||
points = self.points
|
||||
n = np.cross(points[1] - points[0], points[2] - points[0])
|
||||
|
@ -186,6 +256,10 @@ class Surface:
|
|||
|
||||
@property
|
||||
def azimuth(self):
|
||||
"""
|
||||
Surface azimuth in radians
|
||||
:return: float
|
||||
"""
|
||||
if self._azimuth is None:
|
||||
normal = self.normal
|
||||
self._azimuth = np.arctan2(normal[1], normal[0])
|
||||
|
@ -193,12 +267,20 @@ class Surface:
|
|||
|
||||
@property
|
||||
def inclination(self):
|
||||
"""
|
||||
Surface inclination in radians
|
||||
:return: float
|
||||
"""
|
||||
if self._inclination is None:
|
||||
self._inclination = np.arccos(self.normal[2])
|
||||
return self._inclination
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
Surface type Ground, Wall or Roof
|
||||
:return: str
|
||||
"""
|
||||
if self._type is None:
|
||||
grad = np.rad2deg(self.inclination)
|
||||
if 170 <= grad:
|
||||
|
@ -210,36 +292,68 @@ class Surface:
|
|||
return self._type
|
||||
|
||||
def add_shared(self, surface, intersection_area):
|
||||
"""
|
||||
Add a given surface and shared area in percent to this surface.
|
||||
:param surface:
|
||||
:param intersection_area:
|
||||
:return:
|
||||
"""
|
||||
percent = intersection_area / self.area
|
||||
self._shared_surfaces.append((percent, surface))
|
||||
|
||||
def shared(self, surface):
|
||||
"""
|
||||
Check if given surface share some area with this surface
|
||||
:param surface: Surface
|
||||
:return: None
|
||||
"""
|
||||
if self.type is not 'Wall' or surface.type is not 'Wall':
|
||||
return
|
||||
if self._geometry.is_almost_same_surface(self, surface):
|
||||
intersection_area = self.intersect(surface).area
|
||||
percent = intersection_area / self.area
|
||||
self._shared_surfaces.append((percent, surface))
|
||||
self.add_shared(surface, intersection_area)
|
||||
surface.add_shared(self, intersection_area)
|
||||
|
||||
@property
|
||||
def global_irradiance_hour(self):
|
||||
"""
|
||||
Get surface global irradiance hour in Wh/m2
|
||||
:return: float
|
||||
"""
|
||||
return self._global_irradiance_hour
|
||||
|
||||
@global_irradiance_hour.setter
|
||||
def global_irradiance_hour(self, value):
|
||||
"""
|
||||
Set surface global irradiance per hour in Wh/m2
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._global_irradiance_hour = value
|
||||
|
||||
@property
|
||||
def global_irradiance_month(self):
|
||||
"""
|
||||
Get surface global irradiance per month in Wh/m2
|
||||
:return: float
|
||||
"""
|
||||
return self._global_irradiance_month
|
||||
|
||||
@global_irradiance_month.setter
|
||||
def global_irradiance_month(self, value):
|
||||
"""
|
||||
Set surface global irradiance per month in Wh/m2
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._global_irradiance_month = value
|
||||
|
||||
@property
|
||||
def shapely(self):
|
||||
def shapely(self) -> Union[None, pn.Polygon]:
|
||||
"""
|
||||
Surface shapely (Z projection)
|
||||
:return: None or pyny3d.Polygon
|
||||
"""
|
||||
if self.polygon is None:
|
||||
return None
|
||||
if self._shapely is None:
|
||||
|
@ -247,7 +361,7 @@ class Surface:
|
|||
return self._shapely
|
||||
|
||||
@staticmethod
|
||||
def _polygon_to_surface(polygon):
|
||||
def _polygon_to_surface(polygon) -> Surface:
|
||||
coordinates = ''
|
||||
for coordinate in polygon.exterior.coords:
|
||||
if coordinates != '':
|
||||
|
@ -257,6 +371,10 @@ class Surface:
|
|||
|
||||
@property
|
||||
def projection(self) -> Surface:
|
||||
"""
|
||||
Projected surface (Z projection)
|
||||
:return: Surface
|
||||
"""
|
||||
if self._is_projected:
|
||||
return self
|
||||
if self._projected_surface is None:
|
||||
|
@ -264,6 +382,11 @@ class Surface:
|
|||
return self._projected_surface
|
||||
|
||||
def intersect(self, surface) -> Union[Surface, None]:
|
||||
"""
|
||||
Get the intersection surface, if any, between the given surface and this surface
|
||||
:param surface: Surface
|
||||
:return: None or Surface
|
||||
"""
|
||||
min_x = min(self.min_x, surface.min_x)
|
||||
min_y = min(self.min_y, surface.min_y)
|
||||
min_z = min(self.min_z, surface.min_z)
|
||||
|
|
|
@ -47,7 +47,7 @@ class ThermalZone:
|
|||
@property
|
||||
def floor_area(self):
|
||||
"""
|
||||
Get thermal zone floor area in m2
|
||||
Get thermal zone floor area in square meters
|
||||
:return: float
|
||||
"""
|
||||
if self._floor_area is None:
|
||||
|
|
|
@ -8,6 +8,9 @@ from typing import List
|
|||
|
||||
|
||||
class UsageZone:
|
||||
"""
|
||||
UsageZone class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._usage = None
|
||||
self._internal_gains = None
|
||||
|
@ -20,14 +23,27 @@ class UsageZone:
|
|||
|
||||
@property
|
||||
def internal_gains(self) -> List[InternalGains]:
|
||||
"""
|
||||
Get usage zone internal gains
|
||||
:return: [InternalGains]
|
||||
"""
|
||||
return self._internal_gains
|
||||
|
||||
@internal_gains.setter
|
||||
def internal_gains(self, value):
|
||||
"""
|
||||
Set usage zone internal gains
|
||||
:param value: [InternalGains]
|
||||
:return: None
|
||||
"""
|
||||
self._internal_gains = value
|
||||
|
||||
@property
|
||||
def heating_setpoint(self):
|
||||
"""
|
||||
|
||||
:return:
|
||||
"""
|
||||
return self._heating_setpoint
|
||||
|
||||
@heating_setpoint.setter
|
||||
|
|
Loading…
Reference in New Issue
Block a user