Add defines for certain reprojection constants

This commit is contained in:
Petr Sloup
2015-07-13 17:24:54 +02:00
parent f481070f82
commit be6bf00d74
4 changed files with 54 additions and 18 deletions

View File

@@ -28,6 +28,13 @@ ol.DEFAULT_MAX_ZOOM = 42;
ol.DEFAULT_MIN_ZOOM = 0; ol.DEFAULT_MIN_ZOOM = 0;
/**
* @define {number} Default maximum allowed threshold (in pixels) for
* reprojection triangulation. Default is `0.5`.
*/
ol.DEFAULT_RASTER_REPROJ_ERROR_THRESHOLD = 0.5;
/** /**
* @define {number} Default high water mark. * @define {number} Default high water mark.
*/ */
@@ -166,6 +173,39 @@ ol.OVERVIEWMAP_MAX_RATIO = 0.75;
ol.OVERVIEWMAP_MIN_RATIO = 0.1; ol.OVERVIEWMAP_MIN_RATIO = 0.1;
/**
* @define {number} Maximum number of source tiles for raster reprojection.
* If too many source tiles are determined to be loaded to create a single
* reprojected tile the browser can become unresponsive or even crash.
* This can happen if the developer defines projections improperly and/or
* with unlimited extents.
* If too many tiles are required, no tiles are loaded and
* `ol.TileState.ERROR` state is set. Default is `100`.
*/
ol.RASTER_REPROJ_MAX_SOURCE_TILES = 100;
/**
* @define {number} Maximum number of subdivision steps during raster
* reprojection triangulation. Prevents high memory usage and large
* number of proj4 calls when for certain transformations and areas.
* At most `2*(4^this)` triangles are created. Default is `5`.
*/
ol.RASTER_REPROJ_MAX_SUBDIVISION = 5;
/**
* @define {number} Maximum allowed size of triangle relative to world width.
* When transforming corners of world extent between certain projections,
* The resulting triangulation seems to have zero error and no subdivision
* is performed.
* If the triangle width is more than this (relative to world width; 0-1),
* subdivison is forced (respecting `ol.RASTER_REPROJ_MAX_SUBDIVISION`).
* Default is `0.25`.
*/
ol.RASTER_REPROJ_MAX_TRIANGLE_WIDTH = 0.25;
/** /**
* @define {number} Tolerance for geometry simplification in device pixels. * @define {number} Tolerance for geometry simplification in device pixels.
*/ */

View File

@@ -63,7 +63,7 @@ ol.reproj.Image = function(sourceProj, targetProj,
* @type {!ol.reproj.Triangulation} * @type {!ol.reproj.Triangulation}
*/ */
this.triangulation_ = new ol.reproj.Triangulation( this.triangulation_ = new ol.reproj.Triangulation(
sourceProj, targetProj, limitedTargetExtent, this.maxSourceExtent_); sourceProj, targetProj, limitedTargetExtent, this.maxSourceExtent_, 0);
/** /**
* @private * @private

View File

@@ -99,7 +99,7 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
var targetResolution = targetTileGrid.getResolution(z); var targetResolution = targetTileGrid.getResolution(z);
var errorThresholdInPixels = 0.5; var errorThresholdInPixels = ol.DEFAULT_RASTER_REPROJ_ERROR_THRESHOLD;
// in source units // in source units
var errorThreshold = targetResolution * errorThresholdInPixels * var errorThreshold = targetResolution * errorThresholdInPixels *
@@ -111,7 +111,7 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
*/ */
this.triangulation_ = new ol.reproj.Triangulation( this.triangulation_ = new ol.reproj.Triangulation(
sourceProj, targetProj, limitedTargetExtent, maxSourceExtent, sourceProj, targetProj, limitedTargetExtent, maxSourceExtent,
5, errorThreshold); errorThreshold);
if (this.triangulation_.getTriangles().length === 0) { if (this.triangulation_.getTriangles().length === 0) {
// no valid triangles -> EMPTY // no valid triangles -> EMPTY
@@ -166,11 +166,11 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
xRange = goog.array.range(srcRange.minX, srcRange.maxX + 1); xRange = goog.array.range(srcRange.minX, srcRange.maxX + 1);
} }
if (xRange.length * srcRange.getHeight() > 100) { var tilesRequired = xRange.length * srcRange.getHeight();
// Too many source tiles are needed -- something probably went wrong goog.asserts.assert(tilesRequired < ol.RASTER_REPROJ_MAX_SOURCE_TILES,
// This sometimes happens for certain non-global projections 'reasonable number of tiles is required');
// if no extent is specified.
// TODO: detect somehow better? or at least make this a define if (tilesRequired > ol.RASTER_REPROJ_MAX_SOURCE_TILES) {
this.state = ol.TileState.ERROR; this.state = ol.TileState.ERROR;
return; return;
} }

View File

@@ -20,13 +20,12 @@ ol.reproj.Triangle;
* @param {ol.proj.Projection} sourceProj * @param {ol.proj.Projection} sourceProj
* @param {ol.proj.Projection} targetProj * @param {ol.proj.Projection} targetProj
* @param {ol.Extent} targetExtent * @param {ol.Extent} targetExtent
* @param {ol.Extent=} opt_maxSourceExtent * @param {ol.Extent} maxSourceExtent
* @param {number=} opt_maxSubdiv Maximal subdivision. * @param {number} errorThreshold Acceptable error (in source units).
* @param {number=} opt_errorThreshold Acceptable error (in source units).
* @constructor * @constructor
*/ */
ol.reproj.Triangulation = function(sourceProj, targetProj, targetExtent, ol.reproj.Triangulation = function(sourceProj, targetProj, targetExtent,
opt_maxSourceExtent, opt_maxSubdiv, opt_errorThreshold) { maxSourceExtent, errorThreshold) {
/** /**
* @type {ol.proj.Projection} * @type {ol.proj.Projection}
@@ -50,11 +49,8 @@ ol.reproj.Triangulation = function(sourceProj, targetProj, targetExtent,
* @type {ol.Extent} * @type {ol.Extent}
* @private * @private
*/ */
this.maxSourceExtent_ = goog.isDef(opt_maxSourceExtent) ? this.maxSourceExtent_ = maxSourceExtent;
opt_maxSourceExtent : null;
var errorThreshold = goog.isDef(opt_errorThreshold) ?
opt_errorThreshold : 0; //TODO: define
/** /**
* @type {number} * @type {number}
* @private * @private
@@ -99,7 +95,7 @@ ol.reproj.Triangulation = function(sourceProj, targetProj, targetExtent,
this.addQuadIfValid_(tlDst, trDst, brDst, blDst, this.addQuadIfValid_(tlDst, trDst, brDst, blDst,
tlDstSrc, trDstSrc, brDstSrc, blDstSrc, tlDstSrc, trDstSrc, brDstSrc, blDstSrc,
opt_maxSubdiv || 0); ol.RASTER_REPROJ_MAX_SUBDIVISION);
}; };
@@ -155,7 +151,7 @@ ol.reproj.Triangulation.prototype.addQuadIfValid_ = function(a, b, c, d,
if (maxSubdiv > 0) { if (maxSubdiv > 0) {
var needsSubdivision = !wrapsX && this.sourceProj_.isGlobal() && var needsSubdivision = !wrapsX && this.sourceProj_.isGlobal() &&
srcCoverageX > 0.25; //TODO: define srcCoverageX > ol.RASTER_REPROJ_MAX_TRIANGLE_WIDTH;
var center = [(a[0] + c[0]) / 2, (a[1] + c[1]) / 2]; var center = [(a[0] + c[0]) / 2, (a[1] + c[1]) / 2];
var centerSrc = this.transformInv_(center); var centerSrc = this.transformInv_(center);