将 4 个纬度经度坐标给出的地球上的区域拆分为等距网格?
Splitting an area on the globe given by 4 Latitude Longitude coordinates into an equidistant grid?
所以我正在用 Java 语言做一个期末项目,这个项目有一个服务器端(由我负责)和一个 GUI 客户端(由其他人负责)。
作为服务器,我不断从 android 客户端获取 GPS 坐标(如经纬度),我需要在预先分配的网格上回复它们的等效位置。
网格由 GUI 客户端发送给我的 4 个 LatLng 坐标和要划分的网格线数量设置。例如。我得到 (35.000,35.000),(35.000,36.000),(36.000,36.000),(36.000,35.000) 和 40x40.
我目前使用的方法是分别计算该区域的纬度距离和经度距离的弧度距离,然后除以40(如给出的示例),每个商都是我的"click",后面会用到的单个距离单位
当我收到一个新坐标时,我将它除以我的 "click" 并执行 Math.floor,此操作的商是网格上的位置。
但是出了点问题,我的计算显然不正确,因为 GUI 客户端不同意我的看法(通常是 1 格 north/south 和 1 格 west/east,他只是拿了地图(例如 google- map) 并将其作为简单分割矩形区域的图片进行操作。
我究竟做错了什么?有没有更好的方法来离散化此设置给出的区域?
我已经检查过的事情:1. 这不是某种浮动下溢,我使用了 BigDecimal 和 SimpleLatLng。
- GUI 客户端同意我关于更接近相对 0x0 网格块的位置的看法,因此这不是通常的差一错误。
编辑:我已经设法解决了大部分错误,我仍然有一些错误,我不知道代码的哪一部分可以负责。
编辑 2:问题似乎已解决,问题首先是没有获得正确的方位,只是假设网格是北向的,附上正确的代码:
在探索和使用代码后,我设法回答了自己。
这是我们项目代码中使用的此解决方案的最终实现。
您可以随意使用它,希望它能在未来帮助到其他人:
import com.javadocmd.simplelatlng.LatLng;
import com.javadocmd.simplelatlng.LatLngTool;
import com.javadocmd.simplelatlng.util.LengthUnit;
import java.awt.*;
import java.util.LinkedList;
import java.util.List;
public class GridMap {
private double lat_rad;
private double lng_rad;
private Polygon grid;
private double factor = 100000;
private List<LatLng> bounds = new LinkedList<>();
public GridMap(int lat_bin, int lng_bin, List<Double> coords) {
// coords should be (y_bot, x_bot;,y_up, x_bot;y_up, x_up;y_bot, x_up)
grid = new Polygon();
for (int i = 0; i < coords.size(); i += 2) {
int nx = (int) Math.floor(factor * coords.get(i));
int ny = (int) Math.floor(factor * coords.get(i + 1));
grid.addPoint(nx, ny);
bounds.add(new LatLng(coords.get(i), coords.get(i + 1)));
}
lat_rad = LatLngTool.distance(bounds.get(0), bounds.get(1), LengthUnit.METER) / (lat_bin);
lng_rad = LatLngTool.distance(bounds.get(0), bounds.get(3), LengthUnit.METER) / (lng_bin);
}
public boolean inGrid(LatLng point) {
int lat = (int) Math.floor(factor * point.getLatitude());
int lng = (int) Math.floor(factor * point.getLongitude());
return grid.contains(lat, lng);
}
public Point toGrid(LatLng llp) {
if (inGrid(llp)) {
double lat = llp.getLatitude();
double lng = llp.getLongitude();
double rel_lat = bounds.get(0).getLatitude();
double rel_lng = bounds.get(0).getLongitude();
int ilat = (int) Math.floor(LatLngTool.distance(new LatLng(rel_lat, lng), bounds.get(0), LengthUnit.METER) / lat_rad);
int ilng = (int) Math.floor(LatLngTool.distance(new LatLng(lat, rel_lng), bounds.get(0), LengthUnit.METER) / lng_rad);
return new Point(ilat, ilng);
}
return new Point(-1, -1);
}
public LatLng toLatLng(Point gridLoc){
double lat_dist = (gridLoc.getY() + 0.5) * lat_rad;
double lng_dist = (gridLoc.getX() + 0.5) * lng_rad;
double y_bearing = LatLngTool.initialBearing(bounds.get(0), bounds.get(1));
double x_bearing = LatLngTool.initialBearing(bounds.get(1), bounds.get(2));
LatLng startLatLng = new LatLng(bounds.get(0).getLatitude(), bounds.get(0).getLongitude());
LatLng lat_llp = LatLngTool.travel(startLatLng, y_bearing, lat_dist, LengthUnit.METER);
return LatLngTool.travel(lat_llp, x_bearing, lng_dist, LengthUnit.METER);
}
}
所以我正在用 Java 语言做一个期末项目,这个项目有一个服务器端(由我负责)和一个 GUI 客户端(由其他人负责)。
作为服务器,我不断从 android 客户端获取 GPS 坐标(如经纬度),我需要在预先分配的网格上回复它们的等效位置。
网格由 GUI 客户端发送给我的 4 个 LatLng 坐标和要划分的网格线数量设置。例如。我得到 (35.000,35.000),(35.000,36.000),(36.000,36.000),(36.000,35.000) 和 40x40.
我目前使用的方法是分别计算该区域的纬度距离和经度距离的弧度距离,然后除以40(如给出的示例),每个商都是我的"click",后面会用到的单个距离单位
当我收到一个新坐标时,我将它除以我的 "click" 并执行 Math.floor,此操作的商是网格上的位置。 但是出了点问题,我的计算显然不正确,因为 GUI 客户端不同意我的看法(通常是 1 格 north/south 和 1 格 west/east,他只是拿了地图(例如 google- map) 并将其作为简单分割矩形区域的图片进行操作。 我究竟做错了什么?有没有更好的方法来离散化此设置给出的区域?
我已经检查过的事情:1. 这不是某种浮动下溢,我使用了 BigDecimal 和 SimpleLatLng。
- GUI 客户端同意我关于更接近相对 0x0 网格块的位置的看法,因此这不是通常的差一错误。
编辑:我已经设法解决了大部分错误,我仍然有一些错误,我不知道代码的哪一部分可以负责。
编辑 2:问题似乎已解决,问题首先是没有获得正确的方位,只是假设网格是北向的,附上正确的代码:
在探索和使用代码后,我设法回答了自己。 这是我们项目代码中使用的此解决方案的最终实现。 您可以随意使用它,希望它能在未来帮助到其他人:
import com.javadocmd.simplelatlng.LatLng;
import com.javadocmd.simplelatlng.LatLngTool;
import com.javadocmd.simplelatlng.util.LengthUnit;
import java.awt.*;
import java.util.LinkedList;
import java.util.List;
public class GridMap {
private double lat_rad;
private double lng_rad;
private Polygon grid;
private double factor = 100000;
private List<LatLng> bounds = new LinkedList<>();
public GridMap(int lat_bin, int lng_bin, List<Double> coords) {
// coords should be (y_bot, x_bot;,y_up, x_bot;y_up, x_up;y_bot, x_up)
grid = new Polygon();
for (int i = 0; i < coords.size(); i += 2) {
int nx = (int) Math.floor(factor * coords.get(i));
int ny = (int) Math.floor(factor * coords.get(i + 1));
grid.addPoint(nx, ny);
bounds.add(new LatLng(coords.get(i), coords.get(i + 1)));
}
lat_rad = LatLngTool.distance(bounds.get(0), bounds.get(1), LengthUnit.METER) / (lat_bin);
lng_rad = LatLngTool.distance(bounds.get(0), bounds.get(3), LengthUnit.METER) / (lng_bin);
}
public boolean inGrid(LatLng point) {
int lat = (int) Math.floor(factor * point.getLatitude());
int lng = (int) Math.floor(factor * point.getLongitude());
return grid.contains(lat, lng);
}
public Point toGrid(LatLng llp) {
if (inGrid(llp)) {
double lat = llp.getLatitude();
double lng = llp.getLongitude();
double rel_lat = bounds.get(0).getLatitude();
double rel_lng = bounds.get(0).getLongitude();
int ilat = (int) Math.floor(LatLngTool.distance(new LatLng(rel_lat, lng), bounds.get(0), LengthUnit.METER) / lat_rad);
int ilng = (int) Math.floor(LatLngTool.distance(new LatLng(lat, rel_lng), bounds.get(0), LengthUnit.METER) / lng_rad);
return new Point(ilat, ilng);
}
return new Point(-1, -1);
}
public LatLng toLatLng(Point gridLoc){
double lat_dist = (gridLoc.getY() + 0.5) * lat_rad;
double lng_dist = (gridLoc.getX() + 0.5) * lng_rad;
double y_bearing = LatLngTool.initialBearing(bounds.get(0), bounds.get(1));
double x_bearing = LatLngTool.initialBearing(bounds.get(1), bounds.get(2));
LatLng startLatLng = new LatLng(bounds.get(0).getLatitude(), bounds.get(0).getLongitude());
LatLng lat_llp = LatLngTool.travel(startLatLng, y_bearing, lat_dist, LengthUnit.METER);
return LatLngTool.travel(lat_llp, x_bearing, lng_dist, LengthUnit.METER);
}
}