Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Take snapshot of a specific area under google map javascript

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?

like image 293
Prem Avatar asked Dec 11 '17 06:12

Prem


People also ask

How do I snip a Google map?

Open the Google Maps app on your Android phone or tablet. Browse the app to find the area you want to capture. When you're ready to take a screenshot, press the Power and Volume Down buttons together at the same time. The screenshot should be automatically generated and saved in a Screenshots folder in your Gallery.

Is Google Maps screenshot legal?

Street View imagery can only be used in digital advertisements where you're using the Google Maps APIs or the imagery is embedded or linked to on your website using HTML and URL provided on Google Maps. You may not screenshot Street View imagery or remove it from embedded sources for any purpose.


1 Answers

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!

like image 89
xomena Avatar answered Sep 28 '22 20:09

xomena