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,35 @@
1
+ module C80MapFloors
2
+
3
+ class MapJson < ActiveRecord::Base
4
+
5
+ def self.update_json
6
+
7
+ # открываем файл на чтение
8
+ locations_path = Rails.root.join("public", "locations.json")
9
+ locs = File.read(locations_path)
10
+ locs_hash = JSON.parse(locs)
11
+
12
+ # поместим в него детей - здания со всеми детьми и внуками
13
+ buildings = []
14
+ C80MapFloors::MapBuilding.all.each do |building|
15
+ buildings << building.as_json
16
+ end
17
+
18
+ locs_hash["buildings"] = buildings
19
+
20
+ # запишем в файл
21
+ File.open(locations_path, 'w') do |f|
22
+ f.write(locs_hash.to_json)
23
+ end
24
+
25
+ end
26
+
27
+ def self.fetch_json
28
+ locations_path = Rails.root.join("public", "locations.json")
29
+ locs = File.read(locations_path)
30
+ JSON.parse(locs)
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,32 @@
1
+ module C80MapFloors
2
+ class Setting < ActiveRecord::Base
3
+ mount_uploader :map_image, C80MapFloors::MapImageUploader
4
+ after_save :update_json
5
+
6
+ def map_img
7
+ MiniMagick::Image.open(map_image.path)
8
+ end
9
+
10
+ protected
11
+
12
+ def update_json
13
+
14
+ if self.map_image.present?
15
+ locations_path = Rails.root.join("public", "locations.json")
16
+ locs = File.read(locations_path)
17
+ puts "<update_json> #{ Rails.root.join("public", "locations.json") }"
18
+
19
+ locs_hash = JSON.parse(locs)
20
+ locs_hash["mapwidth"] = map_img["width"].to_s
21
+ locs_hash["mapheight"] = map_img["height"].to_s
22
+ locs_hash["img"] = map_image.url.to_s
23
+
24
+ File.open(locations_path, 'w') do |f|
25
+ f.write(locs_hash.to_json)
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ module C80MapFloors
2
+
3
+ class BuildingImageUploader < CarrierWave::Uploader::Base
4
+
5
+ include CarrierWave::MiniMagick
6
+
7
+ storage :file
8
+
9
+ version :thumb do
10
+ process :resize_to_fit => [500,500]
11
+ end
12
+
13
+ def store_dir
14
+ "uploads/map/buildings"
15
+ end
16
+
17
+ def filename
18
+ if original_filename
19
+ "img_#{secure_token(4)}.#{file.extension}"
20
+ end
21
+ end
22
+
23
+ protected
24
+ def secure_token(length=16)
25
+ var = :"@#{mounted_as}_secure_token"
26
+ model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.hex(length/2))
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,33 @@
1
+ module C80MapFloors
2
+
3
+ # TODO:: FloorImageUploader класс должен использоваться только для загрузки img_bg [потому что 78aasq]
4
+
5
+ class FloorImageUploader < CarrierWave::Uploader::Base
6
+
7
+ include CarrierWave::MiniMagick
8
+
9
+ storage :file
10
+
11
+ version :thumb do
12
+ process :resize_to_fit => [500,500]
13
+ end
14
+
15
+ def store_dir
16
+ "uploads/map/floors"
17
+ end
18
+
19
+ def filename
20
+ if original_filename
21
+ "floor_#{secure_token(4)}.#{file.extension}"
22
+ end
23
+ end
24
+
25
+ protected
26
+ def secure_token(length=16)
27
+ var = :"@#{mounted_as}_secure_token"
28
+ model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.hex(length/2))
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,31 @@
1
+ module C80MapFloors
2
+
3
+ class MapImageUploader < CarrierWave::Uploader::Base
4
+
5
+ include CarrierWave::MiniMagick
6
+
7
+ storage :file
8
+
9
+ version :thumb do
10
+ process :resize_to_fit => [500,500]
11
+ end
12
+
13
+ def store_dir
14
+ "uploads/map/"
15
+ end
16
+
17
+ def filename
18
+ if original_filename
19
+ "map_#{secure_token(4)}.#{file.extension}"
20
+ end
21
+ end
22
+
23
+ protected
24
+ def secure_token(length=16)
25
+ var = :"@#{mounted_as}_secure_token"
26
+ model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.hex(length/2))
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,40 @@
1
+ <script>
2
+ var LOCS_HASH = <%= locs_hash.to_json.html_safe %>;
3
+ var MAP_WIDTH = <%= mapwidth %>;
4
+ var MAP_HEIGHT = <%= mapheight %>;
5
+ </script>
6
+
7
+ <!--<div class="container" id="container_left_side">
8
+ <div id="left_side">
9
+ <div class="clearfix"><span id="pbrown">ПЛОЩАДИ от</span></div>
10
+ <span id="pnavy"><%# @spro.header_price %></span>
11
+ <span id="pdark">руб/кв.м.</span>
12
+ </div>
13
+ <div id="right_side">
14
+ <p id="ptele"><%# @spro.address_telephone_1 %></p>
15
+ <p id="paddress"><%# @spro.address_locality %>
16
+ <%# @spro.address_street %></p>
17
+ </div>
18
+ </div>-->
19
+
20
+ <div id="map_wrapper">
21
+ <%= render "c80_map_floors/shared/save_preloader" %>
22
+ <%= render "c80_map_floors/shared/modal_window" %>
23
+ <div class="mcontainer">
24
+ <div class="mmap">
25
+ <div class="layers"></div>
26
+ <div id="masked" style="-webkit-clip-path:polygon(0 0, 0 1px)"></div>
27
+ <svg id='svg' xmlns="http://www.w3.org/2000/svg" version="1.2" viewbox='0 0 <%= mapwidth %> <%=mapheight%>' baseProfile="tiny" preserveAspectRatio="xMaxYMax"></svg>
28
+ <div class="overlay_layers"></div>
29
+ <svg id='svg_overlay' xmlns="http://www.w3.org/2000/svg" version="1.2" viewbox='0 0 <%= mapwidth %> <%=mapheight%>' baseProfile="tiny" preserveAspectRatio="xMaxYMax"></svg>
30
+ </div>
31
+ <div class="container" id="ui">
32
+ <%= render "c80_map_floors/shared/map_row/building_info" %>
33
+ <%# render "layouts/shared/map_row/area_order_button" %>
34
+ </div>
35
+ <div class="container" id="container_buttons">
36
+ <div class="mzoom_buttons"></div>
37
+ <div class="status_bar"></div>
38
+ </div>
39
+ </div>
40
+ </div>
@@ -0,0 +1,7 @@
1
+ var $m = $('#modal_window');
2
+ var $cc = $m.find('.modal-body');
3
+ var html_str = "<%= j render :partial => "c80_map_floors/ajax/shared/select_list_unlinked_areas",
4
+ :locals => {
5
+ areas:@unlinked_areas
6
+ } %>";
7
+ $cc.html(html_str);
@@ -0,0 +1,7 @@
1
+ var $m = $('#modal_window');
2
+ var $cc = $m.find('.modal-body');
3
+ var html_str = "<%= j render :partial => "c80_map_floors/ajax/shared/select_list_unlinked_buildings",
4
+ :locals => {
5
+ buildings:@unlinked_buildings
6
+ } %>";
7
+ $cc.html(html_str);
@@ -0,0 +1,36 @@
1
+ <%# особым пользователям разрешает редактировать %>
2
+ <% if current_admin_user.present? %>
3
+ //console.log("<js.erb>");
4
+
5
+ var $btn_layer = $("<%= params[:div_css_selector] %>");
6
+ var $html = $('<a href="#" class="mapplic-edit-button"></a>');
7
+ $btn_layer.append($html);
8
+
9
+ $html = $('<a href="#" class="mapplic-remove-button mapplic-disabled" data-placement="right" data-toggle="tooltip" title="Удалить полигон"></a>');
10
+ $btn_layer.prepend($html);
11
+
12
+ $html = $('<a href="#" class="mapplic-new-button mapplic-disabled" data-placement="right" data-toggle="tooltip" title="Добавить полигон"></a>');
13
+ $btn_layer.prepend($html);
14
+
15
+ $html = $('<a href="#" class="mapplic-building-link-button" data-placement="right" data-toggle="tooltip" title="Назначить Здание"></a>');
16
+ $btn_layer.prepend($html);
17
+
18
+ $html = $('<a href="#" class="mapplic-save-button mapplic-disabled" data-placement="right" data-toggle="tooltip" title="Сохранить изменения"></a>');
19
+ $btn_layer.prepend($html);
20
+
21
+ $html = $('<a href="#" class="mapplic-area-link-button" data-placement="right" data-toggle="tooltip" title="Назначить Площадь"></a>');
22
+ $btn_layer.prepend($html);
23
+
24
+ var $status_layer = $('.status_bar');
25
+ $html = $("<%= j render 'c80_map_floors/ajax/shared/map_creating' %>");
26
+ $status_layer.append($html);
27
+
28
+ $html = $("<%= j render 'c80_map_floors/ajax/shared/map_editing' %>");
29
+ $status_layer.append($html);
30
+
31
+ $html = $("<%= j render 'c80_map_floors/ajax/shared/map_removing' %>");
32
+ $status_layer.append($html);
33
+
34
+ IS_ADMIN = true;
35
+
36
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <%# статус-блок, который виден, когда находимся в режиме рисования полигона %>
2
+ <div id="map_creating" class="status_block">
3
+ <span class="message">Рисование полигона в процессе</span>
4
+ <a href="#" title="Отменить" id="cancelCreating">Отменить (Esc)</a>
5
+ <a href="#" title="Добавить вершину" id="completeCreating">Завершить (Enter)</a>
6
+ </div>
@@ -0,0 +1,4 @@
1
+ <%# статус-блок, который виден, когда находимся в режиме редактирования полигонов Зданий %>
2
+ <div id="map_editing" class="status_block">
3
+ <span class="message">Редактирование полигонов Зданий</span>
4
+ </div>
@@ -0,0 +1,5 @@
1
+ <%# статус-блок, который виден, когда находимся в режиме удаления полигонов %>
2
+ <div id="map_removing" class="status_block">
3
+ <span class="message">Кликните по полигону, который надо удалить</span>
4
+ <a href="#" title="Отменить" id="cancelRemoving">Завершить</a>
5
+ </div>
@@ -0,0 +1,6 @@
1
+ <select id="unlinked_areas" class="selectpicker" data-style="btn-default">
2
+ <% areas.each do |area|%>
3
+ <option value="<%= area.id%>"><%= area.title %></option>
4
+ <% end %>
5
+ </select>
6
+ <button type="button" id='submit_area_link' class="btn btn-primary">Сохранить</button>
@@ -0,0 +1,10 @@
1
+ <select id="unlinked_buildings" class="selectpicker" data-style="btn-default">
2
+ <% buildings.each do |building| %>
3
+ <% tt = building.title %>
4
+ <% if building.map_buildings.count > 0 %>
5
+ <% tt += ' (полигон назначен)' %>
6
+ <% end %>
7
+ <option value="<%= building.id%>"><%= tt %></option>
8
+ <% end %>
9
+ </select>
10
+ <button type="button" id='submit_building_link' class="btn btn-primary">Сохранить</button>
@@ -0,0 +1,28 @@
1
+ <%= link_to 'Показать modal window',
2
+ '#modal_window',
3
+ :data => {
4
+ :toggle => 'modal'
5
+ },
6
+ :class => 'hidden2 show_modal_window',
7
+ :title => 'Показать modal window'
8
+ %>
9
+
10
+ <div class="modal fade" id="modal_window" tabindex="-1" role="dialog" aria-labelledby="modalShowWindow" aria-hidden="true">
11
+ <div class="modal-dialog">
12
+ <div class="modal-content">
13
+
14
+ <div class="modal-header">
15
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
16
+ <h4 class="modal-title" id="myModalLabel">%modal-title%</h4>
17
+ </div>
18
+
19
+ <div class="modal-body">
20
+ %modal-body%
21
+ </div>
22
+
23
+ <div class="modal-footer">
24
+ <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>
25
+ </div>
26
+ </div>
27
+ </div>
28
+ </div>
@@ -0,0 +1,3 @@
1
+ <div id="savePreloader">
2
+ <span class="helper"></span><div class='uil-ring-css'><div></div></div>
3
+ </div>
@@ -0,0 +1,7 @@
1
+ <div class="area_order_button">
2
+ <ul>
3
+ <li id="otopl"><div class="checkbox checked" data-checked="true"></div>Отопление</li>
4
+ <li id="gaz"><div class="checkbox"></div>Газ</li>
5
+ </ul>
6
+ <%= link_to "Оставить заявку", "#", :class => 'ebutton' %>
7
+ </div>
@@ -0,0 +1,17 @@
1
+ <div class="building_info">
2
+ <h2></h2>
3
+ <ul> <%# idишники элементов списка - имена полей таблицы Rent::Building %>
4
+ <li id="square">Общая площадь: <span></span> м кв.</li>
5
+ <li id="free_square">Свободная площадь: <span></span> м кв.</li>
6
+ <li id="floor_height">Высота потолка: <span></span></li>
7
+ <li id="column_step">Шаг колонн: <span></span></li>
8
+ <li id="gate_type">Тип ворот: <span></span></li>
9
+ <li id="communications">Коммуникации: <span></span></li>
10
+ </ul>
11
+ <h5 id="price"><span></span></h5>
12
+ <%= link_to "Оставить заявку",
13
+ "#",
14
+ :class => 'ebutton c80_order_invoking_btn',
15
+ :data => { :comment_text => "этот будет заменён ajax Ответом, заполняющим инфо о площади", :subj_id => 'Это число будет подставлено ajax Ответом' },
16
+ :id => 'area_order_button' %>
17
+ </div>
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "c80_map_floors"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'c80_map_floors/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "c80_map_floors"
8
+ spec.version = C80MapFloors::VERSION
9
+ spec.authors = ["C80609A"]
10
+ spec.email = ["c080609a@gmail.com"]
11
+
12
+ spec.summary = 'Map'
13
+ spec.description = 'Map + map editor'
14
+ spec.homepage = 'http://www.vorsa-park.ru'
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.9"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_dependency 'activesupport', ['>= 3.0.0']
25
+ spec.add_dependency 'bootstrap-sass', '~> 3.3.4'
26
+ spec.add_dependency 'bootstrap-select-rails'
27
+ spec.add_dependency 'historyjs-rails'
28
+ end
@@ -0,0 +1,4 @@
1
+ C80MapFloors::Engine.routes.draw do
2
+ match '/save_map_data', to: 'map_ajax#save_map_data', via: :post
3
+ match '/ajax/map_edit_buttons', :to => 'ajax#map_edit_buttons', :via => :post
4
+ end
@@ -0,0 +1,8 @@
1
+ class CreateC80MapFloorsSettings < ActiveRecord::Migration
2
+ def change
3
+ create_table :c80_map_floors_settings, :options => 'COLLATE=utf8_unicode_ci' do |t|
4
+ t.string :map_image
5
+ t.timestamps
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ class CreateC80MapFloorsMapBuildings < ActiveRecord::Migration
2
+ def change
3
+ create_table :c80_map_floors_map_buildings, :options => 'COLLATE=utf8_unicode_ci' do |t|
4
+ t.string :tag
5
+ t.text :coords
6
+ t.string :img
7
+ t.timestamps
8
+ end
9
+ end
10
+ end