blueshift 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +74 -0
  6. data/Rakefile +1 -0
  7. data/app/assets/fonts/gotham/gotham-bold.eot +0 -0
  8. data/app/assets/fonts/gotham/gotham-bold.svg +628 -0
  9. data/app/assets/fonts/gotham/gotham-bold.ttf +0 -0
  10. data/app/assets/fonts/gotham/gotham-bold.woff +0 -0
  11. data/app/assets/fonts/gotham/gotham-book.eot +0 -0
  12. data/app/assets/fonts/gotham/gotham-book.svg +631 -0
  13. data/app/assets/fonts/gotham/gotham-book.ttf +0 -0
  14. data/app/assets/fonts/gotham/gotham-book.woff +0 -0
  15. data/app/assets/fonts/gotham/gotham-light.eot +0 -0
  16. data/app/assets/fonts/gotham/gotham-light.svg +635 -0
  17. data/app/assets/fonts/gotham/gotham-light.ttf +0 -0
  18. data/app/assets/fonts/gotham/gotham-light.woff +0 -0
  19. data/app/assets/fonts/gotham/gotham-medium.eot +0 -0
  20. data/app/assets/fonts/gotham/gotham-medium.svg +629 -0
  21. data/app/assets/fonts/gotham/gotham-medium.ttf +0 -0
  22. data/app/assets/fonts/gotham/gotham-medium.woff +0 -0
  23. data/app/assets/fonts/ionicons/ionicons.eot +0 -0
  24. data/app/assets/fonts/ionicons/ionicons.svg +2254 -0
  25. data/app/assets/fonts/ionicons/ionicons.ttf +0 -0
  26. data/app/assets/fonts/ionicons/ionicons.woff +0 -0
  27. data/blueshift.gemspec +23 -0
  28. data/lib/blueshift.rb +6 -0
  29. data/lib/blueshift/version.rb +3 -0
  30. data/vendor/assets/javascripts/alert.js +99 -0
  31. data/vendor/assets/javascripts/collapse.js +167 -0
  32. data/vendor/assets/javascripts/date_picker.js +474 -0
  33. data/vendor/assets/javascripts/dropdown.js +169 -0
  34. data/vendor/assets/javascripts/file_input.js +100 -0
  35. data/vendor/assets/javascripts/map.js +2044 -0
  36. data/vendor/assets/javascripts/modal (1).js +247 -0
  37. data/vendor/assets/javascripts/modal.js +247 -0
  38. data/vendor/assets/javascripts/popover.js +114 -0
  39. data/vendor/assets/javascripts/tab.js +144 -0
  40. data/vendor/assets/javascripts/time_picker.js +888 -0
  41. data/vendor/assets/javascripts/tooltip.js +361 -0
  42. data/vendor/assets/javascripts/transitions.js +60 -0
  43. data/vendor/assets/stylesheets/ad.css.scss +72 -0
  44. data/vendor/assets/stylesheets/alert.css.scss +40 -0
  45. data/vendor/assets/stylesheets/breadcrumb.css.scss +22 -0
  46. data/vendor/assets/stylesheets/button.css.scss +202 -0
  47. data/vendor/assets/stylesheets/code.css.scss +49 -0
  48. data/vendor/assets/stylesheets/collapse.css.scss +14 -0
  49. data/vendor/assets/stylesheets/datepicker.css.scss +102 -0
  50. data/vendor/assets/stylesheets/dropdown.css.scss +84 -0
  51. data/vendor/assets/stylesheets/footer.css.scss +33 -0
  52. data/vendor/assets/stylesheets/form.css.scss +207 -0
  53. data/vendor/assets/stylesheets/grid.css.scss +291 -0
  54. data/vendor/assets/stylesheets/header.css.scss +134 -0
  55. data/vendor/assets/stylesheets/icon.css.scss +966 -0
  56. data/vendor/assets/stylesheets/image.css.scss +39 -0
  57. data/vendor/assets/stylesheets/label_and_badge.css.scss +53 -0
  58. data/vendor/assets/stylesheets/link.css.scss +19 -0
  59. data/vendor/assets/stylesheets/list.css.scss +38 -0
  60. data/vendor/assets/stylesheets/map.css.scss +13 -0
  61. data/vendor/assets/stylesheets/modal.css.scss +117 -0
  62. data/vendor/assets/stylesheets/pagination.css.scss +37 -0
  63. data/vendor/assets/stylesheets/placeholder.css.scss +11 -0
  64. data/vendor/assets/stylesheets/popover.css.scss +107 -0
  65. data/vendor/assets/stylesheets/progress.css.scss +25 -0
  66. data/vendor/assets/stylesheets/reset.css.scss +57 -0
  67. data/vendor/assets/stylesheets/tab.css.scss +165 -0
  68. data/vendor/assets/stylesheets/table.css.scss +70 -0
  69. data/vendor/assets/stylesheets/timepicker.css.scss +69 -0
  70. data/vendor/assets/stylesheets/tooltip.css.scss +81 -0
  71. data/vendor/assets/stylesheets/transitions.css.scss +12 -0
  72. data/vendor/assets/stylesheets/trunk.css.scss +72 -0
  73. data/vendor/assets/stylesheets/typography.css.scss +140 -0
  74. metadata +145 -0
@@ -0,0 +1,169 @@
1
+ /* ============================================================
2
+ * bootstrap-dropdown.js v2.3.2
3
+ * http://getbootstrap.com/2.3.2/javascript.html#dropdowns
4
+ * ============================================================
5
+ * Copyright 2013 Twitter, Inc.
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ * ============================================================ */
19
+
20
+
21
+ !function ($) {
22
+
23
+ "use strict"; // jshint ;_;
24
+
25
+
26
+ /* DROPDOWN CLASS DEFINITION
27
+ * ========================= */
28
+
29
+ var toggle = '[data-toggle=dropdown]'
30
+ , Dropdown = function (element) {
31
+ var $el = $(element).on('click.dropdown.data-api', this.toggle)
32
+ $('html').on('click.dropdown.data-api', function () {
33
+ $el.parent().removeClass('open')
34
+ })
35
+ }
36
+
37
+ Dropdown.prototype = {
38
+
39
+ constructor: Dropdown
40
+
41
+ , toggle: function (e) {
42
+ var $this = $(this)
43
+ , $parent
44
+ , isActive
45
+
46
+ if ($this.is('.disabled, :disabled')) return
47
+
48
+ $parent = getParent($this)
49
+
50
+ isActive = $parent.hasClass('open')
51
+
52
+ clearMenus()
53
+
54
+ if (!isActive) {
55
+ if ('ontouchstart' in document.documentElement) {
56
+ // if mobile we we use a backdrop because click events don't delegate
57
+ $('<div class="dropdown-backdrop"/>').insertBefore($(this)).on('click', clearMenus)
58
+ }
59
+ $parent.toggleClass('open')
60
+ }
61
+
62
+ $this.focus()
63
+
64
+ return false
65
+ }
66
+
67
+ , keydown: function (e) {
68
+ var $this
69
+ , $items
70
+ , $active
71
+ , $parent
72
+ , isActive
73
+ , index
74
+
75
+ if (!/(38|40|27)/.test(e.keyCode)) return
76
+
77
+ $this = $(this)
78
+
79
+ e.preventDefault()
80
+ e.stopPropagation()
81
+
82
+ if ($this.is('.disabled, :disabled')) return
83
+
84
+ $parent = getParent($this)
85
+
86
+ isActive = $parent.hasClass('open')
87
+
88
+ if (!isActive || (isActive && e.keyCode == 27)) {
89
+ if (e.which == 27) $parent.find(toggle).focus()
90
+ return $this.click()
91
+ }
92
+
93
+ $items = $('[role=menu] li:not(.divider):visible a', $parent)
94
+
95
+ if (!$items.length) return
96
+
97
+ index = $items.index($items.filter(':focus'))
98
+
99
+ if (e.keyCode == 38 && index > 0) index-- // up
100
+ if (e.keyCode == 40 && index < $items.length - 1) index++ // down
101
+ if (!~index) index = 0
102
+
103
+ $items
104
+ .eq(index)
105
+ .focus()
106
+ }
107
+
108
+ }
109
+
110
+ function clearMenus() {
111
+ $('.dropdown-backdrop').remove()
112
+ $(toggle).each(function () {
113
+ getParent($(this)).removeClass('open')
114
+ })
115
+ }
116
+
117
+ function getParent($this) {
118
+ var selector = $this.attr('data-target')
119
+ , $parent
120
+
121
+ if (!selector) {
122
+ selector = $this.attr('href')
123
+ selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
124
+ }
125
+
126
+ $parent = selector && $(selector)
127
+
128
+ if (!$parent || !$parent.length) $parent = $this.parent()
129
+
130
+ return $parent
131
+ }
132
+
133
+
134
+ /* DROPDOWN PLUGIN DEFINITION
135
+ * ========================== */
136
+
137
+ var old = $.fn.dropdown
138
+
139
+ $.fn.dropdown = function (option) {
140
+ return this.each(function () {
141
+ var $this = $(this)
142
+ , data = $this.data('dropdown')
143
+ if (!data) $this.data('dropdown', (data = new Dropdown(this)))
144
+ if (typeof option == 'string') data[option].call($this)
145
+ })
146
+ }
147
+
148
+ $.fn.dropdown.Constructor = Dropdown
149
+
150
+
151
+ /* DROPDOWN NO CONFLICT
152
+ * ==================== */
153
+
154
+ $.fn.dropdown.noConflict = function () {
155
+ $.fn.dropdown = old
156
+ return this
157
+ }
158
+
159
+
160
+ /* APPLY TO STANDARD DROPDOWN ELEMENTS
161
+ * =================================== */
162
+
163
+ $(document)
164
+ .on('click.dropdown.data-api', clearMenus)
165
+ .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
166
+ .on('click.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
167
+ .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
168
+
169
+ }(window.jQuery);
@@ -0,0 +1,100 @@
1
+ /*
2
+ Bootstrap - File Input
3
+ ======================
4
+
5
+ This is meant to convert all file input tags into a set of elements that displays consistently in all browsers.
6
+
7
+ Converts all
8
+ <input type="file">
9
+ into Bootstrap buttons
10
+ <a class="btn">Browse</a>
11
+
12
+ */
13
+ $(function() {
14
+
15
+ $('input[type=file].btn-file').each(function(i,elem){
16
+
17
+ // Maybe some fields don't need to be standardized.
18
+ if (typeof $(this).attr('data-bfi-disabled') != 'undefined') {
19
+ return;
20
+ }
21
+
22
+ // Set the word to be displayed on the button
23
+ var buttonWord = 'Browse';
24
+
25
+ if (typeof $(this).attr('title') != 'undefined') {
26
+ buttonWord = $(this).attr('title');
27
+ }
28
+
29
+ // Start by getting the HTML of the input element.
30
+ // Thanks for the tip http://stackoverflow.com/a/1299069
31
+ var input = $('<div>').append( $(elem).eq(0).clone() ).html();
32
+
33
+ // Now we're going to replace that input field with a Bootstrap button.
34
+ // The input will actually still be there, it will just be float above and transparent (done with the CSS).
35
+ $(elem).replaceWith('<a class="file-input-wrapper btn btn-block">'+buttonWord+input+'</a>');
36
+ })
37
+ // After we have found all of the file inputs let's apply a listener for tracking the mouse movement.
38
+ // This is important because the in order to give the illusion that this is a button in FF we actually need to move the button from the file input under the cursor. Ugh.
39
+ .promise().done( function(){
40
+
41
+ // As the cursor moves over our new Bootstrap button we need to adjust the position of the invisible file input Browse button to be under the cursor.
42
+ // This gives us the pointer cursor that FF denies us
43
+ $('.file-input-wrapper').mousemove(function(cursor) {
44
+
45
+ var input, wrapper,
46
+ wrapperX, wrapperY,
47
+ inputWidth, inputHeight,
48
+ cursorX, cursorY;
49
+
50
+ // This wrapper element (the button surround this file input)
51
+ wrapper = $(this);
52
+ // The invisible file input element
53
+ input = wrapper.find("input");
54
+ // The left-most position of the wrapper
55
+ wrapperX = wrapper.offset().left;
56
+ // The top-most position of the wrapper
57
+ wrapperY = wrapper.offset().top;
58
+ // The with of the browsers input field
59
+ inputWidth= input.width();
60
+ // The height of the browsers input field
61
+ inputHeight= input.height();
62
+ //The position of the cursor in the wrapper
63
+ cursorX = cursor.pageX;
64
+ cursorY = cursor.pageY;
65
+
66
+ //The positions we are to move the invisible file input
67
+ // The 20 at the end is an arbitrary number of pixels that we can shift the input such that cursor is not pointing at the end of the Browse button but somewhere nearer the middle
68
+ moveInputX = cursorX - wrapperX - inputWidth + 20;
69
+ // Slides the invisible input Browse button to be positioned middle under the cursor
70
+ moveInputY = cursorY- wrapperY - (inputHeight/2);
71
+
72
+ // Apply the positioning styles to actually move the invisible file input
73
+ input.css({
74
+ left:moveInputX,
75
+ top:moveInputY
76
+ });
77
+ });
78
+
79
+ $('.file-input-wrapper input[type=file]').change(function(){
80
+
81
+ // Remove any previous file names
82
+ $(this).parent().next().has('file-input-name').remove();
83
+ $(this).parent().after('<span class="file-input-name">'+$(this).val()+'</span>');
84
+
85
+ });
86
+
87
+
88
+
89
+ });
90
+
91
+ // Add the styles before the first stylesheet
92
+ // This ensures they can be easily overridden with developer styles
93
+ var cssHtml = '<style>'+
94
+ '.file-input-wrapper { overflow: hidden; position: relative; cursor: pointer; z-index: 1; }'+
95
+ '.file-input-wrapper input[type=file], .file-input-wrapper input[type=file]:focus, .file-input-wrapper input[type=file]:hover { position: absolute; top: 0; left: 0; cursor: pointer; opacity: 0; filter: alpha(opacity=0); z-index: 99; outline: 0; }'+
96
+ '.file-input-name { margin-left: 8px; }'+
97
+ '</style>';
98
+ $('link[rel=stylesheet]').eq(0).before(cssHtml);
99
+
100
+ });
@@ -0,0 +1,2044 @@
1
+ /*!
2
+ * GMaps.js v0.4.8
3
+ * http://hpneo.github.com/gmaps/
4
+ *
5
+ * Copyright 2013, Gustavo Leon
6
+ * Released under the MIT License.
7
+ */
8
+
9
+ if (!(typeof window.google === 'object' && window.google.maps)) {
10
+ throw 'Google Maps API is required. Please register the following JavaScript library http://maps.google.com/maps/api/js?sensor=true.'
11
+ }
12
+
13
+ var extend_object = function(obj, new_obj) {
14
+ var name;
15
+
16
+ if (obj === new_obj) {
17
+ return obj;
18
+ }
19
+
20
+ for (name in new_obj) {
21
+ obj[name] = new_obj[name];
22
+ }
23
+
24
+ return obj;
25
+ };
26
+
27
+ var replace_object = function(obj, replace) {
28
+ var name;
29
+
30
+ if (obj === replace) {
31
+ return obj;
32
+ }
33
+
34
+ for (name in replace) {
35
+ if (obj[name] != undefined) {
36
+ obj[name] = replace[name];
37
+ }
38
+ }
39
+
40
+ return obj;
41
+ };
42
+
43
+ var array_map = function(array, callback) {
44
+ var original_callback_params = Array.prototype.slice.call(arguments, 2),
45
+ array_return = [],
46
+ array_length = array.length,
47
+ i;
48
+
49
+ if (Array.prototype.map && array.map === Array.prototype.map) {
50
+ array_return = Array.prototype.map.call(array, function(item) {
51
+ callback_params = original_callback_params;
52
+ callback_params.splice(0, 0, item);
53
+
54
+ return callback.apply(this, callback_params);
55
+ });
56
+ }
57
+ else {
58
+ for (i = 0; i < array_length; i++) {
59
+ callback_params = original_callback_params;
60
+ callback_params.splice(0, 0, array[i]);
61
+ array_return.push(callback.apply(this, callback_params));
62
+ }
63
+ }
64
+
65
+ return array_return;
66
+ };
67
+
68
+ var array_flat = function(array) {
69
+ var new_array = [],
70
+ i;
71
+
72
+ for (i = 0; i < array.length; i++) {
73
+ new_array = new_array.concat(array[i]);
74
+ }
75
+
76
+ return new_array;
77
+ };
78
+
79
+ var coordsToLatLngs = function(coords, useGeoJSON) {
80
+ var first_coord = coords[0],
81
+ second_coord = coords[1];
82
+
83
+ if (useGeoJSON) {
84
+ first_coord = coords[1];
85
+ second_coord = coords[0];
86
+ }
87
+
88
+ return new google.maps.LatLng(first_coord, second_coord);
89
+ };
90
+
91
+ var arrayToLatLng = function(coords, useGeoJSON) {
92
+ var i;
93
+
94
+ for (i = 0; i < coords.length; i++) {
95
+ if (coords[i].length > 0 && typeof(coords[i][0]) == "object") {
96
+ coords[i] = arrayToLatLng(coords[i], useGeoJSON);
97
+ }
98
+ else {
99
+ coords[i] = coordsToLatLngs(coords[i], useGeoJSON);
100
+ }
101
+ }
102
+
103
+ return coords;
104
+ };
105
+
106
+ var getElementById = function(id, context) {
107
+ var element,
108
+ id = id.replace('#', '');
109
+
110
+ if ('jQuery' in this && context) {
111
+ element = $("#" + id, context)[0];
112
+ } else {
113
+ element = document.getElementById(id);
114
+ };
115
+
116
+ return element;
117
+ };
118
+
119
+ var findAbsolutePosition = function(obj) {
120
+ var curleft = 0,
121
+ curtop = 0;
122
+
123
+ if (obj.offsetParent) {
124
+ do {
125
+ curleft += obj.offsetLeft;
126
+ curtop += obj.offsetTop;
127
+ } while (obj = obj.offsetParent);
128
+ }
129
+
130
+ return [curleft, curtop];
131
+ };
132
+
133
+ var GMaps = (function(global) {
134
+ "use strict";
135
+
136
+ var doc = document;
137
+
138
+ var GMaps = function(options) {
139
+ if (!this) return new GMaps(options);
140
+
141
+ options.zoom = options.zoom || 15;
142
+ options.mapType = options.mapType || 'roadmap';
143
+
144
+ var self = this,
145
+ i,
146
+ events_that_hide_context_menu = ['bounds_changed', 'center_changed', 'click', 'dblclick', 'drag', 'dragend', 'dragstart', 'idle', 'maptypeid_changed', 'projection_changed', 'resize', 'tilesloaded', 'zoom_changed'],
147
+ events_that_doesnt_hide_context_menu = ['mousemove', 'mouseout', 'mouseover'],
148
+ options_to_be_deleted = ['el', 'lat', 'lng', 'mapType', 'width', 'height', 'markerClusterer', 'enableNewStyle'],
149
+ container_id = options.el || options.div,
150
+ markerClustererFunction = options.markerClusterer,
151
+ mapType = google.maps.MapTypeId[options.mapType.toUpperCase()],
152
+ map_center = new google.maps.LatLng(options.lat, options.lng),
153
+ zoomControl = options.zoomControl || true,
154
+ zoomControlOpt = options.zoomControlOpt || {
155
+ style: 'DEFAULT',
156
+ position: 'TOP_LEFT'
157
+ },
158
+ zoomControlStyle = zoomControlOpt.style || 'DEFAULT',
159
+ zoomControlPosition = zoomControlOpt.position || 'TOP_LEFT',
160
+ panControl = options.panControl || true,
161
+ mapTypeControl = options.mapTypeControl || true,
162
+ scaleControl = options.scaleControl || true,
163
+ streetViewControl = options.streetViewControl || true,
164
+ overviewMapControl = overviewMapControl || true,
165
+ map_options = {},
166
+ map_base_options = {
167
+ zoom: this.zoom,
168
+ center: map_center,
169
+ mapTypeId: mapType
170
+ },
171
+ map_controls_options = {
172
+ panControl: panControl,
173
+ zoomControl: zoomControl,
174
+ zoomControlOptions: {
175
+ style: google.maps.ZoomControlStyle[zoomControlStyle],
176
+ position: google.maps.ControlPosition[zoomControlPosition]
177
+ },
178
+ mapTypeControl: mapTypeControl,
179
+ scaleControl: scaleControl,
180
+ streetViewControl: streetViewControl,
181
+ overviewMapControl: overviewMapControl
182
+ };
183
+
184
+ if (typeof(options.el) === 'string' || typeof(options.div) === 'string') {
185
+ this.el = getElementById(container_id, options.context);
186
+ } else {
187
+ this.el = container_id;
188
+ }
189
+
190
+ if (typeof(this.el) === 'undefined' || this.el === null) {
191
+ throw 'No element defined.';
192
+ }
193
+
194
+ window.context_menu = window.context_menu || {};
195
+ window.context_menu[self.el.id] = {};
196
+
197
+ this.controls = [];
198
+ this.overlays = [];
199
+ this.layers = []; // array with kml/georss and fusiontables layers, can be as many
200
+ this.singleLayers = {}; // object with the other layers, only one per layer
201
+ this.markers = [];
202
+ this.polylines = [];
203
+ this.routes = [];
204
+ this.polygons = [];
205
+ this.infoWindow = null;
206
+ this.overlay_el = null;
207
+ this.zoom = options.zoom;
208
+ this.registered_events = {};
209
+
210
+ this.el.style.width = options.width || this.el.scrollWidth || this.el.offsetWidth;
211
+ this.el.style.height = options.height || this.el.scrollHeight || this.el.offsetHeight;
212
+
213
+ google.maps.visualRefresh = options.enableNewStyle;
214
+
215
+ for (i = 0; i < options_to_be_deleted.length; i++) {
216
+ delete options[options_to_be_deleted[i]];
217
+ }
218
+
219
+ if(options.disableDefaultUI != true) {
220
+ map_base_options = extend_object(map_base_options, map_controls_options);
221
+ }
222
+
223
+ map_options = extend_object(map_base_options, options);
224
+
225
+ for (i = 0; i < events_that_hide_context_menu.length; i++) {
226
+ delete map_options[events_that_hide_context_menu[i]];
227
+ }
228
+
229
+ for (i = 0; i < events_that_doesnt_hide_context_menu.length; i++) {
230
+ delete map_options[events_that_doesnt_hide_context_menu[i]];
231
+ }
232
+
233
+ this.map = new google.maps.Map(this.el, map_options);
234
+
235
+ if (markerClustererFunction) {
236
+ this.markerClusterer = markerClustererFunction.apply(this, [this.map]);
237
+ }
238
+
239
+ var buildContextMenuHTML = function(control, e) {
240
+ var html = '',
241
+ options = window.context_menu[self.el.id][control];
242
+
243
+ for (var i in options){
244
+ if (options.hasOwnProperty(i)) {
245
+ var option = options[i];
246
+
247
+ html += '<li><a id="' + control + '_' + i + '" href="#">' + option.title + '</a></li>';
248
+ }
249
+ }
250
+
251
+ if (!getElementById('gmaps_context_menu')) return;
252
+
253
+ var context_menu_element = getElementById('gmaps_context_menu');
254
+
255
+ context_menu_element.innerHTML = html;
256
+
257
+ var context_menu_items = context_menu_element.getElementsByTagName('a'),
258
+ context_menu_items_count = context_menu_items.length
259
+ i;
260
+
261
+ for (i = 0; i < context_menu_items_count; i++) {
262
+ var context_menu_item = context_menu_items[i];
263
+
264
+ var assign_menu_item_action = function(ev){
265
+ ev.preventDefault();
266
+
267
+ options[this.id.replace(control + '_', '')].action.apply(self, [e]);
268
+ self.hideContextMenu();
269
+ };
270
+
271
+ google.maps.event.clearListeners(context_menu_item, 'click');
272
+ google.maps.event.addDomListenerOnce(context_menu_item, 'click', assign_menu_item_action, false);
273
+ }
274
+
275
+ var position = findAbsolutePosition.apply(this, [self.el]),
276
+ left = position[0] + e.pixel.x - 15,
277
+ top = position[1] + e.pixel.y- 15;
278
+
279
+ context_menu_element.style.left = left + "px";
280
+ context_menu_element.style.top = top + "px";
281
+
282
+ context_menu_element.style.display = 'block';
283
+ };
284
+
285
+ this.buildContextMenu = function(control, e) {
286
+ if (control === 'marker') {
287
+ e.pixel = {};
288
+
289
+ var overlay = new google.maps.OverlayView();
290
+ overlay.setMap(self.map);
291
+
292
+ overlay.draw = function() {
293
+ var projection = overlay.getProjection(),
294
+ position = e.marker.getPosition();
295
+
296
+ e.pixel = projection.fromLatLngToContainerPixel(position);
297
+
298
+ buildContextMenuHTML(control, e);
299
+ };
300
+ }
301
+ else {
302
+ buildContextMenuHTML(control, e);
303
+ }
304
+ };
305
+
306
+ this.setContextMenu = function(options) {
307
+ window.context_menu[self.el.id][options.control] = {};
308
+
309
+ var i,
310
+ ul = doc.createElement('ul');
311
+
312
+ for (i in options.options) {
313
+ if (options.options.hasOwnProperty(i)) {
314
+ var option = options.options[i];
315
+
316
+ window.context_menu[self.el.id][options.control][option.name] = {
317
+ title: option.title,
318
+ action: option.action
319
+ };
320
+ }
321
+ }
322
+
323
+ ul.id = 'gmaps_context_menu';
324
+ ul.style.display = 'none';
325
+ ul.style.position = 'absolute';
326
+ ul.style.minWidth = '100px';
327
+ ul.style.background = 'white';
328
+ ul.style.listStyle = 'none';
329
+ ul.style.padding = '8px';
330
+ ul.style.boxShadow = '2px 2px 6px #ccc';
331
+
332
+ doc.body.appendChild(ul);
333
+
334
+ var context_menu_element = getElementById('gmaps_context_menu')
335
+
336
+ google.maps.event.addDomListener(context_menu_element, 'mouseout', function(ev) {
337
+ if (!ev.relatedTarget || !this.contains(ev.relatedTarget)) {
338
+ window.setTimeout(function(){
339
+ context_menu_element.style.display = 'none';
340
+ }, 400);
341
+ }
342
+ }, false);
343
+ };
344
+
345
+ this.hideContextMenu = function() {
346
+ var context_menu_element = getElementById('gmaps_context_menu');
347
+
348
+ if (context_menu_element) {
349
+ context_menu_element.style.display = 'none';
350
+ }
351
+ };
352
+
353
+ var setupListener = function(object, name) {
354
+ google.maps.event.addListener(object, name, function(e){
355
+ if (e == undefined) {
356
+ e = this;
357
+ }
358
+
359
+ options[name].apply(this, [e]);
360
+
361
+ self.hideContextMenu();
362
+ });
363
+ };
364
+
365
+ for (var ev = 0; ev < events_that_hide_context_menu.length; ev++) {
366
+ var name = events_that_hide_context_menu[ev];
367
+
368
+ if (name in options) {
369
+ setupListener(this.map, name);
370
+ }
371
+ }
372
+
373
+ for (var ev = 0; ev < events_that_doesnt_hide_context_menu.length; ev++) {
374
+ var name = events_that_doesnt_hide_context_menu[ev];
375
+
376
+ if (name in options) {
377
+ setupListener(this.map, name);
378
+ }
379
+ }
380
+
381
+ google.maps.event.addListener(this.map, 'rightclick', function(e) {
382
+ if (options.rightclick) {
383
+ options.rightclick.apply(this, [e]);
384
+ }
385
+
386
+ if(window.context_menu[self.el.id]['map'] != undefined) {
387
+ self.buildContextMenu('map', e);
388
+ }
389
+ });
390
+
391
+ this.refresh = function() {
392
+ google.maps.event.trigger(this.map, 'resize');
393
+ };
394
+
395
+ this.fitZoom = function() {
396
+ var latLngs = [],
397
+ markers_length = this.markers.length,
398
+ i;
399
+
400
+ for (i = 0; i < markers_length; i++) {
401
+ latLngs.push(this.markers[i].getPosition());
402
+ }
403
+
404
+ this.fitLatLngBounds(latLngs);
405
+ };
406
+
407
+ this.fitLatLngBounds = function(latLngs) {
408
+ var total = latLngs.length;
409
+ var bounds = new google.maps.LatLngBounds();
410
+
411
+ for(var i=0; i < total; i++) {
412
+ bounds.extend(latLngs[i]);
413
+ }
414
+
415
+ this.map.fitBounds(bounds);
416
+ };
417
+
418
+ this.setCenter = function(lat, lng, callback) {
419
+ this.map.panTo(new google.maps.LatLng(lat, lng));
420
+
421
+ if (callback) {
422
+ callback();
423
+ }
424
+ };
425
+
426
+ this.getElement = function() {
427
+ return this.el;
428
+ };
429
+
430
+ this.zoomIn = function(value) {
431
+ value = value || 1;
432
+
433
+ this.zoom = this.map.getZoom() + value;
434
+ this.map.setZoom(this.zoom);
435
+ };
436
+
437
+ this.zoomOut = function(value) {
438
+ value = value || 1;
439
+
440
+ this.zoom = this.map.getZoom() - value;
441
+ this.map.setZoom(this.zoom);
442
+ };
443
+
444
+ var native_methods = [],
445
+ method;
446
+
447
+ for (method in this.map) {
448
+ if (typeof(this.map[method]) == 'function' && !this[method]) {
449
+ native_methods.push(method);
450
+ }
451
+ }
452
+
453
+ for (i=0; i < native_methods.length; i++) {
454
+ (function(gmaps, scope, method_name) {
455
+ gmaps[method_name] = function(){
456
+ return scope[method_name].apply(scope, arguments);
457
+ };
458
+ })(this, this.map, native_methods[i]);
459
+ }
460
+ };
461
+
462
+ return GMaps;
463
+ })(this);
464
+
465
+ GMaps.prototype.createControl = function(options) {
466
+ var control = document.createElement('div');
467
+
468
+ control.style.cursor = 'pointer';
469
+ control.style.fontFamily = 'Arial, sans-serif';
470
+ control.style.fontSize = '13px';
471
+ control.style.boxShadow = 'rgba(0, 0, 0, 0.398438) 0px 2px 4px';
472
+
473
+ for (var option in options.style) {
474
+ control.style[option] = options.style[option];
475
+ }
476
+
477
+ if (options.id) {
478
+ control.id = options.id;
479
+ }
480
+
481
+ if (options.classes) {
482
+ control.className = options.classes;
483
+ }
484
+
485
+ if (options.content) {
486
+ control.innerHTML = options.content;
487
+ }
488
+
489
+ for (var ev in options.events) {
490
+ (function(object, name) {
491
+ google.maps.event.addDomListener(object, name, function(){
492
+ options.events[name].apply(this, [this]);
493
+ });
494
+ })(control, ev);
495
+ }
496
+
497
+ control.index = 1;
498
+
499
+ return control;
500
+ };
501
+
502
+ GMaps.prototype.addControl = function(options) {
503
+ var position = google.maps.ControlPosition[options.position.toUpperCase()];
504
+
505
+ delete options.position;
506
+
507
+ var control = this.createControl(options);
508
+ this.controls.push(control);
509
+
510
+ this.map.controls[position].push(control);
511
+
512
+ return control;
513
+ };
514
+
515
+ GMaps.prototype.createMarker = function(options) {
516
+ if (options.lat == undefined && options.lng == undefined && options.position == undefined) {
517
+ throw 'No latitude or longitude defined.';
518
+ }
519
+
520
+ var self = this,
521
+ details = options.details,
522
+ fences = options.fences,
523
+ outside = options.outside,
524
+ base_options = {
525
+ position: new google.maps.LatLng(options.lat, options.lng),
526
+ map: null
527
+ };
528
+
529
+ delete options.lat;
530
+ delete options.lng;
531
+ delete options.fences;
532
+ delete options.outside;
533
+
534
+ var marker_options = extend_object(base_options, options),
535
+ marker = new google.maps.Marker(marker_options);
536
+
537
+ marker.fences = fences;
538
+
539
+ if (options.infoWindow) {
540
+ marker.infoWindow = new google.maps.InfoWindow(options.infoWindow);
541
+
542
+ var info_window_events = ['closeclick', 'content_changed', 'domready', 'position_changed', 'zindex_changed'];
543
+
544
+ for (var ev = 0; ev < info_window_events.length; ev++) {
545
+ (function(object, name) {
546
+ if (options.infoWindow[name]) {
547
+ google.maps.event.addListener(object, name, function(e){
548
+ options.infoWindow[name].apply(this, [e]);
549
+ });
550
+ }
551
+ })(marker.infoWindow, info_window_events[ev]);
552
+ }
553
+ }
554
+
555
+ var marker_events = ['animation_changed', 'clickable_changed', 'cursor_changed', 'draggable_changed', 'flat_changed', 'icon_changed', 'position_changed', 'shadow_changed', 'shape_changed', 'title_changed', 'visible_changed', 'zindex_changed'];
556
+
557
+ var marker_events_with_mouse = ['dblclick', 'drag', 'dragend', 'dragstart', 'mousedown', 'mouseout', 'mouseover', 'mouseup'];
558
+
559
+ for (var ev = 0; ev < marker_events.length; ev++) {
560
+ (function(object, name) {
561
+ if (options[name]) {
562
+ google.maps.event.addListener(object, name, function(){
563
+ options[name].apply(this, [this]);
564
+ });
565
+ }
566
+ })(marker, marker_events[ev]);
567
+ }
568
+
569
+ for (var ev = 0; ev < marker_events_with_mouse.length; ev++) {
570
+ (function(map, object, name) {
571
+ if (options[name]) {
572
+ google.maps.event.addListener(object, name, function(me){
573
+ if(!me.pixel){
574
+ me.pixel = map.getProjection().fromLatLngToPoint(me.latLng)
575
+ }
576
+
577
+ options[name].apply(this, [me]);
578
+ });
579
+ }
580
+ })(this.map, marker, marker_events_with_mouse[ev]);
581
+ }
582
+
583
+ google.maps.event.addListener(marker, 'click', function() {
584
+ this.details = details;
585
+
586
+ if (options.click) {
587
+ options.click.apply(this, [this]);
588
+ }
589
+
590
+ if (marker.infoWindow) {
591
+ self.hideInfoWindows();
592
+ marker.infoWindow.open(self.map, marker);
593
+ }
594
+ });
595
+
596
+ google.maps.event.addListener(marker, 'rightclick', function(e) {
597
+ e.marker = this;
598
+
599
+ if (options.rightclick) {
600
+ options.rightclick.apply(this, [e]);
601
+ }
602
+
603
+ if (window.context_menu[self.el.id]['marker'] != undefined) {
604
+ self.buildContextMenu('marker', e);
605
+ }
606
+ });
607
+
608
+ if (marker.fences) {
609
+ google.maps.event.addListener(marker, 'dragend', function() {
610
+ self.checkMarkerGeofence(marker, function(m, f) {
611
+ outside(m, f);
612
+ });
613
+ });
614
+ }
615
+
616
+ return marker;
617
+ };
618
+
619
+ GMaps.prototype.addMarker = function(options) {
620
+ var marker;
621
+ if(options.hasOwnProperty('gm_accessors_')) {
622
+ // Native google.maps.Marker object
623
+ marker = options;
624
+ }
625
+ else {
626
+ if ((options.hasOwnProperty('lat') && options.hasOwnProperty('lng')) || options.position) {
627
+ marker = this.createMarker(options);
628
+ }
629
+ else {
630
+ throw 'No latitude or longitude defined.';
631
+ }
632
+ }
633
+
634
+ marker.setMap(this.map);
635
+
636
+ if(this.markerClusterer) {
637
+ this.markerClusterer.addMarker(marker);
638
+ }
639
+
640
+ this.markers.push(marker);
641
+
642
+ GMaps.fire('marker_added', marker, this);
643
+
644
+ return marker;
645
+ };
646
+
647
+ GMaps.prototype.addMarkers = function(array) {
648
+ for (var i = 0, marker; marker=array[i]; i++) {
649
+ this.addMarker(marker);
650
+ }
651
+
652
+ return this.markers;
653
+ };
654
+
655
+ GMaps.prototype.hideInfoWindows = function() {
656
+ for (var i = 0, marker; marker = this.markers[i]; i++){
657
+ if (marker.infoWindow){
658
+ marker.infoWindow.close();
659
+ }
660
+ }
661
+ };
662
+
663
+ GMaps.prototype.removeMarker = function(marker) {
664
+ for (var i = 0; i < this.markers.length; i++) {
665
+ if (this.markers[i] === marker) {
666
+ this.markers[i].setMap(null);
667
+ this.markers.splice(i, 1);
668
+
669
+ if(this.markerClusterer) {
670
+ this.markerClusterer.removeMarker(marker);
671
+ }
672
+
673
+ GMaps.fire('marker_removed', marker, this);
674
+
675
+ break;
676
+ }
677
+ }
678
+
679
+ return marker;
680
+ };
681
+
682
+ GMaps.prototype.removeMarkers = function(collection) {
683
+ var collection = (collection || this.markers);
684
+
685
+ for (var i = 0;i < this.markers.length; i++) {
686
+ if(this.markers[i] === collection[i]) {
687
+ this.markers[i].setMap(null);
688
+ }
689
+ }
690
+
691
+ var new_markers = [];
692
+
693
+ for (var i = 0;i < this.markers.length; i++) {
694
+ if(this.markers[i].getMap() != null) {
695
+ new_markers.push(this.markers[i]);
696
+ }
697
+ }
698
+
699
+ this.markers = new_markers;
700
+ };
701
+
702
+ GMaps.prototype.drawOverlay = function(options) {
703
+ var overlay = new google.maps.OverlayView(),
704
+ auto_show = true;
705
+
706
+ overlay.setMap(this.map);
707
+
708
+ if (options.auto_show != null) {
709
+ auto_show = options.auto_show;
710
+ }
711
+
712
+ overlay.onAdd = function() {
713
+ var el = document.createElement('div');
714
+
715
+ el.style.borderStyle = "none";
716
+ el.style.borderWidth = "0px";
717
+ el.style.position = "absolute";
718
+ el.style.zIndex = 100;
719
+ el.innerHTML = options.content;
720
+
721
+ overlay.el = el;
722
+
723
+ if (!options.layer) {
724
+ options.layer = 'overlayLayer';
725
+ }
726
+
727
+ var panes = this.getPanes(),
728
+ overlayLayer = panes[options.layer],
729
+ stop_overlay_events = ['contextmenu', 'DOMMouseScroll', 'dblclick', 'mousedown'];
730
+
731
+ overlayLayer.appendChild(el);
732
+
733
+ for (var ev = 0; ev < stop_overlay_events.length; ev++) {
734
+ (function(object, name) {
735
+ google.maps.event.addDomListener(object, name, function(e){
736
+ if (navigator.userAgent.toLowerCase().indexOf('msie') != -1 && document.all) {
737
+ e.cancelBubble = true;
738
+ e.returnValue = false;
739
+ }
740
+ else {
741
+ e.stopPropagation();
742
+ }
743
+ });
744
+ })(el, stop_overlay_events[ev]);
745
+ }
746
+
747
+ google.maps.event.trigger(this, 'ready');
748
+ };
749
+
750
+ overlay.draw = function() {
751
+ var projection = this.getProjection(),
752
+ pixel = projection.fromLatLngToDivPixel(new google.maps.LatLng(options.lat, options.lng));
753
+
754
+ options.horizontalOffset = options.horizontalOffset || 0;
755
+ options.verticalOffset = options.verticalOffset || 0;
756
+
757
+ var el = overlay.el,
758
+ content = el.children[0],
759
+ content_height = content.clientHeight,
760
+ content_width = content.clientWidth;
761
+
762
+ switch (options.verticalAlign) {
763
+ case 'top':
764
+ el.style.top = (pixel.y - content_height + options.verticalOffset) + 'px';
765
+ break;
766
+ default:
767
+ case 'middle':
768
+ el.style.top = (pixel.y - (content_height / 2) + options.verticalOffset) + 'px';
769
+ break;
770
+ case 'bottom':
771
+ el.style.top = (pixel.y + options.verticalOffset) + 'px';
772
+ break;
773
+ }
774
+
775
+ switch (options.horizontalAlign) {
776
+ case 'left':
777
+ el.style.left = (pixel.x - content_width + options.horizontalOffset) + 'px';
778
+ break;
779
+ default:
780
+ case 'center':
781
+ el.style.left = (pixel.x - (content_width / 2) + options.horizontalOffset) + 'px';
782
+ break;
783
+ case 'right':
784
+ el.style.left = (pixel.x + options.horizontalOffset) + 'px';
785
+ break;
786
+ }
787
+
788
+ el.style.display = auto_show ? 'block' : 'none';
789
+
790
+ if (!auto_show) {
791
+ options.show.apply(this, [el]);
792
+ }
793
+ };
794
+
795
+ overlay.onRemove = function() {
796
+ var el = overlay.el;
797
+
798
+ if (options.remove) {
799
+ options.remove.apply(this, [el]);
800
+ }
801
+ else {
802
+ overlay.el.parentNode.removeChild(overlay.el);
803
+ overlay.el = null;
804
+ }
805
+ };
806
+
807
+ this.overlays.push(overlay);
808
+ return overlay;
809
+ };
810
+
811
+ GMaps.prototype.removeOverlay = function(overlay) {
812
+ for (var i = 0; i < this.overlays.length; i++) {
813
+ if (this.overlays[i] === overlay) {
814
+ this.overlays[i].setMap(null);
815
+ this.overlays.splice(i, 1);
816
+
817
+ break;
818
+ }
819
+ }
820
+ };
821
+
822
+ GMaps.prototype.removeOverlays = function() {
823
+ for (var i = 0, item; item = this.overlays[i]; i++) {
824
+ item.setMap(null);
825
+ }
826
+
827
+ this.overlays = [];
828
+ };
829
+
830
+ GMaps.prototype.drawPolyline = function(options) {
831
+ var path = [],
832
+ points = options.path;
833
+
834
+ if (points.length) {
835
+ if (points[0][0] === undefined) {
836
+ path = points;
837
+ }
838
+ else {
839
+ for (var i=0, latlng; latlng=points[i]; i++) {
840
+ path.push(new google.maps.LatLng(latlng[0], latlng[1]));
841
+ }
842
+ }
843
+ }
844
+
845
+ var polyline_options = {
846
+ map: this.map,
847
+ path: path,
848
+ strokeColor: options.strokeColor,
849
+ strokeOpacity: options.strokeOpacity,
850
+ strokeWeight: options.strokeWeight,
851
+ geodesic: options.geodesic,
852
+ clickable: true,
853
+ editable: false,
854
+ visible: true
855
+ };
856
+
857
+ if (options.hasOwnProperty("clickable")) {
858
+ polyline_options.clickable = options.clickable;
859
+ }
860
+
861
+ if (options.hasOwnProperty("editable")) {
862
+ polyline_options.editable = options.editable;
863
+ }
864
+
865
+ if (options.hasOwnProperty("icons")) {
866
+ polyline_options.icons = options.icons;
867
+ }
868
+
869
+ if (options.hasOwnProperty("zIndex")) {
870
+ polyline_options.zIndex = options.zIndex;
871
+ }
872
+
873
+ var polyline = new google.maps.Polyline(polyline_options);
874
+
875
+ var polyline_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick'];
876
+
877
+ for (var ev = 0; ev < polyline_events.length; ev++) {
878
+ (function(object, name) {
879
+ if (options[name]) {
880
+ google.maps.event.addListener(object, name, function(e){
881
+ options[name].apply(this, [e]);
882
+ });
883
+ }
884
+ })(polyline, polyline_events[ev]);
885
+ }
886
+
887
+ this.polylines.push(polyline);
888
+
889
+ GMaps.fire('polyline_added', polyline, this);
890
+
891
+ return polyline;
892
+ };
893
+
894
+ GMaps.prototype.removePolyline = function(polyline) {
895
+ for (var i = 0; i < this.polylines.length; i++) {
896
+ if (this.polylines[i] === polyline) {
897
+ this.polylines[i].setMap(null);
898
+ this.polylines.splice(i, 1);
899
+
900
+ GMaps.fire('polyline_removed', polyline, this);
901
+
902
+ break;
903
+ }
904
+ }
905
+ };
906
+
907
+ GMaps.prototype.removePolylines = function() {
908
+ for (var i = 0, item; item = this.polylines[i]; i++) {
909
+ item.setMap(null);
910
+ }
911
+
912
+ this.polylines = [];
913
+ };
914
+
915
+ GMaps.prototype.drawCircle = function(options) {
916
+ options = extend_object({
917
+ map: this.map,
918
+ center: new google.maps.LatLng(options.lat, options.lng)
919
+ }, options);
920
+
921
+ delete options.lat;
922
+ delete options.lng;
923
+
924
+ var polygon = new google.maps.Circle(options),
925
+ polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick'];
926
+
927
+ for (var ev = 0; ev < polygon_events.length; ev++) {
928
+ (function(object, name) {
929
+ if (options[name]) {
930
+ google.maps.event.addListener(object, name, function(e){
931
+ options[name].apply(this, [e]);
932
+ });
933
+ }
934
+ })(polygon, polygon_events[ev]);
935
+ }
936
+
937
+ this.polygons.push(polygon);
938
+
939
+ return polygon;
940
+ };
941
+
942
+ GMaps.prototype.drawRectangle = function(options) {
943
+ options = extend_object({
944
+ map: this.map
945
+ }, options);
946
+
947
+ var latLngBounds = new google.maps.LatLngBounds(
948
+ new google.maps.LatLng(options.bounds[0][0], options.bounds[0][1]),
949
+ new google.maps.LatLng(options.bounds[1][0], options.bounds[1][1])
950
+ );
951
+
952
+ options.bounds = latLngBounds;
953
+
954
+ var polygon = new google.maps.Rectangle(options),
955
+ polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick'];
956
+
957
+ for (var ev = 0; ev < polygon_events.length; ev++) {
958
+ (function(object, name) {
959
+ if (options[name]) {
960
+ google.maps.event.addListener(object, name, function(e){
961
+ options[name].apply(this, [e]);
962
+ });
963
+ }
964
+ })(polygon, polygon_events[ev]);
965
+ }
966
+
967
+ this.polygons.push(polygon);
968
+
969
+ return polygon;
970
+ };
971
+
972
+ GMaps.prototype.drawPolygon = function(options) {
973
+ var useGeoJSON = false;
974
+
975
+ if(options.hasOwnProperty("useGeoJSON")) {
976
+ useGeoJSON = options.useGeoJSON;
977
+ }
978
+
979
+ delete options.useGeoJSON;
980
+
981
+ options = extend_object({
982
+ map: this.map
983
+ }, options);
984
+
985
+ if (useGeoJSON == false) {
986
+ options.paths = [options.paths.slice(0)];
987
+ }
988
+
989
+ if (options.paths.length > 0) {
990
+ if (options.paths[0].length > 0) {
991
+ options.paths = array_flat(array_map(options.paths, arrayToLatLng, useGeoJSON));
992
+ }
993
+ }
994
+
995
+ var polygon = new google.maps.Polygon(options),
996
+ polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick'];
997
+
998
+ for (var ev = 0; ev < polygon_events.length; ev++) {
999
+ (function(object, name) {
1000
+ if (options[name]) {
1001
+ google.maps.event.addListener(object, name, function(e){
1002
+ options[name].apply(this, [e]);
1003
+ });
1004
+ }
1005
+ })(polygon, polygon_events[ev]);
1006
+ }
1007
+
1008
+ this.polygons.push(polygon);
1009
+
1010
+ GMaps.fire('polygon_added', polygon, this);
1011
+
1012
+ return polygon;
1013
+ };
1014
+
1015
+ GMaps.prototype.removePolygon = function(polygon) {
1016
+ for (var i = 0; i < this.polygons.length; i++) {
1017
+ if (this.polygons[i] === polygon) {
1018
+ this.polygons[i].setMap(null);
1019
+ this.polygons.splice(i, 1);
1020
+
1021
+ GMaps.fire('polygon_removed', polygon, this);
1022
+
1023
+ break;
1024
+ }
1025
+ }
1026
+ };
1027
+
1028
+ GMaps.prototype.removePolygons = function() {
1029
+ for (var i = 0, item; item = this.polygons[i]; i++) {
1030
+ item.setMap(null);
1031
+ }
1032
+
1033
+ this.polygons = [];
1034
+ };
1035
+
1036
+ GMaps.prototype.getFromFusionTables = function(options) {
1037
+ var events = options.events;
1038
+
1039
+ delete options.events;
1040
+
1041
+ var fusion_tables_options = options,
1042
+ layer = new google.maps.FusionTablesLayer(fusion_tables_options);
1043
+
1044
+ for (var ev in events) {
1045
+ (function(object, name) {
1046
+ google.maps.event.addListener(object, name, function(e) {
1047
+ events[name].apply(this, [e]);
1048
+ });
1049
+ })(layer, ev);
1050
+ }
1051
+
1052
+ this.layers.push(layer);
1053
+
1054
+ return layer;
1055
+ };
1056
+
1057
+ GMaps.prototype.loadFromFusionTables = function(options) {
1058
+ var layer = this.getFromFusionTables(options);
1059
+ layer.setMap(this.map);
1060
+
1061
+ return layer;
1062
+ };
1063
+
1064
+ GMaps.prototype.getFromKML = function(options) {
1065
+ var url = options.url,
1066
+ events = options.events;
1067
+
1068
+ delete options.url;
1069
+ delete options.events;
1070
+
1071
+ var kml_options = options,
1072
+ layer = new google.maps.KmlLayer(url, kml_options);
1073
+
1074
+ for (var ev in events) {
1075
+ (function(object, name) {
1076
+ google.maps.event.addListener(object, name, function(e) {
1077
+ events[name].apply(this, [e]);
1078
+ });
1079
+ })(layer, ev);
1080
+ }
1081
+
1082
+ this.layers.push(layer);
1083
+
1084
+ return layer;
1085
+ };
1086
+
1087
+ GMaps.prototype.loadFromKML = function(options) {
1088
+ var layer = this.getFromKML(options);
1089
+ layer.setMap(this.map);
1090
+
1091
+ return layer;
1092
+ };
1093
+
1094
+ GMaps.prototype.addLayer = function(layerName, options) {
1095
+ //var default_layers = ['weather', 'clouds', 'traffic', 'transit', 'bicycling', 'panoramio', 'places'];
1096
+ options = options || {};
1097
+ var layer;
1098
+
1099
+ switch(layerName) {
1100
+ case 'weather': this.singleLayers.weather = layer = new google.maps.weather.WeatherLayer();
1101
+ break;
1102
+ case 'clouds': this.singleLayers.clouds = layer = new google.maps.weather.CloudLayer();
1103
+ break;
1104
+ case 'traffic': this.singleLayers.traffic = layer = new google.maps.TrafficLayer();
1105
+ break;
1106
+ case 'transit': this.singleLayers.transit = layer = new google.maps.TransitLayer();
1107
+ break;
1108
+ case 'bicycling': this.singleLayers.bicycling = layer = new google.maps.BicyclingLayer();
1109
+ break;
1110
+ case 'panoramio':
1111
+ this.singleLayers.panoramio = layer = new google.maps.panoramio.PanoramioLayer();
1112
+ layer.setTag(options.filter);
1113
+ delete options.filter;
1114
+
1115
+ //click event
1116
+ if (options.click) {
1117
+ google.maps.event.addListener(layer, 'click', function(event) {
1118
+ options.click(event);
1119
+ delete options.click;
1120
+ });
1121
+ }
1122
+ break;
1123
+ case 'places':
1124
+ this.singleLayers.places = layer = new google.maps.places.PlacesService(this.map);
1125
+
1126
+ //search and nearbySearch callback, Both are the same
1127
+ if (options.search || options.nearbySearch) {
1128
+ var placeSearchRequest = {
1129
+ bounds : options.bounds || null,
1130
+ keyword : options.keyword || null,
1131
+ location : options.location || null,
1132
+ name : options.name || null,
1133
+ radius : options.radius || null,
1134
+ rankBy : options.rankBy || null,
1135
+ types : options.types || null
1136
+ };
1137
+
1138
+ if (options.search) {
1139
+ layer.search(placeSearchRequest, options.search);
1140
+ }
1141
+
1142
+ if (options.nearbySearch) {
1143
+ layer.nearbySearch(placeSearchRequest, options.nearbySearch);
1144
+ }
1145
+ }
1146
+
1147
+ //textSearch callback
1148
+ if (options.textSearch) {
1149
+ var textSearchRequest = {
1150
+ bounds : options.bounds || null,
1151
+ location : options.location || null,
1152
+ query : options.query || null,
1153
+ radius : options.radius || null
1154
+ };
1155
+
1156
+ layer.textSearch(textSearchRequest, options.textSearch);
1157
+ }
1158
+ break;
1159
+ }
1160
+
1161
+ if (layer !== undefined) {
1162
+ if (typeof layer.setOptions == 'function') {
1163
+ layer.setOptions(options);
1164
+ }
1165
+ if (typeof layer.setMap == 'function') {
1166
+ layer.setMap(this.map);
1167
+ }
1168
+
1169
+ return layer;
1170
+ }
1171
+ };
1172
+
1173
+ GMaps.prototype.removeLayer = function(layer) {
1174
+ if (typeof(layer) == "string" && this.singleLayers[layer] !== undefined) {
1175
+ this.singleLayers[layer].setMap(null);
1176
+
1177
+ delete this.singleLayers[layer];
1178
+ }
1179
+ else {
1180
+ for (var i = 0; i < this.layers.length; i++) {
1181
+ if (this.layers[i] === layer) {
1182
+ this.layers[i].setMap(null);
1183
+ this.layers.splice(i, 1);
1184
+
1185
+ break;
1186
+ }
1187
+ }
1188
+ }
1189
+ };
1190
+
1191
+ var travelMode, unitSystem;
1192
+
1193
+ GMaps.prototype.getRoutes = function(options) {
1194
+ switch (options.travelMode) {
1195
+ case 'bicycling':
1196
+ travelMode = google.maps.TravelMode.BICYCLING;
1197
+ break;
1198
+ case 'transit':
1199
+ travelMode = google.maps.TravelMode.TRANSIT;
1200
+ break;
1201
+ case 'driving':
1202
+ travelMode = google.maps.TravelMode.DRIVING;
1203
+ break;
1204
+ default:
1205
+ travelMode = google.maps.TravelMode.WALKING;
1206
+ break;
1207
+ }
1208
+
1209
+ if (options.unitSystem === 'imperial') {
1210
+ unitSystem = google.maps.UnitSystem.IMPERIAL;
1211
+ }
1212
+ else {
1213
+ unitSystem = google.maps.UnitSystem.METRIC;
1214
+ }
1215
+
1216
+ var base_options = {
1217
+ avoidHighways: false,
1218
+ avoidTolls: false,
1219
+ optimizeWaypoints: false,
1220
+ waypoints: []
1221
+ },
1222
+ request_options = extend_object(base_options, options);
1223
+
1224
+ request_options.origin = /string/.test(typeof options.origin) ? options.origin : new google.maps.LatLng(options.origin[0], options.origin[1]);
1225
+ request_options.destination = /string/.test(typeof options.destination) ? options.destination : new google.maps.LatLng(options.destination[0], options.destination[1]);
1226
+ request_options.travelMode = travelMode;
1227
+ request_options.unitSystem = unitSystem;
1228
+
1229
+ delete request_options.callback;
1230
+ delete request_options.error;
1231
+
1232
+ var self = this,
1233
+ service = new google.maps.DirectionsService();
1234
+
1235
+ service.route(request_options, function(result, status) {
1236
+ if (status === google.maps.DirectionsStatus.OK) {
1237
+ for (var r in result.routes) {
1238
+ if (result.routes.hasOwnProperty(r)) {
1239
+ self.routes.push(result.routes[r]);
1240
+ }
1241
+ }
1242
+
1243
+ if (options.callback) {
1244
+ options.callback(self.routes);
1245
+ }
1246
+ }
1247
+ else {
1248
+ if (options.error) {
1249
+ options.error(result, status);
1250
+ }
1251
+ }
1252
+ });
1253
+ };
1254
+
1255
+ GMaps.prototype.removeRoutes = function() {
1256
+ this.routes = [];
1257
+ };
1258
+
1259
+ GMaps.prototype.getElevations = function(options) {
1260
+ options = extend_object({
1261
+ locations: [],
1262
+ path : false,
1263
+ samples : 256
1264
+ }, options);
1265
+
1266
+ if (options.locations.length > 0) {
1267
+ if (options.locations[0].length > 0) {
1268
+ options.locations = array_flat(array_map([options.locations], arrayToLatLng, false));
1269
+ }
1270
+ }
1271
+
1272
+ var callback = options.callback;
1273
+ delete options.callback;
1274
+
1275
+ var service = new google.maps.ElevationService();
1276
+
1277
+ //location request
1278
+ if (!options.path) {
1279
+ delete options.path;
1280
+ delete options.samples;
1281
+
1282
+ service.getElevationForLocations(options, function(result, status) {
1283
+ if (callback && typeof(callback) === "function") {
1284
+ callback(result, status);
1285
+ }
1286
+ });
1287
+ //path request
1288
+ } else {
1289
+ var pathRequest = {
1290
+ path : options.locations,
1291
+ samples : options.samples
1292
+ };
1293
+
1294
+ service.getElevationAlongPath(pathRequest, function(result, status) {
1295
+ if (callback && typeof(callback) === "function") {
1296
+ callback(result, status);
1297
+ }
1298
+ });
1299
+ }
1300
+ };
1301
+
1302
+ GMaps.prototype.cleanRoute = GMaps.prototype.removePolylines;
1303
+
1304
+ GMaps.prototype.drawRoute = function(options) {
1305
+ var self = this;
1306
+
1307
+ this.getRoutes({
1308
+ origin: options.origin,
1309
+ destination: options.destination,
1310
+ travelMode: options.travelMode,
1311
+ waypoints: options.waypoints,
1312
+ unitSystem: options.unitSystem,
1313
+ error: options.error,
1314
+ callback: function(e) {
1315
+ if (e.length > 0) {
1316
+ self.drawPolyline({
1317
+ path: e[e.length - 1].overview_path,
1318
+ strokeColor: options.strokeColor,
1319
+ strokeOpacity: options.strokeOpacity,
1320
+ strokeWeight: options.strokeWeight
1321
+ });
1322
+
1323
+ if (options.callback) {
1324
+ options.callback(e[e.length - 1]);
1325
+ }
1326
+ }
1327
+ }
1328
+ });
1329
+ };
1330
+
1331
+ GMaps.prototype.travelRoute = function(options) {
1332
+ if (options.origin && options.destination) {
1333
+ this.getRoutes({
1334
+ origin: options.origin,
1335
+ destination: options.destination,
1336
+ travelMode: options.travelMode,
1337
+ waypoints : options.waypoints,
1338
+ error: options.error,
1339
+ callback: function(e) {
1340
+ //start callback
1341
+ if (e.length > 0 && options.start) {
1342
+ options.start(e[e.length - 1]);
1343
+ }
1344
+
1345
+ //step callback
1346
+ if (e.length > 0 && options.step) {
1347
+ var route = e[e.length - 1];
1348
+ if (route.legs.length > 0) {
1349
+ var steps = route.legs[0].steps;
1350
+ for (var i=0, step; step=steps[i]; i++) {
1351
+ step.step_number = i;
1352
+ options.step(step, (route.legs[0].steps.length - 1));
1353
+ }
1354
+ }
1355
+ }
1356
+
1357
+ //end callback
1358
+ if (e.length > 0 && options.end) {
1359
+ options.end(e[e.length - 1]);
1360
+ }
1361
+ }
1362
+ });
1363
+ }
1364
+ else if (options.route) {
1365
+ if (options.route.legs.length > 0) {
1366
+ var steps = options.route.legs[0].steps;
1367
+ for (var i=0, step; step=steps[i]; i++) {
1368
+ step.step_number = i;
1369
+ options.step(step);
1370
+ }
1371
+ }
1372
+ }
1373
+ };
1374
+
1375
+ GMaps.prototype.drawSteppedRoute = function(options) {
1376
+ var self = this;
1377
+
1378
+ if (options.origin && options.destination) {
1379
+ this.getRoutes({
1380
+ origin: options.origin,
1381
+ destination: options.destination,
1382
+ travelMode: options.travelMode,
1383
+ waypoints : options.waypoints,
1384
+ error: options.error,
1385
+ callback: function(e) {
1386
+ //start callback
1387
+ if (e.length > 0 && options.start) {
1388
+ options.start(e[e.length - 1]);
1389
+ }
1390
+
1391
+ //step callback
1392
+ if (e.length > 0 && options.step) {
1393
+ var route = e[e.length - 1];
1394
+ if (route.legs.length > 0) {
1395
+ var steps = route.legs[0].steps;
1396
+ for (var i=0, step; step=steps[i]; i++) {
1397
+ step.step_number = i;
1398
+ self.drawPolyline({
1399
+ path: step.path,
1400
+ strokeColor: options.strokeColor,
1401
+ strokeOpacity: options.strokeOpacity,
1402
+ strokeWeight: options.strokeWeight
1403
+ });
1404
+ options.step(step, (route.legs[0].steps.length - 1));
1405
+ }
1406
+ }
1407
+ }
1408
+
1409
+ //end callback
1410
+ if (e.length > 0 && options.end) {
1411
+ options.end(e[e.length - 1]);
1412
+ }
1413
+ }
1414
+ });
1415
+ }
1416
+ else if (options.route) {
1417
+ if (options.route.legs.length > 0) {
1418
+ var steps = options.route.legs[0].steps;
1419
+ for (var i=0, step; step=steps[i]; i++) {
1420
+ step.step_number = i;
1421
+ self.drawPolyline({
1422
+ path: step.path,
1423
+ strokeColor: options.strokeColor,
1424
+ strokeOpacity: options.strokeOpacity,
1425
+ strokeWeight: options.strokeWeight
1426
+ });
1427
+ options.step(step);
1428
+ }
1429
+ }
1430
+ }
1431
+ };
1432
+
1433
+ GMaps.Route = function(options) {
1434
+ this.origin = options.origin;
1435
+ this.destination = options.destination;
1436
+ this.waypoints = options.waypoints;
1437
+
1438
+ this.map = options.map;
1439
+ this.route = options.route;
1440
+ this.step_count = 0;
1441
+ this.steps = this.route.legs[0].steps;
1442
+ this.steps_length = this.steps.length;
1443
+
1444
+ this.polyline = this.map.drawPolyline({
1445
+ path: new google.maps.MVCArray(),
1446
+ strokeColor: options.strokeColor,
1447
+ strokeOpacity: options.strokeOpacity,
1448
+ strokeWeight: options.strokeWeight
1449
+ }).getPath();
1450
+ };
1451
+
1452
+ GMaps.Route.prototype.getRoute = function(options) {
1453
+ var self = this;
1454
+
1455
+ this.map.getRoutes({
1456
+ origin : this.origin,
1457
+ destination : this.destination,
1458
+ travelMode : options.travelMode,
1459
+ waypoints : this.waypoints || [],
1460
+ error: options.error,
1461
+ callback : function() {
1462
+ self.route = e[0];
1463
+
1464
+ if (options.callback) {
1465
+ options.callback.call(self);
1466
+ }
1467
+ }
1468
+ });
1469
+ };
1470
+
1471
+ GMaps.Route.prototype.back = function() {
1472
+ if (this.step_count > 0) {
1473
+ this.step_count--;
1474
+ var path = this.route.legs[0].steps[this.step_count].path;
1475
+
1476
+ for (var p in path){
1477
+ if (path.hasOwnProperty(p)){
1478
+ this.polyline.pop();
1479
+ }
1480
+ }
1481
+ }
1482
+ };
1483
+
1484
+ GMaps.Route.prototype.forward = function() {
1485
+ if (this.step_count < this.steps_length) {
1486
+ var path = this.route.legs[0].steps[this.step_count].path;
1487
+
1488
+ for (var p in path){
1489
+ if (path.hasOwnProperty(p)){
1490
+ this.polyline.push(path[p]);
1491
+ }
1492
+ }
1493
+ this.step_count++;
1494
+ }
1495
+ };
1496
+
1497
+ GMaps.prototype.checkGeofence = function(lat, lng, fence) {
1498
+ return fence.containsLatLng(new google.maps.LatLng(lat, lng));
1499
+ };
1500
+
1501
+ GMaps.prototype.checkMarkerGeofence = function(marker, outside_callback) {
1502
+ if (marker.fences) {
1503
+ for (var i = 0, fence; fence = marker.fences[i]; i++) {
1504
+ var pos = marker.getPosition();
1505
+ if (!this.checkGeofence(pos.lat(), pos.lng(), fence)) {
1506
+ outside_callback(marker, fence);
1507
+ }
1508
+ }
1509
+ }
1510
+ };
1511
+
1512
+ GMaps.prototype.toImage = function(options) {
1513
+ var options = options || {},
1514
+ static_map_options = {};
1515
+
1516
+ static_map_options['size'] = options['size'] || [this.el.clientWidth, this.el.clientHeight];
1517
+ static_map_options['lat'] = this.getCenter().lat();
1518
+ static_map_options['lng'] = this.getCenter().lng();
1519
+
1520
+ if (this.markers.length > 0) {
1521
+ static_map_options['markers'] = [];
1522
+
1523
+ for (var i = 0; i < this.markers.length; i++) {
1524
+ static_map_options['markers'].push({
1525
+ lat: this.markers[i].getPosition().lat(),
1526
+ lng: this.markers[i].getPosition().lng()
1527
+ });
1528
+ }
1529
+ }
1530
+
1531
+ if (this.polylines.length > 0) {
1532
+ var polyline = this.polylines[0];
1533
+
1534
+ static_map_options['polyline'] = {};
1535
+ static_map_options['polyline']['path'] = google.maps.geometry.encoding.encodePath(polyline.getPath());
1536
+ static_map_options['polyline']['strokeColor'] = polyline.strokeColor
1537
+ static_map_options['polyline']['strokeOpacity'] = polyline.strokeOpacity
1538
+ static_map_options['polyline']['strokeWeight'] = polyline.strokeWeight
1539
+ }
1540
+
1541
+ return GMaps.staticMapURL(static_map_options);
1542
+ };
1543
+
1544
+ GMaps.staticMapURL = function(options){
1545
+ var parameters = [],
1546
+ data,
1547
+ static_root = 'http://maps.googleapis.com/maps/api/staticmap';
1548
+
1549
+ if (options.url) {
1550
+ static_root = options.url;
1551
+ delete options.url;
1552
+ }
1553
+
1554
+ static_root += '?';
1555
+
1556
+ var markers = options.markers;
1557
+
1558
+ delete options.markers;
1559
+
1560
+ if (!markers && options.marker) {
1561
+ markers = [options.marker];
1562
+ delete options.marker;
1563
+ }
1564
+
1565
+ var styles = options.styles;
1566
+
1567
+ delete options.styles;
1568
+
1569
+ var polyline = options.polyline;
1570
+ delete options.polyline;
1571
+
1572
+ /** Map options **/
1573
+ if (options.center) {
1574
+ parameters.push('center=' + options.center);
1575
+ delete options.center;
1576
+ }
1577
+ else if (options.address) {
1578
+ parameters.push('center=' + options.address);
1579
+ delete options.address;
1580
+ }
1581
+ else if (options.lat) {
1582
+ parameters.push(['center=', options.lat, ',', options.lng].join(''));
1583
+ delete options.lat;
1584
+ delete options.lng;
1585
+ }
1586
+ else if (options.visible) {
1587
+ var visible = encodeURI(options.visible.join('|'));
1588
+ parameters.push('visible=' + visible);
1589
+ }
1590
+
1591
+ var size = options.size;
1592
+ if (size) {
1593
+ if (size.join) {
1594
+ size = size.join('x');
1595
+ }
1596
+ delete options.size;
1597
+ }
1598
+ else {
1599
+ size = '630x300';
1600
+ }
1601
+ parameters.push('size=' + size);
1602
+
1603
+ if (!options.zoom && options.zoom !== false) {
1604
+ options.zoom = 15;
1605
+ }
1606
+
1607
+ var sensor = options.hasOwnProperty('sensor') ? !!options.sensor : true;
1608
+ delete options.sensor;
1609
+ parameters.push('sensor=' + sensor);
1610
+
1611
+ for (var param in options) {
1612
+ if (options.hasOwnProperty(param)) {
1613
+ parameters.push(param + '=' + options[param]);
1614
+ }
1615
+ }
1616
+
1617
+ /** Markers **/
1618
+ if (markers) {
1619
+ var marker, loc;
1620
+
1621
+ for (var i=0; data=markers[i]; i++) {
1622
+ marker = [];
1623
+
1624
+ if (data.size && data.size !== 'normal') {
1625
+ marker.push('size:' + data.size);
1626
+ delete data.size;
1627
+ }
1628
+ else if (data.icon) {
1629
+ marker.push('icon:' + encodeURI(data.icon));
1630
+ delete data.icon;
1631
+ }
1632
+
1633
+ if (data.color) {
1634
+ marker.push('color:' + data.color.replace('#', '0x'));
1635
+ delete data.color;
1636
+ }
1637
+
1638
+ if (data.label) {
1639
+ marker.push('label:' + data.label[0].toUpperCase());
1640
+ delete data.label;
1641
+ }
1642
+
1643
+ loc = (data.address ? data.address : data.lat + ',' + data.lng);
1644
+ delete data.address;
1645
+ delete data.lat;
1646
+ delete data.lng;
1647
+
1648
+ for(var param in data){
1649
+ if (data.hasOwnProperty(param)) {
1650
+ marker.push(param + ':' + data[param]);
1651
+ }
1652
+ }
1653
+
1654
+ if (marker.length || i === 0) {
1655
+ marker.push(loc);
1656
+ marker = marker.join('|');
1657
+ parameters.push('markers=' + encodeURI(marker));
1658
+ }
1659
+ // New marker without styles
1660
+ else {
1661
+ marker = parameters.pop() + encodeURI('|' + loc);
1662
+ parameters.push(marker);
1663
+ }
1664
+ }
1665
+ }
1666
+
1667
+ /** Map Styles **/
1668
+ if (styles) {
1669
+ for (var i = 0; i < styles.length; i++) {
1670
+ var styleRule = [];
1671
+ if (styles[i].featureType && styles[i].featureType != 'all' ) {
1672
+ styleRule.push('feature:' + styles[i].featureType);
1673
+ }
1674
+
1675
+ if (styles[i].elementType && styles[i].elementType != 'all') {
1676
+ styleRule.push('element:' + styles[i].elementType);
1677
+ }
1678
+
1679
+ for (var j = 0; j < styles[i].stylers.length; j++) {
1680
+ for (var p in styles[i].stylers[j]) {
1681
+ var ruleArg = styles[i].stylers[j][p];
1682
+ if (p == 'hue' || p == 'color') {
1683
+ ruleArg = '0x' + ruleArg.substring(1);
1684
+ }
1685
+ styleRule.push(p + ':' + ruleArg);
1686
+ }
1687
+ }
1688
+
1689
+ var rule = styleRule.join('|');
1690
+ if (rule != '') {
1691
+ parameters.push('style=' + rule);
1692
+ }
1693
+ }
1694
+ }
1695
+
1696
+ /** Polylines **/
1697
+ function parseColor(color, opacity) {
1698
+ if (color[0] === '#'){
1699
+ color = color.replace('#', '0x');
1700
+
1701
+ if (opacity) {
1702
+ opacity = parseFloat(opacity);
1703
+ opacity = Math.min(1, Math.max(opacity, 0));
1704
+ if (opacity === 0) {
1705
+ return '0x00000000';
1706
+ }
1707
+ opacity = (opacity * 255).toString(16);
1708
+ if (opacity.length === 1) {
1709
+ opacity += opacity;
1710
+ }
1711
+
1712
+ color = color.slice(0,8) + opacity;
1713
+ }
1714
+ }
1715
+ return color;
1716
+ }
1717
+
1718
+ if (polyline) {
1719
+ data = polyline;
1720
+ polyline = [];
1721
+
1722
+ if (data.strokeWeight) {
1723
+ polyline.push('weight:' + parseInt(data.strokeWeight, 10));
1724
+ }
1725
+
1726
+ if (data.strokeColor) {
1727
+ var color = parseColor(data.strokeColor, data.strokeOpacity);
1728
+ polyline.push('color:' + color);
1729
+ }
1730
+
1731
+ if (data.fillColor) {
1732
+ var fillcolor = parseColor(data.fillColor, data.fillOpacity);
1733
+ polyline.push('fillcolor:' + fillcolor);
1734
+ }
1735
+
1736
+ var path = data.path;
1737
+ if (path.join) {
1738
+ for (var j=0, pos; pos=path[j]; j++) {
1739
+ polyline.push(pos.join(','));
1740
+ }
1741
+ }
1742
+ else {
1743
+ polyline.push('enc:' + path);
1744
+ }
1745
+
1746
+ polyline = polyline.join('|');
1747
+ parameters.push('path=' + encodeURI(polyline));
1748
+ }
1749
+
1750
+ parameters = parameters.join('&');
1751
+ return static_root + parameters;
1752
+ };
1753
+
1754
+ GMaps.prototype.addMapType = function(mapTypeId, options) {
1755
+ if (options.hasOwnProperty("getTileUrl") && typeof(options["getTileUrl"]) == "function") {
1756
+ options.tileSize = options.tileSize || new google.maps.Size(256, 256);
1757
+
1758
+ var mapType = new google.maps.ImageMapType(options);
1759
+
1760
+ this.map.mapTypes.set(mapTypeId, mapType);
1761
+ }
1762
+ else {
1763
+ throw "'getTileUrl' function required.";
1764
+ }
1765
+ };
1766
+
1767
+ GMaps.prototype.addOverlayMapType = function(options) {
1768
+ if (options.hasOwnProperty("getTile") && typeof(options["getTile"]) == "function") {
1769
+ var overlayMapTypeIndex = options.index;
1770
+
1771
+ delete options.index;
1772
+
1773
+ this.map.overlayMapTypes.insertAt(overlayMapTypeIndex, options);
1774
+ }
1775
+ else {
1776
+ throw "'getTile' function required.";
1777
+ }
1778
+ };
1779
+
1780
+ GMaps.prototype.removeOverlayMapType = function(overlayMapTypeIndex) {
1781
+ this.map.overlayMapTypes.removeAt(overlayMapTypeIndex);
1782
+ };
1783
+
1784
+ GMaps.prototype.addStyle = function(options) {
1785
+ var styledMapType = new google.maps.StyledMapType(options.styles, { name: options.styledMapName });
1786
+
1787
+ this.map.mapTypes.set(options.mapTypeId, styledMapType);
1788
+ };
1789
+
1790
+ GMaps.prototype.setStyle = function(mapTypeId) {
1791
+ this.map.setMapTypeId(mapTypeId);
1792
+ };
1793
+
1794
+ GMaps.prototype.createPanorama = function(streetview_options) {
1795
+ if (!streetview_options.hasOwnProperty('lat') || !streetview_options.hasOwnProperty('lng')) {
1796
+ streetview_options.lat = this.getCenter().lat();
1797
+ streetview_options.lng = this.getCenter().lng();
1798
+ }
1799
+
1800
+ this.panorama = GMaps.createPanorama(streetview_options);
1801
+
1802
+ this.map.setStreetView(this.panorama);
1803
+
1804
+ return this.panorama;
1805
+ };
1806
+
1807
+ GMaps.createPanorama = function(options) {
1808
+ var el = getElementById(options.el, options.context);
1809
+
1810
+ options.position = new google.maps.LatLng(options.lat, options.lng);
1811
+
1812
+ delete options.el;
1813
+ delete options.context;
1814
+ delete options.lat;
1815
+ delete options.lng;
1816
+
1817
+ var streetview_events = ['closeclick', 'links_changed', 'pano_changed', 'position_changed', 'pov_changed', 'resize', 'visible_changed'],
1818
+ streetview_options = extend_object({visible : true}, options);
1819
+
1820
+ for (var i = 0; i < streetview_events.length; i++) {
1821
+ delete streetview_options[streetview_events[i]];
1822
+ }
1823
+
1824
+ var panorama = new google.maps.StreetViewPanorama(el, streetview_options);
1825
+
1826
+ for (var i = 0; i < streetview_events.length; i++) {
1827
+ (function(object, name) {
1828
+ if (options[name]) {
1829
+ google.maps.event.addListener(object, name, function(){
1830
+ options[name].apply(this);
1831
+ });
1832
+ }
1833
+ })(panorama, streetview_events[i]);
1834
+ }
1835
+
1836
+ return panorama;
1837
+ };
1838
+
1839
+ GMaps.prototype.on = function(event_name, handler) {
1840
+ return GMaps.on(event_name, this, handler);
1841
+ };
1842
+
1843
+ GMaps.prototype.off = function(event_name) {
1844
+ GMaps.off(event_name, this);
1845
+ };
1846
+
1847
+ GMaps.custom_events = ['marker_added', 'marker_removed', 'polyline_added', 'polyline_removed', 'polygon_added', 'polygon_removed', 'geolocated', 'geolocation_failed'];
1848
+
1849
+ GMaps.on = function(event_name, object, handler) {
1850
+ if (GMaps.custom_events.indexOf(event_name) == -1) {
1851
+ return google.maps.event.addListener(object, event_name, handler);
1852
+ }
1853
+ else {
1854
+ var registered_event = {
1855
+ handler : handler,
1856
+ eventName : event_name
1857
+ };
1858
+
1859
+ object.registered_events[event_name] = object.registered_events[event_name] || [];
1860
+ object.registered_events[event_name].push(registered_event);
1861
+
1862
+ return registered_event;
1863
+ }
1864
+ };
1865
+
1866
+ GMaps.off = function(event_name, object) {
1867
+ if (GMaps.custom_events.indexOf(event_name) == -1) {
1868
+ google.maps.event.clearListeners(object, event_name);
1869
+ }
1870
+ else {
1871
+ object.registered_events[event_name] = [];
1872
+ }
1873
+ };
1874
+
1875
+ GMaps.fire = function(event_name, object, scope) {
1876
+ if (GMaps.custom_events.indexOf(event_name) == -1) {
1877
+ google.maps.event.trigger(object, event_name, Array.prototype.slice.apply(arguments).slice(2));
1878
+ }
1879
+ else {
1880
+ if(event_name in scope.registered_events) {
1881
+ var firing_events = scope.registered_events[event_name];
1882
+
1883
+ for(var i = 0; i < firing_events.length; i++) {
1884
+ (function(handler, scope, object) {
1885
+ handler.apply(scope, [object]);
1886
+ })(firing_events[i]['handler'], scope, object);
1887
+ }
1888
+ }
1889
+ }
1890
+ };
1891
+
1892
+ GMaps.geolocate = function(options) {
1893
+ var complete_callback = options.always || options.complete;
1894
+
1895
+ if (navigator.geolocation) {
1896
+ navigator.geolocation.getCurrentPosition(function(position) {
1897
+ options.success(position);
1898
+
1899
+ if (complete_callback) {
1900
+ complete_callback();
1901
+ }
1902
+ }, function(error) {
1903
+ options.error(error);
1904
+
1905
+ if (complete_callback) {
1906
+ complete_callback();
1907
+ }
1908
+ }, options.options);
1909
+ }
1910
+ else {
1911
+ options.not_supported();
1912
+
1913
+ if (complete_callback) {
1914
+ complete_callback();
1915
+ }
1916
+ }
1917
+ };
1918
+
1919
+ GMaps.geocode = function(options) {
1920
+ this.geocoder = new google.maps.Geocoder();
1921
+ var callback = options.callback;
1922
+ if (options.hasOwnProperty('lat') && options.hasOwnProperty('lng')) {
1923
+ options.latLng = new google.maps.LatLng(options.lat, options.lng);
1924
+ }
1925
+
1926
+ delete options.lat;
1927
+ delete options.lng;
1928
+ delete options.callback;
1929
+
1930
+ this.geocoder.geocode(options, function(results, status) {
1931
+ callback(results, status);
1932
+ });
1933
+ };
1934
+
1935
+ //==========================
1936
+ // Polygon containsLatLng
1937
+ // https://github.com/tparkin/Google-Maps-Point-in-Polygon
1938
+ // Poygon getBounds extension - google-maps-extensions
1939
+ // http://code.google.com/p/google-maps-extensions/source/browse/google.maps.Polygon.getBounds.js
1940
+ if (!google.maps.Polygon.prototype.getBounds) {
1941
+ google.maps.Polygon.prototype.getBounds = function(latLng) {
1942
+ var bounds = new google.maps.LatLngBounds();
1943
+ var paths = this.getPaths();
1944
+ var path;
1945
+
1946
+ for (var p = 0; p < paths.getLength(); p++) {
1947
+ path = paths.getAt(p);
1948
+ for (var i = 0; i < path.getLength(); i++) {
1949
+ bounds.extend(path.getAt(i));
1950
+ }
1951
+ }
1952
+
1953
+ return bounds;
1954
+ };
1955
+ }
1956
+
1957
+ if (!google.maps.Polygon.prototype.containsLatLng) {
1958
+ // Polygon containsLatLng - method to determine if a latLng is within a polygon
1959
+ google.maps.Polygon.prototype.containsLatLng = function(latLng) {
1960
+ // Exclude points outside of bounds as there is no way they are in the poly
1961
+ var bounds = this.getBounds();
1962
+
1963
+ if (bounds !== null && !bounds.contains(latLng)) {
1964
+ return false;
1965
+ }
1966
+
1967
+ // Raycast point in polygon method
1968
+ var inPoly = false;
1969
+
1970
+ var numPaths = this.getPaths().getLength();
1971
+ for (var p = 0; p < numPaths; p++) {
1972
+ var path = this.getPaths().getAt(p);
1973
+ var numPoints = path.getLength();
1974
+ var j = numPoints - 1;
1975
+
1976
+ for (var i = 0; i < numPoints; i++) {
1977
+ var vertex1 = path.getAt(i);
1978
+ var vertex2 = path.getAt(j);
1979
+
1980
+ if (vertex1.lng() < latLng.lng() && vertex2.lng() >= latLng.lng() || vertex2.lng() < latLng.lng() && vertex1.lng() >= latLng.lng()) {
1981
+ if (vertex1.lat() + (latLng.lng() - vertex1.lng()) / (vertex2.lng() - vertex1.lng()) * (vertex2.lat() - vertex1.lat()) < latLng.lat()) {
1982
+ inPoly = !inPoly;
1983
+ }
1984
+ }
1985
+
1986
+ j = i;
1987
+ }
1988
+ }
1989
+
1990
+ return inPoly;
1991
+ };
1992
+ }
1993
+
1994
+ google.maps.LatLngBounds.prototype.containsLatLng = function(latLng) {
1995
+ return this.contains(latLng);
1996
+ };
1997
+
1998
+ google.maps.Marker.prototype.setFences = function(fences) {
1999
+ this.fences = fences;
2000
+ };
2001
+
2002
+ google.maps.Marker.prototype.addFence = function(fence) {
2003
+ this.fences.push(fence);
2004
+ };
2005
+
2006
+ google.maps.Marker.prototype.getId = function() {
2007
+ return this['__gm_id'];
2008
+ };
2009
+
2010
+ //==========================
2011
+ // Array indexOf
2012
+ // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
2013
+ if (!Array.prototype.indexOf) {
2014
+ Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
2015
+ "use strict";
2016
+ if (this == null) {
2017
+ throw new TypeError();
2018
+ }
2019
+ var t = Object(this);
2020
+ var len = t.length >>> 0;
2021
+ if (len === 0) {
2022
+ return -1;
2023
+ }
2024
+ var n = 0;
2025
+ if (arguments.length > 1) {
2026
+ n = Number(arguments[1]);
2027
+ if (n != n) { // shortcut for verifying if it's NaN
2028
+ n = 0;
2029
+ } else if (n != 0 && n != Infinity && n != -Infinity) {
2030
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
2031
+ }
2032
+ }
2033
+ if (n >= len) {
2034
+ return -1;
2035
+ }
2036
+ var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
2037
+ for (; k < len; k++) {
2038
+ if (k in t && t[k] === searchElement) {
2039
+ return k;
2040
+ }
2041
+ }
2042
+ return -1;
2043
+ }
2044
+ }