From b5206cb354955adb1a4609d68eff62ea5f89c8eb Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 12 Feb 2015 13:43:46 +0100 Subject: [PATCH 1/3] Make ol.layer.Heatmap.createCircle_ an instance function --- src/ol/layer/heatmaplayer.js | 38 ++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/ol/layer/heatmaplayer.js b/src/ol/layer/heatmaplayer.js index e14c9d1fc6..a3469e727a 100644 --- a/src/ol/layer/heatmaplayer.js +++ b/src/ol/layer/heatmaplayer.js @@ -52,6 +52,24 @@ ol.layer.Heatmap = function(opt_options) { */ this.gradient_ = null; + /** + * @private + * @type {number} + */ + this.blur_ = goog.isDef(options.blur) ? options.blur : 15; + + /** + * @private + * @type {number} + */ + this.radius_ = goog.isDef(options.radius) ? options.radius : 8; + + /** + * @private + * @type {number} + */ + this.shadow_ = goog.isDef(options.shadow) ? options.shadow : 250; + goog.events.listen(this, ol.Object.getChangeEventType(ol.layer.HeatmapLayerProperty.GRADIENT), this.handleGradientChanged_, false, this); @@ -59,10 +77,7 @@ ol.layer.Heatmap = function(opt_options) { this.setGradient(goog.isDef(options.gradient) ? options.gradient : ol.layer.Heatmap.DEFAULT_GRADIENT); - var circle = ol.layer.Heatmap.createCircle_( - goog.isDef(options.radius) ? options.radius : 8, - goog.isDef(options.blur) ? options.blur : 15, - goog.isDef(options.shadow) ? options.shadow : 250); + var circle = this.createCircle_(); /** * @type {Array.>} @@ -142,22 +157,19 @@ ol.layer.Heatmap.createGradient_ = function(colors) { /** - * @param {number} radius Radius size in pixel. - * @param {number} blur Blur size in pixel. - * @param {number} shadow Shadow offset size in pixel. * @return {string} * @private */ -ol.layer.Heatmap.createCircle_ = function(radius, blur, shadow) { - var halfSize = radius + blur + 1; +ol.layer.Heatmap.prototype.createCircle_ = function() { + var halfSize = this.radius_ + this.blur_ + 1; var size = 2 * halfSize; var context = ol.dom.createCanvasContext2D(size, size); - context.shadowOffsetX = context.shadowOffsetY = shadow; - context.shadowBlur = blur; + context.shadowOffsetX = context.shadowOffsetY = this.shadow_; + context.shadowBlur = this.blur_; context.shadowColor = '#000'; context.beginPath(); - var center = halfSize - shadow; - context.arc(center, center, radius, 0, Math.PI * 2, true); + var center = halfSize - this.shadow_; + context.arc(center, center, this.radius_, 0, Math.PI * 2, true); context.fill(); return context.canvas.toDataURL(); }; From dfda3e37a4cc9c5d06049eb3a79283e44543079b Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 12 Feb 2015 14:16:48 +0100 Subject: [PATCH 2/3] Add ol.layer.Heatmap#radius getter and setter --- src/ol/layer/heatmaplayer.js | 79 ++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/src/ol/layer/heatmaplayer.js b/src/ol/layer/heatmaplayer.js index a3469e727a..dd65d7906b 100644 --- a/src/ol/layer/heatmaplayer.js +++ b/src/ol/layer/heatmaplayer.js @@ -16,7 +16,8 @@ goog.require('ol.style.Style'); * @enum {string} */ ol.layer.HeatmapLayerProperty = { - GRADIENT: 'gradient' + GRADIENT: 'gradient', + RADIUS: 'radius' }; @@ -62,27 +63,32 @@ ol.layer.Heatmap = function(opt_options) { * @private * @type {number} */ - this.radius_ = goog.isDef(options.radius) ? options.radius : 8; + this.shadow_ = goog.isDef(options.shadow) ? options.shadow : 250; /** * @private - * @type {number} + * @type {string|undefined} */ - this.shadow_ = goog.isDef(options.shadow) ? options.shadow : 250; + this.circleImage_ = undefined; + + /** + * @private + * @type {Array.>} + */ + this.styleCache_ = null; goog.events.listen(this, ol.Object.getChangeEventType(ol.layer.HeatmapLayerProperty.GRADIENT), this.handleGradientChanged_, false, this); + goog.events.listen(this, + ol.Object.getChangeEventType(ol.layer.HeatmapLayerProperty.RADIUS), + this.handleStyleChanged_, false, this); + this.setGradient(goog.isDef(options.gradient) ? options.gradient : ol.layer.Heatmap.DEFAULT_GRADIENT); - var circle = this.createCircle_(); - - /** - * @type {Array.>} - */ - var styleCache = new Array(256); + this.setRadius(goog.isDef(options.radius) ? options.radius : 8); var weight = goog.isDef(options.weight) ? options.weight : 'weight'; var weightFunction; @@ -95,25 +101,25 @@ ol.layer.Heatmap = function(opt_options) { } goog.asserts.assert(goog.isFunction(weightFunction)); - this.setStyle(function(feature, resolution) { + this.setStyle(goog.bind(function(feature, resolution) { var weight = weightFunction(feature); var opacity = goog.isDef(weight) ? goog.math.clamp(weight, 0, 1) : 1; // cast to 8 bits var index = (255 * opacity) | 0; - var style = styleCache[index]; + var style = this.styleCache_[index]; if (!goog.isDef(style)) { style = [ new ol.style.Style({ image: new ol.style.Icon({ opacity: opacity, - src: circle + src: this.circleImage_ }) }) ]; - styleCache[index] = style; + this.styleCache_[index] = style; } return style; - }); + }, this)); // For performance reasons, don't sort the features before rendering. // The render order is not relevant for a heatmap representation. @@ -161,7 +167,8 @@ ol.layer.Heatmap.createGradient_ = function(colors) { * @private */ ol.layer.Heatmap.prototype.createCircle_ = function() { - var halfSize = this.radius_ + this.blur_ + 1; + var radius = this.getRadius(); + var halfSize = radius + this.blur_ + 1; var size = 2 * halfSize; var context = ol.dom.createCanvasContext2D(size, size); context.shadowOffsetX = context.shadowOffsetY = this.shadow_; @@ -169,7 +176,7 @@ ol.layer.Heatmap.prototype.createCircle_ = function() { context.shadowColor = '#000'; context.beginPath(); var center = halfSize - this.shadow_; - context.arc(center, center, this.radius_, 0, Math.PI * 2, true); + context.arc(center, center, radius, 0, Math.PI * 2, true); context.fill(); return context.canvas.toDataURL(); }; @@ -190,6 +197,20 @@ goog.exportProperty( ol.layer.Heatmap.prototype.getGradient); +/** + * @return {number} Radius size in pixel. + * @api + * @observable + */ +ol.layer.Heatmap.prototype.getRadius = function() { + return /** @type {number} */ (this.get(ol.layer.HeatmapLayerProperty.RADIUS)); +}; +goog.exportProperty( + ol.layer.Heatmap.prototype, + 'getRadius', + ol.layer.Heatmap.prototype.getRadius); + + /** * @private */ @@ -198,6 +219,16 @@ ol.layer.Heatmap.prototype.handleGradientChanged_ = function() { }; +/** + * @private + */ +ol.layer.Heatmap.prototype.handleStyleChanged_ = function() { + this.circleImage_ = this.createCircle_(); + this.styleCache_ = new Array(256); + this.changed(); +}; + + /** * @param {ol.render.Event} event Post compose event * @private @@ -233,3 +264,17 @@ goog.exportProperty( ol.layer.Heatmap.prototype, 'setGradient', ol.layer.Heatmap.prototype.setGradient); + + +/** + * @param {number} radius Radius size in pixel. + * @api + * @observable + */ +ol.layer.Heatmap.prototype.setRadius = function(radius) { + this.set(ol.layer.HeatmapLayerProperty.RADIUS, radius); +}; +goog.exportProperty( + ol.layer.Heatmap.prototype, + 'setRadius', + ol.layer.Heatmap.prototype.setRadius); From f11755069424c73567229ecf2514c911f6064065 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 12 Feb 2015 14:20:49 +0100 Subject: [PATCH 3/3] Add a radius input to the heatmap-earthquakes example --- examples/heatmap-earthquakes.html | 11 +++++++++-- examples/heatmap-earthquakes.js | 8 +++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/examples/heatmap-earthquakes.html b/examples/heatmap-earthquakes.html index 1f6a294198..d6ec6f8899 100644 --- a/examples/heatmap-earthquakes.html +++ b/examples/heatmap-earthquakes.html @@ -29,7 +29,7 @@
-
+

Earthquakes heatmap

Demonstrates the use of a heatmap layer.

@@ -40,8 +40,15 @@
heatmap, kml, vector, style
-
+
+
+ + +
+
+ +
diff --git a/examples/heatmap-earthquakes.js b/examples/heatmap-earthquakes.js index e28ce927b1..0e41408931 100644 --- a/examples/heatmap-earthquakes.js +++ b/examples/heatmap-earthquakes.js @@ -5,6 +5,7 @@ goog.require('ol.layer.Tile'); goog.require('ol.source.KML'); goog.require('ol.source.Stamen'); +var radius = $('#radius'); var vector = new ol.layer.Heatmap({ source: new ol.source.KML({ @@ -12,7 +13,7 @@ var vector = new ol.layer.Heatmap({ projection: 'EPSG:3857', url: 'data/kml/2012_Earthquakes_Mag5.kml' }), - radius: 5 + radius: parseInt(radius.val(), 10) }); vector.getSource().on('addfeature', function(event) { @@ -38,3 +39,8 @@ var map = new ol.Map({ zoom: 2 }) }); + + +radius.on('input', function() { + vector.setRadius(parseInt(radius.val(), 10)); +});