You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
7.4 KiB
JavaScript
285 lines
7.4 KiB
JavaScript
import Cartesian3 from "./Cartesian3.js";
|
|
import Cartographic from "./Cartographic.js";
|
|
import defined from "./defined.js";
|
|
import DeveloperError from "./DeveloperError.js";
|
|
import GeographicProjection from "./GeographicProjection.js";
|
|
import CesiumMath from "./Math.js";
|
|
import Matrix2 from "./Matrix2.js";
|
|
import Rectangle from "./Rectangle.js";
|
|
|
|
var cos = Math.cos;
|
|
var sin = Math.sin;
|
|
var sqrt = Math.sqrt;
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
var RectangleGeometryLibrary = {};
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
RectangleGeometryLibrary.computePosition = function (
|
|
computedOptions,
|
|
ellipsoid,
|
|
computeST,
|
|
row,
|
|
col,
|
|
position,
|
|
st
|
|
) {
|
|
var radiiSquared = ellipsoid.radiiSquared;
|
|
var nwCorner = computedOptions.nwCorner;
|
|
var rectangle = computedOptions.boundingRectangle;
|
|
|
|
var stLatitude =
|
|
nwCorner.latitude -
|
|
computedOptions.granYCos * row +
|
|
col * computedOptions.granXSin;
|
|
var cosLatitude = cos(stLatitude);
|
|
var nZ = sin(stLatitude);
|
|
var kZ = radiiSquared.z * nZ;
|
|
|
|
var stLongitude =
|
|
nwCorner.longitude +
|
|
row * computedOptions.granYSin +
|
|
col * computedOptions.granXCos;
|
|
var nX = cosLatitude * cos(stLongitude);
|
|
var nY = cosLatitude * sin(stLongitude);
|
|
|
|
var kX = radiiSquared.x * nX;
|
|
var kY = radiiSquared.y * nY;
|
|
|
|
var gamma = sqrt(kX * nX + kY * nY + kZ * nZ);
|
|
|
|
position.x = kX / gamma;
|
|
position.y = kY / gamma;
|
|
position.z = kZ / gamma;
|
|
|
|
if (computeST) {
|
|
var stNwCorner = computedOptions.stNwCorner;
|
|
if (defined(stNwCorner)) {
|
|
stLatitude =
|
|
stNwCorner.latitude -
|
|
computedOptions.stGranYCos * row +
|
|
col * computedOptions.stGranXSin;
|
|
stLongitude =
|
|
stNwCorner.longitude +
|
|
row * computedOptions.stGranYSin +
|
|
col * computedOptions.stGranXCos;
|
|
|
|
st.x = (stLongitude - computedOptions.stWest) * computedOptions.lonScalar;
|
|
st.y = (stLatitude - computedOptions.stSouth) * computedOptions.latScalar;
|
|
} else {
|
|
st.x = (stLongitude - rectangle.west) * computedOptions.lonScalar;
|
|
st.y = (stLatitude - rectangle.south) * computedOptions.latScalar;
|
|
}
|
|
}
|
|
};
|
|
|
|
var rotationMatrixScratch = new Matrix2();
|
|
var nwCartesian = new Cartesian3();
|
|
var centerScratch = new Cartographic();
|
|
var centerCartesian = new Cartesian3();
|
|
var proj = new GeographicProjection();
|
|
|
|
function getRotationOptions(
|
|
nwCorner,
|
|
rotation,
|
|
granularityX,
|
|
granularityY,
|
|
center,
|
|
width,
|
|
height
|
|
) {
|
|
var cosRotation = Math.cos(rotation);
|
|
var granYCos = granularityY * cosRotation;
|
|
var granXCos = granularityX * cosRotation;
|
|
|
|
var sinRotation = Math.sin(rotation);
|
|
var granYSin = granularityY * sinRotation;
|
|
var granXSin = granularityX * sinRotation;
|
|
|
|
nwCartesian = proj.project(nwCorner, nwCartesian);
|
|
|
|
nwCartesian = Cartesian3.subtract(nwCartesian, centerCartesian, nwCartesian);
|
|
var rotationMatrix = Matrix2.fromRotation(rotation, rotationMatrixScratch);
|
|
nwCartesian = Matrix2.multiplyByVector(
|
|
rotationMatrix,
|
|
nwCartesian,
|
|
nwCartesian
|
|
);
|
|
nwCartesian = Cartesian3.add(nwCartesian, centerCartesian, nwCartesian);
|
|
nwCorner = proj.unproject(nwCartesian, nwCorner);
|
|
|
|
width -= 1;
|
|
height -= 1;
|
|
|
|
var latitude = nwCorner.latitude;
|
|
var latitude0 = latitude + width * granXSin;
|
|
var latitude1 = latitude - granYCos * height;
|
|
var latitude2 = latitude - granYCos * height + width * granXSin;
|
|
|
|
var north = Math.max(latitude, latitude0, latitude1, latitude2);
|
|
var south = Math.min(latitude, latitude0, latitude1, latitude2);
|
|
|
|
var longitude = nwCorner.longitude;
|
|
var longitude0 = longitude + width * granXCos;
|
|
var longitude1 = longitude + height * granYSin;
|
|
var longitude2 = longitude + height * granYSin + width * granXCos;
|
|
|
|
var east = Math.max(longitude, longitude0, longitude1, longitude2);
|
|
var west = Math.min(longitude, longitude0, longitude1, longitude2);
|
|
|
|
return {
|
|
north: north,
|
|
south: south,
|
|
east: east,
|
|
west: west,
|
|
granYCos: granYCos,
|
|
granYSin: granYSin,
|
|
granXCos: granXCos,
|
|
granXSin: granXSin,
|
|
nwCorner: nwCorner,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
RectangleGeometryLibrary.computeOptions = function (
|
|
rectangle,
|
|
granularity,
|
|
rotation,
|
|
stRotation,
|
|
boundingRectangleScratch,
|
|
nwCornerResult,
|
|
stNwCornerResult
|
|
) {
|
|
var east = rectangle.east;
|
|
var west = rectangle.west;
|
|
var north = rectangle.north;
|
|
var south = rectangle.south;
|
|
|
|
var northCap = false;
|
|
var southCap = false;
|
|
|
|
if (north === CesiumMath.PI_OVER_TWO) {
|
|
northCap = true;
|
|
}
|
|
if (south === -CesiumMath.PI_OVER_TWO) {
|
|
southCap = true;
|
|
}
|
|
|
|
var width;
|
|
var height;
|
|
var granularityX;
|
|
var granularityY;
|
|
var dx;
|
|
var dy = north - south;
|
|
if (west > east) {
|
|
dx = CesiumMath.TWO_PI - west + east;
|
|
} else {
|
|
dx = east - west;
|
|
}
|
|
|
|
width = Math.ceil(dx / granularity) + 1;
|
|
height = Math.ceil(dy / granularity) + 1;
|
|
granularityX = dx / (width - 1);
|
|
granularityY = dy / (height - 1);
|
|
|
|
var nwCorner = Rectangle.northwest(rectangle, nwCornerResult);
|
|
var center = Rectangle.center(rectangle, centerScratch);
|
|
if (rotation !== 0 || stRotation !== 0) {
|
|
if (center.longitude < nwCorner.longitude) {
|
|
center.longitude += CesiumMath.TWO_PI;
|
|
}
|
|
centerCartesian = proj.project(center, centerCartesian);
|
|
}
|
|
|
|
var granYCos = granularityY;
|
|
var granXCos = granularityX;
|
|
var granYSin = 0.0;
|
|
var granXSin = 0.0;
|
|
|
|
var boundingRectangle = Rectangle.clone(rectangle, boundingRectangleScratch);
|
|
|
|
var computedOptions = {
|
|
granYCos: granYCos,
|
|
granYSin: granYSin,
|
|
granXCos: granXCos,
|
|
granXSin: granXSin,
|
|
nwCorner: nwCorner,
|
|
boundingRectangle: boundingRectangle,
|
|
width: width,
|
|
height: height,
|
|
northCap: northCap,
|
|
southCap: southCap,
|
|
};
|
|
|
|
if (rotation !== 0) {
|
|
var rotationOptions = getRotationOptions(
|
|
nwCorner,
|
|
rotation,
|
|
granularityX,
|
|
granularityY,
|
|
center,
|
|
width,
|
|
height
|
|
);
|
|
north = rotationOptions.north;
|
|
south = rotationOptions.south;
|
|
east = rotationOptions.east;
|
|
west = rotationOptions.west;
|
|
|
|
//>>includeStart('debug', pragmas.debug);
|
|
if (
|
|
north < -CesiumMath.PI_OVER_TWO ||
|
|
north > CesiumMath.PI_OVER_TWO ||
|
|
south < -CesiumMath.PI_OVER_TWO ||
|
|
south > CesiumMath.PI_OVER_TWO
|
|
) {
|
|
throw new DeveloperError(
|
|
"Rotated rectangle is invalid. It crosses over either the north or south pole."
|
|
);
|
|
}
|
|
//>>includeEnd('debug')
|
|
|
|
computedOptions.granYCos = rotationOptions.granYCos;
|
|
computedOptions.granYSin = rotationOptions.granYSin;
|
|
computedOptions.granXCos = rotationOptions.granXCos;
|
|
computedOptions.granXSin = rotationOptions.granXSin;
|
|
|
|
boundingRectangle.north = north;
|
|
boundingRectangle.south = south;
|
|
boundingRectangle.east = east;
|
|
boundingRectangle.west = west;
|
|
}
|
|
|
|
if (stRotation !== 0) {
|
|
rotation = rotation - stRotation;
|
|
var stNwCorner = Rectangle.northwest(boundingRectangle, stNwCornerResult);
|
|
|
|
var stRotationOptions = getRotationOptions(
|
|
stNwCorner,
|
|
rotation,
|
|
granularityX,
|
|
granularityY,
|
|
center,
|
|
width,
|
|
height
|
|
);
|
|
|
|
computedOptions.stGranYCos = stRotationOptions.granYCos;
|
|
computedOptions.stGranXCos = stRotationOptions.granXCos;
|
|
computedOptions.stGranYSin = stRotationOptions.granYSin;
|
|
computedOptions.stGranXSin = stRotationOptions.granXSin;
|
|
computedOptions.stNwCorner = stNwCorner;
|
|
computedOptions.stWest = stRotationOptions.west;
|
|
computedOptions.stSouth = stRotationOptions.south;
|
|
}
|
|
|
|
return computedOptions;
|
|
};
|
|
export default RectangleGeometryLibrary;
|