Пример #1
0
        /// <summary>
        /// 生产SHP
        /// </summary>
        /// <param name="matrix"></param>
        /// <param name="fullname"></param>
        private void ToSHP(ByteMatrix matrix, string fullname)
        {
            double    size = 6;
            SHPHandle hSHP = null;
            DBFHandle hDBF = null;

            try {
                SHPT shptype = SHPT.POLYGON;
                // 创建SHP文件
                hSHP = SHPHandle.Create(fullname, shptype);
                if (hSHP == null)
                {
                    throw new Exception("Unable to create SHP:" + fullname);
                }
                // 创建DBF文件
                hDBF = DBFHandle.Create(fullname);
                if (hDBF == null)
                {
                    throw new Exception("Unable to create DBF:" + fullname);
                }
                if (hDBF.AddField("_row", FT.Integer, 10, 0) < 0)
                {
                    throw new Exception("DBFHandle.AddField(_row,Integer,10,0) failed.");
                }
                if (hDBF.AddField("_col", FT.Integer, 10, 0) < 0)
                {
                    throw new Exception("DBFHandle.AddField(_col,Integer,10,0) failed.");
                }

                // 绘制二维码
                int record_index = 0;
                for (int row = 0; row < matrix.Width; row++)
                {
                    for (int col = 0; col < matrix.Height; col++)
                    {
                        if (matrix[row, col] == 0)
                        {
                            continue;
                        }

                        // 构造SHPRecord
                        SHPRecord record = new SHPRecord()
                        {
                            ShapeType = shptype
                        };
                        // 分段开始
                        record.Parts.Add(record.Points.Count);
                        // 添加4个角点
                        double ox = row * size + 300;
                        double oy = matrix.Height * size - col * size;
                        record.Points.Add(new double[] { ox, oy, 0, 0 });
                        record.Points.Add(new double[] { ox + size, oy, 0, 0 });
                        record.Points.Add(new double[] { ox + size, oy + size, 0, 0 });
                        record.Points.Add(new double[] { ox, oy + size, 0, 0 });
                        // 写图形
                        int      num_parts  = record.NumberOfParts;   // 总共分为几段
                        int[]    parts      = record.Parts.ToArray(); // 每一个分段的起始节点索引
                        int      num_points = record.NumberOfPoints;  // 所有节点总数
                        double[] xs         = new double[num_points]; // 所有节点X坐标
                        double[] ys         = new double[num_points]; // 所有节点Y坐标
                        double[] zs         = new double[num_points]; // 所有节点Z坐标
                        double[] ms         = new double[num_points]; // 所有节点M坐标
                        for (int n = 0; n < num_points; n++)
                        {
                            xs[n] = record.Points[n][0];            // X坐标
                            ys[n] = record.Points[n][1];            // Y坐标
                            zs[n] = record.Points[n][2];            // Z值
                            ms[n] = record.Points[n][3];            // M值
                        }
                        // PS: 节点 "逆时针"是加 "顺时针"是减
                        SHPObject shpobj = SHPObject.Create(shptype,    // 图形类别
                                                            -1,         // 图形ID -1表示新增
                                                            num_parts,  // 总共分为几段
                                                            parts,      // 每一个分段的起始节点索引
                                                            null,       // 每段的类别
                                                            num_points, // 所有节点总数
                                                            xs,         // 所有节点的X坐标
                                                            ys,         // 所有节点的Y坐标
                                                            zs,         // 所有节点的Z值
                                                            ms);        // 所有节点的M值
                        hSHP.WriteObject(-1, shpobj);
                        // 写属性
                        //hDBF.WriteNULLAttribute(record_index, 0);
                        hDBF.WriteDoubleAttribute(record_index, 0, row);
                        hDBF.WriteDoubleAttribute(record_index, 1, col);
                        record_index++;
                    }
                }
            }
            catch (Exception) {
                throw;
            }
            finally {
                if (hSHP != null)
                {
                    hSHP.Close();
                }
                if (hDBF != null)
                {
                    hDBF.Close();
                }
            }
        }
Пример #2
0
        /// <summary>
        /// 导入SHP文件
        /// </summary>
        /// <param name="sfile"></param>
        private void ImportSHP(string sfile)
        {
            int indexext = sfile.LastIndexOf(".shp", StringComparison.OrdinalIgnoreCase);

            if (indexext < 0)
            {
                return;
            }
            string    dfile = sfile.Substring(0, indexext) + ".dbf";
            SHPHandle hSHP  = SHPHandle.Open(sfile, "rb");
            DBFHandle hDBF  = DBFHandle.Open(dfile, "rb");

            // 读取DBF信息
            Dictionary <int, Dictionary <string, object> > fieldInfos = new Dictionary <int, Dictionary <string, object> >();
            int fieldCount = hDBF.GetFieldCount();      // 字段总数

            for (int i = 0; i < fieldCount; i++)
            {
                string szTitle;
                int    nWidth;
                int    nDecimals;
                FT     eType = hDBF.GetFieldInfo(i, out szTitle, out nWidth, out nDecimals);
                fieldInfos[i] = new Dictionary <string, object>()
                {
                    { "name", szTitle },
                    { "width", nWidth },
                    { "decimals", nDecimals },
                    { "type", eType }
                };
            }

            // 读取SHP信息
            int  nEntities;
            SHPT nShapeType;

            double[] adfMinBound = new double[4];
            double[] adfMaxBound = new double[4];
            hSHP.GetInfo(out nEntities, out nShapeType, adfMinBound, adfMaxBound);

            Dictionary <string, object> featureCollection = new Dictionary <string, object>();
            List <object> features = new List <object>();

            featureCollection["type"]     = "FeatureCollection";
            featureCollection["features"] = features;

            StreamWriter writer = new StreamWriter("山体保护线.txt", false, Encoding.UTF8);

            writer.Write("{'type': 'FeatureCollection','features': [".Replace('\'', '"'));

            for (int irecord = 0; irecord < nEntities; irecord++)
            {
                Dictionary <string, object> feature    = new Dictionary <string, object>();
                Dictionary <string, object> properties = new Dictionary <string, object>();
                Dictionary <string, object> geometry   = new Dictionary <string, object>();
                feature["type"]       = "Feature";
                feature["id"]         = irecord;
                feature["properties"] = properties;     // 属性
                feature["geometry"]   = geometry;       // 图形
                features.Add(feature);                  // 添加到要素列表

                // 填写属性
                for (int ifield = 0; ifield < hDBF.GetFieldCount(); ifield++)
                {
                    FT eType = (FT)fieldInfos[ifield]["type"];
                    switch (eType)
                    {
                    case FT.String: {
                        string value = hDBF.ReadStringAttribute(irecord, ifield);
                        properties[fieldInfos[ifield]["name"].ToString()] = value.Trim();
                    }
                    break;

                    case FT.Integer: {
                        int value = hDBF.ReadIntegerAttribute(irecord, ifield);
                        properties[fieldInfos[ifield]["name"].ToString()] = value;
                    }
                    break;

                    case FT.Double: {
                        double value = hDBF.ReadDoubleAttribute(irecord, ifield);
                        properties[fieldInfos[ifield]["name"].ToString()] = value;
                    }
                    break;

                    case FT.Logical:
                    case FT.Invalid:
                        break;

                    default:
                        break;
                    }
                }

                // 填写图形
                List <object> coordinates = new List <object>();


                geometry["type"]        = "";           //
                geometry["coordinates"] = coordinates;  // 坐标集合

                SHPObject psShape = hSHP.ReadObject(irecord);
                //
                switch (psShape.nSHPType)
                {
                case SHPT.POINT:
                case SHPT.POINTZ:
                case SHPT.POINTM:
                    // 点数据
                    geometry["type"] = "Point";
                    break;

                case SHPT.ARC:
                case SHPT.ARCZ:
                case SHPT.ARCM:
                    // 线数据
                    geometry["type"] = "LineString";
                    break;

                case SHPT.POLYGON:
                case SHPT.POLYGONZ:
                case SHPT.POLYGONM:
                    // 面数据
                    geometry["type"] = "Polygon";
                    break;

                default:
                    MessageBox.Show("暂时无法处理多点/多线数据");
                    throw new Exception();
                }
                //
                if (psShape.nSHPType == SHPT.POINT ||
                    psShape.nSHPType == SHPT.POINTM ||
                    psShape.nSHPType == SHPT.POINTZ)
                {
                    geometry["coordinates"] = new double[] { psShape.padfX[0], psShape.padfY[0] };
                }
                else
                {
                    // 读取所有节点
                    for (int index = 0; index < psShape.panPartStart.Length; index++)
                    {
                        if (index < psShape.panPartStart.Length - 1)
                        {
                            // 普通的有开始有结束的
                            int start = psShape.panPartStart[index];
                            int end   = psShape.panPartStart[index + 1];

                            List <object> parts = new List <object>();    // 坐标段
                            coordinates.Add(parts);
                            for (int n = start; n < end; n++)
                            {
                                double x = Math.Round(psShape.padfX[n], 6);
                                double y = Math.Round(psShape.padfY[n], 6);
                                parts.Add(new List <object>()
                                {
                                    x, y
                                });
                            }
                        }
                        else
                        {
                            // 只有开始无结束的
                            int start = psShape.panPartStart[index];
                            int end   = psShape.nVertices;

                            List <object> parts = new List <object>();    // 坐标段
                            coordinates.Add(parts);
                            for (int n = start; n < end; n++)
                            {
                                double x = Math.Round(psShape.padfX[n], 6);
                                double y = Math.Round(psShape.padfY[n], 6);
                                parts.Add(new List <object>()
                                {
                                    x, y
                                });
                            }
                        }
                    }
                }

                //

                string feature_str = Json.JsonSerialize(feature);
                writer.Write(feature_str + ",");
            }
            writer.Write("]}");
            writer.Close();

            //string jsonstr = Json.JsonSerialize(featureCollection);
            //richTextBox.Text = jsonstr;

            richTextBox.Text = "完成.";
        }
Пример #3
0
        static double xshift = 0, yshift = 0; /* NO SHIFT */

        #endregion Fields

        #region Methods

        public static int Main( string[] args )
        {
            int     nCount_;
            SHPT    nShapeType_;
            /* -------------------------------------------------------------------- */
            /*      Check command line usage.                                       */
            /* -------------------------------------------------------------------- */
            if( args.Length < 1 ) error();
            c.strcpy(ref infile, args[0]);
            if (args.Length > 1) {
                c.strcpy(ref outfile,args[1]);
                if (strncasecmp2(outfile, "LIST",0) == 0) { ilist = true; }
                if (strncasecmp2(outfile, "ALL",0) == 0)  { iall  = true; }
            }
            if (ilist || iall || args.Length == 1 ) {
                setext(ref infile, "shp");
                c.printf("DESCRIBE: {0}\n",infile);
                c.strcpy(ref outfile,"");
            }
            /* -------------------------------------------------------------------- */
            /*      Look for other functions on the command line. (SELECT, UNIT)    */
            /* -------------------------------------------------------------------- */
            for (i = 2; i < args.Length; i++)
            {
                if ((strncasecmp2(args[i],  "SEL",3) == 0) ||
                    (strncasecmp2(args[i],  "UNSEL",5) == 0))
                {
                    if (strncasecmp2(args[i],  "UNSEL",5) == 0) iunselect=true;
                    i++;
                    if (i >= args.Length) error();
                    c.strcpy(ref selectitem,args[i]);
                    i++;
                    if (i >= args.Length) error();
                    selcount=0;
                    c.strcpy(ref temp,args[i]);
                    cpt=temp;
                    tj = c.atoi(cpt);
                    ti = 0;
                    int pos = 0;
                    while (tj>0) {
                        selectvalues[selcount] = tj;
                        while( cpt[pos] >= '0' && cpt[pos] <= '9')
                            pos++;
                        while( cpt[pos] > '\0' && (cpt[pos] < '0' || cpt[pos] > '9') )
                            pos++;
                        tj=c.atoi(cpt.Substring(pos));
                        selcount++;
                    }
                    iselect=true;
                }  /*** End SEL & UNSEL ***/
                else if ((strncasecmp2(args[i], "CLIP",4) == 0) ||
                        (strncasecmp2(args[i],  "ERASE",5) == 0))
                {
                    if (strncasecmp2(args[i],  "ERASE",5) == 0) ierase=true;
                    i++;
                    if (i >= args.Length) error();
                    c.strcpy(ref clipfile,args[i]);
                    c.sscanf(args[i],"{0:F}",ref cxmin);
                    i++;
                    if (i >= args.Length) error();
                    if (strncasecmp2(args[i],  "BOUND",5) == 0) {
                        setext(ref clipfile, "shp");
                        hSHP = SHPHandle.Open( clipfile, "rb" );
                        if( hSHP == null )
                        {
                            c.printf( "ERROR: Unable to open the clip shape file:{0}\n", clipfile );
                            c.exit( 1 );
                        }

                        hSHPappend.GetInfo( out nCount_, out nShapeType_,
                                    adfBoundsMin, adfBoundsMax );
                        cxmin = adfBoundsMin[0];
                        cymin = adfBoundsMin[1];
                        cxmax = adfBoundsMax[0];
                        cymax = adfBoundsMax[1];
                        c.printf("Theme Clip Boundary: ({0:F},{1:F}) - ({2:F},{3:F})\n",
                               cxmin, cymin, cxmax, cymax);
                        ibound=true;
                    } else {  /*** xmin,ymin,xmax,ymax ***/
                        c.sscanf(args[i],"{0:F}",ref cymin);
                        i++;
                        if (i >= args.Length) error();
                        c.sscanf(args[i],"{0:F}",ref cxmax);
                        i++;
                        if (i >= args.Length) error();
                        c.sscanf(args[i],"{0:F}",ref cymax);
                        c.printf("Clip Box: ({0:F},{1:F}) - ({2:F},{3:F})\n",cxmin, cymin, cxmax, cymax);
                    }
                    i++;
                    if (i >= args.Length) error();
                    if      (strncasecmp2(args[i], "CUT",3) == 0)    icut=true;
                    else if (strncasecmp2(args[i], "TOUCH",5) == 0)  itouch=true;
                    else if (strncasecmp2(args[i], "INSIDE",6) == 0) iinside=true;
                    else error();
                    iclip=true;
                } /*** End CLIP & ERASE ***/
                else if (strncasecmp2(args[i],  "FACTOR",0) == 0)
                {
                    i++;
                    if (i >= args.Length) error();
                    infactor=findunit(args[i]);
                    if (infactor == 0) error();
                    iunit=true;
                    i++;
                    if (i >= args.Length) error();
                    outfactor=findunit(args[i]);
                    if (outfactor == 0)
                    {
                        c.sscanf(args[i],"{0:F}",ref factor);
                        if (factor == 0) error();
                    }
                    if (factor == 0)
                    {
                        if (infactor ==0)
                        { c.puts("ERROR: Input unit must be defined before output unit"); c.exit(1); }
                        factor=infactor/outfactor;
                    }
                    c.printf("Output file coordinate values will be factored by {0:G}\n",factor);
                    ifactor=(factor != 1); /* True if a valid factor */
                } /*** End FACTOR ***/
                else if (strncasecmp2(args[i],"SHIFT",5) == 0)
                {
                    i++;
                    if (i >= args.Length) error();
                    c.sscanf(args[i],"{0:F}",ref xshift);
                    i++;
                    if (i >= args.Length) error();
                    c.sscanf(args[i],"{0:F}",ref yshift);
                    iunit=true;
                    c.printf("X Shift: {0:G}   Y Shift: {1:G}\n",xshift,yshift);
                } /*** End SHIFT ***/
                else {
                    c.printf("ERROR: Unknown function {0}\n",args[i]);  error();
                }
            }
            /* -------------------------------------------------------------------- */
            /*      If there is no data in this file let the user know.             */
            /* -------------------------------------------------------------------- */
            openfiles();  /* Open the infile and the outfile for shape and dbf. */
            if( hDBF.GetFieldCount() == 0 )
            {
                c.puts( "There are no fields in this table!" );
                c.exit( 1 );
            }
            /* -------------------------------------------------------------------- */
            /*      Print out the file bounds.                                      */
            /* -------------------------------------------------------------------- */
            iRecord = hDBF.GetRecordCount();
            hSHP.GetInfo( out nCount_, out nShapeType_, adfBoundsMin, adfBoundsMax );

            c.printf( "Input Bounds:  ({0:G},{1:G}) - ({2:G},{3:G})   Entities: {4}   DBF: {5}\n",
                    adfBoundsMin[0], adfBoundsMin[1],
                    adfBoundsMax[0], adfBoundsMax[1],
                    nEntities, iRecord );

            if (c.strcmp(outfile,"") == 0) /* Describe the shapefile; No other functions */
            {
                ti = hDBF.GetFieldCount();
                showitems();
                c.exit(0);
            }

            if (iclip) check_theme_bnd();

            jRecord = hDBFappend.GetRecordCount();
            hSHPappend.GetInfo( out nCount_, out nShapeType_, adfBoundsMin, adfBoundsMax );
            if (nEntitiesAppend == 0)
                c.puts("New Output File\n");
            else
                c.printf( "Append Bounds: ({0:G},{1:G})-({2:G},{3:G})   Entities: {4}  DBF: {5}\n",
                        adfBoundsMin[0], adfBoundsMin[1],
                        adfBoundsMax[0], adfBoundsMax[1],
                        nEntitiesAppend, jRecord );

            /* -------------------------------------------------------------------- */
            /*      Find matching fields in the append file or add new items.       */
            /* -------------------------------------------------------------------- */
            mergefields();
            /* -------------------------------------------------------------------- */
            /*      Find selection field if needed.                                 */
            /* -------------------------------------------------------------------- */
            if (iselect)    findselect();

            /* -------------------------------------------------------------------- */
            /*      Read all the records                                            */
            /* -------------------------------------------------------------------- */
            jRecord = hDBFappend.GetRecordCount();
            for( iRecord = 0; iRecord < nEntities; iRecord++)  /** DBFGetRecordCount(hDBF) **/
            {
                /* -------------------------------------------------------------------- */
                /*      SELECT for values if needed. (Can the record be skipped.)       */
                /* -------------------------------------------------------------------- */
                if (iselect)
                    if (selectrec() == 0) goto SKIP_RECORD;   /** SKIP RECORD **/

                /* -------------------------------------------------------------------- */
                /*      Read a Shape record                                             */
                /* -------------------------------------------------------------------- */
                psCShape = hSHP.ReadObject( iRecord );

                /* -------------------------------------------------------------------- */
                /*      Clip coordinates of shapes if needed.                           */
                /* -------------------------------------------------------------------- */
                if (iclip)
                    if (clip_boundary() == 0) goto SKIP_RECORD; /** SKIP RECORD **/

                /* -------------------------------------------------------------------- */
                /*      Read a DBF record and copy each field.                          */
                /* -------------------------------------------------------------------- */
                for( i = 0; i < hDBF.GetFieldCount(); i++ )
                {
                    /* -------------------------------------------------------------------- */
                    /*      Store the record according to the type and formatting           */
                    /*      information implicit in the DBF field description.              */
                    /* -------------------------------------------------------------------- */
                    if (pt[i] > -1)  /* if the current field exists in output file */
                    {
                        string sFieldName;
                        switch( hDBF.GetFieldInfo( i, out sFieldName, out iWidth, out iDecimals ) )
                        {
                        case FT.String:
                            hDBFappend.WriteStringAttribute(jRecord, pt[i],
                                                    (hDBF.ReadStringAttribute( iRecord, i )) );
                            break;

                        case FT.Integer:
                            hDBFappend.WriteIntegerAttribute(jRecord, pt[i],
                                                     (hDBF.ReadIntegerAttribute( iRecord, i )) );
                            break;

                        case FT.Double:
                            hDBFappend.WriteDoubleAttribute(jRecord, pt[i],
                                                    (hDBF.ReadDoubleAttribute( iRecord, i )) );
                            break;
                        }
                    }
                }
                jRecord++;
                /* -------------------------------------------------------------------- */
                /*      Change FACTOR and SHIFT coordinates of shapes if needed.        */
                /* -------------------------------------------------------------------- */
                if (iunit)
                {
                    for( j = 0; j < psCShape.nVertices; j++ )
                    {
                        psCShape.padfX[j] = psCShape.padfX[j] * factor + xshift;
                        psCShape.padfY[j] = psCShape.padfY[j] * factor + yshift;
                    }
                }

                /* -------------------------------------------------------------------- */
                /*      Write the Shape record after recomputing current extents.       */
                /* -------------------------------------------------------------------- */
                psCShape.ComputeExtents();
                hSHPappend.WriteObject( -1, psCShape );

              SKIP_RECORD:
                psCShape = null;
                j=0;
            }

            /* -------------------------------------------------------------------- */
            /*      Print out the # of Entities and the file bounds.                */
            /* -------------------------------------------------------------------- */
            jRecord = hDBFappend.GetRecordCount();
            hSHPappend.GetInfo( out nEntitiesAppend, out nShapeTypeAppend,
                        adfBoundsMin, adfBoundsMax );

            c.printf( "Output Bounds: ({0:G},{1:G}) - ({2:G},{3:G})   Entities: {4}  DBF: {5}\n\n",
                    adfBoundsMin[0], adfBoundsMin[1],
                    adfBoundsMax[0], adfBoundsMax[1],
                    nEntitiesAppend, jRecord );

            /* -------------------------------------------------------------------- */
            /*      Close the both shapefiles.                                      */
            /* -------------------------------------------------------------------- */
            hSHP.Close();
            hSHPappend.Close();
            hDBF.Close();
            hDBFappend.Close();
            if (nEntitiesAppend == 0) {
                c.puts("Remove the output files.");
                setext(ref outfile, "dbf");
                c.remove(outfile);
                setext(ref outfile, "shp");
                c.remove(outfile);
                setext(ref outfile, "shx");
                c.remove(outfile);
            }
            return( 0 );
        }
Пример #4
0
        /************************************************************************/
        /*                             openfiles()                              */
        /************************************************************************/
        static void openfiles()
        {
            /* -------------------------------------------------------------------- */
            /*      Open the DBF file.                                              */
            /* -------------------------------------------------------------------- */
            setext(ref infile, "dbf");
            hDBF = DBFHandle.Open( infile, "rb" );
            if( hDBF == null )
            {
                c.printf( "ERROR: Unable to open the input DBF:{0}\n", infile );
                c.exit( 1 );
            }
            /* -------------------------------------------------------------------- */
            /*      Open the append DBF file.                                       */
            /* -------------------------------------------------------------------- */
            if (c.strcmp(outfile,"") != 0) {
                setext(ref outfile, "dbf");
                hDBFappend = DBFHandle.Open( outfile, "rb+" );
                newdbf=false;
                if( hDBFappend == null )
                {
                    newdbf=true;
                    hDBFappend = DBFHandle.Create( outfile );
                    if( hDBFappend == null )
                    {
                        c.printf( "ERROR: Unable to open the append DBF:%s\n", outfile );
                        c.exit( 1 );
                    }
                }
            }
            /* -------------------------------------------------------------------- */
            /*      Open the passed shapefile.                                      */
            /* -------------------------------------------------------------------- */
            setext(ref infile, "shp");
            hSHP = SHPHandle.Open( infile, "rb" );

            if( hSHP == null )
            {
                c.printf( "ERROR: Unable to open the input shape file:{0}\n", infile );
                c.exit( 1 );
            }

            hSHP.GetInfo( out nEntities, out nShapeType, null, null );

            /* -------------------------------------------------------------------- */
            /*      Open the passed append shapefile.                               */
            /* -------------------------------------------------------------------- */
            if (c.strcmp(outfile,"") != 0) {
                setext(ref outfile, "shp");
                hSHPappend = SHPHandle.Open( outfile, "rb+" );

                if( hSHPappend == null )
                {
                    hSHPappend = SHPHandle.Create( outfile, nShapeType );
                    if( hSHPappend == null )
                    {
                        c.printf( "ERROR: Unable to open the append shape file:{0}\n",
                                outfile );
                        c.exit( 1 );
                    }
                }
                hSHPappend.GetInfo( out nEntitiesAppend, out nShapeTypeAppend,
                            null, null );

                if (nShapeType != nShapeTypeAppend)
                {
                    c.puts( "ERROR: Input and Append shape files are of different types.");
                    c.exit( 1 );
                }
            }
        }
Пример #5
0
        /// <summary>
        /// 导入SHP文件
        /// </summary>
        /// <param name="sfile"></param>
        private void ImportSHP(string sfile)
        {
            int indexext = sfile.LastIndexOf(".shp", StringComparison.OrdinalIgnoreCase);

            if (indexext < 0)
            {
                return;
            }
            string    dfile = sfile.Substring(0, indexext) + ".dbf";
            SHPHandle hSHP  = SHPHandle.Open(sfile, "rb");
            DBFHandle hDBF  = DBFHandle.Open(dfile, "rb");

            // 读取DBF信息
            Dictionary <int, Dictionary <string, object> > fieldInfos = new Dictionary <int, Dictionary <string, object> >();
            int fieldCount = hDBF.GetFieldCount();      // 字段总数

            for (int i = 0; i < fieldCount; i++)
            {
                string szTitle;
                int    nWidth;
                int    nDecimals;
                FT     eType = hDBF.GetFieldInfo(i, out szTitle, out nWidth, out nDecimals);
                fieldInfos[i] = new Dictionary <string, object>()
                {
                    { "name", szTitle },
                    { "width", nWidth },
                    { "decimals", nDecimals },
                    { "type", eType }
                };
            }

            // 读取SHP信息
            int  nEntities;
            SHPT nShapeType;

            double[] adfMinBound = new double[4];
            double[] adfMaxBound = new double[4];
            hSHP.GetInfo(out nEntities, out nShapeType, adfMinBound, adfMaxBound);

            Dictionary <string, object> featureCollection = new Dictionary <string, object>();
            List <object> features = new List <object>();

            featureCollection["type"]     = "FeatureCollection";
            featureCollection["features"] = features;


            for (int irecord = 0; irecord < nEntities; irecord++)
            {
                Dictionary <string, object> feature    = new Dictionary <string, object>();
                Dictionary <string, object> properties = new Dictionary <string, object>();
                Dictionary <string, object> geometry   = new Dictionary <string, object>();
                feature["type"]       = "Feature";
                feature["id"]         = irecord;
                feature["properties"] = properties;     // 属性
                feature["geometry"]   = geometry;       // 图形
                features.Add(feature);                  // 添加到要素列表

                // 填写属性
                for (int ifield = 0; ifield < hDBF.GetFieldCount(); ifield++)
                {
                    FT eType = (FT)fieldInfos[ifield]["type"];
                    switch (eType)
                    {
                    case FT.String: {
                        string value = hDBF.ReadStringAttribute(irecord, ifield);
                        properties[fieldInfos[ifield]["name"].ToString()] = value.Trim();
                    }
                    break;

                    case FT.Integer: {
                        int value = hDBF.ReadIntegerAttribute(irecord, ifield);
                        properties[fieldInfos[ifield]["name"].ToString()] = value;
                    }
                    break;

                    case FT.Double: {
                        double value = hDBF.ReadDoubleAttribute(irecord, ifield);
                        properties[fieldInfos[ifield]["name"].ToString()] = value;
                    }
                    break;

                    case FT.Logical:
                    case FT.Invalid:
                        break;

                    default:
                        break;
                    }
                }

                // 填写图形
                List <object> coordinates = new List <object>();
                geometry["type"]        = "Polygon";    // < 这里要修改
                geometry["coordinates"] = coordinates;  // 坐标集合

                SHPObject psShape = hSHP.ReadObject(irecord);

                // 读取所有节点
                for (int index = 0; index < psShape.panPartStart.Length; index++)
                {
                    if (index < psShape.panPartStart.Length - 1)
                    {
                        // 普通的有开始有结束的
                        int start = psShape.panPartStart[index];
                        int end   = psShape.panPartStart[index + 1];

                        List <object> parts = new List <object>();    // 坐标段
                        coordinates.Add(parts);
                        for (int n = start; n < end; n++)
                        {
                            double x = Math.Round(psShape.padfX[n], 6);
                            double y = Math.Round(psShape.padfY[n], 6);
                            parts.Add(new List <object>()
                            {
                                x, y
                            });
                        }
                    }
                    else
                    {
                        // 只有开始无结束的
                        int start = psShape.panPartStart[index];
                        int end   = psShape.nVertices;

                        List <object> parts = new List <object>();    // 坐标段
                        coordinates.Add(parts);
                        for (int n = start; n < end; n++)
                        {
                            double x = Math.Round(psShape.padfX[n], 6);
                            double y = Math.Round(psShape.padfY[n], 6);
                            parts.Add(new List <object>()
                            {
                                x, y
                            });
                        }
                    }
                }

                //
            }


            string jsonstr = Json.JsonSerialize(featureCollection);

            richTextBox.Text = jsonstr;
        }