Simplify triangle-shifting logic for reprojection
This commit is contained in:
@@ -49,6 +49,7 @@ ol.reproj.calculateSourceResolution = function(sourceProj, targetProj,
|
|||||||
* Renders the source into the canvas based on the triangulation.
|
* Renders the source into the canvas based on the triangulation.
|
||||||
* @param {CanvasRenderingContext2D} context
|
* @param {CanvasRenderingContext2D} context
|
||||||
* @param {number} sourceResolution
|
* @param {number} sourceResolution
|
||||||
|
* @param {ol.Extent} sourceExtent
|
||||||
* @param {number} targetResolution
|
* @param {number} targetResolution
|
||||||
* @param {ol.Extent} targetExtent
|
* @param {ol.Extent} targetExtent
|
||||||
* @param {ol.reproj.Triangulation} triangulation
|
* @param {ol.reproj.Triangulation} triangulation
|
||||||
@@ -56,9 +57,13 @@ ol.reproj.calculateSourceResolution = function(sourceProj, targetProj,
|
|||||||
* image: (HTMLCanvasElement|Image)}>} sources
|
* image: (HTMLCanvasElement|Image)}>} sources
|
||||||
*/
|
*/
|
||||||
ol.reproj.renderTriangles = function(context,
|
ol.reproj.renderTriangles = function(context,
|
||||||
sourceResolution, targetResolution, targetExtent, triangulation, sources) {
|
sourceResolution, sourceExtent, targetResolution, targetExtent,
|
||||||
|
triangulation, sources) {
|
||||||
|
|
||||||
var shiftDistance = triangulation.shiftDistance;
|
var shiftDistance = !goog.isNull(sourceExtent) ?
|
||||||
|
ol.extent.getWidth(sourceExtent) : null;
|
||||||
|
var shiftThreshold = !goog.isNull(sourceExtent) ?
|
||||||
|
(sourceExtent[0] + sourceExtent[2]) / 2 : null;
|
||||||
var targetTL = ol.extent.getTopLeft(targetExtent);
|
var targetTL = ol.extent.getTopLeft(targetExtent);
|
||||||
|
|
||||||
goog.array.forEach(triangulation.triangles, function(tri, i, arr) {
|
goog.array.forEach(triangulation.triangles, function(tri, i, arr) {
|
||||||
@@ -91,10 +96,10 @@ ol.reproj.renderTriangles = function(context,
|
|||||||
var u0 = tgt[0][0] - targetTL[0], v0 = -(tgt[0][1] - targetTL[1]),
|
var u0 = tgt[0][0] - targetTL[0], v0 = -(tgt[0][1] - targetTL[1]),
|
||||||
u1 = tgt[1][0] - targetTL[0], v1 = -(tgt[1][1] - targetTL[1]),
|
u1 = tgt[1][0] - targetTL[0], v1 = -(tgt[1][1] - targetTL[1]),
|
||||||
u2 = tgt[2][0] - targetTL[0], v2 = -(tgt[2][1] - targetTL[1]);
|
u2 = tgt[2][0] - targetTL[0], v2 = -(tgt[2][1] - targetTL[1]);
|
||||||
if (tri.needsShift) {
|
if (tri.needsShift && !goog.isNull(shiftDistance)) {
|
||||||
x0 = goog.math.modulo(x0 + shiftDistance, shiftDistance);
|
x0 = goog.math.modulo(x0, shiftDistance);
|
||||||
x1 = goog.math.modulo(x1 + shiftDistance, shiftDistance);
|
x1 = goog.math.modulo(x1, shiftDistance);
|
||||||
x2 = goog.math.modulo(x2 + shiftDistance, shiftDistance);
|
x2 = goog.math.modulo(x2, shiftDistance);
|
||||||
}
|
}
|
||||||
var augmentedMatrix = [
|
var augmentedMatrix = [
|
||||||
[x0, y0, 1, 0, 0, 0, u0 / targetResolution],
|
[x0, y0, 1, 0, 0, 0, u0 / targetResolution],
|
||||||
@@ -142,8 +147,9 @@ ol.reproj.renderTriangles = function(context,
|
|||||||
var dataTL = ol.extent.getTopLeft(src.extent);
|
var dataTL = ol.extent.getTopLeft(src.extent);
|
||||||
context.translate(dataTL[0], dataTL[1]);
|
context.translate(dataTL[0], dataTL[1]);
|
||||||
// if the triangle needs to be shifted (because of the dateline wrapping),
|
// if the triangle needs to be shifted (because of the dateline wrapping),
|
||||||
// shift only the source images that need it
|
// shift back only the source images that need it
|
||||||
if (tri.needsShift && dataTL[0] < 0) {
|
if (tri.needsShift && !goog.isNull(shiftDistance) &&
|
||||||
|
dataTL[0] < shiftThreshold) {
|
||||||
context.translate(shiftDistance, 0);
|
context.translate(shiftDistance, 0);
|
||||||
}
|
}
|
||||||
context.scale(sourceResolution, -sourceResolution);
|
context.scale(sourceResolution, -sourceResolution);
|
||||||
|
|||||||
@@ -114,7 +114,8 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.srcZ_ = sourceTileGrid.getZForResolution(sourceResolution);
|
this.srcZ_ = sourceTileGrid.getZForResolution(sourceResolution);
|
||||||
var srcExtent = ol.reproj.triangulation.getSourceExtent(this.triangulation_);
|
var srcExtent = ol.reproj.triangulation.getSourceExtent(
|
||||||
|
this.triangulation_, sourceProj);
|
||||||
|
|
||||||
var sourceProjExtent = sourceProj.getExtent();
|
var sourceProjExtent = sourceProj.getExtent();
|
||||||
if (!sourceProj.isGlobal() && sourceProjExtent) {
|
if (!sourceProj.isGlobal() && sourceProjExtent) {
|
||||||
@@ -238,8 +239,9 @@ ol.reproj.Tile.prototype.reproject_ = function() {
|
|||||||
|
|
||||||
if (sources.length > 0) {
|
if (sources.length > 0) {
|
||||||
var targetExtent = this.targetTileGrid_.getTileCoordExtent(tileCoord);
|
var targetExtent = this.targetTileGrid_.getTileCoordExtent(tileCoord);
|
||||||
ol.reproj.renderTriangles(context, srcResolution, targetResolution,
|
ol.reproj.renderTriangles(context,
|
||||||
targetExtent, this.triangulation_, sources);
|
srcResolution, this.sourceTileGrid_.getExtent(),
|
||||||
|
targetResolution, targetExtent, this.triangulation_, sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.canvas_ = context.canvas;
|
this.canvas_ = context.canvas;
|
||||||
|
|||||||
@@ -22,8 +22,10 @@ ol.reproj.Triangle;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* `needsShift` indicates that _any_ of the triangles has to be shifted during
|
||||||
|
* reprojection. See {@link ol.reproj.Triangle}.
|
||||||
* @typedef {{triangles: Array.<ol.reproj.Triangle>,
|
* @typedef {{triangles: Array.<ol.reproj.Triangle>,
|
||||||
* shiftDistance: number}}
|
* needsShift: boolean}}
|
||||||
*/
|
*/
|
||||||
ol.reproj.Triangulation;
|
ol.reproj.Triangulation;
|
||||||
|
|
||||||
@@ -101,8 +103,7 @@ ol.reproj.triangulation.addTriangleIfValid_ = function(triangulation, a, b, c,
|
|||||||
needsShift: needsShift
|
needsShift: needsShift
|
||||||
});
|
});
|
||||||
if (needsShift) {
|
if (needsShift) {
|
||||||
var sourceProjExtent = sourceProj.getExtent();
|
triangulation.needsShift = true;
|
||||||
triangulation.shiftDistance = ol.extent.getWidth(sourceProjExtent);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -123,7 +124,7 @@ ol.reproj.triangulation.createForExtent = function(extent, sourceProj,
|
|||||||
|
|
||||||
var triangulation = {
|
var triangulation = {
|
||||||
triangles: [],
|
triangles: [],
|
||||||
shiftDistance: 0
|
needsShift: false
|
||||||
};
|
};
|
||||||
|
|
||||||
var tlDst = ol.extent.getTopLeft(extent);
|
var tlDst = ol.extent.getTopLeft(extent);
|
||||||
@@ -167,24 +168,32 @@ ol.reproj.triangulation.createForExtent = function(extent, sourceProj,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.reproj.Triangulation} triangulation
|
* @param {ol.reproj.Triangulation} triangulation
|
||||||
|
* @param {ol.proj.Projection} sourceProj
|
||||||
* @return {ol.Extent}
|
* @return {ol.Extent}
|
||||||
*/
|
*/
|
||||||
ol.reproj.triangulation.getSourceExtent = function(triangulation) {
|
ol.reproj.triangulation.getSourceExtent = function(triangulation, sourceProj) {
|
||||||
var extent = ol.extent.createEmpty();
|
var extent = ol.extent.createEmpty();
|
||||||
|
|
||||||
var distance = triangulation.shiftDistance;
|
if (triangulation.needsShift) {
|
||||||
if (distance > 0) {
|
// although only some of the triangles are crossing the dateline,
|
||||||
|
// all coordiantes need to be "shifted" to be positive
|
||||||
|
// to properly calculate the extent (and then possibly shifted back)
|
||||||
|
|
||||||
|
var sourceProjExtent = sourceProj.getExtent();
|
||||||
|
var sourceProjWidth = ol.extent.getWidth(sourceProjExtent);
|
||||||
goog.array.forEach(triangulation.triangles, function(triangle, i, arr) {
|
goog.array.forEach(triangulation.triangles, function(triangle, i, arr) {
|
||||||
var src = triangle.source;
|
var src = triangle.source;
|
||||||
ol.extent.extendCoordinate(extent,
|
ol.extent.extendCoordinate(extent,
|
||||||
[goog.math.modulo(src[0][0] + distance, distance), src[0][1]]);
|
[goog.math.modulo(src[0][0], sourceProjWidth), src[0][1]]);
|
||||||
ol.extent.extendCoordinate(extent,
|
ol.extent.extendCoordinate(extent,
|
||||||
[goog.math.modulo(src[1][0] + distance, distance), src[1][1]]);
|
[goog.math.modulo(src[1][0], sourceProjWidth), src[1][1]]);
|
||||||
ol.extent.extendCoordinate(extent,
|
ol.extent.extendCoordinate(extent,
|
||||||
[goog.math.modulo(src[2][0] + distance, distance), src[2][1]]);
|
[goog.math.modulo(src[2][0], sourceProjWidth), src[2][1]]);
|
||||||
});
|
});
|
||||||
if (extent[0] > distance / 2) extent[0] -= distance;
|
|
||||||
if (extent[2] > distance / 2) extent[2] -= distance;
|
var right = sourceProjExtent[2];
|
||||||
|
if (extent[0] > right) extent[0] -= sourceProjWidth;
|
||||||
|
if (extent[2] > right) extent[2] -= sourceProjWidth;
|
||||||
} else {
|
} else {
|
||||||
goog.array.forEach(triangulation.triangles, function(triangle, i, arr) {
|
goog.array.forEach(triangulation.triangles, function(triangle, i, arr) {
|
||||||
var src = triangle.source;
|
var src = triangle.source;
|
||||||
|
|||||||
Reference in New Issue
Block a user