createVectorTilePolylines.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. import AttributeCompression from "../Core/AttributeCompression.js";
  2. import Cartesian3 from "../Core/Cartesian3.js";
  3. import Cartographic from "../Core/Cartographic.js";
  4. import Ellipsoid from "../Core/Ellipsoid.js";
  5. import IndexDatatype from "../Core/IndexDatatype.js";
  6. import CesiumMath from "../Core/Math.js";
  7. import Rectangle from "../Core/Rectangle.js";
  8. import createTaskProcessorWorker from "./createTaskProcessorWorker.js";
  9. var maxShort = 32767;
  10. var scratchBVCartographic = new Cartographic();
  11. var scratchEncodedPosition = new Cartesian3();
  12. function decodePositions(
  13. positions,
  14. rectangle,
  15. minimumHeight,
  16. maximumHeight,
  17. ellipsoid
  18. ) {
  19. var positionsLength = positions.length / 3;
  20. var uBuffer = positions.subarray(0, positionsLength);
  21. var vBuffer = positions.subarray(positionsLength, 2 * positionsLength);
  22. var heightBuffer = positions.subarray(
  23. 2 * positionsLength,
  24. 3 * positionsLength
  25. );
  26. AttributeCompression.zigZagDeltaDecode(uBuffer, vBuffer, heightBuffer);
  27. var decoded = new Float64Array(positions.length);
  28. for (var i = 0; i < positionsLength; ++i) {
  29. var u = uBuffer[i];
  30. var v = vBuffer[i];
  31. var h = heightBuffer[i];
  32. var lon = CesiumMath.lerp(rectangle.west, rectangle.east, u / maxShort);
  33. var lat = CesiumMath.lerp(rectangle.south, rectangle.north, v / maxShort);
  34. var alt = CesiumMath.lerp(minimumHeight, maximumHeight, h / maxShort);
  35. var cartographic = Cartographic.fromRadians(
  36. lon,
  37. lat,
  38. alt,
  39. scratchBVCartographic
  40. );
  41. var decodedPosition = ellipsoid.cartographicToCartesian(
  42. cartographic,
  43. scratchEncodedPosition
  44. );
  45. Cartesian3.pack(decodedPosition, decoded, i * 3);
  46. }
  47. return decoded;
  48. }
  49. var scratchRectangle = new Rectangle();
  50. var scratchEllipsoid = new Ellipsoid();
  51. var scratchCenter = new Cartesian3();
  52. var scratchMinMaxHeights = {
  53. min: undefined,
  54. max: undefined,
  55. };
  56. function unpackBuffer(packedBuffer) {
  57. packedBuffer = new Float64Array(packedBuffer);
  58. var offset = 0;
  59. scratchMinMaxHeights.min = packedBuffer[offset++];
  60. scratchMinMaxHeights.max = packedBuffer[offset++];
  61. Rectangle.unpack(packedBuffer, offset, scratchRectangle);
  62. offset += Rectangle.packedLength;
  63. Ellipsoid.unpack(packedBuffer, offset, scratchEllipsoid);
  64. offset += Ellipsoid.packedLength;
  65. Cartesian3.unpack(packedBuffer, offset, scratchCenter);
  66. }
  67. var scratchP0 = new Cartesian3();
  68. var scratchP1 = new Cartesian3();
  69. var scratchPrev = new Cartesian3();
  70. var scratchCur = new Cartesian3();
  71. var scratchNext = new Cartesian3();
  72. function createVectorTilePolylines(parameters, transferableObjects) {
  73. var encodedPositions = new Uint16Array(parameters.positions);
  74. var widths = new Uint16Array(parameters.widths);
  75. var counts = new Uint32Array(parameters.counts);
  76. var batchIds = new Uint16Array(parameters.batchIds);
  77. unpackBuffer(parameters.packedBuffer);
  78. var rectangle = scratchRectangle;
  79. var ellipsoid = scratchEllipsoid;
  80. var center = scratchCenter;
  81. var minimumHeight = scratchMinMaxHeights.min;
  82. var maximumHeight = scratchMinMaxHeights.max;
  83. var positions = decodePositions(
  84. encodedPositions,
  85. rectangle,
  86. minimumHeight,
  87. maximumHeight,
  88. ellipsoid
  89. );
  90. var positionsLength = positions.length / 3;
  91. var size = positionsLength * 4 - 4;
  92. var curPositions = new Float32Array(size * 3);
  93. var prevPositions = new Float32Array(size * 3);
  94. var nextPositions = new Float32Array(size * 3);
  95. var expandAndWidth = new Float32Array(size * 2);
  96. var vertexBatchIds = new Uint16Array(size);
  97. var positionIndex = 0;
  98. var expandAndWidthIndex = 0;
  99. var batchIdIndex = 0;
  100. var i;
  101. var offset = 0;
  102. var length = counts.length;
  103. for (i = 0; i < length; ++i) {
  104. var count = counts[i];
  105. var width = widths[i];
  106. var batchId = batchIds[i];
  107. for (var j = 0; j < count; ++j) {
  108. var previous;
  109. if (j === 0) {
  110. var p0 = Cartesian3.unpack(positions, offset * 3, scratchP0);
  111. var p1 = Cartesian3.unpack(positions, (offset + 1) * 3, scratchP1);
  112. previous = Cartesian3.subtract(p0, p1, scratchPrev);
  113. Cartesian3.add(p0, previous, previous);
  114. } else {
  115. previous = Cartesian3.unpack(
  116. positions,
  117. (offset + j - 1) * 3,
  118. scratchPrev
  119. );
  120. }
  121. var current = Cartesian3.unpack(positions, (offset + j) * 3, scratchCur);
  122. var next;
  123. if (j === count - 1) {
  124. var p2 = Cartesian3.unpack(
  125. positions,
  126. (offset + count - 1) * 3,
  127. scratchP0
  128. );
  129. var p3 = Cartesian3.unpack(
  130. positions,
  131. (offset + count - 2) * 3,
  132. scratchP1
  133. );
  134. next = Cartesian3.subtract(p2, p3, scratchNext);
  135. Cartesian3.add(p2, next, next);
  136. } else {
  137. next = Cartesian3.unpack(positions, (offset + j + 1) * 3, scratchNext);
  138. }
  139. Cartesian3.subtract(previous, center, previous);
  140. Cartesian3.subtract(current, center, current);
  141. Cartesian3.subtract(next, center, next);
  142. var startK = j === 0 ? 2 : 0;
  143. var endK = j === count - 1 ? 2 : 4;
  144. for (var k = startK; k < endK; ++k) {
  145. Cartesian3.pack(current, curPositions, positionIndex);
  146. Cartesian3.pack(previous, prevPositions, positionIndex);
  147. Cartesian3.pack(next, nextPositions, positionIndex);
  148. positionIndex += 3;
  149. var direction = k - 2 < 0 ? -1.0 : 1.0;
  150. expandAndWidth[expandAndWidthIndex++] = 2 * (k % 2) - 1;
  151. expandAndWidth[expandAndWidthIndex++] = direction * width;
  152. vertexBatchIds[batchIdIndex++] = batchId;
  153. }
  154. }
  155. offset += count;
  156. }
  157. var indices = IndexDatatype.createTypedArray(size, positionsLength * 6 - 6);
  158. var index = 0;
  159. var indicesIndex = 0;
  160. length = positionsLength - 1;
  161. for (i = 0; i < length; ++i) {
  162. indices[indicesIndex++] = index;
  163. indices[indicesIndex++] = index + 2;
  164. indices[indicesIndex++] = index + 1;
  165. indices[indicesIndex++] = index + 1;
  166. indices[indicesIndex++] = index + 2;
  167. indices[indicesIndex++] = index + 3;
  168. index += 4;
  169. }
  170. transferableObjects.push(
  171. curPositions.buffer,
  172. prevPositions.buffer,
  173. nextPositions.buffer
  174. );
  175. transferableObjects.push(
  176. expandAndWidth.buffer,
  177. vertexBatchIds.buffer,
  178. indices.buffer
  179. );
  180. return {
  181. indexDatatype:
  182. indices.BYTES_PER_ELEMENT === 2
  183. ? IndexDatatype.UNSIGNED_SHORT
  184. : IndexDatatype.UNSIGNED_INT,
  185. currentPositions: curPositions.buffer,
  186. previousPositions: prevPositions.buffer,
  187. nextPositions: nextPositions.buffer,
  188. expandAndWidth: expandAndWidth.buffer,
  189. batchIds: vertexBatchIds.buffer,
  190. indices: indices.buffer,
  191. };
  192. }
  193. export default createTaskProcessorWorker(createVectorTilePolylines);