int usage(int retval, bool brief) {
  if (brief)
    ( retval ? std::cerr : std::cout ) << "Usage:\n"
"    GeoidEval [ -n name ] [ -d dir ] [ -l ] [ -a | -c south west north east\n"
"    ] [ -w ] [ -z zone ] [ --msltohae ] [ --haetomsl ] [ -v ] [\n"
"    --comment-delimiter commentdelim ] [ --version | -h | --help ] [\n"
"    --input-file infile | --input-string instring ] [ --line-separator\n"
"    linesep ] [ --output-file outfile ]\n"
"\n"
"For full documentation type:\n"
"    GeoidEval --help\n"
"or visit:\n"
"    https://geographiclib.sourceforge.io/1.51/GeoidEval.1.html\n";
  else
    ( retval ? std::cerr : std::cout ) << "Man page:\n"
"NAME\n"
"       GeoidEval -- look up geoid heights\n"
"\n"
"SYNOPSIS\n"
"       GeoidEval [ -n name ] [ -d dir ] [ -l ] [ -a | -c south west north east\n"
"       ] [ -w ] [ -z zone ] [ --msltohae ] [ --haetomsl ] [ -v ] [\n"
"       --comment-delimiter commentdelim ] [ --version | -h | --help ] [\n"
"       --input-file infile | --input-string instring ] [ --line-separator\n"
"       linesep ] [ --output-file outfile ]\n"
"\n"
"DESCRIPTION\n"
"       GeoidEval reads in positions on standard input and prints out the\n"
"       corresponding heights of the geoid above the WGS84 ellipsoid on\n"
"       standard output.\n"
"\n"
"       Positions are given as latitude and longitude, UTM/UPS, or MGRS, in any\n"
"       of the formats accepted by GeoConvert(1).  (MGRS coordinates signify\n"
"       the center of the corresponding MGRS square.)  If the -z option is\n"
"       specified then the specified zone is prepended to each line of input\n"
"       (which must be in UTM/UPS coordinates).  This allows a file with UTM\n"
"       eastings and northings in a single zone to be used as standard input.\n"
"\n"
"       More accurate results for the geoid height are provided by Gravity(1).\n"
"       This utility can also compute the direction of gravity accurately.\n"
"\n"
"       The height of the geoid above the ellipsoid, N, is sometimes called the\n"
"       geoid undulation.  It can be used to convert a height above the\n"
"       ellipsoid, h, to the corresponding height above the geoid (the\n"
"       orthometric height, roughly the height above mean sea level), H, using\n"
"       the relations\n"
"\n"
"           h = N + H,   H = -N + h.\n"
"\n"
"OPTIONS\n"
"       -n name\n"
"           use geoid name instead of the default \"egm96-5\".  See \"GEOIDS\".\n"
"\n"
"       -d dir\n"
"           read geoid data from dir instead of the default.  See \"GEOIDS\".\n"
"\n"
"       -l  use bilinear interpolation instead of cubic.  See \"INTERPOLATION\".\n"
"\n"
"       -a  cache the entire data set in memory.  See \"CACHE\".\n"
"\n"
"       -c south west north east\n"
"           cache the data bounded by south west north east in memory.  The\n"
"           first two arguments specify the SW corner of the cache and the last\n"
"           two arguments specify the NE corner.  The -w flag specifies that\n"
"           longitude precedes latitude for these corners, provided that it\n"
"           appears before -c.  See \"CACHE\".\n"
"\n"
"       -w  toggle the longitude first flag (it starts off); if the flag is on,\n"
"           then when reading geographic coordinates, longitude precedes\n"
"           latitude (this can be overridden by a hemisphere designator, N, S,\n"
"           E, W).\n"
"\n"
"       -z zone\n"
"           prefix each line of input by zone, e.g., \"38n\".  This should be\n"
"           used when the input consists of UTM/UPS eastings and northings.\n"
"\n"
"       --msltohae\n"
"           standard input should include a final token on each line which is\n"
"           treated as a height (in meters) above the geoid and the output\n"
"           echoes the input line with the height converted to height above\n"
"           ellipsoid (HAE).  If -z zone is specified then the third token is\n"
"           treated as the height; this makes it possible to convert LIDAR data\n"
"           where each line consists of: easting northing height intensity.\n"
"\n"
"       --haetomsl\n"
"           this is similar to --msltohae except that the height token is\n"
"           treated as a height (in meters) above the ellipsoid and the output\n"
"           echoes the input line with the height converted to height above the\n"
"           geoid (MSL).\n"
"\n"
"       -v  print information about the geoid on standard error before\n"
"           processing the input.\n"
"\n"
"       --comment-delimiter commentdelim\n"
"           set the comment delimiter to commentdelim (e.g., \"#\" or \"//\").  If\n"
"           set, the input lines will be scanned for this delimiter and, if\n"
"           found, the delimiter and the rest of the line will be removed prior\n"
"           to processing and subsequently appended to the output line\n"
"           (separated by a space).\n"
"\n"
"       --version\n"
"           print version and exit.\n"
"\n"
"       -h  print usage, the default geoid path and name, and exit.\n"
"\n"
"       --help\n"
"           print full documentation and exit.\n"
"\n"
"       --input-file infile\n"
"           read input from the file infile instead of from standard input; a\n"
"           file name of \"-\" stands for standard input.\n"
"\n"
"       --input-string instring\n"
"           read input from the string instring instead of from standard input.\n"
"           All occurrences of the line separator character (default is a\n"
"           semicolon) in instring are converted to newlines before the reading\n"
"           begins.\n"
"\n"
"       --line-separator linesep\n"
"           set the line separator character to linesep.  By default this is a\n"
"           semicolon.\n"
"\n"
"       --output-file outfile\n"
"           write output to the file outfile instead of to standard output; a\n"
"           file name of \"-\" stands for standard output.\n"
"\n"
"GEOIDS\n"
"       GeoidEval computes geoid heights by interpolating on the data in a\n"
"       regularly spaced table (see \"INTERPOLATION\").  The following geoid\n"
"       tables are available (however, some may not be installed):\n"
"\n"
"                                         bilinear error    cubic error\n"
"          name         geoid    grid     max      rms      max      rms\n"
"          egm84-30     EGM84    30'      1.546 m  70 mm    0.274 m  14 mm\n"
"          egm84-15     EGM84    15'      0.413 m  18 mm    0.021 m  1.2 mm\n"
"          egm96-15     EGM96    15'      1.152 m  40 mm    0.169 m  7.0 mm\n"
"          egm96-5      EGM96     5'      0.140 m  4.6 mm   .0032 m  0.7 mm\n"
"          egm2008-5    EGM2008   5'      0.478 m  12 mm    0.294 m  4.5 mm\n"
"          egm2008-2_5  EGM2008   2.5'    0.135 m  3.2 mm   0.031 m  0.8 mm\n"
"          egm2008-1    EGM2008   1'      0.025 m  0.8 mm   .0022 m  0.7 mm\n"
"\n"
"       By default, the \"egm96-5\" geoid is used.  This may changed by setting\n"
"       the environment variable \"GEOGRAPHICLIB_GEOID_NAME\" or with the -n\n"
"       option.  The errors listed here are estimates of the quantization and\n"
"       interpolation errors in the reported heights compared to the specified\n"
"       geoid.\n"
"\n"
"       The geoid data will be loaded from a directory specified at compile\n"
"       time.  This may changed by setting the environment variables\n"
"       \"GEOGRAPHICLIB_GEOID_PATH\" or \"GEOGRAPHICLIB_DATA\", or with the -d\n"
"       option.  The -h option prints the default geoid path and name.  Use the\n"
"       -v option to ascertain the full path name of the data file.\n"
"\n"
"       Instructions for downloading and installing geoid data are available at\n"
"       <https://geographiclib.sourceforge.io/html/geoid.html#geoidinst>.\n"
"\n"
"       NOTE: all the geoids above apply to the WGS84 ellipsoid (a = 6378137 m,\n"
"       f = 1/298.257223563) only.\n"
"\n"
"INTERPOLATION\n"
"       Cubic interpolation is used to compute the geoid height unless -l is\n"
"       specified in which case bilinear interpolation is used.  The cubic\n"
"       interpolation is based on a least-squares fit of a cubic polynomial to\n"
"       a 12-point stencil\n"
"\n"
"          . 1 1 .\n"
"          1 2 2 1\n"
"          1 2 2 1\n"
"          . 1 1 .\n"
"\n"
"       The cubic is constrained to be independent of longitude when evaluating\n"
"       the height at one of the poles.  Cubic interpolation is considerably\n"
"       more accurate than bilinear; however it results in small\n"
"       discontinuities in the returned height on cell boundaries.\n"
"\n"
"CACHE\n"
"       By default, the data file is randomly read to compute the geoid heights\n"
"       at the input positions.  Usually this is sufficient for interactive\n"
"       use.  If many heights are to be computed, use -c south west north east\n"
"       to notify GeoidEval to read a rectangle of data into memory; heights\n"
"       within the this rectangle can then be computed without any disk access.\n"
"       If -a is specified all the geoid data is read; in the case of\n"
"       \"egm2008-1\", this requires about 0.5 GB of RAM.  The evaluation of\n"
"       heights outside the cached area causes the necessary data to be read\n"
"       from disk.  Use the -v option to verify the size of the cache.\n"
"\n"
"       Regardless of whether any cache is requested (with the -a or -c\n"
"       options), the data for the last grid cell in cached.  This allows the\n"
"       geoid height along a continuous path to be returned with little disk\n"
"       overhead.\n"
"\n"
"ENVIRONMENT\n"
"       GEOGRAPHICLIB_GEOID_NAME\n"
"           Override the compile-time default geoid name of \"egm96-5\".  The -h\n"
"           option reports the value of GEOGRAPHICLIB_GEOID_NAME, if defined,\n"
"           otherwise it reports the compile-time value.  If the -n name option\n"
"           is used, then name takes precedence.\n"
"\n"
"       GEOGRAPHICLIB_GEOID_PATH\n"
"           Override the compile-time default geoid path.  This is typically\n"
"           \"/usr/local/share/GeographicLib/geoids\" on Unix-like systems and\n"
"           \"C:/ProgramData/GeographicLib/geoids\" on Windows systems.  The -h\n"
"           option reports the value of GEOGRAPHICLIB_GEOID_PATH, if defined,\n"
"           otherwise it reports the compile-time value.  If the -d dir option\n"
"           is used, then dir takes precedence.\n"
"\n"
"       GEOGRAPHICLIB_DATA\n"
"           Another way of overriding the compile-time default geoid path.  If\n"
"           it is set (and if GEOGRAPHICLIB_GEOID_PATH is not set), then\n"
"           $GEOGRAPHICLIB_DATA/geoids is used.\n"
"\n"
"ERRORS\n"
"       An illegal line of input will print an error message to standard output\n"
"       beginning with \"ERROR:\" and causes GeoidEval to return an exit code of\n"
"       1.  However, an error does not cause GeoidEval to terminate; following\n"
"       lines will be converted.\n"
"\n"
"ABBREVIATIONS\n"
"       The geoid is usually approximated by an \"earth gravity model\". The\n"
"       models published by the NGA are:\n"
"\n"
"       EGM84\n"
"           An earth gravity model published by the NGA in 1984,\n"
"           <http://earth-info.nga.mil/GandG/wgs84/gravitymod/wgs84_180/wgs84_180.html>.\n"
"\n"
"       EGM96\n"
"           An earth gravity model published by the NGA in 1996,\n"
"           <http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm96/egm96.html>.\n"
"\n"
"       EGM2008\n"
"           An earth gravity model published by the NGA in 2008,\n"
"           <http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008>.\n"
"\n"
"       WGS84\n"
"           World Geodetic System 1984, <https://en.wikipedia.org/wiki/WGS84>.\n"
"\n"
"       HAE Height above the WGS84 ellipsoid.\n"
"\n"
"       MSL Mean sea level, used as a convenient short hand for the geoid.\n"
"           (However, typically, the geoid differs by a few meters from mean\n"
"           sea level.)\n"
"\n"
"EXAMPLES\n"
"       The height of the EGM96 geoid at Timbuktu\n"
"\n"
"           echo 16:46:33N 3:00:34W | GeoidEval\n"
"           => 28.7068 -0.02e-6 -1.73e-6\n"
"\n"
"       The first number returned is the height of the geoid and the 2nd and\n"
"       3rd are its slopes in the northerly and easterly directions.\n"
"\n"
"       Convert a point in UTM zone 18n from MSL to HAE\n"
"\n"
"          echo 531595 4468135 23 | GeoidEval --msltohae -z 18n\n"
"          => 531595 4468135 -10.842\n"
"\n"
"SEE ALSO\n"
"       GeoConvert(1), Gravity(1), geographiclib-get-geoids(8).\n"
"\n"
"       An online version of this utility is availbable at\n"
"       <https://geographiclib.sourceforge.io/cgi-bin/GeoidEval>.\n"
"\n"
"AUTHOR\n"
"       GeoidEval was written by Charles Karney.\n"
"\n"
"HISTORY\n"
"       GeoidEval was added to GeographicLib,\n"
"       <https://geographiclib.sourceforge.io>, in 2009-09.\n"
;
  return retval;
}
