LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/gtm - gtmtracklayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 175 142 81.1 %
Date: 2010-01-09 Functions: 12 10 83.3 %

       1                 : /******************************************************************************
       2                 :  * $Id: gtmtracklayer.cpp 17637 2009-09-12 23:22:00Z warmerdam $
       3                 :  *
       4                 :  * Project:  GTM Driver
       5                 :  * Purpose:  Implementation of GTMTrackLayer 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                 : 
      32                 : 
      33               4 : GTMTrackLayer::GTMTrackLayer( const char* pszName,
      34                 :                               OGRSpatialReference* poSRSIn,
      35                 :                               int bWriterIn,
      36               4 :                               OGRGTMDataSource* poDSIn )
      37                 : {
      38               4 :     poCT = NULL;
      39                 :   
      40                 :     /* We are implementing just WGS84, although GTM supports other datum
      41                 :        formats. */
      42               4 :     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               1 :         poSRS = NULL;
      74                 :     }
      75                 : 
      76               4 :     poDS = poDSIn;
      77                 : 
      78               4 :     nNextFID = 0;
      79               4 :     nTotalFCount = poDS->getNTracks();
      80                 : 
      81               4 :     poFeatureDefn = new OGRFeatureDefn( pszName );
      82               4 :     poFeatureDefn->Reference();
      83               4 :     poFeatureDefn->SetGeomType ( wkbLineString );
      84                 : 
      85                 :     /* We implement just name, type, and color for tracks, if others
      86                 :        needed feel free to append more parameters and implement the
      87                 :        code */
      88               4 :     OGRFieldDefn oFieldName( "name", OFTString );
      89               4 :     poFeatureDefn->AddFieldDefn( &oFieldName );
      90                 : 
      91               4 :     OGRFieldDefn oFieldTrackType( "type", OFTInteger );
      92               4 :     poFeatureDefn->AddFieldDefn( &oFieldTrackType );
      93                 : 
      94               4 :     OGRFieldDefn oFieldColor( "color", OFTInteger );
      95               4 :     poFeatureDefn->AddFieldDefn( &oFieldColor );
      96                 :   
      97               4 :     this->pszName = CPLStrdup(pszName);
      98               4 : }
      99                 : 
     100               8 : GTMTrackLayer::~GTMTrackLayer()
     101                 : {
     102                 :     /* poDS, poSRS, poCT, pszName, and poFeatureDefn are released on
     103                 :        parent class*/
     104               8 : }
     105                 : 
     106                 : 
     107                 : /************************************************************************/
     108                 : /*                      WriteFeatureAttributes()                        */
     109                 : /************************************************************************/
     110               4 : void GTMTrackLayer::WriteFeatureAttributes( OGRFeature *poFeature )
     111                 : {
     112               4 :     void* pBuffer = NULL;
     113               4 :     char* psztrackname = NULL;
     114               4 :     int type = 1;
     115               4 :     unsigned int color = 0;
     116              16 :     for (int i = 0; i < poFeatureDefn->GetFieldCount(); ++i)
     117                 :     {
     118              12 :         OGRFieldDefn *poFieldDefn = poFeatureDefn->GetFieldDefn( i );
     119              12 :         if( poFeature->IsFieldSet( i ) )
     120                 :         {
     121              12 :             const char* pszName = poFieldDefn->GetNameRef();
     122                 :             /* track name */
     123              12 :             if (strncmp(pszName, "name", 4) == 0)
     124                 :             {
     125               4 :                 psztrackname = CPLStrdup( poFeature->GetFieldAsString( i ) );
     126                 :             }
     127                 :             /* track type */
     128               8 :             else if (strncmp(pszName, "type", 4) == 0)
     129                 :             {
     130               4 :                 type = poFeature->GetFieldAsInteger( i );
     131                 :                 // Check if it is a valid type
     132               4 :                 if (type < 1 || type > 30)
     133               0 :                     type = 1;
     134                 :             }
     135                 :             /* track color */
     136               4 :             else if (strncmp(pszName, "color", 5) == 0)
     137                 :             {
     138               4 :                 color = (unsigned int) poFeature->GetFieldAsInteger( i );
     139               4 :                 if (color > 0xFFFFFF)
     140               0 :                     color = 0xFFFFFFF;
     141                 :             }
     142                 :         }
     143                 :     }
     144                 : 
     145               4 :     if (psztrackname == NULL)
     146               0 :         psztrackname = CPLStrdup( "" );
     147                 : 
     148               4 :     int trackNameLength = 0;
     149               4 :     if (psztrackname != NULL)
     150               4 :         trackNameLength = strlen(psztrackname);
     151                 : 
     152               4 :     int bufferSize = 14 + trackNameLength;
     153               4 :     pBuffer = CPLMalloc(bufferSize);
     154               4 :     void* pBufferAux = pBuffer;
     155                 :     /* Write track string name size to buffer */
     156               4 :     appendUShort(pBufferAux, trackNameLength);
     157               4 :     pBufferAux = (char*)pBufferAux + 2;
     158                 : 
     159                 :     /* Write track name */
     160               4 :     strncpy((char*)pBufferAux, psztrackname, trackNameLength);
     161               4 :     pBufferAux = (char*)pBufferAux + trackNameLength;
     162                 : 
     163                 :     /* Write track type */
     164               4 :     appendUChar(pBufferAux, type);
     165               4 :     pBufferAux = (char*)pBufferAux + 1;
     166                 :   
     167                 :     /* Write track color */
     168               4 :     appendInt(pBufferAux, color);
     169               4 :     pBufferAux = (char*)pBufferAux + 4;
     170                 :   
     171                 :     /* Write track scale */
     172               4 :     appendFloat(pBufferAux, 0);
     173               4 :     pBufferAux = (char*)pBufferAux + 4;
     174                 : 
     175                 :     /* Write track label */
     176               4 :     appendUChar(pBufferAux, 0);
     177               4 :     pBufferAux = (char*)pBufferAux + 1;
     178                 : 
     179                 :     /* Write track layer */
     180               4 :     appendUShort(pBufferAux, 0);
     181                 : 
     182               4 :     VSIFWriteL(pBuffer, bufferSize, 1, poDS->getTmpTracksFP());
     183               4 :     poDS->incNumTracks();
     184                 : 
     185               4 :     if (psztrackname != NULL)
     186               4 :         CPLFree(psztrackname);
     187               4 :     CPLFree(pBuffer);
     188               4 : }
     189                 : 
     190                 : /************************************************************************/
     191                 : /*                          WriteTrackpoint()                           */
     192                 : /************************************************************************/
     193              15 : inline void GTMTrackLayer::WriteTrackpoint( double lat, double lon, float altitude, bool start )
     194                 : {
     195              15 :     void* pBuffer = CPLMalloc(25);
     196              15 :     void* pBufferAux = pBuffer;
     197                 :     //latitude
     198              15 :     appendDouble(pBufferAux, lat);
     199              15 :     pBufferAux = (char*)pBufferAux + 8; 
     200                 :     //longitude
     201              15 :     appendDouble(pBufferAux, lon);
     202              15 :     pBufferAux = (char*)pBufferAux + 8; 
     203                 :     //date
     204              15 :     appendInt(pBufferAux, 0);
     205              15 :     pBufferAux = (char*)pBufferAux + 4; 
     206                 :     //start
     207              15 :     appendUChar(pBufferAux, start);
     208              15 :     pBufferAux = (char*)pBufferAux + 1; 
     209                 :     //altitude
     210              15 :     appendFloat(pBufferAux, altitude);
     211              15 :     VSIFWriteL(pBuffer, 25, 1, poDS->getTmpTrackpointsFP());
     212              15 :     poDS->incNumTrackpoints();
     213              15 :     CPLFree(pBuffer);
     214              15 : }
     215                 : 
     216                 : 
     217                 : /************************************************************************/
     218                 : /*                           CreateFeature()                            */
     219                 : /************************************************************************/
     220               3 : OGRErr GTMTrackLayer::CreateFeature (OGRFeature *poFeature)
     221                 : {
     222               3 :     FILE* fpTmpTrackpoints = poDS->getTmpTrackpointsFP();
     223               3 :     if (fpTmpTrackpoints == NULL)
     224               0 :         return CE_Failure;
     225                 : 
     226               3 :     FILE* fpTmpTracks = poDS->getTmpTracksFP();
     227               3 :     if (fpTmpTracks == NULL)
     228               0 :         return CE_Failure;
     229                 : 
     230               3 :     OGRGeometry *poGeom = poFeature->GetGeometryRef();
     231               3 :     if ( poGeom == NULL )
     232                 :     {
     233                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     234               0 :                   "Features without geometry not supported by GTM writer in track layer." );
     235               0 :         return OGRERR_FAILURE;
     236                 :     }
     237                 :    
     238               3 :     if (NULL != poCT)
     239                 :     {
     240               0 :         poGeom = poGeom->clone();
     241               0 :         poGeom->transform( poCT );
     242                 :     }
     243                 :     
     244               3 :     switch( poGeom->getGeometryType() )
     245                 :     {
     246                 :     case wkbLineString:
     247                 :     case wkbLineString25D:
     248                 :     {
     249               2 :         WriteFeatureAttributes(poFeature);
     250               2 :         OGRLineString* line = (OGRLineString*)poGeom;
     251              10 :         for(int i = 0; i < line->getNumPoints(); ++i)
     252                 :         {
     253               8 :             double lat = line->getY(i);
     254               8 :             double lon = line->getX(i);
     255               8 :             float altitude = 0;
     256               8 :             CheckAndFixCoordinatesValidity(lat, lon);
     257               8 :             poDS->checkBounds((float)lat, (float)lon);
     258               8 :             if (line->getGeometryType() == wkbLineString25D)
     259               0 :         altitude = (float)line->getZ(i);
     260               8 :             WriteTrackpoint( lat, lon, altitude, i==0 );
     261                 :         }
     262               2 :         break;
     263                 :     }
     264                 : 
     265                 :     case wkbMultiLineString:
     266                 :     case wkbMultiLineString25D:
     267                 :     {
     268               1 :         int nGeometries = ((OGRGeometryCollection*)poGeom)->getNumGeometries ();
     269               3 :         for(int j = 0; j < nGeometries; ++j)
     270                 :         {
     271               2 :             WriteFeatureAttributes(poFeature);
     272               2 :             OGRLineString* line = (OGRLineString*) ( ((OGRGeometryCollection*)poGeom)->getGeometryRef(j) );
     273               2 :             int n = (line) ? line->getNumPoints() : 0;
     274               9 :             for(int i = 0; i < n; ++i)
     275                 :             {
     276               7 :                 double lat = line->getY(i);
     277               7 :                 double lon = line->getX(i);
     278               7 :                 float altitude = 0;
     279               7 :                 CheckAndFixCoordinatesValidity(lat, lon);
     280               7 :                 if (line->getGeometryType() == wkbLineString25D)
     281               0 :       altitude = (float) line->getZ(i);
     282               7 :                 WriteTrackpoint( lat, lon, altitude, i==0 );
     283                 :             }
     284                 :         }
     285               1 :         break;
     286                 :     }
     287                 :     
     288                 :     default:
     289                 :     {
     290                 :         CPLError( CE_Failure, CPLE_NotSupported,
     291                 :                   "Geometry type of `%s' not supported for 'track' element.\n",
     292               0 :                   OGRGeometryTypeToName(poGeom->getGeometryType()) );
     293               0 :         if (NULL != poCT)
     294               0 :             delete poGeom;
     295               0 :         return OGRERR_FAILURE;
     296                 :     }
     297                 :     }
     298                 :     
     299               3 :     if (NULL != poCT)
     300               0 :         delete poGeom;
     301                 : 
     302               3 :     return OGRERR_NONE;
     303                 : }
     304                 : 
     305                 : 
     306               7 : OGRFeature* GTMTrackLayer::GetNextFeature()
     307                 : {
     308               7 :     if (bError)
     309               0 :         return NULL;
     310                 :         
     311              14 :     while (poDS->hasNextTrack())
     312                 :     {
     313               7 :         Track* poTrack = poDS->fetchNextTrack();
     314               7 :         if (poTrack == NULL)
     315                 :         {
     316                 :             CPLError(CE_Failure, CPLE_AppDefined,
     317               0 :                      "Could not read track. File probably corrupted");
     318               0 :             bError = TRUE;
     319               0 :             return NULL;
     320                 :         }
     321               7 :         OGRFeature* poFeature = new OGRFeature( poFeatureDefn );
     322              14 :         OGRLineString* lineString = new OGRLineString ();
     323                 :     
     324              37 :         for (int i = 0; i < poTrack->getNumPoints(); ++i)
     325                 :         {
     326              30 :             const TrackPoint* psTrackPoint = poTrack->getPoint(i);
     327                 :             lineString->addPoint(psTrackPoint->x, 
     328              30 :                                  psTrackPoint->y);
     329                 :         }
     330               7 :         if (poSRS)
     331               7 :             lineString->assignSpatialReference(poSRS);
     332               7 :         poFeature->SetField( NAME, poTrack->getName());
     333               7 :         poFeature->SetField( TYPE, poTrack->getType());
     334               7 :         poFeature->SetField( COLOR, poTrack->getColor());
     335               7 :         poFeature->SetFID( nNextFID++ );
     336               7 :         delete poTrack;
     337                 : 
     338               7 :         poFeature->SetGeometryDirectly(lineString);
     339               7 :         if( (m_poFilterGeom == NULL
     340                 :              || FilterGeometry( poFeature->GetGeometryRef() ) )
     341                 :             && (m_poAttrQuery == NULL
     342                 :                 || m_poAttrQuery->Evaluate( poFeature )) )
     343               7 :             return poFeature;
     344                 : 
     345               0 :         delete poFeature;
     346                 :     }
     347               0 :     return NULL;
     348                 : }
     349                 : 
     350               2 : int GTMTrackLayer::GetFeatureCount(int bForce)
     351                 : {
     352               2 :     if (m_poFilterGeom == NULL && m_poAttrQuery == NULL)
     353               2 :         return poDS->getNTracks();
     354                 :         
     355               0 :     return OGRLayer::GetFeatureCount(bForce);
     356                 : }
     357                 : 
     358                 : 
     359               0 : void GTMTrackLayer::ResetReading()
     360                 : {
     361               0 :     nNextFID = 0;
     362               0 :     poDS->rewindTrack();
     363            1140 : }
     364                 : 

Generated by: LCOV version 1.7