1. 程式人生 > >openlayers入門開發系列之聚合圖篇

openlayers入門開發系列之聚合圖篇

本篇的重點內容是利用openlayers實現聚合圖功能,效果圖如下:

實現思路

  • 介面設計
//聚合圖
"<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); } } }