SuperMap iClient 9D for MapboxGL地图风格浅析

作者:dominating
###前言
随着SuperMap iServer 9D的发布,iServer增加了许多的新功能,其中之一就是地图服务模块,矢量切片(tileFeature)资源增加了支持 mvt的表述。mvt矢量切片格式是mapbox标准的矢量切片,而我们的SuperMap iClient 9D 加入了MapboxGL框架,所以我们就可以通过SuperMap iClient 9D来对接SuperMap iServer 9D发布的矢量切片服务,制作出精美的矢量地图。

今天就简单为大家介绍下如何使用SuperMap iClient 9D for MapboxGL来修改地图风格。

###定义MapboxGL的map对象

var map = new mapboxgl.Map({
        container: 'map', // container id
        style: {
            "version": 8,
            "sources": {
                "vector-tiles": {
                    "attribution": attribution,
                    "type": "vector",
                    "tiles": [host + "/iserver/services/map-beijing/rest/maps/beijingMap/tileFeature.mvt?returnAttributes=true&compressTolerance=-1&width=512&height=512&viewBounds={bbox-epsg-3857}&expands=0:0_2,132_128,138_64,141_32,143_16,145_8,147_4"]
                },
            },
            "sprite": "http://iclient.supermapol.com/web/styles/osm/sprite",
            "glyphs": host + "/iserver/services/map-beijing/rest/maps/beijingMap/tileFeature/sdffonts/{fontstack}/{range}.pbf",
            "layers": []
        },
        center: [116.4, 39.9],
        minZoom: 10,
        zoom: 11
    });

tiles,矢量切片的服务地址
sprite,用于渲染背景图案,填充图片,线条图案,点图标的图片url地址(由两个文件组成,索引文件和图片文件,可以使用iClient官网的资源,具体可以参考mapboxGL官方说明)

SuperMap iClient 9D for MapboxGL地图风格浅析_第1张图片SuperMap iClient 9D for MapboxGL地图风格浅析_第2张图片

glyphs,字体库,字体样式资源url地址。 如果任意图层使用了text-field布局属性,此属性不能为空。(下面的symbol图层文字样式将会用到)
layers,需要绘制的图层,将按照顺序进行绘制

"layers": [
  {
            "id": "	四级道路L@北京",  //唯一的图层名称
            "type": "line",   //图层类型
            "source": "vector-tiles",
            "source-layer": "四级道路L@北京",
            "layout": {   //布局样式
                "line-cap": "round",
                "line-join": "round",
                "visibility": "visible"
            },
            "paint": {  //绘制样式
                "line-color": "hsl(224, 22%, 45%)",
                "line-width": {
                    "base": 1.55,
                    "stops": [
                        [13,1.8],
                        [20,20]
                    ]
                },
                "line-opacity": 0.9
            }
        }
]

咱们主要围绕layers来介绍。layers属性列出了可用的所有图层,图层的类型由type属性指定,并且必须是background, fill, line, symbol, raster, circle, fill-extrusion中的一种。
除了背景类型的图层,每个图层都需要引用source。 图层将从source中获取数据,可选地过滤要素,然后定义这些要素的样式。
图层拥有两个子属性,用于确定如何渲染该图层的数据:layout和paint属性。
本篇文章主要介绍我们常用的几种图层类型
###图层类型
####background 背景图层
顾名思义也就是作为地图背景的图层,不需要指定source

map.addLayer({
            "id": "background",
            "type": "background",
            "layout": {
                "visibility":"visible"
            },
            "paint": {
                "background-color": "hsl(55, 1%, 20%)"  //背景颜色
            }
        });

SuperMap iClient 9D for MapboxGL地图风格浅析_第3张图片SuperMap iClient 9D for MapboxGL地图风格浅析_第4张图片

可以设置不同颜色的背景图层。注意,MapboxGL中颜色以各种允许的格式写成JSON字符串,HTML格式的十六进制,rgb,rgba,hsl和hsla,也可以使用预定义的HTML颜色名称,如"blue","yellow

{
  "line-color": "#ff0",
  "line-color": "#ffff00",
  "line-color": "rgb(255, 255, 0)",
  "line-color": "rgba(255, 255, 0, 1)",
  "line-color": "hsl(100, 50%, 50%)",
  "line-color": "hsla(100, 50%, 50%, 1)",
  "line-color": "yellow"
}

####fill 填充图层
可以理解为面图层

        map.addLayer({  //绿地
            "id": "绿地R@北京",
            "type": "fill",
            "source": "vector-tiles",
            "source-layer": "绿地R@北京",
            "paint": {
                "fill-color": "hsl(100, 58%, 76%)",  //填充色
                "fill-opacity": {  //填充透明度
                    "base": 1,
                    "stops": [  //线性变化
                        [
                            5,
                            0
                        ],
                        [
                            7,
                            0.5
                        ]
                    ]
                }
            },
        });
        //湖泊、水库
        map.addLayer({
            "id": "湖泊、水库R@北京",
            "type": "fill",
            "source": "vector-tiles",
            "source-layer": "湖泊、水库R@北京",
            "paint": {
                "fill-color": "hsl(196, 80%, 70%)"
            }
        });

SuperMap iClient 9D for MapboxGL地图风格浅析_第5张图片

可以对面的填充色,透明度,轮廓线颜色进行修改
fill-outline-color ,填充的轮廓颜色。默认为填充颜色
####stop属性
可以注意到代码中我们使用到了一个“stop”属性,这个值被指定为一个函数,该函数是根据输入和输出值进行定义,一组输入值和输出值被称为"stop"。该函数允许你通过使用缩放地图级别来改变地图要素的外观。

"fill-color": "hsl(100, 58%, 76%)",  
                "fill-opacity": {  
                    "base": 1,
                    "stops": [  
                        [5,0],
                        [7,0.5]
                    ]
                }

每个stop是由两个元素组成的数组,第一个是缩放级,第二个是函数输出值。以上例子中,当缩放级为5时,fill-opacity为0,当缩放级为7时,fill-opacity为0.5。fill-opacity的值将从第5级的0线性过渡到第七7级的0.5。"base"参数为内插曲线指数基数,将会影响到两个stop之间的线性变化。我们可以通过两张图来增加理解

SuperMap iClient 9D for MapboxGL地图风格浅析_第6张图片SuperMap iClient 9D for MapboxGL地图风格浅析_第7张图片

当前我的缩放级为5.2,可以看出不同base值的曲线的值是不一样的。

####line 线图层

map.addLayer({
            "id": "	三级道路L@北京",
            "type": "line",
            "source": "vector-tiles",
            "source-layer": "三级道路L@北京",
            "paint": {
                "line-width": {   //线宽
                    "base": 1.5,
                    "stops": [
                        [11,1],
                        [18,10]
                    ]
                },
                "line-color": "hsl(0, 0%, 100%)",  //线颜色
            }
        });
        map.addLayer({
            "id": "	二级道路L@北京",
            "type": "line",
            "source": "vector-tiles",
            "source-layer": "二级道路L@北京",
            "paint": {
                "line-width": 4,
                "line-color": "hsl(230, 24%, 87%)",
            }
        });
    
        map.addLayer({
            "id": "一级道路L@北京1",
            "type": "line",
            "source": "vector-tiles",
            "source-layer": "一级道路L@北京",
            "layout":{
                "line-cap":"butt",    //线段末端样式
                "line-join":"miter"   //线段交汇处样式
            },
            "paint": {
                "line-width": {
                    "base": 1.5,
                    "stops": [
                        [11,6],
                        [18,26]
                    ]
                },
                "line-color": "hsl(230, 24%, 87%)",
                "line-opacity": {   //线透明度
                    "base": 1,
                    "stops": [
                        [10.99,0],
                        [11,1]
                    ]
                },
            }
        });

SuperMap iClient 9D for MapboxGL地图风格浅析_第8张图片

以上例子的line图层,有三种不同样式的道路。我们可以对线的颜色,宽度,透明度,光晕效果进行修改,以及对线头,线交汇处等这样的细节作出调整
其他常用的线样式属性:
line-blur:线的模糊度,默认为0
line-gap-width:在一条线实际路径外画一条线壳。值表示内部间隙的宽度。

####symbol 符号图层
包括文字,图标。

        //道路名称
        map.addLayer({
            "id": "	一级道路Name",
            "type": "symbol",   //类型为symbol
            "source": "vector-tiles",
            "source-layer": "一级道路L@北京",
            "layout": {
                "text-line-height": 1.1,   //行高
                "text-size": {      //字体大小
                    "base": 1.5,
                    "stops": [
                        [13.99,12],
                        [20,24
                    ]
                },
                "text-font": [    //字体类型
                    "DIN Offc Pro Italic",
                    "Arial Unicode MS Regular"
                ],
                "symbol-placement": "line",   //符号位置,默认为point,由于是道路名称所以设置为line
                "text-field": "{道路名称}",    //需要显示的字段名称
                "text-letter-spacing": 0.1,   //字间距
                "text-max-width": 5    //文本换行最大行宽
            },
            "paint": {
                "text-color": "hsl(0, 0%, 0%)",   //字体颜色
                "text-halo-color": "hsl(0, 0%, 100%)",  //字体光晕颜色
                "text-halo-width": 1.25,  //光晕宽度
                "text-opacity": {  //文字透明度
                    "base": 1,
                    "stops": [
                        [13.99,0],
                        [14,1]
                    ]
                },
            },
        });
        map.addLayer({
            "id": "医疗卫生@北京",
            "type": "symbol",
            "source": "vector-tiles",
            "source-layer": "医疗卫生@北京",
            "layout": {
                "icon-image": "hospital-11",  //图标id
                "text-offset": [0, -0.5],  //文字偏移量
                "text-anchor": "bottom",  //文字锚点,支持center, left, right, top, bottom, top-left, top-right, bottom-left, bottom-right,默认center
                "text-field": "{NAME}",
                "text-size": 12
            },
            "paint": {
                "text-color": "hsl(0, 0%, 78%)",
                "text-halo-color": "#212121",
                "text-halo-width": 1,
                "text-halo-blur": 0
            }

        });
        map.addLayer({
            "id": "其它@北京2",
            "type": "symbol",
            "source": "vector-tiles",
            "source-layer": "其它@北京",
            "layout": {
                "icon-image": "car-11",
                "text-offset": [0, -0.5],
                "text-anchor": "bottom",
                "text-field": "{NAME}",
                "text-size": 12
            },
            "filter": [   //过滤条件
                "==",
                "NAME",
                "停车场"
            ],
            "paint": {
                "text-color": "hsl(0, 0%, 0%)",
                "text-opacity": 1,
                "text-halo-color": "hsl(0, 0%, 100%)",
                "text-halo-width": 1,
                "text-halo-blur": 1
            }

        });

SuperMap iClient 9D for MapboxGL地图风格浅析_第9张图片

以上例子可以看出来,我们可以通过symbol图层对点,线的标签以及点符号进行绘制。我们几乎可以对它们进行任意的操作。以下是我们在symbol图层中需要注意的地方:
layout中的symbol-placement,默认为point,如果要显示线标注,需要修改为line,这样就沿线标注了
text-field的值为需要显示的字段名称,用{fieldname}格式填写
text-anchor ,文字的锚点,包括有center, left, right, top, bottom, top-left, top-right, bottom-left, bottom-right,默认center
text-offset,文字偏移量,正值表示右和下,负值表示左和上
icon-image,用于绘制的图片在sprite中的图像名称,所以配文字图层的时候,我们需要知道sprite中有哪些图片和对应的名称

####filter过滤器
可以看出我们最后添加的图层上使用了过滤器filter,MapboxGL的过滤器可以说是非常强大的。过滤器支持以下形式的数组:
存在过滤(Existential Filters)

["has", key] feature[key] exists
["!has", key] feature[key] does not exist

比较过滤器(Comparison Filters)

["==", key, value] equality: feature[key] = value
["!=", key, value] inequality: feature[key] ≠ value
[">", key, value] greater than: feature[key] > value
[">=", key, value] greater than or equal: feature[key] ≥ value
["<", key, value] less than: feature[key] < value
["<=", key, value] less than or equal: feature[key] ≤ value

设置成员资格过滤器(Set Membership Filters)

["in", key, v0, ..., vn] set inclusion: feature[key] ∈ {v0, ..., vn}
["!in", key, v0, ..., vn] set exclusion: feature[key] ∉ {v0, ..., vn}

组合过滤(Combining Filters)

["all", f0, ..., fn] logical AND: f0 ∧ ... ∧ fn
["any", f0, ..., fn] logical OR: f0 ∨ ... ∨ fn
["none", f0, ..., fn] logical NOR: ¬f0 ∧ ... ∧ ¬fn

key必须是一个字符串,用来标识要素属性或者是下面的特殊键:

  • “$type”:要素类型,该key可以和"==", “!=”, “in”,与"!in"一起使用。值可能为"Point", “LineString”, 和"Polygon"
  • “$id”:要素标识符,该key可以与"==", “!=”, “has”, “!has”, “in”, 和"!in" 一起使用

value必须是一个字符,数字或者布尔值才能用来比较属性值,如

["==", "NAME", "停车场"]

设置成员资格过滤器可以用来测试字段是否匹配多个值。这个过滤就是要求要素的class必须是"street_major", “street_minor”, "street_limited"中的一个。

["in", "class", "street_major", "street_minor", "street_limited"]

“all”,“any”,和"none"操作符用于创建复合过滤。值f0,…,fn必须是过滤表达式,比如以下的例子

[
  "all",
  ["==", "class", "street_limited"],
  [">=", "admin_level", 3],
  ["!in", "$type", "Polygon"]
]

这个组合过滤器由三个过滤表达式组成,要求此要素必须满足这三个条件,class需要是"street_limited",admin_level必须大于等于3,类型type不能是多边形。当然你也可以换成any,满足其中之一或者多个条件,或者使用none来取反。
###结语
以上的话就是MapboxGL地图风格中常用的几种图层类型以及相关函数的简单介绍。可以看出如果要配出一幅精美的地图的话是非常需要耐心和时间的。其实我们也可以借助Mapbox的mapbox studio可视化编辑工具来制作地图。我们可以在工具中将地图的风格配置好,然后导出风格文件,做相关修改后使用在我们自己的地图中。

SuperMap iClient 9D for MapboxGL地图风格浅析_第10张图片

Mapbox studio地址:https://www.mapbox.com/mapbox-studio/

更多详细请参考:https://www.mapbox.com/mapbox-gl-js/style-spec

你可能感兴趣的:(云GIS)