Ejemplo n.º 1
0
	void
geod_set(int argc, char **argv) {
	paralist *start = 0, *curr;
	double es;
	char *name;
	int i;

    /* put arguments into internal linked list */
	if (argc <= 0)
		emess(1, "no arguments in initialization list");
	start = curr = pj_mkparam(argv[0]);
	for (i = 1; i < argc; ++i) {
		curr->next = pj_mkparam(argv[i]);
		curr = curr->next;
	}
	/* set elliptical parameters */
	if (pj_ell_set(pj_get_default_ctx(),start, &geod_a, &es)) emess(1,"ellipse setup failure");
	/* set units */
	if ((name = pj_param(NULL,start, "sunits").s) != NULL) {
		char *s;
                struct PJ_UNITS *unit_list = pj_get_units_ref();
		for (i = 0; (s = unit_list[i].id) && strcmp(name, s) ; ++i) ;
		if (!s)
			emess(1,"%s unknown unit conversion id", name);
		fr_meter = 1. / (to_meter = atof(unit_list[i].to_meter));
	} else
		to_meter = fr_meter = 1.;
	geod_f = es/(1 + sqrt(1 - es));
	geod_ini();
	/* check if line or arc mode */
	if (pj_param(NULL,start, "tlat_1").i) {
		double del_S;
#undef f
		phi1 = pj_param(NULL,start, "rlat_1").f;
		lam1 = pj_param(NULL,start, "rlon_1").f;
		if (pj_param(NULL,start, "tlat_2").i) {
			phi2 = pj_param(NULL,start, "rlat_2").f;
			lam2 = pj_param(NULL,start, "rlon_2").f;
			geod_inv();
			geod_pre();
		} else if ((geod_S = pj_param(NULL,start, "dS").f) != 0.) {
			al12 = pj_param(NULL,start, "rA").f;
			geod_pre();
			geod_for();
		} else emess(1,"incomplete geodesic/arc info");
		if ((n_alpha = pj_param(NULL,start, "in_A").i) > 0) {
			if (!(del_alpha = pj_param(NULL,start, "rdel_A").f))
				emess(1,"del azimuth == 0");
		} else if ((del_S = fabs(pj_param(NULL,start, "ddel_S").f)) != 0.) {
			n_S = (int)(geod_S / del_S + .5);
		} else if ((n_S = pj_param(NULL,start, "in_S").i) <= 0)
			emess(1,"no interval divisor selected");
	}
	/* free up linked list */
	for ( ; start; start = curr) {
		curr = start->next;
		pj_dalloc(start);
	}
}
Ejemplo n.º 2
0
PJ_INIT_INFO proj_init_info(const char *initname){
/******************************************************************************
    Information about a named init file.

    Maximum length of initname is 64.

    Returns PJ_INIT_INFO struct.

    If the init file is not found all members of the return struct are set
    to the empty string.

    If the init file is found, but the metadata is missing, the value is
    set to "Unknown".
******************************************************************************/
    int file_found;
    char param[80], key[74];
    paralist *start, *next;
    PJ_INIT_INFO ininfo;
    PJ_CONTEXT *ctx = pj_get_default_ctx();

    memset(&ininfo, 0, sizeof(PJ_INIT_INFO));

    file_found = pj_find_file(ctx, initname, ininfo.filename, sizeof(ininfo.filename));
    if (!file_found || strlen(initname) > 64) {
        return ininfo;
    }

    /* The initial memset (0) makes strncpy safe here */
    strncpy (ininfo.name, initname, sizeof(ininfo.name) - 1);
    strcpy(ininfo.origin, "Unknown");
    strcpy(ininfo.version, "Unknown");
    strcpy(ininfo.lastupdate, "Unknown");

    strncpy (key, initname, 64); /* make room for ":metadata\0" at the end */
    key[64] = 0;
    strncat(key, ":metadata", 9);
    strcpy(param, "+init=");
    /* The +strlen(param) avoids a cppcheck false positive warning */
    strncat(param + strlen(param), key, sizeof(param)-1-strlen(param));

    start = pj_mkparam(param);
    pj_expand_init(ctx, start);

    if (pj_param(ctx, start, "tversion").i)
        strncpy(ininfo.version, pj_param(ctx, start, "sversion").s, sizeof(ininfo.version) - 1);

    if (pj_param(ctx, start, "torigin").i)
        strncpy(ininfo.origin, pj_param(ctx, start, "sorigin").s, sizeof(ininfo.origin) - 1);

    if (pj_param(ctx, start, "tlastupdate").i)
        strncpy(ininfo.lastupdate, pj_param(ctx, start, "slastupdate").s, sizeof(ininfo.lastupdate) - 1);

    for ( ; start; start = next) {
        next = start->next;
        pj_dalloc(start);
    }

   return ininfo;
}
Ejemplo n.º 3
0
static paralist *
get_opt(paralist **start, FILE *fid, char *name, paralist *next) {
    char sword[302], *word = sword+1;
    int first = 1, len, c;

    len = strlen(name);
    *sword = 't';
    while (fscanf(fid, "%300s", word) == 1) {
        if (*word == '#') /* skip comments */
            while((c = fgetc(fid)) != EOF && c != '\n') ;
        else if (*word == '<') { /* control name */
            if (first && !strncmp(name, word + 1, len)
                && word[len + 1] == '>')
                first = 0;
            else if (!first && *word == '<') {
                while((c = fgetc(fid)) != EOF && c != '\n') ;
                break;
            }
        } else if (!first && !pj_param(*start, sword).i) {
            /* don't default ellipse if datum, ellps or any earth model
               information is set. */
            if( strncmp(word,"ellps=",6) != 0 
                || (!pj_param(*start, "tdatum").i 
                    && !pj_param(*start, "tellps").i 
                    && !pj_param(*start, "ta").i 
                    && !pj_param(*start, "tb").i 
                    && !pj_param(*start, "trf").i 
                    && !pj_param(*start, "tf").i) )
            {
                next = next->next = pj_mkparam(word);
            }
        }
    }

    if (errno == 25)
        errno = 0;
    return next;
}
Ejemplo n.º 4
0
PJ *
pj_init(int argc, char **argv) {
	char *s, *name;
        paralist *start = NULL;
	PJ *(*proj)(PJ *);
	paralist *curr;
	int i;
	PJ *PIN = 0;
        const char *old_locale;

	errno = pj_errno = 0;
        start = NULL;

        old_locale = setlocale(LC_NUMERIC, NULL); 
        setlocale(LC_NUMERIC,"C");

	/* put arguments into internal linked list */
	if (argc <= 0) { pj_errno = -1; goto bum_call; }
	for (i = 0; i < argc; ++i)
		if (i)
			curr = curr->next = pj_mkparam(argv[i]);
		else
			start = curr = pj_mkparam(argv[i]);
	if (pj_errno) goto bum_call;

	/* check if +init present */
	if (pj_param(start, "tinit").i) {
		paralist *last = curr;

		if (!(curr = get_init(&start, curr, pj_param(start, "sinit").s)))
			goto bum_call;
		if (curr == last) { pj_errno = -2; goto bum_call; }
	}

	/* find projection selection */
	if (!(name = pj_param(start, "sproj").s))
		{ pj_errno = -4; goto bum_call; }
	for (i = 0; (s = pj_list[i].id) && strcmp(name, s) ; ++i) ;
	if (!s) { pj_errno = -5; goto bum_call; }

	/* set defaults, unless inhibited */
	if (!pj_param(start, "bno_defs").i)
		curr = get_defaults(&start, curr, name);
	proj = (PJ *(*)(PJ *)) pj_list[i].proj;

	/* allocate projection structure */
	if (!(PIN = (*proj)(0))) goto bum_call;
	PIN->params = start;
        PIN->is_latlong = 0;
        PIN->is_geocent = 0;
        PIN->long_wrap_center = 0.0;

        /* set datum parameters */
        if (pj_datum_set(start, PIN)) goto bum_call;

	/* set ellipsoid/sphere parameters */
	if (pj_ell_set(start, &PIN->a, &PIN->es)) goto bum_call;

        PIN->a_orig = PIN->a;
        PIN->es_orig = PIN->es;

	PIN->e = sqrt(PIN->es);
	PIN->ra = 1. / PIN->a;
	PIN->one_es = 1. - PIN->es;
	if (PIN->one_es == 0.) { pj_errno = -6; goto bum_call; }
	PIN->rone_es = 1./PIN->one_es;

        /* Now that we have ellipse information check for WGS84 datum */
        if( PIN->datum_type == PJD_3PARAM 
            && PIN->datum_params[0] == 0.0
            && PIN->datum_params[1] == 0.0
            && PIN->datum_params[2] == 0.0
            && PIN->a == 6378137.0
            && ABS(PIN->es - 0.006694379990) < 0.000000000050 )/*WGS84/GRS80*/
        {
            PIN->datum_type = PJD_WGS84;
        }
        
	/* set PIN->geoc coordinate system */
	PIN->geoc = (PIN->es && pj_param(start, "bgeoc").i);

	/* over-ranging flag */
	PIN->over = pj_param(start, "bover").i;

	/* longitude center for wrapping */
	PIN->long_wrap_center = pj_param(start, "rlon_wrap").f;

	/* central meridian */
	PIN->lam0=pj_param(start, "rlon_0").f;

	/* central latitude */
	PIN->phi0 = pj_param(start, "rlat_0").f;

	/* false easting and northing */
	PIN->x0 = pj_param(start, "dx_0").f;
	PIN->y0 = pj_param(start, "dy_0").f;

	/* general scaling factor */
	if (pj_param(start, "tk_0").i)
		PIN->k0 = pj_param(start, "dk_0").f;
	else if (pj_param(start, "tk").i)
		PIN->k0 = pj_param(start, "dk").f;
	else
		PIN->k0 = 1.;
	if (PIN->k0 <= 0.) {
		pj_errno = -31;
		goto bum_call;
	}

	/* set units */
	s = 0;
	if ((name = pj_param(start, "sunits").s)) { 
		for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i) ;
		if (!s) { pj_errno = -7; goto bum_call; }
		s = pj_units[i].to_meter;
	}
	if (s || (s = pj_param(start, "sto_meter").s)) {
		PIN->to_meter = strtod(s, &s);
		if (*s == '/') /* ratio number */
			PIN->to_meter /= strtod(++s, 0);
		PIN->fr_meter = 1. / PIN->to_meter;
	} else
		PIN->to_meter = PIN->fr_meter = 1.;

	/* prime meridian */
	s = 0;
	if ((name = pj_param(start, "spm").s)) { 
            const char *value = NULL;
            char *next_str = NULL;

            for (i = 0; pj_prime_meridians[i].id != NULL; ++i )
            {
                if( strcmp(name,pj_prime_meridians[i].id) == 0 )
                {
                    value = pj_prime_meridians[i].defn;
                    break;
                }
            }
            
            if( value == NULL 
                && (dmstor(name,&next_str) != 0.0  || *name == '0')
                && *next_str == '\0' )
                value = name;

            if (!value) { pj_errno = -46; goto bum_call; }
            PIN->from_greenwich = dmstor(value,NULL);
	}
        else
            PIN->from_greenwich = 0.0;

	/* projection specific initialization */
	if (!(PIN = (*proj)(PIN)) || errno || pj_errno) {
bum_call: /* cleanup error return */
		if (!pj_errno)
			pj_errno = errno;
		if (PIN)
			pj_free(PIN);
		else
			for ( ; start; start = curr) {
				curr = start->next;
				pj_dalloc(start);
			}
		PIN = 0;
	}
        setlocale(LC_NUMERIC,old_locale);

	return PIN;
}
parameters pj_init(R const& arguments, bool use_defaults = true)
{
    parameters pin;
    for (std::vector<std::string>::const_iterator it = boost::begin(arguments);
        it != boost::end(arguments); it++)
    {
        pin.params.push_back(pj_mkparam(*it));
    }

    /* check if +init present */
    if (pj_param(pin.params, "tinit").i)
    {
        // maybe TODO: handle "init" parameter
        //if (!(curr = get_init(&arguments, curr, pj_param(pin.params, "sinit").s)))
    }

    // find projection -> implemented in projection factory
    pin.name = pj_param(pin.params, "sproj").s;
    //if (pin.name.empty())
    //{ throw proj_exception(-4); }


    // set defaults, unless inhibited
    // GL-Addition, if use_defaults is false then defaults are ignored
    if (use_defaults && ! pj_param(pin.params, "bno_defs").i)
    {
        // proj4 gets defaults from "proj_def.dat", file of 94/02/23 with a few defaults.
        // Here manually
        if (pin.name == "lcc")
        {
            pin.params.push_back(pj_mkparam("lat_1=33"));
            pin.params.push_back(pj_mkparam("lat_2=45"));
        }
        else if (pin.name == "aea")
        {
            pin.params.push_back(pj_mkparam("lat_1=29.5"));
            pin.params.push_back(pj_mkparam("lat_2=45.5 "));
        }
        else
        {
            //<general>ellps=WGS84
        }
        //curr = get_defaults(&arguments, curr, name);
    }

    /* allocate projection structure */
    // done by constructor:
    // pin.is_latlong = 0;
    // pin.is_geocent = 0;
    // pin.long_wrap_center = 0.0;

    /* set datum parameters */
    pj_datum_set(pin.params, pin);

    /* set ellipsoid/sphere parameters */
    pj_ell_set(pin.params, pin.a, pin.es);

    pin.a_orig = pin.a;
    pin.es_orig = pin.es;

    pin.e = sqrt(pin.es);
    pin.ra = 1. / pin.a;
    pin.one_es = 1. - pin.es;
    if (pin.one_es == 0.) { throw proj_exception(-6); }
    pin.rone_es = 1./pin.one_es;

    /* Now that we have ellipse information check for WGS84 datum */
    if( pin.datum_type == PJD_3PARAM
        && pin.datum_params[0] == 0.0
        && pin.datum_params[1] == 0.0
        && pin.datum_params[2] == 0.0
        && pin.a == 6378137.0
        && geometry::math::abs(pin.es - 0.006694379990) < 0.000000000050 )/*WGS84/GRS80*/
    {
        pin.datum_type = PJD_WGS84;
    }

    /* set pin.geoc coordinate system */
    pin.geoc = (pin.es && pj_param(pin.params, "bgeoc").i);

    /* over-ranging flag */
    pin.over = pj_param(pin.params, "bover").i;

    /* longitude center for wrapping */
    pin.long_wrap_center = pj_param(pin.params, "rlon_wrap").f;

    /* central meridian */
    pin.lam0 = pj_param(pin.params, "rlon_0").f;

    /* central latitude */
    pin.phi0 = pj_param(pin.params, "rlat_0").f;

    /* false easting and northing */
    pin.x0 = pj_param(pin.params, "dx_0").f;
    pin.y0 = pj_param(pin.params, "dy_0").f;

    /* general scaling factor */
    if (pj_param(pin.params, "tk_0").i)
        pin.k0 = pj_param(pin.params, "dk_0").f;
    else if (pj_param(pin.params, "tk").i)
        pin.k0 = pj_param(pin.params, "dk").f;
    else
        pin.k0 = 1.;
    if (pin.k0 <= 0.) {
        throw proj_exception(-31);
    }

    /* set units */
    std::string s;
    std::string units = pj_param(pin.params, "sunits").s;
    if (! units.empty())
    {
        const int n = sizeof(pj_units) / sizeof(pj_units[0]);
        int index = -1;
        for (int i = 0; i < n && index == -1; i++)
        {
            if(pj_units[i].id == units)
            {
                index = i;
            }
        }

        if (index == -1) { throw proj_exception(-7); }
        s = pj_units[index].to_meter;
    }

    if (s.empty())
    {
        s = pj_param(pin.params, "sto_meter").s;
    }

    if (! s.empty())
    {
        // TODO: IMPLEMENT SPLIT
        pin.to_meter = atof(s.c_str());
        //if (*s == '/') /* ratio number */
        //    pin.to_meter /= strtod(++s, 0);
        pin.fr_meter = 1. / pin.to_meter;
    }
    else
    {
        pin.to_meter = pin.fr_meter = 1.;
    }

    /* prime meridian */
    s.clear();
    std::string pm = pj_param(pin.params, "spm").s;
    if (! pm.empty())
    {
        std::string value;

        int n = sizeof(pj_prime_meridians) / sizeof(pj_prime_meridians[0]);
        int index = -1;
        for (int i = 0; i < n && index == -1; i++)
        {
            if(pj_prime_meridians[i].id == pm)
            {
                value = pj_prime_meridians[i].defn;
                index = i;
            }
        }

        if (index == -1) { throw proj_exception(-7); }
        if (value.empty()) { throw proj_exception(-46); }

        geometry::strategy::dms_parser<true> parser;
        pin.from_greenwich = parser(value.c_str());
    }
    else
    {
        pin.from_greenwich = 0.0;
    }

    return pin;
}
Ejemplo n.º 6
0
/* initialize geographic shape parameters */
inline void pj_ell_set(std::vector<pvalue>& parameters, double &a, double &es)
{
    int i = 0;
    double b = 0.0;
    double e = 0.0;
    std::string name;

    /* check for varying forms of ellipsoid input */
    a = es = 0.;

    /* R takes precedence */
    if (pj_param(parameters, "tR").i)
        a = pj_param(parameters, "dR").f;
    else { /* probable elliptical figure */

        /* check if ellps present and temporarily append its values to pl */
        name = pj_param(parameters, "sellps").s;
        if (! name.empty())
        {
            const int n = sizeof(pj_ellps) / sizeof(pj_ellps[0]);
            int index = -1;
            for (int i = 0; i < n && index == -1; i++)
            {
                if(pj_ellps[i].id == name)
                {
                    index = i;
                }
            }

            if (index == -1) { throw proj_exception(-9); }

            parameters.push_back(pj_mkparam(pj_ellps[index].major));
            parameters.push_back(pj_mkparam(pj_ellps[index].ell));
        }
        a = pj_param(parameters, "da").f;
        if (pj_param(parameters, "tes").i) /* eccentricity squared */
            es = pj_param(parameters, "des").f;
        else if (pj_param(parameters, "te").i) { /* eccentricity */
            e = pj_param(parameters, "de").f;
            es = e * e;
        } else if (pj_param(parameters, "trf").i) { /* recip flattening */
            es = pj_param(parameters, "drf").f;
            if (!es) {
                throw proj_exception(-10);
            }
            es = 1./ es;
            es = es * (2. - es);
        } else if (pj_param(parameters, "tf").i) { /* flattening */
            es = pj_param(parameters, "df").f;
            es = es * (2. - es);
        } else if (pj_param(parameters, "tb").i) { /* minor axis */
            b = pj_param(parameters, "db").f;
            es = 1. - (b * b) / (a * a);
        }     /* else es == 0. and sphere of radius a */
        if (!b)
            b = a * sqrt(1. - es);
        /* following options turn ellipsoid into equivalent sphere */
        if (pj_param(parameters, "bR_A").i) { /* sphere--area of ellipsoid */
            a *= 1. - es * (SIXTH + es * (RA4 + es * RA6));
            es = 0.;
        } else if (pj_param(parameters, "bR_V").i) { /* sphere--vol. of ellipsoid */
            a *= 1. - es * (SIXTH + es * (RV4 + es * RV6));
            es = 0.;
        } else if (pj_param(parameters, "bR_a").i) { /* sphere--arithmetic mean */
            a = .5 * (a + b);
            es = 0.;
        } else if (pj_param(parameters, "bR_g").i) { /* sphere--geometric mean */
            a = sqrt(a * b);
            es = 0.;
        } else if (pj_param(parameters, "bR_h").i) { /* sphere--harmonic mean */
            a = 2. * a * b / (a + b);
            es = 0.;
        } else if ((i = pj_param(parameters, "tR_lat_a").i) || /* sphere--arith. */
            pj_param(parameters, "tR_lat_g").i) { /* or geom. mean at latitude */
            double tmp;

            tmp = sin(pj_param(parameters, i ? "rR_lat_a" : "rR_lat_g").f);
            if (geometry::math::abs(tmp) > HALFPI) {
                throw proj_exception(-11);
            }
            tmp = 1. - es * tmp * tmp;
            a *= i ? .5 * (1. - es + tmp) / ( tmp * sqrt(tmp)) :
                sqrt(1. - es) / tmp;
            es = 0.;
        }
    }

    /* some remaining checks */
    if (es < 0.)
        { throw proj_exception(-12); }
    if (a <= 0.)
        { throw proj_exception(-13); }
}
Ejemplo n.º 7
0
/* set ellipsoid parameters a and es */
#include "projects.h"
#include <string.h>
#define SIXTH .1666666666666666667 /* 1/6 */
#define RA4 .04722222222222222222 /* 17/360 */
#define RA6 .02215608465608465608 /* 67/3024 */
#define RV4 .06944444444444444444 /* 5/72 */
#define RV6 .04243827160493827160 /* 55/1296 */
	int /* initialize geographic shape parameters */
pj_ell_set(paralist *pl, double *a, double *es) {
	int i;
	double b=0.0, e;
	char *name;
	paralist *start = 0, *curr;

		/* check for varying forms of ellipsoid input */
	*a = *es = 0.;
	/* R takes precedence */
	if (pj_param(pl, "tR").i)
		*a = pj_param(pl, "dR").f;
	else { /* probable elliptical figure */

		/* check if ellps present and temporarily append its values to pl */
		if (name = pj_param(pl, "sellps").s) {
			char *s;

			for (start = pl; start && start->next ; start = start->next) ;
			curr = start;
			for (i = 0; (s = pj_ellps[i].id) && strcmp(name, s) ; ++i) ;
			if (!s) { pj_errno = -9; return 1; }
			curr = curr->next = pj_mkparam(pj_ellps[i].major);
			curr = curr->next = pj_mkparam(pj_ellps[i].ell);
		}
		*a = pj_param(pl, "da").f;
		if (pj_param(pl, "tes").i) /* eccentricity squared */
			*es = pj_param(pl, "des").f;
		else if (pj_param(pl, "te").i) { /* eccentricity */
			e = pj_param(pl, "de").f;
			*es = e * e;
		} else if (pj_param(pl, "trf").i) { /* recip flattening */
			*es = pj_param(pl, "drf").f;
			if (!*es) {
				pj_errno = -10;
				goto bomb;
			}
			*es = 1./ *es;
			*es = *es * (2. - *es);
		} else if (pj_param(pl, "tf").i) { /* flattening */
			*es = pj_param(pl, "df").f;
			*es = *es * (2. - *es);
		} else if (pj_param(pl, "tb").i) { /* minor axis */
			b = pj_param(pl, "db").f;
			*es = 1. - (b * b) / (*a * *a);
		}     /* else *es == 0. and sphere of radius *a */
		if (!b)
			b = *a * sqrt(1. - *es);
		/* following options turn ellipsoid into equivalent sphere */
		if (pj_param(pl, "bR_A").i) { /* sphere--area of ellipsoid */
			*a *= 1. - *es * (SIXTH + *es * (RA4 + *es * RA6));
			*es = 0.;
		} else if (pj_param(pl, "bR_V").i) { /* sphere--vol. of ellipsoid */
			*a *= 1. - *es * (SIXTH + *es * (RV4 + *es * RV6));
			*es = 0.;
		} else if (pj_param(pl, "bR_a").i) { /* sphere--arithmetic mean */
			*a = .5 * (*a + b);
			*es = 0.;
		} else if (pj_param(pl, "bR_g").i) { /* sphere--geometric mean */
			*a = sqrt(*a * b);
			*es = 0.;
		} else if (pj_param(pl, "bR_h").i) { /* sphere--harmonic mean */
			*a = 2. * *a * b / (*a + b);
			*es = 0.;
		} else if ((i = pj_param(pl, "tR_lat_a").i) || /* sphere--arith. */
			pj_param(pl, "tR_lat_g").i) { /* or geom. mean at latitude */
			double tmp;

			tmp = sin(pj_param(pl, i ? "rR_lat_a" : "rR_lat_g").f);
			if (fabs(tmp) > HALFPI) {
				pj_errno = -11;
				goto bomb;
			}
			tmp = 1. - *es * tmp * tmp;
			*a *= i ? .5 * (1. - *es + tmp) / ( tmp * sqrt(tmp)) :
				sqrt(1. - *es) / tmp;
			*es = 0.;
		}
bomb:
		if (start) { /* clean up temporary extension of list */
			pj_dalloc(start->next->next);
			pj_dalloc(start->next);
			start->next = 0;
		}
		if (pj_errno)
			return 1;
	}
	/* some remaining checks */
	if (*es < 0.)
		{ pj_errno = -12; return 1; }
	if (*a <= 0.)
		{ pj_errno = -13; return 1; }
	return 0;
}
Ejemplo n.º 8
0
int pj_datum_set(projCtx ctx, paralist *pl, PJ *projdef)

{
    const char *name, *towgs84, *nadgrids, *catalog;

    projdef->datum_type = PJD_UNKNOWN;

/* -------------------------------------------------------------------- */
/*      Is there a datum definition in the parameters list?  If so,     */
/*      add the defining values to the parameter list.  Note that       */
/*      this will append the ellipse definition as well as the          */
/*      towgs84= and related parameters.  It should also be pointed     */
/*      out that the addition is permanent rather than temporary        */
/*      like most other keyword expansion so that the ellipse           */
/*      definition will last into the pj_ell_set() function called      */
/*      after this one.                                                 */
/* -------------------------------------------------------------------- */
    if( (name = pj_param(ctx, pl,"sdatum").s) != NULL )
    {
        paralist *curr;
        const char *s;
        int i;

        /* find the end of the list, so we can add to it */
        for (curr = pl; curr && curr->next ; curr = curr->next) {}
        
        /* find the datum definition */
        for (i = 0; (s = pj_datums[i].id) && strcmp(name, s) ; ++i) {}

        if (!s) { pj_ctx_set_errno(ctx, -9); return 1; }

        if( pj_datums[i].ellipse_id && strlen(pj_datums[i].ellipse_id) > 0 )
        {
            char	entry[100];
            
            strcpy( entry, "ellps=" );
            strncat( entry, pj_datums[i].ellipse_id, 80 );
            curr = curr->next = pj_mkparam(entry);
        }
        
        if( pj_datums[i].defn && strlen(pj_datums[i].defn) > 0 )
            curr = curr->next = pj_mkparam(pj_datums[i].defn);
    }

/* -------------------------------------------------------------------- */
/*      Check for nadgrids parameter.                                   */
/* -------------------------------------------------------------------- */
    if( (nadgrids = pj_param(ctx, pl,"snadgrids").s) != NULL )
    {
        /* We don't actually save the value separately.  It will continue
           to exist int he param list for use in pj_apply_gridshift.c */

        projdef->datum_type = PJD_GRIDSHIFT;
    }

/* -------------------------------------------------------------------- */
/*      Check for grid catalog parameter, and optional date.            */
/* -------------------------------------------------------------------- */
    else if( (catalog = pj_param(ctx, pl,"scatalog").s) != NULL )
    {
        const char *date;

        projdef->datum_type = PJD_GRIDSHIFT;
        projdef->catalog_name = strdup(catalog);

        date = pj_param(ctx, pl, "sdate").s;
        if( date != NULL) 
            projdef->datum_date = pj_gc_parsedate( ctx, date);
    }

/* -------------------------------------------------------------------- */
/*      Check for towgs84 parameter.                                    */
/* -------------------------------------------------------------------- */
    else if( (towgs84 = pj_param(ctx, pl,"stowgs84").s) != NULL )
    {
        int    parm_count = 0;
        const char *s;

        memset( projdef->datum_params, 0, sizeof(double) * 7);

        /* parse out the parameters */
        s = towgs84;
        for( s = towgs84; *s != '\0' && parm_count < 7; ) 
        {
            projdef->datum_params[parm_count++] = atof(s);
            while( *s != '\0' && *s != ',' )
                s++;
            if( *s == ',' )
                s++;
        }

        if( projdef->datum_params[3] != 0.0 
            || projdef->datum_params[4] != 0.0 
            || projdef->datum_params[5] != 0.0 
            || projdef->datum_params[6] != 0.0 )
        {
            projdef->datum_type = PJD_7PARAM;

            /* transform from arc seconds to radians */
            projdef->datum_params[3] *= SEC_TO_RAD;
            projdef->datum_params[4] *= SEC_TO_RAD;
            projdef->datum_params[5] *= SEC_TO_RAD;
            /* transform from parts per million to scaling factor */
            projdef->datum_params[6] = 
                (projdef->datum_params[6]/1000000.0) + 1;
        }
        else 
            projdef->datum_type = PJD_3PARAM;

        /* Note that pj_init() will later switch datum_type to 
           PJD_WGS84 if shifts are all zero, and ellipsoid is WGS84 or GRS80 */
    }

    return 0;
}
Ejemplo n.º 9
0
PJ *
pj_init_ctx(projCtx ctx, int argc, char **argv) {
    char *s, *name;
    PJ_CONSTRUCTOR proj;
    paralist *curr, *init, *start;
    int i;
    int err;
    PJ *PIN = 0;
    int n_pipelines = 0;
    int n_inits = 0;

    if (0==ctx)
        ctx = pj_get_default_ctx ();

    ctx->last_errno = 0;

    if (argc <= 0) {
        pj_ctx_set_errno (ctx, PJD_ERR_NO_ARGS);
        return 0;
    }

    /* count occurrences of pipelines and inits */
    for (i = 0; i < argc; ++i) {
        if (!strcmp (argv[i], "+proj=pipeline") || !strcmp(argv[i], "proj=pipeline") )
                n_pipelines++;
        if (!strncmp (argv[i], "+init=", 6) || !strncmp(argv[i], "init=", 5))
            n_inits++;
    }

    /* can't have nested pipelines directly */
    if (n_pipelines > 1) {
        pj_ctx_set_errno (ctx, PJD_ERR_MALFORMED_PIPELINE);
        return 0;
    }

    /* don't allow more than one +init in non-pipeline operations */
    if (n_pipelines == 0 && n_inits > 1) {
        pj_ctx_set_errno (ctx, PJD_ERR_TOO_MANY_INITS);
        return 0;
    }


    /* put arguments into internal linked list */
    start = curr = pj_mkparam(argv[0]);
    if (!curr)
        return pj_dealloc_params (ctx, start, ENOMEM);

    for (i = 1; i < argc; ++i) {
        curr->next = pj_mkparam(argv[i]);
        if (!curr->next)
            return pj_dealloc_params (ctx, start, ENOMEM);
        curr = curr->next;
    }


    /* Only expand '+init's in non-pipeline operations. '+init's in pipelines are */
    /* expanded in the individual pipeline steps during pipeline initialization.  */
    /* Potentially this leads to many nested pipelines, which shouldn't be a      */
    /* problem when '+init's are expanded as late as possible.                    */
    init = pj_param_exists (start, "init");
    if (init && n_pipelines == 0) {
        init = pj_expand_init (ctx, init);
        if (!init)
            return pj_dealloc_params (ctx, start, PJD_ERR_NO_ARGS);
    }
    if (ctx->last_errno)
        return pj_dealloc_params (ctx, start, ctx->last_errno);

    /* Find projection selection */
    curr = pj_param_exists (start, "proj");
    if (0==curr)
        return pj_dealloc_params (ctx, start, PJD_ERR_PROJ_NOT_NAMED);
    name =  curr->param;
    if (strlen (name) < 6)
        return pj_dealloc_params (ctx, start, PJD_ERR_PROJ_NOT_NAMED);
    name += 5;

    proj = locate_constructor (name);
    if (0==proj)
        return pj_dealloc_params (ctx, start, PJD_ERR_UNKNOWN_PROJECTION_ID);


    /* Append general and projection specific defaults to the definition list */
    append_defaults_to_paralist (ctx, start, "general");
    append_defaults_to_paralist (ctx, start, name);


    /* Allocate projection structure */
    PIN = proj(0);
    if (0==PIN)
        return pj_dealloc_params (ctx, start, ENOMEM);


    PIN->ctx = ctx;
    PIN->params = start;
    PIN->is_latlong = 0;
    PIN->is_geocent = 0;
    PIN->is_long_wrap_set = 0;
    PIN->long_wrap_center = 0.0;
    strcpy( PIN->axis, "enu" );

    PIN->gridlist = NULL;
    PIN->gridlist_count = 0;

    PIN->vgridlist_geoid = NULL;
    PIN->vgridlist_geoid_count = 0;

    /* Set datum parameters. Similarly to +init parameters we want to expand    */
    /* +datum parameters as late as possible when dealing with pipelines.       */
    /* otherwise only the first occurrence of +datum will be expanded and that */
    if (n_pipelines == 0) {
        if (pj_datum_set(ctx, start, PIN))
            return pj_default_destructor (PIN, proj_errno(PIN));
    }

    err = pj_ellipsoid (PIN);

    if (err) {
        /* Didn't get an ellps, but doesn't need one: Get a free WGS84 */
        if (PIN->need_ellps) {
            pj_log (ctx, PJ_LOG_DEBUG_MINOR, "pj_init_ctx: Must specify ellipsoid or sphere");
            return pj_default_destructor (PIN, proj_errno(PIN));
        }
        else {
            if (PJD_ERR_MAJOR_AXIS_NOT_GIVEN==proj_errno (PIN))
                proj_errno_reset (PIN);
            PIN->f = 1.0/298.257223563;
            PIN->a_orig  = PIN->a  = 6378137.0;
            PIN->es_orig = PIN->es = PIN->f*(2-PIN->f);
        }
    }
    PIN->a_orig = PIN->a;
    PIN->es_orig = PIN->es;
    if (pj_calc_ellipsoid_params (PIN, PIN->a, PIN->es))
        return pj_default_destructor (PIN, PJD_ERR_ECCENTRICITY_IS_ONE);

    /* Now that we have ellipse information check for WGS84 datum */
    if( PIN->datum_type == PJD_3PARAM
        && PIN->datum_params[0] == 0.0
        && PIN->datum_params[1] == 0.0
        && PIN->datum_params[2] == 0.0
        && PIN->a == 6378137.0
        && ABS(PIN->es - 0.006694379990) < 0.000000000050 )/*WGS84/GRS80*/
    {
        PIN->datum_type = PJD_WGS84;
    }

    /* Set PIN->geoc coordinate system */
    PIN->geoc = (PIN->es != 0.0 && pj_param(ctx, start, "bgeoc").i);

    /* Over-ranging flag */
    PIN->over = pj_param(ctx, start, "bover").i;

    /* Vertical datum geoid grids */
    PIN->has_geoid_vgrids = pj_param(ctx, start, "tgeoidgrids").i;
    if( PIN->has_geoid_vgrids ) /* we need to mark it as used. */
        pj_param(ctx, start, "sgeoidgrids");

    /* Longitude center for wrapping */
    PIN->is_long_wrap_set = pj_param(ctx, start, "tlon_wrap").i;
    if (PIN->is_long_wrap_set) {
        PIN->long_wrap_center = pj_param(ctx, start, "rlon_wrap").f;
        /* Don't accept excessive values otherwise we might perform badly */
        /* when correcting longitudes around it */
        /* The test is written this way to error on long_wrap_center "=" NaN */
        if( !(fabs(PIN->long_wrap_center) < 10 * M_TWOPI) )
            return pj_default_destructor (PIN, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT);
    }

    /* Axis orientation */
    if( (pj_param(ctx, start,"saxis").s) != NULL )
    {
        const char *axis_legal = "ewnsud";
        const char *axis_arg = pj_param(ctx, start,"saxis").s;
        if( strlen(axis_arg) != 3 )
            return pj_default_destructor (PIN, PJD_ERR_AXIS);

        if( strchr( axis_legal, axis_arg[0] ) == NULL
            || strchr( axis_legal, axis_arg[1] ) == NULL
            || strchr( axis_legal, axis_arg[2] ) == NULL)
            return pj_default_destructor (PIN, PJD_ERR_AXIS);

        /* TODO: it would be nice to validate we don't have on axis repeated */
        strcpy( PIN->axis, axis_arg );
    }

    /* Central meridian */
    PIN->lam0=pj_param(ctx, start, "rlon_0").f;

    /* Central latitude */
    PIN->phi0 = pj_param(ctx, start, "rlat_0").f;

    /* False easting and northing */
    PIN->x0 = pj_param(ctx, start, "dx_0").f;
    PIN->y0 = pj_param(ctx, start, "dy_0").f;
    PIN->z0 = pj_param(ctx, start, "dz_0").f;
    PIN->t0 = pj_param(ctx, start, "dt_0").f;

    /* General scaling factor */
    if (pj_param(ctx, start, "tk_0").i)
        PIN->k0 = pj_param(ctx, start, "dk_0").f;
    else if (pj_param(ctx, start, "tk").i)
        PIN->k0 = pj_param(ctx, start, "dk").f;
    else
        PIN->k0 = 1.;
    if (PIN->k0 <= 0.)
        return pj_default_destructor (PIN, PJD_ERR_K_LESS_THAN_ZERO);

    /* Set units */
    s = 0;
    if ((name = pj_param(ctx, start, "sunits").s) != NULL) {
        for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i) ;
        if (!s)
            return pj_default_destructor (PIN, PJD_ERR_UNKNOWN_UNIT_ID);
        s = pj_units[i].to_meter;
    }
    if (s || (s = pj_param(ctx, start, "sto_meter").s)) {
        double factor;
        int ratio = 0;

        /* ratio number? */
        if (strlen (s) > 1 && s[0] == '1' && s[1]=='/') {
            ratio = 1;
            s += 2;
        }

        factor = pj_strtod(s, &s);
        if ((factor <= 0.0) || (1/factor==0))
            return pj_default_destructor (PIN, PJD_ERR_UNIT_FACTOR_LESS_THAN_0);

        PIN->to_meter = ratio?  1 / factor: factor;
        PIN->fr_meter = 1 / PIN->to_meter;

    } else
        PIN->to_meter = PIN->fr_meter = 1.;

    /* Set vertical units */
    s = 0;
    if ((name = pj_param(ctx, start, "svunits").s) != NULL) {
        for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i) ;
        if (!s)
            return pj_default_destructor (PIN, PJD_ERR_UNKNOWN_UNIT_ID);
        s = pj_units[i].to_meter;
    }
    if (s || (s = pj_param(ctx, start, "svto_meter").s)) {
        PIN->vto_meter = pj_strtod(s, &s);
        if (*s == '/') /* ratio number */
            PIN->vto_meter /= pj_strtod(++s, 0);
        if (PIN->vto_meter <= 0.0)
            return pj_default_destructor (PIN, PJD_ERR_UNIT_FACTOR_LESS_THAN_0);
        PIN->vfr_meter = 1. / PIN->vto_meter;
    } else {
        PIN->vto_meter = PIN->to_meter;
        PIN->vfr_meter = PIN->fr_meter;
    }

    /* Prime meridian */
    s = 0;
    if ((name = pj_param(ctx, start, "spm").s) != NULL) {
        const char *value = NULL;
        char *next_str = NULL;

        for (i = 0; pj_prime_meridians[i].id != NULL; ++i )
        {
            if( strcmp(name,pj_prime_meridians[i].id) == 0 )
            {
                value = pj_prime_meridians[i].defn;
                break;
            }
        }

        if( value == NULL
            && (dmstor_ctx(ctx,name,&next_str) != 0.0  || *name == '0')
            && *next_str == '\0' )
            value = name;

        if (!value)
            return pj_default_destructor (PIN, PJD_ERR_UNKNOWN_PRIME_MERIDIAN);
        PIN->from_greenwich = dmstor_ctx(ctx,value,NULL);
    }
    else
        PIN->from_greenwich = 0.0;

    /* Private object for the geodesic functions */
    PIN->geod = pj_calloc (1, sizeof (struct geod_geodesic));
    if (0==PIN->geod)
        return pj_default_destructor (PIN, ENOMEM);
    geod_init(PIN->geod, PIN->a,  (1 - sqrt (1 - PIN->es)));

    /* Projection specific initialization */
    err = proj_errno_reset (PIN);
    PIN = proj(PIN);
    if (proj_errno (PIN)) {
        pj_free(PIN);
        return 0;
    }
    proj_errno_restore (PIN, err);
    return PIN;
}
Ejemplo n.º 10
0
static paralist *append_defaults_to_paralist (PJ_CONTEXT *ctx, paralist *start, char *key) {
    paralist *defaults, *last = 0;
    char keystring[ID_TAG_MAX + 20];
    paralist *next, *proj;
    int err;

    if (0==start)
        return 0;

    if (strlen(key) > ID_TAG_MAX)
        return 0;

    /* Set defaults, unless inhibited (either explicitly through a "no_defs" token */
    /* or implicitly, because we are initializing a pipeline) */
    if (pj_param_exists (start, "no_defs"))
        return start;
    proj = pj_param_exists (start, "proj");
    if (0==proj)
        return start;
    if (strlen (proj->param) < 6)
        return start;
    if (0==strcmp ("pipeline", proj->param + 5))
        return start;

    err = pj_ctx_get_errno (ctx);
    pj_ctx_set_errno (ctx, 0);

    /* Locate end of start-list */
    for (last = start;  last->next;  last = last->next);

    strcpy (keystring, "proj_def.dat:");
    strcat (keystring, key);
    defaults = get_init (ctx, keystring);

    /* Defaults are optional - so we don't care if we cannot open the file */
    pj_ctx_set_errno (ctx, err);

    if (!defaults)
        return last;

    /* Loop over all default items */
    for (next = defaults;  next;  next = next->next) {

        /* Don't override existing parameter value of same name */
        if (pj_param_exists (start, next->param))
            continue;

        /* Don't default ellipse if datum, ellps or any ellipsoid information is set */
        if (0==strncmp(next->param,"ellps=", 6)) {
            if  (pj_param_exists (start, "datum"))  continue;
            if  (pj_param_exists (start, "ellps"))  continue;
            if  (pj_param_exists (start, "a"))      continue;
            if  (pj_param_exists (start, "b"))      continue;
            if  (pj_param_exists (start, "rf"))     continue;
            if  (pj_param_exists (start, "f"))      continue;
            if  (pj_param_exists (start, "e"))      continue;
            if  (pj_param_exists (start, "es"))     continue;
        }

        /* If we're here, it's OK to append the current default item */
        last = last->next = pj_mkparam(next->param);
    }
    last->next = 0;

    pj_dealloc_params (ctx, defaults, 0);
    return last;
}
Ejemplo n.º 11
0
void geod_set(int argc, char **argv)
{
    paralist *start = 0, *curr = NULL;	/* added NULL */
    double es;
    char *name;
    int i;

/*
 * put arguments into internal linked list 
 */
    if (argc <= 0)
	emess(1, "no arguments in initialization list");
    for (i = 0; i < argc; ++i)
	if (i)
	    curr = curr->next = pj_mkparam(argv[i]);
	else
	    start = curr = pj_mkparam(argv[i]);
/*
 * set elliptical parameters 
 */
    if (pj_ell_set(start, &geod_a, &es))
	emess(1, "ellipse setup failure");
/*
 * set units 
 */
    if ((name = pj_param(start, "sunits").s)) {	/* added parentheses */
	char *s;

	for (i = 0; (s = pj_units[i].id) && strcmp(name, s); ++i);
	if (!s)
	    emess(1, "%s unknown unit conversion id", name);
	fr_meter = 1. / (to_meter = atof(pj_units[i].to_meter));
    } else
	to_meter = fr_meter = 1.;
    if ((ellipse = es != 0.)) {	/* added parentheses */
	onef = sqrt(1. - es);
	geod_f = 1 - onef;
	f2 = geod_f / 2;
	f4 = geod_f / 4;
	f64 = geod_f * geod_f / 64;
    } else {
	onef = 1.;
	geod_f = f2 = f4 = f64 = 0.;
    }
/*
 * check if line or arc mode 
 */
    if (pj_param(start, "tlat_1").i) {
	double del_S;
#undef f
	phi1 = pj_param(start, "rlat_1").f;
	lam1 = pj_param(start, "rlon_1").f;
	if (pj_param(start, "tlat_2").i) {
	    phi2 = pj_param(start, "rlat_2").f;
	    lam2 = pj_param(start, "rlon_2").f;
	    geod_inv();
	    geod_pre();
	} else if ((geod_S = pj_param(start, "dS").f)) {	/* added
								 * parentheses 
								 */
	    al12 = pj_param(start, "rA").f;
	    geod_pre();
	    geod_for();
	} else
	    emess(1, "incomplete geodesic/arc info");
	if ((n_alpha = pj_param(start, "in_A").i) > 0) {
	    if (!(del_alpha = pj_param(start, "rdel_A").f))
		emess(1, "del azimuth == 0");
	} else if ((del_S = fabs(pj_param(start, "ddel_S").f))) {	/* added 
									 * parentheses 
									 */
	    n_S = geod_S / del_S + .5;
	} else if ((n_S = pj_param(start, "in_S").i) <= 0)
	    emess(1, "no interval divisor selected");
    }
/*
 * free up linked list 
 */
    for (; start; start = curr) {
	curr = start->next;
	pj_dalloc(start);
    }
}
Ejemplo n.º 12
0
PJ *
pj_init_ctx(projCtx ctx, int argc, char **argv) {
    char *s, *name;
    paralist *start = NULL;
    PJ *(*proj)(PJ *);
    paralist *curr;
    int i;
    PJ *PIN = 0;
    char *old_locale;

    ctx->last_errno = 0;
    start = NULL;

    old_locale = strdup(setlocale(LC_NUMERIC, NULL));
    if( strcmp(old_locale,"C") != 0 )
        setlocale(LC_NUMERIC,"C");

    /* put arguments into internal linked list */
    if (argc <= 0) { pj_ctx_set_errno( ctx, -1 ); goto bum_call; }
    for (i = 0; i < argc; ++i)
        if (i)
            curr = curr->next = pj_mkparam(argv[i]);
        else
            start = curr = pj_mkparam(argv[i]);
    if (ctx->last_errno) goto bum_call;

    /* check if +init present */
    if (pj_param(ctx, start, "tinit").i) {
        paralist *last = curr;

        if (!(curr = get_init(ctx,&start, curr, pj_param(ctx, start, "sinit").s)))
            goto bum_call;
        if (curr == last) { pj_ctx_set_errno( ctx, -2); goto bum_call; }
    }

    /* find projection selection */
    if (!(name = pj_param(ctx, start, "sproj").s))
    { pj_ctx_set_errno( ctx, -4 ); goto bum_call; }
    for (i = 0; (s = pj_list[i].id) && strcmp(name, s) ; ++i) ;
    if (!s) { pj_ctx_set_errno( ctx, -5 ); goto bum_call; }

    /* set defaults, unless inhibited */
    if (!pj_param(ctx, start, "bno_defs").i)
        curr = get_defaults(ctx,&start, curr, name);
    proj = (PJ *(*)(PJ *)) pj_list[i].proj;

    /* allocate projection structure */
    if (!(PIN = (*proj)(0))) goto bum_call;
    PIN->ctx = ctx;
    PIN->params = start;
    PIN->is_latlong = 0;
    PIN->is_geocent = 0;
    PIN->is_long_wrap_set = 0;
    PIN->long_wrap_center = 0.0;
    strcpy( PIN->axis, "enu" );

    PIN->gridlist = NULL;
    PIN->gridlist_count = 0;

    PIN->vgridlist_geoid = NULL;
    PIN->vgridlist_geoid_count = 0;

    /* set datum parameters */
    if (pj_datum_set(ctx, start, PIN)) goto bum_call;

    /* set ellipsoid/sphere parameters */
    if (pj_ell_set(ctx, start, &PIN->a, &PIN->es)) goto bum_call;

    PIN->a_orig = PIN->a;
    PIN->es_orig = PIN->es;

    PIN->e = sqrt(PIN->es);
    PIN->ra = 1. / PIN->a;
    PIN->one_es = 1. - PIN->es;
    if (PIN->one_es == 0.) { pj_ctx_set_errno( ctx, -6 ); goto bum_call; }
    PIN->rone_es = 1./PIN->one_es;

    /* Now that we have ellipse information check for WGS84 datum */
    if( PIN->datum_type == PJD_3PARAM 
        && PIN->datum_params[0] == 0.0
        && PIN->datum_params[1] == 0.0
        && PIN->datum_params[2] == 0.0
        && PIN->a == 6378137.0
        && ABS(PIN->es - 0.006694379990) < 0.000000000050 )/*WGS84/GRS80*/
    {
        PIN->datum_type = PJD_WGS84;
    }
        
    /* set PIN->geoc coordinate system */
    PIN->geoc = (PIN->es && pj_param(ctx, start, "bgeoc").i);

    /* over-ranging flag */
    PIN->over = pj_param(ctx, start, "bover").i;

    /* vertical datum geoid grids */
    PIN->has_geoid_vgrids = pj_param(ctx, start, "tgeoidgrids").i;
    if( PIN->has_geoid_vgrids ) /* we need to mark it as used. */
        pj_param(ctx, start, "sgeoidgrids");

    /* longitude center for wrapping */
    PIN->is_long_wrap_set = pj_param(ctx, start, "tlon_wrap").i;
    if (PIN->is_long_wrap_set)
        PIN->long_wrap_center = pj_param(ctx, start, "rlon_wrap").f;

    /* axis orientation */
    if( (pj_param(ctx, start,"saxis").s) != NULL )
    {
        static const char *axis_legal = "ewnsud";
        const char *axis_arg = pj_param(ctx, start,"saxis").s;
        if( strlen(axis_arg) != 3 )
        {
            pj_ctx_set_errno( ctx, PJD_ERR_AXIS );
            goto bum_call;
        }

        if( strchr( axis_legal, axis_arg[0] ) == NULL
            || strchr( axis_legal, axis_arg[1] ) == NULL
            || strchr( axis_legal, axis_arg[2] ) == NULL)
        {
            pj_ctx_set_errno( ctx, PJD_ERR_AXIS );
            goto bum_call;
        }

        /* it would be nice to validate we don't have on axis repeated */
        strcpy( PIN->axis, axis_arg );
    }

    PIN->is_long_wrap_set = pj_param(ctx, start, "tlon_wrap").i;
    if (PIN->is_long_wrap_set)
        PIN->long_wrap_center = pj_param(ctx, start, "rlon_wrap").f;

    /* central meridian */
    PIN->lam0=pj_param(ctx, start, "rlon_0").f;

    /* central latitude */
    PIN->phi0 = pj_param(ctx, start, "rlat_0").f;

    /* false easting and northing */
    PIN->x0 = pj_param(ctx, start, "dx_0").f;
    PIN->y0 = pj_param(ctx, start, "dy_0").f;

    /* general scaling factor */
    if (pj_param(ctx, start, "tk_0").i)
        PIN->k0 = pj_param(ctx, start, "dk_0").f;
    else if (pj_param(ctx, start, "tk").i)
        PIN->k0 = pj_param(ctx, start, "dk").f;
    else
        PIN->k0 = 1.;
    if (PIN->k0 <= 0.) {
        pj_ctx_set_errno( ctx, -31 );
        goto bum_call;
    }

    /* set units */
    s = 0;
    if ((name = pj_param(ctx, start, "sunits").s) != NULL) { 
        for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i) ;
        if (!s) { pj_ctx_set_errno( ctx, -7 ); goto bum_call; }
        s = pj_units[i].to_meter;
    }
    if (s || (s = pj_param(ctx, start, "sto_meter").s)) {
        PIN->to_meter = strtod(s, &s);
        if (*s == '/') /* ratio number */
            PIN->to_meter /= strtod(++s, 0);
        PIN->fr_meter = 1. / PIN->to_meter;
    } else
        PIN->to_meter = PIN->fr_meter = 1.;

    /* set vertical units */
    s = 0;
    if ((name = pj_param(ctx, start, "svunits").s) != NULL) { 
        for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i) ;
        if (!s) { pj_ctx_set_errno( ctx, -7 ); goto bum_call; }
        s = pj_units[i].to_meter;
    }
    if (s || (s = pj_param(ctx, start, "svto_meter").s)) {
        PIN->vto_meter = strtod(s, &s);
        if (*s == '/') /* ratio number */
            PIN->vto_meter /= strtod(++s, 0);
        PIN->vfr_meter = 1. / PIN->vto_meter;
    } else {
        PIN->vto_meter = PIN->to_meter;
        PIN->vfr_meter = PIN->fr_meter;
    }

    /* prime meridian */
    s = 0;
    if ((name = pj_param(ctx, start, "spm").s) != NULL) { 
        const char *value = NULL;
        char *next_str = NULL;

        for (i = 0; pj_prime_meridians[i].id != NULL; ++i )
        {
            if( strcmp(name,pj_prime_meridians[i].id) == 0 )
            {
                value = pj_prime_meridians[i].defn;
                break;
            }
        }
            
        if( value == NULL 
            && (dmstor_ctx(ctx,name,&next_str) != 0.0  || *name == '0')
            && *next_str == '\0' )
            value = name;

        if (!value) { pj_ctx_set_errno( ctx, -46 ); goto bum_call; }
        PIN->from_greenwich = dmstor_ctx(ctx,value,NULL);
    }
    else
        PIN->from_greenwich = 0.0;

    /* projection specific initialization */
    if (!(PIN = (*proj)(PIN)) || ctx->last_errno) {
      bum_call: /* cleanup error return */
        if (PIN)
            pj_free(PIN);
        else
            for ( ; start; start = curr) {
                curr = start->next;
                pj_dalloc(start);
            }
        PIN = 0;
    }

    if( strcmp(old_locale,"C") != 0 )
        setlocale(LC_NUMERIC,old_locale);
    free( (char*)old_locale );

    return PIN;
}
Ejemplo n.º 13
0
inline void pj_datum_set(std::vector<pvalue>& pvalues, parameters& projdef)
{
    std::string name, towgs84, nadgrids;

    projdef.datum_type = PJD_UNKNOWN;

    /* -------------------------------------------------------------------- */
    /*      Is there a datum definition in the parameter list?  If so,     */
    /*      add the defining values to the parameter list.  Note that       */
    /*      this will append the ellipse definition as well as the          */
    /*      towgs84= and related parameters.  It should also be pointed     */
    /*      out that the addition is permanent rather than temporary        */
    /*      like most other keyword expansion so that the ellipse           */
    /*      definition will last into the pj_ell_set() function called      */
    /*      after this one.                                                 */
    /* -------------------------------------------------------------------- */
    name = pj_param(pvalues, "sdatum").s;
    if(! name.empty())
    {
        /* find the datum definition */
        const int n = sizeof(pj_datums) / sizeof(pj_datums[0]);
        int index = -1;
        for (int i = 0; i < n && index == -1; i++)
        {
            if(pj_datums[i].id == name)
            {
                index = i;
            }
        }

        if (index == -1)
        {
            throw proj_exception(-9);
        }

        if(! pj_datums[index].ellipse_id.empty())
        {
            std::string entry("ellps=");
            entry +=pj_datums[index].ellipse_id;
            pvalues.push_back(pj_mkparam(entry));
        }

        if(! pj_datums[index].defn.empty())
        {
            pvalues.push_back(pj_mkparam(pj_datums[index].defn));
        }
    }

/* -------------------------------------------------------------------- */
/*      Check for nadgrids parameter.                                   */
/* -------------------------------------------------------------------- */
    nadgrids = pj_param(pvalues, "snadgrids").s;
    towgs84 = pj_param(pvalues, "stowgs84").s;
    if(! nadgrids.empty())
    {
        /* We don't actually save the value separately.  It will continue
           to exist int he param list for use in pj_apply_gridshift.c */

        projdef.datum_type = PJD_GRIDSHIFT;
    }

/* -------------------------------------------------------------------- */
/*      Check for towgs84 parameter.                                    */
/* -------------------------------------------------------------------- */
    else if(! towgs84.empty())
    {
        int parm_count = 0;

        int n = sizeof(projdef.datum_params) / sizeof(projdef.datum_params[0]);

        /* parse out the pvalues */
        std::vector<std::string> parm;
        boost::split(parm, towgs84, boost::is_any_of(" ,"));
        for (std::vector<std::string>::const_iterator it = parm.begin();
            it != parm.end() && parm_count < n;
            ++it)
        {
            projdef.datum_params[parm_count++] = atof(it->c_str());
        }

        if( projdef.datum_params[3] != 0.0
            || projdef.datum_params[4] != 0.0
            || projdef.datum_params[5] != 0.0
            || projdef.datum_params[6] != 0.0 )
        {
            projdef.datum_type = PJD_7PARAM;

            /* transform from arc seconds to radians */
            projdef.datum_params[3] *= SEC_TO_RAD;
            projdef.datum_params[4] *= SEC_TO_RAD;
            projdef.datum_params[5] *= SEC_TO_RAD;
            /* transform from parts per million to scaling factor */
            projdef.datum_params[6] =
                (projdef.datum_params[6]/1000000.0) + 1;
        }
        else
        {
            projdef.datum_type = PJD_3PARAM;
        }

        /* Note that pj_init() will later switch datum_type to
           PJD_WGS84 if shifts are all zero, and ellipsoid is WGS84 or GRS80 */
    }
}
Ejemplo n.º 14
0
GEODESIC_T *
GEOD_init(int argc, char **argv, GEODESIC_T *GEODESIC)
{
  paralist *start = 0, *curr = 0;
	double es;
	char *name;
	int i;


    if(0 == GEODESIC)
    {
       GEODESIC = malloc(sizeof(GEODESIC_T));
    }
    memset(GEODESIC, 0, sizeof(GEODESIC_T));

    /* put arguments into internal linked list */
	if (argc <= 0)
		emess(1, "no arguments in initialization list");
	for (i = 0; i < argc; ++i)
		if (i)
			curr = curr->next = pj_mkparam(argv[i]);
		else
			start = curr = pj_mkparam(argv[i]);
	/* set elliptical parameters */
	if (pj_ell_set(start, &GEODESIC->A, &es)) emess(1,"ellipse setup failure");
	/* set units */
	if ((name = pj_param(start, "sunits").s)) {
		char *s;
                struct PJ_UNITS *unit_list = pj_get_units_ref();
		for (i = 0; (s = unit_list[i].id) && strcmp(name, s) ; ++i) ;
		if (!s)
			emess(1,"%s unknown unit conversion id", name);
		GEODESIC->FR_METER = 1. / (GEODESIC->TO_METER = atof(unit_list[i].to_meter));
	} else
		GEODESIC->TO_METER = GEODESIC->FR_METER = 1.;
	if ((GEODESIC->ELLIPSE = (es != 0.))) {
		GEODESIC->ONEF = sqrt(1. - es);
		GEODESIC->FLAT = 1 - GEODESIC->ONEF;
		GEODESIC->FLAT2 = GEODESIC->FLAT/2;
		GEODESIC->FLAT4 = GEODESIC->FLAT/4;
		GEODESIC->FLAT64 = GEODESIC->FLAT*GEODESIC->FLAT/64;
	} else {
		GEODESIC->ONEF = 1.;
		GEODESIC->FLAT = GEODESIC->FLAT2 = GEODESIC->FLAT4 = GEODESIC->FLAT64 = 0.;
	}
	/* check if line or arc mode */
	if (pj_param(start, "tlat_1").i) {
		double del_S;
#undef f

    GEODESIC->p1.u = pj_param(start, "rlat_1").f;
		GEODESIC->p1.v = pj_param(start, "rlon_1").f;
		if (pj_param(start, "tlat_2").i) {
			GEODESIC->p2.u = pj_param(start, "rlat_2").f;
			GEODESIC->p2.v = pj_param(start, "rlon_2").f;
			geod_inv(GEODESIC);
			geod_pre(GEODESIC);
		} else if ((GEODESIC->DIST = pj_param(start, "dS").f)) {
			GEODESIC->ALPHA12 = pj_param(start, "rA").f;
			geod_pre(GEODESIC);
			geod_for(GEODESIC);
		} else emess(1,"incomplete geodesic/arc info");
		if ((GEODESIC->n_alpha = pj_param(start, "in_A").i) > 0) {
			if (!(GEODESIC->del_alpha = pj_param(start, "rdel_A").f))
				emess(1,"del azimuth == 0");
		} else if ((del_S = fabs(pj_param(start, "ddel_S").f))) {
			GEODESIC->n_S = GEODESIC->DIST / del_S + .5;
		} else if ((GEODESIC->n_S = pj_param(start, "in_S").i) <= 0)
			emess(1,"no interval divisor selected");
	}
	/* free up linked list */
	for ( ; start; start = curr) {
		curr = start->next;
		pj_dalloc(start);
	}
  return GEODESIC;
}