15180
ENVI: Adding custom polygons to the display
A recent project I worked on required custom polygons –
Controlled by my application – to be added to the ENVI display. The following
code defines an object class that allows the user to place a polygon in the ENVI
display using window coordinates. To run the application:
- Save
the code that follows to a file named envi_polygon_example.pro
- Open
and compile the file in the IDLDE
- Execute
the following at the IDL command prompt
envi_polygon_example
;------------------------------------------------------------------------------
;+
; Lifecycle method for destroying the object
;-
pro my_polygon::Cleanup
compile_opt idl2, logical_predicate
self->Destruct
end
;------------------------------------------------------------------------------
;+
; Cleans up the member variables of the object class
;-
pro my_polygon::Destruct
compile_opt idl2, logical_predicate
self->IDLmiManipGraphicOverlay::Cleanup
self->IDLmiManipLayer::Cleanup
self->IDLgrPolygon::Cleanup
end
;------------------------------------------------------------------------------
;+
; Lifecycle method for initializing the class
;
; :Returns:
; 1 if the object initializes successfully and 0 otherwise
;
; :Params:
; xy: in, optional, type="int"
; a [2,n] array containing the [x,y] points in window
coordinates
;
; :Keywords:
; POLYGONS: in, optional, type="int"
; An integer array of one or more polygon descriptions. See
IDL help for
; IDLgrPolygon for more information
; _REF_EXTRA: Used to set properties of the inherited
IDLgrPolygon
;-
function my_polygon::Init, xy, $
POLYGONS=poly, $
_REF_EXTRA=refExtra
compile_opt idl2, logical_predicate
void = self->IDLmiManipGraphicOverlay::Init(_EXTRA=refExtra)
if ~void then begin
return, 0
endif
self->InitializeDataspace
self->SetupManipulatorGraphics
self->InitializeGraphics
if n_elements(xy) then begin
self->SetProperty, DATA=xy, POLYGONS=poly
endif
if n_elements(refExtra) then begin
self->SetProperty, _EXTRA=refExtra
endif
return, 1
end
;------------------------------------------------------------------------------
;+
; This method initializes the data space used by the graphics
layer
;-
pro my_polygon::InitializeDataspace
compile_opt idl2, logical_predicate
e = envi(/CURRENT)
eView = e->GetView()
eView->GetProperty, _COMPONENT=ecfViewGroup
oDS = ecfViewGroup->GetDescendants(BY_TYPE='DATASPACE', /FIRST_ONLY)
self._oTargetDS = oDS
end
;------------------------------------------------------------------------------
;+
; Initializes the graphics components of the class
;-
pro my_polygon::InitializeGraphics
compile_opt idl2, logical_predicate
void = self->IDLgrPolygon::Init(COLOR=[255,0,0], /PRIVATE, THICK=2)
self._oGrOverlay->IDLmiContainer::Add, self
end
;------------------------------------------------------------------------------
;+
; This method is for setting class properties
;-
pro my_polygon::SetProperty, $
DATA=data, $
POLYGONS=poly, $
_REF_EXTRA=refExtra
compile_opt idl2, logical_predicate
if n_elements(data) then begin
self->SetData, data, POLYGONS=poly
endif
if n_elements(refExtra) then begin
self->IDLgrPolygon::SetProperty, _EXTRA=refExtra
self->IDLmiManipLayer::SetProperty, _EXTRA=refExtra
endif
end
;------------------------------------------------------------------------------
;+
; This method maps the points from window coordinates to map
coordinates and
; adds the mapped points to the IDLgrPolygon.
;
; :Params:
; xy: in, required, type="int"
; A [2,n] array of points (In window coordinates) to be
added to the polygon
;
; :Keywords:
; POLYGONS: in, optional, type="int"
; An integer array of one or more polygon descriptions. See
IDL help for
; IDLgrPolygon for more information
;-
pro my_polygon::SetData, xy, $
POLYGONS=poly
compile_opt idl2, logical_predicate
self._oTargetDS->WindowToVis, reform(xy[0,*]), reform(xy[1,*]), xVis, yVis
self->IDLgrPolygon::SetProperty, DATA=transpose([[xVis],[yVis]]), $
POLYGONS=poly
end
;------------------------------------------------------------------------------
;+
; Class structure definition
;-
pro my_polygon__define
compile_opt idl2, logical_predicate
void = {my_polygon $
, inherits IDLmiManipGraphicOverlay $
, inherits IDLmiManipLayer $
, inherits IDLgrPolygon $
}
end
;------------------------------------------------------------------------------
;+
;-
pro envi_polygon_example
compile_opt idl2, logical_predicate
e = envi(/CURRENT)
if ~isa(e, 'envi') then begin
e = envi()
endif
file = FILEPATH('qb_boulder_msi', ROOT_DIR=e.ROOT_DIR, SUBDIRECTORY=['data'])
eRaster = e->OpenRaster(file)
eView = e->GetView()
eLayer = eView->CreateLayer(eRaster)
xy = [[470,140],[560,140],[560,230],[470,230], $
[750,115],[1200,115],[1200,665],[750,665]]
conn = [4,0,1,2,3,4,4,5,6,7]
oPolygon = obj_new('my_polygon', xy, LINESTYLE=5, POLYGONS=conn,
STYLE=1)
end