基于Python的单次/批量高程查询

通常来说,高程数据的获取途径有以下两个:
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")
  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HydroCoder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值