-
-
Notifications
You must be signed in to change notification settings - Fork 149
Description
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:
Lines 487 to 508 in 352fb9d
| 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.