NtripShare Cloud平台之CORS服务之基准站RTCM坐标编辑

最近有点累,一直在摸鱼,想在平差方面做点事情,但是一直在构思应该怎么去做,有想法的朋友可以交流。

收到了TW和国内顶尖测绘行业朋友的需求:

1、将NtripShare Cloud的CORS服务模块由单基站模块改为VRS。

2、由于电离层影响,基于VRS的CORS服务出现大面积的不能固定,需要使用单基站的网络CORS服务,但是由于CORS站本身的特殊性,不能对外暴扣精确的基准站坐标,能否在CORS软件中将单基站播发的RTCM中的基准站坐标进行编辑修改(测量结果需要后处理)。

其中VRS这件事有很多朋友提过,一直以来也没有做,主要考虑一下三点:

1、友商的VRS产品很多,没有必要再去做一款,已经很卷了。

2、VRS需要一定的技术难度,可以查找到的资料非常少。

3、NtripShare Cloud的CORS模块采用的是Java的技术路线,在应对大并发方面有一定优势,但是对于RTCM这种实时数据流解析与计算不是很适用。

RTCM基准站坐标编辑修改这事评估了一下可行,耗费四天时间,实现了在Java端的RTCM数据解析与1005、1006报文的实时修正。不得不说关于GNSS方面的java开源项目实在是太少了,真的只能手撸。这次的代码开放一部分,以便大家少走弯路。

java 复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

public class Rtcm1005 extends RtcmMessage {

    private static Logger logger = LoggerFactory.getLogger(Rtcm1005.class);
    public double[] ecef = new double[3];
    public double[] lla = new double[3];

    public Rtcm1005(byte[] data, int index, int length) {
        super(data, index, length);
    }

    public Rtcm1005() {
        super(new byte[25], 0, 25);
    }

    public void setECEF(double x, double y, double z) {
        ecef[0] = x;
        ecef[1] = y;
        ecef[2] = z;
        lla = GeoCode.ecef2lla(ecef);
    }

    public void setLatLon(double lat, double lon, double alt) {
        lla[0] = lat;
        lla[1] = lon;
        lla[2] = alt;
        ecef = GeoCode.lla2ecef(lla);
    }

    @Override
    public Rtcm1005 decode() {
        int bitPoint = HEADER_BYTE_LENGTH * 8;
        // DF002 Message Number
        messageType = Utilities.bitToInt(data, bitPoint, 12);
        bitPoint += 12;
        // DF003 Reference Station ID
        @SuppressWarnings("unused")
        int stationID = Utilities.bitToInt(data, bitPoint, 12);
        bitPoint += 12;
        // DF021 ITRF (not used)
        bitPoint += 6;
        // DF022/023/024/141
        bitPoint += 4;
        // DF025 Antenna Reference Point ECEF-X
        ecef[0] = Utilities.bitToLongMSB(data, bitPoint, 38) * 0.0001;
        bitPoint += 38;
        // DF142/001
        bitPoint += 2;
        // DF026 Antenna Reference Point ECEF-Y
        ecef[1] = Utilities.bitToLongMSB(data, bitPoint, 38) * 0.0001;
        bitPoint += 38;
        // DF364
        bitPoint += 2;
        // DF027 Antenna Reference Point ECEF-Y
        ecef[2] = Utilities.bitToLongMSB(data, bitPoint, 38) * 0.0001;
//        bitPoint += 38;
        lla = GeoCode.ecef2lla(ecef);

        return this;
    }

    @Override
    public String getSuccinctInfo() {
        return "ECEF\t" + Arrays.toString(ecef) + "\r\nLLA\t" + Arrays.toString(lla);
    }

    @Override
    public String getAnalyzedString() {
        return "Stationary RTK Reference Station ARP\r\n" +
                "ECEF(X) " + ecef[0] + ", ECEF(Y) " + ecef[1] + ", ECEF(Z) " + ecef[2] + "\r\n";
    }

    public byte[] recode() {
        ecef = GeoCode.lla2ecef(lla);
        int i = 24;
//        Utilities.setbitu(datass, i, 12, 1005);
        i += 12; /* message no */
//        Utilities.setbitu(datass, i, 12, 0);
        i += 12; /* ref station id */
//        Utilities.setbitu(datass, i, 6, 0);
        i += 6; /* itrf realization year */
//        Utilities.setbitu(datass, i, 1, 1);
        i += 1; /* gps indicator */
//        Utilities.setbitu(datass, i, 1, 1);
        i += 1; /* glonass indicator */
//        Utilities.setbitu(datass, i, 1, 0);
        i += 1; /* galileo indicator */
//        Utilities.setbitu(datass, i, 1, 0);
        i += 1; /* ref station indicator */
//        logger.info("--"+Utilities.getBinaryStrFromByte2( data,i,38));
        Utilities.longToBitMSB(data, i, ecef[0] / 0.0001);
//        logger.info("AA"+Utilities.getBinaryStrFromByte2( data,i,38));
        i += 38; /* antenna ref point ecef-y */
//        Utilities.setbitu(datass, i, 1, 1);
        i += 1; /* oscillator indicator */
//        Utilities.setbitu(datass, i, 1, 1);
        i += 1; /* reserved */
        Utilities.longToBitMSB(data, i, ecef[1] / 0.0001);
//        logger.info("BB"+Utilities.getBinaryStrFromByte( data));
        i += 38; /* antenna ref point ecef-y */
//        Utilities.setbitu(datass, i, 2, 0);
        i += 2; /* quarter cycle indicator */
        Utilities.longToBitMSB(data, i, ecef[2] / 0.0001);
//        logger.info("CC"+Utilities.getBinaryStrFromByte( data));
        i += 38; /* antenna ref point ecef-z */
        int crc = 0;
        for (int m = 0; m < data.length - DecodeRTCM3.CRCBYTELENGTH; m++) {
            crc ^= data[0 + m] << 16;
            for (int j = 0; j < 8; j++) {
                crc <<= 1;
                if ((crc & 0x1000000) != 0) {
                    crc ^= DecodeRTCM3.CRC24_POLY;
                }
            }
        }
        Utilities.intToBit(data, (data.length - DecodeRTCM3.CRCBYTELENGTH) * 8, DecodeRTCM3.CRCBYTELENGTH * 8, crc);
        return data;
    }

    @Override
    public byte[] encode() {
        ecef = GeoCode.lla2ecef(lla);
        data = Utilities.hexToByteArray("d300133ed00003fab70dd5be0a44a89893094e19c0e5f16d7b");
        int i = 24;
//        Utilities.setbitu(data, i, 12, 1005);
        i += 12; /* message no */
//        Utilities.setbitu(data, i, 12, 0);
        i += 12; /* ref station id */
//        Utilities.setbitu(data, i, 6, 0);
        i += 6; /* itrf realization year */
//        Utilities.setbitu(data, i, 1, 1);
        i += 1; /* gps indicator */
//        Utilities.setbitu(data, i, 1, 1);
        i += 1; /* glonass indicator */
//        Utilities.setbitu(data, i, 1, 0);
        i += 1; /* galileo indicator */
//        Utilities.setbitu(data, i, 1, 0);
        i += 1; /* ref station indicator */
//        logger.info("--"+Utilities.getBinaryStrFromByte2( data,i,38));
        Utilities.longToBitMSB(data, i, ecef[0] / 0.0001);
//        logger.info("AA"+Utilities.getBinaryStrFromByte2( data,i,38));
        i += 38; /* antenna ref point ecef-y */
//        Utilities.setbitu(data, i, 1, 1);
        i += 1; /* oscillator indicator */
//        Utilities.setbitu(data, i, 1, 1);
        i += 1; /* reserved */
        Utilities.longToBitMSB(data, i, ecef[1] / 0.0001);
//        logger.info("BB"+Utilities.getBinaryStrFromByte( data));
        i += 38; /* antenna ref point ecef-y */
//        Utilities.setbitu(data, i, 2, 0);
        i += 2; /* quarter cycle indicator */
        Utilities.longToBitMSB(data, i, ecef[2] / 0.0001);
//        logger.info("CC"+Utilities.getBinaryStrFromByte( data));
        i += 38; /* antenna ref point ecef-z */
        int crc = 0;
        for (int m = 0; m < data.length - DecodeRTCM3.CRCBYTELENGTH; m++) {
            crc ^= data[0 + m] << 16;
            for (int j = 0; j < 8; j++) {
                crc <<= 1;
                if ((crc & 0x1000000) != 0) {
                    crc ^= DecodeRTCM3.CRC24_POLY;
                }
            }
        }
        Utilities.intToBit(data, (data.length - DecodeRTCM3.CRCBYTELENGTH) * 8, DecodeRTCM3.CRCBYTELENGTH * 8, crc);
        return data;
    }
}
java 复制代码
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class RtcmMsm extends RtcmMessage {
    private static final String[] GPSSIGNALMAP = {"","","1C","1P","1W","","","","2C","2P","2W","","","","","2S","2L","2X","","","","","5I","5Q","5X","","","","","","1S","1L","1X"};
    private static final String[] GLONASSSIGNALMAP = {"","","1C","1P","","","","","2C","2P"};
    private static final String[] GALILEOSIGNALMAP = {"","","1C","1A","1B","1X","1Z","","6C","6A","6B","6X","6Z","","7I","7Q","7X","","8I","8Q","8X","","5I","5Q","5X"};
    private static final String[] SBASSINGALMAP = {"","","1C","","","","","","","","","","","","","","","","","","","","5I","5Q","5X"};
    private static final String[] QZSSIGNALMAP = {"","","1C","","","","","","","6S","6L","6X","","","","2S","2L","2X","","","","","5I","5Q","5X","","","","","","1S","1L","1X"};
    private static final String[] BEIDOUSIGNALMAP = {"","","2I","2Q","2X","","","","6I","6Q","6X","","","","7I","7Q","7X"};
    private static final String[][] SIGNALMAP = {GPSSIGNALMAP,GLONASSSIGNALMAP,GALILEOSIGNALMAP,SBASSINGALMAP,QZSSIGNALMAP,BEIDOUSIGNALMAP};

    private int msmType;
    private int gnssType;

    private List<Integer> satelliteList;	
    private List<Integer> signalList;		
    private long cellMask;					
    private int epochTime;
    private List<Integer> ltiList;
    private List<Integer> cnrList;

    public RtcmMsm(byte[] data, int index, int length) {
        super(data, index, length);
    }

    @Override
    RtcmMsm decode() {
        int bitPoint = decodeHeader();
        ltiList = new ArrayList<>();
        cnrList = new ArrayList<>();

        /*
         * satellite Data
         */
        int satelliteNumber = satelliteList.size();
        if(msmType == 4 || msmType == 5 || msmType == 6 || msmType == 7) {
            // DF397	8bits*Nsat
            bitPoint += 8 * satelliteNumber;
        }

        if(msmType == 5 || msmType == 7) {
            // Extended Satellite Information	4bits*Nsat
            bitPoint += 4 * satelliteNumber;
        }

        // DF398	10bits*Nsat
        bitPoint += 10 * satelliteNumber;


        if(msmType == 5 || msmType == 7) {
            // DF399	14bits*Nsat
            bitPoint += 14 * satelliteNumber;
        }

        /*
         * signal Data
         */
        int cellNumber = Long.bitCount(cellMask);
        if(msmType == 1 || msmType == 3 || msmType == 4 || msmType == 5) {
            // DF400 signal fine pseudorange
            bitPoint += 15 * cellNumber;
        }

        if(msmType == 2 || msmType == 3 || msmType == 4 || msmType == 5) {
            // DF401 signal fine phaserange data
            bitPoint += 22 * cellNumber;

            // DF402 phaserange Lock Time Indicator
            for(int i = 0; i < cellNumber; i++) {
                ltiList.add(Utilities.bitToInt(data, bitPoint, 4));
                bitPoint += 4;
            }

            // DF420 half-cycle ambiguity indicator
            bitPoint += cellNumber;
        }

        if(msmType == 4 || msmType == 5) {
            // DF403 signal CNRs
            for(int i = 0; i < cellNumber; i++) {
                cnrList.add(Utilities.bitToInt(data, bitPoint, 6));
                bitPoint += 6;
            }
        }

        if(msmType == 5) {
            // DF404 signal fine phaserangerate
            bitPoint += 15 * cellNumber;
        }

        if(msmType == 6 || msmType == 7) {
            // DF405 signal fine pseudoranges
            bitPoint += 20 * cellNumber;

            // DF406 signal fine Phaserange
            bitPoint += 24 * cellNumber;

            // DF407 Phaserange Lock Time Indicator
            for(int i = 0; i < cellNumber; i++) {
                ltiList.add(Utilities.bitToInt(data, bitPoint, 10));
                bitPoint += 10;
            }

            // DF420 Half-cycle ambiguity indicator
            bitPoint += cellNumber;

            // DF408 signal CNR	 
            for(int i = 0; i < cellNumber; i++) {
                cnrList.add((int)(Utilities.bitToInt(data, bitPoint, 10) * Math.pow(2, -4)));
                bitPoint += 10;
            }
        }

 //       if(msmType == 5 || msmType == 7) {
 //           // DF404 signal fine PhaseRangeRates
 //           bitPoint += 15 * cellNumber;
 //       }

        return this;
    }

    private int decodeHeader() {
        int bitPoint = HEADER_BYTE_LENGTH * 8;

        // DF002 Message Number
        messageType = Utilities.bitToInt(data, bitPoint, 12);
        bitPoint += 12;

        classifyMSM();

        // DF003 Reference Station ID
        @SuppressWarnings("unused")
        int stationID = Utilities.bitToInt(data, bitPoint, 12);
        bitPoint += 12;

        // GNSS Epoch Time
        if(gnssType == GeoCode.GNSSGLONASS) {
            @SuppressWarnings("unused")
            int dow = Utilities.bitToInt(data, bitPoint, 3);
            epochTime = Utilities.bitToInt(data, bitPoint + 3, 27);
        } else {
            epochTime = Utilities.bitToInt(data, bitPoint, 30);
        }
        bitPoint += 30;

        // MMB:1, IODS:3, Rsv:7, CSI:2, ECI:2, GDSI:1, GSI:3
        bitPoint += 19;

        // DF394  satellite Mask
        satelliteList = getBitMask(data, bitPoint, 64);
        bitPoint += 64;

        // DF395  signal Mask
        signalList = getBitMask(data, bitPoint, 32);
        bitPoint += 32;

        // DF396  cell Mask
        cellMask = Utilities.bitToLong(data, bitPoint, satelliteList.size() * signalList.size());
        bitPoint += satelliteList.size() * signalList.size();

        return bitPoint;
    }

    private List<Integer> getCombinedCellList(List<Integer> target) {
        List<Integer> list = new ArrayList<>();
        int cellLength = satelliteList.size() * signalList.size();
        for(int i = 0, counter = 0; i < satelliteList.size() * signalList.size(); i++) {
            if(((cellMask >> --cellLength) & 0x01) == 1) {
                list.add(target.get(counter++));
            } else {
                list.add(0);
            }
        }
        return list;
    }

    private void classifyMSM() {
        if(messageType >= 1071 && messageType <= 1077) {
            msmType = messageType - 1070; gnssType = GeoCode.GNSSGPS;
        } else if(messageType >= 1081 && messageType <= 1087) {
            msmType = messageType - 1080; gnssType = GeoCode.GNSSGLONASS;
        } else if(messageType >= 1091 && messageType <= 1097) {
            msmType = messageType - 1090; gnssType = GeoCode.GNSSGALILEO;
        } else if(messageType >= 1101 && messageType <= 1107) {
            msmType = messageType - 1100; gnssType = GeoCode.GNSSSBAS;
        } else if(messageType >= 1111 && messageType <= 1117) {
            msmType = messageType - 1110; gnssType = GeoCode.GNSSQZSS;
        } else if(messageType >= 1121 && messageType <= 1127) {
            msmType = messageType - 1120; gnssType = GeoCode.GNSSBEIDOU;
        }
    }
    
    private List<String> getPRNList() {
        int weight;

        switch(gnssType) {
            case GeoCode.GNSSSBAS:
                weight = 119;
                break;
            case GeoCode.GNSSQZSS:
                weight = 192;
                break;
            default:
                weight = 0;
        }

        return satelliteList.stream().map(Object -> Object + weight).map(Object::toString).collect(Collectors.toList());
    }

    private List<Integer> getBitMask(byte[] src, int bitPosition, int bitLength) {
        List<Integer> list = new ArrayList<>();
        int j = 0;
        for(int i = bitPosition; i < bitPosition + bitLength; i++) {
            ++j;
            if(((src[i / 8] >> (7 - i % 8)) & 0x01) == 1) {
                list.add(j);
            }
        }

        return list;
    }

    private String printTable(List<Integer> data) {
        return GeoCode.print2DimensionTable(getPRNList(), getSignalStringList(), data);
    }

    @Override
    String getSuccinctInfo() {
        return GeoCode.getGnssName(gnssType) + " MSM" + msmType +"\r\n" +
                "Satellite: " + getPRNList().size() +
                ",  Signal: " + getSignalStringList().size();
    }

    @Override
    String getAnalyzedString() {
        StringBuilder sb = new StringBuilder();

        sb.append(GeoCode.getGnssName(gnssType)).append(" MSM").append(msmType).append("\r\n");
        sb.append("epochtime: ").append(epochTime).append("\r\n");
        sb.append("satellite: ").append(getPRNList()).append("\r\n");
        sb.append("signal: ").append(getSignalStringList()).append("\r\n");
        if(ltiList.size() > 0) {
            sb.append("Lock Time Indicator\r\n").append(printTable(getCombinedCellList(ltiList))).append("\r\n");
        }
        if(cnrList.size() > 0) {
            sb.append("CNR\r\n").append(printTable(getCombinedCellList(cnrList))).append("\r\n");
        }
        return sb.toString();
    }

    @Override
    public byte[] encode() {
        byte [] bytes = new byte[25];
        return  bytes;
    }

    @SuppressWarnings("unused")
    private String getConvertedEpocTime() {
        return null;
    }

    private List<String> getSignalStringList() {
        List<String> list = new ArrayList<>();
        try {
            for (Integer integer : signalList) {
                list.add(SIGNALMAP[gnssType][integer]);
            }
            return list;
        }catch (Exception e){
        }
        return  list;
    }

    // Getter
    List<Integer> getSatelliteList() {
        return satelliteList;
    }
    List<Integer> getSignalList() {
        return signalList;
    }
    int getGnssType() {
        return gnssType;
    }
    int getMsmType() {
        return msmType;
    }
    int getEpochTime() {
        return epochTime;
    }
    List<Integer> getLtiList() {
        return ltiList;
    }
    List<Integer> getCnrList() {
        return cnrList;
    }
}
java 复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static java.lang.Math.floor;

public class Utilities {
    private static Logger logger = LoggerFactory.getLogger(Utilities.class);
    public static final int INDEX_NOT_FOUND = -1;

    public static int indexOf(final byte[] dstArray, final byte[] toFind) {
        return indexOf(dstArray, dstArray.length, toFind, 0);
    }


    public static int indexOf(final byte[] dstArray, int dstArrayLength, final byte[] toFind, int startIndex) {
        if (dstArray == null || toFind == null) {
            return INDEX_NOT_FOUND;
        }
        if (startIndex < 0) {
            startIndex = 0;
        }
        if (dstArrayLength > dstArray.length) {
            dstArrayLength = dstArray.length;
        }

        for (int i = startIndex; i < dstArrayLength - toFind.length + 1; i++) {
            boolean found = true;
            for (int j = 0; j < toFind.length; j++) {
                if (dstArray[i + j] != toFind[j]) {
                    found = false;
                    break;
                }
            }
            if (found) {
                return i;
            }
        }
        return INDEX_NOT_FOUND;
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() < 2) {
                sb.append(0);
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    public static byte[] hexToByteArray(String inHex) {
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1) {
            hexlen++;
            result = new byte[hexlen / 2];
            inHex = "0" + inHex;
        } else {
            result = new byte[hexlen / 2];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = hexToByte(inHex.substring(i, i + 2));
            j++;
        }
        return result;
    }

    public static byte hexToByte(String inHex) {
        return (byte) Integer.parseInt(inHex, 16);
    }

    public static void set38bits(byte[] buff, int pos, double value) {
        int word_h = (int) (floor(value / 64.0));
        int word_l = (int) (value - word_h * 64.0);
        setbits(buff, pos, 32, word_h);
        setbitu(buff, pos + 32, 6, word_l);
    }

    public static int bitToInt(final byte[] data, int bitPosition, int bitLength) {
        if (data == null || bitLength > 32) {
            return 0;
        }
        int sum = 0;
        for (int i = bitPosition; i < bitPosition + bitLength; i++) {
            sum = (sum << 1) + ((data[i / 8] >> (7 - i % 8)) & 0x01);
        }
        return sum;
    }

    static void setbits(byte[] buff, int pos, int len, int data) {
        if (data < 0) {
            data |= 1 << (len - 1);
            byte[] dataaa = intToByteArray(data);
            logger.info(getBinaryStrFromByte(dataaa));
        } else {
            data &= ~(1 << (len - 1));
        } /* set sign bit */
        setbitu(buff, pos, len, data);
        logger.info(getBinaryStrFromByte2(buff, pos, len));
    }

    public static byte[] intToByteArray(int i) {
        byte[] result = new byte[4];
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);
        return result;
    }

    public static byte[] LongToBytes(long values) {
        byte[] buffer = new byte[8];
        for (int i = 0; i < 8; i++) {
            int offset = 64 - (i + 1) * 8;
            buffer[i] = (byte) ((values >> offset) & 0xff);
        }
        return buffer;
    }

    public static void intToBit(byte[] buff, int pos, int len, int data) {
        int mask = 1 << (len - 1);
        int i;
        if (len <= 0 || 32 < len) return;
        for (i = pos; i < pos + len; i++, mask >>= 1) {
            if ((data & mask) != 0) {
                buff[i / 8] |= 1 << (7 - i % 8);
            } else {
                buff[i / 8] &= ~(1 << (7 - i % 8));
            }
        }
    }


    public static long bitToLong(byte[] data, int bitPosition, int bitLength) {
        if (data == null || bitLength > 64) {
            return 0;
        }
        long sum = 0;
        for (int i = bitPosition; i < bitPosition + bitLength; i++) {
            sum = (sum << 1) + ((data[i / 8] >> (7 - i % 8)) & 0x01);
        }
        return sum;
    }


    public static void setbitu(byte[] buff, int pos, int len, int data) {
        int mask = 1 << (len - 1);
        int i;
        if (len <= 0 || 32 < len) return;
        for (i = pos; i < pos + len; i++, mask >>= 1) {
            if ((data & mask) != 0) {
                buff[i / 8] |= 1 << (7 - i % 8);
            } else {
                buff[i / 8] &= ~(1 << (7 - i % 8));
            }
        }
    }

    public static long bitToLongMSB(byte[] data, int bitPosition, int bitLength) {
        if (data == null || bitLength > 64) {
            return 0;
        }
        long sum = bitToLong(data, bitPosition, bitLength);
        if (((data[bitPosition / 8] >> (7 - bitPosition % 8)) & 0x01) == 1) {
            long mask = -1L << bitLength;
            sum |= mask;
        }
        return sum;
    }


    public static void longToBitMSB(byte[] data, int bitPosition, double val) {
        long myData = (long) val;
//        logger.info("--"+getBinaryStrFromByte2( LongToBytes(myData),64-38,38));
//        if (val < 0) {
//            myData |= 1 << (63);
//        } else {
//            myData &= ~(1 << 63);
//        } /* set sign bit */
//        logger.info("$$"+getBinaryStrFromByte2( data,bitPosition,38));
//        logger.info("@@"+getBinaryStrFromByte2( LongToBytes(myData),64-38,38));
//                    logger.info(current+"$$"+getBinaryStrFromByte2( data,bitPosition,38));
        byte[] b = LongToBytes(myData);
        for (int m = 0; m < b.length; m++) {
            byte a = b[m];
            for (int i = 0; i < 8; i++) {
                byte c = a;
                a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。
                a = (byte) (a << 1);
                int current = m * 8 + i - (64 - 38) + bitPosition;
                if (current >= bitPosition) {
                    if (a == c) {
//                        logger.info(current+"$$0");
                        data[current / 8] &= ~(1 << current % 8);
                    } else {
//                        logger.info(current+"$$1");
                        data[current / 8] |= 1 << current % 8;
                    }

                }
                a = (byte) (a >> 1);
            }
        }
//        logger.info("@@"+getBinaryStrFromByte2( data,bitPosition,38));
        int word_h = (int) (floor(val / 64.0));
        int word_l = (int) (val - word_h * 64.0);
        setbitu(data, bitPosition + 32, 6, word_l);
//        longToBit(data, bitPosition, 38, myData);
//        logger.info("$$"+getBinaryStrFromByte2( data,bitPosition,38));
    }


    public static void longToBit(byte[] buff, int pos, int len, long data) {
        if (len <= 0 || 38 < len) return;
        byte[] b = LongToBytes(data);
        String result = "";
        for (int m = 0; m < b.length; m++) {
            byte a = b[m];
            for (int i = 0; i < 8; i++) {
                if ((m * 8 + i) < 38 || (m * 8 + i) >= 38 + len) {
                    continue;
                }
                byte c = a;
                a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。
                a = (byte) (a << 1);
                int current = m * 8 + i - 38 + pos;
                if (a == c) {
                    result = "0" + result;
                    buff[current / 8] |= 1 << (7 - current % 8);
                } else {
                    result = "0" + result;
                    buff[current / 8] &= ~(1 << (7 - current % 8));
                }
                a = (byte) (a >> 1);
            }
        }
        logger.info("**" + result);
    }

    /**
     * 把byte转化成2进制字符串
     *
     * @param b
     * @return
     */
    public static String getBinaryStrFromByte(byte[] b) {
        String result = "";
        for (byte bb : b) {
            byte a = bb;
            for (int i = 0; i < 8; i++) {
                byte c = a;
                a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。
                a = (byte) (a << 1);
                if (a == c) {
                    result = "0" + result;
                } else {
                    result = "1" + result;
                }
                a = (byte) (a >> 1);
            }
        }

        return result;
    }


    /**
     * 把byte转化成2进制字符串
     *
     * @param b
     * @return
     */
    public static String getBinaryStrFromByte2(byte[] b, int start, int len) {
        String result = "";
        for (int m = 0; m < b.length; m++) {
            byte a = b[m];
            for (int i = 0; i < 8; i++) {
                if ((m * 8 + i) < start || (m * 8 + i) >= start + len) {
                    continue;
                }
                byte c = a;
                a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。
                a = (byte) (a << 1);
                if (a == c) {
                    result = "0" + result;
                } else {
                    result = "1" + result;
                }
                a = (byte) (a >> 1);
            }
        }

        return result;
    }

    public static byte[] byteConcat(byte[] bt1, byte[] bt2) {
        byte[] bt4 = new byte[bt1.length + bt2.length];
        int len = 0;
        System.arraycopy(bt1, 0, bt4, 0, bt1.length);
        len += bt1.length;
        System.arraycopy(bt2, 0, bt4, len, bt2.length);
        return bt4;
    }
}

欢迎交流,VX:NtripShare

相关推荐
做完作业了18 天前
RTKLIB学习记录【postpos、execses_b、execses_r】
gnss·rtklib·rtklib源码解析
小 y 同 学1 个月前
Ubuntu22.04安装GNSS数据处理软件GAMIT/GLOBK
linux·gnss·测绘·gamit
记得往前走2 个月前
北斗卫星系统信号介绍
gnss
山东仁科2 个月前
自然灾害预警系统的重要性
gnss·自然灾害·预警系统
山东仁科2 个月前
桥梁在线监测解决方案:科技赋能,守护桥梁安全
gnss·在线监测·桥梁
黄小鹿2 个月前
【GNSS射频前端】MA2769初识
fpga·gnss·北斗
山东仁科2 个月前
水库大坝预警解决方案:守护生命线的科技防线
gnss·水库大坝·水库大坝预警
成龙的龙4 个月前
让GNSS&RTK不再难【第17讲 RTK定位技术原理-站间单差浮点解--第1部分】
gnss·rtk
Mr.Peng~NtripShare4 个月前
NtripShare2024年第二季度主要技术进展
gnss·ntripshare·高精度定位·自动化监测·静态解算