; docformat = 'rst' ; ; NAME: ; cgMapGrid ; ; PURPOSE: ; This object is a wrapper for the cgMap_Grid routine in IDL. It provides a simple ; way to allow map grids on images which use a cgMAP object to set up the map ; projection space. A map coordinate space must be in effect at the time the ; Draw method of this object is used. ; ;******************************************************************************************; ; ; ; Copyright (c) 2011, by Fanning Software Consulting, Inc. All rights reserved. ; ; ; ; Redistribution and use in source and binary forms, with or without ; ; modification, are permitted provided that the following conditions are met: ; ; ; ; * Redistributions of source code must retain the above copyright ; ; notice, this list of conditions and the following disclaimer. ; ; * Redistributions in binary form must reproduce the above copyright ; ; notice, this list of conditions and the following disclaimer in the ; ; documentation and/or other materials provided with the distribution. ; ; * Neither the name of Fanning Software Consulting, Inc. nor the names of its ; ; contributors may be used to endorse or promote products derived from this ; ; software without specific prior written permission. ; ; ; ; THIS SOFTWARE IS PROVIDED BY FANNING SOFTWARE CONSULTING, INC. ''AS IS'' AND ANY ; ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ; ; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT ; ; SHALL FANNING SOFTWARE CONSULTING, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, ; ; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ; ; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ; ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ; ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ; ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ;******************************************************************************************; ; ;+-------------------------------------------------------------------------- ; This object is a wrapper for the cgMap_Grid routine in IDL. It provides a simple ; way to allow map grids on images which use a cgMAP object to set up the map ; projection space. A map coordinate space must be in effect at the time the ; Draw method of this object is used. ; ; :Categories: ; Graphics, Map Projections ; ; :Author: ; FANNING SOFTWARE CONSULTING:: ; David W. Fanning ; 1645 Sheely Drive ; Fort Collins, CO 80526 USA ; Phone: 970-221-0438 ; E-mail: david@idlcoyote.com ; Coyote's Guide to IDL Programming: http://www.idlcoyote.com ; ; :History: ; Change History:: ; Written by David W. Fanning, 7 November 2011. ; Modified AutoDrawGrid method to update, better-working method in cgMap_Grid. 28 Dec 2011. DWF. ; ; :Copyright: ; Copyright (c) 2011, Fanning Software Consulting, Inc. ;--------------------------------------------------------------------------- ;+-------------------------------------------------------------------------- ; The initialization method for the object. ; ; :Params: ; mapCoord: in, required, type=object ; A map coordinate object that will set up a map coordinate data space. ; Required to convert lat/lon values to projected meter space. A cgMap object. ; ; :Keywords: ; addcmd: in, optional, type=boolean, default=0 ; If this keyword is set, the object is added to the resizeable graphics ; window, cgWindow. The DRAW method of the object is called in cgWindow. ; autodrawgrid: in, optional, type=boolean, default=0 ; If this keyword is set, the grid latitude and longitude values ; are automatically calculated from the mapCoord object ranges and drawn ; appropriately. Most keywords are ignored when auto drawing the grid. ; bcolor: optional, type=string, default='opposite' ; The name of the color to draw box axes with. ; box_axes: in, optional, type=boolean, default=0 ; Set this keyword to draw a box-style axes around the map. ; charsize: in, optional, type=float, default=1.0 ; Set this keyword to the size of characters used for the labels. ; clip_text: in, optional, type=boolean, default=1 ; Set this keyword to a zero value to turn off clipping of text labels. ; By default, text labels are clipped. This keyword is ignored if the ; BOX_AXES keyword is set. ; color: in, optional, type=string, default="opposite" ; The name of the color to draw the grid lines in. ; fill_horizon: in, optional, type=boolean, default=0 ; Set this keyword to fill the current map horizon. ; format: in, optional, type=string ; Set this keyword to a string format for formatting the grid ; labels (e.g., '(F0.2)') ; fuzzy: in, optional, type=float, default=0.0 ; This keyword applies only if the MAP_STRUCTURE keyword is used. Set the ; keyword to a value that is a percentage of the current data range. ; This percentage of the range is added to or subtracted from the ; values used to determine if the label is "inside" the boundary. ; It allows you to be a little less exact when selecting inside ; points. There are occasional aesthetic reasons for allowing fuzzy ; boundaries. A reasonable value for fuzziness might be 0.0125. ; horizon: in, optional, type=boolean, default=0 ; Set this keyword to draw the current map horizon. ; increment: in, optional, type=float ; Set this keyword to the spacing between the graticle points. ; label: in, optional, type=integer, default=1 ; Set this keyword to an integer, n, that labels every n parallels and meridians. ; For example, LABEL=3 will label every 3rd line. Default is 1. ; latalign: in, optional, type=float, default=0.5 ; This keyword controls the alignment of the text baseline for latitude ; labels. A value of 0.0 left justifies the label, 1.0 right justifies ; it, and 0.5 centers it. This keyword is ignored if the BOX_AXES keyword is set. ; latdel: in, optional, type=float ; Set this keyword equal to the spacing (in degrees) between parallels of ; latitude in the grid. If this keyword is not set, a default value of 5 is used. ; latlab: in, optional, type=float ; The longitude at which to place latitude labels. The default is the center ; longitude on the map. This keyword is ignored if the BOX_AXES keyword is set. ; latnames: in, optional, type=varies ; Set this keyword equal to an array specifying the names to be used for the ; latitude labels. By default, this array is automatically generated in units ; of degrees. The LATNAMES array can be either type string or any single numeric ; type, but should not be of mixed type.When LATNAMES is specified, the LATS ; keyword must also be specified. ; lats: in, optional, type=float ; Set this keyword equal to a one or more element vector of latitudes for which ; lines will be drawn (and optionally labeled). If LATS is omitted, appropriate ; latitudes will be generated based on the value of the (optional) LATDEL keyword. ; If LATS is set to a single value, that latitude and a series of automatically ; generated latitudes will be drawn (and optionally labeled). ; lcolor: in, optional, type=string ; Set this to the name of the label color to use in labeling grid lines. ; By default, the same as COLOR, or if BOX_AXIS is set, then same as BCOLOR. ; linestyle: in, optional, type=integer, default=1 ; Set this keyword to the type of linestyle desired. See Graphics Keywords in ; the on-line help for additional information. ; lonalign: in, optional, type=float, default=0.5 ; This keyword controls the alignment of the text baseline for longitude ; labels. A value of 0.0 left justifies the label, 1.0 right justifies ; it, and 0.5 centers it. This keyword is ignored if the BOX_AXES keyword is set. ; londel: in, optional, type=integer, default=10 ; Set this keyword equal to the spacing (in degrees) between parallels of ; longitude in the grid. If this keyword is not set, a default value of 10 is used. ; lonlab: in, optional, type=float ; The latitude at which to place longitude labels. The default is the center ; latitude on the map. This keyword is ignored if the BOX_AXES keyword is set. ; lonnames: in, optional, type=varies ; Set this keyword equal to an array specifying the names to be used for the ; longitude labels. By default, this array is automatically generated in units ; of degrees. The LONNAMES array can be either type string or any single numeric ; type, but should not be of mixed type.When LONNAMES is specified, the LONS ; keyword must also be specified. ; lons: in, optional, type=float ; Set this keyword equal to a one or more element vector of longitudes for which ; lines will be drawn (and optionally labeled). If LONS is omitted, appropriate ; longitudes will be generated based on the value of the (optional) LONDEL keyword. ; If LONS is set to a single value, that longitudes and a series of automatically ; generated longitudes will be drawn (and optionally labeled). ; thick: in, optional, type=integer, default=1 ; Set this keyword to the thickness of the line used to draw the grid. ; ;--------------------------------------------------------------------------- FUNCTION cgMapGrid::INIT, mapCoord, $ ADDCMD=addcmd, $ AUTODRAWGRID=autodrawgrid, $ BCOLOR=bcolor, $ BOX_AXES=box_axes, $ CLIP_TEXT=clip_text, $ CHARSIZE=charsize, $ COLOR=color, $ FILL_HORIZON=fill_horizon, $ FORMAT=format, $ FUZZY=fuzzy, $ LINESTYLE=linestyle, $ HORIZON=horizon, $ INCREMENT=increment, $ LABEL=label, $ LATALIGN=latalign, $ LATDEL=latdel, $ LATLAB=latlab, $ LATNAMES=latnames, $ LATS=lats, $ LCOLOR=lcolor, $ LONALIGN=lonalign, $ LONDEL=londel, $ LONLAB=lonlab, $ LONNAMES=lonnames, $ LONS=lons, $ THICK=thick, $ _EXTRA=extra ; Error handling Catch, theError IF theError NE 0 THEN BEGIN Catch, /Cancel void = cgErrorMsg() RETURN, 0 ENDIF ; Initialize superclass object, ok = self -> cgContainer::INIT(_EXTRA=extra) IF ~ok THEN RETURN, 0 ; Default values. self._cg_autodrawgrid = Keyword_Set(autodrawgrid) self._cg_box_axes = Keyword_Set(box_axes) IF N_Elements(format) NE 0 THEN self._cg_format = format self._cg_fill_horizon = Keyword_Set(fill_horizon) self._cg_horizon = Keyword_Set(horizon) SetDefaultValue, clip_text, 1 IF N_Elements(charsize) EQ 0 THEN $ ;charsize = (StrUpCase(!Version.OS_Family) EQ 'WINDOWS') ? 0.75 : 1.0 charsize = cgDefCharsize() * 0.75 SetDefaultValue, bcolor, 'opposite' SetDefaultValue, color, 'opposite' IF N_Elements(lcolor) EQ 0 THEN lcolor = Keyword_Set(box_axes) ? bcolor : color SetDefaultValue, fuzzy, 0.0 SetDefaultValue, label, 1 SetDefaultValue, linestyle, 1 SetDefaultValue, latalign, 0.5 SetDefaultValue, latdel, 5.0 SetDefaultValue, lonalign, 0.5 SetDefaultValue, londel, 10.0 SetDefaultValue, thick, 1.0 self._cg_bcolor = bcolor self._cg_clip_text = clip_text self._cg_charsize = charsize self._cg_color = color self._cg_label = label self._cg_latalign = latalign self._cg_lcolor = lcolor self._cg_lonalign = lonalign self._cg_linestyle = linestyle self._cg_thick = thick ; Initialize all program pointers. IF N_Elements(increment) EQ 0 $ THEN self._cg_increment = Ptr_New(/ALLOCATE_HEAP) $ ELSE self._cg_increment = Ptr_New(increment) IF N_Elements(latdel) EQ 0 $ THEN self._cg_latdel = Ptr_New(/ALLOCATE_HEAP) $ ELSE self._cg_latdel = Ptr_New(latdel) IF N_Elements(londel) EQ 0 $ THEN self._cg_londel = Ptr_New(/ALLOCATE_HEAP) $ ELSE self._cg_londel = Ptr_New(londel) IF N_Elements(latlab) EQ 0 $ THEN self._cg_latlab = Ptr_New(/ALLOCATE_HEAP) $ ELSE self._cg_latlab = Ptr_New(latlab) IF N_Elements(lonlab) EQ 0 $ THEN self._cg_lonlab = Ptr_New(/ALLOCATE_HEAP) $ ELSE self._cg_lonlab = Ptr_New(lonlab) IF N_Elements(latnames) EQ 0 $ THEN self._cg_latnames = Ptr_New(/ALLOCATE_HEAP) $ ELSE self._cg_latnames = Ptr_New(latnames) IF N_Elements(lonnames) EQ 0 $ THEN self._cg_lonnames = Ptr_New(/ALLOCATE_HEAP) $ ELSE self._cg_lonnames = Ptr_New(lonnames) IF N_Elements(lats) EQ 0 $ THEN self._cg_lats = Ptr_New(/ALLOCATE_HEAP) $ ELSE self._cg_lats = Ptr_New(lats) IF N_Elements(lons) EQ 0 $ THEN self._cg_lons = Ptr_New(/ALLOCATE_HEAP) $ ELSE self._cg_lons = Ptr_New(lons) ; Make sure you have a valid mapCoord object. IF Obj_Valid(mapCoord) $ THEN self._cg_map_object = mapCoord $ ELSE Message, 'A valid map object is required to create a cgMapGrid object.' ; Need to add this command to a resizeable cgWindow? IF Keyword_Set(addcmd) THEN self -> AddCmd RETURN, 1 END ;+-------------------------------------------------------------------------- ; Adds the object as a command (the DRAW method is called) in a cgWindow ; resizeable graphics window. ; ;--------------------------------------------------------------------------- PRO cgMapGrid::AddCmd cgWindow, "Draw", self, /Method, /AddCmd END ;+-------------------------------------------------------------------------- ; Calculates suitable latitude and longitude lines that run through the ; map range and suggests a default position for labeling such lines. ; ; :Keywords: ; success: out, optional, type=boolean ; Will be set to 1 on return, if the operation was successful. Otherwise, ; this value is set to 0. ;--------------------------------------------------------------------------- PRO cgMapGrid::AutoDrawGrid, SUCCESS=success ; Error handling Catch, theError IF theError NE 0 THEN BEGIN Catch, /Cancel void = cgErrorMsg() seccess = 0 RETURN ENDIF ; Assume success. success = 1 ; The longitudes might be calculated from the results of the latitude calculation. ; If they are, this flag will be set to 1. lonsdone = 0 latsdone = 0 ; Get the ranges of the map coordinate object. IF ~Obj_Valid(self._cg_map_object) THEN Message, 'A valid map object is required.' self._cg_map_object -> GetProperty, XRANGE=xrange, YRANGE=yrange ; Sample XY grid at 625 locations throughout the grid (25x25). xstep = (xrange[1] - xrange[0]) / 24.0 ystep = (yrange[1] - yrange[0]) / 24.0 xvec = (Findgen(25) * xstep) + xrange[0] yvec = (Findgen(25) * ystep) + yrange[0] xarr = Rebin(xvec, 25, 25) yarr = Rebin(Reform(Reverse(yvec), 1, 25), 25, 25) ; Find the latitude/longitude of these locations. Find the min, max, ; and lat/lon at the center of the grid. ll = Map_Proj_Inverse(xarr, yarr, MAP_STRUCTURE=self._cg_map_object->GetMapStruct()) latlon = Reform(ll, 2, 25, 25) latlon = Transpose(latlon, [1,2,0]) latitudes = latlon[*,*,1] longitudes = latlon[*,*,0] ; Convert the longitudes to 0 to 360. Otherwise, I have ; problems near the date line. ; longitudes = (longitudes + 360.0) MOD 360.0 lon_min = Min(longitudes, MAX=lon_max, /NAN) lat_min = Min(latitudes, MAX=lat_max, /NAN) center_lat = latitudes[12,12] center_lon = longitudes[12,12] ; We are going to try to have seven lines running through the grid space. ; We will have special rules if the center latitude is at the pole. latrange = Abs(lat_max - lat_min) IF latrange GT 90.0 THEN BEGIN lats = -90.0 > (Findgen(13) * 15 - 90.0) < 90.0 latsdone = 1 ENDIF latstep = latrange / 6.0 lonrange = Abs(lon_max - lon_min) IF lonrange GT 180.0 THEN BEGIN lons = -180.0 > (Findgen(13) * 30 - 180.0) < 180.0 lonsdone = 1 ENDIF lonstep = (lonrange)/ 6.0 ; Make sure we don't have a center latitude at either pole. If we ; do, then lons are calulated differently. IF (center_lat GT (90.-0.05)) && (center_lat LT (90.0 + 0.05)) THEN BEGIN lats = cgScaleVector(Findgen(5), 0 > lat_min < 80) latsdone = 1 IF lonstep GT 40 THEN BEGIN lons = Findgen(11) * 36 lonsDone = 1 ENDIF ENDIF ELSE BEGIN IF (center_lat LT (-90.+0.05)) && (center_lat GT (-90.0 - 0.05)) THEN BEGIN lats = cgScaleVector(Findgen(5), -80, 0 < lat_max) latsdone = 1 IF lonstep GT 40 THEN BEGIN lons = Findgen(11) * 36 lonsDone = 1 ENDIF ENDIF ENDELSE IF latsdone EQ 0 THEN BEGIN CASE 1 OF (latstep GE 30): BEGIN latstep = 30 center_lat = Round(center_lat) lats = -90.0 > [(Indgen(4)+1)*(-latstep) + center_lat, center_lat, $ (Indgen(4)+1)*( latstep) + center_lat] < 90.0 END (latstep GT 10) && (latstep LT 60): BEGIN latstep = Ceil(latstep/10.) * 10.0 center_lat = Round(center_lat) lats = -90.0 > [(Indgen(4)+1)*(-latstep) + center_lat, center_lat, $ (Indgen(4)+1)*( latstep) + center_lat] < 90.0 END (latstep GT 1) && (latstep LT 10): BEGIN latstep = Ceil(latstep) center_lat = Round(center_lat) lats = -90.0 > [(Indgen(4)+1)*(-latstep) + center_lat, center_lat, $ (Indgen(4)+1)*( latstep) + center_lat] < 90.0 END (latstep GT 0.1) && (latstep LT 1): BEGIN latstep = Ceil(latstep*10.0)/ 10. center_lat = Round(center_lat*10.0) / 10.0 lats = -90.0 > [(Indgen(4)+1)*(-latstep) + center_lat, center_lat, $ (Indgen(4)+1)*( latstep) + center_lat] < 90.0 END (latstep GT 0.01) && (latstep LT 0.1): BEGIN latstep = Ceil(latstep*100.0)/ 100. center_lat = Round(center_lat*100.0) / 100.0 lats = -90.0 > [(Indgen(4)+1)*(-latstep) + center_lat, center_lat, $ (Indgen(4)+1)*( latstep) + center_lat] < 90.0 END (latstep LT 0.01) : BEGIN latstep = Ceil(latstep*1000.0)/ 1000. center_lat = Round(center_lat*1000.0) / 1000.0 lats = -90.0 > [(Indgen(4)+1)*(-latstep) + center_lat, center_lat, $ (Indgen(4)+1)*( latstep) + center_lat] < 90.0 END ELSE: BEGIN latstep = 30 center_lat = Round(center_lat) lats = -90.0 > [(Indgen(4)+1)*(-latstep) + center_lat, center_lat, $ (Indgen(4)+1)*( latstep) + center_lat] < 90.0 END ENDCASE ENDIF IF lonsDone EQ 0 THEN BEGIN CASE 1 OF (lonstep GE 60): BEGIN lonstep = 60 center_lon = Round(center_lon) lons = -180.0 > [(Indgen(3)+1)*(-lonstep) + center_lon, center_lon, $ (Indgen(3)+1)*( lonstep) + center_lon] < 360.0 END (lonstep GT 10) && (lonstep LT 60): BEGIN lonstep = Ceil(lonstep/10.) * 10.0 center_lon = Round(center_lon) lons = -180.0 > [(Indgen(4)+1)*(-lonstep) + center_lon, center_lon, $ (Indgen(4)+1)*( lonstep) + center_lon] < 360.0 END (lonstep GT 1) && (lonstep LT 10): BEGIN lonstep = Ceil(lonstep) center_lon = Round(center_lon) lons = -180.0 > [(Indgen(4)+1)*(-lonstep) + center_lon, center_lon, $ (Indgen(4)+1)*( lonstep) + center_lon] < 360.0 END (lonstep GT 0.1) && (lonstep LT 1): BEGIN lonstep = Ceil(lonstep*10.0)/ 10. center_lon = Round(center_lon*10.0) / 10.0 lons = -180.0 > [(Indgen(4)+1)*(-lonstep) + center_lon, center_lon, $ (Indgen(4)+1)*( lonstep) + center_lon] < 360.0 END (lonstep GT 0.01) && (lonstep LT 0.1): BEGIN lonstep = Ceil(lonstep*100.0)/ 100. center_lon = Round(center_lon*100.0) / 100.0 lons = -180.0 > [(Indgen(4)+1)*(-lonstep) + center_lon, center_lon, $ (Indgen(4)+1)*( lonstep) + center_lon] < 360.0 END (lonstep LT 0.01) : BEGIN lonstep = Ceil(lonstep*1000.0)/ 1000. center_lon = Round(center_lon*1000.0) / 1000.0 lons = -180.0 > [(Indgen(4)+1)*(-lonstep) + center_lon, center_lon, $ (Indgen(4)+1)*( lonstep) + center_lon] < 360.0 END ELSE: BEGIN lonstep = 30 center_lon = Round(center_lon) lons = -180.0 > [(Indgen(4)+1)*(-lonstep) + center_lon, center_lon, $ (Indgen(4)+1)*( lonstep) + center_lon] < 360.0 END ENDCASE ENDIF ; The values might need to be sorted. lats = lats[Sort(lats)] lons = lons[Sort(lons)] ; Labels should be near the center. index = Value_Locate(lons, center_lon) latlab = (lons[index] - lons[index-1]) / 2.0 + lons[index-1] index = Value_Locate(lats, center_lat) lonlab = (lats[index] - lats[index-1]) / 2.0 + lats[index-1] ; Set up the latitude and longitude names. IF Total(lats-Long(lats)) EQ 0 THEN format='(I0)' ELSE format='(F0.2)' latnames = String(lats, FORMAT=format) IF Total(lons-Long(lons)) EQ 0 THEN format='(I0)' ELSE format='(F0.2)' lonnames = String(lons, FORMAT=format) ; Set the properties of the object. self -> SetProperty, LATLAB=latlab, LATS=lats, LATNAMES=latnames, $ LONLAB=lonlab, LONS=lons, LONNAMES=lonnames END ;+-------------------------------------------------------------------------- ; Draws the map grid by calling cgMap_Grid. ; ;--------------------------------------------------------------------------- PRO cgMapGrid::Draw ; Error handling Catch, theError IF theError NE 0 THEN BEGIN Catch, /Cancel void = cgErrorMsg() RETURN ENDIF ; This can cause all kinds of error messages from MAP_PROJ_FORWARD. Turn them all off. except = !Except !Except = 0 ; If you are auto drawing grids, set up the lats and lons. IF self._cg_autodrawgrid THEN BEGIN self -> AutoDrawGrid, SUCCESS=success void = Check_Math() !Except = except IF ~success THEN RETURN ENDIF ; Draw the map grid. cgMap_Grid, $ BCOLOR=self._cg_bcolor, BOX_AXES=self._cg_box_axes, $ CLIP_TEXT=1, $ CHARSIZE=self._cg_charsize, $ COLOR=self._cg_color, $ FILL_HORIZON=self._cg_fill_horizon, $ FORMAT=self._cg_format, $ FUZZY=self._cg_fuzzy, $ HORIZON=self._cg_horizon, $ INCREMENT=*self._cg_increment, $ LABEL=self._cg_label, $ LATALIGN=self._cg_latalign, $ LATDEL=*self._cg_latdel, $ LATLAB=*self._cg_latlab, $ LATNAMES=*self._cg_latnames, $ LATS=*self._cg_lats, $ LCOLOR=self._cg_lcolor, $ LINESTYLE=self._cg_linestyle, $ LONALIGN=self._cg_lonalign, $ LONDEL=*self._cg_londel, $ LONLAB=*self._cg_lonlab, $ LONNAMES=*self._cg_lonnames, $ LONS=*self._cg_lons, $ MAP_STRUCTURE=self._cg_map_object, $ ; The map object itself. THICK=self._cg_thick ; Turn messages back on. void = Check_Math() !Except = except END ;+-------------------------------------------------------------------------- ; This method allows the user to get various properties of the object. In general, ; the same keywords that are used for the INIT method can be used here. ;--------------------------------------------------------------------------- PRO cgMapGrid::GetProperty, $ AUTODRAWGRID=autodrawgrid, $ BOX_AXES=box_axes, $ CLIP_TEXT=clip_text, $ CHARSIZE=charsize, $ COLOR=color, $ FILL_HORIZON=fill_horizon, $ FIXED_cgMapGrid=fixed_map_grid, $ FORMAT=format, $ LCOLOR=lcolor, $ LINESTYLE=linestyle, $ THICK=thick, $ HORIZON=horizon, $ INCREMENT=increment, $ LABEL=label, $ LATALIGN=latalign, $ LATDEL=latdel, $ LATLAB=latlab, $ LATNAMES=latnames, $ LATS=lats, $ LONALIGN=lonalign, $ LONDEL=londel, $ LONLAB=lonlab, $ LONNAMES=lonnames, $ LONS=lons, $ MAP_OBJECT=map_object, $ MAP_STRUCTURE=map_structure, $ _REF_EXTRA=extra ; Error handling Catch, theError IF theError NE 0 THEN BEGIN Catch, /Cancel void = cgErrorMsg() RETURN ENDIF autodrawgrid = self._cg_autodrawgrid box_axes = self._cg_box_axes clip_text = self._cg_clip_text charsize = self._cg_charsize color = self._cg_color fill_horizon = self._cg_fill_horizon format = self._cg_format latalign = self._cg_latalign lcolor = self._cg_lcolor lonalign = self._cg_lonalign linestyle = self._cg_linestyle thick = self._cg_thick horizon = self._cg_horizon increment = self._cg_increment IF Ptr_Valid(self._cg_label) THEN label = self._cg_label IF N_Elements(*self._cg_latdel) NE 0 THEN latdel = *self._cg_latdel IF N_Elements(*self._cg_latlab) NE 0 THEN latlab = *self._cg_latlab IF N_Elements(*self._cg_latnames) NE 0 THEN latnames = *self._cg_latnames IF N_Elements(*self._cg_lats) NE 0 THEN lats = *self._cg_lats IF N_Elements(*self._cg_londel) NE 0 THEN londel = *self._cg_londel IF N_Elements(*self._cg_lonlab) NE 0 THEN lonlab = *self._cg_lonlab IF N_Elements(*self._cg_lonnames) NE 0 THEN lonnames = *self._cg_lonnames IF N_Elements(*self._cg_lons) NE 0 THEN lons = *self._cg_lons map_object = self._cg_map_object IF Arg_Present(map_structure) THEN map_structure = self._cg_map_object -> GetMapStruct() IF N_Elements(extra) NE 0 THEN self -> cgContainer::GetProperty, _EXTRA=extra END ;+-------------------------------------------------------------------------- ; This method allows the user to set various properties of the object. In general, ; the same keywords that are used for the INIT method can be used here. ;--------------------------------------------------------------------------- PRO cgMapGrid::SetProperty, $ AUTODRAWGRID=autodrawgrid, $ BOX_AXES=box_axes, $ CLIP_TEXT=clip_text, $ CHARSIZE=charsize, $ COLOR=color, $ DRAW=draw, $ FILL_HORIZON=fill_horizon, $ FIXED_cgMapGrid=fixed_map_grid, $ FORMAT=format, $ LINESTYLE=linestyle, $ HORIZON=horizon, $ INCREMENT=increment, $ LABEL=label, $ LATALIGN=latalign, $ LATDEL=latdel, $ LATLAB=latlab, $ LATNAMES=latnames, $ LATS=lats, $ LCOLOR=lcolor, $ LONALIGN=lonalign, $ LONDEL=londel, $ LONLAB=lonlab, $ LONNAMES=lonnames, $ LONS=lons, $ THICK=thick, $ _EXTRA=extra ; Error handling Catch, theError IF theError NE 0 THEN BEGIN Catch, /Cancel void = cgErrorMsg() RETURN ENDIF IF N_Elements(autodrawgrid) NE 0 THEN self._cg_autodrawgrid = Keyword_Set(autodrawgrid) IF N_Elements(box_axes) NE 0 THEN self._cg_box_axes = Keyword_Set(box_axes) IF N_Elements(clip_text) NE 0 THEN self._cg_clip_text = clip_text IF N_Elements(charsize) NE 0 THEN self._cg_charsize = charsize IF N_Elements(color) NE 0 THEN self._cg_color = color IF N_Elements(fill_horizon) NE 0 THEN self._cg_fill_horizon = Keyword_Set(fill_horizon) IF N_Elements(format) NE 0 THEN self._cg_format = format IF N_Elements(linestyle) NE 0 THEN self._cg_linestyle = linestyle IF N_Elements(horizon) NE 0 THEN self._cg_horizon = Keyword_Set(horizon) IF N_Elements(increment) NE 0 THEN *self._cg_increment = increment IF N_Elements(label) NE 0 THEN self._cg_label = label IF N_Elements(latalign) NE 0 THEN self._cg_latalign = latalign IF N_Elements(latdel) NE 0 THEN *self._cg_latdel = latdel IF N_Elements(latlab) NE 0 THEN *self._cg_latlab = latlab IF N_Elements(latnames) NE 0 THEN *self._cg_latnames = latnames IF N_Elements(lats) NE 0 THEN *self._cg_lats = lats IF N_Elements(lcolor) NE 0 THEN self._cg_lcolor = lcolor IF N_Elements(lonalign) NE 0 THEN self._cg_lonalign = lonalign IF N_Elements(londel) NE 0 THEN *self._cg_londel = londel IF N_Elements(lonlab) NE 0 THEN *self._cg_lonlab = lonlab IF N_Elements(lonnames) NE 0 THEN *self._cg_lonnames = lonnames IF N_Elements(lons) NE 0 THEN *self._cg_lons = lons IF N_Elements(thick) NE 0 THEN self._cg_thick = thick IF N_Elements(extra) NE 0 THEN self -> cgContainer::SetProperty, _EXTRA=extra ; Need a draw? IF Keyword_Set(draw) THEN self -> Draw END ;+-------------------------------------------------------------------------- ; This is the clean-up routine for the object. ; ;--------------------------------------------------------------------------- PRO cgMapGrid::CLEANUP ; Destroy object pointers. Ptr_Free, self._cg_increment Ptr_Free, self._cg_latdel Ptr_Free, self._cg_latlab Ptr_Free, self._cg_latnames Ptr_Free, self._cg_lats Ptr_Free, self._cg_londel Ptr_Free, self._cg_lonlab Ptr_Free, self._cg_lonnames Ptr_Free, self._cg_lons ; Call the superclass cleanup or memory leaks will occur. self -> cgContainer::CLEANUP END ;+-------------------------------------------------------------------------- ; This is the class definition module. Structures used to manipulate ; map projection and map datum information are also created here. ; ; :Params: ; class: out, optional, type=structure ; Occasionally, it is useful to have an object class definition as ; a structure variable. Using this output keyword will allow that. ;--------------------------------------------------------------------------- PRO cgMapGrid__DEFINE, class class = { cgMapGrid, $ _cg_autodrawgrid: 0B, $ _cg_bcolor: "", $ _cg_box_axes: 0B, $ _cg_clip_text: 0B, $ _cg_charsize: 0.0, $ _cg_color: "", $ _cg_fill_horizon: 0B, $ _cg_format: "", $ _cg_fuzzy: 0.0, $ _cg_linestyle: 0, $ _cg_thick: 0, $ _cg_horizon: 0B, $ _cg_increment: Ptr_New(), $ _cg_label: 0, $ _cg_latalign: 0.0, $ _cg_latdel: Ptr_New(), $ _cg_latlab: Ptr_New(), $ _cg_latnames: Ptr_New(), $ _cg_lats: Ptr_New(), $ _cg_lcolor: "", $ _cg_lonalign: 0.0, $ _cg_londel: Ptr_New(), $ _cg_lonlab: Ptr_New(), $ _cg_lonnames: Ptr_New(), $ _cg_lons: Ptr_New(), $ _cg_map_object: Obj_New(), $ INHERITS cgContainer $ } END