diff --git a/examples/drag-and-drop-image-vector.js b/examples/drag-and-drop-image-vector.js
index 6c65270335..7aa470eea9 100644
--- a/examples/drag-and-drop-image-vector.js
+++ b/examples/drag-and-drop-image-vector.js
@@ -121,7 +121,7 @@ dragAndDropInteraction.on('addfeatures', function(event) {
map.getLayers().push(new ol.layer.Image({
source: new ol.source.ImageVector({
source: vectorSource,
- styleFunction: styleFunction
+ style: styleFunction
})
}));
var view2D = map.getView().getView2D();
diff --git a/examples/drag-and-drop.js b/examples/drag-and-drop.js
index 4e39605838..aa3e6f2fa9 100644
--- a/examples/drag-and-drop.js
+++ b/examples/drag-and-drop.js
@@ -118,7 +118,7 @@ dragAndDropInteraction.on('addfeatures', function(event) {
});
map.getLayers().push(new ol.layer.Vector({
source: vectorSource,
- styleFunction: styleFunction
+ style: styleFunction
}));
var view2D = map.getView().getView2D();
view2D.fitExtent(vectorSource.getExtent(), map.getSize());
diff --git a/examples/draw-features.js b/examples/draw-features.js
index 19415de98f..88a09399b5 100644
--- a/examples/draw-features.js
+++ b/examples/draw-features.js
@@ -15,29 +15,25 @@ var raster = new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'sat'})
});
-var styleArray = [new ol.style.Style({
- fill: new ol.style.Fill({
- color: 'rgba(255, 255, 255, 0.2)'
- }),
- stroke: new ol.style.Stroke({
- color: '#ffcc33',
- width: 2
- }),
- image: new ol.style.Circle({
- radius: 7,
- fill: new ol.style.Fill({
- color: '#ffcc33'
- })
- })
-})];
-
var source = new ol.source.Vector();
var vector = new ol.layer.Vector({
source: source,
- styleFunction: function(feature, resolution) {
- return styleArray;
- }
+ style: new ol.style.Style({
+ fill: new ol.style.Fill({
+ color: 'rgba(255, 255, 255, 0.2)'
+ }),
+ stroke: new ol.style.Stroke({
+ color: '#ffcc33',
+ width: 2
+ }),
+ image: new ol.style.Circle({
+ radius: 7,
+ fill: new ol.style.Fill({
+ color: '#ffcc33'
+ })
+ })
+ })
});
var map = new ol.Map({
diff --git a/examples/geojson.js b/examples/geojson.js
index f8146d1000..9889d08d3e 100644
--- a/examples/geojson.js
+++ b/examples/geojson.js
@@ -177,7 +177,7 @@ vectorSource.addFeature(new ol.Feature(new ol.geom.Circle([5e6, 7e6], 1e6)));
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
- styleFunction: styleFunction
+ style: styleFunction
});
var map = new ol.Map({
diff --git a/examples/google-map.js b/examples/google-map.js
index 83c18c7016..f6dd0a6994 100644
--- a/examples/google-map.js
+++ b/examples/google-map.js
@@ -34,20 +34,15 @@ google.maps.event.addListenerOnce(gmap, 'tilesloaded', function() {
url: 'data/geojson/countries.geojson',
projection: 'EPSG:3857'
}),
- styleFunction: (function() {
- var styleArray = [new ol.style.Style({
- fill: new ol.style.Fill({
- color: 'rgba(255, 255, 255, 0.6)'
- }),
- stroke: new ol.style.Stroke({
- color: '#319FD3',
- width: 1
- })
- })];
- return function(feature, resolution) {
- return styleArray;
- };
- }())
+ style: new ol.style.Style({
+ fill: new ol.style.Fill({
+ color: 'rgba(255, 255, 255, 0.6)'
+ }),
+ stroke: new ol.style.Stroke({
+ color: '#319FD3',
+ width: 1
+ })
+ })
});
var center = gmap.getCenter();
diff --git a/examples/gpx.js b/examples/gpx.js
index 438811d93c..b0f1c9294d 100644
--- a/examples/gpx.js
+++ b/examples/gpx.js
@@ -48,7 +48,7 @@ var vector = new ol.layer.Vector({
projection: 'EPSG:3857',
url: 'data/gpx/fells_loop.gpx'
}),
- styleFunction: function(feature, resolution) {
+ style: function(feature, resolution) {
return style[feature.getGeometry().getType()];
}
});
diff --git a/examples/icon.js b/examples/icon.js
index 7b1f6af21b..bdb89645e5 100644
--- a/examples/icon.js
+++ b/examples/icon.js
@@ -18,19 +18,17 @@ var iconFeature = new ol.Feature({
rainfall: 500
});
-var styleArray = [new ol.style.Style({
+var iconStyle = new ol.style.Style({
image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'data/icon.png'
}))
-})];
-
-iconFeature.setStyleFunction(function(resolution) {
- return styleArray;
});
+iconFeature.setStyle(iconStyle);
+
var vectorSource = new ol.source.Vector({
features: [iconFeature]
});
diff --git a/examples/igc.js b/examples/igc.js
index 7ab9d9fa49..a0fd613f60 100644
--- a/examples/igc.js
+++ b/examples/igc.js
@@ -63,7 +63,7 @@ var map = new ol.Map({
}),
new ol.layer.Vector({
source: vectorSource,
- styleFunction: styleFunction
+ style: styleFunction
})
],
renderer: 'canvas',
diff --git a/examples/image-vector-layer.js b/examples/image-vector-layer.js
index bc38cedc5e..83bf47477b 100644
--- a/examples/image-vector-layer.js
+++ b/examples/image-vector-layer.js
@@ -11,16 +11,6 @@ goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
-var styleArray = [new ol.style.Style({
- fill: new ol.style.Fill({
- color: 'rgba(255, 255, 255, 0.6)'
- }),
- stroke: new ol.style.Stroke({
- color: '#319FD3',
- width: 1
- })
-})];
-
var map = new ol.Map({
layers: [
new ol.layer.Tile({
@@ -32,9 +22,15 @@ var map = new ol.Map({
projection: 'EPSG:3857',
url: 'data/geojson/countries.geojson'
}),
- styleFunction: function(feature, resolution) {
- return styleArray;
- }
+ style: new ol.style.Style({
+ fill: new ol.style.Fill({
+ color: 'rgba(255, 255, 255, 0.6)'
+ }),
+ stroke: new ol.style.Stroke({
+ color: '#319FD3',
+ width: 1
+ })
+ })
})
})
],
@@ -46,21 +42,17 @@ var map = new ol.Map({
})
});
-var highlightStyleArray = [new ol.style.Style({
- stroke: new ol.style.Stroke({
- color: '#f00',
- width: 1
- }),
- fill: new ol.style.Fill({
- color: 'rgba(255,0,0,0.1)'
- })
-})];
-
var featureOverlay = new ol.FeatureOverlay({
map: map,
- styleFunction: function(feature, resolution) {
- return highlightStyleArray;
- }
+ style: new ol.style.Style({
+ stroke: new ol.style.Stroke({
+ color: '#f00',
+ width: 1
+ }),
+ fill: new ol.style.Fill({
+ color: 'rgba(255,0,0,0.1)'
+ })
+ })
});
var highlight;
diff --git a/examples/kml-earthquakes.html b/examples/kml-earthquakes.html
index 4d3f2386c9..73951c9226 100644
--- a/examples/kml-earthquakes.html
+++ b/examples/kml-earthquakes.html
@@ -55,7 +55,7 @@
Demonstrates the use of a Shape symbolizer to render earthquake locations.
- This example parses a KML file and renders the features as a vector layer. The layer is given a styleFunction that renders earthquake locations with a size relative to their magnitude.
+ This example parses a KML file and renders the features as a vector layer. The layer is given a style that renders earthquake locations with a size relative to their magnitude.
See the kml-earthquakes.js source to see how this is done.
diff --git a/examples/kml-earthquakes.js b/examples/kml-earthquakes.js
index d4edebcc3b..4bbc80716f 100644
--- a/examples/kml-earthquakes.js
+++ b/examples/kml-earthquakes.js
@@ -42,7 +42,7 @@ var vector = new ol.layer.Vector({
projection: 'EPSG:3857',
url: 'data/kml/2012_Earthquakes_Mag5.kml'
}),
- styleFunction: styleFunction
+ style: styleFunction
});
var raster = new ol.layer.Tile({
diff --git a/examples/kml-timezones.js b/examples/kml-timezones.js
index 6211b4957d..2973b637d6 100644
--- a/examples/kml-timezones.js
+++ b/examples/kml-timezones.js
@@ -49,7 +49,7 @@ var vector = new ol.layer.Vector({
projection: 'EPSG:3857',
url: 'data/kml/timezones.kml'
}),
- styleFunction: styleFunction
+ style: styleFunction
});
var raster = new ol.layer.Tile({
diff --git a/examples/modify-features.js b/examples/modify-features.js
index 2ed0e6aa86..ed8bb3714c 100644
--- a/examples/modify-features.js
+++ b/examples/modify-features.js
@@ -161,7 +161,7 @@ var vectorSource = new ol.source.GeoJSON(
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
- styleFunction: styleFunction
+ style: styleFunction
});
var overlayStyle = (function() {
@@ -228,7 +228,7 @@ var overlayStyle = (function() {
})();
var overlay = new ol.FeatureOverlay({
- styleFunction: overlayStyle
+ style: overlayStyle
});
var modify = new ol.interaction.Modify({ featureOverlay: overlay });
diff --git a/examples/rtree.js b/examples/rtree.js
index 7a9f184753..43e8a3d10c 100644
--- a/examples/rtree.js
+++ b/examples/rtree.js
@@ -83,16 +83,14 @@ for (i = 0, ii = extentsByDepth.length; i < ii; ++i) {
var vector = new ol.layer.Vector({
source: vectorSource,
- styleFunction: function(feature, resolution) {
- return styleArray;
- }
+ style: styleArray
});
var rtree = new ol.layer.Vector({
source: new ol.source.Vector({
features: rtreeExtentFeatures
}),
- styleFunction: function(feature, resolution) {
+ style: function(feature, resolution) {
return feature.get('styleArray');
}
});
diff --git a/examples/select-features.js b/examples/select-features.js
index d9d5a0ca37..def9194a29 100644
--- a/examples/select-features.js
+++ b/examples/select-features.js
@@ -15,36 +15,28 @@ var raster = new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'sat'})
});
-var unselectedStyle = [new ol.style.Style({
- fill: new ol.style.Fill({
- color: 'rgba(255,255,255,0.25)'
- }),
- stroke: new ol.style.Stroke({
- color: '#6666ff'
- })
-})];
-
-var selectedStyle = [new ol.style.Style({
- fill: new ol.style.Fill({
- color: 'rgba(255,255,255,0.5)'
- })
-})];
-
var vector = new ol.layer.Vector({
source: new ol.source.GeoJSON({
projection: 'EPSG:3857',
url: 'data/geojson/countries.geojson'
}),
- styleFunction: function(feature, resolution) {
- return unselectedStyle;
- }
+ style: new ol.style.Style({
+ fill: new ol.style.Fill({
+ color: 'rgba(255,255,255,0.25)'
+ }),
+ stroke: new ol.style.Stroke({
+ color: '#6666ff'
+ })
+ })
});
var select = new ol.interaction.Select({
featureOverlay: new ol.FeatureOverlay({
- styleFunction: function(feature, resolution) {
- return selectedStyle;
- }
+ style: new ol.style.Style({
+ fill: new ol.style.Fill({
+ color: 'rgba(255,255,255,0.5)'
+ })
+ })
})
});
diff --git a/examples/synthetic-lines.js b/examples/synthetic-lines.js
index 9a5dd9e4ee..789a7c2571 100644
--- a/examples/synthetic-lines.js
+++ b/examples/synthetic-lines.js
@@ -36,20 +36,16 @@ for (i = 0; i < count; ++i) {
startPoint = endPoint;
}
-var styleArray = [new ol.style.Style({
- stroke: new ol.style.Stroke({
- color: '#666666',
- width: 1
- })
-})];
-
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
features: features
}),
- styleFunction: function(feature, resolution) {
- return styleArray;
- }
+ style: new ol.style.Style({
+ stroke: new ol.style.Stroke({
+ color: '#666666',
+ width: 1
+ })
+ })
});
var view = new ol.View2D({
diff --git a/examples/synthetic-points.js b/examples/synthetic-points.js
index 7ebd447c4b..7246fbfda1 100644
--- a/examples/synthetic-points.js
+++ b/examples/synthetic-points.js
@@ -46,7 +46,7 @@ var vectorSource = new ol.source.Vector({
});
var vector = new ol.layer.Vector({
source: vectorSource,
- styleFunction: function(feature, resolution) {
+ style: function(feature, resolution) {
return styles[feature.get('size')];
}
});
diff --git a/examples/topojson.js b/examples/topojson.js
index 0cdde09c0c..d9eb762642 100644
--- a/examples/topojson.js
+++ b/examples/topojson.js
@@ -30,7 +30,7 @@ var vector = new ol.layer.Vector({
projection: 'EPSG:3857',
url: 'data/topojson/world-110m.json'
}),
- styleFunction: function(feature, resolution) {
+ style: function(feature, resolution) {
// don't want to render the full world polygon, which repeats all countries
return feature.getId() !== undefined ? styleArray : null;
}
diff --git a/examples/vector-layer.js b/examples/vector-layer.js
index 8b36ced3a3..ca33ead397 100644
--- a/examples/vector-layer.js
+++ b/examples/vector-layer.js
@@ -17,7 +17,7 @@ var vectorLayer = new ol.layer.Vector({
projection: 'EPSG:3857',
url: 'data/geojson/countries.geojson'
}),
- styleFunction: function(feature, resolution) {
+ style: function(feature, resolution) {
var text = resolution < 5000 ? feature.get('name') : '';
if (!styleCache[text]) {
styleCache[text] = [new ol.style.Style({
@@ -64,7 +64,7 @@ var highlightStyleCache = {};
var featureOverlay = new ol.FeatureOverlay({
map: map,
- styleFunction: function(feature, resolution) {
+ style: function(feature, resolution) {
var text = resolution < 5000 ? feature.get('name') : '';
if (!highlightStyleCache[text]) {
highlightStyleCache[text] = [new ol.style.Style({
diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc
index c57fc51ad8..9ffa917fca 100644
--- a/src/objectliterals.jsdoc
+++ b/src/objectliterals.jsdoc
@@ -389,7 +389,8 @@
* drawing finish (default is 12).
* @property {ol.geom.GeometryType} type Drawing type ('Point', 'LineString',
* 'Polygon', 'MultiPoint', 'MultiLineString', or 'MultiPolygon').
- * @property {ol.feature.StyleFunction|undefined} styleFunction Style function.
+ * @property {ol.style.Style|Array.|ol.feature.StyleFunction|undefined} style
+ * Style for sketch features.
* @todo stability experimental
*/
@@ -541,7 +542,7 @@
* @property {number|undefined} opacity Opacity. 0-1. Default is `1`.
* @property {number|undefined} saturation Saturation.
* @property {ol.source.Vector} source Source.
- * @property {ol.feature.StyleFunction|undefined} styleFunction Style function.
+ * @property {ol.style.Style|Array.|ol.feature.StyleFunction|undefined} style Layer style.
* @property {boolean|undefined} visible Visibility. Default is `true` (visible).
* @todo stability experimental
*/
@@ -575,7 +576,7 @@
* @typedef {Object} olx.FeatureOverlayOptions
* @property {Array.|ol.Collection|undefined} features Features.
* @property {ol.Map|undefined} map Map.
- * @property {ol.feature.StyleFunction|undefined} styleFunction Style function.
+ * @property {ol.style.Style|Array.|ol.feature.StyleFunction|undefined} style Feature style.
*/
/**
@@ -745,8 +746,8 @@
* new canvases will be created for these resolutions only.
* @property {ol.source.Vector} source The vector source from which the vector
* features drawn in canvas elements are read.
- * @property {ol.feature.StyleFunction|undefined} styleFunction Style function
- * providing the styles to use when rendering features to the canvas.
+ * @property {ol.style.Style|Array.|ol.feature.StyleFunction|undefined} style
+ * Style to use when rendering features to the canvas.
*/
/**
diff --git a/src/ol/feature.exports b/src/ol/feature.exports
index 08e79a2c8c..6c1f200ea6 100644
--- a/src/ol/feature.exports
+++ b/src/ol/feature.exports
@@ -1,5 +1,8 @@
@exportSymbol ol.Feature
@exportProperty ol.Feature.prototype.getGeometryName
-@exportProperty ol.Feature.prototype.setGeometryName
@exportProperty ol.Feature.prototype.getId
+@exportProperty ol.Feature.prototype.getStyle
+@exportProperty ol.Feature.prototype.getStyleFunction
+@exportProperty ol.Feature.prototype.setGeometryName
@exportProperty ol.Feature.prototype.setId
+@exportProperty ol.Feature.prototype.setStyle
diff --git a/src/ol/feature.js b/src/ol/feature.js
index 68f36d1cec..276efe83e8 100644
--- a/src/ol/feature.js
+++ b/src/ol/feature.js
@@ -10,14 +10,6 @@ goog.require('ol.geom.Geometry');
goog.require('ol.style.Style');
-/**
- * @enum {string}
- */
-ol.FeatureProperty = {
- STYLE_FUNCTION: 'styleFunction'
-};
-
-
/**
* @constructor
@@ -42,6 +34,20 @@ ol.Feature = function(opt_geometryOrValues) {
*/
this.geometryName_ = 'geometry';
+ /**
+ * User provided style.
+ * @private
+ * @type {ol.style.Style|Array.|
+ * ol.feature.FeatureStyleFunction}
+ */
+ this.style_ = null;
+
+ /**
+ * @private
+ * @type {ol.feature.FeatureStyleFunction|undefined}
+ */
+ this.styleFunction_;
+
/**
* @private
* @type {goog.events.Key}
@@ -51,9 +57,6 @@ ol.Feature = function(opt_geometryOrValues) {
goog.events.listen(
this, ol.Object.getChangeEventType(this.geometryName_),
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) {
@@ -103,18 +106,23 @@ ol.Feature.prototype.getGeometryName = function() {
};
+/**
+ * @return {ol.style.Style|Array.|
+ * ol.feature.FeatureStyleFunction} User provided style.
+ * @todo stability experimental
+ */
+ol.Feature.prototype.getStyle = function() {
+ return this.style_;
+};
+
+
/**
* @return {ol.feature.FeatureStyleFunction|undefined} Style function.
* @todo stability experimental
*/
ol.Feature.prototype.getStyleFunction = function() {
- return /** @type {ol.feature.FeatureStyleFunction|undefined} */ (
- this.get(ol.FeatureProperty.STYLE_FUNCTION));
+ return this.styleFunction_;
};
-goog.exportProperty(
- ol.Feature.prototype,
- 'getStyleFunction',
- ol.Feature.prototype.getStyleFunction);
/**
@@ -142,14 +150,6 @@ ol.Feature.prototype.handleGeometryChanged_ = function() {
};
-/**
- * @private
- */
-ol.Feature.prototype.handleStyleFunctionChange_ = function() {
- this.dispatchChangeEvent();
-};
-
-
/**
* @param {ol.geom.Geometry|undefined} geometry Geometry.
* @todo stability experimental
@@ -164,17 +164,15 @@ goog.exportProperty(
/**
- * @param {ol.feature.FeatureStyleFunction|undefined} styleFunction Style
- * function
+ * @param {ol.style.Style|Array.|
+ * ol.feature.FeatureStyleFunction} style Feature style.
* @todo stability experimental
*/
-ol.Feature.prototype.setStyleFunction = function(styleFunction) {
- this.set(ol.FeatureProperty.STYLE_FUNCTION, styleFunction);
+ol.Feature.prototype.setStyle = function(style) {
+ this.style_ = style;
+ this.styleFunction_ = ol.feature.createFeatureStyleFunction(style);
+ this.dispatchChangeEvent();
};
-goog.exportProperty(
- ol.Feature.prototype,
- 'setStyleFunction',
- ol.Feature.prototype.setStyleFunction);
/**
@@ -247,3 +245,70 @@ ol.feature.defaultStyleFunction = function(feature, resolution) {
}
return featureStyleFunction.call(feature, resolution);
};
+
+
+/**
+ * Convert the provided object into a feature style function. Functions passed
+ * through unchanged. Arrays of ol.style.Style or single style objects wrapped
+ * in a new feature style function.
+ * @param {ol.feature.FeatureStyleFunction|Array.|
+ * ol.style.Style} obj A feature style function, a single style, or an array
+ * of styles.
+ * @return {ol.feature.FeatureStyleFunction} A style function.
+ */
+ol.feature.createFeatureStyleFunction = function(obj) {
+ /**
+ * @type {ol.feature.FeatureStyleFunction}
+ */
+ var styleFunction;
+
+ if (goog.isFunction(obj)) {
+ styleFunction = /** @type {ol.feature.FeatureStyleFunction} */ (obj);
+ } else {
+ /**
+ * @type {Array.}
+ */
+ var styles;
+ if (goog.isArray(obj)) {
+ styles = obj;
+ } else {
+ goog.asserts.assertInstanceof(obj, ol.style.Style);
+ styles = [obj];
+ }
+ styleFunction = goog.functions.constant(styles);
+ }
+ return styleFunction;
+};
+
+
+/**
+ * Convert the provided object into a style function. Functions passed through
+ * unchanged. Arrays of ol.style.Style or single style objects wrapped in a
+ * new style function.
+ * @param {ol.feature.StyleFunction|Array.|ol.style.Style} obj
+ * A style function, a single style, or an array of styles.
+ * @return {ol.feature.StyleFunction} A style function.
+ */
+ol.feature.createStyleFunction = function(obj) {
+ /**
+ * @type {ol.feature.StyleFunction}
+ */
+ var styleFunction;
+
+ if (goog.isFunction(obj)) {
+ styleFunction = /** @type {ol.feature.StyleFunction} */ (obj);
+ } else {
+ /**
+ * @type {Array.}
+ */
+ var styles;
+ if (goog.isArray(obj)) {
+ styles = obj;
+ } else {
+ goog.asserts.assertInstanceof(obj, ol.style.Style);
+ styles = [obj];
+ }
+ styleFunction = goog.functions.constant(styles);
+ }
+ return styleFunction;
+};
diff --git a/src/ol/featureoverlay.exports b/src/ol/featureoverlay.exports
index 120ff391d2..9cfe34b200 100644
--- a/src/ol/featureoverlay.exports
+++ b/src/ol/featureoverlay.exports
@@ -1,7 +1,9 @@
@exportSymbol ol.FeatureOverlay
@exportProperty ol.FeatureOverlay.prototype.addFeature
@exportProperty ol.FeatureOverlay.prototype.getFeatures
+@exportProperty ol.FeatureOverlay.prototype.getStyle
+@exportProperty ol.FeatureOverlay.prototype.getStyleFunction
@exportProperty ol.FeatureOverlay.prototype.setFeatures
@exportProperty ol.FeatureOverlay.prototype.setMap
-@exportProperty ol.FeatureOverlay.prototype.setStyleFunction
+@exportProperty ol.FeatureOverlay.prototype.setStyle
@exportProperty ol.FeatureOverlay.prototype.removeFeature
diff --git a/src/ol/featureoverlay.js b/src/ol/featureoverlay.js
index ccc5f68b45..4962b7cd18 100644
--- a/src/ol/featureoverlay.js
+++ b/src/ol/featureoverlay.js
@@ -52,11 +52,18 @@ ol.FeatureOverlay = function(opt_options) {
*/
this.postComposeListenerKey_ = null;
+ /**
+ * @private
+ * @type {ol.style.Style|Array.|ol.feature.StyleFunction}
+ */
+ this.style_ = null;
+
/**
* @private
* @type {ol.feature.StyleFunction|undefined}
*/
- this.styleFunction_ = undefined;
+ this.styleFunction_ = goog.isDef(options.style) ?
+ ol.feature.createStyleFunction(options.style) : undefined;
if (goog.isDef(options.features)) {
if (goog.isArray(options.features)) {
@@ -69,10 +76,6 @@ ol.FeatureOverlay = function(opt_options) {
this.setFeatures(new ol.Collection());
}
- if (goog.isDef(options.styleFunction)) {
- this.setStyleFunction(options.styleFunction);
- }
-
if (goog.isDef(options.map)) {
this.setMap(options.map);
}
@@ -238,16 +241,33 @@ ol.FeatureOverlay.prototype.setMap = function(map) {
/**
- * @param {ol.feature.StyleFunction} styleFunction Style function.
+ * Set the style for features. This can be a single style object, an array
+ * of styles, or a function that takes a feature and resolution and returns
+ * an array of styles.
+ * @param {ol.style.Style|Array.|ol.feature.StyleFunction} style
+ * Overlay style.
* @todo stability experimental
*/
-ol.FeatureOverlay.prototype.setStyleFunction = function(styleFunction) {
- this.styleFunction_ = styleFunction;
+ol.FeatureOverlay.prototype.setStyle = function(style) {
+ this.style_ = style;
+ this.styleFunction_ = ol.feature.createStyleFunction(style);
this.requestRenderFrame_();
};
/**
+ * Get the style for features. This returns whatever was passed to the `style`
+ * option at construction or to the `setStyle` method.
+ * @return {ol.style.Style|Array.|ol.feature.StyleFunction}
+ * Overlay style.
+ */
+ol.FeatureOverlay.prototype.getStyle = function() {
+ return this.style_;
+};
+
+
+/**
+ * Get the style function.
* @return {ol.feature.StyleFunction|undefined} Style function.
*/
ol.FeatureOverlay.prototype.getStyleFunction = function() {
diff --git a/src/ol/format/kmlformat.js b/src/ol/format/kmlformat.js
index 2b5548ad7f..8351b856dc 100644
--- a/src/ol/format/kmlformat.js
+++ b/src/ol/format/kmlformat.js
@@ -1448,7 +1448,7 @@ ol.format.KML.prototype.readPlacemark_ = function(node, objectStack) {
} else {
featureStyleFunction = ol.format.KML.makeFeatureStyleFunction_(style);
}
- feature.setStyleFunction(featureStyleFunction);
+ feature.setStyle(featureStyleFunction);
return feature;
};
diff --git a/src/ol/interaction/drawinteraction.js b/src/ol/interaction/drawinteraction.js
index c2d19aded1..9a263bc38b 100644
--- a/src/ol/interaction/drawinteraction.js
+++ b/src/ol/interaction/drawinteraction.js
@@ -146,9 +146,11 @@ ol.interaction.Draw = function(options) {
* @type {ol.FeatureOverlay}
* @private
*/
- this.overlay_ = new ol.FeatureOverlay();
- this.overlay_.setStyleFunction(goog.isDef(options.styleFunction) ?
- options.styleFunction : ol.interaction.Draw.getDefaultStyleFunction());
+ this.overlay_ = new ol.FeatureOverlay({
+ style: goog.isDef(options.style) ?
+ options.style : ol.interaction.Draw.getDefaultStyleFunction()
+ });
+
};
goog.inherits(ol.interaction.Draw, ol.interaction.Interaction);
diff --git a/src/ol/layer/vectorlayer.exports b/src/ol/layer/vectorlayer.exports
index 3dc18a2d27..be493b810d 100644
--- a/src/ol/layer/vectorlayer.exports
+++ b/src/ol/layer/vectorlayer.exports
@@ -1 +1,4 @@
@exportSymbol ol.layer.Vector
+@exportProperty ol.layer.Vector.prototype.getStyle
+@exportProperty ol.layer.Vector.prototype.getStyleFunction
+@exportProperty ol.layer.Vector.prototype.setStyle
diff --git a/src/ol/layer/vectorlayer.js b/src/ol/layer/vectorlayer.js
index e9bd4110d3..5123320e1b 100644
--- a/src/ol/layer/vectorlayer.js
+++ b/src/ol/layer/vectorlayer.js
@@ -1,5 +1,6 @@
goog.provide('ol.layer.Vector');
+goog.require('goog.object');
goog.require('ol.feature');
goog.require('ol.layer.Layer');
@@ -8,8 +9,7 @@ goog.require('ol.layer.Layer');
* @enum {string}
*/
ol.layer.VectorProperty = {
- RENDER_GEOMETRY_FUNCTIONS: 'renderGeometryFunctions',
- STYLE_FUNCTION: 'styleFunction'
+ RENDER_GEOMETRY_FUNCTIONS: 'renderGeometryFunctions'
};
@@ -25,11 +25,28 @@ ol.layer.Vector = function(opt_options) {
var options = goog.isDef(opt_options) ?
opt_options : /** @type {olx.layer.VectorOptions} */ ({});
- goog.base(this, /** @type {olx.layer.LayerOptions} */ (options));
+ var baseOptions = /** @type {olx.layer.LayerOptions} */
+ (goog.object.clone(options));
- // FIXME veryify this
- if (goog.isDef(options.styleFunction)) {
- this.setStyleFunction(options.styleFunction);
+ delete baseOptions.style;
+ goog.base(this, baseOptions);
+
+ /**
+ * User provided style.
+ * @type {ol.style.Style|Array.|ol.feature.StyleFunction}
+ * @private
+ */
+ this.style_ = null;
+
+ /**
+ * Style function for use within the library.
+ * @type {ol.feature.StyleFunction}
+ * @private
+ */
+ this.styleFunction_;
+
+ if (goog.isDef(options.style)) {
+ this.setStyle(options.style);
}
};
@@ -51,17 +68,24 @@ goog.exportProperty(
/**
- * @return {ol.feature.StyleFunction|undefined} Style function.
+ * Get the style for features. This returns whatever was passed to the `style`
+ * option at construction or to the `setStyle` method.
+ * @return {ol.style.Style|Array.|ol.feature.StyleFunction}
+ * Layer style.
+ */
+ol.layer.Vector.prototype.getStyle = function() {
+ return this.style_;
+};
+
+
+/**
+ * Get the style function.
+ * @return {ol.feature.StyleFunction} Layer style function.
* @todo stability experimental
*/
ol.layer.Vector.prototype.getStyleFunction = function() {
- return /** @type {ol.feature.StyleFunction|undefined} */ (
- this.get(ol.layer.VectorProperty.STYLE_FUNCTION));
+ return this.styleFunction_;
};
-goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getStyleFunction',
- ol.layer.Vector.prototype.getStyleFunction);
/**
@@ -81,16 +105,15 @@ goog.exportProperty(
/**
- * If the styles are changed by setting a new style function or by changing the
- * value returned by the style function then `dispatchChangeEvent` should be
- * called on the layer for the layer to be refreshed on the screen.
- * @param {ol.feature.StyleFunction|undefined} styleFunction Style function.
+ * Set the style for features. This can be a single style object, an array
+ * of styles, or a function that takes a feature and resolution and returns
+ * an array of styles.
+ * @param {ol.style.Style|Array.|ol.feature.StyleFunction} style
+ * Layer style.
* @todo stability experimental
*/
-ol.layer.Vector.prototype.setStyleFunction = function(styleFunction) {
- this.set(ol.layer.VectorProperty.STYLE_FUNCTION, styleFunction);
+ol.layer.Vector.prototype.setStyle = function(style) {
+ this.style_ = style;
+ this.styleFunction_ = ol.feature.createStyleFunction(style);
+ this.dispatchChangeEvent();
};
-goog.exportProperty(
- ol.layer.Vector.prototype,
- 'setStyleFunction',
- ol.layer.Vector.prototype.setStyleFunction);
diff --git a/src/ol/source/imagevectorsource.js b/src/ol/source/imagevectorsource.js
index 97d84e32e6..d6050ac8d4 100644
--- a/src/ol/source/imagevectorsource.js
+++ b/src/ol/source/imagevectorsource.js
@@ -44,8 +44,9 @@ ol.source.ImageVector = function(options) {
* @private
* @type {!ol.feature.StyleFunction}
*/
- this.styleFunction_ = goog.isDef(options.styleFunction) ?
- options.styleFunction : ol.feature.defaultStyleFunction;
+ this.styleFunction_ = goog.isDef(options.style) ?
+ ol.feature.createStyleFunction(options.style) :
+ ol.feature.defaultStyleFunction;
/**
* @private
diff --git a/test/spec/ol/feature.test.js b/test/spec/ol/feature.test.js
index afbf896ed9..afe29368ec 100644
--- a/test/spec/ol/feature.test.js
+++ b/test/spec/ol/feature.test.js
@@ -207,10 +207,191 @@ describe('ol.Feature', function() {
});
+ describe('#getStyleFunction()', function() {
+
+ var styleFunction = function(resolution) {
+ return null;
+ };
+
+ it('returns undefined after construction', function() {
+ var feature = new ol.Feature();
+ expect(feature.getStyleFunction()).to.be(undefined);
+ });
+
+ it('returns the function passed to setStyle', function() {
+ var feature = new ol.Feature();
+ feature.setStyle(styleFunction);
+ expect(feature.getStyleFunction()).to.be(styleFunction);
+ });
+
+ it('does not get confused with user "styleFunction" property', function() {
+ var feature = new ol.Feature();
+ feature.set('styleFunction', 'foo');
+ expect(feature.getStyleFunction()).to.be(undefined);
+ });
+
+ it('does not get confused with "styleFunction" option', function() {
+ var feature = new ol.Feature({
+ styleFunction: 'foo'
+ });
+ expect(feature.getStyleFunction()).to.be(undefined);
+ });
+
+ });
+
+ describe('#setStyle()', function() {
+
+ var style = new ol.style.Style();
+
+ var styleFunction = function(feature, resolution) {
+ return null;
+ };
+
+ it('accepts a single style', function() {
+ var feature = new ol.Feature();
+ feature.setStyle(style);
+ var func = feature.getStyleFunction();
+ expect(func()).to.eql([style]);
+ });
+
+ it('accepts an array of styles', function() {
+ var feature = new ol.Feature();
+ feature.setStyle([style]);
+ var func = feature.getStyleFunction();
+ expect(func()).to.eql([style]);
+ });
+
+ it('accepts a style function', function() {
+ var feature = new ol.Feature();
+ feature.setStyle(styleFunction);
+ expect(feature.getStyleFunction()).to.be(styleFunction);
+ });
+
+ it('dispatches a change event', function(done) {
+ var feature = new ol.Feature();
+ feature.on('change', function() {
+ done();
+ });
+ feature.setStyle(style);
+ });
+
+ });
+
+ describe('#getStyle()', function() {
+
+ var style = new ol.style.Style();
+
+ var styleFunction = function(resolution) {
+ return null;
+ };
+
+ it('returns what is passed to setStyle', function() {
+ var feature = new ol.Feature();
+
+ expect(feature.getStyle()).to.be(null);
+
+ feature.setStyle(style);
+ expect(feature.getStyle()).to.be(style);
+
+ feature.setStyle([style]);
+ expect(feature.getStyle()).to.eql([style]);
+
+ feature.setStyle(styleFunction);
+ expect(feature.getStyle()).to.be(styleFunction);
+
+ });
+
+ /**
+ * We should be able to make the assertion below, but the constructor
+ * calls setValues which calls setFoo when provided with 'foo'. This
+ * is different behavior than calling set('foo', 'bar').
+ * See https://github.com/openlayers/ol3/issues/1672
+
+
+ it('does not get confused with "style" option to constructor', function() {
+ var feature = new ol.Feature({
+ style: 'foo'
+ });
+
+ expect(feature.getStyle()).to.be(null);
+ });
+
+ */
+
+ it('does not get confused with user set "style" property', function() {
+ var feature = new ol.Feature();
+ feature.set('style', 'foo');
+
+ expect(feature.getStyle()).to.be(null);
+ });
+
+ });
+
+
+});
+
+describe('ol.feature.createStyleFunction()', function() {
+ var style = new ol.style.Style();
+
+ it('creates a style function from a single style', function() {
+ var styleFunction = ol.feature.createStyleFunction(style);
+ expect(styleFunction()).to.eql([style]);
+ });
+
+ it('creates a style function from an array of styles', function() {
+ var styleFunction = ol.feature.createStyleFunction([style]);
+ expect(styleFunction()).to.eql([style]);
+ });
+
+ it('passes through a function', function() {
+ var original = function() {
+ return [style];
+ };
+ var styleFunction = ol.feature.createStyleFunction(original);
+ expect(styleFunction).to.be(original);
+ });
+
+ it('throws on (some) unexpected input', function() {
+ expect(function() {
+ ol.feature.createStyleFunction({bogus: 'input'});
+ }).to.throwException();
+ });
+
+});
+
+describe('ol.feature.createFeatureStyleFunction()', function() {
+ var style = new ol.style.Style();
+
+ it('creates a feature style function from a single style', function() {
+ var styleFunction = ol.feature.createFeatureStyleFunction(style);
+ expect(styleFunction()).to.eql([style]);
+ });
+
+ it('creates a feature style function from an array of styles', function() {
+ var styleFunction = ol.feature.createFeatureStyleFunction([style]);
+ expect(styleFunction()).to.eql([style]);
+ });
+
+ it('passes through a function', function() {
+ var original = function() {
+ return [style];
+ };
+ var styleFunction = ol.feature.createFeatureStyleFunction(original);
+ expect(styleFunction).to.be(original);
+ });
+
+ it('throws on (some) unexpected input', function() {
+ expect(function() {
+ ol.feature.createFeatureStyleFunction({bogus: 'input'});
+ }).to.throwException();
+ });
+
});
goog.require('goog.events');
goog.require('goog.object');
goog.require('ol.Feature');
+goog.require('ol.feature');
goog.require('ol.geom.Point');
+goog.require('ol.style.Style');
diff --git a/test/spec/ol/layer/vectorlayer.test.js b/test/spec/ol/layer/vectorlayer.test.js
new file mode 100644
index 0000000000..f00c97ba41
--- /dev/null
+++ b/test/spec/ol/layer/vectorlayer.test.js
@@ -0,0 +1,117 @@
+goog.provide('ol.test.layer.Vector');
+
+describe('ol.layer.Vector', function() {
+
+ describe('constructor', function() {
+ var source = new ol.source.Vector();
+ var style = new ol.style.Style();
+
+ it('creates a new layer', function() {
+ var layer = new ol.layer.Vector({source: source});
+ expect(layer).to.be.a(ol.layer.Vector);
+ expect(layer).to.be.a(ol.layer.Layer);
+ });
+
+ it('accepts a style option with a single style', function() {
+ var layer = new ol.layer.Vector({
+ source: source,
+ style: style
+ });
+
+ var styleFunction = layer.getStyleFunction();
+ expect(styleFunction()).to.eql([style]);
+ });
+
+ it('accepts a style option with an array of styles', function() {
+ var layer = new ol.layer.Vector({
+ source: source,
+ style: [style]
+ });
+
+ var styleFunction = layer.getStyleFunction();
+ expect(styleFunction()).to.eql([style]);
+ });
+
+ it('accepts a style option with a style function', function() {
+ var layer = new ol.layer.Vector({
+ source: source,
+ style: function(feature, resolution) {
+ return [style];
+ }
+ });
+
+ var styleFunction = layer.getStyleFunction();
+ expect(styleFunction()).to.eql([style]);
+ });
+
+ });
+
+ describe('#setStyle()', function() {
+
+ var source = new ol.source.Vector();
+ var style = new ol.style.Style();
+
+ it('allows the style to be set after construction', function() {
+ var layer = new ol.layer.Vector({
+ source: source
+ });
+
+ layer.setStyle(style);
+ expect(layer.getStyle()).to.be(style);
+ });
+
+ it('dispatches the change event', function(done) {
+ var layer = new ol.layer.Vector({
+ source: source
+ });
+ layer.on('change', function() {
+ done();
+ });
+ layer.setStyle(style);
+ });
+
+ it('updates the internal style function', function() {
+ var layer = new ol.layer.Vector({
+ source: source
+ });
+ expect(layer.getStyleFunction()).to.be(undefined);
+ layer.setStyle(style);
+ expect(layer.getStyleFunction()).to.be.a('function');
+ });
+
+ });
+
+ describe('#getStyle()', function() {
+
+ var source = new ol.source.Vector();
+ var style = new ol.style.Style();
+
+ it('returns what is provided to setStyle', function() {
+ var layer = new ol.layer.Vector({
+ source: source
+ });
+
+ expect(layer.getStyle()).to.be(null);
+
+ layer.setStyle(style);
+ expect(layer.getStyle()).to.be(style);
+
+ layer.setStyle([style]);
+ expect(layer.getStyle()).to.eql([style]);
+
+ var styleFunction = function(feature, resolution) {
+ return [style];
+ };
+ layer.setStyle(styleFunction);
+ expect(layer.getStyle()).to.be(styleFunction);
+
+ });
+
+ });
+
+});
+
+goog.require('ol.layer.Layer');
+goog.require('ol.layer.Vector');
+goog.require('ol.source.Vector');
+goog.require('ol.style.Style');