/// <summary> /// Here we need to create the lines of sight and determine is a target can be seen or not /// </summary> internal override async Task CreateMapElement() { try { await ReadSelectedLayers(); if (string.IsNullOrWhiteSpace(SelectedSurfaceName)) { ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgSurfaceLayerNotFound, VisibilityLibrary.Properties.Resources.CaptionError); } if (!CanCreateElement || MapView.Active == null || MapView.Active.Map == null) { return; } if ((LLOS_ObserversInExtent.Any() || ObserverAddInPoints.Any()) && LLOS_TargetsInExtent.Any() || TargetAddInPoints.Any()) { 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); } } else { ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(VisibilityLibrary.Properties.Resources.OutOfExtentMsg, VisibilityLibrary.Properties.Resources.OutOfExtentHeader); } DeactivateTool(VisibilityMapTool.ToolId); OnMapPointToolDeactivated(null); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); //await base.CreateMapElement(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(VisibilityLibrary.Properties.Resources.ExceptionSomethingWentWrong, VisibilityLibrary.Properties.Resources.CaptionError); } finally { IsRunning = false; ClearLLOSCollections(); } }
/// <summary> /// Here we need to create the lines of sight and determine is a target can be seen or not /// Visualize the visible targets with GREEN circles /// Visualize the non visible targets with RED circles /// Visualize the number of observers that can see a target with a label # /// Visualize an observer that can see no targets with a RED circle on top of a BLUE circle /// Visualize an observer that can see at least one target with a GREEN circle on top of a BLUE circle /// </summary> internal override void CreateMapElement() { try { IsRunning = true; IPolyline longestLine = new PolylineClass(); ReadSelectedLayerPoints(); if (!CanCreateElement || ArcMap.Document == null || ArcMap.Document.FocusMap == null || string.IsNullOrWhiteSpace(SelectedSurfaceName)) { return; } if ((LLOS_ObserversInExtent.Any() || ObserverAddInPoints.Any()) && LLOS_TargetsInExtent.Any() || TargetAddInPoints.Any()) { // take your observer and target points and get lines of sight var observerPoints = new ObservableCollection <AddInPoint>(LLOS_ObserversInExtent.Select(x => x.AddInPoint).Union(ObserverInExtentPoints)); var targetPoints = new ObservableCollection <AddInPoint>(LLOS_TargetsInExtent.Select(x => x.AddInPoint).Union(TargetInExtentPoints)); var surface = GetSurfaceFromMapByName(ArcMap.Document.FocusMap, SelectedSurfaceName); if (surface == null) { return; } 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; if (geoDataset == null) { System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgTryAgain, VisibilityLibrary.Properties.Resources.CaptionError); return; } SelectedSurfaceSpatialRef = geoDataset.SpatialReference; if (SelectedSurfaceSpatialRef is IGeographicCoordinateSystem) { MessageBox.Show(VisibilityLibrary.Properties.Resources.LLOSUserPrompt, VisibilityLibrary.Properties.Resources.LLOSUserPromptCaption); return; } if (ArcMap.Document.FocusMap.SpatialReference.FactoryCode != geoDataset.SpatialReference.FactoryCode) { MessageBox.Show(VisibilityLibrary.Properties.Resources.LOSDataFrameMatch, VisibilityLibrary.Properties.Resources.LOSSpatialReferenceCaption); return; } SelectedSurfaceSpatialRef = geoDataset.SpatialReference; var geoBridge = (IGeoDatabaseBridge2) new GeoDatabaseHelperClass(); IPoint pointObstruction = null; IPolyline polyVisible = null; IPolyline polyInvisible = null; bool targetIsVisible = false; double finalObserverOffset = GetOffsetInZUnits(ObserverOffset.Value, surface.ZFactor, OffsetUnitType); double finalTargetOffset = GetOffsetInZUnits(TargetOffset.Value, surface.ZFactor, OffsetUnitType); var DictionaryTargetObserverCount = new Dictionary <IPoint, int>(); foreach (var observerPoint in observerPoints) { // keep track of visible targets for this observer var CanSeeAtLeastOneTarget = false; var z1 = surface.GetElevation(observerPoint.Point) + finalObserverOffset; if (double.IsNaN(z1)) { System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.LLOSPointsOutsideOfSurfaceExtent, VisibilityLibrary.Properties.Resources.MsgCalcCancelled); return; } foreach (var targetPoint in targetPoints) { var z2 = surface.GetElevation(targetPoint.Point) + finalTargetOffset; if (double.IsNaN(z2)) { System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.LLOSPointsOutsideOfSurfaceExtent, VisibilityLibrary.Properties.Resources.MsgCalcCancelled); return; } var fromPoint = new PointClass() { Z = z1, X = observerPoint.Point.X, Y = observerPoint.Point.Y, ZAware = true } as IPoint; var toPoint = new PointClass() { Z = z2, X = targetPoint.Point.X, Y = targetPoint.Point.Y, ZAware = true } as IPoint; geoBridge.GetLineOfSight(surface, fromPoint, toPoint, out pointObstruction, out polyVisible, out polyInvisible, out targetIsVisible, false, false); var pcol = new PolylineClass() as IPointCollection; pcol.AddPoint(fromPoint); pcol.AddPoint(toPoint); IPolyline pcolPolyline = pcol as IPolyline; longestLine = (longestLine != null && longestLine.Length < pcolPolyline.Length) ? pcolPolyline : longestLine; // set the flag if we can see at least one target if (targetIsVisible) { CanSeeAtLeastOneTarget = true; // update target observer count 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 }, size: 5); } if (polyInvisible != null) { AddGraphicToMap(polyInvisible, new RgbColorClass() { Red = 255 }, size: 3); } if (polyVisible == null && polyInvisible == null) { if (targetIsVisible) { AddGraphicToMap(pcol as IPolyline, new RgbColorClass() { Green = 255 }, size: 3); } else { AddGraphicToMap(pcol as IPolyline, new RgbColorClass() { Red = 255 }, size: 3); } } } // visualize observer // add blue dot AddGraphicToMap(observerPoint.Point, new RgbColorClass() { Blue = 255 }, size: 10); if (CanSeeAtLeastOneTarget) { // add green dot AddGraphicToMap(observerPoint.Point, new RgbColorClass() { Green = 255 }); } else { // add red dot AddGraphicToMap(observerPoint.Point, new RgbColorClass() { Red = 255 }); } } VisualizeTargets(DictionaryTargetObserverCount, targetPoints); if ((ObserverInExtentPoints.Any() || LLOS_ObserversInExtent.Any()) && (TargetInExtentPoints.Any() || LLOS_TargetsInExtent.Any())) { ZoomToExtent(longestLine); } DisplayOutOfExtentMsg(); //display points present out of extent var colorObserver = new RgbColorClass() { Blue = 255 }; var colorTarget = new RgbColorClass() { Red = 255 }; var colorObserverBorder = new RgbColorClass() { Red = 255, Blue = 255, Green = 255 }; var colorTargetBorder = new RgbColorClass() { Red = 0, Blue = 0, Green = 0 }; var observerOutOfExtent = new ObservableCollection <AddInPoint>(LLOS_ObserversOutOfExtent.Select(x => x.AddInPoint).Union(ObserverOutExtentPoints)); foreach (var point in observerOutOfExtent) { AddGraphicToMap(point.Point, colorObserver, markerStyle: esriSimpleMarkerStyle.esriSMSX, size: 10, borderColor: colorObserverBorder); } var targetOutOfExtent = new ObservableCollection <AddInPoint>(LLOS_TargetsOutOfExtent.Select(x => x.AddInPoint).Union(TargetOutExtentPoints)); foreach (var point in targetOutOfExtent) { AddGraphicToMap(point.Point, colorTarget, markerStyle: esriSimpleMarkerStyle.esriSMSX, size: 10, borderColor: colorTargetBorder); } } else { System.Windows.MessageBox.Show(VisibilityLibrary.Properties.Resources.OutOfExtentMsg, VisibilityLibrary.Properties.Resources.OutOfExtentHeader); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); System.Windows.Forms.MessageBox.Show(VisibilityLibrary.Properties.Resources.ExceptionSomethingWentWrong, VisibilityLibrary.Properties.Resources.CaptionError); } finally { IsRunning = false; ClearLLOSCollections(); ValidateLLOS_LayerSelection(); } }