Commit c4452659 authored by Rick Gruber-Riemer's avatar Rick Gruber-Riemer

Handling chimneys tagged as nodes or ways/buildings by using static models in FGData.

parent 96cfa884
......@@ -1002,6 +1002,10 @@ def analyse(buildings: List[Building], fg_elev: FGElev,
'man_made' in b.tags and b.tags['man_made'] in ['storage_tank', 'tank']):
logging.debug("Excluded storage tank with osm_id={}".format(b.osm_id))
continue
# exclude chimneys -> pylons.py
if 'man_made' in b.tags and b.tags['man_made'] in ['chimney']:
logging.debug("Excluded chimney or with osm_id={}".format(b.osm_id))
continue
# -- get geometry right
# - simplify
......
......@@ -176,6 +176,7 @@ C2P_PROCESS_OVERHEAD_LINES = False
C2P_PROCESS_WIND_TURBINES = True
C2P_PROCESS_STREETLAMPS = False
C2P_PROCESS_STORAGE_TANKS = True
C2P_PROCESS_CHIMNEYS = True
# The radius for the cable. The cable will be a triangle with side length 2*radius.
# In order to be better visible the radius might be chosen larger than in real life
......@@ -225,6 +226,10 @@ C2P_STREETLAMPS_MIN_STREET_LENGTH = 20
C2P_WIND_TURBINE_MAX_DISTANCE_WITHIN_WIND_FARM = 700
C2P_WIND_TURBINE_MIN_DISTANCE_SHARED_OBJECT = 10
C2P_CHIMNEY_BRICK_RATION = 0.2 # the ratio of chimneys being made of bricks (rest is cement etc.)
C2P_CHIMNEY_DEFAULT_HEIGHT = 100 # the default height of chimneys, where the height is not specified in OSM
C2P_CHIMNEY_DEFAULT_HEIGHT_VARIATION = 20 # a random variation on top of the default height between 0 and value
# =============================================================================
# PARAMETERS RELATED TO landuse.py - might be replaced by another library
# =============================================================================
......
......@@ -22,6 +22,7 @@ import logging
import math
import multiprocessing as mp
import os
import random
import time
from typing import Dict, List, Tuple
import unittest
......@@ -322,6 +323,86 @@ class SharedPylon(object):
_stg_angle(self.heading - 90 + direction_correction))
class Chimney(SharedPylon):
def __init__(self, osm_id: int, lon: float, lat: float, elevation: float, tags: Dict[str, str]) -> None:
super().__init__()
self.osm_id = osm_id
self.lon = lon
self.lat = lat
self.height = parameters.C2P_CHIMNEY_DEFAULT_HEIGHT # the height of the chimney
variation = random.uniform(0, parameters.C2P_CHIMNEY_DEFAULT_HEIGHT_VARIATION)
self.height += variation
if 'height' in tags:
self.height = osmparser.parse_length(tags['height'])
bricks = False
if 'building:material' in tags and tags['building:material'] == 'brick':
bricks = True
else: # determine brick material randomly
ratio = random.uniform(0, 1)
if ratio <= parameters.C2P_CHIMNEY_BRICK_RATION:
bricks = True
if bricks:
self.pylon_model = 'brick_chimney_502m.ac'
model_height = 502.
if self.height > 502.:
self.height = 502.
else:
if self.height <= 120.:
model_height = 120
self.pylon_model = 'TPS_Drujba2_chimney.ac'
else:
if self.height <= 205.:
model_height = 205.
self.pylon_model = 'Boesdorf_Chimney.xml'
elif 205 < self.height < 250:
model_height = 250.
self.pylon_model = 'kw_altbach_chimney250.xml'
else:
if self.height > 500:
self.height = 500.
self.poly_model = 'generic_chimney_01.xml'
model_height = 500.
# correct elevation to account for model height vs. chimney height
self.elevation = elevation - (model_height - self.height)
self.pylon_model = 'Models/Industrial/' + self.pylon_model
def _process_osm_chimneys_nodes(osm_nodes_dict: Dict[int, osmparser.Node], coords_transform: coordinates.Transformation,
fg_elev: utilities.FGElev) -> List[Chimney]:
chimneys = list()
for key, node in osm_nodes_dict.items():
probe_tuple = fg_elev.probe(vec2d.Vec2d(node.lon, node.lat), True)
chimney = Chimney(key, node.lon, node.lat, probe_tuple[0], node.tags)
chimney.x, chimney.y = coords_transform.toLocal((node.lon, node.lat))
chimneys.append(chimney)
return chimneys
def _process_osm_chimneys_ways(nodes_dict, ways_dict, my_coord_transformator,
fg_elev: utilities.FGElev) -> List[Chimney]:
chimneys = list()
for way in list(ways_dict.values()):
for key in way.tags:
my_coordinates = list()
for ref in way.refs:
if ref in nodes_dict:
my_node = nodes_dict[ref]
my_coordinates.append(my_coord_transformator.toLocal((my_node.lon, my_node.lat)))
if 2 < len(my_coordinates):
my_polygon = shg.Polygon(my_coordinates)
if my_polygon.is_valid and not my_polygon.is_empty:
my_centroid = my_polygon.centroid
lon, lat = my_coord_transformator.toGlobal((my_centroid.x, my_centroid.y))
probe_tuple = fg_elev.probe(vec2d.Vec2d(lon, lat), True)
chimney = Chimney(key, lon, lat, probe_tuple[0], way.tags)
chimney.x = my_centroid.x
chimney.y = my_centroid.y
chimneys.append(chimney)
return chimneys
class StorageTank(SharedPylon):
def __init__(self, osm_id: int, lon: float, lat: float, tags: Dict[str, str], radius: float,
elevation: float) -> None:
......@@ -1797,6 +1878,18 @@ def process(coords_transform: coordinates.Transformation, fg_elev: utilities.FGE
osm_nodes_dict = osmparser.fetch_db_nodes_isolated(["generator:source=>wind"])
wind_turbines = _process_osm_wind_turbines(osm_nodes_dict, coords_transform, fg_elev, stg_entries)
logging.info("Number of valid wind turbines found: {}".format(len(wind_turbines)))
# chimneys
chimneys = list()
if parameters.C2P_PROCESS_WIND_TURBINES:
# start with chimneys tagged as node
osm_nodes_dict = osmparser.fetch_db_nodes_isolated(['man_made=>chimney'])
chimneys = _process_osm_chimneys_nodes(osm_nodes_dict, coords_transform, fg_elev)
# add chimneys tagged as way
osm_way_result = osmparser.fetch_osm_db_data_ways_key_values(['man_made=>chimney'])
osm_nodes_dict = osm_way_result.nodes_dict
osm_ways_dict = osm_way_result.ways_dict
chimneys.extend(_process_osm_chimneys_ways(osm_nodes_dict, osm_ways_dict, coords_transform, fg_elev))
logging.info("Number of valid chimneys found: {}".format(len(chimneys)))
# free some memory
del building_refs
......@@ -1833,6 +1926,9 @@ def process(coords_transform: coordinates.Transformation, fg_elev: utilities.FGE
if parameters.C2P_PROCESS_STORAGE_TANKS:
for tank in storage_tanks:
tank.make_stg_entry(stg_manager)
if parameters.C2P_PROCESS_CHIMNEYS:
for chimney in chimneys:
chimney.make_stg_entry(stg_manager)
stg_manager.write(file_lock)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment