GeoDataDocument *GpsbabelRunner::parseFile(const QString &fileName, DocumentRole role, QString &error) { // Check and see if the file exists if ( !QFileInfo( fileName ).exists() ) { error = QStringLiteral("File %1 does not exist").arg(fileName); mDebug() << error; return nullptr; } // Inspect the filename suffix QString const fileSuffix = QFileInfo( fileName ).suffix(); // Determine if fileName suffix is supported by this plugin QMap<QString,QString> fileTypes; fileTypes["nmea"] = "nmea"; fileTypes["igc"] = "igc"; fileTypes["tiger"] = "tiger"; fileTypes["ov2"] = "tomtom"; fileTypes["garmin"] = "garmin_txt"; fileTypes["magellan"] = "magellan"; fileTypes["csv"] = "csv"; QString const inputFileType = fileTypes[fileSuffix]; if ( inputFileType.isEmpty() ) { error = QStringLiteral("Unsupported file extension for").arg(fileName); mDebug() << error; return nullptr; } // Set up temporary file to hold output KML from gpsbabel executable QTemporaryFile tempKmlFile(QDir::tempPath() + QLatin1String("/marble-gpsbabel-XXXXXX.kml")); tempKmlFile.open(); QFile kmlFile( tempKmlFile.fileName() ); // Set up gpsbabel command line const QString command = QLatin1String("gpsbabel -i ") + inputFileType + QLatin1String(" -f ") + fileName + QLatin1String(" -o kml -F ") + tempKmlFile.fileName(); // Execute gpsbabel to parse the input file int const exitStatus = QProcess::execute( command ); if ( exitStatus == 0 ) { kmlFile.open( QIODevice::ReadWrite ); GeoDataParser parser( GeoData_KML ); parser.read( &kmlFile ); GeoDataDocument *document = dynamic_cast<GeoDataDocument*>( parser.releaseDocument() ); if ( !document ) { error = parser.errorString(); mDebug() << error; return nullptr; } document->setDocumentRole( role ); return document; } else { error = QStringLiteral("Gpsbabel returned error code %1").arg(exitStatus); mDebug() << error; return nullptr; } }
void TourWidgetPrivate::createTour() { if ( overrideModifications() ) { GeoDataDocument *document = new GeoDataDocument(); document->setDocumentRole( UserDocument ); document->setName( "New Tour" ); document->setId( "new_tour" ); GeoDataTour *tour = new GeoDataTour(); tour->setName( "New Tour" ); GeoDataPlaylist *playlist = new GeoDataPlaylist; tour->setPlaylist( playlist ); document->append( static_cast<GeoDataFeature*>( tour ) ); m_playback.setBaseUrl( QUrl::fromLocalFile( MarbleDirs::marbleDataPath() ) ); openDocument( document ); m_isChanged = true; m_tourUi.m_actionSaveTour->setEnabled( true ); } }
GeoDataDocument *LogRunner::parseFile(const QString &fileName, DocumentRole role, QString &errorString) { QFile file( fileName ); if ( !file.exists() ) { errorString = QStringLiteral("File %1 does not exist").arg(fileName); mDebug() << errorString; return nullptr; } file.open( QIODevice::ReadOnly ); QTextStream stream( &file ); GeoDataLineString *const track = new GeoDataLineString; GeoDataPlacemark *const placemark = new GeoDataPlacemark; placemark->setGeometry( track ); GeoDataDocument *document = new GeoDataDocument(); document->setDocumentRole( role ); document->append( placemark ); int count = 0; bool error = false; while( !stream.atEnd() || error ){ const QString line = stream.readLine(); const QStringList list = line.split(QLatin1Char(',')); if ( list.size() != 7 ) { mDebug() << Q_FUNC_INFO << "Aborting due to error in line" << count << ". Line was:" << line; error = true; break; } const QString strLat = list[0]; const QString strLon = list[1]; const QString strElevation = list[2]; const QString strSpeed = list[3]; const QString strCourse = list[4]; const QString strHdop = list[5]; const QString strTime = list[6]; if ( strLat.isEmpty() || strLon.isEmpty() || strElevation.isEmpty() ) { continue; } bool okLat, okLon, okAlt = false; const qreal lat = strLat.toDouble( &okLat ); const qreal lon = strLon.toDouble( &okLon ); const qreal alt = strElevation.toDouble( &okAlt ); if ( !okLat || !okLon || !okAlt ) { continue; } GeoDataCoordinates coord( lon, lat, alt, GeoDataCoordinates::Degree ); track->append( coord ); } file.close(); if ( track->size() == 0 || error ) { delete document; document = 0; return nullptr; } document->setFileName( fileName ); return document; }
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; } }
GeoDataDocument* Pn2Runner::parseForVersion1(const QString& fileName, DocumentRole role) { GeoDataDocument *document = new GeoDataDocument(); document->setDocumentRole( role ); bool error = false; quint32 ID, nrAbsoluteNodes; quint8 flag, prevFlag = -1; GeoDataStyle::Ptr style; GeoDataPolygon *polygon = new GeoDataPolygon; for ( quint32 currentPoly = 1; ( currentPoly <= m_fileHeaderPolygons ) && ( !error ) && ( !m_stream.atEnd() ); currentPoly++ ) { m_stream >> ID >> nrAbsoluteNodes >> flag; if ( flag != INNERBOUNDARY && ( prevFlag == INNERBOUNDARY || prevFlag == OUTERBOUNDARY ) ) { GeoDataPlacemark *placemark = new GeoDataPlacemark; placemark->setGeometry( polygon ); if ( m_isMapColorField ) { if ( style ) { placemark->setStyle( style ); } } document->append( placemark ); } if ( flag == LINESTRING ) { GeoDataLineString *linestring = new GeoDataLineString; error = error | importPolygon( m_stream, linestring, nrAbsoluteNodes ); GeoDataPlacemark *placemark = new GeoDataPlacemark; placemark->setGeometry( linestring ); document->append( placemark ); } if ( ( flag == LINEARRING ) || ( flag == OUTERBOUNDARY ) || ( flag == INNERBOUNDARY ) ) { if ( flag == OUTERBOUNDARY && m_isMapColorField ) { quint8 colorIndex; m_stream >> colorIndex; style = GeoDataStyle::Ptr(new GeoDataStyle); GeoDataPolyStyle polyStyle; polyStyle.setColorIndex( colorIndex ); style->setPolyStyle( polyStyle ); } GeoDataLinearRing* linearring = new GeoDataLinearRing; error = error | importPolygon( m_stream, linearring, nrAbsoluteNodes ); if ( flag == LINEARRING ) { GeoDataPlacemark *placemark = new GeoDataPlacemark; placemark->setGeometry( linearring ); document->append( placemark ); } if ( flag == OUTERBOUNDARY ) { polygon = new GeoDataPolygon; polygon->setOuterBoundary( *linearring ); } if ( flag == INNERBOUNDARY ) { polygon->appendInnerBoundary( *linearring ); } } if ( flag == MULTIGEOMETRY ) { // not implemented yet, for now elements inside a multigeometry are separated as individual geometries } prevFlag = flag; }