深入解析 KMZ 文件的处理与可视化:从数据提取到地图展示项目实战
文章目录
- 1. KMZ 文件与 KML 文件简介
- 1.1 KMZ 文件
- 1.2 KML 文件
- 2. Python 环境配置与依赖安装
- 3. 代码实现详解
- 3.1 查找 KMZ 文件
- 3.2 解压 KMZ 文件
- 3.3 解析 KML 文件
- 3.4 可视化 KMZ 数据
- 4. 项目实战
- 4.1. 数据采集
- 4.2. 项目完整代码
- 5. 项目运行与结果展示
- 6. 总结与展望
在处理地理空间数据时,KMZ 文件是一种常见的格式,用于存储地图和地理信息数据。KMZ 文件是 KML 文件的压缩版本,其中 KML(Keyhole Markup Language)用于描述地理数据的格式。本文将详细介绍如何使用 Python 处理 KMZ 文件,提取其中的地理数据,并将其可视化到地图上。本文的核心代码将涉及文件的解压、KML 文件的解析、GPS 数据的提取以及如何使用 Folium 库将数据展示到地图上。
1. KMZ 文件与 KML 文件简介
1.1 KMZ 文件
KMZ 文件是 KML 文件的压缩版本,通常用于存储 Google Earth 或 Google Maps 中使用的地理信息数据。KMZ 文件可以包含一个或多个 KML 文件以及其他资源文件(如图片、图标等)。KML 文件是基于 XML 的格式,用于描述地理数据的标记、路径、区域等信息。
1.2 KML 文件
KML 文件由 XML 构成,用于存储地理数据,如地点标记、线条、区域、图像叠加等。KML 的基本结构包括:
- Placemark:标记点
- Point:点类型
- LineString:线条
- Polygon:多边形
- TimeStamp:时间戳
2. Python 环境配置与依赖安装
在开始之前,确保你的 Python 环境中已经安装了以下依赖:
folium
:用于地图可视化xml.etree.ElementTree
:用于解析 XML 文件zipfile
:用于解压 KMZ 文件glob
:用于文件路径匹配
可以使用以下命令安装所需的库:
pip install folium
3. 代码实现详解
3.1 查找 KMZ 文件
import os
import globdef find_kmz_files(directory):# 使用 glob 模块查找指定目录下的所有 .kmz 文件kmz_files = glob.glob(os.path.join(directory, '*.kmz'))return kmz_files
- 功能:遍历指定目录,查找所有以
.kmz
结尾的文件。 - 实现:使用
glob
模块和通配符模式来匹配所有 KMZ 文件。
3.2 解压 KMZ 文件
import zipfiledef extract_kml_from_kmz(kmz_file_path):# 解压 KMZ 文件with zipfile.ZipFile(kmz_file_path, 'r') as kmz:# 查找 KML 文件kml_files = [name for name in kmz.namelist() if name.lower().endswith('.kml')]if kml_files:kml_file_path = kml_files[0]kmz.extract(kml_file_path, os.path.dirname(kmz_file_path))return os.path.join(os.path.dirname(kmz_file_path), kml_file_path)return None
- 功能:解压 KMZ 文件,并提取其中的 KML 文件。
- 实现:使用
zipfile
模块打开 KMZ 文件,查找并解压 KML 文件。
3.3 解析 KML 文件
import xml.etree.ElementTree as ETdef parse_kml(kml_file_path):gps_data = []tree = ET.parse(kml_file_path)root = tree.getroot()# KML 的 XML namespacenamespace = {'kml': 'http://earth.google.com/kml/2.2'}print(f"Root element: {root.tag}")# 查找所有 Placemark 元素for placemark in root.findall('.//kml:Placemark', namespace):coordinates = placemark.find('.//kml:Point/kml:coordinates', namespace)if coordinates is not None:coords = coordinates.text.strip().split(',')if len(coords) >= 3:try:longitude = float(coords[0])latitude = float(coords[1])altitude = float(coords[2])gps_data.append({'latitude': latitude,'longitude': longitude,'altitude': altitude})except ValueError as e:print(f"Error parsing coordinates: {e}")return gps_data
- 功能:解析 KML 文件,提取 GPS 数据(经纬度和高度)。
- 实现:使用
xml.etree.ElementTree
解析 XML 格式的 KML 文件,通过查找Placemark
元素和coordinates
元素来获取地理数据。
3.4 可视化 KMZ 数据
import folium
from folium.features import CustomIcondef visualize_multiple_kmz_data(kmz_data_list):if not kmz_data_list:print("No GPS data available to visualize.")return# 计算所有经纬度的平均值,作为地图的中心all_latitudes = []all_longitudes = []for kmz_data in kmz_data_list:latitudes = [data['latitude'] for data in kmz_data['gps_data']]longitudes = [data['longitude'] for data in kmz_data['gps_data']]all_latitudes.extend(latitudes)all_longitudes.extend(longitudes)avg_latitude = sum(all_latitudes) / len(all_latitudes)avg_longitude = sum(all_longitudes) / len(all_longitudes)map_center = [avg_latitude, avg_longitude]gps_map = folium.Map(location=map_center, zoom_start=14, tiles='OpenStreetMap')folium.TileLayer(tiles='https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',name='Google Satellite',attr='© Google').add_to(gps_map)folium.LayerControl().add_to(gps_map)# 为每个 KMZ 文件使用不同的颜色colors = ['red', 'blue', 'green', 'purple', 'orange', 'darkred', 'lightred', 'beige', 'darkblue', 'darkgreen', 'cadetblue', 'darkpurple', 'white', 'pink', 'lightblue', 'lightgreen', 'gray', 'black', 'lightgray']for idx, kmz_data in enumerate(kmz_data_list):color = colors[idx % len(colors)]for data in kmz_data['gps_data']:folium.CircleMarker([data['latitude'], data['longitude']],radius=0.5, # 半径大小color=color, # 边框颜色fill=True,fill_color=color, # 填充颜色fill_opacity=0.8).add_to(gps_map)# 绘制路径线并添加箭头for i in range(1, len(kmz_data['gps_data'])):start_point = kmz_data['gps_data'][i-1]end_point = kmz_data['gps_data'][i]# 绘制线条folium.PolyLine(locations=[(start_point['latitude'], start_point['longitude']),(end_point['latitude'], end_point['longitude'])],color=color,weight=2).add_to(gps_map)# 添加箭头folium.Marker(location=[(start_point['latitude'] + end_point['latitude']) / 2,(start_point['longitude'] + end_point['longitude']) / 2],icon=CustomIcon('https://upload.wikimedia.org/wikipedia/commons/e/e5/Black_triangle_pointing_right.svg',icon_size=(10, 10), icon_anchor=(5, 5))).add_to(gps_map)gps_map.save('multiple_kmz_map.html')print("GPS map saved as 'multiple_kmz_map.html'.")
- 功能:将多个 KMZ 文件的数据可视化到一个地图上,使用不同的颜色表示不同的 KMZ 文件。
- 实现:
- 计算所有点的平均经纬度作为地图的中心。
- 使用
folium.Map
创建地图,并添加地图图层。 - 对每个 KMZ 文件使用不同的颜色,并将其 GPS 数据以
CircleMarker
的形式添加到地图上。
绘制路径线,并在路径中添加箭头指示方向。
4. 项目实战
4.1. 数据采集
两个kmz文件:
其中一个kmz文件解压,会看到有一个kml文件:
kml文件打开,会看到一些关键信息,以下是部分信息截图:
4.2. 项目完整代码
import os
import glob
import folium
import zipfile
import xml.etree.ElementTree as ET
from folium.features import CustomIcondef find_kmz_files(directory):kmz_files = glob.glob(os.path.join(directory, '*.kmz'))return kmz_filesdef extract_kml_from_kmz(kmz_file_path):with zipfile.ZipFile(kmz_file_path, 'r') as kmz:kml_files = [name for name in kmz.namelist() if name.lower().endswith('.kml')]if kml_files:kml_file_path = kml_files[0]kmz.extract(kml_file_path, os.path.dirname(kmz_file_path))return os.path.join(os.path.dirname(kmz_file_path), kml_file_path)return Nonedef parse_kml(kml_file_path):gps_data = []tree = ET.parse(kml_file_path)root = tree.getroot()namespace = {'kml': 'http://earth.google.com/kml/2.2'}for placemark in root.findall('.//kml:Placemark', namespace):coordinates = placemark.find('.//kml:Point/kml:coordinates', namespace)if coordinates is not None:coords = coordinates.text.strip().split(',')if len(coords) >= 3:try:longitude = float(coords[0])latitude = float(coords[1])altitude = float(coords[2])gps_data.append({'latitude': latitude,'longitude': longitude,'altitude': altitude})except ValueError as e:print(f"Error parsing coordinates: {e}")return gps_datadef visualize_multiple_kmz_data(kmz_data_list):if not kmz_data_list:print("No GPS data available to visualize.")returnall_latitudes = []all_longitudes = []for kmz_data in kmz_data_list:latitudes = [data['latitude'] for data in kmz_data['gps_data']]longitudes = [data['longitude'] for data in kmz_data['gps_data']]all_latitudes.extend(latitudes)all_longitudes.extend(longitudes)avg_latitude = sum(all_latitudes) / len(all_latitudes)avg_longitude = sum(all_longitudes) / len(all_longitudes)map_center = [avg_latitude, avg_longitude]gps_map = folium.Map(location=map_center, zoom_start=14, tiles='OpenStreetMap')folium.TileLayer(tiles='https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',name='Google Satellite',attr='© Google').add_to(gps_map)folium.LayerControl().add_to(gps_map)colors = ['red', 'blue', 'green', 'purple', 'orange', 'darkred', 'lightred', 'beige', 'darkblue', 'darkgreen', 'cadetblue', 'darkpurple', 'white', 'pink', 'lightblue', 'lightgreen', 'gray', 'black', 'lightgray']for idx, kmz_data in enumerate(kmz_data_list):color = colors[idx % len(colors)]for data in kmz_data['gps_data']:folium.CircleMarker([data['latitude'], data['longitude']],radius=0.5,color=color,fill=True,fill_color=color,fill_opacity=0.8).add_to(gps_map)for i in range(1, len(kmz_data['gps_data'])):start_point = kmz_data['gps_data'][i-1]end_point = kmz_data['gps_data'][i]folium.PolyLine(locations=[(start_point['latitude'], start_point['longitude']),(end_point['latitude'], end_point['longitude'])],color=color,weight=2).add_to(gps_map)folium.Marker(location=[(start_point['latitude'] + end_point['latitude']) / 2,(start_point['longitude'] + end_point['longitude']) / 2],icon=CustomIcon('https://upload.wikimedia.org/wikipedia/commons/e/e5/Black_triangle_pointing_right.svg',icon_size=(10, 10), icon_anchor=(5, 5))).add_to(gps_map)gps_map.save('multiple_kmz_map.html')print("GPS map saved as 'multiple_kmz_map.html'.")if __name__ == '__main__':directory_path = "F:\\notebookComputer\\20240723"kmz_files = find_kmz_files(directory_path)if kmz_files:kmz_data_list = []for kmz_file_path in kmz_files:kml_file_path = extract_kml_from_kmz(kmz_file_path)if kml_file_path:parsed_gps_data = parse_kml(kml_file_path)print(f"Parsed GPS data: {parsed_gps_data}")kmz_data_list.append({'file_name': os.path.basename(kmz_file_path),'gps_data': parsed_gps_data})if kmz_data_list:visualize_multiple_kmz_data(kmz_data_list)else:print("No GPS data available to visualize.")else:print(f"No .kmz files found in directory: {directory_path}")
5. 项目运行与结果展示
在代码执行完毕后,将会生成一个名为 multiple_kmz_map.html
的文件,该文件可以用浏览器打开以查看地图上的标记点和路径。地图将会显示所有 KMZ 文件中提取的 GPS 数据,每个文件的标记点使用不同的颜色表示。
multiple_kmz_map.html文件不好截图如下:
浏览器打开multiple_kmz_map.html文件效果图如下:
6. 总结与展望
本文详细介绍了如何使用 Python 处理 KMZ 文件,提取其中的 GPS 数据,并通过 Folium 库将其可视化。通过将 KMZ 文件中的地理数据转换为地图标记点和路径线,我们可以更直观地分析和展示地理数据。未来的工作可以包括支持更多的地理数据格式、添加更多的地图样式和功能、以及优化代码的性能和可读性。根据需求,文章可以继续扩展,以包含更多的技术细节、优化建议和实际应用场景的分析。
欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力 |
相关文章:
深入解析 KMZ 文件的处理与可视化:从数据提取到地图展示项目实战
文章目录 1. KMZ 文件与 KML 文件简介1.1 KMZ 文件1.2 KML 文件 2. Python 环境配置与依赖安装3. 代码实现详解3.1 查找 KMZ 文件3.2 解压 KMZ 文件3.3 解析 KML 文件3.4 可视化 KMZ 数据 4. 项目实战4.1. 数据采集4.2. 项目完整代码 5. 项目运行与结果展示6. 总结与展望 在处理…...
YOLOv5轻量化改进 | backbone | 结合MobileNetV4(包含多个结构和使用方式)
YOLOv5轻量化改进 | backbone | 结合MobileNetV4(包含多个结构) 本文介绍论文原理介绍网络代码多种yaml设置网络测试及实验结果<!-- 这里放入论文图片 -->  ;本文介绍 本文给大家带来的改进机制是结合MobileNetV4骨干网络,其中来自2024.5月发布的MobileNetV4…...
学习安卓开发遇到的问题
问题1:学习禁用与恢复按钮中: java代码报错:报错代码是 R.id.btn_enable;case R.id.btn_disable;case R.id.btn_test: 代码如下:(实现功能在代码后面) package com.example.apptest;import static java.…...
数学建模--禁忌搜索
目录 算法基本原理 关键要素 应用实例 实现细节 python代码示例 总结 禁忌搜索算法在解决哪些具体类型的组合优化问题中最有效? 禁忌搜索算法的邻域结构设计有哪些最佳实践或案例研究? 如何动态更新禁忌表以提高禁忌搜索算法的效率和性能&#…...
LeetCode 第136场双周赛个人题解
Q1. 求出胜利玩家的数目 原题链接 Q1. 求出胜利玩家的数目 思路分析 直接模拟 时间复杂度:O(N) AC代码 class Solution { public:int winningPlayerCount(int n, vector<vector<int>>& pick) {unordered_map<int, unordered_map<int, …...
The operation was rejected by your operating system. code CERT_HAS_EXPIRED报错解决
各种报错,试了清缓存,使用管理员权限打开命令行工具,更新npm,都不好使 最终解决:删除 c:/user/admin/ .npmrc...
[Git][基本操作]详细讲解
目录 1.创建本地仓库2.配置 Git3.添加文件1.添加文件2.提交文件3.其他 && 说明 4.删除文件5.跟踪修改文件6.版本回退7.撤销修改0.前言1.未add2.已add,未commit3.已add,已commit 1.创建本地仓库 创建⼀个Git本地仓库:git init运行该命…...
springMVC中从Excel文件中导入导出数据
目录 1. 数据库展示2. 导入依赖3. 写方法3.1 导入数据3.2 导出数据 4. 效果5. 不足6. 参考链接 1. 数据库展示 2. 导入依赖 pom.xml <!--文件上传处理--><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId>&…...
C++的STL简介(三)
目录 1.vector的模拟实现 1.1begin() 1.2end() 1.3打印信息 1.4 reserve() 1.5 size() 1.6 capacity() 1.7 push_back() 1.8[ ] 1.9 pop_back() 1.10 insert&…...
BERT模型
BERT模型是由谷歌团队于2019年提出的 Encoder-only 的 语言模型,发表于NLP顶会ACL上。原文题目为:《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》链接 在前大模型时代,BERT模型可以算是一个参数量比…...
举例说明计算机视觉(CV)技术的优势和挑战
计算机视觉(CV)技术是通过计算机模拟和处理图像与视频数据来模拟人类视觉的能力。它可以带来许多优势,也面临一些挑战。 优势: 自动化:CV技术可以自动处理大量的图像和视频数据,从而提高工作效率和准确性。…...
Animate软件基础:关于补间动画中的图层
Animate 文档中的每一个场景都可以包含任意数量的时间轴图层。使用图层和图层文件夹可组织动画序列的内容和分隔动画对象。在图层和文件夹中组织它们可防止它们在重叠时相互擦除、连接或分段。若要创建一次包含多个元件或文本字段的补间移动的动画,请将每个对象放置…...
mac|安装hashcat(压缩包密码p解)
一、安装Macports(如果有brew就不用这一步) 根据官网文档:The MacPorts Project -- Download & Installation,安装步骤如下 1、下载MacPorts,这里我用的是tar.gz ,可以通过keka(keka安装在…...
【保姆级系列:锐捷模拟器的下载安装使用全套教程】
保姆级系列:锐捷模拟器的下载安装使用全套教程 1.介绍2.下载3.安装4.实践教程5.验证 1.介绍 锐捷目前可以通过EVE-NG来模拟自己家的路由器,交换机,防火墙。实现方式是把自己家的镜像导入到EVE-ng里面来运行。下面主要就是介绍如何下载镜像和…...
virtualbox7安装centos7.9配置静态ip
1.背景 我大概在一年之前安装virtualbox7centos7.9的环境,但看视频说用vagrant启动的窗口可以不用第三方工具(比如xshell、secure等)连接centos7.9,于是尝鲜试了下还可以,导致系统文件格式是vmdk了(网上有vmdk转vdi的方法…...
结构型设计模式:桥接/组合/装饰/外观/享元
结构型设计模式:适配器/代理 (qq.com)...
vLLM初识(一)
vLLM初识(一) 前言 在LLM推理优化——KV Cache篇(百倍提速)中,我们已经介绍了KV Cache技术的原理,从中我们可以知道,KV Cache本质是空间换时间的技术,对于大型模型和长序列…...
【Apache Doris】周FAQ集锦:第 18 期
【Apache Doris】周FAQ集锦:第 18 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目! 在这个栏目中,每周将筛选社区反馈的热门问题和话题,重点回答并进行深入探讨。旨在为广大用户…...
docker部署可执行的jar
1.将项目打包,上传到服务器的指定目录 2.在该目录下创建Dockerfile文件 3.Dockerfile写入如下指令 # 基于哪个镜像 FROM java:8 # 拷贝文件到容器,也可以直接写成ADD xxxxx.jar /app.jar ADD springboot-file-0.0.1.jar file.jar RUN bash -c touch /…...
OpenCV||超详细的图像处理模块
一、颜色变换cvtColor dst cv2.cvtColor(src, code[, dstCn[, dst]]) src: 输入图像,即要进行颜色空间转换的原始图像。code: 转换代码,指定要执行的颜色空间转换类型。这是一个必需的参数,决定了源颜色空间到目标颜色空间的转换方式。dst…...
java面向对象期末总结
子类父类方法执行顺序?多态中和子类打印不一样; 子类在实现父类方法的时候没有用super关键字进行调用也会先执行父类的构造方法吗? 是的,当子类实例化时,先执行父类的构造方法,再执行子类的构造方法。即使在…...
文件搜索 36
删除文件 文件搜索 package File;import java.io.File;public class file3 {public static void main(String[] args) {search(new File("D :/"), "qq");}/*** 去目录搜索文件* param dir 目录* param filename 要搜索的文件名称*/public static void sear…...
IO多路转接
文章目录 五种IO模型fcntl多路转接selectpollepollepoll的工作模式 五种IO模型 阻塞IO: 在内核将数据准备好之前, 系统调用会一直等待. 所有的套接字, 默认都是阻塞方式.阻塞IO是最常见的IO模型。非阻塞IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULD…...
基于深度学习的面部表情分类识别系统
:温馨提示:文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 面部表情识别是计算机视觉领域的一个重要研究方向, 它在人机交互、心理健康评估、安全监控等领域具有广泛的应用。近年来,随着深度学习技术的快速发展…...
日志远程同步实验
目录 一.实验环境 二.实验配置 1.node1发送方配置 (1)node1写udp协议 (2)重启服务并清空日志 2.node2接收方配置 (1)node2打开接受日志的插件,指定插件用的端口 (2ÿ…...
数据结构之《二叉树》(中)
在数据结构之《二叉树》(上)中学习了树的相关概念,还了解的树中的二叉树的顺序结构和链式结构,在本篇中我们将重点学习二叉树中的堆的相关概念与性质,同时试着实现堆中的相关方法,一起加油吧! 1.实现顺序结构二叉树 在…...
php json_encode 参数 JSON_PRETTY_PRINT
https://andi.cn/page/621642.html...
【UE 网络】Gameplay框架在DS架构中的扮演的角色
目录 0 引言1 核心内容1.1 Gameplay各部分创建的流程1.2 Gameplay框架在DS和客户端的存在情况1.3 数据是独立存在于DS和客户端的 2 Gameplay框架各自负责的功能2.1 GameMode2.2 GameState2.3 PlayerController2.4 PlayerState2.5 Pawn2.6 AIController2.7 Actor2.8 HUD2.9 UI &…...
【云原生】StatefulSet控制器详解
StatefulSet 文章目录 StatefulSet一、介绍与特点1.1、介绍1.2、特点1.3、组成部分1.4、为什么需要无头服务1.5、为什么需要volumeClaimTemplate 二、教程2.1、创建StatefulSet2.2、查看部署资源 三、StatefulSet中的Pod3.1、检查Pod的顺序索引3.2、使用稳定的网络身份标识3.3、…...
使用 Python 制作一个属于自己的 AI 搜索引擎
1. 使用到技术 OpenAI KEYSerper KEYBing Search 2. 原理解析 使用Google和Bing的搜搜结果交由OpenAI处理并给出回答。 3. 代码实现 import requests from lxml import etree import os from openai import OpenAI# 从环境变量中加载 API 密钥 os.environ["OPENAI_AP…...
哪里有网站开发服务器/东莞seo网站推广建设
从去年上半年,公司就想搞考核,也就坚持了三个月的样子就不了了之了。年前公司领导更换后,又开始将考核提上日程,从过年到现在,将近半年过去了,考核还是没有落实下来。 公司上周六刚开了半年总结会议&#x…...
临安城市建设公司网站/百度总部客服电话
很多朋友经常会忘记Linux系统的root密码,linux系统忘记root密码的情况该怎么办呢?重新安装系统吗?当然不用!进入单用户模式更改一下root密码即可。 步骤如下: 重启linux系统 3 秒之内要按一下回车,出现如下…...
品牌商城网站建设公司/线上营销推广公司
因为我是做运维工作的,主要负责Linux系统交付这块的工作,所以经常需要查看系统的安装完成时间,来分析工作中的一些问题。查看的方法就是执行last命令,根据系统最近一次的启动时间和次数来判断是什么时候重装完成的。在这里简单的写…...
找人做网站怎么知道归属人/站长统计在线观看
近些天,在开发的时候,需要接入微信授权登陆,并且需求是登陆后需要将微信的昵称,此时如果微信昵称中有emoji表情,可能会导致数据库存储失败...因为mysql的utf8字符集不能存储emoji表情...主要解决办法有一下几种方式 存取微信昵称时候进行加解密操作# 存 base64_encode($wechatN…...
类似于微博网站怎么做/站长工具果冻传媒
其实,修片就是修生活,萝卜青菜各有所爱。我不知道最后出的风格是不是有人喜欢,反正我是喜欢的。世界上成功人士很多,他们就像航灯,指引着众生的方向。如果你不是成功人士,也许永远不会明白其中的酸甜苦辣。…...
做直销建立个人网站好吗/长沙网站seo优化
一、测试过程 使用在Docker run的时候使用--restart参数来设置。 no - container:不重启 on-failure - container:退出状态非0时重启 always:始终重启 [rootdocker ~]# docker run -i -t -d --name centos_aways --restartalways centos e278cabec91e36f5582d92ba…...