/// <summary> /// Method to handle the display coordinate type change /// Need to update the list boxes /// </summary> /// <param name="obj">null, not used</param> internal virtual void OnDisplayCoordinateTypeChanged(object obj) { var list = ObserverAddInPoints.ToList(); var inExtentList = ObserverInExtentPoints.ToList(); var outExtentList = ObserverOutExtentPoints.ToList(); ObserverAddInPoints.Clear(); ObserverInExtentPoints.Clear(); ObserverOutExtentPoints.Clear(); foreach (var item in list) { ObserverAddInPoints.Add(item); } foreach (var item in inExtentList) { ObserverInExtentPoints.Add(item); } foreach (var item in outExtentList) { ObserverOutExtentPoints.Add(item); } RaisePropertyChanged(() => HasMapGraphics); }
/// <summary> /// Override to add aditional items in the class to reset tool /// </summary> /// <param name="toolReset"></param> internal override async Task Reset(bool toolReset) { try { await base.Reset(toolReset); if (MapView.Active == null || MapView.Active.Map == null) { return; } // reset surface names OC await ResetSurfaceNames(); Application.Current.Dispatcher.Invoke(() => { // reset observer points ObserverAddInPoints.Clear(); ObserverInExtentPoints.Clear(); ObserverOutExtentPoints.Clear(); ClearTempGraphics(); }); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } }
/// <summary> /// Override this event to collect observer points based on tool mode /// </summary> /// <param name="obj">MapPointToolMode</param> internal override async void OnNewMapPointEvent(object obj) { if (!IsActiveTab) { return; } var point = obj as MapPoint; // ok, we have a point if (point != null && ToolMode == MapPointToolMode.Observer) { if (IsMapClick) { if (!(await IsValidPoint(point, true))) { IsMapClick = false; return; } } // in tool mode "Observer" we add observer points // otherwise ignore var guid = await AddGraphicToMap(point, ColorFactory.Instance.BlueRGB, true, 5.0); var addInPoint = new AddInPoint() { Point = point, GUID = guid }; bool isValid = await IsValidPoint(point, false); Application.Current.Dispatcher.Invoke(() => { if (!isValid) { ObserverOutExtentPoints.Insert(0, addInPoint); } else { ObserverInExtentPoints.Insert(0, addInPoint); } ObserverAddInPoints.Insert(0, addInPoint); }); IsMapClick = false; } }
/// <summary> /// Override this event to collect observer points based on tool mode /// </summary> /// <param name="obj">MapPointToolMode</param> internal override void OnNewMapPointEvent(object obj) { if (!IsActiveTab) { return; } var point = obj as IPoint; // ok, we have a point if (ToolMode == MapPointToolMode.Observer) { if (IsMapClick) { if (!(IsValidPoint(point, true))) { IsMapClick = false; return; } } // in tool mode "Observer" we add observer points // otherwise ignore var color = new RgbColorClass() { Blue = 255 } as IColor; var guid = AddGraphicToMap(point, color, true); var addInPoint = new AddInPoint() { Point = point, GUID = guid }; bool isValid = IsValidPoint(point, false); if (!isValid) { ObserverOutExtentPoints.Insert(0, addInPoint); } else { ObserverInExtentPoints.Insert(0, addInPoint); } ObserverAddInPoints.Insert(0, addInPoint); IsMapClick = false; } }
private void DeletePoints(List <AddInPoint> observers) { if (observers == null || !observers.Any()) { return; } // remove graphics from map var guidList = observers.Select(x => x.GUID).ToList(); RemoveGraphics(guidList); foreach (var point in observers) { ObserverAddInPoints.Remove(point); ObserverInExtentPoints.Remove(point); ObserverOutExtentPoints.Remove(point); } }
/// <summary> /// Override to add aditional items in the class to reset tool /// </summary> /// <param name="toolReset"></param> internal override void Reset(bool toolReset) { base.Reset(toolReset); if (ArcMap.Document == null || ArcMap.Document.FocusMap == null) { return; } // reset surface names OC ResetSurfaceNames(ArcMap.Document.FocusMap); // reset observer points ObserverAddInPoints.Clear(); ObserverInExtentPoints.Clear(); ObserverOutExtentPoints.Clear(); ClearTempGraphics(); }
private async Task <bool> ExecuteVisibilityRLOS() { bool success = false; 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); } var observerPoints = new ObservableCollection <AddInPoint>(RLOS_ObserversInExtent.Select(x => x.AddInPoint).Union(ObserverInExtentPoints)); // 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); } } //Validate Dataframe Spatial reference with surface spatial reference if (MapView.Active.Map.SpatialReference.Wkid != surfaceSR.Wkid) { MessageBox.Show(VisibilityLibrary.Properties.Resources.LOSDataFrameMatch, VisibilityLibrary.Properties.Resources.LOSSpatialReferenceCaption); return(false); } await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() => { using (Geodatabase geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(CoreModule.CurrentProject.DefaultGeodatabasePath)))) { executionCounter = 0; int featureDataSetSuffix = 0; var enterpriseDefinitionNames = geodatabase.GetDefinitions <FeatureDatasetDefinition>().Where(i => i.GetName().StartsWith(VisibilityLibrary.Properties.Resources.RLOSFeatureDatasetName)).Select(i => i.GetName()).ToList(); foreach (var defName in enterpriseDefinitionNames) { int n; bool isNumeric = int.TryParse(Regex.Match(defName, @"\d+$").Value, out n); if (isNumeric) { featureDataSetSuffix = featureDataSetSuffix < n ? n : featureDataSetSuffix; } } featureDataSetSuffix = enterpriseDefinitionNames.Count > 0 ? featureDataSetSuffix + 1 : 0; var observerLyrSuffix = GetLayerSuffix(VisibilityLibrary.Properties.Resources.LLOSObserversLayerName, geodatabase); var convertedPolygonLyrSuffix = GetLayerSuffix(VisibilityLibrary.Properties.Resources.RLOSConvertedPolygonsLayerName, geodatabase); var outputLyrSuffix = GetLayerSuffix(VisibilityLibrary.Properties.Resources.RLOSOutputLayerName, geodatabase); var maskLyrSuffix = GetLayerSuffix(VisibilityLibrary.Properties.Resources.RLOSMaskLayerName, geodatabase); executionCounter = new List <int> { featureDataSetSuffix, observerLyrSuffix, convertedPolygonLyrSuffix, outputLyrSuffix, maskLyrSuffix }.Max(); } }); //Create Feature dataset success = await FeatureClassHelper.CreateFeatureDataset(FeatureDatasetName); if (!success) { return(false); } success = await FeatureClassHelper.CreateLayer(FeatureDatasetName, ObserversLayerName, "POINT", true, true); if (!success) { return(false); } // add fields for observer offset await FeatureClassHelper.AddFieldToLayer(ObserversLayerName, VisibilityLibrary.Properties.Resources.OffsetFieldName, "DOUBLE"); await FeatureClassHelper.AddFieldToLayer(ObserversLayerName, VisibilityLibrary.Properties.Resources.OffsetWithZFieldName, "DOUBLE"); await FeatureClassHelper.AddFieldToLayer(ObserversLayerName, VisibilityLibrary.Properties.Resources.IsOutOfExtentFieldName, "SHORT"); // add observer points to feature layer await FeatureClassHelper.CreatingFeatures(ObserversLayerName, observerPoints, GetAsMapZUnits(surfaceSR, ObserverOffset.Value)); //execute only if points are available in surface extent if (ObserverInExtentPoints.Any() || RLOS_ObserversInExtent.Any()) { // update with surface information success = await FeatureClassHelper.AddSurfaceInformation(ObserversLayerName, SelectedSurfaceName, VisibilityLibrary.Properties.Resources.ZFieldName); if (!success) { return(false); } // Visibility var observerOffsetInMapZUnits = GetAsMapZUnits(surfaceSR, ObserverOffset.Value); var surfaceOffsetInMapZUnits = GetAsMapZUnits(surfaceSR, SurfaceOffset); var minDistanceInMapUnits = GetAsMapUnits(surfaceSR, MinDistance); var maxDistanceInMapUnits = GetAsMapUnits(surfaceSR, MaxDistance); var horizontalStartAngleInDegrees = GetAngularDistanceFromTo(AngularUnitType, AngularTypes.DEGREES, LeftHorizontalFOV); var horizontalEndAngleInDegrees = GetAngularDistanceFromTo(AngularUnitType, AngularTypes.DEGREES, RightHorizontalFOV); var verticalUpperAngleInDegrees = GetAngularDistanceFromTo(AngularUnitType, AngularTypes.DEGREES, TopVerticalFOV); var verticalLowerAngleInDegrees = GetAngularDistanceFromTo(AngularUnitType, AngularTypes.DEGREES, BottomVerticalFOV); await FeatureClassHelper.UpdateShapeWithZ(ObserversLayerName, VisibilityLibrary.Properties.Resources.ZFieldName, observerOffsetInMapZUnits); await CreateMask(RLOSMaskLayerName, minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, horizontalEndAngleInDegrees, surfaceSR, observerPoints); string maxRangeMaskFeatureClassName = CoreModule.CurrentProject.DefaultGeodatabasePath + System.IO.Path.DirectorySeparatorChar + FeatureDatasetName + System.IO.Path.DirectorySeparatorChar + RLOSMaskLayerName; var environments = Geoprocessing.MakeEnvironmentArray(mask: maxRangeMaskFeatureClassName, overwriteoutput: true); var rlosOutputLayer = CoreModule.CurrentProject.DefaultGeodatabasePath + System.IO.Path.DirectorySeparatorChar + RLOSOutputLayerName; success = await FeatureClassHelper.CreateVisibility(SelectedSurfaceName, ObserversLayerName, rlosOutputLayer, observerOffsetInMapZUnits, surfaceOffsetInMapZUnits, minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, horizontalEndAngleInDegrees, verticalUpperAngleInDegrees, verticalLowerAngleInDegrees, ShowNonVisibleData, environments, false); if (!success) { return(false); } var rlosConvertedPolygonsLayer = CoreModule.CurrentProject.DefaultGeodatabasePath + System.IO.Path.DirectorySeparatorChar + FeatureDatasetName + System.IO.Path.DirectorySeparatorChar + RLOSConvertedPolygonsLayerName; string rangeFanMaskFeatureClassName = string.Empty; if ((MinDistance > 0) || !((horizontalStartAngleInDegrees == 0.0) && (horizontalEndAngleInDegrees == 360.0))) { string RLOSRangeFanMaskLayerName = "RangeFan_" + RLOSMaskLayerName; rangeFanMaskFeatureClassName = CoreModule.CurrentProject.DefaultGeodatabasePath + System.IO.Path.DirectorySeparatorChar + FeatureDatasetName + System.IO.Path.DirectorySeparatorChar + RLOSRangeFanMaskLayerName; await CreateMask(RLOSRangeFanMaskLayerName, minDistanceInMapUnits, maxDistanceInMapUnits, horizontalStartAngleInDegrees, horizontalEndAngleInDegrees, surfaceSR, observerPoints, true); } success = await FeatureClassHelper.IntersectOutput(rlosOutputLayer, rlosConvertedPolygonsLayer, false, "Value", rangeFanMaskFeatureClassName); if (!success) { return(false); } } // add observer points present out of extent to feature layer var outOfExtent = new ObservableCollection <AddInPoint>(RLOS_ObserversOutOfExtent.Select(x => x.AddInPoint).Union(ObserverOutExtentPoints)); await FeatureClassHelper.CreatingFeatures(ObserversLayerName, outOfExtent, GetAsMapZUnits(surfaceSR, ObserverOffset.Value), VisibilityLibrary.Properties.Resources.IsOutOfExtentFieldName); await FeatureClassHelper.CreateUniqueValueRenderer(GetLayerFromMapByName(RLOSConvertedPolygonsLayerName) as FeatureLayer, ShowNonVisibleData, RLOSConvertedPolygonsLayerName, ShowClassicViewshed); var observersLayer = GetLayerFromMapByName(ObserversLayerName) as FeatureLayer; if (observersLayer != null) { await FeatureClassHelper.CreateRLOSObserversRenderer(observersLayer as FeatureLayer); } await FeatureClassHelper.Delete(RLOSOutputLayerName); //await FeatureClassHelper.Delete(RLOSMaskLayerName); // Eventually we will add the new layers to a new group layer for each run // Currently not working in current release of Pro. // From Roshan Herbert - I just spoke with the Dev who wrote the MoveLayer method. Apparently this a known issue. // We have bug to fix this and plan to fix it in the next release. List <Layer> layerList = new List <Layer>(); var observersLayerFromMap = GetLayerFromMapByName(ObserversLayerName); var RLOSConvertedPolygonsLayer = GetLayerFromMapByName(RLOSConvertedPolygonsLayerName); if (observersLayerFromMap != null) { layerList.Add(observersLayerFromMap); } if (RLOSConvertedPolygonsLayer != null) { layerList.Add(GetLayerFromMapByName(RLOSConvertedPolygonsLayerName)); } await FeatureClassHelper.MoveLayersToGroupLayer(layerList, FeatureDatasetName); //string groupName = "RLOS Group"; //if (executionCounter > 0) // groupName = string.Format("{0}_{1}", groupName, executionCounter.ToString()); //await FeatureClassHelper.CreateGroupLayer(layerList, groupName); // for now we are not resetting after a run of the tool //await Reset(true); // Get the extent of the output layer and zoom to extent var layer = GetLayerFromMapByName(RLOSConvertedPolygonsLayerName); if (layer != null) { var envelope = await QueuedTask.Run(() => layer.QueryExtent()); await ZoomToExtent(envelope); } var surfaceEnvelope = await GetSurfaceEnvelope(); await DisplayOutOfExtentMsg(); success = true; } catch (Exception ex) { Debug.Print(ex.Message); success = false; } return(success); }
private async Task <bool> ExecuteVisibilityLLOS() { bool success = false; 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); Application.Current.Dispatcher.Invoke(() => { TargetAddInPoints.Clear(); ObserverAddInPoints.Clear(); ObserverInExtentPoints.Clear(); TargetInExtentPoints.Clear(); ObserverOutExtentPoints.Clear(); TargetOutExtentPoints.Clear(); ClearTempGraphics(); }); await Reset(true); return(false); } if (string.IsNullOrEmpty(SelectedSurfaceName)) { MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgSurfaceLayerNotFound, VisibilityLibrary.Properties.Resources.CaptionError, MessageBoxButton.OK); return(true); } //Validate Dataframe Spatial reference with surface spatial reference IsElevationSurfaceValid = ValidateElevationSurface(MapView.Active.Map, SelectedSurfaceName); if (!await IsElevationSurfaceValid) { ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(VisibilityLibrary.Properties.Resources.LOSDataFrameMatch, VisibilityLibrary.Properties.Resources.LOSSpatialReferenceCaption); SetErrorTemplate(false); return(true); } else { SetErrorTemplate(true); } 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)); // 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); } } await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() => { using (Geodatabase geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(CoreModule.CurrentProject.DefaultGeodatabasePath)))) { executionCounter = 0; int featureDataSetSuffix = 0; var enterpriseDefinitionNames = geodatabase.GetDefinitions <FeatureDatasetDefinition>().Where(i => i.GetName().StartsWith(VisibilityLibrary.Properties.Resources.LLOSFeatureDatasetName)).Select(i => i.GetName()).ToList(); foreach (var defName in enterpriseDefinitionNames) { int n; bool isNumeric = int.TryParse(Regex.Match(defName, @"\d+$").Value, out n); if (isNumeric) { featureDataSetSuffix = featureDataSetSuffix < n ? n : featureDataSetSuffix; } } featureDataSetSuffix = enterpriseDefinitionNames.Count > 0 ? featureDataSetSuffix + 1 : 0; var observerLyrSuffix = GetLayerSuffix(VisibilityLibrary.Properties.Resources.LLOSObserversLayerName, geodatabase); var targetLyrSuffix = GetLayerSuffix(VisibilityLibrary.Properties.Resources.LLOSTargetsLayerName, geodatabase); var sightLinesLyrSuffix = GetLayerSuffix(VisibilityLibrary.Properties.Resources.LLOSSightLinesLayerName, geodatabase); var outputLyrSuffix = GetLayerSuffix(VisibilityLibrary.Properties.Resources.LLOSOutputLayerName, geodatabase); executionCounter = new List <int> { featureDataSetSuffix, observerLyrSuffix, targetLyrSuffix, sightLinesLyrSuffix, outputLyrSuffix }.Max(); } }); //Create Feature dataset success = await FeatureClassHelper.CreateFeatureDataset(FeatureDatasetName); if (!success) { return(false); } success = await FeatureClassHelper.CreateLayer(FeatureDatasetName, ObserversLayerName, "POINT", true, true); if (!success) { return(false); } // add fields for observer offset await FeatureClassHelper.AddFieldToLayer(ObserversLayerName, VisibilityLibrary.Properties.Resources.OffsetFieldName, "DOUBLE"); await FeatureClassHelper.AddFieldToLayer(ObserversLayerName, VisibilityLibrary.Properties.Resources.OffsetWithZFieldName, "DOUBLE"); await FeatureClassHelper.AddFieldToLayer(ObserversLayerName, VisibilityLibrary.Properties.Resources.TarIsVisFieldName, "SHORT"); success = await FeatureClassHelper.CreateLayer(FeatureDatasetName, TargetsLayerName, "POINT", true, true); if (!success) { return(false); } // add fields for target offset await FeatureClassHelper.AddFieldToLayer(TargetsLayerName, VisibilityLibrary.Properties.Resources.OffsetFieldName, "DOUBLE"); await FeatureClassHelper.AddFieldToLayer(TargetsLayerName, VisibilityLibrary.Properties.Resources.OffsetWithZFieldName, "DOUBLE"); await FeatureClassHelper.AddFieldToLayer(TargetsLayerName, VisibilityLibrary.Properties.Resources.NumOfObserversFieldName, "SHORT"); // add observer points to feature layer await FeatureClassHelper.CreatingFeatures(ObserversLayerName, observerPoints, GetAsMapZUnits(surfaceSR, ObserverOffset.Value)); // add target points to feature layer await FeatureClassHelper.CreatingFeatures(TargetsLayerName, targetPoints, GetAsMapZUnits(surfaceSR, TargetOffset.Value)); // update with surface information 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)); // create sight lines GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); success = await FeatureClassHelper.CreateSightLines(ObserversLayerName, TargetsLayerName, CoreModule.CurrentProject.DefaultGeodatabasePath + System.IO.Path.DirectorySeparatorChar + FeatureDatasetName + System.IO.Path.DirectorySeparatorChar + SightLinesLayerName, VisibilityLibrary.Properties.Resources.OffsetWithZFieldName, VisibilityLibrary.Properties.Resources.OffsetWithZFieldName); if (!success) { return(false); } // LOS GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); success = await FeatureClassHelper.CreateLOS(SelectedSurfaceName, CoreModule.CurrentProject.DefaultGeodatabasePath + System.IO.Path.DirectorySeparatorChar + FeatureDatasetName + System.IO.Path.DirectorySeparatorChar + SightLinesLayerName, CoreModule.CurrentProject.DefaultGeodatabasePath + System.IO.Path.DirectorySeparatorChar + FeatureDatasetName + System.IO.Path.DirectorySeparatorChar + OutputLayerName); if (!success) { return(false); } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); // join fields with sight lines await FeatureClassHelper.JoinField(CoreModule.CurrentProject.DefaultGeodatabasePath + System.IO.Path.DirectorySeparatorChar + FeatureDatasetName + System.IO.Path.DirectorySeparatorChar + SightLinesLayerName, "OID", CoreModule.CurrentProject.DefaultGeodatabasePath + System.IO.Path.DirectorySeparatorChar + FeatureDatasetName + System.IO.Path.DirectorySeparatorChar + OutputLayerName, "SourceOID", new string[] { "TarIsVis" }); // gather results for updating observer and target layers var sourceOIDs = await FeatureClassHelper.GetSourceOIDs(OutputLayerName); //if (sourceOIDs.Count > 0) //{ var visStats = await FeatureClassHelper.GetVisibilityStats(sourceOIDs, SightLinesLayerName); await FeatureClassHelper.UpdateLayersWithVisibilityStats(visStats, ObserversLayerName, TargetsLayerName); //} var observersLayer = GetLayerFromMapByName(ObserversLayerName) as FeatureLayer; var targetsLayer = GetLayerFromMapByName(TargetsLayerName) as FeatureLayer; var sightLinesLayer = GetLayerFromMapByName(SightLinesLayerName) as FeatureLayer; var outputLayer = GetLayerFromMapByName(OutputLayerName) as FeatureLayer; var observerOutOfExtent = new ObservableCollection <AddInPoint>(LLOS_ObserversOutOfExtent.Select(x => x.AddInPoint).Union(ObserverOutExtentPoints)); // add observer points present out of extent to feature layer await FeatureClassHelper.CreatingFeatures(ObserversLayerName, observerOutOfExtent, GetAsMapZUnits(surfaceSR, TargetOffset.Value), VisibilityLibrary.Properties.Resources.TarIsVisFieldName); var targetOutOfExtent = new ObservableCollection <AddInPoint>(LLOS_TargetsOutOfExtent.Select(x => x.AddInPoint).Union(TargetOutExtentPoints)); // add target points present out of extent to feature layer await FeatureClassHelper.CreatingFeatures(TargetsLayerName, targetOutOfExtent, GetAsMapZUnits(surfaceSR, TargetOffset.Value), VisibilityLibrary.Properties.Resources.NumOfObserversFieldName); if (observersLayer != null && targetsLayer != null && sightLinesLayer != null && outputLayer != null) { await FeatureClassHelper.CreateObserversRenderer(GetLayerFromMapByName(ObserversLayerName) as FeatureLayer); await FeatureClassHelper.CreateTargetsRenderer(GetLayerFromMapByName(TargetsLayerName) as FeatureLayer); await FeatureClassHelper.CreateTargetLayerLabels(GetLayerFromMapByName(TargetsLayerName) as FeatureLayer); await FeatureClassHelper.CreateVisCodeRenderer(GetLayerFromMapByName(SightLinesLayerName) as FeatureLayer, VisibilityLibrary.Properties.Resources.TarIsVisFieldName, 1, 0, ColorFactory.Instance.WhiteRGB, ColorFactory.Instance.BlackRGB, 6.0, 6.0); await FeatureClassHelper.CreateVisCodeRenderer(GetLayerFromMapByName(OutputLayerName) as FeatureLayer, VisibilityLibrary.Properties.Resources.VisCodeFieldName, 1, 2, ColorFactory.Instance.GreenRGB, ColorFactory.Instance.RedRGB, 5.0, 3.0); //await Reset(true); //string groupName = "LLOS Group"; //if (executionCounter > 0) // groupName = string.Format("{0}_{1}", groupName, executionCounter.ToString()); //await FeatureClassHelper.CreateGroupLayer(layerList, groupName); // for now we are not resetting after a run of the tool //await Reset(true); List <Layer> lyrList = new List <Layer>(); lyrList.Add(observersLayer); lyrList.Add(targetsLayer); lyrList.Add(outputLayer); lyrList.Add(sightLinesLayer); await FeatureClassHelper.MoveLayersToGroupLayer(lyrList, FeatureDatasetName); var envelope = await QueuedTask.Run(() => outputLayer.QueryExtent()); await ZoomToExtent(envelope); var surfaceEnvelope = await GetSurfaceEnvelope(); await DisplayOutOfExtentMsg(surfaceEnvelope); success = true; } else { success = false; } } catch (Exception ex) { success = false; Debug.Print(ex.Message); } return(success); }
/// <summary> /// Override this event to collect observer points based on tool mode /// </summary> /// <param name="obj">MapPointToolMode</param> internal override async void OnNewMapPointEvent(object obj) { if (!IsActiveTab) { return; } //if (string.IsNullOrEmpty(SelectedSurfaceName)) //{ // MessageBox.Show(VisibilityLibrary.Properties.Resources.MsgSurfaceLayerNotFound, // VisibilityLibrary.Properties.Resources.CaptionError, MessageBoxButton.OK); // return; //} //IsElevationSurfaceValid = ValidateElevationSurface(MapView.Active.Map, SelectedSurfaceName); //if (!await IsElevationSurfaceValid) //{ // MessageBox.Show(VisibilityLibrary.Properties.Resources.LOSDataFrameMatch, VisibilityLibrary.Properties.Resources.LOSSpatialReferenceCaption); // SelectedSurfaceTooltip = VisibilityLibrary.Properties.Resources.LOSDataFrameMatch; // SetErrorTemplate(false); // return; //} var point = obj as MapPoint; // ok, we have a point if (point != null && ToolMode == MapPointToolMode.Observer) { if (IsMapClick) { if (!(await IsValidPoint(point, true))) { IsMapClick = false; return; } } // in tool mode "Observer" we add observer points // otherwise ignore var guid = await AddGraphicToMap(point, ColorFactory.Instance.BlueRGB, true, 5.0); var addInPoint = new AddInPoint() { Point = point, GUID = guid }; bool isValid = await IsValidPoint(point, false); Application.Current.Dispatcher.Invoke(() => { if (!isValid) { ObserverOutExtentPoints.Insert(0, addInPoint); } else { ObserverInExtentPoints.Insert(0, addInPoint); } ObserverAddInPoints.Insert(0, addInPoint); }); IsMapClick = false; } }
/// <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(); } }