forked from s_ranjbar/city_retrofit
updating comments in classes for documentation
This commit is contained in:
parent
0218ea470d
commit
e4cf62b2ff
|
@ -29,7 +29,6 @@ class InternalGains:
|
|||
"""
|
||||
Set internal gains average internal gain in W/m2
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._average_internal_gain = value
|
||||
|
||||
|
@ -46,7 +45,6 @@ class InternalGains:
|
|||
"""
|
||||
Set internal gains convective fraction
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._convective_fraction = value
|
||||
|
||||
|
@ -63,7 +61,6 @@ class InternalGains:
|
|||
"""
|
||||
Set internal gains convective fraction
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._radiative_fraction = value
|
||||
|
||||
|
@ -80,6 +77,5 @@ class InternalGains:
|
|||
"""
|
||||
Set internal gains latent fraction
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._latent_fraction = value
|
||||
|
|
|
@ -18,6 +18,10 @@ class Layer:
|
|||
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
Get layer id, an universally unique identifier randomly generated
|
||||
:return: str
|
||||
"""
|
||||
if self._id is None:
|
||||
self._id = uuid.uuid4()
|
||||
return self._id
|
||||
|
@ -35,7 +39,6 @@ class Layer:
|
|||
"""
|
||||
Set layer material
|
||||
:param value: Material
|
||||
:return: None
|
||||
"""
|
||||
self._material = value
|
||||
|
||||
|
@ -52,6 +55,5 @@ class Layer:
|
|||
"""
|
||||
Get layer thickness in meters
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._thickness = value
|
||||
|
|
|
@ -33,7 +33,6 @@ class Material:
|
|||
"""
|
||||
Set material name
|
||||
:param value: string
|
||||
:return: None
|
||||
"""
|
||||
self._name = value
|
||||
|
||||
|
@ -50,7 +49,6 @@ class Material:
|
|||
"""
|
||||
Set material conductivity in W/mK
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._conductivity = value
|
||||
|
||||
|
@ -67,7 +65,6 @@ class Material:
|
|||
"""
|
||||
Get material conductivity in J/kgK
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._specific_heat = value
|
||||
|
||||
|
@ -84,7 +81,6 @@ class Material:
|
|||
"""
|
||||
Set material density in kg/m3
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._density = value
|
||||
|
||||
|
@ -101,7 +97,6 @@ class Material:
|
|||
"""
|
||||
Set material solar absorptance
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._solar_absorptance = value
|
||||
|
||||
|
@ -118,7 +113,6 @@ class Material:
|
|||
"""
|
||||
Set material thermal absorptance
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._thermal_absorptance = value
|
||||
|
||||
|
@ -135,7 +129,6 @@ class Material:
|
|||
"""
|
||||
Set material visible absorptance
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._visible_absorptance = value
|
||||
|
||||
|
@ -152,7 +145,6 @@ class Material:
|
|||
"""
|
||||
Set material no mass flag
|
||||
:param value: Boolean
|
||||
:return: None
|
||||
"""
|
||||
self._no_mass = value
|
||||
|
||||
|
@ -169,6 +161,5 @@ class Material:
|
|||
"""
|
||||
Set material thermal resistance in m2K/W
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._thermal_resistance = value
|
||||
|
|
|
@ -47,7 +47,6 @@ class Occupants:
|
|||
"""
|
||||
Set heat dissipation of occupants in W/person
|
||||
:param value: float
|
||||
:return:
|
||||
"""
|
||||
self._heat_dissipation = value
|
||||
|
||||
|
@ -64,7 +63,6 @@ class Occupants:
|
|||
"""
|
||||
Set rate of schedules
|
||||
:param value: float
|
||||
:return:
|
||||
"""
|
||||
self._occupancy_rate = value
|
||||
|
||||
|
@ -81,7 +79,6 @@ class Occupants:
|
|||
"""
|
||||
Set type of schedules
|
||||
:param value: float
|
||||
:return:
|
||||
"""
|
||||
self._occupant_type = value
|
||||
|
||||
|
@ -106,7 +103,6 @@ class Occupants:
|
|||
"""
|
||||
Set the schedules when an occupant is in a zone (24 values, 1 per hour of the day)
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
self._occupant_schedule = value
|
||||
|
||||
|
@ -123,7 +119,6 @@ class Occupants:
|
|||
"""
|
||||
Set the number of occupants
|
||||
:param value: int
|
||||
:return:
|
||||
"""
|
||||
self._number_of_occupants = value
|
||||
|
||||
|
@ -140,7 +135,6 @@ class Occupants:
|
|||
"""
|
||||
Set the arrival time of the occupant (for office building) in UTC with format YYYYMMDD HH:mm:ss
|
||||
:param value: time
|
||||
:return:
|
||||
"""
|
||||
self._arrival_time = value
|
||||
|
||||
|
@ -157,7 +151,6 @@ class Occupants:
|
|||
"""
|
||||
Set the departure time of the occupant (for office building) in UTC with format YYYYMMDD HH:mm:ss
|
||||
:param value: time
|
||||
:return:
|
||||
"""
|
||||
self._departure_time = value
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import List
|
||||
import sys
|
||||
import numpy as np
|
||||
import math
|
||||
|
@ -24,6 +26,7 @@ class Polygon:
|
|||
def points(self) -> np.ndarray:
|
||||
"""
|
||||
List of points belonging to the polygon [[x, y, z],...]
|
||||
:return: ndarray[coordinates]
|
||||
"""
|
||||
return self._points
|
||||
|
||||
|
@ -57,7 +60,7 @@ class Polygon:
|
|||
if alpha == 0:
|
||||
sys.stderr.write('Warning: the area of a line or point cannot be calculated 2. Area = 0\n')
|
||||
return 0
|
||||
horizontal_points = self.rotate_surface_to_horizontal
|
||||
horizontal_points = self._points_rotated_to_horizontal
|
||||
area = 0
|
||||
for i in range(0, len(horizontal_points)-1):
|
||||
point = horizontal_points[i]
|
||||
|
@ -70,7 +73,11 @@ class Polygon:
|
|||
return self._area
|
||||
|
||||
@property
|
||||
def rotate_surface_to_horizontal(self):
|
||||
def _points_rotated_to_horizontal(self):
|
||||
"""
|
||||
polygon points rotated to horizontal
|
||||
:return: [float]
|
||||
"""
|
||||
z_vector = [0, 0, 1]
|
||||
normal_vector = self.normal
|
||||
horizontal_points = []
|
||||
|
@ -121,7 +128,6 @@ class Polygon:
|
|||
cross_product = cross_product / np.linalg.norm(cross_product)
|
||||
alpha = self._angle_between_vectors(vector_1, vector_2)
|
||||
else:
|
||||
# todo modify here
|
||||
cross_product = [0, 0, 0]
|
||||
alpha = 0
|
||||
if len(points) == 3:
|
||||
|
@ -144,6 +150,13 @@ class Polygon:
|
|||
|
||||
@staticmethod
|
||||
def _angle(vector_1, vector_2, cross_product):
|
||||
"""
|
||||
alpha angle in radians
|
||||
:param vector_1: [float]
|
||||
:param vector_2: [float]
|
||||
:param cross_product: [float]
|
||||
:return: float
|
||||
"""
|
||||
accepted_normal_difference = 0.01
|
||||
cross_product_next = np.cross(vector_1, vector_2)
|
||||
if np.linalg.norm(cross_product_next) != 0:
|
||||
|
@ -160,7 +173,7 @@ class Polygon:
|
|||
else:
|
||||
return -alpha
|
||||
|
||||
def triangulate(self):
|
||||
def triangulate(self) -> List[Polygon]:
|
||||
"""
|
||||
triangulates a polygon following the ear clipping methodology
|
||||
:return: list[triangles]
|
||||
|
@ -169,6 +182,7 @@ class Polygon:
|
|||
# https://github.com/mikedh/trimesh/blob/dad11126742e140ef46ba12f8cb8643c83356467/trimesh/creation.py#L415,
|
||||
# it had a problem with a class called 'triangle', but, if solved,
|
||||
# it could be a very good substitute of this method
|
||||
# this method is very dirty and has an infinite loop solved with a counter!!
|
||||
points_list = self.points_list
|
||||
normal = self.normal
|
||||
if np.linalg.norm(normal) == 0:
|
||||
|
@ -223,7 +237,7 @@ class Polygon:
|
|||
return ears
|
||||
|
||||
@staticmethod
|
||||
def _starting_lists(points_list, normal):
|
||||
def _starting_lists(points_list, normal) -> [List[float], List[float], List[float]]:
|
||||
"""
|
||||
creates the list of vertices (points) that define the polygon (total_points_list), together with other two lists
|
||||
separating points between convex and concave
|
||||
|
@ -268,7 +282,7 @@ class Polygon:
|
|||
return total_points_list, concave_points, convex_points
|
||||
|
||||
@staticmethod
|
||||
def _triangle(points_list, total_points_list, point_position):
|
||||
def _triangle(points_list, total_points_list, point_position) -> Polygon:
|
||||
"""
|
||||
creates a triangular polygon out of three points
|
||||
:param points_list: points_list
|
||||
|
@ -367,7 +381,7 @@ class Polygon:
|
|||
|
||||
@staticmethod
|
||||
def _if_concave_change_status(normal, points_list, convex_point, total_points_list,
|
||||
concave_points, convex_points, point_in_list):
|
||||
concave_points, convex_points, point_in_list) -> [List[float], List[float], bool]:
|
||||
"""
|
||||
checks whether an convex specific point change its status to concave after removing one ear in the polygon
|
||||
returning the new convex and concave points lists together with a flag advising that the list of total points
|
||||
|
|
|
@ -4,6 +4,8 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
Contributors Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import List, Union
|
||||
import sys
|
||||
import numpy as np
|
||||
import math
|
||||
|
@ -33,6 +35,10 @@ class Polyhedron:
|
|||
self._min_x = None
|
||||
|
||||
def _position_of(self, point, face):
|
||||
"""
|
||||
position of a specific point in the list of points that define a face
|
||||
:return: int
|
||||
"""
|
||||
vertices = self.vertices
|
||||
for i in range(len(vertices)):
|
||||
# ensure not duplicated vertex
|
||||
|
@ -71,13 +77,11 @@ class Polyhedron:
|
|||
return self._vertices
|
||||
|
||||
@property
|
||||
def faces(self) -> [[int]]:
|
||||
|
||||
def faces(self) -> List[List[int]]:
|
||||
"""
|
||||
Polyhedron triangular faces
|
||||
:return: [[int]]
|
||||
:return: [face]
|
||||
"""
|
||||
|
||||
if self._faces is None:
|
||||
self._faces = []
|
||||
|
||||
|
@ -102,7 +106,11 @@ class Polyhedron:
|
|||
return self._faces
|
||||
|
||||
@property
|
||||
def trimesh(self) -> Trimesh:
|
||||
def trimesh(self) -> Union[Trimesh, None]:
|
||||
"""
|
||||
Get trimesh
|
||||
:return: Trimesh
|
||||
"""
|
||||
if self._trimesh is None:
|
||||
for face in self.faces:
|
||||
if len(face) != 3:
|
||||
|
@ -129,7 +137,7 @@ class Polyhedron:
|
|||
@property
|
||||
def max_z(self):
|
||||
"""
|
||||
Polyhedron maximal z value
|
||||
Polyhedron maximal z value in meters
|
||||
:return: float
|
||||
"""
|
||||
if self._max_z is None:
|
||||
|
@ -142,7 +150,7 @@ class Polyhedron:
|
|||
@property
|
||||
def max_y(self):
|
||||
"""
|
||||
Polyhedron maximal y value
|
||||
Polyhedron maximal y value in meters
|
||||
:return: float
|
||||
"""
|
||||
if self._max_y is None:
|
||||
|
@ -156,7 +164,7 @@ class Polyhedron:
|
|||
@property
|
||||
def max_x(self):
|
||||
"""
|
||||
Polyhedron maximal x value
|
||||
Polyhedron maximal x value in meters
|
||||
:return: float
|
||||
"""
|
||||
if self._max_x is None:
|
||||
|
@ -169,7 +177,7 @@ class Polyhedron:
|
|||
@property
|
||||
def min_z(self):
|
||||
"""
|
||||
Polyhedron minimal z value
|
||||
Polyhedron minimal z value in meters
|
||||
:return: float
|
||||
"""
|
||||
if self._min_z is None:
|
||||
|
@ -183,7 +191,7 @@ class Polyhedron:
|
|||
@property
|
||||
def min_y(self):
|
||||
"""
|
||||
Polyhedron minimal y value
|
||||
Polyhedron minimal y value in meters
|
||||
:return: float
|
||||
"""
|
||||
if self._min_y is None:
|
||||
|
@ -197,7 +205,7 @@ class Polyhedron:
|
|||
@property
|
||||
def min_x(self):
|
||||
"""
|
||||
Polyhedron minimal x value
|
||||
Polyhedron minimal x value in meters
|
||||
:return: float
|
||||
"""
|
||||
if self._min_x is None:
|
||||
|
|
|
@ -21,7 +21,7 @@ class PvSystem:
|
|||
def modules_mean_seasonal_efficiency(self):
|
||||
"""
|
||||
Get mean modules efficiency (-)
|
||||
:return: real
|
||||
:return: float
|
||||
"""
|
||||
return self._modules_mean_seasonal_efficiency
|
||||
|
||||
|
@ -29,7 +29,7 @@ class PvSystem:
|
|||
def modules_mean_seasonal_efficiency(self, value):
|
||||
"""
|
||||
Set mean modules efficiency (-)
|
||||
:param value: real
|
||||
:param value: float
|
||||
"""
|
||||
self._modules_mean_seasonal_efficiency = value
|
||||
|
||||
|
@ -37,7 +37,7 @@ class PvSystem:
|
|||
def total_area(self):
|
||||
"""
|
||||
Get total modules area (m2)
|
||||
:return: real
|
||||
:return: float
|
||||
"""
|
||||
return self._total_area
|
||||
|
||||
|
@ -45,7 +45,7 @@ class PvSystem:
|
|||
def total_area(self, value):
|
||||
"""
|
||||
Set total modules area (m2)
|
||||
:param value: real
|
||||
:param value: float
|
||||
"""
|
||||
self._total_area = value
|
||||
|
||||
|
@ -53,7 +53,7 @@ class PvSystem:
|
|||
def module_area(self):
|
||||
"""
|
||||
Get module area (m2)
|
||||
:return: real
|
||||
:return: float
|
||||
"""
|
||||
return self._module_area
|
||||
|
||||
|
@ -61,7 +61,7 @@ class PvSystem:
|
|||
def module_area(self, value):
|
||||
"""
|
||||
Set module area (m2)
|
||||
:param value: real
|
||||
:param value: float
|
||||
"""
|
||||
self._module_area = value
|
||||
|
||||
|
@ -85,7 +85,7 @@ class PvSystem:
|
|||
def overall_system_performance_ratio(self):
|
||||
"""
|
||||
Get overall system performance ratio (-)
|
||||
:return: real
|
||||
:return: float
|
||||
"""
|
||||
return self._overall_system_performance_ratio
|
||||
|
||||
|
@ -93,7 +93,7 @@ class PvSystem:
|
|||
def overall_system_performance_ratio(self, value):
|
||||
"""
|
||||
Set overall system performance ratio (-)
|
||||
:param value: real
|
||||
:param value: float
|
||||
"""
|
||||
self._overall_system_performance_ratio = value
|
||||
|
||||
|
@ -101,7 +101,7 @@ class PvSystem:
|
|||
def electricity_generation(self):
|
||||
"""
|
||||
Get electricity generation (J)
|
||||
:return: real
|
||||
:return: float
|
||||
"""
|
||||
return self._electricity_generation
|
||||
|
||||
|
@ -109,6 +109,6 @@ class PvSystem:
|
|||
def electricity_generation(self, value):
|
||||
"""
|
||||
Set electricity generation (J)
|
||||
:param value: real
|
||||
:param value: float
|
||||
"""
|
||||
self._electricity_generation = value
|
||||
|
|
|
@ -4,6 +4,8 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from helpers.location import Location
|
||||
|
||||
|
||||
class Sensor:
|
||||
"""
|
||||
|
@ -19,6 +21,7 @@ class Sensor:
|
|||
def name(self):
|
||||
"""
|
||||
Get sensor name
|
||||
:return: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
|
@ -26,6 +29,7 @@ class Sensor:
|
|||
def name(self, value):
|
||||
"""
|
||||
Set sensor name
|
||||
:param value: str
|
||||
"""
|
||||
self._name = value
|
||||
|
||||
|
@ -33,6 +37,7 @@ class Sensor:
|
|||
def type(self):
|
||||
"""
|
||||
Get sensor type
|
||||
:return: str
|
||||
"""
|
||||
return self._type
|
||||
|
||||
|
@ -40,13 +45,15 @@ class Sensor:
|
|||
def units(self):
|
||||
"""
|
||||
Get sensor units
|
||||
:return: str
|
||||
"""
|
||||
return self._units
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
def location(self) -> Location:
|
||||
"""
|
||||
Get sensor location
|
||||
:return: Location
|
||||
"""
|
||||
return self._location
|
||||
|
||||
|
@ -54,6 +61,7 @@ class Sensor:
|
|||
def location(self, value):
|
||||
"""
|
||||
Set sensor location
|
||||
:param value: Location
|
||||
"""
|
||||
self._location = value
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@ class Surface:
|
|||
self._area_above_ground = None
|
||||
self._area_below_ground = None
|
||||
self._parent = None
|
||||
self._bounds_lower_corner = None
|
||||
self._bounds_upper_corner = None
|
||||
self._lower_corner = None
|
||||
self._upper_corner = None
|
||||
self._shared_surfaces = []
|
||||
self._global_irradiance = dict()
|
||||
self._perimeter_polygon = perimeter_polygon
|
||||
|
@ -106,16 +106,24 @@ class Surface:
|
|||
return min_coordinate
|
||||
|
||||
@property
|
||||
def bounds_lower_corner(self):
|
||||
if self._bounds_lower_corner is None:
|
||||
self._bounds_lower_corner = [self._min_coord('x'), self._min_coord('y'), self._min_coord('z')]
|
||||
return self._bounds_lower_corner
|
||||
def lower_corner(self):
|
||||
"""
|
||||
Surface's lower corner [x, y, z]
|
||||
:return: [float]
|
||||
"""
|
||||
if self._lower_corner is None:
|
||||
self._lower_corner = [self._min_coord('x'), self._min_coord('y'), self._min_coord('z')]
|
||||
return self._lower_corner
|
||||
|
||||
@property
|
||||
def bounds_upper_corner(self):
|
||||
if self._bounds_upper_corner is None:
|
||||
self._bounds_upper_corner = [self._max_coord('x'), self._max_coord('y'), self._max_coord('z')]
|
||||
return self._bounds_upper_corner
|
||||
def upper_corner(self):
|
||||
"""
|
||||
Surface's upper corner [x, y, z]
|
||||
:return: [float]
|
||||
"""
|
||||
if self._upper_corner is None:
|
||||
self._upper_corner = [self._max_coord('x'), self._max_coord('y'), self._max_coord('z')]
|
||||
return self._upper_corner
|
||||
|
||||
@property
|
||||
def area_above_ground(self):
|
||||
|
@ -127,7 +135,7 @@ class Surface:
|
|||
self._area_above_ground = self.perimeter_polygon.area - self.area_below_ground
|
||||
return self._area_above_ground
|
||||
|
||||
# todo: to be implemented
|
||||
# todo: to be implemented when adding terrains
|
||||
@property
|
||||
def area_below_ground(self):
|
||||
"""
|
||||
|
|
|
@ -76,6 +76,7 @@ class ThermalBoundary:
|
|||
"""
|
||||
return self._surface.solid_polygon.area
|
||||
|
||||
# todo: shouldn't be these two attributes come from the associated surface???
|
||||
@property
|
||||
def area_above_ground(self):
|
||||
"""
|
||||
|
@ -105,7 +106,6 @@ class ThermalBoundary:
|
|||
"""
|
||||
Set thermal boundary outside solar absorptance
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._outside_solar_absorptance = value
|
||||
self._shortwave_reflectance = 1.0 - float(value)
|
||||
|
@ -123,7 +123,6 @@ class ThermalBoundary:
|
|||
"""
|
||||
Set thermal boundary outside thermal absorptance
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._outside_thermal_absorptance = value
|
||||
|
||||
|
@ -140,7 +139,6 @@ class ThermalBoundary:
|
|||
"""
|
||||
Set thermal boundary outside visible absorptance
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._outside_visible_absorptance = value
|
||||
|
||||
|
@ -157,7 +155,6 @@ class ThermalBoundary:
|
|||
"""
|
||||
Set thermal boundary thermal openings
|
||||
:param value: [ThermalOpening]
|
||||
:return: None
|
||||
"""
|
||||
self._thermal_openings = value
|
||||
|
||||
|
@ -165,12 +162,16 @@ class ThermalBoundary:
|
|||
def construction_name(self):
|
||||
"""
|
||||
Get construction name
|
||||
:return:
|
||||
:return: str
|
||||
"""
|
||||
return self._construction_name
|
||||
|
||||
@construction_name.setter
|
||||
def construction_name(self, value):
|
||||
"""
|
||||
Set construction name
|
||||
:param value: str
|
||||
"""
|
||||
self._construction_name = value
|
||||
|
||||
@property
|
||||
|
@ -186,7 +187,6 @@ class ThermalBoundary:
|
|||
"""
|
||||
Set thermal boundary layers
|
||||
:param value: [Layer]
|
||||
:return: None
|
||||
"""
|
||||
self._layers = value
|
||||
|
||||
|
@ -211,11 +211,10 @@ class ThermalBoundary:
|
|||
"""
|
||||
Set thermal boundary window ratio
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._window_ratio = value
|
||||
|
||||
# todo: what if I just want to assign a number??
|
||||
# todo: what if I just want to assign a number?? @Guille
|
||||
@property
|
||||
def u_value(self):
|
||||
"""
|
||||
|
@ -259,7 +258,6 @@ class ThermalBoundary:
|
|||
"""
|
||||
Set thermal boundary shortwave reflectance
|
||||
:param value: float
|
||||
:return:
|
||||
"""
|
||||
self._shortwave_reflectance = value
|
||||
self._outside_solar_absorptance = 1.0 - float(value)
|
||||
|
@ -277,7 +275,6 @@ class ThermalBoundary:
|
|||
"""
|
||||
Set internal convective heat transfer coefficient (W/m2K)
|
||||
:param value: internal convective heat transfer coefficient (W/m2K)
|
||||
:return:
|
||||
"""
|
||||
self._hi = value
|
||||
|
||||
|
@ -294,7 +291,6 @@ class ThermalBoundary:
|
|||
"""
|
||||
Set external convective heat transfer coefficient (W/m2K)
|
||||
:param value: external convective heat transfer coefficient (W/m2K)
|
||||
:return:
|
||||
"""
|
||||
self._he = value
|
||||
|
||||
|
|
|
@ -65,7 +65,6 @@ class ThermalOpening:
|
|||
"""
|
||||
Get thermal opening conductivity in W/mK
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
# The code to calculate overall_u_value is duplicated here and in thickness_m.
|
||||
# This ensures a more robust code that returns the overall_u_value regardless the order the parameters are read.
|
||||
|
@ -89,7 +88,6 @@ class ThermalOpening:
|
|||
"""
|
||||
Set thermal opening frame ratio
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._frame_ratio = value
|
||||
|
||||
|
@ -105,8 +103,7 @@ class ThermalOpening:
|
|||
def g_value(self, value):
|
||||
"""
|
||||
Set thermal opening g-value
|
||||
:param value:
|
||||
:return:
|
||||
:param value: float
|
||||
"""
|
||||
self._g_value = value
|
||||
|
||||
|
@ -114,7 +111,7 @@ class ThermalOpening:
|
|||
def thickness(self):
|
||||
"""
|
||||
Get thermal opening thickness in meters
|
||||
:return:
|
||||
:return: float
|
||||
"""
|
||||
return self._thickness
|
||||
|
||||
|
@ -123,7 +120,6 @@ class ThermalOpening:
|
|||
"""
|
||||
Set thermal opening thickness in meters
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
# The code to calculate overall_u_value is duplicated here and in conductivity.
|
||||
# This ensures a more robust code that returns the overall_u_value regardless the order the parameters are read.
|
||||
|
@ -147,7 +143,6 @@ class ThermalOpening:
|
|||
"""
|
||||
Set thermal opening front side solar transmittance at normal incidence
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._front_side_solar_transmittance_at_normal_incidence = value
|
||||
|
||||
|
@ -164,7 +159,6 @@ class ThermalOpening:
|
|||
"""
|
||||
Set thermal opening back side solar transmittance at normal incidence
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._back_side_solar_transmittance_at_normal_incidence = value
|
||||
|
||||
|
@ -181,7 +175,6 @@ class ThermalOpening:
|
|||
"""
|
||||
Get thermal opening overall U-value in W/m2K
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._overall_u_value = value
|
||||
|
||||
|
@ -198,7 +191,6 @@ class ThermalOpening:
|
|||
"""
|
||||
Set internal convective heat transfer coefficient (W/m2K)
|
||||
:param value: internal convective heat transfer coefficient (W/m2K)
|
||||
:return:
|
||||
"""
|
||||
self._hi = value
|
||||
|
||||
|
@ -215,7 +207,6 @@ class ThermalOpening:
|
|||
"""
|
||||
Set external convective heat transfer coefficient (W/m2K)
|
||||
:param value: external convective heat transfer coefficient (W/m2K)
|
||||
:return:
|
||||
"""
|
||||
self._he = value
|
||||
|
||||
|
|
|
@ -36,6 +36,10 @@ class ThermalZone:
|
|||
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
Get thermal zone id, an universally unique identifier randomly generated
|
||||
:return: str
|
||||
"""
|
||||
if self._id is None:
|
||||
self._id = uuid.uuid4()
|
||||
return self._id
|
||||
|
@ -52,7 +56,7 @@ class ThermalZone:
|
|||
def is_heated(self, value):
|
||||
"""
|
||||
Set thermal zone heated flag
|
||||
:return: Boolean
|
||||
:param value: Boolean
|
||||
"""
|
||||
self._is_heated = value
|
||||
|
||||
|
@ -68,7 +72,7 @@ class ThermalZone:
|
|||
def is_cooled(self, value):
|
||||
"""
|
||||
Set thermal zone cooled flag
|
||||
:return: Boolean
|
||||
:param value: Boolean
|
||||
"""
|
||||
self._is_cooled = value
|
||||
|
||||
|
@ -132,7 +136,6 @@ class ThermalZone:
|
|||
"""
|
||||
Set thermal zone additional thermal bridge u value W/m2K
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._additional_thermal_bridge_u_value = value
|
||||
|
||||
|
@ -149,7 +152,6 @@ class ThermalZone:
|
|||
"""
|
||||
Set thermal zone effective thermal capacity in J/m2K
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._effective_thermal_capacity = value
|
||||
|
||||
|
@ -166,7 +168,6 @@ class ThermalZone:
|
|||
"""
|
||||
Set thermal zone indirectly heated area ratio
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._indirectly_heated_area_ratio = value
|
||||
|
||||
|
@ -183,7 +184,6 @@ class ThermalZone:
|
|||
"""
|
||||
Set thermal zone infiltration rate system on in air changes per hour (ACH)
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._infiltration_rate_system_on = value
|
||||
|
||||
|
@ -200,7 +200,6 @@ class ThermalZone:
|
|||
"""
|
||||
Set thermal zone infiltration rate system on in air changes per hour (ACH)
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._infiltration_rate_system_off = value
|
||||
|
||||
|
@ -217,7 +216,6 @@ class ThermalZone:
|
|||
"""
|
||||
Set thermal zone usage zones
|
||||
:param values: [UsageZone]
|
||||
:return: None
|
||||
"""
|
||||
self._usage_zones = values
|
||||
|
||||
|
@ -234,7 +232,6 @@ class ThermalZone:
|
|||
"""
|
||||
Set thermal zone volume
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._volume = value
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
"""
|
||||
UsageZone module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Contributors Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
import uuid
|
||||
from typing import List, TypeVar
|
||||
|
||||
InternalGains = TypeVar('InternalGains')
|
||||
Lighting = TypeVar('Lighting')
|
||||
Occupants = TypeVar('Occupants')
|
||||
Polyhedron = TypeVar('Polyhedron')
|
||||
|
||||
|
@ -32,7 +31,6 @@ class UsageZone:
|
|||
self._electrical_app_average_consumption_sqm_year = None
|
||||
self._mechanical_air_change = None
|
||||
self._occupants = None
|
||||
self._lights = None
|
||||
self._heating_schedule = None
|
||||
self._cooling_schedule = None
|
||||
self._ventilation_schedule = None
|
||||
|
@ -41,14 +39,14 @@ class UsageZone:
|
|||
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
Get usage zone id, an universally unique identifier randomly generated
|
||||
:return: str
|
||||
"""
|
||||
if self._id is None:
|
||||
self._id = uuid.uuid4()
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def lights(self) -> List[Lighting]:
|
||||
return self._lights
|
||||
|
||||
@property
|
||||
def internal_gains(self) -> List[InternalGains]:
|
||||
"""
|
||||
|
@ -62,7 +60,6 @@ class UsageZone:
|
|||
"""
|
||||
Set usage zone internal gains
|
||||
:param value: [InternalGains]
|
||||
:return: None
|
||||
"""
|
||||
self._internal_gains = value
|
||||
|
||||
|
@ -79,7 +76,6 @@ class UsageZone:
|
|||
"""
|
||||
Set usage zone heating set point in celsius grads
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._heating_setpoint = value
|
||||
|
||||
|
@ -96,7 +92,6 @@ class UsageZone:
|
|||
"""
|
||||
Set usage zone heating setback in celsius grads
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._heating_setback = value
|
||||
|
||||
|
@ -113,7 +108,6 @@ class UsageZone:
|
|||
"""
|
||||
Set usage zone cooling setpoint in celsius grads
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._cooling_setpoint = value
|
||||
|
||||
|
@ -130,7 +124,6 @@ class UsageZone:
|
|||
"""
|
||||
Set usage zone usage hours per day
|
||||
:param value: float
|
||||
:return: float
|
||||
"""
|
||||
self._hours_day = value
|
||||
|
||||
|
@ -147,7 +140,6 @@ class UsageZone:
|
|||
"""
|
||||
Set usage zone usage days per year
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._days_year = value
|
||||
|
||||
|
@ -164,7 +156,6 @@ class UsageZone:
|
|||
"""
|
||||
Get usage zone mechanical air change in air change per hour (ACH)
|
||||
:param value: float
|
||||
:return: None
|
||||
"""
|
||||
self._mechanical_air_change = value
|
||||
|
||||
|
@ -181,12 +172,11 @@ class UsageZone:
|
|||
"""
|
||||
Get usage zone usage
|
||||
:param value: str
|
||||
:return: None
|
||||
"""
|
||||
self._usage = value
|
||||
|
||||
@property
|
||||
def occupants(self) -> [Occupants]:
|
||||
def occupants(self) -> List[Occupants]:
|
||||
"""
|
||||
Get occupants data
|
||||
:return: [Occupants]
|
||||
|
@ -202,7 +192,7 @@ class UsageZone:
|
|||
self._occupants = values
|
||||
|
||||
@property
|
||||
def heating_schedule(self):
|
||||
def heating_schedule(self) -> dict:
|
||||
"""
|
||||
Get heating schedules: list of 0, 1 that define whether the heating system should be OFF or ON
|
||||
:return: dict{DataFrame(int)}
|
||||
|
@ -218,7 +208,7 @@ class UsageZone:
|
|||
self._heating_schedule = values
|
||||
|
||||
@property
|
||||
def cooling_schedule(self):
|
||||
def cooling_schedule(self) -> dict:
|
||||
"""
|
||||
Get cooling schedules: list of 0, 1 that define whether the cooling system should be OFF or ON
|
||||
:return: dict{DataFrame(int)}
|
||||
|
@ -234,7 +224,7 @@ class UsageZone:
|
|||
self._cooling_schedule = values
|
||||
|
||||
@property
|
||||
def ventilation_schedule(self):
|
||||
def ventilation_schedule(self) -> dict:
|
||||
"""
|
||||
Get ventilation schedules: list of 0, 1 that define whether the ventilation system should be OFF or ON
|
||||
:return: dict{DataFrame(int)}
|
||||
|
@ -250,14 +240,18 @@ class UsageZone:
|
|||
self._ventilation_schedule = values
|
||||
|
||||
@property
|
||||
def schedules(self):
|
||||
def schedules(self) -> dict:
|
||||
"""
|
||||
Get schedules of diverse issues in a dictionary
|
||||
:return: dict()
|
||||
"""
|
||||
return self._schedules
|
||||
|
||||
@schedules.setter
|
||||
def schedules(self, values):
|
||||
"""
|
||||
Set schedules of diverse issues in a dictionary
|
||||
:param values: dict()
|
||||
"""
|
||||
self._schedules = values
|
||||
|
||||
|
|
|
@ -41,27 +41,27 @@ class Building(CityObject):
|
|||
self._cooling = dict()
|
||||
self._eave_height = None
|
||||
|
||||
self._grounds = []
|
||||
self._roofs = []
|
||||
self._walls = []
|
||||
self._internal_walls = []
|
||||
|
||||
self._thermal_zones = []
|
||||
zone_surfaces = None
|
||||
if zones_surfaces_ids is not None:
|
||||
for zone_surfaces_ids in zones_surfaces_ids:
|
||||
zone_surfaces = []
|
||||
for surface_id in zone_surfaces_ids:
|
||||
zone_surfaces.append(self.surface(surface_id))
|
||||
self._thermal_zones.append(ThermalZone(zone_surfaces))
|
||||
else:
|
||||
zone_surfaces = surfaces
|
||||
self._thermal_zones.append(ThermalZone(zone_surfaces))
|
||||
self._thermal_zones.append(ThermalZone(zone_surfaces))
|
||||
for t_zones in self._thermal_zones:
|
||||
t_zones.bounded = [ThermalBoundary(s, [t_zones]) for s in t_zones.surfaces]
|
||||
|
||||
self._grounds = []
|
||||
self._roofs = []
|
||||
self._walls = []
|
||||
self._internal_walls = []
|
||||
for surface_id, surface in enumerate(self.surfaces):
|
||||
self._min_x = min(self._min_x, surface.bounds_lower_corner[0])
|
||||
self._min_y = min(self._min_y, surface.bounds_lower_corner[1])
|
||||
self._min_z = min(self._min_z, surface.bounds_lower_corner[2])
|
||||
self._min_x = min(self._min_x, surface.lower_corner[0])
|
||||
self._min_y = min(self._min_y, surface.lower_corner[1])
|
||||
self._min_z = min(self._min_z, surface.lower_corner[2])
|
||||
surface.id = surface_id
|
||||
if surface.type == 'Ground':
|
||||
self._grounds.append(surface)
|
||||
|
@ -307,7 +307,7 @@ class Building(CityObject):
|
|||
if self._eave_height is None:
|
||||
self._eave_height = 0
|
||||
for wall in self.walls:
|
||||
self._eave_height = max(self._eave_height, wall.bounds_upper_corner[2])
|
||||
self._eave_height = max(self._eave_height, wall.upper_corner[2])
|
||||
return self._eave_height
|
||||
|
||||
@property
|
||||
|
|
|
@ -5,6 +5,9 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
"""
|
||||
|
||||
from city_model_structure.city_objects_cluster import CityObjectsCluster
|
||||
from typing import List, TypeVar
|
||||
|
||||
CityObject = TypeVar('CityObject')
|
||||
|
||||
|
||||
class BuildingsCluster(CityObjectsCluster):
|
||||
|
@ -19,8 +22,16 @@ class BuildingsCluster(CityObjectsCluster):
|
|||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
Cluster type
|
||||
:return: str
|
||||
"""
|
||||
return self._cluster_type
|
||||
|
||||
@property
|
||||
def city_objects(self):
|
||||
def city_objects(self) -> List[CityObject]:
|
||||
"""
|
||||
List of city objects conforming the cluster
|
||||
:return: [CityObject]
|
||||
"""
|
||||
return self._city_objects
|
||||
|
|
|
@ -6,7 +6,7 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
from __future__ import annotations
|
||||
import sys
|
||||
import pickle
|
||||
from typing import List, Union
|
||||
from typing import List, Union, TypeVar
|
||||
|
||||
import pyproj
|
||||
from pyproj import Transformer
|
||||
|
@ -20,6 +20,8 @@ from helpers.geometry_helper import GeometryHelper
|
|||
from helpers.location import Location
|
||||
import math
|
||||
|
||||
Path = TypeVar('Path')
|
||||
|
||||
|
||||
class City:
|
||||
"""
|
||||
|
@ -78,18 +80,34 @@ class City:
|
|||
|
||||
@property
|
||||
def climate_reference_city(self):
|
||||
"""
|
||||
Name of the city of reference for climatic information
|
||||
:return: str
|
||||
"""
|
||||
return self._climate_reference_city
|
||||
|
||||
@climate_reference_city.setter
|
||||
def climate_reference_city(self, value):
|
||||
"""
|
||||
Name of the city of reference for climatic information
|
||||
:param value: str
|
||||
"""
|
||||
self._climate_reference_city = value
|
||||
|
||||
@property
|
||||
def climate_file(self):
|
||||
def climate_file(self) -> Path:
|
||||
"""
|
||||
Full path of climate file
|
||||
:return: Path
|
||||
"""
|
||||
return self._climate_file
|
||||
|
||||
@climate_file.setter
|
||||
def climate_file(self, value):
|
||||
"""
|
||||
Full path of climate file
|
||||
:param value: Path
|
||||
"""
|
||||
self._climate_file = value
|
||||
|
||||
@property
|
||||
|
@ -171,7 +189,7 @@ class City:
|
|||
"""
|
||||
Add a CityObject to the city
|
||||
:param new_city_object:CityObject
|
||||
:return: None
|
||||
:return: None or not implemented error
|
||||
"""
|
||||
if new_city_object.type == 'building':
|
||||
if self._buildings is None:
|
||||
|
@ -230,7 +248,7 @@ class City:
|
|||
with open(city_filename, 'wb') as f:
|
||||
pickle.dump(self, f)
|
||||
|
||||
def region(self, center, radius):
|
||||
def region(self, center, radius) -> City:
|
||||
"""
|
||||
Save a city into the given filename
|
||||
:param center: specific point in space [x, y, z]
|
||||
|
@ -255,7 +273,7 @@ class City:
|
|||
def latitude(self):
|
||||
"""
|
||||
city latitude in degrees
|
||||
:return: real
|
||||
:return: float
|
||||
"""
|
||||
return self._latitude
|
||||
|
||||
|
@ -263,7 +281,7 @@ class City:
|
|||
def latitude(self, value):
|
||||
"""
|
||||
city latitude in degrees
|
||||
:parameter value: real
|
||||
:parameter value: float
|
||||
"""
|
||||
self._latitude = value
|
||||
|
||||
|
@ -271,7 +289,7 @@ class City:
|
|||
def longitude(self):
|
||||
"""
|
||||
city longitude in degrees
|
||||
:return: real
|
||||
:return: float
|
||||
"""
|
||||
return self._longitude
|
||||
|
||||
|
@ -279,7 +297,7 @@ class City:
|
|||
def longitude(self, value):
|
||||
"""
|
||||
city longitude in degrees
|
||||
:parameter value: real
|
||||
:parameter value: float
|
||||
"""
|
||||
self._longitude = value
|
||||
|
||||
|
@ -287,7 +305,7 @@ class City:
|
|||
def time_zone(self):
|
||||
"""
|
||||
city time_zone
|
||||
:return: real
|
||||
:return: float
|
||||
"""
|
||||
return self._time_zone
|
||||
|
||||
|
@ -295,7 +313,7 @@ class City:
|
|||
def time_zone(self, value):
|
||||
"""
|
||||
city time_zone
|
||||
:parameter value: real
|
||||
:parameter value: float
|
||||
"""
|
||||
self._time_zone = value
|
||||
|
||||
|
@ -333,7 +351,7 @@ class City:
|
|||
"""
|
||||
Add a CityObject to the city
|
||||
:param new_city_objects_cluster:CityObjectsCluster
|
||||
:return: None
|
||||
:return: None or NotImplementedError
|
||||
"""
|
||||
if new_city_objects_cluster.type == 'buildings':
|
||||
if self._buildings_clusters is None:
|
||||
|
|
|
@ -61,7 +61,7 @@ class CityObject:
|
|||
return self.detailed_polyhedron.volume
|
||||
|
||||
@property
|
||||
def detailed_polyhedron(self):
|
||||
def detailed_polyhedron(self) -> Polyhedron:
|
||||
"""
|
||||
City object polyhedron including details such as holes
|
||||
:return: Polyhedron
|
||||
|
@ -77,7 +77,7 @@ class CityObject:
|
|||
return self._detailed_polyhedron
|
||||
|
||||
@property
|
||||
def simplified_polyhedron(self):
|
||||
def simplified_polyhedron(self) -> Polyhedron:
|
||||
"""
|
||||
City object polyhedron, just the simple lod2 representation
|
||||
:return: Polyhedron
|
||||
|
|
|
@ -24,6 +24,10 @@ class CityObjectsCluster(ABC, CityObject):
|
|||
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Cluster name
|
||||
:return: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
|
@ -34,7 +38,11 @@ class CityObjectsCluster(ABC, CityObject):
|
|||
def city_objects(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def add_city_object(self, city_object):
|
||||
def add_city_object(self, city_object) -> List[CityObject]:
|
||||
"""
|
||||
add new object to the cluster
|
||||
:return: [CityObjects]
|
||||
"""
|
||||
if self._city_objects is None:
|
||||
self._city_objects = [city_object]
|
||||
else:
|
||||
|
|
|
@ -4,7 +4,9 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import List, TypeVar
|
||||
from city_model_structure.city_objects_cluster import CityObjectsCluster
|
||||
CityObject = TypeVar['CityObject']
|
||||
|
||||
|
||||
class PartsConsistingBuilding(CityObjectsCluster):
|
||||
|
@ -19,8 +21,16 @@ class PartsConsistingBuilding(CityObjectsCluster):
|
|||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
type of cluster
|
||||
:return: str
|
||||
"""
|
||||
return self._cluster_type
|
||||
|
||||
@property
|
||||
def city_objects(self):
|
||||
def city_objects(self) -> List[CityObject]:
|
||||
"""
|
||||
city objects that compose the cluster
|
||||
:return: [CityObject]
|
||||
"""
|
||||
return self._city_objects
|
||||
|
|
|
@ -212,10 +212,10 @@ class EnergyAde:
|
|||
'gml:boundedBy': {
|
||||
'gml:Envelope': {
|
||||
'@srsName': city.srs_name,
|
||||
'gml:lowerCorner': f'{surface.bounds_lower_corner[0]} {surface.bounds_lower_corner[1]}'
|
||||
f' {surface.bounds_lower_corner[2]}',
|
||||
'gml:upperCorner': f'{surface.bounds_upper_corner[0]} {surface.bounds_upper_corner[1]}'
|
||||
f' {surface.bounds_upper_corner[2]}'
|
||||
'gml:lowerCorner': f'{surface.lower_corner[0]} {surface.lower_corner[1]}'
|
||||
f' {surface.lower_corner[2]}',
|
||||
'gml:upperCorner': f'{surface.upper_corner[0]} {surface.upper_corner[1]}'
|
||||
f' {surface.upper_corner[2]}'
|
||||
}
|
||||
},
|
||||
'bldg:lod2MultiSurface': {
|
||||
|
|
|
@ -106,8 +106,8 @@ class TestGeometryFactory(TestCase):
|
|||
self.assertIsNotNone(surface.area_above_ground, 'surface area_above_ground is none')
|
||||
self.assertIsNotNone(surface.global_irradiance, 'monthly irradiance is none')
|
||||
self.assertIsNone(surface.swr, 'surface swr is not none')
|
||||
self.assertIsNotNone(surface.bounds_lower_corner, 'surface envelope_lower_corner is none')
|
||||
self.assertIsNotNone(surface.bounds_upper_corner, 'surface envelope_upper_corner is none')
|
||||
self.assertIsNotNone(surface.lower_corner, 'surface envelope_lower_corner is none')
|
||||
self.assertIsNotNone(surface.upper_corner, 'surface envelope_upper_corner is none')
|
||||
self.assertIsNotNone(surface.area_above_ground, 'surface area_above_ground is none')
|
||||
self.assertIsNotNone(surface.perimeter_polygon, 'surface perimeter_polygon is none')
|
||||
self.assertIsNone(surface.holes_polygons, 'surface hole_polygons is not none')
|
||||
|
|
Loading…
Reference in New Issue
Block a user