Skip to main content

spacematrix

PyPI version Python versions CI License: MIT

Urban density indicators after Berghauser Pont & Haupt's Spacematrix (2010).

spacematrix measures building intensity (FSI), coverage (GSI), spaciousness (OSR), average storeys (L), network density (N) and tare (T) for lots, islands (urban blocks), fabrics and districts from building footprints, plot/block polygons and street centrelines. It classifies samples into Spacematrix building types, draws the Spacemate diagram with iso-L and iso-OSR lines, and relates the indicators to dwelling density and to the Turkish TAKS / KAKS (emsal) rules.

The core runs on the Python standard library alone (pure-Python polygon area, exact polygon overlap and line clipping). shapely and matplotlib are optional.

pip install spacematrix                # stdlib only
pip install "spacematrix[plot]"        # + Spacemate diagram (matplotlib)
pip install "spacematrix[shapely]"     # + shapely overlap backend
pip install "spacematrix[all]"

Requires Python 3.9 or newer.


Quick start

import spacematrix as sm

lot = sm.Zone(sm.Polygon.rectangle(0, 0, 20, 30), id="lot-1")            # 600 m2
house = sm.Building(sm.Polygon.rectangle(5, 5, 15, 17), floors=3)          # 120 m2 x 3

r = sm.measure(lot, [house], level="lot")
r.fsi, r.gsi, r.osr, r.l      # (0.6, 0.2, 1.333, 3.0)
r.type                        # 'low-rise strip'  (approximate thresholds, see below)

A whole hierarchy, from GeoJSON layers in a projected (metric) CRS:

buildings = sm.read_buildings("buildings.geojson", floors_field="floors")  # or height_field=
res = sm.analyze(
    buildings,
    lots=sm.read_zones("lots.geojson"),
    islands=sm.read_zones("blocks.geojson"),
    fabrics=sm.read_zones("fabrics.geojson"),     # bounded by street centrelines
    network=sm.read_network("streets.geojson"),
)
for f in res.fabrics:
    print(f.id, f.fsi, f.gsi, f.n, f.tare, f.mesh_size, f.profile_width, f.type)
sm.write_csv(res.records(), "density.csv")

The Spacemate:

from spacematrix.plot import spacemate
ax = spacemate(res.islands, type_grid=sm.DEFAULT_THRESHOLDS)
ax.figure.savefig("spacemate.png", dpi=150)

Command line

spacematrix metrics --floor-area 76800 --built-area 19200 --area 40000 \
    --interior-length 400 --edge-length 800 --lower-area 25600
spacematrix grid --w 100 --b 20                      # N and T of an orthogonal grid
spacematrix taks-kaks --taks 0.30 --kaks 1.50 --exempt-share 0.2 \
    --island-tare 0.1 --fabric-tare 0.3
spacematrix analyze --buildings b.geojson --lots lots.geojson --islands blocks.geojson \
    --fabrics fabrics.geojson --network streets.geojson --height-field height \
    --out density.csv --plot spacemate.png
spacematrix diagram density.csv -o islands.png --level island

python examples/quickstart.py reproduces the worked grid example below.

API overview

Area Names
Inputs Polygon, Building (floors or Building.from_height), Zone, Network, floors_from_height
Indicators fsi, gsi, osr, layers, network_density, tare, upscale, mesh_size, grid_network_density, grid_tare, profile_width, fsi_from_gsi_l, fsi_from_gsi_osr
Measurement measure(zone, buildings, level=..., network=..., lower_level=...), analyze(...) → SpacematrixResult, aggregate(records); records are Density objects with as_dict()
Types classify(fsi, gsi, thresholds), TypeThresholds, DEFAULT_THRESHOLDS, THRESHOLDS_VERIFIED (= False)
Other measures dwelling_density, coverage_percent, dwellings_from_fsi, fsi_from_dwelling_density, population_density, fsi_from_kaks, kaks_from_fsi, taks_kaks_equivalent, TAKS_KAKS_NOTE
Geometry / IO shape_area, intersection_area (backend="python" or "shapely"), split_line_length, read_buildings, read_zones, read_network, write_csv, write_geojson
Diagram spacematrix.plot.spacemate(samples, type_grid=..., iso_l=..., iso_osr=...)

Method and sources

Definitions from Berghauser Pont, M. and Haupt, P. (2010), Spacematrix: Space, Density and Urban Form, Rotterdam: NAi Publishers. F gross floor area, B built-up (footprint) area, A plan area of level x:

Indicator Formula Notes
FSI F / A floor space index (intensity)
GSI B / A ground space index (coverage)
OSR (1 − GSI) / FSI unbuilt ground per m² of floor area (spaciousness)
L FSI / GSI average number of storeys
N (l_i + l_e / 2) / A_f m of street per m² of fabric; edge streets (on the fabric boundary) count half
T (A_x − A_y) / A_x tare: share of level x not taken by the lower level y
w 2 / N mesh size of the equivalent orthogonal grid
b 2 (1 − √(1 − T)) / N profile width; inverse of T = (2bw − b²) / w²

Levels: lot (plot) ⊂ island (block, island tare = internal paths and communal space) ⊂ fabric (islands plus the streets around them, bounded by street centrelines; fabric tare ≈ street space) ⊂ district (plus large parks, water, infrastructure). Tare lowers FSI and GSI by the same factor (FSI_x = FSI_y (1 − T_x)), so L is the same at every level.

Building floor area is footprint × floors (or a measured value). Floors can be estimated from height with a configurable storey height (default 3.0 m, a convention, not a standard). Buildings are allocated to zones by footprint overlap (exact, buildings straddling a boundary are split) or by centroid.

Worked example (tested)

Orthogonal 2 × 2 grid, street centrelines every 100 m (w = 100 m), 20 m profiles (b = 20 m), 80 × 80 m islands each with a four-storey perimeter block around a 40 × 40 m courtyard:

Level A (m²) FSI GSI OSR L N (m/m²) T
island 6 400 3.00 0.75 0.083 4 – –
fabric 40 000 1.92 0.48 0.271 4 0.02 (= 2/w) 0.36 (= (2bw−b²)/w²)

profile_width(0.36, 0.02) = 20 m recovers b.

Building types

classify assigns one of nine types — low-/mid-/high-rise × point/strip/block — from L (height class; bands between iso-L rays) and GSI (form class). The book identifies these types as clusters in the Spacemate; the numeric cut-offs used here (L ≤ 3.5 low-rise, L ≤ 7.5 mid-rise; GSI < 0.20 point, GSI < 0.35 strip, otherwise block) are approximations that were not verified against the book. They are fields of TypeThresholds; calibrate them to your own reference samples or a cluster analysis (Berghauser Pont & Olsson, 2017, ISUF Valencia). Classify island-level values: analyze classifies fabrics from their net values FSI/(1−T), GSI/(1−T) to avoid the tare shift.

Other density measures and TAKS / KAKS

Dwelling density (dwellings/ha) depends on dwelling size and the residential share of floor area, so dwellings_from_fsi / fsi_from_dwelling_density make the conversion explicit. Coverage is 100 × GSI.

The Turkish Planlı Alanlar İmar Yönetmeliği (RG 30113, 3 July 2017, as amended; mevzuat.gov.tr no. 23722) defines in Article 4 TAKS = taban alanı / imar parseli alanı (cccc) and KAKS (emsal) = sum of floor areas / imar parseli alanı (tt), where floor area (katlar alanı, şş) excludes the areas of Article 22. Article 20(5) applies the base area to the net parcel and Article 5(8) caps all emsal-exempt areas at 30 % of the emsal area. Therefore:

  • TAKS ≈ GSI_lot and KAKS ≈ FSI_lot — both are lot-level (net) ratios;
  • gross FSI_lot = KAKS × (1 + e) with exempt share 0 ≤ e ≤ 0.30;
  • island/fabric values need the tares: taks_kaks_equivalent(taks, kaks, exempt_share=e, island_tare=T_i, fabric_tare=T_f);
  • plan values are permitted maxima, not the built stock.

Limitations

  • Coordinates must be projected and metric; the readers refuse data that looks like longitude/latitude (override with allow_geographic=True). No reprojection.
  • Pure-Python overlaps are O(buildings × zones) with a bounding-box filter; fine for neighbourhoods and districts, use backend="shapely" for larger sets. Polygons must be valid (simple rings, holes inside the exterior, parts of a multipolygon not overlapping).
  • Edge streets are detected as centreline pieces within edge_tolerance (1 cm by default) of the zone boundary; draw fabric boundaries on the centrelines.
  • Network density at district level uses the same rule as at fabric level.
  • Type thresholds are approximate (see above); THRESHOLDS_VERIFIED is False.
  • Floors from height assume a uniform storey height; basements are not counted.

Academic citation

@software{eminoglu_spacematrix,
  author  = {Eminoğlu, Yusuf},
  title   = {spacematrix},
  year    = {2026},
  version = {0.1.1},
  url     = {https://github.com/YusufEminoglu/spacematrix_sdk}
}

Please also cite the method: Berghauser Pont, M. and Haupt, P. (2010). Spacematrix: Space, Density and Urban Form. Rotterdam: NAi Publishers.

License

MIT © 2026 Yusuf Eminoğlu. Contact: geospacephilo@gmail.com

Metadata

Release files for spacematrix 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spacematrix 0.1.1
File Size Uploaded Provenance Actions
spacematrix-0.1.1.tar.gz 44.8 kB With provenance Details for spacematrix-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for spacematrix 0.1.1
File Interpreter ABI Platform Actions
spacematrix-0.1.1-py3-none-any.whl Python 3 none any Details for spacematrix-0.1.1-py3-none-any.whl

Total release size: 79.8 kB

Release files / spacematrix-0.1.1.tar.gz

Download URL spacematrix-0.1.1.tar.gz
Size 44.8 kB
Tags Source
SHA-256 checksum
How to use checksums
82fd5c0ebac65147d8bd68e78daea4a157fdd0910338c9517f7b63bade9293dd
BLAKE2b-256 checksum
How to use checksums
23e7b2888120ebf3222f72a1de82d63e618adba5b6b67d5bd3f41ec3b2768376
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.

Transparency log

Release files / spacematrix-0.1.1-py3-none-any.whl

Download URL spacematrix-0.1.1-py3-none-any.whl
Size 35.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6d2128227a24ca91a09decc6567098084450eadaf104bf423a38f1be87d30910
BLAKE2b-256 checksum
How to use checksums
1beb00d1f4209d0239d2d6da873032d3b8ac8c37f5b1dda1088543c5753d2001
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.

Transparency log

Security for spacematrix 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for spacematrix-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page