gis_data_editor.js 14 KB

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