Beispiel #1
0
 private void InitDataConnection(CIMStandardDataConnection connection)
 {
     DataSetName         = connection.Dataset;
     DataSetType         = FixDatasetType(connection.DatasetType);
     DataSourceName      = connection.Dataset;
     WorkspacePath       = FixWorkspacePath(connection.WorkspaceConnectionString);
     WorkspaceProgId     = connection.WorkspaceFactory.ToString();
     WorkspaceType       = connection.WorkspaceFactory.ToString();
     DataSource          = BuildFullDataSourceName();
     ConnectionClassName = null;
 }
        private static string GetStandardDataPathName(CIMStandardDataConnection dataConnection)
        {
            string connectStr    = dataConnection?.WorkspaceConnectionString; // e.g.  "DATABASE=D:\Temp".
            string fileName      = dataConnection?.Dataset;                   // e.g.  "test.shp".
            string fileDirectory = "";

            if (connectStr?.Length > 9)
            {
                fileDirectory = connectStr.Substring(9) + Path.DirectorySeparatorChar; // e.g. "D:\Temp\".
            }
            return(fileDirectory + fileName);                                          // e.g. "D:\Temp\test.shp".
        }
        private async void ChangeDatasource(FeatureLayer featLayer, string newGDB)
        {
            await QueuedTask.Run(() =>
            {
                // provide a replacement data connection object
                CIMDataConnection updatedDataConnection = new CIMStandardDataConnection()
                {
                    WorkspaceConnectionString = $"DATABASE={newGDB}",
                    WorkspaceFactory          = WorkspaceFactory.FileGDB,
                    DatasetType = esriDatasetType.esriDTFeatureClass,
                    Dataset     = featLayer.Name
                };
                // the updated Data connection should look like this:
                // CustomWorkspaceFactoryCLSID: null
                // Dataset: "TestMultiPoints"
                // DatasetType: esriDTFeatureClass
                // WorkspaceConnectionString: "DATABASE=C:\\Data\\FeatureTest\\FeatureTest.gdb"
                // WorkspaceFactory: FileGDB

                // overwrite the data connection
                featLayer.SetDataConnection(updatedDataConnection);
            });
        }
        private Task ChangeUSHighwaysLayerDataConnectionAsync(FeatureLayer featureLayer, string catalogPath)
        {
            return(QueuedTask.Run(() => {
                CIMDataConnection currentDataConnection = featureLayer.GetDataConnection();

                string connection = System.IO.Path.GetDirectoryName(catalogPath);
                string suffix = System.IO.Path.GetExtension(connection).ToLower();

                var workspaceConnectionString = string.Empty;
                WorkspaceFactory wf = WorkspaceFactory.FileGDB;
                if (suffix == ".sde")
                {
                    wf = WorkspaceFactory.SDE;
                    var dbGdbConnection = new DatabaseConnectionFile(new Uri(connection, UriKind.Absolute));
                    workspaceConnectionString = new Geodatabase(dbGdbConnection).GetConnectionString();
                }
                else
                {
                    var dbGdbConnectionFile = new FileGeodatabaseConnectionPath(new Uri(connection, UriKind.Absolute));
                    workspaceConnectionString = new Geodatabase(dbGdbConnectionFile).GetConnectionString();
                }

                string dataset = System.IO.Path.GetFileName(catalogPath);
                // provide a replace data connection method
                CIMStandardDataConnection updatedDataConnection = new CIMStandardDataConnection()
                {
                    WorkspaceConnectionString = workspaceConnectionString,
                    WorkspaceFactory = wf,
                    Dataset = dataset,
                    DatasetType = esriDatasetType.esriDTFeatureClass
                };

                featureLayer.SetDataConnection(updatedDataConnection);

                //For a RDBMS, it might look like this:
                //string connection = "C:\\Work\\temp.sde";
                //Geodatabase sde = new Geodatabase(connection);

                //// provide a replace data connection method
                //CIMStandardDataConnection updatedDataConnection = new CIMStandardDataConnection();
                //updatedDataConnection.WorkspaceConnectionString = sde.GetConnectionString();
                //updatedDataConnection.WorkspaceFactory = WorkspaceFactory.SDE;
                //updatedDataConnection.Dataset = "vtest.usa.states";
                //updatedDataConnection.DatasetType = esriDatasetType.esriDTFeatureClass;



                //// Alternatively, use Layer.FindAndReplaceWorkspacePath()
                ////Note: this will not allow changing the dataset name or workspace type
                ////
                ////string connection = "C:\\Work\\temp.sde";
                ////Geodatabase sde = new Geodatabase(connection);
                ////featureLayer.FindAndReplaceWorkspacePath(((CIMStandardDataConnection)currentDataConnection).WorkspaceConnectionString,
                ////                        sde.GetConnectionString(), true);


                //////////////////////////////////////////////
                ////Please Read
                ////
                //ok, so at this point we have a couple of bugs at 1.1 AND 1.2.....
                //
                //#1: if you switched to a Datasource that invalidates the Renderer, the Renderer does
                //not get invalidated in the UI
                //(eg You had a UniqueValueRenderer on a Field called "CATEGORY", the new datasource
                //does NOT have that field and so the renderer is invalid).
                //
                //#2: By default, Layers are added with a permanent cache. The cache is NOT automatically
                //invalidated so data (eg in the Attribute table, on the screen for draws) does NOT get
                //Refreshed so you have to invalidate the cache manually...

                //So, Bug #1 - we arbitrarily switch the Renderer to a simple renderer as a work around for that...
                featureLayer.SetRenderer(featureLayer.CreateRenderer(new SimpleRendererDefinition()));

                //Bug #2, we manually invalidate the cache
                featureLayer.ClearDisplayCache();
            }));
        }
Beispiel #5
0
        private static void RepairWithDataset(Layer layer, Moves.GisDataset oldDataset, Moves.GisDataset newDataset)
        {
            // This routine, can only repair workspace path, and dataset name.
            // The workspace type and data type must be the same.
            // This is checked with a warning in the CSV verifier.
            // Violations are silently ignored in the CSV loader so this code should never see it
            // however if it escapes, it will also be ignored here as well.
            if (oldDataset.DatasourceType != newDataset.DatasourceType ||
                oldDataset.WorkspaceProgId != newDataset.WorkspaceProgId)
            {
                return;
            }
            if (oldDataset.DatasourceName == newDataset.DatasourceName)
            {
                try
                {
                    // This threw an underlying COM exception with a test case with valid input, so wrap in the try for safely
                    layer.FindAndReplaceWorkspacePath(oldDataset.Workspace.Folder, newDataset.Workspace.Folder, false);
                }
                catch
                {
                    var title = @"Map Fixer Error";
                    var msg   = $"Map Fixer failed to repair the layer {layer.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}";
                    MessageBox.Show(msg, title, System.Windows.MessageBoxButton.OK,
                                    System.Windows.MessageBoxImage.Error);
                }
            }
            else
            {
                if (Enum.TryParse(newDataset.DatasourceType, out esriDatasetType dataType) &&
                    Enum.TryParse(newDataset.WorkspaceProgId, out WorkspaceFactory workspaceFactory))
                {
                    //TODO: Replace the existing data connection with the same sub class of CIMDataConnection,
                    //      Need support from the moves database and GetDataset() below to support this.
                    //      Currently GetDataset() will ignore all but CIMStandardDataConnection, so we can
                    //      safely assume that is what we need to create
                    string workspaceConnection = "DATABASE=" + newDataset.Workspace.Folder;
                    CIMStandardDataConnection updatedDataConnection = new CIMStandardDataConnection()
                    {
                        WorkspaceConnectionString = workspaceConnection,
                        WorkspaceFactory          = workspaceFactory,
                        Dataset     = newDataset.DatasourceName,
                        DatasetType = dataType
                    };
                    layer.SetDataConnection(updatedDataConnection);
                }
                else
                {
                    var title = @"Map Fixer Error";
                    var msg   = $"Map Fixer is unable to repair the layer {layer.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}";
                    MessageBox.Show(msg, title, System.Windows.MessageBoxButton.OK,
                                    System.Windows.MessageBoxImage.Error);
                }
            }

            // Alternative implementation
            // switch on newDataset.WorkspaceProgId, newDataset.DatasourceType
            // uri = Uri(Path.Join(newDataset.Workspace.Folder, newDataset.DatasourceName)
            // connection = <Type>ConnectionPath(uri, newDataset.DatasourceType)
            // var dataset = OpenDataset<Type>(new <Type>DataSource(connection))
            // i.e. file geodatabase DatasourceType = .fgdb //ArcGIS.Core.CIM.esriDatasetType, ArcGIS.Core.CIM.WorkspaceFactory
            // var connection = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"newDataset.Workspace.Folder")))
            // var dataset = connection.OpenDataset<FeatureDataset>(newDataset.DatasourceName)
            // for .raster and .shape
            // var connection = new FileSystemDataStore(new FileSystemConnectionPath(new Uri(@"newDataset.Workspace.Folder")))
            // var dataset = connection.OpenDataset<BasicRasterDataset>(newDataset.DatasourceName)
        }
        private Task ChangeUSHighwaysLayerDataConnectionAsync(FeatureLayer featureLayer, string catalogPath) {
            return QueuedTask.Run(() => {
                CIMDataConnection currentDataConnection = featureLayer.GetDataConnection();

                string connection = System.IO.Path.GetDirectoryName(catalogPath);
                string suffix = System.IO.Path.GetExtension(connection).ToLower();

                WorkspaceFactory wf = WorkspaceFactory.FileGDB;
                if (suffix == ".sde") {
                    wf = WorkspaceFactory.SDE;
                }

                string dataset = System.IO.Path.GetFileName(catalogPath);

                // provide a replace data connection method
                CIMStandardDataConnection updatedDataConnection = new CIMStandardDataConnection() {
                    WorkspaceConnectionString = new Geodatabase(connection).GetConnectionString(),
                    WorkspaceFactory = wf,
                    Dataset = dataset,
                    DatasetType = esriDatasetType.esriDTFeatureClass
                };

                featureLayer.SetDataConnection(updatedDataConnection);

                //For a RDBMS, it might look like this:
                //string connection = "C:\\Work\\temp.sde";
                //Geodatabase sde = new Geodatabase(connection);

                //// provide a replace data connection method
                //CIMStandardDataConnection updatedDataConnection = new CIMStandardDataConnection();
                //updatedDataConnection.WorkspaceConnectionString = sde.GetConnectionString();
                //updatedDataConnection.WorkspaceFactory = WorkspaceFactory.SDE;
                //updatedDataConnection.Dataset = "vtest.usa.states";
                //updatedDataConnection.DatasetType = esriDatasetType.esriDTFeatureClass;



                //// Alternatively, use Layer.FindAndReplaceWorkspacePath()
                ////Note: this will not allow changing the dataset name or workspace type
                ////
                ////string connection = "C:\\Work\\temp.sde";
                ////Geodatabase sde = new Geodatabase(connection);
                ////featureLayer.FindAndReplaceWorkspacePath(((CIMStandardDataConnection)currentDataConnection).WorkspaceConnectionString, 
                ////                        sde.GetConnectionString(), true);


                //////////////////////////////////////////////
                ////Please Read
                ////
                //ok, so at this point we have a couple of bugs at 1.1 AND 1.2.....
                //
                //#1: if you switched to a Datasource that invalidates the Renderer, the Renderer does
                //not get invalidated in the UI
                //(eg You had a UniqueValueRenderer on a Field called "CATEGORY", the new datasource
                //does NOT have that field and so the renderer is invalid).
                //
                //#2: By default, Layers are added with a permanent cache. The cache is NOT automatically
                //invalidated so data (eg in the Attribute table, on the screen for draws) does NOT get
                //Refreshed so you have to invalidate the cache manually...

                //So, Bug #1 - we arbitrarily switch the Renderer to a simple renderer as a work around for that...
                featureLayer.SetRenderer(featureLayer.CreateRenderer(new SimpleRendererDefinition()));

                //Bug #2, we manually invalidate the cache
                featureLayer.ClearDisplayCache();
            });
        }