void projection::forward(double & x, double &y ) const { #ifdef MAPNIK_USE_PROJ4 if (!proj_) { throw std::runtime_error("projection::forward not supported unless proj4 is initialized"); } #if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480 mapnik::scoped_lock lock(mutex_); #endif projUV p; p.u = x * DEG_TO_RAD; p.v = y * DEG_TO_RAD; p = pj_fwd(p,proj_); x = p.u; y = p.v; if (is_geographic_) { x *=RAD_TO_DEG; y *=RAD_TO_DEG; } #else throw std::runtime_error("projection::forward not supported without proj4 support (-DMAPNIK_USE_PROJ4)"); #endif }
bool GeoConvHelper::x2cartesian_const(Position& from) const { double x2 = from.x() * myGeoScale; double y2 = from.y() * myGeoScale; double x = x2 * myCos - y2 * mySin; double y = x2 * mySin + y2 * myCos; if (myProjectionMethod == NONE) { from.add(myOffset); } else if (myUseInverseProjection) { cartesian2geo(from); } else { if (x > 180.1 || x < -180.1) { WRITE_WARNING("Invalid longitude " + toString(x)); return false; } if (y > 90.1 || y < -90.1) { WRITE_WARNING("Invalid latitude " + toString(y)); return false; } #ifdef PROJ_API_FILE if (myProjection != nullptr) { #ifdef PROJ_VERSION_MAJOR PJ_COORD c; c.lp.lam = proj_torad(x); c.lp.phi = proj_torad(y); c = proj_trans(myProjection, PJ_FWD, c); //!!! check pj_errno x = c.xy.x; y = c.xy.y; #else projUV p; p.u = x * DEG_TO_RAD; p.v = y * DEG_TO_RAD; p = pj_fwd(p, myProjection); //!!! check pj_errno x = p.u; y = p.v; #endif } #endif if (myProjectionMethod == SIMPLE) { x *= 111320. * cos(DEG2RAD(y)); y *= 111136.; //!!! recheck whether the axes are mirrored } } if (x > std::numeric_limits<double>::max() || y > std::numeric_limits<double>::max()) { return false; } from.set(x, y); from.add(myOffset); if (myFlatten) { from.setz(0); } return true; }
/*--------------------------------------------------------------------*/ int mb_proj_forward(int verbose, void *pjptr, double lon, double lat, double *easting, double *northing, int *error) { char *function_name = "mb_proj_forward"; int status = MB_SUCCESS; projPJ pj; projUV pjxy; projUV pjll; /* print input debug statements */ if (verbose >= 2) { fprintf(stderr,"\ndbg2 MBIO function <%s> called\n",function_name); fprintf(stderr,"dbg2 Revision id: %s\n",rcs_id); fprintf(stderr,"dbg2 Input arguments:\n"); fprintf(stderr,"dbg2 verbose: %d\n",verbose); fprintf(stderr,"dbg2 pjptr: %p\n",(void *)pjptr); fprintf(stderr,"dbg2 lon: %f\n",lon); fprintf(stderr,"dbg2 lat: %f\n",lat); } /* do forward projection */ if (pjptr != NULL) { pj = (projPJ) pjptr; pjll.u = DTR * lon; pjll.v = DTR * lat; pjxy = pj_fwd(pjll, pj); *easting = pjxy.u; *northing = pjxy.v; } /* assume success */ *error = MB_ERROR_NO_ERROR; status = MB_SUCCESS; /* print output debug statements */ if (verbose >= 2) { fprintf(stderr,"\ndbg2 MBIO function <%s> completed\n",function_name); fprintf(stderr,"dbg2 Revision id: %s\n",rcs_id); fprintf(stderr,"dbg2 Return values:\n"); fprintf(stderr,"dbg2 easting: %f\n",*easting); fprintf(stderr,"dbg2 northing: %f\n",*northing); fprintf(stderr,"dbg2 error: %d\n",*error); fprintf(stderr,"dbg2 Return status:\n"); fprintf(stderr,"dbg2 status: %d\n",status); } /* return status */ return(status); }
inline bool forward(const LL& lp, XY& xy) const { try { pj_fwd(m_prj, m_par, lp, xy); return true; } catch(...) { return false; } }
int GTIFProj4FromLatLong( GTIFDefn * psDefn, int nPoints, double *padfX, double *padfY ) { char *pszProjection, **papszArgs; PJ *psPJ; int i; /* -------------------------------------------------------------------- */ /* Get a projection definition. */ /* -------------------------------------------------------------------- */ pszProjection = GTIFGetProj4Defn( psDefn ); if( pszProjection == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Parse into tokens for pj_init(), and initialize the projection. */ /* -------------------------------------------------------------------- */ papszArgs = CSLTokenizeStringComplex( pszProjection, " +", TRUE, FALSE ); free( pszProjection ); psPJ = pj_init( CSLCount(papszArgs), papszArgs ); CSLDestroy( papszArgs ); if( psPJ == NULL ) { return FALSE; } /* -------------------------------------------------------------------- */ /* Process each of the points. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nPoints; i++ ) { UV sUV; sUV.u = padfX[i] * DEG_TO_RAD; sUV.v = padfY[i] * DEG_TO_RAD; sUV = pj_fwd( sUV, psPJ ); padfX[i] = sUV.u; padfY[i] = sUV.v; } pj_free( psPJ ); return TRUE; }
projUV* c_pj_fwd_ptr(projUV *val, projPJ proj) { projUV res; # ifdef _DEBUG printf("Entered c_pj_fwd_ptr(proj=%p), *val={u=%g, v=%g}.\n", proj, val->u, val->v); # endif res = pj_fwd(*val, proj); val->u = res.u; val->v = res.v; return val; }
static void projection_transform (GfsMap * map, const FttVector * src, FttVector * dest) { projLP idata; projXY odata; GfsMapProjection * m = GFS_MAP_PROJECTION (map); gdouble L = gfs_object_simulation (map)->physical_params.L; idata.u = src->x*L*DEG_TO_RAD; idata.v = src->y*L*DEG_TO_RAD; odata = pj_fwd (idata, m->pj); dest->x = (odata.u*m->cosa - odata.v*m->sina)/L; dest->y = (odata.v*m->cosa + odata.u*m->sina)/L; dest->z = src->z; }
/* * === FUNCTION ====================================================================== * Name: project * Description: project from geographical coordinates to the projected ones(tmerc) * I use projPJ here because the init operation is time-consuming * ===================================================================================== */ Point project ( projPJ pj, double lon, double lat ) { Point res; projUV p; p.u = lon * DEG_TO_RAD; p.v = lat * DEG_TO_RAD; p = pj_fwd(p,pj); res.x = p.u; res.y = p.v; return res; } /* ----- end of function project ----- */
//Goes from WGS84 LatLon to projected coordinates static VALUE proj_forward(VALUE self,VALUE uv){ _wrap_pj* wpj; projUV* c_uv; projUV* pResult; Data_Get_Struct(self,_wrap_pj,wpj); Data_Get_Struct(uv,projUV,c_uv); pResult = (projUV*) malloc(sizeof(projUV)); pResult->u = c_uv->u * DEG_TO_RAD; pResult->v = c_uv->v * DEG_TO_RAD; //Pass a pResult equal to uv in Rad as entry to the forward procedure *pResult = pj_fwd(*pResult,wpj->pj); return Data_Wrap_Struct(cUV,0,uv_free,pResult); }
projUV c_pj_fwd (/* int64_t* restrict baseReg, int64_t* restrict sp, int64_t* restrict hp, */ double u, double v, projPJ proj) { projUV val; # ifdef _DEBUG printf("Entered c_pj_fwd(u=%g, v=%g, proj=%p).\n", u, v, proj); # endif val.u = u; val.v = v; val = pj_fwd(val, proj); return val; }
//------------------------------------------------------------------------------- void Projection_libproj::map2screen(double x, double y, int *i, int *j) const { projUV data, res; if (y <= -90.0) y = -90.0+1e-5; if (y >= 90.0) y = 90.0-1e-5; data.v = y * DEG_TO_RAD; data.u = x * DEG_TO_RAD; res = pj_fwd(data, libProj); *i = (int) (W/2.0 + scale * (res.u/111319.0-CX) + 0.5); *j = (int) (H/2.0 - scale * (res.v/111319.0-CY) + 0.5); //printf("PROJ map2screen (%f %f) -> (%3d %3d)\n", x,y, *i,*j); }
/** * Project a latitude/longitude pair to an X/Y pair * * @param p The proj-based projector to use. * @param longitude The longitude part of the pair (degrees). * @param latitude The latitude part of the pair (degrees). * @return The projected coordinates. */ projected_coordinates _proj_project(projector *p, float longitude, float latitude) { // Construct a proj-compatible input, converting degrees to radians // at the same time projUV pj_input; pj_input.u = longitude * DEG_TO_RAD; pj_input.v = latitude * DEG_TO_RAD; // Project the input coordinates projUV pj_output = pj_fwd(pj_input, (projUV *) p->internals); projected_coordinates output = {pj_output.v, pj_output.u}; return output; }
bool GeoConvHelper::x2cartesian_const(Position& from) const { double x = from.x() * myGeoScale; double y = from.y() * myGeoScale; if (myProjectionMethod == NONE) { from.add(myOffset); } else if (myUseInverseProjection) { cartesian2geo(from); } else { if (x > 180.1 || x < -180.1) { WRITE_WARNING("Invalid longitude " + toString(x)); return false; } if (y > 90.1 || y < -90.1) { WRITE_WARNING("Invalid latitude " + toString(y)); return false; } #ifdef HAVE_PROJ if (myProjection != 0) { projUV p; p.u = x * DEG_TO_RAD; p.v = y * DEG_TO_RAD; p = pj_fwd(p, myProjection); //!!! check pj_errno x = p.u; y = p.v; } #endif if (myProjectionMethod == SIMPLE) { double ys = y; x *= 111320. * cos(DEG2RAD(ys)); y *= 111136.; from.set((SUMOReal)x, (SUMOReal)y); //!!! recheck whether the axes are mirrored from.add(myOffset); } } if (x > std::numeric_limits<double>::max() || y > std::numeric_limits<double>::max()) { return false; } if (myProjectionMethod != SIMPLE) { from.set((SUMOReal)x, (SUMOReal)y); from.add(myOffset); } return true; }
/* * NAME: * fmgeo2ucs * * PURPOSE: * Computes User Coordinate Values (northings, eastings) from geographical * latitude, longitude. * * REQUIREMENTS: * * INPUT: * * OUTPUT: * * NOTES: * * BUGS: * * AUTHOR: * Øystein Godøy, met.no/FOU, 10.01.2005 * * MODIFIED: * NA */ fmucspos fmgeo2ucs(fmgeopos ll, fmprojspec myproj) { fmucspos xy; PJ *ref; projUV cnat; /* * Select predefined projection, and initialize interface to PROJ */ if (myproj == MI) { if (!(ref=pj_init(sizeof(miproj)/sizeof(char *), miproj))) { fprintf(stderr,"ERROR: PROJ initialization failed.\n"); } } else if (myproj == MEOS) { if (!(ref=pj_init(sizeof(meosproj)/sizeof(char *), meosproj))) { fprintf(stderr,"ERROR: PROJ initialization failed.\n"); } } else { fprintf(stdout,"ERROR: Projection not supported\n"); } /* * Estimate xy */ cnat.u = (ll.lon)*DEG_TO_RAD; cnat.v = (ll.lat)*DEG_TO_RAD; cnat = pj_fwd(cnat,ref); xy.eastings = cnat.u; xy.northings = cnat.v; /* printf(" ll2xy (lat/lon): %.2f %.2f %.2f %.2f\n", ll.lat, ll.lon, xy.x, xy.y); */ if (cnat.u == HUGE_VAL) { fprintf(stderr, "ERROR: pj_fwd conversion\n"); } pj_free(ref); return(xy); }
/**Transforms a point in WGS84 LonLat in radians to projected coordinates. This version of the method changes the point in-place. call-seq: forward!(point) -> point */ static VALUE proj_forward(VALUE self,VALUE point){ _wrap_pj* wpj; int pj_errno_ref; projLP pj_point; projXY pj_result; Data_Get_Struct(self,_wrap_pj,wpj); pj_point.u = NUM2DBL( rb_funcall(point, idGetX, 0) ); pj_point.v = NUM2DBL( rb_funcall(point, idGetY, 0) ); pj_result = pj_fwd(pj_point, wpj->pj); pj_errno_ref = *pj_get_errno_ref(); if (pj_errno_ref == 0) { rb_funcall(point, idSetX, 1, rb_float_new(pj_result.u) ); rb_funcall(point, idSetY, 1, rb_float_new(pj_result.v) ); return point; } else if (pj_errno_ref > 0) { rb_raise(rb_eSystemCallError, "Unknown system call error"); } else { raise_error(pj_errno_ref); } return self; /* Makes gcc happy */ }
/** * 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); }
static void process(FILE *fid) { char line[MAX_LINE], *s, t, pline[100]; projUV val; double tmp; for (;;) { if (input.bin) fread(&val, sizeof(projUV), 1, fid); else if (s = fgets(line, MAX_LINE, fid)) { if (*s == tag) { fputs(line, stdout); continue; } else if (input.ll) { val.u = dmstor(s, &s); val.v = dmstor(s, &s); } else { val.u = strtod(s, &s); val.v = strtod(s, &s); } } if (feof(fid)) break; if (input.rev) { tmp = val.u; val.u = val.v; val.v = tmp; } /* data in, manupulate */ if (input.cnv) val = pj_inv(val, input.cnv); if (input.hp) val = nad_cvt(val, 1, htab); /* nad conversion */ if (ctab) val = nad_cvt(val, input.t83 ? 1 : 0, ctab); if (output.hp) val = nad_cvt(val, 0, htab); if (output.cnv) val = pj_fwd(val, output.cnv); /* output data */ if (output.rev) { tmp = val.u; val.u = val.v; val.v = tmp; } if (output.bin) (void)fwrite(&val, sizeof(projUV), 1, stdout); else { if (echoin) { t = *s; *s = '\0'; (void)fputs(line, stdout); (void)putchar('\t'); *s = t; } if (val.u == HUGE_VAL) (void)fputs(oterr, stdout); else if (output.ll) if (oform) { (void)printf(oform, val.u * RAD_TO_DEG); (void)putchar('\t'); (void)printf(oform, val.v * RAD_TO_DEG); } else if (output.rev) { (void)fputs(rtodms(pline, val.u, 'N', 'S'), stdout); (void)putchar('\t'); (void)fputs(rtodms(pline, val.v, 'E', 'W'), stdout); } else { (void)fputs(rtodms(pline, val.u, 'E', 'W'), stdout); (void)putchar('\t'); (void)fputs(rtodms(pline, val.v, 'N', 'S'), stdout); } else { (void)printf(oform ? oform : "%.2f", val.u); (void)putchar('\t'); (void)printf(oform ? oform : "%.2f", val.v); } if (input.bin) putchar('\n'); else (void)fputs(s, stdout); } } }
int msProjectPoint(projectionObj *in, projectionObj *out, pointObj *point) { #ifdef USE_PROJ projUV p; int error; if( in && in->gt.need_geotransform ) { double x_out, y_out; x_out = in->gt.geotransform[0] + in->gt.geotransform[1] * point->x + in->gt.geotransform[2] * point->y; y_out = in->gt.geotransform[3] + in->gt.geotransform[4] * point->x + in->gt.geotransform[5] * point->y; point->x = x_out; point->y = y_out; } /* -------------------------------------------------------------------- */ /* If the source and destination are simple and equal, then do */ /* nothing. */ /* -------------------------------------------------------------------- */ if( in && in->numargs == 1 && out && out->numargs == 1 && strcmp(in->args[0],out->args[0]) == 0 ) { /* do nothing, no transformation required */ } /* -------------------------------------------------------------------- */ /* If we have a fully defined input coordinate system and */ /* output coordinate system, then we will use pj_transform. */ /* -------------------------------------------------------------------- */ else if( in && in->proj && out && out->proj ) { double z = 0.0; if( pj_is_latlong(in->proj) ) { point->x *= DEG_TO_RAD; point->y *= DEG_TO_RAD; } msAcquireLock( TLOCK_PROJ ); error = pj_transform( in->proj, out->proj, 1, 0, &(point->x), &(point->y), &z ); msReleaseLock( TLOCK_PROJ ); if( error || point->x == HUGE_VAL || point->y == HUGE_VAL ) return MS_FAILURE; if( pj_is_latlong(out->proj) ) { point->x *= RAD_TO_DEG; point->y *= RAD_TO_DEG; } } /* -------------------------------------------------------------------- */ /* Otherwise we fallback to using pj_fwd() or pj_inv() and */ /* assuming that the NULL projectionObj is supposed to be */ /* lat/long in the same datum as the other projectionObj. This */ /* is essentially a backwards compatibility mode. */ /* -------------------------------------------------------------------- */ else { /* nothing to do if the other coordinate system is also lat/long */ if( in == NULL && out != NULL && pj_is_latlong(out->proj) ) return MS_SUCCESS; if( out == NULL && in != NULL && pj_is_latlong(in->proj) ) return MS_SUCCESS; p.u = point->x; p.v = point->y; if(in==NULL || in->proj==NULL) { /* input coordinates are lat/lon */ p.u *= DEG_TO_RAD; /* convert to radians */ p.v *= DEG_TO_RAD; p = pj_fwd(p, out->proj); } else { if(out==NULL || out->proj==NULL) { /* output coordinates are lat/lon */ p = pj_inv(p, in->proj); p.u *= RAD_TO_DEG; /* convert to decimal degrees */ p.v *= RAD_TO_DEG; } else { /* need to go from one projection to another */ p = pj_inv(p, in->proj); p = pj_fwd(p, out->proj); } } if( p.u == HUGE_VAL || p.v == HUGE_VAL ) return MS_FAILURE; point->x = p.u; point->y = p.v; } if( out && out->gt.need_geotransform ) { double x_out, y_out; x_out = out->gt.invgeotransform[0] + out->gt.invgeotransform[1] * point->x + out->gt.invgeotransform[2] * point->y; y_out = out->gt.invgeotransform[3] + out->gt.invgeotransform[4] * point->x + out->gt.invgeotransform[5] * point->y; point->x = x_out; point->y = y_out; } return(MS_SUCCESS); #else msSetError(MS_PROJERR, "Projection support is not available.", "msProjectPoint()"); return(MS_FAILURE); #endif }
int pj_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset, double *x, double *y, double *z ) { long i; int need_datum_shift; pj_errno = 0; if( point_offset == 0 ) point_offset = 1; /* -------------------------------------------------------------------- */ /* Transform geocentric source coordinates to lat/long. */ /* -------------------------------------------------------------------- */ if( srcdefn->is_geocent ) { if( z == NULL ) { pj_errno = PJD_ERR_GEOCENTRIC; return PJD_ERR_GEOCENTRIC; } if( srcdefn->to_meter != 1.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) { x[point_offset*i] *= srcdefn->to_meter; y[point_offset*i] *= srcdefn->to_meter; } } } if( pj_geocentric_to_geodetic( srcdefn->a_orig, srcdefn->es_orig, point_count, point_offset, x, y, z ) != 0) return pj_errno; } /* -------------------------------------------------------------------- */ /* Transform source points to lat/long, if they aren't */ /* already. */ /* -------------------------------------------------------------------- */ else if( !srcdefn->is_latlong ) { if( srcdefn->inv == NULL ) { pj_errno = -17; /* this isn't correct, we need a no inverse err */ if( getenv( "PROJ_DEBUG" ) != NULL ) { fprintf( stderr, "pj_transform(): source projection not invertable\n" ); } return pj_errno; } for( i = 0; i < point_count; i++ ) { XY projected_loc; LP geodetic_loc; projected_loc.u = x[point_offset*i]; projected_loc.v = y[point_offset*i]; if( projected_loc.u == HUGE_VAL ) continue; geodetic_loc = pj_inv( projected_loc, srcdefn ); if( pj_errno != 0 ) { if( (pj_errno != 33 /*EDOM*/ && pj_errno != 34 /*ERANGE*/ ) && (pj_errno > 0 || pj_errno < -44 || point_count == 1 || transient_error[-pj_errno] == 0 ) ) return pj_errno; else { geodetic_loc.u = HUGE_VAL; geodetic_loc.v = HUGE_VAL; } } x[point_offset*i] = geodetic_loc.u; y[point_offset*i] = geodetic_loc.v; } } /* -------------------------------------------------------------------- */ /* But if they are already lat long, adjust for the prime */ /* meridian if there is one in effect. */ /* -------------------------------------------------------------------- */ if( srcdefn->from_greenwich != 0.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) x[point_offset*i] += srcdefn->from_greenwich; } } /* -------------------------------------------------------------------- */ /* Convert datums if needed, and possible. */ /* -------------------------------------------------------------------- */ if( pj_datum_transform( srcdefn, dstdefn, point_count, point_offset, x, y, z ) != 0 ) return pj_errno; /* -------------------------------------------------------------------- */ /* But if they are staying lat long, adjust for the prime */ /* meridian if there is one in effect. */ /* -------------------------------------------------------------------- */ if( dstdefn->from_greenwich != 0.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) x[point_offset*i] -= dstdefn->from_greenwich; } } /* -------------------------------------------------------------------- */ /* Transform destination latlong to geocentric if required. */ /* -------------------------------------------------------------------- */ if( dstdefn->is_geocent ) { if( z == NULL ) { pj_errno = PJD_ERR_GEOCENTRIC; return PJD_ERR_GEOCENTRIC; } pj_geodetic_to_geocentric( dstdefn->a_orig, dstdefn->es_orig, point_count, point_offset, x, y, z ); if( dstdefn->fr_meter != 1.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) { x[point_offset*i] *= dstdefn->fr_meter; y[point_offset*i] *= dstdefn->fr_meter; } } } } /* -------------------------------------------------------------------- */ /* Transform destination points to projection coordinates, if */ /* desired. */ /* -------------------------------------------------------------------- */ else if( !dstdefn->is_latlong ) { for( i = 0; i < point_count; i++ ) { XY projected_loc; LP geodetic_loc; geodetic_loc.u = x[point_offset*i]; geodetic_loc.v = y[point_offset*i]; if( geodetic_loc.u == HUGE_VAL ) continue; projected_loc = pj_fwd( geodetic_loc, dstdefn ); if( pj_errno != 0 ) { if( (pj_errno != 33 /*EDOM*/ && pj_errno != 34 /*ERANGE*/ ) && (pj_errno > 0 || pj_errno < -44 || point_count == 1 || transient_error[-pj_errno] == 0 ) ) return pj_errno; else { projected_loc.u = HUGE_VAL; projected_loc.v = HUGE_VAL; } } x[point_offset*i] = projected_loc.u; y[point_offset*i] = projected_loc.v; } } /* -------------------------------------------------------------------- */ /* If a wrapping center other than 0 is provided, rewrap around */ /* the suggested center (for latlong coordinate systems only). */ /* -------------------------------------------------------------------- */ else if( dstdefn->is_latlong && dstdefn->long_wrap_center != 0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] == HUGE_VAL ) continue; while( x[point_offset*i] < dstdefn->long_wrap_center - HALFPI ) x[point_offset*i] += PI; while( x[point_offset*i] > dstdefn->long_wrap_center + HALFPI ) x[point_offset*i] -= PI; } } return 0; }
int pj_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset, double *x, double *y, double *z ) { long i; int err; srcdefn->ctx->last_errno = 0; dstdefn->ctx->last_errno = 0; if( point_offset == 0 ) point_offset = 1; /* -------------------------------------------------------------------- */ /* Transform unusual input coordinate axis orientation to */ /* standard form if needed. */ /* -------------------------------------------------------------------- */ if( strcmp(srcdefn->axis,"enu") != 0 ) { int err; err = pj_adjust_axis( srcdefn->ctx, srcdefn->axis, 0, point_count, point_offset, x, y, z ); if( err != 0 ) return err; } /* -------------------------------------------------------------------- */ /* Transform Z to meters if it isn't already. */ /* -------------------------------------------------------------------- */ if( srcdefn->vto_meter != 1.0 && z != NULL ) { for( i = 0; i < point_count; i++ ) z[point_offset*i] *= srcdefn->vto_meter; } /* -------------------------------------------------------------------- */ /* Transform geocentric source coordinates to lat/long. */ /* -------------------------------------------------------------------- */ if( srcdefn->is_geocent ) { if( z == NULL ) { pj_ctx_set_errno( pj_get_ctx(srcdefn), PJD_ERR_GEOCENTRIC); return PJD_ERR_GEOCENTRIC; } if( srcdefn->to_meter != 1.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) { x[point_offset*i] *= srcdefn->to_meter; y[point_offset*i] *= srcdefn->to_meter; } } } err = pj_geocentric_to_geodetic( srcdefn->a_orig, srcdefn->es_orig, point_count, point_offset, x, y, z ); if( err != 0 ) return err; } /* -------------------------------------------------------------------- */ /* Transform source points to lat/long, if they aren't */ /* already. */ /* -------------------------------------------------------------------- */ else if( !srcdefn->is_latlong ) { if( srcdefn->inv == NULL ) { pj_ctx_set_errno( pj_get_ctx(srcdefn), -17 ); pj_log( pj_get_ctx(srcdefn), PJ_LOG_ERROR, "pj_transform(): source projection not invertable" ); return -17; } for( i = 0; i < point_count; i++ ) { XY projected_loc; LP geodetic_loc; projected_loc.u = x[point_offset*i]; projected_loc.v = y[point_offset*i]; if( projected_loc.u == HUGE_VAL ) continue; geodetic_loc = pj_inv( projected_loc, srcdefn ); if( srcdefn->ctx->last_errno != 0 ) { if( (srcdefn->ctx->last_errno != 33 /*EDOM*/ && srcdefn->ctx->last_errno != 34 /*ERANGE*/ ) && (srcdefn->ctx->last_errno > 0 || srcdefn->ctx->last_errno < -44 || point_count == 1 || transient_error[-srcdefn->ctx->last_errno] == 0 ) ) return srcdefn->ctx->last_errno; else { geodetic_loc.u = HUGE_VAL; geodetic_loc.v = HUGE_VAL; } } x[point_offset*i] = geodetic_loc.u; y[point_offset*i] = geodetic_loc.v; } } /* -------------------------------------------------------------------- */ /* But if they are already lat long, adjust for the prime */ /* meridian if there is one in effect. */ /* -------------------------------------------------------------------- */ if( srcdefn->from_greenwich != 0.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) x[point_offset*i] += srcdefn->from_greenwich; } } /* -------------------------------------------------------------------- */ /* Do we need to translate from geoid to ellipsoidal vertical */ /* datum? */ /* -------------------------------------------------------------------- */ if( srcdefn->has_geoid_vgrids ) { if( pj_apply_vgridshift( srcdefn, "sgeoidgrids", &(srcdefn->vgridlist_geoid), &(srcdefn->vgridlist_geoid_count), 0, point_count, point_offset, x, y, z ) != 0 ) return pj_ctx_get_errno(srcdefn->ctx); } /* -------------------------------------------------------------------- */ /* Convert datums if needed, and possible. */ /* -------------------------------------------------------------------- */ if( pj_datum_transform( srcdefn, dstdefn, point_count, point_offset, x, y, z ) != 0 ) { if( srcdefn->ctx->last_errno != 0 ) return srcdefn->ctx->last_errno; else return dstdefn->ctx->last_errno; } /* -------------------------------------------------------------------- */ /* Do we need to translate from geoid to ellipsoidal vertical */ /* datum? */ /* -------------------------------------------------------------------- */ if( dstdefn->has_geoid_vgrids ) { if( pj_apply_vgridshift( dstdefn, "sgeoidgrids", &(dstdefn->vgridlist_geoid), &(dstdefn->vgridlist_geoid_count), 1, point_count, point_offset, x, y, z ) != 0 ) return dstdefn->ctx->last_errno; } /* -------------------------------------------------------------------- */ /* But if they are staying lat long, adjust for the prime */ /* meridian if there is one in effect. */ /* -------------------------------------------------------------------- */ if( dstdefn->from_greenwich != 0.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) x[point_offset*i] -= dstdefn->from_greenwich; } } /* -------------------------------------------------------------------- */ /* Transform destination latlong to geocentric if required. */ /* -------------------------------------------------------------------- */ if( dstdefn->is_geocent ) { if( z == NULL ) { pj_ctx_set_errno( dstdefn->ctx, PJD_ERR_GEOCENTRIC ); return PJD_ERR_GEOCENTRIC; } pj_geodetic_to_geocentric( dstdefn->a_orig, dstdefn->es_orig, point_count, point_offset, x, y, z ); if( dstdefn->fr_meter != 1.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) { x[point_offset*i] *= dstdefn->fr_meter; y[point_offset*i] *= dstdefn->fr_meter; } } } } /* -------------------------------------------------------------------- */ /* Transform destination points to projection coordinates, if */ /* desired. */ /* -------------------------------------------------------------------- */ else if( !dstdefn->is_latlong ) { for( i = 0; i < point_count; i++ ) { XY projected_loc; LP geodetic_loc; geodetic_loc.u = x[point_offset*i]; geodetic_loc.v = y[point_offset*i]; if( geodetic_loc.u == HUGE_VAL ) continue; projected_loc = pj_fwd( geodetic_loc, dstdefn ); if( dstdefn->ctx->last_errno != 0 ) { if( (dstdefn->ctx->last_errno != 33 /*EDOM*/ && dstdefn->ctx->last_errno != 34 /*ERANGE*/ ) && (dstdefn->ctx->last_errno > 0 || dstdefn->ctx->last_errno < -44 || point_count == 1 || transient_error[-dstdefn->ctx->last_errno] == 0 ) ) return dstdefn->ctx->last_errno; else { projected_loc.u = HUGE_VAL; projected_loc.v = HUGE_VAL; } } x[point_offset*i] = projected_loc.u; y[point_offset*i] = projected_loc.v; } } /* -------------------------------------------------------------------- */ /* If a wrapping center other than 0 is provided, rewrap around */ /* the suggested center (for latlong coordinate systems only). */ /* -------------------------------------------------------------------- */ else if( dstdefn->is_latlong && dstdefn->is_long_wrap_set ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] == HUGE_VAL ) continue; while( x[point_offset*i] < dstdefn->long_wrap_center - PI ) x[point_offset*i] += TWOPI; while( x[point_offset*i] > dstdefn->long_wrap_center + PI ) x[point_offset*i] -= TWOPI; } } /* -------------------------------------------------------------------- */ /* Transform Z from meters if needed. */ /* -------------------------------------------------------------------- */ if( dstdefn->vto_meter != 1.0 && z != NULL ) { for( i = 0; i < point_count; i++ ) z[point_offset*i] *= dstdefn->vfr_meter; } /* -------------------------------------------------------------------- */ /* Transform normalized axes into unusual output coordinate axis */ /* orientation if needed. */ /* -------------------------------------------------------------------- */ if( strcmp(dstdefn->axis,"enu") != 0 ) { int err; err = pj_adjust_axis( dstdefn->ctx, dstdefn->axis, 1, point_count, point_offset, x, y, z ); if( err != 0 ) return err; } return 0; }
/* file processing function --- verbosely */ static void vprocess(FILE *fid) { char line[MAX_LINE+3], *s, pline[40]; PJ_LP dat_ll; PJ_XY dat_xy; int linvers; PJ_COORD coord; if (!oform) oform = "%.3f"; if (bin_in || bin_out) emess(1,"binary I/O not available in -V option"); for (;;) { proj_errno_reset(Proj); ++emess_dat.File_line; if (!(s = fgets(line, MAX_LINE, fid))) break; if (!strchr(s, '\n')) { /* overlong line */ int c; (void)strcat(s, "\n"); /* gobble up to newline */ while ((c = fgetc(fid)) != EOF && c != '\n') ; } if (*s == tag) { /* pass on data */ (void)fputs(s, stdout); continue; } /* check to override default input mode */ if (*s == 'I' || *s == 'i') { linvers = 1; ++s; } else linvers = inverse; if (linvers) { if (!PJ_INVERS(Proj)) { emess(-1,"inverse for this projection not avail.\n"); continue; } dat_xy.x = strtod(s, &s); dat_xy.y = strtod(s, &s); if (dat_xy.x == HUGE_VAL || dat_xy.y == HUGE_VAL) { emess(-1,"lon-lat input conversion failure\n"); continue; } if (prescale) { dat_xy.x *= fscale; dat_xy.y *= fscale; } if (reversein) { PJ_XY temp = dat_xy; dat_xy.x = temp.y; dat_xy.y = temp.x; } dat_ll = pj_inv(dat_xy, Proj); } else { dat_ll.lam = proj_dmstor(s, &s); dat_ll.phi = proj_dmstor(s, &s); if (dat_ll.lam == HUGE_VAL || dat_ll.phi == HUGE_VAL) { emess(-1,"lon-lat input conversion failure\n"); continue; } if (reversein) { PJ_LP temp = dat_ll; dat_ll.lam = temp.phi; dat_ll.phi = temp.lam; } dat_xy = pj_fwd(dat_ll, Proj); if (postscale) { dat_xy.x *= fscale; dat_xy.y *= fscale; } } /* For some reason pj_errno does not work as expected in some */ /* versions of Visual Studio, so using pj_get_errno_ref instead */ if (*pj_get_errno_ref()) { emess(-1, pj_strerrno(*pj_get_errno_ref())); continue; } if (!*s && (s > line)) --s; /* assumed we gobbled \n */ coord.lp = dat_ll; facs = proj_factors(Proj, coord); if (proj_errno(Proj)) { emess(-1,"failed to compute factors\n\n"); continue; } if (*s != '\n') (void)fputs(s, stdout); (void)fputs("Longitude: ", stdout); (void)fputs(proj_rtodms(pline, dat_ll.lam, 'E', 'W'), stdout); (void)printf(" [ %.11g ]\n", dat_ll.lam * RAD_TO_DEG); (void)fputs("Latitude: ", stdout); (void)fputs(proj_rtodms(pline, dat_ll.phi, 'N', 'S'), stdout); (void)printf(" [ %.11g ]\n", dat_ll.phi * RAD_TO_DEG); (void)fputs("Easting (x): ", stdout); (void)printf(oform, dat_xy.x); putchar('\n'); (void)fputs("Northing (y): ", stdout); (void)printf(oform, dat_xy.y); putchar('\n'); (void)printf("Meridian scale (h) : %.8f ( %.4g %% error )\n", facs.meridional_scale, (facs.meridional_scale-1.)*100.); (void)printf("Parallel scale (k) : %.8f ( %.4g %% error )\n", facs.parallel_scale, (facs.parallel_scale-1.)*100.); (void)printf("Areal scale (s): %.8f ( %.4g %% error )\n", facs.areal_scale, (facs.areal_scale-1.)*100.); (void)printf("Angular distortion (w): %.3f\n", facs.angular_distortion * RAD_TO_DEG); (void)printf("Meridian/Parallel angle: %.5f\n", facs.meridian_parallel_angle * RAD_TO_DEG); (void)printf("Convergence : "); (void)fputs(proj_rtodms(pline, facs.meridian_convergence, 0, 0), stdout); (void)printf(" [ %.8f ]\n", facs.meridian_convergence * RAD_TO_DEG); (void)printf("Max-min (Tissot axis a-b) scale error: %.5f %.5f\n\n", facs.tissot_semimajor, facs.tissot_semiminor); } }
int main() { //projUV p; //projPJ pj; ////const char* bj1954="+proj=tmerc +ellps=krass +x_0=18500000 +y_0=0 +lat_0=0 +lon_0=105 +units=m +k=1.0"; //const char* bj1954="+proj=tmerc +ellps=krass +lat_0=0 +lon_0=105 +units=m +k=1.0"; //if (!(pj = pj_init_plus(bj1954))) // return 1; //p.u = 106*DEG_TO_RAD; //p.v = 31*DEG_TO_RAD; //p = pj_fwd(p,pj); //std::cout.setf(std::ios_base::fixed); ////std::cout<<"Beijing 1954 & krass椭球, (103.60,36.11)"<<std::endl; //std::cout<<"Beijing 1954 & krass椭球, (106,31)"<<std::endl; //std::cout<<"pj_fwd result:"<<p.u<<" "<<p.v<<std::endl; ////p=pj_inv(p,pj); ////p.u/=DEG_TO_RAD; ////p.v/=DEG_TO_RAD; ////std::cout<<"pj_inv result:"<<p.u<<" "<<p.v<<std::endl; //pj_free(pj); //***************************************** //std::cout<<"*****************************************"<<std::endl; ////std::cout<<"输入用于测试的的中国地区的两点坐标:"<<std::endl; //double xArray[2] = {-122.2445086,-122.2481928}; //double yArray[2] = {47.2964240,47.2981713}; ////double xArray[2]={106,107}; ////double yArray[2]={31,32}; //projUV pc1,pc2; //pc1 = chinaProjection(xArray[0],yArray[0]); //pc2 = chinaProjection(xArray[1],yArray[1]); //Point *p1,*p2; //p1 = new Point(); //p2 = new Point(); //p1->lon = xArray[0]; //p1->lat = yArray[0]; //p2->lon = xArray[1]; //p2->lat = yArray[1]; //double dist1 = thisdist(p1,p2); //std::cout<<"两点球面距离:"<<dist1<<std::endl; //double x12 = (pc1.u - pc2.u)*(pc1.u - pc2.u); //double y12 = (pc1.v - pc2.v)*(pc1.v - pc2.v); //double dist2 = sqrt(x12 + y12); //std::cout<<"两点坐标距离:"<<dist2<<std::endl; //projUV pn1,pn2; //pn1 = northAmericaProjection(xArray[0],yArray[0]); //pn2 = northAmericaProjection(xArray[1],yArray[1]); //double x22 = (pn1.u - pn2.u)*(pn1.u - pn2.u); //double y22 = (pn1.v - pn2.v)*(pn1.v - pn2.v); //double dist3 = sqrt(x22 + y22); //std::cout<<"两点坐标距离:"<<dist3<<std::endl; //***************************************** std::cout<<"*****************************************"<<std::endl; std::string filePath="E:\\孙璐\\ACM_SIGSPATIAL\\ACM SIGSPATIAL CUP 2012\\RoadNetworkData\\WA_Nodes.txt"; std::string outFilePath="E:\\孙璐\\ACM_SIGSPATIAL\\ACM SIGSPATIAL CUP 2012\\RoadNetworkData\\WA_Nodes_Projetion.txt"; //FILE* nodefp; //nodefp = fopen(filePath.c_str(),"r"); //Roads *data = (Roads*)malloc(sizeof(Roads)); //readNodes(data, nodefp); std::ifstream fin(filePath.c_str()); std::ofstream fout(outFilePath.c_str()); projPJ pj1; const char* projection="+proj=tmerc +ellps=WGS84 +lat_0=0 +lon_0=-120 +units=m +k=1.0"; QueryPerformanceFrequency(&Frequency); QueryPerformanceCounter(&BeginTime); if (pj1 = pj_init_plus(projection)) { Node curNode; while(fin>>curNode.id>>curNode.loc.y>>curNode.loc.x) { projUV p; p.u = curNode.loc.y*DEG_TO_RAD; p.v = curNode.loc.x*DEG_TO_RAD; p = pj_fwd(p,pj1); //curP = northAmericaProjection(curNode.loc.lon, curNode.loc.lat, pj1); //std::cout<<curNode.id<<" "<<curP.u<<""<<curP.v<<std::endl; fout<<curNode.id<<" "<<p.u<<" "<<p.v<<std::endl; } }
int pj_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset, double *x, double *y, double *z ) { long i; int need_datum_shift; pj_errno = 0; if( point_offset == 0 ) point_offset = 1; /* -------------------------------------------------------------------- */ /* Transform source points to lat/long, if they aren't */ /* already. */ /* -------------------------------------------------------------------- */ if( !srcdefn->is_latlong ) { for( i = 0; i < point_count; i++ ) { XY projected_loc; LP geodetic_loc; projected_loc.u = x[point_offset*i]; projected_loc.v = y[point_offset*i]; geodetic_loc = pj_inv( projected_loc, srcdefn ); if( pj_errno != 0 ) return pj_errno; x[point_offset*i] = geodetic_loc.u; y[point_offset*i] = geodetic_loc.v; } } /* -------------------------------------------------------------------- */ /* Convert datums if needed, and possible. */ /* -------------------------------------------------------------------- */ if( pj_datum_transform( srcdefn, dstdefn, point_count, point_offset, x, y, z ) != 0 ) return pj_errno; /* -------------------------------------------------------------------- */ /* Transform destination points to projection coordinates, if */ /* desired. */ /* -------------------------------------------------------------------- */ if( !dstdefn->is_latlong ) { for( i = 0; i < point_count; i++ ) { XY projected_loc; LP geodetic_loc; geodetic_loc.u = x[point_offset*i]; geodetic_loc.v = y[point_offset*i]; projected_loc = pj_fwd( geodetic_loc, dstdefn ); if( pj_errno != 0 ) return pj_errno; x[point_offset*i] = projected_loc.u; y[point_offset*i] = projected_loc.v; } } return 0; }