2.2.16 电子海图系统解析及开发 海图显示 - 符号化指令:显示条件符号

条件符号一般需要根据用户设置动态绘制,如非双色显示时,海洋会根据用户设备的等深线,被分成四部分,每部分有着不同的颜色。因此每一条件符号的流程都是独立的,其拥有唯一的流程名。

条件符号命令

参数说明:

  • PROCNAME  流程名
         流程名由8位字母或数字组成,前6位字母代表流程所涉及的物标目录名,后2位数字代表版本号。

示例:CS(DEPARE02)
含义:执行名为DEPARE02的条件符号流程,该流程作用对象为深水区(DEPARE)。

现有的条件符号流程

S-52显示库中有如下流程,流程名后2位数字代表当前版本号。

流程名 适用对象
CLRLIN01 安全导航线
DATCVR02 数据覆盖范围,比例尺边界,超比例尺显示
DEPARE02 水深区颜色填充和疏浚区图案填充
DEPCNT03 等深线,包括安​​全等深线
DEPVAL02 水深值
LEGLIN03 计划航线
LIGHTS05 灯标灯质、光弧及范围
LITDSN01 灯标的描述说明
OBSTRN06 障碍物和岩石
OWNSHP02 本船
PASTRK01 航迹
QUAPOS01 位置精度
QUALIN01 线物标的位置精度
QUAPNT02 点和面物标的位置精度
RESARE03 限制区域
RESTRN01 限制区域的入口程序
RESCSP02 限制区域–属性RESTRN
SAFCON01 等深线标签
SLCONS03 海岸线,包括位置精度。
SEABED01 水深区的颜色填充
SNDFRM03 水深点符号化,包括安全水深
SOUNDG02 水深点绘制的入口程序
SYMINSnn 绘制由IMO指定符号
TOPMAR01 灯标的项标
UDWHAZ04 孤立危险物
VESSEL02 本船以外的船只
VRMEBL02 VRM和EBL
WRECKS04 沉船

S-52标准中的条件流程可能包含子流程,子流程可以被共享。

流程名 物标 子流程名
DATCVR M_COVR(a), M_CSCL(a)
DEPARE DEPARE(a), DRGARE(a) RESCSP, SEABED, SAFCON
DEPCNT DEPARE(l), DEPCNT(l) SAFCON
LIGHTS LIGHTS(p) LITDSN
OBSTRN OBSTRN(pla), UWTROC(p) DEPVAL, QUAPNT, SNDFRM, UDWHAZ
QUAPOS LNDARE(pl), COALNE(l) QUAPNT, QUALIN
RESARE RESARE(a)
RESTRN ACHARE(a), CBLARE(a), DMPGRD(a), DWRTPT(a),
FAIRWY(a), ICNARE(a), ISTZNE(a), MARCUL(a),
MIPARE(a), OSPARE(a), PIPARE(a), PRCARE(a),
SPLARE(a), SUBTLN(a), TESARE(a), TSSCRS(a),
TSSLPT(a), TSSRON(a)
RESCSP
SOUNDG SOUNDG(p) SNDFRM
WRECKS WRECKS(pa) DEPVAL, QUAPNT, SNDFRM, UDWHAZ

物标括号中的字母代表:p = 点物标;l = 线物标;a = 面物标。
如:绘制水深点针对的是点物标SOUNDG,具体流程为条件符号流程SOUNDG,其还使用到子流程SNDFRM

示例

需要针对每一条件符号流程单独编码,如水深点是以符号形式而非文本形式显示在电子海图中的。条件符号流程SOUNDG:

水深点显示流程
水深值符号化

条件符号流程SOUNDG的逻辑很简单:遍历本物标的水深点信息,将水深值传给子流程SNDFRM,将返回的符号数组显示在水深点处。
子流程SNDFRM,根据水深值(是否大于安全水深)添加符号前缘,根据自身物标特点(水深点性质及精度),添加相应修饰符号。然后将水深值拆分,按照一定规则找到相应的符号。最后将符号号组成的数组返回给上层流程。

安全水深由用户设置,默认值为30米。

编码实现

添加全局设置,存在用户设定的安全水深:

    public static class MySettings
    {
        // ...
        internal static double SafetyDepth = 30;                        //用户设定的安全水深
    }

对物标做预处理,将位置信息组装成路径,水深信息转化成浮点数组,并取出物标属性'TECSOU'(测深所使用的技术),‘STATUS’(位置状态),‘QUASOU’(测深质量),‘QUAPOS’(位置质量),将其传入函数。

TECSOU STATUS QUASOU QUAPOS
1 : found by echo-sounder
2 : found by side scan sonar
3 : found by multi-beam
4 : found by diver
5 : found by lead-line
6 : swept by wire-drag
7 : found by laser
8 : swept by vertical acoustic system
9 : found by electromagnetic sensor
10 : photogrammetry
11 : satellite imagery
12 : found by levelling
13 : swept by side-scan sonar
14 : computer generated
1 : permanent
2 : occasional
3 : recommended
4 : not in use
5 : periodic/intermittent
6 : reserved
7 : temporary
8 : private
9 : mandatory
10 : destroyed/ruined
11 : extinguished
12 : illuminated
13 : historic
14 : public
15 : synchronized
16 : watched
17 : un-watched
18 : existence doubtful
1 : depth known
2 : depth unknown
3 : doubtful sounding
4 : unreliable sounding
5 : no bottom found at value shown
6 : least depth known
7 : least depth unknown,
safe clearance at value shown
8 : value reported (not surveyed)
9 : value reported (not confirmed)
10 : maintained depth
11 : not regularly maintained

1 : surveyed
2 : unsurveyed
3 : inadequately surveyed
4 : approximate
5 : position doubtful
6 : unreliable
7 : reported (not surveyed)
8 : reported (not confirmed)
9 : estimated
10 : precisely known
11 : calculated
        public static void DrawCS_SOUNDG(SKCanvas ca, SKPath path, double[] depths,
            string tecsou, string status, string quasou, string quapos)
        {
            for (int i = 0; i < depths.Length; i++)
            {
                //转入水深点,返回符号数组
                var symbols = DrawCS_SNDFRM(depths[i], tecsou, status, quasou, quapos); 

                //依次绘制
                foreach (var sy in symbols)
                {
                    DrawSymbolAtXY(ca, path.Points[i].X, path.Points[i].Y, sy);
                }
            }
        }

        public static List DrawCS_SNDFRM(double depth,
            string tecsou, string status, string quasou, string quapos)
        {
            var symbols = new List();
            var prefix = depth < MySettings.SafetyDepth ? "SOUNDS" : "SOUNDG"; //前缀

            if (tecsou == "6") //扫海水深
            {
                symbols.Add(prefix + "B1");
            }

            if(status == "18") //疑存
            {
                symbols.Add(prefix + "C2");
            }
            else if (quasou == "3" || quasou == "4" || quasou == "5" || quasou == "8" || quasou == "9")
            {
                symbols.Add(prefix + "C2");
            }
            else if (quapos == "2" || quapos == "3" || quapos == "4" || quapos == "5" || quapos == "6" 
                || quapos == "7" || quapos == "8" || quapos == "9")
            {
                symbols.Add(prefix + "C2");
            }

            if (depth < 0)
            {
                symbols.Add(prefix + "A1");
            }
            else if (depth < 10)
            {
                var f = (int)depth;
                var s = (int)(depth * 10 % 10);
                symbols.Add(prefix + (10 + f).ToString());
                symbols.Add(prefix + (50 + s).ToString());
            }
            else if (depth < 31)
            {
                var f = (int)(depth / 10);
                var s = (int)(depth % 10);
                var t = (int)(depth * 10 % 10);
                symbols.Add(prefix + (20 + f).ToString());
                symbols.Add(prefix + (10 + s).ToString());
                symbols.Add(prefix + (50 + t).ToString());
            }
            else if (depth < 100)
            {
                var f = (int)(depth / 10);
                var s = (int)(depth % 10);
                symbols.Add(prefix + (10 + f).ToString());
                symbols.Add(prefix + s.ToString("00"));
            }
            else if (depth < 1000)
            {
                var f = (int)(depth / 100);
                var s = (int)(depth % 100 / 10);
                var t = (int)(depth % 10);
                symbols.Add(prefix + (20 + f).ToString());
                symbols.Add(prefix + (10 + s).ToString());
                symbols.Add(prefix + t.ToString("00"));
            }
            else if (depth < 10000)
            {
                var f = (int)(depth / 1000);
                var s = (int)(depth % 1000 / 100);
                var t = (int)(depth % 100 / 10);
                var l = (int)(depth % 10);
                symbols.Add(prefix + (20 + f).ToString());
                symbols.Add(prefix + (10 + s).ToString());
                symbols.Add(prefix + t.ToString("00"));
                symbols.Add(prefix + (40 + l).ToString());
            }
            else
            {
                var f = (int)(depth / 10000);
                var s = (int)(depth % 10000 / 1000);
                var t = (int)(depth % 1000 / 100);
                var l = (int)(depth % 100 / 10);
                var m = (int)(depth % 10);
                symbols.Add(prefix + (30 + f).ToString());
                symbols.Add(prefix + (20 + s).ToString());
                symbols.Add(prefix + (10 + t).ToString());
                symbols.Add(prefix + l.ToString("00"));
                symbols.Add(prefix + (40 + m).ToString());
            }

            return symbols;
        }

你可能感兴趣的:(2.2.16 电子海图系统解析及开发 海图显示 - 符号化指令:显示条件符号)