diff --git a/Export/exportDXF.py b/Export/exportDXF.py index 1dbad34..68f4b6f 100644 --- a/Export/exportDXF.py +++ b/Export/exportDXF.py @@ -1,5 +1,6 @@ import math import FreeCAD +import Part from Utils.PVPlantUtils import findObjects if FreeCAD.GuiUp: @@ -259,15 +260,60 @@ class exportDXF: 'rotation': rotation }) - def createPolyline(self, wire): + def createPolyline(self, wire, layer=""): try: data = getWire(wire.Shape) lwp = self.msp.add_lwpolyline(data) + if layer: + lwp.dxf.layer = layer return lwp except Exception as e: print("Error creating polyline:", e) return None + def createHatch(self, wire, pattern="SOLID", scale=1.0, angle=0, layer=None): + """Crea un sombreado (hatch) para un área""" + try: + # Obtener los puntos en metros + points = [(x, y) for (x, y, *_) in wire] + + # Crear el hatch + hatch = self.msp.add_hatch(color=7, dxfattribs={'layer': layer}) + + if pattern == "SOLID": + # Sombreado sólido + hatch.set_solid_fill() + else: + # Patrón de sombreado + hatch.set_pattern_fill(name=pattern, scale=scale, angle=angle) + + # Añadir el contorno + hatch.paths.add_polyline_path(points, is_closed=True) + return hatch + except Exception as e: + print("Error creating hatch:", e) + return None + + def export_feature_image(self, feature, layer_name): + """Exporta una imagen del GeoFeature y la añade al DXF""" + try: + # Añadir la imagen al DXF + image_def = self.doc.add_image_def(feature.ImageFile, size_in_pixel=(feature.XSize, feature.YSize)) + self.msp.add_image(image_def, + insert=(0, 0, 0), + size_in_units=(feature.XSize, + feature.YSize), + rotation=0, + dxfattribs={'layer': layer_name}) + + print(f"Imagen exportada para {feature.Label}") + + # Eliminar el archivo temporal + import os + os.unlink(temp_img.name) + except Exception as e: + print(f"Error en exportación de imagen: {e}") + # ================================================================================= # INTERFAZ DE USUARIO # ================================================================================= @@ -575,6 +621,58 @@ class LineTypeComboBox(QtWidgets.QComboBox): finally: painter.end() # Asegurar que el painter se cierre correctamente +layers = [ + ("Available area", QtGui.QColor(0, 204, 153), "Continuous", "1", True), + ("Available area Names", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + + ("Areas Exclusion", QtGui.QColor(255, 85, 0), "Continuous", "1", True), + ("Areas Exclusion Name", QtGui.QColor(255, 85, 0), "Continuous", "1", True), + ("Areas Cadastral Plot", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("Areas Cadastral Plot Name", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("Areas Offset", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + + ("Cable codes LV AC inverter", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("Cable codes LV string", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("Cable codes MV System", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("CABLES LV AC inverter 120 mm2", QtGui.QColor(255, 204, 0), "Continuous", "1", True), + ("CABLES LV AC inverter 185 mm2", QtGui.QColor(204, 153, 0), "Continuous", "1", True), + ("CABLES LV string 4 mm2", QtGui.QColor(255, 255, 0), "Continuous", "1", True), + ("CABLES LV string 10 mm2", QtGui.QColor(255, 255, 102), "Continuous", "1", True), + ("CABLES MV system 300 mm2", QtGui.QColor(102, 51, 0), "Continuous", "1", True), + + ("CIVIL Fence", QtGui.QColor(102, 102, 102), "FENCELINE1", "1", True), + ("CIVIL External Roads", QtGui.QColor(91, 91, 91), "Continuous", "1", True), + ("CIVIL External Roads Axis", QtGui.QColor(255, 255, 192), "Dashed", "1", True), + ("CIVIL External Roads Text", QtGui.QColor(255, 255, 192), "Continuous", "1", True), + ("CIVIL Internal Roads", QtGui.QColor(153, 95, 76), "Continuous", "1", True), + ("CIVIL Internal Roads Axis", QtGui.QColor(192, 192, 192), "Dashed", "1", True), + ("CIVIL External Roads Text", QtGui.QColor(192, 192, 192), "Continuous", "1", True), + + ("Contour Line Legend text", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("Major contour line", QtGui.QColor(0, 0, 0), "Continuous", "1", True), + ("Major contour value", QtGui.QColor(0, 0, 0), "Continuous", "1", True), + ("Minor contour line", QtGui.QColor(128, 128, 128), "Continuous", "1", True), + ("Minor contour value", QtGui.QColor(128, 128, 128), "Continuous", "1", True), + ("Power Stations", QtGui.QColor(255, 0, 0), "Continuous", "1", True), + ("Power Stations Names", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("ST", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("ST Names", QtGui.QColor(255, 255, 0), "Continuous", "1", True), + ("String Inv", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("STRUC Structure 1", QtGui.QColor(0, 0, 255), "Continuous", "1", True), + ("STRUC Structure 2", QtGui.QColor(0, 0, 204), "Continuous", "1", True), + ("STRUC Structure 3", QtGui.QColor(0, 0, 153), "Continuous", "1", True), + ("STRUC Structure 4", QtGui.QColor(0, 0, 128), "Continuous", "1", True), + ("STRUC Structure 5", QtGui.QColor(0, 0, 102), "Continuous", "1", True), + ("STRUC Structure 6", QtGui.QColor(0, 0, 76), "Continuous", "1", True), + ("STRUC Structure 7", QtGui.QColor(0, 0, 51), "Continuous", "1", True), + ("STRUC Structure 8", QtGui.QColor(0, 0, 25), "Continuous", "1", True), + ("Structure Codes", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("TRENCHES Low voltage 400.0 x 1000.0 m", QtGui.QColor(128, 128, 128), "Continuous", "1", True), + ("TRENCHES Medium voltage 400.0 x 1000.", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("TRENCHES Medium voltage 800.0 x 1000.", QtGui.QColor(255, 255, 255), "Continuous", "1", True), + ("TRENCHES Medium voltage 800.0 x 1500.", QtGui.QColor(255, 255, 255), "Continuous", "1", True), +] + class _PVPlantExportDXF(QtGui.QWidget): '''The editmode TaskPanel to select what you want to export''' @@ -610,10 +708,8 @@ class _PVPlantExportDXF(QtGui.QWidget): self.form.tableLayers.removeRow(row) # Configuración de las capas por defecto - self.add_row("Areas_Boundary", QtGui.QColor(0, 125, 125), "FENCELINE1", "1", True) - self.add_row("Areas_Exclusion", QtGui.QColor(255, 0, 0), "CONTINUOUS", "1", True) - self.add_row("Internal_Roads", QtGui.QColor(128, 128, 128), "CONTINUOUS", "1", True) - self.add_row("Frames", QtGui.QColor(0, 255, 0), "CONTINUOUS", "1", True) + for row in layers: + self.add_row(*row) def save_project_settings(self): """Guarda la configuración actual en el proyecto de FreeCAD""" @@ -778,25 +874,25 @@ class _PVPlantExportDXF(QtGui.QWidget): ) def writeArea(self, exporter): - exporter.createPolyline(FreeCAD.ActiveDocument.Site.Boundary, "boundary") - - areas_types = ["Boundaries", "Exclusions", "Offsets"] + exporter.createPolyline(FreeCAD.ActiveDocument.Site.Boundary, "Available area") + areas_types = [("Boundaries", "Available area"), + ("CadastralPlots", "Areas Cadastral Plot"), + ("Exclusions", "Areas Exclusion"), + ("Offsets", "Areas Offset")] for area_type in areas_types: - if hasattr(FreeCAD.ActiveDocument, area_type): - for area in FreeCAD.ActiveDocument.Boundaries.Group: - exporter.createPolyline(area, "Areas_Boundary") - - '''for area in FreeCAD.ActiveDocument.Boundaries.Group: - pol = exporter.createPolyline(area) - pol.dxf.layer = "Areas_Boundary" - - for area in FreeCAD.ActiveDocument.Exclusions.Group: - pol = exporter.createPolyline(area) - pol.dxf.layer = "Areas_Exclusion" - - for area in FreeCAD.ActiveDocument.Offsets.Group: - pol = exporter.createPolyline(area) - pol.dxf.layer = "Areas_Offsets"''' + if hasattr(FreeCAD.ActiveDocument, area_type[0]): + area_group = FreeCAD.ActiveDocument.getObjectsByLabel(area_type[0]) + if len(area_group): + for area in area_group[0].Group: + tmp = exporter.createPolyline(area, area_type[1]) + if area_type[0] == "Exclusions": + exporter.createHatch( + tmp, + pattern="ANSI37", + scale=0.3, + angle=0, + layer=area_type[1] + ) def writeFrameSetups(self, exporter): if not hasattr(FreeCAD.ActiveDocument, "Site"): @@ -811,11 +907,11 @@ class _PVPlantExportDXF(QtGui.QWidget): w.Placement.Base = w.Placement.Base.sub(center) block.add_lwpolyline(getWire(w)) - block.add_circle((0, 0), 0.2, dxfattribs={'color': 2}) + block.add_circle((0, 0), 0.2, dxfattribs={'layer': 'Structure Posts'}) #'color': 2, p = math.sin(math.radians(45)) * 0.2 - block.add_line((-p, -p), (p, p), dxfattribs={"layer": "MyLines"}) - block.add_line((-p, p), (p, -p), dxfattribs={"layer": "MyLines"}) + block.add_line((-p, -p), (p, p), dxfattribs={'layer': 'Structure Posts'}) + block.add_line((-p, p), (p, -p), dxfattribs={'layer': 'Structure Posts'}) # 2. Frames for ts in FreeCAD.ActiveDocument.Site.Frames: @@ -868,10 +964,10 @@ class _PVPlantExportDXF(QtGui.QWidget): if FreeCAD.ActiveDocument.Transport: for road in FreeCAD.ActiveDocument.Transport.Group: - base = exporter.createPolyline(road, "External_Roads") + base = exporter.createPolyline(road, "CIVIL External Roads") base.dxf.const_width = road.Width - axis = exporter.createPolyline(road.Base, "External_Roads_Axis") + axis = exporter.createPolyline(road, "CIVIL External Roads Axis") axis.dxf.const_width = .2 def writeTrenches(self, exporter): @@ -976,8 +1072,12 @@ class _PVPlantExportDXF(QtGui.QWidget): self.writeTrenches(exporter) # Crear espacios de papel - self.setup_layout4(exporter.doc) - self.createPaperSpaces(exporter) + #self.setup_layout4(exporter.doc) + #self.createPaperSpaces(exporter) + + if hasattr(FreeCAD.ActiveDocument, "Background"): + # Exportar como imagen en lugar de polilínea + exporter.export_feature_image(FreeCAD.ActiveDocument.Background, "Site_Image") # Guardar archivo exporter.save() diff --git a/Importer/importOSM.py b/Importer/importOSM.py index 024716b..fe5c5a9 100644 --- a/Importer/importOSM.py +++ b/Importer/importOSM.py @@ -42,11 +42,10 @@ class OSMImporter: } self.ssl_context = ssl.create_default_context(cafile=certifi.where()) - def transform_from_latlon(self, lat, lon): - point = ImportElevation.getElevationFromOE([[lat, lon], ]) - return FreeCAD.Vector(point[0].x, point[0].y, point[0].z) * scale - self.Origin - '''x, y, _, _ = utm.from_latlon(lat, lon) - return FreeCAD.Vector(x, y, .0) * scale - self.Origin''' + def transform_from_latlon(self, coordinates): + points = ImportElevation.getElevationFromOE(coordinates) + pts = [FreeCAD.Vector(p.x, p.y, p.z).sub(self.Origin) for p in points] + return pts def get_osm_data(self, bbox): query = f""" @@ -81,11 +80,16 @@ class OSMImporter: root = ET.fromstring(osm_data) # Almacenar nodos transformados + coordinates = [[float(node.attrib['lat']), float(node.attrib['lon'])] for node in root.findall('node')] + coordinates = self.transform_from_latlon(coordinates) + for i, node in enumerate(root.findall('node')): + self. nodes[node.attrib['id']] = coordinates[i] + '''return for node in root.findall('node'): self.nodes[node.attrib['id']] = self.transform_from_latlon( float(node.attrib['lat']), float(node.attrib['lon']) - ) + )''' # Procesar ways for way in root.findall('way'): @@ -162,11 +166,10 @@ class OSMImporter: def create_buildings(self): building_layer = self.create_layer("Buildings") for way_id, data in self.ways_data.items(): + print(data) if 'building' not in data['tags']: continue - print(data) - tags = data['tags'] nodes = [self.nodes[ref] for ref in data['nodes'] if ref in self.nodes] diff --git a/PVPlantFence.py b/PVPlantFence.py index f78ab6e..6cef531 100644 --- a/PVPlantFence.py +++ b/PVPlantFence.py @@ -376,8 +376,7 @@ class _Fence(ArchComponent.Component): site = PVPlantSite.get() if True: # prueba import MeshPart as mp - land = FreeCAD.ActiveDocument.Terrain.Mesh - segments = mp.projectShapeOnMesh(pathwire, land, FreeCAD.Vector(0, 0, 1)) + segments = mp.projectShapeOnMesh(pathwire, site.Terrain.Mesh, FreeCAD.Vector(0, 0, 1)) points=[] for segment in segments: points.extend(segment) diff --git a/PVPlantFenceGate.py b/PVPlantFenceGate.py index ae57455..a468913 100644 --- a/PVPlantFenceGate.py +++ b/PVPlantFenceGate.py @@ -256,7 +256,9 @@ class _CommandPVPlantGate: gate = makePVPlantFence() try: import MeshPart as mp - point1 = mp.projectPointsOnMesh([point1,], FreeCAD.ActiveDocument.Terrain.Mesh, FreeCAD.Vector(0, 0, 1))[0] + import PVPlantSite + site = PVPlantSite.get() + point1 = mp.projectPointsOnMesh([point1,], site.Terrain.Mesh, FreeCAD.Vector(0, 0, 1))[0] except: FreeCAD.Console.PrintError("No se puede encontrar punto 3D.." + "\n") diff --git a/PVPlantImportGrid.py b/PVPlantImportGrid.py index 3d3b4cd..a4ecca5 100644 --- a/PVPlantImportGrid.py +++ b/PVPlantImportGrid.py @@ -122,6 +122,7 @@ def getElevationFromOE(coordinates): try: r = get(query, timeout=20, verify=certifi.where()) # <-- Corrección aquí except RequestException as e: + print(f"Error en la solicitud: {str(e)}") points = [] for i, point in enumerate(coordinates): c = utm.from_latlon(point[0], point[1]) diff --git a/PVPlantPlacement.py b/PVPlantPlacement.py index 94fe41e..667ce1d 100644 --- a/PVPlantPlacement.py +++ b/PVPlantPlacement.py @@ -26,6 +26,7 @@ import Part if FreeCAD.GuiUp: import FreeCADGui, os from PySide import QtCore, QtGui + from PySide.QtGui import QListWidgetItem from PySide.QtCore import QT_TRANSLATE_NOOP else: # \cond @@ -62,7 +63,8 @@ class _PVPlantPlacementTaskPanel: '''The editmode TaskPanel for Schedules''' def __init__(self, obj=None): - self.Terrain = PVPlantSite.get().Terrain + self.site = PVPlantSite.get() + self.Terrain = self.site.Terrain self.FrameSetups = None self.PVArea = None self.Area = None @@ -77,8 +79,10 @@ class _PVPlantPlacementTaskPanel: self.form.setWindowIcon(QtGui.QIcon(os.path.join(PVPlantResources.DirIcons, "way.svg"))) self.form.buttonPVArea.clicked.connect(self.addPVArea) - self.form.buttonAddFrame.clicked.connect(self.addFrame) - self.form.buttonRemoveFrame.clicked.connect(self.removeFrame) + #self.form.buttonAddFrame.clicked.connect(self.addFrames) + #self.form.buttonRemoveFrame.clicked.connect(self.removeFrame) + + self.addFrames() def addPVArea(self): sel = FreeCADGui.Selection.getSelection() @@ -86,21 +90,10 @@ class _PVPlantPlacementTaskPanel: self.PVArea = sel[0] self.form.editPVArea.setText(self.PVArea.Label) - def addFrame(self): - from Mechanical.Frame import PVPlantFrame - selection = FreeCADGui.Selection.getSelection() - self.FrameSetup = selectionFilter(selection, PVPlantFrame.TrackerSetup) - - if len(selection) > 0: - items = [] - for x in range(self.form.listFrameSetups.count()): - items.append(self.form.listFrameSetups.item(x).text()) - if not (selection[0].Name in items): - self.form.listFrameSetups.addItem(selection[0].Name) - - def removeFrame(self): - ''' remove select item from list ''' - self.form.listFrameSetups.takeItem(self.form.listFrameSetups.currentRow()) + def addFrames(self): + for frame_setup in self.site.Frames: + list_item = QListWidgetItem(frame_setup.Name, self.form.listFrameSetups) + list_item.setCheckState(QtCore.Qt.Checked) def createFrameFromPoints(self, dataframe): from Mechanical.Frame import PVPlantFrame @@ -111,6 +104,12 @@ class _PVPlantPlacementTaskPanel: MechanicalGroup.Label = "Frames" FreeCAD.ActiveDocument.MechanicalGroup.addObject(MechanicalGroup) + if self.form.cbSubfolders.checked: + group = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", self.PVArea.Label) + group.Label = self.PVArea.Label + MechanicalGroup.addObject(group) + MechanicalGroup = group + placements = dataframe["placement"].tolist() types = dataframe["type"].tolist() frames = [] @@ -121,33 +120,30 @@ class _PVPlantPlacementTaskPanel: newrack.Placement = placements[idx] MechanicalGroup.addObject(newrack) frames.append(newrack) + if self.PVArea.Name.startswith("FrameArea"): self.PVArea.Frames = frames - # TODO: else def getProjected(self, shape): """ returns projected edges from a shape and a direction """ - if shape.BoundBox.ZLength == 0: - edges = shape.Edges - return Part.Face(Part.Wire(edges)) - else: - from Utils import PVPlantUtils as utils - wire = utils.simplifyWire(utils.getProjected(shape)) - if wire.isClosed(): - wire = wire.removeSplitter() - return Part.Face(wire) + return Part.Face(Part.Wire(shape.Edges)) + + from Utils import PVPlantUtils as utils + wire = utils.simplifyWire(utils.getProjected(shape)) + return Part.Face(wire.removeSplitter()) if wire.isClosed() else Part.Face(wire) def calculateWorkingArea(self): self.Area = self.getProjected(self.PVArea.Shape) - tmp = FreeCAD.ActiveDocument.findObjects(Name="ExclusionArea") - if len(tmp): - ProhibitedAreas = list() - for obj in tmp: + exclusion_areas = FreeCAD.ActiveDocument.findObjects(Name="ExclusionArea") + + if exclusion_areas: + prohibited_faces = [] + for obj in exclusion_areas: face = self.getProjected(obj.Base.Shape) if face.isValid(): - ProhibitedAreas.append(face) - self.Area = self.Area.cut(ProhibitedAreas) + prohibited_faces.append(face) + self.Area = self.Area.cut(prohibited_faces) def getAligments(self): # TODO: revisar todo esto: ----------------------------------------------------------------- @@ -280,104 +276,6 @@ class _PVPlantPlacementTaskPanel: placeRegion(df) return df - """def placeonregion_old(frames): # old - for colnum, col in enumerate(frames): - groups = list() - groups.append([col[0]]) - for i in range(1, len(col)): - group = groups[-1] - long = (col[i].sub(group[-1])).Length - long -= width - if long <= dist: - group.append(col[i]) - else: - groups.append([col[i]]) - for group in groups: - points = list() - points.append(group[0].sub(vec1)) - for ind in range(0, len(group) - 1): - points.append((group[ind].sub(vec1) + group[ind + 1].add(vec1)) / 2) - points.append(group[-1].add(vec1)) - points3D = list() - ''' - # v0 - for ind in range(len(points) - 1): - line = Part.LineSegment(points[ind], points[ind + 1]) - tmp = terrain.makeParallelProjection(line.toShape(), FreeCAD.Vector(0, 0, 1)) - if len(tmp.Vertexes) > 0: - if ind == 0: - points3D.append(tmp.Vertexes[0].Point) - points3D.append(tmp.Vertexes[-1].Point) - ''' - # V1 - if type == 0: # Mesh: - import MeshPart as mp - for point in points: - point3D = mp.projectPointsOnMesh([point, ], terrain, FreeCAD.Vector(0, 0, 1)) - if len(point3D) > 0: - points3D.append(point3D[0]) - - else: # Shape: - line = Part.LineSegment(points[0], points[-1]) - tmp = terrain.makeParallelProjection(line.toShape(), FreeCAD.Vector(0, 0, 1)) - if len(tmp.Vertexes) > 0: - tmppoints = [ver.Point for ver in tmp.Vertexes] - if mode == 1: # mode = normal - for point in points: - '''# OPTION 1: - line = Part.Line(point, point + FreeCAD.Vector(0, 0, 10)) - for i in range(len(tmppoints) - 1): - seg = Part.LineSegment(tmppoints[i], tmppoints[i + 1]) - inter = line.intersect(seg) - print(inter) - if len(inter) > 0: - points3D.append(FreeCAD.Vector(inter[0].X, inter[0].Y, inter[0].Z)) - ''' - # OPTION 2: - plane = Part.Plane(point, self.Dir) - for i in range(len(tmppoints) - 1): - seg = Part.LineSegment(tmppoints[i], tmppoints[i + 1]) - inter = plane.intersect(seg) - if len(inter) > 0: - if len(inter[0]): - inter = inter[0] - points3D.append(FreeCAD.Vector(inter[0].X, inter[0].Y, inter[0].Z)) - break - else: # TODO: mode = Trend - # TODO: check: - from scipy import stats - xx = list() - yy = list() - zz = list() - - for pts in tmppoints: - xx.append(pts.x) - yy.append(pts.y) - zz.append(pts.z) - - slope, intercept, r, p, std_err = stats.linregress(yy, zz) - - def myfunc(x): - return slope * x + intercept - - x = list() - x.append(yy[0]) - x.append(yy[-1]) - newzz = list(map(myfunc, x)) - points3D.append(FreeCAD.Vector(xx[0], yy[0], newzz[0])) - points3D.append(FreeCAD.Vector(xx[-1], yy[-1], newzz[1])) - - for ind in range(0, len(points3D) - 1): - pl = FreeCAD.Placement() - vec = points3D[ind] - points3D[ind + 1] - pl.Base = FreeCAD.Vector(group[ind]) - p = (points3D[ind] + points3D[ind + 1]) / 2 - pl.Base.z = p.z - rot = FreeCAD.Rotation(FreeCAD.Vector(-1, 0, 0), vec) - pl.Rotation = FreeCAD.Rotation(rot.toEuler()[0], rot.toEuler()[1], 0) - placements.append(pl) - return placements""" - def isInside(self, frame, point): if self.Area.isInside(point, 10, True): frame.Placement.Base = point @@ -542,23 +440,32 @@ class _PVPlantPlacementTaskPanel: params.SetBool("AutoSaveEnabled", False) FreeCAD.ActiveDocument.RecomputesFrozen = True - items = [] - for x in range(self.form.listFrameSetups.count()): - items.append(FreeCAD.ActiveDocument.getObject(self.form.listFrameSetups.item(x).text())) - tmpframes = list() + items = [ + FreeCAD.ActiveDocument.getObject(item.text()) + for i in range(self.form.listFrameSetups.count()) + if (item := self.form.listFrameSetups.item(i)).checkState() == QtCore.Qt.Checked + ] + + """seen_lengths = set() + tmpframes = [] for frame in sorted(items, key=lambda rack: rack.Length, reverse=True): - found = False + if frame.Length not in seen_lengths: + seen_lengths.add(frame.Length) + tmpframes.append(frame) + '''found = False for tmp in tmpframes: if tmp.Length == frame.Length: found = True break if not found: - tmpframes.append(frame) - self.FrameSetups = tmpframes.copy() - longerFrame = self.FrameSetups[0] + tmpframes.append(frame)''' + self.FrameSetups = tmpframes.copy()""" + + unique_frames = {frame.Length.Value: frame for frame in items} + self.FrameSetups = sorted(list(unique_frames.values()), key=lambda rack: rack.Length, reverse=True) self.gap_col = FreeCAD.Units.Quantity(self.form.editGapCols.text()).Value - self.gap_row = FreeCAD.Units.Quantity(self.form.editGapRows.text()).Value + longerFrame.Length.Value + self.gap_row = FreeCAD.Units.Quantity(self.form.editGapRows.text()).Value + self.FrameSetups[0].Length.Value self.offsetX = FreeCAD.Units.Quantity(self.form.editOffsetHorizontal.text()).Value self.offsetY = FreeCAD.Units.Quantity(self.form.editOffsetVertical.text()).Value @@ -581,8 +488,6 @@ class _PVPlantPlacementTaskPanel: print(" -- Tiempo tardado:", total_time) FreeCADGui.Control.closeDialog() FreeCAD.ActiveDocument.recompute() - #return True - # ---------------------------------------------------------------------------------------------------------------------- # function AdjustToTerrain diff --git a/PVPlantPlacement.ui b/PVPlantPlacement.ui index 05e553d..49fc1d4 100644 --- a/PVPlantPlacement.ui +++ b/PVPlantPlacement.ui @@ -15,6 +15,338 @@ Park Settings + + + + Estructura: + + + + + + + + 16777215 + 54 + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Add + + + + + + + Remove + + + + + + + + + + Add + + + + + + + Configuración + + + + 10 + + + 6 + + + + + + De arriba a abajo + + + + + De abajo a arriba + + + + + Del centro a los lados + + + + + + + + + 120 + 16777215 + + + + Dirección Horizontal + + + + + + + + De izquierda a derecha + + + + + De derecha a izquiera + + + + + De centro a los lados + + + + + + + + Alinear estructuras + + + true + + + + + + + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + + + QAbstractSpinBox::ButtonSymbols::NoButtons + + + mm + + + 10000 + + + 500 + + + + + + + + 120 + 16777215 + + + + Pitch + + + + + + + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + + + QAbstractSpinBox::ButtonSymbols::NoButtons + + + m + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + + 120 + 16777215 + + + + Orientación + + + + + + + + 120 + 16777215 + + + + Offset Horizontal + + + + + + + + 120 + 16777215 + + + + Offset Vertical + + + + + + + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + + + QAbstractSpinBox::ButtonSymbols::NoButtons + + + m + + + 3 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + + + QAbstractSpinBox::ButtonSymbols::NoButtons + + + m + + + 3 + + + 100.000000000000000 + + + 5.000000000000000 + + + + + + + + Norte - Sur + + + + + Este - Oeste + + + + + + + + + 120 + 16777215 + + + + Dirección Vertical + + + + + + + + 120 + 16777215 + + + + Espacio entre filas + + + + + + + + + + - Inner Spacing + + + + + + @@ -59,10 +391,10 @@ - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter - QAbstractSpinBox::NoButtons + QAbstractSpinBox::ButtonSymbols::NoButtons @@ -110,10 +442,10 @@ - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter - QAbstractSpinBox::NoButtons + QAbstractSpinBox::ButtonSymbols::NoButtons @@ -135,10 +467,10 @@ - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter - QAbstractSpinBox::NoButtons + QAbstractSpinBox::ButtonSymbols::NoButtons 4 @@ -148,10 +480,10 @@ - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter - QAbstractSpinBox::NoButtons + QAbstractSpinBox::ButtonSymbols::NoButtons 8 @@ -161,45 +493,6 @@ - - - - Add - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Add - - - - - - - Remove - - - - - - @@ -207,292 +500,9 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Configuración - - - - 10 - - - 6 - - - - - - 120 - 16777215 - - - - Offset Vertical - - - - - - - - 120 - 16777215 - - - - Orientación - - - - - - - Alinear estructuras - - - true - - - - - - - - 120 - 16777215 - - - - Espacio entre filas - - - - - - - - 120 - 16777215 - - - - Dirección Horizontal - - - - - - - - 120 - 16777215 - - - - Offset Horizontal - - - - - - - - 120 - 16777215 - - - - Pitch - - - - - - - - 120 - 16777215 - - - - Dirección Vertical - - - - - - - - Norte - Sur - - - - - Este - Oeste - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - QAbstractSpinBox::NoButtons - - - m - - - 3 - - - 100.000000000000000 - - - 5.000000000000000 - - - - - - - - De izquierda a derecha - - - - - De derecha a izquiera - - - - - De centro a los lados - - - - - - - - - De arriba a abajo - - - - - De abajo a arriba - - - - - Del centro a los lados - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - QAbstractSpinBox::NoButtons - - - m - - - 3 - - - -10000.000000000000000 - - - 10000.000000000000000 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - QAbstractSpinBox::NoButtons - - - m - - - 3 - - - -10000.000000000000000 - - - 10000.000000000000000 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - QAbstractSpinBox::NoButtons - - - mm - - - 10000 - - - 500 - - - - - - - - - - Estructura: - - - - - - - - 16777215 - 54 - - - - diff --git a/PVPlantSite.py b/PVPlantSite.py index dc177b4..242b666 100644 --- a/PVPlantSite.py +++ b/PVPlantSite.py @@ -771,12 +771,12 @@ class _PVPlantSite(ArchSite._Site): import PVPlantImportGrid x, y, zone_number, zone_letter = utm.from_latlon(lat, lon) self.obj.UtmZone = zone_list[zone_number - 1] - zz = PVPlantImportGrid.getElevationFromOE([[lat, lon]]) - self.obj.Origin = FreeCAD.Vector(x * 1000, y * 1000, zz[0].z) - #self.obj.OriginOffset = FreeCAD.Vector(x * 1000, y * 1000, 0) #?? + + point = PVPlantImportGrid.getElevationFromOE([[lat, lon]]) + self.obj.Origin = FreeCAD.Vector(point[0].x, point[0].y, point[0].z) self.obj.Latitude = lat self.obj.Longitude = lon - self.obj.Elevation = zz[0].z + self.obj.Elevation = point[0].z class _ViewProviderSite(ArchSite._ViewProviderSite): diff --git a/Project/ProjectSetup.ui b/Project/ProjectSetup.ui index 80a9b3c..e22643b 100644 --- a/Project/ProjectSetup.ui +++ b/Project/ProjectSetup.ui @@ -39,6 +39,16 @@ 9 + + + + Maximum west-east slope: + + + + + + @@ -46,17 +56,20 @@ - - + + - Frame coloring: + South facing + + + Qt::AlignmentFlag::AlignCenter - Qt::Vertical + Qt::Orientation::Vertical @@ -66,71 +79,20 @@ - - + + - Maximum west-east slope: - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - QAbstractSpinBox::NoButtons - - - º - - - 90.000000000000000 - - - 8.000000000000000 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - QAbstractSpinBox::NoButtons - - - º - - - 90.000000000000000 - - - 2.800000000000000 - - - - - - - - - - South facing - - - Qt::AlignCenter + Frame coloring: - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter - QAbstractSpinBox::NoButtons + QAbstractSpinBox::ButtonSymbols::NoButtons º @@ -149,7 +111,45 @@ North Facing - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter + + + + + + + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + + + QAbstractSpinBox::ButtonSymbols::NoButtons + + + º + + + 90.000000000000000 + + + 2.800000000000000 + + + + + + + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + + + QAbstractSpinBox::ButtonSymbols::NoButtons + + + º + + + 90.000000000000000 + + + 8.000000000000000