-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
find-a-church: Make proximity controls zoom the map #154
Comments
Doug, I'm going to leave my notes here for you so you can work on the algebraic refactoring when you have time. We start with this: ratio_milesperzoomlevel = dis/zoom Our goal: get new zoom level So it seems this would be the right formula: zoom * ratio_milesperzoomlevel = zoom * dis/zoom But that doesn't work, because according to docs describing Google Maps, when the zoom goes up linearly, miles go down quadratically, as is represented in the following table.
So the above table can be represented by the following formula. new_radius_miles = original_radius_miles/(2^z)
(2^z)*new_radius_miles = original_radius_miles
(2^z) = original_radius_miles/new_radius_miles TODO: Start here. How can we factor out z? z = ? The following might work: (2^new_zoom) = original_radius_miles/new_radius_miles We can factor out new_zoom using the following formula: var new_zoom = Math.log(dis/Number(this.search_radius)) / Math.LN2; |
Try: (2^z) = original_radius_miles/new_radius_miles
// For a = b^c, c = log b of a, or c = Math.log(a) / Math.log(b)
z = Math.log10(original_radius_miles/new_radius_miles) / Math.log10(2) |
This is the order in which the user's interaction works. First, the interface has a zoom level. Then the user selects a new search radius (in miles), which moves the user's selection up or down the rows of the table below. We need to calculate the new zoom level which results.
When miles go down by 1/2, zoom goes up by 1. When miles go up by 2x, zoom goes down by 1. We need to translate this into a function which takes in a new number of miles selected by the user, and outputs a new zoom level. newMiles = oldMiles/(2^(newZoom - oldZoom)) Check out the Intro to Logarithms at https://www.khanacademy.org/math/algebra-home/alg-exp-and-log. |
We've implemented this partially, and paused development until we hear back from GoogleWebComponents/google-map#339 as to whether we can use non-integer zoom values. For now we just round search radii to the nearest integer zoom level, which is not as fine a resolution as we would like. We did this so we could merge the feature branch and not let it get far behind the |
Problem: Our current algorithm for calculating the zoom level seems to be correct, so long as the map's pixel dimensions remain the same. If the user resizes the window, making the map change pixel dimensions, then the calculations are not accurate anymore. This raises the question, is the map's initial zoom level correctly coordinated with the initial search radius entered in the search radius input? If so, how can we be sure it will be correct on different screen sizes? If not, then the algorithm may be incorrect. |
Here's a recommendation for how to get the right algorithm:
|
If the viewing area is defined in Lat/Lng format, The distortion happens when it is populated with the appropriate Mercator projections. Instead, the correct viewing box must be defined in Mercator or Project Mercator. |
@DouglasHuston, is the point of your last comment on here (at #154 (comment)) that we need to use the Mercator projection? |
If we do use the Mercator projection, we must define the viewing box correctly, and not just use the Lat/Lng format. This does not mean we are restricted to only using the Mercator projection. |
Plan A
Maaayyybe an easy solution would be to:
And you're done!
Note: One motivation for this method is that it appears Google's Maps API's zoom levels only exist in discrete integers, and can't actually be set in finer (fractional or decimal) increments.
Note: This implies when the user selects a search radius, we need to hide all the congregations which don't fit in that radius, and more importantly, when the user pans or zooms the map, we need to SHOW all the new congregations which fit within the map's new bounds, and stop using the circle as the bounds within which to display congregations. In other words, the map needs two modes here:
Plan B
Or, if we want to be all complicated like we used to think we had to, we could try any of the following:
It looks like the zoom levels don't correspond directly to miles. See http://gis.stackexchange.com/questions/7430/what-ratio-scales-do-google-maps-zoom-levels-correspond-to, http://stackoverflow.com/questions/6048975/google-maps-v3-how-to-calculate-the-zoom-level-for-a-given-bounds for information on how to translate from miles to zoom levels.
Some example algorithms:
http://jeffjason.com/2011/12/google-maps-radius-to-zoom/
http://stackoverflow.com/questions/5162950/google-maps-api-v3-set-zoom-level-to-show-a-given-radius
Note: Google Maps uses the "Google Web Mercator" projection and coordinate system. Its official EPSG identifier is EPSG:3857. It uses spherical rather than the standard Mercator ellipsoid formulae. According to https://en.wikipedia.org/wiki/Web_Mercator#Properties, "While the Web Mercator's formulas are for the spherical form of the Mercator, geographical coordinates are required to be in the WGS 84 ellipsoidal datum." Formulae are available at https://en.wikipedia.org/wiki/Web_Mercator#Formulas. (Question: Do x & y values there refer to the bounding box's height & width in pixels?) Note there are a couple more formulae in a JavaScript-like language at the end of this article: https://alastaira.wordpress.com/2011/01/23/the-google-maps-bing-maps-spherical-mercator-projection/.
See general Google Maps coordinate overview at https://developers.google.com/maps/documentation/javascript/maptypes?csw=1#MapCoordinates.
This might work:
When a user changes the search radius (in miles/km):
computeDistanceBetween()
to do the same.Here is a Great Circle Distance formula: http://stackoverflow.com/questions/3525670/radius-of-viewable-region-in-google-maps-v3.
The text was updated successfully, but these errors were encountered: