streetcomplete / StreetComplete

Easy to use OpenStreetMap editor for Android
https://streetcomplete.app
GNU General Public License v3.0
3.82k stars 348 forks source link

Initial quest scan may not found any quests before running out of query quota #1457

Closed matkoniecz closed 5 years ago

matkoniecz commented 5 years ago

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 changing location!=undeground to layer!~-[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

westnordost commented 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

mmd-osm commented 5 years ago

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.

mmd-osm commented 5 years ago

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.

matkoniecz commented 5 years ago

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.

westnordost commented 5 years ago

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.

claudiush commented 5 years ago

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.

westnordost commented 5 years ago

although I know buildings lack this tagging and have addresses tagged

The building type needs to be tagged for them to show

mythsunwind commented 5 years ago

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
matkoniecz commented 5 years ago

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 ).

mmd-osm commented 5 years ago

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.

matkoniecz commented 5 years ago

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).

mmd-osm commented 5 years ago

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.

matkoniecz commented 5 years ago

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 )?

mmd-osm commented 5 years ago

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)

westnordost commented 5 years ago
[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 ors.

westnordost commented 5 years ago

@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

mmd-osm commented 5 years ago

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;
westnordost commented 5 years ago

And also as fast. So, I see two ways to improve for StreetComplete here:

  1. Extend the FiltersParser to define regex in keys. Then, look through all the queries that are currently ored 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.*
  2. Extend the TQL->OQL converter in TagFilterExpression (should probably create an own class for this then) to intelligently detect:
    1. nested or blocks that can be expressed in OQL with if: <condition> blocks (afaik: do not contain regex)
    2. more importantly (because it has a bigger impact): put top-level 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)

mmd-osm commented 5 years ago

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.

westnordost commented 5 years ago

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.

mmd-osm commented 5 years ago

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.

westnordost commented 5 years ago

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?

westnordost commented 5 years ago

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.

mmd-osm commented 5 years ago

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.

matkoniecz commented 5 years ago

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;
matkoniecz commented 5 years ago

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;
mmd-osm commented 5 years ago

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;