コード例 #1
0
ファイル: MapFixer.cs プロジェクト: AKROGIS/MapFixer
        /// <summary>
        /// Fix the broken links in map that have solutions in moves.
        /// Must be called on the MCT (inside QueuedTask.Run)
        /// </summary>
        /// <param name="map">The map to check</param>
        /// <param name="moves">A database of known solutions to broken links</param>
        public static void FixMap(Map map, Moves moves)
        {
            if (map == null)
            {
                return;
            }

            var autoFixesApplied    = 0;
            var unFixableLayers     = 0;
            var intentionallyBroken = 0;

            foreach (var layer in map.GetLayersAsFlattenedList().Where(l => l.ConnectionStatus == ConnectionStatus.Broken))
            {
                Moves.GisDataset?oldDataset = GetDataset(layer);
                if (oldDataset == null)
                {
                    unFixableLayers += 1;
                    continue;
                }
                Moves.Solution?maybeSolution = moves.GetSolution(oldDataset.Value);
                if (maybeSolution == null)
                {
                    unFixableLayers += 1;
                    continue;
                }
                Moves.Solution solution = maybeSolution.Value;
                if (solution.NewDataset != null && solution.ReplacementDataset == null &&
                    solution.ReplacementLayerFilePath == null && solution.Remarks == null)
                {
                    // This is the typical solution (only choice is to update the dataset path).
                    // The user is not prompted, since there is no good reason for a user not to click OK.
                    // The user will be warned that layers have been fixed, and they can choose to not save the changes.
                    autoFixesApplied += 1;
                    RepairWithDataset(layer, oldDataset.Value, solution.NewDataset.Value);
                }
                else
                {
                    var selector = new SelectorWindow
                    {
                        // TODO: fix this -
                        // Setting the owner to the MainWindow will keep the dialog tied to the MainWindow, but it causes the following exception
                        // System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.'
                        // neither Dispatch.invoke(() => { ... }) on selector or the MainWindow worked.
                        //Owner = FrameworkApplication.Current.MainWindow,
                        LayerName = layer.Name,
                        Solution  = solution
                    };
                    selector.ShowDialog();
                    if (selector.UseLayerFile)
                    {
                        RepairWithLayerFile(map, layer, selector.LayerFile, selector.KeepBrokenLayer);
                        if (selector.KeepBrokenLayer)
                        {
                            intentionallyBroken += 1;
                        }
                    }
                    else if (selector.UseDataset && selector.Dataset.HasValue)
                    {
                        RepairWithDataset(layer, oldDataset.Value, selector.Dataset.Value);
                    }
                    else
                    {
                        intentionallyBroken += 1;
                    }
                }
            }

            // Print a Summary
            var brokenDataSourcesCount = map.GetLayersAsFlattenedList().Count(l => l.ConnectionStatus == ConnectionStatus.Broken);

            // Some unfixable layers may actually have been corrected by fixing the Mosaic Dataset Layer
            // Limit unfixable to no more than the actual number of broken layers
            unFixableLayers = Math.Min(unFixableLayers, brokenDataSourcesCount);
            if (autoFixesApplied > 0 || unFixableLayers > 0 || brokenDataSourcesCount > intentionallyBroken)
            {
                string msg = "";
                if (autoFixesApplied > 0)
                {
                    var plural = autoFixesApplied == 1 ? " was" : "s were";
                    msg +=
                        $"{autoFixesApplied} broken layer{plural} automatically fixed based on the new locations of known data sources. " +
                        "Close the document without saving if this is not what you want.";
                }
                if (autoFixesApplied > 0 && (unFixableLayers > 0 || brokenDataSourcesCount > 0))
                {
                    msg += "\n\n";
                }
                if (unFixableLayers > 0)
                {
                    msg +=
                        $"{unFixableLayers} broken layers could not be fixed; breakage is not due to changes on the PDS (X drive).";
                }
                if (unFixableLayers < brokenDataSourcesCount - intentionallyBroken)
                {
                    // We know that brokenDataSources.Count must be >= unFixableLayers, therefore some of the fixes need fixing
                    if (unFixableLayers > 0)
                    {
                        msg += "\n\n";
                    }
                    msg += "Additional fixes are possible and needed.  Please save, close and reopen your map.";
                }
                var title = @"Map Fixer Summary";
                MessageBox.Show(msg, title);
            }
        }
コード例 #2
0
ファイル: MapFixer.cs プロジェクト: AKROGIS/MapFixer
        public void FixMap(Moves moves)
        {
            var brokenDataSources = GetBrokenDataSources();

            // We do not need to do anything if there was nothing to fix
            if (brokenDataSources.Count == 0)
            {
                return;
            }
            var alert               = new AlertForm();
            var selector            = new SelectionForm();
            var autoFixesApplied    = 0;
            var unFixableLayers     = 0;
            var intentionallyBroken = 0;

            foreach (var item in brokenDataSources)
            {
                var mapIndex = item.Key;
                foreach (IDataLayer2 dataLayer in item.Value)
                {
                    var layerName = dataLayer is IDataset dataset ? dataset.Name : ((ILayer2)dataLayer).Name;
                    Moves.GisDataset oldDataset    = GetDataset(dataLayer);
                    Moves.Solution?  maybeSolution = moves.GetSolution(oldDataset);
                    if (maybeSolution == null)
                    {
                        unFixableLayers += 1;
                        continue;
                    }
                    Moves.Solution solution = maybeSolution.Value;
                    if (solution.NewDataset != null && solution.ReplacementDataset == null &&
                        solution.ReplacementLayerFilePath == null && solution.Remarks == null)
                    {
                        // This is the optimal action.
                        // The user is not prompted, since there is no good reason for a user not to click OK.
                        // The user will be warned that layers have been fixed, and they can choose to not save the changes.
                        autoFixesApplied += 1;
                        RepairWithDataset(dataLayer, oldDataset, solution.NewDataset.Value, alert);
                    }
                    else
                    {
                        selector.LayerName = layerName;
                        //selector.GisDataset = oldDataset;
                        selector.Solution = solution;
                        selector.ShowDialog(new WindowWrapper(new IntPtr(ArcMap.Application.hWnd)));
                        if (selector.UseLayerFile)
                        {
                            RepairWithLayerFile(mapIndex, dataLayer, selector.LayerFile, selector.KeepBrokenLayer, alert);
                            if (selector.KeepBrokenLayer)
                            {
                                intentionallyBroken += 1;
                            }
                        }
                        else if (selector.UseDataset && selector.Dataset.HasValue)
                        {
                            RepairWithDataset(dataLayer, oldDataset, selector.Dataset.Value, alert);
                        }
                        else
                        {
                            intentionallyBroken += 1;
                        }
                    }
                }
            }

            // Refresh TOC
            ArcMap.Document.UpdateContents();        //update the TOC
            ArcMap.Document.ActivatedView.Refresh(); // refresh the view

            // Print a Summary
            brokenDataSources = GetBrokenDataSources();
            // Some unfixable layers may actually have been corrected by fixing the Mosaic Dataset Layer
            // Limit unfixable to no more than the actual number of broken layers
            unFixableLayers = Math.Min(unFixableLayers, brokenDataSources.Count);
            if (autoFixesApplied > 0 || unFixableLayers > 0 || brokenDataSources.Count > intentionallyBroken)
            {
                string msg = "";
                if (autoFixesApplied > 0)
                {
                    msg +=
                        $"{autoFixesApplied} broken layers were automatically fixed based on the new locations of known data sources. " +
                        "Close the document without saving if this is not what you want.";
                }
                if (autoFixesApplied > 0 && (unFixableLayers > 0 || brokenDataSources.Count > 0))
                {
                    msg += "\n\n";
                }
                if (unFixableLayers > 0)
                {
                    msg +=
                        $"{unFixableLayers} broken layers could not be fixed; breakage is not due to changes on the PDS (X drive).";
                }
                if (unFixableLayers < brokenDataSources.Count - intentionallyBroken)
                {
                    // We know that brokenDataSources.Count must be >= unFixableLayers, therefore some of the fixes need fixing
                    if (unFixableLayers > 0)
                    {
                        msg += "\n\n";
                    }
                    msg += "Additional fixes are possible and needed.  Please save, close and reopen your map.";
                }
                alert.Text        = @"Map Fixer Summary";
                alert.msgBox.Text = msg;
                alert.ShowDialog(new WindowWrapper(new IntPtr(ArcMap.Application.hWnd)));
            }
        }