Skip to content

Google Earth (KML)

kml

Google Earth (KML) export of trajectories and ATE results.

Trajectories are written as time-stamped tracks (gx:Track) that the time slider of Google Earth plays back. Optionally, the trajectory is additionally drawn as a line colored by a field (speed, height or time for trajectories, a deviation for ATE results): the line is split into runs of consecutive poses of the same color class. Each class is a folder (named by its value range, so that the Places panel of Google Earth shows the legend and the classes can be switched on and off), and each run appears at its time, so that the colored line grows during playback.

Vertically, the trajectory is either clamped to the terrain of Google Earth or drawn at its own heights (see :data:HEIGHT_MODES). Google Earth expects heights above sea level (EGM96 geoid); ellipsoidal heights are converted with the geoid model, which pyproj downloads from the PROJ CDN (cdn.proj.org) where needed.

KmlField dataclass

KmlField(
    key: str,
    label: str,
    unit: str,
    values: Callable[[Any], ndarray],
    needs_orientation: bool = False,
)

A per-pose value of a trajectory or an ATE result that can color the Google Earth export.

kml_color

kml_color(color: str) -> str

Converts "#RRGGBB" or "#RRGGBBAA" to the KML color format "aabbggrr".

Raises:

  • ValueError –

    If the color is not given in one of these formats.

Source code in trajectopy\io\kml.py
def kml_color(color: str) -> str:
    """Converts "#RRGGBB" or "#RRGGBBAA" to the KML color format "aabbggrr".

    Raises:
        ValueError: If the color is not given in one of these formats.
    """
    value = color.strip().removeprefix("#")
    try:
        int(value, 16)
    except ValueError:
        value = ""
    if len(value) not in (6, 8):
        raise ValueError(f'Invalid color "{color}": use "#RRGGBB" or "#RRGGBBAA", e.g. "#ff0000" for red.')
    red, green, blue, alpha = value[0:2], value[2:4], value[4:6], value[6:8] or "ff"
    return f"{alpha}{blue}{green}{red}".lower()

trajectory_kml_fields

trajectory_kml_fields() -> list[KmlField]

The fields that can color the Google Earth export of a trajectory.

Source code in trajectopy\io\kml.py
def trajectory_kml_fields() -> list[KmlField]:
    """The fields that can color the Google Earth export of a trajectory."""
    return list(TRAJECTORY_KML_FIELDS)

ate_kml_fields

ate_kml_fields(ate_result: ATEResult) -> list[KmlField]

The fields of ate_result that can color its Google Earth export.

Source code in trajectopy\io\kml.py
def ate_kml_fields(ate_result: ATEResult) -> list[KmlField]:
    """The fields of ``ate_result`` that can color its Google Earth export."""
    return [field for field in ATE_KML_FIELDS if ate_result.has_orientation or not field.needs_orientation]

write_kml

write_kml(
    trajectory: Trajectory,
    filename: str,
    color: str = DEFAULT_KML_COLOR,
    field: str | None = None,
    colormap: str = "rdylbu",
    max_std: float = 3.0,
    value_range: tuple[float, float] | None = None,
    color_classes: int = DEFAULT_COLOR_CLASSES,
    heights: str = "ground",
    height_offset: float = 0.0,
    extrude: bool = False,
    line_width: float = 3.0,
    precision: float = 1e-06,
) -> None

Exports a trajectory to a Google Earth KML file.

The trajectory is written as a time-stamped track (gx:Track): Google Earth shows its path and plays it back with the time slider. Optionally, it is colored by a field (speed, height or time).

Requires the trajectory to have a valid EPSG code so it can be converted to WGS84 (EPSG:4326).

Parameters:

  • trajectory (Trajectory) –

    Trajectory to export.

  • filename (str) –

    The output filename (e.g., "track.kml").

  • color (str, default: DEFAULT_KML_COLOR ) –

    Color of the track and its points as "#RRGGBB" or "#RRGGBBAA", if it is not colored by a field. Defaults to red.

  • field (str, default: None ) –

    Key of the field that colors the line, see :func:trajectory_kml_fields: "speed", "height" or "time". Defaults to none (one color).

  • colormap (str, default: 'rdylbu' ) –

    Color scale of the field, see :data:trajectopy.utils.colors.COLORMAPS: "rdylbu" (blue = low, red = high, like the plots) or "viridis" (colorblind-safe). Defaults to "rdylbu".

  • max_std (float, default: 3.0 ) –

    The color scale is clipped to mean ± max_std standard deviations (0 = minimum to maximum). Ignored if value_range is given. Defaults to 3.0, like the plots.

  • value_range (tuple[float, float], default: None ) –

    Fixed (lower, upper) limits of the color scale, e.g. to compare several exports; values beyond them get the color of the nearest limit. Defaults to none.

  • color_classes (int, default: DEFAULT_COLOR_CLASSES ) –

    Number of colors of the scale. Defaults to 11.

  • heights (str, default: 'ground' ) –

    Vertical placement, see :data:HEIGHT_MODES: "ground" (clamped to the terrain), "ellipsoidal" (the trajectory's heights are ellipsoidal heights, e.g. GNSS; converted with the EGM96 geoid, which needs an internet connection the first time) or "sea_level" (the heights are above sea level). Defaults to "ground".

  • height_offset (float, default: 0.0 ) –

    Meters added to the heights; with "ground", the trajectory floats this far above the terrain. Defaults to 0.

  • extrude (bool, default: False ) –

    Connect the trajectory to the ground with a vertical curtain (not with "ground" and no offset). Defaults to False.

  • line_width (float, default: 3.0 ) –

    Line width in pixels. Defaults to 3.

  • precision (float, default: 1e-06 ) –

    Coordinate precision in degrees. Defaults to 1e-6 (about 0.1 m).

Raises:

  • ValueError –

    If the trajectory does not have a known EPSG code, an option is invalid, or the geoid model is not available.

Source code in trajectopy\io\kml.py
def write_kml(
    trajectory: Trajectory,
    filename: str,
    color: str = DEFAULT_KML_COLOR,
    field: str | None = None,
    colormap: str = "rdylbu",
    max_std: float = 3.0,
    value_range: tuple[float, float] | None = None,
    color_classes: int = DEFAULT_COLOR_CLASSES,
    heights: str = "ground",
    height_offset: float = 0.0,
    extrude: bool = False,
    line_width: float = 3.0,
    precision: float = 1e-6,
) -> None:
    """Exports a trajectory to a Google Earth KML file.

    The trajectory is written as a time-stamped track (``gx:Track``): Google Earth shows its path and plays
    it back with the time slider. Optionally, it is colored by a field (speed, height or time).

    Requires the trajectory to have a valid EPSG code so it can be converted to WGS84 (EPSG:4326).

    Args:
        trajectory (Trajectory): Trajectory to export.
        filename (str): The output filename (e.g., "track.kml").
        color (str, optional): Color of the track and its points as "#RRGGBB" or "#RRGGBBAA", if it is not
            colored by a field. Defaults to red.
        field (str, optional): Key of the field that colors the line, see :func:`trajectory_kml_fields`:
            "speed", "height" or "time". Defaults to none (one color).
        colormap (str, optional): Color scale of the field, see :data:`trajectopy.utils.colors.COLORMAPS`:
            "rdylbu" (blue = low, red = high, like the plots) or "viridis" (colorblind-safe). Defaults to "rdylbu".
        max_std (float, optional): The color scale is clipped to mean ± ``max_std`` standard deviations
            (0 = minimum to maximum). Ignored if ``value_range`` is given. Defaults to 3.0, like the plots.
        value_range (tuple[float, float], optional): Fixed (lower, upper) limits of the color scale, e.g. to
            compare several exports; values beyond them get the color of the nearest limit. Defaults to none.
        color_classes (int, optional): Number of colors of the scale. Defaults to 11.
        heights (str, optional): Vertical placement, see :data:`HEIGHT_MODES`: "ground" (clamped to the
            terrain), "ellipsoidal" (the trajectory's heights are ellipsoidal heights, e.g. GNSS; converted with
            the EGM96 geoid, which needs an internet connection the first time) or "sea_level" (the heights are
            above sea level). Defaults to "ground".
        height_offset (float, optional): Meters added to the heights; with "ground", the trajectory floats
            this far above the terrain. Defaults to 0.
        extrude (bool, optional): Connect the trajectory to the ground with a vertical curtain (not with
            "ground" and no offset). Defaults to False.
        line_width (float, optional): Line width in pixels. Defaults to 3.
        precision (float, optional): Coordinate precision in degrees. Defaults to 1e-6 (about 0.1 m).

    Raises:
        ValueError: If the trajectory does not have a known EPSG code, an option is invalid, or the geoid model
            is not available.
    """
    scale = _ColorScale(colormap, max_std, value_range, color_classes)
    placement = _placement(trajectory, heights, height_offset)
    root, document = _document(trajectory.name)
    if field is None:
        _add_track_style(document, "track", kml_color(color), line_width)
        _add_track(document, trajectory.name, "track", placement, extrude, precision)
    else:
        selected = _field(trajectory_kml_fields(), field)
        values = np.asarray(selected.values(trajectory), dtype=float)[placement.order]
        _add_colored_line(
            document, trajectory.name, selected, values, placement, scale, extrude, line_width, precision
        )
    _write(root, filename)

write_ate_kml

write_ate_kml(
    ate_result: ATEResult,
    filename: str,
    field: str = "position",
    colormap: str = "rdylbu",
    max_std: float = 3.0,
    value_range: tuple[float, float] | None = None,
    color_classes: int = DEFAULT_COLOR_CLASSES,
    heights: str = "ground",
    height_offset: float = 0.0,
    extrude: bool = False,
    line_width: float = 4.0,
    precision: float = 1e-06,
) -> None

Exports an ATE result to a Google Earth KML file, colored by one of its deviation fields.

The evaluated trajectory is drawn as a colored line, and as a time-stamped track that the time slider of Google Earth plays back. The Places panel lists the color classes with their value ranges (legend).

Parameters:

  • ate_result (ATEResult) –

    Result to export. Its trajectory needs a known EPSG code.

  • filename (str) –

    The output filename (e.g., "ate.kml").

  • field (str, default: 'position' ) –

    Key of the deviation field that colors the line, see :func:ate_kml_fields, e.g. "position", "along_track" or "yaw". Defaults to "position".

  • colormap (str, default: 'rdylbu' ) –

    Color scale, see :func:write_kml. Defaults to "rdylbu".

  • max_std (float, default: 3.0 ) –

    The color scale is clipped to mean ± max_std standard deviations (0 = minimum to maximum). Ignored if value_range is given. Defaults to 3.0, like the plots.

  • value_range (tuple[float, float], default: None ) –

    Fixed (lower, upper) limits of the color scale. Defaults to none.

  • color_classes (int, default: DEFAULT_COLOR_CLASSES ) –

    Number of colors of the scale. Defaults to 11.

  • heights (str, default: 'ground' ) –

    Vertical placement, see :func:write_kml. Defaults to "ground".

  • height_offset (float, default: 0.0 ) –

    Meters added to the heights, see :func:write_kml. Defaults to 0.

  • extrude (bool, default: False ) –

    Connect the line to the ground with a vertical curtain. Defaults to False.

  • line_width (float, default: 4.0 ) –

    Line width in pixels. Defaults to 4.

  • precision (float, default: 1e-06 ) –

    Coordinate precision in degrees. Defaults to 1e-6 (about 0.1 m).

Raises:

  • ValueError –

    If the trajectory has no known EPSG code, the field is not available, an option is invalid, or the geoid model is not available.

Source code in trajectopy\io\kml.py
def write_ate_kml(
    ate_result: ATEResult,
    filename: str,
    field: str = "position",
    colormap: str = "rdylbu",
    max_std: float = 3.0,
    value_range: tuple[float, float] | None = None,
    color_classes: int = DEFAULT_COLOR_CLASSES,
    heights: str = "ground",
    height_offset: float = 0.0,
    extrude: bool = False,
    line_width: float = 4.0,
    precision: float = 1e-6,
) -> None:
    """Exports an ATE result to a Google Earth KML file, colored by one of its deviation fields.

    The evaluated trajectory is drawn as a colored line, and as a time-stamped track that the time slider of
    Google Earth plays back. The Places panel lists the color classes with their value ranges (legend).

    Args:
        ate_result (ATEResult): Result to export. Its trajectory needs a known EPSG code.
        filename (str): The output filename (e.g., "ate.kml").
        field (str, optional): Key of the deviation field that colors the line, see :func:`ate_kml_fields`,
            e.g. "position", "along_track" or "yaw". Defaults to "position".
        colormap (str, optional): Color scale, see :func:`write_kml`. Defaults to "rdylbu".
        max_std (float, optional): The color scale is clipped to mean ± ``max_std`` standard deviations
            (0 = minimum to maximum). Ignored if ``value_range`` is given. Defaults to 3.0, like the plots.
        value_range (tuple[float, float], optional): Fixed (lower, upper) limits of the color scale.
            Defaults to none.
        color_classes (int, optional): Number of colors of the scale. Defaults to 11.
        heights (str, optional): Vertical placement, see :func:`write_kml`. Defaults to "ground".
        height_offset (float, optional): Meters added to the heights, see :func:`write_kml`. Defaults to 0.
        extrude (bool, optional): Connect the line to the ground with a vertical curtain. Defaults to False.
        line_width (float, optional): Line width in pixels. Defaults to 4.
        precision (float, optional): Coordinate precision in degrees. Defaults to 1e-6 (about 0.1 m).

    Raises:
        ValueError: If the trajectory has no known EPSG code, the field is not available, an option is invalid,
            or the geoid model is not available.
    """
    selected = _field(ate_kml_fields(ate_result), field)
    scale = _ColorScale(colormap, max_std, value_range, color_classes)
    placement = _placement(ate_result.trajectory, heights, height_offset)
    values = np.asarray(selected.values(ate_result), dtype=float)[placement.order]
    root, document = _document(ate_result.name)
    _add_colored_line(document, ate_result.name, selected, values, placement, scale, extrude, line_width, precision)
    _write(root, filename)