Esempio n. 1
0
void GeoDataPlacemark::unpack( QDataStream& stream )
{
    detach();
    p()->m_geometry->setParent( this );
    GeoDataFeature::unpack( stream );

    stream >> p()->m_countrycode;
    stream >> p()->m_area;
    stream >> p()->m_population;
    int geometryId;
    stream >> geometryId;
    switch( geometryId ) {
        case InvalidGeometryId:
            break;
        case GeoDataPointId:
            {
            GeoDataPoint* point = new GeoDataPoint;
            point->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = point;
            }
            break;
        case GeoDataLineStringId:
            {
            GeoDataLineString* lineString = new GeoDataLineString;
            lineString->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = lineString;
            }
            break;
        case GeoDataLinearRingId:
            {
            GeoDataLinearRing* linearRing = new GeoDataLinearRing;
            linearRing->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = linearRing;
            }
            break;
        case GeoDataPolygonId:
            {
            GeoDataPolygon* polygon = new GeoDataPolygon;
            polygon->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = polygon;
            }
            break;
        case GeoDataMultiGeometryId:
            {
            GeoDataMultiGeometry* multiGeometry = new GeoDataMultiGeometry;
            multiGeometry->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = multiGeometry;
            }
            break;
        case GeoDataModelId:
            break;
        default: break;
    };
}
Esempio n. 2
0
void GeoDataMultiGeometry::unpack( QDataStream& stream )
{
    detach();
    GeoDataGeometry::unpack( stream );

    int size = 0;

    stream >> size;

    for( int i = 0; i < size; i++ ) {
        int geometryId;
        stream >> geometryId;
        switch( geometryId ) {
        case InvalidGeometryId:
            break;
        case GeoDataPointId:
        {
            GeoDataPoint *point = new GeoDataPoint;
            point->unpack( stream );
            p()->m_vector.append( point );
        }
        break;
        case GeoDataLineStringId:
        {
            GeoDataLineString *lineString = new GeoDataLineString;
            lineString->unpack( stream );
            p()->m_vector.append( lineString );
        }
        break;
        case GeoDataLinearRingId:
        {
            GeoDataLinearRing *linearRing = new GeoDataLinearRing;
            linearRing->unpack( stream );
            p()->m_vector.append( linearRing );
        }
        break;
        case GeoDataPolygonId:
        {
            GeoDataPolygon *polygon = new GeoDataPolygon;
            polygon->unpack( stream );
            p()->m_vector.append( polygon );
        }
        break;
        case GeoDataMultiGeometryId:
        {
            GeoDataMultiGeometry *multiGeometry = new GeoDataMultiGeometry;
            multiGeometry->unpack( stream );
            p()->m_vector.append( multiGeometry );
        }
        break;
        case GeoDataModelId:
            break;
        default:
            break;
        };
    }
}
Esempio n. 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();
    }
}
Esempio n. 4
0
GeoDataDocument *ShpRunner::parseFile(const QString &fileName, DocumentRole role, QString &error)
{
    QFileInfo fileinfo( fileName );
    if (fileinfo.suffix().compare(QLatin1String("shp"), Qt::CaseInsensitive) != 0) {
        error = QStringLiteral("File %1 does not have a shp suffix").arg(fileName);
        mDebug() << error;
        return nullptr;
    }

    SHPHandle handle = SHPOpen( fileName.toStdString().c_str(), "rb" );
    if ( !handle ) {
        error = QStringLiteral("Failed to read %1").arg(fileName);
        mDebug() << error;
        return nullptr;
    }
    int entities;
    int shapeType;
    SHPGetInfo( handle, &entities, &shapeType, NULL, NULL );
    mDebug() << " SHP info " << entities << " Entities "
             << shapeType << " Shape Type ";

    DBFHandle dbfhandle;
    dbfhandle = DBFOpen( fileName.toStdString().c_str(), "rb");
    int nameField = DBFGetFieldIndex( dbfhandle, "Name" );
    int noteField = DBFGetFieldIndex( dbfhandle, "Note" );
    int mapColorField = DBFGetFieldIndex( dbfhandle, "mapcolor13" );

    GeoDataDocument *document = new GeoDataDocument;
    document->setDocumentRole( role );

    if ( mapColorField != -1 ) {
        GeoDataSchema schema;
        schema.setId(QStringLiteral("default"));
        GeoDataSimpleField simpleField;
        simpleField.setName(QStringLiteral("mapcolor13"));
        simpleField.setType( GeoDataSimpleField::Double );
        schema.addSimpleField( simpleField );
        document->addSchema( schema );
    }

    for ( int i=0; i< entities; ++i ) {
        GeoDataPlacemark  *placemark = 0;
        placemark = new GeoDataPlacemark;
        document->append( placemark );

        SHPObject *shape = SHPReadObject( handle, i );
        if (nameField != -1) {
            const char* info = DBFReadStringAttribute( dbfhandle, i, nameField );
            // TODO: defaults to utf-8 encoding, but could be also something else, optionally noted in a .cpg file
            placemark->setName( info );
            mDebug() << "name " << placemark->name();
        }
        if (noteField != -1) {
            const char* note = DBFReadStringAttribute( dbfhandle, i, noteField );
            // TODO: defaults to utf-8 encoding, see comment for name
            placemark->setDescription( note );
            mDebug() << "desc " << placemark->description();
        }

        double mapColor = DBFReadDoubleAttribute( dbfhandle, i, mapColorField );
        if ( mapColor ) {
            GeoDataStyle::Ptr style(new GeoDataStyle);
            if ( mapColor >= 0 && mapColor <=255 ) {
                quint8 colorIndex = quint8( mapColor );
                style->polyStyle().setColorIndex( colorIndex );
            }
            else {
                quint8 colorIndex = 0;     // mapColor is undefined in this case
                style->polyStyle().setColorIndex( colorIndex );
            }
            placemark->setStyle( style );
        }

        switch ( shapeType ) {
            case SHPT_POINT: {
                GeoDataPoint *point = new GeoDataPoint( *shape->padfX, *shape->padfY, 0, GeoDataCoordinates::Degree );
                placemark->setGeometry( point );
                mDebug() << "point " << placemark->name();
                break;
            }

            case SHPT_MULTIPOINT: {
                GeoDataMultiGeometry *geom = new GeoDataMultiGeometry;
                for( int j=0; j<shape->nVertices; ++j ) {
                    geom->append( new GeoDataPoint( GeoDataCoordinates(
                                  shape->padfX[j], shape->padfY[j],
                                  0, GeoDataCoordinates::Degree ) ) );
                }
                placemark->setGeometry( geom );
                mDebug() << "multipoint " << placemark->name();
                break;
            }

            case SHPT_ARC: {
                if ( shape->nParts != 1 ) {
                    GeoDataMultiGeometry *geom = new GeoDataMultiGeometry;
                    for( int j=0; j<shape->nParts; ++j ) {
                        GeoDataLineString *line = new GeoDataLineString;
                        int itEnd = (j + 1 < shape->nParts) ? shape->panPartStart[j+1] : shape->nVertices;
                        for( int k=shape->panPartStart[j]; k<itEnd; ++k ) {
                            line->append( GeoDataCoordinates(
                                          shape->padfX[k], shape->padfY[k],
                                          0, GeoDataCoordinates::Degree ) );
                        }
                        geom->append( line );
                    }
                    placemark->setGeometry( geom );
                    mDebug() << "arc " << placemark->name() << " " << shape->nParts;

                } else {
                    GeoDataLineString *line = new GeoDataLineString;
                    for( int j=0; j<shape->nVertices; ++j ) {
                        line->append( GeoDataCoordinates(
                                      shape->padfX[j], shape->padfY[j],
                                      0, GeoDataCoordinates::Degree ) );
                    }
                    placemark->setGeometry( line );
                    mDebug() << "arc " << placemark->name() << " " << shape->nParts;
                }
                break;
            }

            case SHPT_POLYGON: {
                if ( shape->nParts != 1 ) {
                    bool isRingClockwise = false;
                    GeoDataMultiGeometry *multigeom = new GeoDataMultiGeometry;
                    GeoDataPolygon *poly = 0;
                    int polygonCount = 0;
                    for( int j=0; j<shape->nParts; ++j ) {
                        GeoDataLinearRing ring;
                        int itStart = shape->panPartStart[j];
                        int itEnd = (j + 1 < shape->nParts) ? shape->panPartStart[j+1] : shape->nVertices;
                        for( int k = itStart; k<itEnd; ++k ) {
                            ring.append( GeoDataCoordinates(
                                         shape->padfX[k], shape->padfY[k],
                                         0, GeoDataCoordinates::Degree ) );
                        }
                        isRingClockwise = ring.isClockwise();
                        if ( j == 0 || isRingClockwise ) {
                            poly = new GeoDataPolygon;
                            ++polygonCount;
                            poly->setOuterBoundary( ring );
                            if ( polygonCount > 1 ) {
                                multigeom->append( poly );
                            }
                        }
                        else {
                            poly->appendInnerBoundary( ring );
                        }
                    }
                    if ( polygonCount > 1 ) {
                        placemark->setGeometry( multigeom );
                    }
                    else {
                        placemark->setGeometry( poly );
                        delete multigeom;
                        multigeom = 0;
                    }
                    mDebug() << "donut " << placemark->name() << " " << shape->nParts;

                } else {
                    GeoDataPolygon *poly = new GeoDataPolygon;
                    GeoDataLinearRing ring;
                    for( int j=0; j<shape->nVertices; ++j ) {
                        ring.append( GeoDataCoordinates(
                                         shape->padfX[j], shape->padfY[j],
                                         0, GeoDataCoordinates::Degree ) );
                    }
                    poly->setOuterBoundary( ring );
                    placemark->setGeometry( poly );
                    mDebug() << "poly " << placemark->name() << " " << shape->nParts;
                }
                break;
            }
        }
    }

    SHPClose( handle );

    DBFClose( dbfhandle );

    if ( document->size() ) {
        document->setFileName( fileName );
        return document;
    } else {
        delete document;
        return nullptr;
    }
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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())) );
    }
}
Esempio n. 8
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 );
            }
            
        }
    }

}