AutoCAD Map 3D Developer
Welcome to Autodesk’s AutoCAD Map 3D Developer Forums. Share your knowledge, ask questions, and explore popular AutoCAD Map 3D Developer topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem when I try to touch ObjectData twice in a row in the same C3D session with C#.Net

9 REPLIES 9
Reply
Message 1 of 10
m.chavet7MJRB
751 Views, 9 Replies

Problem when I try to touch ObjectData twice in a row in the same C3D session with C#.Net

Hello,

 

I created a post a few months ago at this location: https://forums.autodesk.com/t5/net/bug-when-successively-launching-a-function-i-ve-created/m-p/12340... , which I validated too quickly by mistake... As it happens, the problem still persists.

In the same project session, when I try again to touch ObjectData (by importing them, or if I want to reread the "records" a second time), I always get the error :

 

Application does not support just-in-time (JIT)
debugging. See the end of this message for details.

************** Exception Text **************
Autodesk.Gis.Map.MapImportExportException: Exception of type 'Autodesk.Gis.Map.MapImportExportException' was thrown.
at Autodesk.Gis.Map.ImportExport.Importer.Init(String formatName, String fileName)
at AEPCreateProfile.MyCommandsAEP.AEPImportShape() in C:\Users\maxime.chavet\Documents\RDC29\VISUAL_STUDIO\Profile\Profile\Class1.cs:line 68
at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()

 

Here is the first code to import shapefile:

 

 

[CommandMethod("SHP2")]
static public void SHP2()
{
      Autodesk.AutoCAD.Windows.OpenFileDialog ofd = new Autodesk.AutoCAD.Windows.OpenFileDialog(
          "Select SHP File", null, "shp", "Select shp", Autodesk.AutoCAD.Windows.OpenFileDialog.OpenFileDialogFlags.AllowAnyExtension);
      if (ofd.ShowDialog() == DialogResult.OK)
      {
          string shpname = ofd.Filename;
          Import2(shpname);
      }// 
}//acad command - SHP2

private static void Import2(string shpname)
{
    string fname = Path.GetFileNameWithoutExtension(shpname).Replace(" ", "");
    MapApplication mapApp = HostMapApplicationServices.Application;
    Importer importer = mapApp.Importer;
    try
    {
        importer.Init("SHP", shpname);
        foreach (InputLayer il in importer)
        {
            il.SetLayerName(LayerNameType.LayerNameDirect, fname);
            il.SetDataMapping(ImportDataMapping.NewObjectDataOnly, fname);
        }// foreach shp layer
        importer.ImportPolygonsAsClosedPolylines = true;
        ImportResults ir = importer.Import(true);
    }
    catch { }
    finally { };
}// Import2

 

 

 

Problem is at : 

 

 

il.SetDataMapping(ImportDataMapping.NewObjectDataOnly, fname);

 

 

 

And for the second :

 

 

using(DocumentLock lk = doc.LockDocument())
{
        if (psr.Status == PromptStatus.OK)
        {
            foreach (SelectedObject so in psr.Value)
            {
                using (Records records = tables.GetObjectRecords(0, so.ObjectId, Autodesk.Gis.Map.Constants.OpenMode.OpenForWrite, false))
                {
                    
                    foreach (Record record in records)  //Error at this line

 

 

 

Problem is at the last line

9 REPLIES 9
Message 2 of 10

 

 

 

 

 

public static Dictionary<string, List<ObjectId>> listprofilepl()
{
    Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
    Editor ed = doc.Editor;
    Database db = doc.Database;
    Tables tables = HostMapApplicationServices.Application.ActiveProject.ODTables;

    TypedValue[] filterList = new TypedValue[]
    {
       new TypedValue((int)DxfCode.Operator, "<or"),
       new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),
       new TypedValue((int)DxfCode.Start, "LINE"),
       new TypedValue((int)DxfCode.Start, "POLYLINE"),
       new TypedValue((int)DxfCode.Operator, "or>")
    };

    SelectionFilter filter = new SelectionFilter(filterList);
    PromptSelectionResult psr = ed.SelectAll(filter);
    //HashSet<String> ExistingProfile = new HashSet<String>();
    //List<ObjectId> idprofile = new List<ObjectId>();
    Dictionary<string, List<ObjectId>> profileObjectIdMap = new Dictionary<string, List<ObjectId>>();

    using(DocumentLock lk = doc.LockDocument())
    {
            if (psr.Status == PromptStatus.OK)
            {
                foreach (SelectedObject so in psr.Value)
                {
                        using (Records records = tables.GetObjectRecords(0, so.ObjectId, Autodesk.Gis.Map.Constants.OpenMode.OpenForRead, false))
                        {
                            //records.RemoveRecord;
                            foreach (Record record in records)  //Error at this line
                            {
                                for (int i = 0; i < record.Count; i++)
                                {
                                    MapValue val = record[i];
                                    Autodesk.Gis.Map.ObjectData.Table table = tables[record.TableName];
                                    FieldDefinition fieldDef = table.FieldDefinitions[i];

                                    if (fieldDef.Name == "Profil")
                                    {
                                        string profil = val.StrValue;
                                        // Vérifiez si le profil est vide ou "0" et ignorez-le
                                        if (!string.IsNullOrWhiteSpace(profil) && profil != "0")
                                        {
                                            // Si le profil n'existe pas dans le dictionnaire, ajoutez-le
                                            if (!profileObjectIdMap.ContainsKey(profil))
                                            {
                                                profileObjectIdMap[profil] = new List<ObjectId>();
                                            }

                                            // Ajoutez l'ObjectId correspondant au profil dans la liste
                                            profileObjectIdMap[profil].Add(so.ObjectId);
                                        }
                                    }
                                    //tables.UpdateTable(table.Name, table.FieldDefinitions);
                                    //table.AddRecord(record,so.ObjectId);
                                }


                                //records.UpdateRecord(record);
                            }
                            //tables.Add("bla", table.FieldDefinitions, "blabla", true);
                            
                            profileObjectIdMap.Remove("");
                            profileObjectIdMap.Remove("0");
                            //records.Dispose();
                        }                                               
                }
                return profileObjectIdMap;
            }
            else
            {
                return profileObjectIdMap;
            }
    }            

}

 

 

 

 

 

"Records" can be opened several times in a row when I run a function with a loop.

 

However, if a function is run a second time, independently of the first time, I get the error mentioned above.

It seems that this is due to the fact that the "records" extracted from the "tables" are empty during the second independent execution. I don't understand why, in the same session, the "records" become "empty" after being opened the first time, whereas if I run the same function in a new 3D civil session, everything works.

 

I hope my problem is clear to anyone reading this...

Message 3 of 10
fieldguy
in reply to: m.chavet7MJRB

You can't run the importer on the same file more than once. My guess is a duplicate records problem. If you use "mapimport" from the command line, acad happily creates duplicates. The managedmap api import does not (again - my guess is the "NewObjectDataOnly" property).

In the second "records" issue, you need to check that records.Count > 0 before the foreach. Again - my guess is an entity in the selection does not return any records.

In the future, include complete code samples and data if you can (you may have your own small set of test data?), with what you are trying to achieve - before and after. 

Message 4 of 10
m.chavet7MJRB
in reply to: fieldguy

Thank you for your reply

 

I can't even import different files (not necessarily the same) in the session C3D session..

 

Yes, indeed, records are empty in the next launch although OD of all the geometries are still present in C3D after a first launch. But with the same geometries selected, the read of OD work the first time.  I tried to (re)add and update record/records in the table/tables :

tables.UpdateTable(table.Name, table.FieldDefinitions);
table.AddRecord(record,so.ObjectId);

records.UpdateRecord(record);

tables.Add(table.Name, table.FieldDefinitions, "blabla", true);

 

it doesn't work and the error is the same than mentionned before

 

And: 

il.SetDataMapping(ImportDataMapping.ExistingObjectDataOnly, fname);

 

Here is some data in shapefile: https://we.tl/t-v5CpnAEEc1

 

So, the idea may be to duplicate and register "records" somewhere else?

 

 

Message 5 of 10
fieldguy
in reply to: m.chavet7MJRB

Check the following against yours - or just try mine.  You can import multiple shp files as long as the data does not exist.  I don't understand why you would want to import the same data again. 

Also - List<ObjectId> should just be ObjectId - no list required (1 to 1 relationship entity to OD record)

 

 [CommandMethod("SHP2")]
 static public void SHP2()
 {
     _debug = true;
     string msg = "BoundaryClass - SHP2";
     Autodesk.AutoCAD.Windows.OpenFileDialog ofd = new Autodesk.AutoCAD.Windows.OpenFileDialog(
         "Select SHP File", null, "shp", "Select shp", Autodesk.AutoCAD.Windows.OpenFileDialog.OpenFileDialogFlags.AllowAnyExtension);
     if (ofd.ShowDialog() == DialogResult.OK)
     {
         string shpname = ofd.Filename;
         // MapClass.Import2(shpname);
         Import2(shpname);
     }// 
     if (_debug)
         MessageBox.Show(msg);
 }// SHP2

  private static void Import2(string shpname)
  {
      string msg = "BoundaryClass - Import2 - local test only";
      msg += "\nimporting " + shpname;
      string fname = Path.GetFileNameWithoutExtension(shpname).Replace(" ", "");
      MapApplication mapApp = HostMapApplicationServices.Application;
      Importer importer = mapApp.Importer;
      try
      {
          importer.Init("SHP", shpname);
          foreach (InputLayer il in importer)
          {
              il.SetLayerName(LayerNameType.LayerNameDirect, fname);
// if you want to catch the error check if Tables contains fname - you would // have to change it if it exists  
              il.SetDataMapping(ImportDataMapping.NewObjectDataOnly, fname);
          }// foreach shp layer
          importer.ImportPolygonsAsClosedPolylines = true;
          ImportResults ir = importer.Import(true);
      }
      catch (Autodesk.Gis.Map.MapImportExportException mapieex)
      {
          msg += "\nmap importexport exception\n" + mapieex.Message;
          msg += "\nerror code\n" + mapieex.ErrorCode;
          // msg += "\nmore? " + Autodesk.Gis.Map.ImportExport.ImportExportErrorCode;
      }// catch mapimport
      catch (MapException mapex2)
      {
          msg += "\nmap exception\n" + mapex2.Message;
          msg += "\nerror code\n" + mapex2.ErrorCode;
      }// catch map
      catch (System.Exception sysex)
      {
          msg += "\nexception:\n" + sysex.Message;
      }
      finally { };
      if (_debug)
          MessageBox.Show(msg);
  }// Import2
// you can change void to Dictionary<string, List<ObjectId>> listprofilepl()
// and modify accordingly  
public static void ListProfilePl()
{
    string msg = "TestingClass - ListProfilePl";
    acapp.Document doc = acapp.Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;
    TypedValue[] filterList = new TypedValue[]
    {
        new TypedValue((int)DxfCode.Operator, "<or"),
        new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),
        new TypedValue((int)DxfCode.Start, "LINE"),
        new TypedValue((int)DxfCode.Start, "POLYLINE"),
        new TypedValue((int)DxfCode.Operator, "or>")
    };
    SelectionFilter filter = new SelectionFilter(filterList);
    PromptSelectionResult psr = ed.SelectAll(filter);
    if (psr.Status == PromptStatus.OK)
    {
        msg += "\nselected " + psr.Value.Count;
        Tables tables = HostMapApplicationServices.Application.ActiveProject.ODTables;
        Dictionary<string, List<ObjectId>> profileObjectIdMap = new Dictionary<string, List<ObjectId>>();
        foreach (SelectedObject so in psr.Value)
        {
            using (Records records = tables.GetObjectRecords(0, so.ObjectId, Autodesk.Gis.Map.Constants.OpenMode.OpenForRead, false))
            {
                msg += "\nrecords " + records.Count;
                if (records.Count > 0)
                {
                    foreach (Record record in records)
                    {
                        Autodesk.Gis.Map.ObjectData.Table table = tables[record.TableName];
                        FieldDefinitions fielddefs = table.FieldDefinitions;
                        for (int i = 0; i < fielddefs.Count; i++)
                        {
                            if (fielddefs[i].Name == "Profil")
                            {
                                MapValue val = record[i];
                                string profil = val.StrValue;
                                if (!profileObjectIdMap.ContainsKey(profil) && profil != "0")
                                {
                                    profileObjectIdMap.Add(profil, new List<ObjectId>() { so.ObjectId });
                                    msg += "\nprofile added to list " + profil;
                                }// add to list
                            }// check fielddef name 
                        }// foreach field def   
                    }// foreach record
                }// any records
            }// using records
        }// foreach object
    }// prompt ok
    if (BoundaryClass._debug)
        MessageBox.Show(msg);
}// ListProfilePl

 

Message 6 of 10
fieldguy
in reply to: fieldguy

That code isn't %100 correct.  It is using the field definitions to determine if the field name is "Profil".  You are not guaranteed that field name doesn't exist in some other table.  IMO you should check the table name first, before getting the field definitions.

Message 7 of 10
m.chavet7MJRB
in reply to: fieldguy

Hello,

 

Thank you!

 

But with the "if records.Count>0", I will be not allowed to launch successvely my function in C3D, it will never work, because I get this error, this problem of records empties in all cases

 

 

Message 8 of 10

If there are no others solutions, I will create a function that create an excel file with all the values of each field for each alignement, instead of directly with the OD, somewhere in the pc root. Then, my others functions that manage with  all the profiles will find the required values there. Because it what I need, and it seems I'm not allowed to call these records two times, nobody has the answer...

Message 9 of 10
fieldguy
in reply to: m.chavet7MJRB

You should post your entire solution - there is no reason for " Because it what I need, and it seems I'm not allowed to call these records two times".  My code will call your data as many times as necessary.

Message 10 of 10
O_Eckmann
in reply to: m.chavet7MJRB

Hi @m.chavet7MJRB 

 

With this code, I don't have anymore error when launching command twice or more.

 

 

using _AcDb = Autodesk.AutoCAD.DatabaseServices;
using _AcAp = Autodesk.AutoCAD.ApplicationServices;
using _AcRx = Autodesk.AutoCAD.Runtime;
using _AcGe = Autodesk.AutoCAD.Geometry;  
using _AcEd = Autodesk.AutoCAD.EditorInput;
using _AcCo = Autodesk.AutoCAD.Colors;

using _AcMp = Autodesk.Gis.Map;
using _AmCt = Autodesk.Gis.Map.Constants;
using _AmUt = Autodesk.Gis.Map.Utilities;
using _AmOd = Autodesk.Gis.Map.ObjectData;

    [_AcRx.CommandMethodAttribute("TEST_OD")]
    public void TEST_OD()
    {
      _AcAp.Document doc = _AcAp.Application.DocumentManager.MdiActiveDocument;
      _AcEd.Editor ed = doc.Editor;
      Dictionary<string, List<_AcDb.ObjectId>> dctProfil = listprofilepl();
      foreach(string sProfil in dctProfil.Keys)
      {
        ed.WriteMessage("\nProfil : " + sProfil);
        foreach(_AcDb.ObjectId id in dctProfil[sProfil])
          ed.WriteMessage("\n   Handle : " + id.Handle.ToString());
      }
    }

    public static Dictionary<string, List<_AcDb.ObjectId>> listprofilepl()
    {
      _AcAp.Document doc = _AcAp.Application.DocumentManager.MdiActiveDocument;
      _AcEd.Editor ed = doc.Editor;
      _AcDb.Database db = doc.Database;
      _AmOd.Tables tables = _AcMp.HostMapApplicationServices.Application.ActiveProject.ODTables;
      Dictionary<string, List<_AcDb.ObjectId>> profileObjectIdMap = new Dictionary<string, List<_AcDb.ObjectId>>();

      _AcDb.TypedValue[] filterList = new _AcDb.TypedValue[]
      {
       new _AcDb.TypedValue((int)_AcDb.DxfCode.Start, "LINE,*POLYLINE")
      };
      _AcEd.PromptSelectionResult psr = ed.SelectAll(new _AcEd.SelectionFilter(filterList));
      // SI la sélection est non valide, on sort tout de suite
      if (psr.Status != _AcEd.PromptStatus.OK)
        return profileObjectIdMap;
      //HashSet<String> ExistingProfile = new HashSet<String>();
      //List<ObjectId> idprofile = new List<ObjectId>();

      // Utile seulement si demandé depuis un dialogue non modal
      using (_AcAp.DocumentLock lk = doc.LockDocument())
      {
        foreach (_AcEd.SelectedObject so in psr.Value) 
        {
//          _AcDb.ObjectId id = so.ObjectId;
          using (_AmOd.Records records = tables.GetObjectRecords(0, so.ObjectId, _AmCt.OpenMode.OpenForRead, false))
          {
            //records.RemoveRecord;
            foreach (_AmOd.Record record in records)  //Error at this line
            {
              for (int i = 0; i < record.Count; i++)
              {
                using (_AmOd.Table table = tables[record.TableName])
                {
                  _AmOd.FieldDefinition fieldDef = table.FieldDefinitions[i];

                  if (fieldDef.Name == "Profil")
                  {
                    _AmUt.MapValue val = record[i];
                    string profil = val.StrValue;
                    // Vérifiez si le profil est vide ou "0" et ignorez-le
                    if (!string.IsNullOrWhiteSpace(profil) && profil != "0")
                    {
                      // Si le profil n'existe pas dans le dictionnaire, ajoutez-le
                      if (!profileObjectIdMap.ContainsKey(profil))
                      {
                        profileObjectIdMap[profil] = new List<_AcDb.ObjectId>();
                      }

                      // Ajoutez l'ObjectId correspondant au profil dans la liste
                      profileObjectIdMap[profil].Add(so.ObjectId);
                    }
                  }
                }
                //tables.UpdateTable(table.Name, table.FieldDefinitions);
                //table.AddRecord(record,so.ObjectId);
              }


              //records.UpdateRecord(record);
            }
            //tables.Add("bla", table.FieldDefinitions, "blabla", true);

            // Inutile puisque déjà exclu dans le test de la valeur du profil
            //profileObjectIdMap.Remove(""); 
            //profileObjectIdMap.Remove("0");
            //records.Dispose();
          }
        }
        return profileObjectIdMap;
      }

    }

 

 

Olivier Eckmann

EESignature

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report