Skip to content

Commit

Permalink
tmerc: add a +alg=auto/evenden_snyder/poder_engsager parameter
Browse files Browse the repository at this point in the history
The default remains +alg=poder_engsager.
This default value can be changed in proj.ini

+alg=auto will use Evenden Synder implementation if the error in
doing so remains below 0.1 mm on Earth-sized ellipsoid
  • Loading branch information
rouault committed Apr 14, 2020
1 parent 5b017a8 commit 0cf0960
Show file tree
Hide file tree
Showing 7 changed files with 316 additions and 63 deletions.
8 changes: 8 additions & 0 deletions data/proj.ini
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@ cache_enabled = on
cache_size_MB = 300

cache_ttl_sec = 86400

; Transverse Mercator default algorithm: auto, evenden_snyder or poder_engsager
; * evenden_snyder is the fastest, but less accurate far from central meridian
; * poder_engsager is slower, but more accurate far from central meridian
; * default will auto-select between the two above depending on the coordinate
; to transform and will use evenden_snyder if the error in doing so is below
; 0.1 mm (for an ellipsoid of the size of Earth)
tmerc_default_alg = poder_engsager
15 changes: 15 additions & 0 deletions docs/source/operations/projections/tmerc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,21 @@ Parameters
It is faster than the default algorithm, but also diverges faster
as the distance from the central meridian increases.

.. option:: +alg=auto/evenden_snyder/poder_engsager

.. versionadded:: 7.1

Selects the algorithm to use. The hardcoded value and the one defined in
:ref:`proj-ini` default to ``poder_engsager``, that is the most precise
one.

When using auto, a heuristics based on the input coordinate to transform
is used to determine if the faster Evenden-Snyder method can be used, for
faster computation, without causing an error greater than 0.1 mm (for an
ellipsoid of the size of Earth)

Note that :option:`+approx` and :option:`+alg` are mutually exclusive.

.. include:: ../options/lon_0.rst

.. include:: ../options/lat_0.rst
Expand Down
8 changes: 8 additions & 0 deletions docs/source/resource_files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ Its default content is:

cache_ttl_sec = 86400

; Transverse Mercator default algorithm: auto, evenden_snyder or poder_engsager
; * evenden_snyder is the fastest, but less accurate far from central meridian
; * poder_engsager is slower, but more accurate far from central meridian
; * default will auto-select between the two above depending on the coordinate
; to transform and will use evenden_snyder if the error in doing so is below
; 0.1 mm (for an ellipsoid of the size of Earth)
tmerc_default_alg = poder_engsager


Transformation grids
-------------------------------------------------------------------------------
Expand Down
12 changes: 12 additions & 0 deletions src/filemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1848,6 +1848,18 @@ void pj_load_ini(projCtx ctx) {
val > 0 ? static_cast<long long>(val) * 1024 * 1024 : -1;
} else if (key == "cache_ttl_sec") {
ctx->gridChunkCache.ttl = atoi(value.c_str());
} else if (key == "tmerc_default_alg") {
if (value == "auto") {
ctx->defaultTmercAlg = TMercAlg::AUTO;
} else if (value == "evenden_snyder") {
ctx->defaultTmercAlg = TMercAlg::EVENDEN_SNYDER;
} else if (value == "poder_engsager") {
ctx->defaultTmercAlg = TMercAlg::PODER_ENGSAGER;
} else {
pj_log(
ctx, PJ_LOG_ERROR,
"pj_load_ini(): Invalid value for tmerc_default_alg");
}
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/proj_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,13 @@ struct CoordOperation
}
};

enum class TMercAlg
{
AUTO, // Poder/Engsager if far from central meridian, otherwise Evenden/Snyder
EVENDEN_SNYDER,
PODER_ENGSAGER,
};

/* base projection data structure */
struct PJconsts {

Expand Down Expand Up @@ -741,6 +748,8 @@ struct projCtx_t {

int projStringParserCreateFromPROJStringRecursionCounter = 0; // to avoid potential infinite recursion in PROJStringParser::createFromPROJString()

TMercAlg defaultTmercAlg = TMercAlg::PODER_ENGSAGER; // can be overriden by content of proj.ini

projCtx_t() = default;
projCtx_t(const projCtx_t&);
~projCtx_t();
Expand Down
Loading

0 comments on commit 0cf0960

Please sign in to comment.