McIDAS Programmer's Manual
Version 2006
[Search Manual] [Table of Contents] [Go to Previous] [Go to Next]
All geophysical data must have a location to be meaningful. McIDAS-X stores geophysical data in the form closest to its native spatial structure; for example, remotely sensed data is stored in the image coordinates of the scanner line and element, while NWP model output is stored as model grid points. Since earth coordinates (for example, latitude, longitude and height above mean sea level) are easiest to interpret, McIDAS-X uses a process called navigation to convert a dataset's native coordinate system to earth coordinates and back again.
Navigating datasets implies the ability to transform any dataset into the spatial coordinates of any other dataset. McIDAS-X' ability to integrate and display a variety of datasets is made possible by its navigation subsystems.
For more information about McIDAS-X coordinate systems, see Chapter 2, Learning the Basics. For additional information about map projections, see Map Projections -- A Working Manual, USGS Professional Paper 1395, U.S. Government Printing Office, Washington, 1987. |

To select and use the best McIDAS-X navigation subsystem for a given task, you need to understand the nature of navigation transforms. Navigation systems and transforms are described below, along with some navigation-specific terminology used throughout this section.
A navigation transform is a set of equations for converting a dataset's image or native coordinates to and from earth coordinates. Each dataset has its own navigation transform. However, navigation transforms can be grouped into classes or types. Within a type, the differences between transforms are quantitative only. Each type has a set of variables, or parameters, whose values uniquely specify an instance of that type. For example, the parameters for a tangent cone projection include the standard latitude and longitude, the scale factor, and the location of the pole relative to the projection surface's origin.
All navigated McIDAS-X data has an associated type and a full set of parameters defining an instance.
Grid navigation converts earth coordinates to and from the row and column locations in the grid structure. This subsystem is separate from image and frame navigation, and supports fewer projections These projection types are implemented in a single set of functions. To add other types, you would have to modify the functions and recompile all grid applications. Since only a single instance can be in use at one time, you must repeatedly reinitialize the subsystem to use multiple projections within an application.
For example, to compare two grids, A and B, you initialize grid navigation for A, compute the earth location of a grid point a in A, reinitialize the subsystem using B's parameters, and transform the earth location of a to a grid in B. This process is then repeated for every grid point being compared. Most applications that process or use grids use grid navigation.
For more information about grid projection formats, see the Grid data section earlier in this chapter. |
Image navigation converts image coordinates to and from earth coordinates. Each image navigation type is implemented in its own source file or module, and each navigable image dataset has an associated navigation block that identifies the type and contains a complete set of parameters needed to define an instance of that type.
Each module implements the same function names and calling sequence. Since McIDAS-X uses the type identifier to select the correct module, you can add new types without modifying existing modules. In addition, up to three instances of navigation, of the same or different types, can be active simultaneously in a single application through different slots. This requires a one- or two-step initialization process before use and is typically used by applications that work directly with image datasets.
Frame navigation converts frame coordinates to and from earth coordinates. Frame navigation uses the image navigation subsystem but through a simpler API. It is sufficient for most applications that just add information to an existing display.
This section contains some navigation-specific terms that may be unfamiliar to you. They are defined below.

The McIDAS-X library provides Application Program Interfaces for geographic calculations as well as grid, image and frame navigation. These APIs are described below.
Many calculations just require a change from one form of earth or planetary coordinate to another; for example, changing from a terrestrial (earth-relative) to celestial (star-relative) coordinate system, or converting a position from a Cartesian to spherical representation. The table below lists the functions for performing these tasks.
| Functions | Description |
|---|---|
The table below shows the grid navigation API. You will use the grddef function with the header to initialize the subsystem, then call ijll and llij to transform grid coordinates to and from earth coordinates, respectively.
| Function | Description |
|---|---|
No API functions currently exist for creating grid headers for a projection. When creating McIDAS-X grid files, you must determine the projection to use and then insert the projection type and parameters into the grid header. The grid header format is described in the GRIDnnnn data structure in Chapter 6.
Use the two functions below to determine the earth coordinates of a pixel or the pixel location of a point in earth coordinates.
| Function | Description |
|---|---|
The only prerequisite for these functions is that the frame has navigation associated with it. The McIDAS-X IMGDISP command creates frame navigation when it displays an image dataset. The McIDAS-X MAP, PTDISP and GRDDISP commands, which can define a map base before generating a display, also establish frame navigation.
The two examples below assume that frame navigation information exists. The first code fragment uses the illtv function to convert an earth location (zlat,zlon) to a frame location (itvlin,itvele), as is done in the McIDAS-X PC command.
zlat = 43.13 zlon = 89.35 if(illtv(iframe,gnum,zlat,zlon,ilin,iele,itvlin,itvele).ne.0)then call edest('unable to navigate point',0) return endif |
The second code fragment uses itvll to determine the earth location of the cursor, as is done in the McIDAS-X E command.
if( mcmoubtn( 0, left, right, itvlin, itvele ) ) then C // handle cursor-positioning error here end if frame = mcgetimageframenumber() rc = itvll(frame,itvlin,itvele,ilin,iele,rlat,rlon,iscene) |
Use the appropriate image navigation API functions from the table below if your application must perform one of these tasks:
To use image navigation services, the application must do the following:
The example below, from remap.pgm, illustrates the initialization and use of two instances (slots) of navigation at the same time.
The lines below assume that navigation blocks were already obtained from the source (snav) and destination (dnav) areas. To link the appropriate navigation module to a slot and initialize it, use nvprep. The lines below initialize slot 1 for the source and slot 2 for the destination. The nv1ini and nv2ini calls set the earth coordinate form to Cartesian for both slots.
The lines below map image coordinate (dline,delement) in the destination image to image coordinate (sline,selement) in the source image by converting from destination image coordinates to earth coordinates, then from earth coordinates to source image coordinates.
When the navigation block source is a local McIDAS-X area format image file or a frame whose number is known and you only intend to use slot 1, you can use nvset. It reads the navigation block out of an area or frame and calls nvprep.
In addition to the commonly used conversions between earth and image coordinates available through nvxsae and nvxeas, other special services are available through the nvxopt function. Some of these services and the modules that support them are listed in the table below.
| Special services | Modules that support them |
|---|---|
nvxdmsp, nvxgoes, nvxgraf, nvxgvar, nvxlamb, nvxmerc, nvxmsat, nvxps, nvxradr, nvxrect, nvxsin, nvxtiro |
|
The sample code below shows the use of nvxopt. When using nvxopt, you need to be aware that the input/output can be different for the different satellite navigations, and you'll have to check the nvx sat.dlm file to check what is appropriate for input/output.

You can extend image navigation to include a new type and make it available to all McIDAS-X commands without changing any applications or existing navigation modules. This section describes the process for implementing a tangent-cone map projection. The complete source listing is in the next section titled Example navigation module code.
The navigation block must consist of an array of no more than 640 Fortran integers that are sufficient to uniquely specify a particular instance of the new navigation type. The first word of the block must be four ASCII characters that uniquely identify the type, stored in an integer variable. The block contents are obvious once the algorithm is fully specified and understood.
The navigation module name must be nvxtype.dlm, where type is the same four characters specified in the first word of the block. The nvprep function uses the type from the block to link the application with the correct module.
The navigation module must implement the functions nvxini, nvxsae, nvxeas and nvxopt, with calling sequences following the documentation blocks in the tangent cone example. In particular, nvxini must support modes 1 (initialize) and 2 (set earth coordinate mode 'LL' (Latitude-longitude) or 'XYZ' (Cartesian)). The nvxopt function must provide, at minimum, an 'SPOS' (subpoint) service.
Between calls, the navigation module must remember the navigation parameters uniquely defining an instance. This is typically accomplished by storing these parameters, and quantities derived from them, in a named common block that is shared among all four API functions in the module.
Satellites and map projections cannot physically represent all earth locations. The limits vary from type to type and even from instance to instance. Applications, therefore, cannot be expected to validate inputs to navigation modules. The new module must be able to recognize inputs it cannot handle and return an error status, typically a negative integer.
A navigation algorithm is a set of equations for mapping McIDAS-X image coordinates to earth coordinates and vice versa. For satellite navigation types, this typically involves a lengthy expression in vector notation. Map projections are simpler. Some manipulation and derivation of additional relationships is often necessary to extend a published relationship into a full algorithm.
The example presented here will show the development of a northern hemisphere tangent cone projection algorithm. The geometry of the tangent cone is shown in Figure 5-6 below. The cone is tangent to the planet at one parallel of latitude and the planetary axis pierces the apex of the cone. A line between a point on the Earth's surface and the pole opposite the cone apex maps that point onto the cone. The imaginary cone is then cut along a meridian opposite an arbitrary standard longitude and flattened. Each point on the Earth's surface in colatitude ψ and longitude λ corresponds to a point (R,θ) in polar coordinates on the flattened cone.
Figure 5-6. Tangent cone projection geometry.



A published form of the equations defining the location (R,θ) on the flattened cone in terms of an earth location (ψ,λ) is:
Adding (6) - (9) to make a complete McIDAS-X navigation algorithm adds additional parameters to make the complete set ψ0, λ0, m, L0, and E0, where the latter specify the scale in km per pixel and the location of the pole of the projection surface in image coordinates.
The last step before implementation is to examine the completed algorithm for limits and singularities; these will serve as the basis for input validation. The limits on the inputs are summarized below.
The contents of the navigation block follow directly from the parameters provided in the previous Algorithms section. The five parameters are:
A sixth parameter, planetary radius, could also be added but is not included in the examples. The parameters can be represented in different ways, such as standard colatitude in place of latitude. However, since the applications will create navigation blocks, you should use units and quantities convenient for McIDAS-X, as shown in the lines of code below. This code is taken from the documentation block at the beginning of nvxini and is shown in lines 0017 through 0022 in the complete source listing that follows.
All instances of 'TANC' navigation must be specified with these parameters.
Applications that create navigation blocks must provide values for a complete set of parameters. Sometimes they must be derived from user inputs using the navigation transformation itself. Below is a code fragment from an application (not the navigation module itself) that creates a tangent-cone navigation block. It assumes that the center latitude and longitude (clat and clon), the standard latitude and longitude (slat and slon), and the scale of standard latitude (sscale), in km per pixel, are already provided. First, the earth locations are converted from McIDAS-X to projection form.
psi = PI/2.d0 - D2R*clat psi_0 = PI/2.d0 - D2R*slat lam = - D2R*clon lam_0 = - D2R*slon |
Next, the radius of the specified image coordinate center point (relative to the projection center or the pole) is computed.
radius = A * tan(psi_0) * $ (tan(psi/2.d0)/tan(psi_0/2.d0))**cos(psi_0) theta = cos(psi_0)*(lam-lam_0) |
Then the pole's image coordinate is computed using simple trigonometry.
call status = mcfsize(mcgetimageframenumber, nlins, neles) lin_c = dble(nlins) / 2.d0 ele_c = dble(neles) / 2.d0 lin_0 = lin_c - radius*cos(theta)/sscale ele_0 = ele_c - radius*sin(theta)/sscale |
Once the parameters are computed, the navigation block can be filled and written either to the image dataset:
or a McIDAS-X area format image file:
call araput(aranum,4*DIRSIZ,4*NVWDS,nvblk) |
If the algorithm and navigation block are complete and unambiguous, implementing a map projection as a McIDAS-X navigation module is generally straightforward. Your major design decision is what to store in the common block. At minimum, you should include the navigation parameters or quantities derived from them without loss of information. This is necessary for the module to remember the characteristics of the instance.
Because navigation modules are called many times, you should precompute additional quantities in the initialization routine nvxini and store them in common, especially if doing so eliminates trigonometric function calls in the other functions. Thus, the variables Coscl, Tancl, Tancl2, and Mxtheta are included in the common block below. This code is located in lines 0099 through 0120 of the source listing that follows.
Also included in the block are physical constants and two flags; Init is
set when nvxini runs successfully, and Latlon is
set if the earth coordinate mode is latitude and longitude rather than Cartesian.
The overall structure of nvxini is a large if-block to handle the two options. Option 1 (lines 0144 - 0220 in the source listing) initializes the instance by range checking the navigation parameters and precomputing the quantities to retain in the common block. Option 2 (lines 0222 - 0233) sets the earth coordinate mode based on word param(1).
The forward (image to Earth) navigation routine's one subtlety is input validation. Points within the split of the projection plane, which is shown in Figure 5-6, are not navigable.
Recognizing such points is possible only after the conversion from McIDAS-X image coordinates to projection coordinates is complete. The code below is from lines 0370 through 0384.
When range checking is done, the projection is inverted and the colatitude and longitude (in radians, east positive) is converted to latitude and longitude (in degrees, west positive); see lines 0389 - 0401. A call to nllxyz to generate Cartesian coordinate output is made if the Latlon flag was cleared by an earlier call to nvxini (line 0404). Inverse (earth-to-image) navigation in nvxeas follows a similar pattern, except the earth-coordinate option must be handled at the beginning (line 0544).
The nvxopt function performs special services. Since the contents of the argument vector depend on the option selected, the routine consists of a large if-block (lines 0716 - 0742) with one branch per recognized option and the necessary input validation done within each branch. As in nvxini, the code must be able to recognize options that it doesn't know and return an appropriate error status. All core McIDAS-X navigation modules have an SPOS option that returns the subpoint at a given time (for satellites) or the latitude and longitude of the center (maps). The example that follows implements only an SCAL to return the map scale factor at any latitude.
1. Saucier, W. J. 1983: Principles of meteorological analysis. Dover Publications, Inc., New York. 438 pp.

0001 C THIS IS SSEC PROPRIETARY SOFTWARE - ITS USE IS RESTRICTED.
0002
0003 C *** McIDAS Revision History ***
0004 C *** McIDAS Revision History ***
0005
0006 *$ Name:
0007 *$ nvxini - Initialize navigation for tangent cone projection
0008 *$
0009 *$ Interface:
0010 *$ integer function
0011 *$ nvxint(integer option, integer param(*))
0012 *$
0013 *$ Input:
0014 *$ option - 1 to set or change projection parameters
0015 *$ option - 2 set output option
0016 *$ param - For option 1:
0017 *$ param( 1) = 'TANC'
0018 *$ param( 2) = image line of pole*10000
0019 *$ param( 3) = image element of pole*10000
0020 *$ param( 4) = km per pixel *10000
0021 *$ param( 6) = standard latitude *10000
0022 *$ param( 7) = standard longitude *10000
0023 *$ for option 2:
0024 *$ param( 1) = 'LL' or 'XYZ'
0025 *$
0026 *$ Input and Output:
0027 *$ none
0028 *$
0029 *$ Output:
0030 *$ none
0031 *$
0032 *$ Return values:
0033 *$ 0 - success
0034 *$ -3 - invalid or inconsistent navigation parameters
0035 *$ -4 - invalid navigation parameter type
0036 *$ -5 - invalid nvxini() option
0037 *$
0038 *$ Remarks:
0039 *$ Latitudes and longitudes are in degrees, West positive.
0040 *$ Projection parameters must be in the following ranges:
0041 *$ 0. < standard latitude < 90.
0042 *$ -180. <= standard longitude < 180.
0043 *$ 0. < scale
0044 *$ Accuracy may suffer near the standard latitude limits.
0045 *$
0046 *$ The projection algorithm is adapted from that in
0047 *$ Saucier, W. J. 1989: Principles of meteorological analysis.
0048 *$ Dover Publications, Inc. 433 pp.
0049 *$
0050 *$ Categories:
0051 *$ navigation
0052
0053 C // CODING CONVENTION note: function declarations and common
0054 C // block declarations are all capitalized to be recognizable
0055 C // to script 'convdlm;' this is necessary for a correct build
0056 C // in MCIDAS-X. For the same reason, avoid referring to
0057 C // function or common block names in uppercase elsewhere
0058
0059 INTEGER FUNCTION NVXINI(option,param)
0060
0061
0062 implicit NONE
0063
0064
0065 C // Interface variables (formal arguments)
0066
0067 integer option ! initialization option
0068 integer param(*) ! navigation parameters or
0069 C ! output coordinate type
0070
0071 C // Local variable definitions
0072
0073 character*4 navtyp ! codicil type
0074 character*4 outcoord ! output coordinate type
0075 real lat0 ! standard latitude
0076 character*80 cbuf ! text output buffer
0077
0078
0079
0080 C /////////////////////////////////////////////////////////
0081 C Common block variables and declaration.
0082
0083 C ALL CODE BETWEEN THE '//////' SEPARATORS MUST BE
0084 C DUPLICATED EXACTLY IN EACH NAVIGATION ROUTINE
0085
0086 C (A more maintenance-safe version would use ENTRY points
0087 C rather than separate functions for the navigation API
0088 C but entry points cannot be processed by 'convdlm.')
0089
0090 C // Common block contents: projection parameters
0091
0092 real Lin0 ! image line of pole
0093 real Ele0 ! image element of pole
0094 real Scale ! km per unit image coordinate
0095 C ! (pixel)
0096 real Lon0 ! standard longitude
0097 real Colat0 ! standard colatitude
0098
0099 C // Common block contents: precomputed intermediate values
0100
0101 real Coscl ! cosine(Colat0)
0102 real Tancl ! tangent(Colat0)
0103 real Tancl2 ! tangent(Colat0/2)
0104 real Mxtheta ! limit of angle from std. lon
0105 C ! on projection surface
0106
0107 C // Common block contents: constants
0108
0109 real D2R ! degrees to radians factor
0110 real Pi
0111 real Badreal ! returned when navigation
0112 C ! cannot be done
0113 real Erad ! Earth radius
0114 logical Init ! initialized flag
0115 logical Latlon ! .TRUE. for lat/lon I/O
0116
0117
0118 COMMON/TANC/ Lin0, Ele0, Scale, Lon0, Colat0,
0119 & Coscl, Tancl, Tancl2, Mxtheta,
0120 & D2R, Pi, Badreal, Erad, Init, Latlon
0121
0122 C End of common block variables and declaration.
0123 C /////////////////////////////////////////////////////////
0124
0125
0126
0127 C // Begin initialization process by setting values of constants.
0128
0129 Erad = 6370. ! This value of Erad is ok
0130 C ! for low precision nav
0131 C ! where a spherical Earth is
0132 C ! adequate (Saucier, p. 32)
0133 Pi = acos(-1.)
0134 D2R = Pi / 180.
0135 Badreal = -1.E10 ! obvious unreasonable value
0136 C ! for nav transform result
0137
0138 C // Process initialization options. Only one option, initialize
0139 C // navigation parameters, is supported in this demo version,
0140 C // but a 'hook' is left for an additional option to set the
0141 C // output coordinate to something other than lat/lon
0142
0143 if( option.eq.1 ) then
0144
0145 call DDEST('nvxini(tanc) option=1',0)
0146
0147 call movwc(param(1),navtyp)
0148 if( navtyp.eq.'TANC') then
0149
0150 C // Unpack tangent cone projection parameters
0151
0152 Lin0 = param(2) / 10000.
0153 Ele0 = param(3) / 10000.
0154 Scale = param(4) / 10000.
0155 lat0 = param(5) / 10000.
0156 Lon0 = param(6) / 10000.
0157
0158 write(cbuf,'('' nvxini: lat0, Lon0 '',2F12.4)')
0159 * lat0, Lon0
0160 call DDEST(cbuf,0)
0161
0162 C // apply range checking
0163
0164 if(Scale.le.0. ) then
0165 call DDEST('nvxini(tanc) scale is negative',0)
0166 Init = .FALSE.
0167 NVXINI = -3
0168 return
0169 end if
0170
0171 if(lat0.le.0. .or. lat0.ge.90. ) then
0172 call DDEST('nvxini(tanc) standard lat out of range',0)
0173 Init = .FALSE.
0174 NVXINI = -3
0175 return
0176 end if
0177
0178 if(Lon0.le.-180. .or. Lon0.gt.180. ) then
0179 call DDEST('nvxini(tanc) standard lon out of range',0)
0180 Init = .FALSE.
0181 NVXINI = -3
0182 return
0183 end if
0184
0185 C // convert degrees to radians and latitude to colatitude.
0186 C // Account for McIDAS longitude convention
0187
0188 Lon0 = -Lon0 * D2R
0189 Colat0 = Pi/2. - D2R*lat0
0190
0191 write(cbuf,'('' nvxini: Colat0, Lon_0 '',2F12.4)')
0192 * Colat0, Lon0
0193 call DDEST(cbuf,0)
0194
0195 C // Compute intermediate quantities
0196
0197 Coscl = cos(Colat0)
0198 Tancl = tan(Colat0)
0199 Tancl2 = tan(Colat0/2.)
0200 Mxtheta = Pi*Coscl
0201
0202 write(cbuf,'('' nvxini: Coscl, Tancl'', 2F7.4)')
0203 * Coscl, Tancl
0204 call DDEST(cbuf,0)
0205 write(cbuf,'('' nvxini: Tancl2, Mxtheta '', 2F7.4)')
0206 * tancl2, Mxtheta
0207 call DDEST(cbuf,0)
0208
0209 Latlon = .TRUE.
0210
0211
0212 else ! option=1 but type not 'TANC'
0213
0214 call DDEST('nvxini(tanc) parameter type bad',0)
0215 Init = .FALSE.
0216 NVXINI = -4
0217 return
0218
0219 end if
0220
0221 else if ( option .eq. 2) then
0222
0223 call movwc(param(1),outcoord)
0224 if( outcoord.eq.'LL' ) then
0225 Latlon = .TRUE.
0226 else if( outcoord.eq.'XYZ') then
0227 Latlon = .FALSE.
0228 else
0229 call DDEST('option=2 coord '//outcoord//' not supported',0)
0230 Init = .FALSE.
0231 NVXINI = -5
0232 end if
0233
0234 else ! option not 1 or 2
0235
0236 call DDEST('nvxini(tanc) unrecognized output option ',option)
0237 NVXINI = -4
0238 return
0239
0240 end if
0241
0242 NVXINI = 0
0243 Init = .TRUE.
0244
0245 return
0246 end
0247
0248
0249
0250
0251 *$ Name:
0252 *$ nvxsae - Compute earth coordinates from image coordinates
0253 *$
0254 *$ Interface:
0255 *$ integer function
0256 *$ nvxsae( real lin, real ele, real dummy,
0257 *$ real e1, real e2, real e3 )
0258 *$
0259 *$ Input:
0260 *$ lin - image line
0261 *$ ele - image element
0262 *$ dummy - (unused)
0263 *$
0264 *$ Input and Output:
0265 *$ none
0266 *$
0267 *$ Output:
0268 *$ e1 - latitude or x
0269 *$ e2 - longitude or y
0270 *$ e3 - height or z
0271 *$
0272 *$ Return values:
0273 *$ 0 - success
0274 *$ -1 - input data physically valid but not navigable
0275 *$ given the specified projection
0276 *$ -6 - module not initialized
0277 *$
0278 *$ Remarks:
0279 *$ The navigation module must first be initialized with
0280 *$ a call to nvxini(). The output form (lat,lon) or (x,y,z)
0281 *$ depends on the last call to nvxini() with option 2.
0282 *$
0283 *$ Categories:
0284 *$ navigation
0285
0286 INTEGER FUNCTION NVXSAE( lin, ele, dummy, e1, e2, e3 )
0287
0288 implicit NONE
0289
0290 C // Interface variables (formal arguments)
0291
0292 real lin ! image line to navigate
0293 real ele ! image element to navigate
0294 real dummy ! (unused argument)
0295 real e1 ! Earth coordinate 1
0296 real e2 ! Earth coordinate 2
0297 real e3 ! Earth coordinate 3
0298
0299 C // Local variables
0300
0301 real lat ! latitude (McIDAS convention)
0302 real lon ! longitude (McIDAS convention)
0303 real hgt ! height
0304 real dx ! zonal displacement from pole
0305 C ! on projection surface
0306 real dy ! meridional displacement from pole
0307 real radius ! distance from pole on projection
0308 real theta ! angle from standard longitude on
0309 C ! projection surface
0310 real colat ! colatitude of navigated point
0311
0312
0313 C ///////////////////////////////////////////////////////
0314 C Common block variables and declaration.
0315
0316 C ALL CODE BETWEEN THE '//////' SEPARATORS MUST BE
0317 C DUPLICATED EXACTLY IN EACH NAVIGATION ROUTINE
0318
0319 C (A more maintenance-safe version would use ENTRY points
0320 C rather than separate functions for the navigation API
0321 C but entry points cannot be processed by 'convdlm.')
0322
0323 C // Common block contents: projection parameters
0324
0325 real Lin0 ! image line of pole
0326 real Ele0 ! image element of pole
0327 real Scale ! km per unit image coordinate
0328 C ! (pixel)
0329 real Lon0 ! standard longitude
0330 real Colat0 ! standard colatitude
0331
0332 C // Common block contents: pre-computed intermediate values
0333
0334 real Coscl ! cosine(Colat0)
0335 real Tancl ! tangent(Colat0)
0336 real Tancl2 ! tangent(Colat0/2)
0337 real Mxtheta ! limit of angle from std. lon
0338 C ! on projection surface
0339
0340 C // Common block contents: constants
0341
0342 real D2R ! degrees to radians factor
0343 real Pi
0344 real Badreal ! returned when navigation
0345 C ! cannot be done
0346 real Erad ! Earth radius
0347 logical Init ! initialized flag
0348 logical Latlon ! .TRUE. for lat/lon I/O
0349
0350 COMMON/TANC/ Lin0, Ele0, Scale, Lon0, Colat0,
0351 & Coscl, Tancl, Tancl2, Mxtheta,
0352 & D2R, Pi, Badreal, Erad, Init, Latlon
0353
0354 C End of common block variables and declaration.
0355 C ///////////////////////////////////////////////////
0356
0357 e1 = Badreal
0358 e2 = Badreal
0359 e3 = Badreal
0360
0361
0362 C // verify initialized module
0363
0364 if(.not.Init) then
0365 NVXSAE = -6
0366 return
0367 end if
0368
0369
0370 C // Compute radius and bearing from pole
0371
0372 dx = Scale*(lin-Lin0)
0373 dy = Scale*(ele-Ele0)
0374
0375 radius = sqrt(dx*dx+dy*dy)
0376 theta = atan2(dy,dx)
0377
0378
0379 C // Apply range checking on theta to determine if point is navigable
0380
0381 if ( theta.le.-Mxtheta .or. theta.gt.Mxtheta ) then
0382 NVXSAE = -1
0383 return
0384 end if
0385
0386 C // Forward navigation: compute longitude and colatitude
0387 C // from radius and theta
0388
0389 lon = Lon0 + theta/Coscl
0390 if(lon.le.-Pi) lon = lon + 2.d0*Pi
0391 if(lon.gt. Pi) lon = lon - 2.d0*Pi
0392
0393 colat = 2.*atan( Tancl2 * (radius/(Erad*Tancl))**(1./Coscl))
0394
0395 C // Rescale to McIDAS convention (degrees, West positive).
0396 C // Apply conversion to Cartesian coordinates if 'XYZ' set
0397 C // as output form. Set return code for success.
0398
0399 lon = -lon/D2R
0400 lat = 90. - colat/D2R
0401 hgt = 0.
0402
0403 if(.not.Latlon) then
0404 call nllxyz(lat,lon,e1,e2,e3)
0405 else
0406 e1 = lat
0407 e2 = lon
0408 e3 = 0.
0409 end if
0410
0411 NVXSAE = 0
0412
0413 return
0414 end
0415 *$ Name: 0416 *$ nvxeas - Compute image coordinates from earth coordinates 0417 *$ 0418 *$ Interface: 0419 *$ integer function 0420 *$ nvxeas( real e1, real e2, real e3, 0421 *$ real lin, real ele, real dummy) 0422 *$ 0423 *$ Input: 0424 *$ e1 - latitude or x 0425 *$ e2 - longitude or y 0426 *$ e3 - height or z 0427 *$ 0428 *$ Input and Output: 0429 *$ none 0430 *$ 0431 *$ Output: 0432 *$ lin - image line 0433 *$ ele - image element 0434 *$ dummy - (unused) 0435 *$ 0436 *$ Return values: 0437 *$ 0 - success 0438 *$ -1 - input data physically valid but not navigable 0439 *$ given the specified projection 0440 *$ -2 - input data exceed physical limits 0441 *$ -6 - module not initialized 0442 *$ 0443 *$ Remarks: 0444 *$ The navigation module must first be initialized with 0445 *$ a call to nvxini(). The input form (lat,lon) or (x,y,z) 0446 *$ depends on the last call to nvxini() with option 2. 0447 *$ Input longitude may be in the range -360 to +360; 0448 *$ values outside this range will not be de-navigated. 0449 *$ Height (hgt) is ignored. 0450 *$ 0451 *$ Categories: 0452 *$ navigation 0453 0454 INTEGER FUNCTION NVXEAS( e1, e2, e3, lin, ele, dummy) 0455 0456 implicit NONE 0457 0458 C // Interface variables (formal arguments) 0459 0460 real e1 ! Earth coordinate 1 0461 real e2 ! Earth coordinate 2 0462 real e3 ! Earth coordinate 3 0463 real lin ! image line to navigate 0464 real ele ! image element to navigate 0465 real dummy ! (unused argument) 0466 0467 C // Local variables 0468 0469 real lat ! latitude (McIDAS convention) 0470 real lon ! longitude (McIDAS convention) 0471 real hgt ! height 0472 real in_lon ! input longitude (radians, 0473 C ! East positive) 0474 real colat ! colatitude 0475 real radius ! distance from pole on projection 0476 real theta ! angle from standard longitude on 0477 C ! projection surface 0478 0479 C //////////////////////////////////////////////////////// 0480 C Common block variables and declaration. 0481 0482 C ALL CODE BETWEEN THE '//////' SEPARATORS MUST BE 0483 C DUPLICATED EXACTLY IN EACH NAVIGATION ROUTINE 0484 0485 C (A more maintenance-safe version would use ENTRY points 0486 C rather than separate functions for the navigation API 0487 C but entry points cannot be processed by 'convdlm.') 0488 0489 C // Common block contents: projection parameters 0490 0491 real Lin0 ! image line of pole 0492 real Ele0 ! image element of pole 0493 real Scale ! km per unit image coordinate 0494 C ! (pixel) 0495 real Lon0 ! standard longitude 0496 real Colat0 ! standard colatitude 0497 0498 C // Common block contents: precomputed intermediate values 0499 0500 real Coscl ! cosine(Colat0) 0501 real Tancl ! tangent(Colat0) 0502 real Tancl2 ! tangent(Colat0/2) 0503 real Mxtheta ! limit of angle from std. lon 0504 C ! on projection surface 0505 0506 C // Common block contents: constants 0507 0508 real D2R ! degrees to radians factor 0509 real Pi 0510 real Badreal ! returned when navigation 0511 C ! cannot be done 0512 real Erad ! Earth radius 0513 logical Init ! initialized flag 0514 logical Latlon ! .TRUE. for lat/lon I/O 0515 0516 0517 COMMON/TANC/ Lin0, Ele0, Scale, Lon0, Colat0, 0518 & Coscl, Tancl, Tancl2, Mxtheta, 0519 & D2R, Pi, Badreal, Erad, Init, Latlon 0520 0521 C End of common block variables and declaration. 0522 C ///////////////////////////////////////////////////// 0523 0524 lin = Badreal 0525 ele = Badreal 0526 dummy = Badreal 0527 0528 C // verify that module is initialized 0529 0530 if(.not.init) then 0531 NVXEAS = -6 0532 return 0533 end if 0534 0535 C // Preprocess input values. If mode is 'XYZ' first convert 0536 C // from Cartesian to lat/lon. If mode is 'LL' just transcribe 0537 C // from arguments. 0538 0539 if(Latlon) then 0540 lat = e1 0541 lon = e2 0542 hgt = e3 0543 else 0544 call nxyzll( e1, e2, e3, lat, lon) 0545 hgt = 0. 0546 end if 0547 0548 C // check that input values are physically possible and 0549 C // then convert to radians and East positive 0550 0551 if ( lat.lt.-90. .or. lat.gt.90. ) then 0552 NVXEAS = -2 0553 return 0554 end if
0555 if( lon.le.-360..or.lon.gt.360.) then 0556 NVXEAS = -2 0557 return 0558 end if 0559 0560 if( lat.eq.-90. .or. lat.eq.90. ) then 0561 NVXEAS = -1 0562 return 0563 end if 0564 0565 colat = Pi/2. - D2R*lat 0566 in_lon = -D2R*lon 0567 0568 C // map longitude into range -Pi to Pi 0569 0570 if(in_lon.le.-Pi) in_lon = in_lon + 2.*Pi 0571 if(in_lon.gt. Pi) in_lon = in_lon - 2.*Pi 0572 0573 0574 C // Now trap South Pole. Though a physically possible latitude, 0575 C // tan(colat/2) -> infinity there so it is not navigable 0576 0577 if ( colat.eq.Pi ) then 0578 NVXEAS = -1 0579 return 0580 end if 0581 0582 0583 C // Compute radius and theta of point on projection surface. 0584 C // Theta is tricky; you have to compute offset relative 0585 C // to standard longitude, force that into -pi to +pi range, 0586 C // and THEN scale by cos(Colat0) 0587 0588 radius = Erad * Tancl *( tan(colat/2.)/Tancl2 ) ** Coscl 0589 theta = in_lon-Lon0 0590 0591 if(theta.le.-Pi) theta = theta + 2.*Pi 0592 if(theta.gt. Pi) theta = theta - 2.*Pi 0593 0594 theta = Coscl * theta 0595 0596 0597 C // Compute line and element 0598 0599 lin = Lin0 + radius*cos(theta)/Scale 0600 ele = Ele0 + radius*sin(theta)/Scale 0601 dummy = 0. 0602 0603 NVXEAS = 0 0604 0605 return 0606 end 0607 0608 0609 *$ Name: 0610 *$ nvxopt - Perform supplemental navigation operations 0611 *$ 0612 *$ Interface: 0613 *$ integer function 0614 *$ nvxopt(integer option, real xin(*), 0615 *$ real xout(*) ) 0616 *$ Input: 0617 *$ option - 'SCAL' compute projection scale 0618 *$ xin(1) - latitude 0619 *$ 0620 *$ Input and Output: 0621 *$ none 0622 *$ 0623 *$ Output: 0624 *$ xout(1) - km per pixel at given latitude
0625 *$ Return values: 0626 *$ 0 - success 0627 *$ -1 - input latitude physically valid, but projection 0628 *$ undefined or scale infinite there 0629 *$ -2 - input latitude exceeds physical limits 0630 *$ -5 - unrecognized option 0631 *$ -6 - module not initialized 0632 *$ 0633 *$ Remarks: 0634 *$ The navigation module must first be initialized by 0635 *$ a call to nvxini(). Latitude is in degrees, north positive, 0636 *$ and must lie between -90. and +90. 0637 *$ 0638 *$ Categories: 0639 *$ navigation 0640 0641 INTEGER FUNCTION NVXOPT( option, xin, xout) 0642 0643 implicit NONE 0644 0645 C // Interface variables (formal arguments) 0646 0647 integer option ! special service name (character 0648 C ! stored as integer) 0649 real xin(*) ! input vector 0650 real xout(*) ! output vector 0651 0652 C // Local variables 0653 0654 character*4 copt ! special service (character form) 0655 real colat ! input colatitude 0656 0657 C //////////////////////////////////////////////////// 0658 C Common block variables and declaration. 0659 0660 C ALL CODE BETWEEN THE '//////' SEPARATORS MUST BE 0661 C DUPLICATED EXACTLY IN EACH NAVIGATION ROUTINE 0662 0663 C (A more maintenance-safe version would use ENTRY points 0664 C rather than separate functions for the navigation API 0665 C but entry points cannot be processed by 'convdlm.') 0666 0667 C // Common block contents: projection parameters 0668 0669 real Lin0 ! image line of pole 0670 real Ele0 ! image element of pole 0671 real Scale ! km per unit image coordinate 0672 C ! (pixel) 0673 real Lon0 ! standard longitude 0674 real Colat0 ! standard colatitude 0675 0676 C // Common block contents: precomputed intermediate values 0677 0678 real Coscl ! cosine(Colat0) 0679 real Tancl ! tangent(Colat0) 0680 real Tancl2 ! tangent(Colat0/2) 0681 real Mxtheta ! limit of angle from std. lon 0682 C ! on projection surface 0683 0684 C // Common block contents: constants 0685 0686 real D2R ! degrees to radians factor 0687 real Pi 0688 real Badreal ! returned when navigation 0689 C ! cannot be done 0690 real Erad ! Earth radius 0691 logical Init ! initialized flag 0692 logical Latlon ! .TRUE. for lat/lon I/O 0693 0694 0695 COMMON/TANC/ Lin0, Ele0, Scale, Lon0, Colat0, 0696 & Coscl, Tancl, Tancl2, Mxtheta, 0697 & D2R, Pi, Badreal, Erad, Init, Latlon 0698 0699 C End of common block variables and declaration. 0700 C //////////////////////////////////////////////////// 0701 0702 0703 xout(1) = Badreal 0704 0705 C // verify initialized module 0706 0707 if(.not.init) then 0708 NVXOPT = -6 0709 return 0710 end if 0711 0712 C // Extract and interpret the option 0713 0714 call movwc(option,copt) 0715 0716 if(copt.eq.'SCAL') then 0717 0718 C // Compute colatitude and make sure it is 0719 C // physically possible and navigable 0720 0721 if ( xin(1).gt.90. .or. xin(1).lt.-90. ) then 0722 NVXOPT = -2 0723 return 0724 else if ( xin(1).eq.90. .or. xin(1).eq.-90. ) then 0725 NVXOPT = -1 0726 return 0727 end if 0728 0729 colat = Pi/2. - D2R*xin(1) 0730 0731 C // Now compute actual scale for this colatitude 0732 0733 xout(1) = scale 0734 * *(sin(Colat0)*(tan(colat/2.)/Tancl2)**Coscl)/sin(colat) 0735 0736 C else if(copt.eq.'????') 0737 C // Add code for additional options here 0738 0739 else 0740 NVXOPT = -5 0741 return 0742 end if 0743 0744 NVXOPT = 0 0745 0746 return 0747 end
[Search Manual] [Table of Contents] [Go to Previous] [Go to Next]