Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tmerc/utm: add a +algo=auto/evenden_snyder/poder_engsager parameter #2030

Merged
merged 1 commit into from
Apr 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 (and UTM) 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_algo = 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:: +algo=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:`+algo` are mutually exclusive.

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

.. include:: ../options/lat_0.rst
Expand Down
15 changes: 15 additions & 0 deletions docs/source/operations/projections/utm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,21 @@ Optional

Use faster, less accurate algorithm for the Transverse Mercator.

.. option:: +algo=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:`+algo` are mutually exclusive.

.. include:: ../options/ellps.rst

Further reading
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 (and UTM) 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_algo = 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_algo") {
if (value == "auto") {
ctx->defaultTmercAlgo = TMercAlgo::AUTO;
} else if (value == "evenden_snyder") {
ctx->defaultTmercAlgo = TMercAlgo::EVENDEN_SNYDER;
} else if (value == "poder_engsager") {
ctx->defaultTmercAlgo = TMercAlgo::PODER_ENGSAGER;
} else {
pj_log(
ctx, PJ_LOG_ERROR,
"pj_load_ini(): Invalid value for tmerc_default_algo");
}
}
}

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 TMercAlgo
{
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()

TMercAlgo defaultTmercAlgo = TMercAlgo::PODER_ENGSAGER; // can be overriden by content of proj.ini

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