1/*global L, define */ 2// (function (window, document, undefined) { 3// 'use strict'; 4 5 6// }(window, document)); 7/*global L */ 8(function (window, document, undefined) { 9 'use strict'; 10 /** 11 * SVG Icon 12 * @type {L.SVGIcon} 13 * @extends {L.Icon} 14 */ 15 L.SVGIcon = L.Icon.extend({ 16 options: { 17 /** @var {L.Point} */ 18 iconSize: [24, 24], 19 /** @var {L.Point} */ 20 iconAnchor: [12, 12], 21 /** @var {Function} */ 22 drawIcon: null, 23 /** @var {string} */ 24 className: 'leaflet-svg-icon' 25 }, 26 27 /** 28 * @param {HTMLElement} icon 29 * @returns {HTMLSVGElement} 30 */ 31 createIcon: function (icon) { 32 var size = L.point(this.options.iconSize); 33 34 if (!icon || (icon.tagName != 'SVG')) { 35 icon = document.createElement('div'); 36 } 37 38 // icon.width = size.x; 39 // icon.height = size.y; 40 41 this._setIconStyles(icon, 'svg'); 42 43 return icon; 44 }, 45 46 /** 47 * @param {HTMLElement} icon 48 * @returns {null} 49 */ 50 createShadow: function (icon) { 51 return null; 52 }, 53 54 /** 55 * @param {HTMLElement} icon 56 * @param {string} type 57 * @private 58 */ 59 _setIconStyles: function (icon, type) { 60 if (typeof this.options.drawIcon == 'function') { 61 this.options.drawIcon.apply(this, arguments); 62 } 63 L.Icon.prototype._setIconStyles.apply(this, arguments); 64 var size = L.point(this.options.iconSize); 65 var anchor = size.divideBy(2); 66 icon.style.marginLeft = (-anchor.x)+"px"; 67 icon.style.marginTop = (-size.y)+"px"; 68 } 69 }); 70 71 /** 72 * SVG Icon factory 73 * @param {Object} options 74 * @returns {L.SVGIcon} 75 */ 76 L.svgIcon = function (options) { 77 return new L.SVGIcon(options); 78 }; 79 80 /** 81 * AMD compatibility 82 */ 83 if ((typeof define == 'function') && define.amd) { 84 define(L.SVGIcon); 85 } 86 /** 87 * Piechart Icon 88 * @type {L.D3Icon} 89 * @extends {L.SVGIcon} 90 */ 91 L.D3Icon = L.SVGIcon.extend({ 92 options: { 93 iconSize: [48, 48], 94 iconAnchor: [24, 24], 95 popupAnchor: [24, 24], 96 className: 'leaflet-piechart-icon', 97 type: 'pie' 98 }, 99 100 /** 101 * @param {HTMLSVGElement} icon 102 * @param {string} type 103 */ 104 _setIconStyles: function (icon, type) { 105 var data = this.options.data; 106 var label = this.options.label; 107 var legendeActivated = this.options.legendeActivated; 108 var container = typeof this.options.container !== 'undefined' ? this.options.container : "#graphD3"; 109 // set the color scale 110 var color = d3.scaleOrdinal() 111 .domain(this.options.legende) 112 .range(d3.schemeTableau10); 113 114 var Tooltip = $(container).find(".tooltip-wrapper"); 115 116 var mouseover = function(event, d) { 117 d = typeof d.data !== "undefined" ? d.data : d; 118 Tooltip 119 .css({ 120 "opacity":1, 121 "z-index":9999, 122 "left": $(this).offset().left+ 'px', 123 "top": $(this).offset().top - $(container).offset().top + 'px'}) 124 Tooltip.find("p") 125 .html("Il y a "+d[1]+" organisation"+(d[1] > 1 ? "s" : "")+" de <span class='tooltip-label'>"+label+" "+d[0]+"</span>"); 126 d3.select(this) 127 .style("stroke", "black") 128 } 129 130 var mousemove = function(event, d) { 131 // .style("left", (d3.mouse(this)[0]+70) + "px") 132 // .style("top", (d3.mouse(this)[1]) + "px") 133 } 134 if ((type == 'svg') && data ) { 135 data = Object.fromEntries(Object.entries(data).filter(([key]) => legendeActivated.includes(key))) 136 if(this.options.type == 'donut') { 137 138 var total = this._getTotal(data); 139 var size = L.point(this.options.iconSize); 140 var center = size.divideBy(2); 141 142 // The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin. 143 var radius = Math.min(center.x, center.y) - 2; 144 // append the svg object to the div called 'my_dataviz' 145 var svg = d3.select(icon) 146 .attr('style', "position:absolute") 147 .append("svg") 148 .attr("width", size.x) 149 .attr("height", size.y) 150 .append("g") 151 .attr("transform", "translate(" + center.x+ "," + center.y+ ")"); 152 153 // Compute the position of each group on the pie: 154 const pie = d3.pie() 155 .value(function(d) {return d[1]}) 156 const data_ready = pie(Object.entries(data)) 157 // Now I know that group A goes from 0 degrees to x degrees and s
157o on. 158 159 // shape helper to build arcs: 160 var arcGenerator = d3.arc() 161 .innerRadius(radius * 0.5) 162 .outerRadius(radius) 163 // Build the pie chart: Basically, each part of the pie is a path that we build using the arc function. 164 165 166 var mouseleave = function(event, d) { 167 Tooltip 168 .css({"opacity":0,"z-index": -999999}) 169 } 170 svg 171 .selectAll('mySlices') 172 .data(data_ready) 173 .join('path') 174 .attr('d', arcGenerator) 175 .attr('fill', function(d){ return(color(d.data[0] == '' ? "Autre" : d.data[0])) }) 176 .attr("stroke", "black") 177 .style('pointer-events', 'inherit') 178 .style("stroke-width", "2px") 179 .style("opacity", 0.75) 180 .on('mouseover', mouseover) // NEW 181 .on('mouseleave', mouseleave) 182 } 183 else if(this.options.type == 'pie') { 184 185 var total = this._getTotal(data); 186 var size = L.point(this.options.iconSize); 187 var center = size.divideBy(2); 188 189 // The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin. 190 var radius = Math.min(center.x, center.y) - 2; 191 // append the svg object to the div called 'my_dataviz' 192 var svg = d3.select(icon) 193 .attr('style', "position:absolute") 194 .append("svg") 195 .attr("width", size.x) 196 .attr("height", size.y) 197 .append("g") 198 .attr("transform", "translate(" + center.x+ "," + center.y+ ")"); 199 200 201 var mouseleave = function(event, d) { 202 Tooltip 203 .css({"opacity":0,"z-index": -999999}) 204 } 205 // Compute the position of each group on the pie: 206 const pie = d3.pie() 207 .value(function(d) {return d[1]}) 208 const data_ready = pie(Object.entries(data)) 209 // Now I know that group A goes from 0 degrees to x degrees and so on. 210 211 // shape helper to build arcs: 212 var arcGenerator = d3.arc() 213 .innerRadius(0) 214 .outerRadius(radius) 215 216 // Build the pie chart: Basically, each part of the pie is a path that we build using the arc function. 217 var path = svg 218 .selectAll('path') 219 .data(data_ready) 220 .join('path') 221 .attr('d', arcGenerator) 222 .attr('fill', function(d){ return(color(d.data[0] == '' ? "Autre" : d.data[0])) }) 223 .attr("stroke", "black") 224 .style('pointer-events', 'inherit') 225 .style("stroke-width", "1px") 226 .style("opacity", 0.75) 227 // .on("mouseover", function (event, d) { 228 // alert("data from event"+event.target) 229 // }) 230 // .append("title") 231 // .text(d => d.data[0]+" : " + d.data[1]); 232 path.on('mouseover', mouseover); // NEW 233 path.on('mouseleave', mouseleave); 234 svg 235 .selectAll('mySlices') 236 .data(data_ready) 237 .join('text') 238 .text(function(d){return (d.data[1]).toFixed(0)}) 239 .attr("transform", function(d) { return `translate(${arcGenerator.centroid(d)})`}) 240 .style("text-anchor", "middle") 241 .style("font-size", 10) 242 .style("color", function(d){ return(color(d.data[0] == '' ? "Autre" : d.data[0]))})
243 // .on("mouseover", mouseover) 244 // .on("mousemove", mousemove) 245 // .on("mouseleave", mouseleave) 246 } 247 else if(this.options.type == 'bar') { 248 var size = L.point(this.options.iconSize); 249 var center = size.divideBy(2); 250 251 // The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin. 252 var radius = Math.min(center.x, center.y) - 2; 253 // append the svg object to the div called 'my_dataviz' 254 var svg = d3.select(icon) 255 .attr('style', "position:absolute") 256 .append("svg") 257 .attr("width", size.x) 258 .attr("height", size.y) 259 .append("g") 260 .attr("transform", 261 "translate(-5,0)"); 262 263 264 var mouseleave = function(event, d) { 265 Tooltip 266 .css({"opacity":0,"z-index": -999999}) 267 d3.select(this) 268 .style("stroke", "none") 269 } 270 // Add Y axis 271 const x = d3.scaleBand() 272 .range([ 0, size.x ]) 273 .domain(Object.keys(data)) 274 .padding(0.2); 275 svg.append("g") 276 .attr("transform", `translate(0,${size.y})`) 277 .call(d3.axisBottom(x)) 278 // Add Y axis 279 const y = d3.scaleLinear() 280 .domain([0, Math.max(...Object.values(data))]) 281 .range([ size.y, 0]); 282 svg.append("g") 283 .attr("class", "myYaxis") 284 .call(d3.axisLeft(y)); 285 var u = svg.selectAll("rect") 286 .data(Object.entries(data)); 287 u 288 .join("rect") 289 .on("mouseover", mouseover) 290 .on("mousemove", mousemove) 291 .on("mouseleave", mouseleave) 292 .transition() 293 .duration(1000) 294 .attr("x", d => x(d[0])) 295 .attr("y", d => y(d[1])) 296 .attr("width", x.bandwidth()) 297 .attr("height", d => size.y - y(d[1])) 298 .attr("fill", function(d){ return(color(d[0])) }) 299 } 300 } 301 302 L.SVGIcon.prototype._setIconStyles.apply(this, arguments); 303 }, 304 305 /** 306 * @param {Object[]} data Array of objects 307 * @param {string} field Field to summarize 308 * @returns {number} 309 * @private 310 */ 311 _getTotal: function (data) { 312 var total = 0; 313 for(const [key, value] of Object.entries(data)) { 314 total += value; 315 } 316 return total; 317 }, 318 }); 319 320 /** 321 * Pie char Icon factory 322 * @param {Object} options 323 * @returns {L.D3Icon} 324 */ 325 L.d3Icon = function (options) { 326 return new L.D3Icon(options); 327 }; 328 329 /** 330 * Pie chart Marker 331 * @type {L.Marker} 332 */ 333 L.D3Marker = L.Marker.extend({ 334 options: { 335 type: 'pie', 336 icon: null, 337 radius: 20, 338 riseOnHover: true 339 }, 340 341 initialize: function (latlng, options) { 342 var opts = {}; 343 L.Util.extend(opts, options); 344 if (opts.radius) { 345 var diameter = opts.radius * 2; 346 opts.iconSize = [diameter, diameter]; 347 opts.iconAnchor = [opts.radius, opts.radius]; 348 } 349 opts.icon = L.d3Icon(opts); 350 L.Marker.prototype.initialize.apply(this, [latlng, opts]); 351 } 352 }); 353 354 /** 355 * Pie chart Marker factory 356 * @param {L.LatLng} latlng 357 * @param {Object} options 358 * @returns {L.D3Marker} 359 */ 360 L.d3Marker = function (latlng, options) { 361 return new L.D3Marker(latlng, options); 362 } 363}(window, document)); 364 365var unique = function(array) { 366 var a = array; 367 for(var i=0; i<a.length; ++i) { 368 for(var j=i+1; j<a.length; ++j) { 369 if(a[i] === a[j]) 370 a.splice(j--, 1); 371 } 372 } 373 374 return a; 375}; 376 377function MapD3(options=null){ 378 /* private properties ==========> */ 379 var _context = this; 380 var _map = null; 381 var _options = { 382 parentContainer: '#mapContainer', 383 parentContainerName: 'mapContainer', 384 container: '#mapContainerMap', 385 hideContainer: 'search-content', 386 data: {}, 387 colors: d3.scaleOrdinal() 388 .range(d3.schemeTableau10), 389 arrayBounds: [], 390 bounds: null, 391 legende: [], 392 legendeActivated: [], 393 lastLegende: [], 394 legendeVar: "tags",
395 legendeLabel: "type", 396 clickedLegende: "", 397 showLegende: true, 398 dynamicLegende: true, 399 groupBy: "type", 400 markerType: 'default', 401 markersCluster: null, 402 geoJSONlayer: null, 403 markerList: {}, 404 clusterType: 'pie', 405 activeCluster: true, 406 activePopUp: false, 407 activePreview: false, 408 listItem: true, 409 distanceToMax: 0, 410 elts:null, 411 mapOpt:{ 412 dragging: true, 413 draggable: false, 414 center: [0, 0], 415 centerOneZoom:18, 416 zoom: 10, 417 offset: { 418 x: 0, 419 y: 0 420 }, 421 menuRight: null, 422 btnHide: false, 423 minZoom: 0, 424 maxZoom: 18, 425 mouseOver : false, 426 doubleClick : false, 427 onclickMarker: null, 428 }, 429 mapCustom:{ 430 tile:"mapnik", 431 css:[], 432 icons: { 433 pie: modules.map.assets + '/images/icons/pie.png', 434 bar: modules.map.assets + '/images/icons/bar.png', 435 donut: modules.map.assets + '/images/icons/donut.png', 436 heatmap: modules.map.assets + '/images/icons/heatmap.png' 437 }, 438 markers: { 439 default: modules.map.assets + '/images/markers/citizen-marker-default.png', 440 organization: modules.map.assets + '/images/markers/ngo-marker-default.png', 441 classified: modules.map.assets + '/images/markers/classified-marker-default.png', 442 proposal: modules.map.assets + '/images/markers/proposal-marker-default.png', 443 poi: modules.map.assets + '/images/markers/poi-marker-default.png', 444 project: modules.map.assets + '/images/markers/project-marker-default.png', 445 event: modules.map.assets + '/images/markers/event-marker-default.png', 446 answer: modules.map.assets + '/images/markers/services/tools-hardware.png', 447 getMarker: function(data){ 448 var markers = _options.mapCustom.markers; 449 var collectionGroups = { 450 organization: ["organization", "organizations", "NGO", "Cooperative"], 451 classified: ["classified", "classifieds"], 452 proposal: ["proposal", "proposals"], 453 poi: ["poi"], 454 project: ["project", "projects"], 455 event: ["event", "events"], 456 answer: ["answers"] 457 } 458 var marker = markers.default; 459 460 if(data){ 461 if(data.profilMarkerImageUrl) 462 marker = data.profilMarkerImageUrl; 463 else if(data.collection){ 464 $.each(collectionGroups, function(k, v){ 465 if(v.indexOf(data.collection) > -1){ 466 marker = markers[k] 467 } 468 }) 469 } 470 } 471 472 return marker; 473 } 474 }, 475 icon:{ 476 options:{ 477 iconSize: [45, 55], 478 iconAnchor: [25, 45], 479 popupAnchor: [-3, -30] 480 }, 481 getIcon:function(params){ 482 if(_options.markerType == "default"){ 483 var iconOptions = _options.mapCustom.icon.options; 484 iconOptions.data = params.elt; 485 iconOptions.iconUrl = _options.mapCustom.markers.getMarker(params.elt); 486 return L.icon(iconOptions); 487 }else{ 488 var iconOptions = _options.mapCustom.icon.options; 489 iconOptions.data = params.elt; 490 iconOptions.type = _options.markerType; 491 iconOptions.legende = params.legende; 492 iconOptions.legendeActivated = params.legendeActivated;
493 iconOptions.label = _options.legendeLabel; 494 // iconOptions.iconUrl = _options.mapCustom.markers.getMarker(params.elt); 495 return L.d3Icon(iconOptions); 496 } 497 } 498 }, 499 lists: { 500 text:"", 501 createItemList: function(kElt, element, container){ 502 if(element.type && $.inArray(element.type, _filtres.types) == -1){ 503 _filtres.types.push(element.type) 504 var valueIdType = element.type.replace(/[^A-Za-z0-9]/g, ""); 505 if (!$('#item_panel_map_' + valueIdType).length){ 506 var newItem = "<button class='item_panel_map' id='item_panel_map_" + valueIdType + "'>" + 507 "<i class='fa fa-tag' ></i> " + element.type + 508 "</button>"; 509 $(_options.parentContainer +' .panel_filter').append(newItem); 510 511 $("#item_panel_map_" + valueIdType).click(function(){ 512 $(".item_panel_map").removeClass("active"); 513 $("#item_panel_map_" + valueIdType).addClass("active"); 514 _filtres.typesActived = [] 515 if($.inArray(valueIdType, _filtres.typesActived) == -1){ 516 _filtres.typesActived.push(valueIdType) 517 } 518 _context.clearMap() 519 _context.addElts(_options.data) 520 }) 521 } 522 } 523 //prépare le nom (ou "anonyme") 524 var name = (element.name)?element.name:(element.title?element.title:"Anonyme") 525 //recuperation de l'image de profil (ou image par defaut) 526 var imgProfilPath = _options.mapCustom.getThumbProfil(element) 527 var button = '<div class="element-right-list" id="element-right-list-' + kElt + '">' + 528 '<button class="item_map_list item_map_list_' + kElt + '">' + 529 "<div class='left-col'>" + 530 "<div class='thumbnail-profil'><img class='lzy_img' height=50 width=50 src='" + modules.co2.url +"/images/thumbnail-default.jpg' data-src='" + imgProfilPath + "'></div>" + 531 "</div>" + 532 "<div class='right-col'>" + 533 "<div class='info_item pseudo_item_map_list'>" + name + "</div>"; 534 if(element.tags){ 535 button += "<div class='info_item items_map_list'>"; 536 var totalTags = 0; 537 $.each(element.tags, function(index, value){ 538 totalTags++; 539 if(totalTags < 4){ 540 var t = tradCategory[value]?tradCategory[value]:value; 541 button += "<a href='javascript:' class='tag_item_map_list'>#" + t + " </a>"; 542 } 543 var valueId = value.replace(/[^A-Za-z0-9]/g, ""); 544 //si l'item n'existe pas deja 545 if (!$('#item_panel_map_' + valueId).length){ 546 var newItem = "<button class='item_panel_map' id='item_panel_map_" + valueId + "'>" + 547 "<i class='fa fa-tag' ></i> " + value + 548 "</button>"; 549 $(_options.parentContainer + ' .panel_map2').append(newItem); 550 551 $("#item_panel_map_"+valueId).click(function(){ 552 $(".item_panel_map").removeClass("active"); 553 $("#item_panel_map_" + valueId).addClass("active"); 554 555 _filtres.tagsActived = []; 556 if($.inArray(value, _filtres.tagsActived) == -1){ 557 _filtres.tagsActived.push(value) 558 } 559 _context.clearMap() 560 _context.addElts(_options.data) 561 }) 562 } 563 if($.inArray(value, _filtres.tags) == -1) 564 _filtres.tags.push(value) 565 }) 566 button += "</div>"; 567 } 568 569 if(element.address){ 570 button += "<div class='info_item city_item_map_list inline'>"; 571 if(element.address.addressLocality){ 572 button += element.address.addressLocality + " " 573 } 574 if(element.address.postalCode){ 575 button += element.address.postalCode + " " 576 } 577 if(element.address.addressCountry){ 578 button += element.address.addressCountry + " " 579 } 580 button += "</div>"; 581 } 582 button += "</div>"; 583 584 if(element.type == "event" || element.type == "events"){ 585 button += displayStartAndEndDate(element); 586 } 587 button += '<div class="col-xs-12 separation"></div>' + 588 '</button>' + 589 '</div>'; 590 $(_options.parentContainer + " .liste_map_element").append(button) 591 592 $(_options.parentContainer + " .item_map_list_" + kElt).click(function(){ 593 if(element.geo && element.geo.latitude && element.geo.longitude){ 594 var m = _options.markerList[kElt] 595 _options.markersCluster.zoomToShowLayer(m, function(){ 596 m.openPopup()
597 coInterface.bindLBHLinks(); 598 }) 599 }else{ 600 $(_options.parentContainer + " .modalItemNotLocated").modal('show'); 601 $(_options.parentContainer + " .modalItemNotLocated .modal-body").html("<i class='fa fa-spin fa-reload'></i>"); 602 $(_options.parentContainer + " .modalItemNotLocated .modal-body").html(_options.mapCustom.getPopup(element)) 603 $(_options.parentContainer + " .modalItemNotLocated #btn-open-details").click(function(){ 604 $("#popup" + kElt).click(); 605 if(networkJson && networkJson.dataSrc){ 606 urlCtrl.loadByHash("'+url+'"); 607 } 608 }) 609 610 $(_options.parentContainer + " .modalItemNotLocated #popup" + kElt).click(function(){ 611 $(_options.parentContainer + " .modalItemNotLocated").modal('hide') 612 }) 613 } 614 }) 615 } 616 }, 617 transformData: function(allData, type) { 618 if(_options.dynamicLegende == "false" || _options.dynamicLegende == false){ 619 if(type.data){ 620 for (const [key, legende] of Object.entries(_options.legende)) { 621 if(type[_options.legendeVar].includes(legende)){ 622 allData[legende] = allData[legende] || 0; 623 allData[legende] += type.data[legende]; 624 } 625 } 626 }else{ 627 var existe = false; 628 if(typeof type[_options.legendeVar] != "undefined"){ 629 if(type[_options.legendeVar] instanceof Array || type[_options.legendeVar] instanceof Object){ 630 for (const [key, legende] of Object.entries(_options.legende)) { 631 if(type[_options.legendeVar].includes(legende) && legende != "Autre"){ 632 allData[legende] = allData[legende] || 0; 633 allData[legende] += 1; 634 existe = true; 635 } 636 if(key == _options.legende.length - 1){ 637 if(!existe){ 638 allData["Autre"] = allData["Autre"] || 0; 639 allData["Autre"] += 1; 640 } 641 } 642 } 643 } 644 645 }else{ 646 allData["Autre"] = allData["Autre"] || 0; 647 allData["Autre"] += 1; 648 } 649 } 650 }else if(type.data){ 651 for (const [key, value] of Object.entries(type.data)) { 652 allData[key] = allData[key] || 0; 653 allData[key] += value; 654 } 655 }else { 656 if(type[_options.groupBy] && type[_options.groupBy] != ""){ 657 allData[type[_options.groupBy]] = allData[type[_options.groupBy]] || 0; 658 allData[type[_options.groupBy]] += 1; 659 }else{ 660 allData["Autre"] = allData["Autre"] || 0; 661 allData["Autre"] += 1; 662 } 663 } 664 return allData; 665 }, 666 getData: function(allData, cluster){ 667 if(cluster._markers){ 668 cluster._markers.forEach(element => { 669 if(_options.mapCustom.transformDataCustom){ 670 allData = _options.mapCustom.transformDataCustom(allData, element.options.icon.options.data, _context) 671 }else{ 672 allData = _options.mapCustom.transformData(allData, element.options.icon.options.data) 673 } 674 }); 675 676 } 677 if(cluster._childClusters.length > 0){
678 cluster._childClusters.forEach(clusterChild => { 679 _options.mapCustom.getData(allData, clusterChild); 680 }) 681 } 682 }, 683 getClusterIcon: function(cluster){ 684 var lastdata = []; 685 var width = 76; 686 _options.mapCustom.getData(lastdata,cluster); 687 if(_options.clickedLegende.length < 1){ 688 return L.d3Icon({type: _options.clusterType, legende: _options.legende,label: _options.legendeLabel, legendeActivated: _options.legendeActivated, data: lastdata, iconSize: [width, width]}); 689 }else{ 690 if(typeof paramsMapCO.mapCustom.getClusterIcon(cluster) != "undefined") 691 return paramsMapCO.mapCustom.getClusterIcon(cluster); 692 var childCount = cluster.getChildCount(); 693 var c = ' marker-cluster-'; 694 if (childCount < 10) { 695 c += 'small'; 696 } else if (childCount < 100) { 697 c += 'medium'; 698 } else { 699 c += 'large'; 700 } 701 return L.divIcon({ html: '<div>' + childCount + '</div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) }); 702 703 } 704 }, 705 getThumbProfil: function (data) { 706 var imgProfilPath = modules.map.assets + "/images/thumb/default.png"; 707 if (typeof data.profilThumbImageUrl !== "undefined" && data.profilThumbImageUrl != "") 708 imgProfilPath = baseUrl + data.profilThumbImageUrl; 709 else 710 imgProfilPath = modules.map.assets + "/images/thumb/default_" + data.collection + ".png"; 711 712 return imgProfilPath; 713 }, 714 getPopup: function(data){ 715 var id = data._id ? data._id.$id:data.id; 716 var imgProfil = _options.mapCustom.getThumbProfil(data) 717 718 var eltName = data.title ? data.title: ((typeof data.properties != "undefined" && typeof data.properties.name != "undefined") ? data.properties.name : data.name); 719 var popup = ""; 720 popup += "<div class='padding-5' id='popup" + id + "'>"; 721 popup += "<img src='" + imgProfil + "' height='30' width='30' class='' style='display: inline; vertical-align: middle; border-radius:100%;'>"; 722 popup += "<span style='margin-left : 5px; font-size:18px'>" + eltName + "</span>"; 723 724 if(data.tags && data.tags.length > 0){ 725 popup += "<div style='margin-top : 5px;'>"; 726 var totalTags = 0; 727 $.each(data.tags, function(index, value){ 728 totalTags++; 729 if (totalTags < 3) { 730 popup += "<div class='popup-tags'>#" + value + " </div>"; 731 } 732 }) 733 popup += "</div>"; 734 } 735 if(data.address){ 736 var addressStr=""; 737 if(data.address.streetAddress) 738 addressStr += data.address.streetAddress; 739 if(data.address.postalCode) 740 addressStr += ((addressStr != "")?", ":"") + data.address.postalCode; 741 if(data.address.addressLocality) 742 addressStr += ((addressStr != "")?", ":"") + data.address.addressLocality; 743 popup += "<div class='popup-address text-dark'>"; 744 popup += "<i class='fa fa-map-marker'></i> "+addressStr; 745 popup += "</div>"; 746 } 747 if(data.shortDescription && data.shortDescription != ""){ 748 popup += "<div class='popup-section'>"; 749 popup += "<div class='popup-subtitle'>Description</div>"; 750 popup += "<div class='popup-shortDescription'>" + data.shortDescription + "</div>"; 751 popup += "</div>"; 752 } 753 if((data.url && typeof data.url == "string") ||Â data.email || data.telep
753hone){ 754 popup += "<div id='pop-contacts' class='popup-section'>"; 755 popup += "<div class='popup-subtitle'>Contacts</div>"; 756 757 if(data.url && typeof data.url === "string"){ 758 popup += "<div class='popup-info-profil'>"; 759 popup += "<i class='fa fa fa-desktop fa_url'></i> "; 760 popup += "<a href='" + data.url + "' target='_blank'>" + data.url + "</a>"; 761 popup += "</div>"; 762 } 763 764 if(data.email){ 765 popup += "<div class='popup-info-profil'>"; 766 popup += "<i class='fa fa-envelope fa_email'></i> " + data.email; 767 popup += "</div>"; 768 } 769 770 if(data.telephone){ 771 popup += "<div class='popup-info-profil'>"; 772 popup += "<i class='fa fa-phone fa_phone'></i> "; 773 var tel = ["fixe", "mobile"]; 774 var iT = 0; 775 $.each(tel, function(keyT, valT){ 776 if(data.telephone[valT]){ 777 $.each(data.telephone[valT], function(keyN, valN){ 778 if(iT > 0) 779 popup += ", "; 780 popup += valN; 781 iT++; 782 }) 783 } 784 }) 785 popup += "</div>"; 786 } 787 788 popup += "</div>"; 789 popup += "</div>"; 790 } 791 if(data.collection && id){ 792 var url = '#page.type.' + data.collection + '.id.' + id; 793 popup += "<div class='popup-section'>"; 794 if(_options.activePreview) 795 popup += "<a href='" + url + "' class='lbh-preview-element item_map_list popup-marker' id='popup" + id + "'>"; 796 else 797 popup += "<a href='" + url + "' target='_blank' class='lbh item_map_list popup-marker' id='popup" + id + "'>"; 798 popup += '<div class="btn btn-sm btn-more col-md-12">'; 799 popup += '<i class="fa fa-hand-pointer-o"></i>' + trad.knowmore; 800 popup += '</div></a>'; 801 } 802 popup += '</div>'; 803 popup += '</div>'; 804 805 return popup; 806 }, 807 addMarker:null, 808 addElts:null, 809 transformDataCustom : null 810 }, 811 buttons:{ 812 fullScreen:{ 813 allow:false, 814 position: "bottomLeft", 815 icon:{ 816 maximize: 'expand', 817 minimize: 'compress' 818 }, 819 style:{ 820 default:{ 821 border: "none", 822 borderRadius: "100%", 823 width: "40px", 824 height: "40px", 825 background: "rgba(255,255,255,.5)", 826 outline:"none" 827 }, 828 onHover:{ 829 background: "rgba(255,255,255,1)" 830 } 831 } 832 } 833 }, 834 actionButtons:[] 835 } 836 var _utils = { 837 bindMap: function(){ 838 $(_options.parentContainer + " .input_name_filter").keyup(function(){ 839 if (notNull(_filtres.timeoutAddCity)) 840 clearTimeout(_filtres.timeoutAddCity); 841 842 _filtres.timeoutAddCity = setTimeout(function () { 843 _filtres.search = $(_options.parentContainer + " .input_name_filter").val(); 844 _context.clearMap(); 845 _context.addElts(_options.data); 846 }, 500); 847 }) 848 849 $(_options.parentContainer + " .item_panel_filter_all").off().click(function(){ 850 $(_options.parentContainer + " .item_panel_map").removeClass("active"); 851 $(_options.parentContainer + " .item_panel_filter_all").addClass("active"); 852 _filtres.typesActived = []; 853 _context.clearMap(); 854 _context.addElts(_options.data) 855 }) 856 857 $(_options.parentContainer + " .item_panel_map_all").off().click(function(){ 858 _filtres.tagsActived = []; 859 $(_options.parentContainer + " .item_panel_map").removeClass("active") 860 $(_options.parentContainer + " .item_panel_map_all").addClass("active") 861 _context.clearMap(); 862 _context.addElts(_options.data) 863 }) 864 865 $(_options.parentContainer + " .btn-hide-map").off().click(function(){ 866 showMap(false); 867 }) 868 869 $(_options.parentContainer + " #btn-close-menuRight").off().click(function(){ 870 if(!$(this).data("close")){ 871 $("#menuRight"+ _options.parentContainerName).hide(); 872 $(this).html('<i class="fa fa-angle-left"></i>'); 873 $(_options.parentContainer + " .closeMenuRight").css('right', "0px"); 874 $(this).data("close", true); 875 }else{ 876 $("#menuRight"+ _options.parentContainerName).show(); 877 $(this).html('<i class="fa fa-angle-right"></i>'); 878 var right = "341px"; 879 if(_options.mapOpt.menuRight && _options.mapOpt.menuRight.btnClose && _options.mapOpt.btnClose.right){ 880 right = _options.mapOpt.btnClose.right; 881 } 882 $(_options.parentContainer + " .closeMenuRight").css('right', right); 883 $(this).data("close", false); 884 } 885 }) 886 }, 887 generateRandomId: function(){ 888 return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10); 889 } 890 } 891 var _filtres = { 892 types: [], 893 typesActived: [], 894 tags: [], 895 tagsActived: [], 896 search: "", 897 result: function(elt){ 898 var res = _filtres.isTags(elt) && _filtres.isSearch(elt) && _filtres.isType(elt) 899 return res; 900 }, 901 isTags: function(elt){ 902 var res = false;
903 if(Object.keys(_filtres.tagsActived).length == 0 || _filtres.tagsActived || _filtres.tagsActived.length == 0){ 904 res = true; 905 }else{ 906 $.each(_filtres.tagsActived, function(k, v){ 907 if(elt.tags && $.inArray(v, elt.tags) > -1) 908 res = true; 909 }) 910 } 911 return res; 912 }, 913 isType: function(elt){ 914 var res = false; 915 if(Object.keys(_filtres.typesActived).length == 0 || _filtres.typesActived || _filtres.typesActived.length == 0){ 916 res = true 917 }else{ 918 $.each(_filtres.typesActived, function(k, v){ 919 if(elt.type && v == elt.type) 920 res = true; 921 }) 922 } 923 return res; 924 }, 925 isSearch: function(elt){ 926 var res = false; 927 if(_filtres.search){ 928 if(elt.name && elt.name.search(new RegExp(_filtres.search, "i")) >= 0) 929 res = true; 930 }else{ 931 res = true 932 } 933 return res; 934 } 935 } 936 /* <========== private properties */ 937 938 /* private methodes ==========> */ 939 var initVar = function(){ 940 if(options){ 941 _options = $.extend(true, {}, _options, options) 942 943 _options.parentContainer = (options.container) ? options.container:"#mapContainer"; 944 _options.parentContainerName = _options.parentContainer.replace("#", "").replace(".","") 945 _options.container = _options.parentContainer + "Map"; 946 _options.geoJSONlayer = new L.LayerGroup(); 947 if(_options.activeCluster){ 948 _options.markersCluster = new L.markerClusterGroup({ 949 iconCreateFunction: function (cluster) { 950 return _options.mapCustom.getClusterIcon(cluster); 951 } 952 }) 953 } 954 } 955 } 956 957 var initView = function(){ 958 var view = ""; 959 960 view += "<div class='mapLoading'></div>"; 961 view += ` <div class="tooltip-wrapper"> 962 <div class="tooltip-content"> 963 <p></p> 964 </div> 965 </div>`; 966 if(_options.mapOpt.menuRight){ 967 var dataCloseMenuRight = false, 968 sizeList = $(_options.parentContainer).height() - 80; 969 970 if(_options.mapOpt.menuRight.btnClose){ 971 view += '<div class="closeMenuRight">'+ 972 '<button type="button" data-close="'+dataCloseMenuRight+'" class="btn btn-default " id="btn-close-menuRight" data-toggle="dropdown">' + 973 '<i class="fa fa-angle-right"></i>' + 974 '</button>' + 975 '</div>'; 976 } 977 978 view += '<div id="menuRight' + _options.parentContainerName + '" class="hidden-xs col-sm-3 no-padding menuRight" style="">' + 979 '<div id="menuRight_search' + _options.parentContainerName + '" class="col-sm-12 no-padding menuRight_search">' + 980 '<div class="menuRight_header col-sm-12 padding-10">' + 981 '<div class="col-xs-6">' + 982 '<span id="result' + _options.parentContainerName + '" class=""></span>' + 983 '<span class="menuRight_header_title"> '+tradMap.Results+' </span>' + 984 '</div>'; 985 986 if(_options.mapOpt.btnHide){ 987 view += '<div class="col-xs-2 pull-right">' + 988 '<button type="button" class="btn btnHeader dropdown-toggle btn-hide-map" data-toggle="dropdown">' + 989 '<i class="fa fa-times"></i>' + 990 '</button>' + 991 '</div>'; 992 } 993 view += '<div class="col-xs-2 pull-right">' + 994 '<button type="button" class="btn btnHeader dropdown-toggle" id="btn-filters' + _options.parentContainerName + '" data-toggle="dropdown">' + 995 '<i class="fa fa-filter"></i>' + 996 '</button>' + 997 '<ul class="dropdown-menu panel_filter panel_map" role="menu" aria-labelledby="panel_filter" style="overflow-y: auto; max-height: 400px;">' + 998 '<h3 class="title_panel_map"><i class="fa fa-angle-down"></i> '+tradMap['Filter results by types']+'</h3>' + 999 '<button class="item_panel_map active item_panel_filter_all" >' + 1000 '<i class="fa fa-star"></i> All' + 1001 '</button>' + 1002 '</ul>' + 1003 '</div>' + 1004 '<div class="col-xs-2 pull-right">' + 1005 '<button type="button" class="btn btnHeader dropdown-toggle" id="bt
1005n-panel' + _options.parentContainerName + '" data-toggle="dropdown">' + 1006 '<i class="fa fa-tags"></i>' + 1007 '</button>' + 1008 '<ul class="dropdown-menu panel_map panel_map2 pull-right" role="menu" aria-labelledby="panel_map" style="overflow-y: auto; max-height: 400px;">' + 1009 '<h3 class="title_panel_map"><i class="fa fa-angle-down"></i> '+tradMap['Filter results by tags']+'</h3>' + 1010 '<button class="item_panel_map active item_panel_map_all" >' + 1011 '<i class="fa fa-star"></i> All' + 1012 '</button>' + 1013 '</ul>' + 1014 '</div>' + 1015 '</div>' + 1016 1017 1018 '<div id="menuRight_search_filters' + _options.parentContainerName + '" class="col-sm-12 no-padding menuRight_search_filters">' + 1019 '<input class="form-control date-range active input_name_filter" type="text" placeholder="'+tradMap['Filter by names']+'">' + 1020 '</div>' + 1021 '<div class="menuRight_body col-sm-12 no-padding liste_map_element" ' + 1022 ' style="height: ' + sizeList + 'px;"></div>' + 1023 '</div>' + 1024 '</div>'; 1025 1026 view += '<div class="modal fade modalItemNotLocated" role="dialog">' + 1027 '<div class="modal-dialog">' + 1028 '<div class="modal-content" style="top: 125px;">' + 1029 '<div class="modal-header">' + 1030 '<button type="button" class="close" data-dismiss="modal">×</button>' + 1031 '<h4 class="modal-title text-dark">' + 1032 '<i class="fa fa-map-marker"></i>' + trad["This data is not geolocated"] + 1033 '</h4>' + 1034 '</div>' + 1035 '<div class="modal-body"></div>' + 1036 '<div class="modal-footer" style="border-top: none;">' + 1037 '<button type="button" class="btn btn-default btn-sm btn-danger" data-dismiss="modal"><i class="fa fa-times"></i>' + trad.closed + '</button>' + 1038 '</div>' + 1039 '</div>' + 1040 '</div>' + 1041 '</div>'; 1042 }else{ 1043 if (_options.mapOpt.btnHide) { 1044 view += '<div class="col-xs-2 div-btn-hide">' + 1045 '<button type="button" class="btn btnHeader dropdown-toggle btn-hide-map" id="" data-toggle="dropdown" style="background-color: #e6434d; color: white;">' + 1046 '<i class="fa fa-times"></i>' + 1047 '</button>' + 1048 '</div>'; 1049 } 1050 } 1051 // view += '<div id="' + _options.container + '" style="z-index: 1; width: 100%; position: fixed; bottom:0; top:inherit;"></div>'; 1052 view += '<div id="' + _options.container + '" style="z-index: 1; width: 100%; height: 100%; position:relative;"></div>'; 1053 1054 $(_options.parentContainer).html(view); 1055 1056 if(_options.mapOpt.menuRight && _options.mapOpt.menuRight.close){ 1057 $("#menuRight"+ _options.parentContainerName).hide(); 1058 $(_options.parentContainer + " #btn-close-menuRight").html('<i class="fa fa-angle-left"></i>'); 1059 $(_options.parentContainer + " .closeMenuRight").css('right', "0px"); 1060 $(_options.parentContainer + " #btn-close-menuRight").data("close", true); 1061 } 1062 1063 if(_options.buttons.fullScreen.allow) 1064 initBtnFullScreen(); 1065 1066 if(_options.actionButtons && Array.isArray(_options.actionButtons) && _options.actionButtons.length > 0){ 1067 initBtnActions() 1068 } 1069 } 1070 1071 var initBtnFullScreen = function(){ 1072 var optBtnFullScreen = _options.buttons.fullScreen, 1073 fullScreenActived = false, 1074 $parentContainer = $(_options.parentContainer), 1075 buttonContainerId = _options.parentContainerName + "-btn-fullscreen-container", 1076 defaultSizeParentContainer = { 1077 width: $parentContainer.width(), 1078 height: $parentContainer.height() 1079 } 1080 1081 var btnContainerPositionOptions = { 1082 topLeft: { left:0, top:0 }, 1083 bottomLeft: { left:0, bottom:0 }, 1084 topRight: { top:0, right:0 }, 1085 bottomRight: { bottom:0, right:0 }, 1086 default: { left:0, bottom:0 } 1087 } 1088 var btnContainerPosition = (btnContainerPositionOptions[optBtnFullScreen.position])? 1089 btnContainerPositionOptions[optBtnFullScreen.position]: 1090 btnContainerPositionOptions.default; 1091 var btnContainerStyle = { 1092 position:"absolute", 1093 zIndex: 100000, 1094 padding:"20px" 1095 } 1096 $.each(btnContainerPosition, function(property, value){ 1097 btnContainerStyle[property] = value; 1098 }) 1099 1100 var button = ` 1101 <div id="${buttonContainerId}"> 1102 <button><i class="fa fa-${optBtnFullScreen.icon.maximize}" aria-hidden="true"></i></button> 1103 </div> 1104 ` 1105 $parentContainer.append(button) 1106 1107 var $buttonContainerId = $("#"+buttonContainerId), 1108 $button = $buttonContainerId.find("button"); 1109 1110 $buttonContainerId.css(btnContainerStyle) 1111 $button.css(optBtnFullScreen.style.default) 1112 $button.hover(function(){ 1113 $button.css(optBtnFullScreen.style.onHover) 1114 }, function(){ 1115 $button.css(optBtnFullScreen.style.default) 1116 }) 1117 1118 $button.click(function(){ 1119 if(fullScreenActived){ 1120 $parentContainer.css({ 1121 position:"relative", 1122 width:defaultSizeParentContainer.width, 1123 height:defaultSizeParentContainer.height 1124 }) 1125 $("html, body").css({ 1126 overflow:"visible" 1127 }); 1128 $button.html(`<i class="fa fa-${optBtnFullScreen.icon.maximize}" aria-hidden="true"></i>`) 1129 $("html, body").scrollTop($parentContainer.offset().top - 100) 1130 }else{ 1131 var mainNavHeight = document.getElementById("mainNav").offsetHeight 1132 $parentContainer.css({ 1133 position:"absolute", 1134 height:`calc(100vh - ${mainNavHeight}px)`, 1135 width:"100vw", 1136 top:0, 1137 left:0, 1138 zIndex:999 1139 }) 1140 $("html, body").scrollTop(0).css({ 1141 overflow:"hidden" 1142 }); 1143 $button.html(`<i class="fa fa-${optBtnFullScreen.icon.minimize}" aria-hidden="true"></i>`) 1144 } 1145 1146 setTimeout(function(){ 1147 _map.invalidateSize() 1148 }, 400) 1149 1150 fullScreenActived = !fullScreenActived; 1151 }) 1152 } 1153 1154 var initBtnActions = function(){ 1155 var btnActionItems = ""; 1156 for(let i in _options.actionButtons){ 1157 _options.actionButtons[i].id = `btn-map-action_${_utils.generateRandomId()}`; 1158 btnActionItems += `<li id="${_options.actionButtons[i].id}"><i class="fa fa-${_options.actionButtons[i].icon}" aria-hidden="true"></i></li>` 1159 } 1160 1161 var btnActions = ` 1162 <div class="btn-map-actions-container"> 1163 <ul class="btn-map-actions"> 1164 ${btnActionItems} 1165 </ul> 1166 <button id="btn-toggle-map-actions"><i class="fa fa-plus" aria-hidden="true"></i></button> 1167 </div> 1168 ` 1169 $(_options.parentContainer).append(btnActions); 1170 1171 $('#btn-toggle-map-actions').click(function(){ 1172 $(this).toggleClass('active') 1173 $(".btn-map-actions").toggleClass('active') 1174 }) 1175 for(let i in _options.actionButtons){ 1176 $("#"+ _options.actionButtons[i].id).click(function(){ 1177 if(_options.actionButtons[i].onclick){ 1178 _options.actionButtons[i].onclick() 1179 } 1180 $('#btn-toggle-map-actions').removeClass("active") 1181 $(".btn-map-actions").removeClass('active') 1182 }) 1183 } 1184 } 1185 1186 var init = function(){ 1187 if($(options.container).length > 0){ 1188 initVar() 1189 initView() 1190 _context.showLoader(); 1191 _map = L.map(_options.container, _options.mapOpt); 1192 _context.setTile(_options.mapCustom.tile) 1193 L.control.zoom({ 1194 position: 'topleft', 1195 }).addTo(_map); 1196 1197 if(_options.elts){ 1198 _context.addElts(_options.elts) 1199 }else{ 1200 setTimeout(function(){ 1201 _map.invalidateSize() 1202 }, 400) 1203 } 1204 } 1205 } 1206 /* <========== private methodes */ 1207 1208 /* getters & setters ==========> */ 1209 this.getMap = function(){ 1210 return _map; 1211 } 1212 this.getOptions = function(){ 1213 return _options; 1214 } 1215 this.setOptions = function(newOptions){ 1216 _options = newOptions; 1217 } 1218 this.getUtils = function(){ 1219 return _utils; 1220 } 1221 this.getFiltres = function(){ 1222 return _filtres; 1223 } 1224 /* <========== getters & setters */ 1225 1226 /* public methodes ==========> */ 1227 this.addElts = function (data, refresh) { 1228 _context.clearMap() 1229 if(_options.mapCustom.addElts){ 1230 _options.mapCustom.addElts(_context, data) 1231 }else{ 1232 _options.legende.push("Autre"); 1233 _options.legende = unique(_options.legende); 1234 if(_options.markerType == "geoshape"){ 1235 var itteration = 1; 1236 data = data.features ? data.features : data; 1237 $.each(data, function(k, v){ 1238 var geoV = {}; 1239 if(v.type && v.geometry){ 1240 geoV = v; 1241 }else if(v.geoShape){ 1242 geoV = { 1243 type: "Feature", 1244 properties: { 1245 name: v.name 1246 }, 1247 geometry: v.geoShape 1248 } 1249 } 1250 _context.addGeoJSON(geoV); 1251 if(itteration == Object.keys(data).length){ 1252 var geoJson = L.geoJSON(_options.arrayBounds, { 1253 onEachFeature: function(feature, layer){ 1254 layer.on("mouseover", function(){ 1255 geoJson.setStyle({color: 'gray', op
1255acity: 0.5}); 1256 this.setStyle({ 1257 color: '#0000FF', 1258 opacity: 1 1259 }) 1260 }) 1261 layer.on("mouseout", function(){ 1262 geoJson.setStyle({color: '#0000FF', opacity: 0.5}); 1263 }) 1264 _context.addPopUp(layer, feature.properties); 1265 }, 1266 style: { 1267 color: "#0000FF" 1268 } 1269 }); 1270 _options.geoJSONlayer.addLayer(geoJson); 1271 _map.addLayer(geoJson); 1272 _context.hideLoader(); 1273 _map.invalidateSize(); 1274 _map.fitBounds(geoJson.getBounds()) 1275 } 1276 itteration++; 1277 }); 1278 }else if(_options.markerType == "heatmap"){ 1279 if(typeof refresh == 'undefined' || refresh){ 1280 _options.clickedLegende = ""; 1281 _options.data = data; 1282 } 1283 var cfg = { 1284 // radius should be small ONLY if scaleRadius is true (or small radius is intended) 1285 // if scaleRadius is false it will be the constant radius used in pixels 1286 "radius": 20, 1287 "maxOpacity": .75, 1288 // scales the radius based on map zoom 1289 "scaleRadius": false, 1290 // if set to false the heatmap uses the global maximum for colorization 1291 // if activated: uses the data maximum within the current map boundaries 1292 // (there will always be a red spot with useLocalExtremas true) 1293 "useLocalExtrema": true, 1294 // which field name in your data represents the latitude - default "lat" 1295 latField: 'lat', 1296 // which field name in your data represents the longitude - default "lng" 1297 lngField: 'lng', 1298 // which field name in your data represents the data value - default "value" 1299 valueField: 'count', 1300 gradient: { 1301 0.25: "rgb(0,0,255)", 1302 0.55: "rgb(3 173 3)", 1303 0.85: "#f9f952", 1304 1.0: '#ff2b40' 1305 } 1306 }; 1307 var heatMapData = {max: 2000, data: []}; 1308 var heatmapLayer = new HeatmapOverlay(cfg); 1309 var geoJson = []; 1310 var i = 1; 1311 var geoJsonLayer = null; 1312 $.each(data, function(k, v){ 1313 if(typeof v.geoShape != "undefined"){ 1314 _context.addGeoJSON({ 1315 type: "Feature", 1316 properties: { 1317 name: v.name 1318 }, 1319 geometry: v.geoShape 1320 }); 1321 } 1322 if(_filtres.result(v) && typeof v.geoShape == "undefined" && typeof v.geo != "undefined"){ 1323 heatMapData.data.push({lat: v.geo.latitude, lng: v.geo.longitude, count: 1}); 1324 var latLon = [v.geo.latitude, v.geo.longitude]; 1325 _options.arrayBounds.push(latLon) 1326 } 1327 if(i == Object.keys(data).length){ 1328 geoJsonLayer = L.geoJSON(_options.arrayBounds, { 1329 onEachFeature: function(feature, layer){ 1330 layer.on("mouseover", function(){ 1331 geoJsonLayer.setStyle({color: 'gray', opacity: 0.5}); 1332 this.setStyle({ 1333 color: '#0000FF', 1334 opacity: 1 1335 }) 1336 }) 1337 layer.on("mouseout", function(){ 1338 geoJsonLayer.setStyle({color: '#0000FF', opacity: 0.5}); 1339 }) 1340 _context.addPopUp(layer, feature.properties); 1341 }, 1342 style: { 1343 color: "#0000FF" 1344 } 1345 }); 1346 heatmapLayer.setData(heatMapData); 1347 _options.geoJSONlayer.addLayer(geoJsonLayer); 1348 _options.geoJSONlayer.addLayer(heatmapLayer); 1349 _map.addLayer(geoJsonLayer); 1350 _map.addLayer(heatmapLayer); 1351 } 1352 i++; 1353 }) 1354 _context.hideLoader(); 1355 _map.invalidateSize(); 1356 _context.fitBounds(data); 1357 }else{ 1358 if(typeof refresh == 'undefined' || refresh){ 1359 _options.clickedLegende = ""; 1360 _options.data = data; 1361 } 1362 var geoJson = []; 1363 $.each(data, function(k, v){ 1364 if(!_options.data[k]) 1365 _options.data[k] = v; 1366 if(_options.dynamicLegende == true || _options.dynamicLegende == 'true'){ 1367 if(v.data){ 1368 _options.legende = unique(_options.legende.concat(Object.keys(v.data))) 1369 }else if(v[_options.groupBy] instanceof Array || v[_options.groupBy] instanceof Object){ 1370 _options.legende = unique(_options.legende.concat(Object.keys(v[_options.groupBy]))) 1371 }else{ 1372 _options.legende.push((!v[_options.groupBy] || v[_options.groupBy] == "" ? "Autre" : v[_options.groupBy])); 1373 _options.legende = unique(_options.legende); 1374 } 1375 } 1376 if(typeof v.geoShape != "undefined"){ 1377 geoJson.push({ 1378 type: "Feature", 1379 properties: { 1380 name: v.name, 1381 id: k 1382 }, 1383 geometry: v.geoShape 1384 }); 1385 } 1386 if(_filtres.result(v) && typeof v.geoShape == "undefined" && typeof v.geo != "undefined"){ 1387 if(typeof refresh == "undefined" || refresh){ 1388 _options.legendeActivated = unique(_options.legendeActivated.concat(_options.legende)); 1389 } 1390 v.id = k; 1391 _context.addMarker({ elt: v, legende: _options.legende, legendeActivated: _options.legendeActivated }) 1392 _options.mapCustom.lists.createItemList(k, v, _options.container) 1393 } 1394 }) 1395 _options.geoJSONlayer.addLayer(L.geoJSON(geoJson, { 1396 onEachFeature: function(feature, layer){ 1397 _context.addPopUp(layer, feature); 1398 if(_options.mapOpt.onclickMarker){ 1399 layer.on('click', function(){ 1400 _options.mapOpt.onclickMarker(feature); 1401 }); 1402 } 1403 }, 1404 style: { 1405 color: "#0000FF" 1406 } 1407 })); 1408 _map.addLayer(_options.geoJSONlayer); 1409 if(_options.activeCluster) 1410 _map.addLayer(_options.markersCluster) 1411 _utils.bindMap(); 1412 1413 if(_options.forced){ 1414 if(_options.forced.latLon && _options.forced.zoom){
1415 _map.setView(_options.forced.latLon, _options.forced.zoom) 1416 }else{ 1417 if(_options.forced.latLon) 1418 _map.panTo(_options.forced.latLon) 1419 if(_options.forced.zoom) 1420 _map.setZoom(_options.forced.zoom) 1421 } 1422 } 1423 if(_options.showLegende){ 1424 // if(document.querySelectorAll("#info-pane").length < 1){ 1425 // $("[id="+_options.container+"]").append('<div id="info-pane" class="leaflet-bar chart-container" style="position: absolute;right: 20px;top: 0;z-index: 9999999;background: white;display: none; ">'+ 1426 // '<div style="max-height: 500px;overflow-y: auto;"><svg id="chartCanvas"></svg></div>'+ 1427 // '<button id="chartBtn" class="btn btn-sm">Enregistrer</button>'+ 1428 // '</div>'); 1429 // } 1430 if(document.querySelectorAll(".chart-legende-container").length < 1){ 1431 legende = L.control({ 1432 position: "topright" 1433 }); 1434 legende.onAdd = function(map){ 1435 var div = L.DomUtil.create('div', 'chart-legende-container'); 1436 var str = '<div style="max-height: 500px;overflow-y: auto;"><svg id="chartCanvas"></svg></div>'; 1437 1438 str += '<button id="chartBtn" class="btn btn-sm">Enregistrer</button>'; 1439 div.innerHTML = str; 1440 return div; 1441 } 1442 legende.addTo(_map) 1443 } 1444 var Svg = d3.select("#chartCanvas") 1445 .attr("width", 200) 1446 .attr("height", _options.legende.length * 20 + 20); 1447 Svg.selectAll(".d3map-legend").remove(); 1448 _options.lastLegende = JSON.parse(JSON.stringify(_options.legendeActivated)); 1449 // Add one dot in the legend for each name. 1450 var group = Svg.selectAll("mydots") 1451 .data(_options.legende) 1452 .join((enter) => { 1453 let g = enter; 1454 g = g.append("g").attr("height", "20px").attr("width", "100%").attr('class', 'd3map-legend').style("cursor", "pointer"); 1455 g.append("circle") 1456 .attr("cx", 20) 1457 .attr("cy", function(d,i){ return 20 + i*20}) // 20 is where the first dot appears. 25 is the distance between dots 1458 .attr("r", 7) 1459 .style("fill", function(d){ return (_options.legendeActivated.indexOf(d) > -1 ? _options.colors(d) : "transparent")}) 1460 .style("stroke", function(d){ return _options.colors(d)}) 1461 .on('click', function(d, i){ 1462 var circle = d3.select(this); 1463 if(circle.attr("class") === "disabled"){ 1464 circle.attr("class", ""); 1465 circle.style("fill", function(d){ return _options.colors(d)}); 1466 _options.lastLegende.push(i); 1467 }else{ 1468 circle.attr("class", "disabled"); 1469 circle.style("fill", "transparent"); 1470 if(_options.lastLegende.indexOf(i) > -1){ 1471 _options.lastLegende.splice(_options.lastLegende.indexOf(i), 1) 1472 } 1473 } 1474 if(JSON.stringify(_options.legendeActivated.sort()) == JSON.stringify(_options.lastLegende.sort())){ 1475 $("#chartBtn").hide(); 1476 }else{ 1477 $("#chartBtn").show(); 1478 } 1479 }) 1480 g.append("text") 1481 .attr("x", 35) 1482 .attr("y", function(d,i){ return 20 + i*20}) // 20 is where the first dot appears. 25 is the distance between dots 1483 .style("fill", function(d){ return _options.colors(d)}) 1484 .text(function(d){ return d}) 1485 .attr("text-anchor", "left") 1486 .style("alignment-baseline", "middle") 1487 .on('click', function(d, i){ 1488 if(_options.clickedLegende == i){ 1489 _context.clearMap() 1490 _context.addElts(_options.data); 1491 }else{ 1492 _options.clickedLegende = i; 1493 i = (i == 'Autre' ? '' : i); 1494 var data = Object.fromEntries(Object.entries(_options.data). 1495 filter(([key, val]) => { 1496 if(_options.dynamicLegende == false || _options.dynamicLegende == 'false'){ 1497 return i == '' ? (!val[_options.legendeVar] || (val[_options.legendeVar] && val[_options.legendeVar].some(ai => _options.legende.includes(ai)) == false)) : (!val[_options.legendeVar] ? false : val[_options.legendeVar].includes(i)); 1498 }else{ 1499 return (i == '' ? (!val[_options.groupBy] || val[_options.groupBy] == '') : val[_options.groupBy] == i ) 1500 } 1501 })) 1502 _context.addElts(data, false); 1503 } 1504 }) 1505 return g; 1506 }) 1507 1508 1509 d3.select("#chartBtn").on('click', function(){ 1510 $(".mapLoading").show(); 1511 _options.legendeActivated = JSON.parse(JSON.stringify(_options.lastLegende)) 1512 setTimeout(function(){ 1513 _context.addElts(data, false); 1514 }, 100) 1515 }) 1516 $("#chartBtn").hide(); 1517 $("#info-pane").show(); 1518 }else{ 1519 $("#info-pane").hide(); 1520 } 1521 _context.hideLoader(); 1522 _map.invalidateSize(); 1523 _context.fitBounds(data); 1524 } 1525 } 1526 } 1527 1528 this.addGeoJSON = function(params){ 1529 _options.arrayBounds.push(params); 1530 1531 } 1532 1533 this.addMarker = function(params){ 1534 if(_options.mapCustom.addMarker){ 1535 _options.mapCustom.addMarker(_context, params) 1536 }else{ 1537 if( params.elt && params.elt.geo && params.elt.geo.latitude && params.elt.geo.longitude){ 1538 if(!params.opt) 1539 params.opt = {} 1540 params.opt.icon = _options.mapCustom.icon.getIcon(params) 1541 1542 var latLon = [params.elt.geo.latitude, params.elt.geo.longitude]; 1543 this.setDistanceToMax(latLon); 1544 1545 var marker = L.marker(latLon, params.opt); 1546 _options.markerList[params.elt.id] = marker; 1547 1548 if(_options.activePopUp){ 1549 _context.addPopUp(marker, params.elt) 1550 } 1551 1552 _options.arrayBounds.push(latLon) 1553 1554 if(_options.activeCluster){ 1555 _options.markersCluster.addLayer(marker) 1556 }else{ 1557 marker.addTo(_map); 1558 if(params.center){ 1559 _map.panTo(latLon) 1560 } 1561 } 1562 1563 if(_options.mapOpt.doubleClick){ 1564 marker.on('click', function(e){ 1565 this.openPopup()
1566 coInterface.bindLBHLinks(); 1567 }) 1568 marker.on('dbclick', function(e){ 1569 _context.centerOne(params.elt.geo.latitude, params.elt.geo.longitude) 1570 coInterface.bindLBHLinks(); 1571 }) 1572 }else{ 1573 marker.on('click', function (e) { 1574 if(_options.mapOpt.onclickMarker){ 1575 _options.mapOpt.onclickMarker(params) 1576 }else{ 1577 _context.centerOne(params.elt.geo.latitude, params.elt.geo.longitude) 1578 coInterface.bindLBHLinks(); 1579 } 1580 }); 1581 } 1582 1583 if(_options.mapOpt.mouseOver){ 1584 marker.on('mouseover', function (e) { 1585 this.openPopup() 1586 coInterface.bindLBHLinks(); 1587 }); 1588 marker.on('mouseout', function (e) { 1589 var thismarker = this; 1590 setTimeout(function(){ 1591 thismarker.closePopup(); 1592 }, 2000); 1593 }); 1594 } 1595 } 1596 } 1597 } 1598 1599 this.setDistanceToMax = function(latLon){ 1600 if(Object.keys(_options.markerList).length > 0){ 1601 var latLonObj = L.latLng(latLon[0], latLon[1]); 1602 $.each(_options.markerList, function(k, v){ 1603 var dist = latLonObj.distanceTo(v.getLatLng()) 1604 _options.distanceToMax = (dist > _options.distanceToMax) ? dist:_options.distanceToMax 1605 }) 1606 } 1607 } 1608 1609 this.setZoomByDistance = function(){ 1610 var markerListCount = Object.keys(_options.markerList).length 1611 if(markerListCount == 0){ 1612 _options.mapOpt.zoom = 0; 1613 _options.mapOpt.offset.x = 0; 1614 _options.mapOpt.offset.y = 0; 1615 }else if(markerListCount == 1){ 1616 _options.mapOpt.zoom = 14; 1617 _options.mapOpt.offset.x = 0.002; 1618 _options.mapOpt.offset.y = 0.003; 1619 }else{ 1620 if(_options.distanceToMax > 9000000){ 1621 _options.mapOpt.zoom = 2; 1622 _options.mapOpt.offset.x = 0; 1623 _options.mapOpt.offset.y = 15; 1624 }else if(_options.distanceToMax > 7500000){ 1625 _options.mapOpt.zoom = 3; 1626 _options.mapOpt.offset.x = 0; 1627 _options.mapOpt.offset.y = 15; 1628 }else if(_options.distanceToMax > 6000000){ 1629 _options.mapOpt.zoom = 4; 1630 _options.mapOpt.offset.x = 0; 1631 _options.mapOpt.offset.y = 0.2; 1632 }else if(_options.distanceToMax > 50000){ 1633 _options.mapOpt.zoom = 6; 1634 _options.mapOpt.offset.x = 0; 1635 _options.mapOpt.offset.y = 0.2; 1636 }else if(_options.distanceToMax > 20000){ 1637 _options.mapOpt.zoom = 8; 1638 _options.mapOpt.offset.x = 0; 1639 _options.mapOpt.offset.y = 0.2; 1640 }else if(_options.distanceToMax > 10000){ 1641 _options.mapOpt.zoom = 10; 1642 _options.mapOpt.offset.x = 0; 1643 _options.mapOpt.offset.y = 0.2; 1644 }else{ 1645 _options.mapOpt.zoom = 12; 1646 _options.mapOpt.offset.x = 0; 1647 _options.mapOpt.offset.y = 0.2; 1648 } 1649 } 1650 1651 if(!_options.mapOpt.menuRight){ 1652 _options.mapOpt.offset.x = 0; 1653 _options.mapOpt.offset.y = 0; 1654 } 1655 } 1656 1657 this.clearMap = function(){ 1658 if(_options.markersCluster){ 1659 _options.markersCluster.clearLayers() 1660 } 1661 if(_options.geoJSONlayer){ 1662 _options.geoJSONlayer.eachLayer(function(layer){ 1663 _map.removeLayer(layer) 1664 }); 1665 } 1666 if(Object.keys(_options.markerList).length > 0){ 1667 $.each(_options.markerList, function(){ 1668 _map.removeLayer(this) 1669 }) 1670 } 1671 if(_options.markerSingleList && Object.keys(_options.markerSingleList)){ 1672 $.each(_options.markerSingleList, function(){ 1673 _map.removeLayer(this) 1674 }) 1675 } 1676 _options.markerList = {}; 1677 _options.arrayBounds = []; 1678 _options.bounds = null; 1679 1680 _context.showLoader() 1681 $(_options.parentContainer + " .liste_map_element").html("") 1682 } 1683 1684 this.addPopUp = function(marker, elt=null, open=false){ 1685 var popupSimple = _options.mapCustom.getPopup(elt) 1686 marker.bindPopup(popupSimple, {width:"300px"}).openPopup(); 1687 if(open) 1688 marker.openPopup(); 1689 } 1690 1691 this.centerOne = function(lat, lon){ 1692 if(_filtres.timeoutAddCity) 1693 clearTimeout(_filtres.timeoutAddCity) 1694 _filtres.timeoutAddCity = setTimeout(function(){ 1695 var moveLat = "0.0008"; 1696 var moveLon = "0.000"; 1697 1698 lat = parseFloat(lat) + parseFloat(moveLat); 1699 lon = parseFloat(lon) + parseFloat(moveLon); 1700 1701 var center = [lat, lon]; 1702
1703 _map.setView(center, _options.mapOpt.centerOneZoom) 1704 }, 500) 1705 } 1706 1707 this.showLoader = function(){ 1708 $(".mapLoading").show(); 1709 var heightMap = $(_options.parentContainer).outerHeight(); 1710 var widthMap = $(_options.parentContainer).outerWidth(); 1711 if ($(_options.parentContainer + " #menuRight" + _options.parentContainerName).is(":visible")) { 1712 widthMap = widthMap - $(_options.parentContainer + " #menuRight" + _options.parentContainerName).outerWidth(); 1713 } 1714 coInterface.showLoader(".mapLoading", trad.currentlyresearching); 1715 var marginLeftLoader = (widthMap - $(".mapLoading").outerWidth()) / 2; 1716 var marginTopLoader = (heightMap - $(".mapLoading").outerHeight()) / 2; 1717 $(".mapLoading").css({ "margin-left": marginLeftLoader + "px", "margin-top": marginTopLoader + "px" }); 1718 } 1719 this.hideLoader = function(){ 1720 $(".mapLoading").fadeOut(); 1721 } 1722 1723 this.setTile = function(tile){ 1724 if (tile === "mapbox" && $('script[src="https://api.mapbox.com/mapbox.js/v3.2.1/mapbox.js"]').length){ 1725 var accessToken = 'pk.eyJ1IjoiY29tbXVuZWN0ZXI5NzQiLCJhIjoiY2tkOHF3cTZ1MDZmNzJzbWk4M3pnZ2dvbCJ9.J9aOUObe8B9lH-8QLmDzNw'; 1726 1727 var mapboxTiles = L.tileLayer('https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/{z}/{x}/{y}
1727?access_token=' + accessToken, { 1728 attribution: '© <a href="https://www.mapbox.com/feedback/">Mapbox</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' 1729 }); 1730 _map.addLayer(mapboxTiles) 1731 } else if (tile === "maptiler" && $('script[src="https://api.mapbox.com/mapbox.js/v3.2.1/mapbox.js"]').length) { 1732 var accessToken = '2FAeSQOpVCo7WdsCmujj'; 1733 1734 var mapboxTiles = L.tileLayer('https://api.maptiler.com/maps/eb5fb1d0-58c0-47ab-af0a-86ed434e011c/256/{z}/{x}/{y}@2x.png?key=' + accessToken, { 1735 "attribution": "<a href=\"https://www.maptiler.com/copyright/\" target=\"_blank\">© MapTiler</a> <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">© OpenStreetMap contributors</a>" 1736 }); 1737 _map.addLayer(mapboxTiles) 1738 }else if(tile === "toner-lite"){ 1739 // L.tileLayer('https://tiles.stadiamaps.com/tiles/stamen_toner_lite/{z}/{x}/{y}{r}.png', { 1740 // attribution: '© <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a> <a href="https://stamen.com/" target="_blank">© Stamen Design</a> © <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> © <a href="https://www.openstreetmap.org/about" target="_blank">OpenStreetMap</a> contributors' 1741 // }).addTo(_map) 1742 1743 var accessToken = '2FAeSQOpVCo7WdsCmujj'; 1744 1745 var mapboxTiles = L.tileLayer('https://api.maptiler.com/maps/toner-v2-lite/256/{z}/{x}/{y}@2x.png?key=' + accessToken, { 1746 "attribution": "<a href=\"https://www.maptiler.com/copyright/\" target=\"_blank\">© MapTiler</a> <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">© OpenStreetMap contributors</a>", 1747 }); 1748 _map.addLayer(mapboxTiles) 1749 }else if(tile === "satelite"){ 1750 // L.tileLayer('https://tiles.stadiamaps.com/tiles/stamen_toner_lite/{z}/{x}/{y}{r}.png', { 1751 // attribution: '© <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a> <a href="https://stamen.com/" target="_blank">© Stamen Design</a> © <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> © <a href="https://www.openstreetmap.org/about" target="_blank">OpenStreetMap</a> contributors' 1752 // }).addTo(_map) 1753 1754 var accessToken = '2FAeSQOpVCo7WdsCmujj'; 1755 1756 var mapboxTiles = L.tileLayer('https://api.maptiler.com/maps/toner-v2-lite/256/{z}/{x}/{y}@2x.png?key=' + accessToken, { 1757 "attribution": "<a href=\"https://www.maptiler.com/copyright/\" target=\"_blank\">© MapTiler</a> <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">© OpenStreetMap contributors</a>", 1758 }); 1759 _map.addLayer(mapboxTiles) 1760 }else if(tile == "mapnik"){ 1761 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 1762 maxZoom: 19, 1763 attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' 1764 }).addTo(_map); 1765 }else{ 1766 if(baseUrl.indexOf("www.communecter.org") > -1){ 1767 if($('script[src="https://api.mapbox.com/mapbox.js/v3.2.1/mapbox.js"]').length){ 1768 var accessToken = '2FAeSQOpVCo7WdsCmujj'; 1769 var mapboxTiles = L.tileLayer('https://api.maptiler.com/maps/eb5fb1d0-58c0-47ab-af0a-86ed434e011c/256/{z}/{x}/{y}@2x.png?key=' + accessToken, { 1770 "attribution": "<a href=\"https://www.maptiler.com/copyright/\" target=\"_blank\">© MapTiler</a> <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">© OpenStreetMap contributors</a>" 1771 }); 1772 _map.addLayer(mapboxTiles) 1773 }else{ 1774 var accessToken = '2FAeSQOpVCo7WdsCmujj'; 1775 1776 var mapboxTiles = L.tileLayer('https://api.maptiler.com/maps/toner-v2/256/{z}/{x}/{y}@2x.png?key=' + accessToken, { 1777 "attribution": "<a href=\"https://www.maptiler.com/copyright/\" target=\"_blank\">© MapTiler</a> <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">© OpenStreetMap contributors</a>", 1778 }); 1779 1780 this.map.addLayer(mapboxTiles) 1781 } 1782 }else{ 1783 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 1784 attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">ODbL</a>' 1785 }).addTo(_map); 1786 } 1787 } 1788 } 1789 1790 this.addPolygon = function(data){ 1791 var polygon = L.polygon(data).addTo(_map) 1792 _context.addPopUp(polygon) 1793 } 1794 1795 this.fitBounds = function(){ 1796 if(_options.arrayBounds.length > 0){ 1797 _options.arrayBounds.forEach(function(element){ 1798 1799 }); 1800 _map.fitBounds(_options.arrayBounds) 1801 if(_map.getZoom() == 0){ 1802 _map.setZoom(3) 1803 } 1804 }else{ 1805 _map.panTo(_options.mapOpt.center); 1806 _map.setZoom(_options.mapOpt.zoom); 1807 _map.invalidateSize(); 1808 } 1809 } 1810 /* public methodes ==========> */ 1811 1812 /* call init when constructing the object */ 1813 init() 1814}
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.