2.2.12 电子海图系统解析及开发 海图显示 - 符号化指令:显示文本

点、线、面物标都存在需要显示相关文本(如:物标名称)的情况。文本虽然不是符号库的一部分,但它却是电子海图数据的一部分。S-52标准规定,显示文本的字体只能是标准的“sans serif”。值得注意的是,水深点处的水深不是以文本方式出现,而是以符号的方式出现的。

为了阅读方便,电子海图显示文本时,一般不会旋转。文本的转心应该位于面物标的中心,或位于单个线段的中点,或位于多个线段的长度各的中心处。

文本显示涉及到两个命令:TXTE

1. TX 纯文本显示,不需要格式控制

纯文本显示命令

参数说明:

  • STRING  待显示的文本
         可传入固定文本,或物标的六字母属性(如:OBJNAM表示物标名称)。如果属性所对应的值为枚举或列表型,需要将其编号所代表的含义输出。
  • HJUST  水平对齐
         ’1‘ 表示居中
         ’2‘ 表示靠右
         ’3‘ 表示靠左(默认值)
  • VJUST  垂直对齐
         ’1‘ 表示靠下(默认值)
         ’2‘ 表示居中
         ’3‘ 表示靠上
  • SPACE  字符间距
         ’1‘ 两端对齐(调整字符间距,使文本填满物标的显示空间)
         ’2‘ 标准间距(默认值)
         ’3‘ 标准间距,但允许换行,单行字符不超过8个
  • CHARS  字符说明(字体,粗细、宽度(直体/斜体),字号等)
         字体
          ’1‘ 标准 sans serif (唯一选项)
         粗细
          ’4‘ 表示加细(对应值300)
          ’5‘ 表示中等(对应值500)
          ’6‘ 表示加粗(对应值700)
         宽度
          ’1‘ 表示直体,对于属性$CHARS的值,必须用直体表示
         字号
          单位为pica point(1 pica point = 0.351mm),最小值为10,同时也是默认值
  • XOFFS  x方向的偏移量
         单位为pica point,表示x方向上的偏移量,向右为正
  • YOFFS  y方向的偏移量
         单位为pica point,表示x方向上的偏移量,向下为正
  • COLOUR  文本的颜色
         用颜色标记指定的颜色
  • DISPLAY  文本的分组
         航海人员可按组选中文本

示例:TX(OBJNAM,1,2,3,’15110’,0,0,CHBLK,26)
含义:纯文本显示物标名称,水平居中,垂直居中,标准间距、允许换行,标准字体、加粗、直体、10号字,无偏移、颜色为CHBLK,组别为26。

2. TE 格式文本显示,其格式控制符合C语言标准

格式文本显示

与TX不同之处是,TE的文本显示是按照一定格式输出。该输出格式是符合C语言标准的,而本项目采用的C#编程,C#与C的格式控制是不兼容的,因此有两种方法解决:

  • 修改查询表中TE的格式控制字符串,使其满足C#标准,如: 将"clr cl %4.1lf"改为clr cl {0:f1}
  • 用C#编写工具类以实现C格式输出,有个现成的方案A printf implementation in C#

示例:TE('clr cl %4.1lf','VERCCL',3,1,2,'15110',1,0,CHBLK,11)
含义:若物标属性VERCCL=16.2,最后显示的结果为:clr cl 16.2,其他含义与TX一样。

3. 编码实现

  • 对于TE指令,先将第一个参数(格式)和第二个参数内容读取出来,组合成纯文本,然后调用方法与TE一样。
    var txt = PrintFTools.sprintf("clr cl %4.1lf", 16.2); 
    
  • SPACE 字符间距
        1. 对于两端对齐方式,Skia并没有现成的现实方案。需要的流程较为复杂:计算物标的地理长度⇒屏幕长度⇒确定文本中单个字符的宽度⇒确定每个字符的绘制位置⇒依次绘制字符。考虑实际作用较小,而暂不考虑。
        2. 标准间距,对应SKFontStyleWidth.Normal
        3. 允许换行的标准间距,当文本长度超过8字符时,进行拆分,然后多行输出。考虑实际作用较小,而暂不考虑。
  • CHARS 字段编程
        字体 SKTypeface FromFamilyName("sans serif")
        粗细 4,5,6 对应SKFontStyleWeight中的LightNormalBold
        宽度 1,2对应SKFontStyleSlant中的UprightItalic
        字号 1 pica point = = 0.351mm = 96 / 25.4 * 0.351 像素
    //chars 形如 15110
    var fontWeight = SKFontStyleWeight.Normal;
    if (chars[1] == '4') fontWeight = SKFontStyleWeight.Light;
    else if (chars[1] == '6') fontWeight = SKFontStyleWeight.Bold;
    
    var fontSlant = SKFontStyleSlant.Upright;
    if (chars[2] != '1') fontSlant = SKFontStyleSlant.Italic;
    
    var textSize = PicaPoint * int.Parse(chars.Substring(3));
    
    var font = SKTypeface.FromFamilyName("sans serif", fontWeight, SKFontStyleWidth.Normal, fontSlant);
    var paint = new SKPaint(){ Typeface = font, TextSize = textSize };
    
  • COLOUR 字体颜色
    paint.Color = S52Colors.Instance[colour];
    
  • ** HJUST/VJUST** 对齐方式
        Skia文本的基点位于文本基线左侧,对于水平对齐可直接设置TextAlign,若要改变垂直对齐方式,需要获取字体信息,然后设置基点的位置。
    文本测量
    //水平对齐
    if (hjust == "2") paint.TextAlign = SKTextAlign.Right;
    else if(hjust == "1") paint.TextAlign = SKTextAlign.Center;
    //垂直对齐
    var fontMetrics = paint.FontMetrics;
    if (vjust == "3") y = y - fontMetrics.CapHeight; //Top:
    else if (hjust == "1") y = y - fontMetrics.CapHeight/2; //Center
    
  • XOFFS/YOFFS 偏移量
    if (xoffs != 0) x += PicaPoint * xoffs;
    if (yoffs != 0) y += PicaPoint * yoffs;
    

如果需要对文本进行理更为复杂的格式控制,可考虑使用第三方库RichTextKit,它是SkiaSharp的富文本布局,测量和渲染库。

  • 显示文本的完整代码如下:
    //字体大小单位 1 pica point = 0.351mm
    public const float PicaPoint = (float)MPP * 0.351f;

    //在屏幕指定坐标处绘制文本
    public static void DrawTextAtXY(SKCanvas ca, float x, float y, string txt,
        string hjust, string vjust, string space, string chars, int xoffs, int yoffs, string colour)
    {
        if (string.IsNullOrEmpty(txt)) return;

        //chars 形如 15110
        var fontWeight = SKFontStyleWeight.Normal;
        if (chars[1] == '4') fontWeight = SKFontStyleWeight.Light;
        else if (chars[1] == '6') fontWeight = SKFontStyleWeight.Bold;

        var fontSlant = SKFontStyleSlant.Upright;
        if (chars[2] != '1') fontSlant = SKFontStyleSlant.Italic;

        var textSize = PicaPoint * int.Parse(chars.Substring(3));

        var font = SKTypeface.FromFamilyName("sans serif", fontWeight, SKFontStyleWidth.Normal, fontSlant);
        var paint = new SKPaint() { Typeface = font, TextSize = textSize };

        //颜色
        paint.Color = S52Colors.Instance[colour];

        //水平对齐
        if (hjust == "2") paint.TextAlign = SKTextAlign.Right;
        else if (hjust == "1") paint.TextAlign = SKTextAlign.Center;

        var fontMetrics = paint.FontMetrics;
        if (vjust == "3") y = y - fontMetrics.CapHeight; //Top:
        else if (hjust == "1") y = y - fontMetrics.CapHeight / 2; //Center

        if (xoffs != 0) x += PicaPoint * xoffs;
        if (yoffs != 0) y += PicaPoint * yoffs;

        ca.DrawText(txt, x, y, paint);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容