void TestGeoDataTrack::simpleParseTest() { GeoDataDocument* dataDocument = parseKml( simpleExampleContent ); GeoDataFolder *folder = dataDocument->folderList().at( 0 ); QCOMPARE( folder->placemarkList().size(), 1 ); GeoDataPlacemark* placemark = folder->placemarkList().at( 0 ); QCOMPARE( placemark->geometry()->geometryId(), GeoDataTrackId ); GeoDataTrack* track = static_cast<GeoDataTrack*>( placemark->geometry() ); QCOMPARE( track->size(), 7 ); { QDateTime when = track->whenList().at( 0 ); QCOMPARE( when, QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 9 ), Qt::UTC ) ); } { GeoDataCoordinates coord = track->coordinatesList().at( 0 ); QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 ); QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 ); QCOMPARE( coord.altitude(), 156.000000 ); } { GeoDataCoordinates coord = track->coordinatesAt( QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 9 ), Qt::UTC ) ); QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 ); QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 ); QCOMPARE( coord.altitude(), 156.000000 ); } delete dataDocument; }
void TestGeoDataTrack::withoutTimeTest() { //"Simple Example" from kmlreference; when elements emptied QString content( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" "<kml xmlns=\"http://www.opengis.net/kml/2.2\"" " xmlns:gx=\"http://www.google.com/kml/ext/2.2\">" "<Folder>" " <Placemark>" " <gx:Track>" " <when></when>" " <when></when>" " <when></when>" " <when></when>" " <when></when>" " <when></when>" " <when></when>" " <gx:coord>-122.207881 37.371915 156.000000</gx:coord>" " <gx:coord>-122.205712 37.373288 152.000000</gx:coord>" " <gx:coord>-122.204678 37.373939 147.000000</gx:coord>" " <gx:coord>-122.203572 37.374630 142.199997</gx:coord>" " <gx:coord>-122.203451 37.374706 141.800003</gx:coord>" " <gx:coord>-122.203329 37.374780 141.199997</gx:coord>" " <gx:coord>-122.203207 37.374857 140.199997</gx:coord>" " </gx:Track>" " </Placemark>" "</Folder>" "</kml>" ); GeoDataDocument* dataDocument = parseKml( content ); GeoDataFolder *folder = dataDocument->folderList().at( 0 ); QCOMPARE( folder->placemarkList().size(), 1 ); GeoDataPlacemark* placemark = folder->placemarkList().at( 0 ); QCOMPARE( placemark->geometry()->geometryId(), GeoDataTrackId ); GeoDataTrack* track = static_cast<GeoDataTrack*>( placemark->geometry() ); QCOMPARE( track->size(), 7 ); { GeoDataCoordinates coord = track->coordinatesList().at( 0 ); QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 ); QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 ); QCOMPARE( coord.altitude(), 156.000000 ); } { const GeoDataLineString *lineString = track->lineString(); QCOMPARE( lineString->size(), 7 ); GeoDataCoordinates coord = lineString->at( 0 ); QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 ); QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 ); QCOMPARE( coord.altitude(), 156.000000 ); } delete dataDocument; }
void MonavMap::parseBoundingBox( const QFileInfo &file ) { GeoDataLineString points; bool tooLarge = false; QFile input( file.absoluteFilePath() ); if ( input.open( QFile::ReadOnly ) ) { GeoDataParser parser( GeoData_KML ); if ( !parser.read( &input ) ) { mDebug() << "Could not parse file: " << parser.errorString(); return; } GeoDocument *doc = parser.releaseDocument(); input.close(); GeoDataDocument *document = dynamic_cast<GeoDataDocument*>( doc ); QVector<GeoDataPlacemark*> placemarks = document->placemarkList(); if ( placemarks.size() == 1 ) { GeoDataPlacemark* placemark = placemarks.first(); m_name = placemark->name(); m_version = placemark->extendedData().value( "version" ).value().toString(); m_date = placemark->extendedData().value( "date" ).value().toString(); m_transport = placemark->extendedData().value( "transport" ).value().toString(); m_payload = placemark->extendedData().value( "payload" ).value().toString(); GeoDataMultiGeometry* geometry = dynamic_cast<GeoDataMultiGeometry*>( placemark->geometry() ); if ( geometry->size() > 1500 ) { tooLarge = true; } for ( int i = 0; geometry && i < geometry->size(); ++i ) { GeoDataLinearRing* poly = dynamic_cast<GeoDataLinearRing*>( geometry->child( i ) ); if ( poly ) { for ( int j = 0; j < poly->size(); ++j ) { points << poly->at( j ); } m_tiles.push_back( *poly ); } if ( poly->size() > 1500 ) { tooLarge = true; } } } else { mDebug() << "File " << file.absoluteFilePath() << " does not contain one placemark, but " << placemarks.size(); } delete doc; } m_boundingBox = points.latLonAltBox(); if ( tooLarge ) { // The bounding box polygon is rather complicated, therefore not allowing a quick check // and also occupying memory. Discard the polygon and only store the rectangular bounding // box. Only happens for non-simplified bounding box polygons. mDebug() << "Discarding too large bounding box poylgon for " << file.absoluteFilePath() << ". Please check for a map update."; m_tiles.clear(); } }
GeoDataLatLonAltBox GeoDataContainer::latLonAltBox() const { Q_D(const GeoDataContainer); GeoDataLatLonAltBox result; QVector<GeoDataFeature*>::const_iterator it = d->m_vector.constBegin(); QVector<GeoDataFeature*>::const_iterator end = d->m_vector.constEnd(); for (; it != end; ++it) { // Get all the placemarks from GeoDataContainer if ( (*it)->nodeType() == GeoDataTypes::GeoDataPlacemarkType ) { GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>(*it); // Only use visible placemarks for extracting their latLonAltBox and // making an union with the global latLonAltBox Marble will fit its // zoom to if (placemark->isVisible()) { if (result.isEmpty()) { result = placemark->geometry()->latLonAltBox(); } else { result |= placemark->geometry()->latLonAltBox(); } } } else if ( (*it)->nodeType() == GeoDataTypes::GeoDataFolderType || (*it)->nodeType() == GeoDataTypes::GeoDataDocumentType ) { GeoDataContainer *container = static_cast<GeoDataContainer*>(*it); if (result.isEmpty()) { result = container->latLonAltBox(); } else { result |= container->latLonAltBox(); } } } return result; }
const GeoDataLatLonAltBox& GeoDataRegion::latLonAltBox() const { // FIXME: This isn't exactly what a 'const' function should do, is it? // If the latLonAltBox hasn't been set try to determine it automatically if ( !d->m_latLonAltBox ) { // If there is a parent try to if ( d->m_parent ) { if ( d->m_parent->nodeType() == GeoDataTypes::GeoDataPlacemarkType ) { GeoDataPlacemark * placemark = dynamic_cast<GeoDataPlacemark*>( d->m_parent ); GeoDataGeometry * geometry = placemark->geometry(); if ( geometry ) { // TODO: automatically calculate the geometry from the // GeoDataGeometry object. // return geometry->latLonAltBox(); } d->m_latLonAltBox = new GeoDataLatLonAltBox( placemark->coordinate() ); } else { // If the parent is not a placemark then create a default LatLonAltBox // FIXME: reference a shared object instead d->m_latLonAltBox = new GeoDataLatLonAltBox(); } } else { // If there is no parent then create a default LatLonAltBox // FIXME: reference a shared object instead d->m_latLonAltBox = new GeoDataLatLonAltBox(); } } return *(d->m_latLonAltBox); }
void TestModel::simpleParseTest() { QString const centerContent ( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" "<kml xmlns=\"http://www.opengis.net/kml/2.2\">" "<Placemark>" "<Model id=\"model_4\">" "<altitudeMode>relativeToGround</altitudeMode>" "<Location>" "<longitude>-105.27</longitude>" "<latitude>40.00</latitude>" "<altitude>23.4</altitude>" "</Location>" "<Orientation>" "<heading>1</heading>" "<tilt>2</tilt>" "<roll>3</roll>" "</Orientation>" "<Scale>" "<x>3</x>" "<y>4</y>" "<z>5</z>" "</Scale>" "<Link>" "<href>MackyBldg.kmz/files/CU Macky.dae</href>" "<refreshMode>onExpire</refreshMode>" "</Link>" "<ResourceMap id=\"resourcemap_for_model_4\">" "<Alias>" "<sourceHref>../files/CU-Macky-4sideturretnoCulling.jpg</sourceHref>" "<targetHref>../files/CU-Macky-4sideturretnoCulling.jpg</targetHref>" "</Alias>" "</ResourceMap>" "</Model>" "</Placemark>" "</kml>" ); GeoDataDocument* dataDocument = parseKml( centerContent ); QCOMPARE( dataDocument->placemarkList().size(), 1 ); GeoDataPlacemark *placemark = dataDocument->placemarkList().at( 0 ); GeoDataModel *model = dynamic_cast<GeoDataModel*>( placemark->geometry() ); QVERIFY( model != 0 ); QCOMPARE( model->altitudeMode(), RelativeToGround); QCOMPARE( model->location().altitude(), 23.4); QCOMPARE( model->location().latitude(GeoDataCoordinates::Degree), 40.00 ); QCOMPARE( model->location().longitude(GeoDataCoordinates::Degree), -105.27 ); QCOMPARE( model->orientation().heading(), 1.0); QCOMPARE( model->orientation().tilt(), 2.0); QCOMPARE( model->orientation().roll(), 3.0); QCOMPARE( model->scale().x(), 3.0); QCOMPARE( model->scale().y(), 4.0); QCOMPARE( model->scale().z(), 5.0); QCOMPARE( model->link().href(), QString("MackyBldg.kmz/files/CU Macky.dae")); QCOMPARE( model->link().refreshMode(), GeoDataLink::OnExpire ); QCOMPARE( model->targetHref(), QString("../files/CU-Macky-4sideturretnoCulling.jpg")); QCOMPARE( model->sourceHref(), QString("../files/CU-Macky-4sideturretnoCulling.jpg")); delete dataDocument; }
void TestTrack::simpleParseTest() { //example track recorded using a Garmin Vista HCx and downloaded using gpsbabel QString content( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" "<gpx" " version=\"1.0\"" " creator=\"GPSBabel - http://www.gpsbabel.org\"" " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" " xmlns=\"http://www.topografix.com/GPX/1/0\"" " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">" "<time>2011-07-03T14:19:57Z</time>" "<bounds minlat=\"47.231073193\" minlon=\"12.549449634\" maxlat=\"48.502999926\" maxlon=\"14.302069964\"/>" "<trk>" " <name>test track</name>" "<number>1</number>" "<trkseg>" "<trkpt lat=\"47.231477033\" lon=\"12.560534449\">" " <ele>1130.647705</ele>" " <time>2011-06-24T10:33:40Z</time>" "</trkpt>" "<trkpt lat=\"47.231486840\" lon=\"12.560604354\">" " <ele>1127.763672</ele>" " <time>2011-06-24T10:33:55Z</time>" "</trkpt>" "<trkpt lat=\"47.231497569\" lon=\"12.560612401\">" " <ele>1121.995850</ele>" " <time>2011-06-24T10:34:00Z</time>" "</trkpt>" "</trkseg>" "</trk>" "</gpx>" ); GpxParser parser; QByteArray array( content.toUtf8() ); QBuffer buffer( &array ); buffer.open( QIODevice::ReadOnly ); qDebug() << "Buffer content:" << endl << buffer.buffer(); if ( !parser.read( &buffer ) ) { QFAIL( "Could not parse data!" ); return; } GeoDocument* document = parser.releaseDocument(); QVERIFY( document ); GeoDataDocument *dataDocument = static_cast<GeoDataDocument*>( document ); GeoDataPlacemark* placemark = dataDocument->placemarkList().at( 0 ); QCOMPARE( placemark->geometry()->geometryId(), GeoDataMultiGeometryId ); GeoDataMultiGeometry* multiGeo = static_cast<GeoDataMultiGeometry*>( placemark->geometry() ); GeoDataTrack* track = static_cast<GeoDataTrack*>( &multiGeo->at( 0 ) ); QCOMPARE( track->size(), 3 ); { QDateTime when = track->whenList().at( 0 ); QCOMPARE( when, QDateTime( QDate( 2011, 6, 24 ), QTime( 10, 33, 40 ), Qt::UTC ) ); } { GeoDataCoordinates coord = track->coordinatesAt( 0 ); QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), 12.560534449 ); QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 47.231477033 ); QCOMPARE( coord.altitude(), 1130.647705 ); } { GeoDataCoordinates coord = track->coordinatesAt( QDateTime( QDate( 2011, 6, 24 ), QTime( 10, 33, 40 ), Qt::UTC ) ); QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), 12.560534449 ); QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 47.231477033 ); QCOMPARE( coord.altitude(), 1130.647705 ); } { const GeoDataLineString* lineString = track->lineString(); QCOMPARE( lineString->size(), 3 ); GeoDataCoordinates coord = lineString->at( 0 ); QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), 12.560534449 ); QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 47.231477033 ); QCOMPARE( coord.altitude(), 1130.647705 ); } delete document; }
void TestTrack::extendedDataHeartRateTest() { //example track recorded using a Garmin Oregon 450 and downloading using it's USB mass storare mode QString content( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" "<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" " " xmlns:gpxx=\"http://www.garmin.com/xmlschemas/WaypointExtension/v1\" " " xmlns:gpxtrx=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\" " " xmlns:gpxtpx=\"http://www.garmin.com/xmlschemas/TrackPointExtension/v1\" " " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " " creator=\"Oregon 450\" " " version=\"1.1\" " " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 " "http://www.topografix.com/GPX/1/1/gpx.xsd " "http://www.garmin.com/xmlschemas/WaypointExtension/v1 " "http://www8.garmin.com/xmlschemas/WaypointExtensionv1.xsd " "http://www.garmin.com/xmlschemas/TrackPointExtension/v1 " "http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd\" " " >" " <metadata>" " <link href=\"http://www.garmin.com\">" " <text>Garmin International</text>" " </link>" " <time>2011-10-29T15:29:19Z</time>" " </metadata>" " <trk>" " <name>29-OKT-11 17:29:17</name>" " <extensions>" " <gpxtrx:TrackExtension>" " <gpxtrx:DisplayColor>Black</gpxtrx:DisplayColor>" " </gpxtrx:TrackExtension>" " </extensions>" " <trkseg>" " <trkpt lat=\"47.951347\" lon=\"13.228035\">" " <ele>571.16</ele>" " <time>2011-10-29T08:35:31Z</time>" " <extensions>" " <gpxtpx:TrackPointExtension>" " <gpxtpx:hr>108</gpxtpx:hr>" " </gpxtpx:TrackPointExtension>" " </extensions>" " </trkpt>" " <trkpt lat=\"47.951348\" lon=\"13.228035\">" " <ele>573.56</ele>" " <time>2011-10-29T08:35:37Z</time>" " <extensions>" " <gpxtpx:TrackPointExtension>" " <gpxtpx:hr>109</gpxtpx:hr>" " </gpxtpx:TrackPointExtension>" " </extensions>" " </trkpt>" " <trkpt lat=\"47.951349\" lon=\"13.228036\">" " <ele>572.12</ele>" " <time>2011-10-29T08:35:43Z</time>" " <extensions>" " <gpxtpx:TrackPointExtension>" " <gpxtpx:hr>110</gpxtpx:hr>" " </gpxtpx:TrackPointExtension>" " </extensions>" " </trkpt>" " </trkseg>" " </trk>" "</gpx>" ); GpxParser parser; QByteArray array( content.toUtf8() ); QBuffer buffer( &array ); buffer.open( QIODevice::ReadOnly ); qDebug() << "Buffer content:" << endl << buffer.buffer(); if ( !parser.read( &buffer ) ) { QFAIL( "Could not parse data!" ); return; } GeoDocument* document = parser.releaseDocument(); QVERIFY( document ); GeoDataDocument *dataDocument = static_cast<GeoDataDocument*>( document ); GeoDataPlacemark* placemark = dataDocument->placemarkList().at( 0 ); QCOMPARE( placemark->geometry()->geometryId(), GeoDataMultiGeometryId ); GeoDataMultiGeometry* multiGeo = static_cast<GeoDataMultiGeometry*>( placemark->geometry() ); GeoDataTrack* track = static_cast<GeoDataTrack*>( &multiGeo->at( 0 ) ); QCOMPARE( track->size(), 3 ); { GeoDataSimpleArrayData* hr = track->extendedData().simpleArrayData( "heartrate" ); QCOMPARE( hr->size(), 3 ); QCOMPARE( hr->valueAt( 0 ), QVariant( "108" ) ); QCOMPARE( hr->valueAt( 2 ), QVariant( "110" ) ); } delete document; }
void CountryByShape::postQuestion( QObject *gameObject ) { //Find a random placemark Q_ASSERT_X( d->m_countryNames, "CountryByShape::postQuestion", "CountryByShapePrivate::m_countryNames is NULL" ); QVector<GeoDataPlacemark*> countryPlacemarks = d->m_countryNames->placemarkList(); uint randomSeed = uint(QTime::currentTime().msec()); qsrand( randomSeed ); bool found = false; GeoDataPlacemark *placemark =0; GeoDataPoint *point = 0; GeoDataCoordinates coord; GeoDataLatLonAltBox box; QVariantList answerOptions; while ( !found ) { int randomIndex = qrand()%countryPlacemarks.size(); placemark = countryPlacemarks[randomIndex]; point = dynamic_cast<GeoDataPoint*>( placemark->geometry() ); coord = point->coordinates(); if ( point ) { /** * Find the country geometry and fetch corresponding * GeoDataLatLonAltBox to zoom in to that country so that * it fills the viewport. */ Q_ASSERT_X( d->m_countryBoundaries, "CountryByShape::postQuestion", "CountryByShapePrivate::m_countryBoundaries is NULL" ); QVector<GeoDataFeature*>::Iterator i = d->m_countryBoundaries->begin(); QVector<GeoDataFeature*>::Iterator const end = d->m_countryBoundaries->end(); for ( ; i != end; ++i ) { GeoDataPlacemark *country = static_cast<GeoDataPlacemark*>( *i ); GeoDataPolygon *polygon = dynamic_cast<GeoDataPolygon*>( country->geometry() ); GeoDataLinearRing *linearring = dynamic_cast<GeoDataLinearRing*>( country->geometry() ); GeoDataMultiGeometry *multigeom = dynamic_cast<GeoDataMultiGeometry*>( country->geometry() ); if ( polygon && polygon->contains( coord ) && !d->m_continentsAndOceans.contains(country->name(), Qt::CaseSensitive) ) { box = polygon->latLonAltBox(); found = true; break; } if ( linearring && linearring->contains( coord ) && !d->m_continentsAndOceans.contains(country->name(), Qt::CaseSensitive) ) { box = linearring->latLonAltBox(); found = true; break; } if ( multigeom ) { QVector<GeoDataGeometry*>::Iterator iter = multigeom->begin(); QVector<GeoDataGeometry*>::Iterator const end = multigeom->end(); for ( ; iter != end; ++iter ) { GeoDataPolygon *poly = dynamic_cast<GeoDataPolygon*>( *iter ); if ( poly && poly->contains( coord ) && !d->m_continentsAndOceans.contains(country->name(), Qt::CaseSensitive) ) { box = poly->latLonAltBox(); found = true; break; } } } if ( found ) { break; } } } } d->m_marbleWidget->setHighlightEnabled( true ); emit announceHighlight( coord.longitude(GeoDataCoordinates::Degree), coord.latitude(GeoDataCoordinates::Degree), GeoDataCoordinates::Degree ); /** * Now disable the highlight feature so that * the user click doesn't disturbe the highlight * we did to ask question. */ d->m_marbleWidget->setHighlightEnabled( false ); d->m_marbleWidget->centerOn( box, true ); answerOptions << placemark->name() << countryPlacemarks[qrand()%countryPlacemarks.size()]->name() << countryPlacemarks[qrand()%countryPlacemarks.size()]->name() << countryPlacemarks[qrand()%countryPlacemarks.size()]->name(); // Randomize options in list answerOptions for ( int i = 0; i < answerOptions.size(); ++i ) { QVariant option = answerOptions.takeAt( qrand()%answerOptions.size() ); answerOptions.append( option ); } if ( gameObject ) { QMetaObject::invokeMethod( gameObject, "countryByShapeQuestion", Q_ARG(QVariant, QVariant(answerOptions)), Q_ARG(QVariant, QVariant(placemark->name())) ); } }
int main(int argc, char** argv) { QApplication app(argc,argv); qDebug( " Syntax: pnt2svg [-i shp-sourcefile -o pn2-targetfile]" ); QString inputFilename; int inputIndex = app.arguments().indexOf( "-i" ); if ( inputIndex > 0 && inputIndex + 1 < argc ) inputFilename = app.arguments().at( inputIndex + 1 ); QString outputFilename = "output.pn2"; int outputIndex = app.arguments().indexOf("-o"); if ( outputIndex > 0 && outputIndex + 1 < argc ) outputFilename = app.arguments().at( outputIndex + 1 ); MarbleModel *model = new MarbleModel; ParsingRunnerManager* manager = new ParsingRunnerManager( model->pluginManager() ); GeoDataDocument* document = manager->openFile( inputFilename ); QFile file( outputFilename ); file.open( QIODevice::WriteOnly ); QDataStream stream( &file ); quint8 fileHeaderVersion; quint32 fileHeaderPolygons; fileHeaderVersion = 1; fileHeaderPolygons = 0; // This variable counts the number of polygons inside the document QVector<GeoDataFeature*>::Iterator i = document->begin(); QVector<GeoDataFeature*>::Iterator const end = document->end(); for (; i != end; ++i) { GeoDataPlacemark* placemark = static_cast<GeoDataPlacemark*>( *i ); // Types of placemarks GeoDataPolygon* polygon = dynamic_cast<GeoDataPolygon*>( placemark->geometry() ); GeoDataLineString* linestring = dynamic_cast<GeoDataLineString*>( placemark->geometry() ); GeoDataMultiGeometry* multigeom = dynamic_cast<GeoDataMultiGeometry*>( placemark->geometry() ); if ( polygon ) { fileHeaderPolygons += 1 + polygon->innerBoundaries().size(); // outer boundary + number of inner boundaries of the polygon } if ( linestring ) { ++fileHeaderPolygons; } if ( multigeom ) { fileHeaderPolygons += multigeom->size(); // number of polygons inside the multigeometry } } stream << fileHeaderVersion << fileHeaderPolygons; i = document->begin(); quint32 polyCurrentID = 0; quint32 polyParentNodes; quint8 polyFlag; for ( ; i != end; ++i ) { GeoDataPlacemark* placemark = static_cast<GeoDataPlacemark*>( *i ); // Types of placemarks GeoDataPolygon* polygon = dynamic_cast<GeoDataPolygon*>( placemark->geometry() ); GeoDataLineString* linestring = dynamic_cast<GeoDataLineString*>( placemark->geometry() ); GeoDataMultiGeometry* multigeom = dynamic_cast<GeoDataMultiGeometry*>( placemark->geometry() ); if ( polygon ) { // Outer boundary ++polyCurrentID; QVector<GeoDataCoordinates>::Iterator jBegin = polygon->outerBoundary().begin(); QVector<GeoDataCoordinates>::Iterator jEnd = polygon->outerBoundary().end(); polyParentNodes = getParentNodes( jBegin, jEnd ); polyFlag = OUTERBOUNDARY; stream << polyCurrentID << polyParentNodes << polyFlag; printAllNodes( jBegin, jEnd, stream ); // Inner boundaries QVector<GeoDataLinearRing>::Iterator inner = polygon->innerBoundaries().begin(); QVector<GeoDataLinearRing>::Iterator innerEnd = polygon->innerBoundaries().end(); for ( ; inner != innerEnd; ++inner ) { GeoDataLinearRing linearring = static_cast<GeoDataLinearRing>( *inner ); ++polyCurrentID; jBegin = linearring.begin(); jEnd = linearring.end(); polyParentNodes = getParentNodes( jBegin, jEnd ); polyFlag = INNERBOUNDARY; stream << polyCurrentID << polyParentNodes << polyFlag; printAllNodes( jBegin, jEnd, stream ); } } if ( linestring ) { ++polyCurrentID; QVector<GeoDataCoordinates>::Iterator jBegin = linestring->begin(); QVector<GeoDataCoordinates>::Iterator jEnd = linestring->end(); polyParentNodes = getParentNodes( jBegin, jEnd ); if ( linestring->isClosed() ) polyFlag = LINEARRING; else polyFlag = LINESTRING; stream << polyCurrentID << polyParentNodes << polyFlag; printAllNodes( jBegin, jEnd, stream ); } if ( multigeom ) { QVector<GeoDataGeometry*>::Iterator multi = multigeom->begin(); QVector<GeoDataGeometry*>::Iterator multiEnd = multigeom->end(); for ( ; multi != multiEnd; ++multi ) { GeoDataLineString* currLineString = dynamic_cast<GeoDataLineString*>( *multi ); ++polyCurrentID; QVector<GeoDataCoordinates>::Iterator jBegin = currLineString->begin(); QVector<GeoDataCoordinates>::Iterator jEnd = currLineString->end(); polyParentNodes = getParentNodes( jBegin, jEnd ); if ( currLineString->isClosed() ) polyFlag = LINEARRING; else polyFlag = LINESTRING; stream << polyCurrentID << polyParentNodes << polyFlag; printAllNodes( jBegin, jEnd, stream ); } } } }
void TestGeoDataTrack::extendedDataParseTest() { //"Example of Track with Extended Data" from kmlreference QString content( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" "<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">" " <Document>" " <name>GPS device</name>" " <Snippet>Created Wed Jun 2 15:33:39 2010</Snippet>" " <Schema id=\"schema\">" " <gx:SimpleArrayField name=\"heartrate\" type=\"int\">" " <displayName>Heart Rate</displayName>" " </gx:SimpleArrayField>" " <gx:SimpleArrayField name=\"cadence\" type=\"int\">" " <displayName>Cadence</displayName>" " </gx:SimpleArrayField>" " <gx:SimpleArrayField name=\"power\" type=\"float\">" " <displayName>Power</displayName>" " </gx:SimpleArrayField>" " </Schema>" " <Folder>" " <name>Tracks</name>" " <Placemark>" " <name>2010-05-28T01:16:35.000Z</name>" " <styleUrl>#multiTrack</styleUrl>" " <gx:Track>" " <when>2010-05-28T02:02:09Z</when>" " <when>2010-05-28T02:02:35Z</when>" " <when>2010-05-28T02:02:44Z</when>" " <when>2010-05-28T02:02:53Z</when>" " <when>2010-05-28T02:02:54Z</when>" " <when>2010-05-28T02:02:55Z</when>" " <when>2010-05-28T02:02:56Z</when>" " <gx:coord>-122.207881 37.371915 156.000000</gx:coord>" " <gx:coord>-122.205712 37.373288 152.000000</gx:coord>" " <gx:coord>-122.204678 37.373939 147.000000</gx:coord>" " <gx:coord>-122.203572 37.374630 142.199997</gx:coord>" " <gx:coord>-122.203451 37.374706 141.800003</gx:coord>" " <gx:coord>-122.203329 37.374780 141.199997</gx:coord>" " <gx:coord>-122.203207 37.374857 140.199997</gx:coord>" " <ExtendedData>" " <SchemaData schemaUrl=\"#schema\">" " <gx:SimpleArrayData name=\"cadence\">" " <gx:value>86</gx:value>" " <gx:value>103</gx:value>" " <gx:value>108</gx:value>" " <gx:value>113</gx:value>" " <gx:value>113</gx:value>" " <gx:value>113</gx:value>" " <gx:value>113</gx:value>" " </gx:SimpleArrayData>" " <gx:SimpleArrayData name=\"heartrate\">" " <gx:value>181</gx:value>" " <gx:value>177</gx:value>" " <gx:value>175</gx:value>" " <gx:value>173</gx:value>" " <gx:value>173</gx:value>" " <gx:value>173</gx:value>" " <gx:value>173</gx:value>" " </gx:SimpleArrayData>" " <gx:SimpleArrayData name=\"power\">" " <gx:value>327.0</gx:value>" " <gx:value>177.0</gx:value>" " <gx:value>179.0</gx:value>" " <gx:value>162.0</gx:value>" " <gx:value>166.0</gx:value>" " <gx:value>177.0</gx:value>" " <gx:value>183.0</gx:value>" " </gx:SimpleArrayData>" " </SchemaData>" " </ExtendedData>" " </gx:Track>" " </Placemark>" " </Folder>" " </Document>" "</kml>" ); GeoDataDocument* dataDocument = parseKml( content ); GeoDataFolder *folder = dataDocument->folderList().at( 0 ); QCOMPARE( folder->placemarkList().size(), 1 ); GeoDataPlacemark* placemark = folder->placemarkList().at( 0 ); QCOMPARE( placemark->geometry()->geometryId(), GeoDataTrackId ); GeoDataTrack* track = static_cast<GeoDataTrack*>( placemark->geometry() ); QCOMPARE( track->size(), 7 ); { GeoDataSimpleArrayData *cadence = track->extendedData().simpleArrayData( "cadence" ); QCOMPARE( cadence->size(), 7 ); QCOMPARE( cadence->valueAt( 0 ), QVariant( "86" ) ); QCOMPARE( cadence->valueAt( 6 ), QVariant( "113" ) ); } { GeoDataSimpleArrayData *hr = track->extendedData().simpleArrayData( "heartrate" ); QCOMPARE( hr->size(), 7 ); QCOMPARE( hr->valueAt( 0 ), QVariant( "181" ) ); QCOMPARE( hr->valueAt( 6 ), QVariant( "173" ) ); } { GeoDataSimpleArrayData *power = track->extendedData().simpleArrayData( "power" ); QCOMPARE( power->size(), 7 ); QCOMPARE( power->valueAt( 0 ), QVariant( "327.0" ) ); QCOMPARE( power->valueAt( 6 ), QVariant( "183.0" ) ); } delete dataDocument; }
void PositionTracking::readSettings() { QFile file( d->statusFile() ); if ( !file.open( QIODevice::ReadOnly ) ) { mDebug() << "Can not read track from " << file.fileName(); return; } GeoDataParser parser( GeoData_KML ); if ( !parser.read( &file ) ) { mDebug() << "Could not parse tracking file: " << parser.errorString(); return; } GeoDataDocument *doc = dynamic_cast<GeoDataDocument*>( parser.releaseDocument() ); file.close(); if( !doc ){ mDebug() << "tracking document not available"; return; } GeoDataPlacemark *track = dynamic_cast<GeoDataPlacemark*>( doc->child( 0 ) ); if( !track ) { mDebug() << "tracking document doesn't have a placemark"; delete doc; return; } d->m_trackSegments = dynamic_cast<GeoDataMultiTrack*>( track->geometry() ); if( !d->m_trackSegments ) { mDebug() << "tracking document doesn't have a multitrack"; delete doc; return; } if( d->m_trackSegments->size() < 1 ) { mDebug() << "tracking document doesn't have a track"; delete doc; return; } d->m_currentTrack = dynamic_cast<GeoDataTrack*>( d->m_trackSegments->child( d->m_trackSegments->size() - 1 ) ); if( !d->m_currentTrack ) { mDebug() << "tracking document doesn't have a last track"; delete doc; return; } doc->remove( 0 ); delete doc; d->m_treeModel->removeDocument( &d->m_document ); d->m_document.remove( 1 ); delete d->m_currentTrackPlacemark; d->m_currentTrackPlacemark = track; d->m_currentTrackPlacemark->setName("Current Track"); d->m_document.append( d->m_currentTrackPlacemark ); d->m_currentTrackPlacemark->setStyleUrl( d->m_currentTrackPlacemark->styleUrl() ); d->m_treeModel->addDocument( &d->m_document ); d->m_length = 0.0; for ( int i = 0; i < d->m_trackSegments->size(); ++i ) { d->m_length += d->m_trackSegments->at( i ).lineString()->length( 1 ); } }