From 77933d0ab3d99ec114ce30b3388d879b1be46c8c Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 20 Feb 2014 22:43:04 +0100 Subject: [PATCH 01/28] Rename ol.source.VectorFile to ol.source.StaticVector --- src/objectliterals.jsdoc | 2 +- src/ol/source/geojsonsource.js | 6 +++--- src/ol/source/gpxsource.js | 6 +++--- src/ol/source/igcsource.js | 6 +++--- src/ol/source/kmlsource.js | 6 +++--- src/ol/source/osmxmlsource.js | 6 +++--- src/ol/source/staticvectorsource.exports | 1 + .../{vectorfilesource.js => staticvectorsource.js} | 12 ++++++------ src/ol/source/topojsonsource.js | 6 +++--- src/ol/source/vectorfilesource.exports | 1 - 10 files changed, 26 insertions(+), 26 deletions(-) create mode 100644 src/ol/source/staticvectorsource.exports rename src/ol/source/{vectorfilesource.js => staticvectorsource.js} (92%) delete mode 100644 src/ol/source/vectorfilesource.exports diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 3083d5e950..26430e0b36 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -952,7 +952,7 @@ */ /** - * @typedef {Object} olx.source.VectorFileOptions + * @typedef {Object} olx.source.StaticVectorOptions * @property {ArrayBuffer|undefined} arrayBuffer Array buffer. * @property {Array.|undefined} attributions Attributions. * @property {Document|undefined} doc Document. diff --git a/src/ol/source/geojsonsource.js b/src/ol/source/geojsonsource.js index 1ee7532fd3..230a79b105 100644 --- a/src/ol/source/geojsonsource.js +++ b/src/ol/source/geojsonsource.js @@ -1,13 +1,13 @@ goog.provide('ol.source.GeoJSON'); goog.require('ol.format.GeoJSON'); -goog.require('ol.source.VectorFile'); +goog.require('ol.source.StaticVector'); /** * @constructor - * @extends {ol.source.VectorFile} + * @extends {ol.source.StaticVector} * @fires {@link ol.source.VectorEvent} ol.source.VectorEvent * @param {olx.source.GeoJSONOptions=} opt_options Options. * @todo stability experimental @@ -31,4 +31,4 @@ ol.source.GeoJSON = function(opt_options) { }); }; -goog.inherits(ol.source.GeoJSON, ol.source.VectorFile); +goog.inherits(ol.source.GeoJSON, ol.source.StaticVector); diff --git a/src/ol/source/gpxsource.js b/src/ol/source/gpxsource.js index 1db7f23603..447751e7dd 100644 --- a/src/ol/source/gpxsource.js +++ b/src/ol/source/gpxsource.js @@ -1,13 +1,13 @@ goog.provide('ol.source.GPX'); goog.require('ol.format.GPX'); -goog.require('ol.source.VectorFile'); +goog.require('ol.source.StaticVector'); /** * @constructor - * @extends {ol.source.VectorFile} + * @extends {ol.source.StaticVector} * @fires {@link ol.source.VectorEvent} ol.source.VectorEvent * @param {olx.source.GPXOptions=} opt_options Options. * @todo stability experimental @@ -30,4 +30,4 @@ ol.source.GPX = function(opt_options) { }); }; -goog.inherits(ol.source.GPX, ol.source.VectorFile); +goog.inherits(ol.source.GPX, ol.source.StaticVector); diff --git a/src/ol/source/igcsource.js b/src/ol/source/igcsource.js index c8f19cddfd..320dda80da 100644 --- a/src/ol/source/igcsource.js +++ b/src/ol/source/igcsource.js @@ -1,13 +1,13 @@ goog.provide('ol.source.IGC'); goog.require('ol.format.IGC'); -goog.require('ol.source.VectorFile'); +goog.require('ol.source.StaticVector'); /** * @constructor - * @extends {ol.source.VectorFile} + * @extends {ol.source.StaticVector} * @fires {@link ol.source.VectorEvent} ol.source.VectorEvent * @param {olx.source.IGCOptions=} opt_options Options. * @todo stability experimental @@ -27,4 +27,4 @@ ol.source.IGC = function(opt_options) { }); }; -goog.inherits(ol.source.IGC, ol.source.VectorFile); +goog.inherits(ol.source.IGC, ol.source.StaticVector); diff --git a/src/ol/source/kmlsource.js b/src/ol/source/kmlsource.js index 00b3891a54..c94b70bf69 100644 --- a/src/ol/source/kmlsource.js +++ b/src/ol/source/kmlsource.js @@ -1,13 +1,13 @@ goog.provide('ol.source.KML'); goog.require('ol.format.KML'); -goog.require('ol.source.VectorFile'); +goog.require('ol.source.StaticVector'); /** * @constructor - * @extends {ol.source.VectorFile} + * @extends {ol.source.StaticVector} * @fires {@link ol.source.VectorEvent} ol.source.VectorEvent * @param {olx.source.KMLOptions=} opt_options Options. * @todo stability experimental @@ -32,4 +32,4 @@ ol.source.KML = function(opt_options) { }); }; -goog.inherits(ol.source.KML, ol.source.VectorFile); +goog.inherits(ol.source.KML, ol.source.StaticVector); diff --git a/src/ol/source/osmxmlsource.js b/src/ol/source/osmxmlsource.js index b93ca145b2..2baecbaa20 100644 --- a/src/ol/source/osmxmlsource.js +++ b/src/ol/source/osmxmlsource.js @@ -1,13 +1,13 @@ goog.provide('ol.source.OSMXML'); goog.require('ol.format.OSMXML'); -goog.require('ol.source.VectorFile'); +goog.require('ol.source.StaticVector'); /** * @constructor - * @extends {ol.source.VectorFile} + * @extends {ol.source.StaticVector} * @fires {@link ol.source.VectorEvent} ol.source.VectorEvent * @param {olx.source.OSMXMLOptions=} opt_options Options. */ @@ -29,4 +29,4 @@ ol.source.OSMXML = function(opt_options) { }); }; -goog.inherits(ol.source.OSMXML, ol.source.VectorFile); +goog.inherits(ol.source.OSMXML, ol.source.StaticVector); diff --git a/src/ol/source/staticvectorsource.exports b/src/ol/source/staticvectorsource.exports new file mode 100644 index 0000000000..1c283475e6 --- /dev/null +++ b/src/ol/source/staticvectorsource.exports @@ -0,0 +1 @@ +@exportSymbol ol.source.StaticVector diff --git a/src/ol/source/vectorfilesource.js b/src/ol/source/staticvectorsource.js similarity index 92% rename from src/ol/source/vectorfilesource.js rename to src/ol/source/staticvectorsource.js index 885a69335a..ace4886d3b 100644 --- a/src/ol/source/vectorfilesource.js +++ b/src/ol/source/staticvectorsource.js @@ -1,7 +1,7 @@ // FIXME consider delaying feature reading so projection can be provided by // consumer (e.g. the view) -goog.provide('ol.source.VectorFile'); +goog.provide('ol.source.StaticVector'); goog.require('goog.asserts'); goog.require('goog.dispose'); @@ -23,10 +23,10 @@ goog.require('ol.xml'); * @constructor * @extends {ol.source.Vector} * @fires {@link ol.source.VectorEvent} ol.source.VectorEvent - * @param {olx.source.VectorFileOptions=} opt_options Options. + * @param {olx.source.StaticVectorOptions=} opt_options Options. * @todo stability experimental */ -ol.source.VectorFile = function(opt_options) { +ol.source.StaticVector = function(opt_options) { var options = goog.isDef(opt_options) ? opt_options : {}; @@ -96,14 +96,14 @@ ol.source.VectorFile = function(opt_options) { } }; -goog.inherits(ol.source.VectorFile, ol.source.Vector); +goog.inherits(ol.source.StaticVector, ol.source.Vector); /** * @param {Event} event Event. * @private */ -ol.source.VectorFile.prototype.handleXhrIo_ = function(event) { +ol.source.StaticVector.prototype.handleXhrIo_ = function(event) { var xhrIo = event.target; goog.asserts.assertInstanceof(xhrIo, goog.net.XhrIo); if (xhrIo.isSuccess()) { @@ -145,7 +145,7 @@ ol.source.VectorFile.prototype.handleXhrIo_ = function(event) { * @param {ArrayBuffer|Document|Node|Object|string} source Source. * @private */ -ol.source.VectorFile.prototype.readFeatures_ = function(source) { +ol.source.StaticVector.prototype.readFeatures_ = function(source) { var format = this.format; var features = format.readFeatures(source); var featureProjection = format.readProjection(source); diff --git a/src/ol/source/topojsonsource.js b/src/ol/source/topojsonsource.js index 991c72afb8..cd65cf76ba 100644 --- a/src/ol/source/topojsonsource.js +++ b/src/ol/source/topojsonsource.js @@ -1,13 +1,13 @@ goog.provide('ol.source.TopoJSON'); goog.require('ol.format.TopoJSON'); -goog.require('ol.source.VectorFile'); +goog.require('ol.source.StaticVector'); /** * @constructor - * @extends {ol.source.VectorFile} + * @extends {ol.source.StaticVector} * @fires {@link ol.source.VectorEvent} ol.source.VectorEvent * @param {olx.source.TopoJSONOptions=} opt_options Options. * @todo stability experimental @@ -30,4 +30,4 @@ ol.source.TopoJSON = function(opt_options) { }); }; -goog.inherits(ol.source.TopoJSON, ol.source.VectorFile); +goog.inherits(ol.source.TopoJSON, ol.source.StaticVector); diff --git a/src/ol/source/vectorfilesource.exports b/src/ol/source/vectorfilesource.exports deleted file mode 100644 index acd6140571..0000000000 --- a/src/ol/source/vectorfilesource.exports +++ /dev/null @@ -1 +0,0 @@ -@exportSymbol ol.source.VectorFile From 073f83cd22656a2f3dbe4fc0b2d855707c9dd2ff Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Fri, 21 Feb 2014 16:20:50 +0100 Subject: [PATCH 02/28] Factor out ol.source.FormatVector --- src/objectliterals.jsdoc | 9 ++ src/ol/source/formatvectorsource.js | 138 ++++++++++++++++++++++++++++ src/ol/source/staticvectorsource.js | 138 +++------------------------- 3 files changed, 162 insertions(+), 123 deletions(-) create mode 100644 src/ol/source/formatvectorsource.js diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 26430e0b36..971291cfca 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -668,6 +668,15 @@ * @todo stability experimental */ +/** + * @typedef {Object} olx.source.FormatVectorOptions + * @property {Array.|undefined} attributions Attributions. + * @property {ol.Extent|undefined} extent Extent. + * @property {ol.format.Feature} format Format. + * @property {string|undefined} logo Logo. + * @property {ol.proj.ProjectionLike} projection Projection. + */ + /** * @typedef {Object} olx.source.GeoJSONOptions * @property {Array.|undefined} attributions Attributions. diff --git a/src/ol/source/formatvectorsource.js b/src/ol/source/formatvectorsource.js new file mode 100644 index 0000000000..418e098f8a --- /dev/null +++ b/src/ol/source/formatvectorsource.js @@ -0,0 +1,138 @@ +// 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.BrowserFeature'); +goog.require('ol.format.FormatType'); +goog.require('ol.proj'); +goog.require('ol.source.State'); +goog.require('ol.source.Vector'); +goog.require('ol.xml'); + + + +/** + * @constructor + * @extends {ol.source.Vector} + * @param {olx.source.FormatVectorOptions} options Options. + * @todo stability experimental + */ +ol.source.FormatVector = function(options) { + + goog.base(this, { + attributions: options.attributions, + extent: options.extent, + logo: options.logo, + projection: options.projection + }); + + /** + * @protected + * @type {ol.format.Feature} + */ + this.format = options.format; + + /** + * @protected + * @type {function(Event)} + */ + this.handleXhrIo = goog.bind(this.handleXhrIo_, this); + +}; +goog.inherits(ol.source.FormatVector, ol.source.Vector); + + +/** + * @param {Event} event Event. + * @private + */ +ol.source.FormatVector.prototype.handleXhrIo_ = function(event) { + var xhrIo = event.target; + goog.asserts.assertInstanceof(xhrIo, 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.BrowserFeature.HAS_ARRAY_BUFFER) { + source = xhrIo.getResponse(); + goog.asserts.assertInstanceof(source, 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.load(xhrIo.getResponseText()); + } + } else { + goog.asserts.fail(); + } + if (goog.isDefAndNotNull(source)) { + this.readFeatures(source); + } else { + this.setState(ol.source.State.ERROR); + goog.asserts.fail(); + } + } else { + this.setState(ol.source.State.ERROR); + } + goog.dispose(xhrIo); +}; + + +/** + * @param {goog.Uri|string} url URL. + */ +ol.source.FormatVector.prototype.loadFeatures = function(url) { + 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.BrowserFeature.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, this.handleXhrIo); + xhrIo.send(url); +}; + + +/** + * @param {ArrayBuffer|Document|Node|Object|string} source Source. + */ +ol.source.FormatVector.prototype.readFeatures = function(source) { + var format = this.format; + var features = format.readFeatures(source); + var featureProjection = format.readProjection(source); + var projection = this.getProjection(); + if (!goog.isNull(projection)) { + if (!ol.proj.equivalent(featureProjection, projection)) { + var transform = ol.proj.getTransform(featureProjection, projection); + var i, ii; + for (i = 0, ii = features.length; i < ii; ++i) { + var feature = features[i]; + var geometry = feature.getGeometry(); + if (!goog.isNull(geometry)) { + geometry.transform(transform); + } + } + } + } + this.addFeaturesInternal(features); + this.setState(ol.source.State.READY); +}; diff --git a/src/ol/source/staticvectorsource.js b/src/ol/source/staticvectorsource.js index ace4886d3b..6070bc8afa 100644 --- a/src/ol/source/staticvectorsource.js +++ b/src/ol/source/staticvectorsource.js @@ -1,168 +1,60 @@ -// FIXME consider delaying feature reading so projection can be provided by -// consumer (e.g. the view) - goog.provide('ol.source.StaticVector'); -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.BrowserFeature'); -goog.require('ol.format.FormatType'); -goog.require('ol.proj'); +goog.require('ol.source.FormatVector'); goog.require('ol.source.State'); -goog.require('ol.source.Vector'); -goog.require('ol.xml'); /** * @constructor - * @extends {ol.source.Vector} + * @extends {ol.source.FormatVector} * @fires {@link ol.source.VectorEvent} ol.source.VectorEvent - * @param {olx.source.StaticVectorOptions=} opt_options Options. + * @param {olx.source.StaticVectorOptions} options Options. * @todo stability experimental */ -ol.source.StaticVector = function(opt_options) { - - var options = goog.isDef(opt_options) ? opt_options : {}; +ol.source.StaticVector = function(options) { goog.base(this, { attributions: options.attributions, extent: options.extent, + format: options.format, logo: options.logo, projection: options.projection }); - /** - * @type {ol.format.Feature} - * @protected - */ - this.format = options.format; + if (goog.isDef(options.arrayBuffer)) { + this.readFeatures(options.arrayBuffer); + } if (goog.isDef(options.doc)) { - this.readFeatures_(options.doc); + this.readFeatures(options.doc); } if (goog.isDef(options.node)) { - this.readFeatures_(options.node); + this.readFeatures(options.node); } if (goog.isDef(options.object)) { - this.readFeatures_(options.object); + this.readFeatures(options.object); } if (goog.isDef(options.text)) { - this.readFeatures_(options.text); - } - - if (goog.isDef(options.arrayBuffer)) { - this.readFeatures_(options.arrayBuffer); + this.readFeatures(options.text); } if (goog.isDef(options.url) || goog.isDef(options.urls)) { this.setState(ol.source.State.LOADING); - - var type = this.format.getType(); - var responseType; - if (type == ol.format.FormatType.BINARY && - ol.BrowserFeature.HAS_ARRAY_BUFFER) { - responseType = goog.net.XhrIo.ResponseType.ARRAY_BUFFER; - } else { - responseType = goog.net.XhrIo.ResponseType.TEXT; - } - var xhrIo; if (goog.isDef(options.url)) { - xhrIo = new goog.net.XhrIo(); - xhrIo.setResponseType(responseType); - goog.events.listen(xhrIo, goog.net.EventType.COMPLETE, - goog.bind(this.handleXhrIo_, this)); - xhrIo.send(options.url); + this.loadFeatures(options.url); } if (goog.isDef(options.urls)) { var urls = options.urls; var i, ii; for (i = 0, ii = urls.length; i < ii; ++i) { - xhrIo = new goog.net.XhrIo(); - xhrIo.setResponseType(responseType); - goog.events.listen(xhrIo, goog.net.EventType.COMPLETE, - goog.bind(this.handleXhrIo_, this)); - xhrIo.send(urls[i]); + this.loadFeatures(urls[i]); } } } }; -goog.inherits(ol.source.StaticVector, ol.source.Vector); - - -/** - * @param {Event} event Event. - * @private - */ -ol.source.StaticVector.prototype.handleXhrIo_ = function(event) { - var xhrIo = event.target; - goog.asserts.assertInstanceof(xhrIo, 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.BrowserFeature.HAS_ARRAY_BUFFER) { - source = xhrIo.getResponse(); - goog.asserts.assertInstanceof(source, 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.load(xhrIo.getResponseText()); - } - } else { - goog.asserts.fail(); - } - goog.dispose(xhrIo); - if (goog.isDefAndNotNull(source)) { - this.readFeatures_(source); - } else { - this.setState(ol.source.State.ERROR); - goog.asserts.fail(); - } - } else { - this.setState(ol.source.State.ERROR); - } -}; - - -/** - * @param {ArrayBuffer|Document|Node|Object|string} source Source. - * @private - */ -ol.source.StaticVector.prototype.readFeatures_ = function(source) { - var format = this.format; - var features = format.readFeatures(source); - var featureProjection = format.readProjection(source); - var projection = this.getProjection(); - if (!goog.isNull(projection)) { - if (!ol.proj.equivalent(featureProjection, projection)) { - var transform = ol.proj.getTransform(featureProjection, projection); - var i, ii; - for (i = 0, ii = features.length; i < ii; ++i) { - var feature = features[i]; - var geometry = feature.getGeometry(); - if (!goog.isNull(geometry)) { - geometry.transform(transform); - } - } - } - } - this.addFeaturesInternal(features); - this.setState(ol.source.State.READY); -}; +goog.inherits(ol.source.StaticVector, ol.source.FormatVector); From b008dd1805811c03ea950e1c33d12d1b2beb611d Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 4 Mar 2014 15:58:43 +0100 Subject: [PATCH 03/28] Rename ol.source.FormatVector#loadFeatures to loadFeaturesFromURL --- src/ol/source/formatvectorsource.js | 2 +- src/ol/source/staticvectorsource.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ol/source/formatvectorsource.js b/src/ol/source/formatvectorsource.js index 418e098f8a..cb7d08dfb9 100644 --- a/src/ol/source/formatvectorsource.js +++ b/src/ol/source/formatvectorsource.js @@ -95,7 +95,7 @@ ol.source.FormatVector.prototype.handleXhrIo_ = function(event) { /** * @param {goog.Uri|string} url URL. */ -ol.source.FormatVector.prototype.loadFeatures = function(url) { +ol.source.FormatVector.prototype.loadFeaturesFromURL = function(url) { var xhrIo = new goog.net.XhrIo(); var type = this.format.getType(); var responseType; diff --git a/src/ol/source/staticvectorsource.js b/src/ol/source/staticvectorsource.js index 6070bc8afa..e13de2eef4 100644 --- a/src/ol/source/staticvectorsource.js +++ b/src/ol/source/staticvectorsource.js @@ -45,13 +45,13 @@ ol.source.StaticVector = function(options) { if (goog.isDef(options.url) || goog.isDef(options.urls)) { this.setState(ol.source.State.LOADING); if (goog.isDef(options.url)) { - this.loadFeatures(options.url); + this.loadFeaturesFromURL(options.url); } if (goog.isDef(options.urls)) { var urls = options.urls; var i, ii; for (i = 0, ii = urls.length; i < ii; ++i) { - this.loadFeatures(urls[i]); + this.loadFeaturesFromURL(urls[i]); } } } From 8c984cc8f78e9b201805f91cf945290c50f50b4d Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 4 Mar 2014 15:59:18 +0100 Subject: [PATCH 04/28] Load features before rendering --- src/ol/renderer/canvas/canvasvectorlayerrenderer.js | 1 + src/ol/source/vectorsource.js | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js index 4a59c94c9d..4de7415bb1 100644 --- a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js +++ b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js @@ -207,6 +207,7 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = var tolerance = frameStateResolution / (2 * pixelRatio); var replayGroup = new ol.render.canvas.ReplayGroup(tolerance, extent, frameStateResolution); + vectorSource.loadFeatures(extent, frameStateResolution); var renderFeature = /** * @param {ol.Feature} feature Feature. diff --git a/src/ol/source/vectorsource.js b/src/ol/source/vectorsource.js index 6383b6dcd9..71d8dc8b2c 100644 --- a/src/ol/source/vectorsource.js +++ b/src/ol/source/vectorsource.js @@ -337,6 +337,13 @@ ol.source.Vector.prototype.isEmpty = function() { }; +/** + * @param {ol.Extent} extent Extent. + * @param {number} resolution Resolution. + */ +ol.source.Vector.prototype.loadFeatures = goog.nullFunction; + + /** * @param {ol.Feature} feature Feature. * @todo stability experimental From 2842d1b2540b9bfe68532ec19caa5fee4ed26b63 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 4 Mar 2014 15:59:58 +0100 Subject: [PATCH 05/28] Add ol.loading --- src/ol/loading.exports | 3 +++ src/ol/loading.js | 52 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/ol/loading.exports create mode 100644 src/ol/loading.js diff --git a/src/ol/loading.exports b/src/ol/loading.exports new file mode 100644 index 0000000000..7564c21668 --- /dev/null +++ b/src/ol/loading.exports @@ -0,0 +1,3 @@ +@exportSymbol ol.loading.all +@exportSymbol ol.loading.bbox +@exportSymbol ol.loading.createTile diff --git a/src/ol/loading.js b/src/ol/loading.js new file mode 100644 index 0000000000..272d3b2887 --- /dev/null +++ b/src/ol/loading.js @@ -0,0 +1,52 @@ +goog.provide('ol.loading'); + +goog.require('ol.TileCoord'); + + +/** + * @param {ol.Extent} extent Extent. + * @param {number} resolution Resolution. + * @return {Array.} Extents. + */ +ol.loading.all = function(extent, resolution) { + return [[-Infinity, -Infinity, Infinity, Infinity]]; +}; + + +/** + * @param {ol.Extent} extent Extent. + * @param {number} resolution Resolution. + * @return {Array.} Extents. + */ +ol.loading.bbox = function(extent, resolution) { + return [extent]; +}; + + +/** + * @param {ol.tilegrid.TileGrid} tileGrid Tile grid. + * @return {function(ol.Extent, number): Array.} Loading strategy. + */ +ol.loading.createTile = function(tileGrid) { + return ( + /** + * @param {ol.Extent} extent Extent. + * @param {number} resolution Resolution. + * @return {Array.} Extents. + */ + function(extent, resolution) { + var z = tileGrid.getZForResolution(resolution); + var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); + /** @type {Array.} */ + var extents = []; + var tileCoord = new ol.TileCoord(z, 0, 0); + for (tileCoord.x = tileRange.minX; tileCoord.x <= tileRange.maxX; + ++tileCoord.x) { + for (tileCoord.y = tileRange.minY; tileCoord.y <= tileRange.maxY; + ++tileCoord.y) { + extents.push(tileGrid.getTileCoordExtent(tileCoord)); + } + } + return extents; + }); +}; From 50c4961b9f28cfb2993e5a32a1cc7b8f2233a827 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 4 Mar 2014 16:02:23 +0100 Subject: [PATCH 06/28] Add ol.source.RemoteVector --- src/objectliterals.jsdoc | 12 +++ src/ol/source/remotevectorsource.exports | 1 + src/ol/source/remotevectorsource.js | 97 ++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 src/ol/source/remotevectorsource.exports create mode 100644 src/ol/source/remotevectorsource.js diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 971291cfca..240dd79e79 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -904,6 +904,18 @@ * @property {string} url Url. */ +/** + * @typedef {Object} olx.source.RemoteVectorOptions + * @property {Array.|undefined} attributions Attributions. + * @property {ol.Extent|undefined} extent Extent. + * @property {function(ol.Extent, number): string} extentUrlFunction Extent URL function. + * @property {Object.|undefined} headers Headers. + * @property {ol.format.Feature} format Format. + * @property {function(ol.Extent, number): Array.} loadingFunction Loading function. + * @property {string|undefined} logo Logo. + * @property {ol.proj.ProjectionLike} projection Projection. + */ + /** * @typedef {Object} olx.source.TileJSONOptions * @property {null|string|undefined} crossOrigin crossOrigin setting for image diff --git a/src/ol/source/remotevectorsource.exports b/src/ol/source/remotevectorsource.exports new file mode 100644 index 0000000000..3e984107fd --- /dev/null +++ b/src/ol/source/remotevectorsource.exports @@ -0,0 +1 @@ +@exportSymbol ol.source.RemoteVector diff --git a/src/ol/source/remotevectorsource.js b/src/ol/source/remotevectorsource.js new file mode 100644 index 0000000000..926c6fc051 --- /dev/null +++ b/src/ol/source/remotevectorsource.js @@ -0,0 +1,97 @@ +// FIXME cache expiration + +goog.provide('ol.source.RemoteVector'); + +goog.require('ol.extent'); +goog.require('ol.source.FormatVector'); +goog.require('ol.structs.RBush'); + + + +/** + * @constructor + * @extends {ol.source.FormatVector} + * @param {olx.source.RemoteVectorOptions} options Options. + */ +ol.source.RemoteVector = function(options) { + + goog.base(this, { + attributions: options.attributions, + extent: options.extent, + format: options.format, + headers: options.headers, + logo: options.logo, + projection: options.projection + }); + + /** + * @private + * @type {ol.structs.RBush.<{extent: ol.Extent}>} + */ + this.loadedExtents_ = new ol.structs.RBush(); + + /** + * @private + * @type {function(ol.Extent, number): Array.} + */ + this.loadingFunction_ = options.loadingFunction; + + /** + * @private + * @type {function(ol.Extent, number): string} + */ + this.extentUrlFunction_ = options.extentUrlFunction; + + /** + * @private + * @type {Object.} + */ + this.loadedFeatures_ = {}; + +}; +goog.inherits(ol.source.RemoteVector, ol.source.FormatVector); + + +/** + * @inheritDoc + */ +ol.source.RemoteVector.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 (!(featureId in this.loadedFeatures_)) { + notLoadedFeatures.push(feature); + this.loadedFeatures_[featureId] = true; + } + } + goog.base(this, 'addFeaturesInternal', notLoadedFeatures); +}; + + +/** + * @inheritDoc + */ +ol.source.RemoteVector.prototype.loadFeatures = function(extent, resolution) { + var loadedExtents = this.loadedExtents_; + var extentsToLoad = this.loadingFunction_(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) { + var url = this.extentUrlFunction_(extentToLoad, resolution); + this.loadFeaturesFromURL(url); + loadedExtents.insert(extentToLoad, {extent: extentToLoad.slice()}); + } + } +}; From 10bddeae59d15285009eccf7624fa3a24c4f6e3b Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 4 Mar 2014 16:02:50 +0100 Subject: [PATCH 07/28] Load features on demand in vector-osm example --- examples/data/osm/map.osm | 2223 ------------------------------------- examples/vector-osm.html | 4 +- examples/vector-osm.js | 22 +- 3 files changed, 20 insertions(+), 2229 deletions(-) delete mode 100644 examples/data/osm/map.osm diff --git a/examples/data/osm/map.osm b/examples/data/osm/map.osm deleted file mode 100644 index 135e798e1d..0000000000 --- a/examples/data/osm/map.osm +++ /dev/null @@ -1,2223 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/vector-osm.html b/examples/vector-osm.html index 6a0e5ea7ef..bbf94f97ba 100644 --- a/examples/vector-osm.html +++ b/examples/vector-osm.html @@ -32,11 +32,11 @@

OSM XML example

-

Example of using the OSM XML source.

+

Example of using the OSM XML source. Vector data is loaded dynamically from a remote server using a tiling strategy.

See the vector-osm.js source to see how this is done.

-
vector, osm, xml
+
vector, osm, xml, loading, remote
diff --git a/examples/vector-osm.js b/examples/vector-osm.js index 7f870fd26e..5c154e2d13 100644 --- a/examples/vector-osm.js +++ b/examples/vector-osm.js @@ -1,13 +1,17 @@ goog.require('ol.Map'); goog.require('ol.View2D'); +goog.require('ol.format.OSMXML'); goog.require('ol.layer.Tile'); goog.require('ol.layer.Vector'); +goog.require('ol.loading'); +goog.require('ol.proj'); goog.require('ol.source.BingMaps'); -goog.require('ol.source.OSMXML'); +goog.require('ol.source.RemoteVector'); goog.require('ol.style.Circle'); goog.require('ol.style.Fill'); goog.require('ol.style.Stroke'); goog.require('ol.style.Style'); +goog.require('ol.tilegrid.XYZ'); var styles = { 'amenity': { @@ -83,9 +87,18 @@ var styles = { } }; -var vectorSource = new ol.source.OSMXML({ - projection: 'EPSG:3857', - url: 'data/osm/map.osm' +var epsg3857ToEPSG4326 = ol.proj.getTransform('EPSG:3857', 'EPSG:4326'); +var vectorSource = new ol.source.RemoteVector({ + extentUrlFunction: function(extent, resolution) { + var epsg4326Extent = epsg3857ToEPSG4326(extent, []); + return 'http://overpass-api.de/api/xapi?map?bbox=' + + epsg4326Extent.join(','); + }, + format: new ol.format.OSMXML(), + loadingFunction: ol.loading.createTile(new ol.tilegrid.XYZ({ + maxZoom: 19 + })), + projection: 'EPSG:3857' }); var vector = new ol.layer.Vector({ @@ -117,6 +130,7 @@ var map = new ol.Map({ target: document.getElementById('map'), view: new ol.View2D({ center: [739218, 5906096], + maxZoom: 19, zoom: 17 }) }); From cbbcab926ee65309b8d03d38a2b74fe7ca0391f1 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 4 Mar 2014 16:14:55 +0100 Subject: [PATCH 08/28] Export ol.format.OSMXML --- src/ol/format/osmxmlformat.exports | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/ol/format/osmxmlformat.exports diff --git a/src/ol/format/osmxmlformat.exports b/src/ol/format/osmxmlformat.exports new file mode 100644 index 0000000000..e9bb1a6835 --- /dev/null +++ b/src/ol/format/osmxmlformat.exports @@ -0,0 +1 @@ +@exportSymbol ol.format.OSMXML From b24e122d4fb908e60869c15c113f4956c5ee9b22 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Wed, 12 Mar 2014 15:27:52 +0100 Subject: [PATCH 09/28] Add projection argument when loading features --- src/objectliterals.jsdoc | 2 +- .../canvas/canvasvectorlayerrenderer.js | 18 ++++++++++-------- src/ol/source/remotevectorsource.js | 7 ++++--- src/ol/source/vectorsource.js | 2 ++ 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 240dd79e79..fe87dcf667 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -908,7 +908,7 @@ * @typedef {Object} olx.source.RemoteVectorOptions * @property {Array.|undefined} attributions Attributions. * @property {ol.Extent|undefined} extent Extent. - * @property {function(ol.Extent, number): string} extentUrlFunction Extent URL function. + * @property {function(ol.Extent, number, ol.proj.Projection): string} extentUrlFunction Extent URL function. * @property {Object.|undefined} headers Headers. * @property {ol.format.Feature} format Format. * @property {function(ol.Extent, number): Array.} loadingFunction Loading function. diff --git a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js index 4de7415bb1..a30659d894 100644 --- a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js +++ b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js @@ -170,7 +170,9 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = } var frameStateExtent = frameState.extent; - var frameStateResolution = frameState.view2DState.resolution; + var view2DState = frameState.view2DState; + var projection = view2DState.projection; + var resolution = view2DState.resolution; var pixelRatio = frameState.pixelRatio; var vectorLayerRevision = vectorLayer.getRevision(); var vectorLayerRenderOrder = vectorLayer.getRenderOrder(); @@ -179,7 +181,7 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = } if (!this.dirty_ && - this.renderedResolution_ == frameStateResolution && + this.renderedResolution_ == resolution && this.renderedRevision_ == vectorLayerRevision && this.renderedRenderOrder_ == vectorLayerRenderOrder && ol.extent.containsExtent(this.renderedExtent_, frameStateExtent)) { @@ -204,10 +206,10 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = if (!goog.isDef(styleFunction)) { styleFunction = ol.feature.defaultStyleFunction; } - var tolerance = frameStateResolution / (2 * pixelRatio); - var replayGroup = new ol.render.canvas.ReplayGroup(tolerance, extent, - frameStateResolution); - vectorSource.loadFeatures(extent, frameStateResolution); + var tolerance = resolution / (2 * pixelRatio); + var replayGroup = + new ol.render.canvas.ReplayGroup(tolerance, extent, resolution); + vectorSource.loadFeatures(extent, resolution, projection); var renderFeature = /** * @param {ol.Feature} feature Feature. @@ -216,7 +218,7 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = function(feature) { goog.asserts.assert(goog.isDef(styleFunction)); var dirty = this.renderFeature( - feature, frameStateResolution, pixelRatio, styleFunction, replayGroup); + feature, resolution, pixelRatio, styleFunction, replayGroup); this.dirty_ = this.dirty_ || dirty; }; if (!goog.isNull(vectorLayerRenderOrder)) { @@ -228,7 +230,7 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = } replayGroup.finish(); - this.renderedResolution_ = frameStateResolution; + this.renderedResolution_ = resolution; this.renderedRevision_ = vectorLayerRevision; this.renderedRenderOrder_ = vectorLayerRenderOrder; this.replayGroup_ = replayGroup; diff --git a/src/ol/source/remotevectorsource.js b/src/ol/source/remotevectorsource.js index 926c6fc051..3b37c560fb 100644 --- a/src/ol/source/remotevectorsource.js +++ b/src/ol/source/remotevectorsource.js @@ -38,7 +38,7 @@ ol.source.RemoteVector = function(options) { /** * @private - * @type {function(ol.Extent, number): string} + * @type {function(ol.Extent, number, ol.proj.Projection): string} */ this.extentUrlFunction_ = options.extentUrlFunction; @@ -74,7 +74,8 @@ ol.source.RemoteVector.prototype.addFeaturesInternal = function(features) { /** * @inheritDoc */ -ol.source.RemoteVector.prototype.loadFeatures = function(extent, resolution) { +ol.source.RemoteVector.prototype.loadFeatures = + function(extent, resolution, projection) { var loadedExtents = this.loadedExtents_; var extentsToLoad = this.loadingFunction_(extent, resolution); var i, ii; @@ -89,7 +90,7 @@ ol.source.RemoteVector.prototype.loadFeatures = function(extent, resolution) { return ol.extent.containsExtent(object.extent, extentToLoad); }); if (!alreadyLoaded) { - var url = this.extentUrlFunction_(extentToLoad, resolution); + var url = this.extentUrlFunction_(extentToLoad, resolution, projection); this.loadFeaturesFromURL(url); loadedExtents.insert(extentToLoad, {extent: extentToLoad.slice()}); } diff --git a/src/ol/source/vectorsource.js b/src/ol/source/vectorsource.js index 71d8dc8b2c..6c5659ab3d 100644 --- a/src/ol/source/vectorsource.js +++ b/src/ol/source/vectorsource.js @@ -13,6 +13,7 @@ goog.require('goog.events.Event'); goog.require('goog.events.EventType'); goog.require('goog.object'); goog.require('ol.ObjectEventType'); +goog.require('ol.proj'); goog.require('ol.source.Source'); goog.require('ol.structs.RBush'); @@ -340,6 +341,7 @@ ol.source.Vector.prototype.isEmpty = function() { /** * @param {ol.Extent} extent Extent. * @param {number} resolution Resolution. + * @param {ol.proj.Projection} projection Projection. */ ol.source.Vector.prototype.loadFeatures = goog.nullFunction; From de4a17b8e25739910a1da08d3b5c32939d393ca5 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 13 Mar 2014 20:05:42 +0100 Subject: [PATCH 10/28] Rename ol.source.RemoteVector to ServerVector --- examples/vector-osm.html | 4 ++-- examples/vector-osm.js | 4 ++-- src/objectliterals.jsdoc | 2 +- src/ol/source/remotevectorsource.exports | 1 - src/ol/source/servervectorsource.exports | 1 + .../{remotevectorsource.js => servervectorsource.js} | 12 ++++++------ 6 files changed, 12 insertions(+), 12 deletions(-) delete mode 100644 src/ol/source/remotevectorsource.exports create mode 100644 src/ol/source/servervectorsource.exports rename src/ol/source/{remotevectorsource.js => servervectorsource.js} (87%) diff --git a/examples/vector-osm.html b/examples/vector-osm.html index bbf94f97ba..67400eee6f 100644 --- a/examples/vector-osm.html +++ b/examples/vector-osm.html @@ -32,11 +32,11 @@

OSM XML example

-

Example of using the OSM XML source. Vector data is loaded dynamically from a remote server using a tiling strategy.

+

Example of using the OSM XML source. Vector data is loaded dynamically from a server using a tiling strategy.

See the vector-osm.js source to see how this is done.

-
vector, osm, xml, loading, remote
+
vector, osm, xml, loading, server
diff --git a/examples/vector-osm.js b/examples/vector-osm.js index 5c154e2d13..94427a1b14 100644 --- a/examples/vector-osm.js +++ b/examples/vector-osm.js @@ -6,7 +6,7 @@ goog.require('ol.layer.Vector'); goog.require('ol.loading'); goog.require('ol.proj'); goog.require('ol.source.BingMaps'); -goog.require('ol.source.RemoteVector'); +goog.require('ol.source.ServerVector'); goog.require('ol.style.Circle'); goog.require('ol.style.Fill'); goog.require('ol.style.Stroke'); @@ -88,7 +88,7 @@ var styles = { }; var epsg3857ToEPSG4326 = ol.proj.getTransform('EPSG:3857', 'EPSG:4326'); -var vectorSource = new ol.source.RemoteVector({ +var vectorSource = new ol.source.ServerVector({ extentUrlFunction: function(extent, resolution) { var epsg4326Extent = epsg3857ToEPSG4326(extent, []); return 'http://overpass-api.de/api/xapi?map?bbox=' + diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index fe87dcf667..7d03ce5bb8 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -905,7 +905,7 @@ */ /** - * @typedef {Object} olx.source.RemoteVectorOptions + * @typedef {Object} olx.source.ServerVectorOptions * @property {Array.|undefined} attributions Attributions. * @property {ol.Extent|undefined} extent Extent. * @property {function(ol.Extent, number, ol.proj.Projection): string} extentUrlFunction Extent URL function. diff --git a/src/ol/source/remotevectorsource.exports b/src/ol/source/remotevectorsource.exports deleted file mode 100644 index 3e984107fd..0000000000 --- a/src/ol/source/remotevectorsource.exports +++ /dev/null @@ -1 +0,0 @@ -@exportSymbol ol.source.RemoteVector diff --git a/src/ol/source/servervectorsource.exports b/src/ol/source/servervectorsource.exports new file mode 100644 index 0000000000..03a26a0698 --- /dev/null +++ b/src/ol/source/servervectorsource.exports @@ -0,0 +1 @@ +@exportSymbol ol.source.ServerVector diff --git a/src/ol/source/remotevectorsource.js b/src/ol/source/servervectorsource.js similarity index 87% rename from src/ol/source/remotevectorsource.js rename to src/ol/source/servervectorsource.js index 3b37c560fb..7f30394494 100644 --- a/src/ol/source/remotevectorsource.js +++ b/src/ol/source/servervectorsource.js @@ -1,6 +1,6 @@ // FIXME cache expiration -goog.provide('ol.source.RemoteVector'); +goog.provide('ol.source.ServerVector'); goog.require('ol.extent'); goog.require('ol.source.FormatVector'); @@ -11,9 +11,9 @@ goog.require('ol.structs.RBush'); /** * @constructor * @extends {ol.source.FormatVector} - * @param {olx.source.RemoteVectorOptions} options Options. + * @param {olx.source.ServerVectorOptions} options Options. */ -ol.source.RemoteVector = function(options) { +ol.source.ServerVector = function(options) { goog.base(this, { attributions: options.attributions, @@ -49,13 +49,13 @@ ol.source.RemoteVector = function(options) { this.loadedFeatures_ = {}; }; -goog.inherits(ol.source.RemoteVector, ol.source.FormatVector); +goog.inherits(ol.source.ServerVector, ol.source.FormatVector); /** * @inheritDoc */ -ol.source.RemoteVector.prototype.addFeaturesInternal = function(features) { +ol.source.ServerVector.prototype.addFeaturesInternal = function(features) { /** @type {Array.} */ var notLoadedFeatures = []; var i, ii; @@ -74,7 +74,7 @@ ol.source.RemoteVector.prototype.addFeaturesInternal = function(features) { /** * @inheritDoc */ -ol.source.RemoteVector.prototype.loadFeatures = +ol.source.ServerVector.prototype.loadFeatures = function(extent, resolution, projection) { var loadedExtents = this.loadedExtents_; var extentsToLoad = this.loadingFunction_(extent, resolution); From b8869805a77dbcf0d4d18e6e9852a322261fe681 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 13 Mar 2014 20:21:15 +0100 Subject: [PATCH 11/28] Rename ol.loading to ol.loadingstrategy --- examples/vector-osm.js | 4 ++-- src/objectliterals.jsdoc | 2 +- src/ol/extent.js | 11 +++++++++++ src/ol/loading.exports | 3 --- src/ol/loadingstrategy.exports | 3 +++ src/ol/{loading.js => loadingstrategy.js} | 8 ++++---- src/ol/source/servervectorsource.js | 4 ++-- 7 files changed, 23 insertions(+), 12 deletions(-) delete mode 100644 src/ol/loading.exports create mode 100644 src/ol/loadingstrategy.exports rename src/ol/{loading.js => loadingstrategy.js} (86%) diff --git a/examples/vector-osm.js b/examples/vector-osm.js index 94427a1b14..cba43f1d7f 100644 --- a/examples/vector-osm.js +++ b/examples/vector-osm.js @@ -3,7 +3,7 @@ goog.require('ol.View2D'); goog.require('ol.format.OSMXML'); goog.require('ol.layer.Tile'); goog.require('ol.layer.Vector'); -goog.require('ol.loading'); +goog.require('ol.loadingstrategy'); goog.require('ol.proj'); goog.require('ol.source.BingMaps'); goog.require('ol.source.ServerVector'); @@ -95,7 +95,7 @@ var vectorSource = new ol.source.ServerVector({ epsg4326Extent.join(','); }, format: new ol.format.OSMXML(), - loadingFunction: ol.loading.createTile(new ol.tilegrid.XYZ({ + loadingStrategy: ol.loadingstrategy.createTile(new ol.tilegrid.XYZ({ maxZoom: 19 })), projection: 'EPSG:3857' diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 7d03ce5bb8..9e566be949 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -911,7 +911,7 @@ * @property {function(ol.Extent, number, ol.proj.Projection): string} extentUrlFunction Extent URL function. * @property {Object.|undefined} headers Headers. * @property {ol.format.Feature} format Format. - * @property {function(ol.Extent, number): Array.} loadingFunction Loading function. + * @property {function(ol.Extent, number): Array.} loadingStrategy Loading strategy. * @property {string|undefined} logo Logo. * @property {ol.proj.ProjectionLike} projection Projection. */ diff --git a/src/ol/extent.js b/src/ol/extent.js index ba146637fc..10f36db01d 100644 --- a/src/ol/extent.js +++ b/src/ol/extent.js @@ -597,6 +597,17 @@ ol.extent.isEmpty = function(extent) { }; +/** + * @param {ol.Extent} extent Extent. + * @return {boolean} Is infinite. + * @todo stability experimental + */ +ol.extent.isInfinite = function(extent) { + return extent[0] == -Infinity || extent[1] == -Infinity || + extent[2] == Infinity || extent[3] == Infinity; +}; + + /** * @param {ol.Extent} extent Extent. * @param {ol.Coordinate} coordinate Coordinate. diff --git a/src/ol/loading.exports b/src/ol/loading.exports deleted file mode 100644 index 7564c21668..0000000000 --- a/src/ol/loading.exports +++ /dev/null @@ -1,3 +0,0 @@ -@exportSymbol ol.loading.all -@exportSymbol ol.loading.bbox -@exportSymbol ol.loading.createTile diff --git a/src/ol/loadingstrategy.exports b/src/ol/loadingstrategy.exports new file mode 100644 index 0000000000..711262d776 --- /dev/null +++ b/src/ol/loadingstrategy.exports @@ -0,0 +1,3 @@ +@exportSymbol ol.loadingstrategy.all +@exportSymbol ol.loadingstrategy.bbox +@exportSymbol ol.loadingstrategy.createTile diff --git a/src/ol/loading.js b/src/ol/loadingstrategy.js similarity index 86% rename from src/ol/loading.js rename to src/ol/loadingstrategy.js index 272d3b2887..58a5dd4b3b 100644 --- a/src/ol/loading.js +++ b/src/ol/loadingstrategy.js @@ -1,4 +1,4 @@ -goog.provide('ol.loading'); +goog.provide('ol.loadingstrategy'); goog.require('ol.TileCoord'); @@ -8,7 +8,7 @@ goog.require('ol.TileCoord'); * @param {number} resolution Resolution. * @return {Array.} Extents. */ -ol.loading.all = function(extent, resolution) { +ol.loadingstrategy.all = function(extent, resolution) { return [[-Infinity, -Infinity, Infinity, Infinity]]; }; @@ -18,7 +18,7 @@ ol.loading.all = function(extent, resolution) { * @param {number} resolution Resolution. * @return {Array.} Extents. */ -ol.loading.bbox = function(extent, resolution) { +ol.loadingstrategy.bbox = function(extent, resolution) { return [extent]; }; @@ -27,7 +27,7 @@ ol.loading.bbox = function(extent, resolution) { * @param {ol.tilegrid.TileGrid} tileGrid Tile grid. * @return {function(ol.Extent, number): Array.} Loading strategy. */ -ol.loading.createTile = function(tileGrid) { +ol.loadingstrategy.createTile = function(tileGrid) { return ( /** * @param {ol.Extent} extent Extent. diff --git a/src/ol/source/servervectorsource.js b/src/ol/source/servervectorsource.js index 7f30394494..5f1e5570bf 100644 --- a/src/ol/source/servervectorsource.js +++ b/src/ol/source/servervectorsource.js @@ -34,7 +34,7 @@ ol.source.ServerVector = function(options) { * @private * @type {function(ol.Extent, number): Array.} */ - this.loadingFunction_ = options.loadingFunction; + this.loadingStrategy_ = options.loadingStrategy; /** * @private @@ -77,7 +77,7 @@ ol.source.ServerVector.prototype.addFeaturesInternal = function(features) { ol.source.ServerVector.prototype.loadFeatures = function(extent, resolution, projection) { var loadedExtents = this.loadedExtents_; - var extentsToLoad = this.loadingFunction_(extent, resolution); + var extentsToLoad = this.loadingStrategy_(extent, resolution); var i, ii; for (i = 0, ii = extentsToLoad.length; i < ii; ++i) { var extentToLoad = extentsToLoad[i]; From 9e756848234e15bca17ad849abd63522c75c7a46 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 13 Mar 2014 20:39:58 +0100 Subject: [PATCH 12/28] Replace extentUrlFunction with generic loadingFunction --- examples/vector-osm.js | 15 +++++++++------ src/objectliterals.jsdoc | 3 +-- src/ol/source/servervectorsource.js | 13 ++++++------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/examples/vector-osm.js b/examples/vector-osm.js index cba43f1d7f..d0c69abc5c 100644 --- a/examples/vector-osm.js +++ b/examples/vector-osm.js @@ -87,14 +87,17 @@ var styles = { } }; -var epsg3857ToEPSG4326 = ol.proj.getTransform('EPSG:3857', 'EPSG:4326'); var vectorSource = new ol.source.ServerVector({ - extentUrlFunction: function(extent, resolution) { - var epsg4326Extent = epsg3857ToEPSG4326(extent, []); - return 'http://overpass-api.de/api/xapi?map?bbox=' + - epsg4326Extent.join(','); - }, format: new ol.format.OSMXML(), + loadingFunction: function(extent, resolution, projection) { + var transform = ol.proj.getTransform(projection, 'EPSG:4326'); + var epsg4326Extent = transform(extent, []); + var url = 'http://overpass-api.de/api/xapi?map?bbox=' + + epsg4326Extent.join(','); + $.ajax(url).then(function(response) { + vectorSource.readFeatures(response); + }); + }, loadingStrategy: ol.loadingstrategy.createTile(new ol.tilegrid.XYZ({ maxZoom: 19 })), diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 9e566be949..fe1441c1e7 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -908,9 +908,8 @@ * @typedef {Object} olx.source.ServerVectorOptions * @property {Array.|undefined} attributions Attributions. * @property {ol.Extent|undefined} extent Extent. - * @property {function(ol.Extent, number, ol.proj.Projection): string} extentUrlFunction Extent URL function. - * @property {Object.|undefined} headers Headers. * @property {ol.format.Feature} format Format. + * @property {function(this: ol.source.ServerVector, ol.Extent, number, ol.proj.Projection)} loadingFunction Loading function. * @property {function(ol.Extent, number): Array.} loadingStrategy Loading strategy. * @property {string|undefined} logo Logo. * @property {ol.proj.ProjectionLike} projection Projection. diff --git a/src/ol/source/servervectorsource.js b/src/ol/source/servervectorsource.js index 5f1e5570bf..6a968372d2 100644 --- a/src/ol/source/servervectorsource.js +++ b/src/ol/source/servervectorsource.js @@ -19,7 +19,6 @@ ol.source.ServerVector = function(options) { attributions: options.attributions, extent: options.extent, format: options.format, - headers: options.headers, logo: options.logo, projection: options.projection }); @@ -32,15 +31,16 @@ ol.source.ServerVector = function(options) { /** * @private - * @type {function(ol.Extent, number): Array.} + * @type {function(this: ol.source.ServerVector, ol.Extent, number, + * ol.proj.Projection): string} */ - this.loadingStrategy_ = options.loadingStrategy; + this.loadingFunction_ = options.loadingFunction; /** * @private - * @type {function(ol.Extent, number, ol.proj.Projection): string} + * @type {function(ol.Extent, number): Array.} */ - this.extentUrlFunction_ = options.extentUrlFunction; + this.loadingStrategy_ = options.loadingStrategy; /** * @private @@ -90,8 +90,7 @@ ol.source.ServerVector.prototype.loadFeatures = return ol.extent.containsExtent(object.extent, extentToLoad); }); if (!alreadyLoaded) { - var url = this.extentUrlFunction_(extentToLoad, resolution, projection); - this.loadFeaturesFromURL(url); + this.loadingFunction_.call(this, extentToLoad, resolution, projection); loadedExtents.insert(extentToLoad, {extent: extentToLoad.slice()}); } } From db1a06ac318130b0d5e5ba1b77cf4472027d36b8 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Mon, 17 Mar 2014 17:19:14 +0100 Subject: [PATCH 13/28] Use a BBOX loading strategy by default --- src/objectliterals.jsdoc | 2 +- src/ol/source/servervectorsource.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index fe1441c1e7..cf1995025b 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -910,7 +910,7 @@ * @property {ol.Extent|undefined} extent Extent. * @property {ol.format.Feature} format Format. * @property {function(this: ol.source.ServerVector, ol.Extent, number, ol.proj.Projection)} loadingFunction Loading function. - * @property {function(ol.Extent, number): Array.} loadingStrategy Loading strategy. + * @property {function(ol.Extent, number): Array.|undefined} loadingStrategy Loading strategy. Default is `ol.loadingstrategy.bbox`. * @property {string|undefined} logo Logo. * @property {ol.proj.ProjectionLike} projection Projection. */ diff --git a/src/ol/source/servervectorsource.js b/src/ol/source/servervectorsource.js index 6a968372d2..e804659b06 100644 --- a/src/ol/source/servervectorsource.js +++ b/src/ol/source/servervectorsource.js @@ -3,6 +3,7 @@ goog.provide('ol.source.ServerVector'); goog.require('ol.extent'); +goog.require('ol.loadingstrategy'); goog.require('ol.source.FormatVector'); goog.require('ol.structs.RBush'); @@ -40,7 +41,8 @@ ol.source.ServerVector = function(options) { * @private * @type {function(ol.Extent, number): Array.} */ - this.loadingStrategy_ = options.loadingStrategy; + this.loadingStrategy_ = goog.isDef(options.loadingStrategy) ? + options.loadingStrategy : ol.loadingstrategy.bbox; /** * @private From ce8d805201dc8c866b780276ea367ac21a8cba77 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 20 Mar 2014 08:18:06 -0600 Subject: [PATCH 14/28] Rename loadingFunction to loader --- examples/vector-osm.js | 2 +- src/objectliterals.jsdoc | 2 +- src/ol/source/servervectorsource.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/vector-osm.js b/examples/vector-osm.js index d0c69abc5c..8b5bcf90f4 100644 --- a/examples/vector-osm.js +++ b/examples/vector-osm.js @@ -89,7 +89,7 @@ var styles = { var vectorSource = new ol.source.ServerVector({ format: new ol.format.OSMXML(), - loadingFunction: function(extent, resolution, projection) { + loader: function(extent, resolution, projection) { var transform = ol.proj.getTransform(projection, 'EPSG:4326'); var epsg4326Extent = transform(extent, []); var url = 'http://overpass-api.de/api/xapi?map?bbox=' + diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index cf1995025b..c9e90714e7 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -909,7 +909,7 @@ * @property {Array.|undefined} attributions Attributions. * @property {ol.Extent|undefined} extent Extent. * @property {ol.format.Feature} format Format. - * @property {function(this: ol.source.ServerVector, ol.Extent, number, ol.proj.Projection)} loadingFunction Loading function. + * @property {function(this: ol.source.ServerVector, ol.Extent, number, ol.proj.Projection)} loader Loading function. * @property {function(ol.Extent, number): Array.|undefined} loadingStrategy Loading strategy. Default is `ol.loadingstrategy.bbox`. * @property {string|undefined} logo Logo. * @property {ol.proj.ProjectionLike} projection Projection. diff --git a/src/ol/source/servervectorsource.js b/src/ol/source/servervectorsource.js index e804659b06..34f8752bf4 100644 --- a/src/ol/source/servervectorsource.js +++ b/src/ol/source/servervectorsource.js @@ -35,7 +35,7 @@ ol.source.ServerVector = function(options) { * @type {function(this: ol.source.ServerVector, ol.Extent, number, * ol.proj.Projection): string} */ - this.loadingFunction_ = options.loadingFunction; + this.loader_ = options.loader; /** * @private @@ -92,7 +92,7 @@ ol.source.ServerVector.prototype.loadFeatures = return ol.extent.containsExtent(object.extent, extentToLoad); }); if (!alreadyLoaded) { - this.loadingFunction_.call(this, extentToLoad, resolution, projection); + this.loader_.call(this, extentToLoad, resolution, projection); loadedExtents.insert(extentToLoad, {extent: extentToLoad.slice()}); } } From 86c5a582c7dbe62a79c029eda0f25cf15a8f8d2b Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 20 Mar 2014 08:20:14 -0600 Subject: [PATCH 15/28] Rename loadingStrategy to strategy --- examples/vector-osm.js | 2 +- src/objectliterals.jsdoc | 2 +- src/ol/source/servervectorsource.js | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/vector-osm.js b/examples/vector-osm.js index 8b5bcf90f4..8dd778508b 100644 --- a/examples/vector-osm.js +++ b/examples/vector-osm.js @@ -98,7 +98,7 @@ var vectorSource = new ol.source.ServerVector({ vectorSource.readFeatures(response); }); }, - loadingStrategy: ol.loadingstrategy.createTile(new ol.tilegrid.XYZ({ + strategy: ol.loadingstrategy.createTile(new ol.tilegrid.XYZ({ maxZoom: 19 })), projection: 'EPSG:3857' diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index c9e90714e7..c9410a7a5d 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -910,7 +910,7 @@ * @property {ol.Extent|undefined} extent Extent. * @property {ol.format.Feature} format Format. * @property {function(this: ol.source.ServerVector, ol.Extent, number, ol.proj.Projection)} loader Loading function. - * @property {function(ol.Extent, number): Array.|undefined} loadingStrategy Loading strategy. Default is `ol.loadingstrategy.bbox`. + * @property {function(ol.Extent, number): Array.|undefined} strategy Loading strategy. Default is `ol.loadingstrategy.bbox`. * @property {string|undefined} logo Logo. * @property {ol.proj.ProjectionLike} projection Projection. */ diff --git a/src/ol/source/servervectorsource.js b/src/ol/source/servervectorsource.js index 34f8752bf4..f10085c2b8 100644 --- a/src/ol/source/servervectorsource.js +++ b/src/ol/source/servervectorsource.js @@ -41,8 +41,8 @@ ol.source.ServerVector = function(options) { * @private * @type {function(ol.Extent, number): Array.} */ - this.loadingStrategy_ = goog.isDef(options.loadingStrategy) ? - options.loadingStrategy : ol.loadingstrategy.bbox; + this.strategy_ = goog.isDef(options.strategy) ? + options.strategy : ol.loadingstrategy.bbox; /** * @private @@ -79,7 +79,7 @@ ol.source.ServerVector.prototype.addFeaturesInternal = function(features) { ol.source.ServerVector.prototype.loadFeatures = function(extent, resolution, projection) { var loadedExtents = this.loadedExtents_; - var extentsToLoad = this.loadingStrategy_(extent, resolution); + var extentsToLoad = this.strategy_(extent, resolution); var i, ii; for (i = 0, ii = extentsToLoad.length; i < ii; ++i) { var extentToLoad = extentsToLoad[i]; From a31ad69ec4c0cf530a5f52aad9ada649ea390204 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 25 Mar 2014 16:50:16 +0100 Subject: [PATCH 16/28] Make tile URL functions more general --- src/ol/source/bingmapssource.js | 4 ++-- src/ol/tileurlfunction.js | 19 ++++++------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/ol/source/bingmapssource.js b/src/ol/source/bingmapssource.js index edc223891a..fa93ddb4d5 100644 --- a/src/ol/source/bingmapssource.js +++ b/src/ol/source/bingmapssource.js @@ -91,6 +91,7 @@ ol.source.BingMaps.prototype.handleImageryMetadataResponse = this.tileGrid = tileGrid; var culture = this.culture_; + var sourceProjection = this.getProjection(); this.tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform( tileGrid.createTileCoordTransform(), ol.TileUrlFunction.createFromTileUrlFunctions( @@ -102,7 +103,6 @@ ol.source.BingMaps.prototype.handleImageryMetadataResponse = .replace('{culture}', culture); return ( /** - * @this {ol.source.BingMaps} * @param {ol.TileCoord} tileCoord Tile coordinate. * @param {number} pixelRatio Pixel ratio. * @param {ol.proj.Projection} projection Projection. @@ -110,7 +110,7 @@ ol.source.BingMaps.prototype.handleImageryMetadataResponse = */ function(tileCoord, pixelRatio, projection) { goog.asserts.assert(ol.proj.equivalent( - projection, this.getProjection())); + projection, sourceProjection)); if (goog.isNull(tileCoord)) { return undefined; } else { diff --git a/src/ol/tileurlfunction.js b/src/ol/tileurlfunction.js index 0626f0ec80..f99bfbcee2 100644 --- a/src/ol/tileurlfunction.js +++ b/src/ol/tileurlfunction.js @@ -10,11 +10,10 @@ goog.require('ol.TileCoord'); * A function that takes an {@link ol.TileCoord} for the tile coordinate, * a `{number}` representing the pixel ratio and an {@link ol.proj.Projection} * for the projection as arguments and returns a `{string}` or - * undefined representing the tile URL. The this keyword inside the function - * references the {@link ol.source.TileImage}. + * undefined representing the tile URL. * - * @typedef {function(this: ol.source.TileImage, ol.TileCoord, - * number, ol.proj.Projection): (string|undefined)} + * @typedef {function(ol.TileCoord, number, + * ol.proj.Projection): (string|undefined)} * @todo stability experimental */ ol.TileUrlFunctionType; @@ -34,7 +33,6 @@ ol.TileCoordTransformType; ol.TileUrlFunction.createFromTemplate = function(template) { return ( /** - * @this {ol.source.TileImage} * @param {ol.TileCoord} tileCoord Tile Coordinate. * @param {number} pixelRatio Pixel ratio. * @param {ol.proj.Projection} projection Projection. @@ -72,7 +70,6 @@ ol.TileUrlFunction.createFromTileUrlFunctions = function(tileUrlFunctions) { } return ( /** - * @this {ol.source.TileImage} * @param {ol.TileCoord} tileCoord Tile Coordinate. * @param {number} pixelRatio Pixel ratio. * @param {ol.proj.Projection} projection Projection. @@ -84,15 +81,13 @@ ol.TileUrlFunction.createFromTileUrlFunctions = function(tileUrlFunctions) { } else { var index = goog.math.modulo(tileCoord.hash(), tileUrlFunctions.length); - return tileUrlFunctions[index].call( - this, tileCoord, pixelRatio, projection); + return tileUrlFunctions[index](tileCoord, pixelRatio, projection); } }); }; /** - * @this {ol.source.TileImage} * @param {ol.TileCoord} tileCoord Tile coordinate. * @param {number} pixelRatio Pixel ratio. * @param {ol.proj.Projection} projection Projection. @@ -114,7 +109,6 @@ ol.TileUrlFunction.withTileCoordTransform = var tmpTileCoord = new ol.TileCoord(0, 0, 0); return ( /** - * @this {ol.source.TileImage} * @param {ol.TileCoord} tileCoord Tile Coordinate. * @param {number} pixelRatio Pixel ratio. * @param {ol.proj.Projection} projection Projection. @@ -124,9 +118,8 @@ ol.TileUrlFunction.withTileCoordTransform = if (goog.isNull(tileCoord)) { return undefined; } else { - return tileUrlFunction.call( - this, - transformFn.call(this, tileCoord, projection, tmpTileCoord), + return tileUrlFunction( + transformFn(tileCoord, projection, tmpTileCoord), pixelRatio, projection); } From 4a484a7ad37217df09ce4ed86b8549bbd01c839f Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 25 Mar 2014 16:51:26 +0100 Subject: [PATCH 17/28] Separate out feature reading and feature adding --- examples/vector-osm.js | 2 +- src/ol/source/formatvectorsource.js | 101 ++++++++++++++-------------- src/ol/source/staticvectorsource.js | 30 +++++++-- 3 files changed, 73 insertions(+), 60 deletions(-) diff --git a/examples/vector-osm.js b/examples/vector-osm.js index 8dd778508b..5834ef230e 100644 --- a/examples/vector-osm.js +++ b/examples/vector-osm.js @@ -95,7 +95,7 @@ var vectorSource = new ol.source.ServerVector({ var url = 'http://overpass-api.de/api/xapi?map?bbox=' + epsg4326Extent.join(','); $.ajax(url).then(function(response) { - vectorSource.readFeatures(response); + vectorSource.addFeatures(vectorSource.readFeatures(response)); }); }, strategy: ol.loadingstrategy.createTile(new ol.tilegrid.XYZ({ diff --git a/src/ol/source/formatvectorsource.js b/src/ol/source/formatvectorsource.js index cb7d08dfb9..3b3ad39fd6 100644 --- a/src/ol/source/formatvectorsource.js +++ b/src/ol/source/formatvectorsource.js @@ -40,62 +40,18 @@ ol.source.FormatVector = function(options) { */ this.format = options.format; - /** - * @protected - * @type {function(Event)} - */ - this.handleXhrIo = goog.bind(this.handleXhrIo_, this); - }; goog.inherits(ol.source.FormatVector, ol.source.Vector); -/** - * @param {Event} event Event. - * @private - */ -ol.source.FormatVector.prototype.handleXhrIo_ = function(event) { - var xhrIo = event.target; - goog.asserts.assertInstanceof(xhrIo, 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.BrowserFeature.HAS_ARRAY_BUFFER) { - source = xhrIo.getResponse(); - goog.asserts.assertInstanceof(source, 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.load(xhrIo.getResponseText()); - } - } else { - goog.asserts.fail(); - } - if (goog.isDefAndNotNull(source)) { - this.readFeatures(source); - } else { - this.setState(ol.source.State.ERROR); - goog.asserts.fail(); - } - } else { - this.setState(ol.source.State.ERROR); - } - goog.dispose(xhrIo); -}; - - /** * @param {goog.Uri|string} url URL. + * @param {function(this: T, Array.)} callback Callback. + * @param {T} thisArg Value to use as `this` when executing `callback`. + * @template T */ -ol.source.FormatVector.prototype.loadFeaturesFromURL = function(url) { +ol.source.FormatVector.prototype.loadFeaturesFromURL = + function(url, callback, thisArg) { var xhrIo = new goog.net.XhrIo(); var type = this.format.getType(); var responseType; @@ -107,13 +63,55 @@ ol.source.FormatVector.prototype.loadFeaturesFromURL = function(url) { responseType = goog.net.XhrIo.ResponseType.TEXT; } xhrIo.setResponseType(responseType); - goog.events.listen(xhrIo, goog.net.EventType.COMPLETE, this.handleXhrIo); + 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); + if (xhrIo.isSuccess()) { + var type = this.format.getType(); + /** @type {ArrayBuffer|Document|Node|Object|string|undefined} */ + var source; + if (type == ol.format.FormatType.BINARY && + ol.BrowserFeature.HAS_ARRAY_BUFFER) { + source = xhrIo.getResponse(); + goog.asserts.assertInstanceof(source, 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.load(xhrIo.getResponseText()); + } + } else { + goog.asserts.fail(); + } + if (goog.isDefAndNotNull(source)) { + callback.call(thisArg, this.readFeatures(source)); + } else { + this.setState(ol.source.State.ERROR); + goog.asserts.fail(); + } + } else { + this.setState(ol.source.State.ERROR); + } + goog.dispose(xhrIo); + }, false, this); xhrIo.send(url); }; /** * @param {ArrayBuffer|Document|Node|Object|string} source Source. + * @return {Array.} Features. */ ol.source.FormatVector.prototype.readFeatures = function(source) { var format = this.format; @@ -133,6 +131,5 @@ ol.source.FormatVector.prototype.readFeatures = function(source) { } } } - this.addFeaturesInternal(features); - this.setState(ol.source.State.READY); + return features; }; diff --git a/src/ol/source/staticvectorsource.js b/src/ol/source/staticvectorsource.js index e13de2eef4..6ebc8ad278 100644 --- a/src/ol/source/staticvectorsource.js +++ b/src/ol/source/staticvectorsource.js @@ -23,35 +23,51 @@ ol.source.StaticVector = function(options) { }); if (goog.isDef(options.arrayBuffer)) { - this.readFeatures(options.arrayBuffer); + this.addFeaturesInternal(this.readFeatures(options.arrayBuffer)); } if (goog.isDef(options.doc)) { - this.readFeatures(options.doc); + this.addFeaturesInternal(this.readFeatures(options.doc)); } if (goog.isDef(options.node)) { - this.readFeatures(options.node); + this.addFeaturesInternal(this.readFeatures(options.node)); } if (goog.isDef(options.object)) { - this.readFeatures(options.object); + this.addFeaturesInternal(this.readFeatures(options.object)); } if (goog.isDef(options.text)) { - this.readFeatures(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.loadFeaturesFromURL(options.url, + /** + * @param {Array.} features Features. + * @this {ol.source.StaticVector} + */ + function(features) { + this.addFeaturesInternal(features); + this.setState(ol.source.State.READY); + }, 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.loadFeaturesFromURL(urls[i], + /** + * @param {Array.} features Features. + * @this {ol.source.StaticVector} + */ + function(features) { + this.addFeaturesInternal(features); + this.setState(ol.source.State.READY); + }, this); } } } From 683483f8a49fead4b6c4e03c1ddbca5cb0371db0 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 25 Mar 2014 16:51:44 +0100 Subject: [PATCH 18/28] Add ol.source.TileVector --- src/objectliterals.jsdoc | 20 ++ src/ol/source/tilevectorsource.exports | 1 + src/ol/source/tilevectorsource.js | 284 +++++++++++++++++++++++++ 3 files changed, 305 insertions(+) create mode 100644 src/ol/source/tilevectorsource.exports create mode 100644 src/ol/source/tilevectorsource.js diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index c9410a7a5d..422a3ded51 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -707,6 +707,26 @@ * @property {Array.|undefined} urls URLs. */ +/** + * @typedef {Object} olx.source.TileVectorOptions + * @property {Array.|undefined} attributions Attributions. + * @property {ol.proj.ProjectionLike} defaultProjection Default projection. + * @property {ol.Extent|undefined} extent Extent. + * @property {string|undefined} logo Logo. + * @property {GeoJSONObject|undefined} object Object. + * @property {ol.proj.ProjectionLike} projection Destination projection. If + * provided, features will be transformed to this projection. If not + * provided, features will not be transformed. + * @property {ol.tilegrid.TileGrid} tileGrid Tile grid. + * @property {ol.TileUrlFunctionType|undefined} tileUrlFunction Optional + * function to get tile URL given a tile coordinate and the projection. + * Required if url or urls are not provided. + * @property {string|undefined} url URL template. Must include `{x}`, `{y}`, + * and `{z}` placeholders. + * @property {Array.|undefined} urls An array of URL templates. + * @property {number} z Z value of tiles to request. FIXME remove! + */ + /** * @typedef {Object} olx.source.TopoJSONOptions * @property {Array.|undefined} attributions Attributions. diff --git a/src/ol/source/tilevectorsource.exports b/src/ol/source/tilevectorsource.exports new file mode 100644 index 0000000000..aca6bdb3e8 --- /dev/null +++ b/src/ol/source/tilevectorsource.exports @@ -0,0 +1 @@ +@exportSymbol ol.source.TileVector diff --git a/src/ol/source/tilevectorsource.js b/src/ol/source/tilevectorsource.js new file mode 100644 index 0000000000..f79b7686e1 --- /dev/null +++ b/src/ol/source/tilevectorsource.js @@ -0,0 +1,284 @@ +// FIXME implement getClosestFeatureToCoordinate +// FIXME implement getExtent +// FIXME handle different Zs + +goog.provide('ol.source.TileVector'); + +goog.require('goog.array'); +goog.require('goog.object'); +goog.require('ol.TileCoord'); +goog.require('ol.TileUrlFunction'); +goog.require('ol.source.FormatVector'); +goog.require('ol.source.State'); +goog.require('ol.tilegrid.TileGrid'); + + + +/** + * @constructor + * @extends {ol.source.FormatVector} + * @param {olx.source.TileVectorOptions} options Options. + */ +ol.source.TileVector = function(options) { + + goog.base(this, { + attributions: options.attributions, + extent: options.extent, + format: options.format, + logo: options.logo, + projection: options.projection + }); + + var tileGrid = options.tileGrid; + var z = options.z; + + /** + * @private + * @type {number} + */ + this.resolution_ = tileGrid.getResolution(z); + + /** + * @private + * @type {ol.tilegrid.TileGrid} + */ + this.tileGrid_ = options.tileGrid; + + /** + * @private + * @type {ol.TileUrlFunctionType} + */ + this.tileUrlFunction_ = ol.TileUrlFunction.nullTileUrlFunction; + + /** + * @private + * @type {ol.TileCoordTransformType} + */ + this.tileCoordTransform_ = tileGrid.createTileCoordTransform({ + extent: options.extent + }); + + /** + * @private + * @type {Object.>} + */ + this.tiles_ = {}; + + /** + * @private + * @type {number} + */ + this.z_ = z; + + if (goog.isDef(options.tileUrlFunction)) { + this.setTileUrlFunction(options.tileUrlFunction); + } else if (goog.isDef(options.urls)) { + this.setUrls(options.urls); + } else if (goog.isDef(options.url)) { + this.setUrl(options.url); + } + +}; +goog.inherits(ol.source.TileVector, ol.source.FormatVector); + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.addFeature = goog.abstractMethod; + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.addFeatures = goog.abstractMethod; + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.clear = function() { + goog.object.clear(this.tiles_); +}; + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.forEachFeature = function(f, opt_this) { + var tiles = this.tiles_; + var tileKey; + for (tileKey in tiles) { + var features = tiles[tileKey]; + var i, ii; + for (i = 0, ii = features.length; i < ii; ++i) { + var result = f.call(opt_this, features[i]); + if (result) { + return result; + } + } + } + return undefined; +}; + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.forEachFeatureInExtent = + function(extent, f, opt_this) { + var resolution = this.resolution_; + var tileGrid = this.tileGrid_; + var tiles = this.tiles_; + var z = this.z_; + var tileRange = + tileGrid.getTileRangeForExtentAndResolution(extent, resolution); + var x, y; + for (x = tileRange.minX; x <= tileRange.maxX; ++x) { + for (y = tileRange.minY; y <= tileRange.maxY; ++y) { + var tileKey = this.getTileKeyZXY_(z, x, y); + var features = tiles[tileKey]; + if (goog.isDef(features)) { + var i, ii; + for (i = 0, ii = features.length; i < ii; ++i) { + var result = f.call(opt_this, features[i]); + if (result) { + return result; + } + } + } + } + } + return undefined; +}; + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.getClosestFeatureToCoordinate = + goog.abstractMethod; + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.getExtent = goog.abstractMethod; + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.getFeatures = function() { + var tiles = this.tiles_; + var features = []; + var tileKey; + for (tileKey in tiles) { + goog.array.extend(features, tiles[tileKey]); + } + return features; +}; + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.getFeaturesInExtent = function(extent) { + var features = []; + this.forEachFeatureInExtent(extent, + /** + * @param {ol.Feature} feature Feature. + */ + function(feature) { + features.push(feature); + }); + return features; +}; + + +/** + * @param {number} z Z. + * @param {number} x X. + * @param {number} y Y. + * @private + * @return {string} Tile key. + */ +ol.source.TileVector.prototype.getTileKeyZXY_ = function(z, x, y) { + return z + '/' + x + '/' + y; +}; + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.loadFeatures = + function(extent, resolution, projection) { + // FIXME should use resolution argument rather than this.resolution_ + var tileCoordTransform = this.tileCoordTransform_; + var tileGrid = this.tileGrid_; + var tileUrlFunction = this.tileUrlFunction_; + var tiles = this.tiles_; + var z = this.z_; + var tileRange = + tileGrid.getTileRangeForExtentAndResolution(extent, this.resolution_); + var tileCoord = new ol.TileCoord(z, 0, 0); + var x, y; + for (x = tileRange.minX; x <= tileRange.maxX; ++x) { + for (y = tileRange.minY; y <= tileRange.maxY; ++y) { + var tileKey = this.getTileKeyZXY_(z, x, y); + if (!(tileKey in tiles)) { + tileCoord.z = z; + tileCoord.x = x; + tileCoord.y = y; + tileCoordTransform(tileCoord, projection, tileCoord); + var url = tileUrlFunction(tileCoord, 1, projection); + if (goog.isDef(url)) { + tiles[tileKey] = []; + this.loadFeaturesFromURL(url, goog.partial( + /** + * @param {string} tileKey Tile key. + * @param {Array.} features Features. + * @this {ol.source.TileVector} + */ + function(tileKey, features) { + tiles[tileKey] = features; + this.setState(ol.source.State.READY); + }, tileKey), this); + } + } + } + } +}; + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.removeFeature = goog.abstractMethod; + + +/** + * @param {ol.TileUrlFunctionType} tileUrlFunction Tile URL function. + */ +ol.source.TileVector.prototype.setTileUrlFunction = function(tileUrlFunction) { + this.tileUrlFunction_ = tileUrlFunction; + this.dispatchChangeEvent(); +}; + + +/** + * @param {string} url URL. + * @todo stability experimental + */ +ol.source.TileVector.prototype.setUrl = function(url) { + this.setTileUrlFunction(ol.TileUrlFunction.createFromTemplates( + ol.TileUrlFunction.expandUrl(url))); +}; + + +/** + * @param {Array.} urls URLs. + */ +ol.source.TileVector.prototype.setUrls = function(urls) { + this.setTileUrlFunction(ol.TileUrlFunction.createFromTemplates(urls)); +}; From 8986ea1ef9dc9de8faa8d88a616abd154060159d Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 25 Mar 2014 16:52:04 +0100 Subject: [PATCH 19/28] Add tile-vector example --- examples/tile-vector.html | 51 +++++++++++++++++++++++++++++++++++++++ examples/tile-vector.js | 42 ++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 examples/tile-vector.html create mode 100644 examples/tile-vector.js diff --git a/examples/tile-vector.html b/examples/tile-vector.html new file mode 100644 index 0000000000..86c5d6a579 --- /dev/null +++ b/examples/tile-vector.html @@ -0,0 +1,51 @@ + + + + + + + + + + + Tile vector example + + + + + +
+ +
+
+
+
+
+ +
+ +
+

Tile vector example

+

Example of vector tiles.

+
+

See the tile-vector.js source to see how this is done.

+
+
tile-vector, openstreetmap
+
+ +
+ +
+ + + + + + + diff --git a/examples/tile-vector.js b/examples/tile-vector.js new file mode 100644 index 0000000000..d80fef1e31 --- /dev/null +++ b/examples/tile-vector.js @@ -0,0 +1,42 @@ +goog.require('ol.Map'); +goog.require('ol.View2D'); +goog.require('ol.format.GeoJSON'); +goog.require('ol.layer.Tile'); +goog.require('ol.layer.Vector'); +goog.require('ol.proj'); +goog.require('ol.source.Stamen'); +goog.require('ol.source.TileVector'); +goog.require('ol.tilegrid.XYZ'); + +var vectorSource = new ol.source.TileVector({ + format: new ol.format.GeoJSON({ + defaultProjection: 'EPSG:4326' + }), + projection: 'EPSG:3857', + tileGrid: new ol.tilegrid.XYZ({ + maxZoom: 19 + }), + url: 'http://www.somebits.com:8001/rivers/{z}/{x}/{y}.json', + z: 11 +}); + +var vector = new ol.layer.Vector({ + source: vectorSource +}); + +var raster = new ol.layer.Tile({ + source: new ol.source.Stamen({ + layer: 'terrain' + }) +}); + +var map = new ol.Map({ + layers: [raster, vector], + renderer: 'canvas', + target: document.getElementById('map'), + view: new ol.View2D({ + center: ol.proj.transform([-120.976, 37.958], 'EPSG:4326', 'EPSG:3857'), + maxZoom: 19, + zoom: 11 + }) +}); From fe216e3da132939f2e58d7cd03fd913efc6bd083 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Tue, 25 Mar 2014 17:08:35 +0100 Subject: [PATCH 20/28] Better vector style in tile-vector example --- examples/tile-vector.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/examples/tile-vector.js b/examples/tile-vector.js index d80fef1e31..6822562e53 100644 --- a/examples/tile-vector.js +++ b/examples/tile-vector.js @@ -6,6 +6,8 @@ goog.require('ol.layer.Vector'); goog.require('ol.proj'); goog.require('ol.source.Stamen'); goog.require('ol.source.TileVector'); +goog.require('ol.style.Stroke'); +goog.require('ol.style.Style'); goog.require('ol.tilegrid.XYZ'); var vectorSource = new ol.source.TileVector({ @@ -20,8 +22,24 @@ var vectorSource = new ol.source.TileVector({ z: 11 }); +var styleCache = {}; + var vector = new ol.layer.Vector({ - source: vectorSource + source: vectorSource, + style: function(feature, resolution) { + var strahler = feature.get('strahler'); + var styleArray = styleCache[strahler]; + if (!styleArray) { + styleArray = [new ol.style.Style({ + stroke: new ol.style.Stroke({ + color: '#29439c', + width: strahler + }) + })]; + styleCache[strahler] = styleArray; + } + return styleArray; + } }); var raster = new ol.layer.Tile({ From 3a8504b7995a1190ed05983ffd4635b5bceb6e93 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 6 Mar 2014 14:57:56 +0100 Subject: [PATCH 21/28] Add ol.source.Vector#forEachFeatureInExtentAtResolution --- src/ol/source/vectorsource.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ol/source/vectorsource.js b/src/ol/source/vectorsource.js index 6c5659ab3d..94ab64349a 100644 --- a/src/ol/source/vectorsource.js +++ b/src/ol/source/vectorsource.js @@ -208,6 +208,21 @@ ol.source.Vector.prototype.forEachFeatureInExtent = }; +/** + * @param {ol.Extent} extent Extent. + * @param {number} resolution Resolution. + * @param {function(this: T, ol.Feature): S} f Callback. + * @param {T=} opt_this The object to use as `this` in `f`. + * @return {S|undefined} + * @template T,S + * @todo stability experimental + */ +ol.source.Vector.prototype.forEachFeatureInExtentAtResolution = + function(extent, resolution, f, opt_this) { + return this.forEachFeatureInExtent(extent, f, opt_this); +}; + + /** * @return {Array.} Features. * @todo stability experimental From ed586bad3969018f67f7b7c1458872be8aac96a8 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 6 Mar 2014 15:01:27 +0100 Subject: [PATCH 22/28] Use forEachFeatureInExtentAtResolution in ol.renderer.canvas.VectorLayer --- src/ol/renderer/canvas/canvasvectorlayerrenderer.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js index a30659d894..aa148b4d77 100644 --- a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js +++ b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js @@ -222,11 +222,20 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = this.dirty_ = this.dirty_ || dirty; }; if (!goog.isNull(vectorLayerRenderOrder)) { - var features = vectorSource.getFeaturesInExtent(extent); + /** @type {Array.} */ + var features = []; + vectorSource.forEachFeatureInExtentAtResolution(extent, resolution, + /** + * @param {ol.Feature} feature Feature. + */ + function(feature) { + features.push(feature); + }, this); goog.array.sort(features, vectorLayerRenderOrder); goog.array.forEach(features, renderFeature, this); } else { - vectorSource.forEachFeatureInExtent(extent, renderFeature, this); + vectorSource.forEachFeatureInExtentAtResolution( + extent, resolution, renderFeature, this); } replayGroup.finish(); From 96b7700d6351bcf1a486039c84e84ba608dfaee2 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 6 Mar 2014 15:01:40 +0100 Subject: [PATCH 23/28] Use forEachFeatureInExtentAtResolution in ol.source.ImageVector --- src/ol/source/imagevectorsource.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol/source/imagevectorsource.js b/src/ol/source/imagevectorsource.js index f7bf16b53c..7f27f19ce6 100644 --- a/src/ol/source/imagevectorsource.js +++ b/src/ol/source/imagevectorsource.js @@ -106,7 +106,7 @@ ol.source.ImageVector.prototype.canvasFunctionInternal_ = resolution); var loading = false; - this.source_.forEachFeatureInExtent(extent, + this.source_.forEachFeatureInExtentAtResolution(extent, resolution, /** * @param {ol.Feature} feature Feature. */ From f13debbbc96ab213f2c42c93f805c7dfca07da2e Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Wed, 26 Mar 2014 11:48:00 +0100 Subject: [PATCH 24/28] Load vector tiles for current resolution --- examples/tile-vector.js | 3 +- src/objectliterals.jsdoc | 1 - src/ol/source/tilevectorsource.js | 67 +++++++------------------------ 3 files changed, 15 insertions(+), 56 deletions(-) diff --git a/examples/tile-vector.js b/examples/tile-vector.js index 6822562e53..84e1b9e17b 100644 --- a/examples/tile-vector.js +++ b/examples/tile-vector.js @@ -18,8 +18,7 @@ var vectorSource = new ol.source.TileVector({ tileGrid: new ol.tilegrid.XYZ({ maxZoom: 19 }), - url: 'http://www.somebits.com:8001/rivers/{z}/{x}/{y}.json', - z: 11 + url: 'http://www.somebits.com:8001/rivers/{z}/{x}/{y}.json' }); var styleCache = {}; diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 422a3ded51..f3b1a22684 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -724,7 +724,6 @@ * @property {string|undefined} url URL template. Must include `{x}`, `{y}`, * and `{z}` placeholders. * @property {Array.|undefined} urls An array of URL templates. - * @property {number} z Z value of tiles to request. FIXME remove! */ /** diff --git a/src/ol/source/tilevectorsource.js b/src/ol/source/tilevectorsource.js index f79b7686e1..cf64f35430 100644 --- a/src/ol/source/tilevectorsource.js +++ b/src/ol/source/tilevectorsource.js @@ -1,7 +1,3 @@ -// FIXME implement getClosestFeatureToCoordinate -// FIXME implement getExtent -// FIXME handle different Zs - goog.provide('ol.source.TileVector'); goog.require('goog.array'); @@ -30,13 +26,6 @@ ol.source.TileVector = function(options) { }); var tileGrid = options.tileGrid; - var z = options.z; - - /** - * @private - * @type {number} - */ - this.resolution_ = tileGrid.getResolution(z); /** * @private @@ -64,12 +53,6 @@ ol.source.TileVector = function(options) { */ this.tiles_ = {}; - /** - * @private - * @type {number} - */ - this.z_ = z; - if (goog.isDef(options.tileUrlFunction)) { this.setTileUrlFunction(options.tileUrlFunction); } else if (goog.isDef(options.urls)) { @@ -105,34 +88,24 @@ ol.source.TileVector.prototype.clear = function() { /** * @inheritDoc */ -ol.source.TileVector.prototype.forEachFeature = function(f, opt_this) { - var tiles = this.tiles_; - var tileKey; - for (tileKey in tiles) { - var features = tiles[tileKey]; - var i, ii; - for (i = 0, ii = features.length; i < ii; ++i) { - var result = f.call(opt_this, features[i]); - if (result) { - return result; - } - } - } - return undefined; -}; +ol.source.TileVector.prototype.forEachFeature = goog.abstractMethod; /** * @inheritDoc */ -ol.source.TileVector.prototype.forEachFeatureInExtent = - function(extent, f, opt_this) { - var resolution = this.resolution_; +ol.source.TileVector.prototype.forEachFeatureInExtent = goog.abstractMethod; + + +/** + * @inheritDoc + */ +ol.source.TileVector.prototype.forEachFeatureInExtentAtResolution = + function(extent, resolution, f, opt_this) { var tileGrid = this.tileGrid_; var tiles = this.tiles_; - var z = this.z_; - var tileRange = - tileGrid.getTileRangeForExtentAndResolution(extent, resolution); + var z = tileGrid.getZForResolution(resolution); + var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); var x, y; for (x = tileRange.minX; x <= tileRange.maxX; ++x) { for (y = tileRange.minY; y <= tileRange.maxY; ++y) { @@ -183,17 +156,7 @@ ol.source.TileVector.prototype.getFeatures = function() { /** * @inheritDoc */ -ol.source.TileVector.prototype.getFeaturesInExtent = function(extent) { - var features = []; - this.forEachFeatureInExtent(extent, - /** - * @param {ol.Feature} feature Feature. - */ - function(feature) { - features.push(feature); - }); - return features; -}; +ol.source.TileVector.prototype.getFeaturesInExtent = goog.abstractMethod; /** @@ -213,14 +176,12 @@ ol.source.TileVector.prototype.getTileKeyZXY_ = function(z, x, y) { */ ol.source.TileVector.prototype.loadFeatures = function(extent, resolution, projection) { - // FIXME should use resolution argument rather than this.resolution_ var tileCoordTransform = this.tileCoordTransform_; var tileGrid = this.tileGrid_; var tileUrlFunction = this.tileUrlFunction_; var tiles = this.tiles_; - var z = this.z_; - var tileRange = - tileGrid.getTileRangeForExtentAndResolution(extent, this.resolution_); + var z = tileGrid.getZForResolution(resolution); + var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); var tileCoord = new ol.TileCoord(z, 0, 0); var x, y; for (x = tileRange.minX; x <= tileRange.maxX; ++x) { From a68d9f22993ca79b41d7f36f60ec3621ce8bbafa Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Wed, 26 Mar 2014 12:09:56 +0100 Subject: [PATCH 25/28] Use openstreetmap.us vector tiles in tile-vector example --- examples/tile-vector.html | 2 +- examples/tile-vector.js | 61 ++++++++++++++++++++++----------------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/examples/tile-vector.html b/examples/tile-vector.html index 86c5d6a579..7b67896375 100644 --- a/examples/tile-vector.html +++ b/examples/tile-vector.html @@ -32,7 +32,7 @@

Tile vector example

-

Example of vector tiles.

+

Example of vector tiles from openstreetmap.us.

See the tile-vector.js source to see how this is done.

diff --git a/examples/tile-vector.js b/examples/tile-vector.js index 84e1b9e17b..b9e594b791 100644 --- a/examples/tile-vector.js +++ b/examples/tile-vector.js @@ -1,10 +1,8 @@ goog.require('ol.Map'); goog.require('ol.View2D'); goog.require('ol.format.GeoJSON'); -goog.require('ol.layer.Tile'); goog.require('ol.layer.Vector'); goog.require('ol.proj'); -goog.require('ol.source.Stamen'); goog.require('ol.source.TileVector'); goog.require('ol.style.Stroke'); goog.require('ol.style.Style'); @@ -18,42 +16,53 @@ var vectorSource = new ol.source.TileVector({ tileGrid: new ol.tilegrid.XYZ({ maxZoom: 19 }), - url: 'http://www.somebits.com:8001/rivers/{z}/{x}/{y}.json' + url: 'http://{a-c}.tile.openstreetmap.us/vectiles-highroad/{z}/{x}/{y}.json' }); var styleCache = {}; +var styleFunction = function(feature, resolution) { + var kind = feature.get('kind'); + var railway = feature.get('railway'); + var sort_key = feature.get('sort_key'); + var styleKey = kind + '/' + railway + '/' + sort_key; + var styleArray = styleCache[styleKey]; + if (!styleArray) { + var color, width; + if (railway) { + color = '#7de'; + width = 1; + } else { + color = { + 'major_road': '#776', + 'minor_road': '#ccb', + 'highway': '#f39' + }[kind]; + width = kind == 'highway' ? 1.5 : 1; + } + styleArray = [new ol.style.Style({ + stroke: new ol.style.Stroke({ + color: color, + width: width + }), + zIndex: sort_key + })]; + styleCache[styleKey] = styleArray; + } + return styleArray; +}; var vector = new ol.layer.Vector({ source: vectorSource, - style: function(feature, resolution) { - var strahler = feature.get('strahler'); - var styleArray = styleCache[strahler]; - if (!styleArray) { - styleArray = [new ol.style.Style({ - stroke: new ol.style.Stroke({ - color: '#29439c', - width: strahler - }) - })]; - styleCache[strahler] = styleArray; - } - return styleArray; - } -}); - -var raster = new ol.layer.Tile({ - source: new ol.source.Stamen({ - layer: 'terrain' - }) + style: styleFunction }); var map = new ol.Map({ - layers: [raster, vector], + layers: [vector], renderer: 'canvas', target: document.getElementById('map'), view: new ol.View2D({ - center: ol.proj.transform([-120.976, 37.958], 'EPSG:4326', 'EPSG:3857'), + center: ol.proj.transform([-74.0064, 40.7142], 'EPSG:4326', 'EPSG:3857'), maxZoom: 19, - zoom: 11 + zoom: 14 }) }); From d3a13a254ce93abb9ff85c0ad72e90f869ae7038 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Wed, 26 Mar 2014 13:26:04 +0100 Subject: [PATCH 26/28] Use TopoJSON in tile-vector example --- examples/tile-vector.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/tile-vector.js b/examples/tile-vector.js index b9e594b791..68048e5636 100644 --- a/examples/tile-vector.js +++ b/examples/tile-vector.js @@ -1,6 +1,6 @@ goog.require('ol.Map'); goog.require('ol.View2D'); -goog.require('ol.format.GeoJSON'); +goog.require('ol.format.TopoJSON'); goog.require('ol.layer.Vector'); goog.require('ol.proj'); goog.require('ol.source.TileVector'); @@ -9,14 +9,15 @@ goog.require('ol.style.Style'); goog.require('ol.tilegrid.XYZ'); var vectorSource = new ol.source.TileVector({ - format: new ol.format.GeoJSON({ + format: new ol.format.TopoJSON({ defaultProjection: 'EPSG:4326' }), projection: 'EPSG:3857', tileGrid: new ol.tilegrid.XYZ({ maxZoom: 19 }), - url: 'http://{a-c}.tile.openstreetmap.us/vectiles-highroad/{z}/{x}/{y}.json' + url: 'http://{a-c}.tile.openstreetmap.us/' + + 'vectiles-highroad/{z}/{x}/{y}.topojson' }); var styleCache = {}; From 3a462f7076bbeb3b18cbd4fdd2627d42c8a60b87 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Wed, 26 Mar 2014 13:38:13 +0100 Subject: [PATCH 27/28] Add a polygon layer and tweak the style of the tile-vector example --- examples/tile-vector.html | 2 +- examples/tile-vector.js | 102 ++++++++++++++++++++++---------------- 2 files changed, 60 insertions(+), 44 deletions(-) diff --git a/examples/tile-vector.html b/examples/tile-vector.html index 7b67896375..e6b7167c85 100644 --- a/examples/tile-vector.html +++ b/examples/tile-vector.html @@ -24,7 +24,7 @@
-
+
diff --git a/examples/tile-vector.js b/examples/tile-vector.js index 68048e5636..d980e62bbc 100644 --- a/examples/tile-vector.js +++ b/examples/tile-vector.js @@ -4,61 +4,77 @@ goog.require('ol.format.TopoJSON'); goog.require('ol.layer.Vector'); goog.require('ol.proj'); goog.require('ol.source.TileVector'); +goog.require('ol.style.Fill'); goog.require('ol.style.Stroke'); goog.require('ol.style.Style'); goog.require('ol.tilegrid.XYZ'); -var vectorSource = new ol.source.TileVector({ - format: new ol.format.TopoJSON({ - defaultProjection: 'EPSG:4326' +var waterLayer = new ol.layer.Vector({ + source: new ol.source.TileVector({ + format: new ol.format.TopoJSON({ + defaultProjection: 'EPSG:4326' + }), + projection: 'EPSG:3857', + tileGrid: new ol.tilegrid.XYZ({ + maxZoom: 19 + }), + url: 'http://{a-c}.tile.openstreetmap.us/' + + 'vectiles-water-areas/{z}/{x}/{y}.topojson' }), - projection: 'EPSG:3857', - tileGrid: new ol.tilegrid.XYZ({ - maxZoom: 19 - }), - url: 'http://{a-c}.tile.openstreetmap.us/' + - 'vectiles-highroad/{z}/{x}/{y}.topojson' + style: new ol.style.Style({ + fill: new ol.style.Fill({ + color: '#9db9e8' + }) + }) }); -var styleCache = {}; -var styleFunction = function(feature, resolution) { - var kind = feature.get('kind'); - var railway = feature.get('railway'); - var sort_key = feature.get('sort_key'); - var styleKey = kind + '/' + railway + '/' + sort_key; - var styleArray = styleCache[styleKey]; - if (!styleArray) { - var color, width; - if (railway) { - color = '#7de'; - width = 1; - } else { - color = { - 'major_road': '#776', - 'minor_road': '#ccb', - 'highway': '#f39' - }[kind]; - width = kind == 'highway' ? 1.5 : 1; +var roadStyleCache = {}; +var roadLayer = new ol.layer.Vector({ + source: new ol.source.TileVector({ + format: new ol.format.TopoJSON({ + defaultProjection: 'EPSG:4326' + }), + projection: 'EPSG:3857', + tileGrid: new ol.tilegrid.XYZ({ + maxZoom: 19 + }), + url: 'http://{a-c}.tile.openstreetmap.us/' + + 'vectiles-highroad/{z}/{x}/{y}.topojson' + }), + style: function(feature, resolution) { + var kind = feature.get('kind'); + var railway = feature.get('railway'); + var sort_key = feature.get('sort_key'); + var styleKey = kind + '/' + railway + '/' + sort_key; + var styleArray = roadStyleCache[styleKey]; + if (!styleArray) { + var color, width; + if (railway) { + color = '#7de'; + width = 1; + } else { + color = { + 'major_road': '#776', + 'minor_road': '#ccb', + 'highway': '#f39' + }[kind]; + width = kind == 'highway' ? 1.5 : 1; + } + styleArray = [new ol.style.Style({ + stroke: new ol.style.Stroke({ + color: color, + width: width + }), + zIndex: sort_key + })]; + roadStyleCache[styleKey] = styleArray; } - styleArray = [new ol.style.Style({ - stroke: new ol.style.Stroke({ - color: color, - width: width - }), - zIndex: sort_key - })]; - styleCache[styleKey] = styleArray; + return styleArray; } - return styleArray; -}; - -var vector = new ol.layer.Vector({ - source: vectorSource, - style: styleFunction }); var map = new ol.Map({ - layers: [vector], + layers: [waterLayer, roadLayer], renderer: 'canvas', target: document.getElementById('map'), view: new ol.View2D({ From c155b70281ea36f36d357a752a1acf251b2c1783 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 3 Apr 2014 15:57:44 +0200 Subject: [PATCH 28/28] Export ol.source.ServerVector#readFeatures --- src/ol/source/servervectorsource.exports | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ol/source/servervectorsource.exports b/src/ol/source/servervectorsource.exports index 03a26a0698..8d0a5d6a63 100644 --- a/src/ol/source/servervectorsource.exports +++ b/src/ol/source/servervectorsource.exports @@ -1 +1,2 @@ @exportSymbol ol.source.ServerVector +@exportProperty ol.source.ServerVector.prototype.readFeatures