Java 将地球上由4个经纬度坐标给出的区域分割成等距网格?

Java 将地球上由4个经纬度坐标给出的区域分割成等距网格?,java,gps,geometry,coordinate-systems,polar-coordinates,Java,Gps,Geometry,Coordinate Systems,Polar Coordinates,所以我正在用Java语言进行最后一个项目,这个项目有一个服务器端(由我负责)和一个GUI客户端(由其他人负责) 作为一个服务器,我经常从android客户端获得GPS坐标(如纬度经度),我需要在预先分配的网格上回复它们的等效位置 网格由GUI客户端发送给我的4个LatLng坐标和要除以的网格线数量设置。例如,我得到(35.000,35.000),(35.000,36.000),(36.000,36.000),(36.000,35.000)和40x40 我目前使用的方法是分别计算区域的纬度距离和经

所以我正在用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(如示例所示),每个商就是我的“点击”,我稍后使用的单个距离单位

当我收到一个新坐标时,我用我的“点击”除以它,然后做一个Math.floor,这个操作的商就是网格上的位置。 但有点不对劲,我的计算显然是不正确的,因为GUI客户端不同意我的意见(通常是1格北/南和1格西/东,他只是简单地获取地图(例如谷歌地图),并将其作为一张简单地分割矩形区域的图片进行处理。 我做错了什么?有没有更好的方法来离散此设置给出的区域

我已经检查过的事情:1.这不是某种浮点下溢,我使用了BigDecimal和

  • 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);
    }
    }
    
    import com.javadocmd.simplelatelng.LatLng;
    导入com.javadocmd.simplelatelng.LatLngTool;
    导入com.javadocmd.simplelatelng.util.LengthUnit;
    导入java.awt.*;
    导入java.util.LinkedList;
    导入java.util.List;
    公共类网格图{
    私人双拉特拉德;
    私人双lng_rad;
    私有多边形网格;
    私人双因子=100000;
    私有列表边界=新的LinkedList();
    公共网格图(内部网格、内部液化天然气网格、列表坐标){
    //合作伙伴应该是(y_-bot,x_-bot;,y_-up,x_-bot;y_-up,x_-up;y_-bot,x_-up)
    网格=新多边形();
    对于(int i=0;i
    在探索和使用代码后,我成功地回答了自己的问题。 这是我们的项目代码中使用的此解决方案的最终实现。 您可以自由使用它,并希望它将来能帮助他人:

    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);
    }
    }
    
    import com.javadocmd.simplelatelng.LatLng;
    导入com.javadocmd.simplelatelng.LatLngTool;
    导入com.javadocmd.simplelatelng.util.LengthUnit;
    导入java.awt.*;
    导入java.util.LinkedList;
    导入java.util.List;
    公共类网格图{
    私人双拉特拉德;
    私人双lng_rad;
    私有多边形网格;
    私人双因子=100000;
    私有列表边界=新的LinkedList();
    公共网格图(内部网格、内部液化天然气网格、列表坐标){
    //合作伙伴应该是(y_-bot,x_-bot;,y_-up,x_-bot;y_-up,x_-up;y_-bot,x_-up)
    网格=新多边形();
    对于(int i=0;i