介绍 CLongLatString是一个类,用于将经度或纬度的多种表示形式中的任何一种解析为double,或将表示地理坐标的double格式化为美观的地理坐标字符串。 背景 地球被划分为经度和纬度的地理网格线。经度是指从英国格林威治向东和向西的角距离。纬度测量的是从赤道向北和向南的角距离。等经度的线在两极收敛,而等纬度的线是环绕地球的平行线。这只是众多地理坐标系统中的一种,但却是迄今为止使用和理解最广泛的一种。 这些坐标通常用半球(N、S、E、W)、角、分、秒来表示。有些使用十进制度、度-分或度-分-秒组合。有些用正/负符号代替半球(东方是正的)。最重要的是,大数量的分隔符和配售的格式更加复杂,一些离开完全分隔符,通常最后一项是十进制,前面的是整数,和一些运行的所有数据一起为了节省空间,和西半球的术语可以位于任何地方的协调。 各种地理坐标格式的一些例子:复制Code

45:26:46N,     65:56:55W
45:26:46.302N, 65:56:55.903W
45°26’21"N,    65°58’36"W
45N26 21,      65W58 36
45.446195N,    65.948862W
45.446195,     -65.948862
N45° 26.7717’, W65° 56.93172’

使用的代码 这个类具有相当强大的(我认为)自动解析数据和提取数值的能力。例如,这允许你为每个地理坐标提供一个编辑框,而不是为半球提供一个组合框,为学位、分钟和秒提供单独的输入。 CLongLatString是一个处理经度和纬度的各种格式的类,这样就可以轻松地处理和转换为双精度值,以便与其他地理方法一起使用。该对象为每个值维护一个double和一个字符串。保留字符串是因为有时需要保留原始数据,以保持精度。您可以从double中输出字符串值,就像您可以从time_t中格式化CTime一样,使用类似printf的值,%C、%C、%H、%H %D、%D、%M、%M、%S和%S作为参数。 CLongLatString不处理成对的坐标——让每个对象都有一个值来表示它是经度还是纬度更有效。因此,如果使用纯双精度初始化数据,如果希望从中获得任何有意义的结果,还必须指出该值是经度还是纬度。 有大量的构造函数和一个复制构造函数。您可以根据需要使用字符串或double对其进行初始化。还有转换运算符和赋值运算符,因此您可以轻松地将其转换为双精度字符串或标准字符串。隐藏,复制Code

CLongLatString llstrLat1("45N54.2356");
CLongLatString llstrLat2("-45.98739874", LL_LATITUDE);
CLongLatString llstrLat5(-45.98739874, LL_LATITUDE);
CLongLatString llstrLat7("N", "45", "34", "33");
CLongLatString llstrLat8("N455698735", "HDDMMmmmmm");

如果要对double或包含文本double的字符串使用赋值操作符,则必须初始化该对象,以告知它是long还是lat。隐藏,复制Code

CLongLatString llstrLat(LL_LATITUDE);
llstrLat = -5.877789;
std::string str = llstrLat.Format("%Dd%M\’%S\"%H");
cout << str.c_str() << endl;
// Output -    5d52’40"S
llstrLat = -5.997789;   // Can be reused - still a latitude
str = llstrLat.Format("%Dd%M\’%S\"%H");
cout << str.c_str() << endl;

或者一个更复杂的例子:Hide  复制Code

std::string str = llstrLat.Format("%H%02D %.5m");
// Output -    S05 52.66734

输出FormatHide,复制Code

%H - hemisphere - single character of N,S,E,W
%C - integer co-ordinate, may be negative or positive
%c - decimal co-ordinate, the entire co-ordinate,
         may be negative or positive
%D - integer degrees, always positive
%M - integer degrees, always positive
%S - integer seconds, always positive, rounded
%d - decimal degrees, always positive
%m - decimal minutes, always positive
%s - decimal seconds, always positive
%% - for %

可以使用标准的printf格式,例如%03D来创建三个带前导零的空格来表示整数度或%。用5m来写分钟的十进制五位数。大写标识符使用与十进制(整数)格式相同的printf标识符,而小写标识符使用浮点格式。在将整个子字符串传递给snprintf C函数时,所有其他标志都可以工作。 每个术语都有整数Get…()方法,可以是整数形式和小数形式。如果需要为每个术语分别提取字符串表单,那么可以重用Format()方法。 例如:隐藏复制Code

CLongLatString llstrLat(-5.9879875, LL_LATITUDE);
std::string strHemi = llstrLat.Format("%H");
std::string strDeg = llstrLat.Format("%02D");
std::string strMin = llstrLat.Format("%02M");
std::string strSec = llstrLat.Format("%05.2s");

输入格式 输入格式不同,只能用于固定长度的情况。“HDD MM.mmmmm”表示“N45 04.25764”),仅在格式相当混乱且同时运行时使用。在大多数情况下,度数、分、秒由任何空格或大多数分隔符分隔,未指定的默认输入格式应该可以工作。H表示半球的位置,大写字母表示小数点左边数字的部分,小写字母表示小数点右边数字的部分。 例如:隐藏复制Code

std::string strInputFormat = "HDDMMmmmmm";
CLongLatString llstrLat1("N650490807", strInputFormat);
CLongLatString llstrLat2;
llstrLat2.Set("N450490807", strInputFormat);
llstrLat2.Set("N45°04.0807\’");
    // No input format needed if there are enough delimiters

需要注意的是——不要在字符串中输入指数符号——它会将“E”误解为东方,并破坏结果。在将参数传递给构造函数或Set方法之前,一定要对其使用atof()。 覆盖它。您可以看一下头文件中提供的方法,它重复了一些格式规范,这些方法有一行注释解释。如果有任何科学准确性问题或严重错误,请告诉我。