mocnik-science / osm-python-tools

A library to access OpenStreetMap related services
GNU General Public License v3.0
440 stars 48 forks source link

Coordinates (latitude, longitude) <-> (longitude, latitude) and how to query countries/worldwide with overpassQueryBuilder() #61

Closed muran123 closed 2 years ago

muran123 commented 2 years ago

Hi Franz

First of all thank you very much for the library you've build. I'm pretty new to OSM (and in general to geographic information) and your library is helping me a lot. My first goal was to identify all libraries within a city (and later per country and around the world) and later to do the same for other keys.

The first step was to find a city by name + verify the coordinates (I used Vienna like in your examples):

    from OSMPythonTools.nominatim import Nominatim
    nominatim = Nominatim()
    city = nominatim.query('Vienna', wkt=True)
    print('Vienna: ' + str(city.wkt()))

I get the following results: POLYGON((16.181831 48.1711198,16.181902 48.1710313, ...))

If I compare the coordinates (again I'm not an expert on geographic information) I wanted to verfiy the coordinates of Vienna via https://www.wikidata.org/wiki/Q1741 https://geohack.toolforge.org/geohack.php?params=48.208333333333336_N_16.3725_E_globe:earth&language=en -> 48.208333, 16.3725

Is it intentional that the latitude and longitude are reversed in order or is that a different format? (latitude=48.208333, longitude=16.3725) <-> the polygons in city.wkt() are containing the longitude first and the latitude second.

After that I started with the overpassQueryBuilder() function, where I used the example from here https://infovis.fh-potsdam.de/tutorials/infovis8geovis.html

library_query = overpassQueryBuilder(
    area=city.areaId(), # the query can be contrained by an area of an item
    elementType='node', # which are points (OSM also has ways and relations)
    # the selector in the next line is really the heart of the query:
    selector='"amenity"="library"', # we're looking for libraries
    out='body', # body indicates that we want the data, not just the count
    includeGeometry=True # and we want the geometric information, too
)
lib_data = overpass.query(library_query)
libraries = [ (lib.tag("name"), lib.geometry() ) for lib in lib_data.nodes()]
for library in libraries:
    name = library[0]
    location = library[1]["coordinates"]
    print('Library: ' + str(name) + ', coordinates: ' + str(location))

I do get the libraries in Vienna, but again it seems the coordinates are in the format (longitude, latitude). Is this on purpose or a different format?

e.g. output: Büchereien Wien, Rabenhof, coordinates: [16.400691, 48.196254] <-> https://www.openstreetmap.org/node/115181418 it shows the coordinates in the format (48.1962536, 16.4006914)

Also may I ask you, how I could extend the existing query to either e.g. a bunch of cities/a country/worldwide? If I try the overpassQueryBuilder() without the parameter "area"

library_query = overpassQueryBuilder(
    # area=city.areaId(), # the query can be contrained by an area of an item
    elementType='node', # which are points (OSM also has ways and relations)
    # the selector in the next line is really the heart of the query:
    selector='"amenity"="library"', # we're looking for libraries
    out='body', # body indicates that we want the data, not just the count
    includeGeometry=True # and we want the geometric information, too
)

I get the feedback "Please provide an area or a bounding box". If I try to use the parameter bbox with a huge number for "around" and the coordinates of Vienna (not sure if I should be using (48.208333, 16.3725) like in wiki/OSM or the opposite (16.3725, 48.208333))

library_query = overpassQueryBuilder(
    # area=city.areaId(), # the query can be contrained by an area of an item
    bbox='(around: 100000000000, 48.208333, 16.3725)',
    elementType='node', # which are points (OSM also has ways and relations)
    # the selector in the next line is really the heart of the query:
    selector='"amenity"="library"', # we're looking for libraries
    out='body', # body indicates that we want the data, not just the count
    includeGeometry=True # and we want the geometric information, too
)

I get the following exception: "('The requested data could not be downloaded. HTTP Error 400: Bad Request', <HTTPError 400: 'Bad Request'>)"

May I ask you if you could help me on this? Thank you very much

mocnik-science commented 2 years ago

Dear @muran123,

Thanks for the nice words.

Regarding the order of the coordinates: I have seen different services ordering latitude and longitude in different ways. The information you access is just queried from Nominatim and are not processed. In this sense, you have to ask the Nominatim community why they chose this order.

The function geometry() you use sorts “longitude, latitude” by convention.

Regarding your question about the several areas: You could either perform several queries (one area per query), or you could provide a proper bounding box. You provide a string rather than four bounding box coordinates, which I would have expected here. It could test whether bbox='around: 100000000000, 48.208333, 16.3725' works.

In general, I advise to check the result of overpassQueryBuilder manually by copying this result to https://overpass-turbo.eu. This should help debugging.

Due to my spare time, I cannot run and test your queries in more detail.

Best, Franz-Benjamin

muran123 commented 2 years ago

Thank you very much for your answer. I was not aware that the order latitude/longtitude was coming from Nominatim. In this case it seems there convention and I will adopt it in my part of the code. The idea with bbox='around: 100000000000, 48.208333, 16.3725 results in timeouts, because it might be to heavy load for the servers. Now I'm trying to use OSM extracts from (http://download.geofabrik.de/) [](http://download.geofabrik.de/) and process and filter th pbf file locally based on certain tags.

mocnik-science commented 2 years ago

Dear @muran123, Yes, sounds reasonable. If the data you want to process is too big, Overpass might be too slow. I experienced the same and would also do it in the way you now do. Best!