Files
old-krovovi-kalkulator/helix/presenters/panel_presenter.py
2017-12-24 23:35:11 +01:00

124 lines
4.8 KiB
Python

import sys
from math import sqrt, atan, degrees
from helix.models.corner import Corner
class ProjectPresenter(object):
def __init__(self, system_type, module_type):
self.offset = None
self.system_type = system_type
self.module_type = module_type
'''"This function expects coordinates to be in unit values, processed in coordinates_calculator.py" '''
def get_panel_data(self, panels, subarrays, max_y = None):
if self.offset is not None:
raise RuntimeError("ProjectPresenter panels must be computed before buildings")
table_data = []
system_constants = self.system_type.system_constants()
module_constants = self.system_type.module_constants(self.module_type)
spacing_x, spacing_y = module_constants.presenter_spacing
wind_zones = system_constants.wind_zones
for panel in panels:
subarray = [x for x in subarrays if x.subarray_number == panel.subarray][0]
origin = subarray.origin
table_data.append({
'x': (panel.coordinate.x + origin.x) * spacing_x,
'y': (panel.coordinate.y + origin.y) * spacing_y,
'width': spacing_x,
'height': spacing_y,
'data': {
'panel_id': panel.id,
'panel_type': panel.panel_type.number(),
'ballast': panel.ballast,
'wind_anchors': panel.wind_anchors,
'seismic_anchors': panel.seismic_anchors,
'wind_zones': wind_zones[panel.wind_zone],
'link_trays': panel.presented_link_tray,
'cross_trays': panel.cross_tray,
'psf': round(panel.pressure, 2),
'subarray': panel.subarray
}
})
# Move coordinates to reflect origin being at top-left
# (as per canvas) instead of bottom-left
height = max(map(lambda row: row['y'], table_data))
first_cell = min(map(lambda row: row['y'], table_data))
self.offset = height
for panel in table_data:
panel['y'] = height - panel['y'] + first_cell
return table_data
def get_buildings(self, buildings, max_y):
if self.offset is None:
self.offset = 0
module_constants = self.system_type.module_constants(self.module_type)
spacing_x, spacing_y = module_constants.presenter_spacing
# max_y = -sys.maxsize - 1 # for flipping the y coordinate
result = []
for building in buildings:
presentable_building = []
result.append(presentable_building)
# origin = self.find_origin(building)
for point in building:
point.x = point.x * spacing_x
point.y = abs((point.y * spacing_y - max_y))
presentable_building.append(point.__dict__)
return result
def get_corners(self, buildings):
result = []
for building in buildings:
presentable_building = []
result.append(presentable_building)
previous_corner = building[-1]
for i, corner in enumerate(building):
if (i+1 == len(building)):
next_corner = building[0]
else:
next_corner = building[i+1]
corner_length = sqrt((next_corner[0] - corner[0])**2 + (next_corner[1] - corner[1])**2)
k1 = (corner[1] - previous_corner[1]) / (corner[0] - previous_corner[0])
k2 = (next_corner[1] - corner[1]) / (next_corner[0] - corner[0])
theta1 = degrees(atan(k1))
theta2 = degrees(atan(k2))
theta1 = theta1 - theta2
if (theta1 < 0):
if (k1 < 0 and k2 < 0):
theta1 = 360 + theta1
elif (k1 < 0 and k2 > 0):
theta1 = 180 + theta1
else:
if (k1 > 0 and k2 > 0):
theta1 = 180 + theta1
corner_angle = theta1
presentable_building.append(Corner(corner[0], corner[1], corner_length, corner_angle).__dict__)
previous_corner = corner
return result
def get_max_y(self,buildings, panels):
module_constants = self.system_type.module_constants(self.module_type)
_, spacing_y = module_constants.presenter_spacing
all_y = []
if buildings is None or buildings == []: # no buildings in the file, probably CSV coordinates loaded
for panel in panels:
all_y.append(panel.coordinate.y)
for building in buildings:
for point in building:
all_y.append(point.y)
return max(all_y) * spacing_y