Coordinates and Geometry

KML ORM provides robust coordinate handling through the Coordinate class and related utilities.

Coordinate Class

Note

Coordinate objects are automatically validated upon creation and will raise kmlorm.core.exceptions.KMLValidationError if invalid values are provided.

class kmlorm.models.point.Coordinate(longitude, latitude, altitude=0)[source]

Bases: object

Represents a geographic coordinate with longitude, latitude, and optional altitude.

longitude

The longitude of the coordinate.

Type:

float

latitude

The latitude of the coordinate.

Type:

float

altitude

The altitude of the coordinate, if available.

Type:

Optional[float]

from_tuple(t

Tuple[float, …]) -> “Coordinate”: Creates a Coordinate instance from a tuple containing longitude, latitude, and optionally altitude.

from_string(s

str) -> “Coordinate”: Creates a Coordinate instance from a comma-separated string representation of longitude, latitude, and optionally altitude.

longitude: float
latitude: float
altitude: float = 0
__post_init__()[source]

Post-initialization hook that is automatically called after the dataclass is instantiated. This method triggers validation logic to ensure the object’s state is consistent and valid.

Return type:

None

classmethod from_tuple(t)[source]

Create a Coordinate instance from a tuple of floats.

Parameters:

t (Tuple[float, ...]) – A tuple containing longitude, latitude, and optionally altitude.

Returns:

An instance of Coordinate with the specified longitude, latitude,

and optional altitude.

Return type:

Coordinate

Raises:
  • IndexError – If the tuple does not contain at least two elements.

  • ValueError – If the tuple elements cannot be converted to float.

classmethod from_string(s)[source]

Creates a Coordinate instance from a comma-separated string.

Parameters:

s (str) – A string containing coordinate values separated by commas (e.g., “longitude, latitude, [altitude]”).

Returns:

An instance of the Coordinate class created from the parsed values.

Return type:

Coordinate

Raises:

ValueError – If the string cannot be parsed into valid float values.

classmethod from_any(value)[source]

Creates a Coordinate instance from various input types.

Parameters:

value (Union[Tuple[float, ...], str, list, Coordinate]) – The input value to convert. Can be a tuple, list, string, or another Coordinate instance.

Returns:

A Coordinate instance created from the input value.

Return type:

Coordinate

Raises:

TypeError – If the input value is not a tuple, list, string, or Coordinate.

validate()[source]

Validates the longitude, latitude, and optional altitude values of the point.

Returns:

True if all coordinate values are valid.

Return type:

bool

Raises:

KMLValidationError – If longitude or latitude are not numeric, out of valid range, or if altitude is provided and is not a finite numeric value.

to_dict()[source]

Convert coordinate to dictionary representation.

Return type:

dict[str, float]

Returns:

Dictionary with longitude, latitude, and altitude values.

get_coordinates()[source]

Return self as the coordinate representation.

This method satisfies the HasCoordinates protocol, allowing Coordinate objects to be used directly in spatial calculations.

Return type:

Optional[Coordinate]

Returns:

Self (this Coordinate object)

distance_to(other, unit=None)[source]

Calculate distance to another spatial object.

Parameters:
  • other (Union[Coordinate, Point, Placemark, Tuple[float, float], list]) – Target object with coordinates (Coordinate, Point, Placemark, or tuple)

  • unit (Optional[DistanceUnit]) – Distance unit (defaults to kilometers)

Return type:

Optional[float]

Returns:

Distance in specified units, or None if target has no coordinates

Examples

>>> coord1 = Coordinate(longitude=-74.006, latitude=40.7128)  # NYC
>>> coord2 = Coordinate(longitude=-0.1276, latitude=51.5074)  # London
>>> distance = coord1.distance_to(coord2)
>>> print(f"Distance: {distance:.1f} km")
>>> # Different units
>>> from kmlorm.spatial import DistanceUnit
>>> distance_miles = coord1.distance_to(coord2, unit=DistanceUnit.MILES)
bearing_to(other)[source]

Calculate bearing to another spatial object.

Parameters:

other (Union[Coordinate, Point, Placemark, Tuple[float, float], list]) – Target object with coordinates

Return type:

Optional[float]

Returns:

Initial bearing in degrees (0-360), or None if target has no coordinates 0° = North, 90° = East, 180° = South, 270° = West

Examples

>>> coord1 = Coordinate(longitude=0, latitude=0)
>>> coord2 = Coordinate(longitude=1, latitude=0)  # Due east
>>> bearing = coord1.bearing_to(coord2)
>>> print(f"Bearing: {bearing:.1f}°")  # Should be ~90°
midpoint_to(other)[source]

Find geographic midpoint to another spatial object.

Parameters:

other (Union[Coordinate, Point, Placemark, Tuple[float, float], list]) – Target object with coordinates

Return type:

Optional[Coordinate]

Returns:

Coordinate at the midpoint, or None if target has no coordinates

Examples

>>> coord1 = Coordinate(longitude=0, latitude=0)
>>> coord2 = Coordinate(longitude=2, latitude=2)
>>> midpoint = coord1.midpoint_to(coord2)
>>> print(f"Midpoint: ({midpoint.longitude}, {midpoint.latitude})")
__hash__()[source]

Hash for caching support in spatial calculations.

Return type:

int

Returns:

Hash based on longitude, latitude, and altitude

__init__(longitude, latitude, altitude=0)

Creating Coordinates

From Tuple

classmethod Coordinate.from_tuple(t)[source]

Create a Coordinate instance from a tuple of floats.

Parameters:

t (Tuple[float, ...]) – A tuple containing longitude, latitude, and optionally altitude.

Returns:

An instance of Coordinate with the specified longitude, latitude,

and optional altitude.

Return type:

Coordinate

Raises:
  • IndexError – If the tuple does not contain at least two elements.

  • ValueError – If the tuple elements cannot be converted to float.

From String

classmethod Coordinate.from_string(s)[source]

Creates a Coordinate instance from a comma-separated string.

Parameters:

s (str) – A string containing coordinate values separated by commas (e.g., “longitude, latitude, [altitude]”).

Returns:

An instance of the Coordinate class created from the parsed values.

Return type:

Coordinate

Raises:

ValueError – If the string cannot be parsed into valid float values.

From Any Format

classmethod Coordinate.from_any(value)[source]

Creates a Coordinate instance from various input types.

Parameters:

value (Union[Tuple[float, ...], str, list, Coordinate]) – The input value to convert. Can be a tuple, list, string, or another Coordinate instance.

Returns:

A Coordinate instance created from the input value.

Return type:

Coordinate

Raises:

TypeError – If the input value is not a tuple, list, string, or Coordinate.

Properties

Coordinate.longitude: float
Coordinate.latitude: float
Coordinate.altitude: float = 0

Validation

Coordinate.validate()[source]

Validates the longitude, latitude, and optional altitude values of the point.

Returns:

True if all coordinate values are valid.

Return type:

bool

Raises:

KMLValidationError – If longitude or latitude are not numeric, out of valid range, or if altitude is provided and is not a finite numeric value.

Data Access

Coordinate.to_dict()[source]

Convert coordinate to dictionary representation.

Return type:

dict[str, float]

Returns:

Dictionary with longitude, latitude, and altitude values.

Usage Examples

Creating Coordinates

from kmlorm.models.point import Coordinate

# From tuple
coord1 = Coordinate.from_tuple((-76.5, 39.3, 100))

# From string
coord2 = Coordinate.from_string("-76.5,39.3,100")

# Direct creation (altitude defaults to 0 if not provided)
coord3 = Coordinate(longitude=-76.5, latitude=39.3, altitude=100)

# From various formats
coord4 = Coordinate.from_any((-76.5, 39.3))
coord5 = Coordinate.from_any("-76.5,39.3")
coord6 = Coordinate.from_any([-76.5, 39.3, 0])

Accessing Properties

from kmlorm.models.point import Coordinate

coord = Coordinate(longitude=-76.5, latitude=39.3, altitude=100)

print(f"Longitude: {coord.longitude}")
print(f"Latitude: {coord.latitude}")
print(f"Altitude: {coord.altitude}")

Validation

from kmlorm.models.point import Coordinate
from kmlorm.core.exceptions import KMLValidationError

# Valid coordinate
valid_coord = Coordinate(longitude=-76.5, latitude=39.3)
if valid_coord.validate():
    print("Coordinate is valid")

# Invalid coordinate (will raise exception automatically on creation)
try:
    invalid_coord = Coordinate(longitude=200, latitude=100)  # Raises on __post_init__
except KMLValidationError as e:
    print(f"Invalid coordinate: {e}")

Integration with Placemark

Coordinates are automatically handled when working with Placemarks:

from kmlorm import Placemark
from kmlorm.models.point import Coordinate

# Set coordinates during creation
placemark = Placemark(
    name="Test Location",
    coordinates=(-76.5, 39.3, 100.0)  # Automatically converted to Coordinate
)

# Access coordinate properties
print(f"Location: {placemark.longitude}, {placemark.latitude}")

# Get the full coordinate object
coord = placemark.coordinates
if coord:
    print(f"Full coordinates: {coord.longitude}, {coord.latitude}, {coord.altitude}")

Accessing Coordinate Data

from kmlorm.models.point import Coordinate
from kmlorm import Placemark

# Create a coordinate
coord = Coordinate(longitude=-76.5294, latitude=39.2904, altitude=100.5)

# Convert to dictionary format
coord_dict = coord.to_dict()
print(coord_dict)
# Output: {'longitude': -76.5294, 'latitude': 39.2904, 'altitude': 100.5}

# Access individual values from dictionary
longitude = coord_dict["longitude"]
latitude = coord_dict["latitude"]
altitude = coord_dict["altitude"]

# Use with placemarks for data transfer
placemark = Placemark(name="Distribution Center", coordinates=(-76.5294, 39.2904, 100.5))

# Access placemark coordinate data
if placemark.coordinates:
    coord_data = placemark.coordinates.to_dict()
    print(f"Coordinate data: {coord_data}")

Coordinate Validation Rules

The Coordinate class enforces standard geographic coordinate ranges:

  • Longitude: Must be between -180.0 and 180.0 degrees

  • Latitude: Must be between -90.0 and 90.0 degrees

  • Altitude: Must be a finite numeric value (if provided)

Invalid coordinates will raise a KMLValidationError.