bytefish.de

Map Projections (with GNU Octave)

You have analyzed your GPS data to death and all that's left is plotting it on a world map. Thank god it's easy with GNU Octave. Since most of the Webservices (Google Maps, Bing Maps, Open Street Map) use a Mercator projection for their maps, we'll use it aswell. So according to xkcd I am not really into maps. If you'd like to know more about map projections and especially map tiling, read Troy Brant's Post on map projections with Objective-C.

Imagine you have to plot the following GPS positions:

City Latitude Longitude
Berlin 52.51 13.4
London 51.47 -0.16
New York 40.78 -73.97

on the map (taken from Wikipedia:File:Mercator-projection.jpg):

Mercator projected world map

So first define the Mercator projection as:

function y = radians(x)
  y = x * pi / 180;
endfunction

function [x, y] = mercator(lat, lng, width, height)
  x = mod(width * (lng+180)/360, width) ;
  y = log(tan((radians(lat)/2) + (pi/4)));
  y = (height/2) - (width * y/(2*pi));
endfunction

… then load and plot the data. Note that the filesize of the resulting image is much larger than the original. If you want to serve this image from a webserver you should postprocess it.

I = imread("Mercator-projection.jpg");
[height, width, channels] = size(I);

data = [ 52.517, 13.4; # berlin
         51.473611 -0.159444; # london
         40.783333, -73.966667 # new york
         ];

fig = figure('visible','off');
imshow(I);
set(gca, 'units','normalized', 'Position', [0 0 1 1]);
set(gcf, 'units', 'pixels','position',[0 0 width height]);
hold on;

[x,y] = mercator(data(1,1), data(1,2), width, height);
plot(x,y, "go", "MarkerSize", 10, "linewidth", 3);

[x,y] = mercator(data(2,1), data(2,2), width, height);
plot(x,y, "ro", "MarkerSize", 10, "linewidth", 3);

[x,y] = mercator(data(3,1), data(3,2), width, height);
plot(x,y, "bo", "MarkerSize", 10, "linewidth", 3);

print("-dpng",sprintf("-S%d,%d",width,height),"mercator-proj.png")
replot;

and you are done: Mercator projection with GPS coordinates.

Discussion

Enter your comment. Wiki syntax is allowed: