forked from hkdobrev/setmap
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetmap.js
More file actions
477 lines (396 loc) · 11.9 KB
/
Copy pathsetmap.js
File metadata and controls
477 lines (396 loc) · 11.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
// preceding comma in case there is broken code before the plugin is included
;
// wraps the code in a function with local variables and undefined as variable for safe comparison
(function ( $, navigator, google, undefined ) {
// force strict ECMAScript mode
"use strict";
/*
********************
*
* Helper functions
*
*******************
*/
// logs error messages using $.error
function e ( code, message ) {
$.error(
( typeof code === stringString ) ?
code + ( message !== undefined ? er[message] : "" ) :
er[code] + ( message ? message : emptyString )
);
}
// change the center of the map
function setPosition ( options, lat, lng ) {
var loc;
if ( ! lng ) {
loc = lat;
} else {
loc = new gmaps.LatLng(lat, lng);
}
options["mapObj"].setCenter(loc);
// options["markerObj"].setPosition(loc);
return loc;
}
// sets the position of the map programatically with a string address
function setAddress ( address, options, callback ) {
address = $.trim(address);
codeAddress(address, options, function ( loc ) {
setPosition(options, loc);
decodeAddress(loc, options, function ( address ) {
if ( typeof callback === functionString ) {
callback(loc.lat(), loc.lng(), address);
}
});
});
}
// sets the position of the map programatically with a coordinates
function setCoords ( lat, lng, options, fn ) {
var loc = setPosition( options, lat, lng);
if ( typeof fn === functionString ) {
decodeAddress(loc, options, fn);
}
}
function resolveType ( type, initial ) {
type = mapTypes[$.inArray(type, mapTypes)];
return type || ( initial ? mapTypes[0] : f);
}
function getType ( map ) {
return map.getMapTypeId();
}
// sets the map type
var setType = function ( map, type ) {
var newType = resolveType(type, t);
if ( newType ) {
map.setMapTypeId(newType);
}
}
// initializes the map and markers; calls initCallback with a success/fail flag when ready
function initialize ( mapDOMElement, options, initCallback ) {
function callback () {
options.latlng = new gmaps.LatLng(options.map["center"].lat, options.map["center"].lng);
try {
options["mapObj"] = new gmaps.Map(mapDOMElement, {
"zoom": options.map.zoom,
"center": options.latlng,
"mapTypeId": options.map.type,
"zoomControlOptions": {
"style": options.map.zoomControls
},
"draggable": options.map.draggable,
"disableDefaultUI": options.map.disabled === t,
"scrollwheel": options.map.disabled === f,
"keyboardShortcuts": options.map.disabled === f,
"disableDoubleClickZoom": options.map.disabled === t,
"streetViewControl": options.map.streetView
});
if ( typeof options["center"] === functionString ) {
options.mapCenterListener = gmaps.event.addListener(options["mapObj"], "center_changed", function ( e ) {
options["center"].call({
"center": {
"lat": this.getCenter().lat(),
"lng": this.getCenter().lng()
}
});
});
}
if ( typeof options["type"] === functionString ) {
options.mapCenterListener = gmaps.event.addListener(options["mapObj"], "maptypeid_changed", function ( e ) {
options["type"].call({
"type": getType(this)
});
});
}
if( ! $.isArray(options["markers"] ) ) {
e(5);
initCallback(f);
return false;
}
options["markerObjects"] = [];
$.each(options["markers"], function ( index, value ) {
var markerOptions = {
"map": options["mapObj"],
"animation": value["animation"] || options["markerOptions"].animation,
"draggable": value["draggable"] || options["markerOptions"].draggable,
"position": value["position"] ? new gmaps.LatLng(value["position"].lat, value["position"].lng) : new gmaps.LatLng(options["markerOptions"].position.lat, options["markerOptions"].position.lng),
"title": value.title || options["markerOptions"].title
},
markerObj = new gmaps.Marker(markerOptions),
listener;
if ( typeof options["drop"] === functionString && markerOptions.draggable === t ) {
listener = gmaps.event.addListener(markerObj, "dragend", function ( event ) {
decodeAddress(event.latLng, options, function ( address ) {
options["drop"].call({
"id": index,
"position": {
"lat": event.latLng.lat(),
"lng": event.latLng.lng(),
"address": address
},
"map": mapDOMElement
});
});
});
}
options["markerObjects"].push({
obj: markerObj,
listener: listener,
id: index
});
});
initCallback(t);
} catch ( ex ) {
e(ex.message);
initCallback(f);
}
}
if ( options.map["current"] ) {
if ( navigator.geolocation ) {
navigator.geolocation.getCurrentPosition(function ( position ) {
options.map["center"] = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
callback();
}, function () {
// user refuses HTML geolocation or the geolocation service failed
e(0);
callback();
});
} else {
// Browser doesn't support Geolocation
e(1);
callback();
}
} else {
callback();
}
}
// Reversed geocoding: convert coordinates to address, calls callback when ready
function decodeAddress ( latlong, options, callback ) {
geocoder.geocode({
"latLng": latlong
}, function ( results, status ) {
var val = emptyString;
if ( status === gmaps.GeocoderStatus.OK ) {
if ( options.components ) {
val = results[0].address_components;
} else {
$.each(results[0].address_components, function (key, value ) {
if ( key > 0 ) {
val = val + ", ";
}
val = val + value["long_name"];
});
}
callback(val);
} else {
e(2, status);
callback(f);
}
});
}
// Geocoding: convert address to coordinates, calls callback when ready
function codeAddress ( address, options, callback) {
geocoder.geocode({
"address": address
}, function ( results, status ) {
if ( status === gmaps.GeocoderStatus.OK ) {
callback(results[0].geometry.location);
} else {
e(2, status);
callback(f);
}
});
}
// Checks if google maps JavaScript API script is loaded
if ( typeof google !== objectString || typeof google.maps !== objectString ) {
e(4);
return;
}
// the google maps namespace from the js API
var gmaps = google.maps,
// geocoder object for geocoding and reversed geocoding
geocoder = new gmaps.Geocoder(),
// namespace for data and events
dotNamespace = ".setmap",
// false
f = false,
// true
t = true,
// object string
objectString = "object",
// style string
styleString = "style",
// number string
numberString = "number",
// function string
functionString = "function",
// empty string
emptyString = "",
// string string
stringString = "string",
// the default options
defaultOptions = {
// the map options
"map": {
"zoom": 12,
"type": "hybrid",
"draggable": t,
"streetView": f,
"disabled": f,
"center": {
"lat": 34.051,
"lng": -118.246
},
"current": false,
"zoomControls": "large"
},
// the markers array
"markers": [],
// global marker options
"markerOptions": {
"animation": "drop",
"draggable": t,
"title": emptyString,
"current": f,
"icon": f
},
"drop": f,
// return components flag: default value is false
"components": f
},
// possible map types
mapTypes = ["hybrid", "terrain", "roadmap", "satellite"],
// possible marker animations
markerAnimations = ["DROP", "BOUNCE"],
// possible zoom controls styles
zoomControls = ["SMALL", "LARGE"],
// error messages
er = [
"The Geolocation service failed",
"Your browser doesn't support geolocation",
"Geocode was not successful for the following reason: ",
"You should destroy the setmap instance first!",
"The Gogle Maps Javascript API is not loaded!",
"The markers property must be an array!",
" does not exist on the setmap plugin!"
];
// the actual jQuery plugin
$.fn.setmap = function ( method ) {
var mainArguments = arguments,
options, element,
methods = {
// initializes the map instance
"init": function ( settings ) {
if ( typeof options === objectString && ! $.isPlainObject(options) ) {
e(3);
return element;
}
$.extend(t, options, defaultOptions, settings);
if ( element.attr(styleString) !== undefined ) {
element.data(styleString + dotNamespace, element.attr(styleString) + emptyString);
}
// sets the map type
options.map["type"] = resolveType(options.map["type"], t);
// sets the animation
options["markerOptions"]["animation"] = gmaps.Animation[
markerAnimations[$.inArray(options["markerOptions"]["animation"].toUpperCase(), markerAnimations)] || markerAnimations[0]
];
// set the disabled property
if ( options.map.disabled !== f ) {
options.map.disabled = t;
}
// sets the zoom controls style
options.map["zoomControls"] = gmaps.ZoomControlStyle[
zoomControls[$.inArray(options.map["zoomControls"].toUpperCase(), zoomControls)] || zoomControls[0]
];
// initialize the map and the map overlays, calls the callback with success flag
initialize(this, options, function ( success ) {
if ( success ) {
element.data(objectString + dotNamespace, options);
}
});
return element;
},
// returns the google.maps.Map object of the map
"getMap": function () {
return options["mapObj"];
},
// gets or sets the zoom level of the map
"zoom": function ( zoomLevel ) {
if ( zoomLevel === undefined ) {
return options["mapObj"].getZoom();
}
if ( typeof zoomLevel === numberString && zoomLevel > 0 ) {
options["mapObj"].setZoom(zoomLevel);
}
return element;
},
// gets or sets the center of the map
"center": function ( lat, lng, callback ) {
if ( typeof lat === numberString && ( typeof lng === numberString || lng === undefined ) ) {
setCoords(lat, lng, options, callback);
return element;
} else if ( typeof lat === stringString && ( lng === undefined || typeof lng === functionString ) ) {
setAddress(lat, options, lng);
return element;
} else {
return options["mapObj"].getCenter();
}
},
// gets or sets the map type
"type": function ( type ) {
if ( type === undefined ) {
return getType(options["mapObj"]);
}
setType.call(options["mapOjb"], type);
return element;
},
// destroy the map instance
"destroy": function () {
if ( ! $.isPlainObject(options) ) {
if ( element.data(styleString + dotNamespace) !== undefined ) {
element.attr(styleString, element.data(styleString + dotNamespace));
} else {
element.removeAttr(styleString);
}
element.removeData(objectString + dotNamespace);
element.removeData(styleString + dotNamespace);
element.unbind(dotNamespace);
element.empty();
if ( options.listener ) {
gmaps.event.removeListener(options.listener);
}
return element;
} else {
return element;
}
}
},
returnValue;
// calls the provided method for each element from the selected jQuery collection
this.each(function () {
// keeps the original jQuery collection on which the plugin was called
element = $(this);
// keeps the data for every jQuery element on the collection
options = element.data(objectString + dotNamespace) || {};
if ( returnValue === undefined ) {
// calls the appropriate method if available
if ( methods[method] && method !== "init" ) {
returnValue = methods[ method ].apply( this, Array.prototype.slice.call( mainArguments, 1 ) );
} else {
if ( typeof method === objectString || ! method ) {
methods["init"].apply( this, mainArguments );
} else {
e( "Method " + method, 6 );
returnValue = f;
}
}
}
});
if (returnValue === undefined ) {
return element;
}
return returnValue;
};
}(jQuery, navigator, google));