Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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();
    }
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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())) );
    }
}
Beispiel #10
0
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 );
            }
            
        }
    }

}
Beispiel #11
0
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;
}
Beispiel #12
0
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 );
    }
}