使用 Java 查找最近的坐标并打印参考
Find nearest coordinate and print reference using Java
我想使用 java 读取一组纬度和经度值,从 table 预定义值中识别最近的坐标并报告参考名称。
例如输入坐标lat=37.423423和long=-122.083953,我想从下面的输入table中找到最近的点,并报告相关的网格参考。
lat long gridRef
37.00 -121.50 A1
37.00 -122.00 A2
37.00 -122.50 A3
37.50 -121.50 B1
37.50 -122.00 B2
37.50 -122.50 B3
38.00 -121.50 C1
38.00 -122.00 C2
38.00 -122.50 C3
在此示例中,输出应打印 "B2"
我有一些代码可以报告最近点的坐标:
public class ClosestPoint {
public static void main(String[] args) {
final int X = 0;
final int Y = 1;
// input coordinates to search against
double[] coordinate = {37.423423, -122.083953};
// input points to search against
double[][] points = {{37.00, -121.50}, // 0 A1
{37.00, -122.00}, // 1 A2
{37.00, -122.50}, // 2 A3
{37.50, -121.50}, // 3 B1
{37.50, -122.00}, // 4 B2
{37.50, -122.50}, // 5 B3
{38.00, -121.50}, // 6 C1
{38.00, -122.00}, // 7 C2
{38.00, -122.50} // 8 C3
};
double[] closest = nearestPoint(coordinate, points);
System.out.println("("+closest[X]+", "+closest[Y]+")");
double d = distance(coordinate[X], coordinate[Y], closest[X], closest[Y]);
System.out.println("Distance: "+ d);
}
public static double distance(double x1, double y1, double x2, double y2) {
double x = Math.pow(x2 - x1, 2);
double y = Math.pow(y2 - y1, 2);
return Math.sqrt( x + y );
}
public static double[] nearestPoint(double[] coordinate, double[][] points) {
final int X = 0;
final int Y = 1;
double[] closestPoint = points[0];
double closestDist = distance(coordinate[X], coordinate[Y],
closestPoint[X], closestPoint[Y]);
// Traverse the array
for(int i = 0; i < points.length; i++) {
double dist = distance(coordinate[X], coordinate[Y],
points[i][X], points[i][Y]);
if (dist < closestDist && dist != 0.0) {
closestDist = dist;
closestPoint = points[i];
}
}
return closestPoint;
}
}
输出如下所示:
(37.5, -122.0)
Distance: 0.11363161152601435
我现在要做的是为这个坐标输出一个参考名,就是上面例子中的B2。
如有任何建议,我们将不胜感激
祝福
奥利
可以使用Haversine formula计算距离。 Java 中的实施示例可在此处找到:
https://gist.github.com/vananth22/888ed9a22105670e7a4092bdcf0d72e4
编辑:您的距离计算在 sphere/curved 表面上不会特别准确。如果准确性是一项要求,我会建议实施上面写的 Haversine 公式。
但是,您的问题似乎与将区域名称映射到一组坐标有关?如果是这种情况,有几种不同的解决方案(下面列出了一些):
您可以创建一个结构 (class) 来保存区域标签(名称)、纬度和经度坐标,并为列表中的每个坐标对存储一个实例。
您可以像现在一样将坐标对存储在一个列表中,并将标签(名称)存储在与坐标列表中的索引匹配的单独字符串列表中。
您可以将每个坐标对存储在哈希图中,标签名称作为键。
此外,我建议根据与固定点的距离等对坐标列表进行排序。这样,可以通过简单的二进制搜索找到最接近给定坐标的点,而不必遍历列表中的每个坐标(最坏情况下为 O(N))。
编辑 2:
这是我修改你的原始代码的例子。这不是最佳解决方案,我建议遵循我上面给出的一些建议。
修改后的代码 return 是最近点的索引,而不是坐标对本身。然后它使用该索引在另一个字符串数组中查找区域。注意:没有错误检查 return 索引是否有效。
public class ClosestPoint {
public static void main(String[] args) {
final int X = 0;
final int Y = 1;
// input coordinates to search against
double[] coordinate = {37.423423, -122.083953};
// input points to search against
double[][] points = {{37.00, -121.50}, // 0 A1
{37.00, -122.00}, // 1 A2
{37.00, -122.50}, // 2 A3
{37.50, -121.50}, // 3 B1
{37.50, -122.00}, // 4 B2
{37.50, -122.50}, // 5 B3
{38.00, -121.50}, // 6 C1
{38.00, -122.00}, // 7 C2
{38.00, -122.50} // 8 C3
};
String[] zonenames = {
"A1",
"A2",
"A3",
"B1",
"B2",
"B3",
"C1",
"C2",
"C3",
};
//double[] closest = nearestPoint(coordinate, points);
int index = nearestPoint(coordinate, points);
double[] closest = points[index];
String zone = zonenames[index];
System.out.println("("+closest[X]+", "+closest[Y]+")");
System.out.println("Zone: " + zone);
double d = distance(coordinate[X], coordinate[Y], closest[X], closest[Y]);
System.out.println("Distance: "+ d);
}
public static double distance(double x1, double y1, double x2, double y2) {
double x = Math.pow(x2 - x1, 2);
double y = Math.pow(y2 - y1, 2);
return Math.sqrt( x + y );
}
//public static double[] nearestPoint(double[] coordinate, double[][] points) {
public static int nearestPoint(double[] coordinate, double[][] points) {
final int X = 0;
final int Y = 1;
int indexFound = 0;
double[] closestPoint = points[0];
double closestDist = distance(coordinate[X], coordinate[Y],
closestPoint[X], closestPoint[Y]);
// Traverse the array
for(int i = 0; i < points.length; i++) {
double dist = distance(coordinate[X], coordinate[Y],
points[i][X], points[i][Y]);
if (dist < closestDist && dist != 0.0) {
closestDist = dist;
closestPoint = points[i];
indexFound = i;
}
}
//return closestPoint;
return indexFound;
}
}
我想使用 java 读取一组纬度和经度值,从 table 预定义值中识别最近的坐标并报告参考名称。
例如输入坐标lat=37.423423和long=-122.083953,我想从下面的输入table中找到最近的点,并报告相关的网格参考。
lat long gridRef
37.00 -121.50 A1
37.00 -122.00 A2
37.00 -122.50 A3
37.50 -121.50 B1
37.50 -122.00 B2
37.50 -122.50 B3
38.00 -121.50 C1
38.00 -122.00 C2
38.00 -122.50 C3
在此示例中,输出应打印 "B2"
我有一些代码可以报告最近点的坐标:
public class ClosestPoint {
public static void main(String[] args) {
final int X = 0;
final int Y = 1;
// input coordinates to search against
double[] coordinate = {37.423423, -122.083953};
// input points to search against
double[][] points = {{37.00, -121.50}, // 0 A1
{37.00, -122.00}, // 1 A2
{37.00, -122.50}, // 2 A3
{37.50, -121.50}, // 3 B1
{37.50, -122.00}, // 4 B2
{37.50, -122.50}, // 5 B3
{38.00, -121.50}, // 6 C1
{38.00, -122.00}, // 7 C2
{38.00, -122.50} // 8 C3
};
double[] closest = nearestPoint(coordinate, points);
System.out.println("("+closest[X]+", "+closest[Y]+")");
double d = distance(coordinate[X], coordinate[Y], closest[X], closest[Y]);
System.out.println("Distance: "+ d);
}
public static double distance(double x1, double y1, double x2, double y2) {
double x = Math.pow(x2 - x1, 2);
double y = Math.pow(y2 - y1, 2);
return Math.sqrt( x + y );
}
public static double[] nearestPoint(double[] coordinate, double[][] points) {
final int X = 0;
final int Y = 1;
double[] closestPoint = points[0];
double closestDist = distance(coordinate[X], coordinate[Y],
closestPoint[X], closestPoint[Y]);
// Traverse the array
for(int i = 0; i < points.length; i++) {
double dist = distance(coordinate[X], coordinate[Y],
points[i][X], points[i][Y]);
if (dist < closestDist && dist != 0.0) {
closestDist = dist;
closestPoint = points[i];
}
}
return closestPoint;
}
}
输出如下所示:
(37.5, -122.0)
Distance: 0.11363161152601435
我现在要做的是为这个坐标输出一个参考名,就是上面例子中的B2。
如有任何建议,我们将不胜感激
祝福 奥利
可以使用Haversine formula计算距离。 Java 中的实施示例可在此处找到:
https://gist.github.com/vananth22/888ed9a22105670e7a4092bdcf0d72e4
编辑:您的距离计算在 sphere/curved 表面上不会特别准确。如果准确性是一项要求,我会建议实施上面写的 Haversine 公式。
但是,您的问题似乎与将区域名称映射到一组坐标有关?如果是这种情况,有几种不同的解决方案(下面列出了一些):
您可以创建一个结构 (class) 来保存区域标签(名称)、纬度和经度坐标,并为列表中的每个坐标对存储一个实例。
您可以像现在一样将坐标对存储在一个列表中,并将标签(名称)存储在与坐标列表中的索引匹配的单独字符串列表中。
您可以将每个坐标对存储在哈希图中,标签名称作为键。
此外,我建议根据与固定点的距离等对坐标列表进行排序。这样,可以通过简单的二进制搜索找到最接近给定坐标的点,而不必遍历列表中的每个坐标(最坏情况下为 O(N))。
编辑 2:
这是我修改你的原始代码的例子。这不是最佳解决方案,我建议遵循我上面给出的一些建议。
修改后的代码 return 是最近点的索引,而不是坐标对本身。然后它使用该索引在另一个字符串数组中查找区域。注意:没有错误检查 return 索引是否有效。
public class ClosestPoint {
public static void main(String[] args) {
final int X = 0;
final int Y = 1;
// input coordinates to search against
double[] coordinate = {37.423423, -122.083953};
// input points to search against
double[][] points = {{37.00, -121.50}, // 0 A1
{37.00, -122.00}, // 1 A2
{37.00, -122.50}, // 2 A3
{37.50, -121.50}, // 3 B1
{37.50, -122.00}, // 4 B2
{37.50, -122.50}, // 5 B3
{38.00, -121.50}, // 6 C1
{38.00, -122.00}, // 7 C2
{38.00, -122.50} // 8 C3
};
String[] zonenames = {
"A1",
"A2",
"A3",
"B1",
"B2",
"B3",
"C1",
"C2",
"C3",
};
//double[] closest = nearestPoint(coordinate, points);
int index = nearestPoint(coordinate, points);
double[] closest = points[index];
String zone = zonenames[index];
System.out.println("("+closest[X]+", "+closest[Y]+")");
System.out.println("Zone: " + zone);
double d = distance(coordinate[X], coordinate[Y], closest[X], closest[Y]);
System.out.println("Distance: "+ d);
}
public static double distance(double x1, double y1, double x2, double y2) {
double x = Math.pow(x2 - x1, 2);
double y = Math.pow(y2 - y1, 2);
return Math.sqrt( x + y );
}
//public static double[] nearestPoint(double[] coordinate, double[][] points) {
public static int nearestPoint(double[] coordinate, double[][] points) {
final int X = 0;
final int Y = 1;
int indexFound = 0;
double[] closestPoint = points[0];
double closestDist = distance(coordinate[X], coordinate[Y],
closestPoint[X], closestPoint[Y]);
// Traverse the array
for(int i = 0; i < points.length; i++) {
double dist = distance(coordinate[X], coordinate[Y],
points[i][X], points[i][Y]);
if (dist < closestDist && dist != 0.0) {
closestDist = dist;
closestPoint = points[i];
indexFound = i;
}
}
//return closestPoint;
return indexFound;
}
}