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

Add +proj=mod_krovak projection method for Modified Krovak that applies to S-JTSK/05 in the Czech Republic #4021

Merged
merged 1 commit into from
Feb 2, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/source/operations/projections/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Projections map the spherical 3D space to a flat 2D space.
mil_os
mill
misrsom
mod_krovak
moll
murd1
murd2
Expand Down
18 changes: 15 additions & 3 deletions docs/source/operations/projections/krovak.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ Krovak
********************************************************************************

+---------------------+----------------------------------------------------------+
| **Classification** | Conical |
| **Classification** | Conformal Conical |
+---------------------+----------------------------------------------------------+
| **Available forms** | Forward and inverse, spherical and ellipsoidal |
+---------------------+----------------------------------------------------------+
| **Defined area** | Global, but more accurate around Czechoslovakia |
| **Defined area** | Global, but more accurate around Czech Republic and |
| | Slovakia |
+---------------------+----------------------------------------------------------+
| **Alias** | krovak |
+---------------------+----------------------------------------------------------+
Expand All @@ -28,6 +29,16 @@ Krovak

proj-string: ``+proj=krovak``

By default, coordinates in the forward direction are output in easting, northing,
and negative in the Czech Republic and Slovakia, with absolute value of
easting/westing being smaller than absolute value of northing/southing.

See also :ref:`mod_krovak` for a variation of Krovak used with the S-JTSK/05 datum
in the Czech Republic.

.. note:: Before PROJ 9.4, using other values for x_0 or y_0 than the default 0
would lead to incorrect results when not using the ``+czech`` switch.

Parameters
################################################################################

Expand All @@ -39,7 +50,8 @@ Parameters
.. option:: +czech

Reverse the sign of the output coordinates, as is tradition in the
Czech Republic.
Czech Republic, to be westing, southing (positive values in Czech Republic
and Slovakia).

.. option:: +lon_0=<value>

Expand Down
77 changes: 77 additions & 0 deletions docs/source/operations/projections/mod_krovak.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
.. _mod_krovak:

********************************************************************************
Modified Krovak
********************************************************************************

.. versionadded:: 9.4.0

+---------------------+----------------------------------------------------------+
| **Classification** | Conical |
+---------------------+----------------------------------------------------------+
| **Available forms** | Forward and inverse, spherical and ellipsoidal |
+---------------------+----------------------------------------------------------+
| **Defined area** | Czech Republic |
+---------------------+----------------------------------------------------------+
| **Alias** | mod_krovak |
+---------------------+----------------------------------------------------------+
| **Domain** | 2D |
+---------------------+----------------------------------------------------------+
| **Input type** | Geodetic coordinates |
+---------------------+----------------------------------------------------------+
| **Output type** | Projected coordinates |
+---------------------+----------------------------------------------------------+


.. figure:: ./images/krovak.png
:width: 500 px
:align: center
:alt: Modified Krovak

proj-string: ``+proj=mod_krovak``

Modified Krovak builts upon traditional :ref:`krovak`, with corrective terms that
are better suited when using it with the S-JTSK/05 datum. This method is specific
to the Czech Republic. Due to the corrective terms, this projection method is
no longer strictly conformal.

By default, coordinates in the forward direction are output in easting, northing,
and negative in the Czech Republic, with absolute value of easting/westing
being smaller than absolute value of northing/southing.
To distinguish it from regular Krovak, the usual value for ``+x_0`` and ``+y_0``
in Modified Krovak is typically 5,000,000.

Parameters
################################################################################

.. note:: All parameters are optional for the Modified Krovak projection.

The latitude of pseudo standard parallel is hardcoded to 78.5° and
the ellipsoid to Bessel.

.. option:: +czech

Reverse the sign of the output coordinates, as is tradition in the
Czech Republic, to be westing, southing (positive values in Czech Republic)

.. option:: +lon_0=<value>

Longitude of projection center.

*Defaults to 24°50' (24.8333333333333)*

.. option:: +lat_0=<value>

Latitude of projection center.

*Defaults to 49.5*

.. option:: +k_0=<value>

Scale factor. Determines scale factor used in the projection.

*Defaults to 0.9999*

.. include:: ../options/x_0.rst

.. include:: ../options/y_0.rst
20 changes: 16 additions & 4 deletions src/iso19111/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10635,7 +10635,7 @@ PROJStringParser::Private::buildDatum(Step &step, const std::string &title) {
!fStr.empty() || !esStr.empty() || !eStr.empty();

if (!numericParamPresent && ellpsStr.empty() && datumStr.empty() &&
step.name == "krovak") {
(step.name == "krovak" || step.name == "mod_krovak")) {
ellpsStr = "bessel";
}

Expand Down Expand Up @@ -11059,7 +11059,8 @@ PROJStringParser::Private::processAxisSwap(Step &step,
throw ParsingException("Unhandled order=" + orderStr);
}
}
} else if (step.name == "krovak" && hasParamValue(step, "czech")) {
} else if ((step.name == "krovak" || step.name == "mod_krovak") &&
hasParamValue(step, "czech")) {
axis[0] = west;
axis[1] = south;
}
Expand Down Expand Up @@ -11519,6 +11520,16 @@ PROJStringParser::Private::buildProjectedCRS(int iStep,
} else if (step.name == "krovak" && iAxisSwap < 0 &&
hasParamValue(step, "czech") && !hasParamValue(step, "axis")) {
mapping = getMapping(EPSG_CODE_METHOD_KROVAK);
} else if (step.name == "mod_krovak" &&
((iAxisSwap < 0 && getParamValue(step, "axis") == "swu" &&
!hasParamValue(step, "czech")) ||
(iAxisSwap > 0 &&
getParamValue(steps_[iAxisSwap], "order") == "-2,-1" &&
!hasParamValue(step, "czech")))) {
mapping = getMapping(EPSG_CODE_METHOD_KROVAK_MODIFIED);
} else if (step.name == "mod_krovak" && iAxisSwap < 0 &&
hasParamValue(step, "czech") && !hasParamValue(step, "axis")) {
mapping = getMapping(EPSG_CODE_METHOD_KROVAK_MODIFIED);
} else if (step.name == "merc") {
if (hasParamValue(step, "a") && hasParamValue(step, "b") &&
getParamValue(step, "a") == getParamValue(step, "b") &&
Expand Down Expand Up @@ -11692,7 +11703,7 @@ PROJStringParser::Private::buildProjectedCRS(int iStep,
if (!paramValue->empty()) {
value = getAngularValue(*paramValue);
}
} else if (step.name == "krovak") {
} else if (step.name == "krovak" || step.name == "mod_krovak") {
// Keep it in sync with defaults of krovak.cpp
if (param->epsg_code ==
EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE) {
Expand Down Expand Up @@ -12278,7 +12289,8 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
continue;
}
foundKeys.insert(kv.key);
if (step.name == "krovak" && kv.key == "alpha") {
if ((step.name == "krovak" || step.name == "mod_krovak") &&
kv.key == "alpha") {
// We recognize it in our CRS parsing code
recognizedByPROJ = true;
} else {
Expand Down
8 changes: 6 additions & 2 deletions src/iso19111/operation/conversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3925,7 +3925,9 @@ void Conversion::_exportToPROJString(
"y_0", parameterValueNumericAsSI(
EPSG_CODE_PARAMETER_NORTHING_PROJECTION_CENTRE));
}
} else if (methodEPSGCode == EPSG_CODE_METHOD_KROVAK_NORTH_ORIENTED) {
} else if (methodEPSGCode == EPSG_CODE_METHOD_KROVAK_NORTH_ORIENTED ||
methodEPSGCode ==
EPSG_CODE_METHOD_KROVAK_MODIFIED_NORTH_ORIENTED) {
double colatitude =
parameterValueNumeric(EPSG_CODE_PARAMETER_COLATITUDE_CONE_AXIS,
common::UnitOfMeasure::DEGREE);
Expand Down Expand Up @@ -4184,7 +4186,9 @@ void Conversion::_exportToPROJString(
if (mapping->proj_name_aux) {
bool addAux = true;
if (internal::starts_with(mapping->proj_name_aux, "axis=")) {
if (mapping->epsg_code == EPSG_CODE_METHOD_KROVAK) {
if (mapping->epsg_code == EPSG_CODE_METHOD_KROVAK ||
mapping->epsg_code ==
EPSG_CODE_METHOD_KROVAK_MODIFIED) {
auto projCRS = dynamic_cast<const crs::ProjectedCRS *>(
l_targetCRS.get());
if (projCRS) {
Expand Down
7 changes: 7 additions & 0 deletions src/iso19111/operation/parammappings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,13 @@ static const MethodMapping projectionMethodMappings[] = {
{EPSG_NAME_METHOD_KROVAK, EPSG_CODE_METHOD_KROVAK, "Krovak", "krovak",
"axis=swu", krovakParameters},

{EPSG_NAME_METHOD_KROVAK_MODIFIED_NORTH_ORIENTED,
EPSG_CODE_METHOD_KROVAK_MODIFIED_NORTH_ORIENTED, nullptr, "mod_krovak",
nullptr, krovakParameters},

{EPSG_NAME_METHOD_KROVAK_MODIFIED, EPSG_CODE_METHOD_KROVAK_MODIFIED,
nullptr, "mod_krovak", "axis=swu", krovakParameters},

{EPSG_NAME_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA,
EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA,
"Lambert_Azimuthal_Equal_Area", "laea", nullptr, paramsLaea},
Expand Down
1 change: 1 addition & 0 deletions src/pj_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ PROJ_HEAD(merc, "Mercator")
PROJ_HEAD(mil_os, "Miller Oblated Stereographic")
PROJ_HEAD(mill, "Miller Cylindrical")
PROJ_HEAD(misrsom, "Space oblique for MISR")
PROJ_HEAD(mod_krovak, "Modified Krovak")
PROJ_HEAD(moll, "Mollweide")
PROJ_HEAD(molobadekas,
"Molodensky-Badekas transform") /* implemented in PJ_helmert.c */
Expand Down
7 changes: 7 additions & 0 deletions src/proj_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@
#define EPSG_NAME_METHOD_KROVAK "Krovak"
#define EPSG_CODE_METHOD_KROVAK 9819

#define EPSG_NAME_METHOD_KROVAK_MODIFIED "Krovak Modified"
#define EPSG_CODE_METHOD_KROVAK_MODIFIED 1042

#define EPSG_NAME_METHOD_KROVAK_MODIFIED_NORTH_ORIENTED \
"Krovak Modified (North Orientated)"
#define EPSG_CODE_METHOD_KROVAK_MODIFIED_NORTH_ORIENTED 1043

rouault marked this conversation as resolved.
Show resolved Hide resolved
#define EPSG_NAME_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA \
"Lambert Azimuthal Equal Area"
#define EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA 9820
Expand Down