前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >geotrellis使用(四十)优雅的处理请求超过最大层级数据

geotrellis使用(四十)优雅的处理请求超过最大层级数据

作者头像
魏守峰
发布于 2018-05-02 02:04:43
发布于 2018-05-02 02:04:43
87700
代码可运行
举报
文章被收录于专栏:点滴积累点滴积累
运行总次数:0
代码可运行

前言

要说清楚这个题目对我来说可能都不是一件简单的事情,我简单尝试。

研究 GIS 的人应该都清楚在 GIS 中最常用的技术是瓦片技术,无论是传统的栅格瓦片还是比较新颖的矢量瓦片,一旦将数据切好瓦片就会造成其层级固定,假如说 0 - 11 级,请求此层级范围内数据的时候能够正常响应,但是当用户请求超过最高级(假如为 12 )的时候该如何处理呢?传统方式只能返回 404 ,即显示空白数据,然而有没有更好的方式呢,能够使得用户在请求超过最高级数据的时候能够优雅的并且正确的返回数据而不是直接 404。这个问题可以用手动挡汽车和自动挡汽车进行类比,传统方式就像手动挡,最大只能到 5 档,而现在的需求是希望挡位能变的更高些。但愿我已经清晰的说明了此问题,本文对此原理和实现方案进行简单探讨。

一、实现

1.1 原理分析

这个解决方案倒是很容易想象,当超过最大层级(以下简称 zoom)的时候(> 11 级)我们只需要读出最大 zoom(11 级)的此范围内数据对应的瓦片,然后将此瓦片根据此范围进行切割并重新采样到 256 * 256 即可。

这里面涉及到了瓦片的金字塔体系的一些常用概念。首先层级越大表示分辨率越高,即显示出来的数据越清晰,每提高一层数据量增加4倍,即一个低层级的瓦片包含了比他高一层级的四个瓦片,整个看下来便像一个金字塔一样;而常用的每个瓦片的大小为 256 * 256,直白的说就是一个 256 * 256 的 PNG 或者 JPG 图片,当然也可以是其他尺寸,每个瓦片对应一个 x、y、z 编号,x、y 代表瓦片的行列号,z 代表瓦片的 zoom,屏幕范围内数据所有瓦片按照 x、y、z 正常排列显示出来便得到了整个地图(或者其他数据,如遥感等),就像房顶的瓦片一样,所以称为瓦片技术。有关具体技术和描述可以百度之。

1.2 实现方案

有了上面的分析,其实这件事情应该已经不困难了。

1.2.1 层级

首先获取当前数据的最大层级并判断当前请求是否大于此层级。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def getMaxZoom(layerName: String) =
    attributeStore.layerIds
      .groupBy(_.name)(layerName)
      .map(_.zoom)
      .max
      
def exist(layerId: LayerId) = 
    attributeStore.layerExists(layerId)

第一个函数取到当前 layerName 数据的最大层级,其中 attributeStore 为你当前 backend 的后台,可以参考此前文章。

exist 函数判断当前 layerId 是否存在, layerId 包含 name 信息和 zoom 信息。当然此处你可以直接判断此 layerId 的 zoom 是否大于第一个函数取到的 maxZoom,但是此处我这么写也是埋下一个伏笔,会在后文介绍。

1.2.2 取到请求瓦片的范围

想要取到最大层的数据首先要取到瓦片包含数据的范围,这个范围我们只能根据所请求瓦片的 z、y、z 获得,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
val layerId: LayerId = LayerId(name, maxZoom)
val rmd = attributeStore.read[TileLayerMetadata[SpatialKey]](layerId, Fields.metadata)
val layoutLevel = ZoomedLayoutScheme(rmd.crs).levelForZoom(rmd.extent, z)
val mapTransform = MapKeyTransform(rmd.crs, layoutLevel.layout.layoutCols, layoutLevel.layout.layoutRows)
val targetExtent = mapTransform(x, y)

首先取到 maxZoom 层的元数据,根据投影(rmd.crs)、范围(rmd.extent)及 zoom 信息,获取到当前 z 层的 layout,这个具体细节涉及到金字塔理论,大意是根据投影、范围和层级就可以取到瓦片的编号和范围情况,最终也正是根据 x、y 计算出瓦片数据范围 targetExtent。

1.2.3 取到最大层级对应瓦片

有了瓦片的范围,我们就可以在最大曾中取出此瓦片,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
val GridBounds(nx, ny, _, _) = rmd.mapTransform(targetExtent)
val sourceExtent = rmd.mapTransform(nx, ny)
val maxZoomTile = tileReader.reader[SpatialKey, Tile](layerId).read(SpatialKey(nx, ny))

tileReader 是 ValueReader 对象,同样与所采用的 backend 有关。其中 nx、ny 正是 maxZoom 层对应的瓦片编号,此处同样用到金字塔理论,高层级的瓦片必然包含在比他层级低的某一个瓦片里,即 sourceExtent 必然能够完全覆盖 targetExtent。

1.2.4 将瓦片重采样到所请求的 zoom

现在只需要我们对获取到的瓦片进行裁切并重采样到 256 * 256 即可,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
val targetTile = sourceTile.resample(sourceExtent, RasterExtent(targetExtent, 256, 256))

这样就获取到了最终的请求瓦片,将此瓦片返回浏览器等其他请求源即可。

1.3 效果

展示一下最终效果:

11 级瓦片是正常取得的瓦片,12 级瓦片即为通过此种方式由 11 级瓦片重采样得到的。

二、进一步思考

做产品和做项目有着本质的区别,一个项目可能只需要考虑到通用情况即可,而产品则必须考虑到方方面面,还记得我在上面留的伏笔吗,在那里我没有采用判断所请求 zoom 是否大于 maxZoom 的方式,而是直接判断 exist,这里面有个逻辑问题。假如切瓦片的时候不是每一层都有切到,必然我切了 0 - 5、7 - 11,而没有切第 6 层,那么采用这种方式肯定是有问题的,并且出现这种情况的时候整个逻辑都需要重新修改,因为第 6 层的某个瓦片肯定包含了2 ^ (2 ^ 5) 个 11 层(maxZoom)的瓦片,这样我们就不能简单的只取出一个,而应该将其全部取出并进行拼接然后再重采样。

再进一步思考,碰到这种方式的时候我们是不是可以取出第 5 层或者第 7 层的某个/些瓦片而不是非要 maxZoom 层的,因为接近的层数据更相似(此处牵扯到层级可视化表达的问题)。

所以这些都需要我们丰富和设计好逻辑,只有这些都考虑清楚才能设计出完美的产品。具体代码此处就不放出了,如果有需要可以探讨。

三、总结

本文介绍了如何在所请求的瓦片层级不存在的情况时通过取出最大层或者相近层的瓦片并进行重采样操作,从而优雅的返回瓦片数据。

Geotrellis系列文章链接地址http://www.cnblogs.com/shoufengwei/p/5619419.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-04-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
动态加载JS 和 CSS
<script type="text/javascript"> $(function () { var filename = '/assets/css/main.css'; var fileref = document.createElement("link"); fileref.setAttribute("rel", "stylesheet"); fileref.setAttribute("type", "text/css"); fileref.setAttribute("href", filename)
逸鹏
2018/04/10
30.1K0
js实用方法记录-js动态加载css、js脚本文件
方法测试:openApp('ios页面','**.apk','metools://home');
易墨
2018/09/14
17.8K0
JavaScript DOM基础
DOM(Document Object Model)即文档对象模型,针对HTML和XML文档的API(应用程序接口)。 一.DOM介绍 DOM中的三个字母,D(文档)可以理解为整个Web加载的网页文档;O(对象)可以理解为类似window对象之类的东西,可以调用属性和方法,这里我们说的是document对象;M(模型)可以理解为网页文档的树型结构。 DOM有三个等级,分别是DOM1、DOM2、DOM3,并且DOM1在1998年10月成为W3C标准。DOM1所支持的浏览器包括IE6+、Firefox、Safa
汤高
2018/01/11
1.4K0
前端JS判断远程文件是否加载
每次在开发项目的时候为方便快捷开发,前端一般都直接使用CDN进行远程文件调用省却多级目录的问题。但这样一般都埋下了潜在的问题,就是怎么知道该远程文件是否已经加载的呢?
谭广健
2020/12/01
14.4K0
js面试题(二)
世间万物皆对象
2024/03/20
1050
用JavaScript来加载css、js文件
友儿
2023/10/21
2820
原生JS动态添加、删除元素&内容
创建元素 createElement ,创建内容 createTextNode ,添加元素 appendChild
德顺
2019/11/13
27.5K0
JS-DOM 综合练习-动态添加删除班级成绩表
费了2个小时,才把原理弄懂,把问题逐个解决,当你发现你最后栽的那个点,是一个小石头拌的你,你起来是该哭还是该笑呢?只怪自己习武不精吧。 虽然问题都解决了,但是还有一个余留的问题就是鼠标经过input时,怎么修改背景颜色的问题。 这一节有点乱,虽然整理的代码编了问题序号。可我相信,再过几天自己回头看肯定还是一头雾水。 so,附上具体问题网址:http://www.imooc.com/code/1636 以下是html整件 <!DOCTYPE html> <html> <head> <meta chars
xing.org1^
2018/05/17
3.7K0
JavaWeb——JavaScript精讲之DOM、BOM对象与案例实战(动态添加删除表格)
上一博文种讲解了JavaScript基础的ECMAScript,包括基本语法和部分对象,本文中继续讲解JavaScript中比较重要的两部分内容BOM、DOM及事件,后文中有对应的实战练习。
Winter_world
2020/09/25
2.2K0
JavaWeb——JavaScript精讲之DOM、BOM对象与案例实战(动态添加删除表格)
Mirages短代码使用
支持 m3u8、mp4,flv 和 mkv 格式,不过编码必须是 H.264 AAC
ZGGSONG
2022/09/09
2.4K0
Mirages短代码使用
常用js,css文件统一加载方法,并在加载之后调用回调函数
为了方便资源管理和提升工作效率,常用的js和css文件的加载应该放在一个统一文件里面完成,也方便后续的资源维护。所以我用js写了以下方法,存放在“sourceController.js”文件内。 /** * Created by MingChen on 2016/11/3. */ function sourceController() { this.root = ""; this.callfunc = null; // 回调函数 this.css = []; thi
就只是小茗
2018/03/07
3.5K0
JS魔法堂:LINK元素深入详解
一、前言                               我们一般使用方式为 <link type="text/css" rel="stylesheet" href="text.css"> 来引入外部层叠式样式文件,但LINK元素各属性的具体含义、资源加载行为等方面却了解不多,本文打算稍微深入一下。   由于内容较多,特设目录一坨: 二、到底有没有结束标签? 三、普通属性介绍 四、属性disabled详解 1. Attribute和Property的disabled 2. dis
^_^肥仔John
2018/01/18
3.3K0
JS魔法堂:LINK元素深入详解
【兼容性】js 浏览器兼容问题处理方式
document.getElementById(“header”).style.styleFloat = “left”;
前端修罗场
2023/10/07
3500
JavaScript图片库
将图片放到网上的方法有很多,你可以简单地把所有的图片都放到网页上。但是,如果你打算发布的图片过多,这个页面很快会变的过于庞大,而且加上这些图片后用户要下载的的数据量就会变得相当可观。我们必须面对这样一个现实:没有人会等待很长长时间去下载一个网页;所以利用JavaScript来创建一个图片库将是最佳的选择; 说下步骤: 第一步:把整个图片库的链接都加载到图片库的主页里; 第二步:当用户点击对应的超链接时,拦截网页的默认行为,即(超链接点击跳转行为); 第三步:当用户点击对应的超链接后,把"占位符"图片替换成那
郑小超.
2018/01/24
3.7K0
javaScript动态添加Li元素「建议收藏」
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/152096.html原文链接:https://javaforall.cn
全栈程序员站长
2022/06/25
2.2K0
使用DOM动态创建标签
本文是参考《javascript Dom 编程艺术》第八章的内容所写,用到的知识点,就是关于创建平稳的web页面。 使用DOM方法:   getElementById()   getElementsByTagName()   getAttribute() setAttribute()   createElement()   createTextNode()   appendChild()   首先网页只是一段简单的html,含有部分复杂的标签。   <abbr>用于缩写,<blockqu
用户1154259
2018/01/17
1.8K0
使用DOM动态创建标签
微信刷屏的「给我一面国旗」如果要做到,技术原理是什么?
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
养码场
2019/09/26
7480
微信刷屏的「给我一面国旗」如果要做到,技术原理是什么?
DOM
DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口)。DOM描绘了一个层次变化的节点树,允许开发人员添加、移除和修改页面的某一部分。
奋飛
2019/08/15
1.5K0
Js DOM
要创建新的 HTML 元素 (节点)需要先创建一个元素,然后在已存在的元素中添加它。
hss
2022/02/25
3.7K0
第三方Javascript开发系列之投放代码
本文先从第三方Javascript脚本的重要组成部分“投放代码”讲起。先从一个最例子看起:Google Analytics(以下简称GA),是Google提供的用于网站监测等一系列功能的服务。网站开发者将GA提供的投放代码放到自己网站上需要监测的页面(一般是全站添加)。
mmzhou
2018/08/06
9900
第三方Javascript开发系列之投放代码
相关推荐
动态加载JS 和 CSS
更多 >
LV.1
软件开发Java后端
目录
  • 前言
  • 一、实现
    • 1.1 原理分析
    • 1.2 实现方案
      • 1.2.1 层级
      • 1.2.2 取到请求瓦片的范围
      • 1.2.3 取到最大层级对应瓦片
      • 1.2.4 将瓦片重采样到所请求的 zoom
    • 1.3 效果
  • 二、进一步思考
  • 三、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文