美文网首页GIS之家开源
openlayers入门开发系列之聚合图篇

openlayers入门开发系列之聚合图篇

作者: gis之家 | 来源:发表于2019-01-06 14:44 被阅读1次

    本篇的重点内容是利用openlayers实现聚合图功能,效果图如下:

    image

    实现思路

    • 界面设计
    //聚合图
    "<div style='height:25px;background:#30A4D5;margin-top:25px;width: 98%;margin-left: 3px;'>" +
                 "<span style='margin-left:5px;font-size: 13px;color:white;'>聚合图</span>" +
            "</div>" +
           '<div id="tool-ol-ClusterLayer" style="padding:5px;">' +
                '<div style="float:left;">' +
                '<input type="checkbox" name="tool-ol-ClusterLayer" style="width: 15px;height: 15px;vertical-align: middle;margin: auto;"/>' +
                '<label style="font-weight: normal;vertical-align: middle;margin: auto;">聚合图</label>' +
                '</div>' +
    '</div>'
    
    • 点击事件
    //加载聚合图
    $("#tool-ol-ClusterLayer input").bind("click", function () {
                if (this.checked) {
                    if(!bxmap.olClusterLayer.isLoad){
                        bxmap.olClusterLayer.Init(bmap);
                    }
                    else{
                        bxmap.olClusterLayer.showClusterLayer();
                    }
                }
                else {
                    bxmap.olClusterLayer.hideClusterLayer();
                }
    })
    
    • 初始化以及核心代码实现
    var bxmap = bxmap || {};
    bxmap.olClusterLayer = {
        map:null,
        isLoad:false,
        layer: null,//聚合图图层
        originalStyle:null,//聚合原始样式
        selectStyleFunction:null,
        Init:function(bmap){
            //加载聚合图
            this.map = bmap.getMap();
            this.isLoad = true;
            //设置原始样式
            this.originalStyle = new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 5,
                    stroke: new ol.style.Stroke({
                        color: '#fff'
                    }),
                    fill: new ol.style.Fill({
                        color: '#3399CC'
                    })
                })
            });
            this.initClusterLayer(qy);
        },
        /**
         * 初始化加载-聚合图
         */
        initClusterLayer:function(data){
            var num = data.features.length;
            if (num > 0) {
                var features = new Array(num);
                for (var i = 0; i < num; i++) {
                    var geo = data.features[i].geometry;
                    var coordinate = [geo.x, geo.y];
                    features[i] = new ol.Feature({
                        geometry: new ol.geom.Point(coordinate),
                        weight: data.features[i].attributes[field_dz]
                    });
                }
                this.loadClusterLayer(features,this.originalStyle);
            }
        },
        /**
         * 创建聚合图层
         * @method loadClusterLayer
         * @param  features 渲染聚合图层的要素集
         * @param  originalStyle图层的原始样式style
         * @return null
         */
        loadClusterLayer:function (features, originalStyle) {
            var self = bxmap.olClusterLayer;
            var maxFeatureCount, currentResolution;
            var textFill = new ol.style.Fill({
                color: '#fff'
            });
            var textStroke = new ol.style.Stroke({
                color: 'rgba(0, 0, 0, 0.6)',
                width: 3
            });
    
            var invisibleFill = new ol.style.Fill({
                color: 'rgba(255, 255, 255, 0.01)'
            });
            var earthquakeFill = new ol.style.Fill({
                color: 'rgba(255, 153, 0, 0.8)'
            });
            var earthquakeStroke = new ol.style.Stroke({
                color: 'rgba(255, 204, 0, 0.2)',
                width: 1
            });
            function createEarthquakeStyle(feature, style) {
                return new ol.style.Style({
                    geometry: feature.getGeometry(),
                    image: new ol.style.Circle({
                        radius: 5,
                        stroke: new ol.style.Stroke({
                            color: '#fff'
                        }),
                        fill: new ol.style.Fill({
                            color: '#3399CC'
                        })
                    })
                });
            }
            /*
             *选中样式
            */
            function selectStyleFunction(feature) {
                var styles = [new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: feature.get('radius'),
                        fill: invisibleFill
                    })
                })];
                var originalFeatures = feature.get('features');
                var originalFeature;
                for (var i = originalFeatures.length - 1; i >= 0; --i) {
                    originalFeature = originalFeatures[i];
                    styles.push(createEarthquakeStyle(originalFeature, originalStyle));
                }
                return styles;
            }
            /*
             *设置没有聚合效果的原始样式
             */
            function createOriginalStyle(feature) {
                return new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 8,
                        stroke: new ol.style.Stroke({
                            color: '#fff'
                        }),
                        fill: new ol.style.Fill({
                            color: '#3399CC'
                        })
                    })
                });
            }
            /*
             *计算每个聚合点的半径大小
             */
            function calculateClusterInfo(resolution) {
                maxFeatureCount = 0;
                var features = self.layer.getSource().getFeatures();
                var feature, radius;
                for (var i = features.length - 1; i >= 0; --i) {
                    feature = features[i];
                    var originalFeatures = feature.get('features');
                    var extent = ol.extent.createEmpty();
                    var j, jj;
                    for (j = 0, jj = originalFeatures.length; j < jj; ++j) {
                        ol.extent.extend(extent, originalFeatures[j].getGeometry().getExtent());
                    }
                    maxFeatureCount = Math.max(maxFeatureCount, jj);
                    radius = 0.25 * (ol.extent.getWidth(extent) + ol.extent.getHeight(extent)) /
                        resolution;
                    feature.set('radius', radius);
                }
            }
            /*
             *设置聚合样式
             */
            function styleFunction(feature, resolution) {
                //计算每个聚合点的半径大小
                if (resolution != currentResolution) {
                    calculateClusterInfo(resolution);
                    currentResolution = resolution;
                }
                var style;
                var size = feature.get('features').length;//每个点当前的聚合点数
                if (size > 1) {//设置聚合效果样式
                    style = new ol.style.Style({
                        image: new ol.style.Circle({
                            radius: feature.get('radius'),//获取聚合圆圈的半径大小,聚合的点数越多,圆圈的半径越大
                            fill: new ol.style.Fill({
                                color: [255, 153, 0, Math.min(0.8, 0.4 + (size / maxFeatureCount))]
                            })
                        }),
                        text: new ol.style.Text({
                            text: size.toString(),
                            fill: textFill,
                            stroke: textStroke
                        })
                    });
                } else {//设置没有聚合效果的原始样式
                    style = originalStyle;
                }
                return style;
            }
            self.layer = new ol.layer.Vector({
                source: new ol.source.Cluster({//矢量图层的数据源为聚合类型
                    distance: 40,//聚合距离
                    source: new ol.source.Vector({//聚合数据来源
                        features: features
                    })
                }),
                style: styleFunction//聚合样式
            });
            self.selectStyleFunction = selectStyleFunction;
            self.map.addLayer(self.layer);
            //缩放至范围
            self.map.getView().setCenter([12637973.949997703, 2657176.0178779177]);
            self.map.getView().setZoom(10);
        },
        showClusterLayer:function(){
            var self = bxmap.olClusterLayer;
            if (self.layer) {
                self.layer.setVisible(true);
                //缩放至范围
                self.map.getView().setCenter([12637973.949997703, 2657176.0178779177]);
                self.map.getView().setZoom(10);
            }
        },
        hideClusterLayer:function(){
            var self = bxmap.olClusterLayer;
            if (self.layer) {
                self.layer.setVisible(false);
            }
        }
    
    }
    

    GIS之家作品:GIS之家
    GIS之家在线咨询:在线咨询

    相关文章

      网友评论

        本文标题:openlayers入门开发系列之聚合图篇

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