diff --git a/src/ol/reproj/triangulation.js b/src/ol/reproj/triangulation.js index 374dd81988..da4655d0d1 100644 --- a/src/ol/reproj/triangulation.js +++ b/src/ol/reproj/triangulation.js @@ -1,6 +1,7 @@ goog.provide('ol.reproj.Triangulation'); goog.require('goog.array'); +goog.require('goog.asserts'); goog.require('goog.math'); goog.require('ol.extent'); goog.require('ol.proj'); @@ -89,10 +90,18 @@ ol.reproj.Triangulation = function(sourceProj, targetProj, targetExtent, ol.extent.getWidth(this.sourceProj_.getExtent())); /** - * @type {number} + * @type {?number} * @private */ - this.sourceWorldWidth_ = ol.extent.getWidth(this.sourceProj_.getExtent()); + this.sourceWorldWidth_ = !goog.isNull(this.sourceProj_.getExtent()) ? + ol.extent.getWidth(this.sourceProj_.getExtent()) : null; + + /** + * @type {?number} + * @private + */ + this.targetWorldWidth_ = !goog.isNull(this.targetProj_.getExtent()) ? + ol.extent.getWidth(this.targetProj_.getExtent()) : null; var tlDst = ol.extent.getTopLeft(targetExtent); var trDst = ol.extent.getTopRight(targetExtent); @@ -146,29 +155,43 @@ ol.reproj.Triangulation.prototype.addQuadIfValid_ = function(a, b, c, d, aSrc, bSrc, cSrc, dSrc, maxSubdiv) { var srcQuadExtent = ol.extent.boundingExtent([aSrc, bSrc, cSrc, dSrc]); - if (!goog.isNull(this.maxSourceExtent_)) { - if (!ol.extent.intersects(srcQuadExtent, this.maxSourceExtent_)) { - // whole quad outside source projection extent -> ignore - return; - } - } - var srcCoverageX = ol.extent.getWidth(srcQuadExtent) / this.sourceWorldWidth_; + var srcCoverageX = !goog.isNull(this.sourceWorldWidth_) ? + ol.extent.getWidth(srcQuadExtent) / this.sourceWorldWidth_ : null; // when the quad is wrapped in the source projection // it covers most of the projection extent, but not fully var wrapsX = this.sourceProj_.canWrapX() && srcCoverageX > 0.5 && srcCoverageX < 1; - if (maxSubdiv > 0) { - var needsSubdivision = !wrapsX && this.sourceProj_.isGlobal() && - srcCoverageX > ol.RASTER_REPROJ_MAX_TRIANGLE_WIDTH; + var needsSubdivision = false; + if (maxSubdiv > 0) { + if (this.targetProj_.isGlobal() && !goog.isNull(this.targetWorldWidth_)) { + var tgtQuadExtent = ol.extent.boundingExtent([a, b, c, d]); + var tgtCoverageX = + ol.extent.getWidth(tgtQuadExtent) / this.targetWorldWidth_; + needsSubdivision |= tgtCoverageX > ol.RASTER_REPROJ_MAX_TRIANGLE_WIDTH; + } + if (!wrapsX && this.sourceProj_.isGlobal() && !goog.isNull(srcCoverageX)) { + needsSubdivision |= srcCoverageX > ol.RASTER_REPROJ_MAX_TRIANGLE_WIDTH; + } + } + + if (!needsSubdivision && !goog.isNull(this.maxSourceExtent_)) { + if (!ol.extent.intersects(srcQuadExtent, this.maxSourceExtent_)) { + // whole quad outside source projection extent -> ignore + return; + } + } + + if (maxSubdiv > 0) { var center = [(a[0] + c[0]) / 2, (a[1] + c[1]) / 2]; var centerSrc = this.transformInv_(center); if (!needsSubdivision) { var dx; if (wrapsX) { + goog.asserts.assert(!goog.isNull(this.sourceWorldWidth_)); var centerSrcEstimX = (goog.math.modulo(aSrc[0], this.sourceWorldWidth_) + goog.math.modulo(cSrc[0], this.sourceWorldWidth_)) / 2; @@ -232,6 +255,7 @@ ol.reproj.Triangulation.prototype.calculateSourceExtent = function() { // to properly calculate the extent (and then possibly shifted back) goog.array.forEach(this.triangles_, function(triangle, i, arr) { + goog.asserts.assert(!goog.isNull(this.sourceWorldWidth_)); var src = triangle.source; ol.extent.extendCoordinate(extent, [goog.math.modulo(src[0][0], this.sourceWorldWidth_), src[0][1]]);