private void Export(string tempMdbPathName, string attributeDatasetName, bool selectedOnly) { IRelationshipClass relClass = null; IFeatureClass outFeatureClass = null; IFeatureClass joinFeatureClass = null; IFeatureLayer joinLayer = null; IDataset attributeDataset; ITable exportAttributes; IWorkspaceFactory joinWorkspaceFactory = new OLEDBWorkspaceFactoryClass(); object outWS = null; try { SetCursor(true); OpenOleDbWorkspace(tempMdbPathName, attributeDatasetName, ref joinWorkspaceFactory, out attributeDataset, out exportAttributes); IDisplayTable hluDisplayTable = (IDisplayTable)_hluLayer; IFeatureClass hluDisplayTableFeatureClass = (IFeatureClass)hluDisplayTable.DisplayTable; // Set the selected and total feature counts. int selectedFeatureCount = _hluFeatureSelection.SelectionSet.Count; int totalFeatureCount = _hluLayer.FeatureClass.FeatureCount(null); int exportFeatureCount = 0; // Prompt the user for where to save the export layer. IExportOperation exportOp = new ExportOperation(); bool saveProjection; esriExportTableOptions exportOptions; IDatasetName exportDatasetName = exportOp.GetOptions(hluDisplayTableFeatureClass, _hluLayer.Name, _hluFeatureSelection != null && _hluFeatureSelection.SelectionSet.Count > 0, true, _application.hWnd, out saveProjection, out exportOptions); // If no export dataset name was chosen by the user then cancel the export. if (exportDatasetName == null) { _pipeData.Add("cancelled"); return; } // Open the export dataset workspace. outWS = ((IName)exportDatasetName.WorkspaceName).Open(); // Determine if the export layer is a shapefile. bool isShp = IsShp(outWS as IWorkspace); //--------------------------------------------------------------------- // FIX: 050 Warn ArcGIS users if field names may be truncated or // renamed exporting to shapefiles. // // If the export layer is a shapefile check if any of // the attribute field names will be truncated. if (isShp) { bool fieldNamesTruncated = false; for (int i = 0; i < exportAttributes.Fields.FieldCount; i++) { IField attributeField = exportAttributes.Fields.get_Field(i); if (attributeField.Name.Length > 10) { fieldNamesTruncated = true; break; } } // Warn the user that some field names may get truncated. if (fieldNamesTruncated) { MessageBoxResult userResponse = MessageBoxResult.No; userResponse = MessageBox.Show("Some field names may get truncated or renamed exporting to a shapefile.\n\nDo you wish to proceed?", "HLU: Export", MessageBoxButton.YesNo, MessageBoxImage.Question); if (userResponse != MessageBoxResult.Yes) { _pipeData.Add("cancelled"); return; } } } //--------------------------------------------------------------------- // Get the geometry definition for the feature layer. IGeometryDef geomDef = _hluFeatureClass.Fields.get_Field(_hluFeatureClass.FindField( _hluFeatureClass.ShapeFieldName)).GeometryDef; ITable joinLayerTable; IDisplayTable joinDisplayTable; //--------------------------------------------------------------------- // CHANGED: CR13 (Export features performance) // // If only a sub-set of features are being exported then // export the sub-set to a temporary feature class before // joining the temporary layer to the attribute dataset. if (selectedOnly) { // Set the export options for which records to export. exportOptions = esriExportTableOptions.esriExportSelectedRecords; // Set the input DataSet name IDataset inDataset; inDataset = (IDataset)hluDisplayTable.DisplayTable; IDatasetName inDatasetName; inDatasetName = (IDatasetName)inDataset.FullName; // set the output temporary DataSet name IFeatureClassName outFCName = new FeatureClassNameClass(); IDatasetName outDatasetName = (IDatasetName)outFCName; outDatasetName.Name = String.Format("{0}_temp", exportDatasetName.Name); outDatasetName.WorkspaceName = exportDatasetName.WorkspaceName; // Get the selected features for export ISelectionSet selectionSet = _hluFeatureSelection.SelectionSet; // If there is no selection cancel the export. if (_hluFeatureSelection.SelectionSet.Count == 0) { _pipeData.Add("noselection"); return; } // Export the selected features to the temporary dataset. exportOp.ExportFeatureClass(inDatasetName, null, selectionSet, geomDef, (IFeatureClassName)outDatasetName, _application.hWnd); // Cast the workspace to IFeatureWorkspace and open the feature class. IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)outWS; joinFeatureClass = featureWorkspace.OpenFeatureClass(outDatasetName.Name); // Add an attribute index to the incid field. AddFieldIndex(joinFeatureClass, String.Format("IX_{0}", _hluLayerStructure.incidColumn.ColumnName), _hluLayerStructure.incidColumn.ColumnName); // Set the join layer to the temporary feature class. joinLayer = new FeatureLayerClass(); joinLayer.FeatureClass = joinFeatureClass; joinLayer.Name = joinFeatureClass.AliasName; // Set the join layer table to the temporary feature class. joinDisplayTable = (IDisplayTable)joinLayer; //IFeatureClass joinDisplayTableFC = (IFeatureClass)joinDisplayTable.DisplayTable; IFeatureClass joinDisplayTableFC = joinFeatureClass; joinLayerTable = (ITable)joinDisplayTableFC; // Set the count for the number of features to be exported. exportFeatureCount = selectedFeatureCount; } // Otherwise, join the whole feature layer to the // attribute dataset. else { // Clear any current selection. _hluFeatureSelection.SelectionSet = null; // Set the export options for which records to export. exportOptions = esriExportTableOptions.esriExportAllRecords; // Set the join feature class to the current HLU feature class. joinFeatureClass = _hluFeatureClass; // Set the join layer to the current HLU feature layer. joinLayer = _hluLayer; joinLayerTable = (ITable)hluDisplayTableFeatureClass; joinDisplayTable = hluDisplayTable; // Set the count for the number of features to be exported. exportFeatureCount = totalFeatureCount; } //--------------------------------------------------------------------- // Get the field names to be used when joining the attribute data and the feature layer string originPKJoinField = _hluLayerStructure.incidColumn.ColumnName; string originFKJoinField = _hluFeatureClass.Fields.get_Field(_hluFieldMap[_hluLayerStructure.incidColumn.Ordinal]).Name; // Get a list of all the fields to be used in the export layer (plus separate lists of all // those fields that will come from the attribute table and those that will come from the // feature layer). List<IField> attributeFields; List<IField> featClassFields; List<IField> exportFields = ExportFieldLists(isShp, originPKJoinField, originFKJoinField, joinFeatureClass, exportAttributes, out attributeFields, out featClassFields); // Add x/y, length, or area and length fields to the list of fields in the export layer // if the export layer is a shapefile. ExportAddGeometryPropertyFields(isShp, exportFields); // Create a virtual relationship between the feature class // and the attribute dataset. IMemoryRelationshipClassFactory memoryRelFactory = new MemoryRelationshipClassFactoryClass(); relClass = memoryRelFactory.Open("ExportRelClass", (IObjectClass)exportAttributes, originPKJoinField, (IObjectClass)joinLayerTable, originFKJoinField, "forward", "backward", esriRelCardinality.esriRelCardinalityOneToMany); // Use the relationship to perform a join. IDisplayRelationshipClass displayRelClass = (IDisplayRelationshipClass)joinLayer; displayRelClass.DisplayRelationshipClass(relClass, esriJoinType.esriLeftInnerJoin); // Create query filter for the export cursor so that // only the required fields are retrieved. bool featClassFieldsQualified; bool attributeFieldsQualified; IQueryFilter exportQueryFilter = ExportQueryFilter(originPKJoinField, joinLayer, joinFeatureClass, joinDisplayTable, attributeDataset, featClassFields, attributeFields, out featClassFieldsQualified, out attributeFieldsQualified); // Create a collection of fields for the output feature class. // Adds OID and SHAPE at beginning. IFields outFields = CreateFieldsCollection(true, geomDef.HasZ, geomDef.HasM, outWS, joinFeatureClass.ShapeType, exportFields.Select(f => f.Length).ToArray(), exportFields.Select(f => f.Name).ToArray(), exportFields.Select(f => f.Name).ToArray(), exportFields.Select(f => f.Type).ToArray(), exportFields.Select(f => f.Type != esriFieldType.esriFieldTypeOID).ToArray(), geomDef.SpatialReference); // Create the output feature class. outFeatureClass = CreateFeatureClass(exportDatasetName.Name, null, outWS, outFields, esriFeatureType.esriFTSimple, joinFeatureClass.ShapeType, null, null); // Map the fields between the display and table and the output feature // class as the display table always includes all fields. // The first two fields are always OID and SHAPE. int[] exportFieldMap = new int[] { 0, 1 }.Concat(featClassFields .Select(f => joinDisplayTable.DisplayTable.Fields.FindField(featClassFieldsQualified ? joinLayer.Name + "." + f.Name : f.Name))).Concat(attributeFields .Select(f => joinDisplayTable.DisplayTable.Fields.FindField(attributeFieldsQualified ? attributeDataset.Name + "." + f.Name : f.Name))).ToArray(); //--------------------------------------------------------------------- // FIX: 038 Display the export progress bar correctly when exporting // from ArcGIS. // Pass the number of features to be exported, not the number of incids, // so that the export progress is displayed corectly // // Insert the features and attributes into the new feature class. ExportInsertFeatures(joinDisplayTable, exportQueryFilter, exportFeatureCount, exportFieldMap, isShp, outWS, outFeatureClass); //--------------------------------------------------------------------- //--------------------------------------------------------------------- // CHANGED: CR16 (Adding exported features) // Ask the user if they want to add the new export layer // to the active map. MessageBoxResult addResponse = MessageBoxResult.No; addResponse = MessageBox.Show("The export operation succeeded.\n\nAdd the exported layer to the current map?", "HLU: Export", MessageBoxButton.YesNo, MessageBoxImage.Question); if (addResponse == MessageBoxResult.Yes) { // Add the exported feature layer to the active map. IFeatureLayer hluExportLayer; hluExportLayer = new FeatureLayer(); hluExportLayer.FeatureClass = outFeatureClass; hluExportLayer.Name = outFeatureClass.AliasName; _focusMap.AddLayer(hluExportLayer); } //--------------------------------------------------------------------- } catch (Exception ex) { _pipeData.Add(ex.Message); } finally { // Remove the virtual relationship. if (relClass != null) { //IRelationshipClassCollectionEdit relClassEdit = (IRelationshipClassCollectionEdit)joinLayer; //relClassEdit.RemoveAllRelationshipClasses(); ((IDisplayRelationshipClass)joinLayer).DisplayRelationshipClass( null, esriJoinType.esriLeftInnerJoin); } // Destroy workspace factory so the attribute dataset can // be deleted later. attributeDataset = null; exportAttributes = null; joinWorkspaceFactory = null; // Delete the temporary feature class. try { if (joinFeatureClass != _hluFeatureClass) { IDataset tempDataset = (IDataset)joinFeatureClass; if (tempDataset != null) tempDataset.Delete(); } } catch { } SetCursor(false); } }
private void Export(string tempMdbPathName, string attributeDatasetName, int exportRowCount) { IRelationshipClass relClass = null; IFeatureClass outFeatureClass = null; try { SetCursor(true); IDataset attributeDataset; ITable exportAttributes; OpenOleDbWorkspace(tempMdbPathName, attributeDatasetName, out attributeDataset, out exportAttributes); IDisplayTable hluDisplayTable = (IDisplayTable)_hluLayer; IFeatureClass hluDisplayTableFeatureClass = (IFeatureClass)hluDisplayTable.DisplayTable; ITable hluLayerTable = (ITable)hluDisplayTableFeatureClass; IExportOperation exportOp = new ExportOperation(); bool saveProjection; esriExportTableOptions exportOptions; IDatasetName exportDatasetName = exportOp.GetOptions(hluDisplayTableFeatureClass, _hluLayer.Name, _hluFeatureSelection != null && _hluFeatureSelection.SelectionSet.Count > 0, true, _application.hWnd, out saveProjection, out exportOptions); if (exportDatasetName == null) { _pipeData.Add("cancelled"); return; } object outWS = ((IName)exportDatasetName.WorkspaceName).Open(); string originPKJoinField = _hluLayerStructure.incidColumn.ColumnName; string originFKJoinField = _hluFeatureClass.Fields.get_Field(_hluFieldMap[_hluLayerStructure.incidColumn.Ordinal]).Name; List<IField> attributeFields; List<IField> featClassFields; List<IField> exportFields = ExportFieldLists(originPKJoinField, originFKJoinField, exportAttributes, out attributeFields, out featClassFields); bool isShp = IsShp(outWS as IWorkspace); ExportAddGeometryPropertyFields(isShp, exportFields); // create virtual relate IMemoryRelationshipClassFactory memoryRelFactory = new MemoryRelationshipClassFactoryClass(); relClass = memoryRelFactory.Open("ExportRelClass", (IObjectClass)exportAttributes, originPKJoinField, (IObjectClass)hluLayerTable, originFKJoinField, "forward", "backward", esriRelCardinality.esriRelCardinalityOneToMany); // use Relate to perform a join IDisplayRelationshipClass displayRelClass = (IDisplayRelationshipClass)_hluLayer; displayRelClass.DisplayRelationshipClass(relClass, esriJoinType.esriLeftOuterJoin); // create query filter for export cursor bool featClassFieldsQualified; bool attributeFieldsQualified; IQueryFilter exportQueryFilter = ExportQueryFilter(originPKJoinField, hluDisplayTable, attributeDataset, featClassFields, attributeFields, out featClassFieldsQualified, out attributeFieldsQualified); IGeometryDef geomDef = _hluFeatureClass.Fields.get_Field(_hluFeatureClass.FindField( _hluFeatureClass.ShapeFieldName)).GeometryDef; // adds OID and SHAPE at beginning, possibly Shape_Length and Shape_Area at end // when populating new rows we loop over exportFieldOrdinals // if we export shp we calculate geometry props into the last two fields, which are // not in exportFields IFields outFields = CreateFieldsCollection(true, geomDef.HasZ, geomDef.HasM, outWS, _hluFeatureClass.ShapeType, exportFields.Select(f => f.Length).ToArray(), exportFields.Select(f => f.Name).ToArray(), exportFields.Select(f => f.Name).ToArray(), exportFields.Select(f => f.Type).ToArray(), exportFields.Select(f => f.Type != esriFieldType.esriFieldTypeOID).ToArray(), geomDef.SpatialReference); // create output feature class outFeatureClass = CreateFeatureClass(exportDatasetName.Name, null, outWS, outFields, esriFeatureType.esriFTSimple, _hluFeatureClass.ShapeType, null, null); // field map between display and output feature class, as display // table always includes all fields, regardless of SubFields // the first two fields are always OID and SHAPE // the last two Shape_Length and Shape_Area, either added automatically or here int[] exportFieldMap = new int[] { 0, 1 }.Concat(featClassFields .Select(f => hluDisplayTable.DisplayTable.Fields.FindField(featClassFieldsQualified ? _hluLayer.Name + "." + f.Name : f.Name))).Concat(attributeFields .Select(f => hluDisplayTable.DisplayTable.Fields.FindField(attributeFieldsQualified ? attributeDataset.Name + "." + f.Name : f.Name))).ToArray(); // insert features into new feature class ExportInsertFeatures(hluDisplayTable, exportQueryFilter, exportRowCount, exportFieldMap, isShp, outWS, outFeatureClass); } catch (Exception ex) { _pipeData.Add(ex.Message); } finally { if (relClass != null) ((IDisplayRelationshipClass)_hluLayer).DisplayRelationshipClass( null, esriJoinType.esriLeftInnerJoin); outFeatureClass = null; try { if (File.Exists(tempMdbPathName)) File.Delete(tempMdbPathName); } catch { } SetCursor(false); } }