Skip to content

Commit

Permalink
Merge pull request #397 from cleder/396-kml-model
Browse files Browse the repository at this point in the history
396 kml model
  • Loading branch information
cleder authored Dec 1, 2024
2 parents c58c8da + abcc0d9 commit 6230566
Show file tree
Hide file tree
Showing 19 changed files with 1,176 additions and 125 deletions.
13 changes: 9 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ Introduction

.. inclusion-marker-do-not-remove
KML is an XML geospatial data format and an OGC_ standard that deserves a canonical python implementation.
KML is an XML geospatial data format and an OGC_ standard that deserves a canonical
python implementation.

Fastkml is a library to read, write and manipulate KML files. It aims to keep
it simple and fast (using lxml_ if available). Fast refers to the time you
Expand All @@ -19,9 +20,12 @@ For more details about the KML Specification, check out the `KML Reference
<https://developers.google.com/kml/documentation/kmlreference>`_ on the Google
developers site.

Geometries are handled as pygeoif_ objects.
Geometries are handled as pygeoif_ objects, which are compatible with any geometry that
implements the ``__geo_interface__`` protocol, such as shapely_.

Fastkml is continually tested
Fastkml is tested on `CPython <https://python.org>`_ and
`PyPy <https://www.pypy.org/>`_, but it should work on alternative
Python implementations (that implement the language specification *>=3.8*) as well.

|test| |hypothesis| |cov| |black| |mypy| |commit|

Expand Down Expand Up @@ -49,7 +53,7 @@ Fastkml is continually tested
:target: https://github.com/pre-commit/pre-commit
:alt: pre-commit

Is Maintained and documented:
Is maintained and documented:

|pypi| |conda-forge| |status| |license| |doc| |stats| |pyversion| |pyimpl| |dependencies| |downloads|

Expand Down Expand Up @@ -134,3 +138,4 @@ Please submit a PR with the features you'd like to see implemented.
.. _lxml: https://pypi.python.org/pypi/lxml
.. _arrow: https://pypi.python.org/pypi/arrow
.. _OGC: https://www.ogc.org/standard/kml/
.. _shapely: https://shapely.readthedocs.io/
9 changes: 9 additions & 0 deletions _typos.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
[default]
extend-ignore-identifiers-re = [
"04AFE6060F147CE66FBD",
"Lod",
"lod",
]



[default.extend-words]
lod = "lod"
Lod = "Lod"
Expand Down
5 changes: 3 additions & 2 deletions docs/HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
Changelog
=========

1.0.0dev0 (unreleased)
1.1.0 (unreleased)
----------------------

- Add support for ScreenOverlay
- Add support for ScreenOverlay and Model.
- allow parsing kml files without namespace declarations.


1.0 (2024/11/19)
Expand Down
9 changes: 9 additions & 0 deletions docs/fastkml.rst
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,15 @@ fastkml.mixins
:undoc-members:
:show-inheritance:

fastkml.model
--------------------

.. automodule:: fastkml.model
:members:
:undoc-members:
:show-inheritance:


fastkml.overlays
-----------------------

Expand Down
10 changes: 6 additions & 4 deletions docs/working_with_kml.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ We need to register the attributes of the KML object to be able to parse it:
>>> registry.register(
... CascadingStyle,
... RegistryItem(
... ns_ids=("kml",),
... ns_ids=("kml", ""),
... attr_name="style",
... node_name="Style",
... classes=(Style,),
Expand Down Expand Up @@ -156,8 +156,10 @@ And register the new element with the KML Document object:
The CascadingStyle object is now part of the KML document and can be accessed like any
other element.
When parsing the document we have to skip the validation as the ``gx:CascadingStyle`` is
not in the XSD Schema.

.. note::
When parsing the document we have to skip the validation by passing ``validate=False``
to ``KML.parse`` as the ``gx:CascadingStyle`` is not in the XSD Schema.

Create a new KML object and confirm that the new element is parsed correctly:

Expand Down Expand Up @@ -236,7 +238,7 @@ Now we can remove the CascadingStyle from the document and have a look at the re
<kml:displayMode>hide</kml:displayMode>
</kml:BalloonStyle>
</kml:Style>
<kml:Placemark id="04SAFE6060F147CE66FBD">
<kml:Placemark id="04AFE6060F147CE66FBD">
<kml:name>Ort1</kml:name>
<kml:LookAt>
<kml:longitude>10.06256752902339</kml:longitude>
Expand Down
4 changes: 2 additions & 2 deletions fastkml/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ def get_style_by_url(self, style_url: str) -> Optional[Union[Style, StyleMap]]:
registry.register(
_Container,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="features",
node_name=(
"Folder,Placemark,Document,GroundOverlay,PhotoOverlay,ScreenOverlay,"
Expand All @@ -351,7 +351,7 @@ def get_style_by_url(self, style_url: str) -> Optional[Union[Style, StyleMap]]:
registry.register(
Document,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="schemata",
node_name="Schema",
classes=(Schema,),
Expand Down
6 changes: 3 additions & 3 deletions fastkml/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def append(self, field: SimpleField) -> None:
registry.register(
Schema,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="fields",
node_name="SimpleField",
classes=(SimpleField,),
Expand Down Expand Up @@ -644,7 +644,7 @@ def append_data(self, data: SimpleData) -> None:
registry.register(
SchemaData,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="data",
node_name="SimpleData",
classes=(SimpleData,),
Expand Down Expand Up @@ -725,7 +725,7 @@ def __bool__(self) -> bool:
registry.register(
ExtendedData,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="elements",
node_name="Data,SchemaData",
classes=(
Expand Down
39 changes: 21 additions & 18 deletions fastkml/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
from fastkml.kml_base import _BaseObject
from fastkml.links import Link
from fastkml.mixins import TimeMixin
from fastkml.model import Model
from fastkml.registry import RegistryItem
from fastkml.registry import registry
from fastkml.styles import Style
Expand All @@ -78,6 +79,7 @@
LineString,
LinearRing,
Polygon,
Model,
MultiGeometry,
gx.MultiTrack,
gx.Track,
Expand Down Expand Up @@ -309,7 +311,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="name",
node_name="name",
classes=(str,),
Expand All @@ -320,7 +322,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="visibility",
node_name="visibility",
classes=(bool,),
Expand All @@ -332,7 +334,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="isopen",
node_name="open",
classes=(bool,),
Expand Down Expand Up @@ -366,7 +368,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="address",
node_name="address",
classes=(str,),
Expand All @@ -377,7 +379,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="phone_number",
node_name="phoneNumber",
classes=(str,),
Expand All @@ -388,7 +390,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="snippet",
node_name="Snippet",
classes=(Snippet,),
Expand All @@ -399,7 +401,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="description",
node_name="description",
classes=(str,),
Expand All @@ -410,7 +412,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="view",
node_name="Camera,LookAt",
classes=(
Expand All @@ -424,7 +426,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="times",
node_name="TimeSpan,TimeStamp",
classes=(
Expand All @@ -438,7 +440,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="style_url",
node_name="styleUrl",
classes=(StyleUrl,),
Expand All @@ -449,7 +451,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="styles",
node_name="Style,StyleMap",
classes=(
Expand All @@ -463,7 +465,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="region",
node_name="region",
classes=(Region,),
Expand All @@ -474,7 +476,7 @@ def __init__(
registry.register(
_Feature,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="extended_data",
node_name="ExtendedData",
classes=(ExtendedData,),
Expand Down Expand Up @@ -662,10 +664,10 @@ def geometry(self) -> Optional[AnyGeometryType]:
registry.register(
Placemark,
RegistryItem(
ns_ids=("kml", "gx"),
ns_ids=("kml", "gx", ""),
attr_name="kml_geometry",
node_name=(
"Point,LineString,LinearRing,Polygon,MultiGeometry,"
"Point,LineString,LinearRing,Polygon,MultiGeometry,Model,"
"gx:MultiTrack,gx:Track"
),
classes=(
Expand All @@ -674,6 +676,7 @@ def geometry(self) -> Optional[AnyGeometryType]:
LinearRing,
Polygon,
MultiGeometry,
Model,
gx.MultiTrack,
gx.Track,
),
Expand Down Expand Up @@ -891,7 +894,7 @@ def __bool__(self) -> bool:
registry.register(
NetworkLink,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="refresh_visibility",
node_name="refreshVisibility",
classes=(bool,),
Expand All @@ -903,7 +906,7 @@ def __bool__(self) -> bool:
registry.register(
NetworkLink,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="fly_to_view",
node_name="flyToView",
classes=(bool,),
Expand All @@ -915,7 +918,7 @@ def __bool__(self) -> bool:
registry.register(
NetworkLink,
RegistryItem(
ns_ids=("kml",),
ns_ids=("kml", ""),
attr_name="link",
node_name="Link",
classes=(Link,),
Expand Down
Loading

0 comments on commit 6230566

Please sign in to comment.