LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/sua - ogrsualayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 193 156 80.8 %
Date: 2012-04-28 Functions: 10 5 50.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsualayer.cpp 23066 2011-09-05 21:10:19Z rouault $
       3                 :  *
       4                 :  * Project:  SUA Translator
       5                 :  * Purpose:  Implements OGRSUALayer class.
       6                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2010, Even Rouault <even dot rouault at mines dash paris dot org>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_sua.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : #include "ogr_p.h"
      34                 : #include "ogr_xplane_geo_utils.h"
      35                 : #include "ogr_srs_api.h"
      36                 : 
      37                 : CPL_CVSID("$Id: ogrsualayer.cpp 23066 2011-09-05 21:10:19Z rouault $");
      38                 : 
      39                 : /************************************************************************/
      40                 : /*                            OGRSUALayer()                             */
      41                 : /************************************************************************/
      42                 : 
      43               2 : OGRSUALayer::OGRSUALayer( VSILFILE* fp )
      44                 : 
      45                 : {
      46               2 :     fpSUA = fp;
      47               2 :     nNextFID = 0;
      48               2 :     bEOF = FALSE;
      49               2 :     bHasLastLine = FALSE;
      50                 : 
      51               2 :     poSRS = new OGRSpatialReference(SRS_WKT_WGS84);
      52                 : 
      53               4 :     poFeatureDefn = new OGRFeatureDefn( "layer" );
      54               2 :     poFeatureDefn->Reference();
      55               2 :     poFeatureDefn->SetGeomType( wkbPolygon );
      56                 : 
      57               2 :     OGRFieldDefn    oField1( "TYPE", OFTString);
      58               2 :     poFeatureDefn->AddFieldDefn( &oField1 );
      59               2 :     OGRFieldDefn    oField2( "CLASS", OFTString);
      60               2 :     poFeatureDefn->AddFieldDefn( &oField2 );
      61               2 :     OGRFieldDefn    oField3( "TITLE", OFTString);
      62               2 :     poFeatureDefn->AddFieldDefn( &oField3 );
      63               2 :     OGRFieldDefn    oField4( "TOPS", OFTString);
      64               2 :     poFeatureDefn->AddFieldDefn( &oField4 );
      65               2 :     OGRFieldDefn    oField5( "BASE", OFTString);
      66               2 :     poFeatureDefn->AddFieldDefn( &oField5 );
      67               2 : }
      68                 : 
      69                 : /************************************************************************/
      70                 : /*                            ~OGRSUALayer()                            */
      71                 : /************************************************************************/
      72                 : 
      73               2 : OGRSUALayer::~OGRSUALayer()
      74                 : 
      75                 : {
      76               2 :     if( poSRS != NULL )
      77               2 :         poSRS->Release();
      78                 : 
      79               2 :     poFeatureDefn->Release();
      80                 : 
      81               2 :     VSIFCloseL( fpSUA );
      82               2 : }
      83                 : 
      84                 : 
      85                 : /************************************************************************/
      86                 : /*                            ResetReading()                            */
      87                 : /************************************************************************/
      88                 : 
      89               0 : void OGRSUALayer::ResetReading()
      90                 : 
      91                 : {
      92               0 :     nNextFID = 0;
      93               0 :     bEOF = FALSE;
      94               0 :     bHasLastLine = FALSE;
      95               0 :     VSIFSeekL( fpSUA, 0, SEEK_SET );
      96               0 : }
      97                 : 
      98                 : 
      99                 : /************************************************************************/
     100                 : /*                           GetNextFeature()                           */
     101                 : /************************************************************************/
     102                 : 
     103               4 : OGRFeature *OGRSUALayer::GetNextFeature()
     104                 : {
     105                 :     OGRFeature  *poFeature;
     106                 : 
     107               0 :     while(TRUE)
     108                 :     {
     109               4 :         poFeature = GetNextRawFeature();
     110               4 :         if (poFeature == NULL)
     111               0 :             return NULL;
     112                 : 
     113               4 :         if((m_poFilterGeom == NULL
     114                 :             || FilterGeometry( poFeature->GetGeometryRef() ) )
     115                 :         && (m_poAttrQuery == NULL
     116                 :             || m_poAttrQuery->Evaluate( poFeature )) )
     117                 :         {
     118               4 :             return poFeature;
     119                 :         }
     120                 :         else
     121               0 :             delete poFeature;
     122                 :     }
     123                 : }
     124                 : 
     125                 : 
     126                 : 
     127                 : /************************************************************************/
     128                 : /*                              GetLatLon()                             */
     129                 : /************************************************************************/
     130                 : 
     131              24 : static int GetLatLon(const char* pszStr, double& dfLat, double& dfLon)
     132                 : {
     133              24 :     if (pszStr[7] != ' ')
     134               0 :         return FALSE;
     135              24 :     if (pszStr[0] != 'N' && pszStr[0] != 'S')
     136               0 :         return FALSE;
     137              24 :     if (pszStr[8] != 'E' && pszStr[8] != 'W')
     138               0 :         return FALSE;
     139                 : 
     140                 :     char szDeg[4], szMin[3], szSec[3];
     141              24 :     szDeg[0] = pszStr[1];
     142              24 :     szDeg[1] = pszStr[2];
     143              24 :     szDeg[2] = 0;
     144              24 :     szMin[0] = pszStr[3];
     145              24 :     szMin[1] = pszStr[4];
     146              24 :     szMin[2] = 0;
     147              24 :     szSec[0] = pszStr[5];
     148              24 :     szSec[1] = pszStr[6];
     149              24 :     szSec[2] = 0;
     150                 : 
     151              24 :     dfLat = atoi(szDeg) + atoi(szMin) / 60. + atoi(szSec) / 3600.;
     152              24 :     if (pszStr[0] == 'S')
     153              24 :         dfLat = -dfLat;
     154                 : 
     155              24 :     szDeg[0] = pszStr[9];
     156              24 :     szDeg[1] = pszStr[10];
     157              24 :     szDeg[2] = pszStr[11];
     158              24 :     szDeg[3] = 0;
     159              24 :     szMin[0] = pszStr[12];
     160              24 :     szMin[1] = pszStr[13];
     161              24 :     szMin[2] = 0;
     162              24 :     szSec[0] = pszStr[14];
     163              24 :     szSec[1] = pszStr[15];
     164              24 :     szSec[2] = 0;
     165                 : 
     166              24 :     dfLon = atoi(szDeg) + atoi(szMin) / 60. + atoi(szSec) / 3600.;
     167              24 :     if (pszStr[8] == 'W')
     168               0 :         dfLon = -dfLon;
     169                 : 
     170              24 :     return TRUE;
     171                 : }
     172                 : 
     173                 : /************************************************************************/
     174                 : /*                         GetNextRawFeature()                          */
     175                 : /************************************************************************/
     176                 : 
     177               4 : OGRFeature *OGRSUALayer::GetNextRawFeature()
     178                 : {
     179                 :     const char* pszLine;
     180               4 :     CPLString osTYPE, osCLASS, osTITLE, osTOPS, osBASE;
     181               4 :     OGRLinearRing oLR;
     182               4 :     double dfLastLat = 0, dfLastLon = 0;
     183               4 :     int bFirst = TRUE;
     184                 : 
     185               4 :     if (bEOF)
     186               0 :         return NULL;
     187                 : 
     188             168 :     while(TRUE)
     189                 :     {
     190             176 :         if (bFirst && bHasLastLine)
     191                 :         {
     192               4 :             pszLine = osLastLine.c_str();
     193               4 :             bFirst = FALSE;
     194                 :         }
     195                 :         else
     196                 :         {
     197             168 :             pszLine = CPLReadLine2L(fpSUA, 1024, NULL);
     198             168 :             if (pszLine == NULL)
     199                 :             {
     200               2 :                 bEOF = TRUE;
     201               2 :                 if (oLR.getNumPoints() == 0)
     202               0 :                     return NULL;
     203               2 :                 break;
     204                 :             }
     205             166 :             osLastLine = pszLine;
     206             166 :             bHasLastLine = TRUE;
     207                 :         }
     208                 : 
     209             170 :         if (pszLine[0] == '#' || pszLine[0] == '\0')
     210             126 :             continue;
     211                 : 
     212              44 :         if (EQUALN(pszLine, "TYPE=", 5))
     213                 :         {
     214               6 :             if (osTYPE.size() != 0)
     215               2 :                 break;
     216               4 :             osTYPE = pszLine + 5;
     217                 :         }
     218              38 :         else if (EQUALN(pszLine, "CLASS=", 6))
     219                 :         {
     220               0 :             if (osCLASS.size() != 0)
     221               0 :                 break;
     222               0 :             osCLASS = pszLine + 6;
     223                 :         }
     224              38 :         else if (EQUALN(pszLine, "TITLE=", 6))
     225                 :         {
     226               4 :             if (osTITLE.size() != 0)
     227               0 :                 break;
     228               4 :             osTITLE = pszLine + 6;
     229                 :         }
     230              34 :         else if (EQUALN(pszLine, "TOPS=", 5))
     231               4 :             osTOPS = pszLine + 5;
     232              30 :         else if (EQUALN(pszLine, "BASE=", 5))
     233               4 :             osBASE = pszLine + 5;
     234              26 :         else if (EQUALN(pszLine, "POINT=", 6))
     235                 :         {
     236              14 :             pszLine += 6;
     237              14 :             if (strlen(pszLine) != 16)
     238               0 :                 continue;
     239                 : 
     240                 :             double dfLat, dfLon;
     241              14 :             if (!GetLatLon(pszLine, dfLat, dfLon))
     242               0 :                 continue;
     243                 : 
     244              14 :             oLR.addPoint(dfLon, dfLat);
     245              14 :             dfLastLat = dfLat;
     246              14 :             dfLastLon = dfLon;
     247                 :         }
     248              16 :         else if (EQUALN(pszLine, "CLOCKWISE", 9) || EQUALN(pszLine, "ANTI-CLOCKWISE", 14))
     249                 :         {
     250               4 :             if (oLR.getNumPoints() == 0)
     251               0 :                 continue;
     252                 : 
     253               4 :             int bClockWise = EQUALN(pszLine, "CLOCKWISE", 9);
     254                 : 
     255                 :             /*const char* pszRADIUS = strstr(pszLine, "RADIUS=");
     256                 :             if (pszRADIUS == NULL)
     257                 :                 continue;
     258                 :             double dfRADIUS = atof(pszRADIUS + 7) * 1852;*/
     259                 : 
     260               4 :             const char* pszCENTRE = strstr(pszLine, "CENTRE=");
     261               4 :             if (pszCENTRE == NULL)
     262               0 :                 continue;
     263               4 :             pszCENTRE += 7;
     264               4 :             if (strlen(pszCENTRE) < 17 || pszCENTRE[16] != ' ')
     265               0 :                 continue;
     266                 :             double dfCenterLat, dfCenterLon;
     267               4 :             if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon))
     268               0 :                 continue;
     269                 : 
     270               4 :             const char* pszTO = strstr(pszLine, "TO=");
     271               4 :             if (pszTO == NULL)
     272               0 :                 continue;
     273               4 :             pszTO += 3;
     274               4 :             if (strlen(pszTO) != 16)
     275               0 :                 continue;
     276                 :             double dfToLat, dfToLon;
     277               4 :             if (!GetLatLon(pszTO, dfToLat, dfToLon))
     278               0 :                 continue;
     279                 : 
     280               4 :             double dfStartDistance = OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon);
     281               4 :             double dfEndDistance = OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfToLat, dfToLon);
     282               4 :             double dfStartAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon);
     283               4 :             double dfEndAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfToLat, dfToLon);
     284               8 :             if (bClockWise && dfEndAngle < dfStartAngle)
     285               4 :                 dfEndAngle += 360;
     286               0 :             else if (!bClockWise && dfStartAngle < dfEndAngle)
     287               0 :                 dfEndAngle -= 360;
     288                 : 
     289               4 :             int nSign = (bClockWise) ? 1 : -1;
     290                 :             double dfAngle;
     291             788 :             for(dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign)
     292                 :             {
     293                 :                 double dfLat, dfLon;
     294             784 :                 double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle);
     295             784 :                 double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct;
     296             784 :                 OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon);
     297             784 :                 oLR.addPoint(dfLon, dfLat);
     298                 :             }
     299               4 :             oLR.addPoint(dfToLon, dfToLat);
     300                 : 
     301               4 :             dfLastLat = oLR.getY(oLR.getNumPoints() - 1);
     302               4 :             dfLastLon = oLR.getX(oLR.getNumPoints() - 1);
     303                 :         }
     304               8 :         else if (EQUALN(pszLine, "CIRCLE", 6))
     305                 :         {
     306               2 :             const char* pszRADIUS = strstr(pszLine, "RADIUS=");
     307               2 :             if (pszRADIUS == NULL)
     308               0 :                 continue;
     309               2 :             double dfRADIUS = atof(pszRADIUS + 7) * 1852;
     310                 : 
     311               2 :             const char* pszCENTRE = strstr(pszLine, "CENTRE=");
     312               2 :             if (pszCENTRE == NULL)
     313               0 :                 continue;
     314               2 :             pszCENTRE += 7;
     315               2 :             if (strlen(pszCENTRE) != 16)
     316               0 :                 continue;
     317                 :             double dfCenterLat, dfCenterLon;
     318               2 :             if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon))
     319               0 :                 continue;
     320                 : 
     321                 :             double dfAngle;
     322                 :             double dfLat, dfLon;
     323             722 :             for(dfAngle = 0; dfAngle < 360; dfAngle += 1)
     324                 :             {
     325             720 :                 OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, dfAngle, &dfLat, &dfLon);
     326             720 :                 oLR.addPoint(dfLon, dfLat);
     327                 :             }
     328               2 :             OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, 0, &dfLat, &dfLon);
     329               2 :             oLR.addPoint(dfLon, dfLat);
     330                 : 
     331               2 :             dfLastLat = oLR.getY(oLR.getNumPoints() - 1);
     332               2 :             dfLastLon = oLR.getX(oLR.getNumPoints() - 1);
     333                 :         }
     334               6 :         else if (EQUALN(pszLine, "INCLUDE", 7) || EQUALN(pszLine, "END", 3))
     335                 :         {
     336                 :         }
     337                 :         else
     338                 :         {
     339               0 :             CPLDebug("SUA", "Unexpected content : %s", pszLine);
     340                 :         }
     341                 :     }
     342                 : 
     343               4 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     344               8 :     poFeature->SetField(0, osTYPE.c_str());
     345               4 :     poFeature->SetField(1, osCLASS.c_str());
     346               4 :     poFeature->SetField(2, osTITLE.c_str());
     347               4 :     poFeature->SetField(3, osTOPS.c_str());
     348               4 :     poFeature->SetField(4, osBASE.c_str());
     349                 : 
     350               4 :     OGRPolygon* poPoly = new OGRPolygon();
     351               4 :     poPoly->assignSpatialReference(poSRS);
     352               4 :     oLR.closeRings();
     353               4 :     poPoly->addRing(&oLR);
     354               4 :     poFeature->SetGeometryDirectly(poPoly);
     355               4 :     poFeature->SetFID(nNextFID++);
     356                 : 
     357               4 :     return poFeature;
     358                 : }
     359                 : /************************************************************************/
     360                 : /*                           TestCapability()                           */
     361                 : /************************************************************************/
     362                 : 
     363               0 : int OGRSUALayer::TestCapability( const char * pszCap )
     364                 : 
     365                 : {
     366               0 :     return FALSE;
     367                 : }
     368                 : 

Generated by: LCOV version 1.7