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 ); }
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(); }
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; }