需求的由来
在某项目中因需要使用无人机对多个临时指定的区域进行航测,一天下来无人机会创建多达几十个文件夹(有自动拍照和手动拍照的),在内业整理中我需要检查每个文件夹对应的飞行区域,以及照片是否覆盖到位,再对每一个文件夹进行整合和命名。

例图:无人文件夹太多
虽然LSV(图新地球)中也有照片生成轨迹的功能,但不支持批量生成轨迹,这对我来说还有些不够方便,因为有时我会将多个文件夹内的照片合并到一个文件夹内再进行检查,如果用LSV再进行一遍遍的路径指定和点击会感到繁琐。

例图:LSV的“照片生成轨迹”
思路
基于此,我需要代码按以下流程来帮搞定这些工作:
1、提取当前目录下所有文件夹内照片的坐标。
2、将照片按飞行轨迹连线。
3、生成KMZ文件并按文件夹命名。
代码
import os
import exifread
import simplekml
from pathlib import Path
def get_gps_coordinates(image_path):
"""从照片EXIF提取GPS坐标"""
with open(image_path, 'rb') as f:
tags = exifread.process_file(f, details=False)
if not all(key in tags for key in ['GPS GPSLatitude', 'GPS GPSLongitude']):
return None
def dms_to_decimal(dms, ref):
degrees = float(dms.values[0])
minutes = float(dms.values[1])
seconds = float(dms.values[2].num) / float(dms.values[2].den)
decimal = degrees + minutes/60 + seconds/3600
return -decimal if ref in ['S', 'W'] else decimal
lon = dms_to_decimal(tags['GPS GPSLongitude'], tags['GPS GPSLongitudeRef'].values)
lat = dms_to_decimal(tags['GPS GPSLatitude'], tags['GPS GPSLatitudeRef'].values)
return (lon, lat)
def process_folder(folder_path):
"""处理单个文件夹生成带自定义图标的KMZ"""
kml = simplekml.Kml()
coordinates = []
# 配置本地图标路径(需确保路径存在)
local_icon = "D:/Program Files/LocaSpaceViewer4/LocaSpaceViewer4/Resource/image/GEMarker/red-stars.png"
for file in Path(folder_path).glob('*.jpg'):
coords = get_gps_coordinates(file)
if coords:
img_path = str(file.resolve()).replace('\\', '/')
popup_html = f'<img src="{img_path}" width="599">'
point = kml.newpoint(name=file.name, coords=[coords])
point.style.iconstyle.icon.href = local_icon
point.style.iconstyle.scale = 1.2 # 图标大小调节
point.description = f'<![CDATA[{popup_html}]]>'
coordinates.append(coords)
if coordinates:
linestring = kml.newlinestring(name="Flight Path")
linestring.coords = coordinates
linestring.style.linestyle.color = simplekml.Color.red
linestring.style.linestyle.width = 3
output_path = f"{Path(folder_path).name}.kmz"
kml.savekmz(output_path)
return output_path
return None
def main():
"""主处理函数"""
current_dir = Path.cwd()
print(f"正在处理目录: {current_dir}")
for folder in current_dir.iterdir():
if folder.is_dir():
print(f"正在处理文件夹: {folder.name}")
result = process_folder(folder)
if result:
print(f"已生成: {result}")
if __name__ == "__main__":
main()
运行库
运行此代码需要exifread库和simplekml库的支持。
1、exifread用来读取照片坐标
2、 simplekml用来绘制点线面并打包KMZ
安装exifread和exifread(打开命令提示符分别输入并回车 ):
pip install exifread
pip install simplekml
运行效果
目录下生成的KMZ文件

运行后批量生成的KMZ文件
导入图新地球(LSV)的效果

导入图形地球
导入奥维地图的效果
图标的修改
注意,照片位置点我使用了本地的图标,你需要在代码中修改为你的路径。
# 配置本地图标路径(需确保路径存在)
local_icon = "D:/Program Files/LocaSpaceViewer4/LocaSpaceViewer4/Resource/image/GEMarker/red-stars.png"
以上是引用图标的代码段。我使用的是图新地球内自带的图标。右键点击图新地球的图标——打开文件所在的位置——依次打开文件夹:Resource\image\GEMarker可以找到这些图标,将你喜欢的图标路径替换为引号内的路径即可。
萌新操作指南
萌新请先搜索安装python(我安装的是3.10.6),然后再安装exifread库和simplekml库(上面有提到怎么安装)。后续操作步骤:新建文本文档——粘贴代码——保存——把文件后缀.TXT改为.PY——把文件放在无人机照片总目录下——双击运行文件,如果双击没反应就右键选择Edit with IDLE打开代码然后按F5运行代码。
附言
最后,老实说我并没有写几个代码,多亏了DeepSeek帮我写出这些代码。不过这中间我确实也经历了多次调试才得到想要的效果,大佬请忽略,希望可以帮助到有相关需求又懒得写代码的人,尤其是小白,哈哈。

1022

被折叠的 条评论
为什么被折叠?



