LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/dxf - ogrdxflayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 722 521 72.2 %
Date: 2012-04-28 Functions: 41 29 70.7 %

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

Generated by: LCOV version 1.7