RectangleGeometryLibrary.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import Cartesian3 from './Cartesian3.js';
  2. import Cartographic from './Cartographic.js';
  3. import defined from './defined.js';
  4. import DeveloperError from './DeveloperError.js';
  5. import GeographicProjection from './GeographicProjection.js';
  6. import CesiumMath from './Math.js';
  7. import Matrix2 from './Matrix2.js';
  8. import Rectangle from './Rectangle.js';
  9. var cos = Math.cos;
  10. var sin = Math.sin;
  11. var sqrt = Math.sqrt;
  12. /**
  13. * @private
  14. */
  15. var RectangleGeometryLibrary = {};
  16. /**
  17. * @private
  18. */
  19. RectangleGeometryLibrary.computePosition = function(computedOptions, ellipsoid, computeST, row, col, position, st) {
  20. var radiiSquared = ellipsoid.radiiSquared;
  21. var nwCorner = computedOptions.nwCorner;
  22. var rectangle = computedOptions.boundingRectangle;
  23. var stLatitude = nwCorner.latitude - computedOptions.granYCos * row + col * computedOptions.granXSin;
  24. var cosLatitude = cos(stLatitude);
  25. var nZ = sin(stLatitude);
  26. var kZ = radiiSquared.z * nZ;
  27. var stLongitude = nwCorner.longitude + row * computedOptions.granYSin + col * computedOptions.granXCos;
  28. var nX = cosLatitude * cos(stLongitude);
  29. var nY = cosLatitude * sin(stLongitude);
  30. var kX = radiiSquared.x * nX;
  31. var kY = radiiSquared.y * nY;
  32. var gamma = sqrt((kX * nX) + (kY * nY) + (kZ * nZ));
  33. position.x = kX / gamma;
  34. position.y = kY / gamma;
  35. position.z = kZ / gamma;
  36. if (computeST) {
  37. var stNwCorner = computedOptions.stNwCorner;
  38. if (defined(stNwCorner)) {
  39. stLatitude = stNwCorner.latitude - computedOptions.stGranYCos * row + col * computedOptions.stGranXSin;
  40. stLongitude = stNwCorner.longitude + row * computedOptions.stGranYSin + col * computedOptions.stGranXCos;
  41. st.x = (stLongitude - computedOptions.stWest) * computedOptions.lonScalar;
  42. st.y = (stLatitude - computedOptions.stSouth) * computedOptions.latScalar;
  43. } else {
  44. st.x = (stLongitude - rectangle.west) * computedOptions.lonScalar;
  45. st.y = (stLatitude - rectangle.south) * computedOptions.latScalar;
  46. }
  47. }
  48. };
  49. var rotationMatrixScratch = new Matrix2();
  50. var nwCartesian = new Cartesian3();
  51. var centerScratch = new Cartographic();
  52. var centerCartesian = new Cartesian3();
  53. var proj = new GeographicProjection();
  54. function getRotationOptions(nwCorner, rotation, granularityX, granularityY, center, width, height) {
  55. var cosRotation = Math.cos(rotation);
  56. var granYCos = granularityY * cosRotation;
  57. var granXCos = granularityX * cosRotation;
  58. var sinRotation = Math.sin(rotation);
  59. var granYSin = granularityY * sinRotation;
  60. var granXSin = granularityX * sinRotation;
  61. nwCartesian = proj.project(nwCorner, nwCartesian);
  62. nwCartesian = Cartesian3.subtract(nwCartesian, centerCartesian, nwCartesian);
  63. var rotationMatrix = Matrix2.fromRotation(rotation, rotationMatrixScratch);
  64. nwCartesian = Matrix2.multiplyByVector(rotationMatrix, nwCartesian, nwCartesian);
  65. nwCartesian = Cartesian3.add(nwCartesian, centerCartesian, nwCartesian);
  66. nwCorner = proj.unproject(nwCartesian, nwCorner);
  67. width -= 1;
  68. height -= 1;
  69. var latitude = nwCorner.latitude;
  70. var latitude0 = latitude + width * granXSin;
  71. var latitude1 = latitude - granYCos * height;
  72. var latitude2 = latitude - granYCos * height + width * granXSin;
  73. var north = Math.max(latitude, latitude0, latitude1, latitude2);
  74. var south = Math.min(latitude, latitude0, latitude1, latitude2);
  75. var longitude = nwCorner.longitude;
  76. var longitude0 = longitude + width * granXCos;
  77. var longitude1 = longitude + height * granYSin;
  78. var longitude2 = longitude + height * granYSin + width * granXCos;
  79. var east = Math.max(longitude, longitude0, longitude1, longitude2);
  80. var west = Math.min(longitude, longitude0, longitude1, longitude2);
  81. return {
  82. north: north,
  83. south: south,
  84. east: east,
  85. west: west,
  86. granYCos : granYCos,
  87. granYSin : granYSin,
  88. granXCos : granXCos,
  89. granXSin : granXSin,
  90. nwCorner : nwCorner
  91. };
  92. }
  93. /**
  94. * @private
  95. */
  96. RectangleGeometryLibrary.computeOptions = function(rectangle, granularity, rotation, stRotation, boundingRectangleScratch, nwCornerResult, stNwCornerResult) {
  97. var east = rectangle.east;
  98. var west = rectangle.west;
  99. var north = rectangle.north;
  100. var south = rectangle.south;
  101. var northCap = false;
  102. var southCap = false;
  103. if (north === CesiumMath.PI_OVER_TWO) {
  104. northCap = true;
  105. }
  106. if (south === -CesiumMath.PI_OVER_TWO) {
  107. southCap = true;
  108. }
  109. var width;
  110. var height;
  111. var granularityX;
  112. var granularityY;
  113. var dx;
  114. var dy = north - south;
  115. if (west > east) {
  116. dx = (CesiumMath.TWO_PI - west + east);
  117. } else {
  118. dx = east - west;
  119. }
  120. width = Math.ceil(dx / granularity) + 1;
  121. height = Math.ceil(dy / granularity) + 1;
  122. granularityX = dx / (width - 1);
  123. granularityY = dy / (height - 1);
  124. var nwCorner = Rectangle.northwest(rectangle, nwCornerResult);
  125. var center = Rectangle.center(rectangle, centerScratch);
  126. if (rotation !== 0 || stRotation !== 0) {
  127. if (center.longitude < nwCorner.longitude) {
  128. center.longitude += CesiumMath.TWO_PI;
  129. }
  130. centerCartesian = proj.project(center, centerCartesian);
  131. }
  132. var granYCos = granularityY;
  133. var granXCos = granularityX;
  134. var granYSin = 0.0;
  135. var granXSin = 0.0;
  136. var boundingRectangle = Rectangle.clone(rectangle, boundingRectangleScratch);
  137. var computedOptions = {
  138. granYCos : granYCos,
  139. granYSin : granYSin,
  140. granXCos : granXCos,
  141. granXSin : granXSin,
  142. nwCorner : nwCorner,
  143. boundingRectangle : boundingRectangle,
  144. width: width,
  145. height: height,
  146. northCap: northCap,
  147. southCap: southCap
  148. };
  149. if (rotation !== 0) {
  150. var rotationOptions = getRotationOptions(nwCorner, rotation, granularityX, granularityY, center, width, height);
  151. north = rotationOptions.north;
  152. south = rotationOptions.south;
  153. east = rotationOptions.east;
  154. west = rotationOptions.west;
  155. //>>includeStart('debug', pragmas.debug);
  156. if (north < -CesiumMath.PI_OVER_TWO || north > CesiumMath.PI_OVER_TWO ||
  157. south < -CesiumMath.PI_OVER_TWO || south > CesiumMath.PI_OVER_TWO) {
  158. throw new DeveloperError('Rotated rectangle is invalid. It crosses over either the north or south pole.');
  159. }
  160. //>>includeEnd('debug')
  161. computedOptions.granYCos = rotationOptions.granYCos;
  162. computedOptions.granYSin = rotationOptions.granYSin;
  163. computedOptions.granXCos = rotationOptions.granXCos;
  164. computedOptions.granXSin = rotationOptions.granXSin;
  165. boundingRectangle.north = north;
  166. boundingRectangle.south = south;
  167. boundingRectangle.east = east;
  168. boundingRectangle.west = west;
  169. }
  170. if (stRotation !== 0) {
  171. rotation = rotation - stRotation;
  172. var stNwCorner = Rectangle.northwest(boundingRectangle, stNwCornerResult);
  173. var stRotationOptions = getRotationOptions(stNwCorner, rotation, granularityX, granularityY, center, width, height);
  174. computedOptions.stGranYCos = stRotationOptions.granYCos;
  175. computedOptions.stGranXCos = stRotationOptions.granXCos;
  176. computedOptions.stGranYSin = stRotationOptions.granYSin;
  177. computedOptions.stGranXSin = stRotationOptions.granXSin;
  178. computedOptions.stNwCorner = stNwCorner;
  179. computedOptions.stWest = stRotationOptions.west;
  180. computedOptions.stSouth = stRotationOptions.south;
  181. }
  182. return computedOptions;
  183. };
  184. export default RectangleGeometryLibrary;