【.net core】.KMZ文件解压为.KML文件并解析为GEOJSON坐标数据集。附KML处理多线(LineString)闭环问题
通过使用ZipFile解压KMZ文件,获取其中的KML文件,并解析KML文件,输出解析后的坐标数据集。
KML文件:地理信息的标准格式
解析后的坐标数据集输出格式(GEOJSON坐标数据集):[[[经度,纬度],[经度,纬度]]]
解析类
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.IO;
using System.Xml;
using System.Linq;namespace WaterCloud.Code
{public static class KMZHelper{/// <summary>/// 解压 KMZ 文件到指定目录。/// </summary>/// <param name="kmzFilePath">kmz文件地址</param>/// <param name="extractDirectory">解压路径</param>/// <returns></returns>public static PlotCoordinateClass HandleKMZ(string kmzFilePath, string extractDirectory){PlotCoordinateClass plotCoordinate = new PlotCoordinateClass();try{if (!File.Exists(kmzFilePath)){Console.WriteLine($"错误: 文件 '{kmzFilePath}' 不存在。");LogHelper.WriteWithTime($"错误: 文件 '{kmzFilePath}' 不存在。");plotCoordinate.message = $"错误: 文件 '{kmzFilePath}' 不存在。";plotCoordinate.code = 1;return plotCoordinate;}if (string.IsNullOrWhiteSpace(extractDirectory)){// 使用临时目录extractDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());Console.WriteLine($"使用临时目录: {extractDirectory}");LogHelper.WriteWithTime($"使用临时目录: {extractDirectory}");}// 确保目录存在Directory.CreateDirectory(extractDirectory);// 解压 KMZ 文件ExtractKMZFile(kmzFilePath, extractDirectory);Console.WriteLine("KMZ 文件解压完成。");LogHelper.WriteWithTime($"KMZ 文件解压完成。");// 查找并读取 KML 文件string[] kmlFiles = Directory.GetFiles(extractDirectory, "*.kml", SearchOption.AllDirectories);if (kmlFiles.Length == 0){Console.WriteLine("警告: 在解压文件中未找到 KML 文件。");LogHelper.WriteWithTime("警告: 在解压文件中未找到 KML 文件。");plotCoordinate.message = ("警告: 在解压文件中未找到 KML 文件。");plotCoordinate.code = 1;return plotCoordinate;}Console.WriteLine($"找到 {kmlFiles.Length} 个 KML 文件:");LogHelper.WriteWithTime($"找到 {kmlFiles.Length} 个 KML 文件:");// 处理第一个 KML 文件plotCoordinate = KMLHelper.HandleKML(kmlFiles[0]);Console.WriteLine("\n处理完成。");LogHelper.WriteWithTime("\n处理完成。");return plotCoordinate;}catch (Exception ex){Console.WriteLine($"发生错误: {ex.Message}");LogHelper.WriteWithTime($"发生错误: {ex.Message}");plotCoordinate.message = $"发生错误: {ex.Message}";plotCoordinate.code = 1;return plotCoordinate;}}/// <summary>/// 解压 KMZ 文件到指定目录。/// </summary>/// <param name="kmzFilePath">kmz文件地址</param>/// <param name="extractDirectory">解压路径</param>public static void ExtractKMZFile(string kmzFilePath, string extractDirectory){try{using (ZipArchive archive = ZipFile.OpenRead(kmzFilePath)){foreach (ZipArchiveEntry entry in archive.Entries){string entryPath = Path.Combine(extractDirectory, entry.FullName);string entryDirectory = Path.GetDirectoryName(entryPath);// 确保目录存在if (!Directory.Exists(entryDirectory)){Directory.CreateDirectory(entryDirectory);}// 跳过目录条目if (entry.Length == 0){continue;}// 提取文件entry.ExtractToFile(entryPath, true);}}}catch (Exception ex){Console.WriteLine($"解压错误: {ex.Message}");throw;}}/// <summary>/// 截断字符串,如果长度超过指定最大长度则添加省略号。/// </summary>/// <param name="value"></param>/// <param name="maxLength"></param>/// <returns></returns>public static string TruncateString(string value, int maxLength){if (string.IsNullOrEmpty(value)){return value;}return value.Length <= maxLength? value: value.Substring(0, maxLength) + "...";}}public static class KMLHelper{/// <summary>/// 解析 KML 文件并提取坐标信息。/// </summary>/// <param name="kmlFilePath">kml文件地址</param>/// <returns></returns>public static PlotCoordinateClass HandleKML(string kmlFilePath){PlotCoordinateClass plotCoordinate = new PlotCoordinateClass();try{if (!File.Exists(kmlFilePath)){Console.WriteLine($"错误: 文件 '{kmlFilePath}' 不存在。");LogHelper.WriteWithTime($"错误: 文件 '{kmlFilePath}' 不存在。");plotCoordinate.message = ($"错误: 文件 '{kmlFilePath}' 不存在。");plotCoordinate.code = 1;return plotCoordinate;}// 加载 KML 文件XmlDocument kmlDoc = new XmlDocument();kmlDoc.Load(kmlFilePath);// 创建命名空间管理器,处理 KML 命名空间XmlNamespaceManager nsmgr = new XmlNamespaceManager(kmlDoc.NameTable);nsmgr.AddNamespace("kml", "http://www.opengis.net/kml/2.2");// 解析基本信息List<PlotCoordinateClass> plotCoordinates = ParseKmlDocument(kmlDoc, nsmgr);if (plotCoordinates != null && plotCoordinates.Count > 0) {// 取最大的坐标点数作为结果,如果有多个则取最大的一个plotCoordinate = plotCoordinates.OrderByDescending(a => a.PlotCoordinateCount).First();}Console.WriteLine("\n解析完成。");LogHelper.WriteWithTime("\n解析完成。");return plotCoordinate;}catch (Exception ex){Console.WriteLine($"发生错误: {ex.Message}");LogHelper.WriteWithTime($"发生错误: {ex.Message}");plotCoordinate.message = ($"发生错误: {ex.Message}");plotCoordinate.code = 1;return plotCoordinate;}}static List<PlotCoordinateClass> ParseKmlDocument(XmlDocument kmlDoc, XmlNamespaceManager nsmgr){List<PlotCoordinateClass> plotCoordinates = new List<PlotCoordinateClass>();// 获取文档名称XmlNode documentNode = kmlDoc.SelectSingleNode("//kml:Document", nsmgr);if (documentNode != null){XmlNode nameNode = documentNode.SelectSingleNode("kml:name", nsmgr);if (nameNode != null){Console.WriteLine($"文档名称: {nameNode.InnerText}");}// 解析文件夹plotCoordinates =ParseFolders(documentNode, nsmgr);// 解析地点标记//plotCoordinates = ParsePlacemarks(documentNode, nsmgr);}return plotCoordinates;}/// <summary>/// 解析文件夹及其子节点(地点标记和嵌套的文件夹)/// </summary>/// <param name="parentNode"></param>/// <param name="nsmgr"></param>/// <returns></returns>static List<PlotCoordinateClass> ParseFolders(XmlNode parentNode, XmlNamespaceManager nsmgr){List<PlotCoordinateClass> plotCoordinates = new List<PlotCoordinateClass>();XmlNodeList folderNodes = parentNode.SelectNodes("kml:Folder", nsmgr);if (folderNodes != null && folderNodes.Count > 0){Console.WriteLine("\n发现 {0} 个文件夹:", folderNodes.Count);foreach (XmlNode folderNode in folderNodes){XmlNode nameNode = folderNode.SelectSingleNode("kml:name", nsmgr);string folderName = nameNode != null ? nameNode.InnerText : "[未命名文件夹]";Console.WriteLine($" - 文件夹: {folderName}");// 递归解析文件夹中的地点标记List<PlotCoordinateClass> result = ParsePlacemarks(folderNode, nsmgr);plotCoordinates.AddRange(result);// 递归解析子文件夹plotCoordinates.AddRange(ParseFolders(folderNode, nsmgr));}}return plotCoordinates;}/// <summary>/// 解析地点标记(点、线、多边形)/// </summary>/// <param name="parentNode"></param>/// <param name="nsmgr"></param>/// <returns></returns>static List<PlotCoordinateClass> ParsePlacemarks(XmlNode parentNode, XmlNamespaceManager nsmgr){List<PlotCoordinateClass> plotCoordinateClasses = new List<PlotCoordinateClass>();XmlNodeList placemarkNodes = parentNode.SelectNodes("kml:Placemark", nsmgr);if (placemarkNodes != null && placemarkNodes.Count > 0){Console.WriteLine("\n发现 {0} 个地点标记:", placemarkNodes.Count);foreach (XmlNode placemarkNode in placemarkNodes){PlotCoordinateClass plotCoordinate = null;// 获取地点标记名称XmlNode nameNode = placemarkNode.SelectSingleNode("kml:name", nsmgr);string placemarkName = nameNode != null ? nameNode.InnerText : "[未命名地点]";Console.WriteLine($" - 地点: {placemarkName}");// 解析点XmlNode pointNode = placemarkNode.SelectSingleNode("kml:c", nsmgr);if (pointNode != null){ParsePoint(pointNode, nsmgr);}// 解析多边形XmlNode MultiGeometryNode = placemarkNode.SelectSingleNode("kml:MultiGeometry", nsmgr);if (MultiGeometryNode != null){XmlNode polygonNode = MultiGeometryNode.SelectSingleNode("kml:Polygon", nsmgr);if (polygonNode != null){plotCoordinate = ParsePolygon(polygonNode, nsmgr);if (plotCoordinate != null) plotCoordinateClasses.Add(plotCoordinate);}// 解析线XmlNodeList lineStringNodes = MultiGeometryNode.SelectNodes("kml:LineString", nsmgr);if (lineStringNodes != null && lineStringNodes.Count > 0){List< PlotCoordinateClass > tempList = new List<PlotCoordinateClass>();//获取所有线串节点数据foreach (XmlNode node in lineStringNodes) {plotCoordinate = ParseLineString(node, nsmgr);if (plotCoordinate != null) tempList.Add(plotCoordinate);}//闭合多边形区域,将多个线串整合为一个闭合的多边形区域,并添加处理结果到返回集合中。plotCoordinateClasses.Add(ClosePolygon(tempList));}}}}return plotCoordinateClasses;}/// <summary>/// 点处理方法/// </summary>/// <param name="pointNode"></param>/// <param name="nsmgr"></param>static void ParsePoint(XmlNode pointNode, XmlNamespaceManager nsmgr){XmlNode coordinatesNode = pointNode.SelectSingleNode("kml:coordinates", nsmgr);if (coordinatesNode != null && !string.IsNullOrWhiteSpace(coordinatesNode.InnerText)){string[] coords = coordinatesNode.InnerText.Trim().Split(',');if (coords.Length >= 2){double longitude = double.Parse(coords[0]);double latitude = double.Parse(coords[1]);double? altitude = coords.Length > 2 ? (double?)double.Parse(coords[2]) : null;Console.WriteLine($" 点坐标: 经度={longitude}, 纬度={latitude}{(altitude.HasValue ? $", 高度={altitude.Value}" : "")}");}}}/// <summary>/// 线处理方法/// </summary>/// <param name="lineStringNode"></param>/// <param name="nsmgr"></param>/// <returns></returns>private static PlotCoordinateClass ParseLineString(XmlNode lineStringNode, XmlNamespaceManager nsmgr){PlotCoordinateClass plotCoordinate = null;XmlNode coordinatesNode = lineStringNode.SelectSingleNode("kml:coordinates", nsmgr);if (coordinatesNode != null && !string.IsNullOrWhiteSpace(coordinatesNode.InnerText)){plotCoordinate = GetPlotCoordinate(coordinatesNode.InnerText);//string[] pointStrings = coordinatesNode.InnerText.Trim().Split(new[] { ' ', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);//Console.WriteLine($" 线串: {pointStrings.Length} 个点");}return plotCoordinate;}/// <summary>/// 多线闭环处理方法,将多个线串整合为一个闭合的多边形区域/// </summary>/// <param name="plotCoordinateClasses">多线集合</param>/// <returns></returns>private static PlotCoordinateClass ClosePolygon(List<PlotCoordinateClass> plotCoordinateClasses){PlotCoordinateClass plotCoordinate = new PlotCoordinateClass();//plotCoordinateClasses中的PlotCoordinates数据格式为[[[经度,纬度],[经度,纬度]]],需要将这些数据整合载入到一个List中List<List<List<double>>> plotCoordinates = new List<List<List<double>>>();if (plotCoordinateClasses != null && plotCoordinateClasses.Count > 0) {if (plotCoordinateClasses.Count == 1) {//如果只有一个区域,则直接返回第一个区域数据plotCoordinate = plotCoordinateClasses.First();}else {//处理多区域数据,将多个区域整合为一个区域foreach (PlotCoordinateClass item in plotCoordinateClasses){List<List<List<double>>> temp = JsonConvert.DeserializeObject<List<List<List<double>>>>(item.PlotCoordinates);if (temp != null && temp.Count > 0) {plotCoordinates.Add(temp.First());}}//调用序列化坐标数据方法获取处理结果List<List<List<double>>> result = SerializePlotCoordinate(plotCoordinates, plotCoordinates.First());if(result != null && result.Count > 0) {//创建新的坐标数据集合并将序列化结果赋值给新的坐标数据List<List<List<double>>> newCoordinates = new List<List<List<double>>>();List<List<double>> newNodes = new List<List<double>>();foreach (List<List<double>> item in result) {foreach (List<double> node in item) {newNodes.Add(node);}}newCoordinates.Add(newNodes);//将处理后的坐标数据赋值给PlotCoordinate对象plotCoordinate.PlotCoordinates = JsonConvert.SerializeObject(newCoordinates);plotCoordinate.CententCoordinate = JsonConvert.SerializeObject(newCoordinates.First().First());plotCoordinate.PlotCoordinateCount = newCoordinates.First().Count;plotCoordinate.code = 0;plotCoordinate.message = "处理成功";}}}return plotCoordinate;}/// <summary>/// 递归序列化区域坐标数据/// </summary>/// <param name="plotCoordinates">坐标数据集合,格式为"[[[经度,纬度],[经度,纬度]],[[经度,纬度],[经度,纬度]]]"</param>/// <param name="coordinates">初始依据坐标数据集,根据该参数处理后续节点内容</param>/// <returns></returns>private static List<List<List<double>>> SerializePlotCoordinate(List<List<List<double>>> plotCoordinates, List<List<double>> coordinates) {List<List<List<double>>> result = new List<List<List<double>>>();//将传入的坐标数据添加到结果中result.Add(coordinates);List<List<double>> nextCoordinates = new List<List<double>>();int deleteIndex = -1;//数据集删除索引//遍历传入的坐标数据集,判断当前传入坐标数据的后一个数据List<double> coordinatesLastNode = coordinates.Last();for (int i = 0; i < plotCoordinates.Count; i++) {List < List<double> > temp = plotCoordinates[i];temp = temp.Distinct().ToList();List<double> tempLastNode = temp.Last();List<double> tempFirstNode = temp.First();if (coordinatesLastNode.First().Equals(tempFirstNode.First())&& coordinatesLastNode.Last().Equals(tempFirstNode.Last())){//说明当前遍历数据temp的第一个节点与coordinates的最后一个节点相同,直接将temp的第一个节点删除,并将剩余数据添加到nextCoordinates中temp.RemoveAt(0);nextCoordinates.AddRange(temp);deleteIndex = i;//获取删除索引break;}else if (coordinatesLastNode.First().Equals(tempLastNode.First())&& coordinatesLastNode.Last().Equals(tempLastNode.Last())){//说明当前遍历数据temp的最后一个节点与coordinates的最后一个节点相同,需要将temp翻转后,删除第一个节点,并将剩余数据添加到nextCoordinates中temp.Reverse();temp.RemoveAt(0);nextCoordinates.AddRange(temp);deleteIndex = i;//获取删除索引break;}else {//未匹配的情况,跳出当前循环,遍历下一个节点continue;}}if (deleteIndex != -1) { //如果存在删除索引,则从数据集中删除该节点plotCoordinates.RemoveAt(deleteIndex);}if (plotCoordinates != null && plotCoordinates.Count > 0){//如果数据集不为空,则继续递归调用该方法result.AddRange(SerializePlotCoordinate(plotCoordinates, nextCoordinates));}else {//如果数据集为空,则将nextCoordinates添加到结果中result.Add(nextCoordinates);}return result;}/// <summary>/// 区域处理方法/// </summary>/// <param name="polygonNode"></param>/// <param name="nsmgr"></param>/// <returns></returns>private static PlotCoordinateClass ParsePolygon(XmlNode polygonNode, XmlNamespaceManager nsmgr){PlotCoordinateClass plotCoordinate = null;XmlNode outerBoundaryNode = polygonNode.SelectSingleNode("kml:outerBoundaryIs", nsmgr);if (outerBoundaryNode != null){XmlNode linearRingNode = outerBoundaryNode.SelectSingleNode("kml:LinearRing", nsmgr);if (linearRingNode != null){XmlNode coordinatesNode = linearRingNode.SelectSingleNode("kml:coordinates", nsmgr);if (coordinatesNode != null && !string.IsNullOrWhiteSpace(coordinatesNode.InnerText)){//string[] pointStrings = coordinatesNode.InnerText.Trim().Split(new[] { '0',' ', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);//获取区域坐标集合plotCoordinate = GetPlotCoordinate(coordinatesNode.InnerText);}}}// 解析内圈(洞)XmlNodeList innerBoundaryNodes = polygonNode.SelectNodes("kml:innerBoundaryIs", nsmgr);if (innerBoundaryNodes != null && innerBoundaryNodes.Count > 0){Console.WriteLine($" 多边形内圈: {innerBoundaryNodes.Count} 个");foreach (XmlNode innerBoundaryNode in innerBoundaryNodes){XmlNode linearRingNode = innerBoundaryNode.SelectSingleNode("kml:LinearRing", nsmgr);if (linearRingNode != null){XmlNode coordinatesNode = linearRingNode.SelectSingleNode("kml:coordinates", nsmgr);if (coordinatesNode != null && !string.IsNullOrWhiteSpace(coordinatesNode.InnerText)){plotCoordinate = GetPlotCoordinate(coordinatesNode.InnerText);string[] pointStrings = coordinatesNode.InnerText.Trim().Split(new[] { ' ', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);Console.WriteLine($" 内圈: {pointStrings.Length} 个点");}}}}return plotCoordinate;}/// <summary>/// 获取区域坐标/// </summary>/// <param name="InnerText"></param>/// <returns></returns>private static PlotCoordinateClass GetPlotCoordinate(string InnerText){PlotCoordinateClass plotCoordinate = new PlotCoordinateClass();List<string> coordinates = InnerText.Trim().Split(",0").ToList();if (coordinates != null && coordinates.Count > 0){coordinates = coordinates.Where(a => !string.IsNullOrEmpty(a)).ToList();coordinates.ForEach(a =>{a = a.Trim();});}plotCoordinate.code = 0;List<List<List<double>>> PlotCoordinates = GetCoordinatesList(coordinates);if ((PlotCoordinates != null && PlotCoordinates.Count > 0) &&(PlotCoordinates[0] != null && PlotCoordinates[0].Count > 0)){plotCoordinate.PlotCoordinates = JsonConvert.SerializeObject(PlotCoordinates);plotCoordinate.CententCoordinate = JsonConvert.SerializeObject(PlotCoordinates[0][0]);plotCoordinate.PlotCoordinateCount = PlotCoordinates[0].Count;plotCoordinate.code = 0;plotCoordinate.message = "数据获取成功";}else{plotCoordinate.code = 1;plotCoordinate.message = "数据获取失败";}return plotCoordinate;}/// <summary>/// 获取坐标集合/// </summary>/// <param name="coordinates"></param>/// <returns></returns>private static List<List<List<double>>> GetCoordinatesList(List<string> coordinates){List<List<List<double>>> result = new List<List<List<double>>>();List<List<double>> secondList = new List<List<double>>();foreach (string item in coordinates){//List<double> ints = item.Split(",").Select(a => Math.Round(a.ToDouble(), 6)).ToList();List<double> ints = item.Split(",").Select(a => a.ToDouble()).ToList();if (ints != null && ints.Count > 1) {var gcjCoord = WGS84ToGCJ02Helper.Wgs84ToGcj02(ints[0], ints[1]);ints[0] = gcjCoord.lng;ints[1] = gcjCoord.lat;secondList.Add(ints);}}result.Add(secondList);return result;}}/// <summary>/// 区域坐标类/// </summary>public class PlotCoordinateClass{/// <summary>/// 地块坐标集合,格式为"[[[经度,纬度],[经度,纬度]]]"/// </summary>public string PlotCoordinates { get; set; }/// <summary>/// 地块中心坐标,格式为"[经度,纬度]"/// </summary>public string CententCoordinate { get; set; }/// <summary>/// 区域坐标数量/// </summary>public int PlotCoordinateCount { get; set; }/// <summary>/// 解析状态码,0为成功,1为失败。默认为0/// </summary>public int code { get; set; }/// <summary>/// 解析状态信息,默认为"成功"。失败时为具体错误描述。/// </summary>public string message { get; set; }}}
调用
PlotCoordinateClass plotCoordinate = null;
//调用解压KMZ文件并解析解压后的KML文件并返回结果
plotCoordinate = KMZHelper.HandleKMZ("/your/kmzFile/path","/your/kmzFile/extractDirectory");
//调用解析KML文件并返回解析结果
plotCoordinate = KMLHelper.HandleKML("/your/kmlFile/path");
相关文章:
【.net core】.KMZ文件解压为.KML文件并解析为GEOJSON坐标数据集。附KML处理多线(LineString)闭环问题
通过使用ZipFile解压KMZ文件,获取其中的KML文件,并解析KML文件,输出解析后的坐标数据集。 KML文件:地理信息的标准格式 解析后的坐标数据集输出格式(GEOJSON坐标数据集):[[[经度,纬度],[经度,纬度]]] 解…...
Python打卡训练营day46——2025.06.06
知识点回顾: 不同CNN层的特征图:不同通道的特征图什么是注意力:注意力家族,类似于动物园,都是不同的模块,好不好试了才知道。通道注意力:模型的定义和插入的位置通道注意力后的特征图和热力图 …...
网络资源缓存
前端性能优化是提升用户体验和页面响应速度的关键,可以从 网络优化、资源优化、缓存优化 三个方面系统地进行。以下是详细说明: 一、网络优化(减少请求数、降低延迟、提升加载速度) 减少 HTTP 请求数量 合并请求(CSS…...
Linux中 SONAME 的作用
🧠 一、从 -lexample 到 SONAME ✅ 假设你有以下文件结构: /libexample.so → libexample.so.1 /libexample.so.1 → libexample.so.1.0.0 /libexample.so.1.0.0 # SONAME: libexample.so.1/libexample.so.2 → libexample.so.2.0.0 /libexample.so.2.0…...

Devops系列---python基础篇二
1、列表 1.1 概念 格式: 名称 [ “元素1”,“元素2”,…] #定义一个列表 computer ["主机","键盘","显示器","鼠标"]类型方法用途查index(“元素”)查看元素索引位置count(“元素”)统计元素出现的次数reverse()倒序排…...
自定义事件wpf
// 自定义控件 public class MyCustomControl : Control { public static readonly RoutedEvent MyCustomEvent EventManager.RegisterRoutedEvent( "MyCustom", RoutingStrategy.Bubbling, typeof(RoutedEventHandler), typeof(MyCustomControl) ); public event R…...

TLV4062-Q1、TLV4082-Q1迟滞电压比较器应用笔记
文章目录 主要作用应用场景关键优势典型应用示意图TLV4062-Q1 和 TLV4082-Q1 的主要作用及应用场景如下: 主要作用 精密电压监测:是一款双通道、低功耗比较器,用于监测输入电压是否超过预设阈值。 集成高精度基准电压源(阈值精度1%),内置60mV迟滞功能,可避免因噪声导致的…...
C++.OpenGL (3/64)着色器(Shader)深入
着色器(Shader)深入 着色器核心概念 #mermaid-svg-xC0jTt9mJWGVa7yE {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-xC0jTt9mJWGVa7yE .error-icon{fill:#552222;}#mermaid-svg-xC0jTt9mJWGVa7yE .error-text{fi…...

DHCP介绍
DHCP介绍 1 DHCP简述2 DHCP协议分析2.1 主要流程2.2 DHCP全部报文介绍2.3 IP租用更新报文2.4 DHCP协议抓包分析 3 DHCP应用3.1 DNSmasq参数配置3.2 DNSmasq框架代码3.2.1 创建socket监听67端口3.2.2 监听67端口3.2.3 处理DHCP请求 3.3 DNSmasq模块排障方法 4 常见问题排查4.1 问…...
李沐《动手学深度学习》d2l安装教程
文章目录 最新回答报错提醒安装对应版本安装C工具和Windows SDK 最新回答 安装旧版本即可 pip install d2l0.17.0 WARNING: Ignoring invalid distribution -pencv-python (e:\python3.10\lib\site-packages) Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple C…...

[蓝桥杯]耐摔指数
耐摔指数 题目描述 X 星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。 各大厂商也就纷纷推出各种耐摔型手机。X 星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。…...
深入理解数字音频:采样率、位深与量化
在当今数字时代,音频技术已经渗透到我们生活的方方面面——从流媒体音乐到视频会议,从播客到智能家居。但你是否曾好奇过,这些美妙的声音是如何被捕捉、存储并在数字世界中重现的?本文将带你深入了解数字音频的核心概念࿰…...

2024年第十五届蓝桥杯青少Scratch初级组-国赛—画矩形
2024年第十五届蓝桥杯青少Scratch初级组-国赛—画矩形 题目点下方,支持在线编程,在线获取源码和素材~ 画矩形_scratch_少儿编程题库学习中心-嗨信奥 程序演示可点下方,支持源码获取~ 画矩形-scratch作品-少儿编程题库…...
java面试场景题: 设计⼀个微博系统
微博系统设计指南:从理论到实践 系统设计考察的核心能力 系统设计面试模拟真实工作场景,候选人需与面试官协作解决模糊问题。关键在于沟通、分析和权衡能力,而非追求完美方案。面试官关注思考过程,而非最终答案。 常见误区与改…...
市面上哪款AI开源软件做ppt最好?
市面上哪款AI开源软件做ppt最好? aippt:AiPPT - 全智能 AI 一键生成 PPT 网站形式,需要注册 ai to pptx :SmartSchoolAI/ai-to-pptx: 前端后端同时开源。 Ai-to-pptx是一个使用AI技术(DeepSeek)制作PPTX的助手,支持在…...

JMM初学
文章目录 1,线程间的同步和通信1.1, 共享内存并发模型 (Shared Memory Model)线程通信机制线程同步机制特点 1.2, 消息传递并发模型 (Message Passing Model)线程通信机制线程同步机制特点 适用场景对比 2,Java内存模型JMM2.0,Java内存模型的基础(1)内存…...
transformer和 RNN以及他的几个变体区别 改进
Transformer、RNN 及其变体(LSTM/GRU)是深度学习中处理序列数据的核心模型,但它们的架构设计和应用场景有显著差异。以下从技术原理、优缺点和适用场景三个维度进行对比分析: 核心架构对比 模型核心机制并行计算能力长序列依赖处…...

构建云原生安全治理体系:挑战、策略与实践路径
📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:从传统安全走向“云原生安全” 随着企业 IT 架构从传统单体系统向容器化、微服务和云原生平台转型…...
vue-print-nb 打印相关问题
一、背景与解决方案 1、ElementUI表格打印通病,均面临边框丢失、宽度超出问题:相关解决代码有注释; 2、大多数情况下不会打印页眉页脚的日期、网址、未配置popTitle显示的undefined:相关解决代码有注释; 3、打印预览页…...

vcs仿真产生fsdb波形的两种方式
目录 方法一: 使用verilog自带的系统函数 方法二: 使用UCLI command 2.1 需要了解什么是vcs的ucli,怎么使用ucli? 2.2 使用ucli dump波形的方法 使用vcs仿真产生fsdb波形有两种方式,本文参考《vcs user guide 20…...
每日算法 -【Swift 算法】三数之和
Swift|三数之和(3Sum)详细题解 注释 拓展(LeetCode 15) ✨题目描述 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a, b, c,使得 a b c 0。请你找出所有和为 0 且不重…...

Go语言底层(三): sync 锁 与 对象池
1. 背景 在并发编程中,正确地管理共享资源是构建高性能程序的关键。Go 语言标准库中的 sync 包提供了一组基础而强大的并发原语,用于实现安全的协程间同步与资源控制。本文将简要介绍 sync 包中常用的类型和方法: sync 锁 与 对象池,帮助开发…...
登高架设作业操作证考试:理论题库高频考点有哪些?
一、安全基础知识 法律法规 《安全生产法》《特种作业人员安全技术培训考核管理规定》中关于登高作业的强制性要求(如持证上岗、培训时限等)。 事故责任划分:未系安全带、无监护作业等违规行为的法律后果。 个人防护 安全带使用标准&#…...

2025年06月06日Github流行趋势
项目名称:agent-zero 项目地址url:https://github.com/frdel/agent-zero项目语言:Python历史star数:8958今日star数:324项目维护者:frdel, 3clyp50, linuztx, evrardt, Jbollenbacher项目简介:A…...
华为云CentOS配置在线yum源,连接公网后,逐步复制粘贴,看好自己对应的版本即可,【新手必看】
华为云镜像源配置 YUM 源的详细步骤: 1. 备份原有的 YUM 源配置文件 在修改 YUM 源之前,建议备份原有的配置文件。通常,YUM 源的配置文件位于 /etc/yum.repos.d/ 目录下。例如,备份 CentOS 的默认 YUM 源配置文件: …...
http头部注入攻击
1.HTTP请求的组成部分 HTTP(HyperText Transfer Protocol)请求由 请求行(Request Line)、请求头(Headers)、空行(Blank Line)和请求体(Request Body) 组成。具体结构如下: 1. 请求行(Request Line) 请求行是HTTP请求的第一行,包含三个部分…...
三类 Telegram 账号的风控差异分析与使用建议
在使用 Telegram 过程中,很多用户会遇到账号被限制、封禁、加群失败等问题。除了操作行为外,账号本身的注册方式、活跃时间、环境匹配程度也会直接影响风控等级。 本篇文章从账号风控角度出发,分析三类常见 Telegram 账号的特点与适用环境&am…...
Matlab | matlab中的点云处理详解
点云处理 ⚙️ **一、点云基础操作**🧹 **二、点云预处理**📊 **三、特征提取与分析**🔄 **四、点云配准(对齐点云)**🔷 **五、三维重建与应用**⚡️ **六、高级功能与性能优化**💎 **七、实战技巧与参数调优**📚 **学习资源**MATLAB 的点云处理能力主要依赖 Poi…...
【机试题解法笔记】寻找最大价值的矿堆
题目 给你一个由 0(空地)、1(银矿)、2(金矿) 组成的的地图,矿堆只能由上下左右相邻的金矿或银矿连接形成。超出地图范围可以认为是空地。 假设银矿价值 1,金矿价值 2,请你找出地图中最大价值的矿堆并输出该矿堆的价值。 输入描述 地图元素信…...

动态规划 熟悉30题 ---上
本来是要写那个二维动态规划嘛,但是我今天在问题时候,一个大佬就把他初一时候教练让他练dp的30题发出来了(初一,啊虽然知道计算机这一专业,很多人从小就学了,但是我每次看到一些大佬从小学还是会很羡慕吧或…...