Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

gtkfmapsproj.c

Go to the documentation of this file.
00001 /* gtkfmapsproj.c - Projection library of gtkfmaps
00002 * 
00003  *  Copyright (c) 2000, Franck Martin <franck@sopac.org>, Eric G. Miller <egm2@jps.net>
00004  *
00005  * This Program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This Program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public
00016  * License along with this Program; if not, write to the
00017  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018  * Boston, MA 02111-1307, USA.
00019  */
00020 
00021 /*
00022  * Modified by the FMaps Team and others 2000.  See the AUTHORS
00023  * file for a list of people on the FMaps Team.  See the ChangeLog
00024  * files for a list of changes.  These files are distributed with
00025  * FMaps at http://FMaps.sourceforge.net/.
00026  */
00027 #include <math.h>
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <ctype.h>
00031 #include <float.h>
00032 #include <string.h>
00033 
00034 #include "gtkfmaps.h"
00035 #include "gtkfmapsproj.h"
00036 
00037 
00038 /*
00039  *  Delimiters for input and output strings.  LDELIM, RDELIM, and DELIM are
00040  *  left, right, and separator delimiters, respectively.  LDELIM_EP,
00041  *  RDELIM_EP are left and right delimiters for paths with endpoints.
00042  *
00043  */
00044 
00045 #define LDELIM                  '('
00046 #define RDELIM                  ')'
00047 #define DELIM                   ','
00048 #define LDELIM_EP               '['
00049 #define RDELIM_EP               ']'
00050 #define LDELIM_C                '<'
00051 #define RDELIM_C                '>'
00052 
00053 
00054 static int point_decode(char *str, gdouble *x, gdouble *y, gdouble *z, char **s);
00055 
00056 void
00057 gtk_fmaps_display_engine (GtkFMaps *fmaps)
00058 {
00059   gint i;
00060   gint j;
00061   gchar *buffer;
00062   PGresult *qryResult;
00063   gint nbtuples;
00064   Point *points;
00065   gint nbpoints;
00066   gfloat r,g,b,a;
00067   gfloat size;
00068   gint type=-1;
00069 
00070   g_return_if_fail (fmaps !=NULL);
00071   g_return_if_fail (GTK_IS_FMAPS (fmaps));
00072 
00073   for(i=0;i<fmaps->nbtables;i++)
00074   {
00075         if (fmaps->table[i]->visible)
00076         {
00077           if (fmaps->table[i]->vector)
00078           {
00079                     buffer=g_strdup_printf("SELECT %s from f_geo_%s ",F_GEO_TABLE_FIELD, fmaps->table[i]->name);
00080               qryResult = PQexec(fmaps->conn,buffer);
00081 
00082               /* debug */
00083               if (!(g_str_equal(PQresultErrorMessage(qryResult),"")))
00084               {
00085                  g_warning("%s : %s",buffer, PQresultErrorMessage(qryResult));
00086               }
00087         
00088                   g_free(buffer);
00089                   nbtuples = PQntuples(qryResult);
00090                   j=0;
00091                           while(j<nbtuples)
00092                   {
00093                       buffer = PQgetvalue(qryResult,j,10);
00094                       points=gtk_fmaps_get_points(fmaps,i,buffer,&nbpoints,&type);      
00095                       size=strtod(PQgetvalue(qryResult,j,1),NULL);
00096                 
00097                       r=strtod(PQgetvalue(qryResult,j,4),NULL);
00098                       g=strtod(PQgetvalue(qryResult,j,5),NULL);
00099                       b=strtod(PQgetvalue(qryResult,j,6),NULL);
00100                       a=strtod(PQgetvalue(qryResult,j,7),NULL);
00101         
00102                       if (nbpoints>0 && type!=-1)
00103                       {
00104                         glColor4f(r,g,b,a);
00105                         glBegin(type);
00106                         glPointSize(size);
00107                         for (i=0;i<nbpoints;i++)
00108                         {               
00109                           glVertex3f(points[i].x,points[i].y,points[i].z);
00110                         }
00111                         glEnd();
00112                       }
00113                       g_free(points);
00114                       j++;
00115                     }
00116                     PQclear(qryResult);         
00117                 }
00118           }
00119         }
00120 }
00121 
00122 Point* gtk_fmaps_get_points(GtkFMaps *fmaps, gint tablenb, gchar *buffer, gint *nbpoints, gint *type)
00123 {
00124   gint i;
00125   gdouble x;
00126   gdouble y;
00127   gdouble z;
00128   gint pointnb;
00129   gint npoints;
00130   Point *points=NULL;
00131   gboolean result=FALSE;
00132   gchar *str=NULL;
00133 
00134   g_return_val_if_fail(fmaps!=NULL,0);
00135   g_return_val_if_fail(buffer!=NULL,0);
00136 
00137   x=0;
00138   y=0;
00139   z=0;
00140   i=0;
00141   pointnb=0;
00142   npoints=0;
00143 
00144     
00145   if (strncmp("POINT",buffer,5)==0)
00146   {
00147     *type=GL_POINTS;
00148     i=5;
00149   } else if (strncmp("POLYLINE",buffer,8)==0)
00150   {
00151     *type=GL_LINE_STRIP;
00152     i=8;
00153   } else
00154   {
00155     *type=-1;
00156   }
00157 
00158   while(i<strlen(buffer))
00159   {
00160     if (buffer[i]==LDELIM)
00161     {
00162       str=g_strdup(buffer+i);
00163       result=point_decode(str,&x,&y,&z,NULL);
00164       g_free(str);
00165       npoints++;
00166       if (npoints==1)
00167       {
00168         points=g_new(Point,npoints);
00169       } else
00170       {
00171         points=g_renew(Point,points,npoints);
00172       }
00173       points[npoints-1].x=x;
00174       points[npoints-1].y=y;
00175       points[npoints-1].z=z;
00176 
00177    }
00178 
00179   i++;
00180   };
00181 
00182   *nbpoints=npoints;
00183   return(points);
00184 
00185 }
00186 
00187 
00188 /* Private Functions */
00189 static int
00190 point_decode(char *str, gdouble *x, gdouble *y, gdouble *z, char **s)
00191 {
00192         int     has_delim;
00193         char    *cp;
00194 
00195         if(NULL == str)
00196                 return FALSE;
00197 
00198         while(isspace(*str))
00199                 str++;
00200         if ((has_delim = (*str == LDELIM)))
00201                 str++;
00202         while(isspace(*str))
00203                 str++;
00204         *x = strtod(str, &cp);
00205         if (cp <= str)
00206                 return FALSE;
00207         while(isspace(*cp))
00208                 cp++;
00209         if (*cp++ != DELIM)
00210                 return FALSE;
00211         while (isspace(*cp))
00212                 cp++;
00213         *y = strtod(cp, &str);
00214         if(str <= cp)
00215                 return FALSE;
00216         while(isspace(*str))
00217                 str++;
00218         if (*str++ != DELIM)
00219                 return FALSE;
00220         while(isspace(*str))
00221                 str++;
00222         *z = strtod(str, &cp);
00223         if(cp <= str)
00224                 return FALSE;
00225         while(isspace(*cp))
00226                 cp++;
00227         if(has_delim)
00228         {
00229                 if (*cp != RDELIM)
00230                         return FALSE;
00231                 cp++;
00232                 while (isspace(*cp))
00233                         cp++;
00234         }
00235         if (s != NULL)
00236                 *s = cp;
00237 
00238         return TRUE;
00239 } /* point_decode() */
00240 
00241 gint16 gtk_fmaps_displayx(gdouble x, GtkFMaps *fmaps)   
00242 {
00243   gint16 xx;
00244 
00245   g_return_val_if_fail(fmaps!=NULL,0);
00246 
00247   xx=((gint16)((((x-fmaps->centerx)/fmaps->width)*GTK_WIDGET(fmaps)->allocation.width)+GTK_WIDGET(fmaps)->allocation.width/2));
00248   return(xx);
00249 }
00250 
00251 gint16 gtk_fmaps_displayy(gdouble y, GtkFMaps *fmaps)
00252 {
00253   gint16 yy;
00254   g_return_val_if_fail(fmaps!=NULL,0);
00255 
00256   yy=((gint16)((((y-fmaps->centery)/fmaps->width)*GTK_WIDGET(fmaps)->allocation.width)+GTK_WIDGET(fmaps)->allocation.height/2));
00257   return(yy);
00258 }
00259 
00260 /* convert longitude, latitude and ellipsoid height into cartesian coordinates */
00261 void gtk_fmaps_lonlath_2_xyz(GtkFMapsProjDatum *projdatum, gdouble lon, gdouble lat, gdouble h, gdouble *x, gdouble *y, gdouble *z)
00262 {
00263   gdouble N;
00264 
00265   g_return_if_fail(projdatum != NULL);
00266 
00267   N=projdatum->a/sqrt(1-projdatum->e*projdatum->e*sin(lat)*sin(lat));
00268   *x=(N+h)*cos(lat)*cos(lon);
00269   *y=(N=h)*cos(lat)*sin(lon);
00270   *z=((1-projdatum->e*projdatum->e)*N+h)*sin(lat);
00271 
00272 }
00273 
00274 /* convert cartesian coordinates into longitude, latitude and ellipsoid height */
00275 void gtk_fmaps_xyz_2_lonlath(GtkFMapsProjDatum *projdatum, gdouble x, gdouble y, gdouble z, gdouble *lon, gdouble *lat, gdouble *h)
00276 {
00277 
00278   gdouble R;
00279   gdouble N;
00280   gdouble lat1;
00281 
00282   g_return_if_fail(projdatum!=NULL);
00283 
00284   R=sqrt(x*x+y*y);
00285   N=0;
00286   if (x==0)
00287   {
00288     *lon=atan(y/x);
00289   } else
00290   {
00291     if (y>=0)
00292     {
00293       *lon=M_PI_2;
00294     } else
00295     {
00296       *lon=-M_PI_2;
00297     }
00298   }
00299 
00300   if (x<0)
00301   {
00302     if (y<0)
00303     {
00304       *lon=*lon-M_PI;
00305     } else
00306     {
00307       *lon=*lon+M_PI;
00308     }
00309   }
00310   lat1=0;
00311   if (R!=0)
00312   {
00313     do
00314     {
00315       lat1=*lat;
00316       N=projdatum->a/sqrt(1-projdatum->e*projdatum->e*sin(lat1)*sin(lat1));
00317       *lat=atan((z+projdatum->e*projdatum->e*N*sin(lat1))/R);
00318       *h=R/cos(lat1)-N;
00319     } while (lat1-*lat!=0);
00320   } else
00321   {
00322     if (z>=0)
00323     {
00324       *lat=M_PI_2;
00325     } else
00326     {
00327       *lat=-M_PI_2;
00328     }
00329     *h=-N;
00330   }
00331 }
00332 
00333 /* transform cartesian coordinates from one datum to WGS84 datun if forward otherwise from WGS84 */
00334 void gtk_fmaps_bursa_wolfe(GtkFMapsProjDatum *projdatum, gboolean forward, gdouble *x, gdouble *y, gdouble *z)
00335 {
00336   gdouble x1,y1,z1;
00337 
00338   g_return_if_fail(projdatum!=NULL);
00339 
00340   x1=*x;
00341   y1=*y;
00342   z1=*z;
00343 
00344   if (forward)
00345   {
00346     *x=projdatum->r11*x1+projdatum->r12*y1+projdatum->r13*z1+projdatum->dx;
00347     *y=projdatum->r21*x1+projdatum->r22*y1+projdatum->r23*z1+projdatum->dy;
00348     *z=projdatum->r31*x1+projdatum->r32*y1+projdatum->r33*z1+projdatum->dz;
00349   } else
00350   {
00351     *x=projdatum->r11*x1+projdatum->r12*y1+projdatum->r13*z1-projdatum->dx;
00352     *y=projdatum->r21*x1+projdatum->r22*y1+projdatum->r23*z1-projdatum->dy;
00353     *z=projdatum->r31*x1+projdatum->r32*y1+projdatum->r33*z1-projdatum->dz;
00354   }
00355 }
00356 
00357 /* transform cartesian coordinates from one datum to WGS84 datun if forward otherwise from WGS84 */
00358 void gtk_fmaps_molendensky(GtkFMapsProjDatum *projdatum, gboolean forward, gdouble *x, gdouble *y, gdouble *z)
00359 {
00360   g_return_if_fail(projdatum!=NULL);
00361 
00362   if (forward)
00363   {
00364     *x=*x+projdatum->dx;
00365     *y=*y+projdatum->dy;
00366     *z=*z+projdatum->dz;
00367   } else
00368   {
00369     *x=*x-projdatum->dx;
00370     *y=*y-projdatum->dy;
00371     *z=*z-projdatum->dz;
00372   }
00373 }
00374 
00375 /* initialise the datum transformation parameters */
00376 void gtk_fmaps_projection_init(GtkFMapsProjDatum *projdatum)
00377 {
00378   g_return_if_fail(projdatum!=NULL);
00379 
00380   switch(projdatum->datumtransform)
00381   {
00382   case DAT_NONE:
00383   case DAT_MOLENDENSKY:
00384     projdatum->r11=1;
00385     projdatum->r12=0;
00386     projdatum->r13=0;
00387 
00388     projdatum->r21=0;
00389     projdatum->r22=1;
00390     projdatum->r23=0;
00391 
00392     projdatum->r31=0;
00393     projdatum->r32=0;
00394     projdatum->r33=1;
00395     break;
00396   case DAT_BURSA_WOLFE:
00397     projdatum->r11=projdatum->m*cos(projdatum->ez)*cos(projdatum->ey);
00398     projdatum->r21=-projdatum->m*sin(projdatum->ez)*cos(projdatum->ey);
00399     projdatum->r31=projdatum->m*sin(projdatum->ey);
00400 
00401     projdatum->r12=projdatum->m*(cos(projdatum->ez)*sin(projdatum->ey)*sin(projdatum->ex)+sin(projdatum->ez)*cos(projdatum->ex));
00402     projdatum->r22=projdatum->m*(cos(projdatum->ez)*cos(projdatum->ex)-sin(projdatum->ez)*sin(projdatum->ey)*sin(projdatum->ex));
00403     projdatum->r32=-projdatum->m*cos(projdatum->ey)*sin(projdatum->ex);
00404 
00405     projdatum->r13=projdatum->m*(sin(projdatum->ey)*sin(projdatum->ex)-cos(projdatum->ey)*sin(projdatum->ey)*cos(projdatum->ex));
00406     projdatum->r23=projdatum->m*(sin(projdatum->ez)*sin(projdatum->ey)*cos(projdatum->ex)+cos(projdatum->ez)*sin(projdatum->ex)); /*error here too many * */
00407     projdatum->r33=projdatum->m*cos(projdatum->ey)*cos(projdatum->ex);
00408     break;
00409   }
00410 }
00411 /* procedure to convert lat lon h from WGS84 to defined projection
00412 *  The data is stored in the database in lat, lon , h WGS84 and need only to be converted in
00413 *    FMaps->projdatum
00414 */
00415 void gtk_fmaps_project(GtkFMaps *fmaps, gint tablenb, gdouble *lon, gdouble *lat, gdouble *h)
00416 {
00417   gdouble x,y,z;
00418 
00419   g_return_if_fail(fmaps!=NULL);
00420 
00421   if (fmaps->projdatum->datumtransform!=DAT_NONE)
00422   {
00423     /* convert first in cartesian */
00424     gtk_fmaps_lonlath_2_xyz(fmaps->projdatum,(*lon*DEG_TO_RAD),(*lat*DEG_TO_RAD),*h,&x,&y,&z);
00425 
00426     /* convert in new datum*/
00427     switch(fmaps->projdatum->datumtransform)
00428     {
00429     case DAT_NONE:
00430         break;
00431     case DAT_MOLENDENSKY:
00432         gtk_fmaps_molendensky(fmaps->projdatum,TRUE,&x,&y,&z);
00433         break;
00434     case DAT_BURSA_WOLFE:
00435         gtk_fmaps_bursa_wolfe(fmaps->projdatum,TRUE,&x,&y,&z);
00436     }
00437 
00438     /* bring back in lon lat h */
00439     gtk_fmaps_xyz_2_lonlath(fmaps->projdatum,x,y,z,lon,lat,h);
00440     *lon=*lon*RAD_TO_DEG;
00441     *lat=*lat*DEG_TO_RAD;
00442   }
00443 }

Generated at Sat Jan 6 20:55:34 2001 for FMaps by doxygen1.2.1 written by Dimitri van Heesch, © 1997-2000