using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.Display; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Geometry; using KGIS.Framework.AE; using KGIS.Framework.Maps; using KGIS.Framework.Platform; using KGIS.Framework.Utils; using KGIS.Framework.Utils.Enum; using KGIS.Framework.Utils.ExtensionMethod; using KGIS.Framework.Utils.Helper; using KGIS.Framework.Utils.Model; using Kingo.Plugin.EngineEditor.Common; using Kingo.Plugin.EngineEditor.Model; using Kingo.Plugin.EngineEditor.Views; using Kingo.PluginServiceInterface; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using UIShell.OSGi; namespace Kingo.Plugin.EngineEditor.Commands.Tools { /// /// 画双线(道路线)工具 /// public class ControlsEditingDrawDoubleLineTool : BaseToolCommand { private IEngineSnapEnvironment snapEnv = null; #region 私有变量 //KOTilesLayer layer = null; private EngineEditorClass m_editor; private IHookHelper m_hookHelper; /// /// 平移工具 /// private ControlsMapPanToolClass panTool = new ControlsMapPanToolClass(); /// /// 中间线 /// private LineModel MiddleLine; /// /// 左边线 /// private LineModel LeftLine; /// /// 右边线 /// private LineModel RightLine; private bool _IsDrawing; /// /// 正在绘制 /// private bool IsDrawing { get { return _IsDrawing; } set { _IsDrawing = value; if (_IsDrawing) { (m_hookHelper.Hook as IMapControlDefault).AutoMouseWheel = false; (m_hookHelper.Hook as IMapControlDefault).AutoKeyboardScrolling = false; } else { (m_hookHelper.Hook as IMapControlDefault).AutoMouseWheel = true; (m_hookHelper.Hook as IMapControlDefault).AutoKeyboardScrolling = true; } } } private Boolean IsSpaceDown = false; private bool IsCtrlDown = false; private IElement TextElement; /// /// 记录鼠标当前位置 /// private System.Drawing.Point MousePoint = new System.Drawing.Point(); private bool IsChangedWidth = false; /// /// 道路线最小点间距 /// private int MinPointDistance = 30; /// /// 道路线最大点间距 /// private int MaxPointDistance = 80; private DrawParam drawParam { get; set; } FrmDrawDoublePolyline paramFrm = null; private bool IsAutoTrackPoint { set { if (MiddleLine != null) { MiddleLine.IsAutoTrackPoint = value; } if (LeftLine != null) { LeftLine.IsAutoTrackPoint = value; } if (RightLine != null) { RightLine.IsAutoTrackPoint = value; } } } /// /// 是否自动追踪 /// private bool IsAuto = false; #region 地图自动漫游相关变量 /// /// 表示是否开启自动漫游功能 /// private bool AllowMoveMap = false; /// /// 地图漫游计时器(表示多久移动一次地图) /// private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); /// /// 鼠标距离地图边界的距离(当小于指定值是开始漫游) /// private int MapBorderDistance = 10; #endregion #region 自动识别功能相关变量 /// /// 自动识别计时器(相隔一定时间,根据鼠标位置自动识别一次) /// private System.Windows.Forms.Timer autoDistinguishTimer = new System.Windows.Forms.Timer(); /// /// 用于存放自动识别到的点元素集合 /// private List PointElement = new List(); /// /// 用于存放自动识别到的宽度 /// private double TempWidht = 0; /// /// 用于临时存放自动识别到的中心点 /// private IPoint TempCenterPoint = null; #endregion /// /// 记录捕捉Element上点的索引 /// private int SnapElementPointIndex = -1; /// /// 记录捕捉的点在哪条线上(0:中心线;1:左边线;-1:右边线) /// private int SnapElementPointLine = 0; #endregion #region 重写BaseCommand public override void OnCreate(object hook) { try { if (m_hookHelper == null) { m_hookHelper = new HookHelper(); m_hookHelper.Hook = hook; } panTool.OnCreate(hook); base.OnCreate(hook); m_editor = new EngineEditorClass(); //m_editor.OnStopEditing += m_editor_OnStopEditing; //m_editor.OnTargetLayerChanged += m_editor_OnTargetLayerChanged; snapEnv = (IEngineSnapEnvironment)m_editor; } catch (Exception ex) { LogAPI.Debug("初始化 画双线 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("初始化 画双线 时异常信息结束"); } } //void m_editor_OnTargetLayerChanged() //{ // if (paramFrm != null) // { // paramFrm.Close(); // paramFrm = null; // base.Deactivate(); // } //} //void m_editor_OnStopEditing(bool saveChanges) //{ // if (paramFrm != null) // { // paramFrm.Close(); // paramFrm = null; // base.Deactivate(); // } //} private bool IsDeactivate; //private EngineSnapAgentClass m_SnapAgent = null; private IMapService _MapService; public override void OnClick() { try { //KGIS.Framework.Common.Utils.LicenseManager.License(); _MapService = MapsManager.Instance.MapService; if (m_editor.EditState != esriEngineEditState.esriEngineStateEditing) return; base.OnClick(); panTool.OnClick(); if (drawParam == null) { drawParam = new DrawParam(); drawParam.DrawMode = DrawMode.LeftAndRight; drawParam.Width = 10; drawParam.ToloranceScale = 0.2; } if (paramFrm != null) { paramFrm.Close(); } if (paramFrm == null) { paramFrm = new FrmDrawDoublePolyline(drawParam); paramFrm.SetParam(true, false); paramFrm.Closed += paramFrm_Closed; //paramFrm.Title = this.Caption; //paramFrm.Topmost = true; paramFrm.ShowInTaskbar = false; paramFrm.Top = 175; paramFrm.Left = 235; paramFrm.Show(); } timer.Interval = 100; timer.Tick += timer_Tick; autoDistinguishTimer.Interval = 100; autoDistinguishTimer.Tick += autoDistinguishTimer_Tick; AllowMoveMap = false; if (_MapService != null) { _MapService.MapContainerMouseWheel -= Platfrom_MapMouseWheel; _MapService.MapContainerMouseWheel += Platfrom_MapMouseWheel; } MiddleLine = new LineModel(m_hookHelper.ActiveView, esriSimpleLineStyle.esriSLSDash, 0.5); LeftLine = new LineModel(m_hookHelper.ActiveView, esriSimpleLineStyle.esriSLSSolid); RightLine = new LineModel(m_hookHelper.ActiveView, esriSimpleLineStyle.esriSLSSolid); this.MiddleLine.Init(); this.RightLine.Init(); this.LeftLine.Init(); IsDeactivate = false; IsSpaceDown = false; base.m_cursor = System.Windows.Forms.Cursors.Cross; } catch (Exception ex) { LogAPI.Debug("点击 画双线 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("点击 画双线 时异常信息结束"); MessageHelper.ShowError(ex.Message); //LogAPI.Debug(ex); } } /// /// 鼠标距离地图边界一定距离时,开始漫游 /// /// /// void timer_Tick(object sender, EventArgs e) { try { IEnvelope extent = this.m_hookHelper.ActiveView.Extent; int centerX = 0; int centerY = 0; int rX = 0; int rY = 0; this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(new PointClass() { X = extent.XMax, Y = extent.YMin }, out rX, out rY); IPoint centerPoint = new PointClass() { X = extent.XMin + (extent.XMax - extent.XMin) / 2, Y = extent.YMin + (extent.YMax - extent.YMin) / 2 }; this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(centerPoint, out centerX, out centerY); bool NeedPan = false; if (!IsDrawing) { timer.Stop(); return; } if (MousePoint.X < MapBorderDistance) { NeedPan = true; centerX -= 5; } if (MousePoint.Y < MapBorderDistance) { NeedPan = true; centerY -= 5; } if (Math.Abs(rX - MousePoint.X) < MapBorderDistance) { NeedPan = true; centerX += 5; } if (Math.Abs(rY - MousePoint.Y) < MapBorderDistance) { NeedPan = true; centerY += 5; } if (NeedPan) { centerPoint = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(centerX, centerY); (this.m_hookHelper.Hook as IMapControl2).CenterAt(centerPoint); } } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线时 计时器标记漫游 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时 计时器标记漫游 时异常信息结束"); } } void paramFrm_Closed(object sender, EventArgs e) { paramFrm = null; } public override bool Enabled { get { if (MapsManager.Instance == null) return false; object pTemp = (MapsManager.Instance.CurrProjectInfo as ProjectInfo); if (pTemp == null) { return false; } else { m_editor = new EngineEditorClass(); if (m_editor.EditState == esriEngineEditState.esriEngineStateEditing && m_editor.TargetLayer != null) { if (m_editor.TargetLayer is IFeatureLayer && (m_editor.TargetLayer as IFeatureLayer).FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline) { return true; } else { if (this.IsDrawing) { this.Deactivate(); } return false; } } else { if (this.IsDrawing) { this.Deactivate(); } return false; } } } } #endregion IElement element = null; private int IsEnterClickNum = 0; private bool IsShiftDown = false; #region 重写BaseTool public override void OnKeyDown(int keyCode, int Shift) { try { base.OnKeyDown(keyCode, Shift); //键盘按下时不启用放大缩小功能 (m_hookHelper.Hook as IMapControlDefault).AutoMouseWheel = false; (m_hookHelper.Hook as IMapControlDefault).AutoKeyboardScrolling = false; //---------------------- IPoint point = this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(MousePoint.X, MousePoint.Y); Platform.Instance.SetCurrentKeyDown(keyCode); if (keyCode == (int)ConsoleKey.F7) { try { #region 自动识别 if (TempCenterPoint == null || TempWidht <= 0) { //如果没有识别到,调用手动取点 this.OnKeyDown((int)ConsoleKey.F8, Shift); return; } this.IsAuto = true; if (TempWidht > 0 && MiddleLine.Line.PointCount == 1 && !IsChangedWidth) { //如果识别到点,并且已经绘制了一个点,并且宽度没有手动调整过,则应用识别的宽度并修改第一个点的宽度 this.drawParam.Width = TempWidht; this.OnMouseMove(1, Shift, MousePoint.X, MousePoint.Y); //Moveing(point); } this.drawParam.Width = TempWidht; ///当前线上面最后一个点的X坐标 int endX = -1; ///当前线上面最后一个点的Y坐标 int endY = -1; ///下一个点的X坐标 int nextX = -1; ///下一个点的Y坐标 int nextY = -1; if (MiddleLine.Line.PointCount > 0) { this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1), out endX, out endY); } this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(TempCenterPoint, out nextX, out nextY); if (nextX != -1 && nextY != -1 && endX != -1 && endY != -1) { IPolyline line = new PolylineClass(); line.FromPoint = MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1); line.ToPoint = TempCenterPoint; //当两次取点距离小于30像素的时候,取消上一个点,以第二次的点为主 if (line.Length < 3) { //取消上一个点 this.OnKeyDown((int)ConsoleKey.F9, 0); } ///以识别到的点进行绘制新的点 LeftClick(nextX, nextY); this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1), out nextX, out nextY); //MoveMapExtent(nextX, nextY, 100); } TempCenterPoint = null; #endregion } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 F7 后自动识别 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 F7 后自动识别 时异常信息结束"); } } else if (keyCode == (int)ConsoleKey.F8) { try { #region 快捷键取点 this.IsAuto = false; ///当前线上面最后一个点的X坐标 int endX = -1; ///当前线上面最后一个点的Y坐标 int endY = -1; if (MiddleLine.Line.PointCount > 0) { this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1), out endX, out endY); } //当两次取点距离小于30像素的时候,取消上一个点,以第二次的点为主 if (endX != -1 && endY != -1 && Math.Abs(MousePoint.X - endX) < 30 && Math.Abs(MousePoint.Y - endY) < 30) { //取消上一个点 this.OnKeyDown((int)ConsoleKey.F9, 0); } //绘制新的点 this.LeftClick(MousePoint.X, MousePoint.Y); #endregion } catch (Exception ex) { //KGIS.Common.Utility.LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 F8 后快捷键取点 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 F8 后快捷键取点 时异常信息结束"); } } else if (keyCode == (int)ConsoleKey.F9 || keyCode == (int)ConsoleKey.Escape || keyCode == (int)ConsoleKey.Delete) { try { if (this.MiddleLine.Line.PointCount > 0 && this.IsDrawing == false) { //删除点 #region 删除点 if (SnapElementPointIndex == -1) { SnapElementPointIndex = SnapElement(point, out SnapElementPointLine); } if (SnapElementPointIndex != -1 && SnapElementPointLine == 0) { MiddleLine.Line.RemovePoints(SnapElementPointIndex, 1); LeftLine.Line.RemovePoints(SnapElementPointIndex, 1); RightLine.Line.RemovePoints(SnapElementPointIndex, 1); MiddleLine.RefreshPoint(SnapElementPointIndex); LeftLine.RefreshPoint(SnapElementPointIndex); RightLine.RefreshPoint(SnapElementPointIndex); SnapElementPointIndex = -1; SnapElementPointLine = int.MaxValue; } #endregion } else { //撤销点 #region 撤销点 IPointCollection tempLine = new Polyline(); if (LeftLine.Line.PointCount > 1) { LeftLine.Line.RemovePoints(LeftLine.Line.PointCount - 1, 1); tempLine.AddPoint(LeftLine.Line.get_Point(LeftLine.Line.PointCount - 1)); } else if (LeftLine.Line.PointCount == 1) { LeftLine.Line.RemovePoints(LeftLine.Line.PointCount - 1, 1); LeftLine.FollowLine.Stop();//.RemovePoints(0, LeftLine.FollowLine.PointCount); //LeftLine.DrawLine(); } if (RightLine.Line.PointCount > 1) { RightLine.Line.RemovePoints(RightLine.Line.PointCount - 1, 1); tempLine.AddPoint(RightLine.Line.get_Point(RightLine.Line.PointCount - 1)); } else if (RightLine.Line.PointCount == 1) { RightLine.Line.RemovePoints(RightLine.Line.PointCount - 1, 1); RightLine.FollowLine.Stop();//.RemovePoints(0, RightLine.FollowLine.PointCount); //RightLine.DrawLine(); } if (MiddleLine.Line.PointCount > 1) { MiddleLine.Line.RemovePoints(MiddleLine.Line.PointCount - 1, 1); IEnvelope extent = m_hookHelper.ActiveView.Extent; IPoint p = MiddleLine.Line.Point[MiddleLine.Line.PointCount - 1]; if (extent.XMax < p.X || extent.XMin > p.X || extent.YMax < p.Y || extent.YMin > p.Y) { (this.m_hookHelper.Hook as IMapControl2).CenterAt(p); } } else if (MiddleLine.Line.PointCount == 1) { MiddleLine.Line.RemovePoints(MiddleLine.Line.PointCount - 1, 1); MiddleLine.FollowLine.Stop();//.RemovePoints(0, MiddleLine.FollowLine.PointCount); //MiddleLine.DrawLine(); PointElement = new List(); this.IsDrawing = false; } //计算前一个点时划线的宽度 //if (tempLine.PointCount == 2) //{ // this.drawParam.Width = (tempLine as IPolyline).Length; //} LeftLine.DrawLine(LeftLine.Line.PointCount); RightLine.DrawLine(LeftLine.Line.PointCount); MiddleLine.DrawLine(LeftLine.Line.PointCount); this.OnMouseMove(1, Shift, MousePoint.X, MousePoint.Y); //Moveing(point); #endregion } } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 F9/ESC(ESCAPE)/DEL(DELETE) 后删除/撤销点 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 F9/ESC(ESCAPE)/DEL(DELETE) 后删除/撤销点 时异常信息结束"); } } else if (keyCode == (int)ConsoleKey.Backspace) { try { #region 清除绘制的图形 this.MiddleLine.Dissvoe(); this.MiddleLine.Init(); this.LeftLine.Dissvoe(); this.LeftLine.Init(); this.RightLine.Dissvoe(); this.RightLine.Init(); PointElement = new List(); this.IsDrawing = false; #endregion } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 BACKSPACE 后清除绘制的图形 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 BACKSPACE 后清除绘制的图形 时异常信息结束"); } } else if (keyCode == (int)ConsoleKey.Spacebar) { try { #region 空格移动地图 if (!IsSpaceDown) { base.Deactivate(); IsSpaceDown = true; } base.m_cursor = System.Windows.Forms.Cursors.Hand; //this.OnMouseMove(1, 0, MousePoint.X, MousePoint.Y); #endregion } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 SPACEBAR 后移动地图 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 SPACEBAR 后移动地图 时异常信息结束"); } } else if (keyCode == (int)ConsoleKey.D9) { try { #region 减小识别灵敏度 if (this.drawParam.ToloranceScale > 0.05) { this.drawParam.ToloranceScale -= 0.05; autoDistinguishTimer.Stop(); autoDistinguishTimer.Start(); } else { this.drawParam.ToloranceScale = 0.05; } #endregion } catch (Exception ex) { LogAPI.Debug("画双线时键盘按下 9 后减小识别灵敏度 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 9 后减小识别灵敏度 时异常信息结束"); } } else if (keyCode == (int)ConsoleKey.D0) { try { #region 增加识别灵敏度 if (this.drawParam.ToloranceScale < 0.5) { this.drawParam.ToloranceScale += 0.05; autoDistinguishTimer.Stop(); autoDistinguishTimer.Start(); } else { this.drawParam.ToloranceScale = 0.5; autoDistinguishTimer.Stop(); autoDistinguishTimer.Start(); } #endregion } catch (Exception ex) { LogAPI.Debug("画双线时键盘按下 0 后增加识别灵敏度 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 0 后增加识别灵敏度 时异常信息结束"); } } else if (keyCode == 17) { try { #region Ctrl键调整双线宽度 if (!IsCtrlDown) { (m_hookHelper.Hook as IMapControlDefault).AutoMouseWheel = false; (m_hookHelper.Hook as IMapControlDefault).AutoKeyboardScrolling = false; DrawTextElement(point, ref TextElement); IsCtrlDown = true; } #endregion } catch (Exception ex) { LogAPI.Debug("画双线时键盘按下 Ctrl键后调整双线宽度 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 Ctrl键后调整双线宽度 时异常信息结束"); } } else if (keyCode == 16) { IsShiftDown = true; } else if (keyCode == (int)ConsoleKey.Enter) { try { #region Enter if (this.MiddleLine.Line.PointCount > 1) { if (IsEnterClickNum == 0) { IsEnterClickNum++; IsDrawing = false; } else if (IsEnterClickNum == 1) { this.DrawComplete(); IsEnterClickNum = 0; SnapElementPointIndex = -1; SnapElementPointLine = 0; } } #endregion } catch (Exception ex) { LogAPI.Debug("画双线时键盘按下 ENTER 键后保存 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 ENTER 键后保存 时异常信息结束"); } } else if (keyCode == (int)ConsoleKey.Insert) { try { //增加点 #region 增加点 if (SnapElementPointIndex == -1) { SnapElementPointIndex = SnapElement(point); double a = GeometryOperations.getAngle(MiddleLine.Line.get_Point(0), MiddleLine.Line.get_Point(1)); if (SnapElementPointIndex != -1) { IPoint p = MiddleLine.Line.get_Point(SnapElementPointIndex); double angle = GeometryOperations.getAngle(p, point); if ((a > 0 && angle > 0) || (a < 0 && angle < 0)) { SnapElementPointIndex++; } else { //if (a < 0 && angle < 0) //{ // SnapElementPointIndex++; //} //if (a > 45 && a < 135) //{ // if (angle > 0) // { // SnapElementPointIndex++; // } //} } IPointCollection newPoint = new Polyline(); newPoint.AddPoint(point); MiddleLine.Line.InsertPointCollection(SnapElementPointIndex, newPoint); LeftLine.Line.InsertPointCollection(SnapElementPointIndex, newPoint); RightLine.Line.InsertPointCollection(SnapElementPointIndex, newPoint); SnapElementPointLine = 0; } } #endregion } catch (Exception ex) { LogAPI.Debug("画双线时键盘按下 INS(INSERT) 键后增加点时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘按下 INS(INSERT) 键后增加点时异常信息结束"); } } } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘操作 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时键盘操作 时异常信息结束"); } } public override void OnKeyUp(int keyCode, int Shift) { Platform.Instance.SetCurrentKeyDown(-1); base.OnKeyUp(keyCode, Shift); if (keyCode == (int)ConsoleKey.Spacebar) { if (IsSpaceDown && IsDrawing) { m_hookHelper.ActiveView.Refresh(); base.OnClick(); IsSpaceDown = false; base.m_cursor = System.Windows.Forms.Cursors.Cross; //this.OnMouseMove(1, 0, MousePoint.X, MousePoint.Y); } } if (keyCode == 17) { if (!IsDrawing) { (m_hookHelper.Hook as IMapControlDefault).AutoMouseWheel = true; (m_hookHelper.Hook as IMapControlDefault).AutoKeyboardScrolling = true; } DelElement(ref TextElement); IsCtrlDown = false; } else if (keyCode == 16) { IsShiftDown = false; } } public override void OnMouseDown(int Button, int Shift, int X, int Y) { try { IsAuto = false; if (IsSpaceDown) { base.Deactivate(); panTool.OnMouseDown(1, Shift, X, Y); return; } if (Button == 1) { //左键按下取点 IPoint point = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y); if (snapEnv != null) { snapEnv.SnapPoint(point); } if (this.MiddleLine.Line.PointCount > 0 && IsDrawing == false) { #region 调整单个点的位置 if (SnapElementPointIndex == -1) { SnapElementPointIndex = SnapElement(point, out SnapElementPointLine); //IsDrawing = true; } else { if (SnapElementPointLine == 0) { this.MiddleLine.Line.UpdatePoint(SnapElementPointIndex, point); double angle = 0; if (SnapElementPointIndex == 0) { angle = GeometryOperations.getAngle(point, this.MiddleLine.Line.get_Point(SnapElementPointIndex + 1)); } else { angle = GeometryOperations.getAngle(this.MiddleLine.Line.get_Point(SnapElementPointIndex - 1), point); } this.LeftLine.Line.UpdatePoint(SnapElementPointIndex, GeometryOperations.GetPoint(point, this.drawParam.Width * 0.5, -angle)); this.RightLine.Line.UpdatePoint(SnapElementPointIndex, GeometryOperations.GetPoint(point, this.drawParam.Width * -0.5, -angle)); this.MiddleLine.RefreshPoint(SnapElementPointIndex); this.LeftLine.RefreshPoint(SnapElementPointIndex); this.RightLine.RefreshPoint(SnapElementPointIndex); } else if (SnapElementPointLine == 1) { this.LeftLine.Line.UpdatePoint(SnapElementPointIndex, point); this.LeftLine.RefreshPoint(SnapElementPointIndex); } else if (SnapElementPointLine == -1) { this.RightLine.Line.UpdatePoint(SnapElementPointIndex, point); this.RightLine.RefreshPoint(SnapElementPointIndex); } SnapElementPointIndex = -1; IsDrawing = false; } #endregion } else { #region 绘制点 #region 根据道路宽度调整相关参数 if (TempWidht < 10) { MinPointDistance = 15; MaxPointDistance = 40; } else if (TempWidht > 15) { MinPointDistance = 30; MaxPointDistance = 80; } #endregion if (this.MiddleLine.Line.PointCount > 0) { IPoint p = this.MiddleLine.Line.get_Point(this.MiddleLine.Line.PointCount - 1); if (p.X == point.X && p.Y == point.Y) { return; } IPolyline line = new PolylineClass(); line.FromPoint = point; line.ToPoint = p; if (line.Length < 3) { return; } } if (TempWidht == -1) { TempWidht = 10; } Drawing(point); if (this.MiddleLine.Line.PointCount > 0) this.IsDrawing = true; else return; if (this.MiddleLine.Line.PointCount > 1) { IPoint p2 = MiddleLine.Line.get_Point(this.MiddleLine.Line.PointCount - 2); IPoint p1 = MiddleLine.Line.get_Point(this.MiddleLine.Line.PointCount - 1); double angle = GeometryOperations.getAngle(p2, p1); //angle = 90 - angle; IPolyline tempLine = new PolylineClass(); tempLine.FromPoint = p1; tempLine.ToPoint = p2; MoveMapExtent(X, Y, (int)Math.Floor(tempLine.Length)); if (this.drawParam.IsAutoTrack) { //this.OnMouseDown(2, Shift, MousePoint.X, MousePoint.Y); } } else { MoveMapExtent(X, Y, 100); } #endregion } } else if (Button == 2) { this.OnKeyDown((int)ConsoleKey.F7, Shift); } else if (Button == 4) { ////鼠标滚轮按下 //base.Deactivate(); //panTool.OnMouseDown(Button, Shift, X, Y); //this.OnKeyDown((int)ConsoleKey.Enter, Shift); } } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线时 鼠标点击后 异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时 鼠标点击后 异常信息结束"); } } private bool isRunning = false; public override void OnMouseMove(int Button, int Shift, int X, int Y) { if (isRunning) return; isRunning = true; try { if (IsSpaceDown) { panTool.OnMouseMove(1, Shift, X, Y); MousePoint.X = X; MousePoint.Y = Y; return; } base.OnMouseMove(Button, Shift, X, Y); IPoint point = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y); if (snapEnv != null) { this.SnapPoint(m_hookHelper.ActiveView, point, snapEnv); } if (this.MiddleLine.Line.PointCount > 0) { if (this.IsDrawing) { Moveing(point); if (MousePoint.X == X && MousePoint.Y == Y) { return; } else { MousePoint.X = X; MousePoint.Y = Y; } autoDistinguishTimer.Stop(); autoDistinguishTimer.Dispose(); try { autoDistinguishTimer.Start(); } catch (Exception ex) { LogAPI.Debug("画双线时 鼠标移动期间 正在绘制时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时 鼠标移动期间 正在绘制时异常信息结束"); //KGIS.Common.Utility.LogAPI.Debug(ex); System.Windows.Forms.Application.DoEvents(); autoDistinguishTimer.Start(); } System.Windows.Forms.Application.DoEvents(); #region 当鼠标移动到地图边界时,自动移动地图 if (AllowMoveMap) { IEnvelope extent = this.m_hookHelper.ActiveView.Extent; int rX = 0; int rY = 0; (m_hookHelper.Hook as IMapControlDefault).FromMapPoint(new PointClass() { X = extent.XMax, Y = extent.YMin }, ref rX, ref rY); bool NeedPan = false; System.Windows.Forms.Application.DoEvents(); if (X < MapBorderDistance) { if (!NeedPan) { timer.Start(); } NeedPan = true; } if (Y < MapBorderDistance) { if (!NeedPan) { timer.Start(); } NeedPan = true; } if (Math.Abs(rX - X) < MapBorderDistance) { if (!NeedPan) { timer.Start(); } NeedPan = true; } if (Math.Abs(rY - Y) < MapBorderDistance) { if (!NeedPan) { timer.Start(); } NeedPan = true; } if (!NeedPan) { timer.Stop(); NeedPan = false; } } #endregion } else { MousePoint.X = X; MousePoint.Y = Y; if (SnapElementPointIndex != -1) { if (SnapElementPointLine == 0) { this.MiddleLine.Line.UpdatePoint(SnapElementPointIndex, point); double angle = 0; if (SnapElementPointIndex == 0) { angle = GeometryOperations.getAngle(point, this.MiddleLine.Line.get_Point(SnapElementPointIndex + 1)); } else { angle = GeometryOperations.getAngle(this.MiddleLine.Line.get_Point(SnapElementPointIndex - 1), point); } this.LeftLine.Line.UpdatePoint(SnapElementPointIndex, GeometryOperations.GetPoint(point, this.drawParam.Width * 0.5, -angle)); this.RightLine.Line.UpdatePoint(SnapElementPointIndex, GeometryOperations.GetPoint(point, this.drawParam.Width * -0.5, -angle)); this.MiddleLine.RefreshPoint(SnapElementPointIndex); this.LeftLine.RefreshPoint(SnapElementPointIndex); this.RightLine.RefreshPoint(SnapElementPointIndex); } else if (SnapElementPointLine == 1) { this.LeftLine.Line.UpdatePoint(SnapElementPointIndex, point); this.LeftLine.RefreshPoint(SnapElementPointIndex); } else if (SnapElementPointLine == -1) { this.RightLine.Line.UpdatePoint(SnapElementPointIndex, point); this.RightLine.RefreshPoint(SnapElementPointIndex); } autoDistinguishTimer.Stop(); autoDistinguishTimer.Dispose(); try { autoDistinguishTimer.Start(); } catch (Exception ex) { LogAPI.Debug("画双线时 鼠标移动期间 未在绘制时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时 鼠标移动期间 未在绘制时异常信息结束"); //KGIS.Common.Utility.LogAPI.Debug(ex); System.Windows.Forms.Application.DoEvents(); autoDistinguishTimer.Start(); } } } } else if (Button == 4) { //鼠标滚轮按下 //panTool.OnMouseMove(Button, Shift, X, Y); //MousePoint.X = X; //MousePoint.Y = Y; } } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线时 鼠标移动时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线时 鼠标移动时异常信息结束"); } finally { isRunning = false; } } public override void OnMouseUp(int Button, int Shift, int X, int Y) { if (Button == 4) { //panTool.OnMouseUp(1, Shift, X, Y); //m_hookHelper.ActiveView.Refresh(); //base.OnClick(); } else { //base.OnMouseUp(button, shift, x, y); //点击右键时,弹出编辑菜单 if (IsSpaceDown) { panTool.OnMouseUp(Button, Shift, X, Y); } else { base.OnMouseUp(Button, Shift, X, Y);//调用基类的OnMouseDown事件 } } } IPolyline StartLine = null; IPolyline EndLine = null; public void DrawComplete() { m_editor.StartOperation(); try { if (LeftLine.Line.PointCount < 2 || this.RightLine.Line.PointCount < 2) { return; } IFeatureLayer layer = m_editor.TargetLayer as IFeatureLayer; if (layer == null) return; IFeatureClass fc = layer.FeatureClass; if (fc == null) return; int selectIdZYQ = 1; IUcZYQMagrHelper ucZYQMagrHelper = null; ProjectInfo ProInfo = MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo; if (ProInfo != null && ProInfo.ProjType == EnumProjType.BHTBTQ && Platform.Instance.SystemType == SystemTypeEnum.BGFWCG) { ucZYQMagrHelper = BundleRuntime.Instance.GetFirstOrDefaultService(); if (ucZYQMagrHelper != null) { selectIdZYQ = ucZYQMagrHelper.GetCheckedID(); } } ////验证区域授权 //if (!base.ValidateAuthorize(LeftLine.Line as IGeometry) || !base.ValidateAuthorize(RightLine.Line as IGeometry)) //{ // MessageHelper.ShowError("绘制图形不在授权区域范围内!"); // DelElement(ref element); // PointElement = new List(); // this.LeftLine.Dissvoe(); // this.RightLine.Dissvoe(); // this.MiddleLine.Dissvoe(); // this.MiddleLine.Init(); // this.RightLine.Init(); // this.LeftLine.Init(); // this.m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewBackground, null, m_hookHelper.ActiveView.Extent); // this.m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, m_hookHelper.ActiveView.Extent); // this.TempWidht = -1; // this.TempCenterPoint = null; // this.IsChangedWidth = false; // this.IsDrawing = false; // base.OnDblClick(); // return; //} IFeatureSelection featureSelection = layer as IFeatureSelection; featureSelection.Clear(); IFeature feature = fc.CreateFeature(); feature.Shape = LeftLine.Line as IGeometry; feature.Store(); //BUG12981 //------------- //featureSelection.Add(feature); m_hookHelper.ActiveView.FocusMap.SelectFeature(layer, feature); //------------- feature = fc.CreateFeature(); feature.Shape = RightLine.Line as IGeometry; feature.Store(); //BUG12981 //------------- //featureSelection.Add(feature); m_hookHelper.ActiveView.FocusMap.SelectFeature(layer, feature); //------------- if (drawParam.IsAutoClose) { //自动封闭两端 IPointCollection line = new Polyline(); line.AddPoint((LeftLine.Line as IPolyline).FromPoint); line.AddPoint((RightLine.Line as IPolyline).FromPoint); feature = fc.CreateFeature(); feature.Shape = line as IGeometry; feature.Store(); //BUG12981 //------------- //featureSelection.Add(feature); m_hookHelper.ActiveView.FocusMap.SelectFeature(layer, feature); //------------- line = new Polyline(); line.AddPoint((LeftLine.Line as IPolyline).ToPoint); line.AddPoint((RightLine.Line as IPolyline).ToPoint); feature = fc.CreateFeature(); feature.Shape = line as IGeometry; feature.Store(); //BUG12981 //------------- //featureSelection.Add(feature); m_hookHelper.ActiveView.FocusMap.SelectFeature(layer, feature); //------------- } m_editor.StopOperation("画线物边界线"); DelElement(ref element); PointElement = new List(); this.LeftLine.Dissvoe(); this.RightLine.Dissvoe(); this.MiddleLine.Dissvoe(); this.MiddleLine.Init(); this.RightLine.Init(); this.LeftLine.Init(); this.m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewBackground, null, m_hookHelper.ActiveView.Extent); this.m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, m_hookHelper.ActiveView.Extent); this.TempWidht = -1; this.TempCenterPoint = null; this.IsChangedWidth = false; this.IsDrawing = false; base.OnDblClick(); if (ucZYQMagrHelper != null) { ucZYQMagrHelper.AddMask(selectIdZYQ); } } catch (Exception ex) { LogAPI.Debug("双线绘画完毕(执行函数DrawComplete)时 异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("双线绘画完毕(执行函数DrawComplete)时 异常信息结束"); m_editor.AbortOperation(); MessageHelper.ShowError(ex.Message); //LogAPI.Debug(ex); } } public override bool Deactivate() { if (paramFrm != null) { paramFrm.Close(); paramFrm = null; } this.MiddleLine.Dissvoe(); this.LeftLine.Dissvoe(); this.RightLine.Dissvoe(); this.MiddleLine = new LineModel(m_hookHelper.ActiveView, esriSimpleLineStyle.esriSLSDash, 0.5); this.LeftLine = new LineModel(m_hookHelper.ActiveView, esriSimpleLineStyle.esriSLSSolid); this.RightLine = new LineModel(m_hookHelper.ActiveView, esriSimpleLineStyle.esriSLSSolid); _MapService.MapContainerMouseWheel -= Platfrom_MapMouseWheel; timer.Tick -= timer_Tick; timer.Stop(); autoDistinguishTimer.Tick -= autoDistinguishTimer_Tick; autoDistinguishTimer.Stop(); PointElement = new List(); this.IsDrawing = false; IsDeactivate = true; return base.Deactivate(); } private void LeftClick(int X, int Y) { //左键按下取点 IPoint point = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y); if (this.MiddleLine.Line.PointCount > 0 && IsDrawing == false) { #region 调整单个点的位置 if (SnapElementPointIndex == -1) { SnapElementPointIndex = SnapElement(point, out SnapElementPointLine); //IsDrawing = true; } else { if (SnapElementPointLine == 0) { this.MiddleLine.Line.UpdatePoint(SnapElementPointIndex, point); double angle = 0; if (SnapElementPointIndex == 0) { angle = GeometryOperations.getAngle(point, this.MiddleLine.Line.get_Point(SnapElementPointIndex + 1)); } else { angle = GeometryOperations.getAngle(this.MiddleLine.Line.get_Point(SnapElementPointIndex - 1), point); } this.LeftLine.Line.UpdatePoint(SnapElementPointIndex, GeometryOperations.GetPoint(point, this.drawParam.Width * 0.5, -angle)); this.RightLine.Line.UpdatePoint(SnapElementPointIndex, GeometryOperations.GetPoint(point, this.drawParam.Width * -0.5, -angle)); this.MiddleLine.RefreshPoint(SnapElementPointIndex); this.LeftLine.RefreshPoint(SnapElementPointIndex); this.RightLine.RefreshPoint(SnapElementPointIndex); } else if (SnapElementPointLine == 1) { this.LeftLine.Line.UpdatePoint(SnapElementPointIndex, point); this.LeftLine.RefreshPoint(SnapElementPointIndex); } else if (SnapElementPointLine == -1) { this.RightLine.Line.UpdatePoint(SnapElementPointIndex, point); this.RightLine.RefreshPoint(SnapElementPointIndex); } SnapElementPointIndex = -1; IsDrawing = false; } #endregion } else { #region 绘制点 #region 根据道路宽度调整相关参数 if (TempWidht < 10) { MinPointDistance = 15; MaxPointDistance = 40; } else if (TempWidht > 15) { MinPointDistance = 30; MaxPointDistance = 80; } #endregion if (this.MiddleLine.Line.PointCount > 0) { IPoint p = this.MiddleLine.Line.get_Point(this.MiddleLine.Line.PointCount - 1); if (p.X == point.X && p.Y == point.Y) { return; } IPolyline line = new PolylineClass(); line.FromPoint = point; line.ToPoint = p; if (line.Length < 3) { return; } } if (TempWidht == -1) { TempWidht = 10; } Drawing(point); if (this.MiddleLine.Line.PointCount > 0) this.IsDrawing = true; if (this.MiddleLine.Line.PointCount > 1) { IPoint p2 = MiddleLine.Line.get_Point(this.MiddleLine.Line.PointCount - 2); IPoint p1 = MiddleLine.Line.get_Point(this.MiddleLine.Line.PointCount - 1); double angle = GeometryOperations.getAngle(p2, p1); //angle = 90 - angle; IPolyline tempLine = new PolylineClass(); tempLine.FromPoint = p1; tempLine.ToPoint = p2; MoveMapExtent(X, Y, (int)Math.Floor(tempLine.Length)); if (this.drawParam.IsAutoTrack) { //this.OnMouseDown(2, Shift, MousePoint.X, MousePoint.Y); } } else { MoveMapExtent(X, Y, 100); } #endregion } } #endregion /// /// 获取两条线段交点 /// /// /// /// /// private IPoint GetIntersectPoint(IPoint pointStart, IPoint pointEnd, IGeometry targetGeo) { IPolyline newLine = new PolylineClass(); IPointCollection newLinepoint = newLine as IPointCollection; if (pointStart.X == pointEnd.X) { double minY = targetGeo.Envelope.YMin; newLinepoint.AddPoint(pointStart); newLinepoint.AddPoint(new PointClass() { X = pointEnd.X, Y = minY }); } else { double pointX = pointEnd.X > pointStart.X ? targetGeo.Envelope.XMax : targetGeo.Envelope.XMin; double sourceLineK = (pointStart.Y - pointEnd.Y) / (pointStart.X - pointEnd.X); double longPointY = pointStart.Y - ((pointStart.X - pointX) * sourceLineK); newLinepoint.AddPoint(pointStart); newLinepoint.AddPoint(new PointClass() { X = pointX, Y = longPointY }); } ITopologicalOperator topOper = targetGeo as ITopologicalOperator; IGeometry geometry = topOper.Intersect(newLine as IGeometry, esriGeometryDimension.esriGeometry0Dimension); return GetMinDisPoint(geometry, pointEnd); } private IPoint GetMinDisPoint(IGeometry geometry, IPoint pointEnd) { if (!geometry.IsEmpty) { IProximityOperator operatorPr = geometry as IProximityOperator; return operatorPr.ReturnNearestPoint(pointEnd, esriSegmentExtension.esriExtendTangents); } return null; } /// /// 滚动滚轮调整宽度 /// /// /// void Platfrom_MapMouseWheel(object sender, System.Windows.Forms.MouseEventArgs e) { if (IsDeactivate) return; if (drawParam != null) { if (Platform.Instance.GetCurrentKeyDown() == 17) { IPoint point = this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(MousePoint.X, MousePoint.Y); if (e.Delta > 0) { drawParam.Width = drawParam.Width + 0.5; } else if (e.Delta < 0 && drawParam.Width > 0) { drawParam.Width = drawParam.Width - 0.5; } int d = (int)Math.Abs(drawParam.Width); if (d == 0) return; if (d < 10) { drawParam.ToloranceScale = 0.1; } if (d == 10) { drawParam.ToloranceScale = 0.15; } if (d > 10 && d < 20) { drawParam.ToloranceScale = 0.2; } if (d == 20) { drawParam.ToloranceScale = 0.25; } if (d > 20) { drawParam.ToloranceScale = 0.3; } if (d > 30) { drawParam.ToloranceScale = 0.4; } if (d > 40) { drawParam.ToloranceScale = 0.5; } this.IsChangedWidth = true; DrawTextElement(point, ref TextElement); //this.OnMouseMove(1, 0, MousePoint.X, MousePoint.Y); //宽度调整标识设置为true并传入Moveing()方法 Moveing(point, IsChangedWidth); } else { //shift+滚轮调节识别度 //if (IsDrawing) if (IsShiftDown) { if (e.Delta > 0) { //drawParam.ToloranceScale += 0.05; this.OnKeyDown((int)ConsoleKey.D0, 0); } if (e.Delta < 0) { //drawParam.ToloranceScale -= 0.05; this.OnKeyDown((int)ConsoleKey.D9, 0); } this.OnKeyDown((int)ConsoleKey.P, 0); } else { //添加滚轮放大缩小地图 (m_hookHelper.Hook as IMapControlDefault).AutoMouseWheel = true; (m_hookHelper.Hook as IMapControlDefault).AutoKeyboardScrolling = true; //---------------- } } } } /// /// 移动地图范围 /// /// 鼠标位置的X坐标 /// 鼠标位置的Y坐标 /// 鼠标位置距离地图边界的宽度 private void MoveMapExtent(int X, int Y, int pWidth) { //鼠标点击的点 IPoint point = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y); #region 当鼠标点击屏幕边界时移动地图范围 //当前屏幕中心点坐标 IPoint centerPoint = new PointClass() { X = (this.m_hookHelper.ActiveView.Extent.XMax - this.m_hookHelper.ActiveView.Extent.Width / 2), Y = (this.m_hookHelper.ActiveView.Extent.YMax - this.m_hookHelper.ActiveView.Extent.Height / 2) }; //地图窗口右下角坐标 IPoint p = new PointClass() { X = this.m_hookHelper.ActiveView.Extent.XMax, Y = this.m_hookHelper.ActiveView.Extent.YMin }; //鼠标点击到边界时移动地图 int x2 = 0; int y2 = 0; //获取地图工作区右下角的坐标x2,y2,用于判断当前鼠标点是否在右边/下边边界处 this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(p, out x2, out y2); //获取工作区右下角的坐标对应的屏幕坐标//m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint; System.Drawing.Point rightBottomPoint = _MapService.PointToScreen(new System.Drawing.Point(x2, y2)); //获取工作区左上角的坐标对应的屏幕坐标 System.Drawing.Point leftTopPoint = _MapService.PointToScreen(new System.Drawing.Point(0, 0)); IPoint CPoint = point; double angle = 0; if (MiddleLine.Line.PointCount > 1) { //计算当前道路线的方向 angle = GeometryOperations.getAngle(MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 2), MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1)); } //计算屏幕每像素代表实际横向距离 double d1 = this.m_hookHelper.ActiveView.Extent.Width / x2; //计算屏幕每像素代表实际纵向距离 double d2 = this.m_hookHelper.ActiveView.Extent.Height / y2; IPoint p1 = MiddleLine.Line.get_Point(this.MiddleLine.Line.PointCount - 1); //自动识别的下一个点的位置 IPoint n_p = GeometryOperations.GetPoint(p1, pWidth, 90 - angle); //第一次识别的点 IPoint n_p2 = null; //第二次识别的点 IPoint n_p3 = null; //记录自动识别下一点的宽度 IPolyline line = null; //第一次识别的宽度 IPolyline line2 = null; //第二次识别的宽度 IPolyline line3 = null; IPolyline tempLine = new PolylineClass(); if (this.MiddleLine.Line.PointCount > 1) { double d = 0; if (this.MiddleLine.Line.PointCount > 0) { tempLine.FromPoint = this.LeftLine.Line.get_Point(this.LeftLine.Line.PointCount - 1); tempLine.ToPoint = this.RightLine.Line.get_Point(this.RightLine.Line.PointCount - 1); d = tempLine.Length; } n_p2 = GeometryOperations.GetPoint(p1, pWidth, 90 - angle); line2 = (IPolyline)AutoDistinguish3(0, n_p2); if (Math.Abs(line2.Length - d) > 4) { n_p3 = GeometryOperations.GetPoint(p1, pWidth + pWidth * 0.1, 90 - angle); line3 = (IPolyline)AutoDistinguish3(0, n_p3); if (Math.Abs(line2.Length - d) < Math.Abs(line3.Length - d)) { n_p = n_p2; line = line2; } else { n_p = n_p3; line = line3; } } else { n_p = n_p2; line = line2; } #region 将自动识别的点显示在地图上 if (this.drawParam.IsAutoStep) { TempCenterPoint = new PointClass(); TempCenterPoint.X = line.FromPoint.X - (line.FromPoint.X - line.ToPoint.X) / 2; TempCenterPoint.Y = line.FromPoint.Y - (line.FromPoint.Y - line.ToPoint.Y) / 2; TempCenterPoint.SpatialReference = (line as IPolyline).SpatialReference; IPointCollection newPoints = new Polyline(); newPoints.AddPoint(line.FromPoint); newPoints.AddPoint(TempCenterPoint); newPoints.AddPoint(line.ToPoint); DrawPoint(newPoints); } #endregion } //计算下一个点的坐标对应的地图工作区坐标位置 int nextX = 0; int nextY = 0; this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(n_p, out nextX, out nextY); if (nextX - 50 < 0 || nextX + 50 > x2) { #region 横向移动 double moveWidth = 0; if (nextX - 50 < 0) { moveWidth = Math.Abs(nextX - 50) * d1; } else if (nextX + 50 > x2) { moveWidth = (nextX + 50 - x2) * d1; } if (moveWidth < this.m_hookHelper.ActiveView.Extent.Width / 2) { moveWidth = this.m_hookHelper.ActiveView.Extent.Width * 0.5; } if (angle != 0) { CPoint = GeometryOperations.GetPoint(centerPoint, moveWidth, 90 - angle); (this.m_hookHelper.Hook as IMapControl2).CenterAt(CPoint); } else { (this.m_hookHelper.Hook as IMapControl2).CenterAt(CPoint); this.OnMouseMove(1, 0, MousePoint.X + 1, MousePoint.Y + 1); } #endregion } if (nextY < 50 || nextY + 50 > y2) { #region 纵向移动 double moveWidth = 0; if (nextY + 50 < 0) { moveWidth = Math.Abs(nextY - 50) * d2; if (moveWidth < this.m_hookHelper.ActiveView.Extent.Height / 2) { moveWidth = this.m_hookHelper.ActiveView.Extent.Height * 0.5; } } else if (nextY + 50 > y2) { moveWidth = (nextY + 50 - y2) * d2; if (moveWidth < this.m_hookHelper.ActiveView.Extent.Height / 2) { moveWidth = this.m_hookHelper.ActiveView.Extent.Height * 0.5; } } if (angle != 0) { CPoint = GeometryOperations.GetPoint(centerPoint, moveWidth, 90 - angle); (this.m_hookHelper.Hook as IMapControl2).CenterAt(CPoint); } else { (this.m_hookHelper.Hook as IMapControl2).CenterAt(CPoint); this.OnMouseMove(1, 0, MousePoint.X + 1, MousePoint.Y + 1); } #endregion } if (n_p != null) { int m_x = 0; int m_y = 0; this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(n_p, out m_x, out m_y); System.Drawing.Point screenPoint = _MapService.PointToScreen(new System.Drawing.Point(m_x, m_y)); this.MousePoint.X = m_x; this.MousePoint.Y = m_y; //this.m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography,null, if (this.drawParam.IsAutoStep) { SetCursorPos(screenPoint.X, screenPoint.Y); } if (this.drawParam.IsAutoTrack && IsAuto && this.drawParam.IsAutoStep) { this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(TempCenterPoint, out nextX, out nextY); this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(p1, out nextX, out nextY); double angle2 = GeometryOperations.getAngle(MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1), TempCenterPoint); ITopologicalOperator topo = TempCenterPoint as ITopologicalOperator; IGeometry geo = topo.Buffer(line.Length / 2); ImgDistinguish imgDis = new ImgDistinguish(); TilesImage img = imgDis.GetImg(geo.Envelope); img.PixelCount = 9; int gray1 = img.GetGrayValue(TempCenterPoint); topo = MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1) as ITopologicalOperator; geo = topo.Buffer(line.Length / 2); img = imgDis.GetImg(geo.Envelope); img.PixelCount = 9; int gray2 = img.GetGrayValue(MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1)); int w = pWidth / 3; if (Math.Abs(Math.Abs(angle) - Math.Abs(angle2)) < 10) { if (Math.Abs(gray1 - gray2) < 25 && Math.Abs(line.Length - tempLine.Length) < tempLine.Length * 0.3) { IsAutoTrackPoint = true; this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(TempCenterPoint, out nextX, out nextY); this.OnMouseDown(2, 0, nextX, nextY); } else { int i = 0; while (pWidth - w >= 3) { i++; w = w + pWidth / 3; if (i > 3) { IsAutoTrackPoint = false; break; } IPoint c_P = AutoTrack(X, Y, pWidth - w); if (c_P != null) { TempCenterPoint = c_P; IsAutoTrackPoint = true; this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(TempCenterPoint, out nextX, out nextY); this.OnMouseDown(2, 0, nextX, nextY); break; } else { IsAutoTrackPoint = false; } } } } else { if (Math.Abs(gray1 - gray2) < 30 && Math.Abs(line.Length - tempLine.Length) < tempLine.Length * 0.3) { IsAutoTrackPoint = true; this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(TempCenterPoint, out nextX, out nextY); this.OnMouseDown(2, 0, nextX, nextY); } else { int i = 0; while (pWidth - w >= 3) { i++; w = w + pWidth / 3; if (i > 3) { IsAutoTrackPoint = false; break; } IPoint c_P = AutoTrack(X, Y, pWidth - w); if (c_P != null) { TempCenterPoint = c_P; IsAutoTrackPoint = true; this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(TempCenterPoint, out nextX, out nextY); this.OnMouseDown(2, 0, nextX, nextY); break; } else { IsAutoTrackPoint = false; } } //if (pWidth / 3 >= 3) //{ // MoveMapExtent(X, Y, pWidth / 3); //} //else //{ // IsAutoTrackPoint = false; //} } } } } #endregion } private IPoint AutoTrack(int X, int Y, int pWidth) { IPoint result = null; try { //鼠标点击的点 IPoint point = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y); #region 当鼠标点击屏幕边界时移动地图范围 //当前屏幕中心点坐标 IPoint centerPoint = new PointClass() { X = (this.m_hookHelper.ActiveView.Extent.XMax - this.m_hookHelper.ActiveView.Extent.Width / 2), Y = (this.m_hookHelper.ActiveView.Extent.YMax - this.m_hookHelper.ActiveView.Extent.Height / 2) }; //地图窗口右下角坐标 IPoint p = new PointClass() { X = this.m_hookHelper.ActiveView.Extent.XMax, Y = this.m_hookHelper.ActiveView.Extent.YMin }; //鼠标点击到边界时移动地图 int x2 = 0; int y2 = 0; //获取地图工作区右下角的坐标x2,y2,用于判断当前鼠标点是否在右边/下边边界处 this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(p, out x2, out y2); //获取工作区右下角的坐标对应的屏幕坐标 System.Drawing.Point rightBottomPoint = _MapService.PointToScreen(new System.Drawing.Point(x2, y2)); //获取工作区左上角的坐标对应的屏幕坐标 System.Drawing.Point leftTopPoint = _MapService.PointToScreen(new System.Drawing.Point(0, 0)); IPoint CPoint = point; double angle = 0; if (MiddleLine.Line.PointCount > 1) { //计算当前道路线的方向 angle = GeometryOperations.getAngle(MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 2), MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1)); } //计算屏幕每像素代表实际横向距离 double d1 = this.m_hookHelper.ActiveView.Extent.Width / x2; //计算屏幕每像素代表实际纵向距离 double d2 = this.m_hookHelper.ActiveView.Extent.Height / y2; IPoint p1 = MiddleLine.Line.get_Point(this.MiddleLine.Line.PointCount - 1); //自动识别的下一个点的位置 IPoint n_p = null; //第一次识别的点 IPoint n_p2 = null; //第二次识别的点 IPoint n_p3 = null; //记录自动识别下一点的宽度 IPolyline line = null; //第一次识别的宽度 IPolyline line2 = null; //第二次识别的宽度 IPolyline line3 = null; IPolyline tempLine = new PolylineClass(); if (this.MiddleLine.Line.PointCount > 1) { double d = 0; if (this.MiddleLine.Line.PointCount > 0) { tempLine.FromPoint = this.LeftLine.Line.get_Point(this.LeftLine.Line.PointCount - 1); tempLine.ToPoint = this.RightLine.Line.get_Point(this.RightLine.Line.PointCount - 1); d = tempLine.Length; } n_p2 = GeometryOperations.GetPoint(p1, pWidth, 90 - angle); line2 = (IPolyline)AutoDistinguish3(0, n_p2); if (Math.Abs(line2.Length - d) > 4) { n_p3 = GeometryOperations.GetPoint(p1, pWidth + pWidth * 0.1, 90 - angle); line3 = (IPolyline)AutoDistinguish3(0, n_p3); if (Math.Abs(line2.Length - d) < Math.Abs(line3.Length - d)) { n_p = n_p2; line = line2; } else { n_p = n_p3; line = line3; } } else { n_p = n_p2; line = line2; } #region 将自动识别的点显示在地图上 TempCenterPoint = new PointClass(); TempCenterPoint.X = line.FromPoint.X - (line.FromPoint.X - line.ToPoint.X) / 2; TempCenterPoint.Y = line.FromPoint.Y - (line.FromPoint.Y - line.ToPoint.Y) / 2; TempCenterPoint.SpatialReference = (line as IPolyline).SpatialReference; IPointCollection newPoints = new Polyline(); newPoints.AddPoint(line.FromPoint); newPoints.AddPoint(TempCenterPoint); newPoints.AddPoint(line.ToPoint); DrawPoint(newPoints); #endregion } //计算下一个点的坐标对应的地图工作区坐标位置 int nextX = 0; int nextY = 0; #region //this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(n_p, out nextX, out nextY); //if (nextX - 50 < 0 || nextX + 50 > x2) //{ // #region 横向移动 // double moveWidth = 0; // if (nextX - 50 < 0) // { // moveWidth = Math.Abs(nextX - 50) * d1; // } // else if (nextX + 50 > x2) // { // moveWidth = (nextX + 50 - x2) * d1; // } // if (angle != 0) // { // CPoint = GeometryOperations.GetPoint(centerPoint, moveWidth, 90 - angle); // (this.m_hookHelper.Hook as IMapControl2).CenterAt(CPoint); // } // else // { // (this.m_hookHelper.Hook as IMapControl2).CenterAt(CPoint); // this.OnMouseMove(1, 0, MousePoint.X + 1, MousePoint.Y + 1); // } // #endregion //} //if (nextY + 50 < 0 || nextY + 50 > y2) //{ // #region 纵向移动 // double moveWidth = 0; // if (nextY + 50 < 0) // { // moveWidth = Math.Abs(nextY - 50) * d2; // } // else if (nextY + 50 > y2) // { // moveWidth = -(nextY + 50 - x2) * d2; // } // if (angle != 0) // { // CPoint = GeometryOperations.GetPoint(centerPoint, moveWidth, 90 - angle); // (this.m_hookHelper.Hook as IMapControl2).CenterAt(CPoint); // } // else // { // (this.m_hookHelper.Hook as IMapControl2).CenterAt(CPoint); // this.OnMouseMove(1, 0, MousePoint.X + 1, MousePoint.Y + 1); // } // #endregion //} #endregion if (n_p != null) { this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(TempCenterPoint, out nextX, out nextY); int m_x = 0; int m_y = 0; this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(n_p, out m_x, out m_y); System.Drawing.Point screenPoint = _MapService.PointToScreen(new System.Drawing.Point(m_x, m_y)); this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(p1, out nextX, out nextY); this.MousePoint.X = m_x; this.MousePoint.Y = m_y; SetCursorPos(screenPoint.X, screenPoint.Y); if (this.drawParam.IsAutoTrack) { double angle2 = GeometryOperations.getAngle(MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1), TempCenterPoint); ITopologicalOperator topo = TempCenterPoint as ITopologicalOperator; IGeometry geo = topo.Buffer(line.Length / 2); ImgDistinguish imgDis = new ImgDistinguish(); TilesImage img = imgDis.GetImg(geo.Envelope); img.PixelCount = 9; int gray1 = img.GetGrayValue(TempCenterPoint); topo = MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1) as ITopologicalOperator; geo = topo.Buffer(line.Length / 2); img = imgDis.GetImg(geo.Envelope); img.PixelCount = 9; int gray2 = img.GetGrayValue(MiddleLine.Line.get_Point(MiddleLine.Line.PointCount - 1)); if (Math.Abs(Math.Abs(angle) - Math.Abs(angle2)) < 5 && Math.Abs(gray1 - gray2) < 25 && Math.Abs(line.Length - tempLine.Length) < tempLine.Length * 0.3) { //IsAutoTrackPoint = true; //this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(TempCenterPoint, out nextX, out nextY); //this.OnMouseDown(2, 0, nextX, nextY); result = TempCenterPoint; } else { //IsAutoTrackPoint = false; } } } return result; #endregion } catch (Exception ex) { LogAPI.Debug("画双线 自动追踪轨迹 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线 自动追踪轨迹 时异常信息结束"); throw ex; } } /// /// 定时进行自动识别影像 /// /// /// void autoDistinguishTimer_Tick(object sender, EventArgs e) { try { IPoint point = this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(MousePoint.X, MousePoint.Y); double angle = 0; if (MiddleLine.Line.PointCount <= 0) { return; #region //IPolyline p1 = (IPolyline)AutoDistinguish(0); //IPolyline p2 = (IPolyline)AutoDistinguish(90); //if (p1.Length > p2.Length) //{ // TempWidht = p2.Length; // #region 将自动识别记过显示在地图上 // TempCenterPoint = new PointClass(); // TempCenterPoint.X = p2.FromPoint.X - (p2.FromPoint.X - p2.ToPoint.X) / 2; // TempCenterPoint.Y = p2.FromPoint.Y - (p2.FromPoint.Y - p2.ToPoint.Y) / 2; // TempCenterPoint.SpatialReference = (p2 as IPolyline).SpatialReference; // IPointCollection newPoints = new Polyline(); // newPoints.AddPoint(p2.FromPoint); // newPoints.AddPoint(TempCenterPoint); // newPoints.AddPoint(p2.ToPoint); // DrawPoint(newPoints); // #endregion //} //else //{ // TempWidht = p1.Length; // #region 将自动识别记过显示在地图上 // TempCenterPoint = new PointClass(); // TempCenterPoint.X = p1.FromPoint.X - (p1.FromPoint.X - p1.ToPoint.X) / 2; // TempCenterPoint.Y = p1.FromPoint.Y - (p1.FromPoint.Y - p1.ToPoint.Y) / 2; // TempCenterPoint.SpatialReference = (p1 as IPolyline).SpatialReference; // IPointCollection newPoints = new Polyline(); // newPoints.AddPoint(p1.FromPoint); // newPoints.AddPoint(TempCenterPoint); // newPoints.AddPoint(p1.ToPoint); // DrawPoint(newPoints); // #endregion //} #endregion } else { //LogAPI.Debug("开始时间:" + DateTime.Now.Subtract(); angle = GeometryOperations.getAngle(MiddleLine.Line.Point[MiddleLine.Line.PointCount - 1], point); if (double.IsNaN(angle) && (MiddleLine.Line.PointCount - 2) > -1) { angle = GeometryOperations.getAngle(MiddleLine.Line.Point[MiddleLine.Line.PointCount - 2], point); } if (!Double.IsNaN(angle)) { //DateTime t1 = DateTime.Now; //Int32 d = t1.Minute * 60 * 1000 + t1.Second * 1000 + t1.Millisecond; //LogAPI.Debug("开始时间:" + (t1.Minute * 60 * 1000 + t1.Second * 1000 + t1.Millisecond)); IPolyline polyline = (IPolyline)AutoDistinguish(angle); this.drawParam.ToloranceScale += 0.05; IPolyline polyline1 = (IPolyline)AutoDistinguish(angle); this.drawParam.ToloranceScale -= 0.1; IPolyline polyline2 = (IPolyline)AutoDistinguish(angle); this.drawParam.ToloranceScale += 0.05; double d = this.drawParam.Width; //if (this.MiddleLine.Line.PointCount > 0) if (this.LeftLine.Line.PointCount > 0 && this.RightLine.Line.PointCount > 0) { IPolyline tempLine = new PolylineClass(); tempLine.FromPoint = this.LeftLine.Line.get_Point(this.LeftLine.Line.PointCount - 1); tempLine.ToPoint = this.RightLine.Line.get_Point(this.RightLine.Line.PointCount - 1); d = tempLine.Length; } if (Math.Abs(polyline.Length - d) < Math.Abs(polyline1.Length - d)) { if (Math.Abs(polyline.Length - d) > Math.Abs(polyline2.Length - d)) { polyline = polyline2; } } else { if (Math.Abs(polyline1.Length - d) > Math.Abs(polyline2.Length - d)) { polyline = polyline2; } else { polyline = polyline1; } } TempWidht = polyline.Length; if ((TempWidht > this.drawParam.Width + this.drawParam.Width * 0.5 || TempWidht < this.drawParam.Width - this.drawParam.Width * 0.5) && this.MiddleLine.Line.PointCount > 1) { TempWidht = -1; TempCenterPoint = null; try { if (PointElement.Count > 0) { foreach (IElement item in PointElement) { m_hookHelper.ActiveView.GraphicsContainer.DeleteElement(item); } PointElement = new List(); m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, m_hookHelper.ActiveView.Extent); } } catch (Exception ex) { //KGIS.Common.Utility.LogAPI.Debug(ex); LogAPI.Debug("画双线期间 定时进行自动识别影像 过程中 图形容器中删除属性后刷新点属性时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 定时进行自动识别影像 过程中 图形容器中删除属性后刷新点属性时异常信息结束"); } } else { #region 将自动识别的点显示在地图上 TempCenterPoint = new PointClass(); TempCenterPoint.X = polyline.FromPoint.X - (polyline.FromPoint.X - polyline.ToPoint.X) / 2; TempCenterPoint.Y = polyline.FromPoint.Y - (polyline.FromPoint.Y - polyline.ToPoint.Y) / 2; TempCenterPoint.SpatialReference = (polyline as IPolyline).SpatialReference; IPointCollection newPoints = new Polyline(); newPoints.AddPoint(polyline.FromPoint); newPoints.AddPoint(TempCenterPoint); newPoints.AddPoint(polyline.ToPoint); DrawPoint(newPoints); #endregion } //DateTime t2 = DateTime.Now; //Int32 d2 = t2.Minute * 60 * 1000 + t2.Second * 1000 + t2.Millisecond; //LogAPI.Debug("识别结束:" + (t2.Minute * 60 * 1000 + t2.Second * 1000 + t2.Millisecond)); //LogAPI.Debug("识别结束:" + (d2 - d) + "毫秒"); } } autoDistinguishTimer.Stop(); } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线期间 定时进行自动识别影像 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 定时进行自动识别影像 时异常信息结束"); } } #region 捕捉 private List Snapping(IPoint pPoint, List pLayers) { List result = new List(); try { if (pPoint != null && pLayers != null) { foreach (IFeatureLayer item in pLayers) { IIdentify identify = item as IIdentify; if (identify == null) continue; ESRI.ArcGIS.esriSystem.IArray array = identify.Identify(pPoint); if (array == null) continue; for (int i = 0; i < array.Count; i++) { IRowIdentifyObject row = (IRowIdentifyObject)array.get_Element(i); if (row == null) continue; IFeature f = row.Row as IFeature; result.Add(f); } } } } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线期间 图层中捕捉点 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 图层中捕捉点 时异常信息结束"); } return result; } #endregion #region 获取所有可见图层 /// /// 获取当前地图中可见的矢量图层 /// /// /// private List GetVisibleLayer(IMap pMap, esriGeometryType geoType = esriGeometryType.esriGeometryAny) { List result = new List(); if (pMap == null) return result; try { for (int i = 0; i < pMap.LayerCount; i++) { ILayer layer = pMap.get_Layer(i); if (layer is IFeatureLayer) { if ((layer as IFeatureLayer).Visible && (layer as IFeatureLayer).FeatureClass.ShapeType == geoType) { result.Add(layer as IFeatureLayer); } } else if (layer is ICompositeLayer) { if ((layer as IGroupLayer).Visible) { result.AddRange(GetVisibleLayerByGroupLayer(layer as ICompositeLayer, geoType)); } } } } catch (Exception ex) { //Common.Utility.LogAPI.Debug(ex); LogAPI.Debug("画双线期间 获取当前地图中可见的矢量图层 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 获取当前地图中可见的矢量图层 时异常信息结束"); } return result; } private List GetVisibleLayerByGroupLayer(ICompositeLayer pGroupLayer, esriGeometryType geoType = esriGeometryType.esriGeometryAny) { List result = new List(); if (pGroupLayer != null && pGroupLayer.Count > 0) { for (int i = 0; i < pGroupLayer.Count; i++) { ILayer layer = pGroupLayer.get_Layer(i); if (layer is IAnnotationLayer) { } else if (layer is IGroupLayer) { if ((layer as IGroupLayer).Visible) { result.AddRange(GetVisibleLayerByGroupLayer(layer as ICompositeLayer, geoType)); } } else { if (layer is IFeatureLayer) { if ((layer as IFeatureLayer).Visible && (layer as IFeatureLayer).FeatureClass.ShapeType == geoType) { result.Add((IFeatureLayer)layer); } } } } } return result; } #endregion #region 绘制相关私有函数 private IPointCollection AutoDistinguish3(double angle = 0, IPoint pPoint = null) { IPolyline polyline = (IPolyline)AutoDistinguish(angle, pPoint); this.drawParam.ToloranceScale += 0.05; IPolyline polyline1 = (IPolyline)AutoDistinguish(angle, pPoint); this.drawParam.ToloranceScale -= 0.1; IPolyline polyline2 = (IPolyline)AutoDistinguish(angle, pPoint); this.drawParam.ToloranceScale += 0.05; double d = this.drawParam.Width; if (this.MiddleLine.Line.PointCount > 0) { IPolyline tempLine = new PolylineClass(); tempLine.FromPoint = this.LeftLine.Line.get_Point(this.LeftLine.Line.PointCount - 1); tempLine.ToPoint = this.RightLine.Line.get_Point(this.RightLine.Line.PointCount - 1); d = tempLine.Length; } if (Math.Abs(polyline.Length - d) < Math.Abs(polyline1.Length - d)) { if (Math.Abs(polyline.Length - d) > Math.Abs(polyline2.Length - d)) { polyline = polyline2; } } else { if (Math.Abs(polyline1.Length - d) > Math.Abs(polyline2.Length - d)) { polyline = polyline2; } else { polyline = polyline1; } } return polyline as IPointCollection; } /// /// 自动识别中心点 /// private IPointCollection AutoDistinguish(double angle = 0, IPoint pPoint = null) { #region 自动识别道路中心线 IPoint point = pPoint; if (point == null) { point = this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(MousePoint.X, MousePoint.Y); } IPointCollection vertical = new Polyline(); vertical.AddPoint(point); vertical.AddPoint(point); //KOTilesLayer layer = Common.Utility.LayerHelper.GetLayerByName(m_hookHelper.FocusMap, "YGYXT"); double InitWidht = 50; //if (layer != null) //{ //获取鼠标点周围50米的范围 IEnvelope env = new EnvelopeClass(); //计算当前道路的角度 if (MiddleLine.Line.PointCount > 1) { env.XMax = point.X + this.drawParam.Width; env.XMin = point.X - this.drawParam.Width; env.YMax = point.Y + this.drawParam.Width; env.YMin = point.Y - this.drawParam.Width; InitWidht = drawParam.Width; angle = GeometryOperations.getAngle(MiddleLine.Line.Point[MiddleLine.Line.PointCount - 1], point); if (double.IsNaN(angle) && (MiddleLine.Line.PointCount - 2) > -1) { angle = GeometryOperations.getAngle(MiddleLine.Line.Point[MiddleLine.Line.PointCount - 2], point); } if (Double.IsNaN(angle)) return vertical; } else { env.XMax = point.X + InitWidht / 2; env.XMin = point.X - InitWidht / 2; env.YMax = point.Y + InitWidht / 2; env.YMin = point.Y - InitWidht / 2; } env.SpatialReference = m_hookHelper.FocusMap.SpatialReference; if (double.IsNaN(angle)) return vertical; //根据范围获取影像图片 //TilesImage img = layer.GetImage(env); ImgDistinguish imgDis = new ImgDistinguish(); TilesImage img = imgDis.GetImg(env); //王欢 2018-11-02 未将对象引用设置到对象的实例 //if(img.Img == null || img.Origin == null) if (img == null || img.Img == null || img.Origin == null) return vertical; img.PixelCount = 49; //获取平均灰度值 int Gray = img.GetGrayValue(point); //重新设置单次搜索像素个数 img.PixelCount = 1; //计算单次搜索的实际距离 double distance = img.Resolution * Math.Sqrt(img.PixelCount); //记录已经搜索的总距离 double sumDistance = distance; //检索出在容差范围内的平均灰度值集合 List grayValues = new List(); grayValues.Add(Gray); //记录参考点左边的错误像素个数 int leftBadPixelCount = 0; //记录参考点右边的错误像素个数 int rightBadPixelCount = 0; //记录容差范围内的灰度平均值 double tolerance = 0; ///容差比例 double toloranceScale = this.drawParam.ToloranceScale; //容差半径(污点宽度) double toloranceRadius = 2.5; while (sumDistance < InitWidht) { #region 循环对比像素值 tolerance = Math.Floor((double)grayValues.Sum() / grayValues.Count); if (leftBadPixelCount < toloranceRadius / distance) { IPoint leftPoint = GeometryOperations.GetPoint(point, sumDistance, -angle); int grayvalue = img.GetGrayValue(leftPoint); if (Math.Abs(grayvalue - tolerance) < tolerance * toloranceScale) { leftBadPixelCount = 0; grayValues.Add(grayvalue); vertical.UpdatePoint(0, leftPoint); } else { leftBadPixelCount++; if (leftBadPixelCount < toloranceRadius / distance / 5) { vertical.UpdatePoint(0, leftPoint); } } } if (rightBadPixelCount < toloranceRadius / distance) { IPoint rightPoint = GeometryOperations.GetPoint(point, -sumDistance, -angle); int grayvalue = img.GetGrayValue(rightPoint); if (Math.Abs(grayvalue - tolerance) < tolerance * toloranceScale) { rightBadPixelCount = 0; grayValues.Add(grayvalue); vertical.UpdatePoint(1, rightPoint); } else { rightBadPixelCount++; if (rightBadPixelCount < toloranceRadius / distance / 5) { vertical.UpdatePoint(1, rightPoint); } } } sumDistance += distance; #endregion } //} return vertical; #endregion } /// /// 自动识别中心点 /// private IPointCollection AutoDistinguish2(IPoint pPoint, double angle, double pWidht) { #region 自动识别道路中心线 IPoint point = pPoint; IPointCollection vertical = new Polyline(); vertical.AddPoint(point); vertical.AddPoint(point); //if (layer != null) //{ //获取鼠标点周围50米的范围 IEnvelope env = new EnvelopeClass(); env.XMax = point.X + pWidht; env.XMin = point.X - pWidht; env.YMax = point.Y + pWidht; env.YMin = point.Y - pWidht; env.SpatialReference = m_hookHelper.FocusMap.SpatialReference; if (double.IsNaN(angle)) return vertical; //根据范围获取影像图片 ImgDistinguish imgDis = new ImgDistinguish(); TilesImage img = imgDis.GetImg(env); img.PixelCount = 49; //获取平均灰度值 int Gray = img.GetGrayValue(point); //重新设置单次搜索像素个数 img.PixelCount = 1; //计算单次搜索的实际距离 double distance = img.Resolution * Math.Sqrt(img.PixelCount); //记录已经搜索的总距离 double sumDistance = distance; //检索出在容差范围内的平均灰度值集合 List grayValues = new List(); grayValues.Add(Gray); //记录参考点左边的错误像素个数 int leftBadPixelCount = 0; //记录参考点右边的错误像素个数 int rightBadPixelCount = 0; //记录容差范围内的灰度平均值 double tolerance = 0; ///容差比例 double toloranceScale = this.drawParam.ToloranceScale; //容差半径 double toloranceRadius = 2.5; while (sumDistance < pWidht) { #region 循环对比像素值 tolerance = Math.Floor((double)grayValues.Sum() / grayValues.Count); if (leftBadPixelCount < toloranceRadius / distance) { IPoint leftPoint = GeometryOperations.GetPoint(point, sumDistance, -angle); int grayvalue = img.GetGrayValue(leftPoint); if (Math.Abs(grayvalue - tolerance) < tolerance * toloranceScale) { leftBadPixelCount = 0; grayValues.Add(grayvalue); vertical.UpdatePoint(0, leftPoint); } else { leftBadPixelCount++; if (leftBadPixelCount < toloranceRadius / distance / 5) { vertical.UpdatePoint(0, leftPoint); } } } if (rightBadPixelCount < toloranceRadius / distance) { IPoint rightPoint = GeometryOperations.GetPoint(point, -sumDistance, -angle); int grayvalue = img.GetGrayValue(rightPoint); if (Math.Abs(grayvalue - tolerance) < tolerance * toloranceScale) { rightBadPixelCount = 0; grayValues.Add(grayvalue); vertical.UpdatePoint(1, rightPoint); } else { rightBadPixelCount++; if (rightBadPixelCount < toloranceRadius / distance / 5) { vertical.UpdatePoint(1, rightPoint); } } } sumDistance += distance; #endregion } //} return vertical; #endregion } /// /// 绘制 /// /// private void Drawing(IPoint pPoint) { try { switch (drawParam.DrawMode) { case DrawMode.Left: this.MiddleLine.Scale = -0.5; this.RightLine.Scale = -1; DrawPointExe(pPoint, this.LeftLine, this.MiddleLine, this.RightLine); break; case DrawMode.Right: this.LeftLine.Scale = 1; this.MiddleLine.Scale = 0.5; DrawPointExe(pPoint, this.RightLine, this.MiddleLine, this.LeftLine); break; case DrawMode.LeftAndRight: this.RightLine.Scale = -0.5; this.LeftLine.Scale = 0.5; DrawPointExe(pPoint, this.MiddleLine, this.LeftLine, this.RightLine); break; default: break; } this.LeftLine.DrawLine(); this.MiddleLine.DrawLine(); this.RightLine.DrawLine(); } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线期间 绘制 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 绘制 时异常信息结束"); } } /// /// 移动 /// /// /// 宽度调整标识 private void Moveing(IPoint pPoint, bool IsAdjustWidth = false) { try { switch (drawParam.DrawMode) { case DrawMode.Left: this.MiddleLine.Scale = -0.5; this.RightLine.Scale = -1; MovePointExe(pPoint, LeftLine, RightLine, MiddleLine, IsAdjustWidth); break; case DrawMode.Right: this.LeftLine.Scale = 1; this.MiddleLine.Scale = 0.5; MovePointExe(pPoint, RightLine, LeftLine, MiddleLine, IsAdjustWidth); break; case DrawMode.LeftAndRight: this.RightLine.Scale = -0.5; this.LeftLine.Scale = 0.5; MovePointExe(pPoint, MiddleLine, LeftLine, RightLine, IsAdjustWidth); break; default: break; } LeftLine.DrawLine(); RightLine.DrawLine(); MiddleLine.DrawLine(); } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线期间 移动 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 移动 时异常信息结束"); } } /// /// 绘制新的点 /// /// 点对象 /// 鼠标绘制的线对象 /// 通过角度和距离计算出来的线对象1 /// 通过角度和距离计算出来的线对象2 private void DrawPointExe(IPoint pPoint, LineModel pMainLine, LineModel pExtLine1, LineModel pExtLine2, double pAngle = -1) { try { if (pExtLine1.Line.PointCount <= 0 || pExtLine2.Line.PointCount <= 0) { if (pMainLine.Line.PointCount > 0) { pMainLine.Line.RemovePoints(0, pMainLine.Line.PointCount); } } pMainLine.Line.AddPoint(pPoint); if (pMainLine.Line.PointCount > 1 && pAngle == -1) { pAngle = GeometryOperations.getAngle(pMainLine.Line.get_Point(pMainLine.Line.PointCount - 2), pMainLine.Line.get_Point(pMainLine.Line.PointCount - 1)); } if (pAngle == -1) pAngle = 0; IPoint p1 = GeometryOperations.GetPoint(pPoint, drawParam.Width * pExtLine1.Scale, -pAngle); if (p1 == null || p1.IsEmpty) return; IPoint p2 = GeometryOperations.GetPoint(pPoint, drawParam.Width * pExtLine2.Scale, -pAngle); if (p2 == null || p2.IsEmpty) return; if (pMainLine.Line.PointCount <= 1) { pExtLine1.Line.AddPoint(p1); pExtLine2.Line.AddPoint(p2); return; } //判断第一个点是否识别到已有要素边界 List IdentifyFeature = null; List lineArray = null; if (pMainLine.Line.PointCount == 2) { #region 起始端线 IdentifyFeature = KGIS.Framework.AE.FeatureAPI.Identify(pMainLine.Line.get_Point(0), m_editor.TargetLayer, 1); IdentifyFeature.AddRange(KGIS.Framework.AE.FeatureAPI.Identify(pExtLine1.Line.get_Point(0), m_editor.TargetLayer, 1)); IdentifyFeature.AddRange(KGIS.Framework.AE.FeatureAPI.Identify(pExtLine2.Line.get_Point(0), m_editor.TargetLayer, 1)); if (IdentifyFeature != null && IdentifyFeature.Count > 0) { lineArray = new List(); IPolyline line = null; if (m_editor.GeometryType == esriGeometryType.esriGeometryPolyline) { foreach (IFeature item in IdentifyFeature) { IPolyline tempLine = item.ShapeCopy as IPolyline; if (FeatureAPI.IsInterSect(pMainLine.Line.get_Point(0) as IGeometry, tempLine)) { IPolyline twoPoint = new PolylineClass(); twoPoint.FromPoint = pExtLine1.Line.get_Point(0); twoPoint.ToPoint = pMainLine.Line.get_Point(0); IPolyline line1 = GetSubCurve(tempLine, pExtLine1.Line.get_Point(0), pMainLine.Line.get_Point(0)); if (Math.Round(line1.Length.ToDecimal(), 2, MidpointRounding.AwayFromZero) < Math.Round(twoPoint.Length.ToDecimal(), 2, MidpointRounding.AwayFromZero)) { line1 = twoPoint; } lineArray.Add(line1); twoPoint = new PolylineClass(); twoPoint.FromPoint = pExtLine2.Line.get_Point(0); twoPoint.ToPoint = pMainLine.Line.get_Point(0); line1 = GetSubCurve(tempLine, pExtLine2.Line.get_Point(0), pMainLine.Line.get_Point(0)); if (Math.Round(line1.Length.ToDecimal(), 2, MidpointRounding.AwayFromZero) < Math.Round(twoPoint.Length.ToDecimal(), 2, MidpointRounding.AwayFromZero)) { line1 = twoPoint; } lineArray.Add(line1); } } StartLine = FeatureAPI.MergeGeometry(lineArray) as IPolyline; } } #endregion } IdentifyFeature = KGIS.Framework.AE.FeatureAPI.Identify(pMainLine.Line.get_Point(pMainLine.Line.PointCount - 1), m_editor.TargetLayer, 1); IdentifyFeature.AddRange(KGIS.Framework.AE.FeatureAPI.Identify(pExtLine1.Line.get_Point(pExtLine1.Line.PointCount - 1), m_editor.TargetLayer, 1)); IdentifyFeature.AddRange(KGIS.Framework.AE.FeatureAPI.Identify(pExtLine2.Line.get_Point(pExtLine2.Line.PointCount - 1), m_editor.TargetLayer, 1)); if (IdentifyFeature == null || IdentifyFeature.Count == 0) { pExtLine1.Line.AddPoint(p1); pExtLine2.Line.AddPoint(p2); return; } #region 结束端线 lineArray = new List(); if (m_editor.GeometryType == esriGeometryType.esriGeometryPolyline) { foreach (IFeature item in IdentifyFeature) { IPolyline tempLine = item.ShapeCopy as IPolyline; if (FeatureAPI.IsInterSect(pMainLine.Line.get_Point(pMainLine.Line.PointCount - 1) as IGeometry, tempLine)) { IPolyline twoPoint = new PolylineClass(); twoPoint.FromPoint = pExtLine1.Line.get_Point(pExtLine1.Line.PointCount - 1); twoPoint.ToPoint = pMainLine.Line.get_Point(pMainLine.Line.PointCount - 2); IPoint p4 = GetIntersectPoint(pExtLine1.Line.get_Point(pExtLine1.Line.PointCount - 1), p1, tempLine as IPolyline); if (p4 != null && !p4.IsEmpty) p1 = p4; IPolyline line1 = GetSubCurve(tempLine as IPolyline, p1, pMainLine.Line.get_Point(pMainLine.Line.PointCount - 1)); if (Math.Round(line1.Length.ToDecimal(), 2, MidpointRounding.AwayFromZero) < Math.Round(twoPoint.Length.ToDecimal(), 2, MidpointRounding.AwayFromZero)) { line1 = twoPoint; } lineArray.Add(line1); IPoint p3 = GetIntersectPoint(pExtLine2.Line.get_Point(pExtLine2.Line.PointCount - 1), p2, tempLine as IPolyline); if (p3 != null && !p3.IsEmpty) p2 = p3; line1 = GetSubCurve(tempLine as IPolyline, p2, pMainLine.Line.get_Point(pMainLine.Line.PointCount - 1)); if (Math.Round(line1.Length.ToDecimal(), 2, MidpointRounding.AwayFromZero) < Math.Round(twoPoint.Length.ToDecimal(), 2, MidpointRounding.AwayFromZero)) { line1 = twoPoint; } lineArray.Add(line1); } } EndLine = FeatureAPI.MergeGeometry(lineArray) as IPolyline; } pExtLine1.Line.AddPoint(p1); pExtLine2.Line.AddPoint(p2); if (EndLine != null && IsShiftDown) { this.DrawComplete(); } #endregion } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线期间 绘制新的点 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 绘制新的点 时异常信息结束"); } } /// /// 移动现有的点 /// /// 目标点 /// 鼠标绘制的线对象 /// 通过角度和距离计算出来的线对象1 /// 通过角度和距离计算出来的线对象2 /// 宽度调整标识 private void MovePointExe(IPoint pPoint, LineModel pMainLine, LineModel pExtLine1, LineModel pExtLine2, bool IsAdjustWidth = false) { try { if (pMainLine.Line.PointCount < 1 || pExtLine1.Line.PointCount < 1 || pExtLine1.Line.PointCount < 1) return; double angle = GeometryOperations.getAngle(pMainLine.Line.Point[pMainLine.Line.PointCount - 1], pPoint); if (Double.IsNaN(angle)) return; IPoint pExtLine1StartPoint = null; IPoint pExtLine2StartPoint = null; IPoint pExtLine1EndPoint = null; IPoint pExtLine2EndPoint = null; //获取鼠标跟随线上的第二个点 pExtLine1EndPoint = GeometryOperations.GetPoint(pPoint, drawParam.Width * pExtLine1.Scale, -angle); pExtLine2EndPoint = GeometryOperations.GetPoint(pPoint, drawParam.Width * pExtLine2.Scale, -angle); if (pMainLine.Line.PointCount == 1) { pExtLine1StartPoint = GeometryOperations.GetPoint(pMainLine.Line.get_Point(0), drawParam.Width * pExtLine1.Scale, -angle); pExtLine2StartPoint = GeometryOperations.GetPoint(pMainLine.Line.get_Point(0), drawParam.Width * pExtLine2.Scale, -angle); //判断第一个点是否识别到已有要素边界 List IdentifyFeature = KGIS.Framework.AE.FeatureAPI.Identify(pMainLine.Line.get_Point(0), m_editor.TargetLayer, 1); IdentifyFeature.AddRange(KGIS.Framework.AE.FeatureAPI.Identify(pExtLine1.Line.get_Point(0), m_editor.TargetLayer, 1)); IdentifyFeature.AddRange(KGIS.Framework.AE.FeatureAPI.Identify(pExtLine2.Line.get_Point(0), m_editor.TargetLayer, 1)); if (IdentifyFeature != null && IdentifyFeature.Count > 0) { IPolyline line = null; if (m_editor.GeometryType == esriGeometryType.esriGeometryPolyline) { foreach (IFeature item in IdentifyFeature) { if (line == null) { line = item.ShapeCopy as IPolyline; } else { //捕捉时,起始点捕捉错误,但是无法修改宽度问题处理 ITopologicalOperator topolog = line as ITopologicalOperator; topolog.Simplify(); IGeometry pGeometry = item.ShapeCopy; (pGeometry as ITopologicalOperator).Simplify(); line = topolog.Union(pGeometry) as IPolyline; //line = topolog.Union(item.ShapeCopy) as IPolyline; } } } if (line != null) { if (KGIS.Framework.AE.FeatureAPI.IsInterSect(pMainLine.Line.get_Point(0) as IGeometry, line)) { ITopologicalOperator2 topo = line as ITopologicalOperator2; IPoint p = GetIntersectPoint(pExtLine1EndPoint, pExtLine1StartPoint, line); if (p != null && !p.IsEmpty) { pExtLine1StartPoint = p; } IPoint p2 = GetIntersectPoint(pExtLine2EndPoint, pExtLine2StartPoint, line); if (p2 != null && !p2.IsEmpty) { pExtLine2StartPoint = p2; } } } } } else { pExtLine1StartPoint = GeometryOperations.getParallelPoint(pMainLine.Line.get_Point(pMainLine.Line.PointCount - 2), pMainLine.Line.get_Point(pMainLine.Line.PointCount - 1), pPoint, drawParam.Width * pExtLine1.Scale); pExtLine2StartPoint = GeometryOperations.getParallelPoint(pMainLine.Line.get_Point(pMainLine.Line.PointCount - 2), pMainLine.Line.get_Point(pMainLine.Line.PointCount - 1), pPoint, drawParam.Width * pExtLine2.Scale); } //更新第一条线上的点 pExtLine1.Line.UpdatePoint(pExtLine1.Line.PointCount - 1, pExtLine1StartPoint); //更新第一条跟随线上的点 pExtLine1.FollowLine.Stop(); pExtLine1.FollowLine.Start(new PolylineClass() { FromPoint = pExtLine1StartPoint, ToPoint = pExtLine1StartPoint }, 0, pExtLine1StartPoint); pExtLine1.FollowLine.MoveTo(GeometryOperations.GetPoint(pPoint, drawParam.Width * pExtLine1.Scale, -angle)); //pExtLine1.FollowLine.UpdatePoint(0, pExtLine1StartPoint); //pExtLine1.FollowLine.UpdatePoint(1, GeometryOperations.GetPoint(pPoint, drawParam.Width * pExtLine1.Scale, -angle)); //更新第二条线上的点 pExtLine2.Line.UpdatePoint(pExtLine1.Line.PointCount - 1, pExtLine2StartPoint); //更新第二条跟随线上的点 pExtLine2.FollowLine.Stop(); pExtLine2.FollowLine.Start(new PolylineClass() { FromPoint = pExtLine2StartPoint, ToPoint = pExtLine2StartPoint }, 0, pExtLine2StartPoint); pExtLine2.FollowLine.MoveTo(GeometryOperations.GetPoint(pPoint, drawParam.Width * pExtLine2.Scale, -angle)); //pExtLine2.FollowLine.UpdatePoint(0, pExtLine2StartPoint); //pExtLine2.FollowLine.UpdatePoint(1, GeometryOperations.GetPoint(pPoint, drawParam.Width * pExtLine2.Scale, -angle)); //根据传入的布尔型参数IsAdjustWidth判断是否是宽度调整 if (!IsAdjustWidth) { //更新主跟随线上的点 pMainLine.FollowLine.Stop(); pMainLine.FollowLine.Start(new PolylineClass() { FromPoint = pMainLine.Line.get_Point(pMainLine.Line.PointCount - 1), ToPoint = pMainLine.Line.get_Point(pMainLine.Line.PointCount - 1) }, 0, pMainLine.Line.get_Point(pMainLine.Line.PointCount - 1)); pMainLine.FollowLine.MoveTo(pPoint); //pMainLine.FollowLine.UpdatePoint(0, pMainLine.Line.get_Point(pMainLine.Line.PointCount - 1)); //pMainLine.FollowLine.UpdatePoint(1, pPoint); } } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线期间 移动现有的点 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 移动现有的点 时异常信息结束"); } } private IPolyline GetSubCurve(IPolyline inpolyLine, IPoint pnt1, IPoint pnt2) { double d1 = GetDistAlong(inpolyLine, pnt1); double d2 = GetDistAlong(inpolyLine, pnt2); var c = inpolyLine as ICurve; ICurve outCurve; c.GetSubcurve(d1, d2, false, out outCurve); if (c == null || c.IsEmpty) throw new Exception("aa"); var outPolyline = outCurve as IPolyline; if (outPolyline == null) { outPolyline = new PolylineClass() as IPolyline; var sc = outPolyline as ISegmentCollection; sc.AddSegment((ISegment)outCurve); ((IGeometry)sc).SpatialReference = outCurve.SpatialReference; } return outPolyline; } private double GetDistAlong(IPolyline polyLine, IPoint pnt) { var outPnt = new PointClass() as IPoint; double distAlong = double.NaN; double distFrom = double.NaN; bool bRight = false; polyLine.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, pnt, false, outPnt, ref distAlong, ref distFrom, ref bRight); return distAlong; } /// /// 创建区间线段 /// /// 输入的线图形 /// 插入的其中第一个点 /// 插入的其中第一个点 /// 这两点间的线段 /// 创建人 : 懒羊羊 private IPolyline BuildLine(IPolyline pLine, IPoint p1, IPoint p2) { bool isSplit; int splitIndex, segIndex; //插入第一点,segIndex记录插入点的相对线的节点位置 pLine.SplitAtPoint(p1, true, false, out isSplit, out splitIndex, out segIndex); int fIndex = segIndex; //插入第二点 pLine.SplitAtPoint(p2, true, false, out isSplit, out splitIndex, out segIndex); int sIndex = segIndex; //比较一下插入第一点和第二点的节点次序 if (fIndex > sIndex) { int temp = fIndex; fIndex = sIndex; sIndex = temp; } IPointCollection pPointCol = new PolylineClass(); object o = Type.Missing; //利用两点区间,获取线上区间所在的点,并将其转换为线 IPointCollection LineCol = pLine as IPointCollection; for (int i = fIndex; i <= sIndex; i++) { pPointCol.AddPoint(LineCol.get_Point(i), ref o, ref o); } return pPointCol as IPolyline; } /// /// 绘制点对象到地图 /// /// private void DrawPoint(IPointCollection pPoints) { try { if (pPoints == null || pPoints.PointCount == 0) return; // 获取IRGBColor接口 IRgbColor color = new RgbColor(); // 设置颜色属性 color.Red = 255; color.Green = 0; color.Blue = 0; IMarkerSymbol symbol = new SimpleMarkerSymbolClass(); symbol.Color = color; symbol.Size = 5; IPointCollection pointList = new Polyline(); pointList.AddPoint(this.LeftLine.Line.get_Point(this.LeftLine.Line.PointCount - 1)); pointList.AddPoint(this.MiddleLine.Line.get_Point(this.MiddleLine.Line.PointCount - 1)); pointList.AddPoint(this.RightLine.Line.get_Point(this.RightLine.Line.PointCount - 1)); IPointCollection pointList2 = new Polyline(); pointList2.AddPoint(this.LeftLine.Line.get_Point(this.LeftLine.Line.PointCount - 1)); pointList2.AddPoint(this.MiddleLine.Line.get_Point(this.MiddleLine.Line.PointCount - 1)); pointList2.AddPoint(this.RightLine.Line.get_Point(this.RightLine.Line.PointCount - 1)); for (int i = 0; i < pPoints.PointCount; i++) { if (PointElement.Count == i) { IMarkerElement e = new MarkerElementClass(); e.Symbol = symbol; PointElement.Add(e as IElement); this.m_hookHelper.ActiveView.GraphicsContainer.AddElement(e as IElement, 0); } IElement element = PointElement[i]; pointList.AddPoint(element.Geometry as IPoint); element.Geometry = pPoints.get_Point(i); pointList2.AddPoint(pPoints.get_Point(i)); } pointList.AddPoint(this.LeftLine.Line.get_Point(this.LeftLine.Line.PointCount - 1)); IPolyline line = pointList as IPolyline; if (line.Length <= 0 || line.Length.Equals(double.NaN)) { return; } ITopologicalOperator topo = line as ITopologicalOperator; IGeometry geo = topo.Buffer(10); this.m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, this.m_hookHelper.ActiveView.Extent); //this.m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, geo.Envelope); //this.m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, (pointList2 as IPolyline).Envelope); } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线期间 绘制点对象到地图 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 绘制点对象到地图 时异常信息结束"); } } /// /// 绘制文本对象 /// /// /// public void DrawTextElement(ESRI.ArcGIS.Geometry.IGeometry geoDraw, ref IElement pElement) { if (pElement != null && geoDraw != null) { if (pElement is ITextElement) { (pElement as ITextElement).Text = string.Format("当前宽度 {0} 米", drawParam.Width); } pElement.Geometry = geoDraw; m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, m_hookHelper.ActiveView.Extent); return; } // 获取IRGBColor接口 IRgbColor color = new RgbColor(); // 设置颜色属性 color.Red = 0; color.Green = 255; color.Blue = 255; //IFontDisp pFont = new StdFont() //{ // Name = "宋体", // Bold = true //} as IFontDisp; ITextSymbol pTextSymbol = new TextSymbolClass() { Color = color, //Font = pFont, Size = 12 }; ITextElement pTextElement = new TextElementClass() { Symbol = pTextSymbol, ScaleText = true, Text = string.Format("当前宽度 {0} 米", drawParam.Width) }; IPoint point = geoDraw as IPoint; point.X += 2; point.Y -= 1; if (pElement == null) { pElement = pTextElement as IElement; pElement.Geometry = point; m_hookHelper.ActiveView.GraphicsContainer.AddElement(pElement, 0); } m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, m_hookHelper.ActiveView.Extent); } /// /// 删除指定的Element /// /// public void DelElement(ref IElement pElement) { try { if (pElement != null) { m_hookHelper.ActiveView.GraphicsContainer.DeleteElement(pElement); m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, m_hookHelper.ActiveView.Extent); pElement = null; } } catch (Exception ex) { //LogAPI.Debug(ex); LogAPI.Debug("画双线期间 删除指定的Element 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 删除指定的Element 时异常信息结束"); } } /// /// 捕捉Element上的点并返回点的索引 /// /// /// private int SnapElement(IPoint pPoint) { int pointIndex = -1; try { //中心线距离 double len = -1; for (int i = 0; i < MiddleLine.Line.PointCount; i++) { IPolyline line = new PolylineClass(); line.FromPoint = MiddleLine.Line.get_Point(i); line.ToPoint = pPoint; line.SpatialReference = pPoint.SpatialReference; if (len == -1) { len = line.Length; pointIndex = i; } else { if (len > line.Length) { len = line.Length; pointIndex = i; } } } } catch (Exception ex) { LogAPI.Debug("画双线期间 在捕捉Element上的点并返回点的索引 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 在捕捉Element上的点并返回点的索引 时异常信息结束"); //LogAPI.Debug(ex); return -1; } return pointIndex; } /// /// 捕捉Element上的点并返回点的索引 /// /// /// private int SnapElement(IPoint pPoint, out int p) { int pointIndex = -1; try { double tempLen = -1; //中心线距离 double len = -1; //左边线距离 double len1 = -1; //右边线距离 double len2 = -1; //中心线索引 int m_index = -1; //左边线索引 int l_index = -1; //右边线索引 int r_index = -1; for (int i = 0; i < MiddleLine.Line.PointCount; i++) { IPolyline line = new PolylineClass(); line.FromPoint = MiddleLine.Line.get_Point(i); line.ToPoint = pPoint; line.SpatialReference = pPoint.SpatialReference; if (len == -1) { len = line.Length; m_index = i; } else { if (len > line.Length) { len = line.Length; m_index = i; } } } for (int i = 0; i < LeftLine.Line.PointCount; i++) { IPolyline line = new PolylineClass(); line.FromPoint = LeftLine.Line.get_Point(i); line.ToPoint = pPoint; line.SpatialReference = pPoint.SpatialReference; if (len1 == -1) { len1 = line.Length; l_index = i; } else { if (len1 > line.Length) { len1 = line.Length; l_index = i; } } } for (int i = 0; i < RightLine.Line.PointCount; i++) { IPolyline line = new PolylineClass(); line.FromPoint = RightLine.Line.get_Point(i); line.ToPoint = pPoint; line.SpatialReference = pPoint.SpatialReference; if (len2 == -1) { len2 = line.Length; r_index = i; } else { if (len2 > line.Length) { len2 = line.Length; r_index = i; } } } if (len > len1) { if (len1 > len2) { p = -1; tempLen = len2; pointIndex = r_index; } else { p = 1; tempLen = len1; pointIndex = l_index; } } else { if (len > len2) { p = -1; tempLen = len2; pointIndex = r_index; } else { p = 0; tempLen = len; pointIndex = m_index; } } if (tempLen > 3) { pointIndex = -1; } } catch (Exception ex) { p = 0; //LogAPI.Debug(ex); LogAPI.Debug("画双线期间 捕捉Element上的点并返回点的索引 时异常,异常信息如下:"); LogAPI.Debug(ex); LogAPI.Debug("画双线期间 捕捉Element上的点并返回点的索引 时异常信息结束"); return -1; } return pointIndex; } #endregion /// /// 设置鼠标的坐标 /// /// 横坐标 /// 纵坐标 [DllImport("User32")] public extern static void SetCursorPos(int x, int y); public override enumProductType AttachProductType { get { return enumProductType.KDB | enumProductType.KAP; } } public override void Refresh(int hDC) { if (MiddleLine != null && MiddleLine.FollowLine != null) MiddleLine.FollowLine.Refresh(hDC); if (LeftLine != null && LeftLine.FollowLine != null) LeftLine.FollowLine.Refresh(hDC); if (RightLine != null && RightLine.FollowLine != null) RightLine.FollowLine.Refresh(hDC); base.Refresh(hDC); } } }