gmap-rails 3.3.2

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.
@@ -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
+