🏢 Building taxonomy

Simplified building taxonomy of selected cities

Created during November 2024

Table of contents

Introduction

Plot simplified taxonomies of buildings across selected cities using PyData, QuackOSM and Metaflow.

#30DayMapChallenge | Day 3: Polygons | 2024 (see: "30DayMapChallenge" official Github repo )

Recently I saw a post by Daniel Gorokhov who illustrated building taxonomy of "interesting buildings" in Milano, Italy, Stockholm, Sweden and Amsterdam, Nethedlands. Here is my extension for that post, with some more cities, mostly in USA, but also in Europe.

Chart type is "small multiple" (a.k.a. "grid chart"). How was it made? I run a script that loaded all mapped buildings within city area and counted exterior vertices (nodes) for all of them. Still, I did not explicitly count inner polygons, like courtyards or patios. Then, I took one hundred of buildings with the most nodes to plot them.

  1. Yet, it happened that under current methodology, quite often, "interesting" buildings are repetitive because of construction nature (for example - neighborhoods of apartment buildings or high-rise housing projects; industrial structures, like water treatment ponds, fuel storages, dockside cranes)
  2. Yet, it happened that under current methodology, quite often, "interesting" buildings are repetitive because of construction nature (for example - neighborhoods of apartment buildings or high-rise housing projects; industrial structures, like water treatment ponds, fuel storages, dockside cranes)

Made with #Python
Data: #OSM, #OpenStreetMap retrieved with QuackOSM
#dataviz #datavisualization

Inspiration: "building taxonomy of Milano, Stockholm and Amsterdam" by Daniel Gorokhov

Further works: "Visualizing a building shapes taxonomy - The City Summit 🏙️🗻 project" by Kamil Raczycki

Method ?

The chart is a small multiple (grid chart):

  • Extract all mapped buildings within each city boundary.
  • Count exterior vertices (nodes) for each building polygon (inner courtyards/patios not explicitly counted).
  • Plot the 100 buildings with the most nodes.

Key caveats:

  1. Under this methodology, “interesting” buildings can be repetitive due to construction patterns (housing projects, industrial structures, etc.).
  2. Some truly complex structures aren’t mapped well and require case-by-case handling (multi-buildings, connections, etc.).
🏗️ How-to: Make this product
Click or tap to open section
★ Click to see code snippets
python
import metaflow
  from metaflow import FlowSpec, Parameter, JSONType, step, NBRunner, pypi

  import quackosm as qosm

  import time
  import datetime

  import numpy as np
  import geopandas as gpd
  import matplotlib
  import matplotlib.pyplot as plt
Pipeline sketch (Metaflow)
python
def _func_count_vertices(row_index, row_values_series):
    """
        * https://gis.stackexchange.com/questions/328884/counting-number-of-vertices-in-geopandas
        * https://gis.stackexchange.com/questions/388606/counting-vertices-and-adding-it-as-number-to-column-using-shapely
    """
    geometry = row_values_series.geometry
    geom_type = geometry.geom_type

    n_vertices = 0
    #try:
    if geom_type == "Polygon":
        n_vertices = len(geometry.exterior.coords)
    elif geom_type == "MultiPolygon":
        for inner_geometry in list(geometry.geoms):
            n_vertices += len(inner_geometry.exterior.coords)
    else:
        None
        #print("- Other type of geometry: ", geom_type, row_index)
    #except:
        #print("- There was unexpected error with row: ", row_index)

    return n_vertices
Pipeline sketch (Metaflow)
python
def _func_count_vertices(row_index, row_values_series):
    """
        * https://gis.stackexchange.com/questions/328884/counting-number-of-vertices-in-geopandas
        * https://gis.stackexchange.com/questions/388606/counting-vertices-and-adding-it-as-number-to-column-using-shapely
    """
    geometry = row_values_series.geometry
    geom_type = geometry.geom_type

    n_vertices = 0
    #try:
    if geom_type == "Polygon":
        n_vertices = len(geometry.exterior.coords)
    elif geom_type == "MultiPolygon":
        for inner_geometry in list(geometry.geoms):
            n_vertices += len(inner_geometry.exterior.coords)
    else:
        None
        #print("- Other type of geometry: ", geom_type, row_index)
    #except:
        #print("- There was unexpected error with row: ", row_index)

    return n_vertices
Pipeline sketch (Metaflow)
python
def _func_count_vertices(row_index, row_values_series):
    """
        * https://gis.stackexchange.com/questions/328884/counting-number-of-vertices-in-geopandas
        * https://gis.stackexchange.com/questions/388606/counting-vertices-and-adding-it-as-number-to-column-using-shapely
    """
    geometry = row_values_series.geometry
    geom_type = geometry.geom_type

    n_vertices = 0
    #try:
    if geom_type == "Polygon":
        n_vertices = len(geometry.exterior.coords)
    elif geom_type == "MultiPolygon":
        for inner_geometry in list(geometry.geoms):
            n_vertices += len(inner_geometry.exterior.coords)
    else:
        None
        #print("- Other type of geometry: ", geom_type, row_index)
    #except:
        #print("- There was unexpected error with row: ", row_index)

    return n_vertices

Method ?

The chart is a small multiple (grid chart):

  1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt, nunc eu interdum pharetra, turpis mi pellentesque mi, ac eleifend nunc orci eu diam. Phasellus consequat sed ipsum non suscipit. Sed tortor leo, pulvinar in odio quis, condimentum lacinia dui. Suspendisse ligula risus, iaculis vel sapien at, pretium tristique mauris. Nulla ac nunc fermentum, aliquet tortor quis, aliquam sapien. Nunc sodales lacinia ante eget maximus. Nullam placerat ligula vel tellus blandit porttitor. Nullam quis tempor orci. Proin non orci vel lectus finibus pellentesque quis at elit. In ultricies diam a mauris porta, porta scelerisque felis lacinia. Nulla ligula arcu, interdum at felis id, ultricies facilisis orci. Ut sollicitudin hendrerit est quis congue. Nullam auctor auctor ligula.
  2. Cras in mauris ut quam ullamcorper mollis. Sed augue diam, suscipit eu ex quis, rhoncus tempus nisi. Sed purus purus, consequat in mattis eu, mattis nec lorem. Vivamus imperdiet hendrerit leo, at varius sapien tempor ut. Fusce ut leo sit amet nunc suscipit vulputate. Integer nec pretium mi. Morbi in nisi velit. Nam a semper purus.
  3. Generated 5 paragraphs, 369 words, 2457 bytes of Lorem Ipsum

example link


Media presence

How to cite this work

For human-readable attribution, please cite this work as:

Visualization “Ukraine's bloody tool” (2025), Vitaliy Y from Witold's Data Consulting
https://witold1.github.io/blog/posts/small-project-blood-tool/post

BibTeX

@misc{witold_blog_viz-building-taxonomy,
  author = {Yevtushenko, Vitaliy},
  title = {{🏢 Building taxonomy}},
  year = {2024},
  url = {/portfolio/blog/viz-building-taxonomy/},
}
Discuss with AI
PerplexityChatGPTClaudeGemini
Share