题 添加到GPS坐标的距离


我正在尝试使用GPS在固定点的随机距离上生成一些点。

如何以米为单位添加距离? 我看过UTM到GPS的转换,但有没有更简单的方法来实现这一目标?

我正在开发Android平台以防万一。

干杯, FGS


23
2018-05-15 08:56


起源




答案:


  • P0(lat0,lon0):初始位置(单位:
  • dx,dy:你初始位置的随机偏移量

您可以使用近似值来计算随机位置的位置:

 lat = lat0 + (180/pi)*(dy/6378137)
 lon = lon0 + (180/pi)*(dx/6378137)/cos(lat0)

只要随机距离偏移低于10-100 km,这就非常精确

编辑:当然在Java Math.cos()中需要使用弧度 Math.cos(Math.PI/180.0*lat0) 如果lat0是如上所述的度数。


49
2018-05-15 09:09



嗨,是6378137地球的半径?谢谢! - fgs
是的(以米为单位)。更确切地说,它是WGS84椭球的半长轴,因此是赤道上地球的半径。 - Stéphane
这对我来说不太合适。经度偏移总是应该是原来的两倍。将其更改为以下更正:`lat = lat0 +(180 / pi)*(dy / 6378137)lon = lon0 +(180 / pi / 2)*(dx / 6378137)/ cos(lat0)` - GeekyMonkey
嗯...我的公式似乎是正确的,它们在我的测试数据上运行良好...你能给我输入数据,也许你的代码? - Stéphane
我可能会使用平均半径6371.0公里而不是赤道的半径。赔率是您引用的区域是半长轴和半短轴之间。如果您需要更高的精确度,请使用Vincenty公式表示椭圆体, movable-type.co.uk/scripts/latlong-vincenty.html。 - Phil


为了占据一个方格,我用这个:

 private double[] getBoundingBox(final double pLatitude, final double pLongitude, final int pDistanceInMeters) {

                final double[] boundingBox = new double[4];

                final double latRadian = Math.toRadians(pLatitude);

                final double degLatKm = 110.574235;
                final double degLongKm = 110.572833 * Math.cos(latRadian);
                final double deltaLat = pDistanceInMeters / 1000.0 / degLatKm;
                final double deltaLong = pDistanceInMeters / 1000.0 /
                                degLongKm;

                final double minLat = pLatitude - deltaLat;
                final double minLong = pLongitude - deltaLong;
                final double maxLat = pLatitude + deltaLat;
                final double maxLong = pLongitude + deltaLong;

                boundingBox[0] = minLat;
                boundingBox[1] = minLong;
                boundingBox[2] = maxLat;
                boundingBox[3] = maxLong;

                return boundingBox;
        }

这将返回一个包含4个坐标的数组,您可以使用它们将原始点放在中心的正方形。


12
2017-10-23 11:14



效果很好.. pDistanceInMeters 这里是“半径”。 - Pavel Vlasov
什么是110.574235?我的轴承角为180°,两个坐标之间的距离为diff。如何使用它来获取边界框中的一个点? - Ari
什么是110.574235? - user5470921
它是赤道上纬度与km转换系数的关系 - user5470921


详细概述见 http://www.movable-type.co.uk/scripts/latlong.html

如果您在某个地方需要将经度/纬度转换为UTM坐标(GPS中使用的坐标),您可能需要查看 http://www.uwgb.edu/dutchs/UsefulData/UTMFormulas.htm


5
2018-05-15 09:25



嗨!非常感谢,链接确实是我需要的。谢谢。 :d - fgs


如果你想去东部或北部或西部或南部,你可以使用这个:

@SuppressLint("DefaultLocale")
public static double go_mock_loc(double xx_lat,double xx_long,double xx_dinstance,String Direction)
{
//  double xx_lat= 45.815005; 
//  double xx_long= 15.978501;

//  int xx_dinstance=500;

    int equator_circumference=6371000;
    int polar_circumference=6356800;

    double m_per_deg_long =  360 / polar_circumference;
    double rad_lat=(xx_lat* (Math.PI) / 180);
    double m_per_deg_lat = 360 / ( Math.cos(rad_lat) * equator_circumference);

    double deg_diff_long = xx_dinstance * m_per_deg_long;
    double deg_diff_lat  = xx_dinstance * m_per_deg_lat; 


    double xx_north_lat = xx_lat + deg_diff_long;
    //double xx_north_long= xx_long;
    double xx_south_lat = xx_lat - deg_diff_long;
    //double xx_south_long= xx_long;

    //double xx_east_lat = xx_lat;
    double xx_east_long= xx_long + deg_diff_lat;  
    //double xx_west_lat = xx_lat;
    double xx_west_long= xx_long - deg_diff_lat;

    if (Direction.toUpperCase().contains("NORTH")) {
        return xx_north_lat;
    } else if (Direction.toUpperCase().contains("SOUTH"))
    {
        return xx_south_lat;
    } else if (Direction.toUpperCase().contains("EAST"))
    {
        return xx_east_long;
    } else if (Direction.toUpperCase().contains("WEST"))
    {
        return xx_west_long;
    }
    else 
        return 0; 

}

1
2017-07-17 17:36



很容易移植到c# - Edza


此代码将n个段中的两个坐标之间的线分开。用固定距离替换增量计算

 @Override
public void split(Coordinates p1, Coordinates p2, int segments) {
    double φ1 = Math.toRadians(p1.getLat());
    double λ1 = Math.toRadians(p1.getLon());
    double φ2 = Math.toRadians(p2.getLat());
    double λ2 = Math.toRadians(p2.getLon());


    double xDelta = (φ2 - φ1) / segments;
    double yDelta = (λ2 - λ1) / segments;
    for (int i = 0; i < segments; i++){
        double x = φ1 + i * xDelta;
        double y = λ1 + i * yDelta;
        double xc = Math.toDegrees(x);
        double yc = Math.toDegrees(y);
        System.out.println(xc+","+yc);
    }
}

0
2017-07-17 10:46