需要一个基于方位,地理位置,距离和角度的扇区

时间:2016-08-05 06:03:40

标签: java math geometry geospatial bearing

我有问题。我正在尝试编写一个 JAVA 代码,在给定的方位,(纬度,经度),速度我需要获得构成扇区的所有点(如图中所示) x1,y1),(x2,y2)以及在轴承给出的方向上形成的点列表(我对轴承的知识非常有限)。

enter image description here

我的第一件事是基于硬编码距离和角度的方向来实现扇区。 (即固定值表示d = 5kmangle = 60 deg。)

下一步是基于我想要的距离dangle的计算速度,如d = func(speed)angle = {{1}但是这会晚些。

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

如果我的理论/解释错了,请纠正我。请我帮帮忙......

更多详情:

我正在开展一个小型项目,同时通过手机上的谷歌地图进行跟踪,我可以func(speed)(lat,lon) - current position of userbearing - in the direction in which I am headed

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

如果我以更快的速度旅行,speed - what speed i am travelling应该更多,d应该更少(弧度会更窄)

如果我的旅行速度较慢,那么angle应该更少,而且角度应该更大(弧度会更宽)

如果我是静止的,速度是d,那么我将围绕当前的0绘制一个圆圈并在我周围找到我的POI。

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

最终,在我开车的时候,我想向用户展示他沿途的POI是什么。 (我们不知道用户的目的地)

更新

(lat,lon)

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

输出

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" } lat更改为弧度后,这是我的结果。

lon

因为我这是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 来自笛卡儿的转换,所以我得到的所有相同。我不知道如何解决这个问题。

Resut

基于lat = Math.asin(z / R) * Rad2deg;代码

enter image description here

Result_1#

我已经计算了弧线上每个点的距离btw iant。它应该导致相同的距离。 (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

3 个答案:

答案 0 :(得分:0)

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

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

通过计算距离和角度作为速度的函数,我不明白你的意思。我认为你还需要一个时间参数来计算距离,从你的问题中无法判断速度和角度之间的关系应该是什么。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我本周早些时候回答了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)的平面投影中它没有看起来像一个圆弧。

Polygon in EPSG:4326 (WGS84)

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

Polygon in EPSG:102016 (Polar Azimuthal Equidistant)

当然,如果你在印度,那么它在EPSG中看起来很好:4326。