Reusable Accessible Mapping Platform

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