# Copyright (C) 2023 Christian Ledermann
#
# This library is free software; you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2.1 of the License, or (at your option)
# any later version.
#
# This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
"""
Enums for the fastkml package.
This module contains the enums used in the fastkml package.
https://developers.google.com/kml/documentation/kmlreference#kml-fields
"""
import logging
from enum import Enum
from enum import unique
__all__ = [
"AltitudeMode",
"ColorMode",
"DataType",
"DateTimeResolution",
"DisplayMode",
"GridOrigin",
"PairKey",
"RefreshMode",
"RelaxedEnum",
"Shape",
"Units",
"Verbosity",
"ViewRefreshMode",
]
logger = logging.getLogger(__name__)
[docs]
class RelaxedEnum(Enum):
"""
Enum with relaxed string value matching.
This class provides an enum with relaxed value matching, allowing case-insensitive
comparison of enum values. If a value is not found in the enum, it will attempt to
find a case-insensitive match. If no match is found, a `ValueError` is raised.
Usage:
To use this enum, simply subclass `RelaxedEnum` and define your enum values.
Example::
class AltitudeMode(RelaxedEnum):
clamp_to_ground = "clampToGround"
relative_to_ground = "relativeToGround"
absolute = "absolute"
my_value = AltitudeMode("CLAMPTOGROUND") # Case-insensitive match
print(my_value) # Output: AltitudeMode.clamp_to_ground
The subclass must define all values as strings.
"""
@classmethod
def _missing_(cls, value: object) -> "RelaxedEnum":
assert isinstance(value, str) # noqa: S101
value = value.lower()
for member in cls:
assert isinstance(member.value, str) # noqa: S101
if member.value.lower() == value.lower():
logger.warning(
"%s: Found case-insensitive match for %s in %r",
cls.__name__,
value,
member.value,
)
return member
msg = (
f"Unknown value '{value}' for {cls.__name__}. "
f"Known values are {', '.join(member.value for member in cls)}."
)
raise ValueError(msg)
[docs]
@unique
class Verbosity(Enum):
"""Enum to represent the different verbosity levels."""
terse = 0
normal = 1
verbose = 2
[docs]
@unique
class DateTimeResolution(RelaxedEnum):
"""Enum to represent the different date time resolutions."""
datetime = "dateTime"
date = "date"
year_month = "gYearMonth"
year = "gYear"
[docs]
@unique
class AltitudeMode(RelaxedEnum):
"""
Enum to represent the different altitude modes.
Specifies how altitude components in the <coordinates> element are interpreted.
Possible values are
- clampToGround - (default) Indicates to ignore an altitude specification
(for example, in the <coordinates> tag).
- relativeToGround - Sets the altitude of the element relative to the actual
ground elevation of a particular location.
For example, if the ground elevation of a location is exactly at sea level
and the altitude for a point is set to 9 meters,
then the elevation for the icon of a point placemark elevation is 9 meters
with this mode.
However, if the same coordinate is set over a location where the ground
elevation is 10 meters above sea level, then the elevation of the coordinate
is 19 meters.
A typical use of this mode is for placing telephone poles or a ski lift.
- absolute - Sets the altitude of the coordinate relative to sea level,
regardless of the actual elevation of the terrain beneath the element.
For example, if you set the altitude of a coordinate to 10 meters with an
absolute altitude mode, the icon of a point placemark will appear to be at
ground level if the terrain beneath is also 10 meters above sea level.
If the terrain is 3 meters above sea level, the placemark will appear elevated
above the terrain by 7 meters.
A typical use of this mode is for aircraft placement.
- relativeToSeaFloor - Interprets the altitude as a value in meters above the
sea floor.
If the point is above land rather than sea, the altitude will be interpreted
as being above the ground.
- clampToSeaFloor - The altitude specification is ignored, and the point will be
positioned on the sea floor.
If the point is on land rather than at sea, the point will be positioned on
the ground.
The Values relativeToSeaFloor and clampToSeaFloor are not part of the KML definition
but of the <gx:altitudeMode> a KML extension in the Google extension namespace,
allowing altitudes relative to the sea floor.
"""
clamp_to_ground = "clampToGround"
relative_to_ground = "relativeToGround"
absolute = "absolute"
clamp_to_sea_floor = "clampToSeaFloor"
relative_to_sea_floor = "relativeToSeaFloor"
[docs]
def get_ns_id(self) -> str:
"""Get the namespace for the altitude mode."""
if self in (
AltitudeMode.clamp_to_sea_floor,
AltitudeMode.relative_to_sea_floor,
):
return "gx"
return "kml"
[docs]
@unique
class DataType(RelaxedEnum):
"""Data type for SimpleField in extended data."""
string = "string"
int_ = "int"
uint = "uint"
short = "short"
ushort = "ushort"
float_ = "float"
double = "double"
bool_ = "bool"
[docs]
@unique
class RefreshMode(RelaxedEnum):
"""
Enum to represent the different refresh modes.
Specifies how the link is refreshed when the "camera" changes.
"""
on_change = "onChange"
on_interval = "onInterval"
on_expire = "onExpire"
[docs]
@unique
class ViewRefreshMode(RelaxedEnum):
"""
Enum to represent the different view refresh modes.
Specifies how the link is refreshed when the "camera" changes.
"""
never = "never"
on_stop = "onStop"
on_request = "onRequest"
on_region = "onRegion"
[docs]
@unique
class ColorMode(RelaxedEnum):
"""
Enum to represent the different color modes.
Specifies how the color is applied to the geometry.
"""
normal = "normal"
random = "random"
[docs]
@unique
class DisplayMode(RelaxedEnum):
"""
DisplayMode for BalloonStyle.
If <displayMode> is default, Google Earth uses the information supplied in <text>
to create a balloon .
If <displayMode> is hide, Google Earth does not display the balloon.
In Google Earth, clicking the List View icon for a Placemark whose balloon's
<displayMode> is hide causes Google Earth to fly to the Placemark.
"""
default = "default"
hide = "hide"
[docs]
@unique
class Shape(RelaxedEnum):
"""
Shape for PhotoOverlay.
The PhotoOverlay is projected onto the <shape>.
The <shape> can be one of the following:
- rectangle (default) - for an ordinary photo
- cylinder - for panoramas, which can be either partial or full cylinders
- sphere - for spherical panoramas
"""
rectangle = "rectangle"
cylinder = "cylinder"
sphere = "sphere"
[docs]
@unique
class GridOrigin(RelaxedEnum):
"""
GridOrigin for GroundOverlay.
Specifies where to begin numbering the tiles in each layer of the pyramid.
A value of lowerLeft specifies that row 1, column 1 of each layer is in
the bottom left corner of the grid.
"""
lower_left = "lowerLeft"
upper_left = "upperLeft"
[docs]
@unique
class Units(RelaxedEnum):
"""
Units for ScreenOverlay and Hotspot.
Specifies how the <x>, <y> values are interpreted.
"""
fraction = "fraction"
pixels = "pixels"
inset_pixels = "insetPixels"
[docs]
@unique
class PairKey(RelaxedEnum):
"""Key for Pair."""
normal = "normal"
highlight = "highlight"