diff options
| author | Frank Warmerdam <warmerdam@pobox.com> | 2010-03-16 12:44:36 +0000 |
|---|---|---|
| committer | Frank Warmerdam <warmerdam@pobox.com> | 2010-03-16 12:44:36 +0000 |
| commit | e4f028223c773d3d60c6e59e00653ff22e538c90 (patch) | |
| tree | ccb372db2f83167ac006f34c5a9892ef645d4669 /src | |
| parent | 4ea16fcba0dd2e67c62488beeaddf8a93b49fdf7 (diff) | |
| download | PROJ-e4f028223c773d3d60c6e59e00653ff22e538c90.tar.gz PROJ-e4f028223c773d3d60c6e59e00653ff22e538c90.zip | |
Rework the translation of nadgrids parameters into a list of gridshift files
to avoid use of static "lastnadgrids" information which screws up
multithreading. Changes the PJ structure.
git-svn-id: http://svn.osgeo.org/metacrs/proj/trunk@1831 4e78687f-474d-0410-85f9-8d5e500ac6b2
Diffstat (limited to 'src')
| -rw-r--r-- | src/pj_apply_gridshift.c | 95 | ||||
| -rw-r--r-- | src/pj_gridlist.c | 92 | ||||
| -rw-r--r-- | src/pj_init.c | 6 | ||||
| -rw-r--r-- | src/pj_transform.c | 18 | ||||
| -rw-r--r-- | src/projects.h | 9 |
5 files changed, 132 insertions, 88 deletions
diff --git a/src/pj_apply_gridshift.c b/src/pj_apply_gridshift.c index 34c7be74..50ff6e6a 100644 --- a/src/pj_apply_gridshift.c +++ b/src/pj_apply_gridshift.c @@ -38,6 +38,11 @@ /************************************************************************/ /* pj_apply_gridshift() */ +/* */ +/* This is the externally callable interface - part of the */ +/* public API - though it is not used internally any more and I */ +/* doubt it is used by any other applications. But we preserve */ +/* it to honour our public api. */ /************************************************************************/ int pj_apply_gridshift( const char *nadgrids, int inverse, @@ -45,17 +50,78 @@ int pj_apply_gridshift( const char *nadgrids, int inverse, double *x, double *y, double *z ) { - int grid_count = 0; - PJ_GRIDINFO **tables; + PJ_GRIDINFO **gridlist; + int grid_count; + int ret; + + gridlist = pj_gridlist_from_nadgrids( nadgrids, &grid_count ); + + if( gridlist == NULL || grid_count == 0 ) + return pj_errno; + + ret = pj_apply_gridshift_3( gridlist, grid_count, inverse, + point_count, point_offset, x, y, z ); + + /* + ** Note this frees the array of grid list pointers, but not the grids + ** which is as intended. The grids themselves live on. + */ + pj_dalloc( gridlist ); + + return ret; +} + +/************************************************************************/ +/* pj_apply_gridshift_2() */ +/* */ +/* This implmentation takes uses the gridlist from a coordinate */ +/* system definition. If the gridlist has not yet been */ +/* populated in the coordinate system definition we set it up */ +/* now. */ +/************************************************************************/ + +int pj_apply_gridshift_2( PJ *defn, int inverse, + long point_count, int point_offset, + double *x, double *y, double *z ) + +{ + if( defn->gridlist == NULL ) + { + defn->gridlist = + pj_gridlist_from_nadgrids( pj_param(defn->params,"snadgrids").s, + &(defn->gridlist_count) ); + + if( defn->gridlist == NULL || defn->gridlist_count == 0 ) + return pj_errno; + } + + return pj_apply_gridshift_3( defn->gridlist, defn->gridlist_count, inverse, + point_count, point_offset, x, y, z ); +} + + +/************************************************************************/ +/* pj_apply_gridshift_3() */ +/* */ +/* This is the real workhorse, given a gridlist. */ +/************************************************************************/ + +int pj_apply_gridshift_3( PJ_GRIDINFO **tables, int grid_count, + int inverse, long point_count, int point_offset, + double *x, double *y, double *z ) + +{ int i; int debug_flag = getenv( "PROJ_DEBUG" ) != NULL; static int debug_count = 0; - pj_errno = 0; - - tables = pj_gridlist_from_nadgrids( nadgrids, &grid_count); if( tables == NULL || grid_count == 0 ) - return pj_errno; + { + pj_errno = -38; + return -38; + } + + pj_errno = 0; for( i = 0; i < point_count; i++ ) { @@ -109,7 +175,7 @@ int pj_apply_gridshift( const char *nadgrids, int inverse, if( ct->cvs == NULL && !pj_gridinfo_load( gi ) ) { pj_errno = -38; - return pj_errno; + return -38; } output = nad_cvt( input, inverse, ct ); @@ -132,12 +198,19 @@ int pj_apply_gridshift( const char *nadgrids, int inverse, " location (%.7fdW,%.7fdN)\n", x[io] * RAD_TO_DEG, y[io] * RAD_TO_DEG ); - fprintf( stderr, - " tried: %s\n", nadgrids ); + for( itable = 0; itable < grid_count; itable++ ) + { + PJ_GRIDINFO *gi = tables[itable]; + if( itable == 0 ) + fprintf( stderr, " tried: %s", gi->gridname ); + else + fprintf( stderr, ",%s", gi->gridname ); + } + fprintf( stderr, "\n" ); } - + pj_errno = PJD_ERR_GRID_AREA; - return pj_errno; + return PJD_ERR_GRID_AREA; } else { diff --git a/src/pj_gridlist.c b/src/pj_gridlist.c index 68637595..52b44e42 100644 --- a/src/pj_gridlist.c +++ b/src/pj_gridlist.c @@ -46,13 +46,6 @@ static PJ_GRIDINFO *grid_list = NULL; -/* used only by pj_load_nadgrids() and pj_deallocate_grids() */ - -static int last_nadgrids_max = 0; -static int last_nadgrids_count = 0; -static PJ_GRIDINFO **last_nadgrids_list = NULL; -static char *last_nadgrids = NULL; - /************************************************************************/ /* pj_deallocate_grids() */ /* */ @@ -70,18 +63,6 @@ void pj_deallocate_grids() pj_gridinfo_free( item ); } - - if( last_nadgrids != NULL ) - { - pj_dalloc( last_nadgrids ); - last_nadgrids = NULL; - - pj_dalloc( last_nadgrids_list ); - last_nadgrids_list = NULL; - - last_nadgrids_count = 0; - last_nadgrids_max = 0; - } } /************************************************************************/ @@ -91,7 +72,10 @@ void pj_deallocate_grids() /* last_nadgrids_list. */ /************************************************************************/ -static int pj_gridlist_merge_gridfile( const char *gridname ) +static int pj_gridlist_merge_gridfile( const char *gridname, + PJ_GRIDINFO ***p_gridlist, + int *p_gridcount, + int *p_gridmax ) { int got_match=0; @@ -113,26 +97,26 @@ static int pj_gridlist_merge_gridfile( const char *gridname ) return 0; /* do we need to grow the list? */ - if( last_nadgrids_count >= last_nadgrids_max - 2 ) + if( *p_gridcount >= *p_gridmax - 2 ) { PJ_GRIDINFO **new_list; - int new_max = last_nadgrids_max + 20; + int new_max = *p_gridmax + 20; new_list = (PJ_GRIDINFO **) pj_malloc(sizeof(void*) * new_max); - if( last_nadgrids_list != NULL ) + if( *p_gridlist != NULL ) { - memcpy( new_list, last_nadgrids_list, - sizeof(void*) * last_nadgrids_max ); - pj_dalloc( last_nadgrids_list ); + memcpy( new_list, *p_gridlist, + sizeof(void*) * (*p_gridmax) ); + pj_dalloc( *p_gridlist ); } - last_nadgrids_list = new_list; - last_nadgrids_max = new_max; + *p_gridlist = new_list; + *p_gridmax = new_max; } /* add to the list */ - last_nadgrids_list[last_nadgrids_count++] = this_grid; - last_nadgrids_list[last_nadgrids_count] = NULL; + (*p_gridlist)[(*p_gridcount)++] = this_grid; + (*p_gridlist)[*p_gridcount] = NULL; } tail = this_grid; @@ -161,7 +145,8 @@ static int pj_gridlist_merge_gridfile( const char *gridname ) /* -------------------------------------------------------------------- */ /* Recurse to add the grid now that it is loaded. */ /* -------------------------------------------------------------------- */ - return pj_gridlist_merge_gridfile( gridname ); + return pj_gridlist_merge_gridfile( gridname, p_gridlist, + p_gridcount, p_gridmax ); } /************************************************************************/ @@ -178,35 +163,13 @@ PJ_GRIDINFO **pj_gridlist_from_nadgrids( const char *nadgrids, int *grid_count) { const char *s; + PJ_GRIDINFO **gridlist = NULL; + int grid_max = 0; pj_errno = 0; *grid_count = 0; pj_acquire_lock(); - if( last_nadgrids != NULL - && strcmp(nadgrids,last_nadgrids) == 0 ) - { - PJ_GRIDINFO **ret = last_nadgrids_list; - *grid_count = last_nadgrids_count; - if( *grid_count == 0 ) - pj_errno = -38; - - pj_release_lock(); - return ret; - } - -/* -------------------------------------------------------------------- */ -/* Free old one, if any, and make space for new list. */ -/* -------------------------------------------------------------------- */ - if( last_nadgrids != NULL ) - { - pj_dalloc(last_nadgrids); - } - - last_nadgrids = (char *) pj_malloc(strlen(nadgrids)+1); - strcpy( last_nadgrids, nadgrids ); - - last_nadgrids_count = 0; /* -------------------------------------------------------------------- */ /* Loop processing names out of nadgrids one at a time. */ @@ -241,7 +204,9 @@ PJ_GRIDINFO **pj_gridlist_from_nadgrids( const char *nadgrids, int *grid_count) if( *s == ',' ) s++; - if( !pj_gridlist_merge_gridfile( name ) && required ) + if( !pj_gridlist_merge_gridfile( name, &gridlist, grid_count, + &grid_max) + && required ) { pj_errno = -38; pj_release_lock(); @@ -251,16 +216,7 @@ PJ_GRIDINFO **pj_gridlist_from_nadgrids( const char *nadgrids, int *grid_count) pj_errno = 0; } - if( last_nadgrids_count > 0 ) - { - PJ_GRIDINFO **ret = last_nadgrids_list; - *grid_count = last_nadgrids_count; - pj_release_lock(); - return ret; - } - else - { - pj_release_lock(); - return NULL; - } + pj_release_lock(); + + return gridlist; } diff --git a/src/pj_init.c b/src/pj_init.c index 9f336073..87d5ca8d 100644 --- a/src/pj_init.c +++ b/src/pj_init.c @@ -271,6 +271,8 @@ pj_init(int argc, char **argv) { PIN->is_long_wrap_set = 0; PIN->long_wrap_center = 0.0; strcpy( PIN->axis, "enu" ); + PIN->gridlist = NULL; + PIN->gridlist_count = 0; /* set datum parameters */ if (pj_datum_set(start, PIN)) goto bum_call; @@ -439,6 +441,10 @@ pj_free(PJ *P) { pj_dalloc(t); } + /* free array of grid pointers if we have one */ + if( P->gridlist != NULL ) + pj_dalloc( P->gridlist ); + /* free projection parameters */ P->pfree(P); } diff --git a/src/pj_transform.c b/src/pj_transform.c index eaf060eb..94f7d6ed 100644 --- a/src/pj_transform.c +++ b/src/pj_transform.c @@ -89,6 +89,7 @@ int pj_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset, { long i; + int err; pj_errno = 0; @@ -132,10 +133,11 @@ int pj_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset, } } - if( pj_geocentric_to_geodetic( srcdefn->a_orig, srcdefn->es_orig, - point_count, point_offset, - x, y, z ) != 0) - return pj_errno; + err = pj_geocentric_to_geodetic( srcdefn->a_orig, srcdefn->es_orig, + point_count, point_offset, + x, y, z ); + if( err != 0 ) + return err; } /* -------------------------------------------------------------------- */ @@ -152,7 +154,7 @@ int pj_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset, fprintf( stderr, "pj_transform(): source projection not invertable\n" ); } - return pj_errno; + return -17; } for( i = 0; i < point_count; i++ ) @@ -604,8 +606,7 @@ int pj_datum_transform( PJ *srcdefn, PJ *dstdefn, /* -------------------------------------------------------------------- */ if( srcdefn->datum_type == PJD_GRIDSHIFT ) { - pj_apply_gridshift( pj_param(srcdefn->params,"snadgrids").s, 0, - point_count, point_offset, x, y, z ); + pj_apply_gridshift_2( srcdefn, 0, point_count, point_offset, x, y, z ); CHECK_RETURN; src_a = SRS_WGS84_SEMIMAJOR; @@ -664,8 +665,7 @@ int pj_datum_transform( PJ *srcdefn, PJ *dstdefn, /* -------------------------------------------------------------------- */ if( dstdefn->datum_type == PJD_GRIDSHIFT ) { - pj_apply_gridshift( pj_param(dstdefn->params,"snadgrids").s, 1, - point_count, point_offset, x, y, z ); + pj_apply_gridshift_2( dstdefn, 1, point_count, point_offset, x, y, z ); CHECK_RETURN; } diff --git a/src/projects.h b/src/projects.h index dcd5b652..fcc9e48d 100644 --- a/src/projects.h +++ b/src/projects.h @@ -234,6 +234,8 @@ typedef struct PJconsts { int datum_type; /* PJD_UNKNOWN/3PARAM/7PARAM/GRIDSHIFT/WGS84 */ double datum_params[7]; + struct _pj_gi **gridlist; + int gridlist_count; double from_greenwich; /* prime meridian offset (in radians) */ double long_wrap_center; /* 0.0 for -180 to 180, actually in radians*/ int is_long_wrap_set; @@ -401,6 +403,13 @@ void nad_free(struct CTABLE *); /* higher level handling of datum grid shift files */ +int pj_apply_gridshift_2( PJ *defn, int inverse, + long point_count, int point_offset, + double *x, double *y, double *z ); +int pj_apply_gridshift_3( PJ_GRIDINFO **gridlist, int gridlist_count, + int inverse, long point_count, int point_offset, + double *x, double *y, double *z ); + PJ_GRIDINFO **pj_gridlist_from_nadgrids( const char *, int * ); void pj_deallocate_grids(); |
