mirror of
https://github.com/csharpee/Map-Projections.git
synced 2025-12-10 00:00:19 -05:00
remove all these pointless constructors
it seems when I wrote this I optimized it to make the Projection constructions as consise as possible, which is stupid and annoying because now I don't remember how to use any of the fancy constructors that automaticly construct descriptions. so I got rid of that. when you construct a projection, you pass its constructor. also, the stupid "fisc" int that is actually four booleans in a trenchcoat is now four booleans not in a trenchcoat. wow, writing the thing you mean instead of encoding it to save twenty bytes of code? the horror!
This commit is contained in:
parent
3befac6590
commit
0ca637928d
@ -73,8 +73,8 @@ public class ArbitraryPseudocylindrical {
|
||||
private final double yScale;
|
||||
|
||||
public ArbitraryProjection(String title, String inventor, double yScale, double[][] table) {
|
||||
super(title, null, 0b1111, Type.PSEUDOCYLINDRICAL, Property.COMPROMISE, 3,
|
||||
null, "designed by "+inventor);
|
||||
super(title, "A compromise pseudocylindrical projection designed by " + inventor,
|
||||
null, true, true, true, true, Type.PSEUDOCYLINDRICAL, Property.COMPROMISE, 3);
|
||||
this.table = table;
|
||||
this.yScale = yScale;
|
||||
this.shape = Shape.meridianEnvelope(this);
|
||||
|
||||
@ -45,8 +45,8 @@ import static java.lang.Math.toRadians;
|
||||
public class Azimuthal {
|
||||
|
||||
public static final Projection STEREOGRAPHIC = new Projection(
|
||||
"Stereographic", Shape.rectangle(4, 4), 0b0111, Type.AZIMUTHAL, Property.CONFORMAL, 2,
|
||||
"mathematically important") {
|
||||
"Stereographic", "A mathematically important conformal azimuthal projection",
|
||||
Shape.rectangle(4, 4), true, false, true, true, Type.AZIMUTHAL, Property.CONFORMAL, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
if (lat < -1.5) lat = -1.5;
|
||||
@ -61,7 +61,8 @@ public class Azimuthal {
|
||||
|
||||
|
||||
public static final Projection POLAR = new Projection(
|
||||
"Azimuthal Equidistant", Shape.circle(PI), 0b1111, Type.AZIMUTHAL,
|
||||
"Azimuthal Equidistant", "An equidistant azimuthal projection",
|
||||
Shape.circle(PI), true, true, true, true, Type.AZIMUTHAL,
|
||||
Property.EQUIDISTANT, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
@ -80,7 +81,8 @@ public class Azimuthal {
|
||||
|
||||
|
||||
public static final Projection EQUAL_AREA = new Projection(
|
||||
"Azimuthal Equal-Area", Shape.circle(1), 0b1111, Type.AZIMUTHAL, Property.EQUAL_AREA, 1) {
|
||||
"Azimuthal Equal-Area", "An equal-area azimuthal projection",
|
||||
Shape.circle(1), true, true, true, true, Type.AZIMUTHAL, Property.EQUAL_AREA, 1) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
final double r = cos((PI/2+lat)/2);
|
||||
@ -98,8 +100,8 @@ public class Azimuthal {
|
||||
|
||||
|
||||
public static final Projection GNOMONIC = new Projection(
|
||||
"Gnomonic", "A projection that draws all great circles as straight lines.",
|
||||
Shape.rectangle(4, 4), 0b0111, Type.AZIMUTHAL, Property.GNOMONIC, 2) {
|
||||
"Gnomonic", "A projection that draws all great circles as straight lines",
|
||||
Shape.rectangle(4, 4), true, false, true, true, Type.AZIMUTHAL, Property.GNOMONIC, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
if (lat < 0.2) lat = 0.2;
|
||||
@ -114,8 +116,8 @@ public class Azimuthal {
|
||||
|
||||
|
||||
public static final Projection ORTHOGRAPHIC = new Projection(
|
||||
"Orthographic", "A projection that mimics the Earth viewed from a great distance.",
|
||||
Shape.circle(1), 0b0111, Type.AZIMUTHAL, Property.PERSPECTIVE, 3) {
|
||||
"Orthographic", "A projection that mimics the Earth viewed from a great distance",
|
||||
Shape.circle(1), true, false, true, true, Type.AZIMUTHAL, Property.PERSPECTIVE, 3) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
if (lat < 0) lat = 0;
|
||||
@ -133,8 +135,8 @@ public class Azimuthal {
|
||||
|
||||
|
||||
public static final Projection PERSPECTIVE = new Projection(
|
||||
"Perspective", "A projection that mimics the actual appearance of the Earth.",
|
||||
null, 0b0111, Type.AZIMUTHAL, Property.PERSPECTIVE, 4,
|
||||
"Perspective", "A projection that mimics the actual appearance of the Earth",
|
||||
null, true, false, true, true, Type.AZIMUTHAL, Property.PERSPECTIVE, 4,
|
||||
new String[] {"Percentage"}, new double[][] {{1,99,33.3}}) {
|
||||
|
||||
private double d; //viewing distance in sphere radii
|
||||
@ -166,8 +168,8 @@ public class Azimuthal {
|
||||
|
||||
|
||||
public static final Projection MAGNIFIER = new Projection(
|
||||
"Magnifying glass", "A projection that dilates its center to great scales.",
|
||||
Shape.circle(1), 0b1111, Type.AZIMUTHAL, Property.POINTLESS, 2,
|
||||
"Magnifying glass", "A projection that dilates its center to great scales",
|
||||
Shape.circle(1), true, true, true, true, Type.AZIMUTHAL, Property.POINTLESS, 2,
|
||||
new String[] {"Actual size", "Apparent size"},
|
||||
new double[][] {{1, 60, 20}, {0.5, 1.0, 0.5}}) {
|
||||
|
||||
|
||||
@ -77,7 +77,7 @@ public class CahillKeyes {
|
||||
public static Projection FACE = new Projection(
|
||||
"Cahill–Keyes (face)", "A single face of Gene Keyes's octohedral projection",
|
||||
Shape.polygon(new double[][] {{0., 0.}, {0., -sqrt(3)/2.}, {1/2., -sqrt(3)/2.}}),
|
||||
0b1011, Projection.Type.OTHER, Projection.Property.COMPROMISE, 2) {
|
||||
true, true, true, false, Projection.Type.OTHER, Projection.Property.COMPROMISE, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
// Mary-Jo's coordinates put the pole at the origin and everything else to the right
|
||||
|
||||
@ -47,7 +47,7 @@ import static utils.Math2.min;
|
||||
public class Conic {
|
||||
|
||||
public static final Projection LAMBERT =
|
||||
new ConicProjection("Conformal Conic", 0b0111, Property.CONFORMAL, 2) {
|
||||
new ConicProjection("Conformal Conic", false, true, true, Property.CONFORMAL, 2) {
|
||||
|
||||
private double n; //the scaling factor for angles
|
||||
|
||||
@ -140,7 +140,7 @@ public class Conic {
|
||||
|
||||
|
||||
public static final Projection EQUIDISTANT =
|
||||
new ConicProjection("Equidistant Conic", 0b1111, Property.EQUIDISTANT, 2) {
|
||||
new ConicProjection("Equidistant Conic", true, true, true, Property.EQUIDISTANT, 2) {
|
||||
|
||||
private double m; //the scaling factor for radii
|
||||
private double n; //the scaling factor for angles
|
||||
@ -195,7 +195,7 @@ public class Conic {
|
||||
|
||||
|
||||
public static final Projection ALBERS =
|
||||
new ConicProjection("Albers", 0b1111, Property.EQUAL_AREA, 2) {
|
||||
new ConicProjection("Albers", true, true, true, Property.EQUAL_AREA, 2) {
|
||||
|
||||
private double n; //the scaling factor for angles
|
||||
private double C; //a scaling factor for radii
|
||||
@ -259,10 +259,12 @@ public class Conic {
|
||||
protected double lat1, lat2;
|
||||
protected boolean reversed;
|
||||
|
||||
ConicProjection(String name, int fisc, Property property, int rating) {
|
||||
super(name, "The "+property+" conic projection.", null, fisc, Type.CONIC, property,
|
||||
rating, new String[] {"Std. Parallel 1", "Std. Parallel 2"},
|
||||
new double[][] {{-89,89,15},{-89,89,45}});
|
||||
ConicProjection(String name, boolean finite, boolean solvable, boolean invertible,
|
||||
Property property, int rating) {
|
||||
super(name, "The " + property + " conic projection", null, true, finite, solvable,
|
||||
invertible, Type.CONIC, property, rating,
|
||||
new String[] {"Std. Parallel 1", "Std. Parallel 2"},
|
||||
new double[][] {{-89,89,15},{-89,89,45}});
|
||||
}
|
||||
|
||||
public final void initialize(double... params) {
|
||||
|
||||
@ -47,8 +47,9 @@ import static java.lang.Math.toRadians;
|
||||
public class Cylindrical {
|
||||
|
||||
public static final Projection MERCATOR = new Projection(
|
||||
"Mercator", Shape.rectangle(2*PI, 2*PI), 0b0111, Type.CYLINDRICAL, Property.CONFORMAL, 1,
|
||||
"very popular") {
|
||||
"Mercator", "A very popular conformal cylindrical projection",
|
||||
Shape.rectangle(2*PI, 2*PI), true, false, true, true,
|
||||
Type.CYLINDRICAL, Property.CONFORMAL, 1) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
return new double[] {lon, log(tan(PI/4+lat/2))};
|
||||
@ -61,8 +62,9 @@ public class Cylindrical {
|
||||
|
||||
|
||||
public static final Projection PLATE_CARREE = new Projection(
|
||||
"Plate Carr\u00E9e", Shape.rectangle(2*Math.PI, Math.PI), 0b1111, Type.CYLINDRICAL,
|
||||
Property.EQUIDISTANT, 2, null, "focused on the equator"){
|
||||
"Plate Carr\u00E9e", "An equidistant cylindrical projection focused on the equator",
|
||||
Shape.rectangle(2*Math.PI, Math.PI), true, true, true, true,
|
||||
Type.CYLINDRICAL, Property.EQUIDISTANT, 2){
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
return new double[] {lon, lat};
|
||||
@ -75,8 +77,8 @@ public class Cylindrical {
|
||||
|
||||
|
||||
public static final Projection EQUIRECTANGULAR = new Projection(
|
||||
"Equirectangular", "A linear mapping from longitude and latitude to x and y.",
|
||||
null, 0b1111, Type.CYLINDRICAL, Property.EQUIDISTANT, 2,
|
||||
"Equirectangular", "A linear mapping from longitude and latitude to x and y",
|
||||
null, true, true, true, true, Type.CYLINDRICAL, Property.EQUIDISTANT, 2,
|
||||
new String[]{"Std. parallel"}, new double[][]{{0, 89, 0}}) {
|
||||
|
||||
private double stdParallel;
|
||||
@ -97,8 +99,8 @@ public class Cylindrical {
|
||||
|
||||
|
||||
public static final Projection GALL_ORTHOGRAPHIC = new Projection(
|
||||
"Gall-Peters", Shape.rectangle(2*Math.PI, 4), 0b1111, Type.CYLINDRICAL, Property.EQUAL_AREA, 0,
|
||||
"somewhat controversial", "with least distortion at 45\u00B0") {
|
||||
"Gall-Peters", "A somewhat controversial equal-area cylindrical projection with least distortion at 45\u00B0",
|
||||
Shape.rectangle(2*Math.PI, 4), true, true, true, true, Type.CYLINDRICAL, Property.EQUAL_AREA, 0) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
return new double[] {lon, sin(lat)*shape.yMax};
|
||||
@ -111,8 +113,8 @@ public class Cylindrical {
|
||||
|
||||
|
||||
public static final Projection HOBO_DYER = new Projection(
|
||||
"Hobo-Dyer", Shape.rectangle(2*PI, 3.178), 0b1111, Type.CYLINDRICAL, Property.EQUAL_AREA, 2,
|
||||
null, "with least distortion at 37.5\u00B0") {
|
||||
"Hobo-Dyer", "An equal-area cylindrical projection with least distortion at 37.5\u00B0",
|
||||
Shape.rectangle(2*PI, 3.178), true, true, true, true, Type.CYLINDRICAL, Property.EQUAL_AREA, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
return new double[] {lon, sin(lat)*shape.yMax};
|
||||
@ -125,8 +127,8 @@ public class Cylindrical {
|
||||
|
||||
|
||||
public static final Projection BEHRMANN = new Projection(
|
||||
"Behrmann", Shape.rectangle(2*PI, 8/3.), 0b1111, Type.CYLINDRICAL, Property.EQUAL_AREA, 3,
|
||||
null, "with least distortion at 30\u00B0") {
|
||||
"Behrmann", "An equal-area cylindrical projection with least distortion at 30\u00B0",
|
||||
Shape.rectangle(2*PI, 8/3.), true, true, true, true, Type.CYLINDRICAL, Property.EQUAL_AREA, 3) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
return new double[] {lon, sin(lat)*shape.yMax};
|
||||
@ -139,8 +141,8 @@ public class Cylindrical {
|
||||
|
||||
|
||||
public static final Projection LAMBERT = new Projection(
|
||||
"Lambert cylindrical", Shape.rectangle(2*PI, 2), 0b1111, Type.CYLINDRICAL, Property.EQUAL_AREA, 2,
|
||||
null, "with least distortion along the equator") {
|
||||
"Lambert cylindrical", "An equal-area cylindrical projection with least distortion along the equator",
|
||||
Shape.rectangle(2*PI, 2), true, true, true, true, Type.CYLINDRICAL, Property.EQUAL_AREA, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
return new double[] {lon, sin(lat)*shape.yMax};
|
||||
@ -153,8 +155,8 @@ public class Cylindrical {
|
||||
|
||||
|
||||
public static final Projection EQUAL_AREA = new Projection(
|
||||
"Cylindrical Equal-area", "A generalized equal-area cylindrical projection.",
|
||||
null, 0b1111, Type.CYLINDRICAL, Property.EQUAL_AREA, 2,
|
||||
"Cylindrical Equal-area", "A generalized equal-area cylindrical projection",
|
||||
null, true, true, true, true, Type.CYLINDRICAL, Property.EQUAL_AREA, 2,
|
||||
new String[]{"Std. parallel"}, new double[][]{{0, 89, 30}}) {
|
||||
|
||||
public void initialize(double... params) {
|
||||
@ -172,8 +174,9 @@ public class Cylindrical {
|
||||
|
||||
|
||||
public static final Projection GALL_STEREOGRAPHIC = new Projection(
|
||||
"Gall Stereographic", Shape.rectangle(2*PI, 1.5*PI), 0b1111, Type.CYLINDRICAL,
|
||||
Property.COMPROMISE, 2) {
|
||||
"Gall Stereographic", "A compromise cylindrical projection",
|
||||
Shape.rectangle(2*PI, 1.5*PI), true, true, true, true,
|
||||
Type.CYLINDRICAL, Property.COMPROMISE, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
return new double[] {lon, tan(lat/2)*(1+sqrt(2))};
|
||||
@ -186,8 +189,9 @@ public class Cylindrical {
|
||||
|
||||
|
||||
public static final Projection MILLER = new Projection(
|
||||
"Miller", Shape.rectangle(2*PI, 2.5*log(tan(9*PI/20))), 0b1111, Type.CYLINDRICAL,
|
||||
Property.COMPROMISE, 2) {
|
||||
"Miller", "A compromise cylindrical projection",
|
||||
Shape.rectangle(2*PI, 2.5*log(tan(9*PI/20))), true, true, true, true,
|
||||
Type.CYLINDRICAL, Property.COMPROMISE, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
return new double[] {lon, log(tan(PI/4+.8*lat/2))/.8};
|
||||
@ -200,8 +204,8 @@ public class Cylindrical {
|
||||
|
||||
|
||||
public static final Projection CENTRAL = new Projection(
|
||||
"Central Cylindrical", Shape.rectangle(2*PI, 2*PI), 0b0111, Type.CYLINDRICAL,
|
||||
Property.PERSPECTIVE, 2) {
|
||||
"Central Cylindrical", "A projection used for architectural photography that is conflated with Mercator",
|
||||
Shape.rectangle(2*PI, 2*PI), true, false, true, true, Type.CYLINDRICAL, Property.PERSPECTIVE, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
return new double[] {lon, tan(lat)};
|
||||
|
||||
@ -54,37 +54,37 @@ public class Danseiji {
|
||||
|
||||
|
||||
public static final DanseijiProjection DANSEIJI_N = new DanseijiProjection(
|
||||
"Danseiji N", "The optimal conventional lenticular map.",
|
||||
"Danseiji N", "The optimal conventional lenticular map",
|
||||
true, Type.OTHER, Property.COMPROMISE, false, "danseijiN.csv");
|
||||
|
||||
|
||||
public static final DanseijiProjection DANSEIJI_I = new DanseijiProjection(
|
||||
"Danseiji I", "The optimal conventional equal-area map.",
|
||||
"Danseiji I", "The optimal conventional equal-area map",
|
||||
true, Type.OTHER, Property.COMPROMISE, false, "danseijiI.csv");
|
||||
|
||||
|
||||
public static final DanseijiProjection DANSEIJI_II = new DanseijiProjection(
|
||||
"Danseiji II", "An optimised map that gives more weight to shapes rather than sizes.",
|
||||
"Danseiji II", "An optimised map that gives more weight to shapes rather than sizes",
|
||||
true, Type.OTHER, Property.COMPROMISE, false, "danseijiII.csv");
|
||||
|
||||
|
||||
public static final DanseijiProjection DANSEIJI_III = new DanseijiProjection(
|
||||
"Danseiji III", "A map optimised to move distortion from the continents into the oceans. I recommend using the newer Elastic III instead.",
|
||||
"Danseiji III", "A map optimised to move distortion from the continents into the oceans. I recommend using the newer Elastic III instead",
|
||||
true, Type.OTHER, Property.COMPROMISE, true, "danseijiIII.csv");
|
||||
|
||||
|
||||
public static final DanseijiProjection DANSEIJI_IV = new DanseijiProjection(
|
||||
"Danseiji IV", "A map optimised to display landmasses accurately and without interruption. I recommend using the newer Elastic I instead.",
|
||||
"Danseiji IV", "A map optimised to display landmasses accurately and without interruption. I recommend using the newer Elastic I instead",
|
||||
true, Type.OTHER, Property.COMPROMISE, true, "danseijiIV.csv");
|
||||
|
||||
|
||||
public static final DanseijiProjection DANSEIJI_V = new DanseijiProjection(
|
||||
"Danseiji V", "A map optimised to show off the continents by compressing the oceans. I recommend using the newer Elastic III instead.",
|
||||
"Danseiji V", "A map optimised to show off the continents by compressing the oceans. I recommend using the newer Elastic III instead",
|
||||
true, Type.OTHER, Property.COMPROMISE, true, "danseijiV.csv");
|
||||
|
||||
|
||||
public static final DanseijiProjection DANSEIJI_VI = new DanseijiProjection(
|
||||
"Danseiji VI", "A compromise conventional map, where both physical area and population affect size.",
|
||||
"Danseiji VI", "A compromise conventional map, where both physical area and population affect size",
|
||||
true, Type.OTHER, Property.COMPROMISE, true, "danseijiVI.csv");
|
||||
|
||||
|
||||
@ -100,8 +100,8 @@ public class Danseiji {
|
||||
public DanseijiProjection(
|
||||
String title, String description, boolean interrupted, Type type, Property property,
|
||||
boolean basedOnLand, String filename) {
|
||||
super(title, description, null, interrupted ? 0b1010 : 0b1011, type, property, 3,
|
||||
new String[0], new double[0][], !basedOnLand);
|
||||
super(title, description, null, !interrupted, true, true, false, type, property, 3,
|
||||
new String[0], new double[0][], !basedOnLand);
|
||||
this.filename = filename;
|
||||
this.shape = null;
|
||||
}
|
||||
|
||||
@ -59,19 +59,19 @@ import static java.lang.String.format;
|
||||
public class Elastic {
|
||||
|
||||
public static final ElasticProjection ELASTIC_I = new ElasticProjection(
|
||||
"Elastic I", "A map optimised to display landmasses accurately and without interruption.",
|
||||
"Elastic I", "A map optimised to display landmasses accurately and without interruption",
|
||||
true, Type.OTHER, Property.COMPROMISE, true,
|
||||
"elastic-I.txt");
|
||||
|
||||
|
||||
public static final ElasticProjection ELASTIC_II = new ElasticProjection(
|
||||
"Elastic II", "A map optimised to display oceans and their drainage basins accurately and without interruption.",
|
||||
"Elastic II", "A map optimised to display oceans and their drainage basins accurately and without interruption",
|
||||
true, Type.OTHER, Property.COMPROMISE, true,
|
||||
"elastic-II.txt");
|
||||
|
||||
|
||||
public static final ElasticProjection ELASTIC_III = new ElasticProjection(
|
||||
"Elastic III", "A map optimised to show off the continents by compressing the oceans.",
|
||||
"Elastic III", "A map optimised to show off the continents by compressing the oceans",
|
||||
false, Type.OTHER, Property.COMPROMISE, true,
|
||||
"elastic-III.txt");
|
||||
|
||||
|
||||
@ -49,8 +49,8 @@ public class EqualEarth {
|
||||
|
||||
|
||||
public static final Projection EQUAL_EARTH = new Projection(
|
||||
"Equal Earth", null, 0b1111, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 3, null,
|
||||
"specifically designed to woo Gall-Peters supporters away from that horrid projection") {
|
||||
"Equal Earth", "An equal-area pseudocylindrical projection specifically designed to woo Gall-Peters supporters away from that horrid thing",
|
||||
null, true, true, true, true, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 3) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
double th = asin(B*sin(lat));
|
||||
|
||||
@ -42,19 +42,19 @@ public class Gyorffy {
|
||||
private static final double PI2M2 = pow(PI/2, -2);
|
||||
|
||||
public static final Projection B = new PolynomialProjection(
|
||||
"B", "The optimal pseudocylindrical projection.", 2,
|
||||
"B", "The optimal pseudocylindrical projection", 2,
|
||||
new double[] {0.75762, 2.00000, 4.63375, 0.00264, 1, 0, 0});
|
||||
|
||||
public static final Projection D = new PolynomialProjection(
|
||||
"D", "An optimal pointed-polar projection, with an emphasis on polar regions.", 3,
|
||||
"D", "An optimal pointed-polar projection, with an emphasis on polar regions", 3,
|
||||
new double[] {0.71416, 3.79209, 2, 0.00902, 0.87550, 0.01004, 0.00273});
|
||||
|
||||
public static final Projection E = new PolynomialProjection(
|
||||
"E", "The optimal pointed-polar projection.", 3,
|
||||
"E", "The optimal pointed-polar projection", 3,
|
||||
new double[] {0.74532, 2, 4.04753, 0.00730, 0.93884, 0.00271, 0.00450});
|
||||
|
||||
public static final Projection F = new PolynomialProjection(
|
||||
"F", "The optimal pointed-polar projection, with a rounded outline.", 4,
|
||||
"F", "The optimal pointed-polar projection, with a rounded outline", 4,
|
||||
new double[] {0.77172, 2, 3.26655, 0.00649, 0.88525, 0.00950, 0.00305});
|
||||
|
||||
|
||||
@ -65,8 +65,8 @@ public class Gyorffy {
|
||||
protected PolynomialProjection(
|
||||
String letter, String description,
|
||||
int rating, double[] coefs) {
|
||||
super("Gy\u00F6rffy "+letter, description,
|
||||
null, 0b1011, (coefs[4]==1 && coefs[5]==0 && coefs[6]==0) ? Type.PSEUDOCYLINDRICAL : Type.OTHER,
|
||||
super("Gy\u00F6rffy "+letter, description, null, true, true, true, false,
|
||||
(coefs[4]==1 && coefs[5]==0 && coefs[6]==0) ? Type.PSEUDOCYLINDRICAL : Type.OTHER,
|
||||
Property.COMPROMISE, rating);
|
||||
this.coefs = coefs;
|
||||
}
|
||||
|
||||
@ -56,8 +56,9 @@ import static utils.Math2.atan;
|
||||
public class Lenticular {
|
||||
|
||||
public static final Projection AITOFF = new Projection(
|
||||
"Aitoff", "A compromise projection shaped like an ellipse.",
|
||||
Shape.ellipse(Math.PI, Math.PI/2), 0b1111, Type.PSEUDOAZIMUTHAL, Property.COMPROMISE, 2) {
|
||||
"Aitoff", "A compromise projection shaped like an ellipse",
|
||||
Shape.ellipse(Math.PI, Math.PI/2), true, true, true, true,
|
||||
Type.PSEUDOAZIMUTHAL, Property.COMPROMISE, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
final double a = acos(cos(lat)*cos(lon/2));
|
||||
@ -77,8 +78,8 @@ public class Lenticular {
|
||||
|
||||
|
||||
public static final Projection HAMMER = new Projection(
|
||||
"Hammer", "An equal-area projection shaped like an ellipse.",
|
||||
Shape.ellipse(2, 1), 0b1111, Type.PSEUDOAZIMUTHAL, Property.EQUAL_AREA, 1) {
|
||||
"Hammer", "An equal-area projection shaped like an ellipse",
|
||||
Shape.ellipse(2, 1), true, true, true, true, Type.PSEUDOAZIMUTHAL, Property.EQUAL_AREA, 1) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
final double z = sqrt(1+cos(lat)*cos(lon/2));
|
||||
@ -96,8 +97,8 @@ public class Lenticular {
|
||||
|
||||
|
||||
public static final Projection VAN_DER_GRINTEN = new Projection(
|
||||
"Van der Grinten", "A circular compromise map that is popular for some reason.",
|
||||
Shape.circle(1), 0b1111, Type.OTHER, Property.COMPROMISE, 0) {
|
||||
"Van der Grinten", "A circular compromise map that is popular for some reason",
|
||||
Shape.circle(1), true, true, true, true, Type.OTHER, Property.COMPROMISE, 0) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
if (lat == 0) //special case 1: equator
|
||||
@ -138,8 +139,8 @@ public class Lenticular {
|
||||
|
||||
|
||||
public static final Projection STREBE_95 = new Projection(
|
||||
"Strebe 1995", "An equal-area map with curvy poles that pushes distortion to the edges.",
|
||||
null, 0b1100, Type.STREBE, Property.COMPROMISE, 2,
|
||||
"Strebe 1995", "An equal-area map with curvy poles that pushes distortion to the edges",
|
||||
null, true, true, false, true, Type.STREBE, Property.COMPROMISE, 2,
|
||||
new String[] {"Scale Factor"},
|
||||
new double[][] {{sqrt(2*PI/(4+PI)), sqrt((4+PI)/PI*2), 1.35}}) {
|
||||
|
||||
@ -178,7 +179,8 @@ public class Lenticular {
|
||||
|
||||
|
||||
public static final Projection BERTIN = new Projection(
|
||||
"Bertin", "An artistically conceived oblique map projection", Shape.ellipse(1.68, 1), 0b1011, Type.OTHER, Property.COMPROMISE, 3) {
|
||||
"Bertin", "An artistically conceived oblique map projection",
|
||||
Shape.ellipse(1.68, 1), true, true, true, false, Type.OTHER, Property.COMPROMISE, 3) {
|
||||
|
||||
private final double[] POLE = {toRadians(42), toRadians(-163.5), toRadians(180)};
|
||||
|
||||
@ -212,8 +214,8 @@ public class Lenticular {
|
||||
|
||||
|
||||
public static final Projection LAGRANGE = new Projection(
|
||||
"Lagrange", "A circular conformal map.",
|
||||
Shape.circle(1), 0b1111, Type.OTHER, Property.CONFORMAL, 2) {
|
||||
"Lagrange", "A circular conformal map",
|
||||
Shape.circle(1), true, true, true, true, Type.OTHER, Property.CONFORMAL, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
if (abs(lat) == PI/2)
|
||||
@ -239,8 +241,8 @@ public class Lenticular {
|
||||
|
||||
|
||||
public static final Projection EISENLOHR = new Projection(
|
||||
"Eisenlohr", "The optimal conventional conformal map.",
|
||||
null, 0b1011, Type.OTHER, Property.CONFORMAL, 2) {
|
||||
"Eisenlohr", "The optimal conventional conformal map",
|
||||
null, true, true, true, false, Type.OTHER, Property.CONFORMAL, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
if (abs(lat) == PI/2)
|
||||
@ -273,8 +275,8 @@ public class Lenticular {
|
||||
|
||||
|
||||
public static final Projection WAGNER_VIII = new Projection(
|
||||
"Wagner VIII", "A compromise projection with pseudoazimuthal energy.",
|
||||
null, 0b1111, Type.OTHER, Property.COMPROMISE, 3) {
|
||||
"Wagner VIII", "A compromise projection with pseudoazimuthal energy",
|
||||
null, true, true, true, true, Type.OTHER, Property.COMPROMISE, 3) {
|
||||
|
||||
private final double m1 = 0.92118, m2 = 0.8855, n = 3.,
|
||||
cX = 5.62290, cY = 2.61626;
|
||||
@ -309,8 +311,8 @@ public class Lenticular {
|
||||
|
||||
|
||||
public static final Projection POLYCONIC = new Projection(
|
||||
"American polyconic", "A map made for narrow strips of longitude that was really popular with the USGS for a while.",
|
||||
null, 0b1011, Type.OTHER, Property.EQUIDISTANT, 3) {
|
||||
"American polyconic", "A map made for narrow strips of longitude that was really popular with the USGS for a while",
|
||||
null, true, true, true, false, Type.OTHER, Property.EQUIDISTANT, 3) {
|
||||
public double[] project(double lat, double lon) {
|
||||
if (lat == 0)
|
||||
return new double[] {lon, 0};
|
||||
|
||||
@ -69,8 +69,8 @@ public class Misc {
|
||||
|
||||
public static final Projection PEIRCE_QUINCUNCIAL =
|
||||
new Projection(
|
||||
"Peirce Quincuncial", "A conformal projection that uses complex elliptic functions.",
|
||||
Shape.rectangle(2, 2), 0b1001, Type.OTHER, Property.CONFORMAL, 3) {
|
||||
"Peirce Quincuncial", "A conformal projection that uses complex elliptic functions",
|
||||
Shape.rectangle(2, 2), false, true, false, false, Type.OTHER, Property.CONFORMAL, 3) {
|
||||
|
||||
private static final double K_RT_HALF = 1.854074677; //this is approx K(sqrt(1/2))
|
||||
|
||||
@ -104,8 +104,8 @@ public class Misc {
|
||||
|
||||
public static final Projection GUYOU =
|
||||
new Projection(
|
||||
"Guyou", "Peirce Quincuncial, rearranged a bit.",
|
||||
Shape.rectangle(2, 1), 0b1001,
|
||||
"Guyou", "Peirce Quincuncial, rearranged a bit",
|
||||
Shape.rectangle(2, 1), false, true, false, false,
|
||||
Type.OTHER, Property.CONFORMAL, 3) {
|
||||
|
||||
private static final double K_RT_HALF = 1.854074677; //this is approx K(sqrt(1/2))
|
||||
@ -141,8 +141,8 @@ public class Misc {
|
||||
|
||||
public static final Projection HAMMER_RETROAZIMUTHAL =
|
||||
new Projection(
|
||||
"Hammer Retroazimuthal", "The full version of a map where bearing and distance to a reference point is preserved.",
|
||||
Shape.circle(Math.PI), 0b1110, Type.PSEUDOCONIC, Property.RETROAZIMUTHAL, 2,
|
||||
"Hammer Retroazimuthal", "The full version of a map where bearing and distance to a reference point is preserved",
|
||||
Shape.circle(Math.PI), false, true, true, true, Type.PSEUDOCONIC, Property.RETROAZIMUTHAL, 2,
|
||||
new String[] {"Latitude","Longitude"},
|
||||
new double[][] {{-89,89,21.4}, {-180,180,39.8}}, false) {
|
||||
|
||||
@ -195,8 +195,8 @@ public class Misc {
|
||||
|
||||
public static final Projection TWO_POINT_EQUIDISTANT =
|
||||
new Projection(
|
||||
"Two-point Equidistant", "A map that preserves distances, but not azimuths, to two arbitrary points.",
|
||||
null, 0b1111, Type.OTHER, Property.EQUIDISTANT, 3,
|
||||
"Two-point Equidistant", "A map that preserves distances, but not azimuths, to two arbitrary points",
|
||||
null, true, true, true, true, Type.OTHER, Property.EQUIDISTANT, 3,
|
||||
new String[] {"Latitude 1","Longitude 1","Latitude 2","Longitude 2"},
|
||||
new double[][] {{-90,90,41.9},{-180,180,12.5},{-90,90,34.7},{-180,180,112.4}},
|
||||
false) {
|
||||
@ -262,8 +262,8 @@ public class Misc {
|
||||
|
||||
public static final Projection BRAUN_CONIC =
|
||||
new Projection(
|
||||
"Braun conic", "A particular perspective conic that is tangent at 30\u00B0.",
|
||||
Shape.annularSector(0, 2*sqrt(3), PI, false), 0b1111,
|
||||
"Braun conic", "A particular perspective conic that is tangent at 30\u00B0",
|
||||
Shape.annularSector(0, 2*sqrt(3), PI, false), true, true, true, true,
|
||||
Type.CONIC, Property.PERSPECTIVE, 3) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
@ -288,8 +288,8 @@ public class Misc {
|
||||
|
||||
public static final Projection BONNE =
|
||||
new Projection(
|
||||
"Bonne", "A traditional pseudoconic projection, also known as the Sylvanus projection.",
|
||||
null, 0b1111, Type.PSEUDOCONIC, Property.EQUAL_AREA, 1,
|
||||
"Bonne", "A traditional pseudoconic projection, also known as the Sylvanus projection",
|
||||
null, true, true, true, true, Type.PSEUDOCONIC, Property.EQUAL_AREA, 1,
|
||||
new String[] {"Std. Parallel"}, new double[][] {{-90, 90, 45}}) {
|
||||
|
||||
private double r0;
|
||||
@ -355,7 +355,7 @@ public class Misc {
|
||||
|
||||
public static final Projection T_SHIRT =
|
||||
new Projection(
|
||||
"T-Shirt", "A conformal projection onto a torso.",
|
||||
"T-Shirt", "A conformal projection onto a torso",
|
||||
Shape.polygon(new double[][] {
|
||||
{ 0.000, 1.784},
|
||||
{-1.17, 2.38},
|
||||
@ -378,7 +378,7 @@ public class Misc {
|
||||
{ 2.500, 2.651},
|
||||
{ 1.17, 2.38},
|
||||
}),
|
||||
0b1001, Type.OTHER, Property.CONFORMAL, 3) {
|
||||
false, true, true, false, Type.OTHER, Property.CONFORMAL, 3) {
|
||||
|
||||
private final double[] X = {0, .507, .753, 1};
|
||||
private final double[] A = {.128, .084, .852, -.500};
|
||||
@ -414,7 +414,7 @@ public class Misc {
|
||||
|
||||
public static final Projection CASSINI = new Projection(
|
||||
"Cassini", "A transverse Plate–Carée projection",
|
||||
Shape.rectangle(PI, 2*PI), 0b1111, Type.CYLINDRICAL, Property.EQUIDISTANT, 2) {
|
||||
Shape.rectangle(PI, 2*PI), true, true, true, true, Type.CYLINDRICAL, Property.EQUIDISTANT, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
double x = asin(cos(lat)*sin(lon)); // I could use obliquifySph() and EQUIRECTANGULAR for this
|
||||
@ -431,8 +431,8 @@ public class Misc {
|
||||
|
||||
|
||||
public static final Projection LEMONS = new Projection(
|
||||
"Lemons", "BURN LIFE'S HOUSE DOWN!!!", null, 0b1110,
|
||||
Type.CYLINDRICAL, Property.COMPROMISE, 2) {
|
||||
"Gores", "A heavily interrupted projection that can be pasted onto a globe",
|
||||
null, false, true, true, true, Type.CYLINDRICAL, Property.COMPROMISE, 2) {
|
||||
|
||||
private static final int NUM_LEMONS = 12; //number of lemons
|
||||
private static final double LEMON_WIDTH = 2*PI/NUM_LEMONS; //longitude span of 1 lemon
|
||||
@ -491,7 +491,7 @@ public class Misc {
|
||||
|
||||
public static final Projection FLAT_EARTH =
|
||||
new Projection(
|
||||
"Flat Earth", "The one true map.", Shape.circle(1), 0b1111,
|
||||
"Flat Earth", "The one true map", Shape.circle(1), true, true, true, true,
|
||||
Type.PLANAR, Property.TRUE, 5, new String[0], new double[0][], false) {
|
||||
|
||||
private final double[] CORE_LONGITUDES = {
|
||||
|
||||
@ -47,9 +47,9 @@ import static java.lang.Math.toRadians;
|
||||
*/
|
||||
public class MyProjections {
|
||||
|
||||
public static final Projection TWO_POINT_EQUALIZED = new Projection("Two-Point Equalised",
|
||||
"A projection I invented specifically for viewing small elliptical regions of the Earth.",
|
||||
null, 0b1111, Type.OTHER, Property.EQUIDISTANT, 2,
|
||||
public static final Projection TWO_POINT_EQUALIZED = new Projection("Two-Point Equalized",
|
||||
"A projection I invented specifically for viewing small elliptical regions of the Earth",
|
||||
null, true, true, true, true, Type.OTHER, Property.EQUIDISTANT, 2,
|
||||
new String[] {"Width"}, new double[][] { {0, 180, 120} }) {
|
||||
|
||||
private double theta;
|
||||
|
||||
@ -59,7 +59,7 @@ public class Octohedral {
|
||||
public static final Projection CONFORMAL_CAHILL_FACE = new Projection(
|
||||
"Cahill Conformal (face)", "The conformal projection from an octant to an equilateral triangle",
|
||||
Shape.polygon(new double[][] {{0., 0.}, {0., -sqrt(3)/2.}, {1/2., -sqrt(3)/2.}}),
|
||||
0b1001, Projection.Type.OCTOHEDRAL, Property.CONFORMAL, 3) {
|
||||
true, true, false, false, Projection.Type.OCTOHEDRAL, Property.CONFORMAL, 3) {
|
||||
|
||||
private final double HEXAGON_SCALE = 1.112913; //this is 2^(2/3)/6*\int_0^\pi sin^(-1/3) x dx
|
||||
private final double TOLERANCE = 1e-3;
|
||||
@ -121,36 +121,36 @@ public class Octohedral {
|
||||
|
||||
|
||||
public static final OctohedralProjection CONFORMAL_CAHILL_BUTTERFLY = new OctohedralProjection(
|
||||
"Cahill Conformal", "The conformal and only reproducible variant of Cahill's original map.",
|
||||
0, 0b1000, Property.CONFORMAL, 3, CONFORMAL_CAHILL_FACE, Configuration.BUTTERFLY);
|
||||
"Cahill Conformal", "The conformal and only reproducible variant of Cahill's original map",
|
||||
0, Property.CONFORMAL, 3, CONFORMAL_CAHILL_FACE, Configuration.BUTTERFLY);
|
||||
|
||||
|
||||
public static final Projection CAHILL_CONCIALDI = new OctohedralProjection(
|
||||
"Cahill\u2013Concialdi", "A conformal octohedral projection with no extra cuts and a unique arrangement.",
|
||||
0, 0b1000, Property.CONFORMAL, 4, CONFORMAL_CAHILL_FACE, Configuration.BAT_SHAPE);
|
||||
"Cahill\u2013Concialdi", "A conformal octohedral projection with no extra cuts and a unique arrangement",
|
||||
0, Property.CONFORMAL, 4, CONFORMAL_CAHILL_FACE, Configuration.BAT_SHAPE);
|
||||
|
||||
|
||||
public static final Projection WATERMAN = new OctohedralProjection(
|
||||
"Waterman Butterfly", "A simple Cahill-esque octohedral map arrangement, with Antarctica left on.",
|
||||
(sqrt(3)-1)/8, 0b1010, Property.COMPROMISE, 3,
|
||||
"Waterman Butterfly", "A simple Cahill-esque octohedral map arrangement, with Antarctica left on",
|
||||
(sqrt(3)-1)/8, Property.COMPROMISE, 3,
|
||||
Waterman.FACE, Configuration.BUTTERFLY);
|
||||
|
||||
|
||||
public static final Projection KEYES_BASIC_M = new OctohedralProjection(
|
||||
"Cahill\u2013Keyes (simplified)", "A simple M-shaped octohedral projection, with Antarctica broken into three pieces.",
|
||||
CahillKeyes.POLE_OFFSET, 0b1010, Property.COMPROMISE, 3,
|
||||
"Cahill\u2013Keyes (simplified)", "A simple M-shaped octohedral projection, with Antarctica broken into three pieces",
|
||||
CahillKeyes.POLE_OFFSET, Property.COMPROMISE, 3,
|
||||
CahillKeyes.FACE, Configuration.M_PROFILE);
|
||||
|
||||
|
||||
public static final Projection KEYES_STANDARD = new OctohedralProjection(
|
||||
"Cahill\u2013Keyes", "An M-shaped octohedral projection with Antarctica assembled in the center.",
|
||||
CahillKeyes.POLE_OFFSET, 0b1010, Property.COMPROMISE, 4,
|
||||
"Cahill\u2013Keyes", "An M-shaped octohedral projection with Antarctica assembled in the center",
|
||||
CahillKeyes.POLE_OFFSET, Property.COMPROMISE, 4,
|
||||
CahillKeyes.FACE, Configuration.M_W_S_POLE);
|
||||
|
||||
|
||||
public static final Projection KEYES_OCTANT = new OctohedralProjection(
|
||||
"Cahill\u2013Keyes (single octant)", "A single octant of the Cahill\u2013Keyes projection (for memory economization in the case of very large maps).",
|
||||
CahillKeyes.POLE_OFFSET, 0b1010, Property.COMPROMISE, 3,
|
||||
"Cahill\u2013Keyes (single octant)", "A single octant of the Cahill\u2013Keyes projection (for memory economization in the case of very large maps)",
|
||||
CahillKeyes.POLE_OFFSET, Property.COMPROMISE, 3,
|
||||
CahillKeyes.FACE, Configuration.SINGLE_OCTANT);
|
||||
|
||||
|
||||
@ -162,9 +162,9 @@ public class Octohedral {
|
||||
|
||||
|
||||
public OctohedralProjection(String name, String desc, double tipOffset,
|
||||
int fisc, Property property, int rating,
|
||||
Property property, int rating,
|
||||
Projection faceProj, Configuration config) {
|
||||
super(name, desc, null, fisc,
|
||||
super(name, desc, null, false, config.finite, faceProj.isSolveable(), faceProj.isInvertable(),
|
||||
(tipOffset == 0) ? Type.OCTOHEDRAL : Type.TETRADECAHEDRAL, property, rating,
|
||||
new String[] {}, new double[][] {}, config.hasAspect);
|
||||
this.octants = config.placeOctants(tipOffset);
|
||||
@ -233,7 +233,7 @@ public class Octohedral {
|
||||
private enum Configuration {
|
||||
|
||||
/** the classic four quadrants splayed out in a nice butterfly shape, with Antarctica divided and attached */
|
||||
BUTTERFLY(true) {
|
||||
BUTTERFLY(true, true) {
|
||||
Octant[] placeOctants(double tipOffset) {
|
||||
return new Octant[] {
|
||||
new Octant(0, 0, -PI/2, -PI/2, PI/2, -3*PI/4),
|
||||
@ -259,7 +259,7 @@ public class Octohedral {
|
||||
},
|
||||
|
||||
/** The more compact zigzag configuration with Antarctica divided and attached */
|
||||
M_PROFILE(true) {
|
||||
M_PROFILE(true, true) {
|
||||
Octant[] placeOctants(double tipOffset) {
|
||||
return new Octant[] {
|
||||
new Octant(-sqrt(3)/2, 0, -PI/6, -PI/2, PI/2, -3*PI/4),
|
||||
@ -285,7 +285,7 @@ public class Octohedral {
|
||||
},
|
||||
|
||||
/** Gene Keyes's current configuration, with Antarctica reassembled in the center */
|
||||
M_W_S_POLE(false) {
|
||||
M_W_S_POLE(true, false) {
|
||||
Octant[] placeOctants(double tipOffset) {
|
||||
double xSouthPole = -tipOffset/2.;
|
||||
double ySouthPole = -1.5 + tipOffset*sqrt(3)/2.;
|
||||
@ -336,7 +336,7 @@ public class Octohedral {
|
||||
},
|
||||
|
||||
/** Luca Concialdi's "Bat" arrangement */
|
||||
BAT_SHAPE(false) {
|
||||
BAT_SHAPE(true, false) {
|
||||
Octant[] placeOctants(double tipOffset) {
|
||||
return rotateOctants(toRadians(5), new Octant[]{
|
||||
new Octant( 0.0, 0.0 , -2*PI/3, 0 , PI/2, toRadians(-160), toRadians(-9), 1), // Alaska
|
||||
@ -374,7 +374,7 @@ public class Octohedral {
|
||||
},
|
||||
|
||||
/** an octohedron that actually only covers the positive octant, in case you want to do each octant separately */
|
||||
SINGLE_OCTANT(true) {
|
||||
SINGLE_OCTANT(false, true) {
|
||||
Octant[] placeOctants(double tipOffset) {
|
||||
return new Octant[]{
|
||||
new Octant(0.0, 0.0, PI/6, 0, PI/2, PI/4),
|
||||
@ -396,12 +396,15 @@ public class Octohedral {
|
||||
}
|
||||
};
|
||||
|
||||
public final boolean finite;
|
||||
public final boolean hasAspect;
|
||||
|
||||
/**
|
||||
* @param finite whether there are enuff octants to project every part of the earth
|
||||
* @param hasAspect whether it would make any sense to change the aspect
|
||||
*/
|
||||
Configuration(boolean hasAspect) {
|
||||
Configuration(boolean finite, boolean hasAspect) {
|
||||
this.finite = finite;
|
||||
this.hasAspect = hasAspect;
|
||||
}
|
||||
|
||||
|
||||
@ -58,8 +58,8 @@ import static utils.Math2.floorMod;
|
||||
public class Polyhedral {
|
||||
|
||||
public static final PolyhedralProjection LEE_TETRAHEDRAL_RECTANGULAR = new PolyhedralProjection(
|
||||
"Lee Tetrahedral", 0b1001, Polyhedron.TETRAHEDRON_WIDE_FACE, Property.CONFORMAL,
|
||||
4, null, "that really deserves more attention") {
|
||||
"Lee Tetrahedral", "A conformal tetrahedral projection that really deserves more attention",
|
||||
true, false, false, Polyhedron.TETRAHEDRON_WIDE_FACE, Property.CONFORMAL, 4) {
|
||||
|
||||
public double[] faceProject(double lat, double lon) {
|
||||
final de.jtem.mfc.field.Complex z = de.jtem.mfc.field.Complex.fromPolar(
|
||||
@ -80,9 +80,8 @@ public class Polyhedral {
|
||||
|
||||
|
||||
public static final PolyhedralProjection LEE_TETRAHEDRAL_TRIANGULAR = new PolyhedralProjection(
|
||||
"Lee Tetrahedral (triangular)", 0b1001, Polyhedron.TRIANGLE_FACE, Property.CONFORMAL,
|
||||
2, null,
|
||||
"in a triangle, because this is the form in which it was published, even though the rectangle is clearly better") {
|
||||
"Lee Tetrahedral (triangular)", "A conformal tetrahedral projection in a triangle, because this is the form in which it was published, even though the rectangle is clearly better",
|
||||
true, false, false, Polyhedron.TRIANGLE_FACE, Property.CONFORMAL, 2) {
|
||||
|
||||
public double[] faceProject(double lat, double lon) {
|
||||
return LEE_TETRAHEDRAL_RECTANGULAR.faceProject(lat, lon);
|
||||
@ -95,8 +94,8 @@ public class Polyhedral {
|
||||
|
||||
|
||||
public static final PolyhedralProjection TETRAGRAPH = new PolyhedralProjection(
|
||||
"TetraGraph", 0b1111, Polyhedron.TETRAHEDRON_WIDE_FACE, Property.EQUIDISTANT,
|
||||
2, null, "that I invented") {
|
||||
"TetraGraph", "An equidistant tetrahedral projection that I invented",
|
||||
true, true, true, Polyhedron.TETRAHEDRON_WIDE_FACE, Property.EQUIDISTANT, 2) {
|
||||
|
||||
public double[] faceProject(double lat, double lon) {
|
||||
return new double[] {
|
||||
@ -113,10 +112,11 @@ public class Polyhedral {
|
||||
|
||||
|
||||
public static final PolyhedralProjection AUTHAGRAPH = new PolyhedralProjection(
|
||||
"IMAGO (AuthaGraph)", "Authagraph is a hip new Japanese map that would be super great if "
|
||||
+ "they actually published their equations. This is technically just an approximation, also known as the Infinitessimal "
|
||||
+ "Mutated AuthaGraph Offspring.",
|
||||
0b1011, Polyhedron.AUTHAGRAPH, Property.COMPROMISE, 3,
|
||||
"IMAGO (AuthaGraph)",
|
||||
"Authagraph is a hip new Japanese map that would be super great if they actually " +
|
||||
"published their equations. This is technically just an approximation, also known as " +
|
||||
"the Infinitessimal Mutated AuthaGraph Offspring.",
|
||||
true, true, false, Polyhedron.AUTHAGRAPH, Property.COMPROMISE, 3,
|
||||
new String[] {"Power"}, new double[][] {{.5,1,.68}}) {
|
||||
|
||||
private final double[] POLE = {toRadians(77), toRadians(143), toRadians(17)};
|
||||
@ -157,8 +157,8 @@ public class Polyhedral {
|
||||
|
||||
|
||||
public static final PolyhedralProjection AUTHAPOWER = new PolyhedralProjection(
|
||||
"TetraPower", "A parametrised, simplified version of my AuthaGraph approximation.",
|
||||
0b1011, Polyhedron.TETRAHEDRON_WIDE_VERTEX, Property.COMPROMISE, 4,
|
||||
"TetraPower", "A parametrised, simplified version of my AuthaGraph approximation",
|
||||
true, true, false, Polyhedron.TETRAHEDRON_WIDE_VERTEX, Property.COMPROMISE, 4,
|
||||
new String[] {"Power"}, new double[][] {{.5,1,.6}}) {
|
||||
|
||||
private double k;
|
||||
@ -186,8 +186,8 @@ public class Polyhedral {
|
||||
|
||||
|
||||
public static final PolyhedralProjection ACTUAUTHAGRAPH = new PolyhedralProjection(
|
||||
"EquaHedral", "An interrupted authalic tetrahedral projection.",
|
||||
0b1010, Polyhedron.TETRAHEDRON_WIDE_VERTEX, Property.EQUAL_AREA, 3,
|
||||
"EquaHedral", "An interrupted authalic tetrahedral projection",
|
||||
true, true, false, Polyhedron.TETRAHEDRON_WIDE_VERTEX, Property.EQUAL_AREA, 3,
|
||||
new String[] {"Sinus length"}, new double[][] {{0, 60, 20}}) {
|
||||
|
||||
private double sig, a0, scale;
|
||||
@ -251,8 +251,12 @@ public class Polyhedral {
|
||||
|
||||
|
||||
public static final Projection VAN_LEEUWEN = new PolyhedralProjection(
|
||||
"Van Leeuwen", "An uninterrupted equal-area tetrahedral projection. It's more accurately known as \"the Vertex-oriented great circle projection applied to a tetrahedron\", but the guy who copublished it with Leeuwen calls it \"the van Leeuwen projection\" on his website, so I think this is fine.",
|
||||
0b1011, Polyhedron.TETRAHEDRON_WIDE_VERTEX, Property.EQUAL_AREA, 2) {
|
||||
"Van Leeuwen",
|
||||
"An uninterrupted equal-area tetrahedral projection. It's more accurately known as " +
|
||||
"\"the Vertex-oriented great circle projection applied to a tetrahedron\", but the " +
|
||||
"guy who copublished it with Leeuwen calls it \"the van Leeuwen projection\" on his " +
|
||||
"website, so I think this is fine.",
|
||||
true, true, false, Polyhedron.TETRAHEDRON_WIDE_VERTEX, Property.EQUAL_AREA, 2) {
|
||||
|
||||
public double[] faceProject(double lat, double lon) {
|
||||
ACTUAUTHAGRAPH.initialize(0);
|
||||
@ -267,8 +271,8 @@ public class Polyhedral {
|
||||
|
||||
|
||||
public static final Projection DYMAXION = new PolyhedralProjection(
|
||||
"Dymaxion", "A polyhedral projection that slices up the oceans as much as possible without slicing up any landmasses.",
|
||||
0b1110, Polyhedron.DYMAXION, Property.COMPROMISE, 3) {
|
||||
"Dymaxion", "A polyhedral projection that slices up the oceans as much as possible without slicing up any landmasses",
|
||||
true, true, true, Polyhedron.DYMAXION, Property.COMPROMISE, 3) {
|
||||
|
||||
private final double[] POLE = {0.040158, -0.091549,-2.015269}; //I derived these numbers from [Robert Gray](http://www.rwgrayprojects.com/rbfnotes/maps/graymap4.html)
|
||||
|
||||
@ -326,26 +330,19 @@ public class Polyhedral {
|
||||
|
||||
|
||||
public PolyhedralProjection(
|
||||
String name, int fisc, Polyhedron config, Property property, int rating,
|
||||
String adjective, String addendum) {
|
||||
super(name, config.shape, fisc, config.type, property, rating,
|
||||
adjective, addendum);
|
||||
String name, String description, boolean finite, boolean solvable,
|
||||
boolean invertible, Polyhedron config, Property property, int rating) {
|
||||
super(name, description, config.shape, false, finite, solvable, invertible,
|
||||
config.type, property, rating);
|
||||
this.configuration = config;
|
||||
}
|
||||
|
||||
public PolyhedralProjection(
|
||||
String name, String description, int fisc, Polyhedron config, Property property,
|
||||
int rating) {
|
||||
super(name, description, config.shape, fisc, config.type, property,
|
||||
rating);
|
||||
this.configuration = config;
|
||||
}
|
||||
|
||||
public PolyhedralProjection(
|
||||
String name, String description, int fisc, Polyhedron config, Property property,
|
||||
String name, String description, boolean finite,
|
||||
boolean solvable, boolean invertible, Polyhedron config, Property property,
|
||||
int rating, String[] paramNames, double[][] paramValues) {
|
||||
super(name, description, config.shape, fisc, config.type, property,
|
||||
rating, paramNames, paramValues);
|
||||
super(name, description, config.shape, false, finite, solvable, invertible,
|
||||
config.type, property, rating, paramNames, paramValues);
|
||||
this.configuration = config;
|
||||
}
|
||||
|
||||
|
||||
@ -68,63 +68,34 @@ public abstract class Projection {
|
||||
private final double[][] paramValues; //the bounds and default value of each parameter
|
||||
private final boolean hasAspect; //is it spherically symmetrical?
|
||||
|
||||
private final boolean continuous; //is the interruption kept to no more than one meridian's equivalent?
|
||||
private final boolean finite; //does it display the entire world?
|
||||
private final boolean invertable; //is the inverse solution closed-form?
|
||||
private final boolean solveable; //is the solution closed-form?
|
||||
private final boolean continuous; //does a random continuous path cross outside of the map?
|
||||
private final boolean invertable; //is the inverse solution closed-form?
|
||||
private final Type type; //the geometry of the projection
|
||||
private final Property property; //what it is good for
|
||||
private final int rating; //how good I think it is
|
||||
protected Shape shape; //bounding shape
|
||||
|
||||
|
||||
|
||||
protected Projection(
|
||||
String name, Shape shape, int fisc, Type type, Property property, int rating) {
|
||||
this(name, buildDescription(type,property,null,null),
|
||||
shape, fisc, type, property, rating, new String[0], new double[0][]);
|
||||
}
|
||||
|
||||
protected Projection(
|
||||
String name, Shape shape, int fisc, Type type, Property property,
|
||||
int rating, String adjective) {
|
||||
this(name, buildDescription(type,property,adjective,null), shape,
|
||||
fisc, type, property, rating, new String[0], new double[0][]); // TODO: I hate these constructors. I don't need so many of them.
|
||||
}
|
||||
|
||||
protected Projection(
|
||||
String name, Shape shape, int fisc, Type type, Property property,
|
||||
int rating, String adjective, String addendum) {
|
||||
this(name, buildDescription(type,property,adjective,addendum), shape,
|
||||
fisc, type, property, rating, new String[0], new double[0][]);
|
||||
}
|
||||
|
||||
protected Projection(
|
||||
String name, String description, Shape shape, int fisc,
|
||||
Type type, Property property, int rating) {
|
||||
this(name, description, shape, fisc, type, property, rating,
|
||||
String name, String description, Shape shape, boolean continuous, boolean finite,
|
||||
boolean solvable, boolean invertible, Type type, Property property, int rating) {
|
||||
this(name, description, shape, continuous, finite, solvable, invertible, type, property, rating,
|
||||
new String[0], new double[0][]);
|
||||
}
|
||||
|
||||
protected Projection(
|
||||
String name, String description, Shape shape, int fisc, Type type,
|
||||
Property property, int rating, String[] paramNames, double[][] paramValues) {
|
||||
this(name, description, shape, fisc, type, property, rating,
|
||||
String name, String description, Shape shape, boolean continuous, boolean finite,
|
||||
boolean solveable, boolean invertable, Type type, Property property, int rating,
|
||||
String[] paramNames, double[][] paramValues) {
|
||||
this(name, description, shape, continuous, finite, solveable, invertable, type, property, rating,
|
||||
paramNames, paramValues, true);
|
||||
}
|
||||
|
||||
protected Projection(
|
||||
String name, String description, Shape shape, int fisc, Type type,
|
||||
Property property, int rating, String[] paramNames, double[][] paramValues,
|
||||
boolean hasAspect) {
|
||||
this(name, description, shape,
|
||||
(fisc&0b1000) > 0, (fisc&0b0100) > 0, (fisc&0b0010) > 0, (fisc&0b0001) > 0,
|
||||
type, property, rating, paramNames, paramValues, hasAspect);
|
||||
}
|
||||
|
||||
protected Projection (
|
||||
String name, String description, Shape shape,
|
||||
boolean finite, boolean invertable, boolean solveable, boolean continuous, Type type, Property property, int rating,
|
||||
String name, String description, Shape shape, boolean continuous, boolean finite,
|
||||
boolean solveable, boolean invertable, Type type, Property property, int rating,
|
||||
String[] paramNames, double[][] paramValues, boolean hasAspect) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
@ -132,10 +103,10 @@ public abstract class Projection {
|
||||
this.paramValues = paramValues;
|
||||
this.hasAspect = hasAspect;
|
||||
this.shape = shape;
|
||||
this.finite = finite;
|
||||
this.invertable = invertable;
|
||||
this.solveable = solveable;
|
||||
this.continuous = continuous;
|
||||
this.finite = finite;
|
||||
this.solveable = solveable;
|
||||
this.invertable = invertable;
|
||||
this.type = type;
|
||||
this.property = property;
|
||||
this.rating = rating;
|
||||
@ -147,18 +118,6 @@ public abstract class Projection {
|
||||
base.paramNames, base.paramValues, base.hasAspect);
|
||||
}
|
||||
|
||||
private static String buildDescription(Type type, Property property, String adjective, String addendum) { //these should all be lowercase
|
||||
String description = property+" "+type+" projection";
|
||||
if (adjective != null)
|
||||
description = adjective+" "+description;
|
||||
if (addendum != null)
|
||||
description += " "+addendum;
|
||||
if (description.charAt(0) == 'a' || description.charAt(0) == 'e' || description.charAt(0) == 'i' || description.charAt(0) == 'o' || description.charAt(0) == 'u')
|
||||
return "An "+description+".";
|
||||
else
|
||||
return "A "+description+".";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* convert a location on the globe to a location on the map plane
|
||||
@ -710,7 +669,7 @@ public abstract class Projection {
|
||||
}
|
||||
|
||||
public static final Projection NULL_PROJECTION = //this exists solely for the purpose of a "More..." option at the end of menus. ah, if only enums were as powerful in Java as they are in Rust.
|
||||
new Projection("More...", null, null, 0, null, null, 0) {
|
||||
new Projection("More...", null, null, false, false, false, false, null, null, 0) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
return null;
|
||||
|
||||
@ -51,8 +51,8 @@ import static java.lang.Math.toRadians;
|
||||
public class Pseudocylindrical {
|
||||
|
||||
public static final Projection SINUSOIDAL = new Projection(
|
||||
"Sinusoidal", "An equal-area map shaped like a sine-wave.",
|
||||
null, 0b1111, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 1) {
|
||||
"Sinusoidal", "An equal-area map shaped like a sine-wave",
|
||||
null, true, true, true, true, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 1) {
|
||||
public void initialize(double... params) {
|
||||
this.shape = Shape.meridianEnvelope(this);
|
||||
}
|
||||
@ -68,8 +68,9 @@ public class Pseudocylindrical {
|
||||
|
||||
|
||||
public static final Projection MOLLWEIDE = new Projection(
|
||||
"Mollweide", "An equal-area projection shaped like an ellipse.",
|
||||
Shape.ellipse(2, 1), 0b1101, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 3) {
|
||||
"Mollweide", "An equal-area projection shaped like an ellipse",
|
||||
Shape.ellipse(2, 1), true, true, false, true,
|
||||
Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 3) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
double tht = NumericalAnalysis.newtonRaphsonApproximation(
|
||||
@ -91,8 +92,8 @@ public class Pseudocylindrical {
|
||||
|
||||
|
||||
public static final Projection HOMOLOSINE = new Projection(
|
||||
"Homolosine (uninterrupted)", "A combination of the sinusoidal and Mollweide projections.",
|
||||
null, 0b1101, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 3) {
|
||||
"Homolosine (uninterrupted)", "A combination of the sinusoidal and Mollweide projections",
|
||||
null, true, true, false, true, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 3) {
|
||||
|
||||
private final double phiH = 0.71098;
|
||||
private final double scale = sqrt(2);
|
||||
@ -127,8 +128,8 @@ public class Pseudocylindrical {
|
||||
|
||||
|
||||
public static final Projection HOMOLOSINE_INTERRUPTED = new Projection(
|
||||
"Goode Homolosine", "An interrupted combination of the sinusoidal and Mollweide projections.",
|
||||
null, 0b1100, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 3) {
|
||||
"Goode Homolosine", "An interrupted combination of the sinusoidal and Mollweide projections",
|
||||
null, false, true, false, true, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 3) {
|
||||
|
||||
private final double[][] edges = {
|
||||
{toRadians(-40), toRadians(180)},
|
||||
@ -194,14 +195,14 @@ public class Pseudocylindrical {
|
||||
|
||||
|
||||
public static final Projection ECKERT_IV = new Projection(
|
||||
"Eckert IV", "An equal-area projection released in a set of six (I'm only giving you the one because the others are not good).",
|
||||
"Eckert IV", "An equal-area projection released in a set of six (I'm only giving you the one because the others are not good)",
|
||||
new Shape(-2, 2, -1, 1, List.of(
|
||||
new Path.Command('M', -1, 1),
|
||||
new Path.Command('A', 1, 1, 0, 0, 1, -1, -1),
|
||||
new Path.Command('L', 1, -1),
|
||||
new Path.Command('A', 1, 1, 0, 0, 1, 1, 1),
|
||||
new Path.Command('Z'))),
|
||||
0b1101, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 3) {
|
||||
true, true, false, true, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 3) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
double tht = NumericalAnalysis.newtonRaphsonApproximation(
|
||||
@ -222,8 +223,8 @@ public class Pseudocylindrical {
|
||||
|
||||
|
||||
public static final Projection WAGNER_II = new Projection(
|
||||
"Wagner II", "A compromise projection with sinusoidal meridians.",
|
||||
null, 0b1111, Type.OTHER, Property.COMPROMISE, 2) {
|
||||
"Wagner II", "A compromise projection with sinusoidal meridians",
|
||||
null, true, true, true, true, Type.OTHER, Property.COMPROMISE, 2) {
|
||||
public void initialize(double... params) {
|
||||
this.shape = Shape.meridianEnvelope(this);
|
||||
}
|
||||
@ -244,8 +245,8 @@ public class Pseudocylindrical {
|
||||
|
||||
|
||||
public static final Projection WAGNER_V = new Projection(
|
||||
"Wagner V", "A compromise projection with elliptical meridians.",
|
||||
null, 0b1111, Type.OTHER, Property.COMPROMISE, 3) {
|
||||
"Wagner V", "A compromise projection with elliptical meridians",
|
||||
null, true, true, true, true, Type.OTHER, Property.COMPROMISE, 3) {
|
||||
public void initialize(double... params) {
|
||||
this.shape = Shape.meridianEnvelope(this);
|
||||
}
|
||||
@ -268,8 +269,8 @@ public class Pseudocylindrical {
|
||||
|
||||
|
||||
public static final Projection KAVRAYSKIY_VII = new Projection(
|
||||
"Kavrayskiy VII", null, 0b1111, Type.PSEUDOCYLINDRICAL,
|
||||
Property.COMPROMISE, 2, null, "mostly popular in the former Soviet Union") {
|
||||
"Kavrayskiy VII", "A compromise pseudocylindrical projection mostly popular in the former Soviet Union",
|
||||
null, true, true, true, true, Type.PSEUDOCYLINDRICAL, Property.COMPROMISE, 2) {
|
||||
public void initialize(double... params) {
|
||||
this.shape = Shape.meridianEnvelope(this);
|
||||
}
|
||||
|
||||
@ -60,7 +60,8 @@ public class Snyder {
|
||||
|
||||
public static final Projection GS50 =
|
||||
new Projection(
|
||||
"GS50", "'MURKA!", Shape.rectangle(1.6, 1.1), 0b0011, Type.POLYNOMIAL, Property.CONFORMAL, 4,
|
||||
"GS50", "America!", Shape.rectangle(1.6, 1.1), true, false, true, false,
|
||||
Type.POLYNOMIAL, Property.CONFORMAL, 4,
|
||||
new String[] {}, new double[][] {}, false) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
|
||||
@ -40,7 +40,7 @@ import static java.lang.Math.sin;
|
||||
import static utils.Math2.linInterp;
|
||||
|
||||
/**
|
||||
* A class of values and functions used to approximate the Tobler projection
|
||||
* A class of values and functions used to approximate the Tobler hyperelliptical projection
|
||||
*
|
||||
* @author jkunimune
|
||||
*/
|
||||
@ -48,8 +48,8 @@ public class Tobler {
|
||||
|
||||
public static final Projection TOBLER =
|
||||
new Projection(
|
||||
"Tobler hyperelliptical", "An equal-area projection shaped like a hyperellipse.",
|
||||
null, 0b1001, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 4,
|
||||
"Tobler hyperelliptical", "An equal-area projection shaped like a hyperellipse",
|
||||
null, true, true, false, false, Type.PSEUDOCYLINDRICAL, Property.EQUAL_AREA, 4,
|
||||
new String[]{"alpha","K"},
|
||||
new double[][] {{0,1,0.0}, {1,5,2.5}}) {
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ public class Waterman {
|
||||
public static Projection FACE = new Projection(
|
||||
"Waterman (face)", "A single face of Waterman's octohedral projection",
|
||||
Shape.polygon(new double[][] {{0., 0.}, {0., -sqrt(3)/2.}, {1/2., -sqrt(3)/2.}}),
|
||||
0b1011, Type.OTHER, Property.COMPROMISE, 2) {
|
||||
true, true, true, false, Type.OTHER, Property.COMPROMISE, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
double[] xELD = jointPositions(lon);
|
||||
|
||||
@ -56,8 +56,8 @@ import static java.lang.Math.toRadians;
|
||||
public final class WinkelTripel {
|
||||
|
||||
public static final Projection WINKEL_TRIPEL =
|
||||
new Projection("Winkel Tripel", "National Geographic's compromise projection of choice.",
|
||||
null, 0b1011, Type.OTHER, Property.COMPROMISE, 3,
|
||||
new Projection("Winkel Tripel", "National Geographic's compromise projection of choice",
|
||||
null, true, true, true, false, Type.OTHER, Property.COMPROMISE, 3,
|
||||
new String[] {"Std. Parallel"}, new double[][] {{0, 90, toDegrees(acos(2/PI))}}) {
|
||||
|
||||
private double stdParallel;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user