예제 #1
0
GeoDataDocument* GosmoreRunnerPrivate::createDocument( GeoDataLineString* routeWaypoints, const QVector<GeoDataPlacemark*> instructions )
{
    if ( !routeWaypoints || routeWaypoints->isEmpty() ) {
        return nullptr;
    }

    GeoDataDocument* result = new GeoDataDocument();
    GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
    routePlacemark->setName(QStringLiteral("Route"));
    routePlacemark->setGeometry( routeWaypoints );
    result->append( routePlacemark );

    QString name = QStringLiteral("%1 %2 (Gosmore)");
    QString unit = QLatin1String( "m" );
    qreal length = routeWaypoints->length( EARTH_RADIUS );
    if (length >= 1000) {
        length /= 1000.0;
        unit = "km";
    }
    result->setName( name.arg( length, 0, 'f', 1 ).arg( unit ) );

    for( GeoDataPlacemark* placemark: instructions )
    {
        result->append( placemark );
    }

    return result;
}
예제 #2
0
void TestGeoDataTrack::simpleParseTest()
{
    GeoDataDocument* dataDocument = parseKml( simpleExampleContent );
    GeoDataFolder *folder = dataDocument->folderList().at( 0 );
    QCOMPARE( folder->placemarkList().size(), 1 );
    GeoDataPlacemark* placemark = folder->placemarkList().at( 0 );
    QCOMPARE( placemark->geometry()->geometryId(), GeoDataTrackId );
    GeoDataTrack* track = static_cast<GeoDataTrack*>( placemark->geometry() );
    QCOMPARE( track->size(), 7 );
    {
        QDateTime when = track->whenList().at( 0 );
        QCOMPARE( when, QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 9 ), Qt::UTC ) );
    }
    {
        GeoDataCoordinates coord = track->coordinatesList().at( 0 );
        QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 );
        QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 );
        QCOMPARE( coord.altitude(), 156.000000 );
    }
    {
        GeoDataCoordinates coord = track->coordinatesAt( QDateTime( QDate( 2010, 5, 28 ), QTime( 2, 2, 9 ), Qt::UTC ) );
        QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 );
        QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 );
        QCOMPARE( coord.altitude(), 156.000000 );
    }

    delete dataDocument;
}
void GosmoreRunner::reverseGeocoding( const GeoDataCoordinates &coordinates )
{
    if ( !d->m_gosmoreMapFile.exists() )
    {
        emit reverseGeocodingFinished( coordinates, GeoDataPlacemark() );
        return;
    }

    QString queryString = "flat=%1&flon=%2&tlat=%1&tlon=%2&fastest=1&v=motorcar";
    double lon = coordinates.longitude( GeoDataCoordinates::Degree );
    double lat = coordinates.latitude( GeoDataCoordinates::Degree );
    queryString = queryString.arg( lat, 0, 'f', 8).arg(lon, 0, 'f', 8 );
    QByteArray output = d->retrieveWaypoints( queryString );

    GeoDataPlacemark placemark;
    placemark.setCoordinate( coordinates );

    QStringList lines = QString::fromUtf8( output ).split( '\r' );
    if ( lines.size() > 2 ) {
        QStringList fields = lines.at( lines.size()-2 ).split(',');
        if ( fields.size() >= 5 ) {
            QString road = fields.last().trimmed();
            placemark.setAddress( road );
            GeoDataExtendedData extendedData;
            extendedData.addValue( GeoDataData( "road", road ) );
            placemark.setExtendedData( extendedData );
        }
    }

    emit reverseGeocodingFinished( coordinates, placemark );
}
예제 #4
0
void HostipRunner::slotRequestFinished( QNetworkReply* reply )
{
    double lon(0.0), lat(0.0);
    for ( QString line = reply->readLine(); !line.isEmpty(); line = reply->readLine() ) {
        QString lonInd = "Longitude: ";
        if ( line.startsWith(lonInd) ) {
            lon = line.mid( lonInd.length() ).toDouble();
        }

        QString latInd = "Latitude: ";
        if (line.startsWith( latInd) ) {
            lat = line.mid( latInd.length() ).toDouble();
        }
    }

    QVector<GeoDataPlacemark*> placemarks;

    if (lon != 0.0 && lat != 0.0) {
        GeoDataPlacemark *placemark = new GeoDataPlacemark;

        placemark->setName( m_hostInfo.hostName() );

        QString description("%1 (%2)");
        placemark->setDescription( description.
                                 arg( m_hostInfo.hostName() ).
                                 arg( m_hostInfo.addresses().first().toString() ) );

        placemark->setCoordinate( lon * DEG2RAD, lat * DEG2RAD );
        placemark->setVisualCategory( GeoDataFeature::Coordinate );
        placemarks << placemark;
    }
    
    emit searchFinished( placemarks );
}
예제 #5
0
void TestGxTimeStamp::simpleParseTest()
{
  QString const centerContent (
              "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
              "<kml xmlns=\"http://www.opengis.net/kml/2.2\""
              " xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
              "<Document>"
                  "<Placemark>"
                    "<Camera>"
                      "<gx:TimeStamp>"
                        "<when>1987-06-05T04:03:02-01:00</when>"
                      "</gx:TimeStamp>"
                    "</Camera>"
                  "</Placemark>"
              "</Document>"
              "</kml>" );

    GeoDataDocument* dataDocument = parseKml( centerContent );
    QCOMPARE( dataDocument->placemarkList().size(), 1 );
    GeoDataPlacemark *placemark = dataDocument->placemarkList().at( 0 );
    GeoDataAbstractView* view = placemark->abstractView();
    QVERIFY( view != 0 );
    GeoDataCamera* camera = dynamic_cast<GeoDataCamera*>( view );
    QVERIFY( camera != 0 );
    QCOMPARE( camera->timeStamp().when().toUTC(), QDateTime::fromString( "1987-06-05T04:03:02-01:00", Qt::ISODate).toUTC() );

    delete dataDocument;
}
예제 #6
0
bool PositionTracking::saveTrack( const QString& fileName )
{

    if ( fileName.isEmpty() ) {
        return false;
    }

    GeoWriter writer;
    //FIXME: a better way to do this?
    writer.setDocumentType( kml::kmlTag_nameSpaceOgc22 );

    GeoDataDocument *document = new GeoDataDocument;
    QFileInfo fileInfo( fileName );
    QString name = fileInfo.baseName();
    document->setName( name );
    foreach( const GeoDataStyle &style, d->m_document.styles() ) {
        document->addStyle( style );
    }
    foreach( const GeoDataStyleMap &map, d->m_document.styleMaps() ) {
        document->addStyleMap( map );
    }
    GeoDataPlacemark *track = new GeoDataPlacemark( *d->m_currentTrackPlacemark );
    track->setName( "Track " + name );
    document->append( track );

    QFile file( fileName );
    file.open( QIODevice::WriteOnly );
    bool const result = writer.write( &file, document );
    file.close();
    delete document;
    return result;
}
예제 #7
0
void LocalDatabaseRunner::search( const QString &searchTerm, const GeoDataLatLonAltBox &preferred )
{
    QVector<GeoDataPlacemark*> vector;

    if (model()) {
        const QAbstractItemModel * placemarkModel = model()->placemarkModel();

        if (placemarkModel) {
            QModelIndexList resultList;
            QModelIndex firstIndex = placemarkModel->index( 0, 0 );
            resultList = placemarkModel->match( firstIndex,
                                    Qt::DisplayRole, searchTerm, -1,
                                    Qt::MatchStartsWith );

            foreach ( const QModelIndex& index, resultList )
            {
                if( !index.isValid() ) {
                    mDebug() << "invalid index!!!";
                    continue;
                }
                GeoDataPlacemark *placemark = dynamic_cast<GeoDataPlacemark*>(qvariant_cast<GeoDataObject*>( index.data( MarblePlacemarkModel::ObjectPointerRole )));
                if ( placemark &&
                     ( preferred.isEmpty() || preferred.contains( placemark->coordinate() ) ) ) {
                    vector.append( new GeoDataPlacemark( *placemark ));
                }
            }
        }
    }

    emit searchFinished( vector );
}
예제 #8
0
void TestGxTimeSpan::simpleParseTest()
{
  QString const centerContent (
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
      "<kml xmlns=\"http://www.opengis.net/kml/2.2\""
      " xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
      "<Document>"
      "<Placemark>"
       "<LookAt>"
        "<gx:TimeSpan>"
          "<begin>2010-05-28T02:02:09Z</begin>"
          "<end>2010-05-28T02:02:56Z</end>"
        "</gx:TimeSpan>"
      "</LookAt>"
      "</Placemark>"
      "</Document>"
      "</kml>" );

    GeoDataDocument* dataDocument = parseKml( centerContent );
    QCOMPARE( dataDocument->placemarkList().size(), 1 );
    GeoDataPlacemark *placemark = dataDocument->placemarkList().at( 0 );
    QVERIFY( placemark->lookAt() != 0 );
    QCOMPARE( placemark->lookAt()->timeSpan().begin().when(), QDateTime::fromString( "2010-05-28T02:02:09Z", Qt::ISODate) );
    QCOMPARE( placemark->lookAt()->timeSpan().end().when(), QDateTime::fromString( "2010-05-28T02:02:56Z", Qt::ISODate) );

    delete dataDocument;
}
예제 #9
0
void TestGeoDataTrack::withoutTimeTest()
{
    //"Simple Example" from kmlreference; when elements emptied
    QString content(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\""
" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
"<Folder>"
"  <Placemark>"
"    <gx:Track>"
"      <when></when>"
"      <when></when>"
"      <when></when>"
"      <when></when>"
"      <when></when>"
"      <when></when>"
"      <when></when>"
"      <gx:coord>-122.207881 37.371915 156.000000</gx:coord>"
"      <gx:coord>-122.205712 37.373288 152.000000</gx:coord>"
"      <gx:coord>-122.204678 37.373939 147.000000</gx:coord>"
"      <gx:coord>-122.203572 37.374630 142.199997</gx:coord>"
"      <gx:coord>-122.203451 37.374706 141.800003</gx:coord>"
"      <gx:coord>-122.203329 37.374780 141.199997</gx:coord>"
"      <gx:coord>-122.203207 37.374857 140.199997</gx:coord>"
"    </gx:Track>"
"  </Placemark>"
"</Folder>"
"</kml>" );

    GeoDataDocument* dataDocument = parseKml( content );
    GeoDataFolder *folder = dataDocument->folderList().at( 0 );
    QCOMPARE( folder->placemarkList().size(), 1 );
    GeoDataPlacemark* placemark = folder->placemarkList().at( 0 );
    QCOMPARE( placemark->geometry()->geometryId(), GeoDataTrackId );
    GeoDataTrack* track = static_cast<GeoDataTrack*>( placemark->geometry() );
    QCOMPARE( track->size(), 7 );
    {
        GeoDataCoordinates coord = track->coordinatesList().at( 0 );
        QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 );
        QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 );
        QCOMPARE( coord.altitude(), 156.000000 );
    }

    {
        const GeoDataLineString *lineString = track->lineString();
        QCOMPARE( lineString->size(), 7 );
        GeoDataCoordinates coord = lineString->at( 0 );
        QCOMPARE( coord.longitude( GeoDataCoordinates::Degree ), -122.207881 );
        QCOMPARE( coord.latitude( GeoDataCoordinates::Degree ), 37.371915 );
        QCOMPARE( coord.altitude(), 156.000000 );
    }

    delete dataDocument;
}
예제 #10
0
void TourWidgetPrivate::addRemovePlacemark()
{
    GeoDataDelete *deleteItem = new GeoDataDelete;
    GeoDataPlacemark *placemark = new GeoDataPlacemark;
    placemark->setTargetId( m_delegate->defaultFeatureId() );
    deleteItem->append( placemark );
    GeoDataUpdate *update = new GeoDataUpdate;
    update->setDelete( deleteItem );
    GeoDataAnimatedUpdate *animatedUpdate = new GeoDataAnimatedUpdate;
    animatedUpdate->setUpdate( update );
    addTourPrimitive( animatedUpdate );
}
예제 #11
0
void LocalOsmSearchRunner::search( const QString &searchTerm, const GeoDataLatLonBox &preferred )
{
    const DatabaseQuery userQuery( model(), searchTerm, preferred );

    QVector<OsmPlacemark> placemarks = m_database.find( userQuery );

    QVector<GeoDataPlacemark*> result;
    for( const OsmPlacemark &placemark: placemarks ) {
        GeoDataPlacemark* hit = new GeoDataPlacemark;
        hit->setName( placemark.name() );
        if ( placemark.category() == OsmPlacemark::Address && !placemark.houseNumber().isEmpty() ) {
            hit->setName(hit->name() + QLatin1Char(' ') + placemark.houseNumber());
        }
        if ( !placemark.additionalInformation().isEmpty() ) {
            hit->setName(hit->name() + QLatin1Char('(') + placemark.additionalInformation() + QLatin1Char(')'));
        }
        if ( placemark.category() != OsmPlacemark::UnknownCategory ) {
            hit->setVisualCategory( m_categoryMap[placemark.category()] );
        }
        hit->setGeometry( new GeoDataPoint( placemark.longitude(), placemark.latitude(), 0.0, GeoDataCoordinates::Degree ) );
        result << hit;
    }

    emit searchFinished( result );
}
예제 #12
0
파일: MonavRunner.cpp 프로젝트: KDE/marble
GeoDataDocument* MonavRunnerPrivate::createDocument( Marble::GeoDataLineString* geometry, const QVector< Marble::GeoDataPlacemark* >& instructions, const QString& name, const Marble::GeoDataExtendedData& data )
{
    if ( !geometry || geometry->isEmpty() ) {
        return 0;
    }

    GeoDataDocument* result = new GeoDataDocument;
    GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
    routePlacemark->setName(QStringLiteral("Route"));
    routePlacemark->setGeometry( geometry );
    routePlacemark->setExtendedData( data );
    result->append( routePlacemark );

    foreach( GeoDataPlacemark* placemark, instructions ) {
        result->append( placemark );
    }
예제 #13
0
QVector<GeoDataPlacemark*> GosmoreRunnerPrivate::parseGosmoreInstructions( const QByteArray &content )
{
    // Determine gosmore version
    QStringList lines = QString::fromUtf8(content).split(QLatin1Char('\r'));
    if ( lines.size() > 2 ) {
        const QStringList fields = lines.at(lines.size()-2).split(QLatin1Char(','));
        m_parser.setFieldIndex( WaypointParser::RoadName, fields.size()-1 );
        if ( fields.size() < 5 || fields.size() > 6 ) {
            // Can happen when gosmore changes the output format, returns garbage
            // or the last street name contains a comma. We may still parse it correctly, just try.
            mDebug() << "Unexpected number of fields. This gosmore version may be unsupported.";
        }
    }

    QVector<GeoDataPlacemark*> result;
    QTextStream stream( content );
    stream.setCodec("UTF8");
    stream.setAutoDetectUnicode( true );

    RoutingInstructions directions = InstructionTransformation::process( m_parser.parse( stream ) );
    for( int i=0; i<directions.size(); ++i ) {
        GeoDataPlacemark* placemark = new GeoDataPlacemark( directions[i].instructionText() );
        GeoDataExtendedData extendedData;
        GeoDataData turnType;
        turnType.setName(QStringLiteral("turnType"));
        turnType.setValue( qVariantFromValue<int>( int( directions[i].turnType() ) ) );
        extendedData.addValue( turnType );
        GeoDataData roadName;
        roadName.setName(QStringLiteral("roadName"));
        roadName.setValue( directions[i].roadName() );
        extendedData.addValue( roadName );
        placemark->setExtendedData( extendedData );
        Q_ASSERT( !directions[i].points().isEmpty() );
        GeoDataLineString* geometry = new GeoDataLineString;
        QVector<RoutingWaypoint> items = directions[i].points();
        for (int j=0; j<items.size(); ++j ) {
            RoutingPoint point = items[j].point();
            GeoDataCoordinates coordinates( point.lon(), point.lat(), 0.0, GeoDataCoordinates::Degree );
            geometry->append( coordinates );
        }
        placemark->setGeometry( geometry );
        result.push_back( placemark );
    }

    return result;
}
예제 #14
0
void TourWidgetPrivate::addChangePlacemark()
{
    GeoDataChange *change = new GeoDataChange;
    GeoDataPlacemark *placemark = 0;
    GeoDataFeature *lastFeature = m_delegate->findFeature( m_delegate->defaultFeatureId() );
    if( lastFeature != 0 && lastFeature->nodeType() == GeoDataTypes::GeoDataPlacemarkType ) {
        GeoDataPlacemark *target = static_cast<GeoDataPlacemark*>( lastFeature );
        placemark = new GeoDataPlacemark( *target );
        placemark->setTargetId( m_delegate->defaultFeatureId() );
        placemark->setId( "" );
    } else {
        placemark = new GeoDataPlacemark;
    }
    change->append( placemark );
    GeoDataUpdate *update = new GeoDataUpdate;
    update->setChange( change );
    GeoDataAnimatedUpdate *animatedUpdate = new GeoDataAnimatedUpdate;
    animatedUpdate->setUpdate( update );
    addTourPrimitive( animatedUpdate );
}
예제 #15
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();
    }
}
예제 #16
0
void OsmNominatimRunner::handleReverseGeocodingResult( QNetworkReply* reply )
{
    if ( !reply->bytesAvailable() ) {
        returnNoReverseGeocodingResult();
        return;
    }

    QDomDocument xml;
    if ( !xml.setContent( reply->readAll() ) ) {
        mDebug() << "Cannot parse osm nominatim result " << xml.toString();
        returnNoReverseGeocodingResult();
        return;
    }

    QDomElement root = xml.documentElement();
    QDomNodeList places = root.elementsByTagName( "result" );
    if ( places.size() == 1 ) {
        QString address = places.item( 0 ).toElement().text();
        GeoDataPlacemark placemark;
        placemark.setAddress( address );
        placemark.setCoordinate( GeoDataPoint( m_coordinates ) );

        QDomNodeList details = root.elementsByTagName( "addressparts" );
        if ( details.size() == 1 ) {
            GeoDataExtendedData extendedData;
            addData( details, "road", &extendedData );
            addData( details, "house_number", &extendedData );
            addData( details, "village", &extendedData );
            addData( details, "city", &extendedData );
            addData( details, "county", &extendedData );
            addData( details, "state", &extendedData );
            addData( details, "postcode", &extendedData );
            addData( details, "country", &extendedData );
            placemark.setExtendedData( extendedData );
        }

        emit reverseGeocodingFinished( m_coordinates, placemark );
    } else {
        returnNoReverseGeocodingResult();
    }
}
예제 #17
0
int AbstractGeoPolygonGraphicsItem::extractElevation(const GeoDataPlacemark &placemark)
{
    int elevation = 0;

    const OsmPlacemarkData &osmData = placemark.osmData();

    const auto tagIter = osmData.findTag(QStringLiteral("ele"));
    if (tagIter != osmData.tagsEnd()) {
        elevation = tagIter.value().toInt();
    }

    return elevation;
}
예제 #18
0
void GeoDataContainer::unpack( QDataStream& stream )
{
    Q_D(GeoDataContainer);
    GeoDataFeature::unpack( stream );

    int count;
    stream >> count;

    for ( int i = 0; i < count; ++i ) {
        int featureId;
        stream >> featureId;
        switch( featureId ) {
            case GeoDataDocumentId:
                /* not usable!!!! */ break;
            case GeoDataFolderId:
                {
                GeoDataFolder *folder = new GeoDataFolder;
                folder->unpack( stream );
                d->m_vector.append( folder );
                }
                break;
            case GeoDataPlacemarkId:
                {
                GeoDataPlacemark *placemark = new GeoDataPlacemark;
                placemark->unpack( stream );
                d->m_vector.append( placemark );
                }
                break;
            case GeoDataNetworkLinkId:
                break;
            case GeoDataScreenOverlayId:
                break;
            case GeoDataGroundOverlayId:
                break;
            default: break;
        };
    }
}
예제 #19
0
GeoDataDocument* MonavRunnerPrivate::createDocument( GeoDataLineString *geometry, const QVector<GeoDataPlacemark*> &instructions ) const
{
    if ( !geometry || geometry->isEmpty() ) {
        return 0;
    }

    GeoDataDocument* result = new GeoDataDocument;
    GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
    routePlacemark->setName( "Route" );
    routePlacemark->setGeometry( geometry );
    result->append( routePlacemark );

    QString name = "%1 %2 (Monav)";
    QString unit = "m";
    qreal length = geometry->length( EARTH_RADIUS );
    if ( length >= 1000 ) {
        length /= 1000.0;
        unit = "km";
    }

    foreach( GeoDataPlacemark* placemark, instructions ) {
        result->append( placemark );
    }
예제 #20
0
GeoDataLatLonAltBox GeoDataContainer::latLonAltBox() const
{
    Q_D(const GeoDataContainer);
    GeoDataLatLonAltBox result;

    QVector<GeoDataFeature*>::const_iterator it = d->m_vector.constBegin();
    QVector<GeoDataFeature*>::const_iterator end = d->m_vector.constEnd();
    for (; it != end; ++it) {

        // Get all the placemarks from GeoDataContainer
        if ( (*it)->nodeType() == GeoDataTypes::GeoDataPlacemarkType ) {
            GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>(*it);

            // Only use visible placemarks for extracting their latLonAltBox and
            // making an union with the global latLonAltBox Marble will fit its
            // zoom to
            if (placemark->isVisible())
            {
                if (result.isEmpty()) {
                    result = placemark->geometry()->latLonAltBox();
                } else {
                    result |= placemark->geometry()->latLonAltBox();
                }
            }
        }
        else if ( (*it)->nodeType() == GeoDataTypes::GeoDataFolderType
                 || (*it)->nodeType() == GeoDataTypes::GeoDataDocumentType ) {
            GeoDataContainer *container = static_cast<GeoDataContainer*>(*it);
            if (result.isEmpty()) {
                result = container->latLonAltBox();
            } else {
                result |= container->latLonAltBox();
            }
        }
    }
    return result;
}
예제 #21
0
const GeoDataLatLonAltBox& GeoDataRegion::latLonAltBox() const
{
    // FIXME: This isn't exactly what a 'const' function should do, is it?

    // If the latLonAltBox hasn't been set try to determine it automatically
    if ( !d->m_latLonAltBox ) {
        // If there is a parent try to 
        if ( d->m_parent ) {

            if ( d->m_parent->nodeType() == GeoDataTypes::GeoDataPlacemarkType ) {

                GeoDataPlacemark * placemark = dynamic_cast<GeoDataPlacemark*>( d->m_parent );
                GeoDataGeometry * geometry = placemark->geometry();
                if ( geometry ) {
                    // TODO: automatically calculate the geometry from the
                    //       GeoDataGeometry object.
                    // return geometry->latLonAltBox();
                }

                d->m_latLonAltBox = new GeoDataLatLonAltBox( placemark->coordinate() );
            }
            else {
                // If the parent is not a placemark then create a default LatLonAltBox
                // FIXME: reference a shared object instead
                d->m_latLonAltBox = new GeoDataLatLonAltBox();
            }
        }
        else {
            // If there is no parent then create a default LatLonAltBox
            // FIXME: reference a shared object instead
            d->m_latLonAltBox = new GeoDataLatLonAltBox();
        }
    }
    
    return *(d->m_latLonAltBox);
}
예제 #22
0
void TourWidgetPrivate::addPlacemark()
{
    // Get the normalized coordinates of the focus point. There will be automatically added a new
    // placemark.
    qreal lat = m_widget->focusPoint().latitude();
    qreal lon = m_widget->focusPoint().longitude();
    GeoDataCoordinates::normalizeLonLat( lon, lat );

    GeoDataDocument *document = new GeoDataDocument;
    if( m_document->id().isEmpty() ) {
        if( m_document->name().isEmpty() ) {
            m_document->setId( "untitled_tour" );
        } else {
            m_document->setId( m_document->name().trimmed().replace( " ", "_" ).toLower() );
        }
    }
    document->setTargetId( m_document->id() );

    GeoDataPlacemark *placemark = new GeoDataPlacemark;
    placemark->setCoordinate( lon, lat );
    placemark->setVisible( true );
    placemark->setBalloonVisible( true );
    GeoDataStyle *newStyle = new GeoDataStyle( *placemark->style() );
    newStyle->iconStyle().setIcon( QImage() );
    newStyle->iconStyle().setIconPath( MarbleDirs::path("bitmaps/redflag_22.png") );
    placemark->setStyle( newStyle );

    document->append( placemark );

    GeoDataCreate *create = new GeoDataCreate;
    create->append( document );
    GeoDataUpdate *update = new GeoDataUpdate;
    update->setCreate( create );
    GeoDataAnimatedUpdate *animatedUpdate = new GeoDataAnimatedUpdate;
    animatedUpdate->setUpdate( update );

    if( m_delegate->editAnimatedUpdate( animatedUpdate ) ) {
        addTourPrimitive( animatedUpdate );
        m_delegate->setDefaultFeatureId( placemark->id() );
    } else {
        delete animatedUpdate;
    }
}
예제 #23
0
void CountryByFlag::postQuestion( QObject *gameObject )
{
    /**
     * Find a random placemark
     */
    Q_ASSERT_X( d->m_countryNames, "CountryByFlag::postQuestion",
                "CountryByFlagPrivate::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;
    QVariantList answerOptions;
    QString flagPath;

    while ( !found ) {
        int randomIndex = qrand()%countryPlacemarks.size();
        placemark = countryPlacemarks[randomIndex];

        if ( !d->m_continentsAndOceans.contains(placemark->name(), Qt::CaseSensitive) ) {
            flagPath = MarbleDirs::path( QString("flags/flag_%1.svg").arg(placemark->countryCode().toLower()) );
            QImage flag = QFile::exists( flagPath ) ? QImage( flagPath ) : QImage();
            if ( !flag.isNull() ) {
                flagPath = QString("%1flag_%2.svg").arg("../../../data/flags/").arg(placemark->countryCode().toLower());
                found = true;
            }
        }
    }

    answerOptions << placemark->name()
    << countryPlacemarks[qrand()%countryPlacemarks.size()]->name()
    << countryPlacemarks[qrand()%countryPlacemarks.size()]->name()
    << countryPlacemarks[qrand()%countryPlacemarks.size()]->name();

    // Randomize the options in the 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, "countryByFlagQuestion",
                                   Q_ARG(QVariant, QVariant::fromValue(answerOptions)),
                                   Q_ARG(QVariant, QVariant::fromValue(flagPath)),
                                   Q_ARG(QVariant, QVariant::fromValue(placemark->name())) );
    }
}
예제 #24
0
파일: GeoUriRunner.cpp 프로젝트: KDE/marble
void GeoUriRunner::search(const QString &searchTerm, const GeoDataLatLonBox &)
{
    QVector<GeoDataPlacemark*> vector;

    GeoUriParser uriParser(searchTerm);
    const bool success = uriParser.parse();
    if (success &&
        (uriParser.planet().id() == model()->planet()->id())) {
        const GeoDataCoordinates coordinates = uriParser.coordinates();

        GeoDataPlacemark *placemark = new GeoDataPlacemark;
        placemark->setName(searchTerm);
        placemark->setCoordinate(coordinates);
        placemark->setVisualCategory(GeoDataPlacemark::Coordinate);
        placemark->setPopularity(1000000000);
        placemark->setZoomLevel(1);

        vector.append(placemark);
    }

    emit searchFinished(vector);
}
예제 #25
0
void OsmNominatimRunner::handleResult( QNetworkReply* reply )
{   
    QDomDocument xml;
    if (!xml.setContent(reply->readAll())) {
        qWarning() << "Cannot parse osm nominatim result";
        returnNoResults();
        return;
    }

    QVector<GeoDataPlacemark*> placemarks;
    QDomElement root = xml.documentElement();
    QDomNodeList places = root.elementsByTagName("place");
    for (int i=0; i<places.size(); ++i) {
        QDomNode place = places.at(i);
        QDomNamedNodeMap attributes = place.attributes();
        QString lon = attributes.namedItem("lon").nodeValue();
        QString lat = attributes.namedItem("lat").nodeValue();
        QString desc = attributes.namedItem("display_name").nodeValue();
        QString key = attributes.namedItem("class").nodeValue();
        QString value = attributes.namedItem("type").nodeValue();

        QString name = place.firstChildElement(value).text();
        QString road = place.firstChildElement("road").text();

        QString city = place.firstChildElement("city").text();
        if( city.isEmpty() ) {
            city = place.firstChildElement("town").text();
            if( city.isEmpty() ) {
                city = place.firstChildElement("village").text();
            } if( city.isEmpty() ) {
                city = place.firstChildElement("hamlet").text();
            }
        }

        QString administrative = place.firstChildElement("county").text();
        if( administrative.isEmpty() ) {
            administrative = place.firstChildElement("region").text();
            if( administrative.isEmpty() ) {
                administrative = place.firstChildElement("state").text();
            }
        }

        QString country = place.firstChildElement("country").text();

        QString description;
        for (int i=0; i<place.childNodes().size(); ++i) {
            QDomElement item = place.childNodes().at(i).toElement();
            description += item.nodeName() + ':' + item.text() + '\n';
        }
        description += "Category: " + key + '/' + value;

        if (!lon.isEmpty() && !lat.isEmpty() && !desc.isEmpty()) {
            QString placemarkName;
            GeoDataPlacemark* placemark = new GeoDataPlacemark;
            // try to provide 2 fields
            if (!name.isEmpty()) {
                placemarkName = name;
            }
            if (!road.isEmpty() && road != placemarkName ) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += road;
            }
            if (!city.isEmpty() && !placemarkName.contains(",") && city != placemarkName) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += city;
            }
            if (!administrative.isEmpty()&& !placemarkName.contains(",") && administrative != placemarkName) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += administrative;
            }
            if (!country.isEmpty()&& !placemarkName.contains(",") && country != placemarkName) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += country;
            }
            if (placemarkName.isEmpty()) {
                placemarkName = desc;
            }
            placemark->setName( placemarkName );
            placemark->setDescription(description);
            placemark->setCoordinate( lon.toDouble(), lat.toDouble(), 0, GeoDataCoordinates::Degree );
            GeoDataFeature::GeoDataVisualCategory category = GeoDataFeature::OsmVisualCategory( key + '=' + value );
            placemark->setVisualCategory( category );
            placemarks << placemark;
        }
    }
    
    emit searchFinished( placemarks );
}
예제 #26
0
파일: JsonParser.cpp 프로젝트: KDE/marble
bool JsonParser::read( QIODevice* device )
{
    // Assert previous document got released.
    delete m_document;
    m_document = new GeoDataDocument;
    Q_ASSERT( m_document );

    // Read file data
    QJsonParseError error;
    const QJsonDocument jsonDoc = QJsonDocument::fromJson(device->readAll(), &error);

    if (jsonDoc.isNull()) {
        qDebug() << "Error parsing GeoJSON : " << error.errorString();
        return false;
    }

    // Start parsing
    const QJsonValue featuresValue = jsonDoc.object().value(QStringLiteral("features"));

    // In GeoJSON format, geometries are stored in features, so we iterate on features
    if (featuresValue.isArray()) {
        const QJsonArray featureArray = featuresValue.toArray();

        // Parse each feature
        for (int featureIndex = 0; featureIndex < featureArray.size(); ++featureIndex) {
            const QJsonObject featureObject = featureArray[featureIndex].toObject();

            // Check if the feature contains a geometry
            const QJsonValue geometryValue = featureObject.value(QStringLiteral("geometry"));
            if (geometryValue.isObject()) {
                const QJsonObject geometryObject = geometryValue.toObject();

                // Variables for creating the geometry
                QList<GeoDataGeometry*> geometryList;
                QList<GeoDataPlacemark*> placemarkList;

                // Create the different geometry types
                const QString geometryType = geometryObject.value(QStringLiteral("type")).toString().toUpper();

                if (geometryType == QLatin1String("POLYGON")) {
                    // Check first that there are coordinates
                    const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
                    if (coordinatesValue.isArray()) {
                        const QJsonArray coordinateArray = coordinatesValue.toArray();

                        GeoDataPolygon * geom = new GeoDataPolygon( RespectLatitudeCircle | Tessellate );

                        // Coordinates first array will be the outer boundary, if there are more
                        // positions those will be inner holes
                        for (int ringIndex = 0 ; ringIndex < coordinateArray.size(); ++ringIndex) {
                            const QJsonArray ringArray = coordinateArray[ringIndex].toArray();

                            GeoDataLinearRing linearRing;

                            for (int coordinatePairIndex = 0; coordinatePairIndex < ringArray.size(); ++coordinatePairIndex) {
                                const QJsonArray coordinatePairArray = ringArray[coordinatePairIndex].toArray();

                                const qreal longitude = coordinatePairArray.at(0).toDouble();
                                const qreal latitude = coordinatePairArray.at(1).toDouble();

                                linearRing.append( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );
                            }

                            // Outer ring
                            if (ringIndex == 0) {
                                geom->setOuterBoundary( linearRing );
                            }
                            // Inner holes
                            else {
                                geom->appendInnerBoundary( linearRing );
                            }
                        }
                        geometryList.append( geom );
                    }

                } else if (geometryType == QLatin1String("MULTIPOLYGON")) {
                    // Check first that there are coordinates
                    const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
                    if (coordinatesValue.isArray()) {
                        const QJsonArray coordinateArray = coordinatesValue.toArray();

                        for (int polygonIndex = 0; polygonIndex < coordinateArray.size(); ++polygonIndex) {
                            const QJsonArray polygonArray = coordinateArray[polygonIndex].toArray();

                            GeoDataPolygon * geom = new GeoDataPolygon( RespectLatitudeCircle | Tessellate );

                            // Coordinates first array will be the outer boundary, if there are more
                            // positions those will be inner holes
                            for (int ringIndex = 0 ; ringIndex < polygonArray.size(); ++ringIndex) {
                                const QJsonArray ringArray = polygonArray[ringIndex].toArray();

                                GeoDataLinearRing linearRing;

                                for (int coordinatePairIndex = 0; coordinatePairIndex < ringArray.size(); ++coordinatePairIndex) {
                                    const QJsonArray coordinatePairArray = ringArray[coordinatePairIndex].toArray();

                                    const qreal longitude = coordinatePairArray.at(0).toDouble();
                                    const qreal latitude = coordinatePairArray.at(1).toDouble();

                                    linearRing.append( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );
                                }

                                // Outer ring
                                if (ringIndex == 0) {
                                    geom->setOuterBoundary( linearRing );
                                }
                                // Inner holes
                                else {
                                    geom->appendInnerBoundary( linearRing );
                                }
                            }
                            geometryList.append( geom );
                        }
                    }

                } else if (geometryType == QLatin1String("LINESTRING")) {

                    // Check first that there are coordinates
                    const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
                    if (coordinatesValue.isArray()) {
                        const QJsonArray coordinateArray = coordinatesValue.toArray();

                        GeoDataLineString * geom = new GeoDataLineString( RespectLatitudeCircle | Tessellate );

                        for (int coordinatePairIndex = 0; coordinatePairIndex < coordinateArray.size(); ++coordinatePairIndex) {
                            const QJsonArray coordinatePairArray = coordinateArray[coordinatePairIndex].toArray();

                            const qreal longitude = coordinatePairArray.at(0).toDouble();
                            const qreal latitude = coordinatePairArray.at(1).toDouble();

                            geom->append( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );
                        }
                        geometryList.append( geom );
                    }

                } else if (geometryType == QLatin1String("MULTILINESTRING")) {

                    // Check first that there are coordinates
                    const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
                    if (coordinatesValue.isArray()) {
                        const QJsonArray coordinateArray = coordinatesValue.toArray();

                        for (int lineStringIndex = 0; lineStringIndex < coordinateArray.size(); ++lineStringIndex) {
                            const QJsonArray lineStringArray = coordinateArray[lineStringIndex].toArray();

                            GeoDataLineString * geom = new GeoDataLineString( RespectLatitudeCircle | Tessellate );

                            for (int coordinatePairIndex = 0; coordinatePairIndex < lineStringArray.size(); ++coordinatePairIndex) {
                                const QJsonArray coordinatePairArray = lineStringArray[coordinatePairIndex].toArray();

                                const qreal longitude = coordinatePairArray.at(0).toDouble();
                                const qreal latitude = coordinatePairArray.at(1).toDouble();

                                geom->append( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );
                            }
                            geometryList.append( geom );
                        }
                    }

                } else if (geometryType == QLatin1String("POINT")) {

                    // Check first that there are coordinates
                    const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
                    if (coordinatesValue.isArray()) {
                        const QJsonArray coordinatePairArray = coordinatesValue.toArray();

                        GeoDataPoint * geom = new GeoDataPoint();

                        const qreal longitude = coordinatePairArray.at(0).toDouble();
                        const qreal latitude = coordinatePairArray.at(1).toDouble();

                        geom->setCoordinates( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );

                        geometryList.append( geom );
                    }
                } else if (geometryType == QLatin1String("MULTIPOINT")) {

                    // Check first that there are coordinates
                    const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
                    if (coordinatesValue.isArray()) {
                        const QJsonArray coordinateArray = coordinatesValue.toArray();

                        for (int pointIndex = 0; pointIndex < coordinateArray.size(); ++pointIndex) {
                            const QJsonArray coordinatePairArray = coordinateArray[pointIndex].toArray();

                            GeoDataPoint * geom = new GeoDataPoint();

                            const qreal longitude = coordinatePairArray.at(0).toDouble();
                            const qreal latitude = coordinatePairArray.at(1).toDouble();

                            geom->setCoordinates( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );

                            geometryList.append( geom );
                        }
                    }
                }


                // Parse the features properties
                const QJsonValue propertiesValue = featureObject.value(QStringLiteral("properties"));
                if (!geometryList.isEmpty() && propertiesValue.isObject()) {
                    const QJsonObject propertiesObject = propertiesValue.toObject();

                    // First create a placemark for each geometry, there could be multi geometries
                    // that are translated into more than one geometry/placemark
                    for ( int numberGeometries = 0 ; numberGeometries < geometryList.length() ; numberGeometries++ ) {
                        GeoDataPlacemark * placemark = new GeoDataPlacemark();
                        placemarkList.append( placemark );
                    }

                    OsmPlacemarkData osmData;

                    QJsonObject::ConstIterator it = propertiesObject.begin();
                    const QJsonObject::ConstIterator end = propertiesObject.end();
                    for ( ; it != end; ++it) {
                        if (it.value().isObject() || it.value().isArray()) {
                            qDebug() << "Skipping property, values of type arrays and objects not supported:" << it.key();
                            continue;
                        }

                        // pass value through QVariant to also get bool & numbers
                        osmData.addTag(it.key(), it.value().toVariant().toString());
                    }

                    // If the property read, is the features name
                    const auto tagIter = osmData.findTag(QStringLiteral("name"));
                    if (tagIter != osmData.tagsEnd()) {
                        const QString& name = tagIter.value();
                        for (int pl = 0 ; pl < placemarkList.length(); ++pl) {
                            placemarkList.at(pl)->setName(name);
                        }
                    }

                    const GeoDataPlacemark::GeoDataVisualCategory category = StyleBuilder::determineVisualCategory(osmData);
                    if (category != GeoDataPlacemark::None) {
                        // Add the visual category to all the placemarks
                        for (int pl = 0 ; pl < placemarkList.length(); ++pl) {
                            placemarkList.at(pl)->setVisualCategory(category);
                            placemarkList.at(pl)->setOsmData(osmData);
                        }
                    }
                }

                // Add the geometry to the document
                if ( geometryList.length() == placemarkList.length() ) {

                    while( placemarkList.length() > 0 ) {

                        GeoDataPlacemark * placemark = placemarkList.last();
                        placemarkList.pop_back();

                        GeoDataGeometry * geom = geometryList.last();
                        geometryList.pop_back();

                        placemark->setGeometry( geom );
                        placemark->setVisible( true );
                        m_document->append( placemark );
                    }
                }

                // If geometries or placemarks missing inside the lists, delete them
                qDeleteAll( geometryList.begin(), geometryList.end() );
                geometryList.clear();
                qDeleteAll( placemarkList.begin(), placemarkList.end() );
                placemarkList.clear();
            }
        }
    }
    return true;
}
예제 #27
0
void OsmNode::create(GeoDataDocument *document) const
{
    GeoDataFeature::GeoDataVisualCategory const category = OsmPresetLibrary::determineVisualCategory(m_osmData);
    if (category == GeoDataFeature::None ||
       (category >= GeoDataFeature::HighwaySteps && category <= GeoDataFeature::HighwayMotorway)) {
        return;
    }

    GeoDataPlacemark* placemark = new GeoDataPlacemark;
    placemark->setOsmData(m_osmData);
    placemark->setCoordinate(m_coordinates);

    if ((category == GeoDataFeature::TransportCarShare || category == GeoDataFeature::MoneyAtm)
            && m_osmData.containsTagKey("operator")) {
        placemark->setName(m_osmData.tagValue("operator"));
    } else {
        placemark->setName(m_osmData.tagValue("name"));
    }
    placemark->setVisualCategory(category);
    placemark->setStyle( GeoDataStyle::Ptr() );

    if (category == GeoDataFeature::NaturalTree) {
        qreal const lat = m_coordinates.latitude(GeoDataCoordinates::Degree);
        if (qAbs(lat) > 15) {
            /** @todo Should maybe auto-adjust to MarbleClock at some point */
            QDate const date = QDate::currentDate();
            bool const southernHemisphere = lat < 0;
            QDate const autumnStart = QDate(date.year(), southernHemisphere ? 3 : 9, 15);
            QDate const winterEnd = southernHemisphere ? QDate(date.year(), 8, 15) : QDate(date.year()+1, 2, 15);
            if (date > autumnStart && date < winterEnd) {
                QDate const autumnEnd = QDate(date.year(), southernHemisphere ? 5 : 11, 15);
                QString const season = date < autumnEnd ? "autumn" : "winter";
                GeoDataIconStyle iconStyle = placemark->style()->iconStyle();
                QString const bitmap = QString("bitmaps/osmcarto/symbols/48/individual/tree-29-%1.png").arg(season);
                iconStyle.setIconPath(MarbleDirs::path(bitmap));

                GeoDataStyle::Ptr style(new GeoDataStyle(*placemark->style()));
                style->setIconStyle(iconStyle);
                placemark->setStyle(style);

            }
        }
    }

    placemark->setZoomLevel( 18 );
    if (category >= GeoDataFeature::PlaceCity && category <= GeoDataFeature::PlaceVillage) {
        int const population = m_osmData.tagValue("population").toInt();
        placemark->setPopulation(qMax(0, population));
        if (population > 0) {
            placemark->setZoomLevel(populationIndex(population));
            placemark->setPopularity(population);
        } else {
            switch (category) {
            case GeoDataFeature::PlaceCity:     placemark->setZoomLevel(9);  break;
            case GeoDataFeature::PlaceSuburb:   placemark->setZoomLevel(13);  break;
            case GeoDataFeature::PlaceHamlet:   placemark->setZoomLevel(15);  break;
            case GeoDataFeature::PlaceLocality: placemark->setZoomLevel(15);  break;
            case GeoDataFeature::PlaceTown:     placemark->setZoomLevel(11);  break;
            case GeoDataFeature::PlaceVillage:  placemark->setZoomLevel(13); break;
            default:                            placemark->setZoomLevel(10); break;
            }
        }
    } else if (category == GeoDataFeature::NaturalPeak) {
        placemark->setZoomLevel(11);
        bool isInteger = false;
        int const elevation = m_osmData.tagValue("ele").toInt(&isInteger);
        if (isInteger) {
            placemark->setName(QString("%1 (%2 m)").arg(placemark->name()).arg(elevation));
        }
    }

    OsmObjectManager::registerId(m_osmData.id());
    document->append(placemark);
}
예제 #28
0
파일: TestModel.cpp 프로젝트: KDE/marble
void TestModel::simpleParseTest()
{
  QString const centerContent (
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\">"
"<Placemark>"
  "<Model id=\"model_4\">"
    "<altitudeMode>relativeToGround</altitudeMode>"
    "<Location>"
      "<longitude>-105.27</longitude>"
      "<latitude>40.00</latitude>"
      "<altitude>23.4</altitude>"
    "</Location>"
    "<Orientation>"
      "<heading>1</heading>"
      "<tilt>2</tilt>"
      "<roll>3</roll>"
    "</Orientation>"
    "<Scale>"
      "<x>3</x>"
      "<y>4</y>"
      "<z>5</z>"
    "</Scale>"
    "<Link>"
      "<href>MackyBldg.kmz/files/CU Macky.dae</href>"
      "<refreshMode>onExpire</refreshMode>"
    "</Link>"
    "<ResourceMap id=\"resourcemap_for_model_4\">"
      "<Alias>"
        "<sourceHref>../files/CU-Macky-4sideturretnoCulling.jpg</sourceHref>"
        "<targetHref>../files/CU-Macky-4sideturretnoCulling.jpg</targetHref>"
      "</Alias>"
    "</ResourceMap>"
  "</Model>"
"</Placemark>"
"</kml>" );
    GeoDataDocument* dataDocument = parseKml( centerContent );

    QCOMPARE( dataDocument->placemarkList().size(), 1 );

    GeoDataPlacemark *placemark = dataDocument->placemarkList().at( 0 );

    GeoDataModel *model = dynamic_cast<GeoDataModel*>( placemark->geometry() );

    QVERIFY( model != 0 );

    QCOMPARE( model->altitudeMode(), RelativeToGround);

    QCOMPARE( model->location().altitude(), 23.4);
    QCOMPARE( model->location().latitude(GeoDataCoordinates::Degree), 40.00 );
    QCOMPARE( model->location().longitude(GeoDataCoordinates::Degree), -105.27 );

    QCOMPARE( model->orientation().heading(), 1.0);
    QCOMPARE( model->orientation().tilt(), 2.0);
    QCOMPARE( model->orientation().roll(), 3.0);
    QCOMPARE( model->scale().x(), 3.0);
    QCOMPARE( model->scale().y(), 4.0);
    QCOMPARE( model->scale().z(), 5.0);
    QCOMPARE( model->link().href(), QString("MackyBldg.kmz/files/CU Macky.dae"));
    QCOMPARE( model->link().refreshMode(), GeoDataLink::OnExpire );
    QCOMPARE( model->targetHref(), QString("../files/CU-Macky-4sideturretnoCulling.jpg"));
    QCOMPARE( model->sourceHref(), QString("../files/CU-Macky-4sideturretnoCulling.jpg"));

    delete dataDocument;
}
예제 #29
0
bool GeoDataPlacemark::operator==( const GeoDataPlacemark& other ) const
{ 
    if ( !equals(other) ||
         p()->m_countrycode != other.p()->m_countrycode ||
         p()->m_area != other.p()->m_area ||
         p()->m_population != other.p()->m_population ||
         p()->m_state != other.p()->m_state ) {
        return false;
    }

    if ( !p()->m_geometry && !other.p()->m_geometry ) {
        return true;
    } else if ( (!p()->m_geometry && other.p()->m_geometry) ||
                (p()->m_geometry && !other.p()->m_geometry) ) {
        return false;
    }

    if ( p()->m_geometry->nodeType() != other.p()->m_geometry->nodeType() ) {
        return false;
    }

    if ( p()->m_geometry->nodeType() == GeoDataTypes::GeoDataPolygonType ) {
        GeoDataPolygon *thisPoly = dynamic_cast<GeoDataPolygon*>( p()->m_geometry );
        GeoDataPolygon *otherPoly = dynamic_cast<GeoDataPolygon*>( other.p()->m_geometry );
        Q_ASSERT( thisPoly && otherPoly );

        if ( *thisPoly != *otherPoly ) {
            return false;
        }
    } else if ( p()->m_geometry->nodeType() == GeoDataTypes::GeoDataLineStringType ) {
        GeoDataLineString *thisLine = dynamic_cast<GeoDataLineString*>( p()->m_geometry );
        GeoDataLineString *otherLine = dynamic_cast<GeoDataLineString*>( other.p()->m_geometry );
        Q_ASSERT( thisLine && otherLine );

        if ( *thisLine != *otherLine ) {
            return false;
        }
    } else if ( p()->m_geometry->nodeType() == GeoDataTypes::GeoDataModelType ) {
        GeoDataModel *thisModel = dynamic_cast<GeoDataModel*>( p()->m_geometry );
        GeoDataModel *otherModel = dynamic_cast<GeoDataModel*>( other.p()->m_geometry );
        Q_ASSERT( thisModel && otherModel );

        if ( *thisModel != *otherModel ) {
            return false;
        }
    /*} else if ( p()->m_geometry->nodeType() == GeoDataTypes::GeoDataMultiGeometryType ) {
        GeoDataMultiGeometry *thisMG = dynamic_cast<GeoDataMultiGeometry*>( p()->m_geometry );
        GeoDataMultiGeometry *otherMG = dynamic_cast<GeoDataMultiGeometry*>( other.p()->m_geometry );
        Q_ASSERT( thisMG && otherMG );

        if ( *thisMG != *otherMG ) {
            return false;
        } */ // Does not have equality operators. I guess they need to be implemented soon.
    } else if ( p()->m_geometry->nodeType() == GeoDataTypes::GeoDataTrackType ) {
        GeoDataTrack *thisTrack = dynamic_cast<GeoDataTrack*>( p()->m_geometry );
        GeoDataTrack *otherTrack = dynamic_cast<GeoDataTrack*>( other.p()->m_geometry );
        Q_ASSERT( thisTrack && otherTrack );

        if ( *thisTrack != *otherTrack ) {
            return false;
        }
    } else if ( p()->m_geometry->nodeType() == GeoDataTypes::GeoDataMultiTrackType ) {
        GeoDataMultiTrack *thisMT = dynamic_cast<GeoDataMultiTrack*>( p()->m_geometry );
        GeoDataMultiTrack *otherMT = dynamic_cast<GeoDataMultiTrack*>( other.p()->m_geometry );
        Q_ASSERT( thisMT && otherMT );

        if ( *thisMT != *otherMT ) {
            return false;
        }
    } else if ( p()->m_geometry->nodeType() == GeoDataTypes::GeoDataPointType ) {
        GeoDataPoint *thisPoint = dynamic_cast<GeoDataPoint*>( p()->m_geometry );
        GeoDataPoint *otherPoint = dynamic_cast<GeoDataPoint*>( other.p()->m_geometry );
        Q_ASSERT( thisPoint && otherPoint );

        if ( *thisPoint != *otherPoint ) {
            return false;
        }
    }

    return true;
}
예제 #30
0
GeoDataDocument* MapQuestRunner::parse( const QByteArray &content ) const
{
    QDomDocument xml;
    if ( !xml.setContent( content ) ) {
        mDebug() << "Cannot parse xml file with routing instructions.";
        return 0;
    }

    // mDebug() << xml.toString(2);
    QDomElement root = xml.documentElement();

    GeoDataDocument* result = new GeoDataDocument();
    result->setName( "MapQuest" );
    GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
    routePlacemark->setName( "Route" );

    GeoDataLineString* routeWaypoints = new GeoDataLineString;
    QDomNodeList shapePoints = root.elementsByTagName( "shapePoints" );
    if ( shapePoints.size() == 1 ) {
        QDomNodeList geometry = shapePoints.at( 0 ).toElement().elementsByTagName( "latLng" );
        for ( int i=0; i<geometry.size(); ++i ) {
            double const lat = geometry.item( i ).namedItem( "lat" ).toElement().text().toDouble();
            double const lon = geometry.item( i ).namedItem( "lng" ).toElement().text().toDouble();
            GeoDataCoordinates const position( lon, lat, 0.0, GeoDataCoordinates::Degree );
            routeWaypoints->append( position );
        }
    }
    routePlacemark->setGeometry( routeWaypoints );

    QTime time;
    time = time.addSecs( root.elementsByTagName( "time" ).at( 0 ).toElement().text().toInt() );
    qreal length = routeWaypoints->length( EARTH_RADIUS );
    const QString name = nameString( "MQ", length, time );
    const GeoDataExtendedData data = routeData( length, time );
    routePlacemark->setExtendedData( data );
    result->setName( name );
    result->append( routePlacemark );

    QMap<int,int> mapping;
    QDomNodeList maneuvers = root.elementsByTagName( "maneuverIndexes" );
    if ( maneuvers.size() == 1 ) {
        maneuvers = maneuvers.at( 0 ).childNodes();
        for ( int i=0; i<maneuvers.size(); ++i ) {
            mapping[i] = maneuvers.at( i ).toElement().text().toInt();
            if ( mapping[i] == routeWaypoints->size() ) {
                --mapping[i];
            }
        }
    }

    QDomNodeList instructions = root.elementsByTagName( "maneuver" );
    unsigned int const lastInstruction = qMax<int>( 0, instructions.length()-1 ); // ignore the last 'Welcome to xy' instruction
    for ( unsigned int i = 0; i < lastInstruction; ++i ) {
        QDomElement node = instructions.item( i ).toElement();

        QDomNodeList maneuver = node.elementsByTagName( "turnType" );
        QDomNodeList textNodes = node.elementsByTagName( "narrative" );
        QDomNodeList points = node.elementsByTagName( "startPoint" );
        QDomNodeList streets = node.elementsByTagName( "streets" );

        Q_ASSERT( mapping.contains( i ) );
        if ( textNodes.size() == 1 && maneuver.size() == 1 && points.size() == 1 && mapping.contains( i ) ) {
            GeoDataPlacemark* instruction = new GeoDataPlacemark;
            instruction->setName( textNodes.at( 0 ).toElement().text() );

            GeoDataExtendedData extendedData;
            GeoDataData turnType;
            turnType.setName( "turnType" );
            turnType.setValue( maneuverType( maneuver.at( 0 ).toElement().text().toInt() ) );
            extendedData.addValue( turnType );
            if ( streets.size() == 1 ) {
                GeoDataData roadName;
                roadName.setName( "roadName" );
                roadName.setValue( streets.at( 0 ).toElement().text() );
                extendedData.addValue( roadName );
            }
            instruction->setExtendedData( extendedData );

            int const start = mapping[i];
            int const end = mapping.contains(i+1) ? mapping[i+1] : routeWaypoints->size()-1;
            if ( start >= 0 && start < routeWaypoints->size() && end < routeWaypoints->size() ) {
                instruction->setName( textNodes.item( 0 ).toElement().text() );
                GeoDataLineString *lineString = new GeoDataLineString;
                for ( int j=start; j<=end; ++j ) {
                    *lineString << GeoDataCoordinates( routeWaypoints->at( j ).longitude(), routeWaypoints->at( j ).latitude() );
                }

                if ( !lineString->isEmpty() ) {
                    instruction->setGeometry( lineString );
                    result->append( instruction );
                }
            }
        }
    }

    if ( routeWaypoints->size() < 1 ) {
        delete result;
        result = 0;
    }

    return result;
}