• 利用Ogr将Kml转为Shape【1】


    最近在研究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中的所有信息;

  • 相关阅读:
    Huffman树与编码
    Python引用复制,参数传递,弱引用与垃圾回收
    Git使用说明
    numpy使用指南
    Python Socket
    温故知新之 数据库的事务、隔离级别、锁
    Oracle数据库的语句级读一致性
    VirtualBox NAT方式与主机互相通信
    Linux的定时任务
    Redis学习
  • 原文地址:https://www.cnblogs.com/LiangXiaoBa/p/3346981.html
Copyright © 2020-2023  润新知