Lucas Willems
Lucas Willems

Reputation: 7073

What is the Google Map zoom algorithm?

I'm working on a map zoom algorithm which change the area (part of the map visible) coordinates on click.

For example, at the beginning, the area has this coordinates :

And when the user clicks somewhere in the area, at a (x, y) coordinate, I say that the new coordinates for the area are :

The problem is that algorithm is not really powerful because when the user clicks somewhere, the point which is under the mouse moves to the middle of the area.

So I would like to have an idea of the algorithm used in Google Maps to change the area coordinates because this algorithm is pretty good : when the user clicks somewhere, the point which is under the mouse stays under the mouse, but the rest of area around is zoomed.

Somebody has an idea of how Google does ?

Upvotes: 11

Views: 5047

Answers (2)

Mikaël Mayer
Mikaël Mayer

Reputation: 10711

Let us state the problem in 1 dimension, with the input (left, right, clickx, ratio) So basically, you want to have the ratio to the click from the left and to the right to be the same:

Left'-clickx    right'-clickx
------------- = --------------
 left-clickx     right-clickx

and furthermore, the window is reduced, so:

right'-left'   
------------ = ratio
 right-left

Therefore, the solution is:

left'  = ratio*(left -clickx)+clickx
right' = ratio*(right-clickx)+clickx

And you can do the same for the other dimensions.

Upvotes: 7

Leszek
Leszek

Reputation: 6598

Lets say you have rectangle windowArea which holds drawing area coordinates(i.e web browser window area in pixels), for example if you are drawing map on the whole screen and the top left corner has coordinates (0, 0) then that rectangle will have values:

windowArea.top = 0;
windowArea.left = 0;
windowArea.right = maxWindowWidth;
windowArea.bottom = maxWindowHeight;

You also need to know visible map fragment, that will be longitude and latitude ranges, for example:

mapArea.top = 8.00; //lat
mapArea.left = 51.00; //lng
mapArea.right = 12.00; //lat
mapArea.bottom = 54.00; //lng

When zooming recalculate mapArea:

mapArea.left = mapClickPoint.x - (windowClickPoint.x- windowArea.left) * (newMapWidth / windowArea.width());
mapArea.top = mapClickPoint.y - (windowArea.bottom - windowClickPoint.y) * (newMapHeight / windowArea.height());
mapArea.right = mapArea.left + newWidth;
mapArea.bottom = mapArea.top + newHeight;

mapClickPoint holds map coordinates under mouse pointer(longitude, latitude). windowClickPoint holds window coordinates under mouse pointer(pixels).
newMapHeight and newMapWidth hold new ranges of visible map fragment after zoom:

newMapWidth = zoomFactor * mapArea.width;//lets say that zoomFactor = <1.0, maxZoomFactor>
newMapHeight = zoomFactor * mapArea.height;

When you have new mapArea values you need to stretch it to cover whole windowArea, that means mapArea.top/left should be drawn at windowArea.top/left and mapArea.right/bottom should be drawn at windowArea.right/bottom.

I am not sure if google maps use the same algorithms, it gives similar results and it is pretty versatile but you need to know window coordinates and some kind of coordinates for visible part of object that will be zoomed.

image

Upvotes: 13

Related Questions