gmapsjs 0.2.30.1 → 0.4.12

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