[GIS] Programmatically get Layer source properties DataType with ArcObjects

arcobjectslayersrest

I am trying to access the DataType property of a Layer in the TOC in ArcMap. The layer is added from a web service as an IMapServerRESTLayer. The Data Type property is listed with Layer -> Properties -> source as in the following screen shot.

enter image description here

The map layer has a Type Of ICompositeLayer. It is a basemap.

Things I've tried.

It cannot be cast as a IFeatureLayer. I have looked at the Carto Object Model Diagram, and cannot find a DataLayer property on anything except IMobileLayerInfo. and a similar ServiceDataType on IImageServerLayer. Tried making interface casts toward these objects but failed.

Looked at using IComProperty Sheets … managed to create an unpopulated version but think this not the way to go.

I am programming in VB.Net (but can read C#) in ArcGIS 10.2 using VS2010

Any ideas?


Here is the code I have been using to test retrieve the layer and test it.
This is the on click method for a command button within an ArcMap Addin. It's part of a bigger toolbar. There are comments on the outcome of various parts of the code.

   Protected Overrides Sub OnClick()
    Const csProceedureName As String = "cmdListBaseMap_OnClick"
    MsgBox("In " & csProceedureName & vbNewLine & My.ThisAddIn.Name & vbNewLine & "  Version " & My.ThisAddIn.Version & vbNewLine & "  Date    " & My.ThisAddIn.Date)
    Try
        Dim pApp As IApplication
        Dim pMxDoc As IMxDocument
        Dim pMap As IMap
        Dim pView As IActiveView
        Dim resturl As String
        'resturl = "http://services.thelist.tas.gov.au/arcgis/rest/services/Basemaps/Topographic/ImageServer/?f=lyr&v=9.3"  ' v1 ' works
        resturl = "http://services.thelist.tas.gov.au/arcgis/rest/services/Basemaps/Topographic/ImageServer/?f=lyr"        ' v2 ' works
        'resturl = "http://services.thelist.tas.gov.au/arcgis/services/Basemaps/Topographic/ImageServer"                     ' v3 ' does not work, does not leave a connection

        ' there was a problem getting the interface to work. 
        ' In addition to carto needed to include ESRI.ArcGIS.DataSourceRaster
        Dim RESTLayer As IMapServerRESTLayer
        RESTLayer = New MapServerRESTLayer

        Dim pLayer As ILayer
        Dim pFLayer As IFeatureLayer
        Dim pGenProperties As ILayerGeneralProperties
        Dim Mouse_cursor As IMouseCursor = New MouseCursor
        Mouse_cursor.SetCursor(2)

        pApp = My.ArcMap.Application
        pMxDoc = pApp.Document
        pMap = pMxDoc.FocusMap
        pView = pMxDoc.ActiveView

        ' Use web HttpWebRequest to see if connection OK and so can retrieve file
        Dim request_json_url As String = "http://services.thelist.tas.gov.au/arcgis/rest/services/Basemaps/Topographic/ImageServer/?f=json"
        Dim request As HttpWebRequest = DirectCast(HttpWebRequest.Create(request_json_url), HttpWebRequest)
        Dim response As HttpWebResponse = DirectCast(request.GetResponse, HttpWebResponse)


        'MsgBox("Doing test " & response.StatusCode.ToString & " " & response.StatusDescription & " " & HttpStatusCode.OK.ToString)
        If response.StatusCode = HttpStatusCode.OK Then
            ' connection and response OK
            'MsgBox("Status Code " & response.StatusCode & vbNewLine & " Status description " & response.StatusDescription & vbNewLine & " Encoding " & response.CharacterSet)


            ' this is one method of getting the json file
            'Dim encoding As Text.Encoding = System.Text.Encoding.GetEncoding(response.CharacterSet)
            'Dim reader As New StreamReader(response.GetResponseStream(), encoding)
            'Dim streamtext As String = reader.ReadToEnd()
            'MsgBox(streamtext)

            '' use a webclient to check connection, the try cast does exception handling
            'Dim wc As WebClient = New WebClient
            'Dim response_client As String
            '    response_client = wc.DownloadString(request_json_url)
            '    MsgBox(response_client)


            ' Get basemap
            RESTLayer.Connect(resturl)
            RESTLayer.TransparentBackground(True)

            ' this cast works
            pLayer = TryCast(RESTLayer, ILayer)
            If pLayer Is Nothing Then
                MsgBox("Cast from MapServerRESTLayer to Ilayer failed")
            Else
                MsgBox("Cast from MapServerRESTLayer to Ilayer OK")
            End If

            'Dim pDataLayer As IDataLayer
            ''this cast works
            'pDataLayer = TryCast(RESTLayer, IDataLayer)
            'If pDataLayer Is Nothing Then
            '    MsgBox("Cast from MapServerRESTLayer to IDataLayer failed")
            'Else
            '    MsgBox("Cast from MapServerRESTLayer to IDataLayer OK -" & pDataLayer.DataSourceName.NameString & "-") ' Name is empty

            '    ' cast here fails: so no path to IIMageserver
            '    Dim pServerLayer As IImageServerLayer
            '    pServerLayer = TryCast(pDataLayer, IImageServerLayer)
            '    If pServerLayer Is Nothing Then
            '        MsgBox("Cast from MapServerRESTLayer to IDataLayer to IImageServerLayer failed")
            '    Else
            '        MsgBox("Cast from MapServerRESTLayer to IDataLayer to IImageServerLayer OK " & pServerLayer.ServiceInfo.ServiceDataType.ToString)
            '    End If
            'End If

            '' this cast fails
            'Dim pServerLayer As IImageServerLayer
            'pServerLayer = TryCast(RESTLayer, IImageServerLayer)
            'If pServerLayer Is Nothing Then
            '    MsgBox("Cast from MapServerRESTLayer to IImageServerLayer failed")
            'Else
            '    MsgBox("Cast from MapServerRESTLayer to IImageServerLayer OK " & pServerLayer.ServiceInfo.ServiceDataType.ToString)
            'End If

            '' this cast also fails
            'Dim pServerLayerA As IImageServerLayer
            'pServerLayerA = TryCast(pLayer, IImageServerLayer)
            'If pServerLayerA Is Nothing Then
            '    MsgBox("Cast from ILayer to IImageServerLayer failed")
            'Else
            '    MsgBox("Cast from ILayer to IImageServerLayer OK " & pServerLayerA.ServiceInfo.ServiceDataType.ToString)
            'End If

            ' This cast sequence fails at first cast
            'Dim pMapServerLayer As IMapServerLayer
            'pMapServerLayer = TryCast(RESTLayer, IMapServerLayer)
            'If pMapServerLayer Is Nothing Then
            '    MsgBox("Cast from MapServerRESTLayer to IMapServerLayer failed")
            'Else
            '    MsgBox("Cast from MapServerRESTLayer to IMapServerLayer OK")
            '    Dim pImageServerLayerC As IImageServerLayer
            '    pImageServerLayerC = TryCast(pLayer, IImageServerLayer)
            '    If pImageServerLayerC Is Nothing Then
            '        MsgBox("* Cast from IMapServerLayer to IImageServerLayer failed")
            '    Else
            '        MsgBox("* Cast from IMapServerLayer to IImageServerLayer OK " & pImageServerLayerC.ServiceInfo.ServiceDataType.ToString)
            '    End If
            'End If


            ' cast failed
            'Dim ImageServiceInfo As IImageServiceInfo
            'ImageServiceInfo = TryCast(pLayer, ImageServiceInfo)
            'If ImageServiceInfo Is Nothing Then
            '    MsgBox("Cast from ILayer to IImageServiceInfo failed")
            'Else
            '    MsgBox("Cast from ILayer to IImageServiceInfo OK " & vbNewLine & _
            '           " Service Data Type " & ImageServiceInfo.ServiceDataType & vbNewLine & _
            '           " Service Source Type " & ImageServiceInfo.ServiceSourceType & vbNewLine & _
            '           " Default Service Properties " & ImageServiceInfo.DefaultServiceProperties)
            'End If


            ' This works
            ' Returns the Description 
            ' this returns a string with 
            ' "Tasmania Topographic base map", "LIST web service"
            ' for services and conditions see URL to services and consitions pdf
            '
            'pGenProperties = TryCast(pLayer, ILayerGeneralProperties)
            'If pGenProperties Is Nothing Then
            '    MsgBox("No general properties")
            'Else
            '    MsgBox("Properties -" & pGenProperties.LayerDescription & "-")

            'End If


            '' This cast works
            'Dim pCompositeLayer As ICompositeLayer2
            'pCompositeLayer = TryCast(pLayer, ICompositeLayer2)
            'If pCompositeLayer Is Nothing Then
            '    MsgBox("Cast from ILayer to ICompositeLayer failed")
            'Else
            '    MsgBox("Cast from ILayer to ICompositeLayer OK " & pCompositeLayer.Count.ToString)
            'End If

            '' This cast also works
            'Dim pCompositeLayerA As ICompositeLayer2
            'pCompositeLayerA = TryCast(RESTLayer, ICompositeLayer2)
            'If pCompositeLayerA Is Nothing Then
            '    MsgBox("Cast from ReST to ICompositeLayer failed")
            'Else
            '    MsgBox("Cast from REST to ICompositeLayer OK " & pCompositeLayerA.Count.ToString)
            'End If



            ' add layer to map
            pMap.AddLayer(pLayer)
            pView.Refresh()


            ' both versions of the imported layer are ILayer, IDataLayer, ICompositeLayer 
            MsgBox("player " & pLayer.Name & " is of type " & LayerType(pLayer))
            MsgBox("RESTLayer " & pLayer.Name & " is of type " & LayerType(pLayer))

            pMxDoc.ActiveView.Refresh()
            MsgBox("Base map layer " & pLayer.Name & "has been added")

        Else
            MsgBox("ERROR ( " & csProceedureName & " ) " & response.StatusCode & vbNewLine & response.StatusDescription)
        End If

        Mouse_cursor.SetCursor(0)

    Catch ex As Exception
        MsgBox("Error " & ex.Message)
    End Try


End Sub

Protected Overrides Sub OnUpdate()

End Sub

Public Function LayerType(ByVal pLayer As ILayer) As String
    ' return layer TypeOf
    LayerType = ""
    If TypeOf pLayer Is ILayer Then
        LayerType = LayerType & " " & "ILayer"
    End If

    If TypeOf pLayer Is IACAcetateLayer Then
        LayerType = LayerType & " " & "IACAcetateLayer"
    End If

    If TypeOf pLayer Is IACImageLayer Then
        LayerType = LayerType & " " & "IACImageLayer"
    End If

    If TypeOf pLayer Is IACFeatureLayer Then
        LayerType = LayerType & " " & "IACFeatureLayer"
    End If

    If TypeOf pLayer Is IACFeatureLayer Then
        LayerType = LayerType & " " & "IACFeatureLayer"
    End If

    If TypeOf pLayer Is IACLayer Then
        LayerType = LayerType & " " & "IACLayer"
    End If

    If TypeOf pLayer Is IAnnotationLayer Then
        LayerType = LayerType & " " & "IAnnotationLayer"
    End If

    If TypeOf pLayer Is IAnnotationSublayer Then
        LayerType = LayerType & " " & "IAnnotationSublayer"
    End If

    If TypeOf pLayer Is ICadastralFabricLayer Then
        LayerType = LayerType & " " & "ICadastralFabricLayer"
    End If

    If TypeOf pLayer Is ICadLayer Then
        LayerType = LayerType & " " & "ICadLayer"
    End If

    If TypeOf pLayer Is ICompositeGraphicsLayer Then
        LayerType = LayerType & " " & "ICompositeGraphicsLayer"
    End If

    If TypeOf pLayer Is ICompositeLayer Then
        LayerType = LayerType & " " & "ICompositeLayer"
    End If

    If TypeOf pLayer Is ICoverageAnnotationLayer Then
        LayerType = LayerType & " " & "ICoverageAnnotationLayer"
    End If

    If TypeOf pLayer Is IDataLayer Then
        LayerType = LayerType & " " & "IDataLayer"
    End If

    If TypeOf pLayer Is IDimensionLayer Then
        LayerType = LayerType & " " & "IDimensionLayer"
    End If

    If TypeOf pLayer Is IFDOGraphicsLayer Then
        LayerType = LayerType & " " & "IFDOGraphicsLayer"
    End If

    If TypeOf pLayer Is IFeatureLayer Then
        LayerType = LayerType & " " & "IFeatureLayer"
    End If

    If TypeOf pLayer Is IGdbRasterCatalogLayer Then
        LayerType = LayerType & " " & "IGdbRasterCatalogLayer"
    End If

    If TypeOf pLayer Is IGeoFeatureLayer Then
        LayerType = LayerType & " " & "IGeoFeatureLayer"
    End If

    If TypeOf pLayer Is IGraphicsLayer Then
        LayerType = LayerType & " " & "IGraphicsLayer"
    End If

    If TypeOf pLayer Is IGroupLayer Then
        LayerType = LayerType & " " & "IGroupLayer"
    End If

    If TypeOf pLayer Is IIMSMapLayer Then
        LayerType = LayerType & " " & "IIMSMapLayer"
    End If

    If TypeOf pLayer Is IIMSSubLayer Then
        LayerType = LayerType & " " & "IIMSSubLayer"
    End If

    If TypeOf pLayer Is IImageServerLayer Then
        LayerType = LayerType & " " & "IImageServerLayer"
    End If

    If TypeOf pLayer Is IImageServerLayer2 Then
        LayerType = LayerType & " " & "IImageServerLayer2"
    End If

    If TypeOf pLayer Is IImageServerLayer3 Then
        LayerType = LayerType & " " & "IImageServerLayer3"
    End If

    If TypeOf pLayer Is IMapServerLayer Then
        LayerType = LayerType & " " & "IMapServerLayer"
    End If

    If TypeOf pLayer Is IMapServerSublayer Then
        LayerType = LayerType & " " & "IMapServerSublayer"
    End If

    If TypeOf pLayer Is INetworkLayer Then
        LayerType = LayerType & " " & "INetworkLayer"
    End If

    If TypeOf pLayer Is IRasterCatalogLayer Then
        LayerType = LayerType & " " & "IRasterCatalogLayer"
    End If

    If TypeOf pLayer Is IRasterLayer Then
        LayerType = LayerType & " " & "IRasterLayer"
    End If

    If TypeOf pLayer Is ITemporaryLayer Then
        LayerType = LayerType & " " & "ITemporaryLayer"
    End If

    If TypeOf pLayer Is ITerrainLayer Then
        LayerType = LayerType & " " & "ITerrainLayer"
    End If

    If TypeOf pLayer Is ITinLayer Then
        LayerType = LayerType & " " & "ITinLayer"
    End If
    If TypeOf pLayer Is ITopologyLayer Then
        LayerType = LayerType & " " & "ITopologyLayer"
    End If
    If TypeOf pLayer Is IWMSGroupLayer Then
        LayerType = LayerType & " " & "IWMSGroupLayer"
    End If

    If TypeOf pLayer Is IWMSLayer Then
        LayerType = LayerType & " " & "IWMSLayer"
    End If
    If TypeOf pLayer Is IWMSMapLayer Then
        LayerType = LayerType & " " & "IWMSMapLayer"
    End If

    'Else
    '    LayerType = "UnKnown"
    'End If

End Function

Best Answer

I can check the URL in your snapshot and say the layer you are trying to work with is an ImageServer Layer.

http://services.thelist.tas.gov.au/arcgis/rest/services/Basemaps/Topographic/ImageServer

You can not access an imageserver layer as a feature layer.

You can only access map server layers that have "Feature Access" enabled, as a feature layer. (e.g. Cast them to IFeatureLayer)

Related Question