gis_data_editor.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /* vim: set expandtab sw=4 ts=4 sts=4: */
  2. /**
  3. * @fileoverview functions used in GIS data editor
  4. *
  5. * @requires jQuery
  6. *
  7. */
  8. var gisEditorLoaded = false;
  9. /**
  10. * Closes the GIS data editor and perform necessary clean up work.
  11. */
  12. function closeGISEditor() {
  13. $("#popup_background").fadeOut("fast");
  14. $("#gis_editor").fadeOut("fast", function () {
  15. $(this).empty();
  16. });
  17. }
  18. /**
  19. * Prepares the HTML recieved via AJAX.
  20. */
  21. function prepareJSVersion() {
  22. // Change the text on the submit button
  23. $("#gis_editor input[name='gis_data[save]']")
  24. .val(PMA_messages.strCopy)
  25. .insertAfter($('#gis_data_textarea'))
  26. .before('<br/><br/>');
  27. // Add close and cancel links
  28. $('#gis_data_editor').prepend('<a class="close_gis_editor" href="#">' + PMA_messages.strClose + '</a>');
  29. $('<a class="cancel_gis_editor" href="#"> ' + PMA_messages.strCancel + '</a>')
  30. .insertAfter($("input[name='gis_data[save]']"));
  31. // Remove the unnecessary text
  32. $('div#gis_data_output p').remove();
  33. // Remove 'add' buttons and add links
  34. $('#gis_editor input.add').each(function (e) {
  35. var $button = $(this);
  36. $button.addClass('addJs').removeClass('add');
  37. var classes = $button.attr('class');
  38. $button.replaceWith(
  39. '<a class="' + classes +
  40. '" name="' + $button.attr('name') +
  41. '" href="#">+ ' + $button.val() + '</a>'
  42. );
  43. });
  44. }
  45. /**
  46. * Returns the HTML for a data point.
  47. *
  48. * @param pointNumber point number
  49. * @param prefix prefix of the name
  50. * @returns the HTML for a data point
  51. */
  52. function addDataPoint(pointNumber, prefix) {
  53. return '<br/>' +
  54. $.sprintf(PMA_messages.strPointN, (pointNumber + 1)) + ': ' +
  55. '<label for="x">' + PMA_messages.strX + '</label>' +
  56. '<input type="text" name="' + prefix + '[' + pointNumber + '][x]" value=""/>' +
  57. '<label for="y">' + PMA_messages.strY + '</label>' +
  58. '<input type="text" name="' + prefix + '[' + pointNumber + '][y]" value=""/>';
  59. }
  60. /**
  61. * Initialize the visualization in the GIS data editor.
  62. */
  63. function initGISEditorVisualization() {
  64. // Loads either SVG or OSM visualization based on the choice
  65. selectVisualization();
  66. // Adds necessary styles to the div that coontains the openStreetMap
  67. styleOSM();
  68. // Loads the SVG element and make a reference to it
  69. loadSVG();
  70. // Adds controllers for zooming and panning
  71. addZoomPanControllers();
  72. zoomAndPan();
  73. }
  74. /**
  75. * Loads JavaScript files and the GIS editor.
  76. *
  77. * @param value current value of the geometry field
  78. * @param field field name
  79. * @param type geometry type
  80. * @param input_name name of the input field
  81. * @param token token
  82. */
  83. function loadJSAndGISEditor(value, field, type, input_name, token) {
  84. var head = document.getElementsByTagName('head')[0];
  85. var script;
  86. // Loads a set of small JS file needed for the GIS editor
  87. var smallScripts = [ 'js/jquery/jquery.svg.js',
  88. 'js/jquery/jquery.mousewheel.js',
  89. 'js/jquery/jquery.event.drag-2.2.js',
  90. 'js/tbl_gis_visualization.js' ];
  91. for (var i = 0; i < smallScripts.length; i++) {
  92. script = document.createElement('script');
  93. script.type = 'text/javascript';
  94. script.src = smallScripts[i];
  95. head.appendChild(script);
  96. }
  97. // OpenLayers.js is BIG and takes time. So asynchronous loading would not work.
  98. // Load the JS and do a callback to load the content for the GIS Editor.
  99. script = document.createElement('script');
  100. script.type = 'text/javascript';
  101. script.onreadystatechange = function () {
  102. if (this.readyState == 'complete') {
  103. loadGISEditor(value, field, type, input_name, token);
  104. }
  105. };
  106. script.onload = function () {
  107. loadGISEditor(value, field, type, input_name, token);
  108. };
  109. script.src = 'js/openlayers/OpenLayers.js';
  110. head.appendChild(script);
  111. gisEditorLoaded = true;
  112. }
  113. /**
  114. * Loads the GIS editor via AJAX
  115. *
  116. * @param value current value of the geometry field
  117. * @param field field name
  118. * @param type geometry type
  119. * @param input_name name of the input field
  120. * @param token token
  121. */
  122. function loadGISEditor(value, field, type, input_name, token) {
  123. var $gis_editor = $("#gis_editor");
  124. $.post('gis_data_editor.php', {
  125. 'field' : field,
  126. 'value' : value,
  127. 'type' : type,
  128. 'input_name' : input_name,
  129. 'get_gis_editor' : true,
  130. 'token' : token,
  131. 'ajax_request': true
  132. }, function (data) {
  133. if (data.success === true) {
  134. $gis_editor.html(data.gis_editor);
  135. initGISEditorVisualization();
  136. prepareJSVersion();
  137. } else {
  138. PMA_ajaxShowMessage(data.error, false);
  139. }
  140. }, 'json');
  141. }
  142. /**
  143. * Opens up the dialog for the GIS data editor.
  144. */
  145. function openGISEditor() {
  146. // Center the popup
  147. var windowWidth = document.documentElement.clientWidth;
  148. var windowHeight = document.documentElement.clientHeight;
  149. var popupWidth = windowWidth * 0.9;
  150. var popupHeight = windowHeight * 0.9;
  151. var popupOffsetTop = windowHeight / 2 - popupHeight / 2;
  152. var popupOffsetLeft = windowWidth / 2 - popupWidth / 2;
  153. var $gis_editor = $("#gis_editor");
  154. var $backgrouond = $("#popup_background");
  155. $gis_editor.css({"top": popupOffsetTop, "left": popupOffsetLeft, "width": popupWidth, "height": popupHeight});
  156. $backgrouond.css({"opacity" : "0.7"});
  157. $gis_editor.append(
  158. '<div id="gis_data_editor">' +
  159. '<img class="ajaxIcon" id="loadingMonitorIcon" src="' +
  160. pmaThemeImage + 'ajax_clock_small.gif" alt=""/>' +
  161. '</div>'
  162. );
  163. // Make it appear
  164. $backgrouond.fadeIn("fast");
  165. $gis_editor.fadeIn("fast");
  166. }
  167. /**
  168. * Prepare and insert the GIS data in Well Known Text format
  169. * to the input field.
  170. */
  171. function insertDataAndClose() {
  172. var $form = $('form#gis_data_editor_form');
  173. var input_name = $form.find("input[name='input_name']").val();
  174. $.post('gis_data_editor.php', $form.serialize() + "&generate=true&ajax_request=true", function (data) {
  175. if (data.success === true) {
  176. $("input[name='" + input_name + "']").val(data.result);
  177. } else {
  178. PMA_ajaxShowMessage(data.error, false);
  179. }
  180. }, 'json');
  181. closeGISEditor();
  182. }
  183. /**
  184. * Unbind all event handlers before tearing down a page
  185. */
  186. AJAX.registerTeardown('gis_data_editor.js', function () {
  187. $("#gis_editor input[name='gis_data[save]']").die('click');
  188. $('#gis_editor').die('submit');
  189. $('#gis_editor').find("input[type='text']").die('change');
  190. $("#gis_editor select.gis_type").die('change');
  191. $('#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor').die('click');
  192. $('#gis_editor a.addJs.addPoint').die('click');
  193. $('#gis_editor a.addLine.addJs').die('click');
  194. $('#gis_editor a.addJs.addPolygon').die('click');
  195. $('#gis_editor a.addJs.addGeom').die('click');
  196. });
  197. AJAX.registerOnload('gis_data_editor.js', function () {
  198. // Remove the class that is added due to the URL being too long.
  199. $('span.open_gis_editor a').removeClass('formLinkSubmit');
  200. /**
  201. * Prepares and insert the GIS data to the input field on clicking 'copy'.
  202. */
  203. $("#gis_editor input[name='gis_data[save]']").live('click', function (event) {
  204. event.preventDefault();
  205. insertDataAndClose();
  206. });
  207. /**
  208. * Prepares and insert the GIS data to the input field on pressing 'enter'.
  209. */
  210. $('#gis_editor').live('submit', function (event) {
  211. event.preventDefault();
  212. insertDataAndClose();
  213. });
  214. /**
  215. * Trigger asynchronous calls on data change and update the output.
  216. */
  217. $('#gis_editor').find("input[type='text']").live('change', function () {
  218. var $form = $('form#gis_data_editor_form');
  219. $.post('gis_data_editor.php', $form.serialize() + "&generate=true&ajax_request=true", function (data) {
  220. if (data.success === true) {
  221. $('#gis_data_textarea').val(data.result);
  222. $('#placeholder').empty().removeClass('hasSVG').html(data.visualization);
  223. $('#openlayersmap').empty();
  224. /* TODO: the gis_data_editor should rather return JSON than JS code to eval */
  225. eval(data.openLayers);
  226. initGISEditorVisualization();
  227. } else {
  228. PMA_ajaxShowMessage(data.error, false);
  229. }
  230. }, 'json');
  231. });
  232. /**
  233. * Update the form on change of the GIS type.
  234. */
  235. $("#gis_editor select.gis_type").live('change', function (event) {
  236. var $gis_editor = $("#gis_editor");
  237. var $form = $('form#gis_data_editor_form');
  238. $.post('gis_data_editor.php', $form.serialize() + "&get_gis_editor=true&ajax_request=true", function (data) {
  239. if (data.success === true) {
  240. $gis_editor.html(data.gis_editor);
  241. initGISEditorVisualization();
  242. prepareJSVersion();
  243. } else {
  244. PMA_ajaxShowMessage(data.error, false);
  245. }
  246. }, 'json');
  247. });
  248. /**
  249. * Handles closing of the GIS data editor.
  250. */
  251. $('#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor').live('click', function () {
  252. closeGISEditor();
  253. });
  254. /**
  255. * Handles adding data points
  256. */
  257. $('#gis_editor a.addJs.addPoint').live('click', function () {
  258. var $a = $(this);
  259. var name = $a.attr('name');
  260. // Eg. name = gis_data[0][MULTIPOINT][add_point] => prefix = gis_data[0][MULTIPOINT]
  261. var prefix = name.substr(0, name.length - 11);
  262. // Find the number of points
  263. var $noOfPointsInput = $("input[name='" + prefix + "[no_of_points]" + "']");
  264. var noOfPoints = parseInt($noOfPointsInput.val(), 10);
  265. // Add the new data point
  266. var html = addDataPoint(noOfPoints, prefix);
  267. $a.before(html);
  268. $noOfPointsInput.val(noOfPoints + 1);
  269. });
  270. /**
  271. * Handles adding linestrings and inner rings
  272. */
  273. $('#gis_editor a.addLine.addJs').live('click', function () {
  274. var $a = $(this);
  275. var name = $a.attr('name');
  276. // Eg. name = gis_data[0][MULTILINESTRING][add_line] => prefix = gis_data[0][MULTILINESTRING]
  277. var prefix = name.substr(0, name.length - 10);
  278. var type = prefix.slice(prefix.lastIndexOf('[') + 1, prefix.lastIndexOf(']'));
  279. // Find the number of lines
  280. var $noOfLinesInput = $("input[name='" + prefix + "[no_of_lines]" + "']");
  281. var noOfLines = parseInt($noOfLinesInput.val(), 10);
  282. // Add the new linesting of inner ring based on the type
  283. var html = '<br/>';
  284. var noOfPoints;
  285. if (type == 'MULTILINESTRING') {
  286. html += PMA_messages.strLineString + ' ' + (noOfLines + 1) + ':';
  287. noOfPoints = 2;
  288. } else {
  289. html += PMA_messages.strInnerRing + ' ' + noOfLines + ':';
  290. noOfPoints = 4;
  291. }
  292. html += '<input type="hidden" name="' + prefix + '[' + noOfLines + '][no_of_points]" value="' + noOfPoints + '"/>';
  293. for (var i = 0; i < noOfPoints; i++) {
  294. html += addDataPoint(i, (prefix + '[' + noOfLines + ']'));
  295. }
  296. html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfLines + '][add_point]" href="#">+ ' +
  297. PMA_messages.strAddPoint + '</a><br/>';
  298. $a.before(html);
  299. $noOfLinesInput.val(noOfLines + 1);
  300. });
  301. /**
  302. * Handles adding polygons
  303. */
  304. $('#gis_editor a.addJs.addPolygon').live('click', function () {
  305. var $a = $(this);
  306. var name = $a.attr('name');
  307. // Eg. name = gis_data[0][MULTIPOLYGON][add_polygon] => prefix = gis_data[0][MULTIPOLYGON]
  308. var prefix = name.substr(0, name.length - 13);
  309. // Find the number of polygons
  310. var $noOfPolygonsInput = $("input[name='" + prefix + "[no_of_polygons]" + "']");
  311. var noOfPolygons = parseInt($noOfPolygonsInput.val(), 10);
  312. // Add the new polygon
  313. var html = PMA_messages.strPolygon + ' ' + (noOfPolygons + 1) + ':<br/>';
  314. html += '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][no_of_lines]" value="1"/>' +
  315. '<br/>' + PMA_messages.strOuterRing + ':' +
  316. '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][0][no_of_points]" value="4"/>';
  317. for (var i = 0; i < 4; i++) {
  318. html += addDataPoint(i, (prefix + '[' + noOfPolygons + '][0]'));
  319. }
  320. html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfPolygons + '][0][add_point]" href="#">+ ' +
  321. PMA_messages.strAddPoint + '</a><br/>' +
  322. '<a class="addLine addJs" name="' + prefix + '[' + noOfPolygons + '][add_line]" href="#">+ ' +
  323. PMA_messages.strAddInnerRing + '</a><br/><br/>';
  324. $a.before(html);
  325. $noOfPolygonsInput.val(noOfPolygons + 1);
  326. });
  327. /**
  328. * Handles adding geoms
  329. */
  330. $('#gis_editor a.addJs.addGeom').live('click', function () {
  331. var $a = $(this);
  332. var prefix = 'gis_data[GEOMETRYCOLLECTION]';
  333. // Find the number of geoms
  334. var $noOfGeomsInput = $("input[name='" + prefix + "[geom_count]" + "']");
  335. var noOfGeoms = parseInt($noOfGeomsInput.val(), 10);
  336. var html1 = PMA_messages.strGeometry + ' ' + (noOfGeoms + 1) + ':<br/>';
  337. var $geomType = $("select[name='gis_data[" + (noOfGeoms - 1) + "][gis_type]']").clone();
  338. $geomType.attr('name', 'gis_data[' + noOfGeoms + '][gis_type]').val('POINT');
  339. var html2 = '<br/>' + PMA_messages.strPoint + ' :' +
  340. '<label for="x"> ' + PMA_messages.strX + ' </label>' +
  341. '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][x]" value=""/>' +
  342. '<label for="y"> ' + PMA_messages.strY + ' </label>' +
  343. '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][y]" value=""/>' +
  344. '<br/><br/>';
  345. $a.before(html1);
  346. $geomType.insertBefore($a);
  347. $a.before(html2);
  348. $noOfGeomsInput.val(noOfGeoms + 1);
  349. });
  350. });