地图分幅算法实现08-08-07 18:34:19 http://blog.sina.com.cn/xiaojingyao
核心提示:地图分幅算法实现
关于地图分幅算法的AE实现,下面是C#代码~
public enum ScaleMark { A, B, C, D, E, F, G, H };//不同比例尺的号码
private int m_1s1000000_row;//1:100万图幅行
private int m_1s1000000_list;//1:100万图幅列
private int m_assign_row;//指定比例尺图幅行
private int m_assign_list;//指定比例尺图幅列
private int m_scale;//指定比例尺;
private FrmGeocodingExport pFGE;
private esriUnits m_CurMapUnits;
#region 图幅号计算函数
private IEnvelope FromGeocodingDawn()
{
//计算要素的值
int h = this.m_1s1000000_row ;//1:100万行号
int l = this.m_1s1000000_list ;//1:100万列号
ScaleMark ScaleMark_1s1000000 = new ScaleMark();
IPoint scaleDelta_1s1000000 = new PointClass();
ScaleMark_1s1000000 = 0;
this.initialScaleMark(ScaleMark_1s1000000, scaleDelta_1s1000000);
double delta_x = scaleDelta_1s1000000.X;//1:100万经差(度)
double delta_y = scaleDelta_1s1000000.Y;//1:100万纬差(度)
ScaleMark pScaleMark = new ScaleMark();
IPoint scaleDelta = new PointClass();
pScaleMark = (ScaleMark )m_scale ;
this.initialScaleMark(pScaleMark , scaleDelta);
double delta_xp = scaleDelta.X;//1:10万经差(度)
double delta_yp = scaleDelta.Y;//1:10万纬差(度)
int hp = m_assign_row;
int lp = m_assign_list;
IEnvelope pEnvelope = new EnvelopeClass();
if (m_assign_list != 0 && m_assign_row != 0)
{
//进行指定图幅号左上角点经纬度计算
double ymax = h * delta_y - (hp - 1) * delta_yp; //纬度
double xmin = (l - 31) * delta_x + (lp - 1) * delta_xp;//经度
//推算指定图幅号右下角点坐标
double ymin = ymax - delta_yp;
double xmax = xmin + delta_xp;
//将点转换成地图存储单位Map(Metres) convertUnits
//esriUnits CurMapUnits = this.axMapControl1.Map.MapUnits;
IUnitConverter UC_map = new UnitConverterClass();
double yMax = UC_map.ConvertUnits(ymax, esriUnits.esriDecimalDegrees, m_CurMapUnits);
double yMin = UC_map.ConvertUnits(ymin, esriUnits.esriDecimalDegrees, m_CurMapUnits);
double xMax = UC_map.ConvertUnits(xmax, esriUnits.esriDecimalDegrees, m_CurMapUnits);
double xMin = UC_map.ConvertUnits(xmin, esriUnits.esriDecimalDegrees, m_CurMapUnits);
pEnvelope.PutCoords(xMin, yMin, xMax, yMax);
return pEnvelope;
}
else
{
return null;
}
}
#endregion
#region 各比例尺经纬度差
private void initialScaleMark(ScaleMark pScaleMark, IPoint scaleDelta)
{
//IPoint[] scaleArr = new IPoint[8];
//IPoint scaleDelta = new PointClass();
switch (pScaleMark)
{
case ScaleMark.A:
scaleDelta.X = 6;//1:100万经差(度)
scaleDelta.Y = 4;//1:100万纬差(度)
break;
case ScaleMark.B:
scaleDelta.X = 3;//1:50万经差(度)
scaleDelta.Y = 2;//1:50万纬差(度)
break;
case ScaleMark.C:
scaleDelta.X = 1.5;//1:25万经差(度)
scaleDelta.Y = 1;//1:25万纬差(度)
break;
case ScaleMark.D:
scaleDelta.X = 0.5;//1:10万经差(度)
scaleDelta.Y = 0.33333;//1:10万纬差(度)
break;
case ScaleMark.E:
scaleDelta.X = 0.25;//1:5万经差(度)
scaleDelta.Y = 0.16667;//1:5万纬差(度)
break;
case ScaleMark.F:
scaleDelta.X = 0.125;//1:2.5万经差(度)
scaleDelta.Y = 0.08333;//1:2.5万纬差(度)
break;
case ScaleMark.G:
scaleDelta.X = 0.0625;//1:1万经差(度)
scaleDelta.Y = 0.04167;//1:1万纬差(度)
break;
case ScaleMark.H:
scaleDelta.X = 0.03125;//1:5000经差(度)
scaleDelta.Y = 0.02083;//1:5000纬差(度)
break;
}
}
#endregion
#region 调整elements里面的显示框标准(因为我用了ae中pagelayout的模板,所以要把MapFrame调整到图幅框的缩放比例)
public void AdjustMapFrameInPageLayout(IMapFrame pMapFrame, IEnvelope pMapControlEnv)
{
//调整elements里面的显示框标准
//IMapFrame pMapFrame = ((IActiveView)this.axPageLayoutControl1.PageLayout).GraphicsContainer.FindFrame(this.axPageLayoutControl1.ActiveView.FocusMap) as IMapFrame;
IElement pElement = pMapFrame as IElement;
//获取当前mapFrame的中心点坐标;
IEnvelope MainEnv = pElement.Geometry.Envelope;
pElement.QueryBounds(this.axPageLayoutControl1.ActiveView.ScreenDisplay, MainEnv);
IPoint pCenterPoint = new PointClass();//MapFrame中心点坐标
pCenterPoint.X = MainEnv.XMax - MainEnv.Width / 2;
pCenterPoint.Y = MainEnv.YMax - MainEnv.Height / 2;
//根据当前MapFrame的标准和pEnvelope的比例关系决定更改后的MapFrame长宽度
double ratio = pMapControlEnv.Height / pMapControlEnv.Width;
double CurMapFrameRatio = MainEnv.Height / MainEnv.Width;
//IEnvelope pageEnvelope = this.axPageLayoutControl1.PageLayout.Page.PrintableBounds;
double dDataFrameWidth, dDataFrameHeight;
double scale;
if (ratio >= CurMapFrameRatio)
{
dDataFrameHeight = MainEnv.Height;
dDataFrameWidth = dDataFrameHeight / ratio;
}
else
{
dDataFrameWidth = MainEnv.Width;//地图MapFrame应该的宽度
dDataFrameHeight = dDataFrameWidth * ratio;//地图MapFrame应该的高度
}
IElement tempElement = pMapFrame as IElement;
tempElement.Geometry = pMapControlEnv;
ITransform2D pTransform2d = (ITransform2D)tempElement;
IPoint pFrameCenter = new PointClass();
pFrameCenter.X = pMapControlEnv.XMax - pMapControlEnv.Width / 2;
pFrameCenter.Y = pMapControlEnv.YMax - pMapControlEnv.Height / 2;
scale = dDataFrameWidth / pMapControlEnv.Width;//缩放比例
double dx = pCenterPoint.X - pFrameCenter.X;
double dy = pCenterPoint.Y - pFrameCenter.Y;
pTransform2d.Move(dx, dy);//移动到指定位置
pTransform2d.Scale(pCenterPoint, scale, scale);//将MapFrame图形缩放
}
#endregion
//最后图幅加载到pagelayout中显示,是单击按钮事件哦
private void bt_contain_Click(object sender, EventArgs e)
{
try
{
this.splitCodeValue();
this.pFGE.axPageLayoutControl1.LoadMxFile(pFGE.filename, "");
//生成指定图幅号图幅两个对角点的坐标 IEnvelope FromGeocodingDawn(string geocoding)
//double xMin = 555000;
//double yMin = 2898000;
//double xMax = 560000;
//double yMax = 2904000;
//确定一个矩形
IEnvelope pEnvelope = new EnvelopeClass();
pEnvelope = this.FromGeocodingDawn();//.PutCoords(xMin, yMin, xMax, yMax);
//用此矩形切底图,并加载到pagelayoutcontrol中显示
IActiveView pActiveView = pFGE.axMapControl1.ActiveView.FocusMap as IActiveView;
pFGE.axMapControl1.ActiveView.Extent = pEnvelope;
IActiveView activeView = pFGE.axPageLayoutControl1.ActiveView.FocusMap as IActiveView;
IDisplayTransformation DT = new DisplayTransformationClass();
DT = activeView.ScreenDisplay.DisplayTransformation;
DT.VisibleBounds = pEnvelope;
activeView.Refresh();
//调整elements里面的显示框标准
IMapFrame pMapFrame = ((IActiveView)pFGE.axPageLayoutControl1.PageLayout).GraphicsContainer.FindFrame(pFGE.axPageLayoutControl1.ActiveView.FocusMap) as IMapFrame;
this.pFGE.AdjustMapFrameInPageLayout(pMapFrame, pEnvelope);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
看看效果吧~~
本篇文章来源于GIS动力站|www.gispower.org 原文链接:http://www.gispower.org/article/arcgis/ao/2008/86/0886183419F74545EGE0JE5EI5HB0H.html