SHP import

SHP import

fieldguy
Advisor Advisor
10,344 Views
12 Replies
Message 1 of 13

SHP import

fieldguy
Advisor
Advisor

I am looking for some help with SHP import using mapapplication.importer.  I have the dotnet importexport example from map objectarx but the import only supports MAPINFO and MIF formats.

 

I can import the entities (closed polygons) but having trouble with creating object data table and od records parts. 

0 Likes
Accepted solutions (1)
10,345 Views
12 Replies
Replies (12)
Message 2 of 13

norman.yuan
Mentor
Mentor

@fieldguy wrote:

... map objectarx but the import only supports MAPINFO and MIF formats.

 


It does support importing shape (how could it not?). You simply pass "SHP" in the importer's Init() method. As for OD data, you add an ImportDataMapping with ImportDataMapping.NewObjectDataOnly/ExistingObjectDataOnly and supply a OD table name when set the datamapping to input layer.

 

I thought the code sample from MAP objectARX SDK shows all the tricks. But I can put together a simple SHP sample code later, if you wish.

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 13

norman.yuan
Mentor
Mentor
Accepted solution

Below is the code sample of importing SHAPE:

 

using System.IO;

using Autodesk.AutoCAD.ApplicationServices;
using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.Gis.Map;
using Autodesk.Gis.Map.Project;
using Autodesk.Gis.Map.ObjectData;
using Autodesk.Gis.Map.ImportExport;

namespace ImportShp
{
    public class ShpImportUtil
    {
        private Importer _mapImporter = null;
        private Document _dwg = null;
        private MapApplication _mapApp = null;

        public ShpImportUtil(Document dwg)
        {
            _dwg = dwg;
            _mapApp = HostMapApplicationServices.Application;
        }

        public void ImportShape(string shpFileName, bool attributeAsOdData)
        {
            if (!File.Exists(shpFileName))
            {
                throw new FileNotFoundException(
                    $"Cannot find shape file: \n{shpFileName}");
            }

            _mapImporter = _mapApp.Importer;

            DoImport(shpFileName, attributeAsOdData);
        }

        #region private methods

        private void DoImport(string shpFile, bool addOdData)
        {
            _mapImporter.Init("SHP", shpFile);

            var fileName = Path.GetFileNameWithoutExtension(shpFile);

            foreach (InputLayer inputLayer in _mapImporter)
            {
                // use file name as layer name
                // assume it is qualified to be AutoCAD layer name
                var layerName = fileName;
                inputLayer.SetLayerName(LayerNameType.LayerNameDirect, layerName);

                if (addOdData)
                {
                    // use file name as OD table name
                    // assume the drawing does not have an OD table with the same name
                    var odTableName = fileName;
                    inputLayer.SetDataMapping(ImportDataMapping.NewObjectDataOnly, odTableName);
                }
            }

            _mapImporter.ImportPolygonsAsClosedPolylines = true;

            var result = _mapImporter.Import(true);
            var count = result.EntitiesImported;
            var msg = $"{count} entit{(count > 1 ? "ies" : "y")} imported!";
            CadApp.ShowAlertDialog(msg);
        }

        /// <summary>
        /// Make sure a new OD Table name
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        private string GetValidObjectDataTableName(string tableName)
        {
            ProjectModel proj = _mapApp.Projects.GetProject(_dwg);
            Tables tables = proj.ODTables;
            int i = 0;
            string tName = tableName;
            while (tables.IsTableDefined(tName))
            {
                i++;
                tName = tableName + "_" + i;
            }

            return tName;
        }

        #endregion
    }
}

As you can see, to let Importer to create OD data from SHAPE's attribute data, you only need to set DataMapping to the InputLayer (for shape, only one layer per shape file).

 

To use it in a CommandClass:

 

using Autodesk.AutoCAD.Runtime;
using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(ImportShp.MyCommands))]

namespace ImportShp
{
    public class MyCommands 
    {
        [CommandMethod("ImportShp")]
        public static void RunCommandA()
        {
            var dwg = CadApp.DocumentManager.MdiActiveDocument;
            var ed = dwg.Editor;

            var shpFile = GetShapeFileName();
            try
            {
                var mapUtil = new ShpImportUtil(dwg);
                mapUtil.ImportShape(shpFile, true);
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError:\n{0}.", ex.Message);
            }
            finally
            {
                Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();
            }
        }

        private static string GetShapeFileName()
        {
            var shpFile = "";
            using (var dlg = new System.Windows.Forms.OpenFileDialog())
            {
                dlg.Title = "Select Shape File for Lmport";
                dlg.Multiselect = false;
                dlg.Filter = "Shape File *.shp|*.shp";
                if (dlg.ShowDialog()== System.Windows.Forms.DialogResult.OK)
                {
                    shpFile = dlg.FileName;
                }
            }
            return shpFile;
        }
    }
}

HTH

 

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 4 of 13

fieldguy
Advisor
Advisor

Thanks again @norman.yuan. Kudos!

Your code is easy to read.

  

0 Likes
Message 5 of 13

subash.nalla
Enthusiast
Enthusiast
Hi can you share me the dotnet example from map objectarx but the import only supports MAPINFO and MIF formats code. I tried numerous ways but was not able to import the Object Data inside the MIF file. Thanks in advance.
0 Likes
Message 6 of 13

norman.yuan
Mentor
Mentor

According to your post in the .NET forum, it seems you have already know how to use Autodesk.Gis.Map.ImportExport.Importer xlass to import *.MIF file. You only need to configure the Importer a bit more details: setting up each InputLayer.

 

By default, if you do nothing about the InputLayer, AutoCAD Map will use the map layer name as AutoCAD layer name and use the Coordinate System of the map, and ignore the attribute data (only import geometries). You can setting up the InputLayer as you needed: using different Coordinate system (Map will automatically does the CS conversion); using desired AutoCAD layer name; and importing attribute data as Object Data. In your case, you need to call InputLayer.SetDataMapping(). The code would be like:

 

foreach (InputLayer layer in _importer)
{

     // If needed, change the CS
     layer.TargetCoordinateSystem = layer.OriginalCoordinateSys; // or whatever CS

 

     // If needed, use desired CAD layer name, other than the default (Map layer name)

     layer.SetLayerName(LayerNameType.LayerNameDirect, "MyDesiredLayerName");


     if ([I need import OD])
     {
        layer.SetDataMapping(ImportDataMapping.NewObjectDataOnly, "[OD Table Name]")
     }
}

 

Obviously, the the import source has multiple layers, you want to make sure the layer name/OD table name do not duplicate. Usually, you would simply use the map layer name for both CAD layer name and OD Table name.

 

Hope this helps.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 7 of 13

adevkarF2WFN
Observer
Observer

Hey, I'm working on a C# plugin to import shapefiles into AutoCAD Map 3D and I've run into a strange issue with importing object data.


My code prompts a user to select a single .shp file and draw a window. It then uses the Importer class to bring in the geometry from that file within the selected bounds. The goal is to also bring in all the associated attribute data. The core of my logic is this snippet:

// Inside a loop that runs once for the shapefile
foreach (InputLayer inputLayer in mapImporter)
{
    // Use the filename for the layer and OD table name
    inputLayer.SetLayerName(LayerNameType.LayerNameDirect, baseName);
    string odTableName = GetValidObjectDataTableName(doc, baseName);

    // This should import all attribute data
    inputLayer.SetDataMapping(ImportDataMapping.NewObjectDataOnly, odTableName);
}

mapImporter.ImportPolygonsAsClosedPolylines = true;
mapImporter.Import(true);

The code successfully imports the geometry (polygons) and correctly creates a new Object Data table with the specified name. However, the table only ever contains a single field named "FeatID". None of the other attributes from the source shapefile's .dbf table (like names, types, material, etc.) are being created.

 

My understanding is that using ImportDataMapping.NewObjectDataOnly should automatically create fields for all columns in the attribute table. The code seems to follow the correct procedure, but the result is missing most of the data.

 

Has anyone seen this behavior before? I'm wondering if I'm missing a configuration step or if this points to a problem with the source shapefiles I'm testing with. Any advice would be greatly appreciated.

0 Likes
Message 8 of 13

norman.yuan
Mentor
Mentor

You did not mention, but I assume you do have this line in code:

 

Importer.Init("SHP", shpFile)

How the columns/fields are named in the shape file? If the name is too long (more than 10), then the data would not be imported.

 

If you can upload a sample SHP file, I might give it a try.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 9 of 13

adevkarF2WFN
Observer
Observer

Hey, yes, I can confirm that Importer.Init("SHP", shpFile) is present in my code right before I set up the InputLayer. There definitely are some field names are longer than 10 characters. However, what's confusing is that fields with short names are also failing to import. For example, a field named "ST_PO" is present in the source file but does not appear in the Object Data table after import. This makes me think there might be another issue at play.

 

As you offered, I've attached the shapefile. It contains publicly available road centerlines for Loudoun County, VA. The file is about 11 MB; if a smaller sample would be easier to work with, please just let me know. Dropbox link: https://www.dropbox.com/scl/fi/0d6nd56vllfjlghan1l5q/Loudoun_Street_Centerline.shp?rlkey=rszo1bdgbzp...

0 Likes
Message 10 of 13

norman.yuan
Mentor
Mentor

The file you provided does not come with companion *.dbf/*.idx/*.prj. That is, the 4 files (the same file name with different file name extensions) make full set of GIS data. With *.shp alone, only geometry data is included. All attribute data are stored in *.dbf file.

 

So the question is, when you import the shape, is there *.dbf file also sitting in the same folder? 

 

If you do have *.dbf file, another way to quick verification of the shape's importability is simply run "MapImport" command to see if the attribute data can be imported correctly (since you did mention that some of the field names are more than 10-char long).

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 11 of 13

adevkarF2WFN
Observer
Observer

Sorry about that. I do have a .dbf, .dbf, and a .shx in the same folder in addition to the .shp file. This link works for access to all 4 files: https://www.dropbox.com/scl/fo/4d8kcv41c0dbd89yl7j27/AMXezqvj9k09wRscJtcHjTs?rlkey=k65f69bg01qj9ya97...

 

I have run the map import command, and with that, I have been able to see all of the object data.

0 Likes
Message 12 of 13

norman.yuan
Mentor
Mentor

Well, the *.dbf you uploaded is still empty. Here is what I saw when running "MapImport" command:

normanyuan_0-1754067089140.png

When you say " ... have been able to see all of the object data..." when running "MapImport" command, do you see all the fields listed in the "Object Data Mapping" dialog box? If you do, the you have good *.dbf file (likely, which is NOT the one you uploaded to Dropbox), and the code should have worked, AS LONG AS the good *.dbf file is in the same folder as the *.shp file the code reads from.

 

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 13 of 13

adevkarF2WFN
Observer
Observer

I see. Thank you for the clarification. It seems that I was using the wrong files for my local test folder. Thank you for all of your help.

0 Likes