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