quantum 0.0.2

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