9

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

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

halfer
  • 19,824
  • 17
  • 99
  • 186
  • 3
    Yes, thhis is possible. But it is very difficult to do accurately. The best approach is probably to use a coordinate transformation library and the local, projected system at the given location. Which coordinate system fits best will depend on where you are, the size of your map and the accuracy required. – PMF Jan 06 '22 at 06:34
  • 1
    What are you actually trying to do? Example - have a projection screen at a football game and have the players each carry a gps tracker... so they can show up on a projection screen? Is that what you're doing? Who is "the user"? What is "the simulator"? What is an "images pin position" ? – Nerdy Bunz Jan 09 '22 at 22:25
  • @NerdyBunz hopefully, I added more clarification to what I am trying to do, and if it is not enough, just let me know – Drake chmon Jan 09 '22 at 23:14
  • Figure out the real GPS coordinates of each of the four corners. For a player that is within the bounds of the field, figure out how to express their position as a percentage of X/Y, so for example if a player is in the middle of the field, their position calculated from their GPS coordinates is 0.5,0.5. Then use that percentage to calculate the position on the image -- so if your image is 600x300 pixels, their position would be (300,150). If this answer is too general, then please edit your question and focus on which part your are having difficulty with. – Nerdy Bunz Jan 10 '22 at 05:39

3 Answers3

3

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;
}
user16930239
  • 6,319
  • 2
  • 9
  • 33
  • 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 Jan 10 '22 at 15:46
  • another follow up question when I rotate my coordinates do I need to do the same for my four corners ? – Drake chmon Jan 10 '22 at 21:12
  • 1
    @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` – zellez Jan 10 '22 at 22:35
  • @Drakechmon please check out my update, it is very rough but I think it will get the job done – user16930239 Jan 12 '22 at 08:24
  • 1
    @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 – Drake chmon Jan 16 '22 at 01:30
  • @drakechmon I hope you get well soon – user16930239 Jan 16 '22 at 06:10
  • @Jabbar How do I do this if I have the lat, lng values of all corners of the real field (not the one shown as in the image)? – Aldrin Joe Mathew Nov 21 '22 at 06:52
  • @AldrinJoeMathew x1=min(lng1,lng2); x2=max(lng1,lng2); y1=min(lat1,lat2); y2=max(lat1,lat2); and you've got your bounding rectangle. – user16930239 Nov 21 '22 at 08:24
3

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.

Nagulan S
  • 617
  • 5
  • 11
  • I have tried `horizontal_scale = delta_x/(cos(latitude)*delta_long)` with `x = ( lon_origin - lon ) * horizontal_scale` from https://stackoverflow.com/questions/3588653/convert-gps-coordinates-to-coordinate-plane but it goes the opposite direction of where the player is supposed to be – Drake chmon Jan 11 '22 at 00:15
  • you have to do both horizontal and vertical scaling – Nagulan S Jan 11 '22 at 05:50
2

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.

halfer
  • 19,824
  • 17
  • 99
  • 186
Nerdy Bunz
  • 6,040
  • 10
  • 41
  • 100