OpenLayer4实现自定义地图聚类图层

前言:一直感觉不论OL还是arcgis 这个地图聚类是真的丑,实在让人看不下去,反观leaflet插件的的聚合效果那叫一个好看,个人感觉好看多了去了,那么把这个聚合效果用到OL上面去啊,这个是一个很好玩的事,本篇文章用到了自定义的聚类的扩展图层,感谢@牛老师源代码启发,在此基础上进行进一步的封装。

先来张效果图:

这张照片整的感觉都变形很多。其实一点没变形

一、自定义扩展图层下载(github)

ol.layer.myClusterLayer =function(options){varself =this;self.styleFunc =function(feat){varattribute = feat.get("attribute");varcount = attribute.cluster.length;if(count <1) {varname = attribute.data.name;returnnewol.style.Style({image:newol.style.Icon(/** @type {olx.style.IconOptions} */({anchor: [0.5,60],anchorOrigin:'top-right',anchorXUnits:'fraction',anchorYUnits:'pixels',offsetOrigin:'top-right',offset: [0,1],//偏移量设置scale:0.7,//图标缩放比例opacity:0.75,//透明度src:'data/marker-icon.png'//图标的url})),text:newol.style.Text({text: name,fill:newol.style.Fill({color:'#000000'}),textAlign:"left",offsetX:5,textBaseline:"middle"})        })    }else{var_smallCorlor;var_bigCorlor;if(count <100) {if(count >50) {                _smallCorlor ="#f0cd41";                _bigCorlor ="#f5de8b";            }else{                _smallCorlor ="#94d769";                _bigCorlor ="#cde7b1";            }        }else{            _smallCorlor ='#f1964d';            _bigCorlor ="#f9bda2";        }        count++;        count = count.toString();varsmallRadius = count.length *10;        smallRadius = smallRadius <10?12: smallRadius ;varbigRadius = smallRadius +5;return[newol.style.Style({image:newol.style.Circle({radius: bigRadius,fill:newol.style.Fill({color: _bigCorlor                    })                }),            }),newol.style.Style({image:newol.style.Circle({radius: smallRadius,fill:newol.style.Fill({color: _smallCorlor                    })                }),text:newol.style.Text({text: count,fill:newol.style.Fill({color:'#620022'}),textAlign:"center",textBaseline:"middle"})            }),        ]    }}vardefaults = {map:null,clusterField:"",zooms: [2,4,8,12],distance:256,data: [],style: self.styleFunc,};//将default和options合并self.options = {map: options.map,clusterField: options.clusterField,zooms: (options.zooms.length >0? options.zooms : defaults.zooms),distance: (options.distance >0? options.distance : defaults.distance),data: options.data,style:(options.style!=null?options.style:defaults.style)}self.proj = self.options.map.getView().getProjection();self.vectorSource =newol.source.Vector({features: []});self.vectorLayer =newol.layer.Vector({source: self.vectorSource,style: self.options.style});self.clusterData = [];//判断该点是否聚合self._clusterTest =function(data, dataCluster){var_flag =false;var_cField = self.options.clusterField;if(_cField !="") {        _flag = data[_cField] === dataCluster[_cField];    }else{//将地理坐标转换成屏幕坐标,进行距离判断var_dataCoord = self._getCoordinate(data.lon, data.lat),            _cdataCoord = self._getCoordinate(dataCluster.lon, dataCluster.lat);var_dataScrCoord = self.options.map.getPixelFromCoordinate(_dataCoord),            _cdataScrCoord = self.options.map.getPixelFromCoordinate(_cdataCoord);var_distance =Math.sqrt(Math.pow((_dataScrCoord[0] - _cdataScrCoord[0]),2) +Math.pow((_dataScrCoord[1] - _cdataScrCoord[1]),2)        );        _flag = _distance <= self.options.distance;    }//如果超过最大的缩放级别,数据全部展示var_zoom = self.options.map.getView().getZoom(),        _maxZoom = self.options.zooms[self.options.zooms.length -1];if(_zoom > _maxZoom) _flag =false;return_flag;};//坐标转换self._getCoordinate =function(lon, lat){returnol.proj.transform([parseFloat(lon),parseFloat(lat)],"EPSG:4326",        self.proj    );};//添加数据到聚合图self._add2CluserData =function(index, data){    self.clusterData[index].cluster.push(data);};self._clusterCreate =function(data){    self.clusterData.push({data: data,cluster: []    });};//展示数据self._showCluster =function(){    self.vectorSource.clear();var_features = [];for(vari =0, len = self.clusterData.length; i < len; i++) {var_cdata = self.clusterData[i];var_coord = self._getCoordinate(_cdata.data.lon, _cdata.data.lat);var_feature =newol.Feature({geometry:newol.geom.Point(_coord),attribute: _cdata        });//如果聚合点里面没有数据就显示该点数据if(_cdata.cluster.length ===0) _feature.attr = _feature.data;        _features.push(_feature);    }    self.vectorSource.addFeatures(_features);};self._clusterFeatures =function(){    self.clusterData = [];//可视域处理var_viewExtent = self.options.map.getView().calculateExtent();//声明一个矩形,范围就是屏幕的四至var_viewGeom =newol.geom.Polygon.fromExtent(_viewExtent);for(vari =0, ilen = self.options.data.length; i < ilen; i++) {var_data = self.options.data[i];var_coord = self._getCoordinate(_data.lon, _data.lat);if(_viewGeom.intersectsCoordinate(_coord)) {//当前点是否聚合,默认是falsevar_clustered =false;for(varj =0, jlen = self.clusterData.length; j < jlen; j++) {var_cdata = self.clusterData[j];if(self._clusterTest(_data, _cdata.data)) {                    self._add2CluserData(j, _data);                    _clustered =true;break;                }            }if(!_clustered) {                self._clusterCreate(_data);            }        }    }    self.vectorSource.clear();    self._showCluster();};self.init =function(){    self._clusterFeatures();    self.options.map.on("moveend",function(){        self._clusterFeatures();    });};self.init();returnself.vectorLayer;};ol.inherits(ol.layer.myClusterLayer, ol.layer.Vector);

下载地址:点我下载

二、demo示例

myClusterLayer图层参数option

map是就当前地图容器

clusterField 该参数是,是否属性聚合,如果赋值仅需要赋属性字段名即可

distance是聚合的距离(屏幕上距离)

data 是数据

style是样式(不填就有默认样式)

{                    map:map,                    clusterField:"",                    zooms:[12],                    distance:100,                    data:result,                    style:null}

clusterbody,#map{border:0px;margin:0px;padding:0px;width:100%;height:100%;font-size:13px;overflow: hidden;        }varmap;functioninit(){varprojection =newol.proj.Projection({code:'EPSG:4326',units:'degrees'});functiongetNavmapLayer(){returnnewol.layer.Tile({source:newol.source.XYZ({url:'http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8'//7,8}),projection: projection                });            }varnavlayer = getNavmapLayer();            map =newol.Map({controls: ol.control.defaults({attribution:false}),target:'map',layers: [navlayer],view:newol.View({projection: projection,center: [116.456,40.251],zoom:4})            });            $.get("data/data.json",function(result){varmycluster =newol.layer.myClusterLayer({map: map,clusterField:"",zooms: [12],distance:100,data: result,style:null});                map.addLayer(mycluster);            })        }

你可能感兴趣的:(OpenLayer4实现自定义地图聚类图层)