mirror of
https://github.com/csharpee/Map-Projections.git
synced 2025-12-17 00:00:19 -05:00
Rectangles are for squares
I changed the Arbitrary maps to account for a change in file format in my Rubber-Earth repo, specifically with respect to the addition of a raster map (which I have yet to implement) and non-rectangular cells. I've got it all nice and smooth, and now it's on to raster maps!
This commit is contained in:
parent
bcf925b2a7
commit
f7d6d6ca70
@ -115,7 +115,7 @@ public abstract class MapApplication extends Application {
|
|||||||
private static final KeyCombination CTRL_ENTER = new KeyCodeCombination(KeyCode.ENTER, KeyCodeCombination.CONTROL_DOWN);
|
private static final KeyCombination CTRL_ENTER = new KeyCodeCombination(KeyCode.ENTER, KeyCodeCombination.CONTROL_DOWN);
|
||||||
|
|
||||||
|
|
||||||
public static final Projection[] FEATURED_PROJECTIONS = { Arbitrary.DANSEIJI_O, Arbitrary.DANSEIJI_I, Arbitrary.DANSEIJI_II, Arbitrary.DANSEIJI_III, Arbitrary.DANSEIJI_IV, Cylindrical.MERCATOR,
|
public static final Projection[] FEATURED_PROJECTIONS = { Arbitrary.DANSEIJI_III, Arbitrary.DANSEIJI_IV, Cylindrical.MERCATOR,
|
||||||
Cylindrical.EQUIRECTANGULAR, Cylindrical.EQUAL_AREA, Cylindrical.GALL_STEREOGRAPHIC,
|
Cylindrical.EQUIRECTANGULAR, Cylindrical.EQUAL_AREA, Cylindrical.GALL_STEREOGRAPHIC,
|
||||||
Azimuthal.STEREOGRAPHIC, Azimuthal.POLAR, Azimuthal.EQUAL_AREA, Azimuthal.GNOMONIC,
|
Azimuthal.STEREOGRAPHIC, Azimuthal.POLAR, Azimuthal.EQUAL_AREA, Azimuthal.GNOMONIC,
|
||||||
Azimuthal.PERSPECTIVE, Conic.LAMBERT, Conic.EQUIDISTANT, Conic.ALBERS,
|
Azimuthal.PERSPECTIVE, Conic.LAMBERT, Conic.EQUIDISTANT, Conic.ALBERS,
|
||||||
@ -555,7 +555,11 @@ public abstract class MapApplication extends Application {
|
|||||||
|
|
||||||
|
|
||||||
protected void loadParameters() {
|
protected void loadParameters() {
|
||||||
|
try {
|
||||||
getProjection().setParameters(currentParams);
|
getProjection().setParameters(currentParams);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
showError("Failed to load projection", e.getLocalizedMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -26,9 +26,9 @@ package maps;
|
|||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import maps.Projection.Property;
|
import maps.Projection.Property;
|
||||||
import maps.Projection.Type;
|
import maps.Projection.Type;
|
||||||
import utils.Math2;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class for completely arbitrary projections, where every square degree can be specified anywhere on the plane.
|
* A class for completely arbitrary projections, where every square degree can be specified anywhere on the plane.
|
||||||
@ -37,7 +37,6 @@ import utils.Math2;
|
|||||||
*/
|
*/
|
||||||
public class Arbitrary {
|
public class Arbitrary {
|
||||||
|
|
||||||
private static final int NE = 0, NW = 1, SW = 2, SE = 3;
|
|
||||||
private static final int X = 0, Y = 1;
|
private static final int X = 0, Y = 1;
|
||||||
|
|
||||||
|
|
||||||
@ -69,38 +68,71 @@ public class Arbitrary {
|
|||||||
|
|
||||||
private static class ArbitraryProjection extends Projection {
|
private static class ArbitraryProjection extends Projection {
|
||||||
|
|
||||||
private double[][] vertices; // the vertex x-y coordinates
|
private String filename; // the data filename
|
||||||
private int[][][] cells; // the indices of the corner of each cell
|
private double[][][][] cells; // the values of the corner of each cell
|
||||||
|
private int[][] cellShapes; // the slope of each cell
|
||||||
|
private double[][][] pixels; // the pixel values, for inverse mapping
|
||||||
|
private double[][] edge; // the indices of the edge vertices
|
||||||
|
|
||||||
public ArbitraryProjection(String title, String description, boolean interrupted, Type type, Property property, String filename) {
|
public ArbitraryProjection(String title, String description, boolean interrupted, Type type, Property property, String filename) {
|
||||||
super(title, description, 0, 0, interrupted ? 0b1010 : 0b1011, type, property, 4);
|
super(title, description, 0, 0, interrupted ? 0b1010 : 0b1011, type, property, 4);
|
||||||
|
this.filename = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setParameters(double... params) throws IllegalArgumentException { // these maps don't actually have parameters, but this is the best place to load files
|
||||||
|
if (cells != null)
|
||||||
|
return; // but don't do it if you've already done it
|
||||||
|
|
||||||
BufferedReader in = null;
|
BufferedReader in = null;
|
||||||
try {
|
try {
|
||||||
in = new BufferedReader(new FileReader(String.format("src/data/%s", filename))); // parsing the input mesh is pretty simple
|
in = new BufferedReader(new FileReader(String.format("src/data/%s", filename))); // parsing the input mesh is pretty simple
|
||||||
String[] row = in.readLine().split(","); // get the header
|
String[] row = in.readLine().split(","); // get the header
|
||||||
vertices = new double[Integer.parseInt(row[0])][2];
|
double[][] vertices = new double[Integer.parseInt(row[0])][2];
|
||||||
cells = new int[Integer.parseInt(row[1])][Integer.parseInt(row[2])][4];
|
cells = new double[Integer.parseInt(row[1])][Integer.parseInt(row[2])][][];
|
||||||
width = Double.parseDouble(row[3]);
|
cellShapes = new int[cells.length][cells[0].length];
|
||||||
height = Double.parseDouble(row[4]);
|
edge = new double[Integer.parseInt(row[3])][];
|
||||||
|
pixels = new double[Integer.parseInt(row[4])][Integer.parseInt(row[5])][2];
|
||||||
|
width = Double.parseDouble(row[6]);
|
||||||
|
height = Double.parseDouble(row[7]);
|
||||||
|
|
||||||
for (int i = 0; i < vertices.length; i ++) { // do the vertex coordinates
|
for (int i = 0; i < vertices.length; i ++) { // do the vertex coordinates
|
||||||
row = in.readLine().split(",");
|
row = in.readLine().split(",");
|
||||||
for (int j = 0; j < vertices[i].length; j ++)
|
for (int j = 0; j < vertices[i].length; j ++)
|
||||||
vertices[i][j] = Double.parseDouble(row[j]);
|
vertices[i][j] = Double.parseDouble(row[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < cells.length; i ++) { // get the cell vertices
|
for (int i = 0; i < cells.length; i ++) { // get the cell vertices
|
||||||
for (int j = 0; j < cells[i].length; j ++) {
|
for (int j = 0; j < cells[i].length; j ++) {
|
||||||
row = in.readLine().split(",");
|
row = in.readLine().split(",");
|
||||||
for (int k = 0; k < cells[i][j].length; k ++)
|
cellShapes[i][j] = Integer.parseInt(row[0]);
|
||||||
cells[i][j][k] = Integer.parseInt(row[k]);
|
cells[i][j] = new double[row.length-1][];
|
||||||
|
for (int k = 1; k < row.length; k ++)
|
||||||
|
cells[i][j][k-1] = vertices[Integer.parseInt(row[k])];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < edge.length; i ++) { // the edge
|
||||||
|
row = in.readLine().split(",");
|
||||||
|
edge[i] = vertices[Integer.parseInt(row[0])];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < pixels.length; i ++) { // the pixels
|
||||||
|
for (int j = 0; j < pixels[i].length; j ++) {
|
||||||
|
row = in.readLine().split(",");
|
||||||
|
for (int k = 0; k < pixels[i][j].length; k ++)
|
||||||
|
pixels[i][j][k] = Double.parseDouble(row[k]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // and skip the edge; it's not relevant here
|
|
||||||
} catch (IOException | NullPointerException | ArrayIndexOutOfBoundsException e) {
|
} catch (IOException | NullPointerException | ArrayIndexOutOfBoundsException e) {
|
||||||
System.err.println("Could not load mesh: "+e);
|
cells = new double[][][][] {{{{0,0},{0,0},{0,0},{0,0}}}};
|
||||||
width = 2;
|
cellShapes = new int[][] {{0}};
|
||||||
height = 2;
|
edge = new double[][] {{0,0}};
|
||||||
vertices = new double[][] {{1,1},{-1,1},{-1,-1},{1,-1}};
|
pixels = new double[][][] {{{0,0}}};
|
||||||
cells = new int[][][] {{{0,1,2,3}}};
|
width = 0;
|
||||||
|
height = 0;
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new IllegalArgumentException("Missing or corrupt data file for "+this.getName());
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
if (in != null) in.close();
|
if (in != null) in.close();
|
||||||
@ -120,11 +152,40 @@ public class Arbitrary {
|
|||||||
double ce = (lon+Math.PI)/(2*Math.PI)*cells[i].length - j;
|
double ce = (lon+Math.PI)/(2*Math.PI)*cells[i].length - j;
|
||||||
double cn = 1 - cs;
|
double cn = 1 - cs;
|
||||||
double cw = 1 - ce;
|
double cw = 1 - ce;
|
||||||
double[] ne = vertices[cells[i][j][NE]], nw = vertices[cells[i][j][NW]],
|
double[][] v; // which vertices we use depends on some things
|
||||||
sw = vertices[cells[i][j][SW]], se = vertices[cells[i][j][SE]];
|
double[] c;
|
||||||
return new double[] {
|
|
||||||
cs*cw*sw[X] + cs*ce*se[X] + cn*cw*nw[X] + cn*ce*ne[X],
|
if (cellShapes[i][j] < 0) { // for negative sloped cells,
|
||||||
cs*cw*sw[Y] + cs*ce*se[Y] + cn*cw*nw[Y] + cn*ce*ne[Y] };
|
if (ce >= cs) { // is it in the ne,
|
||||||
|
v = new double[][] {cells[i][j][0], cells[i][j][1], cells[i][j][5]};
|
||||||
|
c = new double[] { 1-cw-cs, cw, cs};
|
||||||
|
}
|
||||||
|
else { // or the sw?
|
||||||
|
v = new double[][] {cells[i][j][3], cells[i][j][4], cells[i][j][2]};
|
||||||
|
c = new double[] { 1-ce-cn, ce, cn};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cellShapes[i][j] > 0) { // for positive sloped cells,
|
||||||
|
if (ce >= cn) { // is it in the se,
|
||||||
|
v = new double[][] {cells[i][j][5], cells[i][j][0], cells[i][j][4]};
|
||||||
|
c = new double[] { 1-cn-cw, cn, cw};
|
||||||
|
}
|
||||||
|
else { // or the nw?
|
||||||
|
v = new double[][] {cells[i][j][2], cells[i][j][3], cells[i][j][1]};
|
||||||
|
c = new double[] { 1-cs-ce, cs, ce};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // for single-element cells
|
||||||
|
v = new double[][] {cells[i][j][0], cells[i][j][1], cells[i][j][2], cells[i][j][3]}; // we can just use all of them
|
||||||
|
c = new double[] { cn*ce, cn*cw, cs*cw, cs*ce};
|
||||||
|
}
|
||||||
|
|
||||||
|
double[] coords = new double[] {0, 0};
|
||||||
|
for (int k = 0; k < v.length; k ++) {
|
||||||
|
coords[X] += c[k]*v[k][X];
|
||||||
|
coords[Y] += c[k]*v[k][Y];
|
||||||
|
}
|
||||||
|
return coords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -151,7 +151,7 @@ public abstract class Projection {
|
|||||||
public abstract double[] inverse(double x, double y); //convert Cartesian coordinates to spherical
|
public abstract double[] inverse(double x, double y); //convert Cartesian coordinates to spherical
|
||||||
|
|
||||||
|
|
||||||
public void setParameters(double... params) {
|
public void setParameters(double... params) throws IllegalArgumentException {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user