LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/dxf - ogrdxflayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 742 600 80.9 %
Date: 2012-12-26 Functions: 41 31 75.6 %

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

Generated by: LCOV version 1.7