ArcEngine下输电线路二三维交互选线

前面输电线路的生成方式前提是实地勘测了杆塔点位,采集了杆塔的坐标,直接导入Excel生成shape文件。现在是做一个输电线路的选址,传统的规划选线作业采用失效性差的纸质地图,造成选线路径方案可行性差,准确性低。应用高分辨率卫星影像和数字高程模型建立三维选线平台以辅助选线并进行杆塔辅助规划,可有效提高线路路径规划的可行性和准确性,节省投资。

基础地理数据主要包括DEM、DOM、DLG,杆塔模型以及其他工程资料。这里条件所限,精度均达不到,只做测试,说明方案的可行性即可。

二维选址场景:

三维选线场景:

二三维交互进行选线,在调整路径平面的同时,可以实时显示纵断面图,并在三维场景下实时显示排位结果,以提高路线优化效率和精度。选线及纵断面图绘制参考前面的博文。二维选线结果:

线路纵断面图绘制结果如下图所示,包括杆塔分布、路线纵断面图以及架空线。架空线采用的是悬链线方程绘制(悬链线的绘制参考前面博文http://blog.csdn.net/giser_whu/article/details/21323807)。从纵断面图来看选线是较为合理的。

三维场景下实时显示排位结果:

通过二三维的交互选线可提高线路规划的效率以及方案的可行性,大大降低了人力劳动,节省了资金,是切实可行的。

下面是纵断面绘制的全部源码,仅供参考。需要说明的是,绘图是采用的Dev的chartcontrol控件,版本是11.1.4,安装见前面博文。

 public partial class ProfileGraphicResult : DevComponents.DotNetBar.Office2007Form
    {
        #region 私有变量

        private IFeatureLayer Linefeaturelayer = null;  //输电线图层
        private IFeatureLayer Pointfeaturelayer = null; //杆塔点位图层
        private IRasterLayer elevationLayer = null;    //DEM

        #endregion

        #region 构造函数

        public ProfileGraphicResult(IFeatureLayer pLineFeaturelayer , IFeatureLayer pPointFeaturelayer , IRasterLayer rasterLayer)
        {
            Linefeaturelayer = new FeatureLayerClass();
            Pointfeaturelayer = new FeatureLayerClass();
            elevationLayer = new RasterLayerClass();

            Linefeaturelayer = pLineFeaturelayer;
            Pointfeaturelayer = pPointFeaturelayer;
            elevationLayer = rasterLayer;
            InitializeComponent();
        }

        #endregion

        #region load
        private void ProfileGraphic_Load(object sender , EventArgs e)
        {
            this.Text = Linefeaturelayer.Name + "纵断面图";
            CreateProfileGraphic();
        }

        #endregion

        #region 获取所有杆塔点位坐标

        //获取杆塔点位
        private static IPointCollection GetTowerPointCollection(IFeatureLayer featurelayer_towerpoint)
        {
            IPointCollection pointCollection = new MultipointClass();
            int featureCount = featurelayer_towerpoint.FeatureClass.FeatureCount(null);
            object missing = Type.Missing;

            for (int i = 0;i < featureCount;i++)
            {
                IPoint point = new PointClass();
                IFeature feature = featurelayer_towerpoint.FeatureClass.GetFeature(i);
                point = feature.ShapeCopy as IPoint;
                pointCollection.AddPoint(point , ref missing , ref missing);

                System.Runtime.InteropServices.Marshal.ReleaseComObject(point);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(feature);

            }

            return pointCollection;

        }

        #endregion

        #region 纵断面内插点

        private List<double> CreateProfileGraphicPointCollection()
        {
            List<double> List_towerElevation = new List<double>(); //高程值集

            try
            {

                //获取所有杆塔点
                IPointCollection ptCollection = new MultipointClass();
                ptCollection = GetTowerPointCollection(Pointfeaturelayer);

                //获取高程内插点
                for (int i = 0;i < ptCollection.PointCount - 1;i++)
                {
                    IPoint point_start = new PointClass();
                    IPoint point_end = new PointClass();
                    IPoint point_temp = new PointClass();
                    (point_temp as IZAware).ZAware = true;

                    IPolyline pLine = new PolylineClass();
                    point_start = ptCollection.get_Point(i);
                    point_end = ptCollection.get_Point(i + 1);
                    pLine.FromPoint = point_start;
                    pLine.ToPoint = point_end;
                    double pLength = OtherHelper.GetPlaneDistance(point_start , point_end);

                   for (int j = 0; j < (int)pLength; j++)
                   {

                       pLine.QueryPoint(esriSegmentExtension.esriNoExtension , j , false , point_temp);
                       double z = OtherHelper.GetValueByPoint(elevationLayer , point_temp);
                       List_towerElevation.Add(z);

                   }

                   System.Runtime.InteropServices.Marshal.ReleaseComObject(pLine);
                   System.Runtime.InteropServices.Marshal.ReleaseComObject(point_start);
                   System.Runtime.InteropServices.Marshal.ReleaseComObject(point_end);
                   System.Runtime.InteropServices.Marshal.ReleaseComObject(point_temp);

                }

                System.Runtime.InteropServices.Marshal.ReleaseComObject(ptCollection);

            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message+"   纵断面插值点生成失败!");
            }

            return List_towerElevation;
        }

        #endregion

        #region 悬链线内插点

        private List<double> CreateTransmissionLinePtCollection(IFeatureLayer featurelayer_line)
        {
            List<double> List_TransmissionLineElevation = new List<double>(); //高程值集

            try
            {
                //获取整条线要素
                IFeature feature = featurelayer_line.FeatureClass.GetFeature(0);
                IPolyline polyline = new PolylineClass();
                polyline = feature.ShapeCopy as IPolyline;

                //获取两个杆塔间的悬链线
                int geometryCount = (polyline as IGeometryCollection).GeometryCount;
                for (int i = 0;i < geometryCount;i++)
                {
                    IPath pLineBetweenTwoTower = new PathClass();
                    pLineBetweenTwoTower = (polyline as IGeometryCollection).get_Geometry(i) as IPath;

                    IPoint point_start = new PointClass();
                    IPoint point_end = new PointClass();
                    point_start = pLineBetweenTwoTower.FromPoint;
                    point_end = pLineBetweenTwoTower.ToPoint;
                    double length = OtherHelper.GetPlaneDistance(point_start , point_end);

                    //判断杆塔点位的前后关系
                    IFeature feature_pt = null;
                    IFeatureCursor featureCursor = Pointfeaturelayer.FeatureClass.Search(null , false);
                    int featureCount = Pointfeaturelayer.FeatureClass.FeatureCount(null);

                    while ((feature_pt=featureCursor.NextFeature())!=null)
                    {
                        IPoint pt = new PointClass();
                        pt = feature_pt.ShapeCopy as IPoint;

                        if (pt.Z == OtherHelper.GetValueByPoint(elevationLayer,point_start))
                        {
                            point_start.ID = feature_pt.OID;
                        }
                        if (pt.Z == OtherHelper.GetValueByPoint(elevationLayer,point_end))
                        {
                            point_end.ID = feature_pt.OID;
                        }
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(pt);
                    }

                    if (point_start.ID>point_end.ID)
                    {

                        for (int j = 0;j <(int) length;j++)
                        {
                            IPoint point_temp = new PointClass();
                            (point_temp as IZAware).ZAware = true;
                            pLineBetweenTwoTower.QueryPoint(esriSegmentExtension.esriNoExtension , length - j , false , point_temp);
                            List_TransmissionLineElevation.Add(point_temp.Z);

                            System.Runtime.InteropServices.Marshal.ReleaseComObject(point_temp);

                        }

                    }
                    else
                    {
                        for (int j = 0;j < (int) length;j++)
                        {
                            IPoint point_temp = new PointClass();
                            (point_temp as IZAware).ZAware = true;
                            pLineBetweenTwoTower.QueryPoint(esriSegmentExtension.esriNoExtension , j , false , point_temp);
                            List_TransmissionLineElevation.Add(point_temp.Z);

                            System.Runtime.InteropServices.Marshal.ReleaseComObject(point_temp);

                        }

                    }

                    System.Runtime.InteropServices.Marshal.ReleaseComObject(pLineBetweenTwoTower);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(point_start);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(point_end);

                }

                System.Runtime.InteropServices.Marshal.ReleaseComObject(feature);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(polyline);

            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message+"  悬链线插值点生成失败!");
            }

            return List_TransmissionLineElevation;
        }
        #endregion

        #region 每一段路线平面长度

        private double[] GetLengthBetweenTwoTower()
        {
            IPointCollection ptCollection = new MultipointClass();
            ptCollection = GetTowerPointCollection(Pointfeaturelayer);

            double[] lengthCollection = new double[ptCollection.PointCount - 1];
            for (int i = 0;i < ptCollection.PointCount - 1;i++)
            {
                double length = OtherHelper.GetPlaneDistance(ptCollection.get_Point(i) , ptCollection.get_Point(i + 1));
                lengthCollection[i] = length;
            }

            return lengthCollection;
        }

        #endregion

        #region 生成纵断面图(地形线、杆塔排位、悬链线)

        private void CreateProfileGraphic()
        {
            try
            {
                //杆塔点位图形
                Series series_point = new Series();
                series_point = CreateTowerPointSeries();

                //纵断面曲线图形
                Series series_line = new Series();
                series_line = CreateProfileGraphicSeries();

                //悬链线图形
                Series series_Transmissionline = new Series();
                series_Transmissionline = CreateTransmissionLineSeries();

                #region 绘图环境参数设置
                //定义标题
                ChartTitle chartTitle = new ChartTitle()
                {
                    Text = Linefeaturelayer.Name + "纵断面图" ,
                    Font = new Font(FontStyle.Bold.ToString() , 22) ,
                    TextColor = System.Drawing.Color.Brown ,
                    Dock = ChartTitleDockStyle.Top ,
                    Alignment = StringAlignment.Center
                };
                chartControl_Profile.Titles.Add(chartTitle);

                //将曲线加入chartcontrol
                chartControl_Profile.Series.Add(series_line);
                chartControl_Profile.Series.Add(series_Transmissionline);
                chartControl_Profile.Series.Add(series_point);
                chartControl_Profile.Legend.Visible = true;

                //定义坐标轴标题

                XYDiagram xydiagram = (XYDiagram) chartControl_Profile.Diagram;

                ((XYDiagram) chartControl_Profile.Diagram).AxisX.Title.Font = new Font("宋体", 10);
                ((XYDiagram) chartControl_Profile.Diagram).AxisX.Title.Alignment = StringAlignment.Far;
                ((XYDiagram) chartControl_Profile.Diagram).AxisX.Title.TextColor = System.Drawing.Color.Red;
                ((XYDiagram) chartControl_Profile.Diagram).AxisX.Title.Text = "输电线路长度/米";
                ((XYDiagram) chartControl_Profile.Diagram).AxisX.Title.Visible = true;
                ((XYDiagram) chartControl_Profile.Diagram).AxisY.Title.Font = new Font("宋体" , 10);
                ((XYDiagram) chartControl_Profile.Diagram).AxisY.Title.Alignment = StringAlignment.Far;
                ((XYDiagram) chartControl_Profile.Diagram).AxisY.Title.TextColor = System.Drawing.Color.Red;
                ((XYDiagram) chartControl_Profile.Diagram).AxisY.Title.Text = "高程/米";
                ((XYDiagram) chartControl_Profile.Diagram).AxisY.Title.Visible = true;
                #endregion

            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message + " 创建纵断面失败!");
            }

        }
        #endregion

        #region 创建杆塔点位图形

        private Series CreateTowerPointSeries()
        {
            //图形属性设置
            Series series_point = new Series("杆塔点位" , ViewType.Point)
            {
                ArgumentScaleType = ScaleType.Numerical
            };
            series_point.Label.Visible = false;
            series_point.View.Color = System.Drawing.Color.Red;
            (series_point.View as PointSeriesView).PointMarkerOptions.Kind = MarkerKind.Star;
            (series_point.View as PointSeriesView).PointMarkerOptions.Size = 15;

            try
            {

                IPointCollection ptCollection = new MultipointClass();
                ptCollection = GetTowerPointCollection(Pointfeaturelayer);

                //获取每一段路线长度集合
                double[] lengthCollection = new double[ptCollection.PointCount - 1];
                lengthCollection = GetLengthBetweenTwoTower();

                //添加杆塔点
                for (int i = 0;i < ptCollection.PointCount;i++)
                {
                    if (i == 0)
                    {
                        double value = ptCollection.get_Point(i).Z;
                        SeriesPoint seriesPt = new SeriesPoint(i + 1 , value);
                        series_point.Points.Add(seriesPt);
                    }
                    else
                    {
                        //循环计算杆塔位置
                        double location = 0.0;
                        for (int j = 0;j < i;j++)
                        {
                            double length = lengthCollection[j];
                            location += length;
                        }

                        double value = ptCollection.get_Point(i).Z;
                        SeriesPoint seriesPt = new SeriesPoint(location , value);
                        series_point.Points.Add(seriesPt);

                    }
                }
                System.Runtime.InteropServices.Marshal.ReleaseComObject(ptCollection);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message + "创建杆塔点位图形失败!!");
            }
            return series_point;

        }

        #endregion

        #region 创建纵断面曲线图

        private Series CreateProfileGraphicSeries()
        {

            //设置纵断面曲线属性
            Series series_line = new Series(Linefeaturelayer.Name + "纵断面图" , ViewType.Spline)
            {
                ArgumentScaleType = ScaleType.Numerical
            };
            series_line.Label.Visible = false;
            series_line.View.Color = System.Drawing.Color.Black;
            (series_line.View as SplineSeriesView).LineMarkerOptions.Kind = MarkerKind.Diamond;
            (series_line.View as SplineSeriesView).LineStyle.Thickness = 2;
            (series_line.View as SplineSeriesView).LineMarkerOptions.BorderVisible = false;
            (series_line.View as SplineSeriesView).LineMarkerOptions.Size = 1;
            (series_line.View as SplineSeriesView).LineStyle.DashStyle = DashStyle.Solid;

            //获取纵断面曲线插值点
            List<double> point_ProfileGraphic = new List<double>();
            point_ProfileGraphic = CreateProfileGraphicPointCollection();

            for (int i = 1;i < point_ProfileGraphic.Count + 1;i++)
            {
                double value = point_ProfileGraphic[i - 1];
                SeriesPoint seriesPoint = new SeriesPoint(i , value);
                series_line.Points.Add(seriesPoint);

            }

            return series_line;

        }

        #endregion

        #region 创建悬链线曲线图

        private Series CreateTransmissionLineSeries()
        {
            //设置曲线属性
            Series series_Transmissionline = new Series("架空线" , ViewType.Line)
            {
                ArgumentScaleType = ScaleType.Numerical
            };
            series_Transmissionline.Label.Visible = false;
            series_Transmissionline.View.Color = SystemColors.HotTrack;

            (series_Transmissionline.View as LineSeriesView).LineMarkerOptions.Kind = MarkerKind.Diamond;
            (series_Transmissionline.View as LineSeriesView).LineStyle.Thickness = 2;
            (series_Transmissionline.View as LineSeriesView).LineMarkerOptions.BorderVisible = false;
            (series_Transmissionline.View as LineSeriesView).LineMarkerOptions.Size = 1;
            (series_Transmissionline.View as LineSeriesView).LineStyle.DashStyle = DashStyle.Dash;

            //获取悬链线插值点
            List<double> point_TransmissionLine = new List<double>();
            point_TransmissionLine = CreateTransmissionLinePtCollection(Linefeaturelayer);

            for (int i = 1;i < point_TransmissionLine.Count + 1;i++)
            {
                double value = point_TransmissionLine[i - 1];
                SeriesPoint seriesPoint = new SeriesPoint(i , value);
                series_Transmissionline.Points.Add(seriesPoint);

            }

            return series_Transmissionline;
        }

        #endregion

    }

欢迎留言交流!

时间: 2024-08-27 19:02:48

ArcEngine下输电线路二三维交互选线的相关文章

ArcEngine下纵断面图的绘制

我是採用Dev控件中的画图控件来绘制的纵断面图,以下主要来介绍下输电线路选址以及纵断面图的实时绘制的实现流程. 一.关于输电线路的选址,首先要准备好基础地理数据,包含选线区的DOM,DEM,DLG以及属性数据等:其次选址採用二三维交互的方式,即以DLG和DOM为背景,初步选择线路路径,,而后在三维场景下将线路反映出来:再次,通过提取线路路径沿线的高程值,绘制纵断面图,并结合三维地貌对塔位进行修正,使各塔处在合理的位置上. 二.详细实现流程 (1)新建一个杆塔点位图层,存放杆塔的属性以及位置信息,

ArcEngine下SceneControl叠加影像数据(构建三维地形)

加载完TIN数据后,需要在三维物体上描绘细节,即纹理:建立DEM表面点与纹理空间点的关系,即纹理映射.叠加影像数据就是把影像看作纹理,将其贴在地形表面,让其具有地形起伏的三维效果. 这里与GlobeControl下三维场景的构建有所不同,在前面的博文中我们提到过,globe下图层主要有三种类型:Floating.Draped.Elevation(浮动.叠加和高程图层),即只需要设置图层的属性即可,叠加图层与浮动图层从高程图层获取高程值.SceneControl中实现影像的叠加,参照ArcScen

【闲聊产品】之二:交互设计还得自己来

移动互联网行业发展到今天,单从技术的地位上来看,核心的软件技术还是被Google.Apple.微软这些巨头掌握着,比如windows.iOS源码,始终会作为一个操作系统的门槛不会被公开,而这些系统平台下衍生的SDK和开发工具却是这些巨头们极力推广的对象. 所以对于大部分不是以技术作为核心竞争力的互联网公司来说,他们其实是在这些巨头们订下的技术标准和自己公司业务做一个整合从而实现成长,因此单从技术的角度来讲,技术固然重要,但已经不是最大的瓶颈了. 如今只要一个技术人员愿意花时间钻研,可供你进步的资

ArcEngine下TIN生成等高线

时间太晚了,直接附上源码: /// <summary> /// TIN生成等高线 /// </summary> /// <param name="pInterval">等高线间距</param> public void Tin2Contour(string path_,string name_,double pInterval) { //获取TIN ITinLayer pTinlayer = GetLayerByName(pScene ,

倾斜摄影技术下打造的三维景区 [转]

http://www.cnblogs.com/Wish3D/p/6557820.html 倾斜摄影技术下打造的三维景区 近年来,节假日随着的游客人流量越来越大,国内各种类型的景区层出不穷,景区规模也是不断扩张,可玩性越来越高. 那么此时问题来了,这么多的景区如何选择自己感兴趣的?景区内有哪些景点?这些景点有怎样的人文历史背景?远在千里之外如何通过网络一睹风采?景区游览路线是什么样子? 如此一来,倾斜摄影技术与三维景区相结合的技术拔地而起,通过倾斜摄影技术来重建采集的景区航拍影像生成倾斜三维模型,

selemiun 下拉菜单、复选框、弹框定位识别

一.下拉菜单识别 对下拉框的操作,主要是通过Select 类里面的方法来实现的,所以需要new 一个Select 对象(org.openqa.selenium.support.ui.Select)来进行操作 public void selectDemo() throws InterruptedException { driver.get("http://tieba.baidu.com/f/search/adv?red_tag=v3168911135"); driver.manage()

在ArcEngine下实现图层属性过滤的两种方法

转自chanyinhelv原文 在ArcEngine下实现图层属性过滤的两种方法 有时候,我们要对图层上的地物进行有选择性的显示,以此来满足实际的功能要求. 按下面介绍的方法可轻松实现图层属性过滤显示: 1.当图层已经加载时 private void ShowByFilter(AxMapControl sMapCtr, IFeatureLayer sFlyr, string sFilter) { ESRI.ArcGIS.Carto.IFeatureLayerDefinition pDef = (

QrenCode : 命令行下生成二维码图片

对于二维码大家应该并不陌生,英文名为 2-dimensional bar code 或 QR Code,是一种用图形记载信息的技术,最常见的是应用在手机应用上.用户通过手机摄像头扫描二维码或输入二维码下面的号码.关键字即可实现快速手机上网,快速便捷地浏览网页.下载图文.音乐.视频等等. 在 Ubuntu / Linux 上,有一个名为 QrenCode 的命令行工具可以很容易帮我们生成二维码. # 安装: sudo apt-get install qrencode # 使用: qrencode

模拟select下拉框之多选(数据源采用模拟Ajax数据--原创)

最近需要一个下拉多选,本来想偷懒的,所以在网上百度了一番,最终还是发现没有一个符合自己要求的,所以我自己写了一个插件.下面是GIF动态效果图展示 相信大家已经看到效果了,接下来就是我的代码展示 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模拟select下拉框之多选</title> <style