Make ol.reproj.Triangulation a class
This commit is contained in:
@@ -9,7 +9,7 @@ goog.require('ol.dom');
|
|||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.proj');
|
goog.require('ol.proj');
|
||||||
goog.require('ol.reproj');
|
goog.require('ol.reproj');
|
||||||
goog.require('ol.reproj.triangulation');
|
goog.require('ol.reproj.Triangulation');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -55,14 +55,15 @@ ol.reproj.Image = function(sourceProj, targetProj,
|
|||||||
this.maxSourceExtent_ = sourceProj.getExtent();
|
this.maxSourceExtent_ = sourceProj.getExtent();
|
||||||
var maxTargetExtent = targetProj.getExtent();
|
var maxTargetExtent = targetProj.getExtent();
|
||||||
|
|
||||||
|
var limitedTargetExtent = ol.extent.getIntersection(
|
||||||
|
targetExtent, maxTargetExtent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {!ol.reproj.Triangulation}
|
* @type {!ol.reproj.Triangulation}
|
||||||
*/
|
*/
|
||||||
this.triangulation_ = ol.reproj.triangulation.createForExtent(
|
this.triangulation_ = new ol.reproj.Triangulation(
|
||||||
targetExtent, sourceProj, targetProj,
|
sourceProj, targetProj, limitedTargetExtent, this.maxSourceExtent_);
|
||||||
maxTargetExtent, this.maxSourceExtent_);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -76,8 +77,7 @@ ol.reproj.Image = function(sourceProj, targetProj,
|
|||||||
*/
|
*/
|
||||||
this.targetExtent_ = targetExtent;
|
this.targetExtent_ = targetExtent;
|
||||||
|
|
||||||
var srcExtent = ol.reproj.triangulation.getSourceExtent(
|
var srcExtent = this.triangulation_.calculateSourceExtent();
|
||||||
this.triangulation_, sourceProj);
|
|
||||||
|
|
||||||
var targetCenter = ol.extent.getCenter(targetExtent);
|
var targetCenter = ol.extent.getCenter(targetExtent);
|
||||||
var sourceResolution = ol.reproj.calculateSourceResolution(
|
var sourceResolution = ol.reproj.calculateSourceResolution(
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ ol.reproj.renderTriangles = function(context,
|
|||||||
(sourceExtent[0] + sourceExtent[2]) / 2 : null;
|
(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.getTriangles(), function(tri, i, arr) {
|
||||||
context.save();
|
context.save();
|
||||||
|
|
||||||
/* Calculate affine transform (src -> dst)
|
/* Calculate affine transform (src -> dst)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ goog.require('ol.dom');
|
|||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.proj');
|
goog.require('ol.proj');
|
||||||
goog.require('ol.reproj');
|
goog.require('ol.reproj');
|
||||||
goog.require('ol.reproj.triangulation');
|
goog.require('ol.reproj.Triangulation');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -62,14 +62,6 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
|
|||||||
var maxTargetExtent = this.targetTileGrid_.getExtent();
|
var maxTargetExtent = this.targetTileGrid_.getExtent();
|
||||||
var maxSourceExtent = this.sourceTileGrid_.getExtent();
|
var maxSourceExtent = this.sourceTileGrid_.getExtent();
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {!ol.reproj.Triangulation}
|
|
||||||
*/
|
|
||||||
this.triangulation_ = ol.reproj.triangulation.createForExtent(
|
|
||||||
targetExtent, sourceProj, targetProj,
|
|
||||||
maxTargetExtent, maxSourceExtent);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {!Array.<ol.Tile>}
|
* @type {!Array.<ol.Tile>}
|
||||||
@@ -88,21 +80,39 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
|
|||||||
*/
|
*/
|
||||||
this.srcZ_ = 0;
|
this.srcZ_ = 0;
|
||||||
|
|
||||||
if (!ol.extent.intersects(maxTargetExtent, targetExtent)) {
|
var limitedTargetExtent = ol.extent.getIntersection(
|
||||||
|
targetExtent, maxTargetExtent);
|
||||||
|
|
||||||
|
if (ol.extent.getArea(limitedTargetExtent) === 0) {
|
||||||
// Tile is completely outside range -> EMPTY
|
// Tile is completely outside range -> EMPTY
|
||||||
// TODO: is it actually correct that the source even creates the tile ?
|
// TODO: is it actually correct that the source even creates the tile ?
|
||||||
this.state = ol.TileState.EMPTY;
|
this.state = ol.TileState.EMPTY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.triangulation_.triangles.length === 0) {
|
var targetResolution = targetTileGrid.getResolution(z);
|
||||||
|
|
||||||
|
var errorThresholdInPixels = 0.5;
|
||||||
|
|
||||||
|
// in source units
|
||||||
|
var errorThreshold = targetResolution * errorThresholdInPixels *
|
||||||
|
targetProj.getMetersPerUnit() / sourceProj.getMetersPerUnit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {!ol.reproj.Triangulation}
|
||||||
|
*/
|
||||||
|
this.triangulation_ = new ol.reproj.Triangulation(
|
||||||
|
sourceProj, targetProj, limitedTargetExtent, maxSourceExtent,
|
||||||
|
5, errorThreshold);
|
||||||
|
|
||||||
|
if (this.triangulation_.getTriangles().length === 0) {
|
||||||
// no valid triangles -> EMPTY
|
// no valid triangles -> EMPTY
|
||||||
this.state = ol.TileState.EMPTY;
|
this.state = ol.TileState.EMPTY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var targetCenter = ol.extent.getCenter(targetExtent);
|
var targetCenter = ol.extent.getCenter(limitedTargetExtent);
|
||||||
var targetResolution = targetTileGrid.getResolution(z);
|
|
||||||
var sourceResolution = ol.reproj.calculateSourceResolution(
|
var sourceResolution = ol.reproj.calculateSourceResolution(
|
||||||
sourceProj, targetProj, targetCenter, targetResolution);
|
sourceProj, targetProj, targetCenter, targetResolution);
|
||||||
|
|
||||||
@@ -114,8 +124,7 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.srcZ_ = sourceTileGrid.getZForResolution(sourceResolution);
|
this.srcZ_ = sourceTileGrid.getZForResolution(sourceResolution);
|
||||||
var srcExtent = ol.reproj.triangulation.getSourceExtent(
|
var srcExtent = this.triangulation_.calculateSourceExtent();
|
||||||
this.triangulation_, sourceProj);
|
|
||||||
|
|
||||||
var sourceProjExtent = sourceProj.getExtent();
|
var sourceProjExtent = sourceProj.getExtent();
|
||||||
if (!sourceProj.isGlobal() && sourceProjExtent) {
|
if (!sourceProj.isGlobal() && sourceProjExtent) {
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
goog.provide('ol.reproj.Triangulation');
|
goog.provide('ol.reproj.Triangulation');
|
||||||
goog.provide('ol.reproj.triangulation');
|
|
||||||
|
|
||||||
goog.require('goog.array');
|
goog.require('goog.array');
|
||||||
goog.require('goog.math');
|
goog.require('goog.math');
|
||||||
goog.require('ol.coordinate');
|
|
||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.proj');
|
goog.require('ol.proj');
|
||||||
|
|
||||||
@@ -21,194 +19,224 @@ goog.require('ol.proj');
|
|||||||
ol.reproj.Triangle;
|
ol.reproj.Triangle;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `needsShift` indicates that _any_ of the triangles has to be shifted during
|
* @param {ol.proj.Projection} sourceProj
|
||||||
* reprojection. See {@link ol.reproj.Triangle}.
|
* @param {ol.proj.Projection} targetProj
|
||||||
* @typedef {{triangles: Array.<ol.reproj.Triangle>,
|
* @param {ol.Extent} targetExtent
|
||||||
* needsShift: boolean}}
|
* @param {ol.Extent=} opt_maxSourceExtent
|
||||||
|
* @param {number=} opt_maxSubdiv Maximal subdivision.
|
||||||
|
* @param {number=} opt_errorThreshold Acceptable error (in source units).
|
||||||
|
* @constructor
|
||||||
*/
|
*/
|
||||||
ol.reproj.Triangulation;
|
ol.reproj.Triangulation = function(sourceProj, targetProj, targetExtent,
|
||||||
|
opt_maxSourceExtent, opt_maxSubdiv, opt_errorThreshold) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ol.proj.Projection}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.sourceProj_ = sourceProj;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ol.proj.Projection}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.targetProj_ = targetProj;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ol.TransformFunction}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.transformInv_ = ol.proj.getTransform(this.targetProj_, this.sourceProj_);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ol.Extent}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.maxSourceExtent_ = goog.isDef(opt_maxSourceExtent) ?
|
||||||
|
opt_maxSourceExtent : null;
|
||||||
|
|
||||||
|
var errorThreshold = goog.isDef(opt_errorThreshold) ?
|
||||||
|
opt_errorThreshold : 0; //TODO: define
|
||||||
|
/**
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.errorThresholdSquared_ = errorThreshold * errorThreshold;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Array.<ol.reproj.Triangle>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.triangles_ = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that _any_ of the triangles has to be shifted during
|
||||||
|
* reprojection. See {@link ol.reproj.Triangle}.
|
||||||
|
* @type {boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.needsShift_ = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.sourceWorldWidth_ = ol.extent.getWidth(this.sourceProj_.getExtent());
|
||||||
|
|
||||||
|
var tlDst = ol.extent.getTopLeft(targetExtent);
|
||||||
|
var trDst = ol.extent.getTopRight(targetExtent);
|
||||||
|
var brDst = ol.extent.getBottomRight(targetExtent);
|
||||||
|
var blDst = ol.extent.getBottomLeft(targetExtent);
|
||||||
|
var tlDstSrc = this.transformInv_(tlDst);
|
||||||
|
var trDstSrc = this.transformInv_(trDst);
|
||||||
|
var brDstSrc = this.transformInv_(brDst);
|
||||||
|
var blDstSrc = this.transformInv_(blDst);
|
||||||
|
|
||||||
|
this.addQuadIfValid_(tlDst, trDst, brDst, blDst,
|
||||||
|
tlDstSrc, trDstSrc, brDstSrc, blDstSrc,
|
||||||
|
opt_maxSubdiv || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds triangle to the triangulation (and reprojects the vertices) if valid.
|
* Adds triangle to the triangulation.
|
||||||
* @private
|
|
||||||
* @param {ol.reproj.Triangulation} 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.proj.Projection} sourceProj
|
* @param {ol.Coordinate} aSrc
|
||||||
* @param {ol.proj.Projection} targetProj
|
* @param {ol.Coordinate} bSrc
|
||||||
* @param {ol.Extent=} opt_maxTargetExtent
|
* @param {ol.Coordinate} cSrc
|
||||||
* @param {ol.Extent=} opt_maxSourceExtent
|
* @param {boolean} wrapsX
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.reproj.triangulation.addTriangleIfValid_ = function(triangulation, a, b, c,
|
ol.reproj.Triangulation.prototype.addTriangle_ = function(a, b, c,
|
||||||
sourceProj, targetProj, opt_maxTargetExtent, opt_maxSourceExtent) {
|
aSrc, bSrc, cSrc, wrapsX) {
|
||||||
if (goog.isDefAndNotNull(opt_maxTargetExtent)) {
|
// wrapsX could be determined by transforming centroid of the target triangle.
|
||||||
if (!ol.extent.containsCoordinate(opt_maxTargetExtent, a) &&
|
|
||||||
!ol.extent.containsCoordinate(opt_maxTargetExtent, b) &&
|
|
||||||
!ol.extent.containsCoordinate(opt_maxTargetExtent, c)) {
|
|
||||||
// whole triangle outside target projection extent -> ignore
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// clamp the vertices to the extent edges before transforming
|
|
||||||
a = ol.extent.closestCoordinate(opt_maxTargetExtent, a);
|
|
||||||
b = ol.extent.closestCoordinate(opt_maxTargetExtent, b);
|
|
||||||
c = ol.extent.closestCoordinate(opt_maxTargetExtent, c);
|
|
||||||
}
|
|
||||||
var transformInv = ol.proj.getTransform(targetProj, sourceProj);
|
|
||||||
var aSrc = transformInv(a);
|
|
||||||
var bSrc = transformInv(b);
|
|
||||||
var cSrc = transformInv(c);
|
|
||||||
if (goog.isDefAndNotNull(opt_maxSourceExtent)) {
|
|
||||||
var srcTriangleExtent = ol.extent.boundingExtent([aSrc, bSrc, cSrc]);
|
|
||||||
if (!ol.extent.intersects(srcTriangleExtent, opt_maxSourceExtent)) {
|
|
||||||
// whole triangle outside source projection extent -> ignore
|
|
||||||
// TODO: intersect triangle with the extent rather than bbox ?
|
|
||||||
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);
|
|
||||||
|
|
||||||
var makeFinite = function(coord, extent) {
|
|
||||||
if (!goog.math.isFiniteNumber(coord[0])) {
|
|
||||||
coord[0] = goog.math.clamp(coord[0], extent[0], extent[2]);
|
|
||||||
}
|
|
||||||
if (!goog.math.isFiniteNumber(coord[1])) {
|
|
||||||
coord[1] = goog.math.clamp(coord[1], extent[1], extent[3]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
makeFinite(aSrc, opt_maxSourceExtent);
|
|
||||||
makeFinite(bSrc, opt_maxSourceExtent);
|
|
||||||
makeFinite(cSrc, opt_maxSourceExtent);
|
|
||||||
|
|
||||||
var transformFwd = ol.proj.getTransform(sourceProj, targetProj);
|
|
||||||
a = transformFwd(aSrc);
|
|
||||||
b = transformFwd(bSrc);
|
|
||||||
c = transformFwd(cSrc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var needsShift = false;
|
|
||||||
if (sourceProj.canWrapX()) {
|
|
||||||
// determine if the triangle crosses the dateline here
|
|
||||||
// This can be detected by transforming centroid of the target triangle.
|
|
||||||
// If the transformed centroid is outside the transformed triangle,
|
// If the transformed centroid is outside the transformed triangle,
|
||||||
// the triangle wraps around projection extent.
|
// the triangle wraps around projection extent.
|
||||||
|
// However, this would require additional transformation call.
|
||||||
|
|
||||||
var centroid = [(a[0] + b[0] + c[0]) / 3,
|
this.triangles_.push({
|
||||||
(a[1] + b[1] + c[1]) / 3];
|
|
||||||
var centroidSrc = transformInv(centroid);
|
|
||||||
|
|
||||||
if (!ol.coordinate.isInTriangle(centroidSrc, aSrc, bSrc, cSrc)) {
|
|
||||||
needsShift = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
triangulation.triangles.push({
|
|
||||||
source: [aSrc, bSrc, cSrc],
|
source: [aSrc, bSrc, cSrc],
|
||||||
target: [a, b, c],
|
target: [a, b, c],
|
||||||
needsShift: needsShift
|
needsShift: wrapsX
|
||||||
});
|
});
|
||||||
if (needsShift) {
|
if (wrapsX) {
|
||||||
triangulation.needsShift = true;
|
this.needsShift_ = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triangulates given extent and reprojects vertices.
|
* Adds quad (points in clock-wise order) to the triangulation
|
||||||
* TODO: improved triangulation, better error handling of some trans fails
|
* (and reprojects the vertices) if valid.
|
||||||
* @param {ol.Extent} extent
|
* @param {ol.Coordinate} a
|
||||||
* @param {ol.proj.Projection} sourceProj
|
* @param {ol.Coordinate} b
|
||||||
* @param {ol.proj.Projection} targetProj
|
* @param {ol.Coordinate} c
|
||||||
* @param {ol.Extent=} opt_maxTargetExtent
|
* @param {ol.Coordinate} d
|
||||||
* @param {ol.Extent=} opt_maxSourceExtent
|
* @param {ol.Coordinate} aSrc
|
||||||
* @param {number=} opt_subdiv Subdivision factor (default 4).
|
* @param {ol.Coordinate} bSrc
|
||||||
* @return {ol.reproj.Triangulation}
|
* @param {ol.Coordinate} cSrc
|
||||||
|
* @param {ol.Coordinate} dSrc
|
||||||
|
* @param {number} maxSubdiv Maximal allowed subdivision of the quad.
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.reproj.triangulation.createForExtent = function(extent, sourceProj,
|
ol.reproj.Triangulation.prototype.addQuadIfValid_ = function(a, b, c, d,
|
||||||
targetProj, opt_maxTargetExtent, opt_maxSourceExtent, opt_subdiv) {
|
aSrc, bSrc, cSrc, dSrc, maxSubdiv) {
|
||||||
|
|
||||||
var triangulation = {
|
var srcQuadExtent = ol.extent.boundingExtent([aSrc, bSrc, cSrc, dSrc]);
|
||||||
triangles: [],
|
if (!goog.isNull(this.maxSourceExtent_)) {
|
||||||
needsShift: false
|
if (!ol.extent.intersects(srcQuadExtent, this.maxSourceExtent_)) {
|
||||||
};
|
// whole quad outside source projection extent -> ignore
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var srcCoverageX = ol.extent.getWidth(srcQuadExtent) / this.sourceWorldWidth_;
|
||||||
|
|
||||||
var tlDst = ol.extent.getTopLeft(extent);
|
// when the quad is wrapped in the source projection
|
||||||
var brDst = ol.extent.getBottomRight(extent);
|
// it covers most of the projection extent, but not fully
|
||||||
|
var wrapsX = this.sourceProj_.canWrapX() &&
|
||||||
|
srcCoverageX > 0.5 && srcCoverageX < 1;
|
||||||
|
|
||||||
var subdiv = opt_subdiv || 4;
|
if (maxSubdiv > 0) {
|
||||||
for (var y = 0; y < subdiv; y++) {
|
var needsSubdivision = !wrapsX && this.sourceProj_.isGlobal() &&
|
||||||
for (var x = 0; x < subdiv; x++) {
|
srcCoverageX > 0.25; //TODO: define
|
||||||
// do 2 triangle: [(x, y), (x + 1, y + 1), (x, y + 1)]
|
|
||||||
// [(x, y), (x + 1, y), (x + 1, y + 1)]
|
|
||||||
|
|
||||||
var x0y0dst = [
|
var center = [(a[0] + c[0]) / 2, (a[1] + c[1]) / 2];
|
||||||
goog.math.lerp(tlDst[0], brDst[0], x / subdiv),
|
var centerSrc = this.transformInv_(center);
|
||||||
goog.math.lerp(tlDst[1], brDst[1], y / subdiv)
|
|
||||||
];
|
|
||||||
var x1y0dst = [
|
|
||||||
goog.math.lerp(tlDst[0], brDst[0], (x + 1) / subdiv),
|
|
||||||
goog.math.lerp(tlDst[1], brDst[1], y / subdiv)
|
|
||||||
];
|
|
||||||
var x0y1dst = [
|
|
||||||
goog.math.lerp(tlDst[0], brDst[0], x / subdiv),
|
|
||||||
goog.math.lerp(tlDst[1], brDst[1], (y + 1) / subdiv)
|
|
||||||
];
|
|
||||||
var x1y1dst = [
|
|
||||||
goog.math.lerp(tlDst[0], brDst[0], (x + 1) / subdiv),
|
|
||||||
goog.math.lerp(tlDst[1], brDst[1], (y + 1) / subdiv)
|
|
||||||
];
|
|
||||||
|
|
||||||
ol.reproj.triangulation.addTriangleIfValid_(
|
if (!needsSubdivision) {
|
||||||
triangulation, x0y0dst, x1y1dst, x0y1dst,
|
var dx;
|
||||||
sourceProj, targetProj, opt_maxTargetExtent, opt_maxSourceExtent);
|
if (wrapsX) {
|
||||||
ol.reproj.triangulation.addTriangleIfValid_(
|
var centerSrcEstimX =
|
||||||
triangulation, x0y0dst, x1y0dst, x1y1dst,
|
(goog.math.modulo(aSrc[0], this.sourceWorldWidth_) +
|
||||||
sourceProj, targetProj, opt_maxTargetExtent, opt_maxSourceExtent);
|
goog.math.modulo(cSrc[0], this.sourceWorldWidth_)) / 2;
|
||||||
|
dx = centerSrcEstimX -
|
||||||
|
goog.math.modulo(centerSrc[0], this.sourceWorldWidth_);
|
||||||
|
} else {
|
||||||
|
dx = (aSrc[0] + cSrc[0]) / 2 - centerSrc[0];
|
||||||
|
}
|
||||||
|
var dy = (aSrc[1] + cSrc[1]) / 2 - centerSrc[1];
|
||||||
|
var centerSrcErrorSquared = dx * dx + dy * dy;
|
||||||
|
needsSubdivision = centerSrcErrorSquared > this.errorThresholdSquared_;
|
||||||
|
}
|
||||||
|
if (needsSubdivision) {
|
||||||
|
var ab = [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];
|
||||||
|
var abSrc = this.transformInv_(ab);
|
||||||
|
var bc = [(b[0] + c[0]) / 2, (b[1] + c[1]) / 2];
|
||||||
|
var bcSrc = this.transformInv_(bc);
|
||||||
|
var cd = [(c[0] + d[0]) / 2, (c[1] + d[1]) / 2];
|
||||||
|
var cdSrc = this.transformInv_(cd);
|
||||||
|
var da = [(d[0] + a[0]) / 2, (d[1] + a[1]) / 2];
|
||||||
|
var daSrc = this.transformInv_(da);
|
||||||
|
|
||||||
|
this.addQuadIfValid_(a, ab, center, da,
|
||||||
|
aSrc, abSrc, centerSrc, daSrc, maxSubdiv - 1);
|
||||||
|
this.addQuadIfValid_(ab, b, bc, center,
|
||||||
|
abSrc, bSrc, bcSrc, centerSrc, maxSubdiv - 1);
|
||||||
|
this.addQuadIfValid_(center, bc, c, cd,
|
||||||
|
centerSrc, bcSrc, cSrc, cdSrc, maxSubdiv - 1);
|
||||||
|
this.addQuadIfValid_(da, center, cd, d,
|
||||||
|
daSrc, centerSrc, cdSrc, dSrc, maxSubdiv - 1);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return triangulation;
|
this.addTriangle_(a, c, d, aSrc, cSrc, dSrc, wrapsX);
|
||||||
|
this.addTriangle_(a, b, c, aSrc, bSrc, cSrc, wrapsX);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.reproj.Triangulation} triangulation
|
|
||||||
* @param {ol.proj.Projection} sourceProj
|
|
||||||
* @return {ol.Extent}
|
* @return {ol.Extent}
|
||||||
*/
|
*/
|
||||||
ol.reproj.triangulation.getSourceExtent = function(triangulation, sourceProj) {
|
ol.reproj.Triangulation.prototype.calculateSourceExtent = function() {
|
||||||
var extent = ol.extent.createEmpty();
|
var extent = ol.extent.createEmpty();
|
||||||
|
|
||||||
if (triangulation.needsShift) {
|
if (this.needsShift_) {
|
||||||
// although only some of the triangles are crossing the dateline,
|
// although only some of the triangles are crossing the dateline,
|
||||||
// all coordiantes need to be "shifted" to be positive
|
// all coordiantes need to be "shifted" to be positive
|
||||||
// to properly calculate the extent (and then possibly shifted back)
|
// to properly calculate the extent (and then possibly shifted back)
|
||||||
|
|
||||||
var sourceProjExtent = sourceProj.getExtent();
|
goog.array.forEach(this.triangles_, function(triangle, i, arr) {
|
||||||
var sourceProjWidth = ol.extent.getWidth(sourceProjExtent);
|
|
||||||
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], sourceProjWidth), src[0][1]]);
|
[goog.math.modulo(src[0][0], this.sourceWorldWidth_), src[0][1]]);
|
||||||
ol.extent.extendCoordinate(extent,
|
ol.extent.extendCoordinate(extent,
|
||||||
[goog.math.modulo(src[1][0], sourceProjWidth), src[1][1]]);
|
[goog.math.modulo(src[1][0], this.sourceWorldWidth_), src[1][1]]);
|
||||||
ol.extent.extendCoordinate(extent,
|
ol.extent.extendCoordinate(extent,
|
||||||
[goog.math.modulo(src[2][0], sourceProjWidth), src[2][1]]);
|
[goog.math.modulo(src[2][0], this.sourceWorldWidth_), src[2][1]]);
|
||||||
});
|
}, this);
|
||||||
|
|
||||||
|
var sourceProjExtent = this.sourceProj_.getExtent();
|
||||||
var right = sourceProjExtent[2];
|
var right = sourceProjExtent[2];
|
||||||
if (extent[0] > right) extent[0] -= sourceProjWidth;
|
if (extent[0] > right) extent[0] -= this.sourceWorldWidth_;
|
||||||
if (extent[2] > right) extent[2] -= sourceProjWidth;
|
if (extent[2] > right) extent[2] -= this.sourceWorldWidth_;
|
||||||
} else {
|
} else {
|
||||||
goog.array.forEach(triangulation.triangles, function(triangle, i, arr) {
|
goog.array.forEach(this.triangles_, function(triangle, i, arr) {
|
||||||
var src = triangle.source;
|
var src = triangle.source;
|
||||||
ol.extent.extendCoordinate(extent, src[0]);
|
ol.extent.extendCoordinate(extent, src[0]);
|
||||||
ol.extent.extendCoordinate(extent, src[1]);
|
ol.extent.extendCoordinate(extent, src[1]);
|
||||||
@@ -218,3 +246,11 @@ ol.reproj.triangulation.getSourceExtent = function(triangulation, sourceProj) {
|
|||||||
|
|
||||||
return extent;
|
return extent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Array.<ol.reproj.Triangle>}
|
||||||
|
*/
|
||||||
|
ol.reproj.Triangulation.prototype.getTriangles = function() {
|
||||||
|
return this.triangles_;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user