-
Notifications
You must be signed in to change notification settings - Fork 802
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
the Bertin 1953 projection #1133
Changes from all commits
6b0567b
c996298
5f4fa9c
e649eb7
0e3debf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
.. _bertin1953: | ||
|
||
******************************************************************************** | ||
Bertin 1953 | ||
******************************************************************************** | ||
|
||
.. versionadded:: 6.0.0 | ||
|
||
+---------------------+-------------------------------+ | ||
| **Classification** | Miscellaneous | | ||
+---------------------+-------------------------------+ | ||
| **Available forms** | Forward, spherical projection | | ||
+---------------------+-------------------------------+ | ||
| **Defined area** | Global | | ||
+---------------------+-------------------------------+ | ||
| **Alias** | bertin1953 | | ||
+---------------------+-------------------------------+ | ||
| **Domain** | 2D | | ||
+---------------------+-------------------------------+ | ||
| **Input type** | Geodetic coordinates | | ||
+---------------------+-------------------------------+ | ||
| **Output type** | Projected coordinates | | ||
+---------------------+-------------------------------+ | ||
|
||
|
||
|
||
.. figure:: ./images/bertin1953.png | ||
:width: 500 px | ||
:align: center | ||
:alt: Bertin 1953 | ||
|
||
proj-string: ``+proj=bertin1953`` | ||
|
||
|
||
The Bertin 1953 projection is intended for making world maps. Created by Jacques Bertin | ||
in 1953, this projection was the go-to choice of the French cartographic school when they | ||
wished to represent phenomena on a global scale. The projection was formulated in 2017 | ||
by Philippe Rivière for visionscarto.net. | ||
|
||
|
||
Usage | ||
############################################################################### | ||
|
||
The Bertin 1953 projection has no special options. Its rotation parameters | ||
are fixed. Here is an example of a forward projection with scale 1: | ||
|
||
$ echo 122 47 | src/proj +proj=bertin1953 +R=1 | ||
0.72 0.73 | ||
|
||
Parameters | ||
################################################################################ | ||
|
||
.. note:: All parameters for the projection are optional. | ||
|
||
.. include:: ../options/R.rst | ||
|
||
.. include:: ../options/x_0.rst | ||
|
||
.. include:: ../options/y_0.rst | ||
|
||
Further reading | ||
################################################################################ | ||
|
||
#. Philippe Rivière (2017). `Bertin Projection (1953) <https://visionscarto.net/bertin-projection-1953>`, Visionscarto.net. | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
Created by Jacques Bertin in 1953, this projection was the go-to choice | ||
of the French cartographic school when they wished to represent phenomena | ||
on a global scale. | ||
|
||
Formula designed by Philippe Rivière, 2017. | ||
https://visionscarto.net/bertin-projection-1953 | ||
|
||
Port to PROJ by Philippe Rivière, 21 September 2018 | ||
*/ | ||
|
||
#define PJ_LIB__ | ||
|
||
#include <errno.h> | ||
#include <math.h> | ||
|
||
#include "proj_internal.h" | ||
#include "proj.h" | ||
#include "projects.h" | ||
|
||
PROJ_HEAD(bertin1953, "Bertin 1953") | ||
"\n\tMisc Sph no inv."; | ||
|
||
struct pj_opaque { | ||
double cos_delta_phi, sin_delta_phi, cos_delta_gamma, sin_delta_gamma, deltaLambda; | ||
}; | ||
|
||
|
||
static XY s_forward (LP lp, PJ *P) { | ||
XY xy = {0.0,0.0}; | ||
struct pj_opaque *Q = P->opaque; | ||
|
||
double fu = 1.4, k = 12., w = 1.68, d; | ||
|
||
/* Rotate */ | ||
double cosphi, x, y, z, z0; | ||
lp.lam += PJ_TORAD(-16.5); | ||
cosphi = cos(lp.phi); | ||
x = cos(lp.lam) * cosphi; | ||
y = sin(lp.lam) * cosphi; | ||
z = sin(lp.phi); | ||
z0 = z * Q->cos_delta_phi + x * Q->sin_delta_phi; | ||
lp.lam = atan2(y * Q->cos_delta_gamma - z0 * Q->sin_delta_gamma, | ||
x * Q->cos_delta_phi - z * Q->sin_delta_phi); | ||
z0 = z0 * Q->cos_delta_gamma + y * Q->sin_delta_gamma; | ||
lp.phi = asin(z0); | ||
|
||
lp.lam = adjlon(lp.lam); | ||
|
||
/* Adjust pre-projection */ | ||
if (lp.lam + lp.phi < -fu) { | ||
d = (lp.lam - lp.phi + 1.6) * (lp.lam + lp.phi + fu) / 8.; | ||
lp.lam += d; | ||
lp.phi -= 0.8 * d * sin(lp.phi + M_PI / 2.); | ||
} | ||
|
||
/* Project with Hammer (1.68,2) */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this is the same Hammer projection as defined in This avoids duplicate code and potential bugs in Hammer will be fixed both places if necessary. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes I wanted to do that, but couldn't find an example in the src/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something similar is done in You'll have to adjust it a bit but the general idea is there. Also notice that you need to create a custom descructor for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feel free to add this! It's my first contribution to Proj.4 and it had been a looong time since I coded anything in C :-) |
||
cosphi = cos(lp.phi); | ||
d = sqrt(2./(1. + cosphi * cos(lp.lam / 2.))); | ||
xy.x = w * d * cosphi * sin(lp.lam / 2.); | ||
xy.y = d * sin(lp.phi); | ||
|
||
/* Adjust post-projection */ | ||
d = (1. - cos(lp.lam * lp.phi)) / k; | ||
if (xy.y < 0.) { | ||
xy.x *= 1. + d; | ||
} | ||
if (xy.y > 0.) { | ||
xy.x *= 1. + d / 1.5 * xy.x * xy.x; | ||
} | ||
|
||
return xy; | ||
} | ||
|
||
|
||
PJ *PROJECTION(bertin1953) { | ||
struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); | ||
if (0==Q) | ||
return pj_default_destructor (P, ENOMEM); | ||
P->opaque = Q; | ||
|
||
P->lam0 = 0; | ||
P->phi0 = PJ_TORAD(-42.); | ||
|
||
Q->cos_delta_phi = cos(P->phi0); | ||
Q->sin_delta_phi = sin(P->phi0); | ||
Q->cos_delta_gamma = 1.; | ||
Q->sin_delta_gamma = 0.; | ||
|
||
P->es = 0.; | ||
P->fwd = s_forward; | ||
|
||
return P; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the best reference we have? If possible, I'd like to have a reference to the mathematical description as well, preferably an academic paper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well if you read that modest blog post, you'll know :)
(I wish I had time and resources to publish this as an academic paper.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did, but it wasn't clear to me if something else was published.
You are welcome to use the PROJ docs as a platform for describing the mathematics behind the projection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PS: I agree that my construction is totally ad-hoc, and that another formula might be much nicer mathematically (esp. with second and third derivatives). It's the best I could come up with as a first approximation, and I'm very open to making an upgraded formula at some point (provided it still respects the original drawing).