File: scale.c

package info (click to toggle)
grass 6.0.2-6
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 40,044 kB
  • ctags: 31,303
  • sloc: ansic: 321,125; tcl: 25,676; sh: 11,176; cpp: 10,098; makefile: 5,025; fortran: 1,846; yacc: 493; lex: 462; perl: 133; sed: 1
file content (134 lines) | stat: -rw-r--r-- 2,909 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* Function: scale
**
** This function returns the horizontal extent of the map in inches and
** modifies the text string.  Much of this code is from p.map's scale.c.
**
** Author: Paul W. Carlson	April 1992
*/
#include <stdlib.h>
#include <string.h>
#include "local_proto.h"
#include "ps_info.h"

#define METERS_TO_INCHES ((double)39.37)
#define MILES_TO_INCHES  ((double)5280*12)
#define PWIDTH	(PS.page_width-PS.left_marg-PS.right_marg)
static double do_scale(char *);

#ifdef __GNUC_MINOR__
static int OOPS (void) __attribute__ ((__noreturn__));
#else
static int OOPS();
#endif

double scale(char *text)
{
    double inches;

    inches = do_scale(text);
    return inches;
}

static double do_scale(char *text)
{
    char unit1[30];
    char unit2[30];
    char equals[30];
    char dummy[2];
    long n1,n2;
    double u1,u2;

/*
* absolute horizontal width specification
*   x inches
*   x panels
* convert text to 1 : n
*/
    u1 = 0;
    *unit1 = 0;
    *dummy = 0;
    if (sscanf(text, "%lf %s %1s", &u1, unit1, dummy) == 2 && *dummy == 0)
    {
	u2 = -1;
	if (strncmp(unit1, "panel", 5) == 0 && u1 > 0) u2 = u1 * (PWIDTH);
	else if (strncmp(unit1, "inch", 4) == 0 && u1 > 0) u2 = u1;
	if (u2 > 0)
	{
	    sprintf(text, "1 : %.0f",
		METERS_TO_INCHES * distance(PS.w.east, PS.w.west) / u2);
	    return u2;
	}
    }

/*
* unitless ratio specification
*    n : m
*/
    *dummy = 0;
    n1 = n2 = 0;
    if (sscanf(text, "%ld : %ld%1s", &n1, &n2, dummy) == 2)
    {
	if (n1 <= 0 || n2 <= 0 || *dummy) OOPS();
	sprintf(text, "%ld : %ld", n1, n2);
	return METERS_TO_INCHES * distance(PS.w.east, PS.w.west) * n1 / n2;
    }

/*
*
* ratio specification with unit conversions
*    x inches equals y miles
*    x inches equals y meters
*    x inches equals y kilometers
*/

    *unit1 = 0;
    *unit2 = 0;
    *equals = 0;
    n1 = n2 = 0;
    if (sscanf(text, "%ld %s %s %ld %s", &n1, unit1, equals, &n2, unit2) == 5)
    {
	if (n1 <= 0 || n2 <= 0) OOPS();
	if (strcmp(equals, "=") != 0 && strncmp(equals, "equal",5) != 0) OOPS();

/* unit1: inches */
	if (strncmp(unit1, "inch", 4) == 0) u1 = n1;
	else OOPS();

/* unit2: meters, miles, kilometers */
	if (strncmp(unit2, "mile", 4) == 0)
	{
	    u2 = MILES_TO_INCHES;
	    strcpy(unit2, "mile");
	}
	else if (strncmp(unit2, "meter", 5) == 0)
	{
	    u2 = METERS_TO_INCHES;
	    strcpy(unit2, "meter");
	}
	else if (strncmp(unit2, "kilometer", 9) == 0)
	{
	    u2 = METERS_TO_INCHES * 1000;
	    strcpy(unit2, "kilometer");
	}
	else OOPS();
	u2 *= n2;

	strcpy(unit1, "inch");
	strcpy(equals, "equal");
	if (n1 == 1) strcat(equals, "s");
	else strcat(unit1, "es");

	if (n2 != 1) strcat(unit2, "s");

	sprintf(text, "%ld %s %s %ld %s", n1, unit1, equals, n2, unit2);

	return METERS_TO_INCHES * distance(PS.w.east, PS.w.west) * u1 / u2;
    }
    OOPS();
}

static int OOPS (void)
{
    G_fatal_error("PSmap: do_scale(): shouldn't happen");
    exit(1);
}