zoukankan      html  css  js  c++  java
  • java读取GPS观测文件(IO流、ArrayList集合、HashMap集合练习)

    package cn.luoxue.reader_o_file;
    
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class Read_O_file {
        /**
         * 读取GPS观测文件O文件
         * @param args
         */
        public static void main(String[] args) {
            //用同一个FileReader 的对象fr作为参数创建的第二个BufferedReader对象读的数据为空,这里创建两个,fr1计算历元个数的时候用
            FileReader fr = null;
            FileReader fr1 = null;
            BufferedReader br = null;
            BufferedReader br1 = null;
            try {
                //创建FileReader对象
                fr = new FileReader("Test.O");
                fr1 = new FileReader("Test.O");
                //创建BufferReader对象
                br = new BufferedReader(fr);
                br1 = new BufferedReader(fr1);
                //通过readLine()方法一行一行的度数据
                String line = "";
                while(((line = br.readLine()) != null)){
                    
                    //读取头文件内的内容
                    //substring(0, 20);前包括后不包括,实际所取的是 索引 0 ~ 19 的内容
                    switch(line.substring(60).trim()){
                    //判断该行是否以RINEX VERSION / TYPE结尾
                    case "RINEX VERSION / TYPE":
                        String  rinexVersion = line.substring(0, 20).trim();
                        String fileType = line.substring(20, 40).trim();
                        String dataType = line.substring(40, 60).trim();
                        System.out.println("版本号为:" + rinexVersion + " 文件类型为: " + fileType + " 数据类型为:" + dataType);
                        continue;
                    //判断该行是否以COMMENT结尾
                    /*case "COMMENT":
                        String comment = line.substring(0,60).trim();
                        System.out.println("注释内容为:" + comment);
                        continue;*/
                    case "PGM / RUN BY / DATE":
                        //建本数据文件所采用程序的名称
                        String program_Name = line.substring(0, 20).trim();
                        //创建本数据文件单位的名称
                        String organization_Name = line.substring(20, 40).trim();
                        //创建文件的时间
                        String date_Time = line.substring(40, 60).trim();
                        //输出
                        System.out.println("程序的名称为:" + program_Name + " 单位名称为:" + organization_Name + " 创建文件的时间为:" + date_Time);
                        continue;
                    case "MARKER NAME":
                        //标记点名
                        String marker_Name = line.substring(0, 60).trim();
                        //输出
                        System.out.println("标记点名为:" + marker_Name);
                        continue;
                    case "MARKER NUMBER":
                        //标记点名
                        String marker_Number = line.substring(0, 60).trim();
                        //输出
                        System.out.println("标记点数量为:" + marker_Number);
                        continue;
                    case "OBSERVER / AGENCY":
                        //观测者的名称
                        String observer_Name = line.substring(0, 20).trim();
                        //观测者所在机构
                        String observer_Organization = line.substring(20, 40).trim();
                        //打印
                        System.out.println("观测者的名称为:" + observer_Name + " 观测者所在机构:" + observer_Organization);
                        continue;
                    case "REC # / TYPE / VERS":
                        //接收机的数量
                        String rec_Number = line.substring(0, 20).trim();
                        //接收机的型号
                        String rec_Type = line.substring(20, 40).trim();
                        //版本
                        String rec_Versions = line.substring(40, 60).trim();
                        System.out.println("接收机的数量为: " +  rec_Number + " 接收机的型号为:" + rec_Type + " 接收机的版本" + rec_Versions);
                        continue;
                    case "ANT # / TYPE":
                        String ant_Number = line.substring(0, 19).trim();
                        String ant_Type = line.substring(20, 40).trim();
                        System.out.println("天线的数量: " + ant_Number + " 天线的型号: " + ant_Type);
                        continue;
                    case "APPROX POSITION XYZ":
                        String x = line.substring(0, 14).trim();
                        String y = line.substring(14, 28).trim();
                        String z = line.substring(28, 42).trim();
                        System.out.println("x = " + x + " y = " + y + " z = " + z );
                        continue;
                        
                    case "ANTENNA: DELTA H/E/N": // 天线高度、天线中心相对标记点东向和北向距离
                        String H = line.substring(0, 14).trim();
                        String E = line.substring(14, 28).trim();
                        String N = line.substring(28, 42).trim();
                        System.out.println("H = " + H + " E = " + E + " N = " + N );
                        continue;
                    case "TIME OF FIRST OBS": //首次观测时间
                        String first_Year = line.substring(0, 6).trim();
                        String first_Month = line.substring(6, 12).trim();
                        String first_Day = line.substring(12, 18).trim();
                        String first_Hour = line.substring(18, 24).trim();
                        String first_Minute = line.substring(24, 30).trim();
                        String first_Second = line.substring(30, 43).trim();
                        String time_System = line.substring(43, 51).trim();
                        System.out.println("首次观测时间:" + first_Year + "" 
                                + first_Month + ""
                                + first_Day + ""
                                + first_Hour + ""
                                + first_Minute + ""
                                + first_Second + "");
                        System.out.println("时间系统为:" + time_System);
                        continue;
                    case "TIME OF LAST OBS"://最后观测时间
                        String last_Year = line.substring(0, 6).trim();
                        String last_Month = line.substring(6, 12).trim();
                        String last_Day = line.substring(12, 18).trim();
                        String last_Hour = line.substring(18, 24).trim();
                        String last_Minute = line.substring(24, 30).trim();
                        String last_Second = line.substring(30, 43).trim();
                        String last_System = line.substring(43, 51).trim();
                        System.out.println("最后观测时间:" + last_Year + "" 
                                + last_Month + ""
                                + last_Day + ""
                                + last_Hour + ""
                                + last_Minute + ""
                                + last_Second + "");
                        System.out.println("时间系统为:" + last_System);
                        continue;
                    case "INTERVAL": //以秒为单位的时间间隔
                        String inteval = line.substring(0, 6).trim();
                        System.out.println("以秒为单位的时间间隔:" + inteval);
                        continue;
                    case "LEAP SECONDS"://跳秒
                        String leap_Seconds = line.substring(0, 6).trim();
                        System.out.println("跳秒数为:" + leap_Seconds);
                        continue;
                    case "# / TYPES OF OBSERV"://观测类型数量及观测类型
                        List<String> observe_Type = new ArrayList<String>();
                        String type_Number = line.substring(0, 6).trim();
                        int int_Type_Number = Integer.valueOf(type_Number).intValue();
                        //这里仅仅考虑了观测值在九个以内的情况(即观测值类型仅仅在一行时候的情况!)
                        for (int i = 0; i < int_Type_Number; i++) {
                            switch(line.substring((i+1)*6, (i+2)*6).trim()){
                            case "p1":
                                observe_Type.add("p1");
                            continue;
                            case "p2":
                                observe_Type.add("p2");
                            continue;
                            case "C1":
                                observe_Type.add("C1");
                            continue;
                            case "C2":
                                observe_Type.add("C2");
                            continue;
                            case "L1":
                                observe_Type.add("L1");
                            continue;
                            case "L2":
                                observe_Type.add("L2");
                            continue;
                            case "S1":
                                observe_Type.add("S1");
                            continue;
                            case "S2":
                                observe_Type.add("S2");
                            continue;
                            default:
                            break;
                            }
                            break;
                        }
                        System.out.println("observe_Type" + observe_Type);
                        continue;
                    case "END OF HEADER":
                        break;
                    default:
                        continue;
                    }
                    break;
                }
                //计算历元数
                int epochNum=0;
                String line1 = "";
                while((line1 = br1.readLine()) != null){
                    if(line1.trim().endsWith("END OF HEADER")){
                        break;
                    }
                }
                System.out.println(line1);
                while((line1 = br1.readLine()) != null){
                    if(line1.contains("G")){
                        epochNum++;
                    }
                }
                System.out.println("历元数为:" + epochNum);
                //通过两种方式存储每个历元的观测数据
                //第一种方式:以历元作为主键的HashMap集合
                Map<Integer, Map<String, List<Double>>> epoch_Observe_Map = new HashMap<Integer, Map<String, List<Double>>>();
                //第二种方式:ArrayList集合
                List<Map<String, List<Double>>> epoch_Observe_List = new ArrayList<Map<String, List<Double>>>();
                //遍历所有历元
                for (int i = 0; i < epochNum; i++) {
                    //以卫星ID作为主键的HashMap集合,存储每个卫星的观测数据
                    //(HashMap集合的key键:无序、唯一的;value值:无序、不唯一)
                    //集合中存储数据的顺序为乱序的,不过不影响可以通过key键值(即卫星ID)来查数据
                    Map<String, List<Double>> satelite_Observe_Map = new HashMap<String, List<Double>>();
                    line = br.readLine();
                    // 卫星个数
                    int satelite_Num = Integer.valueOf(line.substring(29, 32).trim()).intValue();
                    //存储卫星的ID
                    //这里每次循环都重新new了一下,起到了清空集合的作用(效率太低)
                    List<String> satelite_Id_List = new ArrayList<String>();  
                    //提取卫星ID
                    for (int j = 0; j < satelite_Num; j++) {
                        satelite_Id_List.add(line.substring(32 + j * 3, 35 + j * 3).trim());
                    }
                    //(这里可以做一个判断,如果观测数据类型的个数大于5个和小于等于5个的情况各用一种方式提取)
                    //此处仅仅考虑了大于5的情况
                    for (int j = 0; j < satelite_Num; j++) { //每次循环读两行 ① ②
                        //存储每颗卫星的观测数据
                        //同样的,每次循环都重新new了一下,起到了清空集合的作用(但是效率太低)
                        List<Double> observe_Date_List = new ArrayList<Double>();
                        line = br.readLine();  //
                        for (int j2 = 0; j2 < 5; j2++) {
                            observe_Date_List.add(Double.valueOf(line. substring(j2 * 16, 16 + j2 * 16).trim()).doubleValue());
                        }    
                        line = br.readLine();  //
                        observe_Date_List.add(Double.valueOf(line. substring(0, 16).trim()).doubleValue());
                        //读完一个卫星的数据
                        satelite_Observe_Map.put(satelite_Id_List.get(j), observe_Date_List);
                //数组能够存储基本数据类型、引用型数据类型; 而集合只能存储引用型数据类型
    //清空集合 这样清空集合会出现问题 ,貌似因为observe_Date_List和satelite_Observe_Map中添加的observe_Date_List指向的是同一块儿内存 //((会把连带着把satelite_Observe_Map中添加的observe_Date_List集合也给清空了)) //observe_Date_List.clear(); } /*调试测试 * System.out.println("satelite_Observe_Map.keySet()为:" + satelite_Observe_Map.keySet()); Set<String> set = satelite_Observe_Map.keySet(); Iterator<String> it = set.iterator(); while(it.hasNext()){ String key = it.next(); Iterator<Double> its = satelite_Observe_Map.get(key).iterator(); while(its.hasNext()){ double straa = its.next(); System.out.print(" " + straa); } }*/ //两种存储方式的集合分别添加每个历元的观测数据 epoch_Observe_Map.put(i, satelite_Observe_Map); epoch_Observe_List.add(satelite_Observe_Map); } //测试,输出第1个历元卫星号为G01的观测数据 System.out.println("存历元数据的HashMap集合的第一个历元卫星号为G01的观测数据" + epoch_Observe_Map.get(0).get("G01")); System.out.println("存历元数据的ArrayList集合的第一个历元卫星号为G01的观测数据" + epoch_Observe_List.get(0).get("G01")); } catch (FileNotFoundException e) { System.err.println("文件不存在!"); e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); }finally{ try { if(br != null){ br.close(); } if(fr != null){ fr.close(); } } catch (IOException e) { e.printStackTrace(); } } } }

    O文件下载:https://files.cnblogs.com/files/ludengxiadeyingzi/O%E6%96%87%E4%BB%B6.zip

  • 相关阅读:
    20210304
    20210303
    20210302
    20210210
    20210209
    20210208
    20210207
    例4-6
    例4-5
    例4-4
  • 原文地址:https://www.cnblogs.com/ludengxiadeyingzi/p/7430286.html
Copyright © 2011-2022 走看看