[GRASS5] datum transforms...
Eric G. Miller
egm2 at jps.net
Sun Jan 12 20:55:40 EST 2003
On Sun, Jan 12, 2003 at 09:03:31PM +0000, Paul Kelly wrote:
Thanks for working on this. Perhaps the following will help.
> > do_proj.c:
> > * LL<->LL is no longer a no-op.
> > * change all variations of pj_fwd and pj_inv to one call to
> > pj_transform
>
> Had a bit of a problem with this part:
Here's the function I replaced do_proj with. At the moment, I don't
remember why x & y aren't converted to radians for the ll<->ll case.
However, that case needs to be handle properly for strictly doing
datum translations.
static int do_transform(x,y,info_in,info_out)
double *x,*y;
struct pj_info *info_in,*info_out;
{
int ok;
double u,v;
double h = 0.0;
METERS_in = info_in->meters;
METERS_out = info_out->meters;
if (strncmp(info_in->proj,"ll",2) == 0 ) {
if (strncmp(info_out->proj,"ll",2) == 0 )
ok = pj_transform (info_in->pj, info_out->pj, 1, 0, x, y, &h);
else {
u = (*x) / RAD_TO_DEG;
v = (*y) / RAD_TO_DEG;
ok = pj_transform(info_in->pj,info_out->pj, 1, 0, &u, &v, &h);
*x = u / METERS_out;
*y = v / METERS_out;
}
}
else {
if (strncmp(info_out->proj,"ll",2) == 0 ) {
u = *x * METERS_in;
v = *y * METERS_in;
ok = pj_transform(info_in->pj,info_out->pj, 1, 0, &u, &v, &h);
*x = u * RAD_TO_DEG;
*y = v * RAD_TO_DEG;
}
else {
u = *x * METERS_in;
v = *y * METERS_in;
ok = pj_transform(info_in->pj,info_out->pj, 1, 0, &u, &v, &h);
*x = u / METERS_out;
*y = v / METERS_out;
}
}
return ok;
}
For the future, a function like the following would be better.
/* a couple defines to simplify reading the function */
#define MULTIPLY_LOOP(x,y,c,m) \
do {\
int i; \
for (i = 0; i < c; ++i) {\
x[i] *= m; \
y[i] *= m; \
}\
} while (0)
#define DIVIDE_LOOP(x,y,c,m) \
do {\
int i; \
for (i = 0; i < c; ++i) {\
x[i] /= m; \
y[i] /= m; \
}\
} while (0)
int do_transform (int count, double *x, double *y, double *h,
struct pj_info *info_in, struct pj_info *info_out);
{
int ok;
int has_h = 1;
METERS_in = info_in->meters;
METERS_out = info_out->meters;
if (h == NULL) {
int i;
h = G_malloc (sizeof *h * count);
/* they say memset is only guaranteed for chars ;-( */
for (i = 0; i < count; ++i)
h[i] = 0.0;
has_h = 0;
}
if (strncmp(info_in->proj,"ll",2) == 0 ) {
if (strncmp(info_out->proj,"ll",2) == 0 )
ok = pj_transform (info_in->pj, info_out->pj, count, 0, x, y, h);
else {
DIVIDE_LOOP(x,y,count,RAD_TO_DEG);
ok = pj_transform(info_in->pj,info_out->pj, count, 0, x, y, h);
DIVIDE_LOOP(x,y,count,METERS_out);
}
}
else {
if (strncmp(info_out->proj,"ll",2) == 0 ) {
MULTIPLY_LOOP(x,y,count,METERS_in);
ok = pj_transform(info_in->pj,info_out->pj, count, 0, x, y, h);
MULTIPLY_LOOP(x,y,count,RAD_TO_DEG);
}
else {
MULTIPLY_LOOP(x,y,count,METERS_in);
ok = pj_transform(info_in->pj,info_out->pj, count, 0, x, y, h);
DIVIDE_LOOP(x,y,count,METERS_out);
}
}
if (!has_h) free (h);
return ok;
}
> > Before using pj_transform(), set the environment variable PROJ_LIB to
> > $GISBASE/etc/nad
> >
> > #define GRIDDIR "/etc/nad"
> >
> > static void set_proj_lib_env (void)
> > {
> > const char *gisbase = G_gisbase();
> > char *value = NULL;
> > size_t len = strlen(gisbase) * sizeof(GRIDDIR) + 1;
> > value = G_malloc (len);
> > sprintf (value, "%s%s", gisbase, GRIDDIR);
> > if (setenv ("PROJ_LIB", value, 1) == 0)
> > fprintf(stderr, "set PROJ_LIB='%s'\n", value);
> > else
> > fprintf(stderr, "failed to set PROJ_LIB='%s'\n", value);
> >
> > free (value);
> > }
Hmm, maybe s/setenv/putenv/? The function will have to be rewritten
to something like:
#define GRIDDIR "/etc/nad"
int set_proj_lib_env (void)
{
int ok;
const char *gisbase = G_gisbase();
char *buf = NULL;
size_t len = strlen(gisbase) + sizeof(GRIDDIR)
+ sizeof("PROJ_LIB=") + 1;
buf = G_malloc(len);
sprintf (buf, "PROJ_LIB=%s/%s", gisbase, GRIDDIR);
if ((ok = putenv (buf)) == -1)
G_warning ("%s:putenv(%s) failed!", "set_proj_lib_env", buf);
free (buf);
return ok;
}
--
echo ">gra.fcw at 2ztr< eryyvZ .T pveR" | rot13 | reverse
More information about the grass-dev
mailing list