Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gx:Track not supported #37

Closed
hyperknot opened this issue Apr 16, 2016 · 3 comments · Fixed by #92
Closed

gx:Track not supported #37

hyperknot opened this issue Apr 16, 2016 · 3 comments · Fixed by #92

Comments

@hyperknot
Copy link
Contributor

fastkml doesn't support gx:Track geometries.

what happens is that kml.py / Placemark / from_element method cannot detect a {http://www.google.com/kml/ext/2.2}Track element, thus arrives at No geometries found error.

sample file (saved with latest Google Earth):
https://gist.github.com/hyperknot/32ac836881b760aa3d02cc24d01a7dfd

@scls19fr
Copy link

scls19fr commented Nov 10, 2019

Hello,

I was looking for a similar feature.
I have a KML file with gx:Track, altitudeMode, when, gx:coord tags (see reference) and was expecting a way to use fastkml to iterate over positions... but I doesn't seems to be currently possible.

I will directly parse KML file using lxml or ElementTree but maybe a first step for supporting such features in this library could be that fastkml.kml.Placemark could hold simply xml elements as more "low level" lxml objects (ie using ElementTree API).

Kind regards

In [1]: from fastkml import kml

In [2]: fname = "sample.kml"

In [3]: k = kml.KML()

In [4]: with open(fname, 'rb') as fd:
   ...:     doc = fd.read()
   ...:     k.from_string(doc)
   ...:
No geometries found

In [5]: features = list(k.features())

In [6]: p = features[0]

@scls19fr
Copy link

scls19fr commented Nov 10, 2019

Here is some "low level" code using ElementTree

import xml.etree.ElementTree as ET
import datetime
from collections import namedtuple

Position = namedtuple("Position", ["dt", "longitude", "latitude", "altitude"])


def read_kml_track(fname):
    tree = ET.parse(fname)
    root = tree.getroot()
    ns = {
        "kmlns": "http://www.opengis.net/kml/2.2",
        "gx": "http://www.google.com/kml/ext/2.2",
    }
    track_elements = root.find("kmlns:Placemark/gx:Track", namespaces=ns)
    dt = None
    for elt in track_elements:
        tag = elt.tag
        if tag == "{%s}when" % ns["kmlns"]:
            dt = datetime.datetime.strptime(elt.text, "%Y-%m-%dT%H:%M:%S%z")
        elif tag == "{%s}coord" % ns["gx"]:
            s = elt.text
            longitude, latitude, altitude = s.replace(",", ".").split()
            longitude, latitude, altitude = map(float, (longitude, latitude, altitude))
            yield Position(dt, longitude, latitude, altitude)


fname = "sample.kml"
positions = read_kml_track(fname)
for p in positions:
    print(p)

I'm just pasting here if some people need a similar feature.

Not sure if my code can work with @hyperknot sample file.

@scls19fr
Copy link

This code also work with @hyperknot sample file

import xml.etree.ElementTree as ET
import datetime
from collections import namedtuple

Position = namedtuple("Position", ["dt", "longitude", "latitude", "altitude"])


def read_kml_track(fname):
    tree = ET.parse(fname)
    root = tree.getroot()
    ns = {
        "kmlns": "http://www.opengis.net/kml/2.2",
        "gx": "http://www.google.com/kml/ext/2.2",
    }
    # track_elements = root.find("kmlns:Placemark/gx:Track", namespaces=ns)
    track_elements = root.find("kmlns:Document/kmlns:Placemark/gx:Track", namespaces=ns)
    lst_when = track_elements.findall("kmlns:when", namespaces=ns)
    lst_coord = track_elements.findall("gx:coord", namespaces=ns)
    for when, coord in zip(lst_when, lst_coord):
        dt = datetime.datetime.strptime(when.text, "%Y-%m-%dT%H:%M:%S%z")
        s = coord.text
        longitude, latitude, altitude = s.replace(",", ".").split()
        longitude, latitude, altitude = map(float, (longitude, latitude, altitude))
        yield Position(dt, longitude, latitude, altitude)


# fname = "sample.kml"
fname = "gx_track.kml"
positions = read_kml_track(fname)
for p in positions:
    print(p)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants