Files
old-krovovi-kalkulator/helix/Services/dxf_service.py
2017-11-07 09:23:57 +01:00

95 lines
3.7 KiB
Python

import io
import dxfgrabber
from helix.constants.file_validation_error import FileValidationMessage
from helix.models.dxf.dxf_error import OldDxfFormatException
class DXFService(object):
"""
Takes the contents of a DXF file and creates modules, buildings, panels,
subarrays, and polygons based on the data
"""
# l_b is expected to be in inches, not feet!
def parse(self, dxf_file_contents, module_constants, system_type, l_b, dxf_helper, subarray_validator):
"""Parse will generate the panels, subarrays, buildings
and modules that are present in the dxf file
Arguments:
dxf_file_contents (str) Content of the uploaded file
"""
dxf = dxfgrabber.read(io.StringIO(dxf_file_contents, newline=None))
buildings, modules = dxf_helper.build_polygons(dxf.entities)
"""
A new type of aurora format file was added in the project
The visibile difference if you read the file, is that the
new format contains the string buildings.
The old version doesn't
"""
pair_spacing = None
dxf_helper.is_new_aurora_format()
if hasattr(module_constants, "spacing_size_inches"):
pair_spacing = module_constants.spacing_size_inches
if dxf_helper.should_consolidate_modules(modules, system_type,
module_constants):
modules = dxf_helper.consolidate_dual_tilt_modules(modules,
system_type,
pair_spacing)
translated_buildings, translated_modules = dxf_helper.translate_towards_origin(buildings, modules)
translated_buildings_ccw = dxf_helper.get_polygons_counterclockwise(translated_buildings)
buildings_ccw = dxf_helper.get_polygons_counterclockwise(buildings)
panels = dxf_helper.generate_panels(modules, translated_modules)
node_graph = dxf_helper.build_node_graph(panels, module_constants.panel_spacing)
subarrays = dxf_helper.detect_subarrays(node_graph, panels)
for subarray in subarrays:
subarray_validator.validate_subarray(node_graph, subarray.subarray_number, system_type)
dxf_helper.detect_panel_types(node_graph)
dxf_helper.detect_wind_zones(panels, translated_buildings_ccw, translated_modules, l_b, system_type)
all_points = [p.points for p in translated_buildings_ccw + translated_modules]
points = [point for points_list in all_points for point in points_list]
max_x = max(p[0] for p in points)
max_y = max(p[1] for p in points)
panel_orientation = panels[0].coordinate.rotation
return {
'size': (max_x, max_y), # Used for debugging
'buildings': buildings_ccw,
'modules': translated_modules,
'panels': panels,
'subarrays': subarrays,
'lb_polygons': dxf_helper.l_b_polygons(translated_buildings_ccw, l_b, system_type, panel_orientation),
'is_panel_drawing_inaccurate': self.is_panel_drawing_inaccurate(panels)
}
def is_panel_drawing_inaccurate(self,panels):
'''True if subarrays are not rotated more than allowed tolerance, false otherwise'''
ROTATION_ACCURACY_DELTA_DEGREES = 0.1
if panels is None or panels == []:
return True
first_panel_rotation = panels[0].coordinate.rotation # rotation is in degrees
for panel in panels:
difference = abs(first_panel_rotation - panel.coordinate.rotation)
if difference >= ROTATION_ACCURACY_DELTA_DEGREES:
return True
return False