1XA.component.map = (function ($, document) { 2 3 "use strict"; 4 5 var api = {}, 6 maps = [], 7 searchEndpoint, 8 searchResultsSignatures = [], 9 key, 10 urlHelperModel, 11 apiModel, 12 queryModel, 13 mapsConnector, 14 scriptsLoaded = false, 15 initialize, 16 searchResults, 17 pushMapData, 18 resultsLoaded, 19 myLocationChanged, 20 myLocationData, 21 mapViews = [], 22 MapModel, 23 MapView; 24 25 resultsLoaded = function (data) { 26 searchResults = data; 27 }; 28 29 myLocationChanged = function (data) { 30 myLocationData = data; 31 }; 32 33 initialize = function () { 34 var i, mapsCount = maps.length; 35 for (i = 0; i < mapsCount; i++) { 36 //crate Backbone.js views - one view per component on the page 37 mapViews.push(new MapView({el: maps[i], model: new MapModel()})); 38 } 39 if (typeof (XA.component.search) !== "undefined") { 40 pushMapData(); 41 } 42 }; 43 44 pushMapData = function() { 45 var notInitializedMaps, 46 resultsExists = typeof searchResults !== "undefined", 47 myLocationExists = typeof myLocationData !== "undefined"; 48 49 if (resultsExists || myLocationExists) { 50 //in case that results were loaded before initialization of view and model, trigger another event with 51 //previously loaded results 52 //this will happen just once - while initialization 53 //remember about checking if all maps are already rendered 54 notInitializedMaps = mapViews.filter(function (view) { 55 if (view.model.get("showed") === false) { 56 return true; 57 } 58 return false; 59 }); 60 61 if (notInitializedMaps.length > 0) { 62 setTimeout(pushMapData, 1000); 63 } else { 64 if (resultsExists) { 65 XA.component.search.vent.trigger("internal-results-loaded", searchResults); 66 } 67 if (myLocationExists) { 68 XA.component.search.vent.trigger("internal-my-location-coordinates-changed", myLocationData); 69 } 70 } 71 } 72 }; 73 74 MapModel = Backbone.Model.extend({ 75 defaults: { 76 dataProperties: {}, 77 dynamicPoiList: [], 78 showed: false, 79 myLocation: ["", ""], 80 id: null, 81 loadMore: false 82 }, 83 initialize: function() { 84 var sig = this.get("dataProperties").searchResultsSignature, 85 hash = queryModel.parseHashParameters(window.location.hash), 86 param = typeof (sig) !== "undefined" && sig !== "" ? sig + "_g" : "g"; 87 88 if (typeof (XA.component.search) !== "undefined") { 89 XA.component.search.vent.on("results-loaded", this.updateDynamicPoiList.bind(this)); 90 XA.component.search.vent.on("internal-results-loaded", this.updateDynamicPoiList.bind(this)); 91 XA.component.search.vent.on("my-location-coordinates-changed", this.changeMyLocation.bind(this)); 92 XA.component.search.vent.on("internal-my-location-coordinates-changed", this.changeMyLocation.bind(this)); 93 XA.component.search.vent.on("hashChanged", this.hashChanged.bind(this)); 94 } 95 96 if (hash.hasOwnProperty(param) && hash[param] !== "") { 97 //if Location Filter component is on the page it could already fill "g" hash parameter 98 this.set("myLocation", hash[param].split("|")); 99 } 100 }, 101 getPoiVariant: function (poiTypeId, poiVariantId) { 102 var mapping = this.get("dataProperties").typeToVariantMapping, 103 typeId; 104 105 if (typeof poiTypeId !== "undefined" && poiTypeId != null) { 106 typeId = "{" + poiTypeId.toUpperCase() + "}"; 107 if (mapping.hasOwnProperty(typeId)) { 108 return mapping[typeId]; 109 } else { 110 return poiVariantId; 111 } 112 } 113 return poiVariantId; 114 }, 115 updateDynamicPoiList: function(searchResults) { 116 var dynamicPoiList = [], 117 signature = this.get("dataProperties").searchResultsSignature, 118 geolocationData = searchResults.data.filter(function (result) { 119 if (result.hasOwnProperty("Geospatial")) { 120 return true; 121 } else { 122 return false; 123 } 124 }), 125 i, 126 poi; 127 128 if (signature !== searchResults.searchResultsSignature) { 129 return; 130 } 131 132 //save information that those POIs comes from load more action
133 this.set("loadMore", searchResults.loadMore); 134 135 for (i = 0; i < geolocationData.length; i++) { 136 poi = geolocationData[i]; 137 138 //don't show POIs which doesn't have Latitude and Longitude 139 if (poi.Geospatial.Latitude === 0 || poi.Geospatial.Longitude === 0) { 140 continue; 141 } 142 143 dynamicPoiList.push({ 144 id: poi.Id, 145 type: "Dynamic", 146 title: poi.Name, 147 latitude: poi.Geospatial.Latitude, 148 longitude: poi.Geospatial.Longitude, 149 icon: poi.Geospatial.PoiIcon, 150 poiTypeId: poi.Geospatial.PoiTypeId, 151 poiVariantId: this.getPoiVariant(poi.Geospatial.PoiTypeId, poi.Geospatial.PoiVariantId), 152 html: poi.Html 153 }); 154 } 155 156 this.set("dynamicPoiList", dynamicPoiList); 157 }, 158 changeMyLocation: function (myLocationData) { 159 var sig = this.get("dataProperties").searchResultsSignature; 160 if (sig === myLocationData.sig) { 161 this.set("myLocation", myLocationData.coordinates); 162 } 163 }, 164 hashChanged: function (hash) { 165 var sig = this.get("dataProperties").searchResultsSignature, 166 location = hash[sig !== "" ? sig + "_g" : "g"], 167 myLocationDataSignature = typeof myLocationData !== "undefined" ? myLocationData.sig : "", 168 parts; 169 170 if (sig === myLocationDataSignature && typeof location !== "undefined" && location !== null && location !== "") { 171 parts = location.split("|"); 172 if (parts.length > 1) { 173 this.set("myLocation", [parts[0], parts[1]]); 174 } 175 } 176 } 177 }); 178 179 MapView = Backbone.View.extend({ 180 initialize : function () { 181 var dataProperties = this.$el.data(), 182 properties = dataProperties.properties; 183 184 if (this.model) { 185 this.model.set({dataProperties: properties}); 186 this.model.set({id: this.$el.find(".map-canvas").prop("id")}); 187 } 188 189 this.render(); 190 this.model.on("change:dynamicPoiList", this.renderDynamicPois, this); 191 this.model.on("change:myLocation", this.updateMyLocationPoi, this); 192 if (typeof (XA.component.search) !== "undefined") { 193 XA.component.search.vent.on("center-map", this.handleCenterMap.bind(this)); 194 } 195 this.updateMyLocationPoi(); 196 197 }, 198 render : function () { 199 var that = this, 200 showed = this.model.get("showed"), 201 canvas = document.getElementById(this.model.get("id")); 202 203 if (!showed && canvas !== null) { 204 this.getCentralPoint(function (viewBounds, ctx) { 205 if (typeof viewBounds !== "undefined") { 206 var context = typeof ctx !== "undefined" ? ctx : this, 207 id = context.model.get("id"), 208 properties = context.model.get("dataProperties"), 209 mapOptions = { 210 canvasId: id, 211 zoom: typeof(properties.zoom) === "number" ? properties.zoom : context.parseZoom(properties.zoom, 15), 212 mode: properties.mode, 213 poiCount: properties.pois.length, 214 key: properties.key, 215 disableMapScrolling: properties.disableMapScrolling, 216 disableMapZoomOnScroll: properties.disableMapZoomOnScroll 217 }; 218 219 mapsConnector.showMap(id, mapOptions, viewBounds); 220 context.renderPoiList(id, properties.pois); 221 222 context.model.set("showed", true); 223 } 224 }); 225 } 226 }, 227 renderDynamicPois: function() { 228 var dataProperties = this.model.get("dataProperties"), 229 dynamicPoiList = this.model.get("dynamicPoiList"), 230 properties = this.model.get("dataProperties"), 231 id = this.model.get("id"), 232 i; 233 234 if (!this.model.get("loadMore")) { 235 mapsConnector.clearMarkers(id); 236 } 237 238 for (i = 0; i < dynamicPoiList.length; i++) { 239 mapsConnector.renderDynamicPoi(id, dynamicPoiList[i], this.getGeoPoiContent.bind(this)); 240 } 241 242 //if user want to see all POIs then after adding dynamic POIs we have to recalculate map center point 243 if (dataProperties.centralPointMode === "MidOfPoi") { 244 mapsConnector.updateMapPosition(this.model.get("id"), this.parseZoom(properties.zoom, 15)); 245 } 246
247 if (mapsConnector.createClusters) { 248 mapsConnector.createClusters(id); 249 } 250 }, 251 renderPoiList: function(mapId, poiList) { 252 var i, 253 poi, 254 myLocation, 255 poiCount = poiList.length, 256 properties = this.model.get("dataProperties"), 257 sig = properties.searchResultsSignature, 258 hash = queryModel.parseHashParameters(window.location.hash), 259 param = sig !== "" ? sig + "_g" : "g"; 260 261 for (i = 0; i < poiCount; i++) { 262 poi = poiList[i]; 263 var zIndex = ''; 264 var poiIcon = poi.PoiIcon; 265 266 if (poi.Type === "MyLocation") { 267 myLocation = this.model.get("myLocation"); 268 poi.Latitude = myLocation[0]; 269 poi.Longitude = myLocation[1]; 270 271 if (!hash.hasOwnProperty(param) || (hash.hasOwnProperty(param) && hash[param] === "")) { 272 //if there is no "g" param then it's mean that there is no Location Filter on the map 273 //in this case we have take coordinated from the browser to display My Location POI 274 this.getCurrentPosition(function (coordinates) { 275 this.model.set("myLocation", coordinates); 276 }); 277 } else if (hash.hasOwnProperty(param)) { 278 this.model.set("myLocation", hash[param].split("|")); 279 } 280 } else if (poi.Latitude === "" || poi.Longitude === "") { 281 continue; 282 } 283 284 if (poiIcon !== null && poiIcon !== '') { 285 if (poiIcon.indexOf('Salon') !== -1) { 286 zIndex = 150; 287 } else { 288 zIndex = 100; 289 } 290 } 291 292 mapsConnector.renderPoi(mapId, { 293 id: poi.Id.Guid, 294 title: poi.Title, 295 description: poi.Description, 296 latitude: poi.Latitude, 297 longitude: poi.Longitude, 298 icon: poi.PoiIcon, 299 html: poi.Html, 300 type: poi.Type, 301 zIndex: zIndex 302 }); 303 } 304 }, 305 getPoiContent: function(poiId, poiTypeId, poiVariantId, renderPoiContentCallback) { 306 var properties = this.model.get("dataProperties"), 307 url = urlHelperModel.createGetPoiContentUrl({endpoint: properties.variantsEndpoint}, poiId, poiVariantId); 308 309 apiModel.getData({ 310 callback: renderPoiContentCallback, 311 url: url, 312 excludeSiteName: true 313 }); 314 }, 315 getGeoPoiContent: function (poiId, poiTypeId, poiVariantId, renderPoiContentCallback) { 316 console.log(this.model); 317 var myLocation = this.model.get("myLocation"), 318 latitude = myLocation[0], 319 longitude = myLocation[1], 320 properties = this.model.get("dataProperties"), 321 hash = queryModel.parseHashParameters(window.location.hash), 322 units = hash.o, 323 url = urlHelperModel.createGetGeoPoiContentUrl({ endpoint: properties.variantsEndpoint }, poiId, poiVariantId, latitude + "," + longitude, units, properties.itemId); 324 325 apiModel.getData({ 326 callback: renderPoiContentCallback, 327 url: url, 328 excludeSiteName: true 329 }); 330 331 }, 332 getCentralPoint: function (callback) { 333 var properties = this.model.get("dataProperties"), 334 that = this; 335 336 switch (properties.centralPointMode) { 337 case "Auto": { 338 if (properties.centralPoint !== "") { 339 callback.call(that, [properties.latitude, properties.longitude]); 340 } else if (properties.pois.length > 0) { 341 callback.call(that, [properties.pois[0].Latitude, properties.pois[0].Longitude]); 342 } else { 343 this.getCurrentPosition(callback); 344 } 345 break; 346 } 347 case "MidOfPoi": { 348 callback.call(that, this.getPoisCentralPoint()); 349 break; 350 } 351 case "Location":{ 352 this.getCurrentPosition(callback); 353 break; 354 } 355 } 356 }, 357 getCurrentPosition: function (callback) { 358 var that = this; 359 XA.component.locationService.detectLocation( 360 function (location) { 361 callback.call(that, location, that); 362 }, 363 function (errorMessage) { 364 callback.call(that, [0, 0], that); 365 console.log(errorMessage); 366 } 367 ); 368 }, 369 getPoisCentralPoint: function () { 370 var i, 371 poi, 372 poisCoords = [], 373 myLocation = this.model.get("myLocation"), 374 properties = this.model.get("dataProperties"), 375 count = properties.pois.length; 376 377 for (i = 0; i < count; i++) { 378 poi = properties.pois[i]; 379 if (poi.TemplateId.Guid === "7dd9ece5-9461-498d-8721-7cbea8111b5e") { 380 if (myLocation[0] !== "" && myLocation[1] !== "") { 381 poi.Latitude = myLocation[0]; 382 poi.Longitude = myLocation[1]; 383 this.model.set("dataProperties", properties); 384 poisCoords.push({latitude: poi.Latitude, longitude: poi.Longitude}); 385 } 386 } else { 387 poisCoords.push({latitude: poi.Latitude, longitude: poi.Longitude}); 388 } 389 } 390 391 return mapsConnector.getCentralPoint(poisCoords);
392 }, 393 handleCenterMap: function (data) { 394 var centerMap = this.model.get("dataProperties").centerOnFoundPoi === "1", 395 animate = this.model.get("dataProperties").animateFoundPoi === "1"; 396 this.centerOnMap(data, centerMap, animate); 397 }, 398 centerOnMap: function (data, centerMap, animate) { 399 if (data.sig === this.model.get("dataProperties").searchResultsSignature) { 400 mapsConnector.centerMap(this.model.get("id"), data, centerMap, animate); 401 } 402 }, 403 updateMyLocationPoi: function () { 404 var properties = this.model.get("dataProperties"), 405 myLocation = this.model.get("myLocation"); 406 407 //check if there is something in my location 408 if (myLocation[0] !== "" && myLocation[1] !== 0) { 409 //my location was changed so update position of My Location marker 410 mapsConnector.updateMyPoiLocation(this.model.get("id"), myLocation, this.parseZoom(properties.zoom, 15)); 411 } else if (properties.latitude !== "" && properties.longitude !== "") { 412 var data = {}; 413 data.sig = properties.searchResultsSignature; 414 data.coordinates = [properties.latitude, properties.longitude]; 415 this.centerOnMap(data, true, false); 416 } 417 }, 418 parseZoom: function (str, defaultValue) { 419 var retValue = defaultValue; 420 if(str !== null) { 421 if(str.length > 0) { 422 if (!isNaN(str)) { 423 retValue = parseInt(str); 424 } 425 } 426 } 427 return retValue; 428 } 429 }); 430 431 api.init = function() { 432 var i, 433 mapElements = $(".map.component:not(.initialized)"), 434 count = mapElements.length; 435 436 if (typeof (XA.component.search) !== "undefined") { 437 queryModel = XA.component.search.query; 438 urlHelperModel = XA.component.search.url; 439 apiModel = XA.component.search.ajax; 440 441 //if the page was reloaded there could be situation that search results will load results faster then map initialization 442 //so that we have to save them and pass to the models when they will be created 443 XA.component.search.vent.on("results-loaded", resultsLoaded); 444 //the same with "my location", sometimes Location Filter component can change location before map was initialized 445 XA.component.search.vent.on("my-location-coordinates-changed", myLocationChanged); 446 } 447 mapsConnector = XA.connector.mapsConnector; 448 449 if (count > 0) { 450 for (i = 0; i < count; i++) { 451 var $map = $(mapElements[i]); 452 var properties = $map.data("properties"); 453 key = properties.key; 454 searchEndpoint = properties.endpoint; 455 if (properties.pois.length > 0 && properties.searchResultsSignature !== "") { 456 searchResultsSignatures.push(properties.searchResultsSignature); 457 } 458 $map.addClass("initialized"); 459 maps.push($map); 460 } 461 462 if (!scriptsLoaded) { 463 mapsConnector.loadScript(key, XA.component.map.scriptsLoaded); 464 } else { 465 initialize(); 466 } 467 } 468 }; 469 470 api.scriptsLoaded = function() { 471 scriptsLoaded = true; 472 initialize(); 473 }; 474 475 api.getSearchEndpoint = function() { 476 return searchEndpoint; 477 }; 478 479 api.getSignatures = function() { 480 return searchResultsSignatures; 481 } 482 483 return api; 484 485}(jQuery, document)); 486 487XA.register("map", XA.component.map);
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.