Reusable Accessible Mapping Platform

API Docs for: 5.0.0
Show:

File: src\js\RAMP\Utils\tmplUtil.js

  1. /* global define, console */
  2.  
  3. /**
  4. * Utility module containing useful static classes.
  5. *
  6. * @module Utils
  7. */
  8.  
  9. /**
  10. * A set of functions that can be accessed within templates
  11. *
  12. *
  13. * @class TmplUtil
  14. * @static
  15. */
  16.  
  17. define(["ramp/globalStorage"],
  18. function (GlobalStorage) {
  19. "use strict";
  20.  
  21. return {
  22. /**
  23. * Given a feature object or a graphic object (or any object that has a getLayer method and an
  24. * attributes field) return the image URL for that feature/graphic object.
  25. *
  26. * NOTE: all dependent functions should be written as nested functions inside the caller function, otherwise TmplEx templating library won't identify
  27. *
  28. * @method getGraphicIcon
  29. * @param {Graphic} graphic
  30. * @param {Object} layerConfig
  31. * @return {String} imageUrl Url to the features symbology image
  32. */
  33. getGraphicIcon: function (graphic, layerConfig) {
  34. var i, symbolConfig = layerConfig.symbology, img = "";
  35.  
  36. switch (symbolConfig.type) {
  37. case "simple":
  38. return symbolConfig.imageUrl;
  39.  
  40. case "uniqueValue":
  41. //make a key value for the graphic in question, using comma-space delimiter if multiple fields
  42. var graphicKey = graphic.attributes[symbolConfig.field1];
  43.  
  44. //all key values are stored as strings. if the attribute is in a numeric column, we must convert it to a string to ensure the === operator still works.
  45. if (typeof graphicKey !== "string") {
  46. graphicKey = graphicKey.toString();
  47. }
  48.  
  49. if (symbolConfig.field2) {
  50. graphicKey = graphicKey + ", " + graphic.attributes[symbolConfig.field2];
  51. if (symbolConfig.field3) {
  52. graphicKey = graphicKey + ", " + graphic.attributes[symbolConfig.field3];
  53. }
  54. }
  55.  
  56. //search the value maps for a matching entry. if no match found, use the default image
  57. for (i = 0; i < symbolConfig.valueMaps.length; i++) {
  58. if (symbolConfig.valueMaps[i].value === graphicKey) {
  59. img = symbolConfig.valueMaps[i].imageUrl;
  60. break;
  61. }
  62. }
  63.  
  64. if (img === "") {
  65. img = symbolConfig.defaultImageUrl;
  66. }
  67.  
  68. return img;
  69.  
  70. case "classBreaks":
  71.  
  72. var gVal, lower, upper;
  73. gVal = graphic.attributes[symbolConfig.field];
  74.  
  75. //find where the value exists in the range
  76. lower = symbolConfig.minValue;
  77.  
  78. if (gVal < lower) {
  79. img = symbolConfig.defaultImageUrl;
  80. } else {
  81. // a trick to prime the first loop iteration
  82. // the first low value is inclusive. every other low value is exclusive.
  83. // if we have entered this else bracket, we know we are not below the first lower limit.
  84. // so we reduce lower by 1 to make the first exclusive test inclusive
  85. upper = lower - 1;
  86.  
  87. for (i = 0; i < symbolConfig.rangeMaps.length; i++) {
  88. lower = upper;
  89. upper = symbolConfig.rangeMaps[i].maxValue;
  90. if ((gVal > lower) && (gVal <= upper)) {
  91. img = symbolConfig.rangeMaps[i].imageUrl;
  92. break;
  93. }
  94. }
  95.  
  96. if (img === "") {
  97. //no match in defined ranges.
  98. img = symbolConfig.defaultImageUrl;
  99. }
  100. }
  101.  
  102. return img;
  103.  
  104. default:
  105. return symbolConfig.icons["default"].imageUrl;
  106. }
  107. },
  108.  
  109. /**
  110. * Given a feature object or a graphic object (or any object that has a getLayer method and an
  111. * attributes field) return the attribute value for its designed "name" field
  112. *
  113. * NOTE: all dependent functions should be written as nested functions inside the caller function, otherwise TmplEx templating library won't identify
  114. *
  115. * @method getFeatureName
  116. * @param {Graphic} graphic
  117. * @param {Object} layerConfig
  118. * @return {String} imageUrl Url to the features symbology image
  119. */
  120. getFeatureName: function (graphic, layerConfig) {
  121. return graphic.attributes[layerConfig.nameField];
  122. },
  123.  
  124. /**
  125. * Given a feature object return the objectid for that item.
  126. * This will likely fail on a non-feature object (e.g. a plain graphic)
  127. *
  128. * NOTE: all dependent functions should be written as nested functions inside the caller function, otherwise TmplEx templating library won't identify
  129. *
  130. * @method getObjectId
  131. * @param {Graphic} graphic
  132. * @return {Integer} objectId
  133. */
  134. getObjectId: function (graphic) {
  135. return graphic.attributes[graphic.getLayer().objectIdField];
  136. },
  137.  
  138. /*
  139. * Helper function, get attribute value by field name
  140. *
  141. * @method getAttributeValueByName
  142. * @param {Object} graphic ?
  143. * @param {String} fieldName ?
  144. */
  145. getAttributeValueByName: function (graphic, fieldName) {
  146. return graphic.attributes[fieldName];
  147. },
  148.  
  149. /* Helper function used by filterManager.*/
  150. /*
  151. * generate visibility legend object
  152. * @param o
  153. */
  154. generateVisibilityLegend: function (o) {
  155. var attr = "",
  156. visibilityLegendLabel = {
  157. for: "filterGroup_" + o.data[o.idx].id,
  158. attr: attr,
  159. value: o.data[o.idx].id,
  160. checked: "checked",
  161. label: o.data[o.idx].layerConfig.displayName,
  162. class: "eye checked",
  163. layerId: o.data[o.idx].id
  164. };
  165. return visibilityLegendLabel;
  166. },
  167.  
  168. /**
  169. * Wraps plain text urls and emails with <a> tags.
  170. *
  171. * @method autoHyperlink
  172. * @param {String} content the text you would like to search in.
  173. */
  174. autoHyperlink: function (content) {
  175. //http://stackoverflow.com/questions/11863847/regex-to-match-urls-but-not-urls-in-hyperlinks
  176. //http://stackoverflow.com/questions/15039993/javascript-function-to-find-email-address-from-a-webpage
  177.  
  178. // orig regex's. did not handle pre-linked content
  179. // var urlRegex = /((f|ht)tp(s|):\/\/.+?[\w=%\?\&\./-]+)/g;
  180. // var emailRegex = /([\w-\.]+@([\w-]+\.)+[\w-]{2,4})/g;
  181.  
  182. if (content) {
  183. content = content.toString();
  184.  
  185. var urlRegex = /(["'>:]?)((ftp|http|https|file):\/\/[\S]+(\b|$))/gi;
  186. content = content.replace(urlRegex, function ($0, $1) {
  187. return $1 ? $0 : '<a href="' + $0 + '" target="_blank">' + $0 + '</a>';
  188. });
  189.  
  190. var emailRegex = /(["'>:]?)([\w.-]+@[\w.-]+\.[\w.-]+)/gi;
  191. content = content.replace(emailRegex, function ($0, $1) {
  192. return $1 ? $0 : '<a href="mailto:' + $0 + '">' + $0 + '</a>';
  193. });
  194. }
  195. return content;
  196. },
  197.  
  198. /*
  199. * generate visibility legend object
  200. * @param o
  201. */
  202. generateBoundingBoxLegend: function (o) {
  203. // adding flag for the generated o object
  204. // o.disabled will indicate the bounding checkbox is to be disabled.
  205. var checkboxDisabled = false,
  206. attr = "",
  207. boundingLegendLabel;
  208.  
  209. // determine if given layer is static or WMS
  210. checkboxDisabled = Boolean(o.data[o.idx].ramp.type === GlobalStorage.layerType.Static ||
  211. o.data[o.idx].ramp.type === GlobalStorage.layerType.wms);
  212.  
  213. boundingLegendLabel = {
  214. for: "filterGroup_" + o.data[o.idx].id + "1",
  215. attr: attr + "1",
  216. value: o.data[o.idx].id,
  217. checked: "checked",
  218. label: o.data[o.idx].layerConfig.displayName,
  219. class: "box checked",
  220. disabled: checkboxDisabled,
  221. layerId: o.data[o.idx].id
  222. };
  223.  
  224. return boundingLegendLabel;
  225. },
  226.  
  227. /*
  228. * Generate settings toggle object.
  229. *
  230. * @method generateSettingsToggle
  231. * @param o
  232. */
  233. generateSettingsToggle: function (o) {
  234. var //attr = "",
  235. boundingLegendLabel = {
  236. str: o.str,
  237. layerId: o.data[o.idx].id,
  238. settings: o.data[o.idx].layerConfig.settings
  239. };
  240.  
  241. return boundingLegendLabel;
  242. },
  243.  
  244. /**
  245. * Gets an array of symbology images to display in the layer selector
  246. * @method getSymbolForLayer
  247. * @param {Object} layerConfig A layer's config object
  248. * @returns {icon} The array of icon(s) to use in layer selector
  249. */
  250. getSymbolForLayer: function (layerConfig) {
  251. //will take a symbol list that has 1 or more entries. will return first 3. if fewer than 3, will duplicate values
  252. function pick3(symbolList) {
  253. var num = symbolList.length, indexes;
  254.  
  255. if (num > 2) {
  256. //pick first 3
  257. indexes = [0, 1, 2];
  258. } else if (num === 2) {
  259. //duplicate the first
  260. indexes = [0, 1, 0];
  261. } else if (num === 1) {
  262. //triple whammy
  263. indexes = [0, 0, 0];
  264. } else {
  265. //something is ruined
  266. return ["", "", ""];
  267. }
  268.  
  269. //return images in an array
  270. return [symbolList[indexes[0]].imageUrl, symbolList[indexes[1]].imageUrl, symbolList[indexes[2]].imageUrl];
  271. }
  272.  
  273. if (layerConfig.symbology) {
  274. //feature layer. make an array for the appropriate renderer
  275.  
  276. var symbNode = layerConfig.symbology;
  277. switch (symbNode.type) {
  278. case "simple":
  279. return [symbNode.imageUrl];
  280. case "uniqueValue":
  281. return pick3(symbNode.valueMaps);
  282. case "classBreaks":
  283. return pick3(symbNode.rangeMaps);
  284. default:
  285. //we have an unknown renderer type. at this point, something else would have failed most likely. write out a screech to the console just incase
  286. console.log('unknown renderer encountered: ' + symbNode.type);
  287. return [""];
  288. }
  289. } else {
  290. //no symbology defined, assume a WMS
  291.  
  292. if (layerConfig.imageUrl) {
  293. return [layerConfig.imageUrl];
  294. } else {
  295. //catch-all in the case that things are really messed up
  296. console.log('layer with no image info for layer selector');
  297. return [""];
  298. }
  299. }
  300. }
  301. };
  302. });