Add IFeatureLayer from FeatureServer

980
8
Jump to solution
08-16-2016 07:05 AM
MickeyO_Neil
New Contributor III

Hello,

I'm trying to load a IFeatureLayer from a FeatureServer in a ArcGIS Engine 10.3 Application, but I always get a "System.Runtime.InteropServices.COMException" Error Message. (Line is marked with an Error Comment).

What is the Problem of getting the Layers from the Server?

Thank You very much for your help.

    Public Shared Function GetAGSFeatureLayer(ByVal sURL As String) As IFeatureLayer
        Dim pAGSConnectionFactory As IAGSServerConnectionFactory
        Dim pConnectionProps As IPropertySet
        Dim pAGSConnection As IAGSServerConnection
        Dim enumServerObjectName As IAGSEnumServerObjectName
        Dim pServerObjectName As IAGSServerObjectName3
        Dim pName As IName
        Dim pObject As Object
        Dim pServerSymbolOutputOptions As IServerSymbolOutputOptions
        Dim pGraphicFeatureLayers As IGraphicFeatureLayers
        Dim pGraphicFeatureLayer As IGraphicFeatureLayer2
        Dim pGraphicFeatureServer As IGraphicFeatureServer

        Try
            pConnectionProps = New PropertySet
            pConnectionProps.SetProperty("URL", sURL)
            pAGSConnectionFactory = New AGSServerConnectionFactory
            pAGSConnection = pAGSConnectionFactory.Open(pConnectionProps, 0)

            enumServerObjectName = pAGSConnection.ServerObjectNames
            enumServerObjectName.Reset()
            pServerObjectName = enumServerObjectName.Next

            Do Until pServerObjectName Is Nothing

                If pServerObjectName.Type.Equals("FeatureServer", StringComparison.OrdinalIgnoreCase) Then
                    pName = pServerObjectName
                    pObject = pName.Open

                    If TypeOf pObject Is IGraphicFeatureServer Then

                        pServerSymbolOutputOptions = New ServerSymbolOutputOptions
                        pServerSymbolOutputOptions.ConvertLabelExpressions = False
                        pServerSymbolOutputOptions.PictureOutputType = esriServerPictureOutputType.esriServerPictureOutputAsPNG

                        pGraphicFeatureServer = pObject
                        pGraphicFeatureLayers = pGraphicFeatureServer.GetLayers(pServerSymbolOutputOptions) 'ERROR

                        If pGraphicFeatureLayers.Count > 0 Then
                            For i As Integer = 0 To pGraphicFeatureLayers.Count - 1

                                pGraphicFeatureLayer = pGraphicFeatureLayers.Element(i)
                                If TypeOf pGraphicFeatureLayer Is IFeatureLayer Then
                                    Return pGraphicFeatureLayer
                                End If
                            Next
                        End If
                    End If

                End If
                pServerObjectName = enumServerObjectName.Next
            Loop
        Catch ex As Exception
            logger.Error("GetAGSFeatureLayer", ex)
        End Try
        Return Nothing
    End Function

Reply
0 Kudos
1 Solution

Accepted Solutions
MickeyO_Neil
New Contributor III

Got it:

Snippet

Public Shared Function GetAGSFeatureLayer(ByVal sURL As StringAs IFeatureLayer        
   Dim pAGSConnectionFactory As IAGSServerConnectionFactory        
   Dim pConnectionProps As IPropertySet        
   Dim pAGSConnection As IAGSServerConnection        
   Dim enumServerObjectName As IAGSEnumServerObjectName        
   Dim pServerObjectName As IAGSServerObjectName3          
   Dim pLayerFactory As ILayerFactory        
   Dim pEnumLayer As IEnumLayer        
   Dim pLayer As ILayer        
   Dim pCurrentLayer As ILayer        
   Dim pCompositeLayer As ICompositeLayer        
   Try            
      pConnectionProps = New PropertySet            
      pConnectionProps.SetProperty("URL", sURL)             
      pAGSConnectionFactory = New AGSServerConnectionFactory            
      pAGSConnection = pAGSConnectionFactory.Open(pConnectionProps, 0)               
      enumServerObjectName = pAGSConnection.ServerObjectNames             
      enumServerObjectName.Reset()             
      pServerObjectName = enumServerObjectName.Next               
      Do Until pServerObjectName Is Nothing                  
         If pServerObjectName.Type.Equals("FeatureServer"StringComparison.OrdinalIgnoreCase) Then                                         
            pLayerFactory = New FeatureServerLayerFactory                    
            pEnumLayer = pLayerFactory.Create(pServerObjectName)                     
            pLayer = pEnumLayer.Next()                       
            Do Until pLayer Is Nothing                        
               If TypeOf pLayer Is ICompositeLayer Then                            
                  pCompositeLayer = pLayer                               
                  For i As Integer = 0 To pCompositeLayer.Count - 1                                 
                     pCurrentLayer = pCompositeLayer.Layer(i)                                 
                     If TypeOf pCurrentLayer Is IFeatureLayer Then                                      
                        Return DirectCast(pCurrentLayer, IFeatureLayer)                                 
                     End If                            
                  Next                        
               End If                        
               pLayer = pEnumLayer.Next()                     
            Loop                  
         End If                
         pServerObjectName = enumServerObjectName.Next             
      Loop        
   Catch ex As Exception            
      logger.Error("GetAGSFeatureLayer", ex)         
   End Try        
   Return Nothing    
End Function

View solution in original post

8 Replies
seria
by Esri Contributor
Esri Contributor

The code sample here below shows how to add a feature service to ArcMap using ArcObjects (click on the image below to enlarge the image):

How to Add a Feature Service to ArcMap

Reply
0 Kudos
MickeyO_Neil
New Contributor III

Thank you, very much, but in your example you create your own new layer.

Isn't it possible to get the layer with it's symbology/renderer from the Feature-Service?

Reply
0 Kudos
seria
by Esri Contributor
Esri Contributor

Mickey,

Yes, that is correct. I do create my own new layer to add to ArcMap. One would definitely need an instance of a new layer object to hold the properties of the incoming feature service data, so there is definitely a need to create that new layer.

However, in order to symbolize and display that new layer the exact same way it was being displayed on the server (and I believe this is your question), you would simply not assign a renderer to it. Thus, in the code I provided earlier, all you'd have to do is  to comment out the "renderer" part of the code. This should allow the display of the layer in its "original" form. In this case, the original renderer that was used for the feature service layer on the server (the REST endpoint) would automatically be utilized by ArcMap to render the layer.  

Reply
0 Kudos
MickeyO_Neil
New Contributor III

Hello Sami,

thank you, that's what I was looking for. But there are two more things I need to know:

If I load a Feature Service in ArcMap, the Layers have Layernames which are the Name of the Feature-Class in their SDE. In ArcObjects the FC-Names are Numbers. Furthermore the Layer have set a minimum scale. 

Where do I find the FC-Name and minimum Scale in ArcObjects? 

Reply
0 Kudos
seria
by Esri Contributor
Esri Contributor

The feature class name can be accessed via the IFeatureClass.AliasName property:

http://resources.arcgis.com/en/help/arcobjects-net/componenthelp/index.html#//0025000002qs000000 

The layer's minimum scale may be accessed via the ILayer.MinimumScale property:

http://resources.arcgis.com/en/help/arcobjects-net/componenthelp/index.html#//0012000006z1000000 

A good book on ArcObjects development that you might find useful is Beginning ArcGIS for Desktop Development using .NET, by Pouria Amirian (2013).

Reply
0 Kudos
MickeyO_Neil
New Contributor III

Sorry, my english is not very good, maybe you didn't understand me right:

I'm writing an ArcGIS Engine Application which should load Feature-Services the same way as ArcMap. And if I load a Feature-Service in ArcMap, ArcMap creates Layers with a Layername, a Symbology and a minimum scale. 

Now If I use your code from above in my ArcGIS Engine App, I only have a Feature-Class. The name and the alias-name of this Feature-Class is a number (e.g. 0). And if I create a new Layer and set the datasource, the Layer has no minimum scale.

So, my question is: how does ArcMap gets the Layername and minimum scale from the Feature-Service? Your code from above does not answer this question.

Thank you very much.

Reply
0 Kudos
MickeyO_Neil
New Contributor III

Any suggestions so far?

Reply
0 Kudos
MickeyO_Neil
New Contributor III

Got it:

Snippet

Public Shared Function GetAGSFeatureLayer(ByVal sURL As StringAs IFeatureLayer        
   Dim pAGSConnectionFactory As IAGSServerConnectionFactory        
   Dim pConnectionProps As IPropertySet        
   Dim pAGSConnection As IAGSServerConnection        
   Dim enumServerObjectName As IAGSEnumServerObjectName        
   Dim pServerObjectName As IAGSServerObjectName3          
   Dim pLayerFactory As ILayerFactory        
   Dim pEnumLayer As IEnumLayer        
   Dim pLayer As ILayer        
   Dim pCurrentLayer As ILayer        
   Dim pCompositeLayer As ICompositeLayer        
   Try            
      pConnectionProps = New PropertySet            
      pConnectionProps.SetProperty("URL", sURL)             
      pAGSConnectionFactory = New AGSServerConnectionFactory            
      pAGSConnection = pAGSConnectionFactory.Open(pConnectionProps, 0)               
      enumServerObjectName = pAGSConnection.ServerObjectNames             
      enumServerObjectName.Reset()             
      pServerObjectName = enumServerObjectName.Next               
      Do Until pServerObjectName Is Nothing                  
         If pServerObjectName.Type.Equals("FeatureServer"StringComparison.OrdinalIgnoreCase) Then                                         
            pLayerFactory = New FeatureServerLayerFactory                    
            pEnumLayer = pLayerFactory.Create(pServerObjectName)                     
            pLayer = pEnumLayer.Next()                       
            Do Until pLayer Is Nothing                        
               If TypeOf pLayer Is ICompositeLayer Then                            
                  pCompositeLayer = pLayer                               
                  For i As Integer = 0 To pCompositeLayer.Count - 1                                 
                     pCurrentLayer = pCompositeLayer.Layer(i)                                 
                     If TypeOf pCurrentLayer Is IFeatureLayer Then                                      
                        Return DirectCast(pCurrentLayer, IFeatureLayer)                                 
                     End If                            
                  Next                        
               End If                        
               pLayer = pEnumLayer.Next()                     
            Loop                  
         End If                
         pServerObjectName = enumServerObjectName.Next             
      Loop        
   Catch ex As Exception            
      logger.Error("GetAGSFeatureLayer", ex)         
   End Try        
   Return Nothing    
End Function

View solution in original post