WebGIS programming: Openlayers map printing

The simplest function of map printing on the Web side is to output the map within the current window, that is, export the current map as a picture and store it to the client. Different browsers provide their own screen capture functions, and the function of exporting maps can also be realized based on the screen capture function of the browser or plug-in script.

OpenLayers5 has two rendering modes for rendering maps, namely Canvas and WebGL. You can export pictures based on map rendering container objects. This example uses the default Canvas rendering mode to load the map, so it uses the toDataURL method of Canvas mode to export the map. Its page function item exports the download link of the map through the download setting of a tag, and only supports browsers other than IE kernel.

The main implementation steps are as follows:

1. Reference the development library: this example introduces the development library through the local offline [include openlayers local. JS] script;

2. Reference a third-party library: import a third-party library. This example uses the local offline filesaver Min.js and jspdf Min.js script introduction;

3. Create a map container: create a div with id="mapCon" as a map container and set its style;

4. Create map object: create a map object, set the necessary parameters of the map, and set the layers attribute as the sky map layer;

5. Export pictures: by listening to the postcompose event of map, obtain the canvas object drawn by graphics, so as to realize the function of exporting pictures;

 map.once('postcompose', function(event) {
      var canvas = event.context.canvas

      canvas.toBlob(function(blob) {
          saveAs(blob, 'map.png')
      })
  })
  map.renderSync()

6. Export PDF:

By listening to the postcompose event of map, obtain the canvas object of graphic drawing, and use the export PDF function provided by the third-party library to realize the function of exporting PDF.

  var dims = {
    a0: [1189, 841],
    a1: [841, 594],
    a2: [594, 420],
    a3: [420, 297],
    a4: [297, 210],
    a5: [210, 148],
  }
  var format = document.getElementById('format').value
  var resolution = document.getElementById('resolution').value
  var dim = dims[format]
  var width = Math.round((dim[0] * resolution) / 25.4)
  var height = Math.round((dim[1] * resolution) / 25.4)
  var size = /** @type {ol.Size} */ (map.getSize())
  var extent = map.getView().calculateExtent(size)

  map.once('postcompose', function(event) {
    var canvas = event.context.canvas
    var data = canvas.toDataURL('image/jpeg')
    var pdf = new jsPDF('landscape', undefined, format)
    pdf.addImage(data, 'JPEG', 0, 0, dim[0], dim[1])
    pdf.save('map.pdf')
  })
  map.setSize([width, height])
  map.getView().fit(extent, map.getSize())
  map.renderSync()

Key interface

1. [maps] ol map

[method] once(type, listener): listen to a certain type of map event

Parameter name

type

explain

type

String

Array{String}

listener

function

Function triggered when listening event occurs

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <!--Current sample page style sheet reference-->
    <link rel="stylesheet" href="./static/demo/openlayers/example/style.css" />
    <script include="jquery" src="./static/libs/include-lib-local.js"></script>
    <script src="./static/libs/include-openlayers-local.js"></script>
    <script src="./static/libs/cdn/filesaver/dist/FileSaver.min.js"></script>
    <script src="./static/libs/cdn/filesaver/dist/jspdf.min.js"></script>
    <style type="text/css">
        #mapCon {
            width: 100%;
            height: 95%;
            position: absolute;
        }
        
        .ol-mouse-position {
            top: 95%;
            right: 8px;
            position: absolute;
        }
        
        label {
            color: white;
            font-size: 6px;
            font-weight: 500;
            font-family: cursive;
            line-height: 10px;
            margin: 5px 5px;
        }
        
        select {
            height: 16px;
            font-size: 8px;
            width: 60px;
        }
    </style>

    <script type="text/javascript">
        var tdk = '4c27d6e0e8a90715b23a989d42272fd8' //Day map key
        var mousePositionControl = null
        var map = null

        function init() {
            //Load day map tile layer data
            var TiandiMap_vect = new ol.layer.Tile({
                title: 'Sky map vector layer',
                source: new ol.source.XYZ({
                    url: 'http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=' + tdk,
                    wrapX: false,
                    crossOrigin: 'Anonymous',
                }),
            })

            var TiandiMap_vectcia = new ol.layer.Tile({
                    title: 'Sky map vector annotation layer',
                    source: new ol.source.XYZ({
                        url: 'http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=' + tdk,
                        crossOrigin: 'Anonymous',
                    }),
                })
                //Initialize map container
            map = new ol.Map({
                target: 'mapCon', //ID of map container div
                controls: ol.control.defaults({
                    attributionOptions: {
                        collapsible: true,
                    },
                }),
                view: new ol.View({
                    center: [12000000, 4000000], //Map initial center point
                    maxZoom: 28, //Maximum tile display level
                    minZoom: 1, //Minimum tile display stage
                    zoom: 6, //Map initial display level
                }),
                layers: [TiandiMap_vect, TiandiMap_vectcia],
            })

            mousePositionControl = new ol.control.MousePosition({
                coordinateFormat: ol.coordinate.createStringXY(4),
                // projection: 'EPSG:3857'
            })
            map.addControl(mousePositionControl)
        }

        function MapExportPng() {
            map.once('postcompose', function(event) {
                var canvas = event.context.canvas

                canvas.toBlob(function(blob) {
                    saveAs(blob, 'map.png')
                })
            })
            map.renderSync()
        }

        function MapExportPdf() {
            var dims = {
                a0: [1189, 841],
                a1: [841, 594],
                a2: [594, 420],
                a3: [420, 297],
                a4: [297, 210],
                a5: [210, 148],
            }
            var format = document.getElementById('format').value
            var resolution = document.getElementById('resolution').value
            var dim = dims[format]
            var width = Math.round((dim[0] * resolution) / 25.4)
            var height = Math.round((dim[1] * resolution) / 25.4)
            var size = /** @type {ol.Size} */ (map.getSize())
            var extent = map.getView().calculateExtent(size)

            map.once('postcompose', function(event) {
                var canvas = event.context.canvas
                var data = canvas.toDataURL('image/jpeg')
                var pdf = new jsPDF('landscape', undefined, format)
                pdf.addImage(data, 'JPEG', 0, 0, dim[0], dim[1])
                pdf.save('map.pdf')
            })

            map.setSize([width, height])
            map.getView().fit(extent, map.getSize())
            map.renderSync()
        }
    </script>
</head>

<body onload="init()">
    <div id="mapCon"></div>

    <fieldset style="position: absolute;width: 140px;height: 45px;top: 18px;left: 50px;background-color: black;opacity: 0.5;border-radius: 10px;padding: 10px 6px;">
        <label>Picture size:</label>
        <select id="format">
                <option value="a0">A0</option>
                <option value="a1">A1</option>
                <option value="a2">A2</option>
                <option value="a3">A3</option>
                <option value="a4" selected>A4</option>
                <option value="a5">A5</option>
            </select>
        <br />
        <label style="letter-spacing: 4px;margin-right: 0px;">resolving power:</label>
        <select id="resolution">
                <option value="72">72 dpi</option>
                <option value="150">150 dpi</option>
                <option value="300">300 dpi</option>
            </select>
    </fieldset>

    <div id="menuContain" class="menuContain">
        <div id="tool-container">
            <div id="dataSourceMenuID" class="optmain" status="unactive" onclick="switchMenuStatus(this,'menu1')"><span></span><i class="menuGroup">Map output</i><em></em></div>
        </div>
    </div>
    <div id="menu1" class="menuStrip" style="display:none">
        <ul class="menuItems">
            <li onclick="MapExportPng()"><span class="item1"></span><i>picture</i></li>
            <li onclick="MapExportPdf()"><span class="item1"></span><i>PDF</i></li>
        </ul>
    </div>
    <script>
        function switchMenuStatus(div, menuitemFrameID) {
            var temDivs = document.getElementsByClassName('optmain')
            if (temDivs.length > 0) {
                for (var i = 0; i < temDivs.length; i++) {
                    if (temDivs[i] === div) {
                        var status = div.getAttribute('status')
                        if (status == 'unactive') {
                            div.setAttribute('status', 'active')
                            var tem_spans = div.getElementsByTagName('span')
                            var tem_ems = div.getElementsByTagName('em')
                            tem_spans[0].className = 'active'
                            tem_ems[0].className = 'active'

                            //Show menu items
                            DisplayMenuItem(true, menuitemFrameID)
                        } else {
                            div.setAttribute('status', 'unactive')
                            var tem_spans = div.getElementsByTagName('span')
                            var tem_ems = div.getElementsByTagName('em')
                            tem_spans[0].className = ''
                            tem_ems[0].className = ''

                            //Hide menu items
                            DisplayMenuItem(false, menuitemFrameID)
                        }
                    } else {
                        var status = temDivs[i].getAttribute('status')
                        if (status == 'active') {
                            temDivs[i].setAttribute('status', 'unactive')
                            var tem_spans = temDivs[i].getElementsByTagName('span')
                            var tem_ems = temDivs[i].getElementsByTagName('em')
                            tem_spans[0].className = ''
                            tem_ems[0].className = ''
                        }
                    }
                }
            }
        }

        function DisplayMenuItem(isDisplay, iframeID) {
            var menuItemFrame = document.getElementById(iframeID)
            if (menuItemFrame != null) {
                if (isDisplay) {
                    var temDivs = document.getElementsByClassName('menuStrip')
                    if (temDivs.length > 0) {
                        for (var i = 0; i < temDivs.length; i++) {
                            if (temDivs[i] != menuItemFrame) {
                                temDivs[i].style.display = 'none'
                            }
                        }
                    }
                    menuItemFrame.style.display = ''
                } else {
                    menuItemFrame.style.display = 'none'
                }
            }
        }
    </script>
</body>

</html>

Keywords: Javascript Front-end Web Development gis

Added by WindomEarle on Sun, 23 Jan 2022 00:21:55 +0200