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; }; }
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; }; } }
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(); } }
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; } }
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 ); } } } }