Openlayers 实战 - 地图视野(View)- 图层 -(layer)- 资源(source)显示等级设置。

Openlayers 实战 - 地图视野(View)- 图层 -(layer)- 资源(source)显示等级设置。

    • 问题原因
    • 核心代码
    • 完整代码:
    • 在线示例

在以往的项目维护中,出现一个问题,使用最新高清底图发现,设置地图最大等级(21级)之后,地图虽然可以渲染 21 级图层,但是并没有请求 21 级图层瓦片数据

思考之后,认为是地图等级参数限制,经过调试发现问题所在不仅于此,后来解决问题,这里记录一下。

本文包括问题原因、问题解决核心代码以及在线示例。


问题原因

地图图层想要设置缩放等级,需要三个条件:

1. 地图视野 View 对象设置 minzoom maxzoom 参数。

2. 图层 layer 对象设置 minzoom maxzoom 参数。

3. 资源 source 设置分辨率 tileGrid-resolutions 参数。


三个条件缺一不可,以下分别设置部分对象属性出现的问题:

1.只设置地图,不设置图层,地图可以放大,但是不会请求资源;由于图层没有资源,会显示空白。

PS: 下图额外加载了一个显示 zoom 的图层。

在这里插入图片描述

2. 只设置图层,不设置地图,地图不能继续放大,因此也不会加载高等级图层瓦片。

在这里插入图片描述

3. 设置地图以及图层,不设置资源,地图和图层可以放大,但是不会请求资源,只是图片放大了,看起来会模糊。

在这里插入图片描述

4. 地图视野、图层、资源同时设置,会正常请求相应的数据

在这里插入图片描述

核心代码

这里放上控制地图视野(View)、图层(Layer)、资源(Source)对象缩放等级的代码:

其中加载了一个显示瓦片索引的图层,用来查看图层瓦片请求情况:瓦片索引的图层


// 地图视野等级设置
function viewZoom() {
    view.setMaxZoom(maxZoom);
    view.setZoom(defaultMaxZoom + 1);
}

// 图层等级设置
function layerZoom() {
    layer.setMaxZoom(maxZoom);
}

// 图层资源等级设置
function sourceZoom() {
    layer.setSource(getOptional(getUrl(),maxZoom))
}

// 还原所有缩放等级
function restoreZoom() {
    view.setMaxZoom(defaultMaxZoom);
    layer.setMaxZoom(defaultMaxZoom);
    layer.setSource(getOptional(getUrl(),defaultMaxZoom))
    view.setZoom(defaultMaxZoom);
}


完整代码:


<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>
    <title>OpenLayers example</title>
</head>
<body>
<h2>View Layer Zoom</h2>
<!--地图容器,需要指定 id -->
<div id="map" class="map"></div>
<script type="text/javascript">

    // 自己的tk
    let TK = '2b7cbf61123cbe4e9ec6267a87e7442f';

    // 默认地图等级
    const defaultMaxZoom = 14;

    // 设置新的最大等级
    const maxZoom = 18;

    // 定位测试等级
    const moveToZoom = 16;

    // 获取天地图资源地址
    let getUrl = function (type = 'IMG_C') {
        let url = 'http://t{randomNumber}.tianditu.gov.cn/DataServer?T={type}&x={x}&y={y}&l={z}';
        url = url.replace('{randomNumber}', Math.round(Math.random() * 7).toString());
        url = url.replace('{type}', type);
        url = url + "&tk=" + TK;
        return url;
    }

    // 获取分辨率数组
    let getResolutionsExpert = function (size, maxZoom = defaultMaxZoom) {

        let resolutions = new Array(maxZoom);
        let matrixIds = new Array(maxZoom);
        for (let z = 0; z < maxZoom + 1; ++z) {
            //分辨率
            resolutions[z] = size / Math.pow(2, z);
            //放大等级
            matrixIds[z] = z;
        }
        return resolutions;
    }

    // 获取图层资源对象
    let getOptional = function (url, maxZoom) {

        let projection = ol.proj.get('EPSG:4326');
        let projectionExtent = projection.getExtent();
        let size = ol.extent.getWidth(projectionExtent) / 256;

        return new ol.source.XYZ({
            crossOrigin: 'anonymous',
            wrapX: true,
            //切片xyz获取方法
            tileUrlFunction: function (tileCoord) {
                const z = tileCoord[0];
                const x = tileCoord[1];
                let y = tileCoord[2];
                let completeUrl = url.replace('{z}', z.toString())
                    .replace('{y}', y.toString())
                    .replace('{x}', x.toString());
                return completeUrl;
            },
            //坐标系
            projection: projection,
            tileGrid: new ol.tilegrid.TileGrid({
                origin: ol.extent.getTopLeft(projectionExtent),
                tileSize: [256, 256],
                //分辨率数组 天地图为 1.40625
                resolutions: getResolutionsExpert(size, maxZoom)
            }),
        })
    }

    // 初始图层资源对象
    const source = getOptional(getUrl());

    //影像图
    function getIMG_CLayer() {
        let layer = new ol.layer.Tile({
            name: "天地图影像图层",
            source: source,
            maxZoom: defaultMaxZoom,
            minZoom: 1,
        });
        return layer;
    }

    // 地图视野对象
    const view = new ol.View({
        projection: "EPSG:4326",
        // 定位
        center: [116, 39],
        // 缩放
        zoom: defaultMaxZoom,
        maxZoom: defaultMaxZoom,
        minZoom: 1,
    });

    // 图层对象
    const layer = getIMG_CLayer();

    // 网格图层参数
    const size = 256;
    const canvas = document.createElement('canvas');
    canvas.width = size;
    canvas.height = size;
    const context = canvas.getContext('2d');
    context.strokeStyle = 'white';
    context.textAlign = 'center';
    context.font = '40px sans-serif';
    const lineHeight = 15;

    // 地图对象
    const map = new ol.Map({
        // 地图容器
        target: 'map',
        // 地图图层,比如底图、矢量图等
        layers: [
            layer,
            // 添加网格图层,显示等级:Z
            new ol.layer.WebGLTile({
                source: new ol.source.DataTile({
                    loader: function (z, x, y) {
                        const half = size / 2;
                        context.clearRect(0, 0, size, size);
                        context.fillStyle = 'rgba(100, 100, 100, 0.1)';
                        context.fillRect(0, 0, size, size);
                        context.fillStyle = 'white';
                        context.fillText(`z: ${z}`, half, half + lineHeight);
                        // context.fillText(`x: ${x}`, half, half);
                        // context.fillText(`y: ${y}`, half, half + lineHeight);
                        context.strokeRect(0, 0, size, size);
                        const data = context.getImageData(0, 0, size, size).data;
                        // converting to Uint8Array for increased browser compatibility
                        return new Uint8Array(data.buffer);
                    },
                    // disable opacity transition to avoid overlapping labels during tile loading
                    transition: 0,
                }),
            }),
        ],
        // 地图视野
        view: view
    });

    // 地图视野等级设置
    function viewZoom() {
        view.setMaxZoom(maxZoom);
        view.setZoom(defaultMaxZoom + 1);
    }

    // 图层等级设置
    function layerZoom() {
        layer.setMaxZoom(maxZoom);
    }

    // 图层资源等级设置
    function sourceZoom() {
        layer.setSource(getOptional(getUrl(),maxZoom))
    }

    // 还原所有缩放等级
    function restoreZoom() {
        view.setMaxZoom(defaultMaxZoom);
        layer.setMaxZoom(defaultMaxZoom);
        layer.setSource(getOptional(getUrl(),defaultMaxZoom))
        view.setZoom(defaultMaxZoom);
    }
</script>

<button id="viewZoom" onClick="viewZoom()">设置地图缩放等级(不改变 layer 和 source)</button>
<button id="layerZoom" onClick="layerZoom()">设置图层缩放等级(不改变 map 和 source)</button>
<button id="sourceZoom" onClick="sourceZoom()">设置资源缩放等级(不改变 map 和 layer)</button>
<button id="restoreZoom" onClick="restoreZoom()">还原所有缩放等级</button>
</body>
</html>



在线示例

在线示例:Openlayers 显示等级设置

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

error_Network Error

此页面为订单列表&#xff0c;是混合开发(页面嵌入在客户端中) 此页面为订单列表&#xff0c;此需求在开发时后端先将代码发布在测试环境&#xff0c;我在本地调试时调用的后端接口进行联调没有任何问题。 此后我将代码发布在测试环境&#xff0c;在app中打开页面&#xff0c…

JS逆向系列之某多多 anti_content

文章目录 声明目标网址anti_content参数分析参考js 环境python 调用测试往期逆向文章推荐声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请私信我立即删除! 目标网址 aHR0cHM6Ly9tb2JpbGUueWFuZ2tlZHVvL…

【碎碎念随笔】1、回顾我的电脑和编程经历

✏️ 闲着无事&#xff0c;讲述一下我的计算机和代码故事 一、初识计算机 &#x1f5a5;️ 余家贫&#xff0c;耕植无钱买电脑。大约六年级暑假&#xff0c;我在姐姐哪儿第一次接触到了计算机&#xff08;姐姐也是买的二手&#xff09;。 &#x1f5a5;️ 计算机真有趣&#x…

第二章:CSS基础进阶-part1:CSS高级选择器

文章目录 一、 组合选择器二、属性选择器三、伪类选择器1、动态伪类选择器2、状态伪类选择器3、结构性伪类选择器4、否定伪类选择器 一、 组合选择器 后代选择器&#xff1a;E F子元素选择器&#xff1a; E>F相邻兄弟选择器&#xff1a;EF群组选择器&#xff1a;多个选择器…

电脑提示数据错误循环冗余检查怎么办?

有些时候&#xff0c;我们尝试在磁盘上创建分区或清理硬盘时&#xff0c;还可能会遇到这个问题&#xff1a;数据错误循环冗余检查。这是如何导致的呢&#xff1f;我们又该如何解决这个问题呢&#xff1f;下面我们就来了解一下。 导致冗余检查错误的原因有哪些&#xff1f; 数据…

Vue3 setup tsx 子组件向父组件传值 emit

需求&#xff1a;Vue3 setup 父组件向子组件传值&#xff0c;子组件接收父组件传入的值&#xff1b;子组件向父组件传值&#xff0c;父组件接收的子组件传递的值。 父组件&#xff1a;parent.tsx&#xff1a; import { defineComponent, ref, reactive } from vue; import To…

什么是DNS欺骗及如何进行DNS欺骗

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、什么是 DNS 欺骗&#xff1f;二、开始1.配置2.Ettercap启动3.操作 总结 前言 我已经离开了一段时间&#xff0c;我现在回来了&#xff0c;我终于在做一个教…

GloVe、子词嵌入、BPE字节对编码、BERT相关知识(第十四次组会)

GloVe、子词嵌入、BPE字节对编码、BERT相关知识(第十四次组会) Glove子词嵌入上游、下游任务监督学习、无监督学习BERTGlove 子词嵌入 上游、下游任务 监督学习、无监督学习 BERT

一生一芯3——ubuntu下显示器扩展

刚进ubuntu时不知道如何完成屏幕扩展&#xff0c;查阅后发现是显卡驱动问题&#xff0c;这里需要调整内置显示器的驱动 打开附加驱动 选择显卡驱动如上&#xff08;其他没试过&#xff09; 应用更改 -> 下载后重启 重启完成后扩展显示器上就有显示了 在设置中调整显示屏顺…

Go http.Handle和http.HandleFunc的路由问题

Golang的net/http包提供了原生的http服务&#xff0c;其中http.Handle和http.HandleFunc是两个重要的路由函数。 1. 函数介绍 http.HandleFunc和http.Handle的函数原型如下&#xff0c;其中DefaultServeMux是http包提供的一个默认的路由选择器。 func HandleFunc(pattern st…

【Java】2021 RoboCom 机器人开发者大赛-高职组(复赛)题解

7-8 人工智能打招呼 号称具有人工智能的机器人&#xff0c;至少应该能分辨出新人和老朋友&#xff0c;所以打招呼的时候应该能有所区别。本题就请你为这个人工智能机器人实现这个功能&#xff1a;当它遇到陌生人的时候&#xff0c;会说&#xff1a;“Hello X, how are you?”其…

【Oracle 数据库 SQL 语句 】积累1

Oracle 数据库 SQL 语句 1、分组之后再合计2、显示不为空的值 1、分组之后再合计 关键字&#xff1a; grouping sets &#xff08;&#xff08;分组字段1&#xff0c;分组字段2&#xff09;&#xff0c;&#xff08;&#xff09;&#xff09; select sylbdm ,count(sylbmc) a…

动态规划之斐波拉契数列模型

斐波拉契数列模型 1. 第 N 个泰波那契数2. 三步问题&#xff08;easy&#xff09;3. 使⽤最⼩花费爬楼梯&#xff08;easy&#xff09;4. 解码⽅法&#xff08;medium&#xff09; 动态规划的介绍&#xff1a; 动态规划是一种在数学、管理科学、计算机科学、经济学和生物信息学…

Redis之缓存雪崩、缓存击穿、缓存穿透问题

文章目录 前言一、缓存雪崩1.1、原因分析2.2、常用解决方案 二、缓存击穿2.1、原因分析2.2、常用解决方案2.2.1、使用互斥锁2.2.2、逻辑过期方案2.3、方案对比 三、缓存穿透3.1、原因分析3.2、解决方案3.2.1、缓存空对象3.2.3、布隆过滤3.3、方案对比 总结 前言 本文谈谈Redis…

基于DBN的伪测量配电网状态估计,DBN的详细原理

目录 背影 DBN神经网络的原理 DBN神经网络的定义 受限玻尔兹曼机(RBM) DBN的伪测量配电网状态估计 基本结构 主要参数 数据 MATALB代码 结果图 展望 背影 DBN是一种深度学习神经网络,拥有提取特征,非监督学习的能力,是一种非常好的分类算法,本文将DBN算法伪测量配电网…

Photoshop多图片与多窗口下排列操作方法

首先&#xff0c;在Photoshop中打开6张图片&#xff0c;在“窗口”菜单下切换窗口排列状态&#xff1a; 在 “窗口”菜单下对窗口进行排列&#xff0c;分别呈现如下&#xff1a; &#xff08;一&#xff09;. 点击“窗口” -> “排列”->"全部垂直拼贴": &am…

去掉数组中头部和尾部的0numpy.trim_zeros()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 去掉数组中头部和尾部的0 numpy.trim_zeros() 选择题 以下说法错误的是? import numpy as np anp.array([0,0,1,2,3,4,0,0]) print("【显示】a:");print(a) print("【执行1】p…

Intellij IDEA SBT依赖分析插件

可分析模块和传递依赖 安装完插件后&#xff0c;由于IDEA BUG&#xff0c;会出现两个分析按钮&#xff0c;一个是gradle的&#xff0c;一般是后者是新安装的sbt。 选择需要分析的模块 只需要在project/plugins.sbt中添加代码&#xff0c;启动官方分析插件addDependencyTreeP…

【前端 | CSS】align-items与align-content的区别

align-items 描述 CSS align-items 属性将所有直接子节点上的 align-self 值设置为一个组。align-self 属性设置项目在其包含块中在交叉轴方向上的对齐方式 align-items是针对每一个子项起作用&#xff0c;它的基本单位是每一个子项&#xff0c;在所有情况下都有效果&…

postman入门基础 —— 接口测试流程

一、编写接口测试计划 接口测试计划和功能测试计划目标一致&#xff0c;都是为了确认需求、确定测试环境、确定测试方法&#xff0c;为设计测试用例做准备&#xff0c;初步制定接口测试进度方案。一般来说&#xff0c;接口测试计划包括概述、测试资源、测试功能、测试重点、测试…