如何用Node.js构建DeLandslide滑坡监测系统?

来源:Reactjs教程作者:会飞的猪头衔:草根站长
导读:本期聚焦于会飞的猪创作的《如何用Node.js构建DeLandslide滑坡监测系统?》,敬请观看详情。山区边坡的微小位移如果未能及时发现,可能在降雨后迅速发展成滑坡,威胁道路和居民区。DeLandslide滑坡监测系统通过倾角、位移和雨量传感器持续采集现场数据,由Node.js服务端统一接收、解析和存储。相比传统人工巡检,这套做法能实现分钟级异常识别,并把预警消息实时推送给值班人员。本文不讨论硬件选型细节,而是重点说明如何用Express搭建数据接入接口,用Socket.IO完成浏览器端告警推送,再结合SQLite保存历史记录,最后给出一个可运行的核心示例。读者可以根据实际传感器协议调整字段,快速得到一套轻量级的地质灾害监测后端原型。

滑坡监测通常依赖多种传感器协同工作,包括倾角计、裂缝计、雨量计和GPS位移站。这些设备按照固定频率上报数据,后端需要具备高并发接入、异常识别和实时告警能力。Node.js事件驱动模型适合处理大量短连接和消息推送,下面围绕DeLandslide监测系统给出核心实现。

如何用Node.js构建DeLandslide滑坡监测系统?

系统整体架构与数据流设计

DeLandslide监测系统可以划分为采集层、服务层、存储层和展示层。采集层由分布在边坡上的传感器节点组成,它们通过4G或LoRa网关将数据发送到服务端。服务层使用Node.js搭建,负责接收HTTP请求、校验数据格式、判断预警等级并通过Socket.IO实时推送。存储层采用SQLite保存历史位移和雨量记录,便于后续趋势分析。展示层是一个浏览器页面,利用图表库绘制曲线,同时监听WebSocket消息更新预警状态。

传感器数据通常以JSON格式上报,一个典型的数据包包含设备编号、位移量、倾角、降雨量和电池电压。例如设备编号为SLOPE-01的节点可能发送如下结构:deviceId字段用来标识传感器,displacement表示累计位移毫米数,angle表示倾斜角度,rainfall表示小时降雨量。服务端把这些字段解析后写入数据库,再根据规则判断是否需要触发告警。这种分层设计让硬件接入和后端逻辑解耦,后续增加新类型传感器时只需要扩展数据字段,不需要改写核心推送逻辑。

选择Node.js作为服务端的原因在于其非阻塞I/O特性。一个滑坡监测点可能同时连接几十甚至上百个传感器,传统同步模型容易在数据库写入或网络请求处形成瓶颈。Node.js可以在等待磁盘或网络操作时继续处理其他请求,配合Socket.IO的长连接机制,能够把报警信息在毫秒级内广播给所有在线客户端。对于中小规模的地质灾害监测项目,这种单进程架构已经足够稳定,也可以通过PM2启动多个实例来应对更高负载。

搭建数据接收与实时推送服务

首先初始化一个Node.js项目并安装依赖,需要用到express处理HTTP接口,socket.io实现实时通信,以及better-sqlite3完成本地数据存储。服务启动后会创建一个名为delandslide.db的SQLite文件,并在首次运行时自动建立记录表。数据库表的字段与传感器上报结构一一对应,同时增加自增主键和创建时间,方便按时间范围查询。

核心代码如下,它实现了POST /api/sensor/data接口,接收传感器数据后立即写入数据库,并根据位移和倾角是否超过阈值决定推送普通更新还是滑坡告警。Socket.IO服务通过io.emit把消息分发给所有已连接的浏览器客户端。

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const Database = require('better-sqlite3');
const db = new Database('delandslide.db');
db.exec(`CREATE TABLE IF NOT EXISTS records (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  device_id TEXT NOT NULL,
  displacement REAL,
  angle REAL,
  rainfall REAL,
  created_at TEXT DEFAULT (datetime('now','localtime'))
)`);
const app = express();
app.use(express.json());
const server = http.createServer(app);
const io = socketIo(server, { cors: { origin: '*' } });
const WARN_DISPLACEMENT = 5.0;
const WARN_ANGLE = 1.5;
app.post('/api/sensor/data', (req, res) => {
  const { deviceId, displacement = 0, angle = 0, rainfall = 0 } = req.body;
  if (!deviceId) {
    return res.status(400).json({ ok: false, message: '缺少设备编号' });
  }
  const stmt = db.prepare('INSERT INTO records (device_id, displacement, angle, rainfall) VALUES (?, ?, ?, ?)');
  stmt.run(deviceId, displacement, angle, rainfall);
  const level = displacement > WARN_DISPLACEMENT || angle > WARN_ANGLE ? 'warning' : 'normal';
  const payload = { deviceId, displacement, angle, rainfall, level, time: new Date().toISOString() };
  if (level === 'warning') {
    io.emit('landslide-alert', payload);
  } else {
    io.emit('sensor-update', payload);
  }
  res.json({ ok: true, level });
});
app.get('/api/records', (req, res) => {
  const rows = db.prepare('SELECT * FROM records ORDER BY id DESC LIMIT 50').all();
  res.json(rows);
});
io.on('connection', (socket) => {
  console.log('客户端已连接:' + socket.id);
});
server.listen(3000, () => {
  console.log('DeLandslide 监测服务运行在 3000 端口');
});

这段代码中,displacement > WARN_DISPLACEMENTangle > WARN_ANGLE是两个基础判断条件,只要满足其中一个,服务端就会把级别标记为warning并通过landslide-alert事件广播。如果数据正常,则广播sensor-update事件,前端可以据此刷新实时曲线。为了让数据库操作不会阻塞事件循环,实际项目中还可以把数据库写入放到队列中异步执行,但中小规模场景下直接同步写入已经足够快。

滑坡预警阈值判断与分级策略

单一阈值判断只能区分正常和异常,难以适应不同风险等级的通知需求。实际滑坡监测中,位移速率、累计位移和降雨强度往往需要组合评估。例如持续降雨会导致土壤含水率升高,即使当前位移不大,也可能在短时间内发生突变。因此预警逻辑最好采用多级策略,根据多个指标综合判断风险等级。

下面给出一个简单的分级函数,它把位移、倾角和雨量分别设置不同档位,只要任意指标达到更高一级阈值,就返回对应颜色预警。这样后端可以在写入数据后调用该函数,把返回的级别附加到推送消息中,方便前端显示不同颜色的告警卡片。

function evaluateRisk(displacement, angle, rainfall) {
  if (displacement >= 20 || angle >= 5 || rainfall >= 100) {
    return '红色预警';
  }
  if (displacement >= 10 || angle >= 3 || rainfall >= 60) {
    return '橙色预警';
  }
  if (displacement >= 5 || angle >= 1.5 || rainfall >= 30) {
    return '黄色预警';
  }
  return '正常';
}

实际部署时,这些阈值不能直接照搬,需要根据边坡的地质条件、历史位移数据和当地降雨特征进行调整。比如某些地区常年降雨量大,雨量阈值可以适当提高,避免频繁误报。反过来,对于已经出现明显裂缝的边坡,位移阈值应该调低,以便更早发现加速变形。预警级别可以通过配置表或环境变量管理,而不是硬编码在代码中,这样现场维护人员无需修改程序就能调整规则。

历史数据查询与前端可视化

前端大屏通常需要同时展示实时数据和历史趋势。服务端已经提供了/api/records接口,返回最近50条记录。页面加载时可以先请求该接口绘制初始曲线,之后通过Socket.IO监听sensor-update事件把新数据追加到图表尾部。当收到landslide-alert事件时,页面应触发醒目的视觉提醒,比如红色边框闪烁或声音报警。

一个简化的前端页面如下,它引入Socket.IO客户端脚本,连接服务端后分别处理两个事件。landslide-alert会把状态栏文字改为预警信息,sensor-update则在控制台输出最新数据。实际项目中可以把这些数据交给Chart.js或ECharts进行曲线渲染。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>DeLandslide 监测大屏</title>
</head>
<body>
  <h1>滑坡监测实时数据</h1>
  <div id="status">正常</div>
  <script src="/socket.io/socket.io.js"></script>
  <script>
    const socket = io();
    socket.on('landslide-alert', function (data) {
      document.getElementById('status').innerText = '预警:' + data.deviceId;
    });
    socket.on('sensor-update', function (data) {
      console.log(data);
    });
  </script>
</body>
</html>

部署时需要注意Socket.IO客户端脚本路径要与服务端保持一致,如果前端页面由Nginx托管,还需要配置反向代理把/socket.io/请求转发到Node.js进程。传感器接入接口建议增加Token鉴权,防止未授权设备向系统写入伪造数据。服务端可以使用PM2守护进程,保证异常退出后自动拉起,从而让DeLandslide监测系统在无人值守环境下持续运行。

Node.js滑坡监测DeLandslide修改时间:2026-08-20 20:35:46

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。