基于 Visual Studio C# 的 Hypack 测量成果 RAW 原始数据解算
前言
Hypack 是业界公认最好的水文导航测量软件,是目前世界上应用广泛的专业测量疏浚软件。它能够接收,处理,存储和输出各种数据。Hypack支持绝大部分GPS,测深仪(国内如海鹰HY1603单波束测沙仪),多波束测深仪,旁扫声纳,涌浪补偿器,水位仪,验潮仪以及声速剖面仪。利用 Hypack 可以进行导航,单波束测量,多波束测量,旁扫测量以及疏浚实时监测等。软件界面友好,使用方便。
本文讨论 Hypack 2016 版本的 RAW 数据文件解释和解析,暂时只展示了基础航路点的编程(一个计划线),多计划线只是增加测区自动适配计划线,以计算偏航距、在线距等,多计划线下的航路点不影响测点的坐标与水深计算。
- 涉及应用仪器设备:SP-6050H GPS、海鹰 HY1603 单波束测深仪
- 涉及应用测量软件:Hypack 2016
一、Hypack 2016 版本的 RAW 数据文件解释
1.1、Hypack MAX 6.5 版本 和 Hypack 2016 版本的 RAW 数据文件区别
1.1.1 Hypack 2016 RAW 数据文件定标数据后面附有测量点的平面坐标
FIX 99 45235.370 1508 632188.721 3214576.282
1.1.2 Hypack MAX 6.5 RAW 数据文件定标数据后面没有测量点的平面坐标。
- 老版本 RAW 数据文件定标数据只有头部标识、固定标识99、时间秒值、定标号,与 Hypack 2016 RAW 数据相比较,没有测量点平面坐标。
FIX 99 45235.370 1508
1.2、 一份Hypack 2016 版本的 RAW 数据文件(第一个FIX定标数据后面的没有提供,已经能够说明情况)
FTP NEW 2
VER 16.1.1.0
INF "" "" "CGCS2000" "" 0.000 0.000 0.000
ELL GRS-1980 6378137.000 298.257222101
PRO TME 111.000000 1.000000 0.000000 0.000000 0.000000 500000.0000 0.0000
DTM 0.00 0.00 0.00 0.00000 0.00000 0.00000 0.00000
GEO "" 0.000
HVU 1.0000000000 1.0000000000
TND 12:33:55 03/11/2024 -480
DEV 0 33141 "GPS NMEA-0183" 57348 D:\HYPACK 2016\devices\gps.dll 16.0.12.21
OFF 0 0.000 0.000 0.000 0.000 0.000 0.000 0.000
PRD 0 KTD "" "" ""
DDT 0 SYN KTC
DEV 1 16 "HY1601" 512 D:\HYPACK 2016\devices\ECHOTRAC.dll 14.0.2.6
OFF 1 0.000 0.000 0.000 0.000 0.000 0.000 0.000
LIN 2
PTS 632181.68 3214614.95
PTS 632231.17 3214281.81
LBP 632181.68 3214614.95
LNN 中断面
EOL
USR "FENERBAHCE" "NOT FOR COMMERCIAL USE" 0x1FF 1907
EOH 3AD3A31F27D1CC9E4C941DDCF63C86AEFAF2ED3E8B13E8B8446B85E20D85E16657AB85B5672A4F14C8B9AC22DDB0A33A87088DA9B9588104A8A15480C5AD54FD76C708EFBF5007FB36759C6744D1745F73D4781C6F658E99276F1682677B40381CBC9DF36B2881717C875D28B0DD29A36C55CA5D2CCB71829146920D72CDBE5D
MSG 0 45234.809 $GPGGA,043355.20,2902.461449,N,11221.426060,E,2,10,0.8,9.552,M,0.0,M,8.0,0643*78
GYR 0 45234.852 244.200
MSG 0 45234.852 $GPVTG,244.2,T,,M,0.34,N,0.64,K,P*19
MSG 0 45234.872 $GPZDA,043355.20,11,03,2024,00,00*67
EC1 1 45235.009 3.580
POS 0 45235.008 632188.747 3214576.302
QUA 0 45235.008 7 3.000 0.800 10.000 2.000 0.000 0.000 0.000
RAW 0 45235.008 4 290246.14380 1122142.60420 9.54800 43355.40000
MSG 0 45235.008 $GPGGA,043355.40,2902.461438,N,11221.426042,E,2,10,0.8,9.548,M,0.0,M,8.0,0643*73
GYR 0 45235.051 235.600
MSG 0 45235.051 $GPVTG,235.6,T,,M,0.35,N,0.65,K,P*1B
MSG 0 45235.071 $GPZDA,043355.40,11,03,2024,00,00*61
EC1 1 45235.209 3.580
POS 0 45235.208 632188.721 3214576.282
QUA 0 45235.208 7 3.000 0.800 10.000 2.000 0.000 0.000 0.000
RAW 0 45235.208 4 290246.14270 1122142.60260 9.54000 43355.60000
MSG 0 45235.208 $GPGGA,043355.60,2902.461427,N,11221.426026,E,2,10,0.8,9.540,M,0.0,M,8.0,0643*75
GYR 0 45235.251 233.200
MSG 0 45235.251 $GPVTG,233.2,T,,M,0.31,N,0.58,K,P*13
MSG 0 45235.271 $GPZDA,043355.60,11,03,2024,00,00*63
FIX 99 45235.370 1508 632188.721 3214576.282
1.3、Hypack RAW 原始数据文件标识解释
1.3.1 RAW 文件头部参数
标识符 | 示例数据(数据以空格分隔) | 数据解释 |
---|---|---|
FTP | FTP NEW 2 | 标识 NEW 2 (扩展名为 RAW 的原始数据文件) |
FTP | FTP NEW 3 | 标识 NEW 3 (扩展名为 VEL 的声速校正文件) |
FTP | FTP ALL 2 | 标识 ALL 2 (扩展名为 EDT 是对 RAW 文件进行单波束编辑器编辑后保存的文件) |
VER | VER 16.1.1.0 | 标识 Hypack软件版本 |
INF | INF “赵钱孙” “快艇518” “湖泊治理CGCS2000” “洞庭湖” 0.000 0.000 0.000 | 标识 测员 测船 项目 测区 潮汐校正 初步修正 声速 |
ELL | ELL GRS-1980 6378137.000 298.257222101 | 标识 椭球体名称 长半轴 扁率 (椭球信息) |
PRO | PRO TME 111.000000 1.000000 0.000000 0.000000 0.000000 500000.0000 0.0000 | 标识 投影名称 参考经度(中央子午线) 尺度 参考纬度 北平行线 南平行线 东移 北移 |
DTM | DTM 0.00 0.00 0.00 0.00000 0.00000 0.00000 0.00000 | 标识 X平移 Y平移 Z平移 X旋转 Y旋转 Z旋转 旋转尺度S |
GEO | GEO “” 0.000 | 标识 水准面名称 垂直高度校正 |
HVU | HVU 1.0000000000 1.0000000000 | 标识 水平乘数 垂直乘数 (测量单位转换为米的乘数) |
TND | TND 12:33:55 03/11/2024 -480 | 标识 时间 日期 时差(分钟) |
DEV | DEV 0 33141 “GPS NMEA-0183” 57348 D:\HYPACK 2016\devices\gps.dll 16.0.12.21 | 标识 驱动号 设备功能 设备名称 设备码 设备驱动目录 版本 |
OFF | OFF 0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 | 标识 设备编号 左右舷偏移 前向偏移 天线高度或换能器吃水深度偏移 偏航旋转角度 横摇旋转角度 纵摇旋转角度 设备延迟(秒) |
PRD | PRD 0 KTD “” “” “” | 标识 设备号 专用设备 |
DDT | DDT 0 SYN KTC | 标识 设备号 同步标识 |
DEV | DEV 1 16 “HY1601” 512 D:\HYPACK 2016\devices\ECHOTRAC.dll 14.0.2.6 | 标识 驱动号 设备功能 设备名称 设备码 设备驱动目录 版本 |
OFF | OFF 1 0.000 0.000 0.000 0.000 0.000 0.000 0.000 | 标识 设备编号 左右舷偏移 前向偏移 天线高度或换能器吃水深度偏移 偏航旋转角度 横摇旋转角度 纵摇旋转角度 设备延迟(秒) |
LIN | LIN 2 | 标识 计划线或航路点数量 |
PTS | PTS 632181.68 3214614.95 | 标识 东西坐标 南北坐标 |
PTS | PTS 632231.17 3214281.81 | 标识 东西坐标 南北坐标 |
LBP | LBP 632181.68 3214614.95 | 标识 东西坐标 南北坐标(计划线起点) |
LNN | LNN 中断面 | 标识 计划线名称或序号 |
EOL | EOL | 标识(计划线结束) |
USR | USR “FENERBAHCE” “USE” 0x1FF 2084 | 标识 Hypak用户名 经销商 注册标识 注册代号 |
EOH | EOH 3AD3A31F27D1CC9E4C941DDCF63C86AEFAF2ED3E8B13… | 标识(标头消息结束) |
EOH 随后就是测量数据 |
1.3.2 RAW 文件测量数据(关键定位测深标识符)
标识符 | 示例数据(数据以空格分隔) | 数据解释 |
---|---|---|
POS | POS 0 45235.008 632188.747 3214576.302 | 标识 驱动号 午夜后时间秒数 东西坐标 南北坐标 |
QUA | QUA 0 45235.008 7 3.000 0.800 10.000 2.000 0.000 0.000 0.000 | 标识 驱动号 秒数 随后数据个数 10分钟HDOP HDOP 卫星数 定位精度 (定位质量信息) |
RAW | RAW 0 45235.008 4 290246.14380 1122142.60420 9.54800 43355.40000 | 标识 驱动号 秒数 数据个数 纬度X100 经度X100 天线椭球高 GPS时间 |
MSG | MSG 0 45235.008 $GPGGA,043355.40,2902.461438,N,11221.426042,E,2,10,0.8,9.548,M,0.0,M,8.0,0643*73 | 标识 设备号 秒数 GPS报文 【$ GPGGA、$ GPVTG、$ GPZDA等消息】 |
GYR | GYR 0 45235.051 235.600 | 标识 驱动号 秒数 船舶航向角 【陀螺仪数据(航向)】 |
MSG | MSG 0 45235.051 $GPVTG,235.6,T,M,0.35,N,0.65,K,P*1B | 标识 设备号 秒数 GPS报文 【$ GPGGA、$ GPVTG、$ GPZDA等消息】 |
MSG | MSG 0 45235.071 $GPZDA,043355.40,11,03,2024,00,00*61 | 标识 设备号 秒数 GPS报文 【$ GPGGA、$ GPVTG、$ GPZDA等消息】 |
EC1 | EC1 1 45235.209 3.580 | 标识 驱动号 秒数 原始水深 |
FIX | FIX 99 45235.370 1508 632188.721 3214576.282 | 标识 固定数 秒数 定标数 东西位置 南北位置 |
EC2 | EC2 1 45235.209 3.580 3.580 | 标识 驱动号 秒数 原始水深1 原始水深2【双频测深仪】 |
二、Hypack 2016 单波束测深仪测量 RAW 原始数据解算
以下实例代码均以航路点只有 2 个的前提下进行的程序方案,标识 LIN 2 的情况,即单计划线,断面线方案。不涉及航路点 2 个以上。多航路点如果需要计算偏航距、测点投影,要根据航路点切换起始点坐标。
2.1 Hypack 2016 单波束测深仪测量 RAW 原始数据文件的编码识别
参见博文:https://blog.youkuaiyun.com/zyyujq/article/details/142600284
2.2 Visual Studio C# 读取的 Hypack 2016 单波束测深仪测量 RAW 原始数据
List<string> ListSurveyParam = new List<string>();//测量参数
List<double> ListEc1Time = new List<double>();//水深时间
List<double> ListEc1WDepth = new List<double>();//水深时间
List<double> ListPosTime = new List<double>();// 定位时间
List<double> ListPosEast = new List<double>();// 定位坐标东
List<double> ListPosNorth = new List<double>();// 定位坐标北
List<double> ListRawTime = new List<double>();//原始时间
List<double> ListRawLon = new List<double>();// 原始经度
List<double> ListRawLat = new List<double>();// 原始纬度
List<double> ListRawHeight = new List<double>();//原始椭球高
List<double> ListFixTime = new List<double>();//打标时间
List<double> ListFixNumber = new List<double>();//打标序号
List<double> ListFixEast = new List<double>();// 打标坐标东
List<double> ListFixNorth = new List<double>();// 打标坐标北
List<double> ListAddTime = new List<double>();//添加打标时间
List<double> ListAddNumber = new List<double>();//添加打标序号
List<double> ListAddEast = new List<double>();// 添加打标坐标东
List<double> ListAddNorth = new List<double>();// 添加打标坐标北
List<double> ListDelTime = new List<double>();//删除打标时间
List<double> ListDelNumber = new List<double>();//删除打标序号
Encoding encoding = Common.GetEncoding(inFile);
using (StreamReader sr = new StreamReader(inFile, encoding))
{
string RawDataLine = sr.ReadLine();
if (RawDataLine != "FTP NEW 2") return;
List<string> PTS = new List<string>();//起止点
while ((RawDataLine = sr.ReadLine()) != null)
{
if (RawDataLine.Length < 3) break;//
string RowHeader = RawDataLine.Substring(0, 3);//头部标识
string[] SplitString = null;
switch (RowHeader)
{
case "FTP"://Hypak文件标识符
//SplitString = RawDataLine.Split(' ');
//string FTP = SplitString[1];
//if (FTP != "NEW") return;
break;
case "VER"://Hypak版本
SplitString = RawDataLine.Split(' ');
ListSurveyParam.Add(SplitString[1]);
break;
case "INF"://测验信息
SplitString = RawDataLine.Split(' ');
ListSurveyParam.Add(SplitString[1].Replace('"', ' '));
ListSurveyParam.Add(SplitString[2].Replace('"', ' '));
ListSurveyParam.Add(SplitString[3].Replace('"', ' '));
ListSurveyParam.Add(SplitString[4].Replace('"', ' '));
break;
case "ELL"://椭球信息
SplitString = RawDataLine.Split(' ');
if (SplitString.Length == 3)
{
ListSurveyParam.Add("");
ListSurveyParam.Add(SplitString[1].Replace('"', ' '));
ListSurveyParam.Add(SplitString[2]);
}
else
{
ListSurveyParam.Add(SplitString[1]);
ListSurveyParam.Add(SplitString[2]);
ListSurveyParam.Add(SplitString[3]);
}
break;
case "PRO"://投影信息记录
SplitString = RawDataLine.Split(' ');
ListSurveyParam.Add(SplitString[1]);
ListSurveyParam.Add(SplitString[2]);
ListSurveyParam.Add(SplitString[3]);
ListSurveyParam.Add(SplitString[4]);
ListSurveyParam.Add(SplitString[7]);
ListSurveyParam.Add(SplitString[8]);
break;
case "DTM"://基准转换七参数
SplitString = RawDataLine.Split(' ');
ListSurveyParam.Add(SplitString[1]);
ListSurveyParam.Add(SplitString[2]);
ListSurveyParam.Add(SplitString[3]);
ListSurveyParam.Add(SplitString[4]);
ListSurveyParam.Add(SplitString[5]);
ListSurveyParam.Add(SplitString[6]);
ListSurveyParam.Add(SplitString[7]);
break;
case "GEO"://大地水准面信息
break;
case "HVU"://水平和垂直单位的乘数
break;
case "TND"://测验时间和日期
SplitString = RawDataLine.Split(' ');
string DateString = SplitString[1].Trim() + " " + SplitString[2].Trim();//-480/60=8为时区
string format = "HH:mm:ss MM/dd/yyyy";
DateTime dateTime;
DateTime.TryParseExact(DateString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime);//日期标准格式化
ListSurveyParam.Add(dateTime.ToString());
break;
case "DEV"://设备信息
break;
case "OFF"://设备偏移
break;
case "PRD"://专用设备数据
break;
case "LIN"://计划线航路点数 (LIN 2)标识 航路点数量
break;
case "PTS"://计划线航点起点和终点
SplitString = RawDataLine.Split('S');
PTS.Add(SplitString[1].Trim());
break;
case "LBP"://计划线起点
SplitString = RawDataLine.Split('P');
PTS.Add(SplitString[1].Trim());
PTS = PTS.Distinct().ToList();
string StartPoint = SplitString[1].Trim();
string[] coord = StartPoint.Split(' ');
ListSurveyParam.Add(coord[0]);
ListSurveyParam.Add(coord[1]);
string EndPoint;
if (StartPoint == PTS[0])
{
EndPoint = PTS[1];
coord = EndPoint.Split(' ');
ListSurveyParam.Add(coord[0]);
ListSurveyParam.Add(coord[1]);
}
else
{
EndPoint = PTS[0];
coord = EndPoint.Split(' ');
ListSurveyParam.Add(coord[0]);
ListSurveyParam.Add(coord[1]);
}
break;
case "LNN"://计划线名称或序号
SplitString = RawDataLine.Split(' ');
ListSurveyParam.Add(SplitString[1]);
break;
case "EOL"://计划线结束
break;
case "USR"://Hypak用户
break;
case "EOH"://Hypak标头消息结束。
break;
case "MSG"://$GPGGA、$GPVTG、$GPZDA等消息
break;
case "GYR"://陀螺仪数据(航向)
break;
case "SYN"://时间同步状态
break;
case "EC1"://回声探测(单频)水深消息
SplitString = RawDataLine.Split(' ');
ListEc1Time.Add(Convert.ToDouble(SplitString[2]));
ListEc1WDepth.Add(Convert.ToDouble(SplitString[3]));
break;
case "EC2"://回声探测(双频)水深消息
break;
case "POS"://平面坐标位置消息
SplitString = RawDataLine.Split(' ');
ListPosTime.Add(Convert.ToDouble(SplitString[2]));
ListPosEast.Add(Convert.ToDouble(SplitString[3]));
ListPosNorth.Add(Convert.ToDouble(SplitString[4]));
break;
case "QUA"://定位质量信息
break;
case "RAW"://原始定位坐标
SplitString = RawDataLine.Split(' ');
ListRawTime.Add(Convert.ToDouble(SplitString[2]));
double LON = Convert.ToDouble(SplitString[5]) / 10000;
double LAT = Convert.ToDouble(SplitString[4]) / 10000;
double LonDeg = (int)LON + (LON - (int)(LON)) * 100 / 60;
double LatDeg = (int)LAT + (LAT - (int)(LAT)) * 100 / 60;
ListRawLon.Add(LonDeg);
ListRawLat.Add(LatDeg);
ListRawHeight.Add(Convert.ToDouble(SplitString[6]));
break;
case "FIX"://固定(事件)标记打标消息
SplitString = RawDataLine.Split(' ');
if (SplitString.Length == 6)
{
ListFixTime.Add(Convert.ToDouble(SplitString[2]));
ListFixNumber.Add(Convert.ToDouble(SplitString[3]));
ListFixEast.Add(Convert.ToDouble(SplitString[4]));
ListFixNorth.Add(Convert.ToDouble(SplitString[5]));
}
else if (SplitString.Length == 4)
{
ListFixTime.Add(Convert.ToDouble(SplitString[2]));
ListFixNumber.Add(Convert.ToInt32(SplitString[3]));
ListFixEast.Add(-1);
ListFixNorth.Add(-1);
}
break;
case "Add"://适应河道软件处理
case "ADD"://添加测点
SplitString = RawDataLine.Split(' ');
if (SplitString.Length == 6)
{
ListAddTime.Add(Convert.ToDouble(SplitString[2]));
ListAddNumber.Add(Convert.ToDouble(SplitString[3]));
ListAddEast.Add(Convert.ToDouble(SplitString[4]));
ListAddNorth.Add(Convert.ToDouble(SplitString[5]));
}
else if (SplitString.Length == 4)
{
ListAddTime.Add(Convert.ToDouble(SplitString[2]));
ListAddNumber.Add(Convert.ToDouble(SplitString[1]));
ListAddEast.Add(-1);
ListAddNorth.Add(-1);
}
break;
case "Del":
case "DEL"://加入测点
SplitString = RawDataLine.Split(' ');
ListDelTime.Add(Convert.ToDouble(SplitString[2]));
ListDelNumber.Add(Convert.ToDouble(SplitString[3]));
break;
}
}
}
2.3 Visual Studio C# 解算 RAW 原始数据
2.3.1 解算水深测量 EC1 定位坐标
//根据 POS 定位数据和时间数据,以航速计算插补 EC1 水深的定位坐标
for (int i = 0; i < EC1Leng; i++)
{
for (int j = 0; j < POSLeng; j++)
{
if (j + 1 == POSLeng)//最后一个EC1无EC1Time[j + 1]
{
EC1East[i] = POSEast[j] + (POSEast[j] - POSEast[j - 1]) / (POSTime[j] - POSTime[j - 1]) * (EC1Time[i] - POSTime[j]);//水深点东坐标
EC1North[i] = POSNorth[j] + (POSNorth[j] - POSNorth[j - 1]) / (POSTime[j] - POSTime[j - 1]) * (EC1Time[i] - POSTime[j]);//水深点北坐标
break;
}
if ((EC1Time[i] <= POSTime[j + 1]) && (EC1Time[i] >= POSTime[j]))
{
EC1East[i] = POSEast[j] + (POSEast[j + 1] - POSEast[j]) / (POSTime[j + 1] - POSTime[j]) * (EC1Time[i] - POSTime[j]);//水深点东坐标
EC1North[i] = POSNorth[j] + (POSNorth[j + 1] - POSNorth[j]) / (POSTime[j + 1] - POSTime[j]) * (EC1Time[i] - POSTime[j]);//水深点北坐标
break;
}
}
}
2.3.2 解算水深测量 FIX 定标水深
//根据 EC1 定位和水深数据,以三角函数关系计算插补 FIX 打标的水深
for (int i = 0; i < FIXLeng; i++)
{
for (int j = 0; j < EC1Leng; j++)
{
if (j + 1 == EC1Leng)//最后一个FIX无EC1Time[j + 1]
{
double L1 = Pow(FIXEast[i] - EC1East[j - 1], 2) + Pow(FIXNorth[i] - EC1North[j - 1], 2);//距离
double L2 = Pow(EC1East[j] - EC1East[j - 1], 2) + Pow(EC1North[j] - EC1North[j - 1], 2);
FIXWDepth[i] = (EC1WDepth[j] - EC1WDepth[j - 1]) * L1 / L2 + EC1WDepth[j];
//Console.WriteLine(FIXWDepth[i]);
break;
}
if ((FIXTime[i] <= EC1Time[j + 1]) && (FIXTime[i] >= EC1Time[j]))
{
double L1 = Pow(EC1East[j + 1] - EC1East[j], 2) + Pow(EC1North[j + 1] - EC1North[j], 2);//距离
double L2 = Pow(FIXEast[i] - EC1East[j], 2) + Pow(FIXNorth[i] - EC1North[j], 2);
FIXWDepth[i] = (EC1WDepth[j + 1] - EC1WDepth[j]) * L2 / L1 + EC1WDepth[j];//打标处水深
break;
}
}
}
2.3.3 解算午夜后时间的秒数
///<summary>输出小时函数</summary>
///<param name="IntupSecond">输入午夜后的秒数</param>
///<param name="Rounding">是否取整布尔判断</param>
public static double CHour(double IntupSecond, bool Rounding = true) //转换小时
{
double tempCHour = 0;
if (Rounding)
{
tempCHour = (int)(IntupSecond / 3600); //取整
}
else
{
tempCHour = (IntupSecond / 3600); //不取整
}
return tempCHour;
}
///<summary>输出分钟函数</summary>
///<param name="IntupSecond">输入午夜后的秒数</param>
///<param name="Rounding">是否取整布尔判断</param>
public static double CMinute(double IntupSecond, bool Rounding = true) //转换分钟
{
double tempCMinute = 0;
if (Rounding)
{
tempCMinute = (int)((CHour(IntupSecond, false) - CHour(IntupSecond)) * 60); //取整
}
else
{
tempCMinute = (CHour(IntupSecond, false) - CHour(IntupSecond)) * 60; //不取整
}
return tempCMinute;
}
///<summary>输出秒函数</summary>
///<param name="IntupSecond">输入午夜后的秒数</param>
///<param name="Rounding">是否取整布尔判断</param>
public static double CSecond(double IntupSecond, bool Rounding = true) //转换秒
{
double tempCSecond = 0;
if (Rounding)
{
tempCSecond = (int)((CMinute(IntupSecond, false) - CMinute(IntupSecond)) * 60); //取整
}
else
{
tempCSecond = (CMinute(IntupSecond, false) - CMinute(IntupSecond)) * 60; //不取整
}
return tempCSecond;
}
///<summary>输出时间函数</summary>
///<param name="IntupSecond">输入午夜后的秒数</param>
public static string GetTime(double IntupSecond)
{
return CHour(IntupSecond).ToString("00") + ":" + CMinute(IntupSecond).ToString("00") + ":" + CSecond(IntupSecond, false).ToString("00.00");
}
}
2.3.4 数据计算的公共计算类(包含重载)
public class Common
{
/// <summary>计算点距</summary>
/// <param name="StartDotEast">起点东坐标</param>
/// <param name="StartDotNorth">起点北坐标</param>
/// <param name="EndDotEast">终点东坐标</param>
/// <param name="EndDotNorth">终点北坐标</param>
/// <returns>返回两点间距离</returns>
public static double Distance(double StartDotEast, double StartDotNorth, double EndDotEast, double EndDotNorth)
{
double D = Sqrt(Pow(EndDotEast - StartDotEast, 2) + Pow(EndDotNorth - StartDotNorth, 2));
return D;
}
/// <summary>计算点距</summary>
///<param name="EastDiff">输入两点坐标东向差cX</param>
///<param name="NorthDiff">输入两点坐标北向差cY</param>
/// <returns>返回两点间距离</returns>
public static double Distance(double EastDiff, double NorthDiff)
{
double D = Sqrt(Pow(EastDiff, 2) + Pow(NorthDiff, 2));
return D;
}
/// <summary>度数转弧度</summary>
/// <param name="Degrees">度数</param>
/// <returns>返回弧度值</returns>
public static double DegreesToRadian(double Degrees)
{
return Degrees * PI / 180;
}
/// <summary>弧度转度数</summary>
/// <param name="Radian">弧度</param>
/// <returns>返回角度值(度)</returns>
public static double RadianToDegrees(double Radian)
{
return Radian * 180 / PI;
}
///<summary>方位角计算函数</summary>
/// <param name="StartDotEast">起点东坐标</param>
/// <param name="StartDotNorth">起点北坐标</param>
/// <param name="EndDotEast">终点东坐标</param>
/// <param name="EndDotNorth">终点北坐标</param>
/// <returns>返回方位角(度)</returns>
public static double AzimuthCalc(double StartDotEast, double StartDotNorth, double EndDotEast, double EndDotNorth)
{
double Azimuth = 0;
double EastDiff = EndDotEast - StartDotEast;
double NorthDiff = EndDotNorth - StartDotNorth;
if (NorthDiff == 0)
{
NorthDiff = 0.0000000001;
}
if (NorthDiff > 0 & EastDiff > 0) //第一象
{
Azimuth = Atan(EastDiff / NorthDiff) * 180 / PI;
}
else if ((NorthDiff < 0 & EastDiff > 0) || (NorthDiff < 0 & EastDiff < 0)) //第二象 第三象
{
Azimuth = (PI + Atan(EastDiff / NorthDiff)) * 180 / PI;
}
else if (NorthDiff > 0 & EastDiff < 0) //第四象
{
Azimuth = (2 * PI + Atan(EastDiff / NorthDiff)) * 180 / PI;
}
return Round46(Azimuth, 5); //保留5位保证度分秒精确
}
///<summary>方位角计算函数</summary>
///<param name="EastDiff">输入两点坐标东向差cX</param>
///<param name="NorthDiff">输入两点坐标北向差cY</param>
/// <returns>返回方位角(度)</returns>
public static double AzimuthCalc(double EastDiff, double NorthDiff)
{
double Azimuth = 0;
if (NorthDiff == 0)
{
NorthDiff = 0.0000000001;
}
if (NorthDiff > 0 & EastDiff > 0) //第一象
{
Azimuth = Atan(EastDiff / NorthDiff) * 180 / PI;
}
else if ((NorthDiff < 0 & EastDiff > 0) || (NorthDiff < 0 & EastDiff < 0)) //第二象 第三象
{
Azimuth = (PI + Atan(EastDiff / NorthDiff)) * 180 / PI;
}
else if (NorthDiff > 0 & EastDiff < 0) //第四象
{
Azimuth = (2 * PI + Atan(EastDiff / NorthDiff)) * 180 / PI;
}
return Round46(Azimuth,5); //保留5位保证度分秒精确
}
///<summary>四舍六入(小数位数)</summary>
///<param name="InputValue">输入要四舍六入的数值</param>
///<param name="DecimalPlaces">输入要四舍六入数值的小数位数,默认为保留三位小数</param>
/// <returns>返回双精度四舍六入值</returns>
public static double Round46(double InputValue, int DecimalPlaces = 3)
{
double tmpValue = 0;
long tmpLong = 0;
InputValue = Round(InputValue, DecimalPlaces + 3); //预处理输入的浮点数据
tmpValue = InputValue * Pow(10, DecimalPlaces);
tmpLong = Convert.ToInt64(tmpValue); //转换为长整数进行修约
return tmpLong / (Pow(10, DecimalPlaces));
}
///<summary>四舍六入函数(有效位数)</summary>
///<param name="InputValue">输入要四舍六入的数值</param>
///<param name="type">格式化类型水深标识H</param>
///<param name="Enob">输入要四舍六入数值的有效位数,默认为三位有效位数</param>
/// <returns>返回字符串四舍六入值</returns>
public static string Round46(double InputValue, string type, int Enob = 3)
{
int IntIN = (int)Common.Round46(InputValue, 1);//预处理可入或可进位的数
double Value; string format;
string Datatype = type.ToUpper();
if (IntIN >= 100)
{
int leng = IntIN.ToString().Length;
Value = Common.Round46(InputValue, Enob - leng);
return Value.ToString("0");
}
else if (IntIN >= 10 && IntIN < 100)
{
Value = Common.Round46(InputValue, Enob - 2);
format = "0.".PadRight(Enob, '0');
return Value.ToString(format);
}
else if (IntIN >= 1 && IntIN < 10)
{
if (Datatype == "H")
{
Value = Common.Round46(InputValue, Enob - 1);
if (Value >= 5)
{
Value = Common.Round46(InputValue, Enob - 2);
format = "0.".PadRight(Enob, '0');
return Value.ToString(format);
}
else
{
Value = Common.Round46(InputValue, Enob - 1);
format = "0.".PadRight(Enob + 1, '0');
return Value.ToString(format);
}
}
else
{
Value = Common.Round46(InputValue, Enob - 1);
format = "0.".PadRight(Enob + 1, '0');
return Value.ToString(format);
}
}
else //if (IntIN == 0)
{
Value = Common.Round46(InputValue, Enob);
if (Value < 0.1)
{
Value = Common.Round46(InputValue, Enob);
format = "0.".PadRight(Enob + 2, '0');
return Value.ToString(format);
}
else//0.099
{
Value = Common.Round46(InputValue, Enob - 1);
format = "0.".PadRight(Enob + 1, '0');
return Value.ToString(format);
}
}
}
}
2.3.5 其它数据的解算(POS、EC2等)
可以参照以上代码进行解算
三、Visual Studio C# 显示解算的原始数据进行绘图
3.1 显示和绘图
string[] SP = new string[0];//测站参数
double[,] POS = new double[0, 7]; //创建定位坐标二维数组
double[,] EC1 = new double[0, 4]; //创建水深二维数组
double[,] FIX = new double[0, 5];//创建打标水深二维数组
double[,] ADD = new double[0, 5];//创建添加水深二维数组
NotLoadData = false;//已载入数据
RawFilePath = Openfiledialog.FileName;
StatusLabel6.Text = RawFilePath;
RawLineMarksBool = false;
HypackRAW.RAWconvert(RawFilePath, ref SP, ref POS, ref EC1, ref FIX, ref ADD);//Hypack RAW 解算类
//将参数载入控件与定义
for (int i = 0; i < SP.Length; i++)
{
// Console.WriteLine("{0} , {1}", string.IsNullOrEmpty(inBOX), string.IsNullOrWhiteSpace(inBOX));
groupBox3.Controls["textBox" + i.ToString()].Text = SP[i];
switch (i)
{
case 3:
StationName = SP[i];
break;
case 22:
StartDotCoordEast = Convert.ToDouble(SP[i]);
break;
case 23:
StartDotCoordNorth = Convert.ToDouble(SP[i]);
break;
case 24:
EndDotCoordEast = Convert.ToDouble(SP[i]);
break;
case 25:
EndDotCoordNorth = Convert.ToDouble(SP[i]);
break;
case 26:
PlannedLineName = SP[i];
break;
}
}
EC1PointDistance = new double[EC1.GetLength(0)];
EC1OnlineDistance = new double[EC1.GetLength(0)];
EC1WaterDepth = new double[EC1.GetLength(0)];
POSWaterDepth = new double[POS.GetLength(0)];
double PlannedLineAzimuth = DegreesToRadian(AzimuthCalc(StartDotCoordEast, StartDotCoordNorth, EndDotCoordEast, EndDotCoordNorth));//计划线方位角
double MaxWaterDepth = 0; double MaxDistance = 0; double MinDistance = 1000000;
MaxSecond = 0; MinSecond = 1000000;
for (int i = 0; i < POS.GetLength(0); i++)
{
double Second = POS[i, 0];
double X = Common.Round46(POS[i, 4]);
double Y = Common.Round46(POS[i, 5]);
POSWaterDepth[i] = Convert.ToDouble(Common.Round46(POS[i, 6], "H"));
double POSPointDistance = Distance(StartDotCoordEast, StartDotCoordNorth, X, Y);//点距到点距
double MeasureLine = DegreesToRadian(AzimuthCalc(StartDotCoordEast, StartDotCoordNorth, X, Y));//测线方位角
double POSOnlineDistance = Cos(MeasureLine - PlannedLineAzimuth) * POSPointDistance;//在线距
MaxWaterDepth = Max(MaxWaterDepth, POSWaterDepth[i]);//最大水深
MaxDistance = Max(MaxDistance, POSOnlineDistance);//最大在线距离
MinDistance = Min(MinDistance, POSOnlineDistance);//最小在线距离
MaxSecond = Max(MaxSecond, Second);//最大秒数
MinSecond = Min(MinSecond, Second);//最小秒数
}
double Xwide = Math.Abs(EndDotCoordEast - StartDotCoordEast);//X宽
double Ywide = Math.Abs(EndDotCoordNorth - StartDotCoordNorth);//Y宽
double Xcenter = (StartDotCoordEast + EndDotCoordEast) / 2;//X中心
double Ycenter = (StartDotCoordNorth + EndDotCoordNorth) / 2;//Y中心
double XYwideMax = Math.Max(Xwide, Ywide);//最大图幅XY宽
double Inter = Math.Pow(10, ((int)XYwideMax).ToString().Length - 1);//图幅位数,坐标间隔
XMin = Math.Round((Xcenter - XYwideMax / 2) / 10, 0) * 10 - 50;
YMin = Math.Round((Ycenter - XYwideMax / 2) / 10, 0) * 10 - 50;
XMax = Math.Round((Xcenter + XYwideMax / 2) / 10, 0) * 10 + 50;
YMax = Math.Round((Ycenter + XYwideMax / 2) / 10, 0) * 10 + 50;
chart1.Series.Clear();// 清除Chart控件中所有系列
chart2.Series.Clear();// 清除Chart控件中所有系列
chart3.Series.Clear();// 清除Chart控件中所有系列
if (string.IsNullOrEmpty(PlannedLineName)) PlannedLineName = "未知计划线名";
#region "平面图 初始化"
//区域边框实线
chart1.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
// 设置X和Y轴的标签
chart1.ChartAreas[0].AxisX.Title = "东向坐标 X (m)";
chart1.ChartAreas[0].AxisY.Title = "北向坐标 Y (m)";
// X坐标范围最大最小
chart1.ChartAreas[0].AxisX.Minimum = XMin;
chart1.ChartAreas[0].AxisX.Maximum = XMax;
// X坐标范围最大最小
chart1.ChartAreas[0].AxisY.Minimum = YMin;
chart1.ChartAreas[0].AxisY.Maximum = YMax;
// 坐标轴间隔
chart1.ChartAreas[0].AxisX.Interval = Inter / 2;
chart1.ChartAreas[0].AxisY.Interval = Inter / 2;
// 设置 X 坐标轴和 Y 坐标轴刻度的格式
chart1.ChartAreas[0].AxisX.LabelStyle.Format = "0";
chart1.ChartAreas[0].AxisY.LabelStyle.Format = "0";
// 显示主坐标网格线
chart1.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
chart1.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
// 主坐标网格线间隔
chart1.ChartAreas[0].AxisX.MajorGrid.Interval = Inter;
chart1.ChartAreas[0].AxisY.MajorGrid.Interval = Inter;
// 显示主坐标网格 X轴和Y轴的刻度
chart1.ChartAreas[0].AxisX.MajorTickMark.Enabled = true;
chart1.ChartAreas[0].AxisY.MajorTickMark.Enabled = true;
// 设置主网格线为点
chart1.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
chart1.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
// 设置主网格线颜色
chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Black;
chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Black;
// 显示次坐标网格线
chart1.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
chart1.ChartAreas[0].AxisY.MinorGrid.Enabled = true;
// 次坐标网格线间隔
chart1.ChartAreas[0].AxisX.MinorGrid.Interval = Inter / 10;
chart1.ChartAreas[0].AxisY.MinorGrid.Interval = Inter / 10;
// 显示次坐标网格 X轴和Y轴的刻度
chart1.ChartAreas[0].AxisX.MinorTickMark.Enabled = true;
chart1.ChartAreas[0].AxisY.MinorTickMark.Enabled = true;
// 设置次网格线为点
chart1.ChartAreas[0].AxisX.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
chart1.ChartAreas[0].AxisY.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
// 设置次网格线颜色
chart1.ChartAreas[0].AxisX.MinorGrid.LineColor = Color.LightGray;
chart1.ChartAreas[0].AxisY.MinorGrid.LineColor = Color.LightGray;
//缩放状态禁止显示滚动条
chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = false;
chart1.ChartAreas[0].AxisY.ScrollBar.Enabled = false;
// 如果你想要更多的自定义设置,可以设置鼠标滚轮的行为
chart1.ChartAreas[0].AxisX.ScaleView.Zoomable = true; // 横向轴允许缩放
chart1.ChartAreas[0].AxisY.ScaleView.Zoomable = true; // 纵向轴允许缩放
// 如果需要,还可以设置选中区域的样式
chart1.ChartAreas[0].CursorX.SelectionColor = Color.Blue;
chart1.ChartAreas[0].CursorY.SelectionColor = Color.Blue;
// 将Chart置于放大状态
chart1.ChartAreas[0].CursorX.AutoScroll = true;
chart1.ChartAreas[0].CursorY.AutoScroll = true;
//启用游标鼠标滚动放大
chart1.ChartAreas[0].AxisX.ScaleView.Zoom(XMin, XMax);
chart1.ChartAreas[0].AxisY.ScaleView.Zoom(YMin, YMax);
chart1.ChartAreas[0].AxisX.IsMarginVisible = true;
chart1.ChartAreas[0].AxisY.IsMarginVisible = true;
chart1.ChartAreas[0].AxisX.ScaleBreakStyle.Enabled = false;
chart1.ChartAreas[0].AxisY.ScaleBreakStyle.Enabled = false;
//chart1.ChartAreas[0].AxisX.ScaleView.MinSize = chart1.ChartAreas[0].AxisY.ScaleView.MinSize = 1;
//chart1.ChartAreas[0].AxisX.IsLogarithmic = chart1.ChartAreas[0].AxisY.IsLogarithmic = true;
// 可以设置更多样式,如图表标题和图例等
chart1.Titles.Clear();
chart1.Titles.Add(StationName);
chart1.Titles[0].Text = StationName;
//chart1.Legends.Add("Legend");//图例
chart1.Legends[0].BackColor = Color.Transparent;
#endregion
#region "起点距⁓水深 剖面图 初始化"
chart2.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
chart2.ChartAreas[0].AxisY.IsReversed = true;//反转Y坐标
// 设置X和Y轴的标签
chart2.ChartAreas[0].AxisX.Title = "起点距 X (m)";
chart2.ChartAreas[0].AxisY.Title = "水深 Y (m)";
// X坐标范围最大最小
double PlanLineLength = Distance(Xwide, Ywide);// Math.Sqrt(Math.Pow(Xwide, 2) + Math.Pow(Ywide, 2));//计划线长
chart2.ChartAreas[0].AxisX.Minimum = (int)MinDistance - 5;
chart2.ChartAreas[0].AxisX.Maximum = Round46(MaxDistance, 0) + 5;
// X坐标范围最大最小
chart2.ChartAreas[0].AxisY.Minimum = 0;
chart2.ChartAreas[0].AxisY.Maximum = Round46(MaxWaterDepth, 0) + 2;
// 坐标轴间隔
chart2.ChartAreas[0].AxisX.Interval = 10;
chart2.ChartAreas[0].AxisY.Interval = 5;
// 设置 X 坐标轴和 Y 坐标轴刻度的格式
chart2.ChartAreas[0].AxisX.LabelStyle.Format = "0";
chart2.ChartAreas[0].AxisY.LabelStyle.Format = "0.0";
// 显示主坐标网格线
chart2.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
chart2.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
// 主坐标网格线间隔
chart2.ChartAreas[0].AxisX.MajorGrid.Interval = 10;
chart2.ChartAreas[0].AxisY.MajorGrid.Interval = 5;
// 显示主坐标网格 X轴和Y轴的刻度
chart2.ChartAreas[0].AxisX.MajorTickMark.Enabled = true;
chart2.ChartAreas[0].AxisY.MajorTickMark.Enabled = true;
// 设置主网格线为点
chart2.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
chart2.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
// 设置主网格线颜色
chart2.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Black;
chart2.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Black;
// 显示次坐标网格线
chart2.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
chart2.ChartAreas[0].AxisY.MinorGrid.Enabled = true;
// 次坐标网格线间隔
chart2.ChartAreas[0].AxisX.MinorGrid.Interval = 1;
chart2.ChartAreas[0].AxisY.MinorGrid.Interval = 1;
// 显示次坐标网格 X轴和Y轴的刻度
chart2.ChartAreas[0].AxisX.MinorTickMark.Enabled = true;
chart2.ChartAreas[0].AxisY.MinorTickMark.Enabled = true;
// 设置次网格线为点
chart2.ChartAreas[0].AxisX.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
chart2.ChartAreas[0].AxisY.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
// 设置次网格线颜色
chart2.ChartAreas[0].AxisX.MinorGrid.LineColor = Color.LightGray;
chart2.ChartAreas[0].AxisY.MinorGrid.LineColor = Color.LightGray;
//缩放状态禁止显示滚动条
chart2.ChartAreas[0].AxisX.ScrollBar.Enabled = false;
chart2.ChartAreas[0].AxisY.ScrollBar.Enabled = false;
// 如果你想要更多的自定义设置,可以设置鼠标滚轮的行为
chart2.ChartAreas[0].AxisX.ScaleView.Zoomable = true; // 横向轴允许缩放
chart2.ChartAreas[0].AxisY.ScaleView.Zoomable = false; // 纵向轴禁止缩放
// 将Chart置于放大状态
chart2.ChartAreas[0].CursorX.AutoScroll = true;
chart2.ChartAreas[0].CursorY.AutoScroll = false;
//启用游标鼠标滚动放大
chart2.ChartAreas[0].AxisX.ScaleView.Zoom((int)MinDistance - 5, Round46(MaxDistance, 0) + 5);
chart2.Legends[0].BackColor = Color.Transparent;
#endregion
#region "时间⁓水深 剖面图 初始化"
chart3.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
chart3.ChartAreas[0].AxisY.IsReversed = true;//反转Y坐标
// 设置X和Y轴的标签
chart3.ChartAreas[0].AxisX.Title = "时间 (s)";
chart3.ChartAreas[0].AxisY.Title = "水深 Y (m)";
// X坐标范围最大最小
chart3.ChartAreas[0].AxisX.Minimum = (int)MinSecond - 10;
chart3.ChartAreas[0].AxisX.Maximum = Round46(MaxSecond, 0) + 10;
// X坐标范围最大最小
chart3.ChartAreas[0].AxisY.Minimum = 0;
chart3.ChartAreas[0].AxisY.Maximum = Round46(MaxWaterDepth, 0) + 2;
// 坐标轴间隔
chart3.ChartAreas[0].AxisX.Interval = 60;
chart3.ChartAreas[0].AxisY.Interval = 5;
// 设置 X 坐标轴和 Y 坐标轴刻度的格式
chart3.ChartAreas[0].AxisX.LabelStyle.Format = "0";
chart3.ChartAreas[0].AxisY.LabelStyle.Format = "0.0";
// 显示主坐标网格线
chart3.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
chart3.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
// 主坐标网格线间隔
chart3.ChartAreas[0].AxisX.MajorGrid.Interval = 60;
chart3.ChartAreas[0].AxisY.MajorGrid.Interval = 5;
// 显示主坐标网格 X轴和Y轴的刻度
chart3.ChartAreas[0].AxisX.MajorTickMark.Enabled = true;
chart3.ChartAreas[0].AxisY.MajorTickMark.Enabled = true;
// 设置主网格线为点
chart3.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
chart3.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
// 设置主网格线颜色
chart3.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Black;
chart3.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Black;
// 显示次坐标网格线
chart3.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
chart3.ChartAreas[0].AxisY.MinorGrid.Enabled = true;
// 次坐标网格线间隔
chart3.ChartAreas[0].AxisX.MinorGrid.Interval = 10;
chart3.ChartAreas[0].AxisY.MinorGrid.Interval = 1;
// 显示次坐标网格 X轴和Y轴的刻度
chart3.ChartAreas[0].AxisX.MinorTickMark.Enabled = true;
chart3.ChartAreas[0].AxisY.MinorTickMark.Enabled = true;
// 设置次网格线为点
chart3.ChartAreas[0].AxisX.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
chart3.ChartAreas[0].AxisY.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
// 设置次网格线颜色
chart3.ChartAreas[0].AxisX.MinorGrid.LineColor = Color.LightGray;
chart3.ChartAreas[0].AxisY.MinorGrid.LineColor = Color.LightGray;
//缩放状态禁止显示滚动条
chart3.ChartAreas[0].AxisX.ScrollBar.Enabled = false;
chart3.ChartAreas[0].AxisY.ScrollBar.Enabled = false;
// 如果你想要更多的自定义设置,可以设置鼠标滚轮的行为
chart3.ChartAreas[0].AxisX.ScaleView.Zoomable = true; // 横向轴允许缩放
chart3.ChartAreas[0].AxisY.ScaleView.Zoomable = false; // 纵向轴禁止缩放
// 将Chart置于放大状态
chart3.ChartAreas[0].CursorX.AutoScroll = true;
chart3.ChartAreas[0].CursorY.AutoScroll = false;
//启用游标鼠标滚动放大
chart3.ChartAreas[0].AxisX.ScaleView.Zoom((int)MinSecond - 10, Round46(MaxSecond, 0) + 10);
chart3.Legends[0].BackColor = Color.Transparent;
#endregion
Series series1 = new Series();
series1.Name = PlannedLineName;
//Series series1 = new Series(PlannedLineName);
series1.ChartType = SeriesChartType.Line;// 添加一个二维线图表系列
series1.Color = Color.Black;
series1.MarkerColor = Color.Black;
series1.MarkerSize = 5;
series1.MarkerStyle = MarkerStyle.Circle;
// 添加数据点
series1.Points.AddXY(StartDotCoordEast, StartDotCoordNorth);
series1.Points.AddXY(EndDotCoordEast, EndDotCoordNorth);
// 添加起点终点坐标系列
chart1.Series.Add(series1);
// 设置标签样式
series1.Label = "#SERIESNAME(#VALX #VAL)"; // #VAL将显示每个数据点的值 //#VALX #LEGENDTEXT #SERIESNAME
if (EC1.Length > 0)
{
Series series2 = new Series();
series2.Name = "EC1水深测量点";
series2.ChartType = SeriesChartType.Line;
series2.Color = Color.Blue;
series2.MarkerColor = Color.Blue;
series2.MarkerSize = 5;
series2.MarkerStyle = MarkerStyle.Circle;
Series series3 = new Series();
series3.Name = "EC1水深测量点";
series3.ChartType = SeriesChartType.Line;
series3.Color = Color.Blue;
series3.MarkerColor = Color.Blue;
series3.MarkerSize = 5;
series3.MarkerStyle = MarkerStyle.Circle;
Series series4 = new Series();
series4.Name = "EC1水深测量点";
series4.ChartType = SeriesChartType.Line;
series4.Color = Color.Blue;
series4.MarkerColor = Color.Blue;
series4.MarkerSize = 5;
series4.MarkerStyle = MarkerStyle.Circle;
// 添加数据点
for (int i = 0; i < EC1.GetLength(0); i++)
{
double Second = EC1[i, 0];
double X = Common.Round46(EC1[i, 1]);
double Y = Common.Round46(EC1[i, 2]);
EC1WaterDepth[i] = Convert.ToDouble(Common.Round46(EC1[i, 3], "H"));
if (EC1SurveyLineCheck.Checked)
{
series2.Points.AddXY(X, Y);
}
EC1PointDistance[i] = Distance(StartDotCoordEast, StartDotCoordNorth, X, Y);
double MeasureLine = DegreesToRadian(AzimuthCalc(StartDotCoordEast, StartDotCoordNorth, X, Y));//测线方位角
EC1OnlineDistance[i] = Cos(MeasureLine - PlannedLineAzimuth) * EC1PointDistance[i];//在线距
series3.Points.AddXY(EC1OnlineDistance[i], EC1WaterDepth[i]);
series4.Points.AddXY(Second, EC1WaterDepth[i]);
}
if (EC1SurveyLineCheck.Checked)
{
chart1.Series.Add(series2);
}
chart2.Series.Add(series3);
chart3.Series.Add(series4);
}
3.2 输出解算数据(限于篇幅只提供定位坐标数据输出代码)
int PosNum = RawFilePath.LastIndexOf(".");
string POSFilePathName = RawFilePath.Substring(0, PosNum) + "-PosRaw.TXT";
string EC1FilePathName = RawFilePath.Substring(0, PosNum) + "-EC1.TXT";
string FIXFilePathName = RawFilePath.Substring(0, PosNum) + "-FIX.TXT";
if (OutPOSFileCheck.Checked)
{
if (POS.GetLength(0) > 0)
{
FileStream SavePOS = new FileStream(POSFilePathName, FileMode.Create);
StreamWriter SWPOS = new StreamWriter(SavePOS, Encoding.Default);
if (EC1.GetLength(0) > 0)//有水深
{
if (RadioTab.Checked)
{
SWPOS.Write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\r\n", "测点午夜秒", "原始 WGS-84 经度", "原始 WGS-84 纬度", "大地高", "原始东坐标X", "原始北坐标Y", "水深", "测量日期", "测点时间");
}
else
{
SWPOS.Write("{0} {1} {2} {3} {4} {5} {6} {7} {8}\r\n", "测点午夜秒", "原始 WGS-84 经度", "原始 WGS-84 纬度", "大地高", "原始东坐标X", "原始北坐标Y", "水深", "测量日期", "测点时间");
}
for (int i = 0; i < POS.GetLength(0); i++)
{
double dSecond = POS[i, 0];
string sSecond = dSecond.ToString("0.000");
string LON = POS[i, 1].ToString("0.000000000000");
string LAT = POS[i, 2].ToString("0.0000000000000");
string Height = Common.Round46(POS[i, 3]).ToString("0.000");
string East = Common.Round46(POS[i, 4]).ToString("0.000");
string North = Common.Round46(POS[i, 5]).ToString("0.000");
string Depth = Common.Round46(POS[i, 6], "H");
string sTime = HypackRAW.GetTime(dSecond);
if (RadioTab.Checked)
{
SWPOS.Write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\r\n", sSecond, LON, LAT, Height, East, North, Depth, SP[21].Substring(0, 10), sTime);
}
else
{
SWPOS.Write("{0} {1} {2} {3} {4} {5} {6} {7} {8}\r\n", sSecond, LON, LAT, Height, East, North, Depth, SP[21].Substring(0, 10), sTime);
}
}
}
else//无水深
{
if (RadioTab.Checked)
{
SWPOS.Write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\r\n", "测点午夜秒", "原始WGS84经度", "原始WGS84纬度", "大地高", "原始东坐标X", "原始北坐标Y", "测量日期", "测点时间");
}
else
{
SWPOS.Write("{0} {1} {2} {3} {4} {5} {6} {7}\r\n", "测点午夜秒", "原始WGS84经度", "原始WGS84纬度", "大地高", "原始东坐标X", "原始北坐标Y", "测量日期", "测点时间");
}
for (int i = 0; i < POS.GetLength(0); i++)
{
double dSecond = POS[i, 0];
string sSecond = dSecond.ToString("0.000");
string LON = POS[i, 1].ToString("0.000000000000");
string LAT = POS[i, 2].ToString("0.0000000000000");
string Height = Common.Round46(POS[i, 3]).ToString("0.000");
string East = Common.Round46(POS[i, 4]).ToString("0.000");
string North = Common.Round46(POS[i, 5]).ToString("0.000");
string sTime = HypackRAW.GetTime(dSecond);
if (RadioTab.Checked)
{
SWPOS.Write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\r\n", sSecond, LON, LAT, Height, East, North, SP[21].Substring(0, 10), sTime);
}
else
{
SWPOS.Write("{0} {1} {2} {3} {4} {5} {6} {7}\r\n", sSecond, LON, LAT, Height, East, North, SP[21].Substring(0, 10), sTime);
}
}
}
SWPOS.Flush();
SWPOS.Close();
}
}
四、Hypack测量原始数据处理程序
五、Hypack测量原始数据处理程序下载
本地下载:
https://download.youkuaiyun.com/download/zyyujq/89884242