4

I am looking for a solution that works with the overpass api.

for example:

http://overpass-api.de/api/interpreter?data=[out:geojson];area(3600225494);(node(area)[%22amenity%22~%22theatre|cinema|arts_centre%22];);out%20body;

When trying this approach I get an error that says

"Error: line 1: static error: For the attribute "output" of the element "osm-script" the only allowed values are "xml", "json", "csv", "custom", or "popup"."

Therefore GeoJSON is not supported this way.

I tried several approaches in ipython (python 2.7) to transform json into geojson, but failed so far.

What I need is a way to get OSM as geojson in ipython via using a url (e.g. overpass api).

BR

10

Overpass API doesn't support GeoJSON. You have to perform the conversion from JSON to GeoJSON yourself.

For converting JSON into GeoJSON see this answer. It even contains a solution in Python. Another Python solution is contained in this answer.

| improve this answer | |
  • Thanks! For confirming/clarifying my issue and also providing a possible solution. Will try it out the first solution and let you know later. The second solution I already tried and hat some problem with the d["lon"] – Apachai Dec 7 '16 at 13:56
  • 2
    To elaborate: adding geojson output to the overpass API was discussed and rejected here github.com/drolbr/Overpass-API/issues/48, because semantics are unclear for e.g. closed ways. They then mention github.com/tyrasd/osmtogeojson as a way to produce geojson from OSM data. – til_b Dec 7 '16 at 14:23
  • @scai I tried it out and both approaches return a KeyError: KeyError Traceback (most recent call last) <ipython-input-152-f46acadcf165> in <module>() ----> 1 v = convert_json(data) <ipython-input-151-b6174edc078d> in convert_json(items) 10 if key not in ('lat', 'lon') } 11 } ---> 12 for feature in json.loads(items) 13 ] 14 }) KeyError: 'lon' – Apachai Dec 7 '16 at 20:57
  • 1
1

I developed a slightly clunky approach using Pandas and GeoPandas. Posting in case it's useful, especially to someone who might be looking for GeoJSON to use with GeoPandas in the first place. Basically, the flow is:

overpass JSON > Pandas > GeoPandas > GeoJSON

import requests
import pandas as pd
import geopandas as gp
from shapely.geometry import Point

def get_overpass_gdf(query_string):

    # Retrieve URL contents
    r = requests.get(query_string)

    # Make dataframe
    df = pd.DataFrame(r.json()['elements'])

    # Make geodataframe
    df['geometry'] = [Point(xy) for xy in zip(df.lon, df.lat)]
    df = gp.GeoDataFrame(df, geometry='geometry')

    return df

# Specify query
query_string = 'http://overpass-api.de/api/interpreter?data=[out:json];area(3600225494);(node(area)[%22amenity%22~%22theatre%7Ccinema%7Carts_centre%22];);out%20body;'

# Export to GeoJSON
gdf = get_overpass_gdf(query_string)
gdf.to_file("query_results.json", driver="GeoJSON")
| improve this answer | |
  • 1
    Note that this code only works with nodes. It does not support ways and relations, nor out center; to process the center point of a way. – mmd Nov 2 '19 at 10:09
0

Python package to convert OSM/Overpass XML to GeoJSON osm2geojson.

I have some problems with your example. But I made similar:

import requests
import urllib
import codecs
import json
from osm2geojson import json2geojson

OVERPASS = "https://overpass-api.de/api/interpreter/"


def overpass_call(query):
    encoded = urllib.parse.quote(query.encode('utf-8'), safe='~()*!.\'')
    r = requests.post(OVERPASS,
                      data=f"data={encoded}",
                      headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'})
    if not r.status_code is 200:
        raise requests.exceptions.HTTPError('Overpass server respond with status '+str(r.status_code))
    return r.text


def save_data(data, geom_file):
    json_data = json.dumps(data, indent=2)
    f = codecs.open(geom_file, 'w')
    f.write(json_data)
    f.close()


data = overpass_call(f"""
    [out:json];
    node["amenity"~"theatre|cinema|arts_centre"](50.33, 30.30, 50.57, 30.68);
    out geom;
""")

geojson_data = json2geojson(data)
save_data(geojson_data, 'art.geojson')

| improve this answer | |
New contributor
rapkin is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.