Logo Search packages:      
Sourcecode: r-cran-mapproj version File versions  Download package

mapproject.c

#include "R.h"
#include "map.h"

#define MIN(a,b)  (a)<(b)?(a):(b)
#define MAX(a,b)  (a)>(b)?(a):(b)
#define ABS(x)          ((x)<0?-(x):(x))
#define RAD2DEG(x)      ((x)*180/PI)
#define DEG2RAD(x)      ((x)*PI/180)

/* must be consistent with map.h in maps library */
#define XMIN            0
#define XMAX            1
#define YMIN            2
#define YMAX            3

static int (*projfun)();

00018 struct index {
      char *name;
      proj (*prog)();
      int npar;
} mapindex[] = {
      {"mercator", mercator, 0},
      {"cylindrical", cylindrical, 0},
      {"cylequalarea", cylequalarea, 1},
      {"rectangular", rectangular, 1},
      {"trapezoidal", trapezoidal, 2},
      {"lune",lune,2},
      {"gall", gall, 1},
      {"sinusoidal", sinusoidal, 0},
      {"mollweide", mollweide, 0},
      {"gilbert", gilbert, 0},
      {"azequidistant", azequidistant, 0},
      {"azequalarea", azequalarea, 0},
      {"gnomonic", gnomonic, 0},
      {"perspective", map_perspective, 1},
      {"harrison", harrison, 2},
      {"orthographic", orthographic, 0},
      {"stereographic", stereographic, 0},
      {"laue", laue, 0},
      {"fisheye", fisheye, 1},
      {"newyorker", newyorker, 1},
      {"conic", conic, 1},
      {"lambert", lambert, 2},
      {"albers", albers, 2},
      {"bonne", bonne, 1},
      {"polyconic", polyconic, 0},
      {"aitoff", aitoff, 0},
      {"globular", globular, 0},
      {"vandergrinten", vandergrinten, 0},
      {"eisenlohr", eisenlohr, 0},
      {"guyou",guyou,0},
      {"square",square,0},
      {"tetra",tetra,0},
      {"hex",map_hex,0},
      {"lagrange",lagrange,0},
      {"bicentric", bicentric, 1},
      {"elliptic", elliptic, 1},
      {"mecca", mecca, 1},
      {"simpleconic", simpleconic, 2},
      {"homing", homing, 1},
      {"sp_mercator", sp_mercator, 0},
      {"sp_albers", sp_albers, 2},
      {NULL,NULL,0},
};

void setproj(name, par, n, o, error)
     char **name, **error;
     double par[], o[];
     int *n;
{
  struct index *i, *theproj = 0;
  static char errbuf[200];

  *error = "";
  if(**name == 0) {
    *error = "Null projection specified";
    return;
  }
  for(i = mapindex; i->name != 0; i++) {
    if(strncmp(*name, i->name, strlen(*name)) == 0) {
      if(theproj) {
      sprintf(errbuf, "Ambiguous projection specified: %s or %s?", theproj->name, i->name);
      *error = errbuf;
      return;
      }
      if(*n != i->npar) {
      sprintf(errbuf, "%s projection requires %d parameter%s", i->name, i->npar, i->npar>1?"s":"");
      *error = errbuf;
      return;
      }
      if(strcmp(i->name, "bicentric") == 0 ||
       strcmp(i->name, "elliptic") == 0)
      par[0] = -par[0];
      switch(*n) {
      case 0: projfun = (i->prog)(); break;
      case 1: projfun = (i->prog)(par[0]); break;
      case 2: projfun = (i->prog)(par[0], par[1]); break;
      }
      theproj = i;
    }
  }
  if(theproj == 0) {
    sprintf(errbuf, "Unknown projection: %s", *name);
    *error = errbuf;
    return;
  }
  orient(o[0], -o[1], -o[2]);
}

static int project(lon, lat, x, y)
     double lon, lat;
     double *x, *y;
{
  struct place p;

  if(projfun == 0) {
    *x = lon;
    *y = lat;
    return(1);
  }
  lon = DEG2RAD(lon);
  lat = DEG2RAD(lat);
  p.wlon.l = -lon; p.wlon.s = sin(-lon); p.wlon.c = cos(-lon);
  p.nlat.l = lat; p.nlat.s = sin(lat); p.nlat.c = cos(lat);
  normalize(&p);
  return((*projfun)(&p, x, y));
}

void doproj(lon, lat, n, range, error)
     double lon[], lat[], range[];
     int *n, *error;
{
  int i, ok;
  double x, y;

  *error = 0;
  range[XMIN] = range[YMIN] = SINGLE_XMAX;
  range[XMAX] = range[YMAX] = -SINGLE_XMAX;
  for(i = 0; i < *n; i++, lon++, lat++) {
    if(ISNA(*lon) || ISNA(*lat))
      continue;
    ok = 1 == project(*lon, *lat, &x, &y);
    if(!ok || ABS(x) > SINGLE_XMAX || ABS(y) > SINGLE_XMAX) {
      *error = 1;
      *lon = NA_REAL;
      *lat = NA_REAL;
    } else {
      *lon = x;
      *lat = y;
      range[XMIN] = MIN(range[XMIN], x);
      range[XMAX] = MAX(range[XMAX], x);
      range[YMIN] = MIN(range[YMIN], y);
      range[YMAX] = MAX(range[YMAX], y);
    }
  }
}


Generated by  Doxygen 1.6.0   Back to index