Openlayers Print Function

2019-06-23 22:24发布

问题:

I would like to create a print button for my Openlayers map which grabs the map image and creates a nice image file. I have tried http://dev.openlayers.org/sandbox/camptocamp/canvas/openlayers/examples/exportMapCanvas.html but it seams like it is experimental. I have also looked at http://trac.osgeo.org/openlayers/wiki/Printing but I don't want any server involved. I also checked out http://html2canvas.hertzen.com/ but can't get it to work. I get the following error, Uncaught TypeError: Cannot read property 'images' of undefined, html2canvas.js

<button onclick="printFunction()">Click me</button>

function printFunction() {

        html2canvas(('#map'), {
            onrendered: function (canvas) {
                var img = canvas.toDataURL("image/png")
                window.open(img);
            }
        });
    };

回答1:

Try

function printFunction() {

    html2canvas(document.getElementById("map"), {
        onrendered: function (canvas) {
            var img = canvas.toDataURL("image/png")
            window.open(img);
        }
    });

This works for me. The hashtag identification only works for jQuery, took me a while to figure that out :-)

There is a slight problem though. The html2canvas did not render the background WMS layer - only the map window and markers, so some tweaking still needs to be done.

Update : I have done some fiddling with this, and I do not think that it will work with openlayers. Since the openlayers map is a composition of many divs, it seems that the html2canvas is not capable of drawing all of them properly. Specifically a WMS layer, which, when attempted to be drawn on its own, returns an error. You can try rendering one of the children divs in the map, but that has not worked for me. Although, if you are only using simple vector graphic, it could work for you.



回答2:

Ok, I've spent a few hours on this now and the best I've come up with is an enhancement on @Kenny806 's answer, which is basically this one.

It does seem to pick up WMS and Vector layers:

    function exportMap() {

        var mapElem = document.getElementById('map'); // the id of your map div here

        // html2canvas not able to render css transformations (the container holding the image tiles uses a transform)
        // so we determine the values of the transform, and then apply them to TOP and LEFT 
        var transform=$(".gm-style>div:first>div").css("transform");
        var comp=transform.split(","); //split up the transform matrix
        var mapleft=parseFloat(comp[4]); //get left value
        var maptop=parseFloat(comp[5]);  //get top value
        $(".gm-style>div:first>div").css({ //get the map container. not sure if stable
          "transform":"none",
          "left":mapleft,
          "top":maptop,
        });

        html2canvas(mapElem, {
          useCORS: true,
          onrendered: function(canvas) {
             mapImg = canvas.toDataURL('image/png');

            // reset the map to original styling
            $(".gm-style>div:first>div").css({
              left:0,
              top:0,
              "transform":transform
            });

            // do something here with your mapImg
            // e.g. I then use the dataURL in a pdf using jsPDF...
            // createPDFObject();
          }
        });
    }

Notes

  • Only tested on Chrome and Firefox
  • This is a hacky solution (unfortunately I am struggling to find other options for my situation)
  • If you have the option to use Openlayers 3, there seems to be better canvas support, and I've also seen a convincing toBlob example: http://codepen.io/barbalex/pen/raagKq


回答3:

WMS draw works fine but you have to implement a Proxy for downloading WMS tiles using AJAX. See the PHP proxy example of html2canvas for the implementation details of the "proxy" (which is not a http proxy".