c80_map_floors 0.1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,23 @@
1
+ #= require history_jquery
2
+ #= require bootstrap/transition
3
+ #= require bootstrap/modal
4
+ #= require bootstrap/tooltip
5
+ #= require bootstrap/alert
6
+ #= require bootstrap/dropdown
7
+ #= require bootstrap-select
8
+
9
+ #= require ./svg_elements/helper.js
10
+ #= require ./svg_elements/polygon.js
11
+ #= require ./svg_elements/area_label.js
12
+ #= require ./svg_elements/building_label.js
13
+
14
+ #= require_directory ./events
15
+ #= require_directory ./map_objects
16
+ #= require_directory ./view
17
+ #= require_tree ./buttons
18
+
19
+ #= require ./src/utils/utils.js
20
+ #= require ./src/utils/opacity_buttons_utils.js
21
+ #= require ./src/utils/map_utils.js
22
+ #= require ./src/state_controller.js
23
+ #= require ./src/main.js
@@ -0,0 +1,15 @@
1
+
2
+ /* AppEvent constructor */
3
+ function AppEvent(target, eventType, func) {
4
+ console.log("<AppEvent.new> target = " + target);
5
+
6
+ this.target = target;
7
+ this.eventType = eventType;
8
+ this.func = func;
9
+
10
+ target.addEventListener(eventType, func, false);
11
+ }
12
+
13
+ AppEvent.prototype.remove = function () {
14
+ this.target.removeEventListener(this.eventType, this.func, false);
15
+ };
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+
3
+ function Area() {
4
+
5
+ var _map = null;
6
+ var _this = this;
7
+ _this.id = null;
8
+
9
+ //var _polygon = null;
10
+ //var _polygon_overlay = null;
11
+
12
+
13
+ // экранные координаты левой верхней точки, куда надо вписать полигон здания
14
+ //var _left_page_x = 342;
15
+ //var _left_page_y = 65;
16
+
17
+ // bounding box полигона (в логических координатах)
18
+ var _bbox = null;
19
+
20
+ // центр полигона (в логических координатах)
21
+ var _cx = null;
22
+ var _cy = null;
23
+
24
+ // если is_new, значит был полигон был
25
+ // нарисован и ждёт сохранения на сервере
26
+ //_this.is_new = false;
27
+
28
+ _this.init = function (options, parent_building_hash, pself) {
29
+ clog("<Area.init>");
30
+ //clog(parent_building_hash); // => see building.js init comment
31
+
32
+ //clog(options);
33
+ /*{
34
+ "id": 1,
35
+ "object_type": "area",
36
+ "area_hash": {
37
+ "id": 2,
38
+ "title": "Площадь 2.12",
39
+ "is_free": false,
40
+ "props": {
41
+ "square": "100 кв.м.",
42
+ "floor_height": "6 кв. м",
43
+ "column_step": "2 м",
44
+ "gate_type": "распашные",
45
+ "communications": "Интернет, электричество, водоснабжение",
46
+ "price": "от 155 руб/кв.м в месяц"
47
+ }
48
+ },
49
+ "coords": [998.8649298732183,1717.326608643258,998.8649298732183,1717.326608643258,1230.8649298732184,1631.326608643258,1254.8649298732184,1663.326608643258,1160.8649298732184,1695.326608643258,1214.8649298732184,1803.326608643258,1066.8649298732184,1862.326608643258
50
+ ]
51
+ }*/
52
+
53
+ _map = pself;
54
+ _this._options = options;
55
+ if (typeof _this._options["coords"] == "string") { /* когда нажимаем ENTER в редакторе и завершаем рисование полигона - приходит массив */
56
+ _this._options["coords"] = _this._options["coords"].split(',');
57
+ }
58
+ _this.id = options["id"];
59
+
60
+ // [4ddl5df]
61
+ if (_this._options["id"] == undefined) {
62
+ _this._options["id"] = Math.ceil((Math.random()*100000));
63
+ }
64
+
65
+ // [NOTE::56dfaw1: парсим координаты объекта на карте, поданные в виде строки]
66
+ for (var i=0; i<_this._options.coords.length; i++) {
67
+ _this._options.coords[i] = Number(_this._options.coords[i]);
68
+ }
69
+
70
+ _this._options.parent_building_hash = parent_building_hash;
71
+ //clog(_this._options.parent_building_hash);
72
+
73
+
74
+ _this._polygon = Polygon.createFromSaved(options, false, _map);
75
+ _this._polygon.area = _this;
76
+ _this._polygon.parent_building_hash = parent_building_hash;
77
+ _this._polygon = $(_this._polygon.polygon);
78
+
79
+ // подпись над полигоном показываем только админам
80
+ if (IS_ADMIN) {
81
+ _this._label = new AreaLabel(options, _map);
82
+ }
83
+
84
+ _this._polygon_overlay = Polygon.createFromSaved(options, true, _map);
85
+ _this._polygon_overlay.area = _this;
86
+ _this._polygon_overlay = $(_this._polygon_overlay.polygon);
87
+ _this._polygon_overlay.hover(_this._mouse_in, _this._mouse_out);
88
+ _this._calcBBox();
89
+
90
+ var k = 'unassigned';
91
+ if (options.area_hash != undefined) {
92
+ if (typeof options.area_hash.id !== 'undefined') {
93
+ k = 'free';
94
+ if (!options.area_hash.is_free) {
95
+ k = 'busy';
96
+ }
97
+ }
98
+ }
99
+ _this._polygon.parent().attr("class", k);
100
+
101
+ };
102
+
103
+ // optimisation
104
+ var timeoutEnter = function () {
105
+ _map.showAreaInfo(_this._options.area_hash, _this._options.parent_building_hash);
106
+ _map.setMode('view_area');
107
+ };
108
+
109
+ _this.enter = function () {
110
+ console.log("<Area.enter>");
111
+ //clog(_this._options);
112
+
113
+ /* рассчитаем масштаб, при котором можно вписать прямоугольник дома в прямоугольник рабочей области */
114
+
115
+ var scaleX = _map.calcScale(_bbox.xmin, _bbox.xmax, _map.X1S, _map.X2S);
116
+ var scaleY = _map.calcScale(_bbox.ymin, _bbox.ymax, _map.Y1S, _map.Y2S);
117
+ var scale = (scaleX < scaleY) ? scaleX : scaleY;
118
+
119
+ //_map.scale = scale;
120
+
121
+ // совмещаем точку на экране, в которую надо центрировать дома, с центром дома с учётом рассчитанного масштаба
122
+ //_map.x = _map.normalizeX(_map.CX - _map.scale * _cx - _map.container.offset().left);
123
+ //_map.y = _map.normalizeY(_map.CY - _map.scale * _cy - _map.container.offset().top);
124
+
125
+ var x = _map.normalizeX({
126
+ x: _map.CX - scale * _cx - _map.container.offset().left,
127
+ scale: scale
128
+ });
129
+
130
+ var y = _map.normalizeY({
131
+ y: _map.CY - scale * _cy - _map.container.offset().top,
132
+ scale: scale
133
+ });
134
+
135
+ //clog("<Area.enter> [qq] moveTo: " + _map.x + ", " + _map.y);
136
+ //clog("<Area.enter> Call moveTo.");
137
+ _map.moveTo(x, y, scale, 400, 'easeInOutCubic');
138
+
139
+ setTimeout(timeoutEnter, 400);
140
+
141
+ var k;
142
+ if (_map.current_area != null) {
143
+ k = _map.current_area._polygon.parent().attr('class');
144
+ //clog("k = " + k);
145
+ k = k.split('viewing_area').join("");
146
+ _map.current_area._polygon.parent().attr("class", k);
147
+ }
148
+
149
+ // <g class='busy viewing_area'>..<polygon >.</g>
150
+ k = _this._polygon.parent().attr("class");
151
+ k += " viewing_area";
152
+ _this._polygon.parent().attr("class", k);
153
+
154
+ _this.invalidateAnimationMask();
155
+
156
+ _map.current_area = _this;
157
+ _map.mark_virgin = false;
158
+
159
+ };
160
+
161
+ _this.exit = function () {
162
+ console.log('<Area.exit>');
163
+ };
164
+
165
+ this.invalidateAnimationMask = function () {
166
+ $("#masked").attr('style', _this._calc_polygon_attr);
167
+ };
168
+
169
+ // выдать центр площади в логических координатах
170
+ _this.cx = function () {
171
+ return _cx;
172
+ };
173
+ _this.cy = function () {
174
+ return _cy;
175
+ };
176
+
177
+ // рассчитаем bounding box полигона (в логических координатах)
178
+ _this._calcBBox = function () {
179
+
180
+ var coords = _this._options.coords;
181
+ var xmin = Number.MAX_VALUE;
182
+ var ymin = Number.MAX_VALUE;
183
+ var xmax = Number.MIN_VALUE;
184
+ var ymax = Number.MIN_VALUE;
185
+
186
+ var ix, iy;
187
+ for (var i = 0, c = coords.length; i < c; i += 2) {
188
+ ix = coords[i];
189
+ iy = coords[i + 1];
190
+
191
+ //clog(xmin + " VS " + ix);
192
+ xmin = (ix < xmin) ? ix : xmin;
193
+ ymin = (iy < ymin) ? iy : ymin;
194
+
195
+ xmax = (ix > xmax) ? ix : xmax;
196
+ ymax = (iy > ymax) ? iy : ymax;
197
+ }
198
+
199
+
200
+ _bbox = {
201
+ xmin: xmin,
202
+ ymin: ymin,
203
+ xmax: xmax,
204
+ ymax: ymax
205
+ };
206
+
207
+ _cx = xmin + (xmax - xmin) / 2;
208
+ _cy = ymin + (ymax - ymin) / 2;
209
+
210
+ //clog("<Area._calcBBox> " +
211
+ //xmin + "," + ymin + "; " + xmax + "," + ymax +
212
+ //"; center logical: " + _cx + "," + _cy + ", center screen: " + _map.rightX(_cx) + ", " + _map.rightY(_cy));
213
+ };
214
+
215
+ _this._mouse_in = function () {
216
+ //clog('<Area._mouse_in>');
217
+ //clog(_this._polygon);
218
+ _this._polygon.attr('class', 'hover');
219
+ };
220
+
221
+ _this._mouse_out = function () {
222
+ //clog('<Area._mouse_out>');
223
+ _this._polygon.attr('class', '');
224
+ };
225
+
226
+ _this._calc_polygon_attr = function () {
227
+ var res = "";
228
+
229
+ var coords = _this._options["coords"];
230
+ var ix, iy;
231
+ for (var i = 0, c = coords.length; i < c; i += 2) {
232
+ ix = _map.scale * coords[i];
233
+ iy = _map.scale * coords[i + 1];
234
+ res += ix + "px " + iy + "px,"
235
+ }
236
+
237
+ //clog("<Area._calc_polygon_attr> res = " + res);
238
+ res = res.slice(0, res.length - 1);
239
+ res = "-webkit-clip-path:polygon(" + res + ")";
240
+ return res;
241
+
242
+ }
243
+
244
+ _this.to_json = function () {
245
+ return {
246
+ id: _this._options["id"],
247
+ coords: _this._options["coords"],
248
+ parent_building_id: _this._options.parent_building_hash["id"]
249
+ }
250
+ }
251
+ }
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+
3
+ function Building() {
4
+
5
+ var _map = null;
6
+ var _this = this;
7
+ var _options = null;
8
+ var _polygon = null;
9
+
10
+
11
+ // экранные координаты левой верхней точки, куда надо вписать полигон здания
12
+ //var _left_page_x = 342;
13
+ //var _left_page_y = 65;
14
+
15
+ // bounding box полигона (в логических координатах)
16
+ var _bbox = null;
17
+
18
+ // центр полигона (в логических координатах)
19
+ var _cx = null;
20
+ var _cy = null;
21
+
22
+ var _image_bg = null;
23
+ var _image_overlay = null;
24
+
25
+ var _zoomToMe = function () {
26
+
27
+ /* рассчитаем масштаб, при котором можно вписать прямоугольник дома в прямоугольник рабочей области */
28
+
29
+ var scaleX = _map.calcScale(_bbox.xmin, _bbox.xmax, _map.X1, _map.X2);
30
+ var scaleY = _map.calcScale(_bbox.ymin, _bbox.ymax, _map.Y1, _map.Y2);
31
+ //console.log("<Building.enter> scaleX = " + scaleX + ", scaleY = " + scaleY);
32
+
33
+ var scale = (scaleX < scaleY) ? scaleX : scaleY;
34
+ //var selfX = _map.calcCoord(scale, _map.X1, _bbox.xmin);
35
+ //var selfY = _map.calcCoord(scale, _map.Y1, _bbox.ymin);
36
+
37
+ //_map.scale = scale;
38
+ //_map.x = selfX;
39
+ //_map.y = selfY;
40
+
41
+ /* по-отдельности */
42
+
43
+ //var scaleX = _map.calcScale(_bbox.xmin, _bbox.xmax, _map.X1, _map.X2);
44
+ //console.log("<Building.enter> scaleX = " + scaleX);
45
+ //var selfX = _map.calcCoord(scaleX, _map.X1, _bbox.xmin);
46
+ //_map.scale = scaleX;
47
+ //_map.x = selfX;
48
+
49
+ //var scaleY = _map.calcScale(_bbox.ymin, _bbox.ymax, _map.Y1, _map.Y2);
50
+ //console.log("<Building.enter> scaleY = " + scaleY);
51
+ //var selfY = _map.calcCoord(scaleY, _map.Y1, _bbox.ymin);
52
+ //_map.scale = scaleY;
53
+ //_map.y = selfY;
54
+
55
+ // совмещаем точку на экране, в которую надо центрировать дома, с центром дома с учётом рассчитанного масштаба
56
+ // или, другими словами, перегоняем логические координаты в систему координат экрана
57
+ //_map.x = _map.normalizeX(_map.CX - scale * _cx - _map.container.offset().left);
58
+ //_map.y = _map.normalizeY(_map.CY - scale * _cy - _map.container.offset().top);
59
+
60
+ var x = _map.normalizeX({
61
+ x: _map.CX - scale * _cx - _map.container.offset().left,
62
+ scale: scale
63
+ });
64
+
65
+ var y = _map.normalizeY({
66
+ y: _map.CY - scale * _cy - _map.container.offset().top,
67
+ scale: scale
68
+ });
69
+
70
+ //console.log("<Building.enter> [qq] moveTo: " + _map.x + ", " + _map.y);
71
+ _map.moveTo(x, y, scale, 400, 'easeInOutCubic');
72
+ };
73
+
74
+ // the_floor - это as_json модели C80MapFloors::Floor
75
+ /*{
76
+ "map_building_id": 7,
77
+ "img_bg": {
78
+ "url": "/uploads/map/floors/floor_e7dc.gif",
79
+ "thumb": {"url": "/uploads/map/floors/thumb_floor_e7dc.gif"}
80
+ },
81
+ "img_overlay": {
82
+ "url": null,
83
+ "thumb": {"url": null}
84
+ },
85
+ "id": 2,
86
+ "title": "Первый этаж",
87
+ "tag": "first_test_floor",
88
+ "ord": 1,
89
+ "coords": "",
90
+ "class_name": "C80MapFloors::Floor",
91
+ "areas": [
92
+ {
93
+ "floor_id": 2,
94
+ "id": 2,
95
+ "tag": "test_area",
96
+ "coords": "10,12,110,112",
97
+ "area_representator_id": null,
98
+ "class_name": "C80MapFloors::Area"
99
+ }
100
+ ]
101
+ }*/
102
+ var _draw_floor = function (the_floor) {
103
+ console.log('<Building._draw_floor>');
104
+
105
+ // это тот самый код, который остался без изменений с версии c80_map (прошлой версии)
106
+ if (the_floor["img_overlay"]["url"] != "null") {
107
+ //_image_overlay = _map.draw_child_bg_image(the_floor["img_overlay"]["url"], 'building', true);
108
+ }
109
+ if (the_floor["img_bg"]["url"] != "null") {
110
+
111
+ // картинку этажа рисуем не по bounding box здания, а по значениям из базы
112
+ var tmp = _options["coords_img"].split(",");
113
+ var xx = tmp[0];
114
+ var yy = tmp[1];
115
+
116
+ // просим карту нарисовать картинку с данными характеристиками
117
+ _image_bg = _map.draw_map_object_image_bg(the_floor["img_bg"]["url"], {
118
+ //x: _bbox.xmin,
119
+ //y: _bbox.ymin,
120
+ x: xx,
121
+ y: yy,
122
+ width: the_floor["img_bg_width"],
123
+ height: the_floor["img_bg_height"]
124
+ }/*, 'building'*/);
125
+
126
+ }
127
+
128
+ // просим карту нарисовать площади
129
+ _map.draw_childs(the_floor["areas"]/*, _options["rent_building_hash"]*/);
130
+
131
+ };
132
+
133
+ // options_floors - as_json массива этажей модели C80MapFloors::Floor
134
+ var _parse_floors = function (options_floors) {
135
+
136
+ // NOTE:: тестово возьмем 1й этаж
137
+ var the_first_floor = options_floors[0];
138
+
139
+ _draw_floor(the_first_floor);
140
+
141
+ };
142
+
143
+ var _proccess_floors_data = function () {
144
+
145
+ if (_options["floors"] != undefined && _options["floors"].length) {
146
+ _parse_floors(_options["floors"]);
147
+ } else {
148
+ alert('У здания нет этажей, а должны быть.');
149
+ }
150
+
151
+ };
152
+
153
+ _this.init = function (options, link_to_map) {
154
+
155
+ if (options['coords'] != undefined && options['coords'].length) {
156
+ console.log("<Building.init>");
157
+
158
+ _map = link_to_map;
159
+ _options = options;
160
+ _this.options = options;
161
+ if (typeof _this.options["coords"] == 'string') { /* когда нажимаем ENTER в редакторе и завершаем рисование полигона - приходит массив */
162
+ _this.options["coords"] = _this.options["coords"].split(',');
163
+ }
164
+ _this.id = options["id"];
165
+
166
+ // [NOTE::56dfaw1: парсим координаты объекта на карте, поданные в виде строки]
167
+ for (var i=0; i<_this.options.coords.length; i++) {
168
+ _this.options.coords[i] = Number(_this.options.coords[i]);
169
+ }
170
+
171
+ // [4ddl5df]: в случае, если это только что отрисованное Здание - генерим временный случайный id
172
+ if (_this.options["id"] == undefined) {
173
+ _this.options["id"] = Math.ceil((Math.random()*100000));
174
+ }
175
+
176
+ _polygon = Polygon.createFromSaved(options, false, _map);
177
+ _polygon.building = _this;
178
+
179
+ _this._calcBBox();
180
+
181
+ // подпись над зданием - сколько свободных площадей
182
+ _this._label = new BuildingLabel(options, _map);
183
+
184
+ }
185
+ };
186
+
187
+ _this.enter = function () {
188
+ //console.log("<Building.enter>");
189
+ //console.log(_options);
190
+
191
+ _zoomToMe();
192
+
193
+
194
+ setTimeout(function () {
195
+
196
+ // попросим изменить состояние окружающей среды
197
+ _map.setMode('view_building');
198
+
199
+ // попросим показать информацию о Rent::Building здании (привязанному к данному C80MapFloors::MapBuilding)
200
+ //_map.showBuildingInfo(_options["rent_building_hash"]);
201
+
202
+ // запустим внутренний механизм парсинга этажей и их отрисовки
203
+ _proccess_floors_data();
204
+
205
+ }, 400);
206
+
207
+ _map.svgRemoveAllNodes();
208
+
209
+ _map.current_building = _this;
210
+ //console.log("<Building.enter> id: " + _this.id);
211
+ _map.mark_virgin = false;
212
+
213
+ };
214
+
215
+ _this.exit = function () {
216
+ _image_bg.remove();
217
+ if (_image_overlay != null) {
218
+ _image_overlay.remove();
219
+ }
220
+ _image_bg = null;
221
+ _image_overlay = null;
222
+ //_zoomToMe();
223
+ };
224
+
225
+ // выдать центр дома в логических координатах
226
+ _this.cx = function () {
227
+ return _cx;
228
+ };
229
+ _this.cy = function () {
230
+ return _cy;
231
+ };
232
+
233
+ // рассчитаем bounding box полигона (в логических координатах)
234
+ _this._calcBBox = function () {
235
+
236
+ var coords = _options.coords;
237
+ var xmin = Number.MAX_VALUE;
238
+ var ymin = Number.MAX_VALUE;
239
+ var xmax = Number.MIN_VALUE;
240
+ var ymax = Number.MIN_VALUE;
241
+
242
+ var ix, iy;
243
+ for (var i = 0, c = coords.length; i < c; i += 2) {
244
+ ix = coords[i];
245
+ iy = coords[i + 1];
246
+
247
+ //console.log(xmin + " VS " + ix);
248
+ xmin = (ix < xmin) ? ix : xmin;
249
+ ymin = (iy < ymin) ? iy : ymin;
250
+
251
+ xmax = (ix > xmax) ? ix : xmax;
252
+ ymax = (iy > ymax) ? iy : ymax;
253
+ }
254
+
255
+
256
+ _bbox = {
257
+ xmin: xmin,
258
+ ymin: ymin,
259
+ xmax: xmax,
260
+ ymax: ymax
261
+ };
262
+
263
+ _cx = xmin + (xmax - xmin) / 2;
264
+ _cy = ymin + (ymax - ymin) / 2;
265
+
266
+ //console.log("<Building._calcBBox> " +
267
+ //xmin + "," + ymin + "; " + xmax + "," + ymax +
268
+ //"; center logical: " + _cx + "," + _cy + ", center screen: " + _map.rightX(_cx) + ", " + _map.rightY(_cy));
269
+
270
+ console.log('<Building._calcBBox> ' + xmin + ', ' + ymin);
271
+ };
272
+
273
+ // при редактировании здания (т.е. изменении полигонов и holer-ов площадей)
274
+ // необходимо, чтобы оверлейный слой с колоннами не мешал кликам мышки
275
+ // добраться до слоя с svg
276
+ // эти методы для этого имплементированы
277
+ _this.changeOverlayZindex = function () {
278
+ if (_image_overlay != null) {
279
+ _image_overlay.css('z-index', '1');
280
+ }
281
+ };
282
+ _this.resetOverlayZindex = function () {
283
+ if (_image_overlay != null) {
284
+ _image_overlay.css('z-index', '3');
285
+ }
286
+ };
287
+
288
+ _this.to_json = function () {
289
+ return {
290
+ id: _this.options["id"],
291
+ coords: _this.options["coords"]
292
+ }
293
+ }
294
+ }