// reproject shape shape_t* shape_proj( const shape_t* shape, const char* from, const char* to ){ shape_t* projected = shape_copy(shape); projPJ old_prj = pj_init_plus(from); projPJ new_prj = pj_init_plus(to); for(uint32_t i=0; i<kv_size(projected->points); i++) { point_t* p = &kv_A(projected->points, i); p->x *= DEG_TO_RAD; p->y *= DEG_TO_RAD; int32_t err = pj_transform(old_prj, new_prj, 1, 0, &p->x, &p->y, NULL); if (err) fprintf(stderr, "ERR%d %s\n", err, pj_strerrno(err)); assert(err == 0); } for(uint32_t i=0; i<kv_size(projected->hull); i++) { point_t* p = &kv_A(projected->hull, i); p->x *= DEG_TO_RAD; p->y *= DEG_TO_RAD; int32_t err = pj_transform(old_prj, new_prj, 1, 0, &p->x, &p->y, NULL); if (err) fprintf(stderr, "ERR%d %s\n", err, pj_strerrno(err)); assert(err == 0); } pj_free(old_prj); pj_free(new_prj); return projected; }
static void set_zone(int in, struct IO_CON *io) { char tmp[20]; if (io->hp) { io->t83 = 1; if (!(htab = nad_init(io->hp))) emess(1,"hp datum file: %s, failed: %s", io->hp, pj_strerrno(pj_errno)); } if (io->zone > 0) { if (io->zone <= 60) { /* UTM zone */ io->nprojc = 2; /* no other options allowed */ io->projc[0] = "proj=utm"; sprintf(tmp, "zone=%d", io->zone); io->projc[1] = io->t83 ? "ellps=GRS80" : "ellps=clrk66"; } else /* SPCS zone */ sprintf(tmp, "init=nad%s:%d", io->t83 ? "83" : "27", io->zone); io->projc[io->nprojc++] = tmp; io->projc[io->nprojc++] = "no_defs"; if (!(io->cnv = pj_init(io->nprojc, io->projc))) emess(1,pj_strerrno(pj_errno)); io->ll = 0; } }
SEXP checkCRSArgs(SEXP args) { SEXP res; projPJ pj; PROTECT(res = NEW_LIST(2)); SET_VECTOR_ELT(res, 0, NEW_LOGICAL(1)); SET_VECTOR_ELT(res, 1, NEW_CHARACTER(1)); LOGICAL_POINTER(VECTOR_ELT(res, 0))[0] = FALSE; if (!(pj = pj_init_plus(CHAR(STRING_ELT(args, 0))))) { SET_STRING_ELT(VECTOR_ELT(res, 1), 0, COPY_TO_USER_STRING(pj_strerrno(*pj_get_errno_ref()))); UNPROTECT(1); return(res); } SET_STRING_ELT(VECTOR_ELT(res, 1), 0, COPY_TO_USER_STRING(pj_get_def(pj, 0))); LOGICAL_POINTER(VECTOR_ELT(res, 0))[0] = TRUE; UNPROTECT(1); return(res); }
JNIEXPORT jstring JNICALL Java_org_gvsig_crs_proj_JNIBaseCrs_strErrno (JNIEnv * env, jobject parent, jint errno) { int err = errno; char * strerr = pj_strerrno(err); return (*env)->NewStringUTF(env,strerr); }
static GhtErr l2g_coordinate_reproject(const Las2GhtState *state, GhtCoordinate *coord) { int *pj_errno_ref; GhtCoordinate origcoord; /* Make a copy of the input point so we can report the original should an error occur */ origcoord = *coord; if (pj_is_latlong(state->pj_input)) l2g_coordinate_to_rad(coord); /* Perform the transform */ pj_transform(state->pj_input, state->pj_output, 1, 0, &(coord->x), &(coord->y), NULL); /* For NAD grid-shift errors, display an error message with an additional hint */ pj_errno_ref = pj_get_errno_ref(); if (*pj_errno_ref != 0) { if (*pj_errno_ref == -38) { ght_warn("No no grid shift files were found, or point out of range."); } ght_error("%s: could not project point (%g %g): %s (%d)", __func__, origcoord.x, origcoord.y, pj_strerrno(*pj_errno_ref), *pj_errno_ref ); return GHT_ERROR; } if (pj_is_latlong(state->pj_output)) l2g_coordinate_to_dec(coord); return GHT_OK; }
Point SphericalInterpolator::project(const Point &lonlat) { Point xy; projLP dest; //std::cerr << "lon/lat: " << lonlat.x << ", " << lonlat.y; dest.u = lonlat.x * DEG_TO_RAD; dest.v = lonlat.y * DEG_TO_RAD; //std::cerr << " => " << dest.u << ", " << dest.v; int status = pj_transform(m_src_proj, m_dest_proj, 1, 1, &dest.u, &dest.v, NULL); if (status == -14 || status == -20) { // -14 => "latitude or longitude exceeded limits" // -20 => "tolerance condition error" dest.u = dest.v = HUGE_VAL; } else if (status != 0) { // TODO: Raise a Python exception instead std::cerr << "*******************" << std::endl; std::cerr << status << std::endl; std::cerr << pj_strerrno(status) << std::endl; exit(2); } //std::cerr << " -> " << dest.u << ", " << dest.v; xy.x = dest.u; xy.y = dest.v; //std::cerr << "xy: " << xy.x << ", " << xy.y << std::endl; return xy; }
Point CartesianInterpolator::project(const Point &src_xy) { Point dest_xy; projLP xy; xy.u = src_xy.x; xy.v = src_xy.y; int status = pj_transform(m_src_proj, m_dest_proj, 1, 1, &xy.u, &xy.v, NULL); if (status == -14 || status == -20) { // -14 => "latitude or longitude exceeded limits" // -20 => "tolerance condition error" xy.u = xy.v = HUGE_VAL; } else if (status != 0) { // TODO: Raise a Python exception instead std::cerr << "*******************" << std::endl; std::cerr << status << std::endl; std::cerr << pj_strerrno(status) << std::endl; exit(2); } dest_xy.x = xy.u; dest_xy.y = xy.v; return dest_xy; }
/** * Transform coordinates from one CRS into another. Wraps the same * function of the proj library. * * Coordinates have to be in radians and are produced in radians. * * @throws osmmium::projection_error if the projection fails */ inline Coordinates transform(const CRS& src, const CRS& dest, Coordinates c) { int result = pj_transform(src.get(), dest.get(), 1, 1, &c.x, &c.y, nullptr); if (result != 0) { throw osmium::projection_error(std::string("projection failed: ") + pj_strerrno(result)); } return c; }
void project_inv(int *n, double *x, double *y, double *xlon, double *ylat, char **projarg){ /* call the _inverse_ projection specified by the string projarg, * returning longitude and lat in xlon and ylat vectors, given the * numbers in x and y vectors (all vectors of length n) */ int i; projUV p; projPJ pj; if (!(pj = pj_init_plus(*projarg))) error(pj_strerrno(*pj_get_errno_ref())); /* Rprintf("%s\n", pj_get_def(pj, 0));*/ for(i=0;i<*n;i++){ if(ISNAN(x[i]) || ISNAN(y[i])){ xlon[i]=x[i]; ylat[i]=y[i]; } else { p.u=x[i]; p.v=y[i]; p = pj_inv(p, pj); if (p.u == HUGE_VAL || ISNAN(p.u)) { Rprintf("inverse projected point not finite\n"); } xlon[i]=p.u * RAD_TO_DEG; ylat[i]=p.v * RAD_TO_DEG; } } pj_free(pj); }
int S57_setMercPrj(double lat, double lon) { // From: http://trac.osgeo.org/proj/wiki/GenParms (and other link from that page) // Note: For merc, PROJ.4 does not support a latitude of natural origin other than the equator (lat_0=0). // Note: true scale using the +lat_ts parameter, which is the latitude at which the scale is 1. // Note: +lon_wrap=180.0 convert clamp [-180..180] to clamp [0..360] const char *templ = "+proj=merc +lat_ts=%.6f +lon_0=%.6f +ellps=WGS84 +datum=WGS84 +unit=m"; if (NULL != _pjstr) { PRINTF("WARNING: Merc projection allready set\n"); return FALSE; } _pjstr = g_strdup_printf(templ, lat, lon); PRINTF("DEBUG: lat:%f, lon:%f [%s]\n", lat, lon, _pjstr); if (NULL != _pjdst) pj_free(_pjdst); if (!(_pjdst = pj_init_plus(_pjstr))) { PRINTF("ERROR: init pjdst PROJ4 (lat:%f) [%s]\n", lat, pj_strerrno(pj_errno)); g_assert(0); return FALSE; } return TRUE; }
/** Returns the current error message. call-seq: Error.message(errno) */ static VALUE proj_error_message(VALUE self, VALUE rerrno) { int error_id = NUM2INT(rerrno); char *msg = pj_strerrno(error_id); if (msg) return rb_str_new2(msg); else return rb_str_new2("unknown error"); }
/** * Initialise a proj-based projector as specified in the given file (as *serialised by a proj-based projector. * * @param input_file The file which a proj-based projector has been serialised *to. * @return A pointer to an initialised projector. */ projector *get_proj_projector_from_file(FILE *input_file) { unsigned int projection_string_length; fread(&projection_string_length, sizeof(unsigned int), 1, input_file); // Check projection string length if (projection_string_length == 0) { fprintf(stderr, "Read a projection string length of 0\n"); exit(EXIT_FAILURE); } // Read the projection string char *projection_string = calloc(projection_string_length, sizeof(char)); if (projection_string == NULL) { fprintf(stderr, "Failed to allocate space (%d chars) for projection string\n", projection_string_length); exit(EXIT_FAILURE); } fread(projection_string, sizeof(char), projection_string_length, input_file); // Paranoid checks on projection string if (projection_string[projection_string_length-1] != '\0') { fprintf( stderr, "Corrupted string read from file (null terminator doesn't exist in "\ "expected position (%d), found %d)\n", projection_string_length, projection_string[projection_string_length - 1]); // Don't attempt to print out the projection string as we know it's // corrupt - very bad things may happen! exit(EXIT_FAILURE); } if (strlen(projection_string) != projection_string_length -1) { fprintf(stderr, "Corrupted string read from file (string length is wrong)\n"); // Don't attempt to print out the projection string as we know it's // corrupt - very bad things may happen! exit(EXIT_FAILURE); } // Initialize the projection projPJ *projection = pj_init_plus(projection_string); if (projection == NULL) { fprintf( stderr, "Couldn't initialise projection '%s' (Proj error message: '%s')\n", projection_string, pj_strerrno(*pj_get_errno_ref())); exit(EXIT_FAILURE); } projector *p = malloc(sizeof(projector)); p->internals = (void *)projection; p->project = &_proj_project; p->inverse_project = &_proj_inverse_project; p->serialize_to_file = &_proj_serialize_to_file; p->free = &_proj_free; return p; }
void GridGeometryTest::testGetGeometryHirlam10() { std::ostringstream exp; double x0 = 5.75 * DEG_TO_RAD; double y0 = -13.25 * DEG_TO_RAD; double x1 = (5.75+(247*0.1)) * DEG_TO_RAD; double y1 = -13.25 * DEG_TO_RAD; double x2 = (5.75+(247*0.1)) * DEG_TO_RAD; double y2 = (-13.25+(399*0.1)) * DEG_TO_RAD; double x3 = 5.75 * DEG_TO_RAD; double y3 = (-13.25+(399*0.1)) * DEG_TO_RAD; int error = pj_transform( hirlam10Proj, targetProj, 1, 0, &x0, &y0, NULL ); if ( error ) { std::ostringstream msg; msg << "Error during reprojection: " << pj_strerrno(error) << "."; CPPUNIT_FAIL( msg.str() ); } error = pj_transform( hirlam10Proj, targetProj, 1, 0, &x1, &y1, NULL ); if ( error ) { std::ostringstream msg; msg << "Error during reprojection: " << pj_strerrno(error) << "."; CPPUNIT_FAIL( msg.str() ); } error = pj_transform( hirlam10Proj, targetProj, 1, 0, &x2, &y2, NULL ); if ( error ) { std::ostringstream msg; msg << "Error during reprojection: " << pj_strerrno(error) << "."; CPPUNIT_FAIL( msg.str() ); } error = pj_transform( hirlam10Proj, targetProj, 1, 0, &x3, &y3, NULL ); if ( error ) { std::ostringstream msg; msg << "Error during reprojection: " << pj_strerrno(error) << "."; CPPUNIT_FAIL( msg.str() ); } exp << "POLYGON(("; exp << wdb::round(x0 * RAD_TO_DEG, 4) << " " << wdb::round (y0 * RAD_TO_DEG, 4) << ","; exp << wdb::round(x1 * RAD_TO_DEG, 4) << " " << wdb::round (y1 * RAD_TO_DEG, 4) << ","; exp << wdb::round(x2 * RAD_TO_DEG, 4) << " " << wdb::round (y2 * RAD_TO_DEG, 4) << ","; exp << wdb::round(x3 * RAD_TO_DEG, 4) << " " << wdb::round (y3 * RAD_TO_DEG, 4) << ","; exp << wdb::round(x0 * RAD_TO_DEG, 4) << " " << wdb::round (y0 * RAD_TO_DEG, 4) << "))"; const std::string expected = exp.str(); std::string geometry = grid->wktRepresentation(); CPPUNIT_ASSERT_EQUAL( expected, geometry); }
//----------------------------------------------------------------------------------------- void Projection_libproj::setProjection(int code) { const char *params[20]; int nbpar=0; switch (code) { case PROJ_UTM : nbpar = 0; params[nbpar++] = "proj=utm"; cylindrical = false; break; case PROJ_CENTRAL_CYL: nbpar = 0; params[nbpar++] = "proj=cc"; cylindrical = true; break; case PROJ_EQU_CYL: nbpar = 0; params[nbpar++] = "proj=eqc"; cylindrical = true; break; case PROJ_MILLER : // Miller nbpar = 0; params[nbpar++] = "proj=mill"; cylindrical = true; break; case PROJ_LAMBERT_CONF_CON : // Lambert Conformal Conic nbpar = 0; params[nbpar++] = "proj=lcc"; params[nbpar++] = "lat_1=80N"; params[nbpar++] = "lat_2=20N"; params[nbpar++] = "lon_0=0W"; cylindrical = false; break; case PROJ_MERCATOR : default : // Mercator nbpar = 0; params[nbpar++] = "proj=merc"; cylindrical = true; break; } params[nbpar++] = "ellps=WGS84"; params[nbpar++] = "no_defs"; params[nbpar++] = "over"; // allow longitude > 180° // XXX ouch pj_init libProj = pj_init(nbpar, (char **)params); if (!libProj) printf("proj error: %s\n", pj_strerrno(pj_errno)); assert(libProj); currentProj = code; // libProj->over = 1; // allow longitude > 180° //printf("Projection: %s\n", libProj->descr); }
// reproject shapes shapes_v shape_proj( const shapes_v* shapes, const char* from, const char* to){ projPJ old_prj = pj_init_plus(from); projPJ new_prj = pj_init_plus(to); shapes_v shapes_prj; kv_init(shapes_prj); shapes_prj.min = (point_t){ INFINITY, INFINITY}; shapes_prj.max = (point_t){-INFINITY,-INFINITY}; double k = 0.0; for(uint32_t s=0; s<shapes->n; s++) { shape_v* shape = &shapes->a[s]; shape_v shape_prj; kv_init(shape_prj); for(uint32_t p=0; p<shape->n; p++) { point_t pnt = shape->a[p]; pnt.x *= DEG_TO_RAD; pnt.y *= DEG_TO_RAD; int32_t err = pj_transform(old_prj, new_prj, 1, 0, &pnt.x, &pnt.y, NULL); if (err) { fprintf(stderr, "ERR%d %s\n", err, pj_strerrno(err)); continue; } // cumulitive average for center if(k>=1.0) { shapes_prj.center.x = (k-1.0)/k*shapes_prj.center.x + pnt.x/k; shapes_prj.center.y = (k-1.0)/k*shapes_prj.center.y + pnt.y/k; }else { shapes_prj.center.x = pnt.x; shapes_prj.center.y = pnt.y; } k+=1.0; // new bounds if(pnt.x>shapes_prj.max.x) shapes_prj.max.x = pnt.x; if(pnt.y>shapes_prj.max.y) shapes_prj.max.y = pnt.y; if(pnt.x<shapes_prj.min.x) shapes_prj.min.x = pnt.x; if(pnt.y<shapes_prj.min.y) shapes_prj.min.y = pnt.y; kv_push(point_t, shape_prj, pnt); } kv_push(shape_v, shapes_prj, shape_prj); } pj_free(old_prj); pj_free(new_prj); return shapes_prj; }
static int test_nad27_ll(double lat, double lon, double expected_lat, double expected_lon) { double lats[1]; double lons[1]; double hts[1]; char input_projection_info[255]; char output_projection_info[255]; projPJ input_projection, output_projection; sprintf(input_projection_info, "+proj=latlong +datum=NAD27"); sprintf(output_projection_info, "+proj=latlong +datum=NAD83"); input_projection = pj_init_plus(input_projection_info); output_projection = pj_init_plus(output_projection_info); lats[0] = lat * D2R; lons[0] = lon * D2R; hts[0] = 0; pj_transform (input_projection, output_projection, 1, 1, lats, lons, hts); if (pj_errno != 0) { asfPrintWarning("libproj error: %s\n", pj_strerrno(pj_errno)); } pj_free(input_projection); pj_free(output_projection); lats[0] *= R2D; lons[0] *= R2D; CU_ASSERT(double_equals(lats[0], expected_lat, 6)); CU_ASSERT(double_equals(lons[0], expected_lon, 6)); if (double_equals(lats[0], expected_lat, 6) && double_equals(lons[0], expected_lon, 6)) { //asfPrintStatus("Proj (fwd): %f, %f ... OK\n", lat, lon); return TRUE; } else { asfPrintStatus("Proj (fwd): %f, %f ... ERROR\n", lat, lon); asfPrintStatus("Result: %.10f %.10f (%.10f)\n", lats[0], lons[0], hts[0]); asfPrintStatus("Expected: %.10f %.10f\n", expected_lat, expected_lon); return FALSE; } }
int point4d_transform(POINT4D *pt, projPJ srcpj, projPJ dstpj) { int* pj_errno_ref; POINT4D orig_pt; /* Make a copy of the input point so we can report the original should an error occur */ orig_pt.x = pt->x; orig_pt.y = pt->y; orig_pt.z = pt->z; if (pj_is_latlong(srcpj)) to_rad(pt) ; LWDEBUGF(4, "transforming POINT(%f %f) from '%s' to '%s'", orig_pt.x, orig_pt.y, pj_get_def(srcpj,0), pj_get_def(dstpj,0)); /* Perform the transform */ pj_transform(srcpj, dstpj, 1, 0, &(pt->x), &(pt->y), &(pt->z)); /* For NAD grid-shift errors, display an error message with an additional hint */ pj_errno_ref = pj_get_errno_ref(); if (*pj_errno_ref != 0) { if (*pj_errno_ref == -38) { lwnotice("PostGIS was unable to transform the point because either no grid shift files were found, or the point does not lie within the range for which the grid shift is defined. Refer to the ST_Transform() section of the PostGIS manual for details on how to configure PostGIS to alter this behaviour."); lwerror("transform: couldn't project point (%g %g %g): %s (%d)", orig_pt.x, orig_pt.y, orig_pt.z, pj_strerrno(*pj_errno_ref), *pj_errno_ref); return 0; } else { lwerror("transform: couldn't project point (%g %g %g): %s (%d)", orig_pt.x, orig_pt.y, orig_pt.z, pj_strerrno(*pj_errno_ref), *pj_errno_ref); return 0; } } if (pj_is_latlong(dstpj)) to_dec(pt); return 1; }
static int list_err_codes (void) { int i; const int n = sizeof lookup / sizeof lookup[0]; for (i = 0; i < n; i++) { if (9999==lookup[i].the_errno) break; fprintf (T.fout, "%25s (%2.2d): %s\n", lookup[i].the_err_const + 8, lookup[i].the_errno, pj_strerrno(lookup[i].the_errno)); } return 0; }
void ProjectionPointTransformer::Transform(double *x, double *y, double *z) { if (pj_is_latlong(this->from)) { *x *= DEG_TO_RAD; *y *= DEG_TO_RAD; } int err = pj_transform(this->from, this->to, 1, 1, x, y, z); if (pj_is_latlong(this->to)) { *x *= RAD_TO_DEG; *y *= RAD_TO_DEG; } if (err != 0) { throw TransformerException(pj_strerrno(err)); } }
/** * Initialise a proj-based projector from a proj string. * * @param projection_string The proj compatible projection string. * @return A pointer to an initialised projector. */ projector *get_proj_projector_from_string(char *projection_string) { projPJ *projection = pj_init_plus(projection_string); if (projection == NULL) { fprintf( stderr, "Couldn't initialise projection '%s' (Proj error message: '%s')\n", projection_string, pj_strerrno(*pj_get_errno_ref())); return NULL; } projector *p = malloc(sizeof(projector)); p->internals = (void *)projection; p->project = &_proj_project; p->inverse_project = &_proj_inverse_project; p->serialize_to_file = &_proj_serialize_to_file; p->free = &_proj_free; return p; }
projXY S57_prj2geo(projUV uv) // convert PROJ to geographic (LL) { if (TRUE == _doInit) return uv; if (NULL == _pjdst) return uv; uv = pj_inv(uv, _pjdst); if (0 != pj_errno) { PRINTF("ERROR: x=%f y=%f %s\n", uv.u, uv.v, pj_strerrno(pj_errno)); g_assert(0); return uv; } uv.u /= DEG_TO_RAD; uv.v /= DEG_TO_RAD; return uv; }
int S57_geo2prj3dv(guint npt, double *data) // convert to XY 'in-place' { return_if_null(data); pt3 *pt = (pt3*)data; if (TRUE == _doInit) S57_initPROJ(); if (NULL == _pjdst) { PRINTF("ERROR: nothing to project to .. load a chart frist!\n"); // debug g_assert(0); return FALSE; } // deg to rad --latlon for (guint i=0; i<npt; ++i, ++pt) { pt->x *= DEG_TO_RAD, pt->y *= DEG_TO_RAD; // debug //if (-10.0 == pt->z) { // PRINTF("DEBUG: overlap found\n"); // //g_assert(0); //} } // reset to beginning pt = (pt3*)data; // rad to cartesian --mercator int ret = pj_transform(_pjsrc, _pjdst, npt, 3, &pt->x, &pt->y, &pt->z); if (0 != ret) { PRINTF("ERROR: in transform (%i): %s (%f,%f)\n", ret, pj_strerrno(pj_errno), pt->x, pt->y); g_assert(0); return FALSE; } return TRUE; }
static void setup() { /* check and set zone operations */ if (input.hp && output.hp) emess(1,"both input and output cannot be high precision"); set_zone(1, &input); set_zone(0, &output); if (input.cnv && !output.cnv) output.ll = 1; if (output.cnv && !input.cnv) input.ll = 1; if (!input.cnv && !output.cnv) output.ll = input.ll = 1; if (czone) { if (!input.hp && !output.hp && input.t83 == output.t83) emess(1,"identical datums"); if (!(ctab = nad_init(czone))) emess(1,"datum file: %s, failed: %s", czone, pj_strerrno(pj_errno)); } else if (input.t83 != output.t83) emess(1,"conversion region (-r) not specified"); }
Handle<Value> Projection::New(const Arguments& args) { Projection *proj; HandleScope scope; if (args.Length() == 1 && args[0]->IsString()) { String::Utf8Value init(args[0]->ToString()); proj = new Projection(*init); if (!proj->IsValid()) { int *errno = pj_get_errno_ref(); char *description = pj_strerrno(*errno); return ThrowException(String::New(description)); } } else { return ThrowException(String::New("No valid arguments passed for projection initialization string.")); } proj->Wrap(args.This()); return args.This(); }
/** * converts a point on earth to a projection plane * @param projStr projection definition for proj4 * @param lon longitude in degree * @param lat latitutde in degree * @param x output of proj (usually m, but dependent on projStr) * @param y output of proj * @throws runtime_error on proj-failure */ static void projConvert(const std::string& projStr, double lon, double lat, double& x, double& y) { projPJ outputPJ; if ( !(outputPJ = pj_init_plus(projStr.c_str())) ) { std::string errorMsg(pj_strerrno(pj_errno)); throw std::runtime_error("Proj error: " + errorMsg); } projUV uv; uv.u = lon * DEG_TO_RAD; uv.v = lat * DEG_TO_RAD; uv = pj_fwd(uv, outputPJ); pj_free(outputPJ); if (uv.u == HUGE_VAL) { std::ostringstream errMsg; errMsg << "projection fails:" << projStr << " (lon,lat)=(" << lon << "," << lat << ")"; throw std::runtime_error(errMsg.str()); } x = uv.u; y = uv.v; }
void project(int *n, double *xlon, double *ylat, double *x, double *y, char **projarg){ /* call the _forward_ projection specified by the string projarg, * using longitude and lat from xlon and ylat vectors, return * answers in x and y vectors (all vectors of length n) */ int i; projUV p; projPJ pj; if (!(pj = pj_init_plus(*projarg))) error(pj_strerrno(*pj_get_errno_ref())); /* Rprintf("%s\n", pj_get_def(pj, 0));*/ for (i=0; i<*n; i++) { /* preserve NAs and NaNs. Allow Infs, since maybe proj can handle them. */ if(ISNAN(xlon[i]) || ISNAN(ylat[i])){ x[i]=xlon[i]; y[i]=ylat[i]; } else { p.u=xlon[i]; p.v=ylat[i]; p.u *= DEG_TO_RAD; p.v *= DEG_TO_RAD; p = pj_fwd(p, pj); if (p.u == HUGE_VAL || ISNAN(p.u)) { Rprintf("projected point not finite\n"); } x[i]=p.u; y[i]=p.v; } } pj_free(pj); }
int main(int argc, char **argv) { char *arg, **eargv = argv, *from_argv[MAX_PARGS], *to_argv[MAX_PARGS], **iargv = argv; FILE *fid; int from_argc=0, to_argc=0, iargc = argc, eargc = 0, c, mon = 0; int have_to_flag = 0, inverse = 0, i; if (emess_dat.Prog_name = strrchr(*argv,DIR_CHAR)) ++emess_dat.Prog_name; else emess_dat.Prog_name = *argv; inverse = ! strncmp(emess_dat.Prog_name, "inv", 3); if (argc <= 1 ) { (void)fprintf(stderr, usage, pj_get_release(), emess_dat.Prog_name); exit (0); } /* process run line arguments */ while (--argc > 0) { /* collect run line arguments */ if(**++argv == '-') for(arg = *argv;;) { switch(*++arg) { case '\0': /* position of "stdin" */ if (arg[-1] == '-') eargv[eargc++] = "-"; break; case 'v': /* monitor dump of initialization */ mon = 1; continue; case 'I': /* alt. method to spec inverse */ inverse = 1; continue; case 'E': /* echo ascii input to ascii output */ echoin = 1; continue; case 't': /* set col. one char */ if (arg[1]) tag = *++arg; else emess(1,"missing -t col. 1 tag"); continue; case 'l': /* list projections, ellipses or units */ if (!arg[1] || arg[1] == 'p' || arg[1] == 'P') { /* list projections */ struct PJ_LIST *lp; int do_long = arg[1] == 'P', c; char *str; for (lp = pj_get_list_ref() ; lp->id ; ++lp) { (void)printf("%s : ", lp->id); if (do_long) /* possibly multiline description */ (void)puts(*lp->descr); else { /* first line, only */ str = *lp->descr; while ((c = *str++) && c != '\n') putchar(c); putchar('\n'); } } } else if (arg[1] == '=') { /* list projection 'descr' */ struct PJ_LIST *lp; arg += 2; for (lp = pj_get_list_ref() ; lp->id ; ++lp) if (!strcmp(lp->id, arg)) { (void)printf("%9s : %s\n", lp->id, *lp->descr); break; } } else if (arg[1] == 'e') { /* list ellipses */ struct PJ_ELLPS *le; for (le = pj_get_ellps_ref(); le->id ; ++le) (void)printf("%9s %-16s %-16s %s\n", le->id, le->major, le->ell, le->name); } else if (arg[1] == 'u') { /* list units */ struct PJ_UNITS *lu; for (lu = pj_get_units_ref(); lu->id ; ++lu) (void)printf("%12s %-20s %s\n", lu->id, lu->to_meter, lu->name); } else if (arg[1] == 'd') { /* list datums */ struct PJ_DATUMS *ld; printf("__datum_id__ __ellipse___ __definition/comments______________________________\n" ); for (ld = pj_get_datums_ref(); ld->id ; ++ld) { printf("%12s %-12s %-30s\n", ld->id, ld->ellipse_id, ld->defn); if( ld->comments != NULL && strlen(ld->comments) > 0 ) printf( "%25s %s\n", " ", ld->comments ); } } else if( arg[1] == 'm') { /* list prime meridians */ struct PJ_PRIME_MERIDIANS *lpm; for (lpm = pj_get_prime_meridians_ref(); lpm->id ; ++lpm) (void)printf("%12s %-30s\n", lpm->id, lpm->defn); } else emess(1,"invalid list option: l%c",arg[1]); exit(0); continue; /* artificial */ case 'e': /* error line alternative */ if (--argc <= 0) noargument: emess(1,"missing argument for -%c",*arg); oterr = *++argv; continue; case 'W': /* specify seconds precision */ case 'w': /* -W for constant field width */ if ((c = arg[1]) != 0 && isdigit(c)) { set_rtodms(c - '0', *arg == 'W'); ++arg; } else emess(1,"-W argument missing or non-digit"); continue; case 'f': /* alternate output format degrees or xy */ if (--argc <= 0) goto noargument; oform = *++argv; continue; case 'r': /* reverse input */ reversein = 1; continue; case 's': /* reverse output */ reverseout = 1; continue; default: emess(1, "invalid option: -%c",*arg); break; } break; } else if (strcmp(*argv,"+to") == 0 ) { have_to_flag = 1; } else if (**argv == '+') { /* + argument */ if( have_to_flag ) { if( to_argc < MAX_PARGS ) to_argv[to_argc++] = *argv + 1; else emess(1,"overflowed + argument table"); } else { if (from_argc < MAX_PARGS) from_argv[from_argc++] = *argv + 1; else emess(1,"overflowed + argument table"); } } else /* assumed to be input file name(s) */ eargv[eargc++] = *argv; } if (eargc == 0 ) /* if no specific files force sysin */ eargv[eargc++] = "-"; /* * If the user has requested inverse, then just reverse the * coordinate systems. */ if( inverse ) { int argcount; for( i = 0; i < MAX_PARGS; i++ ) { char *arg; arg = from_argv[i]; from_argv[i] = to_argv[i]; to_argv[i] = arg; } argcount = from_argc; from_argc = to_argc; to_argc = argcount; } if (!(fromProj = pj_init(from_argc, from_argv))) { printf( "Using from definition: " ); for( i = 0; i < from_argc; i++ ) printf( "%s ", from_argv[i] ); printf( "\n" ); emess(3,"projection initialization failure\ncause: %s", pj_strerrno(pj_errno)); } if( to_argc == 0 ) { if (!(toProj = pj_latlong_from_proj( fromProj ))) { printf( "Using to definition: " ); for( i = 0; i < to_argc; i++ ) printf( "%s ", to_argv[i] ); printf( "\n" ); emess(3,"projection initialization failure\ncause: %s", pj_strerrno(pj_errno)); } } else if (!(toProj = pj_init(to_argc, to_argv))) { printf( "Using to definition: " ); for( i = 0; i < to_argc; i++ ) printf( "%s ", to_argv[i] ); printf( "\n" ); emess(3,"projection initialization failure\ncause: %s", pj_strerrno(pj_errno)); } if (mon) { printf( "%c ---- From Coordinate System ----\n", tag ); pj_pr_list(fromProj); printf( "%c ---- To Coordinate System ----\n", tag ); pj_pr_list(toProj); } /* set input formating control */ if( !fromProj->is_latlong ) informat = strtod; else { informat = dmstor; } if( !toProj->is_latlong && !oform ) oform = "%.2f"; /* process input file list */ for ( ; eargc-- ; ++eargv) { if (**eargv == '-') { fid = stdin; emess_dat.File_name = "<stdin>"; } else { if ((fid = fopen(*eargv, "rt")) == NULL) { emess(-2, *eargv, "input file"); continue; } emess_dat.File_name = *eargv; } emess_dat.File_line = 0; process(fid); fclose(fid); emess_dat.File_name = 0; } if( fromProj != NULL ) pj_free( fromProj ); if( toProj != NULL ) pj_free( toProj ); pj_deallocate_grids(); exit(0); /* normal completion */ }
CRS(const std::string& crs) : m_crs(pj_init_plus(crs.c_str()), ProjCRSDeleter()) { if (!m_crs) { throw osmium::projection_error(std::string("creation of CRS failed: ") + pj_strerrno(*pj_get_errno_ref())); } }
void QgsCoordinateTransform::transformCoords( const int& numPoints, double *x, double *y, double *z, TransformDirection direction ) const { // Refuse to transform the points if the srs's are invalid if ( !mSourceCRS.isValid() ) { QgsMessageLog::logMessage( tr( "The source spatial reference system (CRS) is not valid. " "The coordinates can not be reprojected. The CRS is: %1" ) .arg( mSourceCRS.toProj4() ), tr( "CRS" ) ); return; } if ( !mDestCRS.isValid() ) { QgsMessageLog::logMessage( tr( "The destination spatial reference system (CRS) is not valid. " "The coordinates can not be reprojected. The CRS is: %1" ).arg( mDestCRS.toProj4() ), tr( "CRS" ) ); return; } #ifdef COORDINATE_TRANSFORM_VERBOSE double xorg = *x; double yorg = *y; QgsDebugMsg( QString( "[[[[[[ Number of points to transform: %1 ]]]]]]" ).arg( numPoints ) ); #endif // use proj4 to do the transform QString dir; // if the source/destination projection is lat/long, convert the points to radians // prior to transforming if (( pj_is_latlong( mDestinationProjection ) && ( direction == ReverseTransform ) ) || ( pj_is_latlong( mSourceProjection ) && ( direction == ForwardTransform ) ) ) { for ( int i = 0; i < numPoints; ++i ) { x[i] *= DEG_TO_RAD; y[i] *= DEG_TO_RAD; z[i] *= DEG_TO_RAD; } } int projResult; if ( direction == ReverseTransform ) { projResult = pj_transform( mDestinationProjection, mSourceProjection, numPoints, 0, x, y, z ); } else { Q_ASSERT( mSourceProjection != 0 ); Q_ASSERT( mDestinationProjection != 0 ); projResult = pj_transform( mSourceProjection, mDestinationProjection, numPoints, 0, x, y, z ); } if ( projResult != 0 ) { //something bad happened.... QString points; for ( int i = 0; i < numPoints; ++i ) { if ( direction == ForwardTransform ) { points += QString( "(%1, %2)\n" ).arg( x[i], 0, 'f' ).arg( y[i], 0, 'f' ); } else { points += QString( "(%1, %2)\n" ).arg( x[i] * RAD_TO_DEG, 0, 'f' ).arg( y[i] * RAD_TO_DEG, 0, 'f' ); } } dir = ( direction == ForwardTransform ) ? tr( "forward transform" ) : tr( "inverse transform" ); QString msg = tr( "%1 of\n" "%2" "PROJ.4: %3 +to %4\n" "Error: %5" ) .arg( dir ) .arg( points ) .arg( mSourceCRS.toProj4() ).arg( mDestCRS.toProj4() ) .arg( QString::fromUtf8( pj_strerrno( projResult ) ) ); QgsDebugMsg( "Projection failed emitting invalid transform signal: " + msg ); emit invalidTransformInput(); QgsDebugMsg( "throwing exception" ); throw QgsCsException( msg ); } // if the result is lat/long, convert the results from radians back // to degrees if (( pj_is_latlong( mDestinationProjection ) && ( direction == ForwardTransform ) ) || ( pj_is_latlong( mSourceProjection ) && ( direction == ReverseTransform ) ) ) { for ( int i = 0; i < numPoints; ++i ) { x[i] *= RAD_TO_DEG; y[i] *= RAD_TO_DEG; z[i] *= RAD_TO_DEG; } } #ifdef COORDINATE_TRANSFORM_VERBOSE QgsDebugMsg( QString( "[[[[[[ Projected %1, %2 to %3, %4 ]]]]]]" ) .arg( xorg, 0, 'g', 15 ).arg( yorg, 0, 'g', 15 ) .arg( *x, 0, 'g', 15 ).arg( *y, 0, 'g', 15 ) ); #endif }
static void test_proj_direct(const char *input_projection_info, const char *proj_name, double projX, double projY, double height, double expected_lat, double expected_lon, const char *datum) { double x[1]; double y[1]; double hts[1]; char output_projection_info[255]; sprintf(output_projection_info, "+proj=latlong +datum=WGS84"); projPJ input_projection, output_projection; input_projection = pj_init_plus(input_projection_info); output_projection = pj_init_plus(output_projection_info); y[0] = projX; x[0] = projY; hts[0] = height; pj_transform (input_projection, output_projection, 1, 1, x, y, hts); if (pj_errno != 0) { asfPrintWarning("libproj error: %s\n", pj_strerrno(pj_errno)); } x[0] *= R2D; y[0] *= R2D; CU_ASSERT(double_equals(x[0], expected_lat, 6)); CU_ASSERT(double_equals(y[0], expected_lon, 6)); if (double_equals(x[0], expected_lat, 6) && double_equals(y[0], expected_lon, 6)) { //asfPrintStatus("%s %s (fwd): %f, %f ... OK\n", // proj_name, datum, projX, projY); ++n_ok; } else { asfPrintStatus("%s (fwd): %s %f, %f ... ERROR\n", proj_name, datum, projX, projY); asfPrintStatus("Result: %.10f %.10f (%.10f)\n", x[0], y[0], hts[0]); asfPrintStatus("Expected: %.10f %.10f\n", expected_lat, expected_lon); ++n_bad; } // now project the other way y[0] = expected_lon*D2R; x[0] = expected_lat*D2R; hts[0] = height; pj_transform(output_projection, input_projection, 1, 1, x, y, hts); if (pj_errno != 0) { asfPrintWarning("libproj error: %s\n", pj_strerrno(pj_errno)); } pj_free(input_projection); pj_free(output_projection); CU_ASSERT(double_equals(y[0], projX, 5)); CU_ASSERT(double_equals(x[0], projY, 5)); if (double_equals(y[0], projX, 5) && double_equals(x[0], projY, 5)) { //asfPrintStatus("%s %s (rev): %f, %f ... OK\n", // proj_name, datum, expected_lon, expected_lat); ++n_ok; } else { asfPrintStatus("%s (rev): %s %f, %f ... ERROR\n", proj_name, datum, expected_lon, expected_lat); asfPrintStatus("Result: %.10f %.10f (%.10f)\n", y[0], x[0], hts[0]); asfPrintStatus("Expected: %.10f %.10f\n", projX, projY); ++n_bad; } }