streetcomplete / StreetComplete

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

Performance improvements: Faster Overpass queries #1514

Closed westnordost closed 4 years ago

westnordost commented 4 years ago

Some Overpass queries are very slow and clog up the download process by pitching the app in a long queue, waiting to replenish its Overpass download quota. If the queries were executed faster, the app would reach the quota later.

So:

  1. Find out which quests take long and why. First step here is to create a little program in the tests/ directory that iterates through the quest type list and outputs the compiled overpass query for each for some bbox to console. See https://github.com/westnordost/StreetComplete/issues/1457#issuecomment-509031473. The output of this program would also be interesting for @rugk who is maintaining the quests wiki page and links to the used overpass queries for each quest type. Executing each query on some location should give an idea which quest types are problematic.

  2. Implement optimizations based on these observations. In the predecessor ticket to this one, a few suggestions have already been made:

    1. make possible the usage of regex in keys in the TQL syntax and use it where applicable
    2. express nested ors in OQL with if: <condition> blocks if they don't contain regex
    3. Far the biggest impact though has some fiddling of evaluation strategies for Overpass Queries. At the moment, it is unknown what the best strategy would be here. See https://github.com/westnordost/StreetComplete/issues/1457#issuecomment-513545692 and /cc @mmd-osm
goldfndr commented 4 years ago

Something that might conceivably help (if not already planned) is to output the resource usage (e.g. System time) for the queries. I don't know of a method in Overpass Turbo to output these data, or if they're even remotely available. The transactions.log includes the PID but I don't know if it includes other metrics.

westnordost commented 4 years ago
Quest Type Response time for a bbox of central Hamburg
AddRoadName 6s
AddPlaceName 45s
AddOneway
AddBusStopName 114s
AddIsBuildingUnderground 2s
AddHousenumber 6s
MarkCompletedHighwayConstruction 7s
AddReligionToPlaceOfWorship 7s
AddParkingAccess 6s
AddRecyclingType 12s
AddSport 5s
AddRoadSurface 1s
AddMaxSpeed 2s
AddMaxHeight 1s
AddRailwayCrossingBarrier 2s
AddPostboxCollectionTimes 1s
AddOpeningHours 14s
AddBikeParkingCapacity 0s
AddOrchardProduce 3s
AddCycleway 41s
AddSidewalk 57s
AddProhibitedForPedestrians 43s
AddCrossingType 1s
AddBuildingLevels 3s
AddBusStopShelter 3s
AddVegetarian 4s
AddVegan 2s
AddInternetAccess 3s
AddParkingFee 3s
AddMotorcycleParkingCapacity 5s
AddPathSurface 4s
AddTracktype 3s
AddBikeParkingType 1s
AddWheelChairAccessToilets 2s
AddPlaygroundAccess 1s
AddWheelchairAccessBusiness 7s
AddToiletAvailability 7s
AddFerryAccessPedestrian 3s
AddFerryAccessMotorVehicle 2s
AddBuildingType 2s
AddWayLit 6s
AddToiletsFee 6s
AddBabyChangingTable 4s
AddBikeParkingCover 3s
AddTrafficSignalsSound 2s
AddRoofShape 4s
AddWheelChairAccessPublicTransport 3s
AddWheelchairAccessOutside 2s
AddTactilePavingBusStop 3s
AddTactilePavingCrosswalk 2s
AddBridgeStructure 0s
AddReligionToWaysideShrine 1s
AddCyclewaySegregation 2s
MarkCompletedBuildingConstruction 1s
AddMotorcycleParkingCover 1s
AddFireHydrantType 1s
AddParkingType 0s
AddPowerPolesMaterial 0s
AddCarWashType 1s
AddBenchBackrest 1s
AddTrafficSignalsButton 1s

Note: The times somewhat vary, even if using the same bbox to download. So this list is only good for a very rough categorization of what is expensive and what not.

westnordost commented 4 years ago

Current queries

AddRoadName

[bbox:{{bbox}}];
way[highway~"^(primary|secondary|tertiary|unclassified|residential|living_street|pedestrian)$"][!name][!ref][noname != yes][!junction][area != yes];
 out meta geom 2000;
[bbox:{{bbox}}];
way[highway~"^(primary|secondary|tertiary|unclassified|residential|living_street|pedestrian)$"][!name][!ref][noname != yes][!junction][area != yes] -> .without_names;
way[highway~"^(primary|secondary|tertiary|unclassified|residential|living_street|pedestrian)$"][name] -> .with_names;
way.with_names(around.without_names:30.0);
out body geom;

AddPlaceName

[bbox:{{bbox}}];
(
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;

AddOneway

AddBusStopName

[bbox:{{bbox}}];
(
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;

AddIsBuildingUnderground

[bbox:{{bbox}}];
(
way["building"]["location"!~"."]["layer"~"^(-[0-9]+)$"];
rel["building"]["location"!~"."]["layer"~"^(-[0-9]+)$"];
);
out meta geom 2000;

AddHousenumber

(  way['building'~'^(house|residential|apartments|detached|terrace|dormitory|semi|semidetached_house|farm|school|civic|college|university|public|hospital|kindergarten|train_station|hotel|retail|commercial)$'][location!=underground][!'addr:housenumber'][!'addr:housename'][!'addr:conscriptionnumber'][!'addr:streetnumber'][!noaddress]({{bbox}});
  rel['building'~'^(house|residential|apartments|detached|terrace|dormitory|semi|semidetached_house|farm|school|civic|college|university|public|hospital|kindergarten|train_station|hotel|retail|commercial)$'][location!=underground][!'addr:housenumber'][!'addr:housename'][!'addr:conscriptionnumber'][!'addr:streetnumber'][!noaddress]({{bbox}});
) -> .buildings;
.buildings > -> .building_nodes;
node.building_nodes[~'^addr:(housenumber|housename|conscriptionnumber|streetnumber)$'~'.'];
< -> .buildings_with_addr_nodes;
(
.buildings;
 - .buildings_with_addr_nodes;
);
out meta geom;

MarkCompletedHighwayConstruction

[bbox:{{bbox}}];
way[highway=construction](if:!is_date(t['opening_date']) || date(t['opening_date'])<date('2019-08-02T00:00:00Z')) -> .construction_with_unknown_state;
 (way[highway=construction](newer: '2019-07-19T00:00:00Z');
relation[highway=construction](newer: '2019-07-19T00:00:00Z');
) -> .recently_edited_construction;
(
.construction_with_unknown_state;
 - .recently_edited_construction;
) -> .roads_for_review;
.roads_for_review out meta geom 2000;

AddReligionToPlaceOfWorship

[bbox:{{bbox}}];
(
node["amenity"="place_of_worship"]["religion"!~"."]["name"];
way["amenity"="place_of_worship"]["religion"!~"."]["name"];
rel["amenity"="place_of_worship"]["religion"!~"."]["name"];
);
out meta geom 2000;

AddParkingAccess

[bbox:{{bbox}}];
(
node["amenity"="parking"]["access"!~"."];
node["amenity"="parking"]["access"="unknown"];
way["amenity"="parking"]["access"!~"."];
way["amenity"="parking"]["access"="unknown"];
rel["amenity"="parking"]["access"!~"."];
rel["amenity"="parking"]["access"="unknown"];
);
out meta geom 2000;

AddRecyclingType

[bbox:{{bbox}}];
(
node["amenity"="recycling"]["recycling_type"!~"."];
way["amenity"="recycling"]["recycling_type"!~"."];
rel["amenity"="recycling"]["recycling_type"!~"."];
);
out meta geom 2000;

AddSport

[bbox:{{bbox}}];
(
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;

AddRoadSurface

[bbox:{{bbox}}];
(
way["highway"~"^(primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential|living_street|pedestrian|track|road)$"]["surface"!~"."]["access"!~"^(private|no)$"];
way["highway"~"^(primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential|living_street|pedestrian|track|road)$"]["surface"!~"."]["foot"]["foot"!~"^(private|no)$"];
);
out meta geom 2000;

AddMaxSpeed

[bbox:{{bbox}}];
(
way["highway"~"^(motorway|trunk|primary|secondary|tertiary|unclassified|residential)$"]["maxspeed"!~"."]["maxspeed:forward"!~"."]["maxspeed:backward"!~"."]["source:maxspeed"!~"."]["zone:maxspeed"!~"."]["maxspeed:type"!~"."]["zone:traffic"!~"."]["surface"!~"^(unpaved|compacted|gravel|fine_gravel|pebblestone|grass_paver|ground|earth|dirt|grass|sand|mud|ice|salt|snow|woodchips)$"]["motor_vehicle"!~"^(private|no)$"]["vehicle"!~"^(private|no)$"]["access"!~"^(private|no)$"]["area"!="yes"];
way["highway"~"^(motorway|trunk|primary|secondary|tertiary|unclassified|residential)$"]["maxspeed"!~"."]["maxspeed:forward"!~"."]["maxspeed:backward"!~"."]["source:maxspeed"!~"."]["zone:maxspeed"!~"."]["maxspeed:type"!~"."]["zone:traffic"!~"."]["surface"!~"^(unpaved|compacted|gravel|fine_gravel|pebblestone|grass_paver|ground|earth|dirt|grass|sand|mud|ice|salt|snow|woodchips)$"]["motor_vehicle"!~"^(private|no)$"]["vehicle"!~"^(private|no)$"]["foot"]["foot"!~"^(private|no)$"]["area"!="yes"];
);
out meta geom 2000;

AddMaxHeight

[bbox:{{bbox}}];
(
(node["barrier"="height_restrictor"]["maxheight"!~"."]["maxheight:physical"!~"."];
node["amenity"="parking_entrance"]["parking"~"^(underground|multi-storey)$"]["maxheight"!~"."]["maxheight:physical"!~"."];
);
(
way["highway"~"^(motorway|motorway_link|trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential|living_street|track|road)$"]["covered"="yes"]["maxheight"!~"."]["maxheight:physical"!~"."];
way["highway"~"^(motorway|motorway_link|trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential|living_street|track|road)$"]["tunnel"~"^(yes|building_passage|avalanche_protector)$"]["maxheight"!~"."]["maxheight:physical"!~"."];
way["highway"="service"]["access"!~"^(private|no)$"]["vehicle"!~"^(private|no)$"]["covered"="yes"]["maxheight"!~"."]["maxheight:physical"!~"."];
way["highway"="service"]["access"!~"^(private|no)$"]["vehicle"!~"^(private|no)$"]["tunnel"~"^(yes|building_passage|avalanche_protector)$"]["maxheight"!~"."]["maxheight:physical"!~"."];
);
);
out meta geom 2000;

AddRailwayCrossingBarrier

[bbox:{{bbox}}];

        way["highway"]["access"~"^private|no$"];
 node(w) -> .private_roads;

        way["railway"~"^tram|abandoned$"];
 node(w) -> .excluded_railways;

        node["railway"="level_crossing"][!"crossing:barrier"];

        (._;
 - .private_roads;
 );

        (._;
 - .excluded_railways;
 );
out meta geom 2000;

AddPostboxCollectionTimes

[bbox:{{bbox}}];
node["amenity"="post_box"]["collection_times"!~"."]["collection_times:signed"!="no"]["access"!~"^(private|no)$"];
out meta geom 2000;

AddOpeningHours

[bbox:{{bbox}}];
(
node["shop"]["shop"!~"^(no|vacant)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
node["amenity"="bicycle_parking"]["bicycle_parking"="building"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
node["amenity"="parking"]["parking"="multi-storey"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
node["amenity"="recycling"]["recycling_type"="centre"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
node["tourism"="information"]["information"="office"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
node["amenity"~"^(restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|planetarium|casino|library|townhall|courthouse|embassy|community_centre|youth_centre|bank|bureau_de_change|money_transfer|post_office|marketplace|internet_cafe|car_wash|car_rental|boat_rental|fuel|dentist|doctors|clinic|pharmacy|veterinary)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
node["tourism"~"^(zoo|aquarium|theme_park|gallery|museum)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
node["leisure"~"^(fitness_centre|dance|golf_course|water_park|miniature_golf|bowling_alley|horse_riding|amusement_arcade|adult_gaming_centre|tanning_salon)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
node["office"~"^(insurance|government|estate_agent|travel_agent|religion)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
way["shop"]["shop"!~"^(no|vacant)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
way["amenity"="bicycle_parking"]["bicycle_parking"="building"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
way["amenity"="parking"]["parking"="multi-storey"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
way["amenity"="recycling"]["recycling_type"="centre"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
way["tourism"="information"]["information"="office"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
way["amenity"~"^(restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|planetarium|casino|library|townhall|courthouse|embassy|community_centre|youth_centre|bank|bureau_de_change|money_transfer|post_office|marketplace|internet_cafe|car_wash|car_rental|boat_rental|fuel|dentist|doctors|clinic|pharmacy|veterinary)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
way["tourism"~"^(zoo|aquarium|theme_park|gallery|museum)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
way["leisure"~"^(fitness_centre|dance|golf_course|water_park|miniature_golf|bowling_alley|horse_riding|amusement_arcade|adult_gaming_centre|tanning_salon)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
way["office"~"^(insurance|government|estate_agent|travel_agent|religion)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
rel["shop"]["shop"!~"^(no|vacant)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
rel["amenity"="bicycle_parking"]["bicycle_parking"="building"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
rel["amenity"="parking"]["parking"="multi-storey"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
rel["amenity"="recycling"]["recycling_type"="centre"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
rel["tourism"="information"]["information"="office"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
rel["amenity"~"^(restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|planetarium|casino|library|townhall|courthouse|embassy|community_centre|youth_centre|bank|bureau_de_change|money_transfer|post_office|marketplace|internet_cafe|car_wash|car_rental|boat_rental|fuel|dentist|doctors|clinic|pharmacy|veterinary)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
rel["tourism"~"^(zoo|aquarium|theme_park|gallery|museum)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
rel["leisure"~"^(fitness_centre|dance|golf_course|water_park|miniature_golf|bowling_alley|horse_riding|amusement_arcade|adult_gaming_centre|tanning_salon)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
rel["office"~"^(insurance|government|estate_agent|travel_agent|religion)$"]["opening_hours"!~"."]["name"]["opening_hours:signed"!="no"]["access"!~"^(private|no)$"];
);
out meta geom 2000;

AddBikeParkingCapacity

[bbox:{{bbox}}];
(
node["amenity"="bicycle_parking"]["capacity"!~"."]["access"!~"^(private|no)$"];
way["amenity"="bicycle_parking"]["capacity"!~"."]["access"!~"^(private|no)$"];
);
out meta geom 2000;

AddOrchardProduce

[bbox:{{bbox}}];
(
way["landuse"="orchard"]["trees"!~"."]["produce"!~"."]["crop"!~"."];
rel["landuse"="orchard"]["trees"!~"."]["produce"!~"."]["crop"!~"."];
);
out meta geom 2000;

AddCycleway

[bbox:{{bbox}}];
way[highway ~ "^(primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"][area != yes][motorroad != yes][!cycleway][!"cycleway:left"][!"cycleway:right"][!"cycleway:both"][!"sidewalk:bicycle"][!"sidewalk:both:bicycle"][!"sidewalk:left:bicycle"][!"sidewalk:right:bicycle"][maxspeed !~ "^(20|15|10|8|7|6|5|10 mph|5 mph|walk)$"][surface !~ "^(unpaved|compacted|gravel|fine_gravel|pebblestone|grass_paver|ground|earth|dirt|grass|sand|mud|ice|salt|snow|woodchips)$"][bicycle != no][access !~ "^private|no$"][bicycle != use_sidepath]["bicycle:backward" != use_sidepath]["bicycle:forward" != use_sidepath] -> .streets;
(
way[highway=cycleway](around.streets: 15);
way[highway ~ "^(path|footway)$"](around.streets: 15);
) -> .cycleways;
way.streets(around.cycleways: 15) -> .streets_near_cycleways;
(
.streets;
 - .streets_near_cycleways;
);
out meta geom 2000;

AddSidewalk

[bbox:{{bbox}}];
way[highway ~ "^(primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential)$"][area != yes][motorroad != yes][!sidewalk][!"sidewalk:left"][!"sidewalk:right"][!"sidewalk:both"][maxspeed !~ "^(8|7|6|5|5 mph|walk)$"][surface !~ "^(unpaved|compacted|gravel|fine_gravel|pebblestone|grass_paver|ground|earth|dirt|grass|sand|mud|ice|salt|snow|woodchips)$"][lit = yes][foot != no][access !~ "^private|no$"][foot != use_sidepath] -> .streets;
way[highway ~ "^(path|footway|cycleway)$"](around.streets: 15) -> .ways;
way.streets(around.ways: 15) -> .streets_near_ways;
(
.streets;
 - .streets_near_ways;
);
out meta geom 2000;

AddProhibitedForPedestrians

[bbox:{{bbox}}];
(
way["foot"!~"."]["sidewalk"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["oneway"~"^(yes|-1)$"];
way["foot"!~"."]["sidewalk"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["bridge"="yes"];
way["foot"!~"."]["sidewalk"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["tunnel"="yes"];
way["foot"!~"."]["sidewalk"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["bicycle"~"^(no|use_sidepath)$"];
way["foot"!~"."]["sidewalk"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["lit"="yes"];
way["foot"!~"."]["sidewalk:both"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["oneway"~"^(yes|-1)$"];
way["foot"!~"."]["sidewalk:both"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["bridge"="yes"];
way["foot"!~"."]["sidewalk:both"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["tunnel"="yes"];
way["foot"!~"."]["sidewalk:both"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["bicycle"~"^(no|use_sidepath)$"];
way["foot"!~"."]["sidewalk:both"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["lit"="yes"];
way["foot"!~"."]["sidewalk:left"~"^(none|no)$"]["sidewalk:right"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["oneway"~"^(yes|-1)$"];
way["foot"!~"."]["sidewalk:left"~"^(none|no)$"]["sidewalk:right"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["bridge"="yes"];
way["foot"!~"."]["sidewalk:left"~"^(none|no)$"]["sidewalk:right"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["tunnel"="yes"];
way["foot"!~"."]["sidewalk:left"~"^(none|no)$"]["sidewalk:right"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["bicycle"~"^(no|use_sidepath)$"];
way["foot"!~"."]["sidewalk:left"~"^(none|no)$"]["sidewalk:right"~"^(none|no)$"]["access"!~"^(private|no)$"]["motorroad"!="yes"]["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"]["lit"="yes"];
);
out meta geom 2000;

AddCrossingType

[bbox:{{bbox}}];
node["highway"="crossing"]["crossing"!~"."];
out meta geom 2000;

AddBuildingLevels

[bbox:{{bbox}}];
(
way["building"~"^(house|residential|apartments|detached|terrace|dormitory|semi|semidetached_house|bungalow|school|civic|college|university|public|hospital|kindergarten|transportation|train_station|hotel|retail|commercial|office|warehouse|industrial|manufacture|parking|farm|farm_auxiliary|barn|cabin)$"]["building:levels"!~"."]["height"!~"."]["building:height"!~"."]["man_made"!~"."]["location"!="underground"];
rel["building"~"^(house|residential|apartments|detached|terrace|dormitory|semi|semidetached_house|bungalow|school|civic|college|university|public|hospital|kindergarten|transportation|train_station|hotel|retail|commercial|office|warehouse|industrial|manufacture|parking|farm|farm_auxiliary|barn|cabin)$"]["building:levels"!~"."]["height"!~"."]["building:height"!~"."]["man_made"!~"."]["location"!="underground"];
);
out meta geom 2000;

AddBusStopShelter

[bbox:{{bbox}}];
(
node["public_transport"="platform"]["bus"="yes"]["shelter"!~"."]["covered"!~"."];
node["public_transport"="platform"]["trolleybus"="yes"]["shelter"!~"."]["covered"!~"."];
node["public_transport"="platform"]["tram"="yes"]["shelter"!~"."]["covered"!~"."];
node["highway"="bus_stop"]["public_transport"!="stop_position"]["shelter"!~"."]["covered"!~"."];
);
out meta geom 2000;

AddVegetarian

[bbox:{{bbox}}];
(
node["amenity"~"^(restaurant|cafe|fast_food)$"]["name"]["diet:vegetarian"!~"."];
way["amenity"~"^(restaurant|cafe|fast_food)$"]["name"]["diet:vegetarian"!~"."];
);
out meta geom 2000;

AddVegan

[bbox:{{bbox}}];
(
node["amenity"~"^(restaurant|cafe|fast_food)$"]["name"]["diet:vegetarian"~"^(yes|only)$"]["diet:vegan"!~"."];
way["amenity"~"^(restaurant|cafe|fast_food)$"]["name"]["diet:vegetarian"~"^(yes|only)$"]["diet:vegan"!~"."];
);
out meta geom 2000;

AddInternetAccess

[bbox:{{bbox}}];
(
node["amenity"="library"]["internet_access"!~"."]["wifi"!~"."]["name"];
node["tourism"~"^(hotel|guest_house|hostel|motel)$"]["internet_access"!~"."]["wifi"!~"."]["name"];
way["amenity"="library"]["internet_access"!~"."]["wifi"!~"."]["name"];
way["tourism"~"^(hotel|guest_house|hostel|motel)$"]["internet_access"!~"."]["wifi"!~"."]["name"];
rel["amenity"="library"]["internet_access"!~"."]["wifi"!~"."]["name"];
rel["tourism"~"^(hotel|guest_house|hostel|motel)$"]["internet_access"!~"."]["wifi"!~"."]["name"];
);
out meta geom 2000;

AddParkingFee

[bbox:{{bbox}}];
(
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;

AddMotorcycleParkingCapacity

[bbox:{{bbox}}];
(
node["amenity"="motorcycle_parking"]["capacity"!~"."]["access"!~"^(private|no)$"];
way["amenity"="motorcycle_parking"]["capacity"!~"."]["access"!~"^(private|no)$"];
);
out meta geom 2000;

AddPathSurface

[bbox:{{bbox}}];
way["highway"~"^(path|footway|cycleway|bridleway|steps)$"]["surface"!~"."]["access"!~"^(private|no)$"];
out meta geom 2000;

AddTracktype

[bbox:{{bbox}}];
(
way["highway"="track"]["tracktype"!~"."]["access"!~"^(private|no)$"];
way["highway"="track"]["tracktype"!~"."]["foot"]["foot"!~"^(private|no)$"];
);
out meta geom 2000;

AddBikeParkingType

[bbox:{{bbox}}];
(
node["amenity"="bicycle_parking"]["access"!="private"]["bicycle_parking"!~"."];
way["amenity"="bicycle_parking"]["access"!="private"]["bicycle_parking"!~"."];
);
out meta geom 2000;

AddWheelChairAccessToilets

[bbox:{{bbox}}];
(
node["amenity"="toilets"]["access"!~"^(private|customers)$"]["wheelchair"!~"."];
way["amenity"="toilets"]["access"!~"^(private|customers)$"]["wheelchair"!~"."];
);
out meta geom 2000;

AddPlaygroundAccess

[bbox:{{bbox}}];
(
node["leisure"="playground"]["access"!~"."];
node["leisure"="playground"]["access"="unknown"];
way["leisure"="playground"]["access"!~"."];
way["leisure"="playground"]["access"="unknown"];
rel["leisure"="playground"]["access"!~"."];
rel["leisure"="playground"]["access"="unknown"];
);
out meta geom 2000;

AddWheelchairAccessBusiness

[bbox:{{bbox}}];
(
node["shop"]["shop"!~"^(no|vacant)$"]["wheelchair"!~"."]["name"];
node["amenity"="parking"]["parking"="multi-storey"]["wheelchair"!~"."]["name"];
node["amenity"="recycling"]["recycling_type"="centre"]["wheelchair"!~"."]["name"];
node["tourism"="information"]["information"="office"]["wheelchair"!~"."]["name"];
node["amenity"~"^(restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|library|theatre|arts_centre|casino|conference_centre|bank|bureau_de_change|money_transfer|post_office|internet_cafe|marketplace|police|ranger_station|courthouse|embassy|townhall|community_centre|youth_centre|car_wash|car_rental|fuel|driving_school|doctors|clinic|pharmacy|veterinary|dentist|place_of_worship)$"]["wheelchair"!~"."]["name"];
node["tourism"~"^(zoo|aquarium|theme_park|gallery|attraction|viewpoint|museum|hotel|guest_house|hostel|motel|apartment|chalet)$"]["wheelchair"!~"."]["name"];
node["leisure"~"^(golf_course|water_park|miniature_golf|dance|bowling_alley|horse_riding|sports_centre|fitness_centre|amusement_arcade|adult_gaming_centre|tanning_salon)$"]["wheelchair"!~"."]["name"];
node["office"~"^(insurance|government|lawyer|estate_agent|political_party|travel_agent|tax_advisor|therapist|religion)$"]["wheelchair"!~"."]["name"];
way["shop"]["shop"!~"^(no|vacant)$"]["wheelchair"!~"."]["name"];
way["amenity"="parking"]["parking"="multi-storey"]["wheelchair"!~"."]["name"];
way["amenity"="recycling"]["recycling_type"="centre"]["wheelchair"!~"."]["name"];
way["tourism"="information"]["information"="office"]["wheelchair"!~"."]["name"];
way["amenity"~"^(restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|library|theatre|arts_centre|casino|conference_centre|bank|bureau_de_change|money_transfer|post_office|internet_cafe|marketplace|police|ranger_station|courthouse|embassy|townhall|community_centre|youth_centre|car_wash|car_rental|fuel|driving_school|doctors|clinic|pharmacy|veterinary|dentist|place_of_worship)$"]["wheelchair"!~"."]["name"];
way["tourism"~"^(zoo|aquarium|theme_park|gallery|attraction|viewpoint|museum|hotel|guest_house|hostel|motel|apartment|chalet)$"]["wheelchair"!~"."]["name"];
way["leisure"~"^(golf_course|water_park|miniature_golf|dance|bowling_alley|horse_riding|sports_centre|fitness_centre|amusement_arcade|adult_gaming_centre|tanning_salon)$"]["wheelchair"!~"."]["name"];
way["office"~"^(insurance|government|lawyer|estate_agent|political_party|travel_agent|tax_advisor|therapist|religion)$"]["wheelchair"!~"."]["name"];
rel["shop"]["shop"!~"^(no|vacant)$"]["wheelchair"!~"."]["name"];
rel["amenity"="parking"]["parking"="multi-storey"]["wheelchair"!~"."]["name"];
rel["amenity"="recycling"]["recycling_type"="centre"]["wheelchair"!~"."]["name"];
rel["tourism"="information"]["information"="office"]["wheelchair"!~"."]["name"];
rel["amenity"~"^(restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|library|theatre|arts_centre|casino|conference_centre|bank|bureau_de_change|money_transfer|post_office|internet_cafe|marketplace|police|ranger_station|courthouse|embassy|townhall|community_centre|youth_centre|car_wash|car_rental|fuel|driving_school|doctors|clinic|pharmacy|veterinary|dentist|place_of_worship)$"]["wheelchair"!~"."]["name"];
rel["tourism"~"^(zoo|aquarium|theme_park|gallery|attraction|viewpoint|museum|hotel|guest_house|hostel|motel|apartment|chalet)$"]["wheelchair"!~"."]["name"];
rel["leisure"~"^(golf_course|water_park|miniature_golf|dance|bowling_alley|horse_riding|sports_centre|fitness_centre|amusement_arcade|adult_gaming_centre|tanning_salon)$"]["wheelchair"!~"."]["name"];
rel["office"~"^(insurance|government|lawyer|estate_agent|political_party|travel_agent|tax_advisor|therapist|religion)$"]["wheelchair"!~"."]["name"];
);
out meta geom 2000;

AddToiletAvailability

[bbox:{{bbox}}];
(
node["shop"~"^(mall|department_store)$"]["name"]["toilets"!~"."];
node["highway"~"^(services|rest_area)$"]["toilets"!~"."];
way["shop"~"^(mall|department_store)$"]["name"]["toilets"!~"."];
way["highway"~"^(services|rest_area)$"]["toilets"!~"."];
);
out meta geom 2000;

AddFerryAccessPedestrian

[bbox:{{bbox}}];
(
way["route"="ferry"]["foot"!~"."];
rel["route"="ferry"]["foot"!~"."];
);
out meta geom 2000;

AddFerryAccessMotorVehicle

[bbox:{{bbox}}];
(
way["route"="ferry"]["motor_vehicle"!~"."];
rel["route"="ferry"]["motor_vehicle"!~"."];
);
out meta geom 2000;

AddBuildingType

[bbox:{{bbox}}];
(
way["building"="yes"]["man_made"!~"."]["historic"!~"."]["military"!~"."]["power"!~"."]["location"!="underground"];
rel["building"="yes"]["man_made"!~"."]["historic"!~"."]["military"!~"."]["power"!~"."]["location"!="underground"];
);
out meta geom 2000;

AddWayLit

[bbox:{{bbox}}];
(
way["highway"~"^(residential|living_street|pedestrian)$"]["lit"!~"."]["access"!~"^(private|no)$"];
way["highway"~"^(residential|living_street|pedestrian)$"]["lit"!~"."]["foot"]["foot"!~"^(private|no)$"];
way["highway"~"^(primary|secondary|tertiary|unclassified|service)$"]["sidewalk"~"^(both|left|right|yes|separate)$"]["lit"!~"."]["access"!~"^(private|no)$"];
way["highway"~"^(primary|secondary|tertiary|unclassified|service)$"]["sidewalk"~"^(both|left|right|yes|separate)$"]["lit"!~"."]["foot"]["foot"!~"^(private|no)$"];
way["highway"~"^(primary|secondary|tertiary|unclassified|service)$"]["source:maxspeed"~"^(.+:urban)$"]["lit"!~"."]["access"!~"^(private|no)$"];
way["highway"~"^(primary|secondary|tertiary|unclassified|service)$"]["source:maxspeed"~"^(.+:urban)$"]["lit"!~"."]["foot"]["foot"!~"^(private|no)$"];
way["highway"~"^(primary|secondary|tertiary|unclassified|service)$"]["maxspeed:type"~"^(.+:urban)$"]["lit"!~"."]["access"!~"^(private|no)$"];
way["highway"~"^(primary|secondary|tertiary|unclassified|service)$"]["maxspeed:type"~"^(.+:urban)$"]["lit"!~"."]["foot"]["foot"!~"^(private|no)$"];
way["highway"~"^(primary|secondary|tertiary|unclassified|service)$"]["zone:maxspeed"~"^(.+:urban)$"]["lit"!~"."]["access"!~"^(private|no)$"];
way["highway"~"^(primary|secondary|tertiary|unclassified|service)$"]["zone:maxspeed"~"^(.+:urban)$"]["lit"!~"."]["foot"]["foot"!~"^(private|no)$"];
way["highway"~"^(primary|secondary|tertiary|unclassified|service)$"]["zone:traffic"~"^(.+:urban)$"]["lit"!~"."]["access"!~"^(private|no)$"];
way["highway"~"^(primary|secondary|tertiary|unclassified|service)$"]["zone:traffic"~"^(.+:urban)$"]["lit"!~"."]["foot"]["foot"!~"^(private|no)$"];
way["highway"~"^(footway|cycleway|steps)$"]["lit"!~"."]["access"!~"^(private|no)$"];
way["highway"~"^(footway|cycleway|steps)$"]["lit"!~"."]["foot"]["foot"!~"^(private|no)$"];
way["highway"="path"]["foot"="designated"]["lit"!~"."]["access"!~"^(private|no)$"];
way["highway"="path"]["foot"="designated"]["lit"!~"."]["foot"]["foot"!~"^(private|no)$"];
way["highway"="path"]["bicycle"="designated"]["lit"!~"."]["access"!~"^(private|no)$"];
way["highway"="path"]["bicycle"="designated"]["lit"!~"."]["foot"]["foot"!~"^(private|no)$"];
);
out meta geom 2000;

AddToiletsFee

[bbox:{{bbox}}];
(
node["amenity"="toilets"]["access"!~"^(private|customers)$"]["fee"!~"."];
way["amenity"="toilets"]["access"!~"^(private|customers)$"]["fee"!~"."];
);
out meta geom 2000;

AddBabyChangingTable

[bbox:{{bbox}}];
(
node["amenity"~"^(restaurant|cafe|fuel|fast_food)$"]["name"]["toilets"="yes"]["diaper"!~"."]["changing_table"!~"."];
node["shop"~"^(mall|department_store)$"]["name"]["toilets"="yes"]["diaper"!~"."]["changing_table"!~"."];
node["amenity"="toilets"]["diaper"!~"."]["changing_table"!~"."];
way["amenity"~"^(restaurant|cafe|fuel|fast_food)$"]["name"]["toilets"="yes"]["diaper"!~"."]["changing_table"!~"."];
way["shop"~"^(mall|department_store)$"]["name"]["toilets"="yes"]["diaper"!~"."]["changing_table"!~"."];
way["amenity"="toilets"]["diaper"!~"."]["changing_table"!~"."];
);
out meta geom 2000;

AddBikeParkingCover

[bbox:{{bbox}}];
(
node["amenity"="bicycle_parking"]["access"!~"^(private|no)$"]["covered"!~"."]["bicycle_parking"!~"^(shed|lockers|building)$"];
way["amenity"="bicycle_parking"]["access"!~"^(private|no)$"]["covered"!~"."]["bicycle_parking"!~"^(shed|lockers|building)$"];
);
out meta geom 2000;

AddTrafficSignalsSound

[bbox:{{bbox}}];
node["highway"="crossing"]["crossing"="traffic_signals"]["traffic_signals:sound"!~"."];
out meta geom 2000;

AddRoofShape

[bbox:{{bbox}}];
(
way["roof:levels"]["roof:levels"!="0"]["roof:shape"!~"."]["3dr:type"!~"."]["3dr:roof"!~"."];
rel["roof:levels"]["roof:levels"!="0"]["roof:shape"!~"."]["3dr:type"!~"."]["3dr:roof"!~"."];
);
out meta geom 2000;

AddWheelChairAccessPublicTransport

[bbox:{{bbox}}];
(
node["amenity"="bus_station"]["wheelchair"!~"."];
node["railway"~"^(station|subway_entrance)$"]["wheelchair"!~"."];
way["amenity"="bus_station"]["wheelchair"!~"."];
way["railway"~"^(station|subway_entrance)$"]["wheelchair"!~"."];
rel["amenity"="bus_station"]["wheelchair"!~"."];
rel["railway"~"^(station|subway_entrance)$"]["wheelchair"!~"."];
);
out meta geom 2000;

AddWheelchairAccessOutside

[bbox:{{bbox}}];
(
node["leisure"="dog_park"]["wheelchair"!~"."];
way["leisure"="dog_park"]["wheelchair"!~"."];
rel["leisure"="dog_park"]["wheelchair"!~"."];
);
out meta geom 2000;

AddTactilePavingBusStop

[bbox:{{bbox}}];
(
node["public_transport"="platform"]["tactile_paving"!~"."];
node["highway"="bus_stop"]["public_transport"!="stop_position"]["tactile_paving"!~"."];
way["public_transport"="platform"]["tactile_paving"!~"."];
way["highway"="bus_stop"]["public_transport"!="stop_position"]["tactile_paving"!~"."];
);
out meta geom 2000;

AddTactilePavingCrosswalk

[bbox:{{bbox}}];
node["highway"="crossing"]["tactile_paving"!~"."]["foot"!="no"];
out meta geom 2000;

AddBridgeStructure

[bbox:{{bbox}}];
way["man_made"="bridge"]["bridge:structure"!~"."];
out meta geom 2000;

AddReligionToWaysideShrine

[bbox:{{bbox}}];
(
node["historic"="wayside_shrine"]["religion"!~"."]["access"!~"^(private|no)$"];
way["historic"="wayside_shrine"]["religion"!~"."]["access"!~"^(private|no)$"];
rel["historic"="wayside_shrine"]["religion"!~"."]["access"!~"^(private|no)$"];
);
out meta geom 2000;

AddCyclewaySegregation

[bbox:{{bbox}}];
(
way["highway"="path"]["bicycle"="designated"]["foot"="designated"]["segregated"!~"."]["area"!="yes"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"];
way["highway"="footway"]["bicycle"="designated"]["segregated"!~"."]["area"!="yes"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"];
way["highway"="cycleway"]["foot"~"^(designated|yes)$"]["segregated"!~"."]["area"!="yes"]["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"];
);
out meta geom 2000;

MarkCompletedBuildingConstruction

[bbox:{{bbox}}];
way[building=construction](if:!is_date(t['opening_date']) || date(t['opening_date'])<date('2019-08-02T00:00:00Z')) -> .construction_with_unknown_state;
 (way[building=construction](newer: '2019-02-03T00:00:00Z');
relation[building=construction](newer: '2019-02-03T00:00:00Z');
) -> .recently_edited_construction;
(
.construction_with_unknown_state;
 - .recently_edited_construction;
) -> .buildings_under_construction_ways;
relation[building=construction](if:!is_date(t['opening_date']) || date(t['opening_date'])<date('2019-08-02T00:00:00Z')) -> .construction_with_unknown_state;
 (way[building=construction](newer: '2019-02-03T00:00:00Z');
relation[building=construction](newer: '2019-02-03T00:00:00Z');
) -> .recently_edited_construction;
(
.construction_with_unknown_state;
 - .recently_edited_construction;
) -> .buildings_under_construction_relations;
(
.buildings_under_construction_ways;
 .buildings_under_construction_relations;
);
 out meta geom 2000;

AddMotorcycleParkingCover

[bbox:{{bbox}}];
(
node["amenity"="motorcycle_parking"]["access"!~"^(private|no)$"]["covered"!~"."]["motorcycle_parking"!~"^(shed|garage_boxes|building)$"];
way["amenity"="motorcycle_parking"]["access"!~"^(private|no)$"]["covered"!~"."]["motorcycle_parking"!~"^(shed|garage_boxes|building)$"];
);
out meta geom 2000;

AddFireHydrantType

[bbox:{{bbox}}];
node["emergency"="fire_hydrant"]["fire_hydrant:type"!~"."];
out meta geom 2000;

AddParkingType

[bbox:{{bbox}}];
(
node["amenity"="parking"]["parking"!~"."];
way["amenity"="parking"]["parking"!~"."];
rel["amenity"="parking"]["parking"!~"."];
);
out meta geom 2000;

AddPowerPolesMaterial

[bbox:{{bbox}}];
node["power"="pole"]["material"!~"."];
out meta geom 2000;

AddCarWashType

[bbox:{{bbox}}];
(
node["amenity"="car_wash"]["automated"!~"."]["self_service"!~"."];
way["amenity"="car_wash"]["automated"!~"."]["self_service"!~"."];
);
out meta geom 2000;

AddBenchBackrest

[bbox:{{bbox}}];
node["amenity"="bench"]["backrest"!~"."];
out meta geom 2000;

AddTrafficSignalsButton

[bbox:{{bbox}}];
node["highway"="crossing"]["crossing"="traffic_signals"]["button_operated"!~"."];
out meta geom 2000;
mmd-osm commented 4 years ago

Wow, thanks a lot, that's a lot to go through. I will update this comment over time:

AddBusStopName

See https://github.com/westnordost/StreetComplete/issues/1457#issuecomment-513540882

AddPlaceName

Use nwr instead of node/way/relation, move name check at the end.

https://github.com/westnordost/StreetComplete/issues/1457#issuecomment-517664263

[bbox:{{bbox}}];
(
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)$"];
)->.set;

nwr.set[!name][!brand]["noname"!="yes"];

out meta geom 2000;

AddProhibitedForPedestrians

I'm using two intermediate inputsets for this one, also adding regular expressions for keys.

[bbox:{{bbox}}];
(

way[!"foot"]
    ["motorroad"!="yes"]
    ["access"!~"^(private|no)$"]
    [~"^sidewalk(:both|:left|:right)?$"~"^(none|no)$"]   // regular expression for keys
    ["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]
    ["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"];)->.w1;

(
  way.w1[~"^sidewalk(:both)?$"~"^(none|no)$"];
  way.w1["sidewalk:left"~"^(none|no)$"]["sidewalk:right"~"^(none|no)$"];   // both tags need to be present
)->.w2;  
(
  way.w2["oneway"~"^(yes|-1)$"];
  way.w2["bridge"="yes"];
  way.w2["tunnel"="yes"];
  way.w2["bicycle"~"^(no|use_sidepath)$"];
  way.w2["lit"="yes"];
);  
out meta geom 2000;

AddCycleway and AddSidewalk

Depends on optimization in https://github.com/drolbr/Overpass-API/pull/167

goldfndr commented 4 years ago

@mmd-osm For the AddProhibitedForPedestrians query, I'm surprised you included surface after highway rather than before. I'd've guessed that highway matching would dominate over surface -- doing spot checks, highway is a combination for sidewalk~(none|no) 99.97% of the time. (sidewalk:(both|left|right) has about 3000 instances total.) But I admittedly didn't check highway=residential and more minor roads (or, for that matter, any values), which are excluded from the query.

I'd expect the following to be a better first part, although admittedly it's not as friendly.

[bbox:{{bbox}}];
(
    way[!"foot"]
    ["motorroad"!="yes"]
    [~"^sidewalk(:both|:left|:right)?$"~"^(none|no)$"]   // regular expression for keys
    ["surface"~"^(paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone)$"];
    ["access"!~"^(private|no)$"]
    ["highway"~"^(trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$"]
)->.w1;

@westnordost Additionally, after looking at the AddMaxHeight query, perhaps the way.w2["tunnel"="yes"]; line should be changed to way.w2["tunnel"~"^(yes|building_passage|avalanche_protector)$"]; ? (I wasn't sure if building passages had sidewalks very often, but I'd expect many avalanche protectors to have them.)

westnordost commented 4 years ago

New version

No performance gain, but for better readability:

Performance gain:

Remaining heavy queries

Quest type Response time
AddPlaceName 28s
AddBusStopName 16s
AddOpeningHours 25s
AddCycleway 59s
AddSidewalk 66s
AddProhibitedForPedestrians 39s

Many more at 4-8s. If all can be optimized with the same method, will also boost performance of the queries.

AddPlaceName

[bbox:{{bbox}}];
(
nwr[!name][!brand][noname != yes][shop][shop !~ '^no|vacant$'];
nwr[!name][!brand][noname != yes][tourism = information][information = office];
nwr[!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$'];
nwr[!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$'];
nwr[!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$'];
nwr[!name][!brand][noname != yes][office ~ '^insurance|estate_agent|travel_agent$'];
);
out meta geom 2000;

AddBusStopName

[bbox:{{bbox}}];
(
node[public_transport = platform][~'^bus|trolleybus|tram$' ~ '^yes$'][!name][noname != yes];
node[highway = bus_stop][public_transport != stop_position][!name][noname != yes];
);
out meta geom 2000;

AddOpeningHours

[bbox:{{bbox}}];
(
nwr[shop][shop !~ '^no|vacant$'][!opening_hours][name]['opening_hours:signed' != no][access !~ '^private|no$'];
nwr[amenity = bicycle_parking][bicycle_parking = building][!opening_hours][name]['opening_hours:signed' != no][access !~ '^private|no$'];
nwr[amenity = parking][parking = 'multi-storey'][!opening_hours][name]['opening_hours:signed' != no][access !~ '^private|no$'];
nwr[amenity = recycling][recycling_type = centre][!opening_hours][name]['opening_hours:signed' != no][access !~ '^private|no$'];
nwr[tourism = information][information = office][!opening_hours][name]['opening_hours:signed' != no][access !~ '^private|no$'];
nwr[amenity ~ '^restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|planetarium|casino|library|townhall|courthouse|embassy|community_centre|youth_centre|bank|bureau_de_change|money_transfer|post_office|marketplace|internet_cafe|car_wash|car_rental|boat_rental|fuel|dentist|doctors|clinic|pharmacy|veterinary$'][!opening_hours][name]['opening_hours:signed' != no][access !~ '^private|no$'];
nwr[tourism ~ '^zoo|aquarium|theme_park|gallery|museum$'][!opening_hours][name]['opening_hours:signed' != no][access !~ '^private|no$'];
nwr[leisure ~ '^fitness_centre|dance|golf_course|water_park|miniature_golf|bowling_alley|horse_riding|amusement_arcade|adult_gaming_centre|tanning_salon$'][!opening_hours][name]['opening_hours:signed' != no][access !~ '^private|no$'];
nwr[office ~ '^insurance|government|estate_agent|travel_agent|religion$'][!opening_hours][name]['opening_hours:signed' != no][access !~ '^private|no$'];
);
out meta geom 2000;

AddCycleway

[bbox:{{bbox}}];
way[highway ~ '^(primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$'][area != yes][motorroad != yes][!cycleway][!'cycleway:left'][!'cycleway:right'][!'cycleway:both'][!'sidewalk:bicycle'][!'sidewalk:both:bicycle'][!'sidewalk:left:bicycle'][!'sidewalk:right:bicycle'][maxspeed !~ '^(20|15|10|8|7|6|5|10 mph|5 mph|walk)$'][surface !~ '^(unpaved|compacted|gravel|fine_gravel|pebblestone|grass_paver|ground|earth|dirt|grass|sand|mud|ice|salt|snow|woodchips)$'][bicycle != no][access !~ '^private|no$'][bicycle != use_sidepath]['bicycle:backward' != use_sidepath]['bicycle:forward' != use_sidepath] -> .streets;
(
way[highway=cycleway](around.streets: 15);
way[highway ~ '^(path|footway)$'](around.streets: 15);
) -> .cycleways;
way.streets(around.cycleways: 15) -> .streets_near_cycleways;
(
.streets;
 - .streets_near_cycleways;
);
out meta geom 2000;

AddSidewalk

[bbox:{{bbox}}];
way[highway ~ '^(primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential)$'][area != yes][motorroad != yes][!sidewalk][!'sidewalk:left'][!'sidewalk:right'][!'sidewalk:both'][maxspeed !~ '^(8|7|6|5|5 mph|walk)$'][surface !~ '^(unpaved|compacted|gravel|fine_gravel|pebblestone|grass_paver|ground|earth|dirt|grass|sand|mud|ice|salt|snow|woodchips)$'][lit = yes][foot != no][access !~ '^private|no$'][foot != use_sidepath] -> .streets;
way[highway ~ '^(path|footway|cycleway)$'](around.streets: 15) -> .ways;
way.streets(around.ways: 15) -> .streets_near_ways;
(
.streets;
 - .streets_near_ways;
);
out meta geom 2000;

AddProhibitedForPedestrians

[bbox:{{bbox}}];
(
way[!foot][~'^sidewalk(:both)?$' ~ '^none|no$'][access !~ '^private|no$'][motorroad != yes][highway ~ '^trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified$'][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'][oneway ~ '^yes|-1$'];
way[!foot][~'^sidewalk(:both)?$' ~ '^none|no$'][access !~ '^private|no$'][motorroad != yes][highway ~ '^trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified$'][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'][bridge = yes];
way[!foot][~'^sidewalk(:both)?$' ~ '^none|no$'][access !~ '^private|no$'][motorroad != yes][highway ~ '^trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified$'][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'][tunnel = yes];
way[!foot][~'^sidewalk(:both)?$' ~ '^none|no$'][access !~ '^private|no$'][motorroad != yes][highway ~ '^trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified$'][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'][bicycle ~ '^no|use_sidepath$'];
way[!foot][~'^sidewalk(:both)?$' ~ '^none|no$'][access !~ '^private|no$'][motorroad != yes][highway ~ '^trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified$'][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'][lit = yes];
way[!foot]['sidewalk:left' ~ '^none|no$']['sidewalk:right' ~ '^none|no$'][access !~ '^private|no$'][motorroad != yes][highway ~ '^trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified$'][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'][oneway ~ '^yes|-1$'];
way[!foot]['sidewalk:left' ~ '^none|no$']['sidewalk:right' ~ '^none|no$'][access !~ '^private|no$'][motorroad != yes][highway ~ '^trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified$'][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'][bridge = yes];
way[!foot]['sidewalk:left' ~ '^none|no$']['sidewalk:right' ~ '^none|no$'][access !~ '^private|no$'][motorroad != yes][highway ~ '^trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified$'][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'][tunnel = yes];
way[!foot]['sidewalk:left' ~ '^none|no$']['sidewalk:right' ~ '^none|no$'][access !~ '^private|no$'][motorroad != yes][highway ~ '^trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified$'][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'][bicycle ~ '^no|use_sidepath$'];
way[!foot]['sidewalk:left' ~ '^none|no$']['sidewalk:right' ~ '^none|no$'][access !~ '^private|no$'][motorroad != yes][highway ~ '^trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified$'][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'][lit = yes];
);
out meta geom 2000;
westnordost commented 4 years ago

@mmd-osm Regarding putting the name later: You said in https://github.com/westnordost/StreetComplete/issues/1457#issuecomment-513574779

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.

If the heuristic is there to cut down the number of objects as early as possible, why does it not work in the cases mentioned above? Is it because the grouping by filter type comes first and only then within these groups, the filters are sorted by that heuristic?

If I understand correctly, this query would not be very optimized because it pulls in first all elements with no name, even though pulling in only elements with superspecialkey would be the better strategy.

way[superspecialkey ~ "right|okay"][!name];

Did I understand this correctly? If yes, isn't this then a topic that should better be handled upstream (at Overpass)?

mmd-osm commented 4 years ago

Is it because the grouping by filter type comes first and only then within these groups, the filters are sorted by that heuristic?

No, what I meant by the heuristic is a certain sequence in which those different groups are being evaluated. Although a bit dated and somewhat high level, Roland gave a presentation at FOSSGIS2013 on how the evaluation works, starting on slide 23: https://www.fossgis.de/konferenz/2013/programm/attachments/428_workshop.odp / https://www.fossgis.de/konferenz/2013/programm/events/520.de.html

Some of the filters take size of the bounding box into account, or switch evaluation strategy on the fly, if one approach produces too much data during evaluation. I'm not aware of a concise description on all the details (and there are many more, which I didn't mention yet), except for the source code.

If I understand correctly, this query would not be very optimized because it pulls in first all elements with no name, even though pulling in only elements with superspecialkey would be the better strategy.

The major issue here is that there's no statistical information available on local or even global tag distribution and frequency, i.e. it is not known up front that superspecialkey is quite rare, and name is very frequent.

By forcing a different evaluation sequence, I'm bringing in my own knowledge about tag frequency - which should be fairly universal in case of a name tag. On the other hand, this makes it hard to generalize this optimization approach, as you would need to keep some statistical information around to decide if this is worthwhile or even counterproductive.

westnordost commented 4 years ago

The major issue here is that there's no statistical information available on local or even global tag distribution and frequency, i.e. it is not known up front that superspecialkey is quite rare, and name is very frequent.

But that could be done, in the future, right? A server-local taginfo of the like. After all, the data is all already there and overpass itself has the best means to acquire this data (quickly).

rugk commented 4 years ago

Uhm, did I miss something or how did you extract the compiled overpass queries now? In the OP you stated:

First step here is to create a little program in the tests/ directory that iterates through the quest type list and outputs the compiled overpass query for each for some bbox to console.

โ€ฆ but then you just came up with the results (out of nowhere). I also checked the tests dir and could not find anythingโ€ฆ :thinking:

westnordost commented 4 years ago

I wrote it, but did not commit it yet, work in progress. If you intend to copy&paste the queries to the wiki page, better wait until I am through with the optimizations. Minus imports, it is less than 30 lines of code.

westnordost commented 4 years ago

@mmd-osm : I took your proposed query for AddPlaceName and turned it around - first nwr[!name][!brand]["noname"!="yes"] -> .set; and then the rest. It turned out that the runtime of that query is still in the same dimension as your proposal. So, maybe the heuristic isn't the problem after all, but that the whole query pulls in the mountain of data not once (as in your proposal) but 6 times (as it is currently) - in other words, the ors being expanded is the problem.

Maybe I can write a transpiler that automatically converts a boolean expression like this:

addr:housenumber or (((shop and opening_hours) or amenity) and name)

into an efficient overpass query. This is the way the queries are defined in StreetComplete.

Current situation

Currently, a boolean expression like this is expanded (=ausmultipliziert) before conversion, so that the ors are all at top level. So the above query becomes

(
  node['addr:housenumber'];
  node[shop][opening_hours][name];
  node[amenity][name];
);

This works, but experienced especially for deeper nested expressions, it is not so efficient.

Solution

With the intersection operator, it is perhaps possible to convert expressions into overpass syntax without having to expand it. So, I am looking for automatically appliable rules. ands on leaf-level and ors one level above are already no problem. For example.. (shop and opening_hours) or amenity already converts fine to ( node[shop][opening_hours]; node[amenity]; );. The hard part is to find rules for how to handle ands on higher levels, that is, ands that contain nested ors.

So, for and chains which are not at leaf-level (= contain ored sub-expressions), the following rules could be used:

(X or Y) and Z

The boolean expression mentioned at the beginning could be expressed like this:

(
  node['addr:housenumber'];
  (
    node[shop][opening_hours];
    node[amenity];
  ) -> .n1;
  node.n1[name];
);

Z and (X or Y)

An expression like this

addr:housenumber or (name and ((shop and opening_hours) or amenity))

could look like this:

(
  node['addr:housenumber'];
  node[name] -> .n1;
  (
    node.n1[shop][opening_hours];
    node.n1[amenity];
  );
);

(X or Y) and (A or B)

An expression like this

addr:housenumber or ((name or noname) and ((shop and opening_hours) or amenity))

could look like this:

(
  node['addr:housenumber'];
  (
    node[shop][opening_hours];
    node[amenity];
  ) -> .n1;
  (
    node.n1[name];
    node.n1[noname];
  );
);

Rules

So, rules are:

@mmd-osm Does sind sound right?

mmd-osm commented 4 years ago

You have to be careful with union statements: Z and (X or Y) will not work in your example, as node[name] -> .n1; is also included in the result. Inside a union statement, every single statement's result is also added to final union result, regardless of the inputset it is assigned to (here: .n1).

[bbox:{{bbox}}];

(
  node[name] -> .n1;
  (
    node.n1[shop][opening_hours];
    node.n1[amenity];
  );
);
node._[!shop][!opening_hours][!amenity];
out;

-> query shows some results!

westnordost commented 4 years ago

Oh, thank you for that remark! Too bad though. So, the only way to solve this is to pull out all the things that should not work on the default input set out of the union statement and to the top of the statement.

This makes it more difficult because I can not simply recurse through the expression.

mmd-osm commented 4 years ago

Right, maybe this isn't too bad by using different inputsets to store intermediate resutls:

[bbox:{{bbox}}];

node['addr:housenumber']->.res1;

node[name] -> .n1;
(
  node.n1[shop][opening_hours];
  node.n1[amenity];
) -> .res2;

(.res1; .res2;);

out;

or maybe better:

node['addr:housenumber']->.res1;
(
  node[shop][opening_hours];
  node[amenity];
)->.n1;  
node.n1[name] -> .res2;
(.res1; .res2;);
out;
mmd-osm commented 4 years ago

I took your proposed query for AddPlaceName and turned it around - first nwr[!name][!brand]["noname"!="yes"] -> .set; and then the rest. It turned out that the runtime of that query is still in the same dimension as your proposal

I don't think this is a good idea, as you need much more memory this way to store all objects which don't fulfill those properties. By applying the name filter towards the end (as in my example), we already have a fairly small number of objects.

I'd recommend to add a few out count; or (.n1 out count;) here and there for testing, to see how large intermediate results are:

[bbox:{{bbox}}];
nwr[!name][!brand]["noname"!="yes"];
out count;
westnordost commented 4 years ago

Re myself @westnordost : This means though, that any and-expression deeply nested in the whole boolean expression always works on the full data set instead of whatever is left after other filters reduced the result.

westnordost commented 4 years ago

It's quite a brain teaser to find an algorithm to convert any boolean expression to overpass syntax. Though I may have cracked it now. Here is a teaser of an automatically generated query:

AddBusStopName

Tag Filters ``` nodes with ((public_transport = platform and ~bus|trolleybus|tram ~ yes) or (highway = bus_stop and public_transport != stop_position)) and !name and noname != yes ```
[bbox:{{bbox}}];
node[!name][noname != yes] -> .n1;
node.n1[public_transport = platform][~'^bus|trolleybus|tram$' ~ '^yes$'] -> .n2;
node.n1[highway = bus_stop][public_transport != stop_position] -> .n3;
(.n2; .n3;) -> .n1;
out meta geom;
mmd-osm commented 4 years ago

Both queries look surprisingly similar ๐Ÿ˜Ž

A quick comment,though: You really need to double check if moving the second line (producing .n1) towards the end helps avoiding excessive memory consumption, see https://github.com/westnordost/StreetComplete/issues/1514#issuecomment-517916909

Example:

[bbox:50.04559282551578,19.9237060546875,50.070472406781924,19.967780113220215];
node[!name][noname != yes] -> .n1;
node.n1[public_transport = platform][~'^bus|trolleybus|tram$' ~ '^yes$'] -> .n2;
node.n1[highway = bus_stop][public_transport != stop_position] -> .n3;
.n1 out count;
.n2 out count;
.n3 out count;

.n1 has 172850 nodes in this case... this will not really fly. node[!name][noname != yes] is a very weak filter, and will include almost all nodes in a bounding box, even all those nodes that don't have any tags at all(!). The idea should be to move weak filters to the end, when the strong filters already removed most of the data.

vs:

[bbox:50.04559282551578,19.9237060546875,50.070472406781924,19.967780113220215];

(node[public_transport = platform][~'^bus|trolleybus|tram$' ~ '^yes$'];
 node[highway = bus_stop][public_transport != stop_position];
 )->.n2;
node.n2[!name][noname != yes] -> .n1;
.n1 out count;
.n2 out count;
westnordost commented 4 years ago

@mmd-osm Okay, two things.

  1. Is it possible to query only elements that have any tags? That would be another angle how to increase query performance by reducing the number of elements as the first thing in the generated query. (The algorithm could be: If the first tag filter is not by-key or by-key-value, put a "has any tags" in front)

  2. Actually, I am really not sure about that the second query is better. I tried out both variants on large areas and the number of seconds it takes for overpass to reply is always longer for the second variant. For example 5s vs 7s. I know the response time is a very rough measure, maybe you have access to more precise ones? My attempt to explain why the first may actually be more performant:

    1. From my experience, performance-wise, it is always the CPU that is the bottleneck, not the RAM. Historically, available RAM size grew much faster than CPU speed. If a query pulls in more data, it is not bad per se, as long as the CPU has less to do. The areas being queried by StreetComplete are also rather small (about as big as small towns)
    2. Let's say there are 100k elements. !name is a cheap operation, but only removes few elements from the input set. While a merge plus regex are expensive operations. Now, it looks like it is faster to apply the cheap operation on the full 100k elements in order to apply the expensive operations on a few less elements than the other way round. I think that makes sense. In the query above, it is a regex in a merge. Thus, there are two statements that work (partly expensively) on the full input set, as opposed to only one statement that cuts the input set down a bit already.
mmd-osm commented 4 years ago

Is it possible to query only elements that have any tags?

Yes, that's possible, although we need to check what it means from a performance pov. ((if:count_tags() > 0)).

I tried out both variants on large areas and the number of seconds it takes for overpass to reply is always longer for the second variant. For example 5s vs 7s

My results are pretty much the oppositie, both in memory consumption and CPU consumption. Can you share the exact bbox and server instance you were using for testing? When testing on the public instances, keep an eye on CPU utilization (https://lz4.overpass-api.de/munin/localdomain/localhost.localdomain/cpu.html), as high CPU utilization heavily skews your measurements. Also, always try several measurements, and discard outliers (slowest and fastest ones).

I'm testing this both on lz4.overpass-api.de and the dev instance. On the dev instance (that's on my branch), I'm getting:

!name at the end: 208ms

[bbox:50.04559282551578,19.9237060546875,50.070472406781924,19.967780113220215];
(node[public_transport = platform][~'^bus|trolleybus|tram$' ~ '^yes$'];
 node[highway = bus_stop][public_transport != stop_position];
 )->.n1;
node.n1[!name][noname != yes];
out meta geom;

!name first: 270ms

[bbox:50.04559282551578,19.9237060546875,50.070472406781924,19.967780113220215];
node[!name][noname != yes] -> .n1;
node.n1[public_transport = platform][~'^bus|trolleybus|tram$' ~ '^yes$'] -> .n2;
node.n1[highway = bus_stop][public_transport != stop_position] -> .n3;
(.n2; .n3;) -> .n1;
.n1 out meta geom;

Not really in scope for StreetComplete: if you like you can try a much larger bbox: 49.82292311172603,19.41009521484375,50.35159464074624,20.820465087890625 to see a much larger runtime difference between both queries.

Now, it looks like it is faster to apply the cheap operation on the full 100k elements in order to apply the expensive operations on a few less elements than the other way round. I think that makes sense. In the query above, it is a regex in a merge.

Both [public_transport = platform] and [highway = bus_stop] will be evaluated first, and they're already very selective. Regex will be applied on this result only.

[bbox:50.04559282551578,19.9237060546875,50.070472406781924,19.967780113220215];
node[public_transport = platform]; out count;
node[highway = bus_stop]; out count;
westnordost commented 4 years ago

I used this bbox: [bbox:50.1289423,18.7158966,50.4522579,19.3167114]

After doing more runs to even out outliers, the results are inconclusive after all. Looks pretty much the same:

mmd-osm commented 4 years ago

Ok, dev instance reports back 2s for !name in front, and 350ms with union in front.

lz4.overpass-api.de is currently not suitable for performance measurements due to the high system load (as can be seen in the largely varying numbers). Also, please make sure that you don't use overpass-api.de, as it points to both z.overpass-api.de and lz4.overpass-api.de with very different performance characteristics.

Instead, I tried https://overpass.maptime.in/api/ (which is used for OSMCha and has rather little load atm). Figures were fairly stable across 5-10 measurements: !name is front: 3.4s union in front: 2.5s

westnordost commented 4 years ago

Ok, so I/we can conclude that you are right and I need to change the implementation of the generator. Currently, the generator just puts all leaves (non-unions) in front of the generated overpass query, regardless of the order defined in Streetcomplete's "tag filter" syntax.

westnordost commented 4 years ago

Alrighty, this is the final syntax:

AddRoadName

[bbox:{{bbox}}];
way[highway~"^(primary|secondary|tertiary|unclassified|residential|living_street|pedestrian)$"][!name][!ref][noname != yes][!junction][area != yes]->.unnamed;
(
  way.unnamed['access' !~ '^private|no$'];
  way.unnamed['foot']['foot' !~ '^private|no$'];
); out meta geom;
[bbox:{{bbox}}];
way[highway~"^(primary|secondary|tertiary|unclassified|residential|living_street|pedestrian)$"][!name][!ref][noname != yes][!junction][area != yes] -> .without_names;
way[highway~"^(primary|secondary|tertiary|unclassified|residential|living_street|pedestrian)$"][name] -> .with_names;
way.with_names(around.without_names: 30.0 );
out body geom;

AddPlaceName

[bbox:{{bbox}}];
nwr[shop][shop !~ '^no|vacant$'] -> .e2;
nwr[craft] -> .e3;
nwr[office] -> .e4;
nwr[tourism = information][information = office] -> .e5;
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$'] -> .e6;
nwr[tourism ~ '^attraction|zoo|aquarium|theme_park|gallery|museum|hotel|guest_house|motel|hostel|alpine_hut|apartment|resort|camp_site|caravan_site|chalet$'] -> .e7;
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$'] -> .e8;
(.e2; .e3; .e4; .e5; .e6; .e7; .e8;) -> .e1;
nwr.e1[!name][!brand][noname != yes];
out meta geom;

AddOneway

AddBusStopName

Tag Filters ``` nodes with ((public_transport = platform and ~bus|trolleybus|tram ~ yes) or (highway = bus_stop and public_transport != stop_position)) and !name and noname != yes ```
[bbox:{{bbox}}];
node[public_transport = platform][~'^bus|trolleybus|tram$' ~ '^yes$'] -> .n2;
node[highway = bus_stop][public_transport != stop_position] -> .n3;
(.n2; .n3;) -> .n1;
node.n1[!name][noname != yes];
out meta geom;

AddIsBuildingUnderground

Tag Filters ``` ways, relations with building and !location and layer~-[0-9]+ ```
[bbox:{{bbox}}];
way[building][!location][layer ~ '^-[0-9]+$'] -> .w1;
rel[building][!location][layer ~ '^-[0-9]+$'] -> .r1;
(.w1; .r1;);
out meta geom;

AddHousenumber

(
  way['building'~'^(house|residential|apartments|detached|terrace|dormitory|semi|semidetached_house|farm|school|civic|college|university|public|hospital|kindergarten|train_station|hotel|retail|commercial)$'][location!=underground][ruins!=yes][!'addr:housenumber'][!'addr:housename'][!'addr:conscriptionnumber'][!'addr:streetnumber'][!noaddress]({{bbox}});
  rel['building'~'^(house|residential|apartments|detached|terrace|dormitory|semi|semidetached_house|farm|school|civic|college|university|public|hospital|kindergarten|train_station|hotel|retail|commercial)$'][location!=underground][ruins!=yes][!'addr:housenumber'][!'addr:housename'][!'addr:conscriptionnumber'][!'addr:streetnumber'][!noaddress]({{bbox}});
) -> .buildings;
.buildings > -> .building_nodes;
node.building_nodes[~'^addr:(housenumber|housename|conscriptionnumber|streetnumber)$'~'.']; < -> .buildings_with_addr_nodes;
(.buildings; - .buildings_with_addr_nodes;);
out meta geom;

MarkCompletedHighwayConstruction

[bbox:{{bbox}}];way[highway = construction](if:!is_date(t['opening_date']) || date(t['opening_date']) < date('2019-09-01T00:00:00Z')) -> .construction_with_unknown_state;
(
  way[highway=construction](newer: '2019-08-18T00:00:00Z');
  relation[highway=construction](newer: '2019-08-18T00:00:00Z');
) -> .recently_edited_construction;
(.construction_with_unknown_state; - .recently_edited_construction;) -> .roads_for_review;
.roads_for_review out meta geom;

AddReligionToPlaceOfWorship

Tag Filters ``` nodes, ways, relations with amenity=place_of_worship and !religion and name ```
[bbox:{{bbox}}];
nwr[amenity = place_of_worship][!religion][name];
out meta geom;

AddParkingAccess

Tag Filters ``` nodes, ways, relations with amenity=parking and (!access or access=unknown) ```
[bbox:{{bbox}}];
nwr[amenity = parking] -> .e1;
nwr.e1[!access] -> .e2;
nwr.e1[access = unknown] -> .e3;
(.e2; .e3;);
out meta geom;

AddRecyclingType

Tag Filters ``` nodes, ways, relations with amenity = recycling and !recycling_type ```
[bbox:{{bbox}}];
nwr[amenity = recycling][!recycling_type];
out meta geom;

AddSport

Tag Filters ``` nodes, ways with leisure=pitch and (!sport or sport ~ team_handball|hockey|skating|football ) and (access !~ private|no) ```
[bbox:{{bbox}}];
node[leisure = pitch] -> .n1;
node.n1[!sport] -> .n2;
node.n1[sport ~ '^team_handball|hockey|skating|football$'] -> .n3;
(.n2; .n3;) -> .n1;
node.n1[access !~ '^private|no$'] -> .n1;
way[leisure = pitch] -> .w1;
way.w1[!sport] -> .w2;
way.w1[sport ~ '^team_handball|hockey|skating|football$'] -> .w3;
(.w2; .w3;) -> .w1;
way.w1[access !~ '^private|no$'] -> .w1;
(.n1; .w1;);
out meta geom;

AddRoadSurface

Tag Filters ``` ways with highway ~ primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential|living_street|pedestrian|track|road and !surface and (access !~ private|no or (foot and foot !~ private|no)) ```
[bbox:{{bbox}}];
way[highway ~ '^primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential|living_street|pedestrian|track|road$'][!surface] -> .w1;
way.w1[access !~ '^private|no$'] -> .w2;
way.w1[foot][foot !~ '^private|no$'] -> .w3;
(.w2; .w3;);
out meta geom;

AddMaxSpeed

Tag Filters ``` ways with highway ~ motorway|motorway_link|trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential and !maxspeed and !maxspeed:forward and !maxspeed:backward and !source:maxspeed and !zone:maxspeed and !maxspeed:type and !zone:traffic and surface !~ unpaved|compacted|gravel|fine_gravel|pebblestone|grass_paver|ground|earth|dirt|grass|sand|mud|ice|salt|snow|woodchips and motor_vehicle !~ private|no and vehicle !~ private|no and area != yes and (access !~ private|no or (foot and foot !~ private|no)) ```
[bbox:{{bbox}}];
way[highway ~ '^motorway|motorway_link|trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential$'][!maxspeed][!'maxspeed:forward'][!'maxspeed:backward'][!'source:maxspeed'][!'zone:maxspeed'][!'maxspeed:type'][!'zone:traffic'][surface !~ '^unpaved|compacted|gravel|fine_gravel|pebblestone|grass_paver|ground|earth|dirt|grass|sand|mud|ice|salt|snow|woodchips$'][motor_vehicle !~ '^private|no$'][vehicle !~ '^private|no$'][area != yes] -> .w1;
way.w1[access !~ '^private|no$'] -> .w2;
way.w1[foot][foot !~ '^private|no$'] -> .w3;
(.w2; .w3;);
out meta geom;

AddMaxHeight

[bbox:{{bbox}}];
node[barrier = height_restrictor] -> .n2;
node[amenity = parking_entrance][parking ~ '^underground|multi-storey$'] -> .n3;
(.n2; .n3;) -> .n1;
node.n1[!maxheight][!'maxheight:physical'];

out meta geom;
[bbox:{{bbox}}];
way[highway ~ '^motorway|motorway_link|trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential|living_street|track|road$'] -> .w2;
way[highway = service][access !~ '^private|no$'][vehicle !~ '^private|no$'] -> .w3;
(.w2; .w3;) -> .w1;
way.w1[covered = yes] -> .w4;
way.w1[tunnel ~ '^yes|building_passage|avalanche_protector$'] -> .w5;
(.w4; .w5;) -> .w1;
way.w1[!maxheight][!'maxheight:physical'];

out meta geom;

AddRailwayCrossingBarrier

[bbox:{{bbox}}];
way[highway][access ~ '^private|no$'];
node(w) -> .private_roads;
way[railway ~ '^tram|abandoned$'];
node(w) -> .excluded_railways;
node[railway = level_crossing][!'crossing:barrier'];
(._; - .private_roads; );
(._; - .excluded_railways; );
out meta geom;

AddPostboxCollectionTimes

Tag Filters ``` nodes with amenity=post_box and !collection_times and collection_times:signed != no and access !~ private|no ```
[bbox:{{bbox}}];
node[amenity = post_box][!collection_times]['collection_times:signed' != no][access !~ '^private|no$'];
out meta geom;

AddOpeningHours

Tag Filters ``` nodes, ways, relations with ( shop and shop !~ no|vacant or amenity = bicycle_parking and bicycle_parking = building or amenity = parking and parking = multi-storey or amenity = recycling and recycling_type = centre or tourism = information and information = office or amenity ~ restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|planetarium|casino|library|townhall|courthouse|embassy|community_centre|youth_centre|bank|bureau_de_change|money_transfer|post_office|marketplace|internet_cafe|car_wash|car_rental|boat_rental|fuel|dentist|doctors|clinic|pharmacy|veterinary or tourism ~ zoo|aquarium|theme_park|gallery|museum or leisure ~ fitness_centre|dance|golf_course|water_park|miniature_golf|bowling_alley|horse_riding|amusement_arcade|adult_gaming_centre|tanning_salon or office ~ insurance|government|travel_agent|tax_advisor|religion|employment_agency or craft ~ carpenter|shoemaker|tailor|photographer|dressmaker|electronics_repair|key_cutter|stonemason ) and !opening_hours and name and opening_hours:signed != no and (access !~ private|no) ```
[bbox:{{bbox}}];
nwr[shop][shop !~ '^no|vacant$'] -> .e2;
nwr[amenity = bicycle_parking][bicycle_parking = building] -> .e3;
nwr[amenity = parking][parking = 'multi-storey'] -> .e4;
nwr[amenity = recycling][recycling_type = centre] -> .e5;
nwr[tourism = information][information = office] -> .e6;
nwr[amenity ~ '^restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|planetarium|casino|library|townhall|courthouse|embassy|community_centre|youth_centre|bank|bureau_de_change|money_transfer|post_office|marketplace|internet_cafe|car_wash|car_rental|boat_rental|fuel|dentist|doctors|clinic|pharmacy|veterinary$'] -> .e7;
nwr[tourism ~ '^zoo|aquarium|theme_park|gallery|museum$'] -> .e8;
nwr[leisure ~ '^fitness_centre|dance|golf_course|water_park|miniature_golf|bowling_alley|horse_riding|amusement_arcade|adult_gaming_centre|tanning_salon$'] -> .e9;
nwr[office ~ '^insurance|government|travel_agent|tax_advisor|religion|employment_agency$'] -> .e10;
nwr[craft ~ '^carpenter|shoemaker|tailor|photographer|dressmaker|electronics_repair|key_cutter|stonemason$'] -> .e11;
(.e2; .e3; .e4; .e5; .e6; .e7; .e8; .e9; .e10; .e11;) -> .e1;
nwr.e1[!opening_hours][name]['opening_hours:signed' != no][access !~ '^private|no$'];
out meta geom;

AddBikeParkingCapacity

Tag Filters ``` nodes, ways with amenity=bicycle_parking and !capacity and access !~ private|no ```
[bbox:{{bbox}}];
node[amenity = bicycle_parking][!capacity][access !~ '^private|no$'] -> .n1;
way[amenity = bicycle_parking][!capacity][access !~ '^private|no$'] -> .w1;
(.n1; .w1;);
out meta geom;

AddOrchardProduce

Tag Filters ``` ways, relations with landuse = orchard and !trees and !produce and !crop ```
[bbox:{{bbox}}];
way[landuse = orchard][!trees][!produce][!crop] -> .w1;
rel[landuse = orchard][!trees][!produce][!crop] -> .r1;
(.w1; .r1;);
out meta geom;

AddCycleway

[bbox:{{bbox}}];
way[highway ~ '^(primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified)$'][area != yes][motorroad != yes][!cycleway][!'cycleway:left'][!'cycleway:right'][!'cycleway:both'][!'sidewalk:bicycle'][!'sidewalk:both:bicycle'][!'sidewalk:left:bicycle'][!'sidewalk:right:bicycle'][maxspeed !~ '^(20|15|10|8|7|6|5|10 mph|5 mph|walk)$'][surface !~ '^(unpaved|compacted|gravel|fine_gravel|pebblestone|grass_paver|ground|earth|dirt|grass|sand|mud|ice|salt|snow|woodchips)$'][bicycle != no][access !~ '^private|no$'][bicycle != use_sidepath]['bicycle:backward' != use_sidepath]['bicycle:forward' != use_sidepath] -> .streets;
(
  way[highway=cycleway](around.streets: 15);
  way[highway ~ '^(path|footway)$'](around.streets: 15);
) -> .cycleways;
way.streets(around.cycleways: 15) -> .streets_near_cycleways;
(.streets; - .streets_near_cycleways;);
out meta geom;

AddSidewalk

[bbox:{{bbox}}];
way[highway ~ '^(primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential)$'][area != yes][motorroad != yes][!sidewalk][!'sidewalk:left'][!'sidewalk:right'][!'sidewalk:both'][maxspeed !~ '^(8|7|6|5|5 mph|walk)$'][surface !~ '^(unpaved|compacted|gravel|fine_gravel|pebblestone|grass_paver|ground|earth|dirt|grass|sand|mud|ice|salt|snow|woodchips)$'][lit = yes][foot != no][access !~ '^private|no$'][foot != use_sidepath] -> .streets;
way[highway ~ '^(path|footway|cycleway)$'](around.streets: 15) -> .ways;
way.streets(around.ways: 15) -> .streets_near_ways;
(.streets; - .streets_near_ways;);
out meta geom;

AddProhibitedForPedestrians

Tag Filters ``` ways with ( ~'sidewalk(:both)?' ~ none|no or (sidewalk:left ~ none|no and sidewalk:right ~ none|no) ) and !foot and access !~ private|no and motorroad != yes and highway ~ trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified and surface ~ paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone and ( oneway~yes|-1 or bridge=yes or tunnel=yes or bicycle~no|use_sidepath or lit=yes ) ```
[bbox:{{bbox}}];
way[~'^sidewalk(:both)?$' ~ '^none|no$'] -> .w2;
way['sidewalk:left' ~ '^none|no$']['sidewalk:right' ~ '^none|no$'] -> .w3;
(.w2; .w3;) -> .w1;
way.w1[!foot][access !~ '^private|no$'][motorroad != yes][highway ~ '^trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified$'][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'] -> .w1;
way.w1[oneway ~ '^yes|-1$'] -> .w4;
way.w1[bridge = yes] -> .w5;
way.w1[tunnel = yes] -> .w6;
way.w1[bicycle ~ '^no|use_sidepath$'] -> .w7;
way.w1[lit = yes] -> .w8;
(.w4; .w5; .w6; .w7; .w8;);
out meta geom;

AddCrossingType

Tag Filters ``` nodes with highway=crossing and !crossing ```
[bbox:{{bbox}}];
node[highway = crossing][!crossing];
out meta geom;

AddBuildingLevels

Tag Filters ``` ways, relations with building ~ house|residential|apartments|detached|terrace|dormitory|semi|semidetached_house|bungalow|school|civic|college|university|public|hospital|kindergarten|transportation|train_station|hotel|retail|commercial|office|warehouse|industrial|manufacture|parking|farm|farm_auxiliary|barn|cabin and !building:levels and !height and !building:height and !man_made and location!=underground and ruins!=yes ```
[bbox:{{bbox}}];
way[building ~ '^house|residential|apartments|detached|terrace|dormitory|semi|semidetached_house|bungalow|school|civic|college|university|public|hospital|kindergarten|transportation|train_station|hotel|retail|commercial|office|warehouse|industrial|manufacture|parking|farm|farm_auxiliary|barn|cabin$'][!'building:levels'][!height][!'building:height'][!man_made][location != underground][ruins != yes] -> .w1;
rel[building ~ '^house|residential|apartments|detached|terrace|dormitory|semi|semidetached_house|bungalow|school|civic|college|university|public|hospital|kindergarten|transportation|train_station|hotel|retail|commercial|office|warehouse|industrial|manufacture|parking|farm|farm_auxiliary|barn|cabin$'][!'building:levels'][!height][!'building:height'][!man_made][location != underground][ruins != yes] -> .r1;
(.w1; .r1;);
out meta geom;

AddBusStopShelter

Tag Filters ``` nodes with ((public_transport = platform and ~bus|trolleybus|tram ~ yes) or (highway = bus_stop and public_transport != stop_position)) and !shelter and !covered ```
[bbox:{{bbox}}];
node[public_transport = platform][~'^bus|trolleybus|tram$' ~ '^yes$'] -> .n2;
node[highway = bus_stop][public_transport != stop_position] -> .n3;
(.n2; .n3;) -> .n1;
node.n1[!shelter][!covered];
out meta geom;

AddVegetarian

Tag Filters ``` nodes, ways with amenity ~ restaurant|cafe|fast_food and name and !diet:vegetarian ```
[bbox:{{bbox}}];
node[amenity ~ '^restaurant|cafe|fast_food$'][name][!'diet:vegetarian'] -> .n1;
way[amenity ~ '^restaurant|cafe|fast_food$'][name][!'diet:vegetarian'] -> .w1;
(.n1; .w1;);
out meta geom;

AddVegan

Tag Filters ``` nodes, ways with amenity ~ restaurant|cafe|fast_food and name and diet:vegetarian ~ yes|only and !diet:vegan ```
[bbox:{{bbox}}];
node[amenity ~ '^restaurant|cafe|fast_food$'][name]['diet:vegetarian' ~ '^yes|only$'][!'diet:vegan'] -> .n1;
way[amenity ~ '^restaurant|cafe|fast_food$'][name]['diet:vegetarian' ~ '^yes|only$'][!'diet:vegan'] -> .w1;
(.n1; .w1;);
out meta geom;

AddInternetAccess

Tag Filters ``` nodes, ways, relations with (amenity=library or tourism ~ hotel|guest_house|hostel|motel) and !internet_access and !wifi and name ```
[bbox:{{bbox}}];
nwr[amenity = library] -> .e2;
nwr[tourism ~ '^hotel|guest_house|hostel|motel$'] -> .e3;
(.e2; .e3;) -> .e1;
nwr.e1[!internet_access][!wifi][name];
out meta geom;

AddParkingFee

Tag Filters ``` nodes, ways, relations with amenity = parking and !fee and !fee:conditional and access ~ yes|customers|public ```
[bbox:{{bbox}}];
nwr[amenity = parking][!fee][!'fee:conditional'][access ~ '^yes|customers|public$'];
out meta geom;

AddMotorcycleParkingCapacity

Tag Filters ``` nodes, ways with amenity=motorcycle_parking and !capacity and access !~ private|no ```
[bbox:{{bbox}}];
node[amenity = motorcycle_parking][!capacity][access !~ '^private|no$'] -> .n1;
way[amenity = motorcycle_parking][!capacity][access !~ '^private|no$'] -> .w1;
(.n1; .w1;);
out meta geom;

AddPathSurface

Tag Filters ``` ways with highway ~ path|footway|cycleway|bridleway|steps and !surface and access !~ private|no ```
[bbox:{{bbox}}];
way[highway ~ '^path|footway|cycleway|bridleway|steps$'][!surface][access !~ '^private|no$'];
out meta geom;

AddTracktype

Tag Filters ``` ways with highway=track and !tracktype and (access !~ private|no or (foot and foot !~ private|no)) ```
[bbox:{{bbox}}];
way[highway = track][!tracktype] -> .w1;
way.w1[access !~ '^private|no$'] -> .w2;
way.w1[foot][foot !~ '^private|no$'] -> .w3;
(.w2; .w3;);
out meta geom;

AddForestLeafType

[bbox:{{bbox}}];(way[landuse=forest][!leaf_type](if: length()<700.0);
relation[landuse=forest][!leaf_type](if: length()<700.0);
way[natural=wood][!leaf_type](if: length()<700.0);
relation[natural=wood][!leaf_type](if: length()<700.0);
);out meta geom;

AddBikeParkingType

Tag Filters ``` nodes, ways with amenity=bicycle_parking and access !~ private|no and !bicycle_parking ```
[bbox:{{bbox}}];
node[amenity = bicycle_parking][access !~ '^private|no$'][!bicycle_parking] -> .n1;
way[amenity = bicycle_parking][access !~ '^private|no$'][!bicycle_parking] -> .w1;
(.n1; .w1;);
out meta geom;

AddWheelchairAccessToilets

Tag Filters ``` nodes, ways with amenity=toilets and access !~ private|customers and !wheelchair ```
[bbox:{{bbox}}];
node[amenity = toilets][access !~ '^private|customers$'][!wheelchair] -> .n1;
way[amenity = toilets][access !~ '^private|customers$'][!wheelchair] -> .w1;
(.n1; .w1;);
out meta geom;

AddPlaygroundAccess

Tag Filters ``` nodes, ways, relations with leisure = playground and (!access or access = unknown) ```
[bbox:{{bbox}}];
nwr[leisure = playground] -> .e1;
nwr.e1[!access] -> .e2;
nwr.e1[access = unknown] -> .e3;
(.e2; .e3;);
out meta geom;

AddWheelchairAccessBusiness

Tag Filters ``` nodes, ways, relations with ( shop and shop !~ no|vacant or amenity = parking and parking = multi-storey or amenity = recycling and recycling_type = centre or tourism = information and information = office or amenity ~ restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|library|theatre|arts_centre|casino|conference_centre|bank|bureau_de_change|money_transfer|post_office|internet_cafe|marketplace|police|ranger_station|courthouse|embassy|townhall|community_centre|youth_centre|car_wash|car_rental|fuel|driving_school|doctors|clinic|pharmacy|veterinary|dentist|place_of_worship or tourism ~ zoo|aquarium|theme_park|gallery|attraction|viewpoint|museum|hotel|guest_house|hostel|motel|apartment|chalet or leisure ~ golf_course|water_park|miniature_golf|dance|bowling_alley|horse_riding|sports_centre|fitness_centre|amusement_arcade|adult_gaming_centre|tanning_salon or office ~ insurance|government|travel_agent|tax_advisor|religion|employment_agency|lawyer|estate_agent|political_party|therapist or craft ~ carpenter|shoemaker|tailor|photographer|dressmaker|electronics_repair|key_cutter|stonemason|winery ) and !wheelchair and name ```
[bbox:{{bbox}}];
nwr[shop][shop !~ '^no|vacant$'] -> .e2;
nwr[amenity = parking][parking = 'multi-storey'] -> .e3;
nwr[amenity = recycling][recycling_type = centre] -> .e4;
nwr[tourism = information][information = office] -> .e5;
nwr[amenity ~ '^restaurant|cafe|ice_cream|fast_food|bar|pub|biergarten|food_court|nightclub|cinema|library|theatre|arts_centre|casino|conference_centre|bank|bureau_de_change|money_transfer|post_office|internet_cafe|marketplace|police|ranger_station|courthouse|embassy|townhall|community_centre|youth_centre|car_wash|car_rental|fuel|driving_school|doctors|clinic|pharmacy|veterinary|dentist|place_of_worship$'] -> .e6;
nwr[tourism ~ '^zoo|aquarium|theme_park|gallery|attraction|viewpoint|museum|hotel|guest_house|hostel|motel|apartment|chalet$'] -> .e7;
nwr[leisure ~ '^golf_course|water_park|miniature_golf|dance|bowling_alley|horse_riding|sports_centre|fitness_centre|amusement_arcade|adult_gaming_centre|tanning_salon$'] -> .e8;
nwr[office ~ '^insurance|government|travel_agent|tax_advisor|religion|employment_agency|lawyer|estate_agent|political_party|therapist$'] -> .e9;
nwr[craft ~ '^carpenter|shoemaker|tailor|photographer|dressmaker|electronics_repair|key_cutter|stonemason|winery$'] -> .e10;
(.e2; .e3; .e4; .e5; .e6; .e7; .e8; .e9; .e10;) -> .e1;
nwr.e1[!wheelchair][name];
out meta geom;

AddToiletAvailability

Tag Filters ``` nodes, ways with ( (shop ~ mall|department_store and name) or highway ~ services|rest_area ) and !toilets ```
[bbox:{{bbox}}];
node[shop ~ '^mall|department_store$'][name] -> .n2;
node[highway ~ '^services|rest_area$'] -> .n3;
(.n2; .n3;) -> .n1;
node.n1[!toilets] -> .n1;
way[shop ~ '^mall|department_store$'][name] -> .w2;
way[highway ~ '^services|rest_area$'] -> .w3;
(.w2; .w3;) -> .w1;
way.w1[!toilets] -> .w1;
(.n1; .w1;);
out meta geom;

AddFerryAccessPedestrian

Tag Filters ``` ways, relations with route=ferry and !foot ```
[bbox:{{bbox}}];
way[route = ferry][!foot] -> .w1;
rel[route = ferry][!foot] -> .r1;
(.w1; .r1;);
out meta geom;

AddFerryAccessMotorVehicle

Tag Filters ``` ways, relations with route=ferry and !motor_vehicle ```
[bbox:{{bbox}}];
way[route = ferry][!motor_vehicle] -> .w1;
rel[route = ferry][!motor_vehicle] -> .r1;
(.w1; .r1;);
out meta geom;

AddBuildingType

Tag Filters ``` ways, relations with building = yes and !man_made and !historic and !military and !power and location!=underground and ruins!=yes ```
[bbox:{{bbox}}];
way[building = yes][!man_made][!historic][!military][!power][location != underground][ruins != yes] -> .w1;
rel[building = yes][!man_made][!historic][!military][!power][location != underground][ruins != yes] -> .r1;
(.w1; .r1;);
out meta geom;

AddWayLit

Tag Filters ``` ways with ( highway ~ residential|living_street|pedestrian or highway ~ primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|service and ( sidewalk ~ both|left|right|yes|separate or ~source:maxspeed|maxspeed:type|zone:maxspeed|zone:traffic ~ .+:urban ) or highway ~ footway|cycleway|steps or highway = path and (foot = designated or bicycle = designated) ) and !lit and (access !~ private|no or (foot and foot !~ private|no)) ```
[bbox:{{bbox}}];
way[highway ~ '^residential|living_street|pedestrian$'] -> .w2;
way[highway ~ '^primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|service$'] -> .w3;
way.w3[sidewalk ~ '^both|left|right|yes|separate$'] -> .w4;
way.w3[~'^source:maxspeed|maxspeed:type|zone:maxspeed|zone:traffic$' ~ '^.+:urban$'] -> .w5;
(.w4; .w5;) -> .w3;
way[highway ~ '^footway|cycleway|steps$'] -> .w6;
way[highway = path] -> .w7;
way.w7[foot = designated] -> .w8;
way.w7[bicycle = designated] -> .w9;
(.w8; .w9;) -> .w7;
(.w2; .w3; .w6; .w7;) -> .w1;
way.w1[!lit] -> .w1;
way.w1[access !~ '^private|no$'] -> .w10;
way.w1[foot][foot !~ '^private|no$'] -> .w11;
(.w10; .w11;);
out meta geom;

AddToiletsFee

Tag Filters ``` nodes, ways with amenity = toilets and access !~ private|customers and !fee ```
[bbox:{{bbox}}];
node[amenity = toilets][access !~ '^private|customers$'][!fee] -> .n1;
way[amenity = toilets][access !~ '^private|customers$'][!fee] -> .w1;
(.n1; .w1;);
out meta geom;

AddBabyChangingTable

Tag Filters ``` nodes, ways with (((amenity ~ restaurant|cafe|fuel|fast_food or shop ~ mall|department_store) and name and toilets=yes) or amenity=toilets) and !diaper and !changing_table ```
[bbox:{{bbox}}];
node[amenity ~ '^restaurant|cafe|fuel|fast_food$'] -> .n3;
node[shop ~ '^mall|department_store$'] -> .n4;
(.n3; .n4;) -> .n2;
node.n2[name][toilets = yes] -> .n2;
node[amenity = toilets] -> .n5;
(.n2; .n5;) -> .n1;
node.n1[!diaper][!changing_table] -> .n1;
way[amenity ~ '^restaurant|cafe|fuel|fast_food$'] -> .w3;
way[shop ~ '^mall|department_store$'] -> .w4;
(.w3; .w4;) -> .w2;
way.w2[name][toilets = yes] -> .w2;
way[amenity = toilets] -> .w5;
(.w2; .w5;) -> .w1;
way.w1[!diaper][!changing_table] -> .w1;
(.n1; .w1;);
out meta geom;

AddBikeParkingCover

Tag Filters ``` nodes, ways with amenity=bicycle_parking and access !~ private|no and !covered and bicycle_parking !~ shed|lockers|building ```
[bbox:{{bbox}}];
node[amenity = bicycle_parking][access !~ '^private|no$'][!covered][bicycle_parking !~ '^shed|lockers|building$'] -> .n1;
way[amenity = bicycle_parking][access !~ '^private|no$'][!covered][bicycle_parking !~ '^shed|lockers|building$'] -> .w1;
(.n1; .w1;);
out meta geom;

AddTrafficSignalsSound

Tag Filters ``` nodes with highway = crossing and crossing = traffic_signals and !traffic_signals:sound ```
[bbox:{{bbox}}];
node[highway = crossing][crossing = traffic_signals][!'traffic_signals:sound'];
out meta geom;

AddRoofShape

Tag Filters ``` ways, relations with roof:levels and roof:levels!=0 and !roof:shape and !3dr:type and !3dr:roof ```
[bbox:{{bbox}}];
way['roof:levels']['roof:levels' != 0][!'roof:shape'][!'3dr:type'][!'3dr:roof'] -> .w1;
rel['roof:levels']['roof:levels' != 0][!'roof:shape'][!'3dr:type'][!'3dr:roof'] -> .r1;
(.w1; .r1;);
out meta geom;

AddWheelchairAccessPublicTransport

Tag Filters ``` nodes, ways, relations with (amenity = bus_station or railway ~ station|subway_entrance) and !wheelchair ```
[bbox:{{bbox}}];
nwr[amenity = bus_station] -> .e2;
nwr[railway ~ '^station|subway_entrance$'] -> .e3;
(.e2; .e3;) -> .e1;
nwr.e1[!wheelchair];
out meta geom;

AddWheelchairAccessOutside

Tag Filters ``` nodes, ways, relations with leisure=dog_park and !wheelchair ```
[bbox:{{bbox}}];
nwr[leisure = dog_park][!wheelchair];
out meta geom;

AddTactilePavingBusStop

Tag Filters ``` nodes, ways with (public_transport = platform or (highway = bus_stop and public_transport != stop_position)) and !tactile_paving ```
[bbox:{{bbox}}];
node[public_transport = platform] -> .n2;
node[highway = bus_stop][public_transport != stop_position] -> .n3;
(.n2; .n3;) -> .n1;
node.n1[!tactile_paving] -> .n1;
way[public_transport = platform] -> .w2;
way[highway = bus_stop][public_transport != stop_position] -> .w3;
(.w2; .w3;) -> .w1;
way.w1[!tactile_paving] -> .w1;
(.n1; .w1;);
out meta geom;

AddTactilePavingCrosswalk

Tag Filters ``` nodes with highway = crossing and !tactile_paving and foot != no ```
[bbox:{{bbox}}];
node[highway = crossing][!tactile_paving][foot != no];
out meta geom;

AddBridgeStructure

Tag Filters ``` ways with man_made=bridge and !bridge:structure ```
[bbox:{{bbox}}];
way[man_made = bridge][!'bridge:structure'];
out meta geom;

AddReligionToWaysideShrine

Tag Filters ``` nodes, ways, relations with historic=wayside_shrine and !religion and (access !~ private|no) ```
[bbox:{{bbox}}];
nwr[historic = wayside_shrine][!religion][access !~ '^private|no$'];
out meta geom;

AddCyclewaySegregation

Tag Filters ``` ways with ( (highway = path and bicycle = designated and foot = designated) or (highway = footway and bicycle = designated) or (highway = cycleway and foot ~ designated|yes) ) and !segregated and area != yes and surface ~ paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone ```
[bbox:{{bbox}}];
way[highway = path][bicycle = designated][foot = designated] -> .w2;
way[highway = footway][bicycle = designated] -> .w3;
way[highway = cycleway][foot ~ '^designated|yes$'] -> .w4;
(.w2; .w3; .w4;) -> .w1;
way.w1[!segregated][area != yes][surface ~ '^paved|asphalt|cobblestone|cobblestone:flattened|sett|concrete|concrete:lanes|concrete:plates|paving_stones|metal|wood|unhewn_cobblestone$'];
out meta geom;

MarkCompletedBuildingConstruction

[bbox:{{bbox}}];
way[building = construction](if:!is_date(t['opening_date']) || date(t['opening_date']) < date('2019-09-01T00:00:00Z')) -> .construction_with_unknown_state;
(
  way[building=construction](newer: '2019-03-05T00:00:00Z');
  relation[building=construction](newer: '2019-03-05T00:00:00Z');
) -> .recently_edited_construction;
(.construction_with_unknown_state; - .recently_edited_construction;) -> .buildings_under_construction_ways;
relation[building = construction](if:!is_date(t['opening_date']) || date(t['opening_date']) < date('2019-09-01T00:00:00Z')) -> .construction_with_unknown_state;
(
  way[building=construction](newer: '2019-03-05T00:00:00Z');
  relation[building=construction](newer: '2019-03-05T00:00:00Z');
) -> .recently_edited_construction;
(.construction_with_unknown_state; - .recently_edited_construction;) -> .buildings_under_construction_relations;
(.buildings_under_construction_ways; .buildings_under_construction_relations;);
out meta geom;

AddCyclewayPartSurface

Tag Filters ``` ways with highway ~ path|footway|cycleway|bridleway and surface = paved and bicycle ~ designated|yes and segregated=yes and !cycleway:surface and !surface:cycleway ```
[bbox:{{bbox}}];
way[highway ~ '^path|footway|cycleway|bridleway$'][surface = paved][bicycle ~ '^designated|yes$'][segregated = yes][!'cycleway:surface'][!'surface:cycleway'];
out meta geom;

AddFootwayPartSurface

Tag Filters ``` ways with highway ~ path|footway|cycleway|bridleway and surface = paved and foot ~ designated|yes and segregated=yes and !footway:surface and !surface:footway ```
[bbox:{{bbox}}];
way[highway ~ '^path|footway|cycleway|bridleway$'][surface = paved][foot ~ '^designated|yes$'][segregated = yes][!'footway:surface'][!'surface:footway'];
out meta geom;

AddMotorcycleParkingCover

Tag Filters ``` nodes, ways with amenity = motorcycle_parking and access !~ private|no and !covered and motorcycle_parking !~ shed|garage_boxes|building ```
[bbox:{{bbox}}];
node[amenity = motorcycle_parking][access !~ '^private|no$'][!covered][motorcycle_parking !~ '^shed|garage_boxes|building$'] -> .n1;
way[amenity = motorcycle_parking][access !~ '^private|no$'][!covered][motorcycle_parking !~ '^shed|garage_boxes|building$'] -> .w1;
(.n1; .w1;);
out meta geom;

AddFireHydrantType

Tag Filters ``` nodes with emergency = fire_hydrant and !fire_hydrant:type ```
[bbox:{{bbox}}];
node[emergency = fire_hydrant][!'fire_hydrant:type'];
out meta geom;

AddParkingType

Tag Filters ``` nodes, ways, relations with amenity = parking and !parking ```
[bbox:{{bbox}}];
nwr[amenity = parking][!parking];
out meta geom;

AddPowerPolesMaterial

Tag Filters ``` nodes with power = pole and !material ```
[bbox:{{bbox}}];
node[power = pole][!material];
out meta geom;

AddCarWashType

Tag Filters ``` nodes, ways with amenity = car_wash and !automated and !self_service ```
[bbox:{{bbox}}];
node[amenity = car_wash][!automated][!self_service] -> .n1;
way[amenity = car_wash][!automated][!self_service] -> .w1;
(.n1; .w1;);
out meta geom;

AddBenchBackrest

Tag Filters ``` nodes with amenity = bench and !backrest ```
[bbox:{{bbox}}];
node[amenity = bench][!backrest];
out meta geom;

AddTrafficSignalsButton

Tag Filters ``` nodes with highway = crossing and crossing = traffic_signals and !button_operated ```
[bbox:{{bbox}}];
node[highway = crossing][crossing = traffic_signals][!button_operated];
out meta geom;
westnordost commented 4 years ago

The following times are from https://overpass.maptime.in/api/ which has little load, so the times are more stable (and probably less than one can expect from the main instance). The bbox used was [bbox:53.5, 9.9, 53.6, 10.0]

Quest Type Old Time New Time ๐Ÿ˜€
AddRoadName 4.0s 3.7s
AddPlaceName 23.4s 4.4s ๐ŸŽ๏ธ
AddOneway
AddBusStopName 23.8s 1.3s ๐ŸŽ๏ธ
AddIsBuildingUnderground 1.3s 1.3s
AddHousenumber 1.8s 1.9s
MarkCompletedHighwayConstruction 1.1s 1.1s
AddReligionToPlaceOfWorship 1.2s 1.2s
AddParkingAccess 1.8s 1.5s
AddRecyclingType 1.2s 1.1s
AddSport 1.6s 1.3s
AddRoadSurface 1.4s 1.3s
AddMaxSpeed 1.4s 1.2s
AddMaxHeight 2.1s 2.4s
AddRailwayCrossingBarrier 1.5s 1.4s
AddPostboxCollectionTimes 1.0s 1.0s
AddOpeningHours 13.4s 5.5s ๐Ÿš—
AddBikeParkingCapacity 0.9s 0.9s
AddOrchardProduce 1.1s 1.1s
AddCycleway 25.9s 25.8s ๐ŸŒ
AddSidewalk 31.4s 31.4s ๐ŸŒ
AddProhibitedForPedestrians 22.5s 1.7s ๐ŸŽ๏ธ
AddCrossingType 0.9s 0.9s
AddBuildingLevels 1.5s 1.5s
AddBusStopShelter 1.7s 1.2s
AddVegetarian 1.2s 1.2s
AddVegan 1.1s 1.1s
AddInternetAccess 1.9s 1.8s
AddParkingFee 1.4s 1.4s
AddMotorcycleParkingCapacity 0.9s 0.9s
AddPathSurface 1.1s 1.1s
AddTracktype 1.4s 1.1s
AddBikeParkingType 1.6s 1.6s
AddWheelChairAccessToilets 0.9s 1.0s
AddPlaygroundAccess 1.3s 1.3s
AddWheelchairAccessBusiness 6.3s 5.6s ๐Ÿš—
AddToiletAvailability 1.5s 1.4s
AddFerryAccessPedestrian 1.2s 1.2s
AddFerryAccessMotorVehicle 1.3s 1.3s
AddBuildingType 2.1s 2.1s
AddWayLit 7.1s 2.7s ๐Ÿš—
AddToiletsFee 0.9s 0.9s
AddBabyChangingTable 1.4s 1.8s
AddBikeParkingCover 1.0s 1.0s
AddTrafficSignalsSound 0.9s 0.9s
AddRoofShape 1.4s 1.4s
AddWheelChairAccessPublicTransport 1.7s 1.7s
AddWheelchairAccessOutside 0.9s 0.9s
AddTactilePavingBusStop 1.6s 1.6s
AddTactilePavingCrosswalk 1.0s 1.0s
AddBridgeStructure 0.9s 0.9s
AddReligionToWaysideShrine 0.9s 0.9s
AddCyclewaySegregation 2.4s 1.7s ๐Ÿš—
MarkCompletedBuildingConstruction 1.7s 1.7s
AddMotorcycleParkingCover 0.8s 0.8s
AddFireHydrantType 0.9s 0.9s
AddParkingType 1.5s 1.5s
AddPowerPolesMaterial 0.9s 0.9s
AddCarWashType 0.9s 0.9s
AddBenchBackrest 0.9s 0.8s
AddTrafficSignalsButton 0.9s 0.9s
Total response time 223s 146s

So, this is in waiting for the response time alone, almost 1.5 minutes, or overall, 53% faster. To summarize, the following queries are above average (of 2.4s):

Quest Type Time
AddSidewalk 31.4s
AddCycleway 25.8s
AddWheelcharAccessBusiness 5.6s
AddOpeningHours 5.5s
AddPlaceName 4.4s
AddRoadName 3.7s
AddWayLit 2.7s

By the way, how come that the pull request you mentioned https://github.com/drolbr/Overpass-API/pull/167 has not been merged after more than 4 years? That's a pretty long time.

westnordost commented 4 years ago

By the way, how come that the pull request you mentioned drolbr/Overpass-API#167 has not been merged after more than 4 years? That's a pretty long time.

Though, I noticed that there hasn't been any activity neither on drolbr's nor on your fork in the last year or so. Did development on overpass cease and it is considered done?

mmd-osm commented 4 years ago

I think you're looking at the wrong branches: both https://github.com/mmd-osm/Overpass-API/commits/test759 and https://github.com/drolbr/Overpass-API/tree/minor_issues have activity this year. So no, we're not yet done...

westnordost commented 4 years ago

Good to hear :-) I was looking on GitHub at https://github.com/mmd-osm/Overpass-API/graphs/contributors and https://github.com/mmd-osm/Overpass-API/branches/active , apparently activity on branches is not counted properly.

mmd-osm commented 4 years ago

By the way, which bbox did you use for AddSidewalk and AddCycleway? I can do a quick retest on our dev instance, to see where would be at with additional patches in place.

Atrate commented 4 years ago

AddWheelchairAccessBuisness is also above average, just pointing this out

westnordost commented 4 years ago

@mmd-osm I used [bbox:50.1289423,18.7158966,50.4522579,19.3167114]

mmd-osm commented 4 years ago

Maybe I'm missing something here. I'm unable to reproduce those runtime measurements. AddSidewalk runs for several minutes here: https://overpass-turbo.eu/s/Lna - Even on the dev instance this query takes 53s, using optimizations that aren't available elsewhere.

Are you maybe splitting the bbox into smaller chunks and send several requests instead?

westnordost commented 4 years ago

Oh, I am sorry, I told you the wrong bbox! The bbox used in the tests above is actually the city center of Hamburg, 53.5, 9.9, 53.6, 10.0, here is the code.

mmd-osm commented 4 years ago

Thanks, AddSidewalk currently takes 1s on the dev instance with the new bbox. Let's see how we can move those changes into master branch over time.

westnordost commented 4 years ago

Wow, that's pretty cool!

That, together with my optimizations, would make the whole process take only 40% of the time (or in other words, makes it 150% faster) than it does at the moment.

westnordost commented 4 years ago

By the way, do you know who hosts https://overpass.maptime.in/api/ ? I would like to ask, if it is okay to add it to StreetComplete's alternative overpass servers list

mmd-osm commented 4 years ago

AFAIK it was set up for OSMCha by the Mapbox team in India. I don't know exactly if the team is stilll around or who currently maintains the box. I think @willemarcel should have more details.

westnordost commented 4 years ago

I did the above performance test also on other servers, the results are:

Overpass server Total response time for downloading all quests
maptime.in 146s
kumi systems 248s
lz4.overpass-api.de 304s
z.overpass-api.de 795s (+ 595s waiting for quota = 1390s)
westnordost commented 4 years ago

So even simply switching away from the default overpass instance, of which at least z.overpass-api.de seems to be hopelessly overloaded, will lead to a massive time reduction in download. Something between 3x to 6x faster. Is it "ok" to use lz4.overpass-api.de as the default server, or may the server name change any time or is otherwise only intended to be used behind the load balancer? z.overpass-api.de seems to be the only server that imposes a quota on the requests.

mmd-osm commented 4 years ago

lz4 has seen a massive increase in load during the last two weeks and has higher than expected response times., z.* uses a slower compression, and is expected to be slower. one of the 4 kumi boxes lags behind by 7 years, another one is currently unavailable.

mmd-osm commented 4 years ago

overpass-api.de uses DNS round robin rather than a load balancer, i.e. the server has two DNS entries, one pointing to the z. IP address, the other one to lz4.. And yes, this might change...

I think both servers have rate limiting in place: http://lz4.overpass-api.de/api/status

westnordost commented 4 years ago

I figure they have both rate limiting in place, but the test did not run into any rate limiting, I guess because it is has enough free capacities.

So, can you confirm that lz4 may be used and is also intended to be used directly, without the DNS round robin / load balancer in between? Not querying the overloaded server every ~second time would already increase the speed the quests are downloaded three-fold.

westnordost commented 4 years ago

StreetComplete always correctly sets the user agent for every request it makes. Can it be ascertained from munin or other statistics for how many % of requests / for how much load the app is actually responsible for?

mmd-osm commented 4 years ago

can you confirm that lz4 may be used and is also intended to be used directly, without the DNS round robin / load balancer in between?

If you manage a list of servers in your app and fall back to other servers if one turns out to be unavailable, that should be ok. Ideally, that would be part of some configuration that won't require users to download a new version of the app, in case some changes are needed.

I can't really help with the question re. production, you need to get in touch with Roland by email.

rugk commented 4 years ago

So may I use the queries from https://github.com/westnordost/StreetComplete/issues/1514#issuecomment-518362266 for updating the wiki now?

westnordost commented 4 years ago

Absolutely! I ran the script again in case there were small changes and changed my comment above.

You can also run the program later in case things get changed or new quests added. It is a simple Java program that prints all the things. To run it yourself in Android Studio, just press this button: PrintOverpassQueries

mmd-osm commented 4 years ago

If you change your script a bit, you can create a wiki page with links to overpass turbo: https://wiki.openstreetmap.org/wiki/User:Mmd/Test_SC

(btw: dev branch runs all queries in 24s)

westnordost commented 4 years ago

Cool, nice Page!

@rugk keeps links to all the overpass queries on this page https://wiki.openstreetmap.org/wiki/StreetComplete/Quests

What, you mean, all of them together in 24s??

mmd-osm commented 4 years ago

Yeah, I know this page, I thought it might be easier to just generate the content based on the existing quests in the code.

Thatโ€™s the โ€œTotal response time for downloading all questsโ€ as before.