ol4加载pbf矢量切片与样式定义

概述

看了一下mapbox的矢量切片的展示方式,其核心是定义的一个样式配置文件,我就在想:Ol4里面我是否通过styleFunction的方式实现同样的效果呢,折腾了一上午,别说,styleFunction真好用,在此分享出来,供大家参看。

mapbox的样式配置

如上图所示,mapbox的样式定义是通过一个这样的配置实现的,实现后效果如下:

openlayers4的样式配置

如上图所示,我是模仿mapbox的配置文件,并结合ol4的特性做了一部分修改。实现后效果如下:

实现

1、矢量切片

矢量切片是通过geoserver来实现的。实现可参考博客Geoserver2.11矢量切片与OL3中的调用展示。切片图层是一个layer group,如下图:

2、样式定义文件

{
    "province": [
        {
            "type": "polygon",
            "fill": {
                "color": "rgba(255, 0, 0, 0)"
            },
            "stroke": {
                "color": "#ccc",
                "width": "3",
                "dash": [
                    5,
                    5
                ]
            }
        }
    ],
    "lake": [
        {
            "type": "polygon",
            "fill": {
                "color": "rgba(0, 0, 255, .3)"
            },
            "stroke": {
                "color": "rgba(0, 0, 255, .75)",
                "width": "1"
            }
        }
    ],
    "river": [
        {
            "type": "line",
            "minZoom": 12,
            "maxZoom": 18,
            "stroke": {
                "color": "rgba(0,0,255,.2)",
                "width": "2"
            }
        }
    ],
    "road": [
        {
            "type": "line",
            "minZoom": 8,
            "maxZoom": 18,
            "stroke": {
                "color": "#ccc",
                "width": "2"
            }
        }
    ],
    "railway": [
        {
            "type": "line",
            "minZoom": 6,
            "maxZoom": 18,
            "stroke": {
                "color": "#ccc",
                "width": "6"
            }
        },
        {
            "type": "line",
            "minZoom": 6,
            "maxZoom": 18,
            "stroke": {
                "color": "white",
                "width": "2",
                "dash": [
                    5
                ]
            }
        }
    ],
    "capital": [
        {
            "type": "point",
            "size": 5,
            "fill": {
                "color": "rgba(255, 0, 0, .8)"
            },
            "stroke": {
                "color": "#f00",
                "width": "1"
            },
            "label": {
                "field": "name",
                "color": "balck",
                "font": "bold 13px 微软雅黑",
                "textAlign": "center",
                "textBaseline": "top",
                "offsetY": 6,
                "offsetX": 0
            }
        }
    ]
}

说明: 1、如上图所示,每一个图层对应一个样式配置; 2、样式配置是一个数组,主要是为了有些图层的复合样式考虑的,例如铁路的样式,实现后的效果如下:

3、样式函数

function getFillJson(data) {
    var json = {};
    if (data.color) json.color = data.color;
    return json;
}
function getStrokeJson(data) {
    var json = {};
    if (data.color) json.color = data.color;
    if (data.width) json.width = data.width;
    if (data.dash) json.lineDash = data.dash;
    return json;
}
function getMarkerJson(data) {
    var json = {};

    if (data.size) json.radius = data.size;

    var _fill = data.fill;
    if (_fill) json.fill = new ol.style.Fill(getFillJson(_fill));

    var _stroke = data.stroke;
    if (_stroke) json.stroke = new ol.style.Stroke(getStrokeJson(_stroke));

    return json;
}
function getLabelJson(data, feature) {
    var json = {};
    if (data.field) json.text = feature.get(data.field).toString();
    if (data.color) json.fill = new ol.style.Fill({
        color: data.color
    });
    if (data.textAlign) json.textAlign = data.textAlign;
    if (data.textBaseline) json.textBaseline = data.textBaseline;
    if (data.font) json.font = data.font;
    if (data.offsetX) json.offsetX = data.offsetX;
    if (data.offsetY) json.offsetY = data.offsetY;
    return json;
}

function styleFunction(feature) {
    var layer = feature.get("layer");
    var layerStyle = styleMap[layer];
    if (layerStyle) {
        var styles = [];
        for (var i = 0,
        len = layerStyle.length; i < len; i++) {
            var _styleData = layerStyle[i];
            var _zoom = map.getView().getZoom();
            if (_styleData.minZoom > _zoom || _styleData.maxZoom < _zoom) {
                return;
            } else {
                var _styleJson = {};
                switch (_styleData.type) {
                case "line":
                    {
                        var _stroke = _styleData.stroke;
                        if (_stroke) {
                            _styleJson.stroke = new ol.style.Stroke(getStrokeJson(_stroke));
                        }
                        break;
                    }
                case "polygon":
                    {
                        var _fill = _styleData.fill;
                        if (_fill) _styleJson.fill = new ol.style.Fill(getFillJson(_fill));

                        var _stroke = _styleData.stroke;
                        if (_stroke) _styleJson.stroke = new ol.style.Stroke(getStrokeJson(_stroke));

                        var _label = _styleData.label;
                        if (_label) _styleJson.text = new ol.style.Text(getLabelJson(_label, feature));
                        break;
                    }
                default:
                    {
                        _styleJson.image = new ol.style.Circle(getMarkerJson(_styleData));

                        var _label = _styleData.label;
                        if (_label) _styleJson.text = new ol.style.Text(getLabelJson(_label, feature));

                        break;
                    }
                }
                styles.push(new ol.style.Style(_styleJson));
            }
        }
        return styles;
    } else {
        return null;
    }
}

4、图层调用代码

var gridsetName = 'EPSG:900913';
var gridNames = ['EPSG:900913:0', 'EPSG:900913:1', 'EPSG:900913:2', 'EPSG:900913:3', 'EPSG:900913:4', 'EPSG:900913:5', 'EPSG:900913:6', 'EPSG:900913:7', 'EPSG:900913:8', 'EPSG:900913:9', 'EPSG:900913:10', 'EPSG:900913:11', 'EPSG:900913:12', 'EPSG:900913:13', 'EPSG:900913:14', 'EPSG:900913:15', 'EPSG:900913:16', 'EPSG:900913:17', 'EPSG:900913:18', 'EPSG:900913:19', 'EPSG:900913:20', 'EPSG:900913:21', 'EPSG:900913:22', 'EPSG:900913:23', 'EPSG:900913:24', 'EPSG:900913:25', 'EPSG:900913:26', 'EPSG:900913:27', 'EPSG:900913:28', 'EPSG:900913:29', 'EPSG:900913:30'];
var baseUrl = 'http://localhost:6080/geoserver/gwc/service/wmts';
var style = '';
var format = 'application/x-protobuf;type=mapbox-vector';
var layerName = 'layer_china';
var projection = new ol.proj.Projection({
    code: 'EPSG:900913',
    units: 'm',
    axisOrientation: 'neu'
});
var resolutions = [156543.03390625, 78271.516953125, 39135.7584765625, 19567.87923828125, 9783.939619140625, 4891.9698095703125, 2445.9849047851562, 1222.9924523925781, 611.4962261962891, 305.74811309814453, 152.87405654907226, 76.43702827453613, 38.218514137268066, 19.109257068634033, 9.554628534317017, 4.777314267158508, 2.388657133579254, 1.194328566789627, 0.5971642833948135, 0.29858214169740677, 0.14929107084870338, 0.07464553542435169, 0.037322767712175846, 0.018661383856087923, 0.009330691928043961, 0.004665345964021981, 0.0023326729820109904, 0.0011663364910054952, 5.831682455027476E-4, 2.915841227513738E-4, 1.457920613756869E-4];
params = {
    'REQUEST': 'GetTile',
    'SERVICE': 'WMTS',
    'VERSION': '1.0.0',
    'LAYER': layerName,
    'STYLE': style,
    'TILEMATRIX': gridsetName + ':{z}',
    'TILEMATRIXSET': gridsetName,
    'FORMAT': format,
    'TILECOL': '{x}',
    'TILEROW': '{y}'
};

function constructSource() {
    var url = baseUrl + '?'
    for (var param in params) {
        url = url + param + '=' + params[param] + '&';
    }
    url = url.slice(0, -1);

    var source = new ol.source.VectorTile({
        url: url,
        format: new ol.format.MVT({}),
        projection: projection,
        tileGrid: new ol.tilegrid.WMTS({
            tileSize: [256, 256],
            origin: [ - 2.003750834E7, 2.003750834E7],
            resolutions: resolutions,
            matrixIds: gridNames
        })
    });
    return source;
}

var layer = new ol.layer.VectorTile({
    source: constructSource(),
    renderMode: "hybrid",
    declutter: true,
    style: styleFunction
});

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Alice

一个layer可以跟着画完的线移动ios程序 好玩啊。

用法:采用的是关键帧实现的。    实验目的:让上层的layer子层能够跟着在另一个子层上花的线进行移动 。即当线画完之后,图形开始移动,并且能够停在最后的那个...

23460
来自专栏非典型技术宅

iOS动画系列之五:基础动画之缩放篇&旋转篇Swift+OC1. 思路和最终成果2. 抽取公共方法3. 懒加载Layer4. 添加动画

19010
来自专栏xx_Cc的学习总结专栏

iOS-视频播放器的简单封装

498110
来自专栏郭霖

Android高级图片滚动控件,编写3D版的图片轮播器

大家好,好久不见了,最近由于工作特别繁忙,已经有一个多月的时间没写博客了,我也是深感惭愧。那么今天的这篇既然是阔别了一个多月的文章,当然要带来更加给力点的内容了...

88480
来自专栏Sorrower的专栏

Android绘制(三):Path结合属性动画, 让图标动起来!

21820
来自专栏一“技”之长

设计iOS中随系统键盘弹收和内容文字长度自适应高度的文本框

    文本输入框是多数与社交相关的app中不可或缺的一个控件,这些文本输入框应该具备如下的功能:

11420
来自专栏格子的个人博客

Markdown语法学习记录

鉴于每次写博客,写文章的时候,总是要重复去查询Markdown的相关语法,这种闹心的感觉我再也不要了。

11820
来自专栏菩提树下的杨过

Flash/Flex学习笔记(28):动态文本的滚动控制

虽然label组件很好用,但是达人们都好象不太喜欢用组件(用组件后最明显的问题:会使swf文件增大好多),所以我也慢慢开始习惯能不用组件则尽量不用 import...

21750
来自专栏转载gongluck的CSDN博客

CListCtrl控件使用方法总结

今天第一次用CListCtrl控件,遇到不少问题,查了许多资料,现将用到的一些东西总结如下: 以下未经说明,listctrl默认view 风格为report ...

456130
来自专栏一“技”之长

AppleWatch开发入门九——Watch帧动画的实现

        动画一直是iOS系统的一大亮点,CoreAnimation和粒子效果的支持,开发者可以很容易的做出效果炫酷的动画特效。在watchOS中,由于性...

10220

扫码关注云+社区

领取腾讯云代金券