Files
WebGIS_Project/03/choropleth.html
T

275 lines
6.0 KiB
HTML

<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WebGIS Choropleth Kota Pontianak</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<style>
html,body{
margin:0;
padding:0;
height:100%;
font-family:Arial, Helvetica, sans-serif;
}
#map{
width:100%;
height:100%;
}
.info{
padding:10px 14px;
background:white;
box-shadow:0 0 15px rgba(0,0,0,0.2);
border-radius:10px;
line-height:1.5;
}
.info h4{
margin:0 0 8px;
color:#444;
}
.legend{
background:white;
padding:10px;
line-height:18px;
color:#555;
border-radius:10px;
box-shadow:0 0 15px rgba(0,0,0,0.2);
}
.legend i{
width:18px;
height:18px;
float:left;
margin-right:8px;
opacity:0.8;
}
.titlebox{
position:absolute;
top:10px;
left:50%;
transform:translateX(-50%);
z-index:999;
background:#0d6efd;
color:white;
padding:10px 18px;
border-radius:10px;
font-weight:bold;
}
.selector{
position:absolute;
top:60px;
left:10px;
z-index:999;
background:white;
padding:10px;
border-radius:10px;
box-shadow:0 0 10px rgba(0,0,0,0.2);
}
</style>
</head>
<body>
<div class="titlebox">WEBGIS CHOROPLETH KOTA PONTIANAK</div>
<div class="selector">
<b>Pilih Tema:</b><br>
<select id="mode" onchange="updateMap()">
<option value="density">Kepadatan Penduduk</option>
<option value="population">Jumlah Penduduk</option>
</select>
</div>
<div id="map"></div>
<script src="pontianak-state.js"></script>
<script>
const map = L.map('map').setView([-0.03,109.34],12);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png',{
maxZoom:19,
attribution:'&copy; OpenStreetMap'
}).addTo(map);
let geojson;
/* ======================
INFO PANEL
====================== */
const info = L.control();
info.onAdd = function(){
this._div = L.DomUtil.create('div','info');
this.update();
return this._div;
};
info.update = function(props){
let mode = document.getElementById("mode").value;
if(props){
this._div.innerHTML = `
<h4>Data Kecamatan</h4>
<b>${props.name}</b><br>
Kepadatan : ${props.density.toLocaleString()} jiwa/km²<br>
Penduduk : ${props.population.toLocaleString()} jiwa`;
}else{
this._div.innerHTML = `<h4>${mode=="density"?"Kepadatan":"Penduduk"}</h4>Arahkan cursor ke wilayah`;
}
};
info.addTo(map);
/* ======================
WARNA
====================== */
function getColorDensity(d){
return d > 10000 ? '#800026' :
d > 8000 ? '#BD0026' :
d > 6000 ? '#E31A1C' :
d > 5000 ? '#FC4E2A' :
d > 4000 ? '#FD8D3C' :
d > 3000 ? '#FEB24C' :
'#FED976';
}
function getColorPopulation(d){
return d > 120000 ? '#00441b' :
d > 100000 ? '#006d2c' :
d > 80000 ? '#238b45' :
d > 60000 ? '#41ab5d' :
d > 50000 ? '#74c476' :
d > 40000 ? '#a1d99b' :
'#c7e9c0';
}
function style(feature){
let mode = document.getElementById("mode").value;
return {
weight:2,
opacity:1,
color:'white',
dashArray:'3',
fillOpacity:0.75,
fillColor:
mode=="density"
? getColorDensity(feature.properties.density)
: getColorPopulation(feature.properties.population)
};
}
/* ======================
INTERAKSI
====================== */
function highlightFeature(e){
const layer = e.target;
layer.setStyle({
weight:4,
color:'#222',
dashArray:'',
fillOpacity:0.9
});
layer.bringToFront();
info.update(layer.feature.properties);
}
function resetHighlight(e){
geojson.resetStyle(e.target);
info.update();
}
function zoomToFeature(e){
map.fitBounds(e.target.getBounds());
}
function onEachFeature(feature, layer){
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature
});
layer.bindPopup(`
<b>${feature.properties.name}</b><br>
Kepadatan : ${feature.properties.density.toLocaleString()} jiwa/km²<br>
Penduduk : ${feature.properties.population.toLocaleString()} jiwa
`);
}
/* ======================
LOAD DATA
====================== */
geojson = L.geoJson(statesData,{
style:style,
onEachFeature:onEachFeature
}).addTo(map);
map.fitBounds(geojson.getBounds());
/* ======================
LEGENDA
====================== */
const legend = L.control({position:'bottomright'});
legend.onAdd = function(){
this._div = L.DomUtil.create('div','legend');
this.update();
return this._div;
};
legend.update = function(){
let mode = document.getElementById("mode").value;
let grades, labels=[];
if(mode=="density"){
grades=[0,3000,4000,5000,6000,8000,10000];
for(let i=0;i<grades.length;i++){
let from=grades[i];
let to=grades[i+1];
labels.push(
'<i style="background:'+getColorDensity(from+1)+'"></i> '+
from+(to?'&ndash;'+to:'+')
);
}
this._div.innerHTML="<b>Kepadatan</b><br>"+labels.join("<br>");
}else{
grades=[0,40000,50000,60000,80000,100000,120000];
for(let i=0;i<grades.length;i++){
let from=grades[i];
let to=grades[i+1];
labels.push(
'<i style="background:'+getColorPopulation(from+1)+'"></i> '+
from+(to?'&ndash;'+to:'+')
);
}
this._div.innerHTML="<b>Penduduk</b><br>"+labels.join("<br>");
}
};
legend.addTo(map);
/* ======================
UPDATE MAP
====================== */
function updateMap(){
geojson.setStyle(style);
legend.update();
info.update();
}
</script>
</body>
</html>