diff --git a/examples/gml.js b/examples/gml.js
index b61d50a199..373028937d 100644
--- a/examples/gml.js
+++ b/examples/gml.js
@@ -4,7 +4,6 @@ goog.require('ol.View2D');
goog.require('ol.layer.TileLayer');
goog.require('ol.layer.Vector');
goog.require('ol.parser.ogc.GML_v3');
-goog.require('ol.proj');
goog.require('ol.source.MapQuestOpenAerial');
goog.require('ol.source.Vector');
goog.require('ol.style.Polygon');
@@ -17,7 +16,8 @@ var raster = new ol.layer.TileLayer({
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
- projection: ol.proj.get('EPSG:4326')
+ parser: new ol.parser.ogc.GML_v3({axisOrientation: 'neu'}),
+ url: 'data/gml/topp-states-wfs.xml'
}),
style: new ol.style.Style({rules: [
new ol.style.Rule({
@@ -39,22 +39,3 @@ var map = new ol.Map({
zoom: 4
})
});
-
-var gml = new ol.parser.ogc.GML_v3({axisOrientation: 'neu'});
-
-var url = 'data/gml/topp-states-wfs.xml';
-var xhr = new XMLHttpRequest();
-xhr.open('GET', url, true);
-
-
-/**
- * onload handler for the XHR request.
- */
-xhr.onload = function() {
- if (xhr.status == 200) {
- // this is silly to have to tell the layer the destination projection
- var projection = map.getView().getProjection();
- vector.parseFeatures(xhr.responseText, gml, projection);
- }
-};
-xhr.send();
diff --git a/examples/gpx.js b/examples/gpx.js
index d709cdfcc0..44e307effb 100644
--- a/examples/gpx.js
+++ b/examples/gpx.js
@@ -4,7 +4,6 @@ goog.require('ol.View2D');
goog.require('ol.layer.TileLayer');
goog.require('ol.layer.Vector');
goog.require('ol.parser.GPX');
-goog.require('ol.proj');
goog.require('ol.source.OSM');
goog.require('ol.source.Vector');
@@ -14,7 +13,8 @@ var raster = new ol.layer.TileLayer({
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
- projection: ol.proj.get('EPSG:4326')
+ parser: new ol.parser.GPX(),
+ url: 'data/gpx/yahoo.xml'
}),
transformFeatureInfo: function(features) {
var info = [];
@@ -44,22 +44,3 @@ map.on(['click', 'mousemove'], function(evt) {
}
});
});
-
-var gpx = new ol.parser.GPX();
-
-var url = 'data/gpx/yahoo.xml';
-var xhr = new XMLHttpRequest();
-xhr.open('GET', url, true);
-
-
-/**
- * onload handler for the XHR request.
- */
-xhr.onload = function() {
- if (xhr.status == 200) {
- // this is silly to have to tell the layer the destination projection
- var projection = map.getView().getProjection();
- vector.parseFeatures(xhr.responseText, gpx, projection);
- }
-};
-xhr.send();
diff --git a/examples/kml-timezones.js b/examples/kml-timezones.js
index 7c5db6b48c..ff4209d03a 100644
--- a/examples/kml-timezones.js
+++ b/examples/kml-timezones.js
@@ -5,7 +5,6 @@ goog.require('ol.expr');
goog.require('ol.layer.TileLayer');
goog.require('ol.layer.Vector');
goog.require('ol.parser.KML');
-goog.require('ol.proj');
goog.require('ol.source.Stamen');
goog.require('ol.source.Vector');
goog.require('ol.style.Polygon');
@@ -55,7 +54,8 @@ var style = new ol.style.Style({rules: [
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
- projection: ol.proj.get('EPSG:4326')
+ parser: new ol.parser.KML({dimension: 2}),
+ url: 'data/kml/timezones.kml'
}),
style: style
});
@@ -103,21 +103,3 @@ map.on(['click', 'mousemove'], function(evt) {
}
});
});
-
-var kml = new ol.parser.KML({dimension: 2});
-
-var url = 'data/kml/timezones.kml';
-var xhr = new XMLHttpRequest();
-xhr.open('GET', url, true);
-
-
-/**
- * onload handler for the XHR request.
- */
-xhr.onload = function() {
- if (xhr.status == 200) {
- var projection = map.getView().getProjection();
- vector.parseFeatures(xhr.responseText, kml, projection);
- }
-};
-xhr.send();
diff --git a/examples/kml.js b/examples/kml.js
index 885ab94ff0..772eb74928 100644
--- a/examples/kml.js
+++ b/examples/kml.js
@@ -4,7 +4,6 @@ goog.require('ol.View2D');
goog.require('ol.layer.TileLayer');
goog.require('ol.layer.Vector');
goog.require('ol.parser.KML');
-goog.require('ol.proj');
goog.require('ol.source.TiledWMS');
goog.require('ol.source.Vector');
@@ -20,11 +19,12 @@ var raster = new ol.layer.TileLayer({
})
});
-var epsg4326 = ol.proj.get('EPSG:4326');
-
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
- projection: epsg4326
+ parser: new ol.parser.KML({
+ maxDepth: 1, dimension: 2, extractStyles: true, extractAttributes: true
+ }),
+ url: 'data/kml/lines.kml'
}),
transformFeatureInfo: function(features) {
var info = [];
@@ -40,15 +40,12 @@ var map = new ol.Map({
renderer: ol.RendererHint.CANVAS,
target: 'map',
view: new ol.View2D({
- projection: epsg4326,
+ projection: 'EPSG:4326',
center: [-112.169, 36.099],
zoom: 11
})
});
-var kml = new ol.parser.KML({
- maxDepth: 1, dimension: 2, extractStyles: true, extractAttributes: true});
-
map.on(['click', 'mousemove'], function(evt) {
map.getFeatureInfo({
pixel: evt.getPixel(),
@@ -58,19 +55,3 @@ map.on(['click', 'mousemove'], function(evt) {
}
});
});
-
-var url = 'data/kml/lines.kml';
-var xhr = new XMLHttpRequest();
-xhr.open('GET', url, true);
-
-
-/**
- * onload handler for the XHR request.
- */
-xhr.onload = function() {
- if (xhr.status == 200) {
- // this is silly to have to tell the layer the destination projection
- vector.parseFeatures(xhr.responseText, kml, epsg4326);
- }
-};
-xhr.send();
diff --git a/examples/style-rules.js b/examples/style-rules.js
index eafea47bd7..6e98f675ec 100644
--- a/examples/style-rules.js
+++ b/examples/style-rules.js
@@ -60,112 +60,111 @@ var style = new ol.style.Style({rules: [
var vector = new ol.layer.Vector({
style: style,
source: new ol.source.Vector({
+ data: {
+ 'type': 'FeatureCollection',
+ 'features': [{
+ 'type': 'Feature',
+ 'properties': {
+ 'color': '#BADA55',
+ 'where': 'inner'
+ },
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [[-10000000, -10000000], [10000000, 10000000]]
+ }
+ }, {
+ 'type': 'Feature',
+ 'properties': {
+ 'color': '#BADA55',
+ 'where': 'inner'
+ },
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [[-10000000, 10000000], [10000000, -10000000]]
+ }
+ }, {
+ 'type': 'Feature',
+ 'properties': {
+ 'color': '#013',
+ 'where': 'outer'
+ },
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [[-10000000, -10000000], [-10000000, 10000000]]
+ }
+ }, {
+ 'type': 'Feature',
+ 'properties': {
+ 'color': '#013',
+ 'where': 'outer'
+ },
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [[-10000000, 10000000], [10000000, 10000000]]
+ }
+ }, {
+ 'type': 'Feature',
+ 'properties': {
+ 'color': '#013',
+ 'where': 'outer'
+ },
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [[10000000, 10000000], [10000000, -10000000]]
+ }
+ }, {
+ 'type': 'Feature',
+ 'properties': {
+ 'color': '#013',
+ 'where': 'outer'
+ },
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [[10000000, -10000000], [-10000000, -10000000]]
+ }
+ }, {
+ 'type': 'Feature',
+ 'properties': {
+ 'label': 'South'
+ },
+ 'geometry': {
+ 'type': 'Point',
+ 'coordinates': [0, -6000000]
+ }
+ }, {
+ 'type': 'Feature',
+ 'properties': {
+ 'label': 'West'
+ },
+ 'geometry': {
+ 'type': 'Point',
+ 'coordinates': [-6000000, 0]
+ }
+ }, {
+ 'type': 'Feature',
+ 'properties': {
+ 'label': 'North'
+ },
+ 'geometry': {
+ 'type': 'Point',
+ 'coordinates': [0, 6000000]
+ }
+ }, {
+ 'type': 'Feature',
+ 'properties': {
+ 'label': 'East'
+ },
+ 'geometry': {
+ 'type': 'Point',
+ 'coordinates': [6000000, 0]
+ }
+ }]
+ },
+ parser: new ol.parser.GeoJSON(),
projection: ol.proj.get('EPSG:3857')
})
});
-vector.parseFeatures({
- 'type': 'FeatureCollection',
- 'features': [{
- 'type': 'Feature',
- 'properties': {
- 'color': '#BADA55',
- 'where': 'inner'
- },
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [[-10000000, -10000000], [10000000, 10000000]]
- }
- }, {
- 'type': 'Feature',
- 'properties': {
- 'color': '#BADA55',
- 'where': 'inner'
- },
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [[-10000000, 10000000], [10000000, -10000000]]
- }
- }, {
- 'type': 'Feature',
- 'properties': {
- 'color': '#013',
- 'where': 'outer'
- },
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [[-10000000, -10000000], [-10000000, 10000000]]
- }
- }, {
- 'type': 'Feature',
- 'properties': {
- 'color': '#013',
- 'where': 'outer'
- },
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [[-10000000, 10000000], [10000000, 10000000]]
- }
- }, {
- 'type': 'Feature',
- 'properties': {
- 'color': '#013',
- 'where': 'outer'
- },
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [[10000000, 10000000], [10000000, -10000000]]
- }
- }, {
- 'type': 'Feature',
- 'properties': {
- 'color': '#013',
- 'where': 'outer'
- },
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [[10000000, -10000000], [-10000000, -10000000]]
- }
- }, {
- 'type': 'Feature',
- 'properties': {
- 'label': 'South'
- },
- 'geometry': {
- 'type': 'Point',
- 'coordinates': [0, -6000000]
- }
- }, {
- 'type': 'Feature',
- 'properties': {
- 'label': 'West'
- },
- 'geometry': {
- 'type': 'Point',
- 'coordinates': [-6000000, 0]
- }
- }, {
- 'type': 'Feature',
- 'properties': {
- 'label': 'North'
- },
- 'geometry': {
- 'type': 'Point',
- 'coordinates': [0, 6000000]
- }
- }, {
- 'type': 'Feature',
- 'properties': {
- 'label': 'East'
- },
- 'geometry': {
- 'type': 'Point',
- 'coordinates': [6000000, 0]
- }
- }]
-}, new ol.parser.GeoJSON(), ol.proj.get('EPSG:3857'));
-
-
var map = new ol.Map({
layers: [vector],
controls: ol.control.defaults({
diff --git a/examples/vector-layer.js b/examples/vector-layer.js
index 05774f56f5..23b8f9e4ee 100644
--- a/examples/vector-layer.js
+++ b/examples/vector-layer.js
@@ -5,7 +5,6 @@ goog.require('ol.expr');
goog.require('ol.layer.TileLayer');
goog.require('ol.layer.Vector');
goog.require('ol.parser.GeoJSON');
-goog.require('ol.proj');
goog.require('ol.source.MapQuestOpenAerial');
goog.require('ol.source.Vector');
goog.require('ol.style.Polygon');
@@ -25,7 +24,8 @@ ol.expr.register('resolution', function() {
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
- projection: ol.proj.get('EPSG:4326')
+ parser: new ol.parser.GeoJSON(),
+ url: 'data/countries.geojson'
}),
style: new ol.style.Style({rules: [
new ol.style.Rule({
@@ -72,22 +72,3 @@ map.on(['click', 'mousemove'], function(evt) {
}
});
});
-
-
-var geojson = new ol.parser.GeoJSON();
-var url = 'data/countries.geojson';
-var xhr = new XMLHttpRequest();
-xhr.open('GET', url, true);
-
-
-/**
- * onload handler for the XHR request.
- */
-xhr.onload = function() {
- if (xhr.status == 200) {
- // this is silly to have to tell the layer the destination projection
- var projection = map.getView().getProjection();
- vector.parseFeatures(xhr.responseText, geojson, projection);
- }
-};
-xhr.send();
diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc
index 215f8d1328..fdbf4f59e7 100644
--- a/src/objectliterals.jsdoc
+++ b/src/objectliterals.jsdoc
@@ -499,6 +499,20 @@
* of `url` when the WMS supports multiple urls for GetMap requests.
*/
+/**
+ * @typedef {Object} ol.source.VectorOptions
+ * @property {Array.
|undefined} attributions Attributions.
+ * @property {Object|string|undefined} data Data to parse.
+ * @property {ol.Extent|undefined} extent Extent.
+ * @property {string|undefined} logo Logo.
+ * @property {ol.parser.Parser} parser Parser instance to parse data
+ * provided as `data` or fetched from `url`.
+ * @property {ol.ProjectionLike|undefined} projection Projection. EPSG:4326
+ * is assumed if not defined. TODO: Get projection from the parser instead
+ * of assuming EPSG:4326.
+ * @property {string|undefined} url Server url providing the vector data.
+ */
+
/**
* @typedef {Object} ol.source.VectorSource2Options
* @property {Array.|undefined} attributions Attributions.
diff --git a/src/ol/layer/vectorlayer.exports b/src/ol/layer/vectorlayer.exports
index 669da99ad1..fa79c6b730 100644
--- a/src/ol/layer/vectorlayer.exports
+++ b/src/ol/layer/vectorlayer.exports
@@ -1,4 +1,3 @@
@exportClass ol.layer.Vector ol.layer.VectorLayerOptions
@exportProperty ol.layer.Vector.prototype.addFeatures
-@exportProperty ol.layer.Vector.prototype.parseFeatures
diff --git a/src/ol/layer/vectorlayer.js b/src/ol/layer/vectorlayer.js
index 264c4c9fa4..fdef16b75a 100644
--- a/src/ol/layer/vectorlayer.js
+++ b/src/ol/layer/vectorlayer.js
@@ -279,34 +279,26 @@ ol.layer.Vector.prototype.getVectorSource = function() {
/**
- * @param {ol.expr.Expression=} opt_expr Expression for filtering.
- * @return {Array.} Array of features.
- */
-ol.layer.Vector.prototype.getFeatures = function(opt_expr) {
- return goog.object.getValues(
- this.featureCache_.getFeaturesObject(opt_expr));
-};
-
-
-/**
- * @param {ol.expr.Expression=} opt_expr Expression for filtering.
- * @return {Object.} Features.
- */
-ol.layer.Vector.prototype.getFeaturesObject = function(opt_expr) {
- return this.featureCache_.getFeaturesObject(opt_expr);
-};
-
-
-/**
- * Get all features whose bounding box intersects the provided extent.
+ * Get all features whose bounding box intersects the provided extent. This
+ * method is intended for being called by the renderer. When null is returned,
+ * the renderer should not waste time rendering, and `opt_callback` is
+ * usually a function that requests a renderFrame, which will be called as soon
+ * as the data for `extent` is available.
*
* @param {ol.Extent} extent Bounding extent.
+ * @param {ol.Projection} projection Target projection.
* @param {ol.geom.GeometryType=} opt_type Optional geometry type.
- * @return {Object.} Features.
+ * @param {Function=} opt_callback Callback to call when data is parsed.
+ * @return {Object.} Features or null if source is loading
+ * data for `extent`.
*/
ol.layer.Vector.prototype.getFeaturesObjectForExtent = function(extent,
- opt_type) {
- return this.featureCache_.getFeaturesObjectForExtent(extent, opt_type);
+ projection, opt_type, opt_callback) {
+ var source = this.getSource();
+ return source.prepareFeatures(this, extent, projection, opt_callback) ==
+ ol.source.VectorLoadState.LOADING ?
+ null :
+ this.featureCache_.getFeaturesObjectForExtent(extent, opt_type);
};
diff --git a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js
index 343d783f72..bc378f465c 100644
--- a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js
+++ b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js
@@ -228,9 +228,11 @@ ol.renderer.canvas.VectorLayer.prototype.getFeatureInfoForPixel =
* @param {function(Array., ol.layer.Layer)} success Callback for
* successful queries. The passed arguments are the resulting features
* and the layer.
+ * @param {function()=} opt_error Callback for unsuccessful queries.
*/
ol.renderer.canvas.VectorLayer.prototype.getFeaturesForPixel =
- function(pixel, success) {
+ function(pixel, success, opt_error) {
+ // TODO What do we want to pass to the error callback?
var map = this.getMap();
var result = [];
@@ -247,7 +249,15 @@ ol.renderer.canvas.VectorLayer.prototype.getFeaturesForPixel =
var locationMin = [location[0] - halfMaxWidth, location[1] - halfMaxHeight];
var locationMax = [location[0] + halfMaxWidth, location[1] + halfMaxHeight];
var locationBbox = ol.extent.boundingExtent([locationMin, locationMax]);
- var candidates = layer.getFeaturesObjectForExtent(locationBbox);
+ var candidates = layer.getFeaturesObjectForExtent(locationBbox,
+ map.getView().getView2D().getProjection());
+ if (goog.isNull(candidates)) {
+ // data is not loaded
+ if (goog.isDef(opt_error)) {
+ goog.global.setTimeout(function() { opt_error(); }, 0);
+ }
+ return;
+ }
var candidate, geom, type, symbolBounds, symbolSize, halfWidth, halfHeight,
coordinates, j;
@@ -446,6 +456,7 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
dirty = false,
i, type, tileExtent,
groups, group, j, numGroups, featuresObject, tileHasFeatures;
+ fetchTileData:
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
tileCoord = new ol.TileCoord(0, x, y);
@@ -464,7 +475,12 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
if (!goog.isDef(featuresToRender[type])) {
featuresToRender[type] = {};
}
- featuresObject = layer.getFeaturesObjectForExtent(tileExtent, type);
+ featuresObject = layer.getFeaturesObjectForExtent(tileExtent,
+ projection, type, this.requestMapRenderFrame_);
+ if (goog.isNull(featuresObject)) {
+ deferred = true;
+ break fetchTileData;
+ }
tileHasFeatures = tileHasFeatures ||
!goog.object.isEmpty(featuresObject);
goog.object.extend(featuresToRender[type], featuresObject);
diff --git a/src/ol/source/vectorsource.exports b/src/ol/source/vectorsource.exports
index 27cbc2bea0..d7842f5b84 100644
--- a/src/ol/source/vectorsource.exports
+++ b/src/ol/source/vectorsource.exports
@@ -1 +1 @@
-@exportClass ol.source.Vector ol.source.SourceOptions
+@exportClass ol.source.Vector ol.source.VectorOptions
diff --git a/src/ol/source/vectorsource.js b/src/ol/source/vectorsource.js
index 80a85b5d55..6dee9600cf 100644
--- a/src/ol/source/vectorsource.js
+++ b/src/ol/source/vectorsource.js
@@ -1,15 +1,97 @@
goog.provide('ol.source.Vector');
+goog.require('goog.asserts');
+goog.require('goog.net.XhrIo');
+goog.require('ol.proj');
goog.require('ol.source.Source');
+/**
+ * @enum {number}
+ */
+ol.source.VectorLoadState = {
+ IDLE: 0,
+ LOADING: 1,
+ LOADED: 2,
+ ERROR: 3
+};
+
+
/**
* @constructor
* @extends {ol.source.Source}
- * @param {ol.source.SourceOptions} options Source options.
+ * @param {ol.source.VectorOptions} options Vector source options.
*/
ol.source.Vector = function(options) {
- goog.base(this, options);
+
+ /**
+ * @private
+ * @type {Object|string}
+ */
+ this.data_ = goog.isDef(options.data) ? options.data : null;
+
+ /**
+ * @private
+ * @type {ol.source.VectorLoadState}
+ */
+ this.loadState_ = ol.source.VectorLoadState.IDLE;
+
+ /**
+ * @private
+ * @type {ol.parser.Parser}
+ */
+ this.parser_ = goog.isDef(options.parser) ? options.parser : null;
+
+ /**
+ * @private
+ * @type {string|undefined}
+ */
+ this.url_ = options.url;
+
+ goog.base(this, {
+ attributions: options.attributions,
+ extent: options.extent,
+ logo: options.logo,
+ projection: goog.isDef(options.projection) ?
+ options.projection : ol.proj.get('EPSG:4326')
+ });
};
goog.inherits(ol.source.Vector, ol.source.Source);
+
+
+/**
+ * @param {ol.layer.Vector} layer Layer that parses the data.
+ * @param {ol.Extent} extent Extent that needs to be fetched.
+ * @param {ol.Projection} projection Projection of the view.
+ * @param {function()=} opt_callback Callback which is called when features are
+ * parsed after loading.
+ * @return {ol.source.VectorLoadState} The current load state.
+ */
+ol.source.Vector.prototype.prepareFeatures = function(layer, extent, projection,
+ opt_callback) {
+ // TODO: Implement strategies. BBOX aware strategies will need the extent.
+ if (goog.isDef(this.url_) &&
+ this.loadState_ == ol.source.VectorLoadState.IDLE) {
+ this.loadState_ = ol.source.VectorLoadState.LOADING;
+ goog.net.XhrIo.send(this.url_, goog.bind(function(event) {
+ var xhr = event.target;
+ if (xhr.isSuccess()) {
+ // TODO: Get source projection from data if supported by parser.
+ layer.parseFeatures(xhr.getResponseText(), this.parser_, projection);
+ this.loadState_ = ol.source.VectorLoadState.LOADED;
+ if (goog.isDef(opt_callback)) {
+ opt_callback();
+ }
+ } else {
+ // TODO: Error handling.
+ this.loadState_ = ol.source.VectorLoadState.ERROR;
+ }
+ }, this));
+ } else if (!goog.isNull(this.data_)) {
+ layer.parseFeatures(this.data_, this.parser_, projection);
+ this.data_ = null;
+ this.loadState_ = ol.source.VectorLoadState.LOADED;
+ }
+ return this.loadState_;
+};
diff --git a/test/spec/ol/layer/vectorlayer.test.js b/test/spec/ol/layer/vectorlayer.test.js
index 1525617d6a..8c6c9f06e1 100644
--- a/test/spec/ol/layer/vectorlayer.test.js
+++ b/test/spec/ol/layer/vectorlayer.test.js
@@ -9,11 +9,12 @@ describe('ol.layer.Vector', function() {
source: new ol.source.Vector({})
});
layer.addFeatures([new ol.Feature(), new ol.Feature()]);
- expect(layer.getFeatures().length).to.eql(2);
+ expect(goog.object.getCount(layer.featureCache_.getFeaturesObject()))
+ .to.eql(2);
});
});
- describe('#getFeatures()', function() {
+ describe('ol.layer.FeatureCache#getFeaturesObject()', function() {
var layer, features;
@@ -55,18 +56,18 @@ describe('ol.layer.Vector', function() {
it('can filter by geometry type using its GeometryType index', function() {
sinon.spy(geomFilter, 'evaluate');
- var lineStrings = layer.getFeatures(geomFilter);
+ var lineStrings = layer.featureCache_.getFeaturesObject(geomFilter);
expect(geomFilter.evaluate).to.not.be.called();
- expect(lineStrings.length).to.eql(4);
- expect(lineStrings).to.contain(features[4]);
+ expect(goog.object.getCount(lineStrings)).to.eql(4);
+ expect(goog.object.getValues(lineStrings)).to.contain(features[4]);
});
it('can filter by extent using its RTree', function() {
sinon.spy(extentFilter, 'evaluate');
- var subset = layer.getFeatures(extentFilter);
+ var subset = layer.featureCache_.getFeaturesObject(extentFilter);
expect(extentFilter.evaluate).to.not.be.called();
- expect(subset.length).to.eql(4);
- expect(subset).not.to.contain(features[7]);
+ expect(goog.object.getCount(subset)).to.eql(4);
+ expect(goog.object.getValues(subset)).not.to.contain(features[7]);
});
it('can filter by extent and geometry type using its index', function() {
@@ -76,21 +77,21 @@ describe('ol.layer.Vector', function() {
ol.expr.LogicalOp.AND, extentFilter, geomFilter);
sinon.spy(filter1, 'evaluate');
sinon.spy(filter2, 'evaluate');
- var subset1 = layer.getFeatures(filter1);
- var subset2 = layer.getFeatures(filter2);
+ var subset1 = layer.featureCache_.getFeaturesObject(filter1);
+ var subset2 = layer.featureCache_.getFeaturesObject(filter2);
expect(filter1.evaluate).to.not.be.called();
expect(filter2.evaluate).to.not.be.called();
- expect(subset1.length).to.eql(0);
- expect(subset2.length).to.eql(0);
+ expect(goog.object.getCount(subset1)).to.eql(0);
+ expect(goog.object.getCount(subset2)).to.eql(0);
});
it('can handle query using the filter\'s evaluate function', function() {
var filter = new ol.expr.Logical(
ol.expr.LogicalOp.OR, geomFilter, extentFilter);
sinon.spy(filter, 'evaluate');
- var subset = layer.getFeatures(filter);
+ var subset = layer.featureCache_.getFeaturesObject(filter);
expect(filter.evaluate).to.be.called();
- expect(subset.length).to.eql(8);
+ expect(goog.object.getCount(subset)).to.eql(8);
});
});
@@ -177,6 +178,7 @@ describe('ol.layer.Vector', function() {
});
goog.require('goog.dispose');
+goog.require('goog.object');
goog.require('ol.Feature');
goog.require('ol.expr');
goog.require('ol.expr.Logical');
diff --git a/test/spec/ol/source/vectorsource.test.js b/test/spec/ol/source/vectorsource.test.js
index bef91ced07..ee40475a22 100644
--- a/test/spec/ol/source/vectorsource.test.js
+++ b/test/spec/ol/source/vectorsource.test.js
@@ -11,7 +11,77 @@ describe('ol.source.Vector', function() {
});
});
+ describe('#prepareFeatures', function() {
+ it('loads and parses data from a file', function(done) {
+ var source = new ol.source.Vector({
+ url: 'spec/ol/parser/geojson/countries.geojson',
+ parser: new ol.parser.GeoJSON()
+ });
+ var layer = new ol.layer.Vector({
+ source: source
+ });
+ source.prepareFeatures(layer, [-180, 180, -90, 90],
+ ol.proj.get('EPSG:4326'),
+ function() {
+ expect(source.loadState_).to.be(ol.source.VectorLoadState.LOADED);
+ expect(goog.object.getCount(
+ layer.featureCache_.getFeaturesObject())).to.be(179);
+ done();
+ });
+ });
+
+ it('parses inline data', function() {
+ var source = new ol.source.Vector({
+ data: {
+ 'type': 'FeatureCollection',
+ 'features': [{
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Point',
+ 'coordinates': [0, -6000000]
+ }
+ }, {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Point',
+ 'coordinates': [-6000000, 0]
+ }
+ }, {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Point',
+ 'coordinates': [0, 6000000]
+ }
+ }, {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Point',
+ 'coordinates': [6000000, 0]
+ }
+ }]
+ },
+ parser: new ol.parser.GeoJSON(),
+ projection: ol.proj.get('EPSG:4326')
+ });
+ var layer = new ol.layer.Vector({
+ source: source
+ });
+ source.prepareFeatures(layer, [-180, 180, -90, 90],
+ ol.proj.get('EPSG:4326'),
+ function() {
+ expect(source.loadState_).to.be(ol.source.VectorLoadState.LOADED);
+ expect(goog.object.getCount(
+ layer.featureCache_.getFeaturesObject())).to.be(4);
+ done();
+ });
+ });
+ });
+
});
+goog.require('goog.object');
+goog.require('ol.layer.Vector');
+goog.require('ol.parser.GeoJSON');
+goog.require('ol.proj');
goog.require('ol.source.Source');
goog.require('ol.source.Vector');