ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

百度地图经纬度打印全攻略:从手动拾取到API批量输出

2026/9/10 10:19:35 拓冰建站 浏览量
百度地图经纬度打印全攻略:从手动拾取到API批量输出 干这行最常被问到的需求里“把这个地点的经纬度打出来”看似是个小活真做起来能绕进去一整天。最近又要整理一批门店坐标我顺手把百度地图打印经纬度的几种方式从头到尾捋了一遍从手动拾取、页面点击取点到JS API的console输出、批量地理编码再到纸面打印的排版处理把踩过的坑也都记了下来。这篇东西没有绕弯子全是实际操作里能直接照抄的内容适合前端开发、地图数据整理、门店运营和搞GIS二次开发的同行参考。1. 这个需求到底在解决什么问题1.1 一句“打印经纬度”背后的真实诉求先说个常被误解的点。“打印经纬度”在很多场景下并不是真的要按CtrlP把地图打成纸而是指把经纬度信息从地图系统中提取出来以文本、日志、表格或标签的形式输出。我在日常项目里接到过几种典型诉求前端调试页面上集成了百度地图需要点击地图任意位置立刻在控制台打印出对应的经度、纬度用来做点位标注和联动查询。运营导数据外包同学拿了一张Excel里面只有门店名称和地址需要在百度地图上找到每个店的位置再把经纬度填回去做成一张报表打印给领导看。批量建点几十个地址要转成经纬度并入数据库写个定时脚本每天喝一次数据输出成日志方便排查。纸面归档工程巡检记录、户外活动路线表、资产管理位置清单最终要打印在纸质表格上坐标只是其中一列。所以第一步就是搞清楚你要的“打印”到底是控制台输出、页面展示、导出文件还是纸质排版。不同目标对应的工具和代码差别很大但核心数据只有一个——经纬度。理解了这一点后面每个方案都能看懂。1.2 谁需要这份操作清单我按人群和核心方案整理了一张对应表方便你在看正文之前直接跳到自己关心的部分。使用人群典型场景推荐方案前端/地图开发地图点击取点、调试定位百度地图JS API console看第3章运营/产品把地址转成坐标并导出报表坐标拾取器手动整理看第2章数据/爬虫工程师批量地址转经纬度地理编码API Python看第4章测绘/GIS方向从链接或二维地图中提取坐标分享链接解析、坐标转换看第5章和第6章2. 偷懒方案用坐标拾取器手动取点并打印2.1 坐标拾取器的正确用法如果只有一个或几个地点要处理没必要写代码直接用百度地图官方的坐标拾取系统就行。入口是百度地图开放平台里的“坐标拾取器”地址是https://api.map.baidu.com/lbsapi/getpoint/index.html。打开之后页面逻辑很简单在顶部搜索框输入地点名称比如“北京西站”。地图定位到该区域后点击地图上的具体位置也可以拖动红色气泡微调。页面右侧或底部会实时显示一组坐标格式通常是“经度,纬度”比如116.328154,39.894915。点击坐标旁边的复制按钮把内容粘贴到记事本、Excel或自己维护的数据库里。这里有个细节气泡放在不同位置坐标完全不同。同一个“北京西站”如果搜索出来的是公交枢纽你点的是北广场实际经纬度会差非常多。手动取点一定要放大到能看到目标建筑物轮廓再慢慢拖动气泡对齐到你要的那个门口。别嫌麻烦坐标精度不够后面做门店距离计算、配送范围圈选都会跟着错。还有一个容易被忽略的点直接按CtrlP打印这个页面生成出来的纸质文件通常很难看。原因是百度地图瓦片是动态加载的浏览器打印时不一定会把所有瓦片完整拼出来可能出现大面积空白或者灰底色。我试过多次效果都不太稳定。手动方案下我更建议的做法是把坐标复制出来单独粘贴到一个文档里再打印地图截图只是辅助示意。2.2 把坐标整理成能打印的表格坐标拿到手之后规范整理很关键。我在Excel里踩过一个经典坑经纬度数值位数较多Excel默认会把超过一定长度的数字转成科学计数法或者在实际显示时丢掉末尾小数。打印出来的表格里坐标变成一串看不出意义的数字非常被动。建议在Excel里这样处理新建一列单元格格式直接设为“文本”再粘贴坐标值避免被自动转换。如果需要保留数字格式方便计算设置“数字 → 数值 → 小数位数6位”超过6位的小数不要随便四舍五入去见人。表头至少包含地点名称、所属城市、经度、纬度、备注、采集日期。这样打印出来无论是归档还是复核都一目了然。表格做好之后用Excel的“打印预览”检查一下列宽。经纬度如果显示不下打印出来会被截断这种情况下把列宽拉伸到12-15再把页面方向调成横向。要长期归档的话用“页面布局 → 打印标题”固定表头行翻页后每一页都有表头这个操作一定要养成习惯。3. 技术方案用百度地图JavaScript API实时获取并打印3.1 准备工作申请AK和引入地图库手动方案始终有上限一旦地址数量超过50个或者你需要在业务系统里嵌入地图就必须走API。我用的比较多的是百度地图JavaScript API目标就是在页面上点击任意地点把经纬度实时打印到浏览器控制台。第一步是去百度地图开放平台注册开发者账号创建一个“浏览器端”应用拿到AK密钥。创建时有一个Referer白名单配置开发阶段可以直接填*但上线前务必改成自己的域名否则别人拿到你的AK就能盗刷配额。这一步很多人会忽略结果部署到线上后地图加载不出来排查半天才发现是白名单没配对。第二步是引入地图JS文件。目前常用两种版本!-- JS API 3.0普通版 -- script typetext/javascript src//api.map.baidu.com/api?v3.0ak你的AK/script !-- JS API GLWebGL版 -- script typetext/javascript src//api.map.baidu.com/api?typewebglv1.0ak你的AK/script如果是新项目我建议直接用GL版。它渲染效率更高视觉上更接近现代地图事件接口也相对统一。下面示例以GL版为主但3.0版的event对象结构类似稍作修改就能复用。3.2 点击地图拿到经纬度并输出下面这段代码是一个最小可运行页面加载地图到指定城市点击地图时把经度、纬度同时打印到控制台和页面上。!DOCTYPE html html langzh-CN head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1 title点击地图打印经纬度/title style html, body, #map { width: 100%; height: 600px; margin: 0; } #info { padding: 12px 16px; background: #f5f5f5; border: 1px solid #ddd; font-size: 14px; line-height: 1.8; } /style /head body div idmap/div div idinfo点击地图这里会显示经纬度/div script src//api.map.baidu.com/api?typewebglv1.0ak你的AK/script script (function () { var map new BMapGL.Map(map); var point new BMapGL.Point(116.404, 39.915); map.centerAndZoom(point, 15); map.enableScrollWheelZoom(true); map.addEventListener(click, function (e) { var lng e.latlng.lng; var lat e.latlng.lat; // 打印到浏览器控制台 console.log(经度: lng , 纬度: lat); // 打印到页面DOM document.getElementById(info).innerHTML 你点击的位置经度 b lng /b纬度 b lat /b; }); })(); /script /body /html这里有一个新手容易踩的坑BMapGL对象在引入JS文件之后才能用所以我的代码把脚本标签放在body后面确保地图库已经加载。如果你把API脚本放在head里又在地图库尚未加载完时执行初始化浏览器会直接报BMapGL is not defined。遇到这个问题把地图初始化逻辑放到window.onload或页面底部就能解决。只看坐标还不太够实际业务中通常还需要知道这个坐标对应的地址。这时候可以配合逆地理编码点击地图后用BMapGL.Geocoder把坐标转成地址描述。我常用写法如下var geocoder new BMapGL.Geocoder(); map.addEventListener(click, function (e) { var lng e.latlng.lng; var lat e.latlng.lat; console.log(经纬度:, lng, lat); geocoder.getLocation({ lng: lng, lat: lat }, function (result) { if (result result.addressComponents) { var addr result.addressComponents; console.log(地址: addr.province addr.city addr.district addr.street addr.streetNumber); document.getElementById(info).innerHTML 经纬度: lng , lat br地址: addr.province addr.city addr.district addr.street addr.streetNumber; } }); });注意逆地理编码属于付费配额接口频繁点击地图会消耗大量配额所以我一般会在页面里做节流比如每次点击后等500毫秒再允许下一次调用。否则并行请求一多很容易触发并发限制。3.3 按格式打印到页面和纸张现在讲回“打印”的另一层含义把结果区域真正打到纸上。我的做法是页面里放一个结果面板点击地图时把经纬度写入面板点击“打印”按钮时只打印结果面板不打印地图。style .no-print { display: block; } .print-area { display: none; } media print { .no-print { display: none; } .print-area { display: block; } } /style div classno-print div idmap stylewidth:100%;height:500px;/div button onclickwindow.print()打印坐标结果/button /div div classprint-area idresultArea h3地点坐标记录/h3 p idprintText请先在地图上点击选择地点/p /div在点击事件里除了更新页面上的#info同时把内容更新到#printTextdocument.getElementById(printText).innerHTML 经度: lng br纬度: lat br地址: addressText;核心逻辑是media print打印时隐藏地图只显示结果区块。这样无论用户怎么点击、地图怎么拖动最后打印纸上的内容始终干净清爽。如果你遇到打印预览卡顿或闪退多半是因为地图Canvas面积太大打印引擎处理不过来这种“只打印结果区”的方案能直接避开问题。4. 进阶方案用地理编码API批量打印地点经纬度4.1 单个地点怎么调用如果是几十上百个地址要转成经纬度再靠手点就太不现实了。这个时候用百度地图Web服务API里的“地理编码”接口输入地址返回结构化经纬度。请求参数非常简洁curl https://api.map.baidu.com/geocoding/v3/?address北京市海淀区上地十街10号outputjsonak你的AK返回的JSON里主要看这几段{ status: 0, result: { location: { lng: 116.308396372, lat: 40.057035754 }, precise: 1, confidence: 80, comprehension: 100, level: 门址 } }status为0表示成功result.location.lng和result.location.lat就是我们要打印的经纬度。这里的坐标默认是百度坐标系BD-09后面会专门讲坐标系转换的问题。precise为1代表解析到门址级别confidence是可信度批量建点时如果置信度太低建议单独标记不要直接进库。4.2 Python批量打印到终端和CSV批量处理我通常用Python写一个小脚本一个地址一个地址地请求把结果打印到终端的同时写入CSV。代码结构很简单import csv import time import requests AK 你的AK ADDRESSES [ 北京市海淀区上地十街10号, 上海市浦东新区世纪大道100号, 广州市天河区体育西路123号, ] def get_location(address: str): url https://api.map.baidu.com/geocoding/v3/ params { address: address, output: json, ak: AK, } try: resp requests.get(url, paramsparams, timeout5) data resp.json() except Exception as e: print(f[请求异常] {address}: {e}) return None, None if data.get(status) 0: loc data[result][location] return loc[lng], loc[lat] else: print(f[返回错误] {address}: {data.get(message)}) return None, None def main(): output_file locations.csv with open(output_file, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerow([地址, 经度, 纬度]) for addr in ADDRESSES: lng, lat get_location(addr) if lng is not None and lat is not None: print(f{addr} - {lng},{lat}) writer.writerow([addr, lng, lat]) else: writer.writerow([addr, 解析失败, 解析失败]) # 控制请求频率避免触发并发限制 time.sleep(0.2) if __name__ __main__: main()这里有几个经验点编码一定要用utf-8-sig而不是utf-8否则Office Excel打开CSV时中文会直接乱码。utf-8-sig会写入BOM头Excel能正确识别UTF-8。每请求一个地址后sleep(0.2)也就是每秒最多5个请求。个人认证开发者配额有限别把日志打太快。失败的要单独记录不要在循环里print完就彻底丢弃。建议把失败地址单独存到一个failed.csv下一次脚本重跑只处理失败列表能省很多配额。4.3 逆地理编码拿到经纬度后反查地址有地址转坐标的需求自然也有坐标转地址的需求。百度地图提供了/reverse_geocoding/v3/接口传location纬度,经度返回对应的地址描述。这个在“打印地点经纬度信息”的场景里经常配合使用比如你手里只有一堆GPS坐标想知道这些点分别落在哪个街道就需要反查。curl https://api.map.baidu.com/reverse_geocoding/v3/?ak你的AKlocation39.894915,116.328154outputjson返回的result.formatted_address就是可读地址。我在做外勤轨迹回放时就是定时把人员上报的经纬度反查成“某路某号”再打印成日志方便业务同学快速判断位置是否正常。不过这个接口同样有配额和QPS限制批量调用时务必控制频率。5. 从分享链接里提取经纬度并打印5.1 百度地图分享链接的坐标格式有些场景连API都不想碰比如别人在微信里发来一条百度地图的定位分享你要赶紧把坐标抄下来。这时候不用打开页面再去点百度地图的分享链接里往往直接带着经纬度。常见的链接格式大概是https://map.baidu.com/116.404,39.915,18z https://map.baidu.com/?qtinfuidxxxlocation116.404,39.915第一种格式里符号后面跟的就是经度、纬度、缩放级别。第二种格式里location参数就是坐标。解析规则很简单先找再按逗号切分或者找location再按逗号切分。如果是短链接比如https://j.map.baidu.com/xxxx链接里看不到坐标这种必须先访问短链接拿到跳转后的完整URL再解析。我在日常工作中碰到的大多数分享都是短链所以这个前置步骤不能跳过。5.2 浏览器控制台一行正则打印坐标如果你正在电脑上打开了百度地图某个位置想立刻把当前视图中心的经纬度打出来可以直接按F12打开开发者工具在Console里执行一段代码var url location.href; var match url.match(/([\d.]),([\d.])/) || url.match(/location([\d.]),([\d.])/); if (match) { var lng match[1]; var lat match[2]; console.log(经度: lng , 纬度: lat); }运行后控制台会打印出当前链接里的坐标。这个方法不需要申请任何密钥纯读链接字段适合临时救急。不过要注意链接里的坐标不一定是你鼠标点击的位置它多数情况下只是地图视图中心点。如果你要打印的是某个POI兴趣点的精确定位建议还是用坐标拾取器或JS API点击事件那里拿到的才是你真正标记的位置。6. 常见问题排查与避坑指南6.1 坐标对不上先搞清楚坐标系这是我在做地图开发时被问得最多的问题。同一个地点百度地图显示的经纬度粘到高德地图里偏出去几百米或者用GPS设备记录的点放到百度地图上也对不上。原因是三家用的坐标系不一样坐标系全称使用方BD-09百度坐标系百度地图GCJ-02火星坐标系高德、腾讯等国内地图WGS-84世界大地坐标系GPS设备、Google Earth、部分GIS软件百度地图默认输出的经纬度是BD-09如果直接拿到ArcGIS里当WGS-84用就会出现几百米甚至更大的偏移。做GIS数据处理时尤其要注意。如果只是把百度坐标转成GCJ-02给高德系用可以套用下面这个基础转换公式import math def bd09_to_gcj02(lng, lat): x_pi 3.14159265358979324 * 3000.0 / 180.0 x lng - 0.0065 y 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) gcj_lng z * math.cos(theta) gcj_lat z * math.sin(theta) return gcj_lng, gcj_lat至于GCJ-02转WGS-84网上能搜到很多公开算法但精度和适用区域有差异我一般不直接推荐在生产环境用转换公式。更好的做法是如果业务对坐标精度要求高尤其是涉及测绘、无人机、车辆轨迹的专业场景请直接从官方渠道拿WGS-84数据或者在采集现场用RTK这类高精度设备做基准点校正。民用展示场景用百度坐标或GCJ-02问题不大但到了规划、合规层面必须按项目要求的坐标系来。6.2 地图不显示、点击没反应、日志打不出来这一块的问题基本都是环境配置问题我列出几个高频原因和处理办法地图白屏AK没填对或者AK类型选了服务端却用在了网页上。浏览器端应用就用浏览器端AK服务端应用用服务端AK两者不能混用。页面提示“APP Referer校验失败”AK的Referer白名单没匹配当前域名。本地调试如果你是用file://打开的页面很多浏览器白名单校验会失败建议本地起个localhost服务调试。点击事件没触发检查事件绑定是否在地图初始化之后执行。另外要确认你真的注册了click事件而不是dblclick这两个在移动端尤其容易混淆。控制台没有输出先确认控制台没有过滤掉log级别再确认点击时是否真的触发了回调。可以临时在回调里加一个alert测试能弹窗说明事件回调没问题问题是console.log被浏览器插件或设置吞了。打印预览有大片空白地图是用Canvas或瓦片渲染的打印引擎处理不了所以尽量让打印区域避开地图本体只用文本结果排版。6.3 批量请求失败和配额限制批量地理编码最常见的报错是QUOTA_LIMIT_EXCEEDED或RATE_LIMIT_EXCEEDED。前者是总配额用完了后者是并发请求太快。我的处理经验是给每个请求加延时最简单就是sleep(0.2)QPS基本能压在5以内。请求失败不要立即重试容易把QPS顶爆。用指数退避比如第一次失败等1秒第二次等2秒第三次等4秒。把成功结果及时落盘别等全部跑完再统一保存。脚本中途挂了还能从断点继续不用重新消耗配额。如果日配额不够用去开发者平台查看“配额调整”入口按业务需要申请提升。但申请前一定要确认当前AK的配额确实用完了而不是代码有bug。6.4 CSV乱码与打印排版问题CSV乱码的问题前面提过统一用encodingutf-8-sig写入就能解决。但还有一个隐藏问题如果你用记事本改了CSV再保存成ANSI编码Excel打开也会乱码。所以维护CSV时尽量用VS Code这类能识别编码的编辑器不要反复用系统自带记事本另存为。纸面打印排版方面建议表格里的经纬度列宽至少12个字符宽度字体用等宽字体比如Consolas或Courier New。等宽字体下数字和逗号对齐效果非常好纸质文件扫描后也更容易做OCR识别。7. 实际使用中的几点补充建议工具和方法说完了最后再分享几个我项目里沉淀下来的习惯。第一所有坐标数据都要保留采集时间和数据来源。同样一个门店去年和今年的坐标可能因为地址变更、门牌调整而变化不同来源拿到的坐标也可能属于不同坐标系。我在数据库里会给每个地点加source字段标记是百度拾取、API解析还是GPS采集并且存一份原始坐标系说明。这样哪怕后续发现坐标有偏移也知道该去哪种口径下排查。第二不要重复请求已经拿到的坐标。地理编码接口的配额是花钱的能本地缓存就本地缓存。我通常会在脚本里维护一个address_cache.json每次请求前先查本地缓存命中就直接打印没命中才调接口。第三打印日志要关注异常而不是只关注坐标。真正在线上跑的时候我不会只看哪个地址返回了经纬度而是重点盯status非0的记录、置信度低于某一阈值的记录。这些异常点才是数据质量的主要破坏者。我的脚本里会把所有解析置信度低于60的地址单独输出成一个warning文件人工复核一遍再入库。最后说一句实在话百度地图打印经纬度的需求看起来永远是三五分钟能搞定的小功能但真正把它做稳定要考虑坐标系、配额、批量频率、打印排版和环境差异。把上面这些坑提前踩一遍后面不管接门店数、巡检点还是外勤轨迹都能少熬夜几次。这篇里的代码和模板我都在自己的项目里跑过你按场景挑一个用就行剩下的细节问题欢迎对照各自的报错信息进一步排查。