2
votes

How do I convert lat/lng coordinates to pixels on a rotated map (a div)?

The twist is that the map does not point towards north, but is tilted 10 degrees... and my high school math is failing me!

I've found a couple of other questions that does the conversion on a north-facing map which points to here.

I am however not complete sure how to do it when the map is rotated.

The map is a 3*3km map of a location in London.

I'm using javascript, but any language will do :-)

1
After determining the coordinates on the north-facing map, you can use this math to rotate: x = cos(a) * l; y = sin(a) * l; Where l is the distance from the origin, and a is the rotation of the map in radians.Theron Luhn
What is the origin in this case?jkgeyti
Whatever point the map was rotated on. I'd try having the origin be the center of the map and see if that works.Theron Luhn

1 Answers

2
votes

You have two maps. Reality measured in lat and longitude, and the map you are drawing measured in (I presume) pixels. You need to transform from one to the other. Do this with vector math and do it in three steps.

1.) Find your original vector going from your origin to the point you want to map.

let O = <Ox, Oy>; 
(the origin in lat and long of your map).

let M = <Mx, My>; 
(the point in lat/long that you want to convert to a pixel on your drawn map)

let V := M - O = <Mx - Ox, My - Oy>; 
(This is a vector from origin to the point you want to convert.)

As a vector it contains two mathematical quantities, direction and magnitude. We need to transform both of these quantities from our lat longitude coord system to our new pixel coordinate system.

2.) First Scale.

Scale is a multiple, figure out what it is and multiply your vector by it. Basic its a multiple of how many pixels per degree of lat/long.

let c = our 'zoom' multiple. 

Scaling is as easy as multiplying our vector by our scalar.

cV = <cVx, cVy>;

3.) then Rotate

Rotation is a trigonometric function. X of the rotated vector is equal to sin(t)|V| and Y of the rotated vector is equal to cos(t)|V| where t is our rotation amount in (degrees or radians depending on how you cos/sine functions are defined.

Note : Scale and Rotate are linear functions. That means it doesn't matter the order you do this in scale the rotate or rotate then scale, its the same answer.

Doing it all at once would look like this :

Vector notation :

let O := the origin 
let M := the point you want to map. 
let R(V,t) := a function to rotate vector V by t. 
let c := or zoom or scale multiple. 

solve for P.

P = c * R(M-O, t). (Or since R and c are linear R(c(M-O), t);  )

Ordered Pair notation :

let O := <Ox, Oy>

let M := <Mx, My>

let R(V,t) = < cos(t) * ((Mx - Ox)^2 + (My - Oy)^2)^.5
               sin(t) * ((Mx - Ox)^2 + (My - Oy)^2)^.5 >

Note : |M - O| = ((Mx - Ox)^2 + (My - Oy)^2)^.5

solve for P.

<Px, Py> = < c * cos(t) * ((Mx - Ox)^2 + (My - Oy)^2)^.5
             c*  sin(t) * ((Mx - Ox)^2 + (My - Oy)^2)^.5 >