Permalink
Browse files

Collect features before rendering to the sketch canvas

This avoids features being rendered multiple times when they
cross tile borders. Currently this makes the style-rules.html
example extremely slow. Fix for that to come in my next commit.
  • Loading branch information...
1 parent f0039ee commit f4a16e7f57b8475f20361d661db814b9f79ec604 @ahocevar ahocevar committed Mar 7, 2013
Showing with 37 additions and 30 deletions.
  1. +14 −15 src/ol/layer/vectorlayer.js
  2. +23 −15 src/ol/renderer/canvas/canvasvectorlayerrenderer.js
@@ -76,9 +76,8 @@ ol.layer.FeatureCache.prototype.add = function(feature) {
/**
* @param {ol.filter.Filter=} opt_filter Optional filter.
* @return {Object.<string, ol.Feature>} Object of features, keyed by id.
- * @private
*/
-ol.layer.FeatureCache.prototype.getFeaturesObject_ = function(opt_filter) {
+ol.layer.FeatureCache.prototype.getFeaturesObject = function(opt_filter) {
var i, features;
if (!goog.isDef(opt_filter)) {
features = this.idLookup_;
@@ -124,15 +123,6 @@ ol.layer.FeatureCache.prototype.getFeaturesObject_ = function(opt_filter) {
/**
- * @param {ol.filter.Filter=} opt_filter Optional filter.
- * @return {Array.<ol.Feature>} Array of features.
- */
-ol.layer.FeatureCache.prototype.getFeatures = function(opt_filter) {
- return goog.object.getValues(this.getFeaturesObject_(opt_filter));
-};
-
-
-/**
* @param {ol.filter.Geometry} filter Geometry type filter.
* @return {Array.<ol.Feature>} Array of features.
* @private
@@ -209,22 +199,31 @@ ol.layer.Vector.prototype.getVectorSource = function() {
* @return {Array.<ol.Feature>} Array of features.
*/
ol.layer.Vector.prototype.getFeatures = function(opt_filter) {
- return this.featureCache_.getFeatures(opt_filter);
+ return goog.object.getValues(
+ this.featureCache_.getFeaturesObject(opt_filter));
+};
+
+
+/**
+ * @param {ol.filter.Filter=} opt_filter Optional filter.
+ * @return {Object.<string, ol.Feature>} Features.
+ */
+ol.layer.Vector.prototype.getFeaturesObject = function(opt_filter) {
+ return this.featureCache_.getFeaturesObject(opt_filter);
};
/**
- * @param {Array.<ol.Feature>} features Features.
+ * @param {Object.<string, ol.Feature>} features Features.
* @return {Array.<Array>} symbolizers for features.
*/
ol.layer.Vector.prototype.groupFeaturesBySymbolizerLiteral =
function(features) {
var uniqueLiterals = {},
featuresBySymbolizer = [],
style = this.style_,
- numFeatures = features.length,
i, j, l, feature, literals, numLiterals, literal, uniqueLiteral, key;
- for (i = 0; i < numFeatures; ++i) {
+ for (i in features) {
feature = features[i];
literals = feature.getSymbolizerLiterals();
if (goog.isNull(literals)) {
@@ -300,15 +300,16 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
finalCanvas.height = sketchSize.height;
var finalContext = this.context_;
- var renderedFeatures = {};
+ var featuresToRender = {};
var tilesToRender = {};
+ var tilesOnSketchCanvas = {};
// TODO make gutter configurable?
var tileGutter = 15 * tileResolution;
var tile, tileCoord, key, tileState, x, y;
// render features by geometry type
var filters = this.geometryFilters_,
numFilters = filters.length,
- i, geomFilter, tileExtent, extentFilter, type, features,
+ i, geomFilter, tileExtent, extentFilter, type,
groups, group, j, numGroups, deferred;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
@@ -327,25 +328,32 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
for (i = 0; i < numFilters; ++i) {
geomFilter = filters[i];
type = geomFilter.getType();
- features = layer.getFeatures(new ol.filter.Logical(
- [geomFilter, extentFilter], ol.filter.LogicalOperator.AND));
- if (features.length) {
- groups = layer.groupFeaturesBySymbolizerLiteral(features);
- numGroups = groups.length;
- for (j = 0; j < numGroups; ++j) {
- group = groups[j];
- deferred = sketchCanvasRenderer.renderFeaturesByGeometryType(
- type, group[0], group[1]) || deferred;
- }
+ if (!goog.isDef(featuresToRender[type])) {
+ featuresToRender[type] = {};
}
+ goog.object.extend(featuresToRender[type],
+ layer.getFeaturesObject(new ol.filter.Logical(
+ [geomFilter, extentFilter], ol.filter.LogicalOperator.AND)));
}
- if (!deferred) {
- tilesToRender[key] = tileCoord;
- }
+ tilesOnSketchCanvas[key] = tileCoord;
}
}
}
+ for (type in featuresToRender) {
+ groups = layer.groupFeaturesBySymbolizerLiteral(featuresToRender[type]);
+ numGroups = groups.length;
+ for (j = 0; j < numGroups; ++j) {
+ group = groups[j];
+ deferred = sketchCanvasRenderer.renderFeaturesByGeometryType(
+ /** @type {ol.geom.GeometryType} */ (type),
+ group[0], group[1]) || deferred;
+ }
+ if (!deferred) {
+ goog.object.extend(tilesToRender, tilesOnSketchCanvas);
+ }
+ }
+
this.dirty_ = true;
for (key in tilesToRender) {
tileCoord = tilesToRender[key];

0 comments on commit f4a16e7

Please sign in to comment.