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 : * 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 : /************************************************************************/
35 : /* OGRIdrisiDataSource() */
36 : /************************************************************************/
37 :
38 3 : OGRIdrisiDataSource::OGRIdrisiDataSource()
39 3 : : pszName(nullptr), papoLayers(nullptr), nLayers(0)
40 : {
41 3 : }
42 :
43 : /************************************************************************/
44 : /* ~OGRIdrisiDataSource() */
45 : /************************************************************************/
46 :
47 6 : OGRIdrisiDataSource::~OGRIdrisiDataSource()
48 :
49 : {
50 3 : CPLFree(pszName);
51 6 : for (int i = 0; i < nLayers; i++)
52 3 : delete papoLayers[i];
53 3 : CPLFree(papoLayers);
54 6 : }
55 :
56 : /************************************************************************/
57 : /* TestCapability() */
58 : /************************************************************************/
59 :
60 0 : int OGRIdrisiDataSource::TestCapability(const char * /* pszCap */)
61 : {
62 0 : return FALSE;
63 : }
64 :
65 : /************************************************************************/
66 : /* GetLayer() */
67 : /************************************************************************/
68 :
69 3 : OGRLayer *OGRIdrisiDataSource::GetLayer(int iLayer)
70 :
71 : {
72 3 : if (iLayer < 0 || iLayer >= nLayers)
73 0 : return nullptr;
74 :
75 3 : return papoLayers[iLayer];
76 : }
77 :
78 : /************************************************************************/
79 : /* Open() */
80 : /************************************************************************/
81 :
82 3 : int OGRIdrisiDataSource::Open(const char *pszFilename)
83 :
84 : {
85 3 : pszName = CPLStrdup(pszFilename);
86 :
87 3 : VSILFILE *fpVCT = VSIFOpenL(pszFilename, "rb");
88 3 : if (fpVCT == nullptr)
89 0 : return FALSE;
90 :
91 : // --------------------------------------------------------------------
92 : // Look for .vdc file
93 : // --------------------------------------------------------------------
94 3 : const char *pszVDCFilename = CPLResetExtension(pszFilename, "vdc");
95 3 : VSILFILE *fpVDC = VSIFOpenL(pszVDCFilename, "rb");
96 3 : if (fpVDC == nullptr)
97 : {
98 0 : pszVDCFilename = CPLResetExtension(pszFilename, "VDC");
99 0 : fpVDC = VSIFOpenL(pszVDCFilename, "rb");
100 : }
101 :
102 3 : char **papszVDC = nullptr;
103 3 : if (fpVDC != nullptr)
104 : {
105 3 : VSIFCloseL(fpVDC);
106 3 : fpVDC = nullptr;
107 :
108 3 : CPLPushErrorHandler(CPLQuietErrorHandler);
109 3 : papszVDC = CSLLoad2(pszVDCFilename, 1024, 256, nullptr);
110 3 : CPLPopErrorHandler();
111 3 : CPLErrorReset();
112 : }
113 :
114 3 : OGRwkbGeometryType eType = wkbUnknown;
115 :
116 3 : char *pszWTKString = nullptr;
117 3 : if (papszVDC != nullptr)
118 : {
119 3 : CSLSetNameValueSeparator(papszVDC, ":");
120 :
121 3 : const char *pszVersion = CSLFetchNameValue(papszVDC, "file format");
122 :
123 3 : if (pszVersion == nullptr || !EQUAL(pszVersion, "IDRISI Vector A.1"))
124 : {
125 0 : CSLDestroy(papszVDC);
126 0 : VSIFCloseL(fpVCT);
127 0 : return FALSE;
128 : }
129 :
130 3 : const char *pszRefSystem = CSLFetchNameValue(papszVDC, "ref. system");
131 3 : const char *pszRefUnits = CSLFetchNameValue(papszVDC, "ref. units");
132 :
133 3 : if (pszRefSystem != nullptr && pszRefUnits != nullptr)
134 : {
135 6 : OGRSpatialReference oSRS;
136 3 : IdrisiGeoReference2Wkt(pszFilename, pszRefSystem, pszRefUnits,
137 : oSRS);
138 3 : if (!oSRS.IsEmpty())
139 : {
140 3 : oSRS.exportToWkt(&pszWTKString);
141 : }
142 : }
143 : }
144 :
145 3 : GByte chType = 0;
146 3 : if (VSIFReadL(&chType, 1, 1, fpVCT) != 1)
147 : {
148 0 : VSIFCloseL(fpVCT);
149 0 : CSLDestroy(papszVDC);
150 0 : CPLFree(pszWTKString);
151 0 : return FALSE;
152 : }
153 :
154 3 : if (chType == 1)
155 1 : eType = wkbPoint;
156 2 : else if (chType == 2)
157 1 : eType = wkbLineString;
158 1 : else if (chType == 3)
159 1 : eType = wkbPolygon;
160 : else
161 : {
162 0 : CPLError(CE_Failure, CPLE_AppDefined, "Unsupported geometry type : %d",
163 : static_cast<int>(chType));
164 0 : VSIFCloseL(fpVCT);
165 0 : CSLDestroy(papszVDC);
166 0 : CPLFree(pszWTKString);
167 0 : return FALSE;
168 : }
169 :
170 3 : const char *pszMinX = CSLFetchNameValue(papszVDC, "min. X");
171 3 : const char *pszMaxX = CSLFetchNameValue(papszVDC, "max. X");
172 3 : const char *pszMinY = CSLFetchNameValue(papszVDC, "min. Y");
173 3 : const char *pszMaxY = CSLFetchNameValue(papszVDC, "max. Y");
174 :
175 : OGRIdrisiLayer *poLayer = new OGRIdrisiLayer(
176 3 : pszFilename, CPLGetBasename(pszFilename), fpVCT, eType, pszWTKString);
177 3 : papoLayers = static_cast<OGRLayer **>(CPLMalloc(sizeof(OGRLayer *)));
178 3 : papoLayers[nLayers++] = poLayer;
179 :
180 3 : if (pszMinX != nullptr && pszMaxX != nullptr && pszMinY != nullptr &&
181 : pszMaxY != nullptr)
182 : {
183 3 : poLayer->SetExtent(CPLAtof(pszMinX), CPLAtof(pszMinY), CPLAtof(pszMaxX),
184 : CPLAtof(pszMaxY));
185 : }
186 :
187 3 : CPLFree(pszWTKString);
188 :
189 3 : CSLDestroy(papszVDC);
190 :
191 3 : return TRUE;
192 : }
|