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,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
+ }