gis_data_editor.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  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 received via AJAX.
  20. */
  21. function prepareJSVersion () {
  22. // Change the text on the submit button
  23. $('#gis_editor').find('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').find('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. PMA_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) {
  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/vendor/jquery/jquery.svg.js',
  88. 'js/vendor/jquery/jquery.mousewheel.js',
  89. 'js/vendor/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);
  104. }
  105. };
  106. script.onload = function () {
  107. loadGISEditor(value, field, type, input_name);
  108. };
  109. script.onerror = function () {
  110. loadGISEditor(value, field, type, input_name);
  111. };
  112. script.src = 'js/vendor/openlayers/OpenLayers.js';
  113. head.appendChild(script);
  114. gisEditorLoaded = true;
  115. }
  116. /**
  117. * Loads the GIS editor via AJAX
  118. *
  119. * @param value current value of the geometry field
  120. * @param field field name
  121. * @param type geometry type
  122. * @param input_name name of the input field
  123. */
  124. function loadGISEditor (value, field, type, input_name) {
  125. var $gis_editor = $('#gis_editor');
  126. $.post('gis_data_editor.php', {
  127. 'field' : field,
  128. 'value' : value,
  129. 'type' : type,
  130. 'input_name' : input_name,
  131. 'get_gis_editor' : true,
  132. 'ajax_request': true,
  133. 'server': PMA_commonParams.get('server')
  134. }, function (data) {
  135. if (typeof data !== 'undefined' && data.success === true) {
  136. $gis_editor.html(data.gis_editor);
  137. initGISEditorVisualization();
  138. prepareJSVersion();
  139. } else {
  140. PMA_ajaxShowMessage(data.error, false);
  141. }
  142. }, 'json');
  143. }
  144. /**
  145. * Opens up the dialog for the GIS data editor.
  146. */
  147. function openGISEditor () {
  148. // Center the popup
  149. var windowWidth = document.documentElement.clientWidth;
  150. var windowHeight = document.documentElement.clientHeight;
  151. var popupWidth = windowWidth * 0.9;
  152. var popupHeight = windowHeight * 0.9;
  153. var popupOffsetTop = windowHeight / 2 - popupHeight / 2;
  154. var popupOffsetLeft = windowWidth / 2 - popupWidth / 2;
  155. var $gis_editor = $('#gis_editor');
  156. var $backgrouond = $('#popup_background');
  157. $gis_editor.css({ 'top': popupOffsetTop, 'left': popupOffsetLeft, 'width': popupWidth, 'height': popupHeight });
  158. $backgrouond.css({ 'opacity' : '0.7' });
  159. $gis_editor.append(
  160. '<div id="gis_data_editor">' +
  161. '<img class="ajaxIcon" id="loadingMonitorIcon" src="' +
  162. pmaThemeImage + 'ajax_clock_small.gif" alt=""/>' +
  163. '</div>'
  164. );
  165. // Make it appear
  166. $backgrouond.fadeIn('fast');
  167. $gis_editor.fadeIn('fast');
  168. }
  169. /**
  170. * Prepare and insert the GIS data in Well Known Text format
  171. * to the input field.
  172. */
  173. function insertDataAndClose () {
  174. var $form = $('form#gis_data_editor_form');
  175. var input_name = $form.find('input[name=\'input_name\']').val();
  176. var argsep = PMA_commonParams.get('arg_separator');
  177. $.post('gis_data_editor.php', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) {
  178. if (typeof data !== 'undefined' && data.success === true) {
  179. $('input[name=\'' + input_name + '\']').val(data.result);
  180. } else {
  181. PMA_ajaxShowMessage(data.error, false);
  182. }
  183. }, 'json');
  184. closeGISEditor();
  185. }
  186. /**
  187. * Unbind all event handlers before tearing down a page
  188. */
  189. AJAX.registerTeardown('gis_data_editor.js', function () {
  190. $(document).off('click', '#gis_editor input[name=\'gis_data[save]\']');
  191. $(document).off('submit', '#gis_editor');
  192. $(document).off('change', '#gis_editor input[type=\'text\']');
  193. $(document).off('change', '#gis_editor select.gis_type');
  194. $(document).off('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor');
  195. $(document).off('click', '#gis_editor a.addJs.addPoint');
  196. $(document).off('click', '#gis_editor a.addLine.addJs');
  197. $(document).off('click', '#gis_editor a.addJs.addPolygon');
  198. $(document).off('click', '#gis_editor a.addJs.addGeom');
  199. });
  200. AJAX.registerOnload('gis_data_editor.js', function () {
  201. /**
  202. * Prepares and insert the GIS data to the input field on clicking 'copy'.
  203. */
  204. $(document).on('click', '#gis_editor input[name=\'gis_data[save]\']', function (event) {
  205. event.preventDefault();
  206. insertDataAndClose();
  207. });
  208. /**
  209. * Prepares and insert the GIS data to the input field on pressing 'enter'.
  210. */
  211. $(document).on('submit', '#gis_editor', function (event) {
  212. event.preventDefault();
  213. insertDataAndClose();
  214. });
  215. /**
  216. * Trigger asynchronous calls on data change and update the output.
  217. */
  218. $(document).on('change', '#gis_editor input[type=\'text\']', function () {
  219. var $form = $('form#gis_data_editor_form');
  220. var argsep = PMA_commonParams.get('arg_separator');
  221. $.post('gis_data_editor.php', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) {
  222. if (typeof data !== 'undefined' && data.success === true) {
  223. $('#gis_data_textarea').val(data.result);
  224. $('#placeholder').empty().removeClass('hasSVG').html(data.visualization);
  225. $('#openlayersmap').empty();
  226. /* TODO: the gis_data_editor should rather return JSON than JS code to eval */
  227. eval(data.openLayers);
  228. initGISEditorVisualization();
  229. } else {
  230. PMA_ajaxShowMessage(data.error, false);
  231. }
  232. }, 'json');
  233. });
  234. /**
  235. * Update the form on change of the GIS type.
  236. */
  237. $(document).on('change', '#gis_editor select.gis_type', function (event) {
  238. var $gis_editor = $('#gis_editor');
  239. var $form = $('form#gis_data_editor_form');
  240. var argsep = PMA_commonParams.get('arg_separator');
  241. $.post('gis_data_editor.php', $form.serialize() + argsep + 'get_gis_editor=true' + argsep + 'ajax_request=true', function (data) {
  242. if (typeof data !== 'undefined' && data.success === true) {
  243. $gis_editor.html(data.gis_editor);
  244. initGISEditorVisualization();
  245. prepareJSVersion();
  246. } else {
  247. PMA_ajaxShowMessage(data.error, false);
  248. }
  249. }, 'json');
  250. });
  251. /**
  252. * Handles closing of the GIS data editor.
  253. */
  254. $(document).on('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor', function () {
  255. closeGISEditor();
  256. });
  257. /**
  258. * Handles adding data points
  259. */
  260. $(document).on('click', '#gis_editor a.addJs.addPoint', function () {
  261. var $a = $(this);
  262. var name = $a.attr('name');
  263. // Eg. name = gis_data[0][MULTIPOINT][add_point] => prefix = gis_data[0][MULTIPOINT]
  264. var prefix = name.substr(0, name.length - 11);
  265. // Find the number of points
  266. var $noOfPointsInput = $('input[name=\'' + prefix + '[no_of_points]' + '\']');
  267. var noOfPoints = parseInt($noOfPointsInput.val(), 10);
  268. // Add the new data point
  269. var html = addDataPoint(noOfPoints, prefix);
  270. $a.before(html);
  271. $noOfPointsInput.val(noOfPoints + 1);
  272. });
  273. /**
  274. * Handles adding linestrings and inner rings
  275. */
  276. $(document).on('click', '#gis_editor a.addLine.addJs', function () {
  277. var $a = $(this);
  278. var name = $a.attr('name');
  279. // Eg. name = gis_data[0][MULTILINESTRING][add_line] => prefix = gis_data[0][MULTILINESTRING]
  280. var prefix = name.substr(0, name.length - 10);
  281. var type = prefix.slice(prefix.lastIndexOf('[') + 1, prefix.lastIndexOf(']'));
  282. // Find the number of lines
  283. var $noOfLinesInput = $('input[name=\'' + prefix + '[no_of_lines]' + '\']');
  284. var noOfLines = parseInt($noOfLinesInput.val(), 10);
  285. // Add the new linesting of inner ring based on the type
  286. var html = '<br/>';
  287. var noOfPoints;
  288. if (type === 'MULTILINESTRING') {
  289. html += PMA_messages.strLineString + ' ' + (noOfLines + 1) + ':';
  290. noOfPoints = 2;
  291. } else {
  292. html += PMA_messages.strInnerRing + ' ' + noOfLines + ':';
  293. noOfPoints = 4;
  294. }
  295. html += '<input type="hidden" name="' + prefix + '[' + noOfLines + '][no_of_points]" value="' + noOfPoints + '"/>';
  296. for (var i = 0; i < noOfPoints; i++) {
  297. html += addDataPoint(i, (prefix + '[' + noOfLines + ']'));
  298. }
  299. html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfLines + '][add_point]" href="#">+ ' +
  300. PMA_messages.strAddPoint + '</a><br/>';
  301. $a.before(html);
  302. $noOfLinesInput.val(noOfLines + 1);
  303. });
  304. /**
  305. * Handles adding polygons
  306. */
  307. $(document).on('click', '#gis_editor a.addJs.addPolygon', function () {
  308. var $a = $(this);
  309. var name = $a.attr('name');
  310. // Eg. name = gis_data[0][MULTIPOLYGON][add_polygon] => prefix = gis_data[0][MULTIPOLYGON]
  311. var prefix = name.substr(0, name.length - 13);
  312. // Find the number of polygons
  313. var $noOfPolygonsInput = $('input[name=\'' + prefix + '[no_of_polygons]' + '\']');
  314. var noOfPolygons = parseInt($noOfPolygonsInput.val(), 10);
  315. // Add the new polygon
  316. var html = PMA_messages.strPolygon + ' ' + (noOfPolygons + 1) + ':<br/>';
  317. html += '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][no_of_lines]" value="1"/>' +
  318. '<br/>' + PMA_messages.strOuterRing + ':' +
  319. '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][0][no_of_points]" value="4"/>';
  320. for (var i = 0; i < 4; i++) {
  321. html += addDataPoint(i, (prefix + '[' + noOfPolygons + '][0]'));
  322. }
  323. html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfPolygons + '][0][add_point]" href="#">+ ' +
  324. PMA_messages.strAddPoint + '</a><br/>' +
  325. '<a class="addLine addJs" name="' + prefix + '[' + noOfPolygons + '][add_line]" href="#">+ ' +
  326. PMA_messages.strAddInnerRing + '</a><br/><br/>';
  327. $a.before(html);
  328. $noOfPolygonsInput.val(noOfPolygons + 1);
  329. });
  330. /**
  331. * Handles adding geoms
  332. */
  333. $(document).on('click', '#gis_editor a.addJs.addGeom', function () {
  334. var $a = $(this);
  335. var prefix = 'gis_data[GEOMETRYCOLLECTION]';
  336. // Find the number of geoms
  337. var $noOfGeomsInput = $('input[name=\'' + prefix + '[geom_count]' + '\']');
  338. var noOfGeoms = parseInt($noOfGeomsInput.val(), 10);
  339. var html1 = PMA_messages.strGeometry + ' ' + (noOfGeoms + 1) + ':<br/>';
  340. var $geomType = $('select[name=\'gis_data[' + (noOfGeoms - 1) + '][gis_type]\']').clone();
  341. $geomType.attr('name', 'gis_data[' + noOfGeoms + '][gis_type]').val('POINT');
  342. var html2 = '<br/>' + PMA_messages.strPoint + ' :' +
  343. '<label for="x"> ' + PMA_messages.strX + ' </label>' +
  344. '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][x]" value=""/>' +
  345. '<label for="y"> ' + PMA_messages.strY + ' </label>' +
  346. '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][y]" value=""/>' +
  347. '<br/><br/>';
  348. $a.before(html1);
  349. $geomType.insertBefore($a);
  350. $a.before(html2);
  351. $noOfGeomsInput.val(noOfGeoms + 1);
  352. });
  353. });