Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: Idrisi Translator 4 : * Purpose: Implements OGRIdrisiDataSource class 5 : * Author: Even Rouault, even dot rouault at spatialys.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2011-2012, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "cpl_conv.h" 14 : #include "cpl_string.h" 15 : #include "idrisi.h" 16 : #include "ogr_idrisi.h" 17 : 18 : /************************************************************************/ 19 : /* OGRIdrisiDataSource() */ 20 : /************************************************************************/ 21 : 22 : OGRIdrisiDataSource::OGRIdrisiDataSource() = default; 23 : 24 : /************************************************************************/ 25 : /* ~OGRIdrisiDataSource() */ 26 : /************************************************************************/ 27 : 28 6 : OGRIdrisiDataSource::~OGRIdrisiDataSource() 29 : 30 : { 31 6 : for (int i = 0; i < nLayers; i++) 32 3 : delete papoLayers[i]; 33 3 : CPLFree(papoLayers); 34 6 : } 35 : 36 : /************************************************************************/ 37 : /* GetLayer() */ 38 : /************************************************************************/ 39 : 40 3 : OGRLayer *OGRIdrisiDataSource::GetLayer(int iLayer) 41 : 42 : { 43 3 : if (iLayer < 0 || iLayer >= nLayers) 44 0 : return nullptr; 45 : 46 3 : return papoLayers[iLayer]; 47 : } 48 : 49 : /************************************************************************/ 50 : /* Open() */ 51 : /************************************************************************/ 52 : 53 3 : int OGRIdrisiDataSource::Open(const char *pszFilename) 54 : 55 : { 56 3 : VSILFILE *fpVCT = VSIFOpenL(pszFilename, "rb"); 57 3 : if (fpVCT == nullptr) 58 0 : return FALSE; 59 : 60 : // -------------------------------------------------------------------- 61 : // Look for .vdc file 62 : // -------------------------------------------------------------------- 63 3 : const char *pszVDCFilename = CPLResetExtension(pszFilename, "vdc"); 64 3 : VSILFILE *fpVDC = VSIFOpenL(pszVDCFilename, "rb"); 65 3 : if (fpVDC == nullptr) 66 : { 67 0 : pszVDCFilename = CPLResetExtension(pszFilename, "VDC"); 68 0 : fpVDC = VSIFOpenL(pszVDCFilename, "rb"); 69 : } 70 : 71 3 : char **papszVDC = nullptr; 72 3 : if (fpVDC != nullptr) 73 : { 74 3 : VSIFCloseL(fpVDC); 75 3 : fpVDC = nullptr; 76 : 77 3 : CPLPushErrorHandler(CPLQuietErrorHandler); 78 3 : papszVDC = CSLLoad2(pszVDCFilename, 1024, 256, nullptr); 79 3 : CPLPopErrorHandler(); 80 3 : CPLErrorReset(); 81 : } 82 : 83 3 : OGRwkbGeometryType eType = wkbUnknown; 84 : 85 3 : char *pszWTKString = nullptr; 86 3 : if (papszVDC != nullptr) 87 : { 88 3 : CSLSetNameValueSeparator(papszVDC, ":"); 89 : 90 3 : const char *pszVersion = CSLFetchNameValue(papszVDC, "file format"); 91 : 92 3 : if (pszVersion == nullptr || !EQUAL(pszVersion, "IDRISI Vector A.1")) 93 : { 94 0 : CSLDestroy(papszVDC); 95 0 : VSIFCloseL(fpVCT); 96 0 : return FALSE; 97 : } 98 : 99 3 : const char *pszRefSystem = CSLFetchNameValue(papszVDC, "ref. system"); 100 3 : const char *pszRefUnits = CSLFetchNameValue(papszVDC, "ref. units"); 101 : 102 3 : if (pszRefSystem != nullptr && pszRefUnits != nullptr) 103 : { 104 6 : OGRSpatialReference oSRS; 105 3 : IdrisiGeoReference2Wkt(pszFilename, pszRefSystem, pszRefUnits, 106 : oSRS); 107 3 : if (!oSRS.IsEmpty()) 108 : { 109 3 : oSRS.exportToWkt(&pszWTKString); 110 : } 111 : } 112 : } 113 : 114 3 : GByte chType = 0; 115 3 : if (VSIFReadL(&chType, 1, 1, fpVCT) != 1) 116 : { 117 0 : VSIFCloseL(fpVCT); 118 0 : CSLDestroy(papszVDC); 119 0 : CPLFree(pszWTKString); 120 0 : return FALSE; 121 : } 122 : 123 3 : if (chType == 1) 124 1 : eType = wkbPoint; 125 2 : else if (chType == 2) 126 1 : eType = wkbLineString; 127 1 : else if (chType == 3) 128 1 : eType = wkbPolygon; 129 : else 130 : { 131 0 : CPLError(CE_Failure, CPLE_AppDefined, "Unsupported geometry type : %d", 132 : static_cast<int>(chType)); 133 0 : VSIFCloseL(fpVCT); 134 0 : CSLDestroy(papszVDC); 135 0 : CPLFree(pszWTKString); 136 0 : return FALSE; 137 : } 138 : 139 3 : const char *pszMinX = CSLFetchNameValue(papszVDC, "min. X"); 140 3 : const char *pszMaxX = CSLFetchNameValue(papszVDC, "max. X"); 141 3 : const char *pszMinY = CSLFetchNameValue(papszVDC, "min. Y"); 142 3 : const char *pszMaxY = CSLFetchNameValue(papszVDC, "max. Y"); 143 : 144 : OGRIdrisiLayer *poLayer = new OGRIdrisiLayer( 145 3 : pszFilename, CPLGetBasename(pszFilename), fpVCT, eType, pszWTKString); 146 3 : papoLayers = static_cast<OGRLayer **>(CPLMalloc(sizeof(OGRLayer *))); 147 3 : papoLayers[nLayers++] = poLayer; 148 : 149 3 : if (pszMinX != nullptr && pszMaxX != nullptr && pszMinY != nullptr && 150 : pszMaxY != nullptr) 151 : { 152 3 : poLayer->SetExtent(CPLAtof(pszMinX), CPLAtof(pszMinY), CPLAtof(pszMaxX), 153 : CPLAtof(pszMaxY)); 154 : } 155 : 156 3 : CPLFree(pszWTKString); 157 : 158 3 : CSLDestroy(papszVDC); 159 : 160 3 : return TRUE; 161 : }