尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
百度地图API批量地址转坐标:Excel处理与坐标系避坑指南
简介面向Web开发与GIS数据处理场景的百度地图API地址批量转换工具基于前端页面实现Excel表格上传、地理编码批量解析与经纬度回填同时涉及GCJ-02、BD-09等坐标系转换与地图撒点展示适合需要处理大量地址数据的产品、运营或开发者直接复用。压缩包共4个文件包括jQuery与xlsx.core.min.js两个JavaScript库、一个index.html主页面和一份dz.xlsx示例数据整体体积仅375KB结构简洁导入浏览器即可快速测试。已有4433人学习下载。通过该包可获得完整的前端批量转换方案借助xlsx库解析Excel调用百度地图API完成地址到坐标的转换并自动生成可下载结果文件HTML页面中还包含地图撒点示例便于理解坐标展示逻辑。对物流配送、门店分布分析、热力图制作等应用场景有直接参考价值也可作为学习百度地图JavaScript API与坐标系转换的入门案例。1. 百度地图 API 地址批量转坐标这对 Excel 批量处理意味着什么手头有一张两万行的 Excel里面是从各系统汇总来的中文收货地址要把它全部换成经纬度投到地图上看分布人工一个个查能查到怀疑人生通用代码一股脑拉去请求又容易撞上坐标漂移、限流和地址解析不全。这份资源解决的就是这个链条读取 Excel 地址列、批量调用百度地图 API 地理编码服务、把经纬度和匹配状态写回新表地址清洗、并发限速、失败重试、断点续传这些事都提前处理过。适合做门店选址、物流调度、空间数据清洗的工程师也适合 GIS 方向的学生拿真实数据练手省去从零搭一遍的功夫。2. 坐标系与鉴权所有批量转坐标脚本绕不开的两道门槛2.1 BD-09 坐标系为什么转完坐标一换底图就漂移百度地图 API 返回的经纬度用的是 BD-09 坐标系这是在地理加密坐标系GCJ-02基础上又做了一层偏移处理。拿这套坐标直接投到高德或者卫星底图上位置通常会偏出几十米到上百米而且偏移方向不固定看起像是到处乱偏。很多第一次跑批量转换的开发者会在这里卡住以为是地址匹配错了实际是坐标系不一致。如果你的项目只在百度地图底图上展示那直接用返回坐标没问题。但多数场景是地址数据最终要进业务系统、给 ECharts 画散点、或叠加到第三方底图上这时就必须把 BD-09 转回 GCJ-02 或 WGS-84。百度地图 API 本身提供坐标转换接口但批量转码时每次多一次请求就多花一份配额和时间本地直接做数学转换更划算。资源包里通常自带了转换模块核心逻辑就是下面这套公开算法import math # 常量GCJ-02 加密使用的地球参数 A 6378245.0 EE 0.00669342162296594323 X_PI math.pi * 3000.0 / 180.0 def _gcj02_delta(lng, lat): 计算 GCJ-02 与 WGS-84 之间的偏移量 x lng - 105.0 y lat - 35.0 d_lat -100.0 2.0 * x 3.0 * y 0.2 * y * y 0.1 * x * y d_lat 0.2 * math.sqrt(abs(x)) d_lat (20.0 * math.sin(6.0 * x * math.pi) 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0 d_lat (20.0 * math.sin(y * math.pi) 40.0 * math.sin(y / 3.0 * math.pi)) * 2.0 / 3.0 d_lat (160.0 * math.sin(y / 12.0 * math.pi) 320.0 * math.sin(y * math.pi / 30.0)) * 2.0 / 3.0 d_lng 300.0 x 2.0 * y 0.1 * x * x 0.1 * x * y d_lng 0.1 * math.sqrt(abs(x)) d_lng (20.0 * math.sin(6.0 * x * math.pi) 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0 d_lng (20.0 * math.sin(x * math.pi) 40.0 * math.sin(x / 3.0 * math.pi)) * 2.0 / 3.0 d_lng (150.0 * math.sin(x / 12.0 * math.pi) 300.0 * math.sin(x / 30.0 * math.pi)) * 2.0 / 3.0 rad_lat lat / 180.0 * math.pi magic math.sin(rad_lat) magic 1 - EE * magic * magic sqrt_magic math.sqrt(magic) d_lat (d_lat * 180.0) / ((A * (1 - EE)) / (magic * sqrt_magic) * math.pi) d_lng (d_lng * 180.0) / (A / sqrt_magic * math.cos(rad_lat) * math.pi) return d_lng, d_lat def bd09_to_gcj02(bd_lng, bd_lat): BD-09 转 GCJ-02 x bd_lng - 0.0065 y bd_lat - 0.006 z math.sqrt(x * x y * y) - 0.00002 * math.sin(y * X_PI) theta math.atan2(y, x) - 0.000003 * math.cos(x * X_PI) return z * math.cos(theta), z * math.sin(theta) def gcj02_to_wgs84(gcj_lng, gcj_lat): GCJ-02 转 WGS-84用两次迭代逼近 lng, lat gcj_lng, gcj_lat for _ in range(2): d_lng, d_lat _gcj02_delta(lng, lat) lng gcj_lng - d_lng lat gcj_lat - d_lat return lng, lat这段代码的逻辑是先算出 GCJ-02 相对 WGS-84 的偏移量然后从 BD-09 反向减掉自己的第一层偏移再套用 GCJ-02 的标准偏移公式。_gcj02_delta里的三角函数用于修正不同纬度上的偏移幅度直接抄公式容易抄错建议以资源包内的文件为准跑通后用一条你知道准确位置的地址做验证。提示这套本地转换算法适用于绝大多数业务场景误差在米级。如果做测绘级应用还是走官方坐标转换接口别省这个请求。如果你的数据最终只在百度底图上展示那这一步可以直接跳过不用转。怕的是中途换了底图所以建议转换函数保留在脚本里需要时一键切换。2.2 ak 校验方式从手动签名到白名单先把一条请求跑通百度地图开放平台的鉴权方式早期用手动 SN 签名后来逐步迁到 ak 校验加域名/IP 白名单。旧示例代码里那一堆 md5 拼接签名的写法现在已经不推荐了资源包里如果还有这种代码建议绕开。现在的流程是在控制台创建应用拿到一个 akAPI Key然后在应用设置里配置白名单请求时把 ak 放在参数里带上。最容易踩的坑是白名单方向搞反。控制台里服务端应用用的是 IP 白名单或域名白名单浏览器端应用用的是 referer 白名单。跑本地脚本属于服务端场景你如果创建成了浏览器端应用批量一跑就返回权限类错误。另外本地调试时如果你的出口 IP 经常变配一次 IP 白名单可能没几天就失效调试阶段可以先不配跑通后再锁白名单。先手动 curl 一条请求验证链路比直接写批量脚本靠谱得多curl -G https://api.map.baidu.com/geocoding/v3/ \ --data-urlencode address某市某区某路测试点 \ --data-urlencode city某市 \ --data-urlencode outputjson \ --data-urlencode ak你的ak | jq .result.location这里--data-urlencode会自动做 URL 编码避免中文字符在 shell 里被截断。address是详细地址city是城市限定词用于减少同名街道的歧义outputjson指定返回格式ak换成你控制台里创建的那个值。返回结果里能看到location字段下的lng和lat就说明链路通了。如果这一步返回非 0 状态码优先检查 ak 有没有抄错、应用类型对不对、白名单配没配。链路通了再进批量环节否则后面所有排错都会被放大。3. Excel 地址清洗与请求构造跳过这一步解析成功率至少掉两成3.1 地址清洗合并单元格、全角空格与拼接顺序拿到手的地址表很少是干净的单列数据。常见情况是省、市、区、详细地址分成好几列得先拼起来有的表里地址带全角空格、换行符、tab 符还有的地址列是公式生成的读出来是空的。这些脏数据如果不处理地理编码接口会返回不精确匹配甚至直接在状态码里报参数错误。第一步读取时建议用 pandas 读 xlsx并强制把整列读成字符串避免某些地址被读成数字或日期import pandas as pd # data_onlyTrue 才能取到公式的缓存值否则读到的是公式字符串 df pd.read_excel(地址表.xlsx, dtypestr, keep_default_naFalse, data_onlyTrue) # 有合并单元格的表读出来只有左上角第一个非空需要向下填充 df[[省, 市, 区]] df[[省, 市, 区]].ffill() # 按 省 市 区 详细地址 的顺序拼接 df[地址] ( df[省].str.strip() df[市].str.strip() df[区].str.strip() df[详细地址].str.strip() ) def clean_addr(s): 全角空格转半角清理换行和连续空白 s s.replace( , ).replace(\n, ).replace(\t, ).replace(\r, ) return .join(s.split()).strip() df[地址] df[地址].map(clean_addr)这段代码里ffill()解决的是合并单元格问题pandas 读取合并区域时只有左上角有值往下都是空串ffill()会把上一个非空值沿列方向往下填充。keep_default_naFalse保证地址里的空字符串不会被变成NaN。join内部split的写法是把连续空白合并成一个空格比单纯strip()更彻底。拼接顺序上有个细节如果原表省列已经带省字但市列不带市字拼出来的地址可能是某省某这种残缺形态补字逻辑要放在清洗函数里。资源包里一般会把拼接规则做成可配置的你只要改列名映射就行。3.2 构造地理编码请求直接拼 URL 很容易翻车很多新手写请求时喜欢用字符串拼接把 URL 串出来遇到地址里有#、、中文标点时会出各种怪问题。正确做法是把参数交给 requests 库的params参数处理它会自动做百分号编码。import requests GEOCODE_URL https://api.map.baidu.com/geocoding/v3/ def geocode(address, city, ak你的ak): params { address: address, city: city, output: json, ak: ak, ret_coordtype: gcj02ll, # 直接要 GCJ-02 坐标省去后续手动转码 } resp requests.get(GEOCODE_URL, paramsparams, timeout5) data resp.json() if data.get(status) 0: loc data[result][location] precise data[result].get(precise, -1) return loc[lng], loc[lat], precise return None, None, data.get(status)参数说明ret_coordtypegcj02ll是可选参数加了之后接口直接返回 GCJ-02 坐标系省掉第 2 章的本地转换步骤如果你后续要在百度底图上展示就不加这个参数返回默认的 bd09ll。注意全流程统一不要这条请求返回 bd09ll、那条返回 gcj02ll后面处理坐标会乱成一锅粥。timeout5是硬性要求不设超时的话某条请求卡住会拖垮整个批量任务。函数返回值统一成三元组成功时precise表示匹配精度失败时第三个元素是接口返回的错误状态码。有这么一条小函数批量脚本就有地基了。第 4 章开始在这个函数外面套并发和重试逻辑。4. 批量请求的并发与限速几万条地址不能一把梭哈4.1 单线程同步循环能跑但慢得让人怀疑人生最简单的批量写法是 for 循环逐条调用第 3 章的geocode函数每调用一次就写回一行。这个方案不是不能跑是一万条地址跑起来真的等到花儿都谢了。地理编码单次请求大概 100-200 毫秒加上你主动 sleep 限速一万条基本要 25-40 分钟。如果跑到一半撞上限流前面的时间全白花。import pandas as pd import time df pd.read_excel(待转换地址.xlsx, dtypestr) df[经度] df[纬度] df[匹配状态] for idx, row in df.iterrows(): lng, lat, status geocode(row[地址], row.get(城市, ), ak) df.at[idx, 经度] lng df.at[idx, 纬度] lat df.at[idx, 匹配状态] status time.sleep(0.1) # 控制请求频率最多约 10 QPS这个写法的问题在于串行等待前一个请求还没回来后一个就不能发。对一万条数据来说这个方案勉强能用但效率确实低。另一个隐患是iterrows()本身很慢它每次要构造一个 Series行数多的时候 pandas 自身开销比请求还大。换成itertuples()会更快但可读性差一点这里先不展开。4.2 并发限速与断点续传把配额吃满又不被拉黑真正能跑的批量脚本要做两件事一是用线程池并发发请求二是用信号量控制并发数避免超过接口的 QPS 配额。百度地图 API 对并发有限制超过配额不是报错而是直接限流或者返回异常所以控制节奏比拼命加速更重要。import concurrent.futures import threading import time import pandas as pd MAX_QPS 10 # 按你账号的配额来宁可保守一点 THREADS 4 # 并发线程数受 QPS 约束 SEMAPHORE threading.Semaphore(MAX_QPS) ak 你的ak def limited_geocode(address, city): with SEMAPHORE: result geocode(address, city, ak) time.sleep(1.0 / MAX_QPS) # 保证平均 QPS 不超过上限 return result df pd.read_excel(待转换地址.xlsx, dtypestr) df[经度] df[纬度] df[匹配状态] # 跳过已完成的行实现断点续传 df df[df[经度].isna() | (df[经度] )].copy() with concurrent.futures.ThreadPoolExecutor(max_workersTHREADS) as pool: future_map { pool.submit(limited_geocode, row[地址], row[城市]): idx for idx, row in df.iterrows() } for future in concurrent.futures.as_completed(future_map): idx future_map[future] lng, lat, status future.result() df.at[idx, 经度] lng df.at[idx, 纬度] lat df.at[idx, 匹配状态] status df.to_excel(转换结果.xlsx, indexFalse)核心在三行Semaphore(MAX_QPS)限制了同时处于请求中的任务数sleep(1.0 / MAX_QPS)把平均请求频率压到配额以内as_completed保证先完成的先写回。断点续传的逻辑是读入 Excel 后先过滤掉已经有经纬度的行只处理空行这样跑挂了重新跑一次已完成的行不会重复请求省配额也省时间。参数推荐值说明MAX_QPS10地理编码接口的并发配额按账号实际调整THREADS4-8并发线程数调大不一定更快受 QPS 限制TIMEOUT5 秒单条请求超时防止卡死拖垮整批RETRY3 次失败重试次数配合退避使用注意QPS 以你账号当前配额为准。建议先用 2 QPS 小批量试跑 100 条确认稳定之后再调高别一上来就拉满。跑完以后记得把结果里的匹配状态列过一眼非 0 状态的行就是失败条目这些会在第 6 章讲怎么二次补救。5. 避坑与排查五个高频翻车点挨个记下来5.1 ak 明明填了批量一跑全是权限类错误现象单条 curl 测试能通批量脚本跑起来返回一堆状态码 2、4、5看起来全是权限和配额问题。原因本地调试的出口 IP 不在 IP 白名单里或者控制台里创建应用时选了浏览器端服务端脚本却用了 referer 校验两者对不上。解决在控制台把应用类型改成服务端调试阶段把 IP 白名单暂时放宽跑通逻辑之后再把白名单锁死。如果公司出口 IP 是动态的建议直接配域名白名单省去 IP 变动的麻烦。5.2 经纬度都返回了换成高德底图整体偏移现象坐标没有一条报错但放到高德地图底图上所有点都偏了几十到几百米方向还不一致。原因百度地图返回的是 BD-09 坐标系高德用的是 GCJ-02Google 卫星图是 WGS-84三者之间不是简单平移是带位置相关的非线性偏移。解决用第 2 章的转换函数把 BD-09 转成目标坐标系或者在请求时加ret_coordtypegcj02ll参数。注意如果数据要流出给 GPS 设备用还得继续从 GCJ-02 转到 WGS-84做两层转换。5.3 地址明明存在解析结果却匹配到隔壁区现象同一条路有的地址精确到门牌号有的只匹配到区甚至跑到同名乡镇去。原因地址里缺省市区限定出现同名道路时接口按省去猜猜错就不奇怪。还有一个常见原因清洗时把原本有用的行政前缀误删了。解决city参数必填拼接地址时保留省市区前缀不要为了看起来干净把行政层级砍掉。同名严重的区域可以把city写成省市的完整形式例如某省某市。5.4 pandas 读 Excel 读出一堆空行和公式现象两万多行的地址表读进 DataFrame 只剩几千行有值一半以上是空串。原因原表里有合并单元格pandas 只会保留左上角那个值地址列是公式生成的直接读拿到的是公式文本而不是计算结果。解决读取时加data_onlyTrue取公式缓存值合并单元格用ffill()向下填充。如果ffill()把不该填的列也填了先只对省市区这几列做填充再合并。5.5 跑了一半突然连续超时现象日志里全是 timeout重试也超时看起来像接口挂了。原因短期内并发打太高触发了接口的限流熔断重试策略太激进接口还没恢复就持续打加重了熔断。解决把 QPS 降到配额的一半左右重试用指数退避连续失败超过 10 条直接冷却 60 秒再继续。别小看这个冷却它往往决定了整个批次能不能跑完。6. 结果验证与二次降级把整体解析成功率抬到九成以上6.1 逆地理回查拿坐标反查地址交叉验证批量结果批量转完坐标第一件事不是急着存库而是抽检。最常见有效的办法是随机抽 20 条调逆地理编码接口把坐标反查成地址再和原始地址做行政区一致性比对。如果 20 条里有 3 条以上对不上区那这批结果的坐标系或者city参数大概率有问题得回头排查。def reverse_geocode(lng, lat, ak): params { location: f{lat},{lng}, coordtype: gcj02ll, # 和批量转换时的坐标类型保持一致 output: json, ak: ak, } resp requests.get(https://api.map.baidu.com/reverse_geocoding/v3/, paramsparams, timeout5) data resp.json() if data.get(status) 0: return data[result].get(formatted_address, ) return 抽检逻辑很简单从结果 Excel 里随机取 20 行调reverse_geocode拿到反查地址再手写一个字符串比对函数看反查地址里是否包含原始地址的区级地名。注意coordtype参数必须和批量请求里的ret_coordtype或者你手动转码后的坐标系一致否则反查出来的地址同样会漂。6.2 二次降级匹配与质量报告抽检通过后把上一轮匹配状态非 0 的行捞出来做二次补救。常见做法是按优先级降级重试先用原地址加省市区前缀试一次不行就只用市详细地址再不行去掉地址里的特殊符号和数字最后仍然失败的单独导出人工处理。降级逻辑可以写在一个重试循环里每轮之间加 1 秒等待避免对同一批地址在短时间连续打接口。最后汇总一份质量报告记录总数、成功数、失败数、平均耗时、失败清单路径。这一份报告是你交付给下游同事最有力的说明也方便下次拿到新数据时对比解析质量是否稳定。从那以后我每次拿 Excel 批量转坐标都会先抽 20 条做逆地理回查再放量跑跑完顺手对齐一次失败清单这个习惯把交付返工率压得很低希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

从粉丝动机到内容推荐逻辑:涨粉增长的完整运营框架

从粉丝动机到内容推荐逻辑:涨粉增长的完整运营框架

1. 我从后台数据里看见的“我的粉丝”做内容这几年,后台私信里被问得最多的一句话不是“你这个怎么做”,而是“你粉丝怎么来的”。说实话,每次看到这个问题我都得愣一下,因为我自己也没有一个标准答案。粉丝从来不是靠某一个爆款突…

📅 2026/10/19 5:50:43
Blender模型导入JME全流程:坐标、材质、碰撞与性能优化

Blender模型导入JME全流程:坐标、材质、碰撞与性能优化

简介:面向Java游戏开发与3D动画学习者的JMonkeyEngine入门资源,基于Blender制作3D鱼类模型与游动、转身动画,在JMonkeyEngine中实现物理、碰撞与键盘交互控制,覆盖从模型制作到引擎集成的完整流程。资源共254个文件,包…

📅 2026/10/19 5:50:43
图像边缘检测算法实战:Sobel、Laplacian、Canny原理与OpenCV实现

图像边缘检测算法实战:Sobel、Laplacian、Canny原理与OpenCV实现

简介:这份基于 Visual Studio 2015 开发的图像边缘检测算法 Demo,面向图像处理初学者与计算机视觉入门者,用于在 Windows 10 x64 环境下直观学习 Sobel、Canny 等边缘检测原理,并可与灰度化、二值化、滤波、锐化等预处理步骤联动对…

📅 2026/10/19 5:50:43
MORE NEWS

更多资讯

📰

基于YOLOv26的绝缘子缺陷检测系统:从数据到部署全流程实践

电力绝缘子缺陷检测这几年在巡检圈子里真的是绕不开的话题,输电线路上的绝缘子数量大、分布广,尤其是山区和林区的杆塔,人工巡检一趟成本极高,而且很多缺陷在肉眼看来并不明显。我这次要分享的,是同事前段时间做的一个…

📰

作业车间调度中深度强化学习状态特征设计实战与避坑指南

作业车间调度是制造系统里最经典的优化问题之一。这些年我一直在帮工厂做排产相关的算法落地,最深的体会是:调度算法从理论到能用,中间隔着一条叫"状态表达"的河。模型选得再花哨,超参调得再好,状态特征设计…

📰

视频智能分析算法实战:从模型选型到部署优化的关键细节

这些年做视频智能分析算法,从最早的帧差法、背景建模,到现在的深度学习端到端推理,技术路线换了好几代,踩过的坑也足够写一本小册子了。视频智能分析算法,说白了就是让计算机"看懂"摄像头画面里正在发生什么…

📰

Qt5 WebEngine SEO行为模拟实验框架

简介:本资源是一套基于Qt5框架开发的SEO快排点击软件源码,面向具备C和Qt基础的开发者,用于研究黑帽SEO中模拟用户点击行为的技术实现原理。代码通过多浏览器UA切换、随机停留与点击逻辑、网络请求调度等机制,尝试影响搜索引擎对目…

📰

Gemma 4本地部署实战指南:从硬件评估到参数调优

1. 为什么要在本地跑 Gemma 4:价值与适用场景1.1 本地部署解决的三大核心问题把 Gemma 4 跑在本地,这件事本身就有很强的吸引力。先说一个大白话结论:大模型本地部署不是你非得有八张专业显卡才能碰的领域。Gemma 4 属于开放权重模型里对消费…

📰

二自由度横摆动力学与自适应参数MPC路径跟踪控制

做自动驾驶路径跟踪的人,基本都会遇到一个尴尬场景:同一套MPC参数,在低速园区绕个圆道又稳又准,车速一旦提到80甚至120,过连续弯道就明显开始抖,要么横向误差变大,要么方向盘来回修正。这个问题…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬