最近在研究Kml怎么转化为Shape文件,因为客户中很多在原来采集了一部分数据都是在google Earth中,而我们的应用中特别需要这份数据,所以打算先在GE中把这份数据导出为Kml或Kmz文件,然后我们的应用系统把Kml或Kmz数据转化为Shape,再导入到系统中。

这样做优点是:导出的Shape数据能够在很多GIS平台中读取,缺点是,会丢失Kml或Kmz的符号等信息;

我们第一阶段的目标是:只解析Kml中的点、线、面,对于贴地图片什么的暂时不考虑;

在以上的目的上我们选择了GDAL作为GIS的平台,之所以选择他是因为他不需要安装直接部署就能使用(绿色),查找一些资料发现OGR可以解析Kml数据,但是我却没有找到相关的资料方法,所以索性,自己解析Kml,要解析Kml看了好些Kml的编码资料,大概找出了编码规则开始着手解析;废话少说,直接补充解析的代码:

1.KMLPlacemarker接口,包含了Kml中Placemarker下的信息

/// <summary>
    /// IKMLPlacemarker
    /// </summary>
    public interface IKMLPlacemarker
    {
        #region 成员属性

/// <summary>
        /// 名称
        /// </summary>
        string Name { set; get; }

/// <summary>
        /// 描述信息
       
        string Description { set; get; }

/// <summary>
        /// 样式路径
        /// </summary>
        string StyleURL { set; get; }

/// <summary>
        /// 图形类型
        /// </summary>
        enumKmlGeometryType GeometryType { set; get; }

/// <summary>
        /// KMLGeometry
        /// </summary>
        IKMLGeometry Geometry { set; get; }

#endregion

#region 成员方法

/// <summary>
        /// 初始化
        /// </summary>
        /// <param name="placemarkerNode">PlacemarkerNode</param>
        /// <returns>是否成功</returns>
        bool Initial(System.Xml.XmlNode  placemarkerNode)   ;
                  
        #endregion
    }

2.KMLGeometry空接口,作为KMLPlacemarker的一个属性

/// <summary>
    /// KMLGeometry
    /// </summary>
    public interface IKMLGeometry
    {
    }

3.KMLPoint接口 KML中点

/// <summary>
    /// IKMLPoint
    /// </summary>
    public interface IKMLPoint
    {
        #region 成员属性

/// <summary>
        /// 坐标信息
        /// </summary>
        string Coordinates { set; get; }

#endregion

#region 成员方法

/// <summary>
        /// 初始化
        /// </summary>
        /// <param name="pointXmlNode">point节点</param>
        /// <returns>是否成功</returns>
        bool InitialPoint(System.Xml.XmlNode pointXmlNode);

#endregion
    }

4. KMLPolyline接口 KML中线类型

/// <summary>
    /// IKMLPolyLine
    /// </summary>
    public interface IKMLPolyline
    {
        #region 成员属性

/// <summary>
        /// 坐标信息
        /// </summary>
        string Coordinates { set; get; }

#endregion

#region 成员方法

/// <summary>
        /// 初始化
        /// </summary>
        /// <param name="polylineXmlNode">polyLine节点</param>
        /// <returns>是否成功</returns>
        bool InitialPolyline(System.Xml.XmlNode polylineXmlNode);

#endregion
    }

5.KMLPolygon接口 Kml中的面类型(不是多面,是面)

/// <summary>
    /// IKMLPolygon
    /// </summary>
    public interface IKMLPolygon
    {
        #region 成员属性

/// <summary>
        /// 坐标信息-内轮廓
        /// </summary>
        string Coordinates_InnerBoundary { set; get; }

/// <summary>
        /// 坐标信息-外轮廓
        /// </summary>
        string Coordinates_OuterBoundary { set; get; }

#endregion

#region 成员方法

/// <summary>
        /// 初始化
        /// </summary>
        /// <param name="polygonXmlNode">polyLine节点</param>
        /// <returns>是否成功</returns>
        bool InitialPolygon(System.Xml.XmlNode polygonXmlNode);

#endregion
    }

6. KMLPoint的实现

/// <summary>
    /// KMLPoint
    /// </summary>
    public class KMLPoint : IKMLPoint, IKMLGeometry
    {
        #region IKMLPoint 成员

#region 成员属性

/// <summary>
        /// 坐标信息
        /// </summary>
        public string Coordinates { set; get; }

#endregion

#region 成员方法

/// <summary>
        /// 初始化
        /// </summary>
        /// <param name="pointXmlNode">point节点</param>
        /// <returns>是否成功</returns>
        public bool InitialPoint(System.Xml.XmlNode pointXmlNode)
        {
            System.Xml.XmlNode childNode = null;
            for (int k = 0; k < pointXmlNode.ChildNodes.Count; k++)
            {
                childNode = pointXmlNode.ChildNodes[k];
                switch (childNode.Name)
                {
                    case "coordinates":
                        {
                            this.Coordinates = childNode.InnerText;
                            break;
                        }
                    default:
                        {
                            break;
                        }
                }
            }

return true;
        }

#endregion

#endregion
    }

7.KMLPolyline的实现

/// <summary>
    /// KMLPolyline
    /// </summary>
    public class KMLPolyline : IKMLPolyline, IKMLGeometry
    {
        #region IKMLPolyline 成员

#region 成员属性

/// <summary>
        /// 坐标信息
        /// </summary>
        public string Coordinates { set; get; }

#endregion

#region 成员方法

/// <summary>
        /// 初始化
        /// </summary>
        /// <param name="polylineXmlNode">polyLine节点</param>
        /// <returns>是否成功</returns>
        public bool InitialPolyline(System.Xml.XmlNode polylineXmlNode)
        {
            System.Xml.XmlNode childNode = null;
            for (int k = 0; k < polylineXmlNode.ChildNodes.Count; k++)
            {
                childNode = polylineXmlNode.ChildNodes[k];
                switch (childNode.Name)
                {
                    case "coordinates":
                        {
                            this.Coordinates = childNode.InnerText;
                            break;
                        }
                    default:
                        {
                            break;
                        }
                }
            }

return true;
        }

#endregion

#endregion
    }

8. KMLPolygon的实现

/// <summary>
    /// KMLPolygon
    /// </summary>
    public class KMLPolygon : IKMLPolygon, IKMLGeometry
    {
        #region IKMLPolygon 成员

#region 成员属性

/// <summary>
        /// 坐标信息-内轮廓
        /// </summary>
        public string Coordinates_InnerBoundary { set; get; }

/// <summary>
        /// 坐标信息-外轮廓
        /// </summary>
        public string Coordinates_OuterBoundary { set; get; }

#endregion

#region 成员方法

/// <summary>
        /// 初始化
        /// </summary>
        /// <param name="polygonXmlNode">polyLine节点</param>
        /// <returns>是否成功</returns>
        public bool InitialPolygon(System.Xml.XmlNode polygonXmlNode)
        {
            System.Xml.XmlNode childNode = null;
            for (int i = 0; i < polygonXmlNode.ChildNodes.Count; i++)
            {
                childNode = polygonXmlNode.ChildNodes[i];
                switch (childNode.Name)
                {
                    case "outerBoundaryIs":
                        {
                            this.Coordinates_OuterBoundary = GetCoordinates(childNode);
                            break;
                        }
                    case "innerBoundaryIs":
                        {
                            this.Coordinates_InnerBoundary = GetCoordinates(childNode);
                            break;
                        }
                    default:
                        {
                            break;
                        }
                }
            }

return true;
        }

#endregion

#endregion

#region 私有方法

/// <summary>
        /// 获得轮廓线坐标集
        /// </summary>
        /// <param name="boundaryNode">轮廓线节点</param>
        /// <returns>坐标集</returns>
        private string GetCoordinates(System.Xml.XmlNode boundaryNode)
        {
            System.Xml.XmlNode childNodeBoundary = null;
            System.Xml.XmlNode childNodeLinering = null;

for (int k = 0; k < boundaryNode.ChildNodes.Count; k++)
            {
                childNodeBoundary = boundaryNode.ChildNodes[k];
                if(childNodeBoundary.Name!="LinearRing") continue;
                for (int j = 0; j < childNodeBoundary.ChildNodes.Count; j++)
                {
                      childNodeLinering= childNodeBoundary.ChildNodes[j];
                      switch (childNodeLinering.Name)
                      {
                          case "coordinates":
                              {
                                  return childNodeLinering.InnerText;
                              }
                          default:
                              {
                                  break;
                              }
                      }
                }
            }

return string.Empty; ;
        }

#endregion
    }

9.KmlGeometryType枚举类型

/// <summary>
    /// KmlGeometry类型枚举
    /// </summary>
    public enum enumKmlGeometryType
    {
        /// <summary>
        /// 未知
        /// </summary>
        KMLNull=0,

/// <summary>
        /// 点
        /// </summary>
        KMLPoint=1,

/// <summary>
        /// 线
        /// </summary>
        KMLPolyline=2,

/// <summary>
        /// 面
        /// </summary>
        KMLPolygon=3
    }

10.KMLPlacemarker的实现

/// <summary>
    /// KMLPlacemarker
    /// </summary>
    public class KMLPlacemarker:IKMLPlacemarker
    {
        #region IKMLPlacemarker 成员

#region 成员属性

/// <summary>
        /// 名称
        /// </summary>
        public string Name { set; get; }

/// <summary>
        /// 描述信息

public string Description { set; get; }

/// <summary>
        /// 样式路径
        /// </summary>
        public string StyleURL { set; get; }

/// <summary>
        /// 图形类型
        /// </summary>
        public enumKmlGeometryType GeometryType { set; get; }

/// <summary>
        /// KMLGeometry
        /// </summary>
        public IKMLGeometry Geometry { set; get; }

#endregion

#region 成员方法

/// <summary>
        /// 初始化
        /// </summary>
        /// <param name="placemarkerNode">PlacemarkerNode</param>
        /// <returns>是否成功</returns>
        public bool Initial(System.Xml.XmlNode placemarkerNode)
        {
            if (placemarkerNode == null) return false;
            if (placemarkerNode.ChildNodes.Count < 1) return false;

System.Xml.XmlNode childNode = null;
            for (int i = 0; i < placemarkerNode.ChildNodes.Count; i++)
            {
                childNode = placemarkerNode.ChildNodes[i];
                switch (childNode.Name)
                {
                    case "name":
                        {
                            this.Name = childNode.InnerText;
                            break;
                        }
                    case "description":
                        {
                            this.Description = childNode.InnerText;
                            break;
                        }
                    case "styleUrl":
                        {
                            this.StyleURL = childNode.InnerText;
                            break;
                        }
                    case "Point":
                        {
                            this.GeometryType = enumKmlGeometryType.KMLPoint;
                            this.Geometry = new KMLPoint();
                            (this.Geometry as IKMLPoint).InitialPoint(childNode);
                            break;
                        }
                    case "LineString":
                        {
                            this.GeometryType = enumKmlGeometryType.KMLPolyline;
                            this.Geometry = new KMLPolyline();
                            (this.Geometry as IKMLPolyline).InitialPolyline(childNode);
                            break;
                        }
                    case "Polygon":
                        {
                            this.GeometryType = enumKmlGeometryType.KMLPolygon;
                            this.Geometry = new KMLPolygon();
                            (this.Geometry as IKMLPolygon).InitialPolygon(childNode);
                            break;
                        }
                    default:
                        break;
                }
            }

return true;
        }

#endregion

#endregion
    }

11.1KML解析为KMLPlacemarker的方法:(后续会补充上,这只是一部分)

/// <summary>
        /// 转换KML为Shape文件
        /// </summary>
        /// <param name="kmlFilePath">kml文件路径</param>
        /// <param name="shapeDirectoryPath">shape文件夹路径</param>
        /// <returns></returns>
        public bool ConvertKMLToShape(string kmlFilePath, string shapeDirectoryPath)
        {
            // 判断
            if (string.IsNullOrEmpty(kmlFilePath)) return false;
            if (string.IsNullOrEmpty(shapeDirectoryPath)) return false;
            if (!System.IO.File.Exists(kmlFilePath)) return false;
            if (!System.IO.Directory.Exists(shapeDirectoryPath)) { System.IO.Directory.CreateDirectory(shapeDirectoryPath); };

string kmlFileName = System.IO.Path.GetFileNameWithoutExtension(kmlFilePath);
            System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
            xmlDocument.Load(kmlFilePath);

System.Xml.XmlNodeList placeMarkerNodeList = xmlDocument.GetElementsByTagName("Placemark");
            System.Xml.XmlNode placeMarkerNode = null;

IList<IKMLPlacemarker> kmlPlaceMarkers_Point = new List<IKMLPlacemarker>(); ;
            IList<IKMLPlacemarker> kmlPlaceMarkers_Polyline = new List<IKMLPlacemarker>(); ;
            IList<IKMLPlacemarker> kmlPlaceMarkers_Polygon = new List<IKMLPlacemarker>(); ;

IKMLPlacemarker kmlPlacemarker = null;
            string coordinates = string.Empty;
            int i = 0;
            for (i = 0; i < placeMarkerNodeList.Count; i++)
            {
                placeMarkerNode = placeMarkerNodeList.Item(i);
                kmlPlacemarker = new KMLPlacemarker();
                kmlPlacemarker.Initial(placeMarkerNode);
                switch (kmlPlacemarker.GeometryType)
                {
                    case enumKmlGeometryType.KMLPoint:
                        kmlPlaceMarkers_Point.Add(kmlPlacemarker);
                        break;
                    case enumKmlGeometryType.KMLPolyline:
                        kmlPlaceMarkers_Polyline.Add(kmlPlacemarker);
                        break;
                    case enumKmlGeometryType.KMLPolygon:
                        kmlPlaceMarkers_Polygon.Add(kmlPlacemarker);
                        break;
                    default:
                        break;
                }
            }

    ////////////////////////////////////////隐掉了部分生成Shape的代码/////////////////////////////////////////

return true;
        }

这时候就能把Kml文件解析为自己定义的KmlPlacemarker,它包含了Kml中Placemarker中的所有信息;

利用Ogr将Kml转为Shape【1】的更多相关文章

  1. python 利用 ogr 写入shp文件,数据格式

    python 利用 ogr 写入 shp 文件, 定义shp文件中的属性字段(field)的数据格式为: OFTInteger # 整型 OFTIntegerList # 整型list OFTReal ...

  2. .net 利用Emit将object转为DbParameter,DataTable转为List<>

    先放测试结果图,测试的方法是拷贝了老赵的一个简单的性能计数器:CodeTimer.发现速度还是比利用反射来获取快了2倍左右的,将object转为DbParameter的反射方法我没写.         ...

  3. ArcGIS中KML转为shp文件

    问题:如何将KML转为shp文件? 方法: 1.打开ArcMap -> ArcToolbox: 2.在ArcToolbox中选择“转换工具”-> “由KML转出” -> “KML转图 ...

  4. java利用反射将pojo转为json对象

    最近做以太坊钱包项目需要与前台进行json交互,写一个工具类,经普通javaBean转为json对象 package util; import java.lang.reflect.Field; imp ...

  5. 利用css将英文转为大写或小写

    项目需要在后台接收的字段值为小写,但在页面上显示大写英文,但操作页面之后,最终传给后台的依旧是小写,所以就需要使用css转化一下即可 <li>This.is.a.book,全部转为大写:& ...

  6. 利用PhotoShop将Font-Awesome转为图片格式

    介绍如何将Font-Awesome等字体图标转换为图片格式,使用PHOTPSHOP很简单. 网上找了很多,都比较麻烦.别问为什么要这么做,因为你还没遇到需要的时候. 下载Font-Awesome字体库 ...

  7. 利用itext将html转为pdf

    亲测代码没有问题,需要注意细节已经标注:需要jar包:iText-2.0.8.jar:core-renderer-R8.jar: core-renderer-R8.jar下载地址:http://cen ...

  8. json处理三部曲之第三曲:利用Gson处理json

    需要导入gson-xxx.jar包 <dependency> <groupId>com.google.code.gson</groupId> <artifac ...

  9. shp的基本操作

    本节将介绍如何利用python完成对shp的基本操作 1.读取shp四至 import shapefile sf = shapefile.Reader(r"E:\shp\1.shp" ...

随机推荐

  1. 【转载】MDX Step by Step 读书笔记(三) - Understanding Tuples (理解元组)

    1. 在 Analysis Service 分析服务中,Cube (多维数据集) 是以一个多维数据空间来呈现的.在Cube 中,每一个纬度的属性层次结构都形成了一个轴.沿着这个轴,在属性层次结构上的每 ...

  2. [Re:从零开始的分布式] 0.x——Reids实现分布式锁

    上节提到了,分布式锁通常应满足如下要求,互斥性.高可用.高效率.可重入.锁失效这五个基本原则.由于Redis自身“快”的特点,所以高效率可以看作满足. 下文在单机情况下与多机情况下,对利用Redis实 ...

  3. Windows开发经验 - Visual Studio 2017

    1. 调试子进程 Visual Studio 2017及更早的版本原生不支持调试子进程,不确定未来是否会支持.可以通过官方插件让Visual Studio能够调试子进程. https://market ...

  4. 认识python正则模块re

    python正则模块re python中re中内置匹配.搜索.替换方法见博客---python附录-re.py模块源码(含re官方文档链接) 正则的应用是处理一些字符串,phthon的博文python ...

  5. Service层异常处理

    1.在service方法里面如果对异常进行了捕获的话,该事务是不会进行回滚的 * 默认spring事务只在发生未被捕获的 runtime excetpion()时才回滚. * * spring aop ...

  6. java翻译到mono C#实现系列(4) 利用CountDownTimer类实现倒计时功能 mono版

    群里的朋友问利用CountDownTimer类实现倒计时功能怎么实现,我就百度了,参考http://blog.csdn.net/qq344429461/article/details/7521361写 ...

  7. springboot项目:登录 登录aop拦截 使用Redis与cookie 进行设置获取清除操作

    登录.登出: 第一步:在pom文件中引入依赖 <dependency> <groupId>org.springframework.boot</groupId> &l ...

  8. 关于c#中”ref”和”out”关键字的一些理解

    一. 综述(本文内容大部分来自网络,经本人整理而成,仅供学习参考,不免理解错误,欢迎批评指正) 在c#中,方法的参数传递有四种类型: (1) 传值参数(by value) 传值参数无需额外的修饰符.传 ...

  9. 前后端完全分离开发模式Tomcat跨域问题处理

    公司新项目实现方案采用前后端完全分离架构,后端采用spring boot框架,前端纯HTML5开发部署会采用同一台服务器,但是在实现过程中分工开发出现ajax请求跨域问题故为解决开发问题发现如下解决方 ...

  10. AngularJs双向绑定详解

    双向绑定的三个重要方法: $scope.$apply() $scope.$digest() $scope.$watch() 一.$scope.$watch() 我理解的$watch就是将对某个数据的监 ...