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 ); }
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 ); }
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->setZoomLevel( 18 ); placemark->setVisualCategory(category); placemark->setStyle( 0 ); 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* style = new GeoDataStyle(*placemark->style()); style->setIconStyle(iconStyle); placemark->setStyle(style); } } } OsmObjectManager::registerId(m_osmData.id()); document->append(placemark); }
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; } }
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(); } }
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); }
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 ); }
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); }
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; }
void OsmNominatimRunner::handleResult( QNetworkReply* reply ) { QDomDocument xml; if (!xml.setContent(reply->readAll())) { qWarning() << "Cannot parse osm nominatim result"; qWarning() << reply->error(); returnNoResults(); return; } QVector<GeoDataPlacemark*> placemarks; QDomElement root = xml.documentElement(); QDomNodeList places = root.elementsByTagName(QStringLiteral("place")); for (int i=0; i<places.size(); ++i) { QDomNode place = places.at(i); QDomNamedNodeMap attributes = place.attributes(); QString lon = attributes.namedItem(QStringLiteral("lon")).nodeValue(); QString lat = attributes.namedItem(QStringLiteral("lat")).nodeValue(); QString desc = attributes.namedItem(QStringLiteral("display_name")).nodeValue(); QString key = attributes.namedItem(QStringLiteral("class")).nodeValue(); QString value = attributes.namedItem(QStringLiteral("type")).nodeValue(); OsmPlacemarkData data; GeoDataExtendedData placemarkData = extractChildren(place); placemarkData.addValue(GeoDataData(QStringLiteral("class"), key)); placemarkData.addValue(GeoDataData(QStringLiteral("type"), value)); QString name = place.firstChildElement(value).text(); QString road = place.firstChildElement(QStringLiteral("road")).text(); placemarkData.addValue(GeoDataData(QStringLiteral("name"), name)); QString city = place.firstChildElement(QStringLiteral("city")).text(); if( city.isEmpty() ) { city = place.firstChildElement(QStringLiteral("town")).text(); if( city.isEmpty() ) { city = place.firstChildElement(QStringLiteral("village")).text(); } if( city.isEmpty() ) { city = place.firstChildElement(QStringLiteral("hamlet")).text(); } } QString administrative = place.firstChildElement(QStringLiteral("county")).text(); if( administrative.isEmpty() ) { administrative = place.firstChildElement(QStringLiteral("region")).text(); if( administrative.isEmpty() ) { administrative = place.firstChildElement(QStringLiteral("state")).text(); data.addTag(QStringLiteral("addr:state"), administrative); } else { data.addTag(QStringLiteral("district"), administrative); } } QString country = place.firstChildElement(QStringLiteral("country")).text(); QString description; for (int i=0; i<place.childNodes().size(); ++i) { QDomElement item = place.childNodes().at(i).toElement(); description += item.nodeName() + QLatin1Char(':') + item.text() + QLatin1Char('\n'); } description += QLatin1String("Category: ") + key + QLatin1Char('/') + 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 += QLatin1String(", "); } placemarkName += road; data.addTag(QStringLiteral("addr:street"), road); } if (!city.isEmpty() && !placemarkName.contains(QLatin1Char(',')) && city != placemarkName) { if( !placemarkName.isEmpty() ) { placemarkName += QLatin1String(", "); } placemarkName += city; data.addTag(QStringLiteral("addr:city"), city); } if (!administrative.isEmpty() && !placemarkName.contains(QLatin1Char(',')) && administrative != placemarkName) { if( !placemarkName.isEmpty() ) { placemarkName += QLatin1String(", "); } placemarkName += administrative; } if (!country.isEmpty() && !placemarkName.contains(QLatin1Char(',')) && country != placemarkName) { if( !placemarkName.isEmpty() ) { placemarkName += QLatin1String(", "); } placemarkName += country; data.addTag(QStringLiteral("addr:country"), country); } if (placemarkName.isEmpty()) { placemarkName = desc; } placemark->setName( placemarkName ); placemark->setDescription(description); placemark->setAddress(desc); placemark->setCoordinate( lon.toDouble(), lat.toDouble(), 0, GeoDataCoordinates::Degree ); const auto category = StyleBuilder::determineVisualCategory(data); placemark->setVisualCategory( category ); placemark->setExtendedData(placemarkData); placemark->setOsmData(data); placemarks << placemark; } } emit searchFinished( placemarks ); }