前言:一直感覺(jué)不論OL還是arcgis 這個(gè)地圖聚類(lèi)是真的丑婿崭,實(shí)在讓人看不下去,反觀(guān)leaflet插件的的聚合效果那叫一個(gè)好看,個(gè)人感覺(jué)好看多了去了轮傍,那么把這個(gè)聚合效果用到OL上面去啊,這個(gè)是一個(gè)很好玩的事首装,本篇文章用到了自定義的聚類(lèi)的擴(kuò)展圖層创夜,感謝@牛老師源代碼啟發(fā),在此基礎(chǔ)上進(jìn)行進(jìn)一步的封裝仙逻。
先來(lái)張效果圖:
這張照片整的感覺(jué)都變形很多。其實(shí)一點(diǎn)沒(méi)變形
一、自定義擴(kuò)展圖層下載(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],//偏移量設(shè)置scale:0.7,//圖標(biāo)縮放比例opacity:0.75,//透明度src:'data/marker-icon.png'//圖標(biāo)的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 = [];//判斷該點(diǎn)是否聚合self._clusterTest =function(data, dataCluster){var_flag =false;var_cField = self.options.clusterField;if(_cField !="") {? ? ? ? _flag = data[_cField] === dataCluster[_cField];? ? }else{//將地理坐標(biāo)轉(zhuǎn)換成屏幕坐標(biāo)税手,進(jìn)行距離判斷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;? ? }//如果超過(guò)最大的縮放級(jí)別殿怜,數(shù)據(jù)全部展示var_zoom = self.options.map.getView().getZoom(),? ? ? ? _maxZoom = self.options.zooms[self.options.zooms.length -1];if(_zoom > _maxZoom) _flag =false;return_flag;};//坐標(biāo)轉(zhuǎn)換self._getCoordinate =function(lon, lat){returnol.proj.transform([parseFloat(lon),parseFloat(lat)],"EPSG:4326",? ? ? ? self.proj? ? );};//添加數(shù)據(jù)到聚合圖self._add2CluserData =function(index, data){? ? self.clusterData[index].cluster.push(data);};self._clusterCreate =function(data){? ? self.clusterData.push({data: data,cluster: []? ? });};//展示數(shù)據(jù)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? ? ? ? });//如果聚合點(diǎn)里面沒(méi)有數(shù)據(jù)就顯示該點(diǎn)數(shù)據(jù)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();//聲明一個(gè)矩形,范圍就是屏幕的四至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)) {//當(dāng)前點(diǎn)是否聚合挡篓,默認(rèn)是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);
下載地址:點(diǎn)我下載
二、demo示例
myClusterLayer圖層參數(shù)option
map是就當(dāng)前地圖容器
clusterField 該參數(shù)是,是否屬性聚合庄蹋,如果賦值僅需要賦屬性字段名即可
distance是聚合的距離(屏幕上距離)
data 是數(shù)據(jù)
style是樣式(不填就有默認(rèn)樣式)
{? ? ? ? ? ? ? ? ? ? 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);? ? ? ? ? ? })? ? ? ? }