Loading...
Logo
Processing Forum

Using a world map in Processing?

in General Discussion  •  Other  •  3 years ago  
Hi folks,

I'm a novice with a question: I have a data set that relates to the size of transportation services in different cities around the world and I want to visualize it by plotting cylinders of different sizes/colors in the various cities.

So first I need a map. Is there a way of loading a map and then using the latitude and longitude coordinates to place other shapes/objects on the map?

I found an earlier discussion on this ( http://processing.org/discourse/yabb2/YaBB.pl?num=1259917547) but the code provided was for a particular map file that I couldn't find.

Thanks in advance for any help!

Replies(3)

Sure -- just take your object and align it along the X axis (assuming Y=up)

Now translate() it by the radius of your globe in X. It will be on the surface at the equator.

Now rotate it around Z by the latitude. It will now be aligned north and south

Now rotate around Y by the longtitude. *voila*!

/// or if not using a globe.... ///

Just translate by latitude and longitude. But beware of non-linearities -- e.g. Mercator's projection

kb, http://www.riftgame.com/
Assuming you want a 2D map of the world, it should be pretty straightforward. The important thing is that you need to know the extent of the map you are drawing in geographical coordinates (lat/long) and that you use a map projection that has a linear relationship between image coordinates and geographical coordinates. A good starting point might be Tom Patterson's beautiful cartography at  Natural Earth .

Personally, I wouldn't use use scale and translate to convert between lat/long and pixel coordinates as this has implications for drawing text and other features on the map. Better is to create a pair of methods that convert from geographic to pixel coordinates, and pixel to geographic coordinates. Below is an example deliberately using a world map that does not use the full global extent (+-180, +-90).



PImage backgroundMap;

float mapGeoLeft   = -125.22;          // Longitude 125 degrees west
float mapGeoRight  =  153.44;          // Longitude 153 degrees east
float mapGeoTop    =   71.89;          // Latitude 72 degrees north.
float mapGeoBottom =  -56.11;          // Latitude 56 degrees south.
                         
float mapScreenWidth,mapScreenHeight;  // Dimension of map in pixels.

void setup()
{
  size(600,350);
  smooth();
  noLoop();
  backgroundMap   = loadImage("world.jpg");
  mapScreenWidth  = width;
  mapScreenHeight = height;
}

void draw()
{
  image(backgroundMap,0,0,mapScreenWidth,mapScreenHeight);
  
  fill(180,120,120);
  strokeWeight(0.5);
  
  PVector p = geoToPixel(new PVector(0.8,51.5));  // London
  ellipse(p.x,p.y,5,10);
  p = geoToPixel(new PVector(-73.9,40.8));        // New York
  ellipse(p.x,p.y,5,10);
  p = geoToPixel(new PVector(139.8,35.7));        // Tokyo
  ellipse(p.x,p.y,5,10); 
  p = geoToPixel(new PVector(151.0,-34.0));       // Sydney
  ellipse(p.x,p.y,5,10);
}

// Converts screen coordinates into geographical coordinates. 
// Useful for interpreting mouse position.
public PVector pixelToGeo(PVector screenLocation)
{
    return new PVector(mapGeoLeft + (mapGeoRight-mapGeoLeft)*(screenLocation.x)/mapScreenWidth,
                       mapGeoTop - (mapGeoTop-mapGeoBottom)*(screenLocation.y)/mapScreenHeight);
}

// Converts geographical coordinates into screen coordinates.
// Useful for drawing geographically referenced items on screen.
public PVector geoToPixel(PVector geoLocation)
{
    return new PVector(mapScreenWidth*(geoLocation.x-mapGeoLeft)/(mapGeoRight-mapGeoLeft),
                       mapScreenHeight - mapScreenHeight*(geoLocation.y-mapGeoBottom)/(mapGeoTop-mapGeoBottom));
}
Hi Jo,
I exported a full world map from TileMill with width of 1000 pixels and height of 652 pixels. The following are coordinates for its bounding box: 
float mapGeoLeft   = -180;          
float mapGeoRight  =  180;          
float mapGeoTop    =  83.7539;          
float mapGeoBottom =  -56.1700;         

But when I tried to plot data on it, the locations are not correct. Can you please explain?