Exemple #1
0
PJ *proj_create_argv (PJ_CONTEXT *ctx, int argc, char **argv) {
/**************************************************************************************
Create a new PJ object in the context ctx, using the given definition argument
array argv. If ctx==0, the default context is used, if definition==0, or invalid,
a null-pointer is returned. The definition arguments may use '+' as argument start
indicator, as in {"+proj=utm", "+zone=32"}, or leave it out, as in {"proj=utm",
"zone=32"}.
**************************************************************************************/
    PJ *P;
    const char *c;

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

    /* We assume that free format is used, and build a full proj_create compatible string */
    c = pj_make_args (argc, argv);
    if (0==c)
        return 0;

    P = proj_create (ctx, c);

    pj_dealloc ((char *) c);
    return P;
}
Exemple #2
0
PJ  *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *srid_from, const char *srid_to, PJ_AREA *area) {
/******************************************************************************
    Create a transformation pipeline between two known coordinate reference
    systems.

    srid_from and srid_to should be the value part of a +init=... parameter
    set, i.e. "epsg:25833" or "IGNF:AMST63". Any projection definition that
    can be found in a init-file in PROJ_LIB is a valid input to this function.

    For now the function mimics the cs2cs app: An input and an output CRS is
    given and coordinates are transformed via a hub datum (WGS84). This
    transformation strategy is referred to as "early-binding" by the EPSG. The
    function can be extended to support "late-binding" transformations in the
    future without affecting users of the function.

    An "area of use" can be specified in area. In the current version of this
    function is has no function, but is added in anticipation of a
    "late-binding" implementation in the future. The idea being, that if a user
    supplies an area of use, the more accurate transformation between two given
    systems can be chosen.

    Example call:

        PJ *P = proj_create_crs_to_crs(0, "epsg:25832", "epsg:25833", NULL);

******************************************************************************/
    PJ *P;
    char buffer[512];
    size_t len;

    /* area not in use yet, suppressing warning */
    (void)area;

    strcpy(buffer, "+proj=pipeline +step +init=");
    len = strlen(buffer);
    strncat(buffer + len, srid_from, sizeof(buffer)-1-len);
    len += strlen(buffer + len);
    strncat(buffer + len, " +inv +step +init=", sizeof(buffer)-1-len);
    len += strlen(buffer + len);
    strncat(buffer + len, srid_to, sizeof(buffer)-1-len);

    P = proj_create(ctx, buffer);

    return P;
}
Exemple #3
0
GeoConvHelper::GeoConvHelper(const std::string& proj, const Position& offset,
                             const Boundary& orig, const Boundary& conv, double scale, double rot, bool inverse, bool flatten):
    myProjString(proj),
#ifdef PROJ_API_FILE
    myProjection(nullptr),
    myInverseProjection(nullptr),
    myGeoProjection(nullptr),
#endif
    myOffset(offset),
    myGeoScale(scale),
    mySin(sin(DEG2RAD(-rot))), // rotate clockwise
    myCos(cos(DEG2RAD(-rot))),
    myProjectionMethod(NONE),
    myUseInverseProjection(inverse),
    myFlatten(flatten),
    myOrigBoundary(orig),
    myConvBoundary(conv) {
    if (proj == "!") {
        myProjectionMethod = NONE;
    } else if (proj == "-") {
        myProjectionMethod = SIMPLE;
    } else if (proj == "UTM") {
        myProjectionMethod = UTM;
    } else if (proj == "DHDN") {
        myProjectionMethod = DHDN;
    } else if (proj == "DHDN_UTM") {
        myProjectionMethod = DHDN_UTM;
#ifdef PROJ_API_FILE
    } else {
        myProjectionMethod = PROJ;
#ifdef PROJ_VERSION_MAJOR
        myProjection = proj_create(PJ_DEFAULT_CTX, proj.c_str());
#else
        myProjection = pj_init_plus(proj.c_str());
#endif
        if (myProjection == nullptr) {
            // !!! check pj_errno
            throw ProcessError("Could not build projection!");
        }
#endif
    }
}
Exemple #4
0
static int operation (char *args) {
/*****************************************************************************
Define the operation to apply to the input data (in ISO 19100 lingo,
an operation is the general term describing something that can be
either a conversion or a transformation)
******************************************************************************/
    T.op_id++;

    T.operation_lineno = F->lineno;

    strncpy (&(T.operation[0]), F->args, MAX_OPERATION);
    T.operation[MAX_OPERATION] = '\0';

    if (T.verbosity > 1) {
        finish_previous_operation (F->args);
        banner (args);
    }


    T.op_ok = 0;
    T.op_ko = 0;
    T.op_skip = 0;
    T.skip_test = 0;

    direction ("forward");
    tolerance ("0.5 mm");
    ignore ("pjd_err_dont_skip");

    proj_errno_reset (T.P);

    if (T.P)
        proj_destroy (T.P);
    proj_errno_reset (nullptr);
    proj_context_use_proj4_init_rules(nullptr, T.use_proj4_init_rules);

    T.P = proj_create (nullptr, F->args);

    /* Checking that proj_create succeeds is first done at "expect" time, */
    /* since we want to support "expect"ing specific error codes */

    return 0;
}
Exemple #5
0
static int cs2cs_emulation_setup (PJ *P) {
/**************************************************************************************
If any cs2cs style modifiers are given (axis=..., towgs84=..., ) create the 4D API
equivalent operations, so the preparation and finalization steps in the pj_inv/pj_fwd
invocators can emulate the behaviour of pj_transform and the cs2cs app.

Returns 1 on success, 0 on failure
**************************************************************************************/
    PJ *Q;
    paralist *p;
    int do_cart = 0;
    if (0==P)
        return 0;

    /* Don't recurse when calling proj_create (which calls us back) */
    if (pj_param_exists (P->params, "break_cs2cs_recursion"))
        return 1;

    /* Swap axes? */
    p = pj_param_exists (P->params, "axis");

    /* Don't axisswap if data are already in "enu" order */
    if (p && (0!=strcmp ("enu", p->param))) {
        char *def = malloc (100+strlen(P->axis));
        if (0==def)
            return 0;
        sprintf (def, "break_cs2cs_recursion     proj=axisswap  axis=%s", P->axis);
        Q = proj_create (P->ctx, def);
        free (def);
        if (0==Q)
            return 0;
        P->axisswap = skip_prep_fin(Q);
    }

    /* Geoid grid(s) given? */
    p = pj_param_exists (P->params, "geoidgrids");
    if (p  &&  strlen (p->param) > strlen ("geoidgrids=")) {
        char *gridnames = p->param + strlen ("geoidgrids=");
        char *def = malloc (100+strlen(gridnames));
        if (0==def)
            return 0;
        sprintf (def, "break_cs2cs_recursion     proj=vgridshift  grids=%s", gridnames);
        Q = proj_create (P->ctx, def);
        free (def);
        if (0==Q)
            return 0;
        P->vgridshift = skip_prep_fin(Q);
    }

    /* Datum shift grid(s) given? */
    p = pj_param_exists (P->params, "nadgrids");
    if (p  &&  strlen (p->param) > strlen ("nadgrids=")) {
        char *gridnames = p->param + strlen ("nadgrids=");
        char *def = malloc (100+strlen(gridnames));
        if (0==def)
            return 0;
        sprintf (def, "break_cs2cs_recursion     proj=hgridshift  grids=%s", gridnames);
        Q = proj_create (P->ctx, def);
        free (def);
        if (0==Q)
            return 0;
        P->hgridshift = skip_prep_fin(Q);
    }

    /* We ignore helmert if we have grid shift */
    p = P->hgridshift ? 0 : pj_param_exists (P->params, "towgs84");
    while (p) {
        char *def;
        char *s = p->param;
        double *d = P->datum_params;
        size_t n = strlen (s);

        /* We ignore null helmert shifts (common in auto-translated resource files, e.g. epsg) */
        if (0==d[0] && 0==d[1] && 0==d[2] && 0==d[3] && 0==d[4] && 0==d[5] && 0==d[6]) {
            /* If the current ellipsoid is not WGS84, then make sure the */
            /* change in ellipsoid is still done. */
            if (!(fabs(P->a_orig - 6378137.0) < 1e-8 && fabs(P->es_orig - 0.0066943799901413) < 1e-15)) {
                do_cart = 1;
            }
            break;
        }

        if (n <= 8) /* 8==strlen ("towgs84=") */
            return 0;

        def = malloc (100+n);
        if (0==def)
            return 0;
        sprintf (def, "break_cs2cs_recursion     proj=helmert exact %s transpose", s);
        Q = proj_create (P->ctx, def);
        pj_inherit_ellipsoid_def (P, Q);
        free (def);
        if (0==Q)
            return 0;
        P->helmert = skip_prep_fin (Q);

        break;
    }

    /* We also need cartesian/geographical transformations if we are working in */
    /* geocentric/cartesian space or we need to do a Helmert transform.         */
    if (P->is_geocent || P->helmert || do_cart) {
        char def[150];
        sprintf (def, "break_cs2cs_recursion     proj=cart   a=%40.20g  es=%40.20g", P->a_orig, P->es_orig);
        Q = proj_create (P->ctx, def);
        if (0==Q)
            return 0;
        P->cart = skip_prep_fin (Q);

        sprintf (def, "break_cs2cs_recursion     proj=cart  ellps=WGS84");
        Q = proj_create (P->ctx, def);
        if (0==Q)
            return 0;
        P->cart_wgs84 = skip_prep_fin (Q);
    }

    return 1;
}
Exemple #6
0
bool
GeoConvHelper::x2cartesian(Position& from, bool includeInBoundary) {
    if (includeInBoundary) {
        myOrigBoundary.add(from);
    }
    // init projection parameter on first use
#ifdef PROJ_API_FILE
    if (myProjection == nullptr) {
        double x = from.x() * myGeoScale;
        switch (myProjectionMethod) {
            case DHDN_UTM: {
                int zone = (int)((x - 500000.) / 1000000.);
                if (zone < 1 || zone > 5) {
                    WRITE_WARNING("Attempt to initialize DHDN_UTM-projection on invalid longitude " + toString(x));
                    return false;
                }
                myProjString = "+proj=tmerc +lat_0=0 +lon_0=" + toString(3 * zone) +
                               " +k=1 +x_0=" + toString(zone * 1000000 + 500000) +
                               " +y_0=0 +ellps=bessel +datum=potsdam +units=m +no_defs";
#ifdef PROJ_VERSION_MAJOR
                myInverseProjection = proj_create(PJ_DEFAULT_CTX, myProjString.c_str());
                myGeoProjection = proj_create(PJ_DEFAULT_CTX, "+proj=latlong +datum=WGS84");
#else
                myInverseProjection = pj_init_plus(myProjString.c_str());
                myGeoProjection = pj_init_plus("+proj=latlong +datum=WGS84");
#endif
                //!!! check pj_errno
                x = ((x - 500000.) / 1000000.) * 3; // continues with UTM
            }
            FALLTHROUGH;
            case UTM: {
                int zone = (int)(x + 180) / 6 + 1;
                myProjString = "+proj=utm +zone=" + toString(zone) +
                               " +ellps=WGS84 +datum=WGS84 +units=m +no_defs";
#ifdef PROJ_VERSION_MAJOR
                myProjection = proj_create(PJ_DEFAULT_CTX, myProjString.c_str());
#else
                myProjection = pj_init_plus(myProjString.c_str());
#endif
                //!!! check pj_errno
            }
            break;
            case DHDN: {
                int zone = (int)(x / 3);
                if (zone < 1 || zone > 5) {
                    WRITE_WARNING("Attempt to initialize DHDN-projection on invalid longitude " + toString(x));
                    return false;
                }
                myProjString = "+proj=tmerc +lat_0=0 +lon_0=" + toString(3 * zone) +
                               " +k=1 +x_0=" + toString(zone * 1000000 + 500000) +
                               " +y_0=0 +ellps=bessel +datum=potsdam +units=m +no_defs";
#ifdef PROJ_VERSION_MAJOR
                myProjection = proj_create(PJ_DEFAULT_CTX, myProjString.c_str());
#else
                myProjection = pj_init_plus(myProjString.c_str());
#endif
                //!!! check pj_errno
            }
            break;
            default:
                break;
        }
    }
    if (myInverseProjection != nullptr) {
#ifdef PROJ_VERSION_MAJOR
        PJ_COORD c;
        c.xy.x = from.x();
        c.xy.y = from.y();
        c = proj_trans(myInverseProjection, PJ_INV, c);
        from.set(proj_todeg(c.lp.lam), proj_todeg(c.lp.phi));
#else
        double x = from.x();
        double y = from.y();
        if (pj_transform(myInverseProjection, myGeoProjection, 1, 1, &x, &y, nullptr)) {
            WRITE_WARNING("Could not transform (" + toString(x) + "," + toString(y) + ")");
        }
        from.set(double(x * RAD_TO_DEG), double(y * RAD_TO_DEG));
#endif
    }
#endif
    // perform conversion
    bool ok = x2cartesian_const(from);
    if (ok) {
        if (includeInBoundary) {
            myConvBoundary.add(from);
        }
    }
    return ok;
}
Exemple #7
0
GeoConvHelper&
GeoConvHelper::operator=(const GeoConvHelper& orig) {
    myProjString = orig.myProjString;
    myOffset = orig.myOffset;
    myProjectionMethod = orig.myProjectionMethod;
    myOrigBoundary = orig.myOrigBoundary;
    myConvBoundary = orig.myConvBoundary;
    myGeoScale = orig.myGeoScale;
    myCos = orig.myCos;
    mySin = orig.mySin;
    myUseInverseProjection = orig.myUseInverseProjection;
    myFlatten = orig.myFlatten;
#ifdef PROJ_API_FILE
    if (myProjection != nullptr) {
#ifdef PROJ_VERSION_MAJOR
        proj_destroy(myProjection);
#else
        pj_free(myProjection);
#endif
        myProjection = nullptr;
    }
    if (myInverseProjection != nullptr) {
#ifdef PROJ_VERSION_MAJOR
        proj_destroy(myInverseProjection);
#else
        pj_free(myInverseProjection);
#endif
        myInverseProjection = nullptr;
    }
    if (myGeoProjection != nullptr) {
#ifdef PROJ_VERSION_MAJOR
        proj_destroy(myGeoProjection);
#else
        pj_free(myGeoProjection);
#endif
        myGeoProjection = nullptr;
    }
    if (orig.myProjection != nullptr) {
#ifdef PROJ_VERSION_MAJOR
        myProjection = proj_create(PJ_DEFAULT_CTX, orig.myProjString.c_str());
#else
        myProjection = pj_init_plus(orig.myProjString.c_str());
#endif
    }
    if (orig.myInverseProjection != nullptr) {
#ifdef PROJ_VERSION_MAJOR
        myInverseProjection = orig.myInverseProjection;
#else
        myInverseProjection = pj_init_plus(pj_get_def(orig.myInverseProjection, 0));
#endif
    }
    if (orig.myGeoProjection != nullptr) {
#ifdef PROJ_VERSION_MAJOR
        myGeoProjection = orig.myGeoProjection;
#else
        myGeoProjection = pj_init_plus(pj_get_def(orig.myGeoProjection, 0));
#endif
    }
#endif
    return *this;
}