You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中将经纬度转换为GT06协议格式?

GT06协议经纬度转换修复(Flutter)

我是Flutter新手,正尝试将经纬度转换为GT06协议格式,协议结构如下:

字段长度(字节)
起始位2
数据包长度1
协议编号1
信息内容N
信息序列号2
校验码2
停止位2

我编写了以下转换函数,但无法正常工作:

String convertCoordinatesToFormat(double latitude, double longitude) {
    // 起始位(2字节)
    String startBit = (0x78.toString()) ;

    // 协议编号(1字节)
    int protocolNumber = 0x22; // 替换为合适的协议编号

    // 信息内容(N字节)
    // 将经纬度转换为所需格式,例如字符串形式
    String latitudeString = latitude.toStringAsFixed(6); // 替换为所需的纬度精度
    String longitudeString = longitude.toStringAsFixed(6); // 替换为所需的经度精度
    String informationContent = "$latitudeString$longitudeString";

    // 计算字节长度
    int length = 5 + informationContent.length ~/ 2; // 除以2是因为每个字节在十六进制中用2个字符表示

    // 长度(1字节)
    String lengthString = length.toRadixString(16).padLeft(2, "0");

    // 数据包长度(1字节)
    // int packetLength = lengthString; // 剩余字节的长度(协议编号 + 信息内容 + 信息序列号 + 校验码 + 停止位)

    // 信息序列号(2字节)
    int informationSerialNumber = 1; // 替换为合适的序列号


    // 校验码(2字节)
    int errorCheck = calculateErrorCheck(informationContent);
    String errorCheckString = errorCheck.toRadixString(16).padLeft(4, "0");

    // 停止位(2字节)
    String stopBit = (0x0D.toString()) + (0x0A.toString());

    // 将所有字段拼接在一起
    String result = "$startBit$lengthString$protocolNumber$informationContent$informationSerialNumber$errorCheckString$stopBit";

    List<int> bytes = utf8.encode(result);
    String answer = "";
    for (int a in bytes){
      answer += a.toString();
    }

    // 将格式化后的坐标转换为大写
    return answer;
  }

  int calculateErrorCheck(String content) {
    int sum = 0;
    for (int i = 0; i < content.length; i++) {
      sum += content.codeUnitAt(i);
    }
    return sum % 65536;
  }

问题分析

原代码存在多个核心错误,完全不符合GT06协议的二进制编码规则:

  1. 字段编码逻辑错误:所有协议字段需以十六进制字节形式表示,而非十进制字符串或普通文本
  2. 经纬度编码错误:GT06不使用字符串存储经纬度,需将经纬度值×10^6后转为4字节大端整数
  3. 数据包长度计算错误:数据包长度是「协议编号+信息内容+信息序列号」的总字节数
  4. 校验码计算范围错误:校验码需计算从数据包长度到信息序列号的所有字节累加和,取低16位
  5. 起始/停止位错误:起始位应为0x7878、停止位应为0x0D0A,需转成十六进制字符串而非十进制

修复后的代码

String convertCoordinatesToGT06(double latitude, double longitude) {
  // 1. 起始位:0x7878(2字节)
  final startBit = "7878";

  // 2. 协议编号:0x22是位置信息包(1字节)
  final protocolNumber = 0x22;
  final protocolHex = protocolNumber.toRadixString(16).padLeft(2, "0");

  // 3. 经纬度编码:转成4字节大端整数(值×10^6)
  final latInt = (latitude * 1000000).toInt();
  final lonInt = (longitude * 1000000).toInt();
  // 转大端十六进制,每个占8位(4字节)
  final latHex = latInt.toRadixString(16).padLeft(8, "0");
  final lonHex = lonInt.toRadixString(16).padLeft(8, "0");

  // 信息内容:这里简化处理,实际GT06位置包还有状态、时间等字段,需根据协议补全
  // 示例仅包含经纬度,实际需参考GT06协议规范添加其他必填字段
  final informationContent = latHex + lonHex;
  final infoContentLen = informationContent.length ~/ 2; // 字节数

  // 4. 数据包长度:协议编号(1) + 信息内容(N) + 信息序列号(2) 的总字节数
  final packetLength = 1 + infoContentLen + 2;
  final packetLengthHex = packetLength.toRadixString(16).padLeft(2, "0");

  // 5. 信息序列号:2字节,自增即可
  final serialNumber = 1;
  final serialHex = serialNumber.toRadixString(16).padLeft(4, "0");

  // 6. 校验码:计算从packetLength到serialNumber的所有字节累加和,取低16位
  final checkData = packetLengthHex + protocolHex + informationContent + serialHex;
  int checkSum = 0;
  for (int i = 0; i < checkData.length; i += 2) {
    final byteStr = checkData.substring(i, i + 2);
    checkSum += int.parse(byteStr, radix: 16);
  }
  final checkCode = checkSum % 65536;
  final checkCodeHex = checkCode.toRadixString(16).padLeft(4, "0");

  // 7. 停止位:0x0D0A(2字节)
  final stopBit = "0D0A";

  // 拼接所有十六进制字段
  final hexResult = startBit + packetLengthHex + protocolHex + informationContent + serialHex + checkCodeHex + stopBit;

  // 如果需要转为字节数组(发送给设备用),可以用下面的代码:
  // List<int> bytes = [];
  // for (int i = 0; i < hexResult.length; i += 2) {
  //   bytes.add(int.parse(hexResult.substring(i, i + 2), radix: 16));
  // }

  return hexResult.toUpperCase();
}

注意事项

  • GT06的位置信息包(0x22协议)的信息内容包含更多字段(如定位状态、速度、方向、时间等),上述代码仅做经纬度核心编码,实际使用需参考完整的GT06协议规范补全所有必填字段
  • 经纬度的正负需注意:GT06中通常用最高位或单独的字节表示南北纬/东西经,上述代码默认处理正负整数的十六进制转换,需根据协议确认是否需要调整
  • 信息序列号需每次发送自增,避免重复

内容的提问来源于stack exchange,提问作者Vedant Kakade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 19:05:39