From 47c2d5cb3d3255c7e32a1329965245740f075ec7 Mon Sep 17 00:00:00 2001 From: Natalie Feuerstein Date: Thu, 26 Jan 2017 16:20:20 -0700 Subject: [PATCH 01/42] Updated Tags Added Military-Tools-for-ArcGIS --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f33778a..8bcfaf9 100644 --- a/README.md +++ b/README.md @@ -184,5 +184,5 @@ limitations under the License. A copy of the license is available in the repository's [license.txt](license.txt) file. -[](Esri Tags: Military Analyst Defense ArcGIS ArcObjects .NET WPF ArcGISSolutions ArcMap ArcPro Add-In) +[](Esri Tags: Military Analyst Defense ArcGIS ArcObjects .NET WPF ArcGISSolutions ArcMap ArcPro Add-In Military-Tools-for-ArcGIS) [](Esri Language: C#) From ce435ed179465089e5d99c00ced541deab0cf531 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Tue, 7 Feb 2017 09:55:02 -0500 Subject: [PATCH 02/42] Update version to 2.0 --- source/Visibility/ProAppVisibilityModule/Config.daml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Visibility/ProAppVisibilityModule/Config.daml b/source/Visibility/ProAppVisibilityModule/Config.daml index 96558be..b3f347d 100644 --- a/source/Visibility/ProAppVisibilityModule/Config.daml +++ b/source/Visibility/ProAppVisibilityModule/Config.daml @@ -1,11 +1,11 @@  - + Visibility Conduct Linear Line of Sight and Radial Line of Sight analysis Images\AddinDesktop32.png Esri Esri - 4/12/2016 1:35:21 PM, 2016 + 01/20/2017 Framework @@ -48,4 +48,4 @@ - \ No newline at end of file + From a8232de2491785e58494b6e473fb8f0b3e9b1403 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Tue, 7 Feb 2017 09:56:27 -0500 Subject: [PATCH 03/42] Update version to 2.0 --- source/Visibility/ArcMapAddinVisibility/Config.esriaddinx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx b/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx index c9226ab..f2e2c57 100644 --- a/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx +++ b/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx @@ -2,7 +2,7 @@ Visibility {9cb838f4-d17a-403b-85d0-8f7dc002697e} Conduct Linear Line of Sight and Radial Line of Sight analysis - 1.0 + 2.0 Images\ArcMapAddinVisibility.png ESRI ESRI @@ -23,4 +23,4 @@ - \ No newline at end of file + From 8b5ecf7b706f14a9a88bccc18eb380905c9da101 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Tue, 7 Feb 2017 12:02:31 -0500 Subject: [PATCH 04/42] Update date --- source/Visibility/ArcMapAddinVisibility/Config.esriaddinx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx b/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx index f2e2c57..3058e9e 100644 --- a/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx +++ b/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx @@ -6,7 +6,7 @@ Images\ArcMapAddinVisibility.png ESRI ESRI - 2/16/2016 + 01/20/2017 From 83be2ec794dda804343d27f4c9d818e9fab803a2 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Wed, 8 Feb 2017 10:49:18 -0500 Subject: [PATCH 05/42] ESRI to Esri --- source/Visibility/ArcMapAddinVisibility/Config.esriaddinx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx b/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx index c9226ab..e68cd21 100644 --- a/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx +++ b/source/Visibility/ArcMapAddinVisibility/Config.esriaddinx @@ -4,8 +4,8 @@ Conduct Linear Line of Sight and Radial Line of Sight analysis 1.0 Images\ArcMapAddinVisibility.png - ESRI - ESRI + Esri + Esri 2/16/2016 @@ -23,4 +23,4 @@ - \ No newline at end of file + From ff7910f086aa851e0dfdf6d1e3e5791dd5f77dae Mon Sep 17 00:00:00 2001 From: Lorraine Funkhouser Date: Mon, 13 Feb 2017 10:21:38 -0800 Subject: [PATCH 06/42] Update README.md Updated repo owner --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8bcfaf9..11eefe4 100644 --- a/README.md +++ b/README.md @@ -155,14 +155,14 @@ Anyone and everyone is welcome to contribute. Please see our [guidelines for con ### Repository Points of Contact -#### Repository Owner: [Joe](https://github.com/jmccausland) +#### Repository Owner: [Kevin](https://github.com/kgonzago) * Merge Pull Requests * Creates Releases and Tags * Manages Milestones * Manages and Assigns Issues -#### Secondary: [Lyle](https://github.com/topowright) +#### Secondary: [Patrick](https://github.com/pHill5136) * Backup when the Owner is away From 082e30170663ee8fd8f5fb1872da2b19f0b89b4b Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Wed, 15 Feb 2017 09:54:08 -0500 Subject: [PATCH 07/42] Run XAML Styler --- .../DockableWindowVisibility.xaml | 8 +- .../VisibilityDockpane.xaml | 20 +- .../MAResourceDictionary.xaml | 70 ++- .../Views/EditPropertiesView.xaml | 72 +-- .../VisibilityLibrary/Views/LLOSView.xaml | 339 ++++++------ .../VisibilityLibrary/Views/RLOSView.xaml | 482 +++++++++--------- 6 files changed, 526 insertions(+), 465 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/DockableWindowVisibility.xaml b/source/Visibility/ArcMapAddinVisibility/DockableWindowVisibility.xaml index f915add..cc8739f 100644 --- a/source/Visibility/ArcMapAddinVisibility/DockableWindowVisibility.xaml +++ b/source/Visibility/ArcMapAddinVisibility/DockableWindowVisibility.xaml @@ -1,9 +1,11 @@ - + xmlns:viewModels="clr-namespace:ArcMapAddinVisibility.ViewModels" + Width="300" + Height="300"> diff --git a/source/Visibility/ProAppVisibilityModule/VisibilityDockpane.xaml b/source/Visibility/ProAppVisibilityModule/VisibilityDockpane.xaml index c833c4e..e9c75ad 100644 --- a/source/Visibility/ProAppVisibilityModule/VisibilityDockpane.xaml +++ b/source/Visibility/ProAppVisibilityModule/VisibilityDockpane.xaml @@ -1,15 +1,17 @@ - + - + diff --git a/source/Visibility/VisibilityLibrary/MAResourceDictionary.xaml b/source/Visibility/VisibilityLibrary/MAResourceDictionary.xaml index 14f06fc..5fec5d4 100644 --- a/source/Visibility/VisibilityLibrary/MAResourceDictionary.xaml +++ b/source/Visibility/VisibilityLibrary/MAResourceDictionary.xaml @@ -1,46 +1,57 @@ - + - - + + - + - + - + - - - + @@ -129,51 +137,56 @@ - - + + - + - - + + - + - - + @@ -204,48 +218,49 @@ - - + + - + - + - + - - + + - - - + @@ -137,19 +146,21 @@ - - + + - + - - - + + - + + - + + Date: Wed, 8 Mar 2017 08:42:04 -0500 Subject: [PATCH 18/42] Tool Toggle Issue #159 for ArcMap --- .../ArcMapAddinVisibility/MapPointTool.cs | 9 ++ .../ViewModels/LOSBaseViewModel.cs | 82 ++++++++++++++++--- .../ViewModels/TabBaseViewModel.cs | 28 ++++++- 3 files changed, 105 insertions(+), 14 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs b/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs index 3b360cd..e037ea7 100644 --- a/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs +++ b/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs @@ -53,6 +53,15 @@ protected override void OnActivate() m_Snapper = m_SnappingEnv.PointSnapper; m_SnappingFeedback = new SnappingFeedbackClass(); m_SnappingFeedback.Initialize(ArcMap.Application, m_SnappingEnv, true); + + Mediator.NotifyColleagues(VisibilityLibrary.Constants.MAP_POINT_TOOL_ACTIVATED, true); + } + + protected override bool OnDeactivate() + { + Mediator.NotifyColleagues(VisibilityLibrary.Constants.MAP_POINT_TOOL_DEACTIVATED, false); + + return base.OnDeactivate(); } protected override void OnMouseDown(ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs arg) diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/LOSBaseViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/LOSBaseViewModel.cs index a9899e8..a7f26ca 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/LOSBaseViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/LOSBaseViewModel.cs @@ -40,8 +40,8 @@ public LOSBaseViewModel() AngularUnitType = AngularTypes.DEGREES; ObserverAddInPoints = new ObservableCollection(); - - ToolMode = MapPointToolMode.Unknown; + + toolMode = MapPointToolMode.Unknown; SurfaceLayerNames = new ObservableCollection(); SelectedSurfaceName = string.Empty; @@ -51,11 +51,32 @@ public LOSBaseViewModel() DeletePointCommand = new RelayCommand(OnDeletePointCommand); DeleteAllPointsCommand = new RelayCommand(OnDeleteAllPointsCommand); EditPropertiesDialogCommand = new RelayCommand(OnEditPropertiesDialogCommand); - } #region Properties + private bool observerToolActive = false; + public bool ObserverToolActive + { + get { return observerToolActive; } + set + { + observerToolActive = value; + RaisePropertyChanged(() => ObserverToolActive); + } + } + + private bool targetToolActive = false; + public bool TargetToolActive + { + get { return targetToolActive; } + set + { + targetToolActive = value; + RaisePropertyChanged(() => TargetToolActive); + } + } + private bool isRunning = false; public bool IsRunning { @@ -93,7 +114,34 @@ public double? TargetOffset throw new ArgumentException(VisibilityLibrary.Properties.Resources.AEInvalidInput); } } - internal MapPointToolMode ToolMode { get; set; } + + private MapPointToolMode toolMode; + public MapPointToolMode ToolMode + { + get { return toolMode; } + set + { + toolMode = value; + if (toolMode == MapPointToolMode.Observer) + { + ObserverToolActive = true; + TargetToolActive = false; + } + else if (toolMode == MapPointToolMode.Target) + { + ObserverToolActive = false; + TargetToolActive = true; + } + else + { + ObserverToolActive = false; + TargetToolActive = false; + + DeactivateTool("Esri_ArcMapAddinVisibility_MapPointTool"); + } + } + } + public ObservableCollection ObserverAddInPoints { get; set; } public ObservableCollection SurfaceLayerNames { get; set; } public string SelectedSurfaceName { get; set; } @@ -180,20 +228,34 @@ private void OnMapTocUpdated(object obj) /// observer points and target points /// /// ToolMode string from resource file - internal override void OnActivateTool(object obj) + internal override void OnActivateToolCommand(object obj) { var mode = obj.ToString(); - ToolMode = MapPointToolMode.Unknown; + + MapPointToolMode lastToolMode = ToolMode; if (string.IsNullOrWhiteSpace(mode)) return; - if (mode == VisibilityLibrary.Properties.Resources.ToolModeObserver) + if ((mode == VisibilityLibrary.Properties.Resources.ToolModeObserver) && + (lastToolMode != MapPointToolMode.Observer)) ToolMode = MapPointToolMode.Observer; - else if (mode == VisibilityLibrary.Properties.Resources.ToolModeTarget) + else if ((mode == VisibilityLibrary.Properties.Resources.ToolModeTarget) && + (lastToolMode != MapPointToolMode.Target)) ToolMode = MapPointToolMode.Target; + else + ToolMode = MapPointToolMode.Unknown; + + if (ToolMode != MapPointToolMode.Unknown) + base.OnActivateToolCommand(obj); + } + + protected override void OnMapPointToolDeactivated(object obj) + { + if (ToolMode != MapPointToolMode.Unknown) + ToolMode = MapPointToolMode.Unknown; - base.OnActivateTool(obj); + base.OnMapPointToolDeactivated(obj); } /// @@ -298,7 +360,7 @@ internal bool IsValidPoint(IPoint point, bool showPopup = false) /// /// Enumeration used for the different tool modes /// - internal enum MapPointToolMode : int + public enum MapPointToolMode : int { Unknown = 0, Observer = 1, diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs index 83e1e7f..af44bdc 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs @@ -37,7 +37,7 @@ public TabBaseViewModel() { //commands ClearGraphicsCommand = new RelayCommand(OnClearGraphics); - ActivateToolCommand = new RelayCommand(OnActivateTool); + ActivateToolCommand = new RelayCommand(OnActivateToolCommand); EnterKeyCommand = new RelayCommand(OnEnterKeyCommand); CancelCommand = new RelayCommand(OnCancelCommand); @@ -45,6 +45,20 @@ public TabBaseViewModel() Mediator.Register(Constants.NEW_MAP_POINT, OnNewMapPointEvent); Mediator.Register(Constants.MOUSE_MOVE_POINT, OnMouseMoveEvent); Mediator.Register(Constants.TAB_ITEM_SELECTED, OnTabItemSelected); + + Mediator.Register(VisibilityLibrary.Constants.MAP_POINT_TOOL_ACTIVATED, OnMapPointToolActivated); + Mediator.Register(VisibilityLibrary.Constants.MAP_POINT_TOOL_DEACTIVATED, OnMapPointToolDeactivated); + } + + protected void OnMapPointToolActivated(object obj) + { + // reactivate any graphics on the map + } + + protected virtual void OnMapPointToolDeactivated(object obj) + { + + // remove graphics from map } #region Properties @@ -278,7 +292,7 @@ internal virtual void CreateMapElement() /// /// Clears all the graphics from the maps graphic container except temp graphics - /// Inlucdes map graphics only + /// Includes map graphics only /// Only removes map graphics that were created by this add-in /// /// @@ -384,10 +398,11 @@ internal void RemoveGraphics(List guidList) /// Activates the map tool to get map points from mouse clicks/movement /// /// - internal virtual void OnActivateTool(object obj) + internal virtual void OnActivateToolCommand(object obj) { SetToolActiveInToolBar(ArcMap.Application, "Esri_ArcMapAddinVisibility_MapPointTool"); } + /// /// Handler for the "Enter"key command /// Calls CreateMapElement @@ -428,9 +443,10 @@ public void DeactivateTool(string toolname) && ArcMap.Application.CurrentTool != null && ArcMap.Application.CurrentTool.Name.Equals(toolname)) { - ArcMap.Application.CurrentTool = null; + SetToolActiveInToolBar(ArcMap.Application, "esriArcMapUI.PanTool"); } } + /// /// Method to set the map tool as the active tool for the map /// @@ -438,6 +454,9 @@ public void DeactivateTool(string toolname) /// public void SetToolActiveInToolBar(ESRI.ArcGIS.Framework.IApplication application, System.String toolName) { + if (ArcMap.Application.CurrentTool.Name.Equals(toolName)) + return; + ESRI.ArcGIS.Framework.ICommandBars commandBars = application.Document.CommandBars; ESRI.ArcGIS.esriSystem.UID commandID = new ESRI.ArcGIS.esriSystem.UIDClass(); commandID.Value = toolName; @@ -447,6 +466,7 @@ public void SetToolActiveInToolBar(ESRI.ArcGIS.Framework.IApplication applicatio application.CurrentTool = commandItem; } #endregion + #region Private Functions /// /// Method will return a formatted point as a string based on the configuration settings for display coordinate type From 8c40dbf13427ed9f765f5931a27a5e028a628a0f Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Wed, 8 Mar 2017 08:43:09 -0500 Subject: [PATCH 19/42] Moved to parent class --- .../ViewModels/ProLOSBaseViewModel.cs | 23 +----- .../ViewModels/ProTabBaseViewModel.cs | 76 ++++++++++++------- 2 files changed, 51 insertions(+), 48 deletions(-) diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs index f2dfcce..15b9656 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs @@ -60,8 +60,6 @@ public ProLOSBaseViewModel() LayersRemovedEvent.Subscribe(OnLayersAdded); MapPropertyChangedEvent.Subscribe(OnMapPropertyChanged); MapMemberPropertiesChangedEvent.Subscribe(OnMapMemberPropertyChanged); - - ArcGIS.Desktop.Framework.Events.ActiveToolChangedEvent.Subscribe(OnActiveToolChanged); } ~ProLOSBaseViewModel() @@ -74,8 +72,6 @@ public ProLOSBaseViewModel() #region Properties - private string lastActiveToolName; - protected override void OnMapPointToolDeactivated(object obj) { ToolMode = MapPointToolMode.Unknown; @@ -165,10 +161,11 @@ public MapPointToolMode ToolMode ObserverToolActive = false; TargetToolActive = false; - ArcGIS.Desktop.Framework.FrameworkApplication.SetCurrentToolAsync(lastActiveToolName); + DeactivateTool("ProAppVisibilityModule_MapTool"); } } } + public ObservableCollection ObserverAddInPoints { get; set; } public ObservableCollection SurfaceLayerNames { get; set; } public string SelectedSurfaceName { get; set; } @@ -273,8 +270,6 @@ internal override void OnEnterKeyCommand(object obj) /// ToolMode string from resource file internal override void OnActivateToolCommand(object obj) { - string currentTool = ArcGIS.Desktop.Framework.FrameworkApplication.CurrentTool; - var mode = obj.ToString(); MapPointToolMode lastToolMode = ToolMode; @@ -291,7 +286,8 @@ internal override void OnActivateToolCommand(object obj) else ToolMode = MapPointToolMode.Unknown; - base.OnActivateToolCommand(obj); + if (ToolMode != MapPointToolMode.Unknown) + base.OnActivateToolCommand(obj); } /// @@ -638,17 +634,6 @@ private async void OnMapMemberPropertyChanged(MapMemberPropertiesChangedEventArg await ResetSurfaceNames(); } - private void OnActiveToolChanged(ArcGIS.Desktop.Framework.Events.ToolEventArgs args) - { - string currentActiveToolName = args.CurrentID; - - if (currentActiveToolName != "ProAppVisibilityModule_MapTool") - { - lastActiveToolName = currentActiveToolName; - } - - } - internal LinearUnit GetLinearUnit(DistanceTypes dtype) { LinearUnit result = LinearUnit.Meters; diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs index 1f33adb..9cc3898 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs @@ -56,31 +56,9 @@ public ProTabBaseViewModel() Mediator.Register(VisibilityLibrary.Constants.MAP_POINT_TOOL_ACTIVATED, OnMapPointToolActivated); Mediator.Register(VisibilityLibrary.Constants.MAP_POINT_TOOL_DEACTIVATED, OnMapPointToolDeactivated); - } - - protected virtual void OnMapPointToolDeactivated(object obj) - { - foreach (var item in ProGraphicsList) - { - if (item.Disposable != null && item.IsTemp == true) - { - if (item.Disposable != null) - item.Disposable.Dispose(); - item.Disposable = null; - } - } - } - - private class tempProGraphic - { - public tempProGraphic() { } - public string GUID { get; set; } - public Geometry Geometry { get; set; } - public CIMColor Color { get; set; } - public bool IsTemp { get; set; } - public double Size { get; set; } - public SimpleMarkerStyle MarkerStyle { get; set; } + // Pro Events + ArcGIS.Desktop.Framework.Events.ActiveToolChangedEvent.Subscribe(OnActiveToolChanged); } private async void OnMapPointToolActivated(object obj) @@ -88,7 +66,7 @@ private async void OnMapPointToolActivated(object obj) var addList = new List(); var removeList = new List(); - foreach(var item in ProGraphicsList) + foreach (var item in ProGraphicsList) { if (item.Disposable != null || item.IsTemp == false) continue; @@ -113,7 +91,7 @@ private async void OnMapPointToolActivated(object obj) }); } - foreach(var temp in addList) + foreach (var temp in addList) { var pgOLD = ProGraphicsList.FirstOrDefault(g => g.GUID == temp.GUID); @@ -128,8 +106,38 @@ private async void OnMapPointToolActivated(object obj) ProGraphicsList.Remove(pg); } + protected virtual void OnMapPointToolDeactivated(object obj) + { + foreach (var item in ProGraphicsList) + { + if (item.Disposable != null && item.IsTemp == true) + { + if (item.Disposable != null) + item.Disposable.Dispose(); + item.Disposable = null; + } + } + } + + private class tempProGraphic + { + public tempProGraphic() { } + + public string GUID { get; set; } + public Geometry Geometry { get; set; } + public CIMColor Color { get; set; } + public bool IsTemp { get; set; } + public double Size { get; set; } + public SimpleMarkerStyle MarkerStyle { get; set; } + } + #region Properties + /// + /// save last active tool used, so we can set back to this + /// + private string lastActiveToolName; + /// /// lists to store GUIDs of graphics, temp feedback and map graphics /// @@ -676,9 +684,19 @@ internal void DeactivateTool(string toolname) FrameworkApplication.CurrentTool.Equals(toolname)) { Application.Current.Dispatcher.Invoke(() => - { - FrameworkApplication.SetCurrentToolAsync(String.Empty); - }); + { + FrameworkApplication.SetCurrentToolAsync(lastActiveToolName); + }); + } + } + + private void OnActiveToolChanged(ArcGIS.Desktop.Framework.Events.ToolEventArgs args) + { + string currentActiveToolName = args.CurrentID; + + if (currentActiveToolName != "ProAppVisibilityModule_MapTool") + { + lastActiveToolName = currentActiveToolName; } } From 0a5c5ef0e9bddefff02aa2c9d62732abcdff3757 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Wed, 8 Mar 2017 11:50:57 -0500 Subject: [PATCH 20/42] Get back to previous tool in ArcMap --- .../ArcMapAddinVisibility/MapPointTool.cs | 25 ++++++++++++ .../ViewModels/TabBaseViewModel.cs | 38 ++++++++++++++----- .../VisibilityLibrary/Helpers/Constants.cs | 1 + 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs b/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs index e037ea7..12b5643 100644 --- a/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs +++ b/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs @@ -32,13 +32,35 @@ public class MapPointTool : ESRI.ArcGIS.Desktop.AddIns.Tool IPointSnapper m_Snapper; ISnappingFeedback m_SnappingFeedback; + /// + /// save last active tool used, so we can set back to this + /// + private string lastActiveToolGuid; + public MapPointTool() { + if ((ArcMap.Application != null) && (ArcMap.Application.CurrentTool != null)) + lastActiveToolGuid = ArcMap.Application.CurrentTool.ID.Value as string; } protected override void OnUpdate() { Enabled = ArcMap.Application != null; + + if ((ArcMap.Application == null) || (ArcMap.Application.CurrentTool == null)) + return; + + // Keep track of the last tool used here so we can set it back to address: + // https://github.com/Esri/visibility-addin-dotnet/issues/159 + // This is not a very efficient place to do this because it is called repeatedly + // but only place I could find that knew the previous tool in use + + if (ArcMap.Application.CurrentTool.ID.Value.ToString().Equals(lastActiveToolGuid)) + return; + + // this is a GUID - with no way to get the progID + // (except PInvoke of Win32 ProgIDFromCLSID) so using GUIDs instead of more readable ProgID + lastActiveToolGuid = ArcMap.Application.CurrentTool.ID.Value as string; } protected override void OnActivate() @@ -55,6 +77,9 @@ protected override void OnActivate() m_SnappingFeedback.Initialize(ArcMap.Application, m_SnappingEnv, true); Mediator.NotifyColleagues(VisibilityLibrary.Constants.MAP_POINT_TOOL_ACTIVATED, true); + + // Also notify what the previous tool was so it can be set back + Mediator.NotifyColleagues(VisibilityLibrary.Constants.MAP_TOOL_CHANGED, lastActiveToolGuid); } protected override bool OnDeactivate() diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs index af44bdc..3a38287 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs @@ -48,6 +48,8 @@ public TabBaseViewModel() Mediator.Register(VisibilityLibrary.Constants.MAP_POINT_TOOL_ACTIVATED, OnMapPointToolActivated); Mediator.Register(VisibilityLibrary.Constants.MAP_POINT_TOOL_DEACTIVATED, OnMapPointToolDeactivated); + Mediator.Register(VisibilityLibrary.Constants.MAP_TOOL_CHANGED, OnActiveToolChanged); + } protected void OnMapPointToolActivated(object obj) @@ -61,8 +63,23 @@ protected virtual void OnMapPointToolDeactivated(object obj) // remove graphics from map } + protected virtual void OnActiveToolChanged(object obj) + { + string currentActiveToolName = obj as string; + + if ((currentActiveToolName == "Esri_ArcMapAddinVisibility_MapPointTool")) + return; + + lastActiveToolName = currentActiveToolName; + } + #region Properties + /// + /// save last active tool used, so we can set back to this + /// + private string lastActiveToolName; + // lists to store GUIDs of graphics, temp feedback and map graphics private static List GraphicsList = new List(); @@ -400,7 +417,7 @@ internal void RemoveGraphics(List guidList) /// internal virtual void OnActivateToolCommand(object obj) { - SetToolActiveInToolBar(ArcMap.Application, "Esri_ArcMapAddinVisibility_MapPointTool"); + SetToolActiveInToolBar("Esri_ArcMapAddinVisibility_MapPointTool"); } /// @@ -439,12 +456,7 @@ internal virtual void OnNewMapPointEvent(object obj) /// public void DeactivateTool(string toolname) { - if (ArcMap.Application != null - && ArcMap.Application.CurrentTool != null - && ArcMap.Application.CurrentTool.Name.Equals(toolname)) - { - SetToolActiveInToolBar(ArcMap.Application, "esriArcMapUI.PanTool"); - } + SetToolActiveInToolBar(lastActiveToolName); } /// @@ -452,18 +464,24 @@ public void DeactivateTool(string toolname) /// /// /// - public void SetToolActiveInToolBar(ESRI.ArcGIS.Framework.IApplication application, System.String toolName) + public void SetToolActiveInToolBar(string toolName) { + if ((ArcMap.Application == null) || (ArcMap.Application.CurrentTool == null) || + string.IsNullOrEmpty(toolName)) + return; + + // Tricky: Check if tool already active - because setting CurrentTool will + // cause Activate/Deactive to be called by framework if (ArcMap.Application.CurrentTool.Name.Equals(toolName)) return; - ESRI.ArcGIS.Framework.ICommandBars commandBars = application.Document.CommandBars; + ESRI.ArcGIS.Framework.ICommandBars commandBars = ArcMap.Application.Document.CommandBars; ESRI.ArcGIS.esriSystem.UID commandID = new ESRI.ArcGIS.esriSystem.UIDClass(); commandID.Value = toolName; ESRI.ArcGIS.Framework.ICommandItem commandItem = commandBars.Find(commandID, false, false); if (commandItem != null) - application.CurrentTool = commandItem; + ArcMap.Application.CurrentTool = commandItem; } #endregion diff --git a/source/Visibility/VisibilityLibrary/Helpers/Constants.cs b/source/Visibility/VisibilityLibrary/Helpers/Constants.cs index 1c04491..52bf778 100644 --- a/source/Visibility/VisibilityLibrary/Helpers/Constants.cs +++ b/source/Visibility/VisibilityLibrary/Helpers/Constants.cs @@ -31,5 +31,6 @@ public class Constants public const string DISPLAY_COORDINATE_TYPE_CHANGED = "DisplayCoordinateTypeChanged"; public const string MAP_POINT_TOOL_ACTIVATED = "MAP_POINT_TOOL_ACTIVATED"; public const string MAP_POINT_TOOL_DEACTIVATED = "MAP_POINT_TOOL_DEACTIVATED"; + public const string MAP_TOOL_CHANGED = "MAP_TOOL_CHANGED"; } } From ab8d70ed08b18aa05ac8bf867552af2c4ed83ac0 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Wed, 8 Mar 2017 14:44:23 -0500 Subject: [PATCH 21/42] Change Tool IDs to single declaration --- .../ArcMapAddinVisibility/ViewModels/LOSBaseViewModel.cs | 2 +- .../ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs | 6 +++--- .../ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs | 2 +- .../ViewModels/ProLOSBaseViewModel.cs | 2 +- .../ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs | 2 +- .../ViewModels/ProTabBaseViewModel.cs | 6 +++--- .../Visibility/ProAppVisibilityModule/VisibilityMapTool.cs | 6 ++++++ 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/LOSBaseViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/LOSBaseViewModel.cs index a7f26ca..d04a5ef 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/LOSBaseViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/LOSBaseViewModel.cs @@ -137,7 +137,7 @@ public MapPointToolMode ToolMode ObserverToolActive = false; TargetToolActive = false; - DeactivateTool("Esri_ArcMapAddinVisibility_MapPointTool"); + DeactivateTool(ThisAddIn.IDs.MapPointTool); } } } diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs index 3a38287..e00ad61 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs @@ -67,7 +67,7 @@ protected virtual void OnActiveToolChanged(object obj) { string currentActiveToolName = obj as string; - if ((currentActiveToolName == "Esri_ArcMapAddinVisibility_MapPointTool")) + if ((currentActiveToolName == ThisAddIn.IDs.MapPointTool)) return; lastActiveToolName = currentActiveToolName; @@ -417,7 +417,7 @@ internal void RemoveGraphics(List guidList) /// internal virtual void OnActivateToolCommand(object obj) { - SetToolActiveInToolBar("Esri_ArcMapAddinVisibility_MapPointTool"); + SetToolActiveInToolBar(ThisAddIn.IDs.MapPointTool); } /// @@ -536,7 +536,7 @@ internal virtual void Reset(bool toolReset) { if (toolReset) { - DeactivateTool("Esri_ArcMapAddinVisibility_MapPointTool"); + DeactivateTool(ThisAddIn.IDs.MapPointTool); } Point1 = null; diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs index 6011391..f4216f8 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs @@ -299,7 +299,7 @@ internal override async Task CreateMapElement() await ExecuteVisibilityLLOS(); - DeactivateTool("ProAppVisibilityModule_MapTool"); + DeactivateTool(VisibilityMapTool.ToolId); GC.Collect(); GC.WaitForPendingFinalizers(); diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs index 15b9656..0e0c62e 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs @@ -161,7 +161,7 @@ public MapPointToolMode ToolMode ObserverToolActive = false; TargetToolActive = false; - DeactivateTool("ProAppVisibilityModule_MapTool"); + DeactivateTool(VisibilityMapTool.ToolId); } } } diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs index 3cc0c19..961797b 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs @@ -274,7 +274,7 @@ internal override async Task CreateMapElement() await ExecuteVisibilityRLOS(); - DeactivateTool("ProAppVisibilityModule_MapTool"); + DeactivateTool(VisibilityMapTool.ToolId); //await base.CreateMapElement(); } diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs index 9cc3898..e728ed2 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs @@ -385,7 +385,7 @@ private void OnCancelCommand(object obj) /// internal virtual void OnActivateToolCommand(object obj) { - FrameworkApplication.SetCurrentToolAsync("ProAppVisibilityModule_MapTool"); + FrameworkApplication.SetCurrentToolAsync(VisibilityMapTool.ToolId); } #endregion @@ -471,7 +471,7 @@ internal virtual async Task Reset(bool toolReset) { if (toolReset) { - DeactivateTool("ProAppVisibilityModule_MapTool"); + DeactivateTool(VisibilityMapTool.ToolId); } Point1 = null; @@ -694,7 +694,7 @@ private void OnActiveToolChanged(ArcGIS.Desktop.Framework.Events.ToolEventArgs a { string currentActiveToolName = args.CurrentID; - if (currentActiveToolName != "ProAppVisibilityModule_MapTool") + if (currentActiveToolName != VisibilityMapTool.ToolId) { lastActiveToolName = currentActiveToolName; } diff --git a/source/Visibility/ProAppVisibilityModule/VisibilityMapTool.cs b/source/Visibility/ProAppVisibilityModule/VisibilityMapTool.cs index a50b9be..e7693eb 100644 --- a/source/Visibility/ProAppVisibilityModule/VisibilityMapTool.cs +++ b/source/Visibility/ProAppVisibilityModule/VisibilityMapTool.cs @@ -30,6 +30,12 @@ public VisibilityMapTool() UseSnapping = true; } + public static string ToolId + { + // Important: this must match the Tool ID used in the DAML + get { return "ProAppVisibilityModule_MapTool"; } + } + protected override Task OnToolActivateAsync(bool active) { Mediator.NotifyColleagues(VisibilityLibrary.Constants.MAP_POINT_TOOL_ACTIVATED, active); From 21d78d762e99b69887db441a7812e455528409a8 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Fri, 10 Mar 2017 12:45:48 -0500 Subject: [PATCH 22/42] Issue #119 - add overall Sightline in Arcmap Also: 1. Changed line widths to match those used in Pro 2. Removed unused methods --- .../ViewModels/LLOSViewModel.cs | 17 +++++++++---- .../ViewModels/TabBaseViewModel.cs | 24 +++---------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs index 1715121..15baf6c 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs @@ -264,22 +264,31 @@ internal override void CreateMapElement() UpdateTargetObserverCount(DictionaryTargetObserverCount, targetPoint.Point); } + // First Add "SightLine" so it appears behind others + // Black = Not visible -or- White = Visible + if (targetIsVisible) + AddGraphicToMap(pcolPolyline, new RgbColorClass() { RGB = 0xFFFFFF }, false, + size: 6); // white line + else + AddGraphicToMap(pcolPolyline, new RgbColorClass() { RGB = 0x000000 }, false, + size: 6); // black line + if (polyVisible != null) { - AddGraphicToMap(polyVisible, new RgbColorClass() { Green = 255 }); + AddGraphicToMap(polyVisible, new RgbColorClass() { Green = 255 }, size: 5); } if (polyInvisible != null) { - AddGraphicToMap(polyInvisible, new RgbColorClass() { Red = 255 }); + AddGraphicToMap(polyInvisible, new RgbColorClass() { Red = 255 }, size: 3); } if (polyVisible == null && polyInvisible == null) { if (targetIsVisible) - AddGraphicToMap(pcol as IPolyline, new RgbColorClass() { Green = 255 }); + AddGraphicToMap(pcol as IPolyline, new RgbColorClass() { Green = 255 }, size: 3); else - AddGraphicToMap(pcol as IPolyline, new RgbColorClass() { Red = 255 }); + AddGraphicToMap(pcol as IPolyline, new RgbColorClass() { Red = 255 }, size: 3); } } diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs index e00ad61..54a4b72 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs @@ -612,13 +612,13 @@ internal string AddTextToMap(string text, IGeometry geom, IColor color, bool IsT /// Adds a graphic element to the map graphics container /// /// IGeometry - internal string AddGraphicToMap(IGeometry geom, IColor color, bool IsTempGraphic = false, esriSimpleMarkerStyle markerStyle = esriSimpleMarkerStyle.esriSMSCircle, int size = 5) + internal string AddGraphicToMap(IGeometry geom, IColor color, bool IsTempGraphic = false, + esriSimpleMarkerStyle markerStyle = esriSimpleMarkerStyle.esriSMSCircle, int size = 5) { if (geom == null || ArcMap.Document == null || ArcMap.Document.FocusMap == null) return string.Empty; IElement element = null; - double width = 2.0; geom.Project(ArcMap.Document.FocusMap.SpatialReference); @@ -644,7 +644,7 @@ internal string AddGraphicToMap(IGeometry geom, IColor color, bool IsTempGraphic var lineSymbol = new SimpleLineSymbolClass(); lineSymbol.Color = color; - lineSymbol.Width = width; + lineSymbol.Width = (double)size; le.Symbol = lineSymbol; } @@ -691,24 +691,6 @@ internal string AddGraphicToMap(IGeometry geom, IColor color, bool IsTempGraphic return eprop.Name; } - internal void AddGraphicToMap(IGeometry geom, IColor color) - { - AddGraphicToMap(geom, color, false); - } - - internal void AddGraphicToMap(IGeometry geom) - { - var rgbColor = new ESRI.ArcGIS.Display.RgbColorClass() { Red = 255 }; - AddGraphicToMap(geom, rgbColor); - } - internal void AddGraphicToMap(IGeometry geom, bool isTemp) - { - ESRI.ArcGIS.Display.IRgbColor rgbColor = new ESRI.ArcGIS.Display.RgbColorClass(); - rgbColor.Red = 255; - //ESRI.ArcGIS.Display.IColor color = rgbColor; // Implicit cast. - AddGraphicToMap(geom, rgbColor, isTemp); - } - internal DistanceTypes GetDistanceType(int linearUnitFactoryCode) { DistanceTypes distanceType = DistanceTypes.Meters; From 9e8e8d623ece9238d4677fc36e9c33fc50f0a296 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Tue, 14 Mar 2017 17:07:42 -0400 Subject: [PATCH 23/42] Clip FOV & Range Fix for Pro - Issue #125 --- .../Helpers/FeatureClassHelper.cs | 12 +- .../Helpers/GeometryHelper.cs | 109 ++++++++++++++++++ .../ProAppVisibilityModule.csproj | 3 +- .../ViewModels/ProRLOSViewModel.cs | 67 +++++++---- 4 files changed, 163 insertions(+), 28 deletions(-) create mode 100644 source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs diff --git a/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs b/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs index f617252..4957f58 100644 --- a/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs +++ b/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs @@ -332,7 +332,7 @@ public static async Task IntersectOutput(string inputRasterLayer, string outputP /// geoprocessing environments /// add to map or not /// - public static async Task CreateVisibility(string surfaceName, string observerFeatureClassName, string outRLOSFeatureClass, + public static async Task CreateVisibility(string surfaceName, string observerFeatureClassName, string outRLOSFeatureClass, double observerOffset, double surfaceOffset, double minDistance, double maxDistance, double horizontalStartAngle, double horizontalEndAngle, @@ -387,9 +387,17 @@ public static async Task CreateVisibility(string surfaceName, string observerFea if (result.IsFailed) { + // Provide the user some feedback of what went wrong + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + sb.AppendLine("Visibility_3d GP Tool FAILED:"); foreach (var msg in result.Messages) - Debug.Print(msg.Text); + sb.AppendLine(msg.Text); + + ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(sb.ToString(), + VisibilityLibrary.Properties.Resources.CaptionError); } + + return result.IsFailed == false; } /// diff --git a/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs b/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs new file mode 100644 index 0000000..d4cc43d --- /dev/null +++ b/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs @@ -0,0 +1,109 @@ +// Copyright 2016 Esri +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.Collections.Generic; + +using ArcGIS.Core.Geometry; + +namespace ProAppVisibilityModule.Helpers +{ + /// + /// Geometry Helper Utilities + /// + public static class GeometryHelper + { + /// + /// Returns a polygon with a circular ring sector (like a wiper blade swipe with inner and outer radius) + /// from the input parameters + /// + public static Geometry constructCircularRingSector(MapPoint centerPoint, + double innerDistanceInMapUnits, double outerDistanceInMapUnits, + double horizontalStartAngleInBearing, double horizontalEndAngleInBearing, + SpatialReference sr) + { + var points = new List(); + + MapPoint startPoint = null; + + if (innerDistanceInMapUnits == 0.0) + { + startPoint = centerPoint; + points.Add(startPoint); + } + + // Tricky - if angle cuts across 360, need to adjust for this case (ex. Angle: 270->90) + if (horizontalStartAngleInBearing > horizontalEndAngleInBearing) + horizontalStartAngleInBearing = -(360.0 - horizontalStartAngleInBearing); + + double minAngle = Math.Min(horizontalStartAngleInBearing, horizontalEndAngleInBearing); + double maxAngle = Math.Max(horizontalStartAngleInBearing, horizontalEndAngleInBearing); + double step = 5.0; + + // Draw Outer Arc of Ring + // Implementation Note: because of the unique shape of this ring, + // it was easier to manually create these points than use EllipticArcBuilder + for (double angle = minAngle; angle <= maxAngle; angle += step) + { + double cartesianAngle = (450 - angle) % 360; + double angleInRadians = cartesianAngle * (Math.PI / 180.0); + double x = centerPoint.X + (outerDistanceInMapUnits * Math.Cos(angleInRadians)); + double y = centerPoint.Y + (outerDistanceInMapUnits * Math.Sin(angleInRadians)); + + MapPoint pointToAdd = MapPointBuilder.CreateMapPoint(x, y, sr); + points.Add(pointToAdd); + + if (startPoint == null) + startPoint = pointToAdd; + } + + if (innerDistanceInMapUnits > 0.0) + { + // Draw Inner Arc of Ring - if inner distance set + for (double angle = maxAngle; angle >= minAngle; angle -= step) + { + double cartesianAngle = (450 - angle) % 360; + double angleInRadians = cartesianAngle * (Math.PI / 180.0); + double x = centerPoint.X + (innerDistanceInMapUnits * Math.Cos(angleInRadians)); + double y = centerPoint.Y + (innerDistanceInMapUnits * Math.Sin(angleInRadians)); + + points.Add(MapPointBuilder.CreateMapPoint(x, y, sr)); + } + } + + // close Polygon + points.Add(startPoint); + + PolygonBuilder pb = new PolygonBuilder(); + pb.AddPart(points); + + // TRICKY: Observer Point must be included in GP Tool Mask, + // so if masking mimimum distance, add observer point back in + if (innerDistanceInMapUnits > 0.0) + { + // Buffer 1% of distance + var observerBuffer = GeometryEngine.Buffer(centerPoint, outerDistanceInMapUnits * 0.01); + + // Tricky/Workaround: GP mask did not work with Multiparts with arcs so had to convert to densified polygon + var observerBufferDensified = GeometryEngine.DensifyByLength(observerBuffer, outerDistanceInMapUnits * 0.002); + var observerBufferPolygon = observerBufferDensified as Polygon; + + pb.AddPart(observerBufferPolygon.Points); + } + + return pb.ToGeometry(); + } + } + +} diff --git a/source/Visibility/ProAppVisibilityModule/ProAppVisibilityModule.csproj b/source/Visibility/ProAppVisibilityModule/ProAppVisibilityModule.csproj index 1ab9865..c1c639a 100644 --- a/source/Visibility/ProAppVisibilityModule/ProAppVisibilityModule.csproj +++ b/source/Visibility/ProAppVisibilityModule/ProAppVisibilityModule.csproj @@ -87,6 +87,7 @@ + @@ -156,4 +157,4 @@ - + \ No newline at end of file diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs index 961797b..96881d0 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs @@ -335,12 +335,13 @@ private async Task ExecuteVisibilityRLOS() string maskFeatureClassName = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSMaskLayerName; - await CreateMask(RLOSMaskLayerName, maxDistanceInMapUnits, surfaceSR); + await CreateMask(RLOSMaskLayerName, minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, + horizontalEndAngleInDegrees, surfaceSR); var environments = Geoprocessing.MakeEnvironmentArray(mask: maskFeatureClassName, overwriteoutput: true); var rlosOutputLayer = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSOutputLayerName; - await FeatureClassHelper.CreateVisibility(SelectedSurfaceName, ObserversLayerName, + bool vizSuccess = await FeatureClassHelper.CreateVisibility(SelectedSurfaceName, ObserversLayerName, rlosOutputLayer, observerOffsetInMapZUnits, surfaceOffsetInMapZUnits, minDistanceInMapUnits, maxDistanceInMapUnits, @@ -350,6 +351,9 @@ await FeatureClassHelper.CreateVisibility(SelectedSurfaceName, ObserversLayerNam environments, false); + if (!vizSuccess) + return; + var rlosConvertedPolygonsLayer = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSConvertedPolygonsLayerName; await FeatureClassHelper.IntersectOutput(rlosOutputLayer, rlosConvertedPolygonsLayer, false, "Value"); @@ -396,7 +400,9 @@ await FeatureClassHelper.CreateVisibility(SelectedSurfaceName, ObserversLayerNam /// /// /// Task - private async Task CreateMask(string maskFeatureClassName, double bufferDistance, SpatialReference surfaceSR) + private async Task CreateMask(string maskFeatureClassName, + double minDistanceInMapUnits, double maxDistanceInMapUnits, + double horizontalStartAngleInDegrees, double horizontalEndAngleInDegrees, SpatialReference surfaceSR) { // create new await FeatureClassHelper.CreateLayer(maskFeatureClassName, "POLYGON", false, false); @@ -414,32 +420,43 @@ await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(async () => EditOperation editOperation = new EditOperation(); editOperation.Callback(context => { - try - { - var shapeFieldName = fcDefinition.GetShapeField(); + try + { + var shapeFieldName = fcDefinition.GetShapeField(); - foreach (var observer in ObserverAddInPoints) + foreach (var observer in ObserverAddInPoints) + { + using (var rowBuffer = enterpriseFeatureClass.CreateRowBuffer()) { - using (var rowBuffer = enterpriseFeatureClass.CreateRowBuffer()) + // Either the field index or the field name can be used in the indexer. + // project the point here or the buffer tool may use an angular unit and run forever + var point = GeometryEngine.Project(observer.Point, surfaceSR); + Geometry polygon = null; + + if (ShowNonVisibleData && + !((LeftHorizontalFOV == 0.0) && (RightHorizontalFOV == 360.0))) { - // Either the field index or the field name can be used in the indexer. - // project the point here or the buffer tool may use an angular unit and run forever - var point = GeometryEngine.Project(observer.Point, surfaceSR); - var polygon = GeometryEngine.Buffer(point, bufferDistance); - rowBuffer[shapeFieldName] = polygon; - - using (var feature = enterpriseFeatureClass.CreateRow(rowBuffer)) - { - //To Indicate that the attribute table has to be updated - context.Invalidate(feature); - } + polygon = GeometryHelper.constructCircularRingSector(point as MapPoint, + minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, + horizontalEndAngleInDegrees, surfaceSR); } - } - } - catch (GeodatabaseException exObj) - { - message = exObj.Message; - } + else + { + polygon = GeometryEngine.Buffer(point, maxDistanceInMapUnits); + } + + rowBuffer[shapeFieldName] = polygon; + + Feature feature = enterpriseFeatureClass.CreateRow(rowBuffer); + feature.Store(); + context.Invalidate(feature); + } // using + } // for each + } + catch (GeodatabaseException exObj) + { + message = exObj.Message; + } }, enterpriseFeatureClass); creationResult = await editOperation.ExecuteAsync(); From 9a9b61aba702b11e338193b694d0ba5f2a65ffcd Mon Sep 17 00:00:00 2001 From: Joe Bayles Date: Tue, 21 Mar 2017 14:13:57 -0400 Subject: [PATCH 24/42] Update README.md Correcting the Esri Language Tag for the GitHub.io page. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1be9666..a449d9a 100644 --- a/README.md +++ b/README.md @@ -120,4 +120,4 @@ limitations under the License. A copy of the license is available in the repository's [license.txt](license.txt) file. [](Esri Tags: Military Analyst Defense ArcGIS ArcObjects .NET WPF ArcGISSolutions ArcMap ArcPro Add-In Military-Tools-for-ArcGIS) -[](Esri Language: C#) +[](Esri Language: C-Sharp) From dc5f49c9308132d9d54bcc9994366299fcdcad17 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Wed, 22 Mar 2017 11:23:53 -0400 Subject: [PATCH 25/42] Issue #124 - clip RLOS range fan in ArcMap --- .../ViewModels/RLOSViewModel.cs | 111 ++++++++++++++---- 1 file changed, 85 insertions(+), 26 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs index 0ef6d91..b328193 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs @@ -128,6 +128,76 @@ public override bool CanCreateElement } } + /// + /// Returns a polygon with a range fan(circular ring sector - like a donut wedge or wiper blade swipe with inner and outer radius) + /// from the input parameters + /// + public static IGeometry ConstructRangeFan(IPoint centerPoint, + double innerDistanceInMapUnits, double outerDistanceInMapUnits, + double horizontalStartAngleInBearing, double horizontalEndAngleInBearing, + ISpatialReference sr) + { + // Create Polygon to store points + IPointCollection points = new PolygonClass(); + + IPoint startPoint = null; + + if (innerDistanceInMapUnits == 0.0) + { + startPoint = centerPoint; + points.AddPoint(startPoint); + } + + // Tricky - if angle cuts across 360, need to adjust for this case (ex.Angle: 270->90) + if (horizontalStartAngleInBearing > horizontalEndAngleInBearing) + horizontalStartAngleInBearing = -(360.0 - horizontalStartAngleInBearing); + + double minAngle = Math.Min(horizontalStartAngleInBearing, horizontalEndAngleInBearing); + double maxAngle = Math.Max(horizontalStartAngleInBearing, horizontalEndAngleInBearing); + double step = 5.0; + + // Draw Outer Arc of Ring + // Implementation Note: because of the unique shape of this ring, + // it was easier to manually create these points than use IConstructCircularArc + for (double angle = minAngle; angle <= maxAngle; angle += step) + { + double cartesianAngle = (450 - angle) % 360; + double angleInRadians = cartesianAngle * (Math.PI / 180.0); + double x = centerPoint.X + (outerDistanceInMapUnits * Math.Cos(angleInRadians)); + double y = centerPoint.Y + (outerDistanceInMapUnits * Math.Sin(angleInRadians)); + + IPoint pointToAdd = new PointClass(); + pointToAdd.PutCoords(x, y); + pointToAdd.SpatialReference = sr; + points.AddPoint(pointToAdd); + + if (startPoint == null) + startPoint = pointToAdd; + } + + if (innerDistanceInMapUnits > 0.0) + { + // Draw Inner Arc of Ring - if inner distance set + for (double angle = maxAngle; angle >= minAngle; angle -= step) + { + double cartesianAngle = (450 - angle) % 360; + double angleInRadians = cartesianAngle * (Math.PI / 180.0); + double x = centerPoint.X + (innerDistanceInMapUnits * Math.Cos(angleInRadians)); + double y = centerPoint.Y + (innerDistanceInMapUnits * Math.Sin(angleInRadians)); + + IPoint pointToAdd = new PointClass(); + pointToAdd.PutCoords(x, y); + pointToAdd.SpatialReference = sr; + points.AddPoint(pointToAdd); + } + } + + // close Polygon + points.AddPoint(startPoint); + + return points as IGeometry; + } + /// /// Where all of the work is done. Override from TabBaseViewModel /// @@ -140,8 +210,6 @@ internal override void CreateMapElement() if (!CanCreateElement || ArcMap.Document == null || ArcMap.Document.FocusMap == null || string.IsNullOrWhiteSpace(SelectedSurfaceName)) return; - //base.CreateMapElement(); - var surface = GetSurfaceFromMapByName(ArcMap.Document.FocusMap, SelectedSurfaceName); if (surface == null) @@ -166,7 +234,6 @@ internal override void CreateMapElement() using (ComReleaser oComReleaser = new ComReleaser()) { - // Create feature workspace IFeatureWorkspace workspace = CreateFeatureWorkspace("tempWorkspace"); @@ -189,30 +256,22 @@ internal override void CreateMapElement() double finalBottomVerticalFOV = GetAngularDistance(ArcMap.Document.FocusMap, BottomVerticalFOV, AngularUnitType); double finalTopVerticalFOV = GetAngularDistance(ArcMap.Document.FocusMap, TopVerticalFOV, AngularUnitType); - // Out radius geometries - List radius2GeomList = new List(); - List radius1_2GeomList = new List(); - List donutGeomList = new List(); + // Output radius geometries + List maxRangeBufferGeomList = new List(); + List rangeFanGeomList = new List(); foreach (var observerPoint in ObserverAddInPoints) { - // Create buffer geometries for final Min/Max distance + // Create 2 clipping geometries: + // 1. maxRangeBufferGeomList - is used to clip the viz GP output because 2. doesn't work directly + // 2. rangeFanGeomList - this is the range fan input by the user ITopologicalOperator topologicalOperator = observerPoint.Point as ITopologicalOperator; - IGeometry geom = topologicalOperator.Buffer(finalMaxDistance); - radius2GeomList.Add(geom); - radius1_2GeomList.Add(geom); - if (finalMinDistance > 0) - { - IGeometry geom2 = topologicalOperator.Buffer(finalMinDistance); + IGeometry geomBuffer = topologicalOperator.Buffer(finalMaxDistance); + maxRangeBufferGeomList.Add(geomBuffer); - ITopologicalOperator eraseTopo = geom as ITopologicalOperator; - IGeometry erasedGeom = eraseTopo.Difference(geom2); - donutGeomList.Add(erasedGeom); - } - else - { - radius1_2GeomList.Add(geom); - } + IGeometry geomRangeFan = ConstructRangeFan(observerPoint.Point, finalMinDistance, finalMaxDistance, + finalLeftHorizontalFOV, finalRightHorizontalFOV, SelectedSurfaceSpatialRef); + rangeFanGeomList.Add(geomRangeFan); double z1 = surface.GetElevation(observerPoint.Point) + finalObserverOffset; @@ -272,7 +331,7 @@ internal override void CreateMapElement() gp.AddOutputsToMap = false; // Add a mask to buffer the output to selected distance - SetGPMask(workspace, radius2GeomList, gp, "radiusMask"); + SetGPMask(workspace, maxRangeBufferGeomList, gp, "radiusMask"); object oResult = gp.Execute("Visibility_sa", parameters, null); IGeoProcessorResult ipResult = (IGeoProcessorResult)oResult; @@ -281,8 +340,8 @@ internal override void CreateMapElement() gp = null; GC.Collect(); - // Add buffer geometries to the map - foreach (IGeometry geom in radius1_2GeomList) + // Add the range fan geometries to the map + foreach (IGeometry geom in rangeFanGeomList) { var color = new RgbColorClass() { Blue = 255 } as IColor; AddGraphicToMap(geom, color, true); @@ -291,7 +350,7 @@ internal override void CreateMapElement() IRasterLayer outputRasterLayer = new RasterLayerClass(); outputRasterLayer.CreateFromFilePath(outPath); - string fcName = IntersectOutput(outputRasterLayer, ipDataset, workspace, donutGeomList); + string fcName = IntersectOutput(outputRasterLayer, ipDataset, workspace, rangeFanGeomList); IFeatureClass finalFc = workspace.OpenFeatureClass(fcName); From ee1b33414042c9c79ce1aa1fc0f0bfb2ae5ddb1e Mon Sep 17 00:00:00 2001 From: Patrick Hill Date: Thu, 23 Mar 2017 08:52:51 -0700 Subject: [PATCH 26/42] fix tool icon on deactivate --- source/Visibility/ArcMapAddinVisibility/MapPointTool.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs b/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs index 12b5643..5e3f17a 100644 --- a/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs +++ b/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs @@ -85,7 +85,7 @@ protected override void OnActivate() protected override bool OnDeactivate() { Mediator.NotifyColleagues(VisibilityLibrary.Constants.MAP_POINT_TOOL_DEACTIVATED, false); - + this.Cursor = Cursors.Default; return base.OnDeactivate(); } From 48d4944ecd3bab44ad8a3047d262dfe3b2cd02b8 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Thu, 23 Mar 2017 17:50:06 -0400 Subject: [PATCH 27/42] Rename method to ConstructRangeFan --- .gitignore | 2 ++ .../ProAppVisibilityModule/Helpers/GeometryHelper.cs | 8 ++++---- .../ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 169e828..94d29f9 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,8 @@ develop-eggs [Bb]in/ [Oo]bj/ *.vshost.* +*.VC.db +*.VC.opendb ################# ## Eclipse diff --git a/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs b/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs index d4cc43d..f70518c 100644 --- a/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs +++ b/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs @@ -25,10 +25,10 @@ namespace ProAppVisibilityModule.Helpers public static class GeometryHelper { /// - /// Returns a polygon with a circular ring sector (like a wiper blade swipe with inner and outer radius) + /// Returns a polygon with a range fan(circular ring sector - like a donut wedge or wiper blade swipe with inner and outer radius) /// from the input parameters /// - public static Geometry constructCircularRingSector(MapPoint centerPoint, + public static Geometry ConstructRangeFan(MapPoint centerPoint, double innerDistanceInMapUnits, double outerDistanceInMapUnits, double horizontalStartAngleInBearing, double horizontalEndAngleInBearing, SpatialReference sr) @@ -92,8 +92,8 @@ public static Geometry constructCircularRingSector(MapPoint centerPoint, // so if masking mimimum distance, add observer point back in if (innerDistanceInMapUnits > 0.0) { - // Buffer 1% of distance - var observerBuffer = GeometryEngine.Buffer(centerPoint, outerDistanceInMapUnits * 0.01); + // Buffer % of observer distance + var observerBuffer = GeometryEngine.Buffer(centerPoint, outerDistanceInMapUnits * 0.025); // Tricky/Workaround: GP mask did not work with Multiparts with arcs so had to convert to densified polygon var observerBufferDensified = GeometryEngine.DensifyByLength(observerBuffer, outerDistanceInMapUnits * 0.002); diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs index 96881d0..d57b372 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs @@ -436,7 +436,7 @@ await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(async () => if (ShowNonVisibleData && !((LeftHorizontalFOV == 0.0) && (RightHorizontalFOV == 360.0))) { - polygon = GeometryHelper.constructCircularRingSector(point as MapPoint, + polygon = GeometryHelper.ConstructRangeFan(point as MapPoint, minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, horizontalEndAngleInDegrees, surfaceSR); } From 53bcd703dabd2d61b39ac7fe2e8a7cefad7d4d9b Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Mon, 27 Mar 2017 14:33:52 -0400 Subject: [PATCH 28/42] Add intersect range fan to processing --- .../Helpers/FeatureClassHelper.cs | 42 +++++++++++++++++-- .../Helpers/GeometryHelper.cs | 37 +++++++++------- .../ViewModels/ProRLOSViewModel.cs | 24 +++++++---- 3 files changed, 79 insertions(+), 24 deletions(-) diff --git a/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs b/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs index 4957f58..08f6f6f 100644 --- a/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs +++ b/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs @@ -290,14 +290,24 @@ public static async Task Delete(string name) /// /// /// - public static async Task IntersectOutput(string inputRasterLayer, string outputPolygonLayer, bool simplify, string rasterField) + public static async Task IntersectOutput(string inputRasterLayer, string outputPolygonLayer, + bool simplify, string rasterField, string intersectMaskFeatureClass) { + string rasterToPolyLayer = outputPolygonLayer; + + bool addToMap = true; + if (!string.IsNullOrEmpty(intersectMaskFeatureClass)) + { + rasterToPolyLayer += "_rasterToPoly"; + addToMap = false; + } + //RasterToPolygon_conversion (in_raster, out_polygon_features, {simplify}, {raster_field}) List arguments = new List(); // in_raster arguments.Add(inputRasterLayer); // out_polygon_features - arguments.Add(outputPolygonLayer); + arguments.Add(rasterToPolyLayer); // {simplify} arguments.Add(simplify); // {raster_field} @@ -305,13 +315,39 @@ public static async Task IntersectOutput(string inputRasterLayer, string outputP var environments = Geoprocessing.MakeEnvironmentArray(overwriteoutput: true); - IGPResult result = await Geoprocessing.ExecuteToolAsync("RasterToPolygon_conversion", Geoprocessing.MakeValueArray(arguments.ToArray()), environments); + IGPResult result = await Geoprocessing.ExecuteToolAsync("RasterToPolygon_conversion", + Geoprocessing.MakeValueArray(arguments.ToArray()), environments, + null, null, addToMap ? GPExecuteToolFlags.Default : GPExecuteToolFlags.None); if (result.IsFailed) { foreach (var msg in result.Messages) Debug.Print(msg.Text); } + + if (string.IsNullOrEmpty(intersectMaskFeatureClass)) + return; + + // Intersect_analysis('infeatures';'in_features', 'out_feature_class', 'NO_FID') + List argumentsIntersect = new List(); + // in_features + string intersectLayers = rasterToPolyLayer + ';' + intersectMaskFeatureClass; + argumentsIntersect.Add(intersectLayers); + // out_polygon_features + argumentsIntersect.Add(outputPolygonLayer); + // Don't include FIDs in join (or they will both appear in output) + argumentsIntersect.Add("NO_FID"); + + // if non-empty, intersect with intersectMaskFeatureClass + result = await Geoprocessing.ExecuteToolAsync("Intersect_analysis", + Geoprocessing.MakeValueArray(argumentsIntersect.ToArray()), environments); + + if (result.IsFailed) + { + foreach (var msg in result.Messages) + Debug.Print(msg.Text); + } + } /// diff --git a/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs b/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs index f70518c..8e20702 100644 --- a/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs +++ b/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs @@ -33,6 +33,29 @@ public static Geometry ConstructRangeFan(MapPoint centerPoint, double horizontalStartAngleInBearing, double horizontalEndAngleInBearing, SpatialReference sr) { + // if full circle(or greater), return donut section with inner/outer rings + if ((horizontalStartAngleInBearing <= 0.0) && (horizontalEndAngleInBearing >= 360.0)) + { + // Just add 2 concentric circle buffers + PolygonBuilder donutPb = new PolygonBuilder(); + + var outerBuffer = GeometryEngine.Buffer(centerPoint, outerDistanceInMapUnits); + // Tricky/Workaround: GP mask/intersect did not work with Multiparts with arcs so had to convert to densified polygon + var outerBufferDensified = GeometryEngine.DensifyByLength(outerBuffer, outerDistanceInMapUnits * 0.005); + var outerBufferPolygon = outerBufferDensified as Polygon; + + donutPb.AddPart(outerBufferPolygon.Points); + + var innerBuffer = GeometryEngine.Buffer(centerPoint, innerDistanceInMapUnits); + var innerBufferDensified = GeometryEngine.DensifyByLength(innerBuffer, innerDistanceInMapUnits * 0.005); + var innerBufferPolygon = innerBufferDensified as Polygon; + + donutPb.AddPart(innerBufferPolygon.Points); + + return donutPb.ToGeometry(); + } + + // Otherwise if range fan, construct that var points = new List(); MapPoint startPoint = null; @@ -88,20 +111,6 @@ public static Geometry ConstructRangeFan(MapPoint centerPoint, PolygonBuilder pb = new PolygonBuilder(); pb.AddPart(points); - // TRICKY: Observer Point must be included in GP Tool Mask, - // so if masking mimimum distance, add observer point back in - if (innerDistanceInMapUnits > 0.0) - { - // Buffer % of observer distance - var observerBuffer = GeometryEngine.Buffer(centerPoint, outerDistanceInMapUnits * 0.025); - - // Tricky/Workaround: GP mask did not work with Multiparts with arcs so had to convert to densified polygon - var observerBufferDensified = GeometryEngine.DensifyByLength(observerBuffer, outerDistanceInMapUnits * 0.002); - var observerBufferPolygon = observerBufferDensified as Polygon; - - pb.AddPart(observerBufferPolygon.Points); - } - return pb.ToGeometry(); } } diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs index d57b372..23fe78a 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs @@ -332,13 +332,13 @@ private async Task ExecuteVisibilityRLOS() var verticalLowerAngleInDegrees = GetAngularDistanceFromTo(AngularUnitType, AngularTypes.DEGREES, BottomVerticalFOV); await FeatureClassHelper.UpdateShapeWithZ(ObserversLayerName, VisibilityLibrary.Properties.Resources.ZFieldName, observerOffsetInMapZUnits); - - string maskFeatureClassName = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSMaskLayerName; await CreateMask(RLOSMaskLayerName, minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, horizontalEndAngleInDegrees, surfaceSR); - var environments = Geoprocessing.MakeEnvironmentArray(mask: maskFeatureClassName, overwriteoutput: true); + string maxRangeMaskFeatureClassName = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSMaskLayerName; + var environments = Geoprocessing.MakeEnvironmentArray(mask: maxRangeMaskFeatureClassName, overwriteoutput: true); + var rlosOutputLayer = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSOutputLayerName; bool vizSuccess = await FeatureClassHelper.CreateVisibility(SelectedSurfaceName, ObserversLayerName, @@ -356,7 +356,17 @@ await CreateMask(RLOSMaskLayerName, minDistanceInMapUnits, maxDistanceInMapUnits var rlosConvertedPolygonsLayer = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSConvertedPolygonsLayerName; - await FeatureClassHelper.IntersectOutput(rlosOutputLayer, rlosConvertedPolygonsLayer, false, "Value"); + string rangeFanMaskFeatureClassName = string.Empty; + if ((MinDistance > 0) || !((LeftHorizontalFOV == 0.0) && (RightHorizontalFOV == 360.0))) + { + string RLOSRangeFanMaskLayerName = "RangeFan_" + RLOSMaskLayerName; + rangeFanMaskFeatureClassName = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSRangeFanMaskLayerName; + + await CreateMask(RLOSRangeFanMaskLayerName, minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, + horizontalEndAngleInDegrees, surfaceSR, true); + } + + await FeatureClassHelper.IntersectOutput(rlosOutputLayer, rlosConvertedPolygonsLayer, false, "Value", rangeFanMaskFeatureClassName); await FeatureClassHelper.CreateUniqueValueRenderer(GetLayerFromMapByName(RLOSConvertedPolygonsLayerName) as FeatureLayer, ShowNonVisibleData, RLOSConvertedPolygonsLayerName); @@ -402,7 +412,8 @@ await CreateMask(RLOSMaskLayerName, minDistanceInMapUnits, maxDistanceInMapUnits /// Task private async Task CreateMask(string maskFeatureClassName, double minDistanceInMapUnits, double maxDistanceInMapUnits, - double horizontalStartAngleInDegrees, double horizontalEndAngleInDegrees, SpatialReference surfaceSR) + double horizontalStartAngleInDegrees, double horizontalEndAngleInDegrees, + SpatialReference surfaceSR, bool constructRangeFans = false) { // create new await FeatureClassHelper.CreateLayer(maskFeatureClassName, "POLYGON", false, false); @@ -433,8 +444,7 @@ await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(async () => var point = GeometryEngine.Project(observer.Point, surfaceSR); Geometry polygon = null; - if (ShowNonVisibleData && - !((LeftHorizontalFOV == 0.0) && (RightHorizontalFOV == 360.0))) + if (constructRangeFans) { polygon = GeometryHelper.ConstructRangeFan(point as MapPoint, minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, From f84320e02d100f20603a904ba6e45860493f88dd Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Wed, 29 Mar 2017 21:32:03 -0400 Subject: [PATCH 29/42] Changes from review and testing Also added test method --- .../ViewModels/RLOSViewModel.cs | 42 +++++- .../ProAppVisibilityModuleTests.cs | 114 +++++++++++++++++ .../Helpers/FeatureClassHelper.cs | 120 ++++++++---------- .../Helpers/GeometryHelper.cs | 53 +++++--- .../ViewModels/ProRLOSViewModel.cs | 8 +- 5 files changed, 247 insertions(+), 90 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs index b328193..7404472 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs @@ -137,9 +137,47 @@ public static IGeometry ConstructRangeFan(IPoint centerPoint, double horizontalStartAngleInBearing, double horizontalEndAngleInBearing, ISpatialReference sr) { + if ((centerPoint == null) || (sr == null) || + (innerDistanceInMapUnits < 0.0) || (outerDistanceInMapUnits < 0.0) || + (horizontalStartAngleInBearing < 0.0) || (horizontalStartAngleInBearing > 360.0) || + (horizontalEndAngleInBearing < 0.0) || (horizontalEndAngleInBearing > 360.0)) + return null; + + // Tricky - if angle cuts across 360, need to adjust for this case (ex.Angle: 270->90) + if (horizontalStartAngleInBearing > horizontalEndAngleInBearing) + horizontalStartAngleInBearing = -(360.0 - horizontalStartAngleInBearing); + + double deltaAngle = Math.Abs(horizontalStartAngleInBearing - horizontalEndAngleInBearing); + // Create Polygon to store points IPointCollection points = new PolygonClass(); + // if full circle(or greater), return donut section with inner/outer rings + if ((deltaAngle == 0.0) || (deltaAngle >= 360.0)) + { + IGeometryCollection geometryCollection = points as IGeometryCollection; + + ICircularArc circularArcOuter = new CircularArcClass(); + ISegmentCollection ringOuter = new RingClass(); + circularArcOuter.PutCoordsByAngle(centerPoint, 0.0, 2 * Math.PI, outerDistanceInMapUnits); + ringOuter.AddSegment(circularArcOuter as ISegment); + geometryCollection.AddGeometry(ringOuter as IGeometry); + + if (innerDistanceInMapUnits > 0.0) + { + ICircularArc circularArcInner = new CircularArcClass(); + ISegmentCollection ringInner = new RingClass(); + circularArcInner.PutCoordsByAngle(centerPoint, 0.0, 2 * Math.PI, innerDistanceInMapUnits); + ringInner.AddSegment(circularArcInner as ISegment); + geometryCollection.AddGeometry(ringInner as IGeometry); + } + + (points as ITopologicalOperator).Simplify(); + + return points as IGeometry; + } + + // Otherwise if range fan, construct that IPoint startPoint = null; if (innerDistanceInMapUnits == 0.0) @@ -148,10 +186,6 @@ public static IGeometry ConstructRangeFan(IPoint centerPoint, points.AddPoint(startPoint); } - // Tricky - if angle cuts across 360, need to adjust for this case (ex.Angle: 270->90) - if (horizontalStartAngleInBearing > horizontalEndAngleInBearing) - horizontalStartAngleInBearing = -(360.0 - horizontalStartAngleInBearing); - double minAngle = Math.Min(horizontalStartAngleInBearing, horizontalEndAngleInBearing); double maxAngle = Math.Max(horizontalStartAngleInBearing, horizontalEndAngleInBearing); double step = 5.0; diff --git a/source/Visibility/ProAppVisibilityModule.Tests/ProAppVisibilityModuleTests.cs b/source/Visibility/ProAppVisibilityModule.Tests/ProAppVisibilityModuleTests.cs index ee1f629..1cd7767 100644 --- a/source/Visibility/ProAppVisibilityModule.Tests/ProAppVisibilityModuleTests.cs +++ b/source/Visibility/ProAppVisibilityModule.Tests/ProAppVisibilityModuleTests.cs @@ -92,5 +92,119 @@ public void ProCreateLLOSViewModelTest() Assert.IsNotNull(llosViewModel.TargetAddInPoints); } + [TestMethod, Description("Tests creating RangeFans")] + [TestCategory("ArcGISPro")] + public void TestGeometryHelperConstructRangeFan() + { + SpatialReference sr = SpatialReferences.WGS84; + + MapPoint centerPoint1 = MapPointBuilder.CreateMapPoint(10.0, 20.0, sr); + MapPoint centerPoint2 = MapPointBuilder.CreateMapPoint(-10.0, 20.0, sr); + MapPoint centerPoint3 = MapPointBuilder.CreateMapPoint(10.0, -20.0, sr); + MapPoint centerPoint4 = MapPointBuilder.CreateMapPoint(-10.0, -20.0, sr); + MapPoint centerPoint5 = MapPointBuilder.CreateMapPoint(0.0, 0.0, sr); + + MapPoint[] mapPoints = { centerPoint1, centerPoint2, centerPoint3, centerPoint4, centerPoint5 }; + + foreach (MapPoint centerPoint in mapPoints) + { + /////////////////////////////////////////////// + // Basic Test + double minDistanceInMapUnits = 1.0; + double maxDistanceInMapUnits = 2.0; + double horizontalStartAngleInDegrees = 45.0; + double horizontalEndAngleInDegrees = 90.0; + double stepAngle = 5.0; + Geometry polygon = Helpers.GeometryHelper.ConstructRangeFan(centerPoint, + minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, + horizontalEndAngleInDegrees, sr, stepAngle); + Assert.IsNotNull(polygon); + Assert.IsTrue(polygon.PointCount > 20); + /////////////////////////////////////////////// + + /////////////////////////////////////////////// + // range fan, crossing 360 + horizontalStartAngleInDegrees = 315.0; + horizontalEndAngleInDegrees = 45.0; + minDistanceInMapUnits = 1.0; + maxDistanceInMapUnits = 2.0; + stepAngle = 5.0; + polygon = Helpers.GeometryHelper.ConstructRangeFan(centerPoint, + minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, + horizontalEndAngleInDegrees, sr, stepAngle); + Assert.IsNotNull(polygon); + Assert.IsTrue(polygon.PointCount > 38); + /////////////////////////////////////////////// + + /////////////////////////////////////////////// + // full circle/360 degrees, 2 circles + horizontalStartAngleInDegrees = 0.0; + horizontalEndAngleInDegrees = 360.0; + minDistanceInMapUnits = 1.0; + maxDistanceInMapUnits = 2.0; + polygon = Helpers.GeometryHelper.ConstructRangeFan(centerPoint, + minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, + horizontalEndAngleInDegrees, sr, stepAngle); + Assert.IsNotNull(polygon); + Assert.IsTrue(GeometryEngine.Length(polygon) >= minDistanceInMapUnits * 4 * Math.PI); + /////////////////////////////////////////////// + + /////////////////////////////////////////////// + // full circle/360 degrees, 1 circle + horizontalStartAngleInDegrees = 0.0; + horizontalEndAngleInDegrees = 360.0; + minDistanceInMapUnits = 0.0; + maxDistanceInMapUnits = 2.0; + polygon = Helpers.GeometryHelper.ConstructRangeFan(centerPoint, + minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, + horizontalEndAngleInDegrees, sr, stepAngle); + Assert.IsNotNull(polygon); + Assert.IsTrue(GeometryEngine.Length(polygon) >= maxDistanceInMapUnits * 2 * Math.PI); + /////////////////////////////////////////////// + + /////////////////////////////////////////////// + // full circle/360 degrees, 1 circle - start/stop angle != 0,360 + horizontalStartAngleInDegrees = 10.0; + horizontalEndAngleInDegrees = 10.0; + minDistanceInMapUnits = 0.0; + maxDistanceInMapUnits = 2.0; + polygon = Helpers.GeometryHelper.ConstructRangeFan(centerPoint, + minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, + horizontalEndAngleInDegrees, sr, stepAngle); + Assert.IsNotNull(polygon); + Assert.IsTrue(GeometryEngine.Length(polygon) >= maxDistanceInMapUnits * 2 * Math.PI); + /////////////////////////////////////////////// + + /////////////////////////////////////////////// + // bad input, negative distance + horizontalStartAngleInDegrees = 120.0; + horizontalEndAngleInDegrees = 180.0; + minDistanceInMapUnits = 0.0; + maxDistanceInMapUnits = -2.0; + polygon = Helpers.GeometryHelper.ConstructRangeFan(centerPoint, + minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, + horizontalEndAngleInDegrees, sr, stepAngle); + Assert.IsNull(polygon); + /////////////////////////////////////////////// + + /////////////////////////////////////////////// + // null center point + polygon = Helpers.GeometryHelper.ConstructRangeFan(null, + minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, + horizontalEndAngleInDegrees, sr); + Assert.IsNull(polygon); + /////////////////////////////////////////////// + + /////////////////////////////////////////////// + // null SR + polygon = Helpers.GeometryHelper.ConstructRangeFan(centerPoint, + minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, + horizontalEndAngleInDegrees, null); + Assert.IsNull(polygon); + /////////////////////////////////////////////// + } + + } + } } diff --git a/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs b/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs index 08f6f6f..7628528 100644 --- a/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs +++ b/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs @@ -43,7 +43,7 @@ public class FeatureClassHelper /// POLYLINE /// POLYGON /// - public static async Task CreateLayer(string featureclassName, string featureclassType, bool zEnabled, bool addToMap) + public static async Task CreateLayer(string featureclassName, string featureclassType, bool zEnabled, bool addToMap) { List arguments = new List(); // store the results in the default geodatabase @@ -73,17 +73,7 @@ public static async Task CreateLayer(string featureclassName, string featureclas null, addToMap ? GPExecuteToolFlags.Default : GPExecuteToolFlags.None); - if (result.IsFailed) - { - foreach (var msg in result.Messages) - Debug.Print(msg.Text); - - // If the tool failed, try to remove the table that was created so execution will run next time - //List args = new List(); - //args.Add(outLineFeatureLayer); - //IGPResult result2 = await Geoprocessing.ExecuteToolAsync("Delete_management", Geoprocessing.MakeValueArray(args.ToArray()), environments, flags: GPExecuteToolFlags.Default); - - } + return isResultGoodAndReportMessages(result, "CreateFeatureclass_management"); } /// @@ -135,6 +125,7 @@ public static async Task JoinField(string inData, string inField, string joinTab IGPResult result = await Geoprocessing.ExecuteToolAsync("JoinField_management", Geoprocessing.MakeValueArray(arguments.ToArray())); } + /// /// Create sight lines /// @@ -144,7 +135,7 @@ public static async Task JoinField(string inData, string inField, string joinTab /// /// /// - public static async Task CreateSightLines(string observersFeatureLayer, + public static async Task CreateSightLines(string observersFeatureLayer, string targetsFeatureLayer, string outLineFeatureLayer, string observerOffsetFieldName, @@ -172,17 +163,16 @@ public static async Task CreateSightLines(string observersFeatureLayer, IGPResult result = await Geoprocessing.ExecuteToolAsync("ConstructSightLines_3d", Geoprocessing.MakeValueArray(arguments.ToArray()), environments, flags: GPExecuteToolFlags.Default); - if (result.IsFailed) + bool success = isResultGoodAndReportMessages(result, "ConstructSightLines_3d"); + if (!success) { - foreach (var msg in result.Messages) - Debug.Print(msg.Text); - // If the tool failed, try to remove the table that was created so execution will run next time List args = new List(); args.Add(outLineFeatureLayer); IGPResult result2 = await Geoprocessing.ExecuteToolAsync("Delete_management", Geoprocessing.MakeValueArray(args.ToArray()), environments, flags: GPExecuteToolFlags.Default); - } + + return success; } /// @@ -192,7 +182,7 @@ public static async Task CreateSightLines(string observersFeatureLayer, /// /// /// - public static async Task AddSurfaceInformation(string featureClass, string surface, string outProperty) + public static async Task AddSurfaceInformation(string featureClass, string surface, string outProperty) { //AddSurfaceInformation_3d List arguments = new List(); @@ -205,11 +195,7 @@ public static async Task AddSurfaceInformation(string featureClass, string surfa IGPResult result = await Geoprocessing.ExecuteToolAsync("AddSurfaceInformation_3d", Geoprocessing.MakeValueArray(arguments.ToArray()), flags: GPExecuteToolFlags.Default); - if (result.IsFailed) - { - foreach (var msg in result.Messages) - Debug.Print(msg.Text); - } + return isResultGoodAndReportMessages(result, "AddSurfaceInformation_3d"); } /// @@ -219,7 +205,7 @@ public static async Task AddSurfaceInformation(string featureClass, string surfa /// /// /// - public static async Task CreateLOS(string surfaceName, + public static async Task CreateLOS(string surfaceName, string lineFeatureClassName, string outLOSFeatureClass) { @@ -247,17 +233,16 @@ public static async Task CreateLOS(string surfaceName, IGPResult result = await Geoprocessing.ExecuteToolAsync("LineOfSight_3d", Geoprocessing.MakeValueArray(arguments.ToArray()), environments, flags: GPExecuteToolFlags.Default); - if(result.IsFailed) + bool success = isResultGoodAndReportMessages(result, "LineOfSight_3d"); + if (!success) { - foreach (var msg in result.Messages) - Debug.Print(msg.Text); - // If the tool failed, try to remove the table that was created so execution will run next time List args = new List(); args.Add(outLOSFeatureClass); IGPResult result2 = await Geoprocessing.ExecuteToolAsync("Delete_management", Geoprocessing.MakeValueArray(args.ToArray()), environments, flags: GPExecuteToolFlags.Default); - } + + return success; } /// @@ -283,21 +268,27 @@ public static async Task Delete(string name) } /// - /// Method to run Raster to polygon + /// Method to run raster to polygon and optionally intersect with layer /// - /// - /// - /// - /// - /// - public static async Task IntersectOutput(string inputRasterLayer, string outputPolygonLayer, - bool simplify, string rasterField, string intersectMaskFeatureClass) + /// input raster layer to convert to polygons + /// output layer converted to polygons + /// simplify(smooth) output polygons + /// field from raster + /// (Optional)If present, the layer to intersect with the output polygon layer + /// success + public static async Task IntersectOutput(string inputRasterLayer, string outputPolygonLayer, + bool simplify, string rasterField, string intersectMaskFeatureClass = "") { + if (string.IsNullOrEmpty(inputRasterLayer) || string.IsNullOrEmpty(outputPolygonLayer)) + return false; + string rasterToPolyLayer = outputPolygonLayer; bool addToMap = true; + if (!string.IsNullOrEmpty(intersectMaskFeatureClass)) { + // If intersect layer present, create a temporary polygon layer & don't add to map rasterToPolyLayer += "_rasterToPoly"; addToMap = false; } @@ -319,14 +310,12 @@ public static async Task IntersectOutput(string inputRasterLayer, string outputP Geoprocessing.MakeValueArray(arguments.ToArray()), environments, null, null, addToMap ? GPExecuteToolFlags.Default : GPExecuteToolFlags.None); - if (result.IsFailed) - { - foreach (var msg in result.Messages) - Debug.Print(msg.Text); - } + if (!isResultGoodAndReportMessages(result, "RasterToPolygon_conversion")) + return false; + // If intersect layer *not* present, we are done, return if (string.IsNullOrEmpty(intersectMaskFeatureClass)) - return; + return true; // Intersect_analysis('infeatures';'in_features', 'out_feature_class', 'NO_FID') List argumentsIntersect = new List(); @@ -342,12 +331,7 @@ public static async Task IntersectOutput(string inputRasterLayer, string outputP result = await Geoprocessing.ExecuteToolAsync("Intersect_analysis", Geoprocessing.MakeValueArray(argumentsIntersect.ToArray()), environments); - if (result.IsFailed) - { - foreach (var msg in result.Messages) - Debug.Print(msg.Text); - } - + return isResultGoodAndReportMessages(result, "Intersect_analysis"); } /// @@ -421,19 +405,7 @@ public static async Task CreateVisibility(string surfaceName, string obser IGPResult result = await Geoprocessing.ExecuteToolAsync("Visibility_3d", Geoprocessing.MakeValueArray(arguments.ToArray()), environments, null, null, addToMap ? GPExecuteToolFlags.Default : GPExecuteToolFlags.None); - if (result.IsFailed) - { - // Provide the user some feedback of what went wrong - System.Text.StringBuilder sb = new System.Text.StringBuilder(); - sb.AppendLine("Visibility_3d GP Tool FAILED:"); - foreach (var msg in result.Messages) - sb.AppendLine(msg.Text); - - ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(sb.ToString(), - VisibilityLibrary.Properties.Resources.CaptionError); - } - - return result.IsFailed == false; + return isResultGoodAndReportMessages(result, "Visibility_3d"); } /// @@ -1146,6 +1118,7 @@ await QueuedTask.Run(() => featureLayer.SetRenderer(uniqueValueRenderer); }); } + public static async Task CreateVisCodeRenderer(FeatureLayer featureLayer, string visField, int visCodeVisible, int visCodeNotVisible, CIMColor visibleColor, CIMColor notVisibleColor, @@ -1219,7 +1192,26 @@ await QueuedTask.Run(() => }); } - } + private static bool isResultGoodAndReportMessages(IGPResult result, string toolToReport) + { + // Return if no errors + if (!result.IsFailed) + return true; + + // If failed, provide feedback of what went wrong + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + sb.Append(toolToReport); + sb.AppendLine(" - GP Tool FAILED:"); + foreach (var msg in result.Messages) + sb.AppendLine(msg.Text); + + ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(sb.ToString(), + VisibilityLibrary.Properties.Resources.CaptionError); + + return false; + } + + } // end class public class VisibilityStats { diff --git a/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs b/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs index 8e20702..6ccf6df 100644 --- a/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs +++ b/source/Visibility/ProAppVisibilityModule/Helpers/GeometryHelper.cs @@ -27,30 +27,46 @@ public static class GeometryHelper /// /// Returns a polygon with a range fan(circular ring sector - like a donut wedge or wiper blade swipe with inner and outer radius) /// from the input parameters + /// Input Angles must be 0-360 degrees /// public static Geometry ConstructRangeFan(MapPoint centerPoint, double innerDistanceInMapUnits, double outerDistanceInMapUnits, double horizontalStartAngleInBearing, double horizontalEndAngleInBearing, - SpatialReference sr) + SpatialReference sr, double incrementAngleStep = 5.0) { + // Check inputs + if ((centerPoint == null) || (sr == null) || + (innerDistanceInMapUnits < 0.0) || (outerDistanceInMapUnits < 0.0) || + (horizontalStartAngleInBearing < 0.0) || (horizontalStartAngleInBearing > 360.0) || + (horizontalEndAngleInBearing < 0.0) || (horizontalEndAngleInBearing > 360.0)) + return null; + + // Tricky - if angle cuts across 360, need to adjust for this case (ex. Angle: 270->90) + if (horizontalStartAngleInBearing > horizontalEndAngleInBearing) + horizontalStartAngleInBearing = -(360.0 - horizontalStartAngleInBearing); + + double deltaAngle = Math.Abs(horizontalStartAngleInBearing - horizontalEndAngleInBearing); + // if full circle(or greater), return donut section with inner/outer rings - if ((horizontalStartAngleInBearing <= 0.0) && (horizontalEndAngleInBearing >= 360.0)) + if ((deltaAngle == 0.0) || (deltaAngle >= 360.0)) { // Just add 2 concentric circle buffers PolygonBuilder donutPb = new PolygonBuilder(); - var outerBuffer = GeometryEngine.Buffer(centerPoint, outerDistanceInMapUnits); - // Tricky/Workaround: GP mask/intersect did not work with Multiparts with arcs so had to convert to densified polygon - var outerBufferDensified = GeometryEngine.DensifyByLength(outerBuffer, outerDistanceInMapUnits * 0.005); - var outerBufferPolygon = outerBufferDensified as Polygon; + EllipticArcSegment circularArcOuter = + EllipticArcBuilder.CreateEllipticArcSegment((Coordinate2D)centerPoint, + outerDistanceInMapUnits, esriArcOrientation.esriArcClockwise, sr); - donutPb.AddPart(outerBufferPolygon.Points); + donutPb.AddPart(new List { circularArcOuter }); - var innerBuffer = GeometryEngine.Buffer(centerPoint, innerDistanceInMapUnits); - var innerBufferDensified = GeometryEngine.DensifyByLength(innerBuffer, innerDistanceInMapUnits * 0.005); - var innerBufferPolygon = innerBufferDensified as Polygon; + if (innerDistanceInMapUnits > 0.0) + { + EllipticArcSegment circularArcInner = + EllipticArcBuilder.CreateEllipticArcSegment((Coordinate2D)centerPoint, + innerDistanceInMapUnits, esriArcOrientation.esriArcCounterClockwise, sr); - donutPb.AddPart(innerBufferPolygon.Points); + donutPb.AddPart(new List { circularArcInner }); + } return donutPb.ToGeometry(); } @@ -60,24 +76,23 @@ public static Geometry ConstructRangeFan(MapPoint centerPoint, MapPoint startPoint = null; - if (innerDistanceInMapUnits == 0.0) + if (innerDistanceInMapUnits <= 0.0) { startPoint = centerPoint; points.Add(startPoint); } - // Tricky - if angle cuts across 360, need to adjust for this case (ex. Angle: 270->90) - if (horizontalStartAngleInBearing > horizontalEndAngleInBearing) - horizontalStartAngleInBearing = -(360.0 - horizontalStartAngleInBearing); - double minAngle = Math.Min(horizontalStartAngleInBearing, horizontalEndAngleInBearing); double maxAngle = Math.Max(horizontalStartAngleInBearing, horizontalEndAngleInBearing); - double step = 5.0; + + // don't let this create more than 360 points per arc + if ((deltaAngle / incrementAngleStep) > 360.0) + incrementAngleStep = deltaAngle / 360.0; // Draw Outer Arc of Ring // Implementation Note: because of the unique shape of this ring, // it was easier to manually create these points than use EllipticArcBuilder - for (double angle = minAngle; angle <= maxAngle; angle += step) + for (double angle = minAngle; angle <= maxAngle; angle += incrementAngleStep) { double cartesianAngle = (450 - angle) % 360; double angleInRadians = cartesianAngle * (Math.PI / 180.0); @@ -94,7 +109,7 @@ public static Geometry ConstructRangeFan(MapPoint centerPoint, if (innerDistanceInMapUnits > 0.0) { // Draw Inner Arc of Ring - if inner distance set - for (double angle = maxAngle; angle >= minAngle; angle -= step) + for (double angle = maxAngle; angle >= minAngle; angle -= incrementAngleStep) { double cartesianAngle = (450 - angle) % 360; double angleInRadians = cartesianAngle * (Math.PI / 180.0); diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs index 23fe78a..094cbe9 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs @@ -341,7 +341,7 @@ await CreateMask(RLOSMaskLayerName, minDistanceInMapUnits, maxDistanceInMapUnits var rlosOutputLayer = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSOutputLayerName; - bool vizSuccess = await FeatureClassHelper.CreateVisibility(SelectedSurfaceName, ObserversLayerName, + bool success = await FeatureClassHelper.CreateVisibility(SelectedSurfaceName, ObserversLayerName, rlosOutputLayer, observerOffsetInMapZUnits, surfaceOffsetInMapZUnits, minDistanceInMapUnits, maxDistanceInMapUnits, @@ -351,7 +351,7 @@ await CreateMask(RLOSMaskLayerName, minDistanceInMapUnits, maxDistanceInMapUnits environments, false); - if (!vizSuccess) + if (!success) return; var rlosConvertedPolygonsLayer = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSConvertedPolygonsLayerName; @@ -366,7 +366,9 @@ await CreateMask(RLOSRangeFanMaskLayerName, minDistanceInMapUnits, maxDistanceIn horizontalEndAngleInDegrees, surfaceSR, true); } - await FeatureClassHelper.IntersectOutput(rlosOutputLayer, rlosConvertedPolygonsLayer, false, "Value", rangeFanMaskFeatureClassName); + success = await FeatureClassHelper.IntersectOutput(rlosOutputLayer, rlosConvertedPolygonsLayer, false, "Value", rangeFanMaskFeatureClassName); + if (!success) + return; await FeatureClassHelper.CreateUniqueValueRenderer(GetLayerFromMapByName(RLOSConvertedPolygonsLayerName) as FeatureLayer, ShowNonVisibleData, RLOSConvertedPolygonsLayerName); From 45062391e907367bb4e7ba83c8aa2ab4e68940fd Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Fri, 31 Mar 2017 12:39:24 -0400 Subject: [PATCH 30/42] Add error reporting+stop tool after 1st error --- .../Helpers/FeatureClassHelper.cs | 26 +++++++---- .../ViewModels/ProLLOSViewModel.cs | 46 ++++++++++++++----- .../ViewModels/ProRLOSViewModel.cs | 31 +++++++++---- 3 files changed, 76 insertions(+), 27 deletions(-) diff --git a/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs b/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs index 7628528..faa7652 100644 --- a/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs +++ b/source/Visibility/ProAppVisibilityModule/Helpers/FeatureClassHelper.cs @@ -73,7 +73,7 @@ public static async Task CreateLayer(string featureclassName, string featu null, addToMap ? GPExecuteToolFlags.Default : GPExecuteToolFlags.None); - return isResultGoodAndReportMessages(result, "CreateFeatureclass_management"); + return isResultGoodAndReportMessages(result, "CreateFeatureclass_management", arguments); } /// @@ -163,7 +163,7 @@ public static async Task CreateSightLines(string observersFeatureLayer, IGPResult result = await Geoprocessing.ExecuteToolAsync("ConstructSightLines_3d", Geoprocessing.MakeValueArray(arguments.ToArray()), environments, flags: GPExecuteToolFlags.Default); - bool success = isResultGoodAndReportMessages(result, "ConstructSightLines_3d"); + bool success = isResultGoodAndReportMessages(result, "ConstructSightLines_3d", arguments); if (!success) { // If the tool failed, try to remove the table that was created so execution will run next time @@ -195,7 +195,7 @@ public static async Task AddSurfaceInformation(string featureClass, string IGPResult result = await Geoprocessing.ExecuteToolAsync("AddSurfaceInformation_3d", Geoprocessing.MakeValueArray(arguments.ToArray()), flags: GPExecuteToolFlags.Default); - return isResultGoodAndReportMessages(result, "AddSurfaceInformation_3d"); + return isResultGoodAndReportMessages(result, "AddSurfaceInformation_3d", arguments); } /// @@ -233,7 +233,7 @@ public static async Task CreateLOS(string surfaceName, IGPResult result = await Geoprocessing.ExecuteToolAsync("LineOfSight_3d", Geoprocessing.MakeValueArray(arguments.ToArray()), environments, flags: GPExecuteToolFlags.Default); - bool success = isResultGoodAndReportMessages(result, "LineOfSight_3d"); + bool success = isResultGoodAndReportMessages(result, "LineOfSight_3d", arguments); if (!success) { // If the tool failed, try to remove the table that was created so execution will run next time @@ -310,7 +310,7 @@ public static async Task IntersectOutput(string inputRasterLayer, string o Geoprocessing.MakeValueArray(arguments.ToArray()), environments, null, null, addToMap ? GPExecuteToolFlags.Default : GPExecuteToolFlags.None); - if (!isResultGoodAndReportMessages(result, "RasterToPolygon_conversion")) + if (!isResultGoodAndReportMessages(result, "RasterToPolygon_conversion", arguments)) return false; // If intersect layer *not* present, we are done, return @@ -331,7 +331,7 @@ public static async Task IntersectOutput(string inputRasterLayer, string o result = await Geoprocessing.ExecuteToolAsync("Intersect_analysis", Geoprocessing.MakeValueArray(argumentsIntersect.ToArray()), environments); - return isResultGoodAndReportMessages(result, "Intersect_analysis"); + return isResultGoodAndReportMessages(result, "Intersect_analysis", arguments); } /// @@ -405,7 +405,7 @@ public static async Task CreateVisibility(string surfaceName, string obser IGPResult result = await Geoprocessing.ExecuteToolAsync("Visibility_3d", Geoprocessing.MakeValueArray(arguments.ToArray()), environments, null, null, addToMap ? GPExecuteToolFlags.Default : GPExecuteToolFlags.None); - return isResultGoodAndReportMessages(result, "Visibility_3d"); + return isResultGoodAndReportMessages(result, "Visibility_3d", arguments); } /// @@ -1192,7 +1192,8 @@ await QueuedTask.Run(() => }); } - private static bool isResultGoodAndReportMessages(IGPResult result, string toolToReport) + private static bool isResultGoodAndReportMessages(IGPResult result, string toolToReport, + List toolParameters) { // Return if no errors if (!result.IsFailed) @@ -1205,6 +1206,15 @@ private static bool isResultGoodAndReportMessages(IGPResult result, string toolT foreach (var msg in result.Messages) sb.AppendLine(msg.Text); + if (toolParameters != null) + { + sb.Append("Parameters: "); + int count = 0; + foreach (var param in toolParameters) + sb.Append(string.Format("{0}:{1} ", count++, param)); + sb.AppendLine(); + } + ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(sb.ToString(), VisibilityLibrary.Properties.Resources.CaptionError); diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs index f4216f8..69b0899 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs @@ -297,7 +297,11 @@ internal override async Task CreateMapElement() if (!CanCreateElement || MapView.Active == null || MapView.Active.Map == null || string.IsNullOrWhiteSpace(SelectedSurfaceName)) return; - await ExecuteVisibilityLLOS(); + bool success = await ExecuteVisibilityLLOS(); + + if (!success) + MessageBox.Show("LLOS computations did not complete correctly.\nPlease check your parameters and try again.", + VisibilityLibrary.Properties.Resources.CaptionError); DeactivateTool(VisibilityMapTool.ToolId); @@ -318,8 +322,10 @@ internal override async Task CreateMapElement() } } - private async Task ExecuteVisibilityLLOS() + private async Task ExecuteVisibilityLLOS() { + bool success = false; + try { var surfaceSR = await GetSpatialReferenceFromLayer(SelectedSurfaceName); @@ -337,10 +343,10 @@ private async Task ExecuteVisibilityLLOS() await Reset(true); - return; + return false; } - await FeatureClassHelper.CreateLayer(ObserversLayerName, "POINT", true, true); + success = await FeatureClassHelper.CreateLayer(ObserversLayerName, "POINT", true, true); // add fields for observer offset @@ -348,7 +354,10 @@ private async Task ExecuteVisibilityLLOS() await FeatureClassHelper.AddFieldToLayer(ObserversLayerName, VisibilityLibrary.Properties.Resources.OffsetWithZFieldName, "DOUBLE"); await FeatureClassHelper.AddFieldToLayer(ObserversLayerName, VisibilityLibrary.Properties.Resources.TarIsVisFieldName, "SHORT"); - await FeatureClassHelper.CreateLayer(TargetsLayerName, "POINT", true, true); + success = await FeatureClassHelper.CreateLayer(TargetsLayerName, "POINT", true, true); + + if (!success) + return false; // add fields for target offset @@ -363,8 +372,13 @@ private async Task ExecuteVisibilityLLOS() await FeatureClassHelper.CreatingFeatures(TargetsLayerName, TargetAddInPoints, GetAsMapZUnits(surfaceSR, TargetOffset.Value)); // update with surface information - await FeatureClassHelper.AddSurfaceInformation(ObserversLayerName, SelectedSurfaceName, VisibilityLibrary.Properties.Resources.ZFieldName); - await FeatureClassHelper.AddSurfaceInformation(TargetsLayerName, SelectedSurfaceName, VisibilityLibrary.Properties.Resources.ZFieldName); + success = await FeatureClassHelper.AddSurfaceInformation(ObserversLayerName, SelectedSurfaceName, VisibilityLibrary.Properties.Resources.ZFieldName); + if (!success) + return false; + + success = await FeatureClassHelper.AddSurfaceInformation(TargetsLayerName, SelectedSurfaceName, VisibilityLibrary.Properties.Resources.ZFieldName); + if (!success) + return false; await FeatureClassHelper.UpdateShapeWithZ(ObserversLayerName, VisibilityLibrary.Properties.Resources.ZFieldName, GetAsMapZUnits(surfaceSR, ObserverOffset.Value)); await FeatureClassHelper.UpdateShapeWithZ(TargetsLayerName, VisibilityLibrary.Properties.Resources.ZFieldName, GetAsMapZUnits(surfaceSR, TargetOffset.Value)); @@ -374,21 +388,27 @@ private async Task ExecuteVisibilityLLOS() GC.WaitForPendingFinalizers(); GC.Collect(); - await FeatureClassHelper.CreateSightLines(ObserversLayerName, + success = await FeatureClassHelper.CreateSightLines(ObserversLayerName, TargetsLayerName, CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + SightLinesLayerName, VisibilityLibrary.Properties.Resources.OffsetWithZFieldName, VisibilityLibrary.Properties.Resources.OffsetWithZFieldName); + if (!success) + return false; + // LOS GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); - await FeatureClassHelper.CreateLOS(SelectedSurfaceName, + success = await FeatureClassHelper.CreateLOS(SelectedSurfaceName, CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + SightLinesLayerName, CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + OutputLayerName); + if (!success) + return false; + GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); @@ -455,17 +475,21 @@ await FeatureClassHelper.CreateVisCodeRenderer(GetLayerFromMapByName(OutputLayer var envelope = await QueuedTask.Run(() => outputLayer.QueryExtent()); await ZoomToExtent(envelope); executionCounter++; + + success = true; } else { - MessageBox.Show("LLOS computations did not complete correctly. Please try again by selecting the 'OK' button."); + success = false; } - } catch(Exception ex) { + success = false; Debug.Print(ex.Message); } + + return success; } internal override void OnDisplayCoordinateTypeChanged(object obj) diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs index 094cbe9..cfd1808 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs @@ -272,7 +272,11 @@ internal override async Task CreateMapElement() if (!CanCreateElement || MapView.Active == null || MapView.Active.Map == null || string.IsNullOrWhiteSpace(SelectedSurfaceName)) return; - await ExecuteVisibilityRLOS(); + bool success = await ExecuteVisibilityRLOS(); + + if (!success) + MessageBox.Show("LLOS computations did not complete correctly.\nPlease check your parameters and try again.", + VisibilityLibrary.Properties.Resources.CaptionError); DeactivateTool(VisibilityMapTool.ToolId); @@ -293,8 +297,10 @@ internal override async Task CreateMapElement() #region Private - private async Task ExecuteVisibilityRLOS() + private async Task ExecuteVisibilityRLOS() { + bool success = false; + try { var surfaceSR = await GetSpatialReferenceFromLayer(SelectedSurfaceName); @@ -302,10 +308,12 @@ private async Task ExecuteVisibilityRLOS() if(surfaceSR == null || !surfaceSR.IsProjected) { MessageBox.Show(VisibilityLibrary.Properties.Resources.RLOSUserPrompt, VisibilityLibrary.Properties.Resources.RLOSUserPromptCaption); - return; + return false; } - await FeatureClassHelper.CreateLayer(ObserversLayerName, "POINT", true, true); + success = await FeatureClassHelper.CreateLayer(ObserversLayerName, "POINT", true, true); + if (!success) + return false; // add fields for observer offset @@ -318,7 +326,9 @@ private async Task ExecuteVisibilityRLOS() // update with surface information - await FeatureClassHelper.AddSurfaceInformation(ObserversLayerName, SelectedSurfaceName, VisibilityLibrary.Properties.Resources.ZFieldName); + success = await FeatureClassHelper.AddSurfaceInformation(ObserversLayerName, SelectedSurfaceName, VisibilityLibrary.Properties.Resources.ZFieldName); + if (!success) + return false; // Visibility @@ -341,7 +351,7 @@ await CreateMask(RLOSMaskLayerName, minDistanceInMapUnits, maxDistanceInMapUnits var rlosOutputLayer = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSOutputLayerName; - bool success = await FeatureClassHelper.CreateVisibility(SelectedSurfaceName, ObserversLayerName, + success = await FeatureClassHelper.CreateVisibility(SelectedSurfaceName, ObserversLayerName, rlosOutputLayer, observerOffsetInMapZUnits, surfaceOffsetInMapZUnits, minDistanceInMapUnits, maxDistanceInMapUnits, @@ -352,7 +362,7 @@ await CreateMask(RLOSMaskLayerName, minDistanceInMapUnits, maxDistanceInMapUnits false); if (!success) - return; + return false; var rlosConvertedPolygonsLayer = CoreModule.CurrentProject.DefaultGeodatabasePath + "\\" + RLOSConvertedPolygonsLayerName; @@ -368,7 +378,7 @@ await CreateMask(RLOSRangeFanMaskLayerName, minDistanceInMapUnits, maxDistanceIn success = await FeatureClassHelper.IntersectOutput(rlosOutputLayer, rlosConvertedPolygonsLayer, false, "Value", rangeFanMaskFeatureClassName); if (!success) - return; + return false; await FeatureClassHelper.CreateUniqueValueRenderer(GetLayerFromMapByName(RLOSConvertedPolygonsLayerName) as FeatureLayer, ShowNonVisibleData, RLOSConvertedPolygonsLayerName); @@ -398,11 +408,16 @@ await CreateMask(RLOSRangeFanMaskLayerName, minDistanceInMapUnits, maxDistanceIn } executionCounter++; + + success = true; } catch (Exception ex) { Debug.Print(ex.Message); + success = false; } + + return success; } /// From 53180e0bd3af23f1895024a89e13b9a5161db9b5 Mon Sep 17 00:00:00 2001 From: Kevin Gonzago Date: Wed, 26 Apr 2017 13:44:22 -0400 Subject: [PATCH 31/42] Changed licensing level to basic for RLOS --- .../ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs index 7404472..b37d65f 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs @@ -353,8 +353,7 @@ internal override void CreateMapElement() esriLicenseStatus status = GetSpatialAnalystLicense(); if (status == esriLicenseStatus.esriLicenseUnavailable || status == esriLicenseStatus.esriLicenseFailure || - status == esriLicenseStatus.esriLicenseNotInitialized || status == esriLicenseStatus.esriLicenseNotLicensed || - status == esriLicenseStatus.esriLicenseUnavailable) + status == esriLicenseStatus.esriLicenseNotInitialized || status == esriLicenseStatus.esriLicenseNotLicensed) { System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.LOSSpatialAnalystLicenseInvalid, VisibilityLibrary.Properties.Resources.MsgCalcCancelled); return; @@ -524,11 +523,12 @@ public esriLicenseStatus GetSpatialAnalystLicense() { //Check out a Spatial Analyst license with the ArcView product. esriLicenseProductCode productCode = - esriLicenseProductCode.esriLicenseProductCodeAdvanced; + esriLicenseProductCode.esriLicenseProductCodeBasic; IAoInitialize pAoInitialize = new AoInitializeClass(); esriLicenseStatus licenseStatus = esriLicenseStatus.esriLicenseUnavailable; //Check the productCode. licenseStatus = pAoInitialize.IsProductCodeAvailable(productCode); + Console.WriteLine("licenstatus:" + licenseStatus); if (licenseStatus == esriLicenseStatus.esriLicenseAvailable) { //Check the extensionCode. From 4c9131637ad310cf5dd3b9e2c9ddb080c0148455 Mon Sep 17 00:00:00 2001 From: Kevin Gonzago Date: Fri, 28 Apr 2017 10:02:39 -0400 Subject: [PATCH 32/42] Removed console reference --- .../Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs index b37d65f..a7d6417 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs @@ -528,7 +528,6 @@ public esriLicenseStatus GetSpatialAnalystLicense() esriLicenseStatus licenseStatus = esriLicenseStatus.esriLicenseUnavailable; //Check the productCode. licenseStatus = pAoInitialize.IsProductCodeAvailable(productCode); - Console.WriteLine("licenstatus:" + licenseStatus); if (licenseStatus == esriLicenseStatus.esriLicenseAvailable) { //Check the extensionCode. From a78e5ced1b93b239596a31f8fb232f404a945861 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Mon, 1 May 2017 11:57:17 -0400 Subject: [PATCH 33/42] Fix license issue caused by previous change --- .../ViewModels/RLOSViewModel.cs | 49 +++++-------------- 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs index a7d6417..3c4e289 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs @@ -249,6 +249,13 @@ internal override void CreateMapElement() if (surface == null) return; + bool spatialAnalystAvailable = IsSpatialAnalystAvailable(); + if (!spatialAnalystAvailable) + { + System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.LOSSpatialAnalystLicenseInvalid, VisibilityLibrary.Properties.Resources.MsgCalcCancelled); + return; + } + // Determine if selected surface is projected or geographic ILayer surfaceLayer = GetLayerFromMapByName(ArcMap.Document.FocusMap, SelectedSurfaceName); var geoDataset = surfaceLayer as IGeoDataset; @@ -351,14 +358,6 @@ internal override void CreateMapElement() parameters.Add(strPath); parameters.Add(outPath); - esriLicenseStatus status = GetSpatialAnalystLicense(); - if (status == esriLicenseStatus.esriLicenseUnavailable || status == esriLicenseStatus.esriLicenseFailure || - status == esriLicenseStatus.esriLicenseNotInitialized || status == esriLicenseStatus.esriLicenseNotLicensed) - { - System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.LOSSpatialAnalystLicenseInvalid, VisibilityLibrary.Properties.Resources.MsgCalcCancelled); - return; - } - IGeoProcessor2 gp = new GeoProcessorClass(); gp.AddOutputsToMap = false; @@ -516,38 +515,14 @@ public IFeatureRenderer UniqueValueRenderer(IFeatureWorkspace workspace, IFeatur } /// - /// Check out spatial analyst license + /// Checks to see if spatial analyst license available (it has been checked out by ArcMap) /// - /// esriLicenseStatus - public esriLicenseStatus GetSpatialAnalystLicense() + /// true/false + public bool IsSpatialAnalystAvailable() { - //Check out a Spatial Analyst license with the ArcView product. - esriLicenseProductCode productCode = - esriLicenseProductCode.esriLicenseProductCodeBasic; - IAoInitialize pAoInitialize = new AoInitializeClass(); - esriLicenseStatus licenseStatus = esriLicenseStatus.esriLicenseUnavailable; - //Check the productCode. - licenseStatus = pAoInitialize.IsProductCodeAvailable(productCode); - if (licenseStatus == esriLicenseStatus.esriLicenseAvailable) - { - //Check the extensionCode. - licenseStatus = pAoInitialize.IsExtensionCodeAvailable(productCode, - esriLicenseExtensionCode.esriLicenseExtensionCodeSpatialAnalyst); - if (licenseStatus == esriLicenseStatus.esriLicenseAvailable) - { - //Initialize the license. - licenseStatus = pAoInitialize.Initialize(productCode); - if ((licenseStatus == esriLicenseStatus.esriLicenseCheckedOut)) - { - //Check out the Spatial Analyst extension. - licenseStatus = pAoInitialize.CheckOutExtension - (esriLicenseExtensionCode.esriLicenseExtensionCodeSpatialAnalyst) - ; - } - } - } + IAoInitialize aoInitializer = new AoInitializeClass(); - return licenseStatus; + return aoInitializer.IsExtensionCheckedOut(esriLicenseExtensionCode.esriLicenseExtensionCodeSpatialAnalyst); } /// From 9125ebe841a141217716952bd07edfe27896db21 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Wed, 17 May 2017 10:17:35 -0400 Subject: [PATCH 34/42] Fix issue on name lookup with image service+warning Add warning if surface is Image Service --- .../ViewModels/LLOSViewModel.cs | 16 +++++++++- .../ViewModels/RLOSViewModel.cs | 29 +++++++++++++++++-- .../Properties/Resources.Designer.cs | 27 +++++++++++++++++ .../Properties/Resources.resx | 9 ++++++ 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs index 15baf6c..1314040 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs @@ -185,8 +185,22 @@ internal override void CreateMapElement() if (surface == null) return; - // Determine if selected surface is projected or geographic ILayer surfaceLayer = GetLayerFromMapByName(ArcMap.Document.FocusMap, SelectedSurfaceName); + + // Issue warning if layer is ImageServerLayer + if (surfaceLayer is IImageServerLayer) + { + MessageBoxResult mbr = MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgLayerIsImageService, + VisibilityLibrary.Properties.Resources.CaptionLayerIsImageService, MessageBoxButton.YesNo); + + if (mbr == MessageBoxResult.No) + { + System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgTryAgain, VisibilityLibrary.Properties.Resources.MsgCalcCancelled); + return; + } + } + + // Determine if selected surface is projected or geographic var geoDataset = surfaceLayer as IGeoDataset; SelectedSurfaceSpatialRef = geoDataset.SpatialReference; diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs index 3c4e289..e945795 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/RLOSViewModel.cs @@ -256,8 +256,21 @@ internal override void CreateMapElement() return; } - // Determine if selected surface is projected or geographic ILayer surfaceLayer = GetLayerFromMapByName(ArcMap.Document.FocusMap, SelectedSurfaceName); + // Issue warning if layer is ImageServerLayer + if (surfaceLayer is IImageServerLayer) + { + MessageBoxResult mbr = MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgLayerIsImageService, + VisibilityLibrary.Properties.Resources.CaptionLayerIsImageService, MessageBoxButton.YesNo); + + if (mbr == MessageBoxResult.No) + { + System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgTryAgain, VisibilityLibrary.Properties.Resources.MsgCalcCancelled); + return; + } + } + + // Determine if selected surface is projected or geographic var geoDataset = surfaceLayer as IGeoDataset; SelectedSurfaceSpatialRef = geoDataset.SpatialReference; @@ -345,6 +358,13 @@ internal override void CreateMapElement() ILayer layer = GetLayerFromMapByName(ArcMap.Document.FocusMap, SelectedSurfaceName); string layerPath = GetLayerPath(layer); + if (string.IsNullOrEmpty(layerPath)) + { + // if layer path didn't resolve, issue error and stop + System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgSurfaceLayerNotFound, VisibilityLibrary.Properties.Resources.AEInvalidInput); + throw new Exception(VisibilityLibrary.Properties.Resources.MsgSurfaceLayerNotFound); + } + IFeatureLayer ipFeatureLayer = new FeatureLayerClass(); ipFeatureLayer.FeatureClass = pointFc; @@ -1053,7 +1073,12 @@ private double GetAngularDistanceFromTo(AngularTypes fromType, AngularTypes toTy /// file path of layer private static string GetLayerPath(ILayer layer) { - if (layer is IRasterLayer) + if (layer is IImageServerLayer) + { + IImageServerLayer mlayer = layer as IImageServerLayer; + return mlayer.Name; + } + else if (layer is IRasterLayer) { IRasterLayer rlayer = layer as IRasterLayer; return rlayer.FilePath; diff --git a/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs b/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs index 29aab2d..e95103a 100644 --- a/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs +++ b/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs @@ -141,6 +141,15 @@ public static string CaptionError { } } + /// + /// Looks up a localized string similar to Image Service Layer Warning. + /// + public static string CaptionLayerIsImageService { + get { + return ResourceManager.GetString("CaptionLayerIsImageService", resourceCulture); + } + } + /// /// Looks up a localized string similar to DD. /// @@ -654,6 +663,15 @@ public static string MsgCalcCancelled { } } + /// + /// Looks up a localized string similar to The selected layer is an Image Service and make take a long time to process. Do you wish to continue?. + /// + public static string MsgLayerIsImageService { + get { + return ResourceManager.GetString("MsgLayerIsImageService", resourceCulture); + } + } + /// /// Looks up a localized string similar to Point does not fall within the input extent.. /// @@ -663,6 +681,15 @@ public static string MsgOutOfAOI { } } + /// + /// Looks up a localized string similar to The surface layer was not found. Please try again.. + /// + public static string MsgSurfaceLayerNotFound { + get { + return ResourceManager.GetString("MsgSurfaceLayerNotFound", resourceCulture); + } + } + /// /// Looks up a localized string similar to Results not calculated. Check input parameters and try again.. /// diff --git a/source/Visibility/VisibilityLibrary/Properties/Resources.resx b/source/Visibility/VisibilityLibrary/Properties/Resources.resx index 70a6a4e..ff23c66 100644 --- a/source/Visibility/VisibilityLibrary/Properties/Resources.resx +++ b/source/Visibility/VisibilityLibrary/Properties/Resources.resx @@ -396,4 +396,13 @@ Please verify that all Observer Points are within the extents of the selected Surface + + Image Service Layer Warning + + + The selected layer is an Image Service and make take a long time to process. Do you wish to continue? + + + The surface layer was not found. Please try again. + \ No newline at end of file From 3e76fc6cd0d55ee06cd57d4aedb9fbb8d4758477 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Wed, 17 May 2017 12:03:09 -0400 Subject: [PATCH 35/42] Add image service warning to Pro --- .../ViewModels/ProLLOSViewModel.cs | 16 +++++++++++++++- .../ViewModels/ProRLOSViewModel.cs | 16 +++++++++++++++- .../Properties/Resources.Designer.cs | 2 +- .../VisibilityLibrary/Properties/Resources.resx | 2 +- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs index 69b0899..e883cb8 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLLOSViewModel.cs @@ -328,8 +328,8 @@ private async Task ExecuteVisibilityLLOS() try { + // Check surface spatial reference var surfaceSR = await GetSpatialReferenceFromLayer(SelectedSurfaceName); - if (surfaceSR == null || !surfaceSR.IsProjected) { MessageBox.Show(VisibilityLibrary.Properties.Resources.RLOSUserPrompt, VisibilityLibrary.Properties.Resources.RLOSUserPromptCaption); @@ -346,6 +346,20 @@ private async Task ExecuteVisibilityLLOS() return false; } + // Warn if Image Service layer + Layer surfaceLayer = GetLayerFromMapByName(SelectedSurfaceName); + if (surfaceLayer is ImageServiceLayer) + { + MessageBoxResult mbr = MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgLayerIsImageService, + VisibilityLibrary.Properties.Resources.CaptionLayerIsImageService, MessageBoxButton.YesNo); + + if (mbr == MessageBoxResult.No) + { + System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgTryAgain, VisibilityLibrary.Properties.Resources.MsgCalcCancelled); + return false; + } + } + success = await FeatureClassHelper.CreateLayer(ObserversLayerName, "POINT", true, true); // add fields for observer offset diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs index cfd1808..9c62086 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProRLOSViewModel.cs @@ -303,14 +303,28 @@ private async Task ExecuteVisibilityRLOS() try { + // Check surface spatial reference var surfaceSR = await GetSpatialReferenceFromLayer(SelectedSurfaceName); - if(surfaceSR == null || !surfaceSR.IsProjected) { MessageBox.Show(VisibilityLibrary.Properties.Resources.RLOSUserPrompt, VisibilityLibrary.Properties.Resources.RLOSUserPromptCaption); return false; } + // Warn if Image Service layer + Layer surfaceLayer = GetLayerFromMapByName(SelectedSurfaceName); + if (surfaceLayer is ImageServiceLayer) + { + MessageBoxResult mbr = MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgLayerIsImageService, + VisibilityLibrary.Properties.Resources.CaptionLayerIsImageService, MessageBoxButton.YesNo); + + if (mbr == MessageBoxResult.No) + { + System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgTryAgain, VisibilityLibrary.Properties.Resources.MsgCalcCancelled); + return false; + } + } + success = await FeatureClassHelper.CreateLayer(ObserversLayerName, "POINT", true, true); if (!success) return false; diff --git a/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs b/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs index e95103a..fa4fab1 100644 --- a/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs +++ b/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs @@ -664,7 +664,7 @@ public static string MsgCalcCancelled { } /// - /// Looks up a localized string similar to The selected layer is an Image Service and make take a long time to process. Do you wish to continue?. + /// Looks up a localized string similar to The selected input surface layer is an Image Service and make take a long time to process. Do you wish to continue?. /// public static string MsgLayerIsImageService { get { diff --git a/source/Visibility/VisibilityLibrary/Properties/Resources.resx b/source/Visibility/VisibilityLibrary/Properties/Resources.resx index ff23c66..73625da 100644 --- a/source/Visibility/VisibilityLibrary/Properties/Resources.resx +++ b/source/Visibility/VisibilityLibrary/Properties/Resources.resx @@ -400,7 +400,7 @@ Image Service Layer Warning - The selected layer is an Image Service and make take a long time to process. Do you wish to continue? + The selected input surface layer is an Image Service and make take a long time to process. Do you wish to continue? The surface layer was not found. Please try again. From 3d445882e508c031950aa172556a0bb9ae852856 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Thu, 18 May 2017 08:24:52 -0400 Subject: [PATCH 36/42] Fix typo --- .../VisibilityLibrary/Properties/Resources.Designer.cs | 2 +- source/Visibility/VisibilityLibrary/Properties/Resources.resx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs b/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs index fa4fab1..01bbd20 100644 --- a/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs +++ b/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs @@ -664,7 +664,7 @@ public static string MsgCalcCancelled { } /// - /// Looks up a localized string similar to The selected input surface layer is an Image Service and make take a long time to process. Do you wish to continue?. + /// Looks up a localized string similar to The selected input surface layer is an Image Service and may take a long time to process. Do you wish to continue?. /// public static string MsgLayerIsImageService { get { diff --git a/source/Visibility/VisibilityLibrary/Properties/Resources.resx b/source/Visibility/VisibilityLibrary/Properties/Resources.resx index 73625da..2edea1c 100644 --- a/source/Visibility/VisibilityLibrary/Properties/Resources.resx +++ b/source/Visibility/VisibilityLibrary/Properties/Resources.resx @@ -400,7 +400,7 @@ Image Service Layer Warning - The selected input surface layer is an Image Service and make take a long time to process. Do you wish to continue? + The selected input surface layer is an Image Service and may take a long time to process. Do you wish to continue? The surface layer was not found. Please try again. From 46fb2a856c73c33f21bdc22d10251499d3139289 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Sat, 20 May 2017 13:16:45 -0400 Subject: [PATCH 37/42] Fix for #190 Bug saving last tool if current tool = null --- .../ArcMapAddinVisibility/MapPointTool.cs | 13 +++++++------ .../ViewModels/TabBaseViewModel.cs | 18 +++++++++++++----- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs b/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs index 5e3f17a..69b27e9 100644 --- a/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs +++ b/source/Visibility/ArcMapAddinVisibility/MapPointTool.cs @@ -39,8 +39,6 @@ public class MapPointTool : ESRI.ArcGIS.Desktop.AddIns.Tool public MapPointTool() { - if ((ArcMap.Application != null) && (ArcMap.Application.CurrentTool != null)) - lastActiveToolGuid = ArcMap.Application.CurrentTool.ID.Value as string; } protected override void OnUpdate() @@ -55,12 +53,15 @@ protected override void OnUpdate() // This is not a very efficient place to do this because it is called repeatedly // but only place I could find that knew the previous tool in use - if (ArcMap.Application.CurrentTool.ID.Value.ToString().Equals(lastActiveToolGuid)) - return; - // this is a GUID - with no way to get the progID // (except PInvoke of Win32 ProgIDFromCLSID) so using GUIDs instead of more readable ProgID - lastActiveToolGuid = ArcMap.Application.CurrentTool.ID.Value as string; + string currentActiveToolGuid = ArcMap.Application.CurrentTool.ID.Value as string; + + if (currentActiveToolGuid.Equals(lastActiveToolGuid) + || currentActiveToolGuid.Equals("{224824C0-D14C-E386-96E2-C1D699426A56}")) // this tool's GUID + return; + + lastActiveToolGuid = currentActiveToolGuid; } protected override void OnActivate() diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs index 54a4b72..836a721 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs @@ -466,14 +466,22 @@ public void DeactivateTool(string toolname) /// public void SetToolActiveInToolBar(string toolName) { - if ((ArcMap.Application == null) || (ArcMap.Application.CurrentTool == null) || - string.IsNullOrEmpty(toolName)) + if (ArcMap.Application == null) return; - // Tricky: Check if tool already active - because setting CurrentTool will - // cause Activate/Deactive to be called by framework - if (ArcMap.Application.CurrentTool.Name.Equals(toolName)) + if (string.IsNullOrEmpty(toolName)) + { + if (ArcMap.Application.CurrentTool != null) // TRICKY: setting current tool to null at startup causes crash so extra check + ArcMap.Application.CurrentTool = null; + return; + } + + if ((ArcMap.Application.CurrentTool != null) && + (ArcMap.Application.CurrentTool.Name.Equals(toolName))) + // Tricky: Check if tool already active - because setting CurrentTool again will + // cause Activate/Deactive to be called by ArcGIS framework + return; ESRI.ArcGIS.Framework.ICommandBars commandBars = ArcMap.Application.Document.CommandBars; ESRI.ArcGIS.esriSystem.UID commandID = new ESRI.ArcGIS.esriSystem.UIDClass(); From 0264214c378ab26602ea29912663c16a3480d035 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Mon, 22 May 2017 11:24:47 -0400 Subject: [PATCH 38/42] Address #175 - Pro MapPoint tool & Image Service Address #175 - Pro MapPoint tool doesn't work with Image Service - takes minutes to activate with large image service because of ImageServiceLayer.QueryExtent() call --- .../ViewModels/ProLOSBaseViewModel.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs index 0e0c62e..3c3934b 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProLOSBaseViewModel.cs @@ -360,10 +360,21 @@ internal async Task IsValidPoint(MapPoint point, bool showPopup = false) if (!string.IsNullOrWhiteSpace(SelectedSurfaceName) && MapView.Active != null && MapView.Active.Map != null) { var layer = GetLayerFromMapByName(SelectedSurfaceName); + + // WORKAROUND/BUG: + // QueryExtent() is taking several minutes to return from this call with ImageServiceLayer + // during which MCT can't do anything, so for now just return true, + // fix this in the future when QueryExtent() or alternate works with ImageServiceLayer + if (layer is ImageServiceLayer) + { + return true; + } + var env = await QueuedTask.Run(() => - { - return layer.QueryExtent(); - }); + { + return layer.QueryExtent(); + }); + validPoint = await IsPointWithinExtent(point, env); if (validPoint == false && showPopup) From f7f8d50c622539f2242082b180e9d8ee4d660ca0 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Mon, 22 May 2017 12:13:01 -0400 Subject: [PATCH 39/42] #156 - Change Offset to Height --- .../VisibilityLibrary/Properties/Resources.Designer.cs | 2 +- source/Visibility/VisibilityLibrary/Properties/Resources.resx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs b/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs index 01bbd20..1801c45 100644 --- a/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs +++ b/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs @@ -457,7 +457,7 @@ public static string LabelObserverPoints { } /// - /// Looks up a localized string similar to Offsets. + /// Looks up a localized string similar to Height. /// public static string LabelOffsets { get { diff --git a/source/Visibility/VisibilityLibrary/Properties/Resources.resx b/source/Visibility/VisibilityLibrary/Properties/Resources.resx index 2edea1c..b7d48f6 100644 --- a/source/Visibility/VisibilityLibrary/Properties/Resources.resx +++ b/source/Visibility/VisibilityLibrary/Properties/Resources.resx @@ -229,7 +229,7 @@ Observer Points - Offsets + Height OK From 807bc4b2280adf9ee56d2a753652d2449c7346cd Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Mon, 22 May 2017 12:22:32 -0400 Subject: [PATCH 40/42] Changed to Height Above Surface Changed to "Height Above Surface" to be consistent with GP Tools --- .../VisibilityLibrary/Properties/Resources.Designer.cs | 2 +- source/Visibility/VisibilityLibrary/Properties/Resources.resx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs b/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs index 1801c45..a044908 100644 --- a/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs +++ b/source/Visibility/VisibilityLibrary/Properties/Resources.Designer.cs @@ -457,7 +457,7 @@ public static string LabelObserverPoints { } /// - /// Looks up a localized string similar to Height. + /// Looks up a localized string similar to Height Above Surface. /// public static string LabelOffsets { get { diff --git a/source/Visibility/VisibilityLibrary/Properties/Resources.resx b/source/Visibility/VisibilityLibrary/Properties/Resources.resx index b7d48f6..4036863 100644 --- a/source/Visibility/VisibilityLibrary/Properties/Resources.resx +++ b/source/Visibility/VisibilityLibrary/Properties/Resources.resx @@ -229,7 +229,7 @@ Observer Points - Height + Height Above Surface OK From 34d311cf034ea0c12176d2aee68def3d08e6fed0 Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Mon, 22 May 2017 15:26:21 -0400 Subject: [PATCH 41/42] #154, #157 Remove Clear Graphics Button --- .../ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs | 2 ++ .../ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs | 9 +++++++++ .../ViewModels/ProTabBaseViewModel.cs | 7 +++++++ source/Visibility/VisibilityLibrary/Views/LLOSView.xaml | 7 +++++-- source/Visibility/VisibilityLibrary/Views/RLOSView.xaml | 5 ++++- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs index 1314040..73111fe 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/LLOSViewModel.cs @@ -40,6 +40,8 @@ public LLOSViewModel() // commands SubmitCommand = new RelayCommand(OnSubmitCommand); + + ClearGraphicsVisible = true; } #region Properties diff --git a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs index 836a721..f320a34 100644 --- a/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs +++ b/source/Visibility/ArcMapAddinVisibility/ViewModels/TabBaseViewModel.cs @@ -50,6 +50,7 @@ public TabBaseViewModel() Mediator.Register(VisibilityLibrary.Constants.MAP_POINT_TOOL_DEACTIVATED, OnMapPointToolDeactivated); Mediator.Register(VisibilityLibrary.Constants.MAP_TOOL_CHANGED, OnActiveToolChanged); + ClearGraphicsVisible = false; } protected void OnMapPointToolActivated(object obj) @@ -83,6 +84,9 @@ protected virtual void OnActiveToolChanged(object obj) // lists to store GUIDs of graphics, temp feedback and map graphics private static List GraphicsList = new List(); + /// + /// Property used to determine if there are non temp graphics + /// public bool HasMapGraphics { get @@ -92,6 +96,11 @@ public bool HasMapGraphics } } + /// + /// Property used to determine if ClearGraphics button should be visible + /// + public bool ClearGraphicsVisible { get; set; } + private IPoint point1 = null; /// /// Property for the first IPoint diff --git a/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs b/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs index e728ed2..fe95fbe 100644 --- a/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs +++ b/source/Visibility/ProAppVisibilityModule/ViewModels/ProTabBaseViewModel.cs @@ -59,6 +59,8 @@ public ProTabBaseViewModel() // Pro Events ArcGIS.Desktop.Framework.Events.ActiveToolChangedEvent.Subscribe(OnActiveToolChanged); + + ClearGraphicsVisible = false; } private async void OnMapPointToolActivated(object obj) @@ -154,6 +156,11 @@ public bool HasMapGraphics } } + /// + /// Property used to determine if ClearGraphics button should be visible + /// + public bool ClearGraphicsVisible { get; set; } + private MapPoint point1 = null; /// /// Property for the observer MapPoint diff --git a/source/Visibility/VisibilityLibrary/Views/LLOSView.xaml b/source/Visibility/VisibilityLibrary/Views/LLOSView.xaml index 5a142fc..86175db 100644 --- a/source/Visibility/VisibilityLibrary/Views/LLOSView.xaml +++ b/source/Visibility/VisibilityLibrary/Views/LLOSView.xaml @@ -15,6 +15,8 @@ + + @@ -344,9 +346,10 @@ Margin="3,20,0,0" Command="{Binding ClearGraphicsCommand}" Content="{x:Static prop:Resources.LabelClearGraphics}" - ToolTip="{x:Static prop:Resources.LabelClearGraphics}"> + ToolTip="{x:Static prop:Resources.LabelClearGraphics}" + Visibility="{Binding Path=ClearGraphicsVisible, Converter={StaticResource BoolToVis}}" > -