Ô nhiễm không khí do bụi mịn PM2.5 khiến mỗi người dân Hà Nội chịu tổn hại sức khỏe tương đương việc hút thụ động hai điếu thuốc lá mỗi ngày.
Người Hà Nội 'hút' thụ động bao nhiêu điếu thuốc mỗi ngày?
Người Hà Nội 'hút'
thụ động bao nhiêu điếu thuốc mỗi ngày?
Ô nhiễm không khí do bụi mịn PM2.5 khiến mỗi người dân Hà Nội
chịu tổn hại sức khỏe tương đương việc hút thụ động hai điếu
thuốc lá mỗi ngày.
Hà Nội đang trong đợt ô nhiễm không khí thứ ba kể từ đầu mùa, bắt
đầu hôm 28/11 và dự báo kéo dài đến 5/12, theo mô hình dự báo chất
lượng không khí ứng dụng trí tuệ nhân tạo (HanoiAir) của
nhóm nghiên cứu Địa không gian thông minh (GEOI), Trường Đại
học Công nghệ - Đại học Quốc gia Hà Nội.
Theo đó, chỉ số AQI trung bình toàn thành phố hôm qua là 143 -
ngưỡng kém, tương ứng nồng độ PM2.5 mức 77 µg/m³ - gấp 5 lần
khuyến nghị của Tổ chức Y tế Thế giới (WHO) - 15 µg/m³.
Ba trạm đo tại Hà Nội trong hệ thống quan trắc của Cục Môi trường
(Bộ Nông nghiệp và Môi trường) cũng ghi nhận chỉ số AQI liên tục
tăng lên mức xấu đến rất xấu. Chỉ số này phản ánh trực tiếp nồng
độ PM2.5 - chất gây ô nhiễm chính.
Theo một nghiên cứu từ năm 2015 của Berkeley Earth, tổ
chức nghiên cứu khoa học khí hậu độc lập có trụ sở tại Mỹ, hít thở
không khí có nồng độ PM2.5 ở mức 22 µg/m³ trong 24 giờ, phổi và
tim mạch chịu tổn thương tương tự hút một điếu thuốc. Mức PM2.5
theo khuyến nghị của WHO là 15 µg/m³ (tương đương hút 0,7 điếu
thuốc). Đây là quy đổi dựa trên mức độ tổn hại sức khoẻ, không
phải về thành phần hoá học giữa thuốc lá và bụi mịn.
Dựa trên dữ liệu nồng độ PM2.5 trung bình năm 2024 theo phường, xã
(sau sáp nhập) do nhóm nghiên cứu GEOI cung cấp,
VnExpress quy đổi mức độ ô nhiễm không khí với ảnh hưởng
sức khoẻ tương đương lượng thuốc lá tiêu thụ. Theo đó, người dân
Hà Nội "hút" thụ động trung bình hai điếu thuốc mỗi ngày, tương
đương nồng độ PM2.5 là 41 µg/m³.
Độc giả có thể tìm theo vị trí, theo phường xã, hoặc chọn khu vực
bất kỳ trên bản đồ để xem chi tiết.
Hít thở không khí ô nhiễm tại Hà Nộitương đương hút ... điếu thuốc.
Nồng độ PM2.5 trung bình ngày là ... µg/m³ |
Có ... người chịu ảnh hưởng.
Bản đồ chất lượng không khí 2024
Thông tin dữ liệu
Dữ liệu chất lượng không khí trung bình năm theo phường, xã được tính toán bởi nhóm nghiên cứu GEOI (Trường Đại học Công nghệ, Đại học Quốc gia Hà Nội).
Quy đổi sang số điếu thuốc do VnExpress thực hiện, dựa trên nghiên cứu của Berkeley Earth. Trong đó, mỗi điếu thuốc một ngày tương đương khoảng 22 µg/m³ nồng độ PM2.5.
Dữ liệu dân số và ranh giới phường xã từ NXB Tài nguyên - Môi trường và Bản đồ Việt Nam. Bản đồ nền của Google Satellite.
Xếp hạng
Tệ nhất
Tốt nhất
Tên
AQI ▼
PM2.5 (ug/m³)
Dân số
Trang 1
PM2.5: ${formatNum(
props.pm25,
1
)} µg/m³
AQI: ${Math.round(
props.aqi
)}
`,
{ sticky: true }
);
l.on("click", L.DomEvent.stopPropagation);
l.on("click", () =>
selectWard(
AppState.featureIndexByName.get(
getProps(f.properties).name.toLowerCase()
),
true
)
);
l.on("mouseover", () => {
if (AppState.highlightedLayer !== l)
l.setStyle({ weight: 2, opacity: 1 });
});
l.on("mouseout", () => {
if (AppState.highlightedLayer !== l)
AppState.geoJsonLayer.resetStyle(l);
});
},
}).addTo(AppState.map);
AppState.hanoiBounds = AppState.geoJsonLayer.getBounds();
const isMobile = window.innerWidth < 768;
const padding = isMobile
? [
AppState.map.getSize().x * 0.1,
AppState.map.getSize().y * 0.1,
]
: [0, 0];
AppState.map.fitBounds(AppState.hanoiBounds, {
padding: padding,
});
}
// --- CORE LOGIC ---
function selectWard(index, isUserAction = false) {
if (index === undefined || index < 0) return;
const feature = AppState.wardData.features[index];
const layer = AppState.geoJsonLayer.getLayers()[index]; // Assuming sequential
const p = getProps(feature.properties);
if (isUserAction) {
AppState.userInteracted = true;
stopAnimation();
els.wardSearch.value = p.name;
els.clearSearch.classList.remove("hidden");
els.wardSuggestions.classList.add("hidden");
}
// UI Updates
AppState.currentBaseCigs = p.pm25 / 22;
updateCigDisplay();
document.getElementById("pm25-value").innerText = formatNum(
p.pm25,
1
);
els.popInfo.innerText = `Có ${
p.pop > 0 ? p.pop.toLocaleString("vi-VN") : "..."
} người chịu ảnh hưởng.`;
if (isUserAction) {
els.wardName.innerText = p.name;
els.typingCursor.classList.remove("is-typing");
} else {
animateTyping(p.name);
}
// Map Updates
if (AppState.highlightedLayer)
AppState.geoJsonLayer.resetStyle(AppState.highlightedLayer);
if (layer) {
layer.setStyle({
color: "#e85d04",
weight: 3,
opacity: 1,
fillOpacity: 0.8,
});
AppState.highlightedLayer = layer;
if (isUserAction && AppState.map) {
const isMobile = window.innerWidth < 768;
const mapSize = AppState.map.getSize();
const padding = isMobile
? [mapSize.x * 0.1, mapSize.y * 0.1]
: [50, 50];
AppState.map.fitBounds(layer.getBounds(), {
padding: padding,
maxZoom: 14,
});
}
layer.bringToFront(); // Bring to front after fitting bounds
}
}
function updateCigDisplay() {
const val =
AppState.currentBaseCigs *
CONFIG.multipliers[AppState.currentMode];
els.cigs.innerText = formatNum(val, 1);
}
// --- ANIMATION & SEARCH ---
function animateTyping(text) {
if (AppState.typingId) clearInterval(AppState.typingId);
els.wardName.innerText = "";
els.typingCursor.classList.add("is-typing");
let i = 0;
AppState.typingId = setInterval(() => {
if (i < text.length)
els.wardName.textContent += text.charAt(i++);
else clearInterval(AppState.typingId);
}, 50);
}
function startAnimation() {
if (AppState.userInteracted) return;
let idx = 0;
// Sort by population desc for animation importance
const popSorted = [...AppState.rankingData].sort(
(a, b) => b.pop - a.pop
);
if (popSorted.length) selectWard(popSorted[0].originalIndex); // Initial
AppState.animationId = setInterval(() => {
idx = (idx + 1) % popSorted.length;
selectWard(popSorted[idx].originalIndex);
}, 4000);
}
function stopAnimation() {
clearInterval(AppState.animationId);
clearInterval(AppState.typingId);
els.typingCursor.classList.remove("is-typing");
}
// --- RAY CASTING (Point in Polygon) ---
// Replacement for Turf.js to reduce weight
function isPointInFeature(pt, feature) {
const geometry = feature.geometry;
if (geometry.type === "Polygon") {
return isPointInPoly(pt, geometry.coordinates);
} else if (geometry.type === "MultiPolygon") {
return geometry.coordinates.some((poly) =>
isPointInPoly(pt, poly)
);
}
return false;
}
function isPointInPoly(pt, poly) {
// Check main ring (index 0)
const ring = poly[0];
let x = pt[0],
y = pt[1];
let inside = false;
for (
let i = 0, j = ring.length - 1;
i < ring.length;
j = i++
) {
let xi = ring[i][0],
yi = ring[i][1];
let xj = ring[j][0],
yj = ring[j][1];
let intersect =
yi > y != yj > y &&
x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
if (intersect) inside = !inside;
}
return inside;
}
function locateUser() {
if (!navigator.geolocation)
return showMessage(
"Trình duyệt không hỗ trợ định vị.",
"error"
);
showMessage("Đang tìm vị trí...", "info");
navigator.geolocation.getCurrentPosition(
(pos) => {
const pt = [pos.coords.longitude, pos.coords.latitude];
const foundIndex = AppState.wardData.features.findIndex(
(f) => isPointInFeature(pt, f)
);
if (foundIndex !== -1) {
selectWard(foundIndex, true);
} else {
showMessage(
"Bạn đang ở ngoài khu vực dữ liệu.",
"warn"
);
}
},
() => showMessage("Không thể truy cập vị trí.", "error")
);
}
// --- EVENTS SETUP ---
function setupEvents() {
// Mode Switching
els.modeBtns.forEach((btn) =>
btn.addEventListener("click", () => {
AppState.currentMode = btn.dataset.mode;
els.modeBtns.forEach((b) => {
const active = b.dataset.mode === AppState.currentMode;
b.className = `mode-btn px-4 py-1.5 rounded-md text-sm font-bold transition-all duration-200 ${
active
? "bg-white text-orange-600 shadow-sm ring-1 ring-gray-200"
: "text-gray-400 hover:text-gray-600"
}`;
});
updateCigDisplay();
})
);
// Search Box (Debounced)
els.wardSearch.addEventListener(
"input",
debounce((e) => {
const v = e.target.value.toLowerCase().trim();
els.clearSearch.classList.toggle("hidden", !v);
if (!v) {
els.wardSuggestions.innerHTML = "";
els.wardSuggestions.classList.add("hidden");
return;
}
const matches = AppState.suggestionSource
.filter((s) => s.norm.includes(v))
.slice(0, 5);
let html = ``;
if (matches.length) {
html += matches
.map(
(m) =>
`
Chưa có bình luận nào.