@macallumharvey/first-test-wet 1.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (292) hide show
  1. package/dist/WetButton.d.ts +9 -0
  2. package/dist/WetModal.d.ts +6 -0
  3. package/dist/first-test-wet.cjs.development.js +26 -0
  4. package/dist/first-test-wet.cjs.development.js.map +1 -1
  5. package/dist/first-test-wet.cjs.production.min.js +1 -1
  6. package/dist/first-test-wet.cjs.production.min.js.map +1 -1
  7. package/dist/first-test-wet.esm.js +26 -1
  8. package/dist/first-test-wet.esm.js.map +1 -1
  9. package/dist/index.d.ts +1 -0
  10. package/package.json +1 -1
  11. package/src/WetButton.tsx +19 -0
  12. package/src/WetModal.tsx +26 -0
  13. package/src/index.tsx +2 -2
  14. package/src/theme-wet-boew/assets/favicon-mobile.png +0 -0
  15. package/src/theme-wet-boew/assets/favicon.ico +0 -0
  16. package/src/theme-wet-boew/assets/logo.png +0 -0
  17. package/src/theme-wet-boew/assets/logo.svg +14 -0
  18. package/src/theme-wet-boew/css/ie8-theme.css +17370 -0
  19. package/src/theme-wet-boew/css/ie8-theme.min.css +193 -0
  20. package/src/theme-wet-boew/css/ie8-wet-boew.css +12 -0
  21. package/src/theme-wet-boew/css/ie8-wet-boew.min.css +7 -0
  22. package/src/theme-wet-boew/css/theme.css +11357 -0
  23. package/src/theme-wet-boew/css/theme.min.css +6 -0
  24. package/src/theme-wet-boew/css/wet-boew.css +12 -0
  25. package/src/theme-wet-boew/css/wet-boew.min.css +6 -0
  26. package/src/theme-wet-boew/payload.json +66 -0
  27. package/src/wet-boew/assets/cloud-popup-relative.png +0 -0
  28. package/src/wet-boew/assets/fd-slider-sprite.png +0 -0
  29. package/src/wet-boew/assets/loading.png +0 -0
  30. package/src/wet-boew/assets/mediacontrols.html +32 -0
  31. package/src/wet-boew/assets/sprites_share.png +0 -0
  32. package/src/wet-boew/assets/zoom-minus-mini.png +0 -0
  33. package/src/wet-boew/assets/zoom-plus-mini.png +0 -0
  34. package/src/wet-boew/assets/zoom-world-mini.png +0 -0
  35. package/src/wet-boew/css/noscript.css +112 -0
  36. package/src/wet-boew/css/noscript.min.css +6 -0
  37. package/src/wet-boew/css/polyfills/datalist.css +32 -0
  38. package/src/wet-boew/css/polyfills/datalist.min.css +1 -0
  39. package/src/wet-boew/css/polyfills/datepicker.css +47 -0
  40. package/src/wet-boew/css/polyfills/datepicker.min.css +1 -0
  41. package/src/wet-boew/css/polyfills/details.css +28 -0
  42. package/src/wet-boew/css/polyfills/details.min.css +1 -0
  43. package/src/wet-boew/css/polyfills/mathml.css +16 -0
  44. package/src/wet-boew/css/polyfills/mathml.min.css +1 -0
  45. package/src/wet-boew/css/polyfills/meter.css +24 -0
  46. package/src/wet-boew/css/polyfills/meter.min.css +1 -0
  47. package/src/wet-boew/css/polyfills/progress.css +8 -0
  48. package/src/wet-boew/css/polyfills/progress.min.css +1 -0
  49. package/src/wet-boew/css/polyfills/slider.css +229 -0
  50. package/src/wet-boew/css/polyfills/slider.min.css +1 -0
  51. package/src/wet-boew/fonts/glyphicons-halflings-regular.eot +0 -0
  52. package/src/wet-boew/fonts/glyphicons-halflings-regular.svg +288 -0
  53. package/src/wet-boew/fonts/glyphicons-halflings-regular.ttf +0 -0
  54. package/src/wet-boew/fonts/glyphicons-halflings-regular.woff +0 -0
  55. package/src/wet-boew/fonts/glyphicons-halflings-regular.woff2 +0 -0
  56. package/src/wet-boew/js/MathJax/mml-chtml.js +1 -0
  57. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_AMS-Regular.woff +0 -0
  58. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Bold.woff +0 -0
  59. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Regular.woff +0 -0
  60. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Fraktur-Bold.woff +0 -0
  61. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Fraktur-Regular.woff +0 -0
  62. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Main-Bold.woff +0 -0
  63. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Main-Italic.woff +0 -0
  64. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Main-Regular.woff +0 -0
  65. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Math-BoldItalic.woff +0 -0
  66. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Math-Italic.woff +0 -0
  67. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Math-Regular.woff +0 -0
  68. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Bold.woff +0 -0
  69. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Italic.woff +0 -0
  70. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Regular.woff +0 -0
  71. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Script-Regular.woff +0 -0
  72. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Size1-Regular.woff +0 -0
  73. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Size2-Regular.woff +0 -0
  74. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Size3-Regular.woff +0 -0
  75. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Size4-Regular.woff +0 -0
  76. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Typewriter-Regular.woff +0 -0
  77. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Vector-Bold.woff +0 -0
  78. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Vector-Regular.woff +0 -0
  79. package/src/wet-boew/js/MathJax/output/chtml/fonts/woff-v2/MathJax_Zero.woff +0 -0
  80. package/src/wet-boew/js/deps/additional-methods.js +1512 -0
  81. package/src/wet-boew/js/deps/additional-methods.min.js +9 -0
  82. package/src/wet-boew/js/deps/geomap-lib.js +3758 -0
  83. package/src/wet-boew/js/deps/geomap-lib.min.js +1 -0
  84. package/src/wet-boew/js/deps/jquery.dataTables.js +15345 -0
  85. package/src/wet-boew/js/deps/jquery.dataTables.min.js +4 -0
  86. package/src/wet-boew/js/deps/jquery.flot.canvas.js +345 -0
  87. package/src/wet-boew/js/deps/jquery.flot.canvas.min.js +1 -0
  88. package/src/wet-boew/js/deps/jquery.flot.js +3168 -0
  89. package/src/wet-boew/js/deps/jquery.flot.min.js +1 -0
  90. package/src/wet-boew/js/deps/jquery.flot.orderBars.js +282 -0
  91. package/src/wet-boew/js/deps/jquery.flot.orderBars.min.js +1 -0
  92. package/src/wet-boew/js/deps/jquery.flot.pie.js +820 -0
  93. package/src/wet-boew/js/deps/jquery.flot.pie.min.js +1 -0
  94. package/src/wet-boew/js/deps/jquery.magnific-popup.js +2061 -0
  95. package/src/wet-boew/js/deps/jquery.magnific-popup.min.js +4 -0
  96. package/src/wet-boew/js/deps/jquery.validate.js +1661 -0
  97. package/src/wet-boew/js/deps/jquery.validate.min.js +9 -0
  98. package/src/wet-boew/js/deps/json-patch.js +315 -0
  99. package/src/wet-boew/js/deps/json-patch.min.js +1 -0
  100. package/src/wet-boew/js/deps/jsonpointer.js +349 -0
  101. package/src/wet-boew/js/deps/jsonpointer.min.js +1 -0
  102. package/src/wet-boew/js/deps/lang-apollo.js +53 -0
  103. package/src/wet-boew/js/deps/lang-apollo.min.js +1 -0
  104. package/src/wet-boew/js/deps/lang-basic.js +49 -0
  105. package/src/wet-boew/js/deps/lang-basic.min.js +1 -0
  106. package/src/wet-boew/js/deps/lang-clj.js +64 -0
  107. package/src/wet-boew/js/deps/lang-clj.min.js +1 -0
  108. package/src/wet-boew/js/deps/lang-css.js +160 -0
  109. package/src/wet-boew/js/deps/lang-css.min.js +1 -0
  110. package/src/wet-boew/js/deps/lang-dart.js +92 -0
  111. package/src/wet-boew/js/deps/lang-dart.min.js +1 -0
  112. package/src/wet-boew/js/deps/lang-erlang.js +94 -0
  113. package/src/wet-boew/js/deps/lang-erlang.min.js +1 -0
  114. package/src/wet-boew/js/deps/lang-go.js +59 -0
  115. package/src/wet-boew/js/deps/lang-go.min.js +1 -0
  116. package/src/wet-boew/js/deps/lang-hs.js +102 -0
  117. package/src/wet-boew/js/deps/lang-hs.min.js +1 -0
  118. package/src/wet-boew/js/deps/lang-lasso.js +67 -0
  119. package/src/wet-boew/js/deps/lang-lasso.min.js +1 -0
  120. package/src/wet-boew/js/deps/lang-lisp.js +95 -0
  121. package/src/wet-boew/js/deps/lang-lisp.min.js +1 -0
  122. package/src/wet-boew/js/deps/lang-llvm.js +63 -0
  123. package/src/wet-boew/js/deps/lang-llvm.min.js +1 -0
  124. package/src/wet-boew/js/deps/lang-logtalk.js +50 -0
  125. package/src/wet-boew/js/deps/lang-logtalk.min.js +1 -0
  126. package/src/wet-boew/js/deps/lang-lua.js +60 -0
  127. package/src/wet-boew/js/deps/lang-lua.min.js +1 -0
  128. package/src/wet-boew/js/deps/lang-matlab.js +183 -0
  129. package/src/wet-boew/js/deps/lang-matlab.min.js +1 -0
  130. package/src/wet-boew/js/deps/lang-ml.js +57 -0
  131. package/src/wet-boew/js/deps/lang-ml.min.js +1 -0
  132. package/src/wet-boew/js/deps/lang-mumps.js +140 -0
  133. package/src/wet-boew/js/deps/lang-mumps.min.js +1 -0
  134. package/src/wet-boew/js/deps/lang-n.js +67 -0
  135. package/src/wet-boew/js/deps/lang-n.min.js +1 -0
  136. package/src/wet-boew/js/deps/lang-pascal.js +49 -0
  137. package/src/wet-boew/js/deps/lang-pascal.min.js +1 -0
  138. package/src/wet-boew/js/deps/lang-proto.js +37 -0
  139. package/src/wet-boew/js/deps/lang-proto.min.js +1 -0
  140. package/src/wet-boew/js/deps/lang-r.js +59 -0
  141. package/src/wet-boew/js/deps/lang-r.min.js +1 -0
  142. package/src/wet-boew/js/deps/lang-rd.js +50 -0
  143. package/src/wet-boew/js/deps/lang-rd.min.js +1 -0
  144. package/src/wet-boew/js/deps/lang-rust.js +81 -0
  145. package/src/wet-boew/js/deps/lang-rust.min.js +1 -0
  146. package/src/wet-boew/js/deps/lang-scala.js +56 -0
  147. package/src/wet-boew/js/deps/lang-scala.min.js +1 -0
  148. package/src/wet-boew/js/deps/lang-sql.js +59 -0
  149. package/src/wet-boew/js/deps/lang-sql.min.js +1 -0
  150. package/src/wet-boew/js/deps/lang-swift.js +60 -0
  151. package/src/wet-boew/js/deps/lang-swift.min.js +1 -0
  152. package/src/wet-boew/js/deps/lang-tcl.js +63 -0
  153. package/src/wet-boew/js/deps/lang-tcl.min.js +1 -0
  154. package/src/wet-boew/js/deps/lang-tex.js +49 -0
  155. package/src/wet-boew/js/deps/lang-tex.min.js +1 -0
  156. package/src/wet-boew/js/deps/lang-vb.js +67 -0
  157. package/src/wet-boew/js/deps/lang-vb.min.js +1 -0
  158. package/src/wet-boew/js/deps/lang-vhdl.js +51 -0
  159. package/src/wet-boew/js/deps/lang-vhdl.min.js +1 -0
  160. package/src/wet-boew/js/deps/lang-wiki.js +55 -0
  161. package/src/wet-boew/js/deps/lang-wiki.min.js +1 -0
  162. package/src/wet-boew/js/deps/lang-xq.js +71 -0
  163. package/src/wet-boew/js/deps/lang-xq.min.js +1 -0
  164. package/src/wet-boew/js/deps/lang-yaml.js +45 -0
  165. package/src/wet-boew/js/deps/lang-yaml.min.js +1 -0
  166. package/src/wet-boew/js/deps/ol.js +1008 -0
  167. package/src/wet-boew/js/deps/ol.min.js +1 -0
  168. package/src/wet-boew/js/deps/prettify.js +1742 -0
  169. package/src/wet-boew/js/deps/prettify.min.js +1 -0
  170. package/src/wet-boew/js/deps/proj4.js +3 -0
  171. package/src/wet-boew/js/deps/proj4.min.js +1 -0
  172. package/src/wet-boew/js/deps/run_prettify.js +1998 -0
  173. package/src/wet-boew/js/deps/run_prettify.min.js +1 -0
  174. package/src/wet-boew/js/deps/tableparser.js +2216 -0
  175. package/src/wet-boew/js/deps/tableparser.min.js +1 -0
  176. package/src/wet-boew/js/deps/unorm.js +452 -0
  177. package/src/wet-boew/js/deps/unorm.min.js +1 -0
  178. package/src/wet-boew/js/i18n/af.js +246 -0
  179. package/src/wet-boew/js/i18n/af.min.js +7 -0
  180. package/src/wet-boew/js/i18n/ar.js +285 -0
  181. package/src/wet-boew/js/i18n/ar.min.js +7 -0
  182. package/src/wet-boew/js/i18n/bg.js +285 -0
  183. package/src/wet-boew/js/i18n/bg.min.js +7 -0
  184. package/src/wet-boew/js/i18n/cs.js +286 -0
  185. package/src/wet-boew/js/i18n/cs.min.js +7 -0
  186. package/src/wet-boew/js/i18n/de.js +355 -0
  187. package/src/wet-boew/js/i18n/de.min.js +7 -0
  188. package/src/wet-boew/js/i18n/el.js +285 -0
  189. package/src/wet-boew/js/i18n/el.min.js +7 -0
  190. package/src/wet-boew/js/i18n/en.js +246 -0
  191. package/src/wet-boew/js/i18n/en.min.js +7 -0
  192. package/src/wet-boew/js/i18n/es.js +288 -0
  193. package/src/wet-boew/js/i18n/es.min.js +7 -0
  194. package/src/wet-boew/js/i18n/et.js +283 -0
  195. package/src/wet-boew/js/i18n/et.min.js +7 -0
  196. package/src/wet-boew/js/i18n/fr.js +314 -0
  197. package/src/wet-boew/js/i18n/fr.min.js +7 -0
  198. package/src/wet-boew/js/i18n/hi.js +246 -0
  199. package/src/wet-boew/js/i18n/hi.min.js +7 -0
  200. package/src/wet-boew/js/i18n/hu.js +285 -0
  201. package/src/wet-boew/js/i18n/hu.min.js +7 -0
  202. package/src/wet-boew/js/i18n/hy.js +246 -0
  203. package/src/wet-boew/js/i18n/hy.min.js +7 -0
  204. package/src/wet-boew/js/i18n/id.js +284 -0
  205. package/src/wet-boew/js/i18n/id.min.js +7 -0
  206. package/src/wet-boew/js/i18n/is.js +283 -0
  207. package/src/wet-boew/js/i18n/is.min.js +7 -0
  208. package/src/wet-boew/js/i18n/it.js +312 -0
  209. package/src/wet-boew/js/i18n/it.min.js +7 -0
  210. package/src/wet-boew/js/i18n/iu.js +246 -0
  211. package/src/wet-boew/js/i18n/iu.min.js +7 -0
  212. package/src/wet-boew/js/i18n/ja.js +286 -0
  213. package/src/wet-boew/js/i18n/ja.min.js +7 -0
  214. package/src/wet-boew/js/i18n/ko.js +285 -0
  215. package/src/wet-boew/js/i18n/ko.min.js +7 -0
  216. package/src/wet-boew/js/i18n/lt.js +285 -0
  217. package/src/wet-boew/js/i18n/lt.min.js +7 -0
  218. package/src/wet-boew/js/i18n/lv.js +285 -0
  219. package/src/wet-boew/js/i18n/lv.min.js +7 -0
  220. package/src/wet-boew/js/i18n/nl.js +319 -0
  221. package/src/wet-boew/js/i18n/nl.min.js +7 -0
  222. package/src/wet-boew/js/i18n/pl.js +288 -0
  223. package/src/wet-boew/js/i18n/pl.min.js +7 -0
  224. package/src/wet-boew/js/i18n/pt-BR.js +246 -0
  225. package/src/wet-boew/js/i18n/pt-BR.min.js +7 -0
  226. package/src/wet-boew/js/i18n/pt.js +271 -0
  227. package/src/wet-boew/js/i18n/pt.min.js +7 -0
  228. package/src/wet-boew/js/i18n/ru.js +285 -0
  229. package/src/wet-boew/js/i18n/ru.min.js +7 -0
  230. package/src/wet-boew/js/i18n/sk.js +283 -0
  231. package/src/wet-boew/js/i18n/sk.min.js +7 -0
  232. package/src/wet-boew/js/i18n/sq.js +246 -0
  233. package/src/wet-boew/js/i18n/sq.min.js +7 -0
  234. package/src/wet-boew/js/i18n/th.js +285 -0
  235. package/src/wet-boew/js/i18n/th.min.js +7 -0
  236. package/src/wet-boew/js/i18n/tr.js +287 -0
  237. package/src/wet-boew/js/i18n/tr.min.js +7 -0
  238. package/src/wet-boew/js/i18n/uk.js +285 -0
  239. package/src/wet-boew/js/i18n/uk.min.js +7 -0
  240. package/src/wet-boew/js/i18n/vi.js +285 -0
  241. package/src/wet-boew/js/i18n/vi.min.js +7 -0
  242. package/src/wet-boew/js/i18n/zh-Hans.js +246 -0
  243. package/src/wet-boew/js/i18n/zh-Hans.min.js +7 -0
  244. package/src/wet-boew/js/i18n/zh.js +286 -0
  245. package/src/wet-boew/js/i18n/zh.min.js +7 -0
  246. package/src/wet-boew/js/ie8-wet-boew.js +3992 -0
  247. package/src/wet-boew/js/ie8-wet-boew.min.js +7 -0
  248. package/src/wet-boew/js/ie8-wet-boew2.js +15294 -0
  249. package/src/wet-boew/js/ie8-wet-boew2.min.js +7 -0
  250. package/src/wet-boew/js/jquery/2.2.4/jquery.js +9814 -0
  251. package/src/wet-boew/js/jquery/2.2.4/jquery.min.js +4 -0
  252. package/src/wet-boew/js/jquery/2.2.4/jquery.min.map +1 -0
  253. package/src/wet-boew/js/polyfills/datalist.js +423 -0
  254. package/src/wet-boew/js/polyfills/datalist.min.js +8 -0
  255. package/src/wet-boew/js/polyfills/datalist.min.js.map +1 -0
  256. package/src/wet-boew/js/polyfills/datalist_dynamic.js +50 -0
  257. package/src/wet-boew/js/polyfills/datalist_dynamic.min.js +8 -0
  258. package/src/wet-boew/js/polyfills/datalist_dynamic.min.js.map +1 -0
  259. package/src/wet-boew/js/polyfills/datepicker.js +338 -0
  260. package/src/wet-boew/js/polyfills/datepicker.min.js +8 -0
  261. package/src/wet-boew/js/polyfills/datepicker.min.js.map +1 -0
  262. package/src/wet-boew/js/polyfills/details.js +126 -0
  263. package/src/wet-boew/js/polyfills/details.min.js +8 -0
  264. package/src/wet-boew/js/polyfills/details.min.js.map +1 -0
  265. package/src/wet-boew/js/polyfills/jawsariafixes.js +47 -0
  266. package/src/wet-boew/js/polyfills/jawsariafixes.min.js +16 -0
  267. package/src/wet-boew/js/polyfills/jawsariafixes.min.js.map +1 -0
  268. package/src/wet-boew/js/polyfills/meter.js +140 -0
  269. package/src/wet-boew/js/polyfills/meter.min.js +8 -0
  270. package/src/wet-boew/js/polyfills/meter.min.js.map +1 -0
  271. package/src/wet-boew/js/polyfills/mobile.js +783 -0
  272. package/src/wet-boew/js/polyfills/mobile.min.js +8 -0
  273. package/src/wet-boew/js/polyfills/mobile.min.js.map +1 -0
  274. package/src/wet-boew/js/polyfills/progress.js +107 -0
  275. package/src/wet-boew/js/polyfills/progress.min.js +8 -0
  276. package/src/wet-boew/js/polyfills/progress.min.js.map +1 -0
  277. package/src/wet-boew/js/polyfills/slider.js +1343 -0
  278. package/src/wet-boew/js/polyfills/slider.min.js +9 -0
  279. package/src/wet-boew/js/polyfills/slider.min.js.map +1 -0
  280. package/src/wet-boew/js/polyfills/slider_wrapper.js +73 -0
  281. package/src/wet-boew/js/polyfills/slider_wrapper.min.js +8 -0
  282. package/src/wet-boew/js/polyfills/slider_wrapper.min.js.map +1 -0
  283. package/src/wet-boew/js/polyfills/svg.js +29 -0
  284. package/src/wet-boew/js/polyfills/svg.min.js +8 -0
  285. package/src/wet-boew/js/polyfills/svg.min.js.map +1 -0
  286. package/src/wet-boew/js/polyfills/test.js +603 -0
  287. package/src/wet-boew/js/polyfills/test.min.js +8 -0
  288. package/src/wet-boew/js/polyfills/test.min.js.map +1 -0
  289. package/src/wet-boew/js/wet-boew.js +17714 -0
  290. package/src/wet-boew/js/wet-boew.min.js +9 -0
  291. package/src/wet-boew/js/wet-boew.min.js.map +1 -0
  292. package/src/wet-boew/payload.json +1722 -0
@@ -0,0 +1,3758 @@
1
+
2
+ /*
3
+ * @title WET-BOEW Geomap
4
+ * @overview Displays a dynamic map over which information from additional sources can be overlaid.
5
+ * @license wet-boew.github.io/wet-boew/License-en.html / wet-boew.github.io/wet-boew/Licence-fr.html
6
+ * @author @pjackson28
7
+ */
8
+ /*global wet_boew_geomap: false, ol: false, proj4: false*/
9
+ ( function( $, window, document, wb ) {
10
+ "use strict";
11
+
12
+ var componentName = "wb-geomap",
13
+ selector = "." + componentName,
14
+ $document = wb.doc,
15
+ colourIndex = 0,
16
+ mapArray = [],
17
+ mobile = false,
18
+ i18n, i18nText, tooltip,
19
+
20
+ /*
21
+ * Plugin users can override these defaults by setting attributes on the html elements that the
22
+ * selector matches.
23
+ * For example, adding the attribute data-option1="false", will override option1 for that plugin instance.
24
+ */
25
+ defaults = {
26
+ overlays: [],
27
+ tables: [],
28
+ useScaleLine: false,
29
+ useMousePosition: false,
30
+ useLegend: false,
31
+ useMapControls: true,
32
+ useGeocoder: false,
33
+ useGeolocation: false,
34
+ useAOI: false
35
+ },
36
+
37
+ /**
38
+ * @method init
39
+ * @param {jQuery Event} event Event that triggered this handler
40
+ */
41
+ init = function( event ) {
42
+
43
+ var elm = event.target,
44
+ className = elm.className.split( /\s+/ ),
45
+ settings = {},
46
+ $elm, overrides;
47
+
48
+ if ( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) ) {
49
+ mobile = true;
50
+ }
51
+
52
+ // Filter out any events triggered by descendants
53
+ if ( event.currentTarget === elm ) {
54
+ $elm = $( elm );
55
+
56
+ // Only initialize the i18nText once
57
+ if ( !i18nText ) {
58
+ i18n = wb.i18n;
59
+ i18nText = {
60
+ add: i18n( "add" ),
61
+ close: i18n( "close" ),
62
+ colon: i18n( "colon" ),
63
+ err: i18n( "err" ),
64
+ hiddenLayer: i18n( "geo-hdnlyr" ),
65
+ toggleLayer: i18n( "geo-tgllyr" ),
66
+ labelSelect: i18n( "geo-lblsel" ),
67
+ select: i18n( "geo-sel" ),
68
+ zoomFeature: i18n( "geo-zmfeat" ),
69
+ zoomin: i18n( "geo-zmin" ),
70
+ zoomout: i18n( "geo-zmout" ),
71
+ zoomworld: i18n( "geo-zmwrld" ),
72
+ baseMapTitle: i18n( "geo-bmapttl" ),
73
+ baseMapURL: i18n( "geo-bmap-url" ),
74
+ baseMapMatrixSet: i18n( "geo-bmap-matrix-set" ),
75
+ scaleline: i18n( "geo-sclln" ),
76
+ mouseposition: i18n( "geo-msepos" ),
77
+ access: i18n( "geo-ally" ),
78
+ accessTitle: i18n( "geo-allyttl" ),
79
+ attribLink: i18n( "geo-attrlnk" ),
80
+ attribTitle: i18n( "geo-attrttl" ),
81
+ ariaMap: i18n( "geo-ariamap" ),
82
+ geoLocationURL: i18n( "geo-locurl-geogratis" ),
83
+ geoCoderPlaceholder: i18n( "geo-loc-placeholder" ),
84
+ geoCoderLabel: i18n( "geo-loc-label" ),
85
+ aoiNorth: i18n( "geo-aoi-north" ),
86
+ aoiEast: i18n( "geo-aoi-east" ),
87
+ aoiSouth: i18n( "geo-aoi-south" ),
88
+ aoiWest: i18n( "geo-aoi-west" ),
89
+ aoiInstructions: i18n( "geo-aoi-instructions" ),
90
+ aoiTitle: i18n( "geo-aoi-title" ),
91
+ aoiBtnDraw: i18n( "geo-aoi-btndraw" ),
92
+ aoiBtnClear: i18n( "geo-aoi-btnclear" ),
93
+ aoiBtnClose: i18n( "close" ),
94
+ geolocBtn: i18n( "geo-geoloc-btn" ),
95
+ geolocFail: i18n( "geo-geoloc-fail" ),
96
+ geolocUncapable: i18n( "geo-geoloc-uncapable" ),
97
+ geoLgndGrphc: i18n( "geo-lgnd-grphc" ),
98
+ dismiss: i18n( "dismiss" )
99
+ };
100
+ }
101
+
102
+ // Class-based overrides - use undefined where no override should occur
103
+ overrides = {
104
+ useScaleLine: className.indexOf( "scaleline" ) !== -1 ? true : undefined,
105
+ useMousePosition: className.indexOf( "position" ) !== -1 ? true : undefined,
106
+ useLegend: className.indexOf( "legend" ) !== -1,
107
+ useMapControls: className.indexOf( "static" ) !== -1 ? false : true,
108
+ useGeocoder: className.indexOf( "geocoder" ) !== -1 ? true : false,
109
+ useGeolocation: className.indexOf( "geolocation" ) !== -1 ? true : false,
110
+ useAOI: className.indexOf( "aoi" ) !== -1 ? true : false,
111
+ useAOIOpen: className.indexOf( "aoi-open" ) !== -1 ? true : false
112
+ };
113
+
114
+ // Merge default settings with overrides from the selected plugin element.
115
+ $.extend( settings, defaults, overrides, wb.getData( $elm, componentName ) );
116
+
117
+ // Load configuration file
118
+ if ( settings.layersFile ) {
119
+
120
+ $.ajax( {
121
+ url: settings.layersFile,
122
+ async: true,
123
+ dataType: "script",
124
+ success: function() {
125
+
126
+ // Extend settings with data loaded from the
127
+ // configuration file (through wet_boew_geomap)
128
+ settings = $.extend( settings, wet_boew_geomap );
129
+
130
+ // Support OSM basemap as defined prior v4.0.30, to be removed in v5.0
131
+ // Check if the basemap type is defined to xyz, if so change it to osm
132
+ if ( settings && settings.basemap && settings.basemap.type && settings.basemap.type === "xyz" ) {
133
+ settings.basemap.type = "osm";
134
+ }
135
+
136
+ // Create Geomap Object and add to map array
137
+ elm.geomap = new Geomap( { target: $elm, settings: settings } );
138
+ mapArray.push( elm.geomap );
139
+
140
+ }
141
+ } );
142
+
143
+ } else {
144
+
145
+ // Create Geomap Object and add to map array
146
+ elm.geomap = new Geomap( { target: $elm, settings: settings } );
147
+ mapArray.push( elm.geomap );
148
+ }
149
+
150
+ }
151
+
152
+ // Provide for easy access to OpenLayers olMap object
153
+ wb.getMap = function( id ) {
154
+ return getMapById( id );
155
+ };
156
+
157
+ //Provide for easy access to OpenLayers olLayer object
158
+ wb.getLayer = function( map, id ) {
159
+ return getLayerById( map, id );
160
+ };
161
+
162
+ },
163
+
164
+ /**
165
+ * Geomap Object
166
+ */
167
+ Geomap = function( options ) {
168
+
169
+ var $elm = options.target,
170
+ viewOptions = {};
171
+
172
+ this.id = $elm.attr( "id" );
173
+ this.mapLayers = [];
174
+ this.layerDiv = $elm.find( ".wb-geomap-layers" ).attr( "id", "geomap-layers-" + this.id );
175
+ this.legendDiv = $elm.find( ".wb-geomap-legend" ).attr( "id", "geomap-legend-" + this.id );
176
+ this.mapDiv = $elm.find( ".wb-geomap-map" ).attr( "id", "geomap-map-" + this.id );
177
+ this.settings = options.settings;
178
+ this.settings.aspectRatio = ( this.settings.basemap &&
179
+ this.settings.basemap.mapOptions &&
180
+ this.settings.basemap.mapOptions.aspectRatio !== undefined ) ?
181
+ this.settings.basemap.mapOptions.aspectRatio : 0.8;
182
+
183
+ this.map = createOLMap( this );
184
+ this.legend = new MapLegend( this );
185
+
186
+ // Add basemap data
187
+ viewOptions = this.addBasemap();
188
+
189
+ // The map view is set from the basedata
190
+ this.map.setView( new ol.View( viewOptions ) );
191
+
192
+ // Add map layers
193
+ this.addMapLayers();
194
+
195
+ // If an extent was configured, fit the map to it
196
+ if ( viewOptions.extent ) {
197
+ this.map.getView().fit( viewOptions.extent, this.map.getSize() );
198
+ }
199
+
200
+ // Get layer(s) by name
201
+ // Build a layer object containing features with "OL2 friendly" properties
202
+ // (( To be removed on next major version ))
203
+ var mapLayersCached = this.mapLayers;
204
+ this.map.getLayersByName = function( layerName ) {
205
+ var i, i_lyr,
206
+ i_len = mapLayersCached.length,
207
+ feature = {
208
+ popup: {
209
+ visible: function() {
210
+ return true;
211
+ }
212
+ },
213
+ geometry: {
214
+ bounds: ol.proj.transform( this.getOverlays().getArray()[ 0 ].getPosition(), "EPSG:3978", "EPSG:4326" )
215
+ }
216
+ };
217
+
218
+ for ( i = 0; i !== i_len; i += 1 ) {
219
+ i_lyr = mapLayersCached[ i ];
220
+ if ( i_lyr.id && i_lyr.id === layerName ) {
221
+ return [ { features: [ feature ] } ];
222
+ }
223
+ }
224
+ };
225
+
226
+ // Load Controls
227
+ this.loadControls();
228
+
229
+ // Set the title and aria-label text
230
+ this.accessibilize();
231
+
232
+ // Add the popup
233
+ this.createPopup();
234
+
235
+ // Do some housekeeping once map is ready
236
+ $document.on( "wb-ready.wb-geomap", "#" + this.id, function() {
237
+
238
+ // Remove the loader
239
+ $( "#" + this.id ).find( ".geomap-progress" ).remove();
240
+
241
+ } );
242
+
243
+ }, // End Geomap Object
244
+
245
+ /**
246
+ * MapLayer Object
247
+ *
248
+ * @param Object {Geomap}
249
+ * @param Object {options} MapLayer options
250
+ * @return Object {MapLayer}
251
+ */
252
+ MapLayer = function( map, options ) {
253
+
254
+ var _this = this,
255
+ visibilytyCallBackArr = [];
256
+
257
+ this.map = map;
258
+ this.settings = options;
259
+ this.id = this.settings.tableId ? this.settings.tableId : generateGuid();
260
+ this.layer = this.createOLLayer();
261
+ this.settings.accessible = ( typeof this.settings.accessible === "undefined" ) ? true : this.settings.accessible;
262
+ this.settings.visible = ( typeof this.settings.visible === "undefined" ) ? true : this.settings.visible;
263
+ this.settings.zoom = typeof this.settings.zoom === "undefined" ? true : this.settings.zoom;
264
+
265
+ // Add a section to hold the data table
266
+ if ( this.settings.accessible ) {
267
+ this.map.layerDiv.append( "<div class='panel panel-default'><div class='panel-heading'><div class='panel-title' role='heading'>" +
268
+ this.settings.title + "</div></div><div class='panel-body'><div data-layer='" +
269
+ this.id + "' class='geomap-table-wrapper' style='display:none;'></div></div></div>" );
270
+ }
271
+
272
+ // Make isVisibile Reactive
273
+ Object.defineProperty( _this, "isVisible", {
274
+ get: function get() {
275
+ return _this.visibilityState;
276
+ },
277
+ set: function set( newVal ) {
278
+ _this.visibilityState = newVal;
279
+
280
+ // Notify
281
+ visibilytyCallBackArr.forEach( function( signalHandler ) {
282
+
283
+ return signalHandler( newVal );
284
+ } );
285
+ }
286
+ } );
287
+
288
+ // Skip if layer is null
289
+ if ( !_this.layer ) {
290
+ return null;
291
+ }
292
+
293
+ // Allow the properties to be observed
294
+ this.observeVisibility = function( callback ) {
295
+ visibilytyCallBackArr.push( callback );
296
+ };
297
+
298
+ this.observeVisibility( function( vis ) {
299
+
300
+ var $table = $( "div[ data-layer='" + _this.id + "' ].geomap-table-wrapper" );
301
+
302
+ if ( !vis ) {
303
+ $table.fadeOut();
304
+ $table.parent().append( "<div class='layer-msg'><p>" + i18nText.hiddenLayer + "</p></div>" ).fadeIn();
305
+ } else {
306
+ $table.fadeIn();
307
+ $table.parent().find( ".layer-msg" ).remove();
308
+ }
309
+
310
+ _this.layer.setVisible( _this.isVisible );
311
+ } );
312
+
313
+
314
+ // Add to legend if legend is configured
315
+ if ( this.map.legendDiv.length !== 0 ) {
316
+ this.addToLegend();
317
+ }
318
+
319
+ this.isVisible = this.settings.visible;
320
+
321
+ return this;
322
+ },
323
+
324
+ /**
325
+ * MapLegend Object
326
+ *
327
+ * @param {Geomap}
328
+ * @return {MapLegend}
329
+ */
330
+ MapLegend = function( map ) {
331
+
332
+ this.map = map;
333
+ this.symbolMapArray = [];
334
+ this.target = $( "#" + map.id + ".wb-geomap" ).find( ".wb-geomap-legend" );
335
+ this.target.attr( "id", "geomap-legend-" + map.id );
336
+
337
+ // remove the placehoders
338
+ this.target.empty();
339
+
340
+ return this;
341
+ },
342
+
343
+ /**
344
+ * Get ol.interaction.Interaction
345
+ */
346
+ getMapInteraction = function( map, interactionType ) {
347
+ var intrctn;
348
+ map.getInteractions().forEach( function( interaction ) {
349
+ if ( interaction instanceof interactionType ) {
350
+ intrctn = interaction;
351
+ }
352
+ } );
353
+ return intrctn;
354
+ },
355
+
356
+ setRendererDimensions = function( id, map, feature, symbolWidth, symbolHeight ) {
357
+
358
+ var gb = feature.getGeometry().getExtent(),
359
+ gw = ol.extent.getWidth( gb ),
360
+ gh = ol.extent.getHeight( gb ),
361
+ el = $( "#" + id ),
362
+ bhalfw, bhalfh, bounds, center, resolution, height, width;
363
+
364
+ /*
365
+ * Determine resolution based on the following rules:
366
+ * 1) always use value specified in config
367
+ * 2) if not specified, use max res based on width or height of element
368
+ * 3) if no width or height, assume a resolution of 1
369
+ */
370
+ resolution = 1;
371
+ if ( !resolution ) {
372
+ resolution = Math.max(
373
+ gw / symbolWidth || 0,
374
+ gh / symbolHeight || 0
375
+ ) || 1;
376
+ }
377
+ map.setView( new ol.View( {
378
+ minResolution: resolution,
379
+ maxResolution: resolution,
380
+ projection: new ol.proj.Projection( {
381
+ code: "",
382
+ units: "pixels"
383
+ } )
384
+ } ) );
385
+
386
+ // determine height and width of element
387
+ width = Math.max( symbolWidth, gw / resolution );
388
+ height = Math.max( symbolHeight, gh / resolution );
389
+
390
+ // determine bounds of renderer
391
+ center = ol.extent.getCenter( gb );
392
+ bhalfw = width * resolution / 2;
393
+ bhalfh = height * resolution / 2;
394
+ bounds = [ center[ 0 ] - bhalfw, center[ 1 ] - bhalfh, center[ 0 ] + bhalfw, center[ 1 ] + bhalfh ];
395
+ el.width( Math.round( width ) );
396
+ el.height( Math.round( height ) );
397
+
398
+ map.updateSize();
399
+ map.getView().fit( bounds, map.getSize() );
400
+
401
+ },
402
+
403
+ defaultColors = function() {
404
+
405
+ var fill = hexToRGB( wb.drawColours[ colourIndex ], 0.5 ),
406
+ stroke = hexToRGB( wb.drawColours[ colourIndex ], 1.0 ),
407
+ colors = { fill: fill, stroke: stroke, transparent: [ 0, 0, 0, 0 ] };
408
+
409
+ // Increment the colour index
410
+ colourIndex += 1;
411
+ if ( colourIndex === wb.drawColours.length ) {
412
+ colourIndex = 0;
413
+ }
414
+
415
+ return colors;
416
+ },
417
+
418
+ StyleFactory = function() {
419
+
420
+ var colors = defaultColors(),
421
+ externalGraphic, graphicHeight, graphicWidth, graphicName, style, styleType,
422
+ fillColor, opacity, radius, strokeColor, strokeDash, strokeWidth;
423
+
424
+ this.createStyleFunction = function( theStyle, featureType ) {
425
+ style = theStyle;
426
+ styleType = style && style.type ? style.type : "default";
427
+
428
+ // called on each feature
429
+ return function( feature ) {
430
+
431
+ if ( styleType === "rule" ) {
432
+
433
+ return new RuleStyle( feature, featureType );
434
+
435
+ } else if ( styleType === "symbol" ) {
436
+
437
+ return new SymbolStyle();
438
+
439
+ } else if ( styleType === "default" ) {
440
+
441
+ return new DefaultStyle( feature, featureType );
442
+
443
+ } else if ( styleType === "unique" ) {
444
+
445
+ return new UniqueStyle( feature, featureType );
446
+
447
+ } else if ( styleType === "select" ) {
448
+
449
+ return new SelectStyle( feature, featureType );
450
+
451
+ }
452
+
453
+ };
454
+
455
+ };
456
+
457
+ var RuleStyle = function( feature ) {
458
+
459
+ var styleRule = style.rule,
460
+ len = styleRule.length,
461
+ operators = {
462
+ "EQUAL_TO": function( a, b ) {
463
+ return String( a ) === String( b[ 0 ] );
464
+ },
465
+ "GREATER_THAN": function( a, b ) {
466
+ return a > b[ 0 ];
467
+ },
468
+ "LESS_THAN": function( a, b ) {
469
+ return a < b[ 0 ];
470
+ },
471
+ "BETWEEN": function( a, b ) {
472
+ return a >= b[ 0 ] && a <= b[ 1 ];
473
+ }
474
+ },
475
+ featureType = feature && feature.getGeometry() ? feature.getGeometry().getType() : "Polygon",
476
+ rule, ruleFilter;
477
+
478
+ for ( var i = 0; i !== len; i += 1 ) {
479
+
480
+ // Set the filter
481
+ rule = styleRule[ i ];
482
+ ruleFilter = rule.filter;
483
+
484
+ // Set the style elements
485
+ strokeDash = rule.init.strokeDash ? rule.init.strokeDash : [ 1, 0 ];
486
+ strokeWidth = rule.init.strokeWidth ? rule.init.strokeWidth : 1.0;
487
+ opacity = rule.init.fillOpacity ? rule.init.fillOpacity : rule.init.graphicOpacity ? rule.init.graphicOpacity : 0.5;
488
+ radius = rule.init.pointRadius ? rule.init.pointRadius : 5;
489
+ strokeColor = rule.init.strokeColor ? hexToRGB( rule.init.strokeColor, opacity ) : colors.transparent;
490
+ fillColor = hexToRGB( rule.init.fillColor, opacity );
491
+ graphicName = rule.init.graphicName ? rule.init.graphicName : null;
492
+ externalGraphic = rule.init.externalGraphic ? rule.init.externalGraphic : null;
493
+ graphicHeight = rule.init.graphicHeight ? rule.init.graphicHeight : 25;
494
+ graphicWidth = rule.init.graphicWidth ? rule.init.graphicWidth : 25;
495
+
496
+ if ( operators[ ruleFilter ]( feature.attributes[ rule.field ], rule.value ) ) {
497
+ switch ( featureType ) {
498
+ case "Polygon" || "MultiPolygon":
499
+ return getPolygonStyle( {
500
+ fill: new ol.style.Fill( { color: fillColor } ),
501
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
502
+ } );
503
+ case "Point" || "MultiPoint":
504
+ if ( graphicName ) {
505
+ return getSymbolStyle( {
506
+ symbol: graphicName,
507
+ fill: new ol.style.Fill( { color: fillColor } ),
508
+ stroke: new ol.style.Stroke( { color: strokeColor, lineDash: strokeDash } ),
509
+ radius: radius
510
+ } );
511
+ } else if ( externalGraphic ) {
512
+ return getIconStyle( {
513
+ src: externalGraphic,
514
+ opacity: opacity,
515
+ size: [ graphicWidth, graphicHeight ]
516
+ } );
517
+ } else {
518
+ return getPointStyle( {
519
+ radius: radius,
520
+ fill: new ol.style.Fill( { color: fillColor } ),
521
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
522
+ } );
523
+ }
524
+ case "LineString" || "MultiLineString":
525
+ return getLineStyle( {
526
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
527
+ } );
528
+ default:
529
+ return getPolygonStyle( {
530
+ fill: new ol.style.Fill( { color: fillColor } ),
531
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
532
+ } );
533
+ }
534
+
535
+ }
536
+ }
537
+
538
+ };
539
+
540
+ var SymbolStyle = function() {
541
+
542
+ // Set the style elements
543
+ opacity = style.init.fillOpacity ? style.init.fillOpacity : style.init.graphicOpacity ? style.init.graphicOpacity : 1.0;
544
+ radius = style.init.pointRadius ? style.init.pointRadius : 5;
545
+ strokeColor = style.init.strokeColor ? hexToRGB( style.init.strokeColor, opacity ) : colors.transparent;
546
+ fillColor = hexToRGB( style.init.fillColor, opacity );
547
+ graphicName = style.init.graphicName ? style.init.graphicName : null;
548
+ externalGraphic = style.init.externalGraphic ? style.init.externalGraphic : null;
549
+ graphicHeight = style.init.graphicHeight ? style.init.graphicHeight : 25;
550
+ graphicWidth = style.init.graphicWidth ? style.init.graphicWidth : 25;
551
+
552
+ if ( graphicName ) {
553
+ return getSymbolStyle( {
554
+ symbol: style.init.graphicName,
555
+ fill: new ol.style.Fill( { color: fillColor } ),
556
+ stroke: new ol.style.Stroke( { color: strokeColor, lineDash: strokeDash } ),
557
+ radius: radius
558
+ } );
559
+ } else if ( externalGraphic ) {
560
+ return getIconStyle( {
561
+ src: externalGraphic,
562
+ opacity: opacity,
563
+ size: [ graphicWidth, graphicHeight ]
564
+ } );
565
+ } else {
566
+ return getPointStyle( {
567
+ radius: radius,
568
+ fill: new ol.style.Fill( { color: fillColor } ),
569
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth } )
570
+ } );
571
+ }
572
+
573
+ };
574
+
575
+ var DefaultStyle = function() {
576
+
577
+ opacity = style.fillOpacity ? style.fillOpacity : style.graphicOpacity ? style.graphicOpacity : 1.0;
578
+ fillColor = style.fillColor ? hexToRGB( style.fillColor, opacity ) : colors.transparent;
579
+ strokeColor = style.strokeColor ? hexToRGB( style.strokeColor, opacity ) : colors.transparent;
580
+ strokeWidth = style.strokeWidth ? style.strokeWidth : 1.0;
581
+ strokeDash = style.strokeDash ? style.strokeDash : [ 1, 0 ];
582
+
583
+ return [ new ol.style.Style( {
584
+ image: new ol.style.Circle( {
585
+ fill: new ol.style.Fill( { color: fillColor } ),
586
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } ),
587
+ radius: 5
588
+ } ),
589
+ fill: new ol.style.Fill( { color: fillColor } ),
590
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
591
+ } ) ];
592
+
593
+ };
594
+
595
+ var UniqueStyle = function( feature, featureType ) {
596
+
597
+ var field = style.field,
598
+ obj, objStyle;
599
+
600
+ for ( obj in style.init ) {
601
+ objStyle = style.init[ obj ];
602
+
603
+ strokeDash = objStyle.strokeDash ? objStyle.strokeDash : [ 1, 0 ];
604
+ strokeWidth = objStyle.strokeWidth ? objStyle.strokeWidth : 1.0;
605
+ opacity = objStyle.fillOpacity ? objStyle.fillOpacity : objStyle.graphicOpacity ? objStyle.graphicOpacity : 0.5;
606
+ radius = objStyle.pointRadius ? objStyle.pointRadius : 5;
607
+ strokeColor = objStyle.strokeColor ? hexToRGB( objStyle.strokeColor, opacity ) : colors.transparent;
608
+ fillColor = objStyle.fillColor ? hexToRGB( objStyle.fillColor, opacity ) : null;
609
+ graphicHeight = objStyle.graphicHeight ? objStyle.graphicHeight : 25;
610
+ externalGraphic = objStyle.externalGraphic;
611
+ graphicWidth = objStyle.graphicWidth ? objStyle.graphicWidth : 25;
612
+
613
+ switch ( featureType ) {
614
+ case "Polygon" || "MultiPolygon":
615
+ if ( feature.attributes && feature.attributes[ field ] === obj ) {
616
+ return getPolygonStyle( {
617
+ fill: new ol.style.Fill( { color: fillColor } ),
618
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
619
+ } );
620
+ }
621
+ break;
622
+ case "Point" || "MultiPoint":
623
+ if ( externalGraphic ) {
624
+ if ( feature.attributes && feature.attributes[ field ] === obj ) {
625
+ return getIconStyle( {
626
+ src: externalGraphic,
627
+ opacity: opacity,
628
+ size: [ graphicWidth, graphicHeight ]
629
+ } );
630
+ }
631
+ } else {
632
+ if ( feature.attributes && feature.attributes[ field ] === obj ) {
633
+ return getPointStyle( {
634
+ radius: radius,
635
+ fill: new ol.style.Fill( { color: fillColor } ),
636
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
637
+ } );
638
+ }
639
+ }
640
+ break;
641
+ case "LineString" || "MultiLineString":
642
+ if ( feature.attributes && feature.attributes[ field ] === obj ) {
643
+ return getLineStyle( {
644
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
645
+ } );
646
+ }
647
+ break;
648
+ default:
649
+ if ( feature.attributes && feature.attributes[ field ] === obj ) {
650
+ return getPolygonStyle( {
651
+ fill: new ol.style.Fill( { color: fillColor } ),
652
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
653
+ } );
654
+ }
655
+ break;
656
+ }
657
+
658
+ }
659
+
660
+ };
661
+
662
+ var SelectStyle = function( feature, featureType ) {
663
+
664
+ strokeDash = style.strokeDash ? style.strokeDash : [ 1, 0 ];
665
+ strokeWidth = style.strokeWidth ? style.strokeWidth : 1.0;
666
+ opacity = style.fillOpacity ? style.fillOpacity : style.graphicOpacity ? style.graphicOpacity : 0.5;
667
+ radius = style.pointRadius ? style.pointRadius : 5;
668
+ strokeColor = style.strokeColor ? hexToRGB( style.strokeColor, opacity ) : colors.transparent;
669
+ fillColor = style.fillColor ? hexToRGB( style.fillColor, opacity ) : null;
670
+ graphicHeight = style.graphicHeight ? style.graphicHeight : 25;
671
+ externalGraphic = style.externalGraphic;
672
+ graphicWidth = style.graphicWidth ? style.graphicWidth : 25;
673
+
674
+ switch ( featureType ) {
675
+ case "Polygon" || "MultiPolygon":
676
+ return getPolygonStyle( {
677
+ fill: new ol.style.Fill( { color: fillColor } ),
678
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
679
+ } );
680
+ case "Point" || "MultiPoint":
681
+ if ( externalGraphic ) {
682
+ return getIconStyle( {
683
+ src: externalGraphic,
684
+ opacity: opacity,
685
+ size: [ graphicWidth, graphicHeight ]
686
+ } );
687
+ } else {
688
+ return getPointStyle( {
689
+ radius: radius,
690
+ fill: new ol.style.Fill( { color: fillColor } ),
691
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
692
+ } );
693
+ }
694
+
695
+ case "LineString" || "MultiLineString":
696
+ return getLineStyle( {
697
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
698
+ } );
699
+
700
+ default:
701
+ return getPolygonStyle( {
702
+ fill: new ol.style.Fill( { color: fillColor } ),
703
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
704
+ } );
705
+ }
706
+
707
+ };
708
+
709
+ },
710
+
711
+ /**
712
+ * Symbol Style
713
+ * @param symbolizer { obj } - style attributes
714
+ */
715
+
716
+ //TODO: add stroke width
717
+ getSymbolStyle = function( symbolizer ) {
718
+
719
+ var symbols = {
720
+ "square": [ new ol.style.Style( {
721
+ image: new ol.style.RegularShape( {
722
+ fill: symbolizer.fill,
723
+ stroke: symbolizer.stroke,
724
+ points: 4,
725
+ radius: symbolizer.radius,
726
+ angle: Math.PI / 4
727
+ } )
728
+ } ) ],
729
+ "triangle": [ new ol.style.Style( {
730
+ image: new ol.style.RegularShape( {
731
+ fill: symbolizer.fill,
732
+ stroke: symbolizer.stroke,
733
+ points: 3,
734
+ radius: symbolizer.radius,
735
+ rotation: Math.PI / 4,
736
+ angle: 0
737
+ } )
738
+ } ) ],
739
+ "star": [ new ol.style.Style( {
740
+ image: new ol.style.RegularShape( {
741
+ fill: symbolizer.fill,
742
+ stroke: symbolizer.stroke,
743
+ points: 5,
744
+ radius: symbolizer.radius,
745
+ radius2: symbolizer.radius * 0.4,
746
+ angle: 0
747
+ } )
748
+ } ) ],
749
+ "cross": [ new ol.style.Style( {
750
+ image: new ol.style.RegularShape( {
751
+ fill: symbolizer.fill,
752
+ stroke: symbolizer.stroke,
753
+ points: 4,
754
+ radius: symbolizer.radius,
755
+ radius2: 0,
756
+ angle: 0
757
+ } )
758
+ } ) ],
759
+ "x": [ new ol.style.Style( {
760
+ image: new ol.style.RegularShape( {
761
+ fill: symbolizer.fill,
762
+ stroke: symbolizer.stroke,
763
+ points: 4,
764
+ radius: symbolizer.radius,
765
+ radius2: 0,
766
+ angle: Math.PI / 4
767
+ } )
768
+ } ) ]
769
+ };
770
+
771
+ return symbols[ symbolizer.symbol ];
772
+ },
773
+
774
+ /**
775
+ * Icon Style
776
+ * @param symbolizer { obj } - style attributes
777
+ */
778
+ getIconStyle = function( symbolizer ) {
779
+
780
+ return [ new ol.style.Style( {
781
+ image: new ol.style.Icon( ( {
782
+ opacity: symbolizer.opacity,
783
+ src: symbolizer.src,
784
+ size: symbolizer.size
785
+ } ) )
786
+ } ) ];
787
+
788
+ },
789
+
790
+ /**
791
+ * Point Style
792
+ * @param symbolizer { obj } - style attributes
793
+ */
794
+ getPointStyle = function( symbolizer ) {
795
+
796
+ return [ new ol.style.Style( {
797
+ image: new ol.style.Circle( ( {
798
+ radius: symbolizer.radius,
799
+ fill: symbolizer.fill,
800
+ stroke: symbolizer.stroke
801
+ } ) )
802
+ } ) ];
803
+
804
+ },
805
+
806
+ /**
807
+ * Polygon Style
808
+ * @param symbolizer { obj } - style attributes
809
+ */
810
+ getPolygonStyle = function( symbolizer ) {
811
+ return [ new ol.style.Style( {
812
+ fill: symbolizer.fill,
813
+ stroke: symbolizer.stroke
814
+ } ) ];
815
+ },
816
+
817
+ /**
818
+ * Line Style
819
+ * @param symbolizer { obj } - style attributes
820
+ */
821
+ getLineStyle = function( symbolizer ) {
822
+ return [ new ol.style.Style( {
823
+ stroke: symbolizer.stroke
824
+ } ) ];
825
+ },
826
+
827
+ // Convert a hexidecimal color string to 0..255 R,G,B for backwards compatibility
828
+ hexToRGB = function( code, alpha ) {
829
+
830
+ var hex = ( code + "" ).trim(),
831
+ rgb = null,
832
+ match = hex.match( /^#?(([0-9a-zA-Z]{3}){1,3})$/ ),
833
+ a = alpha ? alpha : 1.0;
834
+
835
+ if ( !match ) {
836
+ return code;
837
+ }
838
+
839
+ hex = match[ 1 ];
840
+
841
+ if ( hex.length === 6 ) {
842
+ rgb = [ parseInt( hex.substring( 0, 2 ), 16 ), parseInt( hex.substring( 2, 4 ), 16 ), parseInt( hex.substring( 4, 6 ), 16 ), a ];
843
+ } else if ( hex.length === 3 ) {
844
+ rgb = [ parseInt( hex.substring( 0, 1 ) + hex.substring( 0, 1 ), 16 ), parseInt( hex.substring( 1, 2 ) + hex.substring( 1, 2 ), 16 ), parseInt( hex.substring( 2, 3 ) + hex.substring( 2, 3 ), 16 ), a ];
845
+ }
846
+
847
+ return rgb;
848
+ },
849
+
850
+ /**
851
+ * Add the checkbox to the column
852
+ *
853
+ */
854
+ addChkBox = function( mapLayer, feature ) {
855
+
856
+ return "<label class='wb-inv' for='cb_" + feature.getId() + "'>" +
857
+ i18nText.labelSelect + "</label><input type='checkbox' id='cb_" +
858
+ feature.getId() + "' class='geomap-cbx' data-map='" + mapLayer.map.id +
859
+ "' data-layer='" + feature.layerId + "' data-feature='" +
860
+ feature.getId() + "' />";
861
+ },
862
+
863
+ /**
864
+ * Add zoom button to table columns
865
+ */
866
+ addZoomTo = function( mapLayer, feature ) {
867
+ return "<a href='javascript:;' data-map='" + mapLayer.map.id +
868
+ "' data-layer='" + feature.layerId + "' data-feature='" + feature.getId() +
869
+ "' class='btn btn-link geomap-zoomto' alt='" + i18nText.zoomFeature + "' role='button'><span class='glyphicon glyphicon-zoom-in'></span></a>";
870
+ },
871
+
872
+ /**
873
+ * Show popup
874
+ */
875
+ showPopup = function( evt, feature, map ) {
876
+
877
+ if ( !feature ) {
878
+ return;
879
+ }
880
+
881
+ var overlay = map.getOverlays().getArray()[ 0 ],
882
+ $popup = $( document.getElementById( "popup-geomap-map-" + map.id ) ),
883
+ content = "",
884
+ layer = getLayerById( map, feature.layerId );
885
+
886
+ if ( feature && feature.attributes ) {
887
+ var geometry = feature.getGeometry(),
888
+ coord = geometry.getType() === "Point" ? geometry.getCoordinates() : event.mapBrowserEvent.coordinate,
889
+ obj = feature.attributes,
890
+ key, regex;
891
+
892
+ if ( layer.popupsInfo ) {
893
+
894
+ content += layer.popupsInfo.content;
895
+
896
+ for ( key in obj ) {
897
+ if ( Object.prototype.hasOwnProperty.call( obj, key ) ) {
898
+ regex = new RegExp( "_" + key, "igm" );
899
+ content = content.replace( regex, obj[ key ] );
900
+ }
901
+ }
902
+
903
+ } else {
904
+
905
+ for ( key in obj ) {
906
+ if ( Object.prototype.hasOwnProperty.call( obj, key ) ) {
907
+ content += "<tr><th><strong>" + key + "</strong></th><td> " + obj[ key ] + "</td></tr>";
908
+ }
909
+ }
910
+
911
+ }
912
+
913
+ $popup.find( ".popup-content" ).html( "<h5>" + feature.layerTitle + "</h5><table style='width:100%;'>" + content + "</table>" );
914
+ overlay.setPosition( coord );
915
+
916
+ } else {
917
+ overlay.setPosition( undefined );
918
+ }
919
+
920
+ },
921
+
922
+ /**
923
+ * Parse layer configuration keys
924
+ */
925
+ getLayerKeys = function( obj ) {
926
+ var key, keys = {};
927
+ for ( key in obj ) {
928
+ if ( Object.prototype.hasOwnProperty.call( obj, key ) ) {
929
+ if ( key !== "type" && key !== "caption" && key !== "url" && key !== "title" ) {
930
+ keys[ key ] = obj[ key ];
931
+ }
932
+ }
933
+ }
934
+ return keys;
935
+ },
936
+
937
+ /**
938
+ * Remove key
939
+ */
940
+ removeKeys = function( obj, k ) {
941
+ var key, keys = {};
942
+ for ( key in obj ) {
943
+ if ( Object.prototype.hasOwnProperty.call( obj, key ) ) {
944
+ if ( $.inArray( key, k ) < 0 ) {
945
+ keys[ key ] = obj[ key ];
946
+ }
947
+ }
948
+ }
949
+ return keys;
950
+ },
951
+
952
+ /*
953
+ * Remove null keys
954
+ */
955
+ removeNullKeys = function( obj ) {
956
+ var key, keys = {};
957
+ for ( key in obj ) {
958
+ if ( Object.prototype.hasOwnProperty.call( obj, key ) ) {
959
+ if ( obj[ key ] !== null ) {
960
+ keys[ key ] = obj[ key ];
961
+ }
962
+ }
963
+ }
964
+ return keys;
965
+ },
966
+
967
+ /**
968
+ * Create map
969
+ *
970
+ * @return {ol.map} an OpenLayers map.
971
+ */
972
+ createOLMap = function( geomap ) {
973
+
974
+ var controls = geomap.settings.useMapControls ? ol.control.defaults( {
975
+ attributionOptions: ( {
976
+ collapsible: false
977
+ } )
978
+ } ) : [],
979
+ interactions = geomap.settings.useMapControls ? ol.interaction.defaults( {
980
+ mouseWheelZoom: true
981
+ } ) : [],
982
+ intrctn;
983
+
984
+ // Add projection for default base map
985
+ proj4.defs( "EPSG:3978", "+proj=lcc +lat_1=49 +lat_2=77 +lat_0=49 +lon_0=-95 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs" );
986
+
987
+ // Add projection alias
988
+ proj4.defs( "urn:ogc:def:crs:OGC:1.3:CRS84", proj4.defs( "EPSG:4326" ) );
989
+
990
+ // Create the OpenLayers Map Object
991
+ var map = new ol.Map( {
992
+ controls: controls,
993
+ interactions: interactions,
994
+ logo: false,
995
+ target: geomap.mapDiv.attr( "id" )
996
+ } );
997
+
998
+ intrctn = getMapInteraction( map, ol.interaction.MouseWheelZoom );
999
+
1000
+ // Disable the mouseWheelZoom until the user focuses on the map
1001
+ if ( geomap.settings.useMapControls && intrctn ) {
1002
+ intrctn.setActive( false );
1003
+ }
1004
+
1005
+ geomap.mapDiv.height( geomap.mapDiv.width() * geomap.settings.aspectRatio );
1006
+ map.set( "aspectRatio", geomap.settings.aspectRatio );
1007
+ map.id = geomap.id;
1008
+
1009
+ // Once the map is rendered fire ready event
1010
+ map.once( "postrender", function() {
1011
+
1012
+ // v4.0.x transition function to support static map.
1013
+ // The following makes assumption the geometry only inlude a point and it is WKT format
1014
+ // The following should be removed in WET 5
1015
+ map.getLayer = function( strSelector ) {
1016
+
1017
+ var geometryElm = document.querySelector( strSelector + " [data-geometry][data-type]" ),
1018
+ geometry = geometryElm.dataset.geometry,
1019
+ geometryType = geometryElm.dataset.type,
1020
+ latitudes, longitudes;
1021
+
1022
+ // Provide support wkt with a POINT geometry, like the demo of the Static map with open layer 2
1023
+ if ( geometryType === "wkt" && geometry.indexOf( "POINT" ) !== -1 ) {
1024
+ geometry = geometry.replace( /,/, "" );
1025
+ geometry = geometry.substring( geometry.indexOf( "(" ) + 1, geometry.indexOf( ")" ) );
1026
+ geometry = geometry.split( " " );
1027
+
1028
+ latitudes = parseFloat( geometry[ 0 ] );
1029
+ longitudes = parseFloat( geometry[ 1 ] );
1030
+
1031
+ }
1032
+ return {
1033
+ getDataExtent: function() {
1034
+ return [ latitudes, longitudes ];
1035
+ }
1036
+ };
1037
+ };
1038
+
1039
+ map.zoomToExtent = function( layerCoordinates ) {
1040
+ map.getView().setCenter( ol.proj.transform( [ layerCoordinates[ 0 ], layerCoordinates[ 1 ] ], "EPSG:4326", "EPSG:3978" ) );
1041
+ map.getView().setZoom( 5 );
1042
+ };
1043
+
1044
+ wb.ready( $( "#" + geomap.id ), componentName, [ map ] );
1045
+ } );
1046
+
1047
+ // Everytime the map view is changed, fire the updated event
1048
+ map.on( "moveend", function() {
1049
+ $( geomap.id ).trigger( "wb-updated" + selector, [ geomap.map ] );
1050
+ } );
1051
+
1052
+ geomap.mapDiv.append( "<div id='tooltip_" + geomap.id + "' style='display:none;'><span class='tooltip-txt'></span></div>" );
1053
+
1054
+ var displayFeatureInfo = function( pixel ) {
1055
+
1056
+ tooltip = $( "#tooltip_" + geomap.id );
1057
+
1058
+ var tooltipTxt = $( "#tooltip_" + geomap.id + " span.tooltip-txt" ),
1059
+ feature;
1060
+
1061
+ tooltip.css( {
1062
+ left: pixel[ 0 ] + "px",
1063
+ top: ( pixel[ 1 ] - 15 ) + "px",
1064
+ position: "absolute"
1065
+ } );
1066
+
1067
+ feature = map.forEachFeatureAtPixel( pixel, function( feature ) {
1068
+ return feature;
1069
+ } );
1070
+
1071
+ if ( feature && feature.tooltip ) {
1072
+ tooltip.hide();
1073
+ tooltipTxt.html( feature.tooltip );
1074
+ tooltip.show();
1075
+ } else {
1076
+ tooltip.hide();
1077
+ }
1078
+ };
1079
+
1080
+ map.on( "pointermove", function( event ) {
1081
+
1082
+ tooltip = $( "#tooltip_" + geomap.id );
1083
+
1084
+ if ( event.dragging ) {
1085
+ tooltip.hide();
1086
+ return;
1087
+ }
1088
+ displayFeatureInfo( map.getEventPixel( event.originalEvent ) );
1089
+
1090
+ return;
1091
+ } );
1092
+
1093
+ return map;
1094
+
1095
+ },
1096
+
1097
+ /**
1098
+ * Get the OpenLayers map object by id
1099
+ *
1100
+ * @return {Geomap}
1101
+ */
1102
+ getMapById = function( id ) {
1103
+
1104
+ var mapArrayItem, len;
1105
+
1106
+ for ( len = mapArray.length - 1; len !== -1; len -= 1 ) {
1107
+ mapArrayItem = mapArray[ len ];
1108
+ if ( mapArrayItem.id === id ) {
1109
+ return mapArrayItem;
1110
+ }
1111
+ }
1112
+ return;
1113
+ },
1114
+
1115
+ /**
1116
+ * Area of Interest (AOI) Widget
1117
+ */
1118
+ AOIWidget = function( geomap ) {
1119
+
1120
+ var interaction = new ol.interaction.DragBox(),
1121
+ projLatLon = new ol.proj.Projection( { code: "EPSG:4326" } ),
1122
+ projMap = geomap.map.getView().getProjection();
1123
+
1124
+ // Handle the draw end event
1125
+ interaction.on( "boxend", function() {
1126
+
1127
+ var extent = interaction.getGeometry().transform( projMap, projLatLon ).getExtent();
1128
+
1129
+ geomProj = drawAOI( geomap, extent );
1130
+
1131
+ // zoom to extent of feature
1132
+ geomap.map.getView().fit( geomProj.getGeometry().getExtent(), geomap.map.getSize() );
1133
+
1134
+ // Round extent to step value of input controls
1135
+ $( "#geomap-aoi-minx-" + geomap.id ).val( extent[ 0 ].toFixed( 6 ) );
1136
+ $( "#geomap-aoi-maxx-" + geomap.id ).val( extent[ 2 ].toFixed( 6 ) );
1137
+ $( "#geomap-aoi-maxy-" + geomap.id ).val( extent[ 3 ].toFixed( 6 ) );
1138
+ $( "#geomap-aoi-miny-" + geomap.id ).val( extent[ 1 ].toFixed( 6 ) );
1139
+
1140
+ $( "#geomap-aoi-extent-" + geomap.id ).val( geomProj.getGeometry().getExtent() ).trigger( "change" );
1141
+ $( "#geomap-aoi-extent-lonlat-" + geomap.id ).val( extent[ 0 ] + ", " + extent[ 1 ] + ", " + extent[ 2 ] + ", " + extent[ 3 ] ).trigger( "change" );
1142
+
1143
+ } );
1144
+
1145
+ // Clear selection when drawing a new box and when clicking on the map
1146
+ interaction.on( "boxstart", function() {
1147
+ getLayerById( geomap.map, "locLayer" ).getSource().clear( true );
1148
+ } );
1149
+
1150
+ geomap.map.addInteraction( interaction );
1151
+
1152
+ interaction.setActive( false );
1153
+
1154
+ if ( geomap.settings.useAOIOpen ) {
1155
+ geomap.mapDiv.before( "<div class='geomap-aoi panel panel-default'><div id='geomap-aoi-" + geomap.id + "' class='panel-body'></div></div>" );
1156
+ } else {
1157
+ geomap.mapDiv.before( "<details class='geomap-aoi'><summary>" + i18nText.aoiTitle + "</summary><div id='geomap-aoi-" + geomap.id + "'></div></details>" );
1158
+ }
1159
+
1160
+ var aoiDiv = $( "#geomap-aoi-" + geomap.id ),
1161
+ extent, left, bottom, right, top, geomProj;
1162
+
1163
+ aoiDiv.append( "<fieldset id='form-aoi-" + geomap.id + "'>" +
1164
+ "<legend tabindex='-1'>" + i18nText.aoiInstructions + "</legend>" +
1165
+ "<div class='row'>" +
1166
+ "<div class='col-md-2 form-group'>" +
1167
+ "<label for='geomap-aoi-maxy-" + geomap.id + "' class='wb-inv'>" + i18nText.aoiNorth + "</label>" +
1168
+ "<div class='input-group input-group-sm'>" +
1169
+ "<span class='input-group-addon'>" + i18nText.aoiNorth.charAt( 0 ) + "</span>" +
1170
+ "<input type='number' id='geomap-aoi-maxy-" + geomap.id + "' placeholder='90' class='form-control input-sm' min='-90' max='90' step='0.000001'></input>" +
1171
+ "</div>" +
1172
+ "</div>" +
1173
+ "<div class='col-md-2 form-group'>" +
1174
+ "<label for='geomap-aoi-maxx-" + geomap.id + "' class='wb-inv'>" + i18nText.aoiEast + "</label>" +
1175
+ "<div class='input-group input-group-sm'>" +
1176
+ "<span class='input-group-addon'>" + i18nText.aoiEast.charAt( 0 ) + "</span>" +
1177
+ "<input type='number' id='geomap-aoi-maxx-" + geomap.id + "' placeholder='180' class='form-control input-sm' min='-180' max='180' step='0.000001'></input> " +
1178
+ "</div>" +
1179
+ "</div>" +
1180
+ "<div class='col-md-2 form-group'>" +
1181
+ "<label for='geomap-aoi-miny-" + geomap.id + "' class='wb-inv'>" + i18nText.aoiSouth + "</label>" +
1182
+ "<div class='input-group input-group-sm'>" +
1183
+ "<span class='input-group-addon'>" + i18nText.aoiSouth.charAt( 0 ) + "</span>" +
1184
+ "<input type='number' id='geomap-aoi-miny-" + geomap.id + "' placeholder='-90' class='form-control input-sm' min='-90' max='90' step='0.000001'></input> " +
1185
+ "</div>" +
1186
+ "</div>" +
1187
+ "<div class='col-md-2 form-group'>" +
1188
+ "<label for='geomap-aoi-minx-" + geomap.id + "' class='wb-inv'>" + i18nText.aoiWest + "</label>" +
1189
+ "<div class='input-group input-group-sm'>" +
1190
+ "<span class='input-group-addon'>" + i18nText.aoiWest.charAt( 0 ) + "</span>" +
1191
+ "<input type='number' id='geomap-aoi-minx-" + geomap.id + "' placeholder='-180' class='form-control input-sm' min='-180' max='180' step='0.000001'></input> " +
1192
+ "</div>" +
1193
+ "</div>" +
1194
+ "<div class='col-md-4'>" +
1195
+ "<button class='btn btn-default btn-sm' id='geomap-aoi-btn-draw-" + geomap.id + "'>" + i18nText.add + "</button> " +
1196
+ "<button class='btn btn-default btn-sm' id='geomap-aoi-btn-clear-" + geomap.id + "'>" + i18nText.aoiBtnClear + "</button> " +
1197
+ "</div>" +
1198
+ "</div>" +
1199
+ "<input type='hidden' id='geomap-aoi-extent-" + geomap.id + "'></input>" +
1200
+ "<input type='hidden' id='geomap-aoi-extent-lonlat-" + geomap.id + "'></input>" +
1201
+ "</fieldset>" );
1202
+
1203
+ $( "#geomap-aoi-btn-clear-" + geomap.id ).after( "<button id='geomap-aoi-toggle-mode-draw-" + geomap.id +
1204
+ "' href='#' class='btn btn-sm btn-default geomap-geoloc-aoi-btn' title='" + i18nText.aoiBtnDraw +
1205
+ "'><i class='glyphicon glyphicon-edit'></i> " +
1206
+ i18nText.aoiBtnDraw + "</button>" );
1207
+
1208
+ // toggle draw mode
1209
+ $document.on( "click", "#geomap-aoi-toggle-mode-draw-" + geomap.id, function( event ) {
1210
+
1211
+ event.preventDefault();
1212
+
1213
+ var drawInteraction = getMapInteraction( geomap.map, ol.interaction.DragBox ),
1214
+ selectInteraction = getMapInteraction( geomap.map, ol.interaction.Select ),
1215
+ active = interaction.getActive(),
1216
+ $aoiElm = $( "#geomap-aoi-" + geomap.id );
1217
+
1218
+ $( this ).toggleClass( "active" );
1219
+
1220
+ if ( !active ) {
1221
+ $aoiElm.find( "legend" ).trigger( "setfocus.wb" );
1222
+ }
1223
+
1224
+ drawInteraction.setActive( !active );
1225
+ selectInteraction.setActive( active );
1226
+
1227
+ } );
1228
+
1229
+ // clear drawn features
1230
+ $document.on( "click", "#geomap-aoi-btn-clear-" + geomap.id, function( event ) {
1231
+
1232
+ event.preventDefault();
1233
+
1234
+ $( "#geomap-aoi-extent-" + geomap.id ).val( "" );
1235
+ $( "#geomap-aoi-extent-lonlat-" + geomap.id ).val( "" );
1236
+ $( "#geomap-aoi-minx-" + geomap.id ).val( "" ).parent().removeClass( "has-error" );
1237
+ $( "#geomap-aoi-miny-" + geomap.id ).val( "" ).parent().removeClass( "has-error" );
1238
+ $( "#geomap-aoi-maxx-" + geomap.id ).val( "" ).parent().removeClass( "has-error" );
1239
+ $( "#geomap-aoi-maxy-" + geomap.id ).val( "" ).parent().removeClass( "has-error" );
1240
+
1241
+ getLayerById( geomap.map, "locLayer" ).getSource().clear( true );
1242
+
1243
+ } );
1244
+
1245
+ // draw feature from input coordinates
1246
+ $document.on( "click", "#geomap-aoi-btn-draw-" + geomap.id, function( event ) {
1247
+
1248
+ event.preventDefault();
1249
+
1250
+ $( "#geomap-aoi-extent-" + geomap.id ).val( "" );
1251
+ $( "#geomap-aoi-extent-lonlat-" + geomap.id ).val( "" );
1252
+ $( "#geomap-aoi-minx-" + geomap.id ).parent().removeClass( "has-error" );
1253
+ $( "#geomap-aoi-maxx-" + geomap.id ).parent().removeClass( "has-error" );
1254
+ $( "#geomap-aoi-maxy-" + geomap.id ).parent().removeClass( "has-error" );
1255
+ $( "#geomap-aoi-miny-" + geomap.id ).parent().removeClass( "has-error" );
1256
+
1257
+ getLayerById( geomap.map, "locLayer" ).getSource().clear( true );
1258
+
1259
+ var left = parseFloat( $( "#geomap-aoi-minx-" + geomap.id ).val() ),
1260
+ bottom = parseFloat( $( "#geomap-aoi-miny-" + geomap.id ).val() ),
1261
+ right = parseFloat( $( "#geomap-aoi-maxx-" + geomap.id ).val() ),
1262
+ top = parseFloat( $( "#geomap-aoi-maxy-" + geomap.id ).val() ),
1263
+ isValid = true,
1264
+ geomProj,
1265
+ extent;
1266
+
1267
+ if ( !left || left < -180 || left > 180 ) {
1268
+ $( "#geomap-aoi-minx-" + geomap.id ).parent().addClass( "has-error" );
1269
+ isValid = false;
1270
+ }
1271
+
1272
+ if ( !right || right < -180 || right > 180 ) {
1273
+ $( "#geomap-aoi-maxx-" + geomap.id ).parent().addClass( "has-error" );
1274
+ isValid = false;
1275
+ }
1276
+
1277
+ if ( !top || top < -90 || top > 90 ) {
1278
+ $( "#geomap-aoi-maxy-" + geomap.id ).parent().addClass( "has-error" );
1279
+ isValid = false;
1280
+ }
1281
+
1282
+ if ( !bottom || bottom < -90 || bottom > 90 ) {
1283
+ $( "#geomap-aoi-miny-" + geomap.id ).parent().addClass( "has-error" );
1284
+ isValid = false;
1285
+ }
1286
+
1287
+ if ( isValid === false ) {
1288
+ return false;
1289
+ }
1290
+
1291
+ extent = [ left, bottom, right, top ];
1292
+
1293
+ geomProj = drawAOI( geomap, extent );
1294
+
1295
+ // zoom to extent of feature
1296
+ geomap.map.getView().fit( geomProj.getGeometry().getExtent(), geomap.map.getSize() );
1297
+
1298
+ $( "#geomap-aoi-extent-" + geomap.id ).val( geomProj.getGeometry().getExtent() ).trigger( "change" );
1299
+ $( "#geomap-aoi-extent-lonlat-" + geomap.id ).val( left + ", " + bottom + ", " + right + ", " + top ).trigger( "change" );
1300
+
1301
+ } );
1302
+
1303
+ // if a default AOI is provided add it to the map and zoom to it
1304
+ if ( geomap.aoiExtent ) {
1305
+
1306
+ extent = geomap.aoiExtent.split( "," );
1307
+ left = extent[ 0 ].trim();
1308
+ bottom = extent[ 1 ].trim();
1309
+ right = extent[ 2 ].trim();
1310
+ top = extent[ 3 ].trim();
1311
+ geomProj = drawAOI( geomap, extent );
1312
+
1313
+ // zoom to extent of feature
1314
+ geomap.map.getView().fit( geomProj.getGeometry().getExtent(), geomap.map.getSize() );
1315
+
1316
+ $( "#geomap-aoi-minx-" + geomap.id ).val( left );
1317
+ $( "#geomap-aoi-maxx-" + geomap.id ).val( right );
1318
+ $( "#geomap-aoi-maxy-" + geomap.id ).val( top );
1319
+ $( "#geomap-aoi-miny-" + geomap.id ).val( bottom );
1320
+ $( "#geomap-aoi-extent-" + geomap.id ).val( geomProj.getBounds().toBBOX() );
1321
+ $( "#geomap-aoi-extent-lonlat-" + geomap.id ).val( left + ", " + bottom + ", " + right + ", " + top );
1322
+
1323
+ }
1324
+ },
1325
+
1326
+ //
1327
+ // Param:
1328
+ // - geomap = geomap Object
1329
+ // - extext = array with 4 point ( West, South, East, North)
1330
+ // - dontAddFeat = boolean (default:false) if true, no delimiter box would be added to the map
1331
+ //
1332
+ drawAOI = function( geomap, extent, dontAddFeat ) {
1333
+
1334
+ var coords = [],
1335
+ dens, len, feat,
1336
+ projLatLon = new ol.proj.Projection( { code: "EPSG:4326" } ),
1337
+ projMap = geomap.map.getView().getProjection();
1338
+
1339
+ dens = densifyBBox( parseFloat( extent[ 0 ] ), parseFloat( extent[ 1 ] ), parseFloat( extent[ 2 ] ), parseFloat( extent[ 3 ] ) );
1340
+
1341
+ for ( len = dens.length - 1; len !== -1; len -= 1 ) {
1342
+ coords.push( [ dens[ len ].getCoordinates()[ 0 ], dens[ len ].getCoordinates()[ 1 ] ] );
1343
+ }
1344
+
1345
+ feat = new ol.Feature( {
1346
+ geometry: new ol.geom.Polygon( [ coords ] ).transform( projLatLon, projMap )
1347
+ } );
1348
+
1349
+ if ( !dontAddFeat ) {
1350
+ getLayerById( geomap.map, "locLayer" ).getSource().addFeature( feat );
1351
+ }
1352
+
1353
+ return feat;
1354
+
1355
+ },
1356
+
1357
+ /**
1358
+ * Help Control - displays navigation help popup
1359
+ */
1360
+ HelpControl = function( geomap ) {
1361
+
1362
+ var button = document.createElement( "button" ),
1363
+ element = document.createElement( "div" );
1364
+
1365
+ button.innerHTML = "?";
1366
+ button.title = i18nText.accessTitle;
1367
+ button.setAttribute( "type", "button" );
1368
+
1369
+ button.addEventListener( "click", function() {
1370
+
1371
+ var dialog = document.createElement( "div" ),
1372
+ header = document.createElement( "header" ),
1373
+ h3 = document.createElement( "h3" ),
1374
+ closeButton = document.createElement( "a" ),
1375
+ panel = document.createElement( "div" ),
1376
+ role = document.createAttribute( "role" ),
1377
+ title = document.createAttribute( "title" ),
1378
+ href = document.createAttribute( "href" );
1379
+
1380
+ dialog.className = "panel panel-default geomap-help-dialog ol-control ";
1381
+ header.className = "panel-heading";
1382
+
1383
+ h3.innerHTML = i18nText.accessTitle;
1384
+ h3.className = "panel-title";
1385
+
1386
+ header.appendChild( h3 );
1387
+
1388
+ title.value = i18nText.dismiss;
1389
+ closeButton.setAttributeNode( title );
1390
+ href.value = "#";
1391
+ closeButton.setAttributeNode( href );
1392
+ role.value = "button";
1393
+ closeButton.setAttributeNode( role );
1394
+ closeButton.innerHTML = "&#xd7;<span class='wb-inv'>" + i18nText.dismiss + "</span>";
1395
+ closeButton.className = "btn btn-link";
1396
+
1397
+ dialog.appendChild( closeButton );
1398
+
1399
+ panel.innerHTML = "<p>" + i18nText.access + "</p>";
1400
+ panel.className = "panel-body";
1401
+
1402
+ dialog.appendChild( header );
1403
+ dialog.appendChild( panel );
1404
+
1405
+ var myControl = new ol.control.Control( { element: dialog } );
1406
+
1407
+ // Handle the close button event
1408
+ closeButton.addEventListener( "click", function( event ) {
1409
+
1410
+ event.preventDefault();
1411
+
1412
+ $( event.target ).closest( ".geomap-help-dialog" ).fadeOut( function() {
1413
+ geomap.map.removeControl( myControl );
1414
+ } );
1415
+
1416
+ } );
1417
+
1418
+ geomap.map.addControl( myControl );
1419
+
1420
+ }, false );
1421
+
1422
+ element.className = "geomap-help-btn ol-unselectable ol-control";
1423
+ element.appendChild( button );
1424
+
1425
+ ol.control.Control.call( this, {
1426
+ element: element
1427
+ } );
1428
+
1429
+ geomap.map.addControl( this );
1430
+
1431
+ },
1432
+
1433
+ /*
1434
+ * Geocoder Widget - search for place names (e.g. cities/towns, addresses,
1435
+ * streets, postal codes)
1436
+ */
1437
+ GeocodeControl = function( geomap ) {
1438
+
1439
+ var element = document.createElement( "div" ),
1440
+ setFocusEvent = "setfocus.wb",
1441
+ url = i18nText.geoLocationURL,
1442
+ mapObj = {
1443
+ "quebec": "<abbr title='Quebec'>QC</abbr>",
1444
+ "québec": "<abbr title='Québec'>QC</abbr>",
1445
+ "british columbia": "<abbr title='British Columbia'>BC</abbr>",
1446
+ "colombie-britannique": "<abbr title='Colombie-Britannique'>BC</abbr>",
1447
+ "alberta": "<abbr title='Alberta'>AB</abbr>",
1448
+ "saskatchewan": "<abbr title='Saskatchewan'>SK</abbr>",
1449
+ "manitoba": "<abbr title='Manitoba'>MB</abbr>",
1450
+ "ontario": "<abbr title='Ontario'>ON</abbr>",
1451
+ "newfoundland and labrador": "<abbr title='Newfoundland and Labrador'>NL</abbr>",
1452
+ "terre-neuve-et-labrador": "<abbr title='Terre-Neuve-et-Labrador'>NL</abbr>",
1453
+ "prince edward island": "<abbr title='Prince Edward Island'>PE</abbr>",
1454
+ "île-du-prince-édouard": "<abbr title='Île-du-prince-Édouard'>PE</abbr>",
1455
+ "nova scotia": "<abbr title='Nova Scotia'>NS</abbr>",
1456
+ "nouvelle-écosse": "<abbr title='Nouvelle-Écosse'>NS</abbr>",
1457
+ "new brunswick": "<abbr title='New Brunswick'>NB</abbr>",
1458
+ "nouveau-brunswick": "<abbr title='Nouveau-Brunswick'>NB</abbr>",
1459
+ "yukon": "<abbr title='Yukon'>YT</abbr>",
1460
+ "northwest territories": "<abbr title='Northwest Territories'>NT</abbr>",
1461
+ "territoires du nord-ouest": "<abbr title='Territoires du Nord-Ouest'>NT</abbr>",
1462
+ "nunavut": "<abbr title='Nunavut'>NU</abbr>"
1463
+ },
1464
+ iconObj = {
1465
+ "ca.gc.nrcan.geoloc.data.model.Street": "<span class='glyphicon glyphicon-road' aria-hidden='true'></span>",
1466
+ "ca.gc.nrcan.geoloc.data.model.Intersection": "<span class='glyphicon glyphicon-road' aria-hidden='true'></span>",
1467
+ "ca.gc.nrcan.geoloc.data.model.Geoname": "<span class='glyphicon glyphicon-map-marker' aria-hidden='true'></span>",
1468
+ "ca.gc.nrcan.geoloc.data.model.PostalCode": "<span class='glyphicon glyphicon-envelope' aria-hidden='true'></span>",
1469
+ "ca.gc.nrcan.geoloc.data.model.NTS": "<span class='glyphicon glyphicon-globe' aria-hidden='true'></span>"
1470
+ },
1471
+ width, x;
1472
+
1473
+ element.innerHTML =
1474
+ "<label for='wb-geomap-geocode-search-" + geomap.id + "' class='wb-inv'>" + i18nText.geoCoderLabel + "</label>" +
1475
+ "<input type='text' class='form-control' id='wb-geomap-geocode-search-" + geomap.id + "' placeholder='" + i18nText.geoCoderPlaceholder + "' ></input>" +
1476
+ "<div class='wb-geomap-geoloc-al-cnt'><ul role='listbox' id='wb-geomap-geoloc-al-" + geomap.id + "' class='wb-geomap-geoloc-al hide' aria-hidden='true' aria-live='polite'></ul></div>";
1477
+
1478
+ element.className = "geomap-geoloc ol-unselectable ol-control";
1479
+
1480
+ ol.control.Control.call( this, {
1481
+ element: element
1482
+ } );
1483
+
1484
+ geomap.map.addControl( this );
1485
+
1486
+ // Adds WAI-ARIA
1487
+ $( "#wb-geomap-geocode-search-" + geomap.id ).attr( "autocomplete", "off" );
1488
+ $( "#wb-geomap-geocode-search-" + geomap.id ).attr( "role", "textbox" );
1489
+ $( "#wb-geomap-geocode-search-" + geomap.id ).attr( "aria-haspopup", "true" );
1490
+ $( "#wb-geomap-geocode-search-" + geomap.id ).attr( "aria-autocomplete", "list" );
1491
+ $( "#wb-geomap-geocode-search-" + geomap.id ).attr( "aria-owns", "wb-geomap-geoloc-al-" + geomap.id );
1492
+ $( "#wb-geomap-geocode-search-" + geomap.id ).attr( "aria-activedescendent", "" );
1493
+
1494
+ width = parseFloat( $( ".geomap-geoloc" ).parent().width() );
1495
+ x = width > 768 ? .6 : .8;
1496
+
1497
+ if ( !mobile ) {
1498
+ $( ".geomap-geoloc" ).css( { "width": width * x } );
1499
+ $( ".wb-geomap-geoloc-al-cnt" ).css( { "width": width * x } );
1500
+ } else {
1501
+ $( ".geomap-geoloc" ).css( { "width": width - 10 + "px" } );
1502
+ $( ".wb-geomap-geoloc-al-cnt" ).css( { "width": width - 10 + "px" } );
1503
+ }
1504
+
1505
+ function panZoomToFeature( bbox, ll ) {
1506
+
1507
+ var bnds,
1508
+ coords = [],
1509
+ dens,
1510
+ feat,
1511
+ len,
1512
+ projLatLon = new ol.proj.Projection( { code: "EPSG:4326" } ),
1513
+ projMap = geomap.map.getView().getProjection(),
1514
+ zoom;
1515
+
1516
+ getLayerById( geomap.map, "locLayer" ).getSource().clear( true );
1517
+
1518
+ if ( bbox && typeof bbox !== "undefined" ) {
1519
+
1520
+ bnds = bbox.split( "," );
1521
+ dens = densifyBBox( parseFloat( bnds[ 0 ] ), parseFloat( bnds[ 1 ] ), parseFloat( bnds[ 2 ] ), parseFloat( bnds[ 3 ] ) );
1522
+
1523
+ for ( len = dens.length - 1; len !== -1; len -= 1 ) {
1524
+ coords.push( [ dens[ len ].getCoordinates()[ 0 ], dens[ len ].getCoordinates()[ 1 ] ] );
1525
+ }
1526
+
1527
+ feat = new ol.Feature( {
1528
+ geometry: new ol.geom.Polygon( [ coords ] ).transform( projLatLon, projMap )
1529
+ } );
1530
+
1531
+ getLayerById( geomap.map, "locLayer" ).getSource().addFeature( feat );
1532
+
1533
+ // zoom to extent of feature
1534
+ geomap.map.getView().fit( feat.getGeometry().getExtent(), geomap.map.getSize() );
1535
+
1536
+ } else if ( ll && typeof ll !== "undefined" ) {
1537
+
1538
+ zoom = geomap.map.getView().getZoom() === 0 ? 12 : geomap.map.getView().getZoom();
1539
+ feat = new ol.Feature( {
1540
+ geometry: new ol.geom.Point( ll.split( "," ) ).transform( projLatLon, projMap )
1541
+ } );
1542
+ getLayerById( geomap.map, "locLayer" ).getSource().addFeature( feat );
1543
+
1544
+ // zoom to feature
1545
+ geomap.map.getView().setZoom( zoom );
1546
+ geomap.map.getView().setCenter( feat.getGeometry().getCoordinates() );
1547
+
1548
+ }
1549
+
1550
+ }
1551
+
1552
+ $document.on( "keydown", "#wb-geomap-geocode-search-" + geomap.id, function( event ) {
1553
+
1554
+ // TODO: find another way to do this, maybe setting negative tabindex
1555
+ getMapInteraction( geomap.map, ol.interaction.KeyboardPan ).setActive( false );
1556
+
1557
+ var which = event.which;
1558
+
1559
+ if ( !( event.ctrlKey || event.metaKey ) ) {
1560
+ return keyboardHandlerInput( which, event );
1561
+ }
1562
+
1563
+ } );
1564
+
1565
+ /**
1566
+ * Hides all the options
1567
+ * @method closeOptions
1568
+ * @param {DOM element} input The polyfilled input field
1569
+ */
1570
+ function closeOptions( input ) {
1571
+ var autolist = input.nextSibling.firstChild;
1572
+
1573
+ // TODO: find another way to do this, maybe setting negative tabindex
1574
+ getMapInteraction( geomap.map, ol.interaction.KeyboardPan ).setActive( true );
1575
+
1576
+ autolist.className += " hide";
1577
+ autolist.innerHTML = "";
1578
+ autolist.setAttribute( "aria-hidden", "true" );
1579
+ input.setAttribute( "aria-expanded", "false" );
1580
+ input.setAttribute( "aria-activedescendent", "" );
1581
+ }
1582
+
1583
+ /**
1584
+ * Returns the available options based upon the input in the input field.
1585
+ * @method showOptions
1586
+ * @param {DOM element} input The input field
1587
+ */
1588
+ function showOptions( input, value ) {
1589
+
1590
+ var options = "",
1591
+ $input = $( "#wb-geomap-geocode-search-" + geomap.id ),
1592
+ $autolist = $( "#wb-geomap-geoloc-al-" + geomap.id ),
1593
+ abbrProv = function( str, mapObj ) {
1594
+ var re = new RegExp( Object.keys( mapObj ).join( "|" ), "gi" );
1595
+ return str.replace( re, function( matched ) {
1596
+ return mapObj[ matched.toLowerCase() ];
1597
+ } );
1598
+ };
1599
+
1600
+ if ( !value || value.length < 3 ) {
1601
+ $autolist.empty();
1602
+ }
1603
+
1604
+ $.ajax( {
1605
+ type: "GET",
1606
+ url: url,
1607
+ data: { q: value + "*" },
1608
+ success: function( data ) {
1609
+
1610
+ if ( data.length > 0 ) {
1611
+
1612
+ var len = data.length,
1613
+ icon = "",
1614
+ i, item, label, title, bnd, ll;
1615
+
1616
+ for ( i = 0; i !== len; i += 1 ) {
1617
+
1618
+ item = data[ i ];
1619
+ title = item.title
1620
+ .replace( /&/g, "&amp;" )
1621
+ .replace( /"/g, "&quot;" )
1622
+ .replace( /'/g, "&#39;" )
1623
+ .replace( /</g, "&lt;" )
1624
+ .replace( />/g, "&gt;" );
1625
+ bnd = item.bbox ? item.bbox[ 0 ] + ", " + item.bbox[ 1 ] + ", " + item.bbox[ 2 ] + ", " + item.bbox[ 3 ] : "";
1626
+ ll = item.geometry && item.geometry.type === "Point" ? item.geometry.coordinates[ 0 ] + ", " + item.geometry.coordinates[ 1 ] : "";
1627
+ icon = iconObj[ item.type ] ? iconObj[ item.type ] : "<span class='glyphicon glyphicon-map-marker' aria-hidden='true'></span>";
1628
+ title = abbrProv( title, mapObj );
1629
+ label = title.replace( /<(?:.|\n)*?>/gm, "" );
1630
+
1631
+ options += "<li id='al-opt-" + geomap.id + "-" + i +
1632
+ "' class='al-opt' data-lat-lon='" + ll +
1633
+ "' data-bbox='" + bnd +
1634
+ "' data-type='" + item.type + "'>" +
1635
+ "<a href='javascript:;' tabindex='-1'>" + icon +
1636
+ "<span class='al-val'>" + title + "</span>" +
1637
+ "<span class='al-lbl wb-inv' aria-hidden='true'>" + label + "</span>" +
1638
+ "</a></li>";
1639
+
1640
+ }
1641
+
1642
+ $autolist.empty().append( options );
1643
+ $autolist.removeClass( "hide" ).attr( "aria-hidden", "false" );
1644
+ $input.attr( "aria-expanded", "true" );
1645
+
1646
+ // bind events to the options
1647
+ // TODO: do this in the wb-update event
1648
+ $( ".al-opt a" ).on( "keydown click vclick", function( event ) {
1649
+ var link = event.target,
1650
+ eventType = event.type,
1651
+ which = event.which;
1652
+
1653
+ switch ( eventType ) {
1654
+ case "keydown":
1655
+ if ( !( event.ctrlKey || event.metaKey ) ) {
1656
+ return keyboardHandlerAutolist( which, link );
1657
+ }
1658
+ break;
1659
+ case "click":
1660
+ case "vclick":
1661
+ case "touchstart":
1662
+
1663
+ // Ignore middle/right mouse buttons
1664
+ if ( !which || which === 1 ) {
1665
+ return clickHandlerAutolist( link );
1666
+ }
1667
+ break;
1668
+ }
1669
+
1670
+ } );
1671
+
1672
+ } else {
1673
+ $autolist.empty();
1674
+ $autolist.addClass( "hide" ).attr( "aria-hidden", "true" );
1675
+ $autolist.attr( "aria-expanded", "false" );
1676
+ }
1677
+
1678
+ },
1679
+ dataType: "json",
1680
+ cache: false
1681
+ } );
1682
+
1683
+ }
1684
+
1685
+ /**
1686
+ * Keyboard event handler for the polyfilled input field
1687
+ * @param {integer} which Value for event.which
1688
+ * @param {jQuery Event} event The event that triggered this method call
1689
+ */
1690
+ function keyboardHandlerInput( which, event ) {
1691
+
1692
+ var input = event.target,
1693
+ autolist = input.nextSibling.firstChild,
1694
+ autolistHidden = ( autolist.className.indexOf( "hide" ) !== -1 ),
1695
+ options, dest, value, len;
1696
+
1697
+ // Unmodified keystrokes only
1698
+ if ( !( event.ctrlKey || event.altKey || event.metaKey ) ) {
1699
+
1700
+ // Spacebar, a - z keys, 0 - 9 keys punctuation, and symbols
1701
+ if ( which === 32 || ( which > 47 && which < 91 ) ||
1702
+ ( which > 95 && which < 112 ) || ( which > 159 && which < 177 ) ||
1703
+ ( which > 187 && which < 223 ) ) {
1704
+ if ( !event.altKey ) {
1705
+ showOptions( input, input.value + String.fromCharCode( which ) );
1706
+ }
1707
+
1708
+ // Backspace
1709
+ } else if ( which === 8 && !event.altKey ) {
1710
+ value = input.value;
1711
+ len = value.length;
1712
+
1713
+ if ( len !== 0 ) {
1714
+ showOptions( input, value.substring( 0, len - 1 ) );
1715
+ }
1716
+
1717
+ // Up / down arrow
1718
+ } else if ( ( which === 38 || which === 40 ) && input.getAttribute( "aria-activedescendent" ) === "" ) {
1719
+
1720
+ if ( autolistHidden ) {
1721
+ showOptions( input );
1722
+ }
1723
+
1724
+ options = autolist.getElementsByTagName( "a" );
1725
+
1726
+ if ( options.length === 0 ) {
1727
+ return false;
1728
+ }
1729
+
1730
+ dest = options[ ( which === 38 ? options.length - 1 : 0 ) ];
1731
+
1732
+ input.setAttribute( "aria-activedescendent", dest.parentNode.getAttribute( "id" ) );
1733
+
1734
+ // Assign focus to dest
1735
+ $( dest ).trigger( setFocusEvent );
1736
+
1737
+ return false;
1738
+
1739
+ } else if ( !autolistHidden ) {
1740
+
1741
+ // Tab or Escape key
1742
+ if ( ( which === 9 || which === 27 ) || ( which === 27 && !event.altKey ) ) {
1743
+ closeOptions( input );
1744
+ }
1745
+ }
1746
+ }
1747
+ }
1748
+
1749
+ /**
1750
+ * Click / Touch event handler for the autolist of the polyfilled input field
1751
+ * @param {integer} eventTarget Value for event.target
1752
+ */
1753
+ function clickHandlerAutolist( eventTarget ) {
1754
+
1755
+ var nodeName = eventTarget.nodeName.toLowerCase(),
1756
+ link = nodeName === "a" ? eventTarget : eventTarget.parentNode,
1757
+ autolist = link.parentNode.parentNode,
1758
+ input = autolist.parentNode.previousSibling,
1759
+ $input = $( input ),
1760
+ span = link.getElementsByTagName( "span" ),
1761
+ value = span[ 2 ].innerHTML;
1762
+
1763
+ input.value = value;
1764
+
1765
+ panZoomToFeature( link.parentNode.getAttribute( "data-bbox" ), link.parentNode.getAttribute( "data-lat-lon" ) );
1766
+
1767
+ $input.trigger( setFocusEvent );
1768
+ closeOptions( input );
1769
+
1770
+ return false;
1771
+ }
1772
+
1773
+ /**
1774
+ * Keyboard event handler for the autolist of the polyfilled input field
1775
+ * @param {integer} which Value for event.which
1776
+ * @param {DOM element} link Link element that is the target of the event
1777
+ */
1778
+ function keyboardHandlerAutolist( which, link ) {
1779
+ var autolist = link.parentNode.parentNode,
1780
+ input = autolist.parentNode.previousSibling,
1781
+ $input = $( input ),
1782
+ span, dest, value, len, children;
1783
+
1784
+ // Unmodified keystrokes only
1785
+ if ( !( event.ctrlKey || event.altKey || event.metaKey ) ) {
1786
+
1787
+ // Spacebar, a - z keys, 0 - 9 keys punctuation, and symbols
1788
+ if ( which === 32 || ( which > 47 && which < 91 ) ||
1789
+ ( which > 95 && which < 112 ) || ( which > 159 && which < 177 ) ||
1790
+ ( which > 187 && which < 223 ) ) {
1791
+
1792
+ input.value += String.fromCharCode( which );
1793
+ $input.trigger( setFocusEvent );
1794
+ showOptions( input, input.value );
1795
+
1796
+ return false;
1797
+
1798
+ // Backspace
1799
+ } else if ( which === 8 ) {
1800
+ value = input.value;
1801
+ len = value.length;
1802
+
1803
+ if ( len !== 0 ) {
1804
+ input.value = value.substring( 0, len - 1 );
1805
+ showOptions( input, input.value );
1806
+ }
1807
+
1808
+ $input.trigger( setFocusEvent );
1809
+
1810
+ return false;
1811
+
1812
+ // Enter key
1813
+ } else if ( which === 13 ) {
1814
+ span = link.getElementsByTagName( "span" );
1815
+ value = span[ 2 ].innerHTML;
1816
+
1817
+ input.value = value;
1818
+
1819
+ panZoomToFeature( link.parentNode.getAttribute( "data-bbox" ), link.parentNode.getAttribute( "data-lat-lon" ) );
1820
+
1821
+ $input.trigger( setFocusEvent );
1822
+ closeOptions( input );
1823
+
1824
+ return false;
1825
+
1826
+ // Tab or Escape key
1827
+ } else if ( which === 9 || which === 27 ) {
1828
+ $input.trigger( setFocusEvent );
1829
+ closeOptions( input );
1830
+
1831
+ return false;
1832
+
1833
+ // Up or down arrow
1834
+ } else if ( which === 38 || which === 40 ) {
1835
+
1836
+ // Up arrow
1837
+ if ( which === 38 ) {
1838
+ dest = link.parentNode.previousSibling;
1839
+ if ( !dest ) {
1840
+ children = autolist.getElementsByTagName( "li" );
1841
+ dest = children[ children.length - 1 ];
1842
+ }
1843
+
1844
+ // Down arrow
1845
+ } else {
1846
+ dest = link.parentNode.nextSibling;
1847
+ if ( !dest ) {
1848
+ dest = autolist.getElementsByTagName( "li" )[ 0 ];
1849
+ }
1850
+ }
1851
+ dest = dest.getElementsByTagName( "a" )[ 0 ];
1852
+
1853
+ input.setAttribute( "aria-activedescendent", dest.parentNode.getAttribute( "id" ) );
1854
+ $( dest ).trigger( setFocusEvent );
1855
+
1856
+ return false;
1857
+ }
1858
+ }
1859
+
1860
+ }
1861
+
1862
+ },
1863
+
1864
+ /*
1865
+ * Geolocation control - locate client and display icon on map
1866
+ */
1867
+ GeolocationControl = function( options ) {
1868
+
1869
+ var opts = options || {},
1870
+ _this = this,
1871
+ accuracyFeature, positionFeature,
1872
+ button, coordinates, element;
1873
+
1874
+ $( "body" ).append(
1875
+ "<section id='overlay-location-error' class='wb-overlay modal-content overlay-def wb-bar-t bg-danger'>" +
1876
+ "<header><h2 class='modal-title'>Geolocation error.</h2></header>" +
1877
+ "</section>"
1878
+ );
1879
+
1880
+ $( "#overlay-location-error" ).trigger( "wb-init.wb-overlay" );
1881
+
1882
+ button = document.createElement( "button" );
1883
+ button.setAttribute( "type", "button" );
1884
+ button.setAttribute( "title", i18nText.geolocBtn );
1885
+ button.innerHTML = "<span class='glyphicon glyphicon-screenshot'></span>";
1886
+
1887
+ element = document.createElement( "div" );
1888
+ element.className = "ol-geolocate ol-unselectable ol-control";
1889
+
1890
+ element.appendChild( button );
1891
+
1892
+ _this.geolocation = new ol.Geolocation( opts );
1893
+
1894
+ function createFeatures() {
1895
+
1896
+ positionFeature = new ol.Feature();
1897
+ accuracyFeature = new ol.Feature();
1898
+
1899
+ positionFeature.setStyle( getPointStyle( {
1900
+ radius: 6,
1901
+ fill: new ol.style.Fill( {
1902
+ color: "#3399CC"
1903
+ } ),
1904
+ stroke: new ol.style.Stroke( {
1905
+ color: "#fff",
1906
+ width: 2
1907
+ } ) } )
1908
+ );
1909
+
1910
+ return [ accuracyFeature, positionFeature ];
1911
+ }
1912
+
1913
+ ol.control.Control.call( this, {
1914
+ element: element,
1915
+ target: opts.target
1916
+ } );
1917
+
1918
+ _this.geolocation.on( "change:accuracyGeometry", function() {
1919
+ accuracyFeature.setGeometry( _this.geolocation.getAccuracyGeometry() );
1920
+ } );
1921
+
1922
+ _this.geolocation.on( "change:position", function() {
1923
+ coordinates = _this.geolocation.getPosition();
1924
+ positionFeature.setGeometry( coordinates ?
1925
+ new ol.geom.Point( coordinates ) : null );
1926
+
1927
+ // zoom to feature
1928
+ var extent = _this.featuresOverlay.getSource().getExtent();
1929
+ _this.getMap().getView().fit( extent, _this.getMap().getSize() );
1930
+
1931
+ $( button ).html( "<span style='color:#3399CC;' class='glyphicon glyphicon-screenshot'></span>" );
1932
+
1933
+ } );
1934
+
1935
+ /* Handle errors.
1936
+ * Codes:
1937
+ PERMISSION_DENIED: 1
1938
+ POSITION_UNAVAILABLE: 2
1939
+ TIMEOUT: 3
1940
+ */
1941
+ _this.geolocation.on( "error", function( error ) {
1942
+ if ( error.code === 2 ) {
1943
+ $( "#overlay-location-error h2.modal-title" ).text( i18nText.geolocUncapable );
1944
+ $( "#overlay-location-error" ).trigger( "open.wb-overlay" );
1945
+ } else {
1946
+ $( "#overlay-location-error h2.modal-title" ).text( i18nText.geolocFail );
1947
+ $( "#overlay-location-error" ).trigger( "open.wb-overlay" );
1948
+ }
1949
+ } );
1950
+
1951
+ button.addEventListener( "click", function() {
1952
+
1953
+ $( this ).html( "<span style='font-size:.9em;' class='glyphicon glyphicon-refresh glyphicon-spin'></span>" );
1954
+
1955
+ if ( typeof _this.featuresOverlay === "undefined" ) {
1956
+
1957
+ _this.featuresOverlay = new ol.layer.Vector( {
1958
+ map: _this.getMap(),
1959
+ source: new ol.source.Vector( { } )
1960
+ } );
1961
+
1962
+ _this.featuresOverlay.getSource().addFeatures( createFeatures() );
1963
+ _this.geolocation.setTracking( true );
1964
+
1965
+ } else if ( _this.featuresOverlay.getSource().getFeatures().length === 0 ) {
1966
+
1967
+ _this.featuresOverlay.getSource().addFeatures( createFeatures() );
1968
+ _this.geolocation.setTracking( true );
1969
+
1970
+ } else {
1971
+
1972
+ _this.geolocation.setTracking( false );
1973
+ _this.featuresOverlay.getSource().clear();
1974
+
1975
+ $( this ).html( "<span class='glyphicon glyphicon-screenshot'></span>" );
1976
+
1977
+ }
1978
+
1979
+ }, false );
1980
+
1981
+ },
1982
+
1983
+ /*
1984
+ * Construct a polygon and densify the latitudes to show the curvature
1985
+ */
1986
+ densifyBBox = function( minX, minY, maxX, maxY ) {
1987
+
1988
+ var left = parseFloat( minX ),
1989
+ bottom = parseFloat( minY ),
1990
+ right = parseFloat( maxX ),
1991
+ top = parseFloat( maxY ),
1992
+ newbounds = [ ],
1993
+ j;
1994
+
1995
+ if ( left.length === 0 || bottom.length === 0 ||
1996
+ right.length === 0 || top.length === 0 ) {
1997
+
1998
+ return false;
1999
+ }
2000
+
2001
+ // If default BBOX, make it fit in view showing Canada and not the world.
2002
+ if ( left === -180.0 ) {
2003
+ left += 0.1;
2004
+ }
2005
+ if ( right === 180.0 ) {
2006
+ right = -5.0;
2007
+ }
2008
+ if ( top === 90.0 ) {
2009
+ top -= 3;
2010
+ }
2011
+ if ( bottom === -90.0 ) {
2012
+ bottom = 35.0;
2013
+ }
2014
+
2015
+ for ( j = left; j < right; j += 0.5 ) {
2016
+ newbounds.push( new ol.geom.Point( [ j, bottom ] ) );
2017
+ }
2018
+
2019
+ newbounds.push( new ol.geom.Point( [ right, bottom ] ) );
2020
+
2021
+ for ( j = right; j > left; j -= 0.5 ) {
2022
+ newbounds.push( new ol.geom.Point( [ j, top ] ) );
2023
+ }
2024
+
2025
+ newbounds.push( new ol.geom.Point( [ left, top ] ) );
2026
+ newbounds.push( new ol.geom.Point( [ left, bottom ] ) );
2027
+
2028
+ return newbounds;
2029
+ },
2030
+
2031
+ /*
2032
+ * Refresh WET plugins
2033
+ */
2034
+ refreshPlugins = function() {
2035
+ $( ".wb-tables" ).trigger( "wb-init.wb-tables" );
2036
+ },
2037
+
2038
+ getLayerById = function( map, id ) {
2039
+ var layer;
2040
+
2041
+ map.getLayers().forEach( function( lyr ) {
2042
+ if ( id === lyr.id ) {
2043
+ layer = lyr;
2044
+ return;
2045
+ }
2046
+ } );
2047
+
2048
+ return layer;
2049
+ },
2050
+
2051
+ // Retrieve the map, layer and feature using data attributes on an element
2052
+ getMapLayerFeature = function( elm ) {
2053
+
2054
+ var geomap = getMapById( elm.getAttribute( "data-map" ) ),
2055
+ layer;
2056
+
2057
+ if ( elm.getAttribute( "data-layer" ) ) {
2058
+ layer = getLayerById( geomap.map, elm.getAttribute( "data-layer" ) );
2059
+
2060
+ return [
2061
+ geomap.map,
2062
+ layer,
2063
+ elm.getAttribute( "data-feature" ) ? layer.getSource().getFeatureById( elm.getAttribute( "data-feature" ) ) : null
2064
+ ];
2065
+
2066
+ } else {
2067
+ return [ geomap.map, null, null ];
2068
+ }
2069
+ },
2070
+
2071
+ /**
2072
+ * Create a random Guid.
2073
+ *
2074
+ * @return {String} a random Guid value.
2075
+ */
2076
+ generateGuid = function() {
2077
+ return Math.random().toString( 36 ).slice( 2 );
2078
+ };
2079
+
2080
+ // Handle the Zoom to button events
2081
+ $document.on( "click", ".geomap-zoomto", function( event ) {
2082
+ var which = event.which,
2083
+ target = ( event.target.tagName === "A" ) ? event.target : $( event.target ).closest( "a" )[ 0 ],
2084
+ mapId, mapLayerFeature, geometry, extent, view;
2085
+
2086
+ // Ignore middle/right mouse buttons
2087
+ if ( !which || which === 1 ) {
2088
+ event.preventDefault();
2089
+ mapId = target.getAttribute( "data-map" );
2090
+ mapLayerFeature = getMapLayerFeature( target );
2091
+ geometry = mapLayerFeature[ 2 ].getGeometry();
2092
+ extent = geometry.getExtent();
2093
+ view = mapLayerFeature[ 0 ].getView();
2094
+
2095
+ //TODO: rework, using undocumented function
2096
+ if ( geometry.getType() === "Point" ) {
2097
+ view.fit( extent, mapLayerFeature[ 0 ].getSize() );
2098
+ view.setZoom( 10 );
2099
+ } else {
2100
+ view.fit( extent, mapLayerFeature[ 0 ].getSize() );
2101
+ }
2102
+
2103
+ $( "#" + mapId + " .wb-geomap-map" ).trigger( "setfocus.wb" );
2104
+ }
2105
+ } );
2106
+
2107
+ // Bind the init function to the geomap.wb event
2108
+ $document.on( "geomap.wb", selector, init );
2109
+
2110
+ // Update the map when the window is resized
2111
+ $document.on( wb.resizeEvents, function( event ) {
2112
+
2113
+ mapArray.forEach( function( geomap ) {
2114
+
2115
+ var $mapDiv = $( geomap.map.getTargetElement() ),
2116
+ $myDiv = $mapDiv.find( ".geomap-geoloc" ),
2117
+ width = $mapDiv.width();
2118
+
2119
+ $mapDiv.height( width * geomap.map.get( "aspectRatio" ) );
2120
+
2121
+ geomap.map.updateSize();
2122
+
2123
+ if ( $myDiv ) {
2124
+ if ( event.type === "mediumview" || event.type === "largeview" || event.type === "xlargeview" ) {
2125
+ $myDiv.css( { "width": "60%" } );
2126
+ } else {
2127
+ $myDiv.css( { "width": "80%" } );
2128
+ }
2129
+ }
2130
+
2131
+ } );
2132
+
2133
+ } );
2134
+
2135
+ // Handle clicking of checkboxes within the tables
2136
+ $document.on( "change", ".geomap-cbx", function( event ) {
2137
+
2138
+ var target = event.target,
2139
+ feature = getMapLayerFeature( target )[ 2 ],
2140
+ map = getMapLayerFeature( target )[ 0 ],
2141
+ selectInteraction = getMapInteraction( map, ol.interaction.Select ),
2142
+ checked = target.checked;
2143
+
2144
+ if ( checked ) {
2145
+ selectInteraction.getFeatures().push( feature );
2146
+ } else {
2147
+ selectInteraction.getFeatures().remove( feature );
2148
+ }
2149
+
2150
+ } );
2151
+
2152
+ /**
2153
+ * Add/remove map border based on mouse pointer location
2154
+ */
2155
+ $document.on( "focusin focusout mouseover mouseout", ".wb-geomap-map", function( event ) {
2156
+
2157
+ var target = event.currentTarget,
2158
+ type = event.type,
2159
+ isActive = target.className.indexOf( "active" ),
2160
+ geomap = getMapById( target.getAttribute( "data-map" ) ),
2161
+ mouseWheelZoom = getMapInteraction( geomap.map, ol.interaction.MouseWheelZoom );
2162
+
2163
+ // disable mouseWheelZoom so that page scrolling isn't interupted
2164
+ if ( geomap.settings.useMapControls ) {
2165
+ mouseWheelZoom.setActive( false );
2166
+ }
2167
+
2168
+ if ( type === "mouseover" || type === "focusin" ) {
2169
+ if ( isActive ) {
2170
+ $( target ).addClass( "active" );
2171
+ }
2172
+
2173
+ // enable mouseWheelZoom if using map controls and user has focused in on map
2174
+ if ( type === "focusin" && geomap.settings.useMapControls ) {
2175
+ mouseWheelZoom.setActive( true );
2176
+ }
2177
+ } else if ( isActive > 0 ) {
2178
+ $( target ).removeClass( "active" );
2179
+ }
2180
+
2181
+ } );
2182
+
2183
+ /*
2184
+ * Add basemap data
2185
+ */
2186
+ Geomap.prototype.addBasemap = function() {
2187
+
2188
+ var _this = this,
2189
+ basemap = _this.settings.basemap,
2190
+ hasBasemap = basemap && basemap.length !== 0,
2191
+ viewOptions = {},
2192
+ urls = [],
2193
+ mapOpts = {},
2194
+ olLayers = [],
2195
+ params, z,
2196
+ projection, resolutions, mapWidth, zoomOffset, offset, matrixIds;
2197
+
2198
+ if ( _this.settings.attribution ) {
2199
+ mapOpts.attributions = [ new ol.Attribution( {
2200
+ html: _this.settings.attribution.text
2201
+ } ) ];
2202
+ }
2203
+
2204
+ // Check to see if a base map has been configured. If not add the
2205
+ // default base map (the Canada Transportation Base Map (CBMT))
2206
+ if ( hasBasemap ) {
2207
+
2208
+ // map OL2 params to OL3 view properties
2209
+ viewOptions.extent = ( basemap.mapOptions && basemap.mapOptions.maxExtent ) ? basemap.mapOptions.maxExtent.split( "," ).map( Number ) : null;
2210
+ viewOptions.projection = ( basemap.mapOptions && basemap.mapOptions.projection ) ? basemap.mapOptions.projection : "EPSG:3857";
2211
+ viewOptions.center = ( _this.settings && _this.settings.center ) ? ol.proj.transform( _this.settings.center, "EPSG:4326", viewOptions.projection ) : ( basemap.mapOptions && basemap.mapOptions.center ) ? ol.proj.transform( basemap.mapOptions.center, "EPSG:4326", viewOptions.projection ) : ( basemap.mapOptions && basemap.mapOptions.maxExtent ) ? ol.extent.getCenter( viewOptions.extent ) : [ 0, 0 ];
2212
+ viewOptions.zoom = ( _this.settings && _this.settings.zoom ) ? _this.settings.zoom : ( basemap.mapOptions && basemap.mapOptions.zoomLevel ) ? basemap.mapOptions.zoomLevel : 2;
2213
+
2214
+ if ( basemap.type === "wms" ) {
2215
+
2216
+ params = removeKeys( basemap, [ "mapOptions", "url" ] );
2217
+ params.srs = viewOptions.projection;
2218
+ params.crs = viewOptions.projection;
2219
+
2220
+ olLayers.push(
2221
+ new ol.layer.Image( {
2222
+ extent: viewOptions.extent,
2223
+ source: new ol.source.ImageWMS( {
2224
+ url: basemap.url,
2225
+ params: params
2226
+ } )
2227
+ } )
2228
+ );
2229
+
2230
+ } else if ( basemap.type === "esri" ) {
2231
+
2232
+ // Backwards compatibility with OL2 configurations
2233
+ // TODO: this should only be tried if resource is not found
2234
+ mapOpts.url = basemap.url.replace( "/MapServer/export", "/MapServer" );
2235
+
2236
+ olLayers.push(
2237
+ new ol.layer.Tile( {
2238
+ extent: viewOptions.extent,
2239
+ source: new ol.source.TileArcGISRest( mapOpts )
2240
+ } )
2241
+ );
2242
+
2243
+ } else if ( basemap.type === "xyz" ) {
2244
+
2245
+ // Backwards compatibility with OL2 configurations
2246
+ // TODO: test with known configurations
2247
+ if ( $.isArray( basemap.url ) ) {
2248
+ $.each( basemap.url, function( index, url ) {
2249
+ urls.push( url.replace( /\${/g, "{" ) );
2250
+ } );
2251
+ mapOpts.urls = urls;
2252
+ } else {
2253
+ mapOpts.url = basemap.url.replace( /\${/g, "{" );
2254
+ }
2255
+
2256
+ olLayers.push(
2257
+ new ol.layer.Tile( {
2258
+ source: new ol.source.XYZ( mapOpts )
2259
+ } )
2260
+ );
2261
+
2262
+ } else if ( basemap.type === "osm" ) {
2263
+
2264
+ olLayers.push(
2265
+ new ol.layer.Tile( {
2266
+ source: new ol.source.OSM( { attributions: [ ol.source.OSM.ATTRIBUTION ] } )
2267
+ } )
2268
+ );
2269
+
2270
+ } else if ( basemap.type === "mapquest" ) {
2271
+ olLayers.push(
2272
+ new ol.layer.Tile( {
2273
+ source: new ol.source.MapQuest( { layer: "sat" } )
2274
+ } )
2275
+ );
2276
+ }
2277
+
2278
+ // No basemap configured so use default
2279
+ } else {
2280
+
2281
+ projection = ol.proj.get( "EPSG:3978" );
2282
+
2283
+ resolutions = [
2284
+ 38364.660062653464,
2285
+ 22489.62831258996,
2286
+ 13229.193125052918,
2287
+ 7937.5158750317505,
2288
+ 4630.2175937685215,
2289
+ 2645.8386250105837,
2290
+ 1587.5031750063501,
2291
+ 926.0435187537042,
2292
+ 529.1677250021168,
2293
+ 317.50063500127004,
2294
+ 185.20870375074085,
2295
+ 111.12522225044451,
2296
+ 66.1459656252646,
2297
+ 38.36466006265346,
2298
+ 22.48962831258996,
2299
+ 13.229193125052918,
2300
+ 7.9375158750317505,
2301
+ 4.6302175937685215
2302
+ ];
2303
+
2304
+ mapWidth = this.mapDiv.width();
2305
+ zoomOffset = 5;
2306
+
2307
+ // In function of map width size, set the proper resolution and zoom offset
2308
+ if ( mapWidth > 260 && mapWidth <= 500 ) {
2309
+ zoomOffset = 1;
2310
+ } else if ( mapWidth > 500 && mapWidth <= 725 ) {
2311
+ zoomOffset = 2;
2312
+ } else if ( mapWidth > 725 && mapWidth <= 1175 ) {
2313
+ zoomOffset = 3;
2314
+ } else if ( mapWidth > 1175 && mapWidth <= 2300 ) {
2315
+ zoomOffset = 4;
2316
+ }
2317
+
2318
+ for ( offset = zoomOffset - 1; offset !== -1; offset -= 1 ) {
2319
+ resolutions.shift();
2320
+ }
2321
+
2322
+ matrixIds = new Array( resolutions.length );
2323
+
2324
+ for ( z = 0; z < resolutions.length; ++z ) {
2325
+ matrixIds[ z ] = zoomOffset + z;
2326
+ }
2327
+
2328
+ viewOptions = {
2329
+ extent: [ -2750000.0, -900000.0, 3600000.0, 4630000.0 ],
2330
+ resolutions: resolutions,
2331
+ projection: projection
2332
+ };
2333
+
2334
+ olLayers.push( new ol.layer.Tile( {
2335
+ source: new ol.source.WMTS( {
2336
+ attributions: [ new ol.Attribution( {
2337
+ html: "<a href='" + i18nText.attribLink + "'>" + i18nText.attribTitle + "</a>"
2338
+ } ) ],
2339
+ url: i18nText.baseMapURL,
2340
+ layer: i18nText.baseMapTitle,
2341
+ matrixSet: i18nText.baseMapMatrixSet,
2342
+ projection: projection,
2343
+ tileGrid: new ol.tilegrid.WMTS( {
2344
+ extent: [ -2750000.0, -900000.0, 3600000.0, 4630000.0 ],
2345
+ origin: [ -3.46558E7, 3.931E7 ],
2346
+ resolutions: resolutions,
2347
+ matrixIds: matrixIds
2348
+ } ),
2349
+ style: "default"
2350
+ } )
2351
+ } ) );
2352
+
2353
+ }
2354
+
2355
+ // Add the base layers to the map
2356
+ for ( var lyrLen = olLayers.length - 1; lyrLen !== -1; lyrLen -= 1 ) {
2357
+ _this.map.addLayer( olLayers[ lyrLen ] );
2358
+ }
2359
+
2360
+ return removeNullKeys( viewOptions );
2361
+
2362
+ };
2363
+
2364
+ /**
2365
+ * Create Legend
2366
+ */
2367
+ MapLayer.prototype.addToLegend = function() {
2368
+
2369
+ var _this = this,
2370
+ legendDiv = this.map.legend.target,
2371
+ $fieldset, $ul, checked, $chkBox, $label, $li;
2372
+
2373
+ // If no legend or fieldset add them
2374
+ $fieldset = legendDiv.find( "fieldset" );
2375
+ if ( $fieldset.length === 0 ) {
2376
+ $fieldset = $( "<fieldset name='legend'><legend class='wb-inv'>" +
2377
+ i18nText.toggleLayer + "</legend></fieldset>" ).appendTo( legendDiv );
2378
+ }
2379
+
2380
+ checked = this.isVisibile ? "checked='checked'" : "";
2381
+
2382
+ $ul = legendDiv.find( "ul.geomap-lgnd" );
2383
+ if ( $ul.length === 0 ) {
2384
+ $ul = $( "<ul class='list-unstyled geomap-lgnd'></ul>" ).appendTo( $fieldset );
2385
+ }
2386
+
2387
+ $chkBox = $( "<input type='checkbox' id='cb_" + this.id +
2388
+ "' class='geomap-lgnd-cbx' value='" + this.id +
2389
+ "' " + checked + " data-map='" + this.map.id +
2390
+ "' data-layer='" + this.id + "' />" );
2391
+
2392
+ _this.observeVisibility( function( visibility ) {
2393
+
2394
+ // Show/hide legend symbols
2395
+ $( "#sb_" + _this.id ).toggle( visibility );
2396
+
2397
+ // Refresh the legend
2398
+ _this.map.legend.refresh();
2399
+
2400
+ $chkBox.get( 0 ).checked = visibility;
2401
+ } );
2402
+
2403
+ // Handle the change event to Show/hide layer
2404
+ $chkBox.change( function() {
2405
+ _this.isVisible = $( this ).is( ":checked" );
2406
+ } );
2407
+
2408
+ $label = $( "<label>", {
2409
+ "for": "cb_" + this.id,
2410
+ text: this.settings.title
2411
+ } ).prepend( $chkBox );
2412
+
2413
+ $li = $( "<li class='checkbox geomap-lgnd-layer'>" )
2414
+ .append( $label, "<div id='sb_" + this.id + "'></div>" );
2415
+
2416
+ $ul.append( $li );
2417
+
2418
+ if ( this.settings.options && this.settings.options.legendUrl ) {
2419
+ $( "#sb_" + this.id ).append( "<img src='" + this.settings.options.legendUrl + "' alt='" + i18nText.geoLgndGrphc + "'/>" );
2420
+ } else if ( this.settings.options && this.settings.options.legendHTML ) {
2421
+ $( "#sb_" + this.id ).append( this.settings.options.legendHTML );
2422
+ } else if ( this.settings.type !== "wms" && this.settings.type !== "esritile" ) {
2423
+ this.map.legend.symbolize( this );
2424
+ }
2425
+
2426
+ };
2427
+
2428
+ /**
2429
+ * Add tabluar data
2430
+ */
2431
+ Geomap.prototype.addTabularData = function() {
2432
+
2433
+ var $table, table, featureTable, featureArray, attr, theadTr, tdChkBox, tdZoomTo, thElms, thLen,
2434
+ trElms, trLen, useMapControls, attrMap, trElmsInd, geomType,
2435
+ feat, feature, features, vectorFeature, wktFeature,
2436
+ script, bbox, vertices, len, vertLen, lenTable,
2437
+ thZoom = "<span class='wb-inv'>" + i18nText.zoomFeature + "</span>",
2438
+ thSelect = "<span class='wb-inv'>" + i18nText.select + "</span>",
2439
+ thElmZoom, thElmSelect,
2440
+ wktParser = new ol.format.WKT(),
2441
+ thRegex = /<\/?[^>]+>/gi,
2442
+ vectRegex = /\W/g,
2443
+ visibility,
2444
+ style, colors, mapLayer;
2445
+
2446
+ for ( lenTable = this.settings.tables.length - 1; lenTable !== -1; lenTable -= 1 ) {
2447
+
2448
+ table = document.getElementById( this.settings.tables[ lenTable ].id );
2449
+
2450
+ // If the table is not found continue
2451
+ if ( !table ) {
2452
+ continue;
2453
+ }
2454
+
2455
+ $table = $( table ).wrap( "<div data-layer='" + this.settings.tables[ lenTable ].id + "' class='geomap-table-wrapper'></div>" );
2456
+
2457
+ featureTable = this.settings.tables[ lenTable ];
2458
+ featureArray = [];
2459
+ attr = [];
2460
+ thElms = table.getElementsByTagName( "th" );
2461
+ trElms = table.getElementsByTagName( "tr" );
2462
+ trLen = trElms.length;
2463
+ useMapControls = this.settings.useMapControls;
2464
+
2465
+ if ( $table.hasClass( "wb-tables" ) && typeof $table.attr( "data-wb-tables" ) === "undefined" ) {
2466
+ $table.attr( "data-wb-tables", "{ \"order\": [], \"columnDefs\": [ { \"targets\": [ 0, " + ( thElms.length + 1 ) + " ], \"orderable\": false } ] }" );
2467
+ }
2468
+
2469
+ // If visibility is not set to false, show the layer
2470
+ visibility = this.settings.tables[ lenTable ].visible === false ? false : true;
2471
+
2472
+ // Get the attributes from table header
2473
+ for ( thLen = thElms.length - 1; thLen !== -1; thLen -= 1 ) {
2474
+ attr[ thLen ] = thElms[ thLen ].innerHTML.replace( thRegex, "" );
2475
+ }
2476
+
2477
+ // If zoomTo add the header column headers
2478
+ theadTr = $table.find( "thead tr" ).get( 0 );
2479
+ if ( featureTable.zoom && useMapControls ) {
2480
+ thElmZoom = document.createElement( "th" );
2481
+ thElmZoom.innerHTML = thZoom;
2482
+ theadTr.insertBefore( thElmZoom, theadTr.firstChild );
2483
+ }
2484
+
2485
+ // Add select checkbox
2486
+ thElmSelect = document.createElement( "th" );
2487
+ thElmSelect.innerHTML = thSelect;
2488
+ theadTr.appendChild( thElmSelect );
2489
+
2490
+ colors = defaultColors();
2491
+
2492
+ style = typeof featureTable.style === "undefined" ?
2493
+ { "strokeColor": colors.stroke, "fillColor": colors.fill } :
2494
+ featureTable.style;
2495
+
2496
+ // Loop through each row
2497
+ for ( trLen = trElms.length - 1; trLen !== -1; trLen -= 1 ) {
2498
+
2499
+ // Create an array of attributes: value
2500
+ attrMap = {};
2501
+
2502
+ trElmsInd = trElms[ trLen ];
2503
+
2504
+ // Get the geometry type
2505
+ geomType = trElmsInd.getAttribute( "data-type" );
2506
+ features = trElmsInd.getElementsByTagName( "td" );
2507
+
2508
+ for ( len = 0; len < features.length; len += 1 ) {
2509
+
2510
+ // Use innerHTML instead of innerText or textContent because they react differently in different browser
2511
+ // remove script tag from the attribute
2512
+ feature = features[ len ];
2513
+ script = feature.getElementsByTagName( "script" )[ 0 ];
2514
+ if ( script ) {
2515
+ script.parentNode.removeChild( script );
2516
+ }
2517
+ attrMap[ attr[ len ] ] = feature.innerHTML;
2518
+ }
2519
+
2520
+ if ( geomType !== null ) {
2521
+ if ( geomType === "bbox" ) {
2522
+ bbox = trElmsInd.getAttribute( "data-geometry" ).split( "," );
2523
+
2524
+ feat = densifyBBox(
2525
+ bbox[ 0 ],
2526
+ bbox[ 1 ],
2527
+ bbox[ 2 ],
2528
+ bbox[ 3 ]
2529
+ );
2530
+
2531
+ vertices = "";
2532
+
2533
+ for ( vertLen = feat.length - 1; vertLen !== -1; vertLen -= 1 ) {
2534
+ vertices += feat[ vertLen ].getCoordinates()[ 0 ] + " " + feat[ vertLen ].getCoordinates()[ 1 ] + ", ";
2535
+ }
2536
+
2537
+ vertices = vertices.slice( 0, -2 );
2538
+ wktFeature = "POLYGON ((" + vertices + "))";
2539
+
2540
+ } else if ( geomType === "wkt" ) {
2541
+ wktFeature = trElmsInd.getAttribute( "data-geometry" );
2542
+
2543
+ // Backward compatibility fix
2544
+ // REMOVE in next major version of WET
2545
+ if ( wktFeature.indexOf( "POINT" ) !== -1 ) {
2546
+ wktFeature = wktFeature.replace( ",", "" );
2547
+ }
2548
+ }
2549
+
2550
+ vectorFeature = wktParser.readFeature( wktFeature, {
2551
+ dataProjection: "EPSG:4326",
2552
+ featureProjection: this.map.getView().getProjection()
2553
+ } );
2554
+
2555
+ vectorFeature.setId( generateGuid() );
2556
+ vectorFeature.layerId = featureTable.id;
2557
+ vectorFeature.layerTitle = $table.attr( "aria-label" );
2558
+
2559
+ if ( featureTable.tooltips ) {
2560
+ vectorFeature.tooltip = featureTable.tooltipText ? attrMap[ featureTable.tooltipText ] : attrMap[ Object.keys( attrMap )[ 0 ] ];
2561
+ }
2562
+
2563
+ // Set the table row id
2564
+ trElmsInd.setAttribute( "id", vectorFeature.getId().replace( vectRegex, "_" ) );
2565
+
2566
+ // Add the checkboxes and zoom controls
2567
+ tdChkBox = trElmsInd.insertCell( 0 );
2568
+ tdChkBox.innerHTML = addChkBox( this, vectorFeature );
2569
+ if ( useMapControls && featureTable.zoom ) {
2570
+ tdZoomTo = trElmsInd.insertCell( -1 );
2571
+ tdZoomTo.classList.add( "text-right" );
2572
+ tdZoomTo.innerHTML = addZoomTo( this, vectorFeature );
2573
+ }
2574
+
2575
+ // Add the attributes to the feature then add it to the feature array
2576
+ vectorFeature.attributes = attrMap;
2577
+ featureArray.push( vectorFeature );
2578
+
2579
+ }
2580
+ }
2581
+
2582
+ mapLayer = new MapLayer( this, {
2583
+ tableId: $table.attr( "id" ),
2584
+ type: "wkt",
2585
+ visible: visibility,
2586
+ datatable: featureTable.datatable,
2587
+ popupsInfo: featureTable.popupsInfo,
2588
+ popups: featureTable.popups,
2589
+ tooltips: featureTable.tooltips,
2590
+ tooltipText: featureTable.tooltipText,
2591
+ name: featureTable.id,
2592
+ title: $table.attr( "aria-label" ),
2593
+ features: featureArray,
2594
+ style: style
2595
+ } );
2596
+
2597
+ this.mapLayers.push( mapLayer );
2598
+
2599
+ }
2600
+ };
2601
+
2602
+ /**
2603
+ * Create layers
2604
+ */
2605
+ Geomap.prototype.addMapLayers = function() {
2606
+
2607
+ var _this = this,
2608
+ olLayer, mapLayer;
2609
+
2610
+ // Add tabular data first
2611
+ _this.addTabularData();
2612
+
2613
+ // Add overlays second
2614
+ $.each( _this.settings.overlays, function( index, layer ) {
2615
+ mapLayer = new MapLayer( _this, layer );
2616
+ _this.mapLayers.push( mapLayer );
2617
+ } );
2618
+
2619
+ // Add geocoder and AOI layer
2620
+ olLayer = new ol.layer.Vector( {
2621
+ source: new ol.source.Vector(),
2622
+ style: new ol.style.Style( {
2623
+ fill: new ol.style.Fill( {
2624
+ color: "rgba( 255, 0, 20, 0.1 )"
2625
+ } ),
2626
+ stroke: new ol.style.Stroke( {
2627
+ color: "#ff0033",
2628
+ width: 2
2629
+ } ),
2630
+ image: new ol.style.RegularShape( {
2631
+ fill: new ol.style.Fill( {
2632
+ color: "#ff0033"
2633
+ } ),
2634
+ stroke: new ol.style.Stroke( {
2635
+ color: "#ff0033",
2636
+ width: 5
2637
+ } ),
2638
+ points: 4,
2639
+ radius: 10,
2640
+ radius2: 0,
2641
+ angle: 0
2642
+ } )
2643
+ } )
2644
+ } );
2645
+
2646
+ olLayer.id = "locLayer";
2647
+ _this.map.addLayer( olLayer );
2648
+
2649
+ // Finally add the layers to the map
2650
+ for ( var lyrLen = _this.mapLayers.length - 1; lyrLen !== -1; lyrLen -= 1 ) {
2651
+ if ( _this.mapLayers[ lyrLen ].layer ) {
2652
+ _this.map.addLayer( _this.mapLayers[ lyrLen ].layer );
2653
+ }
2654
+ }
2655
+
2656
+ };
2657
+
2658
+ /**
2659
+ * Create a table for vector features
2660
+ * @return { table }
2661
+ */
2662
+ MapLayer.prototype.populateDataTable = function() {
2663
+
2664
+ if ( !this.settings.accessible ) {
2665
+ return;
2666
+ }
2667
+
2668
+ var _this = this,
2669
+ attributes = _this.settings.attributes,
2670
+ len = attributeLen(),
2671
+ $table,
2672
+ sTable = "<table aria-label='" + _this.settings.title + "' id='" + _this.id + "' " +
2673
+ "data-wb-tables='{ \"order\": [], \"columnDefs\": [ { \"targets\": [ 0, " + ( len + 1 ) + " ], \"orderable\": false } ] }'" +
2674
+ "class='table",
2675
+ sCaption = "'><caption>" + _this.settings.caption + "</caption>",
2676
+ head = "<th><span class='wb-inv'>" + i18nText.select + "</span></th>",
2677
+ body = "",
2678
+ features = _this.layer.getSource().getFeatures(),
2679
+ key, attKey;
2680
+
2681
+ if ( _this.settings.datatable ) {
2682
+ sTable = sTable + " wb-tables";
2683
+ } else {
2684
+ sTable = sTable + " table-condensed";
2685
+ }
2686
+
2687
+ // Create the header row
2688
+ for ( key in attributes ) {
2689
+ if ( Object.prototype.hasOwnProperty.call( attributes, key ) ) {
2690
+ attKey = attributes[ key ].alias ? attributes[ key ].alias : attributes[ key ];
2691
+ head += "<th>" + attKey + "</th>";
2692
+ }
2693
+ }
2694
+
2695
+ head = "<thead><tr>" + head + ( _this.map.settings.useMapControls && _this.settings.zoom ? "<th><span class='wb-inv'>" + i18nText.zoomFeature + "</span></th>" : "" ) + "</tr></thead>";
2696
+
2697
+ // Create the table body rows
2698
+ // for ( var i = 0; i < features.length || ( function() { refreshPlugins( _this.map ); return false; }() ); i += 1 ) {
2699
+ for ( var i = 0; i < features.length; i += 1 ) {
2700
+
2701
+ body += "<tr><td>" + addChkBox( _this, features[ i ] );
2702
+
2703
+ attributes = features[ i ].attributes;
2704
+
2705
+ for ( key in attributes ) {
2706
+ if ( Object.prototype.hasOwnProperty.call( attributes, key ) ) {
2707
+ body += "<td>" + attributes[ key ] + "</td>";
2708
+ }
2709
+ }
2710
+
2711
+ body += _this.map.settings.useMapControls && _this.settings.zoom ? "<td class='text-right'>" + addZoomTo( _this.map, features[ i ] ) : "";
2712
+
2713
+ }
2714
+
2715
+ $table = $( sTable + sCaption + head + "<tbody>" + body + "</tbody>" + "</table>" );
2716
+
2717
+ $( "div[ data-layer='" + _this.id + "'].geomap-table-wrapper" ).append( $table );
2718
+
2719
+ function attributeLen() {
2720
+ var len = 0;
2721
+ for ( var key in attributes ) {
2722
+ if ( Object.prototype.hasOwnProperty.call( attributes, key ) ) {
2723
+ len += 1;
2724
+ }
2725
+ }
2726
+ return len;
2727
+ }
2728
+
2729
+ refreshPlugins( _this.map );
2730
+
2731
+ return $table;
2732
+ };
2733
+
2734
+ /**
2735
+ * Create OpenLayers Layer
2736
+ * @returns {ol.Layer}
2737
+ */
2738
+ MapLayer.prototype.createOLLayer = function() {
2739
+
2740
+ var _this = this,
2741
+ layerAttributes = _this.settings.attributes,
2742
+ colors, olLayer, styleFactory, atts, featureGeometry, key, source;
2743
+
2744
+ if ( _this.settings.type === "wms" ) {
2745
+
2746
+ var keys = getLayerKeys( _this.settings ),
2747
+ opacity = keys.options.opacity ? keys.options.opacity : 1;
2748
+
2749
+ olLayer = new ol.layer.Image( {
2750
+ opacity: opacity,
2751
+ visible: _this.settings.visible,
2752
+ source: new ol.source.ImageWMS( {
2753
+ url: _this.settings.url,
2754
+ params: keys
2755
+ } )
2756
+ } );
2757
+
2758
+ // Image layers don't have features, so don't create table
2759
+ _this.settings.accessible = false;
2760
+
2761
+ } else if ( _this.settings.type === "esritile" ) {
2762
+
2763
+ var mapOpts = {
2764
+ url: _this.settings.url,
2765
+ params: _this.settings.params
2766
+ };
2767
+
2768
+ olLayer = new ol.layer.Tile( {
2769
+ visible: _this.settings.visible,
2770
+ source: new ol.source.TileArcGISRest( mapOpts )
2771
+ } );
2772
+
2773
+ _this.settings.accessible = false;
2774
+
2775
+ } else if ( _this.settings.type === "wkt" ) {
2776
+
2777
+ styleFactory = new StyleFactory();
2778
+
2779
+ // TODO pass data into this rather than taking features from mapLayer
2780
+ // create a new layer with the feature array
2781
+ olLayer = new ol.layer.Vector( {
2782
+ visible: _this.settings.visible,
2783
+ source: new ol.source.Vector( {
2784
+ features: _this.settings.features
2785
+ } ),
2786
+ style: styleFactory.createStyleFunction( _this.settings.style, _this.settings.featureType )
2787
+ } );
2788
+
2789
+ // TODO set this in the addTabular data stream
2790
+ _this.settings.accessible = false;
2791
+
2792
+ } else if ( _this.settings.type === "kml" ) {
2793
+
2794
+ var extractStyles = !_this.settings.style;
2795
+
2796
+ styleFactory = new StyleFactory();
2797
+ colors = defaultColors();
2798
+
2799
+ //TODO: KML styles are getting overridden, don't do this
2800
+ olLayer = new ol.layer.Vector( {
2801
+ visible: _this.settings.visible,
2802
+ source: new ol.source.Vector( {
2803
+ url: _this.settings.url,
2804
+ format: new ol.format.KML( {
2805
+ extractStyles: extractStyles
2806
+ } )
2807
+ } )
2808
+ } );
2809
+
2810
+ // TODO: this overrides style in KML - please fix
2811
+ if ( typeof _this.settings.style === "undefined" ) {
2812
+
2813
+ // TODO: create a defaultStyle object
2814
+ _this.settings.style = { "strokeColor": colors.stroke, "fillColor": colors.fill };
2815
+ }
2816
+
2817
+ // Set the style
2818
+ olLayer.getSource().once( "addfeature", function( event ) {
2819
+ featureGeometry = event.feature.getGeometry().getType();
2820
+
2821
+ if ( !extractStyles ) {
2822
+ var style = styleFactory.createStyleFunction(
2823
+ _this.settings.style,
2824
+ featureGeometry
2825
+ );
2826
+ olLayer.setStyle( style );
2827
+ }
2828
+ } );
2829
+
2830
+ source = olLayer.getSource();
2831
+
2832
+ key = source.on( "change", function() {
2833
+
2834
+ if ( source.getState() === "ready" ) {
2835
+ source.unByKey( key );
2836
+
2837
+ var features = this.getFeatures();
2838
+
2839
+ for ( var i = 0, len = features.length; i < len; i += 1 ) {
2840
+
2841
+ var feature = features[ i ];
2842
+
2843
+ if ( _this.settings.style.select ) {
2844
+ _this.settings.style.select.type = "select";
2845
+ var selStyleFactory = new StyleFactory(),
2846
+ selStyle = selStyleFactory.createStyleFunction(
2847
+ _this.settings.style.select,
2848
+ feature.getGeometry().getType()
2849
+ );
2850
+ feature.selectStyle = selStyle;
2851
+ }
2852
+
2853
+ feature.setId( generateGuid() );
2854
+ feature.layerId = olLayer.id;
2855
+ feature.layerTitle = olLayer.title;
2856
+
2857
+ atts = {};
2858
+
2859
+ //TODO: densify coordinates
2860
+
2861
+ // Parse and store the attributes
2862
+ // TODO: test on nested attributes
2863
+ for ( var name in layerAttributes ) {
2864
+ if ( Object.prototype.hasOwnProperty.call( layerAttributes, name ) ) {
2865
+ atts[ layerAttributes[ name ] ] = feature.getProperties()[ name ];
2866
+ }
2867
+ }
2868
+ feature.attributes = atts;
2869
+
2870
+ if ( _this.settings.tooltips ) {
2871
+ feature.tooltip = _this.settings.tooltipText ? atts[ _this.settings.tooltipText ] : atts[ Object.keys( atts )[ 0 ] ];
2872
+ }
2873
+
2874
+ }
2875
+
2876
+ // Populate table with feature data
2877
+ _this.populateDataTable();
2878
+
2879
+ _this.map.legend.symbolize( _this );
2880
+ }
2881
+ }, source );
2882
+
2883
+
2884
+ } else if ( _this.settings.type === "json" ) {
2885
+
2886
+ var olSource = new ol.source.Vector();
2887
+
2888
+ styleFactory = new StyleFactory();
2889
+ colors = defaultColors();
2890
+
2891
+ if ( typeof _this.settings.style === "undefined" ) {
2892
+
2893
+ // TODO: create a defaultStyle object
2894
+ _this.settings.style = { "strokeColor": colors.stroke, "fillColor": colors.fill };
2895
+ }
2896
+
2897
+ if ( _this.settings.cluster ) {
2898
+ olLayer = new ol.layer.Vector( {
2899
+ visible: _this.settings.visible,
2900
+ source: new ol.source.Cluster( {
2901
+ distance: 40,
2902
+ source: olSource
2903
+ } )
2904
+ } );
2905
+ } else {
2906
+ olLayer = new ol.layer.Vector( {
2907
+ visible: _this.settings.visible,
2908
+ source: olSource
2909
+ } );
2910
+ }
2911
+
2912
+ // Set the style
2913
+ olSource.once( "addfeature", function() {
2914
+ olLayer.setStyle( styleFactory.createStyleFunction( _this.settings.style, featureGeometry ) );
2915
+ } );
2916
+
2917
+ var getCoordKey = function( feature ) {
2918
+
2919
+ var geomKey;
2920
+
2921
+ $.each( feature, function( k, v ) {
2922
+ if ( v.coordinates ) {
2923
+ geomKey = k;
2924
+ }
2925
+ } );
2926
+
2927
+ return geomKey;
2928
+ };
2929
+
2930
+ var successHandler = function( data ) {
2931
+
2932
+ var layerRoot = _this.settings.root,
2933
+ features = data[ layerRoot ] ? data[ layerRoot ] : data.features ? data.features : data,
2934
+ atts, bnds, feature, firstComponent, geom, geomProj, geomKey, i, len, path;
2935
+
2936
+ // in some cases an array is not returned, so create one
2937
+ if ( features instanceof Array === false ) {
2938
+ features = $.map( features, function( obj ) {
2939
+ return obj;
2940
+ } );
2941
+ }
2942
+
2943
+ for ( i = 0, len = features.length; i < len; i += 1 ) {
2944
+
2945
+ feature = features[ i ];
2946
+
2947
+ // look for a property named "coordinates" - lots to go wrong here
2948
+ // TODO: use regex to find something that looks like coordinates
2949
+ if ( !geomKey ) {
2950
+ geomKey = getCoordKey( feature );
2951
+ }
2952
+
2953
+ if ( !feature[ geomKey ] ) {
2954
+ continue;
2955
+ }
2956
+
2957
+ firstComponent = feature[ geomKey ].coordinates[ 0 ];
2958
+
2959
+ // if we have a bounding box polygon, densify the coordinates
2960
+ if ( Object.values( feature[ geomKey ] ).includes( "Polygon" ) &&
2961
+ firstComponent.length === 5 ) {
2962
+
2963
+ bnds = densifyBBox(
2964
+ firstComponent[ 1 ][ 0 ],
2965
+ firstComponent[ 1 ][ 1 ],
2966
+ firstComponent[ 3 ][ 0 ],
2967
+ firstComponent[ 3 ][ 1 ]
2968
+ );
2969
+
2970
+ var coordinates = [];
2971
+
2972
+ for ( var j = 0, len2 = bnds.length; j < len2; j += 1 ) {
2973
+ var point = bnds[ j ];
2974
+ coordinates.push( point.getCoordinates() );
2975
+ }
2976
+
2977
+ geom = new ol.geom.Polygon( [ coordinates ] );
2978
+
2979
+ } else if ( Object.values( feature[ geomKey ] ).includes( "Point" ) ) {
2980
+
2981
+ // TODO: if creating point fails, try reversing the coordinate order. Perhaps a configuration parameter would be best.
2982
+ geom = new ol.geom.Point( [ feature[ geomKey ].coordinates[ 0 ], feature[ geomKey ].coordinates[ 1 ] ] );
2983
+
2984
+ } else if ( Object.values( feature[ geomKey ] ).includes( "LineString" ) ) {
2985
+
2986
+ geom = new ol.geom.LineString( feature[ geomKey ].coordinates );
2987
+
2988
+ }
2989
+
2990
+ // transform the feature
2991
+ // TODO: support GeoJSON projections via OGC CRS URNs such as:
2992
+ // "urn:ogc:def:crs:OGC:1.3:CRS84"
2993
+ geomProj = geom.transform( "EPSG:4326", _this.map.map.getView().getProjection() );
2994
+
2995
+ // Parse and store the attributes
2996
+ // TODO: test on nested attributes
2997
+ // NOTE: it is possible that a feature is missing a value, in
2998
+ // which case we show an empty string in it's place
2999
+ atts = {};
3000
+
3001
+ for ( var name in layerAttributes ) {
3002
+ path = null;
3003
+ if ( Object.prototype.hasOwnProperty.call( layerAttributes, name ) ) {
3004
+ path = layerAttributes[ name ].path;
3005
+ if ( path ) {
3006
+ atts[ layerAttributes[ name ].alias ] = feature[ path ] ? feature[ path ][ name ] : "";
3007
+ } else {
3008
+ atts[ layerAttributes[ name ] ] = feature[ name ] ? feature[ name ] : "";
3009
+ }
3010
+ }
3011
+ }
3012
+
3013
+ feature = new ol.Feature();
3014
+ feature.setId( generateGuid() );
3015
+ feature.layerId = olLayer.id;
3016
+ feature.layerTitle = olLayer.title;
3017
+ feature.attributes = atts;
3018
+ feature.setGeometry( geomProj );
3019
+ olSource.addFeature( feature );
3020
+
3021
+ if ( _this.settings.tooltips ) {
3022
+ feature.tooltip = _this.settings.tooltipText ? atts[ _this.settings.tooltipText ] : atts[ Object.keys( atts )[ 0 ] ];
3023
+ }
3024
+
3025
+ }
3026
+
3027
+ // Populate table with feature data
3028
+ _this.populateDataTable();
3029
+
3030
+ _this.map.legend.symbolize( _this );
3031
+ };
3032
+
3033
+ // Get the file
3034
+ $.getJSON( _this.settings.url, _this.settings.params, successHandler );
3035
+
3036
+ } else if ( _this.settings.type === "geojson" || _this.settings.type === "esrijson" || _this.settings.type === "topojson" ) {
3037
+
3038
+ var layerURL;
3039
+
3040
+ styleFactory = new StyleFactory();
3041
+ colors = defaultColors();
3042
+
3043
+ if ( typeof _this.settings.style === "undefined" ) {
3044
+
3045
+ // TODO: create a defaultStyle object
3046
+ _this.settings.style = { "strokeColor": colors.stroke, "fillColor": colors.fill };
3047
+ }
3048
+
3049
+ layerURL = _this.settings.params ? _this.settings.url + "?" + $.param( _this.settings.params ) : _this.settings.url;
3050
+
3051
+ if ( _this.settings.type === "geojson" ) {
3052
+ olLayer = new ol.layer.Vector( {
3053
+ visible: _this.settings.visible,
3054
+ source: new ol.source.Vector( {
3055
+ url: layerURL,
3056
+ format: new ol.format.GeoJSON(),
3057
+ strategy: ol.loadingstrategy.bbox
3058
+ } )
3059
+ } );
3060
+ } else if ( _this.settings.type === "topojson" ) {
3061
+ olLayer = new ol.layer.Vector( {
3062
+ visible: _this.settings.visible,
3063
+ source: new ol.source.Vector( {
3064
+ url: layerURL,
3065
+ format: new ol.format.TopoJSON()
3066
+ } )
3067
+ } );
3068
+ } else {
3069
+ olLayer = new ol.layer.Vector( {
3070
+ visible: _this.settings.visible,
3071
+ source: new ol.source.Vector( {
3072
+ url: layerURL,
3073
+ format: new ol.format.EsriJSON(),
3074
+ strategy: ol.loadingstrategy.bbox
3075
+ } )
3076
+ } );
3077
+ }
3078
+
3079
+ // Set the style
3080
+ olLayer.getSource().once( "addfeature", function( event ) {
3081
+ featureGeometry = event.feature.getGeometry().getType();
3082
+ var style = styleFactory.createStyleFunction(
3083
+ _this.settings.style,
3084
+ featureGeometry
3085
+ );
3086
+ olLayer.setStyle( style );
3087
+ } );
3088
+
3089
+ // Wait until all features are loaded, then build table and symbolize legend
3090
+ source = olLayer.getSource();
3091
+
3092
+ key = source.on( "change", function() {
3093
+
3094
+ if ( source.getState() === "ready" ) {
3095
+ source.unByKey( key );
3096
+
3097
+ var features = this.getFeatures();
3098
+
3099
+ for ( var i = 0, len = features.length; i < len; i += 1 ) {
3100
+
3101
+ var feature = features[ i ];
3102
+
3103
+ feature.setId( generateGuid() );
3104
+ feature.layerId = olLayer.id;
3105
+ feature.layerTitle = olLayer.title;
3106
+ atts = {};
3107
+
3108
+ //TODO: densify coordinates
3109
+
3110
+ // Parse and store the attributes
3111
+ // TODO: test on nested attributes
3112
+ for ( var name in layerAttributes ) {
3113
+ if ( Object.prototype.hasOwnProperty.call( layerAttributes, name ) ) {
3114
+ atts[ layerAttributes[ name ] ] = feature.getProperties()[ name ];
3115
+ }
3116
+ }
3117
+
3118
+ feature.attributes = atts;
3119
+
3120
+ if ( _this.settings.tooltips ) {
3121
+ feature.tooltip = _this.settings.tooltipText ? atts[ _this.settings.tooltipText ] : atts[ Object.keys( atts )[ 0 ] ];
3122
+ }
3123
+
3124
+ }
3125
+
3126
+ // Populate table with feature data
3127
+ _this.populateDataTable();
3128
+
3129
+ _this.map.legend.symbolize( _this );
3130
+ }
3131
+
3132
+ }, source );
3133
+
3134
+ }
3135
+
3136
+ if ( olLayer ) {
3137
+ olLayer.id = _this.id;
3138
+ olLayer.title = _this.settings.title;
3139
+ olLayer.datatable = _this.settings.datatable;
3140
+ olLayer.popupsInfo = _this.settings.popupsInfo;
3141
+ olLayer.popups = _this.settings.popups;
3142
+
3143
+ return olLayer;
3144
+
3145
+ } else {
3146
+
3147
+ return null;
3148
+
3149
+ }
3150
+
3151
+ };
3152
+
3153
+
3154
+ /**
3155
+ * Load controls and interactions
3156
+ */
3157
+ Geomap.prototype.loadControls = function() {
3158
+
3159
+ var _this = this,
3160
+ map = _this.map,
3161
+ popups = false,
3162
+ extentCtrl, mouseCtrl, scaleCtrl, selectInteraction;
3163
+
3164
+ // Add a select interaction
3165
+ selectInteraction = new ol.interaction.Select( {
3166
+ layers: _this.layers
3167
+ } );
3168
+
3169
+ selectInteraction.getFeatures().on( "remove", function( event ) {
3170
+ var feature = event.element;
3171
+ feature.setStyle( null );
3172
+ $( "#cb_" + feature.getId() ).prop( "checked", false ).closest( "tr" ).removeClass( "active" );
3173
+ } );
3174
+
3175
+ selectInteraction.getFeatures().on( "add", function( event ) {
3176
+ var feature = event.element;
3177
+ if ( feature.selectStyle ) {
3178
+ feature.setStyle( feature.selectStyle );
3179
+ }
3180
+ $( "#cb_" + feature.getId() ).prop( "checked", true ).closest( "tr" ).addClass( "active" );
3181
+ } );
3182
+
3183
+ // Add select event handler
3184
+ selectInteraction.on( "select", function( event ) {
3185
+
3186
+ var _this = this,
3187
+ selected = event.selected ? event.selected : _this.getFeatures();
3188
+
3189
+ if ( selected && selected.length > 0 && typeof selected[ 0 ].layerTitle !== "undefined" ) {
3190
+ popups = getLayerById( _this.getMap(), selected[ 0 ].layerId ).popups;
3191
+
3192
+ selected[ 0 ].layerTitle = _this.getLayer( event.selected[ 0 ] ).title;
3193
+
3194
+ if ( popups ) {
3195
+ showPopup( event, selected[ 0 ], map );
3196
+ }
3197
+ }
3198
+
3199
+ // if there are no selected features then hide the popup
3200
+ if ( selected && selected.length === 0 ) {
3201
+ showPopup( event, null, map );
3202
+ }
3203
+
3204
+ }, selectInteraction );
3205
+
3206
+ // Add the interaction to the map
3207
+ map.getInteractions().extend( [ selectInteraction ] );
3208
+
3209
+ if ( _this.settings.useMapControls ) {
3210
+
3211
+ var element = document.createElement( "span" );
3212
+
3213
+ element.className = "glyphicon glyphicon-home";
3214
+
3215
+ extentCtrl = new ol.control.ZoomToExtent( {
3216
+ extent: map.getView().calculateExtent( map.getSize() ),
3217
+ label: element
3218
+ } );
3219
+
3220
+ map.addControl( extentCtrl );
3221
+
3222
+ extentCtrl.element.setAttribute( "aria-label", i18nText.zoomworld );
3223
+ extentCtrl.element.setAttribute( "title", i18nText.zoomworld );
3224
+
3225
+ if ( _this.settings.useMousePosition ) {
3226
+ mouseCtrl = new ol.control.MousePosition( {
3227
+ coordinateFormat: ol.coordinate.createStringXY( 4 ),
3228
+ projection: "EPSG:4326",
3229
+ undefinedHTML: ""
3230
+ } );
3231
+ map.addControl( mouseCtrl );
3232
+ mouseCtrl.element.setAttribute( "aria-label", i18nText.mouseposition );
3233
+ mouseCtrl.element.setAttribute( "title", i18nText.mouseposition );
3234
+ }
3235
+
3236
+ if ( _this.settings.useScaleLine ) {
3237
+ scaleCtrl = new ol.control.ScaleLine();
3238
+ map.addControl( scaleCtrl );
3239
+ scaleCtrl.element.setAttribute( "aria-label", i18nText.scaleline );
3240
+ scaleCtrl.element.setAttribute( "title", i18nText.scaleline );
3241
+ }
3242
+
3243
+ }
3244
+
3245
+ // Add the geocoder widget
3246
+ if ( _this.settings.useGeocoder ) {
3247
+ new GeocodeControl( _this );
3248
+ }
3249
+
3250
+ // Add the AOI widget
3251
+ if ( _this.settings.useAOI ) {
3252
+ new AOIWidget( _this );
3253
+ }
3254
+
3255
+ // Add the geolocation widget
3256
+ if ( _this.settings.useGeolocation ) {
3257
+ _this.map.addControl( new GeolocationControl( { projection: _this.map.getView().getProjection() } ) );
3258
+ }
3259
+
3260
+ };
3261
+
3262
+ /**
3263
+ * Create an overlay to anchor the popup to the map.
3264
+ */
3265
+ Geomap.prototype.createPopup = function() {
3266
+
3267
+ var _this = this,
3268
+ $closer, overlay, $popup;
3269
+
3270
+ $popup = $( "<div id='popup-" + _this.mapDiv.attr( "id" ) + "' class='ol-popup'></div>" );
3271
+ $closer = $( "<a href='#' title='" + i18nText.dismiss + "' class='ol-popup-closer' role='button'>&#xd7;<span class='wb-inv'>" + i18nText.dismiss + "</span></a>" );
3272
+ $popup.append( $closer, "<div class='popup-content'></div>" );
3273
+
3274
+ // Add the popup container
3275
+ $( "#" + _this.mapDiv.attr( "id" ) ).append( $popup );
3276
+
3277
+ overlay = new ol.Overlay( {
3278
+ element: document.getElementById( "popup-" + _this.mapDiv.attr( "id" ) ),
3279
+ autoPan: true,
3280
+ autoPanAnimation: {
3281
+ duration: 250
3282
+ }
3283
+ } );
3284
+
3285
+ // Add a click handler to hide the popup
3286
+ $closer.on( "click", function( event ) {
3287
+ event.preventDefault();
3288
+ overlay.setPosition( undefined );
3289
+ this.blur();
3290
+ return false;
3291
+ } );
3292
+
3293
+ _this.map.addOverlay( overlay );
3294
+ };
3295
+
3296
+ /**
3297
+ * Add accessibility enhancements
3298
+ */
3299
+ Geomap.prototype.accessibilize = function() {
3300
+
3301
+ var _this = this,
3302
+ $ctrlZoomIn = _this.mapDiv.find( ".ol-zoom-in" ),
3303
+ $ctrlZoomOut = _this.mapDiv.find( ".ol-zoom-out" );
3304
+
3305
+ $ctrlZoomIn.attr( "aria-label", i18nText.zoomin );
3306
+ $ctrlZoomIn.attr( "title", i18nText.zoomin );
3307
+ $ctrlZoomOut.attr( "aria-label", i18nText.zoomout );
3308
+ $ctrlZoomOut.attr( "title", i18nText.zoomout );
3309
+
3310
+ // Add the map div to the tabbing order
3311
+ _this.mapDiv.attr( {
3312
+ tabindex: "0",
3313
+ "data-map": _this.id
3314
+ } );
3315
+
3316
+ // Add WCAG element for the map div
3317
+ _this.mapDiv.attr( {
3318
+ role: "dialog",
3319
+ "aria-label": i18nText.ariaMap
3320
+ } );
3321
+
3322
+ if ( _this.settings.useMapControls ) {
3323
+
3324
+ // Add the map instructions
3325
+ new HelpControl( _this );
3326
+ }
3327
+
3328
+ };
3329
+
3330
+ /**
3331
+ * Zoom to an area of interest
3332
+ *
3333
+ * Param
3334
+ * -----
3335
+ * top = North || space separated list with all of them || WKT || empty
3336
+ * right = East
3337
+ * bottom = South
3338
+ * left = West
3339
+ */
3340
+ Geomap.prototype.zoomAOI = function( top, right, bottom, left ) {
3341
+
3342
+ var _this = this,
3343
+ OLmap = _this.map,
3344
+ olView = OLmap.getView(),
3345
+ extentCoordinate,
3346
+ extent,
3347
+ vectorFeature,
3348
+ isTopString = ( typeof top === "string" );
3349
+
3350
+ if ( isTopString && !top.length ) {
3351
+
3352
+ // Reset the zoom and center the map
3353
+ olView.setZoom( olView.getMaxZoom );
3354
+ return;
3355
+
3356
+ } else if ( isTopString && top.substring( 0, 1 ).match( /[a-z]/gi ) !== null ) {
3357
+
3358
+ // This is wkt type
3359
+ var wktParser = new ol.format.WKT();
3360
+
3361
+ vectorFeature = wktParser.readFeature( top, {
3362
+ dataProjection: "EPSG:4326",
3363
+ featureProjection: olView.getProjection()
3364
+ } );
3365
+
3366
+ } else {
3367
+
3368
+ // Just 4 cardinal point was given
3369
+ if ( !right && isTopString ) {
3370
+ extentCoordinate = top.split( " " );
3371
+ if ( extentCoordinate.length !== 4 ) {
3372
+ throw "4 cardinal point must be provided";
3373
+ }
3374
+ top = extentCoordinate[ 0 ];
3375
+ right = extentCoordinate[ 1 ];
3376
+ bottom = extentCoordinate[ 2 ];
3377
+ left = extentCoordinate[ 3 ];
3378
+ } else if ( !right || !bottom || !left ) {
3379
+ throw "Cardinal point must be provided";
3380
+ }
3381
+ extentCoordinate = [ parseFloat( left ), parseFloat( bottom ), parseFloat( right ), parseFloat( top ) ];
3382
+
3383
+ vectorFeature = drawAOI( _this, extentCoordinate, true );
3384
+ }
3385
+
3386
+ extent = vectorFeature.getGeometry().getExtent();
3387
+
3388
+ olView.fit( extent, OLmap.getSize() );
3389
+ };
3390
+
3391
+ /*
3392
+ * Select a layer
3393
+ *
3394
+ * layerName = String or []<string>: Layer name to apply a state
3395
+ * state = Boolean, default false: Visibility state that are going to be set
3396
+ * onlyThose = Boolean, default false: If true, the inverse visibility state would be set for all the other layers.
3397
+ *
3398
+ */
3399
+ Geomap.prototype.showLayer = function( layerName, state ) {
3400
+
3401
+ var layerNameArray = [],
3402
+ geomapLayers = this.mapLayers,
3403
+ i, i_len = geomapLayers.length,
3404
+ i_lyr, i_lyr_title;
3405
+
3406
+ state = !!state;
3407
+
3408
+ if ( Array.isArray( layerName ) ) {
3409
+ layerNameArray = layerName;
3410
+ } else {
3411
+ layerNameArray.push( layerName );
3412
+ }
3413
+
3414
+ for ( i = 0; i !== i_len; i = i + 1 ) {
3415
+ i_lyr = geomapLayers[ i ];
3416
+ i_lyr_title = i_lyr.layer.title;
3417
+
3418
+ if ( !layerName || layerNameArray.indexOf( i_lyr_title ) !== -1 ) {
3419
+ i_lyr.isVisible = state;
3420
+ } else if ( i_lyr_title ) {
3421
+ i_lyr.isVisible = !state;
3422
+ }
3423
+ }
3424
+ };
3425
+
3426
+ /**
3427
+ * Add the layer symbology to the legend
3428
+ */
3429
+ MapLegend.prototype.symbolize = function( mapLayer ) {
3430
+
3431
+ if ( !mapLayer.layer ) {
3432
+ return;
3433
+ }
3434
+
3435
+ var _this = this,
3436
+ style = mapLayer.settings.style,
3437
+ layerName = mapLayer.id,
3438
+ feature = mapLayer.layer.getSource().getFeatures()[ 0 ],
3439
+ symbolItems = [],
3440
+ symbolList = "",
3441
+ title = "",
3442
+ filter, ruleLen, symbolizer, i, j, len, rule, spanId;
3443
+
3444
+ if ( typeof style !== "undefined" && style.rule ) {
3445
+
3446
+ ruleLen = style.rule.length;
3447
+
3448
+ if ( ruleLen ) {
3449
+
3450
+ for ( j = 0; j !== ruleLen; j += 1 ) {
3451
+ rule = style.rule[ j ];
3452
+ filter = rule.filter;
3453
+ symbolizer = rule.init;
3454
+ title = "";
3455
+ spanId = "ls_" + layerName + "_" + j;
3456
+
3457
+ if ( filter && !rule.name ) {
3458
+ if ( filter.name ) {
3459
+ title = filter.name;
3460
+ } else {
3461
+ switch ( filter ) {
3462
+ case "EQUAL_TO":
3463
+ title = rule.field + " = " + rule.value[ 0 ];
3464
+ break;
3465
+ case "GREATER_THAN":
3466
+ title = rule.field + " > " + rule.value[ 0 ];
3467
+ break;
3468
+ case "LESS_THAN":
3469
+ title = rule.field + " < " + rule.value[ 0 ];
3470
+ break;
3471
+ case "BETWEEN":
3472
+ title = rule.field + " " + rule.value[ 0 ] + " - " + rule.value[ 1 ];
3473
+ break;
3474
+ }
3475
+ }
3476
+ } else if ( rule && rule.name ) {
3477
+ title = rule.name;
3478
+ }
3479
+
3480
+ symbolList += "<li>" +
3481
+ "<div class='geomap-legend-element'>" +
3482
+ "<div id='" + spanId + "' class='geomap-legend-symbol'></div>" +
3483
+ "<span class='geomap-legend-symbol-text'><small>" + title + "</small></span>" +
3484
+ "</div>" +
3485
+ "</li>";
3486
+
3487
+ symbolItems.push( { "id": spanId, "feature": feature, "symbolizer": symbolizer } );
3488
+ }
3489
+
3490
+ }
3491
+
3492
+ } else if ( typeof style !== "undefined" && style.type === "unique" ) {
3493
+
3494
+ j = 0;
3495
+
3496
+ for ( var obj in style.init ) {
3497
+ spanId = "ls_" + layerName + "_" + j;
3498
+ symbolizer = style.init[ obj ];
3499
+ title = symbolizer.name ? symbolizer.name : obj;
3500
+
3501
+ symbolList += "<li>" +
3502
+ "<div class='geomap-legend-element'>" +
3503
+ "<div id='" + spanId + "' class='geomap-legend-symbol'></div>" +
3504
+ "<span class='geomap-legend-symbol-text'><small>" + title + "</small></span>" +
3505
+ "</div>" +
3506
+ "</li>";
3507
+
3508
+ symbolItems.push( { "id": spanId, "feature": feature, "symbolizer": symbolizer } );
3509
+
3510
+ j += 1;
3511
+ }
3512
+ } else if ( typeof style !== "undefined" && style.type === "symbol" ) {
3513
+
3514
+ spanId = "ls_" + layerName + "_0";
3515
+ symbolizer = style.init;
3516
+ title = symbolizer.name ? symbolizer.name : "";
3517
+
3518
+ symbolList += "<li>" +
3519
+ "<div class='geomap-legend-element'>" +
3520
+ "<div id='" + spanId + "' class='geomap-legend-symbol'></div>" +
3521
+ "<span class='geomap-legend-symbol-text'><small>" + title + "</small></span>" +
3522
+ "</div>" +
3523
+ "</li>";
3524
+
3525
+ symbolItems.push( { "id": spanId, "feature": feature, "symbolizer": symbolizer } );
3526
+
3527
+ } else {
3528
+
3529
+ spanId = "ls_" + layerName + "_0";
3530
+ symbolizer = {
3531
+ "fillColor": style.fillColor,
3532
+ "strokeColor": style.strokeColor,
3533
+ "strokeWidth": style.strokeWidth,
3534
+ "strokeDash": style.strokeDash
3535
+ };
3536
+
3537
+ symbolList += "<li>" +
3538
+ "<div class='geomap-legend-element'>" +
3539
+ "<div id='" + spanId + "' class='geomap-legend-symbol'></div>" +
3540
+ "<span class='geomap-legend-symbol-text'><small>" + title + "</small></span>" +
3541
+ "</div>" +
3542
+ "</li>";
3543
+
3544
+ symbolItems.push( { "id": spanId, "feature": feature, "symbolizer": symbolizer } );
3545
+
3546
+ }
3547
+
3548
+ // append the list to the legend
3549
+ $( "#sb_" + layerName ).html( "<ul class='list-unstyled'>" + symbolList + "</ul>" );
3550
+
3551
+ // create the legend symbols
3552
+ for ( i = 0, len = symbolItems.length; i !== len; i += 1 ) {
3553
+ var symbol = symbolItems[ i ];
3554
+ _this.getSymbol( symbol.id, symbol.feature, symbol.symbolizer );
3555
+ }
3556
+
3557
+ };
3558
+
3559
+ /**
3560
+ * Get legend symbols
3561
+ */
3562
+ MapLegend.prototype.getSymbol = function( id, feature, symbolizer ) {
3563
+
3564
+ var colors = defaultColors(), //TODO: symbolizer must have colors else legend won't match
3565
+
3566
+ featureType = feature && feature.getGeometry() ? feature.getGeometry().getType() : "Polygon",
3567
+ opacity = symbolizer.fillOpacity ? symbolizer.fillOpacity : symbolizer.graphicOpacity ? symbolizer.graphicOpacity : 1.0,
3568
+ fillColor = symbolizer.fillColor ? hexToRGB( symbolizer.fillColor, opacity ) : colors.transparent,
3569
+ radius = symbolizer.pointRadius ? symbolizer.pointRadius : 5,
3570
+ strokeColor = symbolizer.strokeColor ? hexToRGB( symbolizer.strokeColor ) : colors.transparent,
3571
+ strokeWidth = symbolizer.strokeWidth ? symbolizer.strokeWidth : 1,
3572
+ strokeDash = symbolizer.strokeDash ? symbolizer.strokeDash : [ 1, 0 ],
3573
+ externalGraphic = symbolizer.externalGraphic ? symbolizer.externalGraphic : null,
3574
+ graphicName = symbolizer.graphicName ? symbolizer.graphicName : null,
3575
+ graphicHeight = symbolizer.graphicHeight ? symbolizer.graphicHeight : 30,
3576
+ graphicWidth = symbolizer.graphicWidth ? symbolizer.graphicWidth : 30,
3577
+ height = graphicHeight < radius * 2 ? radius * 2 : graphicHeight,
3578
+ width = graphicWidth < radius * 2 ? radius * 2 : graphicWidth,
3579
+ pseudoFeature, rendererMap, source, style;
3580
+
3581
+ switch ( featureType ) {
3582
+ case "Polygon" || "MultiPolygon":
3583
+ pseudoFeature = new ol.Feature( {
3584
+ geometry: new ol.geom.Polygon( [ [ [ -10, -7 ], [ 10, -7 ],
3585
+ [ 10, 7 ], [ -10, 7 ] ] ] )
3586
+ } );
3587
+ style = getPolygonStyle( {
3588
+ fill: new ol.style.Fill( {
3589
+ color: fillColor
3590
+ } ),
3591
+ stroke: new ol.style.Stroke( {
3592
+ color: strokeColor,
3593
+ width: strokeWidth,
3594
+ lineDash: strokeDash
3595
+ } )
3596
+ } );
3597
+ pseudoFeature.setStyle( style );
3598
+ break;
3599
+ case "Point" || "MultiPoint":
3600
+ pseudoFeature = new ol.Feature( {
3601
+ geometry: new ol.geom.Point( [ 0, 0 ] )
3602
+ } );
3603
+ if ( graphicName ) {
3604
+ style = getSymbolStyle( {
3605
+ symbol: graphicName,
3606
+ fill: new ol.style.Fill( { color: fillColor } ),
3607
+ stroke: new ol.style.Stroke( { color: strokeColor, lineDash: strokeDash } ),
3608
+ radius: radius
3609
+ } );
3610
+ } else if ( externalGraphic ) {
3611
+ style = getIconStyle( {
3612
+ src: externalGraphic,
3613
+ opacity: opacity,
3614
+ size: [ graphicWidth, graphicHeight ]
3615
+ } );
3616
+ } else {
3617
+ style = getPointStyle( {
3618
+ radius: radius,
3619
+ fill: new ol.style.Fill( { color: fillColor } ),
3620
+ stroke: new ol.style.Stroke( { color: strokeColor, width: strokeWidth, lineDash: strokeDash } )
3621
+ } );
3622
+ }
3623
+ pseudoFeature.setStyle( style );
3624
+ break;
3625
+ case "LineString" || "MultiLineString":
3626
+ pseudoFeature = new ol.Feature( {
3627
+ geometry: new ol.geom.LineString( [ [ -9, -4 ], [ -4, 4 ], [ 4, -4 ], [ 9, 4 ] ] )
3628
+ } );
3629
+ style = getLineStyle( {
3630
+ stroke: new ol.style.Stroke( {
3631
+ color: strokeColor,
3632
+ width: strokeWidth,
3633
+ lineDash: strokeDash
3634
+ } )
3635
+ } );
3636
+ pseudoFeature.setStyle( style );
3637
+ break;
3638
+ default:
3639
+ pseudoFeature = new ol.Feature( {
3640
+ geometry: new ol.geom.Polygon( [ [ [ -10, -7 ], [ 10, -7 ], [ 10, 7 ], [ -10, 7 ] ] ] )
3641
+ } );
3642
+ style = getPolygonStyle( {
3643
+ fill: new ol.style.Fill( {
3644
+ color: fillColor
3645
+ } ),
3646
+ stroke: new ol.style.Stroke( {
3647
+ color: strokeColor,
3648
+ width: strokeWidth,
3649
+ lineDash: strokeDash
3650
+ } )
3651
+ } );
3652
+ pseudoFeature.setStyle( style );
3653
+ break;
3654
+ }
3655
+
3656
+ // create a map for the symbol
3657
+ rendererMap = new ol.Map( {
3658
+ controls: [],
3659
+ interactions: [],
3660
+ layers: [ new ol.layer.Vector( {
3661
+ source: new ol.source.Vector()
3662
+ } ) ]
3663
+ } );
3664
+
3665
+ if ( rendererMap ) {
3666
+ this.symbolMapArray.push( rendererMap );
3667
+ source = rendererMap.getLayers().item( 0 ).getSource();
3668
+ source.clear();
3669
+ source.addFeature( pseudoFeature );
3670
+ }
3671
+
3672
+ rendererMap.setTarget( id );
3673
+ setRendererDimensions( id, rendererMap, pseudoFeature, width, height );
3674
+
3675
+ };
3676
+
3677
+ /**
3678
+ * Refresh the legend symbols
3679
+ */
3680
+ MapLegend.prototype.refresh = function() {
3681
+
3682
+ if ( this.symbolMapArray.length !== 0 ) {
3683
+ var len, map;
3684
+ for ( len = this.symbolMapArray.length - 1; len !== -1; len -= 1 ) {
3685
+ map = this.symbolMapArray[ len ];
3686
+ if ( $( "#" + map.getTarget() ).is( ":visible" ) ) {
3687
+ map.updateSize();
3688
+ }
3689
+ }
3690
+ }
3691
+
3692
+ };
3693
+
3694
+ ol.inherits( GeolocationControl, ol.control.Control );
3695
+ ol.inherits( HelpControl, ol.control.Control );
3696
+ ol.inherits( GeocodeControl, ol.control.Control );
3697
+
3698
+
3699
+ /**
3700
+ * Event Geomap filter
3701
+ *
3702
+ * Apply AOI and Layer filter
3703
+ * - only the <select> element is currently supported
3704
+ *
3705
+ */
3706
+ wb.doc.on( "submit", ".wb-geomap-filter", function( event ) {
3707
+
3708
+ event.preventDefault();
3709
+
3710
+ var $form = $( this ),
3711
+ map = document.getElementById( $form.data( "bind-to" ) ).geomap;
3712
+
3713
+ // Loops though the form group
3714
+ $form.find( "select[data-filter]" ).each( function() {
3715
+ var $elm = $( this ),
3716
+ $optSelected = $elm.find( "option:selected" ),
3717
+ value = $optSelected.val(),
3718
+ tpFilter = $elm.attr( "data-filter" ); // "layer || aoi"
3719
+
3720
+ // if aoi => There will be 4 coordinate space separated (Sequence: N E S W)
3721
+ if ( tpFilter === "aoi" ) {
3722
+ map.zoomAOI( value );
3723
+ }
3724
+
3725
+ // if layer => The layer name
3726
+ if ( tpFilter === "layer" ) {
3727
+ map.showLayer( value, true );
3728
+ }
3729
+ } );
3730
+ } );
3731
+
3732
+ /*
3733
+ * Reset the view on the map and manually reset the layer filter
3734
+ *
3735
+ */
3736
+ wb.doc.on( "click", ".wb-geomap-filter [type=reset]", function( ) {
3737
+
3738
+ var $form = $( this.form ),
3739
+ geomap = document.getElementById( $form.data( "bind-to" ) ).geomap,
3740
+ OLmap = geomap.map,
3741
+ mapGetView = OLmap.getView();
3742
+
3743
+ OLmap.getView().fit( mapGetView.calculateExtent( OLmap.getSize() ), OLmap.getSize() );
3744
+
3745
+ $form.find( "select[data-filter=layer] option" ).each( function() {
3746
+ if ( this.defaultSelected ) {
3747
+ geomap.showLayer( this.value, true );
3748
+ }
3749
+ } );
3750
+ $form.find( "select[data-filter=aoi] option" ).each( function() {
3751
+ if ( this.defaultSelected ) {
3752
+ geomap.zoomAOI( this.value );
3753
+ }
3754
+ } );
3755
+ } );
3756
+
3757
+
3758
+ } )( jQuery, window, document, wb );