Skip to content

Commit

Permalink
Merge 8795737 into 0193607
Browse files Browse the repository at this point in the history
  • Loading branch information
kbevers committed May 24, 2018
2 parents 0193607 + 8795737 commit 5f67c6d
Show file tree
Hide file tree
Showing 12 changed files with 116 additions and 43 deletions.
40 changes: 21 additions & 19 deletions src/PJ_isea.c
Expand Up @@ -4,14 +4,15 @@
*/

#include <errno.h>
#include <float.h>
#include <math.h>
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define PJ_LIB__
#include "proj_internal.h"
#include "proj_math.h"
#include "proj.h"
#include "projects.h"

Expand Down Expand Up @@ -79,7 +80,7 @@ static void hex_iso(struct hex *h) {
static void hexbin2(double width, double x, double y, int *i, int *j) {
double z, rx, ry, rz;
double abs_dx, abs_dy, abs_dz;
int ix, iy, iz, s;
long ix, iy, iz, s;
struct hex h;

x = x / cos(30 * M_PI / 180.0); /* rotated X coord */
Expand All @@ -92,11 +93,11 @@ static void hexbin2(double width, double x, double y, int *i, int *j) {
z = -x - y;

rx = floor(x + 0.5);
ix = (int)rx;
ix = lround(rx);
ry = floor(y + 0.5);
iy = (int)ry;
iy = lround(ry);
rz = floor(z + 0.5);
iz = (int)rz;
iz = lround(rz);

s = ix + iy + iz;

Expand Down Expand Up @@ -666,7 +667,7 @@ static int isea_dddi_ap3odd(struct isea_dgg *g, int quad, struct isea_pt *pt,
double hexwidth;
double sidelength; /* in hexes */
int d, i;
int maxcoord;
long maxcoord;
struct hex h;

/* This is the number of hexes from apex to base of a triangle */
Expand All @@ -678,7 +679,7 @@ static int isea_dddi_ap3odd(struct isea_dgg *g, int quad, struct isea_pt *pt,
/* TODO I think sidelength is always x.5, so
* (int)sidelength * 2 + 1 might be just as good
*/
maxcoord = (int) (sidelength * 2.0 + 0.5);
maxcoord = lround((sidelength * 2.0));

v = *pt;
hexbin2(hexwidth, v.x, v.y, &h.x, &h.y);
Expand Down Expand Up @@ -741,15 +742,15 @@ static int isea_dddi(struct isea_dgg *g, int quad, struct isea_pt *pt,
struct isea_pt *di) {
struct isea_pt v;
double hexwidth;
int sidelength; /* in hexes */
long sidelength; /* in hexes */
struct hex h;

if (g->aperture == 3 && g->resolution % 2 != 0) {
return isea_dddi_ap3odd(g, quad, pt, di);
}
/* todo might want to do this as an iterated loop */
if (g->aperture >0) {
sidelength = (int) (pow(g->aperture, g->resolution / 2.0) + 0.5);
sidelength = lround(pow(g->aperture, g->resolution / 2.0));
} else {
sidelength = g->resolution;
}
Expand Down Expand Up @@ -821,6 +822,7 @@ static int isea_ptdi(struct isea_dgg *g, int tri, struct isea_pt *pt,
}

/* q2di to seqnum */

static int isea_disn(struct isea_dgg *g, int quad, struct isea_pt *di) {
int sidelength;
int sn, height;
Expand All @@ -831,20 +833,20 @@ static int isea_disn(struct isea_dgg *g, int quad, struct isea_pt *di) {
return g->serial;
}
/* hexes in a quad */
hexes = (int) (pow(g->aperture, g->resolution) + 0.5);
hexes = lround(pow(g->aperture, g->resolution));
if (quad == 11) {
g->serial = 1 + 10 * hexes + 1;
return g->serial;
}
if (g->aperture == 3 && g->resolution % 2 == 1) {
height = (int) (pow(g->aperture, (g->resolution - 1) / 2.0));
height = lround(floor((pow(g->aperture, (g->resolution - 1) / 2.0))));
sn = ((int) di->x) * height;
sn += ((int) di->y) / height;
sn += (quad - 1) * hexes;
sn += 2;
} else {
sidelength = (int) (pow(g->aperture, g->resolution / 2.0) + 0.5);
sn = (int) ((quad - 1) * hexes + sidelength * di->x + di->y + 2);
sidelength = lround((pow(g->aperture, g->resolution / 2.0)));
sn = lround(floor(((quad - 1) * hexes + sidelength * di->x + di->y + 2)));
}

g->serial = sn;
Expand All @@ -860,8 +862,8 @@ static int isea_hex(struct isea_dgg *g, int tri,
struct isea_pt *pt, struct isea_pt *hex) {
struct isea_pt v;
#ifdef FIXME
int sidelength;
int d, i, x, y;
long sidelength;
long d, i, x, y;
#endif
int quad;

Expand All @@ -872,12 +874,12 @@ static int isea_hex(struct isea_dgg *g, int tri,

return 1;
#ifdef FIXME
d = (int)v.x;
i = (int)v.y;
d = lround(floor(v.x));
i = lround(floor(v.y));

/* Aperture 3 odd resolutions */
if (g->aperture == 3 && g->resolution % 2 != 0) {
int offset = (int)(pow(3.0, g->resolution - 1) + 0.5);
long offset = lround((pow(3.0, g->resolution - 1) + 0.5));

d += offset * ((g->quad-1) % 5);
i += offset * ((g->quad-1) % 5);
Expand All @@ -901,7 +903,7 @@ static int isea_hex(struct isea_dgg *g, int tri,
}

/* aperture 3 even resolutions and aperture 4 */
sidelength = (int) (pow(g->aperture, g->resolution / 2.0) + 0.5);
sidelength = lround((pow(g->aperture, g->resolution / 2.0)));
if (g->quad == 0) {
hex->x = 0;
hex->y = sidelength;
Expand Down
8 changes: 4 additions & 4 deletions src/PJ_robin.c
Expand Up @@ -78,12 +78,12 @@ static const struct COEFS Y[] = {

static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
XY xy = {0.0,0.0};
int i;
long i;
double dphi;
(void) P;

dphi = fabs(lp.phi);
i = isnan(lp.phi) ? -1 : (int)floor(dphi * C1);
i = isnan(lp.phi) ? -1 : lround(floor(dphi * C1));
if( i < 0 ){
proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
return xy;
Expand All @@ -100,7 +100,7 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */

static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
LP lp = {0.0,0.0};
int i;
long i;
double t, t1;
struct COEFS T;
int iters;
Expand All @@ -118,7 +118,7 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
}
} else { /* general problem */
/* in Y space, reduce to table interval */
i = isnan(lp.phi) ? -1 : (int)floor(lp.phi * NODES);
i = isnan(lp.phi) ? -1 : lround(floor(lp.phi * NODES));
if( i < 0 || i >= NODES ) {
proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
return lp;
Expand Down
11 changes: 6 additions & 5 deletions src/PJ_unitconvert.c
Expand Up @@ -71,6 +71,7 @@ Last update: 2017-05-16
#include <time.h>

#include "proj_internal.h"
#include "proj_math.h"
#include "projects.h"

PROJ_HEAD(unitconvert, "Unit conversion");
Expand Down Expand Up @@ -156,14 +157,14 @@ static double decimalyear_to_mjd(double decimalyear) {
/***********************************************************************
Epoch of modified julian date is 1858-11-16 00:00
************************************************************************/
int year;
long year;
double fractional_year;
double mjd;

if( decimalyear < -10000 || decimalyear > 10000 )
return 0;

year = (int)floor(decimalyear);
year = lround(floor(decimalyear));
fractional_year = decimalyear - year;
mjd = (year - 1859)*365 + 14 + 31;
mjd += fractional_year*days_in_year(year);
Expand Down Expand Up @@ -232,9 +233,9 @@ static double yyyymmdd_to_mjd(double yyyymmdd) {
Date given in YYYY-MM-DD format.
************************************************************************/

int year = (int)floor( yyyymmdd / 10000 );
int month = (int)floor((yyyymmdd - year*10000) / 100);
int day = (int)floor( yyyymmdd - year*10000 - month*100);
long year = lround(floor( yyyymmdd / 10000 ));
long month = lround(floor((yyyymmdd - year*10000) / 100));
long day = lround(floor( yyyymmdd - year*10000 - month*100));
double mjd = daynumber_in_year(year, month, day);

for (year -= 1; year > 1858; year--)
Expand Down
13 changes: 13 additions & 0 deletions src/gie.c
Expand Up @@ -1943,6 +1943,19 @@ static int cart_selftest (void) {
if (P->f != 1.0/298.257223563) return 125;
proj_destroy(P);

/* Test that pj_fwd* and pj_inv* returns NaNs when receiving NaN input */
P = proj_create(PJ_DEFAULT_CTX, "+proj=merc");
if (0==P) return 0;
a = proj_coord(NAN, NAN, NAN, NAN);
a = proj_trans(P, PJ_FWD, a);
if ( !( isnan(a.v[0]) && isnan(a.v[1]) && isnan(a.v[2]) && isnan(a.v[3]) ) )
return 126;
a = proj_coord(NAN, NAN, NAN, NAN);
a = proj_trans(P, PJ_INV, a);
if ( !( isnan(a.v[0]) && isnan(a.v[1]) && isnan(a.v[2]) && isnan(a.v[3]) ) )
return 127;
proj_destroy(P);

return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions src/nad_intr.c
Expand Up @@ -14,9 +14,9 @@ nad_intr(LP t, struct CTABLE *ct) {
int in;

t.lam /= ct->del.lam;
indx.lam = isnan(t.lam) ? 0 : (int)floor(t.lam);
indx.lam = isnan(t.lam) ? 0 : (pj_int32)lround(floor(t.lam));
t.phi /= ct->del.phi;
indx.phi = isnan(t.phi) ? 0 : (int)floor(t.phi);
indx.phi = isnan(t.phi) ? 0 : (pj_int32)lround(floor(t.phi));

frct.lam = t.lam - indx.lam;
frct.phi = t.phi - indx.phi;
Expand Down
8 changes: 4 additions & 4 deletions src/pj_apply_vgridshift.c
Expand Up @@ -48,8 +48,8 @@ static double read_vgrid_value( PJ *defn, LP input, int *gridlist_count_p, PJ_GR
int itable = 0;
double value = HUGE_VAL;
double grid_x, grid_y;
int grid_ix, grid_iy;
int grid_ix2, grid_iy2;
long grid_ix, grid_iy;
long grid_ix2, grid_iy2;
float *cvs;
/* do not deal with NaN coordinates */
/* cppcheck-suppress duplicateExpression */
Expand Down Expand Up @@ -108,8 +108,8 @@ static double read_vgrid_value( PJ *defn, LP input, int *gridlist_count_p, PJ_GR
/* Interpolation a location within the grid */
grid_x = (input.lam - ct->ll.lam) / ct->del.lam;
grid_y = (input.phi - ct->ll.phi) / ct->del.phi;
grid_ix = (int) floor(grid_x);
grid_iy = (int) floor(grid_y);
grid_ix = lround(floor(grid_x));
grid_iy = lround(floor(grid_y));
grid_x -= grid_ix;
grid_y -= grid_iy;

Expand Down
5 changes: 3 additions & 2 deletions src/pj_fwd.c
Expand Up @@ -32,14 +32,15 @@
#include <math.h>

#include "proj_internal.h"
#include "proj_math.h"
#include "projects.h"

#define INPUT_UNITS P->left
#define OUTPUT_UNITS P->right


static PJ_COORD fwd_prepare (PJ *P, PJ_COORD coo) {
if (HUGE_VAL==coo.v[0])
if (HUGE_VAL==coo.v[0] || HUGE_VAL==coo.v[1] || HUGE_VAL==coo.v[2])
return proj_coord_error ();

/* The helmert datum shift will choke unless it gets a sensible 4D coordinate */
Expand Down Expand Up @@ -193,7 +194,7 @@ XY pj_fwd(LP lp, PJ *P) {

if (!P->skip_fwd_prepare)
coo = fwd_prepare (P, coo);
if (HUGE_VAL==coo.v[0])
if (HUGE_VAL==coo.v[0] || HUGE_VAL==coo.v[1])
return proj_coord_error ().xy;

/* Do the transformation, using the lowest dimensional transformer available */
Expand Down
3 changes: 2 additions & 1 deletion src/pj_inv.c
Expand Up @@ -31,13 +31,14 @@
#include <math.h>

#include "proj_internal.h"
#include "proj_math.h"
#include "projects.h"

#define INPUT_UNITS P->right
#define OUTPUT_UNITS P->left

static PJ_COORD inv_prepare (PJ *P, PJ_COORD coo) {
if (coo.xyz.x == HUGE_VAL) {
if (coo.v[0] == HUGE_VAL || coo.v[1] == HUGE_VAL || coo.v[2] == HUGE_VAL) {
proj_errno_set (P, PJD_ERR_INVALID_X_OR_Y);
return proj_coord_error ();
}
Expand Down
45 changes: 41 additions & 4 deletions src/pj_math.c
Expand Up @@ -27,6 +27,21 @@

#include "proj_math.h"

/* pj_isnan is used in gie.c which means that is has to */
/* be exported in the Windows DLL and therefore needs */
/* to be declared even though we have isnan() on the */
/* system. */

#ifdef HAVE_C99_MATH
int pj_isnan (double x);
#endif

/* Returns 0 if not a NaN and non-zero if val is a NaN */
int pj_isnan (double x) {
/* cppcheck-suppress duplicateExpression */
return x != x;
}

#if !(defined(HAVE_C99_MATH) && HAVE_C99_MATH)

/* Compute hypotenuse */
Expand Down Expand Up @@ -61,11 +76,33 @@ double pj_asinh(double x) {
return x > 0 ? y : (x < 0 ? -y : x);
}

/* Returns 0 if not a NaN and non-zero if val is a NaN */
int pj_isnan (double x) {
/* cppcheck-suppress duplicateExpression */
return x != x;
double pj_round(double x) {
/* The handling of corner cases is copied from boost; see
* https://github.com/boostorg/math/pull/8
* with improvements to return -0.0 when appropriate */
double t;
if (x == 0)
return x; /* Retain sign of 0 */
else if (0 < x && x < 0.5)
return +0.0;
else if (0 > x && x > -0.5)
return -0.0;
else if (x > 0) {
t = ceil(x);
return 0.5 < t - x ? t - 1 : t;
} else { /* Includes NaN */
t = floor(x);
return 0.5 < x - t ? t + 1 : t;
}
}

long pj_lround(double x) {
/* Default value for overflow + NaN + (x == LONG_MIN) */
long r = LONG_MIN;
x = round(x);
if (fabs(x) < -(double)LONG_MIN) /* Assume (double)LONG_MIN is exact */
r = (int)x;
return r;
}

#endif /* !(defined(HAVE_C99_MATH) && HAVE_C99_MATH) */
2 changes: 2 additions & 0 deletions src/proj.def
Expand Up @@ -155,3 +155,5 @@ EXPORTS

proj_geod @140
proj_context_errno @141

pj_isnan @142
4 changes: 2 additions & 2 deletions src/proj_etmerc.c
Expand Up @@ -310,7 +310,7 @@ PJ *PROJECTION(etmerc) {


PJ *PROJECTION(utm) {
int zone;
long zone;
struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
if (0==Q)
return pj_default_destructor (P, ENOMEM);
Expand All @@ -337,7 +337,7 @@ PJ *PROJECTION(utm) {
}
else /* nearest central meridian input */
{
zone = (int)(floor ((adjlon (P->lam0) + M_PI) * 30. / M_PI));
zone = lround((floor ((adjlon (P->lam0) + M_PI) * 30. / M_PI)));
if (zone < 0)
zone = 0;
else if (zone >= 60)
Expand Down

0 comments on commit 5f67c6d

Please sign in to comment.