Skip to main content

Python bindings for FlatCityBuf - a cloud-optimized binary format for 3D city models

Project description

FlatCityBuf Python Bindings

Python bindings for FlatCityBuf, a cloud-optimized binary format for storing and retrieving 3D city models with full CityJSON compatibility.

Features

  • Fast reading of FlatCityBuf (.fcb) files with zero-copy access
  • Local and HTTP file support with async iteration
  • CityJSON integration with transform, metadata, and proper structure
  • Spatial queries using bounding boxes with R-tree indexing
  • Attribute queries for filtering features with B+tree indices
  • Async iterators for efficient streaming from HTTP sources
  • Nested boundaries support for complex 3D geometries
  • Pythonic API with comprehensive type support

Installation

From Source

# Prerequisites: Rust toolchain and maturin
pip install maturin

# Build and install with HTTP support
cd src/rust/fcb_py
maturin develop --features http

Using pip (when available)

pip install flatcitybuf

Quick Start

Local File Access

import flatcitybuf as fcb

# Read a local file
reader = fcb.Reader("https://storage.googleapis.com/flatcitybuf/3dbag_all_index.fcb")

# Get file information
info = reader.info()
print(f"Features: {info.feature_count}")

# Get CityJSON header with transform and metadata
cityjson = reader.cityjson_header()
print(f"CityJSON version: {cityjson.version}")
print(f"Transform: {cityjson.transform.scale}, {cityjson.transform.translate}")

# Iterate all features (CityJSON format)
for feature in reader:
    print(f"ID: {feature.id}, Type: {feature.type}")
    print(f"City Objects: {len(feature.city_objects)}")
    print(f"Vertices: {len(feature.vertices)}")

# Spatial query
features = list(reader.query_bbox(84227.77, 445377.33, 85323.23, 446334.69))
print(f"Found {len(features)} features in bounding box")

# Attribute query
id_filter = fcb.AttrFilter("identificatie", fcb.Operator.Eq, "building_123")
buildings = list(reader.query_attr([id_filter]))
print(f"Found {len(buildings)} matching buildings")

HTTP Access with Async Iterators

import asyncio
import flatcitybuf as fcb

async def main():
    # Create async reader for HTTP URL
    async_reader = fcb.AsyncReader("https://storage.googleapis.com/flatcitybuf/3dbag_subset_all_index.fcb")
    opened_reader = await async_reader.open()

    # Get file info
    info = opened_reader.info()
    print(f"Features: {info.feature_count}")

    # Async iteration - efficient streaming
    async_iter = opened_reader.select_all()

    # Process features one by one
    count = 0
    while count < 10:  # Get first 10 features
        feature = await async_iter.next()
        if feature is None:
            break
        print(f"Feature {count}: {feature.id}")
        count += 1

    # Or collect all at once
    all_features = await opened_reader.select_all().collect()
    print(f"Total features: {len(all_features)}")

    # Async spatial query
    bbox_iter = opened_reader.query_bbox(84227.77, 445377.33, 85323.23, 446334.69)
    spatial_features = await bbox_iter.collect()
    print(f"Spatial query result: {len(spatial_features)} features")

asyncio.run(main())

API Reference

Reader (Synchronous)

Main class for reading local FlatCityBuf files.

reader = fcb.Reader(path: str)

Methods:

  • info() -> FileInfo - Get file metadata and statistics
  • cityjson_header() -> CityJSON - Get CityJSON header with transform/metadata
  • query_bbox(min_x, min_y, max_x, max_y) -> Iterator[Feature] - Spatial query
  • query_attr(filters: List[AttrFilter]) -> Iterator[Feature] - Attribute query
  • __iter__() -> Iterator[Feature] - Iterate all features

AsyncReader (HTTP)

Asynchronous reader for HTTP-based FlatCityBuf files.

async_reader = fcb.AsyncReader(url: str)
opened_reader = await async_reader.open()

Methods:

  • info() -> FileInfo - Get file metadata
  • cityjson_header() -> CityJSON - Get CityJSON header information
  • select_all() -> AsyncFeatureIterator - Get all features as async iterator
  • query_bbox(min_x, min_y, max_x, max_y) -> AsyncFeatureIterator - Async spatial query
  • query_attr(filters: List[AttrFilter]) -> AsyncFeatureIterator - Async attribute query

AsyncFeatureIterator

Efficient async iterator for streaming features from HTTP sources.

# Get features one by one
feature = await async_iter.next()  # Returns Feature or None

# Collect all remaining features
features = await async_iter.collect()  # Returns List[Feature]

Feature (CityJSON Format)

Represents a CityJSON feature with proper structure.

class Feature:
    id: str                           # Feature ID
    type: str                         # Feature type
    vertices: List[List[float]]       # 3D vertices as [x, y, z] arrays
    city_objects: Dict[str, CityObject]  # Dictionary of city objects

CityObject

Individual city object within a feature.

class CityObject:
    type: str                         # Object type (e.g., "Building")
    geometry: List[Geometry]          # List of geometries
    attributes: Dict[str, Any]        # Object attributes
    children: List[str]               # Child object IDs
    parents: List[str]                # Parent object IDs

Geometry

3D geometry with nested boundary structure.

class Geometry:
    type: str                         # Geometry type
    boundaries: PyObject              # Nested boundary arrays (preserves structure)
    semantics: Optional[Any]          # Semantic information

CityJSON Header

CityJSON metadata and transform information.

class CityJSON:
    type: str                         # Always "CityJSON"
    version: str                      # CityJSON version
    transform: Transform              # Coordinate transformation
    metadata: Optional[Metadata]      # Optional metadata
    feature_count: int                # Number of features

Transform

Coordinate transformation parameters.

class Transform:
    scale: List[float]                # Scale factors [x, y, z]
    translate: List[float]            # Translation [x, y, z]

Query Types

# Bounding box
bbox = fcb.BBox(min_x=0, min_y=0, max_x=100, max_y=100)

# Attribute filters
filter_eq = fcb.AttrFilter("type", fcb.Operator.Eq, "building")
filter_gt = fcb.AttrFilter("height", fcb.Operator.Gt, 50.0)
filter_le = fcb.AttrFilter("floors", fcb.Operator.Le, 10)

# Available operators
fcb.Operator.Eq    # Equal
fcb.Operator.Ne    # Not equal
fcb.Operator.Gt    # Greater than
fcb.Operator.Ge    # Greater than or equal
fcb.Operator.Lt    # Less than
fcb.Operator.Le    # Less than or equal

Performance

The Python bindings leverage Rust's zero-copy deserialization and efficient indexing:

  • 10-20× faster than parsing equivalent JSON formats
  • 2-6× less memory usage compared to text formats
  • Efficient spatial indexing with packed R-tree queries
  • HTTP range requests for cloud-optimized partial access
  • Async streaming minimizes memory usage for large datasets
  • Nested boundary preservation avoids flattening overhead

Nested Boundaries

The bindings properly preserve CityJSON's nested boundary structure:

# Boundaries can be nested arrays at arbitrary depth
# Example: [[0, 1, 2, 3]] for a single surface
# Example: [[[0, 1, 2, 3], [4, 5, 6, 7]]] for surfaces with holes
geometry.boundaries  # Preserves exact nesting from CityJSON

HTTP Optimization

AsyncReader is optimized for HTTP access:

  • Persistent connections - HTTP client maintained across iterator calls
  • Range request batching - Efficient partial downloads
  • Prefetching strategies - Reduces round-trip latency
  • Async streaming - Process features as they arrive

Examples

See the examples/ directory for comprehensive usage examples including:

  • Basic local file reading
  • HTTP access with async iteration
  • CityJSON header processing
  • Spatial and attribute queries
  • Nested geometry handling

Development

Building from Source

# Install development dependencies
pip install maturin pytest pytest-asyncio

# Build in development mode
maturin develop --features http

# Run tests
pytest tests/

# Run with coverage
pytest tests/ --cov=flatcitybuf

Testing

# Run all tests
python -m pytest tests/test_e2e.py -v

# Run only sync tests
python -m pytest tests/test_e2e.py::TestE2EIntegration -v

# Run only async tests
python -m pytest tests/test_e2e.py::TestAsyncReaderE2E -v

Project Structure

src/rust/fcb_py/
├── python/             # Python stub files
├── src/                # Rust PyO3 bindings
│   ├── lib.rs         # Main module
│   ├── reader.rs      # Sync reader
│   ├── async_reader.rs # Async reader
│   ├── types.rs       # Python types
│   ├── utils.rs       # Conversion utilities
│   └── query.rs       # Query types
├── tests/             # Python tests
├── examples/          # Usage examples
├── Cargo.toml         # Rust dependencies
└── pyproject.toml     # Python project config

License

MIT License - see LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flatcitybuf-0.2.0.tar.gz (1.7 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

flatcitybuf-0.2.0-cp313-cp313-macosx_11_0_arm64.whl (2.0 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

flatcitybuf-0.2.0-cp39-cp39-win_amd64.whl (2.1 MB view details)

Uploaded CPython 3.9Windows x86-64

File details

Details for the file flatcitybuf-0.2.0.tar.gz.

File metadata

  • Download URL: flatcitybuf-0.2.0.tar.gz
  • Upload date:
  • Size: 1.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.9.6

File hashes

Hashes for flatcitybuf-0.2.0.tar.gz
Algorithm Hash digest
SHA256 3ded5c8fa50e427649f0aa9a9345c698866b3ffbd9714d6534a7e975fe7031b5
MD5 84bc5275a3977d85553f8a0bdeb1840a
BLAKE2b-256 6c93e921b99a0ccbb3363fd4e4a7e6cc2ddbfe0d420ebf1891254500581d60a5

See more details on using hashes here.

File details

Details for the file flatcitybuf-0.2.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for flatcitybuf-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9af168476fee1c6bb515cbed527341575401cf209d5daf783dd7b70acc43228d
MD5 dc3e3bc997d85178990972e4f64d8a1a
BLAKE2b-256 c7772283f54852ef0187a32c6e86667bf9efc2aea107b30e1e92f1f9bce9b139

See more details on using hashes here.

File details

Details for the file flatcitybuf-0.2.0-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for flatcitybuf-0.2.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 88c4da33e7d310ebe0e302b6cb066856d2f16c7706eb78aa1c58aaf64fc85163
MD5 831a7df9f10ce5f2fd5a29302084bdda
BLAKE2b-256 8b7e8d32bc80351af2c6d4fb6de598946aad29fac01a1487843313cc1106f643

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page