美文网首页GIS加油站GIS相关
ol4加载pbf矢量切片与样式定义

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

作者: 牛老师讲webgis | 来源:发表于2018-08-10 17:24 被阅读22次

    概述

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

    mapbox的样式配置

    mapbox样式配置

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


    mapbox加载效果

    openlayers4的样式配置

    Ol样式配置

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


    ol加载效果

    实现

    1、矢量切片

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

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

    技术博客
    CSDN:http://blog.csdn.NET/gisshixisheng
    在线教程
    https://edu.csdn.net/course/detail/799
    https://edu.csdn.net/course/detail/7471
    联系方式

    类型 内容
    qq 1004740957
    公众号 lzugis15
    e-mail niujp08@qq.com
    webgis群 452117357
    Android群 337469080
    GIS数据可视化群 458292378

    “GIS讲堂”知识星球开通了,在星球,我将提供一对一的问答服务,你问我答,期待与你相见。


    知识星球二维码 LZUGIS

    相关文章

      网友评论

        本文标题:ol4加载pbf矢量切片与样式定义

        本文链接:https://www.haomeiwen.com/subject/tsllbftx.html