Main Page | File List | Globals | Related Pages

track.c

Go to the documentation of this file.
00001 
00008 /* 
00009    Copyright (C) 1999-2004 Christian Claveleira (Christian.Claveleira@cru.fr)
00010 
00011    This program is free software; you can redistribute it and/or
00012    modify it under the terms of the GNU General Public License
00013    as published by the Free Software Foundation; either version 2
00014    of the License, or (at your option) any later version.
00015    
00016    This program is distributed in the hope that it will be useful,
00017    but WITHOUT ANY WARRANTY; without even the implied warranty of
00018    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019    GNU General Public License for more details.
00020    
00021    You should have received a copy of the GNU General Public License
00022    along with this program; if not, write to the Free Software
00023    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00024  */
00025 
00026 /*      $Id: track.c,v 1.6 2004/01/02 20:39:47 clavelei Exp clavelei $   */
00027 
00028 #ifndef lint
00029 //static char vcid[] = "$Id: track.c,v 1.6 2004/01/02 20:39:47 clavelei Exp clavelei $";
00030 #endif /* lint */
00031 
00032 #include <PalmOS.h>
00033 #include <PalmCompatibility.h>
00034 #include "gtalkRsc.h"
00035 #include "gpslib.h"
00036 #include "gtalk.h"
00037 #include "track.h"
00038 #include "gpsutil.h"
00039 #include "log.h"
00040 #include "dbio.h"
00041 #include "map.h"
00042 #include "ExgMgr.h"                                        // object exchange functions
00043 
00044 static void DrawSpeed (VoidHand RecH) TRACK_SECTION;
00045 static double TrackDistance(VoidHand RecH, Boolean WithHoles) TRACK_SECTION;
00046 
00054 Boolean
00055 TrackFormHandleEvent (EventPtr e)
00056 {
00057   Boolean Edited,
00058     handled = false;
00059   static FormPtr frm;
00060   UInt n;
00061   Object *RecP;
00062   static VoidHand RecH;
00063   UInt category,
00064     attributes;
00065   static UInt MyCategory;
00066   Err error;
00067   FieldPtr fdPtr;
00068   char CategoryName[dmCategoryLength];
00069   RectangleType r;
00070   double dist;
00071 
00072   debug_in (GTALKDBG_CALLS, ("->TrackFormHandleEvent(%s)", e->eType > LASTVALIDEVTNAME ?StrIToA(gbuf1,e->eType):EvtNames[e->eType]));
00073   switch (e->eType)
00074     {
00075     case frmOpenEvent:
00076       frm = FrmGetActiveForm ();
00077       // catégorie
00078       error = DmRecordInfo (TrkDB, CurrentRecordIndex, &attributes, NULL, NULL);
00079       MyCategory = attributes & dmRecAttrCategoryMask;
00080       CategoryGetName (TrkDB, MyCategory, CategoryName);
00081       CategorySetTriggerLabel (GetObjPtr (TrkCatPopupID), CategoryName);
00082       if (Prefs.PermTrackIndex == (CurrentRecordIndex + 1))
00083         SetControlValue (TrkSelID, 1);
00084       //          FrmSetControlValue (frm, FrmGetObjectIndex (frm, TrkSelID), 1);
00085       FrmDrawForm (frm);                                   // position a voir
00086       GetObjectBounds (TrkDrawingID, &DrawRect);           /* recup bound box du gadget */
00087       //      FrmGetObjectBounds (frm, FrmGetObjectIndex (frm, TrkDrawingID), &DrawRect);     /* recup bound box du gadget */
00088       RecH = DmQueryRecord (TrkDB, CurrentRecordIndex);
00089       if (RecH)
00090         {
00091           RecP = MemHandleLock (RecH);
00092           StrNToField (RecP->d.CustTrkHdr.name, StrLen (RecP->d.CustTrkHdr.name), TrkFdNameID);
00093           MemHandleUnlock (RecH);
00094         }
00095       MapFlags.DrawTrk = 1;
00096       DrawTrack (CurrentRecordIndex, 1, 1);
00097       handled = true;
00098       break;
00099 
00100     case penDownEvent:
00101       FrmGetObjectBounds (frm, FrmGetObjectIndex (frm, TrkDrawingID) , &r); 
00102       if (RctPtInRectangle (e->screenX, e->screenY, &r)) { 
00103           Prefs.PermTrackIndex = CurrentRecordIndex + 1;
00104           MapFlags.AllowedOps = MapOpMapTrack;
00105           FrmGotoForm (MapForm);
00106         handled=true; 
00107       } 
00108       break;
00109 
00110     case menuEvent:
00111       MenuEraseStatus (NULL);
00112       switch (e->data.menu.itemID)
00113         {
00114         case MenuEraseID:
00115           SysCopyStringResource (gbuf1, StrRemoveTrkID);
00116           if (FrmCustomAlert (ConfID, gbuf1, " ?", " "))
00117             {
00118               n = CurrentRecordIndex;
00119               error =
00120                 DmSeekRecordInCategory (TrkDB, &CurrentRecordIndex, 1, dmSeekBackward,
00121                                         *CurrentCategory);
00122               DmRemoveRecord (TrkDB, n);
00123               MainListDirty = 1;
00124               FrmReturnToForm (0);
00125             }
00126           break;
00127 
00128         case MenuSpProfID:
00129           DrawSpeed (RecH);
00130           break;
00131 
00132         case MenuTrkDistID: {
00133           FormPtr fp = NULL;
00134           fp = FrmInitForm (WaitForm);
00135           FrmDrawForm (fp);
00136           dist=TrackDistance(RecH,0);
00137           n=StrPrintF (gbuf1, "%s", DToA(dist,0,1));
00138           dist=TrackDistance(RecH,1);
00139           n+=StrPrintF (gbuf1+n, "/%s %s", DToA(dist,0,1), DistanceUnitNames[Prefs.distunit]);
00140           FrmEraseForm (fp);
00141           FrmDeleteForm (fp);
00142           WinDrawChars (gbuf1, n,1, DrawRect.extent.y);
00143         }
00144           break;
00145 
00146         case MenuMapID:
00147           Prefs.PermTrackIndex = CurrentRecordIndex + 1;
00148           //        MapFlags.AllowedOps = 0;
00149           MapFlags.AllowedOps = MapOpMapTrack;
00150           FrmGotoForm (MapForm);
00151           break;
00152 #ifdef BEAM
00153         case MenuBeamID:
00154           {  // factoriser avec route.c $$
00155             ExgSocketType sock;
00156             RecordSeparator RecSep;
00157             void *RecP;
00158             ULong len;
00159 
00160             if (!RecH) break;
00161             RecP = MemHandleLock (RecH);
00162             MemSet (&sock, sizeof (sock), 0);
00163             sock.target = GPilotSID;
00164             sock.count = 1;
00165             sock.length = MemHandleSize (RecH); // useless
00166             sock.appData = DispTrk;                // useless
00167             sock.time = DispTrk;                   // useless
00168             sock.description = "Track";
00169             sock.name = BeamTypes[DispTrk];
00170             //  sock.localMode=1; // debug 
00171             RecSep.length = MemHandleSize (RecH);
00172             RecSep.reserved = 0;
00173 
00174             error = ExgPut (&sock);                // put data to destination
00175             if (!error)
00176               {
00177                 len=ExgSend (&sock, &RecSep, sizeof (RecSep), &error);
00178                 len=0;
00179                 while (!error && len < MemHandleSize (RecH)){
00180                   len+=ExgSend (&sock, RecP, MemHandleSize (RecH), &error);
00181                 }
00182                 error=ExgDisconnect (&sock, error);
00183               }
00184             MemHandleUnlock (RecH);
00185           }
00186           break;
00187 #endif
00188 
00189         case MenuPrefID:
00190           SetPreferences ();
00191           MainListDirty = 1;
00192           break;
00193 
00194         case MenuAboutID:
00195           FrmAlert (idAbout);
00196           break;
00197         }
00198       handled = true;
00199       break;
00200 
00201     case ctlSelectEvent:
00202       switch (e->data.ctlSelect.controlID)
00203         {
00204         case TrkBtOKID:
00205           fdPtr = (FieldPtr) (GetObjPtr (TrkFdNameID));
00206           if (FldDirty (fdPtr) && (RecH = DmGetRecord (TrkDB, CurrentRecordIndex)))
00207             {
00208               RecP = MemHandleLock (RecH);
00209               n = FldGetTextLength (fdPtr);
00210               if (n >= sizeof (RecP->d.CustTrkHdr.name))
00211                 n = sizeof (RecP->d.CustTrkHdr.name) - 1;
00212               DmWrite (RecP, OffsetOf (Object, d.CustTrkHdr.name), FldGetTextPtr (fdPtr), n + 1);
00213               MemHandleUnlock (RecH);
00214               DmReleaseRecord (TrkDB, CurrentRecordIndex, 1);
00215               MainListDirty = 1;
00216             }
00217           if (CurrentRecordIndex != dmMaxRecordIndex)
00218             error = SetCategory (TrkDB, CurrentRecordIndex, MyCategory);
00219 
00220         case BtCancelID:
00221           FrmReturnToForm (0);
00222           handled = true;
00223           break;
00224 
00225 #if 0
00226         case TrkBtDeleteID:
00227           SysCopyStringResource (gbuf1, StrRemoveTrkID);
00228           if (FrmCustomAlert (ConfID, gbuf1, " ?", " "))
00229             {
00230               n = CurrentRecordIndex;
00231               error =
00232                 DmSeekRecordInCategory (TrkDB, &CurrentRecordIndex, 1, dmSeekBackward,
00233                                         *CurrentCategory);
00234               DmRemoveRecord (TrkDB, n);
00235               MainListDirty = 1;
00236               //      CurrentRecordIndex = CurrentRecordIndex == 0 ? 0 : CurrentRecordIndex - 1;
00237               FrmReturnToForm (0);
00238             }
00239           handled = true;
00240           break;
00241 
00242         case TrkMapID:
00243           Prefs.PermTrackIndex = CurrentRecordIndex + 1;
00244           MapFlags.AllowedOps = 0;
00245           FrmGotoForm (MapForm);
00246           handled = true;
00247           break;
00248 #endif
00249         case TrkSelID:
00250           Prefs.PermTrackIndex = e->data.ctlSelect.on ? CurrentRecordIndex + 1 : 0;
00251           /*      MapFlags.AllowedOps= MapOpMapTrack; */
00252           /*        FrmGotoForm (MapForm); */
00253           MainListDirty = 1;
00254           handled = true;
00255           break;
00256 #if 0
00257         case TrkSpdID:
00258           DrawSpeed (RecH);
00259           handled = true;
00260           break;
00261 #endif
00262         case TrkCatPopupID:                                /* categorie */
00263           category = MyCategory;
00264           Edited =
00265             CategorySelect (TrkDB, frm, TrkCatPopupID, TrkCatListID, false, &MyCategory,
00266                             CtlGetLabel (e->data.ctlSelect.pControl), 1, 0);
00267           /*        if ((MyCategory != category) && (CurrentRecordIndex != dmMaxRecordIndex))   // a deplacer vers bouton ok */
00268 
00269           /*            error = SetCategory (TrkDB, CurrentRecordIndex, MyCategory); */
00270           handled = true;
00271           break;
00272         }
00273       break;
00274 
00275     default:
00276       break;
00277     }
00278 
00279   debug_out (GTALKDBG_CALLS, ("<-TrackFormHandleEvent()=%d", handled));
00280   return handled;
00281 }                                                          /* TrackFormHandleEvent */
00282 
00283 
00291 static void DrawSpeed (VoidHand RecH)
00292 {
00293 #define DRAWW 128
00294 #define DRAWH 90
00295 #define DRAWX 20
00296 #define DRAWY 15
00297 #define DISPELT 10  // minimum space between lines
00298 #define TIMEOFFSET 15
00299 
00300   Object *RecP;
00301   Custom_Trk_Point_Type *ht=NULL;
00302   unsigned long prevlat = 0,
00303     prevlon = 0,
00304     prevtime = 0,
00305     elapsedtime = 0,
00306     t0 = 0;
00307   double dist = 0;
00308   float f,
00309     pu=0; /* value range by display unit */
00310   FormPtr frm;
00311   DateTimeType dtp;
00312   static char date[dateStringLength];
00313   static char time[timeStringLength];
00314 
00315   UInt n,m,
00316     k,
00317     i,l,
00318     prevxtime,
00319     U = DRAWH/DISPELT, /* number of display units */
00320     speed,
00321     speeds[DRAWW],
00322     maxspeed = 0;
00323 
00324   if (!RecH)
00325     return;
00326   frm = FrmInitForm (ChartForm);
00327 
00328   FrmDrawForm(frm);
00329 
00330   n = TrkptsInTrkDB (RecH);
00331   k = (n-1) / DRAWW + 1;
00332   RecP = MemHandleLock (RecH);
00333   WinDrawChars (RecP->d.CustTrkHdr.name,StrLen (RecP->d.CustTrkHdr.name),45, 1);
00334     SysCopyStringResource (gbuf1, StrNoTimeInTrack);
00335   if (RecP->d.CustTrkHdr.type == CompactTrkPt) {
00336     //    l=StrPrintF (gbuf1, "No time information in compact track");
00337     WinDrawChars (gbuf1, StrLen (gbuf1),/* DRAWX */ 2, 50);
00338     n=0;
00339   }
00340   else {
00341     ht = (Custom_Trk_Point_Type *) ((void *) RecP + SizeOfObject (RecP));
00342     if (ht->time==0) {
00343       //      l=StrPrintF (gbuf1, "No time information in this track");
00344       WinDrawChars (gbuf1, StrLen (gbuf1),DRAWX, 50);
00345       n=0;
00346     }
00347   }
00348   if(n>=2) {                     // start and stop times
00349     t0=ht->time;
00350     elapsedtime=(ht+n-1)->time-t0;
00351        
00352     TimSecondsToDateTime (GarminTime2PalmSeconds (t0), &dtp);
00353     DateToAscii (dtp.month, dtp.day, dtp.year, dfDMYWithDashes, date);
00354     TimeToAscii (dtp.hour, dtp.minute, tfColon24h, time);
00355     WinDrawChars (date,StrLen (date),5, DRAWY+DRAWH+TIMEOFFSET+3);
00356     WinDrawChars (time,StrLen (time),5, DRAWY+DRAWH+TIMEOFFSET+3+FntCharHeight());
00357     WinDrawChars ("UTC",3, 5, DRAWY+DRAWH+TIMEOFFSET+3+2*FntCharHeight());
00358     TimSecondsToDateTime (GarminTime2PalmSeconds ((ht+n-1)->time), &dtp);
00359     DateToAscii (dtp.month, dtp.day, dtp.year, dfDMYWithDashes, date);
00360     TimeToAscii (dtp.hour, dtp.minute, tfColon24h, time);
00361     WinDrawChars (date,StrLen (date),DRAWX+DRAWW-20, DRAWY+DRAWH+TIMEOFFSET+3);
00362     WinDrawChars (time,StrLen (time),DRAWX+DRAWW-20, DRAWY+DRAWH+TIMEOFFSET+3+FntCharHeight());
00363   }
00364   else n=0;
00365   prevlat = ht->posn.lat;
00366   prevlon = ht->posn.lon;
00367   prevtime = ht->time;
00368   prevxtime=DRAWX;
00369 
00370   for (i = 1; i < n; i++, ht++)
00371     {
00372       if (ht->new_trk) 
00373         {
00374           WinDrawGrayLine (DRAWX + (i-1) / k, DRAWY+DRAWH, 
00375                            DRAWX + ((float)DRAWW*(float)(prevtime-t0))/(float)elapsedtime, DRAWY+DRAWH+TIMEOFFSET);
00376           WinDrawGrayLine (DRAWX + i / k, DRAWY+DRAWH, 
00377                            DRAWX + ((float)DRAWW*(float)(ht->time-t0))/(float)elapsedtime, DRAWY+DRAWH+TIMEOFFSET);
00378 
00379           /*            WinDrawLine (DRAWX + ((float)DRAWW*(float)(prevtime-t0))/(float)elapsedtime, DRAWH+TIMEOFFSET,  */
00380           /* DRAWX + ((float)DRAWW*(float)(ht->time-t0))/(float)elapsedtime, DRAWH+TIMEOFFSET); */
00381           prevtime = ht->time;
00382           dist = 0;
00383           prevxtime=DRAWX + ((float)DRAWW*(float)(ht->time-t0))/(float)elapsedtime;
00384         }
00385       else
00386         {
00387           dist += Distance (prevlat, prevlon, ht->posn.lat, ht->posn.lon, Prefs.distunit);
00388         }
00389 
00390       if (!(i % k))
00391         {
00392           speed =       ht->time ==  prevtime ? 0 : 
00393             (UInt) (dist / (double) (ht->time - prevtime) * 36000. + 0.5);
00394           speeds[i / k] = speed;
00395 
00396           if (speed > maxspeed)
00397             maxspeed = speed;
00398           prevtime = ht->time;
00399           dist = 0;
00400           WinDrawLine (DRAWX + i / k, DRAWY+DRAWH, DRAWX + i / k, DRAWY+DRAWH);
00401           WinDrawLine(prevxtime, DRAWY+DRAWH+TIMEOFFSET,
00402                       DRAWX + ((float)DRAWW*(float)(ht->time-t0))/(float)elapsedtime, DRAWY+DRAWH+TIMEOFFSET);
00403           prevxtime=DRAWX + ((float)DRAWW*(float)(ht->time-t0))/(float)elapsedtime;
00404         }
00405       prevlat = ht->posn.lat;
00406       prevlon = ht->posn.lon;
00407     }
00408   MemHandleUnlock (RecH);
00409   if (n){
00410     /*   WinDrawLine(prevxtime, DRAWY+DRAWH+TIMEOFFSET, */
00411     /*        DRAWX + DRAWW, DRAWY+DRAWH+TIMEOFFSET); */
00412     WinDrawGrayLine (DRAWX + (i-1) / k, DRAWY+DRAWH, 
00413                      DRAWX + DRAWW , DRAWY+DRAWH+TIMEOFFSET);
00414     for (f=1e-6;f<1e6;f*=10.){
00415       pu=f;m=1;
00416       if ((pu*U)>=maxspeed)break;
00417       pu=f*2.;m=2;
00418       if ((pu*U)>=maxspeed)break;
00419       pu=f*5.;m=5;
00420       if ((pu*U)>=maxspeed)break;
00421     }
00422     WinDrawLine (DRAWX, DRAWY+DRAWH, DRAWX, DRAWY);
00423     for(i=0;i<=(U);i++) {       /* y graduations */
00424       WinDrawLine (DRAWX-2, DRAWY+DRAWH-(i*DISPELT), 
00425                    DRAWX,DRAWY+DRAWH-(i*DISPELT) );
00426       WinDrawGrayLine (DRAWX, DRAWY+DRAWH-(i*DISPELT), 
00427                        DRAWX+DRAWW, DRAWY+DRAWH-(i*DISPELT) );
00428       l=StrPrintF (gbuf1, "%s", DToA(pu*i/10.,0,1));
00429       WinDrawChars (gbuf1, StrLen (gbuf1),DRAWX-FntCharsWidth(gbuf1,l)-2, DRAWY+DRAWH-FntCharHeight()/2-(i*DISPELT));
00430     }
00431 
00432     f=(float)DRAWH/(pu*U);
00433     for (i = 1; (i * k) < n; i++)
00434       WinDrawLine (DRAWX + i, DRAWY+DRAWH, DRAWX + i, DRAWY+DRAWH - (long) (speeds[i] * f) );
00435     StrPrintF (gbuf1, "%s/h", DistanceUnitNames[Prefs.distunit]);
00436     WinDrawChars (gbuf1, StrLen (gbuf1), 1, 1);
00437   }
00438   FrmDoDialog (frm) ;
00439   FrmDeleteForm (frm);
00440 }                                                          /* DrawSpeed */
00441 
00442 
00451 static double TrackDistance(VoidHand RecH, Boolean WithHoles){
00452   UInt n,i;
00453   Custom_Trk_Point_Type *ht;
00454   double dist = 0;
00455   Object *RecP;
00456   unsigned long prevlat = 0,
00457     prevlon = 0;
00458   static  VoidHand oldRecH;
00459   static double distwithholes, distwithoutholes;
00460   static UInt oldcount;
00461 
00462   if (!RecH)
00463     return(0.0);
00464   n = TrkptsInTrkDB (RecH);
00465   if ( (RecH==oldRecH) && (n==oldcount))   /* in cache ? */
00466     return (WithHoles?distwithholes:distwithoutholes);
00467   oldcount=n;
00468   oldRecH=RecH;
00469   distwithholes= distwithoutholes=0.0;
00470   RecP = MemHandleLock (RecH);
00471   ht = (Custom_Trk_Point_Type *) ((void *) RecP + SizeOfObject (RecP));
00472   prevlat = ht->posn.lat;
00473   prevlon = ht->posn.lon;
00474   if(n>=2)for (i = 1; i < n; i++, ht++)
00475     {
00476       dist = Distance (prevlat, prevlon, ht->posn.lat, ht->posn.lon, Prefs.distunit);
00477       distwithholes+=dist;
00478       if (!(ht->new_trk) ) distwithoutholes +=dist;
00479       prevlat = ht->posn.lat;
00480       prevlon = ht->posn.lon;
00481     }
00482   MemHandleUnlock (RecH);
00483 
00484   return(WithHoles?distwithholes:distwithoutholes);
00485 }                                      /* TrackDistance */
00486 
00487 
00488 #ifdef EXPORT
00489 
00490 ExportTrack(){
00491   double latitude,
00492     longitude;
00493   char *p;
00494 
00495   memo_open ("Track\n");
00496   m_speed=Distance (prevlat, prevlon, ht->posn.lat, ht->posn.lon, Prefs.distunit)/(double) (ht->time - m_prevtime) * 3600.;
00497   SemiToDegre (&ht->posn, &latitude, &longitude);
00498   p = DegreToChars (latitude, 0, Prefs.displaymode);
00499   l = StrPrintF (gbuf1, "T%s\t",ht->new_trk?">":" ",  p);
00500   p = DegreToChars (longitude, 1, Prefs.displaymode);
00501   l += StrPrintF (gbuf1 + l, "%ld, s=%s\n",ht->time-m_prevtime,DToA(m_speed,0,2) );
00502   memo_write (gbuf1);
00503   m_prevtime=ht->time;
00504   memo_close (NULL);
00505 }
00506 #endif

Generated on Sun Aug 29 11:00:41 2004 for GPilotS by doxygen 1.3.4