Example: Image-Contour Visualization

This example creates a visualization type named example1_visImageContour that displays an image and overlays it with a contour based on the image data.

Example Code
The code for this example visualization type is included in the file example1_visimagecontour__define.pro in the examples/doc/itools subdirectory of the IDL distribution. Run the example procedure by entering example1_visimagecontour__define at the IDL command prompt or view the file in an IDL Editor window by entering .EDIT example1_visimagecontour__define.pro.

Class Definition File

The class definition for example1_visImageContour consists of an Init method, an OnDataChangeUpdate method, and a class structure definition routine. Other important methods — Cleanup, GetProperty, and SetProperty — are handled by the superclass (IDLitVisualization).

As with all object class definition files, the class structure definition routine is the last routine in the file, and the file is given the same name as the class definition routine (with the suffix .pro appended).

Class Definition

PRO example1_visImageContour__define 
   struct = { example1_visImageContour, $ 
      inherits IDLitVisualization, $ 
      _oContour: OBJ_NEW(), $ 
      _oImage: OBJ_NEW() $ 
   } 
END 

Discussion

Our class definition routine creates an IDL structure variable with the name example1_visImageContour, specifying that the structure inherits from the IDLitVisualization class. The structure has two instance data fields named _oContour and _oImage, which will contain object references to the IDLitVisImage and IDLitVisContour objects that make up the example1_visImageContour visualization.

Init Method

The Init method is called when the example1_visImageContour visualization is created.

FUNCTION example1_visImageContour::Init, _REF_EXTRA = _extra 
 
   ; Initialize the superclass 
   IF (~self->IDLitVisualization::Init($ 
      NAME='example1_visImageContour', $ 
      ICON = 'image', _EXTRA = _extra)) THEN RETURN, 0 
 
   ; Register the parameters we are using for data 
   self->RegisterParameter, 'IMAGEPIXELS', $ 
      DESCRIPTION = 'Image Data', /INPUT, $ 
      TYPES = ['IDLIMAGEPIXELS', 'IDLARRAY2D'], /OPTARGET 
   self->RegisterParameter, 'PALETTE', $ 
      DESCRIPTION = 'Palette', /INPUT, /OPTIONAL, $ 
      TYPES = ['IDLPALETTE','IDLARRAY2D'], /OPTARGET 
 
   ; Create objects and add to this Visualization 
   self._oImage = OBJ_NEW('IDLitVisImage', /PRIVATE) 
   self->Add, self._oImage, /AGGREGATE 
   self._oContour = OBJ_NEW('IDLitVisContour', /PRIVATE) 
   self->Add, self._oContour, /AGGREGATE 
 
   ; Return success 
   RETURN, 1 
 
END 

Discussion

The first item in our class definition file is the Init method. The Init method's function signature is defined first, using the class name example1_visImageContour. Note the use of the _REF_EXTRA keyword inheritance mechanism; this allows any keywords specified in a call to the Init method to be passed through to routines that are called within the Init method even if we do not know the names of those keywords in advance.

First, we call the Init method of the superclass. In this case, we are creating a subclass of the IDLitVisualization class; this provides us with all of the standard iTool visualization methods automatically. Any "extra" keywords specified in the call to our Init method are passed to the IDLitVisualization::Init method via the keyword inheritance mechanism. If the call to the superclass Init method fails, we return immediately with a value of 0.

We register two parameters used by our visualization: IMAGEPIXELS and PALETTE. Both parameters are input parameters (meaning they are used to create the visualization), and both can be the target of an operation. The IMAGEPIXELS parameter can contain data of two iTool data types: IDLIMAGEPIXELS or IDLARRAY2D. When data are assigned to the visualization's parameter set, only data that matches one of these two types can be assigned to the IMAGEPIXELS parameter. Similarly, the PALETTE parameter can contain data of type IDLPALETTE or IDLARRAY2D.

Next, we create the two visualization components that make up the example1_visImageContour visualization type: an IDLitVisImage object and an IDLitVisContour object. Each object is created by a call to the OBJ_NEW function; the newly-created object reference is placed in a field of the example1_visImageContour object's instance data structure. We set the PRIVATE property to prevent the IDLitVisImage and IDLitVisContour objects from showing up in the visualization browser as separate items. The new visualization objects are then added to the example1_visImageContour object using the Add method; the AGGREGATE keyword specifies that the properties of each of the component visualization objects will be displayed as properties of the example1_visImageContour object itself.

Finally, we return 1, indicating a successful initialization.

OnDataChangeUpdate Method

The OnDataChangeUpdate method is called whenever the data associated with the example1_visImageContour visualization object changes. This may include the initial creation of the visualization, if data parameters are specified in the call to the iTool launch routine that creates the visualization.

PRO example1_visImageContour::OnDataChangeUpdate, oSubject, $ 
   parmName,    _REF_EXTRA = _extra 
 
   ; Branch based on the value of the parmName string. 
   CASE STRUPCASE(parmName) OF 
 
      ; The method was called with a paramter set as the argument. 
      '<PARAMETER SET>': BEGIN 
      oParams = oSubject->Get(/ALL, COUNT = nParam, $ 
         NAME = paramNames) 
         FOR i = 0, nParam-1 DO BEGIN 
            IF (paramNames[i] EQ '') THEN CONTINUE 
            oData = oSubject->GetByName(paramNames[i]) 
            IF (OBJ_VALID(oData)) THEN $ 
              self->OnDataChangeUpdate, oData, paramNames[i] 
        ENDFOR 
      END 
 
      ; The method was called with an image array as the argument. 
      'IMAGEPIXELS': BEGIN 
      void = self._oImage->SetData(oSubject, $ 
         PARAMETER_NAME = 'IMAGEPIXELS') 
      void = self._oContour->SetData(oSubject, $ 
         PARAMETER_NAME = 'Z') 
      ; Make our contour appear at the top of the surface. 
      IF (oSubject->GetData(zdata)) THEN $ 
         self._oContour->SetProperty, ZVALUE = MAX(zdata) 
      END 
 
      ; The method was called with a palette as the argument. 
      'PALETTE': BEGIN 
      void = self._oImage->SetData(oSubject, $ 
         PARAMETER_NAME = 'PALETTE') 
      void = self._oContour->SetData(oSubject, $ 
         PARAMETER_NAME = 'PALETTE') 
      END 
 
      ELSE: ; DO nothing 
 
   ENDCASE 
 
END 

Discussion

The OnDataChangeUpdate method accepts the two required arguments: an object reference to the data object whose data has changed (oSubject), and a string containing the name of the parameter associated with the data object (parmName).

We use a CASE statement to determine which parameter has been modified, and process the data as appropriate. We first handle the special case where the parameter has the value <PARAMETER SET> by looping through all of the parameters in the parameter set object, calling the OnDataChangeUpdate method again on each parameter.

We handle the IMAGEPIXELS parameter by calling the IDLitParameter::SetData method once on each of the two component visualizations, specifying that the input data object oSubject corresponds to the IMAGEPIXELS parameter of the IDLitVisImage object, and to the Z parameter of the IDLitVisContour object. We also set the Z value of the IDLitVisContour object using the maximum data value of the data contained in oSubject.

Finally, we handle the PALETTE parameter by calling the SetData method again, this time to set the PALETTE parameters of both the IDLitVisImage and IDLitVisContour objects.

OnDataDisconnect Method

The OnDataDisconnect method is called automatically when a data value has been disconnected from a parameter.

PRO example1_visImageContour::OnDataDisconnect, ParmName 
 
CASE STRUPCASE(parmname) OF 
 
   'IMAGEPIXELS': BEGIN 
      self->SetProperty, DATA = 0 
      self._oImage->SetProperty, /HIDE 
      self._oContour->SetProperty, /HIDE 
   END 
 
   'PALETTE': BEGIN 
      self._oImage->SetProperty, PALETTE = OBJ_NEW() 
      self->SetPropertyAttribute, 'PALETTE', SENSITIVE = 0 
   END 
 
   ELSE: ; DO nothing 
 ENDCASE 
 
END 

Discussion

The OnDataDisconnect method takes a single argument, which contains the name of the parameter that was disconnected. In the case of our example1_visImageContour visualization, we handle the IMAGEPIXELS and PALETTE parameters. For the IMAGEPIXELS parameter, we set the DATA property of the parameter to 0, and hide both the image and the contour visualizations. For the PALETTE parameter, we set the PALETTE property of the image to a null object, and desensitize the property in the property sheet display.