Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to set the zoom level of Google Static Maps, based on the availability of imagery?

I use Static maps in my work inviroment for customers. I like the zoom level of 17, (0 for the entire earth, 21 for the closest zoom possible) but depending on where the image location is from, Google may not have the imagery available at the zoom level of 17. Is the a way, to tell the Maps API, to dynamically select the highest zoom possible, up to say 17? I have not seen a way to do this, but i sure appreciate any suggestions.

like image 764
John Avatar asked Jul 15 '11 18:07

John


2 Answers

As far as I know, static maps must have the zoom set in the query string of the url, something like

&zoom=17 or &z=17

If you were using a non-static map, you could easily find and/or set the max zoom:

V2: http://googlegeodevelopers.blogspot.com/2009/06/how-low-can-you-go-introducing.html

v3: http://code.google.com/apis/maps/documentation/javascript/services.html#MaxZoom

Given that you are using static though, I think you have two options:

  1. do not set a zoom on the url query and let Google Maps determine the "best" zoom level.
  2. set the zoom to 17 or something even less zoomed in (14 or 15) and then allow the user to zoom in with a link that refreshes the map with a different URL string. (You need to do this with javascript)

EDIT

Here's one way to implement the js for the zoom. (I was interested and hacked this together. I am sure there is a better/more elegant way)

HTML

<img src="http://maps.googleapis.com/maps/api/staticmap?center=55.516192,-87.39624&size=400x400&maptype=satellite&sensor=false&zoom=12" />

<input type="submit" id="in" value="Zoom in" />
<input type="submit" id="out" value="Zoom out" />

Make sure the zoom level is at the end of the query strings.

JS

$('#in').click(function(){
    var map = $('img').attr('src');
    var zoomPat = /(.+)(zoom=)([\d]*)/;
    var zoomLevel = map.match(zoomPat);
    var zoomLevelNum = Number(zoomLevel[3]); 

    if(zoomLevelNum == 21){
       alert('Maximum level reached');
    } 
    else{    
    var newZoom = zoomLevel[1] + zoomLevel[2] + (zoomLevelNum + 1);
    $('img').attr('src', newZoom);           
    } 

});

$('#out').click(function(){
    var map = $('img').attr('src');
    var zoomPat = /(.+)(zoom=)([\d]*)/;
    var zoomLevel = map.match(zoomPat);
    var zoomLevelNum = Number(zoomLevel[3]); 

    if(zoomLevelNum == 0){
       alert('Minimum level reached');
    } 
    else{    
    var newZoom = zoomLevel[1] + zoomLevel[2] + (zoomLevelNum - 1);
    $('img').attr('src', newZoom);           
    } 

});

http://jsfiddle.net/jasongennaro/FFTKG/2/

like image 58
Jason Gennaro Avatar answered Sep 19 '22 00:09

Jason Gennaro


First I want to THANK Jason Gennaro for an amazing idea with his JS alternative! Unfortunately, this idea assumes you have a 'zoom' level set on each map. If, as in my case, I was letting google(sic) adjust the map size itself, I came up with a modification/addition to Jason's code. If you want to use his idea, but want the maps to size properly around 2 locations, using the lat/long of each location, using the code below to calculate distance, you can estimate a zoom level to add to the string. These distances are somewhat estimated with a lot of testing. I have installed and tested this code. Works perfect. Enjoy.

function tom_distance2($lat1, $lng1, $lat2, $lng2, $miles = true)
{
  $pi80 = M_PI / 180;
  $lat1 *= $pi80;
  $lng1 *= $pi80;
  $lat2 *= $pi80;
  $lng2 *= $pi80;

  $r = 6372.797; // mean radius of Earth in km
  $dlat = $lat2 - $lat1;
  $dlng = $lng2 - $lng1;
  $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2);
  $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
  $km = $r * $c;
  $di9 = round(($km * 0.621371192));
  if ($di9 >= "5000") {$tom98 = "1"; // zoom level
  } else if ($di9 >= "4000") {$tom98 = "2";
  } else if ($di9 >= "1500") {$tom98 = "3";
  } else if ($di9 >= "800") {$tom98 = "4";
  } else if ($di9 >= "400") {$tom98 = "5";
  } else if ($di9 >= "180") {$tom98 = "6";
  } else if ($di9 >= "100") {$tom98 = "7";
  } else if ($di9 >= "0") {$tom98 = "10";
  } else {$tom98 = "8";} // just in case :)
  return $tom98;
}

Call this function with...

$td2 = "&amp;zoom=" . tom_distance2($tlat1, $tlong1, $tlat2, $tlong2, 1);

p.s. Add $td2 to the end of your original map string. Pardon the variable names. Sometimes they make sense :) This is PHP.

like image 29
Tom aka Sparky Avatar answered Sep 21 '22 00:09

Tom aka Sparky