1/* google-maps-connector */ 2XA.connector.mapsConnector = (function ($, document) { 3 4 "use strict"; 5 6 var api = {}, 7 maps = [], 8 markers = [], 9 map, 10 getMapType, 11 createMarker, 12 infoWindows = [], 13 activeInfoWindows = [], 14 popupGenerations = [], 15 addMarker, 16 callbacks = [], 17 animationTimeout, 18 loading = false, 19 maxMapZoom = 18; 20 21 var notifyPoiClicked = function (mapId, data) { 22 var event; 23 24 if (!data || typeof data.id === "undefined" || data.id === null) { 25 return; 26 } 27 28 event = new CustomEvent("thr:map-poi-clicked", { 29 detail: { 30 mapId: mapId, 31 id: data.id, 32 type: data.type 33 } 34 }); 35 36 document.dispatchEvent(event); 37 }; 38 39 var closeInfoWindowsForMap = function (mapId) { 40 var key, 41 mapKeyPrefix = mapId + "#"; 42 43 popupGenerations[mapId] = (popupGenerations[mapId] || 0) + 1; 44 45 if (activeInfoWindows[mapId]) { 46 activeInfoWindows[mapId].close(); 47 activeInfoWindows[mapId] = null; 48 } 49 50 for (key in infoWindows) { 51 if (infoWindows.hasOwnProperty(key) && 52 (key === String(mapId) || key.indexOf(mapKeyPrefix) === 0)) { 53 infoWindows[key].close(); 54 // Dynamic popups are replaced after their content is fetched. 55 // Keep static popup instances available for future pin clicks. 56 if (key === String(mapId)) { 57 delete infoWindows[key]; 58 } 59 } 60 } 61 }; 62 63 var clusterers = []; 64 var clustererReady = false; 65 var clustererReadyPromise = null; 66 67 var getMarkerClustererCtor = function () { 68 if (window.markerClusterer && window.markerClusterer.MarkerClusterer) { 69 return window.markerClusterer.MarkerClusterer; 70 } 71 if (window.MarkerClusterer) { 72 return window.MarkerClusterer; 73 } 74 return null; 75 }; 76 77 var syncClustererMarkers = function (mapId) { 78 var clusterer = clusterers[mapId], 79 mapMarkers, 80 i; 81 82 if (!clusterer || !markers.hasOwnProperty(mapId)) { 83 return; 84 } 85 86 mapMarkers = markers[mapId]; 87 clusterer.clearMarkers(); 88 89 for (i = 0; i < mapMarkers.length; i++) { 90 clusterer.addMarker(mapMarkers[i].marker); 91 } 92 }; 93 94 var clusterStyles = [ 95 { maxCount: 9, diameter: 34, fontSize: 13 }, 96 { maxCount: 24, diameter: 42, fontSize: 14 }, 97 { maxCount: 49, diameter: 50, fontSize: 15 }, 98 { maxCount: 99, diameter: 60, fontSize: 17 }, 99 { maxCount: Infinity, diameter: 72, fontSize: 18 } 100 ]; 101 102 var getClusterStyle = function (count) { 103 var i; 104 105 for (i = 0; i < clusterStyles.length; i++) { 106 if (count <= clusterStyles[i].maxCount) { 107 return clusterStyles[i]; 108 } 109 } 110 111 return clusterStyles[clusterStyles.length - 1]; 112 }; 113 114 var buildClusterRenderer = function () { 115 return { 116 render: function (cluster, stats) { 117 var count = cluster.count, 118 position = cluster.position, 119 style = getClusterStyle(count), 120 radius, 121 textY, 122 svg, 123 title; 124 125 radius = (style.diameter / 2) - 2.5; 126 textY = (style.diameter / 2) + 2; 127 128 svg = [ 129 '<svg xmlns="http://www.w3.org/2000/svg" width="' + style.diameter + '" height="' + style.diameter + '" viewBox="0 0 ' + style.diameter + ' ' + style.diameter + '">', 130 '<defs>', 131 '<filter id="clusterShadow" x="-20%" y="-20%" width="140%" height="140%">', 132 '<feDropShadow dx="0" dy="1" stdDeviation="1.5" flood-color="#000000" flood-opacity="0.18" />', 133 '</filter>', 134 '</defs>', 135 '<circle cx="' + (style.diameter / 2) + '" cy="' + (style.diameter / 2) + '" r="' + radiu
135s + '" fill="#475569" stroke="#ffffff" stroke-width="3" filter="url(#clusterShadow)" />', 136 '<text x="50%" y="' + textY + '" text-anchor="middle" dominant-baseline="middle" font-family="Arial, sans-serif" font-size="' + style.fontSize + '" font-weight="700" fill="#ffffff">', 137 String(count), 138 '</text>', 139 '</svg>' 140 ].join(""); 141 142 title = "Cluster of " + count + " markers"; 143 144 return new google.maps.Marker({ 145 position: position, 146 title: title, 147 zIndex: Number(google.maps.Marker.MAX_ZINDEX) + count, 148 icon: { 149 url: "data:image/svg+xml;charset=UTF-8," + encodeURIComponent(svg), 150 scaledSize: new google.maps.Size(style.diameter, style.diameter) 151 } 152 }); 153 } 154 }; 155 }; 156 157 getMapType = function (options) { 158 switch (options.mode) { 159 case 'Roadmap': { 160 return google.maps.MapTypeId.ROADMAP; 161 } 162 case 'Satellite': { 163 return google.maps.MapTypeId.SATELLITE; 164 } 165 case 'Hybrid':{ 166 return google.maps.MapTypeId.HYBRID; 167 } 168 default: { 169 return google.maps.MapTypeId.ROADMAP; 170 } 171 } 172 }; 173 174 createMarker = function(mapId, data) { 175 var marker; 176 //Added by Vijay - 10/09/2020 - Determine the Zoom based on the distance 177 var zoom = 12; 178 if (data.distance < 12) { 179 zoom = 15; 180 } 181 var map = maps[mapId]; 182 map.setZoom(zoom); 183 184 if (data.icon === null) { 185 marker = new google.maps.Marker({ 186 position: new google.maps.LatLng(data.latitude, data.longitude), 187 title: data.title 188 }); 189 } else { 190 marker = new google.maps.Marker({ 191 position: new google.maps.LatLng(data.latitude, data.longitude), 192 title: data.title, 193 icon: data.icon 194 }); 195 } 196 //Added by Vijay - 10/09/2020 - Determine the Zoom based on the distance 197 // marker.addListener("click", () => { 198 // map.setZoom(zoom); 199 // map.setCenter(marker.getPosition()); 200 //}); 201 if (data.latitude === '' && data.longitude === '') { 202 //if marker doesn't have coordinated then create it but doesn't show it on the map 203 marker.setVisible(false); 204 } 205 206/******** Add By Donaldo Function AddCustomAnimation *****/ 207 /********* Start ***********/ 208 const Divmap = document.getElementById("search-map-urgent-care"); 209 if (Divmap) { 210 marker.setAnimation(google.maps.Animation.BOUNCE); 211 } 212 /********* End ***********/ 213 return marker; 214 }; 215 216 addMarker = function(mapId, marker, data) { 217 //save POI id - this will be used while removing dynamic POIs from the map 218 marker.id = data.id; 219 //Added by Vijay - 10/09/2020 - Determine the Zoom based on the distance 220 if (markers[mapId]) { 221 markers[mapId].push({ marker: marker, type: data.type, zoom: data.zoom }); 222 } else { 223 markers[mapId] = []; 224 markers[mapId].push({ marker: marker, type: data.type, zoom: data.zoom }); 225 } 226 227 if (clusterers[mapId]) { 228 clusterers[mapId].addMarker(marker); 229 } 230 }; 231 232 api.loadScript = function(key, callback) { 233 //save each callback and call them all when script will be loaded - protection for loading maps twice 234 callbacks.push(callback); 235 236 if (!loading) { 237 loading = true; 238 var script = document.createElement("script"), 239 src = "https://maps.googleapis.com/maps/api/js?v=3.exp"; 240 script.type = "text/javascript"; 241 if (typeof key !== "undefined" && key !== "") { 242 src += "&key=" + key + "&v=3.exp&signed_in=false"; 243 } else { 244 src += "&signed_in=false"; 245 } 246 src += "&libraries=places&callback=XA.connector.mapsConnector.scriptsLoaded"; 247 script.src = src; 248 script.onload = function () { 249 console.log("Google loader has been loaded, waiting for maps a
249pi"); 250 }; 251 document.body.appendChild(script); 252 253 // Clusterer script 254 clustererReadyPromise = new Promise(function(resolve, reject) { 255 var clustererScript = document.createElement("script"); 256 clustererScript.type = "text/javascript"; 257 clustererScript.src = "https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"; 258 clustererScript.onload = function () { 259 clustererReady = true; 260 resolve(); 261 }; 262 clustererScript.onerror = reject; 263 document.body.appendChild(clustererScript); 264 }); 265 } 266 }; 267 268 api.scriptsLoaded = function () { 269 var i, length = callbacks.length; 270 for (i = 0; i < length; i++) { 271 callbacks[i].call(); 272 } 273 loading = false; 274 }; 275 276 api.showMap = function(mapId, options, viewBounds) { 277 var mapOptions, 278 listener, 279 idleListener, 280 scrollwheel = options.disableMapZoomOnScroll !== "1", 281 mapDragging = options.disableMapScrolling !== "1"; 282 283 if (viewBounds instanceof Array) { 284 mapOptions = { 285 zoom: options.zoom, 286 scrollwheel: scrollwheel, 287 draggable: mapDragging, 288 center: new google.maps.LatLng(viewBounds[0], viewBounds[1]), 289 mapTypeId: getMapType(options), 290 styles: [{ 291 featureType: 'poi.business', 292 stylers: [{ visibility: 'off' }], 293 },] 294 }; 295 map = new google.maps.Map(document.getElementById(options.canvasId), mapOptions); 296 } else { 297 mapOptions = { 298 scrollwheel: scrollwheel, 299 draggable: mapDragging, 300 mapTypeId: getMapType(options), 301 maxZoom: maxMapZoom, 302 styles: [{ 303 featureType: 'poi.business', 304 stylers: [{ visibility: 'off' }], 305 },] 306 }; 307 map = new google.maps.Map(document.getElementById(options.canvasId), mapOptions); 308 map.fitBounds(viewBounds); 309 if (options.poiCount < 2) { 310 idleListener = google.maps.event.addListener(map, "idle", function() { 311 if (Object.keys(markers).length > 0 && markers[mapId].length < 2) { 312 map.setZoom(options.zoom); 313 google.maps.event.removeListener(idleListener); 314 } 315 }); 316 } 317 } 318 319 listener = google.maps.event.addListener(map, "zoom_changed", function(a, b, c, d) { 320 var zoom = map.getZoom(); 321 322 // A hidden InfoWindow remains active while zooming. Close it so 323 // Google Maps cannot auto-pan back to it later. 324 closeInfoWindowsForMap(mapId); 325 326 if (zoom < 1) { 327 map.setZoom(1); 328 } 329 if (zoom > maxMapZoom) { 330 map.setZoom(maxMapZoom); 331 } 332 }); 333 334 maps[mapId] = map; 335 336 var createClusterer = function () { 337 var MarkerClustererCtor = getMarkerClustererCtor(); 338 339 if (!MarkerClustererCtor) { 340 return; 341 } 342 343 clusterers[mapId] = new MarkerClustererCtor({ 344 map: maps[mapId], 345 markers: [], 346 renderer: buildClusterRenderer(), 347 onClusterClick: function (event, cluster, clusterMap) { 348 closeInfoWindowsForMap(mapId); 349 350 // Preserve the clusterer's normal behavior of zooming 351 // into the clicked cluster after closing the popup. 352 if (cluster.bounds) { 353 clusterMap.fitBounds(cluster.bounds); 354 } 355 } 356 }); 357 syncClustererMarkers(mapId); 358 }; 359 360 if (clustererReady) { 361 createClusterer(); 362 } else if (clustererReadyPromise) { 363 clustererReadyPromise.then(createClusterer); 364 } else { 365 createClusterer(); 366 } 367 }; 368 369 api.renderPoi = function(mapId, data) { 370 var marker = createMarker(mapId, data), 371 key = mapId + "#" + data.id; 372 373 addMarker(mapId, marker, data); 374 375 if (data.html !== "" && data.html !== null) { 376 infoWindows[key] = new google.maps.InfoWindow({ 377 content: data.html 378 }); 379 } 380 381 (function(currentKey, marker, poiData) { 382 var clickHandler = function() { 383 closeInfoWindowsForMap(mapId); 384 385 notifyPoiClicked(mapId, poiData); 386 387 if (typeof infoWindows[currentKey] !== "undefined") { 388 activeInfoWindows[mapId] = infoWindows[currentKey]; 389 activeInfoWindows[mapId].open(maps[mapId], marker); 390 } 391 }; 392 393 if (XA.connector.mapOverlapSpiderfy && XA.connector.mapOverlapSpiderfy.registerMarker(mapId, marker, clickHandler)) { 394 return; 395 } 396 397 google.maps.event.addListener(marker, "click", clickHandler); 398 })(key, marker, data); 399 }; 400 401 api.renderDynamicPoi = function(mapId, data, getPoiContent) { 402 var marker = createMarker(mapId, data); 403 404 addMarker(mapId, marker, data); 405 406 var clickHandler = function () { 407 closeInfoWindowsForMap(mapId); 408 var popupGeneration = popupGenerations[mapId]; 409 notifyPoiClicked(mapId, data); 410 411 if (typeof (getPoiContent) === "function") { 412 var poiId = data.id, 413 poiTypeId = data.poiTypeId, 414 poiVariantId = data.poiVariantId; 415 416 if (poiVariantId == null) { 417 return; 418 } 419 420 getPoiContent(poiId, poiTypeId, poiVariantId, function (result) { 421 if (popupGeneration !== popupGenerations[mapId]) { 422 return; 423 } 424 425 infoWindows[mapId] = new google.maps.InfoWindow({ 426 content: result.Html 427 }); 428 activeInfoWindows[mapId] = infoWindows[mapId]; 429 activeInfoWindows[mapId].open(maps[mapId], marker); 430 }); 431 } 432 }; 433 434 if (XA.connector.mapOverlapSpiderfy && XA.connector.mapOverlapSpiderfy.registerMarker(mapId, marker, clickHandler)) { 435 return; 436 } 437 438 google.maps.event.addListener(marker, "click", clickHandler); 439 }; 440 441 api.clearMarkers = function(mapId) { 442 var mapMarkers; 443 if (markers.hasOwnProperty(mapId)) { 444 mapMarkers = markers[mapId]; 445 for (var i = 0; i < mapMarkers.length; i++) { 446 if (mapMarkers[i].type === "Dynamic") { 447 mapMarkers[i].marker.setMap(null); 448 } 449 } 450 markers[mapId] = mapMarkers.filter(function (markerData) { 451 if (markerData.type === "Static" || markerData.type === "MyLocation") { 452 return true; 453 } else { 454 return false;
455 } 456 }); 457 458 if (clusterers[mapId]) { 459 syncClustererMarkers(mapId); 460 } 461 } 462 }; 463 464 api.updateMapPosition = function (mapId) { 465 var map = maps[mapId], 466 marker, 467 mapMarkers = [], 468 bounds = new google.maps.LatLngBounds(), 469 i; 470 471 if (markers.hasOwnProperty(mapId)) { 472 mapMarkers = markers[mapId]; 473 } 474 475 // Keep the last map position when there are no markers to fit. 476 if (mapMarkers.length === 0) { 477 return; 478 } 479 480 for (i =0; i < mapMarkers.length; i++) { 481 marker = mapMarkers[i].marker; 482 bounds.extend(new google.maps.LatLng(marker.position.lat(), marker.position.lng())); 483 } 484 485 map.fitBounds(bounds); 486 }; 487 488 api.centerMap = function(mapId, data, centerMap, animate) { 489 var map = maps[mapId], 490 mapMarkers = [], 491 animatedMarker, 492 zoom, 493 targetZoom; 494 495 if (centerMap) { 496 map.setCenter(new google.maps.LatLng(data.coordinates[0], data.coordinates[1])); 497 } 498 499 if (animate) { 500 if (markers.hasOwnProperty(mapId)) { 501 mapMarkers = markers[mapId]; 502 } 503 for (var i = 0; i < mapMarkers.length; i++) { 504 mapMarkers[i].marker.setAnimation(null); 505 if (mapMarkers[i].marker.id === data.id) { 506 animatedMarker = mapMarkers[i].marker; 507 //Added by Vijay - 10/09/2020 - Determine the Zoom based on the distance 508 zoom = mapMarkers[i].zoom; 509 if (!clusterers[mapId]) { 510 mapMarkers[i].marker.setMap(null); 511 } 512 } 513 } 514 if (typeof animatedMarker !== "undefined") { 515 targetZoom = clusterers[mapId] ? maxMapZoom : zoom; 516 map.setCenter(animatedMarker.getPosition()); 517 map.setZoom(targetZoom); 518 animatedMarker.setAnimation(google.maps.Animation.BOUNCE); 519 animationTimeout = setTimeout(function () { 520 if (!clusterers[mapId]) { 521 animatedMarker.setMap(map); 522 } 523 }, 2000); 524 } 525 } 526 }; 527 528 api.getCentralPoint = function(poisCoords) { 529 var i, 530 poiCoords, 531 count = poisCoords.length, 532 bounds = new google.maps.LatLngBounds(); 533 534 for (i = 0; i < count; i++) { 535 poiCoords = poisCoords[i]; 536 if (poiCoords.latitude !== "" && poiCoords.longitude !== "") { 537 bounds.extend(new google.maps.LatLng(poiCoords.latitude, poiCoords.longitude)); 538 } 539 } 540 return bounds; 541 }; 542 543 // api.locationAutocomplete has been updated to be able to search location only in us. 544 // function updated at 11/12/2020 545 api.locationAutocomplete = function(queryParams, successCallback, failCallback){ 546 var autocomplete = new google.maps.places.AutocompleteService(), 547 maxResults = queryParams.maxResults <= 0 ? 1 : queryParams.maxResults; 548 autocomplete.getPlacePredictions({ 549 input: queryParams.text, 550 'componentRestrictions': { 551 'country': 'us' 552 }, 553 'types': ['geocode'] 554 }, function(results) { 555 var predictions = [], 556 length; 557 if (results != null && results.length) { 558 length = results.length >= maxResults ? maxResults : results.length; 559 560 for (var i = 0; i < length; i++) { 561 predictions.push(_.extend(results[i], { 562 text: results[i].description 563 })); 564 } 565 successCallback(predictions); 566 } else { 567 failCallback(); 568 } 569 }); 570 }; 571 572/* 573 api.locationAutocomplete = function(queryParams, successCallback, failCallback) { 574 var autocomplete = new google.maps.places.AutocompleteService(), 575 maxResults = queryParams.maxResults <= 0 ? 1 : queryParams.maxResults; 576 var bounds = new google.maps.LatLngBounds( 577 new google.maps.LatLng("32.204460", "-97.910215"), 578 new google.maps.LatLng("33.292131", "-96.428846")); 579 autocomplete.getQueryPredictions({ input: queryParams.text, bounds: boun
579ds }, function(results) { 580 var predictions = [], 581 length; 582 if (results != null && results.length) { 583 length = results.length >= maxResults ? maxResults : results.length; 584 585 for (var i = 0; i < length; i++) { 586 predictions.push(_.extend(results[i], { text: results[i].description })); 587 } 588 589 successCallback(predictions); 590 } else { 591 failCallback(); 592 } 593 }); 594 }; 595 596 */ 597 598 api.addressLookup = function (queryParams, successCallback, failCallback) { 599 var search, 600 query; 601 602 if(queryParams.hasOwnProperty("place_id")){ //places lookup 603 search = new google.maps.places.PlacesService(typeof map !== "undefined" ? map : new google.maps.Map(document.createElement("div"))); 604 search.getDetails({ 605 placeId : queryParams["place_id"] 606 }, function(results,status){ 607 if (status == google.maps.places.PlacesServiceStatus.OK) { 608 if(typeof(results) !== "undefined" && typeof(results.geometry.location) !== "undefined"){ 609 successCallback([results.geometry.location.lat(),results.geometry.location.lng()]); 610 return; 611 } 612 } 613 failCallback(); 614 }); 615 } 616 else { //standard lookup 617 var bounds = new google.maps.LatLngBounds( 618 new google.maps.LatLng("32.204460", "-97.910215"), 619 new google.maps.LatLng("33.292131", "-96.428846")); 620 query = { 621 address: queryParams.text, 622 bounds: bounds 623 }; 624 search = new google.maps.Geocoder(); 625 search.geocode(query, function(results,status){ 626 if (status == google.maps.GeocoderStatus.OK) { 627 if(typeof(results[0]) !== "undefined" && typeof(results[0].geometry.location) !== "undefined"){ 628 successCallback([results[0].geometry.location.lat(),results[0].geometry.location.lng()]); 629 return; 630 } 631 } 632 failCallback(); 633 }); 634 } 635 }; 636 637 api.updateMyPoiLocation = function(mapId, coordinates, zoom) { 638 var map = maps[mapId], 639 mapMarkers = [], 640 myLocationMarker; 641 642 if (markers.hasOwnProperty(mapId)) { 643 mapMarkers = markers[mapId]; 644 myLocationMarker = mapMarkers.filter(function (marker) { 645 if (marker.type === "MyLocation") { 646 return true; 647 } 648 return false; 649 }); 650 if (myLocationMarker.length > 0) { 651 myLocationMarker[0].marker.setPosition(new google.maps.LatLng(coordinates[0], coordinates[1])); 652 myLocationMarker[0].marker.setVisible(true); 653 this.updateMapPosition(mapId); 654 if (clusterers[mapId]) { 655 syncClustererMarkers(mapId); 656 } 657 if (typeof zoom !== "undefined") { 658 map.setZoom(zoom); 659 } 660 } 661 } 662 }; 663 664 return api; 665 666})(jQuery, document); 667 668
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.