0

I have a problem. I am trying to write a JAVA code were in given bearing, (lat,lon) , speed I need to get all points which form a sector (like in the diagram (x1,y1) , (x2,y2) and list of points which form an Arc in the direction which is given by bearing (I have very limited knowledge on bearing).

enter image description here

My first thing is to achieve sector based on the direction with hard-coded distance and angle. (i.e fixed values say d = 5km and angle = 60 deg.)

Next Step is based on the speed I want distance d and angle to be calculated like d = func(speed) and angle = func(speed) but this will be later.

Since bearing is given in terms of degree I don't know how to calculate direction. What i was thinking like If i am able to convert the bearing to a unit vector on the same direction. then i think we can draw the sector.

Correct me if i am wrong in my theory/explanation. Please I need help guys.....

More details:

I am working on a small project were in while tracking through google maps on phone I can get (lat,lon) - current position of user, bearing - in the direction in which I am headed and speed - what speed i am travelling.

Distance and angle relation with speed :

If i am travelling with more speed the d should be more and angle should be less (arc will be more narrower)

If i am travelling with less speed then d should be less and `angle should be more (arc will be wider)

If i am stationary the speed is 0 , then i will draw a circle around my current (lat,lon) and find my POI around me.

Once i get this sector i will use Elastic search ( It provide some func() like nearby search and polygon search) to get all the Point Of Interest along my way while i am tracking

Ultimately, while i am driving i want to show user what are the POI he gets along his way. ( we don't know user's destination)

UPDATE

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]); 
    }

}

For the above code i am getting below output

Output

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" }

But this output is wrong. I don't know where i am going wrong.

Output

After changing lat and lon to radians this is my result.

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

Since I am dong this lat = Math.asin(z / R) * Rad2deg; to convert from cartesian i am getting all lat same. I don't know how to solve this.

Resut

Based on iant code

enter image description here

Result_1#

I have computed the distance btw (lat,lon) to every point on the arc. It should result in same distance. iant check the result there is slight variation in the distance.

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

Distance Calculation

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;
  }
Shreyas Rao B
  • 193
  • 4
  • 17

3 Answers3

0

When you say that you want to draw the arc I assume you mean using Java Swing. If that's the case then the API already does a lot of the work for you. For example, the Arc2D.Float class has a constructor (see javadoc for details) that lets you define the position and extent of the arc to draw. The x, y, w, h arguments would be set according to the position of the origin and the distance/radius. The start and extent arguments would be set as bearing - angle / 2 and angle respectively. The type argument would be Arc2D.PIE if you want it to look like the diagram in your question.

Once you have created the Arc2D you can draw it using Graphics2D.draw.

I don't understand what you mean by calculating distance and angle as a function of speed. I would think you would need a time argument as well to calculate distance and it's impossible to tell from your question what the relationship between speed and angle should be.

sprinter
  • 27,148
  • 6
  • 47
  • 78
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
  • I don't want to draw the sector (i.e I don't want it visually) but I need the points of the sector ( when I join those point it should form a Sector) , like the one we got for polygon. – Shreyas Rao B Aug 05 '16 at 09:20
  • Sorry I had written my question wrong. I have edited it. – Shreyas Rao B Aug 05 '16 at 09:21
  • @ShreyasRaoB but if it's a list of _points_ you want, what's the precision you need? i.e. should there been many points to give an accurate representation? if so how many? are you going to specify this as a parameter to the function call? –  Aug 05 '16 at 09:37
  • No I am not specifying any parameter regarding how many points I need but it should appx resemble a sector. – Shreyas Rao B Aug 05 '16 at 09:41
  • So array will have points in cartesian. Do I have to convert it back to lat and lon to see in map how it looks like? – Shreyas Rao B Aug 05 '16 at 09:47
  • Unless d is of the order of 100's of km, this approach is a valid approximation, so yes convert it back. –  Aug 05 '16 at 09:54
  • Can you please mention what does `A` and `dA` actually mean? I meant why are you doing `bearing - angle * 0.5 ` and similarly for `dA` ? – Shreyas Rao B Aug 05 '16 at 10:00
  • Bearing is something which tells you the direction ( as per my understanding). The above code will give me a sector in the bearing direction rite? ( i will check it but need confirmation from you) – Shreyas Rao B Aug 05 '16 at 10:09
  • I am finding very difficult to convert back to lat, lon from cartesian. Not finding valid answer. – Shreyas Rao B Aug 08 '16 at 06:20
  • @ShreyasRaoB in the code you are converting lat long to 3D coordinates, not 2D map coordinates. –  Aug 08 '16 at 11:18
  • No where i found other conversion from the one I used in the code. I don't know. – Shreyas Rao B Aug 08 '16 at 11:42
  • i forgot to convert `(lat,lon)` to raidans first, Now i did that and updated the same in the question also added my new output. But still I didn't find how to convert geopoint to `x,y` coordinate – Shreyas Rao B Aug 08 '16 at 12:08
  • You know how to convert to cartesian and then back to ? – Shreyas Rao B Aug 08 '16 at 14:55
0

I answered a very similar question earlier this week - GeoTools provides all the tools you need to create an arc which fulfils these requirements - GeodeticCalculator allows you to specify a start point, azimuth and distance and will return you the destination point. Using this it is easy to create an arc of any distance and width.

The full code is here that solved the other problem. You would need to parameterize the width (and may be the number of steps in the arc) for your needs.

EDIT

This does produce an arc:

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))

It just depends on how you look at it - that far north (you are working in Svalbard?) things look weird due to the curvature of the earth, so in a flat projection like Plate Carree (WGS84) it doesn't look like an arc.

Polygon in EPSG:4326 (WGS84)

But in an equidistant projection (designed to keep distances looking correct) it is an arc.

Polygon in EPSG:102016 (Polar Azimuthal Equidistant)

Of course if you are in India then it looks fine in EPSG:4326.

Ian Turton
  • 10,018
  • 1
  • 28
  • 47