package yaokong;
|
|
import java.nio.ByteBuffer;
|
import java.nio.ByteOrder;
|
|
import publicway.Gpstoxuzuobiao;
|
|
public class Control02 {
|
|
/**
|
* 构建基准站坐标指令(指令类型0x02)的HEX格式字符串
|
*
|
* @param baseStationCoords 基准站坐标字符串,格式:"纬度值,纬度方向,经度值,经度方向"
|
* 例如:"3949.90238860,N,11616.75692000,E"
|
* @return 基准站坐标指令的HEX格式字符串
|
*/
|
public static String buildBaseStationCommandHex(String baseStationCoords) {
|
// 解析坐标字符串
|
String[] parts = baseStationCoords.split(",");
|
if (parts.length != 4) {
|
throw new IllegalArgumentException("基准站坐标格式错误,应为:纬度,纬度方向,经度,经度方向");
|
}
|
|
double latitude = parseDMToDecimal(parts[0].trim(), parts[1].trim());
|
double longitude = parseDMToDecimal(parts[2].trim(), parts[3].trim());
|
char latDirection = parts[1].trim().charAt(0);
|
char lonDirection = parts[3].trim().charAt(0);
|
|
byte[] commandBytes = buildBaseStationCommandBytes(latitude, longitude, latDirection, lonDirection);
|
return bytesToHex(commandBytes);
|
}
|
|
/**
|
* 构建基准站坐标指令的字节数组
|
*/
|
public static byte[] buildBaseStationCommandBytes(double latitude, double longitude,
|
char latDirection, char lonDirection) {
|
// 验证参数
|
if (latitude < -90.0 || latitude > 90.0) {
|
throw new IllegalArgumentException("纬度值必须在-90.0到90.0之间");
|
}
|
if (longitude < -180.0 || longitude > 180.0) {
|
throw new IllegalArgumentException("经度值必须在-180.0到180.0之间");
|
}
|
if (!(latDirection == 'N' || latDirection == 'S')) {
|
throw new IllegalArgumentException("纬度方向必须是'N'或'S'");
|
}
|
if (!(lonDirection == 'E' || lonDirection == 'W')) {
|
throw new IllegalArgumentException("经度方向必须是'E'或'W'");
|
}
|
|
int dataLength = 32; // 固定长度32字节
|
|
ByteBuffer buffer = ByteBuffer.allocate(2 + 1 + 2 + 2 + dataLength + 2 + 1);
|
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
|
// 帧头
|
buffer.put(BluetoothProtocol.FRAME_HEADER);
|
|
// 指令类型
|
buffer.put((byte) 0x02);
|
|
// 数据长度
|
buffer.putShort((short) dataLength);
|
|
// 序列号
|
buffer.putShort((short) BluetoothProtocol.getNextSequence());
|
|
// 纬度值 (double, 8字节)
|
buffer.putDouble(latitude);
|
|
// 经度值 (double, 8字节)
|
buffer.putDouble(longitude);
|
|
// 纬度方向 (char, 1字节)
|
buffer.put((byte) latDirection);
|
|
// 经度方向 (char, 1字节)
|
buffer.put((byte) lonDirection);
|
|
// 保留字段 (14字节,全部填0)
|
for (int i = 0; i < 14; i++) {
|
buffer.put((byte) 0x00);
|
}
|
|
// 计算CRC16
|
byte[] dataForCRC = new byte[1 + 2 + 2 + dataLength];
|
System.arraycopy(buffer.array(), 2, dataForCRC, 0, dataForCRC.length);
|
int crc = CRC16.calculateCRC16(dataForCRC, 0, dataForCRC.length);
|
buffer.putShort((short) crc);
|
|
// 帧尾
|
buffer.put((byte) 0x0D);
|
|
return buffer.array();
|
}
|
|
/**
|
* 将度分格式转换为十进制格式
|
* 例如:3949.90238860 -> 39.83170647666667
|
*/
|
private static double parseDMToDecimal(String dmm, String direction) {
|
return Gpstoxuzuobiao.parseDMToDecimal(dmm, direction);
|
}
|
|
private static String bytesToHex(byte[] bytes) {
|
StringBuilder hexString = new StringBuilder();
|
for (int i = 0; i < bytes.length; i++) {
|
String hex = Integer.toHexString(bytes[i] & 0xFF);
|
if (hex.length() == 1) {
|
hexString.append('0');
|
}
|
hexString.append(hex);
|
if (i < bytes.length - 1) {
|
hexString.append(' ');
|
}
|
}
|
return hexString.toString().toUpperCase();
|
}
|
|
}
|