Moving the feature management to the layer
The source will be responsible for fetching vector data.
This commit is contained in:
@@ -15,11 +15,46 @@ goog.require('ol.style.Rule');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
var source = new ol.source.Vector({
|
||||
projection: ol.projection.getFromCode('EPSG:3857')
|
||||
var style = new ol.style.Style({rules: [
|
||||
new ol.style.Rule({
|
||||
filter: new ol.filter.Filter(function(feature) {
|
||||
return feature.get('where') == 'outer';
|
||||
}),
|
||||
symbolizers: [
|
||||
new ol.style.Line({
|
||||
strokeStyle: new ol.Expression('color'),
|
||||
strokeWidth: 4,
|
||||
opacity: 1
|
||||
})
|
||||
]
|
||||
}),
|
||||
new ol.style.Rule({
|
||||
filter: new ol.filter.Filter(function(feature) {
|
||||
return feature.get('where') == 'inner';
|
||||
}),
|
||||
symbolizers: [
|
||||
new ol.style.Line({
|
||||
strokeStyle: '#013',
|
||||
strokeWidth: 4,
|
||||
opacity: 1
|
||||
}),
|
||||
new ol.style.Line({
|
||||
strokeStyle: new ol.Expression('color'),
|
||||
strokeWidth: 2,
|
||||
opacity: 1
|
||||
})
|
||||
]
|
||||
})
|
||||
]});
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
style: style,
|
||||
source: new ol.source.Vector({
|
||||
projection: ol.projection.getFromCode('EPSG:3857')
|
||||
})
|
||||
});
|
||||
|
||||
source.addFeatures([
|
||||
vector.addFeatures([
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10000000, -10000000], [10000000, 10000000]]),
|
||||
'color': '#BADA55',
|
||||
@@ -52,44 +87,6 @@ source.addFeatures([
|
||||
})
|
||||
]);
|
||||
|
||||
var style = new ol.style.Style({
|
||||
rules: [
|
||||
new ol.style.Rule({
|
||||
filter: new ol.filter.Filter(function(feature) {
|
||||
return feature.get('where') == 'outer';
|
||||
}),
|
||||
symbolizers: [
|
||||
new ol.style.Line({
|
||||
strokeStyle: new ol.Expression('color'),
|
||||
strokeWidth: 4,
|
||||
opacity: 1
|
||||
})
|
||||
]
|
||||
}),
|
||||
new ol.style.Rule({
|
||||
filter: new ol.filter.Filter(function(feature) {
|
||||
return feature.get('where') == 'inner';
|
||||
}),
|
||||
symbolizers: [
|
||||
new ol.style.Line({
|
||||
strokeStyle: '#013',
|
||||
strokeWidth: 4,
|
||||
opacity: 1
|
||||
}),
|
||||
new ol.style.Line({
|
||||
strokeStyle: new ol.Expression('color'),
|
||||
strokeWidth: 2,
|
||||
opacity: 1
|
||||
})
|
||||
]
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
source: source,
|
||||
style: style
|
||||
});
|
||||
|
||||
var map = new ol.Map({
|
||||
layers: new ol.Collection([vector]),
|
||||
|
||||
@@ -17,11 +17,13 @@ var raster = new ol.layer.TileLayer({
|
||||
source: new ol.source.MapQuestOpenAerial()
|
||||
});
|
||||
|
||||
var source = new ol.source.Vector({
|
||||
projection: ol.projection.getFromCode('EPSG:3857')
|
||||
var vector = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
projection: ol.projection.getFromCode('EPSG:3857')
|
||||
})
|
||||
});
|
||||
|
||||
source.addFeatures([
|
||||
vector.addFeatures([
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10000000, -10000000], [10000000, 10000000]])
|
||||
}),
|
||||
@@ -31,9 +33,6 @@ source.addFeatures([
|
||||
new ol.Feature({g: new ol.geom.Point([-10000000, 5000000])})
|
||||
]);
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
source: source
|
||||
});
|
||||
|
||||
var map = new ol.Map({
|
||||
layers: new ol.Collection([raster, vector]),
|
||||
|
||||
@@ -3,10 +3,170 @@ goog.provide('ol.layer.Vector');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.structs.RTree');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
ol.layer.FeatureCache = function() {
|
||||
|
||||
/**
|
||||
* @type {Object.<string, ol.Feature>}
|
||||
* @private
|
||||
*/
|
||||
this.idLookup_;
|
||||
|
||||
/**
|
||||
* @type {Object.<string, ol.Feature>}
|
||||
* @private
|
||||
*/
|
||||
this.geometryTypeIndex_;
|
||||
|
||||
/**
|
||||
* @type {Object.<ol.geom.GeometryType, ol.structs.RTree>}
|
||||
* @private
|
||||
*/
|
||||
this.boundsByGeometryType_;
|
||||
|
||||
this.clear();
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clear the cache.
|
||||
*/
|
||||
ol.layer.FeatureCache.prototype.clear = function() {
|
||||
this.idLookup_ = {};
|
||||
|
||||
var geometryTypeIndex = {},
|
||||
boundsByGeometryType = {},
|
||||
geometryType;
|
||||
for (var key in ol.geom.GeometryType) {
|
||||
geometryType = ol.geom.GeometryType[key];
|
||||
geometryTypeIndex[geometryType] = {};
|
||||
boundsByGeometryType[geometryType] = new ol.structs.RTree();
|
||||
}
|
||||
this.geometryTypeIndex_ = geometryTypeIndex;
|
||||
this.boundsByGeometryType_ = boundsByGeometryType;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add a feature to the cache.
|
||||
* @param {ol.Feature} feature Feature to be cached.
|
||||
*/
|
||||
ol.layer.FeatureCache.prototype.add = function(feature) {
|
||||
var id = goog.getUid(feature).toString(),
|
||||
geometry = feature.getGeometry();
|
||||
|
||||
this.idLookup_[id] = feature;
|
||||
|
||||
// index by geometry type and bounding box
|
||||
if (!goog.isNull(geometry)) {
|
||||
var geometryType = geometry.getType();
|
||||
this.geometryTypeIndex_[geometryType][id] = feature;
|
||||
this.boundsByGeometryType_[geometryType].put(geometry.getBounds(),
|
||||
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) {
|
||||
var i, features;
|
||||
if (!goog.isDef(opt_filter)) {
|
||||
features = this.idLookup_;
|
||||
} else {
|
||||
if (opt_filter instanceof ol.filter.Geometry) {
|
||||
features = this.geometryTypeIndex_[opt_filter.getType()];
|
||||
} else if (opt_filter instanceof ol.filter.Extent) {
|
||||
var boundsByGeometryType = this.boundsByGeometryType_,
|
||||
extent = opt_filter.getExtent();
|
||||
features = {};
|
||||
for (i in boundsByGeometryType) {
|
||||
goog.object.extend(features, boundsByGeometryType[i].find(extent));
|
||||
}
|
||||
} else if (opt_filter instanceof ol.filter.Logical &&
|
||||
opt_filter.operator === ol.filter.LogicalOperator.AND) {
|
||||
var filters = opt_filter.getFilters();
|
||||
if (filters.length === 2) {
|
||||
var filter, geometryFilter, extentFilter;
|
||||
for (i = 0; i <= 1; ++i) {
|
||||
filter = filters[i];
|
||||
if (filter instanceof ol.filter.Geometry) {
|
||||
geometryFilter = filter;
|
||||
} else if (filter instanceof ol.filter.Extent) {
|
||||
extentFilter = filter;
|
||||
}
|
||||
}
|
||||
if (extentFilter && geometryFilter) {
|
||||
features = this.boundsByGeometryType_[geometryFilter.getType()]
|
||||
.find(extentFilter.getExtent());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!goog.isDef(features)) {
|
||||
// TODO: support fast lane for other filter types
|
||||
var candidates = this.idLookup_,
|
||||
feature;
|
||||
features = {};
|
||||
for (i in candidates) {
|
||||
feature = candidates[i];
|
||||
if (opt_filter.applies(feature) === true) {
|
||||
features[i] = feature;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return features;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
ol.layer.FeatureCache.prototype.getFeaturesByGeometryType_ = function(filter) {
|
||||
return goog.object.getValues(this.geometryTypeIndex_[filter.getType()]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get features by ids.
|
||||
* @param {Array.<string>} ids Array of (internal) identifiers.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
* @private
|
||||
*/
|
||||
ol.layer.FeatureCache.prototype.getFeaturesByIds_ = function(ids) {
|
||||
var len = ids.length,
|
||||
features = new Array(len),
|
||||
i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
features[i] = this.idLookup_[ids[i]];
|
||||
}
|
||||
return features;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.layer.Layer}
|
||||
@@ -21,10 +181,26 @@ ol.layer.Vector = function(layerOptions) {
|
||||
*/
|
||||
this.style_ = goog.isDef(layerOptions.style) ? layerOptions.style : null;
|
||||
|
||||
/**
|
||||
* @type {ol.layer.FeatureCache}
|
||||
* @private
|
||||
*/
|
||||
this.featureCache_ = new ol.layer.FeatureCache();
|
||||
|
||||
};
|
||||
goog.inherits(ol.layer.Vector, ol.layer.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<ol.Feature>} features Array of features.
|
||||
*/
|
||||
ol.layer.Vector.prototype.addFeatures = function(features) {
|
||||
for (var i = 0, ii = features.length; i < ii; ++i) {
|
||||
this.featureCache_.add(features[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.source.Vector} Source.
|
||||
*/
|
||||
@@ -33,6 +209,15 @@ ol.layer.Vector.prototype.getVectorSource = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.filter.Filter=} opt_filter Optional filter.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
*/
|
||||
ol.layer.Vector.prototype.getFeatures = function(opt_filter) {
|
||||
return this.featureCache_.getFeatures(opt_filter);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<ol.Feature>} features Features.
|
||||
* @return {Array.<Array>} symbolizers for features.
|
||||
@@ -72,3 +257,10 @@ ol.layer.Vector.prototype.groupFeaturesBySymbolizerLiteral =
|
||||
}
|
||||
return featuresBySymbolizer;
|
||||
};
|
||||
|
||||
|
||||
goog.require('ol.filter.Extent');
|
||||
goog.require('ol.filter.Geometry');
|
||||
goog.require('ol.filter.Logical');
|
||||
goog.require('ol.filter.LogicalOperator');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
|
||||
@@ -167,11 +167,10 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
|
||||
resolution = view2DState.resolution,
|
||||
extent = frameState.extent,
|
||||
layer = this.getVectorLayer(),
|
||||
source = layer.getVectorSource(),
|
||||
tileGrid = this.tileGrid_;
|
||||
|
||||
if (goog.isNull(tileGrid)) {
|
||||
// lazy tile source creation to match the view projection
|
||||
// lazy tile grid creation to match the view projection
|
||||
tileGrid = ol.tilegrid.createForProjection(
|
||||
view2DState.projection,
|
||||
22, // should be no harm in going big here - ideally, it would be ∞
|
||||
@@ -282,7 +281,7 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
|
||||
for (i = 0; i < numFilters; ++i) {
|
||||
geomFilter = filters[i];
|
||||
type = geomFilter.getType();
|
||||
features = source.getFeatures(new ol.filter.Logical(
|
||||
features = layer.getFeatures(new ol.filter.Logical(
|
||||
[geomFilter, extentFilter], ol.filter.LogicalOperator.AND));
|
||||
if (features.length) {
|
||||
groups = layer.groupFeaturesBySymbolizerLiteral(features);
|
||||
|
||||
@@ -11,166 +11,6 @@ goog.require('ol.filter.Logical');
|
||||
goog.require('ol.filter.LogicalOperator');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.source.Source');
|
||||
goog.require('ol.structs.RTree');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
ol.source.FeatureCache = function() {
|
||||
|
||||
/**
|
||||
* @type {Object.<string, ol.Feature>}
|
||||
* @private
|
||||
*/
|
||||
this.idLookup_;
|
||||
|
||||
/**
|
||||
* @type {Object.<string, ol.Feature>}
|
||||
* @private
|
||||
*/
|
||||
this.geometryTypeIndex_;
|
||||
|
||||
/**
|
||||
* @type {Object.<ol.geom.GeometryType, ol.structs.RTree>}
|
||||
* @private
|
||||
*/
|
||||
this.boundsByGeometryType_;
|
||||
|
||||
this.clear();
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clear the cache.
|
||||
*/
|
||||
ol.source.FeatureCache.prototype.clear = function() {
|
||||
this.idLookup_ = {};
|
||||
|
||||
var geometryTypeIndex = {},
|
||||
boundsByGeometryType = {},
|
||||
geometryType;
|
||||
for (var key in ol.geom.GeometryType) {
|
||||
geometryType = ol.geom.GeometryType[key];
|
||||
geometryTypeIndex[geometryType] = {};
|
||||
boundsByGeometryType[geometryType] = new ol.structs.RTree();
|
||||
}
|
||||
this.geometryTypeIndex_ = geometryTypeIndex;
|
||||
this.boundsByGeometryType_ = boundsByGeometryType;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add a feature to the cache.
|
||||
* @param {ol.Feature} feature Feature to be cached.
|
||||
*/
|
||||
ol.source.FeatureCache.prototype.add = function(feature) {
|
||||
var id = goog.getUid(feature).toString(),
|
||||
geometry = feature.getGeometry();
|
||||
|
||||
this.idLookup_[id] = feature;
|
||||
|
||||
// index by geometry type and bounding box
|
||||
if (!goog.isNull(geometry)) {
|
||||
var geometryType = geometry.getType();
|
||||
this.geometryTypeIndex_[geometryType][id] = feature;
|
||||
this.boundsByGeometryType_[geometryType].put(geometry.getBounds(),
|
||||
feature);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.filter.Filter=} opt_filter Optional filter.
|
||||
* @return {Object.<string, ol.Feature>} Object of features, keyed by id.
|
||||
* @private
|
||||
*/
|
||||
ol.source.FeatureCache.prototype.getFeaturesObject_ = function(opt_filter) {
|
||||
var i, features;
|
||||
if (!goog.isDef(opt_filter)) {
|
||||
features = this.idLookup_;
|
||||
} else {
|
||||
if (opt_filter instanceof ol.filter.Geometry) {
|
||||
features = this.geometryTypeIndex_[opt_filter.getType()];
|
||||
} else if (opt_filter instanceof ol.filter.Extent) {
|
||||
var boundsByGeometryType = this.boundsByGeometryType_,
|
||||
extent = opt_filter.getExtent();
|
||||
features = {};
|
||||
for (i in boundsByGeometryType) {
|
||||
goog.object.extend(features, boundsByGeometryType[i].find(extent));
|
||||
}
|
||||
} else if (opt_filter instanceof ol.filter.Logical &&
|
||||
opt_filter.operator === ol.filter.LogicalOperator.AND) {
|
||||
var filters = opt_filter.getFilters();
|
||||
if (filters.length === 2) {
|
||||
var filter, geometryFilter, extentFilter;
|
||||
for (i = 0; i <= 1; ++i) {
|
||||
filter = filters[i];
|
||||
if (filter instanceof ol.filter.Geometry) {
|
||||
geometryFilter = filter;
|
||||
} else if (filter instanceof ol.filter.Extent) {
|
||||
extentFilter = filter;
|
||||
}
|
||||
}
|
||||
if (extentFilter && geometryFilter) {
|
||||
features = this.boundsByGeometryType_[geometryFilter.getType()]
|
||||
.find(extentFilter.getExtent());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!goog.isDef(features)) {
|
||||
// TODO: support fast lane for other filter types
|
||||
var candidates = this.idLookup_,
|
||||
feature;
|
||||
features = {};
|
||||
for (i in candidates) {
|
||||
feature = candidates[i];
|
||||
if (opt_filter.applies(feature) === true) {
|
||||
features[i] = feature;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return features;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
ol.source.FeatureCache.prototype.getFeaturesByGeometryType_ = function(filter) {
|
||||
return goog.object.getValues(this.geometryTypeIndex_[filter.getType()]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get features by ids.
|
||||
* @param {Array.<string>} ids Array of (internal) identifiers.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
* @private
|
||||
*/
|
||||
ol.source.FeatureCache.prototype.getFeaturesByIds_ = function(ids) {
|
||||
var len = ids.length,
|
||||
features = new Array(len),
|
||||
i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
features[i] = this.idLookup_[ids[i]];
|
||||
}
|
||||
return features;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@@ -195,30 +35,5 @@ ol.source.Vector = function(options) {
|
||||
projection: options.projection
|
||||
});
|
||||
|
||||
/**
|
||||
* @type {ol.source.FeatureCache}
|
||||
* @private
|
||||
*/
|
||||
this.featureCache_ = new ol.source.FeatureCache();
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.Vector, ol.source.Source);
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<ol.Feature>} features Array of features.
|
||||
*/
|
||||
ol.source.Vector.prototype.addFeatures = function(features) {
|
||||
for (var i = 0, ii = features.length; i < ii; ++i) {
|
||||
this.featureCache_.add(features[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.filter.Filter=} opt_filter Optional filter.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
*/
|
||||
ol.source.Vector.prototype.getFeatures = function(opt_filter) {
|
||||
return this.featureCache_.getFeatures(opt_filter);
|
||||
};
|
||||
|
||||
@@ -2,6 +2,99 @@ goog.provide('ol.test.layer.Vector');
|
||||
|
||||
describe('ol.layer.Vector', function() {
|
||||
|
||||
describe('#addFeatures()', function() {
|
||||
|
||||
it('allows adding features', function() {
|
||||
var layer = new ol.layer.Vector({
|
||||
new ol.source.Vector({})
|
||||
});
|
||||
layer.addFeatures([new ol.Feature(), new ol.Feature()]);
|
||||
expect(layer.getFeatures().length).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getFeatures()', function() {
|
||||
|
||||
var layer, features;
|
||||
|
||||
beforeEach(function() {
|
||||
features = [
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.0, 48.0])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.1, 48.1])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.2, 48.2])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.3, 48.3])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[16.4, 48.4], [16.5, 48.5]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[16.6, 48.6], [16.7, 48.7]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[16.8, 48.8], [16.9, 48.9]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[17.0, 49.0], [17.1, 49.1]])
|
||||
})
|
||||
];
|
||||
layer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({})
|
||||
});
|
||||
layer.addFeatures(features);
|
||||
});
|
||||
|
||||
var geomFilter = new ol.filter.Geometry(ol.geom.GeometryType.LINESTRING);
|
||||
var extentFilter = new ol.filter.Extent(new ol.Extent(16, 48, 16.3, 48.3));
|
||||
|
||||
it('can filter by geometry type using its GeometryType index', function() {
|
||||
spyOn(geomFilter, 'applies');
|
||||
var lineStrings = layer.getFeatures(geomFilter);
|
||||
expect(geomFilter.applies).not.toHaveBeenCalled();
|
||||
expect(lineStrings.length).toEqual(4);
|
||||
expect(lineStrings).toContain(features[4]);
|
||||
});
|
||||
|
||||
it('can filter by extent using its RTree', function() {
|
||||
spyOn(extentFilter, 'applies');
|
||||
var subset = layer.getFeatures(extentFilter);
|
||||
expect(extentFilter.applies).not.toHaveBeenCalled();
|
||||
expect(subset.length).toEqual(4);
|
||||
expect(subset).not.toContain(features[7]);
|
||||
});
|
||||
|
||||
it('can filter by extent and geometry type using its index', function() {
|
||||
var filter1 = new ol.filter.Logical([geomFilter, extentFilter],
|
||||
ol.filter.LogicalOperator.AND);
|
||||
var filter2 = new ol.filter.Logical([extentFilter, geomFilter],
|
||||
ol.filter.LogicalOperator.AND);
|
||||
spyOn(filter1, 'applies');
|
||||
spyOn(filter2, 'applies');
|
||||
var subset1 = layer.getFeatures(filter1);
|
||||
var subset2 = layer.getFeatures(filter2);
|
||||
expect(filter1.applies).not.toHaveBeenCalled();
|
||||
expect(filter2.applies).not.toHaveBeenCalled();
|
||||
expect(subset1.length).toEqual(0);
|
||||
expect(subset2.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('can handle query using the filter\'s applies function', function() {
|
||||
var filter = new ol.filter.Logical([geomFilter, extentFilter],
|
||||
ol.filter.LogicalOperator.OR);
|
||||
spyOn(filter, 'applies').andCallThrough();
|
||||
var subset = layer.getFeatures(filter);
|
||||
expect(filter.applies).toHaveBeenCalled();
|
||||
expect(subset.length).toEqual(8);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#groupFeaturesBySymbolizerLiteral()', function() {
|
||||
|
||||
var layer = new ol.layer.Vector({
|
||||
@@ -84,8 +177,16 @@ describe('ol.layer.Vector', function() {
|
||||
});
|
||||
|
||||
goog.require('ol.Expression');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.filter.Extent');
|
||||
goog.require('ol.filter.Geometry');
|
||||
goog.require('ol.filter.Logical');
|
||||
goog.require('ol.filter.LogicalOperator');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.projection');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
@@ -3,112 +3,15 @@ goog.provide('ol.test.source.Vector');
|
||||
|
||||
describe('ol.source.Vector', function() {
|
||||
|
||||
var vectorSource;
|
||||
|
||||
describe('#addFeatures()', function() {
|
||||
|
||||
it('works', function() {
|
||||
vectorSource = new ol.source.Vector({
|
||||
projection: ol.projection.getFromCode('EPSG:4326')
|
||||
});
|
||||
vectorSource.addFeatures([new ol.Feature()]);
|
||||
expect(vectorSource.getFeatures().length).toEqual(1);
|
||||
describe('constructor', function() {
|
||||
it('creates an instance', function() {
|
||||
var source = new ol.source.Vector({});
|
||||
expect(source).toBeA(ol.source.Vector);
|
||||
expect(source).toBeA(ol.source.Source);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getFeatures()', function() {
|
||||
|
||||
var features;
|
||||
|
||||
beforeEach(function() {
|
||||
features = [
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.0, 48.0])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.1, 48.1])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.2, 48.2])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.3, 48.3])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[16.4, 48.4], [16.5, 48.5]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[16.6, 48.6], [16.7, 48.7]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[16.8, 48.8], [16.9, 48.9]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[17.0, 49.0], [17.1, 49.1]])
|
||||
})
|
||||
];
|
||||
vectorSource = new ol.source.Vector({
|
||||
projection: ol.projection.getFromCode('EPSG:4326')
|
||||
});
|
||||
vectorSource.addFeatures(features);
|
||||
});
|
||||
|
||||
var geomFilter = new ol.filter.Geometry(ol.geom.GeometryType.LINESTRING);
|
||||
var extentFilter = new ol.filter.Extent(new ol.Extent(16, 48, 16.3, 48.3));
|
||||
|
||||
it('can filter by geometry type using its GeometryType index', function() {
|
||||
spyOn(geomFilter, 'applies');
|
||||
var lineStrings = vectorSource.getFeatures(geomFilter);
|
||||
expect(geomFilter.applies).not.toHaveBeenCalled();
|
||||
expect(lineStrings.length).toEqual(4);
|
||||
expect(lineStrings).toContain(features[4]);
|
||||
});
|
||||
|
||||
it('can filter by extent using its RTree', function() {
|
||||
spyOn(extentFilter, 'applies');
|
||||
var subset = vectorSource.getFeatures(extentFilter);
|
||||
expect(extentFilter.applies).not.toHaveBeenCalled();
|
||||
expect(subset.length).toEqual(4);
|
||||
expect(subset).not.toContain(features[7]);
|
||||
});
|
||||
|
||||
it('can filter by extent and geometry type using its index', function() {
|
||||
var filter1 = new ol.filter.Logical([geomFilter, extentFilter],
|
||||
ol.filter.LogicalOperator.AND);
|
||||
var filter2 = new ol.filter.Logical([extentFilter, geomFilter],
|
||||
ol.filter.LogicalOperator.AND);
|
||||
spyOn(filter1, 'applies');
|
||||
spyOn(filter2, 'applies');
|
||||
var subset1 = vectorSource.getFeatures(filter1);
|
||||
var subset2 = vectorSource.getFeatures(filter2);
|
||||
expect(filter1.applies).not.toHaveBeenCalled();
|
||||
expect(filter2.applies).not.toHaveBeenCalled();
|
||||
expect(subset1.length).toEqual(0);
|
||||
expect(subset2.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('can handle query using the filter\'s applies function', function() {
|
||||
var filter = new ol.filter.Logical([geomFilter, extentFilter],
|
||||
ol.filter.LogicalOperator.OR);
|
||||
spyOn(filter, 'applies').andCallThrough();
|
||||
var subset = vectorSource.getFeatures(filter);
|
||||
expect(filter.applies).toHaveBeenCalled();
|
||||
expect(subset.length).toEqual(8);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.filter.Extent');
|
||||
goog.require('ol.filter.Geometry');
|
||||
goog.require('ol.filter.Logical');
|
||||
goog.require('ol.filter.LogicalOperator');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.source.Source');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.projection');
|
||||
|
||||
Reference in New Issue
Block a user