</pre><pre name="code" class="csharp">在网上找的代码,经过自己的修改~为了避免自己忘记,在这里mark一下~
public void openshp()
{
string filename = null;
//Geomtry = new List<ESRI_POINT>();
OpenFileDialog openDialog = new OpenFileDialog();
openDialog.Filter = "shape files (*.shp)|*.shp|All files (*.*)|*.*";
openDialog.FilterIndex = 1;
openDialog.RestoreDirectory = true;
if (openDialog.ShowDialog() == DialogResult.OK)
filename = openDialog.FileName;
string pathnode = Path.GetDirectoryName(filename);
filename = Path.GetFileNameWithoutExtension(filename);
string shpfilepath = pathnode + "\\" + filename + ".shp";
string shxfilepath = pathnode + "\\" + filename + ".shx";
try
{
//先读取.shx文件,得到文件的总字节长度 @"E:\素材\墨西哥Shp数据(ArcGIS)\" +
FileStream fs = new FileStream(shxfilepath, FileMode.Open, FileAccess.Read);
//文件流形式
BinaryReader BinaryFile = new BinaryReader(fs); //二进制读取文件的对象
long BytesSum = fs.Length; //得到文件的字节总长
int shapecount = (int)(BytesSum - 100) / 8; //得以总记录数目
BinaryFile.Close();
fs.Close();
//打开shp文件
if (shxfilepath == "")
{
// MessageBox.Show("索引文件打开出错");
return;
}
//打开.shp文件,读取x,y坐标的信息
fs = new FileStream(shpfilepath, FileMode.Open, FileAccess.Read); //文件流形式
BinaryFile = new BinaryReader(fs); //打开二进制文件
BinaryFile.ReadBytes(32); //先读出36个字节,紧接着是Box边界合
int shapetype = BinaryFile.ReadInt32();
double Left = BinaryFile.ReadDouble(); //读出整个shp图层的边界合
double Bottom = BinaryFile.ReadDouble();
double Right = BinaryFile.ReadDouble();
double Top = BinaryFile.ReadDouble();
BinaryFile.ReadBytes(32); // shp中尚未使用的边界盒
//Get Shape Data From Here On
int stype;
double x, y;
double left, right, top, bottom;
int partcount;
int pointcount;
switch (shapetype)
{
case 1://single point
// geolayer.shapeType = CGConstants.CGShapeType.SHAPE_POINT;
for (int i = 0; i < shapecount; i++)
{
// CGGeoShape.CGGeoPoint gps = new CGGeoShape.CGGeoPoint();
ESRI_POINT shapPoint = new ESRI_POINT();
BinaryFile.ReadBytes(12); //记录头8个字节和一个int(4个字节)的shapetype
/* stype = BinaryFile.ReadInt32();
if (stype != shapetype)
continue;
*/
x = BinaryFile.ReadDouble();
y = BinaryFile.ReadDouble();
shapPoint.objectID = i;
shapPoint.objectUID = i;
shapPoint.x = x;
shapPoint.y = y;
shapPoint.z = 0;
//gps.envlope.left = gps.x;
//gps.envlope.right = gps.x;
//gps.envlope.top = gps.y;
//gps.envlope.bottom = gps.y;
//geolayer.getDataContainer().Add(gps);
Geomtry_Point.Add(shapPoint);
}
StreamWriter sw = new StreamWriter("point.txt");
foreach (ESRI_POINT p in Geomtry_Point)
{
sw.WriteLine("{0},{1},{2} ", p.x, -1 * p.y, 0);
}
sw.Close();
break;
case 8://multi points layer
break;
case 3://Polyline layer
// geolayer.shapeType = CGConstants.CGShapeType.SHAPE_LINE;
for (int i = 0; i < shapecount; i++)
{
// geolayer.getAttributeContainer().Add(ds.Tables[0].Rows[i][0]); //read out the attribute step by step
ESRI_POLYLINE shapePolyline = new ESRI_POLYLINE();
BinaryFile.ReadBytes(12);//记录头8个字节和一个int(4个字节)的shapetype
// int pos = indexRecs[i].Offset+8;
// bb0.position(pos);
// stype = bb0.getInt();
// if (stype!=nshapetype){
// continue;
// }
//获得图形外边框
left = BinaryFile.ReadDouble();
bottom = BinaryFile.ReadDouble();
right = BinaryFile.ReadDouble();
top = BinaryFile.ReadDouble();
partcount = BinaryFile.ReadInt32();
pointcount = BinaryFile.ReadInt32();
int[] parts = new int[partcount];
int[] partspos = new int[partcount];
double[] xpoints = new double[pointcount];
double[] ypoints = new double[pointcount];
double[] zpoints = new double[pointcount];
//firstly read out parts begin pos in file
//节点开始位置
for (int j = 0; j < partcount; j++)
{
parts[j] = BinaryFile.ReadInt32();
}
//shift them to be points count included in parts
if (partcount > 0)
partspos[0] = 0;
int newpos = 0;
for (int j = 0; j <= partcount - 2; j++)
{
parts[j] = parts[j + 1] - parts[j];
newpos += parts[j];
partspos[j + 1] = newpos;
}
parts[partcount - 1] = pointcount - parts[partcount - 1];
//read out coordinates
//读坐标
for (int j = 0; j < pointcount; j++)
{
x = BinaryFile.ReadDouble();
y = BinaryFile.ReadDouble();
xpoints[j] = x;
ypoints[j] = y;
zpoints[j] = 0;
}
if (pointcount > 1)
{
//CGGeoShape.CGGeoLine gl = new CGGeoShape.CGGeoLine(xpoints, ypoints, zpoints, parts, partspos, pointcount, partcount);
//gl.envlope.left = left;
//gl.envlope.right = right;
//gl.envlope.top = top;
//gl.envlope.bottom = bottom;
//gl.objectID = i;
//gl.objectUID = i;
//geolayer.getDataContainer().Add(gl);
shapePolyline.OID = i;
shapePolyline.XPOINTS = xpoints;
shapePolyline.YPOINTS = ypoints;
}
Geomtry_Line.Add(shapePolyline);
}
StreamWriter sw2 = new StreamWriter("line.txt");
count = 1;
foreach (ESRI_POLYLINE p in Geomtry_Line)
{
sw2.WriteLine("{0} ", p.OID);
int number = p.XPOINTS.Length;
for (int i = 0; i < number; i++)
{
sw2.WriteLine("{0} ,{1}", p.XPOINTS[i], -1 * p.YPOINTS[i]);
}
}
sw2.Close();
break;
case 5://Polygon layer
for (int i = 0; i < shapecount; i++)
{
ESRI_POLYGON shapePolygon = new ESRI_POLYGON();
BinaryFile.ReadBytes(12); //记录头8个字节和一个int(4个字节)的shapetype
left = BinaryFile.ReadDouble();
bottom = BinaryFile.ReadDouble();
right = BinaryFile.ReadDouble();
top = BinaryFile.ReadDouble();
partcount = BinaryFile.ReadInt32();
pointcount = BinaryFile.ReadInt32();
int[] parts = new int[partcount];
int[] partspos = new int[partcount];
double[] xpoints = new double[pointcount];
double[] ypoints = new double[pointcount];
double[] zpoints = new double[pointcount];
//firstly read out parts begin pos in file
for (int j = 0; j < partcount; j++)
{
parts[j] = BinaryFile.ReadInt32();
}
//shift them to be points count included in parts
if (partcount > 0)
partspos[0] = 0;
int newpos = 0;
for (int j = 0; j <= partcount - 2; j++)
{
parts[j] = parts[j + 1] - parts[j];
newpos += parts[j];
partspos[j + 1] = newpos;
}
parts[partcount - 1] = pointcount - parts[partcount - 1];
//读坐标
for (int j = 0; j < pointcount; j++)
{
x = BinaryFile.ReadDouble();
y = BinaryFile.ReadDouble();
xpoints[j] = x;
ypoints[j] = y;
zpoints[j] = 0;
}
if (pointcount > 1)
{
shapePolygon.OID = i;
shapePolygon.XPOINTS = xpoints;
shapePolygon.YPOINTS = ypoints;
}
}
break;
default:
return;
}
}
catch (FileNotFoundException ee)
{
ee.ToString();
}
return;
}