diff --git a/changelog/upgrade-notes.md b/changelog/upgrade-notes.md
index dd7dd29110..9f7b60fd5a 100644
--- a/changelog/upgrade-notes.md
+++ b/changelog/upgrade-notes.md
@@ -2,6 +2,8 @@
### v3.5.0
+#### `ol.Object` and `bindTo`
+
* The following experimental methods have been removed from `ol.Object`: `bindTo`, `unbind`, and `unbindAll`. If you want to get notification about `ol.Object` property changes, you can listen for the `'propertychange'` event (e.g. `object.on('propertychange', listener)`). Two-way binding can be set up at the application level using property change listeners. See [#3472](https://github.com/openlayers/ol3/pull/3472) for details on the change.
* The experimental `ol.dom.Input` component has been removed. If you need to synchronize the state of a dom Input element with an `ol.Object`, this can be accomplished using listeners for change events. For example, you might bind the state of a checkbox type input with a layer's visibility like this:
@@ -25,6 +27,91 @@
});
```
+#### New Vector API
+
+* The following experimental vector classes have been removed: `ol.source.GeoJSON`, `ol.source.GML`, `ol.source.GPX`, `ol.source.IGC`, `ol.source.KML`, `ol.source.OSMXML`, and `ol.source.TopoJSON`. You now will use `ol.source.Vector` instead.
+
+ For example, if you used `ol.source.GeoJSON` as follows:
+
+ ```js
+ var source = new ol.source.GeoJSON({
+ url: 'features.json',
+ projection: 'EPSG:3857'
+ });
+ ```
+
+ you will need to change your code to:
+
+ ```js
+ var source = new ol.source.Vector({
+ url: 'features.json',
+ format: new ol.format.GeoJSON()
+ });
+ ```
+
+ See http://openlayers.org/en/master/examples/vector-layer.html for a real example.
+
+ Note that you no longer need to set a `projection` on the source!
+
+ Previously the vector data was loaded at source construction time, and, if the data projection and the source projection were not the same, the vector data was transformed to the source projection before being inserted (as features) into the source.
+
+ The vector data is now loaded at render time, when the view projection is known. And the vector data is transformed to the view projection if the data projection and the source projection are not the same.
+
+ If you still want to "eagerly" load the source you will use something like this:
+
+ ```js
+ var source = new ol.source.Vector();
+ $.ajax('features.json').then(function(response) {
+ var geojsonFormat = new ol.format.GeoJSON();
+ var features = geojsonFormat.readFeatures(response,
+ {featureProjection: 'EPSG:3857'});
+ source.addFeatures(features);
+ });
+ ```
+
+ The above code uses jQuery to send an Ajax request, but you can obviously use any Ajax library.
+
+ See http://openlayers.org/en/master/examples/igc.html for a real example.
+
+* The `ol.source.ServerVector` class has been removed. If you used it, for example as follows:
+
+ ```js
+ var source = new ol.source.ServerVector({
+ format: new ol.format.GeoJSON(),
+ loader: function(extent, resolution, projection) {
+ var url = …;
+ $.ajax(url).then(function(response) {
+ source.addFeatures(source.readFeatures(response));
+ });
+ },
+ strategy: ol.loadingstrategy.bbox,
+ projection: 'EPSG:3857'
+ });
+ ```
+
+ you will need to change your code to:
+
+ ```js
+ var source = new ol.source.Vector({
+ loader: function(extent, resolution, projection) {
+ var url = …;
+ $.ajax(url).then(function(response) {
+ var format = new ol.format.GeoJSON();
+ var features = format.readFeatures(response,
+ {featureProjection: projection});
+ source.addFeatures(features);
+ });
+ },
+ strategy: ol.loadingstrategy.bbox
+ });
+ ```
+
+ See http://openlayers.org/en/master/examples/vector-osm.html for a real example.
+
+* The experimental `ol.loadingstrategy.createTile` function has been renamed to `ol.loadingstrategy.tile`. The signature of the function hasn't changed. See http://openlayers.org/en/master/examples/vector-osm.html for an example.
+
+#### Change to `ol.style.Icon`
+
* When manually loading an image for `ol.style.Icon`, the image size should now be set
with the `imgSize` option and not with `size`. `size` is supposed to be used for the
size of a sub-rectangle in an image sprite.
diff --git a/examples_src/box-selection.js b/examples_src/box-selection.js
index 5a7941e126..33af212a55 100644
--- a/examples_src/box-selection.js
+++ b/examples_src/box-selection.js
@@ -1,19 +1,20 @@
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.events.condition');
+goog.require('ol.format.GeoJSON');
goog.require('ol.interaction.DragBox');
goog.require('ol.interaction.Select');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
-goog.require('ol.source.GeoJSON');
goog.require('ol.source.OSM');
+goog.require('ol.source.Vector');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
-var vectorSource = new ol.source.GeoJSON({
- projection: 'EPSG:3857',
- url: 'data/geojson/countries.geojson'
+var vectorSource = new ol.source.Vector({
+ url: 'data/geojson/countries.geojson',
+ format: new ol.format.GeoJSON()
});
diff --git a/examples_src/center.js b/examples_src/center.js
index 2c63b99bf8..c154b19ebf 100644
--- a/examples_src/center.js
+++ b/examples_src/center.js
@@ -1,20 +1,21 @@
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.control');
+goog.require('ol.format.GeoJSON');
goog.require('ol.geom.Point');
goog.require('ol.geom.SimpleGeometry');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
-goog.require('ol.source.GeoJSON');
goog.require('ol.source.OSM');
+goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
-var source = new ol.source.GeoJSON({
- projection: 'EPSG:3857',
- url: 'data/geojson/switzerland.geojson'
+var source = new ol.source.Vector({
+ url: 'data/geojson/switzerland.geojson',
+ format: new ol.format.GeoJSON()
});
var style = new ol.style.Style({
fill: new ol.style.Fill({
diff --git a/examples_src/earthquake-clusters.js b/examples_src/earthquake-clusters.js
index 0850960250..17c8f5ef66 100644
--- a/examples_src/earthquake-clusters.js
+++ b/examples_src/earthquake-clusters.js
@@ -1,13 +1,14 @@
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.extent');
+goog.require('ol.format.KML');
goog.require('ol.interaction');
goog.require('ol.interaction.Select');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.source.Cluster');
-goog.require('ol.source.KML');
goog.require('ol.source.Stamen');
+goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.RegularShape');
@@ -122,10 +123,10 @@ function selectStyleFunction(feature, resolution) {
var vector = new ol.layer.Vector({
source: new ol.source.Cluster({
distance: 40,
- source: new ol.source.KML({
+ source: new ol.source.Vector({
extractStyles: false,
- projection: 'EPSG:3857',
- url: 'data/kml/2012_Earthquakes_Mag5.kml'
+ url: 'data/kml/2012_Earthquakes_Mag5.kml',
+ format: new ol.format.KML()
})
}),
style: styleFunction
diff --git a/examples_src/export-map.js b/examples_src/export-map.js
index f55f940a53..4b22a09ce8 100644
--- a/examples_src/export-map.js
+++ b/examples_src/export-map.js
@@ -1,10 +1,11 @@
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.control');
+goog.require('ol.format.GeoJSON');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
-goog.require('ol.source.GeoJSON');
goog.require('ol.source.OSM');
+goog.require('ol.source.Vector');
var map = new ol.Map({
layers: [
@@ -12,9 +13,9 @@ var map = new ol.Map({
source: new ol.source.OSM()
}),
new ol.layer.Vector({
- source: new ol.source.GeoJSON({
- projection: 'EPSG:3857',
- url: 'data/geojson/countries.geojson'
+ source: new ol.source.Vector({
+ url: 'data/geojson/countries.geojson',
+ format: new ol.format.GeoJSON()
})
})
],
diff --git a/examples_src/geojson.js b/examples_src/geojson.js
index 4674cf4a33..6d7ce5d26f 100644
--- a/examples_src/geojson.js
+++ b/examples_src/geojson.js
@@ -2,11 +2,12 @@ goog.require('ol.Feature');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.control');
+goog.require('ol.format.GeoJSON');
goog.require('ol.geom.Circle');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
-goog.require('ol.source.GeoJSON');
goog.require('ol.source.OSM');
+goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
@@ -88,91 +89,92 @@ var styleFunction = function(feature, resolution) {
return styles[feature.getGeometry().getType()];
};
-var vectorSource = new ol.source.GeoJSON(
- /** @type {olx.source.GeoJSONOptions} */ ({
- object: {
- 'type': 'FeatureCollection',
- 'crs': {
- 'type': 'name',
- 'properties': {
- 'name': 'EPSG:3857'
- }
- },
- 'features': [
+var geojsonObject = {
+ 'type': 'FeatureCollection',
+ 'crs': {
+ 'type': 'name',
+ 'properties': {
+ 'name': 'EPSG:3857'
+ }
+ },
+ 'features': [
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Point',
+ 'coordinates': [0, 0]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [[4e6, -2e6], [8e6, 2e6]]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [[4e6, 2e6], [8e6, -2e6]]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Polygon',
+ 'coordinates': [[[-5e6, -1e6], [-4e6, 1e6], [-3e6, -1e6]]]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'MultiLineString',
+ 'coordinates': [
+ [[-1e6, -7.5e5], [-1e6, 7.5e5]],
+ [[1e6, -7.5e5], [1e6, 7.5e5]],
+ [[-7.5e5, -1e6], [7.5e5, -1e6]],
+ [[-7.5e5, 1e6], [7.5e5, 1e6]]
+ ]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'MultiPolygon',
+ 'coordinates': [
+ [[[-5e6, 6e6], [-5e6, 8e6], [-3e6, 8e6], [-3e6, 6e6]]],
+ [[[-2e6, 6e6], [-2e6, 8e6], [0, 8e6], [0, 6e6]]],
+ [[[1e6, 6e6], [1e6, 8e6], [3e6, 8e6], [3e6, 6e6]]]
+ ]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'GeometryCollection',
+ 'geometries': [
{
- 'type': 'Feature',
- 'geometry': {
- 'type': 'Point',
- 'coordinates': [0, 0]
- }
+ 'type': 'LineString',
+ 'coordinates': [[-5e6, -5e6], [0, -5e6]]
},
{
- 'type': 'Feature',
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [[4e6, -2e6], [8e6, 2e6]]
- }
+ 'type': 'Point',
+ 'coordinates': [4e6, -5e6]
},
{
- 'type': 'Feature',
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [[4e6, 2e6], [8e6, -2e6]]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'Polygon',
- 'coordinates': [[[-5e6, -1e6], [-4e6, 1e6], [-3e6, -1e6]]]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'MultiLineString',
- 'coordinates': [
- [[-1e6, -7.5e5], [-1e6, 7.5e5]],
- [[1e6, -7.5e5], [1e6, 7.5e5]],
- [[-7.5e5, -1e6], [7.5e5, -1e6]],
- [[-7.5e5, 1e6], [7.5e5, 1e6]]
- ]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'MultiPolygon',
- 'coordinates': [
- [[[-5e6, 6e6], [-5e6, 8e6], [-3e6, 8e6], [-3e6, 6e6]]],
- [[[-2e6, 6e6], [-2e6, 8e6], [0, 8e6], [0, 6e6]]],
- [[[1e6, 6e6], [1e6, 8e6], [3e6, 8e6], [3e6, 6e6]]]
- ]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'GeometryCollection',
- 'geometries': [
- {
- 'type': 'LineString',
- 'coordinates': [[-5e6, -5e6], [0, -5e6]]
- },
- {
- 'type': 'Point',
- 'coordinates': [4e6, -5e6]
- },
- {
- 'type': 'Polygon',
- 'coordinates': [[[1e6, -6e6], [2e6, -4e6], [3e6, -6e6]]]
- }
- ]
- }
+ 'type': 'Polygon',
+ 'coordinates': [[[1e6, -6e6], [2e6, -4e6], [3e6, -6e6]]]
}
]
}
- }));
+ }
+ ]
+};
+
+var vectorSource = new ol.source.Vector({
+ features: (new ol.format.GeoJSON()).readFeatures(geojsonObject)
+});
vectorSource.addFeature(new ol.Feature(new ol.geom.Circle([5e6, 7e6], 1e6)));
diff --git a/examples_src/gpx.js b/examples_src/gpx.js
index d98dceba31..02257ad9b8 100644
--- a/examples_src/gpx.js
+++ b/examples_src/gpx.js
@@ -5,7 +5,7 @@ goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.proj');
goog.require('ol.source.BingMaps');
-goog.require('ol.source.GPX');
+goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
@@ -48,9 +48,9 @@ var style = {
};
var vector = new ol.layer.Vector({
- source: new ol.source.GPX({
- projection: projection,
- url: 'data/gpx/fells_loop.gpx'
+ source: new ol.source.Vector({
+ url: 'data/gpx/fells_loop.gpx',
+ format: new ol.format.GPX()
}),
style: function(feature, resolution) {
return style[feature.getGeometry().getType()];
diff --git a/examples_src/heatmap-earthquakes.js b/examples_src/heatmap-earthquakes.js
index 277ed7fbe3..e93509658c 100644
--- a/examples_src/heatmap-earthquakes.js
+++ b/examples_src/heatmap-earthquakes.js
@@ -1,18 +1,19 @@
goog.require('ol.Map');
goog.require('ol.View');
+goog.require('ol.format.KML');
goog.require('ol.layer.Heatmap');
goog.require('ol.layer.Tile');
-goog.require('ol.source.KML');
goog.require('ol.source.Stamen');
+goog.require('ol.source.Vector');
var blur = $('#blur');
var radius = $('#radius');
var vector = new ol.layer.Heatmap({
- source: new ol.source.KML({
+ source: new ol.source.Vector({
extractStyles: false,
- projection: 'EPSG:3857',
- url: 'data/kml/2012_Earthquakes_Mag5.kml'
+ url: 'data/kml/2012_Earthquakes_Mag5.kml',
+ format: new ol.format.KML()
}),
blur: parseInt(blur.val(), 10),
radius: parseInt(radius.val(), 10)
diff --git a/examples_src/igc.js b/examples_src/igc.js
index 95b380dc1e..4b023bd3e1 100644
--- a/examples_src/igc.js
+++ b/examples_src/igc.js
@@ -4,12 +4,13 @@ goog.require('ol.FeatureOverlay');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.control');
+goog.require('ol.format.IGC');
goog.require('ol.geom.LineString');
goog.require('ol.geom.Point');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
-goog.require('ol.source.IGC');
goog.require('ol.source.OSM');
+goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
@@ -40,16 +41,24 @@ var styleFunction = function(feature, resolution) {
return styleArray;
};
-var vectorSource = new ol.source.IGC({
- projection: 'EPSG:3857',
- urls: [
- 'data/igc/Clement-Latour.igc',
- 'data/igc/Damien-de-Baenst.igc',
- 'data/igc/Sylvain-Dhonneur.igc',
- 'data/igc/Tom-Payne.igc',
- 'data/igc/Ulrich-Prinz.igc'
- ]
-});
+var vectorSource = new ol.source.Vector();
+
+var igcUrls = [
+ 'data/igc/Clement-Latour.igc',
+ 'data/igc/Damien-de-Baenst.igc',
+ 'data/igc/Sylvain-Dhonneur.igc',
+ 'data/igc/Tom-Payne.igc',
+ 'data/igc/Ulrich-Prinz.igc'
+];
+
+var igcFormat = new ol.format.IGC();
+for (var i = 0; i < igcUrls.length; ++i) {
+ $.ajax(igcUrls[i]).then(function(data) {
+ var features = igcFormat.readFeatures(data,
+ {featureProjection: 'EPSG:3857'});
+ vectorSource.addFeatures(features);
+ });
+}
var time = {
start: Infinity,
diff --git a/examples_src/image-vector-layer.js b/examples_src/image-vector-layer.js
index 6cf67e6450..6e7eaf352b 100644
--- a/examples_src/image-vector-layer.js
+++ b/examples_src/image-vector-layer.js
@@ -1,11 +1,12 @@
goog.require('ol.FeatureOverlay');
goog.require('ol.Map');
goog.require('ol.View');
+goog.require('ol.format.GeoJSON');
goog.require('ol.layer.Image');
goog.require('ol.layer.Tile');
-goog.require('ol.source.GeoJSON');
goog.require('ol.source.ImageVector');
goog.require('ol.source.MapQuest');
+goog.require('ol.source.Vector');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
@@ -18,9 +19,9 @@ var map = new ol.Map({
}),
new ol.layer.Image({
source: new ol.source.ImageVector({
- source: new ol.source.GeoJSON({
- projection: 'EPSG:3857',
- url: 'data/geojson/countries.geojson'
+ source: new ol.source.Vector({
+ url: 'data/geojson/countries.geojson',
+ format: new ol.format.GeoJSON()
}),
style: new ol.style.Style({
fill: new ol.style.Fill({
diff --git a/examples_src/kml-earthquakes.js b/examples_src/kml-earthquakes.js
index 10ae729347..1844d77069 100644
--- a/examples_src/kml-earthquakes.js
+++ b/examples_src/kml-earthquakes.js
@@ -1,9 +1,10 @@
goog.require('ol.Map');
goog.require('ol.View');
+goog.require('ol.format.KML');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
-goog.require('ol.source.KML');
goog.require('ol.source.Stamen');
+goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
@@ -38,10 +39,10 @@ var styleFunction = function(feature, resolution) {
};
var vector = new ol.layer.Vector({
- source: new ol.source.KML({
+ source: new ol.source.Vector({
extractStyles: false,
- projection: 'EPSG:3857',
- url: 'data/kml/2012_Earthquakes_Mag5.kml'
+ url: 'data/kml/2012_Earthquakes_Mag5.kml',
+ format: new ol.format.KML()
}),
style: styleFunction
});
diff --git a/examples_src/kml-timezones.js b/examples_src/kml-timezones.js
index 8b8038e167..0683480d5d 100644
--- a/examples_src/kml-timezones.js
+++ b/examples_src/kml-timezones.js
@@ -1,9 +1,10 @@
goog.require('ol.Map');
goog.require('ol.View');
+goog.require('ol.format.KML');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
-goog.require('ol.source.KML');
goog.require('ol.source.Stamen');
+goog.require('ol.source.Vector');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
@@ -45,10 +46,10 @@ var styleFunction = function(feature, resolution) {
};
var vector = new ol.layer.Vector({
- source: new ol.source.KML({
+ source: new ol.source.Vector({
extractStyles: false,
- projection: 'EPSG:3857',
- url: 'data/kml/timezones.kml'
+ url: 'data/kml/timezones.kml',
+ format: new ol.format.KML()
}),
style: styleFunction
});
diff --git a/examples_src/kml.js b/examples_src/kml.js
index 33236288f3..90eae50ea1 100644
--- a/examples_src/kml.js
+++ b/examples_src/kml.js
@@ -5,7 +5,7 @@ goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.proj');
goog.require('ol.source.BingMaps');
-goog.require('ol.source.KML');
+goog.require('ol.source.Vector');
var projection = ol.proj.get('EPSG:3857');
@@ -17,9 +17,9 @@ var raster = new ol.layer.Tile({
});
var vector = new ol.layer.Vector({
- source: new ol.source.KML({
- projection: projection,
- url: 'data/kml/2012-02-10.kml'
+ source: new ol.source.Vector({
+ url: 'data/kml/2012-02-10.kml',
+ format: new ol.format.KML()
})
});
diff --git a/examples_src/modify-features.js b/examples_src/modify-features.js
index d3b6948502..90709d6a8b 100644
--- a/examples_src/modify-features.js
+++ b/examples_src/modify-features.js
@@ -1,12 +1,13 @@
goog.require('ol.Map');
goog.require('ol.View');
+goog.require('ol.format.GeoJSON');
goog.require('ol.interaction');
goog.require('ol.interaction.Modify');
goog.require('ol.interaction.Select');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
-goog.require('ol.source.GeoJSON');
goog.require('ol.source.MapQuest');
+goog.require('ol.source.Vector');
var raster = new ol.layer.Tile({
@@ -16,9 +17,9 @@ var raster = new ol.layer.Tile({
});
var vector = new ol.layer.Vector({
- source: new ol.source.GeoJSON({
- projection: 'EPSG:3857',
- url: 'data/geojson/countries.geojson'
+ source: new ol.source.Vector({
+ url: 'data/geojson/countries.geojson',
+ format: new ol.format.GeoJSON()
})
});
diff --git a/examples_src/modify-test.js b/examples_src/modify-test.js
index 1d88793c46..795932f902 100644
--- a/examples_src/modify-test.js
+++ b/examples_src/modify-test.js
@@ -1,10 +1,11 @@
goog.require('ol.Map');
goog.require('ol.View');
+goog.require('ol.format.GeoJSON');
goog.require('ol.interaction');
goog.require('ol.interaction.Modify');
goog.require('ol.interaction.Select');
goog.require('ol.layer.Vector');
-goog.require('ol.source.GeoJSON');
+goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
@@ -60,106 +61,107 @@ var styleFunction = (function() {
/* jshint +W069 */
})();
-var source = new ol.source.GeoJSON(
- /** @type {olx.source.GeoJSONOptions} */ ({
- object: {
- 'type': 'FeatureCollection',
- 'crs': {
- 'type': 'name',
- 'properties': {
- 'name': 'EPSG:3857'
- }
- },
- 'features': [
+var geojsonObject = {
+ 'type': 'FeatureCollection',
+ 'crs': {
+ 'type': 'name',
+ 'properties': {
+ 'name': 'EPSG:3857'
+ }
+ },
+ 'features': [
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Point',
+ 'coordinates': [0, 0]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'MultiPoint',
+ 'coordinates': [[-2e6, 0], [0, -2e6]]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [[4e6, -2e6], [8e6, 2e6], [9e6, 2e6]]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [[4e6, -2e6], [8e6, 2e6], [8e6, 3e6]]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Polygon',
+ 'coordinates': [[[-5e6, -1e6], [-4e6, 1e6],
+ [-3e6, -1e6], [-5e6, -1e6]], [[-4.5e6, -0.5e6],
+ [-3.5e6, -0.5e6], [-4e6, 0.5e6], [-4.5e6, -0.5e6]]]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'MultiLineString',
+ 'coordinates': [
+ [[-1e6, -7.5e5], [-1e6, 7.5e5]],
+ [[-1e6, -7.5e5], [-1e6, 7.5e5], [-5e5, 0], [-1e6, -7.5e5]],
+ [[1e6, -7.5e5], [15e5, 0], [15e5, 0], [1e6, 7.5e5]],
+ [[-7.5e5, -1e6], [7.5e5, -1e6]],
+ [[-7.5e5, 1e6], [7.5e5, 1e6]]
+ ]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'MultiPolygon',
+ 'coordinates': [
+ [[[-5e6, 6e6], [-5e6, 8e6], [-3e6, 8e6],
+ [-3e6, 6e6], [-5e6, 6e6]]],
+ [[[-3e6, 6e6], [-2e6, 8e6], [0, 8e6],
+ [0, 6e6], [-3e6, 6e6]]],
+ [[[1e6, 6e6], [1e6, 8e6], [3e6, 8e6],
+ [3e6, 6e6], [1e6, 6e6]]]
+ ]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'GeometryCollection',
+ 'geometries': [
{
- 'type': 'Feature',
- 'geometry': {
- 'type': 'Point',
- 'coordinates': [0, 0]
- }
+ 'type': 'LineString',
+ 'coordinates': [[-5e6, -5e6], [0, -5e6]]
},
{
- 'type': 'Feature',
- 'geometry': {
- 'type': 'MultiPoint',
- 'coordinates': [[-2e6, 0], [0, -2e6]]
- }
+ 'type': 'Point',
+ 'coordinates': [4e6, -5e6]
},
{
- 'type': 'Feature',
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [[4e6, -2e6], [8e6, 2e6], [9e6, 2e6]]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'LineString',
- 'coordinates': [[4e6, -2e6], [8e6, 2e6], [8e6, 3e6]]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'Polygon',
- 'coordinates': [[[-5e6, -1e6], [-4e6, 1e6],
- [-3e6, -1e6], [-5e6, -1e6]], [[-4.5e6, -0.5e6],
- [-3.5e6, -0.5e6], [-4e6, 0.5e6], [-4.5e6, -0.5e6]]]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'MultiLineString',
- 'coordinates': [
- [[-1e6, -7.5e5], [-1e6, 7.5e5]],
- [[-1e6, -7.5e5], [-1e6, 7.5e5], [-5e5, 0], [-1e6, -7.5e5]],
- [[1e6, -7.5e5], [15e5, 0], [15e5, 0], [1e6, 7.5e5]],
- [[-7.5e5, -1e6], [7.5e5, -1e6]],
- [[-7.5e5, 1e6], [7.5e5, 1e6]]
- ]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'MultiPolygon',
- 'coordinates': [
- [[[-5e6, 6e6], [-5e6, 8e6], [-3e6, 8e6],
- [-3e6, 6e6], [-5e6, 6e6]]],
- [[[-3e6, 6e6], [-2e6, 8e6], [0, 8e6],
- [0, 6e6], [-3e6, 6e6]]],
- [[[1e6, 6e6], [1e6, 8e6], [3e6, 8e6],
- [3e6, 6e6], [1e6, 6e6]]]
- ]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'GeometryCollection',
- 'geometries': [
- {
- 'type': 'LineString',
- 'coordinates': [[-5e6, -5e6], [0, -5e6]]
- },
- {
- 'type': 'Point',
- 'coordinates': [4e6, -5e6]
- },
- {
- 'type': 'Polygon',
- 'coordinates': [
- [[1e6, -6e6], [2e6, -4e6], [3e6, -6e6], [1e6, -6e6]]
- ]
- }
- ]
- }
+ 'type': 'Polygon',
+ 'coordinates': [
+ [[1e6, -6e6], [2e6, -4e6], [3e6, -6e6], [1e6, -6e6]]
+ ]
}
]
}
- }));
+ }
+ ]
+};
+
+var source = new ol.source.Vector({
+ features: (new ol.format.GeoJSON()).readFeatures(geojsonObject)
+});
var layer = new ol.layer.Vector({
source: source,
diff --git a/examples_src/polygon-styles.js b/examples_src/polygon-styles.js
index 70d18b1510..550f5465b8 100644
--- a/examples_src/polygon-styles.js
+++ b/examples_src/polygon-styles.js
@@ -1,8 +1,9 @@
goog.require('ol.Map');
goog.require('ol.View');
+goog.require('ol.format.GeoJSON');
goog.require('ol.geom.MultiPoint');
goog.require('ol.layer.Vector');
-goog.require('ol.source.GeoJSON');
+goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
@@ -40,51 +41,53 @@ var styles = [
})
];
-var source = new ol.source.GeoJSON(/** @type {olx.source.GeoJSONOptions} */ ({
- object: {
- 'type': 'FeatureCollection',
- 'crs': {
- 'type': 'name',
- 'properties': {
- 'name': 'EPSG:3857'
+var geojsonObject = {
+ 'type': 'FeatureCollection',
+ 'crs': {
+ 'type': 'name',
+ 'properties': {
+ 'name': 'EPSG:3857'
+ }
+ },
+ 'features': [
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Polygon',
+ 'coordinates': [[[-5e6, 6e6], [-5e6, 8e6], [-3e6, 8e6],
+ [-3e6, 6e6], [-5e6, 6e6]]]
}
},
- 'features': [
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'Polygon',
- 'coordinates': [[[-5e6, 6e6], [-5e6, 8e6], [-3e6, 8e6],
- [-3e6, 6e6], [-5e6, 6e6]]]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'Polygon',
- 'coordinates': [[[-2e6, 6e6], [-2e6, 8e6], [0, 8e6],
- [0, 6e6], [-2e6, 6e6]]]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'Polygon',
- 'coordinates': [[[1e6, 6e6], [1e6, 8e6], [3e6, 8e6],
- [3e6, 6e6], [1e6, 6e6]]]
- }
- },
- {
- 'type': 'Feature',
- 'geometry': {
- 'type': 'Polygon',
- 'coordinates': [[[-2e6, -1e6], [-1e6, 1e6],
- [0, -1e6], [-2e6, -1e6]]]
- }
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Polygon',
+ 'coordinates': [[[-2e6, 6e6], [-2e6, 8e6], [0, 8e6],
+ [0, 6e6], [-2e6, 6e6]]]
}
- ]
- }
-}));
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Polygon',
+ 'coordinates': [[[1e6, 6e6], [1e6, 8e6], [3e6, 8e6],
+ [3e6, 6e6], [1e6, 6e6]]]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'Polygon',
+ 'coordinates': [[[-2e6, -1e6], [-1e6, 1e6],
+ [0, -1e6], [-2e6, -1e6]]]
+ }
+ }
+ ]
+};
+
+var source = new ol.source.Vector({
+ features: (new ol.format.GeoJSON()).readFeatures(geojsonObject)
+});
var layer = new ol.layer.Vector({
source: source,
diff --git a/examples_src/select-features.js b/examples_src/select-features.js
index 15514d6f05..c59d0893d2 100644
--- a/examples_src/select-features.js
+++ b/examples_src/select-features.js
@@ -1,20 +1,21 @@
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.events.condition');
+goog.require('ol.format.GeoJSON');
goog.require('ol.interaction.Select');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
-goog.require('ol.source.GeoJSON');
goog.require('ol.source.MapQuest');
+goog.require('ol.source.Vector');
var raster = new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'sat'})
});
var vector = new ol.layer.Vector({
- source: new ol.source.GeoJSON({
- projection: 'EPSG:3857',
- url: 'data/geojson/countries.geojson'
+ source: new ol.source.Vector({
+ url: 'data/geojson/countries.geojson',
+ format: new ol.format.GeoJSON()
})
});
diff --git a/examples_src/sphere-mollweide.js b/examples_src/sphere-mollweide.js
index d15affded3..232c75ae53 100644
--- a/examples_src/sphere-mollweide.js
+++ b/examples_src/sphere-mollweide.js
@@ -1,9 +1,10 @@
goog.require('ol.Graticule');
goog.require('ol.Map');
goog.require('ol.View');
+goog.require('ol.format.GeoJSON');
goog.require('ol.layer.Vector');
goog.require('ol.proj.Projection');
-goog.require('ol.source.GeoJSON');
+goog.require('ol.source.Vector');
proj4.defs('ESRI:53009', '+proj=moll +lon_0=0 +x_0=0 +y_0=0 +a=6371000 ' +
@@ -22,9 +23,9 @@ var map = new ol.Map({
keyboardEventTarget: document,
layers: [
new ol.layer.Vector({
- source: new ol.source.GeoJSON({
- projection: sphereMollweideProjection,
- url: 'data/geojson/countries-110m.geojson'
+ source: new ol.source.Vector({
+ url: 'data/geojson/countries-110m.geojson',
+ format: new ol.format.GeoJSON()
})
})
],
diff --git a/examples_src/topojson.html b/examples_src/topojson.html
index c88ffe2598..1b233d183b 100644
--- a/examples_src/topojson.html
+++ b/examples_src/topojson.html
@@ -3,7 +3,7 @@ template: example.html
title: TopoJSON example
shortdesc: Demonstrates rendering of features from a TopoJSON topology.
docs: >
- This example uses a vector layer with a `ol.source.TopoJSON` for rendering features from [TopoJSON](https://github.com/mbostock/topojson/wiki).
+ This example uses a vector layer with `ol.format.TopoJSON` for rendering features from [TopoJSON](https://github.com/mbostock/topojson/wiki).
tags: "topojson, vector, style"
---
diff --git a/examples_src/topojson.js b/examples_src/topojson.js
index 827fa28c90..df0ff4075d 100644
--- a/examples_src/topojson.js
+++ b/examples_src/topojson.js
@@ -1,9 +1,10 @@
goog.require('ol.Map');
goog.require('ol.View');
+goog.require('ol.format.TopoJSON');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.source.TileJSON');
-goog.require('ol.source.TopoJSON');
+goog.require('ol.source.Vector');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
@@ -26,9 +27,9 @@ var styleArray = [new ol.style.Style({
})];
var vector = new ol.layer.Vector({
- source: new ol.source.TopoJSON({
- projection: 'EPSG:3857',
- url: 'data/topojson/world-110m.json'
+ source: new ol.source.Vector({
+ url: 'data/topojson/world-110m.json',
+ format: new ol.format.TopoJSON()
}),
style: function(feature, resolution) {
// don't want to render the full world polygon, which repeats all countries
diff --git a/examples_src/vector-labels.js b/examples_src/vector-labels.js
index cd89a31e14..3dcb9acbc0 100644
--- a/examples_src/vector-labels.js
+++ b/examples_src/vector-labels.js
@@ -1,10 +1,11 @@
goog.require('ol.Feature');
goog.require('ol.Map');
goog.require('ol.View');
+goog.require('ol.format.GeoJSON');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
-goog.require('ol.source.GeoJSON');
goog.require('ol.source.MapQuest');
+goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
@@ -124,9 +125,9 @@ var createPolygonStyleFunction = function() {
};
var vectorPolygons = new ol.layer.Vector({
- source: new ol.source.GeoJSON({
- projection: 'EPSG:3857',
- url: 'data/geojson/polygon-samples.geojson'
+ source: new ol.source.Vector({
+ url: 'data/geojson/polygon-samples.geojson',
+ format: new ol.format.GeoJSON()
}),
style: createPolygonStyleFunction()
});
@@ -147,9 +148,9 @@ var createLineStyleFunction = function() {
};
var vectorLines = new ol.layer.Vector({
- source: new ol.source.GeoJSON({
- projection: 'EPSG:3857',
- url: 'data/geojson/line-samples.geojson'
+ source: new ol.source.Vector({
+ url: 'data/geojson/line-samples.geojson',
+ format: new ol.format.GeoJSON()
}),
style: createLineStyleFunction()
});
@@ -171,9 +172,9 @@ var createPointStyleFunction = function() {
};
var vectorPoints = new ol.layer.Vector({
- source: new ol.source.GeoJSON({
- projection: 'EPSG:3857',
- url: 'data/geojson/point-samples.geojson'
+ source: new ol.source.Vector({
+ url: 'data/geojson/point-samples.geojson',
+ format: new ol.format.GeoJSON()
}),
style: createPointStyleFunction()
});
diff --git a/examples_src/vector-layer.js b/examples_src/vector-layer.js
index 390ffe8081..25faeca41f 100644
--- a/examples_src/vector-layer.js
+++ b/examples_src/vector-layer.js
@@ -1,10 +1,11 @@
goog.require('ol.FeatureOverlay');
goog.require('ol.Map');
goog.require('ol.View');
+goog.require('ol.format.GeoJSON');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
-goog.require('ol.source.GeoJSON');
goog.require('ol.source.MapQuest');
+goog.require('ol.source.Vector');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
@@ -31,10 +32,11 @@ var style = new ol.style.Style({
})
});
var styles = [style];
+
var vectorLayer = new ol.layer.Vector({
- source: new ol.source.GeoJSON({
- projection: 'EPSG:3857',
- url: 'data/geojson/countries.geojson'
+ source: new ol.source.Vector({
+ url: 'data/geojson/countries.geojson',
+ format: new ol.format.GeoJSON()
}),
style: function(feature, resolution) {
style.getText().setText(resolution < 5000 ? feature.get('name') : '');
diff --git a/examples_src/vector-osm.js b/examples_src/vector-osm.js
index d724b24320..eb1f5659a1 100644
--- a/examples_src/vector-osm.js
+++ b/examples_src/vector-osm.js
@@ -7,7 +7,7 @@ goog.require('ol.layer.Vector');
goog.require('ol.loadingstrategy');
goog.require('ol.proj');
goog.require('ol.source.BingMaps');
-goog.require('ol.source.ServerVector');
+goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
@@ -88,21 +88,23 @@ var styles = {
}
};
-var vectorSource = new ol.source.ServerVector({
- format: new ol.format.OSMXML(),
+var osmxmlFormat = new ol.format.OSMXML();
+
+var vectorSource = new ol.source.Vector({
loader: function(extent, resolution, projection) {
var epsg4326Extent =
ol.proj.transformExtent(extent, projection, 'EPSG:4326');
var url = 'http://overpass-api.de/api/xapi?map?bbox=' +
epsg4326Extent.join(',');
$.ajax(url).then(function(response) {
- vectorSource.addFeatures(vectorSource.readFeatures(response));
+ var features = osmxmlFormat.readFeatures(response,
+ {featureProjection: projection});
+ vectorSource.addFeatures(features);
});
},
- strategy: ol.loadingstrategy.createTile(new ol.tilegrid.XYZ({
+ strategy: ol.loadingstrategy.tile(new ol.tilegrid.XYZ({
maxZoom: 19
- })),
- projection: 'EPSG:3857'
+ }))
});
var vector = new ol.layer.Vector({
diff --git a/examples_src/vector-wfs.js b/examples_src/vector-wfs.js
index 30c2b9d2ef..47386c71d7 100644
--- a/examples_src/vector-wfs.js
+++ b/examples_src/vector-wfs.js
@@ -5,31 +5,34 @@ goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.loadingstrategy');
goog.require('ol.source.BingMaps');
-goog.require('ol.source.ServerVector');
+goog.require('ol.source.Vector');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
goog.require('ol.tilegrid.XYZ');
-var vectorSource = new ol.source.ServerVector({
- format: new ol.format.GeoJSON(),
+
+// format used to parse WFS GetFeature responses
+var geojsonFormat = new ol.format.GeoJSON();
+
+var vectorSource = new ol.source.Vector({
loader: function(extent, resolution, projection) {
var url = 'http://demo.boundlessgeo.com/geoserver/wfs?service=WFS&' +
'version=1.1.0&request=GetFeature&typename=osm:water_areas&' +
'outputFormat=text/javascript&format_options=callback:loadFeatures' +
'&srsname=EPSG:3857&bbox=' + extent.join(',') + ',EPSG:3857';
- $.ajax({
- url: url,
- dataType: 'jsonp'
- });
+ // use jsonp: false to prevent jQuery from adding the "callback"
+ // parameter to the URL
+ $.ajax({url: url, dataType: 'jsonp', jsonp: false});
},
- strategy: ol.loadingstrategy.createTile(new ol.tilegrid.XYZ({
+ strategy: ol.loadingstrategy.tile(new ol.tilegrid.XYZ({
maxZoom: 19
- })),
- projection: 'EPSG:3857'
+ }))
});
+// the global function whose name is specified in the URL of JSONP WFS
+// GetFeature requests
var loadFeatures = function(response) {
- vectorSource.addFeatures(vectorSource.readFeatures(response));
+ vectorSource.addFeatures(geojsonFormat.readFeatures(response));
};
var vector = new ol.layer.Vector({
diff --git a/externs/olx.js b/externs/olx.js
index 5babe3e053..ebf684f3b2 100644
--- a/externs/olx.js
+++ b/externs/olx.js
@@ -3704,206 +3704,6 @@ olx.source.ClusterOptions.prototype.projection;
olx.source.ClusterOptions.prototype.source;
-/**
- * @typedef {{attributions: (Array.
|undefined),
- * format: ol.format.Feature,
- * logo: (string|olx.LogoOptions|undefined),
- * projection: ol.proj.ProjectionLike}}
- * @api
- */
-olx.source.FormatVectorOptions;
-
-
-/**
- * Attributions.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.FormatVectorOptions.prototype.attributions;
-
-
-/**
- * Format.
- * @type {ol.format.Feature}
- * @api
- */
-olx.source.FormatVectorOptions.prototype.format;
-
-
-/**
- * Logo.
- * @type {string|olx.LogoOptions|undefined}
- * @api
- */
-olx.source.FormatVectorOptions.prototype.logo;
-
-
-/**
- * Projection.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.FormatVectorOptions.prototype.projection;
-
-
-/**
- * @typedef {{attributions: (Array.|undefined),
- * defaultProjection: ol.proj.ProjectionLike,
- * logo: (string|olx.LogoOptions|undefined),
- * object: (GeoJSONFeature|GeoJSONFeatureCollection|undefined),
- * projection: ol.proj.ProjectionLike,
- * text: (string|undefined),
- * url: (string|undefined),
- * urls: (Array.|undefined)}}
- * @api
- */
-olx.source.GeoJSONOptions;
-
-
-/**
- * Attributions.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.GeoJSONOptions.prototype.attributions;
-
-
-/**
- * Default projection.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.GeoJSONOptions.prototype.defaultProjection;
-
-
-/**
- * Logo.
- * @type {string|olx.LogoOptions|undefined}
- * @api
- */
-olx.source.GeoJSONOptions.prototype.logo;
-
-
-/**
- * GeoJSON feature or feature collection.
- * @type {GeoJSONFeature|GeoJSONFeatureCollection|undefined}
- * @api
- */
-olx.source.GeoJSONOptions.prototype.object;
-
-
-/**
- * Destination projection. If provided, features will be transformed to this
- * projection. If not provided, features will not be transformed.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.GeoJSONOptions.prototype.projection;
-
-
-/**
- * Text.
- * @type {string|undefined}
- * @api
- */
-olx.source.GeoJSONOptions.prototype.text;
-
-
-/**
- * URL.
- * @type {string|undefined}
- * @api
- */
-olx.source.GeoJSONOptions.prototype.url;
-
-
-/**
- * URLs.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.GeoJSONOptions.prototype.urls;
-
-
-/**
- * @typedef {{attributions: (Array.|undefined),
- * doc: (Document|undefined),
- * logo: (string|olx.LogoOptions|undefined),
- * node: (Node|undefined),
- * projection: ol.proj.ProjectionLike,
- * text: (string|undefined),
- * url: (string|undefined),
- * urls: (Array.|undefined)}}
- * @api
- */
-olx.source.GPXOptions;
-
-
-/**
- * Attributions.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.GPXOptions.prototype.attributions;
-
-
-/**
- * Document.
- * @type {Document|undefined}
- * @api
- */
-olx.source.GPXOptions.prototype.doc;
-
-
-/**
- * Logo.
- * @type {string|olx.LogoOptions|undefined}
- * @api
- */
-olx.source.GPXOptions.prototype.logo;
-
-
-/**
- * Node.
- * @type {Node|undefined}
- * @api
- */
-olx.source.GPXOptions.prototype.node;
-
-
-/**
- * Destination projection. If provided, features will be transformed to this
- * projection. If not provided, features will not be transformed.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.GPXOptions.prototype.projection;
-
-
-/**
- * Text.
- * @type {string|undefined}
- * @api
- */
-olx.source.GPXOptions.prototype.text;
-
-
-/**
- * URL.
- * @type {string|undefined}
- * @api
- */
-olx.source.GPXOptions.prototype.url;
-
-
-/**
- * URLs.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.GPXOptions.prototype.urls;
-
-
/**
* @typedef {{preemptive: (boolean|undefined),
* url: string}}
@@ -4064,7 +3864,6 @@ olx.source.TileImageOptions.prototype.wrapX;
* @typedef {{attributions: (Array.|undefined),
* format: ol.format.Feature,
* logo: (string|olx.LogoOptions|undefined),
- * projection: ol.proj.ProjectionLike,
* tileGrid: ol.tilegrid.TileGrid,
* tileUrlFunction: (ol.TileUrlFunctionType|undefined),
* url: (string|undefined),
@@ -4098,15 +3897,6 @@ olx.source.TileVectorOptions.prototype.format;
olx.source.TileVectorOptions.prototype.logo;
-/**
- * Destination projection. If provided, features will be transformed to this
- * projection. If not provided, features will not be transformed.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.TileVectorOptions.prototype.projection;
-
-
/**
* Tile grid.
* @type {ol.tilegrid.TileGrid}
@@ -4140,129 +3930,6 @@ olx.source.TileVectorOptions.prototype.url;
olx.source.TileVectorOptions.prototype.urls;
-/**
- * @typedef {{attributions: (Array.|undefined),
- * defaultProjection: ol.proj.ProjectionLike,
- * logo: (string|olx.LogoOptions|undefined),
- * object: (GeoJSONObject|undefined),
- * projection: ol.proj.ProjectionLike,
- * text: (string|undefined),
- * url: (string|undefined)}}
- * @api
- */
-olx.source.TopoJSONOptions;
-
-
-/**
- * Attributions.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.TopoJSONOptions.prototype.attributions;
-
-
-/**
- * Default projection.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.TopoJSONOptions.prototype.defaultProjection;
-
-
-/**
- * Logo.
- * @type {string|olx.LogoOptions|undefined}
- * @api
- */
-olx.source.TopoJSONOptions.prototype.logo;
-
-
-/**
- * Object.
- * @type {GeoJSONObject|undefined}
- * @api
- */
-olx.source.TopoJSONOptions.prototype.object;
-
-
-/**
- * Destination projection. If provided, features will be transformed to this
- * projection. If not provided, features will not be transformed.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.TopoJSONOptions.prototype.projection;
-
-
-/**
- * Text.
- * @type {string|undefined}
- * @api
- */
-olx.source.TopoJSONOptions.prototype.text;
-
-
-/**
- * URL.
- * @type {string|undefined}
- * @api
- */
-olx.source.TopoJSONOptions.prototype.url;
-
-
-/**
- * @typedef {{altitudeMode: (ol.format.IGCZ|undefined),
- * projection: ol.proj.ProjectionLike,
- * text: (string|undefined),
- * url: (string|undefined),
- * urls: (Array.|undefined)}}
- * @api
- */
-olx.source.IGCOptions;
-
-
-/**
- * Altitude mode. Possible values are `barometric`, `gps`, and `none`. Default
- * is `none`.
- * @type {ol.format.IGCZ|undefined}
- * @api
- */
-olx.source.IGCOptions.prototype.altitudeMode;
-
-
-/**
- * Destination projection. If provided, features will be transformed to this
- * projection. If not provided, features will not be transformed.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.IGCOptions.prototype.projection;
-
-
-/**
- * Text.
- * @type {string|undefined}
- * @api
- */
-olx.source.IGCOptions.prototype.text;
-
-
-/**
- * URL.
- * @type {string|undefined}
- * @api
- */
-olx.source.IGCOptions.prototype.url;
-
-
-/**
- * URLs.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.IGCOptions.prototype.urls;
-
-
/**
* @typedef {{url: (string|undefined),
* displayDpi: (number|undefined),
@@ -4362,103 +4029,6 @@ olx.source.ImageMapGuideOptions.prototype.imageLoadFunction;
olx.source.ImageMapGuideOptions.prototype.params;
-/**
- * @typedef {{attributions: (Array.|undefined),
- * defaultStyle: (Array.|undefined),
- * doc: (Document|undefined),
- * extractStyles: (boolean|undefined),
- * logo: (string|olx.LogoOptions|undefined),
- * node: (Node|undefined),
- * projection: ol.proj.ProjectionLike,
- * text: (string|undefined),
- * url: (string|undefined),
- * urls: (Array.|undefined)}}
- * @api
- */
-olx.source.KMLOptions;
-
-
-/**
- * Attributions.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.KMLOptions.prototype.attributions;
-
-
-/**
- * Default style.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.KMLOptions.prototype.defaultStyle;
-
-
-/**
- * Document.
- * @type {Document|undefined}
- * @api
- */
-olx.source.KMLOptions.prototype.doc;
-
-
-/**
- * Extract styles from the KML document. Default is `true`.
- * @type {boolean|undefined}
- * @api
- */
-olx.source.KMLOptions.prototype.extractStyles;
-
-
-/**
- * Logo.
- * @type {string|olx.LogoOptions|undefined}
- * @api
- */
-olx.source.KMLOptions.prototype.logo;
-
-
-/**
- * Node.
- * @type {Node|undefined}
- * @api
- */
-olx.source.KMLOptions.prototype.node;
-
-
-/**
- * Destination projection. If provided, features will be transformed to this
- * projection. If not provided, features will not be transformed.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.KMLOptions.prototype.projection;
-
-
-/**
- * Text.
- * @type {string|undefined}
- * @api
- */
-olx.source.KMLOptions.prototype.text;
-
-
-/**
- * URL.
- * @type {string|undefined}
- * @api
- */
-olx.source.KMLOptions.prototype.url;
-
-
-/**
- * URLs.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.KMLOptions.prototype.urls;
-
-
/**
* @typedef {{layer: string,
* tileLoadFunction: (ol.TileLoadFunctionType|undefined),
@@ -4583,84 +4153,6 @@ olx.source.OSMOptions.prototype.url;
olx.source.OSMOptions.prototype.wrapX;
-/**
- * @typedef {{attributions: (Array.|undefined),
- * doc: (Document|undefined),
- * logo: (string|olx.LogoOptions|undefined),
- * node: (Node|undefined),
- * projection: ol.proj.ProjectionLike,
- * text: (string|undefined),
- * url: (string|undefined),
- * urls: (Array.|undefined)}}
- * @api
- */
-olx.source.OSMXMLOptions;
-
-
-/**
- * Attributions.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.OSMXMLOptions.prototype.attributions;
-
-
-/**
- * Document.
- * @type {Document|undefined}
- * @api
- */
-olx.source.OSMXMLOptions.prototype.doc;
-
-
-/**
- * Logo.
- * @type {string|olx.LogoOptions|undefined}
- * @api
- */
-olx.source.OSMXMLOptions.prototype.logo;
-
-
-/**
- * Node.
- * @type {Node|undefined}
- * @api
- */
-olx.source.OSMXMLOptions.prototype.node;
-
-
-/**
- * Projection.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.OSMXMLOptions.prototype.projection;
-
-
-/**
- * Text.
- * @type {string|undefined}
- * @api
- */
-olx.source.OSMXMLOptions.prototype.text;
-
-
-/**
- * URL.
- * @type {string|undefined}
- * @api
- */
-olx.source.OSMXMLOptions.prototype.url;
-
-
-/**
- * URLs.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.OSMXMLOptions.prototype.urls;
-
-
/**
* @typedef {{attributions: (Array.|undefined),
* canvasFunction: ol.CanvasFunctionType,
@@ -5068,66 +4560,6 @@ olx.source.ImageStaticOptions.prototype.projection;
olx.source.ImageStaticOptions.prototype.url;
-/**
- * @typedef {{attributions: (Array.|undefined),
- * format: ol.format.Feature,
- * loader: function(this: ol.source.ServerVector, ol.Extent, number, ol.proj.Projection),
- * strategy: (function(ol.Extent, number): Array.|undefined),
- * logo: (string|olx.LogoOptions|undefined),
- * projection: ol.proj.ProjectionLike}}
- * @api
- */
-olx.source.ServerVectorOptions;
-
-
-/**
- * Attributions.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.ServerVectorOptions.prototype.attributions;
-
-
-/**
- * Format.
- * @type {ol.format.Feature}
- * @api
- */
-olx.source.ServerVectorOptions.prototype.format;
-
-
-/**
- * Loading function.
- * @type {function(this: ol.source.ServerVector, ol.Extent, number, ol.proj.Projection)}
- * @api
- */
-olx.source.ServerVectorOptions.prototype.loader;
-
-
-/**
- * Loading strategy. An {@link ol.loadingstrategy} or a custom function.
- * Default is {@link ol.loadingstrategy.bbox}.
- * @type {function(ol.Extent, number): Array.|undefined}
- * @api
- */
-olx.source.ServerVectorOptions.prototype.strategy;
-
-
-/**
- * Logo.
- * @type {string|olx.LogoOptions|undefined}
- * @api
- */
-olx.source.ServerVectorOptions.prototype.logo;
-
-
-/**
- * Projection.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.ServerVectorOptions.prototype.projection;
-
/**
* @typedef {{attributions: (Array.|undefined),
* params: (Object.|undefined),
@@ -5441,9 +4873,11 @@ olx.source.TileWMSOptions.prototype.wrapX;
/**
* @typedef {{attributions: (Array.|undefined),
* features: (Array.|undefined),
+ * format: (ol.format.Feature|undefined),
+ * loader: (ol.FeatureLoader|undefined),
* logo: (string|olx.LogoOptions|undefined),
- * projection: ol.proj.ProjectionLike,
- * state: (ol.source.State|string|undefined)}}
+ * strategy: (ol.LoadingStrategy|undefined),
+ * url: (string|undefined)}}
* @api
*/
olx.source.VectorOptions;
@@ -5465,6 +4899,25 @@ olx.source.VectorOptions.prototype.attributions;
olx.source.VectorOptions.prototype.features;
+/**
+ * The feature format used by the XHR loader when `url` is set. Required
+ * if `url` is set, otherwise ignored. Default is `undefined`.
+ * `url`
+ * @type {ol.format.Feature|undefined}
+ * @api
+ */
+olx.source.VectorOptions.prototype.format;
+
+
+/**
+ * The loader function used to load features, from a remote source for example.
+ * Note that the source will create and use an XHR loader when `src` is set.
+ * @type {ol.FeatureLoader|undefined}
+ * @api
+ */
+olx.source.VectorOptions.prototype.loader;
+
+
/**
* Logo.
* @type {string|olx.LogoOptions|undefined}
@@ -5474,124 +4927,23 @@ olx.source.VectorOptions.prototype.logo;
/**
- * Projection.
- * @type {ol.proj.ProjectionLike}
+ * The loading strategy to use. By default an {@link ol.loadingstrategy.all}
+ * strategy is used, which means that features at loaded all at once, and
+ * once.
+ * @type {ol.LoadingStrategy|undefined}
* @api
*/
-olx.source.VectorOptions.prototype.projection;
+olx.source.VectorOptions.prototype.strategy;
/**
- * State.
- * @type {ol.source.State|string|undefined}
- * @api
- */
-olx.source.VectorOptions.prototype.state;
-
-
-/**
- * @typedef {{arrayBuffer: (ArrayBuffer|undefined),
- * attributions: (Array.|undefined),
- * doc: (Document|undefined),
- * format: ol.format.Feature,
- * logo: (string|olx.LogoOptions|undefined),
- * node: (Node|undefined),
- * object: (Object|undefined),
- * projection: ol.proj.ProjectionLike,
- * text: (string|undefined),
- * url: (string|undefined),
- * urls: (Array.|undefined)}}
- * @api
- */
-olx.source.StaticVectorOptions;
-
-
-/**
- * Array buffer.
- * @type {ArrayBuffer|undefined}
- * @api
- */
-olx.source.StaticVectorOptions.prototype.arrayBuffer;
-
-
-/**
- * Attributions.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.StaticVectorOptions.prototype.attributions;
-
-
-/**
- * Document.
- * @type {Document|undefined}
- * @api
- */
-olx.source.StaticVectorOptions.prototype.doc;
-
-
-/**
- * Format.
- * @type {ol.format.Feature}
- * @api
- */
-olx.source.StaticVectorOptions.prototype.format;
-
-
-/**
- * Logo.
- * @type {string|olx.LogoOptions|undefined}
- * @api
- */
-olx.source.StaticVectorOptions.prototype.logo;
-
-
-/**
- * Node.
- * @type {Node|undefined}
- * @api
- */
-olx.source.StaticVectorOptions.prototype.node;
-
-
-/**
- * Object.
- * @type {Object|undefined}
- * @api
- */
-olx.source.StaticVectorOptions.prototype.object;
-
-
-/**
- * Projection.
- * @type {ol.proj.ProjectionLike}
- * @api
- */
-olx.source.StaticVectorOptions.prototype.projection;
-
-
-/**
- * Text.
+ * Set this option if you want the source to download features all at once
+ * and once for good. Internally the source uses an XHR feature loader (see
+ * {@link ol.featureloader.xhr}). Requires `format` to be set as well.
* @type {string|undefined}
* @api
*/
-olx.source.StaticVectorOptions.prototype.text;
-
-
-/**
- * URL.
- * @type {string|undefined}
- * @api
- */
-olx.source.StaticVectorOptions.prototype.url;
-
-
-/**
- * URLs.
- * @type {Array.|undefined}
- * @api
- */
-olx.source.StaticVectorOptions.prototype.urls;
+olx.source.VectorOptions.prototype.url;
/**
diff --git a/src/ol/featureloader.js b/src/ol/featureloader.js
new file mode 100644
index 0000000000..2fc5dfe114
--- /dev/null
+++ b/src/ol/featureloader.js
@@ -0,0 +1,116 @@
+goog.provide('ol.FeatureLoader');
+goog.provide('ol.featureloader');
+
+goog.require('goog.asserts');
+goog.require('goog.events');
+goog.require('goog.net.EventType');
+goog.require('goog.net.XhrIo');
+goog.require('goog.net.XhrIo.ResponseType');
+goog.require('ol.format.FormatType');
+goog.require('ol.xml');
+
+
+/**
+ * @typedef {function(this:ol.source.Vector, ol.Extent, number,
+ * ol.proj.Projection)}
+ */
+ol.FeatureLoader;
+
+
+/**
+ * @param {string} url Feature URL service.
+ * @param {ol.format.Feature} format Feature format.
+ * @param {function(this:ol.source.Vector, Array.)} success
+ * Function called with the loaded features. Called with the vector
+ * source as `this`.
+ * @return {ol.FeatureLoader} The feature loader.
+ */
+ol.featureloader.loadFeaturesXhr = function(url, format, success) {
+ return (
+ /**
+ * @param {ol.Extent} extent Extent.
+ * @param {number} resolution Resolution.
+ * @param {ol.proj.Projection} projection Projection.
+ * @this {ol.source.Vector}
+ */
+ function(extent, resolution, projection) {
+ var xhrIo = new goog.net.XhrIo();
+ var type = format.getType();
+ var responseType;
+ // FIXME maybe use ResponseType.DOCUMENT?
+ if (type == ol.format.FormatType.BINARY &&
+ ol.has.ARRAY_BUFFER) {
+ responseType = goog.net.XhrIo.ResponseType.ARRAY_BUFFER;
+ } else {
+ responseType = goog.net.XhrIo.ResponseType.TEXT;
+ }
+ xhrIo.setResponseType(responseType);
+ goog.events.listen(xhrIo, goog.net.EventType.COMPLETE,
+ /**
+ * @param {Event} event Event.
+ * @private
+ * @this {ol.source.Vector}
+ */
+ function(event) {
+ var xhrIo = event.target;
+ goog.asserts.assertInstanceof(xhrIo, goog.net.XhrIo,
+ 'event.target/xhrIo is an instance of goog.net.XhrIo');
+ if (xhrIo.isSuccess()) {
+ var type = format.getType();
+ /** @type {ArrayBuffer|Document|Node|Object|string|undefined} */
+ var source;
+ if (type == ol.format.FormatType.BINARY &&
+ ol.has.ARRAY_BUFFER) {
+ source = xhrIo.getResponse();
+ goog.asserts.assertInstanceof(source, ArrayBuffer,
+ 'source is an instance of ArrayBuffer');
+ } else if (type == ol.format.FormatType.JSON) {
+ source = xhrIo.getResponseText();
+ } else if (type == ol.format.FormatType.TEXT) {
+ source = xhrIo.getResponseText();
+ } else if (type == ol.format.FormatType.XML) {
+ if (!goog.userAgent.IE) {
+ source = xhrIo.getResponseXml();
+ }
+ if (!goog.isDefAndNotNull(source)) {
+ source = ol.xml.parse(xhrIo.getResponseText());
+ }
+ } else {
+ goog.asserts.fail('unexpected format type');
+ }
+ if (goog.isDefAndNotNull(source)) {
+ var features = format.readFeatures(source,
+ {featureProjection: projection});
+ success.call(this, features);
+ } else {
+ goog.asserts.fail('undefined or null source');
+ }
+ } else {
+ // FIXME
+ }
+ goog.dispose(xhrIo);
+ }, false, this);
+ xhrIo.send(url);
+ });
+};
+
+
+/**
+ * Create an XHR feature loader for a `url` and `format`. The feature loader
+ * loads features (with XHR), parses the features, and adds them to the
+ * vector source.
+ * @param {string} url Feature URL service.
+ * @param {ol.format.Feature} format Feature format.
+ * @return {ol.FeatureLoader} The feature loader.
+ * @api
+ */
+ol.featureloader.xhr = function(url, format) {
+ return ol.featureloader.loadFeaturesXhr(url, format,
+ /**
+ * @param {Array.} features The loaded features.
+ * @this {ol.source.Vector}
+ */
+ function(features) {
+ this.addFeatures(features);
+ });
+};
diff --git a/src/ol/loadingstrategy.js b/src/ol/loadingstrategy.js
index 418fc62282..4ea28cad39 100644
--- a/src/ol/loadingstrategy.js
+++ b/src/ol/loadingstrategy.js
@@ -1,8 +1,15 @@
+goog.provide('ol.LoadingStrategy');
goog.provide('ol.loadingstrategy');
goog.require('ol.TileCoord');
+/**
+ * @typedef {function(ol.Extent, number): Array.}
+ */
+ol.LoadingStrategy;
+
+
/**
* Strategy function for loading all features with a single request.
* @param {ol.Extent} extent Extent.
@@ -34,7 +41,7 @@ ol.loadingstrategy.bbox = function(extent, resolution) {
* @return {function(ol.Extent, number): Array.} Loading strategy.
* @api
*/
-ol.loadingstrategy.createTile = function(tileGrid) {
+ol.loadingstrategy.tile = function(tileGrid) {
return (
/**
* @param {ol.Extent} extent Extent.
diff --git a/src/ol/loadingstrategy.jsdoc b/src/ol/loadingstrategy.jsdoc
index baecef7850..7c917fb648 100644
--- a/src/ol/loadingstrategy.jsdoc
+++ b/src/ol/loadingstrategy.jsdoc
@@ -1,5 +1,4 @@
/**
* Strategies for loading vector data.
- * @see ol.source.ServerVector
* @namespace ol.loadingstrategy
*/
diff --git a/src/ol/source/formatvectorsource.js b/src/ol/source/formatvectorsource.js
deleted file mode 100644
index 8e3fd638d8..0000000000
--- a/src/ol/source/formatvectorsource.js
+++ /dev/null
@@ -1,127 +0,0 @@
-// FIXME consider delaying feature reading so projection can be provided by
-// consumer (e.g. the view)
-
-goog.provide('ol.source.FormatVector');
-
-goog.require('goog.asserts');
-goog.require('goog.dispose');
-goog.require('goog.events');
-goog.require('goog.net.EventType');
-goog.require('goog.net.XhrIo');
-goog.require('goog.net.XhrIo.ResponseType');
-goog.require('goog.userAgent');
-goog.require('ol.format.FormatType');
-goog.require('ol.has');
-goog.require('ol.source.State');
-goog.require('ol.source.Vector');
-goog.require('ol.xml');
-
-
-
-/**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Base class for vector sources in one of the supported formats.
- *
- * @constructor
- * @extends {ol.source.Vector}
- * @param {olx.source.FormatVectorOptions} options Options.
- */
-ol.source.FormatVector = function(options) {
-
- goog.base(this, {
- attributions: options.attributions,
- logo: options.logo,
- projection: options.projection
- });
-
- /**
- * @protected
- * @type {ol.format.Feature}
- */
- this.format = options.format;
-
-};
-goog.inherits(ol.source.FormatVector, ol.source.Vector);
-
-
-/**
- * @param {goog.Uri|string} url URL.
- * @param {function(this: T, Array.)} success Success Callback.
- * @param {function(this: T)} error Error callback.
- * @param {T} thisArg Value to use as `this` when executing `success` or
- * `error`.
- * @template T
- */
-ol.source.FormatVector.prototype.loadFeaturesFromURL =
- function(url, success, error, thisArg) {
- var xhrIo = new goog.net.XhrIo();
- var type = this.format.getType();
- var responseType;
- // FIXME maybe use ResponseType.DOCUMENT?
- if (type == ol.format.FormatType.BINARY &&
- ol.has.ARRAY_BUFFER) {
- responseType = goog.net.XhrIo.ResponseType.ARRAY_BUFFER;
- } else {
- responseType = goog.net.XhrIo.ResponseType.TEXT;
- }
- xhrIo.setResponseType(responseType);
- goog.events.listen(xhrIo, goog.net.EventType.COMPLETE,
- /**
- * @param {Event} event Event.
- * @private
- * @this {ol.source.FormatVector}
- */
- function(event) {
- var xhrIo = event.target;
- goog.asserts.assertInstanceof(xhrIo, goog.net.XhrIo,
- 'event.target/xhrIo is an instance of goog.net.XhrIo');
- if (xhrIo.isSuccess()) {
- var type = this.format.getType();
- /** @type {ArrayBuffer|Document|Node|Object|string|undefined} */
- var source;
- if (type == ol.format.FormatType.BINARY &&
- ol.has.ARRAY_BUFFER) {
- source = xhrIo.getResponse();
- goog.asserts.assertInstanceof(source, ArrayBuffer,
- 'source is an instance of ArrayBuffer');
- } else if (type == ol.format.FormatType.JSON) {
- source = xhrIo.getResponseText();
- } else if (type == ol.format.FormatType.TEXT) {
- source = xhrIo.getResponseText();
- } else if (type == ol.format.FormatType.XML) {
- if (!goog.userAgent.IE) {
- source = xhrIo.getResponseXml();
- }
- if (!goog.isDefAndNotNull(source)) {
- source = ol.xml.parse(xhrIo.getResponseText());
- }
- } else {
- goog.asserts.fail('unexpected format type');
- }
- if (goog.isDefAndNotNull(source)) {
- success.call(thisArg, this.readFeatures(source));
- } else {
- this.setState(ol.source.State.ERROR);
- goog.asserts.fail('undefined or null source');
- }
- } else {
- error.call(thisArg);
- }
- goog.dispose(xhrIo);
- }, false, this);
- xhrIo.send(url);
-};
-
-
-/**
- * @param {ArrayBuffer|Document|Node|Object|string} source Source.
- * @return {Array.} Features.
- * @api
- */
-ol.source.FormatVector.prototype.readFeatures = function(source) {
- var format = this.format;
- var projection = this.getProjection();
- return format.readFeatures(source, {featureProjection: projection});
-};
diff --git a/src/ol/source/geojsonsource.js b/src/ol/source/geojsonsource.js
deleted file mode 100644
index b1f11c89c7..0000000000
--- a/src/ol/source/geojsonsource.js
+++ /dev/null
@@ -1,37 +0,0 @@
-goog.provide('ol.source.GeoJSON');
-
-goog.require('ol.format.GeoJSON');
-goog.require('ol.source.StaticVector');
-
-
-
-/**
- * @classdesc
- * Static vector source in GeoJSON format
- *
- * @constructor
- * @extends {ol.source.StaticVector}
- * @fires ol.source.VectorEvent
- * @param {olx.source.GeoJSONOptions=} opt_options Options.
- * @api
- */
-ol.source.GeoJSON = function(opt_options) {
-
- var options = goog.isDef(opt_options) ? opt_options : {};
-
- goog.base(this, {
- attributions: options.attributions,
- extent: options.extent,
- format: new ol.format.GeoJSON({
- defaultDataProjection: options.defaultProjection
- }),
- logo: options.logo,
- object: options.object,
- projection: options.projection,
- text: options.text,
- url: options.url,
- urls: options.urls
- });
-
-};
-goog.inherits(ol.source.GeoJSON, ol.source.StaticVector);
diff --git a/src/ol/source/gpxsource.js b/src/ol/source/gpxsource.js
deleted file mode 100644
index 7f45499be7..0000000000
--- a/src/ol/source/gpxsource.js
+++ /dev/null
@@ -1,36 +0,0 @@
-goog.provide('ol.source.GPX');
-
-goog.require('ol.format.GPX');
-goog.require('ol.source.StaticVector');
-
-
-
-/**
- * @classdesc
- * Static vector source in GPX format
- *
- * @constructor
- * @extends {ol.source.StaticVector}
- * @fires ol.source.VectorEvent
- * @param {olx.source.GPXOptions=} opt_options Options.
- * @api
- */
-ol.source.GPX = function(opt_options) {
-
- var options = goog.isDef(opt_options) ? opt_options : {};
-
- goog.base(this, {
- attributions: options.attributions,
- doc: options.doc,
- extent: options.extent,
- format: new ol.format.GPX(),
- logo: options.logo,
- node: options.node,
- projection: options.projection,
- text: options.text,
- url: options.url,
- urls: options.urls
- });
-
-};
-goog.inherits(ol.source.GPX, ol.source.StaticVector);
diff --git a/src/ol/source/igcsource.js b/src/ol/source/igcsource.js
deleted file mode 100644
index ebe220bad7..0000000000
--- a/src/ol/source/igcsource.js
+++ /dev/null
@@ -1,33 +0,0 @@
-goog.provide('ol.source.IGC');
-
-goog.require('ol.format.IGC');
-goog.require('ol.source.StaticVector');
-
-
-
-/**
- * @classdesc
- * Static vector source in IGC format
- *
- * @constructor
- * @extends {ol.source.StaticVector}
- * @fires ol.source.VectorEvent
- * @param {olx.source.IGCOptions=} opt_options Options.
- * @api
- */
-ol.source.IGC = function(opt_options) {
-
- var options = goog.isDef(opt_options) ? opt_options : {};
-
- goog.base(this, {
- format: new ol.format.IGC({
- altitudeMode: options.altitudeMode
- }),
- projection: options.projection,
- text: options.text,
- url: options.url,
- urls: options.urls
- });
-
-};
-goog.inherits(ol.source.IGC, ol.source.StaticVector);
diff --git a/src/ol/source/kmlsource.js b/src/ol/source/kmlsource.js
deleted file mode 100644
index 13c30f7f8e..0000000000
--- a/src/ol/source/kmlsource.js
+++ /dev/null
@@ -1,38 +0,0 @@
-goog.provide('ol.source.KML');
-
-goog.require('ol.format.KML');
-goog.require('ol.source.StaticVector');
-
-
-
-/**
- * @classdesc
- * Static vector source in KML format
- *
- * @constructor
- * @extends {ol.source.StaticVector}
- * @fires ol.source.VectorEvent
- * @param {olx.source.KMLOptions=} opt_options Options.
- * @api
- */
-ol.source.KML = function(opt_options) {
-
- var options = goog.isDef(opt_options) ? opt_options : {};
-
- goog.base(this, {
- attributions: options.attributions,
- doc: options.doc,
- format: new ol.format.KML({
- extractStyles: options.extractStyles,
- defaultStyle: options.defaultStyle
- }),
- logo: options.logo,
- node: options.node,
- projection: options.projection,
- text: options.text,
- url: options.url,
- urls: options.urls
- });
-
-};
-goog.inherits(ol.source.KML, ol.source.StaticVector);
diff --git a/src/ol/source/osmxmlsource.js b/src/ol/source/osmxmlsource.js
deleted file mode 100644
index d1ba44f49b..0000000000
--- a/src/ol/source/osmxmlsource.js
+++ /dev/null
@@ -1,35 +0,0 @@
-goog.provide('ol.source.OSMXML');
-
-goog.require('ol.format.OSMXML');
-goog.require('ol.source.StaticVector');
-
-
-
-/**
- * @classdesc
- * Static vector source in OSMXML format
- *
- * @constructor
- * @extends {ol.source.StaticVector}
- * @fires ol.source.VectorEvent
- * @param {olx.source.OSMXMLOptions=} opt_options Options.
- * @api
- */
-ol.source.OSMXML = function(opt_options) {
-
- var options = goog.isDef(opt_options) ? opt_options : {};
-
- goog.base(this, {
- attributions: options.attributions,
- doc: options.doc,
- format: new ol.format.OSMXML(),
- logo: options.logo,
- node: options.node,
- projection: options.projection,
- text: options.text,
- url: options.url,
- urls: options.urls
- });
-
-};
-goog.inherits(ol.source.OSMXML, ol.source.StaticVector);
diff --git a/src/ol/source/servervectorsource.js b/src/ol/source/servervectorsource.js
deleted file mode 100644
index 8d36a4c0bc..0000000000
--- a/src/ol/source/servervectorsource.js
+++ /dev/null
@@ -1,126 +0,0 @@
-// FIXME cache expiration
-
-goog.provide('ol.source.ServerVector');
-
-goog.require('goog.object');
-goog.require('ol.extent');
-goog.require('ol.loadingstrategy');
-goog.require('ol.source.FormatVector');
-goog.require('ol.structs.RBush');
-
-
-
-/**
- * @classdesc
- * A vector source in one of the supported formats, using a custom function to
- * read in the data from a remote server.
- *
- * @constructor
- * @extends {ol.source.FormatVector}
- * @param {olx.source.ServerVectorOptions} options Options.
- * @api
- */
-ol.source.ServerVector = function(options) {
-
- goog.base(this, {
- attributions: options.attributions,
- format: options.format,
- logo: options.logo,
- projection: options.projection
- });
-
- /**
- * @private
- * @type {ol.structs.RBush.<{extent: ol.Extent}>}
- */
- this.loadedExtents_ = new ol.structs.RBush();
-
- /**
- * @private
- * @type {function(this: ol.source.ServerVector, ol.Extent, number,
- * ol.proj.Projection)}
- */
- this.loader_ = options.loader;
-
- /**
- * @private
- * @type {function(ol.Extent, number): Array.}
- */
- this.strategy_ = goog.isDef(options.strategy) ?
- options.strategy : ol.loadingstrategy.bbox;
-
- /**
- * @private
- * @type {Object.}
- */
- this.loadedFeatures_ = {};
-
-};
-goog.inherits(ol.source.ServerVector, ol.source.FormatVector);
-
-
-/**
- * @inheritDoc
- */
-ol.source.ServerVector.prototype.addFeaturesInternal = function(features) {
- /** @type {Array.} */
- var notLoadedFeatures = [];
- var i, ii;
- for (i = 0, ii = features.length; i < ii; ++i) {
- var feature = features[i];
- var featureId = feature.getId();
- if (!goog.isDef(featureId)) {
- notLoadedFeatures.push(feature);
- } else if (!(featureId in this.loadedFeatures_)) {
- notLoadedFeatures.push(feature);
- this.loadedFeatures_[featureId] = true;
- }
- }
- goog.base(this, 'addFeaturesInternal', notLoadedFeatures);
-};
-
-
-/**
- * @inheritDoc
- * @api stable
- */
-ol.source.ServerVector.prototype.clear = function(opt_fast) {
- goog.object.clear(this.loadedFeatures_);
- this.loadedExtents_.clear();
- goog.base(this, 'clear', opt_fast);
-};
-
-
-/**
- * @inheritDoc
- */
-ol.source.ServerVector.prototype.loadFeatures =
- function(extent, resolution, projection) {
- var loadedExtents = this.loadedExtents_;
- var extentsToLoad = this.strategy_(extent, resolution);
- var i, ii;
- for (i = 0, ii = extentsToLoad.length; i < ii; ++i) {
- var extentToLoad = extentsToLoad[i];
- var alreadyLoaded = loadedExtents.forEachInExtent(extentToLoad,
- /**
- * @param {{extent: ol.Extent}} object Object.
- * @return {boolean} Contains.
- */
- function(object) {
- return ol.extent.containsExtent(object.extent, extentToLoad);
- });
- if (!alreadyLoaded) {
- this.loader_.call(this, extentToLoad, resolution, projection);
- loadedExtents.insert(extentToLoad, {extent: extentToLoad.slice()});
- }
- }
-};
-
-
-/**
- * @function
- * @param {ArrayBuffer|Document|Node|Object|string} source Source.
- * @return {Array.} Features.
- * @api
- */
-ol.source.ServerVector.prototype.readFeatures;
diff --git a/src/ol/source/staticvectorsource.js b/src/ol/source/staticvectorsource.js
deleted file mode 100644
index 30b5e330e7..0000000000
--- a/src/ol/source/staticvectorsource.js
+++ /dev/null
@@ -1,83 +0,0 @@
-goog.provide('ol.source.StaticVector');
-
-goog.require('ol.source.FormatVector');
-goog.require('ol.source.State');
-
-
-
-/**
- * @classdesc
- * A vector source that uses one of the supported formats to read the data from
- * a file or other static source.
- *
- * @constructor
- * @extends {ol.source.FormatVector}
- * @fires ol.source.VectorEvent
- * @param {olx.source.StaticVectorOptions} options Options.
- * @api
- */
-ol.source.StaticVector = function(options) {
-
- goog.base(this, {
- attributions: options.attributions,
- format: options.format,
- logo: options.logo,
- projection: options.projection
- });
-
- if (goog.isDef(options.arrayBuffer)) {
- this.addFeaturesInternal(this.readFeatures(options.arrayBuffer));
- }
-
- if (goog.isDef(options.doc)) {
- this.addFeaturesInternal(this.readFeatures(options.doc));
- }
-
- if (goog.isDef(options.node)) {
- this.addFeaturesInternal(this.readFeatures(options.node));
- }
-
- if (goog.isDef(options.object)) {
- this.addFeaturesInternal(this.readFeatures(options.object));
- }
-
- if (goog.isDef(options.text)) {
- this.addFeaturesInternal(this.readFeatures(options.text));
- }
-
- if (goog.isDef(options.url) || goog.isDef(options.urls)) {
- this.setState(ol.source.State.LOADING);
- if (goog.isDef(options.url)) {
- this.loadFeaturesFromURL(options.url,
- this.onFeaturesLoadedSuccess_, this.onFeaturesLoadedError_, this);
- }
- if (goog.isDef(options.urls)) {
- var urls = options.urls;
- var i, ii;
- for (i = 0, ii = urls.length; i < ii; ++i) {
- this.loadFeaturesFromURL(urls[i],
- this.onFeaturesLoadedSuccess_, this.onFeaturesLoadedError_, this);
- }
- }
- }
-
-};
-goog.inherits(ol.source.StaticVector, ol.source.FormatVector);
-
-
-/**
- * @private
- */
-ol.source.StaticVector.prototype.onFeaturesLoadedError_ = function() {
- this.setState(ol.source.State.ERROR);
-};
-
-
-/**
- * @param {Array.} features Features.
- * @private
- */
-ol.source.StaticVector.prototype.onFeaturesLoadedSuccess_ = function(features) {
- this.addFeaturesInternal(features);
- this.setState(ol.source.State.READY);
-};
diff --git a/src/ol/source/tilevectorsource.js b/src/ol/source/tilevectorsource.js
index 1a3642fb3e..a1714c3f88 100644
--- a/src/ol/source/tilevectorsource.js
+++ b/src/ol/source/tilevectorsource.js
@@ -5,8 +5,9 @@ goog.require('goog.asserts');
goog.require('goog.object');
goog.require('ol.TileCoord');
goog.require('ol.TileUrlFunction');
-goog.require('ol.source.FormatVector');
+goog.require('ol.featureloader');
goog.require('ol.source.State');
+goog.require('ol.source.Vector');
goog.require('ol.tilegrid.TileGrid');
@@ -17,7 +18,7 @@ goog.require('ol.tilegrid.TileGrid');
* into tiles in a fixed grid pattern.
*
* @constructor
- * @extends {ol.source.FormatVector}
+ * @extends {ol.source.Vector}
* @param {olx.source.TileVectorOptions} options Options.
* @api
*/
@@ -25,11 +26,20 @@ ol.source.TileVector = function(options) {
goog.base(this, {
attributions: options.attributions,
- format: options.format,
logo: options.logo,
- projection: options.projection
+ projection: undefined,
+ state: ol.source.State.READY
});
+ /**
+ * @private
+ * @type {ol.format.Feature}
+ */
+ this.format_ = options.format;
+
+ goog.asserts.assert(goog.isDefAndNotNull(this.format_),
+ 'ol.source.TileVector requires a format');
+
/**
* @private
* @type {ol.tilegrid.TileGrid}
@@ -63,7 +73,7 @@ ol.source.TileVector = function(options) {
}
};
-goog.inherits(ol.source.TileVector, ol.source.FormatVector);
+goog.inherits(ol.source.TileVector, ol.source.Vector);
/**
@@ -258,7 +268,7 @@ ol.source.TileVector.prototype.loadFeatures =
*/
function success(tileKey, features) {
tiles[tileKey] = features;
- this.setState(ol.source.State.READY);
+ this.changed();
}
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
@@ -271,8 +281,9 @@ ol.source.TileVector.prototype.loadFeatures =
var url = tileUrlFunction(tileCoord, 1, projection);
if (goog.isDef(url)) {
tiles[tileKey] = [];
- this.loadFeaturesFromURL(url, goog.partial(success, tileKey),
- goog.nullFunction, this);
+ var loader = ol.featureloader.loadFeaturesXhr(url, this.format_,
+ goog.partial(success, tileKey));
+ loader.call(this, extent, resolution, projection);
}
}
}
diff --git a/src/ol/source/topojsonsource.js b/src/ol/source/topojsonsource.js
deleted file mode 100644
index 8eec88abd1..0000000000
--- a/src/ol/source/topojsonsource.js
+++ /dev/null
@@ -1,36 +0,0 @@
-goog.provide('ol.source.TopoJSON');
-
-goog.require('ol.format.TopoJSON');
-goog.require('ol.source.StaticVector');
-
-
-
-/**
- * @classdesc
- * Static vector source in TopoJSON format
- *
- * @constructor
- * @extends {ol.source.StaticVector}
- * @fires ol.source.VectorEvent
- * @param {olx.source.TopoJSONOptions=} opt_options Options.
- * @api
- */
-ol.source.TopoJSON = function(opt_options) {
-
- var options = goog.isDef(opt_options) ? opt_options : {};
-
- goog.base(this, {
- attributions: options.attributions,
- extent: options.extent,
- format: new ol.format.TopoJSON({
- defaultDataProjection: options.defaultProjection
- }),
- logo: options.logo,
- object: options.object,
- projection: options.projection,
- text: options.text,
- url: options.url
- });
-
-};
-goog.inherits(ol.source.TopoJSON, ol.source.StaticVector);
diff --git a/src/ol/source/vectorsource.js b/src/ol/source/vectorsource.js
index 53446596bf..53b3319f64 100644
--- a/src/ol/source/vectorsource.js
+++ b/src/ol/source/vectorsource.js
@@ -12,9 +12,16 @@ goog.require('goog.events');
goog.require('goog.events.Event');
goog.require('goog.events.EventType');
goog.require('goog.object');
+goog.require('ol.Extent');
+goog.require('ol.FeatureLoader');
+goog.require('ol.LoadingStrategy');
goog.require('ol.ObjectEventType');
+goog.require('ol.extent');
+goog.require('ol.featureloader');
+goog.require('ol.loadingstrategy');
goog.require('ol.proj');
goog.require('ol.source.Source');
+goog.require('ol.source.State');
goog.require('ol.structs.RBush');
@@ -71,16 +78,43 @@ ol.source.Vector = function(opt_options) {
goog.base(this, {
attributions: options.attributions,
logo: options.logo,
- projection: options.projection,
- state: goog.isDef(options.state) ?
- /** @type {ol.source.State} */ (options.state) : undefined
+ projection: undefined,
+ state: ol.source.State.READY
});
+ /**
+ * @private
+ * @type {ol.FeatureLoader}
+ */
+ this.loader_ = goog.nullFunction;
+
+ if (goog.isDef(options.loader)) {
+ this.loader_ = options.loader;
+ } else if (goog.isDef(options.url)) {
+ goog.asserts.assert(goog.isDef(options.format),
+ 'format must be set when url is set');
+ // create a XHR feature loader for "url" and "format"
+ this.loader_ = ol.featureloader.xhr(options.url, options.format);
+ }
+
+ /**
+ * @private
+ * @type {ol.LoadingStrategy}
+ */
+ this.strategy_ = goog.isDef(options.strategy) ? options.strategy :
+ ol.loadingstrategy.all;
+
/**
* @private
* @type {ol.structs.RBush.}
*/
- this.rBush_ = new ol.structs.RBush();
+ this.featuresRtree_ = new ol.structs.RBush();
+
+ /**
+ * @private
+ * @type {ol.structs.RBush.<{extent: ol.Extent}>}
+ */
+ this.loadedExtentsRtree_ = new ol.structs.RBush();
/**
* @private
@@ -136,17 +170,21 @@ ol.source.Vector.prototype.addFeature = function(feature) {
*/
ol.source.Vector.prototype.addFeatureInternal = function(feature) {
var featureKey = goog.getUid(feature).toString();
+
+ if (!this.addToIndex_(featureKey, feature)) {
+ return;
+ }
+
this.setupChangeEvents_(featureKey, feature);
var geometry = feature.getGeometry();
if (goog.isDefAndNotNull(geometry)) {
var extent = geometry.getExtent();
- this.rBush_.insert(extent, feature);
+ this.featuresRtree_.insert(extent, feature);
} else {
this.nullGeometryFeatures_[featureKey] = feature;
}
- this.addToIndex_(featureKey, feature);
this.dispatchEvent(
new ol.source.VectorEvent(ol.source.VectorEventType.ADDFEATURE, feature));
};
@@ -174,17 +212,25 @@ ol.source.Vector.prototype.setupChangeEvents_ = function(featureKey, feature) {
/**
* @param {string} featureKey
* @param {ol.Feature} feature
+ * @return {boolean} `true` if the feature is "valid", in the sense that it is
+ * also a candidate for insertion into the Rtree, otherwise `false`.
* @private
*/
ol.source.Vector.prototype.addToIndex_ = function(featureKey, feature) {
+ var valid = true;
var id = feature.getId();
if (goog.isDef(id)) {
- this.idIndex_[id.toString()] = feature;
+ if (!(id.toString() in this.idIndex_)) {
+ this.idIndex_[id.toString()] = feature;
+ } else {
+ valid = false;
+ }
} else {
goog.asserts.assert(!(featureKey in this.undefIdIndex_),
'Feature already added to the source');
this.undefIdIndex_[featureKey] = feature;
}
+ return valid;
};
@@ -206,30 +252,38 @@ ol.source.Vector.prototype.addFeatures = function(features) {
*/
ol.source.Vector.prototype.addFeaturesInternal = function(features) {
var featureKey, i, length, feature;
+
var extents = [];
- var validFeatures = [];
+ var newFeatures = [];
+ var geometryFeatures = [];
+
for (i = 0, length = features.length; i < length; i++) {
feature = features[i];
featureKey = goog.getUid(feature).toString();
+ if (this.addToIndex_(featureKey, feature)) {
+ newFeatures.push(feature);
+ }
+ }
+
+ for (i = 0, length = newFeatures.length; i < length; i++) {
+ feature = newFeatures[i];
+ featureKey = goog.getUid(feature).toString();
this.setupChangeEvents_(featureKey, feature);
var geometry = feature.getGeometry();
if (goog.isDefAndNotNull(geometry)) {
var extent = geometry.getExtent();
extents.push(extent);
- validFeatures.push(feature);
+ geometryFeatures.push(feature);
} else {
this.nullGeometryFeatures_[featureKey] = feature;
}
}
- this.rBush_.load(extents, validFeatures);
+ this.featuresRtree_.load(extents, geometryFeatures);
- for (i = 0, length = features.length; i < length; i++) {
- feature = features[i];
- featureKey = goog.getUid(feature).toString();
- this.addToIndex_(featureKey, feature);
+ for (i = 0, length = newFeatures.length; i < length; i++) {
this.dispatchEvent(new ol.source.VectorEvent(
- ol.source.VectorEventType.ADDFEATURE, feature));
+ ol.source.VectorEventType.ADDFEATURE, newFeatures[i]));
}
};
@@ -250,7 +304,7 @@ ol.source.Vector.prototype.clear = function(opt_fast) {
this.undefIdIndex_ = {};
} else {
var rmFeatureInternal = this.removeFeatureInternal;
- this.rBush_.forEach(rmFeatureInternal, this);
+ this.featuresRtree_.forEach(rmFeatureInternal, this);
goog.object.forEach(this.nullGeometryFeatures_, rmFeatureInternal, this);
goog.asserts.assert(goog.object.isEmpty(this.featureChangeKeys_),
'featureChangeKeys is an empty object now');
@@ -260,7 +314,8 @@ ol.source.Vector.prototype.clear = function(opt_fast) {
'undefIdIndex is an empty object now');
}
- this.rBush_.clear();
+ this.featuresRtree_.clear();
+ this.loadedExtentsRtree_.clear();
this.nullGeometryFeatures_ = {};
var clearEvent = new ol.source.VectorEvent(ol.source.VectorEventType.CLEAR);
@@ -282,7 +337,7 @@ ol.source.Vector.prototype.clear = function(opt_fast) {
* @api stable
*/
ol.source.Vector.prototype.forEachFeature = function(callback, opt_this) {
- return this.rBush_.forEach(callback, opt_this);
+ return this.featuresRtree_.forEach(callback, opt_this);
};
@@ -335,7 +390,7 @@ ol.source.Vector.prototype.forEachFeatureAtCoordinateDirect =
*/
ol.source.Vector.prototype.forEachFeatureInExtent =
function(extent, callback, opt_this) {
- return this.rBush_.forEachInExtent(extent, callback, opt_this);
+ return this.featuresRtree_.forEachInExtent(extent, callback, opt_this);
};
@@ -398,7 +453,7 @@ ol.source.Vector.prototype.forEachFeatureIntersectingExtent =
* @api stable
*/
ol.source.Vector.prototype.getFeatures = function() {
- var features = this.rBush_.getAll();
+ var features = this.featuresRtree_.getAll();
if (!goog.object.isEmpty(this.nullGeometryFeatures_)) {
goog.array.extend(
features, goog.object.getValues(this.nullGeometryFeatures_));
@@ -431,7 +486,7 @@ ol.source.Vector.prototype.getFeaturesAtCoordinate = function(coordinate) {
* @api
*/
ol.source.Vector.prototype.getFeaturesInExtent = function(extent) {
- return this.rBush_.getInExtent(extent);
+ return this.featuresRtree_.getInExtent(extent);
};
@@ -456,7 +511,7 @@ ol.source.Vector.prototype.getClosestFeatureToCoordinate =
var closestPoint = [NaN, NaN];
var minSquaredDistance = Infinity;
var extent = [-Infinity, -Infinity, Infinity, Infinity];
- this.rBush_.forEachInExtent(extent,
+ this.featuresRtree_.forEachInExtent(extent,
/**
* @param {ol.Feature} feature Feature.
*/
@@ -490,7 +545,7 @@ ol.source.Vector.prototype.getClosestFeatureToCoordinate =
* @api stable
*/
ol.source.Vector.prototype.getExtent = function() {
- return this.rBush_.getExtent();
+ return this.featuresRtree_.getExtent();
};
@@ -519,16 +574,16 @@ ol.source.Vector.prototype.handleFeatureChange_ = function(event) {
var geometry = feature.getGeometry();
if (!goog.isDefAndNotNull(geometry)) {
if (!(featureKey in this.nullGeometryFeatures_)) {
- this.rBush_.remove(feature);
+ this.featuresRtree_.remove(feature);
this.nullGeometryFeatures_[featureKey] = feature;
}
} else {
var extent = geometry.getExtent();
if (featureKey in this.nullGeometryFeatures_) {
delete this.nullGeometryFeatures_[featureKey];
- this.rBush_.insert(extent, feature);
+ this.featuresRtree_.insert(extent, feature);
} else {
- this.rBush_.update(extent, feature);
+ this.featuresRtree_.update(extent, feature);
}
}
var id = feature.getId();
@@ -567,7 +622,7 @@ ol.source.Vector.prototype.handleFeatureChange_ = function(event) {
* @return {boolean} Is empty.
*/
ol.source.Vector.prototype.isEmpty = function() {
- return this.rBush_.isEmpty() &&
+ return this.featuresRtree_.isEmpty() &&
goog.object.isEmpty(this.nullGeometryFeatures_);
};
@@ -577,7 +632,27 @@ ol.source.Vector.prototype.isEmpty = function() {
* @param {number} resolution Resolution.
* @param {ol.proj.Projection} projection Projection.
*/
-ol.source.Vector.prototype.loadFeatures = goog.nullFunction;
+ol.source.Vector.prototype.loadFeatures = function(
+ extent, resolution, projection) {
+ var loadedExtentsRtree = this.loadedExtentsRtree_;
+ var extentsToLoad = this.strategy_(extent, resolution);
+ var i, ii;
+ for (i = 0, ii = extentsToLoad.length; i < ii; ++i) {
+ var extentToLoad = extentsToLoad[i];
+ var alreadyLoaded = loadedExtentsRtree.forEachInExtent(extentToLoad,
+ /**
+ * @param {{extent: ol.Extent}} object Object.
+ * @return {boolean} Contains.
+ */
+ function(object) {
+ return ol.extent.containsExtent(object.extent, extentToLoad);
+ });
+ if (!alreadyLoaded) {
+ this.loader_.call(this, extentToLoad, resolution, projection);
+ loadedExtentsRtree.insert(extentToLoad, {extent: extentToLoad.slice()});
+ }
+ }
+};
/**
@@ -592,7 +667,7 @@ ol.source.Vector.prototype.removeFeature = function(feature) {
if (featureKey in this.nullGeometryFeatures_) {
delete this.nullGeometryFeatures_[featureKey];
} else {
- this.rBush_.remove(feature);
+ this.featuresRtree_.remove(feature);
}
this.removeFeatureInternal(feature);
this.changed();
diff --git a/test/spec/ol/data/point.json b/test/spec/ol/data/point.json
new file mode 100644
index 0000000000..9ab34adfc1
--- /dev/null
+++ b/test/spec/ol/data/point.json
@@ -0,0 +1 @@
+{"type":"FeatureCollection","features":[{"type":"Feature","id":"01","properties":{},"geometry":{"type":"Point","coordinates":[-87.359296,35.001181]}}]}
diff --git a/test/spec/ol/featureloader.test.js b/test/spec/ol/featureloader.test.js
new file mode 100644
index 0000000000..6ce714c98e
--- /dev/null
+++ b/test/spec/ol/featureloader.test.js
@@ -0,0 +1,30 @@
+goog.provide('ol.test.featureloader');
+
+describe('ol.featureloader', function() {
+ describe('ol.featureloader.xhr', function() {
+ var loader;
+ var source;
+
+ beforeEach(function() {
+ var url = 'spec/ol/data/point.json';
+ var format = new ol.format.GeoJSON();
+
+ loader = ol.featureloader.xhr(url, format);
+ source = new ol.source.Vector();
+ });
+
+ it('adds features to the source', function(done) {
+ source.on(ol.source.VectorEventType.ADDFEATURE, function(e) {
+ expect(source.getFeatures().length).to.be.greaterThan(0);
+ done();
+ });
+ loader.call(source, [], 1, 'EPSG:3857');
+ });
+
+ });
+});
+
+goog.require('ol.featureloader');
+goog.require('ol.format.GeoJSON');
+goog.require('ol.source.Vector');
+goog.require('ol.source.VectorEventType');
diff --git a/test/spec/ol/source/servervectorsource.test.js b/test/spec/ol/source/servervectorsource.test.js
deleted file mode 100644
index 17dd0786b3..0000000000
--- a/test/spec/ol/source/servervectorsource.test.js
+++ /dev/null
@@ -1,68 +0,0 @@
-goog.provide('ol.test.source.ServerVector');
-
-
-describe('ol.source.ServerVector', function() {
-
- describe('when empty', function() {
-
- var vectorSource;
- beforeEach(function() {
- vectorSource = new ol.source.ServerVector({});
- });
-
- describe('#addFeatures', function() {
-
- it('adds features with the same id only once', function() {
- var addfeatureSpy = sinon.spy();
- vectorSource.on('addfeature', addfeatureSpy);
- features = [];
- var i;
- var feature;
- for (i = 0; i < 5; i++) {
- feature = new ol.Feature();
- feature.setId(0);
- features.push(feature);
- }
- vectorSource.addFeatures(features);
- expect(vectorSource.getFeatures().length).to.be(1);
- expect(addfeatureSpy.callCount).to.be(1);
- });
-
- it('adds features all features with distinct ids', function() {
- var addfeatureSpy = sinon.spy();
- vectorSource.on('addfeature', addfeatureSpy);
- features = [];
- var i;
- var feature;
- for (i = 0; i < 5; i++) {
- feature = new ol.Feature();
- feature.setId(i);
- features.push(feature);
- }
- vectorSource.addFeatures(features);
- expect(vectorSource.getFeatures().length).to.be(5);
- expect(addfeatureSpy.callCount).to.be(5);
- });
-
- it('adds features without ids', function() {
- var addfeatureSpy = sinon.spy();
- vectorSource.on('addfeature', addfeatureSpy);
- features = [];
- var i;
- for (i = 0; i < 10; i++) {
- features.push(new ol.Feature());
- }
- vectorSource.addFeatures(features);
- expect(vectorSource.getFeatures().length).to.be(10);
- expect(addfeatureSpy.callCount).to.be(10);
- });
-
- });
-
- });
-
-});
-
-
-goog.require('ol.Feature');
-goog.require('ol.source.ServerVector');
diff --git a/test/spec/ol/source/vectorsource.test.js b/test/spec/ol/source/vectorsource.test.js
index 558cd725e8..df782e7a67 100644
--- a/test/spec/ol/source/vectorsource.test.js
+++ b/test/spec/ol/source/vectorsource.test.js
@@ -365,20 +365,38 @@ describe('ol.source.Vector', function() {
});
+ describe('#loadFeatures', function() {
+
+ describe('with no loader and the "all" strategy', function() {
+
+ it('stores the infinity extent in the Rtree', function() {
+ var source = new ol.source.Vector();
+ source.loadFeatures([-10000, -10000, 10000, 10000], 1,
+ ol.proj.get('EPSG:3857'));
+ var loadedExtents = source.loadedExtentsRtree_.getAll();
+ expect(loadedExtents).to.have.length(1);
+ expect(loadedExtents[0].extent).to.eql(
+ [-Infinity, -Infinity, Infinity, Infinity]);
+ });
+ });
+
+ });
+
describe('the feature id index', function() {
var source;
beforeEach(function() {
source = new ol.source.Vector();
});
- it('allows adding feature with the same id', function() {
+ it('ignores features with the same id', function() {
var feature = new ol.Feature();
feature.setId('foo');
source.addFeature(feature);
var dupe = new ol.Feature();
dupe.setId('foo');
source.addFeature(dupe);
- expect(source.getFeatureById('foo')).to.be(dupe);
+ expect(source.getFeatures()).to.have.length(1);
+ expect(source.getFeatureById('foo')).to.be(feature);
});
it('allows changing feature and set the same id', function() {
@@ -415,4 +433,5 @@ describe('ol.source.Vector', function() {
goog.require('goog.events');
goog.require('ol.Feature');
goog.require('ol.geom.Point');
+goog.require('ol.proj');
goog.require('ol.source.Vector');