.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FDO - Map Checking-In / Checking-Out Features

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
Anonymous
1129 Views, 2 Replies

FDO - Map Checking-In / Checking-Out Features

Hello everybody !

My first post here 😉

Many thanks to everybody reading it 😉

 

Context :

  • AutoCAD Map 2013
  • Visual Studio 2010
  • .NET, C#, WPF
  • FDO
  • Oracle DataStore

Business Requirement :

The application manages some objects (features), containing business attributes and a geometry attribute (in an FDO meaning).
One of these business attributes should contain the length of the item drawn under AutoCAD Map.
If a user wants to modify the geometry of one of these items (by moving vertices for example), he must check out the feature of its choice (a polyline, or a point).

Then he can update the geometry of the feature, and finally, he has to check in the feature to store it permanently.

When checking-in the feature, I need to get the new length of the polyline (or new coordinates of a point for example), and I need to update the appropriate business attribute of the relevant object with the new length.

 

My technical implementation, not working :

I've handled the CommandEventHandler "CommandEnded" of  the Document Object (Autodesk.AutoCAD.ApplicationServices.Document). This event is raised when an AutoCAD Map Command has ended. In this handler, I test the GlobalCommandName of the Event Argument. I test "MAPCANCELCHECKOUT", "MAPCHECKOUT" and "MAPCHECKINALL".

  1. When MAPCHECKOUT has finished : I need to retrieve all of the objects that have been selected. I put each of them in a Dictionary, where the Key is the ObjectId (Autodesk.AutoCAD.DatabaseServices.ObjectId) and the Value is the relevant Business Object (in my own Application).
  2. When MAPCHECKINALL has finished : I need to browse all Checked-Out entries of my Dictionary. Using the ObjectId (the Key), I try to get the new Length of the Polyline (or Coordinates for a Point). and I need to get this value and update the relevant Business Object (the Value). But when I call transaction.GetObject(key, OpenMode.ForRead, true), it always throws an Exception of type "ePermanentlyErased". So, in other words, I'm unable to get the new Length of any checked-out Polyline (Object, Entity, Curve, etc...).

 

 

 

 

        void doc_CommandEnded(object sender, CommandEventArgs e)
        {
            Document doc = (Document)sender;
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
            switch (e.GlobalCommandName)
            {
                case "MAPCANCELCHECKOUT":
                    CancelCheckOut();
                    break;

                case "MAPCHECKOUT":
                    DoCheckOut();
                    break;

                case "MAPCHECKINALL":
                    DoCheckIn();
                    break;

                default:
                    break;
            }
            ed.WriteMessage("\nCommand ended : [" + e.GlobalCommandName + "]");
        }
        
        
        
        
                Dictionary<ObjectId, TakmGenericObject> __objectsIdToTakmGenericObjectsCheckedOut = new Dictionary<ObjectId, TakmGenericObject>();



        public void DoCheckOut()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            PromptSelectionResult result = ed.GetSelection();
            SelectionSet selSet = result.Value;
            AcMapMap currentMap = AcMapMap.GetCurrentMap();
            MgLayerCollection layers = currentMap.GetLayers();

            Database db = doc.Database;

            using (Transaction acTrans = db.TransactionManager.StartTransaction())
            {

                foreach (SelectedObject selObj in selSet)
                {
                    // Check to make sure a valid SelectedObject object was returned
                    if (selObj != null)
                    {
                        // Open the selected object for write
                        SelectionSet selSet2 = SelectionSet.FromObjectIds(new ObjectId[1] { selObj.ObjectId });
                        AcMapSelection sel = (AcMapSelection)AcMapFeatureEntityService.GetSelection(selSet2);
                        foreach (MgLayerBase layer in layers)
                        {
                            Int32 iCount = sel.GetSelectedFeaturesCount(layer, layer.FeatureClassName);
                            if (iCount>0)
                            {
                                    // Getting Relevant Business Object
                                MgFeatureReader reader = sel.GetSelectedFeatures(layer, layer.FeatureClassName, false);
                                Collection<Object> ids = new Collection<Object>();
                                while (reader.ReadNext())
                                {
                                    Int64 id = reader.GetInt64("ID");
                                    ids.Add(id);
                                    ed.WriteMessage("\nID: " + id);
                                }
                                String shortName = (layer.FeatureClassName.Contains(':') ? layer.FeatureClassName.Substring(layer.FeatureClassName.IndexOf(':') + 1) : layer.Name);
                                TakmGenericObjectCollection<TakmGenericObject> goCollection = new TakmGenericObjectCollection<TakmGenericObject>();
                                goCollection.Descriptor = TakmGenericObjectDescriptorDictionary.Instance.GetFirstGenericObjectDescriptorByTableName(shortName);
                                if (goCollection.Descriptor != null)
                                {
                                    goCollection.SelectWherein("ID", ids);
                                    foreach (TakmGenericObject genericObject in goCollection)
                                    {
                                            // Putting Key-Value into Dictionary
                                            __objectsIdToTakmGenericObjectsCheckedOut.Add(selObj.ObjectId, genericObject);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        
        
        public void DoCheckIn()
        {
            Collection<ObjectId> unlocked = new Collection<ObjectId>();
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            using (Transaction acTrans = db.TransactionManager.StartTransaction())
            {
                foreach (KeyValuePair<ObjectId, TakmGenericObject> kvp in __objectsIdToTakmGenericObjectsCheckedOut)
                {
                    FeatureToDraw feature = new FeatureToDraw();
                    
                    try
                    {
                            //
                            //
                            //
                            
                        DBObject dbObj = acTrans.GetObject(kvp.Key, OpenMode.ForRead, true);
                        
                        // ---> this line always generate exception!
                        //
                        //
                        
                        
                        
                        Polyline pl = dbObj as Polyline;
                        if (pl != null)
                        {
                            feature.Length = pl.Length;
                        }
                        Curve crv = dbObj as Curve;
                        if (crv != null)
                        {
                            feature.Length = crv.GetDistanceAtParameter(crv.EndParam) - crv.GetDistanceAtParameter(crv.StartParam);
                        }

                        TakmGenericObject genericObject = kvp.Value;
                        if (genericObject.Descriptor != null)
                        {
                                // Updating Business attributes of Business Objects
                                // new length, new coordinates
                                // blablabla...
                        }
                    }
                    catch (System.Exception ex)
                    {
                        TakmLogger.Instance.LogError(__classFullName + "DoCheckIn", ex.Message);
                        if (ex.InnerException != null)
                        {
                            TakmLogger.Instance.LogError(__classFullName + "DoCheckIn", ex.InnerException.Message);
                        }
                    }
                }
            }
            foreach (ObjectId objId in unlocked)
            {
                __objectsIdToTakmGenericObjectsCheckedOut.Remove(objId);
            }
        }

 

 

 

Can someone help me please ?

Do I had made the good choice ?

Is there any best practice regarding my needs ?

Thank you very much.

 

tom.

2 REPLIES 2
Message 2 of 3
alberto_manero_geograma
in reply to: Anonymous

I think that for the MAPCHECKINALL probably you shoud do the process before the command begins. Could it be?

Luis Alberto Manero, Geograma.com
Message 3 of 3
Anonymous

Hi amareno,

 

it works like a charm ! Smiley Very Happy

 

Thank you so much. I just handle the CommandWillStart Event, just before the MAPCHECKINALL command is really executed.

 

Document.CommandWillStart += new CommandEventHandler(doc_CommandWillStart);

 

And at this time, when I call the GetObject, I get the result !

 

Many Thanks again.

 

tom.

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost