LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/dxf - ogrdxflayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 721 520 72.1 %
Date: 2011-12-18 Functions: 41 29 70.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrdxflayer.cpp 22527 2011-06-13 03:58:34Z warmerdam $
       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                 : CPL_CVSID("$Id: ogrdxflayer.cpp 22527 2011-06-13 03:58:34Z warmerdam $");
      35                 : 
      36                 : #ifndef PI
      37                 : #define PI  3.14159265358979323846
      38                 : #endif 
      39                 : 
      40                 : /************************************************************************/
      41                 : /*                            OGRDXFLayer()                             */
      42                 : /************************************************************************/
      43                 : 
      44              16 : OGRDXFLayer::OGRDXFLayer( OGRDXFDataSource *poDS )
      45                 : 
      46                 : {
      47              16 :     this->poDS = poDS;
      48                 : 
      49              16 :     iNextFID = 0;
      50                 : 
      51              16 :     poFeatureDefn = new OGRFeatureDefn( "entities" );
      52              16 :     poFeatureDefn->Reference();
      53                 : 
      54              16 :     poDS->AddStandardFields( poFeatureDefn );
      55                 : 
      56              16 :     if( !poDS->InlineBlocks() )
      57                 :     {
      58               1 :         OGRFieldDefn  oScaleField( "BlockScale", OFTRealList );
      59               1 :         poFeatureDefn->AddFieldDefn( &oScaleField );
      60                 : 
      61               1 :         OGRFieldDefn  oBlockAngleField( "BlockAngle", OFTReal );
      62               1 :         poFeatureDefn->AddFieldDefn( &oBlockAngleField );
      63                 :     }
      64              16 : }
      65                 : 
      66                 : /************************************************************************/
      67                 : /*                           ~OGRDXFLayer()                           */
      68                 : /************************************************************************/
      69                 : 
      70              16 : OGRDXFLayer::~OGRDXFLayer()
      71                 : 
      72                 : {
      73              16 :     ClearPendingFeatures();
      74              16 :     if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
      75                 :     {
      76                 :         CPLDebug( "DXF", "%d features read on layer '%s'.",
      77                 :                   (int) m_nFeaturesRead, 
      78              14 :                   poFeatureDefn->GetName() );
      79                 :     }
      80                 : 
      81              16 :     if( poFeatureDefn )
      82              16 :         poFeatureDefn->Release();
      83              16 : }
      84                 : 
      85                 : /************************************************************************/
      86                 : /*                        ClearPendingFeatures()                        */
      87                 : /************************************************************************/
      88                 : 
      89              29 : void OGRDXFLayer::ClearPendingFeatures()
      90                 : 
      91                 : {
      92              58 :     while( !apoPendingFeatures.empty() )
      93                 :     {
      94               0 :         delete apoPendingFeatures.front();
      95               0 :         apoPendingFeatures.pop();
      96                 :     }
      97              29 : }
      98                 : 
      99                 : /************************************************************************/
     100                 : /*                            ResetReading()                            */
     101                 : /************************************************************************/
     102                 : 
     103              13 : void OGRDXFLayer::ResetReading()
     104                 : 
     105                 : {
     106              13 :     iNextFID = 0;
     107              13 :     ClearPendingFeatures();
     108              13 :     poDS->RestartEntities();
     109              13 : }
     110                 : 
     111                 : /************************************************************************/
     112                 : /*                      TranslateGenericProperty()                      */
     113                 : /*                                                                      */
     114                 : /*      Try and convert entity properties handled similarly for most    */
     115                 : /*      or all entity types.                                            */
     116                 : /************************************************************************/
     117                 : 
     118             772 : void OGRDXFLayer::TranslateGenericProperty( OGRFeature *poFeature, 
     119                 :                                             int nCode, char *pszValue )
     120                 : 
     121                 : {
     122             772 :     switch( nCode )
     123                 :     {
     124                 :       case 8: 
     125             100 :         poFeature->SetField( "Layer", TextUnescape(pszValue) );
     126             100 :         break;
     127                 :             
     128                 :       case 100: 
     129                 :       {
     130             210 :           CPLString osSubClass = poFeature->GetFieldAsString("SubClasses");
     131             210 :           if( osSubClass.size() > 0 )
     132             114 :               osSubClass += ":";
     133             210 :           osSubClass += pszValue;
     134             210 :           poFeature->SetField( "SubClasses", osSubClass.c_str() );
     135                 :       }
     136             210 :       break;
     137                 : 
     138                 :       case 62:
     139              85 :         oStyleProperties["Color"] = pszValue;
     140              85 :         break;
     141                 : 
     142                 :       case 6:
     143              85 :         poFeature->SetField( "Linetype", TextUnescape(pszValue) );
     144              85 :         break;
     145                 : 
     146                 :       case 370:
     147                 :       case 39:
     148              85 :         oStyleProperties["LineWeight"] = pszValue;
     149              85 :         break;
     150                 : 
     151                 :       case 5:
     152              96 :         poFeature->SetField( "EntityHandle", pszValue );
     153              96 :         break;
     154                 : 
     155                 :         // Extended entity data
     156                 :       case 1000:
     157                 :       case 1002:
     158                 :       case 1004:
     159                 :       case 1005:
     160                 :       case 1040:
     161                 :       case 1041:
     162                 :       case 1070:
     163                 :       case 1071:
     164                 :       {
     165               0 :           CPLString osAggregate = poFeature->GetFieldAsString("ExtendedEntity");
     166                 : 
     167               0 :           if( osAggregate.size() > 0 )
     168               0 :               osAggregate += " ";
     169               0 :           osAggregate += pszValue;
     170                 :             
     171               0 :           poFeature->SetField( "ExtendedEntity", osAggregate );
     172                 :       }
     173               0 :       break;
     174                 : 
     175                 :       // OCS vector.
     176                 :       case 210:
     177               1 :         oStyleProperties["210_N.dX"] = pszValue;
     178               1 :         break;
     179                 :         
     180                 :       case 220:
     181               1 :         oStyleProperties["220_N.dY"] = pszValue;
     182               1 :         break;
     183                 :         
     184                 :       case 230:
     185               1 :         oStyleProperties["230_N.dZ"] = pszValue;
     186                 :         break;
     187                 : 
     188                 : 
     189                 :       default:
     190                 :         break;
     191                 :     }
     192             772 : }
     193                 : 
     194                 : /************************************************************************/
     195                 : /*                          PrepareLineStyle()                          */
     196                 : /************************************************************************/
     197                 : 
     198              78 : void OGRDXFLayer::PrepareLineStyle( OGRFeature *poFeature )
     199                 : 
     200                 : {
     201              78 :     CPLString osLayer = poFeature->GetFieldAsString("Layer");
     202                 : 
     203                 : /* -------------------------------------------------------------------- */
     204                 : /*      Is the layer disabled/hidden/frozen/off?                        */
     205                 : /* -------------------------------------------------------------------- */
     206                 :     int bHidden = 
     207              78 :         EQUAL(poDS->LookupLayerProperty( osLayer, "Hidden" ), "1");
     208                 : 
     209                 : /* -------------------------------------------------------------------- */
     210                 : /*      Work out the color for this feature.                            */
     211                 : /* -------------------------------------------------------------------- */
     212              78 :     int nColor = 256;
     213                 : 
     214              78 :     if( oStyleProperties.count("Color") > 0 )
     215              72 :         nColor = atoi(oStyleProperties["Color"]);
     216                 : 
     217                 :     // Use layer color? 
     218              78 :     if( nColor < 1 || nColor > 255 )
     219                 :     {
     220              73 :         const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" );
     221              73 :         if( pszValue != NULL )
     222              73 :             nColor = atoi(pszValue);
     223                 :     }
     224                 :         
     225              78 :     if( nColor < 1 || nColor > 255 )
     226                 :         return;
     227                 : 
     228                 : /* -------------------------------------------------------------------- */
     229                 : /*      Get line weight if available.                                   */
     230                 : /* -------------------------------------------------------------------- */
     231              73 :     double dfWeight = 0.0;
     232                 : 
     233              73 :     if( oStyleProperties.count("LineWeight") > 0 )
     234                 :     {
     235              69 :         CPLString osWeight = oStyleProperties["LineWeight"];
     236                 : 
     237              69 :         if( osWeight == "-1" )
     238              64 :             osWeight = poDS->LookupLayerProperty(osLayer,"LineWeight");
     239                 : 
     240              69 :         dfWeight = CPLAtof(osWeight) / 100.0;
     241                 :     }
     242                 : 
     243                 : /* -------------------------------------------------------------------- */
     244                 : /*      Do we have a dash/dot line style?                               */
     245                 : /* -------------------------------------------------------------------- */
     246                 :     const char *pszPattern = poDS->LookupLineType(
     247              73 :         poFeature->GetFieldAsString("Linetype") );
     248                 : 
     249                 : /* -------------------------------------------------------------------- */
     250                 : /*      Format the style string.                                        */
     251                 : /* -------------------------------------------------------------------- */
     252              73 :     CPLString osStyle;
     253              73 :     const unsigned char *pabyDXFColors = ACGetColorTable();
     254                 : 
     255                 :     osStyle.Printf( "PEN(c:#%02x%02x%02x", 
     256              73 :                     pabyDXFColors[nColor*3+0],
     257              73 :                     pabyDXFColors[nColor*3+1],
     258             219 :                     pabyDXFColors[nColor*3+2] );
     259                 : 
     260              73 :     if( bHidden )
     261               0 :         osStyle += "00"; 
     262                 : 
     263              73 :     if( dfWeight > 0.0 )
     264                 :     {
     265                 :         char szBuffer[64];
     266               3 :         snprintf(szBuffer, sizeof(szBuffer), "%.2g", dfWeight);
     267               3 :         char* pszComma = strchr(szBuffer, ',');
     268               3 :         if (pszComma)
     269               0 :             *pszComma = '.';
     270               3 :         osStyle += CPLString().Printf( ",w:%sg", szBuffer );
     271                 :     }
     272                 : 
     273              73 :     if( pszPattern )
     274                 :     {
     275               3 :         osStyle += ",p:\"";
     276               3 :         osStyle += pszPattern;
     277               3 :         osStyle += "\"";
     278                 :     }
     279                 : 
     280              73 :     osStyle += ")";
     281                 :     
     282              73 :     poFeature->SetStyleString( osStyle );
     283                 : }
     284                 : 
     285                 : /************************************************************************/
     286                 : /*                            OCSTransformer                            */
     287                 : /************************************************************************/
     288                 : 
     289                 : class OCSTransformer : public OGRCoordinateTransformation
     290               1 : {
     291                 : private:
     292                 :     double adfN[3];
     293                 :     double adfAX[3];
     294                 :     double adfAY[3];
     295                 :     
     296                 : public:
     297               1 :     OCSTransformer( double adfN[3] ) {
     298                 :         static const double dSmall = 1.0 / 64.0;
     299                 :         static const double adfWZ[3] = {0, 0, 1};
     300                 :         static const double adfWY[3] = {0, 1, 0};
     301                 : 
     302               1 :         memcpy( this->adfN, adfN, sizeof(double)*3 );
     303                 : 
     304               1 :     if ((ABS(adfN[0]) < dSmall) && (ABS(adfN[1]) < dSmall))
     305               0 :             CrossProduct(adfWY, adfN, adfAX);
     306                 :     else
     307               1 :             CrossProduct(adfWZ, adfN, adfAX);
     308                 : 
     309               1 :     Scale2Unit( adfAX );
     310               1 :     CrossProduct(adfN, adfAX, adfAY);
     311               1 :     Scale2Unit( adfAY );
     312               1 :     }
     313                 : 
     314               2 :     void CrossProduct(const double *a, const double *b, double *vResult) {
     315               2 :         vResult[0] = a[1] * b[2] - a[2] * b[1];
     316               2 :         vResult[1] = a[2] * b[0] - a[0] * b[2];
     317               2 :         vResult[2] = a[0] * b[1] - a[1] * b[0];
     318               2 :     }
     319                 : 
     320               2 :     void Scale2Unit(double* adfV) {
     321               2 :     double dfLen=sqrt(adfV[0]*adfV[0] + adfV[1]*adfV[1] + adfV[2]*adfV[2]);
     322               2 :     if (dfLen != 0)
     323                 :     {
     324               2 :             adfV[0] /= dfLen;
     325               2 :             adfV[1] /= dfLen;
     326               2 :             adfV[2] /= dfLen;
     327                 :     }
     328               2 :     }
     329               0 :     OGRSpatialReference *GetSourceCS() { return NULL; }
     330               1 :     OGRSpatialReference *GetTargetCS() { return NULL; }
     331               0 :     int Transform( int nCount, 
     332                 :                    double *x, double *y, double *z )
     333               0 :         { return TransformEx( nCount, x, y, z, NULL ); }
     334                 :     
     335               1 :     int TransformEx( int nCount, 
     336                 :                      double *adfX, double *adfY, double *adfZ = NULL,
     337                 :                      int *pabSuccess = NULL )
     338                 :         {
     339                 :             int i;
     340               4 :             for( i = 0; i < nCount; i++ )
     341                 :             {
     342               3 :                 double x = adfX[i], y = adfY[i], z = adfZ[i];
     343                 :                 
     344               3 :                 adfX[i] = x * adfAX[0] + y * adfAY[0] + z * adfN[0];
     345               3 :                 adfY[i] = x * adfAX[1] + y * adfAY[1] + z * adfN[1];
     346               3 :                 adfZ[i] = x * adfAX[2] + y * adfAY[2] + z * adfN[2];
     347                 : 
     348               3 :                 if( pabSuccess )
     349               3 :                     pabSuccess[i] = TRUE;
     350                 :             }
     351               1 :             return TRUE;
     352                 :         }
     353                 : };
     354                 : 
     355                 : /************************************************************************/
     356                 : /*                        ApplyOCSTransformer()                         */
     357                 : /*                                                                      */
     358                 : /*      Apply a transformation from OCS to world coordinates if an      */
     359                 : /*      OCS vector was found in the object.                             */
     360                 : /************************************************************************/
     361                 : 
     362              11 : void OGRDXFLayer::ApplyOCSTransformer( OGRGeometry *poGeometry )
     363                 : 
     364                 : {
     365              11 :     if( oStyleProperties.count("210_N.dX") == 0
     366                 :         || oStyleProperties.count("220_N.dY") == 0
     367                 :         || oStyleProperties.count("230_N.dZ") == 0 )
     368              10 :         return;
     369                 : 
     370               1 :     if( poGeometry == NULL )
     371               0 :         return;
     372                 : 
     373                 :     double adfN[3];
     374                 : 
     375               1 :     adfN[0] = CPLAtof(oStyleProperties["210_N.dX"]);
     376               2 :     adfN[1] = CPLAtof(oStyleProperties["220_N.dY"]);
     377               2 :     adfN[2] = CPLAtof(oStyleProperties["230_N.dZ"]);
     378                 : 
     379               1 :     OCSTransformer oTransformer( adfN );
     380                 : 
     381               2 :     poGeometry->transform( &oTransformer );
     382                 : }
     383                 : 
     384                 : /************************************************************************/
     385                 : /*                            TextUnescape()                            */
     386                 : /*                                                                      */
     387                 : /*      Unexcape DXF style escape sequences such as \P for newline      */
     388                 : /*      and \~ for space, and do the recoding to UTF8.                  */
     389                 : /************************************************************************/
     390                 : 
     391             192 : CPLString OGRDXFLayer::TextUnescape( const char *pszInput )
     392                 : 
     393                 : {
     394             192 :     return ACTextUnescape( pszInput, poDS->GetEncoding() );
     395                 : }
     396                 : 
     397                 : /************************************************************************/
     398                 : /*                           TranslateMTEXT()                           */
     399                 : /************************************************************************/
     400                 : 
     401               7 : OGRFeature *OGRDXFLayer::TranslateMTEXT()
     402                 : 
     403                 : {
     404                 :     char szLineBuf[257];
     405                 :     int nCode;
     406               7 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     407               7 :     double dfX = 0.0, dfY = 0.0, dfZ = 0.0;
     408               7 :     double dfAngle = 0.0;
     409               7 :     double dfHeight = 0.0;
     410               7 :     double dfXDirection = 0.0, dfYDirection = 0.0;
     411               7 :     int bHaveZ = FALSE;
     412               7 :     int nAttachmentPoint = -1;
     413               7 :     CPLString osText;
     414                 : 
     415             144 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     416                 :     {
     417             130 :         switch( nCode )
     418                 :         {
     419                 :           case 10:
     420               7 :             dfX = CPLAtof(szLineBuf);
     421               7 :             break;
     422                 : 
     423                 :           case 20:
     424               7 :             dfY = CPLAtof(szLineBuf);
     425               7 :             break;
     426                 : 
     427                 :           case 30:
     428               4 :             dfZ = CPLAtof(szLineBuf);
     429               4 :             bHaveZ = TRUE;
     430               4 :             break;
     431                 : 
     432                 :           case 40:
     433               7 :             dfHeight = CPLAtof(szLineBuf);
     434               7 :             break;
     435                 : 
     436                 :           case 71:
     437               7 :             nAttachmentPoint = atoi(szLineBuf);
     438               7 :             break;
     439                 : 
     440                 :           case 11:
     441               0 :             dfXDirection = CPLAtof(szLineBuf);
     442               0 :             break;
     443                 : 
     444                 :           case 21:
     445               0 :             dfYDirection = CPLAtof(szLineBuf);
     446               0 :             dfAngle = atan2( dfYDirection, dfXDirection ) * 180.0 / PI;
     447               0 :             break;
     448                 : 
     449                 :           case 1:
     450                 :           case 3:
     451               7 :             if( osText != "" )
     452               0 :                 osText += "\n";
     453               7 :             osText += TextUnescape(szLineBuf);
     454               7 :             break;
     455                 : 
     456                 :           case 50:
     457               7 :             dfAngle = CPLAtof(szLineBuf);
     458               7 :             break;
     459                 : 
     460                 :           default:
     461              84 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     462                 :             break;
     463                 :         }
     464                 :     }
     465                 : 
     466               7 :     if( nCode == 0 )
     467               7 :         poDS->UnreadValue();
     468                 : 
     469               7 :     if( bHaveZ )
     470               4 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY, dfZ ) );
     471                 :     else
     472               3 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY ) );
     473                 : 
     474                 : /* -------------------------------------------------------------------- */
     475                 : /*      Apply text after stripping off any extra terminating newline.   */
     476                 : /* -------------------------------------------------------------------- */
     477               7 :     if( osText != "" && osText[osText.size()-1] == '\n' )
     478               0 :         osText.resize( osText.size() - 1 );
     479                 : 
     480               7 :     poFeature->SetField( "Text", osText );
     481                 : 
     482                 :     
     483                 : /* -------------------------------------------------------------------- */
     484                 : /*      We need to escape double quotes with backslashes before they    */
     485                 : /*      can be inserted in the style string.                            */
     486                 : /* -------------------------------------------------------------------- */
     487               7 :     if( strchr( osText, '"') != NULL )
     488                 :     {
     489               2 :         CPLString osEscaped;
     490                 :         size_t iC;
     491                 : 
     492              46 :         for( iC = 0; iC < osText.size(); iC++ )
     493                 :         {
     494              44 :             if( osText[iC] == '"' )
     495               4 :                 osEscaped += "\\\"";
     496                 :             else
     497              40 :                 osEscaped += osText[iC];
     498                 :         }
     499               2 :         osText = osEscaped;
     500                 :     }
     501                 : 
     502                 : /* -------------------------------------------------------------------- */
     503                 : /*      Work out the color for this feature.                            */
     504                 : /* -------------------------------------------------------------------- */
     505               7 :     int nColor = 256;
     506                 : 
     507               7 :     if( oStyleProperties.count("Color") > 0 )
     508               7 :         nColor = atoi(oStyleProperties["Color"]);
     509                 : 
     510                 :     // Use layer color? 
     511               7 :     if( nColor < 1 || nColor > 255 )
     512                 :     {
     513               7 :         CPLString osLayer = poFeature->GetFieldAsString("Layer");
     514               7 :         const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" );
     515               7 :         if( pszValue != NULL )
     516               7 :             nColor = atoi(pszValue);
     517                 :     }
     518                 :         
     519                 : /* -------------------------------------------------------------------- */
     520                 : /*      Prepare style string.                                           */
     521                 : /* -------------------------------------------------------------------- */
     522               7 :     CPLString osStyle;
     523                 :     char szBuffer[64];
     524                 :     char* pszComma;
     525                 : 
     526               7 :     osStyle.Printf("LABEL(f:\"Arial\",t:\"%s\"",osText.c_str());
     527                 : 
     528               7 :     if( dfAngle != 0.0 )
     529                 :     {
     530               5 :         snprintf(szBuffer, sizeof(szBuffer), "%.3g", dfAngle);
     531               5 :         pszComma = strchr(szBuffer, ',');
     532               5 :         if (pszComma)
     533               0 :             *pszComma = '.';
     534               5 :         osStyle += CPLString().Printf(",a:%s", szBuffer);
     535                 :     }
     536                 : 
     537               7 :     if( dfHeight != 0.0 )
     538                 :     {
     539               7 :         snprintf(szBuffer, sizeof(szBuffer), "%.3g", dfHeight);
     540               7 :         pszComma = strchr(szBuffer, ',');
     541               7 :         if (pszComma)
     542               0 :             *pszComma = '.';
     543               7 :         osStyle += CPLString().Printf(",s:%sg", szBuffer);
     544                 :     }
     545                 : 
     546               7 :     if( nAttachmentPoint >= 0 && nAttachmentPoint <= 9 )
     547                 :     {
     548                 :         const static int anAttachmentMap[10] = 
     549                 :             { -1, 7, 8, 9, 4, 5, 6, 1, 2, 3 };
     550                 :         
     551                 :         osStyle += 
     552               7 :             CPLString().Printf(",p:%d", anAttachmentMap[nAttachmentPoint]);
     553                 :     }
     554                 : 
     555               7 :     if( nColor > 0 && nColor < 256 )
     556                 :     {
     557               7 :         const unsigned char *pabyDXFColors = ACGetColorTable();
     558                 :         osStyle += 
     559                 :             CPLString().Printf( ",c:#%02x%02x%02x", 
     560               7 :                                 pabyDXFColors[nColor*3+0],
     561               7 :                                 pabyDXFColors[nColor*3+1],
     562              21 :                                 pabyDXFColors[nColor*3+2] );
     563                 :     }
     564                 : 
     565               7 :     osStyle += ")";
     566                 : 
     567               7 :     poFeature->SetStyleString( osStyle );
     568                 : 
     569               7 :     return poFeature;
     570                 : }
     571                 : 
     572                 : /************************************************************************/
     573                 : /*                           TranslateTEXT()                            */
     574                 : /************************************************************************/
     575                 : 
     576               0 : OGRFeature *OGRDXFLayer::TranslateTEXT()
     577                 : 
     578                 : {
     579                 :     char szLineBuf[257];
     580                 :     int nCode;
     581               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     582               0 :     double dfX = 0.0, dfY = 0.0, dfZ = 0.0;
     583               0 :     double dfAngle = 0.0;
     584               0 :     double dfHeight = 0.0;
     585               0 :     CPLString osText;
     586               0 :     int bHaveZ = FALSE;
     587                 : 
     588               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     589                 :     {
     590               0 :         switch( nCode )
     591                 :         {
     592                 :           case 10:
     593               0 :             dfX = CPLAtof(szLineBuf);
     594               0 :             break;
     595                 : 
     596                 :           case 20:
     597               0 :             dfY = CPLAtof(szLineBuf);
     598               0 :             break;
     599                 : 
     600                 :           case 30:
     601               0 :             dfZ = CPLAtof(szLineBuf);
     602               0 :             bHaveZ = TRUE;
     603               0 :             break;
     604                 : 
     605                 :           case 40:
     606               0 :             dfHeight = CPLAtof(szLineBuf);
     607               0 :             break;
     608                 : 
     609                 :           case 1:
     610                 :           // case 3:  // we used to capture prompt, but it should not be displayed as text.
     611               0 :             osText += szLineBuf;
     612               0 :             break;
     613                 : 
     614                 :           case 50:
     615               0 :             dfAngle = CPLAtof(szLineBuf);
     616               0 :             break;
     617                 : 
     618                 :           default:
     619               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     620                 :             break;
     621                 :         }
     622                 :     }
     623                 : 
     624               0 :     if( nCode == 0 )
     625               0 :         poDS->UnreadValue();
     626                 : 
     627               0 :     if( bHaveZ )
     628               0 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY, dfZ ) );
     629                 :     else
     630               0 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY ) );
     631                 : 
     632                 : /* -------------------------------------------------------------------- */
     633                 : /*      Translate text from Win-1252 to UTF8.  We approximate this      */
     634                 : /*      by treating Win-1252 as Latin-1.                                */
     635                 : /* -------------------------------------------------------------------- */
     636               0 :     osText.Recode( poDS->GetEncoding(), CPL_ENC_UTF8 );
     637                 : 
     638               0 :     poFeature->SetField( "Text", osText );
     639                 : 
     640                 : /* -------------------------------------------------------------------- */
     641                 : /*      We need to escape double quotes with backslashes before they    */
     642                 : /*      can be inserted in the style string.                            */
     643                 : /* -------------------------------------------------------------------- */
     644               0 :     if( strchr( osText, '"') != NULL )
     645                 :     {
     646               0 :         CPLString osEscaped;
     647                 :         size_t iC;
     648                 : 
     649               0 :         for( iC = 0; iC < osText.size(); iC++ )
     650                 :         {
     651               0 :             if( osText[iC] == '"' )
     652               0 :                 osEscaped += "\\\"";
     653                 :             else
     654               0 :                 osEscaped += osText[iC];
     655                 :         }
     656               0 :         osText = osEscaped;
     657                 :     }
     658                 : 
     659                 : /* -------------------------------------------------------------------- */
     660                 : /*      Is the layer disabled/hidden/frozen/off?                        */
     661                 : /* -------------------------------------------------------------------- */
     662               0 :     CPLString osLayer = poFeature->GetFieldAsString("Layer");
     663                 : 
     664                 :     int bHidden = 
     665               0 :         EQUAL(poDS->LookupLayerProperty( osLayer, "Hidden" ), "1");
     666                 : 
     667                 : /* -------------------------------------------------------------------- */
     668                 : /*      Work out the color for this feature.                            */
     669                 : /* -------------------------------------------------------------------- */
     670               0 :     int nColor = 256;
     671                 : 
     672               0 :     if( oStyleProperties.count("Color") > 0 )
     673               0 :         nColor = atoi(oStyleProperties["Color"]);
     674                 : 
     675                 :     // Use layer color? 
     676               0 :     if( nColor < 1 || nColor > 255 )
     677                 :     {
     678               0 :         const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" );
     679               0 :         if( pszValue != NULL )
     680               0 :             nColor = atoi(pszValue);
     681                 :     }
     682                 :         
     683               0 :     if( nColor < 1 || nColor > 255 )
     684               0 :         nColor = 8;
     685                 : 
     686                 : /* -------------------------------------------------------------------- */
     687                 : /*      Prepare style string.                                           */
     688                 : /* -------------------------------------------------------------------- */
     689               0 :     CPLString osStyle;
     690                 :     char szBuffer[64];
     691                 :     char* pszComma;
     692                 : 
     693               0 :     osStyle.Printf("LABEL(f:\"Arial\",t:\"%s\"",osText.c_str());
     694                 : 
     695               0 :     if( dfAngle != 0.0 )
     696                 :     {
     697               0 :         snprintf(szBuffer, sizeof(szBuffer), "%.3g", dfAngle);
     698               0 :         pszComma = strchr(szBuffer, ',');
     699               0 :         if (pszComma)
     700               0 :             *pszComma = '.';
     701               0 :         osStyle += CPLString().Printf(",a:%s", szBuffer);
     702                 :     }
     703                 : 
     704               0 :     if( dfHeight != 0.0 )
     705                 :     {
     706               0 :         snprintf(szBuffer, sizeof(szBuffer), "%.3g", dfHeight);
     707               0 :         pszComma = strchr(szBuffer, ',');
     708               0 :         if (pszComma)
     709               0 :             *pszComma = '.';
     710               0 :         osStyle += CPLString().Printf(",s:%sg", szBuffer);
     711                 :     }
     712                 : 
     713               0 :     const unsigned char *pabyDWGColors = ACGetColorTable();
     714                 : 
     715                 :     snprintf( szBuffer, sizeof(szBuffer), ",c:#%02x%02x%02x", 
     716               0 :               pabyDWGColors[nColor*3+0],
     717               0 :               pabyDWGColors[nColor*3+1],
     718               0 :               pabyDWGColors[nColor*3+2] );
     719               0 :     osStyle += szBuffer;
     720                 : 
     721               0 :     if( bHidden )
     722               0 :         osStyle += "00"; 
     723                 : 
     724               0 :     osStyle += ")";
     725                 : 
     726               0 :     poFeature->SetStyleString( osStyle );
     727                 : 
     728               0 :     return poFeature;
     729                 : }
     730                 : 
     731                 : /************************************************************************/
     732                 : /*                           TranslatePOINT()                           */
     733                 : /************************************************************************/
     734                 : 
     735               6 : OGRFeature *OGRDXFLayer::TranslatePOINT()
     736                 : 
     737                 : {
     738                 :     char szLineBuf[257];
     739                 :     int nCode;
     740               6 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     741               6 :     double dfX = 0.0, dfY = 0.0, dfZ = 0.0;
     742               6 :     int bHaveZ = FALSE;
     743                 : 
     744              56 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     745                 :     {
     746              44 :         switch( nCode )
     747                 :         {
     748                 :           case 10:
     749               6 :             dfX = CPLAtof(szLineBuf);
     750               6 :             break;
     751                 : 
     752                 :           case 20:
     753               6 :             dfY = CPLAtof(szLineBuf);
     754               6 :             break;
     755                 : 
     756                 :           case 30:
     757               5 :             dfZ = CPLAtof(szLineBuf);
     758               5 :             bHaveZ = TRUE;
     759               5 :             break;
     760                 : 
     761                 :           default:
     762              27 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     763                 :             break;
     764                 :         }
     765                 :     }
     766                 : 
     767               6 :     if( bHaveZ )
     768               5 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY, dfZ ) );
     769                 :     else
     770               1 :         poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY ) );
     771                 : 
     772               6 :     if( nCode == 0 )
     773               6 :         poDS->UnreadValue();
     774                 : 
     775               6 :     return poFeature;
     776                 : }
     777                 : 
     778                 : /************************************************************************/
     779                 : /*                           TranslateLINE()                            */
     780                 : /************************************************************************/
     781                 : 
     782              49 : OGRFeature *OGRDXFLayer::TranslateLINE()
     783                 : 
     784                 : {
     785                 :     char szLineBuf[257];
     786                 :     int nCode;
     787              49 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     788              49 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0;
     789              49 :     double dfX2 = 0.0, dfY2 = 0.0, dfZ2 = 0.0;
     790              49 :     int bHaveZ = FALSE;
     791                 : 
     792                 : /* -------------------------------------------------------------------- */
     793                 : /*      Process values.                                                 */
     794                 : /* -------------------------------------------------------------------- */
     795             738 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     796                 :     {
     797             640 :         switch( nCode )
     798                 :         {
     799                 :           case 10:
     800              49 :             dfX1 = CPLAtof(szLineBuf);
     801              49 :             break;
     802                 : 
     803                 :           case 11:
     804              49 :             dfX2 = CPLAtof(szLineBuf);
     805              49 :             break;
     806                 : 
     807                 :           case 20:
     808              49 :             dfY1 = CPLAtof(szLineBuf);
     809              49 :             break;
     810                 : 
     811                 :           case 21:
     812              49 :             dfY2 = CPLAtof(szLineBuf);
     813              49 :             break;
     814                 : 
     815                 :           case 30:
     816              49 :             dfZ1 = CPLAtof(szLineBuf);
     817              49 :             bHaveZ = TRUE;
     818              49 :             break;
     819                 : 
     820                 :           case 31:
     821              49 :             dfZ2 = CPLAtof(szLineBuf);
     822              49 :             bHaveZ = TRUE;
     823              49 :             break;
     824                 : 
     825                 :           default:
     826             346 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     827                 :             break;
     828                 :         }
     829                 :     }
     830                 : 
     831              49 :     if( nCode == 0 )
     832              49 :         poDS->UnreadValue();
     833                 : 
     834                 : /* -------------------------------------------------------------------- */
     835                 : /*      Create geometry                                                 */
     836                 : /* -------------------------------------------------------------------- */
     837              49 :     OGRLineString *poLS = new OGRLineString();
     838              49 :     if( bHaveZ )
     839                 :     {
     840              49 :         poLS->addPoint( dfX1, dfY1, dfZ1 );
     841              49 :         poLS->addPoint( dfX2, dfY2, dfZ2 );
     842                 :     }
     843                 :     else
     844                 :     {
     845               0 :         poLS->addPoint( dfX1, dfY1 );
     846               0 :         poLS->addPoint( dfX2, dfY2 );
     847                 :     }
     848                 : 
     849              49 :     poFeature->SetGeometryDirectly( poLS );
     850                 : 
     851              49 :     PrepareLineStyle( poFeature );
     852                 : 
     853              49 :     return poFeature;
     854                 : }
     855                 : 
     856                 : /************************************************************************/
     857                 : /*                         TranslateLWPOLYLINE()                        */
     858                 : /************************************************************************/
     859              10 : OGRFeature *OGRDXFLayer::TranslateLWPOLYLINE()
     860                 : 
     861                 : {
     862                 :     // Collect vertices and attributes into a smooth polyline.
     863                 :     // If there are no bulges, then we are a straight-line polyline.
     864                 :     // Single-vertex polylines become points.
     865                 :     // Group code 30 (vertex Z) is not part of this entity.
     866                 : 
     867                 :     char                szLineBuf[257];
     868                 :     int                 nCode;
     869              10 :     int                 nPolylineFlag = 0;
     870                 : 
     871                 : 
     872              10 :     OGRFeature          *poFeature = new OGRFeature( poFeatureDefn );
     873              10 :     double              dfX = 0.0, dfY = 0.0, dfZ = 0.0;
     874              10 :     int                 bHaveX = FALSE;
     875              10 :     int                 bHaveY = FALSE;
     876                 : 
     877              10 :     int                 nNumVertices = 1;   // use 1 based index
     878              10 :     int                 npolyarcVertexCount = 1;
     879              10 :     double              dfBulge = 0.0;
     880              10 :     DXFSmoothPolyline   smoothPolyline;
     881                 : 
     882              10 :     smoothPolyline.setCoordinateDimension(2);
     883                 : 
     884                 : /* -------------------------------------------------------------------- */
     885                 : /*      Collect information from the LWPOLYLINE object itself.          */
     886                 : /* -------------------------------------------------------------------- */
     887             161 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     888                 :     {
     889             141 :         if(npolyarcVertexCount > nNumVertices)
     890                 :         {
     891                 :             CPLError( CE_Failure, CPLE_AppDefined,
     892               0 :                       "Too many vertices found in LWPOLYLINE." );
     893               0 :             delete poFeature;
     894               0 :             return NULL;
     895                 :         }
     896                 : 
     897             141 :         switch( nCode )
     898                 :         {
     899                 :           case 38:
     900                 :             // Constant elevation.
     901               1 :             dfZ = CPLAtof(szLineBuf);
     902               1 :             smoothPolyline.setCoordinateDimension(3);
     903               1 :             break;
     904                 : 
     905                 :           case 90:
     906              10 :             nNumVertices = atoi(szLineBuf);
     907              10 :             break;
     908                 : 
     909                 :           case 70:
     910              10 :             nPolylineFlag = atoi(szLineBuf);
     911              10 :             break;
     912                 : 
     913                 :           case 10:
     914              27 :             if( bHaveX && bHaveY )
     915                 :             {
     916              17 :                 smoothPolyline.AddPoint(dfX, dfY, dfZ, dfBulge);
     917              17 :                 npolyarcVertexCount++;
     918              17 :                 dfBulge = 0.0;
     919              17 :                 bHaveY = FALSE;
     920                 :             }
     921              27 :             dfX = CPLAtof(szLineBuf);
     922              27 :             bHaveX = TRUE;
     923              27 :             break;
     924                 : 
     925                 :           case 20:
     926              27 :             if( bHaveX && bHaveY )
     927                 :             {
     928               0 :                 smoothPolyline.AddPoint( dfX, dfY, dfZ, dfBulge );
     929               0 :                 npolyarcVertexCount++;
     930               0 :                 dfBulge = 0.0;
     931               0 :                 bHaveX = FALSE;
     932                 :             }
     933              27 :             dfY = CPLAtof(szLineBuf);
     934              27 :             bHaveY = TRUE;
     935              27 :             break;
     936                 : 
     937                 :           case 42:
     938               4 :             dfBulge = CPLAtof(szLineBuf);
     939               4 :             break;
     940                 : 
     941                 : 
     942                 :           default:
     943              62 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     944                 :             break;
     945                 :         }
     946                 :     }
     947                 : 
     948              10 :     poDS->UnreadValue();
     949                 : 
     950              10 :     if( bHaveX && bHaveY )
     951              10 :         smoothPolyline.AddPoint(dfX, dfY, dfZ, dfBulge);
     952                 : 
     953                 :     
     954              10 :     if(smoothPolyline.IsEmpty())
     955                 :     {
     956               0 :         delete poFeature;
     957               0 :         return NULL;
     958                 :     }
     959                 : 
     960                 : /* -------------------------------------------------------------------- */
     961                 : /*      Close polyline if necessary.                                    */
     962                 : /* -------------------------------------------------------------------- */
     963              10 :     if(nPolylineFlag & 0x01)
     964               1 :         smoothPolyline.Close();
     965                 : 
     966              10 :     OGRGeometry* poGeom = smoothPolyline.Tesselate();
     967              10 :     ApplyOCSTransformer( poGeom );
     968              10 :     poFeature->SetGeometryDirectly( poGeom );
     969                 : 
     970              10 :     PrepareLineStyle( poFeature );
     971                 : 
     972              10 :     return poFeature;
     973                 : }
     974                 : 
     975                 : 
     976                 : /************************************************************************/
     977                 : /*                         TranslatePOLYLINE()                          */
     978                 : /*                                                                      */
     979                 : /*      We also capture the following VERTEXes.                         */
     980                 : /************************************************************************/
     981                 : 
     982               1 : OGRFeature *OGRDXFLayer::TranslatePOLYLINE()
     983                 : 
     984                 : {
     985                 :     char szLineBuf[257];
     986                 :     int nCode;
     987               1 :     int nPolylineFlag = 0;
     988               1 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     989                 : 
     990                 : /* -------------------------------------------------------------------- */
     991                 : /*      Collect information from the POLYLINE object itself.            */
     992                 : /* -------------------------------------------------------------------- */
     993               8 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     994                 :     {
     995               6 :         switch( nCode )
     996                 :         {
     997                 :           case 70:
     998               1 :             nPolylineFlag = atoi(szLineBuf);
     999               1 :             break;
    1000                 : 
    1001                 :           default:
    1002               5 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
    1003                 :             break;
    1004                 :         }
    1005                 :     }
    1006                 : 
    1007                 : /* -------------------------------------------------------------------- */
    1008                 : /*      Collect VERTEXes as a smooth polyline.                          */
    1009                 : /* -------------------------------------------------------------------- */
    1010               1 :     double              dfX = 0.0, dfY = 0.0, dfZ = 0.0;
    1011               1 :     double              dfBulge = 0.0;
    1012               1 :     DXFSmoothPolyline   smoothPolyline;
    1013                 : 
    1014               1 :     smoothPolyline.setCoordinateDimension(2);
    1015                 : 
    1016               7 :     while( nCode == 0 && !EQUAL(szLineBuf,"SEQEND") )
    1017                 :     {
    1018                 :         // Eat non-vertex objects.
    1019               5 :         if( !EQUAL(szLineBuf,"VERTEX") )
    1020                 :         {
    1021               0 :             while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf)))>0 ) {}
    1022               0 :             continue;
    1023                 :         }
    1024                 : 
    1025                 :         // process a Vertex
    1026              39 :         while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
    1027                 :         {
    1028              29 :             switch( nCode )
    1029                 :             {
    1030                 :               case 10:
    1031               5 :                 dfX = CPLAtof(szLineBuf);
    1032               5 :                 break;
    1033                 :                 
    1034                 :               case 20:
    1035               5 :                 dfY = CPLAtof(szLineBuf);
    1036               5 :                 break;
    1037                 :                 
    1038                 :               case 30:
    1039               5 :                 dfZ = CPLAtof(szLineBuf);
    1040               5 :                 smoothPolyline.setCoordinateDimension(3);
    1041               5 :                 break;
    1042                 : 
    1043                 :               case 42:
    1044               4 :                 dfBulge = CPLAtof(szLineBuf);
    1045                 :                 break;
    1046                 : 
    1047                 :               default:
    1048                 :                 break;
    1049                 :             }
    1050                 :         }
    1051                 : 
    1052               5 :         smoothPolyline.AddPoint( dfX, dfY, dfZ, dfBulge );
    1053               5 :         dfBulge = 0.0;
    1054                 :     }
    1055                 : 
    1056                 : /* -------------------------------------------------------------------- */
    1057                 : /*      Close polyline if necessary.                                    */
    1058                 : /* -------------------------------------------------------------------- */
    1059               1 :     if(nPolylineFlag & 0x01)
    1060               1 :         smoothPolyline.Close();
    1061                 : 
    1062               1 :     OGRGeometry* poGeom = smoothPolyline.Tesselate();
    1063               1 :     ApplyOCSTransformer( poGeom );
    1064               1 :     poFeature->SetGeometryDirectly( poGeom );
    1065                 : 
    1066               1 :     PrepareLineStyle( poFeature );
    1067                 : 
    1068               1 :     return poFeature;
    1069                 : }
    1070                 : 
    1071                 : /************************************************************************/
    1072                 : /*                          TranslateCIRCLE()                           */
    1073                 : /************************************************************************/
    1074                 : 
    1075               0 : OGRFeature *OGRDXFLayer::TranslateCIRCLE()
    1076                 : 
    1077                 : {
    1078                 :     char szLineBuf[257];
    1079                 :     int nCode;
    1080               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
    1081               0 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0, dfRadius = 0.0;
    1082               0 :     int bHaveZ = FALSE;
    1083                 : 
    1084                 : /* -------------------------------------------------------------------- */
    1085                 : /*      Process values.                                                 */
    1086                 : /* -------------------------------------------------------------------- */
    1087               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
    1088                 :     {
    1089               0 :         switch( nCode )
    1090                 :         {
    1091                 :           case 10:
    1092               0 :             dfX1 = CPLAtof(szLineBuf);
    1093               0 :             break;
    1094                 : 
    1095                 :           case 20:
    1096               0 :             dfY1 = CPLAtof(szLineBuf);
    1097               0 :             break;
    1098                 : 
    1099                 :           case 30:
    1100               0 :             dfZ1 = CPLAtof(szLineBuf);
    1101               0 :             bHaveZ = TRUE;
    1102               0 :             break;
    1103                 : 
    1104                 :           case 40:
    1105               0 :             dfRadius = CPLAtof(szLineBuf);
    1106               0 :             break;
    1107                 : 
    1108                 :           default:
    1109               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
    1110                 :             break;
    1111                 :         }
    1112                 :     }
    1113                 : 
    1114               0 :     if( nCode == 0 )
    1115               0 :         poDS->UnreadValue();
    1116                 : 
    1117                 : /* -------------------------------------------------------------------- */
    1118                 : /*      Create geometry                                                 */
    1119                 : /* -------------------------------------------------------------------- */
    1120                 :     OGRGeometry *poCircle = 
    1121                 :         OGRGeometryFactory::approximateArcAngles( dfX1, dfY1, dfZ1, 
    1122                 :                                                   dfRadius, dfRadius, 0.0,
    1123                 :                                                   0.0, 360.0, 
    1124               0 :                                                   0.0 );
    1125                 : 
    1126               0 :     if( !bHaveZ )
    1127               0 :         poCircle->flattenTo2D();
    1128                 : 
    1129               0 :     poFeature->SetGeometryDirectly( poCircle );
    1130               0 :     PrepareLineStyle( poFeature );
    1131                 : 
    1132               0 :     return poFeature;
    1133                 : }
    1134                 : 
    1135                 : /************************************************************************/
    1136                 : /*                          TranslateELLIPSE()                          */
    1137                 : /************************************************************************/
    1138                 : 
    1139               6 : OGRFeature *OGRDXFLayer::TranslateELLIPSE()
    1140                 : 
    1141                 : {
    1142                 :     char szLineBuf[257];
    1143                 :     int nCode;
    1144               6 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
    1145               6 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0, dfRatio = 0.0;
    1146               6 :     double dfStartAngle = 0.0, dfEndAngle = 360.0;
    1147               6 :     double dfAxisX=0.0, dfAxisY=0.0, dfAxisZ=0.0;
    1148               6 :     int bHaveZ = FALSE;
    1149                 : 
    1150                 : /* -------------------------------------------------------------------- */
    1151                 : /*      Process values.                                                 */
    1152                 : /* -------------------------------------------------------------------- */
    1153             108 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
    1154                 :     {
    1155              96 :         switch( nCode )
    1156                 :         {
    1157                 :           case 10:
    1158               6 :             dfX1 = CPLAtof(szLineBuf);
    1159               6 :             break;
    1160                 : 
    1161                 :           case 20:
    1162               6 :             dfY1 = CPLAtof(szLineBuf);
    1163               6 :             break;
    1164                 : 
    1165                 :           case 30:
    1166               6 :             dfZ1 = CPLAtof(szLineBuf);
    1167               6 :             bHaveZ = TRUE;
    1168               6 :             break;
    1169                 : 
    1170                 :           case 11:
    1171               6 :             dfAxisX = CPLAtof(szLineBuf);
    1172               6 :             break;
    1173                 : 
    1174                 :           case 21:
    1175               6 :             dfAxisY = CPLAtof(szLineBuf);
    1176               6 :             break;
    1177                 : 
    1178                 :           case 31:
    1179               6 :             dfAxisZ = CPLAtof(szLineBuf);
    1180               6 :             break;
    1181                 : 
    1182                 :           case 40:
    1183               6 :             dfRatio = CPLAtof(szLineBuf);
    1184               6 :             break;
    1185                 : 
    1186                 :           case 41:
    1187                 :             // These *seem* to always be in radians regardless of $AUNITS
    1188               6 :             dfEndAngle = -1 * CPLAtof(szLineBuf) * 180.0 / PI;
    1189               6 :             break;
    1190                 : 
    1191                 :           case 42:
    1192                 :             // These *seem* to always be in radians regardless of $AUNITS
    1193               6 :             dfStartAngle = -1 * CPLAtof(szLineBuf) * 180.0 / PI;
    1194               6 :             break;
    1195                 : 
    1196                 :           default:
    1197              42 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
    1198                 :             break;
    1199                 :         }
    1200                 :     }
    1201                 : 
    1202               6 :     if( nCode == 0 )
    1203               6 :         poDS->UnreadValue();
    1204                 : 
    1205                 : /* -------------------------------------------------------------------- */
    1206                 : /*      Compute primary and secondary axis lengths, and the angle of    */
    1207                 : /*      rotation for the ellipse.                                       */
    1208                 : /* -------------------------------------------------------------------- */
    1209                 :     double dfPrimaryRadius, dfSecondaryRadius;
    1210                 :     double dfRotation;
    1211                 : 
    1212               6 :     if( dfStartAngle > dfEndAngle )
    1213               0 :         dfEndAngle += 360.0;
    1214                 : 
    1215                 :     dfPrimaryRadius = sqrt( dfAxisX * dfAxisX 
    1216                 :                             + dfAxisY * dfAxisY
    1217               6 :                             + dfAxisZ * dfAxisZ );
    1218                 : 
    1219               6 :     dfSecondaryRadius = dfRatio * dfPrimaryRadius;
    1220                 : 
    1221               6 :     dfRotation = -1 * atan2( dfAxisY, dfAxisX ) * 180 / PI;
    1222                 : 
    1223                 : /* -------------------------------------------------------------------- */
    1224                 : /*      Create geometry                                                 */
    1225                 : /* -------------------------------------------------------------------- */
    1226                 :     OGRGeometry *poEllipse = 
    1227                 :         OGRGeometryFactory::approximateArcAngles( dfX1, dfY1, dfZ1, 
    1228                 :                                                   dfPrimaryRadius, 
    1229                 :                                                   dfSecondaryRadius,
    1230                 :                                                   dfRotation, 
    1231                 :                                                   dfStartAngle, dfEndAngle,
    1232               6 :                                                   0.0 );
    1233                 : 
    1234               6 :     if( !bHaveZ )
    1235               0 :         poEllipse->flattenTo2D();
    1236                 : 
    1237               6 :     poFeature->SetGeometryDirectly( poEllipse );
    1238                 : 
    1239               6 :     PrepareLineStyle( poFeature );
    1240                 : 
    1241               6 :     return poFeature;
    1242                 : }
    1243                 : 
    1244                 : /************************************************************************/
    1245                 : /*                            TranslateARC()                            */
    1246                 : /************************************************************************/
    1247                 : 
    1248               3 : OGRFeature *OGRDXFLayer::TranslateARC()
    1249                 : 
    1250                 : {
    1251                 :     char szLineBuf[257];
    1252                 :     int nCode;
    1253               3 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
    1254               3 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0, dfRadius = 0.0;
    1255               3 :     double dfStartAngle = 0.0, dfEndAngle = 360.0;
    1256               3 :     int bHaveZ = FALSE;
    1257                 : 
    1258                 : /* -------------------------------------------------------------------- */
    1259                 : /*      Process values.                                                 */
    1260                 : /* -------------------------------------------------------------------- */
    1261              48 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
    1262                 :     {
    1263              42 :         switch( nCode )
    1264                 :         {
    1265                 :           case 10:
    1266               3 :             dfX1 = CPLAtof(szLineBuf);
    1267               3 :             break;
    1268                 : 
    1269                 :           case 20:
    1270               3 :             dfY1 = CPLAtof(szLineBuf);
    1271               3 :             break;
    1272                 : 
    1273                 :           case 30:
    1274               3 :             dfZ1 = CPLAtof(szLineBuf);
    1275               3 :             bHaveZ = TRUE;
    1276               3 :             break;
    1277                 : 
    1278                 :           case 40:
    1279               3 :             dfRadius = CPLAtof(szLineBuf);
    1280               3 :             break;
    1281                 : 
    1282                 :           case 50:
    1283                 :             // This is apparently always degrees regardless of AUNITS
    1284               3 :             dfEndAngle = -1 * CPLAtof(szLineBuf);
    1285               3 :             break;
    1286                 : 
    1287                 :           case 51:
    1288                 :             // This is apparently always degrees regardless of AUNITS
    1289               3 :             dfStartAngle = -1 * CPLAtof(szLineBuf);
    1290               3 :             break;
    1291                 : 
    1292                 :           default:
    1293              24 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
    1294                 :             break;
    1295                 :         }
    1296                 :     }
    1297                 : 
    1298               3 :     if( nCode == 0 )
    1299               3 :         poDS->UnreadValue();
    1300                 : 
    1301                 : /* -------------------------------------------------------------------- */
    1302                 : /*      Create geometry                                                 */
    1303                 : /* -------------------------------------------------------------------- */
    1304               3 :     if( dfStartAngle > dfEndAngle )
    1305               3 :         dfEndAngle += 360.0;
    1306                 : 
    1307                 :     OGRGeometry *poArc = 
    1308                 :         OGRGeometryFactory::approximateArcAngles( dfX1, dfY1, dfZ1, 
    1309                 :                                                   dfRadius, dfRadius, 0.0,
    1310                 :                                                   dfStartAngle, dfEndAngle,
    1311               3 :                                                   0.0 );
    1312               3 :     if( !bHaveZ )
    1313               0 :         poArc->flattenTo2D();
    1314                 : 
    1315               3 :     poFeature->SetGeometryDirectly( poArc );
    1316                 : 
    1317               3 :     PrepareLineStyle( poFeature );
    1318                 : 
    1319               3 :     return poFeature;
    1320                 : }
    1321                 : 
    1322                 : /************************************************************************/
    1323                 : /*                          TranslateSPLINE()                           */
    1324                 : /************************************************************************/
    1325                 : 
    1326                 : void rbspline(int npts,int k,int p1,double b[],double h[], double p[]);
    1327                 : void rbsplinu(int npts,int k,int p1,double b[],double h[], double p[]);
    1328                 : 
    1329               0 : OGRFeature *OGRDXFLayer::TranslateSPLINE()
    1330                 : 
    1331                 : {
    1332                 :     char szLineBuf[257];
    1333               0 :     int nCode, nDegree = -1, nFlags = -1, bClosed = FALSE, i;
    1334               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
    1335               0 :     std::vector<double> adfControlPoints;
    1336                 : 
    1337               0 :     adfControlPoints.push_back(0.0);
    1338                 : 
    1339                 : /* -------------------------------------------------------------------- */
    1340                 : /*      Process values.                                                 */
    1341                 : /* -------------------------------------------------------------------- */
    1342               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
    1343                 :     {
    1344               0 :         switch( nCode )
    1345                 :         {
    1346                 :           case 10:
    1347               0 :             adfControlPoints.push_back( CPLAtof(szLineBuf) );
    1348               0 :             break;
    1349                 : 
    1350                 :           case 20:
    1351               0 :             adfControlPoints.push_back( CPLAtof(szLineBuf) );
    1352               0 :             adfControlPoints.push_back( 0.0 );
    1353               0 :             break;
    1354                 : 
    1355                 :           case 70:
    1356               0 :             nFlags = atoi(szLineBuf);
    1357               0 :             if( nFlags & 1 )
    1358               0 :                 bClosed = TRUE;
    1359               0 :             break;
    1360                 : 
    1361                 :           case 71:
    1362               0 :             nDegree = atoi(szLineBuf);
    1363               0 :             break;
    1364                 : 
    1365                 :           default:
    1366               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
    1367                 :             break;
    1368                 :         }
    1369                 :     }
    1370                 : 
    1371               0 :     if( nCode == 0 )
    1372               0 :         poDS->UnreadValue();
    1373                 : 
    1374               0 :     if( bClosed )
    1375                 :     {
    1376               0 :         for( i = 0; i < nDegree; i++ )
    1377                 :         {
    1378               0 :             adfControlPoints.push_back( adfControlPoints[i*3+1] );
    1379               0 :             adfControlPoints.push_back( adfControlPoints[i*3+2] );
    1380               0 :             adfControlPoints.push_back( adfControlPoints[i*3+3] );
    1381                 :         }
    1382                 :     }
    1383                 : 
    1384                 : /* -------------------------------------------------------------------- */
    1385                 : /*      Interpolate spline                                              */
    1386                 : /* -------------------------------------------------------------------- */
    1387               0 :     int nControlPoints = adfControlPoints.size() / 3;
    1388               0 :     std::vector<double> h, p;
    1389                 : 
    1390               0 :     h.push_back(1.0);
    1391               0 :     for( i = 0; i < nControlPoints; i++ )
    1392               0 :         h.push_back( 1.0 );
    1393                 :     
    1394                 :     // resolution:
    1395                 :     //int p1 = getGraphicVariableInt("$SPLINESEGS", 8) * npts;
    1396               0 :     int p1 = nControlPoints * 8;
    1397                 : 
    1398               0 :     p.push_back( 0.0 );
    1399               0 :     for( i = 0; i < 3*p1; i++ )
    1400               0 :         p.push_back( 0.0 );
    1401                 : 
    1402               0 :     if( bClosed )
    1403                 :         rbsplinu( nControlPoints, nDegree+1, p1, &(adfControlPoints[0]), 
    1404               0 :                   &(h[0]), &(p[0]) );
    1405                 :     else
    1406                 :         rbspline( nControlPoints, nDegree+1, p1, &(adfControlPoints[0]), 
    1407               0 :                   &(h[0]), &(p[0]) );
    1408                 :     
    1409                 : /* -------------------------------------------------------------------- */
    1410                 : /*      Turn into OGR geometry.                                         */
    1411                 : /* -------------------------------------------------------------------- */
    1412               0 :     OGRLineString *poLS = new OGRLineString();
    1413                 : 
    1414               0 :     poLS->setNumPoints( p1 );
    1415               0 :     for( i = 0; i < p1; i++ )
    1416               0 :         poLS->setPoint( i, p[i*3+1], p[i*3+2] );
    1417                 : 
    1418               0 :     poFeature->SetGeometryDirectly( poLS );
    1419                 : 
    1420               0 :     PrepareLineStyle( poFeature );
    1421                 : 
    1422               0 :     return poFeature;
    1423                 : }
    1424                 : 
    1425                 : /************************************************************************/
    1426                 : /*                      GeometryInsertTransformer                       */
    1427                 : /************************************************************************/
    1428                 : 
    1429                 : class GeometryInsertTransformer : public OGRCoordinateTransformation
    1430               7 : {
    1431                 : public:
    1432               7 :     GeometryInsertTransformer() : 
    1433                 :             dfXOffset(0),dfYOffset(0),dfZOffset(0),
    1434                 :             dfXScale(1.0),dfYScale(1.0),dfZScale(1.0),
    1435               7 :             dfAngle(0.0) {}
    1436                 : 
    1437                 :     double dfXOffset;
    1438                 :     double dfYOffset;
    1439                 :     double dfZOffset;
    1440                 :     double dfXScale;
    1441                 :     double dfYScale;
    1442                 :     double dfZScale;
    1443                 :     double dfAngle;
    1444                 : 
    1445               0 :     OGRSpatialReference *GetSourceCS() { return NULL; }
    1446              34 :     OGRSpatialReference *GetTargetCS() { return NULL; }
    1447               4 :     int Transform( int nCount, 
    1448                 :                    double *x, double *y, double *z )
    1449               4 :         { return TransformEx( nCount, x, y, z, NULL ); }
    1450                 :     
    1451              28 :     int TransformEx( int nCount, 
    1452                 :                      double *x, double *y, double *z = NULL,
    1453                 :                      int *pabSuccess = NULL )
    1454                 :         {
    1455                 :             int i;
    1456              80 :             for( i = 0; i < nCount; i++ )
    1457                 :             {
    1458                 :                 double dfXNew, dfYNew;
    1459                 : 
    1460              52 :                 x[i] *= dfXScale;
    1461              52 :                 y[i] *= dfYScale;
    1462              52 :                 z[i] *= dfZScale;
    1463                 : 
    1464              52 :                 dfXNew = x[i] * cos(dfAngle) - y[i] * sin(dfAngle);
    1465              52 :                 dfYNew = x[i] * sin(dfAngle) + y[i] * cos(dfAngle);
    1466                 : 
    1467              52 :                 x[i] = dfXNew;
    1468              52 :                 y[i] = dfYNew;
    1469                 : 
    1470              52 :                 x[i] += dfXOffset;
    1471              52 :                 y[i] += dfYOffset;
    1472              52 :                 z[i] += dfZOffset;
    1473                 : 
    1474              52 :                 if( pabSuccess )
    1475              48 :                     pabSuccess[i] = TRUE;
    1476                 :             }
    1477              28 :             return TRUE;
    1478                 :         }
    1479                 : };
    1480                 : 
    1481                 : /************************************************************************/
    1482                 : /*                          TranslateINSERT()                           */
    1483                 : /************************************************************************/
    1484                 : 
    1485               7 : OGRFeature *OGRDXFLayer::TranslateINSERT()
    1486                 : 
    1487                 : {
    1488                 :     char szLineBuf[257];
    1489                 :     int nCode;
    1490               7 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
    1491               7 :     GeometryInsertTransformer oTransformer;
    1492               7 :     CPLString osBlockName;
    1493               7 :     double dfAngle = 0.0;
    1494                 : 
    1495                 : /* -------------------------------------------------------------------- */
    1496                 : /*      Process values.                                                 */
    1497                 : /* -------------------------------------------------------------------- */
    1498              85 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
    1499                 :     {
    1500              71 :         switch( nCode )
    1501                 :         {
    1502                 :           case 10:
    1503               7 :             oTransformer.dfXOffset = CPLAtof(szLineBuf);
    1504               7 :             break;
    1505                 : 
    1506                 :           case 20:
    1507               7 :             oTransformer.dfYOffset = CPLAtof(szLineBuf);
    1508               7 :             break;
    1509                 : 
    1510                 :           case 30:
    1511               3 :             oTransformer.dfZOffset = CPLAtof(szLineBuf);
    1512               3 :             break;
    1513                 : 
    1514                 :           case 41:
    1515               1 :             oTransformer.dfXScale = CPLAtof(szLineBuf);
    1516               1 :             break;
    1517                 : 
    1518                 :           case 42:
    1519               1 :             oTransformer.dfYScale = CPLAtof(szLineBuf);
    1520               1 :             break;
    1521                 : 
    1522                 :           case 43:
    1523               1 :             oTransformer.dfZScale = CPLAtof(szLineBuf);
    1524               1 :             break;
    1525                 : 
    1526                 :           case 50:
    1527               1 :             dfAngle = CPLAtof(szLineBuf);
    1528                 :             // We want to transform this to radians. 
    1529                 :             // It is apparently always in degrees regardless of $AUNITS
    1530               1 :             oTransformer.dfAngle = dfAngle * PI / 180.0;
    1531               1 :             break;
    1532                 : 
    1533                 :           case 2: 
    1534               7 :             osBlockName = szLineBuf;
    1535               7 :             break;
    1536                 :             
    1537                 :           default:
    1538              43 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
    1539                 :             break;
    1540                 :         }
    1541                 :     }
    1542                 : 
    1543               7 :     if( nCode == 0 )
    1544               7 :         poDS->UnreadValue();
    1545                 : 
    1546                 : /* -------------------------------------------------------------------- */
    1547                 : /*      In the case where we do not inlined blocks we just capture      */
    1548                 : /*      info on a point feature.                                        */
    1549                 : /* -------------------------------------------------------------------- */
    1550               7 :     if( !poDS->InlineBlocks() )
    1551                 :     {
    1552                 :         poFeature->SetGeometryDirectly(
    1553                 :             new OGRPoint( oTransformer.dfXOffset, 
    1554                 :                           oTransformer.dfYOffset,
    1555               1 :                           oTransformer.dfZOffset ) );
    1556                 : 
    1557               1 :         poFeature->SetField( "BlockName", osBlockName );
    1558                 : 
    1559               1 :         poFeature->SetField( "BlockAngle", dfAngle );
    1560               1 :         poFeature->SetField( "BlockScale", 3, &(oTransformer.dfXScale) );
    1561                 : 
    1562               1 :         return poFeature;
    1563                 :     }
    1564                 : 
    1565                 : /* -------------------------------------------------------------------- */
    1566                 : /*      Lookup the block.                                               */
    1567                 : /* -------------------------------------------------------------------- */
    1568               6 :     DXFBlockDefinition *poBlock = poDS->LookupBlock( osBlockName );
    1569                 :     
    1570               6 :     if( poBlock == NULL )
    1571                 :     {
    1572               0 :         delete poFeature;
    1573               0 :         return NULL;
    1574                 :     }
    1575                 : 
    1576                 : /* -------------------------------------------------------------------- */
    1577                 : /*      Transform the geometry.                                         */
    1578                 : /* -------------------------------------------------------------------- */
    1579               6 :     if( poBlock->poGeometry != NULL )
    1580                 :     {
    1581               6 :         OGRGeometry *poGeometry = poBlock->poGeometry->clone();
    1582                 : 
    1583               6 :         poGeometry->transform( &oTransformer );
    1584                 : 
    1585               6 :         poFeature->SetGeometryDirectly( poGeometry );
    1586                 :     }
    1587                 : 
    1588                 : /* -------------------------------------------------------------------- */
    1589                 : /*      If we have complete features associated with the block, push    */
    1590                 : /*      them on the pending feature stack copying over key override     */
    1591                 : /*      information.                                                    */
    1592                 : /*                                                                      */
    1593                 : /*      Note that while we transform the geometry of the features we    */
    1594                 : /*      don't adjust subtle things like text angle.                     */
    1595                 : /* -------------------------------------------------------------------- */
    1596                 :     unsigned int iSubFeat;
    1597                 : 
    1598              10 :     for( iSubFeat = 0; iSubFeat < poBlock->apoFeatures.size(); iSubFeat++ )
    1599                 :     {
    1600               4 :         OGRFeature *poSubFeature = poBlock->apoFeatures[iSubFeat]->Clone();
    1601               4 :         CPLString osCompEntityId;
    1602                 : 
    1603               4 :         if( poSubFeature->GetGeometryRef() != NULL )
    1604               4 :             poSubFeature->GetGeometryRef()->transform( &oTransformer );
    1605                 : 
    1606               4 :         ACAdjustText( dfAngle, oTransformer.dfXScale, poSubFeature );
    1607                 : 
    1608                 : #ifdef notdef
    1609                 :         osCompEntityId = poSubFeature->GetFieldAsString( "EntityHandle" );
    1610                 :         osCompEntityId += ":";
    1611                 : #endif
    1612               4 :         osCompEntityId += poFeature->GetFieldAsString( "EntityHandle" );
    1613                 : 
    1614               4 :         poSubFeature->SetField( "EntityHandle", osCompEntityId );
    1615                 : 
    1616               4 :         apoPendingFeatures.push( poSubFeature );
    1617                 :     }
    1618                 : 
    1619                 : /* -------------------------------------------------------------------- */
    1620                 : /*      Return the working feature if we had geometry, otherwise        */
    1621                 : /*      return NULL and let the machinery find the rest of the          */
    1622                 : /*      features in the pending feature stack.                          */
    1623                 : /* -------------------------------------------------------------------- */
    1624               6 :     if( poBlock->poGeometry == NULL )
    1625                 :     {
    1626               0 :         delete poFeature;
    1627               0 :         return NULL;
    1628                 :     }
    1629                 :     else
    1630                 :     {
    1631               6 :         return poFeature;
    1632               0 :     }
    1633                 : }
    1634                 : 
    1635                 : /************************************************************************/
    1636                 : /*                      GetNextUnfilteredFeature()                      */
    1637                 : /************************************************************************/
    1638                 : 
    1639             124 : OGRFeature *OGRDXFLayer::GetNextUnfilteredFeature()
    1640                 : 
    1641                 : {
    1642             124 :     OGRFeature *poFeature = NULL;
    1643                 : 
    1644                 : /* -------------------------------------------------------------------- */
    1645                 : /*      If we have pending features, return one of them.                */
    1646                 : /* -------------------------------------------------------------------- */
    1647             124 :     if( !apoPendingFeatures.empty() )
    1648                 :     {
    1649              13 :         poFeature = apoPendingFeatures.front();
    1650              13 :         apoPendingFeatures.pop();
    1651                 : 
    1652              13 :         poFeature->SetFID( iNextFID++ );
    1653              13 :         return poFeature;
    1654                 :     }
    1655                 : 
    1656                 : /* -------------------------------------------------------------------- */
    1657                 : /*      Read the entity type.                                           */
    1658                 : /* -------------------------------------------------------------------- */
    1659                 :     char szLineBuf[257];
    1660                 :     int nCode;
    1661                 : 
    1662             322 :     while( poFeature == NULL )
    1663                 :     {
    1664                 :         // read ahead to an entity.
    1665             111 :         while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 ) {}
    1666                 : 
    1667             111 :         if( nCode == -1 )
    1668                 :         {
    1669               0 :             CPLDebug( "DXF", "Unexpected end of data without ENDSEC." );
    1670               0 :             return NULL;
    1671                 :         }
    1672                 :         
    1673             111 :         if( EQUAL(szLineBuf,"ENDSEC") )
    1674                 :         {
    1675                 :             //CPLDebug( "DXF", "Clean end of features at ENDSEC." );
    1676               1 :             poDS->UnreadValue();
    1677               1 :             return NULL;
    1678                 :         }
    1679                 : 
    1680             110 :         if( EQUAL(szLineBuf,"ENDBLK") )
    1681                 :         {
    1682                 :             //CPLDebug( "DXF", "Clean end of block at ENDBLK." );
    1683              10 :             poDS->UnreadValue();
    1684              10 :             return NULL;
    1685                 :         }
    1686                 : 
    1687                 : /* -------------------------------------------------------------------- */
    1688                 : /*      Handle the entity.                                              */
    1689                 : /* -------------------------------------------------------------------- */
    1690             100 :         oStyleProperties.clear();
    1691                 : 
    1692             100 :         if( EQUAL(szLineBuf,"POINT") )
    1693                 :         {
    1694               6 :             poFeature = TranslatePOINT();
    1695                 :         }
    1696              94 :         else if( EQUAL(szLineBuf,"MTEXT") )
    1697                 :         {
    1698               7 :             poFeature = TranslateMTEXT();
    1699                 :         }
    1700              87 :         else if( EQUAL(szLineBuf,"TEXT") 
    1701                 :                  || EQUAL(szLineBuf,"ATTDEF") )
    1702                 :         {
    1703               0 :             poFeature = TranslateTEXT();
    1704                 :         }
    1705              87 :         else if( EQUAL(szLineBuf,"LINE") )
    1706                 :         {
    1707              49 :             poFeature = TranslateLINE();
    1708                 :         }
    1709              38 :         else if( EQUAL(szLineBuf,"POLYLINE") )
    1710                 :         {
    1711               1 :             poFeature = TranslatePOLYLINE();
    1712                 :         }
    1713              37 :         else if( EQUAL(szLineBuf,"LWPOLYLINE") )
    1714                 :         {
    1715              10 :             poFeature = TranslateLWPOLYLINE();
    1716                 :         }
    1717              27 :         else if( EQUAL(szLineBuf,"CIRCLE") )
    1718                 :         {
    1719               0 :             poFeature = TranslateCIRCLE();
    1720                 :         }
    1721              27 :         else if( EQUAL(szLineBuf,"ELLIPSE") )
    1722                 :         {
    1723               6 :             poFeature = TranslateELLIPSE();
    1724                 :         }
    1725              21 :         else if( EQUAL(szLineBuf,"ARC") )
    1726                 :         {
    1727               3 :             poFeature = TranslateARC();
    1728                 :         }
    1729              18 :         else if( EQUAL(szLineBuf,"SPLINE") )
    1730                 :         {
    1731               0 :             poFeature = TranslateSPLINE();
    1732                 :         }
    1733              18 :         else if( EQUAL(szLineBuf,"INSERT") )
    1734                 :         {
    1735               7 :             poFeature = TranslateINSERT();
    1736                 :         }
    1737              11 :         else if( EQUAL(szLineBuf,"DIMENSION") )
    1738                 :         {
    1739               9 :             poFeature = TranslateDIMENSION();
    1740                 :         }
    1741               2 :         else if( EQUAL(szLineBuf,"HATCH") )
    1742                 :         {
    1743               2 :             poFeature = TranslateHATCH();
    1744                 :         }
    1745                 :         else
    1746                 :         {
    1747               0 :             if( oIgnoredEntities.count(szLineBuf) == 0 )
    1748                 :             {
    1749               0 :                 oIgnoredEntities.insert( szLineBuf );
    1750                 :                 CPLDebug( "DWG", "Ignoring one or more of entity '%s'.", 
    1751               0 :                           szLineBuf );
    1752                 :             }
    1753                 :         }
    1754                 :     }
    1755                 : 
    1756                 : /* -------------------------------------------------------------------- */
    1757                 : /*      Set FID.                                                        */
    1758                 : /* -------------------------------------------------------------------- */
    1759             100 :     poFeature->SetFID( iNextFID++ );
    1760             100 :     m_nFeaturesRead++;
    1761                 : 
    1762             100 :     return poFeature;
    1763                 : }
    1764                 : 
    1765                 : /************************************************************************/
    1766                 : /*                           GetNextFeature()                           */
    1767                 : /************************************************************************/
    1768                 : 
    1769              65 : OGRFeature *OGRDXFLayer::GetNextFeature()
    1770                 : 
    1771                 : {
    1772               0 :     while( TRUE )
    1773                 :     {
    1774              65 :         OGRFeature *poFeature = GetNextUnfilteredFeature();
    1775                 : 
    1776              65 :         if( poFeature == NULL )
    1777               1 :             return NULL;
    1778                 : 
    1779              64 :         if( (m_poFilterGeom == NULL
    1780                 :              || FilterGeometry( poFeature->GetGeometryRef() ) )
    1781                 :             && (m_poAttrQuery == NULL
    1782                 :                 || m_poAttrQuery->Evaluate( poFeature ) ) )
    1783                 :         {
    1784              64 :             return poFeature;
    1785                 :         }
    1786                 : 
    1787               0 :         delete poFeature;
    1788                 :     }
    1789                 : }
    1790                 : 
    1791                 : /************************************************************************/
    1792                 : /*                           TestCapability()                           */
    1793                 : /************************************************************************/
    1794                 : 
    1795               0 : int OGRDXFLayer::TestCapability( const char * pszCap )
    1796                 : 
    1797                 : {
    1798               0 :     if( EQUAL(pszCap,OLCStringsAsUTF8) )
    1799               0 :         return TRUE;
    1800                 :     else
    1801               0 :         return FALSE;
    1802                 : }
    1803                 : 

Generated by: LCOV version 1.7