Back to index

plt-scheme  4.2.1
Defines | Functions
plmap.c File Reference
#include "plplotP.h"

Go to the source code of this file.

Defines

#define MAP_FILE   ".map"
#define OFFSET   (180*100)
#define SCALE   100.0
#define W_BUFSIZ   (32*1024)
#define NSEG   100

Functions

void plmap (void(*mapform)(PLINT, PLFLT *, PLFLT *), char *type, PLFLT minlong, PLFLT maxlong, PLFLT minlat, PLFLT maxlat)
void plmeridians (void(*mapform)(PLINT, PLFLT *, PLFLT *), PLFLT dlong, PLFLT dlat, PLFLT minlong, PLFLT maxlong, PLFLT minlat, PLFLT maxlat)

Define Documentation

#define MAP_FILE   ".map"

Definition at line 83 of file plmap.c.

#define NSEG   100

Definition at line 251 of file plmap.c.

#define OFFSET   (180*100)

Definition at line 84 of file plmap.c.

#define SCALE   100.0

Definition at line 85 of file plmap.c.

#define W_BUFSIZ   (32*1024)

Definition at line 86 of file plmap.c.


Function Documentation

void plmap ( void(*)(PLINT, PLFLT *, PLFLT *)  mapform,
char *  type,
PLFLT  minlong,
PLFLT  maxlong,
PLFLT  minlat,
PLFLT  maxlat 
)

Definition at line 89 of file plmap.c.

{
    PLINT wrap, sign;
    int i, j;
    PLFLT bufx[200], bufy[200], x[2], y[2];
    short int test[400];
    register PDFstrm *in;
    char filename[100];

    unsigned char n_buff[2], buff[800];
    int n;
    long int t;

    /*
     * read map outline 
     */
    strcpy(filename,type);
    strcat(filename,MAP_FILE);

    if ((in = plLibOpenPdfstrm(filename)) == NULL)
       return;

    for (;;) {
       /* read in # points in segment */
       if (pdf_rdx(n_buff, sizeof (unsigned char)* 2, in) == 0) break;
       n = (n_buff[0] << 8) + n_buff[1];
       if (n == 0) break;

       pdf_rdx(buff, sizeof (unsigned char)*4*n, in);
       if (n == 1) continue;

       for (j = i = 0; i < n; i++, j += 2) {
           t = (buff[j] << 8) + buff[j+1];
           bufx[i] = (t - OFFSET) / SCALE;
       }
       for (i = 0; i < n; i++, j += 2) {
           t = (buff[j] << 8) + buff[j+1];
           bufy[i] = (t - OFFSET) / SCALE;
       }

       for (i = 0; i < n; i++) {
           while (bufx[i] < minlong) {
              bufx[i] += 360.0;
           }
           while (bufx[i] > maxlong) {
              bufx[i] -= 360.0;
           }
       }

       /* remove last 2 points if both outside of domain and won't plot */

/* AR: 18/11/01 
*       I have commented out the next section which supposedly
*       removes points that do not plot within the domain. 
*       
*       This code appears at any rate to be superseded by the next
*       block of code that checks for wrapping problems. Removing
*       this code seems to have fixed up the problems with mapping
*       function, but I do not wish to delete it outright just now in
*       case I have managed to miss something.
*/

/*     while (n > 1) {
           if ((bufx[n-1] < minlong && bufx[n-2] < minlong) ||
              (bufx[n-1] > maxlong && bufx[n-2] > maxlong) ||
              (bufy[n-1] < minlat && bufy[n-2] < minlat) ||
              (bufy[n-1] > maxlat && bufy[n-2] > maxlat)) {
              n--;
           }
           else {
              break;
           }
       }
       if (n <= 1) continue;
*/

       if (mapform != NULL) (*mapform)(n,bufx,bufy); /* moved transformation to here   */
                                                     /* so bound-checking worked right */

       wrap = 0;
       /* check for wrap around problems */
       for (i = 0; i < n-1; i++) {

         /* jc: this code is wrong, as the bufx/y are floats that are
            converted to ints before abs() is called. Thus, small
            differences are masked off. The proof that it is wrong is
            that when replacing abs() with fabs(), as it should be,
            the code works the wrong way. What a proof :-)

           test[i] = abs((bufx[i]-bufx[i+1])) > abs(bufy[i]/3);

           If the intended behaviour is *really* that, than an
           explicit cast should be used to help other programmers, as
           is done bellow!!!
         */

           test[i] = abs((int)(bufx[i]-bufx[i+1])) > abs((int)bufy[i]/3); /* Changed this from 30 degrees so it is now "polar sensitive" */
           if (test[i]) wrap = 1;
       }

       if (wrap == 0) {     
           plline(n,bufx,bufy);
       }
       else {
           for (i = 0; i < n-1; i++) {
              x[0] = bufx[i];
              x[1] = bufx[i+1];
              y[0] = bufy[i];
              y[1] = bufy[i+1];
              if (test[i] == 0) {
                  plline(2,x,y);
              }
              else {  /* this code seems to supercede the block commented out above */
                  /* segment goes off the edge */
                  sign = (x[1] > x[0]) ? 1 : -1;
                  x[1] -= sign * 360.0;
                  plline(2,x,y);
                  x[0] = bufx[i];
                  x[1] = bufx[i+1];
                  y[0] = bufy[i];
                  y[1] = bufy[i+1];
                  x[0] += sign * 360.0;
                  plline(2,x,y);
              }
           }
       }
    }
}

Here is the call graph for this function:

void plmeridians ( void(*)(PLINT, PLFLT *, PLFLT *)  mapform,
PLFLT  dlong,
PLFLT  dlat,
PLFLT  minlong,
PLFLT  maxlong,
PLFLT  minlat,
PLFLT  maxlat 
)

Definition at line 254 of file plmap.c.

{
    PLFLT yy, xx, temp, x[2], y[2], dx, dy;

    if (minlong > maxlong) {
       temp = minlong;
       minlong = maxlong;
       maxlong = temp;
    }
    if (minlat > maxlat) {
       temp = minlat;
       minlat = maxlat;
       maxlat = temp;
    }
    dx = (maxlong - minlong) / NSEG;
    dy = (maxlat - minlat) / NSEG;

    /* latitudes */

    for (yy = dlat * ceil(minlat/dlat); yy <= maxlat; yy += dlat) {
       if (mapform == NULL) {
           y[0] = y[1] = yy;
           x[0] = minlong;
           x[1] = maxlong;
           plline(2,x,y);
       }
       else {
           for (xx = minlong; xx < maxlong; xx += dx) {
               y[0] = y[1] = yy;
              x[0] = xx;
              x[1] = xx + dx;
              (*mapform)(2,x,y);
              plline(2,x,y);
           }
       }
    }

    /* longitudes */
 
    for (xx = dlong * ceil(minlong/dlong); xx <= maxlong; xx += dlong) {
        if (mapform == NULL) {
            x[0] = x[1] = xx;
            y[0] = minlat;
            y[1] = maxlat;
            plline(2,x,y);
        }
        else {
            for (yy = minlat; yy < maxlat; yy += dy) {
                x[0] = x[1] = xx;
                y[0] = yy;
                y[1] = yy + dy;
                (*mapform)(2,x,y);
                plline(2,x,y);
            }
        }
    }
}