mirror of
https://github.com/csharpee/Map-Projections.git
synced 2025-12-09 00:00:11 -05:00
Hah! Aitoff _does_ have an inverse solution!
I tweaked MapExplainer to be a little bit better, corrected some minor issues with the Projection metadata, added real descriptions to my custom parameterised projections, and fixed a critical bug with WinkelTripel's inverse solution.
This commit is contained in:
parent
5207b1999c
commit
c1eb163af6
BIN
MapAnalyzer.jar
BIN
MapAnalyzer.jar
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -64,7 +64,7 @@ public class MapExplainer {
|
||||
Tetrahedral.TETRAGRAPH, Tetrahedral.AUTHAGRAPH, Pseudocylindrical.SINUSOIDAL,
|
||||
Pseudocylindrical.MOLLWEIDE, Tobler.TOBLER, Misc.HAMMER, Misc.AITOFF,
|
||||
Misc.VAN_DER_GRINTEN, Robinson.ROBINSON, WinkelTripel.WINKEL_TRIPEL,
|
||||
Misc.PEIRCE_QUINCUNCIAL.transverse(), Misc.GUYOU, Misc.TWO_POINT_EQUIDISTANT,
|
||||
Misc.PEIRCE_QUINCUNCIAL.transverse(), Misc.TWO_POINT_EQUIDISTANT,
|
||||
Misc.HAMMER_RETROAZIMUTHAL },
|
||||
|
||||
{ MyProjections.PSEUDOSTEREOGRAPHIC, MyProjections.HYPERELLIPOWER,
|
||||
@ -117,6 +117,7 @@ public class MapExplainer {
|
||||
"title=\"TODO\">");
|
||||
out.println(" </div>");
|
||||
out.println("</div>");
|
||||
out.println("<br>");
|
||||
|
||||
out.println();
|
||||
}
|
||||
|
||||
@ -45,7 +45,8 @@ public class Azimuthal {
|
||||
|
||||
|
||||
public static final Projection POLAR =
|
||||
new Projection("Polar", 1., 0b1111, Type.AZIMUTHAL, Property.EQUIDISTANT) {
|
||||
new Projection(
|
||||
"Azimuthal Equidistant", 1., 0b1111, Type.AZIMUTHAL, Property.EQUIDISTANT) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
final double r = .5 - lat/Math.PI;
|
||||
|
||||
@ -39,7 +39,7 @@ public class Misc {
|
||||
|
||||
public static final Projection AITOFF =
|
||||
new Projection("Aitoff", "A compromise projection shaped like an ellipse",
|
||||
2., 0b1011, Type.PSEUDOAZIMUTHAL, Property.COMPROMISE) {
|
||||
2., 0b1111, Type.PSEUDOAZIMUTHAL, Property.COMPROMISE) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
final double a = Math.acos(Math.cos(lat)*Math.cos(lon/2));
|
||||
|
||||
@ -85,7 +85,8 @@ public class MyProjections {
|
||||
|
||||
|
||||
public static final Projection PSEUDOSTEREOGRAPHIC =
|
||||
new Projection("Pseudostereographic", "The logical next step after Aitoff and Hammer",
|
||||
new Projection(
|
||||
"Pseudostereographic", "The logical next step after Aitoff and Hammer",
|
||||
2, 0b1111, Type.PSEUDOAZIMUTHAL, Property.COMPROMISE) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
@ -106,7 +107,8 @@ public class MyProjections {
|
||||
|
||||
|
||||
public static final Projection HYPERELLIPOWER =
|
||||
new Projection("Hyperellipower", "A parametric projection that I'm still testing",
|
||||
new Projection(
|
||||
"Hyperellipower", "A parametrised pseudocylindrical projection that I invented",
|
||||
2., 0b1111, Type.PSEUDOCYLINDRICAL, Property.COMPROMISE,
|
||||
new String[] {"k","n","a"},
|
||||
new double[][] {{1,3,5},{.5,2.,1.20},{.5,2.,1.13}}) {
|
||||
@ -136,7 +138,8 @@ public class MyProjections {
|
||||
|
||||
|
||||
public static final Projection TWO_POINT_EQUALIZED =
|
||||
new Projection("Two-Point Equalized", "A parametric projection that I'm still testing",
|
||||
new Projection("Two-Point Equalized",
|
||||
"A projection I invented specifically for viewing small elliptical regions of the Earth",
|
||||
0, 0b1111, Type.OTHER, Property.EQUIDISTANT, new String[] {"Width"},
|
||||
new double[][] { {0, 180, 120} }) {
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ public class Tetrahedral {
|
||||
|
||||
public static final Projection TETRAPOWER =
|
||||
new TetrahedralProjection(
|
||||
"Tetrapower", "A parametric projection that I'm still testing",
|
||||
"Tetrapower", "A parameterised tetrahedral projection that I invented.",
|
||||
Math.sqrt(3), 0b1111, Property.COMPROMISE, new String[] {"k1","k2","k3"},
|
||||
new double[][] {{.01,2.,.98},{.01,2.,1.2},{.01,2.,.98}}) {
|
||||
|
||||
@ -118,7 +118,8 @@ public class Tetrahedral {
|
||||
|
||||
|
||||
public static final Projection TETRAFILLET =
|
||||
new TetrahedralProjection("TetraFillet", "A parametric projection that I'm still testing",
|
||||
new TetrahedralProjection("TetraFillet",
|
||||
"A parameterised tetrahedral projection I invented with the corners filleted off",
|
||||
Math.sqrt(3), 0b1110, Property.COMPROMISE, new String[] {"k1","k2","k3"},
|
||||
new double[][] {{.01,2.,.78},{.01,2.,.99},{.01,2.,1.3}}) {
|
||||
|
||||
@ -165,8 +166,9 @@ public class Tetrahedral {
|
||||
|
||||
public static final Projection TETRACHAMFER =
|
||||
new TetrahedralProjection(
|
||||
"TetraChamfer", "A parametric projection that I'm still testing", Math.sqrt(3),
|
||||
0b1110, Property.COMPROMISE, new String[] {"k1","k2","k3"},
|
||||
"TetraChamfer",
|
||||
"A parameterised tetrahedral projection I invented with the corners chamfered off",
|
||||
Math.sqrt(3), 0b1110, Property.COMPROMISE, new String[] {"k1","k2","k3"},
|
||||
new double[][] {{.01,2.,.78},{.01,2.,.99},{.01,2.,1.3}}) {
|
||||
|
||||
private double k1, k2, k3;
|
||||
|
||||
@ -42,7 +42,7 @@ public class Tobler {
|
||||
"Tobler", "An equal-area projection shaped like a hyperellipse (in case you're wondering about gamma, it's calculated automatically)",
|
||||
2., 0b1001, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA,
|
||||
new String[]{"Std. Parallel","alpha","K"},
|
||||
new double[][] {{0,89,30.6}, {0,1,.5}, {1,8,3.63}}) {
|
||||
new double[][] {{0,89,37}, {0,1,0}, {1,8,3.6}}) { //optimal parameters are 30.6,.50,3.63, but these defaults are more recognizably Tobler
|
||||
|
||||
private static final int N = 10000;
|
||||
private double alpha, kappa, epsilon; //epsilon is related to gamma, but defined somewhat differently
|
||||
|
||||
@ -55,12 +55,14 @@ public final class WinkelTripel {
|
||||
}
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
return new double[] { f1pX(lat,lon)/aspectRatio, f2pY(lat,lon)/aspectRatio };
|
||||
return new double[] {
|
||||
f1pX(lat,lon)/aspectRatio/Math.PI, f2pY(lat,lon)/aspectRatio/Math.PI };
|
||||
}
|
||||
|
||||
public double[] inverse(double x, double y) {
|
||||
return NumericalAnalysis.newtonRaphsonApproximation(
|
||||
x*aspectRatio, y, y/2, x*(1 + Math.cos(y*Math.PI/2))/2,
|
||||
x*Math.PI*aspectRatio, y*Math.PI,
|
||||
y*Math.PI/2, x*Math.PI*(1 + Math.cos(y*Math.PI/2))/2,
|
||||
this::f1pX, this::f2pY,
|
||||
this::df1dphi, this::df1dlam, this::df2dphi, this::df2dlam, .002);
|
||||
}
|
||||
@ -68,14 +70,13 @@ public final class WinkelTripel {
|
||||
private double f1pX(double phi, double lam) {
|
||||
final double d = D(phi,lam);
|
||||
final double c = C(phi,lam);
|
||||
return 2/Math.PI*d/Math.sqrt(c)*Math.cos(phi)*Math.sin(lam/2)
|
||||
+ lam/Math.PI*(aspectRatio-1);
|
||||
return 2*d/Math.sqrt(c)*Math.cos(phi)*Math.sin(lam/2) + lam*(aspectRatio-1);
|
||||
}
|
||||
|
||||
private double f2pY(double phi, double lam) {
|
||||
final double d = D(phi,lam);
|
||||
final double c = C(phi,lam);
|
||||
return d/Math.sqrt(c)*Math.sin(phi)/Math.PI + phi/Math.PI;
|
||||
return d/Math.sqrt(c)*Math.sin(phi) + phi;
|
||||
}
|
||||
|
||||
private double df1dphi(double phi, double lam) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user