Reputation: 81
function get_map_zoom_level(distance) {
var zoom = 1;
if (distance == 0)
zoom = 11;
else if (distance == 1)
zoom = 15;
else if (distance > 880 && distance <= 1760)
zoom = 14;
else if (distance > 1760 && distance <= 3520)
zoom = 13;
else if (distance > 3520 && distance <= 7040)
zoom = 12;
else if (distance > 7040 && distance <= 14080)
zoom = 11;
else if (distance > 14080 && distance <= 28160)
zoom = 10;
else if (distance > 28160 && distance <= 56320)
zoom = 9;
else if (distance > 56320 && distance <= 112640)
zoom = 8;
else if (distance > 112640 && distance <= 225280)
zoom = 7;
else if (distance > 225280 && distance <= 450560)
zoom = 6;
else if (distance > 450560 && distance <= 889120)
zoom = 5;
else if (distance > 889120 && distance <= 1718240)
zoom = 4;
else if (distance > 1718240)
zoom = 3;
return zoom;
}
I want to know if there is any way to avoid many if else in this code. Basically I want to find out zoom level on the basis of distance, this code is working perfectly but I need some better way to do this.
Upvotes: 3
Views: 204
Reputation: 16609
When you have a large number of if
statements comparing the same data as yours is, the usual approach is to create an Array, where each entry contains the data to compare and the result, in other words the minimum distance, the maximum distance, and the zoom level.
To do the comparison, you use a for
loop to go through the array, checking the values for each. if you find a matching entry, then set the result and break
out of the loop.
This is not more efficient or quicker than the way you have done it, but it means you can have any number of options and your actual code doesn't get bigger or more complicated.
Here is how you can do this with yours:
function get_map_zoom_level(distance) {
// create the array of values. Each entry can be either an array or an object, doesn't matter too much.
// I'll use an array set up as [minDistance, maxDistance, zoom]
var zoomLevels = [
[880, 1760, 14],
[1760, 3520, 13],
[3520, 7040, 12],
[7040, 14080, 11],
// ... etc.
]
var zoom = 1;
// special cases
if (distance == 0)
zoom = 11;
else if (distance == 1)
zoom = 15;
else if (distance > 1718240)
zoom = 3;
else {
for (var i = 0; i < zoomLevels.length; i++) {
var zoomLevel = zoomLevels[i];
if (distance > zoomLevel[0] && distance <= zoomLevel[1]) {
zoom = zoomLevel[2];
// found a match - stop the loop
break;
}
}
}
return zoom;
}
By the way, zoom level 11 seems to have an error in it, 7040 and 1480 don't match.
Upvotes: 3
Reputation: 10196
The following code keeps the exact same edge cases (explicit, e.g. distance is 0 -> zoom is 11, and implicit, e.g. distance is 42 -> zoom is 1) that your code has in the same order as well, but, if we are not dealing with an edge case, decides on the applicable intermediate range using an array of distances in ascending order, representing inclusive upper bounds (of ranges). The exclusive lower bound is handled by iterating the array from the beginning, since the values are ascending.
function get_map_zoom_level(distance) {
var distanceBreakpoints = [1760, 3520, 7040, 14080, 28160, 56320, 112640, 225280, 450560, 889120, 1718240];
var zoom = 1;
if (distance == 0)
zoom = 11;
else if (distance == 1)
zoom = 15;
else if (distance > 880 && distance <= 1718240) {
for (var i = 0; i < distanceBreakpoints.length; ++i) {
if (distance <= distanceBreakpoints[i]) {
zoom = 14 - i;
break;
}
}
} else if (distance > 1718240)
zoom = 3;
return zoom;
}
Upvotes: 0
Reputation: 154
This should work:
function get_map_zoom_level(distance) {
var zoom = 15;
var temp=880;
if (distance == 0)
zoom = 11
while (distance > temp){
temp=temp*2;
zoom--;
}
return zoom;
}
Upvotes: 3
Reputation: 6202
You could have an object like:
var zooms = [ { min:1480 , max:28160} , // array index is zoom level
// ...
{ min:880 , max:1760} ];
and then iterate it until the zoom is found
for(var z = 1 ; z <= MAX_ZOOM ; z++) {
if (distance > zooms[z].min && distance <= zooms[z].max) {
return z;
}
}
Upvotes: 2