15 # pragma warning (disable: 4127)
30 replace(dmsa,
"\xc2\xb0",
'd');
31 replace(dmsa,
"\xc2\xba",
'd');
32 replace(dmsa,
"\xe2\x81\xb0",
'd');
33 replace(dmsa,
"\xcb\x9a",
'd');
34 replace(dmsa,
"\xe2\x80\xb2",
'\'');
35 replace(dmsa,
"\xc2\xb4",
'\'');
36 replace(dmsa,
"\xe2\x80\x99",
'\'');
37 replace(dmsa,
"\xe2\x80\xb3",
'"');
38 replace(dmsa,
"\xe2\x80\x9d",
'"');
39 replace(dmsa,
"\xe2\x88\x92",
'-');
40 replace(dmsa,
"\xb0",
'd');
41 replace(dmsa,
"\xba",
'd');
42 replace(dmsa,
"\xb4",
'\'');
43 replace(dmsa,
"''",
'"');
46 end = unsigned(dmsa.size());
47 while (beg <
end && isspace(dmsa[beg]))
49 while (beg <
end && isspace(dmsa[
end - 1]))
56 for (string::size_type
p = beg, pb;
p <
end;
p = pb, ++
i) {
57 string::size_type pa =
p;
65 pb =
min(dmsa.find_first_of(signs_, pa),
end);
67 v += InternalDecode(dmsa.substr(
p, pb -
p), ind2);
70 else if (!(ind2 == NONE || ind1 == ind2))
72 dmsa.substr(beg, pb - beg));
76 dmsa.substr(beg,
end - beg));
87 end = unsigned(dmsa.size());
91 ind1 = (k / 2) ? LONGITUDE : LATITUDE;
92 sign = k % 2 ? 1 : -1;
98 if (toupper(dmsa[beg - 1]) == toupper(dmsa[
end - 1]))
99 errormsg =
"Repeated hemisphere indicators "
101 +
" in " + dmsa.substr(beg - 1,
end - beg + 1);
103 errormsg =
"Contradictory hemisphere indicators "
106 + dmsa.substr(beg - 1,
end - beg + 1);
109 ind1 = (k / 2) ? LONGITUDE : LATITUDE;
110 sign = k % 2 ? 1 : -1;
121 errormsg =
"Empty or incomplete DMS string " + dmsa;
124 real ipieces[] = {0, 0, 0};
125 real fpieces[] = {0, 0, 0};
129 unsigned ncurrent = 0,
p = beg;
130 bool pointseen =
false;
131 unsigned digcount = 0, intcount = 0;
139 icurrent = 10 * icurrent + k;
142 }
else if (
x ==
'.') {
144 errormsg =
"Multiple decimal points in "
145 + dmsa.substr(beg,
end - beg);
153 errormsg =
"Illegal for : to appear at the end of " +
154 dmsa.substr(beg,
end - beg);
159 if (
unsigned(k) == npiece - 1) {
160 errormsg =
"Repeated " + string(components_[k]) +
161 " component in " + dmsa.substr(beg,
end - beg);
163 }
else if (
unsigned(k) < npiece) {
164 errormsg = string(components_[k]) +
" component follows "
165 + string(components_[npiece - 1]) +
" component in "
166 + dmsa.substr(beg,
end - beg);
170 errormsg =
"Missing numbers in " + string(components_[k]) +
171 " component of " + dmsa.substr(beg,
end - beg);
175 istringstream
s(dmsa.substr(
p - intcount - digcount - 1,
176 intcount + digcount));
180 ipieces[k] = icurrent;
181 fpieces[k] = icurrent + fcurrent;
184 icurrent = fcurrent = 0;
185 ncurrent = digcount = intcount = 0;
188 errormsg =
"Internal sign in DMS string "
189 + dmsa.substr(beg,
end - beg);
192 errormsg =
"Illegal character " +
Utility::str(
x) +
" in DMS string "
193 + dmsa.substr(beg,
end - beg);
197 if (!errormsg.empty())
201 errormsg =
"Extra text following seconds in DMS string "
202 + dmsa.substr(beg,
end - beg);
206 errormsg =
"Missing numbers in trailing component of "
207 + dmsa.substr(beg,
end - beg);
211 istringstream
s(dmsa.substr(
p - intcount - digcount,
212 intcount + digcount));
216 ipieces[npiece] = icurrent;
217 fpieces[npiece] = icurrent + fcurrent;
219 if (pointseen && digcount == 0) {
220 errormsg =
"Decimal point in non-terminal component of "
221 + dmsa.substr(beg,
end - beg);
225 if (ipieces[1] >= 60 || fpieces[1] > 60 ) {
227 +
" not in range [0, 60)";
230 if (ipieces[2] >= 60 || fpieces[2] > 60) {
232 +
" not in range [0, 60)";
240 (60*(60*fpieces[0] + fpieces[1]) + fpieces[2]) / 3600 :
242 (60*fpieces[0] + fpieces[1]) / 60 : fpieces[0] ) );
244 real val = Utility::nummatch<real>(dmsa);
257 a = Decode(stra, ia);
258 b = Decode(strb, ib);
259 if (ia == NONE && ib == NONE) {
261 ia = longfirst ? LONGITUDE : LATITUDE;
262 ib = longfirst ? LATITUDE : LONGITUDE;
263 }
else if (ia == NONE)
264 ia =
flag(LATITUDE + LONGITUDE - ib);
266 ib =
flag(LATITUDE + LONGITUDE - ia);
269 + strb +
" interpreted as "
270 + (ia == LATITUDE ?
"latitudes" :
"longitudes"));
272 lat1 = ia == LATITUDE ?
a :
b,
273 lon1 = ia == LATITUDE ?
b :
a;
276 +
"d not in [-90d, 90d]");
283 real ang = Decode(angstr,
ind);
286 +
" includes a hemisphere, N/E/W/S");
292 real azi = Decode(azistr,
ind);
295 +
" has a latitude hemisphere, N/S");
304 return angle < 0 ? string(
"-inf") :
305 (angle > 0 ? string(
"inf") : string(
"nan"));
311 for (
unsigned i = 0;
i < unsigned(trailing); ++
i)
313 for (
unsigned i = 0;
i < prec; ++
i)
316 angle -=
floor(angle/360) * 360;
317 int sign = angle < 0 ? -1 : 1;
323 idegree =
floor(angle),
324 fdegree = (angle - idegree) *
scale +
real(0.5);
328 fdegree = (
f == fdegree &&
fmod(
f,
real(2)) == 1) ?
f - 1 :
f;
335 real pieces[3] = {fdegree, 0, 0};
336 for (
unsigned i = 1;
i <= unsigned(trailing); ++
i) {
338 ip =
floor(pieces[
i - 1]),
339 fp = pieces[
i - 1] - ip;
343 pieces[0] += idegree;
345 s << fixed << setfill(
'0');
351 s << setw(1 +
min(
int(
ind), 2) + prec + (prec ? 1 : 0));
357 s << setw(1 +
min(
int(
ind), 2));
359 << (dmssep ? dmssep : char(tolower(dmsindicators_[0])));
362 s << setw(2 + prec + (prec ? 1 : 0)) <<
Utility::str(pieces[1], prec);
364 s << char(tolower(dmsindicators_[1]));
369 << (dmssep ? dmssep : char(tolower(dmsindicators_[1])))
370 << setw(2 + prec + (prec ? 1 : 0)) <<
Utility::str(pieces[2], prec);
372 s << char(tolower(dmsindicators_[2]));
378 if (
ind != NONE &&
ind != AZIMUTH)
379 s << hemispheres_[(
ind == LATITUDE ? 0 : 2) + (
sign < 0 ? 0 : 1)];