LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/dxf - ogrdxflayer.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 660
Code covered: 64.2 % Executed lines: 424

       1                 : /******************************************************************************
       2                 :  * $Id: ogrdxflayer.cpp 19643 2010-05-08 21:56:18Z rouault $
       3                 :  *
       4                 :  * Project:  DXF Translator
       5                 :  * Purpose:  Implements OGRDXFLayer class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2009, Frank Warmerdam <warmerdam@pobox.com>
      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_dxf.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "ogrdxf_polyline_smooth.h"
      33                 : 
      34                 :         
      35                 : CPL_CVSID("$Id: ogrdxflayer.cpp 19643 2010-05-08 21:56:18Z rouault $");
      36                 : 
      37                 : #ifndef PI
      38                 : #define PI  3.14159265358979323846
      39                 : #endif 
      40                 : 
      41                 : /************************************************************************/
      42                 : /*                            OGRDXFLayer()                             */
      43                 : /************************************************************************/
      44                 : 
      45               6 : OGRDXFLayer::OGRDXFLayer( OGRDXFDataSource *poDS )

      46                 : 
      47                 : {
      48               6 :     this->poDS = poDS;

      49                 : 
      50               6 :     iNextFID = 0;

      51                 : 
      52               6 :     poFeatureDefn = new OGRFeatureDefn( "entities" );

      53               6 :     poFeatureDefn->Reference();

      54                 : 
      55               6 :     OGRFieldDefn  oLayerField( "Layer", OFTString );

      56               6 :     poFeatureDefn->AddFieldDefn( &oLayerField );

      57                 : 
      58               6 :     OGRFieldDefn  oClassField( "SubClasses", OFTString );

      59               6 :     poFeatureDefn->AddFieldDefn( &oClassField );

      60                 : 
      61               6 :     OGRFieldDefn  oExtendedField( "ExtendedEntity", OFTString );

      62               6 :     poFeatureDefn->AddFieldDefn( &oExtendedField );

      63                 : 
      64               6 :     OGRFieldDefn  oLinetypeField( "Linetype", OFTString );

      65               6 :     poFeatureDefn->AddFieldDefn( &oLinetypeField );

      66                 : 
      67               6 :     OGRFieldDefn  oEntityHandleField( "EntityHandle", OFTString );

      68               6 :     poFeatureDefn->AddFieldDefn( &oEntityHandleField );

      69                 : 
      70               6 :     OGRFieldDefn  oTextField( "Text", OFTString );

      71               6 :     poFeatureDefn->AddFieldDefn( &oTextField );

      72               6 : }

      73                 : 
      74                 : /************************************************************************/
      75                 : /*                           ~OGRDXFLayer()                           */
      76                 : /************************************************************************/
      77                 : 
      78               6 : OGRDXFLayer::~OGRDXFLayer()

      79                 : 
      80                 : {
      81               6 :     ClearPendingFeatures();

      82               6 :     if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )

      83                 :     {
      84                 :         CPLDebug( "DXF", "%d features read on layer '%s'.",
      85                 :                   (int) m_nFeaturesRead, 
      86               6 :                   poFeatureDefn->GetName() );

      87                 :     }
      88                 : 
      89               6 :     if( poFeatureDefn )

      90               6 :         poFeatureDefn->Release();

      91               6 : }

      92                 : 
      93                 : /************************************************************************/
      94                 : /*                        ClearPendingFeatures()                        */
      95                 : /************************************************************************/
      96                 : 
      97              15 : void OGRDXFLayer::ClearPendingFeatures()

      98                 : 
      99                 : {
     100              30 :     while( !apoPendingFeatures.empty() )

     101                 :     {
     102               0 :         delete apoPendingFeatures.top();

     103               0 :         apoPendingFeatures.pop();

     104                 :     }
     105              15 : }

     106                 : 
     107                 : /************************************************************************/
     108                 : /*                            ResetReading()                            */
     109                 : /************************************************************************/
     110                 : 
     111               9 : void OGRDXFLayer::ResetReading()

     112                 : 
     113                 : {
     114               9 :     iNextFID = 0;

     115               9 :     ClearPendingFeatures();

     116               9 :     poDS->RestartEntities();

     117               9 : }

     118                 : 
     119                 : /************************************************************************/
     120                 : /*                      TranslateGenericProperty()                      */
     121                 : /*                                                                      */
     122                 : /*      Try and convert entity properties handled similarly for most    */
     123                 : /*      or all entity types.                                            */
     124                 : /************************************************************************/
     125                 : 
     126                 : void OGRDXFLayer::TranslateGenericProperty( OGRFeature *poFeature, 
     127             230 :                                             int nCode, char *pszValue )

     128                 : 
     129                 : {
     130             230 :     switch( nCode )

     131                 :     {
     132                 :       case 8: 
     133              29 :         poFeature->SetField( "Layer", pszValue );

     134              29 :         break;

     135                 :             
     136                 :       case 100: 
     137                 :       {
     138              58 :           CPLString osSubClass = poFeature->GetFieldAsString("SubClasses");

     139              58 :           if( osSubClass.size() > 0 )

     140              33 :               osSubClass += ":";

     141              58 :           osSubClass += pszValue;

     142              58 :           poFeature->SetField( "SubClasses", osSubClass.c_str() );

     143                 :       }
     144              58 :       break;

     145                 : 
     146                 :       case 62:
     147              23 :         oStyleProperties["Color"] = pszValue;

     148              23 :         break;

     149                 : 
     150                 :       case 6:
     151              23 :         poFeature->SetField( "Linetype", pszValue );

     152              23 :         break;

     153                 : 
     154                 :       case 370:
     155                 :       case 39:
     156              23 :         oStyleProperties["LineWeight"] = pszValue;

     157              23 :         break;

     158                 : 
     159                 :       case 5:
     160              25 :         poFeature->SetField( "EntityHandle", pszValue );

     161              25 :         break;

     162                 : 
     163                 :         // Extended entity data
     164                 :       case 1000:
     165                 :       case 1002:
     166                 :       case 1004:
     167                 :       case 1005:
     168                 :       case 1040:
     169                 :       case 1041:
     170                 :       case 1070:
     171                 :       case 1071:
     172                 :       {
     173               0 :           CPLString osAggregate = poFeature->GetFieldAsString("ExtendedEntity");

     174                 : 
     175               0 :           if( osAggregate.size() > 0 )

     176               0 :               osAggregate += " ";

     177               0 :           osAggregate += pszValue;

     178                 :             
     179               0 :           poFeature->SetField( "ExtendedEntity", osAggregate );

     180                 :       }
     181               0 :       break;

     182                 : 
     183                 :       // OCS vector.
     184                 :       case 210:
     185               1 :         oStyleProperties["210_N.dX"] = pszValue;

     186               1 :         break;

     187                 :         
     188                 :       case 220:
     189               1 :         oStyleProperties["220_N.dY"] = pszValue;

     190               1 :         break;

     191                 :         
     192                 :       case 230:
     193               1 :         oStyleProperties["230_N.dZ"] = pszValue;

     194                 :         break;
     195                 : 
     196                 : 
     197                 :       default:
     198                 :         break;
     199                 :     }
     200             230 : }

     201                 : 
     202                 : /************************************************************************/
     203                 : /*                          PrepareLineStyle()                          */
     204                 : /*                                                                      */
     205                 : /*      For now I don't bother trying to translate the dash/dot         */
     206                 : /*      linetype into the style string since I'm not aware of any       */
     207                 : /*      application that will honour it anyways.                        */
     208                 : /************************************************************************/
     209                 : 
     210              23 : void OGRDXFLayer::PrepareLineStyle( OGRFeature *poFeature )

     211                 : 
     212                 : {
     213              23 :     CPLString osLayer = poFeature->GetFieldAsString("Layer");

     214                 : 
     215                 : /* -------------------------------------------------------------------- */
     216                 : /*      Work out the color for this feature.                            */
     217                 : /* -------------------------------------------------------------------- */
     218              23 :     int nColor = 256;

     219                 : 
     220              23 :     if( oStyleProperties.count("Color") > 0 )

     221              19 :         nColor = atoi(oStyleProperties["Color"]);

     222                 : 
     223                 :     // Use layer color? 
     224              23 :     if( nColor < 1 || nColor > 255 )

     225                 :     {
     226              21 :         const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" );

     227              21 :         if( pszValue != NULL )

     228              21 :             nColor = atoi(pszValue);

     229                 :     }
     230                 :         
     231              23 :     if( nColor < 1 || nColor > 255 )

     232               5 :         return;

     233                 : 
     234                 : /* -------------------------------------------------------------------- */
     235                 : /*      Get line weight if available.                                   */
     236                 : /* -------------------------------------------------------------------- */
     237              18 :     double dfWeight = 0.0;

     238                 : 
     239              18 :     if( oStyleProperties.count("LineWeight") > 0 )

     240                 :     {
     241              16 :         CPLString osWeight = oStyleProperties["LineWeight"];

     242                 : 
     243              16 :         if( osWeight == "-1" )

     244              14 :             osWeight = poDS->LookupLayerProperty(osLayer,"LineWeight");

     245                 : 
     246              16 :         dfWeight = CPLAtof(osWeight) / 100.0;

     247                 :     }
     248                 : 
     249                 : /* -------------------------------------------------------------------- */
     250                 : /*      Format the style string.                                        */
     251                 : /* -------------------------------------------------------------------- */
     252              18 :     CPLString osStyle;

     253              18 :     const unsigned char *pabyDXFColors = OGRDXFDriver::GetDXFColorTable();

     254                 : 
     255                 :     osStyle.Printf( "PEN(c:#%02x%02x%02x", 
     256                 :                     pabyDXFColors[nColor*3+0],
     257                 :                     pabyDXFColors[nColor*3+1],
     258              18 :                     pabyDXFColors[nColor*3+2] );

     259                 : 
     260              18 :     if( dfWeight > 0.0 )

     261                 :     {
     262                 :         char szBuffer[64];
     263               0 :         snprintf(szBuffer, sizeof(szBuffer), "%.2g", dfWeight);

     264               0 :         char* pszComma = strchr(szBuffer, ',');

     265               0 :         if (pszComma)

     266               0 :             *pszComma = '.';

     267               0 :         osStyle += CPLString().Printf( ",w:%smm", szBuffer );

     268                 :     }
     269                 : 
     270              18 :     osStyle += ")";

     271                 :     
     272              18 :     poFeature->SetStyleString( osStyle );

     273                 : }
     274                 : 
     275                 : /************************************************************************/
     276                 : /*                            OCSTransformer                            */
     277                 : /************************************************************************/
     278                 : 
     279                 : class OCSTransformer : public OGRCoordinateTransformation
     280               1 : {

     281                 : private:
     282                 :     double adfN[3];
     283                 :     double adfAX[3];
     284                 :     double adfAY[3];
     285                 :     
     286                 : public:
     287               1 :     OCSTransformer( double adfN[3] ) {

     288                 :         static const double dSmall = 1.0 / 64.0;
     289                 :         static const double adfWZ[3] = {0, 0, 1};
     290                 :         static const double adfWY[3] = {0, 1, 0};
     291                 : 
     292               1 :         memcpy( this->adfN, adfN, sizeof(double)*3 );

     293                 : 
     294               1 :     if ((ABS(adfN[0]) < dSmall) && (ABS(adfN[1]) < dSmall))

     295               0 :             CrossProduct(adfWY, adfN, adfAX);

     296                 :     else
     297               1 :             CrossProduct(adfWZ, adfN, adfAX);

     298                 : 
     299               1 :     Scale2Unit( adfAX );

     300               1 :     CrossProduct(adfN, adfAX, adfAY);

     301               1 :     Scale2Unit( adfAY );

     302               1 :     }

     303                 : 
     304               2 :     void CrossProduct(const double *a, const double *b, double *vResult) {

     305               2 :         vResult[0] = a[1] * b[2] - a[2] * b[1];

     306               2 :         vResult[1] = a[2] * b[0] - a[0] * b[2];

     307               2 :         vResult[2] = a[0] * b[1] - a[1] * b[0];

     308               2 :     }

     309                 : 
     310               2 :     void Scale2Unit(double* adfV) {

     311               2 :     double dfLen=sqrt(adfV[0]*adfV[0] + adfV[1]*adfV[1] + adfV[2]*adfV[2]);

     312               2 :     if (dfLen != 0)

     313                 :     {
     314               2 :             adfV[0] /= dfLen;

     315               2 :             adfV[1] /= dfLen;

     316               2 :             adfV[2] /= dfLen;

     317                 :     }
     318               2 :     }

     319               0 :     OGRSpatialReference *GetSourceCS() { return NULL; }

     320               1 :     OGRSpatialReference *GetTargetCS() { return NULL; }

     321                 :     int Transform( int nCount, 
     322               1 :                    double *x, double *y, double *z )

     323               1 :         { return TransformEx( nCount, x, y, z, NULL ); }

     324                 :     
     325                 :     int TransformEx( int nCount, 
     326                 :                      double *adfX, double *adfY, double *adfZ = NULL,
     327               1 :                      int *pabSuccess = NULL )

     328                 :         {
     329                 :             int i;
     330               4 :             for( i = 0; i < nCount; i++ )

     331                 :             {
     332               3 :                 double x = adfX[i], y = adfY[i], z = adfZ[i];

     333                 :                 
     334               3 :                 adfX[i] = x * adfAX[0] + y * adfAY[0] + z * adfN[0];

     335               3 :                 adfY[i] = x * adfAX[1] + y * adfAY[1] + z * adfN[1];

     336               3 :                 adfZ[i] = x * adfAX[2] + y * adfAY[2] + z * adfN[2];

     337                 : 
     338               3 :                 if( pabSuccess )

     339               0 :                     pabSuccess[i] = TRUE;

     340                 :             }
     341               1 :             return TRUE;

     342                 :         }
     343                 : };
     344                 : 
     345                 : /************************************************************************/
     346                 : /*                        ApplyOCSTransformer()                         */
     347                 : /*                                                                      */
     348                 : /*      Apply a transformation from OCS to world coordinates if an      */
     349                 : /*      OCS vector was found in the object.                             */
     350                 : /************************************************************************/
     351                 : 
     352               6 : void OGRDXFLayer::ApplyOCSTransformer( OGRGeometry *poGeometry )

     353                 : 
     354                 : {
     355               6 :     if( oStyleProperties.count("210_N.dX") == 0

     356                 :         || oStyleProperties.count("220_N.dY") == 0
     357                 :         || oStyleProperties.count("230_N.dZ") == 0 )
     358               5 :         return;

     359                 : 
     360               1 :     if( poGeometry == NULL )

     361               0 :         return;

     362                 : 
     363                 :     double adfN[3];
     364                 : 
     365               1 :     adfN[0] = CPLAtof(oStyleProperties["210_N.dX"]);

     366               2 :     adfN[1] = CPLAtof(oStyleProperties["220_N.dY"]);

     367               2 :     adfN[2] = CPLAtof(oStyleProperties["230_N.dZ"]);

     368                 : 
     369               1 :     OCSTransformer oTransformer( adfN );

     370                 : 
     371               2 :     poGeometry->transform( &oTransformer );

     372                 : }
     373                 : 
     374                 : /************************************************************************/
     375                 : /*                           TranslateMTEXT()                           */
     376                 : /************************************************************************/
     377                 : 
     378               2 : OGRFeature *OGRDXFLayer::TranslateMTEXT()

     379                 : 
     380                 : {
     381                 :     char szLineBuf[257];
     382                 :     int nCode;
     383               2 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

     384               2 :     double dfX = 0.0, dfY = 0.0, dfZ = 0.0;

     385               2 :     double dfAngle = 0.0;

     386               2 :     double dfHeight = 0.0;

     387               2 :     double dfXDirection = 0.0, dfYDirection = 0.0;

     388               2 :     int bHaveZ = FALSE;

     389               2 :     int nAttachmentPoint = -1;

     390               2 :     CPLString osText;

     391                 : 
     392              40 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

     393                 :     {
     394              36 :         switch( nCode )

     395                 :         {
     396                 :           case 10:
     397               2 :             dfX = CPLAtof(szLineBuf);

     398               2 :             break;

     399                 : 
     400                 :           case 20:
     401               2 :             dfY = CPLAtof(szLineBuf);

     402               2 :             break;

     403                 : 
     404                 :           case 30:
     405               0 :             dfZ = CPLAtof(szLineBuf);

     406               0 :             bHaveZ = TRUE;

     407               0 :             break;

     408                 : 
     409                 :           case 40:
     410               2 :             dfHeight = CPLAtof(szLineBuf);

     411               2 :             break;

     412                 : 
     413                 :           case 71:
     414               2 :             nAttachmentPoint = atoi(szLineBuf);

     415               2 :             break;

     416                 : 
     417                 :           case 11:
     418               0 :             dfXDirection = CPLAtof(szLineBuf);

     419               0 :             break;

     420                 : 
     421                 :           case 21:
     422               0 :             dfYDirection = CPLAtof(szLineBuf);

     423               0 :             dfAngle = atan2( dfYDirection, dfXDirection ) * 180.0 / PI;

     424               0 :             break;

     425                 : 
     426                 :           case 1:
     427                 :           case 3:
     428               2 :             osText += szLineBuf;

     429               2 :             break;

     430                 : 
     431                 :           case 50:
     432               2 :             dfAngle = CPLAtof(szLineBuf);

     433               2 :             break;

     434                 : 
     435                 :           default:
     436              24 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );

     437                 :             break;
     438                 :         }
     439                 :     }
     440                 : 
     441               2 :     if( nCode == 0 )

     442               2 :         poDS->UnreadValue();

     443                 : 
     444               2 :     poFeature->SetField( "Text", osText );

     445                 : 
     446               2 :     if( bHaveZ )

     447               0 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY, dfZ ) );

     448                 :     else
     449               2 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY ) );

     450                 : 
     451                 : /* -------------------------------------------------------------------- */
     452                 : /*      Work out the color for this feature.                            */
     453                 : /* -------------------------------------------------------------------- */
     454               2 :     int nColor = 256;

     455                 : 
     456               2 :     if( oStyleProperties.count("Color") > 0 )

     457               2 :         nColor = atoi(oStyleProperties["Color"]);

     458                 : 
     459                 :     // Use layer color? 
     460               2 :     if( nColor < 1 || nColor > 255 )

     461                 :     {
     462               2 :         CPLString osLayer = poFeature->GetFieldAsString("Layer");

     463               2 :         const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" );

     464               2 :         if( pszValue != NULL )

     465               2 :             nColor = atoi(pszValue);

     466                 :     }
     467                 :         
     468                 : /* -------------------------------------------------------------------- */
     469                 : /*      Prepare style string.                                           */
     470                 : /* -------------------------------------------------------------------- */
     471               2 :     CPLString osStyle;

     472                 :     char szBuffer[64];
     473                 :     char* pszComma;
     474                 : 
     475               2 :     osStyle.Printf("LABEL(f:\"Arial\",t:\"%s\"",osText.c_str());

     476                 : 
     477               2 :     if( dfAngle != 0.0 )

     478                 :     {
     479               2 :         snprintf(szBuffer, sizeof(szBuffer), "%.3g", dfAngle);

     480               2 :         pszComma = strchr(szBuffer, ',');

     481               2 :         if (pszComma)

     482               0 :             *pszComma = '.';

     483               2 :         osStyle += CPLString().Printf(",a:%s", szBuffer);

     484                 :     }
     485                 : 
     486               2 :     if( dfHeight != 0.0 )

     487                 :     {
     488               2 :         snprintf(szBuffer, sizeof(szBuffer), "%.3g", dfHeight);

     489               2 :         pszComma = strchr(szBuffer, ',');

     490               2 :         if (pszComma)

     491               0 :             *pszComma = '.';

     492               2 :         osStyle += CPLString().Printf(",s:%sg", szBuffer);

     493                 :     }
     494                 : 
     495               2 :     if( nAttachmentPoint >= 0 && nAttachmentPoint <= 9 )

     496                 :     {
     497                 :         const static int anAttachmentMap[10] = 
     498                 :             { -1, 7, 8, 9, 4, 5, 6, 1, 2, 3 };
     499                 :         
     500                 :         osStyle += 
     501               2 :             CPLString().Printf(",p:%d", anAttachmentMap[nAttachmentPoint]);

     502                 :     }
     503                 : 
     504               2 :     if( nColor > 0 && nColor < 256 )

     505                 :     {
     506               2 :         const unsigned char *pabyDXFColors = OGRDXFDriver::GetDXFColorTable();

     507                 :         osStyle += 
     508                 :             CPLString().Printf( ",c:#%02x%02x%02x", 
     509                 :                                 pabyDXFColors[nColor*3+0],
     510                 :                                 pabyDXFColors[nColor*3+1],
     511               2 :                                 pabyDXFColors[nColor*3+2] );

     512                 :     }
     513                 : 
     514               2 :     osStyle += ")";

     515                 : 
     516               2 :     poFeature->SetStyleString( osStyle );

     517                 : 
     518               2 :     return poFeature;

     519                 : }
     520                 : 
     521                 : /************************************************************************/
     522                 : /*                           TranslateTEXT()                            */
     523                 : /************************************************************************/
     524                 : 
     525               0 : OGRFeature *OGRDXFLayer::TranslateTEXT()

     526                 : 
     527                 : {
     528                 :     char szLineBuf[257];
     529                 :     int nCode;
     530               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

     531               0 :     double dfX = 0.0, dfY = 0.0, dfZ = 0.0;

     532               0 :     double dfAngle = 0.0;

     533               0 :     double dfHeight = 0.0;

     534               0 :     CPLString osText;

     535               0 :     int bHaveZ = FALSE;

     536                 : 
     537               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

     538                 :     {
     539               0 :         switch( nCode )

     540                 :         {
     541                 :           case 10:
     542               0 :             dfX = CPLAtof(szLineBuf);

     543               0 :             break;

     544                 : 
     545                 :           case 20:
     546               0 :             dfY = CPLAtof(szLineBuf);

     547               0 :             break;

     548                 : 
     549                 :           case 30:
     550               0 :             dfZ = CPLAtof(szLineBuf);

     551               0 :             bHaveZ = TRUE;

     552               0 :             break;

     553                 : 
     554                 :           case 40:
     555               0 :             dfHeight = CPLAtof(szLineBuf);

     556               0 :             break;

     557                 : 
     558                 :           case 1:
     559                 :           case 3:
     560               0 :             osText += szLineBuf;

     561               0 :             break;

     562                 : 
     563                 :           case 50:
     564               0 :             dfAngle = CPLAtof(szLineBuf);

     565               0 :             break;

     566                 : 
     567                 :           default:
     568               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );

     569                 :             break;
     570                 :         }
     571                 :     }
     572                 : 
     573               0 :     if( nCode == 0 )

     574               0 :         poDS->UnreadValue();

     575                 : 
     576               0 :     poFeature->SetField( "Text", osText );

     577                 : 
     578               0 :     if( bHaveZ )

     579               0 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY, dfZ ) );

     580                 :     else
     581               0 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY ) );

     582                 : 
     583                 : /* -------------------------------------------------------------------- */
     584                 : /*      Prepare style string.                                           */
     585                 : /* -------------------------------------------------------------------- */
     586               0 :     CPLString osStyle;

     587                 :     char szBuffer[64];
     588                 :     char* pszComma;
     589                 : 
     590               0 :     osStyle.Printf("LABEL(f:\"Arial\",t:\"%s\"",osText.c_str());

     591                 : 
     592               0 :     if( dfAngle != 0.0 )

     593                 :     {
     594               0 :         snprintf(szBuffer, sizeof(szBuffer), "%.3g", dfAngle);

     595               0 :         pszComma = strchr(szBuffer, ',');

     596               0 :         if (pszComma)

     597               0 :             *pszComma = '.';

     598               0 :         osStyle += CPLString().Printf(",a:%s", szBuffer);

     599                 :     }
     600                 : 
     601               0 :     if( dfHeight != 0.0 )

     602                 :     {
     603               0 :         snprintf(szBuffer, sizeof(szBuffer), "%.3g", dfHeight);

     604               0 :         pszComma = strchr(szBuffer, ',');

     605               0 :         if (pszComma)

     606               0 :             *pszComma = '.';

     607               0 :         osStyle += CPLString().Printf(",s:%sg", szBuffer);

     608                 :     }
     609                 : 
     610                 :     // add color!
     611                 : 
     612               0 :     osStyle += ")";

     613                 : 
     614               0 :     poFeature->SetStyleString( osStyle );

     615                 : 
     616               0 :     return poFeature;

     617                 : }
     618                 : 
     619                 : /************************************************************************/
     620                 : /*                           TranslatePOINT()                           */
     621                 : /************************************************************************/
     622                 : 
     623               4 : OGRFeature *OGRDXFLayer::TranslatePOINT()

     624                 : 
     625                 : {
     626                 :     char szLineBuf[257];
     627                 :     int nCode;
     628               4 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

     629               4 :     double dfX = 0.0, dfY = 0.0, dfZ = 0.0;

     630               4 :     int bHaveZ = FALSE;

     631                 : 
     632              36 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

     633                 :     {
     634              28 :         switch( nCode )

     635                 :         {
     636                 :           case 10:
     637               4 :             dfX = CPLAtof(szLineBuf);

     638               4 :             break;

     639                 : 
     640                 :           case 20:
     641               4 :             dfY = CPLAtof(szLineBuf);

     642               4 :             break;

     643                 : 
     644                 :           case 30:
     645               4 :             dfZ = CPLAtof(szLineBuf);

     646               4 :             bHaveZ = TRUE;

     647               4 :             break;

     648                 : 
     649                 :           default:
     650              16 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );

     651                 :             break;
     652                 :         }
     653                 :     }
     654                 : 
     655               4 :     if( bHaveZ )

     656               4 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY, dfZ ) );

     657                 :     else
     658               0 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY ) );

     659                 : 
     660               4 :     if( nCode == 0 )

     661               4 :         poDS->UnreadValue();

     662                 : 
     663               4 :     return poFeature;

     664                 : }
     665                 : 
     666                 : /************************************************************************/
     667                 : /*                           TranslateLINE()                            */
     668                 : /************************************************************************/
     669                 : 
     670               7 : OGRFeature *OGRDXFLayer::TranslateLINE()

     671                 : 
     672                 : {
     673                 :     char szLineBuf[257];
     674                 :     int nCode;
     675               7 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

     676               7 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0;

     677               7 :     double dfX2 = 0.0, dfY2 = 0.0, dfZ2 = 0.0;

     678               7 :     int bHaveZ = FALSE;

     679                 : 
     680                 : /* -------------------------------------------------------------------- */
     681                 : /*      Process values.                                                 */
     682                 : /* -------------------------------------------------------------------- */
     683             108 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

     684                 :     {
     685              94 :         switch( nCode )

     686                 :         {
     687                 :           case 10:
     688               7 :             dfX1 = CPLAtof(szLineBuf);

     689               7 :             break;

     690                 : 
     691                 :           case 11:
     692               7 :             dfX2 = CPLAtof(szLineBuf);

     693               7 :             break;

     694                 : 
     695                 :           case 20:
     696               7 :             dfY1 = CPLAtof(szLineBuf);

     697               7 :             break;

     698                 : 
     699                 :           case 21:
     700               7 :             dfY2 = CPLAtof(szLineBuf);

     701               7 :             break;

     702                 : 
     703                 :           case 30:
     704               7 :             dfZ1 = CPLAtof(szLineBuf);

     705               7 :             bHaveZ = TRUE;

     706               7 :             break;

     707                 : 
     708                 :           case 31:
     709               7 :             dfZ2 = CPLAtof(szLineBuf);

     710               7 :             bHaveZ = TRUE;

     711               7 :             break;

     712                 : 
     713                 :           default:
     714              52 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );

     715                 :             break;
     716                 :         }
     717                 :     }
     718                 : 
     719               7 :     if( nCode == 0 )

     720               7 :         poDS->UnreadValue();

     721                 : 
     722                 : /* -------------------------------------------------------------------- */
     723                 : /*      Create geometry                                                 */
     724                 : /* -------------------------------------------------------------------- */
     725               7 :     OGRLineString *poLS = new OGRLineString();

     726               7 :     if( bHaveZ )

     727                 :     {
     728               7 :         poLS->addPoint( dfX1, dfY1, dfZ1 );

     729               7 :         poLS->addPoint( dfX2, dfY2, dfZ2 );

     730                 :     }
     731                 :     else
     732                 :     {
     733               0 :         poLS->addPoint( dfX1, dfY1 );

     734               0 :         poLS->addPoint( dfX2, dfY2 );

     735                 :     }
     736                 : 
     737               7 :     poFeature->SetGeometryDirectly( poLS );

     738                 : 
     739               7 :     PrepareLineStyle( poFeature );

     740                 : 
     741               7 :     return poFeature;

     742                 : }
     743                 : 
     744                 : /************************************************************************/
     745                 : /*                         TranslateLWPOLYLINE()                        */
     746                 : /************************************************************************/
     747               5 : OGRFeature *OGRDXFLayer::TranslateLWPOLYLINE()

     748                 : 
     749                 : {
     750                 :     // Collect vertices and attributes into a smooth polyline.
     751                 :     // If there are no bulges, then we are a straight-line polyline.
     752                 :     // Single-vertex polylines become points.
     753                 :     // Group code 30 (vertex Z) is not part of this entity.
     754                 : 
     755                 :     char                szLineBuf[257];
     756                 :     int                 nCode;
     757               5 :     int                 nPolylineFlag = 0;

     758                 : 
     759                 : 
     760               5 :     OGRFeature          *poFeature = new OGRFeature( poFeatureDefn );

     761               5 :     double              dfX = 0.0, dfY = 0.0, dfZ = 0.0;

     762               5 :     int                 bHaveX = FALSE;

     763               5 :     int                 bHaveY = FALSE;

     764                 : 
     765               5 :     int                 nNumVertices = 1;   // use 1 based index

     766               5 :     int                 npolyarcVertexCount = 1;

     767               5 :     int                 bPLineGen = FALSE;

     768               5 :     double              dfBulge = 0.0;

     769               5 :     DXFSmoothPolyline   smoothPolyline;

     770                 : 
     771               5 :   smoothPolyline.setCoordinateDimension(2);

     772                 : 
     773                 : /* -------------------------------------------------------------------- */
     774                 : /*      Collect information from the LWPOLYLINE object itself.          */
     775                 : /* -------------------------------------------------------------------- */
     776              96 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

     777                 :     {
     778              86 :         if(npolyarcVertexCount > nNumVertices)

     779                 :         {
     780                 :             CPLError( CE_Failure, CPLE_AppDefined,
     781               0 :               "Too many vertices found in LWPOLYLINE." );

     782               0 :             delete poFeature;

     783               0 :             return NULL;

     784                 :         }
     785                 : 
     786              86 :         switch( nCode )

     787                 :         {
     788                 :             case 38:
     789                 :                 // Constant elevation.
     790               1 :                 dfZ = CPLAtof(szLineBuf);

     791               1 :         smoothPolyline.setCoordinateDimension(3);

     792               1 :                 break;

     793                 : 
     794                 :             case 90:
     795               5 :                 nNumVertices = atoi(szLineBuf);

     796               5 :                 break;

     797                 : 
     798                 :             case 70:
     799               5 :                 nPolylineFlag = atoi(szLineBuf);

     800               5 :                 break;

     801                 : 
     802                 :             case 10:
     803              19 :                 if( bHaveX && bHaveY )

     804                 :                 {
     805              14 :                     smoothPolyline.AddPoint(dfX, dfY, dfZ, dfBulge);

     806              14 :                     npolyarcVertexCount++;

     807              14 :                     dfBulge = 0.0;

     808              14 :                     bHaveY = FALSE;

     809                 :                 }
     810              19 :                 dfX = CPLAtof(szLineBuf);

     811              19 :                 bHaveX = TRUE;

     812              19 :                 break;

     813                 : 
     814                 :             case 20:
     815              19 :                 if( bHaveX && bHaveY )

     816                 :                 {
     817               0 :                     smoothPolyline.AddPoint( dfX, dfY, dfZ, dfBulge );

     818               0 :                     npolyarcVertexCount++;

     819               0 :                     dfBulge = 0.0;

     820               0 :                     bHaveX = FALSE;

     821                 :                 }
     822              19 :                 dfY = CPLAtof(szLineBuf);

     823              19 :                 bHaveY = TRUE;

     824              19 :                 break;

     825                 : 
     826                 :             case 42:
     827               4 :                 dfBulge = CPLAtof(szLineBuf);

     828               4 :                 break;

     829                 : 
     830                 : 
     831                 :             default:
     832              33 :                 TranslateGenericProperty( poFeature, nCode, szLineBuf );

     833                 :                 break;
     834                 :         }
     835                 :     }
     836                 : 
     837               5 :     poDS->UnreadValue();

     838                 : 
     839               5 :     if( bHaveX && bHaveY )

     840               5 :          smoothPolyline.AddPoint(dfX, dfY, dfZ, dfBulge);

     841                 : 
     842                 :     
     843               5 :     if(smoothPolyline.IsEmpty())

     844                 :     {
     845               0 :         delete poFeature;

     846               0 :         return NULL;

     847                 :     }
     848                 : 
     849                 : /* -------------------------------------------------------------------- */
     850                 : /*      Close polyline if necessary.                                    */
     851                 : /* -------------------------------------------------------------------- */
     852               5 :     if(nPolylineFlag & 0x01)

     853               2 :         smoothPolyline.Close();

     854                 : 
     855               5 :     OGRGeometry* poGeom = smoothPolyline.Tesselate();

     856               5 :     ApplyOCSTransformer( poGeom );

     857               5 :     poFeature->SetGeometryDirectly( poGeom );

     858                 : 
     859               5 :     PrepareLineStyle( poFeature );

     860                 : 
     861               5 :     return poFeature;

     862                 : }
     863                 : 
     864                 : 
     865                 : /************************************************************************/
     866                 : /*                         TranslatePOLYLINE()                          */
     867                 : /*                                                                      */
     868                 : /*      We also capture the following VERTEXes.                         */
     869                 : /************************************************************************/
     870                 : 
     871               1 : OGRFeature *OGRDXFLayer::TranslatePOLYLINE()

     872                 : 
     873                 : {
     874                 :     char szLineBuf[257];
     875                 :     int nCode;
     876               1 :     int nPolylineFlag = 0;

     877               1 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

     878                 : 
     879                 : /* -------------------------------------------------------------------- */
     880                 : /*      Collect information from the POLYLINE object itself.            */
     881                 : /* -------------------------------------------------------------------- */
     882               8 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

     883                 :     {
     884               6 :         switch( nCode )

     885                 :         {
     886                 :           case 70:
     887               1 :             nPolylineFlag = atoi(szLineBuf);

     888               1 :             break;

     889                 : 
     890                 :           default:
     891               5 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );

     892                 :             break;
     893                 :         }
     894                 :     }
     895                 : 
     896                 : /* -------------------------------------------------------------------- */
     897                 : /*      Collect VERTEXes as a smooth polyline.                          */
     898                 : /* -------------------------------------------------------------------- */
     899               1 :     double              dfX = 0.0, dfY = 0.0, dfZ = 0.0;

     900               1 :     double              dfBulge = 0.0;

     901               1 :     DXFSmoothPolyline   smoothPolyline;

     902                 : 
     903               1 :   smoothPolyline.setCoordinateDimension(2);

     904                 : 
     905               7 :     while( nCode == 0 && !EQUAL(szLineBuf,"SEQEND") )

     906                 :     {
     907                 :         // Eat non-vertex objects.
     908               5 :         if( !EQUAL(szLineBuf,"VERTEX") )

     909                 :         {
     910               0 :             while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf)))>0 ) {}

     911               0 :             continue;

     912                 :         }
     913                 : 
     914                 :         // process a Vertex
     915              39 :         while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

     916                 :         {
     917              29 :             switch( nCode )

     918                 :             {
     919                 :               case 10:
     920               5 :                 dfX = CPLAtof(szLineBuf);

     921               5 :                 break;

     922                 :                 
     923                 :               case 20:
     924               5 :                 dfY = CPLAtof(szLineBuf);

     925               5 :                 break;

     926                 :                 
     927                 :               case 30:
     928               5 :                 dfZ = CPLAtof(szLineBuf);

     929               5 :         smoothPolyline.setCoordinateDimension(3);

     930               5 :                 break;

     931                 : 
     932                 :               case 42:
     933               4 :                 dfBulge = CPLAtof(szLineBuf);

     934                 :                 break;
     935                 : 
     936                 :               default:
     937                 :                 break;
     938                 :             }
     939                 :         }
     940                 : 
     941               5 :         smoothPolyline.AddPoint( dfX, dfY, dfZ, dfBulge );

     942               5 :         dfBulge = 0.0;

     943                 :     }
     944                 : 
     945                 : /* -------------------------------------------------------------------- */
     946                 : /*      Close polyline if necessary.                                    */
     947                 : /* -------------------------------------------------------------------- */
     948               1 :     if(nPolylineFlag & 0x01)

     949               1 :         smoothPolyline.Close();

     950                 : 
     951               1 :     OGRGeometry* poGeom = smoothPolyline.Tesselate();

     952               1 :     ApplyOCSTransformer( poGeom );

     953               1 :     poFeature->SetGeometryDirectly( poGeom );

     954                 : 
     955               1 :     PrepareLineStyle( poFeature );

     956                 : 
     957               1 :     return poFeature;

     958                 : }
     959                 : 
     960                 : /************************************************************************/
     961                 : /*                          TranslateCIRCLE()                           */
     962                 : /************************************************************************/
     963                 : 
     964               0 : OGRFeature *OGRDXFLayer::TranslateCIRCLE()

     965                 : 
     966                 : {
     967                 :     char szLineBuf[257];
     968                 :     int nCode;
     969               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

     970               0 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0, dfRadius = 0.0;

     971               0 :     int bHaveZ = FALSE;

     972                 : 
     973                 : /* -------------------------------------------------------------------- */
     974                 : /*      Process values.                                                 */
     975                 : /* -------------------------------------------------------------------- */
     976               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

     977                 :     {
     978               0 :         switch( nCode )

     979                 :         {
     980                 :           case 10:
     981               0 :             dfX1 = CPLAtof(szLineBuf);

     982               0 :             break;

     983                 : 
     984                 :           case 20:
     985               0 :             dfY1 = CPLAtof(szLineBuf);

     986               0 :             break;

     987                 : 
     988                 :           case 30:
     989               0 :             dfZ1 = CPLAtof(szLineBuf);

     990               0 :             bHaveZ = TRUE;

     991               0 :             break;

     992                 : 
     993                 :           case 40:
     994               0 :             dfRadius = CPLAtof(szLineBuf);

     995               0 :             break;

     996                 : 
     997                 :           default:
     998               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );

     999                 :             break;
    1000                 :         }
    1001                 :     }
    1002                 : 
    1003               0 :     if( nCode == 0 )

    1004               0 :         poDS->UnreadValue();

    1005                 : 
    1006                 : /* -------------------------------------------------------------------- */
    1007                 : /*      Create geometry                                                 */
    1008                 : /* -------------------------------------------------------------------- */
    1009                 :     OGRGeometry *poCircle = 
    1010                 :         OGRGeometryFactory::approximateArcAngles( dfX1, dfY1, dfZ1, 
    1011                 :                                                   dfRadius, dfRadius, 0.0,
    1012                 :                                                   0.0, 360.0, 
    1013               0 :                                                   0.0 );

    1014                 : 
    1015               0 :     if( !bHaveZ )

    1016               0 :         poCircle->flattenTo2D();

    1017                 : 
    1018               0 :     poFeature->SetGeometryDirectly( poCircle );

    1019               0 :     PrepareLineStyle( poFeature );

    1020                 : 
    1021               0 :     return poFeature;

    1022                 : }
    1023                 : 
    1024                 : /************************************************************************/
    1025                 : /*                          TranslateELLIPSE()                          */
    1026                 : /************************************************************************/
    1027                 : 
    1028               4 : OGRFeature *OGRDXFLayer::TranslateELLIPSE()

    1029                 : 
    1030                 : {
    1031                 :     char szLineBuf[257];
    1032                 :     int nCode;
    1033               4 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

    1034               4 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0, dfRatio = 0.0;

    1035               4 :     double dfStartAngle = 0.0, dfEndAngle = 360.0;

    1036               4 :     double dfAxisX=0.0, dfAxisY=0.0, dfAxisZ=0.0;

    1037               4 :     int bHaveZ = FALSE;

    1038                 : 
    1039                 : /* -------------------------------------------------------------------- */
    1040                 : /*      Process values.                                                 */
    1041                 : /* -------------------------------------------------------------------- */
    1042              72 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

    1043                 :     {
    1044              64 :         switch( nCode )

    1045                 :         {
    1046                 :           case 10:
    1047               4 :             dfX1 = CPLAtof(szLineBuf);

    1048               4 :             break;

    1049                 : 
    1050                 :           case 20:
    1051               4 :             dfY1 = CPLAtof(szLineBuf);

    1052               4 :             break;

    1053                 : 
    1054                 :           case 30:
    1055               4 :             dfZ1 = CPLAtof(szLineBuf);

    1056               4 :             bHaveZ = TRUE;

    1057               4 :             break;

    1058                 : 
    1059                 :           case 11:
    1060               4 :             dfAxisX = CPLAtof(szLineBuf);

    1061               4 :             break;

    1062                 : 
    1063                 :           case 21:
    1064               4 :             dfAxisY = CPLAtof(szLineBuf);

    1065               4 :             break;

    1066                 : 
    1067                 :           case 31:
    1068               4 :             dfAxisZ = CPLAtof(szLineBuf);

    1069               4 :             break;

    1070                 : 
    1071                 :           case 40:
    1072               4 :             dfRatio = CPLAtof(szLineBuf);

    1073               4 :             break;

    1074                 : 
    1075                 :           case 41:
    1076               4 :             dfEndAngle = -1 * CPLAtof(szLineBuf) * 180.0 / PI;

    1077               4 :             break;

    1078                 : 
    1079                 :           case 42:
    1080               4 :             dfStartAngle = -1 * CPLAtof(szLineBuf) * 180.0 / PI;

    1081               4 :             break;

    1082                 : 
    1083                 :           default:
    1084              28 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );

    1085                 :             break;
    1086                 :         }
    1087                 :     }
    1088                 : 
    1089               4 :     if( nCode == 0 )

    1090               4 :         poDS->UnreadValue();

    1091                 : 
    1092                 : /* -------------------------------------------------------------------- */
    1093                 : /*      Compute primary and secondary axis lengths, and the angle of    */
    1094                 : /*      rotation for the ellipse.                                       */
    1095                 : /* -------------------------------------------------------------------- */
    1096                 :     double dfPrimaryRadius, dfSecondaryRadius;
    1097                 :     double dfRotation;
    1098                 : 
    1099               4 :     if( dfStartAngle > dfEndAngle )

    1100               0 :         dfEndAngle += 360.0;

    1101                 : 
    1102                 :     dfPrimaryRadius = sqrt( dfAxisX * dfAxisX 
    1103                 :                             + dfAxisY * dfAxisY
    1104               4 :                             + dfAxisZ * dfAxisZ );

    1105                 : 
    1106               4 :     dfSecondaryRadius = dfRatio * dfPrimaryRadius;

    1107                 : 
    1108               4 :     dfRotation = -1 * atan2( dfAxisY, dfAxisX ) * 180 / PI;

    1109                 : 
    1110                 : /* -------------------------------------------------------------------- */
    1111                 : /*      Create geometry                                                 */
    1112                 : /* -------------------------------------------------------------------- */
    1113                 :     OGRGeometry *poEllipse = 
    1114                 :         OGRGeometryFactory::approximateArcAngles( dfX1, dfY1, dfZ1, 
    1115                 :                                                   dfPrimaryRadius, 
    1116                 :                                                   dfSecondaryRadius,
    1117                 :                                                   dfRotation, 
    1118                 :                                                   dfStartAngle, dfEndAngle,
    1119               4 :                                                   0.0 );

    1120                 : 
    1121               4 :     if( !bHaveZ )

    1122               0 :         poEllipse->flattenTo2D();

    1123                 : 
    1124               4 :     poFeature->SetGeometryDirectly( poEllipse );

    1125                 : 
    1126               4 :     PrepareLineStyle( poFeature );

    1127                 : 
    1128               4 :     return poFeature;

    1129                 : }
    1130                 : 
    1131                 : /************************************************************************/
    1132                 : /*                            TranslateARC()                            */
    1133                 : /************************************************************************/
    1134                 : 
    1135               2 : OGRFeature *OGRDXFLayer::TranslateARC()

    1136                 : 
    1137                 : {
    1138                 :     char szLineBuf[257];
    1139                 :     int nCode;
    1140               2 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

    1141               2 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0, dfRadius = 0.0;

    1142               2 :     double dfStartAngle = 0.0, dfEndAngle = 360.0;

    1143               2 :     int bHaveZ = FALSE;

    1144                 : 
    1145                 : /* -------------------------------------------------------------------- */
    1146                 : /*      Process values.                                                 */
    1147                 : /* -------------------------------------------------------------------- */
    1148              32 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

    1149                 :     {
    1150              28 :         switch( nCode )

    1151                 :         {
    1152                 :           case 10:
    1153               2 :             dfX1 = CPLAtof(szLineBuf);

    1154               2 :             break;

    1155                 : 
    1156                 :           case 20:
    1157               2 :             dfY1 = CPLAtof(szLineBuf);

    1158               2 :             break;

    1159                 : 
    1160                 :           case 30:
    1161               2 :             dfZ1 = CPLAtof(szLineBuf);

    1162               2 :             bHaveZ = TRUE;

    1163               2 :             break;

    1164                 : 
    1165                 :           case 40:
    1166               2 :             dfRadius = CPLAtof(szLineBuf);

    1167               2 :             break;

    1168                 : 
    1169                 :           case 50:
    1170               2 :             dfEndAngle = -1 * CPLAtof(szLineBuf);

    1171               2 :             break;

    1172                 : 
    1173                 :           case 51:
    1174               2 :             dfStartAngle = -1 * CPLAtof(szLineBuf);

    1175               2 :             break;

    1176                 : 
    1177                 :           default:
    1178              16 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );

    1179                 :             break;
    1180                 :         }
    1181                 :     }
    1182                 : 
    1183               2 :     if( nCode == 0 )

    1184               2 :         poDS->UnreadValue();

    1185                 : 
    1186                 : /* -------------------------------------------------------------------- */
    1187                 : /*      Create geometry                                                 */
    1188                 : /* -------------------------------------------------------------------- */
    1189               2 :     if( dfStartAngle > dfEndAngle )

    1190               2 :         dfEndAngle += 360.0;

    1191                 : 
    1192                 :     OGRGeometry *poArc = 
    1193                 :         OGRGeometryFactory::approximateArcAngles( dfX1, dfY1, dfZ1, 
    1194                 :                                                   dfRadius, dfRadius, 0.0,
    1195                 :                                                   dfStartAngle, dfEndAngle,
    1196               2 :                                                   0.0 );

    1197               2 :     if( !bHaveZ )

    1198               0 :         poArc->flattenTo2D();

    1199                 : 
    1200               2 :     poFeature->SetGeometryDirectly( poArc );

    1201                 : 
    1202               2 :     PrepareLineStyle( poFeature );

    1203                 : 
    1204               2 :     return poFeature;

    1205                 : }
    1206                 : 
    1207                 : /************************************************************************/
    1208                 : /*                          TranslateSPLINE()                           */
    1209                 : /************************************************************************/
    1210                 : 
    1211                 : void rbspline(int npts,int k,int p1,double b[],double h[], double p[]);
    1212                 : void rbsplinu(int npts,int k,int p1,double b[],double h[], double p[]);
    1213                 : 
    1214               0 : OGRFeature *OGRDXFLayer::TranslateSPLINE()

    1215                 : 
    1216                 : {
    1217                 :     char szLineBuf[257];
    1218               0 :     int nCode, nDegree = -1, nFlags = -1, bClosed = FALSE, i;

    1219               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

    1220               0 :     std::vector<double> adfControlPoints;

    1221                 : 
    1222               0 :     adfControlPoints.push_back(0.0);

    1223                 : 
    1224                 : /* -------------------------------------------------------------------- */
    1225                 : /*      Process values.                                                 */
    1226                 : /* -------------------------------------------------------------------- */
    1227               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

    1228                 :     {
    1229               0 :         switch( nCode )

    1230                 :         {
    1231                 :           case 10:
    1232               0 :             adfControlPoints.push_back( CPLAtof(szLineBuf) );

    1233               0 :             break;

    1234                 : 
    1235                 :           case 20:
    1236               0 :             adfControlPoints.push_back( CPLAtof(szLineBuf) );

    1237               0 :             adfControlPoints.push_back( 0.0 );

    1238               0 :             break;

    1239                 : 
    1240                 :           case 70:
    1241               0 :             nFlags = atoi(szLineBuf);

    1242               0 :             if( nFlags & 1 )

    1243               0 :                 bClosed = TRUE;

    1244               0 :             break;

    1245                 : 
    1246                 :           case 71:
    1247               0 :             nDegree = atoi(szLineBuf);

    1248               0 :             break;

    1249                 : 
    1250                 :           default:
    1251               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );

    1252                 :             break;
    1253                 :         }
    1254                 :     }
    1255                 : 
    1256               0 :     if( nCode == 0 )

    1257               0 :         poDS->UnreadValue();

    1258                 : 
    1259               0 :     if( bClosed )

    1260                 :     {
    1261               0 :         for( i = 0; i < nDegree; i++ )

    1262                 :         {
    1263               0 :             adfControlPoints.push_back( adfControlPoints[i*3+1] );

    1264               0 :             adfControlPoints.push_back( adfControlPoints[i*3+2] );

    1265               0 :             adfControlPoints.push_back( adfControlPoints[i*3+3] );

    1266                 :         }
    1267                 :     }
    1268                 : 
    1269                 : /* -------------------------------------------------------------------- */
    1270                 : /*      Interpolate spline                                              */
    1271                 : /* -------------------------------------------------------------------- */
    1272               0 :     int nControlPoints = adfControlPoints.size() / 3;

    1273               0 :     std::vector<double> h, p;

    1274                 : 
    1275               0 :     h.push_back(1.0);

    1276               0 :     for( i = 0; i < nControlPoints; i++ )

    1277               0 :         h.push_back( 1.0 );

    1278                 :     
    1279                 :     // resolution:
    1280                 :     //int p1 = getGraphicVariableInt("$SPLINESEGS", 8) * npts;
    1281               0 :     int p1 = nControlPoints * 8;

    1282                 : 
    1283               0 :     p.push_back( 0.0 );

    1284               0 :     for( i = 0; i < 3*p1; i++ )

    1285               0 :         p.push_back( 0.0 );

    1286                 : 
    1287               0 :     if( bClosed )

    1288                 :         rbsplinu( nControlPoints, nDegree+1, p1, &(adfControlPoints[0]), 
    1289               0 :                   &(h[0]), &(p[0]) );

    1290                 :     else
    1291                 :         rbspline( nControlPoints, nDegree+1, p1, &(adfControlPoints[0]), 
    1292               0 :                   &(h[0]), &(p[0]) );

    1293                 :     
    1294                 : /* -------------------------------------------------------------------- */
    1295                 : /*      Turn into OGR geometry.                                         */
    1296                 : /* -------------------------------------------------------------------- */
    1297               0 :     OGRLineString *poLS = new OGRLineString();

    1298                 : 
    1299               0 :     poLS->setNumPoints( p1 );

    1300               0 :     for( i = 0; i < p1; i++ )

    1301               0 :         poLS->setPoint( i, p[i*3+1], p[i*3+2] );

    1302                 : 
    1303               0 :     poFeature->SetGeometryDirectly( poLS );

    1304                 : 
    1305               0 :     PrepareLineStyle( poFeature );

    1306                 : 
    1307               0 :     return poFeature;

    1308                 : }
    1309                 : 
    1310                 : /************************************************************************/
    1311                 : /*                      GeometryInsertTransformer                       */
    1312                 : /************************************************************************/
    1313                 : 
    1314                 : class GeometryInsertTransformer : public OGRCoordinateTransformation
    1315               0 : {

    1316                 : public:
    1317               0 :     GeometryInsertTransformer() : 

    1318                 :             dfXOffset(0),dfYOffset(0),dfZOffset(0),
    1319                 :             dfXScale(1.0),dfYScale(1.0),dfZScale(1.0),
    1320               0 :             dfAngle(0.0) {}

    1321                 : 
    1322                 :     double dfXOffset;
    1323                 :     double dfYOffset;
    1324                 :     double dfZOffset;
    1325                 :     double dfXScale;
    1326                 :     double dfYScale;
    1327                 :     double dfZScale;
    1328                 :     double dfAngle;
    1329                 : 
    1330               0 :     OGRSpatialReference *GetSourceCS() { return NULL; }

    1331               0 :     OGRSpatialReference *GetTargetCS() { return NULL; }

    1332                 :     int Transform( int nCount, 
    1333               0 :                    double *x, double *y, double *z )

    1334               0 :         { return TransformEx( nCount, x, y, z, NULL ); }

    1335                 :     
    1336                 :     int TransformEx( int nCount, 
    1337                 :                      double *x, double *y, double *z = NULL,
    1338               0 :                      int *pabSuccess = NULL )

    1339                 :         {
    1340                 :             int i;
    1341               0 :             for( i = 0; i < nCount; i++ )

    1342                 :             {
    1343                 :                 double dfXNew, dfYNew;
    1344                 : 
    1345               0 :                 x[i] *= dfXScale;

    1346               0 :                 y[i] *= dfYScale;

    1347               0 :                 z[i] *= dfZScale;

    1348                 : 
    1349               0 :                 dfXNew = x[i] * cos(dfAngle) - y[i] * sin(dfAngle);

    1350               0 :                 dfYNew = x[i] * sin(dfAngle) + y[i] * cos(dfAngle);

    1351                 : 
    1352               0 :                 x[i] = dfXNew;

    1353               0 :                 y[i] = dfYNew;

    1354                 : 
    1355               0 :                 x[i] += dfXOffset;

    1356               0 :                 y[i] += dfYOffset;

    1357               0 :                 z[i] += dfZOffset;

    1358                 : 
    1359               0 :                 if( pabSuccess )

    1360               0 :                     pabSuccess[i] = TRUE;

    1361                 :             }
    1362               0 :             return TRUE;

    1363                 :         }
    1364                 : };
    1365                 : 
    1366                 : /************************************************************************/
    1367                 : /*                          TranslateINSERT()                           */
    1368                 : /************************************************************************/
    1369                 : 
    1370               0 : OGRFeature *OGRDXFLayer::TranslateINSERT()

    1371                 : 
    1372                 : {
    1373                 :     char szLineBuf[257];
    1374                 :     int nCode;
    1375               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

    1376               0 :     GeometryInsertTransformer oTransformer;

    1377               0 :     CPLString osBlockName;

    1378                 : 
    1379                 : /* -------------------------------------------------------------------- */
    1380                 : /*      Process values.                                                 */
    1381                 : /* -------------------------------------------------------------------- */
    1382               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )

    1383                 :     {
    1384               0 :         switch( nCode )

    1385                 :         {
    1386                 :           case 10:
    1387               0 :             oTransformer.dfXOffset = CPLAtof(szLineBuf);

    1388               0 :             break;

    1389                 : 
    1390                 :           case 20:
    1391               0 :             oTransformer.dfYOffset = CPLAtof(szLineBuf);

    1392               0 :             break;

    1393                 : 
    1394                 :           case 30:
    1395               0 :             oTransformer.dfZOffset = CPLAtof(szLineBuf);

    1396               0 :             break;

    1397                 : 
    1398                 :           case 41:
    1399               0 :             oTransformer.dfXScale = CPLAtof(szLineBuf);

    1400               0 :             break;

    1401                 : 
    1402                 :           case 42:
    1403               0 :             oTransformer.dfYScale = CPLAtof(szLineBuf);

    1404               0 :             break;

    1405                 : 
    1406                 :           case 43:
    1407               0 :             oTransformer.dfZScale = CPLAtof(szLineBuf);

    1408               0 :             break;

    1409                 : 
    1410                 :           case 50:
    1411               0 :             oTransformer.dfAngle = CPLAtof(szLineBuf) * PI / 180.0;

    1412               0 :             break;

    1413                 : 
    1414                 :           case 2: 
    1415               0 :             osBlockName = szLineBuf;

    1416               0 :             break;

    1417                 :             
    1418                 :           default:
    1419               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );

    1420                 :             break;
    1421                 :         }
    1422                 :     }
    1423                 : 
    1424               0 :     if( nCode == 0 )

    1425               0 :         poDS->UnreadValue();

    1426                 : 
    1427                 : /* -------------------------------------------------------------------- */
    1428                 : /*      Lookup the block.                                               */
    1429                 : /* -------------------------------------------------------------------- */
    1430               0 :     DXFBlockDefinition *poBlock = poDS->LookupBlock( osBlockName );

    1431                 :     
    1432               0 :     if( poBlock == NULL )

    1433                 :     {
    1434               0 :         delete poFeature;

    1435               0 :         return NULL;

    1436                 :     }
    1437                 : 
    1438                 : /* -------------------------------------------------------------------- */
    1439                 : /*      Transform the geometry.                                         */
    1440                 : /* -------------------------------------------------------------------- */
    1441               0 :     if( poBlock->poGeometry != NULL )

    1442                 :     {
    1443               0 :         OGRGeometry *poGeometry = poBlock->poGeometry->clone();

    1444                 : 
    1445               0 :         poGeometry->transform( &oTransformer );

    1446                 : 
    1447               0 :         poFeature->SetGeometryDirectly( poGeometry );

    1448                 :     }
    1449                 : 
    1450                 : /* -------------------------------------------------------------------- */
    1451                 : /*      If we have complete features associated with the block, push    */
    1452                 : /*      them on the pending feature stack copying over key override     */
    1453                 : /*      information.                                                    */
    1454                 : /*                                                                      */
    1455                 : /*      Note that while we transform the geometry of the features we    */
    1456                 : /*      don't adjust subtle things like text angle.                     */
    1457                 : /* -------------------------------------------------------------------- */
    1458                 :     unsigned int iSubFeat;
    1459                 : 
    1460               0 :     for( iSubFeat = 0; iSubFeat < poBlock->apoFeatures.size(); iSubFeat++ )

    1461                 :     {
    1462               0 :         OGRFeature *poSubFeature = poBlock->apoFeatures[iSubFeat]->Clone();

    1463                 : 
    1464               0 :         if( poSubFeature->GetGeometryRef() != NULL )

    1465               0 :             poSubFeature->GetGeometryRef()->transform( &oTransformer );

    1466                 : 
    1467               0 :         apoPendingFeatures.push( poSubFeature );

    1468                 :     }
    1469                 : 
    1470                 : /* -------------------------------------------------------------------- */
    1471                 : /*      Return the working feature if we had geometry, otherwise        */
    1472                 : /*      return NULL and let the machinery find the rest of the          */
    1473                 : /*      features in the pending feature stack.                          */
    1474                 : /* -------------------------------------------------------------------- */
    1475               0 :     if( poBlock->poGeometry == NULL )

    1476                 :     {
    1477               0 :         delete poFeature;

    1478               0 :         return NULL;

    1479                 :     }
    1480                 :     else
    1481                 :     {
    1482               0 :         return poFeature;

    1483               0 :     }

    1484                 : }
    1485                 : 
    1486                 : /************************************************************************/
    1487                 : /*                      GetNextUnfilteredFeature()                      */
    1488                 : /************************************************************************/
    1489                 : 
    1490              35 : OGRFeature *OGRDXFLayer::GetNextUnfilteredFeature()

    1491                 : 
    1492                 : {
    1493              35 :     OGRFeature *poFeature = NULL;

    1494                 : 
    1495                 : /* -------------------------------------------------------------------- */
    1496                 : /*      If we have pending features, return one of them.                */
    1497                 : /* -------------------------------------------------------------------- */
    1498              35 :     if( !apoPendingFeatures.empty() )

    1499                 :     {
    1500               4 :         poFeature = apoPendingFeatures.top();

    1501               4 :         apoPendingFeatures.pop();

    1502                 : 
    1503               4 :         poFeature->SetFID( iNextFID++ );

    1504               4 :         return poFeature;

    1505                 :     }
    1506                 : 
    1507                 : /* -------------------------------------------------------------------- */
    1508                 : /*      Read the entity type.                                           */
    1509                 : /* -------------------------------------------------------------------- */
    1510                 :     char szLineBuf[257];
    1511                 :     int nCode;
    1512                 : 
    1513              91 :     while( poFeature == NULL )

    1514                 :     {
    1515                 :         // read ahead to an entity.
    1516              31 :         while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 ) {}

    1517                 : 
    1518              31 :         if( nCode == -1 )

    1519                 :         {
    1520               0 :             CPLDebug( "DXF", "Unexpected end of data without ENDSEC." );

    1521               0 :             return NULL;

    1522                 :         }
    1523                 :         
    1524              31 :         if( EQUAL(szLineBuf,"ENDSEC") )

    1525                 :         {
    1526                 :             //CPLDebug( "DXF", "Clean end of features at ENDSEC." );
    1527               1 :             poDS->UnreadValue();

    1528               1 :             return NULL;

    1529                 :         }
    1530                 : 
    1531              30 :         if( EQUAL(szLineBuf,"ENDBLK") )

    1532                 :         {
    1533                 :             //CPLDebug( "DXF", "Clean end of block at ENDBLK." );
    1534               1 :             poDS->UnreadValue();

    1535               1 :             return NULL;

    1536                 :         }
    1537                 : 
    1538                 : /* -------------------------------------------------------------------- */
    1539                 : /*      Handle the entity.                                              */
    1540                 : /* -------------------------------------------------------------------- */
    1541              29 :         oStyleProperties.clear();

    1542                 : 
    1543              29 :         if( EQUAL(szLineBuf,"POINT") )

    1544                 :         {
    1545               4 :             poFeature = TranslatePOINT();

    1546                 :         }
    1547              25 :         else if( EQUAL(szLineBuf,"MTEXT") )

    1548                 :         {
    1549               2 :             poFeature = TranslateMTEXT();

    1550                 :         }
    1551              23 :         else if( EQUAL(szLineBuf,"TEXT") )

    1552                 :         {
    1553               0 :             poFeature = TranslateTEXT();

    1554                 :         }
    1555              23 :         else if( EQUAL(szLineBuf,"LINE") )

    1556                 :         {
    1557               7 :             poFeature = TranslateLINE();

    1558                 :         }
    1559              16 :         else if( EQUAL(szLineBuf,"POLYLINE") )

    1560                 :         {
    1561               1 :             poFeature = TranslatePOLYLINE();

    1562                 :         }
    1563              15 :         else if( EQUAL(szLineBuf,"LWPOLYLINE") )

    1564                 :         {
    1565               5 :             poFeature = TranslateLWPOLYLINE();

    1566                 :         }
    1567              10 :         else if( EQUAL(szLineBuf,"CIRCLE") )

    1568                 :         {
    1569               0 :             poFeature = TranslateCIRCLE();

    1570                 :         }
    1571              10 :         else if( EQUAL(szLineBuf,"ELLIPSE") )

    1572                 :         {
    1573               4 :             poFeature = TranslateELLIPSE();

    1574                 :         }
    1575               6 :         else if( EQUAL(szLineBuf,"ARC") )

    1576                 :         {
    1577               2 :             poFeature = TranslateARC();

    1578                 :         }
    1579               4 :         else if( EQUAL(szLineBuf,"SPLINE") )

    1580                 :         {
    1581               0 :             poFeature = TranslateSPLINE();

    1582                 :         }
    1583               4 :         else if( EQUAL(szLineBuf,"INSERT") )

    1584                 :         {
    1585               0 :             poFeature = TranslateINSERT();

    1586                 :         }
    1587               4 :         else if( EQUAL(szLineBuf,"DIMENSION") )

    1588                 :         {
    1589               4 :             poFeature = TranslateDIMENSION();

    1590                 :         }
    1591                 :         else
    1592                 :         {
    1593               0 :             CPLDebug( "DXF", "Ignoring entity '%s'.", szLineBuf );

    1594                 :         }
    1595                 :     }
    1596                 : 
    1597                 : /* -------------------------------------------------------------------- */
    1598                 : /*      Set FID.                                                        */
    1599                 : /* -------------------------------------------------------------------- */
    1600              29 :     poFeature->SetFID( iNextFID++ );

    1601              29 :     m_nFeaturesRead++;

    1602                 : 
    1603              29 :     return poFeature;

    1604                 : }
    1605                 : 
    1606                 : /************************************************************************/
    1607                 : /*                           GetNextFeature()                           */
    1608                 : /************************************************************************/
    1609                 : 
    1610              31 : OGRFeature *OGRDXFLayer::GetNextFeature()

    1611                 : 
    1612                 : {
    1613               0 :     while( TRUE )

    1614                 :     {
    1615              31 :         OGRFeature *poFeature = GetNextUnfilteredFeature();

    1616                 : 
    1617              31 :         if( poFeature == NULL )

    1618               1 :             return NULL;

    1619                 : 
    1620              30 :         if( (m_poFilterGeom == NULL

    1621                 :              || FilterGeometry( poFeature->GetGeometryRef() ) )
    1622                 :             && (m_poAttrQuery == NULL
    1623                 :                 || m_poAttrQuery->Evaluate( poFeature ) ) )
    1624                 :         {
    1625              30 :             return poFeature;

    1626                 :         }
    1627                 : 
    1628               0 :         delete poFeature;

    1629                 :     }
    1630                 : }
    1631                 : 
    1632                 : /************************************************************************/
    1633                 : /*                           TestCapability()                           */
    1634                 : /************************************************************************/
    1635                 : 
    1636               0 : int OGRDXFLayer::TestCapability( const char * pszCap )

    1637                 : 
    1638                 : {
    1639               0 :     return FALSE;

    1640                 : }
    1641                 : 

Generated by: LTP GCOV extension version 1.5