[Shapefile C Library]读写shp图形(C++&.net Wapper)
ShapeLib的.net Wapper版可以在官网下载到,在WorldWind中也有使用。ORG据说也是使用的ShapeLib实现的shp文件的读写。
官网:http://shapelib.maptools.org/
1. C++读取shpfile文件代码
int main() { //读取shp const char * pszShapeFile = "data\\LineSegments2.shp"; SHPHandle hShp= SHPOpen(pszShapeFile, "r"); int nShapeType, nVertices; int nEntities = 0; double* minB = new double[4]; double* maxB = new double[4]; SHPGetInfo(hShp, &nEntities, &nShapeType, minB, maxB); printf("ShapeType:%d\n", nShapeType); printf("Entities:%d\n", nEntities); for (int i = 0; i < nEntities;i++) { int iShape = i; SHPObject *obj = SHPReadObject(hShp, iShape); printf("--------------Feature:%d------------\n",iShape); int parts = obj->nParts; int verts=obj->nVertices; printf("nParts:%d\n", parts); printf("nVertices:%d\n", verts); for (size_t i = 0; i < verts; i++) { double x=obj->padfX[i]; double y = obj->padfY[i]; printf("%f,%f;", x,y); } printf("\n"); } SHPClose(hShp); system("pause"); }
输出结果:
2. 以下是.net读取Shp文件中图形的代码:
1 private void button1_Click(object sender, EventArgs e)
2 {
3 OpenFileDialog dlg = new OpenFileDialog();
4 dlg.Filter = "(*.shp)|*.shp";
5 if (dlg.ShowDialog() == DialogResult.OK)
6 {
7 string fileName = dlg.FileName;
8 txtFilePath.Text = fileName;
9 ReadSHP(fileName);
10 }
11 }
12
13 private void ReadSHP(string FILENAME)
14 {
15 IntPtr hShp;
16 hShp = ShapeLib.SHPOpen(FILENAME, "rb+");
17
18 // get shape info and verify shapes were created correctly
19 double[] minB = new double[4];
20 double[] maxB = new double[4];
21 int nEntities = 0;
22 ShapeLib.ShapeType shapeType = 0;
23 ShapeLib.SHPGetInfo(hShp, ref nEntities, ref shapeType, minB, maxB);
24 listBox1.Items.Add(string.Format("Number Entries: {0}", nEntities));
25 listBox1.Items.Add(string.Format("ShapeType: {0}", shapeType));
26 listBox1.Items.Add(string.Format("Min XY: {0}, {1}", minB[0], minB[1]));
27 listBox1.Items.Add(string.Format("Max XY: {0}, {1}", maxB[0], maxB[1]));
28
29 // test SHPReadObject on the first shape
30 for (int i = 0; i < nEntities; i++)
31 {
32 int iShape = i;
33 listBox1.Items.Add(string.Format("Shape({0}): ", iShape));
34 IntPtr pshpObj = ShapeLib.SHPReadObject(hShp, iShape);
35
36 // Get the SHPObject associated with our IntPtr pshpObj
37 // We create a new SHPObject in managed code, then use Marshal.PtrToStructure
38 // to copy the unmanaged memory pointed to by pshpObj into our managed copy.
39 ShapeLib.SHPObject shpObj = new ShapeLib.SHPObject();
40 Marshal.PtrToStructure(pshpObj, shpObj);
41
42 listBox1.Items.Add(string.Format("Min XY of shape({0}): ({1}, {2})", iShape, shpObj.dfXMin, shpObj.dfYMin));
43 listBox1.Items.Add(string.Format("Max XY of shape({0}): ({1}, {2})", iShape, shpObj.dfXMax, shpObj.dfYMax));
44 listBox1.Items.Add(string.Format("Points of shape({0}): ({1})", iShape, shpObj.nVertices));
45 int parts = shpObj.nParts;
46 listBox1.Items.Add(string.Format("Parts of shape({0}): ({1})", iShape, parts));
47 if (parts>0)
48 {
49 int[] partStart = new int[parts];
50 Marshal.Copy(shpObj.paPartStart, partStart, 0, parts);
51 for (int j = 0; j < partStart.Length; j++)
52 {
53 listBox1.Items.Add(string.Format("FirstPart of shape({0}): ({1})", iShape, partStart[j]));
54 }
55 int[] partType = new int[parts];
56 Marshal.Copy(shpObj.paPartType, partType, 0, parts);
57 for (int j = 0; j < partType.Length; j++)
58 {
59 listBox1.Items.Add(string.Format("FirstPartType of shape({0}): ({1})", iShape, (MapTools.ShapeLib.PartType)partType[j]));
60 }
61 }
62
63 ShapeLib.SHPDestroyObject(pshpObj);
64 }
65 ShapeLib.SHPClose(hShp);
66 Console.WriteLine("\nPress any key to continue...");
67 Console.ReadLine();
68 }
3.新建shp并保存属性
//简化后保存 const char* saveFileName = "data\\simplyRoom.shp"; int nShpTpyeSave = SHPT_POLYGON; SHPHandle outShp = SHPCreate(saveFileName, nShpTpyeSave); DBFHandle dbf_h = DBFCreate(saveFileName); int fieldIdx=DBFAddField(dbf_h, "Shape", FTInteger, 2, 0); SHPObject *psShape; for (int ir=0;ir<rooms_.size();ir++) { printf("--------------Room:%d------------\n",ir); std::vector<Coordinate> coords=rooms_[ir].simplyCoords_; double *xCoords = new double[coords.size()]; double *yCoords = new double[coords.size()]; for (int ip=0;ip<coords.size();ip++) { double x=coords[ip].x; double y=coords[ip].y; xCoords[ip] = x; yCoords[ip] = y; printf("%f,%f;\n", x,y); } printf("\n"); psShape = SHPCreateObject(nShpTpyeSave, -1, 0, NULL, NULL, coords.size(), xCoords, yCoords, NULL, NULL); std::cout << std::endl; int ishape=SHPWriteObject(outShp, -1, psShape); SHPDestroyObject(psShape); DBFWriteIntegerAttribute(dbf_h, ishape, 0, ishape); } SHPClose(outShp); DBFClose(dbf_h);
作者:太一吾鱼水
文章未经说明均属原创,学习笔记可能有大段的引用,一般会注明参考文献。
欢迎大家留言交流,转载请注明出处。