1 | /*jslint browser: true*/
|
---|
2 |
|
---|
3 | // Location Finder module
|
---|
4 | // Use HTML5 Geolocation to find current user's location.
|
---|
5 | var LocationFinder = (function ($) {
|
---|
6 | "use strict";
|
---|
7 |
|
---|
8 | return function (fallbackLat, fallbackLng) {
|
---|
9 | // Private
|
---|
10 | var lat = fallbackLat,
|
---|
11 | lng = fallbackLng,
|
---|
12 | $dfd = new $.Deferred(),
|
---|
13 | me = {
|
---|
14 | fallbackUsed: false,
|
---|
15 | usersPosition: function () {
|
---|
16 | return {
|
---|
17 | lat: lat,
|
---|
18 | lng: lng
|
---|
19 | };
|
---|
20 | }
|
---|
21 | },
|
---|
22 | userLocationNotFound = function () {
|
---|
23 | // window.console.warn("User Location NOT found. Set to fallback: " + lat + ", " + lng);
|
---|
24 | me.fallbackUsed = true;
|
---|
25 | $dfd.resolve(fallbackLat, fallbackLng);
|
---|
26 | };
|
---|
27 |
|
---|
28 | // Async method which returns a promise that resolves when the current users geolocation is found
|
---|
29 | me.findUserLocationAsync = function () {
|
---|
30 | var $html = $('html'),
|
---|
31 | isOldIe = $html.hasClass('no-geolocation') || $html.hasClass('ie8') || $html.hasClass('lt-ie9');
|
---|
32 |
|
---|
33 | /*global window */
|
---|
34 | if (window.navigator.geolocation && !isOldIe) {
|
---|
35 |
|
---|
36 | var geoOptions = {
|
---|
37 | enableHighAccuracy: false,
|
---|
38 | timeout: 5000, // Wait 5 seconds
|
---|
39 | maximumAge: 300000 // Valid for 5 minutes
|
---|
40 | };
|
---|
41 |
|
---|
42 | window.navigator.geolocation.getCurrentPosition(function (position) {
|
---|
43 | lat = position.coords.latitude;
|
---|
44 | lng = position.coords.longitude;
|
---|
45 | //window.console.info("User confirmed! Location found: " + lat + ", " + lng);
|
---|
46 | // location has been found. So set $deferredObject to resolved so dependant functions can run
|
---|
47 | $dfd.resolve(lat, lng);
|
---|
48 |
|
---|
49 | }, function () {
|
---|
50 | //window.console.log("User declined!");
|
---|
51 | userLocationNotFound();
|
---|
52 | }, geoOptions);
|
---|
53 |
|
---|
54 | // Using a timeout to handle events when the getCurrentPosition() timeout never occurs
|
---|
55 | setTimeout(function () {
|
---|
56 | if ($dfd.state() !== "resolved") {
|
---|
57 | //window.console.log("No confirmation from user, using fallback");
|
---|
58 | userLocationNotFound();
|
---|
59 | }
|
---|
60 | }, geoOptions.timeout + 1000); // Wait an extra second
|
---|
61 |
|
---|
62 |
|
---|
63 | } else {
|
---|
64 | userLocationNotFound();
|
---|
65 | }
|
---|
66 |
|
---|
67 | return $dfd.promise();
|
---|
68 | };
|
---|
69 |
|
---|
70 | return me;
|
---|
71 | };
|
---|
72 | }(window.jQuery));
|
---|
73 |
|
---|
74 | // Loads Google Maps API asynchronously and returns a promise when finished
|
---|
75 | var LoadGoogleMapsWithPromise = (function ($) {
|
---|
76 | "use strict";
|
---|
77 |
|
---|
78 | var promise;
|
---|
79 |
|
---|
80 | return function (version, apiKey, language, sensor) {
|
---|
81 | if (promise) {
|
---|
82 | return promise;
|
---|
83 | }
|
---|
84 |
|
---|
85 | //Create a Deferred Object
|
---|
86 | var $dfd = new $.Deferred(),
|
---|
87 | //Declare a resolve function, pass google.maps for the done functions
|
---|
88 | resolve = function () {
|
---|
89 | $dfd.resolve(window.google && window.google.maps ? window.google.maps : false);
|
---|
90 | },
|
---|
91 | //global callback name
|
---|
92 | callbackName = "loadGoogleMaps_" + $.now(),
|
---|
93 |
|
---|
94 | // Default Parameters
|
---|
95 | params = $.extend({
|
---|
96 | 'sensor': sensor || "true"
|
---|
97 | },
|
---|
98 | apiKey ? {
|
---|
99 | "key": apiKey
|
---|
100 | } : {},
|
---|
101 | language ? {
|
---|
102 | "language": language
|
---|
103 | } : {},
|
---|
104 | { "libraries": "places" });
|
---|
105 |
|
---|
106 | //If google.maps exists, then Google Maps API was probably loaded with the <script> tag
|
---|
107 | if (window.google && window.google.maps) {
|
---|
108 | resolve();
|
---|
109 | //If the google.load method exists, lets load the Google Maps API in Async.
|
---|
110 | } else if (window.google && window.google.load) {
|
---|
111 | window.google.load("maps", version || 3, {
|
---|
112 | "other_params": $.param(params),
|
---|
113 | "callback": resolve
|
---|
114 | });
|
---|
115 | //Last, try pure jQuery Ajax technique to load the Google Maps API in Async.
|
---|
116 | } else {
|
---|
117 | //Ajax URL paramsnow
|
---|
118 | params = $.extend(params, {
|
---|
119 | 'callback': callbackName
|
---|
120 | });
|
---|
121 |
|
---|
122 | //Declare the global callback
|
---|
123 | window[callbackName] = function () {
|
---|
124 | resolve();
|
---|
125 | //Delete callback
|
---|
126 | setTimeout(function () {
|
---|
127 | try {
|
---|
128 | delete window[callbackName];
|
---|
129 | } catch (ignore) { }
|
---|
130 | }, 20);
|
---|
131 | };
|
---|
132 |
|
---|
133 | //Can't use the jXHR promise because 'script' doesn't support 'callback=?'
|
---|
134 | $.ajax({
|
---|
135 | dataType: 'script',
|
---|
136 | data: params,
|
---|
137 | url: '//maps.googleapis.com/maps/api/js',
|
---|
138 | crossDomain: true,
|
---|
139 | error: function () {
|
---|
140 | throw "Could not load Google Maps";
|
---|
141 | }
|
---|
142 | });
|
---|
143 | }
|
---|
144 |
|
---|
145 | return $dfd.promise();
|
---|
146 | };
|
---|
147 | }(window.jQuery));
|
---|
148 |
|
---|
149 | /*jslint browser: true*/
|
---|
150 | // Module to add a Google map
|
---|
151 | var GoogleMap = (function ($) {
|
---|
152 | //"use strict";
|
---|
153 | return function (passedOptions) {
|
---|
154 | // PRIVATE PROPERTIES
|
---|
155 |
|
---|
156 | var map,
|
---|
157 | // Default options for the Google Map
|
---|
158 | defaults = {
|
---|
159 | mapId: "map_canvas", // Id of the div to add the map to. * Required
|
---|
160 | directionsId: "", // Id of the div to add the directions to. Optional
|
---|
161 | zoomLevel: 5, // Default zoom level for the map. Optional
|
---|
162 | fallbackZoomLevel: 5, // Default zoom level for the map when user's location is not found
|
---|
163 | showIconLabels: true, //
|
---|
164 | userLocationAsMapCenter: false,
|
---|
165 | showDistanceFromUserInInfoBox: true,
|
---|
166 | showCurrentUsersLocationMarker: true,
|
---|
167 | mapCentreLat: -41.136115, // NZ center
|
---|
168 | mapCentreLng: 172.557641, // NZ center
|
---|
169 | disableControls: false,
|
---|
170 | locationsArray: [], // An pre-defined JSON array of locations. This is used over a locationsServicePath
|
---|
171 | locationsServicePath: "", // A service (e.g Web API) that can be called to load a JSON array of locations.
|
---|
172 | directionsOnSetCallback: function() {
|
---|
173 | return undefined;
|
---|
174 | },
|
---|
175 | directionsOnUpdateCallback: function() {
|
---|
176 | return undefined;
|
---|
177 | },
|
---|
178 | directionsOnCloseCallback: function() {
|
---|
179 | return undefined;
|
---|
180 | },
|
---|
181 | userLocationSetCallback: function() {
|
---|
182 | return undefined;
|
---|
183 | },
|
---|
184 | defaultMarkerPath: "",
|
---|
185 | firstResultMarkerPath: ""
|
---|
186 | },
|
---|
187 | options = $.extend(defaults, passedOptions),
|
---|
188 | requirementsCheckOk = function() {
|
---|
189 | // If Google maps or InfoBox isn't loaded then return;
|
---|
190 | if ((!window.google && !window.google.maps) || !window.InfoBox) {
|
---|
191 | if (!window.google && !window.google.maps) {
|
---|
192 | throw "Google map module - Google maps has not been loaded!";
|
---|
193 | }
|
---|
194 |
|
---|
195 | if (!window.InfoBox) {
|
---|
196 | throw "Google map module - InfoBox has not been loaded!";
|
---|
197 | }
|
---|
198 | return false;
|
---|
199 | }
|
---|
200 | if (!$('#' + options.mapId)) {
|
---|
201 | throw 'Google map module - No map id specified!';
|
---|
202 | // return false;
|
---|
203 | }
|
---|
204 |
|
---|
205 | return true;
|
---|
206 | },
|
---|
207 | mapCentre = new window.google.maps.LatLng(options.mapCentreLat, options.mapCentreLng),
|
---|
208 | mapStyle = [{
|
---|
209 | featureType: "poi.park",
|
---|
210 | stylers: [{
|
---|
211 | "visibility": "off"
|
---|
212 | }]
|
---|
213 | }, {
|
---|
214 | featureType: "administrative.locality",
|
---|
215 | elementType: "labels",
|
---|
216 | stylers: [{
|
---|
217 | visibility: "off"
|
---|
218 | }]
|
---|
219 | }, {
|
---|
220 | featureType: "administrative.country",
|
---|
221 | elementType: "labels",
|
---|
222 | stylers: [{
|
---|
223 | visibility: "off"
|
---|
224 | }]
|
---|
225 | }],
|
---|
226 | directionsRenderer = new window.google.maps.DirectionsRenderer(),
|
---|
227 | directionsService = new window.google.maps.DirectionsService(),
|
---|
228 | isLowerThanIe8 = $('html').hasClass('ie7') || $('html').hasClass('lt - ie8') ? true : false,
|
---|
229 | infobox = new window.InfoBox({
|
---|
230 | alignBottom: true,
|
---|
231 | boxClass: "infobox",
|
---|
232 | disableAutoPan: false,
|
---|
233 | pixelOffset: new window.google.maps.Size(-80, -50),
|
---|
234 | zIndex: null,
|
---|
235 | closeBoxMargin: "0px",
|
---|
236 | closeBoxURL: isLowerThanIe8 ? "http://www.google.com/intl/en_us/mapfiles/close.gif" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAUNJREFUOE+tkT1ug0AQhadwH9Ehyx1NEAHxE0RAICIaGq6AfAROkDrHiHKBtC6DFKVCielTpIpcWooPsJkXz2Iit3nSk0ffvF1mx/RvMk1zzX5mf7L3Uq+lfS7DMC44sLUsS7muq3zfV0EQ/NZg6CEj8ZOWy+XoeZ6KokjFcXzA77xGDxmJH4VR9KGiKD7GcaybptnAqMH04T9j27b9qm8fhuFWKbVgX4oXYPrLjuNs5BgR3/QNiDetVqtHwZPA0EOG3/4lmChJkh0gnGXZk+BJYLofhuFBMFGe52+AGKfv+1jwJDA9almW74KJ2ra9A8Q42Jz8NQ8wajA9KrJyjIgXYM43x8E9L0zBqOcbR1aOHYXN6cP69nmNHjISPwlrZ193XXdfVdUWb0rTdFfX9QsYeshI/FwYhe2zc/YN+wpM2iKiH9yl0dFnXUuVAAAAAElFTkSuQmCC",
|
---|
237 | infoBoxClearance: new window.google.maps.Size(1, 1),
|
---|
238 | pane: "floatPane",
|
---|
239 | enableEventPropagation: false
|
---|
240 | }),
|
---|
241 | directionsObject, userLocation = {}, currentZoomLevel, curMapCenter,
|
---|
242 | // An array to hold our json results from the lookup service
|
---|
243 | locationsArray,
|
---|
244 | // An array to keep track of our marker icons
|
---|
245 | markersArray = [],
|
---|
246 | // An array to keep track of the locaion labels
|
---|
247 | labelsArray = [],
|
---|
248 | // A deferred object which we can use to check if the async load in getNzCitiesAsync is finished/resolved
|
---|
249 | $citiesAsyncHasFinished = $.Deferred(),
|
---|
250 | startLocationMarker,
|
---|
251 | startLocation,
|
---|
252 | endLocation,
|
---|
253 | methodOfTravel;
|
---|
254 |
|
---|
255 |
|
---|
256 | if (!requirementsCheckOk()) {
|
---|
257 | return;
|
---|
258 | }
|
---|
259 |
|
---|
260 | // Initilise map
|
---|
261 | init();
|
---|
262 |
|
---|
263 | /***********************/
|
---|
264 |
|
---|
265 | // PRIVATE FUNCTIONS
|
---|
266 |
|
---|
267 | /* Core functionality */
|
---|
268 |
|
---|
269 | // Initialise the map - run dependant async function
|
---|
270 |
|
---|
271 | function init() {
|
---|
272 |
|
---|
273 | // If the locationsArray is empty & a locationsServicePath has been passed
|
---|
274 | if (!options.locationsArray.length && options.locationsServicePath.length) {
|
---|
275 | // Init async methods
|
---|
276 | $citiesAsyncHasFinished = getLocationsAsync(options.locationsServicePath);
|
---|
277 | } else {
|
---|
278 | locationsArray = options.locationsArray;
|
---|
279 | $citiesAsyncHasFinished.resolve();
|
---|
280 | }
|
---|
281 | var loc = new LocationFinder(-41.29247, 174.7732);
|
---|
282 |
|
---|
283 | // Fire async callbacks when they are resolved.
|
---|
284 | // When user's location is found, start loading the map.
|
---|
285 | // Once all the location markers have finished loading from the server,
|
---|
286 | // add them to the map.
|
---|
287 | $.when(loc.findUserLocationAsync()).then(function (lat, lng) {
|
---|
288 | userLocation.lat = lat;
|
---|
289 | userLocation.lng = lng;
|
---|
290 | startLocation = new window.google.maps.LatLng(lat, lng);
|
---|
291 |
|
---|
292 | // User location is now set to fire callback
|
---|
293 | options.userLocationSetCallback(userLocation);
|
---|
294 |
|
---|
295 | //var mapZoomLevel = loc.fallbackUsed ? options.fallbackZoomLevel : options.zoomLevel;
|
---|
296 | var mapZoomLevel = options.zoomLevel;
|
---|
297 | // Add our Google map to the page
|
---|
298 | addMap(startLocation, mapZoomLevel);
|
---|
299 |
|
---|
300 | $.when($citiesAsyncHasFinished)
|
---|
301 | .then(function () {
|
---|
302 | loadMarkers();
|
---|
303 | });
|
---|
304 | });
|
---|
305 | }
|
---|
306 |
|
---|
307 | // Add the Google Map w/ some default values & event listeners
|
---|
308 |
|
---|
309 | function addMap(userGoogleLocation, zoom) {
|
---|
310 |
|
---|
311 | if (options.userLocationAsMapCenter) {
|
---|
312 | mapCentre = startLocation;
|
---|
313 | }
|
---|
314 |
|
---|
315 | var mapOptions = {
|
---|
316 | scrollwheel: true,
|
---|
317 | zoom: zoom,
|
---|
318 | center: mapCentre,
|
---|
319 | mapTypeId: window.google.maps.MapTypeId.ROADMAP,
|
---|
320 | mapTypeControlOptions: {
|
---|
321 | style: window.google.maps.MapTypeControlStyle.DROPDOWN_MENU,
|
---|
322 | position: window.google.maps.ControlPosition.TOP_RIGHT
|
---|
323 | },
|
---|
324 | mapTypeControl: true,
|
---|
325 | panControl: false,
|
---|
326 | streetViewControl: true,
|
---|
327 | zoomControlOptions: {
|
---|
328 | position: window.google.maps.ControlPosition.RIGHT_TOP
|
---|
329 | },
|
---|
330 | styles: mapStyle,
|
---|
331 | keepMapZoom: false,
|
---|
332 | isZoomSearch: false,
|
---|
333 | isCenterChange: false,
|
---|
334 | currentAddressSearchResult: null,
|
---|
335 | directMatchItem: null,
|
---|
336 | isMarkerClick : false
|
---|
337 | };
|
---|
338 |
|
---|
339 | // if disableControls is true then hide zoom, pan, satellite view etc
|
---|
340 | if (options.disableControls) {
|
---|
341 | disableMapControls(mapOptions);
|
---|
342 | }
|
---|
343 |
|
---|
344 | map = new window.google.maps.Map(document.getElementById(options.mapId), mapOptions);
|
---|
345 |
|
---|
346 | directionsRenderer.setMap(map);
|
---|
347 | directionsRenderer.setPanel(document.getElementById('directionsPanel'));
|
---|
348 |
|
---|
349 | if (options.showCurrentUsersLocationMarker) {
|
---|
350 | var iconShape = {
|
---|
351 | coord: [9, 0, 6, 1, 4, 2, 2, 4, 0, 8, 0, 12, 1, 14, 2, 16, 5, 19, 7, 23, 8, 26, 9, 30, 9, 34, 11, 34, 11, 30, 12, 26, 13, 24, 14, 21, 16, 18, 18, 16, 20, 12, 20, 8, 18, 4, 16, 2, 15, 1, 13, 0],
|
---|
352 | type: 'poly'
|
---|
353 | };
|
---|
354 | var iconImage = new window.google.maps.MarkerImage('http://maps.google.com/mapfiles/arrow.png', new window.google.maps.Size(39, 34), new window.google.maps.Point(0, 0), new window.google.maps.Point(9, 34));
|
---|
355 | var iconShadow = new window.google.maps.MarkerImage('http://www.google.com/mapfiles/arrowshadow.png', new window.google.maps.Size(39, 34), new window.google.maps.Point(0, 0), new window.google.maps.Point(9, 34));
|
---|
356 |
|
---|
357 | startLocationMarker = new window.google.maps.Marker({
|
---|
358 | draggable: true,
|
---|
359 | position: userGoogleLocation,
|
---|
360 | map: map,
|
---|
361 | title: "You are here!",
|
---|
362 | animation: null,//window.google.maps.Animation.DROP,
|
---|
363 | shape: iconShape,
|
---|
364 | icon: iconImage,
|
---|
365 | shadow: iconShadow
|
---|
366 | //,zIndex: Math.round(userGoogleLocation.lat() * -100000) << 5
|
---|
367 | });
|
---|
368 |
|
---|
369 | // Moved current location so get the nearest places to me now
|
---|
370 | window.google.maps.event.addListener(startLocationMarker, 'dragend', function () {
|
---|
371 | mapCentre = startLocationMarker.getPosition();
|
---|
372 | loadMarkers();
|
---|
373 | if ($('#' + options.directionsId).is(':visible')) {
|
---|
374 | calcRoute(true);
|
---|
375 | // window.console.info("Current lat: " + startLocationMarker.getPosition().lat() + " long: " + startLocationMarker.getPosition().lng());
|
---|
376 | }
|
---|
377 | });
|
---|
378 | }
|
---|
379 |
|
---|
380 | var startTimer = null,
|
---|
381 | windowSize = $(window).width();
|
---|
382 |
|
---|
383 | // Re-center the map when the window is resized. Handy for responsive layouts
|
---|
384 | window.google.maps.event.addDomListener(window, 'resize', function () {
|
---|
385 | if (startTimer) {
|
---|
386 | clearTimeout(startTimer);
|
---|
387 | }
|
---|
388 | startTimer = setTimeout(triggerResize, 300);
|
---|
389 |
|
---|
390 | function triggerResize() {
|
---|
391 | var currentWindowSize = $(window).width();
|
---|
392 | if (windowSize != currentWindowSize) {
|
---|
393 | window.google.maps.event.trigger(map, "resize");
|
---|
394 | fitMapToMarkers();
|
---|
395 | windowSize = currentWindowSize;
|
---|
396 | }
|
---|
397 | }
|
---|
398 | });
|
---|
399 |
|
---|
400 | /* Change markers on zoom */
|
---|
401 | // supp 97
|
---|
402 | window.google.maps.event.addListener(map, 'zoom_changed', function () {
|
---|
403 | //currentZoomLevel = map.getZoom();
|
---|
404 | //if (currentZoomLevel > 14) {
|
---|
405 | // map.isZoomSearch = true;
|
---|
406 | //}
|
---|
407 | //curMapCenter = map.getCenter();
|
---|
408 | //options.zoomLevelSetCallback(currentZoomLevel, curMapCenter);
|
---|
409 | });
|
---|
410 |
|
---|
411 | window.google.maps.event.addListener(map, 'center_changed', function () {
|
---|
412 | //window.setTimeout(function () {
|
---|
413 | // currentZoomLevel = map.getZoom();
|
---|
414 | // if (currentZoomLevel > 14) {
|
---|
415 | // map.isZoomSearch = true;
|
---|
416 | // map.isCenterChange = true;
|
---|
417 | // }
|
---|
418 | // if (map.isMarkerClick == false)
|
---|
419 | // options.mapCenterSetCallback(currentZoomLevel, map.getCenter());
|
---|
420 | // else map.isMarkerClick = false;
|
---|
421 | //}, 300);
|
---|
422 | });
|
---|
423 |
|
---|
424 | //window.google.maps.event.addListener(map, 'bounds_changed', function () {
|
---|
425 | // alert(map.getBounds());
|
---|
426 | //});
|
---|
427 | }
|
---|
428 |
|
---|
429 | // Get the array nzCities, which contains all the cities and the co-ordinates
|
---|
430 | // Result are loaded asyncroniously
|
---|
431 | function getLocationsAsync(lookupServiceUrl) {
|
---|
432 | return $.ajax({
|
---|
433 | async: true,
|
---|
434 | cache: false,
|
---|
435 | type: "GET",
|
---|
436 | url: lookupServiceUrl,
|
---|
437 | // data params have to match method params in lookupServiceUrl
|
---|
438 | contentType: "application/json; charset=utf-8",
|
---|
439 | dataType: "json",
|
---|
440 | success: function (data) {
|
---|
441 | locationsArray = [];
|
---|
442 | if ($.isArray(data)) { // If many results
|
---|
443 | $.each(data, function (i) {
|
---|
444 | locationsArray.push(data[i]);
|
---|
445 | });
|
---|
446 | } else if (typeof data === "object") { // 1 result
|
---|
447 | locationsArray.push(data);
|
---|
448 | }
|
---|
449 | },
|
---|
450 | error: function (xhr) {
|
---|
451 | alert(JSON.parse(xhr.responseText).Message);
|
---|
452 | }
|
---|
453 | }).promise();
|
---|
454 | }
|
---|
455 |
|
---|
456 | // Adds all the markers to the map
|
---|
457 |
|
---|
458 | function loadMarkers() {
|
---|
459 | clearMarkers();
|
---|
460 | clearLabels();
|
---|
461 | hideDirections();
|
---|
462 | infobox.close();
|
---|
463 |
|
---|
464 | var fallbackDefaultMarker = "https://maps.gstatic.com/mapfiles/ms2/micons/red.png";
|
---|
465 |
|
---|
466 | // console.time("Location Array Timer");
|
---|
467 | // console.profile("Location Array Profiling");
|
---|
468 |
|
---|
469 | $.each(locationsArray, function (index, item) {
|
---|
470 | var markeyIconPath = "";
|
---|
471 |
|
---|
472 | if (options.currentAddressSearchResult && item.RegisterNumber==0) {
|
---|
473 | if (options.currentAddressSearchResult.Lat != item.Lat || options.currentAddressSearchResult.Lng != item.Lng)
|
---|
474 | return;
|
---|
475 | }
|
---|
476 |
|
---|
477 | //First result is the closet to current location so highlight this with diff icon
|
---|
478 | if (item.IconUrl) {
|
---|
479 | markeyIconPath = item.IconUrl;
|
---|
480 | } else if (index === 0) {
|
---|
481 | if (options.directMatchItem == null)
|
---|
482 | markeyIconPath = options.firstResultMarkerPath.length > 0 ? options.firstResultMarkerPath : options.defaultMarkerPath.length > 0 ? options.defaultMarkerPath : fallbackDefaultMarker;
|
---|
483 | else if (options.directMatchItem == item.RegisterNumber)
|
---|
484 | markeyIconPath = options.firstResultMarkerPath.length > 0 ? options.firstResultMarkerPath : options.defaultMarkerPath.length > 0 ? options.defaultMarkerPath : fallbackDefaultMarker;
|
---|
485 | else
|
---|
486 | markeyIconPath = options.defaultMarkerPath.length > 0 ? options.defaultMarkerPath : fallbackDefaultMarker;
|
---|
487 |
|
---|
488 | } else {
|
---|
489 | if (item.RegisterNumber == 0) //it is a address search
|
---|
490 | markeyIconPath = "/content/images/icon-google.png";
|
---|
491 |
|
---|
492 | else if (options.directMatchItem && options.directMatchItem == item.RegisterNumber)
|
---|
493 | markeyIconPath = options.firstResultMarkerPath.length > 0 ? options.firstResultMarkerPath : options.defaultMarkerPath.length > 0 ? options.defaultMarkerPath : fallbackDefaultMarker;
|
---|
494 | else
|
---|
495 | markeyIconPath = options.defaultMarkerPath.length > 0 ? options.defaultMarkerPath : fallbackDefaultMarker;
|
---|
496 | }
|
---|
497 |
|
---|
498 | var marker = new window.google.maps.Marker({
|
---|
499 | position: new window.google.maps.LatLng(item.Lat, item.Lng),
|
---|
500 | map: map,
|
---|
501 | title: item.Name,
|
---|
502 | icon: markeyIconPath,
|
---|
503 | //animation: index === 0 ? window.google.maps.Animation.DROP : null,
|
---|
504 | animation: null,
|
---|
505 | zIndex: (item.zIndex !== 'undefined') ? item.zIndex :
|
---|
506 | index === 0 ? 999999 : null
|
---|
507 | });
|
---|
508 |
|
---|
509 | if (!!item.IconOnly) {
|
---|
510 | return;
|
---|
511 | }
|
---|
512 |
|
---|
513 | var infoBoxContent = "";
|
---|
514 |
|
---|
515 | infoBoxContent += "<div id='custom-infobox-" + index + "'>";
|
---|
516 | infoBoxContent += " <div id='infobox-text'>";
|
---|
517 |
|
---|
518 | if (item.HtmlSnippet) {
|
---|
519 | infoBoxContent += item.HtmlSnippet;
|
---|
520 | } else {
|
---|
521 | infoBoxContent += " <h3>" + item.Name + "</h3>";
|
---|
522 | infoBoxContent += " <p>" + item.Details + "</p>";
|
---|
523 | }
|
---|
524 |
|
---|
525 | if (options.showDistanceFromUserInInfoBox) {
|
---|
526 | var distanceFromCurrentLocation = getGeoDistance(item.Lat, item.Lng, startLocationMarker.getPosition().lat(), startLocationMarker.getPosition().lng());
|
---|
527 | infoBoxContent += " <p>Distance from you: " + distanceFromCurrentLocation + ".<br /></p>";
|
---|
528 | }
|
---|
529 |
|
---|
530 | if (options.directionsId) {
|
---|
531 | infoBoxContent += " <p><strong>Get directions:</strong></p>";
|
---|
532 | infoBoxContent += " <div class='infobox-direction-links'>";
|
---|
533 | infoBoxContent += " <ul>";
|
---|
534 | infoBoxContent += " <li class='walking' title='Click here to get walking directions to " + item.Name + "'><a class='infobox-link' href='#' data-lat='" + item.Lat + "' data-lng='" + item.Lng + "' data-mode='walking'><span class='icon'></span><span class='label'>Walking</span></a></li>";
|
---|
535 | infoBoxContent += " <li class='driving' title='Click here to get driving directions to " + item.Name + "'><a class='infobox-link' href='#' data-lat='" + item.Lat + "' data-lng='" + item.Lng + "' data-mode='driving'><span class='icon'></span><span class='label'>Driving</span></a></li>";
|
---|
536 | infoBoxContent += " <li class='transit' title='Click here to get transit directions to " + item.Name + "'><a class='infobox-link' href='#' data-lat='" + item.Lat + "' data-lng='" + item.Lng + "' data-mode='transit'><span class='icon'></span><span class='label'>Transit</span></a></li>";
|
---|
537 | infoBoxContent += " </ul>";
|
---|
538 | infoBoxContent += " </div>";
|
---|
539 | }
|
---|
540 |
|
---|
541 | infoBoxContent += " </div>";
|
---|
542 | infoBoxContent += "</div>";
|
---|
543 |
|
---|
544 | markersArray.push(marker);
|
---|
545 |
|
---|
546 | window.google.maps.event.addListener(marker, "click", function () {
|
---|
547 | map.isMarkerClick = true;
|
---|
548 | infobox.setContent(infoBoxContent);
|
---|
549 | infobox.open(map, marker);
|
---|
550 | map.panTo(marker.position);
|
---|
551 | });
|
---|
552 |
|
---|
553 | // Check to see is 'showIconLabels' is set
|
---|
554 | // If true then continue and add the labels otherwise skip to the next item
|
---|
555 | if (!options.showIconLabels) {
|
---|
556 | return;
|
---|
557 | }
|
---|
558 |
|
---|
559 | var locationLabel = new InfoBox({
|
---|
560 | content: item.Name,
|
---|
561 | closeBoxURL: "",
|
---|
562 | boxClass: "infobox-label infobox-label-" + index,
|
---|
563 | pixelOffset: new window.google.maps.Size(5, -12),
|
---|
564 | pane: "floatPane",
|
---|
565 | enableEventPropagation: false,
|
---|
566 | alignBottom: false,
|
---|
567 | isHidden: false,
|
---|
568 | disableAutoPan: true
|
---|
569 | });
|
---|
570 |
|
---|
571 | labelsArray.push(locationLabel);
|
---|
572 |
|
---|
573 | locationLabel.open(map, marker);
|
---|
574 |
|
---|
575 | window.google.maps.event.addListener(locationLabel, "domready", function () {
|
---|
576 | $('.infobox-label-' + index).on('click', function () {
|
---|
577 | infobox.setContent(infoBoxContent);
|
---|
578 | infobox.open(map, marker);
|
---|
579 | map.panTo(marker.position);
|
---|
580 | });
|
---|
581 | });
|
---|
582 |
|
---|
583 | });
|
---|
584 |
|
---|
585 | // console.timeEnd("Location Array Timer");
|
---|
586 | // console.profileEnd();
|
---|
587 |
|
---|
588 | window.google.maps.event.addListener(infobox, "domready", function () {
|
---|
589 | $('.infobox-link').on('click', directionsLinkClick);
|
---|
590 | });
|
---|
591 | }
|
---|
592 |
|
---|
593 | /* utils functions */
|
---|
594 |
|
---|
595 | // Removes all markers from the map
|
---|
596 | function clearMarkers() {
|
---|
597 | if (markersArray) {
|
---|
598 | for (var i = 0; i < markersArray.length; i++) {
|
---|
599 | markersArray[i].setMap(null);
|
---|
600 | }
|
---|
601 | markersArray.length = 0;
|
---|
602 | }
|
---|
603 | }
|
---|
604 |
|
---|
605 | // Removes all labels from the map
|
---|
606 | function clearLabels() {
|
---|
607 | if (labelsArray) {
|
---|
608 | for (var i = 0; i < labelsArray.length; i++) {
|
---|
609 | labelsArray[i].setMap(null);
|
---|
610 | }
|
---|
611 | labelsArray.length = 0;
|
---|
612 | }
|
---|
613 | }
|
---|
614 |
|
---|
615 | function clearLocationsArray() {
|
---|
616 | locationsArray.length = 0;
|
---|
617 | }
|
---|
618 |
|
---|
619 | // Returns the distance between to sets to Geo (lat, long) in Km (or meters if they are very close)
|
---|
620 |
|
---|
621 | function getGeoDistance(lat1, lng1, lat2, lng2) {
|
---|
622 | var earthRadiusInKilometers = 6367.0;
|
---|
623 | var toRadian = function (v) {
|
---|
624 | return v * (Math.PI / 180);
|
---|
625 | };
|
---|
626 | var diffRadian = function (v1, v2) {
|
---|
627 | return toRadian(v2) - toRadian(v1);
|
---|
628 | };
|
---|
629 | var distance = earthRadiusInKilometers * 2 * Math.asin(Math.min(1, Math.sqrt((Math.pow(Math.sin((diffRadian(lat1, lat2)) / 2.0), 2.0) + Math.cos(toRadian(lat1)) * Math.cos(toRadian(lat2)) * Math.pow(Math.sin((diffRadian(lng1, lng2)) / 2.0), 2.0)))));
|
---|
630 |
|
---|
631 | //window.console.log("Distance: " + distance);
|
---|
632 |
|
---|
633 | if (distance < 1) {
|
---|
634 | return (distance.toFixed(2) * 1000) + "m";
|
---|
635 | } else {
|
---|
636 | return distance.toFixed(2) + "Km";
|
---|
637 | }
|
---|
638 | }
|
---|
639 |
|
---|
640 | function calcRoute(isUpdateRequest) {
|
---|
641 | if (!startLocationMarker.getPosition() || !endLocation) {
|
---|
642 | // window.console.log("No origin/destination set. Origin: '" + startLocationMarker.getPosition() + "', Destination: '" + endLocation + "'");
|
---|
643 | return;
|
---|
644 | }
|
---|
645 |
|
---|
646 | //window.console.log("calcRoute / Start location : " + startLocationMarker.getPosition());
|
---|
647 | //window.console.log("calcRoute / End location : " + endLocation);
|
---|
648 | infobox.close();
|
---|
649 |
|
---|
650 | var mode;
|
---|
651 |
|
---|
652 | switch (methodOfTravel) {
|
---|
653 | case "transit":
|
---|
654 | mode = window.google.maps.DirectionsTravelMode.TRANSIT;
|
---|
655 | break;
|
---|
656 | case "driving":
|
---|
657 | mode = window.google.maps.DirectionsTravelMode.DRIVING;
|
---|
658 | break;
|
---|
659 | case "walking":
|
---|
660 | mode = window.google.maps.DirectionsTravelMode.WALKING;
|
---|
661 | break;
|
---|
662 | case "bicycling":
|
---|
663 | mode = window.google.maps.DirectionsTravelMode.BICYCLING;
|
---|
664 | break;
|
---|
665 | default:
|
---|
666 | mode = window.google.maps.DirectionsTravelMode.DRIVING;
|
---|
667 | }
|
---|
668 |
|
---|
669 | var request = {
|
---|
670 | origin: startLocationMarker.getPosition(),
|
---|
671 | destination: endLocation,
|
---|
672 | //waypoints: waypoints,
|
---|
673 | travelMode: mode
|
---|
674 | //optimizeWaypoints: document.getElementById('optimize').checked,
|
---|
675 | //avoidHighways: document.getElementById('highways').checked,
|
---|
676 | //avoidTolls: document.getElementById('tolls').checked
|
---|
677 | };
|
---|
678 |
|
---|
679 | directionsService.route(request, function (response, status) {
|
---|
680 | if (status === window.google.maps.DirectionsStatus.OK) {
|
---|
681 |
|
---|
682 | directionsRenderer.setOptions({
|
---|
683 | markerOptions: {
|
---|
684 | visible: false
|
---|
685 | }
|
---|
686 | });
|
---|
687 |
|
---|
688 | directionsRenderer.setDirections(response);
|
---|
689 | directionsObject = response.routes[0].legs[0];
|
---|
690 |
|
---|
691 | if (isUpdateRequest) {
|
---|
692 | options.directionsOnUpdateCallback(directionsObject);
|
---|
693 | } else {
|
---|
694 | options.directionsOnSetCallback(directionsObject);
|
---|
695 | }
|
---|
696 | } else {
|
---|
697 | //alert('Error: ' + status);
|
---|
698 | var directionsFailedText = '<h2>Sorry!</h2><p>Google could not determine the directions from your current location, to your requested destination.</p>';
|
---|
699 | updateDirections($('#' + options.directionsId), directionsFailedText);
|
---|
700 | }
|
---|
701 | });
|
---|
702 | }
|
---|
703 |
|
---|
704 | function updateDirections($container, directions) {
|
---|
705 | $container.html(directions);
|
---|
706 | }
|
---|
707 |
|
---|
708 | function hideDirections() {
|
---|
709 | options.directionsOnCloseCallback();
|
---|
710 | setTimeout(function () {
|
---|
711 | window.google.maps.event.trigger(map, "resize");
|
---|
712 | //resetMap();
|
---|
713 | resetDirections();
|
---|
714 | }, 500);
|
---|
715 | }
|
---|
716 |
|
---|
717 | function resetMap() {
|
---|
718 | map.panTo(mapCentre);
|
---|
719 | map.setZoom(options.zoomLevel);
|
---|
720 | }
|
---|
721 |
|
---|
722 | function mapResize() {
|
---|
723 | window.google.maps.event.trigger(map, 'resize');
|
---|
724 | fitMapToMarkers();
|
---|
725 |
|
---|
726 | }
|
---|
727 |
|
---|
728 | function panToMapCenter() {
|
---|
729 | window.google.maps.event.trigger(map, 'resize');
|
---|
730 | fitMapToMarkers();
|
---|
731 | }
|
---|
732 |
|
---|
733 | function fitMapToMarkers() {
|
---|
734 | window.google.maps.event.trigger(map, 'resize');
|
---|
735 |
|
---|
736 | if (!locationsArray || locationsArray.length === 0) {
|
---|
737 | map.panTo(mapCentre);
|
---|
738 | return;
|
---|
739 | }
|
---|
740 |
|
---|
741 | var latlngbounds = new window.google.maps.LatLngBounds();
|
---|
742 |
|
---|
743 | if (map.isZoomSearch == false) {
|
---|
744 | for (var i = 0; i < locationsArray.length; i++) {
|
---|
745 | var lat = parseFloat(locationsArray[i].Lat);
|
---|
746 | var lng = parseFloat(locationsArray[i].Lng);
|
---|
747 | var point = new window.google.maps.LatLng(lat, lng);
|
---|
748 |
|
---|
749 | latlngbounds.extend(point);
|
---|
750 | }
|
---|
751 | map.fitBounds(latlngbounds);
|
---|
752 | //var zoom = map.getZoom();
|
---|
753 | //map.setZoom(zoom > 15 ? 15 : zoom);
|
---|
754 | if (locationsArray.length == 1) {
|
---|
755 | map.setZoom(14);
|
---|
756 | }
|
---|
757 | }
|
---|
758 | else {
|
---|
759 | map.isZoomSearch = false;
|
---|
760 | map.isCenterChange = false;
|
---|
761 | }
|
---|
762 |
|
---|
763 | //map.setZoom(options.zoomLevel);
|
---|
764 | //map.panToBounds(latlngbounds);
|
---|
765 | }
|
---|
766 |
|
---|
767 | function resetDirections() {
|
---|
768 | directionsRenderer.setMap(null);
|
---|
769 | directionsRenderer.setPanel(null);
|
---|
770 | directionsRenderer = new window.google.maps.DirectionsRenderer();
|
---|
771 | directionsRenderer.setMap(map);
|
---|
772 | directionsRenderer.setPanel(document.getElementById("directionsPanel"));
|
---|
773 | }
|
---|
774 |
|
---|
775 | function directionsLinkClick(event) {
|
---|
776 | var $this = $(event.currentTarget);
|
---|
777 | var lat = $this.data('lat');
|
---|
778 | var lng = $this.data('lng');
|
---|
779 | methodOfTravel = $this.data('mode').toLowerCase();
|
---|
780 | setDestinations(lat, lng);
|
---|
781 | }
|
---|
782 |
|
---|
783 | function setDestinations(lat, lng) {
|
---|
784 | endLocation = new window.google.maps.LatLng(lat, lng);
|
---|
785 | calcRoute(false);
|
---|
786 | window.google.maps.event.trigger(map, "resize");
|
---|
787 | }
|
---|
788 |
|
---|
789 | function disableMapControls(mapOptions) {
|
---|
790 | mapOptions.panControl = false;
|
---|
791 | mapOptions.streetViewControl = false;
|
---|
792 | mapOptions.zoomControl = false;
|
---|
793 | mapOptions.mapTypeControl = false;
|
---|
794 | }
|
---|
795 |
|
---|
796 |
|
---|
797 | // PUBLIC FUNCTIONS AND PROPERTIES
|
---|
798 |
|
---|
799 | this.userLocation = userLocation;
|
---|
800 |
|
---|
801 | // Add a new set of location markers to the map
|
---|
802 | this.addNewLocationMarkersAsync = function (locationsServicePathForNewMarkers) {
|
---|
803 | $.when(getLocationsAsync(locationsServicePathForNewMarkers))
|
---|
804 | .done(function () {
|
---|
805 | hideDirections();
|
---|
806 | loadMarkers();
|
---|
807 | resetMap();
|
---|
808 | resetDirections();
|
---|
809 | });
|
---|
810 | };
|
---|
811 |
|
---|
812 | this.addNewLocationMarkers = function (newMarkersArray) {
|
---|
813 | locationsArray = [];
|
---|
814 | $.each(newMarkersArray, function (index) {
|
---|
815 | locationsArray.push(newMarkersArray[index]);
|
---|
816 | });
|
---|
817 |
|
---|
818 | loadMarkers();
|
---|
819 |
|
---|
820 | if (map.keepMapZoom == false)
|
---|
821 | fitMapToMarkers();
|
---|
822 | else map.keepMapZoom = false;
|
---|
823 |
|
---|
824 | resetDirections();
|
---|
825 | };
|
---|
826 |
|
---|
827 | this.clearMap = function () {
|
---|
828 | clearMarkers();
|
---|
829 | clearLabels();
|
---|
830 | clearLocationsArray();
|
---|
831 | infobox.close();
|
---|
832 | };
|
---|
833 |
|
---|
834 | this.directions = directionsObject;
|
---|
835 |
|
---|
836 | this.fitMapToMarkers = function () {
|
---|
837 | fitMapToMarkers();
|
---|
838 | };
|
---|
839 |
|
---|
840 | this.keepZoom = function(keep) {
|
---|
841 | map.keepMapZoom = keep;
|
---|
842 | };
|
---|
843 |
|
---|
844 | this.getMapBounds = function() {
|
---|
845 | return map.getBounds();
|
---|
846 | };
|
---|
847 |
|
---|
848 | this.setZoomLevel = function(value) {
|
---|
849 | map.setZoom(value);
|
---|
850 | };
|
---|
851 |
|
---|
852 | this.getZoomLevel = function() {
|
---|
853 | return map.getZoom();
|
---|
854 | };
|
---|
855 |
|
---|
856 | this.setZoomSearchFlag = function (flag) {
|
---|
857 | map.isZoomSearch = flag;
|
---|
858 | };
|
---|
859 |
|
---|
860 | this.options = options;
|
---|
861 | };
|
---|
862 |
|
---|
863 | }(window.jQuery)); |
---|