Allow styles to override feature geometries

With this change, application developers are able to define styles that
render a different geometry than the feature geometry. This can e.g. be
used to render an interior point of a polygon instead of the polygon, or
to render symbols like arrows along lines.
This commit is contained in:
Andreas Hocevar
2014-12-05 13:33:44 +01:00
parent e57ea1e66b
commit 2d12531105
3 changed files with 74 additions and 3 deletions

View File

@@ -6075,7 +6075,8 @@ olx.style.TextOptions.prototype.stroke;
/**
* @typedef {{fill: (ol.style.Fill|undefined),
* @typedef {{geometry: (undefined|string|ol.geom.Geometry|function(ol.Feature): ol.geom.Geometry),
* fill: (ol.style.Fill|undefined),
* image: (ol.style.Image|undefined),
* stroke: (ol.style.Stroke|undefined),
* text: (ol.style.Text|undefined),
@@ -6085,6 +6086,15 @@ olx.style.TextOptions.prototype.stroke;
olx.style.StyleOptions;
/**
* Feature property or geometry or function returning a geometry to render
* for this style.
* @type {undefined|string|ol.geom.Geometry|function(ol.Feature): ol.geom.Geometry}
* @api
*/
olx.style.StyleOptions.prototype.geometry;
/**
* Fill style.
* @type {ol.style.Fill|undefined}

View File

@@ -123,8 +123,8 @@ ol.renderer.vector.renderFeature = function(
*/
ol.renderer.vector.renderFeature_ = function(
replayGroup, feature, style, squaredTolerance) {
var geometry = feature.getGeometry();
if (!goog.isDefAndNotNull(geometry)) {
var geometry = style.getGeometryFunction()(feature);
if (goog.isNull(geometry)) {
return;
}
var simplifiedGeometry = geometry.getSimplifiedGeometry(squaredTolerance);

View File

@@ -1,7 +1,9 @@
goog.provide('ol.style.Style');
goog.provide('ol.style.defaultGeometryFunction');
goog.require('goog.asserts');
goog.require('goog.functions');
goog.require('ol.geom.Geometry');
goog.require('ol.geom.GeometryType');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
@@ -24,6 +26,18 @@ ol.style.Style = function(opt_options) {
var options = goog.isDef(opt_options) ? opt_options : {};
/**
* Function that is called with a feature and returns the geometry to render
* for this style.
* @private
* @type {!function(ol.Feature): ol.geom.Geometry}
*/
this.geometryFunction_ = ol.style.defaultGeometryFunction;
if (goog.isDef(options.geometry)) {
this.setGeometry(options.geometry);
}
/**
* @private
* @type {ol.style.Fill}
@@ -57,6 +71,16 @@ ol.style.Style = function(opt_options) {
};
/**
* @return {!function(ol.Feature): ol.geom.Geometry} Function that is called
* with a feature and returns the geometry to render instead of the feature's
* geometry.
*/
ol.style.Style.prototype.getGeometryFunction = function() {
return this.geometryFunction_;
};
/**
* @return {ol.style.Fill} Fill style.
* @api
@@ -102,6 +126,32 @@ ol.style.Style.prototype.getZIndex = function() {
};
/**
* Set a geometry that is rendered instead of the feature's geometry.
*
* @param {string|ol.geom.Geometry|function(ol.Feature): ol.geom.Geometry} geometry
* Feature property or geometry or function returning a geometry to render
* for this style.
* @api
*/
ol.style.Style.prototype.setGeometry = function(geometry) {
if (goog.isFunction(geometry)) {
this.geometryFunction_ = geometry;
} else if (goog.isString(geometry)) {
this.geometryFunction_ = function(feature) {
return feature.get(geometry);
};
} else if (goog.isDef(geometry)) {
goog.asserts.assertInstanceof(geometry, ol.geom.Geometry);
this.geometryFunction_ = function() {
return geometry;
};
} else {
this.geometryFunction_ = ol.style.defaultGeometryFunction;
}
};
/**
* Set the zIndex.
*
@@ -264,3 +314,14 @@ ol.style.createDefaultEditingStyles = function() {
return styles;
};
/**
* @param {ol.Feature} feature Feature to get the geometry for.
* @return {ol.geom.Geometry} Geometry to render.
*/
ol.style.defaultGeometryFunction = function(feature) {
goog.asserts.assert(!goog.isNull(feature));
var geometry = feature.getGeometry();
return goog.isDef(geometry) ? geometry : null;
};