Convert GPS Coordinates to Match Custom 2d outdoor layout Image

282

Solution 1

First of All, Yes you can do this with high accuracy if the GPS coordinates are accurate.

Second, the main problem is rotation if the field are straight with lat lng lines this would be easy and straightforward (no bun intended).

The easy way is to convert coordinate to rotated image similar to the real field then rotated every X,Y point to the new straight image. (see the image below)

enter image description here

Here is how to rotate x,y knowing the angel:

double x,y;
double newX,newY;
double angle;

//Test values:
x=1;
y=1;
angle = 45;

double rad = angle*M_PI/180;

newX = x * cos(rad) - y * sin(rad);
newY = y * cos(rad) + x * sin(rad);

UPDATE

long double lat1,lat2,lng1,lng2; //fill these with GPS coordinates
double x1,x2,y1,y2;//fill these of rectangle coordinate in the image

long double realWidth = distance(lat1, long1,lat2,long1);// distance btween the upper left corner & the upper right corner
long double realHieght = distance(lat1, long1,lat1,long2);// distance btween the upper left corner & the lower left corner

double image1Width = abs(x2-x1);
double image1Hieght = abs(y2-y1);

long double playerLat,playerLng;//fill the player lat lng GPS coordiantes 

POINT imagePlayerXY = convertGPS2xy(lat1,  lng1, playerLat,  playerLng, realWidth, realHieght, image1Width, image1Hieght);
//NOW rotate imagePlayerXY.x & imagePlayerXY.y to the final image
POINT convertGPS2xy(long double latOrigin, long double lngOrigin,long double playerLat, long double playerLng,long double realWidth,long double realHieght, double image1Width,double image1Hieght)
{
    double lngRatio2Width = distance(playerLat,playerLng, playerLat,lngOrigin ) / realWidth; //horizantal distance from the player place to rectangle origin (then compute the width ratio)
    double lngRatio2Hieght = distance(playerLat,playerLng, latOrigin,playerLng ) / realHieght; //virtical distance from the player place to rectangle origin (then compute the Hieght ratio)

    POINT imageXY;
    imageXY.x = image1Width * lngRatio2Width;
    imageXY.y = image1Hieght * lngRatio2Hieght;

    return imageXY;
}


long double distance(long double lat1, long double long1,
                     long double lat2, long double long2)
{
    // Convert the latitudes
    // and longitudes
    // from degree to radians.
    lat1 = toRadians(lat1);
    long1 = toRadians(long1);
    lat2 = toRadians(lat2);
    long2 = toRadians(long2);
     
    // Haversine Formula
    long double dlong = long2 - long1;
    long double dlat = lat2 - lat1;
 
    long double ans = pow(sin(dlat / 2), 2) +
                          cos(lat1) * cos(lat2) *
                          pow(sin(dlong / 2), 2);
 
    ans = 2 * asin(sqrt(ans));
 
    // Radius of Earth in
    // Kilometers, R = 6371
    // Use R = 3956 for miles
    long double R = 6371;
     
    // Calculate the result
    ans = ans * R;
 
    return ans;
}

Solution 2

Yes, the answer in the link will work but under the condition that the goalposts in the field are pointing in exactly North and south directions. What they have basically done in the two links is downscaling the GPS coordinates to fit into your screen, so while down scaling only if the goalposts are pointing in east and west direction like the image you attached the scaling will work.

But in real data, the field can be located at any angle, maybe one goal post is NE and the other is SW. So in order to solve that problem also use @Jabbar's answer.

Solution 3

The bounty is finished, but there is a general algorithm for what you're trying to do that hasn't been described yet.

This approach removes the problem of having to correct for the real field's orientation and also the problem of correcting for any difference in aspect ratio between the real field and your pixelated display.

We split the problem into two main parts:

Field 1: the real world field where player positions will be treated as vectors (triangulated using field corners)

Field 2: the pixelated canvas that you happen to be using as the final display (which does not need to be the exact same aspect ratio as the real field).

Steps:

  1. Decide how you want to map the orientation from the real field to the display by labelling the corners (A,B,C,D) correspondingly.

enter image description here

  1. For each player, draw a line to corner A and corner B forming a triangle

enter image description here

  1. Using pythagorian theorem, calculate the lengths of each side (a,b,p) of the triangle using the gps co-ordinates of points A, B, and P.

enter image description here

  1. Using the law of cosines, calculate the angle at corner A

enter image description here

  1. Using law of [cos = adj/hyp], get the players co-ordinate position (W,H) relative to corner A

enter image description here

  1. convert these W and H values to a percentage of the real field's width and height -- a number between 0 and 1.

  2. Using the numbers from step 7, plot the player's position on Field 2.

Share:
282
Drake chmon
Author by

Drake chmon

Updated on January 03, 2023

Comments

  • Drake chmon
    Drake chmon over 1 year

    I don't know if this is possible, but I am trying to take the image of a custom outdoor football field layout and have the players' GPS coordinates correspond to the image xand y position. This way, it can be viewed via the app to show the players' current location on the field as a sort of live tracking.

    I have also looked into this Convert GPS coordinates to coordinate plane. The problem is that I don't know if this would work and wanted to confirm beforehand. The image provided in the post was for indoor location, and it was from 11 years ago.

    I used Location and Google Maps packages for flutter. The player's latitude and longitude correspond to the actual latitude and longitude that the simulator in the android studio shows when tested.

    The layout in question and a close comparison to the result I am looking for.

    enter image description here

    Any help on this matter would be appreciated highly, and thanks in advance for all the help.

    Edit:

    After looking more at the matter I tried the answer of this post GPS Conversion - pixel coords to GPS coords, but it wasn't working as intended. I took some points on the image and the correspond coordinates, and followed the same logic that the answer used, but reversed it to give me the actual image X, Ypositions.

    The formula that was given in the post above:

    screenY0 //Screen origin (pixel corresponding to zero degrees latitude)
    worldY0 //World origin (zero degrees latitude)
    screenYscale //Screen scale (distance between 2 pixels)
    worldYscale //World scale (distance between two latitude lines)
    screenYpoint //Screen point (pixel y location)
    worldYpoint //World point (latitude on the ground)   
    
    screenY0 + screenYscale * screenYpoint = worldY0 + worldYscale * worldYpoint.
    

    The post said there would be some inaccuracy about 7.4 meters. The solution provided works only for the points or areas close to the chosen point. When a player would move a bit more, the marker for that player would jump outside of the image area or be very far off.

    Edit2:

    I have tried the solution from this post Convert GPS coordinates to coordinate plane with the following formula to calculate the Xposition:

    delta_long to be the differences, in degrees, in the GPS of the fields corners. delta_xis the width of the image.

    horizontal_scale = delta_x/(cos(latitude)*delta_long) and then x = ( lon - lon_origin ) * horizontal_scaleThe issue that I am facing right now is that the marker moves at the opposite x-axis like this, where the black arrow is how the actual player moves and the red arrow shows how the player moves inside the app.

    enter image description here

  • Drake chmon
    Drake chmon over 2 years
    Do you know if the method to convert the GPS coordinates to my image position are correct with the links I provided or do you have another way of calculating it because the two links are very old and thanks in advance for all the help.
  • Drake chmon
    Drake chmon over 2 years
    another follow up question when I rotate my coordinates do I need to do the same for my four corners ?
  • zellez
    zellez over 2 years
    @Drakechmon you need to choose the four corners like the first image that @Jabbar showed in his explanation and rotate only the position of the players x,y
  • Drake chmon
    Drake chmon over 2 years
    I have tried horizontal_scale = delta_x/(cos(latitude)*delta_long) with x = ( lon_origin - lon ) * horizontal_scale from stackoverflow.com/questions/3588653/… but it goes the opposite direction of where the player is supposed to be
  • Nagulan S
    Nagulan S over 2 years
    you have to do both horizontal and vertical scaling
  • Jabbar
    Jabbar over 2 years
    @Drakechmon please check out my update, it is very rough but I think it will get the job done
  • Drake chmon
    Drake chmon over 2 years
    @Jabbar sorry I have been sick lately and yes your answer helped me with my question and I have awarded the question sorry again for the delay
  • Jabbar
    Jabbar over 2 years
    @drakechmon I hope you get well soon