Files
2026-06-11 16:37:05 +07:00

163 lines
14 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<base target="_top">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Kepadatan Penduduk Pontianak</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.9.0/proj4.js"></script>
<style>
html, body {
height: 100%;
margin: 0;
}
#map {
width: 100%;
height: 100vh;
}
.info {
padding: 6px 8px;
font: 14px/16px Arial, Helvetica, sans-serif;
background: rgba(255,255,255,0.85);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
}
.info h4 { margin: 0 0 5px; color: #777; }
.legend { text-align: left; line-height: 22px; color: #555; }
.legend i { width: 18px; height: 18px; float: left; margin-right: 8px; opacity: 0.7; }
</style>
</head>
<body>
<div id="map"></div>
<script>
// ── 1. Register UTM Zone 49N (covers Pontianak at ~109°E) ──────────────────
proj4.defs('EPSG:32649', '+proj=utm +zone=49 +datum=WGS84 +units=m +no_defs');
// Convert a ring of [easting, northing] pairs → [lng, lat]
function convertRings(rings) {
return rings.map(ring =>
ring.map(([x, y]) => proj4('EPSG:32649', 'WGS84', [x, y]))
);
}
// ── 2. Raw data (UTM coords) ───────────────────────────────────────────────
var rawData = {
type: "FeatureCollection",
features: [
{ type:"Feature", id:"1", properties:{ name:"Pontianak Selatan", density:5.673 }, geometry:{ type:"Polygon", coordinates:[[[315791.7496880172,-2872.6773100267],[315493.9173600795,-3043.9080895001625],[315326.6521934429,-3151.333180362999],[315140.4188381387,-3281.935194921576],[315066.9918184001,-3327.8058926928916],[314996.8467820659,-3371.6262979517323],[314888.67104393616,-3478.080758171731],[314812.70706351567,-3552.7994604061805],[314746.1257071411,-3618.2893480278017],[314655.6433510417,-3707.2884260803185],[314606.10591966007,-3756.013789919325],[314454.0137261031,-3905.612734831022],[314344.4320643814,-3996.3010035972147],[314259.6778418068,-4066.4424268491857],[314085.032268201,-4210.976689869447],[313840.1791924136,-4413.613711391907],[313536.192724674,-4712.359024276697],[313300.8322324334,-4943.661570138169],[312916.42216176353,-5321.443869765168],[312612.50988089014,-5620.11627486908],[312370.45105957426,-5854.688712254208],[312057.7659053877,-6157.703154576355],[311585.92455374077,-6614.9514189124275],[311333.4393242495,-6891.340090787351],[313474.832878937,-8889.931704557468],[313757.1209584046,-8461.458752544078],[314215.6677178042,-7765.450320278544],[314471.81653076597,-7473.440609211619],[314877.1271904595,-7011.386355436478],[315170.0992892701,-6667.707583206353],[315565.04540335014,-6204.405459439875],[315762.9765556948,-5956.206301724727],[315946.9456108697,-5783.346926725002],[316115.1479424136,-5571.442019498811],[316233.71287194826,-5370.136871324419],[316413.0633267751,-5142.274731615995],[316588.3382888399,-4973.07120414943],[315803.17076956015,-2870.648806607189],[315791.7496880172,-2872.6773100267]]] } },
{ type:"Feature", id:"2", properties:{ name:"Pontianak Utara", density:3.642 }, geometry:{ type:"Polygon", coordinates:[[[309688.2266975902,951.2434479881485],[310155.9051329456,933.8867466094162],[310357.96077316906,885.1327602118836],[311332.6877226224,552.8154289115046],[312269.31459587533,306.7524367839651],[313016.67581282463,28.516046978937084],[313225.22203908674,-84.19626616407731],[313546.372705549,-322.5867385597503],[313720.9980547987,-448.5286571102988],[314170.79062105156,-811.0085487379129],[314504.16628780216,-895.1462170118866],[314775.1001630025,-1443.89314784007],[315291.5124306837,-1928.5005853951407],[315734.48124843184,-2324.9574099686342],[316159.40293160826,-2368.349163418803],[316654.17475448735,-2251.9322639187267],[317038.8796905633,-2161.4445829436972],[317913.59393999074,-2046.6151866172168],[318283.48217976745,-2054.023534766595],[318775.15660756174,-2147.859083549327],[319287.81429954246,-2395.9329130315673],[319416.881835456,-2033.8234388107558],[319526.1020538965,-1800.9896398106011],[319533.72206913494,-1723.0961506912936],[319510.86202341504,-1622.342615849966],[319574.3621504167,-1479.2556630090148],[319598.91553285625,-1507.1957188887664],[319482.0752991745,-1853.4830781301353],[319424.3083182946,-874.973119525288],[319320.91374074016,-644.5676602992062],[318847.9647948425,226.72111005606712],[318658.4169157464,989.0401346929066],[316567.76460495684,2999.9040346896763],[314562.85392847005,3541.7717850915287],[312083.8089703787,4381.666798215181],[309688.2266975902,951.2434479881485]]] } },
{ type:"Feature", id:"3", properties:{ name:"Pontianak Timur", density:9.196 }, geometry:{ type:"Polygon", coordinates:[[[319887.57044806925,-5373.344392278639],[319702.88422977563,-5132.534790727044],[319580.270434435,-4979.559484159208],[319416.78537397756,-4779.407060143594],[319288.3328264768,-4635.773757029033],[319063.0274988217,-4397.196101115128],[318712.6388119413,-4027.525809986318],[319240.45505877363,-3500.8371123406214],[319482.70326267194,-3416.1079811805625],[319930.7033710063,-3290.5899437818016],[320060.2158619128,-2885.3158597254237],[319668.47127330344,-2832.0761712812755],[319302.34583165945,-2724.1663001296456],[319016.246975861,-2582.2846226671395],[318611.86326987745,-2402.6633110638345],[318312.0934654712,-2349.9022867323624],[317831.7500457056,-2325.396742533832],[317450.6828969274,-2376.0793589098607],[316961.72475783527,-2448.1651844011494],[316290.7174679831,-2617.4144481542617],[315891.63306421525,-2646.1325691096436],[316108.6562515756,-3080.1789438243754],[316374.4062489303,-3648.9273296033716],[316666.3438568887,-4078.0756132950055],[316960.2915036416,-4459.3151686055135],[317511.1983193059,-4982.14799761562],[318003.96436076245,-5498.157720267835],[318525.46364961116,-6295.854170744091],[318997.8492128665,-6873.389132317587],[319200.2395574156,-6725.148423245205],[319464.4036415865,-6506.445073789114],[319929.8147521868,-6173.089029280636],[320230.3441586008,-5948.45374608942],[319892.69977100904,-5382.870277737669],[319887.57044806925,-5373.344392278639]]] } },
{ type:"Feature", id:"4", properties:{ name:"Pontianak Tenggara", density:3.103 }, geometry:{ type:"Polygon", coordinates:[[[316509.95719540527,-5101.833566810722],[316277.42321839795,-5368.326560621595],[315586.95250728936,-6227.493567962928],[314650.4343267438,-7312.870467518172],[313943.0478521116,-8266.304411587676],[313570.5827409144,-8808.522535934284],[314482.8144881896,-9756.429398367298],[315386.15532470803,-10595.173154648382],[315969.86388160125,-10324.183934093831],[316202.0711808827,-9921.28120289028],[316389.8178299225,-9632.15192111897],[316955.59155603434,-8811.299556391281],[317370.6954695009,-8105.002669764531],[318021.28465803474,-6941.185008999439],[318253.2629668124,-6576.773915689321],[318236.68267524854,-6280.690804057879],[317914.4077884978,-5744.010290518615],[317403.09039107355,-5217.314926254428],[316771.0250557211,-4765.816074840871],[316509.95719540527,-5101.833566810722]]] } },
{ type:"Feature", id:"5", properties:{ name:"Pontianak Kota", density:8.102 }, geometry:{ type:"Polygon", coordinates:[[[310276.47296142485,-3455.9797973638633],[309858.4304809589,-3797.2929687509313],[309527.70056152344,-4114.79357910133],[309256.67931494024,-4394.240588930203],[309517.11724853516,-4686.294799805153],[309900.76403808687,-5093.753967286088],[310421.994140625,-5638.796691895346],[310977.62023925874,-6427.256591796759],[311295.12091064546,-6863.819946288946],[311784.60089111235,-6451.0691528309835],[312297.8936767578,-5916.60974120989],[312922.31152343843,-5310.71270752023],[313407.04170880467,-4843.868031024118],[313851.00109863374,-4424.356750487466],[314247.8766479511,-4080.397766113165],[314713.5443115253,-3659.709350586054],[315263.87866211124,-3191.395935058943],[315803.6297607431,-2876.541137695778],[315533.75421142764,-2532.582153319032],[315086.40909403935,-2251.8851285779383],[314597.12731933594,-1876.4141235346906],[314187.02246093843,-2037.810302733793],[313546.7294311533,-2148.9354858405422],[312935.5408325214,-2270.64410400379],[312366.6854858408,-2413.519348145579],[311906.3095092783,-2564.3322143565165],[311385.0793457031,-2783.936767577892],[310773.8905639658,-3093.4998779299203],[310276.47296142485,-3455.9797973638633]]] } },
{ type:"Feature", id:"6", properties:{ name:"Pontianak Barat", density:9.331 }, geometry:{ type:"Polygon", coordinates:[[[314496.5855712909,-1831.4348754876992],[314333.6083123619,-1673.1813620609464],[313976.42009798624,-1469.4517879342893],[313709.19039686024,-1196.9304095584666],[313412.8564708587,-1024.9508989329915],[313156.21012423374,-776.2420681805816],[312690.5425262293,-424.3455310544232],[312129.62473772746,-204.74092517967802],[311526.37353122514,-96.26154155412223],[310896.6639384739,-149.17831405519973],[310303.9960864708,-154.46999130456243],[309732.49494346976,70.42629182199016],[309351.49418146536,70.42629182199016],[309319.74411796685,-400.5329834310105],[309364.7233745931,-715.3877798067406],[309351.49418146536,-974.679965057876],[309232.4314433411,-1506.493528684834],[309176.8688322166,-1879.5567748110043],[309205.97305709217,-2040.952930937754],[308552.45091671497,-2472.2246268143645],[308147.6376070874,-3011.9757063165307],[308430.74233996496,-3734.289650943014],[308827.6181337144,-4363.999243696919],[309142.47293009236,-4490.9994976965245],[309479.5459254207,-4168.759302856284],[310007.24186643306,-3657.238962248084],[310429.9315185547,-3344.854614257114],[310773.8905639658,-3093.4998779299203],[311336.9246401787,-2797.156559649622],[311906.3095092783,-2564.3322143565165],[312525.43572998233,-2360.602661131881],[313125.56844345294,-2227.800214529503],[313970.063720705,-2077.4978637696477],[314456.89801025484,-1908.1641845697304],[314496.5855712909,-1831.4348754876992]]] } }
]
};
// ── 3. Reproject every feature to WGS84 ───────────────────────────────────
var statesData = {
type: "FeatureCollection",
features: rawData.features.map(function(f) {
return Object.assign({}, f, {
geometry: Object.assign({}, f.geometry, {
coordinates: convertRings(f.geometry.coordinates)
})
});
})
};
// ── 4. Map & tiles ─────────────────────────────────────────────────────────
const map = L.map('map').setView([-0.03, 109.33], 12);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
// ── 5. Hover info box ──────────────────────────────────────────────────────
const info = L.control();
info.onAdd = function() {
this._div = L.DomUtil.create('div', 'info');
this.update();
return this._div;
};
info.update = function(props) {
const contents = props
? `<b>${props.name}</b><br />${props.density} ribu jiwa / km<sup>2</sup>`
: 'Arahkan kursor ke kecamatan';
this._div.innerHTML = `<h4>Kepadatan Penduduk Pontianak</h4>${contents}`;
};
info.addTo(map);
// ── 6. Three-level colour scale ────────────────────────────────────────────
// Rendah (low) : ≤ 5 → light yellow
// Sedang (medium) : 57 → orange
// Tinggi (high) : > 7 → red
function getColor(d) {
return d > 7 ? '#E31A1C'
: d > 5 ? '#FD8D3C'
: '#d3ffa0';
}
function style(feature) {
return {
weight: 2, opacity: 1, color: 'white', dashArray: '3',
fillOpacity: 0.7,
fillColor: getColor(feature.properties.density)
};
}
// ── 7. Interaction ─────────────────────────────────────────────────────────
function highlightFeature(e) {
const layer = e.target;
layer.setStyle({ weight: 5, color: '#666', dashArray: '', fillOpacity: 0.7 });
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 });
}
const geojson = L.geoJson(statesData, { style, onEachFeature }).addTo(map);
// Auto-fit the map to the actual data extent
map.fitBounds(geojson.getBounds());
map.attributionControl.addAttribution(
'Data penduduk &copy; <a href="https://pontianakkota.bps.go.id/">BPS Kota Pontianak</a>'
);
// ── 8. Legend ──────────────────────────────────────────────────────────────
const legend = L.control({ position: 'bottomright' });
legend.onAdd = function() {
const div = L.DomUtil.create('div', 'info legend');
const levels = [
{ threshold: 0, label: '≤ 5 (Rendah)' },
{ threshold: 5, label: '5 7 (Sedang)' },
{ threshold: 7, label: '> 7 (Tinggi)' }
];
levels.forEach(({ threshold, label }) => {
div.innerHTML +=
`<i style="background:${getColor(threshold + 0.1)}"></i> ${label}<br>`;
});
div.innerHTML += '<small>ribu jiwa / km²</small>';
return div;
};
legend.addTo(map);
</script>
</body>
</html>