aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFrank Warmerdam <warmerdam@pobox.com>2010-03-16 12:44:36 +0000
committerFrank Warmerdam <warmerdam@pobox.com>2010-03-16 12:44:36 +0000
commite4f028223c773d3d60c6e59e00653ff22e538c90 (patch)
treeccb372db2f83167ac006f34c5a9892ef645d4669 /src
parent4ea16fcba0dd2e67c62488beeaddf8a93b49fdf7 (diff)
downloadPROJ-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.c95
-rw-r--r--src/pj_gridlist.c92
-rw-r--r--src/pj_init.c6
-rw-r--r--src/pj_transform.c18
-rw-r--r--src/projects.h9
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();