コード例 #1
0
ファイル: projection.cpp プロジェクト: FlavioFalcao/mapnik
void projection::inverse(double & x,double & y) const
{
#ifdef MAPNIK_USE_PROJ4
    if (!proj_)
    {
        throw std::runtime_error("projection::inverse not supported unless proj4 is initialized");
    }

    #if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
    mapnik::scoped_lock lock(mutex_);
    #endif
    if (is_geographic_)
    {
        x *=DEG_TO_RAD;
        y *=DEG_TO_RAD;
    }
    projUV p;
    p.u = x;
    p.v = y;
    p = pj_inv(p,proj_);
    x = RAD_TO_DEG * p.u;
    y = RAD_TO_DEG * p.v;
#else
    throw std::runtime_error("projection::inverse not supported without proj4 support (-DMAPNIK_USE_PROJ4)");
#endif
}
コード例 #2
0
ファイル: projectit.cpp プロジェクト: jeroenooms/rgdal
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);
}
コード例 #3
0
ファイル: GeoConvHelper.cpp プロジェクト: behrisch/sumo
void
GeoConvHelper::cartesian2geo(Position& cartesian) const {
    cartesian.sub(getOffsetBase());
    if (myProjectionMethod == NONE) {
        return;
    }
    if (myProjectionMethod == SIMPLE) {
        const double y = cartesian.y() / 111136.;
        const double x = cartesian.x() / 111320. / cos(DEG2RAD(y));
        cartesian.set(x, y);
        return;
    }
#ifdef PROJ_API_FILE
#ifdef PROJ_VERSION_MAJOR
    PJ_COORD c;
    c.xy.x = cartesian.x();
    c.xy.y = cartesian.y();
    c = proj_trans(myProjection, PJ_INV, c);
    cartesian.set(proj_todeg(c.lp.lam), proj_todeg(c.lp.phi));
#else
    projUV p;
    p.u = cartesian.x();
    p.v = cartesian.y();
    p = pj_inv(p, myProjection);
    //!!! check pj_errno
    p.u *= RAD_TO_DEG;
    p.v *= RAD_TO_DEG;
    cartesian.set((double) p.u, (double) p.v);
#endif
#endif
}
コード例 #4
0
ファイル: fmcoord.c プロジェクト: alborg/snowcover
/*
 * NAME:
 * fmucs2geo
 *
 * PURPOSE:
 * Computes geographical latitude, longitude from UCS northings, eastings.
 *
 * REQUIREMENTS:
 *
 * INPUT:
 *
 * OUTPUT:
 *
 * NOTES:
 *
 * BUGS:
 *
 * AUTHOR:
 * Øystein Godøy, met.no/FOU, 10.01.2005 
 *
 * MODIFIED:
 * NA
 */
fmgeopos fmucs2geo(fmucspos xy, fmprojspec myproj) {
    fmgeopos ll;
    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 ll
     */
    cnat.u = xy.eastings;
    cnat.v = xy.northings;
    cnat = pj_inv(cnat,ref);
    ll.lon = cnat.u*RAD_TO_DEG;
    ll.lat = cnat.v*RAD_TO_DEG;
    if (cnat.u == HUGE_VAL) {
	fprintf(stderr, "ERROR: pj_inv conversion\n");
    }
    pj_free(ref);

    return(ll);
}
コード例 #5
0
ファイル: GISUtils.cpp プロジェクト: highattack30/xptools
static	bool	TransformTiffCorner(GTIF * gtif, GTIFDefn * defn, double x, double y, double& outLon, double& outLat)
{
    /* Try to transform the coordinate into PCS space */
    if( !GTIFImageToPCS( gtif, &x, &y ) )
        return false;
	
    if( defn->Model == ModelTypeGeographic )
    {
    	outLon = x;
    	outLat = y;
    	return true;
    }
    else    
	{
        if( GTIFProj4ToLatLong( defn, 1, &x, &y ) )
        {
			outLon = x;
			outLat = y;
			return true;
		}

		int size = 0;
		tagtype_t type = TYPE_UNKNOWN;
		int key_count = GTIFKeyInfo(gtif, GTCitationGeoKey, &size, &type);
		
		if(key_count > 0 && key_count < 1024 && type == TYPE_ASCII && size == 1)
		{
			vector<char>	ascii(key_count);
			int r = GTIFKeyGet(gtif, GTCitationGeoKey, &ascii[0], 0, key_count);
			if(r == key_count)
			{
				DebugAssert(ascii.back() == 0);
				string citation = string(&ascii[0]);
				if(citation == "PCS Name = WGS_1984_Web_Mercator_Auxiliary_Sphere")
				{
					char ** args = CSLTokenizeStringComplex("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs", " +", TRUE, FALSE);
					PJ * psPJ = pj_init( CSLCount(args), args );
					CSLDestroy(args);
					if(psPJ)
					{
						projUV	sUV;

						sUV.u = x;
						sUV.v = y;

						sUV = pj_inv( sUV, psPJ );

						outLon = sUV.u * RAD_TO_DEG;
						outLat = sUV.v * RAD_TO_DEG;
						pj_free(psPJ);
						return true;
					}
				}
			}
		}
	}
	return false;
}
コード例 #6
0
ファイル: Projection_libproj.cpp プロジェクト: norulz/zyGrib
//-------------------------------------------------------------------------------
void Projection_libproj::screen2map(int i, int j, double *x, double *y) const
{
	projUV data, res;
	data.u =  ((i-W/2.0)/scale+ CX)*111319.0 ;
	data.v =  ((H/2.0-j)/scale+ CY)*111319.0 ;
	res = pj_inv(data, libProj);
	*x = (double)(res.u*RAD_TO_DEG);
	*y = (double)(res.v*RAD_TO_DEG);
	//printf("PROJ   screen2map (%3d %3d) -> (%f %f)\n", i,j, *x,*y);
}
コード例 #7
0
ファイル: mb_proj.c プロジェクト: hohonuuli/mb-system
/*--------------------------------------------------------------------*/
int mb_proj_inverse(int verbose,
		void *pjptr,
		double easting, double northing,
		double *lon, double *lat,
		int *error)
{
	char	*function_name = "mb_proj_inverse";
	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       easting:    %f\n",easting);
		fprintf(stderr,"dbg2       northing:   %f\n",northing);
		}

	/* do forward projection */
	if (pjptr != NULL)
		{
		pj = (projPJ) pjptr;
		pjxy.u = easting;
		pjxy.v = northing;
		pjll = pj_inv(pjxy, pj);
		*lon = RTD * pjll.u;
		*lat = RTD * pjll.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       lon:             %f\n",*lon);
		fprintf(stderr,"dbg2       lat:             %f\n",*lat);
		fprintf(stderr,"dbg2       error:           %d\n",*error);
		fprintf(stderr,"dbg2  Return status:\n");
		fprintf(stderr,"dbg2       status:          %d\n",status);
		}

	/* return status */
	return(status);
}
コード例 #8
0
 inline bool inverse(const XY& xy, LL& lp) const
 {
     try
     {
         pj_inv(this->m_prj, this->m_par, xy, lp);
         return true;
     }
     catch(...)
     {
         return false;
     }
 }
コード例 #9
0
ファイル: projrb.c プロジェクト: gvellut/geopochi
//Goes from the projected coordinates to WGS84 LatLon
static VALUE proj_inverse(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 = pj_inv(*c_uv,wpj->pj);
  pResult->u *= RAD_TO_DEG;
  pResult->v *= RAD_TO_DEG;
  return Data_Wrap_Struct(cUV,0,uv_free,pResult);
}
コード例 #10
0
ファイル: c_proj4.c プロジェクト: pavpen/proj4-hs-bindings
projUV* c_pj_inv_ptr(projUV *val, projPJ proj)
{
	projUV res;
	
#  ifdef _DEBUG
	printf("Entered c_pj_inv_ptr(proj=%p).\n", proj);
#  endif
	res = pj_inv(*val, proj);
	val->u = res.u;
	val->v = res.v;
	return val;
}
コード例 #11
0
ファイル: geotiff_proj4.c プロジェクト: fb/jasper-xcsoar
int GTIFProj4ToLatLong( 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];
        sUV.v = padfY[i];

        sUV = pj_inv( sUV, psPJ );

        padfX[i] = sUV.u * RAD_TO_DEG;
        padfY[i] = sUV.v * RAD_TO_DEG;
    }

    pj_free( psPJ );

    return TRUE;
}
コード例 #12
0
ファイル: map.c プロジェクト: Exteris/Gerris
static void projection_inverse (GfsMap * map, const FttVector * src, FttVector * dest)
{
  projLP odata;
  projXY idata;
  GfsMapProjection * m = GFS_MAP_PROJECTION (map);
  gdouble L = gfs_object_simulation (map)->physical_params.L;
  idata.u = (src->x*m->cosa + src->y*m->sina)*L;
  idata.v = (src->y*m->cosa - src->x*m->sina)*L;
  odata = pj_inv (idata, GFS_MAP_PROJECTION (map)->pj);
  dest->x = odata.u*RAD_TO_DEG/L;
  dest->y = odata.v*RAD_TO_DEG/L;
  dest->z = src->z;
}
コード例 #13
0
ファイル: proj_projector.c プロジェクト: andyclegg/Caspian
/**
  * Project an X/Y pair to a latitude/longitude pair
  *
  * @param p The proj-based projector to use.
  * @param y The Y part of the pair (metres).
  * @param x The X part of the pair (metres).
  * @return The spherical coordinates.
  */
spherical_coordinates _proj_inverse_project(projector *p, float y, float x) {
   // Construct a proj-compatible input
   projUV pj_input;
   pj_input.u = y;
   pj_input.v = x;

   // Project the coordinates
   projUV pj_output = pj_inv(pj_input, (projUV *) p->internals);

   // Convert the result back to degrees
   spherical_coordinates output =
   {pj_output.v * RAD_TO_DEG, pj_output.u * RAD_TO_DEG};
   return output;
}
コード例 #14
0
void
GeoConvHelper::cartesian2geo(Position& cartesian) const {
    cartesian.sub(getOffsetBase());
    if (myProjectionMethod == NONE) {
        return;
    }
#ifdef HAVE_PROJ
    projUV p;
    p.u = cartesian.x();
    p.v = cartesian.y();
    p = pj_inv(p, myProjection);
    //!!! check pj_errno
    p.u *= RAD_TO_DEG;
    p.v *= RAD_TO_DEG;
    cartesian.set((SUMOReal) p.u, (SUMOReal) p.v);
#endif
}
コード例 #15
0
ファイル: GISUtils.cpp プロジェクト: highattack30/xptools
void	UTMToLonLat(double x, double y, int zone, double * outLon, double * outLat)
{
	SetupUTMMap(zone);
	if (sUTMProj.find(zone) == sUTMProj.end())
		return;

      projUV	sUV;

    sUV.u = x;
    sUV.v = y;

//    sUV = nad_cvt(sUV, false, sNADGrid);

	sUV = pj_inv( sUV, sUTMProj[zone]);

	if (outLon) *outLon = sUV.u * RAD_TO_DEG;
	if (outLat) *outLat = sUV.v * RAD_TO_DEG;
}
コード例 #16
0
ファイル: S57data.c プロジェクト: pcannon67/S52
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;
}
コード例 #17
0
ファイル: projrb.c プロジェクト: LouisStAmour/proj4rb19
/**Transforms a point in the coordinate system defined at initialization of the Projection object to WGS84 LonLat in radians.
   This version of the method changes the point in-place.

   call-seq: inverse!(point) -> point

 */
static VALUE proj_inverse(VALUE self,VALUE point){
  _wrap_pj* wpj;
  int pj_errno_ref;
  projXY pj_point;
  projLP 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_inv(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 */
}
コード例 #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);
		}
	}
}
コード例 #19
0
ファイル: mapproject.c プロジェクト: codeforeurope/gim
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
}
コード例 #20
0
ファイル: pj_transform.c プロジェクト: naadsm/proj4_delphi
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;
}
コード例 #21
0
ファイル: pj_transform.c プロジェクト: hminth/Rice-Video
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;
}
コード例 #22
0
ファイル: pj_transform.c プロジェクト: SvenGastauer/oce
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;
}
コード例 #23
0
ファイル: proj.cpp プロジェクト: QuLogic/proj.4
/* 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);
    }
}
コード例 #24
0
static
void write_shapefile (local_data_t *local_data)
{
  guint npolys;

  char *shape_filename;
  SHPHandle shape_file = NULL;
  SHPObject *shape;
  double *vertex_x, *vertex_y;
  guint i, j;
  projUV p;

  char *dbf_filename;
  DBFHandle dbf_file = NULL;
  int nunits_field_index;
  int avg_ninfected_field_index;
  int avg_ndestroyed_field_index;
  int avg_nvaccinated_field_index;
  int avg_frinfected_field_index;
  int avg_frdestroyed_field_index;
  int avg_frvaccinated_field_index;

  #if DEBUG
    g_debug ("----- ENTER write_shapefile (%s)", MODEL_NAME);
  #endif

  vertex_x = g_new (double, local_data->max_nvertices);
  vertex_y = g_new (double, local_data->max_nvertices);

  /* We are going to write 2 files: the .shp file, containing the geometry of
   * the polygons, and the .dbf file, containing the numeric attributes
   * attached to the polygons. */

  shape_filename = g_strdup_printf ("%s.shp", local_data->base_filename);
  #if DEBUG
    g_debug ("creating new shapefile \"%s\"", shape_filename);
  #endif
  shape_file = SHPCreate (shape_filename, SHPT_POLYGON);
  g_assert (shape_file != NULL);

  npolys = local_data->polys->len;
  for (i = 0; i < npolys; i++)
    {
      gpc_polygon *poly;
      gpc_vertex_list *contour;

      poly = (gpc_polygon *) g_ptr_array_index (local_data->polys, i);
      g_assert (poly->num_contours == 1);
      contour = &(poly->contour[0]);
      for (j = 0; j < contour->num_vertices; j++)
        {
          /* The polygon vertices are in x-y coordinates.  We need to
           * "unproject" them back to lat-long. */
          p.u = contour->vertex[j].x;
          p.v = contour->vertex[j].y;
          p = pj_inv (p, local_data->projection);
          vertex_x[j] = p.u * RAD_TO_DEG;
          vertex_y[j] = p.v * RAD_TO_DEG;
        }
      shape = SHPCreateSimpleObject (SHPT_POLYGON, j, vertex_x, vertex_y, NULL);
      SHPWriteObject (shape_file, -1, shape);
      SHPDestroyObject (shape);
    }
  if (shape_file != NULL)
    SHPClose (shape_file);
  g_free (shape_filename);

  /* Now the attribute file */

  dbf_filename = g_strdup_printf ("%s.dbf", local_data->base_filename);
  #if DEBUG
    g_debug ("creating new attributes file \"%s\"", dbf_filename);
  #endif
  dbf_file = DBFCreate (dbf_filename);
  g_assert (dbf_file != NULL);

  /* Add attribute definitions. */
  #if DEBUG
    g_debug ("adding field definitions to DBF file \"%s\": nunits, avgninf, avgndest, avgnvacc, avgfrinf, avgfrdest, avgfrvacc",
             dbf_filename);
  #endif
  /* 9-digit integers should be enough to count # of units in a polygon. */
  nunits_field_index = DBFAddField (dbf_file, "nunits", FTInteger, 9, 0);
  /* 1 decimal place for average # of units infected or destroyed, 3 for
   * average fraction of units. */
  avg_ninfected_field_index = DBFAddField (dbf_file, "avgninf", FTDouble, 9, 1);
  avg_ndestroyed_field_index = DBFAddField (dbf_file, "avgndest", FTDouble, 9, 1);
  avg_nvaccinated_field_index = DBFAddField (dbf_file, "avgnvacc", FTDouble, 9, 1);
  avg_frinfected_field_index = DBFAddField (dbf_file, "avgfrinf", FTDouble, 9, 3);
  avg_frdestroyed_field_index = DBFAddField (dbf_file, "avgfrdest", FTDouble, 9, 3);
  avg_frvaccinated_field_index = DBFAddField (dbf_file, "avgfrvacc", FTDouble, 9, 3);

  /* Write the attributes to the file. */
  #if DEBUG
    g_debug ("writing attributes to \"%s\"", dbf_filename);
  #endif
  for (i = 0; i < npolys; i++)
    {
      guint nunits;

      /* Divide the counts by the number of runs to get the mean */
      local_data->ninfected[i] /= local_data->nruns;
      local_data->ndestroyed[i] /= local_data->nruns;
      local_data->nvaccinated[i] /= local_data->nruns;

      nunits = local_data->unit_count[i];
      DBFWriteIntegerAttribute (dbf_file, i, nunits_field_index, nunits);
      DBFWriteDoubleAttribute (dbf_file, i, avg_ninfected_field_index, local_data->ninfected[i]);
      DBFWriteDoubleAttribute (dbf_file, i, avg_ndestroyed_field_index, local_data->ndestroyed[i]);
      DBFWriteDoubleAttribute (dbf_file, i, avg_nvaccinated_field_index, local_data->nvaccinated[i]);
      DBFWriteDoubleAttribute (dbf_file, i, avg_frinfected_field_index, local_data->ninfected[i] / nunits);
      DBFWriteDoubleAttribute (dbf_file, i, avg_frdestroyed_field_index, local_data->ndestroyed[i] / nunits);
      DBFWriteDoubleAttribute (dbf_file, i, avg_frvaccinated_field_index, local_data->nvaccinated[i] / nunits);
    }
  if (dbf_file != NULL)
    DBFClose (dbf_file);
  g_free (dbf_filename);

  /* Clean up. */
  g_free (vertex_y);
  g_free (vertex_x);

  #if DEBUG
    g_debug ("----- EXIT write_shapefile (%s)", MODEL_NAME);
  #endif
  
  return;
}