GPS4Palm

Source Code Documentation


georef.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * $RCSfile: georef_8c-source.html,v $
00004  *
00005  * GPS4Palm Map File Georeference Decoding
00006  *
00007  * History:
00008  * 2003-10-19:  first version
00009  *
00010  * Reads Georeference Parameters
00011  *   - currently the parameters SCALE, LAT and LON are encoded in the filename
00012  *   - the next step should be to get these parameters from the GIF87a
00013  *     Comment Extension or PNG tEXt chunks, respectively
00014  *   - the final implementation should use an appropriate file format like
00015  *     GeoTiff, which contains both image data and georeferencing meta data
00016  *
00017  *
00018  * This program is Copyright (C) 10/2003 Matthias Prinke
00019  * <matthias.prinke@surfeu.de> and covered by GNU's GPL.
00020  * In particular, this program is free software and comes WITHOUT
00021  * ANY WARRANTY.
00022  *
00023  * $Author: mp $
00024  *
00025  * $Date: 2007-10-08 20:40:33 $
00026  *
00027  * $Revision: 1.7.2.1 $
00028  *
00029  * $Log: georef_8c-source.html,v $
00029  * Revision 1.7.2.1  2007-10-08 20:40:33  mp
00029  * updated for gps4palm V0.9.5 beta
00029  *
00030  * Revision 1.9  2005-05-15 12:36:04  mp
00031  * added map size to map search conditions
00032  *
00033  * Revision 1.8  2005/05/06 13:49:26  mp
00034  * modified documentation
00035  *
00036  * Revision 1.7  2005/05/06 13:42:40  mp
00037  * removed call to WinGetDisplayExtent() and supporting code
00038  *
00039  * Revision 1.6  2005/04/17 18:32:58  mp
00040  * added High-Density Display support to search_map()
00041  *
00042  * Revision 1.5  2005/02/19 14:39:17  mp
00043  * modified VFS support to search_map(), modified comments for doxygen
00044  *
00045  * Revision 1.4  2003/12/30 14:47:52  mp
00046  * filename cleared at start of search_map, removed debugging code
00047  *
00048  * Revision 1.3  2003/12/28 18:08:38  mp
00049  * fixed order of arguments to calcxy()
00050  *
00051  * Revision 1.2  2003/11/23 20:00:44  mp
00052  * added search_map()
00053  *
00054  * Revision 1.1  2003/10/19 16:56:30  mp
00055  * initial version
00056  *
00057  *
00058  ****************************************************************************/
00059 #include <PalmOS.h>
00060 #include <PalmCompatibility.h>
00061 #include "stringil.h"
00062 #include "MapForm.h"
00063 #include "georef.h"
00064 #include "geo.h"
00065 #include "file_io.h"
00066 #include "getdir.h"
00067 #include "imginfo.h"
00068 #include "common.h"
00069 
00070 /* Preferences data structure */
00071 extern PrefsType gPrefs;
00072 
00073 /* VFS Manager Feature Set */
00074 extern Boolean   gVfsManagerFtr;
00075 
00076 
00077 /**********************************************************************/
00078 /**
00079  * \brief       Get the map parameters SCALE, LAT and LON from the filename
00080  *
00081  * \param       filename        filename
00082  * \param       map_lat         Ptr to Latitude
00083  * \param       map_lon         Ptr to Longitude
00084  * \param       map_scale       Ptr to Scale
00085  *
00086  * \return      true if all parameters decoded successfully, otherwise false
00087  *              map_lat, map_lon, and map_scale
00088  *
00089  ****************************************************************************/
00090 Boolean georef_filename(const Char *filename, double *map_lat, double *map_lon,
00091                  UInt32 *map_scale)
00092 {
00093   UInt32        scale = 0;              /* Scale */
00094   double        lat;                    /* Latitude */
00095   double        lon;                    /* Longitude */
00096   FlpCompDouble dval;
00097   Char          tmp[12];
00098   UInt16        i;                      /* loop index */
00099   UInt16        j;                      /* loop index */
00100   Boolean       valid = false;          /* decoding valid flag */
00101   
00102   /*
00103    * Decode scale information
00104    *   Scale information ends with 'k', 'M', '+' or '-'
00105    *   and can contain at most 3 digits.
00106    */
00107    
00108    for (i=0; i<5; i++) {
00109      if (filename[i] == 'k') {
00110        /* multiply by 10^3 */
00111        scale *= 1000;
00112        i++;
00113        valid = true;
00114        break;
00115      }
00116      if (filename[i] == 'M') {
00117        /* multiply by 10^6 */
00118        scale *= 1000000L;
00119        i++;
00120        valid = true;
00121        break;
00122      }
00123      if ((filename[i] == '+') || (filename[i] == '-')) {
00124        valid = true;
00125        break;
00126      }
00127      if ((filename[i] >= '0') && (filename[i] <= '9')) {
00128        /* next digit */
00129        scale *= 10;
00130        scale += filename[i] - '0';
00131      }
00132    }
00133    
00134    if (!valid) {
00135      /* Decoding scale info failed */
00136      return false;
00137    }
00138    
00139 
00140    /*
00141     * Decode Latitude
00142     *   Latitude information ends with '+' or '-' and consists of at most
00143     *   11 characters.
00144     *   Example: +52.1614999
00145     */
00146    if (filename[i] == '+') {
00147      lat = 1.0;
00148    } else if (filename[i] == '-') {
00149      lat = -1.0;
00150    } else {
00151      /* Lat. decoding failed - no sign found */ 
00152      return false;
00153    }
00154 
00155    /* sign done */
00156    i++;
00157    
00158    /* copy lat to temp. string */
00159    for (j=0; j < 10; j++) {
00160      if ((filename[i] == '+') || (filename[i] == '-'))
00161        break;
00162      tmp[j] = filename[i++];
00163    }
00164    
00165    if ((filename[i] == '+') || (filename[i] == '-')) {
00166      /* valid end (sign of lon.) found, terminate temp. string */
00167      tmp[j] = '\0';
00168      
00169      /* get floating point value from string */
00170      FlpBufferAToF(&dval.fd, tmp);
00171    
00172      /* store "double"-field of union FlpCompDouble in variable lat */
00173      lat = lat * dval.d;
00174    } else {
00175      /* decoding failed */
00176      return false;
00177    }
00178    
00179 
00180    /*
00181     * Decode Longitude
00182     *   Longitude information ends with '.' and consists of 5 to 11
00183     *   characters.
00184     *   Example: -110.3126601
00185     */
00186    if (filename[i] == '+') {
00187      lon = 1.0;
00188    } else if (filename[i] == '-') {
00189      lon = -1.0;
00190    } else {
00191      /* Lon. decoding failed - no sign found */ 
00192      return false;
00193    }
00194    
00195    /* sign done */
00196    i++;
00197    
00198    /* copy lon to temp. string */
00199    for (j=0; j < 11; j++) {
00200      if ((j > 4) && (filename[i] == '.'))
00201        break;
00202      tmp[j] = filename[i++];
00203    }
00204    
00205    if (filename[i] == '.') {
00206      /* valid end (filename extension) found, terminate temp. string */
00207      tmp[j] = '\0';
00208      
00209      /* get floating point value from string */
00210      FlpBufferAToF(&dval.fd, tmp);
00211    
00212      /* store "double"-field of union FlpCompDouble in variable lat */
00213      lon = lon * dval.d;
00214    } else {
00215      /* decoding failed */
00216      return false;
00217    }
00218 
00219    /* return internal values */ 
00220    *map_scale   = scale;
00221    *map_lat     = lat;
00222    *map_lon     = lon;
00223    
00224    /* decoding successful */
00225    return true;
00226 }
00227 
00228 
00229 /**********************************************************************/
00230 /**
00231  * \brief       Search for usable map
00232  *
00233  * \note        Currently search_map stops on the first map which fits, even
00234  *              if there is a better map (i.e. with the map center closer to
00235  *              the current position) available. 
00236  *
00237  * \param       filename        filename or NULL (returned by reference)
00238  * \param       card            card/volume number and VFS flag
00239  *                                (returned by reference)
00240  * \param       lat             Latitude of current position
00241  * \param       lon             Longitude of current position
00242  * \param       maxx            Max. x-extent of screen
00243  * \param       maxy            Max. y-extent of screen
00244  *
00245  * \return      true if usable map found, otherwise false
00246  ****************************************************************************/
00247 Boolean search_map(char *filename, UInt32 *card, double lon, double lat,
00248                    UInt16 maxx, UInt16 maxy)
00249 {
00250   static DmOpenRef      scratch;                /* scratchpad DB reference */
00251   static char           *filelist;              /* filelist DB record */
00252   static char           *filecard;              /* filecard DB record */
00253   static char           **filelp;               /* filelp DB record */
00254   Err                   err;                    /* error code */
00255   FileDescrType         filedescr;              /* file descriptor */
00256   UInt16                i;                      /* loop index */
00257   UInt16                files = 0;              /* number of files found */
00258   Char                  **f;                    /* filename */
00259   double                map_lat;                /* map center latitude */
00260   double                map_lon;                /* map center longitude */
00261   UInt32                map_scale;              /* map scale */
00262   Int32                 x;                      /* map xoord. x */
00263   Int32                 y;                      /* map coord. y */
00264   Int32                 w;                      /* map width/2 */
00265   Int32                 h;                      /* map height/2 */
00266   UInt16                width;                  /* map width */
00267   UInt16                height;                 /* map height */
00268   UInt8                 type;                   /* map type */
00269   Boolean               found = false;          /* map found */
00270 
00271   *filename = '\0';
00272   *card = 0;
00273 
00274   /* get directory */
00275   CreateDatabase(&scratch, &filelist, &filecard, &filelp);
00276   files = getdir(filelist, filecard, filelp);
00277 
00278   if (gVfsManagerFtr) {
00279     files = getdir_vfs(filelist, filecard, filelp, files);
00280   }
00281   
00282   if (files == 0) {
00283     /* no map found */    
00284     /* free directory storage */
00285     DestroyDatabase(scratch, filelist, filecard, filelp);
00286 
00287     return false;
00288   }
00289   
00290   /* file list pointer */
00291   f = filelp;
00292   
00293   /* search for usable map */
00294   for (i = 0; i<files; i++, f++) {
00295     
00296     /* get map parameters from filename, skip invalid files */
00297     if (georef_filename(*f+SORTPREFIX, &map_lat, &map_lon, &map_scale)) {
00298       
00299       /* check if current map has reqired scale */
00300       if (map_scale == gPrefs.mapprefs.scale) {
00301       
00302         /* calculate offset between position and map center */
00303         calcxy(&x, &y, lon, lat, map_lon, map_lat, map_scale);
00304         
00305         /* copy card/volume number and VFS flag */
00306         memcpy(card, &filecard[i*4], 4);
00307         
00308         /* get map's dimensions */
00309         filedescr = fopen(*card, *f+SORTPREFIX, FILEDIR, &err);
00310     
00311         if (!err) {
00312           if (imginfo(filedescr, &type, &width, &height)) {
00313             /* no valid info */
00314             fclose(filedescr);
00315             continue;
00316           }
00317           fclose(filedescr);
00318         } else {
00319           width  = 0;
00320           height = 0;
00321         }
00322         
00323         /* offset from map center must be smaller than half image */
00324         w = width/2;
00325         h = height/2;
00326         
00327         /* check if current position is on map */
00328         if ( (x > -w+CROSS_X) &&
00329              (x <  w-CROSS_X) &&
00330              (y > -h+CROSS_Y) &&
00331              (y <  h-CROSS_Y) ) {
00332           StrCopy(filename, *f+SORTPREFIX);
00333           found = true;
00334           break;
00335         }
00336       } /* if (scale == gPrefs.mapprefs.scale) */
00337     } /* if (georef_filename()) */
00338     
00339   } /* for (i = 0; i<files; i++) */
00340   
00341   /* free directory storage */
00342   DestroyDatabase(scratch, filelist, filecard, filelp);
00343   
00344   return found;
00345 }

Created: Mon, 08 Oct 2007 22:33:16 +0200
Copyright ©2004 M. Prinke