~ubuntu-branches/ubuntu/warty/proj/warty

« back to all changes in this revision

Viewing changes to src/pj_apply_gridshift.c

  • Committer: Bazaar Package Importer
  • Author(s): Peter S Galbraith
  • Date: 2003-05-02 22:56:05 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20030502225605-psu6gl4cs31ezg9g
Tags: 4.4.7-3
autoreconf with libtool from unstable so that package may build on
mips (closes: #188684)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
 
 * $Id: pj_apply_gridshift.c,v 1.2 2001/03/15 16:57:55 warmerda Exp $
 
2
 * $Id: pj_apply_gridshift.c,v 1.8 2003/03/20 21:29:41 warmerda Exp $
3
3
 *
4
4
 * Project:  PROJ.4
5
5
 * Purpose:  Apply datum shifts based on grid shift files (normally NAD27 to
6
6
 *           NAD83 or the reverse).  This module is responsible for keeping
7
7
 *           a list of loaded grids, and calling with each one that is 
8
8
 *           allowed for a given datum (expressed as the nadgrids= parameter).
9
 
 * Author:   Frank Warmerdam, warmerda@home.com
 
9
 * Author:   Frank Warmerdam, warmerdam@pobox.com
10
10
 *
11
11
 ******************************************************************************
12
 
 * Copyright (c) 2000, Frank Warmerdam
 
12
 * Copyright (c) 2000, Frank Warmerdam <warmerdam@pobox.com>
13
13
 *
14
14
 * Permission is hereby granted, free of charge, to any person obtaining a
15
15
 * copy of this software and associated documentation files (the "Software"),
31
31
 ******************************************************************************
32
32
 *
33
33
 * $Log: pj_apply_gridshift.c,v $
 
34
 * Revision 1.8  2003/03/20 21:29:41  warmerda
 
35
 * Fixed bug in checking against grid bounds.
 
36
 *
 
37
 * Revision 1.7  2003/03/17 19:45:23  warmerda
 
38
 * improved error handling
 
39
 *
 
40
 * Revision 1.6  2003/03/17 18:56:34  warmerda
 
41
 * implement heirarchical NTv2 gridinfos
 
42
 *
 
43
 * Revision 1.5  2003/03/15 06:02:02  warmerda
 
44
 * preliminary NTv2 support, major restructure of datum shifting
 
45
 *
 
46
 * Revision 1.4  2002/07/08 02:32:05  warmerda
 
47
 * ensure clean C++ builds
 
48
 *
 
49
 * Revision 1.3  2002/04/30 16:27:27  warmerda
 
50
 * improve debug output
 
51
 *
34
52
 * Revision 1.2  2001/03/15 16:57:55  warmerda
35
53
 * fixed intermittent problem in pj_load_nadgrids()
36
54
 *
45
63
#include <string.h>
46
64
#include <math.h>
47
65
 
48
 
#define GRID_MAX 100
49
 
 
50
 
/* used only by pj_get_grid() and pj_deallocate_grids() */
51
 
static int grid_count = 0;
52
 
static char **grid_names = NULL;
53
 
static struct CTABLE **grid_list = NULL;
54
 
 
55
 
/* used only by pj_load_nadgrids() and pj_deallocate_grids() */
56
 
static struct CTABLE **last_nadgrids_list = NULL;
57
 
static char          *last_nadgrids = NULL;
58
 
 
59
 
/************************************************************************/
60
 
/*                        pj_deallocate_grids()                         */
61
 
/*                                                                      */
62
 
/*      Deallocate all loaded grids.                                    */
63
 
/************************************************************************/
64
 
 
65
 
void pj_deallocate_grids()
66
 
 
67
 
{
68
 
    if( grid_count > 0 )
69
 
    {
70
 
        int        i;
71
 
 
72
 
        for( i = 0; i < grid_count; i++ )
73
 
        {
74
 
            if( grid_list[i] != NULL )
75
 
                nad_free( grid_list[i] );
76
 
            pj_dalloc( grid_names[i] );
77
 
        }
78
 
         
79
 
        pj_dalloc( grid_names );
80
 
        pj_dalloc( grid_list );
81
 
 
82
 
        grid_names = NULL;
83
 
        grid_list = NULL;
84
 
 
85
 
        grid_count = 0;
86
 
    }
87
 
 
88
 
    if( last_nadgrids != NULL )
89
 
    {
90
 
        pj_dalloc( last_nadgrids );
91
 
        last_nadgrids = NULL;
92
 
 
93
 
        pj_dalloc( last_nadgrids_list );
94
 
        last_nadgrids_list = NULL;
95
 
    }
96
 
}
97
 
 
98
 
/************************************************************************/
99
 
/*                            pj_get_grid()                             */
100
 
/*                                                                      */
101
 
/*      Find the requested grid in the list, or if not present, try     */
102
 
/*      and load it.  On failure returns NULL and sets pj_errno.        */
103
 
/************************************************************************/
104
 
 
105
 
static struct CTABLE *pj_get_grid( const char *name )
106
 
 
107
 
{
108
 
    int   i;
109
 
 
110
 
/* -------------------------------------------------------------------- */
111
 
/*      First look in the existing list.                                */
112
 
/* -------------------------------------------------------------------- */
113
 
    for( i = 0; i < grid_count; i++ )
114
 
    {
115
 
        if( strcmp( grid_names[i], name ) == 0 )
116
 
        {
117
 
            if( grid_list[i] == NULL )
118
 
                pj_errno = -38;
119
 
 
120
 
            return grid_list[i];
121
 
        }
122
 
    }
123
 
 
124
 
/* -------------------------------------------------------------------- */
125
 
/*      Add entry for this file in the grid list.                       */
126
 
/* -------------------------------------------------------------------- */
127
 
    if( grid_count == 0 )
128
 
    {
129
 
        grid_names = pj_malloc(sizeof(char *) * GRID_MAX);
130
 
        memset( grid_names, 0, sizeof(char *) * GRID_MAX );
131
 
        grid_list = pj_malloc(sizeof(struct CTABLE *) * GRID_MAX );
132
 
        memset( grid_list, 0, sizeof(struct CTABLE *) * GRID_MAX );
133
 
    }
134
 
    else if( grid_count >= GRID_MAX )
135
 
    {
136
 
        pj_errno = -38;
137
 
        return NULL;
138
 
    }
139
 
 
140
 
    grid_count++;
141
 
 
142
 
    grid_names[grid_count-1] = (char *) pj_malloc(strlen(name)+1);
143
 
    strcpy( grid_names[grid_count-1], name );
144
 
 
145
 
/* -------------------------------------------------------------------- */
146
 
/*      Read the file.                                                  */
147
 
/* -------------------------------------------------------------------- */
148
 
    grid_list[grid_count-1] = nad_init( (char *) name );
149
 
 
150
 
    return grid_list[grid_count-1];
151
 
}
152
 
 
153
 
/************************************************************************/
154
 
/*                          pj_load_nadgrids()                          */
155
 
/*                                                                      */
156
 
/*      This functions loads the list of grids corresponding to a       */
157
 
/*      particular nadgrids string into a list, and returns it.  The    */
158
 
/*      list is kept around till a request is made with a different     */
159
 
/*      string in order to cut down on the string parsing cost, and     */
160
 
/*      the cost of building the list of tables each time.              */
161
 
/************************************************************************/
162
 
 
163
 
static struct CTABLE **pj_load_nadgrids( const char *nadgrids )
164
 
 
165
 
{
166
 
    int     nadgrids_count = 0;
167
 
    const char *s;
168
 
 
169
 
    pj_errno = 0;
170
 
 
171
 
    if( last_nadgrids != NULL 
172
 
        && strcmp(nadgrids,last_nadgrids) == 0 )
173
 
        return last_nadgrids_list;
174
 
 
175
 
/* -------------------------------------------------------------------- */
176
 
/*      Free old one, if any, and make space for new list.              */
177
 
/* -------------------------------------------------------------------- */
178
 
    if( last_nadgrids != NULL )
179
 
    {
180
 
        pj_dalloc(last_nadgrids);
181
 
    }
182
 
    
183
 
    last_nadgrids = (char *) pj_malloc(strlen(nadgrids)+1);
184
 
    strcpy( last_nadgrids, nadgrids );
185
 
 
186
 
    if( last_nadgrids_list == NULL )
187
 
        last_nadgrids_list = (struct CTABLE **) 
188
 
            pj_malloc(sizeof(struct CTABLE *) * GRID_MAX);
189
 
 
190
 
/* -------------------------------------------------------------------- */
191
 
/*      Loop processing names out of nadgrids one at a time.            */
192
 
/* -------------------------------------------------------------------- */
193
 
    for( s = nadgrids; *s != '\0'; )
194
 
    {
195
 
        int   end_char;
196
 
        char  name[128];
197
 
 
198
 
        for( end_char = 0; 
199
 
             s[end_char] != '\0' && s[end_char] != ','; 
200
 
             end_char++ ) {}
201
 
 
202
 
        if( end_char > sizeof(name) )
203
 
        {
204
 
            pj_errno = -38;
205
 
            return NULL;
206
 
        }
207
 
        
208
 
        strncpy( name, s, end_char );
209
 
        name[end_char] = '\0';
210
 
 
211
 
        s += end_char;
212
 
        if( *s == ',' )
213
 
            s++;
214
 
 
215
 
 
216
 
        last_nadgrids_list[nadgrids_count] = pj_get_grid( name );
217
 
        if( last_nadgrids_list[nadgrids_count] == NULL )
218
 
            return NULL;
219
 
 
220
 
        nadgrids_count++;
221
 
    }
222
 
 
223
 
    last_nadgrids_list[nadgrids_count] = NULL;
224
 
 
225
 
    return last_nadgrids_list;
226
 
}
227
 
 
228
66
/************************************************************************/
229
67
/*                         pj_apply_gridshift()                         */
230
68
/************************************************************************/
234
72
                        double *x, double *y, double *z )
235
73
 
236
74
{
237
 
    struct CTABLE   **tables = pj_load_nadgrids( nadgrids );
 
75
    int grid_count = 0;
 
76
    PJ_GRIDINFO   **tables;
238
77
    int  i;
239
 
 
240
 
    if( tables == NULL )
 
78
    int debug_flag = getenv( "PROJ_DEBUG" ) != NULL;
 
79
    static int debug_count = 0;
 
80
 
 
81
    pj_errno = 0;
 
82
 
 
83
    tables = pj_gridlist_from_nadgrids( nadgrids, &grid_count);
 
84
    if( tables == NULL || grid_count == 0 )
241
85
        return pj_errno;
242
86
 
243
87
    for( i = 0; i < point_count; i++ )
248
92
 
249
93
        input.phi = y[io];
250
94
        input.lam = x[io];
 
95
        output.phi = HUGE_VAL;
 
96
        output.lam = HUGE_VAL;
251
97
 
252
98
        /* keep trying till we find a table that works */
253
 
        for( itable = 0; tables[itable] != NULL; itable++ )
 
99
        for( itable = 0; itable < grid_count; itable++ )
254
100
        {
255
 
            output = nad_cvt( input, inverse, tables[itable] );
 
101
            PJ_GRIDINFO *gi = tables[itable];
 
102
            struct CTABLE *ct = gi->ct;
 
103
 
 
104
            /* skip tables that don't match our point at all.  */
 
105
            if( ct->ll.phi > input.phi || ct->ll.lam > input.lam
 
106
                || ct->ll.phi + (ct->lim.phi-1) * ct->del.phi < input.phi
 
107
                || ct->ll.lam + (ct->lim.lam-1) * ct->del.lam < input.lam )
 
108
                continue;
 
109
 
 
110
            /* If we have child nodes, check to see if any of them apply. */
 
111
            if( gi->child != NULL )
 
112
            {
 
113
                PJ_GRIDINFO *child;
 
114
 
 
115
                for( child = gi->child; child != NULL; child = child->next )
 
116
                {
 
117
                    struct CTABLE *ct1 = child->ct;
 
118
 
 
119
                    if( ct1->ll.phi > input.phi || ct1->ll.lam > input.lam
 
120
                      || ct1->ll.phi+(ct1->lim.phi-1)*ct1->del.phi < input.phi
 
121
                      || ct1->ll.lam+(ct1->lim.lam-1)*ct1->del.lam < input.lam)
 
122
                        continue;
 
123
 
 
124
                    break;
 
125
                }
 
126
 
 
127
                /* we found a more refined child node to use */
 
128
                if( child != NULL )
 
129
                {
 
130
                    gi = child;
 
131
                    ct = child->ct;
 
132
                }
 
133
            }
 
134
 
 
135
            /* load the grid shift info if we don't have it. */
 
136
            if( ct->cvs == NULL && !pj_gridinfo_load( gi ) )
 
137
            {
 
138
                pj_errno = -38;
 
139
                return pj_errno;
 
140
            }
 
141
            
 
142
            output = nad_cvt( input, inverse, ct );
256
143
            if( output.lam != HUGE_VAL )
 
144
            {
 
145
                if( debug_flag && debug_count++ < 20 )
 
146
                    fprintf( stderr,
 
147
                             "pj_apply_gridshift(): used %s\n",
 
148
                             ct->id );
257
149
                break;
 
150
            }
258
151
        }
259
152
 
260
153
        if( output.lam == HUGE_VAL )
261
154
        {
 
155
            if( debug_flag )
 
156
            {
 
157
                fprintf( stderr, 
 
158
                         "pj_apply_gridshift(): failed to find a grid shift table for\n"
 
159
                         "                      location (%.7fdW,%.7fdN)\n",
 
160
                         x[io] * RAD_TO_DEG, 
 
161
                         y[io] * RAD_TO_DEG );
 
162
                fprintf( stderr, 
 
163
                         "   tried: %s\n", nadgrids );
 
164
            }
 
165
        
262
166
            pj_errno = -38;
263
167
            return pj_errno;
264
168
        }