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.
This commit is contained in:
@@ -76,9 +76,8 @@ ol.layer.FeatureCache.prototype.add = function(feature) {
|
|||||||
/**
|
/**
|
||||||
* @param {ol.filter.Filter=} opt_filter Optional filter.
|
* @param {ol.filter.Filter=} opt_filter Optional filter.
|
||||||
* @return {Object.<string, ol.Feature>} Object of features, keyed by id.
|
* @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;
|
var i, features;
|
||||||
if (!goog.isDef(opt_filter)) {
|
if (!goog.isDef(opt_filter)) {
|
||||||
features = this.idLookup_;
|
features = this.idLookup_;
|
||||||
@@ -123,15 +122,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.
|
* @param {ol.filter.Geometry} filter Geometry type filter.
|
||||||
* @return {Array.<ol.Feature>} Array of features.
|
* @return {Array.<ol.Feature>} Array of features.
|
||||||
@@ -209,12 +199,22 @@ ol.layer.Vector.prototype.getVectorSource = function() {
|
|||||||
* @return {Array.<ol.Feature>} Array of features.
|
* @return {Array.<ol.Feature>} Array of features.
|
||||||
*/
|
*/
|
||||||
ol.layer.Vector.prototype.getFeatures = function(opt_filter) {
|
ol.layer.Vector.prototype.getFeatures = function(opt_filter) {
|
||||||
return this.featureCache_.getFeatures(opt_filter);
|
return goog.object.getValues(
|
||||||
|
this.featureCache_.getFeaturesObject(opt_filter));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array.<ol.Feature>} features Features.
|
* @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 {Object.<string, ol.Feature>} features Features.
|
||||||
* @return {Array.<Array>} symbolizers for features.
|
* @return {Array.<Array>} symbolizers for features.
|
||||||
*/
|
*/
|
||||||
ol.layer.Vector.prototype.groupFeaturesBySymbolizerLiteral =
|
ol.layer.Vector.prototype.groupFeaturesBySymbolizerLiteral =
|
||||||
@@ -222,9 +222,8 @@ ol.layer.Vector.prototype.groupFeaturesBySymbolizerLiteral =
|
|||||||
var uniqueLiterals = {},
|
var uniqueLiterals = {},
|
||||||
featuresBySymbolizer = [],
|
featuresBySymbolizer = [],
|
||||||
style = this.style_,
|
style = this.style_,
|
||||||
numFeatures = features.length,
|
|
||||||
i, j, l, feature, literals, numLiterals, literal, uniqueLiteral, key;
|
i, j, l, feature, literals, numLiterals, literal, uniqueLiteral, key;
|
||||||
for (i = 0; i < numFeatures; ++i) {
|
for (i in features) {
|
||||||
feature = features[i];
|
feature = features[i];
|
||||||
literals = feature.getSymbolizerLiterals();
|
literals = feature.getSymbolizerLiterals();
|
||||||
if (goog.isNull(literals)) {
|
if (goog.isNull(literals)) {
|
||||||
|
|||||||
@@ -300,15 +300,16 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
|
|||||||
finalCanvas.height = sketchSize.height;
|
finalCanvas.height = sketchSize.height;
|
||||||
var finalContext = this.context_;
|
var finalContext = this.context_;
|
||||||
|
|
||||||
var renderedFeatures = {};
|
var featuresToRender = {};
|
||||||
var tilesToRender = {};
|
var tilesToRender = {};
|
||||||
|
var tilesOnSketchCanvas = {};
|
||||||
// TODO make gutter configurable?
|
// TODO make gutter configurable?
|
||||||
var tileGutter = 15 * tileResolution;
|
var tileGutter = 15 * tileResolution;
|
||||||
var tile, tileCoord, key, tileState, x, y;
|
var tile, tileCoord, key, tileState, x, y;
|
||||||
// render features by geometry type
|
// render features by geometry type
|
||||||
var filters = this.geometryFilters_,
|
var filters = this.geometryFilters_,
|
||||||
numFilters = filters.length,
|
numFilters = filters.length,
|
||||||
i, geomFilter, tileExtent, extentFilter, type, features,
|
i, geomFilter, tileExtent, extentFilter, type,
|
||||||
groups, group, j, numGroups, deferred;
|
groups, group, j, numGroups, deferred;
|
||||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||||
@@ -327,25 +328,32 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
|
|||||||
for (i = 0; i < numFilters; ++i) {
|
for (i = 0; i < numFilters; ++i) {
|
||||||
geomFilter = filters[i];
|
geomFilter = filters[i];
|
||||||
type = geomFilter.getType();
|
type = geomFilter.getType();
|
||||||
features = layer.getFeatures(new ol.filter.Logical(
|
if (!goog.isDef(featuresToRender[type])) {
|
||||||
[geomFilter, extentFilter], ol.filter.LogicalOperator.AND));
|
featuresToRender[type] = {};
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
goog.object.extend(featuresToRender[type],
|
||||||
|
layer.getFeaturesObject(new ol.filter.Logical(
|
||||||
|
[geomFilter, extentFilter], ol.filter.LogicalOperator.AND)));
|
||||||
}
|
}
|
||||||
if (!deferred) {
|
tilesOnSketchCanvas[key] = tileCoord;
|
||||||
tilesToRender[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;
|
this.dirty_ = true;
|
||||||
for (key in tilesToRender) {
|
for (key in tilesToRender) {
|
||||||
tileCoord = tilesToRender[key];
|
tileCoord = tilesToRender[key];
|
||||||
|
|||||||
Reference in New Issue
Block a user