如何使用Overpy获取{{geocodeArea:xxx}}查询以在python中工作?

时间:2018-09-08 15:19:37

标签: python openstreetmap overpass-api

我想使用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;

但是当我使用overpy在python中实现该查询时...

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}} 立交桥只会发出地理编码请求。我决定自己使用geopyNominatim在程序中实现该目标:

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,以从关系ID中获取区域ID

这不是一个很干净的解决方案,我想知道是否有可能直接将第一个结果(就这一点而言主要是城市)用于我的目的。仍然欢迎提示。

2 个答案:

答案 0 :(得分:0)

{{geocodeArea: xxx }}是Overpass Turbo的特殊功能,不是Overpass API的一部分。 overpy直接使用Overpass API,这意味着您不能使用此关键字。

但是{{geocodeArea: xxx }}只是告诉立交桥涡轮执行地理编码请求,即将地址转换为地理位置。您可以执行相同的操作,例如通过拨打Nominatim,Photon或其他任何地理编码器进行呼叫。

答案 1 :(得分:0)

您可以使用area过滤器而不是geocodeArea获得类似的结果。例如:

area[name="Berlin"]->.searchArea;
(
  node["amenity"="pub"](area.searchArea);
  way["amenity"="pub"](area.searchArea);
  relation["amenity"="pub"](area.searchArea);
);
out body;
>;
out skel qt;

这可能行得通,但是对于其他领域,您可能需要更详细地了解area过滤器中使用的标签,请在Language Guide中获得更多信息以进行立交