c80_map_floors 0.1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.travis.yml +3 -0
  4. data/CODE_OF_CONDUCT.md +13 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +67 -0
  8. data/Rakefile +1 -0
  9. data/app/admin/c80_map_floors/floors.rb +57 -0
  10. data/app/admin/c80_map_floors/map_buildings.rb +49 -0
  11. data/app/admin/c80_map_floors/settings.rb +32 -0
  12. data/app/assets/javascripts/buttons/admin_buttons/button_area_link.js +91 -0
  13. data/app/assets/javascripts/buttons/admin_buttons/button_building_link.js +91 -0
  14. data/app/assets/javascripts/buttons/admin_buttons/button_cancel_create.js +21 -0
  15. data/app/assets/javascripts/buttons/admin_buttons/button_cancel_remove.js +23 -0
  16. data/app/assets/javascripts/buttons/admin_buttons/button_complete_create.js +22 -0
  17. data/app/assets/javascripts/buttons/admin_buttons/button_edit.js +96 -0
  18. data/app/assets/javascripts/buttons/admin_buttons/button_new.js +46 -0
  19. data/app/assets/javascripts/buttons/admin_buttons/button_remove.js +23 -0
  20. data/app/assets/javascripts/buttons/admin_buttons/button_save.js +111 -0
  21. data/app/assets/javascripts/buttons/button_back_to_map.js +84 -0
  22. data/app/assets/javascripts/buttons/zoom_buttons.js +78 -0
  23. data/app/assets/javascripts/c80_map_floors.js.coffee +23 -0
  24. data/app/assets/javascripts/events/app_event.js +15 -0
  25. data/app/assets/javascripts/map_objects/area.js +251 -0
  26. data/app/assets/javascripts/map_objects/building.js +294 -0
  27. data/app/assets/javascripts/map_objects/dot.js +14 -0
  28. data/app/assets/javascripts/map_objects/floor.js +10 -0
  29. data/app/assets/javascripts/src/main.js +1421 -0
  30. data/app/assets/javascripts/src/state_controller.js +322 -0
  31. data/app/assets/javascripts/src/utils/map_utils.js +23 -0
  32. data/app/assets/javascripts/src/utils/opacity_buttons_utils.js +15 -0
  33. data/app/assets/javascripts/src/utils/utils.js +140 -0
  34. data/app/assets/javascripts/svg_elements/area_label.js +25 -0
  35. data/app/assets/javascripts/svg_elements/building_label.js +65 -0
  36. data/app/assets/javascripts/svg_elements/helper.js +36 -0
  37. data/app/assets/javascripts/svg_elements/polygon.js +194 -0
  38. data/app/assets/javascripts/view/save_preloader.js +30 -0
  39. data/app/assets/stylesheets/c80_map_floors.scss +4 -0
  40. data/app/assets/stylesheets/map.scss +1464 -0
  41. data/app/assets/stylesheets/view/buttons/area_order_button.scss +16 -0
  42. data/app/assets/stylesheets/view/buttons/back_to_map_button.scss +28 -0
  43. data/app/assets/stylesheets/view/elems/building_info.scss +54 -0
  44. data/app/assets/stylesheets/view/elems/free_areas_label.scss +116 -0
  45. data/app/assets/stylesheets/view/elems/map_objects/map_object_image_bg.scss +10 -0
  46. data/app/assets/stylesheets/view/modal_window.scss +13 -0
  47. data/app/assets/stylesheets/view/save_preloader.scss +206 -0
  48. data/app/controllers/c80_map_floors/ajax_controller.rb +65 -0
  49. data/app/controllers/c80_map_floors/application_controller.rb +6 -0
  50. data/app/controllers/c80_map_floors/map_ajax_controller.rb +70 -0
  51. data/app/helpers/c80_map_floors/application_helper.rb +28 -0
  52. data/app/models/c80_map_floors/area.rb +20 -0
  53. data/app/models/c80_map_floors/area_representator.rb +75 -0
  54. data/app/models/c80_map_floors/base_map_object.rb +41 -0
  55. data/app/models/c80_map_floors/building_representator.rb +72 -0
  56. data/app/models/c80_map_floors/floor.rb +37 -0
  57. data/app/models/c80_map_floors/map_building.rb +45 -0
  58. data/app/models/c80_map_floors/map_json.rb +35 -0
  59. data/app/models/c80_map_floors/setting.rb +32 -0
  60. data/app/uploaders/c80_map_floors/building_image_uploader.rb +31 -0
  61. data/app/uploaders/c80_map_floors/floor_image_uploader.rb +33 -0
  62. data/app/uploaders/c80_map_floors/map_image_uploader.rb +31 -0
  63. data/app/views/c80_map_floors/_map_row_index.html.erb +40 -0
  64. data/app/views/c80_map_floors/ajax/fetch_unlinked_areas.js.erb +7 -0
  65. data/app/views/c80_map_floors/ajax/fetch_unlinked_buildings.js.erb +7 -0
  66. data/app/views/c80_map_floors/ajax/map_edit_buttons.js.erb +36 -0
  67. data/app/views/c80_map_floors/ajax/shared/_map_creating.html.erb +6 -0
  68. data/app/views/c80_map_floors/ajax/shared/_map_editing.html.erb +4 -0
  69. data/app/views/c80_map_floors/ajax/shared/_map_removing.html.erb +5 -0
  70. data/app/views/c80_map_floors/ajax/shared/_select_list_unlinked_areas.html.erb +6 -0
  71. data/app/views/c80_map_floors/ajax/shared/_select_list_unlinked_buildings.html.erb +10 -0
  72. data/app/views/c80_map_floors/shared/_modal_window.html.erb +28 -0
  73. data/app/views/c80_map_floors/shared/_save_preloader.html.erb +3 -0
  74. data/app/views/c80_map_floors/shared/map_row/_area_order_button.html.erb +7 -0
  75. data/app/views/c80_map_floors/shared/map_row/_building_info.html.erb +17 -0
  76. data/bin/console +14 -0
  77. data/bin/setup +7 -0
  78. data/c80_map_floors.gemspec +28 -0
  79. data/config/routes.rb +4 -0
  80. data/db/migrate/20161015190000_create_c80_map_floors_settings.rb +8 -0
  81. data/db/migrate/20161015190001_create_c80_map_floors_map_buildings.rb +10 -0
  82. data/db/migrate/20161015190002_create_c80_map_floors_areas.rb +12 -0
  83. data/db/migrate/20161015190003_add_building_representator_to_c80_map_floors_buildings.rb +6 -0
  84. data/db/migrate/20161015190004_create_c80_map_floors_floors.rb +16 -0
  85. data/db/migrate/20161019111010_add_title_to_c80_map_floors_buildings.rb +5 -0
  86. data/db/migrate/20161020184040_add_coords_img_to_c80_map_floors_buildings.rb +5 -0
  87. data/db/seeds/c80_map_floors_01_fill_map_settings.rb +6 -0
  88. data/db/seeds/c80_map_floors_02_create_test_area.rb +7 -0
  89. data/lib/c80_map_floors.rb +8 -0
  90. data/lib/c80_map_floors/engine.rb +23 -0
  91. data/lib/c80_map_floors/version.rb +3 -0
  92. metadata +218 -0
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ function CancelCreatingButton() {
4
+
5
+ var _map = null;
6
+ var _this = this;
7
+ _this.el = null;
8
+
9
+ this.onClick = function (e) {
10
+ console.log("<CancelCreatingButton.onClick>");
11
+ e.preventDefault();
12
+ _map.setMode("editing");
13
+ };
14
+
15
+ this.init = function (button_css_selector, link_to_map) {
16
+ _map = link_to_map;
17
+ _this.el = $(button_css_selector);
18
+ _this.el.on('click', this.onClick);
19
+ };
20
+
21
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ function CancelRemoveButton() {
4
+
5
+ var _map = null;
6
+ var _this = this;
7
+ _this.el = null;
8
+
9
+ _this.onClick = function (e) {
10
+ if (_this.el.hasClass('disabled')) return;
11
+ e.preventDefault();
12
+
13
+ console.log("<CancelRemoveButton.onClick> Выходим из режима удаления полигона.");
14
+ _map.setMode('editing');
15
+
16
+ };
17
+
18
+ _this.init = function (button_css_selector, link_to_map) {
19
+ _map = link_to_map;
20
+ _this.el = $(button_css_selector);
21
+ _this.el.on('click', _this.onClick);
22
+ };
23
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ function CompleteCreatingButton() {
4
+
5
+ var _map = null;
6
+ var _this = this;
7
+ _this.el = null;
8
+
9
+ _this.onClick = function (e) {
10
+ console.log("<CompleteCreatingButton.onClick>");
11
+ if (e != null) e.preventDefault();
12
+ _map.onDrawStop();
13
+ };
14
+
15
+ _this.init = function (button_css_selector, link_to_map) {
16
+ _map = link_to_map;
17
+ _this.el = $(button_css_selector);
18
+ _this.el.on('click', _this.onClick);
19
+ _map.complete_creating_button_klass = _this;
20
+ };
21
+
22
+ }
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+
3
+ // именно эта кнопка контролирует переходы между состояниями:
4
+ // - viewing, editing;
5
+ // - view_building, edit_building;
6
+ // - view_area, edit_area;
7
+ function EditButton() {
8
+
9
+ var _map = null;
10
+ var _this = this;
11
+ _this.state = 'init'; // editing / viewing
12
+ _this.el = null;
13
+
14
+ // состояние этой кнопки извне меняет приложение,
15
+ // когда входим в здание\площадь (вот тут [a1x7]),
16
+ // и чтобы не происходило бесконечного зацикленного вызова,
17
+ // вводится флаг mark_change_only_inner_state
18
+ this.setState = function (state,mark_change_only_inner_state) {
19
+ if (mark_change_only_inner_state == undefined) {
20
+ mark_change_only_inner_state = false;
21
+ }
22
+ console.log("<EditButton.setState> state = " + state);
23
+
24
+ // этот код коррелирует с [x9cs7]
25
+ _this.state = state;
26
+ _this.el.removeClass('editing');
27
+ _this.el.removeClass('viewing');
28
+ _this.el.removeClass('removing');
29
+ _this.el.removeClass('view_building');
30
+ _this.el.removeClass('edit_building');
31
+ _this.el.removeClass('view_area');
32
+ _this.el.removeClass('edit_area');
33
+ _this.el.addClass(state);
34
+
35
+ if (!mark_change_only_inner_state) {
36
+ _map.setMode(state);
37
+ }
38
+
39
+ };
40
+
41
+ this.onClick = function (e) {
42
+ e.preventDefault();
43
+
44
+ // если после исполнения switch..case эта перменная будет true - значит надо будет вызвать кое-какой код
45
+ var mark_restore_svg_overlay = false;
46
+
47
+ switch (_this.state) {
48
+ case 'editing':
49
+ _this.setState('viewing');
50
+ break;
51
+
52
+ case 'viewing':
53
+ _this.setState('editing');
54
+ break;
55
+
56
+ case 'view_building':
57
+ _this.setState('edit_building');
58
+ break;
59
+
60
+ // находились в режиме редактирования здания, и перешли в режим просмотра здания
61
+ case 'edit_building':
62
+ _this.setState('view_building');
63
+ mark_restore_svg_overlay = true;
64
+ break;
65
+
66
+ case 'view_area':
67
+ _this.setState('edit_area');
68
+ // спрячем от клика мышки все полигоны из svg_overlay, кроме редактируемого полигона
69
+ MapUtils.svgOverlayHideAllExcept(_map.last_clicked_g);
70
+ break;
71
+
72
+ // находились в режиме редактирования площади, и перешли в режим просмотра площади
73
+ case 'edit_area':
74
+ _this.setState('view_area');
75
+ mark_restore_svg_overlay = true;
76
+ break;
77
+
78
+ }
79
+
80
+ // покажем для клика мышкой все полигоны из svg_overlay
81
+ if (mark_restore_svg_overlay) {
82
+ MapUtils.svgOverlayRestore(_map.last_clicked_g);
83
+ _map.last_clicked_g = null;
84
+ }
85
+
86
+ };
87
+
88
+ this.init = function (button_css_selector, link_to_map) {
89
+ _map = link_to_map;
90
+ _this.el = $(button_css_selector);
91
+ _this.state = _map.mode;
92
+ _this.el.addClass(_map.mode);
93
+ _this.el.on('click', this.onClick);
94
+ };
95
+
96
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ function NewButton() {
4
+
5
+ var _map = null;
6
+ var _this = this;
7
+ _this.state = 'init'; // creating / editing
8
+ _this.el = null;
9
+
10
+ _this.setState = function (state) {
11
+
12
+ _this.state = state;
13
+ _this.el.removeClass('creating');
14
+ _this.el.removeClass('editing');
15
+ _this.el.addClass(state);
16
+
17
+ _map.setMode(state);
18
+
19
+ };
20
+
21
+ _this.resetState = function () {
22
+ _this.state = 'editing';
23
+ _this.el.removeClass('creating');
24
+ _this.el.removeClass('editing');
25
+ _this.el.addClass('editing');
26
+ };
27
+
28
+ _this.onClick = function (e) {
29
+ if (_this.el.hasClass('disabled')) return;
30
+ e.preventDefault();
31
+
32
+ if (_this.state == 'creating') {
33
+ _this.setState('editing');
34
+ } else {
35
+ console.log("<NewButton.onClick> Переходим в режим создания полигона.");
36
+ _this.setState('creating');
37
+ }
38
+ };
39
+
40
+ _this.init = function (button_css_selector, link_to_map) {
41
+ _map = link_to_map;
42
+ _this.el = $(button_css_selector);
43
+ _this.setState(_map.mode);
44
+ _this.el.on('click', _this.onClick);
45
+ };
46
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ function RemoveButton() {
4
+
5
+ var _map = null;
6
+ var _this = this;
7
+ _this.el = null;
8
+
9
+ _this.onClick = function (e) {
10
+ if (_this.el.hasClass('disabled')) return;
11
+ e.preventDefault();
12
+
13
+ console.log("<RemoveButton.onClick> Переходим в режим удаления полигона.");
14
+ _map.setMode('removing');
15
+
16
+ };
17
+
18
+ _this.init = function (button_css_selector, link_to_map) {
19
+ _map = link_to_map;
20
+ _this.el = $(button_css_selector);
21
+ _this.el.on('click', _this.onClick);
22
+ };
23
+ }
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+
3
+ function SaveChangesButton() {
4
+
5
+ var _map = null;
6
+ var _this = this;
7
+ _this.el = null;
8
+
9
+ var sendDataToServer = function () {
10
+
11
+ var areas;
12
+ var buildings;
13
+ var i, len;
14
+
15
+ len = _map.drawn_areas.length;
16
+ if (len > 0) {
17
+ areas = [];
18
+ for (i = 0; i < len; i++) {
19
+ areas.push(_map.drawn_areas[i].to_json());
20
+ }
21
+ }
22
+
23
+ len = _map.drawn_buildings.length;
24
+ if (len > 0) {
25
+ buildings = [];
26
+ for (i = 0; i < len; i++) {
27
+ buildings.push(_map.drawn_buildings[i].to_json());
28
+ }
29
+ }
30
+
31
+ $.ajax({
32
+ url: '/save_map_data',
33
+ type: 'POST',
34
+ data: {
35
+ areas: areas,
36
+ buildings: buildings
37
+ },
38
+ dataType: 'json'
39
+ }).done(sendDataToServerDone);
40
+ };
41
+
42
+ var sendDataToServerDone = function (data, result) {
43
+
44
+ //console.log("<ButtonSave.sendDataToServerDone> data,result:");
45
+ //console.log(data);
46
+ // => Object
47
+ // areas: Array[1]
48
+ // 0: Object:
49
+ // id: 16,
50
+ // old_temp_id: "76400",
51
+ // buildings: Array,
52
+ // updated_locations_json: null
53
+ //console.log(result);
54
+ // => success
55
+
56
+ _map.save_preloader_klass.hide();
57
+
58
+ _map.data = data["updated_locations_json"];
59
+
60
+ //var i;
61
+ //var iarea_resp_params;
62
+ //var idrawn_area;
63
+ //for (i = 0; i< data["areas"].length; i++) {
64
+ // iarea_resp_params = data["areas"][i];
65
+ // найдем в массиве drawn_areas область, данные о которой сохранили на сервере
66
+ //idrawn_area = utils.getById(iarea["old_temp_id"], _map.drawn_areas);
67
+ //idrawn_area["id"] = iarea["id"];
68
+ //
69
+ //}
70
+
71
+ _map.drawn_areas = [];
72
+ _map.drawn_buildings = [];
73
+ _this.check_and_enable();
74
+
75
+ };
76
+
77
+ _this.onClick = function (e) {
78
+ if (_this.el.hasClass('disabled')) return;
79
+ e.preventDefault();
80
+ _map.save_preloader_klass.show();
81
+ sendDataToServer();
82
+ };
83
+
84
+ _this.init = function (button_css_selector, link_to_map) {
85
+ _map = link_to_map;
86
+ _this.el = $(button_css_selector);
87
+ _this.el.on('click', _this.onClick);
88
+ };
89
+
90
+ _this.check_and_enable = function () {
91
+
92
+ //check
93
+ var mark_dirty = _map.drawn_areas.length || _map.drawn_buildings.length;
94
+
95
+ // enable
96
+ if (mark_dirty) {
97
+ _this.el.removeClass('mapplic-disabled');
98
+ } else {
99
+ _this.el.addClass('mapplic-disabled');
100
+ }
101
+
102
+ };
103
+
104
+ _this.hide = function () {
105
+ _this.el.css('display','none');
106
+ };
107
+
108
+ _this.show = function () {
109
+ _this.el.css('display','block');
110
+ };
111
+ }
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+
3
+ function BackToMapButton() {
4
+
5
+ var _map = null;
6
+ var _this = this;
7
+
8
+ var _cnt = null;
9
+ var _btn = null;
10
+
11
+ var _$building_info = null;
12
+
13
+ var _onClick = function () {
14
+ _map.setMode('viewing');
15
+
16
+ if (_map.current_building) {
17
+ _map.current_building.exit();
18
+ _map.current_building = null;
19
+ }
20
+
21
+ if (_map.current_area) {
22
+ _map.current_area.exit();
23
+ _map.current_area = null;
24
+ }
25
+
26
+ _map.svgRemoveAllNodes();
27
+ _map.draw_childs(_map.data["buildings"]);
28
+
29
+ if (_map.initial_map_position != null) {
30
+ /* TODO:: необходимо удостовериться, что параметр scale используется и используется правильно*/
31
+ _map.moveTo(
32
+ _map.initial_map_position.x,
33
+ _map.initial_map_position.y,
34
+ _map.initial_map_position.scale,
35
+ 400,
36
+ 'easeInOutCubic'
37
+ );
38
+ }
39
+
40
+ };
41
+
42
+ _this.init = function (parent_div_selector, link_to_map) {
43
+ _map = link_to_map;
44
+ _cnt = $('<div></div>').addClass('back_to_map_button');
45
+ _cnt.appendTo($(parent_div_selector));
46
+ _btn = $('<a href="#" id="BackToMapButton">Обратно на карту</a>');
47
+ _btn.on('click', _onClick);
48
+ _cnt.append(_btn);
49
+
50
+ _$building_info = $('.building_info');
51
+
52
+ };
53
+
54
+ _this.show = function () {
55
+
56
+ // хардкод - подгоняем под длину анимации, прописанной в css
57
+ setTimeout(__show, 800);
58
+
59
+
60
+ };
61
+ var __show = function () {
62
+ // фиксируем
63
+ var building_info_top = _$building_info.offset().top;
64
+ var building_info_height = _$building_info.height();
65
+
66
+ // считаем
67
+ var btn_top = building_info_top + building_info_height;
68
+ var btn_left = _$building_info.offset().left;
69
+
70
+ // позиционируем
71
+ _btn.css('top', btn_top + 'px');
72
+ _btn.css('left', btn_left + 'px');
73
+
74
+ // показываем
75
+ _btn.css('opacity','1');
76
+ _cnt.css('display', 'block');
77
+ };
78
+
79
+ _this.hide = function () {
80
+ _cnt.css('display', 'none');
81
+ _btn.css('opacity', '0');
82
+ }
83
+
84
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+
3
+ // Zoom Buttons
4
+ function ZoomButtons() {
5
+
6
+ var self = this;
7
+ var _map = null;
8
+ this.el = null;
9
+
10
+ this.init = function (options, link_to_map) {
11
+ var mt = options["height"] - 10;
12
+ _map = link_to_map;
13
+
14
+ //var div_container = $('<div></div>')
15
+ // .addClass("container")
16
+ // .attr("id",'container_buttons')
17
+ // .appendTo(_map.container)
18
+ // .css('margin-top',mt+"px");
19
+ var div_container = $("#container_buttons");
20
+ div_container.css('margin-top', mt + "px");
21
+
22
+ //this.el = $('<div></div>').addClass('mzoom_buttons').appendTo(div_container);
23
+ this.el = $('.mzoom_buttons');
24
+
25
+ this.zoomin = $('<a></a>').attr('href', '#').addClass('mapplic-zoomin-button').appendTo(this.el);
26
+
27
+ this.zoomin.on('click touchstart', function (e) {
28
+ e.preventDefault();
29
+
30
+ var scale = _map.normalizeScale(_map.scale + 0.2);
31
+ //_map.scale = _map.normalizeScale(scale + .2);
32
+
33
+ //_map.x = _map.normalizeX(_map.x - (_map.container.width() / 2 - _map.x) * (_map.scale / scale - 1));
34
+ //_map.y = _map.normalizeY(_map.y - (_map.container.height() / 2 - _map.y) * (_map.scale / scale - 1));
35
+
36
+ self.__execute_zoom(scale);
37
+
38
+ });
39
+
40
+ this.zoomout = $('<a></a>').attr('href', '#').addClass('mapplic-zoomout-button').appendTo(this.el);
41
+
42
+ this.zoomout.on('click touchstart', function (e) {
43
+ e.preventDefault();
44
+
45
+ var scale = _map.normalizeScale(_map.scale - .2);
46
+ //_map.scale = _map.normalizeScale(scale - .2);
47
+
48
+ //_map.x = _map.normalizeX(_map.x - (_map.container.width() / 2 - _map.x) * (_map.scale / scale - 1));
49
+ //_map.y = _map.normalizeY(_map.y - (_map.container.height() / 2 - _map.y) * (_map.scale / scale - 1));
50
+
51
+ self.__execute_zoom(scale);
52
+
53
+ });
54
+ };
55
+
56
+ self.__execute_zoom = function (scale) {
57
+ var x = _map.normalizeX({
58
+ x: _map.x - (_map.container.width() / 2 - _map.x) * (scale / _map.scale - 1),
59
+ scale: scale
60
+ });
61
+
62
+ var y = _map.normalizeY({
63
+ y: _map.y - (_map.container.width() / 2 - _map.y) * (scale / _map.scale - 1),
64
+ scale: scale
65
+ });
66
+
67
+ _map.moveTo(x, y, scale, 400, 'easeInOutCubic');
68
+ _map.mark_virgin = false;
69
+ };
70
+
71
+ this.update = function (scale) {
72
+ this.zoomin.removeClass('mapplic-disabled');
73
+ this.zoomout.removeClass('mapplic-disabled');
74
+ if (scale == _map.o.fitscale) this.zoomout.addClass('mapplic-disabled');
75
+ else if (scale == _map.o.maxscale) this.zoomin.addClass('mapplic-disabled');
76
+ };
77
+
78
+ }