gmap-rails 3.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ pkg
data/LICENSE ADDED
File without changes
@@ -0,0 +1 @@
1
+ http://www.smashinglabs.pl/gmap
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/gmap-rails/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["bokmann"]
6
+ gem.email = ["dbock@codesherpas.com"]
7
+ gem.description = %q{gmap is a helpful little Javascript library by Sebastian Poręba. I'm just turning it into an asset gem for the rails asset pipeline.}
8
+ gem.summary = %q{A simple asset pipeline bundling of the gmap javascript library.}
9
+ gem.homepage = "https://github.com/bokmann/fullcalendar-rails"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "gmap-rails"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Gmap::Rails::VERSION
17
+
18
+ gem.add_development_dependency "rake"
19
+ end
@@ -0,0 +1,8 @@
1
+ require "gmap-rails/version"
2
+
3
+ module Gmap
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Gmap
2
+ module Rails
3
+ VERSION = "3.3.2"
4
+ end
5
+ end
@@ -0,0 +1,872 @@
1
+ /**
2
+ * jQuery gMap v3
3
+ *
4
+ * @url http://www.smashinglabs.pl/gmap
5
+ * @author Sebastian Poreba <sebastian.poreba@gmail.com>
6
+ * @version 3.3.2
7
+ * @date 16.03.2011
8
+ */
9
+ /*jslint white: false, undef: true, regexp: true, plusplus: true, bitwise: true, newcap: true, strict: true, devel: true, maxerr: 50, indent: 4 */
10
+ /*global window, jQuery, $, google, $googlemaps */
11
+ (function ($) {
12
+ "use strict";
13
+
14
+ /**
15
+ * Internals and experimental section
16
+ */
17
+ var Cluster = function () {
18
+ this.markers = [];
19
+ this.mainMarker = false;
20
+ this.icon = "http://www.google.com/mapfiles/marker.png";
21
+ };
22
+
23
+ /**
24
+ * For iterating over all clusters to find if any is close enough to be merged with marker
25
+ *
26
+ * @param marker
27
+ * @param currentSize - calculated as viewport percentage (opts.clusterSize)
28
+ * @return bool
29
+ */
30
+ Cluster.prototype.dist = function (marker) {
31
+ return Math.sqrt(Math.pow(this.markers[0].latitude - marker.latitude, 2) +
32
+ Math.pow(this.markers[0].longitude - marker.longitude, 2));
33
+ };
34
+
35
+ Cluster.prototype.setIcon = function (icon) {
36
+ this.icon = icon;
37
+ };
38
+
39
+ Cluster.prototype.addMarker = function (marker) {
40
+ this.markers[this.markers.length] = marker;
41
+ };
42
+
43
+ /**
44
+ * returns one marker if there is only one or
45
+ * returns special cloister marker if there are more
46
+ */
47
+ Cluster.prototype.getMarker = function () {
48
+ if (this.mainmarker) {return this.mainmarker; }
49
+ var gicon, title;
50
+ if (this.markers.length > 1) {
51
+ gicon = new $googlemaps.MarkerImage("http://thydzik.com/thydzikGoogleMap/markerlink.php?text=" + this.markers.length + "&color=EF9D3F");
52
+ title = "cluster of " + this.markers.length + " markers";
53
+ } else {
54
+ gicon = new $googlemaps.MarkerImage(this.icon);
55
+ title = this.markers[0].title;
56
+ }
57
+ this.mainmarker = new $googlemaps.Marker({
58
+ position: new $googlemaps.LatLng(this.markers[0].latitude, this.markers[0].longitude),
59
+ icon: gicon,
60
+ title: title,
61
+ map: null
62
+ });
63
+ return this.mainmarker;
64
+ };
65
+
66
+ // global google maps objects
67
+ var $googlemaps = google.maps,
68
+ $geocoder = new $googlemaps.Geocoder(),
69
+ $markersToLoad = 0,
70
+ overQueryLimit = 0,
71
+ methods = {};
72
+ methods = {
73
+ /**
74
+ * initialisation/internals
75
+ */
76
+
77
+ init: function (options) {
78
+ var k,
79
+ // Build main options before element iteration
80
+ opts = $.extend({}, $.fn.gMap.defaults, options);
81
+
82
+ // recover icon array
83
+ for (k in $.fn.gMap.defaults.icon) {
84
+ if(!opts.icon[k]) {
85
+ opts.icon[k] = $.fn.gMap.defaults.icon[k];
86
+ }
87
+ }
88
+
89
+ // Iterate through each element
90
+ return this.each(function () {
91
+ var $this = $(this),
92
+ center = methods._getMapCenter.apply($this, [opts]),
93
+ i, $data;
94
+
95
+ if (opts.zoom == "fit") {
96
+ opts.zoomFit = true;
97
+ opts.zoom = methods._autoZoom.apply($this, [opts]);
98
+ }
99
+
100
+ var mapOptions = {
101
+ zoom: opts.zoom,
102
+ center: center,
103
+ mapTypeControl: opts.mapTypeControl,
104
+ mapTypeControlOptions: {},
105
+ zoomControl: opts.zoomControl,
106
+ zoomControlOptions: {},
107
+ panControl : opts.panControl,
108
+ panControlOptions: {},
109
+ scaleControl : opts.scaleControl,
110
+ scaleControlOptions: {},
111
+ streetViewControl: opts.streetViewControl,
112
+ streetViewControlOptions: {},
113
+ mapTypeId: opts.maptype,
114
+ scrollwheel: opts.scrollwheel,
115
+ maxZoom: opts.maxZoom,
116
+ minZoom: opts.minZoom
117
+ };
118
+ if(opts.controlsPositions.mapType) {mapOptions.mapTypeControlOptions.position = opts.controlsPositions.mapType};
119
+ if(opts.controlsPositions.zoom) {mapOptions.zoomControlOptions.position = opts.controlsPositions.zoom};
120
+ if(opts.controlsPositions.pan) {mapOptions.panControlOptions.position = opts.controlsPositions.pan};
121
+ if(opts.controlsPositions.scale) {mapOptions.scaleControlOptions.position = opts.controlsPositions.scale};
122
+ if(opts.controlsPositions.streetView) {mapOptions.streetViewControlOptions.position = opts.controlsPositions.streetView};
123
+
124
+ mapOptions.mapTypeControlOptions.style = opts.controlsStyle.mapType;
125
+ mapOptions.zoomControlOptions.style = opts.controlsStyle.zoom;
126
+
127
+ // Create map and set initial options
128
+ var $gmap = new $googlemaps.Map(this, mapOptions);
129
+
130
+ if (opts.log) {console.log('map center is:'); }
131
+ if (opts.log) {console.log(center); }
132
+
133
+ // Create map and set initial options
134
+
135
+ $this.data("$gmap", $gmap);
136
+
137
+ $this.data('gmap', {
138
+ 'opts': opts,
139
+ 'gmap': $gmap,
140
+ 'markers': [],
141
+ 'markerKeys' : {},
142
+ 'infoWindow': null,
143
+ 'clusters': []
144
+ });
145
+
146
+ // Check for map controls
147
+ if (opts.controls.length !== 0) {
148
+ // Add custom map controls
149
+ for (i = 0; i < opts.controls.length; i += 1) {
150
+ $gmap.controls[opts.controls[i].pos].push(opts.controls[i].div);
151
+ }
152
+ }
153
+
154
+ if (opts.clustering.enabled) {
155
+ $data = $this.data('gmap');
156
+ (function(markers) {$data.markers = markers;}(opts.markers));
157
+ methods._renderCluster.apply($this, []);
158
+
159
+ $googlemaps.event.addListener($gmap, 'bounds_changed', function () {
160
+ methods._renderCluster.apply($this, []);
161
+ });
162
+ } else {
163
+ if (opts.markers.length !== 0) {
164
+ methods.addMarkers.apply($this, [opts.markers]);
165
+ }
166
+ }
167
+
168
+ methods._onComplete.apply($this, []);
169
+ });
170
+ },
171
+
172
+
173
+ _delayedMode: false,
174
+
175
+ /**
176
+ * Check every 100ms if all markers were loaded, then call onComplete
177
+ */
178
+ _onComplete: function () {
179
+ var $data = this.data('gmap'),
180
+ that = this;
181
+ if ($markersToLoad !== 0) {
182
+ window.setTimeout(function () {methods._onComplete.apply(that, []); }, 100);
183
+ return;
184
+ }
185
+ if(methods._delayedMode) {
186
+ var center = methods._getMapCenter.apply(this, [$data.opts, true]);
187
+ methods._setMapCenter.apply(this, [center]);
188
+ if($data.opts.zoomFit) {
189
+ var zoom = methods._autoZoom.apply(this, [$data.opts, true]);
190
+ $data.gmap.setZoom(zoom);
191
+ }
192
+ }
193
+ $data.opts.onComplete();
194
+ },
195
+
196
+ /**
197
+ * set map center when map is loaded (check every 100ms)
198
+ */
199
+ _setMapCenter: function (center) {
200
+ var $data = this.data('gmap');
201
+ if ($data.opts.log) {console.log('delayed setMapCenter called'); }
202
+ if ($data.gmap !== undefined && $markersToLoad == 0) {
203
+ $data.gmap.setCenter(center);
204
+ } else {
205
+ var that = this;
206
+ window.setTimeout(function () {methods._setMapCenter.apply(that, [center]); }, 100);
207
+ }
208
+ },
209
+
210
+ /**
211
+ * calculate boundaries, optimised and independent from Google Maps
212
+ */
213
+ _boundaries: null,
214
+ _getBoundaries: function (opts) {
215
+ // if(methods._boundaries) {return methods._boundaries; }
216
+ var markers = opts.markers, i;
217
+ var mostN = 1000,
218
+ mostE = -1000,
219
+ mostW = 1000,
220
+ mostS = -1000;
221
+ if(markers) {
222
+ for (i = 0; i < markers.length; i += 1) {
223
+ if(!markers[i].latitude || !markers[i].longitude) continue;
224
+
225
+ if(mostN > markers[i].latitude) {mostN = markers[i].latitude; }
226
+ if(mostE < markers[i].longitude) {mostE = markers[i].longitude; }
227
+ if(mostW > markers[i].longitude) {mostW = markers[i].longitude; }
228
+ if(mostS < markers[i].latitude) {mostS = markers[i].latitude; }
229
+ console.log(markers[i].latitude, markers[i].longitude, mostN, mostE, mostW, mostS);
230
+ }
231
+ methods._boundaries = {N: mostN, E: mostE, W: mostW, S: mostS};
232
+ }
233
+
234
+ if(mostN == -1000) methods._boundaries = {N: 0, E: 0, W: 0, S: 0};
235
+
236
+ return methods._boundaries;
237
+ },
238
+
239
+ _getBoundariesFromMarkers: function () {
240
+
241
+ var markers = this.data('gmap').markers, i;
242
+ var mostN = 1000,
243
+ mostE = -1000,
244
+ mostW = 1000,
245
+ mostS = -1000;
246
+ if(markers) {
247
+ for (i = 0; i < markers.length; i += 1) {
248
+ if(mostN > markers[i].getPosition().lat()) {mostN = markers[i].getPosition().lat(); }
249
+ if(mostE < markers[i].getPosition().lng()) {mostE = markers[i].getPosition().lng(); }
250
+ if(mostW > markers[i].getPosition().lng()) {mostW = markers[i].getPosition().lng(); }
251
+ if(mostS < markers[i].getPosition().lat()) {mostS = markers[i].getPosition().lat(); }
252
+ }
253
+ methods._boundaries = {N: mostN, E: mostE, W: mostW, S: mostS};
254
+ }
255
+
256
+ if(mostN == -1000) methods._boundaries = {N: 0, E: 0, W: 0, S: 0};
257
+
258
+ return methods._boundaries;
259
+ },
260
+
261
+ /**
262
+ * Priorities order:
263
+ * - latitude & longitude in options
264
+ * - address in options
265
+ * - latitude & longitude of first marker having it
266
+ * - address of first marker having it
267
+ * - failsafe (0,0)
268
+ *
269
+ * Note: with geocoding returned value is (0,0) and callback sets map center. It's not very nice nor efficient.
270
+ * It is quite good idea to use only first option
271
+ */
272
+ _getMapCenter: function (opts, fromMarkers) {
273
+ // Create new object to geocode addresses
274
+
275
+ var center,
276
+ that = this, // 'that' scope fix in geocoding
277
+ i,
278
+ selectedToCenter,
279
+ most; //hoisting
280
+
281
+ if (opts.markers.length && (opts.latitude == "fit" || opts.longitude == "fit")) {
282
+ if(fromMarkers) most = methods._getBoundariesFromMarkers.apply(this);
283
+ else most = methods._getBoundaries(opts);
284
+ center = new $googlemaps.LatLng((most.N + most.S)/2, (most.E + most.W)/2);
285
+ console.log(fromMarkers, most, center);
286
+ return center;
287
+ }
288
+
289
+ if (opts.latitude && opts.longitude) {
290
+ // lat & lng available, return
291
+ center = new $googlemaps.LatLng(opts.latitude, opts.longitude);
292
+ return center;
293
+ } else {
294
+ center = new $googlemaps.LatLng(0, 0);
295
+ }
296
+
297
+ // Check for address to center on
298
+ if (opts.address) {
299
+ // Get coordinates for given address and center the map
300
+ $geocoder.geocode(
301
+ {address: opts.address},
302
+ function (result, status) {
303
+ if (status === google.maps.GeocoderStatus.OK) {
304
+ methods._setMapCenter.apply(that, [result[0].geometry.location]);
305
+ } else {
306
+ if (opts.log) {console.log("Geocode was not successful for the following reason: " + status); }
307
+ }
308
+ }
309
+ );
310
+ return center;
311
+ }
312
+
313
+ // Check for a marker to center on (if no coordinates given)
314
+ if (opts.markers.length > 0) {
315
+ selectedToCenter = null;
316
+
317
+ for (i = 0; i < opts.markers.length; i += 1) {
318
+ if(opts.markers[i].setCenter) {
319
+ selectedToCenter = opts.markers[i];
320
+ break;
321
+ }
322
+ }
323
+
324
+ if (selectedToCenter === null) {
325
+ for (i = 0; i < opts.markers.length; i += 1) {
326
+ if (opts.markers[i].latitude && opts.markers[i].longitude) {
327
+ selectedToCenter = opts.markers[i];
328
+ break;
329
+ }
330
+ if (opts.markers[i].address) {
331
+ selectedToCenter = opts.markers[i];
332
+ }
333
+ }
334
+ }
335
+ // failed to find any reasonable marker (it's quite impossible BTW)
336
+ if (selectedToCenter === null) {
337
+ return center;
338
+ }
339
+
340
+ if (selectedToCenter.latitude && selectedToCenter.longitude) {
341
+ return new $googlemaps.LatLng(selectedToCenter.latitude, selectedToCenter.longitude);
342
+ }
343
+
344
+ // Check if the marker has an address
345
+ if (selectedToCenter.address) {
346
+ // Get the coordinates for given marker address and center
347
+ $geocoder.geocode(
348
+ {address: selectedToCenter.address},
349
+ function (result, status) {
350
+ if (status === google.maps.GeocoderStatus.OK) {
351
+ methods._setMapCenter.apply(that, [result[0].geometry.location]);
352
+ } else {
353
+ if (opts.log) {console.log("Geocode was not successful for the following reason: " + status); }
354
+ }
355
+ }
356
+ );
357
+ }
358
+ }
359
+ return center;
360
+ },
361
+
362
+
363
+ /**
364
+ * clustering
365
+ */
366
+ _renderCluster: function () {
367
+ var $data = this.data('gmap'),
368
+ markers = $data.markers,
369
+ clusters = $data.clusters,
370
+ opts = $data.opts,
371
+ i,
372
+ j,
373
+ viewport;
374
+
375
+ for (i = 0; i < clusters.length; i += 1) {
376
+ clusters[i].getMarker().setMap(null);
377
+ }
378
+ clusters.length = 0;
379
+
380
+ viewport = $data.gmap.getBounds();
381
+
382
+ if (!viewport) {
383
+ var that = this;
384
+ window.setTimeout(function () {methods._renderCluster.apply(that); }, 1000);
385
+ return;
386
+ }
387
+
388
+ var ne = viewport.getNorthEast(),
389
+ sw = viewport.getSouthWest(),
390
+ width = ne.lat() - sw.lat(),
391
+ // height = ne.lng() - sw.lng(), // unused
392
+ clusterable = [],
393
+ best,
394
+ bestDist,
395
+ maxSize = width * opts.clustering.clusterSize / 100,
396
+ dist,
397
+ newCluster;
398
+
399
+ for (i = 0; i < markers.length; i += 1) {
400
+ if (markers[i].latitude < ne.lat() &&
401
+ markers[i].latitude > sw.lat() &&
402
+ markers[i].longitude < ne.lng() &&
403
+ markers[i].longitude > sw.lng()) {
404
+ clusterable[clusterable.length] = markers[i];
405
+ }
406
+ }
407
+
408
+ if (opts.log) {console.log("number of markers " + clusterable.length + "/" + markers.length); }
409
+ if (opts.log) {console.log('cluster radius: ' + maxSize); }
410
+
411
+ for (i = 0; i < clusterable.length; i += 1) {
412
+ bestDist = 10000;
413
+ best = -1;
414
+ for (j = 0; j < clusters.length; j += 1) {
415
+ dist = clusters[j].dist(clusterable[i]);
416
+ if (dist < maxSize) {
417
+ bestDist = dist;
418
+ best = j;
419
+ if (opts.clustering.fastClustering) {break; }
420
+ }
421
+ }
422
+ if (best === -1) {
423
+ newCluster = new Cluster();
424
+ newCluster.addMarker(clusterable[i]);
425
+ clusters[clusters.length] = newCluster;
426
+ } else {
427
+ clusters[best].addMarker(clusterable[i]);
428
+ }
429
+ }
430
+
431
+ if (opts.log) {console.log("Total clusters in viewport: " + clusters.length); }
432
+
433
+ for (j = 0; j < clusters.length; j += 1) {
434
+ clusters[j].getMarker().setMap($data.gmap);
435
+ }
436
+ },
437
+
438
+ _processMarker: function (marker, gicon, gshadow, location) {
439
+ var $data = this.data('gmap'),
440
+ $gmap = $data.gmap,
441
+ opts = $data.opts,
442
+ gmarker,
443
+ markeropts;
444
+
445
+ if (location === undefined) {
446
+ location = new $googlemaps.LatLng(marker.latitude, marker.longitude);
447
+ }
448
+
449
+ if (!gicon) {
450
+
451
+ // Set icon properties from global options
452
+ var _gicon = {
453
+ image: opts.icon.image,
454
+ iconSize: new $googlemaps.Size(opts.icon.iconsize[0], opts.icon.iconsize[1]),
455
+ iconAnchor: new $googlemaps.Point(opts.icon.iconanchor[0], opts.icon.iconanchor[1]),
456
+ infoWindowAnchor: new $googlemaps.Size(opts.icon.infowindowanchor[0], opts.icon.infowindowanchor[1])
457
+ };
458
+ gicon = new $googlemaps.MarkerImage(_gicon.image, _gicon.iconSize, null, _gicon.iconAnchor);
459
+ }
460
+
461
+ if (!gshadow) {
462
+ var _gshadow = {
463
+ image: opts.icon.shadow,
464
+ iconSize: new $googlemaps.Size(opts.icon.shadowsize[0], opts.icon.shadowsize[1]),
465
+ anchor: (_gicon && _gicon.iconAnchor)?_gicon.iconAnchor:new $googlemaps.Point(opts.icon.iconanchor[0], opts.icon.iconanchor[1])
466
+ };
467
+ }
468
+
469
+ markeropts = {
470
+ position: location,
471
+ icon: gicon,
472
+ title: marker.title,
473
+ map: null,
474
+ draggable: ((marker.draggable === true) ? true : false)
475
+ };
476
+
477
+ if (!opts.clustering.enabled) {markeropts.map = $gmap; }
478
+
479
+ gmarker = new $googlemaps.Marker(markeropts);
480
+ gmarker.setShadow(gshadow);
481
+ $data.markers.push(gmarker);
482
+
483
+ if(marker.key) {$data.markerKeys[marker.key] = gmarker; }
484
+
485
+ // Set HTML and check if info window should be opened
486
+ var infoWindow;
487
+ if (marker.html) {
488
+ var infoContent = typeof(marker.html) === "string" ? opts.html_prepend + marker.html + opts.html_append : marker.html;
489
+ var infoOpts = {
490
+ content: infoContent,
491
+ pixelOffset: marker.infoWindowAnchor
492
+ };
493
+
494
+ if (opts.log) {console.log('setup popup with data'); }
495
+ if (opts.log) {console.log(infoOpts); }
496
+ infoWindow = new $googlemaps.InfoWindow(infoOpts);
497
+
498
+ $googlemaps.event.addListener(gmarker, 'click', function () {
499
+ if (opts.log) {console.log('opening popup ' + marker.html); }
500
+ if (opts.singleInfoWindow && $data.infoWindow) {$data.infoWindow.close(); }
501
+ infoWindow.open($gmap, gmarker);
502
+ $data.infoWindow = infoWindow;
503
+ });
504
+ }
505
+ if (marker.html && marker.popup) {
506
+ if (opts.log) {console.log('opening popup ' + marker.html); }
507
+ infoWindow.open($gmap, gmarker);
508
+ $data.infoWindow = infoWindow;
509
+ }
510
+
511
+ if (marker.onDragEnd){
512
+ $googlemaps.event.addListener(gmarker, 'dragend', function(event) {
513
+ if (opts.log) {console.log('drag end');}
514
+ marker.onDragEnd(event);
515
+ });
516
+ }
517
+
518
+ },
519
+
520
+ _geocodeMarker: function (marker, gicon, gshadow) {
521
+ var that = this;
522
+ $geocoder.geocode({'address': marker.address}, function (results, status) {
523
+ if (status === $googlemaps.GeocoderStatus.OK) {
524
+ $markersToLoad -= 1;
525
+ if (that.data('gmap').opts.log) {console.log("Geocode was successful with point: ", results[0].geometry.location); }
526
+ methods._processMarker.apply(that, [marker, gicon, gshadow, results[0].geometry.location]);
527
+ } else {
528
+ if(status === $googlemaps.GeocoderStatus.OVER_QUERY_LIMIT) {
529
+ if ((!that.data('gmap').opts.noAlerts) && (overQueryLimit === 0)) {alert('Error: too many geocoded addresses! Switching to 1 marker/s mode.'); }
530
+
531
+ overQueryLimit+=1000;
532
+ window.setTimeout(function() {
533
+ methods._geocodeMarker.apply(that, [marker, gicon, gshadow]);
534
+ }, overQueryLimit);
535
+ }
536
+ if (that.data('gmap').opts.log) {console.log("Geocode was not successful for the following reason: " + status); }
537
+ }
538
+ });
539
+ },
540
+
541
+ _autoZoom: function (options, fromMarkers){
542
+ var data = $(this).data('gmap'),
543
+ opts = $.extend({}, data?data.opts:{}, options),
544
+ i, boundaries, resX, resY, baseScale = 39135.758482;
545
+ if (opts.log) {console.log("autozooming map");}
546
+
547
+ if(fromMarkers) boundaries = methods._getBoundariesFromMarkers.apply(this);
548
+ else boundaries = methods._getBoundaries(opts);
549
+
550
+ resX = (boundaries.E - boundaries.W) * 111000 / this.width();
551
+ resY = (boundaries.S - boundaries.N) * 111000 / this.height();
552
+
553
+ for(i = 2; i < 20; i += 1) {
554
+ if (resX > baseScale || resY > baseScale) {
555
+ break;
556
+ }
557
+ baseScale = baseScale / 2;
558
+ }
559
+ return i - 2;
560
+ },
561
+
562
+ /**
563
+ * public methods section
564
+ */
565
+
566
+ /**
567
+ * add array of markers
568
+ * @param markers
569
+ */
570
+ addMarkers: function (markers){
571
+ var opts = this.data('gmap').opts;
572
+
573
+ if (markers.length !== 0) {
574
+ if (opts.log) {console.log("adding " + markers.length +" markers");}
575
+ // Loop through marker array
576
+ for (var i = 0; i < markers.length; i+= 1) {
577
+ methods.addMarker.apply(this,[markers[i]]);
578
+ }
579
+ }
580
+ },
581
+
582
+ /**
583
+ * add single marker
584
+ * @param marker
585
+ */
586
+ addMarker: function (marker) {
587
+ var opts = this.data('gmap').opts;
588
+
589
+ if (opts.log) {console.log("putting marker at " + marker.latitude + ', ' + marker.longitude + " with address " + marker.address + " and html " + marker.html); }
590
+
591
+ // Create new icon
592
+ // Set icon properties from global options
593
+ var _gicon = {
594
+ image: opts.icon.image,
595
+ iconSize: new $googlemaps.Size(opts.icon.iconsize[0], opts.icon.iconsize[1]),
596
+ iconAnchor: new $googlemaps.Point(opts.icon.iconanchor[0], opts.icon.iconanchor[1]),
597
+ infoWindowAnchor: new $googlemaps.Size(opts.icon.infowindowanchor[0], opts.icon.infowindowanchor[1])
598
+ },
599
+ _gshadow = {
600
+ image: opts.icon.shadow,
601
+ iconSize: new $googlemaps.Size(opts.icon.shadowsize[0], opts.icon.shadowsize[1]),
602
+ anchor: new $googlemaps.Point(opts.icon.shadowanchor[0], opts.icon.shadowanchor[1])
603
+ };
604
+
605
+ // not very nice, but useful
606
+ marker.infoWindowAnchor = _gicon.infoWindowAnchor;
607
+
608
+ if (marker.icon) {
609
+ // Overwrite global options
610
+ if (marker.icon.image) { _gicon.image = marker.icon.image; }
611
+ if (marker.icon.iconsize) { _gicon.iconSize = new $googlemaps.Size(marker.icon.iconsize[0], marker.icon.iconsize[1]); }
612
+
613
+ if (marker.icon.iconanchor) { _gicon.iconAnchor = new $googlemaps.Point(marker.icon.iconanchor[0], marker.icon.iconanchor[1]); }
614
+ if (marker.icon.infowindowanchor) { _gicon.infoWindowAnchor = new $googlemaps.Size(marker.icon.infowindowanchor[0], marker.icon.infowindowanchor[1]); }
615
+
616
+ if (marker.icon.shadow) { _gshadow.image = marker.icon.shadow; }
617
+ if (marker.icon.shadowsize) { _gshadow.iconSize = new $googlemaps.Size(marker.icon.shadowsize[0], marker.icon.shadowsize[1]); }
618
+
619
+ if (marker.icon.shadowanchor) { _gshadow.anchor = new $googlemaps.Point(marker.icon.shadowanchor[0], marker.icon.shadowanchor[1]); }
620
+ }
621
+
622
+ var gicon = new $googlemaps.MarkerImage(_gicon.image, _gicon.iconSize, null, _gicon.iconAnchor);
623
+ var gshadow = new $googlemaps.MarkerImage( _gshadow.image,_gshadow.iconSize, null, _gshadow.anchor);
624
+
625
+ // Check if address is available
626
+ if (marker.address) {
627
+ // Check for reference to the marker's address
628
+ if (marker.html === '_address') {
629
+ marker.html = marker.address;
630
+ }
631
+
632
+ if (marker.title == '_address') {
633
+ marker.title = marker.address;
634
+ }
635
+
636
+ if (opts.log) {console.log('geocoding marker: ' + marker.address); }
637
+ // Get the point for given address
638
+ $markersToLoad += 1;
639
+ methods._delayedMode = true;
640
+ methods._geocodeMarker.apply(this, [marker, gicon, gshadow]);
641
+ } else {
642
+ // Check for reference to the marker's latitude/longitude
643
+ if (marker.html === '_latlng') {
644
+ marker.html = marker.latitude + ', ' + marker.longitude;
645
+ }
646
+
647
+ if (marker.title == '_latlng') {
648
+ marker.title = marker.latitude + ', ' + marker.longitude;
649
+ }
650
+
651
+ // Create marker
652
+ var gpoint = new $googlemaps.LatLng(marker.latitude, marker.longitude);
653
+ methods._processMarker.apply(this, [marker, gicon, gshadow, gpoint]);
654
+ }
655
+ },
656
+
657
+ /**
658
+ *
659
+ */
660
+ removeAllMarkers: function () {
661
+ var markers = this.data('gmap').markers, i;
662
+
663
+ for (i = 0; i < markers.length; i += 1) {
664
+ markers[i].setMap(null);
665
+ delete markers[i];
666
+ }
667
+ markers.length = 0;
668
+ },
669
+
670
+ /**
671
+ * get marker by key, if set previously
672
+ * @param key
673
+ */
674
+ getMarker: function (key) {
675
+ return this.data('gmap').markerKeys[key];
676
+ },
677
+
678
+ /**
679
+ * should be called if DOM element was resized
680
+ * @param nasty
681
+ */
682
+ fixAfterResize: function (nasty) {
683
+ var data = this.data('gmap');
684
+ $googlemaps.event.trigger(data.gmap, 'resize');
685
+
686
+ if(nasty) {
687
+ data.gmap.panTo(new google.maps.LatLng(0,0));
688
+ }
689
+ data.gmap.panTo(this.gMap('_getMapCenter', data.opts));
690
+ },
691
+
692
+ /**
693
+ * change zoom, works with 'fit' option as well
694
+ * @param zoom
695
+ */
696
+ setZoom: function (zoom, opts, fromMarkers) {
697
+ var $map = this.data('gmap').gmap;
698
+ if (zoom === "fit"){
699
+ zoom = methods._autoZoom.apply(this, [opts, fromMarkers]);
700
+ }
701
+ $map.setZoom(parseInt(zoom));
702
+ },
703
+
704
+ changeSettings: function (options) {
705
+ var data = this.data('gmap'),
706
+ markers = [], i;
707
+ for (i = 0; i < data.markers.length; i += 1) {
708
+ markers[i] = {
709
+ latitude: data.markers[i].getPosition().lat(),
710
+ longitude: data.markers[i].getPosition().lng()
711
+ }
712
+ }
713
+ options.markers = markers;
714
+
715
+ if(options.zoom) methods.setZoom.apply(this,[options.zoom, options]);
716
+ if(options.latitude || options.longitude) {
717
+ data.gmap.panTo(methods._getMapCenter.apply(this,[options]));
718
+ }
719
+
720
+ // add controls and maptype
721
+ },
722
+
723
+ mapclick: function(callback) {
724
+ google.maps.event.addListener(this.data('gmap').gmap, 'click', function(event) {
725
+ callback(event.latLng);
726
+ });
727
+ },
728
+
729
+ geocode: function(address, callback, errorCallback) {
730
+ $geocoder.geocode({'address': address}, function (results, status) {
731
+ if (status === $googlemaps.GeocoderStatus.OK) {
732
+ callback(results[0].geometry.location);
733
+ } else if(errorCallback) {
734
+ errorCallback(results, status);
735
+ }
736
+ });
737
+ },
738
+
739
+ getRoute: function (options) {
740
+
741
+ var $data = this.data('gmap'),
742
+ $gmap = $data.gmap,
743
+ $directionsDisplay = new $googlemaps.DirectionsRenderer(),
744
+ $directionsService = new $googlemaps.DirectionsService(),
745
+ $travelModes = { 'BYCAR': $googlemaps.DirectionsTravelMode.DRIVING, 'BYBICYCLE': $googlemaps.DirectionsTravelMode.BICYCLING, 'BYFOOT': $googlemaps.DirectionsTravelMode.WALKING },
746
+ $travelUnits = { 'MILES': $googlemaps.DirectionsUnitSystem.IMPERIAL, 'KM': $googlemaps.DirectionsUnitSystem.METRIC },
747
+ displayObj = null,
748
+ travelMode = null,
749
+ travelUnit = null,
750
+ unitSystem = null;
751
+
752
+ // look if there is an individual or otherwise a default object for this call to display route text informations
753
+ if(options.routeDisplay !== undefined){
754
+ displayObj = (options.routeDisplay instanceof jQuery) ? options.routeDisplay[0] : ((typeof options.routeDisplay == "string") ? $(options.routeDisplay)[0] : null);
755
+ } else if($data.opts.routeFinder.routeDisplay !== null){
756
+ displayObj = ($data.opts.routeFinder.routeDisplay instanceof jQuery) ? $data.opts.routeFinder.routeDisplay[0] : ((typeof $data.opts.routeFinder.routeDisplay == "string") ? $($data.opts.routeFinder.routeDisplay)[0] : null);
757
+ }
758
+
759
+ // set route renderer to map
760
+ $directionsDisplay.setMap($gmap);
761
+ if(displayObj !== null){
762
+ $directionsDisplay.setPanel(displayObj);
763
+ }
764
+
765
+ // get travel mode and unit
766
+ travelMode = ($travelModes[$data.opts.routeFinder.travelMode] !== undefined) ? $travelModes[$data.opts.routeFinder.travelMode] : $travelModes['BYCAR'];
767
+ travelUnit = ($travelUnits[$data.opts.routeFinder.travelUnit] !== undefined) ? $travelUnits[$data.opts.routeFinder.travelUnit] : $travelUnits['KM'];
768
+
769
+ // build request
770
+ var request = {
771
+ origin: options.from,
772
+ destination: options.to,
773
+ travelMode: travelMode,
774
+ unitSystem: travelUnit
775
+ };
776
+
777
+ // send request
778
+ $directionsService.route(request, function(result, status) {
779
+ // show the rout or otherwise show an error message in a defined container for route text information
780
+ if (status == $googlemaps.DirectionsStatus.OK) {
781
+ $directionsDisplay.setDirections(result);
782
+ } else if(displayObj !== null){
783
+ $(displayObj).html($data.opts.routeFinder.routeErrors[status]);
784
+ }
785
+ });
786
+ return this;
787
+ }
788
+ };
789
+
790
+
791
+ // Main plugin function
792
+ $.fn.gMap = function (method) {
793
+ // Method calling logic
794
+ if (methods[method]) {
795
+ return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
796
+ } else if (typeof method === 'object' || !method) {
797
+ return methods.init.apply(this, arguments);
798
+ } else {
799
+ $.error('Method ' + method + ' does not exist on jQuery.gmap');
800
+ }
801
+ };
802
+
803
+ // Default settings
804
+ $.fn.gMap.defaults = {
805
+ log: false,
806
+ address: '',
807
+ latitude: null,
808
+ longitude: null,
809
+ zoom: 3,
810
+ maxZoom: null,
811
+ minZoom: null,
812
+ markers: [],
813
+ controls: {},
814
+ scrollwheel: true,
815
+ maptype: google.maps.MapTypeId.ROADMAP,
816
+
817
+ mapTypeControl: true,
818
+ zoomControl: true,
819
+ panControl: false,
820
+ scaleControl: false,
821
+ streetViewControl: true,
822
+
823
+ controlsPositions: {
824
+ mapType: null,
825
+ zoom: null,
826
+ pan: null,
827
+ scale: null,
828
+ streetView: null
829
+ },
830
+ controlsStyle: {
831
+ mapType: google.maps.MapTypeControlStyle.DEFAULT,
832
+ zoom: google.maps.ZoomControlStyle.DEFAULT
833
+ },
834
+
835
+ singleInfoWindow: true,
836
+
837
+ html_prepend: '<div class="gmap_marker">',
838
+ html_append: '</div>',
839
+ icon: {
840
+ image: "http://www.google.com/mapfiles/marker.png",
841
+ iconsize: [20, 34],
842
+ iconanchor: [9, 34],
843
+ infowindowanchor: [9, 2],
844
+ shadow: "http://www.google.com/mapfiles/shadow50.png",
845
+ shadowsize: [37, 34],
846
+ shadowanchor: [9, 34]
847
+ },
848
+
849
+ onComplete: function () {},
850
+
851
+ routeFinder: {
852
+ travelMode: 'BYCAR',
853
+ travelUnit: 'KM',
854
+ routeDisplay: null,
855
+ routeErrors: {
856
+ 'INVALID_REQUEST': 'The provided request is invalid.',
857
+ 'NOT_FOUND': 'One or more of the given addresses could not be found.',
858
+ 'OVER_QUERY_LIMIT': 'A temporary error occured. Please try again in a few minutes.',
859
+ 'REQUEST_DENIED': 'An error occured. Please contact us.',
860
+ 'UNKNOWN_ERROR': 'An unknown error occured. Please try again.',
861
+ 'ZERO_RESULTS': 'No route could be found within the given addresses.'
862
+ }
863
+ },
864
+
865
+ clustering: {
866
+ enabled: false,
867
+ fastClustering: false,
868
+ clusterCount: 10,
869
+ clusterSize: 40 //radius as % of viewport width
870
+ }
871
+ };
872
+ }(jQuery));
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gmap-rails
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease:
6
+ segments:
7
+ - 3
8
+ - 3
9
+ - 2
10
+ version: 3.3.2
11
+ platform: ruby
12
+ authors:
13
+ - bokmann
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-09-07 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rake
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: "gmap is a helpful little Javascript library by Sebastian Por\xC4\x99ba. I'm just turning it into an asset gem for the rails asset pipeline."
36
+ email:
37
+ - dbock@codesherpas.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - .gitignore
46
+ - LICENSE
47
+ - README.md
48
+ - Rakefile
49
+ - gemfile
50
+ - gmap-rails.gemspec
51
+ - lib/gmap-rails.rb
52
+ - lib/gmap-rails/version.rb
53
+ - vendor/assets/javascripts/jquery.gmap.js
54
+ has_rdoc: true
55
+ homepage: https://github.com/bokmann/fullcalendar-rails
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options: []
60
+
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ requirements: []
82
+
83
+ rubyforge_project:
84
+ rubygems_version: 1.6.2
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: A simple asset pipeline bundling of the gmap javascript library.
88
+ test_files: []
89
+