Closed matkoniecz closed 5 years ago
(4) experiment with making the overpass queries faster. Maybe the rate limit on the overpass-api is dependent not on how many requests are made, but also on how expensive they are? @mmd-osm In any case, if the requests are faster, it is less painful to wait for the query quota to replenish
There could be a number of reasons why a query appears to be slow, including which server is being used (they differ in multiple ways), the complexity of the query (e.g. multiple query statements, expensive filters,..), and of course rare limiting: it’s correct that the runtime of a query has an impact on how much quota is still left for further queries.
Maybe you could come up with a top 5 list of expensive queries so we could double check them on the dev instance.
Ah, maybe I should ping @Nakaner re: https://www.fossgis.de/wiki/F%C3%B6rderantr%C3%A4ge/Dev-Overpass-2019 as this will become relevant for performance topics in the future.
Maybe you could come up with a top 5 list of expensive queries
What would be the best way to measure it? Is run time of queries a good approximation?
I also thought about script checking how much time is needed to run query N times. It would include waiting for replenishing quota. It represents well cost for StreetComplete. But I worry than running queries over and over again will mark my IP as heavy user with later queries getting more limited quota skeving stats.
Imagine a little ad-hoc java/kotlin console app (fun main() { ... }
) that calls QuestModule.questTypeRegistry
with a Mockito
-mocked (like in the tests) OverpassMapDataDao
that instead of making a real call, outputs the Overpass query to console (or writes to file) and then calls download
on each Quest in the the resulting list of Quests.
This will give us the actual overpass queries made for each quest. From there, I think it will already become quite clear which quests are candidates from the pure length of the queries.
Hmm, as it is maybe more than a few lines of code (I suspect about 50-100), this app could go into the tests/
folder while not being a test class itself.
I have recently over the past two months observed that the building levels and roof quests are not showing both in Leipzig, Hamburg and Tallinn, Estonia although I know buildings lack this tagging and have addresses tagged. SC usually returns a failure loading quests message on screen. I assume this is caused by hitting the query quota. So there is some test areas you can look at to verify your improvements.
although I know buildings lack this tagging and have addresses tagged
The building type needs to be tagged for them to show
I experienced the same issue in Berlin that I could not get any quests at all for certain areas. I ran logcat with adb logcat -s QuestDownload:*
and saw timeouts especially for the AddBusStopName and the AddPlaceName queries. After removing them from the quest selection settings, I was able to get quest markers on the map again.
Here is some example error:
07-20 19:44:37.307 21937 24886 I QuestDownload: AddBusStopName: Starting
07-20 19:45:22.331 21937 24886 I QuestDownload: ([location coordinates removed]) Finished
07-20 19:45:22.333 21937 24886 E QuestDownload: Unable to download quests
07-20 19:45:22.333 21937 24886 E QuestDownload: Unable to download quests
07-20 19:45:22.333 21937 24886 E QuestDownload: de.westnordost.osmapi.common.errors.OsmConnectionException: java.net.SocketTimeoutException: timeout
07-20 19:45:22.333 21937 24886 E QuestDownload: at de.westnordost.osmapi.OsmConnection.makeRequest(OsmConnection.java:202)
07-20 19:45:22.333 21937 24886 E QuestDownload: at de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao.get(OverpassMapDataDao.java:60)
07-20 19:45:22.333 21937 24886 E QuestDownload: at de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao.getAndHandleQuota(OverpassMapDataDao.java:84)
07-20 19:45:22.333 21937 24886 E QuestDownload: at de.westnordost.streetcomplete.data.osm.SimpleOverpassQuestType.download(SimpleOverpassQuestType.kt:23)
07-20 19:45:22.333 21937 24886 E QuestDownload: at de.westnordost.streetcomplete.data.osm.download.OsmQuestDownload.download(OsmQuestDownload.java:90)
07-20 19:45:22.333 21937 24886 E QuestDownload: at de.westnordost.streetcomplete.data.download.QuestDownload.downloadQuestTypes(QuestDownload.java:200)
07-20 19:45:22.333 21937 24886 E QuestDownload: at de.westnordost.streetcomplete.data.download.QuestDownload.download(QuestDownload.java:124)
07-20 19:45:22.333 21937 24886 E QuestDownload: at de.westnordost.streetcomplete.data.download.QuestDownloadService$ServiceHandler.handleMessage(QuestDownloadService.java:207)
07-20 19:45:22.333 21937 24886 E QuestDownload: at android.os.Handler.dispatchMessage(Handler.java:106)
07-20 19:45:22.333 21937 24886 E QuestDownload: at android.os.Looper.loop(Looper.java:193)
07-20 19:45:22.333 21937 24886 E QuestDownload: at android.os.HandlerThread.run(HandlerThread.java:65)
07-20 19:45:22.333 21937 24886 E QuestDownload: Caused by: java.net.SocketTimeoutException: timeout
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.okio.Okio$3.newTimeoutException(Okio.java:212)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.okio.AsyncTimeout.exit(AsyncTimeout.java:261)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:215)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:306)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.internal.http.Http1xStream.readResponse(Http1xStream.java:186)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:127)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:737)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:609)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:471)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:538)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:26)
07-20 19:45:22.333 21937 24886 E QuestDownload: at de.westnordost.osmapi.OsmConnection.handleResponseCode(OsmConnection.java:341)
07-20 19:45:22.333 21937 24886 E QuestDownload: at de.westnordost.osmapi.OsmConnection.makeRequest(OsmConnection.java:195)
07-20 19:45:22.333 21937 24886 E QuestDownload: ... 10 more
07-20 19:45:22.333 21937 24886 E QuestDownload: Caused by: java.net.SocketException: socket is closed
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream.read(ConscryptFileDescriptorSocket.java:551)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.okio.Okio$2.read(Okio.java:136)
07-20 19:45:22.333 21937 24886 E QuestDownload: at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
07-20 19:45:22.333 21937 24886 E QuestDownload: ... 24 more
saw timeouts especially for the AddBusStopName and the AddPlaceName queries
This should be fixed by #1472 (currently not included in the released version - see https://github.com/westnordost/StreetComplete/releases ).
Increasing the timeout may be one option. It doesn’t solve the original issue, though: why are those two queries so slow? Wasn’t the idea to post the generated overpass ql and start with some performance optimisations? The faster the query runs the less resources you use on the public instance, which again reduces chances to hit the quota.
I don’t see any overpass api server IP address in the logs, which makes it difficult to assess the log contents.
Increasing the timeout may be one option. It doesn’t solve the original issue, though
Timeout in queries was not changed. Both before and after #1472 SC was requesting queries to run for 180 seconds (by not specifying timeout explicitly but rather relying on a default). What was changed was that SC is no longer rejecting responses arriving after 45 seconds.
180 seconds default is very large, it may be worth changing it in Overpass API or specifying explicitly something smaller in StreetComplete.
Wasn’t the idea to post the generated overpass ql and start with some performance optimisations?
Script-based testing was not done (yet), but BusStopName appears over and over again in this context.
Query is defined in https://github.com/westnordost/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/localized_name/AddBusStopName.kt#L10-L16 with SC-specific syntax.
It turns into
[bbox:50.0782945473894,19.775390625,50.1205780979601,19.8193359375];(node["public_transport"="platform"]["bus"="yes"]["name"!~"."]["noname"!="yes"];node["public_transport"="platform"]["trolleybus"="yes"]["name"!~"."]["noname"!="yes"];node["public_transport"="platform"]["tram"="yes"]["name"!~"."]["noname"!="yes"];node["highway"="bus_stop"]["public_transport"!="stop_position"]["name"!~"."]["noname"!="yes"];);out meta geom 2000;
query.
More readable equivalent is
[bbox:50.0782945473894,19.775390625,50.1205780979601,19.8193359375];
(
node["public_transport"="platform"]["bus"="yes"]["name"!~"."]["noname"!="yes"];
node["public_transport"="platform"]["trolleybus"="yes"]["name"!~"."]["noname"!="yes"];
node["public_transport"="platform"]["tram"="yes"]["name"!~"."]["noname"!="yes"];
node["highway"="bus_stop"]["public_transport"!="stop_position"]["name"!~"."]["noname"!="yes"];
);
out meta geom 2000;
From things noticeable to me - it may be better to use [!"name"]
syntax (proposed in #1479).
Ok, thanks. I‘d say that the first 3 node statements could be written as one statement.
it may be better to use [!"name"] syntax
Such a change really has no impact at all, it is just syntactic sugar and both variants are identical performance wise.
Ok, thanks. I‘d say that the first 3 node statements could be written as one statement.
Thanks!
So regexp is better for performance than multiple statements ( https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL#Key.2Fvalue_matches_regular_expression_.28.7E.22key_regex.22.7E.22value_regex.22.29 )?
My proposal would be as follows. Note that I moved the [!name]
filter at the end, which should be much faster. Assumption is that a name tag is much more frequent that any public_transport node, hence I query for all the public transport nodes first and filter out those without a name later on.
[bbox:{{bbox}}];
(
node["public_transport"="platform"]["noname"!="yes"]
(if:t["bus"] == "yes" ||
t["trolleybus"] == "yes" ||
t["tram"] =="yes");
node["highway"="bus_stop"]
["public_transport"!="stop_position"]
["noname"!="yes"];
);
node._[!"name"];
out meta geom 2000;
This version takes some 864ms vs. 20s for the previous one (on lz4.overpass-api.de)
[bbox:50.0782945473894,19.775390625,50.1205780979601,19.8193359375];
(
node["public_transport"="platform"]["noname"!="yes"][!"name"](if: t["bus"] == "yes" || t["trolleybus"] == "yes" || t["tram"] == "yes");
node["highway"="bus_stop"]["public_transport"!="stop_position"][!"name"]["noname"!="yes"];
);
out meta geom 2000;
executes in about 11s, the original query did execute in about 18 seconds. Is this what you suggest, @mmd-osm ? The problem is, the queries are not written in OQL in StreetComplete, but like this:
nodes with
((public_transport = platform and (bus = yes or trolleybus = yes or tram = yes))
or
(highway = bus_stop and public_transport != stop_position))
and !name and noname != yes
which gets translated into OQL. Currently by expanding all the "or"s to the top level, making it multiple queries. So this transpiler would need to be changed to in certain circumstances prefer the if:
syntax over expanding the or
s.
@mmd-osm I missed your last post. Your example executes for me in 2 seconds for that bbox. What the heck, how is your query so different from mine? :-o
By the way, regexp would also work here:
[bbox:50.0782945473894,19.775390625,50.1205780979601,19.8193359375];
(
node["public_transport"="platform"]["noname"!="yes"]
[~"^(bus|trolleybus|tram)$"~"^yes$"];
node["highway"="bus_stop"]
["public_transport"!="stop_position"]
["noname"!="yes"];
);
node._[!"name"];
out meta geom 2000;
And also as fast. So, I see two ways to improve for StreetComplete here:
FiltersParser
to define regex in keys. Then, look through all the queries that are currently or
ed and see if they can be expressed as regexes in keys. This will be easier to do, but will not be applicable for all cases where or
is used.*TagFilterExpression
(should probably create an own class for this then) to intelligently detect:
or
blocks that can be expressed in OQL with if: <condition>
blocks (afaik: do not contain regex)and
conditions dangling at the end of top-level or
conditions at the end with syntax as seen above - node._[!"name"]["noname"!="yes"];
Not sure if above is the proper correct receipt for automatically handling this, will need to thoroughly test it.
* Though, the current FiltersParser
is written in vanilla code, without making use of any tool or library. I once said to myself that if I ever touch the FiltersParser
again, I will reimplement it by just providing the syntax in EBNF and let some library that is able to parse DSLs based on a given EBNF do the actual work. (Would need to research first though what's available)
Re 2. II: effectively, I'm forcing a different evaluation strategy by using node._[!"name"];
. This makes sense in this particular case, as name
is both a very frequent tag and also has a high cardinality. For some reason, the previous evaluation strategy used by Overpass API pulls in way too much data, making the query very expensive. I need to do some further performance tracing to see what's going on here.
I think It's quite difficult to reason about such a logic in more general terms, especially with the additional indirection introduced by the transpiler. It sounds like a good idea to test different options in more detail.
For some reason, the previous evaluation strategy used by Overpass API pulls in way too much data, making the query very expensive. I need to do some further performance tracing to see what's going on here.
But the check for the name
is also at the end at the original query.
Different filter criteria are not executed in the exact sequence given in the query, in particular they are grouped by the type of filter first. Different types are: key only, exact key value, key w/ negated value, key w/ value regex, key w/ negated value regex, key regex w/ value regex. There’s a heuristic in place which aims at cutting down the number of objects as early as possible.
So that means, that this heuristic kinda fails to do its job and thus you circumvented this in https://github.com/westnordost/StreetComplete/issues/1457#issuecomment-513541787 by forcing !name
to be evaluated last?
I created a new ticket #1514 to succeed this ticket - to keep the overview. @mmd-osm I am thankful for any input about the overpass magic you did above and how it may be applicable for general strategies to generate performant overpass query code.
The approach is similar to what you might otherwise know from SQL Hints, i.e. a way to override a database optimizer plan, which would be applied with care and on a case by case basis.
As I said, I don't know how the other queries look like, nor how the query generator works. My recommendation would be do this kind of optimization on a case by case basis by reviewing the resulting Overpass QL code, once a query has been found to be (too) slow. This may in some way subvert the idea of a code generator, but would avoid a full blown performance regression test.
From long running query there is also this monster that detects places where name is missing and can be added. I am guessing that the same performance optimizations can be applied here
[bbox:50.0359736721955,19.92919921875,50.0782945473894,19.951171875];
(
node["name"!~"."]["brand"!~"."]["noname"!="yes"]["shop"]["shop"!~"^(no|vacant)$"];
node["name"!~"."]["brand"!~"."]["noname"!="yes"]["tourism"="information"]["information"="office"];
node["name"!~"."]["brand"!~"."]["noname"!="yes"]["amenity"~"^(restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|theatre|planetarium|arts_centre|studio|events_venue|conference_centre|exhibition_centre|music_venue|townhall|prison|courthouse|embassy|police|fire_station|ranger_station|bank|bureau_de_change|money_transfer|post_office|library|marketplace|internet_cafe|community_centre|social_facility|nursing_home|childcare|retirement_home|social_centre|youth_centre|car_wash|car_rental|boat_rental|fuel|ferry_terminal|dentist|doctors|clinic|pharmacy|hospital|place_of_worship|monastery|kindergarten|school|college|university|research_institute|driving_school|dive_centre|language_school|music_school|casino|brothel|gambling|love_hotel|stripclub|animal_boarding|animal_shelter|animal_breeding|veterinary)$"];
node["name"!~"."]["brand"!~"."]["noname"!="yes"]["tourism"~"^(attraction|zoo|aquarium|theme_park|gallery|museum|hotel|guest_house|motel|hostel|alpine_hut|apartment|resort|camp_site|caravan_site)$"];
node["name"!~"."]["brand"!~"."]["noname"!="yes"]["leisure"~"^(nature_reserve|sports_centre|fitness_centre|dance|golf_course|water_park|miniature_golf|stadium|marina|bowling_alley|amusement_arcade|adult_gaming_centre|tanning_salon|horse_riding)$"];
node["name"!~"."]["brand"!~"."]["noname"!="yes"]["office"~"^(insurance|estate_agent|travel_agent)$"];
way["name"!~"."]["brand"!~"."]["noname"!="yes"]["shop"]["shop"!~"^(no|vacant)$"];
way["name"!~"."]["brand"!~"."]["noname"!="yes"]["tourism"="information"]["information"="office"];
way["name"!~"."]["brand"!~"."]["noname"!="yes"]["amenity"~"^(restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|theatre|planetarium|arts_centre|studio|events_venue|conference_centre|exhibition_centre|music_venue|townhall|prison|courthouse|embassy|police|fire_station|ranger_station|bank|bureau_de_change|money_transfer|post_office|library|marketplace|internet_cafe|community_centre|social_facility|nursing_home|childcare|retirement_home|social_centre|youth_centre|car_wash|car_rental|boat_rental|fuel|ferry_terminal|dentist|doctors|clinic|pharmacy|hospital|place_of_worship|monastery|kindergarten|school|college|university|research_institute|driving_school|dive_centre|language_school|music_school|casino|brothel|gambling|love_hotel|stripclub|animal_boarding|animal_shelter|animal_breeding|veterinary)$"];
way["name"!~"."]["brand"!~"."]["noname"!="yes"]["tourism"~"^(attraction|zoo|aquarium|theme_park|gallery|museum|hotel|guest_house|motel|hostel|alpine_hut|apartment|resort|camp_site|caravan_site)$"];
way["name"!~"."]["brand"!~"."]["noname"!="yes"]["leisure"~"^(nature_reserve|sports_centre|fitness_centre|dance|golf_course|water_park|miniature_golf|stadium|marina|bowling_alley|amusement_arcade|adult_gaming_centre|tanning_salon|horse_riding)$"];
way["name"!~"."]["brand"!~"."]["noname"!="yes"]["office"~"^(insurance|estate_agent|travel_agent)$"];
rel["name"!~"."]["brand"!~"."]["noname"!="yes"]["shop"]["shop"!~"^(no|vacant)$"];
rel["name"!~"."]["brand"!~"."]["noname"!="yes"]["tourism"="information"]["information"="office"];
rel["name"!~"."]["brand"!~"."]["noname"!="yes"]["amenity"~"^(restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|theatre|planetarium|arts_centre|studio|events_venue|conference_centre|exhibition_centre|music_venue|townhall|prison|courthouse|embassy|police|fire_station|ranger_station|bank|bureau_de_change|money_transfer|post_office|library|marketplace|internet_cafe|community_centre|social_facility|nursing_home|childcare|retirement_home|social_centre|youth_centre|car_wash|car_rental|boat_rental|fuel|ferry_terminal|dentist|doctors|clinic|pharmacy|hospital|place_of_worship|monastery|kindergarten|school|college|university|research_institute|driving_school|dive_centre|language_school|music_school|casino|brothel|gambling|love_hotel|stripclub|animal_boarding|animal_shelter|animal_breeding|veterinary)$"];
rel["name"!~"."]["brand"!~"."]["noname"!="yes"]["tourism"~"^(attraction|zoo|aquarium|theme_park|gallery|museum|hotel|guest_house|motel|hostel|alpine_hut|apartment|resort|camp_site|caravan_site)$"];
rel["name"!~"."]["brand"!~"."]["noname"!="yes"]["leisure"~"^(nature_reserve|sports_centre|fitness_centre|dance|golf_course|water_park|miniature_golf|stadium|marina|bowling_alley|amusement_arcade|adult_gaming_centre|tanning_salon|horse_riding)$"];
rel["name"!~"."]["brand"!~"."]["noname"!="yes"]["office"~"^(insurance|estate_agent|travel_agent)$"];
);
out meta geom 2000;
And some examples of queries that appear to not take excessive time, but maybe may benefit from optimization:
[bbox:50.0359736721955,19.92919921875,50.0782945473894,19.951171875];
(
node["leisure"="pitch"]["sport"!~"."]["access"!~"^(private|no)$"];
node["leisure"="pitch"]["sport"~"^(team_handball|hockey|skating|football)$"]["access"!~"^(private|no)$"];
way["leisure"="pitch"]["sport"!~"."]["access"!~"^(private|no)$"];
way["leisure"="pitch"]["sport"~"^(team_handball|hockey|skating|football)$"]["access"!~"^(private|no)$"];
);
out meta geom 2000;
[bbox:50.0359736721955,19.92919921875,50.0782945473894,19.951171875];
(
node["amenity"="recycling"]["recycling_type"!~"."];
way["amenity"="recycling"]["recycling_type"!~"."];
rel["amenity"="recycling"]["recycling_type"!~"."];
);
out meta geom 2000;
[bbox:45.7368595473605,5.82275390625,45.7675229621499,5.86669921875];
(
way["building"="yes"]["man_made"!~"."]["historic"!~"."]["military"!~"."]["power"!~"."]["location"!="underground"];
rel["building"="yes"]["man_made"!~"."]["historic"!~"."]["military"!~"."]["power"!~"."]["location"!="underground"];
);
out meta geom 2000;
[bbox:45.7368595473605,5.82275390625,45.7675229621499,5.86669921875];
(
way["route"="ferry"]["motor_vehicle"!~"."];rel["route"="ferry"]["motor_vehicle"!~"."];
);
out meta geom 2000;
[bbox:45.7368595473605,5.82275390625,45.7675229621499,5.86669921875];
(
node["amenity"="toilets"]["access"!~"^(private|customers)$"]["wheelchair"!~"."];
way["amenity"="toilets"]["access"!~"^(private|customers)$"]["wheelchair"!~"."];
);
out meta geom 2000;
[bbox:45.7368595473605,5.82275390625,45.7675229621499,5.86669921875];
(
node["amenity"="parking"]["fee"!~"."]["fee:conditional"!~"."]["access"~"^(yes|customers|public)$"];
way["amenity"="parking"]["fee"!~"."]["fee:conditional"!~"."]["access"~"^(yes|customers|public)$"];
rel["amenity"="parking"]["fee"!~"."]["fee:conditional"!~"."]["access"~"^(yes|customers|public)$"];
);
out meta geom 2000;
Re "monster" query: https://github.com/westnordost/StreetComplete/issues/1457#issuecomment-517609887
Right, I would try a similar approach as before. Besides, I'd suggest to merge those node, way, rel queries to nwr (assuming they all share the same filter criteria). That won't improve the runtime but improves readability of the query a bit:
[bbox:50.0359736721955,19.92919921875,50.0782945473894,19.951171875];
(
nwr["shop"]["shop"!~"^(no|vacant)$"];
nwr["tourism"="information"]["information"="office"];
nwr["amenity"~"^(restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|theatre|planetarium|arts_centre|studio|events_venue|conference_centre|exhibition_centre|music_venue|townhall|prison|courthouse|embassy|police|fire_station|ranger_station|bank|bureau_de_change|money_transfer|post_office|library|marketplace|internet_cafe|community_centre|social_facility|nursing_home|childcare|retirement_home|social_centre|youth_centre|car_wash|car_rental|boat_rental|fuel|ferry_terminal|dentist|doctors|clinic|pharmacy|hospital|place_of_worship|monastery|kindergarten|school|college|university|research_institute|driving_school|dive_centre|language_school|music_school|casino|brothel|gambling|love_hotel|stripclub|animal_boarding|animal_shelter|animal_breeding|veterinary)$"];
nwr["tourism"~"^(attraction|zoo|aquarium|theme_park|gallery|museum|hotel|guest_house|motel|hostel|alpine_hut|apartment|resort|camp_site|caravan_site)$"];
nwr["leisure"~"^(nature_reserve|sports_centre|fitness_centre|dance|golf_course|water_park|miniature_golf|stadium|marina|bowling_alley|amusement_arcade|adult_gaming_centre|tanning_salon|horse_riding)$"];
nwr["office"~"^(insurance|estate_agent|travel_agent)$"];
);
nwr._[!name][!"brand"]["noname"!="yes"];
out meta geom 2000;
At least in some places brand new, just installed application may scan for a long time before showing quests.
What worse sometimes overpass query runs out before any quests are found.
Note that severity highly depends on many factors
I noticed the issue in a more rural area where data density is significantly lower than in a city, especially name quests that are typically providing many objects produced nothing.
solutions (nonexclusive):
(1) maybe during startup for a new user run queries at multiple overpass servers? Both on main instance, Kumi systems, overpass.openstreetmap.fr (has limit of 1000 queries day from all users of a single app, but how many new daily users SC has), maybe also Taiwan instance?
(2) I will try moving underground building quest a bit later and add more complicated check that will allow to keep the same functionality and freely reorder this quest. It may be useful as this specific quest is extremely rare and currently near top of the list and very often querying it "wastes" a query- bad idea, housenumber quest would be horryfying (I thought about changinglocation!=undeground
tolayer!~-[0-9]+ or (location and location!=underground)
)(3) more clearly show that app is waiting for replenishing of quota, especially in case where no quests were found so far