Beispiel #1
0
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
}
Beispiel #2
0
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;
}
Beispiel #3
0
/*--------------------------------------------------------------------*/
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;
     }
 }
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
/* 
 * ===  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  ----- */
Beispiel #9
0
//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);
}
Beispiel #10
0
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;
}
Beispiel #11
0
//-------------------------------------------------------------------------------
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);
}
Beispiel #12
0
/**
  * 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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
/*
 * 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);
}
Beispiel #15
0
/**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 */
}
Beispiel #16
0
/**
 * 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;
}
Beispiel #17
0
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);
}
Beispiel #18
0
	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);
		}
	}
}
Beispiel #19
0
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
}
Beispiel #20
0
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;
}
Beispiel #21
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;
}
Beispiel #22
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);
    }
}
Beispiel #23
0
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;
		}
	}
Beispiel #24
0
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;
}