Can Someone Explain LayerTableRecords

Can Someone Explain LayerTableRecords

mgorecki
Collaborator Collaborator
1,325 Views
4 Replies
Message 1 of 5

Can Someone Explain LayerTableRecords

mgorecki
Collaborator
Collaborator

Hi, I know this is a real newbie question, but I have seen so many different ways of setting the layer table and layer table record:

Dim layTable As LayerTable = DirectCast(tr.GetObject(db.LayerTableId, OpenMode.ForRead), LayerTable)

Dim layTable As LayerTable = tr.GetObject(doc.Database.LayerTableId, OpenMode.ForRead)

myLT = myDB.LayerTableId.GetObject(DatabaseServices.OpenMode.ForWrite)

 

and

 

Dim layTabRec AsLayerTableRecord = tr.GetObject(layId, OpenMode.ForRead)

myLTR = myLT(sourceLayer).GetObject(DatabaseServices.OpenMode.ForWrite)

 

Can someone explain to me when to use which version?  What is the layertablerecord, is it the layer ID?

 

I have this code (some of which is borrowed from a post on this website) and changed to locate an existing layer.  When it gets to the line:

layerId = layTable.Add(layTabRec)

It crashes.  I know it has to have something to do with what I'm passing it.

 

    Public Sub FreezeNewLayerInVPs(ByVal pageNumber)
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim layerToFreeze As String = "DETAIL_" & pageNumber

        Using tr As Transaction = db.TransactionManager.StartTransaction()
            Dim layTable As LayerTable = DirectCast(tr.GetObject(db.LayerTableId, OpenMode.ForRead), LayerTable)
            Dim layerId As ObjectId
            ' Search the layers for the newly created layer
            For Each layId As ObjectId In layTable
                Dim layTabRec As LayerTableRecord = tr.GetObject(layId, OpenMode.ForRead)
                ' If the layer name is greater than or equal to 8 characters
                If layTabRec.Name = layerToFreeze Then
                    ' If the layer table record equals the new layer get the layer ID
                    layerId = layTable.Add(layTabRec)
                End If
            Next
            ' Freeze the new layer in all viewports
            Dim ids As ObjectId() = New ObjectId(0) {layerId}
            Dim layoutDict As DBDictionary = DirectCast(tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead), DBDictionary)
            For Each entry As DBDictionaryEntry In layoutDict
                If entry.Key <> "Model" Then
                    Dim lay As Layout = DirectCast(tr.GetObject(entry.Value, OpenMode.ForRead), Layout)
                    For Each vpId As ObjectId In lay.GetViewports()
                        Dim vp As Viewport = DirectCast(tr.GetObject(vpId, OpenMode.ForWrite), Viewport)
                        vp.FreezeLayersInViewport(ids.GetEnumerator())
                    Next
                End If
            Next
            tr.Commit()
        End Using
    End Sub

 Thanks for your patience and help,

Mark

0 Likes
1,326 Views
4 Replies
Replies (4)
Message 2 of 5

fieldguy
Advisor
Advisor

I'll give it a shot. 

 

1. Dim layTable As LayerTable = DirectCast(tr.GetObject(db.LayerTableId, OpenMode.ForRead), LayerTable)

 

Directcast is an explicit conversion of data types.  To me it means Option Strict is on.  It is safe to use if you are sure of the types involved.  You can also use TryCast or CType and test for nothing if you are not sure.  This code occurs within a transaction (tr.getobject).

 

2. Dim layTable As LayerTable = tr.GetObject(doc.Database.LayerTableId, OpenMode.ForRead)

 

To me this means Option Strict is off - type casting (Directcast or Trycast) is not required.  Type casting still occurs but it is "implicit" (implied) cast.  Again this code occurs within a transaction.

 

3. myLT = myDB.LayerTableId.GetObject(DatabaseServices.OpenM​ode.ForWrite)

 

Option strict is off (no explicit type casting required) and this code occurs without a transaction.  We are requesting objects directly from the database.

 

4. Dim layTabRec As LayerTableRecord = tr.GetObject(layId, OpenMode.ForRead)

 

Option strict off, code occurs within a transaction.

 

5. myLTR = myLT(sourceLayer).GetObject(DatabaseServices.OpenM​ode.ForWrite)

 

Option strict off, no transaction.

 

There is plenty of discussion on the internet as to when to use what methods.  My language preference is C# but my teammates prefer VB.  I work in VB and use Option Strict On as a rule.  I have only had trouble with casting layerstatemasks so far so I have 1 application that does not have option strict on.  I prefer the transaction methods for dealing with database objects.  I like "using" statements as they do most of the housekeeping (dispose, etc.) 

 

The layertable is a collection of objectids,  Each objectid can be cast to a layertablerecord object.  You can add to the layertable by creating a new layertablerecord and assigning the necessary properties (name, color, etc.).    

 

In this example, you are not really adding to the layertable - the layer you want exists already.  If you want the objectid of the layer to freeze, and you want to use the code you have here, you can change the statement to be layerid = laytabrec.objectid.

0 Likes
Message 3 of 5

fieldguy
Advisor
Advisor

Doh!  You can also use layid since you have it defined already.

 

For each layid as objectid in laytable

    'if this is the layername that I want to freeze

   layerid = layid

 

next

0 Likes
Message 4 of 5

mgorecki
Collaborator
Collaborator

Hi Fieldguy,

Thanks for the info.  I've been reading up on layertables and layertablerecords.  I think I understand, but I appreciate you taking the time to explain in "plain english".

 

Mark

0 Likes
Message 5 of 5

jeff
Collaborator
Collaborator

Do you understand DBObject's and how anything that inherits from it is for adding to the Database?

 

Do you understand SymbolTable and SymbolTableRecords(which Inherit from DBOject) and how LayerTable and LayerTableRecords inherit from them?

 

Look in the docs under 'Comparison of Symbol Tables and Dictionaries' and 'ObjectId' and that would also help.

 

Seems like your question is more how GetObject() uses a ObjectID and then converts (Implicit or Explict narrowing conversion) from DBObject to a LayerTable or LayerTableRecord.

With Option strict ON it does not allow Implicit narrowing conversion.

 

 

Also

myLT = myDB.LayerTableId.GetObject(DatabaseServices.OpenMode.ForWrite)

I believe just uses the TransactionManager.TopTransaction to open the object and would probably fail outside all transactions.

 

 

You can also find your answers @ TheSwamp
0 Likes