PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/gdal-1.6.1-tcl_patched/ogr/ogrsf_frmts/ili/ogrili2datasource.cpp

http://tcl-map.googlecode.com/
C++ | 312 lines | 181 code | 62 blank | 69 comment | 31 complexity | 4f38024a6fe82e9f9d816abf5375a346 MD5 | raw file
Possible License(s): LGPL-2.0, GPL-3.0, BSD-3-Clause, LGPL-3.0
  1. /******************************************************************************
  2. * $Id: ogrili2datasource.cpp 15089 2008-07-31 18:56:56Z rouault $
  3. *
  4. * Project: Interlis 2 Translator
  5. * Purpose: Implements OGRILI2DataSource 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. #include "ogr_ili2.h"
  30. #include "cpl_conv.h"
  31. #include "cpl_string.h"
  32. #include "ili2reader.h"
  33. #include "iomhelper.h"
  34. using namespace std;
  35. CPL_CVSID("$Id: ogrili2datasource.cpp 15089 2008-07-31 18:56:56Z rouault $");
  36. /************************************************************************/
  37. /* OGRILI2DataSource() */
  38. /************************************************************************/
  39. OGRILI2DataSource::OGRILI2DataSource()
  40. {
  41. pszName = NULL;
  42. poReader = NULL;
  43. fpTransfer = NULL;
  44. basket = NULL;
  45. nLayers = 0;
  46. papoLayers = NULL;
  47. }
  48. /************************************************************************/
  49. /* ~OGRILI2DataSource() */
  50. /************************************************************************/
  51. OGRILI2DataSource::~OGRILI2DataSource()
  52. {
  53. int i;
  54. for(i=0;i<nLayers;i++)
  55. {
  56. delete papoLayers[i];
  57. }
  58. CPLFree( papoLayers );
  59. if (basket) iom_releasebasket(basket);
  60. if (fpTransfer)
  61. {
  62. // write file
  63. iom_save(fpTransfer);
  64. // clean up
  65. iom_close(fpTransfer);
  66. iom_end();
  67. }
  68. DestroyILI2Reader( poReader );
  69. CPLFree( pszName );
  70. }
  71. /************************************************************************/
  72. /* Open() */
  73. /************************************************************************/
  74. int OGRILI2DataSource::Open( const char * pszNewName, int bTestOpen )
  75. {
  76. FILE *fp;
  77. char szHeader[1000];
  78. char **modelFilenames = NULL;
  79. char **filenames = CSLTokenizeString2( pszNewName, ",", 0 );
  80. pszName = CPLStrdup( filenames[0] );
  81. if( CSLCount(filenames) > 1 )
  82. modelFilenames = &filenames[1];
  83. /* -------------------------------------------------------------------- */
  84. /* Open the source file. */
  85. /* -------------------------------------------------------------------- */
  86. fp = VSIFOpen( pszName, "r" );
  87. if( fp == NULL )
  88. {
  89. if( !bTestOpen )
  90. CPLError( CE_Failure, CPLE_OpenFailed,
  91. "Failed to open ILI2 file `%s'.",
  92. pszNewName );
  93. CSLDestroy( filenames );
  94. return FALSE;
  95. }
  96. /* -------------------------------------------------------------------- */
  97. /* If we aren't sure it is ILI2, load a header chunk and check */
  98. /* for signs it is ILI2 */
  99. /* -------------------------------------------------------------------- */
  100. if( bTestOpen )
  101. {
  102. int nLen = (int)VSIFRead( szHeader, 1, sizeof(szHeader), fp );
  103. if (nLen == sizeof(szHeader))
  104. szHeader[sizeof(szHeader)-1] = '\0';
  105. else
  106. szHeader[nLen] = '\0';
  107. if( szHeader[0] != '<'
  108. || strstr(szHeader,"interlis.ch/INTERLIS2") == NULL )
  109. { // "www.interlis.ch/INTERLIS2.2"
  110. VSIFClose( fp );
  111. CSLDestroy( filenames );
  112. return FALSE;
  113. }
  114. }
  115. /* -------------------------------------------------------------------- */
  116. /* We assume now that it is ILI2. Close and instantiate a */
  117. /* ILI2Reader on it. */
  118. /* -------------------------------------------------------------------- */
  119. VSIFClose( fp );
  120. poReader = CreateILI2Reader();
  121. if( poReader == NULL )
  122. {
  123. CPLError( CE_Failure, CPLE_AppDefined,
  124. "File %s appears to be ILI2 but the ILI2 reader can't\n"
  125. "be instantiated, likely because Xerces support wasn't\n"
  126. "configured in.",
  127. pszNewName );
  128. CSLDestroy( filenames );
  129. return FALSE;
  130. }
  131. if (modelFilenames)
  132. poReader->ReadModel( modelFilenames );
  133. if( getenv( "ARC_DEGREES" ) != NULL ) {
  134. //No better way to pass arguments to the reader (it could even be an -lco arg)
  135. poReader->SetArcDegrees( atof( getenv("ARC_DEGREES") ) );
  136. }
  137. poReader->SetSourceFile( pszName );
  138. poReader->SaveClasses( pszName );
  139. listLayer = poReader->GetLayers();
  140. CSLDestroy( filenames );
  141. return TRUE;
  142. }
  143. /************************************************************************/
  144. /* Create() */
  145. /************************************************************************/
  146. int OGRILI2DataSource::Create( const char *pszFilename,
  147. char **papszOptions )
  148. {
  149. char **filenames = CSLTokenizeString2( pszFilename, ",", 0 );
  150. pszName = CPLStrdup(filenames[0]);
  151. const char *pszModelFilename = (CSLCount(filenames)>1) ? filenames[1] : NULL;
  152. if( pszModelFilename == NULL )
  153. {
  154. CPLError( CE_Warning, CPLE_OpenFailed,
  155. "Model file '%s' (%s) not found : %s.",
  156. pszModelFilename, pszFilename, VSIStrerror( errno ) );
  157. CSLDestroy(filenames);
  158. return FALSE;
  159. }
  160. iom_init();
  161. // set error listener to a iom provided one, that just
  162. // dumps all errors to stderr
  163. iom_seterrlistener(iom_stderrlistener);
  164. // compile ili model
  165. char *iliFiles[1] = {(char *)pszModelFilename};
  166. IOM_BASKET model=iom_compileIli(1,iliFiles);
  167. if(!model){
  168. CPLError( CE_Warning, CPLE_OpenFailed,
  169. "iom_compileIli %s, %s.",
  170. pszName, VSIStrerror( errno ) );
  171. iom_end();
  172. CSLDestroy(filenames);
  173. return FALSE;
  174. }
  175. // open new file
  176. fpTransfer=iom_open(pszName,IOM_CREATE | IOM_DONTREAD,0);
  177. if(!fpTransfer){
  178. CPLError( CE_Warning, CPLE_OpenFailed,
  179. "Failed to open %s.",
  180. pszName );
  181. CSLDestroy(filenames);
  182. return FALSE;
  183. }
  184. // set model of new file
  185. iom_setmodel(fpTransfer,model);
  186. iom_setheadsender(fpTransfer, pszModelFilename);
  187. iom_setheadcomment(fpTransfer,"Created by OGR");
  188. // create new basket
  189. static char basketname[512];
  190. basketname[0] = '\0';
  191. const char* val = GetAttrObjName(model, "iom04.metamodel.DataModel");
  192. if (val)
  193. {
  194. strcat(basketname, val);
  195. strcat(basketname, ".");
  196. val = GetAttrObjName(model, "iom04.metamodel.Topic");
  197. if (val) strcat(basketname, val);
  198. }
  199. else
  200. {
  201. strcat(basketname, "Basket");
  202. }
  203. CSLDestroy(filenames);
  204. basket=iom_newbasket(fpTransfer);
  205. iom_setbaskettag(basket, basketname);
  206. iom_setbasketoid(basket, "0");
  207. return TRUE;
  208. }
  209. /************************************************************************/
  210. /* CreateLayer() */
  211. /************************************************************************/
  212. OGRLayer *
  213. OGRILI2DataSource::CreateLayer( const char * pszLayerName,
  214. OGRSpatialReference *poSRS,
  215. OGRwkbGeometryType eType,
  216. char ** papszOptions )
  217. {
  218. OGRILI2Layer *poLayer = new OGRILI2Layer(pszLayerName, poSRS, TRUE, eType, this);
  219. nLayers ++;
  220. papoLayers = (OGRILI2Layer**)CPLRealloc(papoLayers, sizeof(OGRILI2Layer*) * nLayers);
  221. papoLayers[nLayers-1] = poLayer;
  222. return poLayer;
  223. }
  224. /************************************************************************/
  225. /* TestCapability() */
  226. /************************************************************************/
  227. int OGRILI2DataSource::TestCapability( const char * pszCap )
  228. {
  229. if( EQUAL(pszCap,ODsCCreateLayer) )
  230. return TRUE;
  231. else
  232. return FALSE;
  233. }
  234. /************************************************************************/
  235. /* GetLayer() */
  236. /************************************************************************/
  237. OGRLayer *OGRILI2DataSource::GetLayer( int iLayer )
  238. {
  239. list<OGRLayer *>::const_iterator layerIt = listLayer.begin();
  240. int i = 0;
  241. while (i < iLayer && layerIt != listLayer.end()) {
  242. i++;
  243. layerIt++;
  244. }
  245. if (i == iLayer) {
  246. OGRILI2Layer *tmpLayer = (OGRILI2Layer *)*layerIt;
  247. return tmpLayer;
  248. } else
  249. return NULL;
  250. }