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 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 ****************************************************************************/
28
29 #include "cpl_conv.h"
30 #include "cpl_string.h"
31 #include "idrisi.h"
32 #include "ogr_idrisi.h"
33
34 CPL_CVSID("$Id: ogridrisidatasource.cpp ce778433e8ac725886855a39d2fe26f25aaf1fa4 2021-03-12 12:42:06 +0100 Even Rouault $")
35
36 /************************************************************************/
37 /* OGRIdrisiDataSource() */
38 /************************************************************************/
39
OGRIdrisiDataSource()40 OGRIdrisiDataSource::OGRIdrisiDataSource() :
41 pszName(nullptr),
42 papoLayers(nullptr),
43 nLayers(0)
44 {}
45
46 /************************************************************************/
47 /* ~OGRIdrisiDataSource() */
48 /************************************************************************/
49
~OGRIdrisiDataSource()50 OGRIdrisiDataSource::~OGRIdrisiDataSource()
51
52 {
53 CPLFree( pszName );
54 for( int i = 0; i < nLayers; i++ )
55 delete papoLayers[i];
56 CPLFree( papoLayers );
57 }
58
59 /************************************************************************/
60 /* TestCapability() */
61 /************************************************************************/
62
TestCapability(const char *)63 int OGRIdrisiDataSource::TestCapability( const char * /* pszCap */ )
64 {
65 return FALSE;
66 }
67
68 /************************************************************************/
69 /* GetLayer() */
70 /************************************************************************/
71
GetLayer(int iLayer)72 OGRLayer *OGRIdrisiDataSource::GetLayer( int iLayer )
73
74 {
75 if( iLayer < 0 || iLayer >= nLayers )
76 return nullptr;
77
78 return papoLayers[iLayer];
79 }
80
81 /************************************************************************/
82 /* Open() */
83 /************************************************************************/
84
Open(const char * pszFilename)85 int OGRIdrisiDataSource::Open( const char * pszFilename )
86
87 {
88 pszName = CPLStrdup( pszFilename );
89
90 VSILFILE* fpVCT = VSIFOpenL(pszFilename, "rb");
91 if (fpVCT == nullptr)
92 return FALSE;
93
94 // --------------------------------------------------------------------
95 // Look for .vdc file
96 // --------------------------------------------------------------------
97 const char* pszVDCFilename = CPLResetExtension(pszFilename, "vdc");
98 VSILFILE* fpVDC = VSIFOpenL(pszVDCFilename, "rb");
99 if (fpVDC == nullptr)
100 {
101 pszVDCFilename = CPLResetExtension(pszFilename, "VDC");
102 fpVDC = VSIFOpenL(pszVDCFilename, "rb");
103 }
104
105 char** papszVDC = nullptr;
106 if (fpVDC != nullptr)
107 {
108 VSIFCloseL(fpVDC);
109 fpVDC = nullptr;
110
111 CPLPushErrorHandler(CPLQuietErrorHandler);
112 papszVDC = CSLLoad2(pszVDCFilename, 1024, 256, nullptr);
113 CPLPopErrorHandler();
114 CPLErrorReset();
115 }
116
117 OGRwkbGeometryType eType = wkbUnknown;
118
119 char* pszWTKString = nullptr;
120 if (papszVDC != nullptr)
121 {
122 CSLSetNameValueSeparator( papszVDC, ":" );
123
124 const char *pszVersion = CSLFetchNameValue( papszVDC, "file format" );
125
126 if( pszVersion == nullptr || !EQUAL( pszVersion, "IDRISI Vector A.1" ) )
127 {
128 CSLDestroy( papszVDC );
129 VSIFCloseL(fpVCT);
130 return FALSE;
131 }
132
133 const char *pszRefSystem
134 = CSLFetchNameValue( papszVDC, "ref. system" );
135 const char *pszRefUnits = CSLFetchNameValue( papszVDC, "ref. units" );
136
137 if (pszRefSystem != nullptr && pszRefUnits != nullptr)
138 IdrisiGeoReference2Wkt( pszFilename, pszRefSystem, pszRefUnits,
139 &pszWTKString);
140 }
141
142 GByte chType = 0;
143 if (VSIFReadL(&chType, 1, 1, fpVCT) != 1)
144 {
145 VSIFCloseL(fpVCT);
146 CSLDestroy( papszVDC );
147 CPLFree(pszWTKString);
148 return FALSE;
149 }
150
151 if (chType == 1)
152 eType = wkbPoint;
153 else if (chType == 2)
154 eType = wkbLineString;
155 else if (chType == 3)
156 eType = wkbPolygon;
157 else
158 {
159 CPLError( CE_Failure, CPLE_AppDefined, "Unsupported geometry type : %d",
160 static_cast<int>(chType) );
161 VSIFCloseL(fpVCT);
162 CSLDestroy( papszVDC );
163 CPLFree(pszWTKString);
164 return FALSE;
165 }
166
167 const char *pszMinX = CSLFetchNameValue( papszVDC, "min. X" );
168 const char *pszMaxX = CSLFetchNameValue( papszVDC, "max. X" );
169 const char *pszMinY = CSLFetchNameValue( papszVDC, "min. Y" );
170 const char *pszMaxY = CSLFetchNameValue( papszVDC, "max. Y" );
171
172 OGRIdrisiLayer* poLayer = new OGRIdrisiLayer(pszFilename,
173 CPLGetBasename(pszFilename),
174 fpVCT, eType, pszWTKString);
175 papoLayers = static_cast<OGRLayer**>( CPLMalloc(sizeof(OGRLayer*)) );
176 papoLayers[nLayers ++] = poLayer;
177
178 if( pszMinX != nullptr && pszMaxX != nullptr && pszMinY != nullptr &&
179 pszMaxY != nullptr)
180 {
181 poLayer->SetExtent(
182 CPLAtof(pszMinX), CPLAtof(pszMinY), CPLAtof(pszMaxX),
183 CPLAtof(pszMaxY) );
184 }
185
186 CPLFree(pszWTKString);
187
188 CSLDestroy( papszVDC );
189
190 return TRUE;
191 }
192