1 : /******************************************************************************
2 : * $Id: ogrhtfdatasource.cpp 23042 2011-09-04 15:07:22Z rouault $
3 : *
4 : * Project: HTF Translator
5 : * Purpose: Implements OGRHTFDataSource class
6 : * Author: Even Rouault, even dot rouault at mines dash paris dot org
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2010, Even Rouault <even dot rouault at mines dash paris dot org>
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 :
30 : #include "ogr_htf.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 :
34 : CPL_CVSID("$Id: ogrhtfdatasource.cpp 23042 2011-09-04 15:07:22Z rouault $");
35 :
36 : /************************************************************************/
37 : /* OGRHTFDataSource() */
38 : /************************************************************************/
39 :
40 68 : OGRHTFDataSource::OGRHTFDataSource()
41 :
42 : {
43 68 : papoLayers = NULL;
44 68 : nLayers = 0;
45 68 : poMetadataLayer = NULL;
46 :
47 68 : pszName = NULL;
48 68 : }
49 :
50 : /************************************************************************/
51 : /* ~OGRHTFDataSource() */
52 : /************************************************************************/
53 :
54 68 : OGRHTFDataSource::~OGRHTFDataSource()
55 :
56 : {
57 80 : for( int i = 0; i < nLayers; i++ )
58 12 : delete papoLayers[i];
59 68 : CPLFree( papoLayers );
60 68 : delete poMetadataLayer;
61 :
62 68 : CPLFree( pszName );
63 68 : }
64 :
65 : /************************************************************************/
66 : /* TestCapability() */
67 : /************************************************************************/
68 :
69 0 : int OGRHTFDataSource::TestCapability( const char * pszCap )
70 :
71 : {
72 0 : return FALSE;
73 : }
74 :
75 : /************************************************************************/
76 : /* GetLayer() */
77 : /************************************************************************/
78 :
79 9 : OGRLayer *OGRHTFDataSource::GetLayer( int iLayer )
80 :
81 : {
82 9 : if( iLayer < 0 || iLayer >= nLayers )
83 0 : return NULL;
84 : else
85 9 : return papoLayers[iLayer];
86 : }
87 :
88 : /************************************************************************/
89 : /* GetLayerByName() */
90 : /************************************************************************/
91 :
92 12 : OGRLayer* OGRHTFDataSource::GetLayerByName( const char* pszLayerName )
93 : {
94 12 : if (nLayers == 0)
95 0 : return NULL;
96 12 : if (EQUAL(pszLayerName, "polygon"))
97 4 : return papoLayers[0];
98 8 : if (EQUAL(pszLayerName, "sounding"))
99 4 : return papoLayers[1];
100 4 : if (EQUAL(pszLayerName, "metadata"))
101 4 : return poMetadataLayer;
102 0 : return NULL;
103 : }
104 :
105 : /************************************************************************/
106 : /* Open() */
107 : /************************************************************************/
108 :
109 68 : int OGRHTFDataSource::Open( const char * pszFilename, int bUpdateIn)
110 :
111 : {
112 68 : if (bUpdateIn)
113 : {
114 11 : return FALSE;
115 : }
116 :
117 57 : pszName = CPLStrdup( pszFilename );
118 :
119 : // --------------------------------------------------------------------
120 : // Does this appear to be a .htf file?
121 : // --------------------------------------------------------------------
122 :
123 57 : VSILFILE* fp = VSIFOpenL(pszFilename, "rb");
124 57 : if (fp == NULL)
125 23 : return FALSE;
126 :
127 : char szBuffer[11];
128 34 : int nbRead = (int)VSIFReadL(szBuffer, 1, sizeof(szBuffer) - 1, fp);
129 34 : szBuffer[nbRead] = '\0';
130 :
131 34 : int bIsHTF = strcmp(szBuffer, "HTF HEADER") == 0;
132 34 : if (!bIsHTF)
133 : {
134 28 : VSIFCloseL(fp);
135 28 : return FALSE;
136 : }
137 :
138 6 : VSIFSeekL(fp, 0, SEEK_SET);
139 :
140 : const char* pszLine;
141 6 : int bEndOfHTFHeader = FALSE;
142 6 : int bIsSouth = FALSE;
143 6 : int bGeodeticDatumIsWGS84 = FALSE;
144 6 : int bIsUTM = FALSE;
145 6 : int nZone = 0;
146 6 : int nLines = 0;
147 6 : int bHasSWEasting = FALSE, bHasSWNorthing = FALSE, bHasNEEasting = FALSE, bHasNENorthing = FALSE;
148 6 : double dfSWEasting = 0, dfSWNorthing = 0, dfNEEasting = 0, dfNENorthing = 0;
149 6 : std::vector<CPLString> aosMD;
150 6 : int nTotalSoundings = 0;
151 300 : while( (pszLine = CPLReadLine2L(fp, 1024, NULL)) != NULL)
152 : {
153 294 : nLines ++;
154 294 : if (nLines == 1000)
155 : {
156 0 : break;
157 : }
158 294 : if (*pszLine == ';' || *pszLine == '\0')
159 0 : continue;
160 :
161 294 : if (strcmp(pszLine, "END OF HTF HEADER") == 0)
162 : {
163 6 : bEndOfHTFHeader = TRUE;
164 6 : break;
165 : }
166 :
167 288 : aosMD.push_back(pszLine);
168 :
169 288 : if (strncmp(pszLine, "GEODETIC DATUM: ", 16) == 0)
170 : {
171 6 : if (strcmp(pszLine + 16, "WG84") == 0 ||
172 : strcmp(pszLine + 16, "WGS84") == 0)
173 6 : bGeodeticDatumIsWGS84 = TRUE;
174 : else
175 : {
176 0 : VSIFCloseL(fp);
177 : CPLError(CE_Failure, CPLE_NotSupported,
178 0 : "Unsupported datum : %s", pszLine + 16);
179 0 : return FALSE;
180 : }
181 : }
182 282 : else if (strncmp(pszLine, "NE LATITUDE: -", 14) == 0)
183 6 : bIsSouth = TRUE;
184 276 : else if (strncmp(pszLine, "GRID REFERENCE SYSTEM: ", 23) == 0)
185 : {
186 6 : if (strncmp(pszLine + 23, "UTM", 3) == 0)
187 6 : bIsUTM = TRUE;
188 : else
189 : {
190 0 : VSIFCloseL(fp);
191 : CPLError(CE_Failure, CPLE_NotSupported,
192 0 : "Unsupported grid : %s", pszLine + 23);
193 0 : return FALSE;
194 : }
195 : }
196 270 : else if (strncmp(pszLine, "GRID ZONE: ", 11) == 0)
197 : {
198 6 : nZone = atoi(pszLine + 11);
199 : }
200 264 : else if (strncmp(pszLine, "SW GRID COORDINATE - EASTING: ", 30) == 0)
201 : {
202 6 : bHasSWEasting = TRUE;
203 6 : dfSWEasting = atof(pszLine + 30);
204 : }
205 258 : else if (strncmp(pszLine, "SW GRID COORDINATE - NORTHING: ", 31) == 0)
206 : {
207 6 : bHasSWNorthing = TRUE;
208 6 : dfSWNorthing = atof(pszLine + 31);
209 : }
210 252 : else if (strncmp(pszLine, "NE GRID COORDINATE - EASTING: ", 30) == 0)
211 : {
212 6 : bHasNEEasting = TRUE;
213 6 : dfNEEasting = atof(pszLine + 30);
214 : }
215 246 : else if (strncmp(pszLine, "NE GRID COORDINATE - NORTHING: ", 31) == 0)
216 : {
217 6 : bHasNENorthing = TRUE;
218 6 : dfNENorthing = atof(pszLine + 31);
219 : }
220 240 : else if (strncmp(pszLine, "TOTAL SOUNDINGS: ", 17) == 0)
221 : {
222 6 : nTotalSoundings = atoi(pszLine + 17);
223 : }
224 : }
225 :
226 6 : VSIFCloseL(fp);
227 :
228 6 : if (!bEndOfHTFHeader)
229 0 : return FALSE;
230 6 : if (!bGeodeticDatumIsWGS84)
231 0 : return FALSE;
232 6 : if (!bIsUTM)
233 0 : return FALSE;
234 6 : if (nZone == 0)
235 0 : return FALSE;
236 :
237 6 : nLayers = 2;
238 6 : papoLayers = (OGRHTFLayer**) CPLMalloc(sizeof(OGRHTFLayer*) * 2);
239 6 : papoLayers[0] = new OGRHTFPolygonLayer(pszFilename, nZone, !bIsSouth);
240 12 : papoLayers[1] = new OGRHTFSoundingLayer(pszFilename, nZone, !bIsSouth, nTotalSoundings);
241 :
242 12 : if (bHasSWEasting && bHasSWNorthing && bHasNEEasting && bHasNENorthing)
243 : {
244 6 : papoLayers[0]->SetExtent(dfSWEasting, dfSWNorthing, dfNEEasting, dfNENorthing);
245 6 : papoLayers[1]->SetExtent(dfSWEasting, dfSWNorthing, dfNEEasting, dfNENorthing);
246 : }
247 :
248 6 : poMetadataLayer = new OGRHTFMetadataLayer(aosMD);
249 :
250 6 : return TRUE;
251 : }
|