← 返回文章列表

把几千张手机照片按地图归位:我做了一张自己的足迹地图

读取照片自带的定位,按省市区归位、画成地图、排出城市榜单,顺便导出一份 Excel 报表——整套东西在手机上就能跑,照片不出本地。

手机里攒了几千张照片,散在好几个相册文件夹里。想知道"我都在哪些地方拍过"——一张张翻不现实,所以我写了个小工具:把照片自带的定位读出来,画成一张地图,顺便按城市排出排行。

先把三个词说白,后面不再解释:

  • EXIF:照片文件里自带的一段"出生信息"——拍摄时间、相机型号、光圈快门,还可能带定位。只有拍照时开了定位,才会写进去
  • 行政归属:把一组经纬度换算成"省 / 市 / 区县",这样才能按城市统计
  • 底图:地图的背景图(这里用的是高德)
木桌上摊开的相册与折起的老地图
相册、老地图与一杯热茶——把照片按地点归位

先说清楚用了什么

环节 用的东西 这玩意是干嘛的
运行环境 手机上的终端工具 + Python 3.12 终端工具 ≈ 手机里的命令行窗口;Python 是写脚本的语言
读照片信息 Pillow Python 的图像处理库,负责读出照片的 EXIF
出报表 openpyxl Python 的 Excel 库,把统计结果写成 .xlsx
画地图 Leaflet 开源的网页地图库,把光点画到地图上(前端 JS)
地图背景 高德地图底图 网页里引用的底图服务,看地图要联网
判断归属 省界数据(本地缓存) 用边界数据判断一张照片落在哪个省市区
纯网页兜底 exifr 浏览器里直接读 EXIF 的库,不装任何东西也能用

怎么跑(挑一种就行)

A · 手机出离线单文件(最稳,推荐)

生成一个 + 一份 Excel 报表,用浏览器打开 HTML 就能看——不开服务、不占端口,数据全内联在一个文件里。

B · 手机起服务(实时看)

C · 电脑上跑

D · 纯网页兜底(什么都不装)
直接用浏览器打开 ,手动选择相册文件夹,浏览器自己读 EXIF。

水墨风远山与蜿蜒小径
走过的路,就交给地图记住

地图上能看出什么

  • 地点排行:哪个城市/区县拍得最多,一眼看排名
  • 省 / 市 / 区县三级归属:不是只给个经纬度,而是直接告诉你"这是哪儿"
  • 时间线:按拍摄时间排出的照片流
  • 占用体积:每个地点的照片占了多少空间
  • 缩略图预览:地图上点开就能看
  • Excel 报表 7 张表:含一份"无定位清单"——把因为没定位而没上图的名字全列出来,方便核对

我认为最值钱的一个设计:定位索引

第一次扫描时,把每一张照片(包括没有定位的那些)的经纬度、拍摄时间、省市区、文件指纹(文件大小 + 修改时间)记进两个文件:一个是给程序读的缓存,一个是给人看的 Excel 索引。

之后每次扫描,命中索引的文件直接从缓存取值,不再打开照片读 EXIF;只有新增或改动过的文件才真读一遍。效果是第二次起扫描从 11 秒降到 3 秒量级。

还有两个细节挺省心:索引文件丢了不要紧,程序能从那份 Excel 索引里恢复;换电脑时把这两个文件一起拷过去,新机器也不用重读一遍照片。

六个真踩过的坑

  1. 手机浏览器打不开 127.0.0.1:多半是代理或 VPN 把"本机地址"也一起代理走了 → 关掉代理再试,或改用 ,最稳的是直接用 A 方案的离线单文件(完全不占端口)
  2. 有些照片缩略图打不开:那是 HEIC 格式(苹果手机的图片格式),装个 再重启就好
  3. 第一次遇到新省份会联网:要下载省界数据(约 200KB),缓存在本地;下载失败会自动降级到上一级归属,不影响出图
  4. 没有定位的照片上不了地图:只统计体积。这是拍照时没开定位导致的,谁也补不回来(报表里有清单可核对)
  5. 截图和转发来的图没有拍摄时间:时间线会缺这些,属正常
  6. 扫描慢:别一上来就勾"整个手机存储",先只勾 DCIM 和 Pictures 两个相册文件夹

效果如实说

  • 能用的:看自己的足迹、按城市排行、导 Excel、缩略图预览、省市区三级归属、断点记忆(关掉页面重开还有数据)
  • 差在哪:没定位的照片归不了位;第一次遇到新省份要联网下边界;时间是按照片里的原始字符串比较的,不做时区修正——跨时区旅行时顺序可能有小偏差
  • 精度口径:用照片自带的 GPS(度分秒换算成小数度),坐标 0,0 视为无效丢弃;同一地点的坐标取该地所有照片的算术平均

隐私提醒

照片定位是挺敏感的数据——连着几十张照片的定位,基本能推出你家和单位在哪。所以这套东西建议全程在本地跑:照片不出手机、不出电脑,不上传任何服务器。要分享,就只分享那张地图截图。

名词小抄(读不懂就翻这里)

词 一句话解释
EXIF 照片文件里自带的信息区:拍摄时间、设备、参数、可能含定位
GPS 经纬度 地理坐标,经度定东西、纬度定南北
度分秒 经纬度的一种写法(像"116 度 23 分 29 秒"),程序里要换算成小数度
行政归属 判断某个坐标属于哪个省 / 市 / 区县
点面判定 判断一个点落不落在某个多边形里的算法(这里用射线法)
底图 地图的背景图层,通常是第三方服务,看地图需要联网
缓存 / 索引 把算过一次的结果存下来,下次直接用,不用重算
文件指纹 用"文件大小 + 修改时间"判断文件有没有变过
HEIC 苹果设备常用的一种图片格式,需要额外组件才能解码
127.0.0.1 / localhost 指向"本机自己"的地址,代理软件有时会误拦它
网格聚合 点太密时按格子合并显示,避免地图糊成一团

🛠 本文由自建 Agent 调度内容流水线自动完成:写稿 → 模型 API 生图 → R2 图床 → 排版 → MCP 落站。
配图由模型 API 生成、托管在自建对象存储上;内容仅供参考。