One reques on overpass-turbo with various - variables :etc. etx - can we do this in a single request!?

hi dear community

can we run such a request on the overpass-turbo.eu - API (end) on google-colab - in a serial request - that is : for various countries with the corresponding ISO keys like 3166 for

example

brasil

norway

turkey

italy

switzerland

etc. etx - can we do this in a single request!?

`` [out:csv(::id,::type,"name","addr:postcode","addr:city", "addr:street","addr:housenumber","website"," contact:email=*")][timeout:300]; area["ISO3166-1"="MT"]->.a; ( node(area.a)[amenity=bank]; way(area.a)[amenity=bank]; rel(area.a)[amenity=bank];); out;

guess that this is possible

wecan achieve this by using the Overpass API’s “area” feature to specify the ISO 3166-1 code for each country and then querying for the desired amenities within those areas. However, the Overpass API doesn’t support multiple areas in a single query. So, we need to make separate requests for each country.
we can automate this process by looping through a list of ISO 3166-1 codes and making a request for each country.

Here’s a Python example using the requests library:


import requests

countries = {
    "br": "Brazil",
    "no": "Norway",
    "tr": "Turkey",
    "it": "Italy",
    "ch": "Switzerland"
}

for iso_code, country_name in countries.items():
    overpass_query = (
        f'[out:csv(::id,::type,"name","addr:postcode","addr:city",'
        f'"addr:street","addr:housenumber","website","contact:email=*")][timeout:300];'
        f'area["ISO3166-1"="{iso_code}"]->.a;'
        f'( node(area.a)[amenity=bank];'
        f'  way(area.a)[amenity=bank];'
        f'  rel(area.a)[amenity=bank];);'
        f'out;'
    )

    response = requests.get("https://overpass-api.de/api/interpreter", params={"data": overpass_query})
    if response.status_code == 200:
        with open(f"{country_name}_banks.csv", "wb") as f:
            f.write(response.content)
        print(f"Data for {country_name} retrieved and saved.")
    else:
        print(f"Failed to retrieve data for {country_name}.")

This script will loop through the dictionary of countries, send a request for each country’s data, and save the results to CSV files named after the country. we can then run this script in Google Colab or any other Python environment that supports the requests library.

The premise is basically not true. You can assemble a series of them by union, as has already been done for separate node , way , and rel . Yes, it might be better to query each country separately anyway, perhaps for the purpose of splitting them into files. However, you can technically out; separately as well. This guarantees some order among them, which eg out qt; is not be enough. Then you may do a hack by adding a filler line eg out ids; to delineate them up, for further processing.
A. Union

(
  area["ISO3166-1"="XX"];
  area["ISO3166-1"="YY"];
)->.a;  // Format this in your code
nwr(area.a)[amenity=bank];
out;

B. Separate out;

area["ISO3166-1"="XX"];
out ids;
nwr(area)[amenity=bank];
out;
// Format these in your code
area["ISO3166-1"="YY"];
out ids;
nwr(area)[amenity=bank];
out;

C. Regex

area["ISO3166-1"~"XX|YY"];  // Format this in your code
nwr(area)[amenity=bank];
out;
1 Like

good day dear kovoschiz - many thanks for the reply and for all your hints. Well convinced - you point to the option to union in a single request - even direct on the overpas-turbo.eu - … i think this is also possible.

btw:; the results i get - using this approach - these are all “somewhat” - empty:

Data for Brazil retrieved and saved.
Data for Norway retrieved and saved.
Data for Turkey retrieved and saved.
Data for Italy retrieved and saved.
Data for Switzerland retrieved and saved.

see the full code - here below: well i stlll wonder why this does not work propperly…

import requests

countries = {
    "br": "Brazil",
    "no": "Norway",
    "tr": "Turkey",
    "it": "Italy",
    "ch": "Switzerland"
}

for iso_code, country_name in countries.items():
    overpass_query = (
        f'[out:csv(::id,::type,"name","addr:postcode","addr:city",'
        f'"addr:street","addr:housenumber","website","contact:email=*")][timeout:300];'
        f'area["ISO3166-1"="{iso_code}"]->.a;'
        f'( node(area.a)[amenity=hospital];'
        f'  way(area.a)[amenity=hospital];'
        f'  rel(area.a)[amenity=hospital];);'
        f'out;'
    )

    response = requests.get("https://overpass-api.de/api/interpreter", params={"data": overpass_query})
    if response.status_code == 200:
        with open(f"{country_name}_hospital.csv", "wb") as f:
            f.write(response.content)
        print(f"Data for {country_name} retrieved and saved.")
    else:
        print(f"Failed to retrieve data for {country_name}.")





Data for Brazil retrieved and saved.
Data for Norway retrieved and saved.
Data for Turkey retrieved and saved.
Data for Italy retrieved and saved.
Data for Switzerland retrieved and saved.

dear Kovoschiz - again many many thanks for the ideas and the hints:

well you ideas are very inspiring’. you say: separately as well. This guarantees some order among them, which eg out qt; is not be enough. Then you may do a hack by adding a filler line eg out ids; to delineate them up, for further processing.

A. Union

so the question - can w do like so - on the overpass-turbo.eu backend:


(
  area["ISO3166-1"="XX"];
  area["ISO3166-1"="YY"];
)->.a;  // Format this in your code
nwr(area.a)[amenity=bank];
out;



[out:csv(::id,::type,"name","addr:postcode","addr:city",
"addr:street","addr:housenumber","website"," contact:email=*")][timeout:900];
 area["ISO3166-1"="CH"]->.a;
 area["ISO3166-1"="ES"]->.a;
 area["ISO3166-1"="NO"]->.a;
 area["ISO3166-1"="IT"]->.a;
 area["ISO3166-1"="PT"]->.a;
( node(area.a)[amenity=hospital];
  way(area.a)[amenity=hospital];
  rel(area.a)[amenity=hospital];);
out;

hmmm !? i do not know -

this does not give back anything other than portugal results…

why is this so!?

You must bracket them together, same as what you have done for node , way , and rel next. Otherwise, it overwrites .a every line.

(
 area["ISO3166-1"="CH"];
 area["ISO3166-1"="ES"];
 area["ISO3166-1"="NO"];
 area["ISO3166-1"="IT"];
 area["ISO3166-1"="PT"];
)->.a;
1 Like

dear Kovoschiz

many thanks for the hints: awesome - i am glad. well i did a further try with another example - see here:

due to your help i was encouraged to go on

import requests
import pandas as pd
from io import StringIO

# List of ISO3166-1 country codes
country_codes = ["NL", "DE", "AT", "CH", "FR"]  # Add more country codes as needed

# Base request template
base_request = """
[out:csv(::id,::type,"name","addr:postcode","addr:city","addr:street","addr:housenumber","website"," contact:email=*")][timeout:600];
area["ISO3166-1"="{}"]->.a;
( node(area.a)[amenity=childcare];
  way(area.a)[amenity=childcare];
  rel(area.a)[amenity=childcare];);
out;
"""

# List to store individual DataFrames
dfs = []

# Loop through each country code
for code in country_codes:
    # Construct the request for the current country
    request = base_request.format(code)
    
    # Send the request to the Overpass API
    response = requests.post("https://overpass-api.de/api/interpreter", data=request)
    
    # Check if the request was successful
    if response.status_code == 200:
        # Parse the response as CSV and convert it to DataFrame
        try:
            df = pd.read_csv(StringIO(response.text), sep='\t')
        except pd.errors.ParserError as e:
            print(f"Error parsing CSV data for {code}: {e}")
            continue
        
        # Add country code as a new column
        df['country_code'] = code
        
        # Append the DataFrame to the list
        dfs.append(df)
    else:
        print(f"Error retrieving data for {code}")

# Merge all DataFrames into a single DataFrame
result_df = pd.concat(dfs, ignore_index=True)

# Save the DataFrame to a CSV file or perform further processing
result_df.to_csv("merged_childcare_data.csv", index=False)

solved the issues got back 570 kb data -

thanks alot