Commit 18a423a9 authored by Rick Gruber-Riemer's avatar Rick Gruber-Riemer

* Documentation of building generation parameters.

* Make sure that BTG landuse types are used for generated land-use where possible.
parent b853fa32
......@@ -440,7 +440,9 @@ It is possible to let ``osm2city`` generate buildings, where it is plausible tha
A lot of processing is dependent on land-use information (see e.g. :ref:`Land-use Handling <chapter-howto-land-use-label>` and :ref:`Land-use Parameters <chapter-parameters-landuse-label>`). For a short explanation of the process used see :ref:`Generate Would-Be Buildings <chapter-howto-generate-would-be-buildings-label>`.
In rural and periphery settlement areas an attempt is made to have the same terrace houses or apartment buildings along both sides of a way
In rural and periphery settlement areas an attempt is made to have the same terrace houses or apartment buildings along both sides of a way.
The first set of parameters determines the overall placement heuristics:
============================================= ======== ======= ==============================================================================
Parameter Type Default Description / Example
......@@ -453,20 +455,12 @@ OWBB_USE_EXTERNAL_LANDUSE_FOR_B.._GENERATION Boolean True External la
land-use is available. Currently this only land-use from FlightGear (parameter
``OWBB_USE_BTG_LANDUSE``), which is why most probably plausible buildings
should be generated.
OWBB_RESIDENTIAL_RURAL_TERRACE_SHARE Decimal 0.1 The share of terraces / row houses in rural settlement areas.
OWBB_RESIDENTIAL_PERIPHERY_TERRACE_SHARE Decimal 0.25 Ditto in periphery settlement areas.
OWBB_RESIDENTIAL_RURAL_APARTMENT_SHARE Decimal 0.1 The share of apartment buildings in rural settlement areas.
OWBB_RESIDENTIAL_PERIPHERY_APARTMENT_SHARE Decimal 0.3 Ditto in periphery settlement areas.
OWBB_RESIDENTIAL_DENSE_SHARE_APARTMENT Decimal 0.3 For generated buildings there are only apartments in residential areas in
dense, but there is still a share of detached instead of attached buildings.
OWBB_STEP_DISTANCE Integer 2 How many meters along the way to travel before trying to set a building again.
Smaller values might be more accurate, but also increase processing time.
OWBB_MIN_STREET_LENGTH Integer 10 How long a way needs to be at least to be considered for generating buildings
along.
OWBB_MIN_CITY_BLOCK_AREA Integer 200 The minimal area of a city block along a way to be considered for generating
buildings.
OWBB_RESIDENTIAL_HIGHWAY_MIN_GEN_SHARE Decimal 0.3 If there are already buildings along the way: what is the minimal share of
an uninterrupted length along the way to consider for terraces or apartments
(detached houses might still be "built").
......@@ -476,6 +470,60 @@ OWBB_ZONE_AREA_MAX_GEN Decimal 0.1 If the shar
============================================= ======== ======= ==============================================================================
The second set of parameters determines the type of residential buildings to use and the distances between the buildings and the street as well as what happens in the backyard. The ``width`` of a building is along the street, the ``depth`` of a building is away from the street (front door to back door).
============================================= ======== ======= ==============================================================================
Parameter Type Default Description / Example
============================================= ======== ======= ==============================================================================
OWBB_RESIDENTIAL_RURAL_TERRACE_SHARE Decimal 0.1 The share of terraces / row houses in rural settlement areas. Most houses are
detached, which is the default.
OWBB_RESIDENTIAL_PERIPHERY_TERRACE_SHARE Decimal 0.25 Ditto in periphery settlement areas.
OWBB_RESIDENTIAL_RURAL_APARTMENT_SHARE Decimal 0.1 The share of apartment buildings in rural settlement areas.
OWBB_RESIDENTIAL_PERIPHERY_APARTMENT_SHARE Decimal 0.3 Ditto in periphery settlement areas.
OWBB_RESIDENTIAL_DENSE_TYPE_SHARE Dict In dense areas not everything is attached like in block or centre settlement
areas. It can be quite region specific. Therefore there is quite a choice for
specifying the distribution. E.g.
``{'detached': 0.1, 'terraces': 0.1, 'apartments': 0.3, 'attached': 0.5}``.
OWBB_RESIDENTIAL_TERRACE_MIN_NUMBER Integer 4 The minimum number of terrace houses to fit along a street before it is
considered to build terraces along the way.
OWBB_RESIDENTIAL_TERRACE_TYPICAL_NUMBER Integer 5 The typical number of terrace houses attached to each other before there will
be a break. The actual number is randomized around this value.
OWBB_RESIDENTIAL_SIDE_FACTOR_PERIPHERY Decimal 1.0 The default buffer on the side of detached houses and apartment houses is
the sqaure root of the house's width. So the distance between two houses gets
the square root of the one house's width plus the square root of the other
house's width. This factor is multiplied to allow some linear correction for
region specific adaptation. E.g. in Switzerland the houses tend to be farther
apart along the street than in Denmark (the opposite is true for the
backyard). This factor is used for rural and periphery settlement types.
OWBB_RESIDENTIAL_SIDE_FACTOR_DENSE Decimal 0.8 Ditto for dense settlement type. Attached houses and terrace houses have a
distance of ca. 0 (it is not exactly 0 due to the way placements are made
in the heuristics - but close enough; you can play with the step distance).
OWBB_RESIDENTIAL_BACK_FACTOR_PERIPHERY Decimal 2.0 Same as the ..SIDE_FACTOR.., but now for the back. Again the starting point
is a square root - this time of the building's depth.
OWBB_RESIDENTIAL_FRONT_FACTOR_PERIPHERY Decimal 1.0 Same as the ..SIDE_FACTOR.., but now for the back. The starting point is
the square root of the building's width.
OWBB_FRONT_DENSE Decimal 3.0 The distance in metres between the street and the front. Same for settlement
types ``dense``, ``block`` and ``centre``.
============================================= ======== ======= ==============================================================================
Finally a set of parameters for industrial buildings:
============================================= ======== ======= ==============================================================================
Parameter Type Default Description / Example
============================================= ======== ======= ==============================================================================
OWBB_INDUSTRIAL_LARGE_MIN_AREA Integer 500 The minimal number of square metres for an industrial building being
considered large.
OWBB_INDUSTRIAL_LARGE_SHARE Decimal 0.4 If the building zone type is industrial, then this share is used between
large buildings and smaller buildings.
OWBB_INDUSTRIAL_BUILDING_SIDE_MIN Decimal 2.0 The minimal buffer around a building - so the total distance between two
industrial buildings is at least twice this value. The actual value used is
chosen randomly between the .._SIDE_MIN and .._SIDE_MAX.
OWBB_INDUSTRIAL_BUILDING_SIDE_MAX Decimal 5.0 See above.
============================================= ======== ======= ==============================================================================
.. _chapter-parameters-roads:
......
......@@ -84,8 +84,7 @@ def _generate_building_zones_from_buildings(building_zones: List[m.BuildingZone]
break
if not within_existing_building_zone:
my_candidate = m.GeneratedBuildingZone(op.get_next_pseudo_osm_id(op.OSMFeatureType.landuse),
buffer_polygon, m.BuildingZoneType.non_osm,
True)
buffer_polygon, m.BuildingZoneType.non_osm)
my_candidate.relate_building(my_building)
zones_candidates[my_candidate.osm_id] = my_candidate
logging.debug("Candidate land-uses found: %s", len(zones_candidates))
......@@ -151,8 +150,7 @@ def _split_multipolygon_generated_building_zone(zone: m.GeneratedBuildingZone) -
logging.debug("Handling a generated land-use Multipolygon with %d polygons", len(zone.geometry.geoms))
for split_polygon in zone.geometry.geoms:
my_split_generated = m.GeneratedBuildingZone(op.get_next_pseudo_osm_id(op.OSMFeatureType.landuse),
split_polygon,
zone.type_, zone.from_buildings)
split_polygon, zone.type_)
new_generated.append(my_split_generated)
while len(zone.osm_buildings) > 0:
my_building = zone.osm_buildings.pop()
......
......@@ -490,12 +490,28 @@ class BTGBuildingZone(object):
class GeneratedBuildingZone(BuildingZone):
"""A fake OSM Land-use for buildings based on heuristics"""
def __init__(self, generated_id, geometry, building_zone_type, from_buildings=False) -> None:
def __init__(self, generated_id, geometry, building_zone_type) -> None:
super().__init__(generated_id, geometry, building_zone_type)
self.from_buildings = from_buildings # False for e.g. external land-use
self.from_buildings = self.type_ is BuildingZoneType.non_osm
def guess_building_zone_type(self, farm_places: List[Place]):
"""Based on some heuristics of linked buildings guess the building zone type"""
# first we try to map directly BTG zones to OSM zones
if self.type_ in [BuildingZoneType.btg_suburban, BuildingZoneType.btg_town, BuildingZoneType.btg_urban,
BuildingZoneType.btg_builtupcover]:
self.type_ = BuildingZoneType.residential
return
if self.type_ in [BuildingZoneType.btg_port, BuildingZoneType.btg_industrial,
BuildingZoneType.btg_construction]:
self.type_ = BuildingZoneType.industrial
return
# now we should only have non_osm based on lonely buildings
if self.type_ is not BuildingZoneType.non_osm:
logging.error('Should be of type "non_osm", but actually is: %s. Programming logic error!',
self.type_.name)
exit(1)
residential_buildings = 0
commercial_buildings = 0
industrial_buildings = 0
......@@ -897,6 +913,7 @@ class SharedModel(object):
else:
self._side_buffer = math.sqrt(self.width) * parameters.OWBB_RESIDENTIAL_SIDE_FACTOR_PERIPHERY
self._back_buffer = math.sqrt(self.depth) * parameters.OWBB_RESIDENTIAL_BACK_FACTOR_PERIPHERY
self._front_buffer = math.sqrt(self.width) * parameters.OWBB_RESIDENTIAL_FRONT_FACTOR_PERIPHERY
# terraces
if self.building_model.model_type is bl.BuildingType.terrace:
self._side_buffer = 0.0
......@@ -956,9 +973,6 @@ class SharedModel(object):
class SharedModelsLibrary(object):
INDUSTRIAL_LARGE_MIN_AREA = 500 # FIXME: should be a parameter
def __init__(self, building_models: List[BuildingModel]):
self._residential_detached = list()
self._residential_terraces = list()
......@@ -1008,7 +1022,7 @@ class SharedModelsLibrary(object):
self._residential_terraces.append(a_model)
elif building_model.model_type is bl.BuildingType.industrial:
a_model = SharedModel(building_model)
if building_model.area > self.INDUSTRIAL_LARGE_MIN_AREA:
if building_model.area > parameters.OWBB_INDUSTRIAL_LARGE_MIN_AREA:
self._industrial_buildings_large.append(a_model)
else:
self._industrial_buildings_small.append(a_model)
......
......@@ -347,18 +347,20 @@ OWBB_RESIDENTIAL_RURAL_APARTMENT_SHARE = 0.1
OWBB_RESIDENTIAL_PERIPHERY_APARTMENT_SHARE = 0.3
OWBB_RESIDENTIAL_DENSE_TYPE_SHARE = {'detached': 0.1, 'terraces': 0.1, 'apartments': 0.3, 'attached': 0.5}
OWBB_RESIDENTIAL_TERRACE_MIN_NUMBER = 4
OWBB_RESIDENTIAL_TERRACE_TYPICAL_NUMBER = 5
OWBB_RESIDENTIAL_SIDE_FACTOR_PERIPHERY = 1.0
OWBB_RESIDENTIAL_SIDE_FACTOR_DENSE = 0.8
OWBB_RESIDENTIAL_BACK_FACTOR_PERIPHERY = 2.0
OWBB_RESIDENTIAL_FRONT_FACTOR_PERIPHERY = 1.0
OWBB_FRONT_DENSE = 3.0 # same for BLOCK and CENTRE
OWBB_RESIDENTIAL_TERRACE_MIN_NUMBER = 4
OWBB_RESIDENTIAL_TERRACE_TYPICAL_NUMBER = 5
OWBB_INDUSTRIAL_LARGE_MIN_AREA = 500
OWBB_INDUSTRIAL_LARGE_SHARE = 0.4
OWBB_INDUSTRIAL_BUILDING_SIDE_MIN = 2.0
OWBB_INDUSTRIAL_BUILDING_SIDE_MAX = 5.0
OWBB_FRONT_DENSE = 3.0 # same for BLOCK and CENTRE
# ==================== BUILDINGS LIBRARY ============
ALLOW_EMPTY_REGIONS = True
......
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