Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed imagery providers whose rectangle crosses the IDL. #2313

Merged
merged 12 commits into from
Dec 9, 2014
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Change Log

* Improved polygon loading performance.
* Added `Math.mod` which computes `m % n` but also works when `m` is negative.
* Fixed imagery providers whose rectangle crosses the IDL. Added `Rectangle.computeWidth`, `Rectangle.computeHeight`, `Rectangle.width`, and `Rectangle.height`. [#2195](https://github.com/AnalyticalGraphicsInc/cesium/issues/2195)

### 1.4 - 2014-12-01

Expand Down
20 changes: 11 additions & 9 deletions Source/Core/GeographicTilingScheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,11 @@ define([
var xTiles = this.getNumberOfXTilesAtLevel(level);
var yTiles = this.getNumberOfYTilesAtLevel(level);

var xTileWidth = (rectangle.east - rectangle.west) / xTiles;
var xTileWidth = rectangle.width / xTiles;
var west = x * xTileWidth + rectangle.west;
var east = (x + 1) * xTileWidth + rectangle.west;

var yTileHeight = (rectangle.north - rectangle.south) / yTiles;
var yTileHeight = rectangle.height / yTiles;
var north = rectangle.north - y * yTileHeight;
var south = rectangle.north - (y + 1) * yTileHeight;

Expand Down Expand Up @@ -207,21 +207,23 @@ define([
*/
GeographicTilingScheme.prototype.positionToTileXY = function(position, level, result) {
var rectangle = this._rectangle;
if (position.latitude > rectangle.north ||
position.latitude < rectangle.south ||
position.longitude < rectangle.west ||
position.longitude > rectangle.east) {
if (!Rectangle.contains(rectangle, position)) {
// outside the bounds of the tiling scheme
return undefined;
}

var xTiles = this.getNumberOfXTilesAtLevel(level);
var yTiles = this.getNumberOfYTilesAtLevel(level);

var xTileWidth = (rectangle.east - rectangle.west) / xTiles;
var yTileHeight = (rectangle.north - rectangle.south) / yTiles;
var xTileWidth = rectangle.width / xTiles;
var yTileHeight = rectangle.height / yTiles;

var xTileCoordinate = (position.longitude - rectangle.west) / xTileWidth | 0;
var longitude = position.longitude;
if (rectangle.east < rectangle.west) {
longitude += CesiumMath.TWO_PI;
}

var xTileCoordinate = (longitude - rectangle.west) / xTileWidth | 0;
if (xTileCoordinate >= xTiles) {
xTileCoordinate = xTiles - 1;
}
Expand Down
10 changes: 6 additions & 4 deletions Source/Core/HeightmapTessellator.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ define([
'./DeveloperError',
'./Ellipsoid',
'./freezeObject',
'./Math'
'./Math',
'./Rectangle'
], function(
Cartesian3,
defaultValue,
defined,
DeveloperError,
Ellipsoid,
freezeObject,
CesiumMath) {
CesiumMath,
Rectangle) {
"use strict";

/**
Expand Down Expand Up @@ -186,8 +188,8 @@ define([
var elementMultiplier = defaultValue(structure.elementMultiplier, HeightmapTessellator.DEFAULT_STRUCTURE.elementMultiplier);
var isBigEndian = defaultValue(structure.isBigEndian, HeightmapTessellator.DEFAULT_STRUCTURE.isBigEndian);

var granularityX = (nativeRectangle.east - nativeRectangle.west) / (width - 1);
var granularityY = (nativeRectangle.north - nativeRectangle.south) / (height - 1);
var granularityX = Rectangle.computeWidth(nativeRectangle) / (width - 1);
var granularityY = Rectangle.computeHeight(nativeRectangle) / (height - 1);

var radiiSquared = ellipsoid.radiiSquared;
var radiiSquaredX = radiiSquared.x;
Expand Down
6 changes: 5 additions & 1 deletion Source/Core/Math.js
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,11 @@ define([
throw new DeveloperError('x is required.');
}
//>>includeEnd('debug');
return CesiumMath.mod(x, CesiumMath.TWO_PI);
var mod = CesiumMath.mod(x, CesiumMath.TWO_PI);
if (mod === 0.0 && x !== 0.0) {
return CesiumMath.sign(x) * CesiumMath.TWO_PI;
}
return mod;
};

/**
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/QuantizedMeshTerrainData.js
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,9 @@ define([
* the rectangle, so expect incorrect results for positions far outside the rectangle.
*/
QuantizedMeshTerrainData.prototype.interpolateHeight = function(rectangle, longitude, latitude) {
var u = CesiumMath.clamp((longitude - rectangle.west) / (rectangle.east - rectangle.west), 0.0, 1.0);
var u = CesiumMath.clamp((longitude - rectangle.west) / rectangle.width, 0.0, 1.0);
u *= maxShort;
var v = CesiumMath.clamp((latitude - rectangle.south) / (rectangle.north - rectangle.south), 0.0, 1.0);
var v = CesiumMath.clamp((latitude - rectangle.south) / rectangle.height, 0.0, 1.0);
v *= maxShort;

var uBuffer = this._uValues;
Expand Down
141 changes: 112 additions & 29 deletions Source/Core/Rectangle.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ define([
'./Cartographic',
'./defaultValue',
'./defined',
'./defineProperties',
'./DeveloperError',
'./Ellipsoid',
'./freezeObject',
Expand All @@ -11,6 +12,7 @@ define([
Cartographic,
defaultValue,
defined,
defineProperties,
DeveloperError,
Ellipsoid,
freezeObject,
Expand Down Expand Up @@ -64,6 +66,63 @@ define([
this.north = defaultValue(north, 0.0);
};

defineProperties(Rectangle.prototype, {
/**
* Gets the width of the rectangle in radians.
* @memberof Rectangle.prototype
* @type {Number}
*/
width : {
get : function() {
return Rectangle.computeWidth(this);
}
},

/**
* Gets the height of the rectangle in radians.
* @memberof Rectangle.prototype
* @type {Number}
*/
height : {
get : function() {
return Rectangle.computeHeight(this);
}
}
});

/**
* Computes the width of a rectangle in radians.
* @param {Rectangle} rectangle The rectangle to compute the width of.
* @returns {Number} The width.
*/
Rectangle.computeWidth = function(rectangle) {
//>>includeStart('debug', pragmas.debug);
if (!defined(rectangle)) {
throw new DeveloperError('rectangle is required.');
}
//>>includeEnd('debug');
var east = rectangle.east;
var west = rectangle.west;
if (east < west) {
east += CesiumMath.TWO_PI;
}
return east - west;
};

/**
* Computes the height of a rectangle in radians.
* @param {Rectangle} rectangle The rectangle to compute the height of.
* @returns {Number} The height.
*/
Rectangle.computeHeight = function(rectangle) {
//>>includeStart('debug', pragmas.debug);
if (!defined(rectangle)) {
throw new DeveloperError('rectangle is required.');
}
//>>includeEnd('debug');
return rectangle.north - rectangle.south;
};

/**
* Creates an rectangle given the boundary longitude and latitude in degrees.
*
Expand Down Expand Up @@ -439,17 +498,19 @@ define([
var east = rectangle.east;
var west = rectangle.west;

var longitude = (west + east) * 0.5;
if (east < west) {
longitude = CesiumMath.negativePiToPi(longitude + CesiumMath.PI);
east += CesiumMath.TWO_PI;
}

var longitude = CesiumMath.negativePiToPi((west + east) * 0.5);
var latitude = (rectangle.south + rectangle.north) * 0.5;

if (!defined(result)) {
return new Cartographic(longitude, (rectangle.south + rectangle.north) * 0.5);
return new Cartographic(longitude, latitude);
}

result.longitude = longitude;
result.latitude = (rectangle.south + rectangle.north) * 0.5;
result.latitude = latitude;
result.height = 0.0;
return result;
};
Expand All @@ -460,7 +521,7 @@ define([
* @param {Rectangle} rectangle On rectangle to find an intersection
* @param {Rectangle} otherRectangle Another rectangle to find an intersection
* @param {Rectangle} [result] The object onto which to store the result.
* @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided.
* @returns {Rectangle|undefined} The modified result parameter, a new Rectangle instance if none was provided or undefined if there is no intersection.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically a breaking change, but I don't think it is an issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, actually we should deprecate this (one release before removal is fine) and replace it with a function with a new name.

*/
Rectangle.intersectWith = function(rectangle, otherRectangle, result) {
//>>includeStart('debug', pragmas.debug);
Expand All @@ -472,10 +533,38 @@ define([
}
//>>includeEnd('debug');

var west = Math.max(rectangle.west, otherRectangle.west);
var rectangleEast = rectangle.east;
var rectangleWest = rectangle.west;

var otherRectangleEast = otherRectangle.east;
var otherRectangleWest = otherRectangle.west;

if (rectangleEast < rectangleWest && otherRectangleEast > 0.0) {
rectangleEast += CesiumMath.TWO_PI;
} else if (otherRectangleEast < otherRectangleWest && rectangleEast > 0.0) {
otherRectangleEast += CesiumMath.TWO_PI;
}

if (rectangleEast < rectangleWest && otherRectangleWest < 0.0) {
otherRectangleWest += CesiumMath.TWO_PI;
} else if (otherRectangleEast < otherRectangleWest && rectangleWest < 0.0) {
rectangleWest += CesiumMath.TWO_PI;
}

var west = CesiumMath.negativePiToPi(Math.max(rectangleWest, otherRectangleWest));
var east = CesiumMath.negativePiToPi(Math.min(rectangleEast, otherRectangleEast));

if ((rectangle.west < rectangle.east || otherRectangle.west < otherRectangle.east) && east <= west) {
return undefined;
}

var south = Math.max(rectangle.south, otherRectangle.south);
var east = Math.min(rectangle.east, otherRectangle.east);
var north = Math.min(rectangle.north, otherRectangle.north);

if (south >= north) {
return undefined;
}

if (!defined(result)) {
return new Rectangle(west, south, east, north);
}
Expand Down Expand Up @@ -503,27 +592,22 @@ define([
}
//>>includeEnd('debug');

return cartographic.longitude >= rectangle.west &&
cartographic.longitude <= rectangle.east &&
cartographic.latitude >= rectangle.south &&
cartographic.latitude <= rectangle.north;
};
var longitude = cartographic.longitude;
var latitude = cartographic.latitude;

/**
* Determines if the rectangle is empty, i.e., if <code>west >= east</code>
* or <code>south >= north</code>.
*
* @param {Rectangle} rectangle The rectangle
* @returns {Boolean} True if the rectangle is empty; otherwise, false.
*/
Rectangle.isEmpty = function(rectangle) {
//>>includeStart('debug', pragmas.debug);
if (!defined(rectangle)) {
throw new DeveloperError('rectangle is required');
}
//>>includeEnd('debug');
var west = rectangle.west;
var east = rectangle.east;

return rectangle.west >= rectangle.east || rectangle.south >= rectangle.north;
if (east < west) {
east += CesiumMath.TWO_PI;
if (longitude < 0.0) {
longitude += CesiumMath.TWO_PI;
}
}
return (longitude > west || CesiumMath.equalsEpsilon(longitude, west, CesiumMath.EPSILON14)) &&
(longitude < east || CesiumMath.equalsEpsilon(longitude, east, CesiumMath.EPSILON14)) &&
latitude >= rectangle.south &&
latitude <= rectangle.north;
};

var subsampleLlaScratch = new Cartographic();
Expand Down Expand Up @@ -587,9 +671,8 @@ define([
}

for ( var i = 1; i < 8; ++i) {
var temp = -Math.PI + i * CesiumMath.PI_OVER_TWO;
if (west < temp && temp < east) {
lla.longitude = temp;
lla.longitude = -Math.PI + i * CesiumMath.PI_OVER_TWO;
if (Rectangle.contains(rectangle, lla)) {
result[length] = ellipsoid.cartographicToCartesian(lla, result[length]);
length++;
}
Expand Down
5 changes: 2 additions & 3 deletions Source/Core/RectangleGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,6 @@ define([
* @exception {DeveloperError} <code>options.rectangle.east</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>].
* @exception {DeveloperError} <code>options.rectangle.west</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>].
* @exception {DeveloperError} <code>options.rectangle.north</code> must be greater than <code>options.rectangle.south</code>.
* @exception {DeveloperError} <code>options.rectangle.east</code> must be greater than <code>options.rectangle.west</code>.
*
* @see RectangleGeometry#createGeometry
*
Expand Down Expand Up @@ -616,8 +615,8 @@ define([
Matrix3.clone(Matrix3.IDENTITY, tangentRotationMatrix);
}

options.lonScalar = 1.0 / (rectangle.east - rectangle.west);
options.latScalar = 1.0 / (rectangle.north - rectangle.south);
options.lonScalar = 1.0 / rectangle.width;
options.latScalar = 1.0 / rectangle.height;
options.vertexFormat = vertexFormat;
options.textureMatrix = textureMatrix;
options.tangentRotationMatrix = tangentRotationMatrix;
Expand Down
1 change: 0 additions & 1 deletion Source/Core/RectangleOutlineGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ define([
* @exception {DeveloperError} <code>options.rectangle.east</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>].
* @exception {DeveloperError} <code>options.rectangle.west</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>].
* @exception {DeveloperError} <code>options.rectangle.north</code> must be greater than <code>rectangle.south</code>.
* @exception {DeveloperError} <code>options.rectangle.east</code> must be greater than <code>rectangle.west</code>.
*
* @see RectangleOutlineGeometry#createGeometry
*
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/VRTheWorldTerrainProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ define([
var testRectangle = rectangle.rectangle;

var intersection = Rectangle.intersectWith(testRectangle, parentRectangle, rectangleScratch);
if (!Rectangle.isEmpty(intersection)) {
if (defined(intersection)) {
// Parent tile is inside this rectangle, so at least one child is, too.
if (isTileInRectangle(tilingScheme, testRectangle, x * 2, y * 2, level + 1)) {
childMask |= 4; // northwest
Expand All @@ -332,7 +332,7 @@ define([

function isTileInRectangle(tilingScheme, rectangle, x, y, level) {
var tileRectangle = tilingScheme.tileXYToRectangle(x, y, level);
return !Rectangle.isEmpty(Rectangle.intersectWith(tileRectangle, rectangle, rectangleScratch));
return defined(Rectangle.intersectWith(tileRectangle, rectangle, rectangleScratch));
}

/**
Expand Down
5 changes: 1 addition & 4 deletions Source/Core/WebMercatorTilingScheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,7 @@ define([
*/
WebMercatorTilingScheme.prototype.positionToTileXY = function(position, level, result) {
var rectangle = this._rectangle;
if (position.latitude > rectangle.north ||
position.latitude < rectangle.south ||
position.longitude < rectangle.west ||
position.longitude > rectangle.east) {
if (!Rectangle.contains(rectangle, position)) {
// outside the bounds of the tiling scheme
return undefined;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Scene/BingMapsImageryProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ define([
var area = coverageAreas[areaIndex];
if (level >= area.zoomMin && level <= area.zoomMax) {
var intersection = Rectangle.intersectWith(rectangle, area.bbox, intersectionScratch);
if (!Rectangle.isEmpty(intersection)) {
if (defined(intersection)) {
included = true;
}
}
Expand Down
8 changes: 4 additions & 4 deletions Source/Scene/GlobeSurfaceTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -733,11 +733,11 @@ define([
// Compute the water mask translation and scale
var sourceTileRectangle = sourceTile.rectangle;
var tileRectangle = tile.rectangle;
var tileWidth = tileRectangle.east - tileRectangle.west;
var tileHeight = tileRectangle.north - tileRectangle.south;
var tileWidth = tileRectangle.width;
var tileHeight = tileRectangle.height;

var scaleX = tileWidth / (sourceTileRectangle.east - sourceTileRectangle.west);
var scaleY = tileHeight / (sourceTileRectangle.north - sourceTileRectangle.south);
var scaleX = tileWidth / sourceTileRectangle.width;
var scaleY = tileHeight / sourceTileRectangle.height;
surfaceTile.waterMaskTranslationAndScale.x = scaleX * (tileRectangle.west - sourceTileRectangle.west) / tileWidth;
surfaceTile.waterMaskTranslationAndScale.y = scaleY * (tileRectangle.south - sourceTileRectangle.south) / tileHeight;
surfaceTile.waterMaskTranslationAndScale.z = scaleX;
Expand Down
Loading