探寻电子地图背后的秘密:瓦片技术的原理与实现 您所在的位置:网站首页 瓦片设计运用什么技术 探寻电子地图背后的秘密:瓦片技术的原理与实现

探寻电子地图背后的秘密:瓦片技术的原理与实现

2024-07-17 18:00| 来源: 网络整理| 查看: 265

不知道大家是否还有电子地图出现以前出行场景的记忆?彼时的出行,对于陌生的路线,我们只能通过问人或者查看纸质地图的人肉方式推进,因此出行之前要搜集信息、查看路线做很多出行前的准备,一些报刊亭甚至还提供收费问路服务。而电子地图应用的出现,极大地方便了我们在出行导航、地址查找等方面的需求,而瓦片技术则是实现电子地图服务的重要技术之一。接下来我们将逐步探寻电子地图背后的秘密,了解地图瓦片技术的原理与实现。

image.png

地图的演变

首先让我们先来看看人类发展的过程中,地图是如何一步步从过去的纸质地图模式演进到如今的电子地图模式的。地图的历史可以大致划分为四个阶段:手工制图阶段、数字地图阶段、电子地图阶段和智能地图阶段。从1960年代开始,每个阶段都出现了一些阶段性的标志事件推动了电子地图技术不断发展。

image.png

1960年代末,美国国防部开发了第一个基于计算机的地图制作系统,称为GEOCOMP。 1970年代,美国国家地理空间情报局开始使用计算机制作地图,并开发了自己的地图数据库。 1980年代,计算机技术的进步使得地图制作变得更加高效和精确。此时,商业公司也开始涉足电子地图的制作和销售。 1990年代,互联网的普及使得电子地图应用的使用变得更加广泛。 2000年代,全球卫星定位系统(GPS)的发展使得电子地图的精确度得到了大幅提升。此时,移动设备也开始普及,使得人们可以在手机、平板或电脑上使用地图应用。 2010年代至今,人工智能、大数据等新技术的出现使得电子地图得到了更多的升级和改进。同时,室内定位技术的发展也为电子地图的应用提供了更多可能性。

简单了解完地图的主要发展阶段后,让我们把视线集中在从电子地图阶段到智能地图阶段的跃进的千禧年的时代,来看看电子地图应用发展经历了哪些难题,又是怎么逐一解决的。

瓦片地图的诞生

大概在2000年左右,互联网地图多采用CS架构(客户端/服务器架构) ,客户端安装客户端软件,服务器运行服务端程序。地图使用者需要预先在本地安装客户端软件,再下载保存矢量地图数据(点、线、面数据)的文件才能浏览使用地图,但一张包含世界地物信息的地图数据文件往往很大,想象一下千禧年代的网络环境和基建,可想而知下载文件耗时会很久,而且相关软件的操作也通常需要专业知识才可操作,在设备平台浏览地图不是一件易事。

image.png

随着互联网的发展,ajax技术逐渐兴起,也催生了通过浏览器使用地图的需求,BS架构(浏览器/服务器架构) 网页版地图服务随之流行起来。这种方式下用户可以直接通过浏览器查看地图,省去了用户安装客户端软件和下载地图数据的操作,极大地降低了使用电子地图的门槛。

image.png

在网页上浏览地图的方式已经很接近当下我们使用电子地图的形态了,那地图应用就此得到大范围的推广了吗?答案是并没有,此时的地图服务商们不得不面临两大难题:

地图数据太大,而网络传输带宽却很小,用户在浏览器端等待数据返回的时间过长,用户使用体验差 地图数据太大,即使传输到浏览器端,数据渲染时也会出现性能卡顿问题,用户使用体验差

面对这些问题,让我们来看看地图开发商们都提出过哪些主意?1999年,出现了WMS(Web Map Service)这样的解决方案:

在服务器端把地图渲染成图片,浏览器端只做文本和图片显示 地图图片大小根据浏览器视窗大小来定

虽然WMS大大推进了电子地图的发展进程, 但问题还是存在,WMS根据浏览器视窗大小每次生成一大张图片,对于后端数据渲染能力和网络传输带宽都是挑战,效率仍旧低下。紧接着就有了WMS-C(Cached) 的方案,通过缓存地图瓦片提高效率,但仍没有从根本上解决问题。

较大的地图数据给浏览器、服务器、网络带宽都带来了压力,早期的解决方案大多对硬件设备和网络环境提出了较高的要求。如果没有更好的硬件和网络环境可供选择,那是否可以从数据本身出发,尝试减小地图数据的数据量呢?比如:每次请求的地图数据量小一些,渲染速度和网络传输不就可以应付自如了吗?

最终,在工程实践方面更胜一筹的Google成为这一思想的最佳实践者,2005年Google地图发布,提出并实现了瓦片地图技术,让全球用户轻而易举的享受到了地图应用的福利。Google瓦片地图技术中采用的 墨卡托投影(Web Mecator投影)和 瓦片分级切割方案,也成为目前互联网地图事实上的标准。接下来就让我们逐步了解墨卡托投影和瓦片分级切割方案是如何让地图应用蓬勃发展起来的。

image.png

瓦片地图的原理 地图投影

说到墨卡托投影,非地图学专业的读者可能很陌生,但是要说到地图投影,大家就能稍微get到一些方向了。在地图学中,地图投影是一种将地球表面展平的方法,以便制作地图,这就需要一种方法将球面上的点转换为平面上的点。

但是将球体投影到平面上,球面必然会有一定程度的变形,打个比方:吃完橘子🍊后把橘子皮压平,肯定会产生撕裂和变形。根据地图的目的,有些变形是可以接受的,有些则是不可以接受的,因此,为了保留球面的某些性质而牺牲其他性质,就存在不同的地图投影。

image.png

五花八门的地图投影方式

一般情况下,由以下三个维度的因素影响投影坐标:

投影面:能展开成平面而不发生拉伸、撕裂或收缩的曲面称为可展曲面,如:圆柱、圆锥和平面。 投影朝向:指可展曲面相对于地球的位置,它可以是法向(曲面的对称轴与地轴重合)、横向(曲面的与地轴成直角)或斜向(两者之间的任何角度)。 切割程度:可展曲面可以是与球面相切或相割的表面。相切是指曲面与地球接触但不切开地球;相割是指曲面会切开地球。

image.png

墨卡托投影就是使用一个外切地球赤道的圆柱做正轴投影方向后得到的投影。

image.png

墨卡托投影简介

墨卡托投影,又称正轴等角圆柱投影,是一种等角的圆柱形地图投影。由荷兰地图学家墨卡托(G.Mercator)于1569年创立,他于这一年发表长202公分、宽124公分以此方式绘制的世界地图。

image.png

1111.gif

image.png

细心的同学可能会注意到一个问题,墨卡托投影会使面积产生变形,赤道地区变化最小,南北两极的变形最大,但因为在南北回归线之间影响很少,而这是多数航线所在区域,所以被广泛用来编制地图。目前百度地图、高德地图、腾讯地图和Google Maps使用的投影方法都是墨卡托投影。

image.png

投影结果 右图中红色矩形区域是真实投影结果、蓝色正方形区域是数学计算区域 右图蓝色正方形的边长是赤道周长 横轴方向,经度的变化是线性的,等比例放大 纵轴方向,纬度的变化是非线性的,赤道 地区变化最小, 南北两极 的变形最大 投影偏差

由于墨卡托投影在高纬度过分放大,低纬度又过分缩小,因此会产生有趣的投影偏差。比如:世界第一大岛高纬度的格陵兰比澳洲看起来还大好几倍,然而实际上格陵兰岛面积(216万平方公里)不足澳洲面积(769万平方公里)的三分之一。

image.png

image.png

如果使用人脸的来模拟墨卡托投影形变的程度,投影后的脸大概长这个样子😅:

image.png

好了,现在我们已经对墨卡托投影有了简单地了解了,接下来我们进一步了解谷歌地图瓦片技术的另一大绝妙方案——瓦片切割方案。

瓦片金字塔原理

在日常使用电子地图时,我们看到的是一张铺满整个屏幕的大的地图图片。还记得文章开头提到的2000年左右的互联网环境吗?当时的硬件条件和网络传输都无法满足大数据量的地图应用,如果能把这张大的地图图片裁切成多个小的地图图片,那数据的处理量就自然变小了。然后再像拼图🧩一样将小图片拼起来,就能完美地解决地图应用面临的问题了。

实际上,这就是谷歌地图瓦片切割技术方案的具体做法:将大的地图图片切割成多个尺寸相同(通常是256*256像素)的小地图图片,再按照既定规则无缝拼接成大的地图图片,这些小图片就是瓦片。

瓦片:将一定范围内的地图图片按照一定的尺寸和格式裁切成若干行和列的正方形图片,对切片后的正方形图片因为跟屋顶上按序排列的瓦片非常相似,因此它们也被形象的称为瓦片(Tile) 。

image.png

上面提到地图中的瓦片需要按瓦片按照如下图所示的金字塔结构组织,每张瓦片都可通过级别、行列号唯一标记。在平移地图、缩放地图时,浏览器根据金字塔规则,计算出所需的瓦片,从瓦片服务器获取并拼接。

image.pngimage.png

image.pngimage.png

转存失败,建议直接上传图片文件

由于瓦片是静态的图片,可预先生成,通过缓存和CDN技术,瓦片服务器可提供高效的瓦片读取服务。此外,浏览器并行获取和显示多张小图片,比获取和显示一张大图片要高效的多。显示地图变成和显示图片一样简单,这也是互联网地图能够承载亿级规模用户的原因。

瓦片分层加载体验地址👉 Tiles à la Google Maps: Coordinates, Tile Bounds and Projection | MapTiler

转存失败,建议直接上传图片文件

瓦片地图的进化 瓦片分类

瓦片技术又分为栅格瓦片和矢量瓦片。栅格瓦片就是图片切片,以图片为介质的瓦片打开了互联网地图的大门,互联网地图得以迅速普及。但是,随着地图的移动化和应用的逐渐深入,栅格瓦片至少遇到了两个问题:

图片占用带宽和存储都较大,不利于地图在移动设备的应用 图片无法交互

受网络带宽开销和存储空间的限制,栅格瓦片地图在移动端一开始就显现出先天不足。这促使在移动端,使用矢量瓦片替代栅格瓦片。矢量瓦片采用和栅格瓦片相同的分级切割方案,所不同的是,瓦片数据以矢量形式存在(为了减少客户端计算量,存储的不是坐标位置而是相对位置)。矢量瓦片体积小,可高度压缩,占用的存储空间比栅格瓦片要小上千倍。一方面减小网络带宽消耗,另一方面使地图离线成为可能。

image.png

目前在浏览器端,矢量瓦片也在逐渐成为互联网地图的主流技术。但这并不是说栅格瓦片将退出历史舞台。 互联网地图数据更新不频繁,单个瓦片内需要显示的地物数量和种类有限,矢量瓦片可预先生成,进行局部更新的代价也很小。矢量瓦片并不适合数据更新频繁,数据量大,渲染方式复杂多样的场景。

特点矢量瓦片栅格瓦片数据存储方式数据以矢量形式存储(点、线、面),每个对象有自己的几何信息和属性信息数据以像素点形式存储,每个像素点有自己的数值信息数据大小数据量相对较小,同等区域的数据文件通常比栅格数据小数据量较大,同等区域的数据文件通常比矢量数据大渲染效果渲染效果较好,可以对每个对象进行不同的渲染,并能够更好地表达地理要素的几何形态和属性信息渲染效果较差,不支持动态渲染和交互,不能直观地表达地理要素的几何形态和属性信息动态性支持动态渲染和更新,可以根据需求对数据进行编辑和更新不支持动态渲染和更新,数据通常是静态的适用范围适用于需要表达地理要素的几何形态和属性信息的场景,如:地图制图、城市规划、资源管理等适用于需要表达地理要素的数值信息的场景,如:遥感影像分析、农业监测、自然资源调查等数据更新数据更新相对容易,只需要更新对应的矢量数据即可数据更新相对困难,需要重新生成整张瓦片才能更新网络传输矢量数据较小,网络传输速度较快图片数据较大,网络传输速度较慢 瓦片服务体验

地理可视化引擎:AntV L7 地理空间数据可视化引擎

瓦片服务资源:国家地理信息公共服务平台_天地图_在线地图

瓦片图层操作:图层的添加与移除-覆盖物与图层管理-示例中心-JS API 2.0 示例 | 高德地图API

贴两张截图给大家增加一些对栅格数据和矢量数据的体感。

下图中黄色区域的边界很不规整,有些像马赛克的形状,那是因为栅格瓦片图层中的数据是arrayBuffer二进制数据,在可视化出来后全部转化成像素点了,你看到的黄色像素点数据是算法同学通过模型识别出来的玉米作物🌽,聚少成多,形成了一个个黄色片区。

image.png

下图中红色边界是规整的线条,因为矢量数据的就是由点、线、面构成,无论地图如何缩放,用户看到的都是规整的地理图像元素。

image.png

瓦片切割技术的实现

要裁剪地图瓦片,首先需要确定要裁剪的瓦片的范围。假设我们已经确定了裁剪范围的左上角坐标为 (x1, y1),右下角坐标为 (x2, y2),则可以按如下方式裁剪:

step1 遍历需要裁剪的瓦片,对于每个瓦片,获取其左上角坐标 (tileX, tileY) 和右下角坐标 (tileX + tileSize, tileY + tileSize), tileSize 是瓦片的大小(通常为 256)。 step2 判断该瓦片是否完全包含在裁剪范围内。如果是,则直接保留该瓦片;如果不是,则进行裁剪。 step3 对于需要裁剪的瓦片,计算其裁剪后在地图上的位置和大小。具体来说,对于左上角坐标为 (tileX, tileY) 的瓦片,其裁剪后在地图上的位置为: var clipX = Math.max(tileX, x1); var clipY = Math.max(tileY, y1); var clipWidth = Math.min(tileX + tileSize, x2) - clipX; var clipHeight = Math.min(tileY + tileSize, y2) - clipY; step4 创建一个新的 canvas 元素,将裁剪后的瓦片绘制到该 canvas 上。具体来说,可以使用 drawImage 方法绘制: var canvas = document.createElement('canvas'); canvas.width = clipWidth; canvas.height = clipHeight; var ctx = canvas.getContext('2d'); ctx.drawImage(tileImage, clipX - tileX, clipY - tileY, clipWidth, clipHeight, 0, 0, clipWidth, clipHeight);

其中,tileImage 是原始瓦片的 Image 对象。

step5 将裁剪后的 canvas 元素作为新的瓦片使用。

完整的代码实现如下:

function clipTiles(tiles, x1, y1, x2, y2) { var tileSize = 256; // 瓦片大小 var clippedTiles = []; for (var i = 0; i < tiles.length; i++) { var tile = tiles[i]; var tileX = tile.x * tileSize; var tileY = tile.y * tileSize; var tileImage = tile.image; if (tileX + tileSize = x2 || tileY + tileSize = y2) { // 瓦片完全在裁剪范围外,不需要裁剪 continue; } var clipX = Math.max(tileX, x1); var clipY = Math.max(tileY, y1); var clipWidth = Math.min(tileX + tileSize, x2) - clipX; var clipHeight = Math.min(tileY + tileSize, y2) - clipY; var canvas = document.createElement('canvas'); canvas.width = clipWidth; canvas.height = clipHeight; var ctx = canvas.getContext('2d'); ctx.drawImage(tileImage, clipX - tileX, clipY - tileY, clipWidth, clipHeight, 0, 0, clipWidth, clipHeight); clippedTiles.push({ x: Math.floor(clipX / tileSize), y: Math.floor(clipY / tileSize), image: canvas }); } return clippedTiles; }

其中,tiles 是原始的瓦片数组,每个元素包含 x、y 和 image 三个属性,分别表示瓦片在地图上的横向和纵向索引以及瓦片的 Image 对象。函数返回裁剪后的瓦片数组,格式与原始瓦片数组相同。

图片裁剪瓦片体验 GitHub - lvisei/image2tiles tiff瓦片切割 GitHub - lzxue/raster2tiles: 栅格切片工具 延伸阅读 L7 2.9: 炫酷的瓦片数据可视化 · 语雀


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有