LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/ili - ili2reader.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 436 3 0.7 %
Date: 2011-12-18 Functions: 37 1 2.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: ili2reader.cpp 15947 2008-12-13 22:53:24Z rouault $
       3                 :  *
       4                 :  * Project:  Interlis 2 Reader
       5                 :  * Purpose:  Implementation of ILI2Reader class.
       6                 :  * Author:   Markus Schnider, Sourcepole AG
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2004, Pirmin Kalberer, Sourcepole AG
      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_ili2.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : 
      34                 : #include "ilihelper.h"
      35                 : #include "iomhelper.h"
      36                 : #include "ili2reader.h"
      37                 : #include "ili2readerp.h"
      38                 : 
      39                 : using namespace std;
      40                 : 
      41                 : CPL_CVSID("$Id: ili2reader.cpp 15947 2008-12-13 22:53:24Z rouault $");
      42                 : 
      43                 : //
      44                 : // constants
      45                 : //
      46                 : static const char *ILI2_TID = "TID";
      47                 : static const char *ILI2_REF = "REF";
      48                 : 
      49                 : static const int ILI2_STRING_TYPE = 0;
      50                 : static const int ILI2_COORD_TYPE = 1;
      51                 : static const int ILI2_ARC_TYPE = 2;
      52                 : static const int ILI2_POLYLINE_TYPE = 4;
      53                 : static const int ILI2_BOUNDARY_TYPE = 8;
      54                 : static const int ILI2_AREA_TYPE = 16; // also SURFACE
      55                 : static const int ILI2_GEOMCOLL_TYPE = 32;
      56                 : 
      57                 : static const char *ILI2_COORD = "COORD";
      58                 : static const char *ILI2_ARC = "ARC";
      59                 : static const char *ILI2_POLYLINE = "POLYLINE";
      60                 : static const char *ILI2_BOUNDARY = "BOUNDARY";
      61                 : static const char *ILI2_AREA = "AREA";
      62                 : static const char *ILI2_SURFACE = "SURFACE";
      63                 : 
      64                 : 
      65                 : //
      66                 : // helper functions
      67                 : //
      68               0 : int cmpStr(string s1, string s2) {
      69                 : 
      70               0 :   string::const_iterator p1 = s1.begin();
      71               0 :   string::const_iterator p2 = s2.begin();
      72                 : 
      73               0 :   while (p1 != s1.end() && p2 != s2.end()) {
      74               0 :     if (toupper(*p1) != toupper(*p2))
      75               0 :       return (toupper(*p1) < toupper(*p2)) ? -1 : 1;
      76               0 :     ++p1;
      77               0 :     ++p2;
      78                 :   }
      79                 : 
      80                 :   return (s2.size() == s1.size()) ? 0 :
      81               0 :          (s1.size() < s2.size()) ? -1 : 1;
      82                 : }
      83                 : 
      84               0 : string ltrim(string tmpstr) {
      85               0 :   unsigned int i = 0;
      86               0 :   while (i < tmpstr.length() && (tmpstr[i] == ' ' || tmpstr[i] == '\t' || tmpstr[i] == '\r' || tmpstr[i] == '\n')) ++i;
      87               0 :   return i > 0 ? tmpstr.substr(i, tmpstr.length()-i) : tmpstr;
      88                 : }
      89                 : 
      90               0 : string rtrim(string tmpstr) {
      91               0 :   unsigned int i = tmpstr.length() - 1;
      92               0 :   while (i >= 0 && (tmpstr[i] == ' ' || tmpstr[i] == '\t' || tmpstr[i] == '\r' || tmpstr[i] == '\n')) --i;
      93               0 :   return i < tmpstr.length() - 1 ? tmpstr.substr(0, i+1) : tmpstr;
      94                 : }
      95                 : 
      96               0 : string trim(string tmpstr) {
      97               0 :   tmpstr = ltrim(tmpstr);
      98               0 :   tmpstr = rtrim(tmpstr);
      99               0 :   return tmpstr;
     100                 : }
     101                 : 
     102               0 : int getGeometryTypeOfElem(DOMElement* elem) {
     103               0 :   int type = ILI2_STRING_TYPE;
     104               0 :   char* pszTagName = XMLString::transcode(elem->getTagName());
     105                 : 
     106               0 :   if (elem && elem->getNodeType() == DOMNode::ELEMENT_NODE) {
     107               0 :     if (cmpStr(ILI2_COORD, pszTagName) == 0) {
     108               0 :       type = ILI2_COORD_TYPE;
     109               0 :     } else if (cmpStr(ILI2_ARC, pszTagName) == 0) {
     110               0 :       type = ILI2_ARC_TYPE;
     111               0 :     } else if (cmpStr(ILI2_POLYLINE, pszTagName) == 0) {
     112               0 :       type = ILI2_POLYLINE_TYPE;
     113               0 :     } else if (cmpStr(ILI2_BOUNDARY, pszTagName) == 0) {
     114               0 :       type = ILI2_BOUNDARY_TYPE;
     115               0 :     } else if (cmpStr(ILI2_AREA, pszTagName) == 0) {
     116               0 :       type = ILI2_AREA_TYPE;
     117               0 :     } else if (cmpStr(ILI2_SURFACE, pszTagName) == 0) {
     118               0 :       type = ILI2_AREA_TYPE;
     119                 :     }
     120                 :   }
     121               0 :   XMLString::release(&pszTagName);
     122               0 :   return type;
     123                 : }
     124                 : 
     125               0 : char *getObjValue(DOMElement *elem) {
     126               0 :   DOMElement *textElem = (DOMElement *)elem->getFirstChild();
     127                 : 
     128               0 :   if ((textElem != NULL) && (textElem->getNodeType() == DOMNode::TEXT_NODE))
     129                 :   {
     130               0 :     char* pszNodeValue = XMLString::transcode(textElem->getNodeValue());
     131               0 :     char* pszRet = CPLStrdup(pszNodeValue);
     132               0 :     XMLString::release(&pszNodeValue);
     133               0 :     return pszRet;
     134                 :   }
     135                 : 
     136               0 :   return NULL;
     137                 : }
     138                 : 
     139               0 : char *getREFValue(DOMElement *elem) {
     140               0 :   XMLCh* pszIli2_ref = XMLString::transcode(ILI2_REF);
     141               0 :   char* pszREFValue = XMLString::transcode(elem->getAttribute(pszIli2_ref));
     142               0 :   char* pszRet = CPLStrdup(pszREFValue);
     143               0 :   XMLString::release(&pszIli2_ref);
     144               0 :   XMLString::release(&pszREFValue);
     145               0 :   return pszRet;
     146                 : }
     147                 : 
     148               0 : OGRPoint *getPoint(DOMElement *elem) {
     149                 :   // elem -> COORD (or ARC)
     150               0 :   OGRPoint *pt = new OGRPoint();
     151                 : 
     152               0 :   DOMElement *coordElem = (DOMElement *)elem->getFirstChild();
     153               0 :   while (coordElem != NULL) {
     154               0 :     char* pszTagName = XMLString::transcode(coordElem->getTagName());
     155               0 :     char* pszObjValue = getObjValue(coordElem);
     156               0 :     if (cmpStr("C1", pszTagName) == 0)
     157               0 :       pt->setX(atof(pszObjValue));
     158               0 :     else if (cmpStr("C2", pszTagName) == 0)
     159               0 :       pt->setY(atof(pszObjValue));
     160               0 :     else if (cmpStr("C3", pszTagName) == 0)
     161               0 :       pt->setZ(atof(pszObjValue));
     162               0 :     CPLFree(pszObjValue);
     163               0 :     XMLString::release(&pszTagName);
     164               0 :     coordElem = (DOMElement *)coordElem->getNextSibling();
     165                 :   }
     166               0 :   pt->flattenTo2D();
     167               0 :   return pt;
     168                 : }
     169                 : 
     170               0 : OGRLineString *ILI2Reader::getArc(DOMElement *elem) {
     171                 :   // elem -> ARC
     172               0 :   OGRLineString *ls = new OGRLineString();
     173                 :   // previous point -> start point
     174               0 :   OGRPoint *ptStart = getPoint((DOMElement *)elem->getPreviousSibling()); // COORD or ARC
     175                 :   // end point
     176               0 :   OGRPoint *ptEnd = new OGRPoint();
     177                 :   // point on the arc
     178               0 :   OGRPoint *ptOnArc = new OGRPoint();
     179               0 :   double radius = 0; // radius
     180                 : 
     181               0 :   DOMElement *arcElem = (DOMElement *)elem->getFirstChild();
     182               0 :   while (arcElem != NULL) {
     183               0 :     char* pszTagName = XMLString::transcode(arcElem->getTagName());
     184               0 :     char* pszObjValue = getObjValue(arcElem);
     185               0 :     if (cmpStr("C1", pszTagName) == 0)
     186               0 :       ptEnd->setX(atof(pszObjValue));
     187               0 :     else if (cmpStr("C2", pszTagName) == 0)
     188               0 :       ptEnd->setY(atof(pszObjValue));
     189               0 :     else if (cmpStr("C3", pszTagName) == 0)
     190               0 :       ptEnd->setZ(atof(pszObjValue));
     191               0 :     else if (cmpStr("A1", pszTagName) == 0)
     192               0 :       ptOnArc->setX(atof(pszObjValue));
     193               0 :     else if (cmpStr("A2", pszTagName) == 0)
     194               0 :       ptOnArc->setY(atof(pszObjValue));
     195               0 :     else if (cmpStr("A3", pszTagName) == 0)
     196               0 :       ptOnArc->setZ(atof(pszObjValue));
     197               0 :     else if (cmpStr("R", pszTagName) == 0)
     198               0 :       radius = atof(pszObjValue);
     199               0 :     CPLFree(pszObjValue);
     200               0 :     XMLString::release(&pszTagName);
     201               0 :     arcElem = (DOMElement *)arcElem->getNextSibling();
     202                 :   }
     203               0 :   ptEnd->flattenTo2D();
     204               0 :   ptOnArc->flattenTo2D();
     205               0 :   interpolateArc(ls, ptStart, ptOnArc, ptEnd, arcIncr);
     206               0 :   return ls;
     207                 : }
     208                 : 
     209               0 : OGRLineString *getLineString(DOMElement *elem) {
     210                 :   // elem -> POLYLINE
     211               0 :   OGRLineString *ls = new OGRLineString();
     212                 : 
     213               0 :   DOMElement *lineElem = (DOMElement *)elem->getFirstChild();
     214               0 :   while (lineElem != NULL) {
     215               0 :     char* pszTagName = XMLString::transcode(lineElem->getTagName());
     216               0 :     if (cmpStr(ILI2_COORD, pszTagName) == 0)
     217               0 :       ls->addPoint(getPoint(lineElem));
     218               0 :     else if (cmpStr(ILI2_ARC, pszTagName) == 0) {
     219                 :       // end point
     220               0 :       OGRPoint *ptEnd = new OGRPoint();
     221                 :       // point on the arc
     222               0 :       OGRPoint *ptOnArc = new OGRPoint();
     223                 :       // radius
     224               0 :       double radius = 0;
     225                 : 
     226               0 :       DOMElement *arcElem = (DOMElement *)lineElem->getFirstChild();
     227               0 :       while (arcElem != NULL) {
     228               0 :         char* pszTagName = XMLString::transcode(arcElem->getTagName());
     229               0 :         char* pszObjValue = getObjValue(arcElem);
     230               0 :         if (cmpStr("C1", pszTagName) == 0)
     231               0 :           ptEnd->setX(atof(pszObjValue));
     232               0 :         else if (cmpStr("C2", pszTagName) == 0)
     233               0 :           ptEnd->setY(atof(pszObjValue));
     234               0 :         else if (cmpStr("C3", pszTagName) == 0)
     235               0 :           ptEnd->setZ(atof(pszObjValue));
     236               0 :         else if (cmpStr("A1", pszTagName) == 0)
     237               0 :           ptOnArc->setX(atof(pszObjValue));
     238               0 :         else if (cmpStr("A2", pszTagName) == 0)
     239               0 :           ptOnArc->setY(atof(pszObjValue));
     240               0 :         else if (cmpStr("A3", pszTagName) == 0)
     241               0 :           ptOnArc->setZ(atof(pszObjValue));
     242               0 :         else if (cmpStr("R", pszTagName) == 0)
     243               0 :           radius = atof(pszObjValue);
     244               0 :         CPLFree(pszObjValue);
     245               0 :         XMLString::release(&pszTagName);
     246                 : 
     247               0 :         arcElem = (DOMElement *)arcElem->getNextSibling();
     248                 :       }
     249                 : 
     250               0 :       ptEnd->flattenTo2D();
     251               0 :       ptOnArc->flattenTo2D();
     252               0 :       OGRPoint *ptStart = getPoint((DOMElement *)lineElem->getPreviousSibling()); // COORD or ARC
     253               0 :       interpolateArc(ls, ptStart, ptOnArc, ptEnd, PI/180);
     254                 :     } /* else { // FIXME StructureValue in Polyline not yet supported
     255                 :     } */
     256               0 :     XMLString::release(&pszTagName);
     257                 : 
     258               0 :     lineElem = (DOMElement *)lineElem->getNextSibling();
     259                 :   }
     260                 : 
     261               0 :   return ls;
     262                 : }
     263                 : 
     264               0 : OGRLineString *getBoundary(DOMElement *elem) {
     265                 : 
     266               0 :   DOMElement *lineElem = (DOMElement *)elem->getFirstChild();
     267               0 :   if (lineElem != NULL)
     268                 :   {
     269               0 :     char* pszTagName = XMLString::transcode(lineElem->getTagName());
     270               0 :     if (cmpStr(ILI2_POLYLINE, pszTagName) == 0)
     271                 :     {
     272               0 :       XMLString::release(&pszTagName);
     273               0 :       return getLineString(lineElem);
     274                 :     }
     275               0 :     XMLString::release(&pszTagName);
     276                 :   }
     277                 : 
     278               0 :   return new OGRLineString;
     279                 : }
     280                 : 
     281               0 : OGRPolygon *getPolygon(DOMElement *elem) {
     282               0 :   OGRPolygon *pg = new OGRPolygon();
     283                 : 
     284               0 :   DOMElement *boundaryElem = (DOMElement *)elem->getFirstChild(); // outer boundary
     285               0 :   while (boundaryElem != NULL) {
     286               0 :     char* pszTagName = XMLString::transcode(boundaryElem->getTagName());
     287               0 :     if (cmpStr(ILI2_BOUNDARY, pszTagName) == 0)
     288               0 :       pg->addRing((OGRLinearRing *)getBoundary(boundaryElem));
     289               0 :     XMLString::release(&pszTagName);
     290               0 :     boundaryElem = (DOMElement *)boundaryElem->getNextSibling(); // inner boundaries
     291                 :   }
     292                 : 
     293               0 :   return pg;
     294                 : }
     295                 : 
     296               0 : OGRGeometry *ILI2Reader::getGeometry(DOMElement *elem, int type) {
     297               0 :   OGRGeometryCollection *gm = new OGRGeometryCollection();
     298                 : 
     299               0 :   DOMElement *childElem = elem;
     300               0 :   while (childElem != NULL) {
     301               0 :     char* pszTagName = XMLString::transcode(childElem->getTagName());
     302               0 :     switch (type) {
     303                 :       case ILI2_COORD_TYPE :
     304               0 :         if (cmpStr(ILI2_COORD, pszTagName) == 0)
     305                 :         {
     306               0 :           delete gm;
     307               0 :           XMLString::release(&pszTagName);
     308               0 :           return getPoint(childElem);
     309                 :         }
     310               0 :         break;
     311                 :       case ILI2_ARC_TYPE :
     312                 :         // is it possible here? It have to be a ARC or COORD before (getPreviousSibling)
     313               0 :         if (cmpStr(ILI2_ARC, pszTagName) == 0)
     314                 :         {
     315               0 :           delete gm;
     316               0 :           XMLString::release(&pszTagName);
     317               0 :           return getArc(childElem);
     318                 :         }
     319               0 :         break;
     320                 :       case ILI2_POLYLINE_TYPE :
     321               0 :         if (cmpStr(ILI2_POLYLINE, pszTagName) == 0)
     322                 :         {
     323               0 :           delete gm;
     324               0 :           XMLString::release(&pszTagName);
     325               0 :           return getLineString(childElem);
     326                 :         }
     327               0 :         break;
     328                 :       case ILI2_BOUNDARY_TYPE :
     329               0 :         if (cmpStr(ILI2_BOUNDARY, pszTagName) == 0)
     330                 :         {
     331               0 :           delete gm;
     332               0 :           XMLString::release(&pszTagName);
     333               0 :           return getLineString(childElem);
     334                 :         }
     335               0 :         break;
     336                 :       case ILI2_AREA_TYPE :
     337               0 :         if ((cmpStr(ILI2_AREA, pszTagName) == 0) ||
     338                 :           (cmpStr(ILI2_SURFACE, pszTagName) == 0))
     339                 :         {
     340               0 :           delete gm;
     341               0 :           XMLString::release(&pszTagName);
     342               0 :           return getPolygon(childElem);
     343                 :         }
     344               0 :         break;
     345                 :       default :
     346               0 :         if (type >= ILI2_GEOMCOLL_TYPE) {
     347               0 :           int subType = getGeometryTypeOfElem(childElem); //????
     348               0 :           gm->addGeometryDirectly(getGeometry(childElem, subType));
     349                 :         }
     350                 :         break;
     351                 :     }
     352               0 :     XMLString::release(&pszTagName);
     353                 : 
     354                 :     // GEOMCOLL
     355               0 :     childElem = (DOMElement *)childElem->getNextSibling();
     356                 :   }
     357                 : 
     358               0 :   return gm;
     359                 : }
     360                 : 
     361               0 : const char* ILI2Reader::GetLayerName(IOM_BASKET model, IOM_OBJECT table) {
     362                 :     static char layername[512];
     363               0 :     IOM_OBJECT topic = GetAttrObj(model, table, "container");
     364               0 :     layername[0] = '\0';
     365               0 :     strcat(layername, iom_getattrvalue(GetAttrObj(model, topic, "container"), "name"));
     366               0 :     strcat(layername, ".");
     367               0 :     strcat(layername, iom_getattrvalue(topic, "name"));
     368               0 :     strcat(layername, ".");
     369               0 :     strcat(layername, iom_getattrvalue(table, "name"));
     370               0 :     return layername;
     371                 : }
     372                 : 
     373               0 : void ILI2Reader::AddField(OGRLayer* layer, IOM_BASKET model, IOM_OBJECT obj) {
     374               0 :   const char* typenam = "Reference";
     375               0 :   if (EQUAL(iom_getobjecttag(obj),"iom04.metamodel.LocalAttribute")) typenam = GetTypeName(model, obj);
     376               0 :   if (EQUAL(typenam, "iom04.metamodel.SurfaceType")) {
     377               0 :   } else if (EQUAL(typenam, "iom04.metamodel.AreaType")) {
     378               0 :   } else if (EQUAL(typenam, "iom04.metamodel.PolylineType") ) {
     379               0 :   } else if (EQUAL(typenam, "iom04.metamodel.CoordType")) {
     380                 :   } else {
     381               0 :     OGRFieldDefn fieldDef(iom_getattrvalue(obj, "name"), OFTString);
     382               0 :     layer->GetLayerDefn()->AddFieldDefn(&fieldDef);
     383               0 :     CPLDebug( "OGR_ILI", "Field %s: %s", fieldDef.GetNameRef(), typenam);
     384                 :   }
     385               0 : }
     386                 : 
     387               0 : int ILI2Reader::ReadModel(char **modelFilenames) {
     388                 : 
     389                 :   IOM_BASKET model;
     390                 :   IOM_ITERATOR modelelei;
     391                 :   IOM_OBJECT modelele;
     392                 : 
     393               0 :   iom_init();
     394                 : 
     395                 :   // set error listener to a iom provided one, that just
     396                 :   // dumps all errors to stderr
     397               0 :   iom_seterrlistener(iom_stderrlistener);
     398                 : 
     399                 :   // compile ili models
     400               0 :   model=iom_compileIli(CSLCount(modelFilenames), modelFilenames);
     401               0 :   if(!model){
     402               0 :     CPLError( CE_Failure, CPLE_FileIO, "iom_compileIli failed." );
     403               0 :     iom_end();
     404               0 :     return FALSE;
     405                 :   }
     406                 : 
     407                 :   // read tables
     408               0 :   modelelei=iom_iteratorobject(model);
     409               0 :   modelele=iom_nextobject(modelelei);
     410               0 :   while(modelele){
     411               0 :     const char *tag=iom_getobjecttag(modelele);
     412               0 :     if (tag && EQUAL(tag,"iom04.metamodel.Table")) {
     413               0 :       const char* topic = iom_getattrvalue(GetAttrObj(model, modelele, "container"), "name");
     414               0 :       if (!EQUAL(topic, "INTERLIS")) {
     415               0 :         const char* layername = GetLayerName(model, modelele);
     416               0 :         OGRLayer* layer = new OGRILI2Layer(layername, NULL, 0, wkbUnknown, NULL);
     417               0 :         m_listLayer.push_back(layer);
     418               0 :         CPLDebug( "OGR_ILI", "Reading table model '%s'", layername );
     419                 : 
     420                 :         // read fields
     421                 :         IOM_OBJECT fields[255];
     422                 :         IOM_OBJECT roledefs[255];
     423               0 :         memset(fields, 0, 255);
     424               0 :         memset(roledefs, 0, 255);
     425               0 :         int maxIdx = -1;
     426               0 :         IOM_ITERATOR fieldit=iom_iteratorobject(model);
     427               0 :         for (IOM_OBJECT fieldele=iom_nextobject(fieldit); fieldele; fieldele=iom_nextobject(fieldit)){
     428               0 :           const char *etag=iom_getobjecttag(fieldele);
     429               0 :           if (etag && (EQUAL(etag,"iom04.metamodel.ViewableAttributesAndRoles"))) {
     430               0 :             IOM_OBJECT table = GetAttrObj(model, fieldele, "viewable");
     431               0 :             if (table == modelele) {
     432               0 :               IOM_OBJECT obj = GetAttrObj(model, fieldele, "attributesAndRoles");
     433               0 :               int ili1AttrIdx = GetAttrObjPos(fieldele, "attributesAndRoles")-1;
     434               0 :               if (EQUAL(iom_getobjecttag(obj),"iom04.metamodel.RoleDef")) {
     435                 :                 //??ili1AttrIdx = atoi(iom_getattrvalue(GetAttrObj(model, obj, "oppend"), "ili1AttrIdx"));
     436               0 :                 roledefs[ili1AttrIdx] = obj;
     437                 :               } else {
     438               0 :                 fields[ili1AttrIdx] = obj;
     439                 :               }
     440               0 :               if (ili1AttrIdx > maxIdx) maxIdx = ili1AttrIdx;
     441                 :               //CPLDebug( "OGR_ILI", "Field %s Pos: %d", iom_getattrvalue(obj, "name"), ili1AttrIdx);
     442                 :             }
     443                 :           }
     444               0 :           iom_releaseobject(fieldele);
     445                 :         }
     446               0 :         iom_releaseiterator(fieldit);
     447                 : 
     448               0 :         for (int i=0; i<=maxIdx; i++) {
     449               0 :           IOM_OBJECT obj = fields[i];
     450               0 :           IOM_OBJECT roleobj = roledefs[i];
     451               0 :           if (roleobj) AddField(layer, model, roleobj);
     452               0 :           if (obj) AddField(layer, model, obj);
     453                 :         }
     454                 :       }
     455                 :     }
     456               0 :     iom_releaseobject(modelele);
     457                 : 
     458               0 :     modelele=iom_nextobject(modelelei);
     459                 :   }
     460                 : 
     461               0 :   iom_releaseiterator(modelelei);
     462                 : 
     463               0 :   iom_releasebasket(model);
     464                 : 
     465               0 :   iom_end();
     466                 : 
     467               0 :   return 0;
     468                 : }
     469                 : 
     470               0 : char* fieldName(DOMElement* elem) {
     471               0 :   string fullname;
     472               0 :   int depth = 0;
     473                 :   DOMNode *node;
     474               0 :   for (node = elem; node; node = node->getParentNode()) ++depth;
     475               0 :   depth-=3; //ignore root elements
     476                 : 
     477                 : // We cannot do this sort of dynamic stack alloc on MSVC6.
     478                 : //  DOMNode* elements[depth];
     479                 :   DOMNode* elements[1000];
     480               0 :   CPLAssert( depth < (int)(sizeof(elements) / sizeof(DOMNode*)) );
     481                 : 
     482               0 :   int d=0;
     483               0 :   for (node = elem; d<depth; node = node->getParentNode()) elements[d++] = node;
     484               0 :   for (d=depth-1; d>=0; --d) {
     485               0 :     if (d < depth-1) fullname += "_";
     486               0 :     char* pszNodeName = XMLString::transcode(elements[d]->getNodeName());
     487               0 :     fullname += pszNodeName;
     488               0 :     XMLString::release(&pszNodeName);
     489                 :   }
     490               0 :   return CPLStrdup(fullname.c_str());
     491                 : }
     492                 : 
     493               0 : void ILI2Reader::setFieldDefn(OGRFeatureDefn *featureDef, DOMElement* elem) {
     494               0 :   int type = 0;
     495                 :   //recursively search children
     496               0 :   for (DOMElement *childElem = (DOMElement *)elem->getFirstChild();
     497               0 :         type == 0 && childElem && childElem->getNodeType() == DOMNode::ELEMENT_NODE;
     498               0 :         childElem = (DOMElement*)childElem->getNextSibling()) {
     499               0 :     type = getGeometryTypeOfElem(childElem);
     500               0 :     if (type == 0) {
     501               0 :       if (childElem->getFirstChild() && childElem->getFirstChild()->getNodeType() == DOMNode::ELEMENT_NODE) {
     502               0 :         setFieldDefn(featureDef, childElem);
     503                 :       } else {
     504               0 :         char *fName = fieldName(childElem);
     505               0 :         if (featureDef->GetFieldIndex(fName) == -1) {
     506               0 :           CPLDebug( "OGR_ILI", "AddFieldDefn: %s",fName );
     507               0 :           OGRFieldDefn oFieldDefn(fName, OFTString);
     508               0 :           featureDef->AddFieldDefn(&oFieldDefn);
     509                 :         }
     510               0 :         CPLFree(fName);
     511                 :       }
     512                 :     }
     513                 :   }
     514               0 : }
     515                 : 
     516               0 : void ILI2Reader::SetFieldValues(OGRFeature *feature, DOMElement* elem) {
     517               0 :   int type = 0;
     518                 :   //recursively search children
     519               0 :   for (DOMElement *childElem = (DOMElement *)elem->getFirstChild();
     520               0 :         type == 0 && childElem && childElem->getNodeType() == DOMNode::ELEMENT_NODE;
     521               0 :         childElem = (DOMElement*)childElem->getNextSibling()) {
     522               0 :     type = getGeometryTypeOfElem(childElem);
     523               0 :     if (type == 0) {
     524               0 :       if (childElem->getFirstChild() && childElem->getFirstChild()->getNodeType() == DOMNode::ELEMENT_NODE) {
     525               0 :         SetFieldValues(feature, childElem);
     526                 :       } else {
     527               0 :         char *fName = fieldName(childElem);
     528               0 :         int fIndex = feature->GetFieldIndex(fName);
     529               0 :         if (fIndex != -1) {
     530               0 :           char * objVal = getObjValue(childElem);
     531               0 :           if (objVal == NULL)
     532               0 :             objVal = getREFValue(childElem); // only to try
     533               0 :           feature->SetField(fIndex, objVal);
     534               0 :           CPLFree(objVal);
     535                 :         } else {
     536               0 :           m_missAttrs.push_back(fName);
     537                 :         }
     538               0 :         CPLFree(fName);
     539                 :       }
     540                 :     } else {
     541               0 :       feature->SetGeometryDirectly(getGeometry(childElem, type));
     542                 :     }
     543                 :   }
     544               0 : }
     545                 : 
     546                 : 
     547                 : //
     548                 : // ILI2Reader
     549                 : //
     550               0 : IILI2Reader::~IILI2Reader() {
     551               0 : }
     552                 : 
     553               0 : ILI2Reader::ILI2Reader() {
     554               0 :     m_poILI2Handler = NULL;
     555               0 :     m_poSAXReader = NULL;
     556               0 :     m_bReadStarted = FALSE;
     557                 : 
     558               0 :     m_pszFilename = NULL;
     559                 : 
     560               0 :     SetupParser();
     561               0 : }
     562                 : 
     563               0 : ILI2Reader::~ILI2Reader() {
     564               0 :     CPLFree( m_pszFilename );
     565                 : 
     566               0 :     CleanupParser();
     567                 : 
     568               0 :     list<OGRLayer *>::const_iterator layerIt = m_listLayer.begin();
     569               0 :     while (layerIt != m_listLayer.end()) {
     570               0 :         OGRILI2Layer *tmpLayer = (OGRILI2Layer *)*layerIt;
     571               0 :         delete tmpLayer;
     572               0 :         layerIt++;
     573                 :     }
     574               0 : }
     575                 : 
     576               0 : void ILI2Reader::SetArcDegrees(double arcDegrees) {
     577               0 :   arcIncr = arcDegrees*PI/180;
     578               0 : }
     579                 : 
     580               0 : void ILI2Reader::SetSourceFile( const char *pszFilename ) {
     581               0 :     CPLFree( m_pszFilename );
     582               0 :     m_pszFilename = CPLStrdup( pszFilename );
     583               0 : }
     584                 : 
     585               0 : int ILI2Reader::SetupParser() {
     586                 : 
     587                 :     static int bXercesInitialized = FALSE;
     588                 : 
     589               0 :     if( !bXercesInitialized )
     590                 :     {
     591                 :         try
     592                 :         {
     593               0 :             XMLPlatformUtils::Initialize();
     594                 :         }
     595                 : 
     596               0 :         catch (const XMLException& toCatch)
     597                 :         {
     598               0 :             char* msg = XMLString::transcode(toCatch.getMessage());
     599                 :             CPLError( CE_Failure, CPLE_AppDefined,
     600                 :                       "Unable to initalize Xerces C++ based ILI2 reader. "
     601               0 :                       "Error message:\n%s\n", msg );
     602               0 :             XMLString::release(&msg);
     603                 : 
     604               0 :             return FALSE;
     605                 :         }
     606               0 :         bXercesInitialized = TRUE;
     607                 :     }
     608                 : 
     609                 :     // Cleanup any old parser.
     610               0 :     if( m_poSAXReader != NULL )
     611               0 :         CleanupParser();
     612                 : 
     613                 :     // Create and initialize parser.
     614               0 :     m_poSAXReader = XMLReaderFactory::createXMLReader();
     615                 : 
     616               0 :     m_poILI2Handler = new ILI2Handler( this );
     617                 : 
     618               0 :     m_poSAXReader->setContentHandler( m_poILI2Handler );
     619               0 :     m_poSAXReader->setErrorHandler( m_poILI2Handler );
     620               0 :     m_poSAXReader->setLexicalHandler( m_poILI2Handler );
     621               0 :     m_poSAXReader->setEntityResolver( m_poILI2Handler );
     622               0 :     m_poSAXReader->setDTDHandler( m_poILI2Handler );
     623                 : 
     624                 : /* No Validation
     625                 : #if (OGR_ILI2_VALIDATION)
     626                 :     m_poSAXReader->setFeature(
     627                 :         XMLString::transcode("http://xml.org/sax/features/validation"), true);
     628                 :     m_poSAXReader->setFeature(
     629                 :         XMLString::transcode("http://xml.org/sax/features/namespaces"), true);
     630                 : 
     631                 :     m_poSAXReader->setFeature( XMLUni::fgSAX2CoreNameSpaces, true );
     632                 :     m_poSAXReader->setFeature( XMLUni::fgXercesSchema, true );
     633                 : 
     634                 : //    m_poSAXReader->setDoSchema(true);
     635                 : //    m_poSAXReader->setValidationSchemaFullChecking(true);
     636                 : #else
     637                 : */
     638               0 :     XMLCh *tmpCh = XMLString::transcode("http://xml.org/sax/features/validation");
     639               0 :     m_poSAXReader->setFeature(tmpCh, false);
     640               0 :     XMLString::release(&tmpCh);
     641               0 :     tmpCh = XMLString::transcode("http://xml.org/sax/features/namespaces");
     642               0 :     m_poSAXReader->setFeature(tmpCh, false);
     643               0 :     XMLString::release(&tmpCh);
     644                 : //#endif
     645                 : 
     646               0 :     m_bReadStarted = FALSE;
     647                 : 
     648               0 :     return TRUE;
     649                 : }
     650                 : 
     651               0 : void ILI2Reader::CleanupParser() {
     652               0 :     if( m_poSAXReader == NULL )
     653               0 :         return;
     654                 : 
     655               0 :     delete m_poSAXReader;
     656               0 :     m_poSAXReader = NULL;
     657                 : 
     658               0 :     delete m_poILI2Handler;
     659               0 :     m_poILI2Handler = NULL;
     660                 : 
     661               0 :     m_bReadStarted = FALSE;
     662                 : }
     663                 : 
     664               0 : int ILI2Reader::SaveClasses( const char *pszFile = NULL ) {
     665                 : 
     666                 :     // Add logic later to determine reasonable default schema file.
     667               0 :     if( pszFile == NULL )
     668               0 :         return FALSE;
     669                 : 
     670                 :     // parse and create layers and features
     671                 :     try
     672                 :     {
     673               0 :         m_poSAXReader->parse(pszFile);
     674                 :     }
     675               0 :     catch (const SAXException& toCatch)
     676                 :     {
     677               0 :         char* msg = XMLString::transcode(toCatch.getMessage());
     678                 :         CPLError( CE_Failure, CPLE_AppDefined,
     679               0 :                     "Parsing failed: %s\n", msg );
     680               0 :         XMLString::release(&msg);
     681                 : 
     682               0 :         return FALSE;
     683                 :     }
     684                 : 
     685               0 :   if (m_missAttrs.size() != 0) {
     686               0 :     m_missAttrs.sort();
     687               0 :     m_missAttrs.unique();
     688               0 :     string attrs = "";
     689               0 :     list<string>::const_iterator it = m_missAttrs.begin();
     690               0 :     for (it = m_missAttrs.begin(); it != m_missAttrs.end(); ++it)
     691               0 :       attrs += *it + ", ";
     692                 : 
     693                 :     CPLError( CE_Warning, CPLE_NotSupported,
     694               0 :               "Failed to add new definition to existing layers, attributes not saved: %s", attrs.c_str() );
     695                 :   }
     696                 : 
     697               0 :     return TRUE;
     698                 : }
     699                 : 
     700               0 : list<OGRLayer *> ILI2Reader::GetLayers() {
     701               0 :   return m_listLayer;
     702                 : }
     703                 : 
     704               0 : int ILI2Reader::GetLayerCount() {
     705               0 :   return m_listLayer.size();
     706                 : }
     707                 : 
     708                 : 
     709               0 : int ILI2Reader::AddFeature(DOMElement *elem) {
     710               0 :   bool newLayer = true;
     711               0 :   OGRLayer *curLayer = 0;
     712               0 :   char *pszName = XMLString::transcode(elem->getTagName());
     713                 : 
     714                 :   // test if this layer exist
     715               0 :   for (list<OGRLayer *>::reverse_iterator layerIt = m_listLayer.rbegin();
     716                 :        layerIt != m_listLayer.rend();
     717                 :        ++layerIt) {
     718               0 :     OGRFeatureDefn *fDef = (*layerIt)->GetLayerDefn();
     719               0 :     if (cmpStr(fDef->GetName(), pszName) == 0) {
     720               0 :       newLayer = false;
     721               0 :       curLayer = *layerIt;
     722               0 :       break;
     723                 :     }
     724                 :   }
     725                 : 
     726                 :   // add a layer
     727               0 :   if (newLayer) { // FIXME in Layer: SRS Writer Type datasource
     728               0 :     CPLDebug( "OGR_ILI", "Adding layer: %s", pszName );
     729                 :     // new layer data
     730               0 :     OGRSpatialReference *poSRSIn = NULL; // FIXME fix values for initial layer
     731               0 :     int bWriterIn = 0;
     732               0 :     OGRwkbGeometryType eReqType = wkbUnknown;
     733               0 :     OGRILI2DataSource *poDSIn = NULL;
     734               0 :     curLayer = new OGRILI2Layer(pszName, poSRSIn, bWriterIn, eReqType, poDSIn);
     735               0 :     m_listLayer.push_back(curLayer);
     736                 :   }
     737                 : 
     738                 :   // the feature and field definition
     739               0 :   OGRFeatureDefn *featureDef = curLayer->GetLayerDefn();
     740               0 :   if (newLayer) {
     741                 :     // the TID feature
     742               0 :     OGRFieldDefn ofieldDefn (ILI2_TID, OFTString);
     743               0 :     featureDef->AddFieldDefn(&ofieldDefn);
     744                 : 
     745               0 :     setFieldDefn(featureDef, elem);
     746                 :   }
     747                 : 
     748                 :   // add the features
     749               0 :   OGRFeature *feature = new OGRFeature(featureDef);
     750                 : 
     751                 :   // the TID feature
     752               0 :   int fIndex = feature->GetFieldIndex(ILI2_TID);
     753               0 :   XMLCh *pszIli2_tid = XMLString::transcode(ILI2_TID);
     754               0 :   char *fChVal = XMLString::transcode(elem->getAttribute(pszIli2_tid));
     755               0 :   feature->SetField(fIndex, fChVal);
     756               0 :   XMLString::release (&pszIli2_tid);
     757               0 :   XMLString::release (&fChVal);
     758                 : 
     759               0 :   SetFieldValues(feature, elem);
     760               0 :   curLayer->SetFeature(feature);
     761                 :   
     762               0 :   XMLString::release (&pszName);
     763                 : 
     764               0 :   return 0;
     765                 : }
     766                 : 
     767               0 : IILI2Reader *CreateILI2Reader() {
     768               0 :     return new ILI2Reader();
     769                 : }
     770                 : 
     771             174 : void DestroyILI2Reader(IILI2Reader* reader)
     772                 : {
     773             174 :     if (reader)
     774               0 :         delete reader;
     775             174 : }

Generated by: LCOV version 1.7