MIF数据知多少

1.简介

MIF是Mapinfo用来向外交换数据的一种中间交换文件。当用户在Mapinfo中将一张Mapinfo地图表以MIF格式转出来MIF文件中后,Mapinfo会同时在用户指定的保存目录下生成两个文件.mif,.mid)。其中*.mif文件保存了该Mapinfo表的表结构及表中所有空间对象的空间信息(如:每个点对象的符号样式、点位坐标;每个线对象的线样式、节点数据、节点坐标;区域对象的填充模式、每个区域包含的子区域个数及每个区域的节点数、节点数等),它由两个区域:文件头区域、数据节组成;*.mid文件则按记录顺序保存了每个空间对象的所有属性信息

2.数据说明

2.1 文件头

MIF File header 格式:
Version n
Charset "characterSetName"
[ DELIMITER "<c>" ]
[ UNIQUE n,n.. ]
[ INDEX n,n.. ]
[ COORDSYS... ]
[ TRANSFORM... ]
COLUMNS n
<name> <type>
<name> <type>
…
…
DATA

2.2 分析

Version 子句说明您所使用的是VERSION 1、VERSION 2、VERSION 300还是VERSION 450 格式。
Charset 子句指定在表中创建文本时使用的字符集。
Delimiter 在引号中指定分隔符,缺省情况下,分隔符是TAB键;如果使用缺省值,则无需DELIMITER行。
Unique(唯一) 指定一个号码。这个号码指示数据库的一列;
Index(索引) 要指出表中的列有索引,可以在Index子句中引入一个号码(或一系列用逗号分隔的号码)。每个号码代表数据库的一列;INDEX 列表中的列将有附录为它们制作的索引。
CoordSys(坐标系统)子句 指定COORDSYS子句以注明数据不是以经度/纬度形式保存的。未指定COORDSYS子句时,假定数据是以经度/纬度形式保存的。所有坐标都是以相对于东北象限的值保存的。(
其中一些参数设置比较复杂)
Columns(列) 指定列数。然后为每列创建一行,它包含列名、列类型,对于字符列和小数列,还包含一个指示字段宽度的数。
MIF文件的数据节在文件头之后,且必须由DATA 以单独的一行引入:
DATA
MIF文件的数据节可以有任意多个图形初值,每个初值代表一个图形对象。MapInfo使MIF和MID 文件中的条目相互匹配,MIF文件中的第一个对象与MID文件中的第一行关联,MIF文件中的第二个对象与MID 文件中的第二行关联,依此类推。如果MID 文件中特定的一行没有对应的图形对象,那么必须在MIF 文件中的相应位置上写一个“空白”对象(NONE)以保留该位置:
NONE

2.3 列类型

有效的列类型是
l char(宽度)
l integer(4 个字节)
l smallint(2 个字节,因此只能存储从-32767 到+32767 的数)
l decimal(宽度,小数位数)
l float
l date
l logical

2.4 图形对象类型

可以指定的图形对象为
l 点(point)
l 直线(line)
l 折线(polyline)
l 区域(region)
l 圆弧(arc)
l 文本(text)
l 矩形(rectangle)
l 圆角矩形(rounded rectangle)
l 椭圆(ellipse)
  • 一个点(point)对象需要两个参数:一个X 坐标和一个Y坐标。作为一个选项,可以设定代表该点的symbol(符号)。symbol
    是用数字标明的。如果忽略了SYMBOL 子句,则使用当前symbol。
    POINT x y
    〔 SYMBOL (shape, color, size)〕
    直线
    一个直线(line)对象需要四个参数;每个端点各一个X 坐标和一个Y 坐标。作为一个选项,可以指定pen
    类型,如果没有指定pen类型,则使用当前pen 类型。
    LINE x1 y1 x2 y2
    〔 PEN (width, pattern, color)〕

  • 折线

    一个折线(polyline)对象由一节或多节构成。如果该折线不止一节,则应包含MULTIPLE
    关键字,并在其后写明节数。为每节设定一个numpts 参数(该参数指出该节中节点的数量),
    其后为每个节点的x/y坐标对。用可选的PEN 子句(本附录稍后说明)来指定线样式。如果包含了可选的SMOOTH 关键字,则折线被平滑。
    PLINE 〔 MULTIPLE numsections 〕
    numpts1
    x1 y1
    x2 y2
    :
    〔 numpts2
    x1 y1
    x2 y2 〕
    :
    〔 PEN (width, pattern, color)〕
    〔 SMOOTH 〕

  • 区域
    一个区域(region)对象由一个或多个多边形构成。用numpolygons 参数设定多边形数量(紧
    跟在REGION 关键字后面)。为每个多边形设定一个numpts参数(该参数指出该多边形中节点的数量),其后为每个节点的x/y坐标对。用可选的PEN
    和BRUSH 子句(本附录稍后说明)指定该对象的样式。用可选的CENTER子句来精确定义该对象的中心位置。中心必须位于对象内。
    REGION numpolygons
    numpts1
    x1 y1
    x2 y2
    :
    〔numpts2
    x1 y1
    x2 y2 〕
    :
    〔 PEN (width, pattern, color)〕
    〔 BRUSH (pattern, forecolor, backcolor)〕
    〔 CENTER x y 〕

  • 圆弧
    一个圆弧(arc)需要其外接矩形的对角位置以及该圆弧的起点(a)和终点(b)的角度,其中角度以度的形式表示,以时钟上三点钟处为零点反时针移动。作为一个选项,可以指定pen类型。(一段圆弧指定了一个椭圆的一段,圆弧的两角由外接矩形确定。)
    ARC x1 y1 x2 y2
    a b
    〔 PEN (width, pattern, color)〕

  • 文本
    一个文本(text)对象由一个文本字符串构成,不超过255个字符。要使文本字符串换行成多行,可在textstring参数内插入字符\n(例如“第一行\n
    第二行\n第三行”)。x1、y1、
    x2和y2 指定了文本在地图上的位置。间隔可以是1.0(单间距)、1.5 或2.0(双间距)。
    用Font 子句来控制字体等等。
    TEXT “textstring”
    x1 y1 x2 y2
    〔 FONT…〕
    〔 Spacing {1.0 | 1.5 | 2.0}〕
    〔 Justify {Left | Center | Right}〕
    〔 Angle text_angle〕
    〔 Label Line {simple | arrow} x y 〕

  • 矩形
    一个矩形(rectangle)需要一对对角的坐标。作为选项,可以指定pen和brush类型。
    RECT x1 y1 x2 y2
    〔 PEN (width, pattern, color)〕
    〔 BRUSH (pattern, forecolor, backcolor)〕
    圆角矩形
    一个圆角矩形(rounded rectangle)需要一对对角的坐标和圆的角度(a)。作为选项,可以指定pen 和brush
    类型。圆角的角度用坐标单位表示。
    ROUNDRECT x1 y1 x2 y2
    a
    〔 PEN (width, pattern, color)〕
    〔 BRUSH (pattern, forecolor, backcolor)〕

  • 椭圆
    一个椭圆(ellipse)对象需要其外接矩形的一对对角的坐标。作为选项,可以指定pen 和brush类型。
    ELLIPSE x1 y1 x2 y2
    〔 PEN (width, pattern, color)〕
    〔 BRUSH (pattern, forecolor, backcolor)〕

2.5 相关样式

  • Pen样式

    Pen 子句设定诸如直线、折线或圆弧此类的线性对象的宽度、图案和颜色。
    Pen 子句有如下语法:
    PEN (width, pattern, color)
    Width 是从1 到7 的一个数。1-7 是屏幕象素的宽度。11-2047是要转换为点的数值:
    penwidth = (点数 * 10) + 100 只有在针对不可见的线,笔模式为1时才有效。
    color 是一个整数,表示一个24 位的RGB颜色值。
    Pattern 是一个从1到118的整数,模式号为1时可见。模式号和画笔文件中画笔号相对应。可以用画笔编辑器来编辑画笔文件。 有效的画笔号是从1 到画笔文件中最大的画笔号,应该不超过127。如果一个画笔样式是交叠的,就增加128 作为其画笔号。交叠样式在129-255范围之内。由于画笔文件可以修改,而且交叠也可以指定,所以画笔模式可以是1-255之间的数。

  • Brush 样式

    Brush 设定诸如圆或区域这样的填充对象的图案、前景颜色和背景颜色。Brush 子句有如下语法:
    Brush (pattern, forecolor 〔, backcolor 〕)
    forecolor(前景颜色)和backcolor(背景颜色)参数都是整数,代表24 位RGB 颜色值。
    pattern(图案)是一个1 到71 之间的数。注意:1 号图案是“不填充”而2号图案是纯色填充。

  • Symbol 样式

    Symbol 子句设定点对象的外观。Symbol 子句有三种格式,如下所述。

  • MapInfo 3.0语法

    Symbol 子句设定一个点对象的外观。Symbol 子句有三种格式。
    要设定一种使用“Old MapInfo Symbols”(MapInfo早期版本使用的符号)的Symbol 样式,使用如下语法:
    SYMBOL (shape, color, size)
    shape(形状)参数是一个整数值、31 或更大;31代表空白symbol(即该对象是不可见的)。标准symbol 集合包括32到67号symbol,但用户可以用Symbol 应用程序来自定义symbol集合。
    color(颜色)参数是一个整数,代表一个24 位RGB颜色值
    size(大小)参数是一个1 到48 之间的整数,代表点的尺寸。

  • TrueType字体语法

    要设定一个基于TrueType 字体的字符的Symbol 样式,使用如下语法:
    SYMBOL (shape, color, size, fontname, fontstyle, rotation)
    fontname(字体名称)参数是一个文本字符串,指明一个字体的名称(例如“Wingdings”)。
    fontstyle(字体样式)参数是一个控制样式设置(例如粗体)的整数。

  • 自定义位图文件语法

    要设定一个基于自定义位图文件的symbol 样式,使用如下语法:
    SYMBOL (filename, color, size, customstyle)
    filename(文件名)参数是一个文本字符串,它标明了CustSymb 目录中的一个位图文件(例如“Arrow.BMP”)。
    customstyle(自定义样式)参数是一个整数,控制是否使用颜色和背景属性。

  • Font样式
    Font 子句设定文本对象的外观(字体、颜色等)。Font 子句有如下语法:
    FONT (“fontname”, style, size, forecolor 〔, backcolor〕 )
    双引号内的fontname(字体名称)是被显示的字体。
    style(样式)是字体的文本属性。MIF文件中的size(大小)必须是0,因为一幅地图上的文本对象是附加到该地图上的(这样在放大或缩小时文本尺寸改变)。
    forecolor(前景颜色)是一个整数,代表一种24位RGB 颜色。
    backcolor(背景颜色)是可选的;如果包含了它,则MapInfo在文本背后的区域中填充指定的颜色。

2.6 颜色

颜色通常是以红、绿和蓝色的相对浓度来定义的。其中每种颜色是一个0到255包括0和255之间的数;各种颜色的RGB 值由以下公式计算:
(红色 * 65536)+(绿色 * 256)+蓝色
这里是一些常用颜色及其数值:
红色:16711680
绿色:65280
蓝色:255
青色:65535
紫红:16711935
黄色:16776960
黑色:0

3.C++使用GDAL库进行MIF解析

有关GDAL库的相关介绍后续会出专门的文章进行介绍,在此不再进行累述。相关网站:https://gdal.org/download.html

3.1 MIF文件的读取

需要还包含的头文件:#include <gdal/ogrsf_frmts.h>
  	// 支持中文路径 
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");  
   	// 支持中文字段
    CPLSetConfigOption("SHAPE_ENCODING", ""); 
    // 注册驱动 
    RegisterOGRTAB();    
    // 获取驱动
    OGRSFDriver* pDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("MapInfo File");   
   if (pDriver == nullptr)
    {
    	//TODO:异常处理
        ...
    }
	//打开mif文件,strFilePath:mif文件全路径
    OGRDataSource* poDS = pDriver->Open(strFilePath, false);    
    if (poDS == nullptr)
    {
         //TODO:异常处理
         ...
    }
    OGRLayer* poLayer = poDS->GetLayer(0);    //只有一个图层;
    OGRFeature* poFeature = poLayer->GetNextFeature();
    while (poFeature != nullptr)
    {
    	//获得几何信息
        OGRGeometry *poGeometry = poFeature->GetGeometryRef();
        if (poGeometry == nullptr)
        {
            continue;
        } 
        //判断当前要素的几何类型,是否为点图层,利用 getGeometryType() 函数获取要素类型
        OGRwkbGeometryType eType = poGeometry->getGeometryType();
        //TODO:根据几何类型以及实际业务进行相关操作
        switch (eType)
		{
		...
		default:
			break;
		}
        //内存释放
        OGRFeature::DestroyFeature(poFeature);
        //读取下一条数据
        poFeature = poLayer->GetNextFeature();
    }
    //数据源释放,不释放会造成资源(文件)的占用
	OGRDataSource::DestroyDataSource(poDS);
	 //反注册驱动
	OGRSFDriverRegistrar::GetRegistrar()->DeregisterDriver(pDriver);
  

3.2 MIF文件的生成

需要还包含的头文件:#include <gdal/ogrsf_frmts.h>
	CPLSetConfigOption("SHAPE_ENCODING", "");
    RegisterOGRTAB();
    OGRSFDriver *pDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("MapInfo File");
    if (pDriver == nullptr)
    {
       //TODO:异常处理
    }
	//创建一个MIF文件,strFilePath:文件全路径
    OGRDataSource* pDS = pDriver->CreateDataSource(strFilePath);
    if (pDS == nullptr)
    {
        //TODO:异常处理
    }
    //设置地理坐标相关信息 
    OGRSpatialReference oSRS;
    char* pszWKT = nullptr;
    oSRS.SetWellKnownGeogCS("WGS84");
    oSRS.exportToWkt(&pszWKT);
    //TODO:根据实际业务要求创建图层,strLayerName:图层名称、wkbPoint几何类型
     pDS->CreateLayer(strLayerName, &oSRS, wkbPoint, NULL);
     //只有一个图层;
    OGRLayer* pLayer= pDS->GetLayer(0);
    if (pLayer == nullptr)
    {
         //TODO:异常处理
    }
	//TODO:字段写入值
	OGRFeature *pFeature = OGRFeature::CreateFeature(pLayer->GetLayerDefn());
	if(pFeature == nullptr)
	{
		//TODO:异常处理
	}
	//TODO:设置字段以及字段值,实际可能有多个字段
    pFeature ->SetField("Test_1", "TEST_1");
	...
   
	//TODO:设置几何以及几何信息
    OGRLineString line;
    for (int i = 0; i < pointNum; i++)
    {
        line.addPoint(...);
    }
    pFeature ->SetGeometry(&line);
    if (pLayer->CreateFeature(pFeature ) != OGRERR_NONE)
    {
         //TODO:异常处理
    }
    OGRFeature::DestroyFeature(poFeature);
     //数据源释放,不释放会造成资源(文件)的占用
	OGRDataSource::DestroyDataSource(poDS);
	 //反注册驱动
	OGRSFDriverRegistrar::GetRegistrar()->DeregisterDriver(pDriver);
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值