aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile.in17
-rw-r--r--src/nad_init.c194
-rw-r--r--src/pj_apply_gridshift.c216
-rw-r--r--src/projects.h32
5 files changed, 77 insertions, 384 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 3806d09b..fedb8909 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -58,7 +58,7 @@ libproj_la_SOURCES = \
\
nad_cvt.c nad_init.c nad_intr.c emess.c emess.h \
pj_apply_gridshift.c pj_datums.c pj_datum_set.c pj_transform.c \
- geocent.c geocent.h pj_utils.c
+ geocent.c geocent.h pj_utils.c pj_gridinfo.c pj_gridlist.c
install-exec-local:
diff --git a/src/Makefile.in b/src/Makefile.in
index 73898766..9ae881ee 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -143,7 +143,7 @@ libproj_la_SOURCES = \
\
nad_cvt.c nad_init.c nad_intr.c emess.c emess.h \
pj_apply_gridshift.c pj_datums.c pj_datum_set.c pj_transform.c \
- geocent.c geocent.h pj_utils.c
+ geocent.c geocent.h pj_utils.c pj_gridinfo.c pj_gridlist.c
subdir = src
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -178,7 +178,8 @@ am_libproj_la_OBJECTS = PJ_aeqd.lo PJ_gnom.lo PJ_laea.lo PJ_mod_ster.lo \
pj_units.lo pj_zpoly1.lo rtodms.lo vector1.lo pj_release.lo \
nad_cvt.lo nad_init.lo nad_intr.lo emess.lo \
pj_apply_gridshift.lo pj_datums.lo pj_datum_set.lo \
- pj_transform.lo geocent.lo pj_utils.lo
+ pj_transform.lo geocent.lo pj_utils.lo pj_gridinfo.lo \
+ pj_gridlist.lo
libproj_la_OBJECTS = $(am_libproj_la_OBJECTS)
bin_PROGRAMS = proj$(EXEEXT) nad2nad$(EXEEXT) nad2bin$(EXEEXT) \
geod$(EXEEXT) cs2cs$(EXEEXT)
@@ -274,10 +275,12 @@ am__depfiles_maybe = depfiles
@AMDEP_TRUE@ ./$(DEPDIR)/pj_ell_set.Plo ./$(DEPDIR)/pj_ellps.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/pj_errno.Plo ./$(DEPDIR)/pj_factors.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/pj_fwd.Plo ./$(DEPDIR)/pj_geocent.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/pj_init.Plo ./$(DEPDIR)/pj_inv.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/pj_latlong.Plo ./$(DEPDIR)/pj_list.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/pj_malloc.Plo ./$(DEPDIR)/pj_mlfn.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/pj_msfn.Plo ./$(DEPDIR)/pj_open_lib.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/pj_gridinfo.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/pj_gridlist.Plo ./$(DEPDIR)/pj_init.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/pj_inv.Plo ./$(DEPDIR)/pj_latlong.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/pj_list.Plo ./$(DEPDIR)/pj_malloc.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/pj_mlfn.Plo ./$(DEPDIR)/pj_msfn.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/pj_open_lib.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/pj_param.Plo ./$(DEPDIR)/pj_phi2.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/pj_pr_list.Plo ./$(DEPDIR)/pj_qsfn.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/pj_release.Plo \
@@ -530,6 +533,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pj_factors.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pj_fwd.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pj_geocent.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pj_gridinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pj_gridlist.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pj_init.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pj_inv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pj_latlong.Plo@am__quote@
diff --git a/src/nad_init.c b/src/nad_init.c
index cdc13d41..77e267e2 100644
--- a/src/nad_init.c
+++ b/src/nad_init.c
@@ -28,6 +28,9 @@
******************************************************************************
*
* $Log$
+ * Revision 1.7 2003/03/15 06:02:02 warmerda
+ * preliminary NTv2 support, major restructure of datum shifting
+ *
* Revision 1.6 2002/07/08 02:32:05 warmerda
* ensure clean C++ builds
*
@@ -50,171 +53,13 @@
#include <assert.h>
#include <string.h>
-static int byte_order_test = 1;
-#define IS_LSB (((unsigned char *) (&byte_order_test))[0] == 1)
-
-/************************************************************************/
-/* local_order() */
-/* */
-/* Convert the given words into local order in place. */
-/************************************************************************/
-
-static void local_order( unsigned char *data, int word_size, int word_count )
-
-{
- /* We only need to do work on LSB machines. Perhaps we should
- convert the data files into LSB order to cut workload! */
-
- if( IS_LSB )
- {
- int word;
-
- for( word = 0; word < word_count; word++ )
- {
- int i;
-
- for( i = 0; i < word_size/2; i++ )
- {
- int t;
-
- t = data[i];
- data[i] = data[word_size-i-1];
- data[word_size-i-1] = t;
- }
-
- data += word_size;
- }
- }
-}
-
-/************************************************************************/
-/* nad_load_ntv1() */
-/* */
-/* Load an NTv1 style Canadian grid shift file. */
-/************************************************************************/
-
-static struct CTABLE *nad_load_ntv1( FILE * fid )
-
-{
- unsigned char header[176];
- struct CTABLE *ct;
- LP ur;
- double *row_buf;
- int row;
-
- assert( sizeof(int) == 4 );
- assert( sizeof(double) == 8 );
- if( sizeof(int) != 4 || sizeof(double) != 8 )
- {
- fprintf( stderr,
- "basic types of inappropraiate size in nad_load_ntv1()\n" );
- pj_errno = -38;
- return NULL;
- }
-
-/* -------------------------------------------------------------------- */
-/* Read the header. */
-/* -------------------------------------------------------------------- */
- if( fread( header, sizeof(header), 1, fid ) != 1 )
- {
- fclose( fid );
- pj_errno = -38;
- return 0;
- }
-
-/* -------------------------------------------------------------------- */
-/* Regularize fields of interest. */
-/* -------------------------------------------------------------------- */
- local_order( header+8, 4, 1 );
- local_order( header+24, 8, 1 );
- local_order( header+40, 8, 1 );
- local_order( header+56, 8, 1 );
- local_order( header+72, 8, 1 );
- local_order( header+88, 8, 1 );
- local_order( header+104, 8, 1 );
-
- if( *((int *) (header+8)) != 12 )
- {
- pj_errno = -38;
- printf("NTv1 grid shift file has wrong record count, corrupt?\n");
- return NULL;
- }
-
-/* -------------------------------------------------------------------- */
-/* Fill in CTABLE structure. */
-/* -------------------------------------------------------------------- */
- ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
- strcpy( ct->id, "NTv1 Grid Shift File" );
-
- ct->ll.lam = - *((double *) (header+72));
- ct->ll.phi = *((double *) (header+24));
- ur.lam = - *((double *) (header+56));
- ur.phi = *((double *) (header+40));
- ct->del.lam = *((double *) (header+104));
- ct->del.phi = *((double *) (header+88));
- ct->lim.lam = (int) (fabs(ur.lam-ct->ll.lam)/ct->del.lam + 0.5) + 1;
- ct->lim.phi = (int) (fabs(ur.phi-ct->ll.phi)/ct->del.phi + 0.5) + 1;
-
- ct->ll.lam *= DEG_TO_RAD;
- ct->ll.phi *= DEG_TO_RAD;
- ct->del.lam *= DEG_TO_RAD;
- ct->del.phi *= DEG_TO_RAD;
-
-/* -------------------------------------------------------------------- */
-/* Fill the data array. */
-/* */
-/* We process one line at a time. Note that the array storage */
-/* direction (e-w) is different in the NTv1 file and what */
-/* the CTABLE is supposed to have. The phi/lam are also */
-/* reversed, and we have to be aware of byte swapping. */
-/* -------------------------------------------------------------------- */
- row_buf = (double *) pj_malloc(ct->lim.lam * sizeof(double) * 2);
- ct->cvs = (FLP *) pj_malloc(ct->lim.lam*ct->lim.phi*sizeof(FLP));
- if( row_buf == NULL || ct->cvs == NULL )
- return NULL;
-
- for( row = 0; row < ct->lim.phi; row++ )
- {
- int i;
- FLP *cvs;
- double *diff_seconds;
-
- if( fread( row_buf, sizeof(double), ct->lim.lam * 2, fid )
- != 2 * ct->lim.lam )
- {
- pj_dalloc( row_buf );
- pj_dalloc( ct->cvs );
- pj_errno = -38;
- return NULL;
- }
-
- local_order( (unsigned char *) row_buf, 8, ct->lim.lam * 2 );
-
- /* convert seconds to radians */
- diff_seconds = row_buf;
-
- for( i = 0; i < ct->lim.lam; i++ )
- {
- cvs = ct->cvs + (row) * ct->lim.lam
- + (ct->lim.lam - i - 1);
-
- cvs->phi = *(diff_seconds++) * ((PI/180.0) / 3600.0);
- cvs->lam = *(diff_seconds++) * ((PI/180.0) / 3600.0);
- }
- }
-
- pj_dalloc( row_buf );
-
- return ct;
-}
-
/************************************************************************/
/* nad_load_ctable() */
/* */
/* Load a datum shift file already in "CTABLE" format. */
/************************************************************************/
-static struct CTABLE *nad_load_ctable( FILE * fid )
+struct CTABLE *nad_load_ctable( FILE * fid )
{
struct CTABLE *ct;
int a_size, id_end;
@@ -283,32 +128,7 @@ struct CTABLE *nad_init(char *name)
return 0;
}
-/* -------------------------------------------------------------------- */
-/* Load a header, to determine the file type. */
-/* -------------------------------------------------------------------- */
- if( fread( header, sizeof(header), 1, fid ) != 1 )
- {
- fclose( fid );
- pj_errno = -38;
- return 0;
- }
-
- fseek( fid, SEEK_SET, 0 );
-
-/* -------------------------------------------------------------------- */
-/* Determine file type. */
-/* -------------------------------------------------------------------- */
- if( strncmp(header + 0, "HEADER", 6) == 0
- && strncmp(header + 96, "W GRID", 6) == 0
- && strncmp(header + 144, "TO NAD83 ", 16) == 0 )
- {
- ct = nad_load_ntv1( fid );
- }
-
- else
- {
- ct = nad_load_ctable( fid );
- }
+ ct = nad_load_ctable( fid );
fclose(fid);
return ct;
@@ -323,7 +143,9 @@ struct CTABLE *nad_init(char *name)
void nad_free(struct CTABLE *ct)
{
if (ct) {
- pj_dalloc(ct->cvs);
+ if( ct->cvs != NULL )
+ pj_dalloc(ct->cvs);
+
pj_dalloc(ct);
}
}
diff --git a/src/pj_apply_gridshift.c b/src/pj_apply_gridshift.c
index 7860cbdd..287ffb07 100644
--- a/src/pj_apply_gridshift.c
+++ b/src/pj_apply_gridshift.c
@@ -6,10 +6,10 @@
* NAD83 or the reverse). This module is responsible for keeping
* a list of loaded grids, and calling with each one that is
* allowed for a given datum (expressed as the nadgrids= parameter).
- * Author: Frank Warmerdam, warmerda@home.com
+ * Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
- * Copyright (c) 2000, Frank Warmerdam
+ * Copyright (c) 2000, Frank Warmerdam <warmerdam@pobox.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -31,6 +31,9 @@
******************************************************************************
*
* $Log$
+ * Revision 1.5 2003/03/15 06:02:02 warmerda
+ * preliminary NTv2 support, major restructure of datum shifting
+ *
* Revision 1.4 2002/07/08 02:32:05 warmerda
* ensure clean C++ builds
*
@@ -51,190 +54,6 @@
#include <string.h>
#include <math.h>
-#define GRID_MAX 100
-
-/* used only by pj_get_grid() and pj_deallocate_grids() */
-static int grid_count = 0;
-static char **grid_names = NULL;
-static struct CTABLE **grid_list = NULL;
-
-/* used only by pj_load_nadgrids() and pj_deallocate_grids() */
-static struct CTABLE **last_nadgrids_list = NULL;
-static char *last_nadgrids = NULL;
-
-/************************************************************************/
-/* pj_deallocate_grids() */
-/* */
-/* Deallocate all loaded grids. */
-/************************************************************************/
-
-void pj_deallocate_grids()
-
-{
- if( grid_count > 0 )
- {
- int i;
-
- for( i = 0; i < grid_count; i++ )
- {
- if( grid_list[i] != NULL )
- nad_free( grid_list[i] );
- pj_dalloc( grid_names[i] );
- }
-
- pj_dalloc( grid_names );
- pj_dalloc( grid_list );
-
- grid_names = NULL;
- grid_list = NULL;
-
- grid_count = 0;
- }
-
- if( last_nadgrids != NULL )
- {
- pj_dalloc( last_nadgrids );
- last_nadgrids = NULL;
-
- pj_dalloc( last_nadgrids_list );
- last_nadgrids_list = NULL;
- }
-}
-
-/************************************************************************/
-/* pj_get_grid() */
-/* */
-/* Find the requested grid in the list, or if not present, try */
-/* and load it. On failure returns NULL and sets pj_errno. */
-/************************************************************************/
-
-static struct CTABLE *pj_get_grid( const char *name )
-
-{
- int i;
-
-/* -------------------------------------------------------------------- */
-/* First look in the existing list. */
-/* -------------------------------------------------------------------- */
- for( i = 0; i < grid_count; i++ )
- {
- if( strcmp( grid_names[i], name ) == 0 )
- {
- if( grid_list[i] == NULL )
- pj_errno = -38;
-
- return grid_list[i];
- }
- }
-
-/* -------------------------------------------------------------------- */
-/* Add entry for this file in the grid list. */
-/* -------------------------------------------------------------------- */
- if( grid_count == 0 )
- {
- grid_names = (char **) pj_malloc(sizeof(char *) * GRID_MAX);
- memset( grid_names, 0, sizeof(char *) * GRID_MAX );
- grid_list = (struct CTABLE **)
- pj_malloc(sizeof(struct CTABLE *) * GRID_MAX );
- memset( grid_list, 0, sizeof(struct CTABLE *) * GRID_MAX );
- }
- else if( grid_count >= GRID_MAX )
- {
- pj_errno = -38;
- return NULL;
- }
-
- grid_count++;
-
- grid_names[grid_count-1] = (char *) pj_malloc(strlen(name)+1);
- strcpy( grid_names[grid_count-1], name );
-
-/* -------------------------------------------------------------------- */
-/* Read the file. */
-/* -------------------------------------------------------------------- */
- grid_list[grid_count-1] = nad_init( (char *) name );
-
- return grid_list[grid_count-1];
-}
-
-/************************************************************************/
-/* pj_load_nadgrids() */
-/* */
-/* This functions loads the list of grids corresponding to a */
-/* particular nadgrids string into a list, and returns it. The */
-/* list is kept around till a request is made with a different */
-/* string in order to cut down on the string parsing cost, and */
-/* the cost of building the list of tables each time. */
-/************************************************************************/
-
-static struct CTABLE **pj_load_nadgrids( const char *nadgrids )
-
-{
- int nadgrids_count = 0;
- const char *s;
-
- pj_errno = 0;
-
- if( last_nadgrids != NULL
- && strcmp(nadgrids,last_nadgrids) == 0 )
- return last_nadgrids_list;
-
-/* -------------------------------------------------------------------- */
-/* 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 );
-
- if( last_nadgrids_list == NULL )
- last_nadgrids_list = (struct CTABLE **)
- pj_malloc(sizeof(struct CTABLE *) * GRID_MAX);
-
-/* -------------------------------------------------------------------- */
-/* Loop processing names out of nadgrids one at a time. */
-/* -------------------------------------------------------------------- */
- for( s = nadgrids; *s != '\0'; )
- {
- int end_char;
- char name[128];
-
- for( end_char = 0;
- s[end_char] != '\0' && s[end_char] != ',';
- end_char++ ) {}
-
- if( end_char > sizeof(name) )
- {
- pj_errno = -38;
- return NULL;
- }
-
- strncpy( name, s, end_char );
- name[end_char] = '\0';
-
- s += end_char;
- if( *s == ',' )
- s++;
-
-
- last_nadgrids_list[nadgrids_count] = pj_get_grid( name );
- if( last_nadgrids_list[nadgrids_count] == NULL )
- {
- pj_errno = -38;
- return NULL;
- }
-
- nadgrids_count++;
- }
-
- last_nadgrids_list[nadgrids_count] = NULL;
-
- return last_nadgrids_list;
-}
-
/************************************************************************/
/* pj_apply_gridshift() */
/************************************************************************/
@@ -244,10 +63,11 @@ int pj_apply_gridshift( const char *nadgrids, int inverse,
double *x, double *y, double *z )
{
- struct CTABLE **tables = pj_load_nadgrids( nadgrids );
+ int grid_count = 0;
+ PJ_GRIDINFO **tables = pj_gridlist_from_nadgrids( nadgrids, &grid_count);
int i;
- if( tables == NULL )
+ if( tables == NULL || grid_count == 0 )
return pj_errno;
for( i = 0; i < point_count; i++ )
@@ -260,9 +80,25 @@ int pj_apply_gridshift( const char *nadgrids, int inverse,
input.lam = x[io];
/* keep trying till we find a table that works */
- for( itable = 0; tables[itable] != NULL; itable++ )
+ for( itable = 0; itable < grid_count; itable++ )
{
- output = nad_cvt( input, inverse, tables[itable] );
+ struct CTABLE *ct = tables[itable]->ct;
+
+ /* skip tables that don't match our point at all. */
+ if( ct->ll.phi > input.phi || ct->ll.lam > input.lam
+ || ct->ll.phi + ct->lim.phi * ct->del.phi < input.phi
+ || ct->ll.lam + ct->lim.lam * ct->del.lam < input.lam )
+ continue;
+
+ /* load the grid shift info if we don't have it. */
+ if( tables[itable]->ct->cvs == NULL
+ && !pj_gridinfo_load( tables[itable] ) )
+ {
+ pj_errno = -38;
+ return pj_errno;
+ }
+
+ output = nad_cvt( input, inverse, tables[itable]->ct );
if( output.lam != HUGE_VAL )
break;
}
diff --git a/src/projects.h b/src/projects.h
index ff65e574..f417e4a8 100644
--- a/src/projects.h
+++ b/src/projects.h
@@ -28,6 +28,9 @@
******************************************************************************
*
* $Log$
+ * Revision 1.16 2003/03/15 06:02:02 warmerda
+ * preliminary NTv2 support, major restructure of datum shifting
+ *
* Revision 1.15 2002/12/14 20:35:15 warmerda
* fix C_NAMESPACE warning issue with C_NAMESPACE_VAR for variables
*
@@ -309,6 +312,7 @@ extern struct PJ_PRIME_MERIDIANS pj_prime_meridians[];
#define MAX_TAB_ID 80
typedef struct { float lam, phi; } FLP;
typedef struct { int lam, phi; } ILP;
+
struct CTABLE {
char id[MAX_TAB_ID]; /* ascii info */
LP ll; /* lower left corner coordinates */
@@ -316,7 +320,22 @@ struct CTABLE {
ILP lim; /* limits of conversion matrix */
FLP *cvs; /* conversion matrix */
};
- /* procedure prototypes */
+
+typedef struct _pj_gi {
+ char *gridname; /* identifying name of grid, eg "conus" or ntv2_0.gsb */
+ char *filename; /* full path to filename */
+
+ const char *format; /* format of this grid, ie "ctable", "ntv1",
+ "ntv2" or "missing". */
+
+ int grid_offset; /* offset in file, for delayed loading */
+
+ struct CTABLE *ct;
+
+ struct _pj_gi *next;
+} PJ_GRIDINFO;
+
+/* procedure prototypes */
double dmstor(const char *, char **);
void set_rtodms(int, int);
char *rtodms(char *, double, int, int);
@@ -371,7 +390,18 @@ int bch2bps(projUV, projUV, projUV **, int, int);
LP nad_intr(LP, struct CTABLE *);
LP nad_cvt(LP, int, struct CTABLE *);
struct CTABLE *nad_init(char *);
+struct CTABLE *nad_load_ctable( FILE * fid );
void nad_free(struct CTABLE *);
+
+/* higher level handling of datum grid shift files */
+
+PJ_GRIDINFO **pj_gridlist_from_nadgrids( const char *, int * );
+void pj_deallocate_grids();
+
+PJ_GRIDINFO *pj_gridinfo_init( const char * );
+int pj_gridinfo_load( PJ_GRIDINFO * );
+void pj_gridinfo_free( PJ_GRIDINFO * );
+
extern char const pj_release[];
#ifndef DISABLE_CVSID