找回密码
 立即注册

微信扫码登录

搜索
查看: 240|回复: 5

[进阶教程] Traccar Server原版利用node-red修复高德地图偏移

[复制链接]
frx 手机认证

14

主题

168

回帖

1845

积分

论坛技术达人

积分
1845
金钱
1648
HASS币
60
发表于 2025-7-24 11:48:55 | 显示全部楼层 |阅读模式
本帖最后由 frx 于 2025-7-24 12:00 编辑

看到有个适配高德版本的 Traccar Server,就想到我正在用的方式,分享给大家:
使用方法:

1、将流导入node-red。

2、修改函数节点最下面http://192.168.200.10:5057为你的Traccar Server地址和端口。

2、手机端Traccar Client中服务器地址填写为http://你的node-red地址:你的node-red端口/traccar。

原理就是拦截数据,转换经纬度后替换掉数据中的经纬度,然后再完整的发送出去。

利用这种方法,可以实现任何能取得经纬度数据的设备接入Traccar。


比如我车上用的是凯励程,抓到它的数据包后就可以模拟成Traccar能够接收的方式发送给Traccar。

[{"id":"e8df90d7cd57759a","type":"http request","z":"77c34a38.f5cc64","name":"发送到Traccar","method":"POST","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"basic","senderr":false,"headers":[],"x":540,"y":400,"wires":[[]]},{"id":"cac71e6068ca1a23","type":"http response","z":"77c34a38.f5cc64","name":"","statusCode":"200","headers":{},"x":340,"y":360,"wires":[]},{"id":"c883e2ad6cca0fd5","type":"http in","z":"77c34a38.f5cc64","name":"手机服务端","url":"/traccar","method":"post","upload":false,"swaggerDoc":"","x":140,"y":400,"wires":[["cac71e6068ca1a23","6a8574bec30ce8da"]]},{"id":"a4889e5308247a96","type":"comment","z":"77c34a38.f5cc64","name":"移动端纠偏","info":"","x":140,"y":360,"wires":[]},{"id":"6a8574bec30ce8da","type":"function","z":"77c34a38.f5cc64","name":"wgs84togcj02","func":"// --- 坐标转换核心函数 ---\n// 将WGS-84坐标转换为GCJ-02坐标\nfunction wgs84togcj02(lng_wgs, lat_wgs) {\n    // 检查是否在中国大陆地理范围外,如果是,则直接返回原始坐标\n    if (lng_wgs < 72.004 || lng_wgs > 137.8347 || lat_wgs < 0.8293 || lat_wgs > 55.8271) {\n        return [lng_wgs, lat_wgs];\n    }\n\n    const PI = 3.1415926535897932384626;\n    const a = 6378245.0; // 克拉索夫斯基椭球体长半轴\n    const ee = 0.00669342162296594323; // 椭球体第一偏心率的平方\n\n    function transformLat(lng, lat) {\n        let lat_offset = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));\n        lat_offset += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;\n        lat_offset += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;\n        lat_offset += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;\n        return lat_offset;\n    }\n\n    function transformLng(lng, lat) {\n        let lng_offset = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));\n        lng_offset += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;\n        lng_offset += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;\n        lng_offset += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;\n        return lng_offset;\n    }\n\n    const lng_offset_wgs = lng_wgs - 105.0;\n    const lat_offset_wgs = lat_wgs - 35.0;\n\n    let dLat = transformLat(lng_offset_wgs, lat_offset_wgs);\n    // *** 已修正 *** : 调用正确的经度转换函数\n    let dLng = transformLng(lng_offset_wgs, lat_offset_wgs);\n\n    const radLat = lat_wgs / 180.0 * PI;\n    let magic = Math.sin(radLat);\n    magic = 1 - ee * magic * magic;\n    const sqrtMagic = Math.sqrt(magic);\n\n    dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);\n    dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);\n\n    const lng_gcj = lng_wgs + dLng;\n    const lat_gcj = lat_wgs + dLat;\n\n    // 返回 [经度, 纬度]\n    return [lng_gcj, lat_gcj];\n}\n\n// --- Node-RED 主逻辑 ---\n// 1. 安全地获取输入坐标\nconst lat_wgs = parseFloat(msg.payload.location.coords.latitude);\nconst lng_wgs = parseFloat(msg.payload.location.coords.longitude);\n// 2. 检查坐标是否有效\nif (isNaN(lat_wgs) || isNaN(lng_wgs)) {\n    node.error("Invalid latitude or longitude in msg.payload.", msg);\n    return null; // 终止该路径的执行\n}\n// 3. 执行坐标转换\nconst [lng_gcj, lat_gcj] = wgs84togcj02(lng_wgs, lat_wgs);\n// 4. 更新 msg 对象\nmsg.payload.location.coords.latitude = lat_gcj;\nmsg.payload.location.coords.longitude = lng_gcj;\nmsg.url = `http://192.168.200.10:5057`;\n// 5. 返回消息对象\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":400,"wires":[["e8df90d7cd57759a"]]}]



回复

使用道具 举报

11

主题

96

回帖

1224

积分

金牌会员

积分
1224
金钱
1117
HASS币
0
发表于 2025-7-24 15:00:16 | 显示全部楼层
本帖最后由 xiongmx 于 2025-7-24 15:09 编辑

火星坐标系最恶心,顶一个,可惜兄弟没经验,论坛这样贴的代码没用
回复

使用道具 举报

15

主题

500

回帖

2867

积分

金牌会员

积分
2867
金钱
2352
HASS币
0
发表于 2025-7-24 16:00:28 | 显示全部楼层
最早也这是用的nodered来转换坐标。现在用适配版就没用了
回复

使用道具 举报

47

主题

307

回帖

2576

积分

金牌会员

积分
2576
金钱
2222
HASS币
0
发表于 2025-7-24 17:03:04 | 显示全部楼层
xiongmx 发表于 2025-7-24 15:00
火星坐标系最恶心,顶一个,可惜兄弟没经验,论坛这样贴的代码没用

我改造了traccar的集成,新增了一个转换后的WGS84 实体
回复

使用道具 举报

0

主题

62

回帖

250

积分

中级会员

积分
250
金钱
188
HASS币
0
发表于 2025-7-25 09:40:23 | 显示全部楼层
好多流程感觉没必要用node-red这么庞大的东西
回复

使用道具 举报

frx 手机认证

14

主题

168

回帖

1845

积分

论坛技术达人

积分
1845
金钱
1648
HASS币
60
 楼主| 发表于 2025-7-25 09:44:46 | 显示全部楼层
miaoguoqiang 发表于 2025-7-25 09:40
好多流程感觉没必要用node-red这么庞大的东西

单独为了这个装个node-red确实有点大材小用,我的场景是还有几十条流在node-red里
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian ( 晋ICP备17001384号-1 )

GMT+8, 2025-8-2 15:28 , Processed in 0.663189 second(s), 9 queries , MemCached On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表