测绘工具箱(1)坐标txt生成KML文件

作为一名测量工程师,日常扛杆扶尺,做控制、测地形图,经常需要利用工具生成kml文件导入手簿。
刚好最近项目空档期,心血来潮就研究了一下kml文件,发现是xml格式的文档,于是利用C#参照测量软件生成的kml格式写了一段生成kml文件的代码。
计划今年有时间自己写一个测量工具集合的小软件,那就先从这个功能开始吧。
本段代码的生成格式为序号,纬度,经度,经纬度单位为度

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;

namespace KmlGenerator
{
    //实验发现标签的经纬度和谷歌地图上的经纬度是反的
    //文件格式需要为 序号,纬度,经度
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("请选择输入方式: 1 - 从TXT文件读取");
            var input = Console.ReadLine();

            List<Coordinate> coordinates = new List<Coordinate>();

            string fileDir = null;//声明时必须有值,因此设置坐标txt所在目录为null
            string fileName = null;//声明时必须有值,因此设置声明坐标txt名称为为null
            
            if (input == "1")
            {
                Console.WriteLine("请输入TXT文件路径:");

                string txtFilePath = Console.ReadLine();
                coordinates = ReadCoordinatesFromTxt(txtFilePath);

                fileDir = Path.GetDirectoryName(txtFilePath);
                fileName = Path.GetFileNameWithoutExtension(txtFilePath);
            }
            else
            {
                Console.WriteLine("无效的输入选项");
                return;
            }
            //生成kml文件目录
            string kmlFilePath = fileDir + "\\"+ fileName + ".kml";

            GenerateKmlFile(coordinates, kmlFilePath);
            Console.WriteLine($"KML文件已生成: {Path.GetFullPath(kmlFilePath)}");
        }

        //坐标转换方法
        static List<Coordinate> ReadCoordinatesFromTxt(string filePath)
        {
            if (!File.Exists(filePath))
                throw new FileNotFoundException($"文件不存在: {filePath}");

            var coordinates = new List<Coordinate>();

            foreach (string line in File.ReadAllLines(filePath))
            {
                if (string.IsNullOrWhiteSpace(line))
                    continue;

                string[] parts = line.Split(',');
                if (parts.Length != 3)
                    throw new FormatException($"无效的坐标格式: {line}");

                try
                {
                    coordinates.Add(new Coordinate
                    {
                        Latitude = double.Parse(parts[1].Trim()),
                        Longitude = double.Parse(parts[2].Trim())
                    });
                }
                catch (FormatException)
                {
                    throw new FormatException($"无效的坐标值: {line}");
                }
            }

            if (coordinates.Count == 0)
                throw new Exception("文件中没有有效的坐标数据");

            return coordinates;
        }

        //生成xml格式的kml文件
        static void GenerateKmlFile(List<Coordinate> coordinates, string filePath)
        {
            if (coordinates == null || coordinates.Count == 0)
                throw new ArgumentException("坐标列表不能为空");

            // 创建KML文档结构
            XNamespace ns = "http://www.opengis.net/kml/2.2";
            XNamespace gx = "http://www.google.com/kml/ext/2.2";
            XNamespace kml = "http://www.opengis.net/kml/2.2";
            XNamespace atom = "http://www.w3.org/2005/Atom";

            XDocument kmlDoc = new XDocument(
                new XDeclaration("1.0", "UTF-8", "yes"),
                new XElement(ns + "kml",
                    new XAttribute(XNamespace.Xmlns + "gx", gx),
                    new XAttribute(XNamespace.Xmlns + "kml", kml),
                    new XAttribute(XNamespace.Xmlns + "atom", atom),
                    new XAttribute("xmlns", ns),
                    //new XElement(ns + "Document",
                        new XElement(ns + "Folder",
                            new XElement(ns + "name", "txttokml"),
                            coordinates.Select((coord, index) =>
                                new XElement(ns + "Placemark",
                                    new XElement(ns + "name", index + 1),
                                    new XElement(ns + "LookAt",
                                        new XElement(ns + "longitude", coord.Longitude),
                                        new XElement(ns + "latitude", coord.Latitude),
                                        new XElement(ns + "altitude", "0"),
                                        new XElement(ns + "heading", "0"),
                                        new XElement(ns + "tilt", "0"),
                                        new XElement(ns + "range", "1000")
                                    ),
                                    new XElement(ns + "Point",
                                        new XElement(ns + "coordinates", $"{coord.Latitude},{coord.Longitude},0")
                                 )
                            )
                        ),
                        
                        // 连接线(LineString)的Placemark 
                        new XElement(ns + "Placemark",
                            new XElement(ns + "name", "NONAME"),
                            new XElement(ns + "LookAt",
                                new XElement(ns + "longitude", coordinates.Last().Longitude),
                                new XElement(ns + "latitude", coordinates.Last().Latitude),
                                new XElement(ns + "altitude", "0"),
                                new XElement(ns + "heading", "0"),
                                new XElement(ns + "tilt", "0"),
                                new XElement(ns + "range", "1000")
                            ),
                            new XElement(ns + "LineString",
                                new XElement(ns + "tessellate", "1"),
                                new XElement(ns + "coordinates",
                                    string.Join(" ", coordinates.Select(c => $"{c.Latitude},{c.Longitude},0"))
                                )
                            )
                        )
                    )
                )
            );

            kmlDoc.Save(filePath);
        }
    }

    //定义坐标类
        public class Coordinate
    {
        public double Longitude { get; set; }
        public double Latitude { get; set; }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值