gmapsjs 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gmapsjs.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Alvaro Pereyra
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Gmapsjs
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'gmapsjs'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install gmapsjs
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,1124 @@
1
+ var GMaps = (function($) {
2
+ "use strict";
3
+
4
+ var GMaps = function(options) {
5
+ var self = this;
6
+ var context_menu_style = 'position:absolute;display:none;min-width:100px;' +
7
+ 'background:white;list-style:none;padding:8px;box-shadow:2px 2px 6px #ccc';
8
+ window.context_menu = {};
9
+
10
+ this.div = $(options.div)[0];
11
+ this.overlays = [];
12
+ this.markers = [];
13
+ this.polylines = [];
14
+ this.routes = [];
15
+ this.polygons = [];
16
+ this.infoWindow = null;
17
+ this.overlay_div = null;
18
+ this.zoom = options.zoom || 15;
19
+
20
+ //'Hybrid', 'Roadmap', 'Satellite' or 'Terrain'
21
+ var mapType;
22
+
23
+ if (options.mapType) {
24
+ mapType = google.maps.MapTypeId[options.mapType.toUpperCase()];
25
+ }
26
+ else {
27
+ mapType = google.maps.MapTypeId.ROADMAP;
28
+ }
29
+
30
+ var map_center = new google.maps.LatLng(options.lat, options.lng);
31
+
32
+ delete options.lat;
33
+ delete options.lng;
34
+ delete options.mapType;
35
+
36
+ var map_base_options = {
37
+ zoom: this.zoom,
38
+ center: map_center,
39
+ mapTypeId: mapType
40
+ };
41
+
42
+ var map_options = $.extend(map_base_options, options);
43
+
44
+ this.map = new google.maps.Map(this.div, map_options);
45
+
46
+ // Context menus
47
+ var buildContextMenuHTML = function(control, e) {
48
+ var html = '';
49
+ var options = window.context_menu[control];
50
+ for (var i in options){
51
+ if (options.hasOwnProperty(i)){
52
+ var option = options[i];
53
+ html += '<li><a id="' + control + '_' + i + '" href="#">' +
54
+ option.title + '</a></li>';
55
+ }
56
+ }
57
+ var $context_menu = $('#gmaps_context_menu');
58
+ $context_menu.html(html);
59
+ $context_menu.undelegate();
60
+ $context_menu.delegate('li a', 'click', function(ev) {
61
+ ev.preventDefault();
62
+ options[$(this).attr('id').replace(control + '_', '')].action.call(self, e);
63
+ self.hideContextMenu();
64
+ });
65
+
66
+ var left = $(self.div).offset().left + e.pixel.x - 15;
67
+ var top = $(self.div).offset().top + e.pixel.y - 15;
68
+ $context_menu.css({
69
+ left: left,
70
+ top: top
71
+ }).fadeIn(200);
72
+ };
73
+
74
+ var buildContextMenu = function(control, e) {
75
+ if (control === 'marker') {
76
+ e.pixel = {};
77
+ var overlay = new google.maps.OverlayView();
78
+ overlay.setMap(self.map);
79
+ overlay.draw = function() {
80
+ var projection = overlay.getProjection();
81
+ var position = e.marker.getPosition();
82
+ e.pixel = projection.fromLatLngToContainerPixel(position);
83
+
84
+ buildContextMenuHTML(control, e);
85
+ };
86
+ }
87
+ else {
88
+ buildContextMenuHTML(control, e);
89
+ }
90
+ };
91
+
92
+ this.setContextMenu = function(options) {
93
+ window.context_menu[options.control] = {};
94
+ var html = '<ul id="gmaps_context_menu" style="' + context_menu_style + '"></ul>';
95
+ for (var i in options.options){
96
+ if (options.options.hasOwnProperty(i)){
97
+ var option = options.options[i];
98
+ window.context_menu[options.control][option.name] = {
99
+ title: option.title,
100
+ action: option.action
101
+ };
102
+ }
103
+ }
104
+ $('body').append(html);
105
+ $('#gmaps_context_menu').mouseleave(function() {
106
+ $(this).delay(100).fadeOut(200);
107
+ });
108
+ };
109
+
110
+ this.hideContextMenu = function() {
111
+ $('#gmaps_context_menu').fadeOut(200);
112
+ };
113
+
114
+ //Events
115
+ google.maps.event.addListener(this.map, 'bounds_changed', function(e) {
116
+ if (options.bounds_changed) {
117
+ options.bounds_changed(e);
118
+ }
119
+ self.hideContextMenu();
120
+ });
121
+ google.maps.event.addListener(this.map, 'center_changed', function(e) {
122
+ if (options.center_changed) {
123
+ options.center_changed(e);
124
+ }
125
+ self.hideContextMenu();
126
+ });
127
+ google.maps.event.addListener(this.map, 'click', function(e) {
128
+ if (options.click) {
129
+ options.click(e);
130
+ }
131
+ self.hideContextMenu();
132
+ });
133
+ google.maps.event.addListener(this.map, 'dblclick', function(e) {
134
+ if (options.dblclick) {
135
+ options.dblclick(e);
136
+ }
137
+ self.hideContextMenu();
138
+ });
139
+ google.maps.event.addListener(this.map, 'drag', function(e) {
140
+ if (options.drag) {
141
+ options.drag(e);
142
+ }
143
+ self.hideContextMenu();
144
+ });
145
+ google.maps.event.addListener(this.map, 'dragend', function(e) {
146
+ if (options.dragend) {
147
+ options.dragend(e);
148
+ }
149
+ self.hideContextMenu();
150
+ });
151
+ google.maps.event.addListener(this.map, 'dragstart', function(e) {
152
+ if (options.dragstart) {
153
+ options.dragstart(e);
154
+ }
155
+ self.hideContextMenu();
156
+ });
157
+ google.maps.event.addListener(this.map, 'idle', function(e) {
158
+ if (options.idle) {
159
+ options.idle(e);
160
+ }
161
+ self.hideContextMenu();
162
+ });
163
+ google.maps.event.addListener(this.map, 'maptypeid_changed', function(e) {
164
+ if (options.maptypeid_changed) {
165
+ options.maptypeid_changed(e);
166
+ }
167
+ self.hideContextMenu();
168
+ });
169
+ google.maps.event.addListener(this.map, 'mousemove', function(e) {
170
+ if (options.mousemove) {
171
+ options.mousemove(e);
172
+ }
173
+ });
174
+ google.maps.event.addListener(this.map, 'mouseout', function(e) {
175
+ if (options.mouseout) {
176
+ options.mouseout(e);
177
+ }
178
+ });
179
+ google.maps.event.addListener(this.map, 'mouseover', function(e) {
180
+ if (options.mouseover) {
181
+ options.mouseover(e);
182
+ }
183
+ });
184
+ google.maps.event.addListener(this.map, 'projection_changed', function(e) {
185
+ if (options.projection_changed) {
186
+ options.projection_changed(e);
187
+ }
188
+ self.hideContextMenu();
189
+ });
190
+ google.maps.event.addListener(this.map, 'resize', function(e) {
191
+ if (options.resize) {
192
+ options.resize(e);
193
+ }
194
+ self.hideContextMenu();
195
+ });
196
+ google.maps.event.addListener(this.map, 'rightclick', function(e) {
197
+ if (options.rightclick) {
198
+ options.rightclick(e);
199
+ }
200
+
201
+ buildContextMenu('map', e);
202
+ });
203
+ google.maps.event.addListener(this.map, 'tilesloaded', function(e) {
204
+ if (options.tilesloaded) {
205
+ options.tilesloaded(e);
206
+ }
207
+ self.hideContextMenu();
208
+ });
209
+ google.maps.event.addListener(this.map, 'zoom_changed', function(e) {
210
+ if (options.zoom_changed) {
211
+ options.zoom_changed(e);
212
+ }
213
+ self.hideContextMenu();
214
+ });
215
+
216
+ // Map methods
217
+ this.setCenter = function(lat, lng, callback) {
218
+ this.map.panTo(new google.maps.LatLng(lat, lng));
219
+ if (callback) {
220
+ callback();
221
+ }
222
+ };
223
+
224
+ this.getCenter = function() {
225
+ return this.map.getCenter();
226
+ };
227
+
228
+ this.getDiv = function() {
229
+ return this.div;
230
+ };
231
+
232
+ this.setZoom = function(value) {
233
+ this.map.setZoom(value);
234
+ };
235
+
236
+ this.zoomIn = function(value) {
237
+ this.map.setZoom(this.map.getZoom() + value);
238
+ };
239
+
240
+ this.zoomOut = function(value) {
241
+ this.map.setZoom(this.map.getZoom() - value);
242
+ };
243
+
244
+ // Markers
245
+ this.createMarker = function(options) {
246
+ if (options.lat && options.lng) {
247
+ var self = this;
248
+ var details = options.details;
249
+ var fences = options.fences;
250
+ var outside = options.outside;
251
+ var base_options = {
252
+ position: new google.maps.LatLng(options.lat, options.lng),
253
+ map: null
254
+ };
255
+ delete options.lat;
256
+ delete options.lng;
257
+ delete options.fences;
258
+ delete options.outside;
259
+
260
+ var marker_options = $.extend(base_options, options);
261
+
262
+ var marker = new google.maps.Marker(marker_options);
263
+
264
+ marker.fences = fences;
265
+
266
+ if (options.infoWindow) {
267
+ marker.infoWindow = new google.maps.InfoWindow(options.infoWindow);
268
+
269
+ if (options.infoWindow.closeclick) {
270
+ google.maps.event.addListener(marker.infoWindow, 'closeclick', function() {
271
+ options.infoWindow.closeclick();
272
+ });
273
+ }
274
+ if (options.infoWindow.content_changed) {
275
+ google.maps.event.addListener(marker.infoWindow, 'content_changed', function() {
276
+ options.infoWindow.content_changed();
277
+ });
278
+ }
279
+ if (options.infoWindow.domready) {
280
+ google.maps.event.addListener(marker.infoWindow, 'domready', function() {
281
+ options.infoWindow.domready();
282
+ });
283
+ }
284
+ if (options.infoWindow.position_changed) {
285
+ google.maps.event.addListener(marker.infoWindow, 'position_changed', function() {
286
+ options.infoWindow.position_changed();
287
+ });
288
+ }
289
+ if (options.infoWindow.zindex_changed) {
290
+ google.maps.event.addListener(marker.infoWindow, 'zindex_changed', function() {
291
+ options.infoWindow.zindex_changed();
292
+ });
293
+ }
294
+ }
295
+
296
+ google.maps.event.addListener(marker, 'click', function() {
297
+ this.details = details;
298
+
299
+ if (options.click) {
300
+ options.click.apply(this, [this]);
301
+ }
302
+
303
+ if (marker.infoWindow) {
304
+ self.hideInfoWindows();
305
+ marker.infoWindow.open(self.map, marker);
306
+ }
307
+ });
308
+
309
+ if (options.drag) {
310
+ google.maps.event.addListener(marker, 'drag', function() {
311
+ options.drag(this);
312
+ });
313
+ }
314
+ if (options.dragend || marker.fences) {
315
+ google.maps.event.addListener(marker, 'dragend', function() {
316
+ if (options.dragend) {
317
+ options.dragend(this);
318
+ }
319
+ if (marker.fences) {
320
+ self.checkMarkerGeofence(marker, function(m, f) {
321
+ outside(m, f);
322
+ });
323
+ }
324
+ });
325
+ }
326
+ if (options.dragstart) {
327
+ google.maps.event.addListener(marker, 'dragstart', function() {
328
+ options.dragstart(this);
329
+ });
330
+ }
331
+ if (options.mouseout) {
332
+ google.maps.event.addListener(marker, 'mouseout', function() {
333
+ options.mouseout(this);
334
+ });
335
+ }
336
+ if (options.mouseover) {
337
+ google.maps.event.addListener(marker, 'mouseover', function() {
338
+ options.mouseover(this);
339
+ });
340
+ }
341
+ if (options.mouseup) {
342
+ google.maps.event.addListener(marker, 'mouseup', function() {
343
+ options.mouseup(this);
344
+ });
345
+ }
346
+ if (options.position_changed) {
347
+ google.maps.event.addListener(marker, 'position_changed', function() {
348
+ options.position_changed(this);
349
+ });
350
+ }
351
+
352
+ return marker;
353
+ }
354
+ else {
355
+ throw 'No latitude or longitude defined';
356
+ }
357
+ };
358
+
359
+ this.addMarker = function(options) {
360
+ if (options.lat && options.lng) {
361
+ var marker = this.createMarker(options);
362
+ marker.setMap(this.map);
363
+ this.markers.push(marker);
364
+
365
+ return marker;
366
+ }
367
+ else {
368
+ throw 'No latitude or longitude defined';
369
+ }
370
+ };
371
+
372
+ this.addMarkers = function(array) {
373
+ for (var i=0, marker; marker=array[i]; i++) {
374
+ this.addMarker(marker);
375
+ }
376
+ return this.markers;
377
+ };
378
+
379
+ this.hideInfoWindows = function() {
380
+ for (var i=0, marker; marker=this.markers[i]; i++){
381
+ if (marker.infoWindow){
382
+ marker.infoWindow.close();
383
+ }
384
+ }
385
+ };
386
+
387
+ this.removeMarkers = function() {
388
+ for (var i=0, marker; marker=this.markers[i]; i++){
389
+ marker.setMap(null);
390
+ }
391
+ this.markers = [];
392
+ };
393
+
394
+ // Overlays
395
+ this.drawOverlay = function(options) {
396
+ var overlay = new google.maps.OverlayView();
397
+ overlay.setMap(self.map);
398
+
399
+ overlay.onAdd = function() {
400
+ var div = document.createElement('div');
401
+ div.style.borderStyle = "none";
402
+ div.style.borderWidth = "0px";
403
+ div.style.position = "absolute";
404
+ div.innerHTML = options.content;
405
+
406
+ self.overlay_div = div;
407
+
408
+ var panes = this.getPanes();
409
+ if (!options.layer) {
410
+ options.layer = 'overlayLayer';
411
+ }
412
+ var overlayLayer = panes[options.layer];
413
+ overlayLayer.appendChild(div);
414
+ };
415
+
416
+ overlay.draw = function() {
417
+ var projection = this.getProjection();
418
+ var pixel = projection.fromLatLngToDivPixel(new google.maps.LatLng(options.lat, options.lng));
419
+
420
+ options.horizontalOffset = options.horizontalOffset || 0;
421
+ options.verticalOffset = options.verticalOffset || 0;
422
+
423
+ var div = self.overlay_div;
424
+ var content = div.children;
425
+
426
+ switch (options.verticalAlign) {
427
+ case 'top':
428
+ div.style.top = (pixel.y - $(content).height() + options.verticalOffset) + 'px';
429
+ break;
430
+ default:
431
+ case 'middle':
432
+ div.style.top = (pixel.y - ($(content).height() / 2) + options.verticalOffset) + 'px';
433
+ break;
434
+ case 'bottom':
435
+ div.style.top = (pixel.y + options.verticalOffset) + 'px';
436
+ break;
437
+ }
438
+
439
+ switch (options.horizontalAlign) {
440
+ case 'left':
441
+ div.style.left = (pixel.x - $(content).width() + options.horizontalOffset) + 'px';
442
+ break;
443
+ default:
444
+ case 'center':
445
+ div.style.left = (pixel.x - ($(content).width() / 2) + options.horizontalOffset) + 'px';
446
+ break;
447
+ case 'right':
448
+ div.style.left = (pixel.x + options.horizontalOffset) + 'px';
449
+ break;
450
+ }
451
+ };
452
+
453
+ overlay.onRemove = function() {
454
+ self.overlay_div.parentNode.removeChild(self.overlay_div);
455
+ self.overlay_div = null;
456
+ };
457
+ self.overlays.push(overlay);
458
+ return overlay;
459
+ };
460
+
461
+ this.removeOverlay = function(overlay) {
462
+ overlay.setMap(null);
463
+ };
464
+
465
+ this.removeOverlays = function() {
466
+ for (var i=0, item; item=self.overlays[i]; i++){
467
+ item.setMap(null);
468
+ }
469
+ self.overlays = [];
470
+ };
471
+
472
+ this.drawPolyline = function(options) {
473
+ var path = [];
474
+ var points = options.path;
475
+
476
+ if (points.length){
477
+ if (points[0][0] === undefined){
478
+ path = points;
479
+ }
480
+ else {
481
+ for (var i=0, latlng; latlng=points[i]; i++){
482
+ path.push(new google.maps.LatLng(latlng[0], latlng[1]));
483
+ }
484
+ }
485
+ }
486
+
487
+ var polyline = new google.maps.Polyline({
488
+ map: this.map,
489
+ path: path,
490
+ strokeColor: options.strokeColor,
491
+ strokeOpacity: options.strokeOpacity,
492
+ strokeWeight: options.strokeWeight
493
+ });
494
+
495
+ if (options.click) {
496
+ google.maps.event.addListener(polyline, 'click', function(e) {
497
+ options.click(e);
498
+ });
499
+ }
500
+ if (options.dblclick) {
501
+ google.maps.event.addListener(polyline, 'dblclick', function(e) {
502
+ options.dblclick(e);
503
+ });
504
+ }
505
+ if (options.mousedown) {
506
+ google.maps.event.addListener(polyline, 'mousedown', function(e) {
507
+ options.mousedown(e);
508
+ });
509
+ }
510
+ if (options.mousemove) {
511
+ google.maps.event.addListener(polyline, 'mousemove', function(e) {
512
+ options.mousemove(e);
513
+ });
514
+ }
515
+ if (options.mouseout) {
516
+ google.maps.event.addListener(polyline, 'mouseout', function(e) {
517
+ options.mouseout(e);
518
+ });
519
+ }
520
+ if (options.mouseover) {
521
+ google.maps.event.addListener(polyline, 'mouseover', function(e) {
522
+ options.mouseover(e);
523
+ });
524
+ }
525
+ if (options.mouseup) {
526
+ google.maps.event.addListener(polyline, 'mouseup', function(e) {
527
+ options.mouseup(e);
528
+ });
529
+ }
530
+ if (options.rightclick) {
531
+ google.maps.event.addListener(polyline, 'rightclick', function(e) {
532
+ options.rightclick(e);
533
+ });
534
+ }
535
+
536
+ this.polylines.push(polyline);
537
+
538
+ return polyline;
539
+ };
540
+
541
+ this.drawCircle = function(options) {
542
+ options = $.extend({
543
+ map: this.map,
544
+ center: new google.maps.LatLng(options.lat, options.lng)
545
+ }, options);
546
+
547
+ delete options.lat;
548
+ delete options.lng;
549
+ var polygon = new google.maps.Circle(options);
550
+
551
+ google.maps.event.addListener(polygon, 'click', function(e) {
552
+ if (options.click) {
553
+ options.click(e);
554
+ }
555
+ });
556
+ google.maps.event.addListener(polygon, 'dblclick', function(e) {
557
+ if (options.dblclick) {
558
+ options.dblclick(e);
559
+ }
560
+ });
561
+ google.maps.event.addListener(polygon, 'mousedown', function(e) {
562
+ if (options.mousedown) {
563
+ options.mousedown(e);
564
+ }
565
+ });
566
+ google.maps.event.addListener(polygon, 'mousemove', function(e) {
567
+ if (options.mousemove) {
568
+ options.mousemove(e);
569
+ }
570
+ });
571
+ google.maps.event.addListener(polygon, 'mouseout', function(e) {
572
+ if (options.mouseout) {
573
+ options.mouseout(e);
574
+ }
575
+ });
576
+ google.maps.event.addListener(polygon, 'mouseover', function(e) {
577
+ if (options.mouseover) {
578
+ options.mouseover(e);
579
+ }
580
+ });
581
+ google.maps.event.addListener(polygon, 'mouseup', function(e) {
582
+ if (options.mouseup) {
583
+ options.mouseup(e);
584
+ }
585
+ });
586
+ google.maps.event.addListener(polygon, 'rightclick', function(e) {
587
+ if (options.rightclick) {
588
+ options.rightclick(e);
589
+ }
590
+ });
591
+
592
+ return polygon;
593
+ };
594
+
595
+ this.drawPolygon = function(options) {
596
+ options = $.extend({
597
+ map: this.map
598
+ }, options);
599
+ var polygon = new google.maps.Polygon(options);
600
+
601
+ google.maps.event.addListener(polygon, 'click', function(e) {
602
+ if (options.click) {
603
+ options.click(e);
604
+ }
605
+ });
606
+ google.maps.event.addListener(polygon, 'dblclick', function(e) {
607
+ if (options.dblclick) {
608
+ options.dblclick(e);
609
+ }
610
+ });
611
+ google.maps.event.addListener(polygon, 'mousedown', function(e) {
612
+ if (options.mousedown) {
613
+ options.mousedown(e);
614
+ }
615
+ });
616
+ google.maps.event.addListener(polygon, 'mousemove', function(e) {
617
+ if (options.mousemove) {
618
+ options.mousemove(e);
619
+ }
620
+ });
621
+ google.maps.event.addListener(polygon, 'mouseout', function(e) {
622
+ if (options.mouseout) {
623
+ options.mouseout(e);
624
+ }
625
+ });
626
+ google.maps.event.addListener(polygon, 'mouseover', function(e) {
627
+ if (options.mouseover) {
628
+ options.mouseover(e);
629
+ }
630
+ });
631
+ google.maps.event.addListener(polygon, 'mouseup', function(e) {
632
+ if (options.mouseup) {
633
+ options.mouseup(e);
634
+ }
635
+ });
636
+ google.maps.event.addListener(polygon, 'rightclick', function(e) {
637
+ if (options.rightclick) {
638
+ options.rightclick(e);
639
+ }
640
+ });
641
+
642
+ this.polygons.push(polygon);
643
+
644
+ return polygon;
645
+ };
646
+
647
+ // Services
648
+ var travelMode, unitSystem;
649
+ this.getRoutes = function(options) {
650
+ switch (options.travelMode) {
651
+ case 'bicycling':
652
+ travelMode = google.maps.TravelMode.BICYCLING;
653
+ break;
654
+ case 'driving':
655
+ travelMode = google.maps.TravelMode.DRIVING;
656
+ break;
657
+ // case 'walking':
658
+ default:
659
+ travelMode = google.maps.TravelMode.WALKING;
660
+ break;
661
+ }
662
+
663
+ if (options.unitSystem === 'imperial') {
664
+ unitSystem = google.maps.UnitSystem.IMPERIAL;
665
+ }
666
+ else {
667
+ unitSystem = google.maps.UnitSystem.METRIC;
668
+ }
669
+
670
+ var base_options = {
671
+ avoidHighways: true,
672
+ avoidTolls: true,
673
+ optimizeWaypoints: true,
674
+ waypoints: []
675
+ };
676
+ var request_options = $.extend(base_options, options);
677
+ request_options.origin = new google.maps.LatLng(options.origin[0], options.origin[1]);
678
+ request_options.destination = new google.maps.LatLng(options.destination[0], options.destination[1]);
679
+ request_options.travelMode = travelMode;
680
+ request_options.unitSystem = unitSystem;
681
+
682
+ delete request_options.callback;
683
+
684
+ var self = this;
685
+ var service = new google.maps.DirectionsService();
686
+
687
+ service.route(request_options, function(result, status) {
688
+ if (status === google.maps.DirectionsStatus.OK) {
689
+ for (var r in result.routes) {
690
+ if (result.routes.hasOwnProperty(r)) {
691
+ self.routes.push(result.routes[r]);
692
+ }
693
+ }
694
+ }
695
+ if (options.callback) {
696
+ options.callback(self.routes);
697
+ }
698
+ });
699
+ };
700
+
701
+ this.drawRoute = function(options) {
702
+ var self = this;
703
+ this.getRoutes({
704
+ origin: options.origin,
705
+ destination: options.destination,
706
+ travelMode: options.travelMode,
707
+ callback: function(e) {
708
+ if (e.length > 0) {
709
+ self.drawPolyline({
710
+ path: e[e.length - 1].overview_path,
711
+ strokeColor: options.strokeColor,
712
+ strokeOpacity: options.strokeOpacity,
713
+ strokeWeight: options.strokeWeight
714
+ });
715
+ if (options.callback) {
716
+ options.callback(e[e.length - 1]);
717
+ }
718
+ }
719
+ }
720
+ });
721
+ };
722
+
723
+ this.travelRoute = function(options) {
724
+ if (options.origin && options.destination) {
725
+ this.getRoutes({
726
+ origin: options.origin,
727
+ destination: options.destination,
728
+ travelMode: options.travelMode,
729
+ callback: function(e) {
730
+ if (e.length > 0 && options.step) {
731
+ var route = e[e.length - 1];
732
+ if (route.legs.length > 0) {
733
+ var steps = route.legs[0].steps;
734
+ for (var i=0, step; step=steps[i]; i++) {
735
+ step.step_number = i;
736
+ options.step(step);
737
+ }
738
+ }
739
+ }
740
+ }
741
+ });
742
+ }
743
+ else if (options.route) {
744
+ if (options.route.legs.length > 0) {
745
+ var steps = options.route.legs[0].steps;
746
+ for (var i=0, step; step=steps[i]; i++) {
747
+ step.step_number = i;
748
+ options.step(step);
749
+ }
750
+ }
751
+ }
752
+ };
753
+
754
+ this.drawSteppedRoute = function(options) {
755
+ if (options.origin && options.destination) {
756
+ this.getRoutes({
757
+ origin: options.origin,
758
+ destination: options.destination,
759
+ travelMode: options.travelMode,
760
+ callback: function(e) {
761
+ if (e.length > 0 && options.step) {
762
+ var route = e[e.length - 1];
763
+ if (route.legs.length > 0) {
764
+ var steps = route.legs[0].steps;
765
+ for (var i=0, step; step=steps[i]; i++) {
766
+ step.step_number = i;
767
+ self.drawPolyline({
768
+ path: step.path,
769
+ strokeColor: options.strokeColor,
770
+ strokeOpacity: options.strokeOpacity,
771
+ strokeWeight: options.strokeWeight
772
+ });
773
+ options.step(step);
774
+ }
775
+ }
776
+ }
777
+ }
778
+ });
779
+ }
780
+ else if (options.route) {
781
+ if (options.route.legs.length > 0) {
782
+ var steps = options.route.legs[0].steps;
783
+ for (var i=0, step; step=steps[i]; i++) {
784
+ step.step_number = i;
785
+ self.drawPolyline({
786
+ path: step.path,
787
+ strokeColor: options.strokeColor,
788
+ strokeOpacity: options.strokeOpacity,
789
+ strokeWeight: options.strokeWeight
790
+ });
791
+ options.step(step);
792
+ }
793
+ }
794
+ }
795
+ };
796
+
797
+ // Geofence
798
+ this.checkGeofence = function(lat, lng, fence) {
799
+ return fence.containsLatLng(new google.maps.LatLng(lat, lng));
800
+ };
801
+
802
+ this.checkMarkerGeofence = function(marker, outside_callback) {
803
+ if (marker.fences) {
804
+ for (var i=0, fence; fence=marker.fences[i]; i++) {
805
+ var pos = marker.getPosition();
806
+ if (!self.checkGeofence(pos.lat(), pos.lng(), fence)) {
807
+ outside_callback(marker, fence);
808
+ }
809
+ }
810
+ }
811
+ };
812
+ };
813
+
814
+ GMaps.Route = function(options) {
815
+ this.map = options.map;
816
+ this.route = options.route;
817
+ this.step_count = 0;
818
+ this.steps = this.route.legs[0].steps;
819
+ this.steps_length = this.steps.length;
820
+
821
+ this.polyline = this.map.drawPolyline({
822
+ path: new google.maps.MVCArray(),
823
+ strokeColor: options.strokeColor,
824
+ strokeOpacity: options.strokeOpacity,
825
+ strokeWeight: options.strokeWeight
826
+ }).getPath();
827
+
828
+ this.back = function() {
829
+ if (this.step_count > 0) {
830
+ this.step_count--;
831
+ var path = this.route.legs[0].steps[this.step_count].path;
832
+ for (var p in path){
833
+ if (path.hasOwnProperty(p)){
834
+ this.polyline.pop();
835
+ }
836
+ }
837
+ }
838
+ };
839
+
840
+ this.forward = function() {
841
+ if (this.step_count < this.steps_length) {
842
+ var path = this.route.legs[0].steps[this.step_count].path;
843
+ for (var p in path){
844
+ if (path.hasOwnProperty(p)){
845
+ this.polyline.push(path[p]);
846
+ }
847
+ }
848
+ this.step_count++;
849
+ }
850
+ };
851
+ };
852
+
853
+ // Geolocation (Modern browsers only)
854
+ GMaps.geolocate = function(options) {
855
+ if (navigator.geolocation) {
856
+ navigator.geolocation.getCurrentPosition(function(position) {
857
+ options.success(position);
858
+ if (options.always) {
859
+ options.always();
860
+ }
861
+ }, function(error) {
862
+ options.error(error);
863
+ if (options.always) {
864
+ options.always();
865
+ }
866
+ }, options.options);
867
+ }
868
+ else {
869
+ options.not_supported();
870
+ if (options.always) {
871
+ options.always();
872
+ }
873
+ }
874
+ };
875
+
876
+ // Geocoding
877
+ GMaps.geocode = function(options) {
878
+ this.geocoder = new google.maps.Geocoder();
879
+ var callback = options.callback;
880
+ if (options.lat && options.lng) {
881
+ options.latLng = new google.maps.LatLng(options.lat, options.lng);
882
+ }
883
+
884
+ delete options.lat;
885
+ delete options.lng;
886
+ delete options.callback;
887
+ this.geocoder.geocode(options, function(results, status) {
888
+ callback(results, status);
889
+ });
890
+ };
891
+
892
+ // Static maps
893
+ GMaps.staticMapURL = function(options){
894
+ var parameters = [];
895
+ var data;
896
+
897
+ var static_root = 'http://maps.googleapis.com/maps/api/staticmap';
898
+ if (options.url){
899
+ static_root = options.url;
900
+ delete options.url;
901
+ }
902
+ static_root += '?';
903
+
904
+ var markers = options.markers;
905
+ delete options.markers;
906
+ if (!markers && options.marker){
907
+ markers = [options.marker];
908
+ delete options.marker;
909
+ }
910
+
911
+ var polyline = options.polyline;
912
+ delete options.polyline;
913
+
914
+ /** Map options **/
915
+ if (options.center){
916
+ parameters.push('center=' + options.center);
917
+ delete options.center;
918
+ }
919
+ else if (options.address){
920
+ parameters.push('center=' + options.address);
921
+ delete options.address;
922
+ }
923
+ else if (options.lat){
924
+ parameters.push(['center=', options.lat, ',', options.lng].join(''));
925
+ delete options.lat;
926
+ delete options.lng;
927
+ }
928
+ else if (options.visible){
929
+ var visible = encodeURI(options.visible.join('|'));
930
+ parameters.push('visible=' + visible);
931
+ }
932
+
933
+ var size = options.size;
934
+ if (size){
935
+ if (size.join){
936
+ size = size.join('x');
937
+ }
938
+ delete options.size;
939
+ }
940
+ else {
941
+ size = '630x300';
942
+ }
943
+ parameters.push('size=' + size);
944
+
945
+ if (!options.zoom){
946
+ options.zoom = 15;
947
+ }
948
+
949
+ var sensor = options.hasOwnProperty('sensor') ? !!options.sensor : true;
950
+ delete options.sensor;
951
+ parameters.push('sensor=' + sensor);
952
+
953
+ for (var param in options){
954
+ if (options.hasOwnProperty(param)){
955
+ parameters.push(param + '=' + options[param]);
956
+ }
957
+ }
958
+
959
+ /** Markers **/
960
+ if (markers){
961
+ var marker, loc;
962
+
963
+ for (var i=0; data=markers[i]; i++){
964
+ marker = [];
965
+
966
+ if (data.size && data.size !== 'normal'){
967
+ marker.push('size:' + data.size);
968
+ }
969
+ else if (data.icon){
970
+ marker.push('icon:' + encodeURI(data.icon));
971
+ }
972
+
973
+ if (data.color){
974
+ marker.push('color:' + data.color.replace('#', '0x'));
975
+ }
976
+
977
+ if (data.label){
978
+ marker.push('label:' + data.label[0].toUpperCase());
979
+ }
980
+
981
+ loc = (data.address ? data.address : data.lat + ',' + data.lng);
982
+
983
+ if (marker.length || i === 0){
984
+ marker.push(loc);
985
+ marker = marker.join('|');
986
+ parameters.push('markers=' + encodeURI(marker));
987
+ }
988
+ // New marker without styles
989
+ else {
990
+ marker = parameters.pop() + encodeURI('|' + loc);
991
+ parameters.push(marker);
992
+ }
993
+ }
994
+ }
995
+
996
+ /** Polylines **/
997
+ function parseColor(color, opacity){
998
+ if (color[0] === '#'){
999
+ color = color.replace('#', '0x');
1000
+
1001
+ if (opacity){
1002
+ opacity = parseFloat(opacity);
1003
+ opacity = Math.min(1, Math.max(opacity, 0));
1004
+ if (opacity === 0){
1005
+ return '0x00000000';
1006
+ }
1007
+ opacity = (opacity * 255).toString(16);
1008
+ if (opacity.length === 1){
1009
+ opacity += opacity;
1010
+ }
1011
+
1012
+ color = color.slice(0,8) + opacity;
1013
+ }
1014
+ }
1015
+ return color;
1016
+ }
1017
+
1018
+ if (polyline){
1019
+ data = polyline;
1020
+ polyline = [];
1021
+
1022
+ if (data.strokeWeight){
1023
+ polyline.push('weight:' + parseInt(data.strokeWeight, 10));
1024
+ }
1025
+
1026
+ if (data.strokeColor){
1027
+ var color = parseColor(data.strokeColor, data.strokeOpacity);
1028
+ polyline.push('color:' + color);
1029
+ }
1030
+
1031
+ if (data.fillColor){
1032
+ var fillcolor = parseColor(data.fillColor, data.fillOpacity);
1033
+ polyline.push('fillcolor:' + fillcolor);
1034
+ }
1035
+
1036
+ var path = data.path;
1037
+ if (path.join){
1038
+ for (var j=0, pos; pos=path[j]; j++){
1039
+ polyline.push(pos.join(','));
1040
+ }
1041
+ }
1042
+ else {
1043
+ polyline.push('enc:' + path);
1044
+ }
1045
+
1046
+ polyline = polyline.join('|');
1047
+ parameters.push('path=' + encodeURI(polyline));
1048
+ }
1049
+
1050
+ parameters = parameters.join('&');
1051
+ return static_root + parameters;
1052
+ };
1053
+
1054
+ //==========================
1055
+ // Polygon containsLatLng
1056
+ // https://github.com/tparkin/Google-Maps-Point-in-Polygon
1057
+ // Poygon getBounds extension - google-maps-extensions
1058
+ // http://code.google.com/p/google-maps-extensions/source/browse/google.maps.Polygon.getBounds.js
1059
+ if (!google.maps.Polygon.prototype.getBounds) {
1060
+ google.maps.Polygon.prototype.getBounds = function(latLng) {
1061
+ var bounds = new google.maps.LatLngBounds();
1062
+ var paths = this.getPaths();
1063
+ var path;
1064
+
1065
+ for (var p = 0; p < paths.getLength(); p++) {
1066
+ path = paths.getAt(p);
1067
+ for (var i = 0; i < path.getLength(); i++) {
1068
+ bounds.extend(path.getAt(i));
1069
+ }
1070
+ }
1071
+
1072
+ return bounds;
1073
+ };
1074
+ }
1075
+
1076
+ // Polygon containsLatLng - method to determine if a latLng is within a polygon
1077
+ google.maps.Polygon.prototype.containsLatLng = function(latLng) {
1078
+ // Exclude points outside of bounds as there is no way they are in the poly
1079
+ var bounds = this.getBounds();
1080
+
1081
+ if (bounds !== null && !bounds.contains(latLng)) {
1082
+ return false;
1083
+ }
1084
+
1085
+ // Raycast point in polygon method
1086
+ var inPoly = false;
1087
+
1088
+ var numPaths = this.getPaths().getLength();
1089
+ for (var p = 0; p < numPaths; p++) {
1090
+ var path = this.getPaths().getAt(p);
1091
+ var numPoints = path.getLength();
1092
+ var j = numPoints - 1;
1093
+
1094
+ for (var i = 0; i < numPoints; i++) {
1095
+ var vertex1 = path.getAt(i);
1096
+ var vertex2 = path.getAt(j);
1097
+
1098
+ if (vertex1.lng() < latLng.lng() && vertex2.lng() >= latLng.lng() || vertex2.lng() < latLng.lng() && vertex1.lng() >= latLng.lng()) {
1099
+ if (vertex1.lat() + (latLng.lng() - vertex1.lng()) / (vertex2.lng() - vertex1.lng()) * (vertex2.lat() - vertex1.lat()) < latLng.lat()) {
1100
+ inPoly = !inPoly;
1101
+ }
1102
+ }
1103
+
1104
+ j = i;
1105
+ }
1106
+ }
1107
+
1108
+ return inPoly;
1109
+ };
1110
+
1111
+ google.maps.LatLngBounds.prototype.containsLatLng = function(latLng) {
1112
+ return this.contains(latLng);
1113
+ };
1114
+
1115
+ google.maps.Marker.prototype.setFences = function(fences) {
1116
+ this.fences = fences;
1117
+ };
1118
+
1119
+ google.maps.Marker.prototype.addFence = function(fence) {
1120
+ this.fences.push(fence);
1121
+ };
1122
+
1123
+ return GMaps;
1124
+ }(jQuery));
@@ -0,0 +1 @@
1
+ //= require ./gmapsjs
data/gmapsjs.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+ # -*- encoding: utf-8 -*-
3
+ require File.expand_path('../lib/gmapsjs/version', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.authors = ["Alvaro Pereyra", "Gustavo Leon"]
7
+ gem.email = ["alvaro@xendacentral.com", "hpneo@gmail.com"]
8
+ gem.description = "gmaps.js allows you to use the potential of Google Maps in a simple way.
9
+ No more extensive documentation or large amount of code."
10
+ gem.summary = ""
11
+ gem.homepage = "http://hpneo.github.com/gmaps/"
12
+
13
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
14
+ gem.files = `git ls-files`.split("\n")
15
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ gem.name = "gmapsjs"
17
+ gem.require_paths = ["lib"]
18
+ gem.version = GmapsJS::VERSION
19
+ end
data/lib/gmapsjs.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "gmapsjs/version"
2
+
3
+ module GmapsJS
4
+ require 'gmapsjs/engine'
5
+ end
@@ -0,0 +1,5 @@
1
+ module GmapsJS
2
+ class Engine < Rails::Engine
3
+
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module GmapsJS
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gmapsjs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alvaro Pereyra
9
+ - Gustavo Leon
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-05-17 00:00:00.000000000Z
14
+ dependencies: []
15
+ description: ! 'gmaps.js allows you to use the potential of Google Maps in a simple
16
+ way.
17
+
18
+ No more extensive documentation or large amount of code.'
19
+ email:
20
+ - alvaro@xendacentral.com
21
+ - hpneo@gmail.com
22
+ executables: []
23
+ extensions: []
24
+ extra_rdoc_files: []
25
+ files:
26
+ - .gitignore
27
+ - Gemfile
28
+ - LICENSE
29
+ - README.md
30
+ - Rakefile
31
+ - app/assets/javascripts/gmapsjs/gmapsjs.js
32
+ - app/assets/javascripts/gmapsjs/index.js
33
+ - gmapsjs.gemspec
34
+ - lib/gmapsjs.rb
35
+ - lib/gmapsjs/engine.rb
36
+ - lib/gmapsjs/version.rb
37
+ homepage: http://hpneo.github.com/gmaps/
38
+ licenses: []
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 1.8.17
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: ''
61
+ test_files: []