7
votes

I am trying to take the snapshot of an area enclosed by a rectangle drawn on the google map. Is it possible to take the snapshot of the area beneath the rectangle? I have searched for answers but couldn't find any helpful info.

Rectangle drawn on the map

I tried to take the snapshot of the area under rectangle using static map API by specifying the map centre, zoom level, image width and image height. Like https://maps.googleapis.com/maps/api/staticmap?center=CENTER OF THE RECTANGLE&zoom=ZOOM LEVEL OF THE MAP&size=WIDTH AND HEIGHT OF THE RECTANGLE&maptype=satellite&key=API KEY

Here is the code I tried,

var zoom = map.zoom;
var centre = rectangle.getBounds().getCenter(); //rectangle is the shape drawn on the map
var spherical = google.maps.geometry.spherical;
bounds = rectangle.getBounds(); //rectangle is the shape drawn on the map
cor1 = bounds.getNorthEast();
cor2 = bounds.getSouthWest();
cor3 = new google.maps.LatLng(cor2.lat(), cor1.lng()); 
cor4 = new google.maps.LatLng(cor1.lat(), cor2.lng()); 
width = spherical.computeDistanceBetween(cor1,cor3); 
height = spherical.computeDistanceBetween( cor1, cor4);

Now I downloaded the image using this URL,

"https://maps.googleapis.com/maps/api/staticmap?center=" + centre.lat() + "," + centre.lng() + "&zoom=" + zoom + "&size=" + width + "x" + height + "&maptype=satellite&key=API_KEY"

Original URL : "https://maps.googleapis.com/maps/api/staticmap?center=40.804197008355914,-74.11213619168848&zoom=20&size=26x37&maptype=satellite&key=API_KEY"

Output image I got

My expected output

I got the image, but the image doesn't include the whole area enclosed by the rectangle(It is too small). what I am doing wrong? Is there any other methods to do it?

1

1 Answers

4
votes

The main mistake that you have in your code is that the width and height parameters of Static Maps API must be in pixels. Currently you calculate a distance in meters and pass it in Static Maps URLs instead of pixels.

I created an example based on your sample code and was able to create a correct static maps URL. Please have a look at my example. The distanceInPx function is the most important thing. Create the rectangle with drawing manager and click the Show static map link. Also, note that Static Maps API are limited to 640x640 px image size in Standard plan, so you cannot create a link for rectangles that have a bigger size.

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 28.45765, lng: -16.363564},
    zoom: 21,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  });

  var drawingManager = new google.maps.drawing.DrawingManager({
    drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
    drawingControl: true,
    drawingControlOptions: {
      position: google.maps.ControlPosition.TOP_CENTER,
      drawingModes: ['rectangle']
    }
  });
  drawingManager.setMap(map);

  google.maps.event.addListener(drawingManager, "rectanglecomplete", function(rectangle){
    function distanceInPx(pos1, pos2) {
        var p1 = map.getProjection().fromLatLngToPoint(pos1);
        var p2 = map.getProjection().fromLatLngToPoint(pos2);

        var pixelSize = Math.pow(2, -map.getZoom());

        var d = Math.sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y))/pixelSize;

        return Math.round(d);
    }

    var zoom = map.zoom;
    var centre = rectangle.getBounds().getCenter(); //rectangle is the shape drawn on the map
    var spherical = google.maps.geometry.spherical;
    bounds = rectangle.getBounds(); //rectangle is the shape drawn on the map
    var cor1 = bounds.getNorthEast();
    var cor2 = bounds.getSouthWest();
    var cor3 = new google.maps.LatLng(cor2.lat(), cor1.lng()); 
    var cor4 = new google.maps.LatLng(cor1.lat(), cor2.lng()); 

    var width = distanceInPx(cor1, cor4);
    var height = distanceInPx(cor1, cor3); 

    var imgUrl = "https://maps.googleapis.com/maps/api/staticmap?center=" + 
        centre.lat() + "," + centre.lng() + "&zoom=" + zoom + 
        "&size=" + width + "x" + height + "&maptype=satellite&key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU";

    var aElem = document.getElementById("staticLink");
    aElem.setAttribute("href", imgUrl);
    aElem.style.display="block";

  });

}
#map {
  height: 100%;
}
html, body {
  height: 95%;
  margin: 0;
  padding: 0;
}
<div id="map"></div>
    <a id="staticLink" href="#" target="_blank" title="Show static map" style="display:none;">Show static map</a>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU&libraries=drawing&callback=initMap"
         async defer></script>    

This example is also available at jsbin: http://jsbin.com/humuko/edit?html,output

I hope this helps!