Zoning Primitives

This page describes the zone objects used by GenPlanner to define zoning goals, constraints, and presets. Zones are lightweight Python objects (hashable and orderable) that are used as keys in ratio mappings and as identifiers across the pipeline.

Overview

GenPlanner uses four main zone classes:

  • Zone: abstract base interface for all zones.

  • BasicZone: minimal zone identified only by its name.

  • TerritoryZone: a concrete territorial zone type (kind + name + min block area).

  • FunctionalZone: a composite zone describing the desired mix of territorial zones.

Note

GenPlan and gen_plan exist in the codebase but are intentionally not documented here.


Zone (abstract base)

Zone defines the minimal interface and shared behavior for all zone types:

  • name: a human-readable identifier.

  • min_area: generic minimum area constraint (defaults to 1.0).

  • hash + ordering: zones are comparable and hashable by (name, min_area).

Example: ordering and hashing

from genplanner.zones import Zone, BasicZone

a = BasicZone("block_a")
b = BasicZone("block_b")

assert a != b
assert a < b  # ordering by (name, min_area)
s = {a, b}    # hashable -> can be used in sets / dict keys

BasicZone

BasicZone is a minimal concrete implementation of Zone that only stores a non-empty string name. It is typically used for technical or intermediate concepts (e.g., generated blocks).

Example

from genplanner.zones import BasicZone

z = BasicZone("block_1")
print(z)  # Zone "block_1"

TerritoryZoneKind

TerritoryZoneKind is an enum of supported territorial zone kinds. Its values are stable string identifiers used in outputs and configuration.

Example

from genplanner.zones.territory_zones import TerritoryZoneKind

assert TerritoryZoneKind.RESIDENTIAL.value == "residential"

Relation matrix and kind-based rules

Territorial zone kinds are also used to derive adjacency constraints. See Zone Relations for details on how forbidden neighborhood rules are converted into a symmetric relation matrix using ZoneRelationMatrix.from_kind_forbidden.

TerritoryZone

TerritoryZone is the core unit of territorial zoning. It defines:

  • kind: one of TerritoryZoneKind

  • name: a non-empty name used as an identifier in outputs and in fixed points

  • min_block_area: a positive number controlling minimum block size for that zone

For compatibility with generic constraints, TerritoryZone.min_area is defined as min_block_area. kind can be provided as an enum or a value convertible to it (it is coerced on validation).

Example: custom territorial zone

from genplanner.zones import TerritoryZone
from genplanner.zones.territory_zones import TerritoryZoneKind

tech_park = TerritoryZone(
    kind=TerritoryZoneKind.BUSINESS,
    name="tech_park",
    min_block_area=50_000,
)

print(tech_park)  # Territory zone "tech_park" (business)

Example: coercing kind from string

from genplanner.zones import TerritoryZone

# kind may be coerced from string values
z = TerritoryZone(kind="residential", name="res", min_block_area=10_000)
assert z.kind.value == "residential"

FunctionalZone

FunctionalZone describes a program (mix) of territorial zones using target area ratios. It stores a mapping:

{TerritoryZone -> ratio}

Validation rules:

  • name must be a non-empty string

  • mapping must be non-empty

  • keys must be TerritoryZone

  • ratios must be finite numbers > 0

Ratios are normalized to sum to 1.0 on initialization. The functional zone’s min_area is computed as the weighted sum:

sum(zone.min_area * ratio) using the normalized ratios.

Example: define a functional program

from genplanner.zones import FunctionalZone
from genplanner.zones.territory_zones import (
    residential_terr,
    business_terr,
    recreation_terr,
)

downtown = FunctionalZone(
    zones_ratio={
        residential_terr: 0.6,
        business_terr: 0.3,
        recreation_terr: 0.1,
    },
    name="downtown",
)

# ratios are normalized internally
ratios = downtown.zones_ratio
assert abs(sum(ratios.values()) - 1.0) < 1e-9

Preset zones

GenPlanner ships with a set of predefined territorial zones and functional presets.

Basic functional zone

basic_func_zone is a balanced preset that defines a default target mix across all default territorial zones.

from genplanner.zones import basic_func_zone

print(basic_func_zone.name)          # "basic"
print(basic_func_zone.zones_ratio)   # mapping {TerritoryZone -> ratio}

Default territorial zones

default_terr_zones is a module-like collection of predefined territorial zones:

  • residential_terr

  • industrial_terr

  • business_terr

  • recreation_terr

  • transport_terr

  • agriculture_terr

  • special_terr

from genplanner.zones import default_terr_zones

# Access as attributes on the module
print(default_terr_zones.residential_terr)
print(default_terr_zones.industrial_terr.min_block_area)

Default functional presets

default_func_zones is a module-like collection of predefined functional programs:

  • residential_func_zone

  • industrial_func_zone

  • business_func_zone

  • recreation_func_zone

  • transport_func_zone

  • agricalture_func_zone

  • special_func_zone

from genplanner.zones import default_func_zones

fz = default_func_zones.residential_func_zone
print(fz.name)
print(sum(fz.zones_ratio.values()))  # always 1.0 after normalization

Using zones with GenPlanner

In most cases you only need to pass a functional zone preset into the planner:

import geopandas as gpd
from genplanner import GenPlanner
from genplanner.zones import basic_func_zone

features = gpd.read_file("territory.geojson")

gp = GenPlanner(features_gdf=features)
zones_gdf, roads_gdf = gp.features2terr_zones(funczone=basic_func_zone)

Tip

In fixed points GeoDataFrame, the fixed_zone column is matched against the keys of funczone.zones_ratio. In the current implementation those keys are TerritoryZone objects, so fixed_zone should contain the corresponding TerritoryZone instances.

import geopandas as gpd
from shapely.geometry import Point
from genplanner.zones import default_terr_zones

fix_points = gpd.GeoDataFrame(
    {
        "fixed_zone": [default_terr_zones.residential_terr],
        "geometry": [Point(10, 10)],
    },
    crs="EPSG:4326",
)

API reference

Core zone classes

Zone

Abstract base class for all zone types.

BasicZone

A minimal zone implementation identified only by name.

TerritoryZone

A concrete territorial zone definition.

FunctionalZone

A composite zone describing a functional program of territorial zones.

Zone presets

basic_func_zone

A composite zone describing a functional program of territorial zones.

default_func_zones

default_terr_zones

Territorial zone kinds

TerritoryZoneKind

Enumeration of supported territorial zone kinds.