示例#1
0
void PopupLayer::popup()
{
    GeoDataCoordinates coords = d->m_popupItem->coordinate();
    ViewportParams viewport( d->m_widget->viewport()->projection(),
                             coords.longitude(), coords.latitude(), d->m_widget->viewport()->radius(),
                             d->m_widget->viewport()->size() );
    qreal sx, sy, lon, lat;
    viewport.screenCoordinates( coords, sx, sy );
    sx = viewport.radius() < viewport.width() ? 0.5 * (viewport.width() + viewport.radius()) : 0.75 * viewport.width();
    viewport.geoCoordinates( sx, sy, lon, lat, GeoDataCoordinates::Radian );
    coords.setLatitude( lat );
    coords.setLongitude( lon );
    d->m_widget->centerOn( coords, true );
    setVisible( true );
}
示例#2
0
void WikipediaItem::setLatitude( qreal latitude )
{
    GeoDataCoordinates updatedCoordinates = coordinate();
    updatedCoordinates.setLatitude( latitude );
    setCoordinate( updatedCoordinates );
}
void GroundOverlayFrame::paint(GeoPainter *painter, const ViewportParams *viewport )
{
    m_viewport = viewport;
    m_regionList.clear();

    painter->save();
    if ( placemark()->geometry()->nodeType() == GeoDataTypes::GeoDataPolygonType ) {
        GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
        GeoDataLinearRing &ring = polygon->outerBoundary();
        QList<GeoDataCoordinates> coordinateList;

        coordinateList.append( ring.at( NorthWest ) );
        coordinateList.append( ring.at( SouthWest ) );
        coordinateList.append( ring.at( SouthEast ) );
        coordinateList.append( ring.at( NorthEast ) );

        GeoDataCoordinates northernHandle = ring.at( NorthEast ).interpolate( ring.at( NorthWest ), 0.5 );
        GeoDataCoordinates southernHandle = ring.at( SouthEast ).interpolate( ring.at( SouthWest ), 0.5 );
        // Special case handle position to take tessellation
        // along latitude circles into account
        if (m_overlay->latLonBox().rotation() == 0) {
            northernHandle.setLatitude(ring.at( NorthEast ).latitude());
            southernHandle.setLatitude(ring.at( SouthEast ).latitude());
        }
        coordinateList.append( northernHandle );
        coordinateList.append( southernHandle );

        coordinateList.append( ring.at( NorthEast ).interpolate( ring.at( SouthEast ), 0.5 ) );
        coordinateList.append( ring.at( NorthWest ).interpolate( ring.at( SouthWest ), 0.5 ) );

        m_regionList.append( painter->regionFromEllipse( coordinateList.at( NorthWest ), 16, 16 ) );
        m_regionList.append( painter->regionFromEllipse( coordinateList.at( SouthWest ), 16, 16 ) );
        m_regionList.append( painter->regionFromEllipse( coordinateList.at( SouthEast ), 16, 16 ) );
        m_regionList.append( painter->regionFromEllipse( coordinateList.at( NorthEast ), 16, 16 ) );
        m_regionList.append( painter->regionFromEllipse( coordinateList.at( North ), 16, 16 ) );
        m_regionList.append( painter->regionFromEllipse( coordinateList.at( South ), 16, 16 ) );
        m_regionList.append( painter->regionFromEllipse( coordinateList.at( East ),  16, 16 ) );
        m_regionList.append( painter->regionFromEllipse( coordinateList.at( West ),  16, 16 ) );
        m_regionList.append( painter->regionFromPolygon( ring, Qt::OddEvenFill ) );

        // Calculate handle icon orientation due to the projection
        qreal xNW, yNW, xSW, ySW;
        viewport->screenCoordinates(ring.at( NorthWest ), xNW, yNW);
        viewport->screenCoordinates(ring.at( SouthWest ), xSW, ySW);
        qreal westernAngle = qAtan2(ySW - yNW, xSW - xNW) - M_PI/2;
        qreal xNE, yNE, xSE, ySE;
        viewport->screenCoordinates(ring.at( NorthEast ), xNE, yNE);
        viewport->screenCoordinates(ring.at( SouthEast ), xSE, ySE);
        qreal easternAngle = qAtan2(ySE - yNE, xSE - xNE) - M_PI/2;

        painter->setPen( Qt::DashLine );
        painter->setBrush( Qt::NoBrush );
        painter->drawPolygon( ring );

        qreal projectedAngle = 0;

        for( int i = NorthWest; i != Polygon; ++i ) {

            // Assign handle icon orientation due to the projection
            if (i == NorthWest || i == West || i == SouthWest) {
                projectedAngle = westernAngle;
            }
            else if (i == NorthEast || i == East || i == SouthEast) {
                projectedAngle = easternAngle;
            }
            else if (i == North || i == South) {
                projectedAngle = (westernAngle + easternAngle) / 2;
            }
            QTransform trans;
            trans.rotateRadians( projectedAngle );
            if ( m_editStatus == Resize ){
                if( m_hoveredHandle != i ) {
                    painter->drawImage( coordinateList.at( i ),
                                        m_resizeIcons.at( 2*i ).transformed( trans, Qt::SmoothTransformation ) );
                } else {
                    painter->drawImage( coordinateList.at( i ),
                                        m_resizeIcons.at( 2*i + 1 ).transformed( trans, Qt::SmoothTransformation ) );
                }
            } else if ( m_editStatus == Rotate ) {
                if( m_hoveredHandle != i ) {
                    painter->drawImage( coordinateList.at( i ),
                                        m_rotateIcons.at( 2*i ).transformed( trans, Qt::SmoothTransformation ) );
                } else {
                    painter->drawImage( coordinateList.at( i ),
                                        m_rotateIcons.at( 2*i + 1 ).transformed( trans, Qt::SmoothTransformation ) );
                }
            }
        }
    }
    painter->restore();
}
示例#4
0
GeoDataDocument* OpenRouteServiceRunner::parse( const QByteArray &content ) const
{
    QDomDocument xml;
    if ( !xml.setContent( content ) ) {
        mDebug() << "Cannot parse xml file with routing instructions.";
        return nullptr;
    }

    QDomElement root = xml.documentElement();

    GeoDataDocument* result = new GeoDataDocument();
    result->setName(QStringLiteral("OpenRouteService"));

    QDomNodeList errors = root.elementsByTagName(QStringLiteral("xls:Error"));
    if ( errors.size() > 0 ) {
        return nullptr;
        // Returning early because fallback routing providers are used now
        // The code below can be used to parse OpenGis errors reported by ORS
        // and may be useful in the future

        for (int i=0 ; i < errors.length(); ++i ) {
            QDomNode node = errors.item( i );
            QString errorMessage = node.attributes().namedItem(QStringLiteral("message")).nodeValue();
            QRegExp regexp = QRegExp( "^(.*) Please Check your Position: (-?[0-9]+.[0-9]+) (-?[0-9]+.[0-9]+) !" );
            if ( regexp.indexIn( errorMessage ) == 0 ) {
                if ( regexp.capturedTexts().size() == 4 ) {
                    GeoDataPlacemark* placemark = new GeoDataPlacemark;
                    placemark->setName( regexp.capturedTexts().at( 1 ) );
                    GeoDataCoordinates position;
                    position.setLongitude( regexp.capturedTexts().at( 2 ).toDouble(), GeoDataCoordinates::Degree );
                    position.setLatitude( regexp.capturedTexts().at( 3 ).toDouble(), GeoDataCoordinates::Degree );
                    placemark->setCoordinate( position );
                    result->append( placemark );
                }
            } else {
                mDebug() << "Error message " << errorMessage << " not parsable.";
                /** @todo: How to handle this now with plugins? */
//                QString message = tr( "Sorry, a problem occurred when calculating the route. Try adjusting start and destination points." );
//                QPointer<QMessageBox> messageBox = new QMessageBox( QMessageBox::Warning, "Route Error", message );
//                messageBox->setDetailedText( errorMessage );
//                messageBox->exec();
//                delete messageBox;
            }
        }
    }

    GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
    routePlacemark->setName(QStringLiteral("Route"));
    QTime time;
    QDomNodeList summary = root.elementsByTagName(QStringLiteral("xls:RouteSummary"));
    if ( summary.size() > 0 ) {
        QDomNodeList timeNodeList = summary.item(0).toElement().elementsByTagName(QStringLiteral("xls:TotalTime"));
        if ( timeNodeList.size() == 1 ) {
            QRegExp regexp = QRegExp( "^P(?:(\\d+)D)?T(?:(\\d+)H)?(?:(\\d+)M)?(\\d+)S" );
            if ( regexp.indexIn( timeNodeList.item( 0 ).toElement().text() ) == 0 ) {
                QStringList matches = regexp.capturedTexts();
                unsigned int hours( 0 ), minutes( 0 ), seconds( 0 );
                switch ( matches.size() ) {
                case 5:
                    // days    = regexp.cap( matches.size() - 4 ).toInt();
                    // Intentionally no break
                case 4:
                    hours   = regexp.cap( matches.size() - 3 ).toInt();
                    // Intentionally no break
                case 3:
                    minutes = regexp.cap( matches.size() - 2 ).toInt();
                    // Intentionally no break
                case 2:
                    seconds = regexp.cap( matches.size() - 1 ).toInt();
                    break;
                default:
                    mDebug() << "Unable to parse time string " << timeNodeList.item( 0 ).toElement().text();
                }

                time = QTime( hours, minutes, seconds, 0 );
            }
        }
    }

    GeoDataLineString* routeWaypoints = new GeoDataLineString;
    QDomNodeList geometry = root.elementsByTagName(QStringLiteral("xls:RouteGeometry"));
    if ( geometry.size() > 0 ) {
        QDomNodeList waypoints = geometry.item( 0 ).toElement().elementsByTagName( "gml:pos" );
        for (int i=0 ; i < waypoints.length(); ++i ) {
            QDomNode node = waypoints.item( i );
            const QStringList content = node.toElement().text().split(QLatin1Char(' '));
            if ( content.length() == 2 ) {
                GeoDataCoordinates position;
                position.setLongitude( content.at( 0 ).toDouble(), GeoDataCoordinates::Degree );
                position.setLatitude( content.at( 1 ).toDouble(), GeoDataCoordinates::Degree );
                routeWaypoints->append( position );
            }
        }
    }
    routePlacemark->setGeometry( routeWaypoints );

    qreal length = routeWaypoints->length( EARTH_RADIUS );
    const QString name = nameString( "ORS", length, time );
    const GeoDataExtendedData data = routeData( length, time );
    routePlacemark->setExtendedData( data );
    result->setName( name );

    result->append( routePlacemark );

    QDomNodeList instructionList = root.elementsByTagName(QStringLiteral("xls:RouteInstructionsList"));
    if ( instructionList.size() > 0 ) {
        QDomNodeList instructions = instructionList.item(0).toElement().elementsByTagName(QStringLiteral("xls:RouteInstruction"));
        for (int i=0 ; i < instructions.length(); ++i ) {
            QDomElement node = instructions.item( i ).toElement();

            QDomNodeList textNodes = node.elementsByTagName(QStringLiteral("xls:Instruction"));
            QDomNodeList positions = node.elementsByTagName(QStringLiteral("gml:pos"));

            if ( textNodes.size() > 0 && positions.size() > 0 ) {
                const QStringList content = positions.at(0).toElement().text().split(QLatin1Char(' '));
                if ( content.length() == 2 ) {
                    GeoDataLineString *lineString = new GeoDataLineString;

                    for( int i = 0; i < positions.count(); ++i ) {
                         const QStringList pointList = positions.at(i).toElement().text().split(QLatin1Char(' '));
                         GeoDataCoordinates position;
                         position.setLongitude( pointList.at( 0 ).toDouble(), GeoDataCoordinates::Degree );
                         position.setLatitude( pointList.at( 1 ).toDouble(), GeoDataCoordinates::Degree );
                         lineString->append( position );
                    }

                    GeoDataPlacemark* instruction = new GeoDataPlacemark;

                    QString const text = textNodes.item( 0 ).toElement().text().remove(QRegExp("<[^>]*>"));
                    GeoDataExtendedData extendedData;
                    GeoDataData turnTypeData;
                    turnTypeData.setName(QStringLiteral("turnType"));
                    QString road;
                    RoutingInstruction::TurnType turnType = parseTurnType( text, &road );
                    turnTypeData.setValue( turnType );
                    extendedData.addValue( turnTypeData );
                    if ( !road.isEmpty() ) {
                        GeoDataData roadName;
                        roadName.setName(QStringLiteral("roadName"));
                        roadName.setValue( road );
                        extendedData.addValue( roadName );
                    }

                    QString const instructionText = turnType == RoutingInstruction::Unknown ? text : RoutingInstruction::generateRoadInstruction( turnType, road );
                    instruction->setName( instructionText );
                    instruction->setExtendedData( extendedData );
                    instruction->setGeometry( lineString );
                    result->append( instruction );
                }
            }
        }
    }

    return result;
}