ili1reader.cpp

来自「支持各种栅格图像和矢量图像读取的库」· C++ 代码 · 共 805 行 · 第 1/2 页

CPP
805
字号
/****************************************************************************** * $Id: ili1reader.cpp 10653 2007-01-18 16:38:13Z warmerdam $ * * Project:  Interlis 1 Reader * Purpose:  Implementation of ILI1Reader class. * Author:   Pirmin Kalberer, Sourcepole AG * ****************************************************************************** * Copyright (c) 2004, Pirmin Kalberer, Sourcepole AG * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/#include "ogr_ili1.h"#include "cpl_conv.h"#include "cpl_string.h"#include "ogr_api.h"#include "ogr_geos.h"#include "ilihelper.h"#include "iomhelper.h"#include "ili1reader.h"#include "ili1readerp.h"#ifdef HAVE_GEOS#  define POLYGONIZE_AREAS#endif#ifndef POLYGONIZE_AREAS#  if defined(__GNUC_PREREQ)#    warning Interlis 1 Area polygonizing disabled. Needs GEOS >= 2.1.0#  endif#endifCPL_CVSID("$Id: ili1reader.cpp 10653 2007-01-18 16:38:13Z warmerdam $");//// ILI1Reader//IILI1Reader::~IILI1Reader() {}ILI1Reader::ILI1Reader() {  fpItf = NULL;  nLayers = 0;  papoLayers = NULL;  nAreaLayers = 0;  papoAreaLayers = NULL;  papoAreaLineLayers = NULL;  nSurfaceLayers = 0;  papoSurfaceLayers = NULL;  papoSurfacePolyLayers = NULL;  SetArcDegrees(1);}ILI1Reader::~ILI1Reader() { if (fpItf) VSIFClose( fpItf );}void ILI1Reader::SetArcDegrees(double arcDegrees) {  arcIncr = arcDegrees*PI/180;}/* -------------------------------------------------------------------- *//*      Open the source file.                                           *//* -------------------------------------------------------------------- */int ILI1Reader::OpenFile( const char *pszFilename ) {    fpItf = VSIFOpen( pszFilename, "r" );    if( fpItf == NULL )    {          CPLError( CE_Failure, CPLE_OpenFailed,                     "Failed to open ILI file `%s'.",                     pszFilename );        return FALSE;    }    return TRUE;}const char* ILI1Reader::GetLayerNameString(const char* topicname, const char* tablename) {    static char layername[512];    layername[0] = '\0';    strcat(layername, topicname);    strcat(layername, "__");    strcat(layername, tablename);    return layername;}const char* ILI1Reader::GetLayerName(IOM_BASKET model, IOM_OBJECT table) {    static char layername[512];    IOM_OBJECT topic = GetAttrObj(model, table, "container");    layername[0] = '\0';    strcat(layername, iom_getattrvalue(topic, "name"));    strcat(layername, "__");    strcat(layername, iom_getattrvalue(table, "name"));    return layername;}void ILI1Reader::AddCoord(OGRLayer* layer, IOM_BASKET model, IOM_OBJECT modelele, IOM_OBJECT typeobj) {  unsigned int dim = ::GetCoordDim(model, typeobj);  for (unsigned int i=0; i<dim; i++) {    OGRFieldDefn fieldDef(CPLSPrintf("%s_%d", iom_getattrvalue(modelele, "name"), i), OFTReal);    layer->GetLayerDefn()->AddFieldDefn(&fieldDef);    CPLDebug( "OGR_ILI", "Field %s: OFTReal", fieldDef.GetNameRef());  }}OGRLayer* ILI1Reader::AddGeomTable(const char* datalayername, const char* geomname, OGRwkbGeometryType eType) {  static char layername[512];  layername[0] = '\0';  strcat(layername, datalayername);  strcat(layername, "_");  strcat(layername, geomname);  OGRLayer* geomlayer = new OGRILI1Layer(layername, NULL, 0, eType, NULL);  AddLayer(geomlayer);  OGRFieldDefn fieldDef(datalayername, OFTString); //"__Ident"  geomlayer->GetLayerDefn()->AddFieldDefn(&fieldDef);  OGRFieldDefn fieldDef2("ILI_Geometry", OFTString); //in write mode only?  geomlayer->GetLayerDefn()->AddFieldDefn(&fieldDef2);  return geomlayer;}void ILI1Reader::AddField(OGRLayer* layer, IOM_BASKET model, IOM_OBJECT obj) {  const char* typenam = "Reference";  if (EQUAL(iom_getobjecttag(obj),"iom04.metamodel.LocalAttribute")) typenam = GetTypeName(model, obj);  CPLDebug( "OGR_ILI", "Field %s: %s", iom_getattrvalue(obj, "name"), typenam);  if (EQUAL(typenam, "iom04.metamodel.SurfaceType")) {    OGRLayer* polyLayer = AddGeomTable(layer->GetLayerDefn()->GetName(), iom_getattrvalue(obj, "name"), wkbPolygon);    AddSurfaceLayer(layer, polyLayer);    //TODO: add line attributes to geometry  } else if (EQUAL(typenam, "iom04.metamodel.AreaType")) {    IOM_OBJECT controlPointDomain = GetAttrObj(model, GetTypeObj(model, obj), "controlPointDomain");    if (controlPointDomain) {      AddCoord(layer, model, obj, GetTypeObj(model, controlPointDomain));      layer->GetLayerDefn()->SetGeomType(wkbPoint);    }    OGRLayer* areaLineLayer = AddGeomTable(layer->GetLayerDefn()->GetName(), iom_getattrvalue(obj, "name"), wkbMultiLineString);#ifdef POLYGONIZE_AREAS    AddAreaLayer(layer, areaLineLayer);#endif  } else if (EQUAL(typenam, "iom04.metamodel.PolylineType") ) {    layer->GetLayerDefn()->SetGeomType(wkbMultiLineString);  } else if (EQUAL(typenam, "iom04.metamodel.CoordType")) {    AddCoord(layer, model, obj, GetTypeObj(model, obj));    if (layer->GetLayerDefn()->GetGeomType() == wkbUnknown) layer->GetLayerDefn()->SetGeomType(wkbPoint);  } else {    OGRFieldDefn fieldDef(iom_getattrvalue(obj, "name"), OFTString);    layer->GetLayerDefn()->AddFieldDefn(&fieldDef);  }}int ILI1Reader::ReadModel(const char *pszModelFilename) {  IOM_BASKET model;  IOM_ITERATOR modelelei;  IOM_OBJECT modelele;  iom_init();  // set error listener to a iom provided one, that just   // dumps all errors to stderr  iom_seterrlistener(iom_stderrlistener);  // compile ili model  char *iomarr[1] = {(char *)pszModelFilename};  model=iom_compileIli(1, iomarr);  if(!model){    CPLError( CE_Failure, CPLE_FileIO, "iom_compileIli failed." );    iom_end();    return FALSE;  }  // read tables  modelelei=iom_iteratorobject(model);  modelele=iom_nextobject(modelelei);  while(modelele){    const char *tag=iom_getobjecttag(modelele);    if (tag && EQUAL(tag,"iom04.metamodel.Table")) {      const char* topic = iom_getattrvalue(GetAttrObj(model, modelele, "container"), "name");      if (!EQUAL(topic, "INTERLIS")) {        const char* layername = GetLayerName(model, modelele);        OGRSpatialReference *poSRSIn = NULL;        int bWriterIn = 0;        OGRwkbGeometryType eReqType = wkbUnknown;        OGRILI1DataSource *poDSIn = NULL;        OGRLayer* layer = new OGRILI1Layer(layername, poSRSIn, bWriterIn, eReqType, poDSIn);        AddLayer(layer);        CPLDebug( "OGR_ILI", "Reading table model '%s'", layername );        // read fields        IOM_OBJECT fields[255];        IOM_OBJECT roledefs[255];        memset(fields, 0, 255);        memset(roledefs, 0, 255);        int maxIdx = -1;        IOM_ITERATOR fieldit=iom_iteratorobject(model);        for (IOM_OBJECT fieldele=iom_nextobject(fieldit); fieldele; fieldele=iom_nextobject(fieldit)){          const char *etag=iom_getobjecttag(fieldele);          if (etag && (EQUAL(etag,"iom04.metamodel.ViewableAttributesAndRoles"))) {            IOM_OBJECT table = GetAttrObj(model, fieldele, "viewable");            if (table == modelele) {              IOM_OBJECT obj = GetAttrObj(model, fieldele, "attributesAndRoles");              int ili1AttrIdx = GetAttrObjPos(fieldele, "attributesAndRoles")-1;              if (EQUAL(iom_getobjecttag(obj),"iom04.metamodel.RoleDef")) {                int ili1AttrIdxOppend = atoi(iom_getattrvalue(GetAttrObj(model, obj, "oppend"), "ili1AttrIdx"));                if (ili1AttrIdxOppend>=0) roledefs[ili1AttrIdxOppend] = obj;              } else {                fields[ili1AttrIdx] = obj;              }              if (ili1AttrIdx > maxIdx) maxIdx = ili1AttrIdx;              //CPLDebug( "OGR_ILI", "Field %s Pos: %d", iom_getattrvalue(obj, "name"), ili1AttrIdx);            }          }          iom_releaseobject(fieldele);        }        iom_releaseiterator(fieldit);        OGRFieldDefn fieldDef("__Ident", OFTString);        layer->GetLayerDefn()->AddFieldDefn(&fieldDef);        for (int i=0; i<=maxIdx; i++) {          IOM_OBJECT obj = fields[i];          IOM_OBJECT roleobj = roledefs[i];          if (roleobj) AddField(layer, model, roleobj);          if (obj) AddField(layer, model, obj);        }      }    }    iom_releaseobject(modelele);    modelele=iom_nextobject(modelelei);  }  iom_releaseiterator(modelelei);  iom_releasebasket(model);  iom_end();  return 0;}int ILI1Reader::ReadFeatures() {    char **tokens = NULL;    const char *firsttok = NULL;    const char *pszLine;    const char *topic = NULL;    int ret = TRUE;        while (ret && (tokens = ReadParseLine()))    {      firsttok = tokens[0];      if (EQUAL(firsttok, "SCNT"))      {        //read description        do         {          pszLine = CPLReadLine( fpItf );        }        while (pszLine && !EQUALN(pszLine, "////", 4));        ret = (pszLine != NULL);      }      else if (EQUAL(firsttok, "MOTR"))      {        //read model        do         {          pszLine = CPLReadLine( fpItf );        }        while (pszLine && !EQUALN(pszLine, "////", 4));        ret = (pszLine != NULL);      }      else if (EQUAL(firsttok, "MTID"))      {      }      else if (EQUAL(firsttok, "MODL"))      {      }      else if (EQUAL(firsttok, "TOPI"))      {        topic = CPLStrdup(CSLGetField(tokens, 1));      }      else if (EQUAL(firsttok, "TABL"))      {        CPLDebug( "OGR_ILI", "Reading table '%s'", GetLayerNameString(topic, CSLGetField(tokens, 1)) );        curLayer = (OGRILI1Layer*)GetLayerByName(GetLayerNameString(topic, CSLGetField(tokens, 1)));        if (curLayer == NULL) { //create one          CPLDebug( "OGR_ILI", "No model found, using default field names." );          OGRSpatialReference *poSRSIn = NULL;          int bWriterIn = 0;          OGRwkbGeometryType eReqType = wkbUnknown;          OGRILI1DataSource *poDSIn = NULL;          curLayer = new OGRILI1Layer(GetLayerNameString(topic, CSLGetField(tokens, 1)), poSRSIn, bWriterIn, eReqType, poDSIn);          AddLayer(curLayer);        }        for (int i=0; i < curLayer->GetLayerDefn()->GetFieldCount(); i++) {          CPLDebug( "OGR_ILI", "Field %d: %s", i,  curLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef());        }        ret = ReadTable();      }      else if (EQUAL(firsttok, "ETOP"))      {      }      else if (EQUAL(firsttok, "EMOD"))      {      }      else if (EQUAL(firsttok, "ENDE"))      {        JoinSurfaceLayers();        PolygonizeAreaLayers();        return TRUE;      }      else      {        CPLDebug( "OGR_ILI", "Unexpected token: %s", firsttok );      }            CSLDestroy(tokens);    }    return ret;}int ILI1Reader::AddIliGeom(OGRFeature *feature, int iField, long fpos){#if defined(_WIN32) || defined(__WIN32__)    //Other positions on Windows !?#else    long nBlockLen = VSIFTell( fpItf )-fpos;    VSIFSeek( fpItf, fpos, SEEK_SET );    char *pszRawData = (char *) CPLMalloc(nBlockLen+1);    if( (int) VSIFRead( pszRawData, 1, nBlockLen, fpItf ) != nBlockLen )    {        CPLFree( pszRawData );        CPLError( CE_Failure, CPLE_FileIO, "Read of transfer file failed." );        return FALSE;    }    pszRawData[nBlockLen]= '\0';    feature->SetField(iField, pszRawData);#endif    return TRUE;}OGRMultiPolygon* ILI1Reader::Polygonize( OGRGeometryCollection* poLines ){    OGRMultiPolygon *poPolygon = new OGRMultiPolygon();#if defined(POLYGONIZE_AREAS)    GEOSGeom *ahInGeoms = NULL;    int       i = 0;        ahInGeoms = (GEOSGeom *) CPLCalloc(sizeof(void*),poLines->getNumGeometries());    for( i = 0; i < poLines->getNumGeometries(); i++ )        ahInGeoms[i] = poLines->getGeometryRef(i)->exportToGEOS();        GEOSGeom hResultGeom = GEOSPolygonize( ahInGeoms,                                            poLines->getNumGeometries() );    for( i = 0; i < poLines->getNumGeometries(); i++ )        GEOSGeom_destroy( ahInGeoms[i] );    CPLFree( ahInGeoms );    if( hResultGeom == NULL )        return NULL;    OGRGeometry *poMP = OGRGeometryFactory::createFromGEOS( hResultGeom );        GEOSGeom_destroy( hResultGeom );    return (OGRMultiPolygon *) poMP;#endif    return poPolygon;}void ILI1Reader::PolygonizeAreaLayers(){    for(int iLayer = 0; iLayer < nAreaLayers; iLayer++ )    {      OGRLayer *poAreaLayer = papoAreaLayers[iLayer];      OGRLayer *poLineLayer = papoAreaLineLayers[iLayer];

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?