Commit 133966aa authored by Rick Gruber-Riemer's avatar Rick Gruber-Riemer

Mkaing sure wind turbines do not interfer with existing shared objects (in...

Mkaing sure wind turbines do not interfer with existing shared objects (in most situations manually placed wind turbines).
parent dc6ea656
......@@ -28,7 +28,7 @@ from utils import ac3d, ac3d_fast, calc_tile
from utils.coordinates import Transformation
from utils.utilities import FGElev, progress, Stats
from utils.vec2d import Vec2d
from utils.stg_io2 import STGVerbType, read_stg_entries
from utils.stg_io2 import STGVerbType, read_stg_entries, read_stg_entries_in_boundary
class Building(object):
......@@ -1255,39 +1255,28 @@ def _create_static_obj_boundaries(my_coord_transformation: Transformation) -> Di
Shapely polygon objects (convex hull of all points in ac-files) in the local x/y coordinate system.
"""
boundaries = dict()
stg_files = calc_tile.get_stg_files_in_boundary(parameters.BOUNDARY_WEST, parameters.BOUNDARY_SOUTH,
parameters.BOUNDARY_EAST, parameters.BOUNDARY_NORTH,
parameters.PATH_TO_SCENERY, "Objects")
if parameters.PATH_TO_SCENERY_OPT is not None:
stg_files_opt = calc_tile.get_stg_files_in_boundary(parameters.BOUNDARY_WEST, parameters.BOUNDARY_SOUTH,
parameters.BOUNDARY_EAST, parameters.BOUNDARY_NORTH,
parameters.PATH_TO_SCENERY_OPT, "Objects")
stg_files.extend(stg_files_opt)
for filename in stg_files:
stg_entries = read_stg_entries(filename, parameters.OVERLAP_CHECK_CONSIDER_SHARED)
for entry in stg_entries:
if entry.verb_type in [STGVerbType.object_static, STGVerbType.object_shared]:
try:
ac_filename = entry.obj_filename
if ac_filename.endswith(".xml"):
entry.overwrite_filename(_extract_ac_from_xml(entry.get_obj_path_and_name(),
entry.get_obj_path_and_name(parameters.PATH_TO_SCENERY)))
boundary_polygon = _extract_boundary(entry.get_obj_path_and_name(),
entry.get_obj_path_and_name(parameters.PATH_TO_SCENERY))
rotated_polygon = affinity.rotate(boundary_polygon, entry.hdg - 90, (0, 0))
x_y_point = my_coord_transformation.toLocal((entry.lon, entry.lat))
translated_polygon = affinity.translate(rotated_polygon, x_y_point[0], x_y_point[1])
if entry.verb_type is STGVerbType.object_static and parameters.OVERLAP_CHECK_CH_BUFFER_STATIC > 0.01:
boundaries[ac_filename] = translated_polygon.buffer(
parameters.OVERLAP_CHECK_CH_BUFFER_STATIC, shg.CAP_STYLE.square)
elif entry.verb_type is STGVerbType.object_shared and parameters.OVERLAP_CHECK_CH_BUFFER_SHARED > 0.01:
boundaries[ac_filename] = translated_polygon.buffer(
parameters.OVERLAP_CHECK_CH_BUFFER_SHARED, shg.CAP_STYLE.square)
else:
boundaries[ac_filename] = translated_polygon
except IOError as reason:
logging.warning("Ignoring unreadable stg_entry %s", reason)
stg_entries = read_stg_entries_in_boundary(parameters.OVERLAP_CHECK_CONSIDER_SHARED)
for entry in stg_entries:
if entry.verb_type in [STGVerbType.object_static, STGVerbType.object_shared]:
try:
ac_filename = entry.obj_filename
if ac_filename.endswith(".xml"):
entry.overwrite_filename(_extract_ac_from_xml(entry.get_obj_path_and_name(),
entry.get_obj_path_and_name(parameters.PATH_TO_SCENERY)))
boundary_polygon = _extract_boundary(entry.get_obj_path_and_name(),
entry.get_obj_path_and_name(parameters.PATH_TO_SCENERY))
rotated_polygon = affinity.rotate(boundary_polygon, entry.hdg - 90, (0, 0))
x_y_point = my_coord_transformation.toLocal((entry.lon, entry.lat))
translated_polygon = affinity.translate(rotated_polygon, x_y_point[0], x_y_point[1])
if entry.verb_type is STGVerbType.object_static and parameters.OVERLAP_CHECK_CH_BUFFER_STATIC > 0.01:
boundaries[ac_filename] = translated_polygon.buffer(
parameters.OVERLAP_CHECK_CH_BUFFER_STATIC, shg.CAP_STYLE.square)
elif entry.verb_type is STGVerbType.object_shared and parameters.OVERLAP_CHECK_CH_BUFFER_SHARED > 0.01:
boundaries[ac_filename] = translated_polygon.buffer(
parameters.OVERLAP_CHECK_CH_BUFFER_SHARED, shg.CAP_STYLE.square)
else:
boundaries[ac_filename] = translated_polygon
except IOError as reason:
logging.warning("Ignoring unreadable stg_entry %s", reason)
return boundaries
......@@ -225,7 +225,8 @@ C2P_STREETLAMPS_RESIDENTIAL_DISTANCE = 40
C2P_STREETLAMPS_OTHER_DISTANCE = 70
C2P_STREETLAMPS_MIN_STREET_LENGTH = 20
C2P_WIND_TURBINE_MAX_DISTANCE_FARM = 700
C2P_WIND_TURBINE_MAX_DISTANCE_WITHIN_WIND_FARM = 700
C2P_WIND_TURBINE_MIN_DISTANCE_SHARED_OBJECT = 10
# =============================================================================
# PARAMETERS RELATED TO landuse.py - might be replaced by another library
......
......@@ -435,10 +435,23 @@ def process_osm_wind_turbines(osm_nodes_dict: Dict[int, osmparser.Node], coords_
my_wind_turbines = list()
wind_farms = list()
# make sure no existing shared objects are duplicated. Do not care what shared obejct within distance
stg_entries = stg_io2.read_stg_entries_in_boundary()
# find relevant / valid wind turbines
for key, node in osm_nodes_dict.items():
if "generator:source" in node.tags and node.tags["generator:source"] == "wind":
if "generator:output:electricity" in node.tags:
# first check against existing
shared_within_distance = False
for entry in stg_entries:
if entry.verb_type is stg_io2.STGVerbType.object_shared:
if coordinates.calc_distance_global(entry.lon, entry.lat, node.lon, node.lat) < parameters.C2P_WIND_TURBINE_MIN_DISTANCE_SHARED_OBJECT:
logging.debug("Excluding turbine osm_id = {} due to overlap shared object.".format(node.osm_id))
shared_within_distance = True
break
if shared_within_distance:
continue
generator_output = osmparser.parse_generator_output(node.tags["generator:output:electricity"])
turbine = WindTurbine(key, node.lon, node.lat, generator_output, node.tags)
turbine.x, turbine.y = coords_transform.toLocal((node.lon, node.lat))
......@@ -457,7 +470,7 @@ def process_osm_wind_turbines(osm_nodes_dict: Dict[int, osmparser.Node], coords_
for j in range (i + 1, len(my_wind_turbines)):
if coordinates.calc_distance_local(my_wind_turbines[i].x, my_wind_turbines[i].y,
my_wind_turbines[j].x, my_wind_turbines[j].y) \
<= parameters.C2P_WIND_TURBINE_MAX_DISTANCE_FARM:
<= parameters.C2P_WIND_TURBINE_MAX_DISTANCE_WITHIN_WIND_FARM:
my_wind_farm = my_wind_turbines[i].wind_farm
if my_wind_farm is None:
my_wind_farm = WindFarm()
......
......@@ -282,7 +282,6 @@ def read_stg_entries(stg_path_and_name: str, consider_shared: bool = True, our_m
hdg = float(splitted[5])
entry = STGEntry(type_, obj_filename, path, lon, lat, elev, hdg)
entries.append(entry)
logging.debug("stg: %s %s", type_, entry.get_obj_path_and_name())
except ValueError as reason:
if not ignore_bad_lines:
logging.warning("stg_io:read: Damaged file %s", reason)
......@@ -303,6 +302,24 @@ def read_stg_entries(stg_path_and_name: str, consider_shared: bool = True, our_m
return entries
def read_stg_entries_in_boundary(consider_shared: bool = True) -> List[STGEntry]:
"""Returns a list of all STGEntries within the boundary according to parameters."""
stg_entries = list()
stg_files = calc_tile.get_stg_files_in_boundary(parameters.BOUNDARY_WEST, parameters.BOUNDARY_SOUTH,
parameters.BOUNDARY_EAST, parameters.BOUNDARY_NORTH,
parameters.PATH_TO_SCENERY, "Objects")
if parameters.PATH_TO_SCENERY_OPT is not None:
stg_files_opt = calc_tile.get_stg_files_in_boundary(parameters.BOUNDARY_WEST, parameters.BOUNDARY_SOUTH,
parameters.BOUNDARY_EAST, parameters.BOUNDARY_NORTH,
parameters.PATH_TO_SCENERY_OPT, "Objects")
stg_files.extend(stg_files_opt)
for filename in stg_files:
stg_entries.extend(read_stg_entries(filename, consider_shared))
return stg_entries
def _make_delimiter_string(our_magic: Optional[str], prefix: Optional[str], is_start: bool) -> str:
if our_magic is None:
magic = ""
......
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