深入浅出学习切片LOD——ArcGIS server模拟缓存切片(影像快显)

一、第一次实践

原理

        免切片实现影像服务的模拟切片,主要原理是接收前端传过来的xyz(行列层级)以及切片方案,计算出该请求的切片的四至经纬度信息,通过mapserver的exportImage接口,传入每个模拟切片的四至经纬度信息得到图片返回。好似前端请求了http://xxx/mapserver/z/y/x,后台返回给前端一张图片(切片),让客户端无感知的就像是请求了缓存切片。

        而这问题的关键在于获取目标图片的四至经纬度信息。怎么计算?

        首先,咱们需要知道细节层次模型LOD。LOD技术即Levels of Detail的简称,意为多细节层次(百度解释的描述会越描越黑)。实际上就是世界地图展示的时候想看某个细节,那么就需要缩放(因为屏幕大小不会变),但缩放不能直接把整个图缩放,数据细节太大,放不下。那只需要把感兴趣的细节部分数据返回给客户拼接到一起,查看不同级别就返回不同级别的图片。

        这里模拟切片,第0级是一张图片,经度从-180到180,纬度从-90到90。流行方式是以左上角(-180,90)为坐标原点(origin),计算每个片的最小经纬度,最大经纬度(xmin,ymin,xmax,ymax)。

         如计算第1级的四张瓦片中的右上角,直观答案是经度0到180,纬度0到90。这个数据从公式中如何计算得来呢?如上图中x,y的计算方式:最小经度xmin(0)= 原点的经度(-180)+偏移量(偏移的瓦片数量(1)*第一级瓦片宽度(以角度为单位,也就是180)),这样就可以算出每个瓦片的最小最大经纬度。

        上图中用的resolution*256是什么意思,这是为了理解常说的切片方案中的参数,其中256是一张瓦片的宽度(256px像素),经过反算得出来的参数结果与天地图常用的切片方案一致。0级的resolution是0.703125,每个层级的resolution是上一层级的½。

lodinfos: [
          { 'level': 0, 'resolution': 0.703125, 'scale': 295497598.570834 },
          { 'level': 1, 'resolution': 0.3515625, 'scale': 147748799.285417 },
          { 'level': 2, 'resolution': 0.17578125, 'scale': 73874399.6427087 },
          { 'level': 3, 'resolution': 0.087890625, 'scale': 36937199.8213544 },
          { 'level': 4, 'resolution': 0.0439453125, 'scale': 18468599.9106772 },
          { 'level': 5, 'resolution': 0.02197265625, 'scale': 9234299.95533859 },
          { 'level': 6, 'resolution': 0.010986328125, 'scale': 4617149.97766929 },...
        ]

获得了这些参数信息,再输入/z/y/x,我们就获得了层级/行/列,通过公式便可计算出图片四至。这里有第一个坑,每个正方形瓦片的经度和纬度的边长是不一样的,宽(经度)是长(纬度)的两倍,可以结合第0级正方形理解,经度总共是360度,纬度总共是180度。

var lt_x = -180 + col * lodinfos[level].resolution * tilecols;
var lt_y = 90 - row * lodinfos[level].resolution * tilerows / 2;
var rb_x = -180  + (col + 1) * lodinfos[level].resolution * tilecols;
var rb_y = 90 - (row + 1) * lodinfos[level].resolution * tilerows / 2;

貌似大功告成,写了个本地服务测试两个切片结果,拉出来检验一下:用ArcGIS的切片服务看看

https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/2/1/2

         两个图片的最小经度和最大经度值是一样的,但纬度差异很大。一开始我以为是公式错误,或者切片方案的问题,实际上这里是投影的问题。从一开始我的计算方案就是以地理坐标的经纬度计算的,瓦片切分下来就是正轴墨卡托投影,而ArcGIS server使用的是横轴墨卡托投影(关于投影可以看看这个一文了解地图投影 - 知乎),所以两者并不对等,当细节级别更高时两者的结果就相差十万八千里了。

二、第二次实践

思路

        既然知道了原因,那么我们可以直接计算投影坐标下的四至,而不是经纬度四至。需要先获取0级的四至,即全球基准四至,然后每一级都可以通过上一级二分来计算。这里的基准四至可以从切片方案中获取也可以从ArcGIS服务中获取

      let deltX = (xmax -xmin)/Math.pow(2,level); //level级别的瓦片宽度 0级一张图,1级两张图
      let deltY = (ymax -ymin)/Math.pow(2,level); //level级别的瓦片高度 0级一张图,1级两张图
      let lt_x = xmin + col * deltX ;
      let lt_y = ymax - row * deltY ;
      let rb_x = xmin + (col + 1) * deltX ;
      let rb_y = ymax - (row + 1) * deltY ;

再拉出来看看结果

        怎么回事???为什么还是不一样???

        原来是取错数值了,我取原图的四至的时候使用了initial extent计算的,这个范围是超出了图本身的范围full extent,所以在计算的时候有偏差(initial不是正方形也有影响)。

        更新使用fullextent参数试试12层级的图片,大体上接近了,还有少许经度差异,可以再深入研究研究。

三、最终实践

正解

        第二次实践是自作聪明了。因为切片方案定义的就是以原点为起点,加偏移量去计算值。使用二分法必然不符合他原始的切片(尽管上面看起来只有微小差距,到了13级也是天差万别...)规则,纯属搞笑**行为。老老实实使用原点+切片方案计算偏移:

      const resolution = 156543.03392800014; //0级resolution(一张图)
      const originX = -2.0037508342787E7;
      const originY = 2.0037508342787E7;
      const delta = resolution*256/Math.pow(2,level);
      let lt_x = originX + col * delta ;
      let lt_y = originY - row * delta ;
      let rb_x = originX + (col + 1) * delta ;
      let rb_y = originY - (row + 1) * delta ;

检验:

鸣金收兵!

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

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

相关文章

nginxWebUI配置conf

在左边相应位置写入要修改的语句后,依次点击“校验文件”、“替换文件”、“重新装载”即可重启conf

柴油发电机负载原理是怎样的

柴油发电机负载原理是指当发电机在运行过程中,通过外部负载设备(如电动机、照明设备等)从发电机输出电能,从而使发电机内部的转子产生旋转磁场,进而驱动发电机的定子绕组产生交流电压的过程。这个过程涉及到发电机的工…

Leetcode - 128双周赛

目录 一,3110. 字符串的分数 二,3111. 覆盖所有点的最少矩形数目 三,3112. 访问消失节点的最少时间​编辑 写法一:朴素 Dijkstra(适用于稠密图,即边比较多的图) 写法二:堆优化 …

海思Hi3519 DV500 部署yolov5并加速优化

本项目代码已开源,见文末 导出onnx模型 yolov5官方地址 利用官方命令导出python export.py --weights yolov5n.pt --include onnx 或者自写代码导出 import os import sys os.chdir(sys.path[0]) import onnx import torch sys.path.append(..) from models.co…

Maui 显示当前时间

1、MainPage.xaml.cs 代码 using System.Threading;namespace Mauitime {public partial class MainPage : ContentPage{private Timer _timer;public MainPage(){InitializeComponent();_timer new Timer(_ > UpdateCurrentTime(), null, 0, 1000);}// 在页面显示时更新当…

CMC学习系列 (10):CMC计算方法介绍

CMC计算方法介绍 0. 引言1. 主要贡献2. 方法2.1 普通CMC2.2 小波CMC2.3 其余方法2.4 预处理增强型CMC 3. 总结欢迎来稿 论文地址:https://www.frontiersin.org/articles/10.3389/fnhum.2019.00100/full 论文题目:Corticomuscular Coherence and Its Appl…

基于springboot的高校教师教学质量评价系统

基于springboot的高校教师教学质量评价系统 前言 随着社会的发展,高校教师教学质量评价系统的管理形势越来越严峻。越来越多的用户利用互联网获得信息,但高校教师教学质量评价系统信息鱼龙混杂,信息真假难以辨别。为了方便用户更好的获得高…

2.SG90舵机模块

当我们输出一段脉冲信号的时候就可以调节舵机的角度 我们可以从原理图可以看到舵机的脚在PA6 从芯片手册我们又可以看到PA6对应TIM3_CH1,并且不用开启部分重映像就能使用 新建Servo.c存放PWM初始化 配置PWM void Servo_TIM3_Init(u16 arr,u16 psc) {//开启TIM3的时钟RCC_APB1…

Docker部署SpringBoot服务(Jar包映射部署)

介绍 项目在docker部署运行以后,每次需更新jar包时,都得重新制作镜像,再重新制作容器。流程及其繁琐,效率极低。 以下步骤是在不更新镜像和容器的前提下,直接更新jar完成项目更新的操作。 不重新制作镜像部署 1. 创…

基于单片机的智能模拟路灯控制系统

摘 要: 随着电力资源的紧缺,以及光污染和雾霾天气的影响,更智能化的路灯设计对人们的日常生活意义重大。本文的智能路灯控制系统是基于单片机的控制器,通过介绍该系统相应的硬件设计和软件设计,实现定时开关和依具体情况是否需要来开关路灯和进行亮度调节,并且具有自检功能…

CESS 受邀出席香港Web3.0标准化协会第一次理事会议,共商行业未来

2024 年 4 月 5 日,CESS(Cumulus Encrypted Storage System)作为香港 Web3.0 标准化协会的副理事会成员,于香港出席了 2024 年度第一次理事会会议。此次会议汇聚了来自不同领域的知名企业和专家(参会代表名单见文末&am…

PaddleOCR训练自己模型(1)----数据准备

一、下载地址: PaddleOCR开源代码(下载的是2.6RC版本的,可以根据自己需求下载) 具体环境安装就不详细介绍了, 挺简单的,也挺多教程的。 二、数据集准备及制作 (1)下载完代码及配置…

实时气象水文监测站

TH-SW4随着科技的飞速发展和人类对环境保护意识的日益增强,实时气象水文监测站在水库环境管理中的作用日益凸显。这种在线监测技术不仅为水库的安全运行提供了坚实的技术支撑,也为环境保护和灾害预防提供了及时、准确的数据支持。 一、实时气象水文监测…

酷开科技以用户为中心,搭建强大空间赋能的酷开系统

从市场前景和竞争格局来看,现在人口红利正在消逝,中国刚需类家电消费正在进入饱和期。在目前激烈的市场竞争环境下,智能家电正在成为家居市场新宠儿。酷开科技以用户为中心,为用户搭建智能的酷开系统,具有强大的空间赋…

[C++][算法基础]求最小生成树(Prim)

给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环,边权可能为负数。 求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G(V,E),其中 V 表示图中点的集合,E 表示图…

【C++】explicit关键字详解(explicit关键字是什么? 为什么需要explicit关键字? 如何使用explicit 关键字)

目录 一、前言 二、explicit关键字是什么? 三、构造函数还具有类型转换的作用 🍎单参构造函数 ✨引出 explicit 关键字 🍍多参构造函数 ✨为什么需要explicit关键字? ✨怎么使用explicit关键字? 四、总结 五…

硕博电子经济型高性能LED面板

在科技进步的洪流中,硕博电子始终保持敏锐的洞察力与创新能力。SPM-LEDP-C12是硕博电子开发的兼具性价比与创新性能的LED面板。该产品具备1路CAN总线,12个LED指示灯(丝印字符带背光)。 不同于以往独立控制的单个指示灯&#xff…

StableDiffusion-02 LoRA上手使用实测 尝试生成图片 使用多个LoRA 调整LoRA效果 10分钟上手 多图

准备工作 请你确保,你已经完成了 StableDiffusion-01 这一节的内容,可以顺利的运行SD,并且可以正常的生成图片。 本节我们就尝试使用LoRA并生成图片。 介绍 LoRA Stable Diffusion中的LoRA(Low-Rank Adaptation,低秩…

ubuntu下的串口调试工具cutecom

系统:ubuntu20.04 (1)接线 使用 rs485<-----> rs232 转接口( 设备直接出来的是rs485),电脑主机接入一根 rs232<-----> USB口 连接线,ubuntu系统下打开 termin…

【Vue】setup语法糖的使用

文章目录 setup简介使用vite-plugin-vue-setup-extend插件 指定组件名字 setup简介 <script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖 相比较普通的<script> ,它有以下优势&#xff1a; 更少的样板内容&#xff0c;更简洁的代码。能够使用纯…