private void menuItemExportTransformedSketch_Click(object sender, EventArgs e)
        {
            var dialog = new SaveFileDialog();

            dialog.Filter       = "Shp文件(*.shp)|*.shp";
            dialog.AddExtension = true;
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var xmlDialog = new OpenFileDialog();
                xmlDialog.Filter = "控制点坐标(*.xml)|*.xml";
                if (xmlDialog.ShowDialog() == DialogResult.OK)
                {
                    List <HorizontalCoordinate> sourceCoordinates, targetCoordinates;
                    KVS.Open(dialog.FileName, out targetCoordinates, out sourceCoordinates);
                    var param4 = LinearTransformation.GetTransformationParameter(sourceCoordinates, targetCoordinates);

                    var pathName = Path.GetDirectoryName(dialog.FileName);
                    var fileName = Path.GetFileNameWithoutExtension(dialog.FileName);

                    var      nVertices = m_mapDocument.GetSketchPointCount();
                    double[] adfX      = new double[1];
                    double[] adfY      = new double[1];
                    double[] adfZ      = new double[1];

                    var shpFileName = string.Format(@"{0}\{1}_point.shp", pathName, fileName);
                    var hSHP        = Shapelib.SHPCreate(shpFileName, Shapelib.ShapeType.Point);

                    for (int i = 0; i < nVertices; i++)
                    {
                        m_mapDocument.GetSketchPointInfo(i, ref adfX, ref adfY, ref adfZ, param4);
                        var psObject = Shapelib.SHPCreateSimpleObject(Shapelib.ShapeType.Point, nVertices, adfX, adfY, adfZ);
                        Shapelib.SHPWriteObject(hSHP, -1, psObject);
                    }
                    Shapelib.SHPClose(hSHP);
                    m_outputWindow.OutputText("点文件已存为:" + shpFileName);

                    nVertices   = m_mapDocument.GetSketchPolylineCount();
                    shpFileName = string.Format(@"{0}\{1}_polyline.shp", pathName, fileName);
                    hSHP        = Shapelib.SHPCreate(shpFileName, Shapelib.ShapeType.PolyLine);

                    for (int i = 0; i < nVertices; i++)
                    {
                        var count = m_mapDocument.GetSketchPolylinePointCount(i);
                        adfX = new double[count];
                        adfY = new double[count];
                        adfZ = new double[count];

                        m_mapDocument.GetSketchPolylineInfo(i, ref adfX, ref adfY, ref adfZ, param4);

                        var psObject = Shapelib.SHPCreateSimpleObject(Shapelib.ShapeType.PolyLine, count, adfX, adfY, adfZ);
                        var iLine    = Shapelib.SHPWriteObject(hSHP, -1, psObject);
                    }
                    Shapelib.SHPClose(hSHP);
                    m_outputWindow.OutputText("线文件已存为:" + shpFileName);

                    nVertices   = m_mapDocument.GetSketchPolygonCount();
                    shpFileName = string.Format(@"{0}\{1}_polygon.shp", pathName, fileName);
                    hSHP        = Shapelib.SHPCreate(shpFileName, Shapelib.ShapeType.Polygon);

                    for (int i = 0; i < nVertices; i++)
                    {
                        var count = m_mapDocument.GetSketchPolygonPointCount(i);
                        adfX = new double[count];
                        adfY = new double[count];
                        adfZ = new double[count];

                        m_mapDocument.GetSketchPolygonInfo(i, ref adfX, ref adfY, ref adfZ, param4);

                        var psObject = Shapelib.SHPCreateSimpleObject(Shapelib.ShapeType.Polygon, count, adfX, adfY, adfZ);
                        var iPolygon = Shapelib.SHPWriteObject(hSHP, -1, psObject);
                    }
                    Shapelib.SHPClose(hSHP);
                    m_outputWindow.OutputText("面文件已存为:" + shpFileName);
                }
            }
        }
        private void OpenLayer(string shpFileName, string xmlFileName = "")
        {
            var pathName = Path.GetDirectoryName(shpFileName);
            var fileName = Path.GetFileNameWithoutExtension(shpFileName);

            var shp  = string.Format(@"{0}\{1}.shp", pathName, fileName);
            var hSHP = Shapelib.SHPOpen(shp, "rb");
            var dbf  = string.Format(@"{0}\{1}.dbf", pathName, fileName);
            var hDBF = Shapelib.DBFOpen(dbf, "rb");

            // 实体数
            int pnEntities = 0;

            // 形状类型
            Shapelib.ShapeType pshpType = Shapelib.ShapeType.NullShape;
            // 界限坐标数组
            double[] adfMinBound = new double[4], adfMaxBound = new double[4];

            // 获取实体数、形状类型、界限坐标等信息
            Shapelib.SHPGetInfo(hSHP, ref pnEntities, ref pshpType, adfMinBound, adfMaxBound);

            var sourceCoordinates = new List <HorizontalCoordinate>();
            var targetCoordinates = new List <HorizontalCoordinate>();

            if (!string.IsNullOrEmpty(xmlFileName))
            {
                KVS.Open(xmlFileName, out sourceCoordinates, out targetCoordinates);
            }

            var param4 = string.IsNullOrEmpty(xmlFileName) ? null : LinearTransformation.GetTransformationParameter(sourceCoordinates, targetCoordinates);
            var rect   = string.IsNullOrEmpty(xmlFileName) ? GetShapeRect(adfMinBound, adfMaxBound) : GetShapeRect(adfMinBound, adfMaxBound, param4);

            var node = new TreeNode(shp);

            node.Tag     = rect;
            node.Checked = true;
            node.ExpandAll();

            GMapOverlay overlay = new GMapOverlay(shp);

            for (int iShape = 0; iShape < pnEntities; iShape++)
            {
                // SHPObject对象
                Shapelib.SHPObject shpObject = new Shapelib.SHPObject();
                // 读取SHPObject对象指针
                var shpObjectPtr = Shapelib.SHPReadObject(hSHP, iShape);
                // 忽略可能存在问题的实体
                if (shpObjectPtr == IntPtr.Zero)
                {
                    continue;
                }
                // 指针转换为SHPObject对象
                Marshal.PtrToStructure(shpObjectPtr, shpObject);

                // 顶点数
                int nVertices = shpObject.nVertices;

                // 顶点的X坐标数组
                var padfX = new double[nVertices];
                // 将顶点的X坐标数组指针转换为数组
                Marshal.Copy(shpObject.padfX, padfX, 0, nVertices);
                // 顶点的Y坐标数组
                var padfY = new double[nVertices];
                // 将顶点的Y坐标数组指针转换为数组
                Marshal.Copy(shpObject.padfY, padfY, 0, nVertices);

                int    iField     = Shapelib.DBFGetFieldIndex(hDBF, "名称");
                string entityName = Shapelib.DBFReadStringAttribute(hDBF, iShape, iField);
                // var entityName = Enum.GetName(pshpType.GetType(), pshpType) + iShape;
                var points     = new List <PointLatLng>();
                var entityNode = new TreeNode();
                entityNode.Text = entityName;
                switch (pshpType)
                {
                case Shapelib.ShapeType.Point:
                    var pointMarker = string.IsNullOrEmpty(xmlFileName) ? GetPoint(padfX[0], padfY[0]) : GetTransformedPoint(padfX[0], padfY[0], param4);
                    points.Add(pointMarker);
                    UpdateOverlay(ref overlay, pshpType, points, entityName);
                    entityNode.Tag = overlay.Id;
                    break;

                default:
                    var minPoint = new PointLatLng();
                    var maxPoint = new PointLatLng();
                    for (int i = 0; i < nVertices; i++)
                    {
                        var point = string.IsNullOrEmpty(xmlFileName) ? GetPoint(padfX[i], padfY[i]) : GetTransformedPoint(padfX[i], padfY[i], param4);
                        points.Add(point);

                        if (i == 0)
                        {
                            minPoint.Lat = maxPoint.Lat = point.Lat;
                            minPoint.Lng = maxPoint.Lng = point.Lng;
                        }
                        else
                        {
                            if (point.Lng > maxPoint.Lng)
                            {
                                maxPoint.Lng = point.Lng;
                            }
                            if (point.Lat > maxPoint.Lat)
                            {
                                maxPoint.Lat = point.Lat;
                            }
                            if (point.Lng < minPoint.Lng)
                            {
                                minPoint.Lng = point.Lng;
                            }
                            if (point.Lat < minPoint.Lat)
                            {
                                minPoint.Lat = point.Lat;
                            }
                        }
                    }

                    UpdateOverlay(ref overlay, pshpType, points, entityName);
                    var entityRect = new RectLatLng(maxPoint.Lat, minPoint.Lng, maxPoint.Lng - minPoint.Lng, maxPoint.Lat - minPoint.Lat);
                    entityNode.Tag = entityRect;
                    break;
                }
                node.Nodes.Add(entityNode);
            }
            Shapelib.DBFClose(hDBF);
            Shapelib.SHPClose(hSHP);

            m_layerWindow.AddNode(node);

            m_mapDocument.AddOverlayer(overlay);
            if (pshpType == Shapelib.ShapeType.Point)
            {
                m_mapDocument.Zoom(overlay.Id);
            }
            else
            {
                m_mapDocument.Zoom(rect);
            }
        }