1. 概述
Matlab MappingTools 打包了全球地图数据,从中抽取政区界限、海岸线经纬坐标数据,并保存为文本格式,但其中含有大量的 NaN 标记(注:地图数据的抽取方法将有专文记录)。NaN 意为 Not a Number,可在描绘地图的时候起到分隔轮廓线的作用。
数据示例 theData.txt:
-16.1080 13.1665
-16.5489 13.1650
-16.7854 13.1475
NaN NaN
-13.7319 12.6773
-13.1625 12.6545
-12.7934 12.5028
/n/r 注:本行是空行,即仅有 /n/r 的行
-12.5641 12.4039
-12.2319 12.3600
-11.9297 12.3859
-11.4890 12.4156
-11.4209 12.3955
NaN NaN
-13.7319 12.6773
-14.7424 12.6823
以上文件允许任意空行存在。为了让 MFC 应用程序读取这种格式的数据,必须采取一定的方法。
2.可重用代码
2.1 建立数组
数据文件包含的数据多少可能是不确定的,为了获取经纬度坐标数目,首先用一个 Enum 来计数。
ifstream Enum("theData.txt",ios::in);
int HowManyLines;
int LineLength=100;//大于数据文件的每行包含的字符数
char* EnumLine;//用来存放读取的每行数据
EnumLine = new char[LineLength];
while(!Enum.eof())
{
Enum.getline(EnumLine,LineLength,'/n');//以 /n 为分隔读取每行内容,但什么都不作
HowManyLines ++;//只是为了计数
}
delete EnumLine;
Enum.close();
double Data**;//以下建立与数据文件相对应的数组
Data = new double*[HowManyLines];
for(int i=0;i<HowManyLines;i++)
{
Data[i] = new double[2];
}
for(i=0;i<HowManyLines;i++)//以下初始化数组所有元素为0.0
{
for(int j=0;j<HowManyLines;j++)
{
Data[0] = 0.0;
Data[1] = 0.0;
}
}
2.2 把数据读入数组
首先要判断某行是否包含 NaN 或者是否空行,如果是,则相应的数组元素赋值为 NULL,如果不是,则读取数据。为了使判断和读取数据不会出现错乱,两者必须并行同时进行,这就需要定义两个 ifstream 对象。
ifstream Try("theData.txt",ios::in);//用于判断
ifstream Read("theData.txt",ios::in);//用于读取数据
char* TryLine;
char* ReadLine;
Cstring Line;
for(i=0;i<HowManyLines;i++)
{
TryLine = new char[LineLength];
ReadLine = new char[LineLength];
Try.getline(TryLine,LineLength,'/n');
Line = TryLine;
if(Line.find("NaN")>=0 || TryLine[0]==NULL)//如果包含 NaN 或者是空行
{
Data[0] = NULL;
Data[1] = NULL;//如果满足上面条件,则把经纬度数据都赋值为 NULL。在 MFC 绘图中,NULL 也可起到分隔作用
Read.getline(ReadLine,LineLength,'/n');
}
else
{
Read >> Data[0] >> Data[1];
Read.getline(ReadLine,LineLength,'/n');
}
delete TryLine;
delete ReadLine;
}
Try.close();
Read.close();
3. 说明
尚未知道是否还有更高明的方法。