AE太重型,还收费,如果只是加载地图作为底图,可以用纯C#实现。线类型用得最多,以下是线类型的数据结构:
总体架构
文件头 |
记录头 记录内容 |
记录头 记录内容 |
。。。。。。。。。。。。 |
记录头 记录内容 |
文件头
位置 | 类型 | 字段 | 说明 |
Byte 0 | int | File Code | 文件代码 |
Byte 4 | int | 无用 | |
Byte 8 | int | 无用 | |
Byte 12 | int | 无用 | |
Byte 16 | int | 无用 | |
Byte 20 | int | 无用 | |
Byte 24 | int | File Length | 文件长度 |
Byte 28 | int | Version | 版本 |
Byte 32 | int | Shape Type |
图形类型 1:Point,点类型 3:PolyLine,线类型 5:Polygon,面类型 |
Byte 36 | double | Xmin | 整图的X轴坐标最小值 |
Byte 44 | double | Ymin | 整图的Y轴坐标最小值 |
Byte 52 | double | Xmax | 整图的X轴坐标最大值 |
Byte 60 | double | Ymax | 整图的Y轴坐标最大值 |
Byte 68* | double | Zmin | |
Byte 76* | double | Zmax | |
Byte 84* | double | Mmin | |
Byte 92* | double | Mmax |
记录头
位置 | 类型 | 字段 | 说明 |
Byte 0 | int | Record Number | 记录号,从1开始 |
Byte 4 | int | Content Length | 内容长度,内容的16位字数,不包括记录号。 |
记录内容
点类型:
位置 | 类型 | 字段 | 说明 |
Byte 0 | int | ShapeType | Shape类型=1 |
Byte 4 | double | X | 点的X坐标 |
Byte 12 | double | Y | 点的Y坐标 |
线类型:
位置 | 类型 | 字段 | 说明 |
Byte 0 | int | ShapeType | Shape类型=3 |
Byte 4 | double [4] | Box | 该线条的边界盒,以Xmin,Ymin,Xmax,Ymax的顺序存储 |
Byte 36 | int | NumParts | 是PolyLine中部分的数目 |
Byte 40 | int | NumPoints | 是PolyLine中点的数目 |
Byte 44 | int [NumParts] | Parts | 每条PolyLine存储它在点数列中的第一个点的索引。数列索引是从0开始的。Parts[NumParts]数组是Points[NumPoints]数组的目录 |
X | Point[NumPoints] | Points | 本条记录的所有点。Struct Point {Double X;Double Y;} |
Parts和Points之间的关系: 如果Parts [0]=0Parts [1]=3Parts [2]=11Parts [3]=15…那么 第0条线:(Points[0], Points[1] , Points[2])三个点依次连结 第1条线:(Points[3], Points[4] , Points[5] , Points[6] , Points[7] , Points[8] , Points[9] , Points[10])这几个点依次连结 第3条线:(Points[11], Points[12] , Points[13] , Points[14])四个点依次连结 … |
ClassShp类:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO; namespace SDD
{
struct StructShapePoint
{
public double X;
public double Y;
} struct StructShapePolyline
{
public int RecordNumber;//记录号
public int ContentLength;//内容长度
public int ShapeType;
public double[] Box;//长度为4
public int PartsCount;
public int PointsCount;
public List<int> Parts;//在部分中第一个点的索引
public List<StructShapePoint> Points;//所有部分的点
public List<StructShapePoint[]> Lines;//把点按线组织好
} class ClassShp
{
public string FileName;
public int FileLength;
public int FileVersion;
public int ShapeType;//绘图类型:1-点,3-线,5-面
public double Xmin, Ymin, Xmax, Ymax;//地图边界尺寸
public double RawWidth, RawHeight;//地图大小,原始值
public double RawCenterX, RawCenterY;//shp原始坐标系的中心点
public List<StructShapePoint> ListPoints = new List<StructShapePoint>();//点集合
public List<StructShapePolyline> ListPolylines = new List<StructShapePolyline>();//线集合 public double Scale = ;//放大倍数,原始数据中1表示的像素数
public double CenterX, CenterY;//地图缩放后的中心点在控件坐标系中的位置 public double WindowWidth;//显示控件大小
public double WindowHeight; public Bitmap Bmp = null;//用于显示的画布,大小等于显示控件
public Pen ThePen = new Pen(Color.White, ); public ClassShp()
{ } public ClassShp(string pmtShpPathName, double pmtVisibleWidth, double pmtVisibleHeight)
{
if (File.Exists(pmtShpPathName) == false) return;
if (Init(pmtShpPathName, pmtVisibleWidth, pmtVisibleHeight))
{
SaveAsTxt(); //把数据保存成文本文档
}
} //################################################################################
// 由Xmin等四个值计算出基本成员参数
//################################################################################
public void SetBaseParameter(double pmtXmin,double pmtYmin,double pmtXmax,double pmtYmax)
{
Xmin = pmtXmin;
Ymin = pmtYmin;
Xmax = pmtXmax;
Ymax = pmtYmax; RawWidth = Xmax - Xmin;
RawHeight = Ymax - Ymin;
RawCenterX = (Xmin + Xmax) / ;
RawCenterY = (Ymin + Ymax) / ; CenterX = WindowWidth / ;
CenterY = WindowHeight / ; SetRelativityScale(, WindowWidth, WindowHeight); Console.WriteLine("绘图类型:{0}", ShapeType);
Console.WriteLine("地图边界:({0}, {1}), ({2}, {3})", Xmin, Ymin, Xmax, Ymax);
Console.WriteLine("地图大小:{0} * {1}", RawWidth, RawHeight);
Console.WriteLine("地图中心:({0}, {1})", RawCenterX, RawCenterY);
} //################################################################################
// 初始化
//################################################################################
public bool Init(string pmtShpPathName, double pmtVisibleWidth, double pmtVisibleHeight)
{
if (File.Exists(pmtShpPathName) == false) return false; int nameIndex = pmtShpPathName.LastIndexOf("\\")+;
int nameLenght = pmtShpPathName.Length--pmtShpPathName.LastIndexOf("\\"); FileName = pmtShpPathName.Substring(nameIndex, nameLenght); WindowWidth = pmtVisibleWidth;
WindowHeight = pmtVisibleHeight; try
{
FileStream fs = new FileStream(pmtShpPathName, FileMode.Open);
BinaryReader br = new BinaryReader(fs, Encoding.Default); br.ReadBytes();
FileLength = br.ReadInt32();
FileVersion = br.ReadInt32();
ShapeType = br.ReadInt32(); Xmin = br.ReadDouble();
Ymin = br.ReadDouble();
Xmax = br.ReadDouble();
Ymax = br.ReadDouble(); br.ReadBytes(); if (ShapeType == )
{
ListPoints.Clear();
while (br.PeekChar() != -)
{
StructShapePoint shapePoint = new StructShapePoint();
uint recordNum = br.ReadUInt32();
int dataLength = br.ReadInt32();
br.ReadInt32();
shapePoint.X = br.ReadDouble();
shapePoint.Y = br.ReadDouble();
ListPoints.Add(shapePoint);
}
}//end of : if (ShpType==1)
else if (ShapeType == || ShapeType == )
{
ListPolylines.Clear();
while (br.PeekChar() != -)
{
StructShapePolyline shapePolyline = new StructShapePolyline();
shapePolyline.Box = new double[];
shapePolyline.Parts = new List<int>();
shapePolyline.Points = new List<StructShapePoint>();
shapePolyline.Lines = new List<StructShapePoint[]>();
shapePolyline.RecordNumber = br.ReadInt32();
shapePolyline.ContentLength = br.ReadInt32();
shapePolyline.ShapeType = br.ReadInt32();
shapePolyline.Box[] = br.ReadDouble();
shapePolyline.Box[] = br.ReadDouble();
shapePolyline.Box[] = br.ReadDouble();
shapePolyline.Box[] = br.ReadDouble();
shapePolyline.PartsCount = br.ReadInt32();
shapePolyline.PointsCount = br.ReadInt32(); //把每一段线的开始点偏移读进Parts队列
for (int i = ; i < shapePolyline.PartsCount; i++)
{
int tmpPart = br.ReadInt32();
shapePolyline.Parts.Add(tmpPart);
}
//把所有点读进Points队列
for (int i = ; i < shapePolyline.PointsCount; i++)
{
StructShapePoint tmpPoint = new StructShapePoint();
tmpPoint.X = br.ReadDouble();
tmpPoint.Y = br.ReadDouble();
shapePolyline.Points.Add(tmpPoint);
}
//把该线的点读进Lines队列
for (int i = ; i < shapePolyline.PartsCount; i++)
{
int startpoint;
int endpoint; if (i == shapePolyline.PartsCount - )
{
startpoint = (int)shapePolyline.Parts[i];
endpoint = shapePolyline.PointsCount;
}
else
{
startpoint = (int)shapePolyline.Parts[i];
endpoint = (int)shapePolyline.Parts[i + ];
}
StructShapePoint[] shpPointArray = new StructShapePoint[endpoint - startpoint];
for (int j = , k = startpoint; k < endpoint; j++, k++)
{
shpPointArray[j].X = shapePolyline.Points[k].X;
shpPointArray[j].Y = shapePolyline.Points[k].Y;
}
shapePolyline.Lines.Add(shpPointArray);
}
//把该线条加进m_polylines队列
ListPolylines.Add(shapePolyline);
}
}//end of : else if (ShpType == 3)
SetBaseParameter(Xmin, Ymin, Xmax, Ymax);
return true;
}
catch (System.Exception ex)
{
Console.WriteLine("异常:ClassShp.Init()" + ex.ToString());
return false;
}
} //################################################################################
// 把数据写成txt文本
//################################################################################
public void SaveAsTxt()
{
StreamWriter swLine = new StreamWriter(FileName+".txt");
swLine.WriteLine("绘图类型:{0}", ShapeType);
swLine.WriteLine("地图边界:({0}, {1}), ({2}, {3})", Xmin, Ymin, Xmax, Ymax);
swLine.WriteLine("地图大小:{0} * {1}", RawWidth, RawHeight);
swLine.WriteLine("地图中心:({0}, {1})", RawCenterX, RawCenterY); int recordCount = ;
if (ShapeType==)
{
foreach (StructShapePoint p in ListPoints)
{
swLine.WriteLine("点{0}: ({1}, {2})", recordCount, p.X, p.Y);
recordCount++;
}
}
else if (ShapeType== || ShapeType==)
{
foreach (StructShapePolyline p in ListPolylines)
{
for (int i = ; i < p.Lines.Count; i++)
{
swLine.WriteLine("记录内容{0}:########################################################", recordCount, i);
for (int j = ; j < p.Lines[i].Length; j++)
{
StructShapePoint ps = p.Lines[i][j];
swLine.WriteLine("线{0}: ({1}, {2})", j, ps.X, ps.Y);
}
}
recordCount++;
}//end of :foreach
}
swLine.Close();
} //################################################################################
// 把图绘进Bmp中
//################################################################################
public bool DrawBmp(int pmtWidth, int pmtHeight)
{
double screenWidth = RawWidth * Scale;
double screenHeight = RawHeight * Scale; try
{
Bmp = new Bitmap(pmtWidth, pmtHeight);//创建画布
Graphics g = Graphics.FromImage(Bmp); g.TranslateTransform((float), (float)pmtHeight);//变换坐标系,把左下角置为原点
g.ScaleTransform((float), (float)-); if (ShapeType == ) //点类型
{
foreach (StructShapePoint p in ListPoints)
{
PointF pf = new PointF();
double offsetX = CenterX - screenWidth / 2.0;
double offsetY = CenterY - screenHeight / 2.0;
pf.X = (float)((p.X - Xmin) * Scale + offsetX);
pf.Y = (float)((p.Y - Ymin) * Scale + offsetY);
float r = ;
//g.DrawEllipse(ThePen, pf.X - r / 2, pf.Y + r / 2, r * 2, r * 2);//画点
Brush bs = new SolidBrush(Color.Green);//填充的颜色
g.FillEllipse(bs, pf.X - r / , pf.Y + r / , r * , r * );
}
}
else if (ShapeType == 3 || ShapeType == 5) //线类型和面类型是一样的
{
//Console.WriteLine("线类型");
foreach (StructShapePolyline p in ListPolylines)
{
for (int i = ; i < p.Lines.Count; i++)
{
PointF[] pfArray = new PointF[p.Lines[i].Length];
for (int j = ; j < p.Lines[i].Length; j++)
{
StructShapePoint ps = p.Lines[i][j];
double offsetX = CenterX - screenWidth / 2.0;
double offsetY = CenterY - screenHeight / 2.0;
pfArray[j].X = (float)((ps.X - Xmin) * Scale + offsetX);
pfArray[j].Y = (float)((ps.Y - Ymin) * Scale + offsetY);
}
g.DrawLines(ThePen, pfArray);
}
}
} return true;
}
catch (System.Exception ex)
{
Console.WriteLine("异常:ClassShp.drawBmp" + ex.ToString());
return false;
}
}
}
}
在主窗口放置一个pictureBox控件,名为pictureBoxMap.
主函数:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging; namespace SDD
{
public partial class FormMain : Form
{
ClassShp ShapeChina; public FormMain()
{
InitializeComponent(); string mapChinaPathName = new ClassShp(@"D:\map\地图\国界.shp", pictureBoxMap.Width, pictureBoxMap.Height);
pictureBoxMap.Refresh();
}
private void pictureBoxMap_Paint(object sender, PaintEventArgs e)
{
Bitmap bmp = new Bitmap(pictureBoxMap.Width, pictureBoxMap.Height);//创建画布
ShapeChina.DrawBmp(pictureBoxMap.Width, pictureBoxMap.Height);
e.Graphics.DrawImage(ShapeChina.Bmp, , );
}
}
}