1 | // License: GPL. For details, see LICENSE file.
|
---|
2 | package org.openstreetmap.josm.data.projection.proj;
|
---|
3 |
|
---|
4 | import static java.lang.Math.abs;
|
---|
5 | import static java.lang.Math.cos;
|
---|
6 | import static java.lang.Math.sin;
|
---|
7 | import static java.lang.Math.sqrt;
|
---|
8 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
9 |
|
---|
10 | import org.openstreetmap.josm.data.Bounds;
|
---|
11 |
|
---|
12 | /**
|
---|
13 | * Sinusoidal projection (aka. Sanson–Flamsteed, Mercator equal-area projection)
|
---|
14 | * <p>
|
---|
15 | * This class has been derived from the implementation of the <a href="https://github.com/geotools/geotools">Geotools</a> project;
|
---|
16 | * git 577dd2d, org.geotools.referencing.operation.projection.Sinusoidal at the time of migration.
|
---|
17 | */
|
---|
18 | public class Sinusoidal extends AbstractProj {
|
---|
19 |
|
---|
20 | @Override
|
---|
21 | public String getName() {
|
---|
22 | return tr("Sinusoidal");
|
---|
23 | }
|
---|
24 |
|
---|
25 | @Override
|
---|
26 | public String getProj4Id() {
|
---|
27 | return "sinu";
|
---|
28 | }
|
---|
29 |
|
---|
30 | @Override
|
---|
31 | public double[] project(final double phi, final double lambda) {
|
---|
32 | if (spherical) {
|
---|
33 | return new double[]{lambda * cos(phi), phi};
|
---|
34 | } else {
|
---|
35 | final double s = sin(phi);
|
---|
36 | return new double[]{lambda * cos(phi) / sqrt(1. - e2 * s * s), mlfn(phi, s, cos(phi))};
|
---|
37 | }
|
---|
38 | }
|
---|
39 |
|
---|
40 | @Override
|
---|
41 | public double[] invproject(final double east, final double north) {
|
---|
42 | if (spherical) {
|
---|
43 | return new double[]{north, east / cos(north)};
|
---|
44 | } else {
|
---|
45 | final double phi = invMlfn(north);
|
---|
46 | double s = abs(phi);
|
---|
47 | final double lambda;
|
---|
48 | if (abs(s - Math.PI / 2) < 1e-10) {
|
---|
49 | lambda = 0.;
|
---|
50 | } else if (s < Math.PI / 2) {
|
---|
51 | s = sin(phi);
|
---|
52 | lambda = (east * sqrt(1. - e2 * s * s) / cos(phi)) % Math.PI;
|
---|
53 | } else {
|
---|
54 | return new double[]{0., 0.}; // this is an error and should be handled somehow
|
---|
55 | }
|
---|
56 | return new double[]{phi, lambda};
|
---|
57 | }
|
---|
58 | }
|
---|
59 |
|
---|
60 | @Override
|
---|
61 | public Bounds getAlgorithmBounds() {
|
---|
62 | return new Bounds(-90, -180, 90, 180, false);
|
---|
63 | }
|
---|
64 | }
|
---|