zoukankan      html  css  js  c++  java
  • 解析KML文件并提取coordinates中的经纬度坐标信息

    从googleEarh导出的kml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
    <Document>
      <!-- Begin Style Definitions -->
      <Style id="line1">
        <LineStyle>
          <color>FF808080</color>
          <width>1</width>
        </LineStyle>
      </Style>
      <Folder>
        <name>Line Features</name>
        <description>Line Features</description>
        <Placemark>
          <description>Unclassified Line Feature</description>
          <styleUrl>#line1</styleUrl>
          <LineString>
            <coordinates>
              115.9676728167,40.4840735806,0
              115.9537842111,40.4823857889,0
              115.9563131444,40.4703987611,0
              115.9551753833,40.4662973972,0
              115.9554458000,40.4636396361,0
              115.9397187972,40.4622803889,0
              115.9405904556,40.4562066889,0
              115.9408371611,40.4549313694,0
              115.9422346222,40.4538901583,0
              115.9448324639,40.4514630028,0
              115.9574561306,40.4524817889,0
              115.9619367944,40.4513946639,0
            </coordinates>
          </LineString>
        </Placemark>
      </Folder>
    </Document>
    </kml>

    做工程中遇到需要解析kml文件并提取其中的经纬度坐标信息的需求,从网上查了一圈资料发现都不好用,干脆自己写,用正则表达式regex和split()方法实现了坐标信息提取功能。

    主要遇到的问题是coordinates中的InnerText文本中有   f 或多空格问题,需要将这些因素排除。

    f 匹配一个换页符
    匹配一个换行符
    匹配一个回车符
    匹配一个制表符

    这些符号用正则表达式字符替换方式直接清除

    Regex reg = new Regex("f| | | ");
    string modified = reg.Replace(tt, "");

    多空格问题用split的StringSplitOptions.RemoveEmptyEntries来清除

    string[] ss = modified.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);//清除空格

    这样就能得到纯粹的x,y,z字符串数组了.OK。

     ***********************************************************************************************************************************************

    想了2种思路,目前第1种思路已经测试通过了,第2种思路懒得写了,哪位如果有兴趣实现了的话告诉我一声喔,,也算是饮水思源啦。

    ************************************************************************************************************************************************

    代码如下:

    private void KMLFileLoadButton_Click(object sender, EventArgs e)
    {// 读取googleEarth的导出的kml/kmz路径文件
                OpenFileDialog dlg = new OpenFileDialog();
                dlg.Filter = "KML文件(*.kml)|*.kml|所有文件|*.*";
                if (dlg.ShowDialog() != DialogResult.OK)
                    return;
                string destPath = dlg.FileName;//CopyToRelavitePath(dlg.FileName);
                if (destPath == null)
                    return;

                XmlDocument xmldoc = new XmlDocument();
                xmldoc.Load(destPath);
                XmlElement root = xmldoc.DocumentElement;
                /////规范命名空间
                XmlNode _document = root.GetElementsByTagName("Document")[0];
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmldoc.NameTable);
                if (_document== null || _document.Attributes["xmlns"]==null)
                {
                    nsmgr.AddNamespace("ns", root.Attributes["xmlns"].Value);
                }
                else
                {
                    nsmgr.AddNamespace("ns", _document.Attributes["xmlns"].Value);
                }

                NGlbLine geo = new NGlbLine(3, false);
                XmlNodeList xmlmark = root.GetElementsByTagName("Placemark");
                for (int m = 0; m < xmlmark.Count; m++)
                {
                    XmlNodeList xmlmarkChilds = xmlmark[m].ChildNodes;
                    for (int n = 0; n < xmlmarkChilds.Count; n++)
                    {
                        XmlNode node = xmlmarkChilds[n];
                        if (node.Name == "LineString" || node.Name == "LineRing")
                        {
                            XmlNode coordsNode = node.FirstChild;
                            while (coordsNode != null && coordsNode.Name != "coordinates")
                            {
                                coordsNode = coordsNode.NextSibling;
                            }
                            if (coordsNode == null)
                                continue;
                            // 思路1 :用正则表达式去除字符串首位的制表符、换行符等符号,然后用' '来划分为string[]
                            string tt = coordsNode.InnerText;
                            Regex reg = new Regex("f| | | ");
                            string modified = reg.Replace(tt, "");
                            string[] ss = modified.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);//清除空格
                            for (int cc = 0; cc < ss.Length; cc++)
                            {
                                string[] aa = ss[cc].Split(',');
                                if (aa.Length == 3)                           
                                    geo.AddPoint(Convert.ToDouble(aa[0]), Convert.ToDouble(aa[1]), Convert.ToDouble(aa[2]));                            
                                else if (aa.Length == 2)                            
                                    geo.AddPoint(Convert.ToDouble(aa[0]), Convert.ToDouble(aa[1]), 0);                                                       
                            }
                            
                            // 思路2 :用regex正则表达式匹配 类似 115.9676728167,40.4840735806,0的样式字段

                        }
                    }
                }

      .............................................
     }

  • 相关阅读:
    C++编程练习(3)----“实现简单的栈的顺序存储结构“
    C++编程练习(2)----“实现简单的线性表的链式存储结构“
    C++编程练习(1)----“实现简单的线性表的顺序存储结构“
    Django--登录实例
    Django--model模型绑定_数据库操作
    Django--初始化
    web框架--MVC、MTV
    CSS--箭头
    CSS--抽屉(dig.chouti.com)页面
    jQuery--加一行减一行
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/8182843.html
Copyright © 2011-2022 走看看