A Simple GISDK Demo

This is a simple demonstration of the GISDK macro language that is supplied with Caliper Maptitude. It lets the user select a layer from the current map and then deletes all of the layer’s selection sets (except the default ‘Selection‘). It demonstrates the use of GISDK command structures, API, and a custom dialog box.

The source code can be downloaded here. This is a compressed RSC file and is distributed under the Modified BSD license. You will need to un-compress it before compiling the RSC file. Enable the GISDK Toolbox in Maptitude by selecting GIS Developer’s Kit on the Tools menu. Compile the RSC file by pressing the Compile button (page with green arrow) on the toolbox. You may then test the macro by pressing the Test button (page with magnifying glass). For regular use, the macro can be compiled into a GUI database, although you will probably wish to add a menu item or button.

The GISDK macro language is a variation on ‘modern’ structured basic. It has modern control structures instead of line numbers, and supports some object oriented features.

The code is divided into two chunks. The first is the delsets macro. This performs the actual delete operation, but also calls the get choice dialog box, which is the second chunk.

We will start with the second chunk, the dialog box. Maptitude does not have a visual editor, therefore the dialog box is defined in text. This includes the controls, their positions, and their callback events:

// Create a dialog box to display the available layers
DBox "get choice" (layer_list)  Title: "Choose a Layer"
    // Displays the layer_list array of strings; requires the
    // user to choose one and click OK.  Returns the selected layer
    // name for OK or null if Cancel is clicked.
    
    Init do    
        // disable the OK button to start; enable it when a line
        // in the scroll list is chosen.
        DisableItem("OK")
    
    endItem
    
    // Add a title for the scroll list.
    Text "Layer Name" 1, 0
    
    // Display the formatted array; the keyword "multiple" is not
    // used, so only one choice will be possible.  The lyr_idx
    // variable will contain the index (subscript) of the selected
    // layer
    Scroll List 1, 1, 40, 15 List: layer_list Variable: lyr_idx
    do
            // When user makes a choice, enable the OK button.
            EnableItem("OK")
    endItem

    // Add an OK button. The Default keyword allows the user to press Enter.
    Button "OK" 21, 17, 7, 1 Default
        Do
            // Return the chosen element
        return( layer_list[lyr_idx] )
    endItem

    // Add a Cancel button. The Cancel keyword allows the user to press Esc.
    Button "Cancel" 31, same, 7, 1 Cancel
        Do
            // Return null if user cancels
            return()
        endItem

EndDBox

The dialog box is defined by the DBox statemeent. This lists the parameters (an array: layer_list) and the dialog box’s title. Event clauses are surrounded by Do … endItem. The first is the initializer, which in this case disables the OK button. The remainder define callback events for each of the controls.

Most of these controls should be self explanatory. Scroll List defines a list box with a vertical scroll bar. This lists the contents of layer_list and returns the selected item in lyr_idx as an index in this array. When the user makes a selection, the Do clause enables the OK button.

The remaining callbacks are for the two buttons. Note that the OK button’s callback does not return the selected index. Instead, it returns the actual selected layer name. Also, the Cancel button returns null to indicate no selection.

Here is the actual delsets macro:

Macro "delsets"
    // Fetch all of the layer names as an array of strings
    lyrnames = GetLayerNames()
    
    // Pass the layer names to the "get choice" dialog box
    // This is defined below and lets the user select a layer
    layer = RunDbox("get choice", lyrnames)

    if layer = null then return()

    result = MessageBox("Do you want to delete the selection sets on layer " + layer + "?", 
	               { {"Caption","Confirmation delete"}, 
                         {"Buttons", "YesNo"} } )

    if result = "No" then return()

    // Set the view to the layer that we are going to work with
    // But first, save the old view so we can restore it when finished
    curr_view = GetView()
    SetView(layer)

    // Fetch the list of selection sets for this layer/view
    list_of_sets = GetSets(layer)

    // Loop over the selection sets, deleting all sets
    // which are not 'Selection'
    // Note: DeleteSet only works
    // Look through the record handles array.
    for i = 1 to list_of_sets.length do

        if list_of_sets[i] <> "Selection" then do
           DeleteSet( list_of_sets[i] )
        end

    end  // end of selection sets loop

    // Restore the view back to the original view before finishing
    SetView(curr_view)

endMacro

Starting at the top, this macro calls the API function GetLayerNames() to fetch an array listing all of the layers on the current map.  This is then passed to the get choice dialog box that we have just defined, using the RunDbox command. This returns the selected layer name, or null if the user cancelled the operation. An if clause catches this latter situation.

A call to the API function, MessageBox(), is used to confirm that the user wishes to delete these selection sets. This is very similar to the VB6 MsgBox function.

After confirmation, we retrieve a list of the selection sets to delete. In order to do this, the Maptitude API requires that we set the current view to the layer. Hence we save the original view to curr_view. When we finish, we will reset the current view back to curr_view.

GetSets() is used to retrieve the selection sets. A for loop is used to loop over them and delete them by name. We delete all selection sets that are not named “Selection” (the default selection set).

Maptitude supports about half a dozen different variations of the if statement, and we have used two of them here. The first two are inline statements that only have one conditional line and no else clause. This form could have been used in the loop, but the if … then do … end version was used instead. This can be used to include multiple statements in the conditional block.

And that is it. This is a simple example that duplicates functionality that is already available in the GUI, but it demonstrates the definition of a custom dialog box, and hints at the richness of the Maptitude API.