void RouteSimulationPositionProviderPlugin::initialize() { m_currentIndex = -1; m_lineString.clear(); GeoDataDocument* document = const_cast<MarbleModel *>( marbleModel() )->routingManager()->alternativeRoutesModel()->currentRoute(); if ( document && document->size() > 0 ) { foreach( const GeoDataPlacemark *placemark, document->placemarkList() ) { GeoDataGeometry* geometry = placemark->geometry(); GeoDataLineString* lineString = dynamic_cast<GeoDataLineString*>( geometry ); if ( lineString ) { m_lineString << *lineString; } } }
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 TestGeoData::parentingTest() { GeoDataDocument *document = new GeoDataDocument; GeoDataFolder *folder = new GeoDataFolder; /// simple parenting test GeoDataPlacemark *placemark = new GeoDataPlacemark; placemark->setParent(document); QCOMPARE(placemark->parent(), document); /// simple append and child count test document->append(placemark); /// appending folder to document before feeding folder document->append(folder); QCOMPARE(document->size(), 2); GeoDataPlacemark *placemark2 = new GeoDataPlacemark; folder->append(placemark2); QCOMPARE(folder->size(), 1); /// retrieve child and check it matches placemark GeoDataPlacemark *placemarkPtr; QCOMPARE(document->child(0)->nodeType(), placemark->nodeType()); placemarkPtr = static_cast<GeoDataPlacemark*>(document->child(0)); QCOMPARE(placemarkPtr, placemark); /// check retrieved placemark matches intented child int position = document->childPosition(placemarkPtr); QCOMPARE(position, 0); /// retrieve child two and check it matches folder GeoDataFolder *folderPtr; QCOMPARE(document->child(1)->nodeType(), folder->nodeType()); folderPtr = static_cast<GeoDataFolder*>(document->child(1)); QCOMPARE(folderPtr, folder); /// check retrieved folder matches intended child position = document->childPosition(folderPtr); QCOMPARE(position, 1); /// retrieve child three and check it matches placemark QCOMPARE(folderPtr->size(), 1); placemarkPtr = static_cast<GeoDataPlacemark*>(folderPtr->child(0)); QCOMPARE(placemarkPtr->nodeType(), placemark2->nodeType()); QCOMPARE(placemarkPtr, placemark2); /// check retrieved placemark matches intended child QCOMPARE(folderPtr->childPosition(placemarkPtr), 0); /// Set a style GeoDataIconStyle iconStyle; iconStyle.setIconPath( "myicon.png" ); GeoDataStyle* style = new GeoDataStyle; style->setStyleId( "mystyle" ); style->setIconStyle( iconStyle ); GeoDataObject* noParent = 0; QCOMPARE( style->parent(), noParent ); QCOMPARE( iconStyle.parent(), noParent ); document->setStyle( style ); QCOMPARE( style->parent(), document ); // Parent should be assigned now QCOMPARE( style->iconStyle().parent(), style ); QCOMPARE( iconStyle.parent(), noParent ); // setIconStyle copies QCOMPARE( placemark->style()->parent(), noParent ); placemark->setStyle( style ); QCOMPARE( placemark->style()->parent(), placemark ); // Parent should be assigned now /// Set a style map GeoDataStyleMap* styleMap = new GeoDataStyleMap; styleMap->setStyleId( "mystylemap" ); styleMap->insert( "normal", "#mystyle" ); styleMap->insert( "highlight", "#mystyle" ); document->addStyle( *style ); document->setStyleMap( styleMap ); QCOMPARE( placemark2->style()->parent(), noParent ); placemark2->setStyleUrl( "#mystyle" ); QCOMPARE( placemark2->style()->parent(), document ); // Parent is document, not placemark2 QCOMPARE( iconStyle.iconPath(), QString( "myicon.png" ) ); QCOMPARE( placemark2->style()->iconStyle().iconPath(), QString( "myicon.png" ) ); }
void RoutingManagerPrivate::loadRoute(const QString &filename) { QFile file( filename ); if ( !file.open( QIODevice::ReadOnly ) ) { mDebug() << "Can not read route from " << file.fileName(); return; } GeoDataParser parser( GeoData_KML ); if ( !parser.read( &file ) ) { mDebug() << "Could not parse file: " << parser.errorString(); return; } GeoDocument *doc = parser.releaseDocument(); file.close(); bool loaded = false; GeoDataDocument* container = dynamic_cast<GeoDataDocument*>( doc ); if ( container && container->size() > 0 ) { GeoDataFolder* viaPoints = dynamic_cast<GeoDataFolder*>( &container->first() ); if ( viaPoints ) { loaded = true; QVector<GeoDataPlacemark*> placemarks = viaPoints->placemarkList(); for( int i=0; i<placemarks.size(); ++i ) { if ( i < m_routeRequest.size() ) { m_routeRequest[i] = *placemarks[i]; } else { m_routeRequest.append( *placemarks[i] ); } } // clear unneeded via points const int viaPoints_needed = placemarks.size(); for ( int i = m_routeRequest.size(); i > viaPoints_needed; --i ) { m_routeRequest.remove( viaPoints_needed ); } } else { mDebug() << "Expected a GeoDataDocument with at least one child, didn't get one though"; } } if ( container && container->size() == 2 ) { GeoDataDocument* route = dynamic_cast<GeoDataDocument*>(&container->last()); if ( route ) { loaded = true; m_alternativeRoutesModel.clear(); m_alternativeRoutesModel.addRoute( route, AlternativeRoutesModel::Instant ); m_alternativeRoutesModel.setCurrentRoute( 0 ); m_state = RoutingManager::Retrieved; emit q->stateChanged( m_state ); emit q->routeRetrieved( route ); } else { mDebug() << "Expected a GeoDataDocument child, didn't get one though"; } } if ( !loaded ) { mDebug() << "File " << filename << " is not a valid Marble route .kml file"; if ( container ) { m_treeModel->addDocument( container ); } } }