#7 better grid line placement

open
nobody
None
4
2008-12-02
2008-12-02
Hamish B
No

Hi, it would be nice to better place the grid lines and respect the user's prefered DMS style, rounding accordingly:
DDD.DDDDD, DDD MM.MMMM, DDD MM SS.SSSS

round on "nice numbers":
deg, min, sec: 30, 15, 10, 5, 2, 1
decimal deg: .5, .25, .1, .05, 0.02, 0.1

here is some sample code to do that, from
https://trac.osgeo.org/grass/browser/grass/trunk/ps/ps.map/ps_fclrtbl.c#L162
(GPL code)

(no idea if SF tracker will linewrap the code, or if <pre> will work. if it gets broken see the above link)

#define NSTEPS 3
#define NNSTEP 4 /* number of nice steps */

double nice_steps[NNSTEP] = { 1.0, 2.0, 2.5, 5.0 }; /* nice steps */
double ex, cur_d, cur_ex;
int ncols, cur_step, ddig;

dy = 1.5 * fontsize;

width = 72.0 * ct.width;
height = 72.0 * ct.height;
cwidth = 0.1;
ncols = (int)height / cwidth;
step = (dmax - dmin) / (ncols - 1);
lwidth = 0.02 * width;

/* Print labels */
/* maximum number of parts we can divide into */
k = (ncols - 1) * cwidth / dy;
/* step in values for labels */
step = (dmax - dmin) / k;

/* raw step - usually decimal number with many places, not nice */
/* find nice step and first nice value for label: nice steps are
* 1, 2, 2.5 or 5 * 10^n,
* we need nice step which is first >= raw step, we take each nice
* step and find 'n' and then compare differences */

for (i = 0; i < NNSTEP; i++) {
/* smalest n for which nice step >= raw step */
if (nice_steps[i] <= step) {
ex = 1;
while (nice_steps[i] * ex < step)
ex *= 10;
}
else {
ex = 0.1;
while (nice_steps[i] * ex > step)
ex *= 0.1;
ex *= 10;
}
if (i == 0 || (nice_steps[i] * ex - step) < cur_d) {
cur_step = i;
cur_d = nice_steps[i] * ex - step;
cur_ex = ex;
}
}
step = nice_steps[cur_step] * cur_ex;

/* Nice first value: first multiple of step >= dmin */
k = dmin / step;
val = k * step;
if (val < dmin)
val += step;

Hamish

Discussion