00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019
00020
00021 00022 00023 00024 00025 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 00040 00041 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
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
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 }
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
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
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
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
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
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));
00407 projdatum->r33=projdatum->m*cos(projdatum->ey)*cos(projdatum->ex);
00408 break;
00409 }
00410 }
00411 00412 00413 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
00424 gtk_fmaps_lonlath_2_xyz(fmaps->projdatum,(*lon*DEG_TO_RAD),(*lat*DEG_TO_RAD),*h,&x,&y,&z);
00425
00426
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
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 }