/** * Lookups location descriptions for the given objects. * @param objects * List of objects * @param result * List of results. The list may hold none, one or more entries for each * object. * @return * True, if there was no error */ bool LocationService::ReverseLookupObjects(const std::list<ObjectFileRef>& objects, std::list<ReverseLookupResult>& result) const { result.clear(); LocationIndexRef locationIndex=database->GetLocationIndex(); if (!locationIndex) { return false; } AdminRegionReverseLookupVisitor adminRegionVisitor(*database, result); for (const auto& object : objects) { std::vector<GeoCoord> coords; if (object.GetType()==refNode) { NodeRef node; if (!database->GetNodeByOffset(object.GetFileOffset(), node)) { return false; } AdminRegionReverseLookupVisitor::SearchEntry searchEntry; searchEntry.object=object; searchEntry.coords.push_back(node->GetCoords()); adminRegionVisitor.AddSearchEntry(searchEntry); } else if (object.GetType()==refArea) { AreaRef area; if (!database->GetAreaByOffset(object.GetFileOffset(), area)) { return false; } for (size_t r=0; r<area->rings.size(); r++) { if (area->rings[r].ring==Area::outerRingId) { AdminRegionReverseLookupVisitor::SearchEntry searchEntry; searchEntry.object=object; searchEntry.coords=area->rings[r].nodes; adminRegionVisitor.AddSearchEntry(searchEntry); } } } else if (object.GetType()==refWay) { WayRef way; if (!database->GetWayByOffset(object.GetFileOffset(), way)) { return false; } AdminRegionReverseLookupVisitor::SearchEntry searchEntry; searchEntry.object=object; searchEntry.coords=way->nodes; adminRegionVisitor.AddSearchEntry(searchEntry); } else { return false; } } if (!VisitAdminRegions(adminRegionVisitor)) { return false; } if (adminRegionVisitor.adminRegions.empty()) { return true; } LocationReverseLookupVisitor locationVisitor(result); for (const auto& object : objects) { locationVisitor.AddObject(object); } for (const auto& regionEntry : adminRegionVisitor.adminRegions) { if (!locationIndex->VisitAdminRegionLocations(*regionEntry.second, locationVisitor, false)) { return false; } } AddressReverseLookupVisitor addressVisitor(result); for (const auto& object : objects) { addressVisitor.AddObject(object); } for (const auto& location : locationVisitor.locations) { if (!locationIndex->VisitLocationAddresses(*location.adminRegion, *location.location, addressVisitor)) { return false; } } return true; }