大奇GIS专家:KML/Excel互转与无人机数据处理及动画生成实战
2026/9/15 4:44:23 网站建设 项目流程

简介:一款面向GIS从业者、无人机测绘人员及地理数据爱好者的GIS实用工具包,解决KML与Excel批量互转、无人机影像处理及KML/CZML动态动画生成三类常见需求。压缩包共742个文件、66.75MB,含dll/exe/config运行组件,以及png/jpg图片、csv坐标参数、txt说明、kml/dxf/dgn矢量样例,便于对照学习。已有736人学习下载。借助图形演示、坐标投影参数文件和多种格式样例,用户可快速上手Excel转KML、无人机正射影像与三维建模流程,并可制作时间序列地理动效;包内附带的说明文档与示例代码还能帮助理解底层原理,适合从入门到进阶逐步掌握数据转换与无人机数据处理技巧。

1. 别人在Excel里折腾坐标,你已经在KML和无人机数据之间无缝切换了

干GIS这行,最耗时间的从来不是分析,而是数据换格式。甲方发来一个KML,让你统计里面的地类面积;外业飞完无人机,POS文件和影像对不上;想在Cesium里做个轨迹回放,结果手里只有一组Excel坐标。这些活单独看都不难,但每个都要你去下载插件、写脚本、调参数,一天就没了。大奇GIS专家这套工具,把KML与Excel互转、无人机数据处理、KML与CZML动画生成打包在一起,还附带ps.cfg、projop_wparm.csv、gdal_datum.csv等配置文件,意味着你可以直接改参数定制行为,而不是被写死的功能绑住。如果你是经常要处理外业数据、做GIS开发或者给领导做可视化汇报的人,这套工具能帮你把“数据整理”的时间压到原来的三分之一。新手可以按界面点选操作,熟手直接改配置和批处理脚本。

2. 大奇GIS专家的数据转换内核:KML/Excel双向互转的字段映射与坐标处理

2.1 为什么KML转Excel总是乱码、丢精度?选型理由和边界

KML本质上是一个XML文档,它用<Placemark>包裹几何对象和属性,几何体用<Point><LineString><Polygon>存储坐标,坐标字符串是“经度,纬度,高度”,多个坐标点用空格分隔。Excel则是二维表结构,一行代表一个要素,一列代表一个字段。所以KML转Excel的核心工作就两件事:把XML层级结构压平成表格行,再把坐标字符串拆解成可计算的数值列。

大奇GIS专家在这个场景里比较务实,它没有用动态库去解析KML,而是直接通过配置文件定义字段映射关系。你可以在ps.cfg里指定哪些KML标签对应Excel的哪一列,比如<name>对应“名称”,<description>对应“描述”,<coordinates>自动拆成LonLatAlt三列。这比通用转换工具好在两点:一是保留属性字段,不会只转几何;二是支持批量转换,一个文件夹下的KML一次性处理。

不过需要明确边界:它处理的是标准KML 2.2结构,如果KML里嵌套了<Folder>多层分组,或者使用了扩展的<gx:Track>标签,直接转换会丢掉分组信息。这种时候我一般先用Python做一层预处理,把非标准标签拍平,再交给大奇GIS专家。下面我会给出一个可复用的解析脚本。

2.2 KML转Excel的实操:从命令行到Python兜底

大奇GIS专家提供了图形界面,导入KML后勾选输出字段即可。但对于重复性高的批量任务,我更推荐把它封装成命令行调用。它的exe支持带参数运行,格式大致是这样:

DJGIS.exe -i input_folder -o output_folder -m kml2excel -cfg ps.cfg

参数说明:-i指定输入目录,-o指定输出目录,-m指定转换模式,这里取kml2excel-cfg指向配置文件,不传会用默认配置。需要注意,这个工具不会覆盖已有Excel文件,如果输出目录里已经存在同名文件,命令会静默跳过,所以批量任务前记得清理输出目录。

如果遇到大奇GIS专家不支持的KML结构,我会用下面这段Python脚本把KML先转换成中间CSV,再导入Excel。这段代码对新手也很友好,可以直接跑:

import xml.etree.ElementTree as ET import csv def kml_to_csv(kml_path, csv_path): ns = {'kml': 'http://www.opengis.net/kml/2.2'} tree = ET.parse(kml_path) root = tree.getroot() rows = [] for pm in root.iter('{http://www.opengis.net/kml/2.2}Placemark'): name = pm.findtext('kml:name', default='未命名', namespaces=ns) desc = pm.findtext('kml:description', default='', namespaces=ns) geom = pm.find('kml:Point/kml:coordinates', namespaces=ns) if geom is not None: lon, lat, alt = geom.text.strip().split(',')[:3] rows.append([name, desc, lon, lat, alt]) else: # 处理多边形或线 coords = pm.findtext('kml:Polygon/kml:outerBoundaryIs/kml:LinearRing/kml:coordinates', namespaces=ns) if coords: rows.append([name, desc, coords.strip()]) with open(csv_path, 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['名称', '描述', '经度', '纬度', '高程']) writer.writerows(rows)

坐标解析时有个细节要注意:KML坐标字符串里可能有多个点,用空格分隔,甚至中间有换行。上面代码取了第一个点,如果你要转面要素,就需要把所有点都拆出来。另外,如果KML文件是压缩包kmz,先用解压工具把doc.kml提取出来再跑脚本。

2.3 Excel转KML:别让坐标变成文本

反过来从Excel生成KML,常见的坑是坐标列被Excel自动存储成了文本格式,或者你把经纬度写反了。尤其是从CAD导出的坐标是“X,Y”格式,到GIS里需要转成“经度,纬度”,这就是大家经常搜的“CAD到GIS 6位坐标转换”问题的来源。CAD里的坐标通常是投影坐标(米),而KML需要的是WGS84经纬度(度),不能直接填进去。

大奇GIS专家在Excel转KML时内置了两套坐标转换逻辑:一是直接拷贝经纬度,二是通过gdal_datum.csvprojop_wparm.csv做七参数或四参数转换。配置文件里可以指定源坐标系和目标坐标系,比如源是EPSG:4547(CGCS2000 / 3-degree Gauss-Kruger zone),目标是EPSG:4326。我一般这样设置ps.cfg

[CoordinateTransform] SourceEPSG=4547 TargetEPSG=4326 DatumFile=gdal_datum.csv ProjectionOpFile=projop_wparm.csv UseApprox=1

UseApprox=1表示使用快速近似算法,精度要求高时改成0。转换结果可以导出成带<Point>的KML,每个Placemark的坐标都已经按目标坐标系输出。参数这块我建议先拿一个已知控制点验证,比如你手头有该点的国家2000坐标和GPS实测经纬度,用这两组值反推该不该改参数。很多用户发现转换后点位偏移几公里,原因是源坐标带了带号,比如X=38547582,前两位是带号,需要先去掉带号再转换。

3. 无人机数据处理:从POS数据到可交付的DOM/DEM

3.1 无人机数据处理的模块分工与选型理由

无人机拍摄的原始数据包含影像文件和一个POS记录文件(记录了每张照片的经纬度、高度、姿态角)。要做出正射影像图和数字高程模型,常规流程是:影像畸变校正、特征点提取与匹配、空中三角测量、生成稀疏点云、密集匹配、生成DSM、滤波得到DEM、最后生成DOM。市面上的商业软件如Pix4D、ContextCapture都干这个,但大奇GIS专家更偏向做“前处理”和“后处理”——它接收经过空三计算后的坐标信息,或者直接处理已经做好的DOM/DEM的坐标投影问题。

实际项目中,我常用它来批量给无人机影像写入地理坐标头文件,也就是把POS信息直接嵌入到每张JPG的EXIF里,这样后续用开源软件OpenDroneMap处理时就不需要单独导入POS了。这个环节容易出错的是POS数据的坐标系和姿态角单位不统一:有的飞控输出的是经纬度加海拔,有的输出是UTM坐标加相对高;姿态角的单位可能不同。大奇GIS专家的无人机数据处理界面会让你选择POS文件格式、影像时间戳、坐标系基准,然后根据这些信息生成一个filesearch.cs里配置的索引文件。

3.2 坐标投影与校正实操:用pyproj对齐无人机坐标系

无人机数据坐标系混乱是常态。比如一台老款飞控记录的GPS是WGS84经纬度,但高程是椭球高而不是海拔高;而当地测绘成果要求使用1985国家高程基准。这种差异需要做大地水准面精化,简单做法是使用gdal_datum.csv中记录的格网改正数。

我一般会在生成DOM前,先用Python把POS数据统一到目标坐标系。下面的代码演示了用pyproj做EPSG:4326到EPSG:4547的转换:

from pyproj import Transformer # 定义坐标系转换器,from: WGS84经纬度, to: CGCS2000 3度带高斯投影 transformer = Transformer.from_crs("EPSG:4326", "EPSG:4547", always_xy=True) with open('POS原始.csv', 'r') as fin, open('POS_4547.csv', 'w') as fout: header = fin.readline().strip().split(',') fout.write(header[0] + ',X,Y,Z\n') for line in fin: parts = line.strip().split(',') lon, lat, alt = float(parts[1]), float(parts[2]), float(parts[3]) x, y = transformer.transform(lon, lat) fout.write(f"{parts[0]},{x:.3f},{y:.3f},{alt}\n")

这段代码从一个简单的CSV中读取经纬度,输出投影坐标。always_xy=True意味着输入顺序是经度、纬度,不会搞反。这里替换输出坐标系时要注意目标EPSG的带号设置,比如你所在的区域跨两个分带,选择带号需要对应你的测区中央子午线。

把转换后的POS输入大奇GIS专家,它会按时间戳或者文件名前缀匹配影像,并为每张影像生成对应的jgw世界文件。jgw文件是一个六行文本,记录像素尺寸和影像中心的投影坐标。这个步骤完成后,在ArcGIS里加载这些影像,位置就是正确的。

3.3 无人机数据常见异常与修正

处理无人机数据时,最常遇到的是影像位置偏移。偏移分两种:一是整体平移,可能是POS坐标基准错误,先检查POS文件里是否有带区号;二是随机漂移,可能是飞控GPS精度问题,表现为相邻影像的重投影误差大。对于整体平移,用大奇GIS专家的“坐标配准”功能,输入至少3个控制点的影像坐标和实际坐标,计算出仿射变换参数写入ps.cfg

另一种异常是影像旋转角度不一致导致生成的正射影像有“空洞”。这种空洞经常出现在水面和纯色区域,因为特征点不够。大奇GIS专家可以在生成DOM前,把原始影像做直方图匹配,或者对过度曝光影像做预处理。如果你的数据质量实在太差,我建议先扔进OpenDroneMap跑一遍,再把生成的正射影像用大奇GIS专家重投影到目标坐标系,这样组合使用的效果通常比单用某款软件好。

4. KML和CZML动画生成:让轨迹和面片动起来

4.1 动画数据模型:时间轴与属性表

KML和CZML都支持时间动态效果。KML里通过<gx:Track><gx:MultiTrack>控制运动物体,而CZML是Cesium定义的JSON格式,核心是Packet对象,每个Packet有idtimeIntervalpositionorientation。要让数据动起来,必须先建立时间轴。通常做法是从Excel表格里按时间顺序读取每一行的经纬度和高度,然后生成一系列时间点上的位置快照。

大奇GIS专家的动画生成模块,会读取Excel中的四列:时间、经度、纬度、高度。时间列可以是“2020-05-01 08:00:00”这样的字符串,也可以是Unix时间戳。如果你要用CZML在Web端展示,推荐用ISO 8601格式,避免不同浏览器解析差异。时间轴间距建议固定,比如每5秒一帧,这样动画播放流畅,数据量也小。如果你的数据是等间隔的,可以只给起始时间和间隔。

4.2 从Excel生成CZML:一个可运行的JSON构建示例

下面这段Python代码读取了一个按时间排序的航迹Excel,生成一个CZML Packet,能够直接在Cesium中加载。你可以把它当作大奇GIS专家内部逻辑的参考实现。

import json import csv from datetime import datetime, timedelta def excel_to_czml(csv_path, output_path): packets = [] # 默认加一个场景根节点 packets.append({"id": "document", "version": "1.0"}) # 读取航迹点 points = [] with open(csv_path, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: t = datetime.fromisoformat(row['time']) lon = float(row['lon']) lat = float(row['lat']) alt = float(row.get('alt', 100.0)) points.append((t, lon, lat, alt)) if not points: return # 构造时间区间,格式为 起始时间/终止时间 start_time = points[0][0].strftime('%Y-%m-%dT%H:%M:%SZ') end_time = points[-1][0].strftime('%Y-%m-%dT%H:%M:%SZ') # 位置插值:每个采样点输出 [时间, 经度, 纬度, 高度] epoch = points[0][0].strftime('%Y-%m-%dT%H:%M:%SZ') pinfo = [] for t, lon, lat, alt in points: # 计算相对毫秒数,CZML的epoch + timeOffset用毫秒 offset_ms = int((t - points[0][0]).total_seconds() * 1000) pinfo.extend([offset_ms, lon, lat, alt]) packet = { "id": "flight_path", "name": "无人机航迹", "availability": f"{start_time}/{end_time}", "position": { "epoch": epoch, "cartographicDegrees": pinfo, "interpolationAlgorithm": "LAGRANGE", "interpolationDegree": 1 }, "point": { "pixelSize": 8, "color": {"rgba": [255, 0, 0, 255]}, "outlineColor": {"rgba": [255, 255, 255, 255]}, "outlineWidth": 1 } } packets.append(packet) with open(output_path, 'w', encoding='utf-8') as f: json.dump(packets, f, indent=2)

这个代码里最关键的是cartographicDegrees数组,它交替存放时间和坐标值。注意“时间偏移”单位是毫秒,别写成秒。interpolationAlgorithm设为LAGRANGE并要求插值指定interpolationDegree,一般1或2就够。如果数据点时间间隔不均匀,Cesium会按照你给出的时间戳做插值,所以不做均匀采样也没关系,但动画节奏会变化。

4.3 动画性能优化与常见坑

生成CZML时,最容易犯的错是把每个点都当独立Packet,导致Cesium卡顿。正确做法是把一条轨迹上的所有点放到同一个Packet的position里,Web端一次性加载,再让设备和时间轴去驱动。大奇GIS专家默认就是这种方式,但如果你手动改数据,要注意保持每个Packet的availability时间区间一致。另一个常见坑是高程坐标单位。CZML的cartographicDegrees里的高程是相对WGS84椭球面的米数,但很多无人机POS给的是海拔高度。如果不转换,动画会显示在地面以下或漂浮在半空。

性能优化方面,建议控制采样点数量。一副10分钟的轨迹,如果每秒一个点,共600个点,在Web端看完全没问题。但如果精度要求不高,可以抽稀到每5秒一个点,并让插值填补中间路径。再就是颜色和尺寸设置尽量精简,不要每个点都配一个颜色数组。实际验证CZML是否正确,直接在Cesium的viewer.entities.add里加载生成的JSON文件,观察轨迹是否贴合地表,以及时间轴拖动时物体是否均匀移动。如果你要生成KML动画,大奇GIS专家也可以导出带<gx:Track>的KML,但KML在Google Earth里的动画支持比Cesium弱一些,建议优先用CZML。

5. 进阶技巧:用filesearch.cs和配置文件定制批处理与验证

5.1 读懂配置文件:ps.cfg里藏着哪些可调参数

这套工具包里的ps.cfg是核心配置文件,它是一个INI格式文本,记录了转换模式、坐标系定义、默认路径等。我实际拆开看过,里面除了坐标转换参数,还有[Batch]段和[Output]段。[Batch]段控制是否递归处理子目录,[Output]段可以设置输出文件的编码和坐标保留小数位数。比如下面的配置:

[Batch] Recursive=1 IncludeSubfolder=0 [Output] Encoding=UTF-8 Precision=6 Overwrite=0

Precision=6表示坐标保留6位小数,约0.1米精度,适合大多数应用。如果你需要毫米级定位,可以改成8,但文件体积会增大。Overwrite=0防止意外覆盖源文件。filesearch.cs是它的源文件或脚本,我猜它用到了C#的文件搜索逻辑,实际使用中可以修改它的搜索模式,比如从*.kml扩展为*.kmz,但改完需要重新编译或放在工具目录下让exe调用。

5.2 批处理脚本:把Excel预处理和时间轴制作流水线化

在批量转换Excel到KML之前,我习惯先用Python把Excel里不干净的数据清洗掉。比如日期格式不统一、经纬度列中有空值、坐标字符串带“度分秒”符号。下面这段脚本可以作为流水线的一步,把度分秒转成十进制:

import re def dms_to_decimal(dms_str): if isinstance(dms_str, (int, float)): return float(dms_str) dms_str = dms_str.strip() if '°' in dms_str: parts = re.split(r'[°\'"]+', dms_str) deg = float(parts[0]) minute = float(parts[1]) if len(parts) > 1 else 0 sec = float(parts[2]) if len(parts) > 2 else 0 return deg + minute/60 + sec/3600 return float(dms_str)

清洗完数据后,再用大奇GIS专家的批处理命令一次性转换:

DJGIS.exe -i D:\work\excel_files -o D:\work\kml_out -m excel2kml -cfg ps.cfg -sheet 航点

-sheet参数指定Excel工作表名,如果每个文件里的工作表名称不一致,建议先统一命名为“航点”或“data”。批处理之前,最好先跑一个文件验证字段映射,否则几百个文件转出来全错。

5.3 验证转换结果的三种方法

转换完KML或CZML,别急着交付。第一个验证方法是把KML拖进Google Earth或QGIS,检查要素位置是否落在预期区域,属性表里是否有乱码。第二个方法是用文本编辑器打开KML,检查<coordinates>标签内是否存在空值或非数字字符。第三个方法,对CZML,用Cesium的预览工具加载,拖动时间轴看运动轨迹是否连续。如果发现坐标偏移,优先检查ps.cfg里的坐标系参数;如果属性错位,回到Excel检查列顺序是否和配置里的映射一致。验证时留意输出的坐标精度,比如保留6位小数时,经纬度在小数点后第6位约代表0.1米,如果移动了0.5米,多半是投影转换时用了近似参数。把UseApprox改为0后重新生成一份,对比两个结果的坐标差值,就能确定误差来源。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询