mapbox

现在我们来添加一些常见的地图控件,导航(NavigationControl,放大、缩小以及指北针按钮)、定位(GeolocateControl)、比例尺(ScaleControl)、全屏(FullscreenControl)

import ReactMapboxGl, { ScaleControl, Layer, Feature, GeoJSONLayer } from ‘react-mapbox-gl’;

urls

该”urls”值是一个数组。对于数组中的每个URL,将创建一个视频元素源,以便支持不同浏览器支持的多种格式的同一媒体。

  1. "urls": [
  2. "https://static-assets.mapbox.com/mapbox-gl-js/drone.mp4",
  3. "https://static-assets.mapbox.com/mapbox-gl-js/drone.webm"
  4. ],

coordinates

“coordinates”数组包含[longitude, latitude]按顺时针顺序列出的视频角对,即左上,右上,右下,左下。

 "coordinates": [
        [-122.51596391201019, 37.56238816766053],
        [-122.51467645168304, 37.56410183312965],
        [-122.51309394836426, 37.563391708549425],
        [-122.51423120498657, 37.56161849366671]
    ]

雪碧图

样式的sprite财产物资装载的小图像使用呈现URL模板background-pattern,fill-pattern,line-pattern,fill-extrusion-pattern和icon-image样式属性。

"sprite": "mapbox://sprites/mapbox/bright-v8"

有效的精灵源必须提供两种类型的文件:

一个索引文件,这是一个包含每个图像的描述的JSON文档包含在子画面。该文件的内容必须是JSON对象,其键构成用作上述样式属性值的标识符,并且其值是描述图像的尺寸(width和height属性)和像素比率(pixelRatio)及其在图像中的位置的对象精灵(x和y)。例如,包含单个图像的精灵可能具有以下索引文件内容:

{
    "poi": {
        "width": 32,
        "height": 32,
        "x": 0,
        "y": 0,
        "pixelRatio": 1
    }
}

然后,样式可以通过创建具有layout属性”icon-image”: “poi”,或者具有标记化值的符号层和具有value 属性的”icon-image”: “{icon}”矢量平铺要素,来引用此sprite图像。iconpoi

Mapbox SDK将使用sprite样式中的属性值来生成用于加载两个文件的URL。首先,对于这两种文件类型,它将附加@2x到高DPI设备上的URL。其次,它将.json为索引文件和.png图像文件添加文件扩展名:。例如,如果指定”sprite”: “https://example.com/sprite",渲染器将加载https://example.com/sprite.json和https://example.com/sprite.png,或https://example.com/sprite@2x.json和https://example.com/sprite@2x.png。

字形

样式的glyphs属性提供了一个URL模板,用于以PBF格式加载带符号距离字段的字形集。

"glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf"

该URL模板应包含两个令牌:

  • {fontstack}请求字形时,此标记将替换text-font为符号层属性中指定的字体堆栈中的逗号分隔的字体列表
  • {range}请求字形时,此令牌将替换为256个Unicode代码点的范围。例如,要为Unicode Basic Latin和Basic Latin-1 Supplement块加载字形,范围将为0-255。加载的实际范围是在运行时根据需要显示的文本确定的。

transition

transition对可转换风格属性以前的值和新值之间的插值属性控制时序。样式的roottransition属性为该样式提供全局过渡默认值。任何可转换样式属性也可以具有自己的-transition属性,该属性为该特定图层属性定义特定的转换时间,从而覆盖全局transition值。

"transition": {
  "duration": 300,
  "delay": 0
}

layers

样式的layers属性列出了该样式中可用的所有图层。图层的类型由”type”属性指定,并且必须是background,fill,line,symbol,raster,circle,fill-extrusion,heatmap,hillshade之一。

除了背景类型的图层外,每个图层都需要引用源。图层从源中获取数据,可以选择过滤要素,然后定义如何对这些要素进行样式设置。

"layers": [
  {
    "id": "water",
    "source": "mapbox-streets",
    "source-layer": "water",
    "type": "fill",
    "paint": {
      "fill-color": "#00ffff"
    }
  }
]

id

唯一图层

type

必需的枚举。 一”fill”,”line”,”symbol”,”circle”,”heatmap”,”fill-extrusion”,”raster”,”hillshade”,”background”。
该层的渲染类型。

“fill”:
具有可选描边边框的填充多边形。

“line”:
描边线。

“symbol”:
图标或文本标签。

“circle”:
实心圆。

“heatmap”:
热图。

“fill-extrusion”:
拉伸的(3D)多边形。

“raster”:
栅格地图纹理,例如卫星图像。

“hillshade”:
基于DEM数据的客户端山体阴影可视化。目前,该实现仅支持Mapbox Terrain RGB和Mapzen Terrarium磁贴。

“background”:
地图的背景颜色或图案

zoom

缩放功能允许地图功能的外观随地图的缩放级别而变化。缩放功能可用于创建深度错觉和控制数据密度。每个停止点都是一个包含两个元素的数组:第一个是缩放级别,第二个是函数输出值。

{
    "circle-radius": {
        "stops": [
            // zoom is 5 -> circle radius will be 1px
            [5, 1],
            // zoom is 10 -> circle radius will be 2px
            [10, 2]
        ]
    }
}

{
    "circle-color": {
        "property": "temperature",
        "stops": [
            // "temperature" is 0   -> circle color will be blue
            [0, 'blue'],
            // "temperature" is 100 -> circle color will be red
            [100, 'red']
        ]
    }
}

{
    "circle-radius": {
        "property": "rating",
        "stops": [
            // zoom is 0 and "rating" is 0 -> circle radius will be 0px
            [{zoom: 0, value: 0}, 0],

            // zoom is 0 and "rating" is 5 -> circle radius will be 5px
            [{zoom: 0, value: 5}, 5],

            // zoom is 20 and "rating" is 0 -> circle radius will be 0px
            [{zoom: 20, value: 0}, 0],

            // zoom is 20 and "rating" is 5 -> circle radius will be 20px
            [{zoom: 20, value: 5}, 20]
        ]
    }
}

Map的组成:

任何GIS引擎必然要处理两个部分:

  • 一个是数据来源
  • 一个是这些数据在界面呈现的样子,在style里面的source和layer对应于这两个部分。

Source:

目前source支持vector,raster, geojson, image,video。geojson的支持比较巧妙,有了这个就可以处理各种矢量类型,包括集合。

  • vector主要解决的是矢量瓦片,
  • raster解决的是目前常用的栅格化的瓦片。
  • video的加入使得功能更加的现代化。
  • mapbox在style里面,为source定义了一个type属性,来说明这些类型。

除了这个属性之外,source其实都有一个id,被layer引用,从而让数据源和数据呈现关联在一起。 这个地方需要注意的是,source和layer之间的关系,可以是1->n

Layer:

layers,需要绘制的图层,将按照顺序进行绘制
图层拥有两个子属性,用于确定如何渲染该图层的数据:layout和paint属性。

"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%)",
                //Hue(色调)相近色,Saturation(饱和度) 相近色,Lightness (亮度)相近色
                "line-width": {
                    "base": 1.55,
                    "stops": [
                        [13,1.8],
                        [20,20]
                    ]
                },
                "line-opacity": 0.9
            }
        }
]

layers属性列出了可用的所有图层,图层的类型由type属性指定,并且必须是background, fill, line, symbol, raster, circle, fill-extrusion中的一种。

  • 除了background类型的layer不需要绑定source之外。其他的都需要有source。图层将从source中获取数据,可选地过滤要素,然后定义这些要素的样式。
  • fill类型的layer只负责填充;
  • line类型的layer只负责线条;
  • mapbox - 图1
  • mapbox - 图2
    不管是什么界面,都是由点线面组成的。 layer其实代表的就是mapbox - 图3,只是大家通常会认为一个layer上会放置各种点,线,面。 mapbox把这种layer再细分层了更小的单元, 只包含点的layer,只负责呈现线的layer,只负责面的layer。如果把多个layer组合在一起,就和现在的通用想法的layer是一样的,source和layer的1->n关系在这个地方发挥作用了。
    这样设计不仅简单化,关键还可以提高效率,能批量化的渲染。

background 背景图层

顾名思义也就是作为地图背景的图层,不需要指定source

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

可以设置不同颜色的背景图层。注意,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"
}

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之间的线性变化。我们可以通过两张图来增加理解

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%)"
    }`
});

可以对面的填充色,透明度,轮廓线颜色进行修改
fill-outline-color ,填充的轮廓颜色。默认为填充颜色

Filter:

mapbox也充分考虑了个别特殊元素的定制化显示需求,如果要对一批元素中的某些个别元素进行定制化呈现:

  • 可以在layer里面设置filter,满足条件的元素才会被呈现出来
  • 并用layer设定的样式渲染。filter是一个很强大的功能,有效融合在设计中,可以解决很多问题。

style

style文件才是核心,API只是围绕着这个核心服务的
想看API, 可以参见 https://www.mapbox.com/mapbox-gl-js/api
Style指定的样式是MapBox提供的、以矢量瓦片的方式加载的地图,可以在 API 和用户信息处找到预定义的样式,也可以自定义地图样式,
参考:https://blog.csdn.net/supermapsupport/article/details/77991911

现在我们可以通过鼠标拖拽、缩放地图,并使用鼠标右键旋转(bearing属性)、倾斜(pitch属性)地图。

矢量切片(tileFeature)

tiles,矢量切片的服务地址

const mapStyle = {
  tencentNight: [
    'https://m0.map.gtimg.com/hwap?z={z}&x={x}&y={y}&styleid='.concat(
      '4',
      '&scene=0&version=224&plusz=1',
    ),
    'https://m1.map.gtimg.com/hwap?z={z}&x={x}&y={y}&styleid='.concat(
      '4',
      '&scene=0&version=224&plusz=1',
    ),
    'https://m2.map.gtimg.com/hwap?z={z}&x={x}&y={y}&styleid='.concat(
      '4',
      '&scene=0&version=224&plusz=1',
    ),
    'https://m3.map.gtimg.com/hwap?z={z}&x={x}&y={y}&styleid='.concat(
      '4',
      '&scene=0&version=224&plusz=1',
    ),
  ],
  tencentDay: [
    'http://rt1.map.gtimg.com/tile?z={z}&x={x}&y={y}&styleid=1&version=117',
    'http://rt2.map.gtimg.com/tile?z={z}&x={x}&y={y}&styleid=1&version=117',
    'http://rt3.map.gtimg.com/tile?z={z}&x={x}&y={y}&styleid=1&version=117',
  ],
};

let tileStyle = mapStyle['tencentNight'];

sources: {
    'raster-tiles': {
        type: 'raster',
        tiles: tileStyle,
    }
}

"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,

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

glyphs,字体库,字体样式资源url地址

如果任意图层使用了text-field布局属性,此属性不能为空。(下面的symbol图层文字样式将会用到)

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]
            ]
        },
    }
});

以上例子的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
         //layout中的symbol-placement,默认为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
   }

});

以上例子可以看出来,我们可以通过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", "停车场"]

"filter": [   //过滤条件
      "==",
      "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来取反。

数组

是按逗号分隔的一个或多个按特定顺序排列的数字的列表。例如,它们用于行破折号数组,其中数字指定行,断点和再次行的间隔。如果将数组用作表达式中的参数,则必须将数组包装在literal表达式中。

{
    "line-dasharray": [2, 4]
}

{
    "circle-color": ["in", 1, ["literal", [1, 2, 3]]]
}

表达方式

可以将任何layout属性,paint属性或filter的值指定为表达式。表达式定义了一个公式,用于使用以下描述的运算符来计算属性的值。Mapbox GL提供的表达式运算符集包括:

  • 用于对数值执行算术和其他运算的数学运算符
  • 逻辑运算符,用于处理布尔值和做出条件决策
  • 用于操作字符串的字符串运算符
  • 数据运算符,提供对源要素属性的访问
  • 摄像机操作员,可访问定义当前地图视图的参数

表达式表示为JSON数组。表达式数组的第一个元素是命名表达式运算符的字符串,例如”*”或”case”。后面的元素(如果有)是表达式的参数。每个参数都是文字值(字符串,数字,布尔值或null),或者是另一个表达式数组。

数据表达

数据表达式是任何表达式,访问特征数据,即任何表达该数据操作员的用途之一:get,has,id,geometry-type,properties,或feature-state。数据表达式允许要素的属性或状态确定其外观。它们可用于区分同一层中的要素并创建数据可视化。

{
    "circle-color": [
        "rgb",
        // red is higher when feature.properties.temperature is higher
        ["get", "temperature"],
        // green is always zero
        0,
        // blue is higher when feature.properties.temperature is lower
        ["-", 100, ["get", "temperature"]]
    ]
}

本示例使用get运算符获取temperature每个功能的值。该值用于计算rgb运算符的参数,并根据其红色,绿色和蓝色成分定义颜色。

数据表达式允许作为filter属性的值,也可以作为大多数绘画和布局属性的值。但是,某些绘画和布局属性尚不支持数据表达式。支持级别由每个属性的“ SDK支持”表的“数据驱动样式”行指示。使用feature-state运算符的数据表达式仅适用于绘画属性。

相机表情

相机表达式是使用任何表达式zoom运算符。这样的表达式允许图层的外观随地图的缩放级别而变化。相机表达式可用于创建深度外观并控制数据密度。

{
    "circle-radius": [
        "interpolate", ["linear"], ["zoom"],
        // zoom is 5 (or less) -> circle radius will be 1px
        5, 1,
        // zoom is 10 (or greater) -> circle radius will be 5px
        10, 5
    ]
}

本示例使用interpolate运算符通过一组输入输出对定义缩放级别和圆形大小之间的线性关系。在这种情况下,该表达式表示当缩放级别为5或以下时,圆半径应为1像素,而当缩放级别为10或以上时,圆半径应为5像素。在两个缩放级别之间,圆半径将在1到5像素之间线性内插

可以在可以使用表达式的任何地方使用相机表达式。当摄影机表达式用作布局或绘画属性的值时,它必须采用以下形式之一

[ "interpolate", interpolation, ["zoom"], ... ]

[ "step", ["zoom"], ... ]

[
    "let",
    ... variable bindings...,
    [ "interpolate", interpolation, ["zoom"], ... ]
]

[
    "let",
    ... variable bindings...,
    [ "step", ["zoom"], ... ]
]

也就是说,在布局或绘画属性中,[“zoom”]可能仅作为外部interpolate或step表达式或表达式中此类表达式的输入出现let。
在相机表情评估的时间上,版面和绘画属性之间存在重要差异。每当缩放级别发生变化时(即使是部分更改),都将重新评估Paint属性相机的表达式。例如,当地图在缩放级别4.1和4.6之间移动时,将连续重新评估涂料属性相机的表情。甲布局属性仅在整数缩放级别相机表达式。缩放比例从4.1更改为4.6 时,不会对其进行重新评估-仅当其大于5或小于4时。

组成

单个表达式可以混合使用数据运算符,相机运算符和其他运算符。这种复合表达式允许通过缩放级别和各个要素属性的组合来确定图层的外观。

{
    "circle-radius": [
        "interpolate", ["linear"], ["zoom"],
        // when zoom is 0, set each feature's circle radius to the value of its "rating" property
        0, ["get", "rating"],
        // when zoom is 10, set each feature's circle radius to four times the value of its "rating" property
        10, ["*", 4, ["get", "rating"]]
    ]
}

同时使用数据和相机运算符的表达式被视为数据表达式和相机表达式,并且必须遵守上述针对两者的限制。

类型系统

表达式的输入参数及其结果值使用与其余样式规范相同的类型集:布尔值,字符串,数字,颜色和这些类型的数组。此外,表达式是类型安全的:表达式的每次使用都具有已知的结果类型和必需的参数类型,并且SDK会验证表达式的结果类型是否适合使用它的上下文。

  • 例如,filter属性中表达式的结果类型必须为boolean,
  • +-运算符的参数必须为number。

使用要素数据时,SDK通常通常不知道要素属性值的类型。为了保持类型安全,在评估数据表达式时,SDK将检查属性值是否适合上下文。例如,如果您[“get”, “feature-color”]对circle-color属性使用表达式,则SDK将验证feature-color每个功能的值是否是标识有效color的字符串。如果此检查失败,将以SDK特定的方式(通常是一条日志消息)指示错误,并将使用该属性的默认值。

在大多数情况下,此验证将在需要的任何地方自动进行。但是,在某些情况下,SDK可能无法根据周围环境自动确定数据表达式的预期结果类型。例如,不清楚表达式[“<”, [“get”, “a”], [“get”, “b”]]是要比较字符串还是数字。在这种情况下,可以使用类型断言表达式运算符之一来指示数据表达式的预期类型:[“<”, [“number”, [“get”, “a”]], [“number”, [“get”, “b”]]]。类型声明检查特征数据是否与数据表达式的预期类型匹配。如果此检查失败,则会产生错误,并使整个表达式恢复为所定义属性的默认值。断言运营商array,boolean,number,和string。

表达式仅执行一种隐式类型转换:在期望颜色的上下文中使用的数据表达式会将颜色的字符串表示形式转换为颜色值。在其他情况下,如果你想类型之间的转换,你必须使用一个类型转换表达式运算符:to-boolean,to-number,to-string,或to-color。例如,如果您具有一个功能属性,该属性以字符串格式存储数字值,并且希望将这些值用作数字而不是字符串,则可以使用诸如的表达式[“to-number”, [“get”, “property-name”]]。

如果表达式接受数组参数,并且用户提供了数组文字,则该数组必须包装在literal表达式中(请参见下面的示例)。当GL-JS在style-spec属性值中遇到一个数组时,它将假定该数组是一个表达式并尝试对其进行解析;该库无法区分验证失败的表达式和数组文字,除非开发人员通过literal运算符明确区分。所述literal如果阵列是由子表达,例如返回操作者没有必要[“in”, 1, [“get”, “myArrayProp”]]。

// will throw an error
{
    "circle-color": ["in", 1, [1, 2, 3]]
}

// will work as expected
{
    "circle-color": ["in", 1, ["literal", [1, 2, 3]]]
}

表达式参考

types

本节中的表达式用于测试不同的数据类型,例如字符串,数字和布尔值,并在它们之间进行转换。

通常,这种测试和转换是不必要的,但是在某些子表达式的类型不明确的某些表达式中,它们可能是必需的。在要素数据类型不一致的情况下,它们也很有用;例如,您可以to-number用来确保将诸如”1.5”(而不是1.5)之类的值视为数字值。

数组

断言输入是一个数组(可以选择具有特定项目类型和长度的数组)。如果在评估输入表达式时,它不是断言类型,则此断言将导致整个表达式被中止。

["array", value]: array
["array", type: "string" | "number" | "boolean", value]: array<type>
["array",
    type: "string" | "number" | "boolean",
    N: number (literal),
    value
]: array<type, N>

布尔值

断言输入值是布尔值。如果提供了多个值,则会依次评估每个值,直到获得布尔值为止。如果所有输入都不是布尔值,则该表达式为错误。

["boolean", value]: boolean
["boolean", value, fallback: value, fallback: value, ...]: boolean

格式化

返回一个formatted字符串,用于在text-field属性中显示混合格式的文本。输入可以包含字符串文字或表达式,包括’image’表达式。字符串后面可以跟随一个支持以下属性的样式覆盖对象:

  • “text-font”:覆盖由根布局属性指定的字体堆栈。
  • “text-color”:覆盖由根油漆属性指定的颜色。
  • “font-scale”:对缩放比例应用text-size根比例布局属性指定的比例因子。
["format",
    input_1: string | image, options_1: { "font-scale": number, "text-font": array<string>, "text-color": color },
    ...,
    input_n: string | image, options_n: { "font-scale": number, "text-font": array<string>, "text-color": color }
]: formatted

文字

提供文字数组或对象值

["literal", [...] (JSON array literal)]: array<T, N>
["literal", {...} (JSON object literal)]: object

数字

断言输入值是一个数字。如果提供了多个值,则依次评估每个值,直到获得一个数字。如果所有输入都不是数字,则表达式为错误。

["number", value]: number
["number", value, fallback: value, fallback: value, ...]: number

数字格式化

使用提供的格式规则将输入数字转换为字符串表示形式。如果设置,则该locale参数指定要用作BCP 47语言标记的语言环境。如果设置,则该currency参数指定用于货币样式格式的ISO 4217代码。如果设置,则min-fraction-digits和max-fraction-digits参数指定要包括的小数位数的最小和最大数目。

["number-format",
    input: number,
    options: { "locale": string, "currency": string, "min-fraction-digits": number, "max-fraction-digits": number }
]: string

object

断言输入值是一个对象。如果提供多个值,则依次评估每个值,直到获得一个对象。如果所有输入都不是对象,则表达式为错误。

["object", value]: object
["object", value, fallback: value, fallback: value, ...]: object

字符串

断言输入值是一个字符串。如果提供了多个值,则将依次评估每个值,直到获得一个字符串。如果所有输入都不是字符串,则表达式为错误

["string", value]: string
["string", value, fallback: value, fallback: value, ...]: string

布尔值

将输入值转换为布尔值。当接着输入‘’,0,false,null或NaN,其结果是false,; 否则是true。

["to-boolean", value]: boolean

转换color

将输入值转换为颜色。如果提供了多个值,则将依次评估每个值,直到获得第一个成功的转换为止。如果没有任何输入可以转换,则该表达式为错误。

["to-color", value, fallback: value, fallback: value, ...]: color

转化数字

如果可能,将输入值转换为数字。如果输入为null或false,结果为0。如果输入为true,结果为1。如果输入为字符串,则将其转换为ECMAScript 的“应用于字符串类型的ToNumber”算法指定的数字。语言规范。如果提供了多个值,则将依次评估每个值,直到获得第一个成功的转换为止。如果没有任何输入可以转换,则该表达式为错误。

["to-number", value, fallback: value, fallback: value, ...]: number

转化为字符串

将输入值转换为字符串。如果输入为null,则结果为””。如果输入为布尔值,则结果为”true”或”false”。如果输入是数字,则将其转换为ECMAScript语言规范的“ NumberToString”算法指定的字符串。如果输入是彩色,它被转换为以下形式的串”rgba(r,g,b,a)”,其中r,g和b是数字范围从0到255,和a范围为0〜1。否则,输入被转换成一个字符串中由指定的格式JSON.stringifyECMAScript语言规范的功能。

["to-string", value]: string

类型

返回描述给定值类型的字符串。

["typeof", value]: string

coalesce函数(下面简称函数),返回一个参数中非空的值。如:

SELECT COALESCE(NULL, NULL, GETDATE())
由于两个参数都为null,所以返回getdate()函数的值,也就是当前时间。即返回第一个非空的值。由于这个函数是返回第一个非空的值,所以参数里面必须最少有一个非空的值,如果使用下面的查询,将会报错:

case

case通常用于分段数值型的字段渲染,值域是前关后开,如分级渲染。

'circle-color': [
  'case',
  ['<', ['get', 'speed'], 10.8], 'rgba(0,0,0,0)', //<10.8
  ['<', ['get', 'speed'], 17.2], 'rgba(153, 255, 153, .9)', //>=10.8 & <17.2
  ['<', ['get', 'speed'], 24.5], 'rgba(102, 204, 255, .9)',
  ['<', ['get', 'speed'], 32.7], 'rgba(255, 255, 102, .9)',
  ['<=', ['get', 'speed'], 41.5], 'rgba(253, 139, 0, .9)',
  ['<=', ['get', 'speed'], 50.1], 'rgba(255, 51, 0, .9)', //>=41.5 & <50.1
  'rgba(255, 0, 255, .9)' // 默认值, >=50.1
]