Pass API Google Maps for JPG image

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 returns me this map:

I wanted to know how to transform this map into a jpg image within php while keeping the route drawn.

Why all of this?

I'm generating a PDF file by MPDF but the only thing it does not support is this <iframe> tag for Google Maps and I need that map within PDF .

    
asked by anonymous 04.04.2015 / 17:18

3 answers

5

Google has a Static Map API that is served as an image. It's pretty easy to use, just build the right URL and put it as src of an image:

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

The problem is that there are no parameters to trace a route. To do so, you'll need to use the Google Maps API route service to get the data for one polyline ), which is supported by the static API. There the code gets a bit more complex, but it 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>Omapavaicarregarabaixo,podedemorarumpouco</p><divid="mapa"></div>
    
09.04.2015 / 22:49
2

As already quoted, html2canvas is a great library to use, before we get started 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 (though in most tests it did very well)
  • To access images of different domains, you will need to use proxy (made by languages such as php, python, java, etc.).
  • I believe the use of <iframe> is not yet supported, so the best 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><scripttype="text/javascript" src="https://www.google.com/jsapi"></script><divid="map_canvas"></div>

To add more options to the map, read the documentation

Using the html2canvas

I recommend downloading the 0.5.0-alpha version at link and include in 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, in order to access images from different domains, in case your domain accesses google images, you must 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 a script that runs on the server and displays the image of the external domain as if it were in your domain, or even three domains seu-site.com , maps.google.com and proxy.seu-site.com it makes use of CORS or data URI scheme .

Proxy for html2canvas

I developed four proxies in different languages:

  • Proxy in PHP : link
  • C # proxy : link
  • Proxy in Python : link (supports any framework)
  • Proxy in VbScript (for classic asp) : link

The usage 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(...)

+-----------------+---------+-----------+----------------------+
| Opção           | Tipo    | padrão    |  Descrição           |
+-----------------+---------+-----------+----------------------+
| allowTaint      | boolean | false     | Permite causar o     |
|                 |         |           | taint quando houver  |
|                 |         |           | imagens cross-origin |
+-----------------+---------+-----------+----------------------+
| background      | string  | #fff      | Troca a cor de fundo |
|                 |         |           | do canvas, se não    |
|                 |         |           | espeficicado no dom  |
|                 |         |           | use 'undefined' para |
|                 |         |           | transparente         |
+-----------------+---------+-----------+----------------------+
| height          | number  | null      | Limita a altura do   |
|                 |         |           | em pixels. Se 'null' |
|                 |         |           | irá renderezar com   |
|                 |         |           | a altura total da ja-|
|                 |         |           | nela                 |
+-----------------+---------+-----------+----------------------+
| letterRendering | boolean | false     | Usado para renderizar|
|                 |         |           | cada letra separada- |
|                 |         |           | mente. É necessário  |
|                 |         |           | se estiver usando    |
|                 |         |           | 'letter-spacing'     |
+-----------------+---------+-----------+----------------------+
| logging         | boolean | false     | Quando 'true' mostra |
|                 |         |           | log no console do    |
|                 |         |           | navegador            |
+-----------------+---------+-----------+----------------------+
| proxy           | string  | undefined | A url do proxy é usa-|
|                 |         |           | da para carregar ima-|
|                 |         |           | gens cross-origin.   |
|                 |         |           | Se não definido ou   |
|                 |         |           | vazio as imagens não |
|                 |         |           | serão carregadas     |
+-----------------+---------+-----------+----------------------+
| taintTest       | boolean | true      | Testa cada imagem    |
|                 |         |           | para antes de dese-  |
|                 |         |           | nhar, para verificar |
|                 |         |           | se irá manchar o can-| 
|                 |         |           | vas.                 |
+-----------------+---------+-----------+----------------------+
| timeout         | number  | 0         |Tempo de espera para  |
|                 |         |           | o carregamento das   |
|                 |         |           | imagens em milesegun-|
|                 |         |           | dos. Se 0 não haverá |
|                 |         |           | esperar              |
+-----------------+---------+-----------+----------------------+
| width           | number  | null      | Limita a largura do  |
|                 |         |           | em pixels. Se 'null' |
|                 |         |           | irá renderezar com   |
|                 |         |           | a largura total da   |
|                 |         |           | janela               |
+-----------------+---------+-----------+----------------------+
| useCORS         | boolean | false     | Se 'true' tenta car- |
|                 |         |           | regar as imagens com |
|                 |         |           | cross-origem, se não |
|                 |         |           | tenta usar o proxy   |
+-----------------+---------+-----------+----------------------+

Reported: How to use jsPDF addHTML?

    
06.04.2015 / 18:21
0

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

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

link

Or after rendering the map, use your own PDF generation medium, which I assume originates from the HTML. (Assuming for the reason above, it may not be displayed.) Hope this helps. Good luck.

    
06.04.2015 / 14:41