Example #1
0
        private void RepairWithDataset(IDataLayer2 dataLayer, Moves.GisDataset oldDataset, Moves.GisDataset newDataset, AlertForm alert)
        {
            // This routine, can only repair workspace path, and dataset name.
            // The workspace type and data type must be the same.
            // This can be checked with the CSV verifier. Violations will be ignored in the CSV loader
            if (oldDataset.DatasourceType != newDataset.DatasourceType ||
                oldDataset.WorkspaceProgId != newDataset.WorkspaceProgId)
            {
                return;
            }
            var helper = (IDataSourceHelperLayer) new DataSourceHelper();

            if (oldDataset.DatasourceName == newDataset.DatasourceName)
            {
                helper.FindAndReplaceWorkspaceNamePath((ILayer)dataLayer, oldDataset.Workspace.Folder, newDataset.Workspace.Folder, false);
            }
            else
            {
                // I can't find a way to simply change the name of the dataset in a layer.
                // To set the data source of a layer I need to first open the data source (using the newDataset properties)
                // I can then use the Name (as IName) of the data source to fix the layer.
                IDataset dataset = TryOpenDataset(newDataset);
                if (dataset == null)
                {
                    alert.Text        = @"Error";
                    alert.msgBox.Text = $"Map Fixer is unable to repair the layer {((ILayer2)dataLayer).Name}. " +
                                        "Use the 'Set Data Source button' on the Source tab of the layer properties dialog to " +
                                        $"set the data source to {newDataset.Workspace.Folder}\\{newDataset.DatasourceName}";
                    alert.ShowDialog(new WindowWrapper(new IntPtr(ArcMap.Application.hWnd)));
                    return;
                }
                helper.ReplaceName((ILayer)dataLayer, dataset.FullName, false);
            }
        }
Example #2
0
        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)));
            }
        }
Example #3
0
        private void RepairWithLayerFile(int mapIndex, IDataLayer2 dataLayer, string newLayerFile, bool keepBrokenLayer, AlertForm alert)
        {
            // Add Layer File to ActiveView Snippet: (http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#//004900000050000000)
            IGxLayer gxLayer = new GxLayer();
            IGxFile  gxFile  = (IGxFile)gxLayer;

            gxFile.Path = newLayerFile;
            if (gxLayer.Layer != null)
            {
                // AddLayer will add the new layer at the most appropriate point in the TOC.
                //   This is much easier and potentially less confusing than adding at the old data location.
                ArcMap.Document.Maps.Item[mapIndex].AddLayer(gxLayer.Layer);
                if (!keepBrokenLayer)
                {
                    ArcMap.Document.Maps.Item[mapIndex].DeleteLayer((ILayer)dataLayer);
                }
            }
            else
            {
                // Notify the user that the LayerFile could not be opened (missing, corrupt, ...)
                alert.Text        = @"Error";
                alert.msgBox.Text = $"The layer file '{newLayerFile}' could not be opened.";
                alert.ShowDialog(new WindowWrapper(new IntPtr(ArcMap.Application.hWnd)));
            }
        }