/// <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(); } } }
/// <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 = "完成."; }
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 ); }
/************************************************************************/ /* 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 ); } } }
/// <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; }