update
This commit is contained in:
@@ -92,10 +92,24 @@ class OSMImporter:
|
||||
'nodes': [nd.attrib['ref'] for nd in way.findall('nd')]
|
||||
}
|
||||
|
||||
print("1. Create Transportations")
|
||||
FreeCADGui.updateGui()
|
||||
self.create_transportation()
|
||||
|
||||
print("2. Create Buildings")
|
||||
FreeCADGui.updateGui()
|
||||
self.create_buildings()
|
||||
|
||||
print("3. Create Power Infrastructure")
|
||||
FreeCADGui.updateGui()
|
||||
self.create_power_infrastructure()
|
||||
|
||||
print("4. Create Vegetation")
|
||||
FreeCADGui.updateGui()
|
||||
self.create_vegetation()
|
||||
|
||||
print("5. Create Water Bodies")
|
||||
FreeCADGui.updateGui()
|
||||
self.create_water_bodies()
|
||||
|
||||
def create_transportation(self):
|
||||
@@ -118,27 +132,27 @@ class OSMImporter:
|
||||
'secondary': 5.0,
|
||||
'tertiary': 4.0
|
||||
}.get(highway_type, 3.0)
|
||||
|
||||
self.create_road(nodes, width, highway_type, transport_layer)
|
||||
self.create_road(nodes, width, highway_type, transport_layer, tags['name'] if 'name' in tags else "")
|
||||
|
||||
# Vías férreas
|
||||
if 'railway' in tags:
|
||||
self.create_railway(nodes, transport_layer)
|
||||
self.create_railway(nodes, transport_layer, tags['name'] if 'name' in tags else "")
|
||||
|
||||
def create_road(self, nodes, width, road_type, layer):
|
||||
def create_road(self, nodes, width, road_type, layer, name=""):
|
||||
points = [n for n in nodes]
|
||||
polyline = Draft.make_wire(points, closed=False, face=False)
|
||||
polyline.Label = f"Road_{road_type}"
|
||||
polyline.Label = f"Road_{name if (name != '') else road_type}"
|
||||
polyline.ViewObject.LineWidth = 2.0
|
||||
polyline.ViewObject.ShapeColor = self.feature_colors['highway'].get(road_type, (0.5, 0.5, 0.5))
|
||||
polyline.addProperty("App::PropertyString", "OSMType", "Metadata", "Tipo de vía").OSMType = road_type
|
||||
polyline.addProperty("App::PropertyFloat", "Width", "Metadata", "Ancho de la vía").Width = width
|
||||
layer.addObject(polyline)
|
||||
|
||||
def create_railway(self, nodes, layer):
|
||||
|
||||
def create_railway(self, nodes, layer, name=""):
|
||||
points = [n for n in nodes]
|
||||
rail_line = Draft.make_wire(points, closed=False, face=False)
|
||||
rail_line.Label = "Railway"
|
||||
rail_line.Label = f"{name if (name != '') else 'Railway'}"
|
||||
rail_line.ViewObject.LineWidth = 1.5
|
||||
rail_line.ViewObject.ShapeColor = self.feature_colors['railway']
|
||||
layer.addObject(rail_line)
|
||||
@@ -149,6 +163,8 @@ class OSMImporter:
|
||||
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]
|
||||
|
||||
@@ -205,9 +221,12 @@ class OSMImporter:
|
||||
nodes = [self.nodes[ref] for ref in data['nodes'] if ref in self.nodes]
|
||||
|
||||
if 'power' in tags:
|
||||
print("\n\n")
|
||||
print(tags)
|
||||
feature_type = tags['power']
|
||||
|
||||
if feature_type == 'line':
|
||||
print("3.1. Create Power Lines")
|
||||
FreeCADGui.updateGui()
|
||||
self.create_power_line(
|
||||
nodes=nodes,
|
||||
tags=tags,
|
||||
@@ -215,6 +234,8 @@ class OSMImporter:
|
||||
)
|
||||
|
||||
elif feature_type == 'substation':
|
||||
print("3.1. Create substations")
|
||||
FreeCADGui.updateGui()
|
||||
self.create_substation(
|
||||
way_id=way_id,
|
||||
tags=tags,
|
||||
@@ -223,11 +244,17 @@ class OSMImporter:
|
||||
)
|
||||
|
||||
elif feature_type == 'tower':
|
||||
print("3.1. Create power towers")
|
||||
FreeCADGui.updateGui()
|
||||
self.create_power_tower(
|
||||
position=nodes[0] if nodes else None,
|
||||
tags=tags,
|
||||
layer=power_layer
|
||||
)
|
||||
'''self.create_power_tower_1(
|
||||
way=way_id,
|
||||
layer=power_layer
|
||||
)'''
|
||||
|
||||
def create_power_line(self, nodes, tags, layer):
|
||||
"""Crea líneas de transmisión eléctrica con propiedades técnicas"""
|
||||
@@ -244,10 +271,10 @@ class OSMImporter:
|
||||
return
|
||||
|
||||
wire = Draft.make_wire(points, closed=False, face=False)
|
||||
wire.Label = f"Power_Line_{voltage}V"
|
||||
wire.Label = f"Power_Line_{int(voltage/1000000)}kV"
|
||||
|
||||
# Propiedades visuales
|
||||
wire.ViewObject.LineWidth = 1 + (voltage / 100000)
|
||||
wire.ViewObject.LineWidth = 6 #'''1 + (voltage / 100000)'''
|
||||
color = self.feature_colors['power']['line']
|
||||
wire.ViewObject.ShapeColor = color
|
||||
|
||||
@@ -260,7 +287,7 @@ class OSMImporter:
|
||||
layer.addObject(wire)
|
||||
|
||||
# Añadir torres si es overhead
|
||||
if line_type == 'overhead':
|
||||
'''if line_type == 'overhead':
|
||||
distance_between_towers = 150 # metros por defecto
|
||||
if 'distance_between_towers' in tags:
|
||||
try:
|
||||
@@ -273,7 +300,7 @@ class OSMImporter:
|
||||
voltage=voltage,
|
||||
distance=distance_between_towers,
|
||||
layer=layer
|
||||
)
|
||||
)'''
|
||||
|
||||
except Exception as e:
|
||||
FreeCAD.Console.PrintError(f"Error creating power line: {str(e)}\n")
|
||||
@@ -318,7 +345,8 @@ class OSMImporter:
|
||||
|
||||
# Unir componentes
|
||||
tower = base.fuse(mast)
|
||||
tower_obj = layer.addObject("Part::Feature", "Power_Tower")
|
||||
tower_obj = FreeCAD.ActiveDocument.addObject("Part::Feature", "Power_Tower")
|
||||
layer.addObject(tower_obj)
|
||||
tower_obj.Shape = tower
|
||||
tower_obj.ViewObject.ShapeColor = self.feature_colors['power']['tower']
|
||||
|
||||
@@ -354,6 +382,164 @@ class OSMImporter:
|
||||
cable.ViewObject.ShapeColor = self.feature_colors['power']['line']
|
||||
layer.addObject(cable)
|
||||
|
||||
def create_power_tower_1(self, way, layer):
|
||||
"""Crea una torre eléctrica según especificaciones OSM"""
|
||||
tags = way['tags']
|
||||
nodes = [self.nodes[ref] for ref in way['nodes'] if ref in self.nodes]
|
||||
|
||||
if not nodes:
|
||||
return
|
||||
|
||||
try:
|
||||
# Obtener parámetros principales
|
||||
structure_type = tags.get('structure', 'lattice')
|
||||
material = tags.get('material', 'steel')
|
||||
height = float(tags.get('height', 30.0)) # Altura en metros
|
||||
voltage = self.parse_voltage(tags.get('voltage', '132000')) # 132kV por defecto
|
||||
lines = int(tags.get('lines', '3'))
|
||||
operator = tags.get('operator', '')
|
||||
tower_name = tags.get('name', f"Tower_{way['id']}")
|
||||
|
||||
# Calcular posición (usar primer nodo)
|
||||
position = FreeCAD.Vector(*nodes[0])
|
||||
|
||||
# Configurar dimensiones basadas en parámetros
|
||||
base_size = self.calculate_base_size(structure_type, height)
|
||||
crossarm_length = self.calculate_crossarm_length(voltage, lines)
|
||||
color = self.get_material_color(material)
|
||||
|
||||
# Crear geometría según tipo de estructura
|
||||
if structure_type == 'lattice':
|
||||
tower = self.create_lattice_tower(height, base_size, crossarm_length)
|
||||
elif structure_type == 'tubular':
|
||||
tower = self.create_tubular_tower(height, base_size, crossarm_length)
|
||||
elif structure_type == 'portal':
|
||||
tower = self.create_portal_tower(height, base_size, crossarm_length)
|
||||
else:
|
||||
tower = self.create_default_tower(height, base_size, crossarm_length)
|
||||
|
||||
# Crear objeto en FreeCAD
|
||||
tower_obj = layer.addObject("Part::Feature", "Power_Tower")
|
||||
tower_obj.Shape = tower
|
||||
tower_obj.ViewObject.ShapeColor = color
|
||||
tower_obj.Placement.Base = position
|
||||
|
||||
# Añadir propiedades técnicas
|
||||
tower_obj.addProperty("App::PropertyFloat", "Voltage", "Technical", "Voltaje nominal (V)").Voltage = voltage
|
||||
tower_obj.addProperty("App::PropertyFloat", "Height", "Technical", "Altura total (m)").Height = height
|
||||
tower_obj.addProperty("App::PropertyString", "StructureType", "Technical",
|
||||
"Tipo de estructura").StructureType = structure_type
|
||||
tower_obj.addProperty("App::PropertyString", "Material", "Technical",
|
||||
"Material de construcción").Material = material
|
||||
tower_obj.addProperty("App::PropertyInteger", "Lines", "Technical", "Número de circuitos").Lines = lines
|
||||
if operator:
|
||||
tower_obj.addProperty("App::PropertyString", "Operator", "General", "Operador").Operator = operator
|
||||
|
||||
# Añadir cables si existen nodos de conexión
|
||||
if len(nodes) >= 2:
|
||||
connection_points = [FreeCAD.Vector(*n) for n in nodes]
|
||||
self.create_power_lines_between_towers(connection_points, voltage, layer)
|
||||
|
||||
except Exception as e:
|
||||
FreeCAD.Console.PrintError(f"Error creando torre {way['id']}: {str(e)}\n")
|
||||
|
||||
def create_lattice_tower(self, height, base_size, crossarm_length):
|
||||
"""Crea torre de celosía tipo armazón"""
|
||||
# Base
|
||||
base = Part.makeBox(base_size, base_size, 3.0)
|
||||
|
||||
# Patas principales
|
||||
leg_profile = Part.makeBox(0.5, 0.5, height)
|
||||
legs = []
|
||||
for x in [-base_size / 2, base_size / 2]:
|
||||
for y in [-base_size / 2, base_size / 2]:
|
||||
leg = leg_profile.copy()
|
||||
leg.translate(FreeCAD.Vector(x, y, 3.0))
|
||||
legs.append(leg)
|
||||
|
||||
# Travesaños horizontales
|
||||
horizontal_bars = []
|
||||
for z in [10.0, height / 2, height - 5.0]:
|
||||
bar = Part.makeBox(base_size + 1.0, 0.3, 0.3, FreeCAD.Vector(-(base_size + 1) / 2, -0.15, z))
|
||||
horizontal_bars.append(bar)
|
||||
|
||||
# Crucetas
|
||||
crossarms = self.create_crossarms(height, crossarm_length)
|
||||
|
||||
# Unir todas las partes
|
||||
tower = base.multiFuse(legs + horizontal_bars + crossarms)
|
||||
return tower.removeSplitter()
|
||||
|
||||
def create_crossarms(self, height, length):
|
||||
"""Crea crucetas para líneas eléctricas"""
|
||||
crossarms = []
|
||||
positions = [
|
||||
(height - 5.0, 0), # Superior
|
||||
(height - 15.0, 22.5), # Media con ángulo
|
||||
(height - 25.0, -22.5) # Inferior con ángulo
|
||||
]
|
||||
|
||||
for z, angle in positions:
|
||||
crossarm = Part.makeBox(length, 0.3, 0.3)
|
||||
crossarm.rotate(FreeCAD.Vector(0, 0, z), FreeCAD.Vector(0, 0, 1), angle)
|
||||
crossarm.translate(FreeCAD.Vector(-length / 2, -0.15, z))
|
||||
crossarms.append(crossarm)
|
||||
|
||||
return crossarms
|
||||
|
||||
def calculate_base_size(self, structure_type, height):
|
||||
"""Calcula tamaño de base según tipo de estructura y altura"""
|
||||
base_sizes = {
|
||||
'lattice': 4.0 + (height * 0.1),
|
||||
'tubular': 3.0 + (height * 0.05),
|
||||
'portal': 6.0,
|
||||
'default': 3.0
|
||||
}
|
||||
return base_sizes.get(structure_type, base_sizes['default'])
|
||||
|
||||
def calculate_crossarm_length(self, voltage, lines):
|
||||
"""Calcula longitud de crucetas según voltaje y número de circuitos"""
|
||||
return (voltage / 100000) * 8.0 + (lines * 2.0)
|
||||
|
||||
def get_material_color(self, material):
|
||||
"""Devuelve color según material de construcción"""
|
||||
colors = {
|
||||
'steel': (0.65, 0.65, 0.7),
|
||||
'concrete': (0.8, 0.8, 0.8),
|
||||
'wood': (0.5, 0.3, 0.2),
|
||||
'aluminum': (0.9, 0.9, 0.9),
|
||||
'default': (0.5, 0.5, 0.5)
|
||||
}
|
||||
return colors.get(material.lower(), colors['default'])
|
||||
|
||||
def create_power_lines_between_towers(self, points, voltage, layer):
|
||||
"""Crea cables entre torres"""
|
||||
cable_thickness = 0.1 + (voltage / 500000)
|
||||
|
||||
for i in range(len(points) - 1):
|
||||
start = points[i]
|
||||
end = points[i + 1]
|
||||
|
||||
# Crear cable curvo (catenaria)
|
||||
cable = self.create_catenary(start, end, sag=5.0)
|
||||
cable_obj = layer.addObject("Part::Feature", f"Power_Line_{i}")
|
||||
cable_obj.Shape = cable
|
||||
cable_obj.ViewObject.LineWidth = cable_thickness * 1000 # Convertir a mm
|
||||
cable_obj.ViewObject.ShapeColor = (0.1, 0.1, 0.1)
|
||||
|
||||
def create_catenary(self, start, end, sag=5.0):
|
||||
"""Crea curva de catenaria para cables eléctricos"""
|
||||
mid_point = (start + end) / 2
|
||||
mid_point.z -= sag
|
||||
|
||||
arc = Part.Arc(
|
||||
start,
|
||||
mid_point,
|
||||
end
|
||||
)
|
||||
|
||||
return Part.Edge(arc.toShape())
|
||||
|
||||
def create_substation(self, way_id, tags, nodes, layer):
|
||||
"""Crea subestaciones con todos los componentes detallados"""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user