1/* Min etmax des données */ 2const conso_min_year = 2013; 3const conso_max_year = 2023; 4 5const num_jenks_classes = 5; 6 7/* Contiendront les bornes des classes de légendes */ 8/* Dynamiques car les bornes (min_year max_year sont variables) */ 9let jenks_coms = []; 10let jenks_epcis = []; 11 12let current_min_year = conso_min_year; 13let current_max_year = conso_max_year; 14 15/* -- 5 classes green from colorbrewer-- */ 16const artif_epci_colors = [ 17 {min: 3.8, max: 5.7, color: '#006837'}, 18 {min: 5.7, max: 9.8, color: '#31a354'}, 19 {min: 9.8, max: 18, color: '#78c679'}, 20 {min: 18, max: 29.4, color: '#c2e699'}, 21 {min: 29.4, max: 54, color: '#ffffcc'}, 22]; 23 24const artif_com_colors = [ 25 {min: 0.5, max: 8.1, color: '#006837'}, 26 {min: 8.1, max: 15.6, color: '#31a354'}, 27 {min: 15.6, max: 26.3, color: '#78c679'}, 28 {min: 26.3, max: 42.2, color: '#addd8e'}, 29 {min: 42.2, max: 61, color: '#d9f0a3'}, 30 {min: 61, max: 82, color: '#ffffcc'}, 31]; 32 33// Couleurs pour 5 classes de conso d'espace 34//const conso_colors = ['#006837', '#31a354', '#78c679', '#c2e699', '#ffffcc']; 35const conso_colors = ['#ffffd4', '#fed98e', '#fe9929', '#d95f0e', '#993404']; 36 37// Remplissage initial des classes de légendes jenks_coms et jenks_epcis 38set_conso_epcis_classes(); 39set_conso_coms_classes(); 40 41$(function() { 42 // set map 43 const estompage = new ol.layer.Tile({ 44 'title':'Relief estompé', 45 visible: true, 46 source: new ol.source.WMTS({ 47 url: 'https://data.geopf.fr/wmts', 48 layer: "ELEVATION.ELEVATIONGRIDCOVERAGE.SHADOW", 49 matrixSet: "PM", 50 format: "image/png", 51 style: "estompage_grayscale", 52 tileGrid : new ol.tilegrid.WMTS({ 53 origin: [-20037508,20037508], // topLeftCorner 54 resolutions: get_resol(), // résolutions 55 matrixIds: ["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19"] // ids des TileMatrix 56 }) 57 }), 58 }); 59 60 /* ------------------------------------------------------- Departement layer --- */ 61 function createDeptTextStyle(feature, fill, stroke, txt) { 62 return new ol.style.Text({ 63 font: '12px "Arial black",sans-serif', 64 text: txt, 65 textAlign:'center', 66 // offsetX:8, 67 fill: new ol.style.Fill({color:fill}), 68 stroke: new ol.style.Stroke({color:stroke, width:2}), 69 overflow: false, 70 }); 71 }; 72 73 function deptStyleFunction(feature, res) { 74 const datadep = artif31.dep[0]; 75 let text = ''; 76 let text_color = '#c1c1c1'; 77 let stroke_color = 'rgba(150,150,150, 1)'; 78 let color = 'transparent'; 79 let zIndex = 1; 80 81 if ( feature.getProperties().dep == '31') { 82 color = get_epci_artifcolor(datadep.tx_art_2013); 83 stroke_color = text_color = 'rgba(0,0,0, 1)'; 84 zIndex = 2; 85 } 86 87 if ( res > 250) { 88 text = createDeptTextStyle(feature, text_color, '#fff', feature.getProperties().libgeo); 89 } 90 91 return new ol.style.Style({ 92 stroke: new ol.style.Stroke({ 93 color: stroke_color, 94 width: 2 95 }), 96 fill: new ol.style.Fill({ 97 color: color 98 }), 99 zIndex: zIndex, 100 text:text 101 }); 102 } 103 104 function consodeptStyleFunction(feature, res) { 105 const datadep = artif31.dep[0]; 106 107 let text = ''; 108 let text_color = '#c1c1c1'; 109 let stroke_color = 'rgba(150,150,150, 1)'; 110 let color = 'transparent'; 111 let zIndex = 1; 112 113 if ( feature.getProperties().dep == '31') { 114 // color = get_epci_artifcolor(datadep.tx_art_2013); 115 color = get_epci_jenks_color(getnafart(datadep)/datadep['surfcom202']); 116 stroke_color = text_color = 'rgba(0,0,0, 1)'; 117 zIndex = 2; 118 119 } 120 121 if ( res > 250) { 122 text = createDeptTextStyle(feature, text_color, '#fff', feature.getProperties().libgeo); 123 } 124 125 return new ol.style.Style({ 126 stroke: new ol.style.Stroke({ 127 color: stroke_color, 128 width: 2 129 }), 130 fill: new ol.style.Fill({ 131 color: color 132 }), 133 zIndex: zIndex, 134 text:text 135 }); 136 } 137 138 const dept_layer = new ol.layer.Vector({ 139 'title':'Départements', 140 allwaysOnTop : false, 141 source: new ol.source.Vector({ 142 url: base_url + 'get_json/departement/dept_limit31.json', 143 format: new ol.format.GeoJSON(), 144 }), 145 style: deptStyleFunction 146 }); 147 148 const dept_layer_conso = new ol.layer.Vector({ 149 'title':'Départements', 150 allwaysOnTop : false, 151 source: new ol.source.Vector({ 152 url: base_url + 'get_json/departement/dept_limit31.json', 153 format: new ol.format.GeoJSON(), 154 }), 155 style: consodeptStyleFunction 156 }); 157 158 /* ------------------------------------------------------- EPCI layer --- */ 159 function createTextStyle(feature, fill, stroke, txt) { 160 return new ol.style.Text({ 161 font: '11px Calibri,sans-serif', 162 text: txt, 163 textAlign:'center', 164 // offsetX:8, 165 fill: new ol.style.Fill({color:fill}), 166 stroke: new ol.style.Stroke({color:stroke, width:2}), 167 overflow: true, 168 }); 169 }; 170 171 function epciStyleFunction(feature, res) { 172 const feature_id = feature.getProperties().siren_epci; 173 174 const dataepci = get_epci_data(feature_id); 175 176 let text = ''; 177 if ( res > 55 && res < 250 ) { 178 //text = createTextStyle(feature,'#000', '#fe3', dataepci['name']); 179 text = createTextStyle(feature,'#000', '#fe3', feature.getProperties().epci); 180 } 181 //const color = scot_colors[feature.getProperties().idscot].replace('alpha', dataepci.evo); 182 const color = get_epci_artifcolor(dataepci.tx_art_2013); 183 const strokecolor = 'rgba(0,0,0,.7)' 184 185 return new ol.style.Style({ 186 stroke: new ol.style.Stroke({ 187 color: strokecolor, 188 width: .7 189 }), 190 fill: new ol.style.Fill({ 191 color: color 192 }), 193 text:text 194 }); 195 } 196 197 function consoepciStyleFunction(feature, res) { 198 const feature_id = feature.getProperties().siren_epci; 199 200 const dataepci = get_epci_data(feature_id); 201 202 let text = ''; 203 if ( res > 55 && res < 250 ) { 204 text = createTextStyle(feature,'#000', '#fe3', feature.getProperties().epci); 205 } 206 207 const color = get_epci_jenks_color(getnafart(dataepci)/dataepci['surfcom202']); 208 209 const strokecolor = 'rgba(0,0,0,.7)'; 210 211 return new ol.style.Style({ 212 stroke: new ol.style.Stroke({ 213 color: strokecolor, 214 width: .7 215 }), 216 fill: new ol.style.Fill({ 217 color: color 218 }), 219 text:text 220 }); 221 } 222 223 const epci_layer = new ol.layer.Vector({ 224 'title':'EPCI', 225 allwaysOnTop : false, 226 // visible: false, 227 source: new ol.source.Vector({ 228 url: base_url + 'get_json/departement/epci.json', 229 format: new ol.format.GeoJSON(), 230 }), 231 visible:false, 232 style: epciStyleFunction 233 }); 234 235 const epci_layer_conso = new ol.layer.Vector({ 236 'title':'EPCI', 237 allwaysOnTop : false, 238 // visible: false, 239 source: new ol.source.Vector({ 240 url: base_url + 'get_json/departement/epci.json', 241 format: new ol.format.GeoJSON(), 242 }), 243 visible:false, 244 style: consoepciStyleFunction 245 }); 246 247 248 /* ------------------------------------------------------- Communes layer --- */ 249 function communesStyleFunction(feature, res) { 250 const feature_id = feature.getProperties().codgeo; 251 const datacom = get_com_data(feature_id); 252 253 if ( datacom === undefined ) { 254 return; 255 } 256 257 let text = ''; 258 if ( res < 55) { 259 text = createTextStyle(feature,'#000', '#fe3', datacom['nom']); 260 } 261 262 const color = get_com_artifcolor(datacom.tx_art_2013); 263 const strokecolor = 'rgba(133,133,133,.7)' 264 265 return new ol.style.Style({ 266 stroke: new ol.style.Stroke({ 267 color: strokecolor, 268 width: 1 269 }), 270 fill: new ol.style.Fill({ 271 color: color 272 }), 273 text:text 274 }); 275 } 276 277 function consocommunesStyleFunction(feature, res) { 278 const feature_id = feature.getProperties().codgeo; 279 const datacom = get_com_data(feature_id); 280 281 if ( datacom === undefined ) { 282 return; 283 } 284 285 let text = ''; 286 if ( res < 55) { 287 text = createTextStyle(feature,'#000', '#fe3', datacom['nom']); 288 } 289 290 const color = get_com_jenks_color(getnafart(datacom)/datacom['surfcom202']); 291 const strokecolor = 'rgba(133,133,133,.7)' 292 293 return new ol.style.Style({ 294 stroke: new ol.style.Stroke({ 295 color: strokecolor, 296 width: 1 297 }), 298 fill: new ol.style.Fill({ 299 color: color 300 }), 301 text:text 302 }); 303 } 304 305 const communes_layer = new ol.layer.Vector({ 306 'title':'Communes', 307 allwaysOnTop : false, 308 // visible: false, 309 source: new ol.source.Vector({ 310 url: base_url + 'get_json/departement/communes.json', 311 format: new ol.format.GeoJSON(), 312 }), 313 visible:true, 314 style: communesStyleFunction 315 }); 316
317 const communes_layer_conso = new ol.layer.Vector({ 318 'title':'Communes', 319 allwaysOnTop : false, 320 // visible: false, 321 source: new ol.source.Vector({ 322 url: base_url + 'get_json/departement/communes.json', 323 format: new ol.format.GeoJSON(), 324 }), 325 visible:true, 326 style: consocommunesStyleFunction 327 }); 328 329 const artif_overlay = new ol.Overlay({ 330 element: document.getElementById('artifpopup'), 331 autoPan: { 332 animation: { 333 duration: 250, 334 } 335 } 336 }); 337 338 /* ------------------------------------------------------- Map artificialisation --- */ 339 let map_artif = new ol.Map({ 340 interactions: ol.interaction.defaults({mouseWheelZoom:false}), 341 controls: ol.control.defaults().extend([ 342 new ol.control.FullScreen() 343 ]), 344 overlays: [artif_overlay], 345 target: 'contmap_artif', 346 view: new ol.View({ 347 zoom: 8.9, 348 center: [130742.2,5358235.1], 349 maxZoom: 15, 350 minZoom: 8 351 }), 352 layers: [dept_layer, epci_layer, communes_layer, estompage] 353 }); 354 355 const mouseWheelInt = new ol.interaction.MouseWheelZoom(); 356 map_artif.addInteraction(mouseWheelInt); 357 358 map_artif.on('wheel', function(evt) { 359 mouseWheelInt.setActive(ol.events.condition.shiftKeyOnly(evt)); 360 }); 361 362 map_artif.addControl(new ol.control.LayerSwitcher({ trash: false, extent:true, collapsed: false, reordering:true })); 363 364 map_artif.addControl(new ol.control.ScaleLine()); 365 366 map_artif.on('singleclick', function (evt) { 367 $('#artifpopup-content').empty(); 368 let template = ``; 369 let nbcom = 0; 370 let nbepci = 0; 371 let nbdep = 0; 372 map_artif.forEachFeatureAtPixel(evt.pixel, 373 function(feature, layer) { 374 if ( nbcom == 0 && layer.getProperties().title == 'Communes' ) { 375 const datacom = get_com_data(feature.getProperties().codgeo); 376 template += `<div>Commune de <strong>${datacom.nom}</strong> <small>(${datacom.idcom})</small><div>`; 377 template += `<div><strong class="soulign">${datacom.tx_art_2013}%</strong> du territoire communal artificialisé en 2013. 378 <small class="soulign">â ${new Intl.NumberFormat().format(Math.round(datacom.surf_art_2013/10000))} ha</small></div> 379 <div><small><strong>${new Intl.NumberFormat().format(datacom.pop_2013)}</strong> habitants et 380 <strong>${new Intl.NumberFormat().format(datacom.emp_2013)}</strong> emplois en 2013.</small></div> 381 <hr>`; 382 nbcom++; 383 /* 384 map_conso.getView().fit(feature.getGeometry().getExtent(), {duration:700}); 385 let prepo = "de"; 386 if ( ['a','e','i','o','u','y'].indexOf(datacom.nom.substr(0,1).toLowerCase()) !== -1 ) { 387 prepo = "d'"; 388 } 389 $("#chartconso_title").html(`Commune ${prepo} ${datacom.nom} <small style="font-weight:normal">(${datacom.idcom}), consommation d'espaces entre 2013 et 2023</small>`); 390 set_conso_chart('com', datacom.idcom);*/ 391 } 392 if ( nbepci == 0 && layer.getProperties().title == 'EPCI' ) { 393 const dataepci = get_epci_data(feature.getProperties().siren_epci); 394 template += `<div><strong>${dataepci.nom_epci}</strong> <small>(${dataepci.siren_epci})</small><div>`; 395 template += `<div><strong class="soulign">${dataepci.tx_art_2013}%</strong> du territoire artificialisé en 2013. 396 <small class="soulign">â ${new Intl.NumberFormat().format(Math.round(dataepci.surf_art_2013/10000))} ha</small></div> 397 <div><small><strong>${new Intl.NumberFormat().format(dataepci.pop_2013)}</strong> habitants et 398 <strong>${new Intl.NumberFormat().format(dataepci.emp_2013)}</strong> emplois en 2013.</small></div> 399 <hr>`; 400 nbepci++; 401 /* 402 if ( nbcom == 0 ) { 403 map_conso.getView().fit(feature.getGeometry().getExtent(), {duration:700}); 404 $("#chartconso_title").html(`${dataepci.nom_epci} <small style="font-weight:normal">(${dataepci.siren_epci}
404), consommation d'espaces entre 2013 et 2023</small>`); 405 set_conso_chart('epci', dataepci.siren_epci); 406 }*/ 407 408 } 409 if ( nbdep == 0 && layer.getProperties().title == 'Départements' && feature.getProperties().dep == '31') { 410 const datadep = artif31.dep[0]; 411 template += `<div><strong>${feature.getProperties().libgeo}</strong><div>`; 412 template += `<div><strong class="soulign">${datadep.tx_art_2013}%</strong> du territoire artificialisé en 2013. 413 <small class="soulign">â ${new Intl.NumberFormat().format(Math.round(datadep.surf_art_2013/10000))} ha</small></div> 414 <div><small><strong>${new Intl.NumberFormat().format(datadep.pop_2013)}</strong> habitants et 415 <strong>${new Intl.NumberFormat().format(datadep.emp_2013)}</strong> emplois en 2013.</small></div> 416 `; 417 nbdep++; 418 /*
419 if (nbcom == 0 && nbepci == 0) { 420 map_conso.getView().fit(feature.getGeometry().getExtent(), {duration:700}); 421 set_conso_chart('dep'); 422 }*/ 423 } 424 }); 425 426 if (template.trim() != '') { 427 $('#artifpopup-content').html(template); 428 artif_overlay.setPosition(evt.coordinate); 429 } else { 430 $('#artifpopup-closer').trigger('click'); 431 } 432 }); 433 434 $(document).on('click', '#artifpopup-closer', function() { 435 artif_overlay.setPosition(undefined); 436 $(this).blur(); 437 return false; 438 }); 439 440 $(document).on('click', '#popupconso-closer', function() { 441 conso_overlay.setPosition(undefined); 442 $(this).blur(); 443 return false; 444 }); 445 446 447 /* ------------------------------------------------------- Legend Artif --- */ 448 const legend = new ol.legend.Legend({ 449 title: 'Légende', 450 textStyle: new ol.style.Text({ 451 font: 'bold 12px Arial, sans-serif', 452 }), 453 margin: 5, 454 size: [20, 10] 455 }) 456 457 const legendCtrl = new ol.control.Legend({ 458 legend: legend, 459 collapsed: false, 460 }); 461 462 map_artif.addControl(legendCtrl); 463 464 legend.addItem({ 465 className: 'Communes', 466 title: 'Communes', 467 textStyle: new ol.style.Text({ 468 font: 'bold 14px Arial, sans-serif', 469 }), 470 height: 30 471 }); 472 473 artif_com_colors.forEach(function(item) { 474 475 legend.addItem({ 476 //className: 'at_item', 477 title: 'Entre '+ item['min'] +' et '+ item['max'] +'%', 478 textStyle: new ol.style.Text({ 479 font: '11px Arial, sans-serif', 480 }), 481 style: get_legende_rectangle(item['color'], '#0000000'), 482 typeGeom: 'Polygon', 483 }); 484 485 }); 486 487 legend.addItem({ 488 className: 'EPCI', 489 title: 'EPCI', 490 textStyle: new ol.style.Text({ 491 font: 'bold 14px Arial, sans-serif', 492 }), 493 height: 30 494 }); 495 496 artif_epci_colors.forEach(function(item) { 497 498 legend.addItem({ 499 //className: 'at_item', 500 title: 'Entre '+ item['min'] +' et '+ item['max'] +'%', 501 textStyle: new ol.style.Text({ 502 font: '11px Arial, sans-serif', 503 }), 504 style: get_legende_rectangle(item['color'], '#0000000'), 505 typeGeom: 'Polygon', 506 }); 507 508 }); 509 510 legend.addItem({ 511 className: 'Departement', 512 title: 'Département 31', 513 textStyle: new ol.style.Text({ 514 font: 'bold 14px Arial, sans-serif', 515 }), 516 height: 30 517 }); 518 519 legend.addItem({ 520 //className: 'at_item', 521 title: artif31.dep[0].tx_art_2013 +'%', 522 textStyle: new ol.style.Text({ 523 font: '11px Arial, sans-serif', 524 }), 525 style: get_legende_rectangle(get_epci_artifcolor(artif31.dep[0].tx_art_2013), '#0000000'), 526 typeGeom: 'Polygon', 527 }); 528 529 /* ------------------------------------------------------- Map artificialisation --- */ 530 531 const conso_overlay = new ol.Overlay({ 532 element: document.getElementById('popupconso'), 533 autoPan: { 534 animation: { 535 duration: 250, 536 } 537 } 538 }); 539 540 let map_conso = new ol.Map({ 541 interactions: ol.interaction.defaults({mouseWheelZoom:false}), 542 /*controls: ol.control.defaults().extend([ 543 new ol.control.FullScreen() 544 ]),*/ 545 overlays: [conso_overlay], 546 target: 'contmap_conso', 547 view: new ol.View({ 548 zoom: 8.3, 549 center: [130742.2,5358235.1], 550 maxZoom: 15, 551 minZoom: 8 552 }), 553 layers: [dept_layer_conso, epci_layer_conso, communes_layer_conso] //dept_layer_conso] 554 }); 555 556 const mouseWheelInt2 = new ol.interaction.MouseWheelZoom(); 557 map_conso.addInteraction(mouseWheelInt2); 558 559 map_conso.on('wheel', function(evt) { 560 mouseWheelInt2.setActive(ol.events.condition.shiftKeyOnly(evt)); 561 }); 562 563 map_conso.addControl(new ol.control.LayerSwitcher({ trash: false, extent:true, collapsed: fal
563se, reordering:true })); 564 565 map_conso.addControl(new ol.control.ScaleLine()); 566 567 map_conso.on('singleclick', function (evt) { 568 569 $('#popupconso-content').empty(); 570 571 let template = ``; 572 let nbcom = 0; 573 let nbepci = 0; 574 let nbdep = 0; 575 let dataset; 576 577 map_conso.forEachFeatureAtPixel(evt.pixel, 578 function(feature, layer) { 579 580 if ( nbcom == 0 && layer.getProperties().title == 'Communes' ) { 581 dataset = get_com_data(feature.getProperties().codgeo); 582 nbcom++; 583 584 let prepo = "de"; 585 if ( ['a','e','i','o','u','y'].indexOf(dataset.nom.substr(0,1).toLowerCase()) !== -1 ) { 586 prepo = "d'"; 587 } 588 $("#chartconso_title").html(`Commune ${prepo} ${dataset.nom} <small style="font-weight:normal">(${dataset.idcom}), consommation d'espaces entre 2013 et 2023</small>`); 589 set_conso_chart('com', dataset.idcom); 590 } 591 592 if ( nbepci == 0 && layer.getProperties().title == 'EPCI' ) { 593 dataset = get_epci_data(feature.getProperties().siren_epci); 594 nbepci++; 595 if ( nbcom == 0 ) { 596 $("#chartconso_title").html(`${dataset.nom_epci} <small style="font-weight:normal">(${dataset.siren_epci}), consommation d'espaces entre 2013 et 2023</small>`); 597 set_conso_chart('epci', dataset.siren_epci); 598 } 599 } 600 if ( nbdep == 0 && layer.getProperties().title == 'Départements' && feature.getProperties().dep == '31') { 601 dataset = artif31.dep[0]; 602 nbdep++; 603 if ( nbcom == 0 && nbepci == 0 ) { 604 set_conso_chart('dep'); 605 } 606 } 607 608 } 609 ); 610 611 if (template.trim() != '') { 612 $('#popupconso-content').html(template); 613 conso_overlay.setPosition(evt.coordinate); 614 } else { 615 $('#popupconso-closer').trigger('click'); 616 } 617 618 }); 619 620 /* ------------------------------------------------------- Legend Artif --- */ 621 const consolegend = new ol.legend.Legend({ 622 title: 'Légende', 623 textStyle: new ol.style.Text({ 624 font: 'bold 12px Arial, sans-serif', 625 }), 626 margin: 3, 627 size: [20, 10] 628 }) 629 630 const consolegendCtrl = new ol.control.Legend({ 631 legend: consolegend, 632 collapsed: false, 633 }); 634 635 map_conso.addControl(consolegendCtrl); 636 637 set_conso_legend(consolegend); 638 639 /* ---- Partie conso espaces ---- */ 640 $('#min_year').attr({ min: conso_min_year, max: conso_max_year-1}).val(conso_min_year); 641 $('#min_year_txt').text(conso_min_year); 642 $('#max_year').attr({ min: conso_min_year + 1, max: conso_max_year }).val(conso_max_year); 643 $('#max_year_txt').text(conso_max_year); 644 645 $('#min_year, #max_year').on("input", function() { 646 const elem = $(this); 647 $('#' + elem.attr("id") + "_txt").text(elem.val()); 648 }); 649 650 // min_year ne peut pas être supérieur à max_year 651 $('#min_year, #max_year').on("change", function() { 652 653 if ( $('#min_year').val() >= $('#max_year').val() ) { 654 $('#max_year').val($('#min_year').val()*1+1); 655 $('#max_year_txt').text($('#min_year').val()*1+1); 656 } 657 current_min_year = $('#min_year').val(); 658 current_max_year = $('#max_year').val(); 659 660 set_conso_epcis_classes(); 661 set_conso_coms_classes(); 662 663 set_conso_legend(consolegend); 664 665 dept_layer_conso.setStyle(consodeptStyleFunction); 666 epci_layer_conso.setStyle(consoepciStyleFunction); 667 communes_layer_conso.setStyle(consocommunesStyleFunction); 668 669 }); 670 671 672 /* Conso chart */ 673 set_conso_chart('dep'); 674}); 675 676function set_conso_chart (what, id) { 677 678 let dataset; 679 if ( what == 'dep') { 680 dataset = artif31['dep'][0]; 681 $("#chartconso_title").html(`Département de Haute-Garonne, <small style="font-weight:normal">
681consommation d'espaces entre 2013 et 2023</small>`); 682 } else if ( what == 'com' ) { 683 dataset = get_com_data(id); 684 } else if ( what == 'epci' ) { 685 dataset = get_epci_data(id); 686 } 687 688 let ev_pop = dataset.ev_pop > 0 ? '+' + dataset.ev_pop : dataset.ev_pop; 689 let ev_emp = dataset.ev_emp > 0 ? '+' + dataset.ev_emp : dataset.ev_emp; 690 691 let tb_tmpl = `<table class="table table-sm table-bordered"> 692 <tr><td></td><th class="text-end">2013</th><th class="text-end">2020</th><th class="text-end">Evol.</th></tr> 693 <tr><th>Population</th><td class="text-end">${Highcharts.numberFormat(dataset.pop_2013, 0)}</td><td class="text-end">${Highcharts.numberFormat(dataset.pop_2020, 0)}</td><td class="text-end">${ev_pop} %</td></tr> 694 <tr><th>Emploi</th><td class="text-end">${Highcharts.numberFormat(dataset.emp_2013, 0)}</td><td class="text-end">${Highcharts.numberFormat(dataset.emp_2020, 0)}</td><td class="text-end">${ev_emp} %</td></tr> 695 `; 696 697 $('#popemploi_tb').html(tb_tmpl); 698 699 const cats = Array.from({ length: (conso_max_year - conso_min_year) }, (v, i) => i+conso_min_year); 700 cats.reverse(); 701 const series_ord = ['mix','inc','inf','act','hab']; 702 const series_alias = ['Mixte','Inconnu','Infrastructures','Activité','Habitat']; 703 704 let serie = []; 705 706 for ( s in series_ord ) { 707 let one = {}; 708 one.name = series_alias[s]; 709 one.data = []; 710 for ( ka in cats ) { 711 let topush = 0; 712 if ( series_ord[s] == 'inf') { 713 topush = dataset['art' + (cats[ka]-2000) + 'rou' + ((cats[ka]+1)-2000)] + dataset['art' + (cats[ka]-2000) + 'fer' + ((cats[ka]+1)-2000)]; 714 } else { 715 topush = dataset['art' + (cats[ka]-2000) + series_ord[s] + ((cats[ka]+1)-2000)]; 716 } 717 one.data.push(topush); 718 } 719 serie.push(one); 720 } 721 722 Highcharts.chart('chartconso', { 723 chart: { 724 type: 'bar', 725 }, 726 colors: ['#38a800', '#adadad', '#a80000', '#00c5ff', '#ffaa00'], 727 title: { 728 text: undefined, 729 }, 730 xAxis: { 731 categories: cats, 732 }, 733 yAxis: { 734 min: 0, 735 title: { 736 text: 'Surfaces consommées, en m²' 737 }, 738 labels: { 739 formatter: function() { 740 return Highcharts.numberFormat(this.value,0); 741 } 742 } 743 }, 744 legend: { 745 reversed: true 746 }, 747 plotOptions: { 748 series: { 749 stacking: 'normal', 750 dataLabels: { 751 enabled: true, 752 useHTML: true, 753 formatter: function() { 754 if ( this.point.percentage == 0 ) { 755 return null; 756 } 757 return Highcharts.numberFormat(this.point.percentage,0)+'<small>%</small>'; 758 }, 759 zIndex: 1 760 } 761 } 762 }, 763 tooltip: { 764 formatter: function() { 765 let s = '<b>'+ this.x +'</b>'; 766 s += '<table>' 767 $.each(this.points, function(i, point) { 768 s += '<tr><th><span style="display:inline-block; width:4px; background-color:' + point.series.color+ '"> </span> '+ point.series.name +' <small style="font-weight:normal;">('+ Highcharts.numberFormat(point.percentage,0) +'%)</small></th><td style="text-align:right">'+ Highcharts.numberFormat(point.y, 0) + ' m²</td></tr>'; 769 }); 770 s += '<tr style="border-top:1px solid #aaa"><th>Total</th><td style="text-align:right">'+ Highcharts.numberFormat(this.points[0].total, 0) + ' m²</td></tr></table>' 771 return s; 772 }, 773 shared: true, 774 useHTML:true, 775 }, 776 series: serie 777 }); 778 779} 780 781 782function set_conso_epcis_classes() { 783 let epcis_vals = []; 784 artif31.epcis.forEach(function(item) { 785 epcis_vals.push(getnafart(item)/item.surfcom202); 786 }); 787 788 jenks_epcis = jenks(epcis_vals, num_jenks_classes); 789} 790 791function set_conso_coms_classes() {
792 let coms_vals = []; 793 artif31.coms.forEach(function(item) { 794 coms_vals.push(getnafart(item)/item.surfcom202); 795 }); 796 797 jenks_coms = jenks(coms_vals, num_jenks_classes); 798} 799 800/* renvoie la somme des nafart entre 2 années: ex: 801naf13art14 + naf14art15 +naf15art16 entre 2013 et 2016 */ 802function getnafart(dataset) { 803 let sum_surf = 0; 804 for ( i = current_min_year; i < current_max_year; i++ ) { 805 const key = 'naf' + (i-2000) + 'art' +(1+(i-2000)*1); 806 sum_surf += dataset[key]; 807 } 808 return sum_surf; 809} 810 811/* renvoie la couleur du tableau jenks_epcis 812correspondant à la valeur envoyée*/ 813function get_epci_jenks_color(surf) { 814 let key = 0; 815 for ( let k in jenks_epcis ) { 816 if ( k == 0 && surf <= jenks_epcis[k] ) { 817 key = 1; 818 } 819 else if ( k > 0 && surf <= jenks_epcis[k] ) { 820 key = k; 821 break; 822 } 823 } 824 return conso_colors[key-1]; 825} 826 827/* renvoie la couleur du tableau jenks_coms 828correspondant à la valeur envoyée*/ 829function get_com_jenks_color(surf) { 830 let key = 0; 831 for ( let k in jenks_coms ) { 832 if ( k == 0 && surf <= jenks_coms[k] ) { 833 key = 1; 834 } 835 else if ( k > 0 && surf <= jenks_coms[k] ) { 836 key = k; 837 break; 838 } 839 } 840 return conso_colors[key-1]; 841} 842 843 844function get_epci_data(id) { 845 return artif31.epcis.find(( {siren_epci} ) => siren_epci == id); 846} 847 848function get_com_data(id) { 849 return artif31.coms.find(( {idcom} ) => idcom == id); 850} 851 852function get_epci_artifcolor(num) { 853 for (let i in artif_epci_colors) { 854 if ( num > artif_epci_colors[i]['min'] && num <= artif_epci_colors[i]['max'] ) { 855 return artif_epci_colors[i]['color']; 856 } 857 } 858 return '#000000'; 859} 860 861function get_com_artifcolor(num) { 862 for (let i in artif_com_colors) { 863 if ( num > artif_com_colors[i]['min'] && num <= artif_com_colors[i]['max'] ) { 864 return artif_com_colors[i]['color']; 865 } 866 } 867 return '#000000'; 868} 869 870function get_legende_rectangle(fillColor, strokeColor) { 871 return new ol.style.Style({ 872 stroke: new ol.style.Stroke({ 873 color: strokeColor, 874 width: 0.5 875 }), 876 fill: new ol.style.Fill({ 877 color: fillColor 878 }) 879 }); 880} 881 882 883function set_conso_legend(consolegend) { 884 885 consolegend.getItems().clear(); 886 887 consolegend.addItem({ 888 className: 'Communes', 889 title: 'Communes', 890 textStyle: new ol.style.Text({ 891 font: 'bold 14px Arial, sans-serif', 892 }), 893 height: 30 894 }); 895 896 for ( let idx = 0; idx < num_jenks_classes; idx++ ) { 897 const min = Math.round(jenks_coms[(idx)] * 10000) / 100; // (jenks_epcis[(idx)]*100).toFixed(4); 898 const max = Math.round(jenks_coms[(idx+1)] * 10000) / 100; // Math.round(jenks_epcis[(idx+1)]*100,4); 899 900 consolegend.addItem({ 901 //className: 'at_item', 902 title: 'De '+ min +' à '+ max +'%', 903 textStyle: new ol.style.Text({ 904 font: '11px Arial, sans-serif', 905 }), 906 style: get_legende_rectangle(conso_colors[idx], '#0000000'), 907 typeGeom: 'Polygon', 908 }); 909 910 } 911 912 consolegend.addItem({ 913 title: '', 914 height: 5 915 }); 916 917 consolegend.addItem({ 918 className: 'EPCI', 919 title: 'EPCI et département', 920 textStyle: new ol.style.Text({ 921 font: 'bold 14px Arial, sans-serif', 922 }), 923 height: 30 924 }); 925 926 for ( let idx = 0; idx < num_jenks_classes; idx++ ) { 927 const min = Math.round(jenks_epcis[(idx)] * 10000) / 100; // (jenks_epcis[(idx)]*100).toFixed(4); 928 const max = Math.round(jenks_epcis[(idx+1)] * 10000) / 100; // Math.round(jenks_epcis[(idx+1)]*100,4); 929 930 consolegend.addItem({ 931 //className: 'at_item', 932 title: 'De '+ min +' à '+ max +'%', 933 textStyle: new ol.style.Text({ 934 font: '11px Arial, sans-serif', 935 }), 936 style: get_legende_rectangle(conso_colors[idx], '#0000000'), 937 typeGeom: 'Polygon', 938 }); 939 940 } 941 942 consolegend.addItem({ 943 title: '', 944 height: 8 945 }); 946 947 consolegend.addItem({ 948 className: 'EPCI', 949 title: 'En % de la surface \n du territoire concerné.', 950 textStyle: new ol.style.Text({ 951 font: 'normal 11px Arial, sans-serif', 952 }), 953 //height: 40 954 }); 955 956} 957 958// résolutions fournies par l'IGN pour travailler avec openLayers 959// https://geoservices.ign.fr/documentation/services/utilisation-web/affichage-wmts/openlayers-et-wmts 960 961function get_resol(){ 962 return [ 963 156543.03392804103, 964 78271.5169640205, 965 39135.75848201024,
966 19567.879241005125, 967 9783.939620502562, 968 4891.969810251281, 969 2445.9849051256406, 970 1222.9924525628203, 971 611.4962262814101, 972 305.74811314070485, 973 152.87405657035254, 974 76.43702828517625, 975 38.218514142588134, 976 19.109257071294063, 977 9.554628535647034, 978 4.777314267823517, 979 2.3886571339117584, 980 1.1943285669558792, 981 0.5971642834779396, 982 0.29858214173896974, 983 0.14929107086948493, 984 0.07464553543474241 985 ]; 986} 987 988function jenks(data, n_classes) { 989 if (n_classes > data.length) return null; 990 991 data = data.slice().sort(function (a, b) { 992 return a - b; 993 }); 994 995 var matrices = getMatrices(data, n_classes); 996 var lower_class_limits = matrices.lower_class_limits; 997 998 // extract n_classes out of the computed matrices 999 return breaks(data, lower_class_limits, n_classes); 1000 1001} 1002 1003/** 1004* the second part of the jenks recipe: take the calculated 1005* matricesand derive an array of n breaks. 1006*/ 1007function breaks(data, lower_class_limits, n_classes) { 1008 1009 var k = data.length - 1, 1010 kclass = [], 1011 countNum = n_classes; 1012 1013 // the calculation of classes will never include the upper and 1014 // lower bounds, so we need to explicitly set them 1015 kclass[n_classes] = data[data.length - 1]; 1016 kclass[0] = data[0]; 1017 1018 // the lower_class_limits matrix is used as indexes into itself 1019 // here: the `k` variable is reused in each iteration. 1020 while (countNum > 1) { 1021 kclass[countNum - 1] = data[lower_class_limits[k][countNum] - 2]; 1022 k = lower_class_limits[k][countNum] - 1; 1023 countNum--; 1024 } 1025 1026 return kclass; 1027} 1028 1029/** 1030* Compute the matrices required for Jenks breaks. These matrices 1031* can be used for any classing of data with `classes <= n_classes` 1032*/ 1033function getMatrices(data, n_classes) { 1034 // * lower_class_limits (LC): optimal lower class limits 1035 // * variance_combinations (OP): optimal variance combinations for all classes 1036 var lower_class_limits = [], 1037 variance_combinations = [], 1038 i, j, 1039 variance = 0; 1040 1041 // Initialize matrix's 1042 for (i = 0; i < data.length + 1; i++) { 1043 var tmp1 = [], 1044 tmp2 = []; 1045 for (j = 0; j < n_classes + 1; j++) { 1046 tmp1.push(0); 1047 tmp2.push(0); 1048 } 1049 lower_class_limits.push(tmp1); 1050 variance_combinations.push(tmp2); 1051 } 1052 1053 for (i = 1; i < n_classes + 1; i++) { 1054 lower_class_limits[1][i] = 1; 1055 variance_combinations[1][i] = 0; 1056 for (j = 2; j < data.length + 1; j++) { 1057 variance_combinations[j][i] = Infinity; 1058 } 1059 } 1060 1061 for (var l = 2; l < data.length + 1; l++) { 1062 1063 var sum = 0, 1064 sum_squares = 0, 1065 w = 0, 1066 i4 = 0; 1067 1068 for (var m = 1; m < l + 1; m++) { 1069 1070 var lower_class_limit = l - m + 1, 1071 val = data[lower_class_limit - 1]; 1072 1073 // here we're estimating variance for each potential classing 1074 // of the data, for each potential number of classes. `w` 1075 // is the number of data points considered so far. 1076 w++; 1077 sum += val; 1078 sum_squares += val * val; 1079 variance = sum_squares - (sum * sum / w); 1080 i4 = lower_class_limit - 1; 1081 1082 if (i4 === 0) { 1083 continue; 1084 } 1085 1086 for (j = 2; j < n_classes + 1; j++) { 1087 // if adding this element to an existing class 1088 // will increase its variance beyond the limit, break 1089 // the class at this point, setting the lower_class_limit 1090 // at this point. 1091 if (variance_combinations[l][j] >= (variance + variance_combinations[i4][j - 1])) { 1092 lower_class_limits[l][j] = lower_class_limit; 1093 variance_combinations[l][j] = variance + variance_combinations[i4][j - 1]; 1094 } 1095 } 1096 1097 } 1098 1099 lower_class_limits[l][1] = 1; 1100 variance_combinations[l][1] = variance; 1101 } 1102 1103 return { 1104 lower_class_limits: lower_class_limits, 1105 variance_combinations: variance_combinations 1106 }; 1107}
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.