智慧水务管理系统 - 精河县供水工程综合管理平台

ConditionsExpression.js 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. import addAllToArray from "../Core/addAllToArray.js";
  2. import clone from "../Core/clone.js";
  3. import defined from "../Core/defined.js";
  4. import Expression from "./Expression.js";
  5. /**
  6. * An expression for a style applied to a {@link Cesium3DTileset}.
  7. * <p>
  8. * Evaluates a conditions expression defined using the
  9. * {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling|3D Tiles Styling language}.
  10. * </p>
  11. * <p>
  12. * Implements the {@link StyleExpression} interface.
  13. * </p>
  14. *
  15. * @alias ConditionsExpression
  16. * @constructor
  17. *
  18. * @param {object} [conditionsExpression] The conditions expression defined using the 3D Tiles Styling language.
  19. * @param {object} [defines] Defines in the style.
  20. *
  21. * @example
  22. * const expression = new Cesium.ConditionsExpression({
  23. * conditions : [
  24. * ['${Area} > 10, 'color("#FF0000")'],
  25. * ['${id} !== "1"', 'color("#00FF00")'],
  26. * ['true', 'color("#FFFFFF")']
  27. * ]
  28. * });
  29. * expression.evaluateColor(feature, result); // returns a Cesium.Color object
  30. */
  31. function ConditionsExpression(conditionsExpression, defines) {
  32. this._conditionsExpression = clone(conditionsExpression, true);
  33. this._conditions = conditionsExpression.conditions;
  34. this._runtimeConditions = undefined;
  35. setRuntime(this, defines);
  36. }
  37. Object.defineProperties(ConditionsExpression.prototype, {
  38. /**
  39. * Gets the conditions expression defined in the 3D Tiles Styling language.
  40. *
  41. * @memberof ConditionsExpression.prototype
  42. *
  43. * @type {object}
  44. * @readonly
  45. *
  46. * @default undefined
  47. */
  48. conditionsExpression: {
  49. get: function () {
  50. return this._conditionsExpression;
  51. },
  52. },
  53. });
  54. function Statement(condition, expression) {
  55. this.condition = condition;
  56. this.expression = expression;
  57. }
  58. function setRuntime(expression, defines) {
  59. const runtimeConditions = [];
  60. const conditions = expression._conditions;
  61. if (!defined(conditions)) {
  62. return;
  63. }
  64. const length = conditions.length;
  65. for (let i = 0; i < length; ++i) {
  66. const statement = conditions[i];
  67. const cond = String(statement[0]);
  68. const condExpression = String(statement[1]);
  69. runtimeConditions.push(
  70. new Statement(
  71. new Expression(cond, defines),
  72. new Expression(condExpression, defines),
  73. ),
  74. );
  75. }
  76. expression._runtimeConditions = runtimeConditions;
  77. }
  78. /**
  79. * Evaluates the result of an expression, optionally using the provided feature's properties. If the result of
  80. * the expression in the
  81. * {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling|3D Tiles Styling language}
  82. * is of type <code>Boolean</code>, <code>Number</code>, or <code>String</code>, the corresponding JavaScript
  83. * primitive type will be returned. If the result is a <code>RegExp</code>, a Javascript <code>RegExp</code>
  84. * object will be returned. If the result is a <code>Cartesian2</code>, <code>Cartesian3</code>, or <code>Cartesian4</code>,
  85. * a {@link Cartesian2}, {@link Cartesian3}, or {@link Cartesian4} object will be returned. If the <code>result</code> argument is
  86. * a {@link Color}, the {@link Cartesian4} value is converted to a {@link Color} and then returned.
  87. *
  88. * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression.
  89. * @param {object} [result] The object onto which to store the result.
  90. * @returns {boolean|number|string|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression.
  91. */
  92. ConditionsExpression.prototype.evaluate = function (feature, result) {
  93. const conditions = this._runtimeConditions;
  94. if (!defined(conditions)) {
  95. return undefined;
  96. }
  97. const length = conditions.length;
  98. for (let i = 0; i < length; ++i) {
  99. const statement = conditions[i];
  100. if (statement.condition.evaluate(feature)) {
  101. return statement.expression.evaluate(feature, result);
  102. }
  103. }
  104. };
  105. /**
  106. * Evaluates the result of a Color expression, using the values defined by a feature.
  107. * <p>
  108. * This is equivalent to {@link ConditionsExpression#evaluate} but always returns a {@link Color} object.
  109. * </p>
  110. * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression.
  111. * @param {Color} [result] The object in which to store the result
  112. * @returns {Color} The modified result parameter or a new Color instance if one was not provided.
  113. */
  114. ConditionsExpression.prototype.evaluateColor = function (feature, result) {
  115. const conditions = this._runtimeConditions;
  116. if (!defined(conditions)) {
  117. return undefined;
  118. }
  119. const length = conditions.length;
  120. for (let i = 0; i < length; ++i) {
  121. const statement = conditions[i];
  122. if (statement.condition.evaluate(feature)) {
  123. return statement.expression.evaluateColor(feature, result);
  124. }
  125. }
  126. };
  127. /**
  128. * Gets the shader function for this expression.
  129. * Returns undefined if the shader function can't be generated from this expression.
  130. *
  131. * @param {string} functionSignature Signature of the generated function.
  132. * @param {object} variableSubstitutionMap Maps variable names to shader variable names.
  133. * @param {object} shaderState Stores information about the generated shader function, including whether it is translucent.
  134. * @param {string} returnType The return type of the generated function.
  135. *
  136. * @returns {string} The shader function.
  137. *
  138. * @private
  139. */
  140. ConditionsExpression.prototype.getShaderFunction = function (
  141. functionSignature,
  142. variableSubstitutionMap,
  143. shaderState,
  144. returnType,
  145. ) {
  146. const conditions = this._runtimeConditions;
  147. if (!defined(conditions) || conditions.length === 0) {
  148. return undefined;
  149. }
  150. let shaderFunction = "";
  151. const length = conditions.length;
  152. for (let i = 0; i < length; ++i) {
  153. const statement = conditions[i];
  154. const condition = statement.condition.getShaderExpression(
  155. variableSubstitutionMap,
  156. shaderState,
  157. );
  158. const expression = statement.expression.getShaderExpression(
  159. variableSubstitutionMap,
  160. shaderState,
  161. );
  162. // Build the if/else chain from the list of conditions
  163. shaderFunction +=
  164. ` ${i === 0 ? "if" : "else if"} (${condition})\n` +
  165. ` {\n` +
  166. ` return ${expression};\n` +
  167. ` }\n`;
  168. }
  169. shaderFunction =
  170. `${returnType} ${functionSignature}\n` +
  171. `{\n${shaderFunction} return ${returnType}(1.0);\n` + // Return a default value if no conditions are met
  172. `}\n`;
  173. return shaderFunction;
  174. };
  175. /**
  176. * Gets the variables used by the expression.
  177. *
  178. * @returns {string[]} The variables used by the expression.
  179. *
  180. * @private
  181. */
  182. ConditionsExpression.prototype.getVariables = function () {
  183. let variables = [];
  184. const conditions = this._runtimeConditions;
  185. if (!defined(conditions) || conditions.length === 0) {
  186. return variables;
  187. }
  188. const length = conditions.length;
  189. for (let i = 0; i < length; ++i) {
  190. const statement = conditions[i];
  191. addAllToArray(variables, statement.condition.getVariables());
  192. addAllToArray(variables, statement.expression.getVariables());
  193. }
  194. // Remove duplicates
  195. variables = variables.filter(function (variable, index, variables) {
  196. return variables.indexOf(variable) === index;
  197. });
  198. return variables;
  199. };
  200. export default ConditionsExpression;