diff --git a/src/ol/proj/proj.js b/src/ol/proj/proj.js index 348432e087..ddcc57484f 100644 --- a/src/ol/proj/proj.js +++ b/src/ol/proj/proj.js @@ -120,9 +120,13 @@ ol.proj.Projection = function(options) { * @type {boolean} */ this.global_ = goog.isDef(options.global) ? options.global : false; - if (this.global_) { - goog.asserts.assert(!goog.isNull(this.extent_)); - } + + + /** + * @private + * @type {boolean} + */ + this.canWrapX_ = this.global_ && !goog.isNull(this.extent_); /** * @private @@ -175,6 +179,14 @@ ol.proj.Projection = function(options) { }; +/** + * @return {boolean} The projection is suitable for wrapping the x-axis + */ +ol.proj.Projection.prototype.canWrapX = function() { + return this.canWrapX_; +}; + + /** * Get the code for this projection, e.g. 'EPSG:4326'. * @return {string} Code. @@ -258,6 +270,7 @@ ol.proj.Projection.prototype.isGlobal = function() { */ ol.proj.Projection.prototype.setGlobal = function(global) { this.global_ = global; + this.canWrapX_ = global && !goog.isNull(this.extent_); }; @@ -284,6 +297,7 @@ ol.proj.Projection.prototype.setDefaultTileGrid = function(tileGrid) { */ ol.proj.Projection.prototype.setExtent = function(extent) { this.extent_ = extent; + this.canWrapX_ = this.global_ && !goog.isNull(extent); }; diff --git a/src/ol/renderer/canvas/canvasmaprenderer.js b/src/ol/renderer/canvas/canvasmaprenderer.js index 17c1d4fafe..3a15b7f199 100644 --- a/src/ol/renderer/canvas/canvasmaprenderer.js +++ b/src/ol/renderer/canvas/canvasmaprenderer.js @@ -108,7 +108,7 @@ ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ = var projectionExtent = projection.getExtent(); var resolution = viewState.resolution; var rotation = viewState.rotation; - var repeatReplay = (wrapX && projection.isGlobal() && + var repeatReplay = (wrapX && projection.canWrapX() && !ol.extent.containsExtent(projectionExtent, extent)); var skippedFeaturesHash = {}; diff --git a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js index 0479523352..5ecbec9901 100644 --- a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js +++ b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js @@ -110,7 +110,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = replayGroup.replay( replayContext, pixelRatio, transform, rotation, skippedFeatureUids); - if (vectorSource.getWrapX() && projection.isGlobal() && + if (vectorSource.getWrapX() && projection.canWrapX() && !ol.extent.containsExtent(projectionExtent, frameState.extent)) { var startX = extent[0]; var worldWidth = ol.extent.getWidth(projectionExtent); @@ -229,7 +229,7 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = vectorLayerRenderBuffer * resolution); var projectionExtent = viewState.projection.getExtent(); - if (vectorSource.getWrapX() && viewState.projection.isGlobal() && + if (vectorSource.getWrapX() && viewState.projection.canWrapX() && !ol.extent.containsExtent(projectionExtent, frameState.extent)) { // do not clip when the view crosses the -180° or 180° meridians extent[0] = projectionExtent[0]; diff --git a/src/ol/renderer/maprenderer.js b/src/ol/renderer/maprenderer.js index 295b3fc174..26145381ca 100644 --- a/src/ol/renderer/maprenderer.js +++ b/src/ol/renderer/maprenderer.js @@ -157,7 +157,7 @@ ol.renderer.Map.prototype.forEachFeatureAtCoordinate = var projection = viewState.projection; var translatedX; - if (projection.isGlobal()) { + if (projection.canWrapX()) { var projectionExtent = projection.getExtent(); var worldWidth = ol.extent.getWidth(projectionExtent); var x = coordinate[0]; diff --git a/test/spec/ol/proj/proj.test.js b/test/spec/ol/proj/proj.test.js index 1714236b0d..de7ba4935a 100644 --- a/test/spec/ol/proj/proj.test.js +++ b/test/spec/ol/proj/proj.test.js @@ -138,6 +138,46 @@ describe('ol.proj', function() { }); }); + describe('canWrapX()', function() { + + it('requires an extent for allowing wrapX', function() { + var proj = new ol.proj.Projection({ + code: 'foo', + global: true + }); + expect(proj.canWrapX()).to.be(false); + proj.setExtent([1, 2, 3, 4]); + expect(proj.canWrapX()).to.be(true); + proj = new ol.proj.Projection({ + code: 'foo', + global: true, + extent: [1, 2, 3, 4] + }); + expect(proj.canWrapX()).to.be(true); + proj.setExtent(null); + expect(proj.canWrapX()).to.be(false); + }); + + it('requires global to be true for allowing wrapX', function() { + var proj = new ol.proj.Projection({ + code: 'foo', + extent: [1, 2, 3, 4] + }); + expect(proj.canWrapX()).to.be(false); + proj.setGlobal(true); + expect(proj.canWrapX()).to.be(true); + proj = new ol.proj.Projection({ + code: 'foo', + global: true, + extent: [1, 2, 3, 4] + }); + expect(proj.canWrapX()).to.be(true); + proj.setGlobal(false); + expect(proj.canWrapX()).to.be(false); + }); + + }); + describe('transformExtent()', function() { it('transforms an extent given projection identifiers', function() {