/// <summary>
        /// Where all of the work is done.  Override from TabBaseViewModel
        /// </summary>
        internal override async Task CreateMapElement()
        {
            try
            {
                IsRunning = true;
                await ReadSelectedLayers();

                if (!CanCreateElement || MapView.Active == null || MapView.Active.Map == null || string.IsNullOrWhiteSpace(SelectedSurfaceName))
                {
                    return;
                }

                if (RLOS_ObserversInExtent.Any() || ObserverAddInPoints.Any())
                {
                    bool success = await ExecuteVisibilityRLOS();

                    if (!success)
                    {
                        MessageBox.Show("RLOS 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);

                //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;
                if (ObserverAddInPoints.Count == 0)
                {
                    IsRLOSValidSelection = false;
                }
                else
                {
                    IsRLOSValidSelection = true;
                }

                ClearRLOSCollections();
                ValidateRLOS_LayerSelection();
            }
        }
Пример #2
0
        private async Task ReadSelectedLayers()
        {
            var observerPoints = new ObservableCollection <MapPoint>();

            RLOS_ObserversInExtent.Clear();
            RLOS_ObserversOutOfExtent.Clear();

            var surfaceEnvelope = await GetSurfaceEnvelope();

            var selectedFeatures = await QueuedTask.Run(() => { return(MapView.Active.Map.GetSelection()); });

            await QueuedTask.Run(() =>
            {
                var selectedFeaturesCollections = selectedFeatures.Where(x => x.Key.Name == SelectedRLOS_ObserverLyrName)
                                                  .Select(x => x.Value).FirstOrDefault();
                ReadPointFromLayer(surfaceEnvelope, RLOS_ObserversInExtent, RLOS_ObserversOutOfExtent, SelectedRLOS_ObserverLyrName, selectedFeaturesCollections);
            });
        }
Пример #3
0
        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);
        }
Пример #4
0
 internal void ClearRLOSCollections()
 {
     RLOS_ObserversInExtent.Clear();
     RLOS_ObserversOutOfExtent.Clear();
 }