Skip to content
forked from OSGeo/PROJ

Commit

Permalink
Merge pull request #45 from OSGeo/master
Browse files Browse the repository at this point in the history
Add support for Degree Sign on input (OSGeo#2791)
  • Loading branch information
sthagen authored Aug 15, 2021
2 parents d35dc66 + 17f83c6 commit 8b2b83e
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 20 deletions.
2 changes: 1 addition & 1 deletion docs/source/apps/cs2cs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ The following script
::

cs2cs +proj=latlong +datum=NAD83 +to +proj=utm +zone=10 +datum=NAD27 -r <<EOF
45d15'33.1" 111.5W
45°15'33.1" 111.5W
45d15.551666667N -111d30
+45.25919444444 111d30'000w
EOF
Expand Down
63 changes: 44 additions & 19 deletions src/dmstor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ vm[] = {
.0002908882086657216,
.0000048481368110953599
};
/* byte sequence for Degree Sign U+00B0 in UTF-8. */
static constexpr char
DEG_SIGN1 = '\xc2';
static constexpr char
DEG_SIGN2 = '\xb0';

double
dmstor(const char *is, char **rs) {
return dmstor_ctx( pj_get_default_ctx(), is, rs );
Expand All @@ -29,57 +35,76 @@ dmstor(const char *is, char **rs) {
dmstor_ctx(PJ_CONTEXT *ctx, const char *is, char **rs) {
int n, nl;
char *s, work[MAX_WORK];
const char* p;
const char* p;
double v, tv;

if (rs)
*rs = (char *)is;
/* copy sting into work space */
/* copy string into work space */
while (isspace(*is)) ++is;
n = MAX_WORK;
s = work;
p = (char *)is;
while (isgraph(*p) && --n)

/*
* Copy characters into work until we hit a non-printable character or run
* out of space in the buffer. Make a special exception for the bytes of
* the Degree Sign in UTF-8.
*
* It is possible that a really odd input (like lots of leading zeros)
* could be truncated in copying into work. But ...
*/
while ((isgraph(*p) || *p == DEG_SIGN1 || *p == DEG_SIGN2) && --n)
*s++ = *p++;
*s = '\0';
/* it is possible that a really odd input (like lots of leading
zeros) could be truncated in copying into work. But ... */
int sign = *(s = work);
if (sign == '+' || sign == '-') s++;
else sign = '+';
v = 0.;
for (nl = 0 ; nl < 3 ; nl = n + 1 ) {
for (nl = 0 ; nl < 3 ; nl = n + 1) {
if (!(isdigit(*s) || *s == '.')) break;
if ((tv = proj_strtod(s, &s)) == HUGE_VAL)
return tv;
switch (*s) {
case 'D': case 'd':
n = 0; break;
case '\'':
n = 1; break;
case '"':
n = 2; break;
case 'r': case 'R':
int adv = 1;

if (*s == 'D' || *s == 'd' || *s == DEG_SIGN2) {
/*
* Accept \xb0 as a single-byte degree symbol. This byte is the
* degree symbol in various single-byte encodings: multiple ISO
* 8859 parts, several Windows code pages and others.
*/
n = 0;
} else if (*s == '\'') {
n = 1;
} else if (*s == '"') {
n = 2;
} else if (s[0] == DEG_SIGN1 && s[1] == DEG_SIGN2) {
/* degree symbol in UTF-8 */
n = 0;
adv = 2;
} else if (*s == 'r' || *s == 'R') {
if (nl) {
proj_context_errno_set( ctx, PROJ_ERR_INVALID_OP_ILLEGAL_ARG_VALUE );
return HUGE_VAL;
}
++s;
v = tv;
goto skip;
default:
n = 4;
continue;
} else {
v += tv * vm[nl];
skip: n = 4;
n = 4;
continue;
}

if (n < nl) {
proj_context_errno_set( ctx, PROJ_ERR_INVALID_OP_ILLEGAL_ARG_VALUE );
return HUGE_VAL;
}
v += tv * vm[n];
++s;
s += adv;
}
/* postfix sign */
/* postfix sign */
if (*s && (p = strchr(sym, *s))) {
sign = (p - sym) >= 4 ? '-' : '+';
++s;
Expand Down
6 changes: 6 additions & 0 deletions test/unit/gie_self_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,12 @@ TEST(gie, info_functions) {
/* we can't expect perfect numerical accuracy so testing with a tolerance */
ASSERT_NEAR(-2.0, proj_dmstor(&buf[0], NULL), 1e-7);

/* test UTF-8 degree sign on DMS input */
ASSERT_NEAR(0.34512432, proj_dmstor("19°46'27\"E", NULL), 1e-7);

/* test ISO 8859-1, cp1252, et al. degree sign on DMS input */
ASSERT_NEAR(0.34512432, proj_dmstor("19" "\260" "46'27\"E", NULL), 1e-7);

/* test proj_derivatives_retrieve() and proj_factors_retrieve() */
P = proj_create(PJ_DEFAULT_CTX, "+proj=merc +ellps=WGS84");
a = proj_coord(0, 0, 0, 0);
Expand Down

0 comments on commit 8b2b83e

Please sign in to comment.