File indexing completed on 2024-04-21 03:50:42

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2011 Niko Sams <niko.sams@gmail.com>
0004 //
0005 
0006 #include <QObject>
0007 
0008 #include "GeoDataPoint.h"
0009 #include "GeoDataLinearRing.h"
0010 #include <GeoDataDocument.h>
0011 #include <GeoDataPlacemark.h>
0012 #include <MarbleDebug.h>
0013 #include <GeoDataFolder.h>
0014 #include <GeoDataTrack.h>
0015 #include <GeoDataExtendedData.h>
0016 #include <GeoDataSimpleArrayData.h>
0017 #include "TestUtils.h"
0018 
0019 #include <QDateTime>
0020 
0021 using namespace Marble;
0022 
0023 
0024 class TestGeoDataTrack : public QObject
0025 {
0026     Q_OBJECT
0027 private Q_SLOTS:
0028     void initTestCase();
0029     void defaultConstructor();
0030     void interpolate();
0031     void simpleParseTest();
0032     void removeBeforeTest();
0033     void removeAfterTest();
0034     void extendedDataParseTest();
0035     void withoutTimeTest();
0036 };
0037 
0038 void TestGeoDataTrack::initTestCase()
0039 {
0040     MarbleDebug::setEnabled( true );
0041 }
0042 
0043 void TestGeoDataTrack::defaultConstructor()
0044 {
0045     const GeoDataTrack track;
0046 
0047     QCOMPARE( track.size(), 0 );
0048     QCOMPARE( track.interpolate(), false );
0049     QCOMPARE( track.coordinatesList().size(), 0 );
0050     QCOMPARE( track.whenList().size(), 0 );
0051     QCOMPARE( track.lineString()->size(), 0 );
0052     QCOMPARE( track.latLonAltBox(), GeoDataLatLonAltBox() );
0053     QCOMPARE( track.coordinatesAt( QDateTime( QDate( 2014, 8, 16 ), QTime( 8, 0, 0 ) ) ), GeoDataCoordinates() );
0054 }
0055 
0056 void TestGeoDataTrack::interpolate()
0057 {
0058     GeoDataTrack track;
0059     track.setInterpolate( true );
0060 
0061     const QDateTime date1( QDate( 2014, 8, 16 ), QTime( 4, 57, 26 ) );
0062     const QDateTime date2( QDate( 2014, 8, 16 ), QTime( 12, 47, 16 ) );
0063     const GeoDataCoordinates coordinates1( 13.592294, 52.675926, 71, GeoDataCoordinates::Degree );
0064     const GeoDataCoordinates coordinates2( 13.572776, 53.517952, 97, GeoDataCoordinates::Degree );
0065     track.addPoint( date1, coordinates1 );
0066     track.addPoint( date2, coordinates2 );
0067 
0068     const GeoDataCoordinates interpolated = track.coordinatesAt( QDateTime( QDate( 2014, 8, 16 ), QTime( 8, 0, 0 ) ) );
0069     QCOMPARE( interpolated.longitude( GeoDataCoordinates::Degree ), 13.5848002666755789391572761815 );
0070     QCOMPARE( interpolated.latitude( GeoDataCoordinates::Degree ), 53.0031187444621139093214878812 );
0071 
0072     const GeoDataCoordinates beforeStart = track.coordinatesAt( QDateTime( QDate( 2014, 8, 16 ), QTime( 0, 0, 0 ) ) );
0073     QCOMPARE( beforeStart, GeoDataCoordinates() );
0074 
0075     const GeoDataCoordinates afterEnd = track.coordinatesAt( QDateTime( QDate( 2014, 8, 16 ), QTime( 23, 0, 0 ) ) );
0076     QCOMPARE( afterEnd, GeoDataCoordinates() );
0077 }
0078 
0079     //"Simple Example" from kmlreference
0080     QString simpleExampleContent(
0081 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
0082 "<kml xmlns=\"http://www.opengis.net/kml/2.2\""
0083 " xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
0084 "<Folder>"
0085 "  <Placemark>"
0086 "    <gx:Track>"
0087 "      <when>2010-05-28T02:02:09Z</when>"
0088 "      <when>2010-05-28T02:02:35Z</when>"
0089 "      <when>2010-05-28T02:02:44Z</when>"
0090 "      <when>2010-05-28T02:02:53Z</when>"
0091 "      <when>2010-05-28T02:02:54Z</when>"
0092 "      <when>2010-05-28T02:02:55Z</when>"
0093 "      <when>2010-05-28T02:02:56Z</when>"
0094 "      <gx:coord>-122.207881 37.371915 156.000000</gx:coord>"
0095 "      <gx:coord>-122.205712 37.373288 152.000000</gx:coord>"
0096 "      <gx:coord>-122.204678 37.373939 147.000000</gx:coord>"
0097 "      <gx:coord>-122.203572 37.374630 142.199997</gx:coord>"
0098 "      <gx:coord>-122.203451 37.374706 141.800003</gx:coord>"
0099 "      <gx:coord>-122.203329 37.374780 141.199997</gx:coord>"
0100 "      <gx:coord>-122.203207 37.374857 140.199997</gx:coord>"
0101 "    </gx:Track>"
0102 "  </Placemark>"
0103 "</Folder>"
0104 "</kml>" );
0105 
0106 void TestGeoDataTrack::simpleParseTest()
0107 {
0108     GeoDataDocument* dataDocument = parseKml( simpleExampleContent );
0109     GeoDataFolder *folder = dataDocument->folderList().at( 0 );
0110     QCOMPARE( folder->placemarkList().size(), 1 );
0111     GeoDataPlacemark* placemark = folder->placemarkList().at( 0 );
0112     QCOMPARE( placemark->geometry()->geometryId(), GeoDataTrackId );
0113     GeoDataTrack* track = static_cast<GeoDataTrack*>( placemark->geometry() );
0114     QCOMPARE( track->size(), 7 );
0115     {
0116         QDateTime when = track->whenList().at( 0 );
0117         QCOMPARE( when, QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 9 ), Qt::UTC ) );
0118     }
0119     {
0120         GeoDataCoordinates coord = track->coordinatesList().at( 0 );
0121         QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 );
0122         QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 );
0123         QCOMPARE( coord.altitude(), 156.000000 );
0124     }
0125     {
0126         GeoDataCoordinates coord = track->coordinatesAt( QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 9 ), Qt::UTC ) );
0127         QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 );
0128         QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 );
0129         QCOMPARE( coord.altitude(), 156.000000 );
0130     }
0131 
0132     delete dataDocument;
0133 }
0134 
0135 void TestGeoDataTrack::removeBeforeTest()
0136 {
0137     GeoDataDocument* dataDocument = parseKml( simpleExampleContent );
0138     GeoDataFolder *folder = dataDocument->folderList().at( 0 );
0139     QCOMPARE( folder->placemarkList().size(), 1 );
0140     GeoDataPlacemark* placemark = folder->placemarkList().at( 0 );
0141     QCOMPARE( placemark->geometry()->geometryId(), GeoDataTrackId );
0142     GeoDataTrack* track = static_cast<GeoDataTrack*>( placemark->geometry() );
0143     QCOMPARE( track->size(), 7 );
0144     track->removeBefore( QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 54 ), Qt::UTC ) );
0145     QCOMPARE( track->size(), 3 );
0146     {
0147         QDateTime when = track->whenList().at( 0 );
0148         QCOMPARE( when, QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 54 ), Qt::UTC ) );
0149     }
0150     {
0151         QDateTime when = track->whenList().at( 2 );
0152         QCOMPARE( when, QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 56 ), Qt::UTC ) );
0153     }
0154     {
0155         GeoDataCoordinates coord = track->coordinatesList().at( 0 );
0156         QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.203451 );
0157         QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.374706 );
0158         QCOMPARE( coord.altitude(), 141.800003 );
0159     }
0160 
0161     delete dataDocument;
0162 }
0163 
0164 void TestGeoDataTrack::removeAfterTest()
0165 {
0166     GeoDataDocument* dataDocument = parseKml( simpleExampleContent );
0167     GeoDataFolder *folder = dataDocument->folderList().at( 0 );
0168     QCOMPARE( folder->placemarkList().size(), 1 );
0169     GeoDataPlacemark* placemark = folder->placemarkList().at( 0 );
0170     QCOMPARE( placemark->geometry()->geometryId(), GeoDataTrackId );
0171     GeoDataTrack* track = static_cast<GeoDataTrack*>( placemark->geometry() );
0172     QCOMPARE( track->size(), 7 );
0173     track->removeAfter( QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 54 ), Qt::UTC ) );
0174     QCOMPARE( track->size(), 5 );
0175     {
0176         QDateTime when = track->whenList().at( 0 );
0177         QCOMPARE( when, QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 9 ), Qt::UTC ) );
0178     }
0179     {
0180         QDateTime when = track->whenList().at( 4 );
0181         QCOMPARE( when, QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 54 ), Qt::UTC ) );
0182     }
0183     {
0184         GeoDataCoordinates coord = track->coordinatesList().at( 0 );
0185         QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 );
0186         QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 );
0187         QCOMPARE( coord.altitude(), 156.000000 );
0188     }
0189 
0190     delete dataDocument;
0191 }
0192 
0193 void TestGeoDataTrack::extendedDataParseTest()
0194 {
0195     //"Example of Track with Extended Data" from kmlreference
0196     QString content(
0197 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
0198 "<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
0199 "  <Document>"
0200 "    <name>GPS device</name>"
0201 "    <Snippet>Created Wed Jun 2 15:33:39 2010</Snippet>"
0202 "    <Schema id=\"schema\">"
0203 "      <gx:SimpleArrayField name=\"heartrate\" type=\"int\">"
0204 "        <displayName>Heart Rate</displayName>"
0205 "      </gx:SimpleArrayField>"
0206 "      <gx:SimpleArrayField name=\"cadence\" type=\"int\">"
0207 "        <displayName>Cadence</displayName>"
0208 "      </gx:SimpleArrayField>"
0209 "      <gx:SimpleArrayField name=\"power\" type=\"float\">"
0210 "        <displayName>Power</displayName>"
0211 "      </gx:SimpleArrayField>"
0212 "    </Schema>"
0213 "    <Folder>"
0214 "      <name>Tracks</name>"
0215 "      <Placemark>"
0216 "        <name>2010-05-28T01:16:35.000Z</name>"
0217 "        <styleUrl>#multiTrack</styleUrl>"
0218 "        <gx:Track>"
0219 "          <when>2010-05-28T02:02:09Z</when>"
0220 "          <when>2010-05-28T02:02:35Z</when>"
0221 "          <when>2010-05-28T02:02:44Z</when>"
0222 "          <when>2010-05-28T02:02:53Z</when>"
0223 "          <when>2010-05-28T02:02:54Z</when>"
0224 "          <when>2010-05-28T02:02:55Z</when>"
0225 "          <when>2010-05-28T02:02:56Z</when>"
0226 "          <gx:coord>-122.207881 37.371915 156.000000</gx:coord>"
0227 "          <gx:coord>-122.205712 37.373288 152.000000</gx:coord>"
0228 "          <gx:coord>-122.204678 37.373939 147.000000</gx:coord>"
0229 "          <gx:coord>-122.203572 37.374630 142.199997</gx:coord>"
0230 "          <gx:coord>-122.203451 37.374706 141.800003</gx:coord>"
0231 "          <gx:coord>-122.203329 37.374780 141.199997</gx:coord>"
0232 "          <gx:coord>-122.203207 37.374857 140.199997</gx:coord>"
0233 "          <ExtendedData>"
0234 "            <SchemaData schemaUrl=\"#schema\">"
0235 "              <gx:SimpleArrayData name=\"cadence\">"
0236 "                <gx:value>86</gx:value>"
0237 "                <gx:value>103</gx:value>"
0238 "                <gx:value>108</gx:value>"
0239 "                <gx:value>113</gx:value>"
0240 "                <gx:value>113</gx:value>"
0241 "                <gx:value>113</gx:value>"
0242 "                <gx:value>113</gx:value>"
0243 "              </gx:SimpleArrayData>"
0244 "              <gx:SimpleArrayData name=\"heartrate\">"
0245 "                <gx:value>181</gx:value>"
0246 "                <gx:value>177</gx:value>"
0247 "                <gx:value>175</gx:value>"
0248 "                <gx:value>173</gx:value>"
0249 "                <gx:value>173</gx:value>"
0250 "                <gx:value>173</gx:value>"
0251 "                <gx:value>173</gx:value>"
0252 "              </gx:SimpleArrayData>"
0253 "              <gx:SimpleArrayData name=\"power\">"
0254 "                <gx:value>327.0</gx:value>"
0255 "                <gx:value>177.0</gx:value>"
0256 "                <gx:value>179.0</gx:value>"
0257 "                <gx:value>162.0</gx:value>"
0258 "                <gx:value>166.0</gx:value>"
0259 "                <gx:value>177.0</gx:value>"
0260 "                <gx:value>183.0</gx:value>"
0261 "              </gx:SimpleArrayData>"
0262 "            </SchemaData>"
0263 "          </ExtendedData>"
0264 "        </gx:Track>"
0265 "      </Placemark>"
0266 "    </Folder>"
0267 "  </Document>"
0268 "</kml>" );
0269 
0270     GeoDataDocument* dataDocument = parseKml( content );
0271     GeoDataFolder *folder = dataDocument->folderList().at( 0 );
0272     QCOMPARE( folder->placemarkList().size(), 1 );
0273     GeoDataPlacemark* placemark = folder->placemarkList().at( 0 );
0274     QCOMPARE( placemark->geometry()->geometryId(), GeoDataTrackId );
0275     GeoDataTrack* track = static_cast<GeoDataTrack*>( placemark->geometry() );
0276     QCOMPARE( track->size(), 7 );
0277 
0278     {
0279         GeoDataSimpleArrayData *cadence = track->extendedData().simpleArrayData( "cadence" );
0280         QCOMPARE( cadence->size(), 7 );
0281         QCOMPARE( cadence->valueAt( 0 ), QVariant( "86" ) );
0282         QCOMPARE( cadence->valueAt( 6 ), QVariant( "113" ) );
0283     }
0284     {
0285         GeoDataSimpleArrayData *hr = track->extendedData().simpleArrayData( "heartrate" );
0286         QCOMPARE( hr->size(), 7 );
0287         QCOMPARE( hr->valueAt( 0 ), QVariant( "181" ) );
0288         QCOMPARE( hr->valueAt( 6 ), QVariant( "173" ) );
0289     }
0290     {
0291         GeoDataSimpleArrayData *power = track->extendedData().simpleArrayData( "power" );
0292         QCOMPARE( power->size(), 7 );
0293         QCOMPARE( power->valueAt( 0 ), QVariant( "327.0" ) );
0294         QCOMPARE( power->valueAt( 6 ), QVariant( "183.0" ) );
0295     }
0296 
0297     delete dataDocument;
0298 }
0299 
0300 void TestGeoDataTrack::withoutTimeTest()
0301 {
0302     //"Simple Example" from kmlreference; when elements emptied
0303     QString content(
0304 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
0305 "<kml xmlns=\"http://www.opengis.net/kml/2.2\""
0306 " xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
0307 "<Folder>"
0308 "  <Placemark>"
0309 "    <gx:Track>"
0310 "      <when></when>"
0311 "      <when></when>"
0312 "      <when></when>"
0313 "      <when></when>"
0314 "      <when></when>"
0315 "      <when></when>"
0316 "      <when></when>"
0317 "      <gx:coord>-122.207881 37.371915 156.000000</gx:coord>"
0318 "      <gx:coord>-122.205712 37.373288 152.000000</gx:coord>"
0319 "      <gx:coord>-122.204678 37.373939 147.000000</gx:coord>"
0320 "      <gx:coord>-122.203572 37.374630 142.199997</gx:coord>"
0321 "      <gx:coord>-122.203451 37.374706 141.800003</gx:coord>"
0322 "      <gx:coord>-122.203329 37.374780 141.199997</gx:coord>"
0323 "      <gx:coord>-122.203207 37.374857 140.199997</gx:coord>"
0324 "    </gx:Track>"
0325 "  </Placemark>"
0326 "</Folder>"
0327 "</kml>" );
0328 
0329     GeoDataDocument* dataDocument = parseKml( content );
0330     GeoDataFolder *folder = dataDocument->folderList().at( 0 );
0331     QCOMPARE( folder->placemarkList().size(), 1 );
0332     GeoDataPlacemark* placemark = folder->placemarkList().at( 0 );
0333     QCOMPARE( placemark->geometry()->geometryId(), GeoDataTrackId );
0334     GeoDataTrack* track = static_cast<GeoDataTrack*>( placemark->geometry() );
0335     QCOMPARE( track->size(), 7 );
0336     {
0337         GeoDataCoordinates coord = track->coordinatesList().at( 0 );
0338         QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 );
0339         QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 );
0340         QCOMPARE( coord.altitude(), 156.000000 );
0341     }
0342 
0343     {
0344         const GeoDataLineString *lineString = track->lineString();
0345         QCOMPARE( lineString->size(), 7 );
0346         GeoDataCoordinates coord = lineString->at( 0 );
0347         QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 );
0348         QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 );
0349         QCOMPARE( coord.altitude(), 156.000000 );
0350     }
0351 
0352     delete dataDocument;
0353 }
0354 
0355 QTEST_MAIN( TestGeoDataTrack )
0356 
0357 #include "TestGeoDataTrack.moc"
0358