views:

400

answers:

4

Is there a way in arcobjects to get a unique id for a layer? If you do a search by layer name there could be possible duplicates.

If there isn't a property is there a way to generate an id? I tried using the GetHash() but that didn't stay consistent.

+1  A: 

It isn't pretty, but in the past I've appended a guid in the layer description. Something like this:

<LAYER guid='a9843c88-3caa-4953-ad96-ca9990b410e9' revision='1' />

I've got a DLL floating around that would slam these xml frags into each layer of an MXD (with enough cr/lf in front to scroll the xml fragment out of the layer description in ArcMap Layer Prop dialog) .

There's a help file in the 7z file (documentation is sparse because I'm doing other things): http://code.google.com/p/umbriel/downloads/list

I guess I can run a routine that adds this to every layer when my tool first starts.You would think after all these years ESRI would add this simple property or at least restrict duplicate names.Thanks
Donny V.
Kirk Kuykendall made mention of adding a propertyset to ILayerExtensions and that it stays with the layer...even with the layer is saved to a layer file:http://bit.ly/38PAK
+1  A: 

There is an ArcObjects Interface present for setting or getting an Id for a layer. You should look at ILayerDescriptor:ID, http://resources.esri.com/help/9.3/ArcGISDesktop/ArcObjects/esriCarto/ILayerDescriptor_ID.htm

Here is a VBA Snippet which shows how it can be used:

Public Sub layerInfo()

Dim app As IApplication '
Set app = Application

Dim mxDoc As IMxDocument
Set mxDoc = app.Document

Dim myMap As IMap
Set myMap = mxDoc.ActiveView

Dim mapServer As IMxdServer
Set mapServer = New MxdServer

'''Point to your .mxd...
mapServer.Start ("D:\Test.mxd")

Dim myArray As IArray
Set myArray = mapServer.LayerDescriptors(myMap.Name)

MsgBox myArray.Count

Dim x As ILayerDescriptor
Dim intX As Integer
intX = 0

For intX = 0 To myArray.Count - 1
Set x = myArray.Element(intX)
MsgBox x.ID
MsgBox x.Name
Next

End Sub
dev
I've never used ILayerDescriptor before. I just tried your code--it doesn't provide IDs for layers that are added after opening (an mxd save prior is needed). Is there a way to get LayerDescriptors without having to start an MXD?
Same question here.
Donny V.
Yes you are right. This interface is basically meant for MXD's which are being served from an ArcGIS Server. They can also be used, when the MXD is saved and being read. However as you have found out, the Map Document needs to be saved, before this can be used.
dev
A: 

Easy. A side effect of using COM and because how the vtables are laid out, is that you can use the memory address of the layer itself as your unique identifier. Inside the implementation of many ESRI GeoDatabase and Carto code itself, this trick is being used all over the place.

rburhum
How do you get the memory address? Also does this address change while they work in the mxd or save it?
Donny V.
Depends on the language. In C++ the interface *pointer* itself is a pointer, use that. In VB6 (or VBA) the same is true. In other words:dim pLayer as ILayerset pLayer = pMap.Layers(0)use pLayer as the key in your collection/dictionary.No, it will not change during the lifetime of the COM object (while they are still working in the same MxD). If they save, *and continue their session* it will remain the same... however, if the close the document and open it again, then it will be different.
rburhum
+1  A: 

I like the idea of using a GUID. This can then be stored in the ModelName property which is a tool for developers of custom objects to use to guarantee the names of objects independent of the true name or alias name.

There are more details and sample code at http://geographika.co.uk/?p=58

geographika