Search code examples
google-maps

Google Maps API PanBy method no longer working?


I've been making my own paper maps for several years (yes, I'm very old-fashioned that way!) - I take them on holiday or use them as wall maps. Basically I use Google Maps API driven from Javascript to generate maps that are offset from each other, grab the resulting images and stitch them together using my own code. I've found that the best way of doing this is to use the PanBy method, because the offset is an exact number of pixels, and not subject to rounding errors.

However, 'PanBy' method no longer seems to work - it's just ignored - the map comes up in same the position (determined by the initial lat long coordinates) whatever setting is put in the PanBy instruction.

I double-checked this by re-using old scripts that have worked successfully in the past, to find that they no longer produce offset maps. I tried using both FireFox and Chrome as browsers, and even fired up my old Windows 7 machine in case it was a Windows update issue - but no joy. It seems to me that the PanBy method is broken!

As you can see the script is very simple: (NB: edited to show full HTML script)

<!DOCTYPE html>
<html> 
<head> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> 
<style type="text/css"> 
html { height: 100% } 
body { height: 100%; margin: 0; padding: 0 } 
#map_canvas { height: 100% } 
</style> 
<script async defer src="https://maps.googleapis.com/maps/api/js?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&callback=initMap"
  type="text/javascript"></script>
<script type="text/javascript">

function initialize() { 

//BMAP_ROWS_COLS:1:5

var PlainStyle = [

{featureType: "administrative",elementType: "all",stylers: [{ visibility: "on" }]},
{featureType: "landscape",elementType: "all",stylers: [{ visibility: "on" }]},
{featureType: "poi",elementType: "all",stylers: [{ visibility: "on" }]},
{featureType: "road",elementType: "all",stylers: [{ visibility: "on" }]},
{featureType: "transit",elementType: "all",stylers: [{ visibility: "on" }]},
{featureType: "water",elementType: "all",stylers: [{ visibility: "on" }]},
];

var latlng = new google.maps.LatLng(51.00000000 , -1.10000000);
var myOptions = { 
zoom: 19,
center: latlng, 
panControl: false,
zoomControl: false,
scaleControl: false,
fullscreenControl: true,
streetViewControl: false,
mapTypeControl: false,
mapTypeId: google.maps.MapTypeId.SATELLITE,
};
 
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 
map.setOptions({styles: PlainStyle});
};

google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
    map.panBy(1820, 0)
});
}

</script> 
</head> 
<body onload="initialize()"> 
<div id="map_canvas" style="width:100%; height:100%"></div> 
</body> 
</html>

In the past I simply varied the X and Y coordinates in the PanBy command to get an offset map.


Solution

  • I'm surprised that ever worked, but something in the startup of the API may have changed. In general, the Google Maps API v3 is event driven, you should wait for the map to be initialized before attempting to pan the map.

    Something like:

      google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
        map.panBy(100, 500)
      })
    

    proof of concept fiddle

    Code snippet:

    function initialize() {
    
    var PlainStyle = [
    
    {featureType: "administrative",elementType: "all",stylers: [{ visibility: "on" }]},
    {featureType: "landscape",elementType: "all",stylers: [{ visibility: "on" }]},
    {featureType: "poi",elementType: "all",stylers: [{ visibility: "on" }]},
    {featureType: "road",elementType: "all",stylers: [{ visibility: "on" }]},
    {featureType: "transit",elementType: "all",stylers: [{ visibility: "on" }]},
    {featureType: "water",elementType: "all",stylers: [{ visibility: "on" }]},
    ];
    
    var latlng = new google.maps.LatLng(-33.9, 151.2);
    var myOptions = { 
    zoom: 19,
    center: latlng, 
    panControl: false,
    zoomControl: false,
    scaleControl: false,
    fullscreenControl: true,
    streetViewControl: false,
    mapTypeControl: false,
    mapTypeId: google.maps.MapTypeId.SATELLITE,
    };
    
      var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
      map.setOptions({
        styles: PlainStyle
      });
      google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
        map.panBy(100, 500)
      })
    
    }
    
    window.initialize = initialize;
    /* 
     * Always set the map height explicitly to define the size of the div element
     * that contains the map. 
     */
    #map_canvas {
      height: 100%;
    }
    
    /* 
     * Optional: Makes the sample page fill the window. 
     */
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    <!doctype html>
    <html>
      <head>
        <title>Complex Marker Icons</title>
        <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
        <!-- jsFiddle will insert css and js -->
      </head>
      <body>
        <div id="map_canvas"></div>
    
        <!-- 
          The `defer` attribute causes the callback to execute after the full HTML
          document has been parsed. For non-blocking uses, avoiding race conditions,
          and consistent behavior across browsers, consider loading using Promises.
          See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
          for more information.
          -->
        <script
          src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize&v=weekly"
          defer
        ></script>
      </body>
    </html>