Export DWG with ObjectData to ESRI shape file using AutoCAD Map 3D API

Many customers want to export their DWG file to ESRI shape file, Map 3D, as a bridge between engineering and GIS, allowing you do the export or import manually by UI, or programmatically by API.

To make it easier, let’s start from UI. For example, we have a county map in DWG file format, there are some attribute data stored in DWG file as Object Data. What we want to do it export the drawing, as well as the attribute data, such as Area, Name, State, etc.

image

 

Select “Output” tab in ribbon, and click “Map 3D Export” button (or type MAPEXPORT in command line), select a directory and file format, *.shp in this case, an export dialogue will show up. As only single geometry type is allowed in one shp file, we must specify the geometry type before you begin the exporting. it’s important, we will talk it later when we doing this by API.

image

When finished all necessary configuration, we are ready to go. But before you click the OK button, you can also save your configuration into a profile file, with extension name *.epf.  It will give us a change to load and use it again it next time.

Here you go, click OK button and just cross your figure, you will get the shp version of the data.

 

If we have many maps to handle, you must want to do in programmatically. Let’s do in with Map 3D API. The AutoCAD Map 3D application maintains lists of available import and export formats. The application Importer and Exporter classes can import and export data using these formats.

Any import or export procedure requires the following:

  • Selecting the external file format and location
  • Mapping attribute data from the external file to object data
  • Setting any necessary driver options
  • Importing or exporting

The particular options will vary depending on the type of data being imported or exported, but the overall procedure is the same. In this topic, we will focus on shp file.

Actually, code samples(in C#,VB and C++) are available in ObjectARX Map SDK, it can be found C:\Map ObjectARX SDK 2011\Map Samples\DotNet\ImportExportCS , these code sample demonstrate how to export to MapInfo Tab file or MapInfo mif file. We will do some modification to support shp file as well.

 

Firstly we need initialize the exporter with suitable format name. But unfortunately, I didn't find any document which explains the format string for ImportExpert. How do we know the exact format name string?  Still remember the *.epf profile file? yes, many information can be found there :)

here is my *.epf file, please pay attention to the section marked in bold:

- <AdMapExportProfile version="2.1.3">
  <LoadedProfileName /> 
- <StorageOptions>
  <StorageType>FileOneEntityType</StorageType> 
  <GeometryType>Line</GeometryType> 
  <FilePrefix /> 
  </StorageOptions>
- <SelectionOptions>
  <UseSelectionSet>1</UseSelectionSet> 
  <UseAutoSelection>1</UseAutoSelection> 
  </SelectionOptions>
- <TranslationOptions>
  <TreatClosedPolylinesAsPolygons>0</TreatClosedPolylinesAsPolygons> 
  <ExplodeBlocks>1</ExplodeBlocks> 
- <LayersToLevels>
  <MapLayersToLevels>0</MapLayersToLevels> 
  <LayerToLevelMapping /> 
  </LayersToLevels>
  </TranslationOptions>
- <TopologyOptions>
  <GroupComplexPolygons>0</GroupComplexPolygons> 
  <TopologyName /> 
  </TopologyOptions>
- <LayerOptions>
  <DoFilterByLayer>0</DoFilterByLayer> 
  <LayerList /> 
  </LayerOptions>
- <FeatureClassOptions>
  <DoFilterByFeatureClass>0</DoFilterByFeatureClass> 
  <FeatureClassList /> 
  </FeatureClassOptions>
- <TableDataOptions>
  <TableDataType>None</TableDataType> 
  <Name /> 
  <SQLKeyOnly>0</SQLKeyOnly> 
  </TableDataOptions>
- <CoordSysOptions>
  <DoCoordinateConversion>0</DoCoordinateConversion> 
  <CoordSysName /> 
  </CoordSysOptions>
- <TargetNameOptions>
  <FormatName>SHP</FormatName> 
  </TargetNameOptions>
  <DriverOptions /> 
  <UseUniqueKeyField>0</UseUniqueKeyField> 
  <UseUniqueKeyFieldName>AdMapKey</UseUniqueKeyFieldName> 
  <ExpressionFieldMappings /> 
  </AdMapExportProfile>

 

we can set the proper value for “FormatName” and “exporter.SetStorageOptions”. As we said before, only single geometry type is allowed in one shp file, we must specify the geometry type before you begin the exporting. We need to add a RadioGroup to enable use select a geometry type to export.

<code>

MapApplication mapApp = HostMapApplicationServices.Application;
exporter = mapApp.Exporter; 

// Initiate the exporter with suitable formate name
exporter.Init("SHP", expFile);
//To select which drawing objects should be exported, call Exporter.SetSelectionSet(). To export all drawing 
//objects, set Exporter.ExportAll to true. To filter the list of objects, set the Exporter.FeatureClassFilter or
//Exporter.LayerFilter properties.
//we export all features here exporter.ExportAll = true;
GeometryType geomtryType1 = (GeometryType)Enum.Parse(typeof(GeometryType), geomtryType, true);
exporter.SetStorageOptions(StorageType.FileOneEntityType, geomtryType1, string.Empty); 

</code>

image

 

The main code snippet goes as below:

        /// <summary>
        /// Exports all of the entities or exports entities layer by layer.
        /// </summary>
        public void DoExport(string format, string expFile, string layerFilter, string isLogFile, bool isODTable, bool isLinkTemplate, string geomtryType)
        {
            string msg = null;

            FileStream fs = new FileStream(isLogFile, FileMode.Append);
            StreamWriter log = new StreamWriter(fs);

            Exporter exporter = null;

            try
            {
                // Get current time and log the time of executing exporting.
                DateTime time = DateTime.UtcNow;
                log.WriteLine(time.ToLocalTime().ToString());
                log.Write("Exporting file ");
                log.WriteLine(expFile);

                MapApplication mapApp = HostMapApplicationServices.Application;
                exporter = mapApp.Exporter; 

                // Initiate the exporter
                exporter.Init(format, expFile);

                exporter.ExportAll = true;

                GeometryType geomtryType1 = (GeometryType)Enum.Parse(typeof(GeometryType), geomtryType, true);
                exporter.SetStorageOptions(StorageType.FileOneEntityType, geomtryType1, string.Empty);

                // Attach event handlers to the exporter
                if (null == m_ExpEventHandler)
                {
                    m_ExpEventHandler = new MyExpEventHandler(log);
                    exporter.RecordReadyForExport += new RecordReadyForExportEventHandler(m_ExpEventHandler.RecordReadyForExport);
                    exporter.RecordExported += new RecordExportedEventHandler(m_ExpEventHandler.RecordExported);
                    exporter.ExportRecordError += new ExportRecordErrorEventHandler(m_ExpEventHandler.RecordError);
                }

                // Get Data mapping object
                ExpressionTargetCollection dataMapping = null;
                dataMapping = exporter.GetExportDataMappings();

                // Set ObjectData data mapping if isODTable is true
                if (isODTable && !MapODData(dataMapping))
                {
                    log.WriteLine("Error in mapping OD table data!");
                }

                // Reset Data mapping with Object data and Link template keys        
                exporter.SetExportDataMappings(dataMapping);

                // If layerFilter isn't null, set the layer filter to export layer by layer
                if (null != layerFilter)
                {
                    exporter.LayerFilter = layerFilter;
                }

                // Do the exporting and log the result
                ExportResults results;
                results = exporter.Export(true);
                msg = string.Format("    {0} objects are exported.", results.EntitiesExported.ToString());
                log.WriteLine(msg);
                msg = string.Format("    {0} objects are skipped.", results.EntitiesSkippedCouldNotTransform.ToString());
                log.WriteLine(msg);

                Utility.ShowMsg("\nExporting succeeded.");
            }
            catch (MapException e) 
            {
                log.WriteLine(e.Message);
                log.WriteLine(e.ErrorCode.ToString());
                Utility.ShowMsg("\nExporting failed.");
            }
            finally 
            {
                log.WriteLine(); 
                log.Close();
            }
        }

The mappings for attribute data are set using Exporter.SetExportDataMappings(). This requires an ExpressionTargetCollection parameter as input. The OD table field name in the data mapping should be in the format “:fieldName@tableName”, and we make the new field name of exported-to file ourselves. It is set to ODFieldName_ODTableName in this sample .

        /// <summary>
        /// Map ObjectData to attribute fields in the exported-to file.
        /// </summary>
        public bool MapODData(ExpressionTargetCollection mapping)
        {
            MapApplication mapApi = null; 
            ProjectModel proj = null; 
            Tables tables = null; 
            Autodesk.Gis.Map.ObjectData.Table table = null; 
            StringCollection tableNames = null;
            FieldDefinitions definitions = null;

            // Get map session and all the OD tables
            MapApplication mapApp = HostMapApplicationServices.Application;
            mapApi = mapApp; 
            proj = mapApi.ActiveProject;
            tables = proj.ODTables;
            tableNames = tables.GetTableNames();

            // Iterate through the OD table definition and get all the field names
            int tableCount = tables.TablesCount;
            try
            {
                for (int i = 0; i < tableCount; i++)
                {
                    table = tables[tableNames[i]];
                    definitions = table.FieldDefinitions;
                    for (int j = 0; j < definitions.Count; j++)
                    {
                        FieldDefinition column = null;
                        column = definitions[j];
                        // fieldName is the OD table field name in the data mapping. It should be 
                        // in the format:fieldName@tableName. 
                        // newFieldName is the attribute field name of exported-to file
                        // It is set to ODFieldName_ODTableName in this sample
                        string newFieldName = null;
                        string fieldName = null;
                        fieldName = ":" + column.Name + "@" + tableNames[i];
                        newFieldName = column.Name + "_" + tableNames[i];
                        mapping.Add(fieldName, newFieldName);
                    }
                }
            }
            catch (MapImportExportException) 
            {
                return false;
            }
            return true;
        }

Let’s check the exported file in Map 3D, connected with OSGeo Fdo Provider for SHP, you will notice that the attribute information is exported successfully.

image

 

you can download the whole sample project from here.

_ImportExportCS.zip       84KB

 

Cheers,

Daniel 峻祁连


Related Posts Plugin for WordPress, Blogger...