LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/edigeo - ogredigeodatasource.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 784 700 89.3 %
Date: 2012-04-28 Functions: 27 23 85.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogredigeodatasource.cpp 23423 2011-11-26 18:40:30Z rouault $
       3                 :  *
       4                 :  * Project:  EDIGEO Translator
       5                 :  * Purpose:  Implements OGREDIGEODataSource class
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault <even dot rouault at mines dash paris dot org>
      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_edigeo.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : 
      34                 : CPL_CVSID("$Id: ogredigeodatasource.cpp 23423 2011-11-26 18:40:30Z rouault $");
      35                 : 
      36                 : #ifndef M_PI
      37                 : # define M_PI  3.1415926535897932384626433832795
      38                 : #endif
      39                 : 
      40                 : /************************************************************************/
      41                 : /*                        OGREDIGEODataSource()                         */
      42                 : /************************************************************************/
      43                 : 
      44             196 : OGREDIGEODataSource::OGREDIGEODataSource()
      45                 : 
      46                 : {
      47             196 :     papoLayers = NULL;
      48             196 :     nLayers = 0;
      49                 : 
      50             196 :     pszName = NULL;
      51             196 :     poSRS = NULL;
      52                 : 
      53             196 :     bExtentValid = FALSE;
      54             196 :     dfMinX = dfMinY = dfMaxX = dfMaxY = 0;
      55                 : 
      56             196 :     fpTHF = NULL;
      57             196 :     bHasReadEDIGEO = FALSE;
      58                 : 
      59                 :     bIncludeFontFamily = CSLTestBoolean(CPLGetConfigOption(
      60             196 :                                  "OGR_EDIGEO_INCLUDE_FONT_FAMILY", "YES"));
      61                 : 
      62             196 :     iATR = iDI3 = iDI4 = iHEI = iFON = -1;
      63             196 :     iATR_VAL = iANGLE = iSIZE = iOBJ_LNK = iOBJ_LNK_LAYER = -1;
      64             196 :     dfSizeFactor = atof(CPLGetConfigOption("OGR_EDIGEO_FONT_SIZE_FACTOR", "2"));
      65             196 :     if (dfSizeFactor <= 0 || dfSizeFactor >= 100)
      66               0 :         dfSizeFactor = 2;
      67                 : 
      68                 :     bRecodeToUTF8 = CSLTestBoolean(CPLGetConfigOption(
      69             196 :                                         "OGR_EDIGEO_RECODE_TO_UTF8", "YES"));
      70             196 :     bHasUTF8ContentOnly = TRUE;
      71             196 : }
      72                 : 
      73                 : /************************************************************************/
      74                 : /*                      ~OGREDIGEODataSource()                          */
      75                 : /************************************************************************/
      76                 : 
      77             196 : OGREDIGEODataSource::~OGREDIGEODataSource()
      78                 : 
      79                 : {
      80             244 :     for( int i = 0; i < nLayers; i++ )
      81              48 :         delete papoLayers[i];
      82             196 :     CPLFree( papoLayers );
      83                 : 
      84             196 :     CPLFree( pszName );
      85                 : 
      86             196 :     if (fpTHF)
      87               0 :         VSIFCloseL(fpTHF);
      88                 : 
      89             196 :     if (poSRS)
      90               2 :         poSRS->Release();
      91             196 : }
      92                 : 
      93                 : /************************************************************************/
      94                 : /*                           TestCapability()                           */
      95                 : /************************************************************************/
      96                 : 
      97               0 : int OGREDIGEODataSource::TestCapability( const char * pszCap )
      98                 : 
      99                 : {
     100               0 :     return FALSE;
     101                 : }
     102                 : 
     103                 : /************************************************************************/
     104                 : /*                              GetLayer()                              */
     105                 : /************************************************************************/
     106                 : 
     107             398 : OGRLayer *OGREDIGEODataSource::GetLayer( int iLayer )
     108                 : 
     109                 : {
     110             398 :     ReadEDIGEO();
     111             398 :     if( iLayer < 0 || iLayer >= nLayers )
     112               0 :         return NULL;
     113                 :     else
     114             398 :         return papoLayers[iLayer];
     115                 : }
     116                 : 
     117                 : /************************************************************************/
     118                 : /*                         GetLayerCount()                              */
     119                 : /************************************************************************/
     120                 : 
     121             400 : int OGREDIGEODataSource::GetLayerCount()
     122                 : {
     123             400 :     ReadEDIGEO();
     124             400 :     return nLayers;
     125                 : }
     126                 : 
     127                 : /************************************************************************/
     128                 : /*                              ReadTHF()                               */
     129                 : /************************************************************************/
     130                 : 
     131               2 : int OGREDIGEODataSource::ReadTHF(VSILFILE* fp)
     132                 : {
     133                 :     const char* pszLine;
     134              94 :     while((pszLine = CPLReadLine2L(fp, 81, NULL)) != NULL)
     135                 :     {
     136              90 :         if (strlen(pszLine) < 8 || pszLine[7] != ':')
     137              10 :             continue;
     138                 : 
     139                 :         /* Cf Z 52000 tableau 56 for field list*/
     140                 : 
     141              80 :         if (strncmp(pszLine, "LONSA", 5) == 0)
     142                 :         {
     143               2 :             if (osLON.size() != 0)
     144                 :             {
     145               0 :                 CPLDebug("EDIGEO", "We only handle one lot per THF file");
     146               0 :                 break;
     147                 :             }
     148               2 :             osLON = pszLine + 8;
     149                 :         }
     150              78 :         else if (strncmp(pszLine, "GNNSA", 5) == 0)
     151               2 :             osGNN = pszLine + 8;
     152              76 :         else if (strncmp(pszLine, "GONSA", 5) == 0)
     153               2 :             osGON = pszLine + 8;
     154              74 :         else if (strncmp(pszLine, "QANSA", 5) == 0)
     155               2 :             osQAN = pszLine + 8;
     156              72 :         else if (strncmp(pszLine, "DINSA", 5) == 0)
     157               2 :             osDIN = pszLine + 8;
     158              70 :         else if (strncmp(pszLine, "SCNSA", 5) == 0)
     159               2 :             osSCN = pszLine + 8;
     160              68 :         else if (strncmp(pszLine, "GDNSA", 5) == 0)
     161               8 :             aosGDN.push_back(pszLine + 8);
     162                 :     }
     163               2 :     if (osLON.size() == 0)
     164                 :     {
     165               0 :         CPLDebug("EDIGEO", "LON field missing");
     166               0 :         return 0;
     167                 :     }
     168               2 :     if (osGON.size() == 0)
     169                 :     {
     170               0 :         CPLDebug("EDIGEO", "GON field missing");
     171               0 :         return 0;
     172                 :     }
     173               2 :     if (osDIN.size() == 0)
     174                 :     {
     175               0 :         CPLDebug("EDIGEO", "DIN field missing");
     176               0 :         return 0;
     177                 :     }
     178               2 :     if (osSCN.size() == 0)
     179                 :     {
     180               0 :         CPLDebug("EDIGEO", "SCN field missing");
     181               0 :         return FALSE;
     182                 :     }
     183                 : 
     184               2 :     CPLDebug("EDIGEO", "LON = %s", osLON.c_str());
     185               2 :     CPLDebug("EDIGEO", "GNN = %s", osGNN.c_str());
     186               2 :     CPLDebug("EDIGEO", "GON = %s", osGON.c_str());
     187               2 :     CPLDebug("EDIGEO", "QAN = %s", osQAN.c_str());
     188               2 :     CPLDebug("EDIGEO", "DIN = %s", osDIN.c_str());
     189               2 :     CPLDebug("EDIGEO", "SCN = %s", osSCN.c_str());
     190              10 :     for(int i=0;i<(int)aosGDN.size();i++)
     191               8 :         CPLDebug("EDIGEO", "GDN[%d] = %s", i, aosGDN[i].c_str());
     192                 :     
     193               2 :     return TRUE;
     194                 : }
     195                 : 
     196                 : 
     197                 : /************************************************************************/
     198                 : /*                             OpenFile()                               */
     199                 : /************************************************************************/
     200                 : 
     201              18 : VSILFILE* OGREDIGEODataSource::OpenFile(const char *pszType,
     202                 :                                         const CPLString& osExt)
     203                 : {
     204              18 :     CPLString osTmp = osLON + pszType;
     205                 :     CPLString osFilename = CPLFormCIFilename(CPLGetPath(pszName),
     206              18 :                                              osTmp.c_str(), osExt.c_str());
     207              18 :     VSILFILE* fp = VSIFOpenL(osFilename, "rb");
     208              18 :     if (fp == NULL)
     209                 :     {
     210               0 :         CPLString osExtLower = osExt;
     211               0 :         for(int i=0;i<(int)osExt.size();i++)
     212               0 :             osExtLower[i] = (char)tolower(osExt[i]);
     213                 :         CPLString osFilename2 = CPLFormCIFilename(CPLGetPath(pszName),
     214               0 :                                              osTmp.c_str(), osExtLower.c_str());
     215               0 :         fp = VSIFOpenL(osFilename2, "rb");
     216               0 :         if (fp == NULL)
     217                 :         {
     218               0 :             CPLDebug("EDIGEO", "Cannot open %s", osFilename.c_str());
     219               0 :         }
     220                 :     }
     221              18 :     return fp;
     222                 : }
     223                 : 
     224                 : /************************************************************************/
     225                 : /*                              ReadGEO()                               */
     226                 : /************************************************************************/
     227                 : 
     228               2 : int OGREDIGEODataSource::ReadGEO()
     229                 : {
     230               2 :     VSILFILE* fp = OpenFile(osGON, "GEO");
     231               2 :     if (fp == NULL)
     232               0 :         return FALSE;
     233                 : 
     234                 :     const char* pszLine;
     235              20 :     while((pszLine = CPLReadLine2L(fp, 81, NULL)) != NULL)
     236                 :     {
     237              18 :         if (strlen(pszLine) < 8 || pszLine[7] != ':')
     238               4 :             continue;
     239                 : 
     240              14 :         if (strncmp(pszLine, "RELSA", 5) == 0)
     241                 :         {
     242               2 :             osREL = pszLine + 8;
     243               2 :             CPLDebug("EDIGEO", "REL = %s", osREL.c_str());
     244               2 :             break;
     245                 :         }
     246                 :     }
     247                 : 
     248               2 :     VSIFCloseL(fp);
     249                 : 
     250               2 :     if (osREL.size() == 0)
     251                 :     {
     252               0 :         CPLDebug("EDIGEO", "REL field missing");
     253               0 :         return FALSE;
     254                 :     }
     255                 : 
     256                 :     /* All the SRS names mentionned in B.8.2.3 and B.8.3.1 are in the IGN file */
     257               2 :     poSRS = new OGRSpatialReference();
     258               4 :     CPLString osProj4Str = "+init=IGNF:" + osREL;
     259               2 :     if (poSRS->SetFromUserInput(osProj4Str.c_str()) != OGRERR_NONE)
     260                 :     {
     261                 :         /* Hard code a few common cases */
     262               0 :         if (osREL == "LAMB1")
     263               0 :             poSRS->importFromProj4("+proj=lcc +lat_1=49.5 +lat_0=49.5 +lon_0=0 +k_0=0.99987734 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356514.999978254 +nadgrids=ntf_r93.gsb,null +pm=paris +units=m +no_defs");
     264               0 :         else if (osREL == "LAMB2")
     265               0 :             poSRS->importFromProj4("+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356514.999978254 +nadgrids=ntf_r93.gsb,null +pm=paris +units=m +no_defs");
     266               0 :         else if (osREL == "LAMB3")
     267               0 :             poSRS->importFromProj4("+proj=lcc +lat_1=44.1 +lat_0=44.1 +lon_0=0 +k_0=0.9998775 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356514.999978254 +nadgrids=ntf_r93.gsb,null +pm=paris +units=m +no_defs");
     268               0 :         else if (osREL == "LAMB4")
     269               0 :             poSRS->importFromProj4("+proj=lcc +lat_1=42.165 +lat_0=42.165 +lon_0=0 +k_0=0.99994471 +x_0=234.358 +y_0=185861.369 +a=6378249.2 +b=6356514.999978254 +nadgrids=ntf_r93.gsb,null +pm=paris +units=m +no_defs");
     270               0 :         else if (osREL == "LAMB93")
     271               0 :             poSRS->importFromProj4("+proj=lcc +lat_1=44 +lat_2=49 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS81 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs");
     272                 :         else
     273                 :         {
     274               0 :             CPLDebug("EDIGEO", "Cannot resolve %s SRS. Check that the IGNF file is in the directory of PROJ.4 ressource files", osREL.c_str());
     275               0 :             delete poSRS;
     276               0 :             poSRS = NULL;
     277                 :         }
     278                 :     }
     279                 :     
     280               2 :     return TRUE;
     281                 : }
     282                 : 
     283                 : /************************************************************************/
     284                 : /*                              ReadGEN()                               */
     285                 : /************************************************************************/
     286                 : 
     287               2 : int OGREDIGEODataSource::ReadGEN()
     288                 : {
     289               2 :     VSILFILE* fp = OpenFile(osGNN, "GEN");
     290               2 :     if (fp == NULL)
     291               0 :         return FALSE;
     292                 : 
     293                 :     const char* pszLine;
     294               2 :     CPLString osCM1, osCM2;
     295              80 :     while((pszLine = CPLReadLine2L(fp, 81, NULL)) != NULL)
     296                 :     {
     297              76 :         if (strlen(pszLine) < 8 || pszLine[7] != ':')
     298              22 :             continue;
     299                 : 
     300              54 :         if (strncmp(pszLine, "CM1CC", 5) == 0)
     301                 :         {
     302               2 :             osCM1 = pszLine + 8;
     303                 :         }
     304              52 :         else if (strncmp(pszLine, "CM2CC", 5) == 0)
     305                 :         {
     306               2 :             osCM2 = pszLine + 8;
     307                 :         }
     308                 :     }
     309                 : 
     310               2 :     VSIFCloseL(fp);
     311                 : 
     312               2 :     if (osCM1.size() == 0 || osCM2.size() == 0)
     313               0 :         return FALSE;
     314                 : 
     315               2 :     char** papszTokens1 = CSLTokenizeString2(osCM1.c_str(), ";", 0);
     316               2 :     char** papszTokens2 = CSLTokenizeString2(osCM2.c_str(), ";", 0);
     317               2 :     if (CSLCount(papszTokens1) == 2 && CSLCount(papszTokens2) == 2)
     318                 :     {
     319               2 :         bExtentValid = TRUE;
     320               2 :         dfMinX = atof(papszTokens1[0]);
     321               2 :         dfMinY = atof(papszTokens1[1]);
     322               2 :         dfMaxX = atof(papszTokens2[0]);
     323               2 :         dfMaxY = atof(papszTokens2[1]);
     324                 :     }
     325               2 :     CSLDestroy(papszTokens1);
     326               2 :     CSLDestroy(papszTokens2);
     327                 : 
     328               2 :     return bExtentValid;
     329                 : }
     330                 : 
     331                 : /************************************************************************/
     332                 : /*                              ReadDIC()                               */
     333                 : /************************************************************************/
     334                 : 
     335               2 : int OGREDIGEODataSource::ReadDIC()
     336                 : {
     337               2 :     VSILFILE* fp = OpenFile(osDIN, "DIC");
     338               2 :     if (fp == NULL)
     339               0 :         return FALSE;
     340                 : 
     341                 :     const char* pszLine;
     342               2 :     CPLString osRTY, osRID, osLAB, osTYP;
     343            2294 :     while(TRUE)
     344                 :     {
     345            2296 :         pszLine = CPLReadLine2L(fp, 81, NULL);
     346            2296 :         if (pszLine != NULL)
     347                 :         {
     348            2294 :             if (strlen(pszLine) < 8 || pszLine[7] != ':')
     349             306 :                 continue;
     350                 :         }
     351                 : 
     352            1990 :         if (pszLine == NULL || strncmp(pszLine, "RTYSA", 5) == 0)
     353                 :         {
     354             154 :             if (osRTY == "DID")
     355                 :             {
     356                 :                 //CPLDebug("EDIGEO", "Object %s = %s",
     357                 :                 //         osRID.c_str(), osLAB.c_str());
     358              42 :                 mapObjects[osRID] = osLAB;
     359                 :             }
     360             112 :             else if (osRTY == "DIA")
     361                 :             {
     362                 :                 //CPLDebug("EDIGEO", "Attribute %s = %s, %s",
     363                 :                 //         osRID.c_str(), osLAB.c_str(), osTYP.c_str());
     364             106 :                 OGREDIGEOAttributeDef sAttributeDef;
     365             106 :                 sAttributeDef.osLAB = osLAB;
     366             106 :                 sAttributeDef.osTYP = osTYP;
     367             106 :                 mapAttributes[osRID] = sAttributeDef;
     368                 :             }
     369             154 :             if (pszLine == NULL)
     370                 :                 break;
     371             152 :             osRTY = pszLine + 8;
     372             152 :             osRID = "";
     373             152 :             osLAB = "";
     374             152 :             osTYP = "";
     375                 :         }
     376            1988 :         if (strncmp(pszLine, "RIDSA", 5) == 0)
     377             152 :             osRID = pszLine + 8;
     378            1836 :         else if (strncmp(pszLine, "LABSA", 5) == 0)
     379             152 :             osLAB = pszLine + 8;
     380            1684 :         else if (strncmp(pszLine, "TYPSA", 5) == 0)
     381             106 :             osTYP = pszLine + 8;
     382                 :     }
     383                 : 
     384               2 :     VSIFCloseL(fp);
     385                 : 
     386                 : 
     387               2 :     return TRUE;
     388                 : }
     389                 : 
     390                 : /************************************************************************/
     391                 : /*                              ReadSCD()                               */
     392                 : /************************************************************************/
     393                 : 
     394               2 : int OGREDIGEODataSource::ReadSCD()
     395                 : {
     396               2 :     VSILFILE* fp = OpenFile(osSCN, "SCD");
     397               2 :     if (fp == NULL)
     398               0 :         return FALSE;
     399                 : 
     400                 :     const char* pszLine;
     401               2 :     CPLString osRTY, osRID, osNameRID, osKND;
     402               2 :     strListType aosAttrRID;
     403               2 :     int nWidth = 0;
     404            2812 :     while(TRUE)
     405                 :     {
     406            2814 :         pszLine = CPLReadLine2L(fp, 81, NULL);
     407            2814 :         if (pszLine != NULL)
     408                 :         {
     409            2812 :             if (strlen(pszLine) < 8 || pszLine[7] != ':')
     410             478 :                 continue;
     411                 :         }
     412                 : 
     413            2336 :         if (pszLine == NULL || strncmp(pszLine, "RTYSA", 5) == 0)
     414                 :         {
     415             240 :             if (osRTY == "OBJ")
     416                 :             {
     417              44 :                 if (mapObjects.find(osNameRID) == mapObjects.end())
     418                 :                 {
     419                 :                     CPLDebug("EDIGEO", "Cannot find object %s",
     420               0 :                              osNameRID.c_str());
     421                 :                 }
     422                 :                 else
     423                 :                 {
     424              44 :                     OGREDIGEOObjectDescriptor objDesc;
     425              44 :                     objDesc.osRID = osRID;
     426              44 :                     objDesc.osNameRID = osNameRID;
     427              44 :                     objDesc.osKND = osKND;
     428              44 :                     objDesc.aosAttrRID = aosAttrRID;
     429                 :                     /*CPLDebug("EDIGEO", "Object %s = %s, %s, %d attributes",
     430                 :                             osRID.c_str(), osNameRID.c_str(), osKND.c_str(),
     431                 :                             (int)aosAttrRID.size());*/
     432                 : 
     433              44 :                     aoObjList.push_back(objDesc);
     434                 :                 }
     435                 :             }
     436             196 :             else if (osRTY == "ATT")
     437                 :             {
     438             106 :                 if (mapAttributes.find(osNameRID) == mapAttributes.end())
     439                 :                 {
     440                 :                     CPLDebug("EDIGEO", "Cannot find attribute %s",
     441               0 :                              osNameRID.c_str());
     442                 :                 }
     443                 :                 else
     444                 :                 {
     445             106 :                     OGREDIGEOAttributeDescriptor attDesc;
     446             106 :                     attDesc.osRID = osRID;
     447             106 :                     attDesc.osNameRID = osNameRID;
     448             106 :                     attDesc.nWidth = nWidth;
     449                 :                     /*CPLDebug("EDIGEO", "Attribute %s = %s, %d",
     450                 :                             osRID.c_str(), osNameRID.c_str(), nWidth);*/
     451                 : 
     452             106 :                     mapAttributesSCD[osRID] = attDesc;
     453                 :                 }
     454                 :             }
     455             240 :             if (pszLine == NULL)
     456                 :                 break;
     457             238 :             osRTY = pszLine + 8;
     458             238 :             osRID = "";
     459             238 :             osNameRID = "";
     460             238 :             osKND = "";
     461             238 :             aosAttrRID.resize(0);
     462             238 :             nWidth = 0;
     463                 :         }
     464            2334 :         if (strncmp(pszLine, "RIDSA", 5) == 0)
     465             238 :             osRID = pszLine + 8;
     466            2096 :         else if (strncmp(pszLine, "DIPCP", 5) == 0)
     467                 :         {
     468             176 :             const char* pszDIP = pszLine + 8;
     469             176 :             char** papszTokens = CSLTokenizeString2(pszDIP, ";", 0);
     470             176 :             if (CSLCount(papszTokens) == 4)
     471                 :             {
     472             176 :                 osNameRID = papszTokens[3];
     473                 :             }
     474             176 :             CSLDestroy(papszTokens);
     475                 :         }
     476            1920 :         else if (strncmp(pszLine, "KNDSA", 5) == 0)
     477             106 :             osKND = pszLine + 8;
     478            1814 :         else if (strncmp(pszLine, "AAPCP", 5) == 0)
     479                 :         {
     480             214 :             const char* pszAAP = pszLine + 8;
     481             214 :             char** papszTokens = CSLTokenizeString2(pszAAP, ";", 0);
     482             214 :             if (CSLCount(papszTokens) == 4)
     483                 :             {
     484             214 :                 const char* pszAttRID = papszTokens[3];
     485             214 :                 aosAttrRID.push_back(pszAttRID);
     486                 :             }
     487             214 :             CSLDestroy(papszTokens);
     488                 :         }
     489            1600 :         else if (strncmp(pszLine, "CANSN", 5) == 0)
     490             106 :             nWidth = atoi(pszLine + 8);
     491                 :     }
     492                 : 
     493               2 :     VSIFCloseL(fp);
     494                 : 
     495                 : 
     496               2 :     return TRUE;
     497                 : }
     498                 : 
     499                 : /************************************************************************/
     500                 : /*                              ReadQAL()                               */
     501                 : /************************************************************************/
     502                 : 
     503               2 : int OGREDIGEODataSource::ReadQAL()
     504                 : {
     505               2 :     VSILFILE* fp = OpenFile(osQAN, "QAL");
     506               2 :     if (fp == NULL)
     507               0 :         return FALSE;
     508                 : 
     509                 :     const char* pszLine;
     510               2 :     CPLString osRTY, osRID;
     511               2 :     int nODA = 0, nUDA = 0;
     512           12080 :     while(TRUE)
     513                 :     {
     514           12082 :         pszLine = CPLReadLine2L(fp, 81, NULL);
     515           12082 :         if (pszLine != NULL)
     516                 :         {
     517           12080 :             if (strlen(pszLine) < 8 || pszLine[7] != ':')
     518            2014 :                 continue;
     519                 :         }
     520                 : 
     521           11074 :         if (pszLine == NULL || strncmp(pszLine, "RTYSA", 5) == 0)
     522                 :         {
     523            1008 :             if (osRTY == "QUP")
     524                 :             {
     525            1006 :                 mapQAL[osRID] = intintType(nODA, nUDA);
     526                 :             }
     527            1008 :             if (pszLine == NULL)
     528                 :                 break;
     529            1006 :             osRTY = pszLine + 8;
     530            1006 :             osRID = "";
     531            1006 :             nODA = 0;
     532            1006 :             nUDA = 0;
     533                 :         }
     534            9060 :         else if (strncmp(pszLine, "RIDSA", 5) == 0)
     535            1006 :             osRID = pszLine + 8;
     536            8054 :         else if (strncmp(pszLine, "ODASD", 5) == 0)
     537            1006 :             nODA = atoi(pszLine + 8);
     538            7048 :         else if (strncmp(pszLine, "UDASD", 5) == 0)
     539            1006 :             nUDA = atoi(pszLine + 8);
     540                 :     }
     541                 : 
     542               2 :     VSIFCloseL(fp);
     543                 : 
     544               2 :     return TRUE;
     545                 : }
     546                 : 
     547                 : /************************************************************************/
     548                 : /*                       CreateLayerFromObjectDesc()                    */
     549                 : /************************************************************************/
     550                 : 
     551              44 : int OGREDIGEODataSource::CreateLayerFromObjectDesc(const OGREDIGEOObjectDescriptor& objDesc)
     552                 : {
     553              44 :     OGRwkbGeometryType eType = wkbUnknown;
     554              44 :     if (objDesc.osKND == "ARE")
     555              22 :         eType = wkbPolygon;
     556              22 :     else if (objDesc.osKND == "LIN")
     557               4 :         eType = wkbLineString;
     558              18 :     else if (objDesc.osKND == "PCT")
     559              18 :         eType = wkbPoint;
     560                 :     else
     561                 :     {
     562               0 :         CPLDebug("EDIGEO", "Unknown KND : %s", objDesc.osKND.c_str());
     563               0 :         return FALSE;
     564                 :     }
     565                 : 
     566              44 :     const char* pszLayerName = objDesc.osRID.c_str();
     567                 :         //mapObjects.find(objDesc.osNameRID)->second.c_str();
     568                 :     OGREDIGEOLayer* poLayer = new OGREDIGEOLayer(this, pszLayerName,
     569              44 :                                                     eType, poSRS);
     570                 : 
     571              88 :     poLayer->AddFieldDefn("OBJECT_RID", OFTString, "");
     572                 : 
     573             258 :     for(int j=0;j<(int)objDesc.aosAttrRID.size();j++)
     574                 :     {
     575                 :         std::map<CPLString,OGREDIGEOAttributeDescriptor>::iterator it =
     576             214 :             mapAttributesSCD.find(objDesc.aosAttrRID[j]);
     577             214 :         if (it != mapAttributesSCD.end())
     578                 :         {
     579             214 :             const OGREDIGEOAttributeDescriptor& attrDesc = it->second;
     580                 :             const OGREDIGEOAttributeDef& attrDef =
     581             214 :                                     mapAttributes[attrDesc.osNameRID];
     582             214 :             OGRFieldType eType = OFTString;
     583             214 :             if (attrDef.osTYP == "R" || attrDef.osTYP == "E")
     584              38 :                 eType = OFTReal;
     585             176 :             else if (attrDef.osTYP == "I" || attrDef.osTYP == "N")
     586               0 :                 eType = OFTInteger;
     587                 : 
     588             214 :             poLayer->AddFieldDefn(attrDef.osLAB, eType, objDesc.aosAttrRID[j]);
     589                 :         }
     590                 :     }
     591                 : 
     592                 : 
     593              44 :     if (strcmp(poLayer->GetName(), "ID_S_OBJ_Z_1_2_2") == 0)
     594                 :     {
     595               2 :         OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn();
     596                 : 
     597               2 :         iATR = poFDefn->GetFieldIndex("ATR");
     598               2 :         iDI3 = poFDefn->GetFieldIndex("DI3");
     599               2 :         iDI4 = poFDefn->GetFieldIndex("DI4");
     600               2 :         iHEI = poFDefn->GetFieldIndex("HEI");
     601               2 :         iFON = poFDefn->GetFieldIndex("FON");
     602                 : 
     603               2 :         poLayer->AddFieldDefn("OGR_OBJ_LNK", OFTString, "");
     604               2 :         iOBJ_LNK = poFDefn->GetFieldIndex("OGR_OBJ_LNK");
     605                 : 
     606               4 :         poLayer->AddFieldDefn("OGR_OBJ_LNK_LAYER", OFTString, "");
     607               2 :         iOBJ_LNK_LAYER = poFDefn->GetFieldIndex("OGR_OBJ_LNK_LAYER");
     608                 : 
     609               4 :         poLayer->AddFieldDefn("OGR_ATR_VAL", OFTString, "");
     610               2 :         iATR_VAL = poFDefn->GetFieldIndex("OGR_ATR_VAL");
     611                 : 
     612               4 :         poLayer->AddFieldDefn("OGR_ANGLE", OFTReal, "");
     613               2 :         iANGLE = poFDefn->GetFieldIndex("OGR_ANGLE");
     614                 : 
     615               4 :         poLayer->AddFieldDefn("OGR_FONT_SIZE", OFTReal, "");
     616               2 :         iSIZE = poFDefn->GetFieldIndex("OGR_FONT_SIZE");
     617                 :     }
     618              42 :     else if (mapQAL.size() != 0)
     619                 :     {
     620              42 :         poLayer->AddFieldDefn("CREAT_DATE", OFTInteger, "");
     621              84 :         poLayer->AddFieldDefn("UPDATE_DATE", OFTInteger, "");
     622                 :     }
     623                 : 
     624              44 :     mapLayer[objDesc.osRID] = poLayer;
     625                 : 
     626                 :     papoLayers = (OGRLayer**)
     627              44 :         CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
     628              44 :     papoLayers[nLayers] = poLayer;
     629              44 :     nLayers ++;
     630                 : 
     631              44 :     return TRUE;
     632                 : }
     633                 : 
     634                 : /************************************************************************/
     635                 : /*                              ReadVEC()                               */
     636                 : /************************************************************************/
     637                 : 
     638               8 : int OGREDIGEODataSource::ReadVEC(const char* pszVECName)
     639                 : {
     640               8 :     VSILFILE* fp = OpenFile(pszVECName, "VEC");
     641               8 :     if (fp == NULL)
     642               0 :         return FALSE;
     643                 : 
     644                 :     const char* pszLine;
     645               8 :     CPLString osRTY, osRID;
     646               8 :     xyPairListType aXY;
     647               8 :     CPLString osLnkStartType, osLnkStartName, osLnkEndType, osLnkEndName;
     648               8 :     strListType osLnkEndNameList;
     649               8 :     CPLString osAttId;
     650               8 :     std::vector< strstrType > aosAttIdVal;
     651               8 :     CPLString osSCP;
     652               8 :     CPLString osQUP_RID;
     653               8 :     int bIso8859_1 = FALSE;
     654                 : 
     655          138164 :     while(TRUE)
     656                 :     {
     657          138172 :         pszLine = CPLReadLine2L(fp, 81, NULL);
     658                 : skip_read_next_line:
     659          146180 :         if (pszLine != NULL)
     660                 :         {
     661          146172 :             if (strlen(pszLine) < 8 || pszLine[7] != ':')
     662           22340 :                 continue;
     663                 :         }
     664                 : 
     665          135006 :         if (pszLine == NULL || strncmp(pszLine, "RTYSA", 5) == 0)
     666                 :         {
     667           11174 :             if (osRTY == "PAR")
     668                 :             {
     669            1488 :                 if (aXY.size() < 2)
     670                 :                     CPLDebug("EDIGEO", "Error: ARC %s has not enough points",
     671               0 :                                     osRID.c_str());
     672                 :                 else
     673            1488 :                     mapPAR[osRID] = aXY;
     674                 :             }
     675            9686 :             else if (osRTY == "LNK")
     676                 :             {
     677            6428 :                 if (osLnkStartType == "PAR" && osLnkEndType == "PFE")
     678                 :                 {
     679                 :                     /*CPLDebug("EDIGEO", "PFE[%s] -> PAR[%s]",
     680                 :                              osLnkEndName.c_str(), osLnkStartName.c_str());*/
     681            1882 :                     if (mapPFE_PAR.find(osLnkEndName) == mapPFE_PAR.end())
     682             570 :                         mapPFE_PAR[osLnkEndName].push_back(osLnkStartName);
     683                 :                     else
     684                 :                     {
     685            1312 :                         int bAlreadyExists = FALSE;
     686            1312 :                         strListType& osPARList = mapPFE_PAR[osLnkEndName];
     687           19644 :                         for(int j=0;j<(int)osPARList.size();j++)
     688                 :                         {
     689           18332 :                             if (osPARList[j] == osLnkStartName)
     690               0 :                                 bAlreadyExists = TRUE;
     691                 :                         }
     692            1312 :                         if (!bAlreadyExists)
     693            1312 :                             osPARList.push_back(osLnkStartName);
     694                 :                     }
     695                 :                 }
     696            4546 :                 else if (osLnkStartType == "FEA" && osLnkEndType == "PFE")
     697                 :                 {
     698                 :                     /*CPLDebug("EDIGEO", "FEA[%s] -> PFE[%s]",
     699                 :                              osLnkStartName.c_str(), osLnkEndName.c_str());*/
     700                 :                     listFEA_PFE.push_back(strstrType
     701             552 :                                                (osLnkStartName, osLnkEndName));
     702                 :                 }
     703            3994 :                 else if (osLnkStartType == "FEA" && osLnkEndType == "PAR")
     704                 :                 {
     705                 :                     /*CPLDebug("EDIGEO", "FEA[%s] -> PAR[%s]",
     706                 :                              osLnkStartName.c_str(), osLnkEndName.c_str());*/
     707                 :                     listFEA_PAR.push_back(std::pair<CPLString, strListType >
     708             298 :                                                 (osLnkStartName, osLnkEndNameList));
     709                 :                 }
     710            3696 :                 else if (osLnkStartType == "FEA" && osLnkEndType == "PNO")
     711                 :                 {
     712                 :                     /*CPLDebug("EDIGEO", "FEA[%s] -> PNO[%s]",
     713                 :                              osLnkStartName.c_str(), osLnkEndName.c_str());*/
     714                 :                     listFEA_PNO.push_back(strstrType
     715             652 :                                                 (osLnkStartName, osLnkEndName));
     716                 :                 }
     717            3044 :                 else if (osLnkStartType == "FEA" && osLnkEndType == "FEA")
     718                 :                 {
     719                 :                     /*CPLDebug("EDIGEO", "FEA[%s] -> FEA[%s]",
     720                 :                              osLnkStartName.c_str(), osLnkEndName.c_str());*/
     721            1400 :                     if (osSCP == "IS_S_REL_IWW")
     722             496 :                         mapFEA_FEA[osLnkStartName] = osLnkEndName;
     723                 :                 }
     724            1644 :                 else if (osLnkStartType == "PAR" && osLnkEndType == "PNO")
     725                 :                 {
     726                 :                 }
     727                 :                 else
     728                 :                 {
     729                 :                     CPLDebug("EDIGEO", "Unhandled LNK(%s) %s=%s --> %s=%s",
     730                 :                              osRID.c_str(),
     731                 :                              osLnkStartType.c_str(), osLnkStartName.c_str(),
     732               0 :                              osLnkEndType.c_str(), osLnkEndName.c_str());
     733                 :                 }
     734                 :             }
     735            3258 :             else if (osRTY == "FEA")
     736                 :             {
     737            1502 :                 OGREDIGEOFEADesc feaDesc;
     738            1502 :                 feaDesc.aosAttIdVal = aosAttIdVal;
     739            1502 :                 feaDesc.osSCP = osSCP;
     740            1502 :                 feaDesc.osQUP_RID = osQUP_RID;
     741            1502 :                 mapFEA[osRID] = feaDesc;
     742                 :             }
     743            1756 :             else if (osRTY == "PNO")
     744                 :             {
     745            1178 :                 if (aXY.size() == 1)
     746                 :                 {
     747                 :                     /*CPLDebug("EDIGEO", "PNO[%s] = %f, %f",
     748                 :                              osRID.c_str(), aXY[0].first, aXY[0].second);*/
     749            1178 :                     mapPNO[osRID] = aXY[0];
     750                 :                 }
     751                 :             }
     752           11174 :             if (pszLine == NULL)
     753                 :                 break;
     754           11166 :             osRTY = pszLine + 8;
     755           11166 :             osRID = "";
     756           11166 :             aXY.resize(0);
     757           11166 :             osLnkStartType = "";
     758           11166 :             osLnkStartName = "";
     759           11166 :             osLnkEndType = "";
     760           11166 :             osLnkEndName = "";
     761           11166 :             osAttId = "";
     762           11166 :             aosAttIdVal.resize(0);
     763           11166 :             osLnkEndNameList.resize(0);
     764           11166 :             osSCP = "";
     765           11166 :             osQUP_RID = "";
     766           11166 :             bIso8859_1 = FALSE;
     767                 :         }
     768          112666 :         else if (strncmp(pszLine, "RIDSA", 5) == 0)
     769           11166 :             osRID = pszLine + 8;
     770          101500 :         else if (strncmp(pszLine, "CORCC", 5) == 0)
     771                 :         {
     772           16018 :             const char* pszY = strchr(pszLine+8, ';');
     773           16018 :             if (pszY)
     774                 :             {
     775           16018 :                 double dfX = atof(pszLine + 8);
     776           16018 :                 double dfY = atof(pszY + 1);
     777           16018 :                 aXY.push_back(xyPairType (dfX, dfY));
     778                 :             }
     779                 :         }
     780           85482 :         else if (strncmp(pszLine, "FTPCP", 5) == 0)
     781                 :         {
     782           12998 :             char** papszTokens = CSLTokenizeString2(pszLine + 8, ";", 0);
     783           12998 :             if (CSLCount(papszTokens) == 4)
     784                 :             {
     785           12998 :                 if (osLnkStartType.size() == 0)
     786                 :                 {
     787            6428 :                     osLnkStartType = papszTokens[2];
     788            6428 :                     osLnkStartName = papszTokens[3];
     789                 :                 }
     790                 :                 else
     791                 :                 {
     792            6570 :                     osLnkEndType = papszTokens[2];
     793            6570 :                     osLnkEndName = papszTokens[3];
     794            6570 :                     osLnkEndNameList.push_back(osLnkEndName);
     795                 :                 }
     796                 :             }
     797           12998 :             CSLDestroy(papszTokens);
     798                 :         }
     799           72484 :         else if (strncmp(pszLine, "SCPCP", 5) == 0)
     800                 :         {
     801           11166 :             char** papszTokens = CSLTokenizeString2(pszLine + 8, ";", 0);
     802           11166 :             if (CSLCount(papszTokens) == 4)
     803                 :             {
     804           11166 :                 if (osRTY == "LNK")
     805                 :                 {
     806            6428 :                     if (strcmp(papszTokens[2], "ASS") == 0)
     807            1400 :                         osSCP = papszTokens[3];
     808                 :                 }
     809            4738 :                 else if (strcmp(papszTokens[2], "OBJ") == 0)
     810            1502 :                     osSCP = papszTokens[3];
     811                 :             }
     812           11166 :             CSLDestroy(papszTokens);
     813                 :         }
     814           61318 :         else if (strncmp(pszLine, "ATPCP", 5) == 0)
     815                 :         {
     816            8504 :             char** papszTokens = CSLTokenizeString2(pszLine + 8, ";", 0);
     817            8504 :             if (CSLCount(papszTokens) == 4)
     818                 :             {
     819            8504 :                 if (strcmp(papszTokens[2], "ATT") == 0)
     820            8504 :                     osAttId = papszTokens[3];
     821                 :             }
     822            8504 :             CSLDestroy(papszTokens);
     823                 :         }
     824           52814 :         else if (strcmp(pszLine, "TEXT 06:8859-1") == 0)
     825                 :         {
     826            1316 :             bIso8859_1 = TRUE;
     827                 :         }
     828           51498 :         else if (strncmp(pszLine, "ATVS", 4) == 0)
     829                 :         {
     830            8008 :             CPLString osAttVal = pszLine + 8;
     831            8008 :             int bSkipReadNextLine = FALSE;
     832               0 :             while(TRUE)
     833                 :             {
     834            8008 :                 pszLine = CPLReadLine2L(fp, 81, NULL);
     835           16016 :                 if (pszLine != NULL &&
     836                 :                     strlen(pszLine) >= 8 &&
     837            8008 :                     pszLine[7] == ':' &&
     838                 :                     strncmp(pszLine, "NEXT ", 5) == 0)
     839                 :                 {
     840               0 :                     osAttVal += pszLine + 8;
     841                 :                 }
     842                 :                 else
     843                 :                 {
     844            8008 :                     bSkipReadNextLine = TRUE;
     845                 :                     break;
     846                 :                 }
     847                 :             }
     848            9324 :             if (bIso8859_1 && bRecodeToUTF8)
     849                 :             {
     850                 :                 char* pszNewVal = CPLRecode(osAttVal.c_str(),
     851            1316 :                                             CPL_ENC_ISO8859_1, CPL_ENC_UTF8);
     852            1316 :                 osAttVal = pszNewVal;
     853            1316 :                 CPLFree(pszNewVal);
     854                 :             }
     855            6692 :             else if (bHasUTF8ContentOnly)
     856                 :             {
     857            6692 :                 bHasUTF8ContentOnly = CPLIsUTF8(osAttVal.c_str(), -1);
     858                 :             }
     859            8008 :             if (osAttId.size() != 0)
     860            8008 :                 aosAttIdVal.push_back( strstrType (osAttId, osAttVal) );
     861            8008 :             osAttId = "";
     862            8008 :             bIso8859_1 = FALSE;
     863            8008 :             if (bSkipReadNextLine)
     864               0 :                 goto skip_read_next_line;
     865                 :         }
     866           43490 :         else if (strncmp(pszLine, "ATVCP", 5) == 0)
     867                 :         {
     868             496 :             char** papszTokens = CSLTokenizeString2(pszLine + 8, ";", 0);
     869             496 :             if (CSLCount(papszTokens) == 4)
     870                 :             {
     871             496 :                 if (strcmp(papszTokens[2], "ATT") == 0)
     872                 :                 {
     873             496 :                     CPLString osAttVal = papszTokens[3];
     874             496 :                     if (osAttId.size() != 0)
     875             496 :                         aosAttIdVal.push_back( strstrType (osAttId, osAttVal) );
     876             496 :                     osAttId = "";
     877                 :                 }
     878                 :             }
     879             496 :             CSLDestroy(papszTokens);
     880                 :         }
     881           42994 :         else if (strncmp(pszLine, "QAPCP", 5) == 0)
     882                 :         {
     883            1006 :             char** papszTokens = CSLTokenizeString2(pszLine + 8, ";", 0);
     884            1006 :             if (CSLCount(papszTokens) == 4)
     885                 :             {
     886            1006 :                 if (strcmp(papszTokens[2], "QUP") == 0)
     887                 :                 {
     888            1006 :                     osQUP_RID = papszTokens[3];
     889                 :                 }
     890                 :             }
     891            1006 :             CSLDestroy(papszTokens);
     892                 :         }
     893                 :     }
     894                 : 
     895               8 :     VSIFCloseL(fp);
     896                 : 
     897               8 :     return TRUE;
     898                 : }
     899                 : 
     900                 : /************************************************************************/
     901                 : /*                        CreateFeature()                               */
     902                 : /************************************************************************/
     903                 : 
     904            1502 : OGRFeature* OGREDIGEODataSource::CreateFeature(const CPLString& osFEA)
     905                 : {
     906                 :     const std::map< CPLString, OGREDIGEOFEADesc >::iterator itFEA =
     907            1502 :                                                         mapFEA.find(osFEA);
     908            1502 :     if (itFEA == mapFEA.end())
     909                 :     {
     910               0 :         CPLDebug("EDIGEO", "ERROR: Cannot find FEA %s", osFEA.c_str());
     911               0 :         return NULL;
     912                 :     }
     913                 : 
     914            1502 :     const OGREDIGEOFEADesc& fea = itFEA->second;
     915                 :     const std::map<CPLString,OGREDIGEOLayer*>::iterator itLyr =
     916            1502 :                                                     mapLayer.find(fea.osSCP);
     917            1502 :     if (itLyr != mapLayer.end())
     918                 :     {
     919            1502 :         OGREDIGEOLayer* poLayer = itLyr->second;
     920                 : 
     921            1502 :         OGRFeature* poFeature = new OGRFeature(poLayer->GetLayerDefn());
     922            1502 :         poFeature->SetField(0, itFEA->first.c_str());
     923           10006 :         for(int i=0;i<(int)fea.aosAttIdVal.size();i++)
     924                 :         {
     925            8504 :             const CPLString& id = fea.aosAttIdVal[i].first;
     926            8504 :             const CPLString& val = fea.aosAttIdVal[i].second;
     927            8504 :             int iIndex = poLayer->GetAttributeIndex(id);
     928            8504 :             if (iIndex != -1)
     929            8504 :                 poFeature->SetField(iIndex, val.c_str());
     930                 :             else
     931                 :                 CPLDebug("EDIGEO",
     932               0 :                          "ERROR: Cannot find attribute %s", id.c_str());
     933                 :         }
     934                 : 
     935            1502 :         if (strcmp(poLayer->GetName(), "ID_S_OBJ_Z_1_2_2") != 0 &&
     936                 :             mapQAL.size() != 0 && fea.osQUP_RID.size() != 0)
     937                 :         {
     938                 :             const std::map<CPLString, intintType>::iterator itQAL =
     939            1006 :                                                         mapQAL.find(fea.osQUP_RID);
     940            1006 :             if (itQAL != mapQAL.end())
     941                 :             {
     942            1004 :                 const intintType& creationUpdateDate = itQAL->second;
     943            1004 :                 if (creationUpdateDate.first != 0)
     944            1004 :                     poFeature->SetField("CREAT_DATE", creationUpdateDate.first);
     945            1004 :                 if (creationUpdateDate.second != 0)
     946            1004 :                     poFeature->SetField("UPDATE_DATE", creationUpdateDate.second);
     947                 :             }
     948                 :         }
     949                 : 
     950            1502 :         poLayer->AddFeature(poFeature);
     951                 : 
     952            1502 :         return poFeature;
     953                 :     }
     954                 :     else
     955                 :     {
     956               0 :         CPLDebug("EDIGEO", "ERROR: Cannot find layer %s", fea.osSCP.c_str());
     957               0 :         return NULL;
     958                 :     }
     959                 : }
     960                 : 
     961                 : /************************************************************************/
     962                 : /*                             SetStyle()                               */
     963                 : /************************************************************************/
     964                 : 
     965             652 : int OGREDIGEODataSource::SetStyle(const CPLString& osFEA,
     966                 :                                   OGRFeature* poFeature)
     967                 : {
     968                 :     /* EDIGEO PCI specific */
     969                 :     /* See EDIGeO_PCI.pdf, chapter 3 "Principes généraux de */
     970                 :     /* positionnement de la toponymie. */
     971             652 :     const char* pszATR = NULL;
     972             652 :     if (strcmp(poFeature->GetDefnRef()->GetName(), "ID_S_OBJ_Z_1_2_2") == 0 &&
     973                 :         iATR != -1 && (pszATR = poFeature->GetFieldAsString(iATR)) != NULL)
     974                 :     {
     975             496 :         const CPLString osATR = pszATR;
     976                 :         std::map< CPLString, CPLString>::iterator itFEA_FEA =
     977             496 :                                                 mapFEA_FEA.find(osFEA);
     978             496 :         if (itFEA_FEA != mapFEA_FEA.end())
     979                 :         {
     980             496 :             const CPLString& osOBJ_LNK = itFEA_FEA->second;
     981                 :             std::map< CPLString, OGREDIGEOFEADesc >::iterator itFEA_LNK =
     982             496 :                                                         mapFEA.find(osOBJ_LNK);
     983             496 :             if (itFEA_LNK != mapFEA.end())
     984                 :             {
     985             496 :                 const OGREDIGEOFEADesc& fea_lnk = itFEA_LNK->second;
     986            1084 :                 for(int j=0;j<(int)fea_lnk.aosAttIdVal.size();j++)
     987                 :                 {
     988            1084 :                     if (fea_lnk.aosAttIdVal[j].first == osATR)
     989                 :                     {
     990             496 :                         double dfAngle = 0;
     991             496 :                         if (iDI3 != -1 && iDI4 != -1)
     992                 :                         {
     993                 :                             double dfBaseVectorX =
     994             496 :                                 poFeature->GetFieldAsDouble(iDI3);
     995                 :                             double dfBaseVectorY =
     996             496 :                                 poFeature->GetFieldAsDouble(iDI4);
     997                 :                             dfAngle = atan2(dfBaseVectorY, dfBaseVectorX)
     998             496 :                                                                 / M_PI * 180;
     999             496 :                             if (dfAngle < 0)
    1000              84 :                                 dfAngle += 360;
    1001                 :                         }
    1002             496 :                         double dfSize = 1;
    1003             496 :                         if (iHEI != -1)
    1004             496 :                             dfSize = poFeature->GetFieldAsDouble(iHEI);
    1005             496 :                         if (dfSize <= 0 || dfSize >= 100)
    1006               0 :                             dfSize = 1;
    1007             496 :                         const char* pszFontFamily = NULL;
    1008             496 :                         if (iFON != -1)
    1009             496 :                             pszFontFamily = poFeature->GetFieldAsString(iFON);
    1010                 : 
    1011             496 :                         CPLString osStyle("LABEL(t:\"");
    1012             496 :                         osStyle += fea_lnk.aosAttIdVal[j].second;
    1013             496 :                         osStyle += "\"";
    1014             496 :                         if (dfAngle != 0)
    1015                 :                         {
    1016             228 :                             osStyle += ",a:";
    1017             228 :                             osStyle += CPLString().Printf("%.1f", dfAngle);
    1018                 :                         }
    1019             496 :                         if (pszFontFamily != NULL && bIncludeFontFamily)
    1020                 :                         {
    1021             496 :                             osStyle += ",f:\"";
    1022             496 :                             osStyle += pszFontFamily;
    1023             496 :                             osStyle += "\"";
    1024                 :                         }
    1025             496 :                         osStyle += ",s:";
    1026             496 :                         osStyle += CPLString().Printf("%.1f", dfSize);
    1027             496 :                         osStyle += ",c:#000000)";
    1028             496 :                         poFeature->SetStyleString(osStyle);
    1029                 : 
    1030                 :                         poFeature->SetField(iATR_VAL,
    1031             496 :                                             fea_lnk.aosAttIdVal[j].second);
    1032             496 :                         poFeature->SetField(iANGLE, dfAngle);
    1033             496 :                         poFeature->SetField(iSIZE, dfSize * dfSizeFactor);
    1034             496 :                         poFeature->SetField(iOBJ_LNK, osOBJ_LNK);
    1035             496 :                         poFeature->SetField(iOBJ_LNK_LAYER, fea_lnk.osSCP);
    1036                 : 
    1037             496 :                         setLayersWithLabels.insert(fea_lnk.osSCP);
    1038                 : 
    1039             496 :                         break;
    1040                 :                     }
    1041                 :                 }
    1042                 :             }
    1043             496 :         }
    1044                 :     }
    1045                 : 
    1046             652 :     return TRUE;
    1047                 : }
    1048                 : 
    1049                 : /************************************************************************/
    1050                 : /*                           BuildPoints()                              */
    1051                 : /************************************************************************/
    1052                 : 
    1053               8 : int OGREDIGEODataSource::BuildPoints()
    1054                 : {
    1055             660 :     for(int i=0;i<(int)listFEA_PNO.size();i++)
    1056                 :     {
    1057             652 :         const CPLString& osFEA = listFEA_PNO[i].first;
    1058             652 :         const CPLString& osPNO = listFEA_PNO[i].second;
    1059                 :         const std::map< CPLString, xyPairType >::iterator itPNO =
    1060             652 :                                                         mapPNO.find(osPNO);
    1061             652 :         if (itPNO == mapPNO.end())
    1062                 :         {
    1063               0 :             CPLDebug("EDIGEO", "Cannot find PNO %s", osPNO.c_str());
    1064                 :         }
    1065                 :         else
    1066                 :         {
    1067             652 :             OGRFeature* poFeature = CreateFeature(osFEA);
    1068             652 :             if (poFeature)
    1069                 :             {
    1070             652 :                 const xyPairType& pno = itPNO->second;
    1071             652 :                 OGRPoint* poPoint = new OGRPoint(pno.first, pno.second);
    1072             652 :                 if (poSRS)
    1073             652 :                     poPoint->assignSpatialReference(poSRS);
    1074             652 :                 poFeature->SetGeometryDirectly(poPoint);
    1075                 : 
    1076             652 :                 SetStyle(osFEA, poFeature);
    1077                 :             }
    1078                 :         }
    1079                 :     }
    1080                 : 
    1081               8 :     return TRUE;
    1082                 : }
    1083                 : 
    1084                 : /************************************************************************/
    1085                 : /*                        BuildLineStrings()                            */
    1086                 : /************************************************************************/
    1087                 : 
    1088               8 : int OGREDIGEODataSource::BuildLineStrings()
    1089                 : {
    1090                 :     int i, iter;
    1091                 : 
    1092             306 :     for(iter=0;iter<(int)listFEA_PAR.size();iter++)
    1093                 :     {
    1094             298 :         const CPLString& osFEA = listFEA_PAR[iter].first;
    1095             298 :         const strListType & aosPAR = listFEA_PAR[iter].second;
    1096             298 :         OGRFeature* poFeature = CreateFeature(osFEA);
    1097             298 :         if (poFeature)
    1098                 :         {
    1099             298 :             OGRMultiLineString* poMulti = NULL;
    1100             726 :             for(int k=0;k<(int)aosPAR.size();k++)
    1101                 :             {
    1102                 :                 const std::map< CPLString, xyPairListType >::iterator itPAR =
    1103             428 :                                                     mapPAR.find(aosPAR[k]);
    1104             428 :                 if (itPAR != mapPAR.end())
    1105                 :                 {
    1106             428 :                     const xyPairListType& arc = itPAR->second;
    1107                 : 
    1108             428 :                     OGRLineString* poLS = new OGRLineString();
    1109             428 :                     poLS->setNumPoints((int)arc.size());
    1110            3270 :                     for(i=0;i<(int)arc.size();i++)
    1111                 :                     {
    1112            2842 :                         poLS->setPoint(i, arc[i].first, arc[i].second);
    1113                 :                     }
    1114                 : 
    1115             428 :                     if (poFeature->GetGeometryRef() != NULL)
    1116                 :                     {
    1117             130 :                         if (poMulti == NULL)
    1118                 :                         {
    1119                 :                             OGRLineString* poPrevLS =
    1120              72 :                                 (OGRLineString*) poFeature->StealGeometry();
    1121              72 :                             poMulti = new OGRMultiLineString();
    1122              72 :                             poMulti->addGeometryDirectly(poPrevLS);
    1123              72 :                             poFeature->SetGeometryDirectly(poMulti);
    1124                 :                         }
    1125             130 :                         poMulti->addGeometryDirectly(poLS);
    1126                 :                     }
    1127                 :                     else
    1128             298 :                         poFeature->SetGeometryDirectly(poLS);
    1129                 :                 }
    1130                 :                 else
    1131                 :                     CPLDebug("EDIGEO",
    1132               0 :                              "ERROR: Cannot find ARC %s", aosPAR[k].c_str());
    1133                 :             }
    1134             298 :             if (poFeature->GetGeometryRef())
    1135             298 :                 poFeature->GetGeometryRef()->assignSpatialReference(poSRS);
    1136                 :         }
    1137                 :     }
    1138                 : 
    1139               8 :     return TRUE;
    1140                 : }
    1141                 : 
    1142                 : /************************************************************************/
    1143                 : /*                           BuildPolygon()                             */
    1144                 : /************************************************************************/
    1145                 : 
    1146             552 : int OGREDIGEODataSource::BuildPolygon(const CPLString& osFEA,
    1147                 :                                       const CPLString& osPFE)
    1148                 : {
    1149                 :     int i;
    1150                 : 
    1151                 :     const std::map< CPLString, strListType >::iterator itPFE_PAR =
    1152             552 :                                                     mapPFE_PAR.find(osPFE);
    1153             552 :     if (itPFE_PAR == mapPFE_PAR.end())
    1154                 :     {
    1155               0 :         CPLDebug("EDIGEO", "ERROR: Cannot find PFE %s", osPFE.c_str());
    1156               0 :         return FALSE;
    1157                 :     }
    1158                 : 
    1159             552 :     const strListType & aosPARList = itPFE_PAR->second;
    1160                 : 
    1161                 : /* -------------------------------------------------------------------- */
    1162                 : /*      Resolve arc ids to arc coordinate lists.                        */
    1163                 : /* -------------------------------------------------------------------- */
    1164             552 :     std::vector< const xyPairListType *> aoPARPtrList;
    1165            2156 :     for(i=0;i<(int)aosPARList.size();i++)
    1166                 :     {
    1167                 :         const std::map< CPLString, xyPairListType >::iterator itPAR =
    1168            1604 :                                             mapPAR.find(aosPARList[i]);
    1169            1604 :         if (itPAR != mapPAR.end())
    1170            1604 :             aoPARPtrList.push_back(&(itPAR->second));
    1171                 :         else
    1172                 :             CPLDebug("EDIGEO",
    1173               0 :                      "ERROR: Cannot find ARC %s", aosPARList[i].c_str());
    1174                 :     }
    1175                 : 
    1176             552 :     if (aoPARPtrList.size() == 0)
    1177               0 :         return FALSE;
    1178                 : 
    1179                 : /* -------------------------------------------------------------------- */
    1180                 : /*      Now try to chain all arcs together.                             */
    1181                 : /* -------------------------------------------------------------------- */
    1182             552 :     std::vector<xyPairListType> aoXYList;
    1183                 : 
    1184                 :     int j;
    1185            1104 :     for(j=0;j<(int)aoPARPtrList.size();j++)
    1186                 :     {
    1187            1604 :         if (aoPARPtrList[j] == NULL)
    1188            1052 :             continue;
    1189             552 :         const xyPairListType& sFirstRing = *(aoPARPtrList[j]);
    1190             552 :         const xyPairType* psNext = &(sFirstRing[sFirstRing.size()-1]);
    1191                 : 
    1192             552 :         xyPairListType aoXY;
    1193            9710 :         for(i=0;i<(int)sFirstRing.size();i++)
    1194            9158 :             aoXY.push_back(sFirstRing[i]);
    1195             552 :         aoPARPtrList[j] = NULL;
    1196                 : 
    1197             552 :         int nIter = 1;
    1198            2156 :         while(aoXY[aoXY.size()-1] != aoXY[0] && nIter < (int)aoPARPtrList.size())
    1199                 :         {
    1200            1052 :             int bFound = FALSE;
    1201            1052 :             int bReverseSecond = FALSE;
    1202            3842 :             for(i=0;i<(int)aoPARPtrList.size();i++)
    1203                 :             {
    1204            3842 :                 if (aoPARPtrList[i] != NULL)
    1205                 :                 {
    1206            2034 :                     const xyPairListType& sSecondRing = *(aoPARPtrList[i]);
    1207            2034 :                     if (*psNext == sSecondRing[0])
    1208                 :                     {
    1209             518 :                         bFound = TRUE;
    1210             518 :                         bReverseSecond = FALSE;
    1211             518 :                         break;
    1212                 :                     }
    1213            1516 :                     else if (*psNext == sSecondRing[sSecondRing.size()-1])
    1214                 :                     {
    1215             534 :                         bFound = TRUE;
    1216             534 :                         bReverseSecond = TRUE;
    1217             534 :                         break;
    1218                 :                     }
    1219                 :                 }
    1220                 :             }
    1221                 : 
    1222            1052 :             if (!bFound)
    1223                 :             {
    1224                 :                 CPLDebug("EDIGEO", "Cannot find ring for FEA %s / PFE %s",
    1225               0 :                         osFEA.c_str(), osPFE.c_str());
    1226               0 :                 break;
    1227                 :             }
    1228                 :             else
    1229                 :             {
    1230            1052 :                 const xyPairListType& secondRing = *(aoPARPtrList[i]);
    1231            1052 :                 aoPARPtrList[i] = NULL;
    1232            1052 :                 if (!bReverseSecond)
    1233                 :                 {
    1234            1836 :                     for(i=1;i<(int)secondRing.size();i++)
    1235            1318 :                         aoXY.push_back(secondRing[i]);
    1236             518 :                     psNext = &secondRing[secondRing.size()-1];
    1237                 :                 }
    1238                 :                 else
    1239                 :                 {
    1240            2114 :                     for(i=1;i<(int)secondRing.size();i++)
    1241            1580 :                         aoXY.push_back(secondRing[secondRing.size()-1-i]);
    1242             534 :                     psNext = &secondRing[0];
    1243                 :                 }
    1244                 :             }
    1245                 : 
    1246            1052 :             nIter ++;
    1247                 :         }
    1248                 : 
    1249             552 :         aoXYList.push_back(aoXY);
    1250                 :     }
    1251                 : 
    1252                 : /* -------------------------------------------------------------------- */
    1253                 : /*      Create feature.                                                 */
    1254                 : /* -------------------------------------------------------------------- */
    1255             552 :     OGRFeature* poFeature = CreateFeature(osFEA);
    1256             552 :     if (poFeature)
    1257                 :     {
    1258             552 :         std::vector<OGRGeometry*> aosPolygons;
    1259            1104 :         for(j=0;j<(int)aoXYList.size();j++)
    1260                 :         {
    1261             552 :             const xyPairListType& aoXY = aoXYList[j];
    1262             552 :             OGRLinearRing* poLS = new OGRLinearRing();
    1263            1104 :             poLS->setNumPoints((int)aoXY.size());
    1264           12608 :             for(i=0;i<(int)aoXY.size();i++)
    1265           12056 :                 poLS->setPoint(i, aoXY[i].first, aoXY[i].second);
    1266             552 :             poLS->closeRings();
    1267             552 :             OGRPolygon* poPolygon = new OGRPolygon();
    1268             552 :             poPolygon->addRingDirectly(poLS);
    1269             552 :             aosPolygons.push_back(poPolygon);
    1270                 :         }
    1271                 : 
    1272                 :         int bIsValidGeometry;
    1273                 :         OGRGeometry* poGeom = OGRGeometryFactory::organizePolygons(
    1274                 :             &aosPolygons[0], (int)aosPolygons.size(),
    1275             552 :             &bIsValidGeometry, NULL);
    1276             552 :         if (poGeom)
    1277                 :         {
    1278             552 :             if (poSRS)
    1279             552 :                 poGeom->assignSpatialReference(poSRS);
    1280             552 :             poFeature->SetGeometryDirectly(poGeom);
    1281             552 :         }
    1282                 :     }
    1283                 : 
    1284             552 :     return TRUE;
    1285                 : }
    1286                 : 
    1287                 : /************************************************************************/
    1288                 : /*                          BuildPolygons()                             */
    1289                 : /************************************************************************/
    1290                 : 
    1291               8 : int OGREDIGEODataSource::BuildPolygons()
    1292                 : {
    1293                 :     int iter;
    1294             560 :     for(iter=0;iter<(int)listFEA_PFE.size();iter++)
    1295                 :     {
    1296             552 :         const CPLString& osFEA = listFEA_PFE[iter].first;
    1297             552 :         const CPLString& osPFE = listFEA_PFE[iter].second;
    1298             552 :         BuildPolygon(osFEA, osPFE);
    1299                 :     }
    1300                 : 
    1301               8 :     return TRUE;
    1302                 : }
    1303                 : 
    1304                 : /************************************************************************/
    1305                 : /*                  OGREDIGEOSortForQGIS()                              */
    1306                 : /************************************************************************/
    1307                 : 
    1308              94 : static int OGREDIGEOSortForQGIS(const void* a, const void* b)
    1309                 : {
    1310              94 :     OGREDIGEOLayer* poLayerA = *((OGREDIGEOLayer**) a);
    1311              94 :     OGREDIGEOLayer* poLayerB = *((OGREDIGEOLayer**) b);
    1312                 :     int nTypeA, nTypeB;
    1313              94 :     switch (poLayerA->GetLayerDefn()->GetGeomType())
    1314                 :     {
    1315              28 :         case wkbPoint: nTypeA = 1; break;
    1316              12 :         case wkbLineString: nTypeA = 2; break;
    1317              54 :         case wkbPolygon: nTypeA = 3; break;
    1318               0 :         default: nTypeA = 4; break;
    1319                 :     }
    1320              94 :     switch (poLayerB->GetLayerDefn()->GetGeomType())
    1321                 :     {
    1322              22 :         case wkbPoint: nTypeB = 1; break;
    1323              14 :         case wkbLineString: nTypeB = 2; break;
    1324              58 :         case wkbPolygon: nTypeB = 3; break;
    1325               0 :         default: nTypeB = 4; break;
    1326                 :     }
    1327              94 :     if (nTypeA == nTypeB)
    1328                 :     {
    1329              58 :         int nCmp = strcmp(poLayerA->GetName(), poLayerB->GetName());
    1330              58 :         if (nCmp == 0)
    1331               0 :             return 0;
    1332                 : 
    1333                 :         static const char* apszPolyOrder[] =
    1334                 :             { "COMMUNE_id", "LIEUDIT_id", "SECTION_id", "SUBDSECT_id",
    1335                 :               "SUBDFISC_id", "PARCELLE_id", "BATIMENT_id" };
    1336             288 :         for(int i=0;i<(int)(sizeof(apszPolyOrder)/sizeof(char*));i++)
    1337                 :         {
    1338             268 :             if (strcmp(poLayerA->GetName(), apszPolyOrder[i]) == 0)
    1339              22 :                 return -1;
    1340             246 :             if (strcmp(poLayerB->GetName(), apszPolyOrder[i]) == 0)
    1341              16 :                 return 1;
    1342                 :         }
    1343              20 :         return nCmp;
    1344                 :     }
    1345                 :     else
    1346              36 :         return nTypeB - nTypeA;
    1347                 : }
    1348                 : 
    1349                 : /************************************************************************/
    1350                 : /*                                Open()                                */
    1351                 : /************************************************************************/
    1352                 : 
    1353             196 : int OGREDIGEODataSource::Open( const char * pszFilename, int bUpdateIn)
    1354                 : 
    1355                 : {
    1356             196 :     if (bUpdateIn)
    1357                 :     {
    1358              26 :         return FALSE;
    1359                 :     }
    1360                 : 
    1361             170 :     pszName = CPLStrdup( pszFilename );
    1362                 : 
    1363                 : /* -------------------------------------------------------------------- */
    1364                 : /*      Does this appear to be a .THF file?                             */
    1365                 : /* -------------------------------------------------------------------- */
    1366             170 :     if( !EQUAL(CPLGetExtension(pszFilename), "thf") )
    1367             168 :         return FALSE;
    1368                 : 
    1369               2 :     fpTHF = VSIFOpenL(pszFilename, "rb");
    1370               2 :     if (fpTHF == NULL)
    1371               0 :         return FALSE;
    1372                 : 
    1373                 :     const char* pszLine;
    1374               2 :     int i = 0;
    1375               2 :     int bIsEDIGEO = FALSE;
    1376              10 :     while(i < 100 && (pszLine = CPLReadLine2L(fpTHF, 81, NULL)) != NULL)
    1377                 :     {
    1378               8 :         if (strcmp(pszLine, "RTYSA03:GTS") == 0)
    1379                 :         {
    1380               2 :             bIsEDIGEO = TRUE;
    1381               2 :             break;
    1382                 :         }
    1383               6 :         i++;
    1384                 :     }
    1385                 : 
    1386               2 :     if (!bIsEDIGEO)
    1387                 :     {
    1388               0 :         VSIFCloseL(fpTHF);
    1389               0 :         fpTHF = NULL;
    1390               0 :         return FALSE;
    1391                 :     }
    1392                 : 
    1393               2 :     return TRUE;
    1394                 : }
    1395                 : 
    1396                 : /************************************************************************/
    1397                 : /*                           ReadEDIGEO()                               */
    1398                 : /************************************************************************/
    1399                 : 
    1400             798 : void OGREDIGEODataSource::ReadEDIGEO()
    1401                 : {
    1402             798 :     if (bHasReadEDIGEO)
    1403             796 :         return;
    1404                 : 
    1405               2 :     bHasReadEDIGEO = TRUE;
    1406                 : 
    1407                 : /* -------------------------------------------------------------------- */
    1408                 : /*      Read .THF file                                                  */
    1409                 : /* -------------------------------------------------------------------- */
    1410               2 :     VSIFSeekL(fpTHF, 0, SEEK_SET);
    1411               2 :     if (!ReadTHF(fpTHF))
    1412                 :     {
    1413               0 :         VSIFCloseL(fpTHF);
    1414               0 :         fpTHF = NULL;
    1415               0 :         return;
    1416                 :     }
    1417               2 :     VSIFCloseL(fpTHF);
    1418               2 :     fpTHF = NULL;
    1419                 : 
    1420                 : /* -------------------------------------------------------------------- */
    1421                 : /*      Read .GEO file                                                  */
    1422                 : /* -------------------------------------------------------------------- */
    1423               2 :     if (!ReadGEO())
    1424               0 :         return;
    1425                 : 
    1426                 : /* -------------------------------------------------------------------- */
    1427                 : /*      Read .GEN file                                                  */
    1428                 : /* -------------------------------------------------------------------- */
    1429               2 :     if (osGNN.size() != 0)
    1430               2 :         ReadGEN();
    1431                 : 
    1432                 : /* -------------------------------------------------------------------- */
    1433                 : /*      Read .DIC file                                                  */
    1434                 : /* -------------------------------------------------------------------- */
    1435               2 :     if (!ReadDIC())
    1436               0 :         return;
    1437                 : 
    1438                 : /* -------------------------------------------------------------------- */
    1439                 : /*      Read .SCD file                                                  */
    1440                 : /* -------------------------------------------------------------------- */
    1441               2 :     if (!ReadSCD())
    1442               0 :         return;
    1443                 : 
    1444                 : /* -------------------------------------------------------------------- */
    1445                 : /*      Read .QAL file                                                  */
    1446                 : /* -------------------------------------------------------------------- */
    1447               2 :     if (osQAN.size() != 0)
    1448               2 :         ReadQAL();
    1449                 : 
    1450                 : /* -------------------------------------------------------------------- */
    1451                 : /*      Create layers from SCD definitions                              */
    1452                 : /* -------------------------------------------------------------------- */
    1453                 :     int i;
    1454              46 :     for(i=0;i<(int)aoObjList.size();i++)
    1455                 :     {
    1456              44 :         CreateLayerFromObjectDesc(aoObjList[i]);
    1457                 :     }
    1458                 : 
    1459                 : /* -------------------------------------------------------------------- */
    1460                 : /*      Read .VEC files and create features                             */
    1461                 : /* -------------------------------------------------------------------- */
    1462              10 :     for(i=0;i<(int)aosGDN.size();i++)
    1463                 :     {
    1464               8 :         ReadVEC(aosGDN[i]);
    1465                 : 
    1466               8 :         BuildPoints();
    1467               8 :         BuildLineStrings();
    1468               8 :         BuildPolygons();
    1469                 : 
    1470               8 :         mapPNO.clear();
    1471               8 :         mapPAR.clear();
    1472               8 :         mapFEA.clear();
    1473               8 :         mapPFE_PAR.clear();
    1474               8 :         listFEA_PFE.clear();
    1475               8 :         listFEA_PAR.clear();
    1476               8 :         listFEA_PNO.clear();
    1477               8 :         mapFEA_FEA.clear();
    1478                 :     }
    1479                 : 
    1480               2 :     mapObjects.clear();
    1481               2 :     mapAttributes.clear();
    1482               2 :     mapAttributesSCD.clear();
    1483               2 :     mapQAL.clear();
    1484                 : 
    1485                 : /* -------------------------------------------------------------------- */
    1486                 : /*      Delete empty layers                                             */
    1487                 : /* -------------------------------------------------------------------- */
    1488              48 :     for(i=0;i<nLayers;/*nothing*/)
    1489                 :     {
    1490              44 :         if (papoLayers[i]->GetFeatureCount(TRUE) == 0)
    1491                 :         {
    1492              10 :             delete papoLayers[i];
    1493              10 :             if (i < nLayers - 1)
    1494                 :                 memmove(papoLayers + i, papoLayers + i + 1,
    1495              10 :                         (nLayers - i - 1) * sizeof(OGREDIGEOLayer*));
    1496              10 :             nLayers --;
    1497                 :         }
    1498                 :         else
    1499              34 :             i++;
    1500                 :     }
    1501                 : 
    1502                 : /* -------------------------------------------------------------------- */
    1503                 : /*      When added from QGIS, the layers must be ordered from           */
    1504                 : /*      bottom (Polygon) to top (Point) to get nice visual effect       */
    1505                 : /* -------------------------------------------------------------------- */
    1506               2 :     if (CSLTestBoolean(CPLGetConfigOption("OGR_EDIGEO_SORT_FOR_QGIS", "YES")))
    1507               2 :         qsort(papoLayers, nLayers, sizeof(OGREDIGEOLayer*), OGREDIGEOSortForQGIS);
    1508                 : 
    1509                 : /* -------------------------------------------------------------------- */
    1510                 : /*      Create a label layer for each feature layer                     */
    1511                 : /* -------------------------------------------------------------------- */
    1512               2 :     if (CSLTestBoolean(CPLGetConfigOption("OGR_EDIGEO_CREATE_LABEL_LAYERS", "YES")))
    1513               2 :         CreateLabelLayers();
    1514                 : 
    1515               2 :     return;
    1516                 : }
    1517                 : 
    1518                 : /************************************************************************/
    1519                 : /*                         CreateLabelLayers()                          */
    1520                 : /************************************************************************/
    1521                 : 
    1522               2 : void OGREDIGEODataSource::CreateLabelLayers()
    1523                 : {
    1524               2 :     OGRLayer* poLayer = GetLayerByName("ID_S_OBJ_Z_1_2_2");
    1525               2 :     if (poLayer == NULL)
    1526               0 :         return;
    1527                 : 
    1528               2 :     std::map<CPLString, OGREDIGEOLayer*> mapLayerNameToLayer;
    1529                 : 
    1530                 :     OGRFeature* poFeature;
    1531               2 :     OGRFeatureDefn* poFeatureDefn = poLayer->GetLayerDefn();
    1532             500 :     while((poFeature = poLayer->GetNextFeature()) != NULL)
    1533                 :     {
    1534                 :         const char* pszBelongingLayerName =
    1535             496 :             poFeature->GetFieldAsString(iOBJ_LNK_LAYER);
    1536             496 :         if (pszBelongingLayerName)
    1537                 :         {
    1538             496 :             CPLString osBelongingLayerName = pszBelongingLayerName;
    1539                 :             std::map<CPLString, OGREDIGEOLayer*>::iterator it =
    1540             496 :                         mapLayerNameToLayer.find(osBelongingLayerName);
    1541                 :             OGREDIGEOLayer* poLabelLayer;
    1542                 : 
    1543             496 :             if (it == mapLayerNameToLayer.end())
    1544                 :             {
    1545                 :                 /* Create label layer if it does not already exist */
    1546              14 :                 CPLString osLayerLabelName = osBelongingLayerName + "_LABEL";
    1547                 :                 poLabelLayer = new OGREDIGEOLayer(this, osLayerLabelName.c_str(),
    1548              14 :                                              wkbPoint, poSRS);
    1549                 :                 int i;
    1550              28 :                 OGRFeatureDefn* poLabelFeatureDefn = poLabelLayer->GetLayerDefn();
    1551             280 :                 for(i=0;i<poFeatureDefn->GetFieldCount();i++)
    1552             266 :                     poLabelFeatureDefn->AddFieldDefn(poFeatureDefn->GetFieldDefn(i));
    1553              14 :                 mapLayerNameToLayer[osBelongingLayerName] = poLabelLayer;
    1554                 : 
    1555                 :                 papoLayers = (OGRLayer**)
    1556              14 :                     CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
    1557              14 :                 papoLayers[nLayers] = poLabelLayer;
    1558              14 :                 nLayers ++;
    1559                 :             }
    1560                 :             else
    1561             482 :                 poLabelLayer = mapLayerNameToLayer[osBelongingLayerName];
    1562                 : 
    1563             496 :             OGRFeature* poNewFeature = new OGRFeature(poLabelLayer->GetLayerDefn());
    1564             496 :             poNewFeature->SetFrom(poFeature);
    1565             496 :             poLabelLayer->AddFeature(poNewFeature);
    1566                 :         }
    1567             496 :         delete poFeature;
    1568                 :     }
    1569                 : 
    1570               2 :     poLayer->ResetReading();
    1571                 : }
    1572                 : 

Generated by: LCOV version 1.7