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 ?
Zoom in the map You can zoom in and out of the map with one hand. Double tap a spot on the map, and then: Drag down to zoom in.
Google Maps has an integer 'zoom level' which is the resolution of the current view. Zoom levels are between 0 (the entire world can be seen on one map) and 21+. You can also set the minimum and maximum values for the zoom parameter.
Convert latitude, longitude to spherical mercator x, y. Get distance between your two points in spherical mercator. The equator is about 40m meters long projected and tiles are 256 pixels wide, so the pixel length of that map at a given zoom level is about 256 * distance/40000000 * 2^zoom.
You can change the zoom level of the map using simple steps. Step 1 Go to Add or Edit Map page . Step 2 Select 'Default zoom level' in the 'Map Information section'. Step 3 click save map and see the changes.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With