【问题标题】:Need a sector based on bearing, geopoint, distance and angle需要基于方位、地理点、距离和角度的扇区
【发布时间】:2016-08-05 06:03:39
【问题描述】:

我有问题。我正在尝试编写一个 JAVA 代码在给定的 bearing, (lat,lon) , speed 我需要得到形成一个扇区的所有点(如图所示( x1,y1) , (x2,y2) 以及在方位给定的方向上形成 Arc 的点列表(我对方位的了解非常有限)。

我的第一件事是根据具有硬编码距离和角度的方向来实现扇区。 (即固定值说d = 5kmangle = 60 deg。)

下一步基于我希望距离 dangle 计算的速度,如 d = func(speed)angle = func(speed) 但这将在以后进行。

由于方位是以度数给出的,我不知道如何计算方向。 我在想什么如果我能够将方位转换为同一方向的单位矢量。那么我认为我们可以绘制该部门。

如果我的理论/解释有误,请纠正我。求各位大佬帮忙.....

更多细节:

我正在做一个小项目,同时在手机上通过谷歌地图进行跟踪,我可以得到(lat,lon) - current position of userbearing - in the direction in which I am headedspeed - what speed i am travelling

距离和角度与速度的关系:

如果我以更快的速度行驶,d 应该更多,angle 应该更少(弧线会更窄)

如果我以较低的速度行驶,那么d 应该更小并且`角度应该更大(弧线会更宽)

如果我是静止的,速度是 0 ,那么我会在我当前的 (lat,lon) 周围画一个圆圈,然后找到我周围的 POI。

一旦我得到这个扇区,我将使用 Elastic 搜索(它提供一些 func(),如附近搜索和多边形搜索)在我跟踪时获取沿途的所有兴趣点

最终,当我开车时,我想向用户展示他一路走来的 POI 是什么。 (我们不知道用户的目的地)

更新

public class Test {

    // N is the number of points on the arc
    // e.g. const int N = 15;
    private static final int N = 10;

    public static void main(String[] args){

        final double deg2Rad = Math.PI / 180.0; //degree to Radian
        final double Rad2deg = 180.0 / Math.PI; //Radian to degree
        double bearing =  90; //direction
        double angle = 60; //sector angle   
        double R = 6371.0; //Radius of earth

        double lat = 12.926428 * deg2Rad;
        double lon = 77.677705 * deg2Rad;

        double d = 5; 

        Geopoint[] array = new Geopoint[N];

        double A = bearing - angle * 0.5;    // starting angle / bearing
        double dA = angle / (double)(N - 1); // angle step between adjacent points

        /* convert lat, lon to cartesian here! */
        double  x = R * Math.cos(lat) * Math.cos(lon);
        System.out.println(x);
        double  y = R * Math.cos(lat) * Math.sin(lon);
        System.out.println(y);
        double  z = R * Math.sin(lat);
        System.out.println(z);


        for (int i = 0; i < N; i++, A += dA)
        {
          double c = Math.cos(A * deg2Rad), 
                 s = Math.sin(A * deg2Rad);

          System.out.println( "C : " + c);
          System.out.println( "S : " + s);

          double x1 = (x + d * c) ;

          double y1 = (y + d * s) ;

          //Convert back to Geopoint
          lat = Math.asin(z / R) * Rad2deg;
          lon = Math.atan2(y1, x1) * Rad2deg;

          array[i] = new Geopoint(lon , lat );
        }

        // return array 
        for ( int i = 0; i < array.length; i++ )
            System.out.println("points," + i + "," + array[i]); 
    }

}

对于上面的代码,我得到低于输出

输出

points,0,{ "lon":130.56759538189806, "lat":20.62976857973366, "geoadress":"null" }
points,1,{ "lon":130.56753333442796, "lat":20.62976857973366, "geoadress":"null" }
points,2,{ "lon":130.56747144031073, "lat":20.62976857973366, "geoadress":"null" }
points,3,{ "lon":130.56740969980146, "lat":20.62976857973366, "geoadress":"null" }
points,4,{ "lon":130.5673481131545, "lat":20.62976857973366, "geoadress":"null" }
points,5,{ "lon":130.5672866806237, "lat":20.62976857973366, "geoadress":"null" }
points,6,{ "lon":130.5672254024622, "lat":20.62976857973366, "geoadress":"null" }
points,7,{ "lon":130.5671642789225, "lat":20.62976857973366, "geoadress":"null" }
points,8,{ "lon":130.5671033102564, "lat":20.62976857973366, "geoadress":"null" }
points,9,{ "lon":130.56704249671517, "lat":20.62976857973366, "geoadress":"null" }

但是这个输出是错误的。我不知道我哪里出错了。

输出

latlon 更改为弧度后,这是我的结果。

points,0,12.926428,77.677705
points,1,12.926428,77.6917252889466
points,2,12.926428,77.68652371253442
points,3,12.926428,77.68120259629767
points,4,12.926428,77.67583406750569
points,5,12.926428,77.67049090073982
points,6,12.926428,77.6652455243131
points,7,12.926428,77.6601690315512
points,8,12.926428,77.65533021080672
points,9,12.926428,77.65079460778875
points,10,12.926428,77.64662363329005

因为我是 dong 这个lat = Math.asin(z / R) * Rad2deg; 从笛卡尔转换我得到所有 lat 相同。我不知道如何解决这个问题。

结果

基于iant代码

结果_1#

我已经计算了 btw (lat,lon) 到弧上每个点的距离。它应该导致相同的距离。 iant查看结果距离有轻微变化。

type,id,lat,lon points,1,12.926428,77.677705 Distance in mtrs : 0.0 points,2,12.92657150782396,77.67778916970093 Distance in mtrs : 9.971162660481445 points,3,12.926578367173896,77.67778862221844 Distance in mtrs : 9.971162660481445 points,4,12.926585180719618,77.67778804926368 Distance in mtrs : 9.971162660481445 points,5,12.926591946385617,77.67778745101116 Distance in mtrs : 9.97070966260917 points,6,12.92659866211097,77.67778682764309 Distance in mtrs : 9.971162660481445 points,7,12.926605325849975,77.6777861793494 Distance in mtrs : 9.971162660481445 points,8,12.926611935572756,77.67778550632754 Distance in mtrs : 9.97070966260917 points,9,12.926618489265902,77.67778480878253 Distance in mtrs : 9.97070966260917 points,10,12.92662498493306,77.67778408692685 Distance in mtrs : 9.971162660481445 points,11,12.926631420595564,77.67778334098041 Distance in mtrs : 9.97070966260917 points,12,12.926637794293018,77.67778257117044 Distance in mtrs : 9.97070966260917 points,13,12.926644104083913,77.67778177773138 Distance in mtrs : 9.97070966260917 points,14,12.9266503480462,77.67778096090498 Distance in mtrs : 9.97070966260917 points,15,12.926656524277885,77.67778012094006 Distance in mtrs : 9.970256644154967 points,16,12.926662630897608,77.67777925809244 Distance in mtrs : 9.970256644154967 points,17,12.926668666045215,77.67777837262499 Distance in mtrs : 9.97070966260917 points,18,12.926674627882324,77.67777746480742 Distance in mtrs : 9.97070966260917 points,19,12.92668051459289,77.67777653491626 Distance in mtrs : 9.970256644154967 points,20,12.926686324383741,77.6777755832348 Distance in mtrs : 9.970256644154967 points,21,12.926692055485155,77.67777461005294 Distance in mtrs : 9.970256644154967 points,22,12.926428,77.677705 Distance in mtrs : 0.0

距离计算

public static double distanceOf(Geopoint a, Geopoint b) {
    if (a.isValid() && b.isValid()) {
      double distFactor = Math.acos(Math.sin(Math.toRadians(a.getLat())) * Math.sin(Math.toRadians(b.getLat()))
          + Math.cos(Math.toRadians(a.getLat())) * Math.cos(Math.toRadians(b.getLat()))
              * Math.cos(Math.toRadians(b.getLon()) - Math.toRadians(a.getLon())));
      return 6378.388 * distFactor;
    }
    return -1;
  }

【问题讨论】:

  • 你是如何计算距离的?我正在使用 WGS84 Ellipsoid 和 Karney 算法 CFF Karney,* dx.doi.org/10.1007/s00190-012-0578-z"> * 测地线算法,* J. Geodesy 87,43–55 ( 2013) * (geographiclib.sf.net/geod-addenda.html">addenda</…)
  • 你使用的那个我不知道。我已经添加了代码
  • 您使用什么工具来查看这些点在地图上的外观?因为软件 Tablue 以某种奇怪的方式显示。但是当计算距离与给定的lat,lon 等距时。
  • 我使用 QGIS (qgis.org) - 您假设地球是球形的,但靠近北极的位置非常不准确。

标签: java math geometry geospatial bearing


【解决方案1】:

当您说要绘制弧线时,我假设您的意思是使用 Java Swing。如果是这种情况,那么 API 已经为您做了很多工作。例如,Arc2D.Float 类有一个构造函数(有关详细信息,请参阅javadoc),它允许您定义要绘制的弧的位置和范围。 xywh 参数将根据原点的位置和距离/半径进行设置。 startextent 参数将分别设置为 bearing - angle / 2angletype 参数将是 Arc2D.PIE 如果您希望它看起来像您问题中的图表。

创建Arc2D 后,您可以使用Graphics2D.draw 绘制它。

我不明白您将距离和角度计算为速度的函数是什么意思。我认为您还需要一个时间参数来计算距离,并且不可能从您的问题中看出速度和角度之间的关系应该是什么。

【讨论】:

  • 我添加了我的项目的更多细节。
【解决方案2】:
const double deg2Rad = Math.PI / 180.0;

// N is the number of points you want on the arc
// If you don't want to pass this, then set it to constant
// e.g. const int N = 15;

Point[] array = new Point[N];
double A = bearing - angle * 0.5;    // starting angle / bearing
double dA = angle / (double)(N - 1); // angle step between adjacent points

double x, y = /* convert lat, lon to cartesian here! */

for (int i = 0; i < N; i++, A += dA)
{
  double c = Math.cos(A * deg2Rad), 
         s = Math.sin(A * deg2Rad);
  array[i] = new Point(x + d * c, y + d * s);
}

// return array

【讨论】:

  • 我不想绘制扇区(即我不希望它在视觉上)但我需要扇区的点(当我加入这些点时它应该形成一个扇区),比如我们得到了一个多边形。
  • 抱歉,我的问题写错了。我已经编辑过了。
  • @ShreyasRaoB 但如果它是您想要的 points 列表,您需要的精度是多少?即是否应该有很多点来给出准确的表示?如果有多少?你打算把它指定为函数调用的参数吗?
  • 不,我没有指定任何关于我需要多少点的参数,但它应该类似于一个扇区。
  • 所以数组会有笛卡尔坐标。我是否必须将其转换回 lat 和 lon 才能在地图中看到它的样子?
【解决方案3】:

我本周早些时候回答了very similar question - GeoTools 提供了创建满足这些要求的弧所需的所有工具 - GeodeticCalculator 允许您指定起点、方位角和距离,并将返回给您目的地点。使用它很容易创建任何距离和宽度的弧。

完整的代码是here,它解决了另一个问题。您需要根据需要参数化宽度(可能是弧中的步数)。

编辑

这确实会产生弧线:

POLYGON((12.926428 77.677705,12.926571507823445 77.67778916970063,12.926578367173352 77.67778862221815,12.926585180719048 77.67778804926338,12.926591946385022 77.67778745101086,12.926598662110349 77.67778682764279,12.926605325849323 77.6777861793491,12.926611935572092 77.67778550632724,12.926618489265206 77.67778480878223,12.926624984932337 77.67778408692658,12.926631420594818 77.67778334098014,12.926637794292239 77.67778257117014,12.926644104083113 77.67778177773111,12.926650348045378 77.67778096090471,12.926656524277035 77.67778012093977 ,12.926662630896734 77.67777925809216,12.926668666044314 77.67777837262472,12.926674627881402 77.67777746480715,12.926680514591945 77.67777653491602,12.92668632438278 77.67777558323456,12.926692055484166 77.67777461005268,12.926428 77.677705))

这仅取决于您如何看待它 - 遥远的北方(您在斯瓦尔巴群岛工作?)由于地球的曲率,事情看起来很奇怪,所以在像 Plate Carree (WGS84) 这样的平面投影中它不会看起来像一个弧线。

但在等距投影(旨在保持距离看起来正确)中,它是一个弧。

当然,如果您在印度,那么在 EPSG:4326 中看起来不错。

【讨论】:

  • 如何将 GeoTools 添加到 maven pom.xml?你能帮帮我吗?
  • 我使用了你的代码。仅将(lat,lon) 更改为(12.926428 , 77.677705) 但是当看到结果时它没有形成弧。我已经用结果更新了我的问题。请检查一下。
  • 你给的方位角值是多少?除了lat,lon 之外,您对您的代码所做的任何更改?
  • 顺便说一下,我使用 Tablue 软件来了解这些点在地图中的外观
  • 方位角从北方顺时针10度,长30m
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-12
  • 1970-01-01
  • 2012-09-21
  • 2019-06-18
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
相关资源
最近更新 更多