Select to view content in your preferred language

Get GroupLayer Name

4334
20
07-29-2013 10:00 AM
LeoDonahue
Deactivated User
ArcObjects Java 10.0 sp5

If an IGroupLayer is composed of IFeatureLayers, the following code will print the IGroupLayer name.

If I pass a name that I *think* is an IGroupLayer, my method crashes with null pointer.  So, if you have a map document with a mosaic with sub layers: Boundary, Footprint and Image, is that not an IGroupLayer?  I've also tried ICompositeLayer also, with the same null pointer result.

If I pass the name of my mosaic layer to the following method, I get a null pointer.
If pass the name of any other group layer, it will print the parent group name, in this example "Transportation".

    public IGroupLayer getGroupLayerName(com.esri.arcgis.carto.Map map, AGSConnection agsconn){
        ILayer layer = null;
        
        try {
            
            UID id = (UID) agsconn.getContext().createObject(UID.getClsid());
            id.setValue(com.esri.arcgis.carto.IGroupLayer.class);
            
            // getLayers(UID, true) uses recursion to the get the layer name in a GroupLayer
            IEnumLayer enumLayer = map.getLayers(id, true);
            enumLayer.reset();
            layer = enumLayer.next();
            
            while(!(layer == null)){
                if(layer.getName().equalsIgnoreCase("Transportation")){
                    break;
                } else {
                    layer = enumLayer.next();
                }
            }
        } catch (AutomationException ae) {
            ae.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            System.out.println(layer.getName());
        } catch (AutomationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        return (IGroupLayer) layer;
    }


This method can find the layer named "Image" located within the Mosaic layer, but I really wanted the name of the mosaic group layer.

    public IRasterLayer getRasterLayerName(com.esri.arcgis.carto.Map map, AGSConnection agsconn){
        ILayer layer = null;
        
        try {
            
            UID id = (UID) agsconn.getContext().createObject(UID.getClsid());
            id.setValue(com.esri.arcgis.carto.IRasterLayer.class);
            
            // getLayers(UID, true) uses recursion to the get the layer name in a GroupLayer
            IEnumLayer enumLayer = map.getLayers(id, true);
            enumLayer.reset();
            layer = enumLayer.next();
            
            while(!(layer == null)){
                if(layer.getName().equalsIgnoreCase("Image")){
                    break;
                } else {
                    layer = enumLayer.next();
                }
            }
        } catch (AutomationException ae) {
            ae.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return (IRasterLayer) layer;
    }
0 Kudos
20 Replies
LeoDonahue
Deactivated User
I published a new map document to ArcGIS Server with two layers.

The first layer is a FeatureLayer (index 0)
The second layer is the mosaic dataset (index 1)

System.out.println(agsconn.getMap().getLayer(1).getName());


I get the same errors I have posted before.  Basically... IGroupLayer.getName(unknown source)

If I really have an IGroupLayer, I can't cast it to a MosaicLayer. 
Known implementing classes for IGroupLayer are: BasemapLayer, GroupLayer and IGroupLayerProxy

Was your VBA example reading a map document "not" published to ArcGIS Server?
0 Kudos
T__WayneWhitley
Honored Contributor
You're outreaching me - yes, my example was simply a test confined to the parent mxd, no publishing to the server.  But I would think the same would apply, provided implemented in Java similarly (I don't know).

You said IGroupLayer --- I didn't use this but engineered backward I guess since IMosaicLayer implements ILayer (or ILayer2) - maybe I said this backwards?  I cast ILayer2 as IMosaicLayer with this line:

Set pMscLyr = pCpsLyr


But that's incidental - I first started with ILayer2 obj with a test for the layer whether IMosaicLayer, this line:

If TypeOf pCpsLyr Is IMosaicLayer Then

...which of course tests true (you could additionally test the Name property, if that's what you need).


And pCpsLyr was set up with this (left in the 2nd line, a comment):

Dim pCpsLyr As ILayer2  'ILayer works too
'accessing 1st layer in TOC; incidentally a mosaic layer
Set pCpsLyr = pMxDoc.FocusMap.Layer(0)


The rest of the code was dinking around the sub-layers of the 'composite layer', if you will.  According to how the code executed, the mosaic layer is both a composite and mosaic layer, hence the term I used earlier 'special' (and special arcobject methods are provided beginning at 10.0).  I don't know about your group layer approach...I didn't try that, but notice in my code the test for featurelayer did not return True.  That's comforting (although not really conclusive) that the testing of layer type seems to be working....I know in debug mode I have seen false returns noted and I don't know if that applies here in the way I used it.

Like I said though, hope I am not way off-base here since I know really nothing of Java.

Hope that helps a little...where is Neil when you need him?
Wayne


EDIT:
I appended a statement to test for IGroupLayer and it does NOT return true....so my guess is that is why you cannot use IMosaicLayer.
0 Kudos
T__WayneWhitley
Honored Contributor
So the answer to your original question:

So, if you have a map document with a mosaic with sub layers: Boundary, Footprint and Image, is that not an IGroupLayer?


No, it is not; it is a member of ICompositeLayer.

...you tried that too???


EDIT-
I'm having a hard time reading your code - just curious why are you using IMosaicDataset in this line:

if(layer instanceof IMosaicDataset
0 Kudos
T__WayneWhitley
Honored Contributor

    public void printMosaicLayerName(com.esri.arcgis.carto.Map map, AGSConnection agsconn){
        ILayer2 layer = null;
        
        try {
            
            UID id = (UID) agsconn.getContext().createObject(UID.getClsid());
            id.setValue(com.esri.arcgis.carto.ILayer2.class);
            
            // getLayers(UID, true) uses recursion to the get the layer name in a GroupLayer
            IEnumLayer enumLayer = map.getLayers(id, true);
            enumLayer.reset();
            layer = (ILayer2) enumLayer.next();
            
            while(!(layer == null)){
                System.out.println(layer.getClass().getName() + " " + layer.getName());  // this is line #93
                if(layer instanceof IMosaicDataset){
                    MosaicDataset md = (MosaicDataset)layer;
                    System.out.println(md.getRelativePath().toString());
                } 
                layer = (ILayer2) enumLayer.next();
            }
        } catch (AutomationException ae) {
            ae.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


The output:

*Note:  all the lines prior to the "Caused by:" are related to the UI not loading becuase of this ClassCastException. I expected to see this in the log.

Jul 31, 2013 7:37:43 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 23085 ms
com.esri.arcgis.carto.FeatureLayer Zoning Case
com.esri.arcgis.carto.GroupLayer Transportation          // The next 5 layers are part of the Transporation GroupLayer
com.esri.arcgis.carto.FeatureLayer Residential Streets
com.esri.arcgis.carto.FeatureLayer Major Roads
com.esri.arcgis.carto.FeatureLayer State Highway
com.esri.arcgis.carto.FeatureLayer US Highway
com.esri.arcgis.carto.FeatureLayer Interstates
com.esri.arcgis.carto.FeatureLayer County Boundary
com.esri.arcgis.carto.FeatureLayer Parcels               //  Right after this layer is the mosaic
Jul 31, 2013 7:38:16 AM com.sun.faces.application.ActionListenerImpl processAction
SEVERE: java.lang.ClassCastException: A COM object reference via iid 34c20002-4d3c-11d0-92d8-00805f7c28b0 does not support COM interface edad6644-1810-11d1-86ae-0000f8751720
javax.faces.el.EvaluationException: java.lang.ClassCastException: A COM object reference via iid 34c20002-4d3c-11d0-92d8-00805f7c28b0 does not support COM interface edad6644-1810-11d1-86ae-0000f8751720
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:98)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:98)
    at javax.faces.component.UICommand.broadcast(UICommand.java:311)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:781)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1246)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:77)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassCastException: A COM object reference via iid 34c20002-4d3c-11d0-92d8-00805f7c28b0 does not support COM interface edad6644-1810-11d1-86ae-0000f8751720
    at com.esri.arcgis.interop.Dispatch.c(Unknown Source)
    at com.esri.arcgis.interop.Dispatch.vtblInvoke(Unknown Source)
    at com.esri.arcgis.carto.ILayerProxy.getName(Unknown Source)
    at com.esri.arcgis.carto.GroupLayer.getName(Unknown Source)
    at blah.blah.blah.printMosaicLayerName(MyClassName.java:93)



Let's back up to here for a sec... in your code, looks like the faulty line, as you noted in red, is where you are using IMosaicDataset with ILayer2.  I think that isn't going to work - shouldn't that be where IMosaicLayer is entered?  You simply want the ability to toggle the layer off, correct, and refresh the map service?  With ILayer2, you can toggle the layer on/off; with IMosaicLayer, you can determine whether 'layer' (an ILayer2 obj) is an instance.

...all in theory.

Enjoy,
Wayne
0 Kudos
LeoDonahue
Deactivated User
In post #3, I tested for an instance of MosaicLayer, but that test never ran.

In post #6, I tested for an instance of MosaicDataset, and that test never ran.

In post #7, the code shows that I have a GroupLayer, and all I'm doing there is printing the class name.  Once I try getting the name of the GroupLayer (that is really a mosaic), it produces an error.

In post #1, I indicated I tried the ICompositeLayer.

The stack trace doesn't give me class names in my cast exception, just some cryptic string names.

What this tells me is that certain code reports I have a GroupLayer, but in fact, I do not, due to this cast exception.  But I can't tell what classes these iid's are.


Caused by: java.lang.ClassCastException: A COM object reference via iid 34c20002-4d3c-11d0-92d8-00805f7c28b0 does not support COM interface edad6644-1810-11d1-86ae-0000f8751720 
0 Kudos
T__WayneWhitley
Honored Contributor
I think you may have had it at #3, but shouldn't that be the following? :

layer instanceof IMosaicLayer


...not:

layer instanceof MosaicLayer



That's all I've got...
Wayne


EDIT:
I guess the difference you're looking at is IMosaicLayer is com.esri.arcgis.carto; MosaicLayer is com.esri.arcgis.carto.MosaicLayer.
0 Kudos
LeoDonahue
Deactivated User
IMosaicLayer only has two implementing classes.  IMosaicLayerProxy and MosaicLayer.  I should be able to test an instanceof MosaicLayer, right?  MosaicLayer implements IMosaicLayer.

And if you look at the implemented interfaces of MosaicLayer... this is what I don't get.  If GroupLayer is not an implemented interface of MosaicLayer, why is certain code telling me I have a GroupLayer?  This is the confusing part.


com.esri.arcgis.carto
Class MosaicLayer

java.lang.Object   com.esri.arcgis.carto.MosaicLayer

All Implemented Interfaces:
IAttributeTable, ICompositeLayer, ICompositeLayer2, IDataLayer, IDataLayer2, IIdentify, IIdentify2, ILayer, ILayer2, ILayerDrawingProperties, ILayerEffects, ILayerExtensions, ILayerGeneralProperties, ILayerInfo, ILayerMasking, ILayerPosition, ILayerSymbologyExtents, IMosaicLayer, IPublishLayer, ITableDefinition, ITimeData, ITimeDataDisplay, ITimeTableDefinition, IRasterDataManagementEvents, IConnectionPointContainer, IDisplayAdmin, IDisplayAdmin2, IDisplayFilterManager, IDataset, IGeoDataset, IWorkspaceEditEvents, com.esri.arcgis.interop.RemoteObjRef, IClassID, IPersist, IPersistStream, ISupportErrorInfo, Externalizable, Serializable, EventListener

0 Kudos
LeoDonahue
Deactivated User

That's all I've got...
Wayne

I appreciate your time batting some ideas around with me.
0 Kudos
T__WayneWhitley
Honored Contributor
Of course... I am acutely interested in this, you might say - actually wish I could do this type thing all of the time, provided I get to keep my marbles by the end of the day!

I guess in your investigations you revisited the below thread, although it applies to VB.NET, I think it still has implications for Java:
http://forums.arcgis.com/threads/47631-Why-is-everything-a-Mosaic-Layer?#5

...actually, you responded to this back a yr ago January.

Thought this curious false for typeof return on IMosaicLayer; true on MosaicLayer.


This works similarly in VBA, as I proved...might not be so in Java.

-Wayne


PS - I was looking at this too (below), but I don't follow it well...

Casting and runtime type checking (using instanceof)
http://resources.arcgis.com/en/help/arcobjects-java/concepts/engine/index.html#//0001000006mw000000
0 Kudos
LeoDonahue
Deactivated User
I've come to the conclusion that I can not get the name of mosaic that has been added to my map document published in ArcGIS Server. But I can get the names of the layers in the mosaic.

It appears as though a mosaic is a GroupLayer containing two FeatureLayers and one ImageServiceLayer, but I can't get the name of the GroupLayer when it's a mosaic.

For what it's worth....

The method:
    public void printMosaicLayerName(com.esri.arcgis.carto.Map map, AGSConnection agsconn){
        ILayer layer = null;
        
        try {
            
            UID id = (UID) agsconn.getContext().createObject(UID.getClsid());
            id.setValue(ILayer.class);
            
            // getLayers(UID, true) uses recursion to the get the layer name in a GroupLayer
            IEnumLayer enumLayer = map.getLayers(id, true);
            enumLayer.reset();
            layer = enumLayer.next();
            
            while(!(layer == null)){
                System.out.println(layer.getClass().getName());
                //System.out.println(layer.getName());
                System.out.println("ILayer?: " + (layer instanceof ILayer));
                System.out.println("IGroupLayer?: " + (layer instanceof IGroupLayer));
                System.out.println("IMosaicLayer?: " + (layer instanceof IMosaicLayer));
                System.out.println("------------------------------------");
                
                layer = enumLayer.next();
            }
        } catch (AutomationException ae) {
            ae.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }




Ouput when not calling layer.getName()

com.esri.arcgis.carto.FeatureLayer
ILayer?: true
IGroupLayer?: false
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.GroupLayer
ILayer?: true
IGroupLayer?: true
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.FeatureLayer
ILayer?: true
IGroupLayer?: false
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.FeatureLayer
ILayer?: true
IGroupLayer?: false
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.FeatureLayer
ILayer?: true
IGroupLayer?: false
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.FeatureLayer
ILayer?: true
IGroupLayer?: false
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.FeatureLayer
ILayer?: true
IGroupLayer?: false
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.FeatureLayer
ILayer?: true
IGroupLayer?: false
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.FeatureLayer
ILayer?: true
IGroupLayer?: false
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.GroupLayer
ILayer?: true
IGroupLayer?: true
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.FeatureLayer
ILayer?: true
IGroupLayer?: false
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.FeatureLayer
ILayer?: true
IGroupLayer?: false
IMosaicLayer?: false
------------------------------------
com.esri.arcgis.carto.ImageServerLayer
ILayer?: true
IGroupLayer?: false
IMosaicLayer?: false
------------------------------------



Result of uncommenting the line of:  layer.getName()

com.esri.arcgis.carto.GroupLayer
Aug 1, 2013 8:32:06 AM com.sun.faces.application.ActionListenerImpl processAction
SEVERE: java.lang.ClassCastException: A COM object reference via iid 34c20002-4d3c-11d0-92d8-00805f7c28b0 does not support COM interface edad6644-1810-11d1-86ae-0000f8751720
javax.faces.el.EvaluationException: java.lang.ClassCastException: A COM object reference via iid 34c20002-4d3c-11d0-92d8-00805f7c28b0 does not support COM interface edad6644-1810-11d1-86ae-0000f8751720
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:98)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:98)
    at javax.faces.component.UICommand.broadcast(UICommand.java:311)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:781)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1246)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:77)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassCastException: A COM object reference via iid 34c20002-4d3c-11d0-92d8-00805f7c28b0 does not support COM interface edad6644-1810-11d1-86ae-0000f8751720
    at com.esri.arcgis.interop.Dispatch.c(Unknown Source)
    at com.esri.arcgis.interop.Dispatch.vtblInvoke(Unknown Source)
    at com.esri.arcgis.carto.ILayerProxy.getName(Unknown Source)
    at com.esri.arcgis.carto.GroupLayer.getName(Unknown Source)

I googled for those string values in the ClassCastException.

The Caused by line is saying: A COM object reference via iid ILayer does not support COM interface IGroupLayer - um what?
0 Kudos