返回介绍

按比例导出地图

发布于 2022-11-30 23:36:05 字数 8877 浏览 0 评论 0 收藏 0

本示例演示按给定比例导出地图。

本示例演示按给定比例导出地图。本示例使用 jsPDF 库将地图导出为 PDF。 跟 Export PDF example 不一样的是,此屏幕上的地图只用来设置中心点和旋转。 地图打印依赖于设置的比例和页面尺寸。 为了打印比例尺和属性,本示例使用了 html2canvas 库。

main.js

import 'ol/ol.css';
import Map from 'ol/Map';
import TileLayer from 'ol/layer/Tile';
import View from 'ol/View';
import WMTS, {optionsFromCapabilities} from 'ol/source/WMTS';
import WMTSCapabilities from 'ol/format/WMTSCapabilities';
import proj4 from 'proj4';
import {ScaleLine, defaults as defaultControls} from 'ol/control';
import {getPointResolution, get as getProjection} from 'ol/proj';
import {register} from 'ol/proj/proj4';

proj4.defs(
  'EPSG:27700',
  '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 ' +
    '+x_0=400000 +y_0=-100000 +ellps=airy ' +
    '+towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 ' +
    '+units=m +no_defs'
);

register(proj4);

const proj27700 = getProjection('EPSG:27700');
proj27700.setExtent([0, 0, 700000, 1300000]);

const raster = new TileLayer();

const url =
  'https://tiles.arcgis.com/tiles/qHLhLQrcvEnxjtPr/arcgis/rest/services/OS_Open_Raster/MapServer/WMTS';
fetch(url)
  .then(function (response) {
    return response.text();
  })
  .then(function (text) {
    const result = new WMTSCapabilities().read(text);
    const options = optionsFromCapabilities(result, {
      layer: 'OS_Open_Raster',
    });
    options.attributions =
      'Contains OS data © Crown Copyright and database right ' +
      new Date().getFullYear();
    options.crossOrigin = '';
    options.projection = proj27700;
    options.wrapX = false;
    raster.setSource(new WMTS(options));
  });

const map = new Map({
  layers: [raster],
  controls: defaultControls({
    attributionOptions: {collapsible: false},
  }),
  target: 'map',
  view: new View({
    center: [373500, 436500],
    projection: proj27700,
    zoom: 7,
  }),
});

const scaleLine = new ScaleLine({bar: true, text: true, minWidth: 125});
map.addControl(scaleLine);

const dims = {
  a0: [1189, 841],
  a1: [841, 594],
  a2: [594, 420],
  a3: [420, 297],
  a4: [297, 210],
  a5: [210, 148],
};

// export options for html2canvase.
// See: https://html2canvas.hertzen.com/configuration
const exportOptions = {
  useCORS: true,
  ignoreElements: function (element) {
    const className = element.className || '';
    return !(
      className.indexOf('ol-control') === -1 ||
      className.indexOf('ol-scale') > -1 ||
      (className.indexOf('ol-attribution') > -1 &&
        className.indexOf('ol-uncollapsible'))
    );
  },
};

const exportButton = document.getElementById('export-pdf');

exportButton.addEventListener(
  'click',
  function () {
    exportButton.disabled = true;
    document.body.style.cursor = 'progress';

    const format = document.getElementById('format').value;
    const resolution = document.getElementById('resolution').value;
    const scale = document.getElementById('scale').value;
    const dim = dims[format];
    const width = Math.round((dim[0] * resolution) / 25.4);
    const height = Math.round((dim[1] * resolution) / 25.4);
    const viewResolution = map.getView().getResolution();
    const scaleResolution =
      scale /
      getPointResolution(
        map.getView().getProjection(),
        resolution / 25.4,
        map.getView().getCenter()
      );

    map.once('rendercomplete', function () {
      exportOptions.width = width;
      exportOptions.height = height;
      html2canvas(map.getViewport(), exportOptions).then(function (canvas) {
        const pdf = new jspdf.jsPDF('landscape', undefined, format);
        pdf.addImage(
          canvas.toDataURL('image/jpeg'),
          'JPEG',
          0,
          0,
          dim[0],
          dim[1]
        );
        pdf.save('map.pdf');
        // Reset original map size
        scaleLine.setDpi();
        map.getTargetElement().style.width = '';
        map.getTargetElement().style.height = '';
        map.updateSize();
        map.getView().setResolution(viewResolution);
        exportButton.disabled = false;
        document.body.style.cursor = 'auto';
      });
    });

    // Set print size
    scaleLine.setDpi(resolution);
    map.getTargetElement().style.width = width + 'px';
    map.getTargetElement().style.height = height + 'px';
    map.updateSize();
    map.getView().setResolution(scaleResolution);
  },
  false
);

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Print to scale example</title>
    <!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
    <script src="https://unpkg.com/elm-pep"></script>
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="./resources/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,URL,TextDecoder,Number.isInteger"></script>
    <script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.3.1/jspdf.umd.min.js"></script>
    <style>
      .map {
        width: 100%;
        height:400px;
      }
      .wrapper {
        max-width: 566px;
        width: 100%;
        height: 400px;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div class="wrapper">
      <div id="map" class="map"></div>
    </div>
    <form class="form">
      <label for="format">Page size </label>
      <select id="format">
        <option value="a0">A0 (slow)</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 (fast)</option>
      </select>
      <label for="resolution">Resolution </label>
      <select id="resolution">
        <option value="72">72 dpi (fast)</option>
        <option value="150">150 dpi</option>
        <option value="200" selected>200 dpi</option>
        <option value="300">300 dpi (slow)</option>
      </select>
      <label for="scale">Scale </label>
      <select id="scale">
        <option value="500">1:500000</option>
        <option value="250" selected>1:250000</option>
        <option value="100">1:100000</option>
        <option value="50">1:50000</option>
        <option value="25">1:25000</option>
        <option value="10">1:10000</option>
      </select>
    </form>
    <button id="export-pdf">Export PDF</button>
    <script src="main.js"></script>
  </body>
</html>

package.json

{
  "name": "print-to-scale",
  "dependencies": {
    "ol": "7.1.0",
    "proj4": "^2.7.5"
  },
  "devDependencies": {
    "parcel": "^2.0.0-beta.1"
  },
  "scripts": {
    "start": "parcel index.html",
    "build": "parcel build --public-url . index.html"
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文