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);