?? ili1reader.cpp
字號:
/****************************************************************************** * $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];
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -