我正在尝试了解如何使用 2D 数组



我有一个CSV文件,其中有将近65000行,分为3个值(经度、纬度和海拔(。我要做的是创建一个数组[][],它是经度乘纬度的。经度和纬度是双精度的,它们不能用于索引,但不知道如何将它们映射到索引。所以我想它会是这样的:

array[0][0] = altitude_value[0];
array[0][1] = altitude_value[1];
·
·
·
array[i][j] = altitude_value[z];

值如下:

-179.75,-89.75,-1965
-179.75,-89.5,-2011
-179.75,-89.25,-2140
-179.75,-89,-2162

我试图实现的是根据经纬度参数获得海拔高度,给出以下方法:

public double getAltitude(double longitude, double latitude) {
return array[array.indexOf(longitude)][array.indexOf(latitude)] = altitude_value;
}

如果你坚持使用2D数组,你可以这样映射你的值:

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

一个更好的解决方案是创建一个Position类来保存一个经度、纬度和海拔高度。然后您就可以拥有一个Position实例的1D数组。

编辑后添加:

这里有一个简单的例子。我用你的四条位置线作为输入。

-179.75,-89.75,-1965
-179.75,-89.5,-2011
-179.75,-89.25,-2140
-179.75,-89,-2162

我收到了以下经度-179.75,纬度-89.5的输出。

-2011

我对我创建的1D阵列进行了简单的线性搜索。对于4个值,它足够快。对于6.5万个值,您可以运行我的代码并查看它需要多长时间。正如我所说,如果你按照经度、纬度对数组进行排序,并使用二进制搜索,你将在大约32次测试中得到正确的结果。

这是我使用的完整的可运行代码。

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

}
}

为了简单起见,假设经度和纬度为0-1,增量为0.25(n = 5增量(。然后你的地图会看起来像这样:

0, 0 -> a0
0, 0.25 -> a1
...
0.25, 0 -> a5
...

然后,您可以使用[longitude * 4][latitude * 4]为任何经度和纬度值确定的索引[x][y]来访问海拔高度。

显然,对于您的实际示例,在查询数组时需要将经度和纬度值偏移为零,但这不应该是太多的额外工作。

Java基元数组没有一个"indexOf";方法,例如您提供的getAltitude方法中显示的方法。您需要将其强制转换为List,或者使用java.util.Array等辅助类来获得该功能。

看看如何使用数组索引,您可能会更好地使用另一种数据类型,例如Map of Maps。这些其他数据类型的基本功能在概念上与2D数组相同,但与基元数组相比,允许更多类型的索引数据类型。

使用地图的基本实现:


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

这可以使用链式get简化为更少的行。它还需要一些NULL保护,但应该传达基于Map的解决方案而不是基元数组解决方案的jit。

如果使用经度和纬度索引的基元数组,那么您基本上是自己手动构建映射(什么值映射到数据数组中的索引(,并且需要将该索引存储在一个单独的对象中,该对象可以是一个数组,但最好是List。您的";indexOf";在getAltitude中,它将进入索引对象,而不是数据数组。

最新更新