⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cs

📁 包含详细例子的c#创建shape文件的开源码
💻 CS
字号:
using System;
using System.Runtime.InteropServices;
using System.Text;
using MapTools;

namespace NetTest
{
	/// <summary>
	/// A demonstration and test program for the use of
	/// ShapeLib, a .NET wrapper class for the Shapefile C Library V1.2.10
	/// </summary>
	class Class1
	{
		const string FILENAME = "test";
		const int NVERTICES = 11;
		const int NFIELDS = 5;
		const int NSHAPES = 3;

		[STAThread]
		static void Main(string[] args)
		{
			CreateSHP();
			CreateDBF();
			Console.WriteLine("\nPress any key to exit...");
			Console.ReadLine();
		}

		private static void CreateSHP()
		{

			ShapeLib.ShapeType shpType = ShapeLib.ShapeType.Polygon;
			Console.WriteLine("*****Creating {0}*****\n", ShapeLib.SHPTypeName(shpType));
			IntPtr hShp;
			double[] xCoord = new double[NVERTICES];
			double[] yCoord = new double[NVERTICES];
			
			// create an arbitrary geometric figure
			// note that our boundary is defined clockwise, according
			// to the ESRI shapefile rule that the neighborhood to the right 
			// of an observer walking along the ring in vertex order is
			// the neighborhood inside the polygon.  In contrast, holes are 
			// defined in counterclockwise order.
			for (int i=0;i<NVERTICES;i++)
			{
				xCoord[i] = Math.Cos(Math.PI/5 * (double)i);
				yCoord[i] = -Math.Sin(Math.PI/5 * (double)i);
			}

			// ensure start and end point are equal (some roundoff err occurs in Sin(2PI))
			xCoord[NVERTICES-1]=xCoord[0];
			yCoord[NVERTICES-1]=yCoord[0];

			// create a new shapefile
			hShp = ShapeLib.SHPCreate(FILENAME, shpType);
			if (hShp.Equals(IntPtr.Zero))
				return;

			// add three shapes
			IntPtr pshpObj = ShapeLib.SHPCreateSimpleObject(shpType, NVERTICES, 
				xCoord, yCoord, new double[NVERTICES]);

			int iRet = ShapeLib.SHPWriteObject(hShp, -1, pshpObj);
			ShapeLib.SHPDestroyObject(pshpObj);

			// next shape will be 2 units to the right
			for (int i=0;i<NVERTICES;i++)
				xCoord[i] += 2;

			pshpObj = ShapeLib.SHPCreateSimpleObject(shpType, NVERTICES, 
				xCoord, yCoord, new double[NVERTICES]);
			iRet = ShapeLib.SHPWriteObject(hShp, -1, pshpObj);
			ShapeLib.SHPDestroyObject(pshpObj);

			// next will be 2 units up
			for (int i=0;i<NVERTICES;i++)
				yCoord[i] += 2;

			// this polygon will have a triangular hole in its center,
			// for the purpose of testing SHPCreateObject
			double[] aX = new double[NVERTICES+4];
			double[] aY = new double[NVERTICES+4];
			double[] aZ = new double[NVERTICES+4];
			double[] aM = new double[NVERTICES+4];

			Array.Copy(xCoord, 0, aX, 0, NVERTICES);
			Array.Copy(yCoord, 0, aY, 0, NVERTICES);
			// center of polygon is at (2,2) - center our triangular hole there.
			// Outer ring is defined clockwise; inner ring (hole) is defined ccwise
			aX[NVERTICES] = 2.5;
			aY[NVERTICES] = 2;
			aX[NVERTICES+1] = 2;
			aY[NVERTICES+1] = 2.5;
			aX[NVERTICES+2] = 1.5;
			aY[NVERTICES+2] = 1.5;
			aX[NVERTICES+3] = aX[NVERTICES];
			aY[NVERTICES+3] = aY[NVERTICES];
			int[] apartStart = new int[2] {0, NVERTICES};
			ShapeLib.PartType[] apartType = 
				new ShapeLib.PartType[2] {ShapeLib.PartType.Ring,ShapeLib.PartType.Ring};

			pshpObj = ShapeLib.SHPCreateObject(shpType, -1, 2, apartStart, apartType, NVERTICES+4, aX, aY, aZ, aM);
			
			iRet = ShapeLib.SHPWriteObject(hShp, -1, pshpObj);
			ShapeLib.SHPDestroyObject(pshpObj);

			// we want to test SHPOpen, so we will close hShp then reopen it
			ShapeLib.SHPClose(hShp);

			hShp = ShapeLib.SHPOpen(FILENAME, "rb+");

			// get shape info and verify shapes were created correctly
			double[] minB = new double[4];
			double[] maxB = new double[4];
			int nEntities=0;
			ShapeLib.ShapeType shapeType = 0;
			ShapeLib.SHPGetInfo(hShp, ref nEntities, ref shapeType, minB, maxB);
			Console.WriteLine("Number Entries: {0}", nEntities);
			Console.WriteLine("ShapeType: {0}", shapeType);
			Console.WriteLine("Min XY: {0}, {1}", minB[0], minB[1]);
			Console.WriteLine("Max XY: {0}, {1}", maxB[0], maxB[1]);

			// test SHPReadObject on the first shape
			int iShape = 0;
			pshpObj = ShapeLib.SHPReadObject(hShp, iShape);

			// Get the SHPObject associated with our IntPtr pshpObj
			// We create a new SHPObject in managed code, then use Marshal.PtrToStructure
			// to copy the unmanaged memory pointed to by pshpObj into our managed copy.
			ShapeLib.SHPObject shpObj = new ShapeLib.SHPObject();
			Marshal.PtrToStructure(pshpObj, shpObj);

			Console.WriteLine("Min XY of shape({0}): ({1}, {2})", iShape, shpObj.dfXMin, shpObj.dfYMin);
			Console.WriteLine("Max XY of shape({0}): ({1}, {2})", iShape, shpObj.dfXMax, shpObj.dfYMax);

            // Recover the vertices for this shape. Use Marshal.Copy to copy the memory pointed 
			// to by shpObj.padfX and shpObj.padfX (each an IntPtr) to a actual array.
			int iVertex = 2;
			Marshal.Copy(shpObj.padfX, xCoord, 0, NVERTICES);
			Marshal.Copy(shpObj.padfY, yCoord,  0, NVERTICES);
			Console.WriteLine("Vertex XY: ({0}, {1})", xCoord[iVertex], yCoord[iVertex]);

			// move some vertices
			for (int i=1;i<NVERTICES;i+=2)
			{
				xCoord[i] = 0.4*Math.Cos(Math.PI/5 * (double)i);
				yCoord[i] = -0.4*Math.Sin(Math.PI/5 * (double)i);
			}

			// scale the figure
			for (int i=0;i<NVERTICES;i++)
			{
				xCoord[i] *= 2;
				yCoord[i] *= 2;
			}

			// Set padfX and padfY to point to our updated array
			Marshal.Copy(xCoord, 0, shpObj.padfX, NVERTICES);
			Marshal.Copy(yCoord, 0, shpObj.padfY, NVERTICES);
			// Copy shpObj to unmanaged memory pointed to by pshpObj 
			// (shpObj is only a COPY at this point.  Use StructureToPtr to 
			// copy it back for use by shapelib.dll)
			Marshal.StructureToPtr(shpObj, pshpObj, true);
			
			// The .NET GC should clean up shpObj, but we'll force the cleanup anyway...
			shpObj = null;

			// recalculate extents
			ShapeLib.SHPComputeExtents(pshpObj);

			// write this updated shape to the shapefile, then destroy the SHPObject
			iRet = ShapeLib.SHPWriteObject(hShp, iShape, pshpObj);
			ShapeLib.SHPDestroyObject(pshpObj);

			// verify change was successful
			ShapeLib.SHPGetInfo(hShp, ref nEntities, ref shapeType, minB, maxB);
			Console.WriteLine("New Min XY: {0}, {1}", minB[0], minB[1]);
			Console.WriteLine("New Max XY: {0}, {1}", maxB[0], maxB[1]);
			
			// free resources
			ShapeLib.SHPClose(hShp);
			Console.WriteLine("\nPress any key to continue...");
			Console.ReadLine();
		}

		private static void CreateDBF()
		{
			Console.WriteLine("\n*****Creating dbf*****\n");
			// create dbase file
			IntPtr hDbf = ShapeLib.DBFCreate(FILENAME);
			if (hDbf.Equals(IntPtr.Zero))
			{
				Console.WriteLine("Error:  Unable to create {0}.dbf!", FILENAME);
				return;
			}
    
			// add some fields 
			int iRet = ShapeLib.DBFAddField(hDbf, "recID", ShapeLib.DBFFieldType.FTInteger, 2, 0);
			iRet = ShapeLib.DBFAddField(hDbf, "textField", ShapeLib.DBFFieldType.FTString, 25, 0);
			iRet = ShapeLib.DBFAddField(hDbf, "dblField", ShapeLib.DBFFieldType.FTDouble, 8, 4);
			iRet = ShapeLib.DBFAddField(hDbf, "boolField", ShapeLib.DBFFieldType.FTLogical, 1,0);
			iRet = ShapeLib.DBFAddField(hDbf, "dateField", ShapeLib.DBFFieldType.FTDate, 8,0);

			// populate
			Random r = new Random();
			for (int iShape=0;iShape<NSHAPES;iShape++)
			{
				int iField = 0;
				iRet = (ShapeLib.DBFWriteIntegerAttribute(hDbf, iShape, iField++, iShape * 10));
				iRet = (ShapeLib.DBFWriteStringAttribute(hDbf, iShape, iField++, "Hello World"));
				iRet = (ShapeLib.DBFWriteDoubleAttribute(hDbf, iShape, iField++, (100 * r.NextDouble())));
				iRet = (ShapeLib.DBFWriteLogicalAttribute(hDbf, iShape, iField++, iShape%2==0));
				iRet = (ShapeLib.DBFWriteDateAttribute(hDbf, iShape, iField++, DateTime.Now));
			}
    
			// set a few null values
			iRet = ShapeLib.DBFWriteNULLAttribute(hDbf, 0, 0);
			iRet =ShapeLib.DBFWriteNULLAttribute(hDbf, 1, 1);
			iRet =ShapeLib.DBFWriteNULLAttribute(hDbf, 2, 2);
			iRet =ShapeLib.DBFWriteNULLAttribute(hDbf, 1, 3);
			iRet =ShapeLib.DBFWriteNULLAttribute(hDbf, 0, 4);

			// modify a value
			iRet = (ShapeLib.DBFWriteStringAttribute(hDbf, 2, 1, "Greetings, Earthlings"));

			// close the file handle then reopen (only so we can test DBFOpen)
			ShapeLib.DBFClose(hDbf);
			hDbf = ShapeLib.DBFOpen(FILENAME, "rb+");

			// verify the table structure
			int recCount =ShapeLib.DBFGetRecordCount(hDbf);
			int fieldCount =ShapeLib.DBFGetFieldCount(hDbf);
			Console.WriteLine("Record Count: {0}", recCount);
			Console.WriteLine("Field Count: {0}\n", fieldCount);

			ShapeLib.DBFFieldType[] fieldTypes = new ShapeLib.DBFFieldType[NFIELDS];
			string[] fieldNames = new string[NFIELDS];
			int fieldWidth=0;
			int numDecimals=0;
			for (int iField=0;iField<fieldCount;iField++)
			{
				StringBuilder sb = new StringBuilder(12);
				fieldTypes[iField] = ShapeLib.DBFGetFieldInfo(hDbf, iField, sb, ref fieldWidth, ref numDecimals);
				fieldNames[iField] = sb.ToString();

				Console.WriteLine("-----Field {0}-----", iField+1);
				Console.WriteLine("Field Name: {0}", fieldNames[iField]);
				Console.WriteLine("Field Type: {0}", fieldTypes[iField]);
				Console.WriteLine("Field Width: {0}", fieldWidth);
				Console.WriteLine("Num Decimals: {0}", numDecimals);
				char c = (char)ShapeLib.DBFGetNativeFieldType(hDbf, iField);
				Console.WriteLine("Native Type: {0}", c);
				Console.WriteLine("\nPress any key to continue...");
				Console.ReadLine();
			}

			// verify records were written correctly
			Console.WriteLine("\n-----Data Values-----");
			for (int iShape=0;iShape<recCount;iShape++)
			{
				for (int iField=0;iField<fieldCount;iField++)
				{
					switch ((ShapeLib.DBFFieldType)fieldTypes[iField])
					{
						case (ShapeLib.DBFFieldType.FTDouble):
							if (ShapeLib.DBFIsAttributeNULL(hDbf, iShape, iField) == 0)
							{
								double val = ShapeLib.DBFReadDoubleAttribute(hDbf, iShape, iField);
								Console.WriteLine("{0}({1}): {2}", fieldNames[iField], iShape, val);
							}
							else
								Console.WriteLine("{0}({1}) Is Null", fieldNames[iField], iShape);
							break;

						case (ShapeLib.DBFFieldType.FTLogical):
							if (ShapeLib.DBFIsAttributeNULL(hDbf, iShape, iField) == 0)
							{
								bool val = ShapeLib.DBFReadLogicalAttribute(hDbf, iShape, iField);
								Console.WriteLine("{0}({1}): {2}", fieldNames[iField], iShape, val.ToString());
							}
							else
								Console.WriteLine("{0}({1}) Is Null", fieldNames[iField], iShape);
							break;

						case (ShapeLib.DBFFieldType.FTInteger):
							if (ShapeLib.DBFIsAttributeNULL(hDbf, iShape, iField) == 0)
							{
								int val = ShapeLib.DBFReadIntegerAttribute(hDbf, iShape, iField);
								Console.WriteLine("{0}({1}): {2}", fieldNames[iField], iShape, val);
							}
							else
								Console.WriteLine("{0}({1}) Is Null", fieldNames[iField], iShape);
							break;

						case (ShapeLib.DBFFieldType.FTDate):
							if (ShapeLib.DBFIsAttributeNULL(hDbf, iShape, iField) == 0)
							{
								DateTime val = ShapeLib.DBFReadDateAttribute(hDbf, iShape, iField);
								Console.WriteLine("{0}({1}): {2}", fieldNames[iField], iShape, val.ToLongDateString());
							}
							else
								Console.WriteLine("{0}({1}) Is Null", fieldNames[iField], iShape);
							break;

						case (ShapeLib.DBFFieldType.FTInvalid):
							Console.WriteLine("Field type is invalid");
							break;

						default:
							if (ShapeLib.DBFIsAttributeNULL(hDbf, iShape, iField) == 0)
							{
								string val = ShapeLib.DBFReadStringAttribute(hDbf, iShape, iField);
								Console.WriteLine("{0}({1}): {2}", fieldNames[iField], iShape, val);
							}
							else
								Console.WriteLine("{0}({1}) Is Null", fieldNames[iField], iShape);
							break;
					}
				}
			}
   
			// check DBFGetFieldIndex function
			iRet =ShapeLib.DBFGetFieldIndex(hDbf, "nonexistant");
			Console.WriteLine("nonexistant is field #{0}", iRet);
			iRet =ShapeLib.DBFGetFieldIndex(hDbf, "dblField");
			Console.WriteLine("dblField is field #{0}", iRet);

			// check DBFCloneEmpty function
			string newFile = FILENAME+"_clone";
			IntPtr hDbfClone = ShapeLib.DBFCloneEmpty(hDbf, newFile);
			if (hDbfClone.Equals(IntPtr.Zero))
				Console.WriteLine("Error:  Unable to create {0}.dbf!",newFile);
			else
			{
				// test Tuple Read/Write 
				int iShape = NSHAPES;
				for (int iDest = 0; iDest<NSHAPES; iDest++)
				{
					IntPtr pTuple = ShapeLib.DBFReadTuple(hDbf, --iShape);
					// write to clone in reverse order
					// note that iDest must increase monotonically from zero
					ShapeLib.DBFWriteTuple(hDbfClone, iDest, pTuple);
					Console.WriteLine("Tuple [{0}]->[{1}] = \"{2}\"", 
						iShape.ToString(), 
						iDest.ToString(), 
						Marshal.PtrToStringAnsi(pTuple));
				}
				// release resources
				ShapeLib.DBFClose(hDbfClone);
			}

			// release resources
			ShapeLib.DBFClose(hDbf);
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -