2.1.7 电子海图系统解析及开发 海图解析 -- 读取ISO/IEC 8211文件

通过上文的内容,已经了解到S-57文件符合ISO/IEC 8211作为其数据封装标准。一个文件已分成若干个逻辑记录(LR),每一个LR有三个基本元素头标区(对应类S57Leader)、目录区(对应类S57Directory)和字段区,其中文件中的第一个LR为DDR(存储文件中实际数据的描述和逻辑结构,对应类S57DDR),其他的LR为DR(存储文件中的实际数据,对应类S57DR)。

S-57文件封装标准

依照上图,新建类Iso8211File解析S-57文件,主要包含一个S57DDR字段和一个List<S57DR>列表。由于DDR和DR的头标区与目录区格式一致,因此将字段S57Leader和字段S57Directory放到类S57LR中,让DDR和DR继承自LR。DDR的字段区包含字段控制字段数据描述字段,因此类S57DDR还包含字段S57FieldControlField和字段S57DataDescriptiveFields。DR的字段区解析逻辑与DDR不一样,因此类S57DR还包含字段S57FieldArea。最后得到如下代码结构:

    public class S57LR
    {
        public S57Leader Leader;                                //头标区
        public S57Directory Directory;                          //目录区
    }

    public class S57DDR : S57LR
    {
        public S57FieldControlField FieldControlField;          //字段区 字段控制字段
        public S57DataDescriptiveFields DataDescriptiveFields;  //字段区 数据描述字段
    }

    public class S57DR : S57LR
    {
        public S57FieldArea FieldArea;                          //字段区 字段控制字段
    }

    public class Iso8211File
    {
        public S57DDR DDR;
        public List<S57DR> DRs;
    }

接下来,完成Iso8211File的构造函数,输入参数为S-57文件的路径。首先解析出文件的DDR头标区、目录录、字段控制字段和数据描述字段,利用其信息,循环解析出其他DR,具体代码如下:

        //构造函数,传入S57文件路径
        public Iso8211File(string filePath)
        {
            DDR = new S57DDR();
            DRs = new List<S57DR>();

            //加载S57文件,得到二进制数据
            BytesHelper.Load(filePath);

            //DDR 头标区
            DDR.Leader = new S57Leader();

            //DDR 目录区
            DDR.Directory = new S57Directory(DDR.Leader);

            //DDR 字段区
            //DDR 字段控制字段
            var tag0000 = DDR.Directory.Items[0];
            DDR.FieldControlField = new S57FieldControlField(tag0000.FieldLength, DDR.Leader.FieldTagSize);

            //DDR 数据描述字段
            DDR.DataDescriptiveFields = new S57DataDescriptiveFields(DDR.Directory);

            //循环解析DR
            while (BytesHelper.Position < BytesHelper.ENCBytes.Length - 2)
            {
                var dr = new S57DR();

                //DR 头标区
                dr.Leader = new S57Leader();

                //DR 目录区
                dr.Directory = new S57Directory(dr.Leader);

                //DR 字段区
                dr.FieldArea = new S57FieldArea(dr.Directory, DDR.DataDescriptiveFields);

                DRs.Add(dr);
            }
        }

最后验证结果:

            var reader = new Iso8211File("..\\US4AK7IM.000");
            var dl = reader.DDR.Leader;
            var header = dl.RecordLength.ToString() + dl.FieldControlString
                + dl.FieldAreaBaseAddress.ToString() + dl.ExCharacterSetIndicator
                + dl.FieldLengthSize.ToString() + dl.FieldPositionSize.ToString()
                + dl.Reserved.ToString() + dl.FieldTagSize.ToString();
            Console.WriteLine("DDR头标区:" + header);

            Console.WriteLine("DDR目录区:");
            foreach (var di in reader.DDR.Directory.Items)
            {
                Console.WriteLine($"标签:{di.Tag}\t长度:{di.FieldLength}\t位置:{di.FieldPosition}");
            }

            Console.WriteLine("DR的个数为:" + reader.DRs.Count);
S-57文件解析结果

至此,S-57文件的解析部分已全部完成了,我们可以清楚的掌握文件中的每一个标签,各标签下都有什么属性,各属性的值是什么。但不同标签对应真实世界实体的什么?不同的属性代表什么含义?各属性的值又能说明什么?需要对S-57标准的进一步解读。

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

推荐阅读更多精彩内容