Openlayers 教程 - 地图以及图层数据导出(打印)图片

news2024/11/19 7:50:33

Openlayers 教程 - 地图以及图层数据导出(打印)图片

    • 地图导出核心代码
    • 完整代码:
    • 在线示例

本文包括地图导出核心代码、完整代码以及在线示例。


地图导出核心代码

这里放上 ES 封装的核心代码,创建多边形或者其他几何对象,直接使用材质即可:


/**
 *  todo 保存地图
 * @param {string} format - 格式,目前只支持图片
 */
function saveMap(format) {

    const thisObject = map;

    thisObject.once('rendercomplete', function () {
        const mapCanvas = document.createElement('canvas');
        const size = thisObject.getSize();
        mapCanvas.width = size[0];
        mapCanvas.height = size[1];
        const mapContext = mapCanvas.getContext('2d');
        Array.prototype.forEach.call(
            document.querySelectorAll('.ol-layers canvas'),
            function (canvas) {
                if (canvas.width > 0) {
                    const opacity = canvas.parentNode.style.opacity;
                    mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
                    const transform = canvas.style.transform;
                    // Get the transform parameters from the style's transform matrix
                    const transformTemp = transform
                        .match(/^matrix\(([^\\(]*)\)$/);

                    const matrix = transformTemp && transformTemp[1]
                        .split(',')
                        .map(Number);
                    // Apply the transform to the export map context
                    CanvasRenderingContext2D.prototype.setTransform.apply(
                        mapContext,
                        matrix
                    );
                    mapContext.drawImage(canvas, 0, 0);
                }
            }
        );
        if (navigator.msSaveBlob) {
            // link download attribuute does not work on MS browsers
            navigator.msSaveBlob(mapCanvas.msToBlob(), 'map.png');
        } else {
            mapCanvas.toBlob(function (blob) {
                saveAs(blob, 'map.png');
            });
        }
    });

    map.renderSync();
}


完整代码:

<html lang="en">
<head>
    <meta charSet="utf-8">
    <!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
    <link rel="stylesheet" href="http://openlayers.vip/examples/css/ol.css" type="text/css">
    <style>
        /* 注意:这里必须给高度,否则地图初始化之后不显示;一般是计算得到高度,然后才初始化地图 */
        .map {
            height: 400px;
            width: 100%;
            float: left;
        }
    </style>
    <!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
    <script src="http://openlayers.vip/examples/resources/ol.js"></script>
    <script src="https://openlayers.vip/examples/resources/FileSaver.js"></script>
    <script src="./tiandituLayers.js"></script>
    <title>OpenLayers example</title>
    <script>
        var _hmt = _hmt || [];
        (function () {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
    </script>
</head>
<body>
<h2>OpenLayers export</h2>
<!--地图容器,需要指定 id -->
<div id="map" class="map"></div>
<br/>
<br/>
<script type="text/javascript">

    var map = new ol.Map({
        // 地图容器
        target: 'map',
        // 地图图层,比如底图、矢量图等
        layers: [
            getIMG_CLayer(),
            getIBO_CLayer(),
            getCIA_CLayer(),
        ],
        // 地图视野
        view: new ol.View({
            projection: "EPSG:4326",
            // 定位
            center: [115.67724700667199, 37.73879478106912],
            // 缩放
            zoom: 6,
            maxZoom: 18,
            minZoom: 1,
        })
    });

    // 默认样式
    var defaultStyle = new ol.style.Style({
        //边框样式
        stroke: new ol.style.Stroke({
            color: 'red',
            width: 2,
        }),
        //填充样式
        fill: new ol.style.Fill({
            color: 'rgba(0, 0, 255, 0.3)',
        }),
        image: new ol.style.Circle({
            radius: 5,
            fill: new ol.style.Fill({
                color: 'white',
            })
        })
    })

    // 初始化图层
    var layer = initVectorLayer();

    // 传递的方式开启悬浮的图形要素
    let polygon1 = "POLYGON((112.80630306271966 46.27140545436643,116.23403743771966 44.33781170436643,117.81606868771966 40.29484295436643,117.90395931271966 38.36124920436643,117.81606868771966 35.02140545436643,116.14614681271966 32.38468670436643,113.50942806271966 33.26359295436643,111.75161556271966 34.58195232936643,110.60903743771966 35.46085857936643,113.28970150021968 36.03214764186642,111.35610775021968 36.33976482936642,110.91665462521968 36.91105389186642,111.22427181271968 37.52628826686642,112.10317806271968 37.30656170436642,112.41079525021968 37.78996014186642,112.32290462521968 38.36124920436642,111.44399837521968 38.66886639186642,110.52114681271968 39.10831951686642,110.38931087521968 39.81144451686642,111.09243587521968 40.07511639186642,112.19106868771968 40.38273357936642,112.49868587521968 41.04191326686642,111.88345150021968 41.21769451686642,111.26821712521968 40.86613201686642,110.43325618771968 40.91007732936642,110.65298275021968 41.39347576686642,110.47720150021968 42.66788982936642,111.79556087521968 42.75578045436642,110.38931087521968 43.19523357936642,110.56509212521968 44.24992107936642,111.44399837521968 43.76652264186642,111.79556087521968 44.16203045436642,111.09243587521968 44.60148357936642,111.22427181271968 45.30460857936642,112.10317806271968 44.95304607936642,112.67446712521968 45.26066326686642,111.75161556271968 45.78800701686642,111.88345150021968 46.40324139186642,112.14712337521968 47.94132732936642,112.45474056271968 47.15031170436642,113.99282650021968 47.28214764186642,113.28970150021968 46.79874920436642,114.95962337521968 46.71085857936642,112.80630306271966 46.27140545436643))";
    // 移入和移出事件的图形要素
    let polygon2 = "POLYGON((123.94676492355833 44.03121337817592,118.40965554855833 38.23043212817592,121.66160867355833 32.82515869067592,129.30809304855833 33.39644775317592,129.92332742355833 39.46090087817592,123.94676492355833 44.03121337817592))";
    // 选中方式的悬浮的图形要素
    let polygon3 = "POLYGON((107.96587424038064 27.434398296739595,125.98345236538064 30.554515484239595,126.68657736538064 24.446117046739595,110.16313986538064 17.942210796739595,107.96587424038064 27.434398296739595))";

    // 添加点线面
    function addFeatures() {

        // 这里处理一下,可以自由传图形要素 start===================================================
        layer.getSource().clear();

        const feature1 = getFeatureByWKT(polygon1);
        const feature2 = getFeatureByWKT(polygon2);

        layer.getSource().addFeatures([feature1, feature2]);

        map.getView().fit([93.64037006658276, 10.72265625,128.53294819158273, 51.181893294147805], {
            duration: 1,//动画的持续时间,
            callback: null,
        });
    }

    addFeatures();

    /**
     * @todo 矢量图层
     * @returns {VectorLayer}
     * @constructor
     */
    function initVectorLayer() {
        //实例化一个矢量图层Vector作为绘制层
        let source = new ol.source.Vector();
        //创建一个图层
        let customVectorLayer = new ol.layer.Vector({
            source: source,
            zIndex: 2,
            //设置样式
            style: defaultStyle,
        });
        //将绘制层添加到地图容器中
        map.addLayer(customVectorLayer);

        return customVectorLayer;
    }

    /**
     * @todo wkt格式数据转化成图形对象
     * @param {string} wkt   "POINT(112.7197265625,39.18164062499999)" 格式数据
     * @param {string|Projection} sourceCode 源投影坐标系
     * @param {string|Projection} targetCode 目标投影坐标系
     * @returns {Feature}
     */
    function getFeatureByWKT(wkt, sourceCode, targetCode) {
        try {
            let view = map.getView();
            if (!wkt) {
                return null;
            }
            let format = new ol.format.WKT();

            let feature;

            feature = format.readFeature(wkt, {
                featureProjection: targetCode || view.getProjection(),
                dataProjection: sourceCode || view.getProjection(),
            });

            return feature;
        } catch (e) {
            console.log(e);
            return null;
        }
    }

    /**
     *  todo 保存地图
     * @param {string} format - 格式,目前只支持图片
     */
    function saveMap(format) {

        const thisObject = map;

        thisObject.once('rendercomplete', function () {
            const mapCanvas = document.createElement('canvas');
            const size = thisObject.getSize();
            mapCanvas.width = size[0];
            mapCanvas.height = size[1];
            const mapContext = mapCanvas.getContext('2d');
            Array.prototype.forEach.call(
                document.querySelectorAll('.ol-layers canvas'),
                function (canvas) {
                    if (canvas.width > 0) {
                        const opacity = canvas.parentNode.style.opacity;
                        mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
                        const transform = canvas.style.transform;
                        // Get the transform parameters from the style's transform matrix
                        const transformTemp = transform
                            .match(/^matrix\(([^\\(]*)\)$/);

                        const matrix = transformTemp && transformTemp[1]
                            .split(',')
                            .map(Number);
                        // Apply the transform to the export map context
                        CanvasRenderingContext2D.prototype.setTransform.apply(
                            mapContext,
                            matrix
                        );
                        mapContext.drawImage(canvas, 0, 0);
                    }
                }
            );
            if (navigator.msSaveBlob) {
                // link download attribuute does not work on MS browsers
                navigator.msSaveBlob(mapCanvas.msToBlob(), 'map.png');
            } else {
                mapCanvas.toBlob(function (blob) {
                    saveAs(blob, 'map.png');
                });
            }
        });

        map.renderSync();
    }

</script>
<button id="saveMap" onClick="saveMap()">打印地图</button>
</body>
</html>

在这里插入图片描述

在这里插入图片描述


在线示例

Openlayers 在线示例:地图以及图层数据导出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1066116.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

做小说推文和短剧推广,找数据好的授权平台

小说推文和短剧推广很多平台吃单怎么办&#xff1f;可以试试”巨量推文“&#xff0c;一个不吃单的平台 众所周知 小说推文和短剧推广很多平台会吃单&#xff0c;比如你实际官方数据是10个订单&#xff0c;很多平台只给你5个&#xff0c;这样你损失可能就是一半的利润&#xf…

【MySQL】基本查询(二)

文章目录 一. 结果排序二. 筛选分页结果三. Update四. Delete五. 截断表六. 插入查询结果结束语 操作如下表 //创建表结构 mysql> create table exam_result(-> id int unsigned primary key auto_increment,-> name varchar(20) not null comment 同学姓名,-> chi…

虚拟展厅有什么重要意义,了解虚拟展厅在宣传中的应用

引言&#xff1a; 随着科技的不断进步&#xff0c;虚拟展厅已经逐渐成为展览行业的重要一环。虚拟展厅是一种数字化平台&#xff0c;为观众提供了与传统展览完全不同的体验。 一&#xff0e;虚拟展厅的定义 虚拟展厅是一个通过互联网和虚拟现实技术创建的数字展示空间&#x…

windows系统下利用python对指定文件夹下面的所有文件的创建时间进行修改

windows系统下利用python对指定文件夹下面的所有文件的创建时间进行修改 不知道其他的朋友们有没有这个需求哈&#xff0c;反正咱家是有这个需求 需求1、当前有大量的文件需要更改文件生成的时间&#xff0c;因为不可告知的原因&#xff0c;当前的文件创建时间是不能满足使用的…

现在玩51单片机,这也太LOW了?

作为一名科普的博主&#xff0c;今天我们来聊一聊51单片机。 一、什么是51单片机 单片机是一种微型计算机&#xff0c;广泛应用于各种电子产品和工业控制领域。51单片机是指基于Intel的8051微处理器为核心的单片机&#xff0c;是最为常见和广泛应用的单片机之一。 二、51单片机…

近视眼选择什么台灯好?分享医生都说好的台灯

如今全国近视人数已经超过6亿&#xff0c;差不多占据了我国人口的一半&#xff0c;而青少年的近视率更是位居世界第一&#xff01;据数据显示&#xff0c;全国儿童青少年总体近视率高达53.6%&#xff0c;其中小学生为36.0%&#xff0c;初中生为71.6%&#xff0c;高中生为81.0%&…

微服务学习(十一):安装Git

微服务学习&#xff08;十一&#xff09;&#xff1a;安装Git 1、下载Git 官网下载Git 2、将下载后的资源包上传到服务器 3、解压并安装 tar -zxvf git-2.42.0.tar.gz4、安装依赖 yum install zlib yum install zlib-devel5、执行操作命令 cd /home/git/git-2.42.0 ./co…

华为云CodeArts Check代码检查服务用户声音反馈集锦(8)

作者&#xff1a;gentle_zhou 原文链接&#xff1a;CodeArts Check代码检查服务用户声音反馈集锦&#xff08;8&#xff09;-云社区-华为云 CodeArts Check&#xff08;原CodeCheck&#xff09;&#xff0c;是自主研发的代码检查服务。建立在华为30年自动化源代码静态检查技术…

张量-算术操作函数

tf.add(x,y,name None)求和函数 示例代码如下: import tensorflow.compat.v1 as tf tf.disable_v2_behavior()x 1 y 2a tf.add(x,y)with tf.Session() as sess:print(sess.run(a)) tf.subtract(x,y,name None)减法函数 示例代码如下: import tensorflow.compat.v1 as …

吐血整理,最全Pytest自动化测试框架快速上手(超详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 pytest框架 pyte…

前端【响应式图片处理】之 【picture标签】

目录 &#x1f31f;前言&#x1f31f;目前最常见的解决方案&#x1f31f;新的解决方案<picture>&#x1f31f;<picture>的工作原理&#x1f31f;<picture> 兼容性解决方案&#x1f31f;写在最后 &#x1f31f;前言 哈喽小伙伴们&#xff0c;前端开发过程中经…

<el-input> textarea文本域显示滚动条(超过高度就自动显示)

需求&#xff1a;首先是给定高度&#xff0c;输入文本框要自适应这个高度。文本超出高度就会显示滚动条否则不显示。 <el-row class"textarea-row"><el-col :span"3" class"first-row-title">天气</el-col><el-col :span&…

多目标优化两种算法:加权、智能优化算法

传统数学优化算法&#xff08;加权&#xff09; 使用数学优化算法解决多目标优化问题通常是将各个子目标聚合成一个带权重的单目标函数&#xff0c;系数由决策者决定&#xff0c;或者由优化方法自适应调整。即通过加权等方式将多目标问题转化为单目标问题进行求解。 这样每次只…

编程每日一练(多语言实现)基础篇:控制台打印九九乘法口诀表

文章目录 一、实例描述二、技术要点三、代码实现3.1 C 语言实现3.2 Python 语言实现3.3 Java 语言实现3.4 JavaScript 语言实现3.5 Go 语言实现 一、实例描述 本实例要求打印出乘法口诀表&#xff0c;在乘法口诀有行和列项的相乘得出的乘法结果。根据这个特点&#xff0c;使用…

Configuration of phpstudy and sqli-labs

Go download the app&#xff1a; 小皮面板(phpstudy) - 让天下没有难配的服务器环境&#xff01; (xp.cn) Have done. Then enter the program. Enable both functions&#xff1a; Apache and MySQL. Open the website&#xff1a; Next, Lets make the sqli-liab. GitHub…

Web server failed to start. Port 8080 was already in use

一、问题 package com.djc.boot;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annota…

几个G视频能压缩成几百MB吗?跟我学视频压缩

视频大小是可以压缩的&#xff0c;现在很多情况下&#xff0c;视频文件的大小都会限制我们的行动&#xff0c;例如需要将大量视频文件随身携带&#xff0c;或者在有限的网络带宽下传输视频文件。为了解决这些问题&#xff0c;下面给大家分享几个视频压缩的技巧&#xff0c;轻松…

6-8 求链表的倒数第m个元素 分数 15

ElementType Find(List L, int m) {int count 0;for (struct Node* cur L; cur ! NULL; cur cur->Next){count;}if (m > count) {return ERROR;}int n count - m 1;struct Node* cur L;while(--n)cur cur->Next;return cur->Data; }

鹿客携手小度、天翼数字生活等生态伙伴,开启全联接Opening计划

物联网、AI等新一代信息技术的飞速发展&#xff0c;各类家居家电智能水平与日俱增。作为智能家居入口级产品&#xff0c;智能门锁行业技术也在不断内卷&#xff0c;从密码解锁&#xff0c;到指纹识别、人脸识别、生物识别&#xff0c;不断升级。寻求更安全、更便捷、更智能的新…

Android之App跳转其他软件

文章目录 前言一、效果图二、实现步骤1.弹框xml(自己替换图标)2.弹框utils3.两个弹框动画4.封装方便调用5.调用6.长按事件方法7.跳转步骤8.复制utils 总结 前言 最近遇到一个需求&#xff0c;就是App内大面积需要长按复制并跳转指定App&#xff0c;没办法&#xff0c;只能埋头…