Morphology Module¶
The morphology module provides functions for creating morphological graphs from urban fabric data, capturing spatial relationships between buildings, streets, and public spaces.
Composite Graphs¶
Module for creating morphological graphs from urban data.
This module provides comprehensive functionality for analyzing urban morphology through graph representations, focusing on the relationships between private spaces (buildings and their tessellations) and public spaces (street segments). It creates heterogeneous graphs that capture the complex spatial relationships inherent in urban environments. Both GeoDataFrame and NetworkX objects can be converted to PyTorch Geometric Data or HeteroData by functions from graph.py.
The module specializes in three types of spatial relationships: 1. Private-to-private: Adjacency relationships between building tessellations 2. Public-to-public: Topological connectivity between street segments 3. Private-to-public: Interface relationships between private and public spaces
Functions:
| Name | Description |
|---|---|
morphological_graph |
Create a morphological graph from buildings and street segments. |
morphological_graph ¶
morphological_graph(
buildings_gdf,
segments_gdf,
center_point=None,
distance=None,
clipping_buffer=inf,
primary_barrier_col="barrier_geometry",
contiguity="queen",
keep_buildings=False,
keep_segments=True,
tolerance=1e-06,
as_nx=False,
)
Create a morphological graph from buildings and street segments.
This function creates a comprehensive morphological graph that captures relationships between private spaces (building tessellations) and public spaces (street segments). The graph includes three types of relationships: private-to-private adjacency, public-to-public connectivity, and private-to-public interfaces.
The 'private_id' for tessellation cells is derived from 'tess_id' (generated by
create_tessellation) or assigned sequentially if 'tess_id' doesn't directly map.
The 'public_id' for street segments is taken directly from the index of segments_gdf.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
buildings_gdf
|
GeoDataFrame
|
GeoDataFrame containing building polygons. Should contain Polygon or MultiPolygon geometries. |
required |
segments_gdf
|
GeoDataFrame
|
GeoDataFrame containing street segments. Should contain LineString geometries. |
required |
center_point
|
GeoSeries or GeoDataFrame
|
Center point(s) for spatial filtering. If provided with distance parameter, only segments within the specified distance will be included. |
None
|
distance
|
float
|
Maximum distance from |
None
|
clipping_buffer
|
float
|
Buffer distance to ensure adequate context for generating tessellation. Must be non-negative. |
math.inf
|
primary_barrier_col
|
str
|
Column name containing alternative geometry for public spaces. If specified and exists, this geometry will be used instead of the main geometry column for tessellation barriers. |
'barrier_geometry'
|
contiguity
|
str
|
Type of spatial contiguity for private-to-private connections. Must be either "queen" or "rook". |
"queen"
|
keep_buildings
|
bool
|
If True, preserves building information in the tessellation output. |
False
|
keep_segments
|
bool
|
If True, preserves the original segment LineString geometry in a column named 'segment_geometry' in the public nodes GeoDataFrame. |
True
|
tolerance
|
float
|
Buffer distance for public geometries when creating private-to-public connections. This parameter controls how close private spaces need to be to public spaces to establish a connection. |
1e-6
|
as_nx
|
bool
|
If True, convert the output to a NetworkX graph. |
False
|
Returns:
| Type | Description |
|---|---|
tuple[dict[str, GeoDataFrame], dict[tuple[str, str, str], GeoDataFrame]] | Graph
|
If as_nx is False (default), returns a tuple (nodes, edges) where:
If as_nx is True, returns a NetworkX graph. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If buildings_gdf or segments_gdf are not GeoDataFrames. |
ValueError
|
If contiguity parameter is not "queen" or "rook". If clipping_buffer is negative. |
See Also
private_to_private_graph : Create adjacency between private spaces. private_to_public_graph : Create connections between private and public spaces. public_to_public_graph : Create connectivity between public spaces.
Notes
The function first filters the street network by distance (resulting in segs).
A segs_buffer GeoDataFrame is also created for tessellation context, potentially
filtered by distance + clipping_buffer or distance if center_point and
distance are provided. This segs_buffer is used to create enclosures and
tessellations.
It then establishes three types of relationships:
1. Private-to-private: Adjacency between tessellation cells (handled by private_to_private_graph)
2. Public-to-public: Topological connectivity between street segments
3. Private-to-public: Spatial interfaces between tessellations and streets
The output follows a heterogeneous graph structure suitable for network analysis of urban morphology.
Examples:
Component Graphs¶
Module for creating morphological graphs from urban data.
This module provides comprehensive functionality for analyzing urban morphology through graph representations, focusing on the relationships between private spaces (buildings and their tessellations) and public spaces (street segments). It creates heterogeneous graphs that capture the complex spatial relationships inherent in urban environments. Both GeoDataFrame and NetworkX objects can be converted to PyTorch Geometric Data or HeteroData by functions from graph.py.
The module specializes in three types of spatial relationships: 1. Private-to-private: Adjacency relationships between building tessellations 2. Public-to-public: Topological connectivity between street segments 3. Private-to-public: Interface relationships between private and public spaces
Functions:
| Name | Description |
|---|---|
private_to_private_graph |
Create edges between contiguous private polygons based on spatial adjacency. |
private_to_public_graph |
Create edges between private polygons and nearby public geometries. |
public_to_public_graph |
Create edges between connected public segments based on topological connectivity. |
segments_to_graph |
Convert a GeoDataFrame of LineString segments into a graph structure. |
private_to_private_graph ¶
Create edges between contiguous private polygons based on spatial adjacency.
This function identifies spatial adjacency relationships between private polygons
(e.g., tessellation cells) using either Queen or Rook contiguity criteria.
Optionally groups connections within specified groups (e.g., enclosures).
The input private_gdf is expected to have a 'private_id' column.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
private_gdf
|
GeoDataFrame
|
GeoDataFrame containing private space polygons. Must contain a 'private_id' column. |
required |
group_col
|
str
|
Column name for grouping connections. Only polygons within the same group will be connected. If None, all polygons are considered as one group. |
None
|
contiguity
|
str
|
Type of spatial contiguity to use. Must be either "queen" or "rook". Queen contiguity includes vertex neighbors, Rook includes only edge neighbors. |
"queen"
|
as_nx
|
bool
|
If True, convert the output to a NetworkX graph. |
False
|
Returns:
| Type | Description |
|---|---|
tuple[GeoDataFrame, GeoDataFrame] or Graph
|
If as_nx is False (default), returns a tuple (nodes, edges) where:
If as_nx is True, returns a networkx.Graph representing the private adjacency. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If private_gdf is not a GeoDataFrame. |
ValueError
|
If contiguity not in {"queen", "rook"}, or if group_col doesn't exist. |
See Also
morphological_graph : Main function that creates comprehensive morphological graphs. private_to_public_graph : Create connections between private and public spaces. public_to_public_graph : Create connectivity between public spaces.
Notes
The function uses libpysal's spatial weights to determine adjacency relationships. Edge geometries are created as LineStrings connecting polygon centroids. Self-connections and duplicate edges are automatically filtered out. The input private_gdf is expected to have a 'private_id' column.
Examples:
private_to_public_graph ¶
private_to_public_graph(
private_gdf,
public_gdf,
primary_barrier_col=None,
tolerance=1e-06,
as_nx=False,
)
Create edges between private polygons and nearby public geometries.
This function identifies spatial relationships between private spaces (tessellations) and public spaces (street segments) by finding intersections between buffered public geometries and private polygons. Input GDFs are expected to have 'private_id' and 'public_id' columns respectively.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
private_gdf
|
GeoDataFrame
|
GeoDataFrame containing private space polygons. Expected to have a 'private_id' column. |
required |
public_gdf
|
GeoDataFrame
|
GeoDataFrame containing public space geometries (typically LineStrings). Expected to have a 'public_id' column. |
required |
primary_barrier_col
|
str
|
Column name for alternative public geometry. If specified and exists, this geometry will be used instead of the main geometry column. |
None
|
tolerance
|
float
|
Buffer distance for public geometries to detect proximity to private spaces. |
1e-6
|
as_nx
|
bool
|
If True, convert the output to a NetworkX graph. |
False
|
Returns:
| Type | Description |
|---|---|
tuple[GeoDataFrame, GeoDataFrame] or Graph
|
If as_nx is False (default), returns a tuple (nodes, edges) where:
If as_nx is True, returns a networkx.Graph representing the private-to-public connections. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If private_gdf or public_gdf are not GeoDataFrames. |
ValueError
|
If 'private_id' or 'public_id' columns are missing from input GDFs. |
See Also
morphological_graph : Main function that creates comprehensive morphological graphs. private_to_private_graph : Create adjacency between private spaces. public_to_public_graph : Create connectivity between public spaces.
Notes
Edge geometries are created as LineStrings connecting the centroids of private polygons and public geometries. The function uses spatial joins to identify overlapping areas within the specified tolerance. Input GDFs are expected to have 'private_id' and 'public_id' columns respectively.
Examples:
public_to_public_graph ¶
Create edges between connected public segments based on topological connectivity.
This function identifies topological connections between public space geometries (typically street segments) using the dual graph approach to find segments that share endpoints or connection points. The function automatically creates a unique identifier for each row if needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_gdf
|
GeoDataFrame
|
GeoDataFrame containing public space geometries (typically LineString). |
required |
as_nx
|
bool
|
If True, convert the output to a NetworkX graph. |
False
|
Returns:
| Type | Description |
|---|---|
tuple[GeoDataFrame, GeoDataFrame] or Graph
|
If as_nx is False (default), returns a tuple (nodes, edges) where:
If as_nx is True, returns a networkx.Graph representing the public connectivity. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If public_gdf is not a GeoDataFrame. |
See Also
morphological_graph : Main function that creates comprehensive morphological graphs. private_to_private_graph : Create adjacency between private spaces. private_to_public_graph : Create connections between private and public spaces.
Notes
The function uses the dual graph approach where each LineString becomes a node, and edges represent topological connections between segments. Edge geometries are created as LineStrings connecting the centroids of connected segments.
Examples:
segments_to_graph ¶
Convert a GeoDataFrame of LineString segments into a graph structure.
This function takes a GeoDataFrame of LineStrings and processes it into a topologically explicit graph representation, consisting of a GeoDataFrame of unique nodes (the endpoints of the lines) and a GeoDataFrame of edges.
The resulting nodes GeoDataFrame contains unique points representing the start
and end points of the input line segments. The edges GeoDataFrame is a copy
of the input, but with a new MultiIndex (from_node_id, to_node_id) that
references the IDs in the new nodes GeoDataFrame. If multigraph is True
and there are multiple edges between the same pair of nodes, an additional
index level (edge_key) is added to distinguish them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
segments_gdf
|
GeoDataFrame
|
A GeoDataFrame where each row represents a line segment, and the 'geometry' column contains LineString objects. |
required |
multigraph
|
bool
|
If True, supports multiple edges between the same pair of nodes by
adding an |
False
|
as_nx
|
bool
|
If True, returns a NetworkX graph instead of a tuple of GeoDataFrames. |
False
|
Returns:
| Type | Description |
|---|---|
tuple[GeoDataFrame, GeoDataFrame]
|
A tuple containing two GeoDataFrames:
|
Examples:
>>> import geopandas as gpd
>>> from shapely.geometry import LineString
>>> # Create a GeoDataFrame of line segments
>>> segments = gpd.GeoDataFrame(
... {"road_name": ["A", "B"]},
... geometry=[LineString([(0, 0), (1, 1)]), LineString([(1, 1), (1, 0)])],
... crs="EPSG:32633"
... )
>>> # Convert to graph representation
>>> nodes_gdf, edges_gdf = segments_to_graph(segments)
>>> print(nodes_gdf)
>>> print(edges_gdf)
node_id geometry
0 POINT (0 0)
1 POINT (1 1)
2 POINT (1 0)
road_name geometry
from_node_id to_node_id
0 1 A LINESTRING (0 0, 1 1)
1 2 B LINESTRING (1 1, 1 0)
>>> # Example with duplicate connections (multigraph)
>>> segments_with_duplicates = gpd.GeoDataFrame(
... {"road_name": ["A", "B", "C"]},
... geometry=[LineString([(0, 0), (1, 1)]),
... LineString([(0, 0), (1, 1)]),
... LineString([(1, 1), (1, 0)])],
... crs="EPSG:32633"
... )
>>> nodes_gdf, edges_gdf = segments_to_graph(segments_with_duplicates, multigraph=True)
>>> print(edges_gdf.index.names)
['from_node_id', 'to_node_id', 'edge_key']