LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/dxf - ogrdxflayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 521 274 52.6 %
Date: 2010-01-09 Functions: 28 14 50.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrdxflayer.cpp 18409 2009-12-29 01:10:00Z warmerdam $
       3                 :  *
       4                 :  * Project:  DXF Translator
       5                 :  * Purpose:  Implements OGRDXFLayer class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2009, Frank Warmerdam <warmerdam@pobox.com>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_dxf.h"
      31                 : #include "cpl_conv.h"
      32                 : 
      33                 : CPL_CVSID("$Id: ogrdxflayer.cpp 18409 2009-12-29 01:10:00Z warmerdam $");
      34                 : 
      35                 : #ifndef PI
      36                 : #define PI  3.14159265358979323846
      37                 : #endif 
      38                 : 
      39                 : /************************************************************************/
      40                 : /*                            OGRDXFLayer()                             */
      41                 : /************************************************************************/
      42                 : 
      43               1 : OGRDXFLayer::OGRDXFLayer( OGRDXFDataSource *poDS )
      44                 : 
      45                 : {
      46               1 :     this->poDS = poDS;
      47                 : 
      48               1 :     iNextFID = 0;
      49                 : 
      50               1 :     poFeatureDefn = new OGRFeatureDefn( "entities" );
      51               1 :     poFeatureDefn->Reference();
      52                 : 
      53               1 :     OGRFieldDefn  oLayerField( "Layer", OFTString );
      54               1 :     poFeatureDefn->AddFieldDefn( &oLayerField );
      55                 : 
      56               1 :     OGRFieldDefn  oClassField( "SubClasses", OFTString );
      57               1 :     poFeatureDefn->AddFieldDefn( &oClassField );
      58                 : 
      59               1 :     OGRFieldDefn  oExtendedField( "ExtendedEntity", OFTString );
      60               1 :     poFeatureDefn->AddFieldDefn( &oExtendedField );
      61                 : 
      62               1 :     OGRFieldDefn  oLinetypeField( "Linetype", OFTString );
      63               1 :     poFeatureDefn->AddFieldDefn( &oLinetypeField );
      64                 : 
      65               1 :     OGRFieldDefn  oEntityHandleField( "EntityHandle", OFTString );
      66               1 :     poFeatureDefn->AddFieldDefn( &oEntityHandleField );
      67                 : 
      68               1 :     OGRFieldDefn  oTextField( "Text", OFTString );
      69               1 :     poFeatureDefn->AddFieldDefn( &oTextField );
      70               1 : }
      71                 : 
      72                 : /************************************************************************/
      73                 : /*                           ~OGRDXFLayer()                           */
      74                 : /************************************************************************/
      75                 : 
      76               2 : OGRDXFLayer::~OGRDXFLayer()
      77                 : 
      78                 : {
      79               1 :     ClearPendingFeatures();
      80               1 :     if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
      81                 :     {
      82                 :         CPLDebug( "DXF", "%d features read on layer '%s'.",
      83                 :                   (int) m_nFeaturesRead, 
      84               1 :                   poFeatureDefn->GetName() );
      85                 :     }
      86                 : 
      87               1 :     if( poFeatureDefn )
      88               1 :         poFeatureDefn->Release();
      89               2 : }
      90                 : 
      91                 : /************************************************************************/
      92                 : /*                        ClearPendingFeatures()                        */
      93                 : /************************************************************************/
      94                 : 
      95               5 : void OGRDXFLayer::ClearPendingFeatures()
      96                 : 
      97                 : {
      98              10 :     while( !apoPendingFeatures.empty() )
      99                 :     {
     100               0 :         delete apoPendingFeatures.top();
     101               0 :         apoPendingFeatures.pop();
     102                 :     }
     103               5 : }
     104                 : 
     105                 : /************************************************************************/
     106                 : /*                            ResetReading()                            */
     107                 : /************************************************************************/
     108                 : 
     109               4 : void OGRDXFLayer::ResetReading()
     110                 : 
     111                 : {
     112               4 :     iNextFID = 0;
     113               4 :     ClearPendingFeatures();
     114               4 :     poDS->RestartEntities();
     115               4 : }
     116                 : 
     117                 : /************************************************************************/
     118                 : /*                      TranslateGenericProperty()                      */
     119                 : /*                                                                      */
     120                 : /*      Try and convert entity properties handled similarly for most    */
     121                 : /*      or all entity types.                                            */
     122                 : /************************************************************************/
     123                 : 
     124             166 : void OGRDXFLayer::TranslateGenericProperty( OGRFeature *poFeature, 
     125                 :                                             int nCode, char *pszValue )
     126                 : 
     127                 : {
     128             166 :     switch( nCode )
     129                 :     {
     130                 :       case 8: 
     131              18 :         poFeature->SetField( "Layer", pszValue );
     132              18 :         break;
     133                 :             
     134                 :       case 100: 
     135                 :       {
     136              44 :           CPLString osSubClass = poFeature->GetFieldAsString("SubClasses");
     137              44 :           if( osSubClass.size() > 0 )
     138              26 :               osSubClass += ":";
     139              44 :           osSubClass += pszValue;
     140              44 :           poFeature->SetField( "SubClasses", osSubClass.c_str() );
     141                 :       }
     142              44 :       break;
     143                 : 
     144                 :       case 62:
     145              18 :         oStyleProperties["Color"] = pszValue;
     146              18 :         break;
     147                 : 
     148                 :       case 6:
     149              18 :         poFeature->SetField( "Linetype", pszValue );
     150              18 :         break;
     151                 : 
     152                 :       case 370:
     153                 :       case 39:
     154              18 :         oStyleProperties["LineWeight"] = pszValue;
     155              18 :         break;
     156                 : 
     157                 :       case 5:
     158              18 :         poFeature->SetField( "EntityHandle", pszValue );
     159              18 :         break;
     160                 : 
     161                 :         // Extended entity data
     162                 :       case 1000:
     163                 :       case 1002:
     164                 :       case 1004:
     165                 :       case 1005:
     166                 :       case 1040:
     167                 :       case 1041:
     168                 :       case 1070:
     169                 :       case 1071:
     170                 :       {
     171               0 :           CPLString osAggregate = poFeature->GetFieldAsString("ExtendedEntity");
     172                 : 
     173               0 :           if( osAggregate.size() > 0 )
     174               0 :               osAggregate += " ";
     175               0 :           osAggregate += pszValue;
     176                 :             
     177               0 :           poFeature->SetField( "ExtendedEntity", osAggregate );
     178                 :       }
     179                 :       break;
     180                 : 
     181                 :       default:
     182                 :         break;
     183                 :     }
     184             166 : }
     185                 : 
     186                 : /************************************************************************/
     187                 : /*                          PrepareLineStyle()                          */
     188                 : /*                                                                      */
     189                 : /*      For now I don't bother trying to translate the dash/dot         */
     190                 : /*      linetype into the style string since I'm not aware of any       */
     191                 : /*      application that will honour it anyways.                        */
     192                 : /************************************************************************/
     193                 : 
     194              14 : void OGRDXFLayer::PrepareLineStyle( OGRFeature *poFeature )
     195                 : 
     196                 : {
     197              14 :     CPLString osLayer = poFeature->GetFieldAsString("Layer");
     198                 : 
     199                 : /* -------------------------------------------------------------------- */
     200                 : /*      Work out the color for this feature.                            */
     201                 : /* -------------------------------------------------------------------- */
     202              14 :     int nColor = 256;
     203                 : 
     204              14 :     if( oStyleProperties.count("Color") > 0 )
     205              14 :         nColor = atoi(oStyleProperties["Color"]);
     206                 : 
     207                 :     // Use layer color? 
     208              14 :     if( nColor < 1 || nColor > 255 )
     209                 :     {
     210              14 :         const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" );
     211              14 :         if( pszValue != NULL )
     212              14 :             nColor = atoi(pszValue);
     213                 :     }
     214                 :         
     215              14 :     if( nColor < 1 || nColor > 255 )
     216                 :         return;
     217                 : 
     218                 : /* -------------------------------------------------------------------- */
     219                 : /*      Get line weight if available.                                   */
     220                 : /* -------------------------------------------------------------------- */
     221              14 :     double dfWeight = 0.0;
     222                 : 
     223              14 :     if( oStyleProperties.count("LineWeight") > 0 )
     224                 :     {
     225              14 :         CPLString osWeight = oStyleProperties["LineWeight"];
     226                 : 
     227              14 :         if( osWeight == "-1" )
     228              14 :             osWeight = poDS->LookupLayerProperty(osLayer,"LineWeight");
     229                 : 
     230              14 :         dfWeight = atof(osWeight) / 100.0;
     231                 :     }
     232                 : 
     233                 : /* -------------------------------------------------------------------- */
     234                 : /*      Format the style string.                                        */
     235                 : /* -------------------------------------------------------------------- */
     236              14 :     CPLString osStyle;
     237              14 :     const unsigned char *pabyDXFColors = OGRDXFDriver::GetDXFColorTable();
     238                 : 
     239                 :     osStyle.Printf( "PEN(c:#%02x%02x%02x", 
     240              14 :                     pabyDXFColors[nColor*3+0],
     241              14 :                     pabyDXFColors[nColor*3+1],
     242              42 :                     pabyDXFColors[nColor*3+2] );
     243                 : 
     244              14 :     if( dfWeight > 0.0 )
     245               0 :         osStyle += CPLString().Printf( ",w:%.2gmm", dfWeight );
     246                 : 
     247              14 :     osStyle += ")";
     248                 :     
     249              14 :     poFeature->SetStyleString( osStyle );
     250                 : }
     251                 : 
     252                 : /************************************************************************/
     253                 : /*                           TranslateMTEXT()                           */
     254                 : /************************************************************************/
     255                 : 
     256               2 : OGRFeature *OGRDXFLayer::TranslateMTEXT()
     257                 : 
     258                 : {
     259                 :     char szLineBuf[257];
     260                 :     int nCode;
     261               2 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     262               2 :     double dfX = 0.0, dfY = 0.0, dfZ = 0.0;
     263               2 :     double dfAngle = 0.0;
     264               2 :     double dfHeight = 0.0;
     265               2 :     int nAttachmentPoint = -1;
     266               2 :     CPLString osText;
     267                 : 
     268              42 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     269                 :     {
     270              38 :         switch( nCode )
     271                 :         {
     272                 :           case 10:
     273               2 :             dfX = atof(szLineBuf);
     274               2 :             break;
     275                 : 
     276                 :           case 20:
     277               2 :             dfY = atof(szLineBuf);
     278               2 :             break;
     279                 : 
     280                 :           case 30:
     281               2 :             dfZ = atof(szLineBuf);
     282               2 :             break;
     283                 : 
     284                 :           case 40:
     285               2 :             dfHeight = atof(szLineBuf);
     286               2 :             break;
     287                 : 
     288                 :           case 71:
     289               2 :             nAttachmentPoint = atoi(szLineBuf);
     290               2 :             break;
     291                 : 
     292                 :           case 1:
     293                 :           case 3:
     294               2 :             osText += szLineBuf;
     295               2 :             break;
     296                 : 
     297                 :           case 50:
     298               2 :             dfAngle = atof(szLineBuf);
     299               2 :             break;
     300                 : 
     301                 :           default:
     302              24 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     303                 :             break;
     304                 :         }
     305                 :     }
     306                 : 
     307               2 :     if( nCode == 0 )
     308               2 :         poDS->UnreadValue();
     309                 : 
     310               2 :     poFeature->SetField( "Text", osText );
     311               2 :     poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY, dfZ ) );
     312                 : 
     313                 : /* -------------------------------------------------------------------- */
     314                 : /*      Work out the color for this feature.                            */
     315                 : /* -------------------------------------------------------------------- */
     316               2 :     int nColor = 256;
     317                 : 
     318               2 :     if( oStyleProperties.count("Color") > 0 )
     319               2 :         nColor = atoi(oStyleProperties["Color"]);
     320                 : 
     321                 :     // Use layer color? 
     322               2 :     if( nColor < 1 || nColor > 255 )
     323                 :     {
     324               2 :         CPLString osLayer = poFeature->GetFieldAsString("Layer");
     325               2 :         const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" );
     326               2 :         if( pszValue != NULL )
     327               2 :             nColor = atoi(pszValue);
     328                 :     }
     329                 :         
     330                 : /* -------------------------------------------------------------------- */
     331                 : /*      Prepare style string.                                           */
     332                 : /* -------------------------------------------------------------------- */
     333               2 :     CPLString osStyle;
     334                 : 
     335               2 :     osStyle.Printf("LABEL(f:\"Arial\",t:\"%s\"",osText.c_str());
     336                 : 
     337               2 :     if( dfAngle != 0.0 )
     338               2 :         osStyle += CPLString().Printf(",a:%.3g", dfAngle);
     339                 : 
     340               2 :     if( dfHeight != 0.0 )
     341               2 :         osStyle += CPLString().Printf(",s:%.3gg", dfHeight);
     342                 : 
     343               2 :     if( nAttachmentPoint >= 0 && nAttachmentPoint <= 9 )
     344                 :     {
     345                 :         const static int anAttachmentMap[10] = 
     346                 :             { -1, 7, 8, 9, 4, 5, 6, 1, 2, 3 };
     347                 :         
     348                 :         osStyle += 
     349               2 :             CPLString().Printf(",p:%d", anAttachmentMap[nAttachmentPoint]);
     350                 :     }
     351                 : 
     352               2 :     if( nColor > 0 && nColor < 256 )
     353                 :     {
     354               2 :         const unsigned char *pabyDXFColors = OGRDXFDriver::GetDXFColorTable();
     355                 :         osStyle += 
     356                 :             CPLString().Printf( ",c:#%02x%02x%02x", 
     357               2 :                                 pabyDXFColors[nColor*3+0],
     358               2 :                                 pabyDXFColors[nColor*3+1],
     359               6 :                                 pabyDXFColors[nColor*3+2] );
     360                 :     }
     361                 : 
     362               2 :     osStyle += ")";
     363                 : 
     364               2 :     poFeature->SetStyleString( osStyle );
     365                 : 
     366               2 :     return poFeature;
     367                 : }
     368                 : 
     369                 : /************************************************************************/
     370                 : /*                           TranslateTEXT()                            */
     371                 : /************************************************************************/
     372                 : 
     373               0 : OGRFeature *OGRDXFLayer::TranslateTEXT()
     374                 : 
     375                 : {
     376                 :     char szLineBuf[257];
     377                 :     int nCode;
     378               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     379               0 :     double dfX = 0.0, dfY = 0.0, dfZ = 0.0;
     380               0 :     double dfAngle = 0.0;
     381               0 :     double dfHeight = 0.0;
     382               0 :     CPLString osText;
     383                 : 
     384               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     385                 :     {
     386               0 :         switch( nCode )
     387                 :         {
     388                 :           case 10:
     389               0 :             dfX = atof(szLineBuf);
     390               0 :             break;
     391                 : 
     392                 :           case 20:
     393               0 :             dfY = atof(szLineBuf);
     394               0 :             break;
     395                 : 
     396                 :           case 30:
     397               0 :             dfZ = atof(szLineBuf);
     398               0 :             break;
     399                 : 
     400                 :           case 40:
     401               0 :             dfHeight = atof(szLineBuf);
     402               0 :             break;
     403                 : 
     404                 :           case 1:
     405                 :           case 3:
     406               0 :             osText += szLineBuf;
     407               0 :             break;
     408                 : 
     409                 :           case 50:
     410               0 :             dfAngle = atof(szLineBuf);
     411               0 :             break;
     412                 : 
     413                 :           default:
     414               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     415                 :             break;
     416                 :         }
     417                 :     }
     418                 : 
     419               0 :     if( nCode == 0 )
     420               0 :         poDS->UnreadValue();
     421                 : 
     422               0 :     poFeature->SetField( "Text", osText );
     423               0 :     poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY, dfZ ) );
     424                 : 
     425                 : /* -------------------------------------------------------------------- */
     426                 : /*      Prepare style string.                                           */
     427                 : /* -------------------------------------------------------------------- */
     428               0 :     CPLString osStyle;
     429                 : 
     430               0 :     osStyle.Printf("LABEL(f:\"Arial\",t:\"%s\"",osText.c_str());
     431                 : 
     432               0 :     if( dfAngle != 0.0 )
     433               0 :         osStyle += CPLString().Printf(",a:%.3g", dfAngle);
     434                 : 
     435               0 :     if( dfHeight != 0.0 )
     436               0 :         osStyle += CPLString().Printf(",s:%.3gg", dfHeight);
     437                 : 
     438                 :     // add color!
     439                 : 
     440               0 :     osStyle += ")";
     441                 : 
     442               0 :     poFeature->SetStyleString( osStyle );
     443                 : 
     444               0 :     return poFeature;
     445                 : }
     446                 : 
     447                 : /************************************************************************/
     448                 : /*                           TranslatePOINT()                           */
     449                 : /************************************************************************/
     450                 : 
     451               2 : OGRFeature *OGRDXFLayer::TranslatePOINT()
     452                 : 
     453                 : {
     454                 :     char szLineBuf[257];
     455                 :     int nCode;
     456               2 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     457               2 :     double dfX = 0.0, dfY = 0.0, dfZ = 0.0;
     458                 : 
     459              24 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     460                 :     {
     461              20 :         switch( nCode )
     462                 :         {
     463                 :           case 10:
     464               2 :             dfX = atof(szLineBuf);
     465               2 :             break;
     466                 : 
     467                 :           case 20:
     468               2 :             dfY = atof(szLineBuf);
     469               2 :             break;
     470                 : 
     471                 :           case 30:
     472               2 :             dfZ = atof(szLineBuf);
     473               2 :             break;
     474                 : 
     475                 :           default:
     476              14 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     477                 :             break;
     478                 :         }
     479                 :     }
     480                 : 
     481               2 :     poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY, dfZ ) );
     482                 : 
     483               2 :     if( nCode == 0 )
     484               2 :         poDS->UnreadValue();
     485                 : 
     486               2 :     return poFeature;
     487                 : }
     488                 : 
     489                 : /************************************************************************/
     490                 : /*                           TranslateLINE()                            */
     491                 : /************************************************************************/
     492                 : 
     493               4 : OGRFeature *OGRDXFLayer::TranslateLINE()
     494                 : 
     495                 : {
     496                 :     char szLineBuf[257];
     497                 :     int nCode;
     498               4 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     499               4 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0;
     500               4 :     double dfX2 = 0.0, dfY2 = 0.0, dfZ2 = 0.0;
     501                 : 
     502                 : /* -------------------------------------------------------------------- */
     503                 : /*      Process values.                                                 */
     504                 : /* -------------------------------------------------------------------- */
     505              60 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     506                 :     {
     507              52 :         switch( nCode )
     508                 :         {
     509                 :           case 10:
     510               4 :             dfX1 = atof(szLineBuf);
     511               4 :             break;
     512                 : 
     513                 :           case 11:
     514               4 :             dfX2 = atof(szLineBuf);
     515               4 :             break;
     516                 : 
     517                 :           case 20:
     518               4 :             dfY1 = atof(szLineBuf);
     519               4 :             break;
     520                 : 
     521                 :           case 21:
     522               4 :             dfY2 = atof(szLineBuf);
     523               4 :             break;
     524                 : 
     525                 :           case 30:
     526               4 :             dfZ1 = atof(szLineBuf);
     527               4 :             break;
     528                 : 
     529                 :           case 31:
     530               4 :             dfZ2 = atof(szLineBuf);
     531               4 :             break;
     532                 : 
     533                 :           default:
     534              28 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     535                 :             break;
     536                 :         }
     537                 :     }
     538                 : 
     539               4 :     if( nCode == 0 )
     540               4 :         poDS->UnreadValue();
     541                 : 
     542                 : /* -------------------------------------------------------------------- */
     543                 : /*      Create geometry                                                 */
     544                 : /* -------------------------------------------------------------------- */
     545               4 :     OGRLineString *poLS = new OGRLineString();
     546               4 :     poLS->addPoint( dfX1, dfY1, dfZ1 );
     547               4 :     poLS->addPoint( dfX2, dfY2, dfZ2 );
     548                 : 
     549               4 :     poFeature->SetGeometryDirectly( poLS );
     550                 : 
     551               4 :     PrepareLineStyle( poFeature );
     552                 : 
     553               4 :     return poFeature;
     554                 : }
     555                 : 
     556                 : /************************************************************************/
     557                 : /*                         TranslateLWPOLYLINE()                        */
     558                 : /************************************************************************/
     559                 : 
     560               0 : OGRFeature *OGRDXFLayer::TranslateLWPOLYLINE()
     561                 : 
     562                 : {
     563                 :     char szLineBuf[257];
     564                 :     int nCode;
     565               0 :     int nPolylineFlag = 0;
     566               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     567               0 :     OGRLineString *poLS = new OGRLineString();
     568               0 :     double dfX = 0.0, dfY = 0.0, dfZ = 0.0;
     569               0 :     int    bHaveX = FALSE, bHaveY = FALSE;
     570                 : 
     571                 : /* -------------------------------------------------------------------- */
     572                 : /*      Collect information from the LWPOLYLINE object itself.          */
     573                 : /* -------------------------------------------------------------------- */
     574               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     575                 :     {
     576               0 :         switch( nCode )
     577                 :         {
     578                 :           case 70:
     579               0 :             nPolylineFlag = atoi(szLineBuf);
     580               0 :             break;
     581                 : 
     582                 :           case 10:
     583               0 :             if( bHaveX && bHaveY )
     584                 :             {
     585               0 :                 poLS->addPoint( dfX, dfY, dfZ );
     586               0 :                 bHaveY = FALSE;
     587                 :             }
     588               0 :             dfX = atof(szLineBuf);
     589               0 :             bHaveX = TRUE;
     590               0 :             break;
     591                 : 
     592                 :           case 20:
     593               0 :             if( bHaveX && bHaveY )
     594                 :             {
     595               0 :                 poLS->addPoint( dfX, dfY, dfZ );
     596               0 :                 bHaveX = FALSE;
     597                 :             }
     598               0 :             dfY = atof(szLineBuf);
     599               0 :             bHaveY = TRUE;
     600               0 :             break;
     601                 : 
     602                 :           case 30:
     603               0 :             dfZ = atof(szLineBuf);
     604               0 :             break;
     605                 : 
     606                 :           default:
     607               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     608                 :             break;
     609                 :         }
     610                 :     }
     611                 : 
     612               0 :     poDS->UnreadValue();
     613                 : 
     614               0 :     if( bHaveX && bHaveY )
     615               0 :         poLS->addPoint( dfX, dfY, dfZ );
     616                 : 
     617                 : /* -------------------------------------------------------------------- */
     618                 : /*      Close polyline as polygon if necessary.                         */
     619                 : /* -------------------------------------------------------------------- */
     620               0 :     if( (nPolylineFlag & 0x01)
     621                 :         && poLS->getNumPoints() > 0 
     622                 :         && (poLS->getX(poLS->getNumPoints()-1) != poLS->getX(0)
     623                 :             || poLS->getY(poLS->getNumPoints()-1) != poLS->getY(0)) )
     624                 :     {
     625               0 :         poLS->addPoint( poLS->getX(0), poLS->getY(0), poLS->getZ(0) );
     626                 :     }
     627                 : 
     628               0 :     poFeature->SetGeometryDirectly( poLS );
     629                 : 
     630               0 :     PrepareLineStyle( poFeature );
     631                 : 
     632               0 :     return poFeature;
     633                 : }
     634                 : 
     635                 : /************************************************************************/
     636                 : /*                         TranslatePOLYLINE()                          */
     637                 : /*                                                                      */
     638                 : /*      We also capture the following VERTEXes.                         */
     639                 : /************************************************************************/
     640                 : 
     641               0 : OGRFeature *OGRDXFLayer::TranslatePOLYLINE()
     642                 : 
     643                 : {
     644                 :     char szLineBuf[257];
     645                 :     int nCode;
     646               0 :     int nPolylineFlag = 0;
     647               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     648                 : 
     649                 : /* -------------------------------------------------------------------- */
     650                 : /*      Collect information from the POLYLINE object itself.            */
     651                 : /* -------------------------------------------------------------------- */
     652               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     653                 :     {
     654               0 :         switch( nCode )
     655                 :         {
     656                 :           case 70:
     657               0 :             nPolylineFlag = atoi(szLineBuf);
     658               0 :             break;
     659                 : 
     660                 :           default:
     661               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     662                 :             break;
     663                 :         }
     664                 :     }
     665                 : 
     666                 : /* -------------------------------------------------------------------- */
     667                 : /*      Collect VERTEXes as a linestring.                               */
     668                 : /* -------------------------------------------------------------------- */
     669               0 :     OGRLineString *poLS = new OGRLineString();
     670               0 :     double dfX = 0.0, dfY = 0.0, dfZ = 0.0;
     671                 : 
     672               0 :     while( nCode == 0 && !EQUAL(szLineBuf,"SEQEND") )
     673                 :     {
     674                 :         // Eat non-vertex objects.
     675               0 :         if( !EQUAL(szLineBuf,"VERTEX") )
     676                 :         {
     677               0 :             while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf)))>0 ) {}
     678               0 :             continue;
     679                 :         }
     680                 : 
     681                 :         // process a Vertex
     682               0 :         while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     683                 :         {
     684               0 :             switch( nCode )
     685                 :             {
     686                 :               case 10:
     687               0 :                 dfX = atof(szLineBuf);
     688               0 :                 break;
     689                 :                 
     690                 :               case 20:
     691               0 :                 dfY = atof(szLineBuf);
     692               0 :                 break;
     693                 :                 
     694                 :               case 30:
     695               0 :                 dfZ = atof(szLineBuf);
     696                 :                 break;
     697                 : 
     698                 :               default:
     699                 :                 break;
     700                 :             }
     701                 :         }
     702                 : 
     703               0 :         poLS->addPoint( dfX, dfY, dfZ );
     704                 :     }
     705                 : 
     706                 : /* -------------------------------------------------------------------- */
     707                 : /*      Close polyline as polygon if necessary.                         */
     708                 : /* -------------------------------------------------------------------- */
     709               0 :     if( (nPolylineFlag & 0x01)
     710                 :         && poLS->getNumPoints() > 0 
     711                 :         && (poLS->getX(poLS->getNumPoints()-1) != poLS->getX(0)
     712                 :             || poLS->getY(poLS->getNumPoints()-1) != poLS->getY(0)) )
     713                 :     {
     714               0 :         poLS->addPoint( poLS->getX(0), poLS->getY(0), poLS->getZ(0) );
     715                 :     }
     716                 : 
     717               0 :     poFeature->SetGeometryDirectly( poLS );
     718                 : 
     719               0 :     PrepareLineStyle( poFeature );
     720                 : 
     721               0 :     return poFeature;
     722                 : }
     723                 : 
     724                 : /************************************************************************/
     725                 : /*                          TranslateCIRCLE()                           */
     726                 : /************************************************************************/
     727                 : 
     728               0 : OGRFeature *OGRDXFLayer::TranslateCIRCLE()
     729                 : 
     730                 : {
     731                 :     char szLineBuf[257];
     732                 :     int nCode;
     733               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     734               0 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0, dfRadius = 0.0;
     735                 : 
     736                 : /* -------------------------------------------------------------------- */
     737                 : /*      Process values.                                                 */
     738                 : /* -------------------------------------------------------------------- */
     739               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     740                 :     {
     741               0 :         switch( nCode )
     742                 :         {
     743                 :           case 10:
     744               0 :             dfX1 = atof(szLineBuf);
     745               0 :             break;
     746                 : 
     747                 :           case 20:
     748               0 :             dfY1 = atof(szLineBuf);
     749               0 :             break;
     750                 : 
     751                 :           case 30:
     752               0 :             dfZ1 = atof(szLineBuf);
     753               0 :             break;
     754                 : 
     755                 :           case 40:
     756               0 :             dfRadius = atof(szLineBuf);
     757               0 :             break;
     758                 : 
     759                 :           default:
     760               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     761                 :             break;
     762                 :         }
     763                 :     }
     764                 : 
     765               0 :     if( nCode == 0 )
     766               0 :         poDS->UnreadValue();
     767                 : 
     768                 : /* -------------------------------------------------------------------- */
     769                 : /*      Create geometry                                                 */
     770                 : /* -------------------------------------------------------------------- */
     771                 :     poFeature->SetGeometryDirectly( 
     772                 :         OGRGeometryFactory::approximateArcAngles( dfX1, dfY1, dfZ1, 
     773                 :                                                   dfRadius, dfRadius, 0.0,
     774                 :                                                   0.0, 360.0, 
     775               0 :                                                   0.0 ) );
     776                 : 
     777               0 :     PrepareLineStyle( poFeature );
     778                 : 
     779               0 :     return poFeature;
     780                 : }
     781                 : 
     782                 : /************************************************************************/
     783                 : /*                          TranslateELLIPSE()                          */
     784                 : /************************************************************************/
     785                 : 
     786               4 : OGRFeature *OGRDXFLayer::TranslateELLIPSE()
     787                 : 
     788                 : {
     789                 :     char szLineBuf[257];
     790                 :     int nCode;
     791               4 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     792               4 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0, dfRatio = 0.0;
     793               4 :     double dfStartAngle = 0.0, dfEndAngle = 360.0;
     794               4 :     double dfAxisX=0.0, dfAxisY=0.0, dfAxisZ=0.0;
     795                 : 
     796                 : /* -------------------------------------------------------------------- */
     797                 : /*      Process values.                                                 */
     798                 : /* -------------------------------------------------------------------- */
     799              72 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     800                 :     {
     801              64 :         switch( nCode )
     802                 :         {
     803                 :           case 10:
     804               4 :             dfX1 = atof(szLineBuf);
     805               4 :             break;
     806                 : 
     807                 :           case 20:
     808               4 :             dfY1 = atof(szLineBuf);
     809               4 :             break;
     810                 : 
     811                 :           case 30:
     812               4 :             dfZ1 = atof(szLineBuf);
     813               4 :             break;
     814                 : 
     815                 :           case 11:
     816               4 :             dfAxisX = atof(szLineBuf);
     817               4 :             break;
     818                 : 
     819                 :           case 21:
     820               4 :             dfAxisY = atof(szLineBuf);
     821               4 :             break;
     822                 : 
     823                 :           case 31:
     824               4 :             dfAxisZ = atof(szLineBuf);
     825               4 :             break;
     826                 : 
     827                 :           case 40:
     828               4 :             dfRatio = atof(szLineBuf);
     829               4 :             break;
     830                 : 
     831                 :           case 41:
     832               4 :             dfEndAngle = -1 * atof(szLineBuf) * 180.0 / PI;
     833               4 :             break;
     834                 : 
     835                 :           case 42:
     836               4 :             dfStartAngle = -1 * atof(szLineBuf) * 180.0 / PI;
     837               4 :             break;
     838                 : 
     839                 :           default:
     840              28 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     841                 :             break;
     842                 :         }
     843                 :     }
     844                 : 
     845               4 :     if( nCode == 0 )
     846               4 :         poDS->UnreadValue();
     847                 : 
     848                 : /* -------------------------------------------------------------------- */
     849                 : /*      Compute primary and secondary axis lengths, and the angle of    */
     850                 : /*      rotation for the ellipse.                                       */
     851                 : /* -------------------------------------------------------------------- */
     852                 :     double dfPrimaryRadius, dfSecondaryRadius;
     853                 :     double dfRotation;
     854                 : 
     855               4 :     if( dfStartAngle > dfEndAngle )
     856               0 :         dfEndAngle += 360.0;
     857                 : 
     858                 :     dfPrimaryRadius = sqrt( dfAxisX * dfAxisX 
     859                 :                             + dfAxisY * dfAxisY
     860               4 :                             + dfAxisZ * dfAxisZ );
     861                 : 
     862               4 :     dfSecondaryRadius = dfRatio * dfPrimaryRadius;
     863                 : 
     864               4 :     dfRotation = -1 * atan2( dfAxisY, dfAxisX ) * 180 / PI;
     865                 : 
     866                 : /* -------------------------------------------------------------------- */
     867                 : /*      Create geometry                                                 */
     868                 : /* -------------------------------------------------------------------- */
     869                 :     poFeature->SetGeometryDirectly( 
     870                 :         OGRGeometryFactory::approximateArcAngles( dfX1, dfY1, dfZ1, 
     871                 :                                                   dfPrimaryRadius, 
     872                 :                                                   dfSecondaryRadius,
     873                 :                                                   dfRotation, 
     874                 :                                                   dfStartAngle, dfEndAngle,
     875               4 :                                                   0.0 ) );
     876                 : 
     877               4 :     PrepareLineStyle( poFeature );
     878                 : 
     879               4 :     return poFeature;
     880                 : }
     881                 : 
     882                 : /************************************************************************/
     883                 : /*                            TranslateARC()                            */
     884                 : /************************************************************************/
     885                 : 
     886               2 : OGRFeature *OGRDXFLayer::TranslateARC()
     887                 : 
     888                 : {
     889                 :     char szLineBuf[257];
     890                 :     int nCode;
     891               2 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     892               2 :     double dfX1 = 0.0, dfY1 = 0.0, dfZ1 = 0.0, dfRadius = 0.0;
     893               2 :     double dfStartAngle = 0.0, dfEndAngle = 360.0;
     894                 : 
     895                 : /* -------------------------------------------------------------------- */
     896                 : /*      Process values.                                                 */
     897                 : /* -------------------------------------------------------------------- */
     898              32 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     899                 :     {
     900              28 :         switch( nCode )
     901                 :         {
     902                 :           case 10:
     903               2 :             dfX1 = atof(szLineBuf);
     904               2 :             break;
     905                 : 
     906                 :           case 20:
     907               2 :             dfY1 = atof(szLineBuf);
     908               2 :             break;
     909                 : 
     910                 :           case 30:
     911               2 :             dfZ1 = atof(szLineBuf);
     912               2 :             break;
     913                 : 
     914                 :           case 40:
     915               2 :             dfRadius = atof(szLineBuf);
     916               2 :             break;
     917                 : 
     918                 :           case 50:
     919               2 :             dfEndAngle = -1 * atof(szLineBuf);
     920               2 :             break;
     921                 : 
     922                 :           case 51:
     923               2 :             dfStartAngle = -1 * atof(szLineBuf);
     924               2 :             break;
     925                 : 
     926                 :           default:
     927              16 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     928                 :             break;
     929                 :         }
     930                 :     }
     931                 : 
     932               2 :     if( nCode == 0 )
     933               2 :         poDS->UnreadValue();
     934                 : 
     935                 : /* -------------------------------------------------------------------- */
     936                 : /*      Create geometry                                                 */
     937                 : /* -------------------------------------------------------------------- */
     938               2 :     if( dfStartAngle > dfEndAngle )
     939               2 :         dfEndAngle += 360.0;
     940                 : 
     941                 :     poFeature->SetGeometryDirectly( 
     942                 :         OGRGeometryFactory::approximateArcAngles( dfX1, dfY1, dfZ1, 
     943                 :                                                   dfRadius, dfRadius, 0.0,
     944                 :                                                   dfStartAngle, dfEndAngle,
     945               2 :                                                   0.0 ) );
     946                 : 
     947               2 :     PrepareLineStyle( poFeature );
     948                 : 
     949               2 :     return poFeature;
     950                 : }
     951                 : 
     952                 : /************************************************************************/
     953                 : /*                          TranslateSPLINE()                           */
     954                 : /************************************************************************/
     955                 : 
     956                 : void rbspline(int npts,int k,int p1,double b[],double h[], double p[]);
     957                 : void rbsplinu(int npts,int k,int p1,double b[],double h[], double p[]);
     958                 : 
     959               0 : OGRFeature *OGRDXFLayer::TranslateSPLINE()
     960                 : 
     961                 : {
     962                 :     char szLineBuf[257];
     963               0 :     int nCode, nDegree = -1, nFlags = -1, bClosed = FALSE, i;
     964               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     965               0 :     std::vector<double> adfControlPoints;
     966                 : 
     967               0 :     adfControlPoints.push_back(0.0);
     968                 : 
     969                 : /* -------------------------------------------------------------------- */
     970                 : /*      Process values.                                                 */
     971                 : /* -------------------------------------------------------------------- */
     972               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
     973                 :     {
     974               0 :         switch( nCode )
     975                 :         {
     976                 :           case 10:
     977               0 :             adfControlPoints.push_back( atof(szLineBuf) );
     978               0 :             break;
     979                 : 
     980                 :           case 20:
     981               0 :             adfControlPoints.push_back( atof(szLineBuf) );
     982               0 :             adfControlPoints.push_back( 0.0 );
     983               0 :             break;
     984                 : 
     985                 :           case 70:
     986               0 :             nFlags = atoi(szLineBuf);
     987               0 :             if( nFlags & 1 )
     988               0 :                 bClosed = TRUE;
     989               0 :             break;
     990                 : 
     991                 :           case 71:
     992               0 :             nDegree = atoi(szLineBuf);
     993               0 :             break;
     994                 : 
     995                 :           default:
     996               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
     997                 :             break;
     998                 :         }
     999                 :     }
    1000                 : 
    1001               0 :     if( nCode == 0 )
    1002               0 :         poDS->UnreadValue();
    1003                 : 
    1004               0 :     if( bClosed )
    1005                 :     {
    1006               0 :         for( i = 0; i < nDegree; i++ )
    1007                 :         {
    1008               0 :             adfControlPoints.push_back( adfControlPoints[i*3+1] );
    1009               0 :             adfControlPoints.push_back( adfControlPoints[i*3+2] );
    1010               0 :             adfControlPoints.push_back( adfControlPoints[i*3+3] );
    1011                 :         }
    1012                 :     }
    1013                 : 
    1014                 : /* -------------------------------------------------------------------- */
    1015                 : /*      Interpolate spline                                              */
    1016                 : /* -------------------------------------------------------------------- */
    1017               0 :     int nControlPoints = adfControlPoints.size() / 3;
    1018               0 :     std::vector<double> h, p;
    1019                 : 
    1020               0 :     h.push_back(1.0);
    1021               0 :     for( i = 0; i < nControlPoints; i++ )
    1022               0 :         h.push_back( 1.0 );
    1023                 :     
    1024                 :     // resolution:
    1025                 :     //int p1 = getGraphicVariableInt("$SPLINESEGS", 8) * npts;
    1026               0 :     int p1 = nControlPoints * 8;
    1027                 : 
    1028               0 :     p.push_back( 0.0 );
    1029               0 :     for( i = 0; i < 3*p1; i++ )
    1030               0 :         p.push_back( 0.0 );
    1031                 : 
    1032               0 :     if( bClosed )
    1033                 :         rbsplinu( nControlPoints, nDegree+1, p1, &(adfControlPoints[0]), 
    1034               0 :                   &(h[0]), &(p[0]) );
    1035                 :     else
    1036                 :         rbspline( nControlPoints, nDegree+1, p1, &(adfControlPoints[0]), 
    1037               0 :                   &(h[0]), &(p[0]) );
    1038                 :     
    1039                 : /* -------------------------------------------------------------------- */
    1040                 : /*      Turn into OGR geometry.                                         */
    1041                 : /* -------------------------------------------------------------------- */
    1042               0 :     OGRLineString *poLS = new OGRLineString();
    1043                 : 
    1044               0 :     poLS->setNumPoints( p1 );
    1045               0 :     for( i = 0; i < p1; i++ )
    1046               0 :         poLS->setPoint( i, p[i*3+1], p[i*3+2] );
    1047                 : 
    1048               0 :     poFeature->SetGeometryDirectly( poLS );
    1049                 : 
    1050               0 :     PrepareLineStyle( poFeature );
    1051                 : 
    1052               0 :     return poFeature;
    1053                 : }
    1054                 : 
    1055                 : /************************************************************************/
    1056                 : /*                      GeometryInsertTransformer                       */
    1057                 : /************************************************************************/
    1058                 : 
    1059                 : class GeometryInsertTransformer : public OGRCoordinateTransformation
    1060               0 : {
    1061                 : public:
    1062               0 :     GeometryInsertTransformer() : 
    1063                 :             dfXOffset(0),dfYOffset(0),dfZOffset(0),
    1064                 :             dfXScale(1.0),dfYScale(1.0),dfZScale(1.0),
    1065               0 :             dfAngle(0.0) {}
    1066                 : 
    1067                 :     double dfXOffset;
    1068                 :     double dfYOffset;
    1069                 :     double dfZOffset;
    1070                 :     double dfXScale;
    1071                 :     double dfYScale;
    1072                 :     double dfZScale;
    1073                 :     double dfAngle;
    1074                 : 
    1075               0 :     OGRSpatialReference *GetSourceCS() { return NULL; }
    1076               0 :     OGRSpatialReference *GetTargetCS() { return NULL; }
    1077               0 :     int Transform( int nCount, 
    1078                 :                    double *x, double *y, double *z )
    1079               0 :         { return TransformEx( nCount, x, y, z, NULL ); }
    1080                 :     
    1081               0 :     int TransformEx( int nCount, 
    1082                 :                      double *x, double *y, double *z = NULL,
    1083                 :                      int *pabSuccess = NULL )
    1084                 :         {
    1085                 :             int i;
    1086               0 :             for( i = 0; i < nCount; i++ )
    1087                 :             {
    1088                 :                 double dfXNew, dfYNew;
    1089                 : 
    1090               0 :                 x[i] *= dfXScale;
    1091               0 :                 y[i] *= dfYScale;
    1092               0 :                 z[i] *= dfZScale;
    1093                 : 
    1094               0 :                 dfXNew = x[i] * cos(dfAngle) - y[i] * sin(dfAngle);
    1095               0 :                 dfYNew = x[i] * sin(dfAngle) + y[i] * cos(dfAngle);
    1096                 : 
    1097               0 :                 x[i] = dfXNew;
    1098               0 :                 y[i] = dfYNew;
    1099                 : 
    1100               0 :                 x[i] += dfXOffset;
    1101               0 :                 y[i] += dfYOffset;
    1102               0 :                 z[i] += dfZOffset;
    1103                 : 
    1104               0 :                 if( pabSuccess )
    1105               0 :                     pabSuccess[i] = TRUE;
    1106                 :             }
    1107               0 :             return TRUE;
    1108                 :         }
    1109                 : };
    1110                 : 
    1111                 : /************************************************************************/
    1112                 : /*                          TranslateINSERT()                           */
    1113                 : /************************************************************************/
    1114                 : 
    1115               0 : OGRFeature *OGRDXFLayer::TranslateINSERT()
    1116                 : 
    1117                 : {
    1118                 :     char szLineBuf[257];
    1119                 :     int nCode;
    1120               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
    1121               0 :     GeometryInsertTransformer oTransformer;
    1122               0 :     CPLString osBlockName;
    1123                 : 
    1124                 : /* -------------------------------------------------------------------- */
    1125                 : /*      Process values.                                                 */
    1126                 : /* -------------------------------------------------------------------- */
    1127               0 :     while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 )
    1128                 :     {
    1129               0 :         switch( nCode )
    1130                 :         {
    1131                 :           case 10:
    1132               0 :             oTransformer.dfXOffset = atof(szLineBuf);
    1133               0 :             break;
    1134                 : 
    1135                 :           case 20:
    1136               0 :             oTransformer.dfYOffset = atof(szLineBuf);
    1137               0 :             break;
    1138                 : 
    1139                 :           case 30:
    1140               0 :             oTransformer.dfZOffset = atof(szLineBuf);
    1141               0 :             break;
    1142                 : 
    1143                 :           case 41:
    1144               0 :             oTransformer.dfXScale = atof(szLineBuf);
    1145               0 :             break;
    1146                 : 
    1147                 :           case 42:
    1148               0 :             oTransformer.dfYScale = atof(szLineBuf);
    1149               0 :             break;
    1150                 : 
    1151                 :           case 43:
    1152               0 :             oTransformer.dfZScale = atof(szLineBuf);
    1153               0 :             break;
    1154                 : 
    1155                 :           case 50:
    1156               0 :             oTransformer.dfAngle = atof(szLineBuf) * PI / 180.0;
    1157               0 :             break;
    1158                 : 
    1159                 :           case 2: 
    1160               0 :             osBlockName = szLineBuf;
    1161               0 :             break;
    1162                 :             
    1163                 :           default:
    1164               0 :             TranslateGenericProperty( poFeature, nCode, szLineBuf );
    1165                 :             break;
    1166                 :         }
    1167                 :     }
    1168                 : 
    1169               0 :     if( nCode == 0 )
    1170               0 :         poDS->UnreadValue();
    1171                 : 
    1172                 : /* -------------------------------------------------------------------- */
    1173                 : /*      Lookup the block.                                               */
    1174                 : /* -------------------------------------------------------------------- */
    1175               0 :     DXFBlockDefinition *poBlock = poDS->LookupBlock( osBlockName );
    1176                 :     
    1177               0 :     if( poBlock == NULL )
    1178                 :     {
    1179               0 :         delete poFeature;
    1180               0 :         return NULL;
    1181                 :     }
    1182                 : 
    1183                 : /* -------------------------------------------------------------------- */
    1184                 : /*      Transform the geometry.                                         */
    1185                 : /* -------------------------------------------------------------------- */
    1186               0 :     if( poBlock->poGeometry != NULL )
    1187                 :     {
    1188               0 :         OGRGeometry *poGeometry = poBlock->poGeometry->clone();
    1189                 : 
    1190               0 :         poGeometry->transform( &oTransformer );
    1191                 : 
    1192               0 :         poFeature->SetGeometryDirectly( poGeometry );
    1193                 :     }
    1194                 : 
    1195                 : /* -------------------------------------------------------------------- */
    1196                 : /*      If we have complete features associated with the block, push    */
    1197                 : /*      them on the pending feature stack copying over key override     */
    1198                 : /*      information.                                                    */
    1199                 : /*                                                                      */
    1200                 : /*      Note that while we transform the geometry of the features we    */
    1201                 : /*      don't adjust subtle things like text angle.                     */
    1202                 : /* -------------------------------------------------------------------- */
    1203                 :     unsigned int iSubFeat;
    1204                 : 
    1205               0 :     for( iSubFeat = 0; iSubFeat < poBlock->apoFeatures.size(); iSubFeat++ )
    1206                 :     {
    1207               0 :         OGRFeature *poSubFeature = poBlock->apoFeatures[iSubFeat]->Clone();
    1208                 : 
    1209               0 :         if( poSubFeature->GetGeometryRef() != NULL )
    1210               0 :             poSubFeature->GetGeometryRef()->transform( &oTransformer );
    1211                 : 
    1212               0 :         apoPendingFeatures.push( poSubFeature );
    1213                 :     }
    1214                 : 
    1215                 : /* -------------------------------------------------------------------- */
    1216                 : /*      Return the working feature if we had geometry, otherwise        */
    1217                 : /*      return NULL and let the machinery find the rest of the          */
    1218                 : /*      features in the pending feature stack.                          */
    1219                 : /* -------------------------------------------------------------------- */
    1220               0 :     if( poBlock->poGeometry == NULL )
    1221                 :     {
    1222               0 :         delete poFeature;
    1223               0 :         return NULL;
    1224                 :     }
    1225                 :     else
    1226                 :     {
    1227               0 :         return poFeature;
    1228               0 :     }
    1229                 : }
    1230                 : 
    1231                 : /************************************************************************/
    1232                 : /*                      GetNextUnfilteredFeature()                      */
    1233                 : /************************************************************************/
    1234                 : 
    1235              23 : OGRFeature *OGRDXFLayer::GetNextUnfilteredFeature()
    1236                 : 
    1237                 : {
    1238              23 :     OGRFeature *poFeature = NULL;
    1239                 : 
    1240                 : /* -------------------------------------------------------------------- */
    1241                 : /*      If we have pending features, return one of them.                */
    1242                 : /* -------------------------------------------------------------------- */
    1243              23 :     if( !apoPendingFeatures.empty() )
    1244                 :     {
    1245               4 :         poFeature = apoPendingFeatures.top();
    1246               4 :         apoPendingFeatures.pop();
    1247                 : 
    1248               4 :         poFeature->SetFID( iNextFID++ );
    1249               4 :         return poFeature;
    1250                 :     }
    1251                 : 
    1252                 : /* -------------------------------------------------------------------- */
    1253                 : /*      Read the entity type.                                           */
    1254                 : /* -------------------------------------------------------------------- */
    1255                 :     char szLineBuf[257];
    1256                 :     int nCode;
    1257                 : 
    1258              56 :     while( poFeature == NULL )
    1259                 :     {
    1260                 :         // read ahead to an entity.
    1261              19 :         while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 ) {}
    1262                 : 
    1263              19 :         if( nCode == -1 )
    1264                 :         {
    1265               0 :             CPLDebug( "DXF", "Unexpected end of data without ENDSEC." );
    1266               0 :             return NULL;
    1267                 :         }
    1268                 :         
    1269              19 :         if( EQUAL(szLineBuf,"ENDSEC") )
    1270                 :         {
    1271                 :             //CPLDebug( "DXF", "Clean end of features at ENDSEC." );
    1272               1 :             poDS->UnreadValue();
    1273               1 :             return NULL;
    1274                 :         }
    1275                 : 
    1276              18 :         if( EQUAL(szLineBuf,"ENDBLK") )
    1277                 :         {
    1278                 :             //CPLDebug( "DXF", "Clean end of block at ENDBLK." );
    1279               0 :             poDS->UnreadValue();
    1280               0 :             return NULL;
    1281                 :         }
    1282                 : 
    1283                 : /* -------------------------------------------------------------------- */
    1284                 : /*      Handle the entity.                                              */
    1285                 : /* -------------------------------------------------------------------- */
    1286              18 :         oStyleProperties.clear();
    1287                 : 
    1288              18 :         if( EQUAL(szLineBuf,"POINT") )
    1289                 :         {
    1290               2 :             poFeature = TranslatePOINT();
    1291                 :         }
    1292              16 :         else if( EQUAL(szLineBuf,"MTEXT") )
    1293                 :         {
    1294               2 :             poFeature = TranslateMTEXT();
    1295                 :         }
    1296              14 :         else if( EQUAL(szLineBuf,"TEXT") )
    1297                 :         {
    1298               0 :             poFeature = TranslateTEXT();
    1299                 :         }
    1300              14 :         else if( EQUAL(szLineBuf,"LINE") )
    1301                 :         {
    1302               4 :             poFeature = TranslateLINE();
    1303                 :         }
    1304              10 :         else if( EQUAL(szLineBuf,"POLYLINE") )
    1305                 :         {
    1306               0 :             poFeature = TranslatePOLYLINE();
    1307                 :         }
    1308              10 :         else if( EQUAL(szLineBuf,"LWPOLYLINE") )
    1309                 :         {
    1310               0 :             poFeature = TranslateLWPOLYLINE();
    1311                 :         }
    1312              10 :         else if( EQUAL(szLineBuf,"CIRCLE") )
    1313                 :         {
    1314               0 :             poFeature = TranslateCIRCLE();
    1315                 :         }
    1316              10 :         else if( EQUAL(szLineBuf,"ELLIPSE") )
    1317                 :         {
    1318               4 :             poFeature = TranslateELLIPSE();
    1319                 :         }
    1320               6 :         else if( EQUAL(szLineBuf,"ARC") )
    1321                 :         {
    1322               2 :             poFeature = TranslateARC();
    1323                 :         }
    1324               4 :         else if( EQUAL(szLineBuf,"SPLINE") )
    1325                 :         {
    1326               0 :             poFeature = TranslateSPLINE();
    1327                 :         }
    1328               4 :         else if( EQUAL(szLineBuf,"INSERT") )
    1329                 :         {
    1330               0 :             poFeature = TranslateINSERT();
    1331                 :         }
    1332               4 :         else if( EQUAL(szLineBuf,"DIMENSION") )
    1333                 :         {
    1334               4 :             poFeature = TranslateDIMENSION();
    1335                 :         }
    1336                 :         else
    1337                 :         {
    1338               0 :             CPLDebug( "DXF", "Ignoring entity '%s'.", szLineBuf );
    1339                 :         }
    1340                 :     }
    1341                 : 
    1342                 : /* -------------------------------------------------------------------- */
    1343                 : /*      Set FID.                                                        */
    1344                 : /* -------------------------------------------------------------------- */
    1345              18 :     poFeature->SetFID( iNextFID++ );
    1346              18 :     m_nFeaturesRead++;
    1347                 : 
    1348              18 :     return poFeature;
    1349                 : }
    1350                 : 
    1351                 : /************************************************************************/
    1352                 : /*                           GetNextFeature()                           */
    1353                 : /************************************************************************/
    1354                 : 
    1355              23 : OGRFeature *OGRDXFLayer::GetNextFeature()
    1356                 : 
    1357                 : {
    1358               0 :     while( TRUE )
    1359                 :     {
    1360              23 :         OGRFeature *poFeature = GetNextUnfilteredFeature();
    1361                 : 
    1362              23 :         if( poFeature == NULL )
    1363               1 :             return NULL;
    1364                 : 
    1365              22 :         if( (m_poFilterGeom == NULL
    1366                 :              || FilterGeometry( poFeature->GetGeometryRef() ) )
    1367                 :             && (m_poAttrQuery == NULL
    1368                 :                 || m_poAttrQuery->Evaluate( poFeature ) ) )
    1369                 :         {
    1370              22 :             return poFeature;
    1371                 :         }
    1372                 : 
    1373               0 :         delete poFeature;
    1374                 :     }
    1375                 : }
    1376                 : 
    1377                 : /************************************************************************/
    1378                 : /*                           TestCapability()                           */
    1379                 : /************************************************************************/
    1380                 : 
    1381               0 : int OGRDXFLayer::TestCapability( const char * pszCap )
    1382                 : 
    1383                 : {
    1384               0 :     return FALSE;
    1385                 : }
    1386                 : 

Generated by: LCOV version 1.7