1 : /******************************************************************************
2 : * $Id: sdtsiref.cpp 17434 2009-07-23 19:55:45Z chaitanya $
3 : *
4 : * Project: SDTS Translator
5 : * Purpose: Implementation of SDTS_IREF class for reading IREF module.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Frank Warmerdam
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 "sdts_al.h"
31 :
32 : CPL_CVSID("$Id: sdtsiref.cpp 17434 2009-07-23 19:55:45Z chaitanya $");
33 :
34 : /************************************************************************/
35 : /* SDTS_IREF() */
36 : /************************************************************************/
37 :
38 13 : SDTS_IREF::SDTS_IREF()
39 :
40 : {
41 13 : dfXScale = 1.0;
42 13 : dfYScale = 1.0;
43 13 : dfXOffset = 0.0;
44 13 : dfYOffset = 0.0;
45 13 : dfXRes = 1.0;
46 13 : dfYRes = 1.0;
47 :
48 13 : pszXAxisName = CPLStrdup("");
49 13 : pszYAxisName = CPLStrdup("");
50 13 : pszCoordinateFormat = CPLStrdup("");
51 13 : }
52 :
53 : /************************************************************************/
54 : /* ~SDTS_IREF() */
55 : /************************************************************************/
56 :
57 13 : SDTS_IREF::~SDTS_IREF()
58 : {
59 13 : CPLFree( pszXAxisName );
60 13 : CPLFree( pszYAxisName );
61 13 : CPLFree( pszCoordinateFormat );
62 13 : }
63 :
64 : /************************************************************************/
65 : /* Read() */
66 : /* */
67 : /* Read the named file to initialize this structure. */
68 : /************************************************************************/
69 :
70 3 : int SDTS_IREF::Read( const char * pszFilename )
71 :
72 : {
73 3 : DDFModule oIREFFile;
74 : DDFRecord *poRecord;
75 :
76 : /* -------------------------------------------------------------------- */
77 : /* Open the file, and read the header. */
78 : /* -------------------------------------------------------------------- */
79 3 : if( !oIREFFile.Open( pszFilename ) )
80 0 : return FALSE;
81 :
82 : /* -------------------------------------------------------------------- */
83 : /* Read the first record, and verify that this is an IREF record. */
84 : /* -------------------------------------------------------------------- */
85 3 : poRecord = oIREFFile.ReadRecord();
86 3 : if( poRecord == NULL )
87 0 : return FALSE;
88 :
89 3 : if( poRecord->GetStringSubfield( "IREF", 0, "MODN", 0 ) == NULL )
90 0 : return FALSE;
91 :
92 : /* -------------------------------------------------------------------- */
93 : /* Get the labels. */
94 : /* -------------------------------------------------------------------- */
95 3 : CPLFree( pszXAxisName );
96 : pszXAxisName = CPLStrdup( poRecord->GetStringSubfield( "IREF", 0,
97 3 : "XLBL", 0 ) );
98 3 : CPLFree( pszYAxisName );
99 : pszYAxisName = CPLStrdup( poRecord->GetStringSubfield( "IREF", 0,
100 3 : "YLBL", 0 ) );
101 :
102 : /* -------------------------------------------------------------------- */
103 : /* Get the coordinate encoding. */
104 : /* -------------------------------------------------------------------- */
105 3 : CPLFree( pszCoordinateFormat );
106 : pszCoordinateFormat =
107 3 : CPLStrdup( poRecord->GetStringSubfield( "IREF", 0, "HFMT", 0 ) );
108 :
109 : /* -------------------------------------------------------------------- */
110 : /* Get the transformation information, and resolution. */
111 : /* -------------------------------------------------------------------- */
112 3 : dfXScale = poRecord->GetFloatSubfield( "IREF", 0, "SFAX", 0 );
113 3 : dfYScale = poRecord->GetFloatSubfield( "IREF", 0, "SFAY", 0 );
114 :
115 3 : dfXOffset = poRecord->GetFloatSubfield( "IREF", 0, "XORG", 0 );
116 3 : dfYOffset = poRecord->GetFloatSubfield( "IREF", 0, "YORG", 0 );
117 :
118 3 : dfXRes = poRecord->GetFloatSubfield( "IREF", 0, "XHRS", 0 );
119 3 : dfYRes = poRecord->GetFloatSubfield( "IREF", 0, "YHRS", 0 );
120 :
121 3 : nDefaultSADRFormat = EQUAL(pszCoordinateFormat,"BI32");
122 :
123 3 : return TRUE;
124 : }
125 :
126 : /************************************************************************/
127 : /* GetSADRCount() */
128 : /* */
129 : /* Return the number of SADR'es in the passed field. */
130 : /************************************************************************/
131 :
132 55 : int SDTS_IREF::GetSADRCount( DDFField * poField )
133 :
134 : {
135 55 : if( nDefaultSADRFormat )
136 55 : return poField->GetDataSize() / SDTS_SIZEOF_SADR;
137 : else
138 0 : return poField->GetRepeatCount();
139 : }
140 :
141 : /************************************************************************/
142 : /* GetSADR() */
143 : /************************************************************************/
144 :
145 : int SDTS_IREF::GetSADR( DDFField * poField, int nVertices,
146 186 : double *padfX, double * padfY, double * padfZ )
147 :
148 : {
149 : /* -------------------------------------------------------------------- */
150 : /* For the sake of efficiency we depend on our knowledge that */
151 : /* the SADR field is a series of bigendian int32's and decode */
152 : /* them directly. */
153 : /* -------------------------------------------------------------------- */
154 186 : if( nDefaultSADRFormat
155 : && poField->GetFieldDefn()->GetSubfieldCount() == 2 )
156 : {
157 : GInt32 anXY[2];
158 184 : const char *pachRawData = poField->GetData();
159 :
160 184 : CPLAssert( poField->GetDataSize() >= nVertices * SDTS_SIZEOF_SADR );
161 :
162 1222 : for( int iVertex = 0; iVertex < nVertices; iVertex++ )
163 : {
164 : // we copy to a temp buffer to ensure it is world aligned.
165 1038 : memcpy( anXY, pachRawData, 8 );
166 1038 : pachRawData += 8;
167 :
168 : // possibly byte swap, and always apply scale factor
169 : padfX[iVertex] = dfXOffset
170 1038 : + dfXScale * ((int) CPL_MSBWORD32( anXY[0] ));
171 : padfY[iVertex] = dfYOffset
172 1038 : + dfYScale * ((int) CPL_MSBWORD32( anXY[1] ));
173 :
174 1038 : padfZ[iVertex] = 0.0;
175 : }
176 : }
177 :
178 : /* -------------------------------------------------------------------- */
179 : /* This is the generic case. We assume either two or three */
180 : /* subfields, and treat these as X, Y and Z regardless of */
181 : /* name. */
182 : /* -------------------------------------------------------------------- */
183 : else
184 : {
185 2 : DDFFieldDefn *poFieldDefn = poField->GetFieldDefn();
186 2 : int nBytesRemaining = poField->GetDataSize();
187 2 : const char *pachFieldData = poField->GetData();
188 : int iVertex;
189 :
190 2 : CPLAssert( poFieldDefn->GetSubfieldCount() == 2
191 : || poFieldDefn->GetSubfieldCount() == 3 );
192 :
193 4 : for( iVertex = 0; iVertex < nVertices; iVertex++ )
194 : {
195 : double adfXYZ[3];
196 : GByte *pabyBString;
197 :
198 2 : adfXYZ[2] = 0.0;
199 :
200 6 : for( int iEntry = 0;
201 : iEntry < poFieldDefn->GetSubfieldCount();
202 : iEntry++ )
203 : {
204 4 : int nBytesConsumed = 0;
205 4 : DDFSubfieldDefn *poSF = poFieldDefn->GetSubfield(iEntry);
206 :
207 4 : switch( poSF->GetType() )
208 : {
209 : case DDFInt:
210 : adfXYZ[iEntry] =
211 : poSF->ExtractIntData( pachFieldData,
212 : nBytesRemaining,
213 0 : &nBytesConsumed );
214 0 : break;
215 :
216 : case DDFFloat:
217 : adfXYZ[iEntry] =
218 : poSF->ExtractFloatData( pachFieldData,
219 : nBytesRemaining,
220 4 : &nBytesConsumed );
221 4 : break;
222 :
223 : case DDFBinaryString:
224 : pabyBString = (GByte *)
225 : poSF->ExtractStringData( pachFieldData,
226 : nBytesRemaining,
227 0 : &nBytesConsumed );
228 :
229 0 : if( EQUAL(pszCoordinateFormat,"BI32") )
230 : {
231 : GInt32 nValue;
232 0 : memcpy( &nValue, pabyBString, 4 );
233 0 : adfXYZ[iEntry] = ((int) CPL_MSBWORD32( nValue ));
234 : }
235 0 : else if( EQUAL(pszCoordinateFormat,"BI16") )
236 : {
237 : GInt16 nValue;
238 0 : memcpy( &nValue, pabyBString, 2 );
239 0 : adfXYZ[iEntry] = ((int) CPL_MSBWORD16( nValue ));
240 : }
241 0 : else if( EQUAL(pszCoordinateFormat,"BU32") )
242 : {
243 : GUInt32 nValue;
244 0 : memcpy( &nValue, pabyBString, 4 );
245 0 : adfXYZ[iEntry] = ((GUInt32) CPL_MSBWORD32( nValue ));
246 : }
247 0 : else if( EQUAL(pszCoordinateFormat,"BU16") )
248 : {
249 : GUInt16 nValue;
250 0 : memcpy( &nValue, pabyBString, 2 );
251 0 : adfXYZ[iEntry] = ((GUInt16) CPL_MSBWORD16( nValue ));
252 : }
253 0 : else if( EQUAL(pszCoordinateFormat,"BFP32") )
254 : {
255 : float fValue;
256 :
257 0 : memcpy( &fValue, pabyBString, 4 );
258 0 : CPL_MSBPTR32( &fValue );
259 0 : adfXYZ[iEntry] = fValue;
260 : }
261 0 : else if( EQUAL(pszCoordinateFormat,"BFP64") )
262 : {
263 : double dfValue;
264 :
265 0 : memcpy( &dfValue, pabyBString, 8 );
266 0 : CPL_MSBPTR64( &dfValue );
267 0 : adfXYZ[iEntry] = dfValue;
268 : }
269 0 : break;
270 :
271 : default:
272 0 : adfXYZ[iEntry] = 0.0;
273 : break;
274 : }
275 :
276 4 : pachFieldData += nBytesConsumed;
277 4 : nBytesRemaining -= nBytesConsumed;
278 : } /* next iEntry */
279 :
280 2 : padfX[iVertex] = dfXOffset + adfXYZ[0] * dfXScale;
281 2 : padfY[iVertex] = dfYOffset + adfXYZ[1] * dfYScale;
282 2 : padfZ[iVertex] = adfXYZ[2];
283 : } /* next iVertex */
284 : }
285 :
286 186 : return TRUE;
287 : }
288 :
|