Tim Falken
Tim Falken

Reputation: 15

Calculating coordinates from reference points

I'm working on a game in Unity where you can walk around in a city that also exists in real life. In the game you should be able to enter real-world coordinates, or use your phone's GPS, and you'll be transported to the in-game position of those coordinates.

For this, i'd need to somehow convert the game coordinates to latitude and longitude coordinates. I have some coordinates from specific buildings, and i figured i might be able to write a script to determine the game coordinates from those reference points.

I've been searching for a bit on Google, and though i have probably come across the right solutions occasionally, i've been unable to understand them enough to use it in my code.

If someone has experience with this, or knows how i could do this, i'd appreciate it if you could help me understand it :)

Edit: Forgot to mention that other previous programmers have already placed the world at some position and rotation they felt like using, which unfortunately i can't simply change without breaking things.

Tim Falken

Upvotes: 0

Views: 2343

Answers (1)

krowe
krowe

Reputation: 2280

This is simple linear math. The main issues you'll come across is the fact that your game coordinate system will be probably be reversed along one or more axis. You'll probably need to reverse the direction along the latitude (Y) axis of your app. Aside from that it is just a simple conversion of the scales. Since you say that this is the map of a real place you should be able to easily figure out the min\max lon\lat which your map covers. Take the absolute value of the difference between these two values and divide that by the width\height of your map in each direction. This will be the change in latitude per map unit value. Store this value and it should be easy to convert both ways between the two units. Make functions that abstract the details and you should have no problems calculating this either way.

I assume that you have been able to retrieve the GPS coordinates OK.

EDIT: By simple linear math I mean something like this (this is C++ style psuedo code and completely untested; in a real world example the constants would all be member variables instead):

define('MAP_WIDTH', 1000);
define('MAP_HEIGHT', 1000);

define('MIN_LON', 25.333);
define('MIN_LAT', 20.333);
define('MAX_LON', 27.25);
define('MAX_LAT', 20.50);

class CoordConversion {
    float XScale=abs(MAX_LON-MIN_LON)/MAP_WIDTH;
    float YScale=abs(MAX_LAT-MIN_LAT)/MAP_HEIGHT;
    int LonDir = MIN_LON<MAX_LON?1:-1;
    int LatDir = MIN_LAT<MAX_LAT?1:-1;

    public static float GetXFromLon(float lon) {
      return (this.LonDir>0?(lon-MIN_LON):(lon-MAX_LON))*this.XScale;
    }
    public static float GetYFromLat(float lat) {
      return (this.LatDir >0?(lat-MIN_LAT):(lat-MAX_LAT))*this.YScale;
    }
    public static float GetLonFromX(float x) {
      return (this.LonDir>0?MIN_LON:MAX_LON)+(x/this.XScale);
    }
    public static float GetLatFromY(float y) {
      return (this.LonDir>0?MIN_LAT:MAX_LAT)+(y/this.YScale);
    }
}

EDIT2: In the case that the map is rotated you'll want to use the minimum and maximum lon\lat actually shown on the map. You'll also need to rotate each point after the conversion. I'm not even going to attempt to get this right off the top of my head but I can give your the code you'll need:

POINT rotate_point(float cx,float cy,float angle,POINT p)
{
  float s = sin(angle);
  float c = cos(angle);

  // translate point back to origin:
  p.x -= cx;
  p.y -= cy;

  // rotate point
  float xnew = p.x * c - p.y * s;
  float ynew = p.x * s + p.y * c;

  // translate point back:
  p.x = xnew + cx;
  p.y = ynew + cy;
}

This will need to be done in when returning a game point and also it needs to be done in reverse before using a game point to convert to a lat\lon point.

EDIT3: More help on getting the coordinates of your maps. First find the city or whatever it is on Google maps. Then you can right click the highest point (furthest north) on your maps and find the highest longitude. Repeat this for all four cardinal directions and you should be set.

Upvotes: 1

Related Questions