LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/gtm - gtmwaypointlayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 162 133 82.1 %
Date: 2010-01-09 Functions: 11 9 81.8 %

       1                 : /******************************************************************************
       2                 :  * $Id: gtmwaypointlayer.cpp 17637 2009-09-12 23:22:00Z warmerdam $
       3                 :  *
       4                 :  * Project:  GTM Driver
       5                 :  * Purpose:  Implementation of gtmwaypoint class.
       6                 :  * Author:   Leonardo de Paula Rosa Piga; http://lampiao.lsc.ic.unicamp.br/~piga
       7                 :  *
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2009, Leonardo de Paula Rosa Piga
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : #include "ogr_gtm.h"
      31                 : #include "cpl_time.h"
      32                 : 
      33               5 : GTMWaypointLayer::GTMWaypointLayer( const char* pszName,
      34                 :                                     OGRSpatialReference* poSRSIn,
      35                 :                                     int bWriterIn,
      36               5 :                                     OGRGTMDataSource* poDSIn )
      37                 : {
      38               5 :     poCT = NULL;
      39                 :   
      40                 :     /* We are implementing just WGS84, although GTM supports other datum
      41                 :        formats. */
      42               5 :     if( poSRSIn != NULL )
      43                 :     {
      44               3 :         poSRS = new OGRSpatialReference(NULL);   
      45               3 :         poSRS->SetWellKnownGeogCS( "WGS84" );
      46               3 :         if (!poSRS->IsSame(poSRSIn))
      47                 :         {
      48               0 :             poCT = OGRCreateCoordinateTransformation( poSRSIn, poSRS );
      49               0 :             if( poCT == NULL && poDSIn->isFirstCTError() )
      50                 :             {
      51                 :                 /* If we can't create a transformation, issue a warning - but
      52                 :                    continue the transformation*/
      53               0 :                 char *pszWKT = NULL;
      54                 : 
      55               0 :                 poSRSIn->exportToPrettyWkt( &pszWKT, FALSE );
      56                 : 
      57                 :                 CPLError( CE_Warning, CPLE_AppDefined,
      58                 :                           "Failed to create coordinate transformation between the\n"
      59                 :                           "input coordinate system and WGS84.  This may be because they\n"
      60                 :                           "are not transformable, or because projection services\n"
      61                 :                           "(PROJ.4 DLL/.so) could not be loaded.\n" 
      62                 :                           "This message will not be issued any more. \n"
      63                 :                           "\nSource:\n%s\n", 
      64               0 :                           pszWKT );
      65                 : 
      66               0 :                 CPLFree( pszWKT );
      67               0 :                 poDSIn->issuedFirstCTError(); 
      68                 :             }
      69                 :         }
      70                 :     }
      71                 :     else
      72                 :     {
      73               2 :         poSRS = NULL;
      74                 :     }
      75                 : 
      76               5 :     poDS = poDSIn;
      77                 : 
      78               5 :     nNextFID = 0;
      79               5 :     nTotalFCount = poDS->getNWpts();
      80                 : 
      81               5 :     poFeatureDefn = new OGRFeatureDefn( pszName );
      82               5 :     poFeatureDefn->Reference();
      83               5 :     poFeatureDefn->SetGeomType ( wkbPoint );
      84                 : 
      85                 :     /* We implement just name, comment, and icon, if others needed feel
      86                 :        free to append more parameters */
      87               5 :     OGRFieldDefn oFieldName( "name", OFTString );
      88               5 :     poFeatureDefn->AddFieldDefn( &oFieldName );
      89                 : 
      90               5 :     OGRFieldDefn oFieldComment( "comment", OFTString );
      91               5 :     poFeatureDefn->AddFieldDefn( &oFieldComment );
      92                 : 
      93               5 :     OGRFieldDefn oFieldIcon( "icon", OFTInteger );
      94               5 :     poFeatureDefn->AddFieldDefn( &oFieldIcon );
      95                 :   
      96               5 :     OGRFieldDefn oFieldTime( "time", OFTDateTime );
      97               5 :     poFeatureDefn->AddFieldDefn( &oFieldTime );
      98                 :     
      99               5 :     this->pszName = CPLStrdup(pszName);
     100               5 : }
     101                 : 
     102              10 : GTMWaypointLayer::~GTMWaypointLayer()
     103                 : {
     104                 :   
     105              10 : }
     106                 : 
     107                 : 
     108                 : /************************************************************************/
     109                 : /*                      WriteFeatureAttributes()                        */
     110                 : /************************************************************************/
     111               3 : void GTMWaypointLayer::WriteFeatureAttributes( OGRFeature *poFeature, float altitude )
     112                 : {
     113               3 :     void* pBuffer = NULL;
     114               3 :     void* pBufferAux = NULL;
     115               3 :     char psNameField[] = "          ";
     116               3 :     char* pszcomment = NULL;
     117               3 :     int icon = 48;
     118               3 :     int date = 0;
     119              15 :     for (int i = 0; i < poFeatureDefn->GetFieldCount(); ++i)
     120                 :     {
     121              12 :         OGRFieldDefn *poFieldDefn = poFeatureDefn->GetFieldDefn( i );
     122              12 :         if( poFeature->IsFieldSet( i ) )
     123                 :         {
     124               9 :             const char* pszName = poFieldDefn->GetNameRef();
     125                 :             /* Waypoint name */
     126               9 :             if (strncmp(pszName, "name", 4) == 0)
     127                 :             {
     128               3 :                 strncpy (psNameField, poFeature->GetFieldAsString( i ), 10);
     129               3 :                 CPLStrlcat (psNameField, "          ", sizeof(psNameField));
     130                 :             }
     131                 :             /* Waypoint comment */
     132               6 :             else if (strncmp(pszName, "comment", 7) == 0)
     133                 :             {
     134               3 :                 pszcomment = CPLStrdup( poFeature->GetFieldAsString( i ) );
     135                 :             }
     136                 :             /* Waypoint icon */
     137               3 :             else if (strncmp(pszName, "icon", 4) == 0)
     138                 :             {
     139               2 :                 icon = poFeature->GetFieldAsInteger( i );
     140                 :                 // Check if it is a valid icon
     141               2 :                 if (icon < 1 || icon > 220)
     142               0 :                     icon = 48;
     143                 :             }
     144                 :             /* Waypoint date */
     145               1 :             else if (EQUAL(pszName, "time"))
     146                 :             {
     147                 :                 struct tm brokendowndate;
     148                 :                 int year, month, day, hour, min, sec, TZFlag;
     149               1 :                 if (poFeature->GetFieldAsDateTime( i, &year, &month, &day, &hour, &min, &sec, &TZFlag))
     150                 :                 {
     151               1 :                     brokendowndate.tm_year = year - 1900;
     152               1 :                     brokendowndate.tm_mon = month - 1;
     153               1 :                     brokendowndate.tm_mday = day;
     154               1 :                     brokendowndate.tm_hour = hour;
     155               1 :                     brokendowndate.tm_min = min;
     156               1 :                     brokendowndate.tm_sec = sec;
     157               1 :                     GIntBig unixTime = CPLYMDHMSToUnixTime(&brokendowndate);
     158               1 :                     if (TZFlag != 0)
     159               0 :                         unixTime -= (TZFlag - 100) * 15;
     160               1 :                     if (unixTime <= GTM_EPOCH || (unixTime - GTM_EPOCH) != (int)(unixTime - GTM_EPOCH))
     161                 :                     {
     162                 :                         CPLError(CE_Warning, CPLE_AppDefined,
     163                 :                                   "%04d/%02d/%02d %02d:%02d:%02d is not a valid datetime for GTM",
     164               0 :                                   year, month, day, hour, min, sec);
     165                 :                     }
     166                 :                     else
     167                 :                     {
     168               1 :                         date = (int)(unixTime - GTM_EPOCH);
     169                 :                     }
     170                 :                 }
     171                 :             }
     172                 :         }
     173                 :     }
     174                 : 
     175               3 :     if (pszcomment == NULL)
     176               0 :         pszcomment = CPLStrdup( "" );
     177                 : 
     178               3 :     int commentLength = 0;
     179               3 :     if (pszcomment != NULL)
     180               3 :         commentLength = strlen(pszcomment);
     181                 : 
     182               3 :     int bufferSize = 27 + commentLength;
     183               3 :     pBuffer = CPLMalloc(bufferSize);
     184               3 :     pBufferAux = pBuffer;
     185                 :     /* Write waypoint name to buffer */
     186               3 :     strncpy((char*)pBufferAux, psNameField, 10);
     187                 : 
     188                 :     /* Write waypoint string comment size to buffer */
     189               3 :     pBufferAux = (char*)pBuffer+10;
     190               3 :     appendUShort(pBufferAux, commentLength);
     191                 : 
     192                 :     /* Write waypoint string comment to buffer */
     193               3 :     strncpy((char*)pBuffer+12, pszcomment, commentLength);
     194                 : 
     195                 :     /* Write icon to buffer */
     196               3 :     pBufferAux = (char*)pBuffer+12+commentLength;
     197               3 :     appendUShort(pBufferAux, icon);
     198                 : 
     199                 :     /* Write dslp to buffer */
     200               3 :     pBufferAux = (char*)pBufferAux + 2;
     201               3 :     appendUChar(pBufferAux, 3);
     202                 : 
     203                 :     /* Date */
     204               3 :     pBufferAux = (char*)pBufferAux + 1;
     205               3 :     appendInt(pBufferAux, date);
     206                 : 
     207                 :     /* wrot */
     208               3 :     pBufferAux = (char*)pBufferAux + 4;
     209               3 :     appendUShort(pBufferAux, 0);
     210                 : 
     211                 :     /* walt */
     212               3 :     pBufferAux = (char*)pBufferAux + 2;
     213               3 :     appendFloat(pBufferAux, altitude);
     214                 : 
     215                 :     /* wlayer */
     216               3 :     pBufferAux = (char*)pBufferAux + 4;
     217               3 :     appendUShort(pBufferAux, 0);
     218                 : 
     219               3 :     VSIFWriteL(pBuffer, bufferSize, 1, poDS->getOutputFP());
     220               3 :     poDS->incNumWaypoints();
     221                 : 
     222               3 :     if (pszcomment != NULL)
     223               3 :         CPLFree(pszcomment);
     224               3 :     CPLFree(pBuffer);
     225               3 : }
     226                 : 
     227                 : /************************************************************************/
     228                 : /*                           CreateFeature()                            */
     229                 : /************************************************************************/
     230               3 : OGRErr GTMWaypointLayer::CreateFeature (OGRFeature *poFeature)
     231                 : {
     232               3 :     FILE* fp = poDS->getOutputFP();
     233               3 :     if (fp == NULL)
     234               0 :         return CE_Failure;
     235                 : 
     236               3 :     OGRGeometry *poGeom = poFeature->GetGeometryRef();
     237               3 :     if ( poGeom == NULL )
     238                 :     {
     239                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     240               0 :                   "Features without geometry not supported by GTM writer in waypoints layer." );
     241               0 :         return OGRERR_FAILURE;
     242                 :     }
     243                 :     
     244               3 :     if (NULL != poCT)
     245                 :     {
     246               0 :         poGeom = poGeom->clone();
     247               0 :         poGeom->transform( poCT );
     248                 :     }
     249                 : 
     250                 : 
     251               3 :     switch( poGeom->getGeometryType() )
     252                 :     {
     253                 :     case wkbPoint:
     254                 :     case wkbPoint25D:
     255                 :     {
     256               3 :         OGRPoint* point = (OGRPoint*)poGeom;
     257               3 :         double lat = point->getY();
     258               3 :         double lon = point->getX();
     259               3 :         CheckAndFixCoordinatesValidity(lat, lon);
     260               3 :         poDS->checkBounds((float)lat, (float)lon);
     261               3 :         writeDouble(fp, lat);
     262               3 :         writeDouble(fp, lon);
     263               3 :         float altitude = 0.0;
     264               3 :         if (poGeom->getGeometryType() == wkbPoint25D)
     265               1 :       altitude = (float) point->getZ();
     266                 : 
     267               3 :         WriteFeatureAttributes(poFeature, altitude);
     268                 :         break;
     269                 :     }
     270                 :             
     271                 :     default:
     272                 :     {
     273                 :         CPLError( CE_Failure, CPLE_NotSupported,
     274                 :                   "Geometry type of `%s' not supported for 'waypoint' element.\n",
     275               0 :                   OGRGeometryTypeToName(poGeom->getGeometryType()) );
     276               0 :         return OGRERR_FAILURE;
     277                 :     }
     278                 :     }
     279                 :     
     280               3 :     if (NULL != poCT)
     281               0 :         delete poGeom;
     282                 :         
     283               3 :     return OGRERR_NONE;
     284                 : 
     285                 : }
     286                 : 
     287               6 : OGRFeature* GTMWaypointLayer::GetNextFeature()
     288                 : {
     289               6 :     if (bError)
     290               0 :         return NULL;
     291                 : 
     292              12 :     while (poDS->hasNextWaypoint())
     293                 :     {
     294               6 :         Waypoint* poWaypoint = poDS->fetchNextWaypoint();
     295               6 :         if (poWaypoint == NULL)
     296                 :         {
     297                 :             CPLError(CE_Failure, CPLE_AppDefined,
     298               0 :                      "Could not read waypoint. File probably corrupted");
     299               0 :             bError = TRUE;
     300               0 :             return NULL;
     301                 :         }
     302                 : 
     303               6 :         OGRFeature* poFeature = new OGRFeature( poFeatureDefn );
     304               6 :         double altitude = poWaypoint->getAltitude();
     305               6 :         if (altitude == 0.0)
     306                 :             poFeature->SetGeometryDirectly(new OGRPoint 
     307                 :                                            (poWaypoint->getLongitude(),
     308               5 :                                             poWaypoint->getLatitude()));
     309                 :         else
     310                 :             poFeature->SetGeometryDirectly(new OGRPoint 
     311                 :                                            (poWaypoint->getLongitude(),
     312                 :                                             poWaypoint->getLatitude(),
     313               1 :                                             altitude));
     314                 :                                             
     315               6 :         if (poSRS)
     316               6 :             poFeature->GetGeometryRef()->assignSpatialReference(poSRS);
     317               6 :         poFeature->SetField( NAME, poWaypoint->getName());
     318               6 :         poFeature->SetField( COMMENT, poWaypoint->getComment());
     319               6 :         poFeature->SetField( ICON, poWaypoint->getIcon());
     320                 :         
     321               6 :         GIntBig wptdate = poWaypoint->getDate();
     322               6 :         if (wptdate != 0)
     323                 :         {
     324                 :             struct tm brokendownTime;
     325               3 :             CPLUnixTimeToYMDHMS(wptdate, &brokendownTime);
     326                 :             poFeature->SetField( DATE,
     327                 :                                  brokendownTime.tm_year + 1900,
     328                 :                                  brokendownTime.tm_mon + 1,
     329                 :                                  brokendownTime.tm_mday,
     330                 :                                  brokendownTime.tm_hour,
     331                 :                                  brokendownTime.tm_min,
     332               3 :                                  brokendownTime.tm_sec);
     333                 :         }
     334                 :         
     335               6 :         poFeature->SetFID( nNextFID++ );
     336               6 :         delete poWaypoint;
     337               6 :         if( (m_poFilterGeom == NULL
     338                 :              || FilterGeometry( poFeature->GetGeometryRef() ) )
     339                 :             && (m_poAttrQuery == NULL
     340                 :                 || m_poAttrQuery->Evaluate( poFeature )) )
     341               6 :             return poFeature;
     342                 : 
     343               0 :         delete poFeature;
     344                 :     }
     345               0 :     return NULL;
     346                 : }
     347                 : 
     348               2 : int GTMWaypointLayer::GetFeatureCount(int bForce)
     349                 : {
     350               2 :     if (m_poFilterGeom == NULL && m_poAttrQuery == NULL)
     351               2 :         return poDS->getNWpts();
     352                 :         
     353               0 :     return OGRLayer::GetFeatureCount(bForce);
     354                 : }
     355                 : 
     356               0 : void GTMWaypointLayer::ResetReading()
     357                 : {
     358               0 :     nNextFID = 0;
     359               0 :     poDS->rewindWaypoint();
     360            1140 : }

Generated by: LCOV version 1.7