Exemplo n.º 1
0
GeoDataLineString GeoDataLineString::toNormalized() const
{
    GeoDataLineString normalizedLineString;

    normalizedLineString.setTessellationFlags( tessellationFlags() );

    qreal lon;
    qreal lat;

    // FIXME: Think about how we can avoid unnecessary copies
    //        if the linestring stays the same.
    QVector<GeoDataCoordinates>::const_iterator end = p()->m_vector.constEnd();
    for( QVector<GeoDataCoordinates>::const_iterator itCoords
          = p()->m_vector.constBegin();
         itCoords != end;
         ++itCoords ) {

        itCoords->geoCoordinates( lon, lat );
        qreal alt = itCoords->altitude();
        GeoDataCoordinates::normalizeLonLat( lon, lat );

        GeoDataCoordinates normalizedCoords( *itCoords );
        normalizedCoords.set( lon, lat, alt );
        normalizedLineString << normalizedCoords;
    }

    return normalizedLineString;
}
Exemplo n.º 2
0
bool PolylineAnnotation::processAddingNodesOnMove( QMouseEvent *mouseEvent )
{
    Q_ASSERT( mouseEvent->button() == Qt::NoButton );

    const int index = virtualNodeContains( mouseEvent->pos() );

    // If we are adjusting a virtual node which has just been clicked and became real, just
    // change its coordinates when moving it, as we do with nodes in Editing state on move.
    if ( m_adjustedNode != -1 ) {
        // The virtual node which has just been added is always the last within
        // GeoDataLinearRing's container.qreal lon, lat;
        qreal lon, lat;
        m_viewport->geoCoordinates( mouseEvent->pos().x(),
                                    mouseEvent->pos().y(),
                                    lon, lat,
                                    GeoDataCoordinates::Radian );
        const GeoDataCoordinates newCoords( lon, lat );
        GeoDataLineString *line = static_cast<GeoDataLineString*>( placemark()->geometry() );
        line->at(m_adjustedNode) = newCoords;

        return true;

    // If we are hovering a virtual node, store its index in order to be painted in drawNodes
    // method.
    } else if ( index != -1 ) {
        m_virtualHoveredNode = index;
        return true;
    }

    return false;
}
Exemplo n.º 3
0
void PolylineAnnotation::updateRegions( GeoPainter *painter )
{
    if ( m_busy ) {
        return;
    }

    const GeoDataLineString line = static_cast<const GeoDataLineString>( *placemark()->geometry() );

    if ( state() == SceneGraphicsItem::AddingNodes ) {
        // Create and update virtual nodes lists when being in the AddingPolgonNodes state, to
        // avoid overhead in other states.
        m_virtualNodesList.clear();
        for ( int i = 0; i < line.size() - 1; ++i ) {
            const QRegion newRegion( painter->regionFromEllipse( line.at(i).interpolate( line.at(i+1), 0.5 ),
                                                                 hoveredDim, hoveredDim ) );
            m_virtualNodesList.append( PolylineNode( newRegion ) );
        }
    }


    // Update the polyline region;
    m_polylineRegion = painter->regionFromPolyline( line, 15 );

    // Update the node lists.
    for ( int i = 0; i < m_nodesList.size(); ++i ) {
        const QRegion newRegion = m_nodesList.at(i).isSelected() ?
                                  painter->regionFromEllipse( line.at(i), selectedDim, selectedDim ) :
                                  painter->regionFromEllipse( line.at(i), regularDim, regularDim );
        m_nodesList[i].setRegion( newRegion );
    }
}
Exemplo n.º 4
0
bool GeoDataLineString::operator==( const GeoDataLineString &other ) const
{
    if ( !GeoDataGeometry::equals(other) ||
          size() != other.size() ||
          tessellate() != other.tessellate() ) {
        return false;
    }

    const GeoDataLineStringPrivate* d = p();
    const GeoDataLineStringPrivate* other_d = other.p();

    QVector<GeoDataCoordinates>::const_iterator itCoords = d->m_vector.constBegin();
    QVector<GeoDataCoordinates>::const_iterator otherItCoords = other_d->m_vector.constBegin();
    QVector<GeoDataCoordinates>::const_iterator itEnd = d->m_vector.constEnd();
    QVector<GeoDataCoordinates>::const_iterator otherItEnd = other_d->m_vector.constEnd();

    for ( ; itCoords != itEnd && otherItCoords != otherItEnd; ++itCoords, ++otherItCoords ) {
        if ( *itCoords != *otherItCoords ) {
            return false;
        }
    }

    Q_ASSERT ( itCoords == itEnd && otherItCoords == otherItEnd );
    return true;
}
Exemplo n.º 5
0
void OsmWayGraphicsItem::append( const GeoDataPoint& point )
{
    GeoDataLineString* line = dynamic_cast<GeoDataLineString*>(m_placemark->geometry());
    if( line ) {
        line->append( point );
    }
}
Exemplo n.º 6
0
bool PolylineAnnotation::processAddingNodesOnPress( QMouseEvent *mouseEvent )
{
    if ( mouseEvent->button() != Qt::LeftButton ) {
        return false;
    }

    GeoDataLineString *line = static_cast<GeoDataLineString*>( placemark()->geometry() );

    // If a virtual node has just been clicked, add it to the polyline and start 'adjusting'
    // its position.
    const int virtualIndex = virtualNodeContains( mouseEvent->pos() );
    if ( virtualIndex != -1 && m_adjustedNode == -1 ) {
        Q_ASSERT( m_virtualHoveredNode == virtualIndex );

        line->insert( virtualIndex + 1, line->at( virtualIndex ).interpolate( line->at( virtualIndex + 1 ), 0.5 ) );
        m_nodesList.insert( virtualIndex + 1, PolylineNode() );

        m_adjustedNode = virtualIndex + 1;
        m_virtualHoveredNode = -1;
        return true;
    }

    // If a virtual node which has been previously clicked and selected to become a
    // 'real node' is clicked one more time, it stops from being 'adjusted'.
    const int realIndex = nodeContains( mouseEvent->pos() );
    if ( realIndex != -1 && m_adjustedNode != -1 ) {
        m_adjustedNode = -1;
        return true;
    }

    return false;
}
Exemplo n.º 7
0
void RoutingWidget::handleSearchResult( RoutingInputWidget *widget )
{
    d->setActiveInput( widget );
    MarblePlacemarkModel *model = widget->searchResultModel();

    if ( model->rowCount() ) {
        QString const results = tr( "%n placemarks found", "", model->rowCount() );
        d->m_ui.resultLabel->setText( results );
        d->m_ui.resultLabel->setVisible( true );
        // Make sure we have a selection
        activatePlacemark( model->index( 0, 0 ) );
    } else {
        QString const results = tr( "No placemark found" );
        d->m_ui.resultLabel->setText( "<font color=\"red\">" + results + "</font>" );
        d->m_ui.resultLabel->setVisible( true );
    }

    GeoDataLineString placemarks;
    for ( int i = 0; i < model->rowCount(); ++i ) {
        QVariant data = model->index( i, 0 ).data( MarblePlacemarkModel::CoordinateRole );
        if ( !data.isNull() ) {
            placemarks << qVariantValue<GeoDataCoordinates>( data );
        }
    }

    if ( placemarks.size() > 1 ) {
        d->m_widget->centerOn( GeoDataLatLonBox::fromLineString( placemarks ) );
        //d->m_ui.descriptionLabel->setVisible( false );

        if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
            d->m_ui.directionsListView->setVisible( true );
        }
    }
}
Exemplo n.º 8
0
void GeoDataPlacemark::unpack( QDataStream& stream )
{
    detach();
    p()->m_geometry->setParent( this );
    GeoDataFeature::unpack( stream );

    stream >> p()->m_countrycode;
    stream >> p()->m_area;
    stream >> p()->m_population;
    int geometryId;
    stream >> geometryId;
    switch( geometryId ) {
        case InvalidGeometryId:
            break;
        case GeoDataPointId:
            {
            GeoDataPoint* point = new GeoDataPoint;
            point->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = point;
            }
            break;
        case GeoDataLineStringId:
            {
            GeoDataLineString* lineString = new GeoDataLineString;
            lineString->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = lineString;
            }
            break;
        case GeoDataLinearRingId:
            {
            GeoDataLinearRing* linearRing = new GeoDataLinearRing;
            linearRing->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = linearRing;
            }
            break;
        case GeoDataPolygonId:
            {
            GeoDataPolygon* polygon = new GeoDataPolygon;
            polygon->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = polygon;
            }
            break;
        case GeoDataMultiGeometryId:
            {
            GeoDataMultiGeometry* multiGeometry = new GeoDataMultiGeometry;
            multiGeometry->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = multiGeometry;
            }
            break;
        case GeoDataModelId:
            break;
        default: break;
    };
}
Exemplo n.º 9
0
 qreal totalDistance() const
 {
     GeoDataLineString measure;
     GeoDataCoordinates sourcePosition(m_source.longitude(), m_source.latitude());
     GeoDataCoordinates targetPosition(m_target.longitude(), m_target.latitude());
     measure << sourcePosition << targetPosition;
     return measure.length(m_planetRadius);
 }
Exemplo n.º 10
0
void GeoDataMultiGeometry::unpack( QDataStream& stream )
{
    detach();
    GeoDataGeometry::unpack( stream );

    int size = 0;

    stream >> size;

    for( int i = 0; i < size; i++ ) {
        int geometryId;
        stream >> geometryId;
        switch( geometryId ) {
        case InvalidGeometryId:
            break;
        case GeoDataPointId:
        {
            GeoDataPoint *point = new GeoDataPoint;
            point->unpack( stream );
            p()->m_vector.append( point );
        }
        break;
        case GeoDataLineStringId:
        {
            GeoDataLineString *lineString = new GeoDataLineString;
            lineString->unpack( stream );
            p()->m_vector.append( lineString );
        }
        break;
        case GeoDataLinearRingId:
        {
            GeoDataLinearRing *linearRing = new GeoDataLinearRing;
            linearRing->unpack( stream );
            p()->m_vector.append( linearRing );
        }
        break;
        case GeoDataPolygonId:
        {
            GeoDataPolygon *polygon = new GeoDataPolygon;
            polygon->unpack( stream );
            p()->m_vector.append( polygon );
        }
        break;
        case GeoDataMultiGeometryId:
        {
            GeoDataMultiGeometry *multiGeometry = new GeoDataMultiGeometry;
            multiGeometry->unpack( stream );
            p()->m_vector.append( multiGeometry );
        }
        break;
        case GeoDataModelId:
            break;
        default:
            break;
        };
    }
}
Exemplo n.º 11
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();
    }
}
Exemplo n.º 12
0
void
AprsObject::render( GeoPainter *painter, ViewportParams *viewport,
                    int fadeTime, int hideTime )
{
    Q_UNUSED( viewport );

    if ( hideTime > 0 && m_history.last().timestamp().elapsed() > hideTime )
        return;

    QColor baseColor = calculatePaintColor( m_seenFrom,
                                      m_history.last().timestamp(),
                                      fadeTime );

    if ( m_history.count() > 1 ) {
    
        QList<GeoAprsCoordinates>::iterator spot = m_history.begin();
        QList<GeoAprsCoordinates>::iterator endSpot = m_history.end();
        
        GeoDataLineString lineString;
        lineString.setTessellate( true );
        lineString << *spot; // *spot exists because m_history.count() > 1

        for( ++spot; spot != endSpot; ++spot ) {

            if ( hideTime > 0 && ( *spot ).timestamp().elapsed() > hideTime )
                break;

            lineString << *spot;

            // draw the new circle in whatever is appropriate for that point
            const QColor penColor = calculatePaintColor( spot->seenFrom(), spot->timestamp(), fadeTime );
            painter->setPen( penColor );
            painter->drawRect( *spot, 5, 5 );
        }

        // draw the line in the base color
        painter->setPen( baseColor );
        painter->drawPolyline( lineString );
    }
    

    // Always draw the symbol then the text last so it's on top
    if ( m_havePixmap ) {
        if ( ! m_pixmap )
            m_pixmap = new QPixmap ( m_pixmapFilename );
        if ( m_pixmap && ! m_pixmap->isNull() )
            painter->drawPixmap( m_history.last(), *m_pixmap ); 
        else
            painter->drawRect( m_history.last(), 6, 6 );
    }
    else
        painter->drawRect( m_history.last(), 6, 6 );

    painter->setPen( baseColor );
    painter->drawText( m_history.last(), m_myName );
}
Exemplo n.º 13
0
void GosmoreRunnerPrivate::merge( GeoDataLineString* one, const GeoDataLineString& two )
{
    Q_ASSERT( one );

    QVector<GeoDataCoordinates>::const_iterator iter = two.constBegin();
    for( ; iter != two.constEnd(); ++iter ) {
        /** @todo: It might be needed to cut off some points at the start or end */
        one->append( *iter );
    }
}
Exemplo n.º 14
0
int RoutingModel::rightNeighbor( const GeoDataCoordinates &position, RouteRequest const *const route ) const
{
    Q_ASSERT( route && "Must not pass a null route ");

    // Quick result for trivial cases
    if ( route->size() < 3 ) {
        return route->size() - 1;
    }

    // Generate an ordered list of all waypoints
    GeoDataLineString points = d->m_route.path();
    QMap<int,int> mapping;

    // Force first mapping point to match the route start
    mapping[0] = 0;

    // Calculate the mapping between waypoints and via points
    // Need two for loops to avoid getting stuck in local minima
    for ( int j=1; j<route->size()-1; ++j ) {
        qreal minDistance = -1.0;
        for ( int i=mapping[j-1]; i<points.size(); ++i ) {
            qreal distance = distanceSphere( points[i], route->at(j) );
            if (minDistance < 0.0 || distance < minDistance ) {
                mapping[j] = i;
                minDistance = distance;
            }
        }
    }

    // Determine waypoint with minimum distance to the provided position
    qreal minWaypointDistance = -1.0;
    int waypoint=0;
    for ( int i=0; i<points.size(); ++i ) {
        qreal waypointDistance = distanceSphere( points[i], position );
        if ( minWaypointDistance < 0.0 || waypointDistance < minWaypointDistance ) {
            minWaypointDistance = waypointDistance;
            waypoint = i;
        }
    }

    // Force last mapping point to match the route destination
    mapping[route->size()-1] = points.size()-1;

    // Determine neighbor based on the mapping
    QMap<int, int>::const_iterator iter = mapping.constBegin();
    for ( ; iter != mapping.constEnd(); ++iter ) {
        if ( iter.value() > waypoint ) {
            int index = iter.key();
            Q_ASSERT( index >= 0 && index <= route->size() );
            return index;
        }
    }

    return route->size()-1;
}
Exemplo n.º 15
0
GeoDataLineString GeoDataLineString::mid(int pos, int length) const
{
    GeoDataLineString substring;
    auto d = substring.d_func();
    d->m_vector = d_func()->m_vector.mid(pos, length);
    d->m_dirtyBox = true;
    d->m_dirtyRange = true;
    d->m_tessellationFlags = d_func()->m_tessellationFlags;
    d->m_extrude = d_func()->m_extrude;
    return substring;
}
Exemplo n.º 16
0
void EditPolylineDialog::handleItemMoving( GeoDataPlacemark *item )
{
    if( item == d->m_placemark ) {
        d->m_nodeModel->clear();
        if( d->m_placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLineStringType ) {
            GeoDataLineString *lineString = static_cast<GeoDataLineString*>( d->m_placemark->geometry() );
            for( int i = 0; i < lineString->size(); ++i ) {
                d->m_nodeModel->addNode( lineString->at( i ) );
            }
        }
    }
}
Exemplo n.º 17
0
qreal YoursRunner::distance( const GeoDataDocument* document ) const
{
    QVector<GeoDataFolder*> folders = document->folderList();
    foreach( const GeoDataFolder *folder, folders ) {
        foreach( const GeoDataPlacemark *placemark, folder->placemarkList() ) {
            GeoDataGeometry* geometry = placemark->geometry();
            if ( geometry->geometryId() == GeoDataLineStringId ) {
                GeoDataLineString* lineString = dynamic_cast<GeoDataLineString*>( geometry );
                Q_ASSERT( lineString && "Internal error: geometry ID does not match class type" );
                return lineString->length( EARTH_RADIUS );
            }
        }
    }
Exemplo n.º 18
0
void GeoLink::paint(GeoPainter* painter) const {
    if (!geoPeer.isSelf() && data_model->getMainLocation(geoPeer) != GeoPeerLoc::DEFAULT) {
        painter->setPen(Qt::yellow);
        foreach (const RsPgpId& gpg_id, geoPeer.getConnectionsList()) {
            const GeoPeer& other = data_model->getPeer(gpg_id);
            if (!other.isNull() && !other.isSelf() && other.getAssociatedSSLIds().size() > 0 && data_model->getMainLocation(other) != GeoPeerLoc::DEFAULT) {
                GeoDataLineString conLine;
                conLine.append(data_model->getMainLocation(geoPeer));
                conLine.append(data_model->getMainLocation(other));
                painter->drawPolyline(conLine);
            }
        }
    }
Exemplo n.º 19
0
GeoDataLineString GosmoreRunnerPrivate::parseGosmoreOutput( const QByteArray &content )
{
    GeoDataLineString routeWaypoints;

    QStringList lines = QString::fromLocal8Bit( content ).split( '\r' );
    foreach( const QString &line, lines ) {
        QStringList fields = line.split(',');
        if (fields.size() >= 5) {
            qreal lon = fields.at(1).toDouble();
            qreal lat = fields.at(0).toDouble();
            GeoDataCoordinates coordinates( lon, lat, 0.0, GeoDataCoordinates::Degree );
            routeWaypoints.append( coordinates );
        }
    }
Exemplo n.º 20
0
void RoutingModel::exportGpx( QIODevice *device ) const
{
    QString content( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n" );
    content += "<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" creator=\"Marble\" version=\"1.1\" ";
    content += "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
    content += "xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 ";
    content += "http://www.topografix.com/GPX/1/1/gpx.xsd\">\n";
    content += "<metadata>\n  <link href=\"http://edu.kde.org/marble\">\n    ";
    content += "<text>Marble Virtual Globe</text>\n  </link>\n</metadata>\n";

    content += "  <rte>\n    <name>Route</name>\n";
    bool hasAltitude = false;
    for ( int i=0; !hasAltitude && i<d->m_route.size(); ++i ) {
        hasAltitude = d->m_route.at( i ).maneuver().position().altitude() != 0.0;
    }
    for ( int i=0; i<d->m_route.size(); ++i ) {
        const Maneuver &maneuver = d->m_route.at( i ).maneuver();
        qreal lon = maneuver.position().longitude( GeoDataCoordinates::Degree );
        qreal lat = maneuver.position().latitude( GeoDataCoordinates::Degree );
        QString const text = maneuver.instructionText();
        content += QString( "    <rtept lat=\"%1\" lon=\"%2\">\n" ).arg( lat, 0, 'f', 7 ).arg( lon, 0, 'f', 7 );
        content += QString( "        <name>%1</name>\n").arg( text );
        if ( hasAltitude ) {
            content += QString( "        <ele>%1</ele>\n" ).arg( maneuver.position().altitude(), 0, 'f', 2 );
        }
        content += QString( "    </rtept>\n" );
    }
    content += "  </rte>\n";

    content += "<trk>\n  <name>Route</name>\n    <trkseg>\n";
    GeoDataLineString points = d->m_route.path();
    hasAltitude = false;
    for ( int i=0; !hasAltitude && i<points.size(); ++i ) {
        hasAltitude = points[i].altitude() != 0.0;
    }
    for ( int i=0; i<points.size(); ++i ) {
        GeoDataCoordinates const &point = points[i];
        qreal lon = point.longitude( GeoDataCoordinates::Degree );
        qreal lat = point.latitude( GeoDataCoordinates::Degree );
        content += QString( "      <trkpt lat=\"%1\" lon=\"%2\">\n" ).arg( lat, 0, 'f', 7 ).arg( lon, 0, 'f', 7 );
        if ( hasAltitude ) {
            content += QString( "        <ele>%1</ele>\n" ).arg( point.altitude(), 0, 'f', 2 );
        }
        content += QString( "      </trkpt>\n" );
    }
    content += "    </trkseg>\n  </trk>\n";
    content += "</gpx>\n";

    device->write( content.toUtf8() );
}
Exemplo n.º 21
0
void PolylineAnnotation::deleteClickedNode()
{
    if ( state() != SceneGraphicsItem::Editing ) {
        return;
    }

    GeoDataLineString *line = static_cast<GeoDataLineString*>( placemark()->geometry() );
    if ( m_nodesList.size() <= 2 ) {
        setRequest( SceneGraphicsItem::RemovePolylineRequest );
        return;
    }

    m_nodesList.removeAt( m_clickedNodeIndex );
    line->remove( m_clickedNodeIndex );
 }
Exemplo n.º 22
0
void GeoDataLineStringPrivate::optimize (GeoDataLineString& lineString) const
{

    QVector<GeoDataCoordinates>::iterator itCoords = lineString.begin();
    QVector<GeoDataCoordinates>::const_iterator itEnd = lineString.constEnd();

    if (lineString.size() < 2) return;

    // Calculate the least non-zero detail-level by checking the bounding box
    int startLevel = levelForResolution( ( lineString.latLonAltBox().width() + lineString.latLonAltBox().height() ) / 2 );

    int currentLevel = startLevel;
    int maxLevel = startLevel;
    GeoDataCoordinates currentCoords;
    lineString.first().setDetail(startLevel);

    // Iterate through the linestring to assign different detail levels to the nodes.
    // In general the first and last node should have the start level assigned as
    // a detail level.
    // Starting from the first node the algorithm picks those nodes which
    // have a distance from each other that is just above the resolution that is
    // associated with the start level (which we use as a "current level").
    // Each of those nodes get the current level assigned as the detail level.
    // After iterating through the linestring we increment the current level value
    // and starting again with the first node we assign detail values in a similar way
    // to the remaining nodes which have no final detail level assigned yet.
    // We do as many iterations through the lineString as needed and bump up the
    // current level until all nodes have a non-zero detail level assigned.

    while ( currentLevel  < 16 && currentLevel <= maxLevel + 1 ) {
        itCoords = lineString.begin();

        currentCoords = *itCoords;
        ++itCoords;

        for( ; itCoords != itEnd; ++itCoords) {
            if (itCoords->detail() != 0 && itCoords->detail() < currentLevel) continue;

            if ( currentLevel == startLevel && (itCoords->longitude() == -M_PI || itCoords->longitude() == M_PI
                || itCoords->latitude() < -89 * DEG2RAD || itCoords->latitude() > 89 * DEG2RAD)) {
                itCoords->setDetail(startLevel);
                currentCoords = *itCoords;
                maxLevel = currentLevel;
                continue;
            }
            if (distanceSphere( currentCoords, *itCoords ) < resolutionForLevel(currentLevel + 1)) {
                itCoords->setDetail(currentLevel + 1);
            }
            else {
                itCoords->setDetail(currentLevel);
                currentCoords = *itCoords;
                maxLevel = currentLevel;
            }
        }
        ++currentLevel;
    }
    lineString.last().setDetail(startLevel);
}
Exemplo n.º 23
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;
}
Exemplo n.º 24
0
void PolylineAnnotation::setupRegionsLists( GeoPainter *painter )
{
    Q_ASSERT( state() == SceneGraphicsItem::DrawingPolyline || !m_regionsInitialized );
    const GeoDataLineString line = static_cast<const GeoDataLineString>( *placemark()->geometry() );

    // Add poyline nodes.
    QVector<GeoDataCoordinates>::ConstIterator itBegin = line.constBegin();
    QVector<GeoDataCoordinates>::ConstIterator itEnd = line.constEnd();

    m_nodesList.clear();
    for ( ; itBegin != itEnd; ++itBegin ) {
        const PolylineNode newNode = PolylineNode( painter->regionFromEllipse( *itBegin, regularDim, regularDim ) );
        m_nodesList.append( newNode );
    }

    // Add region from polyline so that events on polyline's 'lines' could be caught.
    m_polylineRegion = painter->regionFromPolyline( line, 15 );
}
Exemplo n.º 25
0
bool PolylineAnnotation::processMergingOnPress( QMouseEvent *mouseEvent )
{
    if ( mouseEvent->button() != Qt::LeftButton ) {
        return false;
    }

    GeoDataLineString line = static_cast<GeoDataLineString>( *placemark()->geometry() );

    const int index = nodeContains( mouseEvent->pos() );
    if ( index == -1 ) {
        return false;
    }

    // If this is the first node selected to be merged.
    if ( m_firstMergedNode == -1 ) {
        m_firstMergedNode = index;
        m_nodesList[index].setFlag( PolylineNode::NodeIsMerged );
   } else {
        Q_ASSERT( m_firstMergedNode != -1 );

        // Clicking two times the same node results in unmarking it for merging.
        if ( m_firstMergedNode == index ) {
            m_nodesList[index].setFlag( PolylineNode::NodeIsMerged, false );
            m_firstMergedNode = -1;
            return true;
        }

        // If these two nodes are the last ones remained as part of the polyline, remove
        // the whole polyline.
        if ( line.size() <= 2 ) {
            setRequest( SceneGraphicsItem::RemovePolylineRequest );
            return true;
        }
        m_nodesList[index].setFlag( PolylineNode::NodeIsMerged );
        m_secondMergedNode = index;

        delete m_animation;
        m_animation = new MergingPolylineNodesAnimation( this );
        setRequest( SceneGraphicsItem::StartPolylineAnimation );
    }

    return true;
}
Exemplo n.º 26
0
void RoutingModelPrivate::importPlacemark( RouteSegment &outline, QVector<RouteSegment> &segments, const GeoDataPlacemark *placemark )
{
    GeoDataGeometry* geometry = placemark->geometry();
    GeoDataLineString* lineString = dynamic_cast<GeoDataLineString*>( geometry );
    QStringList blacklist = QStringList() << "" << "Route" << "Tessellated";
    RouteSegment segment;
    bool isOutline = true;
    if ( !blacklist.contains( placemark->name() ) ) {
        if( lineString ) {
            Maneuver maneuver;
            maneuver.setInstructionText( placemark->name() );
            maneuver.setPosition( lineString->at( 0 ) );

            if ( placemark->extendedData().contains( "turnType" ) ) {
                QVariant turnType = placemark->extendedData().value( "turnType" ).value();
                // The enum value is converted to/from an int in the QVariant
                // because only a limited set of data types can be serialized with QVariant's
                // toString() method (which is used to serialize <ExtendedData>/<Data> values)
                maneuver.setDirection( Maneuver::Direction( turnType.toInt() ) );
            }

            if ( placemark->extendedData().contains( "roadName" ) ) {
                QVariant roadName = placemark->extendedData().value( "roadName" ).value();
                maneuver.setRoadName( roadName.toString() );
            }

            segment.setManeuver( maneuver );
            isOutline = false;
        }
    }

    if ( lineString ) {
        segment.setPath( *lineString );

        if ( isOutline ) {
            outline = segment;
        } else {
            segments.push_back( segment );
        }
    }
}
Exemplo n.º 27
0
void PolylineAnnotation::deleteAllSelectedNodes()
{
    if ( state() != SceneGraphicsItem::Editing ) {
        return;
    }

    GeoDataLineString *line = static_cast<GeoDataLineString*>( placemark()->geometry() );

    for ( int i = 0; i < line->size(); ++i ) {
        if ( m_nodesList.at(i).isSelected() ) {
            if ( m_nodesList.size() <= 2 ) {
                setRequest( SceneGraphicsItem::RemovePolylineRequest );
                return;
            }

            m_nodesList.removeAt( i );
            line->remove( i );
            --i;
        }
    }
}
Exemplo n.º 28
0
GeoDataLatLonAltBox GeoDataLatLonAltBox::fromLineString(  const GeoDataLineString& lineString  )
{
    // If the line string is empty return a boundingbox that contains everything
    if ( lineString.size() == 0 ) {
        return GeoDataLatLonAltBox();
    }

    const qreal altitude = lineString.first().altitude();

    GeoDataLatLonAltBox temp ( GeoDataLatLonBox::fromLineString( lineString ), altitude, altitude );

    qreal maxAltitude = altitude;
    qreal minAltitude = altitude;

    // If there's only a single node stored then the boundingbox only contains that point
    if ( lineString.size() == 1 ) {
        temp.setMinAltitude( minAltitude );
        temp.setMaxAltitude( maxAltitude );
        return temp;
    }

    QVector<GeoDataCoordinates>::ConstIterator it( lineString.constBegin() );
    QVector<GeoDataCoordinates>::ConstIterator itEnd( lineString.constEnd() );

    for ( ; it != itEnd; ++it )
    {
        // Get coordinates and normalize them to the desired range.
        const qreal altitude = (it)->altitude();

        // Determining the maximum and minimum latitude
        if ( altitude > maxAltitude ) maxAltitude = altitude;
        if ( altitude < minAltitude ) minAltitude = altitude;
    }

    temp.setMinAltitude( minAltitude );
    temp.setMaxAltitude( maxAltitude );
    return temp;
}
Exemplo n.º 29
0
void EditPolylineDialog::checkFields()
{
    bool ok = true;
    if ( d->m_name->text().isEmpty() ) {
        QMessageBox::warning( this,
                              tr( "No name specified" ),
                              tr( "Please specify a name for this polyline." ) );
        ok = false;
    } else {
        if ( d->m_placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLineStringType ) {
            GeoDataLineString *lineString = static_cast<GeoDataLineString*>( d->m_placemark->geometry() );
            if( lineString->size() < 2 ) {
                QMessageBox::warning( this,
                                      tr( "Not enough nodes specified." ),
                                      tr( "Please specify at least 2 nodes for the path by clicking on the map." ) );
                ok = false;
            }
        }
    }
    if( ok ) {
        accept();
    }
}
Exemplo n.º 30
0
GeoNode* OsmNdTagHandler::parse( GeoParser &geoParser ) const
{
    Q_ASSERT( dynamic_cast<OsmParser *>( &geoParser ) != 0 );
    OsmParser &parser = static_cast<OsmParser &>( geoParser );

    Q_ASSERT( parser.isStartElement() );

    GeoStackItem parentItem = parser.parentElement();

    if ( parentItem.represents( osmTag_way ) )
    {
        GeoDataLineString *s = parentItem.nodeAs<GeoDataLineString>();
        Q_ASSERT( s );
        quint64 id = parser.attribute( "ref" ).toULongLong();
        if ( GeoDataPoint *p = parser.node( id ) ) {
            s->append( GeoDataCoordinates( p->coordinates().longitude(), p->coordinates().latitude() ) );
        }

        return 0;
    }

    return 0;
}