Metadata-Version: 2.4
Name: pyczml
Version: 0.1.0
Summary: A Python library for building CZML (Cesium Language) documents
Project-URL: Homepage, https://github.com/xiyusullos/pyczml
Project-URL: Repository, https://github.com/xiyusullos/pyczml.git
Author-email: aponder <i@aponder.top>
License: Apache-2.0
License-File: LICENSE
Keywords: 3d,cesium,czml,czml-writer,geospatial
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: GIS
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# pyczml

A Python library for building and parsing [CZML](https://github.com/AnalyticalGraphicsInc/czml-writer) (Cesium Language) documents.

CZML is a JSON format for describing time-dynamic 3D scenes in CesiumJS. This library provides a clean, type-safe Python API to create and manipulate CZML documents without writing raw JSON.

## Installation

```bash
pip install pyczml
# or
uv add pyczml
```

Requires Python ≥ 3.11. Zero external dependencies.

## Quick Start

```python
from pyczml import CZMLDocument

doc = CZMLDocument()

p = doc.add_packet("satellite-1")
p.name = "Satellite 1"
p.position.cartographic_degrees = [116.39, 39.91, 0.0]
p.billboard.image = "https://example.com/pin.png"
p.billboard.color = [255, 0, 0, 255]
p.billboard.scale = 1.5
p.point.pixel_size = 10
p.point.color = [0, 255, 255, 255]

print(doc.to_json(indent=2))
```

Output:

```json
[
  {
    "id": "satellite-1",
    "name": "Satellite 1",
    "position": {
      "cartographicDegrees": [116.39, 39.91, 0.0]
    },
    "billboard": {
      "image": "https://example.com/pin.png",
      "scale": 1.5,
      "color": { "rgba": [255, 0, 0, 255] }
    },
    "point": {
      "pixelSize": 10,
      "color": { "rgba": [0, 255, 255, 255] }
    }
  }
]
```

## Core Concepts

### Packet

A CZML document is a `list` of **packets**. Each packet represents a single object (satellite, aircraft, building, etc.) identified by a unique `id`. Packets can contain graphic properties like billboard, label, point, model, path, polygon, polyline, box, ellipse, ellipsoid, and position.

### Document

`CZMLDocument` wraps the packet list and provides serialization:

```python
doc = CZMLDocument()
p1 = doc.add_packet("obj-1")
p2 = doc.add_packet("obj-2")
print(doc.to_json())
```

### Builder API

Property names follow `snake_case` conventions and are automatically translated to CZML's `camelCase`:

```python
p.billboard.pixel_offset = [0, 50]    # → pixelOffset
p.label.horizontal_origin = "LEFT"    # → horizontalOrigin
```

Raw values (bool, int, float, str, list) are auto-wrapped into their CZML wrapper types:

```python
p.billboard.show = True           # → Boolean(boolean=True)
p.billboard.scale = 1.5           # → Double(number=1.5)
p.billboard.image = "img.png"     # → Uri(uri="img.png")
p.billboard.color = [255,0,0,255] # → Color(rgba=[255,0,0,255])
```

### Type System

CZML values are modeled as `@dataclass` types in `pyczml.types.values`. Each type is an `InterpolatableProperty` with first-class support for both shorthand and full dict forms.

| Category | Types |
|---|---|
| Primitives | `Boolean`, `Double`, `Integer`, `String`, `Uri`, `Font` |
| Enums | `HorizontalOriginProp`, `VerticalOriginProp`, `LabelStyleProp`, `ArcTypeProp`, etc. |
| Geometry | `Color`, `Position`, `Orientation`, `EyeOffset`, `NearFarScalar`, `BoundingRectangle` |
| Materials | `SolidColorMaterial`, `ImageMaterial`, `GridMaterial`, `StripeMaterial`, `PolylineGlowMaterial` |
| Graphics | `Billboard`, `Label`, `Point`, `Model`, `Path`, `Polygon`, `Polyline`, `Ellipse`, `Ellipsoid`, `Box` |

## Examples

### Position

```python
# Cartographic (longitude, latitude, height in degrees)
p.position.cartographic_degrees = [116.39, 39.91, 0.0]

# Cartesian (x, y, z in meters)
p.position.cartesian = [1215000.0, -4736000.0, 4081600.0]
```

### Color

```python
from pyczml import Color

# RGBA (0-255)
p.billboard.color = [255, 0, 0, 255]

# RGBAf (0.0-1.0)
p.point.color = Color(rgbaf=[1.0, 0.0, 0.0, 1.0])
```

### Material

```python
from pyczml import SolidColorMaterial, Material

p.polygon.material = Material(
    solidColor=SolidColorMaterial(color=Color(rgba=[0, 255, 0, 128]))
)
```

### Time Intervals and Availability

```python
from pyczml import time_interval, to_iso8601
from datetime import datetime, timezone

# Set object availability to a time range
p.availability = time_interval(
    datetime(2024, 1, 1, tzinfo=timezone.utc),
    datetime(2024, 12, 31, tzinfo=timezone.utc),
)

print(p.availability)  # "2024-01-01T00:00:00Z/2024-12-31T00:00:00Z"
```

### References

```python
from pyczml import ref

# Build a reference string: "Satellite/billboard/image"
r = ref("Satellite", "billboard", "image")

# Local reference (same document): "#target/position"
r = ref("target", "position", local=True)

# Use in a CZML property
p.billboard.image = r  # shorthand → Uri(reference=ref("..."))
```

### Loading Existing CZML

```python
doc = CZMLDocument.load("scene.czml")   # from file
# or
doc = CZMLDocument.loads(json_string)   # from string

p = doc.packets[0]
print(p.id)                           # reads from parsed data
print(p.billboard.color)              # Color(rgba=[...])

# Modify and re-export
p.billboard.scale = 2.0
print(doc.to_json(indent=2))
```

### Full Roundtrip

```python
from pyczml import CZMLDocument

doc = CZMLDocument()
p = doc.add_packet("bird")
p.position.cartographic_degrees = [120.0, 30.0, 1000.0]
p.model.gltf = "https://example.com/bird.glb"
p.model.scale = 1.0

json_str = doc.to_json()
loaded = CZMLDocument.loads(json_str)

assert loaded.packets[0].id == "bird"
```

## API Overview

### `CZMLDocument`

| Method | Description |
|---|---|
| `add_packet(id)` | Create and append a new packet |
| `to_json(indent)` | Serialize to JSON string |
| `loads(json_str)` | Deserialize from JSON string |
| `load(path)` | Deserialize from JSON file |
| `packets` | List of `CZMLPacket` |

### `CZMLPacket`

| Property | Type | Description |
|---|---|---|
| `id` | `str` | Unique object identifier |
| `name` | `str` | Display name |
| `delete` | `bool` | Delete this packet |
| `parent` | `str` | Parent object ID |
| `version` | `str` | Version string |
| `availability` | `str` | Time interval string |
| `position` | builder | Position |
| `billboard` | builder | Billboard graphic |
| `label` | builder | Label graphic |
| `point` | builder | Point graphic |
| `model` | builder | 3D model graphic |
| `path` | builder | Path graphic |
| `polygon` | builder | Polygon graphic |
| `polyline` | builder | Polyline graphic |
| `box`| `ellipse`| `ellipsoid` | builder | Shape graphics |

### Helper Functions

| Function | Description |
|---|---|
| `ref(object_id, *properties, local=False)` | Build CZML reference string |
| `to_iso8601(dt=None)` | Convert datetime to ISO 8601 string |
| `time_interval(start, end)` | Build CZML time interval string |

## License

Apache 2.0
