Clamp the triangulation vertices if partially outside source extent

This commit is contained in:
Petr Sloup
2015-06-01 17:48:17 +02:00
parent fcffce46b4
commit ebc3f24671
3 changed files with 29 additions and 12 deletions

View File

@@ -48,7 +48,6 @@ ol.reproj.Image = function(sourceProj, targetProj,
*/ */
this.canvas_ = this.context_.canvas; this.canvas_ = this.context_.canvas;
var transformInv = ol.proj.getTransform(targetProj, sourceProj);
var maxTargetExtent = targetProj.getExtent(); var maxTargetExtent = targetProj.getExtent();
var maxSourceExtent = sourceProj.getExtent(); var maxSourceExtent = sourceProj.getExtent();
@@ -57,7 +56,7 @@ ol.reproj.Image = function(sourceProj, targetProj,
* @type {!ol.reproj.Triangulation} * @type {!ol.reproj.Triangulation}
*/ */
this.triangles_ = ol.reproj.triangulation.createForExtent( this.triangles_ = ol.reproj.triangulation.createForExtent(
targetExtent, transformInv, targetExtent, sourceProj, targetProj,
maxTargetExtent, maxSourceExtent); maxTargetExtent, maxSourceExtent);
/** /**

View File

@@ -93,9 +93,9 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
//return; //return;
} }
var transformInv = ol.proj.getTransform(targetProj, sourceProj);
this.triangles_ = ol.reproj.triangulation.createForExtent( this.triangles_ = ol.reproj.triangulation.createForExtent(
targetExtent, transformInv, maxTargetExtent, maxSourceExtent); targetExtent, sourceProj, targetProj,
maxTargetExtent, maxSourceExtent);
var targetCenter = ol.extent.getCenter(targetExtent); var targetCenter = ol.extent.getCenter(targetExtent);
var targetResolution = targetTileGrid.getResolution(z); var targetResolution = targetTileGrid.getResolution(z);

View File

@@ -4,6 +4,7 @@ goog.provide('ol.reproj.triangulation');
goog.require('goog.array'); goog.require('goog.array');
goog.require('goog.math'); goog.require('goog.math');
goog.require('ol.extent'); goog.require('ol.extent');
goog.require('ol.proj');
/** /**
@@ -23,12 +24,13 @@ ol.reproj.Triangulation;
* @param {ol.Coordinate} a * @param {ol.Coordinate} a
* @param {ol.Coordinate} b * @param {ol.Coordinate} b
* @param {ol.Coordinate} c * @param {ol.Coordinate} c
* @param {ol.TransformFunction} transformFwd Forward transform (src -> dst).
* @param {ol.TransformFunction} transformInv Inverse transform (dst -> src). * @param {ol.TransformFunction} transformInv Inverse transform (dst -> src).
* @param {ol.Extent=} opt_maxTargetExtent * @param {ol.Extent=} opt_maxTargetExtent
* @param {ol.Extent=} opt_maxSourceExtent * @param {ol.Extent=} opt_maxSourceExtent
*/ */
ol.reproj.triangulation.addTriangleIfValid_ = function(triangulation, a, b, c, ol.reproj.triangulation.addTriangleIfValid_ = function(triangulation, a, b, c,
transformInv, opt_maxTargetExtent, opt_maxSourceExtent) { transformFwd, transformInv, opt_maxTargetExtent, opt_maxSourceExtent) {
if (goog.isDefAndNotNull(opt_maxTargetExtent)) { if (goog.isDefAndNotNull(opt_maxTargetExtent)) {
if (!ol.extent.containsCoordinate(opt_maxTargetExtent, a) && if (!ol.extent.containsCoordinate(opt_maxTargetExtent, a) &&
!ol.extent.containsCoordinate(opt_maxTargetExtent, b) && !ol.extent.containsCoordinate(opt_maxTargetExtent, b) &&
@@ -48,8 +50,22 @@ ol.reproj.triangulation.addTriangleIfValid_ = function(triangulation, a, b, c,
var srcTriangleExtent = ol.extent.boundingExtent([aSrc, bSrc, cSrc]); var srcTriangleExtent = ol.extent.boundingExtent([aSrc, bSrc, cSrc]);
if (!ol.extent.intersects(srcTriangleExtent, opt_maxSourceExtent)) { if (!ol.extent.intersects(srcTriangleExtent, opt_maxSourceExtent)) {
// whole triangle outside source projection extent -> ignore // whole triangle outside source projection extent -> ignore
// TODO: intersect triangle with the extent rather than bbox ?
return; return;
} }
if (!ol.extent.containsCoordinate(opt_maxSourceExtent, aSrc) ||
!ol.extent.containsCoordinate(opt_maxSourceExtent, bSrc) ||
!ol.extent.containsCoordinate(opt_maxSourceExtent, cSrc)) {
// if any vertex is outside projection range, modify the target triangle
// TODO: do not do closestCoordinate, but rather scale the triangle with
// respect to a point inside the extent
aSrc = ol.extent.closestCoordinate(opt_maxSourceExtent, aSrc);
bSrc = ol.extent.closestCoordinate(opt_maxSourceExtent, bSrc);
cSrc = ol.extent.closestCoordinate(opt_maxSourceExtent, cSrc);
a = transformFwd(aSrc);
b = transformFwd(bSrc);
c = transformFwd(cSrc);
}
} }
triangulation.push([[aSrc, a], [bSrc, b], [cSrc, c]]); triangulation.push([[aSrc, a], [bSrc, b], [cSrc, c]]);
}; };
@@ -59,16 +75,18 @@ ol.reproj.triangulation.addTriangleIfValid_ = function(triangulation, a, b, c,
* Triangulates given extent and reprojects vertices. * Triangulates given extent and reprojects vertices.
* TODO: improved triangulation, better error handling of some trans fails * TODO: improved triangulation, better error handling of some trans fails
* @param {ol.Extent} extent * @param {ol.Extent} extent
* @param {ol.TransformFunction} transformInv Inverse transform (dst -> src). * @param {ol.proj.Projection} sourceProj
* @param {ol.proj.Projection} targetProj
* @param {ol.Extent=} opt_maxTargetExtent * @param {ol.Extent=} opt_maxTargetExtent
* @param {ol.Extent=} opt_maxSourceExtent * @param {ol.Extent=} opt_maxSourceExtent
* @param {number=} opt_subdiv Subdivision factor (default 4). * @param {number=} opt_subdiv Subdivision factor (default 4).
* @return {ol.reproj.Triangulation} * @return {ol.reproj.Triangulation}
*/ */
ol.reproj.triangulation.createForExtent = function(extent, transformInv, ol.reproj.triangulation.createForExtent = function(extent, sourceProj,
opt_maxTargetExtent, targetProj, opt_maxTargetExtent, opt_maxSourceExtent, opt_subdiv) {
opt_maxSourceExtent,
opt_subdiv) { var transformFwd = ol.proj.getTransform(sourceProj, targetProj);
var transformInv = ol.proj.getTransform(targetProj, sourceProj);
var triangulation = []; var triangulation = [];
@@ -100,10 +118,10 @@ ol.reproj.triangulation.createForExtent = function(extent, transformInv,
ol.reproj.triangulation.addTriangleIfValid_( ol.reproj.triangulation.addTriangleIfValid_(
triangulation, x0y0dst, x1y1dst, x0y1dst, triangulation, x0y0dst, x1y1dst, x0y1dst,
transformInv, opt_maxTargetExtent, opt_maxSourceExtent); transformFwd, transformInv, opt_maxTargetExtent, opt_maxSourceExtent);
ol.reproj.triangulation.addTriangleIfValid_( ol.reproj.triangulation.addTriangleIfValid_(
triangulation, x0y0dst, x1y0dst, x1y1dst, triangulation, x0y0dst, x1y0dst, x1y1dst,
transformInv, opt_maxTargetExtent, opt_maxSourceExtent); transformFwd, transformInv, opt_maxTargetExtent, opt_maxSourceExtent);
} }
} }