openlayers入门开发系列之聚合图篇
2019-01-06 本文已影响1人
gis之家
本篇的重点内容是利用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);
}
}
}