コード例 #1
0
ファイル: GpsbabelRunner.cpp プロジェクト: KDE/marble
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;
    }
}
コード例 #2
0
ファイル: TourWidget.cpp プロジェクト: quannt24/marble
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 );
    }
}
コード例 #3
0
ファイル: LogRunner.cpp プロジェクト: KDE/marble
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;
}
コード例 #4
0
ファイル: ShpRunner.cpp プロジェクト: KDE/marble
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;
    }
}
コード例 #5
0
ファイル: Pn2Runner.cpp プロジェクト: KDE/marble
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;
    }