Skip to content

The current KML parser does not support KML version 2.3 #634

@huyz-git

Description

@huyz-git

Currently, when parsing KML tracks, the parser first read all "when" tags and create trackpoints, and then it read all "coord" tags and check whether the number of "when" and "coord" tags are the same:

while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("when")) {
segment.append(Trackpoint());
segment.last().setTimestamp(time());
if (_reader.error())
return;
} else if (_reader.name() == QLatin1String("coord")) {
if (i == segment.size()) {
_reader.raiseError(error);
return;
} else if (!coord(segment[i])) {
_reader.raiseError("Invalid coordinates");
return;
}
if (segment.at(i).coordinates().isNull())
empty = true;
i++;
} else if (_reader.name() == QLatin1String("ExtendedData"))
extendedData(segment);
else
_reader.skipCurrentElement();
}

This logic is fine for Google's KML extension version 2.2, in which the "when" and "coord" tag are inside a "sequence" defination:

  <element name="Track" type="gx:TrackType"
    substitutionGroup="kml:AbstractGeometryGroup"/>

  <complexType name="TrackType">
    <complexContent>
      <extension base="kml:AbstractGeometryType">
        <sequence>
          <element ref="kml:extrude" minOccurs="0"/>
          <element ref="kml:tessellate" minOccurs="0"/>
          <element ref="kml:altitudeModeGroup" minOccurs="0"/>
          <element ref="kml:when" minOccurs="0" maxOccurs="unbounded"/>
          <element ref="gx:coord" minOccurs="0" maxOccurs="unbounded"/>
          <element ref="gx:angles" minOccurs="0" maxOccurs="unbounded"/>
          <element ref="kml:Model" minOccurs="0"/>
          <element ref="kml:ExtendedData" minOccurs="0"/>
          <element ref="gx:AbstractTrackSimpleExtensionGroup" minOccurs="0"
            maxOccurs="unbounded"/>
        </sequence>
      </extension>
    </complexContent>
  </complexType>

(see line 239 to 256 at kml22gx.xsd ), so that all "when" tags should be in front of "coord" tag.

However, upstream Opengis now updated KML standard to 2.3, in which the order of these tags is no longer fixed:

  <element name="Track" type="kml:TrackType"
      substitutionGroup="kml:AbstractGeometryGroup"/>
  <complexType name="TrackType">
    <complexContent>
      <extension base="kml:AbstractGeometryType">
        <all>
          <element ref="kml:extrude" minOccurs="0"/>
          <element ref="kml:tessellate" minOccurs="0"/>
          <group ref="kml:AltitudeModeGroup"/>
          <element ref="kml:when" minOccurs="0" maxOccurs="unbounded"/>
          <element ref="kml:coord" minOccurs="0" maxOccurs="unbounded"/>
          <element ref="kml:angles" minOccurs="0" maxOccurs="unbounded"/>
          <element ref="kml:Model" minOccurs="0"/>
          <element ref="kml:ExtendedData" minOccurs="0"/>
          <element ref="kml:TrackSimpleExtensionGroup" minOccurs="0"
            maxOccurs="unbounded"/>
          <element ref="kml:TrackObjectExtensionGroup" minOccurs="0"
            maxOccurs="unbounded"/>
        </all>
        <assert test="count(./kml:when) = count(./kml:coord)">
          <annotation>
            <documentation>kml:Track must have an equal number of kml:when and kml:coord elements.</documentation>
          </annotation>
        </assert>
        <assert test="if(./kml:angles) then count(./kml:angles) = count(./kml:when) else true()">
          <annotation>
            <documentation>If kml:angles appears in kml:Track there must be an equal number of kml:angles and kml:when elements.</documentation>
          </annotation>
        </assert>
      </extension>
    </complexContent>
  </complexType>

(see line 1364 to 1393 at ogckml23.xsd , they are inside a "all" defination)

The current logic does not work if the "when" tags is after "coord" tags, in such case, when reading the first "coord" tags, it will result "gx:coord/when element count mismatch" error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions