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

news2024/11/23 11:17:55

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 显示等级设置

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

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

相关文章

JS图表库LightningChart JS全新发布v4.2——新增多种雷达图表类型

LightningChartJS是Web上性能最高的图表库具有出色的执行性能 - 使用高数据速率同时监控数十个数据源。 GPU加速和WebGL渲染确保您的设备的图形处理器得到有效利用&#xff0c;从而实现高刷新率和流畅的动画。用于贸易&#xff0c;工程&#xff0c;航空航天&#xff0c;医药和其…

随机过程的2个例题探讨

&#xff08;一&#xff09;马氏过程和泊松过程、维纳过程的联系 泊松过程、维纳过程两者都是独立增量过程。独立增量过程是马氏过程的条件&#xff1a; 1. 随机过程是独立增量过程 2. X&#xff08;0&#xff09; 0 满足以上两个条件的随机过程都是马氏过程。 注意&#xff1…

C/C++test两步完成CMake项目静态分析

您可能一直在静态分析中使用CMake。但您是否尝试过将Parasoft C/Ctest与CMake一起使用吗&#xff1f;以下是如何使用C/Ctest在基于CMake的项目中运行静态分析的详细说明。 CMake是用于构建、测试和打包软件的最流行的工具之一。Parasoft C/Ctest通过简化构建管理过程&#xff…

Vue常用属性(计算属性和侦听器属性)

目录 计算属性computed 名称例子&#xff1a; 浏览器实现&#xff1a; 性和名输入&#xff1a; 只读输入&#xff1a; 读写输入&#xff1a; 侦听器属性watch 练习例子: 浏览器实现&#xff1a; 属性侦听&#xff1a; 对象侦听&#xff1a; 对象中的属性侦听&#xf…

基于STM32CUBEMX驱动TMOS模块STHS34PF80(2)----驱动STHS34PF80进行人体检测

基于STM32CUBEMX驱动TMOS模块STHS34PF80----2.驱动STHS34PF80进行人体检测 概述样品申请视频教程参考Demo引导温度测量滤波方式智能识别算法使用块数据更新&#xff08;BDU&#xff09;功能设置ODR速率状态寄存器main.c 概述 STHS34PF80 是一款非冷却、工厂校准的红外运动和存…

Java:异常处理:捕获异常,记录异常并响应合话的信息给用户;捕获异常,尝试重新修复

异常处理 1、埔获异常&#xff0c;记录异常并响应合话的信息给用户 public static void main(String[ ] args){ try {test1(); }catch (FileNotFoundException e) {system.out.println("您要找的文件不存在!! ");e.printstackTrace();//打印出这个异常对象的信息。记…

如何运用小程序技术闭环运营链路?

如何通过线上小程序获取用户线索&#xff0c;提高企业抗风险能力&#xff0c;建立有效的营销数字化系统一直是困扰每一个小程序开发者与运营者的问题。 当我们选择使用小程序设计自己的运营流程时&#xff0c;从「推广」到「转化」&#xff0c;再到最终的「留存」都是运营过程…

Grafana Loki

Loki是 Grafana Labs 团队最新的开源项目&#xff0c;是一个水平可扩展&#xff0c;高可用性&#xff0c;多租户的日志聚合系统。它的设计非常经济高效且易于操作&#xff0c;因为它不会为日志内容编制索引&#xff0c;而是为每个日志流编制一组标签。项目受 Prometheus 启发&a…

可组装的模块化开源掌机GameShell,组装起了万千极客的童年

对于热衷于复古游戏及开源掌机的极客玩家来说&#xff0c;开源硬件的普及&#xff0c;让更多极客可以有机会体验到亲手DIY掌机的乐趣&#xff0c;属于开源掌机的圈子也由此应运而生。 由一群复古游戏爱好者组成的Clockwork团队希望更进一步拓展开源掌机的拓展性和自定义性&…

AEM网络助手NSA升级更新-版本大更新

关注过或者使用AEM线缆认证测试的朋友&#xff0c;对于这款8类线认证测试仪不会陌生。 3.0-4.0是一个重大的版本变更&#xff0c;下面我们重点看看那些部分做了升级改动。 1&#xff0c;操作主界面部分&#xff0c;最大的变化的是&#xff0c;颜色对比度大为改动。界面更加协…

rabbitmq的消息应答

消费者完成一个任务可能需要一段时间&#xff0c;如果其中一个消费者处理一个长的任务并仅只完成 了部分突然它挂掉了&#xff0c;会发生什么情况。RabbitMQ 一旦向消费者传递了一条消息&#xff0c;便立即将该消 息标记为删除。在这种情况下&#xff0c;突然有个消费者挂掉了…

如何保证数据库的数据和Redis的数据一致性

实际项目中有可能会使用Redis缓存数据&#xff0c;那么在更新数据的时候如何保证数据库中的数据和Redis缓存的数据一致&#xff0c;缓存同步策略的选择是一个很重要的问题。网上有各种说法&#xff0c;大概总结有以下几种&#xff0c;看看每种方案是否可行以及存在的问题和适用…

思维导图模板下载网站有哪些?这6个网站优质模板任你选!

信息时代&#xff0c;有效的信息组织和知识管理变得尤其重要。思维导图&#xff0c;作为一种强大的视觉化工具&#xff0c;可以帮助我们整理和理解复杂的信息&#xff0c;提高工作和学习效率。 好的思维导图模板能帮助我们拓展思路、提升美观度、更快地完成思维导图的绘制。今…

【小梦C嘎嘎——启航篇】string介绍以及日常使用的接口演示

【小梦C嘎嘎——启航篇】string 使用&#x1f60e; 前言&#x1f64c;C语言中的字符串标准库中的string类string 比较常使用的接口对上述函数和其他函数的测试代码演示&#xff1a; 总结撒花&#x1f49e; &#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右…

好用的安卓手机投屏到mac分享

工具推荐&#xff1a;scrcpy github地址&#xff1a;https://github.com/Genymobile/scrcpy/tree/master mac使用方式 安装环境&#xff0c;打开terminal&#xff0c;执行以下命令&#xff0c;没有brew的先安装brew brew install scrcpy brew install android-platform-too…

Mybatis 源码 ① :开篇

文章目录 一、前言二、项目搭建三、自动装配四、总结 一、前言 Mybatis 官网 以及 本系列文章地址&#xff1a; Mybatis 源码 ① &#xff1a;开篇Mybatis 源码 ② &#xff1a;流程分析Mybatis 源码 ③ &#xff1a;SqlSessionMybatis 源码 ④ &#xff1a;TypeHandlerMybat…

ubuntu1804系统ROS1和ROS2一键装机

备忘一下ROS1和ROS2的一键装机 原网址:小鱼的一键安装系列 指令: wget http://fishros.com/install -O fishros && . fishros如果想同时安装ROS1和ROS2, 运行两次. fishros, 工具会自动将ROS1和ROS2放在不同的文件目录下 安装完每次打开终端时, 会提示选择ROS1还是RO…

【Linux】应用层协议

【Linux】应用层协议 文章目录 【Linux】应用层协议1、协议作用1.1 应用层需求1.2 协议分类 2、HTTP & HTTPS2.1 HTTP/HTTPS 简介2.2 HTTP工作原理2.3 HTTPS工作原理2.4 区别 3、URL3.1 编码解码3.2 URI & URL 4、HTTP 消息结构4.1 HTTP请求方法4.2 HTTP请求头信息 5、…

思维导图在线制作,10款好用的思维导图在线制作网站推荐!

思维导图的强大作用在于它以直观、易理解的图形方式展现信息&#xff0c;让复杂的内容变得简单明了&#xff0c;极大地提升了我们的学习和工作效率。与传统的手绘思维导图相比&#xff0c;在线思维导图制作工具更具有灵活性和实用性&#xff0c;它们提供了丰富的功能&#xff0…

00|Java中常见错误或不清楚

00. 多变量声明并初始化 同时声明同类型的多变量 String a "Hello", c "hello"; int x 5, y 5;01. 变量类型 01.0 浮点类型 默认是double类型&#xff0c;如果需要指定float类型&#xff0c;可以float f 1.0F; 01.1 类型装换 如果将大的类型转为…