open_porch 0.5.0
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.
- data/Gemfile +41 -0
- data/Gemfile.lock +130 -0
- data/README.md +170 -0
- data/Rakefile +19 -0
- data/VERSION +1 -0
- data/app/controllers/admin/areas/base_controller.rb +11 -0
- data/app/controllers/admin/areas/issues_controller.rb +67 -0
- data/app/controllers/admin/areas/memberships_controller.rb +7 -0
- data/app/controllers/admin/areas/posts_controller.rb +44 -0
- data/app/controllers/admin/areas_controller.rb +89 -0
- data/app/controllers/admin/base_controller.rb +16 -0
- data/app/controllers/admin/user_activity_controller.rb +29 -0
- data/app/controllers/admin/users_controller.rb +57 -0
- data/app/controllers/application_controller.rb +15 -0
- data/app/controllers/areas/base_controller.rb +25 -0
- data/app/controllers/areas/issues_controller.rb +35 -0
- data/app/controllers/areas/posts_controller.rb +28 -0
- data/app/controllers/areas_controller.rb +30 -0
- data/app/controllers/passwords_controller.rb +42 -0
- data/app/controllers/registrations_controller.rb +42 -0
- data/app/controllers/sessions_controller.rb +33 -0
- data/app/controllers/users_controller.rb +77 -0
- data/app/helpers/open_porch_helper.rb +24 -0
- data/app/mailers/user_mailer.rb +35 -0
- data/app/models/address.rb +57 -0
- data/app/models/area.rb +171 -0
- data/app/models/area_activity.rb +24 -0
- data/app/models/email_message.rb +104 -0
- data/app/models/issue.rb +66 -0
- data/app/models/issue_number.rb +22 -0
- data/app/models/membership.rb +27 -0
- data/app/models/post.rb +64 -0
- data/app/models/session_user.rb +69 -0
- data/app/models/user.rb +140 -0
- data/app/models/user_activity.rb +31 -0
- data/app/models/user_authority_check.rb +14 -0
- data/app/views/admin/areas/_form.html.haml +8 -0
- data/app/views/admin/areas/_nav.html.haml +12 -0
- data/app/views/admin/areas/edit.html.haml +22 -0
- data/app/views/admin/areas/edit_borders.html.haml +44 -0
- data/app/views/admin/areas/index.html.haml +61 -0
- data/app/views/admin/areas/issues/_post.html.haml +15 -0
- data/app/views/admin/areas/issues/add_posts.js.rjs +3 -0
- data/app/views/admin/areas/issues/edit.html.haml +37 -0
- data/app/views/admin/areas/issues/index.html.haml +31 -0
- data/app/views/admin/areas/issues/remove_posts.js.rjs +3 -0
- data/app/views/admin/areas/issues/show.html.haml +13 -0
- data/app/views/admin/areas/memberships/index.html.haml +17 -0
- data/app/views/admin/areas/new.html.haml +6 -0
- data/app/views/admin/areas/new.js.haml +4 -0
- data/app/views/admin/areas/posts/_edit.html.haml +6 -0
- data/app/views/admin/areas/posts/_post_status.html.haml +1 -0
- data/app/views/admin/areas/posts/destroy.js.rjs +1 -0
- data/app/views/admin/areas/posts/edit.js.rjs +1 -0
- data/app/views/admin/areas/posts/show.js.rjs +1 -0
- data/app/views/admin/areas/posts/toggle_reviewed_by.js.rjs +1 -0
- data/app/views/admin/areas/posts/update.js.rjs +5 -0
- data/app/views/admin/areas/show.html.haml +5 -0
- data/app/views/admin/user_activity/show.html.haml +5 -0
- data/app/views/admin/users/_form.html.haml +21 -0
- data/app/views/admin/users/edit.html.haml +5 -0
- data/app/views/admin/users/index.html.haml +31 -0
- data/app/views/admin/users/new.html.haml +5 -0
- data/app/views/areas/issues/index.html.haml +31 -0
- data/app/views/areas/issues/show.html.haml +22 -0
- data/app/views/areas/posts/_post.html.haml +8 -0
- data/app/views/areas/posts/_posts_search_form.html.haml +8 -0
- data/app/views/areas/posts/index.html.haml +27 -0
- data/app/views/areas/posts/new.html.haml +10 -0
- data/app/views/areas/show.html.haml +47 -0
- data/app/views/layouts/_account_nav.html.haml +18 -0
- data/app/views/layouts/_flash_message.html.haml +4 -0
- data/app/views/layouts/_footer.html.haml +9 -0
- data/app/views/layouts/_head.html.haml +16 -0
- data/app/views/layouts/admin/_nav.html.haml +13 -0
- data/app/views/layouts/admin.html.haml +15 -0
- data/app/views/layouts/application.html.haml +14 -0
- data/app/views/layouts/area_editor.html.haml +11 -0
- data/app/views/passwords/edit.html.haml +9 -0
- data/app/views/passwords/new.html.haml +13 -0
- data/app/views/registrations/_address_form.html.haml +7 -0
- data/app/views/registrations/create.html.haml +49 -0
- data/app/views/registrations/index.html.haml +30 -0
- data/app/views/registrations/new.html.haml +17 -0
- data/app/views/sessions/new.html.haml +18 -0
- data/app/views/stylesheets/common.sass +239 -0
- data/app/views/stylesheets/content.sass +193 -0
- data/app/views/stylesheets/reset.sass +46 -0
- data/app/views/stylesheets/structure.sass +11 -0
- data/app/views/stylesheets/typography.sass +57 -0
- data/app/views/user_mailer/email_verification.html.erb +5 -0
- data/app/views/user_mailer/email_verification.text.erb +7 -0
- data/app/views/user_mailer/new_issue.html.erb +32 -0
- data/app/views/user_mailer/new_issue.text.erb +26 -0
- data/app/views/user_mailer/password_reset.html.erb +7 -0
- data/app/views/user_mailer/password_reset.text.erb +6 -0
- data/app/views/users/_form.html.haml +5 -0
- data/app/views/users/edit.html.haml +11 -0
- data/app/views/users/new.html.haml +41 -0
- data/app/views/users/show.html.haml +30 -0
- data/bin/open_porch_engine +135 -0
- data/config/application.rb +43 -0
- data/config/boot.rb +13 -0
- data/config/database_example.yml +59 -0
- data/config/environment.rb +5 -0
- data/config/environments/development.rb +26 -0
- data/config/environments/production.rb +49 -0
- data/config/environments/test.rb +35 -0
- data/config/initializers/backtrace_silencers.rb +7 -0
- data/config/initializers/email_regex.rb +38 -0
- data/config/initializers/geokit_config.rb +61 -0
- data/config/initializers/inflections.rb +20 -0
- data/config/initializers/meta_search.rb +7 -0
- data/config/initializers/mime_types.rb +5 -0
- data/config/initializers/open_porch.rb +41 -0
- data/config/initializers/sass.rb +1 -0
- data/config/initializers/secret_token.rb +7 -0
- data/config/initializers/session_store.rb +8 -0
- data/config/initializers/states_provinces.rb +2 -0
- data/config/initializers/will_paginate.rb +2 -0
- data/config/locales/en.yml +5 -0
- data/config/open_porch_example.yml +23 -0
- data/config/routes.rb +54 -0
- data/config/schedule.rb +9 -0
- data/config.ru +4 -0
- data/db/migrate/01_create_areas.rb +21 -0
- data/db/migrate/02_create_users.rb +28 -0
- data/db/migrate/03_create_memberships.rb +14 -0
- data/db/migrate/04_create_posts.rb +20 -0
- data/db/migrate/05_create_issue_numbers.rb +13 -0
- data/db/migrate/06_create_issues.rb +21 -0
- data/db/migrate/20110204173301_add_published_to_areas.rb +10 -0
- data/db/migrate/20110204194840_create_user_activities.rb +13 -0
- data/db/migrate/20110208163604_add_zip_to_areas.rb +11 -0
- data/db/migrate/20110209175723_add_counters_to_areas.rb +11 -0
- data/db/migrate/20110209182244_remove_subject_from_issues.rb +9 -0
- data/db/migrate/20110209190146_add_reviewer_info_to_posts.rb +9 -0
- data/db/migrate/20110215173144_add_email_validation_key_to_users.rb +13 -0
- data/db/migrate/20110215182716_remove_published_from_areas.rb +10 -0
- data/db/migrate/20110215211012_create_area_activities.rb +19 -0
- data/db/migrate/20110215213802_create_email_messages.rb +19 -0
- data/db/migrate/20110217165018_change_send_mode_to_string.rb +17 -0
- data/db/migrate/20110223160609_denormalize_user_info_in_posts.rb +19 -0
- data/db/seeds.rb +7 -0
- data/doc/README_FOR_APP +2 -0
- data/lib/generators/open_porch_generator.rb +37 -0
- data/lib/open_porch/engine.rb +20 -0
- data/lib/open_porch.rb +3 -0
- data/lib/tasks/.gitkeep +0 -0
- data/lib/tasks/open_porch.rake +10 -0
- data/lib/tasks/postageapp_tasks.rake +78 -0
- data/open_porch.gemspec +335 -0
- data/public/404.html +26 -0
- data/public/422.html +26 -0
- data/public/500.html +26 -0
- data/public/favicon.ico +0 -0
- data/public/images/icons/ajax-loader.gif +0 -0
- data/public/images/icons/calendar.png +0 -0
- data/public/images/icons/post_new.png +0 -0
- data/public/images/icons/post_reviewed.png +0 -0
- data/public/javascripts/application.js +3 -0
- data/public/javascripts/google_maps.js +153 -0
- data/public/javascripts/highcharts.js +162 -0
- data/public/javascripts/highcharts_init.js +30 -0
- data/public/javascripts/issue_edit.js +57 -0
- data/public/javascripts/jquery-ui.min.js +191 -0
- data/public/javascripts/jquery.js +154 -0
- data/public/javascripts/rails.js +137 -0
- data/public/javascripts/region_editor.js +616 -0
- data/public/javascripts/user_activity.js +29 -0
- data/public/robots.txt +5 -0
- data/public/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/public/stylesheets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/public/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/public/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/public/stylesheets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/public/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/public/stylesheets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/public/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/public/stylesheets/images/ui-icons_222222_256x240.png +0 -0
- data/public/stylesheets/images/ui-icons_2e83ff_256x240.png +0 -0
- data/public/stylesheets/images/ui-icons_454545_256x240.png +0 -0
- data/public/stylesheets/images/ui-icons_888888_256x240.png +0 -0
- data/public/stylesheets/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/public/stylesheets/jquery-ui.css +362 -0
- data/script/rails +6 -0
- data/test/dummy/area.rb +5 -0
- data/test/dummy/area_activity.rb +7 -0
- data/test/dummy/issue.rb +4 -0
- data/test/dummy/membership.rb +4 -0
- data/test/dummy/post.rb +12 -0
- data/test/dummy/user.rb +29 -0
- data/test/dummy/user_activity.rb +11 -0
- data/test/functional/admin/areas/issues_controller_test.rb +48 -0
- data/test/functional/admin/areas/memberships_controller_test.rb +45 -0
- data/test/functional/admin/areas/posts_controller_test.rb +54 -0
- data/test/functional/admin/areas_controller_test.rb +134 -0
- data/test/functional/admin/base_controller_test.rb +8 -0
- data/test/functional/admin/user_activity_controller_test.rb +28 -0
- data/test/functional/admin/users_controller_test.rb +144 -0
- data/test/functional/areas/issues_controller_test.rb +33 -0
- data/test/functional/areas/posts_controller_test.rb +50 -0
- data/test/functional/areas_controller_test.rb +12 -0
- data/test/functional/passwords_controller_test.rb +64 -0
- data/test/functional/registrations_controller_test.rb +64 -0
- data/test/functional/sessions_controller_test.rb +120 -0
- data/test/functional/users_controller_test.rb +144 -0
- data/test/performance/browsing_test.rb +9 -0
- data/test/test_helper.rb +92 -0
- data/test/unit/address_test.rb +25 -0
- data/test/unit/area_activity_test.rb +57 -0
- data/test/unit/area_test.rb +92 -0
- data/test/unit/email_message_test.rb +8 -0
- data/test/unit/issue_number_test.rb +25 -0
- data/test/unit/issue_test.rb +154 -0
- data/test/unit/membership_test.rb +20 -0
- data/test/unit/post_test.rb +69 -0
- data/test/unit/session_user_test.rb +65 -0
- data/test/unit/user_activity_test.rb +31 -0
- data/test/unit/user_mailer_test.rb +20 -0
- data/test/unit/user_test.rb +61 -0
- data/vendor/plugins/.gitkeep +0 -0
- metadata +456 -0
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
(function($){
|
|
2
|
+
$.fn.RegionEditor = function(options) {
|
|
3
|
+
var editor = this;
|
|
4
|
+
var EDIT_MODE = 0;
|
|
5
|
+
var CREATE_MODE = 1;
|
|
6
|
+
var defaults = {
|
|
7
|
+
mode: EDIT_MODE,
|
|
8
|
+
regions : [],
|
|
9
|
+
selected_region_id: 0,
|
|
10
|
+
selected_polygon: null,
|
|
11
|
+
vertices: [],
|
|
12
|
+
map_options: {
|
|
13
|
+
zoom: 14,
|
|
14
|
+
mapTypeControl: false,
|
|
15
|
+
streetViewControl: false,
|
|
16
|
+
scaleControl: false,
|
|
17
|
+
mapTypeId: google.maps.MapTypeId.ROADMAP
|
|
18
|
+
},
|
|
19
|
+
map_style: 'width:100%;height:500px',
|
|
20
|
+
colors : {
|
|
21
|
+
red: '#aa4643',
|
|
22
|
+
blue: '#4572a7'
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
var options = $.extend(defaults, options);
|
|
27
|
+
var map = initialize_google_map();
|
|
28
|
+
$.each(options.regions, add_region); // Add all the regions to the map
|
|
29
|
+
if(options.selected_polygon == null) {
|
|
30
|
+
switch_to_mode(CREATE_MODE);
|
|
31
|
+
alert("Click on the map to add points to the region. When you're done close the region by clicking on the first marker")
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return this.each(function() {
|
|
35
|
+
obj = $(this);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
// -------------------------
|
|
40
|
+
// Initialize Google Map
|
|
41
|
+
// -------------------------
|
|
42
|
+
function initialize_google_map() {
|
|
43
|
+
var map_container = $('<div id="google_map" style ="'+options.map_style+'"></div>');
|
|
44
|
+
editor.append(map_container);
|
|
45
|
+
|
|
46
|
+
// Setting the center of the map
|
|
47
|
+
options.map_options.center = new google.maps.LatLng(options.center.lat, options.center.lng);
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
// Creating the map
|
|
51
|
+
var map = new google.maps.Map(map_container.get(0), options.map_options);
|
|
52
|
+
render_controls(map);
|
|
53
|
+
|
|
54
|
+
// Adjusting the zoom level if bounds were provided
|
|
55
|
+
if (options.bounds != null) {
|
|
56
|
+
map.fitBounds(new google.maps.LatLngBounds(
|
|
57
|
+
new google.maps.LatLng(options.bounds[0][0], options.bounds[0][1]),
|
|
58
|
+
new google.maps.LatLng(options.bounds[1][0], options.bounds[1][1])
|
|
59
|
+
));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Right click to add a new point to the selected region (EDIT_MODE)
|
|
63
|
+
google.maps.event.addDomListener(map, 'rightclick', function(event) {
|
|
64
|
+
if(options.mode == EDIT_MODE) {
|
|
65
|
+
if(confirm('Add new point?')) {
|
|
66
|
+
add_new_point_to_polygon(event.latLng);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Add the click event to add a point to a new region (CREATE_MODE)
|
|
72
|
+
google.maps.event.addListener(map, 'click', function(event) {
|
|
73
|
+
if(options.mode == CREATE_MODE) {
|
|
74
|
+
add_point_to_new_region(event.latLng);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return map;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// -------------------------
|
|
82
|
+
// Adds controls to the map
|
|
83
|
+
// -------------------------
|
|
84
|
+
function render_controls(map){
|
|
85
|
+
// --- Save changes ---
|
|
86
|
+
options.save_btn = $('<div class="editor_button save disabled">Save changes</div>').css('margin-left', '5px');
|
|
87
|
+
google.maps.event.addDomListener(options.save_btn.get(0), 'click', function() {
|
|
88
|
+
if(!options.save_btn.hasClass('disabled')) {
|
|
89
|
+
ajax_update(options.selected_polygon);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(options.save_btn.get(0));
|
|
93
|
+
|
|
94
|
+
// --- Reset polygon ---
|
|
95
|
+
options.reset_btn = $('<div class="editor_button reset disabled">Reset region</div>').css('margin-left', '5px');
|
|
96
|
+
google.maps.event.addDomListener(options.reset_btn.get(0), 'click', function() {
|
|
97
|
+
if(!options.save_btn.hasClass('disabled')) {
|
|
98
|
+
reset_polygon(options.selected_polygon);
|
|
99
|
+
prepare_for_edit(options.selected_polygon);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(options.reset_btn.get(0));
|
|
103
|
+
|
|
104
|
+
// --- New region ---
|
|
105
|
+
options.new_region_btn = $('<div class="editor_button reset">New region</div>').css('margin-left', '5px');
|
|
106
|
+
google.maps.event.addDomListener(options.new_region_btn.get(0), 'click', function() {
|
|
107
|
+
switch(options.mode) {
|
|
108
|
+
case EDIT_MODE:
|
|
109
|
+
if(options.selected_polygon.has_changed) {
|
|
110
|
+
if(confirm('This region has changed. Discard changes?')) {
|
|
111
|
+
switch_to_mode(CREATE_MODE);
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
switch_to_mode(CREATE_MODE);
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
case CREATE_MODE:
|
|
118
|
+
if(options.selected_polygon == null) {
|
|
119
|
+
document.location = options.create_url;
|
|
120
|
+
} else {
|
|
121
|
+
switch_to_mode(EDIT_MODE);
|
|
122
|
+
prepare_for_edit(options.selected_polygon);
|
|
123
|
+
}
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(options.new_region_btn.get(0));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// -------------------------
|
|
131
|
+
// Changes between edit and create modes
|
|
132
|
+
// -------------------------
|
|
133
|
+
function switch_to_mode(mode) {
|
|
134
|
+
switch(mode) {
|
|
135
|
+
|
|
136
|
+
case CREATE_MODE:
|
|
137
|
+
reset_polygon(options.selected_polygon);
|
|
138
|
+
options.new_region_btn.html('Cancel');
|
|
139
|
+
options.mode = CREATE_MODE;
|
|
140
|
+
// Create the temporary polyline that will hold the region coordinates
|
|
141
|
+
options.tmp_poly = new google.maps.Polyline({
|
|
142
|
+
strokeColor: options.colors.red,
|
|
143
|
+
strokeOpacity: 1.0,
|
|
144
|
+
strokeWeight: 3
|
|
145
|
+
});
|
|
146
|
+
options.tmp_poly.setMap(map);
|
|
147
|
+
break;
|
|
148
|
+
|
|
149
|
+
case EDIT_MODE:
|
|
150
|
+
delete_vertices();
|
|
151
|
+
options.tmp_poly.setMap(null);
|
|
152
|
+
options.new_region_btn.html('New region');
|
|
153
|
+
options.mode = EDIT_MODE;
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// -------------------------
|
|
159
|
+
// Adds a new region to the map
|
|
160
|
+
// -------------------------
|
|
161
|
+
function add_region(index, region) {
|
|
162
|
+
// Prepare the coordinates for the polygon
|
|
163
|
+
var coordinates = new Array();
|
|
164
|
+
$.each(region.points, function(){
|
|
165
|
+
coordinates.push(new google.maps.LatLng(this[0], this[1]));
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Create the polygon
|
|
169
|
+
var polygon = new google.maps.Polygon({
|
|
170
|
+
paths: coordinates,
|
|
171
|
+
region_id: region.id,
|
|
172
|
+
region_index: index,
|
|
173
|
+
is_selected: false,
|
|
174
|
+
has_changed: false
|
|
175
|
+
});
|
|
176
|
+
polygon.setMap(map);
|
|
177
|
+
set_polygon_style(polygon, 'mouseout');
|
|
178
|
+
|
|
179
|
+
// Activate it if it's the seleted polygon
|
|
180
|
+
if(region.id == options.selected_region_id) {
|
|
181
|
+
prepare_for_edit(polygon);
|
|
182
|
+
$('.region_details').html(options.regions[options.selected_polygon.region_index].name);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// mouseover event
|
|
186
|
+
google.maps.event.addListener(polygon, 'mouseover', function(event) {
|
|
187
|
+
if(!polygon.is_selected && options.mode == EDIT_MODE) {
|
|
188
|
+
set_polygon_style(polygon, 'mouseover');
|
|
189
|
+
}
|
|
190
|
+
$('.region_details').html(options.regions[polygon.region_index].name);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// mouseout event
|
|
194
|
+
google.maps.event.addListener(polygon, 'mouseout', function() {
|
|
195
|
+
if(!polygon.is_selected && options.mode == EDIT_MODE) {
|
|
196
|
+
set_polygon_style(polygon, 'mouseout');
|
|
197
|
+
}
|
|
198
|
+
if(options.selected_polygon != null){
|
|
199
|
+
$('.region_details').html(options.regions[options.selected_polygon.region_index].name)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
});
|
|
203
|
+
// click event
|
|
204
|
+
google.maps.event.addListener(polygon, 'click', function() {
|
|
205
|
+
if(!polygon.is_selected && options.mode == EDIT_MODE) {
|
|
206
|
+
if(options.selected_polygon.has_changed) {
|
|
207
|
+
if(confirm('This region has changed. Discard changes?')) {
|
|
208
|
+
reset_polygon(options.selected_polygon);
|
|
209
|
+
prepare_for_edit(polygon);
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
reset_polygon(options.selected_polygon);
|
|
213
|
+
prepare_for_edit(polygon);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// -------------------------
|
|
221
|
+
// Changes the color of a polygon as well as any other options passed in style_options
|
|
222
|
+
// -------------------------
|
|
223
|
+
function set_polygon_style(polygon, style, style_options) {
|
|
224
|
+
switch(style) {
|
|
225
|
+
case 'mouseout':
|
|
226
|
+
defaults = {
|
|
227
|
+
strokeColor: options.colors.blue,
|
|
228
|
+
strokeOpacity: 0.8,
|
|
229
|
+
strokeWeight: 2,
|
|
230
|
+
fillColor: options.colors.blue,
|
|
231
|
+
fillOpacity: 0.1
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
case 'mouseover':
|
|
235
|
+
defaults = {
|
|
236
|
+
strokeColor: options.colors.red, //"#FF0000",
|
|
237
|
+
strokeOpacity: 0.8,
|
|
238
|
+
strokeWeight: 2,
|
|
239
|
+
}
|
|
240
|
+
break;
|
|
241
|
+
case 'selected':
|
|
242
|
+
defaults = {
|
|
243
|
+
strokeColor: options.colors.red, //"#FF0000",
|
|
244
|
+
strokeOpacity: 0.8,
|
|
245
|
+
strokeWeight: 2,
|
|
246
|
+
fillColor: options.colors.red, //"#FF0000",
|
|
247
|
+
fillOpacity: 0.35
|
|
248
|
+
}
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
style_options = $.extend(defaults, style_options);
|
|
252
|
+
polygon.setOptions(style_options);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// -------------------------
|
|
256
|
+
// Adds handlers to each vertex of a polygon so it can be edited
|
|
257
|
+
// -------------------------
|
|
258
|
+
function prepare_for_edit(polygon) {
|
|
259
|
+
// Add vertex handlers to the polygon
|
|
260
|
+
polygon.getPath().forEach(function(latlng, index){
|
|
261
|
+
var vertex = new BorderHandler(map, polygon, index, options);
|
|
262
|
+
options.vertices.push(vertex);
|
|
263
|
+
|
|
264
|
+
// Shift + click to delete this vertex
|
|
265
|
+
google.maps.event.addDomListener(vertex.marker, 'click', function(event) {
|
|
266
|
+
if(event.shiftKey) {
|
|
267
|
+
delete_point(polygon, index);
|
|
268
|
+
// [TODO] Finish region snap
|
|
269
|
+
// } else {
|
|
270
|
+
// if(vertex.circle == null) {
|
|
271
|
+
// vertex.create_circle();
|
|
272
|
+
// } else {
|
|
273
|
+
// vertex.delete_circle();
|
|
274
|
+
// }
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
set_polygon_style(polygon, 'selected', { is_selected: true });
|
|
281
|
+
options.selected_polygon = polygon;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// -------------------------
|
|
285
|
+
// Deletes all the vertices from the map
|
|
286
|
+
// -------------------------
|
|
287
|
+
function delete_vertices(){
|
|
288
|
+
for (v in options.vertices) {
|
|
289
|
+
if(options.mode == EDIT_MODE) {
|
|
290
|
+
options.vertices[v].marker.setMap(null);
|
|
291
|
+
} else if(options.mode == CREATE_MODE) {
|
|
292
|
+
options.vertices[v].setMap(null);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
options.vertices = new Array();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// -------------------------
|
|
299
|
+
// Returns a polygon to it's original coordinates
|
|
300
|
+
// -------------------------
|
|
301
|
+
function reset_polygon(polygon) {
|
|
302
|
+
if(polygon == null){
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
var coordinates = new Array();
|
|
306
|
+
$.each(options.regions[polygon.region_index].points, function(){
|
|
307
|
+
coordinates.push(new google.maps.LatLng(this[0], this[1]));
|
|
308
|
+
});
|
|
309
|
+
polygon.setPath(coordinates);
|
|
310
|
+
delete_vertices();
|
|
311
|
+
set_polygon_changed_status(polygon, false)
|
|
312
|
+
set_polygon_style(polygon, 'mouseout', { is_selected: false });
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// -------------------------
|
|
316
|
+
// Saves the changes on the selected polygon
|
|
317
|
+
// -------------------------
|
|
318
|
+
function ajax_update(polygon) {
|
|
319
|
+
new_points = new Array();
|
|
320
|
+
polygon.getPath().forEach(function(point, index){
|
|
321
|
+
new_points.push([point.lat(), point.lng()]);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
$.post(
|
|
325
|
+
options.update_url,
|
|
326
|
+
{
|
|
327
|
+
authenticity_token: $('meta[name=csrf-token]').attr('content'),
|
|
328
|
+
areas: [
|
|
329
|
+
{
|
|
330
|
+
id: polygon.region_id,
|
|
331
|
+
coordinates: new_points
|
|
332
|
+
}
|
|
333
|
+
]
|
|
334
|
+
},
|
|
335
|
+
function(){
|
|
336
|
+
// Update the regions array with the new saved coordinates
|
|
337
|
+
options.regions[polygon.region_index].points = new_points;
|
|
338
|
+
|
|
339
|
+
// Reset buttons state
|
|
340
|
+
set_polygon_changed_status(polygon, false)
|
|
341
|
+
|
|
342
|
+
// Notify the user
|
|
343
|
+
obj.prepend($('<div class="flash_message notice">Saved!</div>'));
|
|
344
|
+
setTimeout(function(){
|
|
345
|
+
$('.flash_message.notice').fadeOut('slow', function(){$(this).remove()});
|
|
346
|
+
}, 5000);
|
|
347
|
+
}
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// -------------------------
|
|
352
|
+
// Creates a new polygon
|
|
353
|
+
// -------------------------
|
|
354
|
+
function ajax_create(region_name) {
|
|
355
|
+
var polyline = options.tmp_poly;
|
|
356
|
+
new_points = new Array();
|
|
357
|
+
polyline.getPath().forEach(function(point, index){
|
|
358
|
+
new_points.push([point.lat(), point.lng()]);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
$.post(
|
|
362
|
+
options.create_url,
|
|
363
|
+
{
|
|
364
|
+
authenticity_token: $('meta[name=csrf-token]').attr('content'),
|
|
365
|
+
area: {
|
|
366
|
+
coordinates: new_points,
|
|
367
|
+
name: region_name
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
function(region_id){
|
|
371
|
+
document.location = options.create_url+'/'+region_id+'/edit_borders';
|
|
372
|
+
},
|
|
373
|
+
'json'
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
// -------------------------
|
|
380
|
+
// Adds a new point to the selected polygon
|
|
381
|
+
// -------------------------
|
|
382
|
+
function add_new_point_to_polygon(latLng) {
|
|
383
|
+
var polygon = options.selected_polygon;
|
|
384
|
+
var path = polygon.getPath();
|
|
385
|
+
var distance = {value: 10000, points: null};
|
|
386
|
+
var point_indexes = null;
|
|
387
|
+
var poly = null;
|
|
388
|
+
var flightPlanCoordinates = [
|
|
389
|
+
path.getAt(0),
|
|
390
|
+
path.getAt(1)
|
|
391
|
+
];
|
|
392
|
+
|
|
393
|
+
// Collect the distances between the new point and every polygon vertex
|
|
394
|
+
path.forEach(function(poly_latLng, index){
|
|
395
|
+
points = [index, index + 1];
|
|
396
|
+
if(index + 1 >= path.getLength()) {
|
|
397
|
+
points = [index, 0];
|
|
398
|
+
}
|
|
399
|
+
p1 = path.getAt(points[0]);
|
|
400
|
+
p2 = path.getAt(points[1]);
|
|
401
|
+
d = dotLineLength(latLng.lat(), latLng.lng(), p1.lat(), p1.lng(), p2.lat(), p2.lng(), true);
|
|
402
|
+
if(d < distance.value) {
|
|
403
|
+
distance = {value: d, points: points};
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
var coordinates = new Array();
|
|
408
|
+
var added_new_coordinate = false;
|
|
409
|
+
path.forEach(function(poly_latLng, index){
|
|
410
|
+
coordinates.push(poly_latLng);
|
|
411
|
+
|
|
412
|
+
points = [index, index + 1];
|
|
413
|
+
if(index + 1 >= path.getLength()) {
|
|
414
|
+
points = [index, 0];
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if(!added_new_coordinate && (points[0] == distance.points[0] && points[1] == distance.points[1])) {
|
|
418
|
+
coordinates.push(latLng);
|
|
419
|
+
added_new_coordinate = true;
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
polygon.setPath(coordinates);
|
|
423
|
+
set_polygon_changed_status(polygon, true)
|
|
424
|
+
delete_vertices();
|
|
425
|
+
prepare_for_edit(polygon)
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// -------------------------
|
|
429
|
+
// Deletes a point from a polygon
|
|
430
|
+
// -------------------------
|
|
431
|
+
function delete_point(polygon, index) {
|
|
432
|
+
if(polygon.getPath().getLength() == 3) {
|
|
433
|
+
alert('Cannot delete this point. A region must have at least 3 points.');
|
|
434
|
+
} else if(confirm('Delete this point?')) {
|
|
435
|
+
polygon.getPath().removeAt(index);
|
|
436
|
+
delete_vertices(polygon);
|
|
437
|
+
prepare_for_edit(polygon);
|
|
438
|
+
set_polygon_changed_status(polygon, true)
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// -------------------------
|
|
443
|
+
// Sets the changed status of a polygon and the control buttons
|
|
444
|
+
// -------------------------
|
|
445
|
+
function set_polygon_changed_status(polygon, changed) {
|
|
446
|
+
if(changed) {
|
|
447
|
+
polygon.has_changed = true;
|
|
448
|
+
options.save_btn.removeClass('disabled');
|
|
449
|
+
options.reset_btn.removeClass('disabled');
|
|
450
|
+
} else {
|
|
451
|
+
options.save_btn.addClass('disabled');
|
|
452
|
+
options.reset_btn.addClass('disabled');
|
|
453
|
+
polygon.has_changed = false;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function add_point_to_new_region(latLng) {
|
|
458
|
+
options.tmp_poly.getPath().push(latLng);
|
|
459
|
+
// Add a new marker at the new plotted point on the polyline.
|
|
460
|
+
var marker = new google.maps.Marker({
|
|
461
|
+
position: latLng,
|
|
462
|
+
map: map,
|
|
463
|
+
animation: google.maps.Animation.DROP,
|
|
464
|
+
clickable: (options.vertices.length == 0)
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
options.vertices.push(marker);
|
|
468
|
+
|
|
469
|
+
// Click to delete this vertex
|
|
470
|
+
google.maps.event.addDomListener(marker, 'click', function(event) {
|
|
471
|
+
if(options.tmp_poly.getPath().getLength() < 3) {
|
|
472
|
+
alert('Please add at least 3 points to the region before closing it.');
|
|
473
|
+
} else {
|
|
474
|
+
var region_name = prompt('Enter the name of the new region.');
|
|
475
|
+
if(region_name == null) {
|
|
476
|
+
switch_to_mode(EDIT_MODE);
|
|
477
|
+
prepare_for_edit(polygon);
|
|
478
|
+
} else {
|
|
479
|
+
ajax_create(region_name);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
};
|
|
488
|
+
})(jQuery);
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
/* --------------------------------------------------------------
|
|
492
|
+
* Creates a draggable marker and binds it to a vertext in a polygon
|
|
493
|
+
* @params
|
|
494
|
+
* {google.maps.Map} map: The map on which to attach the vertex widget. *
|
|
495
|
+
* {google.maps.Polygon} polygon: The polygon to which this vertex marker will bind to
|
|
496
|
+
* {int} index: The index of the point on the polygon to bind to
|
|
497
|
+
* Ref: http://code.google.com/apis/maps/articles/mvcfun.html
|
|
498
|
+
--------------------------------------------------------------*/
|
|
499
|
+
function BorderHandler(map, polygon, index, options) {
|
|
500
|
+
var me = this;
|
|
501
|
+
this.map = map;
|
|
502
|
+
this.circle = null;
|
|
503
|
+
this.set('map', map);
|
|
504
|
+
this.set('position', polygon.getPath().getAt(index));
|
|
505
|
+
this.set('marker', new google.maps.Marker({draggable: true, title: 'index: '+index}));
|
|
506
|
+
this.marker.bindTo('map', this);
|
|
507
|
+
this.marker.bindTo('position', this)
|
|
508
|
+
|
|
509
|
+
google.maps.event.addListener(this.marker, 'drag', function() {
|
|
510
|
+
if(polygon.has_changed == false) {
|
|
511
|
+
polygon.has_changed = true;
|
|
512
|
+
options.save_btn.removeClass('disabled');
|
|
513
|
+
options.reset_btn.removeClass('disabled');
|
|
514
|
+
}
|
|
515
|
+
// update the polygon vertex
|
|
516
|
+
polygon.getPath().setAt(index, this.get('position'));
|
|
517
|
+
|
|
518
|
+
// Update the center of the circle
|
|
519
|
+
if(me.circle != null) {
|
|
520
|
+
me.circle.set('center', this.get('position'))
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
BorderHandler.prototype = new google.maps.MVCObject();
|
|
526
|
+
|
|
527
|
+
BorderHandler.prototype.create_circle = function(){
|
|
528
|
+
if(this.circle == null) {
|
|
529
|
+
this.circle = new RadiusWidget();
|
|
530
|
+
this.circle.bindTo('map', this);
|
|
531
|
+
this.circle.bindTo('center', this, 'position');
|
|
532
|
+
this.bindTo('distance', this.circle);
|
|
533
|
+
this.bindTo('bounds', this.circle);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
BorderHandler.prototype.delete_circle = function(){
|
|
538
|
+
if(this.circle != null) {
|
|
539
|
+
this.circle.unbind('map');
|
|
540
|
+
this.circle.circle.setMap(null);
|
|
541
|
+
this.circle.sizer.setMap(null);
|
|
542
|
+
this.circle = null;
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
/* --------------------------------------------------------------
|
|
548
|
+
* A radius widget that adds a circle to a map and centers on a marker.
|
|
549
|
+
--------------------------------------------------------------*/
|
|
550
|
+
function RadiusWidget() {
|
|
551
|
+
this.circle = new google.maps.Circle({
|
|
552
|
+
strokeWeight: 2
|
|
553
|
+
});
|
|
554
|
+
this.set('distance', 1);
|
|
555
|
+
this.bindTo('bounds', this.circle);
|
|
556
|
+
this.circle.bindTo('center', this);
|
|
557
|
+
this.circle.bindTo('map', this);
|
|
558
|
+
this.circle.bindTo('radius', this);
|
|
559
|
+
this.addSizer_();
|
|
560
|
+
}
|
|
561
|
+
RadiusWidget.prototype = new google.maps.MVCObject();
|
|
562
|
+
|
|
563
|
+
// Update the radius when the distance has changed.
|
|
564
|
+
RadiusWidget.prototype.distance_changed = function() {
|
|
565
|
+
this.set('radius', this.get('distance') * 1000);
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
RadiusWidget.prototype.addSizer_ = function() {
|
|
569
|
+
var me = this;
|
|
570
|
+
this.sizer = new google.maps.Marker({
|
|
571
|
+
draggable: true,
|
|
572
|
+
title: 'Drag me!'
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
this.sizer.bindTo('map', this);
|
|
576
|
+
this.sizer.bindTo('position', this, 'sizer_position');
|
|
577
|
+
|
|
578
|
+
google.maps.event.addListener(this.sizer, 'drag', function() {
|
|
579
|
+
var pos = me.get('sizer_position');
|
|
580
|
+
var center = me.get('center');
|
|
581
|
+
var distance = google.maps.geometry.spherical.computeDistanceBetween(center, pos) / 1000
|
|
582
|
+
me.set('distance', distance);
|
|
583
|
+
});
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
RadiusWidget.prototype.center_changed = function() {
|
|
587
|
+
var bounds = this.get('bounds');
|
|
588
|
+
|
|
589
|
+
// Bounds might not always be set so check that it exists first.
|
|
590
|
+
if (bounds) {
|
|
591
|
+
var lng = bounds.getNorthEast().lng();
|
|
592
|
+
|
|
593
|
+
// Put the sizer at center, right on the circle.
|
|
594
|
+
var position = new google.maps.LatLng(this.get('center').lat(), lng);
|
|
595
|
+
this.set('sizer_position', position);
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
dotLineLength = function(x, y, x0, y0, x1, y1, o){
|
|
600
|
+
function lineLength(x, y, x0, y0){
|
|
601
|
+
return Math.sqrt((x -= x0) * x + (y -= y0) * y);
|
|
602
|
+
}
|
|
603
|
+
if(o && !(o = function(x, y, x0, y0, x1, y1){
|
|
604
|
+
if(!(x1 - x0)) return {x: x0, y: y};
|
|
605
|
+
else if(!(y1 - y0)) return {x: x, y: y0};
|
|
606
|
+
var left, tg = -1 / ((y1 - y0) / (x1 - x0));
|
|
607
|
+
return {x: left = (x1 * (x * tg - y + y0) + x0 * (x * - tg + y - y1)) / (tg * (x1 - x0) + y0 - y1), y: tg * left - tg * x + y};
|
|
608
|
+
}(x, y, x0, y0, x1, y1), o.x >= Math.min(x0, x1) && o.x <= Math.max(x0, x1) && o.y >= Math.min(y0, y1) && o.y <= Math.max(y0, y1))){
|
|
609
|
+
var l1 = lineLength(x, y, x0, y0), l2 = lineLength(x, y, x1, y1);
|
|
610
|
+
return l1 > l2 ? l2 : l1;
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
var a = y0 - y1, b = x1 - x0, c = x0 * y1 - y0 * x1;
|
|
614
|
+
return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b);
|
|
615
|
+
}
|
|
616
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
function get_user_activity(user_name, url, delay) {
|
|
2
|
+
$.ajax({
|
|
3
|
+
type: "GET",
|
|
4
|
+
url: "/admin/user_activity/" + user_name,
|
|
5
|
+
data: {
|
|
6
|
+
url : url,
|
|
7
|
+
authenticity_token: $('meta[name=csrf-token]').attr('content')
|
|
8
|
+
},
|
|
9
|
+
success: function(data){
|
|
10
|
+
setTimeout('get_user_activity(\''+ user_name +'\', \''+ url +'\', \''+ delay +'\')', delay);
|
|
11
|
+
$('#user_activity').html(data);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
function update_user_activity(user_name, url, delay) {
|
|
18
|
+
$.ajax({
|
|
19
|
+
type: "PUT",
|
|
20
|
+
url: "/admin/user_activity/" + user_name,
|
|
21
|
+
data: ({
|
|
22
|
+
url : url,
|
|
23
|
+
authenticity_token: $('meta[name=csrf-token]').attr('content')
|
|
24
|
+
}),
|
|
25
|
+
success: function(data){
|
|
26
|
+
setTimeout('update_user_activity(\''+ user_name +'\', \''+ url +'\', \''+ delay +'\')', delay);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
data/public/robots.txt
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|