Loading...
Logo
Processing Forum
Copy code
    I am using code from Till Nagel to project a world map and then plot data based on lat and lon coordinates. But now I would to retrieve lat and lon coordinates of mouse position. By giving mouseX and mouseY, it should return longitude and latitude on the map. Can someone please help? Below is the code that I use:

    Copy code
    1. /**
    2.  * Utility class to convert between geo-locations and Cartesian screen coordinates.
    3.  * Can be used with a bounding box defining the map section.
    4.  *
    5.  * (c) 2011 Till Nagel, tillnagel.com
    6.  */
    7. public class MercatorMap {
    8.   
    9.   public static final float DEFAULT_TOP_LATITUDE = 80;
    10.   public static final float DEFAULT_BOTTOM_LATITUDE = -80;
    11.   public static final float DEFAULT_LEFT_LONGITUDE = -180;
    12.   public static final float DEFAULT_RIGHT_LONGITUDE = 180;
    13.   
    14.   /** Horizontal dimension of this map, in pixels. */
    15.   protected float mapScreenWidth;
    16.   /** Vertical dimension of this map, in pixels. */
    17.   protected float mapScreenHeight;

    18.   /** Northern border of this map, in degrees. */
    19.   protected float topLatitude;
    20.   /** Southern border of this map, in degrees. */
    21.   protected float bottomLatitude;
    22.   /** Western border of this map, in degrees. */
    23.   protected float leftLongitude;
    24.   /** Eastern border of this map, in degrees. */
    25.   protected float rightLongitude;

    26.   private float topLatitudeRelative;
    27.   private float bottomLatitudeRelative;
    28.   private float leftLongitudeRadians;
    29.   private float rightLongitudeRadians;

    30.   public MercatorMap(float mapScreenWidth, float mapScreenHeight) {
    31.     this(mapScreenWidth, mapScreenHeight, DEFAULT_TOP_LATITUDE, DEFAULT_BOTTOM_LATITUDE, DEFAULT_LEFT_LONGITUDE, DEFAULT_RIGHT_LONGITUDE);
    32.   }
    33.   
    34.   /**
    35.    * Creates a new MercatorMap with dimensions and bounding box to convert between geo-locations and screen coordinates.
    36.    *
    37.    * @param mapScreenWidth Horizontal dimension of this map, in pixels.
    38.    * @param mapScreenHeight Vertical dimension of this map, in pixels.
    39.    * @param topLatitude Northern border of this map, in degrees.
    40.    * @param bottomLatitude Southern border of this map, in degrees.
    41.    * @param leftLongitude Western border of this map, in degrees.
    42.    * @param rightLongitude Eastern border of this map, in degrees.
    43.    */
    44.   public MercatorMap(float mapScreenWidth, float mapScreenHeight, float topLatitude, float bottomLatitude, float leftLongitude, float rightLongitude) {
    45.     this.mapScreenWidth = mapScreenWidth;
    46.     this.mapScreenHeight = mapScreenHeight;
    47.     this.topLatitude = topLatitude;
    48.     this.bottomLatitude = bottomLatitude;
    49.     this.leftLongitude = leftLongitude;
    50.     this.rightLongitude = rightLongitude;
    51.     this.topLatitudeRelative = getScreenYRelative(topLatitude);
    52.     this.bottomLatitudeRelative = getScreenYRelative(bottomLatitude);
    53.     this.leftLongitudeRadians = getRadians(leftLongitude);
    54.     this.rightLongitudeRadians = getRadians(rightLongitude);
    55.   }

    56.   /**
    57.    * Projects the geo location to Cartesian coordinates, using the Mercator projection.
    58.    *
    59.    * @param geoLocation Geo location with (latitude, longitude) in degrees.
    60.    * @returns The screen coordinates with (x, y).
    61.    */
    62.   public PVector getScreenLocation(PVector geoLocation) {
    63.     float latitudeInDegrees = geoLocation.x;
    64.     float longitudeInDegrees = geoLocation.y;
    65.     return new PVector(getScreenX(longitudeInDegrees), getScreenY(latitudeInDegrees));

    66.   }
    67.   

    68.   private float getScreenYRelative(float latitudeInDegrees) {
    69.     return log(tan(latitudeInDegrees / 360f * PI + PI / 4));
    70.   }

    71.   protected float getScreenY(float latitudeInDegrees) {
    72.     return mapScreenHeight * (getScreenYRelative(latitudeInDegrees) - topLatitudeRelative) / (bottomLatitudeRelative - topLatitudeRelative);
    73.   }
    74.   
    75.   private float getRadians(float deg) {
    76.     return deg * PI / 180;
    77.   }


    78.   protected float getScreenX(float longitudeInDegrees) {
    79.     float longitudeInRadians = getRadians(longitudeInDegrees);
    80.     return mapScreenWidth * (longitudeInRadians - leftLongitudeRadians) / (rightLongitudeRadians - leftLongitudeRadians);
    81.   }
    82. }

    Replies(1)

    You have some functions that take the Lat and Long and find the X and Y.
    Those functions use math to work it out.
    All you need to do is work out how to do that math in reverse.
    This involves understanding how the X and Y are determined, and solving that equation for the Lat and Long.

    Here's how the X is determined:

    X = mapScreenWidth * ( getRadians(longitudeInDegrees)  - leftLongitudeRadians) / (rightLongitudeRadians - leftLongitudeRadians);

    If we give each of those variables a simpler name...

    X = W * ( O - L ) / (R - L )

    Now, which variable are we trying to solve for? O...

    X * ( R - L ) = W * (O - L )
    ( X * ( R - L ) / W = ( O - L )
    ( ( X * ( R - L ) / W ) + L = O

    See?