diff --git a/src/ol/feature.js b/src/ol/feature.js index e4200c70d4..63127bb16b 100644 --- a/src/ol/feature.js +++ b/src/ol/feature.js @@ -5,16 +5,24 @@ goog.require('goog.events'); goog.require('goog.events.EventType'); goog.require('ol.Object'); goog.require('ol.geom.Geometry'); +goog.require('ol.style.Style'); /** * @enum {string} */ ol.FeatureProperty = { - GEOMETRY: 'geometry' + GEOMETRY: 'geometry', + STYLE_FUNCTION: 'styleFunction' }; +/** + * @typedef {function(this: ol.Feature, number): Array.} + */ +ol.FeatureStyleFunction; + + /** * @constructor @@ -47,6 +55,9 @@ ol.Feature = function(opt_geometryOrValues) { goog.events.listen( this, ol.Object.getChangeEventType(ol.FeatureProperty.GEOMETRY), this.handleGeometryChanged_, false, this); + goog.events.listen( + this, ol.Object.getChangeEventType(ol.FeatureProperty.STYLE_FUNCTION), + this.handleStyleFunctionChange_, false, this); if (goog.isDefAndNotNull(opt_geometryOrValues)) { if (opt_geometryOrValues instanceof ol.geom.Geometry) { @@ -102,6 +113,19 @@ ol.Feature.prototype.getRevision = function() { }; +/** + * @return {ol.FeatureStyleFunction|undefined} Style function. + */ +ol.Feature.prototype.getStyleFunction = function() { + return /** @type {ol.FeatureStyleFunction|undefined} */ ( + this.get(ol.FeatureProperty.STYLE_FUNCTION)); +}; +goog.exportProperty( + ol.Feature.prototype, + 'getStyleFunction', + ol.Feature.prototype.getStyleFunction); + + /** * @private */ @@ -127,6 +151,14 @@ ol.Feature.prototype.handleGeometryChanged_ = function() { }; +/** + * @private + */ +ol.Feature.prototype.handleStyleFunctionChange_ = function() { + this.dispatchChangeEvent(); +}; + + /** * @param {ol.geom.Geometry|undefined} geometry Geometry. */ @@ -139,6 +171,18 @@ goog.exportProperty( ol.Feature.prototype.setGeometry); +/** + * @param {ol.FeatureStyleFunction|undefined} styleFunction Style function. + */ +ol.Feature.prototype.setStyleFunction = function(styleFunction) { + this.set(ol.FeatureProperty.STYLE_FUNCTION, styleFunction); +}; +goog.exportProperty( + ol.Feature.prototype, + 'setStyleFunction', + ol.Feature.prototype.setStyleFunction); + + /** * @param {number|string|undefined} id Id. */ diff --git a/src/ol/layer/vectorlayer.js b/src/ol/layer/vectorlayer.js index e9a9290119..35e5cd535c 100644 --- a/src/ol/layer/vectorlayer.js +++ b/src/ol/layer/vectorlayer.js @@ -35,6 +35,21 @@ ol.layer.Vector = function(opt_options) { goog.inherits(ol.layer.Vector, ol.layer.Layer); +/** + * @param {ol.Feature} feature Feature. + * @param {number} resolution Resolution. + * @return {Array.} Styles. + */ +ol.layer.Vector.defaultStyleFunction = function(feature, resolution) { + var featureStyleFunction = feature.getStyleFunction(); + if (goog.isDef(featureStyleFunction)) { + return featureStyleFunction.call(feature, resolution); + } else { + return null; + } +}; + + /** * @return {function(ol.geom.Geometry): boolean|undefined} Render geometry * function. diff --git a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js index ba41325eca..1061501efb 100644 --- a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js +++ b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js @@ -6,6 +6,7 @@ goog.require('goog.events.EventType'); goog.require('goog.functions'); goog.require('ol.ViewHint'); goog.require('ol.extent'); +goog.require('ol.layer.Vector'); goog.require('ol.render.canvas.ReplayGroup'); goog.require('ol.renderer.canvas.Layer'); goog.require('ol.renderer.vector'); @@ -194,6 +195,9 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = this.dirty_ = false; var styleFunction = vectorLayer.getStyleFunction(); + if (!goog.isDef(styleFunction)) { + styleFunction = ol.layer.Vector.defaultStyleFunction; + } var replayGroup = new ol.render.canvas.ReplayGroup(); vectorSource.forEachFeatureInExtent(extent, /** @@ -227,6 +231,10 @@ ol.renderer.canvas.VectorLayer.prototype.renderFeature = function(feature, resolution, styleFunction, replayGroup) { var loading = false; var styles = styleFunction(feature, resolution); + // FIXME if styles is null, should we use the default style? + if (!goog.isDefAndNotNull(styles)) { + return false; + } // simplify to a tolerance of half a CSS pixel var squaredTolerance = resolution * resolution / 4; var i, ii, style, imageStyle, imageState; diff --git a/src/ol/style/fillstyle.js b/src/ol/style/fillstyle.js index 438af2e496..78a4ddf59e 100644 --- a/src/ol/style/fillstyle.js +++ b/src/ol/style/fillstyle.js @@ -6,9 +6,11 @@ goog.require('ol.color'); /** * @constructor - * @param {olx.style.FillOptions} options Options. + * @param {olx.style.FillOptions=} opt_options Options. */ -ol.style.Fill = function(options) { +ol.style.Fill = function(opt_options) { + + var options = goog.isDef(opt_options) ? opt_options : {}; /** * @type {ol.Color|string} diff --git a/src/ol/style/imagestyle.js b/src/ol/style/imagestyle.js index 4322dcf9a9..98087746b9 100644 --- a/src/ol/style/imagestyle.js +++ b/src/ol/style/imagestyle.js @@ -24,10 +24,12 @@ ol.style.ImageState = { /** * @constructor - * @param {olx.style.ImageOptions} options Options. + * @param {olx.style.ImageOptions=} opt_options Options. * @extends {goog.events.EventTarget} */ -ol.style.Image = function(options) { +ol.style.Image = function(opt_options) { + + var options = goog.isDef(opt_options) ? opt_options : {}; goog.base(this); diff --git a/src/ol/style/strokestyle.js b/src/ol/style/strokestyle.js index fc5575eff1..7363fd3a2f 100644 --- a/src/ol/style/strokestyle.js +++ b/src/ol/style/strokestyle.js @@ -6,9 +6,11 @@ goog.require('ol.color'); /** * @constructor - * @param {olx.style.StrokeOptions} options Options. + * @param {olx.style.StrokeOptions=} opt_options Options. */ -ol.style.Stroke = function(options) { +ol.style.Stroke = function(opt_options) { + + var options = goog.isDef(opt_options) ? opt_options : {}; /** * @type {ol.Color|string} diff --git a/src/ol/style/style.js b/src/ol/style/style.js index d6e26decac..ebe3360482 100644 --- a/src/ol/style/style.js +++ b/src/ol/style/style.js @@ -8,10 +8,12 @@ goog.require('ol.style.Image'); /** * @constructor - * @param {olx.style.StyleOptions} options Style options. + * @param {olx.style.StyleOptions=} opt_options Style options. * @todo stability experimental */ -ol.style.Style = function(options) { +ol.style.Style = function(opt_options) { + + var options = goog.isDef(opt_options) ? opt_options : {}; /** * @type {ol.style.Fill} diff --git a/src/ol/style/textstyle.js b/src/ol/style/textstyle.js index 6e6d6b9b6c..a2a7851897 100644 --- a/src/ol/style/textstyle.js +++ b/src/ol/style/textstyle.js @@ -4,9 +4,11 @@ goog.provide('ol.style.Text'); /** * @constructor - * @param {olx.style.TextOptions} options Options. + * @param {olx.style.TextOptions=} opt_options Options. */ -ol.style.Text = function(options) { +ol.style.Text = function(opt_options) { + + var options = goog.isDef(opt_options) ? opt_options : {}; /** * @type {string|undefined}