Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Using spatial index and combined filters

This should significantly speed up feature access. Needs unit
tests.
  • Loading branch information...
commit dafa48da2e5875e017dbda68171591da1724261a 1 parent c58f0af
@ahocevar ahocevar authored
Showing with 47 additions and 19 deletions.
  1. +47 −19 src/ol/source/vectorsource.js
View
66 src/ol/source/vectorsource.js
@@ -1,10 +1,12 @@
goog.provide('ol.source.Vector');
goog.require('ol.Feature');
-goog.require('ol.filter.Filter');
+goog.require('ol.filter.Extent');
goog.require('ol.filter.Geometry');
+goog.require('ol.filter.Logical');
goog.require('ol.geom.GeometryType');
goog.require('ol.source.Source');
+goog.require('ol.structs.RTree');
@@ -19,13 +21,18 @@ ol.source.FeatureCache = function() {
*/
this.idLookup_;
-
/**
* @type {Object.<ol.Feature>}
* @private
*/
this.geometryTypeIndex_;
+ /**
+ * @type {ol.structs.RTree}
+ * @private
+ */
+ this.rTree_;
+
this.clear();
};
@@ -42,6 +49,8 @@ ol.source.FeatureCache.prototype.clear = function() {
geometryTypeIndex[ol.geom.GeometryType[key]] = {};
}
this.geometryTypeIndex_ = geometryTypeIndex;
+
+ this.rTree_ = new ol.structs.RTree();
};
@@ -55,35 +64,45 @@ ol.source.FeatureCache.prototype.add = function(feature) {
this.idLookup_[id] = feature;
- // index by geometry type
+ // index by geometry type and bounding box
if (!goog.isNull(geometry)) {
this.geometryTypeIndex_[geometry.getType()][id] = feature;
+ this.rTree_.put(geometry.getBounds(), feature);
}
-
- /**
- * TODO: Index by tile coord. To do this for real requires knowledge about
- * the evaluated symbolizer literal for each feature. Initially, a pixel
- * buffer could be provided.
- */
-
};
/**
* @param {ol.filter.Filter=} opt_filter Optional filter.
- * @return {Array.<ol.Feature>} Array of features.
+ * @return {Object.<string, ol.Feature>} Object of features, keyed by id.
+ * @private
*/
-ol.source.FeatureCache.prototype.getFeatures = function(opt_filter) {
+ol.source.FeatureCache.prototype.getFeaturesObject_ = function(opt_filter) {
var features;
if (!goog.isDef(opt_filter)) {
- features = new Array();
- for (var id in this.idLookup_) {
- features.push(this.idLookup_[id]);
- }
+ features = this.idLookup_;
} else {
- if (opt_filter instanceof ol.filter.Geometry) {
- features = this.getFeaturesByGeometryType_(
- /** @type {ol.filter.Geometry} */ (opt_filter));
+ if (opt_filter instanceof ol.filter.Logical) {
+ features = {};
+ var filters = opt_filter.getFilters(),
+ filterFeatures, key, or;
+ for (var i = filters.length - 1; i >= 0; --i) {
+ filterFeatures = this.getFeaturesObject_(filters[i]);
+ goog.object.extend(features, filterFeatures);
+ if (opt_filter.operator === ol.filter.LogicalOperator.AND) {
+ or = features;
+ features = {};
+ for (key in or) {
+ if (filterFeatures[key]) {
+ features[key] = or[key];
+ }
+ }
+ }
+ }
+ } else if (opt_filter instanceof ol.filter.Geometry) {
+ features = this.geometryTypeIndex_[opt_filter.getType()];
+ } else if (opt_filter instanceof ol.filter.Extent) {
+ features = this.rTree_.find(opt_filter.getExtent());
} else {
// TODO: support other filter types
throw new Error('Filter type not supported: ' + opt_filter);
@@ -94,6 +113,15 @@ ol.source.FeatureCache.prototype.getFeatures = function(opt_filter) {
/**
+ * @param {ol.filter.Filter=} opt_filter Optional filter.
+ * @return {Array.<ol.Feature>} Array of features.
+ */
+ol.source.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
Please sign in to comment.
Something went wrong with that request. Please try again.