"Fossies" - the Fresh Open Source Software Archive

Member "proj-6.2.1/src/proj_internal.h" (28 Oct 2019, 34654 Bytes) of package /linux/privat/proj-6.2.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "proj_internal.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 6.2.0_vs_6.2.1.

    1 /******************************************************************************
    2  * Project:  PROJ.4
    3  * Purpose:  Internal plumbing for the PROJ.4 library.
    4  *
    5  * Author:   Thomas Knudsen, <thokn@sdfe.dk>
    6  *
    7  ******************************************************************************
    8  * Copyright (c) 2016, 2017, Thomas Knudsen / SDFE
    9  *
   10  * Permission is hereby granted, free of charge, to any person obtaining a
   11  * copy of this software and associated documentation files (the "Software"),
   12  * to deal in the Software without restriction, including without limitation
   13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   14  * and/or sell copies of the Software, and to permit persons to whom the
   15  * Software is furnished to do so, subject to the following conditions:
   16  *
   17  * The above copyright notice and this permission notice shall be included
   18  * in all copies or substantial portions of the Software.
   19  *
   20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO COORD SHALL
   23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   26  * DEALINGS IN THE SOFTWARE.
   27  *****************************************************************************/
   28 
   29 #ifndef PROJ_INTERNAL_H
   30 #define PROJ_INTERNAL_H
   31 
   32 #ifndef __cplusplus
   33 #error "proj_internal.h can only be included from a C++ file"
   34 #endif
   35 
   36 #ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
   37 #define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
   38 #endif
   39 
   40 #ifdef _MSC_VER
   41 #  ifndef _CRT_SECURE_NO_DEPRECATE
   42 #    define _CRT_SECURE_NO_DEPRECATE
   43 #  endif
   44 #  ifndef _CRT_NONSTDC_NO_DEPRECATE
   45 #    define _CRT_NONSTDC_NO_DEPRECATE
   46 #  endif
   47 /* enable predefined math constants M_* for MS Visual Studio workaround */
   48 #  ifndef _USE_MATH_DEFINES
   49 #     define _USE_MATH_DEFINES
   50 #  endif
   51 #endif
   52 
   53 /* standard inclusions */
   54 #include <limits.h>
   55 #include <math.h>
   56 #include <stddef.h>
   57 #include <stdio.h>
   58 #include <stdlib.h>
   59 #include <string.h>
   60 
   61 #include "proj/common.hpp"
   62 #include "proj/coordinateoperation.hpp"
   63 
   64 #include <string>
   65 #include <vector>
   66 
   67 #include "proj.h"
   68 
   69 #ifdef PROJ_API_H
   70 #error proj_internal.h must be included before proj_api.h
   71 #endif
   72 
   73 #ifdef PROJ_RENAME_SYMBOLS
   74 #include "proj_symbol_rename.h"
   75 #endif
   76 
   77 #define STATIC_ASSERT(COND) ((void)sizeof(char[(COND) ? 1 : -1]))
   78 
   79 #if !defined(HAVE_C99_MATH)
   80 #define HAVE_C99_MATH 0
   81 #endif
   82 
   83 #ifndef PJ_TODEG
   84 #define PJ_TODEG(rad)  ((rad)*180.0/M_PI)
   85 #endif
   86 #ifndef PJ_TORAD
   87 #define PJ_TORAD(deg)  ((deg)*M_PI/180.0)
   88 #endif
   89 
   90 /* Maximum latitudinal overshoot accepted */
   91 #define PJ_EPS_LAT 1e-12
   92 
   93 #define C_NAMESPACE extern "C"
   94 #define C_NAMESPACE_VAR extern "C"
   95 
   96 #ifndef NULL
   97 #  define NULL 0
   98 #endif
   99 
  100 #ifndef FALSE
  101 #  define FALSE 0
  102 #endif
  103 
  104 #ifndef TRUE
  105 #  define TRUE  1
  106 #endif
  107 
  108 #ifndef MAX
  109 #  define MIN(a,b)      ((a<b) ? a : b)
  110 #  define MAX(a,b)      ((a>b) ? a : b)
  111 #endif
  112 
  113 #ifndef ABS
  114 #  define ABS(x)        ((x<0) ? (-1*(x)) : x)
  115 #endif
  116 
  117 #if INT_MAX == 2147483647
  118 typedef int pj_int32;
  119 #elif LONG_MAX == 2147483647
  120 typedef long pj_int32;
  121 #else
  122 #warning It seems no 32-bit integer type is available
  123 #endif
  124 
  125 /* maximum path/filename */
  126 #ifndef MAX_PATH_FILENAME
  127 #define MAX_PATH_FILENAME 1024
  128 #endif
  129 
  130 /* If we still haven't got M_PI*, we rely on our own defines.
  131  * For example, this is necessary when compiling with gcc and
  132  * the -ansi flag.
  133  */
  134 #ifndef M_PI
  135 #define M_PI            3.14159265358979323846
  136 #define M_PI_2          1.57079632679489661923
  137 #define M_PI_4          0.78539816339744830962
  138 #define M_2_PI          0.63661977236758134308
  139 #endif
  140 
  141 /* M_SQRT2 might be missing */
  142 #ifndef M_SQRT2
  143 #define M_SQRT2         1.41421356237309504880
  144 #endif
  145 
  146 /* some more useful math constants and aliases */
  147 #define M_FORTPI        M_PI_4                   /* pi/4 */
  148 #define M_HALFPI        M_PI_2                   /* pi/2 */
  149 #define M_PI_HALFPI     4.71238898038468985769   /* 1.5*pi */
  150 #define M_TWOPI         6.28318530717958647693   /* 2*pi */
  151 #define M_TWO_D_PI      M_2_PI                   /* 2/pi */
  152 #define M_TWOPI_HALFPI  7.85398163397448309616   /* 2.5*pi */
  153 
  154 
  155 /* maximum tag id length for +init and default files */
  156 #ifndef ID_TAG_MAX
  157 #define ID_TAG_MAX 50
  158 #endif
  159 
  160 /* Use WIN32 as a standard windows 32 bit declaration */
  161 #if defined(_WIN32) && !defined(WIN32)
  162 #  define WIN32
  163 #endif
  164 
  165 #if defined(_WINDOWS) && !defined(WIN32)
  166 #  define WIN32
  167 #endif
  168 
  169 /* directory delimiter for DOS support */
  170 #ifdef WIN32
  171 #define DIR_CHAR '\\'
  172 #else
  173 #define DIR_CHAR '/'
  174 #endif
  175 
  176 enum pj_io_units {
  177     PJ_IO_UNITS_WHATEVER  = 0,  /* Doesn't matter (or depends on pipeline neighbours) */
  178     PJ_IO_UNITS_CLASSIC   = 1,  /* Scaled meters (right), projected system */
  179     PJ_IO_UNITS_PROJECTED = 2,  /* Meters, projected system */
  180     PJ_IO_UNITS_CARTESIAN = 3,  /* Meters, 3D cartesian system */
  181     PJ_IO_UNITS_RADIANS   = 4   /* Radians */
  182 };
  183 enum pj_io_units pj_left (PJ *P);
  184 enum pj_io_units pj_right (PJ *P);
  185 
  186 PJ_COORD PROJ_DLL proj_coord_error (void);
  187 
  188 void proj_context_errno_set (PJ_CONTEXT *ctx, int err);
  189 void PROJ_DLL proj_context_set (PJ *P, PJ_CONTEXT *ctx);
  190 void proj_context_inherit (PJ *parent, PJ *child);
  191 
  192 struct projCppContext;
  193 /* not sure why we need to export it, but mingw needs it */
  194 void PROJ_DLL proj_context_delete_cpp_context(struct projCppContext* cppContext);
  195 
  196 PJ_COORD pj_fwd4d (PJ_COORD coo, PJ *P);
  197 PJ_COORD pj_inv4d (PJ_COORD coo, PJ *P);
  198 
  199 PJ_COORD PROJ_DLL pj_approx_2D_trans (PJ *P, PJ_DIRECTION direction, PJ_COORD coo);
  200 PJ_COORD PROJ_DLL pj_approx_3D_trans (PJ *P, PJ_DIRECTION direction, PJ_COORD coo);
  201 
  202 
  203 /* Grid functionality */
  204 int             proj_vgrid_init(PJ *P, const char *grids);
  205 int             proj_hgrid_init(PJ *P, const char *grids);
  206 double          proj_vgrid_value(PJ *P, PJ_LP lp, double vmultiplier);
  207 PJ_LP           proj_hgrid_value(PJ *P, PJ_LP lp);
  208 PJ_LP           proj_hgrid_apply(PJ *P, PJ_LP lp, PJ_DIRECTION direction);
  209 
  210 void PROJ_DLL proj_log_error (PJ *P, const char *fmt, ...);
  211 void proj_log_debug (PJ *P, const char *fmt, ...);
  212 void proj_log_trace (PJ *P, const char *fmt, ...);
  213 
  214 void proj_context_log_debug (PJ_CONTEXT *ctx, const char *fmt, ...);
  215 
  216 int pj_ellipsoid (PJ *);
  217 void pj_inherit_ellipsoid_def (const PJ *src, PJ *dst);
  218 int pj_calc_ellipsoid_params (PJ *P, double a, double es);
  219 
  220 /* Geographical to geocentric latitude - another of the "simple, but useful" */
  221 PJ_COORD pj_geocentric_latitude (const PJ *P, PJ_DIRECTION direction, PJ_COORD coord);
  222 
  223 char  PROJ_DLL *pj_chomp (char *c);
  224 char  PROJ_DLL *pj_shrink (char *c);
  225 size_t pj_trim_argc (char *args);
  226 char **pj_trim_argv (size_t argc, char *args);
  227 char  *pj_make_args (size_t argc, char **argv);
  228 
  229 /* Lowest level: Minimum support for fileapi */
  230 void proj_fileapi_set (PJ *P, void *fileapi);
  231 
  232 typedef struct { double r, i; } COMPLEX;
  233 
  234 /* Forward declarations and typedefs for stuff needed inside the PJ object */
  235 struct PJconsts;
  236 
  237 union  PJ_COORD;
  238 struct geod_geodesic;
  239 struct ARG_list;
  240 struct PJ_REGION_S;
  241 typedef struct PJ_REGION_S  PJ_Region;
  242 typedef struct ARG_list paralist;   /* parameter list */
  243 
  244 #ifndef PROJ_H
  245 typedef struct PJconsts PJ;         /* the PJ object herself */
  246 typedef union  PJ_COORD PJ_COORD;
  247 #endif
  248 
  249 struct PJ_REGION_S {
  250     double ll_long;        /* lower left corner coordinates (radians) */
  251     double ll_lat;
  252     double ur_long;        /* upper right corner coordinates (radians) */
  253     double ur_lat;
  254 };
  255 
  256 struct PJ_AREA {
  257     int     bbox_set;
  258     double  west_lon_degree;
  259     double  south_lat_degree;
  260     double  east_lon_degree;
  261     double  north_lat_degree;
  262 };
  263 
  264 struct projCtx_t;
  265 typedef struct projCtx_t projCtx_t;
  266 
  267 /*****************************************************************************
  268 
  269     Some function types that are especially useful when working with PJs
  270 
  271 ******************************************************************************
  272 
  273 PJ_CONSTRUCTOR:
  274 
  275     A function taking a pointer-to-PJ as arg, and returning a pointer-to-PJ.
  276     Historically called twice: First with a 0 argument, to allocate memory,
  277     second with the first return value as argument, for actual setup.
  278 
  279 PJ_DESTRUCTOR:
  280 
  281     A function taking a pointer-to-PJ and an integer as args, then first
  282     handling the deallocation of the PJ, afterwards handing the integer over
  283     to the error reporting subsystem, and finally returning a null pointer in
  284     support of the "return free (P)" (aka "get the hell out of here") idiom.
  285 
  286 PJ_OPERATOR:
  287 
  288     A function taking a PJ_COORD and a pointer-to-PJ as args, applying the
  289     PJ to the PJ_COORD, and returning the resulting PJ_COORD.
  290 
  291 *****************************************************************************/
  292 typedef    PJ       *(* PJ_CONSTRUCTOR) (PJ *);
  293 typedef    PJ       *(* PJ_DESTRUCTOR)  (PJ *, int);
  294 typedef    PJ_COORD  (* PJ_OPERATOR)    (PJ_COORD, PJ *);
  295 /****************************************************************************/
  296 
  297 
  298 /* datum_type values */
  299 #define PJD_UNKNOWN   0
  300 #define PJD_3PARAM    1
  301 #define PJD_7PARAM    2
  302 #define PJD_GRIDSHIFT 3
  303 #define PJD_WGS84     4   /* WGS84 (or anything considered equivalent) */
  304 
  305 
  306 /* base projection data structure */
  307 struct PJconsts {
  308 
  309     /*************************************************************************************
  310 
  311                          G E N E R A L   P A R A M E T E R   S T R U C T
  312 
  313     **************************************************************************************
  314 
  315         TODO: Need some description here - especially about the thread context...
  316         This is the struct behind the PJ typedef
  317 
  318     **************************************************************************************/
  319 
  320     projCtx_t *ctx = nullptr;
  321     const char *descr = nullptr;   /* From pj_list.h or individual PJ_*.c file */
  322     paralist *params = nullptr;    /* Parameter list */
  323     char *def_full = nullptr;      /* Full textual definition (usually 0 - set by proj_pj_info) */
  324     PJconsts *parent = nullptr;    /* Parent PJ of pipeline steps - nullptr if not a pipeline step */
  325 
  326     /* For debugging / logging purposes */
  327     char *def_size = nullptr;      /* Shape and size parameters extracted from params */
  328     char *def_shape = nullptr;
  329     char *def_spherification = nullptr;
  330     char *def_ellps = nullptr;
  331 
  332     struct geod_geodesic *geod = nullptr;    /* For geodesic computations */
  333     void *opaque = nullptr;                  /* Projection specific parameters, Defined in PJ_*.c */
  334     int inverted = 0;                        /* Tell high level API functions to swap inv/fwd */
  335 
  336 
  337     /*************************************************************************************
  338 
  339                           F U N C T I O N    P O I N T E R S
  340 
  341     **************************************************************************************
  342 
  343         For projection xxx, these are pointers to functions in the corresponding
  344         PJ_xxx.c file.
  345 
  346         pj_init() delegates the setup of these to pj_projection_specific_setup_xxx(),
  347         a name which is currently hidden behind the magic curtain of the PROJECTION
  348         macro.
  349 
  350     **************************************************************************************/
  351 
  352 
  353     PJ_XY  (*fwd)(PJ_LP,    PJ *) = nullptr;
  354     PJ_LP  (*inv)(PJ_XY,    PJ *) = nullptr;
  355     PJ_XYZ (*fwd3d)(PJ_LPZ, PJ *) = nullptr;
  356     PJ_LPZ (*inv3d)(PJ_XYZ, PJ *) = nullptr;
  357     PJ_OPERATOR fwd4d = nullptr;
  358     PJ_OPERATOR inv4d = nullptr;
  359 
  360     PJ_DESTRUCTOR destructor = nullptr;
  361 
  362 
  363     /*************************************************************************************
  364 
  365                           E L L I P S O I D     P A R A M E T E R S
  366 
  367     **************************************************************************************
  368 
  369         Despite YAGNI, we add a large number of ellipsoidal shape parameters, which
  370         are not yet set up in pj_init. They are, however, inexpensive to compute,
  371         compared to the overall time taken for setting up the complex PJ object
  372         (cf. e.g. https://en.wikipedia.org/wiki/Angular_eccentricity).
  373 
  374         But during single point projections it will often be a useful thing to have
  375         these readily available without having to recompute at every pj_fwd / pj_inv
  376         call.
  377 
  378         With this wide selection, we should be ready for quite a number of geodetic
  379         algorithms, without having to incur further ABI breakage.
  380 
  381     **************************************************************************************/
  382 
  383     /* The linear parameters */
  384 
  385     double  a = 0.0;                   /* semimajor axis (radius if eccentricity==0) */
  386     double  b = 0.0;                   /* semiminor axis */
  387     double  ra = 0.0;                  /* 1/a */
  388     double  rb = 0.0;                  /* 1/b */
  389 
  390     /* The eccentricities */
  391 
  392     double  alpha = 0.0;               /* angular eccentricity */
  393     double  e = 0.0;                   /* first  eccentricity */
  394     double  es = 0.0;                  /* first  eccentricity squared */
  395     double  e2 = 0.0;                  /* second eccentricity */
  396     double  e2s = 0.0;                 /* second eccentricity squared */
  397     double  e3 = 0.0;                  /* third  eccentricity */
  398     double  e3s = 0.0;                 /* third  eccentricity squared */
  399     double  one_es = 0.0;              /* 1 - e^2 */
  400     double  rone_es = 0.0;             /* 1/one_es */
  401 
  402 
  403     /* The flattenings */
  404     double  f = 0.0;                   /* first  flattening */
  405     double  f2 = 0.0;                  /* second flattening */
  406     double  n = 0.0;                   /* third  flattening */
  407     double  rf = 0.0;                  /* 1/f  */
  408     double  rf2 = 0.0;                 /* 1/f2 */
  409     double  rn = 0.0;                   /* 1/n  */
  410 
  411     /* This one's for GRS80 */
  412     double  J = 0.0;                   /* "Dynamic form factor" */
  413 
  414     double  es_orig = 0.0;    /* es and a before any +proj related adjustment */
  415     double  a_orig = 0.0;
  416 
  417 
  418     /*************************************************************************************
  419 
  420                           C O O R D I N A T E   H A N D L I N G
  421 
  422     **************************************************************************************/
  423 
  424     int  over = 0;                  /* Over-range flag */
  425     int  geoc = 0;                  /* Geocentric latitude flag */
  426     int  is_latlong = 0;            /* proj=latlong ... not really a projection at all */
  427     int  is_geocent = 0;            /* proj=geocent ... not really a projection at all */
  428     int  is_pipeline = 0;           /* 1 if PJ represents a pipeline */
  429     int  need_ellps = 0;            /* 0 for operations that are purely cartesian */
  430     int  skip_fwd_prepare = 0;
  431     int  skip_fwd_finalize = 0;
  432     int  skip_inv_prepare = 0;
  433     int  skip_inv_finalize = 0;
  434 
  435     enum pj_io_units left =  PJ_IO_UNITS_WHATEVER; /* Flags for input/output coordinate types */
  436     enum pj_io_units right =  PJ_IO_UNITS_WHATEVER;
  437 
  438     /* These PJs are used for implementing cs2cs style coordinate handling in the 4D API */
  439     PJ *axisswap = nullptr;
  440     PJ *cart = nullptr;
  441     PJ *cart_wgs84 = nullptr;
  442     PJ *helmert = nullptr;
  443     PJ *hgridshift = nullptr;
  444     PJ *vgridshift = nullptr;
  445 
  446 
  447     /*************************************************************************************
  448 
  449                        C A R T O G R A P H I C       O F F S E T S
  450 
  451     **************************************************************************************/
  452 
  453     double  lam0 = 0.0;    /* central meridian */
  454     double  phi0 = 0.0;    /* central parallel */
  455     double  x0 = 0.0;      /* false easting */
  456     double  y0 = 0.0;      /* false northing  */
  457     double  z0 = 0.0;      /* height origin */
  458     double  t0 = 0.0;      /* time origin */
  459 
  460 
  461     /*************************************************************************************
  462 
  463                                     S C A L I N G
  464 
  465     **************************************************************************************/
  466 
  467     double  k0 = 0.0;                  /* General scaling factor - e.g. the 0.9996 of UTM */
  468     double  to_meter = 0.0, fr_meter = 0.0;        /* Plane coordinate scaling. Internal unit [m] */
  469     double  vto_meter = 0.0, vfr_meter = 0.0;      /* Vertical scaling. Internal unit [m] */
  470 
  471 
  472     /*************************************************************************************
  473 
  474                   D A T U M S   A N D   H E I G H T   S Y S T E M S
  475 
  476     **************************************************************************************
  477 
  478         It may be possible, and meaningful, to move the list parts of this up to the
  479         PJ_CONTEXT level.
  480 
  481     **************************************************************************************/
  482 
  483     int     datum_type = PJD_UNKNOWN;  /* PJD_UNKNOWN/3PARAM/7PARAM/GRIDSHIFT/WGS84 */
  484     double  datum_params[7] = {0,0,0,0,0,0,0}; /* Parameters for 3PARAM and 7PARAM */
  485     struct _pj_gi **gridlist = nullptr;     /* TODO: Description needed */
  486     int     gridlist_count = 0;
  487 
  488     int     has_geoid_vgrids = 0;      /* TODO: Description needed */
  489     struct _pj_gi **vgridlist_geoid = nullptr;   /* TODO: Description needed */
  490     int     vgridlist_geoid_count = 0;
  491 
  492     double  from_greenwich = 0.0;       /* prime meridian offset (in radians) */
  493     double  long_wrap_center = 0.0;     /* 0.0 for -180 to 180, actually in radians*/
  494     int     is_long_wrap_set = 0;
  495     char    axis[4] = {0,0,0,0};        /* Axis order, pj_transform/pj_adjust_axis */
  496 
  497     /* New Datum Shift Grid Catalogs */
  498     char   *catalog_name = nullptr;
  499     struct _PJ_GridCatalog *catalog = nullptr;
  500 
  501     double  datum_date = 0.0;           /* TODO: Description needed */
  502 
  503     struct _pj_gi *last_before_grid = nullptr;    /* TODO: Description needed */
  504     PJ_Region     last_before_region = {0,0,0,0}; /* TODO: Description needed */
  505     double        last_before_date = 0.0;         /* TODO: Description needed */
  506 
  507     struct _pj_gi *last_after_grid = nullptr;     /* TODO: Description needed */
  508     PJ_Region     last_after_region = {0,0,0,0};  /* TODO: Description needed */
  509     double        last_after_date = 0.0;          /* TODO: Description needed */
  510 
  511     /*************************************************************************************
  512      ISO-19111 interface
  513     **************************************************************************************/
  514 
  515     NS_PROJ::common::IdentifiedObjectPtr iso_obj{};
  516 
  517     // cached results
  518     mutable std::string lastWKT{};
  519     mutable std::string lastPROJString{};
  520     mutable std::string lastJSONString{};
  521     mutable bool gridsNeededAsked = false;
  522     mutable std::vector<NS_PROJ::operation::GridDescription> gridsNeeded{};
  523 
  524     /*************************************************************************************
  525      proj_create_crs_to_crs() alternative coordinate operations
  526     **************************************************************************************/
  527 
  528     struct CoordOperation
  529     {
  530         double minxSrc = 0.0;
  531         double minySrc = 0.0;
  532         double maxxSrc = 0.0;
  533         double maxySrc = 0.0;
  534         double minxDst = 0.0;
  535         double minyDst = 0.0;
  536         double maxxDst = 0.0;
  537         double maxyDst = 0.0;
  538         PJ* pj = nullptr;
  539         std::string name{};
  540 
  541         CoordOperation(double minxSrcIn, double minySrcIn, double maxxSrcIn, double maxySrcIn,
  542                        double minxDstIn, double minyDstIn, double maxxDstIn, double maxyDstIn,
  543                        PJ* pjIn, const std::string& nameIn):
  544             minxSrc(minxSrcIn), minySrc(minySrcIn), maxxSrc(maxxSrcIn), maxySrc(maxySrcIn),
  545             minxDst(minxDstIn), minyDst(minyDstIn), maxxDst(maxxDstIn), maxyDst(maxyDstIn),
  546             pj(pjIn), name(nameIn) {}
  547 
  548         CoordOperation(const CoordOperation&) = delete;
  549 
  550         CoordOperation(CoordOperation&& other):
  551             minxSrc(other.minxSrc), minySrc(other.minySrc), maxxSrc(other.maxxSrc), maxySrc(other.maxySrc),
  552             minxDst(other.minxDst), minyDst(other.minyDst), maxxDst(other.maxxDst), maxyDst(other.maxyDst),
  553             name(std::move(other.name)) {
  554                 pj = other.pj;
  555                 other.pj = nullptr;
  556             }
  557 
  558         CoordOperation& operator=(const CoordOperation&) = delete;
  559 
  560         ~CoordOperation()
  561         {
  562             proj_destroy(pj);
  563         }
  564     };
  565     std::vector<CoordOperation> alternativeCoordinateOperations{};
  566     int iCurCoordOp = -1;
  567 
  568     /*************************************************************************************
  569 
  570                  E N D   O F    G E N E R A L   P A R A M E T E R   S T R U C T
  571 
  572     **************************************************************************************/
  573 
  574     PJconsts();
  575     PJconsts(const PJconsts &) = delete;
  576     PJconsts &operator=(const PJconsts &) = delete;
  577 };
  578 
  579 
  580 
  581 
  582 /* Parameter list (a copy of the +proj=... etc. parameters) */
  583 struct ARG_list {
  584     paralist *next;
  585     char used;
  586 #if defined(__GNUC__) && __GNUC__ >= 8
  587     char param[]; /* variable-length member */
  588     /* Safer to use [] for gcc 8. See https://github.com/OSGeo/proj.4/pull/1087 */
  589     /* and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86914 */
  590 #else
  591     char param[1]; /* variable-length member */
  592 #endif
  593 };
  594 
  595 
  596 typedef union { double  f; int  i; char *s; } PROJVALUE;
  597 
  598 
  599 struct PJ_DATUMS {
  600     const char    *id;           /* datum keyword */
  601     const char    *defn;         /* ie. "to_wgs84=..." */
  602     const char    *ellipse_id;   /* ie from ellipse table */
  603     const char    *comments;     /* EPSG code, etc */
  604 };
  605 
  606 
  607 struct DERIVS {
  608     double x_l, x_p;       /* derivatives of x for lambda-phi */
  609     double y_l, y_p;       /* derivatives of y for lambda-phi */
  610 };
  611 
  612 struct FACTORS {
  613     struct DERIVS der;
  614     double h, k;           /* meridional, parallel scales */
  615     double omega, thetap;  /* angular distortion, theta prime */
  616     double conv;           /* convergence */
  617     double s;              /* areal scale factor */
  618     double a, b;           /* max-min scale error */
  619     int    code;           /* always 0 */
  620 };
  621 
  622 /* library errors */
  623 #define PJD_ERR_NO_ARGS                  -1
  624 #define PJD_ERR_NO_OPTION_IN_INIT_FILE   -2
  625 #define PJD_ERR_NO_COLON_IN_INIT_STRING  -3
  626 #define PJD_ERR_PROJ_NOT_NAMED           -4
  627 #define PJD_ERR_UNKNOWN_PROJECTION_ID    -5
  628 #define PJD_ERR_INVALID_ECCENTRICITY     -6
  629 #define PJD_ERR_UNKNOWN_UNIT_ID          -7
  630 #define PJD_ERR_INVALID_BOOLEAN_PARAM    -8
  631 #define PJD_ERR_UNKNOWN_ELLP_PARAM       -9
  632 #define PJD_ERR_REV_FLATTENING_IS_ZERO  -10
  633 #define PJD_ERR_REF_RAD_LARGER_THAN_90  -11
  634 #define PJD_ERR_ES_LESS_THAN_ZERO       -12
  635 #define PJD_ERR_MAJOR_AXIS_NOT_GIVEN    -13
  636 #define PJD_ERR_LAT_OR_LON_EXCEED_LIMIT -14
  637 #define PJD_ERR_INVALID_X_OR_Y          -15
  638 #define PJD_ERR_WRONG_FORMAT_DMS_VALUE  -16
  639 #define PJD_ERR_NON_CONV_INV_MERI_DIST  -17
  640 #define PJD_ERR_NON_CON_INV_PHI2        -18
  641 #define PJD_ERR_ACOS_ASIN_ARG_TOO_LARGE -19
  642 #define PJD_ERR_TOLERANCE_CONDITION     -20
  643 #define PJD_ERR_CONIC_LAT_EQUAL         -21
  644 #define PJD_ERR_LAT_LARGER_THAN_90      -22
  645 #define PJD_ERR_LAT1_IS_ZERO            -23
  646 #define PJD_ERR_LAT_TS_LARGER_THAN_90   -24
  647 #define PJD_ERR_CONTROL_POINT_NO_DIST   -25
  648 #define PJD_ERR_NO_ROTATION_PROJ        -26
  649 #define PJD_ERR_W_OR_M_ZERO_OR_LESS     -27
  650 #define PJD_ERR_LSAT_NOT_IN_RANGE       -28
  651 #define PJD_ERR_PATH_NOT_IN_RANGE       -29
  652 #define PJD_ERR_INVALID_H               -30
  653 #define PJD_ERR_K_LESS_THAN_ZERO        -31
  654 #define PJD_ERR_LAT_1_OR_2_ZERO_OR_90   -32
  655 #define PJD_ERR_LAT_0_OR_ALPHA_EQ_90    -33
  656 #define PJD_ERR_ELLIPSOID_USE_REQUIRED  -34
  657 #define PJD_ERR_INVALID_UTM_ZONE        -35
  658 /* -36 no longer used */
  659 #define PJD_ERR_FAILED_TO_FIND_PROJ     -37
  660 #define PJD_ERR_FAILED_TO_LOAD_GRID     -38
  661 #define PJD_ERR_INVALID_M_OR_N          -39
  662 #define PJD_ERR_N_OUT_OF_RANGE          -40
  663 #define PJD_ERR_LAT_1_2_UNSPECIFIED     -41
  664 #define PJD_ERR_ABS_LAT1_EQ_ABS_LAT2    -42
  665 #define PJD_ERR_LAT_0_HALF_PI_FROM_MEAN -43
  666 #define PJD_ERR_UNPARSEABLE_CS_DEF      -44
  667 #define PJD_ERR_GEOCENTRIC              -45
  668 #define PJD_ERR_UNKNOWN_PRIME_MERIDIAN  -46
  669 #define PJD_ERR_AXIS                    -47
  670 #define PJD_ERR_GRID_AREA               -48
  671 #define PJD_ERR_INVALID_SWEEP_AXIS      -49
  672 #define PJD_ERR_MALFORMED_PIPELINE      -50
  673 #define PJD_ERR_UNIT_FACTOR_LESS_THAN_0 -51
  674 #define PJD_ERR_INVALID_SCALE           -52
  675 #define PJD_ERR_NON_CONVERGENT          -53
  676 #define PJD_ERR_MISSING_ARGS            -54
  677 #define PJD_ERR_LAT_0_IS_ZERO           -55
  678 #define PJD_ERR_ELLIPSOIDAL_UNSUPPORTED -56
  679 #define PJD_ERR_TOO_MANY_INITS          -57
  680 #define PJD_ERR_INVALID_ARG             -58
  681 #define PJD_ERR_INCONSISTENT_UNIT       -59
  682 #define PJD_ERR_MUTUALLY_EXCLUSIVE_ARGS -60
  683 #define PJD_ERR_GENERIC_ERROR           -61
  684 /* NOTE: Remember to update src/strerrno.cpp, src/apps/gie.cpp and transient_error in */
  685 /* src/transform.cpp when adding new value */
  686 
  687 struct projFileAPI_t;
  688 
  689 struct projCppContext;
  690 
  691 /* proj thread context */
  692 struct projCtx_t {
  693     int     last_errno = 0;
  694     int     debug_level = 0;
  695     void    (*logger)(void *, int, const char *) = nullptr;
  696     void    *logger_app_data = nullptr;
  697     struct projFileAPI_t *fileapi = nullptr;
  698     struct projCppContext* cpp_context = nullptr; /* internal context for C++ code */
  699     int     use_proj4_init_rules = -1; /* -1 = unknown, 0 = no, 1 = yes */
  700     int     epsg_file_exists = -1; /* -1 = unknown, 0 = no, 1 = yes */
  701 
  702     std::vector<std::string> search_paths{};
  703     const char **c_compat_paths = nullptr; // same, but for projinfo usage
  704 
  705     const char* (*file_finder_legacy) (const char*) = nullptr; // Only for proj_api compat. To remove once it is removed
  706     const char* (*file_finder) (PJ_CONTEXT *, const char*, void* user_data) = nullptr;
  707     void* file_finder_user_data = nullptr;
  708 
  709     int projStringParserCreateFromPROJStringRecursionCounter = 0; // to avoid potential infinite recursion in PROJStringParser::createFromPROJString()
  710 
  711     projCtx_t() = default;
  712     projCtx_t(const projCtx_t&);
  713     ~projCtx_t();
  714 
  715     projCtx_t& operator= (const projCtx_t&) = delete;
  716 
  717     void set_search_paths(const std::vector<std::string>& search_paths_in);
  718 
  719     static projCtx_t createDefault();
  720 };
  721 
  722 /* Generate pj_list external or make list from include file */
  723 #ifndef PJ_DATUMS__
  724 C_NAMESPACE_VAR struct PJ_DATUMS pj_datums[];
  725 #endif
  726 
  727 
  728 
  729 
  730 
  731 #ifdef PJ_LIB__
  732 #define PROJ_HEAD(name, desc) static const char des_##name [] = desc
  733 
  734 #define OPERATION(name, NEED_ELPJ_LPS)                          \
  735                                                              \
  736 pj_projection_specific_setup_##name (PJ *P);                 \
  737 C_NAMESPACE PJ *pj_##name (PJ *P);                           \
  738                                                              \
  739 C_NAMESPACE_VAR const char * const pj_s_##name = des_##name; \
  740                                                              \
  741 C_NAMESPACE PJ *pj_##name (PJ *P) {                          \
  742     if (P)                                                   \
  743         return pj_projection_specific_setup_##name (P);      \
  744     P = pj_new();                                            \
  745     if (nullptr==P)                                          \
  746         return nullptr;                                      \
  747     P->descr = des_##name;                                   \
  748     P->need_ellps = NEED_ELPJ_LPS;                              \
  749     P->left  = PJ_IO_UNITS_RADIANS;                          \
  750     P->right = PJ_IO_UNITS_CLASSIC;                          \
  751     return P;                                                \
  752 }                                                            \
  753                                                              \
  754 PJ *pj_projection_specific_setup_##name (PJ *P)
  755 
  756 /* In ISO19000 lingo, an operation is either a conversion or a transformation */
  757 #define CONVERSION(name, need_ellps)      OPERATION (name, need_ellps)
  758 #define TRANSFORMATION(name, need_ellps)  OPERATION (name, need_ellps)
  759 
  760 /* In PROJ.4 a projection is a conversion taking angular input and giving scaled linear output */
  761 #define PROJECTION(name) CONVERSION (name, 1)
  762 
  763 #endif /* def PJ_LIB__ */
  764 
  765 
  766 #define MAX_TAB_ID 80
  767 typedef struct { float lam, phi; } FLP;
  768 typedef struct { pj_int32 lam, phi; } ILP;
  769 
  770 struct CTABLE {
  771     char id[MAX_TAB_ID];    /* ascii info */
  772     PJ_LP ll;               /* lower left corner coordinates */
  773     PJ_LP del;              /* size of cells */
  774     ILP lim;                /* limits of conversion matrix */
  775     FLP *cvs;               /* conversion matrix */
  776 };
  777 
  778 typedef struct _pj_gi {
  779     char *gridname;     /* identifying name of grid, eg "conus" or ntv2_0.gsb */
  780     char *filename;     /* full path to filename */
  781 
  782     const char *format; /* format of this grid, ie "ctable", "ntv1",
  783                            "ntv2" or "missing". */
  784 
  785     long   grid_offset;  /* offset in file, for delayed loading */
  786     int   must_swap;    /* only for NTv2 */
  787 
  788     struct CTABLE *ct;
  789 
  790     struct _pj_gi *next;
  791     struct _pj_gi *child;
  792 } PJ_GRIDINFO;
  793 
  794 typedef struct {
  795     PJ_Region region;
  796     int  priority;      /* higher used before lower */
  797     double date;        /* year.fraction */
  798     char *definition;   /* usually the gridname */
  799 
  800     PJ_GRIDINFO  *gridinfo;
  801     int available;      /* 0=unknown, 1=true, -1=false */
  802 } PJ_GridCatalogEntry;
  803 
  804 typedef struct _PJ_GridCatalog {
  805     char *catalog_name;
  806 
  807     PJ_Region region;   /* maximum extent of catalog data */
  808 
  809     int entry_count;
  810     PJ_GridCatalogEntry *entries;
  811 
  812     struct _PJ_GridCatalog *next;
  813 } PJ_GridCatalog;
  814 
  815 /* procedure prototypes */
  816 double PROJ_DLL dmstor(const char *, char **);
  817 double dmstor_ctx(projCtx_t *ctx, const char *, char **);
  818 void   PROJ_DLL set_rtodms(int, int);
  819 char  PROJ_DLL *rtodms(char *, double, int, int);
  820 double PROJ_DLL adjlon(double);
  821 double aacos(projCtx_t *,double);
  822 double aasin(projCtx_t *,double);
  823 double asqrt(double);
  824 double aatan2(double, double);
  825 
  826 PROJVALUE PROJ_DLL pj_param(projCtx_t *ctx, paralist *, const char *);
  827 paralist PROJ_DLL *pj_param_exists (paralist *list, const char *parameter);
  828 paralist PROJ_DLL *pj_mkparam(const char *);
  829 paralist *pj_mkparam_ws (const char *str, const char **next_str);
  830 
  831 
  832 int PROJ_DLL pj_ell_set(projCtx_t *ctx, paralist *, double *, double *);
  833 int pj_datum_set(projCtx_t *,paralist *, PJ *);
  834 int pj_angular_units_set(paralist *, PJ *);
  835 
  836 paralist *pj_clone_paralist( const paralist* );
  837 paralist *pj_search_initcache( const char *filekey );
  838 void      pj_insert_initcache( const char *filekey, const paralist *list);
  839 paralist *pj_expand_init(projCtx_t *ctx, paralist *init);
  840 
  841 void     *pj_dealloc_params (projCtx_t *ctx, paralist *start, int errlev);
  842 
  843 
  844 double *pj_enfn(double);
  845 double  pj_mlfn(double, double, double, double *);
  846 double  pj_inv_mlfn(projCtx_t *, double, double, double *);
  847 double  pj_qsfn(double, double, double);
  848 double  pj_tsfn(double, double, double);
  849 double  pj_msfn(double, double, double);
  850 double  PROJ_DLL pj_phi2(projCtx_t *, double, double);
  851 double  pj_qsfn_(double, PJ *);
  852 double *pj_authset(double);
  853 double  pj_authlat(double, double *);
  854 
  855 COMPLEX pj_zpoly1(COMPLEX, const COMPLEX *, int);
  856 COMPLEX pj_zpolyd1(COMPLEX, const COMPLEX *, int, COMPLEX *);
  857 
  858 int pj_deriv(PJ_LP, double, const PJ *, struct DERIVS *);
  859 int pj_factors(PJ_LP, const PJ *, double, struct FACTORS *);
  860 
  861 /* nadcon related protos */
  862 PJ_LP             nad_intr(PJ_LP, struct CTABLE *);
  863 PJ_LP             nad_cvt(PJ_LP, int, struct CTABLE *);
  864 struct CTABLE *nad_init(projCtx_t *ctx, char *);
  865 struct CTABLE *nad_ctable_init( projCtx_t *ctx, struct projFileAPI_t* fid );
  866 int            nad_ctable_load( projCtx_t *ctx, struct CTABLE *, struct projFileAPI_t* fid );
  867 struct CTABLE *nad_ctable2_init( projCtx_t *ctx, struct projFileAPI_t* fid );
  868 int            nad_ctable2_load( projCtx_t *ctx, struct CTABLE *, struct projFileAPI_t* fid );
  869 void           nad_free(struct CTABLE *);
  870 
  871 /* higher level handling of datum grid shift files */
  872 
  873 int pj_apply_vgridshift( PJ *defn, const char *listname,
  874                          PJ_GRIDINFO ***gridlist_p,
  875                          int *gridlist_count_p,
  876                          int inverse,
  877                          long point_count, int point_offset,
  878                          double *x, double *y, double *z );
  879 int pj_apply_gridshift_2( PJ *defn, int inverse,
  880                           long point_count, int point_offset,
  881                           double *x, double *y, double *z );
  882 int pj_apply_gridshift_3( projCtx_t *ctx,
  883                           PJ_GRIDINFO **gridlist, int gridlist_count,
  884                           int inverse, long point_count, int point_offset,
  885                           double *x, double *y, double *z );
  886 
  887 PJ_GRIDINFO **pj_gridlist_from_nadgrids( projCtx_t *, const char *, int * );
  888 
  889 PJ_GRIDINFO *pj_gridinfo_init( projCtx_t *, const char * );
  890 int          pj_gridinfo_load( projCtx_t *, PJ_GRIDINFO * );
  891 void         pj_gridinfo_free( projCtx_t *, PJ_GRIDINFO * );
  892 
  893 PJ_GridCatalog *pj_gc_findcatalog( projCtx_t *, const char * );
  894 PJ_GridCatalog *pj_gc_readcatalog( projCtx_t *, const char * );
  895 void pj_gc_unloadall( projCtx_t *);
  896 int pj_gc_apply_gridshift( PJ *defn, int inverse,
  897                            long point_count, int point_offset,
  898                            double *x, double *y, double *z );
  899 int pj_gc_apply_gridshift( PJ *defn, int inverse,
  900                            long point_count, int point_offset,
  901                            double *x, double *y, double *z );
  902 
  903 double pj_gc_parsedate( projCtx_t *, const char * );
  904 
  905 void  *proj_mdist_ini(double);
  906 double proj_mdist(double, double, double, const void *);
  907 double proj_inv_mdist(projCtx_t *ctx, double, const void *);
  908 void  *pj_gauss_ini(double, double, double *,double *);
  909 PJ_LP     pj_gauss(projCtx_t *, PJ_LP, const void *);
  910 PJ_LP     pj_inv_gauss(projCtx_t *, PJ_LP, const void *);
  911 
  912 struct PJ_DATUMS           PROJ_DLL *pj_get_datums_ref( void );
  913 
  914 PJ *pj_new(void);
  915 PJ *pj_default_destructor (PJ *P, int errlev);
  916 
  917 double PROJ_DLL pj_atof( const char* nptr );
  918 double pj_strtod( const char *nptr, char **endptr );
  919 void   pj_freeup_plain (PJ *P);
  920 
  921 PJ* pj_init_ctx_with_allow_init_epsg( projCtx_t *ctx, int argc, char **argv, int allow_init_epsg );
  922 
  923 std::string PROJ_DLL pj_add_type_crs_if_needed(const std::string& str);
  924 std::string pj_double_quote_string_param_if_needed(const std::string& str);
  925 
  926 PJ *pj_create_internal (PJ_CONTEXT *ctx, const char *definition);
  927 PJ *pj_create_argv_internal (PJ_CONTEXT *ctx, int argc, char **argv);
  928 
  929 /* classic public API */
  930 #include "proj_api.h"
  931 
  932 #endif /* ndef PROJ_INTERNAL_H */