赞
踩
通常来说,高程数据的获取途径有以下两个:
1、如果有全球/全国DEM数据,可以在arcgis中获取点的value值,即为高程值。
2、在科学上网的前提下,通过谷歌地图右下角可以查询。
本文介绍一个以Python
为技术手段查询/批量查询的方法:
这个API接口的限制如下图所示,每秒最大发送一次请求,每次请求最多查询100个地址,每天最多发送1000次请求,也就是说每天可以查询10万次,足够科研/学习所用。
import json
import time
from typing import List
import requests
import pandas as pd
class GetElevation:
@classmethod
def __SendQuery(cls, latLngString: str) -> json:
query = ('https://api.opentopodata.org/v1/mapzen?locations={}&interpolation=bilinear'.format(latLngString))
res = requests.get(query).json()
if res["status"] != "OK":
raise Exception(res["error"])
return res
def GetSingleElevation(self, latitude: float, longitude: float) -> float:
"""
获取单个高程,输入经纬度格式为数值类型,返回值为高程float类型
:param latitude: 纬度
:param longitude: 经度
:return: 高程
"""
if latitude < -90 or latitude > 90:
raise Exception("纬度的范围应在-90-90之间!请检查数据源!")
latLngString = str(latitude) + "," + str(longitude)
res = self.__SendQuery(latLngString)
elevation = res["results"][0]["elevation"]
return elevation
def GetMultiElevation(self, latitude: List[float], longitude: List[float]) -> List[float]:
"""
获取数组类型的高程,输入经纬度格式为经度数组和纬度数组,返回值为高程数组
:param latitude:纬度数组
:param longitude:经度数组
:return:高程数组
"""
if len(latitude) != len(longitude):
raise Exception("纬度数组和经度数组长度不一致!请检查数据源!")
for lat in latitude:
if lat < -90 or lat > 90:
raise Exception("纬度的范围应在-90-90之间!请检查数据源!")
elevationList = []
hundredNums = len(latitude) // 100
# 查询整百的高程
for i in range(hundredNums):
latLngString = ""
for idx in range(100 * i, 100 * (i + 1)):
latLngString += (str(latitude[idx]) + "," + str(longitude[idx]) + "|")
res = self.__SendQuery(latLngString)
for idx in range(100):
elevationList.append(res["results"][idx]["elevation"])
time.sleep(1)
# 查询剩余的不到100的高程
latLngString = ""
for i in range(hundredNums * 100, len(latitude)):
latLngString += (str(latitude[i]) + "," + str(longitude[i]) + "|")
res = self.__SendQuery(latLngString)
for i in range(len(latitude) - hundredNums * 100):
elevationList.append(res["results"][i]["elevation"])
return elevationList
def ExportToXlsx(self, latLongDf: pd.DataFrame, elevationList: List[float], outputPath: str) -> None:
"""
如果用户可以传入一个DataFrame数据,可以将返回得到的高程拼接并输出
:param latLongDf: DataFrame数据
:param elevationList: 高程数组
:param outputPath: 输出路径
:return: 无返回值
"""
latLongDf["elevation"] = elevationList
latLongDf.to_excel(outputPath, index=False)
在实例化对象之后,调用GetSingleElevation
方法,传入纬度和经度,即可得到返回值,即高程数据
if __name__ == "__main__":
ele = GetElevation()
# 单个查询
singleEle = ele.GetSingleElevation(50, 112)
print(singleEle)
在实例化对象之后,从本地导入数据或者直接定义纬度和经度数组(注意:输入类型为数组),调用GetMultiElevation
方法,传入两个数组,即可得到返回的高程数组。
初次之外,如果是通过pandas
读取的DataFrame
类型的数据可以调用ExportToXlsx
方法,将其导出到本地。
if __name__ == "__main__":
ele = GetElevation()
# 批量查询
latLongDf = pd.read_excel(r"C:\Users\wzj\Desktop\工作簿1.xlsx")
multiEle = ele.GetMultiElevation(latLongDf["lat"], latLongDf["lng"])
print(multiEle)
# 导出到本地excel
ele.ExportToXlsx(latLongDf, multiEle, r"C:\Users\wzj\Desktop\工作簿1.xlsx")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。