<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<meta name=description content="">
<meta name=viewport content="width=device-width, initial-scale=1">
<title>Thematic map with legend</title>
<link rel="stylesheet" href="https://openlayers.org/en/v4.6.4/css/ol.css" type="text/css">
<style>
html, body {
height: 100%;
padding: 0;
margin: 0;
}
#map {
width: 100%;
height: 100%;
}
#popup {
background-color: white;
border: solid 1px #888888;
padding: 10px;
border-radius: 5px;
}
#container {
position: relative;
height: inherit;
width: inherit;
}
#canvas, #map {
position: absolute;
background-color: white;
}
#canvas {
bottom: 0px;
}
</style>
<!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://openlayers.org/en/v4.6.4/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.3.6/papaparse.min.js"></script>
</head>
<body>
<div id="container">
<div id="map" class="map"></div>
<div id="popup"></div>
<canvas id="canvas"></canvas>
</div>
<script src="main.js"></script>
</body>
</html>
const radiusCalculation = (val, coeff) => {
return (val / Math.PI) ** 0.5 * coeff;
};
const vectorLayerSource = new ol.source.Vector({
url: 'departements-france-2017.json',
format: new ol.format.GeoJSON()
});
const fillCircle = new ol.style.Fill({
color: 'rgba(125, 125, 125, 0.6)'
});
const strokeCircle = new ol.style.Stroke({
color: '#ffffff',
width: 1
});
const styleProportionalCircle = (feature, resolution) => {
const extent = feature.getGeometry().getExtent();
const center = ol.extent.getCenter(extent);
const geom = new ol.geom.Point(center);
return new ol.style.Style({
geometry: geom,
image: new ol.style.Circle({
stroke: strokeCircle,
fill: fillCircle,
radius: radiusCalculation(feature.get('pop_tot'), 0.02)
}),
zIndex: feature.get('rank')
});
};
const vectorLayer = new ol.layer.Vector({
source: vectorLayerSource,
style: styleProportionalCircle,
renderMode: 'image'
});
const rasterLayer = new ol.layer.Tile({
opacity: 0.4,
source: new ol.source.XYZ({
url: 'https://{a-c}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png',
attributions:
'© Openstreetmap France | © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
})
});
const map = new ol.Map({
layers: [rasterLayer, vectorLayer],
controls: ol.control.defaults({
attributionOptions: {
collapsed: false
}
}),
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([2.21298, 46.44362]),
zoom: 6
})
});
const popupElement = document.getElementById('popup');
var popup = new ol.Overlay({
element: popupElement
});
map.addOverlay(popup);
const intlNumberFormat = new Intl.NumberFormat('fr-FR');
var displayFeatureInfo = (pixel, coordinate) => {
var feature = map.forEachFeatureAtPixel(pixel, feature => feature);
if (feature) {
const formated = intlNumberFormat.format(feature.get('pop_tot'));
popupElement.innerHTML = `<b>Département:</b><br>
${feature.get('NOM_DEP')} (${feature.get('INSEE_DEP')})<br>
<b>Population totale</b>:<br>
${formated} habitants (rang ${feature.get('rank')})`;
popup.setPosition(coordinate);
popupElement.style.display = '';
} else {
popupElement.innerHTML = '';
popupElement.style.display = 'none';
}
};
map.on('pointermove', e => {
if (e.dragging) {
popupElement.style.display = 'none';
return;
}
displayFeatureInfo(e.pixel, e.coordinate);
});
const onChangeListener = vectorLayerSource.on('change', async e => {
if (vectorLayerSource.getState() == 'ready') {
ol.Observable.unByKey(onChangeListener);
const response = await fetch('population-insee-2015.csv');
const text = await response.text();
const data = Papa.parse(text, {
header: true
});
const sortedData = data.data
.slice(0)
.filter(ds => ds.code_dept.length < 3)
.sort((a, b) => Number(b.pop_totale) - Number(a.pop_totale))
.map((ds, i) => {
ds.rank = i + 1;
return ds;
});
const hashTable = sortedData.reduce((acc, curr) => {
acc[curr.code_dept] = {
pop_totale: Number(curr.pop_totale),
rank: curr.rank
};
return acc;
}, {});
vectorLayerSource.forEachFeature(feature => {
var codeDept = feature.get('INSEE_DEP');
feature.set('pop_tot', hashTable[codeDept].pop_totale);
feature.set('rank', hashTable[codeDept].rank);
});
generateLegend(vectorLayerSource.getFeatures());
}
});
const generateLegend = features => {
const vals = features.map(el => el.get('pop_tot'));
const max = Math.max(...vals);
const min = Math.min(...vals);
const canvas = document.getElementById('canvas');
var vectorContext = ol.render.toContext(canvas.getContext('2d'), {
size: [140, 80]
});
[min, (min + max) / 3, max]
.slice(0)
.reverse()
.forEach(val => {
const radius = radiusCalculation(val, 0.02);
const text = new ol.style.Text({
offsetX: 60,
offsetY: -radius,
text: `${intlNumberFormat.format(val.toFixed(0))} habs`
});
const newStyle = new ol.style.Style({
image: new ol.style.Circle({
stroke: new ol.style.Stroke({
color: '#ffffff',
width: 1
}),
fill: fillCircle,
radius: radius
}),
text: text
});
vectorContext.setStyle(newStyle);
vectorContext.drawGeometry(new ol.geom.Point([30, 60 - (2 + radius)]));
});
};
code_region,nom_region,code_dept,nom_dept,nb_arrond,nb_cantons,nb_communes,pop_municipale,pop_totale
84,Auvergne-Rhône-Alpes,01,Ain,4,23,408,631877,649012
32,Hauts-de-France,02,Aisne,5,21,804,538659,552529
84,Auvergne-Rhône-Alpes,03,Allier,3,19,317,341613,351626
93,Provence-Alpes-Côte d'Azur,04,Alpes-de-Haute-Provence,4,15,198,161799,166635
93,Provence-Alpes-Côte d'Azur,05,Hautes-Alpes,2,15,167,140916,146060
93,Provence-Alpes-Côte d'Azur,06,Alpes-Maritimes,2,27,163,1082440,1097556
84,Auvergne-Rhône-Alpes,07,Ardèche,3,17,339,324209,333781
44,Grand Est,08,Ardennes,4,19,452,277752,285612
76,Occitanie,09,Ariège,3,13,331,152499,157904
44,Grand Est,10,Aube,3,17,431,309056,316888
76,Occitanie,11,Aude,3,19,436,366957,376667
76,Occitanie,12,Aveyron,3,23,285,279169,290199
93,Provence-Alpes-Côte d'Azur,13,Bouches-du-Rhône,4,29,119,2016622,2045149
28,Normandie,14,Calvados,4,25,538,693579,709986
84,Auvergne-Rhône-Alpes,15,Cantal,3,15,247,146219,151920
75,Nouvelle-Aquitaine,16,Charente,3,19,383,353613,366289
75,Nouvelle-Aquitaine,17,Charente-Maritime,5,27,469,639938,658529
24,Centre-Val de Loire,18,Cher,3,19,290,308992,317101
75,Nouvelle-Aquitaine,19,Corrèze,3,19,283,241871,250077
94,Corse,2A,Corse-du-Sud,2,11,124,152730,155285
94,Corse,2B,Haute-Corse,3,15,236,174553,177438
27,Bourgogne-Franche-Comté,21,Côte-d'Or,3,23,704,533147,546601
53,Bretagne,22,Côtes-d'Armor,4,27,356,598357,618114
75,Nouvelle-Aquitaine,23,Creuse,2,15,258,120365,124569
75,Nouvelle-Aquitaine,24,Dordogne,4,25,520,415417,428032
27,Bourgogne-Franche-Comté,25,Doubs,3,19,578,536959,551143
84,Auvergne-Rhône-Alpes,26,Drôme,3,19,367,504637,519264
28,Normandie,27,Eure,3,23,602,601948,619392
24,Centre-Val de Loire,28,Eure-et-Loir,4,15,375,434035,445361
53,Bretagne,29,Finistère,4,27,279,907796,936292
76,Occitanie,30,Gard,3,23,353,738189,754170
76,Occitanie,31,Haute-Garonne,3,27,588,1335103,1361286
76,Occitanie,32,Gers,3,17,462,190932,198213
75,Nouvelle-Aquitaine,33,Gironde,6,33,538,1548478,1578386
76,Occitanie,34,Hérault,3,25,343,1120190,1140030
53,Bretagne,35,Ille-et-Vilaine,4,27,345,1042884,1070285
24,Centre-Val de Loire,36,Indre,4,13,243,224200,230546
24,Centre-Val de Loire,37,Indre-et-Loire,3,19,273,604966,619651
84,Auvergne-Rhône-Alpes,38,Isère,3,29,521,1251060,1278347
27,Bourgogne-Franche-Comté,39,Jura,3,17,509,260587,270474
75,Nouvelle-Aquitaine,40,Landes,2,15,330,403234,416642
24,Centre-Val de Loire,41,Loir-et-Cher,3,15,276,333050,343392
84,Auvergne-Rhône-Alpes,42,Loire,3,21,326,759411,775977
84,Auvergne-Rhône-Alpes,43,Haute-Loire,3,19,257,227034,234555
52,Pays de la Loire,44,Loire-Atlantique,3,31,212,1365227,1400585
24,Centre-Val de Loire,45,Loiret,3,21,326,673349,691291
76,Occitanie,46,Lot,3,17,322,173400,179573
75,Nouvelle-Aquitaine,47,Lot-et-Garonne,4,21,319,333417,343059
76,Occitanie,48,Lozère,2,13,158,76309,80176
52,Pays de la Loire,49,Maine-et-Loire,4,21,186,810186,833080
28,Normandie,50,Manche,4,27,477,499287,517500
44,Grand Est,51,Marne,5,23,616,572293,585622
44,Grand Est,52,Haute-Marne,3,17,427,179154,184987
52,Pays de la Loire,53,Mayenne,3,17,255,307940,318079
44,Grand Est,54,Meurthe-et-Moselle,4,23,592,734403,748528
44,Grand Est,55,Meuse,3,17,501,190626,196681
53,Bretagne,56,Morbihan,3,21,253,744813,767538
44,Grand Est,57,Moselle,5,27,727,1044486,1064593
27,Bourgogne-Franche-Comté,58,Nièvre,4,17,309,211747,219019
32,Hauts-de-France,59,Nord,6,41,648,2605238,2641081
32,Hauts-de-France,60,Oise,4,21,687,821552,841252
28,Normandie,61,Orne,3,21,394,286618,295936
32,Hauts-de-France,62,Pas-de-Calais,7,39,891,1472648,1496824
84,Auvergne-Rhône-Alpes,63,Puy-de-Dôme,5,31,467,647501,664386
75,Nouvelle-Aquitaine,64,Pyrénées-Atlantiques,3,27,546,670032,690788
76,Occitanie,65,Hautes-Pyrénées,3,17,470,228582,236017
76,Occitanie,66,Pyrénées-Orientales,3,17,226,471038,479421
44,Grand Est,67,Bas-Rhin,5,23,517,1116658,1134800
44,Grand Est,68,Haut-Rhin,4,17,366,762607,777878
84,Auvergne-Rhône-Alpes,69,Rhône,2,13,280,1821995,1852002
27,Bourgogne-Franche-Comté,70,Haute-Saône,2,17,542,237706,245130
27,Bourgogne-Franche-Comté,71,Saône-et-Loire,5,29,567,555408,573281
52,Pays de la Loire,72,Sarthe,3,21,361,568445,583151
84,Auvergne-Rhône-Alpes,73,Savoie,3,19,285,428204,441669
84,Auvergne-Rhône-Alpes,74,Haute-Savoie,4,17,281,793938,816748
11,Île-de-France,75,Paris,1,,1,2206488,2228409
28,Normandie,76,Seine-Maritime,3,35,711,1257699,1283249
11,Île-de-France,77,Seine-et-Marne,5,23,510,1390121,1412250
11,Île-de-France,78,Yvelines,4,21,262,1427291,1454532
75,Nouvelle-Aquitaine,79,Deux-Sèvres,3,17,293,374435,385395
32,Hauts-de-France,80,Somme,4,23,779,571879,584143
76,Occitanie,81,Tarn,2,23,319,386543,398190
76,Occitanie,82,Tarn-et-Garonne,2,15,195,255274,261452
93,Provence-Alpes-Côte d'Azur,83,Var,3,23,153,1048652,1065985
93,Provence-Alpes-Côte d'Azur,84,Vaucluse,3,17,151,557548,569618
52,Pays de la Loire,85,Vendée,3,17,267,666714,685673
75,Nouvelle-Aquitaine,86,Vienne,3,19,274,434887,445927
75,Nouvelle-Aquitaine,87,Haute-Vienne,3,21,200,375795,384226
44,Grand Est,88,Vosges,3,17,507,372016,385043
27,Bourgogne-Franche-Comté,89,Yonne,3,21,428,340903,351302
27,Bourgogne-Franche-Comté,90,Territoire de Belfort,1,9,102,144483,147799
11,Île-de-France,91,Essonne,3,21,196,1276233,1294240
11,Île-de-France,92,Hauts-de-Seine,3,23,36,1601569,1620776
11,Île-de-France,93,Seine-Saint-Denis,3,21,40,1592663,1603095
11,Île-de-France,94,Val-de-Marne,3,25,47,1372389,1384068
11,Île-de-France,95,Val-d'Oise,3,21,185,1215390,1231356
01,Guadeloupe,971,Guadeloupe,2,21,32,397990,404542
02,Martinique,972,Martinique,4,,34,380877,386875
03,Guyane,973,Guyane,2,,22,259865,262381
04,La Réunion,974,La Réunion,4,25,24,850727,860896