Reputation: 15
I have a CSV file with almost 65,000 rows divided into 3 values (longitude, latitude, and altitude). What I have to do is to create an array[][] that is longitude by latitude. Longitude and latitude are Doubles and they can't be used for indexing but don't know how to map them to indices. So I imagine it would be something like this:
array[0][0] = altitude_value[0];
array[0][1] = altitude_value[1];
·
·
·
array[i][j] = altitude_value[z];
The values are as such:
-179.75,-89.75,-1965
-179.75,-89.5,-2011
-179.75,-89.25,-2140
-179.75,-89,-2162
What I'm trying to achieve to get the altitude based on longitude and latitude parameters given to the following method:
public double getAltitude(double longitude, double latitude) {
return array[array.indexOf(longitude)][array.indexOf(latitude)] = altitude_value;
}
Upvotes: 0
Views: 183
Reputation: 150
Java primitive arrays do not have an "indexOf" method such as the one shown in your provided getAltitude method. You would need to cast it to a List or use a helper class such as java.util.Array to get that functionality.
Looking at how are trying to use the array index you might be better off with another datatype, such as a Map of Maps. The basic functionality of these other datatypes work the same as a 2D array conceptually, but allows for greater variety of index datatype than primitive arrays.
A basic implementation using a Map of Maps:
Map<Double, Map<Double,Double> longitudeMap; //Read your CSV file into this data structure
public double getAltitude(double longitude, double latitude) {
Map<Double> latitudeMap = longitudeMap.get(longitude);
double altitude = latitudeMap.get(latitude);
return altitude;
}
This could be simplified into fewer lines using chained gets. It also needs some NULL protection, but should convey the jist of a Map based solution rather than primitive array solution.
If you have to use a longitude and latitude indexed primitive array you are basically building a mapping yourself by hand (what value maps to what index in the data array) and would need to store that indexing in a separate object, which could be an array, but is better off as a List. Your "indexOf" in getAltitude would be into your indexing object, not not the data array.
Upvotes: 0
Reputation: 51565
If you insist on using a 2D array, you could map your values like this:
array[0][0] = longitude[0];
array[0][1] = latitude[0];
array[0][2] = altitude[0];
array[1][0] = longitude[1];
array[1][1] = latitude[1];
array[1][2] = altitude[1];
...
array[n][0] = longitude[n];
array[n][1] = latitude[n];
array[n][2] = altitude[n];
A better solution would be to create a Position
class to hold one longitude, latitude, and altitude. Then you can have a 1D array of Position
instances.
Edited to add:
Here's a simple example. I used your four position lines as input.
-179.75,-89.75,-1965
-179.75,-89.5,-2011
-179.75,-89.25,-2140
-179.75,-89,-2162
I received the following output for longitude -179.75, latitude -89.5.
-2011
I used a simple linear search through the 1D array I created. For 4 values, it's quick enough. For 65 thousand values, you can run my code and see how long it takes. As I said, if you sort the array by longitude, latitude and use a binary search, you'll get the correct result in about 32 tests.
Here's the complete runnable code I used.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class PositionApp {
public static void main(String[] args) {
new PositionApp().run();
}
private Position[] positions;
public void run() {
try {
int count = readCSVFile();
this.positions = new Position[count];
processCSVFile();
int altitude = getAltitude(-179.75, -89.5);
System.out.println(altitude);
} catch (IOException e) {
e.printStackTrace();
}
}
public int readCSVFile() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
getClass().getResourceAsStream("/sample.csv")));
int count = 0;
String line = reader.readLine();
while (line != null) {
count++;
line = reader.readLine();
}
reader.close();
return count;
}
public void processCSVFile() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
getClass().getResourceAsStream("/sample.csv")));
int count = 0;
String line = reader.readLine();
while (line != null) {
String[] parts = line.split(",");
double longitude = Double.valueOf(parts[0]);
double latitude = Double.valueOf(parts[1]);
int altitude = Integer.valueOf(parts[2]);
positions[count++] = new Position(longitude, latitude, altitude);
line = reader.readLine();
}
reader.close();
}
public int getAltitude(double longitude, double latitude) {
for (int index = 0; index < positions.length; index++) {
if ((positions[index].getLongitude() == longitude) &&
(positions[index].getLatitude() == latitude)) {
return positions[index].getAltitude();
}
}
return Integer.MIN_VALUE;
}
public class Position {
private final int altitude;
private final double longitude;
private final double latitude;
public Position(double longitude, double latitude, int altitude) {
this.longitude = longitude;
this.latitude = latitude;
this.altitude = altitude;
}
public int getAltitude() {
return altitude;
}
public double getLongitude() {
return longitude;
}
public double getLatitude() {
return latitude;
}
}
}
Upvotes: 1
Reputation: 5990
Let's say for simplicity you had longitudes and latitudes from 0-1 in increments of 0.25 (n = 5
increments). Then your mapping would look something like this:
0, 0 -> a0
0, 0.25 -> a1
...
0.25, 0 -> a5
...
Then you could access the altitude with the indices [x][y]
determined by [longitude * 4][latitude * 4]
for any longitude and latitude values.
Obviously for your actual example you would need to offset your longitude and latitude values to zero when querying the array, but that shouldn't be too much extra work.
Upvotes: 0