【问题标题】:Python: Obtaining elevation from latitude and longitude valuesPython:从纬度和经度值获取海拔
【发布时间】:2021-07-31 01:52:03
【问题描述】:

首先,有这个问题的代码。但是,它似乎只适合美国。如他们的网站 (https://nationalmap.gov/epqs/) 所述,当无法找到值时,它将返回 -1000000,这是我的情况。

我正在尝试在瑞典获得海拔。

使用此示例数据:

lat = [57.728905, 57.728874, 57.728916, 57.728836, 57.728848]
lon = [11.949309, 11.949407, 11.949470, 11.949342, 11.949178]

# create df
df = pd.DataFrame({'lat': lat, 'lon': lon})

我怎样才能使下面的代码适应全球,而不仅限于美国?或者至少,有没有办法让我把注意力集中在瑞典? USGS不应该有全球数据吗?

def make_remote_request(url: str, params: dict):
   """
   Makes the remote request
   Continues making attempts until it succeeds
   """

   count = 1
   while True:
       try:
           response = requests.get((url + urllib.parse.urlencode(params)))
       except (OSError, urllib3.exceptions.ProtocolError) as error:
           print('\n')
           print('*' * 20, 'Error Occured', '*' * 20)
           print(f'Number of tries: {count}')
           print(f'URL: {url}')
           print(error)
           print('\n')
           count += 1
           continue
       break

   return response


def elevation_function(x):
   url = 'https://nationalmap.gov/epqs/pqs.php?'
   params = {'x': x[1],
             'y': x[0],
             'units': 'Meters',
             'output': 'json'}
   result = make_remote_request(url, params)
   return result.json()['USGS_Elevation_Point_Query_Service']['Elevation_Query']['Elevation']

运行函数:

df['elevation'] = df.apply(elevation_function, axis=1)


# Print output
df

源码:Obtain elevation from latitude longitude coordinates with a simple python script

更新:

使用已接受答案中的建议并在海拔函数中添加 time.sleep(1),我可以获取所有观测值的海拔数据。请注意,此 API 每个请求仅允许 100 个位置。因此,对于更多的行数,必须将其分解为不同的请求。

【问题讨论】:

  • 服务很可能无法在您指定的请求点找到数据。

标签: python json coordinates geopandas


【解决方案1】:

我一直在使用opentopodata.org 的 api 来获取海拔值。 您可以使用覆盖整个瑞典的EU-DEM 数据集。 API 请求如下所示:

https://api.opentopodata.org/v1/eudem25m?locations=57.728905,11.949309

另一个海拔 API 可以在 https://open-elevation.com/ 找到。请求看起来非常相似:

https://api.open-elevation.com/api/v1/lookup?locations=57.728905,11.949309

因此调整您的elevation_function

def elevation_function(x):
   url = 'https://api.opentopodata.org/v1/eudem25m?'
   # url = 'https://api.open-elevation.com/api/v1/lookup?'
   params = {'locations': f"{x[0]},{x[1]}"}
   result = make_remote_request(url, params)
   return result.json()['results'][0]['elevation']

【讨论】:

  • 感谢提供源码!但是,我收到一个错误:---> 30 return result.json()['results'][0]['elevation'] KeyError: 'results'
  • 你的脚本适合我,所以我想这很可能是由免费 API 的CORS policy 引起的。它阻止跨域请求。我在答案中添加了一个不同的免费海拔 API 端点。以前没用过,不过好像包含Access-Control-Allow-Origin: * header
  • 现在我得到一个不同的错误:``` ~/opt/anaconda3/lib/python3.7/json/decoder.py in raw_decode(self, s, idx) 353 obj, end = self.scan_once(s, idx) 354 除了 StopIteration as err: --> 355 raise JSONDecodeError("Expecting value", s, err.value) from None 356 return obj, end JSONDecodeError: Expecting value: line 1 column 1 (字符 0) ```
  • 另外,仅仅 4 次观察(也许 2 分钟?)似乎花费了太长时间。这正常吗?
  • 更新:当使用您的第二个 API 建议时,我注意到我犯了一个错误。现在不需要那么长时间了。但是,它将高程值四舍五入为 4。在您的图像中,您可以看到高程值略有不同。我可以调整小数位还是不能从 API 更改? (第一次使用)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
  • 1970-01-01
  • 2021-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多