zoukankan      html  css  js  c++  java
  • 地图分幅算法实现

    关于地图分幅算法的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());
                }

            }

    看看效果吧~~
     


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yanleigis/archive/2008/10/15/3078691.aspx

  • 相关阅读:
    【记录】用了七年eclipse突然改用IntelliJ IDEA------- 痛并快乐着
    【记录】集合Collection和Map整理 (看这一篇就够了)
    group by语句报with sql_mode=only_full_group_by错误
    linux下安装mysql二进制版本(5.6.34)
    linux下安装mysql二进制版本(5.7.11)
    表空间传输-例子2(full transportable)
    表空间传输-例子3(rman-transport获取传输表空间文件)
    transport_datafiles与FLASHBACK_SCN不能一起使用
    表空间传输数据文件转换
    12C添加pdb后创建用户没有相应的表空间
  • 原文地址:https://www.cnblogs.com/linghe/p/1635502.html
Copyright © 2011-2022 走看看