• Meet the new blog...

    This ArcGIS Engine blog is retiring.  Its content moving forward is being merged with the new "ArcObjects Development Blog". 

    For ArcObjects developers, our original plan was to create two blogs:

    1.  This ArcGIS Engine development blog here for VS6, .NET, C++, and Java developers, and

    2.  An ArcGIS Desktop development blog, specifically for those developers who are coding with VBA or using the ArcGIS Desktop development kit to create extensions and other applications and such.

    With this post we would like to announce that we're merging the two communities into one.  This link here will take you to the new "ArcObjects Development Blog" which will cover topics and discussions of interest to all developers who are using the ArcObjects API, whether that be with ArcGIS Desktop or ArcGIS Engine using any supported programming language, development environment, or operating system and platform.  

    We would like to thank those who have supported this ArcGIS Engine blog thusfar, and we expect that the scope of this new one will benefit the community much better than the two could separately.

  • How do I get related objects from a table based on a selection?

    The following code samples demonstrate how to get related objects from a table based on the selected records in the first table. Sample one demonstrates doing this from destination table to origin table and sample two demonstrates going from origin table to destination table.

     Sample One: Destination to Origin

    Private Sub GetSelection_fromRelated()

    Dim pDoc As IMxDocument
    Dim pMap As IMap
    Dim pFLayer As IFeatureLayer
    Dim pFClass As IFeatureClass
    Dim pRelClassColl As IRelationshipClassCollection
    Dim pRelClass As IRelationshipClass
    Dim pEnumRelClass As IEnumRelationshipClass
    Dim pStandAloneTable As IStandaloneTable
    Dim pStandtabcollection As IStandaloneTableCollection
    Dim pTable As ITable
    Dim pQf As IQueryFilter
    Dim pInSelSet As ISelectionSet
    Dim pOutSelSet As ISelectionSet


    'Get the feature class from the map
    Set pDoc = ThisDocument
    Set pMap = pDoc.FocusMap
    Set pFLayer = pMap.Layer(0)
    Set pFClass = pFLayer.FeatureClass

    'Get the relate from the feature layer
    Set pRelClassColl = pFLayer
    Set pEnumRelClass = pRelClassColl.RelationshipClasses
    Set pRelClass = pEnumRelClass.Next

    'Make sure relate was found uses first relate on first layer in the map
    If pRelClass Is Nothing Then
    MsgBox "No relate on this featureclass"
    Exit Sub
    End If

    'Get the standalone table from the map
    Set pStandtabcollection = pMap
    Set pStandAloneTable = New StandaloneTable
    Set pStandAloneTable = pStandtabcollection.StandaloneTable(0)
    Set pTable = pStandAloneTable.Table


    'Create a scratch workspace factory to use for the selection
    Dim pScratchWorkspace As IWorkspace
    Dim pScratchWorkspaceFactory As IScratchWorkspaceFactory
    Set pScratchWorkspaceFactory = New ScratchWorkspaceFactory
    Set pScratchWorkspace = pScratchWorkspaceFactory.DefaultScratchWorkspace

    'Create a query filter
    Set pQf = New QueryFilter
    pQf.WhereClause = "STATE_NAME = 'Oregon'"

    'Get the selection set
    'Set pInSelSet = pFClass.Select(pQf, esriSelectionTypeHybrid, esriSelectionOptionNormal, pScratchWorkspace)
    Set pInSelSet = pTable.Select(pQf, esriSelectionTypeHybrid, esriSelectionOptionNormal, Nothing)

    Debug.Print "Destination Class selection count is: " & pInSelSet.Count


    'Get the selection set from the related table
    Set pOutSelSet = GetRelSelection(pInSelSet, pFClass, pRelClass)

    Debug.Print "Origin Class selection count is: " & pOutSelSet.Count

    End Sub

    Private Function GetRelSelection(pFrSelSet As ISelectionSet, pToFClass As IFeatureClass, _
    pRelClass As IRelationshipClass) As ISelectionSet

    Dim pInSet As esriSystem.ISet
    Dim pOutSet As esriSystem.ISet
    Dim pCursor As ICursor
    Dim pRow As IRow
    Dim pOIDList() As Long
    Dim intOIDIndex As Integer
    Dim intCount As Integer
    Dim pOutSelSet As ISelectionSet
    Dim lngOID As Long

    ' Get the set of the selected rows
    Set pInSet = New esriSystem.Set
    pFrSelSet.Search Nothing, False, pCursor
    Set pRow = pCursor.NextRow

    Do While Not pRow Is Nothing
    pInSet.Add pRow
    'Debug.Print pRow.value(53)
    Set pRow = pCursor.NextRow
    Loop
    pInSet.Reset

    Debug.Print "Destination Class is: " & pRelClass.DestinationClass.AliasName
    Debug.Print "Origin Class is: " & pRelClass.OriginClass.AliasName
    'Debug.Print "pInSet Count is: " & pInSet.Count


    'Get the set of related rows and build an OID list
    Set pOutSet = pRelClass.GetObjectsRelatedToObjectSet(pInSet) 'Object Required Error here

    If pOutSet.Count <> 0 Then
    Set pRow = pOutSet.Next
    ReDim pOIDList(pOutSet.Count - 1)
    intOIDIndex = pRow.Fields.FindField(pToFClass.OIDFieldName)
    intCount = 0
    Do While Not pRow Is Nothing
    pOIDList(intCount) = pRow.value(intOIDIndex)
    Set pRow = pOutSet.Next
    intCount = intCount + 1
    Loop
    End If

    'Make a selectionset and add the OID's from the OID list
    Set pOutSelSet = pToFClass.Select(Nothing, esriSelectionTypeHybrid, _
    esriSelectionOptionEmpty, Nothing)
    If pOutSet.Count <> 0 Then
    For lngOID = 0 To pOutSet.Count - 1
    pOutSelSet.Add (pOIDList(lngOID))
    Next
    End If

    Set GetRelSelection = pOutSelSet

    End Function 

     

      Sample Two: Origin to Destination

    Private Sub GetSelection()

    Dim pDoc As IMxDocument
    Dim pMap As IMap
    Dim pFLayer As IFeatureLayer
    Dim pFClass As IFeatureClass
    Dim pRelClassColl As IRelationshipClassCollection
    Dim pRelClass As IRelationshipClass
    Dim pEnumRelClass As IEnumRelationshipClass
    Dim pStandAloneTable As IStandaloneTable
    Dim pStandtabcollection As IStandaloneTableCollection
    Dim pTable As ITable
    Dim pQf As IQueryFilter
    Dim pInSelSet As ISelectionSet
    Dim pOutSelSet As ISelectionSet

    'Get the feature class from the map
    Set pDoc = ThisDocument
    Set pMap = pDoc.FocusMap
    Set pFLayer = pMap.Layer(0)
    Set pFClass = pFLayer.FeatureClass

    'Get the relate from the feature layer
    Set pRelClassColl = pFLayer
    Set pEnumRelClass = pRelClassColl.RelationshipClasses
    Set pRelClass = pEnumRelClass.Next

    'Make sure relate was found uses first relate on first layer in the map
    If pRelClass Is Nothing Then
    MsgBox "No relate on this featureclass"
    Exit Sub
    End If

    'Get the standalone table form the map
    Set pStandtabcollection = pMap
    Set pStandAloneTable = New StandaloneTable
    Set pStandAloneTable = pStandtabcollection.StandaloneTable(0)
    Set pTable = pStandAloneTable.Table

    'Create a query filter
    Set pQf = New QueryFilter
    pQf.WhereClause = "STATE_NAME = 'Oregon'"

    'Get the selection set
    Set pInSelSet = pFClass.Select(pQf, esriSelectionTypeHybrid, esriSelectionOptionNormal, Nothing)

    'Get the selection set from the related table
    Set pOutSelSet = GetRelSelection(pInSelSet, pTable, pRelClass)

    Debug.Print pOutSelSet.Count

    End Sub


    Private Function GetRelSelection(pFrSelSet As ISelectionSet, pToTable As ITable, pRelClass As IRelationshipClass) As ISelectionSet

    Dim pInSet As ISet
    Dim pOutSet As ISet
    Dim pCursor As ICursor
    Dim pRow As IRow
    Dim pOIDList() As Long
    Dim intOIDIndex As Integer
    Dim intCount As Integer
    Dim pOutSelSet As ISelectionSet
    Dim lngOID As Long

    ' Get the set of the selected rows
    Set pInSet = New esriSystem.Set
    pFrSelSet.Search Nothing, False, pCursor
    Set pRow = pCursor.NextRow
    Do While Not pRow Is Nothing
    pInSet.Add pRow
    Set pRow = pCursor.NextRow
    Loop
    pInSet.Reset

    'Get the set of related rows and build an OID list
    Set pOutSet = pRelClass.GetObjectsRelatedToObjectSet(pInSet)
    If pOutSet.Count <> 0 Then
    Set pRow = pOutSet.Next
    ReDim pOIDList(pOutSet.Count - 1)
    intOIDIndex = pRow.Fields.FindField(pToTable.OIDFieldName)
    intCount = 0
    Do While Not pRow Is Nothing
    pOIDList(intCount) = pRow.value(intOIDIndex)
    Set pRow = pOutSet.Next
    intCount = intCount + 1
    Loop
    End If

    'Make a selectionset and add the OID's from the OID list
    Set pOutSelSet = pToTable.Select(Nothing, esriSelectionTypeHybrid, _
    esriSelectionOptionEmpty, Nothing)
    If pOutSet.Count <> 0 Then
    For lngOID = 0 To pOutSet.Count - 1
    pOutSelSet.Add (pOIDList(lngOID))
    Next
    End If

    Set GetRelSelection = pOutSelSet

    End Function

  • Is it possible to create a command that works with the Table of Contents in both an ArcGIS Desktop application and Engine?

    To create a custom command that will work with both ArcGIS engine and ArcGIS Desktop, use the HookHelper CoClass. The developer documentation for the HookHelper CoClass states; the HookHelper should be used "when the command is to support a variety of hook objects" and, "when creating a custom command the ICommand::OnCreate event is passed a hook to the control or application that the command will work with".

    The command needs to determine the type of hook that is passed so it knows how to handle itself. Rather than adding code into the ICommand::OnCreate event to determine the type of hook a HookHelper object can do this. The HookHelper is used to hold the hook and return the IActiveView, PageLayout or FocusMap regardless of whether the hook is a MapControl, PageLayoutControl, ToolbarControl (with a 'buddy' MapControl or PageLayoutControl), the ArcMap application or a custom control or application implementing ICommandHook."

    For an example of how to use the Hook Helper perform the following steps:

    1. Create a new .NET Engine application
    2. Right-click the project in the Solution Explorer and select Add > New Item.
    3. Select a new Universal Command from the ArcGIS New Item Wizard Options dialog.
    4. Expand the Overriden class methods then inspect the OnCreate event code to see how to use the HookHelper.

  • How to show directions in a different language in Network Analyst

    Recently we received a question from a customer in support asking if it was possible to change the language of the directions that are returned from a Network Analyst layer.  Though their question was specific to Engine, this solution could be applied to both Server and Desktop.  The language of the directions that are returned in Network Analyst comes form the "directions.lng" file which is located in the <ArcGIS install directory>NetworkAnalyst\Directions folder. Currently, this file contains directions only in English; however, we can edit the file to include direction strings for other languages.

    The first step of the process is to edit your "directions.lng" file appropriately to support the language that you want. Here are the steps to accomplish this task:

    1. Make a back-up copy of the "directions.lng" file (found in <ArcGIS install directory>NetworkAnalyst\Directions).
    2. Open "directions.lng" in a text editor (Notepad, for example).
    3. Copy all the text in the "English" section (from the line that reads";---English--" to the end of the file).
    4. Paste the text you copied to the end of the file.
    5. If you want to display directions in Thai for instance, modify the first couple of lines of the new section to indicate it's Thai, as shown below:

      ; ---------Thai------------
      [th_TH]
    6. Edit (translate) the new section to represent the Thai language settings. Unfortunately, we don't currently have any documentation on how to change these settings, so it might take some experimentation on your part. In general, things in upper case ('STOP_ARRIVAL', for example) are keywords and should not be edited. Text that appears in brackets ('[ at ]', e.g.) and text that is assigned directly to a variable ('ActionGo = go') is the text that should be translated. Remember that information like street names is going to be read from the route dataset.
    7. When you finished your editing, save the "directions.lng" file.

    The next step is to programmatically set which language to used for the directions when solving the route.

    1. Get the "StreetDirectionsAgents" from INAContext.
    2. Using the INAStreetDirectionsAgents2 interface, set the Language property using LCID defined your lng file. For instance:

      naStreetDirAgent.Language = "th_TH";
    3. Then you would call the INAStreetDirectionsAgent2.Execute passing the Routes to get the directions for your routes.  For more information on how to do this please see the following link here.

    A documentation enhancement request has been submitted to include documentation on how to change the language for Network Anaylst driving directions.  The tracking number for this enhancement is NIM010336. We should be seeing the documentation in 9.3.

    For more information on working with Network Analyst Check out the following links.

  • How can I use my custom command in Engine without using the ToolbarControl?

    In this post ESRI Support shows how to run a Command without using a ToolbarControl.

    To run your custom command, you would need to add a reference to your custom command in your project, create a new instance of the command, pass the control as the hook to the OnCreate method, and then execute the command. Below is a code snippet that uses the Print Active View sample from EDN.  This is a great sample because it demonstrates how to print from both a MapControl and a PageLayoutControl. We can simply build this project, then in our own Engine Application add a reference to the assembly (by browsing to the dll), and then use the following code to execute the Command.

    ICommand command = new PrintActiveViewCS_Net.PrintActiveViewCS_Net();
    //Pass the MapControl to the OnCreate method
    command.OnCreate(axMapControl1.Object);
    command.OnClick();

    The same thing can be done for tool.  We create a new instance of the tool and set it to the MapControl's current tool.

    ICommand command = new ControlsSelectFeaturesToolClass();
    command.OnCreate(axMapControl1.Object);
    axMapControl1.CurrentTool = (ITool) command;

    If you are using multiple commands at once, you can use the CommandPool object to manage these commands and then execute them one at a time. For example:

    ICommandPoolEdit commandPool = new CommandPoolClass();
    //create some commands
    ICommand printCom = new PrintActiveViewCS_Net.PrintActiveViewCS_Net();
    ICommand zoomCom = new ControlsMapZoomInFixedCommandClass();
    //add them to the command pool
    commandPool.AddCommand(zoomCom, null);
    commandPool.AddCommand(printCom, null);
    //or add by uid
    UID u = new UIDClass();
    u.Value = "{299BA806-0256-4E48-8661-5CEE31EB7077}";
    commandPool.AddCommand(null, u);
    ICommandPool cp = commandPool as ICommandPool;
    ICommand command = cp.get_Command(0);
    //pass the MapControl to the oncreate method
    command.OnCreate(axMapControl1.Object);
    //run the tool
    command.OnClick();

    You can find more information on how to use Commands in ArcGIS Engine on EDN here:

  • ArcGIS Engine Licensing Tips and Tricks

    In this post ESRI Support addresses a few common issues when working with licensing in ArcGIS Engine

    When working with an ArcGIS Engine application, the number of map controls (or other controls) in the same application does not make a difference in terms of licensing. The license is initialized for the application, not the individual controls. There are two options for licensing an Engine application: Add the license control to your application and then check the appropriate license levels required by your application in the license control properties, or programmatically handle the license initialization. If you choose to use the programmatic option, you should initialize the license in your code before making use of any ArcObjects components. This would be either in the Form_Load procedure or Sub Main(). Use the IAoInitialize interface to initialize the license, something like this:

    Private m_pAoInitialize As IAoInitialize
    m_pAoInitialize = New AoInitialize
    m_pAoInitialize.Initialize esriLicenseProductCodeEngineGeoDB

    If you are attempting to initialize a license and are getting errors that the application is not licensed, there may be a problem with the license file itself. Specifically, the license may have expired, or it does not contain the necessary components to authorize specific functionality your application requires. To verify what level of software authorization your machine has, run the "Authorization Summary" tool, typically available on most machines by selecting 'Start > Programs > ArcGIS > AuthorizationSummary'.

    For more detailed information on licensing ArcGIS Engine applications, please see the developer documentation for “Building solutions with ArcGIS Engine using .NET" either on the ESRI Developer Network (EDN) web site or in the ".NET Help for VS2005" on your local machine. To locate this help topic on your local machine, select 'Start > Programs > ArcGIS > Developer Help > .NET Help for VS2005'; activate the "Contents" tab, and see the heading "Building solutions with ArcGIS Engine using .NET". This section contains detailed information on licensing custom applications.

    Or you may also find the same and related information on the following links on the EDN web site:

  • Developers' Road Map to ArcGIS Engine

    Rob Elkins, ESRI's product manager for ArcGIS Engine led a "road map" session at this year's Developer Summit conference.  The Flash video can be found here and lasts about one hour.   Some of the initial info pertains to the conference itself, but the bulk of it is a good overview of what ArcGIS Engine developers can do and will be able to do with this toolkit.   Since the components inside ArcGIS Desktop and ArcGIS Explorer are so similar, those products are covered also.

     

     

  • 2008 Developer Summit Content on the Way

    The third annual ESRI Developer Summit conference is now behind us, and all indications are that it was a great success.  For those of you who attended, we all hope you found it productive and helpful as you return and continue getting more and more from ESRI technologies, and ArcGIS Engine in particular.  And whether you attended or not, we are gradually rolling out all of the presentation slides, code samples, demos, and screen cast video.   Many of the slides are up now, and we expect the rest of the content out over the next week or so.

    Stop by the EDN website's Conferences tab to get to the session content you're looking for.

     

  • ArcGIS Desktop and Engine Sessions at the Developer Summit

    Welcome to the new ArcGIS Engine Development Blog. 

    If you are attending the Developer Summit 2008 next week, here is a list of the sessions you might be interested in if you are a Desktop or Engine developer.


    Session Types
    Pre-Summit Seminar Day/Time Room

    Introduction to ArcGIS Desktop and ArcGIS Engine Development

    Mon 1:00pm Mojave Learning Center (Wyndham Hotel)
    -------------------- ----------- ------
    Technical Session Day/Time Room
    Developers Road Map to ArcGIS Desktop and ArcGIS Engine Tue 11:00am Primrose B (Palm Springs Convention Center)
    Developers Road Map to ArcGIS Desktop and ArcGIS Engine Tue 1:00pm Primrose C/D (Palm Springs Convention Center)
    Developing .NET Applications for ArcGIS Engine Tue 2:45pm Primrose C/D (Palm Springs Convention Center)
    Developing Java Applications for ArcGIS Engine Tue 2:45pm Smoketree A - E (Palm Springs Convention Center)
    Moving Desktop Applications to ArcGIS Server Tue 2:45pm Primrose B (Palm Springs Convention Center)
    Deploying Desktop Applications Tue 4:30pm Primrose C/D (Palm Springs Convention Center)
    Developing Desktop Applications with the Geoprocessing Framework Wed 10:30am Pasadena/Ventura/Sierra (Wyndham Hotel)

     

    Extending the ArcGIS Desktop Applications
    Wed 10:30am Catalina/Madera (Wyndham Hotel)

     

    Deploying Desktop Applications
    Wed 1:00pm Pasadena/Ventura/Sierra (Wyndham Hotel)

     

    Extending the ArcGIS Desktop Applications
    Wed 2:45pm Smoketree A - E (Palm Springs Convention Center)

     

    Moving Desktop Applications to ArcGIS Server
    Wed 2:45pm Primrose A (Palm Springs Convention Center)