通过openstreetmap API获取国家边界

我想画一张欧洲地图。为此,我需要将国家轮廓作为多边形。为此,我想使用 openstreetmap API。


我尝试了一下,overpy但我对单个国家/地区的结果需要 10 分钟才能执行,而且看起来不正确(似乎这些方法不适合在一起)。


到目前为止我的代码:


import matplotlib.pyplot as plt


import overpy

api = overpy.Overpass()


result=api.query("area['name:en'='Denmark']->.country;rel['name:en'='Denmark']['type'='boundary']['admin_level'='2'];(way(r)['maritime' != 'yes'](40,-10,70,80);way(area.country)['natural'='coastline'](40,-10,70,80););out geom;")


x=[]

y=[]

i=0

for way in result.ways:

    print(f"way {i} of {len(result.ways)}")

    i=i+1

    for node in way.get_nodes(True):

        x.append(float(node.lon))

        y.append(float(node.lat))

plt.plot(x, y,label=str(way.id))

plt.show()

我走在正确的轨道上还是有更好的解决方案?谢谢!

https://img.mukewang.com/64f72688000161b605850329.jpg

https://img2.mukewang.com/64f726930001b34806550667.jpg

繁星点点滴滴
浏览 342回答 1
1回答

jeck猫

我认为这没关系,只需使用点而不是线。对于长时间运行我也没有解决方案。import matplotlib.pyplot as pltimport overpyapi = overpy.Overpass()result=api.query("area['name:en'='Denmark']->.country;rel['name:en'='Denmark']['type'='boundary']['admin_level'='2'];(way(r)['maritime' != 'yes'](40,-10,70,80);way(area.country)['natural'='coastline'](40,-10,70,80););out geom;")x=[]y=[]i=0for way in result.ways:    print(f"way {i} of {len(result.ways)}")    if 'natural' in way.tags and way.tags['natural']=='coastline' and len(way.get_nodes(True))>0: #just a test        i=i+1        for node in way.get_nodes(True):            print (f'lon: {float(node.lon):3.4f}; lat: {float(node.lat):3.4f}')            x.append(float(node.lon))            y.append(float(node.lat))plt.plot(x, y, 'o',label=str(way.id))plt.show()由于多边形而编辑:import jsonimport matplotlib.pyplot as pltimport overpydef getData():    api = overpy.Overpass()    result = api.query("area['name:en'='Denmark']->.country;rel['name:en'='Denmark']['type'='boundary']['admin_level'='2'];(way(r)['maritime' != 'yes'](40,-10,70,80);way(area.country)['natural'='coastline'](40,-10,70,80););out geom;")    x = []    y = []    i = 0    for way in result.ways:        print(f"way {i} of {len(result.ways)}")        # just a test        if 'natural' in way.tags and way.tags['natural'] == 'coastline' and len(way.get_nodes(True)) > 0:            i = i+1            x1 = []            y1 = []            for node in way.get_nodes(True):                print(                    f'lon: {float(node.lon):3.4f}; lat: {float(node.lat):3.4f}')                x1.append(float(node.lon))                y1.append(float(node.lat))            x.append(x1)            y.append(y1)    xy = [x, y]    with open('data.txt', 'w') as f:        json.dump(xy, f)def readDate():    with open('data.txt', 'r') as f:        return json.load(f)getData()data = readDate()last = Nonefirst = Noned = []k = [[], []]m = []while(len(data[0]) > 0):    if last == None and first == None:   # Make sure that there are no "ways" at the beginning or end that match the line.        last = [data[0][0][-1], data[1][0][-1]] # Get first and last point of a new line        first = [data[0][0][0], data[1][0][0]]        k[0] = k[0] + data[0][0] # Start the new line        k[1] = k[1] + data[1][0]        data[0].pop(0) # Drop the way        data[1].pop(0)     for j in range(0, len(data[0])): # Check all lines        if first == [data[0][j][-1], data[1][j][-1]]: # If the first ...            print(f'First {first[0]}; {first[1]}')            k = [data[0][j] + k[0], data[1][j] + k[1]]            first = [data[0][j][0], data[1][j][0]]            data[0].pop(j)            data[1].pop(j)            break        if last == [data[0][j][0], data[1][j][0]]: # or the last point continue the current line            print(f'Last  {last[0]}; {last[1]}')            k = [k[0] + data[0][j], k[1] + data[1][j]] # Add the segment to the new line            last = [data[0][j][-1], data[1][j][-1]] # Set the point new last point            data[0].pop(j) # Drop the way            data[1].pop(j)            break        if j == len(data[0])-1: # When the for-loop reaches the end, there is no "way" that continue the line            m.append(k)            k = [[], []]            first = None            last = None    if len(data[0]) == 1: # If the last remaining line is a small island, just add it.        k = [data[0][0], data[1][0]]        m.append(k)        data[0].pop(0)        data[1].pop(0)for i in range(0, len(m)):    plt.plot(m[i][0], m[i][1], label=f'Denmark')plt.show()该算法以尽可能创建多边形的方式排列 API 中的“方式”。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python