Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Longitude Laltitude of a point in my Worldmap in Mollweide projection

I searched about a day now, but didnt find any example for my problem in Javacode.

I have a worldmap with a size of 2000*1400 Pixels with a 'Mollweide' projection. How can I find out what is the longitude and laltitude of the point (500,300) in my map ? I would like to code this in Java.

I tried to do this with the 'Java Map Projection Library' :

Point2D.Double pointonmap = null;
Point2D.Double latlon = null;
MolleweideProjection molproj=new MolleweideProjection();

pointonmap = new Point2D.Double (1400,1000);  

latlon=molproj.inverseTransform(pointonmap,new Point2D.Double ());

System.out.println("latlon: " + latlon.getX() + ", " + latlon.getY());

Could anyone help me with that ? Codeexample or hint.

thanks and regards

like image 649
mcfly soft Avatar asked Aug 17 '12 14:08

mcfly soft


People also ask

How do you read a Mollweide projection?

In Mollweide projection, the central meridian and the equator are projected as a straight perpendicular line. The equator is twice the length of the projected central meridian. The 90 degrees west and 90 degrees east form a circle, while the rest of the meridian assume the same spacing at the equator.

What is a Mollweide projection map?

The Mollweide projection is an equal-area pseudocylindrical map projection displaying the world in a form of an ellipse with axes in a 2:1 ratio. It is also known as Babinet, elliptical, homolographic, or homalographic projection. The projection is appropriate for thematic and other world maps requiring accurate areas.

What geometric properties does Mollweide preserve?

The Mollweide projection is an equal-area map projection. It preserves the size of figures, but heavily distorts the shapes when getting nearer to the edge of the map. Mollweide maps are especially used for global maps where its equal-area property helps to display global distributions.


2 Answers

Wikipedia has most of the information you need:

enter image description here

These formulas assume a few things, as usual. They speak in projected dimension, which is smaller than the component. [0,0] is at the centre, not top left. Y coordinate goes up rather than goes down. And the result is in radius instead of degree. Fix these and they'll work for you.

Since you didn't provide a link, I assume you are using the Java Map Projection Library on GitHub. Without documentation and with limited time, I can't understand inverseTransform well enough to fix your code; but the bundled MapComponent is simpler to code:

map.addMouseListener( new MouseAdapter() { @Override public void mouseClicked( MouseEvent e ) {

   double x = e.getX() - map.getWidth() / 2, // Mouse X with [0,0] at centre.
          y = e.getY() - map.getHeight() / 2, // Mouse Y with [0,0] at centre.
          // Max Y of projected map, in pixel with [0,0] at centre.
          maxY = map.getMapExtension().getMaxY() *  map.getScaleToShowAll(), 
          sqrt2 = Math.sqrt( 2 ), // Can be optimised away, but let's be faithful.
          R = maxY / sqrt2, // Radius of projection, in pixel.
          theta = Math.asin( y / ( R * sqrt2 ) );
   int    delta_long = -lon0Slider.getValue(); // Longtitude shift from -180 to 180.

          // Find lat long in radius and converts to degree.
   double latInRad  = Math.asin( -( 2 * theta + Math.sin( 2 * theta ) ) / Math.PI ),
          latitude  = Math.toDegrees( latInRad ),
          longInRad = Math.PI * x / ( 2 * R * sqrt2 * Math.cos( theta ) ),
          longitude = Math.toDegrees( longInRad ) + delta_long;

   System.out.println( "Lat: " + latitude + ", Long: " + longitude );
}

You can paste this code into the constructor of ch.ethz.karto.gui.ProjectionSelectionPanel. The IDE should reports that two methods of the map is private, and you need to change them to public first (or use reflection). Then launch it, select Mollweide, click on the globe and watch the console. Feel free to resize the window.

like image 117
Sheepy Avatar answered Oct 24 '22 14:10

Sheepy


This answer uses information from the English Wikipedia entry on Mollweide projection. I've pretty much transcribed the formula from there verbatim.

The short answer, so you can write your own code:

Get the map's radius, r:
projectionWidth /(2 * √2)

Get theta, the point's angle along the map:
arcsine(y / (r * √2))

Note: Arcsine is the inverse of sine. Use Math.asin(a) in java

Get the latitude:
arcsine((2 * theta + sine(2 * theta)) / PI)

Get the longitude:
PI * x / (2 * R * √2 * cosine(theta)) + central meridian.

Or you can copyPasta this.
It's not very efficient; x and y are spec as doubles becaus too lazy to write typecast avoid narrowing
no-setters no-getters all-vars public
all-world-one-love Dr. Bronner's TV-dinners solve your problems for you
and stuff
enoj

public class MolleweidePoint
{
    public double x, y, latitude, longitude;

    public MolleweidePoint(double projectionWidth, double x, double y)
    {
        double rootTwo = Math.sqrt(2);
        double r = projectionWidth / 2 / rootTwo;
        double theta = Math.asin(y / r / rootTwo);

        this.x = x;
        this.y = y;
        longitude = Math.PI * x / 2 / r / rootTwo / Math.cos(theta);
        latitude = Math.asin(2 * theta + Math.sin(2 * theta) / Math.PI);
    }
}

After calling the constructor like

MolleweidePoint ted = new MolleweidePoint(projection.width, 300, 500)

you can get the latitude and longitude from ted.longitude and ted.latitude. Also, longitude may have to be adjusted based on where the central meridian is placed on your projection.

like image 40
Mark Peschel Avatar answered Oct 24 '22 15:10

Mark Peschel