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(); })); }
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(); }); }