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:
Justin Kunimune 2023-12-13 08:23:23 -08:00
parent 3befac6590
commit 0ca637928d
20 changed files with 208 additions and 237 deletions

View File

@ -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);

View File

@ -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}}) {

View File

@ -77,7 +77,7 @@ public class CahillKeyes {
public static Projection FACE = new Projection(
"CahillKeyes (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

View File

@ -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) {

View File

@ -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)};

View File

@ -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;
}

View File

@ -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");

View File

@ -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));
@ -62,7 +62,7 @@ public class EqualEarth {
y, y/Y_SCALE, EqualEarth::poly9, EqualEarth::poly8, 1e-6);
return new double[] { asin(sin(th)/B), x*B/cos(th)*poly8(th) };
}
public void initialize(double... params) throws IllegalArgumentException {
this.shape = Shape.meridianEnvelope(this);
}

View File

@ -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;
}

View File

@ -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};

View File

@ -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 PlateCaré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 = {

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
@ -146,18 +117,6 @@ public abstract class Projection {
base.solveable, base.continuous, base.type, base.property, base.rating,
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+".";
}
/**
@ -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;

View File

@ -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);
}

View File

@ -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) {

View File

@ -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}}) {

View File

@ -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);

View File

@ -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;