Skip to content
Snippets Groups Projects
Commit a7062d3d authored by Laurens Oostwegel's avatar Laurens Oostwegel Committed by Laurens Oostwegel
Browse files

Add processing rules

parent 05912aa5
No related branches found
No related tags found
No related merge requests found
Pipeline #65077 passed
This commit is part of merge request !4. Comments created here will be created in the context of that merge request.
Showing with 171 additions and 6 deletions
......@@ -25,7 +25,6 @@ linters:
script:
- flake8 --max-line-length=$LINE_LENGTH $SOURCES
- black --check --line-length $LINE_LENGTH $SOURCES
- pylint -E $SOURCES
release_job:
stage: release
......
class GeometryRule:
def __call__(self, geometry, *args, **kwargs):
"""
Wrap the WKT formatted geometry of a building in the `ST_GeomFromText()` function
Args:
geometry (str):
WKT formatted geometry of the building
Returns:
A dictionary with the WKT formatted geometry of the building wrapped in the
`ST_GeomFromText()` function.
"""
return {"geometry": f"ST_GeomFromText('{geometry}', 4326)"}
<?xml version="1.0" encoding="UTF-8" ?>
<rule name="GeometryRule">
<input>
<param type="str">geometry</param>
</input>
<function filepath="geometry.py"/>
<output>
<param type="str">geometry</param>
</output>
</rule>
class QuadkeyRule:
def __call__(self, longitude, latitude, *args, **kwargs):
"""
Determine the Quadkey of the tile in which the building centroid is located given its
longitude and latitude.
Args:
longitude:
Longitude of the building centroid
latitude:
Latitude of the building centroid
Returns:
A dictionary with the zoom-level 18 Quadkey.
"""
import mercantile
if longitude is None or latitude is None:
quadkey = None
else:
quadkey = mercantile.quadkey(mercantile.tile(longitude, latitude, 18))
return {"quadkey": quadkey}
<?xml version="1.0" encoding="UTF-8" ?>
<rule name="QuadkeyRule">
<input>
<param type="float">longitude</param>
<param type="float">latitude</param>
</input>
<function filepath="quadkey.py"/>
<output>
<param type="str">quadkey</param>
</output>
</rule>
class RelationIDRule:
def __call__(self, relations, *args, **kwargs):
"""
Determine the building relation OSM ID.
Args:
relations:
List of the attributes of all relations that the building is member of.
Returns:
OSM ID of the first relation that the building is member of.
"""
for relation in relations:
osm_id = relation.get("osm_id", None)
if osm_id is not None:
return {"relation_id": osm_id}
return {"relation_id": None}
<?xml version="1.0" encoding="UTF-8" ?>
<rule name="RelationIDRule">
<input>
<param type="list">relations</param>
</input>
<function filepath="relation_id.py"/>
<output>
<param type="int">relation_id</param>
</output>
</rule>
<?xml version="1.0" encoding="UTF-8" ?>
<rule name="StoriesAndFloorspaceRule" category="building">
<input>
<param type="int">tags</param>
<param type="float">relations</param>
<param type="float">area</param>
</input>
<function filepath="stories_and_floorspace.py"/>
<output>
<param type="float">storeys</param>
<param type="float">floorspace</param>
</output>
</rule>
class StoriesAndFloorspaceRule:
def __call__(self, tags, relations, area, *args, **kwargs):
"""
Find the `building:levels` tag in the attributes of the building or one of the building
relations and save this as the number of stories. Calculate the floorspace of the
building, based on the footprint size of the building and the number of stories.
Args:
tags (dict):
Building tags, such has the building levels or building type.
relations (list):
List of the attributes of all relations that the building is member of.
area (float):
Footprint size of the building.
Returns:
A dictionary with the number of stories and the floorspace of the building.
"""
from math import ceil
story_options = [self.get_info(building["tags"]) for building in [tags] + relations]
for story_string in story_options:
if story_string is None or story_string == "":
continue
try:
stories = ceil(float(story_string))
if stories < 1:
raise ValueError("Number of stories cannot be below 1")
floorspace = stories * area
return {"stories": stories, "floorspace": floorspace}
except ValueError:
continue
return {"stories": None, "floorspace": None}
@staticmethod
def get_info(tags):
"""
Get the number of stories, if the attribute `building:levels` exist
Args:
tags:
Building tags, such as the building levels or building type.
Returns:
Number of stories, if the attribute `building:levels` exist, otherwise `None`.
"""
return tags.get("building:levels", None)
......@@ -6,7 +6,7 @@ class ObmBuildingsUpsert:
osm_id,
floorspace=None,
occupancy=None,
storeys=None,
stories=None,
relation_id=None,
quadkey=None,
*args,
......@@ -27,7 +27,7 @@ class ObmBuildingsUpsert:
The calculated floorspace of the building.
occupancy (str):
The occupancy type formatted to the GEM occupancy types.
storeys (int):
stories (int):
Number of stories in the building.
relation_id (int):
ID of the OSM relation feature that this building is part of.
......@@ -44,7 +44,7 @@ class ObmBuildingsUpsert:
{geometry},
{self.format_value(floorspace)},
{self.format_value(occupancy)},
{self.format_value(storeys)},
{self.format_value(stories)},
{self.format_value(relation_id)},
{self.format_value(quadkey)},
NOW()
......
......@@ -6,7 +6,7 @@
<param type="int">osm_id</param>
<param type="float">floorspace</param>
<param type="str">occupancy</param>
<param type="int">storeys</param>
<param type="int">stories</param>
<param type="int">relation_id</param>
<param type="str">quadkey</param>
</input>
......
......@@ -10,7 +10,23 @@ all land-use objects that intersect the building.
### Process rules
*Not implemented*
* **Geometry**
Wrap the WKT formatted geometry of a building in the `ST_GeomFromText()` function
* **Quadkey**
Determine the Quadkey tile of a building, based on the latitude and longitude of the centroid.
* **RelationID**
Determine the building relation OSM ID.
* **StoriesAndFloorspace**
Find the `building:levels` tag in the attributes of the building or one of the building
relations and save as number of stories. Calculate the floorspace of the building, based on the
footprint size of the building and the number of stories.
### Upsert rules
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment