diff options
| author | Kristian Evers <kristianevers@gmail.com> | 2018-04-09 22:38:39 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-04-09 22:38:39 +0200 |
| commit | 875d5168b7978fb35ae3e71be85baa176403447d (patch) | |
| tree | e613c2eb254d571ec55290c148ec51f3488e1b50 | |
| parent | 89af2753651f8c21eae9df631a71c0a3b03bcc3b (diff) | |
| parent | 3a2ddb6c6efbccf388ea89e177ca51fd25946ecf (diff) | |
| download | PROJ-875d5168b7978fb35ae3e71be85baa176403447d.tar.gz PROJ-875d5168b7978fb35ae3e71be85baa176403447d.zip | |
Merge pull request #925 from rouault/aux_sphere_type
Add a dedicated proj=webmerc operation
| -rw-r--r-- | docs/source/operations/projections/index.rst | 1 | ||||
| -rw-r--r-- | docs/source/operations/projections/webmerc.rst | 78 | ||||
| -rw-r--r-- | src/PJ_merc.c | 17 | ||||
| -rw-r--r-- | src/PJ_pipeline.c | 2 | ||||
| -rw-r--r-- | src/pj_list.h | 1 | ||||
| -rw-r--r-- | src/proj_4D_api.c | 4 | ||||
| -rw-r--r-- | test/gie/4D-API_cs2cs-style.gie | 13 |
7 files changed, 114 insertions, 2 deletions
diff --git a/docs/source/operations/projections/index.rst b/docs/source/operations/projections/index.rst index 9255d9fd..77decd6c 100644 --- a/docs/source/operations/projections/index.rst +++ b/docs/source/operations/projections/index.rst @@ -141,6 +141,7 @@ Projections map the spherical 3D space to a flat 2D space. wag5 wag6 wag7 + webmerc weren wink1 wink2 diff --git a/docs/source/operations/projections/webmerc.rst b/docs/source/operations/projections/webmerc.rst new file mode 100644 index 00000000..0c465afc --- /dev/null +++ b/docs/source/operations/projections/webmerc.rst @@ -0,0 +1,78 @@ +.. _webmerc: + +******************************************************************************** +Web Mercator / Pseudo Mercator +******************************************************************************** + +The Web Mercator / Pseudo Mercator projection is a cylindrical map projection. +This is a variant of the regular :ref:`merc` projection, except that the computation +is done on a sphere, using the semi-major axis of the ellipsoid. + +From `Wikipedia <https://en.wikipedia.org/wiki/Web_Mercator>`_: + + This projection is widely used by the Web Mercator, Google Web Mercator, + Spherical Mercator, WGS 84 Web Mercator[1] or WGS 84/Pseudo-Mercator is a + variant of the Mercator projection and is the de facto standard for Web + mapping applications. [...] + It is used by virtually all major online map providers [...] + Its official EPSG identifier is EPSG:3857, although others have been used + historically. + + ++---------------------+----------------------------------------------------------+ +| **Classification** | Cylindrical (non conformant if used with ellipsoid) | ++---------------------+----------------------------------------------------------+ +| **Version** | Added in proj 5.1.0 | ++---------------------+----------------------------------------------------------+ +| **Available forms** | Forward and inverse, spherical projection | ++---------------------+----------------------------------------------------------+ +| **Defined area** | Global, but best used near the equator | ++---------------------+----------------------------------------------------------+ +| **Options** | Neither lat_0, lon_0, lat_ts or k_0 should be used. | ++---------------------+----------------------------------------------------------+ + +Usage +######## + +Example:: + + $ echo 2 49 | proj +proj=webmerc +datum=WGS84 + 222638.98 6274861.39 + +Mathematical definition +####################### + +The formulas describing the Mercator projection are all taken from G. Evenden's libproj manuals [Evenden2005]_. + +Forward projection +================== + +.. math:: + + x = \lambda + +.. math:: + + y = \ln \left[ \tan \left(\frac{\pi}{4} + \frac{\phi}{2} \right) \right] + + +Inverse projection +================== + +.. math:: + + \lambda = {x} + +.. math:: + + \phi = \frac{\pi}{2} - 2 \arctan \left[ e^{-y} \right] + + + +Further reading +############### + +#. `Wikipedia <https://en.wikipedia.org/wiki/Web_Mercator>`_ + + + diff --git a/src/PJ_merc.c b/src/PJ_merc.c index 18303c45..a3e5e846 100644 --- a/src/PJ_merc.c +++ b/src/PJ_merc.c @@ -1,8 +1,10 @@ #define PJ_LIB__ +#include "proj_internal.h" #include "proj.h" #include "projects.h" PROJ_HEAD(merc, "Mercator") "\n\tCyl, Sph&Ell\n\tlat_ts="; +PROJ_HEAD(webmerc, "Web Mercator / Pseudo Mercator") "\n\tCyl, Sph\n\t"; #define EPS10 1.e-10 @@ -76,3 +78,18 @@ PJ *PROJECTION(merc) { return P; } +PJ *PROJECTION(webmerc) { + + /* Overriding k_0, lat_0 and lon_0 with fixed parameters */ + P->k0 = 1.0; + P->phi0 = 0.0; + P->lam0 = 0.0; + + P->b = P->a; + /* Clean up the ellipsoidal parameters to reflect the sphere */ + P->es = P->e = P->f = 0; + pj_calc_ellipsoid_params (P, P->a, 0); + P->inv = s_inverse; + P->fwd = s_forward; + return P; +} diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index b60e05a8..aa7d76f8 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -306,6 +306,8 @@ static void set_ellipsoid(PJ *P) { /* the PJ you provided". */ proj_errno_reset (P); } + P->a_orig = P->a; + P->es_orig = P->es; pj_calc_ellipsoid_params (P, P->a, P->es); diff --git a/src/pj_list.h b/src/pj_list.h index 09a66034..440f7972 100644 --- a/src/pj_list.h +++ b/src/pj_list.h @@ -156,6 +156,7 @@ PROJ_HEAD(wag4, "Wagner IV") PROJ_HEAD(wag5, "Wagner V") PROJ_HEAD(wag6, "Wagner VI") PROJ_HEAD(wag7, "Wagner VII") +PROJ_HEAD(webmerc, "Web Mercator / Pseudo Mercator") PROJ_HEAD(weren, "Werenskiold I") PROJ_HEAD(wink1, "Winkel I") PROJ_HEAD(wink2, "Winkel II") diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c index 11a56ac0..aed4685b 100644 --- a/src/proj_4D_api.c +++ b/src/proj_4D_api.c @@ -485,7 +485,7 @@ Returns 1 on success, 0 on failure if (0==d[0] && 0==d[1] && 0==d[2] && 0==d[3] && 0==d[4] && 0==d[5] && 0==d[6]) { /* If the current ellipsoid is not WGS84, then make sure the */ /* change in ellipsoid is still done. */ - if (!(fabs(P->a - 6378137.0) < 1e-8 && fabs(P->f - 1./ 298.257223563) < 1e-15)) { + if (!(fabs(P->a_orig - 6378137.0) < 1e-8 && fabs(P->es_orig - 0.0066943799901413) < 1e-15)) { do_cart = 1; } break; @@ -512,7 +512,7 @@ Returns 1 on success, 0 on failure /* geocentric/cartesian space or we need to do a Helmert transform. */ if (P->is_geocent || P->helmert || do_cart) { char def[150]; - sprintf (def, "break_cs2cs_recursion proj=cart a=%40.20g f=%40.20g", P->a, P->f); + sprintf (def, "break_cs2cs_recursion proj=cart a=%40.20g es=%40.20g", P->a_orig, P->es_orig); Q = proj_create (P->ctx, def); if (0==Q) return 0; diff --git a/test/gie/4D-API_cs2cs-style.gie b/test/gie/4D-API_cs2cs-style.gie index bbd9ee39..6eed4faa 100644 --- a/test/gie/4D-API_cs2cs-style.gie +++ b/test/gie/4D-API_cs2cs-style.gie @@ -216,6 +216,19 @@ expect -10370728.80 5552839.74 0 ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- +Test that Google's Web Mercator with +proj=webmerc +------------------------------------------------------------------------------- +operation proj=pipeline step init=epsg:26915 inv step proj=webmerc datum=WGS84 +------------------------------------------------------------------------------- +tolerance 20 cm +accept 487147.594520173 4934316.46263998 +expect -10370728.80 5552839.74 + +accept 487147.594520173 4934316.46263998 0 +expect -10370728.80 5552839.74 0 +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- Test that +datum parameters are handled correctly in pipelines. See #872 for details. ------------------------------------------------------------------------------- |
