Pass Google Maps API to JPG image

Asked

Viewed 2,029 times

4

I have this code below:

   <iframe width='500' scrolling='no' height='200' frameborder='0' id='map' 
   marginheight='0' marginwidth='0' src='https://maps.google.com/maps?saddr=São Paulo 
   - SP, Brasil&daddr=Rio de Janeiro - RJ, Brasil&output=embed'></iframe>

That brings me back this map:

Mapa com Rota Traçada

What I wanted was to know how to turn this map into an image jpg within php keeping the route drawn.

Why all of this?

I’m generating a file PDF for MPDF but the only thing she can’t stand is this tag from <iframe> to the Google Maps and I need that map inside PDF.

  • I believe there is nothing for PHP to support this. Wkhtmltopdf I believe is the only option. The good thing is that it is extremely fast, although huge (+40MB), and uses a real engine to render the page. It is not 100% stable in what it comes to iframe, however.

3 answers

5


Google has a Static Maps API which are served as image. It’s very easy to use, just build the right URL and put as src image:

<img src="https://maps.googleapis.com/maps/api/staticmap?center=São Paulo, SP, Brazil&zoom=12&size=400x400">

The problem is that there are no parameters to plot a route. For this, you need to use the route service from Google Maps API, to get data from a line (Polyline), this yes accepted by the static API. Then the code gets a little more complex, but produces the desired result:

google.maps.event.addDomListener(window, 'load', init);

function init() {
    var directions = new google.maps.DirectionsService();
    directions.route({
        origin: "São Paulo SP Brazil",
        destination: "Rio de Janeiro RJ Brazil",
        travelMode: google.maps.TravelMode.DRIVING
    }, rotaDisponivel);
}

function rotaDisponivel(dados, status) {
    var url = "http://maps.googleapis.com/maps/api/staticmap?center=Guaratinguetá%20SP%20Brasil&zoom=8&size=800x300&maptype=roadmap&sensor=false&path=color:0x0000ff|weight:5|enc:"
    if(dados.routes[0]) {
        var div = document.getElementById('mapa');
        var img = document.createElement('img');
        img.src = url + dados.routes[0].overview_polyline;
        div.appendChild(img);
    } else {
        // erro ao obter rota
    }
}
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<p>O mapa vai carregar abaixo, pode demorar um pouco</p>
<div id="mapa"></div>

  • +1 Static maps, OMG so simple! I never used, but that’s past now ;)

2

As already quoted, html2canvas is a great library for use, before we start keep in mind:

  • html2canvas does not work real DOM elements it just simulates them with Canvas
  • It is considered alpha or experimental, so it still has a lot to evolve (although in most tests it did very well)
  • To access images from different domains you will need to use proxy (done by languages like php, python, java, etc).
  • I believe the use of <iframe> not yet supported, so the best thing in this case is to use the google-maps API instead of iframes.

Using the Google Maps API

An example of using Google Maps would be:

var parametreCarteVillage = {
    zoom                        : 9,
    center                      : new google.maps.LatLng(38.959409, -87.289124),
    disableDoubleClickZoom      : false,
    draggable                   : true,
    scrollwheel                 : true,
    panControl                  : false,
    disableDefaultUI            : true,
    mapTypeControl              : true,
    keyboardShortcuts           : true,
    mapTypeId                   : google.maps.MapTypeId.ROADMAP
};
  
var map = new google.maps.Map(document.getElementById('map_canvas'), parametreCarteVillage);
  
var marker = new google.maps.Marker({
  position:new google.maps.LatLng(38.959409,-87.289124),
  map: map,
  title: 'Titulo!'
});
#map_canvas{
    height: 400px;
    width: 600px;
    border: 1px #c0c0c0 solid;
}
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>

<div id="map_canvas"></div>

To add more options to the map read to documentation

Using the html2canvas

I recommend downloading the version 0.5.0-alpha in https://github.com/niklasvh/html2canvas/releases and include on the page that will use Google Maps, should look something like:

<script src="html2canvas.js"></script>

html2canvas(document.getElementById("map_canvas"), {
    "logging": true //Habilita os logs
}).then(function(canvas) {
    var img = new Image();
    img.onload = function () {
        img.onload = null;
        document.getElementById("output").appendChild(img);
    };
    img.src = canvas.toDataURL("image/png");
});

But as I mentioned earlier, to access images from different domains, in case your domain accesses the google images, you will need to use CORS, but the images are in the Google domain and we have no control, so we will have to use proxy.

Proxy in this case is not the technology to use a different ip on your machine, but rather a script that runs on the server and displays the image of the external domain as if I’ve been in your domain, or even if it’s three domains seu-site.com, maps.google.com and proxy.seu-site.com he makes use of CORS or of data URI scheme.

Proxy for html2canvas

I developed four proxys in different languages:

The use would be something like (example with aspx):

html2canvas(document.getElementById("map_canvas"), {
    "logging": true, //Habilita os logs
    "proxy":"html2canvasproxy.ashx"
}).then(function(canvas) {
    var img = new Image();
    img.onload = function () {
        img.onload = null;
        document.getElementById("output").appendChild(img);
    };
    img.src = canvas.toDataURL("image/png");
});

List of options to use in html2canvas(..., {opções}).then(...)

Option Type pattern Description
allowTaint boolean false Allows to cause Taint when there are cross-origin images
background string #fff Change the background color of the canvas, if not specific in the gift use undefined for transparent
height number null Limits the height of the in pixels. If null will render with the full height of the window
letterRendering boolean false Used to render each letter separately. Required if using letter-spacing
logging boolean false When true shows log in browser console
proxy string undefined The proxy url is used to load cross-origin images. If not set or empty images will not be loaded
taintTest boolean true Test each image for before drawing, to see if it will stain the <canvas>
timeout number 0 Waiting time for loading images in mileseconds. If 0 there will be no waiting
width number null Limits the width of the in pixels. If null will render with the full width of the window
useCORS boolean false If true tries to load cross-source images if you do not try to use the proxy

Reported: How to use jsPDF addHTML?

0

Hello. Friend, to accomplish this, I make the following suggestion: Use the Google Maps API and create this map in a DIV. Only then, you will have access to the event tilesLoaded, which symbolizes the total loading of the map, allowing you to generate a CANVAS and "print" the image as PNG or JPEG, enabling the passage to your PHP. In IFRAME, GOOGLE’s security policies prevent you from accessing its content, thus making it impossible to manipulate the object, leading to solutions using TIMEOUT that, in general, are flaws.

For map conversion to PNG or JPEG, after rendering you can use :

http://html2canvas.hertzen.com/

Or after rendering the map, use your own PDF generation medium, which I assume is HTML in origin.(Assuming for the above reason, it may not be displayed). I hope I helped. Good luck.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.