矢量切片简介及前端加载

本文作者:长风几万里

标签:#矢量切片 #地图切片 #地图服务 #WebGIS #Mapmost

矢量切片简介

在WebGIS系统中,通常会预先将地图数据分层分块切片,当用户访问地图时仅返回当前比例尺下对应视口范围内的切片数据,以此加快客户端加载地图的速度。这种切片服务包括栅格切片服务和矢量切片服务两类。

视口内的地图实际是由九张地图切片组合而成,图源@长风几万里

栅格切片服务是应用较为广泛的地图数据服务,其基于四叉树金字塔结构将完整的地图数据按照不同的比例尺预先生成固定大小的切片,生成的切片通常为.jpg或.png的图片,分辨率通常为256*256。当用户浏览特定范围的地图时,栅格切片服务只需要计算出当前比例尺下视口所涉及到栅格图像的行列索引,并返回对应切片即可,与直接根据用户视口实时生成单张大图的地图服务相比,栅格切片服务既减轻了服务器的压力,也减少了每次传输的数据量,提高了用户体验,因此在很长一段时间内都是主流的地图服务。

栅格地图切片,图源@长风几万里

但栅格切片服务也存在一些缺陷。其返回的数据本身是一张图片,真正的几何要素在服务器预渲染的过程丢失了,因此在客户端想要获取几何或属性信息时又需要向后端服务再次请求。切片的样式和数据没有分离,如果需要多个样式的地图就需要生成多个对应的切片数据集。数据需要在服务端预先切分,现实地物发生变化后,服务器端重新生成切片需要时间,难以快速更新。随着用户对数据实时性、美观性以及交互性的要求越来越高,栅格地图服务逐渐难以满足用户的需要,矢量切片技术应运而生。

矢量切片与栅格切片类似,也是基于四叉树金字塔模型对地图数据切分得到的,只不过其切分的不是图片而是矢量数据本身。在切分过程中,原始的矢量数据分层分块被裁剪到对应的矩形区域内,并按照切片所在的切分层级,进行相应的抽稀简化等操作。切片通常为GeoJSON、TopoJSON或MVT三种格式,其中MVT格式的矢量切片压缩率较高、体积更小,较为常用。MVT的矢量切片在使用时通常会被编码为 Google Protobufs (PBF)格式,因此也有些矢量切片服务返回的是.pbf后缀名的数据。矢量数据被切分为切片数据集并部署在服务器端后,客户端就可以通过分别请求当前视口范围内对应的矢量瓦片、所需的标注字体、图标以及样式文件等,在客户端进行渲染输出地图。

相较于栅格瓦片服务,矢量瓦片的数据体积较小,生成速度更快,样式与数据解耦,减少了服务器端存储的数据体积,减少了预切片的时间,更有利于地图数据的快速更新。由于客户端可以直接访问到矢量数据,地图要素可以渲染的非常复杂和精细,样式可以在客户端控制,呈现的样式可以更加丰富多样,同时对要素信息的查询不需要再次请求服务器,大大提高了地图的可交互性。且矢量切片与栅格切片的切片范围可以一一对应,可以快速从矢量切片生成对应的栅格切片。可以说矢量切片结合了矢量数据的灵活性和切片地图的缓存优势,是一种更优秀的地图数据显示方式。

以pbf格式传输的矢量切片,图源@长风几万里

矢量切片的前端加载方式

Mapmost  WebGL SDK可以非常方便的在前端加载矢量切片,只需要在代码中配置好矢量瓦片对应的 样式文件即可。 以Mapmost官方的示例样式文件(https://delivery.mapmost.com/cdn/styles/sample_data.json) 为例,一个完整的矢量瓦片加载代码如下所示

<html>
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <script src='https://delivery.mapmost.com/cdn/sdk/webgl/v3.5.0/mapmost-webgl-min.js'></script>
    <style>
        body {
            margin: 0;
            padding: 0;
        }
        #map {
            width: 100%;
            height: 100%;
        }
    </style>
</head>

<body>
    <div id='map'></div>
    <script>
        const map = new mapmost.Map({
            container: 'map', // 地图容器 id
            style: 'https://delivery.mapmost.com/cdn/styles/sample_data.json', //地图样式
            center: [120.71923008473078, 31.29446443371741], // 地图中心点坐标
            zoom: 15, // 起始缩放等级
            pitch: 45, //地图俯仰角
            userId: '***', // sdk授权码 , 可在Mapmost官网申请(https://www.mapmost.com)
        });
    </script>
</body>
</html>

上述代码所做的事情非常简单,仅通过初始化一个Mapmost的地图对象,并传入一个样式文件的url即完成了矢量瓦片的加载,其最终效果如下所示。
 

通过预先配置的样式文件在前端渲染矢量瓦片,图源@长风几万里

如果服务器上并未管理有样式文件或者希望在客户端进行样式的设置,也可在前端指定图层样式。
Mapmost官方的示例数据(https://delivery.mapmost.com/cdn/mvt/sample_data/{z}/{x}/{y}.pbf)为例在前端加载部分图层并指定样式的完整代码如下所示。

<html>
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <script src='https://delivery.mapmost.com/cdn/sdk/webgl/v3.5.0/mapmost-webgl-min.js'></script>
    <style>
        body {
            margin: 0;
            padding: 0;
        }
        #map {
            width: 100%;
            height: 100%;
        }
    </style>
</head>

<body>
    <div id='map'></div>
    <script>
        const style = {
            "version": 8,
            "name": "basemap",
            "light": {
                "position": [2, 135, 45],
                "anchor": "viewport",
                "color": "rgba(250,252,255,1)",
                "intensity": 0.4
            },
            "sources": {
                "wp2wqan1i": {
                    "type": "vector",
                    "tiles": ["https://delivery.mapmost.com/cdn/mvt/sample_data/{z}/{x}/{y}.pbf"]
                }
            },
            "layers": [
                {
                    "id": "bacground",
                    "type": "background",
                    "paint": {
                        "background-color": "rgba(173, 189, 209, 1)"
                    }
                },
                {
                    "id": "ground_massif3",
                    "type": "fill",
                    "source": "wp2wqan1i",
                    "source-layer": "ground",
                    "paint": {
                        "fill-color": "rgba(139, 142, 159, 1)",
                        "fill-opacity": 1
                    }
                },
                {
                    "id": "water_big",
                    "type": "fill",
                    "source": "wp2wqan1i",
                    "source-layer": "water",
                    "minzoom": 4,
                    "filter": ["all", [">=", "area", 50000]],
                    "paint": {
                        "fill-color": "rgba(2, 131, 182, 1)"
                    }
                },
                {
                    "id": "building",
                    "type": "fill-extrusion",
                    "source": "wp2wqan1i",
                    "source-layer": "building",
                    "minzoom": 14.5,
                    "paint": {
                        "fill-extrusion-color": "rgba(252, 254, 255, 1)",
                        "fill-extrusion-height": ["get", "height_2"]
                    }
                }
            ]
        }
        const map = new mapmost.Map({
            container: 'map', // 地图容器 id
            style: style, //地图样式
            center: [120.71923008473078, 31.29446443371741], // 地图中心点坐标
            zoom: 15, // 起始缩放等级
            pitch: 45, //地图俯仰角
            userId: '***', // sdk授权码 , 可在Mapmost官网申请(https://www.mapmost.com)
        });
    </script>
</body>
</html>

上述代码创建了一个符合Mapmost地图样式文件规范的style对象,该对象中描述了三个面图层以及整个地图背景的样式,并在source中指定了所使用的矢量地图切片数据服务的url。使用该对象替换原本样式文件的url即可自定义图层的显示效果。其最终结果如下图所示。

通过前端自定义样式渲染的矢量瓦片,图源@长风几万里

可以发现矢量切片所呈现的效果比栅格瓦片更加细腻,许多地图厂商已经用矢量瓦片替换了除卫星影像外的地图服务。矢量瓦片服务已经逐渐成为主流的地图服务之一。

关注Mapmost,持续更新GIS、三维美术、计算机技术干货

Mapmost是一套以三维地图和时空计算为特色的数字孪生底座平台,包含了空间数据管理工具(Studio)、应用开发工具(SDK)、应用创作工具(Alpha)。平台能力已覆盖城市时空数据的集成、多源数据资源的发布管理,以及数字孪生应用开发工具链,满足企业开发者用户快速搭建数字孪生场景的切实需求,助力实现行业领先。

欢迎进入官网体验使用:Mapmost——让人与机器联合创作成为新常态

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值