LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/openair - ogropenairlayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 228 178 78.1 %
Date: 2012-04-28 Functions: 9 4 44.4 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogropenairlayer.cpp 20996 2010-10-28 18:38:15Z rouault $
       3                 :  *
       4                 :  * Project:  OpenAir Translator
       5                 :  * Purpose:  Implements OGROpenAirLayer 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_openair.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: ogropenairlayer.cpp 20996 2010-10-28 18:38:15Z rouault $");
      38                 : 
      39                 : /************************************************************************/
      40                 : /*                         OGROpenAirLayer()                            */
      41                 : /************************************************************************/
      42                 : 
      43               2 : OGROpenAirLayer::OGROpenAirLayer( VSILFILE* fp )
      44                 : 
      45                 : {
      46               2 :     fpOpenAir = 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( "airspaces" );
      54               2 :     poFeatureDefn->Reference();
      55               2 :     poFeatureDefn->SetGeomType( wkbPolygon );
      56                 : 
      57               2 :     OGRFieldDefn    oField1( "CLASS", OFTString);
      58               2 :     poFeatureDefn->AddFieldDefn( &oField1 );
      59               2 :     OGRFieldDefn    oField2( "NAME", OFTString);
      60               2 :     poFeatureDefn->AddFieldDefn( &oField2 );
      61               2 :     OGRFieldDefn    oField3( "FLOOR", OFTString);
      62               2 :     poFeatureDefn->AddFieldDefn( &oField3 );
      63               2 :     OGRFieldDefn    oField4( "CEILING", OFTString);
      64               2 :     poFeatureDefn->AddFieldDefn( &oField4 );
      65               2 : }
      66                 : 
      67                 : /************************************************************************/
      68                 : /*                         ~OGROpenAirLayer()                           */
      69                 : /************************************************************************/
      70                 : 
      71               2 : OGROpenAirLayer::~OGROpenAirLayer()
      72                 : 
      73                 : {
      74               2 :     if( poSRS != NULL )
      75               2 :         poSRS->Release();
      76                 : 
      77               2 :     poFeatureDefn->Release();
      78                 : 
      79               2 :     std::map<CPLString,OpenAirStyle*>::const_iterator iter;
      80                 : 
      81               4 :     for( iter = oStyleMap.begin(); iter != oStyleMap.end(); ++iter )
      82                 :     {
      83               2 :         CPLFree(iter->second);
      84                 :     }
      85                 : 
      86               2 :     VSIFCloseL( fpOpenAir );
      87               2 : }
      88                 : 
      89                 : 
      90                 : /************************************************************************/
      91                 : /*                            ResetReading()                            */
      92                 : /************************************************************************/
      93                 : 
      94               0 : void OGROpenAirLayer::ResetReading()
      95                 : 
      96                 : {
      97               0 :     nNextFID = 0;
      98               0 :     bEOF = FALSE;
      99               0 :     bHasLastLine = FALSE;
     100               0 :     VSIFSeekL( fpOpenAir, 0, SEEK_SET );
     101               0 : }
     102                 : 
     103                 : 
     104                 : /************************************************************************/
     105                 : /*                           GetNextFeature()                           */
     106                 : /************************************************************************/
     107                 : 
     108               6 : OGRFeature *OGROpenAirLayer::GetNextFeature()
     109                 : {
     110                 :     OGRFeature  *poFeature;
     111                 : 
     112               0 :     while(TRUE)
     113                 :     {
     114               6 :         poFeature = GetNextRawFeature();
     115               6 :         if (poFeature == NULL)
     116               0 :             return NULL;
     117                 : 
     118               6 :         if((m_poFilterGeom == NULL
     119                 :             || FilterGeometry( poFeature->GetGeometryRef() ) )
     120                 :         && (m_poAttrQuery == NULL
     121                 :             || m_poAttrQuery->Evaluate( poFeature )) )
     122                 :         {
     123               6 :             return poFeature;
     124                 :         }
     125                 :         else
     126               0 :             delete poFeature;
     127                 :     }
     128                 : }
     129                 : 
     130                 : /************************************************************************/
     131                 : /*                         GetNextRawFeature()                          */
     132                 : /************************************************************************/
     133                 : 
     134               6 : OGRFeature *OGROpenAirLayer::GetNextRawFeature()
     135                 : {
     136                 :     const char* pszLine;
     137               6 :     CPLString osCLASS, osNAME, osFLOOR, osCEILING;
     138               6 :     OGRLinearRing oLR;
     139               6 :     double dfLastLat = 0, dfLastLon = 0;
     140               6 :     int bFirst = TRUE;
     141               6 :     int bClockWise = TRUE;
     142               6 :     double dfCenterLat = 0, dfCenterLon = 0;
     143               6 :     int bHasCenter = FALSE;
     144                 :     OpenAirStyle sStyle;
     145               6 :     sStyle.penStyle = -1;
     146               6 :     sStyle.penWidth = -1;
     147               6 :     sStyle.penR = sStyle.penG = sStyle.penB = -1;
     148               6 :     sStyle.fillR = sStyle.fillG = sStyle.fillB = -1;
     149                 : 
     150               6 :     if (bEOF)
     151               0 :         return NULL;
     152                 : 
     153              82 :     while(TRUE)
     154                 :     {
     155              94 :         if (bFirst && bHasLastLine)
     156                 :         {
     157               6 :             pszLine = osLastLine.c_str();
     158               6 :             bFirst = FALSE;
     159                 :         }
     160                 :         else
     161                 :         {
     162              82 :             pszLine = CPLReadLine2L(fpOpenAir, 1024, NULL);
     163              82 :             if (pszLine == NULL)
     164                 :             {
     165               2 :                 bEOF = TRUE;
     166               2 :                 if (oLR.getNumPoints() == 0)
     167               0 :                     return NULL;
     168                 : 
     169               2 :                 if (osCLASS.size() != 0 &&
     170                 :                     oStyleMap.find(osCLASS) != oStyleMap.end())
     171                 :                 {
     172               0 :                     memcpy(&sStyle, oStyleMap[osCLASS], sizeof(sStyle));
     173                 :                 }
     174               2 :                 break;
     175                 :             }
     176              80 :             osLastLine = pszLine;
     177              80 :             bHasLastLine = TRUE;
     178                 :         }
     179                 : 
     180              86 :         if (pszLine[0] == '*' || pszLine[0] == '\0')
     181              18 :             continue;
     182                 : 
     183              76 :         if (EQUALN(pszLine, "AC ", 3) || EQUALN(pszLine, "AC,", 3))
     184                 :         {
     185              12 :             if (osCLASS.size() != 0)
     186                 :             {
     187               8 :                 if (sStyle.penStyle != -1 || sStyle.fillR != -1)
     188                 :                 {
     189               2 :                     if (oLR.getNumPoints() == 0)
     190                 :                     {
     191                 :                         OpenAirStyle* psStyle;
     192               2 :                         if (oStyleMap.find(osCLASS) == oStyleMap.end())
     193                 :                         {
     194                 :                             psStyle = (OpenAirStyle*)CPLMalloc(
     195               2 :                                                     sizeof(OpenAirStyle));
     196               2 :                             oStyleMap[osCLASS] = psStyle;
     197                 :                         }
     198                 :                         else
     199               0 :                             psStyle = oStyleMap[osCLASS];
     200               2 :                         memcpy(psStyle, &sStyle, sizeof(sStyle));
     201                 :                     }
     202                 :                     else
     203               0 :                         break;
     204                 :                 }
     205               4 :                 else if (oStyleMap.find(osCLASS) != oStyleMap.end())
     206                 :                 {
     207               2 :                     memcpy(&sStyle, oStyleMap[osCLASS], sizeof(sStyle));
     208               2 :                     break;
     209                 :                 }
     210                 :                 else
     211               2 :                     break;
     212                 :             }
     213               8 :             sStyle.penStyle = -1;
     214               8 :             sStyle.penWidth = -1;
     215               8 :             sStyle.penR = sStyle.penG = sStyle.penB = -1;
     216               8 :             sStyle.fillR = sStyle.fillG = sStyle.fillB = -1;
     217               8 :             osCLASS = pszLine + 3;
     218               8 :             bClockWise = TRUE;
     219               8 :             bHasCenter = FALSE;
     220                 :         }
     221              56 :         else if (EQUALN(pszLine, "AN ", 3))
     222                 :         {
     223               6 :             if (osNAME.size() != 0)
     224               0 :                 break;
     225               6 :             osNAME = pszLine + 3;
     226                 :         }
     227              50 :         else if (EQUALN(pszLine, "AH ", 3))
     228               6 :             osCEILING = pszLine + 3;
     229              44 :         else if (EQUALN(pszLine, "AL ", 3))
     230               6 :             osFLOOR = pszLine + 3;
     231              38 :         else if (EQUALN(pszLine, "AT ", 3))
     232                 :         {
     233                 :             /* Ignored for that layer*/
     234                 :         }
     235              34 :         else if (EQUALN(pszLine, "SP ", 3))
     236                 :         {
     237               4 :             if (osCLASS.size() != 0)
     238                 :             {
     239               4 :                 char** papszTokens = CSLTokenizeString2(pszLine+3, ", ", 0);
     240               4 :                 if (CSLCount(papszTokens) == 5)
     241                 :                 {
     242               4 :                     sStyle.penStyle = atoi(papszTokens[0]);
     243               4 :                     sStyle.penWidth = atoi(papszTokens[1]);
     244               4 :                     sStyle.penR = atoi(papszTokens[2]);
     245               4 :                     sStyle.penG = atoi(papszTokens[3]);
     246               4 :                     sStyle.penB = atoi(papszTokens[4]);
     247                 :                 }
     248               4 :                 CSLDestroy(papszTokens);
     249                 :             }
     250                 :         }
     251              30 :         else if (EQUALN(pszLine, "SB ", 3))
     252                 :         {
     253               4 :             if (osCLASS.size() != 0)
     254                 :             {
     255               4 :                 char** papszTokens = CSLTokenizeString2(pszLine+3, ", ", 0);
     256               4 :                 if (CSLCount(papszTokens) == 3)
     257                 :                 {
     258               4 :                     sStyle.fillR = atoi(papszTokens[0]);
     259               4 :                     sStyle.fillG = atoi(papszTokens[1]);
     260               4 :                     sStyle.fillB = atoi(papszTokens[2]);
     261                 :                 }
     262               4 :                 CSLDestroy(papszTokens);
     263                 :             }
     264                 :         }
     265              26 :         else if (EQUALN(pszLine, "DP ", 3))
     266                 :         {
     267              10 :             pszLine += 3;
     268                 : 
     269                 :             double dfLat, dfLon;
     270              10 :             if (!OGROpenAirGetLatLon(pszLine, dfLat, dfLon))
     271               0 :                 continue;
     272                 : 
     273              10 :             oLR.addPoint(dfLon, dfLat);
     274              10 :             dfLastLat = dfLat;
     275              10 :             dfLastLon = dfLon;
     276                 :         }
     277              16 :         else if (EQUALN(pszLine, "DA ", 3))
     278                 :         {
     279               8 :             pszLine += 3;
     280                 : 
     281               8 :             char* pszStar = strchr((char*)pszLine, '*');
     282               8 :             if (pszStar) *pszStar = 0;
     283               8 :             char** papszTokens = CSLTokenizeString2(pszLine, ",", 0);
     284               8 :             if (bHasCenter && CSLCount(papszTokens) == 3)
     285                 :             {
     286               8 :                 double dfRadius = atof(papszTokens[0]) * 1852;
     287               8 :                 double dfStartAngle = atof(papszTokens[1]);
     288               8 :                 double dfEndAngle = atof(papszTokens[2]);
     289                 : 
     290              10 :                 if (bClockWise && dfEndAngle < dfStartAngle)
     291               2 :                     dfEndAngle += 360;
     292               6 :                 else if (!bClockWise && dfStartAngle < dfEndAngle)
     293               2 :                     dfEndAngle -= 360;
     294                 : 
     295               8 :                 double dfStartDistance = dfRadius;
     296               8 :                 double dfEndDistance = dfRadius;
     297               8 :                 int nSign = (bClockWise) ? 1 : -1;
     298                 :                 double dfAngle;
     299                 :                 double dfLat, dfLon;
     300            1168 :                 for(dfAngle = dfStartAngle;
     301                 :                     (dfAngle - dfEndAngle) * nSign < 0;
     302                 :                     dfAngle += nSign)
     303                 :                 {
     304                 :                     double pct = (dfAngle - dfStartAngle) /
     305            1160 :                                     (dfEndAngle - dfStartAngle);
     306                 :                     double dfDist = dfStartDistance * (1-pct) +
     307            1160 :                                                         dfEndDistance * pct;
     308                 :                     OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon,
     309            1160 :                                              dfDist, dfAngle, &dfLat, &dfLon);
     310            1160 :                     oLR.addPoint(dfLon, dfLat);
     311                 :                 }
     312                 :                 OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon,
     313               8 :                                          dfEndDistance, dfEndAngle, &dfLat, &dfLon);
     314               8 :                 oLR.addPoint(dfLon, dfLat);
     315                 : 
     316               8 :                 dfLastLat = oLR.getY(oLR.getNumPoints() - 1);
     317               8 :                 dfLastLon = oLR.getX(oLR.getNumPoints() - 1);
     318                 :             }
     319               8 :             CSLDestroy(papszTokens);
     320                 :         }
     321               8 :         else if (EQUALN(pszLine, "DB ", 3))
     322                 :         {
     323               0 :             pszLine += 3;
     324                 : 
     325               0 :             char* pszStar = strchr((char*)pszLine, '*');
     326               0 :             if (pszStar) *pszStar = 0;
     327               0 :             char** papszTokens = CSLTokenizeString2(pszLine, ",", 0);
     328                 :             double dfFirstLat, dfFirstLon;
     329                 :             double dfSecondLat, dfSecondLon;
     330               0 :             if (bHasCenter && CSLCount(papszTokens) == 2 &&
     331               0 :                 OGROpenAirGetLatLon(papszTokens[0], dfFirstLat, dfFirstLon) &&
     332               0 :                 OGROpenAirGetLatLon(papszTokens[1], dfSecondLat, dfSecondLon))
     333                 :             {
     334                 :                 double dfStartDistance =OGRXPlane_Distance(dfCenterLat,
     335               0 :                         dfCenterLon, dfFirstLat, dfFirstLon);
     336                 :                 double dfEndDistance = OGRXPlane_Distance(dfCenterLat,
     337               0 :                         dfCenterLon, dfSecondLat, dfSecondLon);
     338                 :                 double dfStartAngle = OGRXPlane_Track(dfCenterLat,
     339               0 :                         dfCenterLon, dfFirstLat, dfFirstLon);
     340                 :                 double dfEndAngle = OGRXPlane_Track(dfCenterLat,
     341               0 :                         dfCenterLon, dfSecondLat, dfSecondLon);
     342                 : 
     343               0 :                 if (bClockWise && dfEndAngle < dfStartAngle)
     344               0 :                     dfEndAngle += 360;
     345               0 :                 else if (!bClockWise && dfStartAngle < dfEndAngle)
     346               0 :                     dfEndAngle -= 360;
     347                 : 
     348               0 :                 int nSign = (bClockWise) ? 1 : -1;
     349                 :                 double dfAngle;
     350               0 :                 for(dfAngle = dfStartAngle;
     351                 :                     (dfAngle - dfEndAngle) * nSign < 0;
     352                 :                     dfAngle += nSign)
     353                 :                 {
     354                 :                     double dfLat, dfLon;
     355                 :                     double pct = (dfAngle - dfStartAngle) /
     356               0 :                                     (dfEndAngle - dfStartAngle);
     357                 :                     double dfDist = dfStartDistance * (1-pct) +
     358               0 :                                                     dfEndDistance * pct;
     359                 :                     OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon,
     360               0 :                                              dfDist, dfAngle, &dfLat, &dfLon);
     361               0 :                     oLR.addPoint(dfLon, dfLat);
     362                 :                 }
     363               0 :                 oLR.addPoint(dfSecondLon, dfSecondLat);
     364                 : 
     365               0 :                 dfLastLat = oLR.getY(oLR.getNumPoints() - 1);
     366               0 :                 dfLastLon = oLR.getX(oLR.getNumPoints() - 1);
     367                 :             }
     368               0 :             CSLDestroy(papszTokens);
     369                 :         }
     370              10 :         else if ((EQUALN(pszLine, "DC ", 3) || EQUALN(pszLine, "DC=", 3)) &&
     371                 :                  (bHasCenter || strstr(pszLine, "V X=") != NULL))
     372                 :         {
     373               2 :             if (!bHasCenter)
     374                 :             {
     375               0 :                 const char* pszVX = strstr(pszLine, "V X=");
     376               0 :                 bHasCenter = OGROpenAirGetLatLon(pszVX, dfCenterLat, dfCenterLon);
     377                 :             }
     378               2 :             if (bHasCenter)
     379                 :             {
     380               2 :                 pszLine += 3;
     381                 : 
     382               2 :                 double dfRADIUS = atof(pszLine) * 1852;
     383                 : 
     384                 :                 double dfAngle;
     385                 :                 double dfLat, dfLon;
     386             722 :                 for(dfAngle = 0; dfAngle < 360; dfAngle += 1)
     387                 :                 {
     388                 :                     OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon,
     389             720 :                                              dfRADIUS, dfAngle, &dfLat, &dfLon);
     390             720 :                     oLR.addPoint(dfLon, dfLat);
     391                 :                 }
     392                 :                 OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon,
     393               2 :                                          dfRADIUS, 0, &dfLat, &dfLon);
     394               2 :                 oLR.addPoint(dfLon, dfLat);
     395                 : 
     396               2 :                 dfLastLat = oLR.getY(oLR.getNumPoints() - 1);
     397               2 :                 dfLastLon = oLR.getX(oLR.getNumPoints() - 1);
     398                 :             }
     399                 :         }
     400               6 :         else if (EQUALN(pszLine, "V X=", 4))
     401                 :         {
     402                 :             bHasCenter =
     403               4 :                     OGROpenAirGetLatLon(pszLine + 4, dfCenterLat, dfCenterLon);
     404                 :         }
     405               2 :         else if (EQUALN(pszLine, "V D=-", 5))
     406                 :         {
     407               2 :             bClockWise = FALSE;
     408                 :         }
     409               0 :         else if (EQUALN(pszLine, "V D=+", 5))
     410                 :         {
     411               0 :             bClockWise = TRUE;
     412                 :         }
     413                 :         else
     414                 :         {
     415                 :             //CPLDebug("OpenAir", "Unexpected content : %s", pszLine);
     416                 :         }
     417                 :     }
     418                 : 
     419               6 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     420              12 :     poFeature->SetField(0, osCLASS.c_str());
     421               6 :     poFeature->SetField(1, osNAME.c_str());
     422               6 :     poFeature->SetField(2, osFLOOR.c_str());
     423               6 :     poFeature->SetField(3, osCEILING.c_str());
     424                 : 
     425               6 :     if (sStyle.penStyle != -1 || sStyle.fillR != -1)
     426                 :     {
     427               4 :         CPLString osStyle;
     428               4 :         if (sStyle.penStyle != -1)
     429                 :         {
     430                 :             osStyle += CPLString().Printf("PEN(c:#%02X%02X%02X,w:%dpt",
     431                 :                                  sStyle.penR, sStyle.penG, sStyle.penB,
     432               4 :                                  sStyle.penWidth);
     433               4 :             if (sStyle.penStyle == 1)
     434               2 :                 osStyle += ",p:\"5px 5px\"";
     435               4 :             osStyle += ")";
     436                 :         }
     437               4 :         if (sStyle.fillR != -1)
     438                 :         {
     439               4 :             if (osStyle.size() != 0)
     440               4 :                 osStyle += ";";
     441                 :             osStyle += CPLString().Printf("BRUSH(fc:#%02X%02X%02X)",
     442               4 :                                  sStyle.fillR, sStyle.fillG, sStyle.fillB);
     443                 :         }
     444                 :         else
     445                 :         {
     446               0 :             if (osStyle.size() != 0)
     447               0 :                 osStyle += ";";
     448               0 :             osStyle += "BRUSH(fc:#00000000,id:\"ogr-brush-1\")";
     449                 :         }
     450               4 :         if (osStyle.size() != 0)
     451               4 :             poFeature->SetStyleString(osStyle);
     452                 :     }
     453                 : 
     454               6 :     OGRPolygon* poPoly = new OGRPolygon();
     455               6 :     oLR.closeRings();
     456               6 :     poPoly->addRing(&oLR);
     457               6 :     poPoly->assignSpatialReference(poSRS);
     458               6 :     poFeature->SetGeometryDirectly(poPoly);
     459               6 :     poFeature->SetFID(nNextFID++);
     460                 : 
     461               6 :     return poFeature;
     462                 : }
     463                 : /************************************************************************/
     464                 : /*                           TestCapability()                           */
     465                 : /************************************************************************/
     466                 : 
     467               0 : int OGROpenAirLayer::TestCapability( const char * pszCap )
     468                 : 
     469                 : {
     470               0 :     return FALSE;
     471                 : }
     472                 : 

Generated by: LCOV version 1.7