Как заставить запрос {{geocodeArea: xxx}} работать в python, используя overpy? - PullRequest
0 голосов
/ 08 сентября 2018

Я хочу найти все пабы в определенной области, используя Overpass API и выбрав область с помощью geocodeArea .

Проверка следующего запроса на overpass-turbo.eu дает мне желаемый результат:

{{geocodeArea:berlin}}->.searchArea;
(
  node["amenity"="pub"](area.searchArea);
  way["amenity"="pub"](area.searchArea);
  relation["amenity"="pub"](area.searchArea);
);
out body;
>;
out skel qt;

Но когда я реализую этот запрос в python, используя overpy ...

import overpy

api = overpy.Overpass()

result = api.query("""
        {{geocodeArea:berlin}}->.searchArea;
        (
          node["amenity"="pub"](area.searchArea);
          way["amenity"="pub"](area.searchArea);
          relation["amenity"="pub"](area.searchArea);
        );
        out body;
        >;
        out skel qt;
    """)

print("Amenities in nodes: %d" % len(result.nodes))
print("Amenities in ways: %d" % len(result.ways))

... Я получаю следующую ошибку:

Traceback (most recent call last):
  File "testOP.py", line 15, in <module>
    """)
  File "/usr/local/lib/python2.7/dist-packages/overpy/__init__.py", line 119, in query
    msgs=msgs
overpy.exception.OverpassBadRequest: Error: line 2: parse error: Unknown type "{" 
Error: line 2: parse error: An empty query is not allowed 
Error: line 2: parse error: ';' expected - '{' found. 

Полагаю, что проблема связана с двойными фигурными скобками, но пока что избежать их и других вариантов не помогло.


Возможное решение с помощью Nominatim

Благодаря @scai теперь я знаю, что с {{geocodeArea: xxx}} турбо-переход только делает геокодзапрос.Я решил реализовать это в своей программе самостоятельно, используя geopy и Nominatim :

from geopy.geocoders import Nominatim
import overpy

city_name = "berlin"

# Geocoding request via Nominatim
geolocator = Nominatim(user_agent="city_compare")
geo_results = geolocator.geocode(city_name, exactly_one=False, limit=3)

# Searching for relation in result set
for r in geo_results:
    print(r.address, r.raw.get("osm_type"))
    if r.raw.get("osm_type") == "relation":
        city = r
        break

# Calculating area id
area_id = int(city.raw.get("osm_id")) + 3600000000

# Excecuting overpass call
api = overpy.Overpass()
result = api.query("""
    area(%s)->.searchArea;
    (
      node["amenity"="pub"](area.searchArea);
      way["amenity"="pub"](area.searchArea);
      relation["amenity"="pub"](area.searchArea);
    );
    out body;
    """ % area_id)

# Printing no. of pubs in nodes and ways
print("Amenities in nodes: %d" % len(result.nodes))
print("Amenities in ways: %d" % len(result.ways))

Код ...

  1. Выполняет ли запрос геокодирования к Nominatim
  2. Поиск первого элемента в результатах (макс. 3), который является отношением
  3. Добавляет 3600000000 для получения идентификатора области из идентификатора отношения

Это не очень чистое решение, и мне интересно, можно ли напрямую использовать первый результат (который в основном является городом) для моих целей.Подсказки все еще приветствуются.

1 Ответ

0 голосов
/ 10 сентября 2018

{{geocodeArea: xxx }} - это особенность турбо-эстакады, которая не входит в API-интерфейс Overpass. overpy использует Overpass API напрямую, что означает, что вы не можете использовать это ключевое слово.

Однако {{geocodeArea: xxx }} просто указывает, что overpass turbo выполняет запрос геокодирования , то есть преобразовывает адрес в географическое местоположение. Вы можете сделать то же самое, например, позвонив Номинатим, Фотону или любому другому геокодеру.

...