我能否使用Python的geopy库获取经纬度相关的海拔高度?

11

这是可能的吗?

我尝试过:

from geopy.point import Point
from geopy import geocoders
[...]
p = Point(Latitude, Longitude)
lat, lon, altitude = p
height_metres = altitude

但是 height_metres 总是为 0。

4个回答

18

请注意,使用地理编码器需要一个谷歌高程API密钥,该密钥现在需要启用计费的项目(截至2018年7月)。

作为替代方案,您可以使用开放的高程公共API。以下是一个返回海拔的示例函数(请注意,Python 3.6用于字符串格式化):

import requests
import pandas as pd

# script for returning elevation from lat, long, based on open elevation data
# which in turn is based on SRTM
def get_elevation(lat, long):
    query = ('https://api.open-elevation.com/api/v1/lookup'
             f'?locations={lat},{long}')
    r = requests.get(query).json()  # json object, various ways you can extract value
    # one approach is to use pandas json functionality:
    elevation = pd.io.json.json_normalize(r, 'results')['elevation'].values[0]
    return elevation

请注意,该API可能会在未来发生变化,我无法对数据的可靠性进行评论,但目前它是与Google不错的选择,并且简单测试表明其运行良好。


1
如果我间歇性地查询纬度和经度,代码就可以正常工作。但是,一旦我尝试连续使用它来填充一个系列,我会得到“JSONDecodeError:('Expecting value: line 1 column 1 (char 0)','occurred at index 0')”错误。这可能不是你的错,但我想指出这一点。 - Bn.F76
这个可以工作,但是偶尔会出现@Bn.F76指出的错误,并且有时候也会有点慢。我猜这可能是服务器问题。 - Vasco Cansado Carvalho
我与 open-elevation 的开发人员没有任何关联,但从他们的文档中可以看出,建议您一次请求多个位置,这可能会解决上述问题。 GET api 有限制,但他们建议改用 POST api。https://github.com/Jorl17/open-elevation/blob/master/docs/api.md - Iain D

9

使用geocoder而不是geopy可以实现此功能:

# pip install geocoder
>>> import geocoder
>>> g = geocoder.elevation('<address or [lat,lng]>')
>>> print (g.meters)

3
这需要一个API密钥。 - Vasco Cansado Carvalho
正如Vasco所说,如果您不这样做,它会引发“ValueError:提供API密钥”的错误。 - gnoodle

3
如果geopy知道地球上每个点的海拔高度,我会吃掉我的袜子。这是不可能的(据我所知),除非进行一些复杂的GoogleEarth/其他数据库搜索来确定海拔高度。 lat, lon, altitude = p之所以可行,是因为Point有一个海拔高度属性。根据源代码,构造函数中修改海拔高度的唯一时间是在这一行:altitude = float(altitude or 0),但这并没有获得海拔高度。

谢谢你的评论!但是Python没有其他方法吗?有很多网站可以粘贴纬度/经度并返回高度。 - Sven Wiesel

0
可以通过Open Topo Data实现。它提供了免费的公共API,用于不同的数据集。试试看,例如https://api.opentopodata.org/v1/aster30m?locations=53.66,13.84。在Python中,可以这样实现。
import requests

lat, lon = (53.66, 13.84)
url = f"https://api.opentopodata.org/v1/aster30m?locations={lat},{lon}"
r = requests.get(url)

data = r.json()
print(data)

给出(为了易读性的格式):

{
  "results": [
    {
      "dataset": "aster30m",
      "elevation": 9,
      "location": {
        "lat": 53.66,
        "lng": 13.84
      }
    }
  ],
  "status": "OK"
}

直接获取海拔高度:
elevation = data['results'][0]['elevation']
print(elevation)

打印
9

当使用eudem25m数据集而不是aster30m时,你会得到4.061931610107422
对于一个Python示例,如果你有很多坐标在一个Pandas的DataFrame中,可以参考我的Stack Overflow回答here

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接