11

I have just started to use Python and I would like to make a query to Overpass and store the results in a geospatial format (e.g. GeoJSON).

As far as I know, there is a library called overpy that should be what I am looking for. After reading its documentation I came up with the following code:

import overpy

API = overpy.Overpass()

# Fetch highways within Granollers' city.

result = API.query("""
    area[name="Granollers"][admin_level=8];
    // query part for: “highway=*”
    (way["highway"](area);
    relation["highway"](area);
    );
    // print results
    out body;
    """)

The thing is that I am not familiar at all with python and I don't know how to store result as a GeoJSON file (Honestly, I don't even know what kind of thing result is -I tried with type(result) and I get overpy.Result as an output, which doesn't mean much to my poor knowledge). I have been reading overpy documentation but I haven't been able to figure it out.

2
  • 2
    Same question as also posted here: github.com/DinoTools/python-overpy/issues/75 - so better follow up there.
    – mmd
    Commented Mar 7, 2019 at 15:38
  • Yes, it's me who posted it there too. Unfortunately, the question was originally asked months ago without receiving any attention
    – ccamara
    Commented Mar 8, 2019 at 6:35

2 Answers 2

11

You could do this using overpass that already returns a geojson object and then, if you want, you can use the geojson package to convert this object into str (string object) or save it in a file.

import overpass
import geojson

api = overpass.API()

# api.get already returns a FeatureCollection, a GeoJSON type
res = api.get("""
    area[name="Granollers"][admin_level=8];
    // query part for: “highway=*”
    (way["highway"](area);
      relation["highway"](area);
    );
    // recurse down to get the nodes, required for the geometry
    (._;>;);
""")

# if you want a str, then use dumps function
#geojson_str = geojson.dumps(res)

# dump as file, if you want to save it in file
with open("./test.geo.json",mode="w") as f:
  geojson.dump(res,f)

OBS: Take a look at the line with (._;>;); it is VERY important for the example you provide. Your query is about ways and relations, and if you don't add the last line to the query, the server will respond with ways and relations but no nodes and therefore won't be coordinates and without coordinates, the resulting geojson won't have geometries at all.

Finally, be aware that this query retrieves almost 2 MB of data, so consider this when you try to handle the results.

9
  • Thank you very much for reviving this issue, @carpinchosaurio!
    – ccamara
    Commented Oct 6, 2019 at 17:51
  • I tried your solution after installing osmtogeojson via pip, but I am afraid nor osm2gojson nor json2geojson are defined. Possibly I am doing something wrong?
    – ccamara
    Commented Oct 6, 2019 at 17:52
  • Hello again, I am afraid that there is an error on the import statement, which should be import osm2geojson (which seems to be a different package than osmtogejson). However, I did not succeed in running the code, as I get some errors ` File "<ipython-input-1-28700f60e0f8>", line 13, in <module> geojson_obj = osm2geojson.json2geojson(res)` amongs others
    – ccamara
    Commented Oct 7, 2019 at 8:58
  • I am really sorry @ccamara, you are right my code was wrong, I get confused with some other libraries that I was using for a problem similar to yours, but I fixed this code and tested thoroughly, seems that overpass already returns a geojson so there is no need of osm2geojson anymore, please don't hesitate in asking for any further details, good luck Commented Oct 7, 2019 at 11:58
  • Thanks for updating the code. Now it works, except by the fact that it only outputs a regular json, with attributes (OK) but no geometries (KO)
    – ccamara
    Commented Oct 7, 2019 at 21:21
3

To export a valid 'line'-geojson you could set the verbosity to 'geom'. If you are facing timeout issues you could set a larger timeout value than the default 25.

import overpass
import geojson

api = overpass.API(timeout=500)

# api.get already returns a FeatureCollection, a GeoJSON type
res = api.get("""
    area[name="Granollers"][admin_level=8];
    // query part for: “highway=*”
    (way["highway"](area);
      relation["highway"](area);
    );
""", verbosity='geom')

# dump as file, if you want to save it in file
with open("c:/temp/testio.geojson",mode="w") as f:
  geojson.dump(res,f)
1
  • Thank you! Works great! I love how simple the solution was!
    – ccamara
    Commented Nov 22, 2021 at 20:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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