aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKristian Evers <kristianevers@gmail.com>2020-12-13 15:30:47 +0100
committerKristian Evers <kristianevers@gmail.com>2020-12-13 15:30:47 +0100
commitc3efbd23a5bf26f1dfd5bc55ae3488d5665ace98 (patch)
treea204df79f7057d7d420bf7c5358791347617b9cd /src
parent126445148d3b742c7f4e31f5f65857be59c48340 (diff)
parent6857d1a4a8eb6fcb7b88b0339413913ba2c3351a (diff)
downloadPROJ-c3efbd23a5bf26f1dfd5bc55ae3488d5665ace98.tar.gz
PROJ-c3efbd23a5bf26f1dfd5bc55ae3488d5665ace98.zip
Merge remote-tracking branch 'osgeo/master'
Diffstat (limited to 'src')
-rw-r--r--src/4D_api.cpp83
-rw-r--r--src/Makefile.am13
-rw-r--r--src/aasincos.cpp8
-rw-r--r--src/apps/cct.cpp97
-rw-r--r--src/apps/cs2cs.cpp190
-rw-r--r--src/apps/emess.cpp6
-rw-r--r--src/apps/geod.cpp1
-rw-r--r--src/apps/geod_set.cpp2
-rw-r--r--src/apps/gie.cpp10
-rw-r--r--src/apps/proj.cpp31
-rw-r--r--src/apps/projinfo.cpp43
-rw-r--r--src/auth.cpp2
-rw-r--r--src/bin_projinfo.cmake4
-rw-r--r--src/conversions/axisswap.cpp2
-rw-r--r--src/conversions/set.cpp2
-rw-r--r--src/conversions/topocentric.cpp165
-rw-r--r--src/conversions/unitconvert.cpp2
-rw-r--r--src/ctx.cpp163
-rw-r--r--src/datum_set.cpp22
-rw-r--r--src/dmstor.cpp6
-rw-r--r--src/ell_set.cpp46
-rw-r--r--src/errno.cpp18
-rw-r--r--src/fileapi.cpp240
-rw-r--r--src/filemanager.cpp149
-rw-r--r--src/gauss.cpp6
-rw-r--r--src/generic_inverse.cpp2
-rw-r--r--src/geodesic.c149
-rw-r--r--src/geodesic.h6
-rw-r--r--src/grids.cpp123
-rw-r--r--src/init.cpp155
-rw-r--r--src/initcache.cpp20
-rw-r--r--src/internal.cpp13
-rw-r--r--src/iso19111/c_api.cpp70
-rw-r--r--src/iso19111/coordinateoperation.cpp575
-rw-r--r--src/iso19111/crs.cpp97
-rw-r--r--src/iso19111/datum.cpp30
-rw-r--r--src/iso19111/factory.cpp391
-rw-r--r--src/iso19111/io.cpp201
-rw-r--r--src/lib_proj.cmake6
-rw-r--r--src/log.cpp6
-rw-r--r--src/malloc.cpp138
-rw-r--r--src/mlfn.cpp4
-rw-r--r--src/mlfn.hpp4
-rw-r--r--src/mutex.cpp25
-rw-r--r--src/networkfilemanager.cpp6
-rw-r--r--src/param.cpp8
-rw-r--r--src/phi2.cpp182
-rw-r--r--src/pipeline.cpp12
-rw-r--r--src/pj_list.h1
-rw-r--r--src/pr_list.cpp8
-rw-r--r--src/proj.h13
-rw-r--r--src/proj_api.h227
-rw-r--r--src/proj_constants.h20
-rw-r--r--src/proj_internal.h123
-rw-r--r--src/proj_mdist.cpp4
-rw-r--r--src/projections/adams.cpp2
-rw-r--r--src/projections/aea.cpp6
-rw-r--r--src/projections/aeqd.cpp4
-rw-r--r--src/projections/airy.cpp2
-rw-r--r--src/projections/aitoff.cpp6
-rw-r--r--src/projections/bacon.cpp6
-rw-r--r--src/projections/bertin1953.cpp2
-rw-r--r--src/projections/bipc.cpp2
-rw-r--r--src/projections/bonne.cpp4
-rw-r--r--src/projections/calcofi.cpp1
-rw-r--r--src/projections/cass.cpp4
-rw-r--r--src/projections/ccon.cpp4
-rw-r--r--src/projections/cea.cpp4
-rw-r--r--src/projections/chamb.cpp6
-rw-r--r--src/projections/col_urban.cpp2
-rw-r--r--src/projections/comill.cpp2
-rw-r--r--src/projections/eck3.cpp8
-rw-r--r--src/projections/eqc.cpp2
-rw-r--r--src/projections/eqdc.cpp4
-rw-r--r--src/projections/eqearth.cpp6
-rw-r--r--src/projections/fouc_s.cpp2
-rw-r--r--src/projections/geos.cpp2
-rw-r--r--src/projections/gn_sinu.cpp10
-rw-r--r--src/projections/gnom.cpp2
-rw-r--r--src/projections/goode.cpp6
-rw-r--r--src/projections/gstmerc.cpp20
-rw-r--r--src/projections/hammer.cpp2
-rw-r--r--src/projections/healpix.cpp14
-rw-r--r--src/projections/igh.cpp2
-rw-r--r--src/projections/igh_o.cpp2
-rw-r--r--src/projections/imw_p.cpp4
-rw-r--r--src/projections/isea.cpp2
-rw-r--r--src/projections/krovak.cpp4
-rw-r--r--src/projections/labrd.cpp2
-rw-r--r--src/projections/laea.cpp4
-rw-r--r--src/projections/lagrng.cpp2
-rw-r--r--src/projections/lcc.cpp12
-rw-r--r--src/projections/lcca.cpp4
-rw-r--r--src/projections/loxim.cpp2
-rw-r--r--src/projections/lsat.cpp2
-rw-r--r--src/projections/merc.cpp30
-rw-r--r--src/projections/misrsom.cpp2
-rw-r--r--src/projections/mod_ster.cpp10
-rw-r--r--src/projections/moll.cpp6
-rw-r--r--src/projections/natearth.cpp2
-rw-r--r--src/projections/natearth2.cpp2
-rw-r--r--src/projections/nsper.cpp4
-rw-r--r--src/projections/ob_tran.cpp17
-rw-r--r--src/projections/ocea.cpp2
-rw-r--r--src/projections/oea.cpp2
-rw-r--r--src/projections/omerc.cpp2
-rw-r--r--src/projections/ortho.cpp4
-rw-r--r--src/projections/patterson.cpp2
-rw-r--r--src/projections/poly.cpp4
-rw-r--r--src/projections/putp3.cpp4
-rw-r--r--src/projections/putp4p.cpp4
-rw-r--r--src/projections/putp5.cpp4
-rw-r--r--src/projections/putp6.cpp4
-rw-r--r--src/projections/qsc.cpp2
-rw-r--r--src/projections/robin.cpp2
-rw-r--r--src/projections/rouss.cpp4
-rw-r--r--src/projections/rpoly.cpp2
-rw-r--r--src/projections/sch.cpp2
-rw-r--r--src/projections/sconics.cpp2
-rw-r--r--src/projections/somerc.cpp2
-rw-r--r--src/projections/stere.cpp9
-rw-r--r--src/projections/sterea.cpp4
-rw-r--r--src/projections/sts.cpp8
-rw-r--r--src/projections/tmerc.cpp43
-rw-r--r--src/projections/tobmerc.cpp19
-rw-r--r--src/projections/tpeqd.cpp2
-rw-r--r--src/projections/urm5.cpp2
-rw-r--r--src/projections/urmfps.cpp4
-rw-r--r--src/projections/vandg2.cpp4
-rw-r--r--src/projections/wag3.cpp2
-rw-r--r--src/projections/wink1.cpp2
-rw-r--r--src/projections/wink2.cpp2
-rw-r--r--src/strerrno.cpp15
-rw-r--r--src/tests/multistresstest.cpp172
-rw-r--r--src/tests/test228.cpp113
-rw-r--r--src/transform.cpp1850
-rw-r--r--src/transformations/affine.cpp2
-rw-r--r--src/transformations/helmert.cpp2
-rw-r--r--src/transformations/horner.cpp10
-rw-r--r--src/transformations/molodensky.cpp2
-rw-r--r--src/tsfn.cpp32
-rw-r--r--src/utils.cpp182
-rw-r--r--src/wkt2_generated_parser.c1932
-rw-r--r--src/wkt2_grammar.y1
144 files changed, 3398 insertions, 5244 deletions
diff --git a/src/4D_api.cpp b/src/4D_api.cpp
index 86c0e071..d6eb901d 100644
--- a/src/4D_api.cpp
+++ b/src/4D_api.cpp
@@ -778,14 +778,14 @@ PJ *pj_create_internal (PJ_CONTEXT *ctx, const char *definition) {
argc = pj_trim_argc (args);
if (argc==0) {
- pj_dealloc (args);
+ free (args);
proj_context_errno_set(ctx, PJD_ERR_NO_ARGS);
return nullptr;
}
argv = pj_trim_argv (argc, args);
if (!argv) {
- pj_dealloc(args);
+ free(args);
proj_context_errno_set(ctx, ENOMEM);
return nullptr;
}
@@ -795,8 +795,8 @@ PJ *pj_create_internal (PJ_CONTEXT *ctx, const char *definition) {
allow_init_epsg = proj_context_get_use_proj4_init_rules(ctx, FALSE);
P = pj_init_ctx_with_allow_init_epsg (ctx, (int) argc, argv, allow_init_epsg);
- pj_dealloc (argv);
- pj_dealloc (args);
+ free (argv);
+ free (args);
/* Support cs2cs-style modifiers */
ret = cs2cs_emulation_setup (P);
@@ -834,7 +834,7 @@ indicator, as in {"+proj=utm", "+zone=32"}, or leave it out, as in {"proj=utm",
P = proj_create (ctx, c);
- pj_dealloc ((char *) c);
+ free ((char *) c);
return P;
}
@@ -862,13 +862,13 @@ Same as proj_create_argv() but calls pj_create_internal() instead of proj_create
P = pj_create_internal (ctx, c);
- pj_dealloc ((char *) c);
+ free ((char *) c);
return P;
}
/** Create an area of use */
PJ_AREA * proj_area_create(void) {
- return static_cast<PJ_AREA*>(pj_calloc(1, sizeof(PJ_AREA)));
+ return static_cast<PJ_AREA*>(calloc(1, sizeof(PJ_AREA)));
}
/** Assign a bounding box to an area of use. */
@@ -886,7 +886,7 @@ void proj_area_set_bbox(PJ_AREA *area,
/** Free an area of use */
void proj_area_destroy(PJ_AREA* area) {
- pj_dealloc(area);
+ free(area);
}
/************************************************************************/
@@ -1260,8 +1260,20 @@ std::vector<CoordOperation> pj_create_prepared_operations(PJ_CONTEXT *ctx,
}
}
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+static const char *getOptionValue(const char *option,
+ const char *keyWithEqual) noexcept {
+ if (ci_starts_with(option, keyWithEqual)) {
+ return option + strlen(keyWithEqual);
+ }
+ return nullptr;
+}
+//! @endcond
+
/*****************************************************************************/
-PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, const PJ *target_crs, PJ_AREA *area, const char* const *) {
+PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, const PJ *target_crs, PJ_AREA *area, const char* const * options) {
/******************************************************************************
Create a transformation pipeline between two known coordinate reference
systems.
@@ -1273,7 +1285,20 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons
ctx = pj_get_default_ctx();
}
- auto operation_ctx = proj_create_operation_factory_context(ctx, nullptr);
+ const char* authority = nullptr;
+ for (auto iter = options; iter && iter[0]; ++iter) {
+ const char *value;
+ if ((value = getOptionValue(*iter, "AUTHORITY="))) {
+ authority = value;
+ } else {
+ std::string msg("Unknown option :");
+ msg += *iter;
+ ctx->logger(ctx->logger_app_data, PJ_LOG_ERROR, msg.c_str());
+ return nullptr;
+ }
+ }
+
+ auto operation_ctx = proj_create_operation_factory_context(ctx, authority);
if( !operation_ctx ) {
return nullptr;
}
@@ -1287,9 +1312,11 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons
area->east_lon_degree,
area->north_lat_degree);
}
+ else {
+ proj_operation_factory_context_set_spatial_criterion(
+ ctx, operation_ctx, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
+ }
- proj_operation_factory_context_set_spatial_criterion(
- ctx, operation_ctx, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
proj_operation_factory_context_set_grid_availability_use(
ctx, operation_ctx,
proj_context_is_network_enabled(ctx) ?
@@ -1353,17 +1380,13 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons
return P;
}
-PJ *proj_destroy (PJ *P) {
- pj_free (P);
- return nullptr;
-}
/*****************************************************************************/
int proj_errno (const PJ *P) {
/******************************************************************************
Read an error level from the context of a PJ.
******************************************************************************/
- return pj_ctx_get_errno (pj_get_ctx ((PJ *) P));
+ return proj_context_errno (pj_get_ctx ((PJ *) P));
}
/*****************************************************************************/
@@ -1374,7 +1397,7 @@ int proj_context_errno (PJ_CONTEXT *ctx) {
******************************************************************************/
if (nullptr==ctx)
ctx = pj_get_default_ctx();
- return pj_ctx_get_errno (ctx);
+ return ctx->last_errno;
}
/*****************************************************************************/
@@ -1389,6 +1412,7 @@ int proj_errno_set (const PJ *P, int err) {
/* For P==0 err goes to the default context */
proj_context_errno_set (pj_get_ctx ((PJ *) P), err);
errno = err;
+
return err;
}
@@ -1439,16 +1463,15 @@ int proj_errno_reset (const PJ *P) {
int last_errno;
last_errno = proj_errno (P);
- pj_ctx_set_errno (pj_get_ctx ((PJ *) P), 0);
+ proj_context_errno_set (pj_get_ctx ((PJ *) P), 0);
errno = 0;
- pj_errno = 0;
return last_errno;
}
/* Create a new context based on the default context */
PJ_CONTEXT *proj_context_create (void) {
- return pj_ctx_alloc ();
+ return new (std::nothrow) pj_ctx(*pj_get_default_ctx());
}
@@ -1460,7 +1483,7 @@ PJ_CONTEXT *proj_context_destroy (PJ_CONTEXT *ctx) {
if (pj_get_default_ctx ()==ctx)
return nullptr;
- pj_ctx_free (ctx);
+ delete ctx;
return nullptr;
}
@@ -1499,15 +1522,15 @@ static char *path_append (char *buf, const char *app, size_t *buf_size) {
/* "pj_realloc", so to speak */
if (*buf_size < len) {
- p = static_cast<char*>(pj_calloc (2 * len, sizeof (char)));
+ p = static_cast<char*>(calloc (2 * len, sizeof (char)));
if (nullptr==p) {
- pj_dealloc (buf);
+ free (buf);
return nullptr;
}
*buf_size = 2 * len;
if (buf != nullptr)
strcpy (p, buf);
- pj_dealloc (buf);
+ free (buf);
buf = p;
}
assert(buf);
@@ -1560,7 +1583,7 @@ PJ_INFO proj_info (void) {
}
}
- pj_dalloc(const_cast<char*>(info.searchpath));
+ free(const_cast<char*>(info.searchpath));
info.searchpath = buf ? buf : empty;
info.paths = ctx ? ctx->c_compat_paths : nullptr;
@@ -1635,7 +1658,7 @@ PJ_PROJ_INFO proj_pj_info(PJ *P) {
pjinfo.definition = empty;
else
pjinfo.definition = pj_shrink (def);
- /* Make pj_free clean this up eventually */
+ /* Make proj_destroy clean this up eventually */
P->def_full = def;
pjinfo.has_inverse = pj_has_inverse(P);
@@ -1746,7 +1769,7 @@ PJ_INIT_INFO proj_init_info(const char *initname){
if( strcmp(initname, "epsg") == 0 || strcmp(initname, "EPSG") == 0 ) {
const char* val;
- pj_ctx_set_errno( ctx, 0 );
+ proj_context_errno_set( ctx, 0 );
strncpy (ininfo.name, initname, sizeof(ininfo.name) - 1);
strcpy(ininfo.origin, "EPSG");
@@ -1764,7 +1787,7 @@ PJ_INIT_INFO proj_init_info(const char *initname){
if( strcmp(initname, "IGNF") == 0 ) {
const char* val;
- pj_ctx_set_errno( ctx, 0 );
+ proj_context_errno_set( ctx, 0 );
strncpy (ininfo.name, initname, sizeof(ininfo.name) - 1);
strcpy(ininfo.origin, "IGNF");
@@ -1809,7 +1832,7 @@ PJ_INIT_INFO proj_init_info(const char *initname){
for ( ; start; start = next) {
next = start->next;
- pj_dalloc(start);
+ free(start);
}
return ininfo;
diff --git a/src/Makefile.am b/src/Makefile.am
index 5b36c8bd..83ee4adc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
AM_CFLAGS = @C_WFLAGS@
-EXTRA_PROGRAMS = multistresstest test228
+EXTRA_PROGRAMS = multistresstest
TESTS = geodtest
check_PROGRAMS = geodtest
@@ -9,7 +9,7 @@ AM_CPPFLAGS = -DPROJ_LIB=\"$(pkgdatadir)\" \
-DMUTEX_@MUTEX_SETTING@ -I$(top_srcdir)/include @SQLITE3_CFLAGS@ @TIFF_CFLAGS@ @TIFF_ENABLED_FLAGS@ @CURL_CFLAGS@ @CURL_ENABLED_FLAGS@
AM_CXXFLAGS = @CXX_WFLAGS@ @FLTO_FLAG@
-include_HEADERS = proj.h proj_experimental.h proj_constants.h proj_api.h geodesic.h \
+include_HEADERS = proj.h proj_experimental.h proj_constants.h geodesic.h \
proj_symbol_rename.h
EXTRA_DIST = bin_cct.cmake bin_gie.cmake bin_cs2cs.cmake \
@@ -36,7 +36,6 @@ bin_PROGRAMS = proj geod cs2cs gie cct projinfo $(PROJSYNC_BIN)
gie_SOURCES = apps/gie.cpp apps/proj_strtod.cpp apps/proj_strtod.h apps/optargpm.h
multistresstest_SOURCES = tests/multistresstest.cpp
-test228_SOURCES = tests/test228.cpp
geodtest_SOURCES = tests/geodtest.cpp
cct_LDADD = libproj.la
@@ -47,7 +46,6 @@ projinfo_LDADD = libproj.la
gie_LDADD = libproj.la
multistresstest_LDADD = libproj.la @THREAD_LIB@
-test228_LDADD = libproj.la @THREAD_LIB@
geodtest_LDADD = libproj.la
lib_LTLIBRARIES = libproj.la
@@ -187,6 +185,7 @@ libproj_la_SOURCES = \
conversions/geoc.cpp \
conversions/geocent.cpp \
conversions/noop.cpp \
+ conversions/topocentric.cpp \
conversions/set.cpp \
conversions/unitconvert.cpp \
\
@@ -209,19 +208,17 @@ libproj_la_SOURCES = \
\
aasincos.cpp adjlon.cpp \
dmstor.cpp auth.cpp \
- deriv.cpp ell_set.cpp ellps.cpp errno.cpp \
+ deriv.cpp ell_set.cpp ellps.cpp \
factors.cpp fwd.cpp init.cpp inv.cpp \
list.cpp malloc.cpp mlfn.cpp mlfn.hpp msfn.cpp proj_mdist.cpp \
param.cpp phi2.cpp pr_list.cpp \
qsfn.cpp strerrno.cpp \
tsfn.cpp units.cpp ctx.cpp log.cpp zpoly1.cpp rtodms.cpp \
release.cpp gauss.cpp \
- fileapi.cpp \
generic_inverse.cpp \
quadtree.hpp \
\
- datums.cpp datum_set.cpp transform.cpp \
- utils.cpp \
+ datums.cpp datum_set.cpp \
mutex.cpp initcache.cpp geodesic.c \
strtod.cpp \
\
diff --git a/src/aasincos.cpp b/src/aasincos.cpp
index 398a8cfc..c4314c67 100644
--- a/src/aasincos.cpp
+++ b/src/aasincos.cpp
@@ -9,24 +9,24 @@
#define ATOL 1e-50
double
-aasin(projCtx ctx,double v) {
+aasin(PJ_CONTEXT *ctx,double v) {
double av;
if ((av = fabs(v)) >= 1.) {
if (av > ONE_TOL)
- pj_ctx_set_errno( ctx, PJD_ERR_ACOS_ASIN_ARG_TOO_LARGE );
+ proj_context_errno_set( ctx, PJD_ERR_ACOS_ASIN_ARG_TOO_LARGE );
return (v < 0. ? -M_HALFPI : M_HALFPI);
}
return asin(v);
}
double
-aacos(projCtx ctx, double v) {
+aacos(PJ_CONTEXT *ctx, double v) {
double av;
if ((av = fabs(v)) >= 1.) {
if (av > ONE_TOL)
- pj_ctx_set_errno( ctx, PJD_ERR_ACOS_ASIN_ARG_TOO_LARGE );
+ proj_context_errno_set( ctx, PJD_ERR_ACOS_ASIN_ARG_TOO_LARGE );
return (v < 0. ? M_PI : 0.);
}
return acos(v);
diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp
index f7413872..4f21f10a 100644
--- a/src/apps/cct.cpp
+++ b/src/apps/cct.cpp
@@ -78,6 +78,9 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-10-26
#include <string.h>
#include <stdarg.h>
+#include <fstream> // std::ifstream
+#include <iostream>
+
#include "proj.h"
#include "proj_internal.h"
#include "proj_strtod.h"
@@ -193,9 +196,8 @@ static void print(PJ_LOG_LEVEL log_level, const char *fmt, ...) {
free( msg_buf );
}
-
int main(int argc, char **argv) {
- PJ *P;
+ PJ *P = nullptr;
PJ_COORD point;
PJ_PROJ_INFO info;
OPTARGS *o;
@@ -292,10 +294,73 @@ int main(int argc, char **argv) {
}
/* Setup transformation */
- P = proj_create_argv (nullptr, o->pargc, o->pargv);
- if ((nullptr==P) || (0==o->pargc)) {
+ if (o-> pargc == 0 && o->fargc > 0) {
+ std::string input(o->fargv[0]);
+
+ if (!input.empty() && input[0] == '@') {
+ std::ifstream fs;
+ auto filename = input.substr(1);
+ fs.open(filename, std::fstream::in | std::fstream::binary);
+ if (!fs.is_open()) {
+ std::cerr << "cannot open " << filename << std::endl;
+ std::exit(1);
+ }
+ input.clear();
+ while (!fs.eof()) {
+ char buffer[256];
+ fs.read(buffer, sizeof(buffer));
+ input.append(buffer, static_cast<size_t>(fs.gcount()));
+ if (input.size() > 100 * 1000) {
+ fs.close();
+ std::cerr << "too big file " << filename << std::endl;
+ std::exit(1);
+ }
+ }
+ fs.close();
+ }
+
+ /* Assume we got a auth:code combination */
+ auto n = input.find(":");
+ if (n > 0) {
+ std::string auth = input.substr(0,n);
+ std::string code = input.substr(n+1, input.length());
+ // Check that the authority matches one of the known ones
+ auto authorityList = proj_get_authorities_from_database(nullptr);
+ if( authorityList )
+ {
+ for( auto iter = authorityList; *iter; iter++ )
+ {
+ if( *iter == auth ) {
+ P = proj_create_from_database(
+ nullptr, auth.c_str(), code.c_str(),
+ PJ_CATEGORY_COORDINATE_OPERATION, 0, nullptr);
+ break;
+ }
+ }
+ proj_string_list_destroy(authorityList);
+ }
+ }
+ if( P == nullptr ) {
+ /* if we didn't get a auth:code combo we try to see if the input matches */
+ /* anything else */
+ P = proj_create(nullptr, input.c_str());
+ }
+
+ /* If instantiating operation without +-options optargpm thinks the input is */
+ /* a file, hence we move all o->fargv entries one place closer to the start */
+ /* of the array. This effectively overwrites the input and only leaves a list */
+ /* of files in o->fargv. */
+ o->fargc = o->fargc-1;
+ for (int j=0; j < o->fargc; j++) {
+ o->fargv[j] = o->fargv[j+1];
+ }
+ } else {
+ P = proj_create_argv (nullptr, o->pargc, o->pargv);
+ }
+
+ if (nullptr==P) {
print (PJ_LOG_ERROR, "%s: Bad transformation arguments - (%s)\n '%s -h' for help",
- o->progname, pj_strerrno (proj_errno(P)), o->progname);
+ o->progname, proj_errno_string (proj_errno(P)), o->progname);
free (o);
if (stdout != fout)
fclose (fout);
@@ -322,7 +387,7 @@ int main(int argc, char **argv) {
buf = static_cast<char*>(calloc (1, 10000));
if (nullptr==buf) {
print (PJ_LOG_ERROR, "%s: Out of memory", o->progname);
- pj_free (P);
+ proj_destroy (P);
free (o);
if (stdout != fout)
fclose (fout);
@@ -370,7 +435,7 @@ int main(int argc, char **argv) {
if (HUGE_VAL==point.xyzt.x) {
/* transformation error */
print (PJ_LOG_NONE, "# Record %d TRANSFORMATION ERROR: %s (%s)",
- (int) o->record_index, buf, pj_strerrno (proj_errno(P)));
+ (int) o->record_index, buf, proj_errno_string (proj_errno(P)));
proj_errno_restore (P, err);
continue;
}
@@ -385,12 +450,22 @@ int main(int argc, char **argv) {
colmax = MAX(colmax, columns_xyzt[i]);
comment = column(buf, colmax+1);
}
+ /* remove the line feed from comment, as logger() above, invoked
+ by print() below (output), will add one */
+ size_t len = strlen(comment);
+ if (len >= 1)
+ comment[len - 1] = '\0';
comment_delimiter = (comment && *comment) ? whitespace : blank_comment;
/* Time to print the result */
- if (proj_angular_output (P, direction)) {
- point.lpzt.lam = proj_todeg (point.lpzt.lam);
- point.lpzt.phi = proj_todeg (point.lpzt.phi);
+ /* use same arguments to printf format string for both radians and
+ degrees; convert radians to degrees before printing */
+ if (proj_angular_output (P, direction) ||
+ proj_degree_output (P, direction)) {
+ if (proj_angular_output (P, direction)) {
+ point.lpzt.lam = proj_todeg (point.lpzt.lam);
+ point.lpzt.phi = proj_todeg (point.lpzt.phi);
+ }
print (PJ_LOG_NONE, "%14.*f %14.*f %12.*f %12.4f%s%s",
decimals_angles, point.xyzt.x,
decimals_angles, point.xyzt.y,
@@ -405,6 +480,8 @@ int main(int argc, char **argv) {
decimals_distances, point.xyzt.z,
point.xyzt.t, comment_delimiter, comment
);
+ if( fout == stdout )
+ fflush(stdout);
}
proj_destroy(P);
diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp
index 58c164c9..409a5ef3 100644
--- a/src/apps/cs2cs.cpp
+++ b/src/apps/cs2cs.cpp
@@ -36,8 +36,13 @@
#include <string.h>
#include <cassert>
+#include <iostream>
#include <string>
+#include <proj/io.hpp>
+#include <proj/metadata.hpp>
+#include <proj/util.hpp>
+
#include <proj/internal/internal.hpp>
// PROJ include order is sensitive
@@ -70,12 +75,19 @@ static const char *oform =
static char oform_buffer[16]; /* buffer for oform when using -d */
static const char *oterr = "*\t*"; /* output line for unprojectable input */
static const char *usage =
- "%s\nusage: %s [-dDeEfIlrstvwW [args]] [+opt[=arg] ...]\n"
- " [+to +opt[=arg] ...] [file ...]\n";
+ "%s\nusage: %s [-dDeEfIlrstvwW [args]]\n"
+ " [[--area name_or_code] | [--bbox west_long,south_lat,east_long,north_lat]]\n"
+ " [--authority {name}]\n"
+ " [+opt[=arg] ...] [+to +opt[=arg] ...] [file ...]\n";
static double (*informat)(const char *,
char **); /* input data deformatter function */
+using namespace NS_PROJ::io;
+using namespace NS_PROJ::metadata;
+using namespace NS_PROJ::util;
+using namespace NS_PROJ::internal;
+
/************************************************************************/
/* process() */
/* */
@@ -217,6 +229,7 @@ static void process(FILE *fid)
printf("%s", s);
else
printf("\n");
+ fflush(stdout);
}
}
@@ -358,9 +371,57 @@ int main(int argc, char **argv) {
}
}
+ ExtentPtr bboxFilter;
+ std::string area;
+ const char* authority = nullptr;
+
/* process run line arguments */
while (--argc > 0) { /* collect run line arguments */
- if (**++argv == '-') {
+ ++argv;
+ if (strcmp(*argv, "--area") == 0 ) {
+ ++argv;
+ --argc;
+ if( argc == 0 ) {
+ emess(1, "missing argument for --area");
+ std::exit(1);
+ }
+ area = *argv;
+ }
+ else if (strcmp(*argv, "--bbox") == 0) {
+ ++argv;
+ --argc;
+ if( argc == 0 ) {
+ emess(1, "missing argument for --bbox");
+ std::exit(1);
+ }
+ auto bboxStr(*argv);
+ auto bbox(split(bboxStr, ','));
+ if (bbox.size() != 4) {
+ std::cerr << "Incorrect number of values for option --bbox: "
+ << bboxStr << std::endl;
+ std::exit(1);
+ }
+ try {
+ bboxFilter = Extent::createFromBBOX(
+ c_locale_stod(bbox[0]), c_locale_stod(bbox[1]),
+ c_locale_stod(bbox[2]), c_locale_stod(bbox[3]))
+ .as_nullable();
+ } catch (const std::exception &e) {
+ std::cerr << "Invalid value for option --bbox: " << bboxStr
+ << ", " << e.what() << std::endl;
+ std::exit(1);
+ }
+ }
+ else if (strcmp(*argv, "--authority") == 0 ) {
+ ++argv;
+ --argc;
+ if( argc == 0 ) {
+ emess(1, "missing argument for --authority");
+ std::exit(1);
+ }
+ authority = *argv;
+ }
+ else if (**argv == '-') {
for (arg = *argv;;) {
switch (*++arg) {
case '\0': /* position of "stdin" */
@@ -467,10 +528,23 @@ int main(int argc, char **argv) {
reverseout = 1;
continue;
case 'D': /* set debug level */
+ {
if (--argc <= 0)
goto noargument;
- pj_ctx_set_debug(pj_get_default_ctx(), atoi(*++argv));
+ int log_level = atoi(*++argv);
+ if (log_level <= 0) {
+ proj_log_level(pj_get_default_ctx(), PJ_LOG_NONE);
+ } else if (log_level == 1) {
+ proj_log_level(pj_get_default_ctx(), PJ_LOG_ERROR);
+ } else if (log_level == 2) {
+ proj_log_level(pj_get_default_ctx(), PJ_LOG_DEBUG);
+ } else if (log_level == 3) {
+ proj_log_level(pj_get_default_ctx(), PJ_LOG_TRACE);
+ } else {
+ proj_log_level(pj_get_default_ctx(), PJ_LOG_TELL);
+ }
continue;
+ }
case 'd':
if (--argc <= 0)
goto noargument;
@@ -522,6 +596,102 @@ int main(int argc, char **argv) {
}
}
+ if (bboxFilter && !area.empty()) {
+ std::cerr << "ERROR: --bbox and --area are exclusive" << std::endl;
+ std::exit(1);
+ }
+
+ PJ_AREA* pj_area = nullptr;
+ if (!area.empty()) {
+
+ DatabaseContextPtr dbContext;
+ try {
+ dbContext =
+ DatabaseContext::create().as_nullable();
+ } catch (const std::exception &e) {
+ std::cerr << "ERROR: Cannot create database connection: "
+ << e.what() << std::endl;
+ std::exit(1);
+ }
+
+ // Process area of use
+ try {
+ if (area.find(' ') == std::string::npos &&
+ area.find(':') != std::string::npos) {
+ auto tokens = split(area, ':');
+ if (tokens.size() == 2) {
+ const std::string &areaAuth = tokens[0];
+ const std::string &areaCode = tokens[1];
+ bboxFilter = AuthorityFactory::create(
+ NN_NO_CHECK(dbContext), areaAuth)
+ ->createExtent(areaCode)
+ .as_nullable();
+ }
+ }
+ if (!bboxFilter) {
+ auto authFactory = AuthorityFactory::create(
+ NN_NO_CHECK(dbContext), std::string());
+ auto res = authFactory->listAreaOfUseFromName(area, false);
+ if (res.size() == 1) {
+ bboxFilter =
+ AuthorityFactory::create(NN_NO_CHECK(dbContext),
+ res.front().first)
+ ->createExtent(res.front().second)
+ .as_nullable();
+ } else {
+ res = authFactory->listAreaOfUseFromName(area, true);
+ if (res.size() == 1) {
+ bboxFilter =
+ AuthorityFactory::create(NN_NO_CHECK(dbContext),
+ res.front().first)
+ ->createExtent(res.front().second)
+ .as_nullable();
+ } else if (res.empty()) {
+ std::cerr << "No area of use matching provided name"
+ << std::endl;
+ std::exit(1);
+ } else {
+ std::cerr << "Several candidates area of use "
+ "matching provided name :"
+ << std::endl;
+ for (const auto &candidate : res) {
+ auto obj =
+ AuthorityFactory::create(
+ NN_NO_CHECK(dbContext), candidate.first)
+ ->createExtent(candidate.second);
+ std::cerr << " " << candidate.first << ":"
+ << candidate.second << " : "
+ << *obj->description() << std::endl;
+ }
+ std::exit(1);
+ }
+ }
+ }
+ } catch (const std::exception &e) {
+ std::cerr << "Area of use retrieval failed: " << e.what()
+ << std::endl;
+ std::exit(1);
+ }
+ }
+
+ if (bboxFilter) {
+ auto geogElts = bboxFilter->geographicElements();
+ if (geogElts.size() == 1)
+ {
+ auto bbox = std::dynamic_pointer_cast<GeographicBoundingBox>(
+ geogElts[0].as_nullable());
+ if (bbox)
+ {
+ pj_area = proj_area_create();
+ proj_area_set_bbox(pj_area,
+ bbox->westBoundLongitude(),
+ bbox->southBoundLatitude(),
+ bbox->eastBoundLongitude(),
+ bbox->northBoundLatitude());
+ }
+ }
+ }
+
/*
* If the user has requested inverse, then just reverse the
* coordinate systems.
@@ -602,15 +772,23 @@ int main(int argc, char **argv) {
}
}
+ std::string authorityOption; /* keep this variable in this outer scope ! */
+ const char* options[2] = { nullptr, nullptr };
+ if( authority ) {
+ authorityOption = "AUTHORITY=";
+ authorityOption += authority;
+ options[0] = authorityOption.data();
+ }
transformation = proj_create_crs_to_crs_from_pj(nullptr, src, dst,
- nullptr, nullptr);
+ pj_area, options);
proj_destroy(src);
proj_destroy(dst);
+ proj_area_destroy(pj_area);
if (!transformation) {
emess(3, "cannot initialize transformation\ncause: %s",
- pj_strerrno(pj_errno));
+ proj_errno_string(proj_context_errno(nullptr)));
}
if (use_env_locale) {
diff --git a/src/apps/emess.cpp b/src/apps/emess.cpp
index 53018ba8..5a50cd25 100644
--- a/src/apps/emess.cpp
+++ b/src/apps/emess.cpp
@@ -9,17 +9,13 @@
# endif
#endif
-#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#endif
-
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "proj_api.h"
+#include "proj_internal.h"
#include "proj_config.h"
#define EMESS_ROUTINE
#include "emess.h"
diff --git a/src/apps/geod.cpp b/src/apps/geod.cpp
index 919430ca..35a8e826 100644
--- a/src/apps/geod.cpp
+++ b/src/apps/geod.cpp
@@ -124,6 +124,7 @@ process(FILE *fid) {
(void)fputs(rtodms(pline, al21, 0, 0), stdout);
}
(void)fputs(s, stdout);
+ fflush(stdout);
}
}
diff --git a/src/apps/geod_set.cpp b/src/apps/geod_set.cpp
index 603f0d95..d6516f22 100644
--- a/src/apps/geod_set.cpp
+++ b/src/apps/geod_set.cpp
@@ -75,6 +75,6 @@ geod_set(int argc, char **argv) {
/* free up linked list */
for ( ; start; start = curr) {
curr = start->next;
- pj_dalloc(start);
+ free(start);
}
}
diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp
index 8940afde..b504b922 100644
--- a/src/apps/gie.cpp
+++ b/src/apps/gie.cpp
@@ -880,8 +880,8 @@ static int expect_failure_with_errno_message (int expected, int got) {
banner (T.operation);
fprintf (T.fout, "%s", T.op_ko? " -----\n": delim);
fprintf (T.fout, " FAILURE in %s(%d):\n", opt_strip_path (T.curr_file), (int) F->lineno);
- fprintf (T.fout, " got errno %s (%d): %s\n", err_const_from_errno(got), got, pj_strerrno (got));
- fprintf (T.fout, " expected %s (%d): %s", err_const_from_errno(expected), expected, pj_strerrno (expected));
+ fprintf (T.fout, " got errno %s (%d): %s\n", err_const_from_errno(got), got, proj_errno_string (got));
+ fprintf (T.fout, " expected %s (%d): %s", err_const_from_errno(expected), expected, proj_errno_string (expected));
fprintf (T.fout, "\n");
return 1;
}
@@ -934,7 +934,7 @@ Tell GIE what to expect, when transforming the ACCEPTed input
/* Otherwise, it's a true failure */
banner (T.operation);
errmsg (3, "%sInvalid operation definition in line no. %d:\n %s (errno=%s/%d)\n",
- delim, (int) T.operation_lineno, pj_strerrno(proj_errno(T.P)),
+ delim, (int) T.operation_lineno, proj_errno_string (proj_errno(T.P)),
err_const_from_errno (proj_errno(T.P)), proj_errno(T.P)
);
return another_failing_failure ();
@@ -1124,7 +1124,7 @@ static const struct errno_vs_err_const lookup[] = {
{"pjd_err_invalid_x_or_y" , -15},
{"pjd_err_wrong_format_dms_value" , -16},
{"pjd_err_non_conv_inv_meri_dist" , -17},
- {"pjd_err_non_con_inv_phi2" , -18},
+ {"pjd_err_non_conv_sinhpsi2tanphi" , -18},
{"pjd_err_acos_asin_arg_too_large" , -19},
{"pjd_err_tolerance_condition" , -20},
{"pjd_err_conic_lat_equal" , -21},
@@ -1186,7 +1186,7 @@ static int list_err_codes (void) {
if (9999==lookup[i].the_errno)
break;
fprintf (T.fout, "%25s (%2.2d): %s\n", lookup[i].the_err_const + 8,
- lookup[i].the_errno, pj_strerrno(lookup[i].the_errno));
+ lookup[i].the_errno, proj_errno_string (lookup[i].the_errno));
}
return 0;
}
diff --git a/src/apps/proj.cpp b/src/apps/proj.cpp
index 0bf98b3a..0108cb74 100644
--- a/src/apps/proj.cpp
+++ b/src/apps/proj.cpp
@@ -9,6 +9,8 @@
#include "emess.h"
#include "utils.h"
+#include <vector>
+
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__WIN32__)
# include <fcntl.h>
# include <io.h>
@@ -171,6 +173,7 @@ static void process(FILE *fid) {
(void)fputs("\t<* * * * * *>", stdout);
}
(void)fputs(bin_in ? "\n" : s, stdout);
+ fflush(stdout);
}
}
@@ -249,10 +252,8 @@ static void vprocess(FILE *fid) {
if (postscale) { dat_xy.x *= fscale; dat_xy.y *= fscale; }
}
- /* For some reason pj_errno does not work as expected in some */
- /* versions of Visual Studio, so using pj_get_errno_ref instead */
- if (*pj_get_errno_ref()) {
- emess(-1, pj_strerrno(*pj_get_errno_ref()));
+ if (proj_context_errno(nullptr)) {
+ emess(-1, proj_errno_string(proj_context_errno(nullptr)));
continue;
}
@@ -286,15 +287,17 @@ static void vprocess(FILE *fid) {
(void)fputs(proj_rtodms(pline, facs.meridian_convergence, 0, 0), stdout);
(void)printf(" [ %.8f ]\n", facs.meridian_convergence * RAD_TO_DEG);
(void)printf("Max-min (Tissot axis a-b) scale error: %.5f %.5f\n\n", facs.tissot_semimajor, facs.tissot_semiminor);
+
+ fflush(stdout);
}
}
int main(int argc, char **argv) {
char *arg;
- char *pargv[MAX_PARGS] = {};
+ std::vector<char*> argvVector;
char **eargv = argv;
FILE *fid;
- int pargc = 0, eargc = 0, mon = 0;
+ int eargc = 0, mon = 0;
if ( (emess_dat.Prog_name = strrchr(*argv,DIR_CHAR)) != nullptr)
++emess_dat.Prog_name;
@@ -449,10 +452,7 @@ int main(int argc, char **argv) {
}
break;
} else if (**argv == '+') { /* + argument */
- if (pargc < MAX_PARGS)
- pargv[pargc++] = *argv + 1;
- else
- emess(1,"overflowed + argument table");
+ argvVector.push_back(*argv + 1);
} else /* assumed to be input file name(s) */
eargv[eargc++] = *argv;
}
@@ -472,9 +472,14 @@ int main(int argc, char **argv) {
postscale = 0;
fscale = 1./fscale;
}
- if (!(Proj = pj_init(pargc, pargv)))
+ proj_context_use_proj4_init_rules(nullptr, true);
+
+ // proj historically ignores any datum shift specifier, like nadgrids, towgs84, etc
+ argvVector.push_back(const_cast<char*>("break_cs2cs_recursion"));
+
+ if (!(Proj = proj_create_argv(nullptr, static_cast<int>(argvVector.size()), argvVector.data())))
emess(3,"projection initialization failure\ncause: %s",
- pj_strerrno(pj_errno));
+ proj_errno_string(proj_context_errno(nullptr)));
if (!proj_angular_input(Proj, PJ_FWD)) {
emess(3, "can't initialize operations that take non-angular input coordinates");
@@ -559,7 +564,7 @@ int main(int argc, char **argv) {
}
if( Proj )
- pj_free(Proj);
+ proj_destroy(Proj);
exit(0); /* normal completion */
}
diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp
index 37b76346..da885fbb 100644
--- a/src/apps/projinfo.cpp
+++ b/src/apps/projinfo.cpp
@@ -72,6 +72,7 @@ struct OutputOptions {
bool singleLine = false;
bool strict = true;
bool ballparkAllowed = true;
+ bool allowEllipsoidalHeightAsVerticalCRS = false;
};
} // anonymous namespace
@@ -79,7 +80,8 @@ struct OutputOptions {
static void usage() {
std::cerr
- << "usage: projinfo [-o formats] [-k crs|operation|datum|ellipsoid] "
+ << "usage: projinfo [-o formats] "
+ "[-k crs|operation|datum|ensemble|ellipsoid] "
"[--summary] [-q]"
<< std::endl
<< " ([--area name_or_code] | "
@@ -94,6 +96,8 @@ static void usage() {
<< " [--pivot-crs always|if_no_direct_transformation|"
<< "never|{auth:code[,auth:code]*}]" << std::endl
<< " [--show-superseded] [--hide-ballpark]" << std::endl
+ << " [--allow-ellipsoidal-height-as-vertical-crs]"
+ << std::endl
<< " [--boundcrs-to-wgs84]" << std::endl
<< " [--main-db-path path] [--aux-db-path path]*"
<< std::endl
@@ -184,11 +188,11 @@ static BaseObjectNNPtr buildObject(
auto urn = "urn:ogc:def:coordinateOperation:" + tokens[0] + "::" +
tokens[1];
obj = createFromUserInput(urn, dbContext).as_nullable();
- } else if (kind == "ellipsoid" && tokens.size() == 2) {
- auto urn = "urn:ogc:def:ellipsoid:" + tokens[0] + "::" + tokens[1];
- obj = createFromUserInput(urn, dbContext).as_nullable();
- } else if (kind == "datum" && tokens.size() == 2) {
- auto urn = "urn:ogc:def:datum:" + tokens[0] + "::" + tokens[1];
+ } else if ((kind == "ellipsoid" || kind == "datum" ||
+ kind == "ensemble") &&
+ tokens.size() == 2) {
+ auto urn =
+ "urn:ogc:def:" + kind + ":" + tokens[0] + "::" + tokens[1];
obj = createFromUserInput(urn, dbContext).as_nullable();
} else {
// Convenience to be able to use C escaped strings...
@@ -222,6 +226,9 @@ static BaseObjectNNPtr buildObject(
AuthorityFactory::ObjectType::ELLIPSOID);
else if (kind == "datum")
allowedTypes.push_back(AuthorityFactory::ObjectType::DATUM);
+ else if (kind == "ensemble")
+ allowedTypes.push_back(
+ AuthorityFactory::ObjectType::DATUM_ENSEMBLE);
constexpr size_t limitResultCount = 10;
auto factory = AuthorityFactory::create(NN_NO_CHECK(dbContext),
std::string());
@@ -483,6 +490,8 @@ static void outputObject(
formatter->setMultiLine(false);
}
formatter->setStrict(outputOpt.strict);
+ formatter->setAllowEllipsoidalHeightAsVerticalCRS(
+ outputOpt.allowEllipsoidalHeightAsVerticalCRS);
auto wkt = wktExportable->exportToWKT(formatter.get());
if (outputOpt.c_ify) {
wkt = c_ify_string(wkt);
@@ -689,6 +698,7 @@ static void outputOperations(
std::vector<CoordinateOperationNNPtr> list;
size_t spatialCriterionPartialIntersectionResultCount = 0;
+ bool spatialCriterionPartialIntersectionMoreRelevant = false;
try {
auto authFactory =
dbContext
@@ -714,10 +724,15 @@ static void outputOperations(
ctxt->setSpatialCriterion(
CoordinateOperationContext::SpatialCriterion::
PARTIAL_INTERSECTION);
- spatialCriterionPartialIntersectionResultCount =
- CoordinateOperationFactory::create()
- ->createOperations(nnSourceCRS, nnTargetCRS, ctxt)
- .size();
+ auto list2 =
+ CoordinateOperationFactory::create()->createOperations(
+ nnSourceCRS, nnTargetCRS, ctxt);
+ spatialCriterionPartialIntersectionResultCount = list2.size();
+ if (spatialCriterionPartialIntersectionResultCount == 1 &&
+ list.size() == 1 &&
+ list2[0]->nameStr() != list[0]->nameStr()) {
+ spatialCriterionPartialIntersectionMoreRelevant = true;
+ }
} catch (const std::exception &) {
}
}
@@ -736,6 +751,10 @@ static void outputOperations(
"more results ("
<< spatialCriterionPartialIntersectionResultCount << ")"
<< std::endl;
+ } else if (spatialCriterionPartialIntersectionMoreRelevant) {
+ std::cout << "Note: using '--spatial-test intersects' would bring "
+ "more relevant results."
+ << std::endl;
}
if (summary) {
for (const auto &op : list) {
@@ -929,6 +948,8 @@ int main(int argc, char **argv) {
objectKind = "ellipsoid";
} else if (ci_equal(kind, "datum")) {
objectKind = "datum";
+ } else if (ci_equal(kind, "ensemble")) {
+ objectKind = "ensemble";
} else {
std::cerr << "Unrecognized value for option -k: " << kind
<< std::endl;
@@ -1054,6 +1075,8 @@ int main(int argc, char **argv) {
showSuperseded = true;
} else if (arg == "--lax") {
outputOpt.strict = false;
+ } else if (arg == "--allow-ellipsoidal-height-as-vertical-crs") {
+ outputOpt.allowEllipsoidalHeightAsVerticalCRS = true;
} else if (arg == "--hide-ballpark") {
outputOpt.ballparkAllowed = false;
} else if (ci_equal(arg, "--3d")) {
diff --git a/src/auth.cpp b/src/auth.cpp
index a8ee262a..ced02fb4 100644
--- a/src/auth.cpp
+++ b/src/auth.cpp
@@ -18,7 +18,7 @@
pj_authset(double es) {
double t, *APA;
- if ((APA = (double *)pj_malloc(APA_SIZE * sizeof(double))) != nullptr) {
+ if ((APA = (double *)malloc(APA_SIZE * sizeof(double))) != nullptr) {
APA[0] = es * P00;
t = es * es;
APA[0] += t * P01;
diff --git a/src/bin_projinfo.cmake b/src/bin_projinfo.cmake
index 16c9e9d0..8610a3a7 100644
--- a/src/bin_projinfo.cmake
+++ b/src/bin_projinfo.cmake
@@ -15,3 +15,7 @@ install(TARGETS binprojinfo
if(MSVC AND BUILD_SHARED_LIBS)
target_compile_definitions(binprojinfo PRIVATE PROJ_MSVC_DLL_IMPORT=1)
endif()
+
+if(CURL_ENABLED)
+ target_compile_definitions(binprojinfo PRIVATE -DCURL_ENABLED)
+endif()
diff --git a/src/conversions/axisswap.cpp b/src/conversions/axisswap.cpp
index 4ae2b4e4..1aa339c3 100644
--- a/src/conversions/axisswap.cpp
+++ b/src/conversions/axisswap.cpp
@@ -169,7 +169,7 @@ static PJ_COORD reverse_4d(PJ_COORD coo, PJ *P) {
/***********************************************************************/
PJ *CONVERSION(axisswap,0) {
/***********************************************************************/
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
char *s;
unsigned int i, j, n = 0;
diff --git a/src/conversions/set.cpp b/src/conversions/set.cpp
index 7628bf4f..2f30bda8 100644
--- a/src/conversions/set.cpp
+++ b/src/conversions/set.cpp
@@ -39,7 +39,7 @@ PJ *OPERATION(set, 0) {
P->inv4d = set_fwd_inv;
P->fwd4d = set_fwd_inv;
- auto set = static_cast<struct Set*>(pj_calloc (1, sizeof(struct Set)));
+ auto set = static_cast<struct Set*>(calloc (1, sizeof(struct Set)));
P->opaque = set;
if (nullptr==P->opaque)
return pj_default_destructor(P, ENOMEM);
diff --git a/src/conversions/topocentric.cpp b/src/conversions/topocentric.cpp
new file mode 100644
index 00000000..f6f328ad
--- /dev/null
+++ b/src/conversions/topocentric.cpp
@@ -0,0 +1,165 @@
+/******************************************************************************
+ * Project: PROJ
+ * Purpose: Convert between geocentric coordinates and topocentric (ENU) coordinates
+ *
+ ******************************************************************************
+ * Copyright (c) 2020, Even Rouault <even.rouault at spatialys.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *****************************************************************************/
+
+#define PJ_LIB__
+
+#include "proj_internal.h"
+#include <errno.h>
+#include <math.h>
+
+PROJ_HEAD(topocentric, "Geocentric/Topocentric conversion");
+
+// Notations and formulas taken from IOGP Publication 373-7-2 -
+// Geomatics Guidance Note number 7, part 2 - October 2020
+
+namespace { // anonymous namespace
+struct pj_opaque {
+ double X0;
+ double Y0;
+ double Z0;
+ double sinphi0;
+ double cosphi0;
+ double sinlam0;
+ double coslam0;
+};
+} // anonymous namespace
+
+// Convert from geocentric to topocentric
+static PJ_COORD topocentric_fwd(PJ_COORD in, PJ * P)
+{
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(P->opaque);
+ PJ_COORD out;
+ const double dX = in.xyz.x - Q->X0;
+ const double dY = in.xyz.y - Q->Y0;
+ const double dZ = in.xyz.z - Q->Z0;
+ out.xyz.x = -dX * Q->sinlam0 + dY * Q->coslam0;
+ out.xyz.y = -dX * Q->sinphi0 * Q->coslam0 - dY * Q->sinphi0 * Q->sinlam0 + dZ * Q->cosphi0;
+ out.xyz.z = dX * Q->cosphi0 * Q->coslam0 + dY * Q->cosphi0 * Q->sinlam0 + dZ * Q->sinphi0;
+ return out;
+}
+
+// Convert from topocentric to geocentric
+static PJ_COORD topocentric_inv(PJ_COORD in, PJ * P)
+{
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(P->opaque);
+ PJ_COORD out;
+ out.xyz.x = Q->X0 - in.xyz.x * Q->sinlam0 - in.xyz.y * Q->sinphi0 * Q->coslam0 + in.xyz.z * Q->cosphi0 * Q->coslam0;
+ out.xyz.y = Q->Y0 + in.xyz.x * Q->coslam0 - in.xyz.y * Q->sinphi0 * Q->sinlam0 + in.xyz.z * Q->cosphi0 * Q->sinlam0;
+ out.xyz.z = Q->Z0 + in.xyz.y * Q->cosphi0 + in.xyz.z * Q->sinphi0;
+ return out;
+}
+
+
+/*********************************************************************/
+PJ *CONVERSION(topocentric,1) {
+/*********************************************************************/
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
+ if (nullptr==Q)
+ return pj_default_destructor (P, ENOMEM);
+ P->opaque = static_cast<void *>(Q);
+
+ // The topocentric origin can be specified either in geocentric coordinates
+ // (X_0,Y_0,Z_0) or as geographic coordinates (lon_0,lat_0,h_0)
+ // Checks:
+ // - X_0 or lon_0 must be specified
+ // - If X_0 is specified, the Y_0 and Z_0 must also be
+ // - If lon_0 is specified, then lat_0 must also be
+ // - If any of X_0, Y_0, Z_0 is specified, then any of lon_0,lat_0,h_0 must
+ // not be, and vice versa.
+ const auto hasX0 = pj_param_exists(P->params, "X_0");
+ const auto hasY0 = pj_param_exists(P->params, "Y_0");
+ const auto hasZ0 = pj_param_exists(P->params, "Z_0");
+ const auto hasLon0 = pj_param_exists(P->params, "lon_0");
+ const auto hasLat0 = pj_param_exists(P->params, "lat_0");
+ const auto hash0 = pj_param_exists(P->params, "h_0");
+ if( !hasX0 && !hasLon0 )
+ {
+ return pj_default_destructor(P, PJD_ERR_MISSING_ARGS);
+ }
+ if ( (hasX0 || hasY0 || hasZ0) &&
+ (hasLon0 || hasLat0 || hash0) )
+ {
+ return pj_default_destructor(P, PJD_ERR_MUTUALLY_EXCLUSIVE_ARGS);
+ }
+ if( hasX0 && (!hasY0 || !hasZ0) )
+ {
+ return pj_default_destructor(P, PJD_ERR_MISSING_ARGS);
+ }
+ if( hasLon0 && !hasLat0 ) // allow missing h_0
+ {
+ return pj_default_destructor(P, PJD_ERR_MISSING_ARGS);
+ }
+
+ // Pass a dummy ellipsoid definition that will be overridden just afterwards
+ PJ* cart = proj_create(P->ctx, "+proj=cart +a=1");
+ if (cart == nullptr)
+ return pj_default_destructor(P, ENOMEM);
+ /* inherit ellipsoid definition from P to cart */
+ pj_inherit_ellipsoid_def (P, cart);
+
+ if( hasX0 )
+ {
+ Q->X0 = pj_param(P->ctx, P->params, "dX_0").f;
+ Q->Y0 = pj_param(P->ctx, P->params, "dY_0").f;
+ Q->Z0 = pj_param(P->ctx, P->params, "dZ_0").f;
+
+ // Compute lam0, phi0 from X0,Y0,Z0
+ PJ_XYZ xyz;
+ xyz.x = Q->X0;
+ xyz.y = Q->Y0;
+ xyz.z = Q->Z0;
+ const auto lpz = pj_inv3d(xyz, cart);
+ Q->sinphi0 = sin(lpz.phi);
+ Q->cosphi0 = cos(lpz.phi);
+ Q->sinlam0 = sin(lpz.lam);
+ Q->coslam0 = cos(lpz.lam);
+ }
+ else
+ {
+ // Compute X0,Y0,Z0 from lam0, phi0, h0
+ PJ_LPZ lpz;
+ lpz.lam = P->lam0;
+ lpz.phi = P->phi0;
+ lpz.z = pj_param(P->ctx, P->params, "dh_0").f;
+ const auto xyz = pj_fwd3d(lpz, cart);
+ Q->X0 = xyz.x;
+ Q->Y0 = xyz.y;
+ Q->Z0 = xyz.z;
+
+ Q->sinphi0 = sin(P->phi0);
+ Q->cosphi0 = cos(P->phi0);
+ Q->sinlam0 = sin(P->lam0);
+ Q->coslam0 = cos(P->lam0);
+ }
+
+ proj_destroy(cart);
+
+ P->fwd4d = topocentric_fwd;
+ P->inv4d = topocentric_inv;
+ P->left = PJ_IO_UNITS_CARTESIAN;
+ P->right = PJ_IO_UNITS_CARTESIAN;
+ return P;
+}
diff --git a/src/conversions/unitconvert.cpp b/src/conversions/unitconvert.cpp
index 172e2c48..61bccbf1 100644
--- a/src/conversions/unitconvert.cpp
+++ b/src/conversions/unitconvert.cpp
@@ -433,7 +433,7 @@ static double get_unit_conversion_factor(const char* name,
/***********************************************************************/
PJ *CONVERSION(unitconvert,0) {
/***********************************************************************/
- struct pj_opaque_unitconvert *Q = static_cast<struct pj_opaque_unitconvert*>(pj_calloc (1, sizeof (struct pj_opaque_unitconvert)));
+ struct pj_opaque_unitconvert *Q = static_cast<struct pj_opaque_unitconvert*>(calloc (1, sizeof (struct pj_opaque_unitconvert)));
const char *s, *name;
int i;
double f;
diff --git a/src/ctx.cpp b/src/ctx.cpp
index 6dbe0de5..2093950b 100644
--- a/src/ctx.cpp
+++ b/src/ctx.cpp
@@ -1,6 +1,6 @@
/******************************************************************************
* Project: PROJ.4
- * Purpose: Implementation of the projCtx thread context object.
+ * Purpose: Implementation of the PJ_CONTEXT thread context object.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
@@ -43,7 +43,7 @@
/* pj_get_ctx() */
/************************************************************************/
-projCtx pj_get_ctx( projPJ pj )
+PJ_CONTEXT* pj_get_ctx( PJ *pj )
{
if (nullptr==pj)
@@ -54,13 +54,17 @@ projCtx pj_get_ctx( projPJ pj )
}
/************************************************************************/
-/* pj_set_ctx() */
-/* */
-/* Note we do not deallocate the old context! */
+/* proj_assign_context() */
/************************************************************************/
-void pj_set_ctx( projPJ pj, projCtx ctx )
-
+/** \brief Re-assign a context to a PJ* object.
+ *
+ * This may be useful if the PJ* has been created with a context that is
+ * thread-specific, and is later used in another thread. In that case,
+ * the user may want to assign another thread-specific context to the
+ * object.
+ */
+void proj_assign_context( PJ* pj, PJ_CONTEXT *ctx )
{
if (pj==nullptr)
return;
@@ -71,36 +75,20 @@ void pj_set_ctx( projPJ pj, projCtx ctx )
}
for( const auto &alt: pj->alternativeCoordinateOperations )
{
- pj_set_ctx(alt.pj, ctx);
+ proj_assign_context(alt.pj, ctx);
}
-}
-
-/************************************************************************/
-/* proj_assign_context() */
-/************************************************************************/
-/** \brief Re-assign a context to a PJ* object.
- *
- * This may be useful if the PJ* has been created with a context that is
- * thread-specific, and is later used in another thread. In that case,
- * the user may want to assign another thread-specific context to the
- * object.
- */
-void proj_assign_context( PJ* pj, PJ_CONTEXT* ctx )
-{
- pj_set_ctx( pj, ctx );
}
/************************************************************************/
/* createDefault() */
/************************************************************************/
-projCtx_t projCtx_t::createDefault()
+pj_ctx pj_ctx::createDefault()
{
- projCtx_t ctx;
+ pj_ctx ctx;
ctx.debug_level = PJ_LOG_NONE;
ctx.logger = pj_stderr_logger;
- ctx.fileapi_legacy = pj_get_default_fileapi();
NS_PROJ::FileManager::fillDefaultNetworkInterface(&ctx);
if( getenv("PROJ_DEBUG") != nullptr )
@@ -117,7 +105,7 @@ projCtx_t projCtx_t::createDefault()
/* get_cpp_context() */
/**************************************************************************/
-projCppContext* projCtx_t::get_cpp_context()
+projCppContext* pj_ctx::get_cpp_context()
{
if (cpp_context == nullptr) {
cpp_context = new projCppContext(this);
@@ -125,12 +113,11 @@ projCppContext* projCtx_t::get_cpp_context()
return cpp_context;
}
-
/**************************************************************************/
/* safeAutoCloseDbIfNeeded() */
/**************************************************************************/
-void projCtx_t::safeAutoCloseDbIfNeeded()
+void pj_ctx::safeAutoCloseDbIfNeeded()
{
if (cpp_context) {
cpp_context->autoCloseDbIfNeeded();
@@ -141,7 +128,7 @@ void projCtx_t::safeAutoCloseDbIfNeeded()
/* set_search_paths() */
/************************************************************************/
-void projCtx_t::set_search_paths(const std::vector<std::string>& search_paths_in )
+void pj_ctx::set_search_paths(const std::vector<std::string>& search_paths_in )
{
search_paths = search_paths_in;
delete[] c_compat_paths;
@@ -158,26 +145,24 @@ void projCtx_t::set_search_paths(const std::vector<std::string>& search_paths_in
/* set_ca_bundle_path() */
/**************************************************************************/
-void projCtx_t::set_ca_bundle_path(const std::string& ca_bundle_path_in)
+void pj_ctx::set_ca_bundle_path(const std::string& ca_bundle_path_in)
{
ca_bundle_path = ca_bundle_path_in;
}
/************************************************************************/
-/* projCtx_t(const projCtx_t& other) */
+/* pj_ctx(const pj_ctx& other) */
/************************************************************************/
-projCtx_t::projCtx_t(const projCtx_t& other) :
+pj_ctx::pj_ctx(const pj_ctx& other) :
debug_level(other.debug_level),
logger(other.logger),
logger_app_data(other.logger_app_data),
- fileapi_legacy(other.fileapi_legacy),
cpp_context(other.cpp_context ? other.cpp_context->clone(this) : nullptr),
use_proj4_init_rules(other.use_proj4_init_rules),
epsg_file_exists(other.epsg_file_exists),
ca_bundle_path(other.ca_bundle_path),
env_var_proj_lib(other.env_var_proj_lib),
- file_finder_legacy(other.file_finder_legacy),
file_finder(other.file_finder),
file_finder_user_data(other.file_finder_user_data),
custom_sqlite3_vfs_name(other.custom_sqlite3_vfs_name),
@@ -197,129 +182,35 @@ projCtx_t::projCtx_t(const projCtx_t& other) :
/* pj_get_default_ctx() */
/************************************************************************/
-projCtx pj_get_default_ctx()
+PJ_CONTEXT* pj_get_default_ctx()
{
// C++11 rules guarantee a thread-safe instantiation.
- static projCtx_t default_context(projCtx_t::createDefault());
+ static pj_ctx default_context(pj_ctx::createDefault());
return &default_context;
}
/************************************************************************/
-/* ~projCtx_t() */
+/* ~pj_ctx() */
/************************************************************************/
-projCtx_t::~projCtx_t()
+pj_ctx::~pj_ctx()
{
delete[] c_compat_paths;
proj_context_delete_cpp_context(cpp_context);
}
/************************************************************************/
-/* pj_ctx_alloc() */
-/************************************************************************/
-
-projCtx pj_ctx_alloc()
-
-{
- return new (std::nothrow) projCtx_t(*pj_get_default_ctx());
-}
-
-/************************************************************************/
/* proj_context_clone() */
/* Create a new context based on a custom context */
/************************************************************************/
-PJ_CONTEXT *proj_context_clone (PJ_CONTEXT *ctx)
-{
- if (nullptr==ctx)
- return pj_ctx_alloc ();
-
- return new (std::nothrow) projCtx_t(*ctx);
-}
-
-/************************************************************************/
-/* pj_ctx_free() */
-/************************************************************************/
-
-void pj_ctx_free( projCtx ctx )
-
-{
- delete ctx;
-}
-
-/************************************************************************/
-/* pj_ctx_get_errno() */
-/************************************************************************/
-
-int pj_ctx_get_errno( projCtx ctx )
-
+PJ_CONTEXT* proj_context_clone (PJ_CONTEXT *ctx)
{
if (nullptr==ctx)
- return pj_get_default_ctx ()->last_errno;
- return ctx->last_errno;
-}
-
-/************************************************************************/
-/* pj_ctx_set_errno() */
-/* */
-/* Also sets the global errno */
-/************************************************************************/
-
-void pj_ctx_set_errno( projCtx ctx, int new_errno )
-
-{
- ctx->last_errno = new_errno;
- if( new_errno == 0 )
- return;
- errno = new_errno;
- pj_errno = new_errno;
-}
-
-/************************************************************************/
-/* pj_ctx_set_debug() */
-/************************************************************************/
-
-void pj_ctx_set_debug( projCtx ctx, int new_debug )
+ return proj_context_create();
-{
- if (nullptr==ctx)
- return;
- ctx->debug_level = new_debug;
+ return new (std::nothrow) pj_ctx(*ctx);
}
-/************************************************************************/
-/* pj_ctx_set_logger() */
-/************************************************************************/
-
-void pj_ctx_set_logger( projCtx ctx, void (*new_logger)(void*,int,const char*) )
-{
- if (nullptr==ctx)
- return;
- ctx->logger = new_logger;
-}
-
-/************************************************************************/
-/* pj_ctx_set_app_data() */
-/************************************************************************/
-
-void pj_ctx_set_app_data( projCtx ctx, void *new_app_data )
-
-{
- if (nullptr==ctx)
- return;
- ctx->logger_app_data = new_app_data;
-}
-
-/************************************************************************/
-/* pj_ctx_get_app_data() */
-/************************************************************************/
-
-void *pj_ctx_get_app_data( projCtx ctx )
-
-{
- if (nullptr==ctx)
- return nullptr;
- return ctx->logger_app_data;
-}
diff --git a/src/datum_set.cpp b/src/datum_set.cpp
index 15d51613..3f612633 100644
--- a/src/datum_set.cpp
+++ b/src/datum_set.cpp
@@ -38,7 +38,7 @@
/* pj_datum_set() */
/************************************************************************/
-int pj_datum_set(projCtx ctx, paralist *pl, PJ *projdef)
+int pj_datum_set(PJ_CONTEXT *ctx, paralist *pl, PJ *projdef)
{
const char *name, *towgs84, *nadgrids;
@@ -71,7 +71,7 @@ int pj_datum_set(projCtx ctx, paralist *pl, PJ *projdef)
for (i = 0; (s = pj_datums[i].id) && strcmp(name, s) ; ++i) {}
if (!s) {
- pj_ctx_set_errno(ctx, PJD_ERR_UNKNOWN_ELLP_PARAM);
+ proj_context_errno_set(ctx, PJD_ERR_UNKNOWN_ELLP_PARAM);
return 1;
}
@@ -84,25 +84,27 @@ int pj_datum_set(projCtx ctx, paralist *pl, PJ *projdef)
sizeof(entry) - 1 - strlen(entry) );
entry[ sizeof(entry) - 1 ] = '\0';
- curr = curr->next = pj_mkparam(entry);
- if (nullptr == curr)
+ auto param = pj_mkparam(entry);
+ if (nullptr == param)
{
- pj_ctx_set_errno(ctx, ENOMEM);
+ proj_context_errno_set(ctx, ENOMEM);
return 1;
}
+ curr->next = param;
+ curr = param;
}
if( pj_datums[i].defn && strlen(pj_datums[i].defn) > 0 )
{
- curr = curr->next = pj_mkparam(pj_datums[i].defn);
- if (nullptr == curr)
+ auto param = pj_mkparam(pj_datums[i].defn);
+ if (nullptr == param)
{
- pj_ctx_set_errno(ctx, ENOMEM);
+ proj_context_errno_set(ctx, ENOMEM);
return 1;
}
+ curr->next = param;
+ /* curr = param; */
}
-
- (void)curr; /* make clang static analyzer happy */
}
/* -------------------------------------------------------------------- */
diff --git a/src/dmstor.cpp b/src/dmstor.cpp
index 3ba66030..24887a11 100644
--- a/src/dmstor.cpp
+++ b/src/dmstor.cpp
@@ -26,7 +26,7 @@ dmstor(const char *is, char **rs) {
}
double
-dmstor_ctx(projCtx ctx, const char *is, char **rs) {
+dmstor_ctx(PJ_CONTEXT *ctx, const char *is, char **rs) {
int sign, n, nl;
char *s, work[MAX_WORK];
const char* p;
@@ -61,7 +61,7 @@ dmstor_ctx(projCtx ctx, const char *is, char **rs) {
n = 2; break;
case 'r': case 'R':
if (nl) {
- pj_ctx_set_errno( ctx, PJD_ERR_WRONG_FORMAT_DMS_VALUE );
+ proj_context_errno_set( ctx, PJD_ERR_WRONG_FORMAT_DMS_VALUE );
return HUGE_VAL;
}
++s;
@@ -73,7 +73,7 @@ dmstor_ctx(projCtx ctx, const char *is, char **rs) {
continue;
}
if (n < nl) {
- pj_ctx_set_errno( ctx, PJD_ERR_WRONG_FORMAT_DMS_VALUE );
+ proj_context_errno_set( ctx, PJD_ERR_WRONG_FORMAT_DMS_VALUE );
return HUGE_VAL;
}
v += tv * vm[n];
diff --git a/src/ell_set.cpp b/src/ell_set.cpp
index ddd507ac..176fc553 100644
--- a/src/ell_set.cpp
+++ b/src/ell_set.cpp
@@ -77,13 +77,13 @@ int pj_ellipsoid (PJ *P) {
int err = proj_errno_reset (P);
const char *empty = {""};
- pj_dealloc(P->def_size);
+ free(P->def_size);
P->def_size = nullptr;
- pj_dealloc(P->def_shape);
+ free(P->def_shape);
P->def_shape = nullptr;
- pj_dealloc(P->def_spherification);
+ free(P->def_spherification);
P->def_spherification = nullptr;
- pj_dealloc(P->def_ellps);
+ free(P->def_ellps);
P->def_ellps = nullptr;
/* Specifying R overrules everything */
@@ -162,7 +162,7 @@ static int ellps_ellps (PJ *P) {
new_params->next = pj_mkparam (ellps->ell);
if (nullptr == new_params->next)
{
- pj_dealloc(new_params);
+ free(new_params);
return proj_errno_set (P, ENOMEM);
}
paralist* old_params = P->params;
@@ -176,8 +176,8 @@ static int ellps_ellps (PJ *P) {
ellps_shape (P);
P->params = old_params;
- pj_dealloc (new_params->next);
- pj_dealloc (new_params);
+ free (new_params->next);
+ free (new_params);
if (proj_errno (P))
return proj_errno (P);
@@ -195,7 +195,7 @@ static int ellps_size (PJ *P) {
paralist *par = nullptr;
int a_was_set = 0;
- pj_dealloc(P->def_size);
+ free(P->def_size);
P->def_size = nullptr;
/* A size parameter *must* be given, but may have been given as ellps prior */
@@ -235,7 +235,7 @@ static int ellps_shape (PJ *P) {
par = nullptr;
len = sizeof (keys) / sizeof (char *);
- pj_dealloc(P->def_shape);
+ free(P->def_shape);
P->def_shape = nullptr;
/* Check which shape key is specified */
@@ -552,7 +552,7 @@ int pj_calc_ellipsoid_params (PJ *P, double a, double es) {
if (0==P->f)
P->f = 1 - cos (P->alpha); /* = 1 - sqrt (1 - PIN->es); */
if (P->f == 1.0) {
- pj_ctx_set_errno( P->ctx, PJD_ERR_INVALID_ECCENTRICITY);
+ proj_context_errno_set( P->ctx, PJD_ERR_INVALID_ECCENTRICITY);
return PJD_ERR_INVALID_ECCENTRICITY;
}
P->rf = P->f != 0.0 ? 1.0/P->f: HUGE_VAL;
@@ -573,7 +573,7 @@ int pj_calc_ellipsoid_params (PJ *P, double a, double es) {
P->one_es = 1. - P->es;
if (P->one_es == 0.) {
- pj_ctx_set_errno( P->ctx, PJD_ERR_INVALID_ECCENTRICITY);
+ proj_context_errno_set( P->ctx, PJD_ERR_INVALID_ECCENTRICITY);
return PJD_ERR_INVALID_ECCENTRICITY;
}
@@ -609,7 +609,7 @@ int pj_ell_set (PJ_CONTEXT *ctx, paralist *pl, double *a, double *es) {
/**************************************************************************************/
-int pj_ell_set (projCtx ctx, paralist *pl, double *a, double *es) {
+int pj_ell_set (PJ_CONTEXT *ctx, paralist *pl, double *a, double *es) {
/***************************************************************************************
Initialize ellipsoidal parameters: This is the original ellipsoid setup
function by Gerald Evenden - significantly more compact than pj_ellipsoid and
@@ -630,7 +630,7 @@ int pj_ell_set (projCtx ctx, paralist *pl, double *a, double *es) {
paralist *start = 0;
/* clear any previous error */
- pj_ctx_set_errno(ctx,0);
+ proj_context_errno_set(ctx,0);
/* check for varying forms of ellipsoid input */
*a = *es = 0.;
@@ -648,7 +648,7 @@ int pj_ell_set (projCtx ctx, paralist *pl, double *a, double *es) {
for (start = pl; start && start->next ; start = start->next) ;
for (i = 0; (s = pj_ellps[i].id) && strcmp(name, s) ; ++i) ;
if (!s) {
- pj_ctx_set_errno( ctx, PJD_ERR_UNKNOWN_ELLP_PARAM);
+ proj_context_errno_set( ctx, PJD_ERR_UNKNOWN_ELLP_PARAM);
return 1;
}
start->next = pj_mkparam(pj_ellps[i].major);
@@ -662,14 +662,14 @@ int pj_ell_set (projCtx ctx, paralist *pl, double *a, double *es) {
else if (pj_param(ctx,pl, "te").i) { /* eccentricity */
e = pj_param(ctx,pl, "de").f;
if (e < 0) {
- pj_ctx_set_errno(ctx, PJD_ERR_INVALID_ECCENTRICITY);
+ proj_context_errno_set(ctx, PJD_ERR_INVALID_ECCENTRICITY);
return 1;
}
*es = e * e;
} else if (pj_param(ctx,pl, "trf").i) { /* recip flattening */
*es = pj_param(ctx,pl, "drf").f;
if (*es == 0.0) {
- pj_ctx_set_errno(ctx, PJD_ERR_REV_FLATTENING_IS_ZERO);
+ proj_context_errno_set(ctx, PJD_ERR_REV_FLATTENING_IS_ZERO);
goto bomb;
}
*es = 1./ *es;
@@ -700,7 +700,7 @@ int pj_ell_set (projCtx ctx, paralist *pl, double *a, double *es) {
*es = 0.;
} else if (pj_param(ctx,pl, "bR_h").i) { /* sphere--harmonic mean */
if ( (*a + b) == 0.0) {
- pj_ctx_set_errno(ctx, PJD_ERR_TOLERANCE_CONDITION);
+ proj_context_errno_set(ctx, PJD_ERR_TOLERANCE_CONDITION);
goto bomb;
}
*a = 2. * *a * b / (*a + b);
@@ -711,7 +711,7 @@ int pj_ell_set (projCtx ctx, paralist *pl, double *a, double *es) {
tmp = sin(pj_param(ctx,pl, i ? "rR_lat_a" : "rR_lat_g").f);
if (fabs(tmp) > M_HALFPI) {
- pj_ctx_set_errno(ctx, PJD_ERR_REF_RAD_LARGER_THAN_90);
+ proj_context_errno_set(ctx, PJD_ERR_REF_RAD_LARGER_THAN_90);
goto bomb;
}
tmp = 1. - *es * tmp * tmp;
@@ -721,8 +721,8 @@ int pj_ell_set (projCtx ctx, paralist *pl, double *a, double *es) {
}
bomb:
if (start) { /* clean up temporary extension of list */
- pj_dalloc(start->next->next);
- pj_dalloc(start->next);
+ free(start->next->next);
+ free(start->next);
start->next = 0;
}
if (ctx->last_errno)
@@ -730,15 +730,15 @@ bomb:
}
/* some remaining checks */
if (*es < 0.) {
- pj_ctx_set_errno(ctx, PJD_ERR_ES_LESS_THAN_ZERO);
+ proj_context_errno_set(ctx, PJD_ERR_ES_LESS_THAN_ZERO);
return 1;
}
if (*es >= 1.) {
- pj_ctx_set_errno(ctx, PJD_ERR_INVALID_ECCENTRICITY);
+ proj_context_errno_set(ctx, PJD_ERR_INVALID_ECCENTRICITY);
return 1;
}
if (*a <= 0.) {
- pj_ctx_set_errno(ctx, PJD_ERR_MAJOR_AXIS_NOT_GIVEN);
+ proj_context_errno_set(ctx, PJD_ERR_MAJOR_AXIS_NOT_GIVEN);
return 1;
}
return 0;
diff --git a/src/errno.cpp b/src/errno.cpp
deleted file mode 100644
index 4f3119b3..00000000
--- a/src/errno.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/* For full ANSI compliance of global variable */
-
-#include "proj.h"
-#include "proj_internal.h"
-
-int pj_errno = 0;
-
-/************************************************************************/
-/* pj_get_errno_ref() */
-/************************************************************************/
-
-int *pj_get_errno_ref()
-
-{
- return &pj_errno;
-}
-
-/* end */
diff --git a/src/fileapi.cpp b/src/fileapi.cpp
deleted file mode 100644
index 70be2502..00000000
--- a/src/fileapi.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-/******************************************************************************
- * Project: PROJ.4
- * Purpose: Implementation of the pj_ctx_* file api, and the default stdio
- * based implementation.
- * Author: Frank Warmerdam, warmerdam@pobox.com
- *
- ******************************************************************************
- * Copyright (c) 2013, Frank Warmerdam
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *****************************************************************************/
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "proj.h"
-#include "proj_internal.h"
-#include "filemanager.hpp"
-
-static PAFile stdio_fopen(projCtx ctx, const char *filename,
- const char *access);
-static size_t stdio_fread(void *buffer, size_t size, size_t nmemb,
- PAFile file);
-static int stdio_fseek(PAFile file, long offset, int whence);
-static long stdio_ftell(PAFile file);
-static void stdio_fclose(PAFile file);
-
-static projFileAPI default_fileapi = {
- stdio_fopen,
- stdio_fread,
- stdio_fseek,
- stdio_ftell,
- stdio_fclose
-};
-
-typedef struct {
- projCtx ctx;
- FILE *fp;
-} stdio_pafile;
-
-/************************************************************************/
-/* pj_get_default_fileapi() */
-/************************************************************************/
-
-projFileAPI *pj_get_default_fileapi(void)
-{
- return &default_fileapi;
-}
-
-/************************************************************************/
-/* stdio_fopen() */
-/************************************************************************/
-
-static PAFile stdio_fopen(projCtx ctx, const char *filename,
- const char *access)
-{
- stdio_pafile *pafile;
- FILE *fp;
-
- fp = fopen(filename, access);
- if (fp == nullptr)
- {
- return nullptr;
- }
-
- pafile = (stdio_pafile *) malloc(sizeof(stdio_pafile));
- if (!pafile)
- {
- pj_ctx_set_errno(ctx, ENOMEM);
- fclose(fp);
- return nullptr;
- }
-
- pafile->fp = fp;
- pafile->ctx = ctx;
- return (PAFile) pafile;
-}
-
-/************************************************************************/
-/* stdio_fread() */
-/************************************************************************/
-
-static size_t stdio_fread(void *buffer, size_t size, size_t nmemb,
- PAFile file)
-{
- stdio_pafile *pafile = (stdio_pafile *) file;
- return fread(buffer, size, nmemb, pafile->fp);
-}
-
-/************************************************************************/
-/* stdio_fseek() */
-/************************************************************************/
-static int stdio_fseek(PAFile file, long offset, int whence)
-{
- stdio_pafile *pafile = (stdio_pafile *) file;
- return fseek(pafile->fp, offset, whence);
-}
-
-/************************************************************************/
-/* stdio_ftell() */
-/************************************************************************/
-static long stdio_ftell(PAFile file)
-{
- stdio_pafile *pafile = (stdio_pafile *) file;
- return ftell(pafile->fp);
-}
-
-/************************************************************************/
-/* stdio_fclose() */
-/************************************************************************/
-static void stdio_fclose(PAFile file)
-{
- stdio_pafile *pafile = (stdio_pafile *) file;
- fclose(pafile->fp);
- free(pafile);
-}
-
-/************************************************************************/
-/* pj_ctx_fopen() */
-/* */
-/* Open a file using the provided file io hooks. */
-/************************************************************************/
-
-PAFile pj_ctx_fopen(projCtx ctx, const char *filename, const char *access)
-{
- return ctx->fileapi_legacy->FOpen(ctx, filename, access);
-}
-
-/************************************************************************/
-/* pj_ctx_fread() */
-/************************************************************************/
-size_t pj_ctx_fread(projCtx ctx, void *buffer, size_t size, size_t nmemb, PAFile file)
-{
- return ctx->fileapi_legacy->FRead(buffer, size, nmemb, file);
-}
-
-/************************************************************************/
-/* pj_ctx_fseek() */
-/************************************************************************/
-int pj_ctx_fseek(projCtx ctx, PAFile file, long offset, int whence)
-{
- return ctx->fileapi_legacy->FSeek(file, offset, whence);
-}
-
-/************************************************************************/
-/* pj_ctx_ftell() */
-/************************************************************************/
-long pj_ctx_ftell(projCtx ctx, PAFile file)
-{
- return ctx->fileapi_legacy->FTell(file);
-}
-
-/************************************************************************/
-/* pj_ctx_fclose() */
-/************************************************************************/
-void pj_ctx_fclose(projCtx ctx, PAFile file)
-{
- ctx->fileapi_legacy->FClose(file);
-}
-
-/************************************************************************/
-/* pj_ctx_fgets() */
-/* */
-/* A not very optimal implementation of fgets on top of */
-/* fread(). If we end up using this a lot more care should be */
-/* taken. */
-/************************************************************************/
-
-char *pj_ctx_fgets(projCtx ctx, char *line, int size, PAFile file)
-{
- long start = pj_ctx_ftell(ctx, file);
- size_t bytes_read;
- int i;
- int max_size;
-
- line[size-1] = '\0';
- bytes_read = pj_ctx_fread(ctx, line, 1, size-1, file);
- if(bytes_read == 0)
- return nullptr;
- if(bytes_read < (size_t)size)
- {
- line[bytes_read] = '\0';
- }
-
- max_size = (int)MIN(bytes_read, (size_t)(size > 2 ? size - 2 : 0));
- for( i = 0; i < max_size; i++)
- {
- if (line[i] == '\n')
- {
- line[i+1] = '\0';
- pj_ctx_fseek(ctx, file, start + i + 1, SEEK_SET);
- break;
- }
- }
- return line;
-}
-
-/************************************************************************/
-/* pj_ctx_set_fileapi() */
-/************************************************************************/
-
-void pj_ctx_set_fileapi( projCtx ctx, projFileAPI *fileapi )
-
-{
- if (nullptr==ctx)
- return;
- ctx->fileapi_legacy = fileapi;
-}
-
-/************************************************************************/
-/* pj_ctx_get_fileapi() */
-/************************************************************************/
-
-projFileAPI *pj_ctx_get_fileapi( projCtx ctx )
-
-{
- if (nullptr==ctx)
- return nullptr;
- return ctx->fileapi_legacy;
-}
-
diff --git a/src/filemanager.cpp b/src/filemanager.cpp
index e6a9ed95..b51205eb 100644
--- a/src/filemanager.cpp
+++ b/src/filemanager.cpp
@@ -786,75 +786,6 @@ std::unique_ptr<File> FileStdio::open(PJ_CONTEXT *ctx, const char *filename,
// ---------------------------------------------------------------------------
-#ifndef REMOVE_LEGACY_SUPPORT
-
-class FileLegacyAdapter : public File {
- PJ_CONTEXT *m_ctx;
- PAFile m_fp;
-
- FileLegacyAdapter(const FileLegacyAdapter &) = delete;
- FileLegacyAdapter &operator=(const FileLegacyAdapter &) = delete;
-
- protected:
- FileLegacyAdapter(const std::string &filename, PJ_CONTEXT *ctx, PAFile fp)
- : File(filename), m_ctx(ctx), m_fp(fp) {}
-
- public:
- ~FileLegacyAdapter() override;
-
- size_t read(void *buffer, size_t sizeBytes) override;
- size_t write(const void *, size_t) override { return 0; }
- bool seek(unsigned long long offset, int whence = SEEK_SET) override;
- unsigned long long tell() override;
- void reassign_context(PJ_CONTEXT *ctx) override { m_ctx = ctx; }
-
- // We may lie, but the real use case is only for network files
- bool hasChanged() const override { return false; }
-
- static std::unique_ptr<File> open(PJ_CONTEXT *ctx, const char *filename,
- FileAccess access);
-};
-
-// ---------------------------------------------------------------------------
-
-FileLegacyAdapter::~FileLegacyAdapter() { pj_ctx_fclose(m_ctx, m_fp); }
-
-// ---------------------------------------------------------------------------
-
-size_t FileLegacyAdapter::read(void *buffer, size_t sizeBytes) {
- return pj_ctx_fread(m_ctx, buffer, 1, sizeBytes, m_fp);
-}
-
-// ---------------------------------------------------------------------------
-
-bool FileLegacyAdapter::seek(unsigned long long offset, int whence) {
- if (offset != static_cast<unsigned long long>(static_cast<long>(offset))) {
- pj_log(m_ctx, PJ_LOG_ERROR,
- "Attempt at seeking to a 64 bit offset. Not supported yet");
- return false;
- }
- return pj_ctx_fseek(m_ctx, m_fp, static_cast<long>(offset), whence) == 0;
-}
-
-// ---------------------------------------------------------------------------
-
-unsigned long long FileLegacyAdapter::tell() {
- return pj_ctx_ftell(m_ctx, m_fp);
-}
-
-// ---------------------------------------------------------------------------
-
-std::unique_ptr<File>
-FileLegacyAdapter::open(PJ_CONTEXT *ctx, const char *filename, FileAccess) {
- auto fid = pj_ctx_fopen(ctx, filename, "rb");
- return std::unique_ptr<File>(fid ? new FileLegacyAdapter(filename, ctx, fid)
- : nullptr);
-}
-
-#endif // REMOVE_LEGACY_SUPPORT
-
-// ---------------------------------------------------------------------------
-
class FileApiAdapter : public File {
PJ_CONTEXT *m_ctx;
PROJ_FILE_HANDLE *m_fp;
@@ -954,12 +885,6 @@ std::unique_ptr<File> FileManager::open(PJ_CONTEXT *ctx, const char *filename,
}
return pj_network_file_open(ctx, filename);
}
-#ifndef REMOVE_LEGACY_SUPPORT
- // If the user has specified a legacy fileapi, use it
- if (ctx->fileapi_legacy != pj_get_default_fileapi()) {
- return FileLegacyAdapter::open(ctx, filename, access);
- }
-#endif
if (ctx->fileApi.open_cbk != nullptr) {
return FileApiAdapter::open(ctx, filename, access);
}
@@ -1444,10 +1369,10 @@ static bool dontReadUserWritableDirectory() {
return envVar != nullptr && envVar[0] != '\0';
}
-static void *
-pj_open_lib_internal(projCtx ctx, const char *name, const char *mode,
- void *(*open_file)(projCtx, const char *, const char *),
- char *out_full_filename, size_t out_full_filename_size) {
+static void *pj_open_lib_internal(
+ PJ_CONTEXT *ctx, const char *name, const char *mode,
+ void *(*open_file)(PJ_CONTEXT *, const char *, const char *),
+ char *out_full_filename, size_t out_full_filename_size) {
try {
std::string fname;
const char *sysname = nullptr;
@@ -1493,10 +1418,6 @@ pj_open_lib_internal(projCtx ctx, const char *name, const char *mode,
ctx, name, ctx->file_finder_user_data)) != nullptr)
;
- else if (ctx->file_finder_legacy != nullptr &&
- (sysname = ctx->file_finder_legacy(name)) != nullptr)
- ;
-
/* The user has search paths set */
else if (!ctx->search_paths.empty()) {
for (const auto &path : ctx->search_paths) {
@@ -1566,7 +1487,7 @@ pj_open_lib_internal(projCtx ctx, const char *name, const char *mode,
}
if (ctx->last_errno == 0 && errno != 0)
- pj_ctx_set_errno(ctx, errno);
+ proj_context_errno_set(ctx, errno);
pj_log(ctx, PJ_LOG_DEBUG_MAJOR, "pj_open_lib(%s): call fopen(%s) - %s",
name, sysname, fid == nullptr ? "failed" : "succeeded");
@@ -1617,7 +1538,7 @@ std::vector<std::string> pj_get_default_searchpaths(PJ_CONTEXT *ctx) {
/* pj_open_file_with_manager() */
/************************************************************************/
-static void *pj_open_file_with_manager(projCtx ctx, const char *name,
+static void *pj_open_file_with_manager(PJ_CONTEXT *ctx, const char *name,
const char * /* mode */) {
return NS_PROJ::FileManager::open(ctx, name, NS_PROJ::FileAccess::READ_ONLY)
.release();
@@ -1639,7 +1560,7 @@ static NS_PROJ::io::DatabaseContextPtr getDBcontext(PJ_CONTEXT *ctx) {
/************************************************************************/
std::unique_ptr<NS_PROJ::File>
-NS_PROJ::FileManager::open_resource_file(projCtx ctx, const char *name) {
+NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name) {
if (ctx == nullptr) {
ctx = pj_get_default_ctx();
@@ -1666,7 +1587,7 @@ NS_PROJ::FileManager::open_resource_file(projCtx ctx, const char *name) {
pj_open_file_with_manager, nullptr,
0)));
if (file) {
- pj_ctx_set_errno(ctx, 0);
+ proj_context_errno_set(ctx, 0);
} else {
// For final network access attempt, use the new
// name.
@@ -1696,7 +1617,7 @@ NS_PROJ::FileManager::open_resource_file(projCtx ctx, const char *name) {
pj_open_file_with_manager, nullptr,
0)));
if (file) {
- pj_ctx_set_errno(ctx, 0);
+ proj_context_errno_set(ctx, 0);
}
}
} catch (const std::exception &e) {
@@ -1721,7 +1642,7 @@ NS_PROJ::FileManager::open_resource_file(projCtx ctx, const char *name) {
if (file) {
pj_log(ctx, PJ_LOG_DEBUG_MAJOR, "Using %s",
remote_file.c_str());
- pj_ctx_set_errno(ctx, 0);
+ proj_context_errno_set(ctx, 0);
}
}
}
@@ -1729,26 +1650,6 @@ NS_PROJ::FileManager::open_resource_file(projCtx ctx, const char *name) {
}
/************************************************************************/
-/* pj_open_lib() */
-/************************************************************************/
-
-#ifndef REMOVE_LEGACY_SUPPORT
-
-// Used by following legacy function
-static void *pj_ctx_fopen_adapter(projCtx ctx, const char *name,
- const char *mode) {
- return pj_ctx_fopen(ctx, name, mode);
-}
-
-// Legacy function
-PAFile pj_open_lib(projCtx ctx, const char *name, const char *mode) {
- return (PAFile)pj_open_lib_internal(ctx, name, mode, pj_ctx_fopen_adapter,
- nullptr, 0);
-}
-
-#endif // REMOVE_LEGACY_SUPPORT
-
-/************************************************************************/
/* pj_find_file() */
/************************************************************************/
@@ -1764,7 +1665,7 @@ PAFile pj_open_lib(projCtx ctx, const char *name, const char *mode) {
* @param out_full_filename_size size of out_full_filename.
* @return 1 if the file was found, 0 otherwise.
*/
-int pj_find_file(projCtx ctx, const char *short_filename,
+int pj_find_file(PJ_CONTEXT *ctx, const char *short_filename,
char *out_full_filename, size_t out_full_filename_size) {
auto file = std::unique_ptr<NS_PROJ::File>(
reinterpret_cast<NS_PROJ::File *>(pj_open_lib_internal(
@@ -1812,7 +1713,7 @@ static std::string trim(const std::string &s) {
/* pj_load_ini() */
/************************************************************************/
-void pj_load_ini(projCtx ctx) {
+void pj_load_ini(PJ_CONTEXT *ctx) {
if (ctx->iniFileLoaded)
return;
@@ -1891,19 +1792,6 @@ void pj_load_ini(projCtx ctx) {
//! @endcond
/************************************************************************/
-/* pj_set_finder() */
-/************************************************************************/
-
-void pj_set_finder(const char *(*new_finder)(const char *))
-
-{
- auto ctx = pj_get_default_ctx();
- if (ctx) {
- ctx->file_finder_legacy = new_finder;
- }
-}
-
-/************************************************************************/
/* proj_context_set_file_finder() */
/************************************************************************/
@@ -1974,19 +1862,6 @@ void proj_context_set_search_paths(PJ_CONTEXT *ctx, int count_paths,
}
/************************************************************************/
-/* pj_set_searchpath() */
-/* */
-/* Path control for callers that can't practically provide */
-/* pj_set_finder() style callbacks. Call with (0,NULL) as args */
-/* to clear the searchpath set. */
-/************************************************************************/
-
-void pj_set_searchpath(int count, const char **path) {
- proj_context_set_search_paths(nullptr, count,
- const_cast<const char *const *>(path));
-}
-
-/************************************************************************/
/* proj_context_set_ca_bundle_path() */
/************************************************************************/
diff --git a/src/gauss.cpp b/src/gauss.cpp
index a34a8f5b..96bd5166 100644
--- a/src/gauss.cpp
+++ b/src/gauss.cpp
@@ -81,7 +81,7 @@ void *pj_gauss_ini(double e, double phi0, double *chi, double *rc) {
return ((void *)en);
}
-PJ_LP pj_gauss(projCtx ctx, PJ_LP elp, const void *data) {
+PJ_LP pj_gauss(PJ_CONTEXT *ctx, PJ_LP elp, const void *data) {
const struct GAUSS *en = (const struct GAUSS *)data;
PJ_LP slp;
(void) ctx;
@@ -93,7 +93,7 @@ PJ_LP pj_gauss(projCtx ctx, PJ_LP elp, const void *data) {
return(slp);
}
-PJ_LP pj_inv_gauss(projCtx ctx, PJ_LP slp, const void *data) {
+PJ_LP pj_inv_gauss(PJ_CONTEXT *ctx, PJ_LP slp, const void *data) {
const struct GAUSS *en = (const struct GAUSS *)data;
PJ_LP elp;
double num;
@@ -109,6 +109,6 @@ PJ_LP pj_inv_gauss(projCtx ctx, PJ_LP slp, const void *data) {
}
/* convergence failed */
if (!i)
- pj_ctx_set_errno(ctx, PJD_ERR_NON_CONV_INV_MERI_DIST);
+ proj_context_errno_set(ctx, PJD_ERR_NON_CONV_INV_MERI_DIST);
return (elp);
}
diff --git a/src/generic_inverse.cpp b/src/generic_inverse.cpp
index a15cfae1..ddd5060b 100644
--- a/src/generic_inverse.cpp
+++ b/src/generic_inverse.cpp
@@ -109,6 +109,6 @@ PJ_LP pj_generic_inverse_2d(PJ_XY xy, PJ *P, PJ_LP lpInitial) {
lp.phi = M_HALFPI;
}
}
- pj_ctx_set_errno(P->ctx, PJD_ERR_NON_CONVERGENT);
+ proj_context_errno_set(P->ctx, PJD_ERR_NON_CONVERGENT);
return lp;
}
diff --git a/src/geodesic.c b/src/geodesic.c
index 7d612d3f..53ec9ed6 100644
--- a/src/geodesic.c
+++ b/src/geodesic.c
@@ -18,7 +18,7 @@
*
* See the comments in geodesic.h for documentation.
*
- * Copyright (c) Charles Karney (2012-2019) <charles@karney.com> and licensed
+ * Copyright (c) Charles Karney (2012-2020) <charles@karney.com> and licensed
* under the MIT/X11 License. For more information, see
* https://geographiclib.sourceforge.io/
*/
@@ -28,15 +28,6 @@
#include <limits.h>
#include <float.h>
-#if !defined(HAVE_C99_MATH)
-#if defined(PROJ_LIB)
-/* PROJ requires C99 so HAVE_C99_MATH is implicit */
-#define HAVE_C99_MATH 1
-#else
-#define HAVE_C99_MATH 0
-#endif
-#endif
-
#if !defined(__cplusplus)
#define nullptr 0
#endif
@@ -88,19 +79,7 @@ static void Init() {
tolb = tol0 * tol2;
xthresh = 1000 * tol2;
degree = pi/180;
-#if defined(NAN)
- NaN = NAN; /* NAN is defined in C99 */
-#else
-#if HAVE_C99_MATH
NaN = nan("0");
-#else
- {
- real minus1 = -1;
- /* cppcheck-suppress wrongmathcall */
- NaN = sqrt(minus1);
- }
-#endif
-#endif
init = 1;
}
}
@@ -116,95 +95,6 @@ enum captype {
OUT_ALL = 0x7F80U
};
-#if HAVE_C99_MATH
-#define hypotx hypot
-/* no need to redirect log1px, since it's only used by atanhx */
-#define atanhx atanh
-#define copysignx copysign
-#define cbrtx cbrt
-#define remainderx remainder
-#define remquox remquo
-#else
-/* Replacements for C99 math functions */
-
-static real hypotx(real x, real y) {
- x = fabs(x); y = fabs(y);
- if (x < y) {
- x /= y; /* y is nonzero */
- return y * sqrt(1 + x * x);
- } else {
- y /= (x != 0 ? x : 1);
- return x * sqrt(1 + y * y);
- }
-}
-
-static real log1px(real x) {
- volatile real
- y = 1 + x,
- z = y - 1;
- /* Here's the explanation for this magic: y = 1 + z, exactly, and z
- * approx x, thus log(y)/z (which is nearly constant near z = 0) returns
- * a good approximation to the true log(1 + x)/x. The multiplication x *
- * (log(y)/z) introduces little additional error. */
- return z == 0 ? x : x * log(y) / z;
-}
-
-static real atanhx(real x) {
- real y = fabs(x); /* Enforce odd parity */
- y = log1px(2 * y/(1 - y))/2;
- return x > 0 ? y : (x < 0 ? -y : x); /* atanh(-0.0) = -0.0 */
-}
-
-static real copysignx(real x, real y) {
- /* 1/y trick to get the sign of -0.0 */
- return fabs(x) * (y < 0 || (y == 0 && 1/y < 0) ? -1 : 1);
-}
-
-static real cbrtx(real x) {
- real y = pow(fabs(x), 1/(real)(3)); /* Return the real cube root */
- return x > 0 ? y : (x < 0 ? -y : x); /* cbrt(-0.0) = -0.0 */
-}
-
-static real remainderx(real x, real y) {
- real z;
- y = fabs(y); /* The result doesn't depend on the sign of y */
- z = fmod(x, y);
- if (z == 0)
- /* This shouldn't be necessary. However, before version 14 (2015),
- * Visual Studio had problems dealing with -0.0. Specifically
- * VC 10,11,12 and 32-bit compile: fmod(-0.0, 360.0) -> +0.0
- * python 2.7 on Windows 32-bit machines has the same problem. */
- z = copysignx(z, x);
- else if (2 * fabs(z) == y)
- z -= fmod(x, 2 * y) - z; /* Implement ties to even */
- else if (2 * fabs(z) > y)
- z += (z < 0 ? y : -y); /* Fold remaining cases to (-y/2, y/2) */
- return z;
-}
-
-static real remquox(real x, real y, int* n) {
- real z = remainderx(x, y);
- if (n) {
- real
- a = remainderx(x, 2 * y),
- b = remainderx(x, 4 * y),
- c = remainderx(x, 8 * y);
- *n = (a > z ? 1 : (a < z ? -1 : 0));
- *n += (b > a ? 2 : (b < a ? -2 : 0));
- *n += (c > b ? 4 : (c < b ? -4 : 0));
- if (y < 0) *n *= -1;
- if (y != 0) {
- if (x/y > 0 && *n <= 0)
- *n += 8;
- else if (x/y < 0 && *n >= 0)
- *n -= 8;
- }
- }
- return z;
-}
-
-#endif
-
static real sq(real x) { return x * x; }
static real sumx(real u, real v, real* t) {
@@ -237,13 +127,13 @@ static void swapx(real* x, real* y)
{ real t = *x; *x = *y; *y = t; }
static void norm2(real* sinx, real* cosx) {
- real r = hypotx(*sinx, *cosx);
+ real r = hypot(*sinx, *cosx);
*sinx /= r;
*cosx /= r;
}
static real AngNormalize(real x) {
- x = remainderx(x, (real)(360));
+ x = remainder(x, (real)(360));
return x != -180 ? x : 180;
}
@@ -275,7 +165,7 @@ static void sincosdx(real x, real* sinx, real* cosx) {
/* In order to minimize round-off errors, this function exactly reduces
* the argument to the range [-45, 45] before converting it to radians. */
real r, s, c; int q;
- r = remquox(x, (real)(90), &q);
+ r = remquo(x, (real)(90), &q);
/* now abs(r) <= 45 */
r *= degree;
/* Possibly could call the gnu extension sincos */
@@ -396,7 +286,7 @@ void geod_init(struct geod_geodesic* g, real a, real f) {
g->b = g->a * g->f1;
g->c2 = (sq(g->a) + sq(g->b) *
(g->e2 == 0 ? 1 :
- (g->e2 > 0 ? atanhx(sqrt(g->e2)) : atan(sqrt(-g->e2))) /
+ (g->e2 > 0 ? atanh(sqrt(g->e2)) : atan(sqrt(-g->e2))) /
sqrt(fabs(g->e2))))/2; /* authalic radius squared */
/* The sig12 threshold for "really short". Using the auxiliary sphere
* solution with dnm computed at (bet1 + bet2) / 2, the relative error in the
@@ -446,7 +336,7 @@ static void geod_lineinit_int(struct geod_geodesicline* l,
l->salp0 = l->salp1 * cbet1; /* alp0 in [0, pi/2 - |bet1|] */
/* Alt: calp0 = hypot(sbet1, calp1 * cbet1). The following
* is slightly better (consider the case salp1 = 0). */
- l->calp0 = hypotx(l->calp1, l->salp1 * sbet1);
+ l->calp0 = hypot(l->calp1, l->salp1 * sbet1);
/* Evaluate sig with tan(bet1) = tan(sig1) * cos(alp1).
* sig = 0 is nearest northward crossing of equator.
* With bet1 = 0, alp1 = pi/2, we have sig1 = 0 (equatorial line).
@@ -550,9 +440,8 @@ real geod_genposition(const struct geod_geodesicline* l,
(pS12 ? GEOD_AREA : GEOD_NONE);
outmask &= l->caps & OUT_ALL;
- if (!( /*Init() &&*/
- (flags & GEOD_ARCMODE || (l->caps & (GEOD_DISTANCE_IN & OUT_ALL))) ))
- /* Uninitialized or impossible distance calculation requested */
+ if (!( (flags & GEOD_ARCMODE || (l->caps & (GEOD_DISTANCE_IN & OUT_ALL))) ))
+ /* Impossible distance calculation requested */
return NaN;
if (flags & GEOD_ARCMODE) {
@@ -617,7 +506,7 @@ real geod_genposition(const struct geod_geodesicline* l,
/* sin(bet2) = cos(alp0) * sin(sig2) */
sbet2 = l->calp0 * ssig2;
/* Alt: cbet2 = hypot(csig2, salp0 * ssig2); */
- cbet2 = hypotx(l->salp0, l->calp0 * csig2);
+ cbet2 = hypot(l->salp0, l->calp0 * csig2);
if (cbet2 == 0)
/* I.e., salp0 = 0, csig2 = 0. Break the degeneracy in this case */
cbet2 = csig2 = tiny;
@@ -630,7 +519,7 @@ real geod_genposition(const struct geod_geodesicline* l,
s12_a12;
if (outmask & GEOD_LONGITUDE) {
- real E = copysignx(1, l->salp0); /* east or west going? */
+ real E = copysign(1, l->salp0); /* east or west going? */
/* tan(omg2) = sin(alp0) * tan(sig2) */
somg2 = l->salp0 * ssig2; comg2 = csig2; /* No need to normalize */
/* omg12 = omg2 - omg1 */
@@ -1045,7 +934,7 @@ static real geod_geninverse_int(const struct geod_geodesic* g,
real
/* From Lambda12: sin(alp1) * cos(bet1) = sin(alp0) */
salp0 = salp1 * cbet1,
- calp0 = hypotx(calp1, salp1 * sbet1); /* calp0 > 0 */
+ calp0 = hypot(calp1, salp1 * sbet1); /* calp0 > 0 */
real alp12;
if (calp0 != 0 && salp0 != 0) {
real
@@ -1279,8 +1168,8 @@ real Astroid(real x, real y) {
* of precision due to cancellation. The result is unchanged because
* of the way the T is used in definition of u. */
T3 += T3 < 0 ? -sqrt(disc) : sqrt(disc); /* T3 = (r * t)^3 */
- /* N.B. cbrtx always returns the real root. cbrtx(-8) = -2. */
- T = cbrtx(T3); /* T = r * t */
+ /* N.B. cbrt always returns the real root. cbrt(-8) = -2. */
+ T = cbrt(T3); /* T = r * t */
/* T can be zero; but then r2 / T -> 0. */
u += T + (T != 0 ? r2 / T : 0);
} else {
@@ -1348,7 +1237,7 @@ real InverseStart(const struct geod_geodesic* g,
sbet12 + cbet2 * sbet1 * sq(somg12) / (1 + comg12) :
sbet12a - cbet2 * sbet1 * sq(somg12) / (1 - comg12);
- ssig12 = hypotx(salp1, calp1);
+ ssig12 = hypot(salp1, calp1);
csig12 = sbet1 * sbet2 + cbet1 * cbet2 * comg12;
if (shortline && ssig12 < g->etol2) {
@@ -1500,7 +1389,7 @@ real Lambda12(const struct geod_geodesic* g,
/* sin(alp1) * cos(bet1) = sin(alp0) */
salp0 = salp1 * cbet1;
- calp0 = hypotx(calp1, salp1 * sbet1); /* calp0 > 0 */
+ calp0 = hypot(calp1, salp1 * sbet1); /* calp0 > 0 */
/* tan(bet1) = tan(sig1) * cos(alp1)
* tan(omg1) = sin(alp0) * tan(sig1) = tan(omg1)=tan(alp1)*sin(bet1) */
@@ -1850,8 +1739,8 @@ int transit(real lon1, real lon2) {
int transitdirect(real lon1, real lon2) {
/* Compute exactly the parity of
int(ceil(lon2 / 360)) - int(ceil(lon1 / 360)) */
- lon1 = remainderx(lon1, (real)(720));
- lon2 = remainderx(lon2, (real)(720));
+ lon1 = remainder(lon1, (real)(720));
+ lon2 = remainder(lon2, (real)(720));
return ( (lon2 <= 0 && lon2 > -360 ? 1 : 0) -
(lon1 <= 0 && lon1 > -360 ? 1 : 0) );
}
@@ -1891,7 +1780,7 @@ void accneg(real s[]) {
void accrem(real s[], real y) {
/* Reduce to [-y/2, y/2]. */
- s[0] = remainderx(s[0], y);
+ s[0] = remainder(s[0], y);
accadd(s, (real)(0));
}
@@ -2093,7 +1982,7 @@ real areareduceA(real area[], real area0,
real areareduceB(real area, real area0,
int crossings, boolx reverse, boolx sign) {
- area = remainderx(area, area0);
+ area = remainder(area, area0);
if (crossings & 1)
area += (area < 0 ? 1 : -1) * area0/2;
/* area is with the clockwise sense. If !reverse convert to
diff --git a/src/geodesic.h b/src/geodesic.h
index b21e6c8c..548fbf47 100644
--- a/src/geodesic.h
+++ b/src/geodesic.h
@@ -107,12 +107,12 @@
* twice about restructuring the internals of the C code since this may make
* porting fixes from the C++ code more difficult.
*
- * Copyright (c) Charles Karney (2012-2019) <charles@karney.com> and licensed
+ * Copyright (c) Charles Karney (2012-2020) <charles@karney.com> and licensed
* under the MIT/X11 License. For more information, see
* https://geographiclib.sourceforge.io/
*
* This library was distributed with
- * <a href="../index.html">GeographicLib</a> 1.50.
+ * <a href="../index.html">GeographicLib</a> 1.51.
**********************************************************************/
#if !defined(GEODESIC_H)
@@ -127,7 +127,7 @@
* The minor version of the geodesic library. (This tracks the version of
* GeographicLib.)
**********************************************************************/
-#define GEODESIC_VERSION_MINOR 50
+#define GEODESIC_VERSION_MINOR 51
/**
* The patch level of the geodesic library. (This tracks the version of
* GeographicLib.)
diff --git a/src/grids.cpp b/src/grids.cpp
index 8065813a..871e21ed 100644
--- a/src/grids.cpp
+++ b/src/grids.cpp
@@ -197,7 +197,7 @@ GTXVerticalShiftGrid *GTXVerticalShiftGrid::open(PJ_CONTEXT *ctx,
/* Read the header. */
/* -------------------------------------------------------------------- */
if (fp->read(header, sizeof(header)) != sizeof(header)) {
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
@@ -223,7 +223,7 @@ GTXVerticalShiftGrid *GTXVerticalShiftGrid::open(PJ_CONTEXT *ctx,
if (xorigin < -360 || xorigin > 360 || yorigin < -90 || yorigin > 90) {
pj_log(ctx, PJ_LOG_ERROR,
"gtx file header has invalid extents, corrupt?");
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
@@ -258,7 +258,7 @@ bool GTXVerticalShiftGrid::valueAt(int x, int y, float &out) const {
m_fp->seek(40 + sizeof(float) * (y * m_width + x));
if (m_fp->read(&out, sizeof(out)) != sizeof(out)) {
- pj_ctx_set_errno(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return false;
}
if (IS_LSB) {
@@ -1389,7 +1389,7 @@ VerticalShiftGridSet::open(PJ_CONTEXT *ctx, const std::string &filename) {
auto set = std::unique_ptr<VerticalShiftGridSet>(
GTiffVGridShiftSet::open(ctx, std::move(fp), actualName));
if (!set)
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return set;
#else
pj_log(ctx, PJ_LOG_ERROR,
@@ -1570,7 +1570,7 @@ NTv1Grid *NTv1Grid::open(PJ_CONTEXT *ctx, std::unique_ptr<File> fp,
/* Read the header. */
/* -------------------------------------------------------------------- */
if (fp->read(header, sizeof(header)) != sizeof(header)) {
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
@@ -1590,7 +1590,7 @@ NTv1Grid *NTv1Grid::open(PJ_CONTEXT *ctx, std::unique_ptr<File> fp,
if (*((int *)(header + 8)) != 12) {
pj_log(ctx, PJ_LOG_ERROR,
"NTv1 grid shift file has wrong record count, corrupt?");
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
@@ -1609,7 +1609,7 @@ NTv1Grid *NTv1Grid::open(PJ_CONTEXT *ctx, std::unique_ptr<File> fp,
extent.resY > 1e-10)) {
pj_log(ctx, PJ_LOG_ERROR, "Inconsistent georeferencing for %s",
filename.c_str());
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
const int columns = static_cast<int>(
@@ -1631,7 +1631,7 @@ bool NTv1Grid::valueAt(int x, int y, bool compensateNTConvention,
m_fp->seek(192 + 2 * sizeof(double) * (y * m_width + m_width - 1 - x));
if (m_fp->read(&two_doubles[0], sizeof(two_doubles)) !=
sizeof(two_doubles)) {
- pj_ctx_set_errno(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return false;
}
if (IS_LSB) {
@@ -1692,7 +1692,7 @@ CTable2Grid *CTable2Grid::open(PJ_CONTEXT *ctx, std::unique_ptr<File> fp,
/* Read the header. */
/* -------------------------------------------------------------------- */
if (fp->read(header, sizeof(header)) != sizeof(header)) {
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
@@ -1718,7 +1718,7 @@ CTable2Grid *CTable2Grid::open(PJ_CONTEXT *ctx, std::unique_ptr<File> fp,
extent.resX > 1e-10 && extent.resY > 1e-10)) {
pj_log(ctx, PJ_LOG_ERROR, "Inconsistent georeferencing for %s",
filename.c_str());
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
int width;
@@ -1726,7 +1726,7 @@ CTable2Grid *CTable2Grid::open(PJ_CONTEXT *ctx, std::unique_ptr<File> fp,
memcpy(&width, header + 128, 4);
memcpy(&height, header + 132, 4);
if (width <= 0 || height <= 0) {
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
extent.east = extent.west + (width - 1) * extent.resX;
@@ -1744,7 +1744,7 @@ bool CTable2Grid::valueAt(int x, int y, bool compensateNTConvention,
float two_floats[2];
m_fp->seek(160 + 2 * sizeof(float) * (y * m_width + x));
if (m_fp->read(&two_floats[0], sizeof(two_floats)) != sizeof(two_floats)) {
- pj_ctx_set_errno(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return false;
}
if (!IS_LSB) {
@@ -1828,7 +1828,7 @@ bool NTv2Grid::valueAt(int x, int y, bool compensateNTConvention,
4 * sizeof(float) *
(static_cast<unsigned long long>(y) * m_width + m_width - 1 - x));
if (m_fp->read(&two_float[0], sizeof(two_float)) != sizeof(two_float)) {
- pj_ctx_set_errno(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return false;
}
if (m_mustSwap) {
@@ -1862,14 +1862,14 @@ std::unique_ptr<NTv2GridSet> NTv2GridSet::open(PJ_CONTEXT *ctx,
/* Read the header. */
/* -------------------------------------------------------------------- */
if (fpRaw->read(header, sizeof(header)) != sizeof(header)) {
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
constexpr int OFFSET_GS_TYPE = 56;
if (memcmp(header + OFFSET_GS_TYPE, "SECONDS", 7) != 0) {
pj_log(ctx, PJ_LOG_ERROR, "Only GS_TYPE=SECONDS is supported");
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
@@ -1899,12 +1899,12 @@ std::unique_ptr<NTv2GridSet> NTv2GridSet::open(PJ_CONTEXT *ctx,
for (unsigned subfile = 0; subfile < num_subfiles; subfile++) {
// Read header
if (fpRaw->read(header, sizeof(header)) != sizeof(header)) {
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
if (strncmp(header, "SUB_NAME", 8) != 0) {
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
@@ -1946,7 +1946,7 @@ std::unique_ptr<NTv2GridSet> NTv2GridSet::open(PJ_CONTEXT *ctx,
extent.resY > 1e-10)) {
pj_log(ctx, PJ_LOG_ERROR, "Inconsistent georeferencing for %s",
filename.c_str());
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
const int columns = static_cast<int>(
@@ -1966,7 +1966,7 @@ std::unique_ptr<NTv2GridSet> NTv2GridSet::open(PJ_CONTEXT *ctx,
pj_log(ctx, PJ_LOG_ERROR,
"GS_COUNT(%u) does not match expected cells (%dx%d)",
gs_count, columns, rows);
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return nullptr;
}
@@ -2367,7 +2367,7 @@ HorizontalShiftGridSet::open(PJ_CONTEXT *ctx, const std::string &filename) {
auto set = std::unique_ptr<HorizontalShiftGridSet>(
GTiffHGridShiftSet::open(ctx, std::move(fp), actualName));
if (!set)
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return set;
#else
pj_log(ctx, PJ_LOG_ERROR,
@@ -2703,7 +2703,7 @@ GenericShiftGridSet::open(PJ_CONTEXT *ctx, const std::string &filename) {
auto set = std::unique_ptr<GenericShiftGridSet>(
GTiffGenericGridShiftSet::open(ctx, std::move(fp), actualName));
if (!set)
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return set;
#else
pj_log(ctx, PJ_LOG_ERROR,
@@ -2786,11 +2786,12 @@ ListOfGenericGrids pj_generic_grid_init(PJ *P, const char *gridkey) {
if (!gridSet) {
if (!canFail) {
if (proj_context_errno(P->ctx) != PJD_ERR_NETWORK_ERROR) {
- pj_ctx_set_errno(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
}
return {};
}
- pj_ctx_set_errno(P->ctx, 0); // don't treat as a persistent error
+ proj_context_errno_set(P->ctx,
+ 0); // don't treat as a persistent error
} else {
grids.emplace_back(std::move(gridSet));
}
@@ -2830,11 +2831,11 @@ static ListOfHGrids getListOfGridSets(PJ_CONTEXT *ctx, const char *grids) {
if (!gridSet) {
if (!canFail) {
if (proj_context_errno(ctx) != PJD_ERR_NETWORK_ERROR) {
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
}
return {};
}
- pj_ctx_set_errno(ctx, 0); // don't treat as a persistent error
+ proj_context_errno_set(ctx, 0); // don't treat as a persistent error
} else {
list.emplace_back(std::move(gridSet));
}
@@ -2948,7 +2949,7 @@ static PJ_LP pj_hgrid_interpolate(PJ_LP t, const HorizontalShiftGrid *grid,
#define MAX_ITERATIONS 10
#define TOL 1e-12
-static PJ_LP pj_hgrid_apply_internal(projCtx ctx, PJ_LP in,
+static PJ_LP pj_hgrid_apply_internal(PJ_CONTEXT *ctx, PJ_LP in,
PJ_DIRECTION direction,
const HorizontalShiftGrid *grid,
HorizontalShiftGridSet *gridset,
@@ -3066,7 +3067,7 @@ PJ_LP pj_hgrid_apply(PJ_CONTEXT *ctx, const ListOfHGrids &grids, PJ_LP lp,
HorizontalShiftGridSet *gridset = nullptr;
const auto grid = findGrid(grids, lp, gridset);
if (!grid) {
- pj_ctx_set_errno(ctx, PJD_ERR_GRID_AREA);
+ proj_context_errno_set(ctx, PJD_ERR_GRID_AREA);
return out;
}
if (grid->isNullGrid()) {
@@ -3082,7 +3083,7 @@ PJ_LP pj_hgrid_apply(PJ_CONTEXT *ctx, const ListOfHGrids &grids, PJ_LP lp,
}
if (out.lam == HUGE_VAL || out.phi == HUGE_VAL)
- pj_ctx_set_errno(ctx, PJD_ERR_GRID_AREA);
+ proj_context_errno_set(ctx, PJD_ERR_GRID_AREA);
return out;
}
@@ -3098,7 +3099,7 @@ PJ_LP pj_hgrid_value(PJ *P, const ListOfHGrids &grids, PJ_LP lp) {
HorizontalShiftGridSet *gridset = nullptr;
const auto grid = findGrid(grids, lp, gridset);
if (!grid) {
- pj_ctx_set_errno(P->ctx, PJD_ERR_GRID_AREA);
+ proj_context_errno_set(P->ctx, PJD_ERR_GRID_AREA);
return out;
}
@@ -3107,7 +3108,7 @@ PJ_LP pj_hgrid_value(PJ *P, const ListOfHGrids &grids, PJ_LP lp) {
if (!extent.isGeographic) {
pj_log(P->ctx, PJ_LOG_ERROR,
"Can only handle grids referenced in a geographic CRS");
- pj_ctx_set_errno(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return out;
}
@@ -3130,7 +3131,7 @@ PJ_LP pj_hgrid_value(PJ *P, const ListOfHGrids &grids, PJ_LP lp) {
}
if (out.lam == HUGE_VAL || out.phi == HUGE_VAL) {
- pj_ctx_set_errno(P->ctx, PJD_ERR_GRID_AREA);
+ proj_context_errno_set(P->ctx, PJD_ERR_GRID_AREA);
}
return out;
@@ -3157,7 +3158,7 @@ static double read_vgrid_value(PJ_CONTEXT *ctx, const ListOfVGrids &grids,
}
}
if (!grid) {
- pj_ctx_set_errno(ctx, PJD_ERR_GRID_AREA);
+ proj_context_errno_set(ctx, PJD_ERR_GRID_AREA);
return HUGE_VAL;
}
if (grid->isNullGrid()) {
@@ -3168,7 +3169,7 @@ static double read_vgrid_value(PJ_CONTEXT *ctx, const ListOfVGrids &grids,
if (!extent.isGeographic) {
pj_log(ctx, PJ_LOG_ERROR,
"Can only handle grids referenced in a geographic CRS");
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return HUGE_VAL;
}
@@ -3200,7 +3201,7 @@ static double read_vgrid_value(PJ_CONTEXT *ctx, const ListOfVGrids &grids,
if (!(grid_ix >= 0 && grid_ix < grid->width())) {
// in the unlikely case we end up here...
pj_log(ctx, PJ_LOG_ERROR, "grid_ix not in grid");
- pj_ctx_set_errno(ctx, PJD_ERR_GRID_AREA);
+ proj_context_errno_set(ctx, PJD_ERR_GRID_AREA);
return HUGE_VAL;
}
int grid_iy = static_cast<int>(lround(floor(grid_y)));
@@ -3309,11 +3310,12 @@ ListOfVGrids pj_vgrid_init(PJ *P, const char *gridkey) {
if (!gridSet) {
if (!canFail) {
if (proj_context_errno(P->ctx) != PJD_ERR_NETWORK_ERROR) {
- pj_ctx_set_errno(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
}
return {};
}
- pj_ctx_set_errno(P->ctx, 0); // don't treat as a persistent error
+ proj_context_errno_set(P->ctx,
+ 0); // don't treat as a persistent error
} else {
grids.emplace_back(std::move(gridSet));
}
@@ -3377,7 +3379,7 @@ bool pj_bilinear_interpolation_three_samples(
if (!extent.isGeographic) {
pj_log(ctx, PJ_LOG_ERROR,
"Can only handle grids referenced in a geographic CRS");
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
return false;
}
@@ -3442,50 +3444,3 @@ bool pj_bilinear_interpolation_three_samples(
}
NS_PROJ_END
-
-/************************************************************************/
-/* pj_apply_gridshift() */
-/* */
-/* This is the externally callable interface - part of the */
-/* public API - though it is not used internally any more and I */
-/* doubt it is used by any other applications. But we preserve */
-/* it to honour our public api. */
-/************************************************************************/
-
-int pj_apply_gridshift(projCtx ctx, const char *nadgrids, int inverse,
- long point_count, int point_offset, double *x, double *y,
- double * /*z */)
-
-{
- auto hgrids = NS_PROJ::getListOfGridSets(ctx, nadgrids);
- if (hgrids.empty()) {
- pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
- return 1;
- }
-
- for (long i = 0; i < point_count; i++) {
- PJ_LP input;
-
- long io = i * point_offset;
- input.phi = y[io];
- input.lam = x[io];
-
- auto output =
- pj_hgrid_apply(ctx, hgrids, input, inverse ? PJ_INV : PJ_FWD);
-
- if (output.lam != HUGE_VAL) {
- y[io] = output.phi;
- x[io] = output.lam;
- } else {
- if (ctx->debug_level >= PJ_LOG_DEBUG_MAJOR) {
- pj_log(ctx, PJ_LOG_DEBUG_MAJOR,
- "pj_apply_gridshift(): failed to find a grid shift "
- "table for\n"
- " location (%.7fdW,%.7fdN)",
- x[io] * RAD_TO_DEG, y[io] * RAD_TO_DEG);
- }
- }
- }
-
- return 0;
-}
diff --git a/src/init.cpp b/src/init.cpp
index 101fc8ad..1e89402d 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1,7 +1,7 @@
/******************************************************************************
* Project: PROJ.4
* Purpose: Initialize projection object from string definition. Includes
- * pj_init(), pj_init_plus() and pj_free() function.
+ * pj_init(), and pj_init_plus() function.
* Author: Gerald Evenden, Frank Warmerdam <warmerdam@pobox.com>
*
******************************************************************************
@@ -55,7 +55,7 @@ static paralist *string_to_paralist (PJ_CONTEXT *ctx, char *definition) {
/* Keep a handle to the start of the list, so we have something to return */
auto param = pj_mkparam_ws (c, &c);
if (nullptr==param) {
- pj_dealloc_params (ctx, first, ENOMEM);
+ free_params (ctx, first, ENOMEM);
return nullptr;
}
if (nullptr==last) {
@@ -84,7 +84,7 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) {
char *buffer = nullptr;
size_t n;
- fname = static_cast<char*>(pj_malloc (MAX_PATH_FILENAME+ID_TAG_MAX+3));
+ fname = static_cast<char*>(malloc (MAX_PATH_FILENAME+ID_TAG_MAX+3));
if (nullptr==fname) {
return nullptr;
}
@@ -96,7 +96,7 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) {
else
key += 5;
if (MAX_PATH_FILENAME + ID_TAG_MAX + 2 < strlen (key)) {
- pj_dealloc (fname);
+ free (fname);
return nullptr;
}
memmove (fname, key, strlen (key) + 1);
@@ -105,7 +105,7 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) {
section = strrchr(fname, ':');
if (nullptr==section) {
proj_context_errno_set (ctx, PJD_ERR_NO_COLON_IN_INIT_STRING);
- pj_dealloc (fname);
+ free (fname);
return nullptr;
}
*section = 0;
@@ -117,7 +117,7 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) {
auto file = NS_PROJ::FileManager::open_resource_file(ctx, fname);
if (nullptr==file) {
- pj_dealloc (fname);
+ free (fname);
proj_context_errno_set (ctx, PJD_ERR_NO_OPTION_IN_INIT_FILE);
return nullptr;
}
@@ -131,7 +131,7 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) {
line = file->read_line(MAX_LINE_LENGTH, maxLenReached, eofReached);
/* End of file? */
if (maxLenReached || eofReached) {
- pj_dealloc (fname);
+ free (fname);
proj_context_errno_set (ctx, PJD_ERR_NO_OPTION_IN_INIT_FILE);
return nullptr;
}
@@ -149,9 +149,9 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) {
}
/* We're at the first line of the right section - copy line to buffer */
- buffer = static_cast<char*>(pj_malloc (current_buffer_size));
+ buffer = static_cast<char*>(malloc (current_buffer_size));
if (nullptr==buffer) {
- pj_dealloc (fname);
+ free (fname);
return nullptr;
}
@@ -183,22 +183,22 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) {
pj_chomp (&line[0]); /* Remove '#' style comments */
next_length = strlen (line.data()) + buffer_length + 2;
if (next_length > current_buffer_size) {
- char *b = static_cast<char*>(pj_malloc (2 * current_buffer_size));
+ char *b = static_cast<char*>(malloc (2 * current_buffer_size));
if (nullptr==b) {
- pj_dealloc (buffer);
+ free (buffer);
buffer = nullptr;
break;
}
strcpy (b, buffer);
current_buffer_size *= 2;
- pj_dealloc (buffer);
+ free (buffer);
buffer = b;
}
buffer[buffer_length] = ' ';
strcpy (buffer + buffer_length + 1, line.data());
}
- pj_dealloc (fname);
+ free (fname);
if (nullptr==buffer)
return nullptr;
pj_shrink (buffer);
@@ -257,7 +257,7 @@ Expand key from buffer or (if not in buffer) from init file
PJ* src;
const char* proj_string;
- pj_ctx_set_errno( ctx, 0 );
+ proj_context_errno_set( ctx, 0 );
if( !allow_init_epsg ) {
pj_log (ctx, PJ_LOG_TRACE, "%s expansion disallowed", xkey);
@@ -306,7 +306,7 @@ Expand key from buffer or (if not in buffer) from init file
definition,
init_items->param,
init_items->next ? init_items->next->param : "(empty)");
- pj_dealloc (definition);
+ free (definition);
if (nullptr==init_items)
return nullptr;
@@ -400,90 +400,6 @@ paralist *pj_expand_init(PJ_CONTEXT *ctx, paralist *init) {
/************************************************************************/
-/* pj_init_plus() */
-/* */
-/* Same as pj_init() except it takes one argument string with */
-/* individual arguments preceded by '+', such as "+proj=utm */
-/* +zone=11 +ellps=WGS84". */
-/************************************************************************/
-
-PJ *
-pj_init_plus( const char *definition )
-
-{
- return pj_init_plus_ctx( pj_get_default_ctx(), definition );
-}
-
-PJ *
-pj_init_plus_ctx( projCtx ctx, const char *definition )
-{
-#define MAX_ARG 200
- char *argv[MAX_ARG];
- char *defn_copy;
- int argc = 0, i, blank_count = 0;
- PJ *result = nullptr;
-
- /* make a copy that we can manipulate */
- defn_copy = (char *) pj_malloc( strlen(definition)+1 );
- if (!defn_copy)
- return nullptr;
- strcpy( defn_copy, definition );
-
- /* split into arguments based on '+' and trim white space */
-
- for( i = 0; defn_copy[i] != '\0'; i++ )
- {
- switch( defn_copy[i] )
- {
- case '+':
- if( i == 0 || defn_copy[i-1] == '\0' || blank_count > 0 )
- {
- /* trim trailing spaces from the previous param */
- if( blank_count > 0 )
- {
- defn_copy[i - blank_count] = '\0';
- blank_count = 0;
- }
-
- if( argc+1 == MAX_ARG )
- {
- pj_dalloc( defn_copy );
- pj_ctx_set_errno( ctx, PJD_ERR_UNPARSEABLE_CS_DEF );
- return nullptr;
- }
-
- argv[argc++] = defn_copy + i + 1;
- }
- break;
-
- case ' ':
- case '\t':
- case '\n':
- /* trim leading spaces from the current param */
- if( i == 0 || defn_copy[i-1] == '\0' || argc == 0 || argv[argc-1] == defn_copy + i )
- defn_copy[i] = '\0';
- else
- blank_count++;
- break;
-
- default:
- /* reset blank_count */
- blank_count = 0;
- }
- }
- /* trim trailing spaces from the last param */
- defn_copy[i - blank_count] = '\0';
-
- /* perform actual initialization */
- result = pj_init_ctx( ctx, argc, argv );
-
- pj_dalloc( defn_copy );
- return result;
-}
-
-
-
-/************************************************************************/
/* pj_init() */
/* */
/* Main entry point for initialing a PJ projections */
@@ -492,11 +408,6 @@ pj_init_plus_ctx( projCtx ctx, const char *definition )
/* large enough to hold projection specific parameters. */
/************************************************************************/
-PJ *
-pj_init(int argc, char **argv) {
- return pj_init_ctx( pj_get_default_ctx(), argc, argv );
-}
-
static PJ_CONSTRUCTOR locate_constructor (const char *name) {
int i;
@@ -511,15 +422,7 @@ static PJ_CONSTRUCTOR locate_constructor (const char *name) {
PJ *
-pj_init_ctx(projCtx ctx, int argc, char **argv) {
- /* Legacy interface: allow init=epsg:XXXX syntax by default */
- int allow_init_epsg = proj_context_get_use_proj4_init_rules(ctx, TRUE);
- return pj_init_ctx_with_allow_init_epsg(ctx, argc, argv, allow_init_epsg);
-}
-
-
-PJ *
-pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_init_epsg) {
+pj_init_ctx_with_allow_init_epsg(PJ_CONTEXT *ctx, int argc, char **argv, int allow_init_epsg) {
const char *s;
char *name;
PJ_CONSTRUCTOR proj;
@@ -538,7 +441,7 @@ pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_i
ctx->last_errno = 0;
if (argc <= 0) {
- pj_ctx_set_errno (ctx, PJD_ERR_NO_ARGS);
+ proj_context_errno_set (ctx, PJD_ERR_NO_ARGS);
return nullptr;
}
@@ -552,13 +455,13 @@ pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_i
/* can't have nested pipelines directly */
if (n_pipelines > 1) {
- pj_ctx_set_errno (ctx, PJD_ERR_MALFORMED_PIPELINE);
+ proj_context_errno_set (ctx, PJD_ERR_MALFORMED_PIPELINE);
return nullptr;
}
/* don't allow more than one +init in non-pipeline operations */
if (n_pipelines == 0 && n_inits > 1) {
- pj_ctx_set_errno (ctx, PJD_ERR_TOO_MANY_INITS);
+ proj_context_errno_set (ctx, PJD_ERR_TOO_MANY_INITS);
return nullptr;
}
@@ -566,14 +469,14 @@ pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_i
/* put arguments into internal linked list */
start = curr = pj_mkparam(argv[0]);
if (!curr) {
- pj_dealloc_params (ctx, start, ENOMEM);
+ free_params (ctx, start, ENOMEM);
return nullptr;
}
for (i = 1; i < argc; ++i) {
curr->next = pj_mkparam(argv[i]);
if (!curr->next) {
- pj_dealloc_params (ctx, start, ENOMEM);
+ free_params (ctx, start, ENOMEM);
return nullptr;
}
curr = curr->next;
@@ -588,31 +491,31 @@ pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_i
if (init && n_pipelines == 0) {
init = pj_expand_init_internal (ctx, init, allow_init_epsg);
if (!init) {
- pj_dealloc_params (ctx, start, PJD_ERR_NO_ARGS);
+ free_params (ctx, start, PJD_ERR_NO_ARGS);
return nullptr;
}
}
if (ctx->last_errno) {
- pj_dealloc_params (ctx, start, ctx->last_errno);
+ free_params (ctx, start, ctx->last_errno);
return nullptr;
}
/* Find projection selection */
curr = pj_param_exists (start, "proj");
if (nullptr==curr) {
- pj_dealloc_params (ctx, start, PJD_ERR_PROJ_NOT_NAMED);
+ free_params (ctx, start, PJD_ERR_PROJ_NOT_NAMED);
return nullptr;
}
name = curr->param;
if (strlen (name) < 6) {
- pj_dealloc_params (ctx, start, PJD_ERR_PROJ_NOT_NAMED);
+ free_params (ctx, start, PJD_ERR_PROJ_NOT_NAMED);
return nullptr;
}
name += 5;
proj = locate_constructor (name);
if (nullptr==proj) {
- pj_dealloc_params (ctx, start, PJD_ERR_UNKNOWN_PROJECTION_ID);
+ free_params (ctx, start, PJD_ERR_UNKNOWN_PROJECTION_ID);
return nullptr;
}
@@ -621,7 +524,7 @@ pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_i
/* Allocate projection structure */
PIN = proj(nullptr);
if (nullptr==PIN) {
- pj_dealloc_params (ctx, start, ENOMEM);
+ free_params (ctx, start, ENOMEM);
return nullptr;
}
@@ -820,7 +723,7 @@ pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_i
PIN->from_greenwich = 0.0;
/* Private object for the geodesic functions */
- PIN->geod = static_cast<struct geod_geodesic*>(pj_calloc (1, sizeof (struct geod_geodesic)));
+ PIN->geod = static_cast<struct geod_geodesic*>(calloc (1, sizeof (struct geod_geodesic)));
if (nullptr==PIN->geod)
return pj_default_destructor (PIN, ENOMEM);
geod_init(PIN->geod, PIN->a, (1 - sqrt (1 - PIN->es)));
@@ -829,7 +732,7 @@ pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_i
err = proj_errno_reset (PIN);
PIN = proj(PIN);
if (proj_errno (PIN)) {
- pj_free(PIN);
+ proj_destroy(PIN);
return nullptr;
}
proj_errno_restore (PIN, err);
diff --git a/src/initcache.cpp b/src/initcache.cpp
index af20fb82..cf9460ab 100644
--- a/src/initcache.cpp
+++ b/src/initcache.cpp
@@ -48,7 +48,7 @@ paralist *pj_clone_paralist( const paralist *list)
for( ; list != nullptr; list = list->next )
{
paralist *newitem = (paralist *)
- pj_malloc(sizeof(paralist) + strlen(list->param));
+ malloc(sizeof(paralist) + strlen(list->param));
newitem->used = 0;
newitem->next = nullptr;
@@ -83,17 +83,17 @@ void pj_clear_initcache()
{
paralist *n, *t = cache_paralist[i];
- pj_dalloc( cache_key[i] );
+ free( cache_key[i] );
/* free parameter list elements */
for (; t != nullptr; t = n) {
n = t->next;
- pj_dalloc(t);
+ free(t);
}
}
- pj_dalloc( cache_key );
- pj_dalloc( cache_paralist );
+ free( cache_key );
+ free( cache_paralist );
cache_count = 0;
cache_alloc= 0;
cache_key = nullptr;
@@ -151,29 +151,29 @@ void pj_insert_initcache( const char *filekey, const paralist *list )
cache_alloc = cache_alloc * 2 + 15;
- cache_key_new = (char **) pj_malloc(sizeof(char*) * cache_alloc);
+ cache_key_new = (char **) malloc(sizeof(char*) * cache_alloc);
if( cache_key && cache_count )
{
memcpy( cache_key_new, cache_key, sizeof(char*) * cache_count);
}
- pj_dalloc( cache_key );
+ free( cache_key );
cache_key = cache_key_new;
cache_paralist_new = (paralist **)
- pj_malloc(sizeof(paralist*) * cache_alloc);
+ malloc(sizeof(paralist*) * cache_alloc);
if( cache_paralist && cache_count )
{
memcpy( cache_paralist_new, cache_paralist,
sizeof(paralist*) * cache_count );
}
- pj_dalloc( cache_paralist );
+ free( cache_paralist );
cache_paralist = cache_paralist_new;
}
/*
** Duplicate the filekey and paralist, and insert in cache.
*/
- cache_key[cache_count] = (char *) pj_malloc(strlen(filekey)+1);
+ cache_key[cache_count] = (char *) malloc(strlen(filekey)+1);
strcpy( cache_key[cache_count], filekey );
cache_paralist[cache_count] = pj_clone_paralist( list );
diff --git a/src/internal.cpp b/src/internal.cpp
index 91994077..175ffa9b 100644
--- a/src/internal.cpp
+++ b/src/internal.cpp
@@ -141,15 +141,15 @@ Check if a a PJ has an inverse.
void proj_context_set (PJ *P, PJ_CONTEXT *ctx) {
if (nullptr==ctx)
ctx = pj_get_default_ctx ();
- pj_set_ctx (P, ctx);
+ proj_assign_context (P, ctx);
}
void proj_context_inherit (PJ *parent, PJ *child) {
if (nullptr==parent)
- pj_set_ctx (child, pj_get_default_ctx());
+ proj_assign_context (child, pj_get_default_ctx());
else
- pj_set_ctx (child, pj_get_ctx(parent));
+ proj_assign_context (child, pj_get_ctx(parent));
}
@@ -411,13 +411,16 @@ to that context.
******************************************************************************/
if (nullptr==ctx)
ctx = pj_get_default_ctx();
- pj_ctx_set_errno (ctx, err);
+ ctx->last_errno = err;
+ if( err == 0 )
+ return;
+ errno = err;
}
/* logging */
/* pj_vlog resides in pj_log.c and relates to pj_log as vsprintf relates to sprintf */
-void pj_vlog( projCtx ctx, int level, const char *fmt, va_list args );
+void pj_vlog( PJ_CONTEXT *ctx, int level, const char *fmt, va_list args );
/***************************************************************************************/
diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp
index 7582f37f..6bc1f166 100644
--- a/src/iso19111/c_api.cpp
+++ b/src/iso19111/c_api.cpp
@@ -79,10 +79,10 @@ static void PROJ_NO_INLINE proj_log_error(PJ_CONTEXT *ctx, const char *function,
msg += ": ";
msg += text;
ctx->logger(ctx->logger_app_data, PJ_LOG_ERROR, msg.c_str());
- auto previous_errno = pj_ctx_get_errno(ctx);
+ auto previous_errno = proj_context_errno(ctx);
if (previous_errno == 0) {
// only set errno if it wasn't set deeper down the call stack
- pj_ctx_set_errno(ctx, PJD_ERR_GENERIC_ERROR);
+ proj_context_errno_set(ctx, PJD_ERR_GENERIC_ERROR);
}
}
@@ -675,6 +675,9 @@ PJ *proj_create_from_database(PJ_CONTEXT *ctx, const char *auth_name,
codeStr, usePROJAlternativeGridNames != 0)
.as_nullable();
break;
+ case PJ_CATEGORY_DATUM_ENSEMBLE:
+ obj = factory->createDatumEnsemble(codeStr).as_nullable();
+ break;
}
return pj_obj_create(ctx, NN_NO_CHECK(obj));
} catch (const std::exception &e) {
@@ -916,7 +919,7 @@ convertPJObjectTypeToObjectType(PJ_TYPE type, bool &valid) {
break;
case PJ_TYPE_DATUM_ENSEMBLE:
- cppType = AuthorityFactory::ObjectType::DATUM;
+ cppType = AuthorityFactory::ObjectType::DATUM_ENSEMBLE;
break;
case PJ_TYPE_TEMPORAL_DATUM:
@@ -1418,6 +1421,13 @@ const char *proj_get_id_code(const PJ *obj, int index) {
* variants, for WKT1_GDAL for ProjectedCRS with easting/northing ordering
* (otherwise stripped), but not for WKT1_ESRI. Setting to YES will output
* them unconditionally, and to NO will omit them unconditionally.</li>
+ * <li>STRICT=YES/NO. Default is YES. If NO, a Geographic 3D CRS can be for
+ * example exported as WKT1_GDAL with 3 axes, whereas this is normally not
+ * allowed.</li>
+ * <li>ALLOW_ELLIPSOIDAL_HEIGHT_AS_VERTICAL_CRS=YES/NO. Default is NO. If set
+ * to YES and type == PJ_WKT1_GDAL, a Geographic 3D CRS or a Projected 3D CRS
+ * will be exported as a compound CRS whose vertical part represents an
+ * ellipsoidal height (for example for use with LAS 1.4 WKT1).</li>
* </ul>
* @return a string, or NULL in case of error.
*/
@@ -1468,6 +1478,11 @@ const char *proj_as_wkt(PJ_CONTEXT *ctx, const PJ *obj, PJ_WKT_TYPE type,
}
} else if ((value = getOptionValue(*iter, "STRICT="))) {
formatter->setStrict(ci_equal(value, "YES"));
+ } else if ((value = getOptionValue(
+ *iter,
+ "ALLOW_ELLIPSOIDAL_HEIGHT_AS_VERTICAL_CRS="))) {
+ formatter->setAllowEllipsoidalHeightAsVerticalCRS(
+ ci_equal(value, "YES"));
} else {
std::string msg("Unknown option :");
msg += *iter;
@@ -2050,6 +2065,8 @@ PJ *proj_get_ellipsoid(PJ_CONTEXT *ctx, const PJ *obj) {
/** \brief Get the horizontal datum from a CRS
*
+ * This function may return a Datum or DatumEnsemble object.
+ *
* The returned object must be unreferenced with proj_destroy() after
* use.
* It should be used by at most one thread at a time.
@@ -2685,11 +2702,11 @@ proj_get_crs_info_list_from_database(PJ_CONTEXT *ctx, const char *auth_name,
void proj_crs_info_list_destroy(PROJ_CRS_INFO **list) {
if (list) {
for (int i = 0; list[i] != nullptr; i++) {
- pj_dalloc(list[i]->auth_name);
- pj_dalloc(list[i]->code);
- pj_dalloc(list[i]->name);
- pj_dalloc(list[i]->area_name);
- pj_dalloc(list[i]->projection_method_name);
+ free(list[i]->auth_name);
+ free(list[i]->code);
+ free(list[i]->name);
+ free(list[i]->area_name);
+ free(list[i]->projection_method_name);
delete list[i];
}
delete[] list;
@@ -2779,11 +2796,11 @@ PROJ_UNIT_INFO **proj_get_units_from_database(PJ_CONTEXT *ctx,
void proj_unit_list_destroy(PROJ_UNIT_INFO **list) {
if (list) {
for (int i = 0; list[i] != nullptr; i++) {
- pj_dalloc(list[i]->auth_name);
- pj_dalloc(list[i]->code);
- pj_dalloc(list[i]->name);
- pj_dalloc(list[i]->category);
- pj_dalloc(list[i]->proj_short_name);
+ free(list[i]->auth_name);
+ free(list[i]->code);
+ free(list[i]->name);
+ free(list[i]->category);
+ free(list[i]->proj_short_name);
delete list[i];
}
delete[] list;
@@ -4438,8 +4455,9 @@ PJ *proj_create_cartesian_2D_cs(PJ_CONTEXT *ctx, PJ_CARTESIAN_CS_2D_TYPE type,
*
* @param ctx PROJ context, or NULL for default context
* @param type Coordinate system type.
- * @param unit_name Unit name.
- * @param unit_conv_factor Unit conversion factor to SI.
+ * @param unit_name Name of the angular units. Or NULL for Degree
+ * @param unit_conv_factor Conversion factor from the angular unit to radian.
+ * Or 0 for Degree if unit_name == NULL. Otherwise should be not NULL
*
* @return Object that must be unreferenced with
* proj_destroy(), or NULL in case of error.
@@ -4478,13 +4496,17 @@ PJ *proj_create_ellipsoidal_2D_cs(PJ_CONTEXT *ctx,
*
* @param ctx PROJ context, or NULL for default context
* @param type Coordinate system type.
- * @param horizontal_angular_unit_name Horizontal angular unit name.
- * @param horizontal_angular_unit_conv_factor Horizontal angular unit conversion
- * factor to SI.
- * @param vertical_linear_unit_name Vertical linear unit name.
+ * @param horizontal_angular_unit_name Name of the angular units. Or NULL for
+ * Degree.
+ * @param horizontal_angular_unit_conv_factor Conversion factor from the angular
+ * unit to radian. Or 0 for Degree if horizontal_angular_unit_name == NULL.
+ * Otherwise should be not NULL
+ * @param vertical_linear_unit_name Vertical linear unit name. Or NULL for
+ * Metre.
* @param vertical_linear_unit_conv_factor Vertical linear unit conversion
- * factor to SI.
- *
+ * factor to metre. Or 0 for Metre if vertical_linear_unit_name == NULL.
+ * Otherwise should be not NULL
+
* @return Object that must be unreferenced with
* proj_destroy(), or NULL in case of error.
* @since 6.3
@@ -7987,6 +8009,9 @@ double proj_coordoperation_get_accuracy(PJ_CONTEXT *ctx,
/** \brief Returns the datum of a SingleCRS.
*
+ * If that function returns NULL, @see proj_crs_get_datum_ensemble() to
+ * potentially get a DatumEnsemble instead.
+ *
* The returned object must be unreferenced with proj_destroy() after
* use.
* It should be used by at most one thread at a time.
@@ -8018,6 +8043,9 @@ PJ *proj_crs_get_datum(PJ_CONTEXT *ctx, const PJ *crs) {
/** \brief Returns the datum ensemble of a SingleCRS.
*
+ * If that function returns NULL, @see proj_crs_get_datum() to
+ * potentially get a Datum instead.
+ *
* The returned object must be unreferenced with proj_destroy() after
* use.
* It should be used by at most one thread at a time.
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index be15b3e0..83b626b3 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -64,6 +64,30 @@
// #define DEBUG_CONCATENATED_OPERATION
#if defined(DEBUG_SORT) || defined(DEBUG_CONCATENATED_OPERATION)
#include <iostream>
+
+void dumpWKT(const NS_PROJ::crs::CRS *crs);
+void dumpWKT(const NS_PROJ::crs::CRS *crs) {
+ auto f(NS_PROJ::io::WKTFormatter::create(
+ NS_PROJ::io::WKTFormatter::Convention::WKT2_2019));
+ std::cerr << crs->exportToWKT(f.get()) << std::endl;
+}
+
+void dumpWKT(const NS_PROJ::crs::CRSPtr &crs);
+void dumpWKT(const NS_PROJ::crs::CRSPtr &crs) { dumpWKT(crs.get()); }
+
+void dumpWKT(const NS_PROJ::crs::CRSNNPtr &crs);
+void dumpWKT(const NS_PROJ::crs::CRSNNPtr &crs) {
+ dumpWKT(crs.as_nullable().get());
+}
+
+void dumpWKT(const NS_PROJ::crs::GeographicCRSPtr &crs);
+void dumpWKT(const NS_PROJ::crs::GeographicCRSPtr &crs) { dumpWKT(crs.get()); }
+
+void dumpWKT(const NS_PROJ::crs::GeographicCRSNNPtr &crs);
+void dumpWKT(const NS_PROJ::crs::GeographicCRSNNPtr &crs) {
+ dumpWKT(crs.as_nullable().get());
+}
+
#endif
using namespace NS_PROJ::internal;
@@ -6010,28 +6034,39 @@ void Conversion::_exportToPROJString(
!isHeightDepthReversal;
bool applyTargetCRSModifiers = applySourceCRSModifiers;
+ if (formatter->getCRSExport()) {
+ if (methodEPSGCode == EPSG_CODE_METHOD_GEOCENTRIC_TOPOCENTRIC ||
+ methodEPSGCode == EPSG_CODE_METHOD_GEOGRAPHIC_TOPOCENTRIC) {
+ throw io::FormattingException("Transformation cannot be exported "
+ "as a PROJ.4 string (but can be part "
+ "of a PROJ pipeline)");
+ }
+ }
+
auto l_sourceCRS = sourceCRS();
+ crs::GeographicCRSPtr srcGeogCRS;
if (!formatter->getCRSExport() && l_sourceCRS && applySourceCRSModifiers) {
- crs::CRS *horiz = l_sourceCRS.get();
- const auto compound = dynamic_cast<const crs::CompoundCRS *>(horiz);
+ crs::CRSPtr horiz = l_sourceCRS;
+ const auto compound =
+ dynamic_cast<const crs::CompoundCRS *>(l_sourceCRS.get());
if (compound) {
const auto &components = compound->componentReferenceSystems();
if (!components.empty()) {
- horiz = components.front().get();
+ horiz = components.front().as_nullable();
}
}
- auto geogCRS = dynamic_cast<const crs::GeographicCRS *>(horiz);
- if (geogCRS) {
+ srcGeogCRS = std::dynamic_pointer_cast<crs::GeographicCRS>(horiz);
+ if (srcGeogCRS) {
formatter->setOmitProjLongLatIfPossible(true);
formatter->startInversion();
- geogCRS->_exportToPROJString(formatter);
+ srcGeogCRS->_exportToPROJString(formatter);
formatter->stopInversion();
formatter->setOmitProjLongLatIfPossible(false);
}
- auto projCRS = dynamic_cast<const crs::ProjectedCRS *>(horiz);
+ auto projCRS = dynamic_cast<const crs::ProjectedCRS *>(horiz.get());
if (projCRS) {
formatter->startInversion();
formatter->pushOmitZUnitConversion();
@@ -6301,6 +6336,30 @@ void Conversion::_exportToPROJString(
}
bConversionDone = true;
bEllipsoidParametersDone = true;
+ } else if (methodEPSGCode == EPSG_CODE_METHOD_GEOGRAPHIC_TOPOCENTRIC) {
+ if (!srcGeogCRS) {
+ throw io::FormattingException(
+ "Export of Geographic/Topocentric conversion to a PROJ string "
+ "requires an input geographic CRS");
+ }
+
+ formatter->addStep("cart");
+ srcGeogCRS->ellipsoid()->_exportToPROJString(formatter);
+
+ formatter->addStep("topocentric");
+ const auto latOrigin = parameterValueNumeric(
+ EPSG_CODE_PARAMETER_LATITUDE_TOPOGRAPHIC_ORIGIN,
+ common::UnitOfMeasure::DEGREE);
+ const auto lonOrigin = parameterValueNumeric(
+ EPSG_CODE_PARAMETER_LONGITUDE_TOPOGRAPHIC_ORIGIN,
+ common::UnitOfMeasure::DEGREE);
+ const auto heightOrigin = parameterValueNumeric(
+ EPSG_CODE_PARAMETER_ELLIPSOIDAL_HEIGHT_TOPOCENTRIC_ORIGIN,
+ common::UnitOfMeasure::METRE);
+ formatter->addParam("lat_0", latOrigin);
+ formatter->addParam("lon_0", lonOrigin);
+ formatter->addParam("h_0", heightOrigin);
+ bConversionDone = true;
}
auto l_targetCRS = targetCRS();
@@ -6425,7 +6484,9 @@ void Conversion::_exportToPROJString(
}
if (!bEllipsoidParametersDone) {
- auto targetGeogCRS = horiz->extractGeographicCRS();
+ auto targetGeodCRS = horiz->extractGeodeticCRS();
+ auto targetGeogCRS =
+ std::dynamic_pointer_cast<crs::GeographicCRS>(targetGeodCRS);
if (targetGeogCRS) {
if (formatter->getCRSExport()) {
targetGeogCRS->addDatumInfoToPROJString(formatter);
@@ -6434,6 +6495,8 @@ void Conversion::_exportToPROJString(
targetGeogCRS->primeMeridian()->_exportToPROJString(
formatter);
}
+ } else if (targetGeodCRS) {
+ targetGeodCRS->ellipsoid()->_exportToPROJString(formatter);
}
}
@@ -8836,11 +8899,16 @@ createSimilarPropertiesTransformation(TransformationNNPtr obj) {
// The domain(s) are unchanged
addDomains(map, obj.get());
- std::string forwardName = obj->nameStr();
+ const std::string &forwardName = obj->nameStr();
if (!forwardName.empty()) {
map.set(common::IdentifiedObject::NAME_KEY, forwardName);
}
+ const std::string &remarks = obj->remarks();
+ if (!remarks.empty()) {
+ map.set(common::IdentifiedObject::REMARKS_KEY, remarks);
+ }
+
addModifiedIdentifier(map, obj.get(), false, true);
return map;
@@ -9179,6 +9247,14 @@ static void setupPROJGeodeticSourceCRS(io::PROJStringFormatter *formatter,
formatter->startInversion();
sourceCRSGeog->_exportToPROJString(formatter);
formatter->stopInversion();
+ if (util::isOfExactType<crs::DerivedGeographicCRS>(
+ *(sourceCRSGeog.get()))) {
+ // The export of a DerivedGeographicCRS in non-CRS mode adds
+ // unit conversion and axis swapping. We must compensate for that
+ formatter->startInversion();
+ sourceCRSGeog->addAngularUnitConvertAndAxisSwap(formatter);
+ formatter->stopInversion();
+ }
if (addPushV3) {
formatter->addStep("push");
@@ -9212,7 +9288,12 @@ static void setupPROJGeodeticTargetCRS(io::PROJStringFormatter *formatter,
formatter->addStep("pop");
formatter->addParam("v_3");
}
-
+ if (util::isOfExactType<crs::DerivedGeographicCRS>(
+ *(targetCRSGeog.get()))) {
+ // The export of a DerivedGeographicCRS in non-CRS mode adds
+ // unit conversion and axis swapping. We must compensate for that
+ targetCRSGeog->addAngularUnitConvertAndAxisSwap(formatter);
+ }
targetCRSGeog->_exportToPROJString(formatter);
} else {
auto targetCRSGeod = dynamic_cast<const crs::GeodeticCRS *>(crs.get());
@@ -11191,6 +11272,12 @@ struct CoordinateOperationFactory::Private {
const crs::GeographicCRS *geogDst,
std::vector<CoordinateOperationNNPtr> &res);
+ static void createOperationsVertToGeogBallpark(
+ const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS,
+ Private::Context &context, const crs::VerticalCRS *vertSrc,
+ const crs::GeographicCRS *geogDst,
+ std::vector<CoordinateOperationNNPtr> &res);
+
static void createOperationsBoundToBound(
const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS,
Private::Context &context, const crs::BoundCRS *boundSrc,
@@ -11292,6 +11379,7 @@ struct PrecomputedOpCharacteristics {
bool gridsKnown_ = false;
size_t stepCount_ = 0;
bool isApprox_ = false;
+ bool hasBallparkVertical_ = false;
bool isNullTransformation_ = false;
PrecomputedOpCharacteristics() = default;
@@ -11299,10 +11387,12 @@ struct PrecomputedOpCharacteristics {
bool isPROJExportable, bool hasGrids,
bool gridsAvailable, bool gridsKnown,
size_t stepCount, bool isApprox,
+ bool hasBallparkVertical,
bool isNullTransformation)
: area_(area), accuracy_(accuracy), isPROJExportable_(isPROJExportable),
hasGrids_(hasGrids), gridsAvailable_(gridsAvailable),
gridsKnown_(gridsKnown), stepCount_(stepCount), isApprox_(isApprox),
+ hasBallparkVertical_(hasBallparkVertical),
isNullTransformation_(isNullTransformation) {}
};
@@ -11346,6 +11436,15 @@ struct SortFunction {
return false;
}
+ if (!iterA->second.hasBallparkVertical_ &&
+ iterB->second.hasBallparkVertical_) {
+ return true;
+ }
+ if (iterA->second.hasBallparkVertical_ &&
+ !iterB->second.hasBallparkVertical_) {
+ return false;
+ }
+
if (!iterA->second.isNullTransformation_ &&
iterB->second.isNullTransformation_) {
return true;
@@ -11612,7 +11711,9 @@ struct FilterResults {
? CoordinateOperationContext::SpatialCriterion::
STRICT_CONTAINMENT
: context->getSpatialCriterion();
- bool hasFoundOpWithExtent = false;
+ bool hasOnlyBallpark = true;
+ bool hasNonBallparkWithoutExtent = false;
+ bool hasNonBallparkOpWithExtent = false;
const bool allowBallpark = context->getAllowBallparkTransformations();
for (const auto &op : sourceList) {
if (desiredAccuracy != 0) {
@@ -11627,9 +11728,15 @@ struct FilterResults {
if (areaOfInterest) {
bool emptyIntersection = false;
auto extent = getExtent(op, true, emptyIntersection);
- if (!extent)
+ if (!extent) {
+ if (!op->hasBallparkTransformation()) {
+ hasNonBallparkWithoutExtent = true;
+ }
continue;
- hasFoundOpWithExtent = true;
+ }
+ if (!op->hasBallparkTransformation()) {
+ hasNonBallparkOpWithExtent = true;
+ }
bool extentContains =
extent->contains(NN_NO_CHECK(areaOfInterest));
if (!hasOpThatContainsAreaOfInterestAndNoGrid &&
@@ -11656,9 +11763,15 @@ struct FilterResults {
BOTH) {
bool emptyIntersection = false;
auto extent = getExtent(op, true, emptyIntersection);
- if (!extent)
+ if (!extent) {
+ if (!op->hasBallparkTransformation()) {
+ hasNonBallparkWithoutExtent = true;
+ }
continue;
- hasFoundOpWithExtent = true;
+ }
+ if (!op->hasBallparkTransformation()) {
+ hasNonBallparkOpWithExtent = true;
+ }
bool extentContainsExtent1 =
!extent1 || extent->contains(NN_NO_CHECK(extent1));
bool extentContainsExtent2 =
@@ -11688,12 +11801,16 @@ struct FilterResults {
}
}
}
+ if (!op->hasBallparkTransformation()) {
+ hasOnlyBallpark = false;
+ }
res.emplace_back(op);
}
// In case no operation has an extent and no result is found,
// retain all initial operations that match accuracy criterion.
- if (res.empty() && !hasFoundOpWithExtent) {
+ if ((res.empty() && !hasNonBallparkOpWithExtent) ||
+ (hasOnlyBallpark && hasNonBallparkWithoutExtent)) {
for (const auto &op : sourceList) {
if (desiredAccuracy != 0) {
const double accuracy = getAccuracy(op);
@@ -11797,6 +11914,8 @@ struct FilterResults {
area, getAccuracy(op), isPROJExportable, hasGrids,
gridsAvailable, gridsKnown, stepCount,
op->hasBallparkTransformation(),
+ op->nameStr().find("ballpark vertical transformation") !=
+ std::string::npos,
isNullTransformation(op->nameStr()));
}
@@ -12615,6 +12734,55 @@ createGeodToGeodPROJBased(const crs::CRSNNPtr &geodSrc,
// ---------------------------------------------------------------------------
+static std::string
+getRemarks(const std::vector<operation::CoordinateOperationNNPtr> &ops) {
+ std::string remarks;
+ for (const auto &op : ops) {
+ const auto &opRemarks = op->remarks();
+ if (!opRemarks.empty()) {
+ if (!remarks.empty()) {
+ remarks += '\n';
+ }
+
+ std::string opName(op->nameStr());
+ if (starts_with(opName, INVERSE_OF)) {
+ opName = opName.substr(INVERSE_OF.size());
+ }
+
+ remarks += "For ";
+ remarks += opName;
+
+ const auto &ids = op->identifiers();
+ if (!ids.empty()) {
+ std::string authority(*ids.front()->codeSpace());
+ if (starts_with(authority, "INVERSE(") &&
+ authority.back() == ')') {
+ authority = authority.substr(strlen("INVERSE("),
+ authority.size() - 1 -
+ strlen("INVERSE("));
+ }
+ if (starts_with(authority, "DERIVED_FROM(") &&
+ authority.back() == ')') {
+ authority = authority.substr(strlen("DERIVED_FROM("),
+ authority.size() - 1 -
+ strlen("DERIVED_FROM("));
+ }
+
+ remarks += " (";
+ remarks += authority;
+ remarks += ':';
+ remarks += ids.front()->code();
+ remarks += ')';
+ }
+ remarks += ": ";
+ remarks += opRemarks;
+ }
+ }
+ return remarks;
+}
+
+// ---------------------------------------------------------------------------
+
static CoordinateOperationNNPtr createHorizVerticalPROJBased(
const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS,
const operation::CoordinateOperationNNPtr &horizTransform,
@@ -12640,6 +12808,10 @@ static CoordinateOperationNNPtr createHorizVerticalPROJBased(
properties.set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY,
NN_NO_CHECK(extent));
}
+ const auto &remarks = verticalTransform->remarks();
+ if (!remarks.empty()) {
+ properties.set(common::IdentifiedObject::REMARKS_KEY, remarks);
+ }
return createPROJBased(
properties, exportable, sourceCRS, targetCRS, nullptr,
verticalTransform->coordinateOperationAccuracies(),
@@ -12664,6 +12836,11 @@ static CoordinateOperationNNPtr createHorizVerticalPROJBased(
NN_NO_CHECK(extent));
}
+ const auto remarks = getRemarks(ops);
+ if (!remarks.empty()) {
+ properties.set(common::IdentifiedObject::REMARKS_KEY, remarks);
+ }
+
std::vector<metadata::PositionalAccuracyNNPtr> accuracies;
const double accuracy = getAccuracy(ops);
if (accuracy >= 0.0) {
@@ -12724,6 +12901,11 @@ static CoordinateOperationNNPtr createHorizVerticalHorizPROJBased(
NN_NO_CHECK(extent));
}
+ const auto remarks = getRemarks(ops);
+ if (!remarks.empty()) {
+ properties.set(common::IdentifiedObject::REMARKS_KEY, remarks);
+ }
+
std::vector<metadata::PositionalAccuracyNNPtr> accuracies;
const double accuracy = getAccuracy(ops);
if (accuracy >= 0.0) {
@@ -13542,11 +13724,17 @@ bool CoordinateOperationFactory::Private::createOperationsFromDatabase(
ENTER_FUNCTION();
if (geogSrc && vertDst) {
- res = createOperationsGeogToVertFromGeoid(sourceCRS, targetCRS, vertDst,
- context);
+ createOperationsFromDatabase(targetCRS, sourceCRS, context, geodDst,
+ geodSrc, geogDst, geogSrc, vertDst,
+ vertSrc, res);
+ res = applyInverse(res);
} else if (geogDst && vertSrc) {
res = applyInverse(createOperationsGeogToVertFromGeoid(
targetCRS, sourceCRS, vertSrc, context));
+ if (!res.empty()) {
+ createOperationsVertToGeogBallpark(sourceCRS, targetCRS, context,
+ vertSrc, geogDst, res);
+ }
}
if (!res.empty()) {
@@ -14222,6 +14410,20 @@ void CoordinateOperationFactory::Private::createOperationsBoundToGeog(
const auto &hubSrc = boundSrc->hubCRS();
auto hubSrcGeog = dynamic_cast<const crs::GeographicCRS *>(hubSrc.get());
auto geogCRSOfBaseOfBoundSrc = boundSrc->baseCRS()->extractGeographicCRS();
+ {
+ // If geogCRSOfBaseOfBoundSrc is a DerivedGeographicCRS, use its base
+ // instead (if it is a GeographicCRS)
+ auto derivedGeogCRS =
+ std::dynamic_pointer_cast<crs::DerivedGeographicCRS>(
+ geogCRSOfBaseOfBoundSrc);
+ if (derivedGeogCRS) {
+ auto baseCRS = std::dynamic_pointer_cast<crs::GeographicCRS>(
+ derivedGeogCRS->baseCRS().as_nullable());
+ if (baseCRS) {
+ geogCRSOfBaseOfBoundSrc = baseCRS;
+ }
+ }
+ }
const auto &authFactory = context.context->getAuthorityFactory();
const auto dbContext =
@@ -14643,23 +14845,38 @@ void CoordinateOperationFactory::Private::createOperationsVertToGeog(
match.get(),
util::IComparable::Criterion::EQUIVALENT) &&
!match->identifiers().empty()) {
- res = createOperations(
+ auto resTmp = createOperations(
NN_NO_CHECK(
util::nn_dynamic_pointer_cast<crs::VerticalCRS>(
match)),
targetCRS, context);
+ res.insert(res.end(), resTmp.begin(), resTmp.end());
return;
}
}
}
}
+ createOperationsVertToGeogBallpark(sourceCRS, targetCRS, context, vertSrc,
+ geogDst, res);
+}
+
+// ---------------------------------------------------------------------------
+
+void CoordinateOperationFactory::Private::createOperationsVertToGeogBallpark(
+ const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS,
+ Private::Context &, const crs::VerticalCRS *vertSrc,
+ const crs::GeographicCRS *geogDst,
+ std::vector<CoordinateOperationNNPtr> &res) {
+
+ ENTER_FUNCTION();
+
const auto &srcAxis = vertSrc->coordinateSystem()->axisList()[0];
const double convSrc = srcAxis->unit().conversionToSI();
double convDst = 1.0;
const auto &geogAxis = geogDst->coordinateSystem()->axisList();
bool dstIsUp = true;
- bool dstIsDown = true;
+ bool dstIsDown = false;
if (geogAxis.size() == 3) {
const auto &dstAxis = geogAxis[2];
convDst = dstAxis->unit().conversionToSI();
@@ -14672,12 +14889,24 @@ void CoordinateOperationFactory::Private::createOperationsVertToGeog(
((srcIsUp && dstIsDown) || (srcIsDown && dstIsUp));
const double factor = convSrc / convDst;
- auto conv = Transformation::createChangeVerticalUnit(
- util::PropertyMap().set(
- common::IdentifiedObject::NAME_KEY,
+
+ const auto &sourceCRSExtent = getExtent(sourceCRS);
+ const auto &targetCRSExtent = getExtent(targetCRS);
+ const bool sameExtent =
+ sourceCRSExtent && targetCRSExtent &&
+ sourceCRSExtent->_isEquivalentTo(
+ targetCRSExtent.get(), util::IComparable::Criterion::EQUIVALENT);
+
+ util::PropertyMap map;
+ map.set(common::IdentifiedObject::NAME_KEY,
buildTransfName(sourceCRS->nameStr(), targetCRS->nameStr()) +
- BALLPARK_VERTICAL_TRANSFORMATION_NO_ELLIPSOID_VERT_HEIGHT),
- sourceCRS, targetCRS,
+ BALLPARK_VERTICAL_TRANSFORMATION_NO_ELLIPSOID_VERT_HEIGHT)
+ .set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY,
+ sameExtent ? NN_NO_CHECK(sourceCRSExtent)
+ : metadata::Extent::WORLD);
+
+ auto conv = Transformation::createChangeVerticalUnit(
+ map, sourceCRS, targetCRS,
common::Scale(heightDepthReversal ? -factor : factor), {});
conv->setHasBallparkTransformation(true);
res.push_back(conv);
@@ -15477,149 +15706,6 @@ void CoordinateOperationFactory::Private::createOperationsBoundToCompound(
// ---------------------------------------------------------------------------
-static crs::CRSNNPtr
-getResolvedCRS(const crs::CRSNNPtr &crs,
- const CoordinateOperationContextNNPtr &context,
- metadata::ExtentPtr &extentOut) {
- const auto &authFactory = context->getAuthorityFactory();
- const auto &ids = crs->identifiers();
- const auto &name = crs->nameStr();
-
- bool approxExtent;
- extentOut = getExtentPossiblySynthetized(crs, approxExtent);
-
- // We try to "identify" the provided CRS with the ones of the database,
- // but in a more restricted way that what identify() does.
- // If we get a match from id in priority, and from name as a fallback, and
- // that they are equivalent to the input CRS, then use the identified CRS.
- // Even if they aren't equivalent, we update extentOut with the one of the
- // identified CRS if our input one is absent/not reliable.
-
- const auto tryToIdentifyByName = [&crs, &name, &authFactory, approxExtent,
- &extentOut](
- io::AuthorityFactory::ObjectType objectType) {
- if (name != "unknown" && name != "unnamed") {
- auto matches = authFactory->createObjectsFromName(
- name, {objectType}, false, 2);
- if (matches.size() == 1) {
- const auto match =
- util::nn_static_pointer_cast<crs::CRS>(matches.front());
- if (approxExtent || !extentOut) {
- extentOut = getExtent(match);
- }
- if (match->isEquivalentTo(
- crs.get(), util::IComparable::Criterion::EQUIVALENT)) {
- return match;
- }
- }
- }
- return crs;
- };
-
- auto geogCRS = dynamic_cast<crs::GeographicCRS *>(crs.get());
- if (geogCRS && authFactory) {
- if (!ids.empty()) {
- const auto tmpAuthFactory = io::AuthorityFactory::create(
- authFactory->databaseContext(), *ids.front()->codeSpace());
- try {
- auto resolvedCrs(
- tmpAuthFactory->createGeographicCRS(ids.front()->code()));
- if (approxExtent || !extentOut) {
- extentOut = getExtent(resolvedCrs);
- }
- if (resolvedCrs->isEquivalentTo(
- crs.get(), util::IComparable::Criterion::EQUIVALENT)) {
- return util::nn_static_pointer_cast<crs::CRS>(resolvedCrs);
- }
- } catch (const std::exception &) {
- }
- } else {
- return tryToIdentifyByName(
- geogCRS->coordinateSystem()->axisList().size() == 2
- ? io::AuthorityFactory::ObjectType::GEOGRAPHIC_2D_CRS
- : io::AuthorityFactory::ObjectType::GEOGRAPHIC_3D_CRS);
- }
- }
-
- auto projectedCrs = dynamic_cast<crs::ProjectedCRS *>(crs.get());
- if (projectedCrs && authFactory) {
- if (!ids.empty()) {
- const auto tmpAuthFactory = io::AuthorityFactory::create(
- authFactory->databaseContext(), *ids.front()->codeSpace());
- try {
- auto resolvedCrs(
- tmpAuthFactory->createProjectedCRS(ids.front()->code()));
- if (approxExtent || !extentOut) {
- extentOut = getExtent(resolvedCrs);
- }
- if (resolvedCrs->isEquivalentTo(
- crs.get(), util::IComparable::Criterion::EQUIVALENT)) {
- return util::nn_static_pointer_cast<crs::CRS>(resolvedCrs);
- }
- } catch (const std::exception &) {
- }
- } else {
- return tryToIdentifyByName(
- io::AuthorityFactory::ObjectType::PROJECTED_CRS);
- }
- }
-
- auto compoundCrs = dynamic_cast<crs::CompoundCRS *>(crs.get());
- if (compoundCrs && authFactory) {
- if (!ids.empty()) {
- const auto tmpAuthFactory = io::AuthorityFactory::create(
- authFactory->databaseContext(), *ids.front()->codeSpace());
- try {
- auto resolvedCrs(
- tmpAuthFactory->createCompoundCRS(ids.front()->code()));
- if (approxExtent || !extentOut) {
- extentOut = getExtent(resolvedCrs);
- }
- if (resolvedCrs->isEquivalentTo(
- crs.get(), util::IComparable::Criterion::EQUIVALENT)) {
- return util::nn_static_pointer_cast<crs::CRS>(resolvedCrs);
- }
- } catch (const std::exception &) {
- }
- } else {
- auto outCrs = tryToIdentifyByName(
- io::AuthorityFactory::ObjectType::COMPOUND_CRS);
- const auto &components = compoundCrs->componentReferenceSystems();
- if (outCrs.get() != crs.get()) {
- bool hasGeoid = false;
- if (components.size() == 2) {
- auto vertCRS =
- dynamic_cast<crs::VerticalCRS *>(components[1].get());
- if (vertCRS && !vertCRS->geoidModel().empty()) {
- hasGeoid = true;
- }
- }
- if (!hasGeoid) {
- return outCrs;
- }
- }
- if (approxExtent || !extentOut) {
- // If we still did not get a reliable extent, then try to
- // resolve the components of the compoundCRS, and take the
- // intersection of their extent.
- extentOut = metadata::ExtentPtr();
- for (const auto &component : components) {
- metadata::ExtentPtr componentExtent;
- getResolvedCRS(component, context, componentExtent);
- if (extentOut && componentExtent)
- extentOut = extentOut->intersection(
- NN_NO_CHECK(componentExtent));
- else if (componentExtent)
- extentOut = componentExtent;
- }
- }
- }
- }
- return crs;
-}
-
-// ---------------------------------------------------------------------------
-
/** \brief Find a list of CoordinateOperation from sourceCRS to targetCRS.
*
* The operations are sorted with the most relevant ones first: by
@@ -15655,13 +15741,14 @@ CoordinateOperationFactory::createOperations(
const auto &targetBoundCRS = targetCRS->canonicalBoundCRS();
auto l_sourceCRS = srcBoundCRS ? NN_NO_CHECK(srcBoundCRS) : sourceCRS;
auto l_targetCRS = targetBoundCRS ? NN_NO_CHECK(targetBoundCRS) : targetCRS;
+ const auto &authFactory = context->getAuthorityFactory();
metadata::ExtentPtr sourceCRSExtent;
auto l_resolvedSourceCRS =
- getResolvedCRS(l_sourceCRS, context, sourceCRSExtent);
+ crs::CRS::getResolvedCRS(l_sourceCRS, authFactory, sourceCRSExtent);
metadata::ExtentPtr targetCRSExtent;
auto l_resolvedTargetCRS =
- getResolvedCRS(l_targetCRS, context, targetCRSExtent);
+ crs::CRS::getResolvedCRS(l_targetCRS, authFactory, targetCRSExtent);
Private::Context contextPrivate(sourceCRSExtent, targetCRSExtent, context);
if (context->getSourceAndTargetCRSExtentUse() ==
@@ -15986,4 +16073,152 @@ PROJBasedOperation::gridsNeeded(const io::DatabaseContextPtr &databaseContext,
// ---------------------------------------------------------------------------
} // namespace operation
+
+namespace crs {
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+
+crs::CRSNNPtr CRS::getResolvedCRS(const crs::CRSNNPtr &crs,
+ const io::AuthorityFactoryPtr &authFactory,
+ metadata::ExtentPtr &extentOut) {
+ const auto &ids = crs->identifiers();
+ const auto &name = crs->nameStr();
+
+ bool approxExtent;
+ extentOut = getExtentPossiblySynthetized(crs, approxExtent);
+
+ // We try to "identify" the provided CRS with the ones of the database,
+ // but in a more restricted way that what identify() does.
+ // If we get a match from id in priority, and from name as a fallback, and
+ // that they are equivalent to the input CRS, then use the identified CRS.
+ // Even if they aren't equivalent, we update extentOut with the one of the
+ // identified CRS if our input one is absent/not reliable.
+
+ const auto tryToIdentifyByName = [&crs, &name, &authFactory, approxExtent,
+ &extentOut](
+ io::AuthorityFactory::ObjectType objectType) {
+ if (name != "unknown" && name != "unnamed") {
+ auto matches = authFactory->createObjectsFromName(
+ name, {objectType}, false, 2);
+ if (matches.size() == 1) {
+ const auto match =
+ util::nn_static_pointer_cast<crs::CRS>(matches.front());
+ if (approxExtent || !extentOut) {
+ extentOut = getExtent(match);
+ }
+ if (match->isEquivalentTo(
+ crs.get(), util::IComparable::Criterion::EQUIVALENT)) {
+ return match;
+ }
+ }
+ }
+ return crs;
+ };
+
+ auto geogCRS = dynamic_cast<crs::GeographicCRS *>(crs.get());
+ if (geogCRS && authFactory) {
+ if (!ids.empty()) {
+ const auto tmpAuthFactory = io::AuthorityFactory::create(
+ authFactory->databaseContext(), *ids.front()->codeSpace());
+ try {
+ auto resolvedCrs(
+ tmpAuthFactory->createGeographicCRS(ids.front()->code()));
+ if (approxExtent || !extentOut) {
+ extentOut = getExtent(resolvedCrs);
+ }
+ if (resolvedCrs->isEquivalentTo(
+ crs.get(), util::IComparable::Criterion::EQUIVALENT)) {
+ return util::nn_static_pointer_cast<crs::CRS>(resolvedCrs);
+ }
+ } catch (const std::exception &) {
+ }
+ } else {
+ return tryToIdentifyByName(
+ geogCRS->coordinateSystem()->axisList().size() == 2
+ ? io::AuthorityFactory::ObjectType::GEOGRAPHIC_2D_CRS
+ : io::AuthorityFactory::ObjectType::GEOGRAPHIC_3D_CRS);
+ }
+ }
+
+ auto projectedCrs = dynamic_cast<crs::ProjectedCRS *>(crs.get());
+ if (projectedCrs && authFactory) {
+ if (!ids.empty()) {
+ const auto tmpAuthFactory = io::AuthorityFactory::create(
+ authFactory->databaseContext(), *ids.front()->codeSpace());
+ try {
+ auto resolvedCrs(
+ tmpAuthFactory->createProjectedCRS(ids.front()->code()));
+ if (approxExtent || !extentOut) {
+ extentOut = getExtent(resolvedCrs);
+ }
+ if (resolvedCrs->isEquivalentTo(
+ crs.get(), util::IComparable::Criterion::EQUIVALENT)) {
+ return util::nn_static_pointer_cast<crs::CRS>(resolvedCrs);
+ }
+ } catch (const std::exception &) {
+ }
+ } else {
+ return tryToIdentifyByName(
+ io::AuthorityFactory::ObjectType::PROJECTED_CRS);
+ }
+ }
+
+ auto compoundCrs = dynamic_cast<crs::CompoundCRS *>(crs.get());
+ if (compoundCrs && authFactory) {
+ if (!ids.empty()) {
+ const auto tmpAuthFactory = io::AuthorityFactory::create(
+ authFactory->databaseContext(), *ids.front()->codeSpace());
+ try {
+ auto resolvedCrs(
+ tmpAuthFactory->createCompoundCRS(ids.front()->code()));
+ if (approxExtent || !extentOut) {
+ extentOut = getExtent(resolvedCrs);
+ }
+ if (resolvedCrs->isEquivalentTo(
+ crs.get(), util::IComparable::Criterion::EQUIVALENT)) {
+ return util::nn_static_pointer_cast<crs::CRS>(resolvedCrs);
+ }
+ } catch (const std::exception &) {
+ }
+ } else {
+ auto outCrs = tryToIdentifyByName(
+ io::AuthorityFactory::ObjectType::COMPOUND_CRS);
+ const auto &components = compoundCrs->componentReferenceSystems();
+ if (outCrs.get() != crs.get()) {
+ bool hasGeoid = false;
+ if (components.size() == 2) {
+ auto vertCRS =
+ dynamic_cast<crs::VerticalCRS *>(components[1].get());
+ if (vertCRS && !vertCRS->geoidModel().empty()) {
+ hasGeoid = true;
+ }
+ }
+ if (!hasGeoid) {
+ return outCrs;
+ }
+ }
+ if (approxExtent || !extentOut) {
+ // If we still did not get a reliable extent, then try to
+ // resolve the components of the compoundCRS, and take the
+ // intersection of their extent.
+ extentOut = metadata::ExtentPtr();
+ for (const auto &component : components) {
+ metadata::ExtentPtr componentExtent;
+ getResolvedCRS(component, authFactory, componentExtent);
+ if (extentOut && componentExtent)
+ extentOut = extentOut->intersection(
+ NN_NO_CHECK(componentExtent));
+ else if (componentExtent)
+ extentOut = componentExtent;
+ }
+ }
+ }
+ }
+ return crs;
+}
+
+//! @endcond
+
+} // namespace crs
NS_PROJ_END
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index edc8a71f..573dd6db 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -533,8 +533,12 @@ CRSNNPtr CRS::createBoundCRSToWGS84IfPossible(
auto authFactory = io::AuthorityFactory::create(
NN_NO_CHECK(dbContext),
authority == "any" ? std::string() : authority);
+ metadata::ExtentPtr extentResolved(extent);
+ if (!extent) {
+ getResolvedCRS(thisAsCRS, authFactory, extentResolved);
+ }
auto ctxt = operation::CoordinateOperationContext::create(
- authFactory, extent, 0.0);
+ authFactory, extentResolved, 0.0);
ctxt->setAllowUseIntermediateCRS(allowIntermediateCRSUse);
// ctxt->setSpatialCriterion(
// operation::CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION);
@@ -1616,6 +1620,34 @@ static bool exportAsESRIWktCompoundCRSWithEllipsoidalHeight(
vertCRSList.front()->_exportToWKT(formatter);
return true;
}
+
+// ---------------------------------------------------------------------------
+
+// Try to format a Geographic/ProjectedCRS 3D CRS as a
+// GEOGCS[]/PROJCS[],VERTCS["Ellipsoid (metre)",DATUM["Ellipsoid",2002],...]
+static bool exportAsWKT1CompoundCRSWithEllipsoidalHeight(
+ const CRSNNPtr &base2DCRS,
+ const cs::CoordinateSystemAxisNNPtr &verticalAxis,
+ io::WKTFormatter *formatter) {
+ std::string verticalCRSName = "Ellipsoid (";
+ verticalCRSName += verticalAxis->unit().name();
+ verticalCRSName += ')';
+ auto vertDatum = datum::VerticalReferenceFrame::create(
+ util::PropertyMap()
+ .set(common::IdentifiedObject::NAME_KEY, "Ellipsoid")
+ .set("VERT_DATUM_TYPE", "2002"));
+ auto vertCRS = VerticalCRS::create(
+ util::PropertyMap().set(common::IdentifiedObject::NAME_KEY,
+ verticalCRSName),
+ vertDatum.as_nullable(), nullptr,
+ cs::VerticalCS::create(util::PropertyMap(), verticalAxis));
+ formatter->startNode(io::WKTConstants::COMPD_CS, false);
+ formatter->addQuotedString(base2DCRS->nameStr() + " + " + verticalCRSName);
+ base2DCRS->_exportToWKT(formatter);
+ vertCRS->_exportToWKT(formatter);
+ formatter->endNode();
+ return true;
+}
//! @endcond
// ---------------------------------------------------------------------------
@@ -1683,6 +1715,13 @@ void GeodeticCRS::_exportToWKT(io::WKTFormatter *formatter) const {
return;
}
+ if (formatter->isAllowedEllipsoidalHeightAsVerticalCRS()) {
+ if (exportAsWKT1CompoundCRSWithEllipsoidalHeight(
+ geogCRS2D, axisList[2], formatter)) {
+ return;
+ }
+ }
+
io::FormattingException::Throw(
"WKT1 does not support Geographic 3D CRS.");
}
@@ -1922,11 +1961,19 @@ getStandardCriterion(util::IComparable::Criterion criterion) {
bool GeodeticCRS::_isEquivalentTo(
const util::IComparable *other, util::IComparable::Criterion criterion,
const io::DatabaseContextPtr &dbContext) const {
+ if (other == nullptr || !util::isOfExactType<GeodeticCRS>(*other)) {
+ return false;
+ }
+ return _isEquivalentToNoTypeCheck(other, criterion, dbContext);
+}
+
+bool GeodeticCRS::_isEquivalentToNoTypeCheck(
+ const util::IComparable *other, util::IComparable::Criterion criterion,
+ const io::DatabaseContextPtr &dbContext) const {
const auto standardCriterion = getStandardCriterion(criterion);
- auto otherGeodCRS = dynamic_cast<const GeodeticCRS *>(other);
+
// TODO test velocityModel
- return otherGeodCRS != nullptr &&
- SingleCRS::baseIsEquivalentTo(other, standardCriterion, dbContext);
+ return SingleCRS::baseIsEquivalentTo(other, standardCriterion, dbContext);
}
//! @endcond
@@ -2482,12 +2529,13 @@ bool GeographicCRS::is2DPartOf3D(util::nn<const GeographicCRS *> other,
bool GeographicCRS::_isEquivalentTo(
const util::IComparable *other, util::IComparable::Criterion criterion,
const io::DatabaseContextPtr &dbContext) const {
- auto otherGeogCRS = dynamic_cast<const GeographicCRS *>(other);
- if (otherGeogCRS == nullptr) {
+ if (other == nullptr || !util::isOfExactType<GeographicCRS>(*other)) {
return false;
}
+
const auto standardCriterion = getStandardCriterion(criterion);
- if (GeodeticCRS::_isEquivalentTo(other, standardCriterion, dbContext)) {
+ if (GeodeticCRS::_isEquivalentToNoTypeCheck(other, standardCriterion,
+ dbContext)) {
return true;
}
if (criterion !=
@@ -2506,7 +2554,29 @@ bool GeographicCRS::_isEquivalentTo(
cs::EllipsoidalCS::AxisOrder::LONG_EAST_LAT_NORTH
? cs::EllipsoidalCS::createLatitudeLongitude(unit)
: cs::EllipsoidalCS::createLongitudeLatitude(unit))
- ->GeodeticCRS::_isEquivalentTo(other, standardCriterion, dbContext);
+ ->GeodeticCRS::_isEquivalentToNoTypeCheck(other, standardCriterion,
+ dbContext);
+ }
+ if (axisOrder ==
+ cs::EllipsoidalCS::AxisOrder::LONG_EAST_LAT_NORTH_HEIGHT_UP ||
+ axisOrder ==
+ cs::EllipsoidalCS::AxisOrder::LAT_NORTH_LONG_EAST_HEIGHT_UP) {
+ const auto &angularUnit = coordinateSystem()->axisList()[0]->unit();
+ const auto &linearUnit = coordinateSystem()->axisList()[2]->unit();
+ return GeographicCRS::create(
+ util::PropertyMap().set(common::IdentifiedObject::NAME_KEY,
+ nameStr()),
+ datum(), datumEnsemble(),
+ axisOrder == cs::EllipsoidalCS::AxisOrder::
+ LONG_EAST_LAT_NORTH_HEIGHT_UP
+ ? cs::EllipsoidalCS::
+ createLatitudeLongitudeEllipsoidalHeight(
+ angularUnit, linearUnit)
+ : cs::EllipsoidalCS::
+ createLongitudeLatitudeEllipsoidalHeight(
+ angularUnit, linearUnit))
+ ->GeodeticCRS::_isEquivalentToNoTypeCheck(other, standardCriterion,
+ dbContext);
}
return false;
}
@@ -3605,6 +3675,14 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const {
return;
}
+ if (!formatter->useESRIDialect() &&
+ formatter->isAllowedEllipsoidalHeightAsVerticalCRS()) {
+ if (exportAsWKT1CompoundCRSWithEllipsoidalHeight(
+ projCRS2D, axisList[2], formatter)) {
+ return;
+ }
+ }
+
io::FormattingException::Throw(
"Projected 3D CRS can only be exported since WKT2:2019");
}
@@ -3885,8 +3963,7 @@ ProjectedCRS::create(const util::PropertyMap &properties,
bool ProjectedCRS::_isEquivalentTo(
const util::IComparable *other, util::IComparable::Criterion criterion,
const io::DatabaseContextPtr &dbContext) const {
- auto otherProjCRS = dynamic_cast<const ProjectedCRS *>(other);
- return otherProjCRS != nullptr &&
+ return other != nullptr && util::isOfExactType<ProjectedCRS>(*other) &&
DerivedCRS::_isEquivalentTo(other, criterion, dbContext);
}
diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp
index 5bc8074c..8e1b8257 100644
--- a/src/iso19111/datum.cpp
+++ b/src/iso19111/datum.cpp
@@ -43,7 +43,6 @@
// clang-format off
#include "proj.h"
#include "proj_internal.h"
-#include "proj_api.h"
// clang-format on
#include "proj_json_streaming_writer.hpp"
@@ -352,6 +351,23 @@ void PrimeMeridian::_exportToWKT(
if (!(isWKT2 && formatter->primeMeridianOmittedIfGreenwich() &&
l_name == "Greenwich")) {
formatter->startNode(io::WKTConstants::PRIMEM, !identifiers().empty());
+
+ if (formatter->useESRIDialect()) {
+ bool aliasFound = false;
+ const auto &dbContext = formatter->databaseContext();
+ if (dbContext) {
+ auto l_alias = dbContext->getAliasFromOfficialName(
+ l_name, "prime_meridian", "ESRI");
+ if (!l_alias.empty()) {
+ l_name = l_alias;
+ aliasFound = true;
+ }
+ }
+ if (!aliasFound) {
+ l_name = io::WKTFormatter::morphNameToESRI(l_name);
+ }
+ }
+
formatter->addQuotedString(l_name);
const auto &l_long = longitude();
if (formatter->primeMeridianInDegree()) {
@@ -418,7 +434,7 @@ std::string
PrimeMeridian::getPROJStringWellKnownName(const common::Angle &angle) {
const double valRad = angle.getSIValue();
std::string projPMName;
- projCtx ctxt = pj_ctx_alloc();
+ PJ_CONTEXT *ctxt = proj_context_create();
auto proj_pm = proj_list_prime_meridians();
for (int i = 0; proj_pm[i].id != nullptr; ++i) {
double valRefRad = dmstor_ctx(ctxt, proj_pm[i].defn, nullptr);
@@ -427,7 +443,7 @@ PrimeMeridian::getPROJStringWellKnownName(const common::Angle &angle) {
break;
}
}
- pj_ctx_free(ctxt);
+ proj_context_destroy(ctxt);
return projPMName;
}
//! @endcond
@@ -1731,6 +1747,14 @@ void DatumEnsemble::_exportToWKT(
formatter->startNode(io::WKTConstants::ENSEMBLEACCURACY, false);
formatter->add(positionalAccuracy()->value());
formatter->endNode();
+
+ // In theory, we should do the following, but currently the WKT grammar
+ // doesn't allow this
+ // ObjectUsage::baseExportToWKT(formatter);
+ if (formatter->outputId()) {
+ formatID(formatter);
+ }
+
formatter->endNode();
}
//! @endcond
diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp
index 5d02aeea..2a03fd4e 100644
--- a/src/iso19111/factory.cpp
+++ b/src/iso19111/factory.cpp
@@ -65,7 +65,6 @@
// clang-format off
#include "proj.h"
#include "proj_internal.h"
-#include "proj_api.h"
// clang-format on
#include <sqlite3.h>
@@ -94,6 +93,12 @@ namespace io {
#define GEOG_3D_SINGLE_QUOTED "'geographic 3D'"
#define GEOCENTRIC_SINGLE_QUOTED "'geocentric'"
+// See data/sql/metadata.sql for the semantics of those constants
+constexpr int DATABASE_LAYOUT_VERSION_MAJOR = 1;
+// If the code depends on the new additions, then DATABASE_LAYOUT_VERSION_MINOR
+// must be incremented.
+constexpr int DATABASE_LAYOUT_VERSION_MINOR = 0;
+
// ---------------------------------------------------------------------------
struct SQLValues {
@@ -192,6 +197,13 @@ struct DatabaseContext::Private {
void cache(const std::string &code,
const datum::GeodeticReferenceFrameNNPtr &datum);
+ datum::DatumEnsemblePtr
+ // cppcheck-suppress functionStatic
+ getDatumEnsembleFromCache(const std::string &code);
+ // cppcheck-suppress functionStatic
+ void cache(const std::string &code,
+ const datum::DatumEnsembleNNPtr &datumEnsemble);
+
datum::EllipsoidPtr
// cppcheck-suppress functionStatic
getEllipsoidFromCache(const std::string &code);
@@ -258,6 +270,7 @@ struct DatabaseContext::Private {
LRUCacheOfObjects cacheCRS_{CACHE_SIZE};
LRUCacheOfObjects cacheEllipsoid_{CACHE_SIZE};
LRUCacheOfObjects cacheGeodeticDatum_{CACHE_SIZE};
+ LRUCacheOfObjects cacheDatumEnsemble_{CACHE_SIZE};
LRUCacheOfObjects cachePrimeMeridian_{CACHE_SIZE};
LRUCacheOfObjects cacheCS_{CACHE_SIZE};
LRUCacheOfObjects cacheExtent_{CACHE_SIZE};
@@ -270,6 +283,8 @@ struct DatabaseContext::Private {
lru11::Cache<std::string, std::list<std::string>> cacheAliasNames_{
CACHE_SIZE};
+ void checkDatabaseLayout();
+
static void insertIntoCache(LRUCacheOfObjects &cache,
const std::string &code,
const util::BaseObjectPtr &obj);
@@ -417,6 +432,22 @@ void DatabaseContext::Private::cache(
// ---------------------------------------------------------------------------
+datum::DatumEnsemblePtr
+DatabaseContext::Private::getDatumEnsembleFromCache(const std::string &code) {
+ util::BaseObjectPtr obj;
+ getFromCache(cacheDatumEnsemble_, code, obj);
+ return std::static_pointer_cast<datum::DatumEnsemble>(obj);
+}
+
+// ---------------------------------------------------------------------------
+
+void DatabaseContext::Private::cache(
+ const std::string &code, const datum::DatumEnsembleNNPtr &datumEnsemble) {
+ insertIntoCache(cacheDatumEnsemble_, code, datumEnsemble.as_nullable());
+}
+
+// ---------------------------------------------------------------------------
+
datum::EllipsoidPtr
DatabaseContext::Private::getEllipsoidFromCache(const std::string &code) {
util::BaseObjectPtr obj;
@@ -548,6 +579,61 @@ void DatabaseContext::Private::open(const std::string &databasePath,
// ---------------------------------------------------------------------------
+void DatabaseContext::Private::checkDatabaseLayout() {
+ auto res = run("SELECT key, value FROM metadata WHERE key IN "
+ "('DATABASE.LAYOUT.VERSION.MAJOR', "
+ "'DATABASE.LAYOUT.VERSION.MINOR')");
+ if (res.size() != 2) {
+ // The database layout of PROJ 7.2 that shipped with EPSG v10.003 is
+ // at the time of writing still compatible of the one we support.
+ static_assert(
+ // cppcheck-suppress knownConditionTrueFalse
+ DATABASE_LAYOUT_VERSION_MAJOR == 1 &&
+ // cppcheck-suppress knownConditionTrueFalse
+ DATABASE_LAYOUT_VERSION_MINOR == 0,
+ "remove that assertion and below lines next time we upgrade "
+ "database structure");
+ res = run("SELECT 1 FROM metadata WHERE key = 'EPSG.VERSION' AND "
+ "value = 'v10.003'");
+ if (!res.empty()) {
+ return;
+ }
+
+ throw FactoryException(
+ databasePath_ +
+ " lacks DATABASE.LAYOUT.VERSION.MAJOR / "
+ "DATABASE.LAYOUT.VERSION.MINOR "
+ "metadata. It comes from another PROJ installation.");
+ }
+ int nMajor = 0;
+ int nMinor = 0;
+ for (const auto &row : res) {
+ if (row[0] == "DATABASE.LAYOUT.VERSION.MAJOR") {
+ nMajor = atoi(row[1].c_str());
+ } else if (row[0] == "DATABASE.LAYOUT.VERSION.MINOR") {
+ nMinor = atoi(row[1].c_str());
+ }
+ }
+ if (nMajor != DATABASE_LAYOUT_VERSION_MAJOR) {
+ throw FactoryException(databasePath_ +
+ " contains DATABASE.LAYOUT.VERSION.MAJOR = " +
+ toString(nMajor) + " whereas " +
+ toString(DATABASE_LAYOUT_VERSION_MAJOR) +
+ " is expected. "
+ "It comes from another PROJ installation.");
+ }
+ if (nMinor < DATABASE_LAYOUT_VERSION_MINOR) {
+ throw FactoryException(databasePath_ +
+ " contains DATABASE.LAYOUT.VERSION.MINOR = " +
+ toString(nMinor) + " whereas a number >= " +
+ toString(DATABASE_LAYOUT_VERSION_MINOR) +
+ " is expected. "
+ "It comes from another PROJ installation.");
+ }
+}
+
+// ---------------------------------------------------------------------------
+
void DatabaseContext::Private::setHandle(sqlite3 *sqlite_handle) {
assert(sqlite_handle);
@@ -865,6 +951,7 @@ DatabaseContext::create(const std::string &databasePath,
if (!auxiliaryDatabasePaths.empty()) {
dbCtx->getPrivate()->attachExtraDatabases(auxiliaryDatabasePaths);
}
+ dbCtx->getPrivate()->checkDatabaseLayout();
return dbCtx;
}
@@ -1064,18 +1151,6 @@ std::string DatabaseContext::getOldProjGridName(const std::string &gridName) {
// ---------------------------------------------------------------------------
-// FIXME: as we don't support datum ensemble yet, add it from name
-static std::string removeEnsembleSuffix(const std::string &name) {
- if (name == "World Geodetic System 1984 ensemble") {
- return "World Geodetic System 1984";
- } else if (name == "European Terrestrial Reference System 1989 ensemble") {
- return "European Terrestrial Reference System 1989";
- }
- return name;
-}
-
-// ---------------------------------------------------------------------------
-
/** \brief Gets the alias name from an official name.
*
* @param officialName Official name. Mandatory
@@ -2012,18 +2087,38 @@ AuthorityFactory::createEllipsoid(const std::string &code) const {
datum::GeodeticReferenceFrameNNPtr
AuthorityFactory::createGeodeticDatum(const std::string &code) const {
+
+ datum::GeodeticReferenceFramePtr datum;
+ datum::DatumEnsemblePtr datumEnsemble;
+ constexpr bool turnEnsembleAsDatum = true;
+ createGeodeticDatumOrEnsemble(code, datum, datumEnsemble,
+ turnEnsembleAsDatum);
+ return NN_NO_CHECK(datum);
+}
+
+// ---------------------------------------------------------------------------
+
+void AuthorityFactory::createGeodeticDatumOrEnsemble(
+ const std::string &code, datum::GeodeticReferenceFramePtr &outDatum,
+ datum::DatumEnsemblePtr &outDatumEnsemble, bool turnEnsembleAsDatum) const {
const auto cacheKey(d->authority() + code);
{
- auto datum = d->context()->d->getGeodeticDatumFromCache(cacheKey);
- if (datum) {
- return NN_NO_CHECK(datum);
+ outDatumEnsemble = d->context()->d->getDatumEnsembleFromCache(cacheKey);
+ if (outDatumEnsemble) {
+ if (!turnEnsembleAsDatum)
+ return;
+ outDatumEnsemble = nullptr;
+ }
+ outDatum = d->context()->d->getGeodeticDatumFromCache(cacheKey);
+ if (outDatum) {
+ return;
}
}
auto res =
d->runWithCodeParam("SELECT name, ellipsoid_auth_name, ellipsoid_code, "
"prime_meridian_auth_name, prime_meridian_code, "
"publication_date, frame_reference_epoch, "
- "deprecated FROM geodetic_datum "
+ "ensemble_accuracy, deprecated FROM geodetic_datum "
"WHERE "
"auth_name = ? AND code = ?",
code);
@@ -2040,29 +2135,63 @@ AuthorityFactory::createGeodeticDatum(const std::string &code) const {
const auto &prime_meridian_code = row[4];
const auto &publication_date = row[5];
const auto &frame_reference_epoch = row[6];
- const bool deprecated = row[7] == "1";
- auto ellipsoid = d->createFactory(ellipsoid_auth_name)
- ->createEllipsoid(ellipsoid_code);
- auto pm = d->createFactory(prime_meridian_auth_name)
- ->createPrimeMeridian(prime_meridian_code);
- auto props = d->createPropertiesSearchUsages(
- "geodetic_datum", code, removeEnsembleSuffix(name), deprecated);
- auto anchor = util::optional<std::string>();
- if (!publication_date.empty()) {
- props.set("PUBLICATION_DATE", publication_date);
- }
- auto datum =
- frame_reference_epoch.empty()
- ? datum::GeodeticReferenceFrame::create(props, ellipsoid,
- anchor, pm)
- : util::nn_static_pointer_cast<datum::GeodeticReferenceFrame>(
- datum::DynamicGeodeticReferenceFrame::create(
- props, ellipsoid, anchor, pm,
- common::Measure(c_locale_stod(frame_reference_epoch),
- common::UnitOfMeasure::YEAR),
- util::optional<std::string>()));
- d->context()->d->cache(cacheKey, datum);
- return datum;
+ const auto &ensemble_accuracy = row[7];
+ const bool deprecated = row[8] == "1";
+
+ std::string massagedName = name;
+ if (turnEnsembleAsDatum) {
+ if (name == "World Geodetic System 1984 ensemble") {
+ massagedName = "World Geodetic System 1984";
+ } else if (name ==
+ "European Terrestrial Reference System 1989 ensemble") {
+ massagedName = "European Terrestrial Reference System 1989";
+ }
+ }
+ auto props = d->createPropertiesSearchUsages("geodetic_datum", code,
+ massagedName, deprecated);
+
+ if (!turnEnsembleAsDatum && !ensemble_accuracy.empty()) {
+ auto resMembers =
+ d->run("SELECT member_auth_name, member_code FROM "
+ "geodetic_datum_ensemble_member WHERE "
+ "ensemble_auth_name = ? AND ensemble_code = ? "
+ "ORDER BY sequence",
+ {d->authority(), code});
+
+ std::vector<datum::DatumNNPtr> members;
+ for (const auto &memberRow : resMembers) {
+ members.push_back(
+ d->createFactory(memberRow[0])->createDatum(memberRow[1]));
+ }
+ auto datumEnsemble = datum::DatumEnsemble::create(
+ props, std::move(members),
+ metadata::PositionalAccuracy::create(ensemble_accuracy));
+ d->context()->d->cache(cacheKey, datumEnsemble);
+ outDatumEnsemble = datumEnsemble.as_nullable();
+ } else {
+ auto ellipsoid = d->createFactory(ellipsoid_auth_name)
+ ->createEllipsoid(ellipsoid_code);
+ auto pm = d->createFactory(prime_meridian_auth_name)
+ ->createPrimeMeridian(prime_meridian_code);
+
+ auto anchor = util::optional<std::string>();
+ if (!publication_date.empty()) {
+ props.set("PUBLICATION_DATE", publication_date);
+ }
+ auto datum = frame_reference_epoch.empty()
+ ? datum::GeodeticReferenceFrame::create(
+ props, ellipsoid, anchor, pm)
+ : util::nn_static_pointer_cast<
+ datum::GeodeticReferenceFrame>(
+ datum::DynamicGeodeticReferenceFrame::create(
+ props, ellipsoid, anchor, pm,
+ common::Measure(
+ c_locale_stod(frame_reference_epoch),
+ common::UnitOfMeasure::YEAR),
+ util::optional<std::string>()));
+ d->context()->d->cache(cacheKey, datum);
+ outDatum = datum.as_nullable();
+ }
} catch (const std::exception &ex) {
throw buildFactoryException("geodetic reference frame", code, ex);
}
@@ -2080,9 +2209,23 @@ AuthorityFactory::createGeodeticDatum(const std::string &code) const {
datum::VerticalReferenceFrameNNPtr
AuthorityFactory::createVerticalDatum(const std::string &code) const {
+ datum::VerticalReferenceFramePtr datum;
+ datum::DatumEnsemblePtr datumEnsemble;
+ constexpr bool turnEnsembleAsDatum = true;
+ createVerticalDatumOrEnsemble(code, datum, datumEnsemble,
+ turnEnsembleAsDatum);
+ return NN_NO_CHECK(datum);
+}
+
+// ---------------------------------------------------------------------------
+
+void AuthorityFactory::createVerticalDatumOrEnsemble(
+ const std::string &code, datum::VerticalReferenceFramePtr &outDatum,
+ datum::DatumEnsemblePtr &outDatumEnsemble, bool turnEnsembleAsDatum) const {
auto res =
d->runWithCodeParam("SELECT name, publication_date, "
- "frame_reference_epoch, deprecated FROM "
+ "frame_reference_epoch, ensemble_accuracy, "
+ "deprecated FROM "
"vertical_datum WHERE auth_name = ? AND code = ?",
code);
if (res.empty()) {
@@ -2094,24 +2237,49 @@ AuthorityFactory::createVerticalDatum(const std::string &code) const {
const auto &name = row[0];
const auto &publication_date = row[1];
const auto &frame_reference_epoch = row[2];
- const bool deprecated = row[3] == "1";
+ const auto &ensemble_accuracy = row[3];
+ const bool deprecated = row[4] == "1";
auto props = d->createPropertiesSearchUsages("vertical_datum", code,
name, deprecated);
- if (!publication_date.empty()) {
- props.set("PUBLICATION_DATE", publication_date);
- }
- if (d->authority() == "ESRI" && starts_with(code, "from_geogdatum_")) {
- props.set("VERT_DATUM_TYPE", "2002");
- }
- auto anchor = util::optional<std::string>();
- if (frame_reference_epoch.empty()) {
- return datum::VerticalReferenceFrame::create(props, anchor);
+ if (!turnEnsembleAsDatum && !ensemble_accuracy.empty()) {
+ auto resMembers =
+ d->run("SELECT member_auth_name, member_code FROM "
+ "vertical_datum_ensemble_member WHERE "
+ "ensemble_auth_name = ? AND ensemble_code = ? "
+ "ORDER BY sequence",
+ {d->authority(), code});
+
+ std::vector<datum::DatumNNPtr> members;
+ for (const auto &memberRow : resMembers) {
+ members.push_back(
+ d->createFactory(memberRow[0])->createDatum(memberRow[1]));
+ }
+ auto datumEnsemble = datum::DatumEnsemble::create(
+ props, std::move(members),
+ metadata::PositionalAccuracy::create(ensemble_accuracy));
+ outDatumEnsemble = datumEnsemble.as_nullable();
} else {
- return datum::DynamicVerticalReferenceFrame::create(
- props, anchor, util::optional<datum::RealizationMethod>(),
- common::Measure(c_locale_stod(frame_reference_epoch),
- common::UnitOfMeasure::YEAR),
- util::optional<std::string>());
+ if (!publication_date.empty()) {
+ props.set("PUBLICATION_DATE", publication_date);
+ }
+ if (d->authority() == "ESRI" &&
+ starts_with(code, "from_geogdatum_")) {
+ props.set("VERT_DATUM_TYPE", "2002");
+ }
+ auto anchor = util::optional<std::string>();
+ if (frame_reference_epoch.empty()) {
+ outDatum = datum::VerticalReferenceFrame::create(props, anchor)
+ .as_nullable();
+ } else {
+ outDatum =
+ datum::DynamicVerticalReferenceFrame::create(
+ props, anchor,
+ util::optional<datum::RealizationMethod>(),
+ common::Measure(c_locale_stod(frame_reference_epoch),
+ common::UnitOfMeasure::YEAR),
+ util::optional<std::string>())
+ .as_nullable();
+ }
}
} catch (const std::exception &ex) {
throw buildFactoryException("vertical reference frame", code, ex);
@@ -2472,20 +2640,24 @@ AuthorityFactory::createGeodeticCRS(const std::string &code,
auto cs =
d->createFactory(cs_auth_name)->createCoordinateSystem(cs_code);
- auto datum =
- d->createFactory(datum_auth_name)->createGeodeticDatum(datum_code);
+ datum::GeodeticReferenceFramePtr datum;
+ datum::DatumEnsemblePtr datumEnsemble;
+ constexpr bool turnEnsembleAsDatum = false;
+ d->createFactory(datum_auth_name)
+ ->createGeodeticDatumOrEnsemble(datum_code, datum, datumEnsemble,
+ turnEnsembleAsDatum);
auto ellipsoidalCS =
util::nn_dynamic_pointer_cast<cs::EllipsoidalCS>(cs);
if ((type == GEOG_2D || type == GEOG_3D) && ellipsoidalCS) {
auto crsRet = crs::GeographicCRS::create(
- props, datum, NN_NO_CHECK(ellipsoidalCS));
+ props, datum, datumEnsemble, NN_NO_CHECK(ellipsoidalCS));
d->context()->d->cache(cacheKey, crsRet);
return crsRet;
}
auto geocentricCS = util::nn_dynamic_pointer_cast<cs::CartesianCS>(cs);
if (type == GEOCENTRIC && geocentricCS) {
- auto crsRet = crs::GeodeticCRS::create(props, datum,
+ auto crsRet = crs::GeodeticCRS::create(props, datum, datumEnsemble,
NN_NO_CHECK(geocentricCS));
d->context()->d->cache(cacheKey, crsRet);
return crsRet;
@@ -2539,16 +2711,19 @@ AuthorityFactory::createVerticalCRS(const std::string &code) const {
const bool deprecated = row[5] == "1";
auto cs =
d->createFactory(cs_auth_name)->createCoordinateSystem(cs_code);
- auto datum =
- d->createFactory(datum_auth_name)->createVerticalDatum(datum_code);
-
+ datum::VerticalReferenceFramePtr datum;
+ datum::DatumEnsemblePtr datumEnsemble;
+ constexpr bool turnEnsembleAsDatum = false;
+ d->createFactory(datum_auth_name)
+ ->createVerticalDatumOrEnsemble(datum_code, datum, datumEnsemble,
+ turnEnsembleAsDatum);
auto props = d->createPropertiesSearchUsages("vertical_crs", code, name,
deprecated);
auto verticalCS = util::nn_dynamic_pointer_cast<cs::VerticalCS>(cs);
if (verticalCS) {
- auto crsRet =
- crs::VerticalCRS::create(props, datum, NN_NO_CHECK(verticalCS));
+ auto crsRet = crs::VerticalCRS::create(props, datum, datumEnsemble,
+ NN_NO_CHECK(verticalCS));
d->context()->d->cache(cacheKey, crsRet);
return crsRet;
}
@@ -5340,6 +5515,11 @@ AuthorityFactory::getAuthorityCodes(const ObjectType &type,
case ObjectType::CONCATENATED_OPERATION:
sql = "SELECT code FROM concatenated_operation WHERE ";
break;
+ case ObjectType::DATUM_ENSEMBLE:
+ sql = "SELECT code FROM object_view WHERE table_name IN "
+ "('geodetic_datum', 'vertical_datum') AND "
+ "type = 'ensemble' AND ";
+ break;
}
sql += "auth_name = ?";
@@ -5617,7 +5797,7 @@ std::string AuthorityFactory::getOfficialNameFromAlias(
if (res.empty()) { // shouldn't happen normally
return std::string();
}
- return removeEnsembleSuffix(res.front()[0]);
+ return res.front()[0];
}
}
return std::string();
@@ -5667,7 +5847,7 @@ std::string AuthorityFactory::getOfficialNameFromAlias(
outTableName = row[1];
outAuthName = row[2];
outCode = row[3];
- return removeEnsembleSuffix(row[0]);
+ return row[0];
}
}
@@ -5849,12 +6029,28 @@ AuthorityFactory::createObjectsFromNameEx(
res.emplace_back(
TableType("concatenated_operation", std::string()));
break;
+ case ObjectType::DATUM_ENSEMBLE:
+ res.emplace_back(TableType("geodetic_datum", "ensemble"));
+ res.emplace_back(TableType("vertical_datum", "ensemble"));
+ break;
}
}
}
return res;
};
+ bool datumEnsembleAllowed = false;
+ if (allowedObjectTypes.empty()) {
+ datumEnsembleAllowed = true;
+ } else {
+ for (const auto type : allowedObjectTypes) {
+ if (type == ObjectType::DATUM_ENSEMBLE) {
+ datumEnsembleAllowed = true;
+ break;
+ }
+ }
+ }
+
const auto listTableNameType = getTableAndTypeConstraints();
bool first = true;
ListOfParams params;
@@ -5872,6 +6068,8 @@ AuthorityFactory::createObjectsFromNameEx(
if (!tableNameTypePair.second.empty()) {
if (tableNameTypePair.second == "frame_reference_epoch") {
sql += "AND frame_reference_epoch IS NOT NULL ";
+ } else if (tableNameTypePair.second == "ensemble") {
+ sql += "AND ensemble_accuracy IS NOT NULL ";
} else {
sql += "AND type = '";
sql += tableNameTypePair.second;
@@ -5906,6 +6104,8 @@ AuthorityFactory::createObjectsFromNameEx(
if (!tableNameTypePair.second.empty()) {
if (tableNameTypePair.second == "frame_reference_epoch") {
sql += "AND ov.frame_reference_epoch IS NOT NULL ";
+ } else if (tableNameTypePair.second == "ensemble") {
+ sql += "AND ov.ensemble_accuracy IS NOT NULL ";
} else {
sql += "AND ov.type = '";
sql += tableNameTypePair.second;
@@ -6019,6 +6219,8 @@ AuthorityFactory::createObjectsFromNameEx(
auto sqlRes = d->run(sql, params);
bool isFirst = true;
bool firstIsDeprecated = false;
+ bool foundExactMatch = false;
+ std::size_t hashCodeFirstMatch = 0;
for (const auto &row : sqlRes) {
const auto &name = row[3];
if (approximateMatch) {
@@ -6053,7 +6255,7 @@ AuthorityFactory::createObjectsFromNameEx(
break;
}
auto factory = d->createFactory(auth_name);
- auto getObject = [&factory](
+ auto getObject = [&factory, datumEnsembleAllowed](
const std::string &l_table_name,
const std::string &l_code) -> common::IdentifiedObjectNNPtr {
if (l_table_name == "prime_meridian") {
@@ -6061,8 +6263,32 @@ AuthorityFactory::createObjectsFromNameEx(
} else if (l_table_name == "ellipsoid") {
return factory->createEllipsoid(l_code);
} else if (l_table_name == "geodetic_datum") {
+ if (datumEnsembleAllowed) {
+ datum::GeodeticReferenceFramePtr datum;
+ datum::DatumEnsemblePtr datumEnsemble;
+ constexpr bool turnEnsembleAsDatum = false;
+ factory->createGeodeticDatumOrEnsemble(
+ l_code, datum, datumEnsemble, turnEnsembleAsDatum);
+ if (datum) {
+ return NN_NO_CHECK(datum);
+ }
+ assert(datumEnsemble);
+ return NN_NO_CHECK(datumEnsemble);
+ }
return factory->createGeodeticDatum(l_code);
} else if (l_table_name == "vertical_datum") {
+ if (datumEnsembleAllowed) {
+ datum::VerticalReferenceFramePtr datum;
+ datum::DatumEnsemblePtr datumEnsemble;
+ constexpr bool turnEnsembleAsDatum = false;
+ factory->createVerticalDatumOrEnsemble(
+ l_code, datum, datumEnsemble, turnEnsembleAsDatum);
+ if (datum) {
+ return NN_NO_CHECK(datum);
+ }
+ assert(datumEnsemble);
+ return NN_NO_CHECK(datumEnsemble);
+ }
return factory->createVerticalDatum(l_code);
} else if (l_table_name == "geodetic_crs") {
return factory->createGeodeticCRS(l_code);
@@ -6082,11 +6308,38 @@ AuthorityFactory::createObjectsFromNameEx(
}
throw std::runtime_error("Unsupported table_name");
};
- res.emplace_back(PairObjectName(getObject(table_name, code), name));
+ const auto obj = getObject(table_name, code);
+ if (metadata::Identifier::canonicalizeName(obj->nameStr()) ==
+ canonicalizedSearchedName) {
+ foundExactMatch = true;
+ }
+
+ const auto objPtr = obj.get();
+ if (res.empty()) {
+ hashCodeFirstMatch = typeid(*objPtr).hash_code();
+ } else if (hashCodeFirstMatch != typeid(*objPtr).hash_code()) {
+ hashCodeFirstMatch = 0;
+ }
+
+ res.emplace_back(PairObjectName(obj, name));
if (limitResultCount > 0 && res.size() == limitResultCount) {
break;
}
}
+
+ // If we found a name that is an exact match, and all objects have the
+ // same type, and we are not in approximate mode, only keep the objet(s)
+ // with the exact name match.
+ if (foundExactMatch && hashCodeFirstMatch != 0 && !approximateMatch) {
+ std::list<PairObjectName> resTmp;
+ for (const auto &pair : res) {
+ if (metadata::Identifier::canonicalizeName(
+ pair.first->nameStr()) == canonicalizedSearchedName) {
+ resTmp.emplace_back(pair);
+ }
+ }
+ res = std::move(resTmp);
+ }
}
auto sortLambda = [](const PairObjectName &a, const PairObjectName &b) {
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index f4ec7740..8a42e7ee 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -70,7 +70,6 @@
// clang-format off
#include "proj.h"
#include "proj_internal.h"
-#include "proj_api.h"
// clang-format on
using namespace NS_PROJ::common;
@@ -140,6 +139,7 @@ struct WKTFormatter::Private {
bool primeMeridianInDegree_ = false;
bool use2019Keywords_ = false;
bool useESRIDialect_ = false;
+ bool allowEllipsoidalHeightAsVerticalCRS_ = false;
OutputAxisRule outputAxis_ = WKTFormatter::OutputAxisRule::YES;
};
Params params_{};
@@ -251,6 +251,8 @@ WKTFormatter::setOutputAxis(OutputAxisRule outputAxisIn) noexcept {
*
* The default is strict mode, in which case a FormattingException can be
* thrown.
+ * In non-strict mode, a Geographic 3D CRS can be for example exported as
+ * WKT1_GDAL with 3 axes, whereas this is normally not allowed.
*/
WKTFormatter &WKTFormatter::setStrict(bool strictIn) noexcept {
d->params_.strict_ = strictIn;
@@ -264,6 +266,28 @@ bool WKTFormatter::isStrict() const noexcept { return d->params_.strict_; }
// ---------------------------------------------------------------------------
+/** \brief Set whether the formatter should export, in WKT1, a Geographic or
+ * Projected 3D CRS as a compound CRS whose vertical part represents an
+ * ellipsoidal height.
+ */
+WKTFormatter &
+WKTFormatter::setAllowEllipsoidalHeightAsVerticalCRS(bool allow) noexcept {
+ d->params_.allowEllipsoidalHeightAsVerticalCRS_ = allow;
+ return *this;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Return whether the formatter should export, in WKT1, a Geographic or
+ * Projected 3D CRS as a compound CRS whose vertical part represents an
+ * ellipsoidal height.
+ */
+bool WKTFormatter::isAllowedEllipsoidalHeightAsVerticalCRS() const noexcept {
+ return d->params_.allowEllipsoidalHeightAsVerticalCRS_;
+}
+
+// ---------------------------------------------------------------------------
+
/** Returns the WKT string from the formatter. */
const std::string &WKTFormatter::toString() const {
if (d->indentLevel_ > 0 || d->level_ > 0) {
@@ -1979,14 +2003,80 @@ PrimeMeridianNNPtr WKTParser::Private::buildPrimeMeridian(
try {
double angleValue = asDouble(children[1]);
- // Correct for GDAL WKT1 departure
+ // Correct for GDAL WKT1 and WKT1-ESRI departure
if (name == "Paris" && std::fabs(angleValue - 2.33722917) < 1e-8 &&
- unit == UnitOfMeasure::GRAD) {
+ unit._isEquivalentTo(UnitOfMeasure::GRAD,
+ util::IComparable::Criterion::EQUIVALENT)) {
angleValue = 2.5969213;
+ } else {
+ static const struct {
+ const char *name;
+ int deg;
+ int min;
+ double sec;
+ } primeMeridiansDMS[] = {
+ {"Lisbon", -9, 7, 54.862}, {"Bogota", -74, 4, 51.3},
+ {"Madrid", -3, 41, 14.55}, {"Rome", 12, 27, 8.4},
+ {"Bern", 7, 26, 22.5}, {"Jakarta", 106, 48, 27.79},
+ {"Ferro", -17, 40, 0}, {"Brussels", 4, 22, 4.71},
+ {"Stockholm", 18, 3, 29.8}, {"Athens", 23, 42, 58.815},
+ {"Oslo", 10, 43, 22.5}, {"Paris RGS", 2, 20, 13.95},
+ {"Paris_RGS", 2, 20, 13.95}};
+
+ // Current epsg.org output may use the EPSG:9110 "sexagesimal DMS"
+ // unit and a DD.MMSSsss value, but this will likely be changed to
+ // use decimal degree.
+ // Or WKT1 may for example use the Paris RGS decimal degree value
+ // but with a GEOGCS with UNIT["Grad"]
+ for (const auto &pmDef : primeMeridiansDMS) {
+ if (name == pmDef.name) {
+ double dmsAsDecimalValue =
+ (pmDef.deg >= 0 ? 1 : -1) *
+ (std::abs(pmDef.deg) + pmDef.min / 100. +
+ pmDef.sec / 10000.);
+ double dmsAsDecimalDegreeValue =
+ (pmDef.deg >= 0 ? 1 : -1) *
+ (std::abs(pmDef.deg) + pmDef.min / 60. +
+ pmDef.sec / 3600.);
+ if (std::fabs(angleValue - dmsAsDecimalValue) < 1e-8 ||
+ std::fabs(angleValue - dmsAsDecimalDegreeValue) <
+ 1e-8) {
+ angleValue = dmsAsDecimalDegreeValue;
+ unit = UnitOfMeasure::DEGREE;
+ }
+ break;
+ }
+ }
+ }
+
+ auto &properties = buildProperties(node);
+ if (dbContext_ && esriStyle_) {
+ std::string outTableName;
+ std::string codeFromAlias;
+ std::string authNameFromAlias;
+ auto authFactory = AuthorityFactory::create(NN_NO_CHECK(dbContext_),
+ std::string());
+ auto officialName = authFactory->getOfficialNameFromAlias(
+ name, "prime_meridian", "ESRI", false, outTableName,
+ authNameFromAlias, codeFromAlias);
+ if (!officialName.empty()) {
+ properties.set(IdentifiedObject::NAME_KEY, officialName);
+ if (!authNameFromAlias.empty()) {
+ auto identifiers = ArrayOfBaseObject::create();
+ identifiers->add(Identifier::create(
+ codeFromAlias,
+ PropertyMap()
+ .set(Identifier::CODESPACE_KEY, authNameFromAlias)
+ .set(Identifier::AUTHORITY_KEY,
+ authNameFromAlias)));
+ properties.set(IdentifiedObject::IDENTIFIERS_KEY,
+ identifiers);
+ }
+ }
}
Angle angle(angleValue, unit);
- return PrimeMeridian::create(buildProperties(node), angle);
+ return PrimeMeridian::create(properties, angle);
} catch (const std::exception &e) {
throw buildRethrow(__FUNCTION__, e);
}
@@ -2098,9 +2188,15 @@ GeodeticReferenceFrameNNPtr WKTParser::Private::buildGeodeticReferenceFrame(
return false;
};
- if (name == "WGS_1984") {
+ // Remap GDAL WGS_1984 to EPSG v9 "World Geodetic System 1984" official
+ // name.
+ // Also remap EPSG v10 datum ensemble names to non-ensemble EPSG v9
+ if (name == "WGS_1984" || name == "World Geodetic System 1984 ensemble") {
properties.set(IdentifiedObject::NAME_KEY,
GeodeticReferenceFrame::EPSG_6326->nameStr());
+ } else if (name == "European Terrestrial Reference System 1989 ensemble") {
+ properties.set(IdentifiedObject::NAME_KEY,
+ "European Terrestrial Reference System 1989");
} else if (starts_with(name, "D_")) {
esriStyle_ = true;
const char *tableNameForAlias = nullptr;
@@ -2110,6 +2206,10 @@ GeodeticReferenceFrameNNPtr WKTParser::Private::buildGeodeticReferenceFrame(
name = "World Geodetic System 1984";
authNameFromAlias = Identifier::EPSG;
codeFromAlias = "6326";
+ } else if (name == "D_ETRS_1989") {
+ name = "European Terrestrial Reference System 1989";
+ authNameFromAlias = Identifier::EPSG;
+ codeFromAlias = "6258";
} else {
tableNameForAlias = "geodetic_datum";
}
@@ -2734,6 +2834,9 @@ WKTParser::Private::buildGeodeticCRS(const WKTNodeNNPtr &node) {
throw ParsingException("Missing DATUM or ENSEMBLE node");
}
+ // Do that now so that esriStyle_ can be set before buildPrimeMeridian()
+ auto props = buildProperties(node);
+
auto &dynamicNode = nodeP->lookForChild(WKTConstants::DYNAMIC);
auto &csNode = nodeP->lookForChild(WKTConstants::CS_);
@@ -2771,7 +2874,6 @@ WKTParser::Private::buildGeodeticCRS(const WKTNodeNNPtr &node) {
angularUnit = primeMeridian->longitude().unit();
}
- auto props = buildProperties(node);
addExtensionProj4ToProp(nodeP, props);
// No explicit AXIS node ? (WKT1)
@@ -2790,6 +2892,32 @@ WKTParser::Private::buildGeodeticCRS(const WKTNodeNNPtr &node) {
.as_nullable()
: nullptr;
auto cs = buildCS(csNode, node, angularUnit);
+
+ // If there's no CS[] node, typically for a BASEGEODCRS of a projected CRS,
+ // in a few rare cases, this might be a Geocentric CRS, and thus a
+ // Cartesian CS, and not the ellipsoidalCS we assumed above. The only way
+ // to figure that is to resolve the CRS from its code...
+ if (isNull(csNode) && dbContext_ &&
+ ci_equal(nodeName, WKTConstants::BASEGEODCRS)) {
+ const auto &nodeChildren = nodeP->children();
+ for (const auto &subNode : nodeChildren) {
+ const auto &subNodeName(subNode->GP()->value());
+ if (ci_equal(subNodeName, WKTConstants::ID) ||
+ ci_equal(subNodeName, WKTConstants::AUTHORITY)) {
+ auto id = buildId(subNode, true, false);
+ if (id) {
+ try {
+ auto authFactory = AuthorityFactory::create(
+ NN_NO_CHECK(dbContext_), *id->codeSpace());
+ auto dbCRS = authFactory->createGeodeticCRS(id->code());
+ cs = dbCRS->coordinateSystem();
+ } catch (const util::Exception &) {
+ }
+ }
+ }
+ }
+ }
+
auto ellipsoidalCS = nn_dynamic_pointer_cast<EllipsoidalCS>(cs);
if (ellipsoidalCS) {
if (ci_equal(nodeName, WKTConstants::GEOCCS)) {
@@ -2940,7 +3068,8 @@ UnitOfMeasure WKTParser::Private::guessUnitForParameter(
const UnitOfMeasure &defaultAngularUnit) {
UnitOfMeasure unit;
// scale must be first because of 'Scale factor on pseudo standard parallel'
- if (ci_find(paramName, "scale") != std::string::npos) {
+ if (ci_find(paramName, "scale") != std::string::npos ||
+ ci_find(paramName, "scaling factor") != std::string::npos) {
unit = UnitOfMeasure::SCALE_UNITY;
} else if (ci_find(paramName, "latitude") != std::string::npos ||
ci_find(paramName, "longitude") != std::string::npos ||
@@ -3872,8 +4001,16 @@ WKTParser::Private::buildProjectedCRS(const WKTNodeNNPtr &node) {
return createPseudoMercator(props, NN_NO_CHECK(cartesianCS));
}
- auto linearUnit = buildUnitInSubNode(node, UnitOfMeasure::Type::LINEAR);
- auto angularUnit = baseGeodCRS->coordinateSystem()->axisList()[0]->unit();
+ // For WKT2, if there is no explicit parameter unit, use metre for linear
+ // units and degree for angular units
+ auto linearUnit =
+ !isNull(conversionNode)
+ ? UnitOfMeasure::METRE
+ : buildUnitInSubNode(node, UnitOfMeasure::Type::LINEAR);
+ auto angularUnit =
+ !isNull(conversionNode)
+ ? UnitOfMeasure::DEGREE
+ : baseGeodCRS->coordinateSystem()->axisList()[0]->unit();
auto conversion =
!isNull(conversionNode)
@@ -4941,6 +5078,10 @@ class JSONParser {
TransformationNNPtr buildTransformation(const json &j);
ConcatenatedOperationNNPtr buildConcatenatedOperation(const json &j);
+ void buildGeodeticDatumOrDatumEnsemble(const json &j,
+ GeodeticReferenceFramePtr &datum,
+ DatumEnsemblePtr &datumEnsemble);
+
static util::optional<std::string> getAnchor(const json &j) {
util::optional<std::string> anchor;
if (j.contains("anchor")) {
@@ -5400,9 +5541,9 @@ BaseObjectNNPtr JSONParser::create(const json &j)
// ---------------------------------------------------------------------------
-GeographicCRSNNPtr JSONParser::buildGeographicCRS(const json &j) {
- GeodeticReferenceFramePtr datum;
- DatumEnsemblePtr datumEnsemble;
+void JSONParser::buildGeodeticDatumOrDatumEnsemble(
+ const json &j, GeodeticReferenceFramePtr &datum,
+ DatumEnsemblePtr &datumEnsemble) {
if (j.contains("datum")) {
auto datumJ = getObject(j, "datum");
datum = util::nn_dynamic_pointer_cast<GeodeticReferenceFrame>(
@@ -5415,6 +5556,14 @@ GeographicCRSNNPtr JSONParser::buildGeographicCRS(const json &j) {
datumEnsemble =
buildDatumEnsemble(getObject(j, "datum_ensemble")).as_nullable();
}
+}
+
+// ---------------------------------------------------------------------------
+
+GeographicCRSNNPtr JSONParser::buildGeographicCRS(const json &j) {
+ GeodeticReferenceFramePtr datum;
+ DatumEnsemblePtr datumEnsemble;
+ buildGeodeticDatumOrDatumEnsemble(j, datum, datumEnsemble);
auto csJ = getObject(j, "coordinate_system");
auto ellipsoidalCS =
util::nn_dynamic_pointer_cast<EllipsoidalCS>(buildCS(csJ));
@@ -5428,12 +5577,9 @@ GeographicCRSNNPtr JSONParser::buildGeographicCRS(const json &j) {
// ---------------------------------------------------------------------------
GeodeticCRSNNPtr JSONParser::buildGeodeticCRS(const json &j) {
- auto datumJ = getObject(j, "datum");
- if (getType(datumJ) != "GeodeticReferenceFrame") {
- throw ParsingException("Unsupported type for datum.");
- }
- auto datum = buildGeodeticReferenceFrame(datumJ);
+ GeodeticReferenceFramePtr datum;
DatumEnsemblePtr datumEnsemble;
+ buildGeodeticDatumOrDatumEnsemble(j, datum, datumEnsemble);
auto csJ = getObject(j, "coordinate_system");
auto cs = buildCS(csJ);
auto props = buildProperties(j);
@@ -5468,7 +5614,13 @@ GeodeticCRSNNPtr JSONParser::buildGeodeticCRS(const json &j) {
// ---------------------------------------------------------------------------
ProjectedCRSNNPtr JSONParser::buildProjectedCRS(const json &j) {
- auto baseCRS = buildGeographicCRS(getObject(j, "base_crs"));
+ auto jBaseCRS = getObject(j, "base_crs");
+ auto jBaseCS = getObject(jBaseCRS, "coordinate_system");
+ auto baseCS = buildCS(jBaseCS);
+ auto baseCRS = dynamic_cast<EllipsoidalCS *>(baseCS.get()) != nullptr
+ ? util::nn_static_pointer_cast<GeodeticCRS>(
+ buildGeographicCRS(jBaseCRS))
+ : buildGeodeticCRS(jBaseCRS);
auto csJ = getObject(j, "coordinate_system");
auto cartesianCS = util::nn_dynamic_pointer_cast<CartesianCS>(buildCS(csJ));
if (!cartesianCS) {
@@ -6263,6 +6415,9 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text,
if (type == "datum") {
return factory->createDatum(code);
}
+ if (type == "ensemble") {
+ return factory->createDatumEnsemble(code);
+ }
if (type == "ellipsoid") {
return factory->createEllipsoid(code);
}
@@ -6381,6 +6536,8 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text,
AuthorityFactory::ObjectType::
DATUM,
AuthorityFactory::ObjectType::
+ DATUM_ENSEMBLE,
+ AuthorityFactory::ObjectType::
COORDINATE_OPERATION},
goOn);
} catch (const std::exception &) {
@@ -9460,8 +9617,8 @@ CRSNNPtr PROJStringParser::Private::buildProjectedCRS(
std::string methodName = "PROJ " + step.name;
for (const auto &param : step.paramValues) {
if (is_in_stringlist(param.key,
- "wktext,no_defs,datum,ellps,a,b,R,towgs84,"
- "nadgrids,geoidgrids,"
+ "wktext,no_defs,datum,ellps,a,b,R,f,rf,"
+ "towgs84,nadgrids,geoidgrids,"
"units,to_meter,vunits,vto_meter,type")) {
continue;
}
@@ -9761,7 +9918,7 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
paralist *list = pj_expand_init(ctx, init);
ctx->projStringParserCreateFromPROJStringRecursionCounter--;
if (!list) {
- pj_dealloc(init);
+ free(init);
throw ParsingException("cannot expand " + projString);
}
std::string expanded;
@@ -9784,7 +9941,7 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
}
auto n = t->next;
- pj_dealloc(t);
+ free(t);
t = n;
}
for (const auto &pair : d->steps_[0].paramValues) {
diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake
index 67bc1f4e..3a4880c6 100644
--- a/src/lib_proj.cmake
+++ b/src/lib_proj.cmake
@@ -173,6 +173,7 @@ set(SRC_LIBPROJ_CONVERSIONS
conversions/geoc.cpp
conversions/geocent.cpp
conversions/noop.cpp
+ conversions/topocentric.cpp
conversions/set.cpp
conversions/unitconvert.cpp
)
@@ -217,9 +218,7 @@ set(SRC_LIBPROJ_CORE
dmstor.cpp
ell_set.cpp
ellps.cpp
- errno.cpp
factors.cpp
- fileapi.cpp
fwd.cpp
gauss.cpp
generic_inverse.cpp
@@ -246,10 +245,8 @@ set(SRC_LIBPROJ_CORE
rtodms.cpp
strerrno.cpp
strtod.cpp
- transform.cpp
tsfn.cpp
units.cpp
- utils.cpp
wkt1_generated_parser.c
wkt1_generated_parser.h
wkt1_parser.cpp
@@ -275,7 +272,6 @@ set(SRC_LIBPROJ_CORE
)
set(HEADERS_LIBPROJ
- proj_api.h
proj.h
proj_experimental.h
proj_constants.h
diff --git a/src/log.cpp b/src/log.cpp
index 3cc10cfd..c343e65b 100644
--- a/src/log.cpp
+++ b/src/log.cpp
@@ -48,9 +48,9 @@ void pj_stderr_logger( void *app_data, int level, const char *msg )
/************************************************************************/
/* pj_vlog() */
/************************************************************************/
-void pj_vlog( projCtx ctx, int level, const char *fmt, va_list args );
+void pj_vlog( PJ_CONTEXT *ctx, int level, const char *fmt, va_list args );
/* Workhorse for the log functions - relates to pj_log as vsprintf relates to sprintf */
-void pj_vlog( projCtx ctx, int level, const char *fmt, va_list args )
+void pj_vlog( PJ_CONTEXT *ctx, int level, const char *fmt, va_list args )
{
char *msg_buf;
@@ -84,7 +84,7 @@ void pj_vlog( projCtx ctx, int level, const char *fmt, va_list args )
/* pj_log() */
/************************************************************************/
-void pj_log( projCtx ctx, int level, const char *fmt, ... )
+void pj_log( PJ_CONTEXT *ctx, int level, const char *fmt, ... )
{
va_list args;
diff --git a/src/malloc.cpp b/src/malloc.cpp
index c8de6630..6b7fbf26 100644
--- a/src/malloc.cpp
+++ b/src/malloc.cpp
@@ -53,99 +53,13 @@
using namespace NS_PROJ;
-/**********************************************************************/
-void *pj_malloc(size_t size) {
-/***********************************************************************
-Currently, pj_malloc is a hack to solve an errno problem.
-The problem is described in more details at
-https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=86420.
-It seems, that pj_init and similar functions incorrectly
-(under debian/glibs-2.3.2) assume that pj_malloc resets
-errno after success. pj_malloc tries to mimic this.
-
-NOTE (2017-09-29): The problem described at the bugzilla page
-referred to above, is most likely a case of someone not
-understanding the proper usage of errno. We should review
-whether "the problem is actually a problem" in PROJ.4 code.
-
-Library specific allocators can be useful, and improve
-interoperability, if properly used. That is, by making them
-run/initialization time switchable, somewhat like the file i/o
-interface.
-
-But as things stand, we are more likely to get benefit
-from reviewing the code for proper errno usage, which is hard,
-due to the presence of context local and global pj_errnos.
-
-Probably, these were introduced in order to support incomplete
-implementations of thread local errnos at an early phase of the
-implementation of multithreading support in PROJ.4).
-
-It is likely too late to get rid of contexts, but we can still
-benefit from a better usage of errno.
-***********************************************************************/
- int old_errno = errno;
- void *res = malloc(size);
- if ( res && !old_errno )
- errno = 0;
- return res;
-}
-
-
-/**********************************************************************/
-void *pj_calloc (size_t n, size_t size) {
-/***********************************************************************
-pj_calloc is the pj-equivalent of calloc().
-
-It allocates space for an array of <n> elements of size <size>.
-The array is initialized to zeros.
-***********************************************************************/
- void *res = pj_malloc (n*size);
- if (nullptr==res)
- return nullptr;
- memset (res, 0, n*size);
- return res;
-}
-
-
-/**********************************************************************/
-void pj_dalloc(void *ptr) {
-/**********************************************************************/
- free(ptr);
-}
-
-
-/**********************************************************************/
-void *pj_dealloc (void *ptr) {
-/***********************************************************************
-pj_dealloc supports the common use case of "clean up and return a null
-pointer" to signal an error in a multi level allocation:
-
- struct foo { int bar; int *baz; };
-
- struct foo *p = pj_calloc (1, sizeof (struct foo));
- if (0==p)
- return 0;
-
- p->baz = pj_calloc (10, sizeof(int));
- if (0==p->baz)
- return pj_dealloc (p); // clean up + signal error by 0-return
-
- return p; // success
-
-***********************************************************************/
- if (nullptr==ptr)
- return nullptr;
- pj_dalloc (ptr);
- return nullptr;
-}
/**********************************************************************/
char *pj_strdup(const char *str)
/**********************************************************************/
{
size_t len = strlen(str) + 1;
- char *dup = static_cast<char*>(pj_malloc(len));
+ char *dup = static_cast<char*>(malloc(len));
if (dup)
memcpy(dup, str, len);
return dup;
@@ -153,7 +67,7 @@ char *pj_strdup(const char *str)
/*****************************************************************************/
-void *pj_dealloc_params (PJ_CONTEXT *ctx, paralist *start, int errlev) {
+void *free_params (PJ_CONTEXT *ctx, paralist *start, int errlev) {
/*****************************************************************************
Companion to pj_default_destructor (below). Deallocates a linked list
of "+proj=xxx" initialization parameters.
@@ -164,9 +78,9 @@ void *pj_dealloc_params (PJ_CONTEXT *ctx, paralist *start, int errlev) {
paralist *t, *n;
for (t = start; t; t = n) {
n = t->next;
- pj_dealloc(t);
+ free(t);
}
- pj_ctx_set_errno (ctx, errlev);
+ proj_context_errno_set (ctx, errlev);
return (void *) nullptr;
}
@@ -174,7 +88,7 @@ void *pj_dealloc_params (PJ_CONTEXT *ctx, paralist *start, int errlev) {
/************************************************************************/
-/* pj_free() */
+/* proj_destroy() */
/* */
/* This is the application callable entry point for destroying */
/* a projection definition. It does work generic to all */
@@ -183,15 +97,16 @@ void *pj_dealloc_params (PJ_CONTEXT *ctx, paralist *start, int errlev) {
/* In most cases P->destructor()==pj_default_destructor. */
/************************************************************************/
-void pj_free(PJ *P) {
+PJ *proj_destroy(PJ *P) {
if (nullptr==P || !P->destructor)
- return;
+ return nullptr;
/* free projection parameters - all the hard work is done by */
/* pj_default_destructor, which is supposed */
/* to be called as the last step of the local destructor */
/* pointed to by P->destructor. In most cases, */
/* pj_default_destructor actually *is* what is pointed to */
P->destructor (P, proj_errno(P));
+ return nullptr;
}
/*****************************************************************************/
@@ -218,42 +133,42 @@ PJ *pj_default_destructor (PJ *P, int errlev) { /* Destructor */
/* Note that both, in the multithreaded case, may then contain undefined */
/* values. This is expected behavior. For MT have one ctx per thread */
if (0!=errlev)
- pj_ctx_set_errno (pj_get_ctx(P), errlev);
+ proj_context_errno_set (pj_get_ctx(P), errlev);
if (nullptr==P)
return nullptr;
- pj_dealloc(P->def_size);
- pj_dealloc(P->def_shape);
- pj_dealloc(P->def_spherification);
- pj_dealloc(P->def_ellps);
+ free(P->def_size);
+ free(P->def_shape);
+ free(P->def_spherification);
+ free(P->def_ellps);
delete static_cast<ListOfHGrids*>(P->hgrids_legacy);
delete static_cast<ListOfVGrids*>(P->vgrids_legacy);
- /* We used to call pj_dalloc( P->catalog ), but this will leak */
+ /* We used to call free( P->catalog ), but this will leak */
/* memory. The safe way to clear catalog and grid is to call */
- /* pj_gc_unloadall(pj_get_default_ctx()); and pj_deallocate_grids(); */
+ /* pj_gc_unloadall(pj_get_default_ctx()); and freeate_grids(); */
/* TODO: we should probably have a public pj_cleanup() method to do all */
/* that */
/* free the interface to Charles Karney's geodesic library */
- pj_dealloc( P->geod );
+ free( P->geod );
/* free parameter list elements */
- pj_dealloc_params (pj_get_ctx(P), P->params, errlev);
- pj_dealloc (P->def_full);
+ free_params (pj_get_ctx(P), P->params, errlev);
+ free (P->def_full);
/* free the cs2cs emulation elements */
- pj_free (P->axisswap);
- pj_free (P->helmert);
- pj_free (P->cart);
- pj_free (P->cart_wgs84);
- pj_free (P->hgridshift);
- pj_free (P->vgridshift);
-
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque));
+ proj_destroy (P->axisswap);
+ proj_destroy (P->helmert);
+ proj_destroy (P->cart);
+ proj_destroy (P->cart_wgs84);
+ proj_destroy (P->hgridshift);
+ proj_destroy (P->vgridshift);
+
+ free (static_cast<struct pj_opaque*>(P->opaque));
delete P;
return nullptr;
}
@@ -262,7 +177,6 @@ PJ *pj_default_destructor (PJ *P, int errlev) { /* Destructor */
void proj_cleanup() {
/*****************************************************************************/
pj_clear_initcache();
- pj_deallocate_grids();
FileManager::clearMemoryCache();
pj_clear_hgridshift_knowngrids_cache();
pj_clear_vgridshift_knowngrids_cache();
diff --git a/src/mlfn.cpp b/src/mlfn.cpp
index 80f9163b..763d83ee 100644
--- a/src/mlfn.cpp
+++ b/src/mlfn.cpp
@@ -26,7 +26,7 @@
double *pj_enfn(double es) {
double t, *en;
- en = (double *) pj_malloc(EN_SIZE * sizeof (double));
+ en = (double *) malloc(EN_SIZE * sizeof (double));
if (nullptr==en)
return nullptr;
@@ -45,7 +45,7 @@ pj_mlfn(double phi, double sphi, double cphi, const double *en) {
}
double
-pj_inv_mlfn(projCtx ctx, double arg, double es, const double *en) {
+pj_inv_mlfn(PJ_CONTEXT *ctx, double arg, double es, const double *en) {
double sinphi_ignored;
double cosphi_ignored;
return inline_pj_inv_mlfn(ctx, arg, es, en, &sinphi_ignored, &cosphi_ignored);
diff --git a/src/mlfn.hpp b/src/mlfn.hpp
index 26a2959f..228c65a4 100644
--- a/src/mlfn.hpp
+++ b/src/mlfn.hpp
@@ -15,7 +15,7 @@ inline static double inline_pj_mlfn(double phi, double sphi, double cphi, const
}
inline static double
-inline_pj_inv_mlfn(projCtx ctx, double arg, double es, const double *en,
+inline_pj_inv_mlfn(PJ_CONTEXT *ctx, double arg, double es, const double *en,
double* sinphi, double* cosphi) {
const double k = 1./(1.-es);
constexpr double INV_MLFN_EPS = 1e-11;
@@ -66,7 +66,7 @@ inline_pj_inv_mlfn(projCtx ctx, double arg, double es, const double *en,
}
*sinphi = s;
*cosphi = c;
- pj_ctx_set_errno( ctx, PJD_ERR_NON_CONV_INV_MERI_DIST );
+ proj_context_errno_set( ctx, PJD_ERR_NON_CONV_INV_MERI_DIST );
return phi;
}
diff --git a/src/mutex.cpp b/src/mutex.cpp
index da415e55..b1a23ccd 100644
--- a/src/mutex.cpp
+++ b/src/mutex.cpp
@@ -33,13 +33,8 @@
#include "proj.h"
#ifndef _WIN32
#include "proj_config.h"
-#include "proj_internal.h"
-#else
-#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#endif
-#include "proj_api.h"
#endif
+#include "proj_internal.h"
/* on win32 we always use win32 mutexes, even if pthreads are available */
#if defined(_WIN32) && !defined(MUTEX_stub)
@@ -184,7 +179,7 @@ void pj_cleanup_lock()
#include <windows.h>
-static HANDLE mutex_lock = NULL;
+static HANDLE mutex_lock = nullptr;
#if _WIN32_WINNT >= 0x0600
@@ -199,7 +194,7 @@ static BOOL CALLBACK pj_create_lock(PINIT_ONCE InitOnce,
(void)InitOnce;
(void)Parameter;
(void)Context;
- mutex_lock = CreateMutex( NULL, FALSE, NULL );
+ mutex_lock = CreateMutex( nullptr, FALSE, nullptr );
return TRUE;
}
#endif
@@ -213,10 +208,10 @@ static void pj_init_lock()
{
#if _WIN32_WINNT >= 0x0600
static INIT_ONCE sInitOnce = INIT_ONCE_STATIC_INIT;
- InitOnceExecuteOnce( &sInitOnce, pj_create_lock, NULL, NULL );
+ InitOnceExecuteOnce( &sInitOnce, pj_create_lock, nullptr, nullptr );
#else
- if( mutex_lock == NULL )
- mutex_lock = CreateMutex( NULL, FALSE, NULL );
+ if( mutex_lock == nullptr )
+ mutex_lock = CreateMutex( nullptr, FALSE, nullptr );
#endif
}
@@ -228,7 +223,7 @@ static void pj_init_lock()
void pj_acquire_lock()
{
- if( mutex_lock == NULL )
+ if( mutex_lock == nullptr )
pj_init_lock();
WaitForSingleObject( mutex_lock, INFINITE );
@@ -242,7 +237,7 @@ void pj_acquire_lock()
void pj_release_lock()
{
- if( mutex_lock == NULL )
+ if( mutex_lock == nullptr )
pj_init_lock();
else
ReleaseMutex( mutex_lock );
@@ -253,10 +248,10 @@ void pj_release_lock()
/************************************************************************/
void pj_cleanup_lock()
{
- if( mutex_lock != NULL )
+ if( mutex_lock != nullptr )
{
CloseHandle( mutex_lock );
- mutex_lock = NULL;
+ mutex_lock = nullptr;
}
}
diff --git a/src/networkfilemanager.cpp b/src/networkfilemanager.cpp
index f6521ed2..9edffaad 100644
--- a/src/networkfilemanager.cpp
+++ b/src/networkfilemanager.cpp
@@ -1315,7 +1315,7 @@ std::unique_ptr<File> NetworkFile::open(PJ_CONTEXT *ctx, const char *filename) {
errorBuffer.resize(strlen(errorBuffer.data()));
pj_log(ctx, PJ_LOG_ERROR, "Cannot open %s: %s", filename,
errorBuffer.c_str());
- pj_ctx_set_errno(ctx, PJD_ERR_NETWORK_ERROR);
+ proj_context_errno_set(ctx, PJD_ERR_NETWORK_ERROR);
}
bool ok = false;
@@ -1404,7 +1404,7 @@ size_t NetworkFile::read(void *buffer, size_t sizeBytes) {
&nRead, errorBuffer.size(), &errorBuffer[0],
m_ctx->networking.user_data);
if (!m_handle) {
- pj_ctx_set_errno(m_ctx, PJD_ERR_NETWORK_ERROR);
+ proj_context_errno_set(m_ctx, PJD_ERR_NETWORK_ERROR);
return 0;
}
} else {
@@ -1420,7 +1420,7 @@ size_t NetworkFile::read(void *buffer, size_t sizeBytes) {
pj_log(m_ctx, PJ_LOG_ERROR, "Cannot read in %s: %s",
m_url.c_str(), errorBuffer.c_str());
}
- pj_ctx_set_errno(m_ctx, PJD_ERR_NETWORK_ERROR);
+ proj_context_errno_set(m_ctx, PJD_ERR_NETWORK_ERROR);
return 0;
}
diff --git a/src/param.cpp b/src/param.cpp
index 289faca3..28d6bc3e 100644
--- a/src/param.cpp
+++ b/src/param.cpp
@@ -38,7 +38,7 @@ static void unquote_string(char* param_str) {
paralist *pj_mkparam(const char *str) {
paralist *newitem;
- if((newitem = (paralist *)pj_malloc(sizeof(paralist) + strlen(str))) != nullptr) {
+ if((newitem = (paralist *)malloc(sizeof(paralist) + strlen(str))) != nullptr) {
newitem->used = 0;
newitem->next = nullptr;
if (*str == '+')
@@ -82,7 +82,7 @@ paralist *pj_mkparam_ws (const char *str, const char **next_str) {
*next_str = str + len;
/* Use calloc to automagically 0-terminate the copy */
- newitem = (paralist *) pj_calloc (1, sizeof(paralist) + len + 1);
+ newitem = (paralist *) calloc (1, sizeof(paralist) + len + 1);
if (nullptr==newitem)
return nullptr;
memcpy(newitem->param, str, len);
@@ -151,7 +151,7 @@ paralist *pj_param_exists (paralist *list, const char *parameter) {
/* */
/************************************************************************/
-PROJVALUE pj_param (projCtx ctx, paralist *pl, const char *opt) {
+PROJVALUE pj_param (PJ_CONTEXT *ctx, paralist *pl, const char *opt) {
int type;
unsigned l;
@@ -220,7 +220,7 @@ PROJVALUE pj_param (projCtx ctx, paralist *pl, const char *opt) {
value.i = 1;
break;
default:
- pj_ctx_set_errno (ctx, PJD_ERR_INVALID_BOOLEAN_PARAM);
+ proj_context_errno_set (ctx, PJD_ERR_INVALID_BOOLEAN_PARAM);
value.i = 0;
break;
}
diff --git a/src/phi2.cpp b/src/phi2.cpp
index b81456b0..2f258e47 100644
--- a/src/phi2.cpp
+++ b/src/phi2.cpp
@@ -1,68 +1,134 @@
/* Determine latitude angle phi-2. */
#include <math.h>
+#include <limits>
+#include <algorithm>
#include "proj.h"
#include "proj_internal.h"
-static const double TOL = 1.0e-10;
-static const int N_ITER = 15;
+double pj_sinhpsi2tanphi(PJ_CONTEXT *ctx, const double taup, const double e) {
+ /****************************************************************************
+ * Convert tau' = sinh(psi) = tan(chi) to tau = tan(phi). The code is taken
+ * from GeographicLib::Math::tauf(taup, e).
+ *
+ * Here
+ * phi = geographic latitude (radians)
+ * psi is the isometric latitude
+ * psi = asinh(tan(phi)) - e * atanh(e * sin(phi))
+ * = asinh(tan(chi))
+ * chi is the conformal latitude
+ *
+ * The representation of latitudes via their tangents, tan(phi) and tan(chi),
+ * maintains full *relative* accuracy close to latitude = 0 and +/- pi/2.
+ * This is sometimes important, e.g., to compute the scale of the transverse
+ * Mercator projection which involves cos(phi)/cos(chi) tan(phi)
+ *
+ * From Karney (2011), Eq. 7,
+ *
+ * tau' = sinh(psi) = sinh(asinh(tan(phi)) - e * atanh(e * sin(phi)))
+ * = tan(phi) * cosh(e * atanh(e * sin(phi))) -
+ * sec(phi) * sinh(e * atanh(e * sin(phi)))
+ * = tau * sqrt(1 + sigma^2) - sqrt(1 + tau^2) * sigma
+ * where
+ * sigma = sinh(e * atanh( e * tau / sqrt(1 + tau^2) ))
+ *
+ * For e small,
+ *
+ * tau' = (1 - e^2) * tau
+ *
+ * The relation tau'(tau) can therefore by reliably inverted by Newton's
+ * method with
+ *
+ * tau = tau' / (1 - e^2)
+ *
+ * as an initial guess. Newton's method requires dtau'/dtau. Noting that
+ *
+ * dsigma/dtau = e^2 * sqrt(1 + sigma^2) /
+ * (sqrt(1 + tau^2) * (1 + (1 - e^2) * tau^2))
+ * d(sqrt(1 + tau^2))/dtau = tau / sqrt(1 + tau^2)
+ *
+ * we have
+ *
+ * dtau'/dtau = (1 - e^2) * sqrt(1 + tau'^2) * sqrt(1 + tau^2) /
+ * (1 + (1 - e^2) * tau^2)
+ *
+ * This works fine unless tau^2 and tau'^2 overflows. This may be partially
+ * cured by writing, e.g., sqrt(1 + tau^2) as hypot(1, tau). However, nan
+ * will still be generated with tau' = inf, since (inf - inf) will appear in
+ * the Newton iteration.
+ *
+ * If we note that for sufficiently large |tau|, i.e., |tau| >= 2/sqrt(eps),
+ * sqrt(1 + tau^2) = |tau| and
+ *
+ * tau' = exp(- e * atanh(e)) * tau
+ *
+ * So
+ *
+ * tau = exp(e * atanh(e)) * tau'
+ *
+ * can be returned unless |tau| >= 2/sqrt(eps); this then avoids overflow
+ * problems for large tau' and returns the correct result for tau' = +/-inf
+ * and nan.
+ *
+ * Newton's method usually take 2 iterations to converge to double precision
+ * accuracy (for WGS84 flattening). However only 1 iteration is needed for
+ * |chi| < 3.35 deg. In addition, only 1 iteration is needed for |chi| >
+ * 89.18 deg (tau' > 70), if tau = exp(e * atanh(e)) * tau' is used as the
+ * starting guess.
+ ****************************************************************************/
-/*****************************************************************************/
-double pj_phi2(projCtx ctx, const double ts0, const double e) {
-/******************************************************************************
-Determine latitude angle phi-2.
-Inputs:
- ts = exp(-psi) where psi is the isometric latitude (dimensionless)
- e = eccentricity of the ellipsoid (dimensionless)
-Output:
- phi = geographic latitude (radians)
-Here isometric latitude is defined by
- psi = log( tan(pi/4 + phi/2) *
- ( (1 - e*sin(phi)) / (1 + e*sin(phi)) )^(e/2) )
- = asinh(tan(phi)) - e * atanh(e * sin(phi))
-This routine inverts this relation using the iterative scheme given
-by Snyder (1987), Eqs. (7-9) - (7-11)
-*******************************************************************************/
- const double eccnth = .5 * e;
- double ts = ts0;
-#ifdef no_longer_used_original_convergence_on_exact_dphi
- double Phi = M_HALFPI - 2. * atan(ts);
-#endif
- int i = N_ITER;
+ constexpr int numit = 5;
+ // min iterations = 1, max iterations = 2; mean = 1.954
+ static const double rooteps = sqrt(std::numeric_limits<double>::epsilon());
+ static const double tol = rooteps / 10; // the criterion for Newton's method
+ static const double tmax = 2 / rooteps; // threshold for large arg limit exact
+ const double e2m = 1 - e * e;
+ const double stol = tol * std::max(1.0, fabs(taup));
+ // The initial guess. 70 corresponds to chi = 89.18 deg (see above)
+ double tau = fabs(taup) > 70 ? taup * exp(e * atanh(e)) : taup / e2m;
+ if (!(fabs(tau) < tmax)) // handles +/-inf and nan and e = 1
+ return tau;
+ // If we need to deal with e > 1, then we could include:
+ // if (e2m < 0) return std::numeric_limits<double>::quiet_NaN();
+ int i = numit;
+ for (; i; --i) {
+ double tau1 = sqrt(1 + tau * tau);
+ double sig = sinh( e * atanh(e * tau / tau1) );
+ double taupa = sqrt(1 + sig * sig) * tau - sig * tau1;
+ double dtau = ( (taup - taupa) * (1 + e2m * (tau * tau)) /
+ (e2m * tau1 * sqrt(1 + taupa * taupa)) );
+ tau += dtau;
+ if (!(fabs(dtau) >= stol)) // backwards test to allow nans to succeed.
+ break;
+ }
+ if (i == 0)
+ proj_context_errno_set(ctx, PJD_ERR_NON_CONV_SINHPSI2TANPHI);
+ return tau;
+}
- for(;;) {
- /*
- * sin(Phi) = sin(PI/2 - 2* atan(ts))
- * = cos(2*atan(ts))
- * = 2*cos^2(atan(ts)) - 1
- * = 2 / (1 + ts^2) - 1
- * = (1 - ts^2) / (1 + ts^2)
- */
- const double sinPhi = (1 - ts * ts) / (1 + ts * ts);
- const double con = e * sinPhi;
- double old_ts = ts;
- ts = ts0 * pow((1. - con) / (1. + con), eccnth);
-#ifdef no_longer_used_original_convergence_on_exact_dphi
- /* The convergence criterion is nominally on exact dphi */
- const double newPhi = M_HALFPI - 2. * atan(ts);
- const double dphi = newPhi - Phi;
- Phi = newPhi;
-#else
- /* If we don't immediately update Phi from this, we can
- * change the conversion criterion to save us computing atan() at each step.
- * Particularly we can observe that:
- * |atan(ts) - atan(old_ts)| <= |ts - old_ts|
- * So if |ts - old_ts| matches our convergence criterion, we're good.
- */
- const double dphi = 2 * (ts - old_ts);
-#endif
- if (fabs(dphi) > TOL && --i) {
- continue;
- }
- break;
- }
- if (i <= 0)
- pj_ctx_set_errno(ctx, PJD_ERR_NON_CON_INV_PHI2);
- return M_HALFPI - 2. * atan(ts);
+/*****************************************************************************/
+double pj_phi2(PJ_CONTEXT *ctx, const double ts0, const double e) {
+ /****************************************************************************
+ * Determine latitude angle phi-2.
+ * Inputs:
+ * ts = exp(-psi) where psi is the isometric latitude (dimensionless)
+ * this variable is defined in Snyder (1987), Eq. (7-10)
+ * e = eccentricity of the ellipsoid (dimensionless)
+ * Output:
+ * phi = geographic latitude (radians)
+ * Here isometric latitude is defined by
+ * psi = log( tan(pi/4 + phi/2) *
+ * ( (1 - e*sin(phi)) / (1 + e*sin(phi)) )^(e/2) )
+ * = asinh(tan(phi)) - e * atanh(e * sin(phi))
+ * = asinh(tan(chi))
+ * chi = conformal latitude
+ *
+ * This routine converts t = exp(-psi) to
+ *
+ * tau' = tan(chi) = sinh(psi) = (1/t - t)/2
+ *
+ * returns atan(sinpsi2tanphi(tau'))
+ ***************************************************************************/
+ return atan(pj_sinhpsi2tanphi(ctx, (1/ts0 - ts0) / 2, e));
}
diff --git a/src/pipeline.cpp b/src/pipeline.cpp
index 80ee0397..e9d11604 100644
--- a/src/pipeline.cpp
+++ b/src/pipeline.cpp
@@ -294,8 +294,8 @@ static PJ *destructor (PJ *P, int errlev) {
auto pipeline = static_cast<struct Pipeline*>(P->opaque);
- pj_dealloc (pipeline->argv);
- pj_dealloc (pipeline->current_argv);
+ free (pipeline->argv);
+ free (pipeline->current_argv);
delete pipeline;
P->opaque = nullptr;
@@ -321,7 +321,7 @@ static const char *argv_sentinel = "step";
static char **argv_params (paralist *params, size_t argc) {
char **argv;
size_t i = 0;
- argv = static_cast<char**>(pj_calloc (argc, sizeof (char *)));
+ argv = static_cast<char**>(calloc (argc, sizeof (char *)));
if (nullptr==argv)
return nullptr;
for (; params != nullptr; params = params->next)
@@ -461,7 +461,7 @@ PJ *OPERATION(pipeline,0) {
if (nullptr==argv)
return destructor (P, ENOMEM);
- pipeline->current_argv = current_argv = static_cast<char**>(pj_calloc (argc, sizeof (char *)));
+ pipeline->current_argv = current_argv = static_cast<char**>(calloc (argc, sizeof (char *)));
if (nullptr==current_argv)
return destructor (P, ENOMEM);
@@ -533,7 +533,7 @@ PJ *OPERATION(pipeline,0) {
int err_to_report = proj_errno(P);
if (0==err_to_report)
err_to_report = PJD_ERR_MALFORMED_PIPELINE;
- proj_log_error (P, "Pipeline: Bad step definition: %s (%s)", current_argv[0], pj_strerrno (err_to_report));
+ proj_log_error (P, "Pipeline: Bad step definition: %s (%s)", current_argv[0], proj_errno_string (err_to_report));
return destructor (P, err_to_report); /* ERROR: bad pipeline def */
}
next_step->parent = P;
@@ -679,7 +679,7 @@ static PJ_COORD pop(PJ_COORD point, PJ *P) {
static PJ *setup_pushpop(PJ *P) {
- auto pushpop = static_cast<struct PushPop*>(pj_calloc (1, sizeof(struct PushPop)));
+ auto pushpop = static_cast<struct PushPop*>(calloc (1, sizeof(struct PushPop)));
P->opaque = pushpop;
if (nullptr==P->opaque)
return destructor(P, ENOMEM);
diff --git a/src/pj_list.h b/src/pj_list.h
index bcdc189e..d00e780f 100644
--- a/src/pj_list.h
+++ b/src/pj_list.h
@@ -155,6 +155,7 @@ PROJ_HEAD(tinshift, "Triangulation based transformation")
PROJ_HEAD(tissot, "Tissot Conic")
PROJ_HEAD(tmerc, "Transverse Mercator")
PROJ_HEAD(tobmerc, "Tobler-Mercator")
+PROJ_HEAD(topocentric, "Geocentric/Topocentric conversion")
PROJ_HEAD(tpeqd, "Two Point Equidistant")
PROJ_HEAD(tpers, "Tilted perspective")
PROJ_HEAD(unitconvert, "Unit conversion")
diff --git a/src/pr_list.cpp b/src/pr_list.cpp
index 77db5bfb..30fc6571 100644
--- a/src/pr_list.cpp
+++ b/src/pr_list.cpp
@@ -66,7 +66,7 @@ char *pj_get_def( PJ *P, int options )
size_t def_max = 10;
(void) options;
- definition = (char *) pj_malloc(def_max);
+ definition = (char *) malloc(def_max);
if (!definition)
return nullptr;
definition[0] = '\0';
@@ -84,14 +84,14 @@ char *pj_get_def( PJ *P, int options )
char *def2;
def_max = def_max * 2 + l + 5;
- def2 = (char *) pj_malloc(def_max);
+ def2 = (char *) malloc(def_max);
if (def2) {
strcpy( def2, definition );
- pj_dalloc( definition );
+ free( definition );
definition = def2;
}
else {
- pj_dalloc( definition );
+ free( definition );
return nullptr;
}
}
diff --git a/src/proj.h b/src/proj.h
index e77a5984..d4defc47 100644
--- a/src/proj.h
+++ b/src/proj.h
@@ -119,8 +119,8 @@
#include <stddef.h> /* For size_t */
-#ifdef PROJ_API_H
-#error proj.h must be included before proj_api.h
+#ifdef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
+ #error "The proj_api.h header has been removed from PROJ with version 8.0.0"
#endif
#ifdef PROJ_RENAME_SYMBOLS
@@ -340,9 +340,9 @@ typedef enum PJ_LOG_LEVEL {
typedef void (*PJ_LOG_FUNCTION)(void *, int, const char *);
-/* The context type - properly namespaced synonym for projCtx */
-struct projCtx_t;
-typedef struct projCtx_t PJ_CONTEXT;
+/* The context type - properly namespaced synonym for pj_ctx */
+struct pj_ctx;
+typedef struct pj_ctx PJ_CONTEXT;
/* A P I */
@@ -694,7 +694,8 @@ typedef enum
PJ_CATEGORY_PRIME_MERIDIAN,
PJ_CATEGORY_DATUM,
PJ_CATEGORY_CRS,
- PJ_CATEGORY_COORDINATE_OPERATION
+ PJ_CATEGORY_COORDINATE_OPERATION,
+ PJ_CATEGORY_DATUM_ENSEMBLE
} PJ_CATEGORY;
/** \brief Object type. */
diff --git a/src/proj_api.h b/src/proj_api.h
deleted file mode 100644
index a26088ca..00000000
--- a/src/proj_api.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/******************************************************************************
- * Project: PROJ.4
- * Purpose: Public (application) include file for PROJ.4 API, and constants.
- * Author: Frank Warmerdam, <warmerdam@pobox.com>
- *
- ******************************************************************************
- * Copyright (c) 2001, Frank Warmerdam <warmerdam@pobox.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *****************************************************************************/
-
-/*
- * This version number should be updated with every release!
- *
- * This file is expected to be removed from the PROJ distribution
- * when a few minor-version releases has been made.
- *
- */
-
-#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#error 'To use the proj_api.h you must define the macro ACCEPT_USE_OF_DEPRECATED_PROJ_API_H'
-#endif
-
-#ifndef PJ_VERSION
-#define PJ_VERSION 800
-#endif
-
-#ifdef PROJ_RENAME_SYMBOLS
-#include "proj_symbol_rename.h"
-#endif
-
-
-/* If we're not asked for PJ_VERSION only, give them everything */
-#ifndef PROJ_API_INCLUDED_FOR_PJ_VERSION_ONLY
-/* General projections header file */
-#ifndef PROJ_API_H
-#define PROJ_API_H
-
-/* standard inclusions */
-#include <math.h>
-#include <stddef.h>
-#include <stdlib.h>
-
-#ifndef PROJ_DLL
-#ifdef PROJ_MSVC_DLL_EXPORT
-#define PROJ_DLL __declspec(dllexport)
-#elif defined(PROJ_MSVC_DLL_IMPORT)
-#define PROJ_DLL __declspec(dllimport)
-#elif defined(__GNUC__)
-#define PROJ_DLL __attribute__ ((visibility("default")))
-#else
-#define PROJ_DLL
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* pj_init() and similar functions can be used with a non-C locale */
-/* Can be detected too at runtime if the symbol pj_atof exists */
-#define PJ_LOCALE_SAFE 1
-
-#define RAD_TO_DEG 57.295779513082321
-#define DEG_TO_RAD .017453292519943296
-
-
-#if defined(PROJ_H)
-#define PROJ_API_H_NOT_INVOKED_AS_PRIMARY_API
-#endif
-
-
-
-extern char const PROJ_DLL pj_release[]; /* global release id string */
-PROJ_DLL extern int pj_errno; /* global error return code */
-
-#ifndef PROJ_INTERNAL_H
-/* replaced by enum proj_log_level in proj_internal.h */
-#define PJ_LOG_NONE 0
-#define PJ_LOG_ERROR 1
-#define PJ_LOG_DEBUG_MAJOR 2
-#define PJ_LOG_DEBUG_MINOR 3
-#endif
-
-#ifdef PROJ_API_H_NOT_INVOKED_AS_PRIMARY_API
- /* These make the function declarations below conform with classic proj */
- typedef PJ *projPJ; /* projPJ is a pointer to PJ */
- typedef struct projCtx_t *projCtx; /* projCtx is a pointer to projCtx_t */
-# define projXY PJ_XY
-# define projLP PJ_LP
-# define projXYZ PJ_XYZ
-# define projLPZ PJ_LPZ
-
-#else
- /* i.e. proj_api invoked as primary API */
- typedef struct { double u, v; } projUV;
- typedef struct { double u, v, w; } projUVW;
- typedef void *projPJ;
- #define projXY projUV
- #define projLP projUV
- #define projXYZ projUVW
- #define projLPZ projUVW
- typedef void *projCtx;
-#endif
-
-
-/* If included *after* proj.h finishes, we have alternative names */
-/* file reading api, like stdio */
-typedef int *PAFile;
-typedef struct projFileAPI_t {
- PAFile (*FOpen)(projCtx ctx, const char *filename, const char *access);
- size_t (*FRead)(void *buffer, size_t size, size_t nmemb, PAFile file);
- int (*FSeek)(PAFile file, long offset, int whence);
- long (*FTell)(PAFile file);
- void (*FClose)(PAFile);
-} projFileAPI;
-
-
-
-/* procedure prototypes */
-
-projCtx PROJ_DLL pj_get_default_ctx(void);
-projCtx PROJ_DLL pj_get_ctx( projPJ );
-
-projXY PROJ_DLL pj_fwd(projLP, projPJ);
-projLP PROJ_DLL pj_inv(projXY, projPJ);
-
-projXYZ PROJ_DLL pj_fwd3d(projLPZ, projPJ);
-projLPZ PROJ_DLL pj_inv3d(projXYZ, projPJ);
-
-
-int PROJ_DLL pj_transform( projPJ src, projPJ dst, long point_count, int point_offset,
- double *x, double *y, double *z );
-int PROJ_DLL pj_datum_transform( projPJ src, projPJ dst, long point_count, int point_offset,
- double *x, double *y, double *z );
-int PROJ_DLL pj_geocentric_to_geodetic( double a, double es,
- long point_count, int point_offset,
- double *x, double *y, double *z );
-int PROJ_DLL pj_geodetic_to_geocentric( double a, double es,
- long point_count, int point_offset,
- double *x, double *y, double *z );
-int PROJ_DLL pj_compare_datums( projPJ srcdefn, projPJ dstdefn );
-int PROJ_DLL pj_apply_gridshift( projCtx, const char *, int,
- long point_count, int point_offset,
- double *x, double *y, double *z );
-void PROJ_DLL pj_deallocate_grids(void);
-void PROJ_DLL pj_clear_initcache(void);
-int PROJ_DLL pj_is_latlong(projPJ);
-int PROJ_DLL pj_is_geocent(projPJ);
-void PROJ_DLL pj_get_spheroid_defn(projPJ defn, double *major_axis, double *eccentricity_squared);
-void PROJ_DLL pj_pr_list(projPJ);
-void PROJ_DLL pj_free(projPJ);
-void PROJ_DLL pj_set_finder( const char *(*)(const char *) );
-void PROJ_DLL pj_set_searchpath ( int count, const char **path );
-projPJ PROJ_DLL pj_init(int, char **);
-projPJ PROJ_DLL pj_init_plus(const char *);
-projPJ PROJ_DLL pj_init_ctx( projCtx, int, char ** );
-projPJ PROJ_DLL pj_init_plus_ctx( projCtx, const char * );
-char PROJ_DLL *pj_get_def(projPJ, int);
-projPJ PROJ_DLL pj_latlong_from_proj( projPJ );
-int PROJ_DLL pj_has_inverse(projPJ);
-
-
-void PROJ_DLL *pj_malloc(size_t);
-void PROJ_DLL pj_dalloc(void *);
-void PROJ_DLL *pj_calloc (size_t n, size_t size);
-void PROJ_DLL *pj_dealloc (void *ptr);
-char PROJ_DLL *pj_strdup(const char *str);
-char PROJ_DLL *pj_strerrno(int);
-int PROJ_DLL *pj_get_errno_ref(void);
-const char PROJ_DLL *pj_get_release(void);
-void PROJ_DLL pj_acquire_lock(void);
-void PROJ_DLL pj_release_lock(void);
-void PROJ_DLL pj_cleanup_lock(void);
-
-void PROJ_DLL pj_set_ctx( projPJ, projCtx );
-projCtx PROJ_DLL pj_ctx_alloc(void);
-void PROJ_DLL pj_ctx_free( projCtx );
-int PROJ_DLL pj_ctx_get_errno( projCtx );
-void PROJ_DLL pj_ctx_set_errno( projCtx, int );
-void PROJ_DLL pj_ctx_set_debug( projCtx, int );
-void PROJ_DLL pj_ctx_set_logger( projCtx, void (*)(void *, int, const char *) );
-void PROJ_DLL pj_ctx_set_app_data( projCtx, void * );
-void PROJ_DLL *pj_ctx_get_app_data( projCtx );
-void PROJ_DLL pj_ctx_set_fileapi( projCtx, projFileAPI *);
-projFileAPI PROJ_DLL *pj_ctx_get_fileapi( projCtx );
-
-void PROJ_DLL pj_log( projCtx ctx, int level, const char *fmt, ... );
-void PROJ_DLL pj_stderr_logger( void *, int, const char * );
-
-/* file api */
-projFileAPI PROJ_DLL *pj_get_default_fileapi(void);
-
-PAFile PROJ_DLL pj_ctx_fopen(projCtx ctx, const char *filename, const char *access);
-size_t PROJ_DLL pj_ctx_fread(projCtx ctx, void *buffer, size_t size, size_t nmemb, PAFile file);
-int PROJ_DLL pj_ctx_fseek(projCtx ctx, PAFile file, long offset, int whence);
-long PROJ_DLL pj_ctx_ftell(projCtx ctx, PAFile file);
-void PROJ_DLL pj_ctx_fclose(projCtx ctx, PAFile file);
-char PROJ_DLL *pj_ctx_fgets(projCtx ctx, char *line, int size, PAFile file);
-
-PAFile PROJ_DLL pj_open_lib(projCtx, const char *, const char *);
-int PROJ_DLL pj_find_file(projCtx ctx, const char *short_filename,
- char* out_full_filename, size_t out_full_filename_size);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ndef PROJ_API_H */
-#endif /* ndef PROJ_API_INCLUDED_FOR_PJ_VERSION_ONLY */
diff --git a/src/proj_constants.h b/src/proj_constants.h
index a3da2c10..ce3b2157 100644
--- a/src/proj_constants.h
+++ b/src/proj_constants.h
@@ -651,4 +651,24 @@
#define EPSG_CODE_METHOD_HEIGHT_DEPTH_REVERSAL 1068
#define EPSG_NAME_METHOD_HEIGHT_DEPTH_REVERSAL "Height Depth Reversal"
+/* ------------------------------------------------------------------------ */
+
+#define EPSG_NAME_METHOD_GEOCENTRIC_TOPOCENTRIC "Geocentric/topocentric conversions"
+#define EPSG_CODE_METHOD_GEOCENTRIC_TOPOCENTRIC 9836
+
+#define EPSG_NAME_PARAMETER_GEOCENTRIC_X_TOPOCENTRIC_ORIGIN "Geocentric X of topocentric origin"
+#define EPSG_CODE_PARAMETER_GEOCENTRIC_X_TOPOCENTRIC_ORIGIN 8837
+
+#define EPSG_NAME_PARAMETER_GEOCENTRIC_Y_TOPOCENTRIC_ORIGIN "Geocentric Y of topocentric origin"
+#define EPSG_CODE_PARAMETER_GEOCENTRIC_Y_TOPOCENTRIC_ORIGIN 8838
+
+#define EPSG_NAME_PARAMETER_GEOCENTRIC_Z_TOPOCENTRIC_ORIGIN "Geocentric Z of topocentric origin"
+#define EPSG_CODE_PARAMETER_GEOCENTRIC_Z_TOPOCENTRIC_ORIGIN 8839
+
+/* ------------------------------------------------------------------------ */
+
+#define EPSG_NAME_METHOD_GEOGRAPHIC_TOPOCENTRIC "Geographic/topocentric conversions"
+#define EPSG_CODE_METHOD_GEOGRAPHIC_TOPOCENTRIC 9837
+
+
#endif /* PROJ_CONSTANTS_INCLUDED */
diff --git a/src/proj_internal.h b/src/proj_internal.h
index 79b1da10..32aaa1ec 100644
--- a/src/proj_internal.h
+++ b/src/proj_internal.h
@@ -33,10 +33,6 @@
#error "proj_internal.h can only be included from a C++ file"
#endif
-#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#endif
-
#ifdef _MSC_VER
# ifndef _CRT_SECURE_NO_DEPRECATE
# define _CRT_SECURE_NO_DEPRECATE
@@ -66,10 +62,6 @@
#include "proj.h"
-#ifdef PROJ_API_H
-#error proj_internal.h must be included before proj_api.h
-#endif
-
#ifdef PROJ_RENAME_SYMBOLS
#include "proj_symbol_rename.h"
#endif
@@ -248,8 +240,6 @@ struct PJ_AREA {
double north_lat_degree;
};
-struct projCtx_t;
-typedef struct projCtx_t projCtx_t;
/*****************************************************************************
@@ -360,7 +350,7 @@ struct PJconsts {
**************************************************************************************/
- projCtx_t *ctx = nullptr;
+ PJ_CONTEXT *ctx = nullptr;
const char *descr = nullptr; /* From pj_list.h or individual PJ_*.c file */
paralist *params = nullptr; /* Parameter list */
char *def_full = nullptr; /* Full textual definition (usually 0 - set by proj_pj_info) */
@@ -401,7 +391,7 @@ struct PJconsts {
PJ_OPERATOR inv4d = nullptr;
PJ_DESTRUCTOR destructor = nullptr;
- void (*reassign_context)(PJ*, projCtx_t *) = nullptr;
+ void (*reassign_context)(PJ*, PJ_CONTEXT*) = nullptr;
/*************************************************************************************
@@ -626,7 +616,7 @@ struct FACTORS {
#define PJD_ERR_INVALID_X_OR_Y -15
#define PJD_ERR_WRONG_FORMAT_DMS_VALUE -16
#define PJD_ERR_NON_CONV_INV_MERI_DIST -17
-#define PJD_ERR_NON_CON_INV_PHI2 -18
+#define PJD_ERR_NON_CONV_SINHPSI2TANPHI -18
#define PJD_ERR_ACOS_ASIN_ARG_TOO_LARGE -19
#define PJD_ERR_TOLERANCE_CONDITION -20
#define PJD_ERR_CONIC_LAT_EQUAL -21
@@ -716,12 +706,11 @@ struct projFileApiCallbackAndData
};
/* proj thread context */
-struct projCtx_t {
+struct pj_ctx{
int last_errno = 0;
int debug_level = 0;
void (*logger)(void *, int, const char *) = nullptr;
void *logger_app_data = nullptr;
- struct projFileAPI_t *fileapi_legacy = nullptr; // for proj_api.h legacy API
struct projCppContext* cpp_context = nullptr; /* internal context for C++ code */
int use_proj4_init_rules = -1; /* -1 = unknown, 0 = no, 1 = yes */
int epsg_file_exists = -1; /* -1 = unknown, 0 = no, 1 = yes */
@@ -753,18 +742,18 @@ struct projCtx_t {
int pipelineInitRecursiongCounter = 0; // to avoid potential infinite recursion in pipeline.cpp
- projCtx_t() = default;
- projCtx_t(const projCtx_t&);
- ~projCtx_t();
+ pj_ctx() = default;
+ pj_ctx(const pj_ctx&);
+ ~pj_ctx();
- projCtx_t& operator= (const projCtx_t&) = delete;
+ pj_ctx& operator= (const pj_ctx&) = delete;
projCppContext* get_cpp_context();
void safeAutoCloseDbIfNeeded();
void set_search_paths(const std::vector<std::string>& search_paths_in);
void set_ca_bundle_path(const std::string& ca_bundle_path_in);
- static projCtx_t createDefault();
+ static pj_ctx createDefault();
};
/* Generate pj_list external or make list from include file */
@@ -812,40 +801,41 @@ PJ *pj_projection_specific_setup_##name (PJ *P)
/* procedure prototypes */
double PROJ_DLL dmstor(const char *, char **);
-double dmstor_ctx(projCtx_t *ctx, const char *, char **);
+double dmstor_ctx(PJ_CONTEXT *ctx, const char *, char **);
void PROJ_DLL set_rtodms(int, int);
char PROJ_DLL *rtodms(char *, double, int, int);
double PROJ_DLL adjlon(double);
-double aacos(projCtx_t *,double);
-double aasin(projCtx_t *,double);
+double aacos(PJ_CONTEXT *,double);
+double aasin(PJ_CONTEXT *,double);
double asqrt(double);
double aatan2(double, double);
-PROJVALUE PROJ_DLL pj_param(projCtx_t *ctx, paralist *, const char *);
+PROJVALUE PROJ_DLL pj_param(PJ_CONTEXT *ctx, paralist *, const char *);
paralist PROJ_DLL *pj_param_exists (paralist *list, const char *parameter);
paralist PROJ_DLL *pj_mkparam(const char *);
paralist *pj_mkparam_ws (const char *str, const char **next_str);
-int PROJ_DLL pj_ell_set(projCtx_t *ctx, paralist *, double *, double *);
-int pj_datum_set(projCtx_t *,paralist *, PJ *);
+int PROJ_DLL pj_ell_set(PJ_CONTEXT *ctx, paralist *, double *, double *);
+int pj_datum_set(PJ_CONTEXT *,paralist *, PJ *);
int pj_angular_units_set(paralist *, PJ *);
paralist *pj_clone_paralist( const paralist* );
paralist *pj_search_initcache( const char *filekey );
void pj_insert_initcache( const char *filekey, const paralist *list);
-paralist *pj_expand_init(projCtx_t *ctx, paralist *init);
+paralist *pj_expand_init(PJ_CONTEXT *ctx, paralist *init);
-void *pj_dealloc_params (projCtx_t *ctx, paralist *start, int errlev);
+void *free_params (PJ_CONTEXT *ctx, paralist *start, int errlev);
double *pj_enfn(double);
double pj_mlfn(double, double, double, const double *);
-double pj_inv_mlfn(projCtx_t *, double, double, const double *);
+double pj_inv_mlfn(PJ_CONTEXT *, double, double, const double *);
double pj_qsfn(double, double, double);
double pj_tsfn(double, double, double);
double pj_msfn(double, double, double);
-double PROJ_DLL pj_phi2(projCtx_t *, const double, const double);
+double PROJ_DLL pj_phi2(PJ_CONTEXT *, const double, const double);
+double pj_sinhpsi2tanphi(PJ_CONTEXT *, const double, const double);
double pj_qsfn_(double, PJ *);
double *pj_authset(double);
double pj_authlat(double, double *);
@@ -858,10 +848,10 @@ int pj_factors(PJ_LP, const PJ *, double, struct FACTORS *);
void *proj_mdist_ini(double);
double proj_mdist(double, double, double, const void *);
-double proj_inv_mdist(projCtx_t *ctx, double, const void *);
+double proj_inv_mdist(PJ_CONTEXT *ctx, double, const void *);
void *pj_gauss_ini(double, double, double *,double *);
-PJ_LP pj_gauss(projCtx_t *, PJ_LP, const void *);
-PJ_LP pj_inv_gauss(projCtx_t *, PJ_LP, const void *);
+PJ_LP pj_gauss(PJ_CONTEXT *, PJ_LP, const void *);
+PJ_LP pj_inv_gauss(PJ_CONTEXT *, PJ_LP, const void *);
struct PJ_DATUMS PROJ_DLL *pj_get_datums_ref( void );
@@ -872,7 +862,7 @@ double PROJ_DLL pj_atof( const char* nptr );
double pj_strtod( const char *nptr, char **endptr );
void pj_freeup_plain (PJ *P);
-PJ* pj_init_ctx_with_allow_init_epsg( projCtx_t *ctx, int argc, char **argv, int allow_init_epsg );
+PJ* pj_init_ctx_with_allow_init_epsg( PJ_CONTEXT *ctx, int argc, char **argv, int allow_init_epsg );
std::string PROJ_DLL pj_add_type_crs_if_needed(const std::string& str);
std::string pj_double_quote_string_param_if_needed(const std::string& str);
@@ -909,7 +899,68 @@ void pj_clear_vgridshift_knowngrids_cache();
PJ_LP pj_generic_inverse_2d(PJ_XY xy, PJ *P, PJ_LP lpInitial);
-/* classic public API */
-#include "proj_api.h"
+
+
+
+/*****************************************************************************/
+/* */
+/* proj_api.h */
+/* */
+/* The rest of this header file includes what used to be "proj_api.h" */
+/* */
+/*****************************************************************************/
+
+/* pj_init() and similar functions can be used with a non-C locale */
+/* Can be detected too at runtime if the symbol pj_atof exists */
+#define PJ_LOCALE_SAFE 1
+
+#define RAD_TO_DEG 57.295779513082321
+#define DEG_TO_RAD .017453292519943296
+
+
+
+
+extern char const PROJ_DLL pj_release[]; /* global release id string */
+
+#ifndef PROJ_INTERNAL_H
+/* replaced by enum proj_log_level in proj_internal.h */
+#define PJ_LOG_NONE 0
+#define PJ_LOG_ERROR 1
+#define PJ_LOG_DEBUG_MAJOR 2
+#define PJ_LOG_DEBUG_MINOR 3
+#endif
+
+
+/* procedure prototypes */
+
+PJ_CONTEXT PROJ_DLL *pj_get_default_ctx(void);
+PJ_CONTEXT *pj_get_ctx( PJ *);
+
+PJ_XY PROJ_DLL pj_fwd(PJ_LP, PJ *);
+PJ_LP PROJ_DLL pj_inv(PJ_XY, PJ *);
+
+PJ_XYZ pj_fwd3d(PJ_LPZ, PJ *);
+PJ_LPZ pj_inv3d(PJ_XYZ, PJ *);
+
+
+void pj_clear_initcache(void);
+void PROJ_DLL pj_pr_list(PJ *); /* used by proj.cpp */
+char *pj_get_def(PJ *, int);
+int pj_has_inverse(PJ *);
+
+
+char *pj_strdup(const char *str);
+const char PROJ_DLL *pj_get_release(void);
+void pj_acquire_lock(void);
+void pj_release_lock(void);
+void pj_cleanup_lock(void);
+
+void pj_log( PJ_CONTEXT * ctx, int level, const char *fmt, ... );
+void pj_stderr_logger( void *, int, const char * );
+
+int pj_find_file(PJ_CONTEXT * ctx, const char *short_filename,
+ char* out_full_filename, size_t out_full_filename_size);
+
+
#endif /* ndef PROJ_INTERNAL_H */
diff --git a/src/proj_mdist.cpp b/src/proj_mdist.cpp
index c515f6c5..ed07ffd1 100644
--- a/src/proj_mdist.cpp
+++ b/src/proj_mdist.cpp
@@ -107,7 +107,7 @@ proj_mdist(double phi, double sphi, double cphi, const void *data) {
return(D + sc * sum);
}
double
-proj_inv_mdist(projCtx ctx, double dist, const void *data) {
+proj_inv_mdist(PJ_CONTEXT *ctx, double dist, const void *data) {
const struct MDIST *b = (const struct MDIST *)data;
double s, t, phi, k;
int i;
@@ -124,6 +124,6 @@ proj_inv_mdist(projCtx ctx, double dist, const void *data) {
return phi;
}
/* convergence failed */
- pj_ctx_set_errno(ctx, PJD_ERR_NON_CONV_INV_MERI_DIST);
+ proj_context_errno_set(ctx, PJD_ERR_NON_CONV_INV_MERI_DIST);
return phi;
}
diff --git a/src/projections/adams.cpp b/src/projections/adams.cpp
index 4f7d1a03..d1217ff1 100644
--- a/src/projections/adams.cpp
+++ b/src/projections/adams.cpp
@@ -205,7 +205,7 @@ static PJ_LP adams_inverse(PJ_XY xy, PJ *P)
static PJ *setup(PJ *P, projection_type mode) {
struct pj_opaque *Q = static_cast<struct pj_opaque*>(
- pj_calloc (1, sizeof (struct pj_opaque)));
+ calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
diff --git a/src/projections/aea.cpp b/src/projections/aea.cpp
index 6ffb4fd6..af0f292d 100644
--- a/src/projections/aea.cpp
+++ b/src/projections/aea.cpp
@@ -94,7 +94,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor (P, errlev);
}
@@ -219,7 +219,7 @@ static PJ *setup(PJ *P) {
PJ *PROJECTION(aea) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -232,7 +232,7 @@ PJ *PROJECTION(aea) {
PJ *PROJECTION(leac) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/aeqd.cpp b/src/projections/aeqd.cpp
index ad8c289e..d5d90b62 100644
--- a/src/projections/aeqd.cpp
+++ b/src/projections/aeqd.cpp
@@ -69,7 +69,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor (P, errlev);
}
@@ -274,7 +274,7 @@ static PJ_LP aeqd_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse
PJ *PROJECTION(aeqd) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/airy.cpp b/src/projections/airy.cpp
index f7602e53..15ff60d8 100644
--- a/src/projections/airy.cpp
+++ b/src/projections/airy.cpp
@@ -120,7 +120,7 @@ static PJ_XY airy_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward
PJ *PROJECTION(airy) {
double beta;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
diff --git a/src/projections/aitoff.cpp b/src/projections/aitoff.cpp
index 7920309c..857ebb80 100644
--- a/src/projections/aitoff.cpp
+++ b/src/projections/aitoff.cpp
@@ -170,7 +170,7 @@ static PJ_LP aitoff_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver
if (iter == MAXITER && round == MAXROUND)
{
- pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );
+ proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT );
/* fprintf(stderr, "Warning: Accuracy of 1e-12 not reached. Last increments: dlat=%e and dlon=%e\n", dp, dl); */
}
@@ -187,7 +187,7 @@ static PJ *setup(PJ *P) {
PJ *PROJECTION(aitoff) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
@@ -198,7 +198,7 @@ PJ *PROJECTION(aitoff) {
PJ *PROJECTION(wintri) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/bacon.cpp b/src/projections/bacon.cpp
index 3efd4dbe..7ff2a7ac 100644
--- a/src/projections/bacon.cpp
+++ b/src/projections/bacon.cpp
@@ -43,7 +43,7 @@ static PJ_XY bacon_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forwar
PJ *PROJECTION(bacon) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -57,7 +57,7 @@ PJ *PROJECTION(bacon) {
PJ *PROJECTION(apian) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -70,7 +70,7 @@ PJ *PROJECTION(apian) {
PJ *PROJECTION(ortel) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/bertin1953.cpp b/src/projections/bertin1953.cpp
index b864f83a..58509e16 100644
--- a/src/projections/bertin1953.cpp
+++ b/src/projections/bertin1953.cpp
@@ -75,7 +75,7 @@ static PJ_XY bertin1953_s_forward (PJ_LP lp, PJ *P) {
PJ *PROJECTION(bertin1953) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/bipc.cpp b/src/projections/bipc.cpp
index bf4ba834..743acd1c 100644
--- a/src/projections/bipc.cpp
+++ b/src/projections/bipc.cpp
@@ -168,7 +168,7 @@ static PJ_LP bipc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse
PJ *PROJECTION(bipc) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/bonne.cpp b/src/projections/bonne.cpp
index c94764cf..7817e968 100644
--- a/src/projections/bonne.cpp
+++ b/src/projections/bonne.cpp
@@ -106,14 +106,14 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor (P, errlev);
}
PJ *PROJECTION(bonne) {
double c;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/calcofi.cpp b/src/projections/calcofi.cpp
index 57c12dde..d1e96de8 100644
--- a/src/projections/calcofi.cpp
+++ b/src/projections/calcofi.cpp
@@ -4,7 +4,6 @@
#include "proj.h"
#include "proj_internal.h"
-#include "proj_api.h"
PROJ_HEAD(calcofi,
"Cal Coop Ocean Fish Invest Lines/Stations") "\n\tCyl, Sph&Ell";
diff --git a/src/projections/cass.cpp b/src/projections/cass.cpp
index e253cafc..f5531f6a 100644
--- a/src/projections/cass.cpp
+++ b/src/projections/cass.cpp
@@ -95,7 +95,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor (P, errlev);
}
@@ -111,7 +111,7 @@ PJ *PROJECTION(cass) {
}
/* otherwise it's ellipsoidal */
- P->opaque = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ P->opaque = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==P->opaque)
return pj_default_destructor (P, ENOMEM);
P->destructor = destructor;
diff --git a/src/projections/ccon.cpp b/src/projections/ccon.cpp
index df995f21..7b3b7105 100644
--- a/src/projections/ccon.cpp
+++ b/src/projections/ccon.cpp
@@ -75,14 +75,14 @@ static PJ *destructor (PJ *P, int errlev) {
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor (P, errlev);
}
PJ *PROJECTION(ccon) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/cea.cpp b/src/projections/cea.cpp
index 7e6d3212..b7874b90 100644
--- a/src/projections/cea.cpp
+++ b/src/projections/cea.cpp
@@ -66,14 +66,14 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->apa);
+ free (static_cast<struct pj_opaque*>(P->opaque)->apa);
return pj_default_destructor (P, errlev);
}
PJ *PROJECTION(cea) {
double t = 0.0;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/chamb.cpp b/src/projections/chamb.cpp
index 36609e79..b315832a 100644
--- a/src/projections/chamb.cpp
+++ b/src/projections/chamb.cpp
@@ -29,7 +29,7 @@ PROJ_HEAD(chamb, "Chamberlin Trimetric") "\n\tMisc Sph, no inv"
#define TOL 1e-9
/* distance and azimuth from point 1 to point 2 */
-static VECT vect(projCtx ctx, double dphi, double c1, double s1, double c2, double s2, double dlam) {
+static VECT vect(PJ_CONTEXT *ctx, double dphi, double c1, double s1, double c2, double s2, double dlam) {
VECT v;
double cdl, dp, dl;
@@ -49,7 +49,7 @@ static VECT vect(projCtx ctx, double dphi, double c1, double s1, double c2, doub
}
/* law of cosines */
-static double lc(projCtx ctx, double b,double c,double a) {
+static double lc(PJ_CONTEXT *ctx, double b,double c,double a) {
return aacos(ctx, .5 * (b * b + c * c - a * a) / (b * c));
}
@@ -103,7 +103,7 @@ static PJ_XY chamb_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forwar
PJ *PROJECTION(chamb) {
int i, j;
char line[10];
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/col_urban.cpp b/src/projections/col_urban.cpp
index 5bc8407f..de0c178f 100644
--- a/src/projections/col_urban.cpp
+++ b/src/projections/col_urban.cpp
@@ -54,7 +54,7 @@ static PJ_LP col_urban_inverse (PJ_XY xy, PJ *P) {
}
PJ *PROJECTION(col_urban) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/comill.cpp b/src/projections/comill.cpp
index 189e583e..44524990 100644
--- a/src/projections/comill.cpp
+++ b/src/projections/comill.cpp
@@ -66,7 +66,7 @@ static PJ_LP comill_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver
}
}
if( i == 0 )
- pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );
+ proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT );
lp.phi = yc;
/* longitude */
diff --git a/src/projections/eck3.cpp b/src/projections/eck3.cpp
index 0deeb4f3..2563053f 100644
--- a/src/projections/eck3.cpp
+++ b/src/projections/eck3.cpp
@@ -52,7 +52,7 @@ static PJ *setup(PJ *P) {
PJ *PROJECTION(eck3) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -67,7 +67,7 @@ PJ *PROJECTION(eck3) {
PJ *PROJECTION(kav7) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -85,7 +85,7 @@ PJ *PROJECTION(kav7) {
PJ *PROJECTION(wag6) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -100,7 +100,7 @@ PJ *PROJECTION(wag6) {
PJ *PROJECTION(putp1) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/eqc.cpp b/src/projections/eqc.cpp
index 194625ef..9ebc9286 100644
--- a/src/projections/eqc.cpp
+++ b/src/projections/eqc.cpp
@@ -39,7 +39,7 @@ static PJ_LP eqc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse
PJ *PROJECTION(eqc) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/eqdc.cpp b/src/projections/eqdc.cpp
index 659488b1..28767d74 100644
--- a/src/projections/eqdc.cpp
+++ b/src/projections/eqdc.cpp
@@ -68,7 +68,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor (P, errlev);
}
@@ -77,7 +77,7 @@ PJ *PROJECTION(eqdc) {
double cosphi, sinphi;
int secant;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/eqearth.cpp b/src/projections/eqearth.cpp
index 832c9444..2ef2775b 100644
--- a/src/projections/eqearth.cpp
+++ b/src/projections/eqearth.cpp
@@ -110,7 +110,7 @@ static PJ_LP eqearth_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal/sphe
}
if( i == 0 ) {
- pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );
+ proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT );
return lp;
}
@@ -137,13 +137,13 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor */
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->apa);
+ free (static_cast<struct pj_opaque*>(P->opaque)->apa);
return pj_default_destructor (P, errlev);
}
PJ *PROJECTION(eqearth) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/fouc_s.cpp b/src/projections/fouc_s.cpp
index c5989514..f7607635 100644
--- a/src/projections/fouc_s.cpp
+++ b/src/projections/fouc_s.cpp
@@ -55,7 +55,7 @@ static PJ_LP fouc_s_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver
PJ *PROJECTION(fouc_s) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/geos.cpp b/src/projections/geos.cpp
index 338f07c2..5de4c7ca 100644
--- a/src/projections/geos.cpp
+++ b/src/projections/geos.cpp
@@ -199,7 +199,7 @@ static PJ_LP geos_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse
PJ *PROJECTION(geos) {
char *sweep_axis;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/gn_sinu.cpp b/src/projections/gn_sinu.cpp
index 815de8be..ef312613 100644
--- a/src/projections/gn_sinu.cpp
+++ b/src/projections/gn_sinu.cpp
@@ -102,7 +102,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor (P, errlev);
}
@@ -121,7 +121,7 @@ static void setup(PJ *P) {
PJ *PROJECTION(sinu) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -143,7 +143,7 @@ PJ *PROJECTION(sinu) {
PJ *PROJECTION(eck6) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -158,7 +158,7 @@ PJ *PROJECTION(eck6) {
PJ *PROJECTION(mbtfps) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -173,7 +173,7 @@ PJ *PROJECTION(mbtfps) {
PJ *PROJECTION(gn_sinu) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/gnom.cpp b/src/projections/gnom.cpp
index 23dee030..9abbb7ce 100644
--- a/src/projections/gnom.cpp
+++ b/src/projections/gnom.cpp
@@ -124,7 +124,7 @@ static PJ_LP gnom_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse
PJ *PROJECTION(gnom) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/goode.cpp b/src/projections/goode.cpp
index fdace387..c0afd2d8 100644
--- a/src/projections/goode.cpp
+++ b/src/projections/goode.cpp
@@ -54,15 +54,15 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor */
return nullptr;
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_free (static_cast<struct pj_opaque*>(P->opaque)->sinu);
- pj_free (static_cast<struct pj_opaque*>(P->opaque)->moll);
+ proj_destroy (static_cast<struct pj_opaque*>(P->opaque)->sinu);
+ proj_destroy (static_cast<struct pj_opaque*>(P->opaque)->moll);
return pj_default_destructor (P, errlev);
}
PJ *PROJECTION(goode) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/gstmerc.cpp b/src/projections/gstmerc.cpp
index 808d9ef7..b21f6ffd 100644
--- a/src/projections/gstmerc.cpp
+++ b/src/projections/gstmerc.cpp
@@ -28,9 +28,9 @@ static PJ_XY gstmerc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forw
double L, Ls, sinLs1, Ls1;
L = Q->n1*lp.lam;
- Ls = Q->c + Q->n1 * log(pj_tsfn(-1.0 * lp.phi, -1.0 * sin(lp.phi), P->e));
+ Ls = Q->c + Q->n1 * log(pj_tsfn(-lp.phi, -sin(lp.phi), P->e));
sinLs1 = sin(L) / cosh(Ls);
- Ls1 = log(pj_tsfn(-1.0 * asin(sinLs1), 0.0, 0.0));
+ Ls1 = log(pj_tsfn(-asin(sinLs1), -sinLs1, 0.0));
xy.x = (Q->XS + Q->n2*Ls1) * P->ra;
xy.y = (Q->YS + Q->n2*atan(sinh(Ls) / cos(L))) * P->ra;
@@ -45,28 +45,28 @@ static PJ_LP gstmerc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inve
L = atan(sinh((xy.x * P->a - Q->XS) / Q->n2) / cos((xy.y * P->a - Q->YS) / Q->n2));
sinC = sin((xy.y * P->a - Q->YS) / Q->n2) / cosh((xy.x * P->a - Q->XS) / Q->n2);
- LC = log(pj_tsfn(-1.0 * asin(sinC), 0.0, 0.0));
+ LC = log(pj_tsfn(-asin(sinC), -sinC, 0.0));
lp.lam = L / Q->n1;
- lp.phi = -1.0 * pj_phi2(P->ctx, exp((LC - Q->c) / Q->n1), P->e);
+ lp.phi = -pj_phi2(P->ctx, exp((LC - Q->c) / Q->n1), P->e);
return lp;
}
PJ *PROJECTION(gstmerc) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
Q->lamc = P->lam0;
- Q->n1 = sqrt(1.0 + P->es * pow(cos(P->phi0), 4.0) / (1.0 - P->es));
+ Q->n1 = sqrt(1 + P->es * pow(cos(P->phi0), 4.0) / (1 - P->es));
Q->phic = asin(sin(P->phi0) / Q->n1);
- Q->c = log(pj_tsfn(-1.0 * Q->phic, 0.0, 0.0))
- - Q->n1 * log(pj_tsfn(-1.0 * P->phi0, -1.0 * sin(P->phi0), P->e));
- Q->n2 = P->k0 * P->a * sqrt(1.0 - P->es) / (1.0 - P->es * sin(P->phi0) * sin(P->phi0));
+ Q->c = log(pj_tsfn(-Q->phic, -sin(P->phi0) / Q->n1, 0.0))
+ - Q->n1 * log(pj_tsfn(-P->phi0, -sin(P->phi0), P->e));
+ Q->n2 = P->k0 * P->a * sqrt(1 - P->es) / (1 - P->es * sin(P->phi0) * sin(P->phi0));
Q->XS = 0;
- Q->YS = -1.0 * Q->n2 * Q->phic;
+ Q->YS = -Q->n2 * Q->phic;
P->inv = gstmerc_s_inverse;
P->fwd = gstmerc_s_forward;
diff --git a/src/projections/hammer.cpp b/src/projections/hammer.cpp
index 8d6d9408..d9bcafc7 100644
--- a/src/projections/hammer.cpp
+++ b/src/projections/hammer.cpp
@@ -57,7 +57,7 @@ static PJ_LP hammer_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver
PJ *PROJECTION(hammer) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/healpix.cpp b/src/projections/healpix.cpp
index aab5c41e..c778f28f 100644
--- a/src/projections/healpix.cpp
+++ b/src/projections/healpix.cpp
@@ -524,7 +524,7 @@ static PJ_LP s_healpix_inverse(PJ_XY xy, PJ *P) { /* sphere */
PJ_LP lp;
lp.lam = HUGE_VAL;
lp.phi = HUGE_VAL;
- pj_ctx_set_errno(P->ctx, PJD_ERR_INVALID_X_OR_Y);
+ proj_context_errno_set(P->ctx, PJD_ERR_INVALID_X_OR_Y);
return lp;
}
return healpix_spherhealpix_e_inverse(xy);
@@ -540,7 +540,7 @@ static PJ_LP e_healpix_inverse(PJ_XY xy, PJ *P) { /* ellipsoid */
if (in_image(xy.x, xy.y, 0, 0, 0) == 0) {
lp.lam = HUGE_VAL;
lp.phi = HUGE_VAL;
- pj_ctx_set_errno(P->ctx, PJD_ERR_INVALID_X_OR_Y);
+ proj_context_errno_set(P->ctx, PJD_ERR_INVALID_X_OR_Y);
return lp;
}
lp = healpix_spherhealpix_e_inverse(xy);
@@ -574,7 +574,7 @@ static PJ_LP s_rhealpix_inverse(PJ_XY xy, PJ *P) { /* sphere */
PJ_LP lp;
lp.lam = HUGE_VAL;
lp.phi = HUGE_VAL;
- pj_ctx_set_errno(P->ctx, PJD_ERR_INVALID_X_OR_Y);
+ proj_context_errno_set(P->ctx, PJD_ERR_INVALID_X_OR_Y);
return lp;
}
xy = combine_caps(xy.x, xy.y, Q->north_square, Q->south_square, 1);
@@ -590,7 +590,7 @@ static PJ_LP e_rhealpix_inverse(PJ_XY xy, PJ *P) { /* ellipsoid */
if (in_image(xy.x, xy.y, 1, Q->north_square, Q->south_square) == 0) {
lp.lam = HUGE_VAL;
lp.phi = HUGE_VAL;
- pj_ctx_set_errno(P->ctx, PJD_ERR_INVALID_X_OR_Y);
+ proj_context_errno_set(P->ctx, PJD_ERR_INVALID_X_OR_Y);
return lp;
}
xy = combine_caps(xy.x, xy.y, Q->north_square, Q->south_square, 1);
@@ -607,13 +607,13 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->apa);
+ free (static_cast<struct pj_opaque*>(P->opaque)->apa);
return pj_default_destructor (P, errlev);
}
PJ *PROJECTION(healpix) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -641,7 +641,7 @@ PJ *PROJECTION(healpix) {
PJ *PROJECTION(rhealpix) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/igh.cpp b/src/projections/igh.cpp
index 2be94889..8aaaaba1 100644
--- a/src/projections/igh.cpp
+++ b/src/projections/igh.cpp
@@ -208,7 +208,7 @@ static bool setup_zone(PJ *P, struct pj_opaque *Q, int n,
PJ *PROJECTION(igh) {
PJ_XY xy1, xy3;
PJ_LP lp = { 0, phi_boundary };
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/igh_o.cpp b/src/projections/igh_o.cpp
index b14d79a5..80874845 100644
--- a/src/projections/igh_o.cpp
+++ b/src/projections/igh_o.cpp
@@ -222,7 +222,7 @@ static bool setup_zone(PJ *P, struct pj_opaque *Q, int n,
PJ *PROJECTION(igh_o) {
PJ_XY xy1, xy4;
PJ_LP lp = { 0, phi_boundary };
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/imw_p.cpp b/src/projections/imw_p.cpp
index ee206091..6e82d287 100644
--- a/src/projections/imw_p.cpp
+++ b/src/projections/imw_p.cpp
@@ -160,7 +160,7 @@ static PJ *destructor (PJ *P, int errlev) {
return pj_default_destructor (P, errlev);
if( static_cast<struct pj_opaque*>(P->opaque)->en )
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor(P, errlev);
}
@@ -169,7 +169,7 @@ static PJ *destructor (PJ *P, int errlev) {
PJ *PROJECTION(imw_p) {
double del, sig, s, t, x1, x2, T2, y1, m1, m2, y2;
int err;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/isea.cpp b/src/projections/isea.cpp
index dd1d48ff..77a5689b 100644
--- a/src/projections/isea.cpp
+++ b/src/projections/isea.cpp
@@ -1039,7 +1039,7 @@ static PJ_XY isea_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward
PJ *PROJECTION(isea) {
char *opt;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/krovak.cpp b/src/projections/krovak.cpp
index aef44d42..adc039fe 100644
--- a/src/projections/krovak.cpp
+++ b/src/projections/krovak.cpp
@@ -181,7 +181,7 @@ static PJ_LP krovak_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal,
fi1 = lp.phi;
}
if( i == 0 )
- pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );
+ proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT );
lp.lam -= P->lam0;
@@ -191,7 +191,7 @@ static PJ_LP krovak_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal,
PJ *PROJECTION(krovak) {
double u0, n0, g;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/labrd.cpp b/src/projections/labrd.cpp
index c9dfdfc6..4fbcf460 100644
--- a/src/projections/labrd.cpp
+++ b/src/projections/labrd.cpp
@@ -105,7 +105,7 @@ static PJ_LP labrd_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, invers
PJ *PROJECTION(labrd) {
double Az, sinp, R, N, t;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/laea.cpp b/src/projections/laea.cpp
index 3d135864..2d19cab1 100644
--- a/src/projections/laea.cpp
+++ b/src/projections/laea.cpp
@@ -234,7 +234,7 @@ static PJ *destructor (PJ *P, int errlev) {
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->apa);
+ free (static_cast<struct pj_opaque*>(P->opaque)->apa);
return pj_default_destructor(P, errlev);
}
@@ -242,7 +242,7 @@ static PJ *destructor (PJ *P, int errlev) {
PJ *PROJECTION(laea) {
double t;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/lagrng.cpp b/src/projections/lagrng.cpp
index d37a00e6..1029bf8d 100644
--- a/src/projections/lagrng.cpp
+++ b/src/projections/lagrng.cpp
@@ -71,7 +71,7 @@ static PJ_LP lagrng_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver
PJ *PROJECTION(lagrng) {
double sin_phi1;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/lcc.cpp b/src/projections/lcc.cpp
index 91ffc511..525281f4 100644
--- a/src/projections/lcc.cpp
+++ b/src/projections/lcc.cpp
@@ -80,7 +80,7 @@ static PJ_LP lcc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse
PJ *PROJECTION(lcc) {
double cosphi, sinphi;
int secant;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc(1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc(1, sizeof (struct pj_opaque)));
if (nullptr == Q)
return pj_default_destructor(P, ENOMEM);
@@ -106,10 +106,10 @@ PJ *PROJECTION(lcc) {
double ml1, m1;
m1 = pj_msfn(sinphi, cosphi, P->es);
- ml1 = pj_tsfn(Q->phi1, sinphi, P->e);
- if( ml1 == 0 ) {
+ if( fabs(Q->phi1) == M_HALFPI ) {
return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90);
}
+ ml1 = pj_tsfn(Q->phi1, sinphi, P->e);
if (secant) { /* secant cone */
sinphi = sin(Q->phi2);
Q->n = log(m1 / pj_msfn(sinphi, cos(Q->phi2), P->es));
@@ -117,10 +117,10 @@ PJ *PROJECTION(lcc) {
// Not quite, but es is very close to 1...
return pj_default_destructor(P, PJD_ERR_INVALID_ECCENTRICITY);
}
- const double ml2 = pj_tsfn(Q->phi2, sinphi, P->e);
- if( ml2 == 0 ) {
- return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90);
+ if( fabs(Q->phi2) == M_HALFPI ) {
+ return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90);
}
+ const double ml2 = pj_tsfn(Q->phi2, sinphi, P->e);
const double denom = log(ml1 / ml2);
if( denom == 0 ) {
// Not quite, but es is very close to 1...
diff --git a/src/projections/lcca.cpp b/src/projections/lcca.cpp
index 51dd28aa..53646fc6 100644
--- a/src/projections/lcca.cpp
+++ b/src/projections/lcca.cpp
@@ -128,14 +128,14 @@ static PJ *destructor (PJ *P, int errlev) {
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor (P, errlev);
}
PJ *PROJECTION(lcca) {
double s2p0, N0, R0, tan0;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/loxim.cpp b/src/projections/loxim.cpp
index 2ee88037..64124bdd 100644
--- a/src/projections/loxim.cpp
+++ b/src/projections/loxim.cpp
@@ -56,7 +56,7 @@ static PJ_LP loxim_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers
PJ *PROJECTION(loxim) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/lsat.cpp b/src/projections/lsat.cpp
index f6114485..a811a3a6 100644
--- a/src/projections/lsat.cpp
+++ b/src/projections/lsat.cpp
@@ -158,7 +158,7 @@ static PJ_LP lsat_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse
PJ *PROJECTION(lsat) {
int land, path;
double lam, alf, esc, ess;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/merc.cpp b/src/projections/merc.cpp
index a77d7517..3a0ed7b4 100644
--- a/src/projections/merc.cpp
+++ b/src/projections/merc.cpp
@@ -10,45 +10,29 @@
PROJ_HEAD(merc, "Mercator") "\n\tCyl, Sph&Ell\n\tlat_ts=";
PROJ_HEAD(webmerc, "Web Mercator / Pseudo Mercator") "\n\tCyl, Ell\n\t";
-#define EPS10 1.e-10
-static double logtanpfpim1(double x) { /* log(tan(x/2 + M_FORTPI)) */
- if (fabs(x) <= DBL_EPSILON) {
- /* tan(M_FORTPI + .5 * x) can be approximated by 1.0 + x */
- return log1p(x);
- }
- return log(tan(M_FORTPI + .5 * x));
-}
-
static PJ_XY merc_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */
PJ_XY xy = {0.0,0.0};
- if (fabs(fabs(lp.phi) - M_HALFPI) <= EPS10) {
- proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
- return xy;
- }
xy.x = P->k0 * lp.lam;
- xy.y = - P->k0 * log(pj_tsfn(lp.phi, sin(lp.phi), P->e));
+ // Instead of calling tan and sin, call sin and cos which the compiler
+ // optimizes to a single call to sincos.
+ double sphi = sin(lp.phi);
+ double cphi = cos(lp.phi);
+ xy.y = P->k0 * (asinh(sphi/cphi) - P->e * atanh(P->e * sphi));
return xy;
}
static PJ_XY merc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */
PJ_XY xy = {0.0,0.0};
- if (fabs(fabs(lp.phi) - M_HALFPI) <= EPS10) {
- proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
- return xy;
-}
xy.x = P->k0 * lp.lam;
- xy.y = P->k0 * logtanpfpim1(lp.phi);
+ xy.y = P->k0 * asinh(tan(lp.phi));
return xy;
}
static PJ_LP merc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */
PJ_LP lp = {0.0,0.0};
- if ((lp.phi = pj_phi2(P->ctx, exp(- xy.y / P->k0), P->e)) == HUGE_VAL) {
- proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
- return lp;
-}
+ lp.phi = atan(pj_sinhpsi2tanphi(P->ctx, sinh(xy.y / P->k0), P->e));
lp.lam = xy.x / P->k0;
return lp;
}
diff --git a/src/projections/misrsom.cpp b/src/projections/misrsom.cpp
index 71116e1e..d7e199f2 100644
--- a/src/projections/misrsom.cpp
+++ b/src/projections/misrsom.cpp
@@ -178,7 +178,7 @@ PJ *PROJECTION(misrsom) {
int path;
double lam, alf, esc, ess;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/mod_ster.cpp b/src/projections/mod_ster.cpp
index c7a8e899..0c30b7b6 100644
--- a/src/projections/mod_ster.cpp
+++ b/src/projections/mod_ster.cpp
@@ -134,7 +134,7 @@ PJ *PROJECTION(mil_os) {
{0.019430, 0.}
};
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -157,7 +157,7 @@ PJ *PROJECTION(lee_os) {
{-0.0088162, -0.00617325}
};
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -182,7 +182,7 @@ PJ *PROJECTION(gs48) {
{0.075528, 0.}
};
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -217,7 +217,7 @@ PJ *PROJECTION(alsk) {
{ .3660976, -.2937382}
};
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -265,7 +265,7 @@ PJ *PROJECTION(gs50) {
{-.0225161, .0853673}
};
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/moll.cpp b/src/projections/moll.cpp
index 5d4f7825..4864c8e1 100644
--- a/src/projections/moll.cpp
+++ b/src/projections/moll.cpp
@@ -77,7 +77,7 @@ static PJ * setup(PJ *P, double p) {
PJ *PROJECTION(moll) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -87,7 +87,7 @@ PJ *PROJECTION(moll) {
PJ *PROJECTION(wag4) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -96,7 +96,7 @@ PJ *PROJECTION(wag4) {
}
PJ *PROJECTION(wag5) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/natearth.cpp b/src/projections/natearth.cpp
index 5c096605..e1f71089 100644
--- a/src/projections/natearth.cpp
+++ b/src/projections/natearth.cpp
@@ -82,7 +82,7 @@ static PJ_LP natearth_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inv
}
}
if( i == 0 )
- pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );
+ proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT );
lp.phi = yc;
/* longitude */
diff --git a/src/projections/natearth2.cpp b/src/projections/natearth2.cpp
index d149ca85..e4516a0a 100644
--- a/src/projections/natearth2.cpp
+++ b/src/projections/natearth2.cpp
@@ -76,7 +76,7 @@ static PJ_LP natearth2_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, in
}
}
if( i == 0 )
- pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );
+ proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT );
lp.phi = yc;
/* longitude */
diff --git a/src/projections/nsper.cpp b/src/projections/nsper.cpp
index 903946b9..951111ac 100644
--- a/src/projections/nsper.cpp
+++ b/src/projections/nsper.cpp
@@ -180,7 +180,7 @@ static PJ *setup(PJ *P) {
PJ *PROJECTION(nsper) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -194,7 +194,7 @@ PJ *PROJECTION(nsper) {
PJ *PROJECTION(tpers) {
double omega, gamma;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/ob_tran.cpp b/src/projections/ob_tran.cpp
index 7cf1cf98..86798e0a 100644
--- a/src/projections/ob_tran.cpp
+++ b/src/projections/ob_tran.cpp
@@ -141,14 +141,15 @@ static ARGS ob_tran_target_params (paralist *params) {
if (argc < 2)
return args;
- /* all args except the proj_ob_tran */
- args.argv = static_cast<char**>(pj_calloc (argc - 1, sizeof (char *)));
+ /* all args except the proj=ob_tran */
+ args.argv = static_cast<char**>(calloc (argc - 1, sizeof (char *)));
if (nullptr==args.argv)
return args;
- /* Copy all args *except* the proj=ob_tran arg to the argv array */
+ /* Copy all args *except* the proj=ob_tran or inv arg to the argv array */
for (i = 0; params != nullptr; params = params->next) {
- if (0==strcmp (params->param, "proj=ob_tran"))
+ if (0==strcmp (params->param, "proj=ob_tran") ||
+ 0==strcmp (params->param, "inv") )
continue;
args.argv[i++] = params->param;
}
@@ -160,7 +161,7 @@ static ARGS ob_tran_target_params (paralist *params) {
continue;
args.argv[i] += 2;
if (strcmp(args.argv[i], "proj=ob_tran") == 0 ) {
- pj_dealloc (args.argv);
+ free (args.argv);
args.argc = 0;
args.argv = nullptr;
}
@@ -177,7 +178,7 @@ PJ *PROJECTION(ob_tran) {
ARGS args;
PJ *R; /* projection to rotate */
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return destructor(P, ENOMEM);
@@ -194,8 +195,8 @@ PJ *PROJECTION(ob_tran) {
if (args.argv == nullptr ) {
return destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ);
}
- R = pj_init_ctx (pj_get_ctx(P), args.argc, args.argv);
- pj_dealloc (args.argv);
+ R = proj_create_argv (P->ctx, args.argc, args.argv);
+ free (args.argv);
if (nullptr==R)
return destructor (P, PJD_ERR_UNKNOWN_PROJECTION_ID);
diff --git a/src/projections/ocea.cpp b/src/projections/ocea.cpp
index de9838cb..c78e1ebc 100644
--- a/src/projections/ocea.cpp
+++ b/src/projections/ocea.cpp
@@ -52,7 +52,7 @@ static PJ_LP ocea_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse
PJ *PROJECTION(ocea) {
double phi_1, phi_2, lam_1, lam_2, lonz, alpha;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/oea.cpp b/src/projections/oea.cpp
index 61fb0647..46c00d16 100644
--- a/src/projections/oea.cpp
+++ b/src/projections/oea.cpp
@@ -58,7 +58,7 @@ static PJ_LP oea_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse
PJ *PROJECTION(oea) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/omerc.cpp b/src/projections/omerc.cpp
index e9f3b833..90067cc3 100644
--- a/src/projections/omerc.cpp
+++ b/src/projections/omerc.cpp
@@ -126,7 +126,7 @@ PJ *PROJECTION(omerc) {
gamma0, lamc=0, lam1=0, lam2=0, phi1=0, phi2=0, alpha_c=0;
int alp, gam, no_off = 0;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/ortho.cpp b/src/projections/ortho.cpp
index 8dcfb53c..4417dac7 100644
--- a/src/projections/ortho.cpp
+++ b/src/projections/ortho.cpp
@@ -273,13 +273,13 @@ static PJ_LP ortho_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inver
return lp;
}
}
- pj_ctx_set_errno(P->ctx, PJD_ERR_NON_CONVERGENT);
+ proj_context_errno_set(P->ctx, PJD_ERR_NON_CONVERGENT);
return lp;
}
PJ *PROJECTION(ortho) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/patterson.cpp b/src/projections/patterson.cpp
index 71099cdb..32544580 100644
--- a/src/projections/patterson.cpp
+++ b/src/projections/patterson.cpp
@@ -100,7 +100,7 @@ static PJ_LP patterson_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, in
}
}
if( i == 0 )
- pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );
+ proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT );
lp.phi = yc;
/* longitude */
diff --git a/src/projections/poly.cpp b/src/projections/poly.cpp
index 10d93ed2..4ea95cc7 100644
--- a/src/projections/poly.cpp
+++ b/src/projections/poly.cpp
@@ -147,14 +147,14 @@ static PJ *destructor(PJ *P, int errlev) {
return pj_default_destructor (P, errlev);
if (static_cast<struct pj_opaque*>(P->opaque)->en)
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor(P, errlev);
}
PJ *PROJECTION(poly) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
diff --git a/src/projections/putp3.cpp b/src/projections/putp3.cpp
index c2df20e8..09763851 100644
--- a/src/projections/putp3.cpp
+++ b/src/projections/putp3.cpp
@@ -38,7 +38,7 @@ static PJ_LP putp3_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers
PJ *PROJECTION(putp3) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -53,7 +53,7 @@ PJ *PROJECTION(putp3) {
}
PJ *PROJECTION(putp3p) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/putp4p.cpp b/src/projections/putp4p.cpp
index 365f7c1b..8df18972 100644
--- a/src/projections/putp4p.cpp
+++ b/src/projections/putp4p.cpp
@@ -45,7 +45,7 @@ static PJ_LP putp4p_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver
PJ *PROJECTION(putp4p) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -62,7 +62,7 @@ PJ *PROJECTION(putp4p) {
PJ *PROJECTION(weren) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/putp5.cpp b/src/projections/putp5.cpp
index 1847e7a9..5e70382d 100644
--- a/src/projections/putp5.cpp
+++ b/src/projections/putp5.cpp
@@ -43,7 +43,7 @@ static PJ_LP putp5_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers
PJ *PROJECTION(putp5) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -60,7 +60,7 @@ PJ *PROJECTION(putp5) {
PJ *PROJECTION(putp5p) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/putp6.cpp b/src/projections/putp6.cpp
index db334ff9..da8c0a7c 100644
--- a/src/projections/putp6.cpp
+++ b/src/projections/putp6.cpp
@@ -59,7 +59,7 @@ static PJ_LP putp6_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers
PJ *PROJECTION(putp6) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
@@ -79,7 +79,7 @@ PJ *PROJECTION(putp6) {
PJ *PROJECTION(putp6p) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/qsc.cpp b/src/projections/qsc.cpp
index 98e3755e..dd9ce965 100644
--- a/src/projections/qsc.cpp
+++ b/src/projections/qsc.cpp
@@ -377,7 +377,7 @@ static PJ_LP qsc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse
PJ *PROJECTION(qsc) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/robin.cpp b/src/projections/robin.cpp
index 8b646502..6a1405b6 100644
--- a/src/projections/robin.cpp
+++ b/src/projections/robin.cpp
@@ -138,7 +138,7 @@ static PJ_LP robin_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers
break;
}
if( iters == 0 )
- pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );
+ proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT );
lp.phi = (5 * i + t) * DEG_TO_RAD;
if (xy.y < 0.) lp.phi = -lp.phi;
lp.lam /= V(X[i], t);
diff --git a/src/projections/rouss.cpp b/src/projections/rouss.cpp
index f5a8f12f..2eb13b3d 100644
--- a/src/projections/rouss.cpp
+++ b/src/projections/rouss.cpp
@@ -93,7 +93,7 @@ static PJ *destructor (PJ *P, int errlev) {
return pj_default_destructor (P, errlev);
if (static_cast<struct pj_opaque*>(P->opaque)->en)
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor (P, ENOMEM);
}
@@ -102,7 +102,7 @@ static PJ *destructor (PJ *P, int errlev) {
PJ *PROJECTION(rouss) {
double N0, es2, t, t2, R_R0_2, R_R0_4;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/rpoly.cpp b/src/projections/rpoly.cpp
index b065861f..e3f09c59 100644
--- a/src/projections/rpoly.cpp
+++ b/src/projections/rpoly.cpp
@@ -44,7 +44,7 @@ static PJ_XY rpoly_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forwar
PJ *PROJECTION(rpoly) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/sch.cpp b/src/projections/sch.cpp
index 7548039d..359e8efc 100644
--- a/src/projections/sch.cpp
+++ b/src/projections/sch.cpp
@@ -184,7 +184,7 @@ static PJ *setup(PJ *P) { /* general initialization */
PJ *PROJECTION(sch) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/sconics.cpp b/src/projections/sconics.cpp
index f305e291..c12b05a2 100644
--- a/src/projections/sconics.cpp
+++ b/src/projections/sconics.cpp
@@ -117,7 +117,7 @@ static PJ_LP sconics_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, (and ellipsoi
static PJ *setup(PJ *P, enum Type type) {
double del, cs;
int err;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/somerc.cpp b/src/projections/somerc.cpp
index fe6477fa..a184500c 100644
--- a/src/projections/somerc.cpp
+++ b/src/projections/somerc.cpp
@@ -71,7 +71,7 @@ static PJ_LP somerc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inver
PJ *PROJECTION(somerc) {
double cp, phip0, sp;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/stere.cpp b/src/projections/stere.cpp
index abc4aa13..ad1caae2 100644
--- a/src/projections/stere.cpp
+++ b/src/projections/stere.cpp
@@ -86,7 +86,10 @@ static PJ_XY stere_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forwar
sinphi = -sinphi;
/*-fallthrough*/
case N_POLE:
- xy.x = Q->akm1 * pj_tsfn (lp.phi, sinphi, P->e);
+ if( fabs(lp.phi - M_HALFPI) < 1e-15 )
+ xy.x = 0;
+ else
+ xy.x = Q->akm1 * pj_tsfn (lp.phi, sinphi, P->e);
xy.y = - xy.x * coslam;
break;
}
@@ -299,7 +302,7 @@ static PJ *setup(PJ *P) { /* general initialization */
PJ *PROJECTION(stere) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -312,7 +315,7 @@ PJ *PROJECTION(stere) {
PJ *PROJECTION(ups) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/sterea.cpp b/src/projections/sterea.cpp
index 55404c86..4dd22d2f 100644
--- a/src/projections/sterea.cpp
+++ b/src/projections/sterea.cpp
@@ -93,14 +93,14 @@ static PJ *destructor (PJ *P, int errlev) {
if (nullptr==P->opaque)
return pj_default_destructor (P, errlev);
- pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
+ free (static_cast<struct pj_opaque*>(P->opaque)->en);
return pj_default_destructor (P, errlev);
}
PJ *PROJECTION(sterea) {
double R;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
diff --git a/src/projections/sts.cpp b/src/projections/sts.cpp
index cbc36b7d..75190e85 100644
--- a/src/projections/sts.cpp
+++ b/src/projections/sts.cpp
@@ -70,7 +70,7 @@ static PJ *setup(PJ *P, double p, double q, int mode) {
PJ *PROJECTION(fouc) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
@@ -80,7 +80,7 @@ PJ *PROJECTION(fouc) {
PJ *PROJECTION(kav5) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
@@ -91,7 +91,7 @@ PJ *PROJECTION(kav5) {
PJ *PROJECTION(qua_aut) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
@@ -101,7 +101,7 @@ PJ *PROJECTION(qua_aut) {
PJ *PROJECTION(mbt_s) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/tmerc.cpp b/src/projections/tmerc.cpp
index 69f4d352..8f897061 100644
--- a/src/projections/tmerc.cpp
+++ b/src/projections/tmerc.cpp
@@ -89,7 +89,7 @@ static PJ_XY approx_e_fwd (PJ_LP lp, PJ *P)
if( lp.lam < -M_HALFPI || lp.lam > M_HALFPI ) {
xy.x = HUGE_VAL;
xy.y = HUGE_VAL;
- pj_ctx_set_errno( P->ctx, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT );
+ proj_context_errno_set( P->ctx, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT );
return xy;
}
@@ -115,25 +115,11 @@ static PJ_XY approx_e_fwd (PJ_LP lp, PJ *P)
return (xy);
}
-static PJ_XY approx_s_fwd (PJ_LP lp, PJ *P) {
+static PJ_XY tmerc_spherical_fwd (PJ_LP lp, PJ *P) {
PJ_XY xy = {0.0,0.0};
double b, cosphi;
const auto *Q = &(static_cast<struct tmerc_data*>(P->opaque)->approx);
- /*
- * Fail if our longitude is more than 90 degrees from the
- * central meridian since the results are essentially garbage.
- * Is error -20 really an appropriate return value?
- *
- * http://trac.osgeo.org/proj/ticket/5
- */
- if( lp.lam < -M_HALFPI || lp.lam > M_HALFPI ) {
- xy.x = HUGE_VAL;
- xy.y = HUGE_VAL;
- pj_ctx_set_errno( P->ctx, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT );
- return xy;
- }
-
cosphi = cos(lp.phi);
b = cosphi * sin (lp.lam);
if (fabs (fabs (b) - 1.) <= EPS10) {
@@ -145,7 +131,12 @@ static PJ_XY approx_s_fwd (PJ_LP lp, PJ *P) {
xy.y = cosphi * cos (lp.lam) / sqrt (1. - b * b);
b = fabs ( xy.y );
- if (b >= 1.) {
+ if (cosphi == 1 && (lp.lam < -M_HALFPI || lp.lam > M_HALFPI) ) {
+ /* Helps to be able to roundtrip |longitudes| > 90 at lat=0 */
+ /* We could also map to -M_PI ... */
+ xy.y = M_PI;
+ }
+ else if (b >= 1.) {
if ((b - 1.) > EPS10) {
proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
return xy;
@@ -192,7 +183,7 @@ static PJ_LP approx_e_inv (PJ_XY xy, PJ *P) {
return lp;
}
-static PJ_LP approx_s_inv (PJ_XY xy, PJ *P) {
+static PJ_LP tmerc_spherical_inv (PJ_XY xy, PJ *P) {
PJ_LP lp = {0.0, 0.0};
double h, g;
const auto *Q = &(static_cast<struct tmerc_data*>(P->opaque)->approx);
@@ -203,11 +194,13 @@ static PJ_LP approx_s_inv (PJ_XY xy, PJ *P) {
return proj_coord_error().lp;
}
g = .5 * (h - 1. / h);
- h = cos (P->phi0 + xy.y / Q->esp);
+ /* D, as in equation 8-8 of USGS "Map Projections - A Working Manual" */
+ const double D = P->phi0 + xy.y / Q->esp;
+ h = cos (D);
lp.phi = asin(sqrt((1. - h * h) / (1. + g * g)));
/* Make sure that phi is on the correct hemisphere when false northing is used */
- if (xy.y < 0. && -lp.phi+P->phi0 < 0.0) lp.phi = -lp.phi;
+ lp.phi = copysign(lp.phi, D);
lp.lam = (g != 0.0 || h != 0.0) ? atan2 (g, h) : 0.;
return lp;
@@ -221,7 +214,7 @@ static PJ *destructor(PJ *P, int errlev) {
if (nullptr==P->opaque)
return pj_default_destructor(P, errlev);
- pj_dealloc (static_cast<struct tmerc_data*>(P->opaque)->approx.en);
+ free (static_cast<struct tmerc_data*>(P->opaque)->approx.en);
return pj_default_destructor(P, errlev);
}
@@ -592,7 +585,7 @@ static PJ_LP auto_e_inv (PJ_XY xy, PJ *P) {
static PJ *setup(PJ *P, TMercAlgo eAlg) {
- struct tmerc_data *Q = static_cast<struct tmerc_data*>(pj_calloc (1, sizeof (struct tmerc_data)));
+ struct tmerc_data *Q = static_cast<struct tmerc_data*>(calloc (1, sizeof (struct tmerc_data)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -609,8 +602,8 @@ static PJ *setup(PJ *P, TMercAlgo eAlg) {
return nullptr;
if( P->es == 0 )
{
- P->inv = approx_s_inv;
- P->fwd = approx_s_fwd;
+ P->inv = tmerc_spherical_inv;
+ P->fwd = tmerc_spherical_fwd;
}
else
{
@@ -679,7 +672,7 @@ static bool getAlgoFromParams(PJ* P, TMercAlgo& algo)
else
{
pj_load_ini(P->ctx); // if not already done
- pj_ctx_set_errno(P->ctx, 0); // reset error in case proj.ini couldn't be found
+ proj_context_errno_set(P->ctx, 0); // reset error in case proj.ini couldn't be found
algo = P->ctx->defaultTmercAlgo;
}
diff --git a/src/projections/tobmerc.cpp b/src/projections/tobmerc.cpp
index a1616036..f05a9b6b 100644
--- a/src/projections/tobmerc.cpp
+++ b/src/projections/tobmerc.cpp
@@ -9,27 +9,24 @@
PROJ_HEAD(tobmerc, "Tobler-Mercator") "\n\tCyl, Sph";
-#define EPS10 1.e-10
-static double logtanpfpim1(double x) { /* log(tan(x/2 + M_FORTPI)) */
- if (fabs(x) <= DBL_EPSILON) {
- /* tan(M_FORTPI + .5 * x) can be approximated by 1.0 + x */
- return log1p(x);
- }
- return log(tan(M_FORTPI + .5 * x));
-}
-
static PJ_XY tobmerc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */
PJ_XY xy = {0.0, 0.0};
double cosphi;
- if (fabs(fabs(lp.phi) - M_HALFPI) <= EPS10) {
+ if (fabs(lp.phi) >= M_HALFPI) {
+ // builtins.gie tests "Test expected failure at the poles:". However
+ // given that M_HALFPI is strictly less than pi/2 in double precision,
+ // it's not clear why shouldn't just return a large result for xy.y (and
+ // it's not even that large, merely 38.025...). Even if the logic was
+ // such that phi was strictly equal to pi/2, allowing xy.y = inf would be
+ // a reasonable result.
proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
return xy;
}
cosphi = cos(lp.phi);
xy.x = P->k0 * lp.lam * cosphi * cosphi;
- xy.y = P->k0 * logtanpfpim1(lp.phi);
+ xy.y = P->k0 * asinh(tan(lp.phi));
return xy;
}
diff --git a/src/projections/tpeqd.cpp b/src/projections/tpeqd.cpp
index 58aeb8e1..90efb395 100644
--- a/src/projections/tpeqd.cpp
+++ b/src/projections/tpeqd.cpp
@@ -64,7 +64,7 @@ static PJ_LP tpeqd_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers
PJ *PROJECTION(tpeqd) {
double lam_1, lam_2, phi_1, phi_2, A12;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/urm5.cpp b/src/projections/urm5.cpp
index 499644d2..c3021841 100644
--- a/src/projections/urm5.cpp
+++ b/src/projections/urm5.cpp
@@ -30,7 +30,7 @@ static PJ_XY urm5_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward
PJ *PROJECTION(urm5) {
double alpha, t;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/urmfps.cpp b/src/projections/urmfps.cpp
index 3f9fdf23..5d689f9f 100644
--- a/src/projections/urmfps.cpp
+++ b/src/projections/urmfps.cpp
@@ -47,7 +47,7 @@ static PJ *setup(PJ *P) {
PJ *PROJECTION(urmfps) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
@@ -66,7 +66,7 @@ PJ *PROJECTION(urmfps) {
PJ *PROJECTION(wag1) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/vandg2.cpp b/src/projections/vandg2.cpp
index 223620d6..cd7e7b6c 100644
--- a/src/projections/vandg2.cpp
+++ b/src/projections/vandg2.cpp
@@ -53,7 +53,7 @@ static PJ_XY vandg2_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forwa
PJ *PROJECTION(vandg2) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
@@ -65,7 +65,7 @@ PJ *PROJECTION(vandg2) {
}
PJ *PROJECTION(vandg3) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/wag3.cpp b/src/projections/wag3.cpp
index 33313cdb..ed3250ef 100644
--- a/src/projections/wag3.cpp
+++ b/src/projections/wag3.cpp
@@ -35,7 +35,7 @@ static PJ_LP wag3_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse
PJ *PROJECTION(wag3) {
double ts;
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
diff --git a/src/projections/wink1.cpp b/src/projections/wink1.cpp
index d097978f..f4ffafe3 100644
--- a/src/projections/wink1.cpp
+++ b/src/projections/wink1.cpp
@@ -33,7 +33,7 @@ static PJ_LP wink1_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers
PJ *PROJECTION(wink1) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/projections/wink2.cpp b/src/projections/wink2.cpp
index d457f842..b5b1e812 100644
--- a/src/projections/wink2.cpp
+++ b/src/projections/wink2.cpp
@@ -53,7 +53,7 @@ static PJ_LP wink2_s_inverse(PJ_XY xy, PJ *P)
PJ *PROJECTION(wink2) {
- struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
+ struct pj_opaque *Q = static_cast<struct pj_opaque*>(calloc (1, sizeof (struct pj_opaque)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = Q;
diff --git a/src/strerrno.cpp b/src/strerrno.cpp
index 5ae0d7e1..3d0131c6 100644
--- a/src/strerrno.cpp
+++ b/src/strerrno.cpp
@@ -1,4 +1,4 @@
-/* list of projection system pj_errno values */
+/* list of projection system errno values */
#include <stddef.h>
#include <stdio.h>
@@ -27,7 +27,7 @@ pj_err_list[] = {
"invalid x or y", /* -15 */
"improperly formed DMS value", /* -16 */
"non-convergent inverse meridional dist", /* -17 */
- "non-convergent inverse phi2", /* -18 */
+ "non-convergent sinh(psi) to tan(phi)", /* -18 */
"acos/asin: |arg| >1.+1e-14", /* -19 */
"tolerance condition error", /* -20 */
"conic lat_1 = -lat_2", /* -21 */
@@ -74,10 +74,11 @@ pj_err_list[] = {
"network error", /* -62 */
/* When adding error messages, remember to update ID defines in
- projects.h, and transient_error array in pj_transform */
+ src/proj_internal.h and src/apps/gie.cpp */
};
-char *pj_strerrno(int err) {
+
+const char* proj_errno_string(int err) {
const int max_error = 9999;
static char note[50];
size_t adjusted_err;
@@ -98,7 +99,7 @@ char *pj_strerrno(int err) {
#endif
}
- /* PROJ.4 error codes are negative: -1 to -9999 */
+ /* PROJ error codes are negative: -1 to -9999 */
adjusted_err = err < -max_error ? max_error : -err - 1;
if (adjusted_err < (sizeof(pj_err_list) / sizeof(char *)))
return (char *)pj_err_list[adjusted_err];
@@ -107,7 +108,3 @@ char *pj_strerrno(int err) {
(err > -max_error) ? err: -max_error);
return note;
}
-
-const char* proj_errno_string(int err) {
- return pj_strerrno(err);
-}
diff --git a/src/tests/multistresstest.cpp b/src/tests/multistresstest.cpp
index 33d2d738..6b7099ce 100644
--- a/src/tests/multistresstest.cpp
+++ b/src/tests/multistresstest.cpp
@@ -30,11 +30,7 @@
#include <stdlib.h>
#include <string.h>
-#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#endif
-
-#include "proj_api.h"
+#include "proj.h"
#ifdef _WIN32
#include <windows.h>
@@ -51,8 +47,8 @@ typedef struct {
const char *src_def;
const char *dst_def;
- double src_x, src_y, src_z;
- double dst_x, dst_y, dst_z;
+ PJ_COORD src;
+ PJ_COORD dst;
int dst_error;
int skip;
@@ -62,125 +58,120 @@ static TestItem test_list[] = {
{
"+proj=utm +zone=11 +datum=WGS84",
"+proj=latlong +datum=WGS84",
- 150000.0, 3000000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 3000000.0, 0.0, 0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=utm +zone=11 +datum=NAD83",
"+proj=latlong +datum=NAD27",
- 150000.0, 3000000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 3000000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=utm +zone=11 +datum=NAD83",
"+proj=latlong +nadgrids=@null +ellps=WGS84",
- 150000.0, 3000000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 3000000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=utm +zone=11 +datum=WGS84",
"+proj=merc +datum=potsdam",
- 150000.0, 3000000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 3000000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=latlong +nadgrids=nzgd2kgrid0005.gsb",
"+proj=latlong +datum=WGS84",
- 150000.0, 3000000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 3000000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=latlong +nadgrids=nzgd2kgrid0005.gsb",
"+proj=latlong +datum=WGS84",
- 170 * DEG_TO_RAD, -40 * DEG_TO_RAD, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(170, -40, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=latlong +ellps=GRS80 +towgs84=2,3,5",
"+proj=latlong +ellps=intl +towgs84=10,12,15",
- 170 * DEG_TO_RAD, -40 * DEG_TO_RAD, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(170, -40, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=eqc +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ",
"+proj=stere +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ",
- 150000.0, 250000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 250000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=cea +lat_ts=11 +lon_0=12 +y_0=200000 +datum=WGS84 ",
"+proj=merc +lon_0=12 +k=0.999 +x_0=100000 +y_0=200000 +datum=WGS84 ",
- 150000.0, 250000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 250000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=bonne +lat_1=11 +lon_0=12 +y_0=200000 +datum=WGS84 ",
"+proj=cass +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ",
- 150000.0, 250000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 250000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=nzmg +lat_0=11 +lon_0=12 +y_0=200000 +datum=WGS84 ",
"+proj=gnom +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ",
- 150000.0, 250000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 250000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=ortho +lat_0=11 +lon_0=12 +y_0=200000 +datum=WGS84 ",
"+proj=laea +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ",
- 150000.0, 250000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 250000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=aeqd +lat_0=11 +lon_0=12 +y_0=200000 +datum=WGS84 ",
"+proj=eqdc +lat_1=20 +lat_2=5 +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ",
- 150000.0, 250000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 250000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+proj=mill +lat_0=11 +lon_0=12 +y_0=200000 +datum=WGS84 ",
"+proj=moll +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ",
- 150000.0, 250000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 250000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
"+init=epsg:3309",
"+init=epsg:4326",
- 150000.0, 30000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 30000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
},
{
/* Bad projection (invalid ellipsoid parameter +R_A=0) */
"+proj=utm +zone=11 +datum=WGS84",
"+proj=merc +datum=potsdam +R_A=0",
- 150000.0, 3000000.0, 0.0,
- 0.0, 0.0, 0.0,
+ proj_coord(150000.0, 3000000.0, 0.0, 0.0),
+ proj_coord(0.0, 0.0, 0.0, 0.0),
0, 0
}
};
static volatile int active_thread_count = 0;
-static projPJ custom_pj_init_plus_ctx(projCtx ctx, const char* def)
-{
- return pj_init_plus_ctx(ctx, def);
-}
-
/************************************************************************/
/* TestThread() */
/************************************************************************/
@@ -195,11 +186,10 @@ static void TestThread()
/* -------------------------------------------------------------------- */
/* Initialize coordinate system definitions. */
/* -------------------------------------------------------------------- */
- projPJ *src_pj_list, *dst_pj_list;
- projCtx ctx = pj_ctx_alloc();
+ PJ **pj_list;
+ PJ_CONTEXT *ctx = proj_context_create();
- src_pj_list = (projPJ *) calloc(test_count,sizeof(projPJ));
- dst_pj_list = (projPJ *) calloc(test_count,sizeof(projPJ));
+ pj_list = (PJ **) calloc(test_count,sizeof(PJ*));
if(!reinit_every_iteration)
{
@@ -207,8 +197,9 @@ static void TestThread()
{
TestItem *test = test_list + i;
- src_pj_list[i] = custom_pj_init_plus_ctx( ctx, test->src_def );
- dst_pj_list[i] = custom_pj_init_plus_ctx( ctx, test->dst_def );
+ pj_list[i] = proj_create_crs_to_crs(
+ ctx, test->src_def, test->dst_def, nullptr
+ );
}
}
@@ -221,28 +212,23 @@ static void TestThread()
for( i = 0; i < test_count; i++ )
{
TestItem *test = test_list + i;
- double x, y, z;
- int error;
-
- x = test->src_x;
- y = test->src_y;
- z = test->src_z;
if( reinit_every_iteration )
{
- src_pj_list[i] = custom_pj_init_plus_ctx( ctx, test->src_def );
- dst_pj_list[i] = custom_pj_init_plus_ctx( ctx, test->dst_def );
+ proj_context_use_proj4_init_rules(nullptr, true);
+ pj_list[i] = proj_create_crs_to_crs(
+ ctx, test->src_def, test->dst_def, nullptr
+ );
{
- int skipTest = (src_pj_list[i] == nullptr || dst_pj_list[i] == nullptr);
+ int skipTest = (pj_list[i] == nullptr);
if ( skipTest != test->skip )
fprintf( stderr, "Threaded projection initialization does not match unthreaded initialization\n" );
if (skipTest)
{
- pj_free( src_pj_list[i] );
- pj_free( dst_pj_list[i] );
+ proj_destroy( pj_list[i] );
continue;
}
}
@@ -251,31 +237,32 @@ static void TestThread()
if ( test->skip )
continue;
- error = pj_transform( src_pj_list[i], dst_pj_list[i], 1, 0,
- &x, &y, &z );
+ PJ_COORD out = proj_trans(pj_list[i], PJ_FWD, test->src);
+ int error = proj_errno(pj_list[i]);
if( error != test->dst_error )
{
fprintf( stderr, "Got error %d, expected %d\n",
error, test->dst_error );
}
+ proj_errno_reset(pj_list[i]);
- if( x != test->dst_x || y != test->dst_y || z != test->dst_z )
+ if ( out.xyz.x != test->dst.xyz.x || out.xyz.y != test->dst.xyz.y || out.xyz.z != test->dst.xyz.z)
+ //if( x != test->dst_x || y != test->dst_y || z != test->dst_z )
{
fprintf( stderr,
"Got %.15g,%.15g,%.15g\n"
"Expected %.15g,%.15g,%.15g\n"
"Diff %.15g,%.15g,%.15g\n",
- x, y, z,
- test->dst_x, test->dst_y, test->dst_z,
- x-test->dst_x, y-test->dst_y, z-test->dst_z);
+ out.xyz.x, out.xyz.y, out.xyz.z,
+ test->dst.xyz.x, test->dst.xyz.y, test->dst.xyz.z,
+ out.xyz.x-test->dst.xyz.x, out.xyz.y-test->dst.xyz.y, out.xyz.z-test->dst.xyz.z);
}
if( reinit_every_iteration )
{
- pj_free( src_pj_list[i] );
- pj_free( dst_pj_list[i] );
+ proj_destroy( pj_list[i] );
}
}
}
@@ -287,15 +274,13 @@ static void TestThread()
{
for( i = 0; i < test_count; i++ )
{
- pj_free( src_pj_list[i] );
- pj_free( dst_pj_list[i] );
+ proj_destroy( pj_list[i] );
}
}
- free( src_pj_list );
- free( dst_pj_list );
+ free( pj_list );
- pj_ctx_free( ctx );
+ proj_context_destroy( ctx );
printf( "%d iterations of the %d tests complete in thread X\n",
repeat_count, test_count );
@@ -349,43 +334,32 @@ static int do_main(void)
{
TestItem *test = test_list + i;
- projPJ src_pj, dst_pj;
+ PJ *pj;
- src_pj = custom_pj_init_plus_ctx( pj_get_default_ctx(), test->src_def );
- dst_pj = custom_pj_init_plus_ctx( pj_get_default_ctx(), test->dst_def );
-
- if( src_pj == nullptr )
- {
- printf( "Unable to translate:\n%s\n", test->src_def );
- test->skip = 1;
- pj_free (dst_pj);
- continue;
- }
+ proj_context_use_proj4_init_rules(nullptr, true);
+ pj = proj_create_crs_to_crs(
+ nullptr, test->src_def, test->dst_def, nullptr
+ );
- if( dst_pj == nullptr )
+ if( pj == nullptr )
{
- printf( "Unable to translate:\n%s\n", test->dst_def );
+ printf( "Unable to translate:\n%s\n or\n%s\n", test->src_def, test->dst_def );
test->skip = 1;
- pj_free (src_pj);
+ proj_destroy(pj);
continue;
}
- test->dst_x = test->src_x;
- test->dst_y = test->src_y;
- test->dst_z = test->src_z;
- test->dst_error = pj_transform( src_pj, dst_pj, 1, 0,
- &(test->dst_x),
- &(test->dst_y),
- &(test->dst_z) );
+ PJ_COORD out = proj_trans(pj, PJ_FWD, test->src);
+ test->dst = out;
+ test->dst_error = proj_errno(pj);
- pj_free( src_pj );
- pj_free( dst_pj );
+ proj_destroy(pj);
test->skip = 0;
-#ifdef notdef
- printf( "Test %d - output %.14g,%.14g,%g\n", i, test->dst_x, test->dst_y, test->dst_z );
+#ifdef nodef
+ printf( "Test %d - output %.14g,%.14g,%g\n", i, test->dst.xyz.x, test->dst.xyz.y, test->dst.xyz.z );
#endif
}
diff --git a/src/tests/test228.cpp b/src/tests/test228.cpp
deleted file mode 100644
index 8ae17c87..00000000
--- a/src/tests/test228.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/******************************************************************************
- *
- * Project: PROJ
- * Purpose: Test
- * Author: Even Rouault <even dot rouault at spatialys dot com>
- *
- ******************************************************************************
- * Copyright (c) 2014, Even Rouault <even dot rouault at spatialys dot com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ****************************************************************************/
-
-#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#endif
-
-#include "proj_api.h"
-#include <stdio.h> /* for printf declaration */
-
-
-#ifdef _WIN32
-
-int main(int argc, char* argv[])
-{
- printf("Test not yet ported on Win32\n");
- return 0;
-}
-
-#else
-
-#include <pthread.h>
-#include <stdio.h>
-#include <assert.h>
-#include <unistd.h>
-
-static volatile int run = 0;
-static volatile int started = 0;
-
-static void* thread_main(void* unused)
-{
- projCtx p_proj_ctxt;
- projPJ p_WGS84_proj;
- projPJ p_OSGB36_proj;
- (void)unused;
-
- __sync_add_and_fetch(&started, 1);
- while(run == 0);
-
- p_proj_ctxt=pj_ctx_alloc();
- p_WGS84_proj=pj_init_plus_ctx(p_proj_ctxt,"+proj=longlat "
- "+ellps=WGS84 +datum=WGS84");
- p_OSGB36_proj=pj_init_plus_ctx(p_proj_ctxt,
- "+proj=longlat +ellps=airy +datum=OSGB36 +nadgrids=OSTN15_NTv2_OSGBtoETRS.gsb");
-
- while(run)
- {
- double x, y;
- int proj_ret;
-
- x = -5.2*DEG_TO_RAD;
- y = 50*DEG_TO_RAD;
- proj_ret = pj_transform(p_WGS84_proj,
- p_OSGB36_proj, 1, 1, &x, &y, nullptr );
- x *= RAD_TO_DEG;
- y *= RAD_TO_DEG;
- /*printf("%.18f %.18f\n", x, y); */
- assert(proj_ret == 0);
- assert(fabs(x - -5.198965207267856492) < 1e-15);
- assert(fabs(y - 49.999396074140378232) < 1e-15);
- }
-
- pj_free (p_OSGB36_proj);
- pj_free (p_WGS84_proj);
- return nullptr;
-}
-
-int main()
-{
- int i;
-
- pthread_t tid1, tid2;
- pthread_attr_t attr1, attr2;
-
- pthread_attr_init(&attr1);
- pthread_attr_init(&attr2);
-
- pthread_create(&tid1, &attr1, thread_main, nullptr);
- pthread_create(&tid2, &attr2, thread_main, nullptr);
- while(started != 2);
- run = 1;
- for(i=0;i<2;i++)
- sleep(1);
- run = 0;
- return 0;
-}
-
-#endif /* _WIN32 */
diff --git a/src/transform.cpp b/src/transform.cpp
deleted file mode 100644
index cff89232..00000000
--- a/src/transform.cpp
+++ /dev/null
@@ -1,1850 +0,0 @@
-/******************************************************************************
- * Project: PROJ.4
- * Purpose: Perform overall coordinate system to coordinate system
- * transformations (pj_transform() function) including reprojection
- * and datum shifting.
- * Author: Frank Warmerdam, warmerdam@pobox.com
- *
- ******************************************************************************
- * Copyright (c) 2000, Frank Warmerdam
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *****************************************************************************/
-
-#include <errno.h>
-#include <math.h>
-#include <string.h>
-
-#include "proj.h"
-#include "proj_internal.h"
-#include "grids.hpp"
-
-using namespace NS_PROJ;
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// From older geocent.h
-///////////////////////////////////////////////////////////////////////////////
-
-
-/***************************************************************************/
-/* RSC IDENTIFIER: GEOCENTRIC
- *
- * ABSTRACT
- *
- * This component provides conversions between Geodetic coordinates (latitude,
- * longitude in radians and height in meters) and Geocentric coordinates
- * (X, Y, Z) in meters.
- *
- * ERROR HANDLING
- *
- * This component checks parameters for valid values. If an invalid value
- * is found, the error code is combined with the current error code using
- * the bitwise or. This combining allows multiple error codes to be
- * returned. The possible error codes are:
- *
- * GEOCENT_NO_ERROR : No errors occurred in function
- * GEOCENT_LAT_ERROR : Latitude out of valid range
- * (-90 to 90 degrees)
- * GEOCENT_LON_ERROR : Longitude out of valid range
- * (-180 to 360 degrees)
- * GEOCENT_A_ERROR : Semi-major axis less than or equal to zero
- * GEOCENT_B_ERROR : Semi-minor axis less than or equal to zero
- * GEOCENT_A_LESS_B_ERROR : Semi-major axis less than semi-minor axis
- *
- *
- * REUSE NOTES
- *
- * GEOCENTRIC is intended for reuse by any application that performs
- * coordinate conversions between geodetic coordinates and geocentric
- * coordinates.
- *
- *
- * REFERENCES
- *
- * An Improved Algorithm for Geocentric to Geodetic Coordinate Conversion,
- * Ralph Toms, February 1996 UCRL-JC-123138.
- *
- * Further information on GEOCENTRIC can be found in the Reuse Manual.
- *
- * GEOCENTRIC originated from : U.S. Army Topographic Engineering Center
- * Geospatial Information Division
- * 7701 Telegraph Road
- * Alexandria, VA 22310-3864
- *
- * LICENSES
- *
- * None apply to this component.
- *
- * RESTRICTIONS
- *
- * GEOCENTRIC has no restrictions.
- *
- * ENVIRONMENT
- *
- * GEOCENTRIC was tested and certified in the following environments:
- *
- * 1. Solaris 2.5 with GCC version 2.8.1
- * 2. Windows 95 with MS Visual C++ version 6
- *
- * MODIFICATIONS
- *
- * Date Description
- * ---- -----------
- *
- *
- */
-
-
-/***************************************************************************/
-/*
- * DEFINES
- */
-#define GEOCENT_NO_ERROR 0x0000
-#define GEOCENT_LAT_ERROR 0x0001
-#define GEOCENT_LON_ERROR 0x0002
-#define GEOCENT_A_ERROR 0x0004
-#define GEOCENT_B_ERROR 0x0008
-#define GEOCENT_A_LESS_B_ERROR 0x0010
-
-
-/***************************************************************************/
-/*
- * FUNCTION PROTOTYPES
- */
-
-/* ensure proper linkage to c++ programs */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct
-{
- double Geocent_a; /* Semi-major axis of ellipsoid in meters */
- double Geocent_b; /* Semi-minor axis of ellipsoid */
- double Geocent_a2; /* Square of semi-major axis */
- double Geocent_b2; /* Square of semi-minor axis */
- double Geocent_e2; /* Eccentricity squared */
- double Geocent_ep2; /* 2nd eccentricity squared */
-} GeocentricInfo;
-
-void pj_Init_Geocentric( GeocentricInfo *gi );
-long pj_Set_Geocentric_Parameters( GeocentricInfo *gi,
- double a,
- double b);
-
-/*
- * The function Set_Geocentric_Parameters receives the ellipsoid parameters
- * as inputs and sets the corresponding state variables.
- *
- * a : Semi-major axis, in meters. (input)
- * b : Semi-minor axis, in meters. (input)
- */
-
-
-void pj_Get_Geocentric_Parameters ( GeocentricInfo *gi,
- double *a,
- double *b);
-
-/*
- * The function Get_Geocentric_Parameters returns the ellipsoid parameters
- * to be used in geocentric coordinate conversions.
- *
- * a : Semi-major axis, in meters. (output)
- * b : Semi-minor axis, in meters. (output)
- */
-
-
-long pj_Convert_Geodetic_To_Geocentric ( GeocentricInfo *gi,
- double Latitude,
- double Longitude,
- double Height,
- double *X,
- double *Y,
- double *Z);
-/*
- * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates
- * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z),
- * according to the current ellipsoid parameters.
- *
- * Latitude : Geodetic latitude in radians (input)
- * Longitude : Geodetic longitude in radians (input)
- * Height : Geodetic height, in meters (input)
- * X : Calculated Geocentric X coordinate, in meters. (output)
- * Y : Calculated Geocentric Y coordinate, in meters. (output)
- * Z : Calculated Geocentric Z coordinate, in meters. (output)
- *
- */
-
-
-void pj_Convert_Geocentric_To_Geodetic (GeocentricInfo *gi,
- double X,
- double Y,
- double Z,
- double *Latitude,
- double *Longitude,
- double *Height);
-/*
- * The function Convert_Geocentric_To_Geodetic converts geocentric
- * coordinates (X, Y, Z) to geodetic coordinates (latitude, longitude,
- * and height), according to the current ellipsoid parameters.
- *
- * X : Geocentric X coordinate, in meters. (input)
- * Y : Geocentric Y coordinate, in meters. (input)
- * Z : Geocentric Z coordinate, in meters. (input)
- * Latitude : Calculated latitude value in radians. (output)
- * Longitude : Calculated longitude value in radians. (output)
- * Height : Calculated height value, in meters. (output)
- */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// From older geocent.cpp
-///////////////////////////////////////////////////////////////////////////////
-
-
-/***************************************************************************/
-/* RSC IDENTIFIER: GEOCENTRIC
- *
- * ABSTRACT
- *
- * This component provides conversions between Geodetic coordinates (latitude,
- * longitude in radians and height in meters) and Geocentric coordinates
- * (X, Y, Z) in meters.
- *
- * ERROR HANDLING
- *
- * This component checks parameters for valid values. If an invalid value
- * is found, the error code is combined with the current error code using
- * the bitwise or. This combining allows multiple error codes to be
- * returned. The possible error codes are:
- *
- * GEOCENT_NO_ERROR : No errors occurred in function
- * GEOCENT_LAT_ERROR : Latitude out of valid range
- * (-90 to 90 degrees)
- * GEOCENT_LON_ERROR : Longitude out of valid range
- * (-180 to 360 degrees)
- * GEOCENT_A_ERROR : Semi-major axis lessthan or equal to zero
- * GEOCENT_B_ERROR : Semi-minor axis lessthan or equal to zero
- * GEOCENT_A_LESS_B_ERROR : Semi-major axis less than semi-minor axis
- *
- *
- * REUSE NOTES
- *
- * GEOCENTRIC is intended for reuse by any application that performs
- * coordinate conversions between geodetic coordinates and geocentric
- * coordinates.
- *
- *
- * REFERENCES
- *
- * An Improved Algorithm for Geocentric to Geodetic Coordinate Conversion,
- * Ralph Toms, February 1996 UCRL-JC-123138.
- *
- * Further information on GEOCENTRIC can be found in the Reuse Manual.
- *
- * GEOCENTRIC originated from : U.S. Army Topographic Engineering Center
- * Geospatial Information Division
- * 7701 Telegraph Road
- * Alexandria, VA 22310-3864
- *
- * LICENSES
- *
- * None apply to this component.
- *
- * RESTRICTIONS
- *
- * GEOCENTRIC has no restrictions.
- *
- * ENVIRONMENT
- *
- * GEOCENTRIC was tested and certified in the following environments:
- *
- * 1. Solaris 2.5 with GCC version 2.8.1
- * 2. Windows 95 with MS Visual C++ version 6
- *
- * MODIFICATIONS
- *
- * Date Description
- * ---- -----------
- * 25-02-97 Original Code
- *
- */
-
-
-/***************************************************************************/
-/*
- * INCLUDES
- */
-#include <math.h>
-//#include "geocent.h"
-/*
- * math.h - is needed for calls to sin, cos, tan and sqrt.
- * geocent.h - is needed for Error codes and prototype error checking.
- */
-
-
-/***************************************************************************/
-/*
- * DEFINES
- */
-#define PI 3.14159265358979323e0
-#define PI_OVER_2 (PI / 2.0e0)
-#define FALSE 0
-#define TRUE 1
-#define COS_67P5 0.38268343236508977 /* cosine of 67.5 degrees */
-#define AD_C 1.0026000 /* Toms region 1 constant */
-
-
-/***************************************************************************/
-/*
- * FUNCTIONS
- */
-
-
-long pj_Set_Geocentric_Parameters (GeocentricInfo *gi, double a, double b)
-
-{ /* BEGIN Set_Geocentric_Parameters */
-/*
- * The function Set_Geocentric_Parameters receives the ellipsoid parameters
- * as inputs and sets the corresponding state variables.
- *
- * a : Semi-major axis, in meters. (input)
- * b : Semi-minor axis, in meters. (input)
- */
- long Error_Code = GEOCENT_NO_ERROR;
-
- if (a <= 0.0)
- Error_Code |= GEOCENT_A_ERROR;
- if (b <= 0.0)
- Error_Code |= GEOCENT_B_ERROR;
- if (a < b)
- Error_Code |= GEOCENT_A_LESS_B_ERROR;
- if (!Error_Code)
- {
- gi->Geocent_a = a;
- gi->Geocent_b = b;
- gi->Geocent_a2 = a * a;
- gi->Geocent_b2 = b * b;
- gi->Geocent_e2 = (gi->Geocent_a2 - gi->Geocent_b2) / gi->Geocent_a2;
- gi->Geocent_ep2 = (gi->Geocent_a2 - gi->Geocent_b2) / gi->Geocent_b2;
- }
- return (Error_Code);
-} /* END OF Set_Geocentric_Parameters */
-
-
-void pj_Get_Geocentric_Parameters (GeocentricInfo *gi,
- double *a,
- double *b)
-{ /* BEGIN Get_Geocentric_Parameters */
-/*
- * The function Get_Geocentric_Parameters returns the ellipsoid parameters
- * to be used in geocentric coordinate conversions.
- *
- * a : Semi-major axis, in meters. (output)
- * b : Semi-minor axis, in meters. (output)
- */
-
- *a = gi->Geocent_a;
- *b = gi->Geocent_b;
-} /* END OF Get_Geocentric_Parameters */
-
-
-long pj_Convert_Geodetic_To_Geocentric (GeocentricInfo *gi,
- double Latitude,
- double Longitude,
- double Height,
- double *X,
- double *Y,
- double *Z)
-{ /* BEGIN Convert_Geodetic_To_Geocentric */
-/*
- * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates
- * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z),
- * according to the current ellipsoid parameters.
- *
- * Latitude : Geodetic latitude in radians (input)
- * Longitude : Geodetic longitude in radians (input)
- * Height : Geodetic height, in meters (input)
- * X : Calculated Geocentric X coordinate, in meters (output)
- * Y : Calculated Geocentric Y coordinate, in meters (output)
- * Z : Calculated Geocentric Z coordinate, in meters (output)
- *
- */
- long Error_Code = GEOCENT_NO_ERROR;
- double Rn; /* Earth radius at location */
- double Sin_Lat; /* sin(Latitude) */
- double Sin2_Lat; /* Square of sin(Latitude) */
- double Cos_Lat; /* cos(Latitude) */
-
- /*
- ** Don't blow up if Latitude is just a little out of the value
- ** range as it may just be a rounding issue. Also removed longitude
- ** test, it should be wrapped by cos() and sin(). NFW for PROJ.4, Sep/2001.
- */
- if( Latitude < -PI_OVER_2 && Latitude > -1.001 * PI_OVER_2 )
- Latitude = -PI_OVER_2;
- else if( Latitude > PI_OVER_2 && Latitude < 1.001 * PI_OVER_2 )
- Latitude = PI_OVER_2;
- else if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
- { /* Latitude out of range */
- Error_Code |= GEOCENT_LAT_ERROR;
- }
-
- if (!Error_Code)
- { /* no errors */
- if (Longitude > PI)
- Longitude -= (2*PI);
- Sin_Lat = sin(Latitude);
- Cos_Lat = cos(Latitude);
- Sin2_Lat = Sin_Lat * Sin_Lat;
- Rn = gi->Geocent_a / (sqrt(1.0e0 - gi->Geocent_e2 * Sin2_Lat));
- *X = (Rn + Height) * Cos_Lat * cos(Longitude);
- *Y = (Rn + Height) * Cos_Lat * sin(Longitude);
- *Z = ((Rn * (1 - gi->Geocent_e2)) + Height) * Sin_Lat;
-
- }
- return (Error_Code);
-} /* END OF Convert_Geodetic_To_Geocentric */
-
-/*
- * The function Convert_Geocentric_To_Geodetic converts geocentric
- * coordinates (X, Y, Z) to geodetic coordinates (latitude, longitude,
- * and height), according to the current ellipsoid parameters.
- *
- * X : Geocentric X coordinate, in meters. (input)
- * Y : Geocentric Y coordinate, in meters. (input)
- * Z : Geocentric Z coordinate, in meters. (input)
- * Latitude : Calculated latitude value in radians. (output)
- * Longitude : Calculated longitude value in radians. (output)
- * Height : Calculated height value, in meters. (output)
- */
-
-#define USE_ITERATIVE_METHOD
-
-void pj_Convert_Geocentric_To_Geodetic (GeocentricInfo *gi,
- double X,
- double Y,
- double Z,
- double *Latitude,
- double *Longitude,
- double *Height)
-{ /* BEGIN Convert_Geocentric_To_Geodetic */
-#if !defined(USE_ITERATIVE_METHOD)
-/*
- * The method used here is derived from 'An Improved Algorithm for
- * Geocentric to Geodetic Coordinate Conversion', by Ralph Toms, Feb 1996
- */
-
-/* Note: Variable names follow the notation used in Toms, Feb 1996 */
-
- double W; /* distance from Z axis */
- double W2; /* square of distance from Z axis */
- double T0; /* initial estimate of vertical component */
- double T1; /* corrected estimate of vertical component */
- double S0; /* initial estimate of horizontal component */
- double S1; /* corrected estimate of horizontal component */
- double Sin_B0; /* sin(B0), B0 is estimate of Bowring aux variable */
- double Sin3_B0; /* cube of sin(B0) */
- double Cos_B0; /* cos(B0) */
- double Sin_p1; /* sin(phi1), phi1 is estimated latitude */
- double Cos_p1; /* cos(phi1) */
- double Rn; /* Earth radius at location */
- double Sum; /* numerator of cos(phi1) */
- int At_Pole; /* indicates location is in polar region */
-
- At_Pole = FALSE;
- if (X != 0.0)
- {
- *Longitude = atan2(Y,X);
- }
- else
- {
- if (Y > 0)
- {
- *Longitude = PI_OVER_2;
- }
- else if (Y < 0)
- {
- *Longitude = -PI_OVER_2;
- }
- else
- {
- At_Pole = TRUE;
- *Longitude = 0.0;
- if (Z > 0.0)
- { /* north pole */
- *Latitude = PI_OVER_2;
- }
- else if (Z < 0.0)
- { /* south pole */
- *Latitude = -PI_OVER_2;
- }
- else
- { /* center of earth */
- *Latitude = PI_OVER_2;
- *Height = -Geocent_b;
- return;
- }
- }
- }
- W2 = X*X + Y*Y;
- W = sqrt(W2);
- T0 = Z * AD_C;
- S0 = sqrt(T0 * T0 + W2);
- Sin_B0 = T0 / S0;
- Cos_B0 = W / S0;
- Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0;
- T1 = Z + gi->Geocent_b * gi->Geocent_ep2 * Sin3_B0;
- Sum = W - gi->Geocent_a * gi->Geocent_e2 * Cos_B0 * Cos_B0 * Cos_B0;
- S1 = sqrt(T1*T1 + Sum * Sum);
- Sin_p1 = T1 / S1;
- Cos_p1 = Sum / S1;
- Rn = gi->Geocent_a / sqrt(1.0 - gi->Geocent_e2 * Sin_p1 * Sin_p1);
- if (Cos_p1 >= COS_67P5)
- {
- *Height = W / Cos_p1 - Rn;
- }
- else if (Cos_p1 <= -COS_67P5)
- {
- *Height = W / -Cos_p1 - Rn;
- }
- else
- {
- *Height = Z / Sin_p1 + Rn * (gi->Geocent_e2 - 1.0);
- }
- if (At_Pole == FALSE)
- {
- *Latitude = atan(Sin_p1 / Cos_p1);
- }
-#else /* defined(USE_ITERATIVE_METHOD) */
-/*
-* Reference...
-* ============
-* Wenzel, H.-G.(1985): Hochauflösende Kugelfunktionsmodelle für
-* das Gravitationspotential der Erde. Wiss. Arb. Univ. Hannover
-* Nr. 137, p. 130-131.
-
-* Programmed by GGA- Leibniz-Institute of Applied Geophysics
-* Stilleweg 2
-* D-30655 Hannover
-* Federal Republic of Germany
-* Internet: www.gga-hannover.de
-*
-* Hannover, March 1999, April 2004.
-* see also: comments in statements
-* remarks:
-* Mathematically exact and because of symmetry of rotation-ellipsoid,
-* each point (X,Y,Z) has at least two solutions (Latitude1,Longitude1,Height1) and
-* (Latitude2,Longitude2,Height2). Is point=(0.,0.,Z) (P=0.), so you get even
-* four solutions, every two symmetrical to the semi-minor axis.
-* Here Height1 and Height2 have at least a difference in order of
-* radius of curvature (e.g. (0,0,b)=> (90.,0.,0.) or (-90.,0.,-2b);
-* (a+100.)*(sqrt(2.)/2.,sqrt(2.)/2.,0.) => (0.,45.,100.) or
-* (0.,225.,-(2a+100.))).
-* The algorithm always computes (Latitude,Longitude) with smallest |Height|.
-* For normal computations, that means |Height|<10000.m, algorithm normally
-* converges after to 2-3 steps!!!
-* But if |Height| has the amount of length of ellipsoid's axis
-* (e.g. -6300000.m), algorithm needs about 15 steps.
-*/
-
-/* local definitions and variables */
-/* end-criterium of loop, accuracy of sin(Latitude) */
-#define genau 1.E-12
-#define genau2 (genau*genau)
-#define maxiter 30
-
- double P; /* distance between semi-minor axis and location */
- double RR; /* distance between center and location */
- double CT; /* sin of geocentric latitude */
- double ST; /* cos of geocentric latitude */
- double RX;
- double RK;
- double RN; /* Earth radius at location */
- double CPHI0; /* cos of start or old geodetic latitude in iterations */
- double SPHI0; /* sin of start or old geodetic latitude in iterations */
- double CPHI; /* cos of searched geodetic latitude */
- double SPHI; /* sin of searched geodetic latitude */
- double SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */
- int iter; /* # of continuous iteration, max. 30 is always enough (s.a.) */
-
- P = sqrt(X*X+Y*Y);
- RR = sqrt(X*X+Y*Y+Z*Z);
-
-/* special cases for latitude and longitude */
- if (P/gi->Geocent_a < genau) {
-
-/* special case, if P=0. (X=0., Y=0.) */
- *Longitude = 0.;
-
-/* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis
- * of ellipsoid (=center of mass), Latitude becomes PI/2 */
- if (RR/gi->Geocent_a < genau) {
- *Latitude = PI_OVER_2;
- *Height = -gi->Geocent_b;
- return ;
-
- }
- }
- else {
-/* ellipsoidal (geodetic) longitude
- * interval: -PI < Longitude <= +PI */
- *Longitude=atan2(Y,X);
- }
-
-/* --------------------------------------------------------------
- * Following iterative algorithm was developed by
- * "Institut für Erdmessung", University of Hannover, July 1988.
- * Internet: www.ife.uni-hannover.de
- * Iterative computation of CPHI,SPHI and Height.
- * Iteration of CPHI and SPHI to 10**-12 radian resp.
- * 2*10**-7 arcsec.
- * --------------------------------------------------------------
- */
- CT = Z/RR;
- ST = P/RR;
- {
- const double denominator = 1.0-gi->Geocent_e2*(2.0-gi->Geocent_e2)*ST*ST;
- if( denominator == 0 )
- {
- *Latitude = HUGE_VAL;
- *Longitude = HUGE_VAL;
- *Height = HUGE_VAL;
- return;
- }
- RX = 1.0/sqrt(denominator);
- }
- CPHI0 = ST*(1.0-gi->Geocent_e2)*RX;
- SPHI0 = CT*RX;
- iter = 0;
-
-/* loop to find sin(Latitude) resp. Latitude
- * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */
- do
- {
- iter++;
- RN = gi->Geocent_a/sqrt(1.0-gi->Geocent_e2*SPHI0*SPHI0);
-
-/* ellipsoidal (geodetic) height */
- *Height = P*CPHI0+Z*SPHI0-RN*(1.0-gi->Geocent_e2*SPHI0*SPHI0);
-
- /* avoid zero division */
- if (RN+*Height==0.0) {
- *Latitude = 0.0;
- return;
- }
- RK = gi->Geocent_e2*RN/(RN+*Height);
- {
- const double denominator = 1.0-RK*(2.0-RK)*ST*ST;
- if( denominator == 0 )
- {
- *Latitude = HUGE_VAL;
- *Longitude = HUGE_VAL;
- *Height = HUGE_VAL;
- return;
- }
- RX = 1.0/sqrt(denominator);
- }
- CPHI = ST*(1.0-RK)*RX;
- SPHI = CT*RX;
- SDPHI = SPHI*CPHI0-CPHI*SPHI0;
- CPHI0 = CPHI;
- SPHI0 = SPHI;
- }
- while (SDPHI*SDPHI > genau2 && iter < maxiter);
-
-/* ellipsoidal (geodetic) latitude */
- *Latitude=atan2(SPHI, fabs(CPHI));
-
-#endif /* defined(USE_ITERATIVE_METHOD) */
-} /* END OF Convert_Geocentric_To_Geodetic */
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// Main of transform.cpp
-///////////////////////////////////////////////////////////////////////////////
-
-
-static int adjust_axis( projCtx ctx, const char *axis, int denormalize_flag,
- long point_count, int point_offset,
- double *x, double *y, double *z );
-
-#ifndef SRS_WGS84_SEMIMAJOR
-#define SRS_WGS84_SEMIMAJOR 6378137.0
-#endif
-
-#ifndef SRS_WGS84_ESQUARED
-#define SRS_WGS84_ESQUARED 0.0066943799901413165
-#endif
-
-#define Dx_BF (defn->datum_params[0])
-#define Dy_BF (defn->datum_params[1])
-#define Dz_BF (defn->datum_params[2])
-#define Rx_BF (defn->datum_params[3])
-#define Ry_BF (defn->datum_params[4])
-#define Rz_BF (defn->datum_params[5])
-#define M_BF (defn->datum_params[6])
-
-/*
-** This table is intended to indicate for any given error code
-** whether that error will occur for all locations (ie.
-** it is a problem with the coordinate system as a whole) in which case the
-** value would be 0, or if the problem is with the point being transformed
-** in which case the value is 1.
-**
-** At some point we might want to move this array in with the error message
-** list or something, but while experimenting with it this should be fine.
-**
-**
-** NOTE (2017-10-01): Non-transient errors really should have resulted in a
-** PJ==0 during initialization, and hence should be handled at the level
-** before calling pj_transform. The only obvious example of the contrary
-** appears to be the PJD_ERR_GRID_AREA case, which may also be taken to
-** mean "no grids available"
-**
-**
-*/
-
-static const int transient_error[70] = {
- /* 0 1 2 3 4 5 6 7 8 9 */
- /* 0 to 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* 10 to 19 */ 0, 0, 0, 0, 1, 1, 0, 1, 1, 1,
- /* 20 to 29 */ 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- /* 30 to 39 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* 40 to 49 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- /* 50 to 59 */ 1, 0, 1, 0, 1, 1, 1, 1, 0, 0,
- /* 60 to 69 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
-
-
-/* -------------------------------------------------------------------- */
-/* Read transient_error[] in a safe way. */
-/* -------------------------------------------------------------------- */
-static int get_transient_error_value(int pos_index)
-{
- const int array_size =
- (int)(sizeof(transient_error) / sizeof(transient_error[0]));
- if( pos_index < 0 || pos_index >= array_size ) {
- return 0;
- }
- return transient_error[pos_index];
-}
-
-
-/* -------------------------------------------------------------------- */
-/* Transform unusual input coordinate axis orientation to */
-/* standard form if needed. */
-/* -------------------------------------------------------------------- */
-static int adjust_axes (PJ *P, PJ_DIRECTION dir, long n, int dist, double *x, double *y, double *z) {
- /* Nothing to do? */
- if (0==strcmp(P->axis,"enu"))
- return 0;
-
- return adjust_axis( P->ctx, P->axis,
- dir==PJ_FWD ? 1: 0, n, dist, x, y, z );
-}
-
-
-
-/* ----------------------------------------------------------------------- */
-/* Transform geographic (lat/long) source coordinates to */
-/* cartesian ("geocentric"), if needed */
-/* ----------------------------------------------------------------------- */
-static int geographic_to_cartesian (PJ *P, PJ_DIRECTION dir, long n, int dist, double *x, double *y, double *z) {
- int res;
- long i;
- double fac = P->to_meter;
-
- /* Nothing to do? */
- if (!P->is_geocent)
- return 0;
-
- if ( z == nullptr ) {
- pj_ctx_set_errno( pj_get_ctx(P), PJD_ERR_GEOCENTRIC);
- return PJD_ERR_GEOCENTRIC;
- }
-
- if (PJ_FWD==dir) {
- fac = P->fr_meter;
- res = pj_geodetic_to_geocentric( P->a_orig, P->es_orig, n, dist, x, y, z );
- if (res)
- return res;
- }
-
- if (fac != 1.0) {
- for( i = 0; i < n; i++ ) {
- if( x[dist*i] != HUGE_VAL ) {
- x[dist*i] *= fac;
- y[dist*i] *= fac;
- z[dist*i] *= fac;
- }
- }
- }
-
- if (PJ_FWD==dir)
- return 0;
- return pj_geocentric_to_geodetic(
- P->a_orig, P->es_orig,
- n, dist,
- x, y, z
- );
-}
-
-
-
-
-
-
-
-
-
-
-/* -------------------------------------------------------------------- */
-/* Transform destination points to projection coordinates, if */
-/* desired. */
-/* */
-/* Ought to fold this into projected_to_geographic */
-/* -------------------------------------------------------------------- */
-static int geographic_to_projected (PJ *P, long n, int dist, double *x, double *y, double *z) {
- long i;
-
- /* Nothing to do? */
- if (P->is_latlong && !P->geoc && P->vto_meter == 1.0)
- return 0;
- if (P->is_geocent)
- return 0;
-
- if(P->fwd3d != nullptr && !(z == nullptr && P->is_latlong))
- {
- /* Three dimensions must be defined */
- if ( z == nullptr)
- {
- pj_ctx_set_errno( pj_get_ctx(P), PJD_ERR_GEOCENTRIC);
- return PJD_ERR_GEOCENTRIC;
- }
-
- for( i = 0; i < n; i++ )
- {
- PJ_XYZ projected_loc;
- PJ_LPZ geodetic_loc;
-
- geodetic_loc.lam = x[dist*i];
- geodetic_loc.phi = y[dist*i];
- geodetic_loc.z = z[dist*i];
-
- if (geodetic_loc.lam == HUGE_VAL)
- continue;
-
- proj_errno_reset( P );
- projected_loc = pj_fwd3d( geodetic_loc, P);
- if( P->ctx->last_errno != 0 )
- {
- if( (P->ctx->last_errno != EDOM
- && P->ctx->last_errno != ERANGE)
- && (P->ctx->last_errno > 0
- || P->ctx->last_errno < -44 || n == 1
- || get_transient_error_value(-P->ctx->last_errno) == 0 ) )
- {
- return P->ctx->last_errno;
- }
- else
- {
- projected_loc.x = HUGE_VAL;
- projected_loc.y = HUGE_VAL;
- projected_loc.z = HUGE_VAL;
- }
- }
-
- x[dist*i] = projected_loc.x;
- y[dist*i] = projected_loc.y;
- z[dist*i] = projected_loc.z;
- }
- return 0;
- }
-
- // Ugly hack. See https://github.com/OSGeo/PROJ/issues/1782
- if( P->right == PJ_IO_UNITS_WHATEVER && P->descr &&
- strncmp(P->descr, "General Oblique Transformation",
- strlen("General Oblique Transformation")) == 0 )
- {
- P->right = PJ_IO_UNITS_PROJECTED;
- }
-
- for( i = 0; i <n; i++ )
- {
- PJ_XY projected_loc;
- PJ_LP geodetic_loc;
-
- geodetic_loc.lam = x[dist*i];
- geodetic_loc.phi = y[dist*i];
-
- if( geodetic_loc.lam == HUGE_VAL )
- continue;
-
- proj_errno_reset( P );
- projected_loc = pj_fwd( geodetic_loc, P );
- if( P->ctx->last_errno != 0 )
- {
- if( (P->ctx->last_errno != EDOM
- && P->ctx->last_errno != ERANGE)
- && (P->ctx->last_errno > 0
- || P->ctx->last_errno < -44 || n == 1
- || get_transient_error_value(-P->ctx->last_errno) == 0 ) )
- {
- return P->ctx->last_errno;
- }
- else
- {
- projected_loc.x = HUGE_VAL;
- projected_loc.y = HUGE_VAL;
- }
- }
-
- x[dist*i] = projected_loc.x;
- y[dist*i] = projected_loc.y;
- }
- return 0;
-}
-
-
-
-
-
-/* ----------------------------------------------------------------------- */
-/* Transform projected source coordinates to lat/long, if needed */
-/* ----------------------------------------------------------------------- */
-static int projected_to_geographic (PJ *P, long n, int dist, double *x, double *y, double *z) {
- long i;
-
- /* Nothing to do? */
- if (P->is_latlong && !P->geoc && P->vto_meter == 1.0)
- return 0;
- if (P->is_geocent)
- return 0;
-
- /* Check first if projection is invertible. */
- if( (P->inv3d == nullptr) && (P->inv == nullptr))
- {
- pj_ctx_set_errno(pj_get_ctx(P), PJD_ERR_NON_CONV_INV_MERI_DIST);
- pj_log( pj_get_ctx(P), PJ_LOG_ERROR,
- "pj_transform(): source projection not invertable" );
- return PJD_ERR_NON_CONV_INV_MERI_DIST;
- }
-
- /* If invertible - First try inv3d if defined */
- if (P->inv3d != nullptr && !(z == nullptr && P->is_latlong))
- {
- /* Three dimensions must be defined */
- if ( z == nullptr)
- {
- pj_ctx_set_errno( pj_get_ctx(P), PJD_ERR_GEOCENTRIC);
- return PJD_ERR_GEOCENTRIC;
- }
-
- for (i=0; i < n; i++)
- {
- PJ_XYZ projected_loc;
- PJ_LPZ geodetic_loc;
-
- projected_loc.x = x[dist*i];
- projected_loc.y = y[dist*i];
- projected_loc.z = z[dist*i];
-
- if (projected_loc.x == HUGE_VAL)
- continue;
-
- proj_errno_reset( P );
- geodetic_loc = pj_inv3d(projected_loc, P);
- if( P->ctx->last_errno != 0 )
- {
- if( (P->ctx->last_errno != EDOM
- && P->ctx->last_errno != ERANGE)
- && (P->ctx->last_errno > 0
- || P->ctx->last_errno < -44 || n == 1
- || get_transient_error_value(-P->ctx->last_errno) == 0 ) )
- {
- return P->ctx->last_errno;
- }
- else
- {
- geodetic_loc.lam = HUGE_VAL;
- geodetic_loc.phi = HUGE_VAL;
- geodetic_loc.z = HUGE_VAL;
- }
- }
-
- x[dist*i] = geodetic_loc.lam;
- y[dist*i] = geodetic_loc.phi;
- z[dist*i] = geodetic_loc.z;
-
- }
- return 0;
- }
-
- // Ugly hack. See https://github.com/OSGeo/PROJ/issues/1782
- if( P->right == PJ_IO_UNITS_WHATEVER && P->descr &&
- strncmp(P->descr, "General Oblique Transformation",
- strlen("General Oblique Transformation")) == 0 )
- {
- P->right = PJ_IO_UNITS_PROJECTED;
- }
-
- /* Fallback to the original PROJ.4 API 2d inversion - inv */
- for( i = 0; i < n; i++ ) {
- PJ_XY projected_loc;
- PJ_LP geodetic_loc;
-
- projected_loc.x = x[dist*i];
- projected_loc.y = y[dist*i];
-
- if( projected_loc.x == HUGE_VAL )
- continue;
-
- proj_errno_reset( P );
- geodetic_loc = pj_inv( projected_loc, P );
- if( P->ctx->last_errno != 0 )
- {
- if( (P->ctx->last_errno != EDOM
- && P->ctx->last_errno != ERANGE)
- && (P->ctx->last_errno > 0
- || P->ctx->last_errno < -44 || n == 1
- || get_transient_error_value(-P->ctx->last_errno) == 0 ) )
- {
- return P->ctx->last_errno;
- }
- else
- {
- geodetic_loc.lam = HUGE_VAL;
- geodetic_loc.phi = HUGE_VAL;
- }
- }
-
- x[dist*i] = geodetic_loc.lam;
- y[dist*i] = geodetic_loc.phi;
- }
- return 0;
-}
-
-
-
-/* -------------------------------------------------------------------- */
-/* Adjust for the prime meridian if needed. */
-/* -------------------------------------------------------------------- */
-static int prime_meridian (PJ *P, PJ_DIRECTION dir, long n, int dist, double *x) {
- int i;
- double pm = P->from_greenwich;
-
- /* Nothing to do? */
- if (pm==0.0)
- return 0;
- if (!(P->is_geocent || P->is_latlong))
- return 0;
-
- if (dir==PJ_FWD)
- pm = -pm;
-
- for (i = 0; i < n; i++)
- if (x[dist*i] != HUGE_VAL)
- x[dist*i] += pm;
-
- return 0;
-}
-
-
-
-/* -------------------------------------------------------------------- */
-/* Adjust for vertical scale factor if needed */
-/* -------------------------------------------------------------------- */
-static int height_unit (PJ *P, PJ_DIRECTION dir, long n, int dist, double *z) {
- int i;
- double fac = P->vto_meter;
-
- if (PJ_FWD==dir)
- fac = P->vfr_meter;
-
- /* Nothing to do? */
- if (fac==1.0)
- return 0;
- if (nullptr==z)
- return 0;
- if (P->is_latlong)
- return 0; /* done in pj_inv3d() / pj_fwd3d() */
-
- for (i = 0; i < n; i++)
- if (z[dist*i] != HUGE_VAL )
- z[dist*i] *= fac;
-
- return 0;
-}
-
-
-/************************************************************************/
-/* pj_apply_vgridshift() */
-/* */
-/* This implementation takes uses the gridlist from a coordinate */
-/* system definition. If the gridlist has not yet been */
-/* populated in the coordinate system definition we set it up */
-/* now. */
-/************************************************************************/
-static int pj_apply_vgridshift( PJ *defn,
- int inverse,
- long point_count, int point_offset,
- double *x, double *y, double *z )
-
-{
- if( defn->vgrids_legacy == nullptr )
- {
- defn->vgrids_legacy = new ListOfVGrids;
- auto vgrids = pj_vgrid_init(defn, "geoidgrids");
- if( vgrids.empty() )
- return 0;
- *static_cast<ListOfVGrids*>(defn->vgrids_legacy) = std::move(vgrids);
- }
- if( static_cast<ListOfVGrids*>(defn->vgrids_legacy)->empty() )
- {
- return 0;
- }
-
- for( int i = 0; i < point_count; i++ )
- {
- double value;
- long io = i * point_offset;
- PJ_LP input;
-
- input.phi = y[io];
- input.lam = x[io];
-
- value = pj_vgrid_value(defn, *static_cast<ListOfVGrids*>(defn->vgrids_legacy), input, 1.0);
-
- if( inverse )
- z[io] -= value;
- else
- z[io] += value;
-
- if( value == HUGE_VAL )
- {
- std::string gridlist;
-
- proj_log_debug(defn,
- "pj_apply_vgridshift(): failed to find a grid shift table for\n"
- " location (%.7fdW,%.7fdN)",
- x[io] * RAD_TO_DEG,
- y[io] * RAD_TO_DEG );
-
- for( const auto& gridset: *static_cast<ListOfVGrids*>(defn->vgrids_legacy) )
- {
- if( gridlist.empty() )
- gridlist += " tried: ";
- else
- gridlist += ',';
- gridlist += gridset->name();
- }
-
- proj_log_debug(defn, "%s", gridlist.c_str());
- pj_ctx_set_errno( defn->ctx, PJD_ERR_GRID_AREA );
-
- return PJD_ERR_GRID_AREA;
- }
- }
-
- return 0;
-}
-
-
-/* -------------------------------------------------------------------- */
-/* Transform to ellipsoidal heights if needed */
-/* -------------------------------------------------------------------- */
-static int geometric_to_orthometric (PJ *P, PJ_DIRECTION dir, long n, int dist, double *x, double *y, double *z) {
- int err;
- if (0==P->has_geoid_vgrids)
- return 0;
- if (z==nullptr)
- return PJD_ERR_GEOCENTRIC;
- err = pj_apply_vgridshift (P, dir==PJ_FWD ? 1 : 0, n, dist, x, y, z );
- if (err)
- return pj_ctx_get_errno(P->ctx);
- return 0;
-}
-
-
-
-/* -------------------------------------------------------------------- */
-/* Convert datums if needed, and possible. */
-/* -------------------------------------------------------------------- */
-static int datum_transform (PJ *P, PJ *Q, long n, int dist, double *x, double *y, double *z) {
- if (0==pj_datum_transform (P, Q, n, dist, x, y, z))
- return 0;
- if (P->ctx->last_errno)
- return P->ctx->last_errno;
- return Q->ctx->last_errno;
-}
-
-
-
-
-
-/* -------------------------------------------------------------------- */
-/* If a wrapping center other than 0 is provided, rewrap around */
-/* the suggested center (for latlong coordinate systems only). */
-/* -------------------------------------------------------------------- */
-static int long_wrap (PJ *P, long n, int dist, double *x) {
- long i;
-
- /* Nothing to do? */
- if (P->is_geocent)
- return 0;
- if (!P->is_long_wrap_set)
- return 0;
- if (!P->is_latlong)
- return 0;
-
- for (i = 0; i < n; i++ ) {
- double val = x[dist*i];
- if (val == HUGE_VAL)
- continue;
-
- /* Get fast in ] -2 PI, 2 PI [ range */
- val = fmod(val, M_TWOPI);
- while( val < P->long_wrap_center - M_PI )
- val += M_TWOPI;
- while( val > P->long_wrap_center + M_PI )
- val -= M_TWOPI;
- x[dist*i] = val;
- }
- return 0;
-}
-
-
-
-/************************************************************************/
-/* pj_transform() */
-/* */
-/* Currently this function doesn't recognise if two projections */
-/* are identical (to short circuit reprojection) because it is */
-/* difficult to compare PJ structures (since there are some */
-/* projection specific components). */
-/************************************************************************/
-
-int pj_transform(
- PJ *src, PJ *dst,
- long point_count, int point_offset,
- double *x, double *y, double *z
-){
- int err;
-
- src->ctx->last_errno = 0;
- dst->ctx->last_errno = 0;
-
- if( point_offset == 0 )
- point_offset = 1;
-
- /* Bring input to "normal form": longitude, latitude, ellipsoidal height */
-
- err = adjust_axes (src, PJ_INV, point_count, point_offset, x, y, z);
- if (err)
- return err;
- err = geographic_to_cartesian (src, PJ_INV, point_count, point_offset, x, y, z);
- if (err)
- return err;
- err = projected_to_geographic (src, point_count, point_offset, x, y, z);
- if (err)
- return err;
- err = prime_meridian (src, PJ_INV, point_count, point_offset, x);
- if (err)
- return err;
- err = height_unit (src, PJ_INV, point_count, point_offset, z);
- if (err)
- return err;
- err = geometric_to_orthometric (src, PJ_INV, point_count, point_offset, x, y, z);
- if (err)
- return err;
-
- /* At the center of the process we do the datum shift (if needed) */
-
- err = datum_transform(src, dst, point_count, point_offset, x, y, z );
- if (err)
- return err;
-
- /* Now get out on the other side: Bring "normal form" to output form */
-
- err = geometric_to_orthometric (dst, PJ_FWD, point_count, point_offset, x, y, z);
- if (err)
- return err;
- err = height_unit (dst, PJ_FWD, point_count, point_offset, z);
- if (err)
- return err;
- err = prime_meridian (dst, PJ_FWD, point_count, point_offset, x);
- if (err)
- return err;
- err = geographic_to_cartesian (dst, PJ_FWD, point_count, point_offset, x, y, z);
- if (err)
- return err;
- err = geographic_to_projected (dst, point_count, point_offset, x, y, z);
- if (err)
- return err;
- err = long_wrap (dst, point_count, point_offset, x);
- if (err)
- return err;
- err = adjust_axes (dst, PJ_FWD, point_count, point_offset, x, y, z);
- if (err)
- return err;
-
- return 0;
-}
-
-
-
-/************************************************************************/
-/* pj_geodetic_to_geocentric() */
-/************************************************************************/
-
-int pj_geodetic_to_geocentric( double a, double es,
- long point_count, int point_offset,
- double *x, double *y, double *z )
-
-{
- double b;
- int i;
- GeocentricInfo gi;
- int ret_errno = 0;
-
- if( es == 0.0 )
- b = a;
- else
- b = a * sqrt(1-es);
-
- if( pj_Set_Geocentric_Parameters( &gi, a, b ) != 0 )
- {
- return PJD_ERR_GEOCENTRIC;
- }
-
- for( i = 0; i < point_count; i++ )
- {
- long io = i * point_offset;
-
- if( x[io] == HUGE_VAL )
- continue;
-
- if( pj_Convert_Geodetic_To_Geocentric( &gi, y[io], x[io], z[io],
- x+io, y+io, z+io ) != 0 )
- {
- ret_errno = PJD_ERR_LAT_OR_LON_EXCEED_LIMIT;
- x[io] = y[io] = HUGE_VAL;
- /* but keep processing points! */
- }
- }
-
- return ret_errno;
-}
-
-/************************************************************************/
-/* pj_geocentric_to_geodetic() */
-/************************************************************************/
-
-int pj_geocentric_to_geodetic( double a, double es,
- long point_count, int point_offset,
- double *x, double *y, double *z )
-
-{
- double b;
- int i;
- GeocentricInfo gi;
-
- if( es == 0.0 )
- b = a;
- else
- b = a * sqrt(1-es);
-
- if( pj_Set_Geocentric_Parameters( &gi, a, b ) != 0 )
- {
- return PJD_ERR_GEOCENTRIC;
- }
-
- for( i = 0; i < point_count; i++ )
- {
- long io = i * point_offset;
-
- if( x[io] == HUGE_VAL )
- continue;
-
- pj_Convert_Geocentric_To_Geodetic( &gi, x[io], y[io], z[io],
- y+io, x+io, z+io );
- }
-
- return 0;
-}
-
-/************************************************************************/
-/* pj_compare_datums() */
-/* */
-/* Returns TRUE if the two datums are identical, otherwise */
-/* FALSE. */
-/************************************************************************/
-
-int pj_compare_datums( PJ *srcdefn, PJ *dstdefn )
-
-{
- if( srcdefn->datum_type != dstdefn->datum_type )
- {
- return 0;
- }
- else if( srcdefn->a_orig != dstdefn->a_orig
- || ABS(srcdefn->es_orig - dstdefn->es_orig) > 0.000000000050 )
- {
- /* the tolerance for es is to ensure that GRS80 and WGS84 are
- considered identical */
- return 0;
- }
- else if( srcdefn->datum_type == PJD_3PARAM )
- {
- return (srcdefn->datum_params[0] == dstdefn->datum_params[0]
- && srcdefn->datum_params[1] == dstdefn->datum_params[1]
- && srcdefn->datum_params[2] == dstdefn->datum_params[2]);
- }
- else if( srcdefn->datum_type == PJD_7PARAM )
- {
- return (srcdefn->datum_params[0] == dstdefn->datum_params[0]
- && srcdefn->datum_params[1] == dstdefn->datum_params[1]
- && srcdefn->datum_params[2] == dstdefn->datum_params[2]
- && srcdefn->datum_params[3] == dstdefn->datum_params[3]
- && srcdefn->datum_params[4] == dstdefn->datum_params[4]
- && srcdefn->datum_params[5] == dstdefn->datum_params[5]
- && srcdefn->datum_params[6] == dstdefn->datum_params[6]);
- }
- else if( srcdefn->datum_type == PJD_GRIDSHIFT )
- {
- const char* srcnadgrids =
- pj_param(srcdefn->ctx, srcdefn->params,"snadgrids").s;
- const char* dstnadgrids =
- pj_param(dstdefn->ctx, dstdefn->params,"snadgrids").s;
- return srcnadgrids != nullptr && dstnadgrids != nullptr &&
- strcmp( srcnadgrids, dstnadgrids ) == 0;
- }
- else
- return 1;
-}
-
-/************************************************************************/
-/* pj_geocentic_to_wgs84() */
-/************************************************************************/
-
-static
-int pj_geocentric_to_wgs84( PJ *defn,
- long point_count, int point_offset,
- double *x, double *y, double *z )
-
-{
- int i;
-
- if( defn->datum_type == PJD_3PARAM )
- {
- for( i = 0; i < point_count; i++ )
- {
- long io = i * point_offset;
-
- if( x[io] == HUGE_VAL )
- continue;
-
- x[io] = x[io] + Dx_BF;
- y[io] = y[io] + Dy_BF;
- z[io] = z[io] + Dz_BF;
- }
- }
- else if( defn->datum_type == PJD_7PARAM )
- {
- for( i = 0; i < point_count; i++ )
- {
- long io = i * point_offset;
- double x_out, y_out, z_out;
-
- if( x[io] == HUGE_VAL )
- continue;
-
- x_out = M_BF*( x[io] - Rz_BF*y[io] + Ry_BF*z[io]) + Dx_BF;
- y_out = M_BF*( Rz_BF*x[io] + y[io] - Rx_BF*z[io]) + Dy_BF;
- z_out = M_BF*(-Ry_BF*x[io] + Rx_BF*y[io] + z[io]) + Dz_BF;
-
- x[io] = x_out;
- y[io] = y_out;
- z[io] = z_out;
- }
- }
-
- return 0;
-}
-
-/************************************************************************/
-/* pj_geocentic_from_wgs84() */
-/************************************************************************/
-
-static
-int pj_geocentric_from_wgs84( PJ *defn,
- long point_count, int point_offset,
- double *x, double *y, double *z )
-
-{
- int i;
-
- if( defn->datum_type == PJD_3PARAM )
- {
- for( i = 0; i < point_count; i++ )
- {
- long io = i * point_offset;
-
- if( x[io] == HUGE_VAL )
- continue;
-
- x[io] = x[io] - Dx_BF;
- y[io] = y[io] - Dy_BF;
- z[io] = z[io] - Dz_BF;
- }
- }
- else if( defn->datum_type == PJD_7PARAM )
- {
- for( i = 0; i < point_count; i++ )
- {
- long io = i * point_offset;
- double x_tmp, y_tmp, z_tmp;
-
- if( x[io] == HUGE_VAL )
- continue;
-
- x_tmp = (x[io] - Dx_BF) / M_BF;
- y_tmp = (y[io] - Dy_BF) / M_BF;
- z_tmp = (z[io] - Dz_BF) / M_BF;
-
- x[io] = x_tmp + Rz_BF*y_tmp - Ry_BF*z_tmp;
- y[io] = -Rz_BF*x_tmp + y_tmp + Rx_BF*z_tmp;
- z[io] = Ry_BF*x_tmp - Rx_BF*y_tmp + z_tmp;
- }
- }
-
- return 0;
-}
-
-
-/************************************************************************/
-/* pj_apply_gridshift_2() */
-/* */
-/* This implementation uses the gridlist from a coordinate */
-/* system definition. If the gridlist has not yet been */
-/* populated in the coordinate system definition we set it up */
-/* now. */
-/************************************************************************/
-static
-int pj_apply_gridshift_2( PJ *defn, int inverse,
- long point_count, int point_offset,
- double *x, double *y, double * /*z*/ )
-
-{
- if( defn->hgrids_legacy == nullptr )
- {
- defn->hgrids_legacy = new ListOfHGrids;
- auto hgrids = pj_hgrid_init(defn, "nadgrids");
- if( hgrids.empty() )
- return 0;
- *static_cast<ListOfHGrids*>(defn->hgrids_legacy) = std::move(hgrids);
- }
- if( static_cast<ListOfHGrids*>(defn->hgrids_legacy)->empty() )
- {
- return 0;
- }
-
- for( long i = 0; i < point_count; i++ )
- {
- PJ_LP input;
-
- long io = i * point_offset;
- input.phi = y[io];
- input.lam = x[io];
-
- auto output = pj_hgrid_apply(defn->ctx, *static_cast<ListOfHGrids*>(defn->hgrids_legacy), input, inverse ? PJ_INV : PJ_FWD);
-
- if ( output.lam != HUGE_VAL )
- {
- y[io] = output.phi;
- x[io] = output.lam;
- }
- else
- {
- if( defn->ctx->debug_level >= PJ_LOG_DEBUG_MAJOR )
- {
- pj_log( defn->ctx, PJ_LOG_DEBUG_MAJOR,
- "pj_apply_gridshift(): failed to find a grid shift table for\n"
- " location (%.7fdW,%.7fdN)",
- x[io] * RAD_TO_DEG,
- y[io] * RAD_TO_DEG );
- }
- }
- }
-
- return 0;
-}
-
-
-/************************************************************************/
-/* pj_datum_transform() */
-/* */
-/* The input should be long/lat/z coordinates in radians in the */
-/* source datum, and the output should be long/lat/z */
-/* coordinates in radians in the destination datum. */
-/************************************************************************/
-
-int pj_datum_transform( PJ *src, PJ *dst,
- long point_count, int point_offset,
- double *x, double *y, double *z )
-
-{
- double src_a, src_es, dst_a, dst_es;
- int z_is_temp = FALSE;
-
-/* -------------------------------------------------------------------- */
-/* We cannot do any meaningful datum transformation if either */
-/* the source or destination are of an unknown datum type */
-/* (ie. only a +ellps declaration, no +datum). This is new */
-/* behavior for PROJ 4.6.0. */
-/* -------------------------------------------------------------------- */
- if( src->datum_type == PJD_UNKNOWN
- || dst->datum_type == PJD_UNKNOWN )
- return 0;
-
-/* -------------------------------------------------------------------- */
-/* Short cut if the datums are identical. */
-/* -------------------------------------------------------------------- */
- if( pj_compare_datums( src, dst ) )
- return 0;
-
- src_a = src->a_orig;
- src_es = src->es_orig;
-
- dst_a = dst->a_orig;
- dst_es = dst->es_orig;
-
-/* -------------------------------------------------------------------- */
-/* Create a temporary Z array if one is not provided. */
-/* -------------------------------------------------------------------- */
- if( z == nullptr )
- {
- size_t bytes = sizeof(double) * point_count * point_offset;
- z = (double *) pj_malloc(bytes);
- memset( z, 0, bytes );
- z_is_temp = TRUE;
- }
-
-#define CHECK_RETURN(defn) {if( defn->ctx->last_errno != 0 && (defn->ctx->last_errno > 0 || get_transient_error_value(-defn->ctx->last_errno) == 0) ) { if( z_is_temp ) pj_dalloc(z); return defn->ctx->last_errno; }}
-
-/* -------------------------------------------------------------------- */
-/* If this datum requires grid shifts, then apply it to geodetic */
-/* coordinates. */
-/* -------------------------------------------------------------------- */
- if( src->datum_type == PJD_GRIDSHIFT )
- {
- pj_apply_gridshift_2( src, 0, point_count, point_offset, x, y, z );
- CHECK_RETURN(src);
-
- src_a = SRS_WGS84_SEMIMAJOR;
- src_es = SRS_WGS84_ESQUARED;
- }
-
- if( dst->datum_type == PJD_GRIDSHIFT )
- {
- dst_a = SRS_WGS84_SEMIMAJOR;
- dst_es = SRS_WGS84_ESQUARED;
- }
-
-/* ==================================================================== */
-/* Do we need to go through geocentric coordinates? */
-/* ==================================================================== */
- if( src_es != dst_es || src_a != dst_a
- || src->datum_type == PJD_3PARAM
- || src->datum_type == PJD_7PARAM
- || dst->datum_type == PJD_3PARAM
- || dst->datum_type == PJD_7PARAM)
- {
-/* -------------------------------------------------------------------- */
-/* Convert to geocentric coordinates. */
-/* -------------------------------------------------------------------- */
- src->ctx->last_errno =
- pj_geodetic_to_geocentric( src_a, src_es,
- point_count, point_offset, x, y, z );
- CHECK_RETURN(src);
-
-/* -------------------------------------------------------------------- */
-/* Convert between datums. */
-/* -------------------------------------------------------------------- */
- if( src->datum_type == PJD_3PARAM
- || src->datum_type == PJD_7PARAM )
- {
- pj_geocentric_to_wgs84( src, point_count, point_offset,x,y,z);
- CHECK_RETURN(src);
- }
-
- if( dst->datum_type == PJD_3PARAM
- || dst->datum_type == PJD_7PARAM )
- {
- pj_geocentric_from_wgs84( dst, point_count,point_offset,x,y,z);
- CHECK_RETURN(dst);
- }
-
-/* -------------------------------------------------------------------- */
-/* Convert back to geodetic coordinates. */
-/* -------------------------------------------------------------------- */
- dst->ctx->last_errno =
- pj_geocentric_to_geodetic( dst_a, dst_es,
- point_count, point_offset, x, y, z );
- CHECK_RETURN(dst);
- }
-
-/* -------------------------------------------------------------------- */
-/* Apply grid shift to destination if required. */
-/* -------------------------------------------------------------------- */
- if( dst->datum_type == PJD_GRIDSHIFT )
- {
- pj_apply_gridshift_2( dst, 1, point_count, point_offset, x, y, z );
- CHECK_RETURN(dst);
- }
-
- if( z_is_temp )
- pj_dalloc( z );
-
- return 0;
-}
-
-/************************************************************************/
-/* adjust_axis() */
-/* */
-/* Normalize or de-normalized the x/y/z axes. The normal form */
-/* is "enu" (easting, northing, up). */
-/************************************************************************/
-static int adjust_axis( projCtx ctx,
- const char *axis, int denormalize_flag,
- long point_count, int point_offset,
- double *x, double *y, double *z )
-
-{
- double x_in, y_in, z_in = 0.0;
- int i, i_axis;
-
- if( !denormalize_flag )
- {
- for( i = 0; i < point_count; i++ )
- {
- x_in = x[point_offset*i];
- y_in = y[point_offset*i];
- if( z )
- z_in = z[point_offset*i];
-
- for( i_axis = 0; i_axis < 3; i_axis++ )
- {
- double value;
-
- if( i_axis == 0 )
- value = x_in;
- else if( i_axis == 1 )
- value = y_in;
- else
- value = z_in;
-
- switch( axis[i_axis] )
- {
- case 'e':
- x[point_offset*i] = value;
- break;
- case 'w':
- x[point_offset*i] = -value;
- break;
- case 'n':
- y[point_offset*i] = value;
- break;
- case 's':
- y[point_offset*i] = -value;
- break;
- case 'u':
- if( z )
- z[point_offset*i] = value;
- break;
- case 'd':
- if( z )
- z[point_offset*i] = -value;
- break;
- default:
- pj_ctx_set_errno( ctx, PJD_ERR_AXIS );
- return PJD_ERR_AXIS;
- }
- } /* i_axis */
- } /* i (point) */
- }
-
- else /* denormalize */
- {
- for( i = 0; i < point_count; i++ )
- {
- x_in = x[point_offset*i];
- y_in = y[point_offset*i];
- if( z )
- z_in = z[point_offset*i];
-
- for( i_axis = 0; i_axis < 3; i_axis++ )
- {
- double *target;
-
- if( i_axis == 2 && z == nullptr )
- continue;
-
- if( i_axis == 0 )
- target = x;
- else if( i_axis == 1 )
- target = y;
- else
- target = z;
-
- switch( axis[i_axis] )
- {
- case 'e':
- target[point_offset*i] = x_in; break;
- case 'w':
- target[point_offset*i] = -x_in; break;
- case 'n':
- target[point_offset*i] = y_in; break;
- case 's':
- target[point_offset*i] = -y_in; break;
- case 'u':
- target[point_offset*i] = z_in; break;
- case 'd':
- target[point_offset*i] = -z_in; break;
- default:
- pj_ctx_set_errno( ctx, PJD_ERR_AXIS );
- return PJD_ERR_AXIS;
- }
- } /* i_axis */
- } /* i (point) */
- }
-
- return 0;
-}
-// ---------------------------------------------------------------------------
-
-void pj_deallocate_grids()
-{
-}
diff --git a/src/transformations/affine.cpp b/src/transformations/affine.cpp
index 28f73b9a..43fd8642 100644
--- a/src/transformations/affine.cpp
+++ b/src/transformations/affine.cpp
@@ -110,7 +110,7 @@ static PJ_LP reverse_2d(PJ_XY xy, PJ *P) {
}
static struct pj_opaque_affine * initQ() {
- struct pj_opaque_affine *Q = static_cast<struct pj_opaque_affine *>(pj_calloc(1, sizeof(struct pj_opaque_affine)));
+ struct pj_opaque_affine *Q = static_cast<struct pj_opaque_affine *>(calloc(1, sizeof(struct pj_opaque_affine)));
if (nullptr==Q)
return nullptr;
diff --git a/src/transformations/helmert.cpp b/src/transformations/helmert.cpp
index d3857d89..99aa74a4 100644
--- a/src/transformations/helmert.cpp
+++ b/src/transformations/helmert.cpp
@@ -476,7 +476,7 @@ static PJ_COORD helmert_reverse_4d (PJ_COORD point, PJ *P) {
static PJ* init_helmert_six_parameters(PJ* P) {
- struct pj_opaque_helmert *Q = static_cast<struct pj_opaque_helmert*>(pj_calloc (1, sizeof (struct pj_opaque_helmert)));
+ struct pj_opaque_helmert *Q = static_cast<struct pj_opaque_helmert*>(calloc (1, sizeof (struct pj_opaque_helmert)));
if (nullptr==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = (void *) Q;
diff --git a/src/transformations/horner.cpp b/src/transformations/horner.cpp
index a6638773..2c049186 100644
--- a/src/transformations/horner.cpp
+++ b/src/transformations/horner.cpp
@@ -89,8 +89,8 @@
PROJ_HEAD(horner, "Horner polynomial evaluation");
/* make horner.h interface with proj's memory management */
-#define horner_dealloc(x) pj_dealloc(x)
-#define horner_calloc(n,x) pj_calloc(n,x)
+#define horner_dealloc(x) free(x)
+#define horner_calloc(n,x) calloc(n,x)
namespace { // anonymous namespace
struct horner {
@@ -412,7 +412,7 @@ static int parse_coefs (PJ *P, double *coefs, const char *param, int ncoefs) {
char *buf, *init, *next = nullptr;
int i;
- buf = static_cast<char*>(pj_calloc (strlen (param) + 2, sizeof(char)));
+ buf = static_cast<char*>(calloc (strlen (param) + 2, sizeof(char)));
if (nullptr==buf) {
proj_log_error (P, "Horner: No memory left");
return 0;
@@ -420,12 +420,12 @@ static int parse_coefs (PJ *P, double *coefs, const char *param, int ncoefs) {
sprintf (buf, "t%s", param);
if (0==pj_param (P->ctx, P->params, buf).i) {
- pj_dealloc (buf);
+ free (buf);
return 0;
}
sprintf (buf, "s%s", param);
init = pj_param(P->ctx, P->params, buf).s;
- pj_dealloc (buf);
+ free (buf);
for (i = 0; i < ncoefs; i++) {
if (i > 0) {
diff --git a/src/transformations/molodensky.cpp b/src/transformations/molodensky.cpp
index 7d17f64c..bf5960d2 100644
--- a/src/transformations/molodensky.cpp
+++ b/src/transformations/molodensky.cpp
@@ -298,7 +298,7 @@ static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) {
PJ *TRANSFORMATION(molodensky,1) {
int count_required_params = 0;
- struct pj_opaque_molodensky *Q = static_cast<struct pj_opaque_molodensky*>(pj_calloc(1, sizeof(struct pj_opaque_molodensky)));
+ struct pj_opaque_molodensky *Q = static_cast<struct pj_opaque_molodensky*>(calloc(1, sizeof(struct pj_opaque_molodensky)));
if (nullptr==Q)
return pj_default_destructor(P, ENOMEM);
P->opaque = (void *) Q;
diff --git a/src/tsfn.cpp b/src/tsfn.cpp
index 32da09f2..8ed258d6 100644
--- a/src/tsfn.cpp
+++ b/src/tsfn.cpp
@@ -4,14 +4,28 @@
#include "proj_internal.h"
double pj_tsfn(double phi, double sinphi, double e) {
- double denominator;
- sinphi *= e;
+ /****************************************************************************
+ * Determine function ts(phi) defined in Snyder (1987), Eq. (7-10)
+ * Inputs:
+ * phi = geographic latitude (radians)
+ * e = eccentricity of the ellipsoid (dimensionless)
+ * Output:
+ * ts = exp(-psi) where psi is the isometric latitude (dimensionless)
+ * = 1 / (tan(chi) + sec(chi))
+ * Here isometric latitude is defined by
+ * psi = log( tan(pi/4 + phi/2) *
+ * ( (1 - e*sin(phi)) / (1 + e*sin(phi)) )^(e/2) )
+ * = asinh(tan(phi)) - e * atanh(e * sin(phi))
+ * = asinh(tan(chi))
+ * chi = conformal latitude
+ ***************************************************************************/
- /* avoid zero division, fail gracefully */
- denominator = 1.0 + sinphi;
- if (denominator == 0.0)
- return HUGE_VAL;
-
- return (tan (.5 * (M_HALFPI - phi)) /
- pow((1. - sinphi) / (denominator), .5 * e));
+ double cosphi = cos(phi);
+ // exp(-asinh(tan(phi))) = 1 / (tan(phi) + sec(phi))
+ // = cos(phi) / (1 + sin(phi)) good for phi > 0
+ // = (1 - sin(phi)) / cos(phi) good for phi < 0
+ return exp(e * atanh(e * sinphi)) *
+ ( sinphi > 0 ?
+ cosphi / (1 + sinphi) :
+ (1 - sinphi) / cosphi );
}
diff --git a/src/utils.cpp b/src/utils.cpp
deleted file mode 100644
index 9cb13f44..00000000
--- a/src/utils.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/******************************************************************************
- * Project: PROJ.4
- * Purpose: Some utility functions we don't want to bother putting in
- * their own source files.
- * Author: Frank Warmerdam, warmerdam@pobox.com
- *
- ******************************************************************************
- * Copyright (c) 2001, Frank Warmerdam
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *****************************************************************************/
-
-#define PJ_LIB__
-
-#include <stdio.h>
-#include <string.h>
-
-#include "proj.h"
-#include "proj_internal.h"
-
-/************************************************************************/
-/* pj_is_latlong() */
-/* */
-/* Returns TRUE if this coordinate system object is */
-/* geographic. */
-/************************************************************************/
-
-int pj_is_latlong( PJ *pj )
-
-{
- return pj == nullptr || pj->is_latlong;
-}
-
-/************************************************************************/
-/* pj_is_geocent() */
-/* */
-/* Returns TRUE if this coordinate system object is geocentric. */
-/************************************************************************/
-
-int pj_is_geocent( PJ *pj )
-
-{
- return pj != nullptr && pj->is_geocent;
-}
-
-/************************************************************************/
-/* pj_latlong_from_proj() */
-/* */
-/* Return a PJ* definition defining the lat/long coordinate */
-/* system on which a projection is based. If the coordinate */
-/* system passed in is latlong, a clone of the same will be */
-/* returned. */
-/************************************************************************/
-
-PJ *pj_latlong_from_proj( PJ *pj_in )
-
-{
- char defn[512];
- int got_datum = FALSE;
-
- pj_errno = 0;
- strcpy( defn, "+proj=latlong" );
-
- if( pj_param(pj_in->ctx, pj_in->params, "tdatum").i )
- {
- got_datum = TRUE;
- sprintf( defn+strlen(defn), " +datum=%s",
- pj_param(pj_in->ctx, pj_in->params,"sdatum").s );
- }
- else if( pj_param(pj_in->ctx, pj_in->params, "tellps").i )
- {
- sprintf( defn+strlen(defn), " +ellps=%s",
- pj_param(pj_in->ctx, pj_in->params,"sellps").s );
- }
- else if( pj_param(pj_in->ctx,pj_in->params, "ta").i )
- {
- sprintf( defn+strlen(defn), " +a=%s",
- pj_param(pj_in->ctx,pj_in->params,"sa").s );
-
- if( pj_param(pj_in->ctx,pj_in->params, "tb").i )
- sprintf( defn+strlen(defn), " +b=%s",
- pj_param(pj_in->ctx,pj_in->params,"sb").s );
- else if( pj_param(pj_in->ctx,pj_in->params, "tes").i )
- sprintf( defn+strlen(defn), " +es=%s",
- pj_param(pj_in->ctx,pj_in->params,"ses").s );
- else if( pj_param(pj_in->ctx,pj_in->params, "tf").i )
- sprintf( defn+strlen(defn), " +f=%s",
- pj_param(pj_in->ctx,pj_in->params,"sf").s );
- else
- {
- char* ptr = defn+strlen(defn);
- sprintf( ptr, " +es=%.16g", pj_in->es );
- /* TODO later: use C++ ostringstream with imbue(std::locale::classic()) */
- /* to be locale unaware */
- for(; *ptr; ptr++)
- {
- if( *ptr == ',' )
- *ptr = '.';
- }
- }
- }
- else
- {
- pj_ctx_set_errno( pj_in->ctx, PJD_ERR_MAJOR_AXIS_NOT_GIVEN );
-
- return nullptr;
- }
-
- if( !got_datum )
- {
- if( pj_param(pj_in->ctx,pj_in->params, "ttowgs84").i )
- sprintf( defn+strlen(defn), " +towgs84=%s",
- pj_param(pj_in->ctx,pj_in->params,"stowgs84").s );
-
- if( pj_param(pj_in->ctx,pj_in->params, "tnadgrids").i )
- sprintf( defn+strlen(defn), " +nadgrids=%s",
- pj_param(pj_in->ctx,pj_in->params,"snadgrids").s );
- }
-
- /* copy over some other information related to ellipsoid */
- if( pj_param(pj_in->ctx,pj_in->params, "tR").i )
- sprintf( defn+strlen(defn), " +R=%s",
- pj_param(pj_in->ctx,pj_in->params,"sR").s );
-
- if( pj_param(pj_in->ctx,pj_in->params, "tR_A").i )
- sprintf( defn+strlen(defn), " +R_A" );
-
- if( pj_param(pj_in->ctx,pj_in->params, "tR_V").i )
- sprintf( defn+strlen(defn), " +R_V" );
-
- if( pj_param(pj_in->ctx,pj_in->params, "tR_a").i )
- sprintf( defn+strlen(defn), " +R_a" );
-
- if( pj_param(pj_in->ctx,pj_in->params, "tR_lat_a").i )
- sprintf( defn+strlen(defn), " +R_lat_a=%s",
- pj_param(pj_in->ctx,pj_in->params,"sR_lat_a").s );
-
- if( pj_param(pj_in->ctx,pj_in->params, "tR_lat_g").i )
- sprintf( defn+strlen(defn), " +R_lat_g=%s",
- pj_param(pj_in->ctx,pj_in->params,"sR_lat_g").s );
-
- /* copy over prime meridian */
- if( pj_param(pj_in->ctx,pj_in->params, "tpm").i )
- sprintf( defn+strlen(defn), " +pm=%s",
- pj_param(pj_in->ctx,pj_in->params,"spm").s );
-
- return pj_init_plus_ctx( pj_in->ctx, defn );
-}
-
-/************************************************************************/
-/* pj_get_spheroid_defn() */
-/* */
-/* Fetch the internal definition of the spheroid. Note that */
-/* you can compute "b" from eccentricity_squared as: */
-/* */
-/* b = a * sqrt(1 - es) */
-/************************************************************************/
-
-void pj_get_spheroid_defn(projPJ defn, double *major_axis, double *eccentricity_squared)
-{
- if ( major_axis )
- *major_axis = defn->a;
-
- if ( eccentricity_squared )
- *eccentricity_squared = defn->es;
-}
diff --git a/src/wkt2_generated_parser.c b/src/wkt2_generated_parser.c
index feb2cc6b..f7bb5798 100644
--- a/src/wkt2_generated_parser.c
+++ b/src/wkt2_generated_parser.c
@@ -542,16 +542,16 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 106
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 3132
+#define YYLAST 3219
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 164
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 353
/* YYNRULES -- Number of rules. */
-#define YYNRULES 694
+#define YYNRULES 695
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 1427
+#define YYNSTATES 1429
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
@@ -658,30 +658,30 @@ static const yytype_uint16 yyrline[] =
997, 1003, 1003, 1007, 1007, 1008, 1008, 1010, 1015, 1016,
1017, 1018, 1019, 1021, 1027, 1032, 1038, 1040, 1042, 1044,
1048, 1054, 1055, 1056, 1058, 1060, 1062, 1066, 1066, 1068,
- 1070, 1075, 1076, 1078, 1080, 1082, 1084, 1088, 1088, 1090,
- 1096, 1103, 1103, 1106, 1113, 1114, 1115, 1116, 1117, 1119,
- 1123, 1125, 1127, 1127, 1131, 1136, 1136, 1136, 1140, 1145,
- 1145, 1147, 1151, 1151, 1155, 1160, 1162, 1166, 1166, 1170,
- 1175, 1177, 1181, 1182, 1183, 1184, 1185, 1187, 1187, 1189,
- 1192, 1194, 1194, 1196, 1198, 1200, 1204, 1210, 1211, 1212,
- 1213, 1215, 1217, 1221, 1226, 1228, 1231, 1236, 1240, 1246,
- 1246, 1246, 1246, 1246, 1246, 1250, 1255, 1257, 1262, 1262,
- 1263, 1265, 1265, 1267, 1274, 1274, 1276, 1283, 1283, 1285,
- 1292, 1299, 1304, 1305, 1306, 1308, 1314, 1319, 1327, 1333,
- 1335, 1337, 1343, 1345, 1345, 1346, 1346, 1350, 1356, 1356,
- 1358, 1363, 1369, 1374, 1380, 1385, 1390, 1396, 1401, 1406,
- 1412, 1417, 1422, 1428, 1428, 1429, 1429, 1430, 1430, 1431,
- 1431, 1432, 1432, 1433, 1433, 1436, 1436, 1438, 1439, 1440,
- 1442, 1444, 1448, 1451, 1451, 1454, 1455, 1456, 1458, 1462,
- 1463, 1465, 1467, 1467, 1468, 1468, 1469, 1469, 1469, 1470,
- 1471, 1471, 1472, 1472, 1473, 1473, 1475, 1475, 1476, 1476,
- 1477, 1478, 1478, 1482, 1486, 1487, 1490, 1495, 1496, 1497,
- 1498, 1499, 1500, 1501, 1503, 1505, 1507, 1510, 1512, 1514,
- 1516, 1518, 1520, 1522, 1524, 1526, 1528, 1533, 1537, 1538,
- 1541, 1546, 1547, 1548, 1549, 1550, 1552, 1557, 1562, 1563,
- 1566, 1572, 1572, 1572, 1572, 1574, 1575, 1576, 1577, 1579,
- 1581, 1586, 1592, 1594, 1599, 1600, 1603, 1609, 1609, 1611,
- 1612, 1613, 1614, 1616, 1618
+ 1070, 1075, 1076, 1077, 1079, 1081, 1083, 1085, 1089, 1089,
+ 1091, 1097, 1104, 1104, 1107, 1114, 1115, 1116, 1117, 1118,
+ 1120, 1124, 1126, 1128, 1128, 1132, 1137, 1137, 1137, 1141,
+ 1146, 1146, 1148, 1152, 1152, 1156, 1161, 1163, 1167, 1167,
+ 1171, 1176, 1178, 1182, 1183, 1184, 1185, 1186, 1188, 1188,
+ 1190, 1193, 1195, 1195, 1197, 1199, 1201, 1205, 1211, 1212,
+ 1213, 1214, 1216, 1218, 1222, 1227, 1229, 1232, 1237, 1241,
+ 1247, 1247, 1247, 1247, 1247, 1247, 1251, 1256, 1258, 1263,
+ 1263, 1264, 1266, 1266, 1268, 1275, 1275, 1277, 1284, 1284,
+ 1286, 1293, 1300, 1305, 1306, 1307, 1309, 1315, 1320, 1328,
+ 1334, 1336, 1338, 1344, 1346, 1346, 1347, 1347, 1351, 1357,
+ 1357, 1359, 1364, 1370, 1375, 1381, 1386, 1391, 1397, 1402,
+ 1407, 1413, 1418, 1423, 1429, 1429, 1430, 1430, 1431, 1431,
+ 1432, 1432, 1433, 1433, 1434, 1434, 1437, 1437, 1439, 1440,
+ 1441, 1443, 1445, 1449, 1452, 1452, 1455, 1456, 1457, 1459,
+ 1463, 1464, 1466, 1468, 1468, 1469, 1469, 1470, 1470, 1470,
+ 1471, 1472, 1472, 1473, 1473, 1474, 1474, 1476, 1476, 1477,
+ 1477, 1478, 1479, 1479, 1483, 1487, 1488, 1491, 1496, 1497,
+ 1498, 1499, 1500, 1501, 1502, 1504, 1506, 1508, 1511, 1513,
+ 1515, 1517, 1519, 1521, 1523, 1525, 1527, 1529, 1534, 1538,
+ 1539, 1542, 1547, 1548, 1549, 1550, 1551, 1553, 1558, 1563,
+ 1564, 1567, 1573, 1573, 1573, 1573, 1575, 1576, 1577, 1578,
+ 1580, 1582, 1587, 1593, 1595, 1600, 1601, 1604, 1610, 1610,
+ 1612, 1613, 1614, 1615, 1617, 1619
};
#endif
@@ -933,7 +933,7 @@ static const yytype_uint16 yytoknum[] =
#define yypact_value_is_default(Yystate) \
(!!((Yystate) == (-1232)))
-#define YYTABLE_NINF -633
+#define YYTABLE_NINF -634
#define yytable_value_is_error(Yytable_value) \
0
@@ -942,149 +942,149 @@ static const yytype_uint16 yytoknum[] =
STATE-NUM. */
static const yytype_int16 yypact[] =
{
- 2573, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232,
+ 1574, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232,
-1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232,
-1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232,
- -1232, -1232, -1232, -1232, -1232, -1232, -1232, 114, -1232, -1232,
- -1232, 231, -1232, -1232, -1232, 231, -1232, -1232, -1232, -1232,
- -1232, -1232, 231, 231, -1232, 231, -1232, -75, 231, -1232,
- 231, -1232, 231, -1232, -1232, -1232, 231, -1232, 231, -1232,
- 231, -1232, 231, -1232, 231, -1232, 231, -1232, 231, -1232,
- 231, -1232, -1232, -1232, -1232, -1232, -1232, -1232, 231, -1232,
- -1232, -1232, -1232, -1232, -1232, 231, -1232, 231, -1232, 231,
- -1232, 231, -1232, 231, -1232, 231, -1232, -1232, -1232, 33,
- 33, 33, 33, 33, -1232, 81, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 879,
- 33, 33, 33, 117, -1232, -1232, -75, -1232, -75, -1232,
- -75, -75, -1232, -75, -1232, -1232, -1232, 231, -1232, -75,
- -75, -1232, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -1232, -75, -1232, -75, -1232, -1232, -1232, -1232, 28,
- -1232, -1232, -1232, -1232, -1232, 97, 168, 186, -1232, -1232,
- -1232, -1232, 284, -1232, -75, -1232, -75, -75, -75, -1232,
- -75, 231, 1038, 176, 66, 66, 713, 33, 287, 179,
- 157, 766, 290, 284, 244, 284, 413, 284, 105, 286,
- 284, 297, 1406, -1232, -1232, -1232, 428, 101, -1232, -1232,
- 101, -1232, -1232, 101, -1232, -1232, 331, 879, -1232, -1232,
- -1232, -1232, -1232, -1232, -1232, 728, -1232, -1232, -1232, -1232,
- 265, 278, 293, 713, -1232, -75, -1232, -75, 231, -1232,
- -1232, -1232, -1232, 231, -75, 231, -75, -1232, 231, 231,
- -75, -75, -1232, -1232, -1232, -1232, -75, -75, -75, -75,
- -1232, -75, -1232, -75, -75, -75, -1232, -1232, -1232, -1232,
- 231, 231, -1232, -1232, -75, 231, -1232, -1232, 231, -75,
- -75, -1232, -75, -1232, -1232, 231, -1232, -75, -75, 231,
- -1232, -1232, -75, -75, 231, -1232, -1232, -75, -75, 231,
- -1232, -1232, -75, -75, 231, -1232, -1232, -75, -75, 231,
- -75, 231, -1232, -1232, -75, 231, -1232, -75, -1232, -1232,
- -1232, -1232, 231, -1232, -75, 231, -75, -75, -75, -75,
- -75, -1232, -75, 231, 284, -1232, 476, 728, -1232, -1232,
- 387, 284, 283, 284, 284, 33, 33, 59, 404, 258,
- 33, 33, 441, 441, 59, 258, 441, 441, 713, 476,
- 284, 452, 33, 33, 349, 284, 33, 33, 88, 477,
- 441, 33, 479, -1232, 479, 33, 477, 441, 33, 477,
- 441, 33, 477, 441, 33, -1232, -1232, 682, 74, -1232,
- 33, 441, 33, 1406, 728, 117, -1232, 33, 331, 117,
- -1232, 487, 117, -1232, 331, 469, 879, -1232, 728, -1232,
- -1232, -1232, -1232, -1232, -1232, -1232, -1232, -75, -75, 231,
- -1232, 231, -1232, -1232, -75, -75, 231, -75, -1232, -1232,
- -1232, -75, -75, -75, -1232, -75, 231, -1232, -1232, -1232,
- -1232, -1232, -1232, 231, 284, -75, -1232, -75, -75, -1232,
- -75, 231, -75, -75, 284, -75, -75, -1232, -75, -75,
- 713, 284, -1232, -75, -75, -75, -1232, -75, -75, 231,
- -1232, -1232, -75, -75, -75, 231, 284, -75, -75, -75,
- -75, -1232, 284, 284, -75, -75, 284, -75, -75, 284,
- -75, -75, -1232, -1232, 116, -1232, 284, -75, -1232, 284,
- -75, -75, -75, 293, 284, -1232, 284, -75, -1232, -75,
- 231, -75, -1232, -75, 231, 284, -1232, 488, 511, 33,
- 33, -1232, -1232, 479, -1232, 1192, 486, 479, 284, 176,
- 258, 614, 284, 728, 1482, -1232, 477, 56, 56, 477,
- 33, 477, 258, -1232, 477, 477, 148, 284, 345, -1232,
- -1232, -1232, 477, 56, 56, -1232, -1232, 33, 284, 176,
- 477, 1503, -1232, 477, 277, -1232, -1232, -1232, -1232, 477,
- -1, -1232, 477, -2, -1232, 477, 22, -1232, -1232, 728,
- -1232, -1232, 728, -1232, -1232, -1232, 477, 179, 1669, 284,
- 728, -1232, -1232, 487, 1210, 284, 33, 523, 1412, 284,
- 33, -1232, -75, -1232, -1232, 284, -1232, 284, -1232, -75,
- -1232, 284, -75, -1232, -75, -1232, -75, 284, -1232, -1232,
- -1232, 231, -1232, 293, 284, -1232, -1232, -1232, -1232, -1232,
- -1232, -1232, -1232, -1232, -75, -1232, -1232, -1232, -1232, -75,
- -75, -75, -1232, -75, -75, -75, -75, 284, -1232, -75,
- 284, 284, 284, 284, -1232, -1232, -75, -75, 231, -1232,
- -1232, -1232, -75, 231, 284, -75, -75, -75, -75, -1232,
- -75, -1232, -75, 284, -75, 284, -75, -75, 284, -75,
- 284, -75, 284, -75, 159, 401, -1232, 767, 284, -1232,
- -1232, -1232, -1232, -75, -1232, -1232, -1232, -1232, -1232, -1232,
- -1232, -1232, -1232, -1232, -1232, -75, 231, -75, 231, -1232,
- -75, 231, -75, 231, -75, 231, -75, 231, -75, -1232,
- 231, -75, -1232, -1232, -75, -1232, -1232, -1232, 231, -75,
- -75, 231, -75, 231, -1232, -1232, -75, -1232, 231, -1232,
- -1232, -75, 511, -1232, -1232, -1232, -1232, -1232, -1232, 257,
- -1232, 33, 728, -1232, 586, 586, 586, 586, 59, 196,
- 284, 59, 284, -1232, 487, -1232, -1232, -1232, -1232, -1232,
- -1232, 33, -1232, 33, -1232, 59, 141, 284, 59, 284,
- 476, 631, -1232, 586, -1232, 88, 284, -1232, 284, -1232,
- 284, -1232, 284, -1232, 728, -1232, -1232, 728, 728, -1232,
- 415, -1232, -1232, -1232, -1232, 452, 145, 548, 528, -1232,
- 33, 547, -1232, 33, 322, -1232, 1192, 325, -1232, 1192,
- 267, -1232, 682, -1232, 439, -1232, 980, 284, 33, -1232,
- -1232, 33, -1232, 1192, 479, 284, 282, 42, -1232, -1232,
- -1232, -75, -1232, -75, -1232, -1232, -1232, -1232, -75, -75,
- -75, -75, -75, -75, -75, -1232, -75, -1232, -75, -1232,
- -75, -75, -75, -75, -1232, -75, -75, -1232, -75, -1232,
- -1232, -75, -75, -75, -75, -1232, -1232, -1232, -1232, -1232,
- 433, 415, -1232, 767, 728, -1232, -75, -1232, -75, -1232,
- -75, -1232, -75, -1232, -1232, 284, -75, -75, -75, -1232,
- 284, -75, -75, -1232, -75, -75, -1232, -75, -1232, -1232,
- -75, -1232, 284, -1232, -1232, -75, -75, -75, 231, -75,
- -1232, -75, -75, 284, -1232, -1232, -1232, -1232, -1232, -1232,
- 284, -75, -75, 284, 284, 284, 284, 284, 284, -1232,
- -1232, 284, 259, 284, 713, 713, 284, -1232, 345, -1232,
- -1232, 284, 456, 284, 284, 284, -1232, -1232, 728, -1232,
- -1232, -1232, 284, -1232, 212, -1232, -1232, 322, -1232, 325,
- -1232, -1232, -1232, 325, -1232, -1232, 1192, -1232, 1192, 682,
- -1232, -1232, -1232, 1052, -1232, 879, -1232, 476, 33, -1232,
- -75, 167, 487, -1232, -1232, -75, -75, -75, -75, -1232,
- -1232, -75, -75, -75, -1232, -1232, -75, -75, -1232, -75,
- -1232, -1232, -1232, -1232, -1232, -1232, 231, -75, -1232, -75,
- -1232, -1232, -1232, 1008, -1232, 284, -75, -75, -75, -1232,
- -75, -75, -75, -75, -1232, -75, -1232, -75, -1232, -1232,
- 284, -75, 284, -75, -1232, -75, 523, 231, -1232, -75,
- -1232, 595, 595, 595, 595, -1232, -1232, -1232, 284, 284,
- -1232, 33, -1232, 595, 1080, -1232, -1232, 315, 622, 553,
- 325, -1232, -1232, -1232, -1232, 1192, 376, 284, -1232, -1232,
- -1232, 775, 284, 231, 33, 1141, 284, -1232, -75, 231,
- -75, 231, -75, -75, 231, -1232, -1232, -75, -75, 525,
- 1080, -1232, -75, -75, -1232, -75, -1232, -1232, -75, -1232,
- -75, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -75,
- -1232, 231, -1232, 282, -75, -1232, -75, -75, -1232, 696,
- -1232, 33, 688, -1232, 33, -1232, 974, -1232, 33, 713,
- 1086, -1232, -1232, 622, 553, 553, -1232, 1192, 284, 33,
- 284, 476, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232,
- -1232, -1232, -1232, -1232, -1232, 231, -1232, 231, -75, -1232,
- -75, -1232, -75, -75, -75, -1232, -75, -75, -75, -1232,
- -1232, -75, -75, 231, -75, -1232, -1232, -1232, -1232, 284,
- -1232, -75, -75, -75, 33, 33, 1412, 2101, -1232, -1232,
- 2559, -1232, 2630, 284, 478, -1232, -1232, 33, 553, -1232,
- 713, 284, 1469, 284, 284, -75, -75, -1232, -1232, -1232,
+ -1232, -1232, -1232, -1232, -1232, -1232, -1232, 62, -1232, -1232,
+ -1232, 98, -1232, -1232, -1232, 98, -1232, -1232, -1232, -1232,
+ -1232, -1232, 98, 98, -1232, 98, -1232, -87, 98, -1232,
+ 98, -1232, 98, -1232, -1232, -1232, 98, -1232, 98, -1232,
+ 98, -1232, 98, -1232, 98, -1232, 98, -1232, 98, -1232,
+ 98, -1232, -1232, -1232, -1232, -1232, -1232, -1232, 98, -1232,
+ -1232, -1232, -1232, -1232, -1232, 98, -1232, 98, -1232, 98,
+ -1232, 98, -1232, 98, -1232, 98, -1232, -1232, -1232, -24,
+ -24, -24, -24, -24, -1232, 83, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24, -24, -24, 810,
+ -24, -24, -24, 113, -1232, -1232, -87, -1232, -87, -1232,
+ -87, -87, -1232, -87, -1232, -1232, -1232, 98, -1232, -87,
+ -87, -1232, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -1232, -87, -1232, -87, -1232, -1232, -1232, -1232, 26,
+ -1232, -1232, -1232, -1232, -1232, 37, 52, 179, -1232, -1232,
+ -1232, -1232, 360, -1232, -87, -1232, -87, -87, -87, -1232,
+ -87, 98, 1048, 212, 59, 59, 761, -24, 256, 138,
+ 156, 467, 304, 360, 203, 360, 322, 360, 217, 314,
+ 360, 275, 1439, -1232, -1232, -1232, 483, 69, -1232, -1232,
+ 69, -1232, -1232, 69, -1232, -1232, 335, 810, -1232, -1232,
+ -1232, -1232, -1232, -1232, -1232, 462, -1232, -1232, -1232, -1232,
+ 252, 265, 287, 761, -1232, -87, -1232, -87, 98, -1232,
+ -1232, -1232, -1232, 98, -87, 98, -87, -1232, 98, 98,
+ -87, -87, -1232, -1232, -1232, -1232, -87, -87, -87, -87,
+ -1232, -87, -1232, -87, -87, -87, -1232, -1232, -1232, -1232,
+ 98, 98, -1232, -1232, -87, 98, -1232, -1232, 98, -87,
+ -87, -1232, -87, -1232, -1232, 98, -1232, -87, -87, 98,
+ -1232, -1232, -87, -87, 98, -1232, -1232, -87, -87, 98,
+ -1232, -1232, -87, -87, 98, -1232, -1232, -87, -87, 98,
+ -87, 98, -1232, -1232, -87, 98, -1232, -87, -1232, -1232,
+ -1232, -1232, 98, -1232, -87, 98, -87, -87, -87, -87,
+ -87, -1232, -87, 98, 360, -1232, 416, 462, -1232, -1232,
+ 558, 360, 75, 360, 360, -24, -24, 78, 390, 102,
+ -24, -24, 413, 413, 78, 102, 413, 413, 761, 416,
+ 360, 466, -24, -24, 364, 360, -24, -24, 89, 477,
+ 413, -24, 488, -1232, 488, -24, 477, 413, -24, 477,
+ 413, -24, 477, 413, -24, -1232, -1232, 387, 104, -1232,
+ -24, 413, -24, 1439, 462, 113, -1232, -24, 335, 113,
+ -1232, 499, 113, -1232, 335, 461, 810, -1232, 462, -1232,
+ -1232, -1232, -1232, -1232, -1232, -1232, -1232, -87, -87, 98,
+ -1232, 98, -1232, -1232, -87, -87, 98, -87, -1232, -1232,
+ -1232, -87, -87, -87, -1232, -87, 98, -1232, -1232, -1232,
+ -1232, -1232, -1232, 98, 360, -87, -1232, -87, -87, -1232,
+ -87, 98, -87, -87, 360, -87, -87, -1232, -87, -87,
+ 761, 360, -1232, -87, -87, -87, -1232, -87, -87, 98,
+ -1232, -1232, -87, -87, -87, 98, 360, -87, -87, -87,
+ -87, -1232, 360, 360, -87, -87, 360, -87, -87, 360,
+ -87, -87, -1232, -1232, 159, -1232, 360, -87, -1232, 360,
+ -87, -87, -87, 287, 360, -1232, 360, -87, -1232, -87,
+ 98, -87, -1232, -87, 98, 360, -1232, 481, 486, -24,
+ -24, -1232, -1232, 488, -1232, 823, 479, 488, 360, 212,
+ 102, 517, 360, 462, 1699, -1232, 477, 112, 112, 477,
+ -24, 477, 102, -1232, 477, 477, 329, 360, 306, -1232,
+ -1232, -1232, 477, 112, 112, -1232, -1232, -24, 360, 212,
+ 477, 940, -1232, 477, 243, -1232, -1232, -1232, -1232, 477,
+ 108, -1232, 477, 192, -1232, 477, 25, -1232, -1232, 462,
+ -1232, -1232, 462, -1232, -1232, -1232, 477, 138, 1409, 360,
+ 462, -1232, -1232, 499, 1212, 360, -24, 498, 1047, 360,
+ -24, -1232, -87, -1232, -1232, 360, -1232, 360, -1232, -87,
+ -1232, 360, -87, -1232, -87, -1232, -87, 360, -1232, -1232,
+ -1232, 98, -1232, 287, 360, -1232, -1232, -1232, -1232, -1232,
+ -1232, -1232, -1232, -1232, -87, -1232, -1232, -1232, -1232, -87,
+ -87, -87, -1232, -87, -87, -87, -87, 360, -1232, -87,
+ 360, 360, 360, 360, -1232, -1232, -87, -87, 98, -1232,
+ -1232, -1232, -87, 98, 360, -87, -87, -87, -87, -1232,
+ -87, -1232, -87, 360, -87, 360, -87, -87, 360, -87,
+ 360, -87, 360, -87, 205, 427, -1232, 497, 360, -1232,
+ -1232, -1232, -1232, -87, -1232, -1232, -1232, -1232, -1232, -1232,
+ -1232, -1232, -1232, -1232, -1232, -87, 98, -87, 98, -1232,
+ -87, 98, -87, 98, -87, 98, -87, 98, -87, -1232,
+ 98, -87, -1232, -1232, -87, -1232, -1232, -1232, 98, -87,
+ -87, 98, -87, 98, -1232, -1232, -87, -1232, 98, -1232,
+ -1232, -87, 486, -1232, -1232, -1232, -1232, -1232, -1232, 117,
+ -1232, -24, 462, -1232, 398, 398, 398, 398, 78, 100,
+ 360, 78, 360, -1232, 499, -1232, -1232, -1232, -1232, -1232,
+ -1232, -24, -1232, -24, -1232, 78, 58, 360, 78, 360,
+ 416, 518, -1232, 398, -1232, 89, 360, -1232, 360, -1232,
+ 360, -1232, 360, -1232, 462, -1232, -1232, 462, 462, -1232,
+ 430, -1232, -1232, -1232, -1232, 466, 176, 566, 530, -1232,
+ -24, 547, -1232, -24, 425, -1232, 823, 281, -1232, 823,
+ 333, -1232, 387, -1232, 469, -1232, 1134, 360, -24, -1232,
+ -1232, -24, -1232, 823, 488, 360, 267, 47, -1232, -1232,
+ -1232, -87, -1232, -87, -1232, -1232, -1232, -1232, -87, -87,
+ -87, -87, -87, -87, -87, -1232, -87, -1232, -87, -1232,
+ -87, -87, -87, -87, -1232, -87, -87, -1232, -87, -1232,
+ -1232, -87, -87, -87, -87, -1232, -1232, -1232, -1232, -1232,
+ 465, 430, -1232, 497, 462, -1232, -87, -1232, -87, -1232,
+ -87, -1232, -87, -1232, -1232, 360, -87, -87, -87, -1232,
+ 360, -87, -87, -1232, -87, -87, -1232, -87, -1232, -1232,
+ -87, -1232, 360, -1232, -1232, -87, -87, -87, 98, -87,
+ -1232, -87, -87, 360, -1232, -1232, -1232, -1232, -1232, -1232,
+ 360, -87, -87, 360, 360, 360, 360, 360, 360, -1232,
+ -1232, 360, 103, 360, 761, 761, 360, -1232, 306, -1232,
+ -1232, 360, 746, 360, 360, 360, -1232, -1232, 462, -1232,
+ -1232, -1232, 360, -1232, 338, -1232, -1232, 425, -1232, 281,
+ -1232, -1232, -1232, 281, -1232, -1232, 823, -1232, 823, 387,
+ -1232, -1232, -1232, 1054, -1232, 810, -1232, 416, -24, -1232,
+ -87, 168, 499, -1232, -1232, -87, -87, -87, -87, -1232,
+ -1232, -87, -87, -87, -1232, -1232, -87, -87, -1232, -87,
+ -1232, -1232, -1232, -1232, -1232, -87, -1232, 98, -87, -1232,
+ -87, -1232, -1232, -1232, 681, -1232, 360, -87, -87, -87,
+ -1232, -87, -87, -87, -87, -1232, -87, -1232, -87, -1232,
+ -1232, 360, -87, 360, -87, -1232, -87, 498, 98, -1232,
+ -87, -1232, 623, 623, 623, 623, -1232, -1232, -1232, 360,
+ 360, -1232, -1232, -24, -1232, 623, 811, -1232, -1232, 199,
+ 535, 579, 281, -1232, -1232, -1232, -1232, 823, 372, 360,
+ -1232, -1232, -1232, 297, 360, 98, -24, 1415, 360, -1232,
+ -87, 98, -87, 98, -87, -87, 98, -1232, -1232, -87,
+ -87, 370, 811, -1232, -87, -87, -1232, -87, -1232, -1232,
+ -87, -1232, -87, -1232, -1232, -1232, -1232, -1232, -1232, -1232,
+ -1232, -87, -1232, 98, -1232, 267, -87, -1232, -87, -87,
+ -1232, 1348, -1232, -24, 1001, -1232, -24, -1232, 711, -1232,
+ -24, 761, 1104, -1232, -1232, 535, 579, 579, -1232, 823,
+ 360, -24, 360, 416, -1232, -1232, -1232, -1232, -1232, -1232,
+ -1232, -1232, -1232, -1232, -1232, -1232, -1232, 98, -1232, 98,
+ -87, -1232, -87, -1232, -87, -87, -87, -1232, -87, -87,
+ -87, -1232, -1232, -87, -87, 98, -87, -1232, -1232, -1232,
+ -1232, 360, -1232, -87, -87, -87, -24, -24, 1047, 2503,
+ -1232, -1232, 2115, -1232, 2716, 360, 1527, -1232, -1232, -24,
+ 579, -1232, 761, 360, 1340, 360, 360, -87, -87, -1232,
-1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232,
-1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232,
-1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232,
- -1232, -1232, -1232, -1232, -75, -75, -75, -75, -75, 284,
- -1232, -75, -75, -75, -75, -75, 284, -1232, -75, -1232,
- -75, -1232, -75, -1232, -75, -1232, -1232, -75, 231, -1232,
- -1232, 713, 284, 55, 284, 563, 563, 723, 723, -1232,
- 741, 457, 563, 593, 593, -1232, 530, -1232, 284, -1232,
- -1232, 282, -75, -1232, -1232, -75, -75, -1232, -75, 231,
- -1232, -1232, -75, -75, -1232, -75, 231, -75, -1232, -1232,
- -75, -75, -1232, -75, 231, -75, -1232, -75, -75, -1232,
- -75, -75, -1232, -75, -75, -1232, -75, -1232, -75, -75,
- -1232, -75, -1232, -75, -1232, 284, 284, -1232, -1232, 92,
- -1232, 728, -1232, -1232, 741, -1232, 1192, 763, -1232, -1232,
- -1232, 741, -1232, 1192, 763, -1232, -1232, -1232, 763, -1232,
- -1232, 530, -1232, -1232, -1232, 530, -1232, -1232, -1232, -1232,
- -75, -1232, -75, 284, -75, -75, -75, -75, -75, -75,
- 284, -75, -75, -75, -75, -1232, -1232, -1232, -1232, 763,
- -1232, 577, -1232, -1232, 763, -1232, -1232, -1232, -1232, -1232,
- -1232, -75, 284, -75, -1232, -1232, -1232
+ -1232, -1232, -1232, -1232, -1232, -1232, -87, -87, -87, -87,
+ -87, 360, -1232, -87, -87, -87, -87, -87, 360, -1232,
+ -87, -1232, -87, -1232, -87, -1232, -87, -1232, -1232, -87,
+ 98, -1232, -1232, 761, 360, 272, 360, 679, 679, 710,
+ 710, -1232, 870, 412, 679, 494, 494, -1232, 336, -1232,
+ 360, -1232, -1232, 267, -87, -1232, -1232, -87, -87, -1232,
+ -87, 98, -1232, -1232, -87, -87, -1232, -87, 98, -87,
+ -1232, -1232, -87, -87, -1232, -87, 98, -87, -1232, -87,
+ -87, -1232, -87, -87, -1232, -87, -87, -1232, -87, -1232,
+ -87, -87, -1232, -87, -1232, -87, -1232, 360, 360, -1232,
+ -1232, 74, -1232, 462, -1232, -1232, 870, -1232, 823, 475,
+ -1232, -1232, -1232, 870, -1232, 823, 475, -1232, -1232, -1232,
+ 475, -1232, -1232, 336, -1232, -1232, -1232, 336, -1232, -1232,
+ -1232, -1232, -87, -1232, -87, 360, -87, -87, -87, -87,
+ -87, -87, 360, -87, -87, -87, -87, -1232, -1232, -1232,
+ -1232, 475, -1232, 438, -1232, -1232, 475, -1232, -1232, -1232,
+ -1232, -1232, -1232, -87, 360, -87, -1232, -1232, -1232
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -1092,190 +1092,190 @@ static const yytype_int16 yypact[] =
means the default is an error. */
static const yytype_uint16 yydefact[] =
{
- 0, 419, 406, 395, 405, 161, 431, 454, 397, 482,
- 485, 600, 644, 679, 682, 507, 500, 356, 559, 492,
- 489, 497, 495, 611, 666, 396, 421, 432, 398, 420,
- 483, 487, 486, 508, 493, 490, 498, 0, 4, 5,
- 2, 0, 13, 346, 347, 0, 583, 385, 383, 384,
- 386, 387, 0, 0, 3, 0, 12, 416, 0, 585,
- 0, 11, 0, 587, 467, 468, 0, 14, 0, 589,
- 0, 15, 0, 591, 0, 16, 0, 593, 0, 17,
- 0, 584, 540, 538, 539, 541, 542, 586, 0, 588,
- 590, 592, 594, 19, 18, 0, 7, 0, 8, 0,
+ 0, 419, 406, 395, 405, 161, 431, 454, 397, 483,
+ 486, 601, 645, 680, 683, 508, 501, 356, 560, 493,
+ 490, 498, 496, 612, 667, 396, 421, 432, 398, 420,
+ 484, 488, 487, 509, 494, 491, 499, 0, 4, 5,
+ 2, 0, 13, 346, 347, 0, 584, 385, 383, 384,
+ 386, 387, 0, 0, 3, 0, 12, 416, 0, 586,
+ 0, 11, 0, 588, 468, 469, 0, 14, 0, 590,
+ 0, 15, 0, 592, 0, 16, 0, 594, 0, 17,
+ 0, 585, 541, 539, 540, 542, 543, 587, 0, 589,
+ 591, 593, 595, 19, 18, 0, 7, 0, 8, 0,
9, 0, 10, 0, 6, 0, 1, 73, 74, 0,
0, 0, 0, 0, 77, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 78, 162, 0, 357, 0, 394,
0, 0, 407, 0, 411, 412, 417, 0, 422, 0,
0, 455, 0, 0, 423, 0, 423, 0, 423, 0,
- 502, 560, 0, 601, 0, 612, 626, 613, 627, 614,
- 615, 629, 616, 617, 618, 619, 620, 621, 622, 623,
- 624, 625, 0, 609, 0, 645, 0, 0, 0, 650,
+ 503, 561, 0, 602, 0, 613, 627, 614, 628, 615,
+ 616, 630, 617, 618, 619, 620, 621, 622, 623, 624,
+ 625, 626, 0, 610, 0, 646, 0, 0, 0, 651,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 75, 76, 608, 0, 0, 633, 635,
- 0, 657, 659, 0, 667, 669, 0, 0, 40, 20,
+ 0, 0, 0, 75, 76, 609, 0, 0, 634, 636,
+ 0, 658, 660, 0, 668, 670, 0, 0, 40, 20,
37, 38, 39, 41, 42, 0, 163, 21, 22, 26,
0, 25, 35, 0, 164, 154, 361, 0, 0, 446,
447, 369, 400, 0, 0, 0, 0, 399, 0, 0,
- 0, 0, 544, 547, 545, 548, 0, 0, 0, 0,
+ 0, 0, 545, 548, 546, 549, 0, 0, 0, 0,
408, 0, 413, 0, 423, 0, 433, 434, 435, 436,
- 0, 0, 458, 457, 451, 0, 572, 472, 0, 0,
- 0, 471, 0, 568, 569, 0, 428, 190, 424, 0,
- 484, 575, 0, 0, 0, 491, 578, 0, 0, 0,
- 496, 581, 0, 0, 0, 514, 510, 190, 190, 0,
- 190, 0, 501, 562, 0, 0, 595, 0, 596, 603,
- 604, 610, 0, 647, 0, 0, 0, 0, 0, 0,
- 0, 652, 0, 0, 0, 34, 27, 0, 33, 23,
+ 0, 0, 458, 457, 451, 0, 573, 473, 0, 0,
+ 0, 472, 0, 569, 570, 0, 428, 190, 424, 0,
+ 485, 576, 0, 0, 0, 492, 579, 0, 0, 0,
+ 497, 582, 0, 0, 0, 515, 511, 190, 190, 0,
+ 190, 0, 502, 563, 0, 0, 596, 0, 597, 604,
+ 605, 611, 0, 648, 0, 0, 0, 0, 0, 0,
+ 0, 653, 0, 0, 0, 34, 27, 0, 33, 23,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 27,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 425, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 506, 505, 0, 0, 503,
- 0, 0, 0, 0, 0, 0, 634, 0, 0, 0,
- 658, 0, 0, 668, 0, 0, 0, 649, 0, 29,
+ 0, 0, 0, 0, 0, 507, 506, 0, 0, 504,
+ 0, 0, 0, 0, 0, 0, 635, 0, 0, 0,
+ 659, 0, 0, 669, 0, 0, 0, 650, 0, 29,
31, 28, 36, 168, 171, 165, 166, 155, 158, 0,
160, 0, 153, 365, 0, 351, 0, 0, 348, 353,
362, 359, 0, 0, 371, 375, 0, 223, 393, 204,
- 205, 206, 207, 0, 0, 0, 448, 0, 0, 521,
+ 205, 206, 207, 0, 0, 0, 448, 0, 0, 522,
0, 0, 0, 0, 0, 0, 0, 409, 402, 190,
- 0, 0, 418, 0, 0, 0, 463, 190, 451, 0,
+ 0, 0, 418, 0, 0, 0, 464, 190, 451, 0,
450, 459, 190, 0, 0, 0, 0, 0, 0, 190,
190, 429, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 50, 511, 48, 512, 0, 190, 515, 0,
- 0, 0, 597, 605, 0, 648, 0, 0, 524, 661,
- 0, 0, 693, 80, 0, 0, 32, 0, 0, 0,
+ 0, 0, 50, 512, 48, 513, 0, 190, 516, 0,
+ 0, 0, 598, 606, 0, 649, 0, 0, 525, 662,
+ 0, 0, 694, 80, 0, 0, 32, 0, 0, 0,
0, 350, 355, 0, 354, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 388, 0, 0, 0, 0,
0, 0, 0, 390, 0, 0, 0, 0, 0, 415,
24, 410, 0, 0, 0, 452, 453, 0, 0, 0,
- 0, 0, 469, 0, 0, 191, 426, 427, 488, 0,
- 0, 494, 0, 0, 499, 0, 0, 44, 58, 0,
- 45, 49, 0, 509, 504, 513, 0, 0, 0, 0,
- 606, 602, 646, 0, 0, 0, 0, 0, 0, 0,
- 0, 651, 156, 159, 169, 0, 172, 0, 367, 351,
+ 0, 0, 470, 0, 0, 191, 426, 427, 489, 0,
+ 0, 495, 0, 0, 500, 0, 0, 44, 58, 0,
+ 45, 49, 0, 510, 505, 514, 0, 0, 0, 0,
+ 607, 603, 647, 0, 0, 0, 0, 0, 0, 0,
+ 0, 652, 156, 159, 169, 0, 172, 0, 367, 351,
366, 0, 351, 363, 359, 358, 0, 0, 380, 381,
376, 0, 368, 372, 0, 224, 225, 226, 227, 228,
229, 230, 231, 232, 0, 233, 234, 235, 236, 0,
- 0, 0, 392, 0, 552, 0, 552, 0, 522, 0,
+ 0, 0, 392, 0, 553, 0, 553, 0, 523, 0,
0, 0, 0, 0, 199, 198, 190, 190, 0, 401,
- 197, 196, 190, 0, 0, 0, 438, 0, 438, 464,
+ 197, 196, 190, 0, 0, 0, 438, 0, 438, 465,
0, 456, 0, 0, 0, 0, 0, 190, 0, 190,
- 0, 190, 0, 190, 48, 0, 59, 0, 0, 563,
- 564, 565, 566, 0, 174, 100, 133, 136, 144, 148,
- 98, 599, 82, 88, 89, 93, 0, 85, 0, 92,
+ 0, 190, 0, 190, 48, 0, 59, 0, 0, 564,
+ 565, 566, 567, 0, 174, 100, 133, 136, 144, 148,
+ 98, 600, 82, 88, 89, 93, 0, 85, 0, 92,
85, 0, 85, 0, 85, 0, 85, 0, 85, 84,
- 0, 597, 582, 607, 637, 536, 656, 665, 0, 661,
- 661, 0, 80, 0, 660, 525, 378, 680, 0, 81,
- 681, 0, 0, 167, 170, 352, 364, 349, 360, 0,
+ 0, 598, 583, 608, 638, 537, 657, 666, 0, 662,
+ 662, 0, 80, 0, 661, 526, 378, 681, 0, 81,
+ 682, 0, 0, 167, 170, 352, 364, 349, 360, 0,
389, 0, 373, 370, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 543, 0, 546, 391, 549, 550, 404,
+ 0, 0, 0, 544, 0, 547, 391, 550, 551, 404,
403, 0, 414, 0, 430, 0, 0, 0, 0, 0,
- 27, 0, 470, 0, 567, 0, 0, 573, 0, 576,
- 0, 579, 0, 46, 0, 43, 68, 0, 0, 53,
- 71, 55, 66, 67, 558, 0, 0, 0, 0, 91,
+ 27, 0, 471, 0, 568, 0, 0, 574, 0, 577,
+ 0, 580, 0, 46, 0, 43, 68, 0, 0, 53,
+ 71, 55, 66, 67, 559, 0, 0, 0, 0, 91,
0, 0, 117, 0, 0, 118, 0, 0, 119, 0,
- 0, 120, 0, 83, 0, 598, 0, 0, 0, 662,
- 663, 0, 664, 0, 0, 0, 0, 0, 683, 685,
+ 0, 120, 0, 83, 0, 599, 0, 0, 0, 663,
+ 664, 0, 665, 0, 0, 0, 0, 0, 684, 686,
157, 0, 382, 378, 374, 237, 238, 239, 190, 190,
- 190, 190, 552, 190, 190, 551, 552, 556, 517, 202,
+ 190, 190, 553, 190, 190, 552, 553, 557, 518, 202,
0, 0, 438, 190, 449, 190, 190, 437, 438, 444,
- 465, 461, 0, 190, 190, 570, 574, 577, 580, 52,
+ 466, 461, 0, 190, 190, 571, 575, 578, 581, 52,
48, 71, 60, 0, 0, 70, 190, 96, 85, 94,
0, 90, 85, 87, 101, 0, 85, 85, 85, 134,
0, 85, 85, 137, 0, 85, 145, 0, 149, 150,
- 0, 79, 0, 654, 643, 637, 637, 80, 0, 80,
- 636, 0, 0, 0, 379, 523, 673, 674, 671, 672,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 554,
- 553, 0, 0, 0, 0, 0, 0, 442, 0, 439,
+ 0, 79, 0, 655, 644, 638, 638, 80, 0, 80,
+ 637, 0, 0, 0, 379, 524, 674, 675, 672, 673,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 555,
+ 554, 0, 0, 0, 0, 0, 0, 442, 0, 439,
441, 0, 0, 0, 0, 0, 47, 69, 0, 54,
57, 72, 0, 95, 0, 86, 99, 0, 121, 0,
122, 123, 132, 0, 124, 125, 0, 126, 0, 0,
- 173, 638, 639, 0, 640, 0, 642, 27, 0, 655,
- 0, 0, 0, 684, 377, 0, 0, 0, 0, 555,
- 557, 190, 517, 517, 516, 203, 190, 190, 443, 190,
- 445, 188, 186, 185, 187, 466, 0, 190, 460, 0,
- 571, 64, 56, 0, 561, 0, 102, 103, 104, 105,
- 85, 85, 85, 85, 138, 0, 146, 142, 151, 152,
- 0, 80, 0, 0, 537, 378, 0, 0, 688, 689,
- 687, 0, 0, 0, 0, 520, 518, 519, 0, 0,
- 440, 0, 462, 0, 0, 63, 97, 0, 0, 0,
- 0, 127, 128, 129, 130, 0, 0, 0, 147, 641,
- 653, 0, 0, 0, 0, 0, 0, 243, 214, 0,
- 209, 0, 80, 220, 0, 192, 189, 0, 474, 65,
- 0, 61, 106, 107, 108, 109, 110, 111, 85, 139,
- 0, 143, 141, 534, 529, 530, 531, 532, 533, 378,
- 527, 0, 535, 0, 0, 692, 689, 689, 686, 0,
- 213, 0, 0, 208, 0, 218, 0, 219, 0, 0,
- 0, 473, 62, 0, 0, 0, 131, 0, 0, 0,
- 0, 27, 691, 690, 183, 180, 179, 182, 200, 181,
- 201, 217, 345, 175, 177, 0, 176, 0, 215, 244,
- 0, 212, 209, 80, 0, 222, 220, 0, 190, 480,
- 478, 80, 80, 0, 112, 113, 114, 115, 140, 0,
- 526, 194, 675, 190, 0, 0, 0, 0, 211, 210,
- 0, 221, 0, 0, 0, 475, 477, 0, 0, 135,
- 0, 0, 0, 0, 0, 0, 194, 216, 303, 304,
- 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
- 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
- 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
- 335, 336, 337, 338, 297, 246, 248, 250, 252, 0,
- 245, 270, 277, 279, 281, 283, 0, 276, 293, 184,
- 80, 481, 378, 116, 190, 528, 678, 80, 0, 670,
- 694, 0, 0, 0, 0, 0, 0, 0, 0, 240,
- 0, 0, 0, 0, 0, 242, 0, 476, 0, 195,
- 677, 0, 190, 193, 344, 190, 190, 298, 190, 0,
- 241, 340, 190, 190, 247, 190, 0, 190, 249, 342,
- 190, 190, 251, 190, 0, 190, 253, 190, 190, 271,
- 190, 190, 278, 190, 190, 280, 190, 282, 190, 190,
- 284, 190, 294, 190, 479, 0, 0, 299, 302, 0,
- 300, 0, 254, 261, 0, 258, 0, 0, 260, 262,
- 269, 0, 266, 0, 0, 268, 272, 275, 0, 273,
- 285, 0, 287, 288, 289, 0, 291, 292, 295, 296,
- 675, 178, 190, 0, 190, 190, 0, 190, 190, 190,
- 0, 190, 190, 190, 190, 676, 301, 343, 257, 0,
- 255, 0, 259, 265, 0, 263, 341, 267, 274, 286,
- 290, 190, 0, 190, 256, 339, 264
+ 173, 639, 640, 0, 641, 0, 643, 27, 0, 656,
+ 0, 0, 0, 685, 377, 0, 0, 0, 0, 556,
+ 558, 190, 518, 518, 517, 203, 190, 190, 443, 190,
+ 445, 188, 186, 185, 187, 190, 467, 0, 190, 460,
+ 0, 572, 64, 56, 0, 562, 0, 102, 103, 104,
+ 105, 85, 85, 85, 85, 138, 0, 146, 142, 151,
+ 152, 0, 80, 0, 0, 538, 378, 0, 0, 689,
+ 690, 688, 0, 0, 0, 0, 521, 519, 520, 0,
+ 0, 440, 462, 0, 463, 0, 0, 63, 97, 0,
+ 0, 0, 0, 127, 128, 129, 130, 0, 0, 0,
+ 147, 642, 654, 0, 0, 0, 0, 0, 0, 243,
+ 214, 0, 209, 0, 80, 220, 0, 192, 189, 0,
+ 475, 65, 0, 61, 106, 107, 108, 109, 110, 111,
+ 85, 139, 0, 143, 141, 535, 530, 531, 532, 533,
+ 534, 378, 528, 0, 536, 0, 0, 693, 690, 690,
+ 687, 0, 213, 0, 0, 208, 0, 218, 0, 219,
+ 0, 0, 0, 474, 62, 0, 0, 0, 131, 0,
+ 0, 0, 0, 27, 692, 691, 183, 180, 179, 182,
+ 200, 181, 201, 217, 345, 175, 177, 0, 176, 0,
+ 215, 244, 0, 212, 209, 80, 0, 222, 220, 0,
+ 190, 481, 479, 80, 80, 0, 112, 113, 114, 115,
+ 140, 0, 527, 194, 676, 190, 0, 0, 0, 0,
+ 211, 210, 0, 221, 0, 0, 0, 476, 478, 0,
+ 0, 135, 0, 0, 0, 0, 0, 0, 194, 216,
+ 303, 304, 305, 306, 307, 308, 309, 310, 311, 312,
+ 313, 314, 315, 316, 317, 318, 319, 320, 321, 322,
+ 323, 324, 325, 326, 327, 328, 329, 330, 331, 332,
+ 333, 334, 335, 336, 337, 338, 297, 246, 248, 250,
+ 252, 0, 245, 270, 277, 279, 281, 283, 0, 276,
+ 293, 184, 80, 482, 378, 116, 190, 529, 679, 80,
+ 0, 671, 695, 0, 0, 0, 0, 0, 0, 0,
+ 0, 240, 0, 0, 0, 0, 0, 242, 0, 477,
+ 0, 195, 678, 0, 190, 193, 344, 190, 190, 298,
+ 190, 0, 241, 340, 190, 190, 247, 190, 0, 190,
+ 249, 342, 190, 190, 251, 190, 0, 190, 253, 190,
+ 190, 271, 190, 190, 278, 190, 190, 280, 190, 282,
+ 190, 190, 284, 190, 294, 190, 480, 0, 0, 299,
+ 302, 0, 300, 0, 254, 261, 0, 258, 0, 0,
+ 260, 262, 269, 0, 266, 0, 0, 268, 272, 275,
+ 0, 273, 285, 0, 287, 288, 289, 0, 291, 292,
+ 295, 296, 676, 178, 190, 0, 190, 190, 0, 190,
+ 190, 190, 0, 190, 190, 190, 190, 677, 301, 343,
+ 257, 0, 255, 0, 259, 265, 0, 263, 341, 267,
+ 274, 286, 290, 190, 0, 190, 256, 339, 264
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int16 yypgoto[] =
{
- -1232, -1232, -1232, -222, -226, -189, -1232, 247, -195, 289,
- -1232, -1232, -1232, -1232, -1232, -1232, -196, -342, -662, -56,
- -783, -637, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -569,
- -252, -1232, -1232, -1232, -849, -1232, -1232, -247, 1222, 1220,
- -57, 1263, -1232, -708, -589, -607, -1232, -1232, -169, -1232,
- -1232, -168, -1232, -1232, -1232, -167, -321, -1232, -1232, -791,
- -1232, -1232, -1232, -1232, -1232, -788, -1232, -1232, -1232, -1232,
- -655, -1232, -1232, -1232, 108, -1232, -1232, -1232, -1232, -1232,
- 130, -1232, -1232, -503, -1232, -1232, -489, -1232, -1232, -1222,
- -1232, -1232, -1232, -1232, -552, 1709, -427, -1231, -565, -1232,
- -1232, -1232, -746, -909, -36, -1232, -516, -1232, -1232, -1232,
- -1232, -518, -334, 99, -1232, -1232, -315, -1007, -385, -466,
- -1008, -980, -1232, -942, -614, -1232, -1232, -1232, -1232, -600,
- -1232, -1232, -1232, -1232, -606, -611, -1232, -583, -1232, -776,
- -1232, -761, -1232, 711, -412, -190, 514, -417, 29, -245,
- -310, 107, -1232, -1232, -1232, 193, -1232, -110, -1232, -77,
- -1232, -1232, -1232, -1232, -1232, -1232, -835, -1232, -1232, -1232,
- -1232, 635, 637, 638, 640, -283, 531, -1232, -1232, -91,
- 41, -1232, -1232, -1232, -1232, -1232, -107, -1232, -1232, -1232,
- -1232, 10, -1232, 502, -104, -1232, -1232, -1232, 642, -1232,
- -1232, -1232, -620, -1232, -1232, -1232, 580, 584, 510, -174,
- 2, 312, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -367,
- -798, -966, -1232, -1232, 662, 671, -1232, 232, -1232, -411,
- -1232, -1232, -1232, -182, -1232, 675, -1232, -178, -1232, 677,
- -1232, -186, -1232, 679, -1232, -187, -1232, -1232, 414, -1232,
- -1232, -1232, -1232, -1232, 969, -289, -1232, -1232, -379, -1232,
- -1232, -785, -1232, -1232, -1232, -775, -1232, -1232, 687, -1232,
- -1232, 625, -1232, 628, -1232, -1232, 230, -618, 234, 241,
- 242, 699, -1232, -1232, -1232, -1232, -1232, 717, -1232, -1232,
- -1232, -1232, 718, -1232, -1232, 719, -1232, -1232, 727, -1232,
- -1232, 738, -188, -344, 109, -1232, -1232, -1232, -1232, -1232,
- -1232, -1232, -1232, -1232, -1232, 842, -1232, 539, -179, -1232,
- -119, -209, -1232, -1232, -86, -1232, 115, -1232, -1232, -1232,
- -808, -1232, -1232, -1232, 549, 16, 887, -1232, -1232, 551,
- -1083, -502, -1232, -988, 892, -1232, -1232, -1232, -49, -1232,
- -375, -1232, -200
+ -1232, -1232, -1232, -221, -226, -189, -1232, 266, -194, 293,
+ -1232, -1232, -1232, -1232, -1232, -1232, -196, -341, -654, -53,
+ -782, -642, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -563,
+ -250, -1232, -1232, -1232, -847, -1232, -1232, -237, 1251, 1249,
+ -57, 1948, -1232, -665, -567, -574, -1232, -1232, -157, -1232,
+ -1232, -156, -1232, -1232, -1232, -154, -306, -1232, -1232, -791,
+ -1232, -1232, -1232, -1232, -1232, -783, -1232, -1232, -1232, -1232,
+ -657, -1232, -1232, -1232, 110, -1232, -1232, -1232, -1232, -1232,
+ 143, -1232, -1232, -505, -1232, -1232, -473, -1232, -1232, -1231,
+ -1232, -1232, -1232, -1232, -557, 1794, -410, -1201, -544, -1232,
+ -1232, -1232, -748, -930, -37, -1232, -497, -1232, -1232, -1232,
+ -1232, -500, -334, 124, -1232, -1232, -290, -1018, -364, -446,
+ -1004, -578, -1232, -852, -597, -1232, -1232, -1232, -1232, -602,
+ -1232, -1232, -1232, -1232, -729, -588, -1232, -701, -1232, -556,
+ -1232, -724, -1232, 716, -416, -148, 519, -419, 36, -102,
+ -326, 101, -1232, -1232, -1232, 188, -1232, -117, -1232, -67,
+ -1232, -1232, -1232, -1232, -1232, -1232, -836, -1232, -1232, -1232,
+ -1232, 600, 604, 605, 607, -280, 663, -1232, -1232, -91,
+ 42, -1232, -1232, -1232, -1232, -1232, -107, -1232, -1232, -1232,
+ -1232, 10, -1232, 506, -105, -1232, -1232, -1232, 609, -1232,
+ -1232, -1232, -644, -1232, -1232, -1232, 546, 552, 527, -204,
+ 4, 277, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -367,
+ -794, -938, -1232, -1232, 627, 633, -1232, 197, -1232, -448,
+ -1232, -1232, -1232, -192, -1232, 640, -1232, -185, -1232, 641,
+ -1232, -186, -1232, 644, -1232, -187, -1232, -1232, 378, -1232,
+ -1232, -1232, -1232, -1232, 540, -406, -1232, -1232, -384, -1232,
+ -1232, -781, -1232, -1232, -1232, -796, -1232, -1232, 648, -1232,
+ -1232, 588, -1232, 590, -1232, -1232, 190, -624, 193, 194,
+ 195, 660, -1232, -1232, -1232, -1232, -1232, 671, -1232, -1232,
+ -1232, -1232, 672, -1232, -1232, 673, -1232, -1232, 674, -1232,
+ -1232, 675, -179, -349, 76, -1232, -1232, -1232, -1232, -1232,
+ -1232, -1232, -1232, -1232, -1232, 806, -1232, 478, -253, -1232,
+ -119, -209, -1232, -1232, -109, -1232, 81, -1232, -1232, -1232,
+ -814, -1232, -1232, -1232, 489, -64, 816, -1232, -1232, 484,
+ -1087, -552, -1232, -1001, 842, -1232, -1232, -1232, -96, -1232,
+ -458, -1232, -249
};
/* YYDEFGOTO[NTERM-NUM]. */
@@ -1284,18 +1284,18 @@ static const yytype_int16 yydefgoto[] =
-1, 37, 38, 39, 235, 620, 237, 880, 238, 470,
239, 240, 419, 420, 241, 348, 242, 243, 894, 589,
503, 590, 504, 695, 890, 591, 809, 969, 592, 810,
- 893, 1032, 1033, 1110, 811, 812, 813, 895, 109, 215,
+ 893, 1033, 1034, 1112, 811, 812, 813, 895, 109, 215,
382, 456, 922, 609, 749, 819, 712, 713, 714, 715,
- 716, 717, 718, 905, 1035, 719, 720, 721, 910, 722,
- 723, 914, 1045, 1120, 1199, 724, 1087, 725, 917, 1047,
- 726, 727, 920, 1050, 489, 351, 41, 136, 245, 427,
- 428, 429, 615, 430, 431, 617, 729, 730, 1172, 1173,
- 1174, 1175, 1025, 1026, 874, 383, 667, 1176, 1221, 673,
- 668, 1177, 870, 1016, 448, 449, 1143, 450, 1140, 451,
- 452, 1147, 453, 649, 650, 651, 858, 1100, 1098, 1103,
- 1101, 1180, 1269, 1324, 1332, 1270, 1339, 1276, 1342, 1347,
- 1277, 1352, 1294, 1317, 1264, 1325, 1326, 1333, 1334, 1327,
- 1319, 1178, 42, 252, 353, 534, 44, 354, 253, 138,
+ 716, 717, 718, 905, 1036, 719, 720, 721, 910, 722,
+ 723, 914, 1046, 1122, 1201, 724, 1089, 725, 917, 1048,
+ 726, 727, 920, 1051, 489, 351, 41, 136, 245, 427,
+ 428, 429, 615, 430, 431, 617, 729, 730, 1174, 1175,
+ 1176, 1177, 1026, 1027, 874, 383, 667, 1178, 1223, 673,
+ 668, 1179, 870, 1016, 448, 449, 1145, 450, 1142, 451,
+ 452, 1149, 453, 649, 650, 651, 858, 1102, 1100, 1105,
+ 1103, 1182, 1271, 1326, 1334, 1272, 1341, 1278, 1344, 1349,
+ 1279, 1354, 1296, 1319, 1266, 1327, 1328, 1335, 1336, 1329,
+ 1321, 1180, 42, 252, 353, 534, 44, 354, 253, 138,
247, 538, 248, 441, 624, 435, 436, 621, 619, 254,
255, 445, 446, 634, 542, 630, 845, 631, 853, 46,
47, 48, 49, 50, 51, 454, 140, 52, 53, 256,
@@ -1303,11 +1303,11 @@ static const yytype_int16 yydefgoto[] =
56, 257, 58, 149, 203, 298, 299, 492, 59, 60,
275, 276, 787, 277, 278, 279, 258, 259, 457, 876,
936, 375, 62, 152, 284, 285, 482, 478, 963, 738,
- 680, 881, 1027, 63, 64, 65, 290, 486, 1151, 1192,
- 1193, 1282, 66, 67, 68, 69, 70, 71, 72, 73,
+ 680, 881, 1028, 63, 64, 65, 290, 486, 1153, 1194,
+ 1195, 1284, 66, 67, 68, 69, 70, 71, 72, 73,
74, 75, 76, 77, 78, 79, 210, 80, 318, 319,
506, 320, 321, 509, 937, 953, 461, 659, 941, 520,
- 746, 739, 1129, 1130, 1131, 740, 741, 1055, 81, 82,
+ 746, 739, 1131, 1132, 1133, 740, 741, 1056, 81, 82,
83, 260, 84, 261, 85, 86, 262, 770, 263, 264,
265, 87, 88, 162, 324, 325, 703, 89, 292, 293,
294, 295, 90, 303, 304, 91, 308, 309, 92, 313,
@@ -1315,8 +1315,8 @@ static const yytype_int16 yydefgoto[] =
96, 182, 97, 183, 184, 938, 218, 219, 837, 99,
186, 334, 335, 516, 336, 191, 342, 343, 927, 928,
742, 743, 100, 221, 222, 605, 939, 102, 224, 225,
- 940, 1223, 103, 748, 328, 105, 523, 848, 849, 1059,
- 1096, 524, 1060
+ 940, 1225, 103, 748, 328, 105, 523, 848, 849, 1060,
+ 1098, 524, 1061
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -1324,638 +1324,654 @@ static const yytype_int16 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int16 yytable[] =
{
- 115, 270, 61, 236, 421, 344, 672, 479, 146, 711,
- 57, 337, 187, 188, 339, 737, 347, 532, 943, 291,
- 307, 312, 531, 697, 326, 613, 302, 421, 929, 45,
- 906, 1053, 519, 907, 842, 808, 911, 871, 772, 345,
- 931, 54, 434, 932, 970, 485, 1017, 190, 349, 918,
- 1160, 925, 205, 1099, 207, 1099, 1104, 803, 789, 512,
- 1, 926, 1316, 1, 19, 21, 1108, 518, 1093, 1168,
- 1, 15, 5, 1323, 1323, 1331, 1331, 1314, 1338, 192,
- 1323, 193, 464, 194, 195, 249, 196, 144, 114, 34,
- 36, 5, 198, 199, 250, 200, 201, 202, 204, 202,
- 206, 202, 208, 209, 267, 211, 1168, 212, 40, 5,
- 33, 442, 251, 822, 106, 825, 17, 828, 266, 831,
- 333, 833, 251, 10, 289, 316, 17, 216, 1392, 217,
- 220, 223, 483, 226, 338, 1182, 26, 340, 1104, 26,
- 29, 189, 1394, 29, 1170, 1397, 26, 144, 670, 1398,
- 29, 422, 1401, 671, 15, 664, 1402, 189, 5, 665,
- 282, 425, 5, 145, 1184, 5, 908, 1012, 1187, 912,
- 370, 704, 915, 467, 31, 32, 476, 1013, 311, 333,
- 134, 1170, 283, 1037, 1075, 1051, 1038, 1421, 350, 1040,
- 352, -628, 1423, 33, 525, 1203, 484, 357, 249, 359,
- 710, 502, 144, 362, 363, 735, 1048, 250, 513, 364,
- 365, 366, 367, 5, 368, 326, 369, 202, 371, 994,
- 1092, 996, 526, 145, 734, 1111, 1058, 374, 1355, 626,
- 288, 968, 378, 379, 1288, 380, 485, 246, 891, 274,
- 1188, 384, 706, 707, 948, 386, 387, 924, 951, 850,
- 389, 390, 956, 966, 731, 392, 393, 627, 961, 682,
- -630, 1152, 2, 398, 144, 708, 709, 401, 476, 661,
- 403, 587, 4, 588, 447, 560, 5, 405, 145, 408,
- 409, 411, 412, 414, 5, 415, 1112, 600, 2, 1113,
- 1115, 973, 2, 704, 1158, 975, 1134, 735, 4, 978,
- 980, 981, 4, 5, 984, 985, 7, 5, 987, 19,
- 297, 1284, 10, 296, -51, 301, 588, 317, 246, 1039,
- 1136, 12, 1041, 338, 1042, 1107, 340, 899, 1043, 903,
- 459, -631, 903, 251, 34, 903, 315, 316, 903, 5,
- 145, 903, 5, 1089, 246, 433, 707, 633, 704, -632,
- 493, 704, 670, 496, 1328, 807, 499, 671, 476, 24,
- 1345, 323, 5, 31, 32, 1194, 5, 443, 708, 709,
- 527, 528, 341, 473, 463, 708, 709, 352, 533, 709,
- 536, 1183, 1312, 664, 537, 539, 540, 665, 541, 1191,
- 107, 108, 687, 694, 1145, 868, 696, 691, 546, 693,
- 547, 548, 689, 549, 733, 551, 552, 762, 554, 555,
- 326, 556, 558, 1201, 1287, 346, 562, 563, 564, 423,
- 424, 374, 1114, 1116, 1117, 1118, 569, 570, -30, 755,
- 573, 574, 757, 1081, 1082, 1083, 1084, 579, 580, 531,
- 582, 583, 229, 585, 586, 213, 214, 1308, 421, 851,
- 859, 860, 861, 596, 597, 598, 654, 656, 1225, 1226,
- 603, 444, 604, 1021, 607, 532, 608, 1022, 1023, 1024,
- 653, 655, 676, 678, 5, 1209, 7, 1321, 883, 1314,
- 21, 882, 477, 1215, 1216, 306, 675, 677, 903, 459,
- 903, 751, 490, 447, 903, 5, 5, 686, 1195, 1196,
- 1197, 696, 329, 330, 704, 36, 1135, 705, 706, 707,
- 652, 1156, 518, 657, 1189, 660, 522, 1318, 662, 663,
- 423, 1335, 1335, 517, 1340, 1344, 674, 1349, 1349, 521,
- 1353, 708, 709, 710, 134, 228, 229, 685, 230, 231,
- 232, 233, 234, 688, 424, 5, 690, 5, 433, 692,
- 1171, 807, 1314, 1181, 704, 752, 587, 1185, 706, 707,
- 698, 1190, 533, 1283, 5, 533, 854, 537, 747, 759,
- 1164, 805, 1307, 704, 1165, 1166, 1167, 705, 707, 1310,
- 5, 708, 709, 1321, 670, 1314, 921, 764, 1395, 671,
- 588, 903, 765, 766, 767, 1399, 768, 769, 771, 769,
- 708, 709, 774, 1097, 1271, 1403, 1278, 709, 889, 1404,
- 5, 696, 892, 884, 1329, 1314, 469, 1227, 785, 786,
- 788, 786, 154, 790, 156, 791, 158, 793, 160, 795,
- 233, 234, 1169, 1286, 1057, 418, 502, 913, 942, 804,
- 916, 618, 971, 141, 967, 623, 815, 897, 150, 900,
- 153, 901, 155, 1036, 157, 421, 159, 612, 816, 1121,
- 818, 1292, 864, 821, 666, 824, 1208, 827, 1211, 830,
- 684, 830, 628, 629, 598, 708, 709, 836, 1102, 875,
- 1186, -59, 604, 604, 1336, 608, -59, -59, -59, 844,
- 1343, 807, 246, 433, 847, 1164, 1097, 696, 892, 1165,
- 1166, 1167, 1168, 1164, 1350, 5, 728, 1165, 1166, 1167,
- 1168, 43, 728, 5, 704, 287, 728, 705, 706, 707,
- 1348, 1348, 704, 1066, 1067, 705, 706, 707, 1057, 622,
- 1164, 758, 807, 933, 1165, 1166, 1167, 855, 856, 857,
- 5, 708, 709, 710, 1329, 1314, 991, 992, 1164, 708,
- 709, 710, 1165, 1166, 1167, 839, 840, 1169, 5, 1015,
- 1015, 1162, 1163, 1314, 165, 1169, 166, 167, 807, 168,
- 1164, 169, 1031, 1052, 1165, 1166, 1167, 1170, 862, 280,
- 5, 866, 1123, 281, 1019, 1170, 1124, 1125, 1126, 1127,
- 566, 170, 1169, 502, 759, 872, 844, 1044, 878, 1046,
- 171, 10, 683, 1280, 172, 769, 173, 1074, 174, 769,
- 1169, 952, 507, 954, 955, 786, 175, 896, 958, 421,
- 268, 786, 251, 269, 962, 791, 17, 699, 176, 134,
- 228, 700, 1169, 230, 231, 232, 286, 696, 701, 702,
- 835, 830, 98, 974, 1128, 830, 177, 178, 179, 977,
- 979, 830, 31, 32, 983, 830, 180, 986, 830, 1422,
- 988, 228, 229, 989, 230, 231, 232, 181, 836, 836,
- 993, 458, 608, 406, 997, 998, 228, 863, 1109, 230,
- 231, 232, 474, 475, 1001, 1002, 410, 101, 1405, 3,
- 413, 488, 104, 1003, 873, 1137, 1119, 6, 495, 0,
- 0, 498, 0, 0, 501, 0, 8, 0, 0, 0,
- 0, 0, 511, 9, 696, 228, 11, 0, 230, 231,
- 232, 233, 234, 805, 898, 806, 902, 0, 0, 902,
- 0, 16, 902, 0, 0, 902, 0, 0, 902, 0,
- 0, 0, 18, 1056, 728, 20, 0, 22, 1061, 1062,
- 1063, 1064, 934, 0, 1015, 952, 952, 0, 25, 0,
- 27, 0, 28, 0, 30, 0, 0, 0, 1198, 0,
- 35, 0, 1073, 0, 0, 0, 0, 0, 0, 1077,
- 1078, 1079, 1097, 1080, 830, 830, 830, 0, 1085, 476,
- 1086, 5, 0, 0, 608, 0, 1091, 5, 844, 0,
- 704, 0, 1095, 705, 706, 707, 704, 0, 0, 705,
- 706, 707, 0, 0, 0, 0, 0, 0, 735, 0,
- 0, 0, 923, 736, 0, 1015, 0, 708, 709, 710,
- 0, 0, 0, 708, 709, 710, 0, 0, 0, 0,
- 0, 1139, 0, 1142, 0, 608, 1146, 0, 0, 0,
- 1149, 1150, 0, 0, 0, 1153, 1154, 0, 1155, 0,
- 1011, 830, 0, 1157, 0, 0, 0, 0, 0, 5,
- 0, 0, 844, 0, 0, 0, 0, 1161, 704, 1095,
- 1095, 705, 706, 707, 0, 902, 0, 902, 0, 0,
- 0, 902, 0, 1164, 0, 736, 1015, 1165, 1166, 1167,
- 1168, 728, 0, 5, 0, 708, 709, 710, 0, 0,
- 0, 0, 704, 0, 0, 705, 706, 707, 0, 0,
- 0, 1206, 1189, 1207, 0, 1142, 608, 1210, 0, 1146,
- 1212, 0, 0, 0, 1214, 608, 0, 1218, 0, 708,
- 709, 710, 0, 0, 1220, 1222, 0, 0, 0, 0,
- 476, 0, 0, 0, 0, 1169, 228, 229, 5, 230,
- 231, 232, 233, 234, 0, 1393, 806, 704, 1291, 1220,
- 705, 706, 707, 0, 0, 1170, 0, 1396, 0, 735,
- 0, 0, 0, 0, 1400, 134, 228, 229, 902, 230,
- 231, 232, 233, 234, 708, 709, 710, 0, 0, 0,
- 0, 0, 0, 728, 0, 0, 0, 1293, 1295, 1296,
- 1297, 1298, 0, 0, 1300, 1301, 1302, 1303, 1304, 476,
- 0, 1306, 0, 608, 0, 844, 0, 5, 228, 0,
- 608, 230, 231, 232, 233, 234, 704, 0, 806, 705,
- 706, 707, 0, 0, 0, 0, 0, 728, 735, 0,
- 728, 0, 0, 736, 728, 0, 0, 0, 728, 0,
- 0, 1359, 0, 708, 709, 710, 0, 110, 1364, 0,
- 1367, 0, 0, 0, 111, 112, 1371, 113, 1374, 0,
- 116, 0, 117, 1378, 118, 0, 1381, 0, 119, 0,
- 120, 1385, 121, 0, 122, 0, 123, 0, 124, 0,
- 125, 0, 126, 0, 0, 0, 0, 0, 0, 0,
- 127, 0, 0, 0, 728, 0, 0, 128, 0, 129,
- 0, 130, 728, 131, 0, 132, 0, 133, 0, 0,
- 728, 460, 462, 1222, 0, 465, 466, 0, 1409, 1411,
- 228, 229, 1414, 230, 231, 232, 233, 234, 0, 487,
- 0, 0, 0, 0, 0, 0, 494, 0, 0, 497,
- 0, 0, 500, 0, 0, 0, 0, 0, 0, 197,
- 510, 0, 135, 137, 139, 139, 142, 0, 0, 148,
- 139, 151, 139, 148, 139, 148, 139, 148, 139, 148,
- 161, 163, 0, 185, 185, 185, 0, 0, 0, 0,
- 0, 1315, 0, 1322, 1322, 1330, 1330, 0, 1337, 1341,
- 1322, 1346, 1346, 227, 1351, 0, 3, 0, 0, 0,
- 0, 0, 0, 300, 6, 305, 0, 310, 0, 5,
- 322, 0, 0, 8, 0, 0, 0, 0, 704, 0,
- 9, 705, 706, 707, 0, 0, 0, 0, 0, 0,
- 0, 0, 14, 0, 0, 244, 0, 0, 16, 0,
- 272, 0, 0, 0, 0, 708, 709, 710, 0, 18,
- 355, 0, 20, 0, 22, 356, 0, 358, 0, 0,
- 360, 361, 0, 0, 0, 25, 5, 27, 0, 28,
- 0, 30, 0, 0, 0, 704, 0, 35, 705, 706,
- 707, 0, 372, 373, 0, 0, 0, 376, 0, 0,
- 377, 0, 736, 0, 747, 0, 0, 381, 0, 0,
- 0, 385, 708, 709, 710, 0, 388, 0, 0, 0,
- 0, 391, 0, 0, 0, 0, 394, 0, 0, 0,
- 0, 397, 0, 400, 0, 0, 0, 402, 0, 0,
- 0, 0, 0, 0, 404, 0, 0, 407, 0, 0,
- 0, 0, 0, 0, 417, 416, 0, 0, 0, 0,
- 0, 432, 0, 438, 439, 635, 636, 637, 638, 639,
- 640, 641, 642, 643, 644, 645, 646, 647, 648, 0,
- 472, 0, 0, 0, 0, 480, 635, 636, 637, 638,
- 639, 640, 641, 642, 643, 0, 0, 0, 0, 0,
- 0, 0, 0, 426, 0, 0, 0, 0, 440, 137,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 481,
- 137, 0, 0, 0, 0, 0, 0, 0, 491, 0,
- 0, 529, 0, 530, 0, 0, 0, 0, 535, 0,
- 505, 0, 0, 508, 0, 0, 0, 0, 543, 0,
- 515, 0, 0, 0, 545, 544, 0, 0, 0, 3,
- 0, 0, 0, 550, 553, 0, 5, 6, 0, 0,
- 0, 561, 0, 0, 0, 704, 8, 0, 705, 706,
- 707, 567, 0, 9, 0, 0, 572, 571, 0, 0,
- 0, 0, 577, 578, 0, 14, 581, 0, 0, 584,
- 0, 16, 708, 709, 710, 0, 593, 0, 0, 595,
- 0, 0, 18, 0, 601, 20, 602, 22, 0, 0,
- 0, 0, 606, 0, 0, 611, 610, 0, 25, 0,
- 27, 0, 28, 0, 30, 0, 0, 0, 625, 0,
- 35, 0, 632, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 669, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 681, 0,
- 0, 0, 614, 616, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 658, 0, 0, 0, 0, 0, 732,
- 0, 0, 0, 0, 0, 744, 0, 0, 0, 750,
- 679, 0, 0, 0, 0, 753, 0, 754, 0, 0,
- 0, 756, 0, 0, 0, 0, 0, 760, 0, 0,
- 0, 0, 0, 761, 763, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 745,
- 0, 0, 0, 185, 0, 0, 0, 773, 0, 0,
- 775, 776, 777, 778, 0, 0, 0, 0, 0, 0,
- 781, 0, 0, 0, 784, 783, 0, 0, 0, 0,
- 0, 0, 0, 792, 0, 794, 0, 0, 797, 0,
- 799, 0, 801, 0, 0, 0, 0, 0, 814, 0,
+ 115, 672, 270, 236, 61, 421, 344, 479, 146, 291,
+ 57, 337, 187, 188, 339, 532, 347, 943, 531, 302,
+ 307, 312, 929, 613, 190, 1017, 434, 519, 421, 697,
+ 906, 711, 772, 326, 789, 871, 45, 737, 907, 345,
+ 926, 911, 54, 808, 931, 485, 970, 932, 1162, 349,
+ 918, 205, 803, 207, 512, 925, 1095, 1110, 1101, 1054,
+ 1101, 1106, 106, 1, 144, 670, 1325, 1325, 1333, 1333,
+ 671, 1340, 518, 1325, 15, 5, 114, 842, 249, 192,
+ 2, 193, 1, 194, 195, 464, 196, 250, 1170, 144,
+ 4, 5, 198, 199, 1318, 200, 201, 202, 204, 202,
+ 206, 202, 208, 209, 267, 211, 144, 212, 144, 189,
+ 40, 338, 476, 33, 340, 251, 1, 5, 447, 17,
+ 5, 5, 2, 134, 10, 333, 1184, 216, 266, 217,
+ 220, 223, 4, 226, 289, 1396, 246, 433, 1399, 26,
+ 145, 735, 1400, 29, 1106, 1403, 822, 333, 825, 1404,
+ 828, 422, 831, 189, 833, 316, 1013, 249, 26, 282,
+ 1394, 425, 29, 1172, 908, 145, 250, 912, 251, 370,
+ 915, 1012, 17, 19, 467, 31, 32, 476, 246, 1052,
+ 1423, 283, 145, 1038, 145, 1425, 484, 1077, 350, -629,
+ 352, 1039, 26, 5, 1041, 525, 29, 357, 34, 359,
+ -631, 502, 704, 362, 363, 1059, 735, 1049, 513, 364,
+ 365, 366, 367, 626, 368, -632, 369, 202, 371, 734,
+ 1094, 1190, 526, 1290, 326, 1205, 1357, 374, 956, 1113,
+ 707, 710, 378, 379, 961, 380, 485, 288, 948, 968,
+ 274, 384, 951, 682, 891, 386, 387, 850, 966, 731,
+ 389, 390, 708, 709, 442, 392, 393, 107, 108, 21,
+ 627, 2, 994, 398, 996, 1154, 15, 401, 19, 924,
+ 403, 4, 661, 246, 301, 483, 560, 405, 10, 408,
+ 409, 411, 412, 414, 36, 415, 1170, 600, 1114, 5,
+ 311, 7, 1286, 34, 1316, 1160, 1115, 1117, 5, 251,
+ 338, 1138, 1136, 340, 1125, 33, 12, 704, 1126, 1127,
+ 1128, 1129, 297, 670, 587, 459, 588, 1040, 671, 317,
+ 1042, 5, 1043, 5, 973, 1109, 1044, 296, 975, 31,
+ 32, 5, 978, 980, 981, 709, 664, 984, 985, 323,
+ 665, 987, -633, 899, 24, 903, 5, 633, 903, 493,
+ 5, 903, 496, 5, 903, 499, 807, 903, 1316, 704,
+ -51, 1172, 588, 1314, 315, 316, 1130, 443, 706, 707,
+ 527, 528, 1196, 476, 463, 473, 341, 352, 533, 664,
+ 536, 5, 687, 665, 537, 539, 540, 1091, 541, 21,
+ 868, 708, 709, 694, 306, 689, 696, 691, 546, 693,
+ 547, 548, 346, 549, 733, 551, 552, 762, 554, 555,
+ 1289, 556, 558, 1203, 36, -30, 562, 563, 564, 326,
+ 1185, 374, 1116, 1118, 1119, 1120, 569, 570, 1193, 5,
+ 573, 574, 1323, 851, 1316, 531, 229, 579, 580, 1147,
+ 582, 583, 5, 585, 586, 670, 1330, 444, 1310, 421,
+ 671, 704, 1347, 596, 597, 598, 654, 656, 1227, 1228,
+ 603, 459, 604, 532, 607, 882, 608, 1083, 1084, 1085,
+ 1086, 755, 676, 678, 757, 859, 860, 861, 708, 709,
+ 653, 655, 1166, 1273, 477, 1280, 1167, 1168, 1169, 517,
+ 7, 751, 5, 447, 490, 521, 675, 677, 1197, 1198,
+ 1199, 696, 10, 883, 903, 5, 903, 686, 522, 652,
+ 903, 5, 657, 423, 660, 1331, 1316, 662, 663, 424,
+ 1211, 213, 214, 251, 518, 674, -59, 17, 1217, 1218,
+ 1137, -59, -59, -59, 134, 228, 685, 286, 230, 231,
+ 232, 433, 688, 747, 1171, 690, 1158, 5, 692, 855,
+ 856, 857, 807, 31, 32, 752, 704, 329, 330, 698,
+ 706, 707, 533, 1285, 5, 533, 854, 537, 1186, 759,
+ 233, 234, 1189, 704, 1173, 628, 629, 1183, 707, 246,
+ 433, 1187, 587, 708, 709, 1192, 805, 764, 708, 709,
+ 423, 424, 765, 766, 767, 705, 768, 769, 771, 769,
+ 708, 709, 774, 884, 1350, 1350, 1067, 1068, 889, 903,
+ 228, 696, 892, 230, 231, 232, 921, 1309, 785, 786,
+ 788, 786, 588, 790, 1312, 791, 154, 793, 156, 795,
+ 158, 1099, 160, 709, 1058, 469, 502, 913, 942, 418,
+ 916, 1229, 804, 618, 971, 228, 815, 623, 230, 231,
+ 232, 233, 234, 805, 967, 806, 421, 1288, 816, 897,
+ 818, 900, 864, 821, 901, 824, 666, 827, 1037, 830,
+ 612, 830, 991, 992, 598, 839, 840, 836, 1123, 875,
+ 1164, 1165, 604, 604, 1294, 608, 1166, 1210, 1213, 844,
+ 1167, 1168, 1169, 807, 847, 684, 5, 696, 892, 1323,
+ 1104, 1316, 1188, 1338, 1352, 134, 228, 229, 728, 230,
+ 231, 232, 233, 234, 728, 1345, 43, 1166, 728, 1099,
+ 287, 1167, 1168, 1169, 622, 758, 933, 5, 5, 165,
+ 1058, 1331, 1316, 166, 167, 807, 168, 704, 169, 1320,
+ 705, 706, 707, 1337, 1337, 280, 1342, 1346, 1171, 1351,
+ 1351, 281, 1355, 1021, 1019, 566, 170, 1022, 1023, 1024,
+ 1015, 1015, 171, 5, 708, 709, 710, 683, 1282, 172,
+ 173, 807, 1032, 174, 1053, 141, 507, 175, 862, 1171,
+ 150, 866, 153, 268, 155, 269, 157, 699, 159, 176,
+ 700, 701, 702, 502, 759, 872, 844, 1045, 878, 1047,
+ 177, 178, 179, 180, 181, 769, 98, 835, 1076, 769,
+ 1397, 952, 406, 954, 955, 786, 101, 1401, 958, 896,
+ 3, 786, 421, 413, 962, 791, 410, 1405, 6, 228,
+ 229, 1406, 230, 231, 232, 233, 234, 8, 696, 806,
+ 1407, 830, 104, 974, 9, 830, 1003, 11, 1139, 977,
+ 979, 830, 0, 0, 983, 830, 1424, 986, 830, 0,
+ 988, 0, 16, 989, 0, 0, 0, 0, 836, 836,
+ 993, 0, 608, 18, 997, 998, 20, 1166, 22, 863,
+ 1111, 1167, 1168, 1169, 1001, 1002, 0, 5, 458, 25,
+ 0, 27, 1316, 28, 0, 30, 873, 0, 1121, 474,
+ 475, 35, 460, 462, 0, 0, 465, 466, 488, 228,
+ 229, 0, 230, 231, 232, 495, 696, 0, 498, 0,
+ 487, 501, 0, 0, 0, 0, 898, 494, 902, 511,
+ 497, 902, 0, 500, 902, 0, 0, 902, 0, 1171,
+ 902, 510, 0, 1057, 0, 0, 728, 0, 1062, 1063,
+ 1064, 1065, 0, 0, 934, 952, 952, 1015, 0, 228,
+ 0, 0, 230, 231, 232, 233, 234, 0, 0, 806,
+ 1200, 228, 229, 1075, 230, 231, 232, 233, 234, 0,
+ 1079, 1080, 1081, 0, 1082, 830, 830, 830, 0, 1087,
+ 0, 1088, 0, 0, 0, 608, 0, 1093, 0, 844,
+ 0, 0, 0, 1097, 0, 0, 0, 0, 1166, 1099,
+ 0, 0, 1167, 1168, 1169, 1170, 0, 0, 5, 0,
+ 0, 0, 0, 0, 0, 0, 0, 704, 1015, 0,
+ 705, 706, 707, 635, 636, 637, 638, 639, 640, 641,
+ 642, 643, 0, 1141, 0, 1144, 0, 608, 1148, 0,
+ 0, 0, 1151, 1152, 708, 709, 710, 1155, 1156, 0,
+ 1157, 0, 1011, 830, 5, 1159, 0, 0, 0, 0,
+ 1171, 5, 1025, 704, 844, 0, 705, 706, 707, 1163,
+ 704, 1097, 1097, 705, 706, 707, 0, 902, 0, 902,
+ 1172, 0, 0, 902, 0, 0, 0, 736, 0, 1015,
+ 708, 709, 710, 728, 0, 0, 0, 708, 709, 710,
+ 0, 1166, 0, 0, 0, 1167, 1168, 1169, 1170, 0,
+ 0, 5, 0, 1208, 0, 1209, 0, 1144, 608, 1212,
+ 704, 1148, 1214, 705, 706, 707, 1216, 608, 0, 1220,
+ 1191, 0, 0, 476, 0, 0, 1222, 1224, 0, 0,
+ 0, 5, 0, 0, 0, 0, 0, 708, 709, 710,
+ 704, 0, 0, 705, 706, 707, 0, 1395, 0, 0,
+ 1293, 1222, 735, 1171, 0, 0, 923, 736, 0, 1398,
+ 0, 0, 0, 0, 0, 0, 1402, 708, 709, 710,
+ 0, 0, 902, 1172, 0, 134, 228, 229, 0, 230,
+ 231, 232, 233, 234, 0, 0, 0, 728, 0, 1295,
+ 1297, 1298, 1299, 1300, 0, 0, 1302, 1303, 1304, 1305,
+ 1306, 476, 0, 1308, 0, 608, 0, 844, 0, 5,
+ 0, 0, 608, 0, 0, 0, 0, 0, 704, 0,
+ 0, 705, 706, 707, 0, 0, 0, 0, 0, 0,
+ 735, 728, 0, 0, 728, 736, 0, 0, 728, 0,
+ 0, 0, 728, 1361, 0, 708, 709, 710, 0, 0,
+ 1366, 0, 1369, 0, 0, 0, 0, 0, 1373, 0,
+ 1376, 0, 0, 0, 0, 1380, 0, 0, 1383, 0,
+ 0, 0, 0, 1387, 0, 0, 110, 0, 0, 0,
+ 0, 0, 0, 111, 112, 0, 113, 0, 0, 116,
+ 0, 117, 0, 118, 0, 0, 0, 119, 728, 120,
+ 0, 121, 0, 122, 0, 123, 728, 124, 0, 125,
+ 0, 126, 0, 0, 728, 1224, 0, 0, 0, 127,
+ 1411, 1413, 0, 0, 1416, 0, 128, 0, 129, 0,
+ 130, 0, 131, 0, 132, 1166, 133, 5, 0, 1167,
+ 1168, 1169, 1170, 0, 0, 5, 704, 0, 0, 705,
+ 706, 707, 0, 0, 704, 0, 0, 705, 706, 707,
+ 0, 0, 0, 736, 0, 747, 0, 0, 0, 0,
+ 0, 0, 0, 708, 709, 710, 0, 0, 197, 0,
+ 0, 708, 709, 710, 0, 1317, 0, 1324, 1324, 1332,
+ 1332, 0, 1339, 1343, 1324, 1348, 1348, 1171, 1353, 3,
+ 0, 0, 0, 0, 476, 0, 5, 6, 0, 0,
+ 0, 0, 5, 0, 0, 704, 8, 1172, 705, 706,
+ 707, 704, 227, 9, 705, 706, 707, 0, 0, 3,
+ 0, 0, 300, 735, 305, 14, 310, 6, 0, 322,
+ 0, 16, 708, 709, 710, 0, 8, 0, 708, 709,
+ 710, 0, 18, 9, 0, 20, 0, 22, 0, 0,
+ 0, 0, 0, 0, 0, 14, 0, 0, 25, 0,
+ 27, 16, 28, 0, 30, 0, 0, 0, 0, 355,
+ 35, 0, 18, 0, 356, 20, 358, 22, 0, 360,
+ 361, 0, 0, 0, 0, 0, 0, 0, 25, 0,
+ 27, 0, 28, 0, 30, 0, 0, 0, 0, 0,
+ 35, 372, 373, 0, 0, 0, 376, 0, 0, 377,
+ 0, 0, 0, 0, 5, 0, 381, 0, 0, 0,
+ 385, 0, 0, 704, 0, 388, 705, 706, 707, 0,
+ 391, 0, 0, 1191, 0, 394, 0, 0, 0, 0,
+ 397, 0, 400, 0, 0, 0, 402, 0, 1, 2,
+ 708, 709, 710, 404, 3, 0, 407, 0, 0, 4,
+ 0, 5, 6, 417, 416, 0, 0, 0, 7, 0,
+ 432, 8, 438, 439, 0, 0, 0, 0, 9, 10,
+ 0, 11, 0, 12, 0, 0, 0, 0, 13, 472,
+ 14, 0, 0, 15, 480, 0, 16, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 18, 0, 19,
+ 20, 21, 22, 0, 0, 0, 0, 0, 0, 0,
+ 23, 24, 0, 25, 26, 27, 0, 28, 29, 30,
+ 31, 32, 33, 0, 34, 35, 36, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 817, 0,
- 820, 0, 0, 823, 0, 826, 0, 829, 0, 832,
- 0, 0, 834, 0, 0, 0, 0, 0, 0, 0,
- 838, 0, 0, 841, 0, 843, 0, 0, 0, 0,
- 846, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 529, 0, 530, 0, 0, 0, 0, 535, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 543, 0, 0,
+ 0, 0, 0, 545, 544, 0, 0, 0, 0, 0,
+ 0, 0, 550, 553, 0, 0, 0, 0, 0, 0,
+ 561, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 567, 0, 0, 0, 0, 572, 571, 0, 0, 0,
+ 0, 577, 578, 0, 0, 581, 0, 0, 584, 0,
+ 0, 0, 0, 0, 0, 593, 0, 0, 595, 0,
+ 0, 0, 0, 601, 0, 602, 0, 0, 0, 0,
+ 0, 606, 0, 0, 611, 610, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 625, 0, 0,
+ 0, 632, 635, 636, 637, 638, 639, 640, 641, 642,
+ 643, 644, 645, 646, 647, 648, 669, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 681, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 865, 0, 867, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 877, 0, 879,
- 0, 0, 0, 0, 0, 0, 885, 0, 886, 0,
- 887, 0, 888, 0, 852, 0, 395, 396, 0, 399,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 869, 0, 869, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 930, 0, 0,
- 0, 0, 0, 0, 0, 935, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 732, 0,
+ 0, 0, 0, 0, 744, 0, 0, 0, 750, 0,
+ 0, 0, 0, 0, 753, 0, 754, 0, 0, 0,
+ 756, 0, 0, 0, 0, 0, 760, 0, 0, 0,
+ 0, 0, 761, 763, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 904, 0, 0, 909, 0, 0, 0,
- 0, 0, 0, 0, 0, 919, 0, 0, 0, 0,
- 0, 679, 0, 0, 679, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 773, 0, 0, 775,
+ 776, 777, 778, 0, 0, 0, 0, 0, 0, 781,
+ 0, 0, 0, 784, 783, 0, 0, 0, 0, 0,
+ 0, 0, 792, 0, 794, 0, 0, 797, 0, 799,
+ 0, 801, 0, 0, 0, 0, 0, 814, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 976, 0, 0, 0, 0,
- 982, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 990, 0, 0, 0, 0, 0, 0, 0,
- 995, 0, 0, 999, 0, 0, 0, 0, 0, 0,
- 1000, 0, 0, 1004, 1005, 1006, 1007, 1008, 1009, 0,
- 0, 1010, 0, 1014, 0, 0, 1018, 0, 559, 0,
- 0, 1020, 0, 1028, 1029, 1030, 565, 0, 0, 0,
- 0, 568, 1034, 0, 0, 0, 0, 0, 575, 576,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1228,
- 1229, 1230, 1231, 1232, 1233, 1234, 594, 1235, 1236, 1237,
- 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247,
- 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257,
- 1258, 0, 0, 1259, 1260, 1261, 1262, 1263, 1071, 0,
- 0, 0, 1049, 0, 0, 1076, 0, 0, 0, 0,
- 0, 1054, 0, 0, 0, 0, 0, 0, 0, 0,
- 1088, 0, 1090, 0, 0, 0, 0, 0, 0, 1094,
- 0, 0, 0, 0, 0, 0, 0, 0, 1105, 1106,
+ 0, 0, 0, 0, 0, 0, 0, 817, 0, 820,
+ 0, 0, 823, 0, 826, 0, 829, 0, 832, 0,
+ 0, 834, 0, 0, 0, 0, 0, 0, 0, 838,
+ 0, 0, 841, 0, 843, 0, 0, 0, 0, 846,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1122, 0, 0,
- 0, 0, 1132, 0, 0, 1133, 1138, 0, 0, 0,
- 0, 1141, 0, 1144, 0, 0, 1148, 0, 0, 0,
- 0, 0, 0, 0, 869, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 865,
+ 0, 867, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 877, 0, 879, 0,
+ 0, 0, 0, 0, 0, 885, 0, 886, 0, 887,
+ 0, 888, 0, 0, 0, 0, 0, 135, 137, 139,
+ 139, 142, 0, 0, 148, 139, 151, 139, 148, 139,
+ 148, 139, 148, 139, 148, 161, 163, 0, 185, 185,
+ 185, 0, 0, 0, 0, 0, 930, 0, 0, 0,
+ 0, 0, 0, 0, 935, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1159, 0, 0, 0, 679, 0, 0,
+ 0, 395, 396, 0, 399, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 779, 780, 0, 1200, 0,
- 1202, 782, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 796, 1204, 798, 1205,
- 800, 0, 802, 0, 1179, 0, 0, 1179, 0, 0,
- 0, 1179, 0, 0, 0, 1217, 0, 0, 0, 1219,
- 0, 0, 869, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1279, 0, 0, 0, 0, 0, 0,
- 0, 1285, 0, 1289, 1290, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 869, 869, 0,
+ 244, 0, 0, 0, 0, 272, 0, 0, 0, 0,
+ 0, 0, 0, 0, 976, 0, 0, 0, 0, 982,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1281, 0, 0, 0, 0, 0, 0, 0, 0, 1299,
- 0, 0, 0, 0, 0, 0, 1305, 0, 0, 0,
+ 0, 990, 0, 0, 0, 0, 0, 0, 0, 995,
+ 0, 0, 999, 0, 0, 0, 0, 0, 0, 1000,
+ 0, 0, 1004, 1005, 1006, 1007, 1008, 1009, 0, 0,
+ 1010, 0, 1014, 0, 0, 1018, 0, 0, 0, 0,
+ 1020, 0, 1029, 1030, 1031, 0, 0, 0, 0, 0,
+ 0, 1035, 1267, 1230, 1231, 1232, 1233, 1234, 1235, 1236,
+ 1268, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245,
+ 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255,
+ 1256, 1257, 1258, 1259, 1260, 1269, 1270, 1261, 1262, 1263,
+ 1264, 1265, 0, 559, 0, 0, 0, 0, 0, 0,
+ 0, 565, 0, 0, 0, 0, 568, 0, 1073, 0,
+ 0, 0, 0, 575, 576, 1078, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 426, 0,
+ 1090, 594, 1092, 440, 137, 0, 0, 0, 0, 1096,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1107, 1108,
+ 0, 0, 0, 0, 481, 137, 0, 0, 0, 0,
+ 0, 0, 0, 491, 0, 0, 0, 0, 1124, 0,
+ 0, 0, 0, 1134, 0, 505, 1135, 1140, 508, 0,
+ 0, 0, 1143, 0, 1146, 515, 0, 1150, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1311, 0, 1313, 0, 1320, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1354, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1361, 0, 0, 0, 0, 0, 0, 1366, 0,
- 0, 0, 0, 0, 0, 0, 1373, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 944, 945, 946,
- 947, 0, 949, 950, 0, 1390, 1391, 1, 2, 0,
- 0, 0, 957, 3, 959, 960, 0, 0, 4, 0,
- 5, 6, 964, 965, 0, 0, 0, 7, 0, 0,
- 8, 0, 0, 0, 0, 972, 0, 9, 10, 0,
- 11, 0, 12, 1407, 0, 0, 0, 13, 0, 14,
- 1416, 0, 15, 0, 0, 16, 0, 0, 0, 0,
- 0, 0, 0, 17, 0, 0, 18, 0, 19, 20,
- 21, 22, 1425, 0, 0, 0, 0, 0, 0, 23,
- 24, 0, 25, 26, 27, 0, 28, 29, 30, 31,
- 32, 33, 0, 34, 35, 36, 1265, 1228, 1229, 1230,
- 1231, 1232, 1233, 1234, 1266, 1235, 1236, 1237, 1238, 1239,
- 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249,
- 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1267,
- 1268, 1259, 1260, 1261, 1262, 1263, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1161, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1065, 0, 0, 0, 0, 1068, 1069, 0, 1070, 0,
- 0, 0, 0, 0, 0, 0, 1072, 1272, 1228, 1229,
- 1230, 1231, 1232, 1233, 1234, 1273, 1235, 1236, 1237, 1238,
- 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248,
- 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258,
- 1274, 1275, 1259, 1260, 1261, 1262, 1263, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1202,
+ 0, 1204, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1206, 0,
+ 1207, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1219, 0, 0, 0,
+ 1221, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 779, 780, 0, 0, 1281, 0, 782, 0, 0, 0,
+ 0, 0, 1287, 0, 1291, 1292, 0, 614, 616, 0,
+ 0, 796, 0, 798, 0, 800, 0, 802, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 658, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 679, 0, 0, 0, 0,
+ 1301, 0, 0, 0, 0, 0, 0, 1307, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1313, 0, 1315, 0, 1322, 0, 0, 0, 0,
+ 0, 0, 0, 0, 745, 0, 0, 0, 185, 1356,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1363, 0, 0, 0, 0, 0, 0, 1368,
+ 0, 0, 0, 0, 0, 0, 0, 1375, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1392, 1393, 0, 0,
+ 0, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 0, 1237,
+ 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247,
+ 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257,
+ 1258, 1259, 1260, 0, 1409, 1261, 1262, 1263, 1264, 1265,
+ 0, 1418, 944, 945, 946, 947, 0, 949, 950, 0,
+ 0, 0, 0, 0, 0, 0, 0, 957, 0, 959,
+ 960, 0, 0, 1427, 0, 0, 0, 964, 965, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 972, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 852,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 869,
+ 0, 869, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 904, 0,
+ 0, 909, 0, 0, 0, 0, 0, 0, 0, 0,
+ 919, 0, 0, 0, 0, 0, 679, 0, 0, 679,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1066, 0, 0, 0, 0,
+ 1069, 1070, 0, 1071, 0, 0, 0, 0, 0, 1072,
+ 0, 0, 1074, 1274, 1230, 1231, 1232, 1233, 1234, 1235,
+ 1236, 1275, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244,
+ 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254,
+ 1255, 1256, 1257, 1258, 1259, 1260, 1276, 1277, 1261, 1262,
+ 1263, 1264, 1265, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1213, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1224, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1050, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1055, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1215, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1226,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1309, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 869, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1356, 0, 0, 1357, 1358, 0, 1360, 0, 0,
- 0, 1362, 1363, 0, 1365, 0, 1368, 0, 0, 1369,
- 1370, 0, 1372, 0, 1375, 0, 1376, 1377, 0, 1379,
- 1380, 0, 1382, 1383, 0, 1384, 0, 1386, 1387, 0,
- 1388, 0, 1389, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 679, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1406, 0, 1408, 1410, 0, 1412, 1413, 1415, 0,
- 1417, 1418, 1419, 1420, 0, 0, 0, 0, 0, 0,
+ 1311, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1181, 0, 0, 1181, 0, 0, 0, 1181, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1358, 869,
+ 0, 1359, 1360, 0, 1362, 0, 0, 0, 1364, 1365,
+ 0, 1367, 0, 1370, 0, 0, 1371, 1372, 0, 1374,
+ 0, 1377, 0, 1378, 1379, 0, 1381, 1382, 0, 1384,
+ 1385, 0, 1386, 0, 1388, 1389, 0, 1390, 0, 1391,
+ 0, 0, 0, 0, 869, 869, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1283, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1424, 0, 1426
+ 0, 0, 0, 0, 0, 0, 0, 0, 1408, 0,
+ 1410, 1412, 0, 1414, 1415, 1417, 0, 1419, 1420, 1421,
+ 1422, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1426, 0, 1428
};
static const yytype_int16 yycheck[] =
{
- 57, 196, 0, 192, 346, 227, 558, 374, 115, 598,
- 0, 220, 131, 132, 223, 604, 242, 434, 853, 201,
- 206, 208, 434, 592, 212, 528, 204, 369, 836, 0,
- 821, 997, 411, 821, 742, 697, 824, 783, 656, 235,
- 838, 0, 352, 841, 893, 379, 955, 133, 243, 832,
- 1133, 836, 156, 1061, 158, 1063, 1064, 694, 678, 403,
- 4, 836, 1293, 4, 65, 67, 1073, 25, 1056, 14,
- 4, 49, 17, 1295, 1296, 1297, 1298, 22, 1300, 136,
- 1302, 138, 365, 140, 141, 19, 143, 6, 163, 90,
- 92, 17, 149, 150, 28, 152, 153, 154, 155, 156,
- 157, 158, 159, 160, 195, 162, 14, 164, 0, 17,
- 88, 356, 56, 720, 0, 722, 60, 724, 195, 726,
- 78, 728, 56, 35, 201, 51, 60, 184, 1359, 186,
- 187, 188, 377, 190, 220, 1142, 80, 223, 1146, 80,
- 84, 40, 1364, 84, 89, 1367, 80, 6, 7, 1371,
- 84, 347, 1374, 12, 49, 7, 1378, 40, 17, 11,
- 3, 350, 17, 82, 1144, 17, 821, 952, 1148, 824,
- 274, 26, 827, 368, 86, 87, 9, 952, 73, 78,
- 147, 89, 25, 974, 1033, 993, 974, 1409, 245, 977,
- 247, 163, 1414, 88, 416, 1161, 378, 254, 19, 256,
- 55, 397, 6, 260, 261, 38, 989, 28, 404, 266,
- 267, 268, 269, 17, 271, 403, 273, 274, 275, 927,
- 1055, 929, 418, 82, 603, 1074, 1001, 284, 1311, 539,
- 201, 893, 289, 290, 1222, 292, 570, 61, 807, 198,
- 1149, 298, 30, 31, 862, 302, 303, 836, 866, 752,
- 307, 308, 872, 890, 598, 312, 313, 540, 878, 569,
- 163, 1110, 5, 320, 6, 53, 54, 324, 9, 552,
- 327, 155, 15, 157, 16, 470, 17, 334, 82, 336,
- 337, 338, 339, 340, 17, 342, 1077, 513, 5, 1077,
- 1078, 898, 5, 26, 1129, 902, 1094, 38, 15, 906,
- 907, 908, 15, 17, 911, 912, 24, 17, 915, 65,
- 202, 1220, 35, 23, 155, 71, 157, 209, 61, 974,
- 1095, 39, 977, 409, 979, 1071, 412, 816, 983, 818,
- 48, 163, 821, 56, 90, 824, 50, 51, 827, 17,
- 82, 830, 17, 1051, 61, 62, 31, 543, 26, 163,
- 386, 26, 7, 389, 1296, 697, 392, 12, 9, 77,
- 1302, 64, 17, 86, 87, 1153, 17, 357, 53, 54,
- 427, 428, 41, 371, 364, 53, 54, 434, 435, 54,
- 437, 1142, 1291, 7, 441, 442, 443, 11, 445, 1150,
- 159, 160, 574, 589, 1102, 774, 592, 583, 455, 586,
- 457, 458, 580, 460, 600, 462, 463, 633, 465, 466,
- 598, 468, 469, 1159, 1222, 150, 473, 474, 475, 32,
- 33, 478, 1077, 1078, 1079, 1080, 483, 484, 150, 619,
- 487, 488, 622, 1040, 1041, 1042, 1043, 494, 495, 851,
- 497, 498, 149, 500, 501, 161, 162, 1282, 790, 759,
- 765, 766, 767, 510, 511, 512, 547, 548, 1204, 1205,
- 517, 57, 519, 7, 521, 882, 523, 11, 12, 13,
- 547, 548, 563, 564, 17, 1183, 24, 20, 793, 22,
- 67, 791, 374, 1191, 1192, 72, 563, 564, 977, 48,
- 979, 610, 384, 16, 983, 17, 17, 574, 1153, 1154,
- 1155, 697, 74, 75, 26, 92, 1095, 29, 30, 31,
- 546, 1118, 25, 549, 36, 551, 47, 1293, 554, 555,
- 32, 1297, 1298, 408, 1300, 1301, 562, 1303, 1304, 414,
- 1306, 53, 54, 55, 147, 148, 149, 573, 151, 152,
- 153, 154, 155, 579, 33, 17, 582, 17, 62, 585,
- 1139, 893, 22, 1142, 26, 612, 155, 1146, 30, 31,
- 596, 1150, 619, 1218, 17, 622, 762, 624, 45, 626,
- 7, 156, 1280, 26, 11, 12, 13, 29, 31, 1287,
- 17, 53, 54, 20, 7, 22, 147, 644, 1364, 12,
- 157, 1080, 649, 650, 651, 1371, 653, 654, 655, 656,
- 53, 54, 659, 8, 1210, 1381, 1212, 54, 804, 1385,
- 17, 807, 808, 795, 21, 22, 369, 1206, 675, 676,
- 677, 678, 120, 680, 122, 682, 124, 684, 126, 686,
- 154, 155, 69, 1222, 1001, 346, 832, 826, 847, 695,
- 829, 533, 894, 112, 891, 537, 703, 816, 117, 817,
- 119, 818, 121, 974, 123, 997, 125, 527, 715, 1086,
- 717, 1226, 769, 720, 556, 722, 1182, 724, 1186, 726,
- 571, 728, 58, 59, 731, 53, 54, 734, 1063, 786,
- 1146, 156, 739, 740, 1298, 742, 161, 162, 163, 746,
- 1301, 1033, 61, 62, 751, 7, 8, 893, 894, 11,
- 12, 13, 14, 7, 1304, 17, 598, 11, 12, 13,
- 14, 0, 604, 17, 26, 201, 608, 29, 30, 31,
- 1303, 1304, 26, 1012, 1013, 29, 30, 31, 1095, 536,
- 7, 624, 1074, 843, 11, 12, 13, 151, 152, 153,
- 17, 53, 54, 55, 21, 22, 925, 926, 7, 53,
- 54, 55, 11, 12, 13, 739, 740, 69, 17, 954,
- 955, 1136, 1137, 22, 129, 69, 129, 129, 1110, 129,
- 7, 129, 968, 995, 11, 12, 13, 89, 768, 199,
- 17, 771, 7, 199, 958, 89, 11, 12, 13, 14,
- 478, 129, 69, 989, 851, 785, 853, 986, 788, 988,
- 129, 35, 570, 1214, 129, 862, 129, 1033, 129, 866,
- 69, 868, 398, 870, 871, 872, 129, 815, 875, 1161,
- 195, 878, 56, 195, 881, 882, 60, 597, 129, 147,
- 148, 597, 69, 151, 152, 153, 70, 1033, 597, 597,
- 731, 898, 0, 900, 69, 902, 129, 129, 129, 906,
- 907, 908, 86, 87, 911, 912, 129, 914, 915, 1411,
- 917, 148, 149, 920, 151, 152, 153, 129, 925, 926,
- 927, 361, 929, 334, 931, 932, 148, 769, 1074, 151,
- 152, 153, 372, 373, 941, 942, 337, 0, 1390, 10,
- 339, 381, 0, 942, 786, 1095, 1085, 18, 388, -1,
- -1, 391, -1, -1, 394, -1, 27, -1, -1, -1,
- -1, -1, 402, 34, 1110, 148, 37, -1, 151, 152,
- 153, 154, 155, 156, 816, 158, 818, -1, -1, 821,
- -1, 52, 824, -1, -1, 827, -1, -1, 830, -1,
- -1, -1, 63, 1000, 836, 66, -1, 68, 1005, 1006,
- 1007, 1008, 844, -1, 1149, 1012, 1013, -1, 79, -1,
- 81, -1, 83, -1, 85, -1, -1, -1, 1157, -1,
- 91, -1, 1029, -1, -1, -1, -1, -1, -1, 1036,
- 1037, 1038, 8, 1040, 1041, 1042, 1043, -1, 1045, 9,
- 1047, 17, -1, -1, 1051, -1, 1053, 17, 1055, -1,
- 26, -1, 1059, 29, 30, 31, 26, -1, -1, 29,
- 30, 31, -1, -1, -1, -1, -1, -1, 38, -1,
- -1, -1, 42, 43, -1, 1220, -1, 53, 54, 55,
- -1, -1, -1, 53, 54, 55, -1, -1, -1, -1,
- -1, 1098, -1, 1100, -1, 1102, 1103, -1, -1, -1,
- 1107, 1108, -1, -1, -1, 1112, 1113, -1, 1115, -1,
- 952, 1118, -1, 1120, -1, -1, -1, -1, -1, 17,
- -1, -1, 1129, -1, -1, -1, -1, 1134, 26, 1136,
- 1137, 29, 30, 31, -1, 977, -1, 979, -1, -1,
- -1, 983, -1, 7, -1, 43, 1291, 11, 12, 13,
- 14, 993, -1, 17, -1, 53, 54, 55, -1, -1,
- -1, -1, 26, -1, -1, 29, 30, 31, -1, -1,
- -1, 1178, 36, 1180, -1, 1182, 1183, 1184, -1, 1186,
- 1187, -1, -1, -1, 1191, 1192, -1, 1194, -1, 53,
- 54, 55, -1, -1, 1201, 1202, -1, -1, -1, -1,
- 9, -1, -1, -1, -1, 69, 148, 149, 17, 151,
- 152, 153, 154, 155, -1, 1361, 158, 26, 1225, 1226,
- 29, 30, 31, -1, -1, 89, -1, 1366, -1, 38,
- -1, -1, -1, -1, 1373, 147, 148, 149, 1080, 151,
- 152, 153, 154, 155, 53, 54, 55, -1, -1, -1,
- -1, -1, -1, 1095, -1, -1, -1, 1264, 1265, 1266,
- 1267, 1268, -1, -1, 1271, 1272, 1273, 1274, 1275, 9,
- -1, 1278, -1, 1280, -1, 1282, -1, 17, 148, -1,
- 1287, 151, 152, 153, 154, 155, 26, -1, 158, 29,
- 30, 31, -1, -1, -1, -1, -1, 1139, 38, -1,
- 1142, -1, -1, 43, 1146, -1, -1, -1, 1150, -1,
- -1, 1318, -1, 53, 54, 55, -1, 45, 1325, -1,
- 1327, -1, -1, -1, 52, 53, 1333, 55, 1335, -1,
- 58, -1, 60, 1340, 62, -1, 1343, -1, 66, -1,
- 68, 1348, 70, -1, 72, -1, 74, -1, 76, -1,
- 78, -1, 80, -1, -1, -1, -1, -1, -1, -1,
- 88, -1, -1, -1, 1206, -1, -1, 95, -1, 97,
- -1, 99, 1214, 101, -1, 103, -1, 105, -1, -1,
- 1222, 362, 363, 1390, -1, 366, 367, -1, 1395, 1396,
- 148, 149, 1399, 151, 152, 153, 154, 155, -1, 380,
- -1, -1, -1, -1, -1, -1, 387, -1, -1, 390,
- -1, -1, 393, -1, -1, -1, -1, -1, -1, 147,
- 401, -1, 109, 110, 111, 112, 113, -1, -1, 116,
- 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
- 127, 128, -1, 130, 131, 132, -1, -1, -1, -1,
- -1, 1293, -1, 1295, 1296, 1297, 1298, -1, 1300, 1301,
- 1302, 1303, 1304, 191, 1306, -1, 10, -1, -1, -1,
- -1, -1, -1, 203, 18, 205, -1, 207, -1, 17,
- 210, -1, -1, 27, -1, -1, -1, -1, 26, -1,
- 34, 29, 30, 31, -1, -1, -1, -1, -1, -1,
- -1, -1, 46, -1, -1, 192, -1, -1, 52, -1,
- 197, -1, -1, -1, -1, 53, 54, 55, -1, 63,
- 248, -1, 66, -1, 68, 253, -1, 255, -1, -1,
- 258, 259, -1, -1, -1, 79, 17, 81, -1, 83,
- -1, 85, -1, -1, -1, 26, -1, 91, 29, 30,
- 31, -1, 280, 281, -1, -1, -1, 285, -1, -1,
- 288, -1, 43, -1, 45, -1, -1, 295, -1, -1,
- -1, 299, 53, 54, 55, -1, 304, -1, -1, -1,
- -1, 309, -1, -1, -1, -1, 314, -1, -1, -1,
- -1, 319, -1, 321, -1, -1, -1, 325, -1, -1,
- -1, -1, -1, -1, 332, -1, -1, 335, -1, -1,
- -1, -1, -1, -1, 344, 343, -1, -1, -1, -1,
- -1, 351, -1, 353, 354, 93, 94, 95, 96, 97,
- 98, 99, 100, 101, 102, 103, 104, 105, 106, -1,
- 370, -1, -1, -1, -1, 375, 93, 94, 95, 96,
- 97, 98, 99, 100, 101, -1, -1, -1, -1, -1,
- -1, -1, -1, 350, -1, -1, -1, -1, 355, 356,
+ 57, 558, 196, 192, 0, 346, 227, 374, 115, 201,
+ 0, 220, 131, 132, 223, 434, 242, 853, 434, 204,
+ 206, 208, 836, 528, 133, 955, 352, 411, 369, 592,
+ 821, 598, 656, 212, 678, 783, 0, 604, 821, 235,
+ 836, 824, 0, 697, 838, 379, 893, 841, 1135, 243,
+ 832, 156, 694, 158, 403, 836, 1057, 1075, 1062, 997,
+ 1064, 1065, 0, 4, 6, 7, 1297, 1298, 1299, 1300,
+ 12, 1302, 25, 1304, 49, 17, 163, 742, 19, 136,
+ 5, 138, 4, 140, 141, 365, 143, 28, 14, 6,
+ 15, 17, 149, 150, 1295, 152, 153, 154, 155, 156,
+ 157, 158, 159, 160, 195, 162, 6, 164, 6, 40,
+ 0, 220, 9, 88, 223, 56, 4, 17, 16, 60,
+ 17, 17, 5, 147, 35, 78, 1144, 184, 195, 186,
+ 187, 188, 15, 190, 201, 1366, 61, 62, 1369, 80,
+ 82, 38, 1373, 84, 1148, 1376, 720, 78, 722, 1380,
+ 724, 347, 726, 40, 728, 51, 952, 19, 80, 3,
+ 1361, 350, 84, 89, 821, 82, 28, 824, 56, 274,
+ 827, 952, 60, 65, 368, 86, 87, 9, 61, 993,
+ 1411, 25, 82, 974, 82, 1416, 378, 1034, 245, 163,
+ 247, 974, 80, 17, 977, 416, 84, 254, 90, 256,
+ 163, 397, 26, 260, 261, 1001, 38, 989, 404, 266,
+ 267, 268, 269, 539, 271, 163, 273, 274, 275, 603,
+ 1056, 1151, 418, 1224, 403, 1163, 1313, 284, 872, 1076,
+ 31, 55, 289, 290, 878, 292, 570, 201, 862, 893,
+ 198, 298, 866, 569, 807, 302, 303, 752, 890, 598,
+ 307, 308, 53, 54, 356, 312, 313, 159, 160, 67,
+ 540, 5, 927, 320, 929, 1112, 49, 324, 65, 836,
+ 327, 15, 552, 61, 71, 377, 470, 334, 35, 336,
+ 337, 338, 339, 340, 92, 342, 14, 513, 1079, 17,
+ 73, 24, 1222, 90, 22, 1131, 1079, 1080, 17, 56,
+ 409, 1097, 1096, 412, 7, 88, 39, 26, 11, 12,
+ 13, 14, 202, 7, 155, 48, 157, 974, 12, 209,
+ 977, 17, 979, 17, 898, 1073, 983, 23, 902, 86,
+ 87, 17, 906, 907, 908, 54, 7, 911, 912, 64,
+ 11, 915, 163, 816, 77, 818, 17, 543, 821, 386,
+ 17, 824, 389, 17, 827, 392, 697, 830, 22, 26,
+ 155, 89, 157, 1293, 50, 51, 69, 357, 30, 31,
+ 427, 428, 1155, 9, 364, 371, 41, 434, 435, 7,
+ 437, 17, 574, 11, 441, 442, 443, 1052, 445, 67,
+ 774, 53, 54, 589, 72, 580, 592, 583, 455, 586,
+ 457, 458, 150, 460, 600, 462, 463, 633, 465, 466,
+ 1224, 468, 469, 1161, 92, 150, 473, 474, 475, 598,
+ 1144, 478, 1079, 1080, 1081, 1082, 483, 484, 1152, 17,
+ 487, 488, 20, 759, 22, 851, 149, 494, 495, 1104,
+ 497, 498, 17, 500, 501, 7, 1298, 57, 1284, 790,
+ 12, 26, 1304, 510, 511, 512, 547, 548, 1206, 1207,
+ 517, 48, 519, 882, 521, 791, 523, 1041, 1042, 1043,
+ 1044, 619, 563, 564, 622, 765, 766, 767, 53, 54,
+ 547, 548, 7, 1212, 374, 1214, 11, 12, 13, 408,
+ 24, 610, 17, 16, 384, 414, 563, 564, 1155, 1156,
+ 1157, 697, 35, 793, 977, 17, 979, 574, 47, 546,
+ 983, 17, 549, 32, 551, 21, 22, 554, 555, 33,
+ 1185, 161, 162, 56, 25, 562, 156, 60, 1193, 1194,
+ 1097, 161, 162, 163, 147, 148, 573, 70, 151, 152,
+ 153, 62, 579, 45, 69, 582, 1120, 17, 585, 151,
+ 152, 153, 893, 86, 87, 612, 26, 74, 75, 596,
+ 30, 31, 619, 1220, 17, 622, 762, 624, 1146, 626,
+ 154, 155, 1150, 26, 1141, 58, 59, 1144, 31, 61,
+ 62, 1148, 155, 53, 54, 1152, 156, 644, 53, 54,
+ 32, 33, 649, 650, 651, 29, 653, 654, 655, 656,
+ 53, 54, 659, 795, 1305, 1306, 1012, 1013, 804, 1082,
+ 148, 807, 808, 151, 152, 153, 147, 1282, 675, 676,
+ 677, 678, 157, 680, 1289, 682, 120, 684, 122, 686,
+ 124, 8, 126, 54, 1001, 369, 832, 826, 847, 346,
+ 829, 1208, 695, 533, 894, 148, 703, 537, 151, 152,
+ 153, 154, 155, 156, 891, 158, 997, 1224, 715, 816,
+ 717, 817, 769, 720, 818, 722, 556, 724, 974, 726,
+ 527, 728, 925, 926, 731, 739, 740, 734, 1088, 786,
+ 1138, 1139, 739, 740, 1228, 742, 7, 1184, 1188, 746,
+ 11, 12, 13, 1034, 751, 571, 17, 893, 894, 20,
+ 1064, 22, 1148, 1300, 1306, 147, 148, 149, 598, 151,
+ 152, 153, 154, 155, 604, 1303, 0, 7, 608, 8,
+ 201, 11, 12, 13, 536, 624, 843, 17, 17, 129,
+ 1097, 21, 22, 129, 129, 1076, 129, 26, 129, 1295,
+ 29, 30, 31, 1299, 1300, 199, 1302, 1303, 69, 1305,
+ 1306, 199, 1308, 7, 958, 478, 129, 11, 12, 13,
+ 954, 955, 129, 17, 53, 54, 55, 570, 1216, 129,
+ 129, 1112, 968, 129, 995, 112, 398, 129, 768, 69,
+ 117, 771, 119, 195, 121, 195, 123, 597, 125, 129,
+ 597, 597, 597, 989, 851, 785, 853, 986, 788, 988,
+ 129, 129, 129, 129, 129, 862, 0, 731, 1034, 866,
+ 1366, 868, 334, 870, 871, 872, 0, 1373, 875, 815,
+ 10, 878, 1163, 339, 881, 882, 337, 1383, 18, 148,
+ 149, 1387, 151, 152, 153, 154, 155, 27, 1034, 158,
+ 1392, 898, 0, 900, 34, 902, 942, 37, 1097, 906,
+ 907, 908, -1, -1, 911, 912, 1413, 914, 915, -1,
+ 917, -1, 52, 920, -1, -1, -1, -1, 925, 926,
+ 927, -1, 929, 63, 931, 932, 66, 7, 68, 769,
+ 1076, 11, 12, 13, 941, 942, -1, 17, 361, 79,
+ -1, 81, 22, 83, -1, 85, 786, -1, 1087, 372,
+ 373, 91, 362, 363, -1, -1, 366, 367, 381, 148,
+ 149, -1, 151, 152, 153, 388, 1112, -1, 391, -1,
+ 380, 394, -1, -1, -1, -1, 816, 387, 818, 402,
+ 390, 821, -1, 393, 824, -1, -1, 827, -1, 69,
+ 830, 401, -1, 1000, -1, -1, 836, -1, 1005, 1006,
+ 1007, 1008, -1, -1, 844, 1012, 1013, 1151, -1, 148,
+ -1, -1, 151, 152, 153, 154, 155, -1, -1, 158,
+ 1159, 148, 149, 1030, 151, 152, 153, 154, 155, -1,
+ 1037, 1038, 1039, -1, 1041, 1042, 1043, 1044, -1, 1046,
+ -1, 1048, -1, -1, -1, 1052, -1, 1054, -1, 1056,
+ -1, -1, -1, 1060, -1, -1, -1, -1, 7, 8,
+ -1, -1, 11, 12, 13, 14, -1, -1, 17, -1,
+ -1, -1, -1, -1, -1, -1, -1, 26, 1222, -1,
+ 29, 30, 31, 93, 94, 95, 96, 97, 98, 99,
+ 100, 101, -1, 1100, -1, 1102, -1, 1104, 1105, -1,
+ -1, -1, 1109, 1110, 53, 54, 55, 1114, 1115, -1,
+ 1117, -1, 952, 1120, 17, 1122, -1, -1, -1, -1,
+ 69, 17, 962, 26, 1131, -1, 29, 30, 31, 1136,
+ 26, 1138, 1139, 29, 30, 31, -1, 977, -1, 979,
+ 89, -1, -1, 983, -1, -1, -1, 43, -1, 1293,
+ 53, 54, 55, 993, -1, -1, -1, 53, 54, 55,
+ -1, 7, -1, -1, -1, 11, 12, 13, 14, -1,
+ -1, 17, -1, 1180, -1, 1182, -1, 1184, 1185, 1186,
+ 26, 1188, 1189, 29, 30, 31, 1193, 1194, -1, 1196,
+ 36, -1, -1, 9, -1, -1, 1203, 1204, -1, -1,
+ -1, 17, -1, -1, -1, -1, -1, 53, 54, 55,
+ 26, -1, -1, 29, 30, 31, -1, 1363, -1, -1,
+ 1227, 1228, 38, 69, -1, -1, 42, 43, -1, 1368,
+ -1, -1, -1, -1, -1, -1, 1375, 53, 54, 55,
+ -1, -1, 1082, 89, -1, 147, 148, 149, -1, 151,
+ 152, 153, 154, 155, -1, -1, -1, 1097, -1, 1266,
+ 1267, 1268, 1269, 1270, -1, -1, 1273, 1274, 1275, 1276,
+ 1277, 9, -1, 1280, -1, 1282, -1, 1284, -1, 17,
+ -1, -1, 1289, -1, -1, -1, -1, -1, 26, -1,
+ -1, 29, 30, 31, -1, -1, -1, -1, -1, -1,
+ 38, 1141, -1, -1, 1144, 43, -1, -1, 1148, -1,
+ -1, -1, 1152, 1320, -1, 53, 54, 55, -1, -1,
+ 1327, -1, 1329, -1, -1, -1, -1, -1, 1335, -1,
+ 1337, -1, -1, -1, -1, 1342, -1, -1, 1345, -1,
+ -1, -1, -1, 1350, -1, -1, 45, -1, -1, -1,
+ -1, -1, -1, 52, 53, -1, 55, -1, -1, 58,
+ -1, 60, -1, 62, -1, -1, -1, 66, 1208, 68,
+ -1, 70, -1, 72, -1, 74, 1216, 76, -1, 78,
+ -1, 80, -1, -1, 1224, 1392, -1, -1, -1, 88,
+ 1397, 1398, -1, -1, 1401, -1, 95, -1, 97, -1,
+ 99, -1, 101, -1, 103, 7, 105, 17, -1, 11,
+ 12, 13, 14, -1, -1, 17, 26, -1, -1, 29,
+ 30, 31, -1, -1, 26, -1, -1, 29, 30, 31,
+ -1, -1, -1, 43, -1, 45, -1, -1, -1, -1,
+ -1, -1, -1, 53, 54, 55, -1, -1, 147, -1,
+ -1, 53, 54, 55, -1, 1295, -1, 1297, 1298, 1299,
+ 1300, -1, 1302, 1303, 1304, 1305, 1306, 69, 1308, 10,
+ -1, -1, -1, -1, 9, -1, 17, 18, -1, -1,
+ -1, -1, 17, -1, -1, 26, 27, 89, 29, 30,
+ 31, 26, 191, 34, 29, 30, 31, -1, -1, 10,
+ -1, -1, 203, 38, 205, 46, 207, 18, -1, 210,
+ -1, 52, 53, 54, 55, -1, 27, -1, 53, 54,
+ 55, -1, 63, 34, -1, 66, -1, 68, -1, -1,
+ -1, -1, -1, -1, -1, 46, -1, -1, 79, -1,
+ 81, 52, 83, -1, 85, -1, -1, -1, -1, 248,
+ 91, -1, 63, -1, 253, 66, 255, 68, -1, 258,
+ 259, -1, -1, -1, -1, -1, -1, -1, 79, -1,
+ 81, -1, 83, -1, 85, -1, -1, -1, -1, -1,
+ 91, 280, 281, -1, -1, -1, 285, -1, -1, 288,
+ -1, -1, -1, -1, 17, -1, 295, -1, -1, -1,
+ 299, -1, -1, 26, -1, 304, 29, 30, 31, -1,
+ 309, -1, -1, 36, -1, 314, -1, -1, -1, -1,
+ 319, -1, 321, -1, -1, -1, 325, -1, 4, 5,
+ 53, 54, 55, 332, 10, -1, 335, -1, -1, 15,
+ -1, 17, 18, 344, 343, -1, -1, -1, 24, -1,
+ 351, 27, 353, 354, -1, -1, -1, -1, 34, 35,
+ -1, 37, -1, 39, -1, -1, -1, -1, 44, 370,
+ 46, -1, -1, 49, 375, -1, 52, -1, -1, -1,
+ -1, -1, -1, -1, 60, -1, -1, 63, -1, 65,
+ 66, 67, 68, -1, -1, -1, -1, -1, -1, -1,
+ 76, 77, -1, 79, 80, 81, -1, 83, 84, 85,
+ 86, 87, 88, -1, 90, 91, 92, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 376,
- 377, -1, -1, -1, -1, -1, -1, -1, 385, -1,
- -1, 429, -1, 431, -1, -1, -1, -1, 436, -1,
- 397, -1, -1, 400, -1, -1, -1, -1, 446, -1,
- 407, -1, -1, -1, 454, 453, -1, -1, -1, 10,
- -1, -1, -1, 461, 464, -1, 17, 18, -1, -1,
- -1, 471, -1, -1, -1, 26, 27, -1, 29, 30,
- 31, 479, -1, 34, -1, -1, 486, 485, -1, -1,
- -1, -1, 492, 493, -1, 46, 496, -1, -1, 499,
- -1, 52, 53, 54, 55, -1, 506, -1, -1, 509,
- -1, -1, 63, -1, 514, 66, 516, 68, -1, -1,
- -1, -1, 520, -1, -1, 525, 524, -1, 79, -1,
- 81, -1, 83, -1, 85, -1, -1, -1, 538, -1,
- 91, -1, 542, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 557, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 568, -1,
- -1, -1, 529, 530, -1, -1, -1, -1, -1, -1,
+ 429, -1, 431, -1, -1, -1, -1, 436, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 446, -1, -1,
+ -1, -1, -1, 454, 453, -1, -1, -1, -1, -1,
+ -1, -1, 461, 464, -1, -1, -1, -1, -1, -1,
+ 471, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 479, -1, -1, -1, -1, 486, 485, -1, -1, -1,
+ -1, 492, 493, -1, -1, 496, -1, -1, 499, -1,
+ -1, -1, -1, -1, -1, 506, -1, -1, 509, -1,
+ -1, -1, -1, 514, -1, 516, -1, -1, -1, -1,
+ -1, 520, -1, -1, 525, 524, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 538, -1, -1,
+ -1, 542, 93, 94, 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 557, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 568, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 550, -1, -1, -1, -1, -1, 599,
- -1, -1, -1, -1, -1, 605, -1, -1, -1, 609,
- 567, -1, -1, -1, -1, 615, -1, 617, -1, -1,
- -1, 621, -1, -1, -1, -1, -1, 627, -1, -1,
- -1, -1, -1, 631, 634, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 606,
- -1, -1, -1, 610, -1, -1, -1, 657, -1, -1,
- 660, 661, 662, 663, -1, -1, -1, -1, -1, -1,
- 668, -1, -1, -1, 674, 673, -1, -1, -1, -1,
- -1, -1, -1, 683, -1, 685, -1, -1, 688, -1,
- 690, -1, 692, -1, -1, -1, -1, -1, 698, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 716, -1,
- 718, -1, -1, 721, -1, 723, -1, 725, -1, 727,
- -1, -1, 730, -1, -1, -1, -1, -1, -1, -1,
- 738, -1, -1, 741, -1, 743, -1, -1, -1, -1,
- 748, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 599, -1,
+ -1, -1, -1, -1, 605, -1, -1, -1, 609, -1,
+ -1, -1, -1, -1, 615, -1, 617, -1, -1, -1,
+ 621, -1, -1, -1, -1, -1, 627, -1, -1, -1,
+ -1, -1, 631, 634, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 770, -1, 772, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 787, -1, 789,
- -1, -1, -1, -1, -1, -1, 796, -1, 798, -1,
- 800, -1, 802, -1, 761, -1, 317, 318, -1, 320,
+ -1, -1, -1, -1, -1, -1, 657, -1, -1, 660,
+ 661, 662, 663, -1, -1, -1, -1, -1, -1, 668,
+ -1, -1, -1, 674, 673, -1, -1, -1, -1, -1,
+ -1, -1, 683, -1, 685, -1, -1, 688, -1, 690,
+ -1, 692, -1, -1, -1, -1, -1, 698, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 781, -1, 783, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 837, -1, -1,
- -1, -1, -1, -1, -1, 845, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 716, -1, 718,
+ -1, -1, 721, -1, 723, -1, 725, -1, 727, -1,
+ -1, 730, -1, -1, -1, -1, -1, -1, -1, 738,
+ -1, -1, 741, -1, 743, -1, -1, -1, -1, 748,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 820, -1, -1, 823, -1, -1, -1,
- -1, -1, -1, -1, -1, 832, -1, -1, -1, -1,
- -1, 838, -1, -1, 841, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 770,
+ -1, 772, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 787, -1, 789, -1,
+ -1, -1, -1, -1, -1, 796, -1, 798, -1, 800,
+ -1, 802, -1, -1, -1, -1, -1, 109, 110, 111,
+ 112, 113, -1, -1, 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, -1, 130, 131,
+ 132, -1, -1, -1, -1, -1, 837, -1, -1, -1,
+ -1, -1, -1, -1, 845, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 905, -1, -1, -1, -1,
- 910, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 922, -1, -1, -1, -1, -1, -1, -1,
- 928, -1, -1, 933, -1, -1, -1, -1, -1, -1,
- 940, -1, -1, 943, 944, 945, 946, 947, 948, -1,
- -1, 951, -1, 953, -1, -1, 956, -1, 469, -1,
- -1, 961, -1, 963, 964, 965, 477, -1, -1, -1,
- -1, 482, 972, -1, -1, -1, -1, -1, 489, 490,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 108,
- 109, 110, 111, 112, 113, 114, 507, 116, 117, 118,
- 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
- 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
- 139, -1, -1, 142, 143, 144, 145, 146, 1026, -1,
- -1, -1, 989, -1, -1, 1035, -1, -1, -1, -1,
- -1, 998, -1, -1, -1, -1, -1, -1, -1, -1,
- 1050, -1, 1052, -1, -1, -1, -1, -1, -1, 1057,
- -1, -1, -1, -1, -1, -1, -1, -1, 1068, 1069,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 1087, -1, -1,
- -1, -1, 1092, -1, -1, 1093, 1096, -1, -1, -1,
- -1, 1099, -1, 1101, -1, -1, 1104, -1, -1, -1,
- -1, -1, -1, -1, 1071, -1, -1, -1, -1, -1,
+ -1, 317, 318, -1, 320, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 1131, -1, -1, -1, 1094, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 666, 667, -1, 1158, -1,
- 1160, 672, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 687, 1175, 689, 1177,
- 691, -1, 693, -1, 1141, -1, -1, 1144, -1, -1,
- -1, 1148, -1, -1, -1, 1193, -1, -1, -1, 1199,
- -1, -1, 1159, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 1213, -1, -1, -1, -1, -1, -1,
- -1, 1221, -1, 1223, 1224, -1, -1, -1, -1, -1,
+ 192, -1, -1, -1, -1, 197, -1, -1, -1, -1,
+ -1, -1, -1, -1, 905, -1, -1, -1, -1, 910,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 1204, 1205, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 1217, -1, -1, -1, -1, -1, -1, -1, -1, 1269,
- -1, -1, -1, -1, -1, -1, 1276, -1, -1, -1,
+ -1, 922, -1, -1, -1, -1, -1, -1, -1, 928,
+ -1, -1, 933, -1, -1, -1, -1, -1, -1, 940,
+ -1, -1, 943, 944, 945, 946, 947, 948, -1, -1,
+ 951, -1, 953, -1, -1, 956, -1, -1, -1, -1,
+ 961, -1, 963, 964, 965, -1, -1, -1, -1, -1,
+ -1, 972, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, -1, 469, -1, -1, -1, -1, -1, -1,
+ -1, 477, -1, -1, -1, -1, 482, -1, 1027, -1,
+ -1, -1, -1, 489, 490, 1036, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 350, -1,
+ 1051, 507, 1053, 355, 356, -1, -1, -1, -1, 1058,
+ -1, -1, -1, -1, -1, -1, -1, -1, 1069, 1070,
+ -1, -1, -1, -1, 376, 377, -1, -1, -1, -1,
+ -1, -1, -1, 385, -1, -1, -1, -1, 1089, -1,
+ -1, -1, -1, 1094, -1, 397, 1095, 1098, 400, -1,
+ -1, -1, 1101, -1, 1103, 407, -1, 1106, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 1288, -1, 1292, -1, 1294, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 1308, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 1319, -1, -1, -1, -1, -1, -1, 1326, -1,
- -1, -1, -1, -1, -1, -1, 1334, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 858, 859, 860,
- 861, -1, 863, 864, -1, 1355, 1356, 4, 5, -1,
- -1, -1, 873, 10, 875, 876, -1, -1, 15, -1,
- 17, 18, 883, 884, -1, -1, -1, 24, -1, -1,
- 27, -1, -1, -1, -1, 896, -1, 34, 35, -1,
- 37, -1, 39, 1393, -1, -1, -1, 44, -1, 46,
- 1400, -1, 49, -1, -1, 52, -1, -1, -1, -1,
- -1, -1, -1, 60, -1, -1, 63, -1, 65, 66,
- 67, 68, 1422, -1, -1, -1, -1, -1, -1, 76,
- 77, -1, 79, 80, 81, -1, 83, 84, 85, 86,
- 87, 88, -1, 90, 91, 92, 107, 108, 109, 110,
- 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
- 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
- 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
- 141, 142, 143, 144, 145, 146, -1, -1, -1, -1,
+ -1, -1, -1, -1, 1133, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 1011, -1, -1, -1, -1, 1016, 1017, -1, 1019, -1,
- -1, -1, -1, -1, -1, -1, 1027, 107, 108, 109,
- 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
- 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
- 140, 141, 142, 143, 144, 145, 146, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 1160,
+ -1, 1162, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 1177, -1,
+ 1179, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 1195, -1, -1, -1,
+ 1201, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 666, 667, -1, -1, 1215, -1, 672, -1, -1, -1,
+ -1, -1, 1223, -1, 1225, 1226, -1, 529, 530, -1,
+ -1, 687, -1, 689, -1, 691, -1, 693, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 550, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 567, -1, -1, -1, -1,
+ 1271, -1, -1, -1, -1, -1, -1, 1278, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1290, -1, 1294, -1, 1296, -1, -1, -1, -1,
+ -1, -1, -1, -1, 606, -1, -1, -1, 610, 1310,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 1321, -1, -1, -1, -1, -1, -1, 1328,
+ -1, -1, -1, -1, -1, -1, -1, 1336, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 1357, 1358, -1, -1,
+ -1, 108, 109, 110, 111, 112, 113, 114, -1, 116,
+ 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
+ 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
+ 137, 138, 139, -1, 1395, 142, 143, 144, 145, 146,
+ -1, 1402, 858, 859, 860, 861, -1, 863, 864, -1,
+ -1, -1, -1, -1, -1, -1, -1, 873, -1, 875,
+ 876, -1, -1, 1424, -1, -1, -1, 883, 884, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 896, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 761,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 781,
+ -1, 783, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 820, -1,
+ -1, 823, -1, -1, -1, -1, -1, -1, -1, -1,
+ 832, -1, -1, -1, -1, -1, 838, -1, -1, 841,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1011, -1, -1, -1, -1,
+ 1016, 1017, -1, 1019, -1, -1, -1, -1, -1, 1025,
+ -1, -1, 1028, 107, 108, 109, 110, 111, 112, 113,
+ 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,
+ 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 1188, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 1203, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 989, -1, -1,
+ -1, -1, -1, -1, -1, -1, 998, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 1190, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 1205,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 1284, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1073, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 1312, -1, -1, 1315, 1316, -1, 1318, -1, -1,
- -1, 1322, 1323, -1, 1325, -1, 1327, -1, -1, 1330,
- 1331, -1, 1333, -1, 1335, -1, 1337, 1338, -1, 1340,
- 1341, -1, 1343, 1344, -1, 1346, -1, 1348, 1349, -1,
- 1351, -1, 1353, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 1096, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 1392, -1, 1394, 1395, -1, 1397, 1398, 1399, -1,
- 1401, 1402, 1403, 1404, -1, -1, -1, -1, -1, -1,
+ 1286, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1143, -1, -1, 1146, -1, -1, -1, 1150, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 1314, 1161,
+ -1, 1317, 1318, -1, 1320, -1, -1, -1, 1324, 1325,
+ -1, 1327, -1, 1329, -1, -1, 1332, 1333, -1, 1335,
+ -1, 1337, -1, 1339, 1340, -1, 1342, 1343, -1, 1345,
+ 1346, -1, 1348, -1, 1350, 1351, -1, 1353, -1, 1355,
+ -1, -1, -1, -1, 1206, 1207, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 1219, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 1421, -1, 1423
+ -1, -1, -1, -1, -1, -1, -1, -1, 1394, -1,
+ 1396, 1397, -1, 1399, 1400, 1401, -1, 1403, 1404, 1405,
+ 1406, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 1423, -1, 1425
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -2064,47 +2080,47 @@ static const yytype_uint16 yystos[] =
203, 482, 482, 204, 207, 202, 207, 204, 204, 203,
203, 204, 204, 512, 203, 203, 203, 203, 203, 203,
203, 238, 425, 429, 203, 172, 267, 267, 203, 373,
- 203, 7, 11, 12, 13, 256, 257, 386, 203, 203,
- 203, 180, 195, 196, 203, 218, 220, 223, 229, 234,
- 229, 234, 234, 234, 169, 226, 169, 233, 184, 205,
- 237, 494, 167, 385, 205, 431, 204, 383, 429, 513,
- 516, 204, 204, 204, 204, 259, 419, 419, 259, 259,
- 259, 202, 259, 204, 168, 198, 203, 204, 204, 204,
- 204, 209, 209, 209, 209, 204, 204, 230, 203, 207,
- 203, 204, 330, 507, 202, 204, 514, 8, 282, 284,
- 281, 284, 282, 283, 284, 203, 203, 266, 281, 180,
- 197, 198, 223, 229, 234, 229, 234, 234, 234, 169,
- 227, 260, 203, 7, 11, 12, 13, 14, 69, 426,
- 427, 428, 203, 202, 384, 208, 429, 516, 203, 204,
- 272, 202, 204, 270, 202, 207, 204, 275, 202, 204,
- 204, 392, 198, 204, 204, 204, 209, 204, 330, 202,
- 504, 204, 514, 514, 7, 11, 12, 13, 14, 69,
- 89, 208, 252, 253, 254, 255, 261, 265, 305, 205,
- 285, 208, 281, 305, 285, 208, 283, 285, 267, 36,
- 208, 305, 393, 394, 229, 234, 234, 234, 169, 228,
- 203, 266, 203, 385, 202, 202, 204, 204, 270, 207,
- 204, 275, 204, 259, 204, 207, 207, 202, 204, 203,
- 204, 262, 204, 505, 259, 266, 266, 208, 108, 109,
- 110, 111, 112, 113, 114, 116, 117, 118, 119, 120,
- 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
- 131, 132, 133, 134, 135, 136, 137, 138, 139, 142,
- 143, 144, 145, 146, 298, 107, 115, 140, 141, 286,
- 289, 298, 107, 115, 140, 141, 291, 294, 298, 203,
- 393, 205, 395, 234, 267, 203, 208, 494, 507, 203,
- 203, 204, 262, 204, 296, 204, 204, 204, 204, 203,
- 204, 204, 204, 204, 204, 203, 204, 207, 330, 259,
- 207, 202, 267, 203, 22, 238, 261, 297, 303, 304,
- 203, 20, 238, 253, 287, 299, 300, 303, 287, 21,
- 238, 253, 288, 301, 302, 303, 288, 238, 253, 290,
- 303, 238, 292, 299, 303, 287, 238, 293, 301, 303,
- 293, 238, 295, 303, 203, 504, 259, 259, 259, 204,
- 259, 202, 259, 259, 204, 259, 202, 204, 259, 259,
- 259, 204, 259, 202, 204, 259, 259, 259, 204, 259,
- 259, 204, 259, 259, 259, 204, 259, 259, 259, 259,
- 203, 203, 261, 180, 253, 303, 169, 253, 253, 303,
- 169, 253, 253, 303, 303, 505, 259, 203, 259, 204,
- 259, 204, 259, 259, 204, 259, 203, 259, 259, 259,
- 259, 253, 258, 253, 259, 203, 259
+ 203, 7, 11, 12, 13, 238, 256, 257, 386, 203,
+ 203, 203, 180, 195, 196, 203, 218, 220, 223, 229,
+ 234, 229, 234, 234, 234, 169, 226, 169, 233, 184,
+ 205, 237, 494, 167, 385, 205, 431, 204, 383, 429,
+ 513, 516, 204, 204, 204, 204, 259, 419, 419, 259,
+ 259, 259, 259, 202, 259, 204, 168, 198, 203, 204,
+ 204, 204, 204, 209, 209, 209, 209, 204, 204, 230,
+ 203, 207, 203, 204, 330, 507, 202, 204, 514, 8,
+ 282, 284, 281, 284, 282, 283, 284, 203, 203, 266,
+ 281, 180, 197, 198, 223, 229, 234, 229, 234, 234,
+ 234, 169, 227, 260, 203, 7, 11, 12, 13, 14,
+ 69, 426, 427, 428, 203, 202, 384, 208, 429, 516,
+ 203, 204, 272, 202, 204, 270, 202, 207, 204, 275,
+ 202, 204, 204, 392, 198, 204, 204, 204, 209, 204,
+ 330, 202, 504, 204, 514, 514, 7, 11, 12, 13,
+ 14, 69, 89, 208, 252, 253, 254, 255, 261, 265,
+ 305, 205, 285, 208, 281, 305, 285, 208, 283, 285,
+ 267, 36, 208, 305, 393, 394, 229, 234, 234, 234,
+ 169, 228, 203, 266, 203, 385, 202, 202, 204, 204,
+ 270, 207, 204, 275, 204, 259, 204, 207, 207, 202,
+ 204, 203, 204, 262, 204, 505, 259, 266, 266, 208,
+ 108, 109, 110, 111, 112, 113, 114, 116, 117, 118,
+ 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
+ 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
+ 139, 142, 143, 144, 145, 146, 298, 107, 115, 140,
+ 141, 286, 289, 298, 107, 115, 140, 141, 291, 294,
+ 298, 203, 393, 205, 395, 234, 267, 203, 208, 494,
+ 507, 203, 203, 204, 262, 204, 296, 204, 204, 204,
+ 204, 203, 204, 204, 204, 204, 204, 203, 204, 207,
+ 330, 259, 207, 202, 267, 203, 22, 238, 261, 297,
+ 303, 304, 203, 20, 238, 253, 287, 299, 300, 303,
+ 287, 21, 238, 253, 288, 301, 302, 303, 288, 238,
+ 253, 290, 303, 238, 292, 299, 303, 287, 238, 293,
+ 301, 303, 293, 238, 295, 303, 203, 504, 259, 259,
+ 259, 204, 259, 202, 259, 259, 204, 259, 202, 204,
+ 259, 259, 259, 204, 259, 202, 204, 259, 259, 259,
+ 204, 259, 259, 204, 259, 259, 259, 204, 259, 259,
+ 259, 259, 203, 203, 261, 180, 253, 303, 169, 253,
+ 253, 303, 169, 253, 253, 303, 303, 505, 259, 203,
+ 259, 204, 259, 204, 259, 259, 204, 259, 203, 259,
+ 259, 259, 259, 253, 258, 253, 259, 203, 259
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
@@ -2156,30 +2172,30 @@ static const yytype_uint16 yyr1[] =
362, 363, 363, 364, 364, 364, 364, 365, 366, 366,
366, 366, 366, 367, 368, 369, 370, 371, 372, 373,
374, 375, 375, 375, 376, 377, 378, 379, 379, 380,
- 381, 382, 382, 383, 384, 385, 386, 387, 387, 388,
- 389, 390, 390, 391, 392, 392, 392, 392, 392, 393,
- 394, 395, 396, 396, 397, 398, 398, 398, 399, 400,
- 400, 401, 402, 402, 403, 404, 405, 406, 406, 407,
- 408, 409, 410, 410, 410, 410, 410, 411, 411, 412,
- 413, 414, 414, 415, 416, 417, 418, 419, 419, 419,
- 419, 420, 421, 422, 423, 424, 425, 426, 427, 428,
- 428, 428, 428, 428, 428, 429, 430, 431, 432, 432,
- 432, 433, 433, 434, 435, 435, 436, 437, 437, 438,
- 439, 440, 441, 441, 441, 442, 443, 444, 445, 446,
- 447, 448, 449, 450, 450, 450, 450, 451, 452, 452,
- 453, 454, 455, 456, 457, 458, 459, 460, 461, 462,
- 463, 464, 465, 466, 466, 466, 466, 466, 466, 466,
- 466, 466, 466, 466, 466, 467, 467, 468, 468, 468,
- 469, 470, 471, 472, 472, 473, 473, 473, 474, 475,
- 475, 476, 477, 477, 477, 477, 477, 477, 477, 477,
- 477, 477, 477, 477, 477, 477, 478, 478, 478, 478,
- 478, 478, 478, 479, 480, 480, 481, 482, 482, 482,
- 482, 482, 482, 482, 483, 484, 485, 486, 487, 488,
- 489, 490, 491, 492, 493, 494, 495, 496, 497, 497,
- 498, 499, 499, 499, 499, 499, 500, 501, 502, 502,
- 503, 504, 504, 504, 504, 505, 505, 505, 505, 506,
- 507, 508, 509, 510, 511, 511, 512, 513, 513, 514,
- 514, 514, 514, 515, 516
+ 381, 382, 382, 382, 383, 384, 385, 386, 387, 387,
+ 388, 389, 390, 390, 391, 392, 392, 392, 392, 392,
+ 393, 394, 395, 396, 396, 397, 398, 398, 398, 399,
+ 400, 400, 401, 402, 402, 403, 404, 405, 406, 406,
+ 407, 408, 409, 410, 410, 410, 410, 410, 411, 411,
+ 412, 413, 414, 414, 415, 416, 417, 418, 419, 419,
+ 419, 419, 420, 421, 422, 423, 424, 425, 426, 427,
+ 428, 428, 428, 428, 428, 428, 429, 430, 431, 432,
+ 432, 432, 433, 433, 434, 435, 435, 436, 437, 437,
+ 438, 439, 440, 441, 441, 441, 442, 443, 444, 445,
+ 446, 447, 448, 449, 450, 450, 450, 450, 451, 452,
+ 452, 453, 454, 455, 456, 457, 458, 459, 460, 461,
+ 462, 463, 464, 465, 466, 466, 466, 466, 466, 466,
+ 466, 466, 466, 466, 466, 466, 467, 467, 468, 468,
+ 468, 469, 470, 471, 472, 472, 473, 473, 473, 474,
+ 475, 475, 476, 477, 477, 477, 477, 477, 477, 477,
+ 477, 477, 477, 477, 477, 477, 477, 478, 478, 478,
+ 478, 478, 478, 478, 479, 480, 480, 481, 482, 482,
+ 482, 482, 482, 482, 482, 483, 484, 485, 486, 487,
+ 488, 489, 490, 491, 492, 493, 494, 495, 496, 497,
+ 497, 498, 499, 499, 499, 499, 499, 500, 501, 502,
+ 502, 503, 504, 504, 504, 504, 505, 505, 505, 505,
+ 506, 507, 508, 509, 510, 511, 511, 512, 513, 513,
+ 514, 514, 514, 514, 515, 516
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
@@ -2231,30 +2247,30 @@ static const yytype_uint8 yyr2[] =
10, 1, 1, 1, 1, 1, 1, 7, 0, 3,
5, 3, 3, 9, 7, 9, 1, 1, 1, 1,
7, 0, 3, 3, 1, 1, 5, 1, 1, 1,
- 7, 0, 3, 1, 1, 1, 1, 1, 1, 8,
- 10, 1, 1, 10, 0, 3, 5, 3, 2, 5,
- 1, 1, 1, 1, 5, 1, 1, 1, 8, 1,
- 1, 5, 1, 1, 8, 1, 5, 1, 1, 8,
- 1, 5, 0, 3, 5, 3, 3, 1, 1, 4,
- 1, 1, 1, 4, 1, 1, 7, 0, 3, 3,
- 3, 1, 1, 5, 1, 1, 9, 1, 5, 1,
- 1, 1, 1, 1, 1, 7, 1, 1, 1, 1,
- 1, 1, 1, 10, 1, 1, 10, 1, 1, 10,
- 10, 7, 0, 3, 3, 9, 7, 9, 10, 1,
- 1, 9, 1, 1, 1, 1, 1, 10, 1, 1,
- 7, 9, 1, 10, 7, 1, 10, 7, 1, 10,
- 7, 1, 9, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 0, 3, 2,
- 1, 1, 4, 1, 1, 1, 2, 3, 4, 1,
- 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 7, 0, 3, 3, 1, 1, 1, 1, 1, 1,
+ 8, 10, 1, 1, 10, 0, 3, 5, 3, 2,
+ 5, 1, 1, 1, 1, 5, 1, 1, 1, 8,
+ 1, 1, 5, 1, 1, 8, 1, 5, 1, 1,
+ 8, 1, 5, 0, 3, 5, 3, 3, 1, 1,
+ 4, 1, 1, 1, 4, 1, 1, 7, 0, 3,
+ 3, 3, 1, 1, 5, 1, 1, 9, 1, 5,
+ 1, 1, 1, 1, 1, 1, 7, 1, 1, 1,
+ 1, 1, 1, 1, 10, 1, 1, 10, 1, 1,
+ 10, 10, 7, 0, 3, 3, 9, 7, 9, 10,
+ 1, 1, 9, 1, 1, 1, 1, 1, 10, 1,
+ 1, 7, 9, 1, 10, 7, 1, 10, 7, 1,
+ 10, 7, 1, 9, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 3,
+ 2, 1, 1, 4, 1, 1, 1, 2, 3, 4,
+ 1, 3, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 4, 3, 1, 8, 0, 3, 3,
- 3, 5, 3, 2, 1, 1, 4, 1, 1, 4,
- 1, 4, 1, 4, 1, 4, 1, 4, 3, 1,
- 6, 0, 3, 3, 3, 2, 1, 4, 3, 1,
- 16, 1, 1, 1, 1, 0, 6, 3, 2, 1,
- 1, 9, 1, 4, 3, 1, 6, 1, 1, 0,
- 3, 3, 2, 1, 7
+ 1, 1, 1, 1, 4, 3, 1, 8, 0, 3,
+ 3, 3, 5, 3, 2, 1, 1, 4, 1, 1,
+ 4, 1, 4, 1, 4, 1, 4, 1, 4, 3,
+ 1, 6, 0, 3, 3, 3, 2, 1, 4, 3,
+ 1, 16, 1, 1, 1, 1, 0, 6, 3, 2,
+ 1, 1, 9, 1, 4, 3, 1, 6, 1, 1,
+ 0, 3, 3, 2, 1, 7
};
diff --git a/src/wkt2_grammar.y b/src/wkt2_grammar.y
index 4f30b5b2..fc2e8bf0 100644
--- a/src/wkt2_grammar.y
+++ b/src/wkt2_grammar.y
@@ -1073,6 +1073,7 @@ map_projection_parameter: parameter_keyword left_delimiter parameter_name
right_delimiter
opt_separator_param_unit_identifier_list:
+ | wkt_separator identifier opt_separator_identifier_list
| wkt_separator map_projection_parameter_unit opt_separator_identifier_list
parameter_keyword: T_PARAMETER