矢量分块专题


一、背景

自从谷歌地图以来,很多地图服务商都根据谷歌地图的金字塔模型,实现了一套切图系统。这种方式在客户端只需要根据地理范围以及缩放级别,就可以请求相应的地图瓦片, 然后再把瓦片拼接起来,就完成了地图在客户端的地图的展示。这种方式很好的避免了网络带宽以及客户端渲染能力弱的问题,这在当时也是WebGIS出图的一个好的解决方案。

但是,当需要修改地图的显示风格时,必须关闭服务器,然后用对地图数据进行重新处理并重新配图,然后再打开服务器重新切图,最后才能在客户端进行新地图的展示。 这样就带来了一些不必要的维护问题。随着网络带宽的日益增长,以及客户端渲染能力的增强,我们可以考虑利用客户端对地图进行实时的渲染,让用户可以直接在客户端完成地图的风格的定制, 方便人们通过互联网轻松地完成地图配图工作,从而免去一些服务器维护工作。矢量分块就是客户端矢量地图实时渲染的一个实现。

二、简介

矢量分块属于客户端的矢量地图,地图的渲染全部都在客户端完成。服务器提供地图矢量数据,以及地图的渲染风格属性信息,这样客户端就可以将地图渲染出来。 矢量分块的实现也类似于金字塔模型,只不过这些切片都是一块一块的矢量切片数据,每个矢量切片数据都是按照瓦片的范围进行裁剪得到。 客户端根据瓦片的位置以及比例尺向服务器请求矢量切片。每个矢量切片都包含多个数据集,一个数据集相当于一个图层,每个数据集都包含了多个要素,包括点、线、面和文本要素。 此外,服务器上还包含有每个图层的渲染风格信息,比如线宽,面的颜色等等信息。客户端根据这些信息就可以将矢量切片数据渲染成地图。

矢量分块除了提供根据服务端的渲染风格信息对地图进行渲染之外,还提供了用户自定义的渲染风格信息的渲染接口。这种渲染风格信息就是一种类CSS的地图风格样式表—— CartoCSS。其中,矢量分块只实现了CartoCSS标准中的一部分,除外, 还对标准的CartoCSS进行了相应的扩展。利用CartoCSS,用户可以方便地定义地图的渲染方式,从而定制属于自己的个性地图。

三、地图样式表的实现

CartoCSS的变量:

在CartoCSS中,用户可以定义一个变量,然后在CartoCSS代码中使用,例如:

@color:#000;
@width:2;
#China_Road_L___China400{
    line-color:@color;
    line-width:@width;
}

CartoCSS的选择器:

ID选择器:

图层ID默认为将图层名中的"@"与"#"符号替换为"___"双划线,例如:图层名为:"China_Road_L@China400#1"会替换为:"China_Road_L___China400___1"

#China_Road_L___China400{
}

类选择器:

图层类名默认为与图层ID保持一致

.China_Road_L___China400{
}

要素ID属性选择器:

目前只支持featureID要素属性

#China_Road_L___China400{
    [featureID=1]{
        line-width:3;
    }
}

缩放级别控制:

可以通过zoom来控制图层在不同缩放级别下的样式符号

#China_Road_L___China400{
    [zoom>4]{
        line-width:2;
    }
}

高亮显示:

点击高亮以及鼠标移动高亮

#China_Road_L___China400{
    ::click{
        line-color:#f00;
    }
    ::hover{
        line-color:#0f0;
    }
}

伪类:

当要素对同一图层定义不同的样式时可用到,如下,就定义了一根边框为红色,中间为黑色的线

#China_Road_L___China400::one{
    line-color:#f00;
    line-width:10;
}
#China_Road_L___China400::tow{
    line-color:#000;
    line-width:2;
}

效果如下


CartoCSS实现的属性

其中的Color类型可为十六进行字符串:#000,也可为rgb:rgb(0,0,0)或者rgba:rgba(0,0,0,1)类型,和hsl类型:hsl(0.5,0.5,0.5)。 而point-comp-op的值可为以下几种:src-over、dst-over、src-in、dst-in、src-out、dst-atop、xor、plus、lighten。

点图层属性:

point-file {URL} 点符号的文件url,格式为:url(“./examples/images/marker.png”)。
point-fill {Color} 矢量点符号的颜色值,只有当point-file为空时点才会被渲染成矢量点,格式为:#000。
point-dx {Number} 点在x轴上的偏移值,单位为px,正值为右移,负值为左移。
point-dy {Number} 点在y轴上的偏移值,单位为px,正值为下移,负值为上移。
point-opacity {Number} 点的透明度,值的范围为0~1。
point-comp-op {String} 属性设置或返回如何将一个源(新的)图像绘制到目标(已有)的图像上,其中源图像是指您打算放置到地图上的绘图,而目标图像则指您已经放置在地图上的绘图。

线图层属性:

line-color {Color} 线的颜色值,格式为:#000。
line-width {Number} 线宽度,单位为px。
line-cap {String} 线端点的样式,值可为:平头”butt”、圆头”round”、方头”square”。
line-join {String} 线的拐角处的样式,值可为:泄角”bevel”、圆角”round”、尖角”miter”。
line-miterlimit {Number} 线的最大斜接长度。
line-dash-offset {Number} 虚线模式的偏移值,即虚线从偏移值处才开始虚线的绘制,被偏移掉的一段为实线。
line-opacity {Number} 线的透明度,值为0~1。
line-dasharray {Array} 虚线的模式,格式为:10,10,其中第0个值为第一段实线的长度,第1个值为第一段空线的长度,后面的虚线按照这个模式重复。
line-offset {Number} 线的偏移,单位为px,正值为向左偏移,负值为向右偏移。
line-comp-op {String} 同point-comp-op。

面图层属性(面支持除了line-offset、line-comp-op和line-opacity之外的所有线属性):

polygon-fill {Color} 面填充的颜色,格式为:#000。
polygon-dx {Number} 面在x轴上的偏移值,单位为px,正值为向右偏移,负值为向左偏移。
polygon-dy {Number} 面在y轴上的偏移值,单位为px,正值为向下偏移,负值为向上偏移。
polygon-comp-op {String} 同point-comp-op。

文本图层属性:

text-size {Number} 文本的尺寸,单位为px。
text-face-name {String} 文本的字体名称,如:Times New Roman。
text-align {String} 文本在水平方向的对齐方式,值可为:center、left、right。
text-vertical-alignment {String} 文本在垂直方向上的对齐方式,值可为:top、middle、baseLine、bottom。
text-halo-radius {Number} 文本外围边框的宽度。
text-fill {Color} 文本的颜色。
text-opacity {Number} 文本的透明度,值为0~1。
text-dx {Number} 文本在x轴上的偏移值,单位为px,正值为向右偏移,负值为向左偏移。
text-dy {Number} 文本在y轴上的偏移值,单位为px,正值为向下偏移,负值为向上偏移。
text-comp-op {String} 同point-comp-op。

四、使用说明

使用矢量分块进行客户端地图的配图非常容易上手,只需要创建一个矢量分块图层,然后编辑地图样式表就可以配出一幅好地图了,但是要配好一幅地图对用户对地图样式表——CartoCSS 的掌握程度要求比较高,因此,想在客户端配出一幅好地图,必须掌握好CartoCSS。以下为矢量分块客户端配图的详细步骤:

1、创建TiledVectorLayer图层

要使用矢量分块功能,必须先创建一个TiledVectorLayer图层并添加到地图中,例如:

    layer = new SuperMap.Layer.TiledVectorLayer("China", url,{cacheEnabled:true}});
    layer.events.on({"layerInitialized": addLayer});

    function addLayer() {
         map.addLayers([layer]);
        var center = new SuperMap.LonLat(0,0);
        map.setCenter(center, 0);
    }

2、编辑CartoCSS样式表

    var cartoCss=["#World_Continent___China400{",
        "polygon-fill:rgb(245,243,240);",
        "line-width:1;",
        "line-color:#ddd;",
        "::hover[featureID=73]{",
        "polygon-fill:#f00;",
        "}",
    "}"].join("\n");

3、应用CartoCSS

    layer.setCartoCSS(cartoCss);

4、其他用法

其中的CartoCSS样式文件也可以在创建TiledVectorLayer图层时传递进去,例如:

    layer = new SuperMap.Layer.TiledVectorLayer("China", url,{cacheEnabled:true},{cartoCss:cartoCss});

也可以将cartoCSS样式保存在一个script标签里(把标签的type属性设置为"text"),然后获取下来,并设置到TiledVectorLayer上,例如:

    <script type="text" id="cartoCssStr">
        @color:#111;
        #China_Railway_L___China400::one{
        line-color:@color;
        line-width:2;
        }
        #China_Railway_L___China400::two{
        line-dasharray:15,15;
        line-color:#DDDDDD;
        line-width:1.5;
        }
    </script>

    <script>
        var cartoCss=document.getElementById("cartoCssStr").text;
        layer.setCartoCSS(cartoCss);
    </script>

效果如下


此完整范例请见 示范程序->可视化->矢量分块->线符号。

三、其他示例


利用矢量分块地图,通过精心地对地图进行配色,以及其他地图风格的调整,我们可以配出一些精美的地图,以下即是利用矢量分块的客户端配图功能配出来的几种不同风格地图

  1、淡雅绿风格


此完整范例请见 示范程序->可视化->矢量分块->淡雅绿风格。

  2、月夜风格


此完整范例请见 示范程序->可视化->矢量分块->月夜风格。

  3、深夜蓝黑风格


此完整范例请见 示范程序->可视化->矢量分块->深夜蓝黑风格。

  4、强边界风格


此完整范例请见 示范程序->可视化->矢量分块->强边界风格。

版权所有 © 2000-2016  北京超图软件股份有限公司