2

As suggested on this answer, I am using html2canvas library to export a Google Map to a image.

I am working on AngularJS. This is the code I am using:

$scope.shareMap = function(){
        var element = $("#mapDiv");
        html2canvas(element, {
            useCORS: true,
            onrendered: function(canvas) {
                var dataUrl= canvas.toDataURL("image/png");

                // DO SOMETHING WITH THE DATAURL
                // Eg. write it to the page
                document.write('<img src="' + dataUrl + '"/>');
            }
        });
    };

The thing is, it is not exporting my dynamically generated markers. This markers are generated based on response of an AJAX call.

This is how it looks with the markers on the web: Map with markers, before exporting

And this is what it exports: enter image description here

Also, I noticed that if I pan on the map, the "new" displayed zone shows in gray, like so: enter image description here

It seems that it can only export what is shown the first time the map renders (only the map on that specific viewport, without the markers and any additional zones of the map).

Is it possible to solve my problem using this same library? Or can you recommend another approach? Thanks!

xomena
  • 31,125
  • 6
  • 88
  • 117
Multitut
  • 2,089
  • 7
  • 39
  • 63

1 Answers1

4

A tool like PhantomJS can help you write a script to automatically take a screenshot of a webpage (which you've drawn using the Google Maps JavaScript API).

I have a small example that uses PhantomJS to take a screenshot of the page.

Here's the JavaScript Map with some information: http://jsbin.com/pevizusana/2/edit

<html> 
<head> 
<title>PhantomJS Test</title> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?libraries=geometry"></script>
<style type="text/css"> 
  body {
    margin: 0;
  }
  #map {
    width:100%;
    height:100%;
  }
  #loaded {
    display: block;
  }
</style> 
<script type='text/javascript'>

  function initialize() {
    var myLatlng = new google.maps.LatLng(44.65905179951626, 8.3835928124999555);
    var myOptions = {
    zoom: 7,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    var map = new google.maps.Map(document.getElementById("map"), myOptions);

    var decodedPath = google.maps.geometry.encoding.decodePath('klhrG}nmg@olFmlInT}uJ{mC_tDhjEymNi}@_|GieEnAsGspIihF{pBopBe~Nr`B_xB}sEqhJm`FkeAsfHheDcmE}vI}bCdF_eCclC}iIpuOoqJisEdjF_y@|l@gmNgsGwcH{Lm`Ty|Ko{Tet@gaNrrDgiGlmAwcWccHgqQl`@egMk|BdY{iDgdG}aH`qEupFcfE{fLlmM{pLarAepH|yAccBm`BqdH{EotCg_EszAsiS}{B\\afAkgCwcDhkAmxDecAikAirMatBgj@ucAq{E__G}}A{pGfdDm`GjdIsuEg|HqOcxKo{Dg~BgbAsmForBsIkqA}pHo~Bo[ybA|lDsrB{iByzEm`[fiB{`BxaOg\\ftD`\\pzE`lFdxEorD`rAhqA~gEmnPnnIa`G`x@gtDfnAj{@~bCstBhqCmbStcBjy@lhIqpClfXj{]b~KqxCxpEvvFffCxH~nHm|FvaBaoJfgF~mApAq{Fr|A`fAtwCuqBm]zlD|zB_PhhCkyFfjCf|@luJobCvdE{gMfsCqDjuDizB{BymBvyFsiBp_BpcW~xDimG`oA|mFxlEdr@z`A|`DdCzzCuyEfx@o|D~tEcZfuLhtBd}Cn`DeeAzzC|wF~AquB`iBbPwTmbCzsCet@dk@frBna@w`EtzBxlEflB_zCdc@`rC{z@_lIdzEzxEj`He|LxyBt^fdEqeFrwExeAzlCqwC_~Bu}H~cEs`K_iBed@dMsdCiuAfV__DaiPdlMkjEg@orG`dE_}BtkA~dAptEc{D|~Bk~I`vCowAr{ArbCxkEurCtMegPblGcbAxwBmdGniLvxA~nPqUr_CbvKedIfzJbgAvmEyaIruDm~@xhOdiFrnHzeDejDt}Hym@_DrzPltB_P~yBntEjlC_g@rnAtnAoWfdCimE{Ba`JhmIy]xrPjyDxaDzqA}yAx{BhpFvcB{Lm~AhqSx{CfcCibBd`ElaFnbDhjAplEo_Cv_AqaCbbNmjCfvBbzA~qDn|DvP~`@dyCjgHubDt_DxxAlaCvvJnpFnTvrApoFncE~ZkpA`aDlnA~lBrdDqhElfCjkDlpAqoBloCjaB|mFyeExqE`tDgcAh_J~kBhhErqBamEnmBfh@_M~yViaFltVb}E`hHrfComBaCodD`mCnxGm`C}[mmHhgIkmGmqBwRloHblDtdBck@z{ItaDroYxiBb]mQ~vKeyD`dBz\\jiKstJzzPiyEfdb@}rG`gA}~AvhFgaBwMg|FzpFk_AhxEyjJwa@_{@ozI{aIlbMigIdyBauF}}MwxD{ZafBs`EkmEvbC_|Cg}Aua@{bU}|D|}@_cBzhFwcGxi@gmBneCeuEgtCazFn`QfuBt}Boe@dmHqyIt{TukDgx@{JthB_aDkkCcuD|mDkoCos@ue@dcM{_I|eAuoCjtD ');

    var setRegion = new google.maps.Polygon({
    path: decodedPath,
    fillColor: "#0000FF",
    fillOpacity: 0.2,
    strokeColor: "#0000FF",
    strokeOpacity: 1.0,
    strokeWeight: 2,      
    map: map
    });

    google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
      document.getElementById("loaded").innerText = "true"; 
    });
}
</script> 
</head> 
<body onload="initialize()"> 
<div id="map"></div>
<div id="loaded"></div>
</body> 
</html>

Here's the PhantomJS code that will take a screenshot on this site: http://pastebin.com/gEXhG1dP

/*
* Captures a webpage with a Google JavaScript Map and exports it to PNG.
*/
//Original code: https://github.com/ariya/phantomjs/blob/master/examples/waitfor.js

function waitFor(testFx, onReady, timeOutMillis) {
    var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
    start = new Date().getTime(),
    condition = false,
    interval = setInterval(function() {
        if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
            // If not time-out yet and condition not yet fulfilled
            condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
        } else {
            if(!condition) {
                // If condition still not fulfilled (timeout but condition is 'false')
                console.log("'waitFor()' timeout");
                phantom.exit(1);
            } else {
                // Condition fulfilled (timeout and/or condition is 'true')
                console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
                typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
                clearInterval(interval); //< Stop this interval
            }
        }
    }, 250); //< repeat check every 250ms
};


var page = require('webpage').create();
page.viewportSize = {
  width: 1000,
  height: 1000
};

page.open("http://jsbin.com/pevizusana", function (status) { //Works best on localhost
    // Check for page load success
    if (status !== "success") {
    console.log("Unable to access network");
    } else {
    // Wait for 'signin-dropdown' to be visible
    waitFor(function() {
        // Check in the page if a specific element is now visible
        return page.evaluate(function() {
            return document.getElementById("loaded");
        });
    }, function() {
       console.log("The map should be visible now.");
       page.render('googleScreenShot' + '.png');
       phantom.exit();
    });        
    }
});

And here's the result: https://i.stack.imgur.com/k3jrr.jpg

enter image description here

I hope you find this information helpful.

xomena
  • 31,125
  • 6
  • 88
  • 117