EVOLUTION-MANAGER
Edit File: sdtsiref.cpp
/****************************************************************************** * $Id: sdtsiref.cpp 17434 2009-07-23 19:55:45Z chaitanya $ * * Project: SDTS Translator * Purpose: Implementation of SDTS_IREF class for reading IREF module. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #include "sdts_al.h" CPL_CVSID("$Id: sdtsiref.cpp 17434 2009-07-23 19:55:45Z chaitanya $"); /************************************************************************/ /* SDTS_IREF() */ /************************************************************************/ SDTS_IREF::SDTS_IREF() { dfXScale = 1.0; dfYScale = 1.0; dfXOffset = 0.0; dfYOffset = 0.0; dfXRes = 1.0; dfYRes = 1.0; pszXAxisName = CPLStrdup(""); pszYAxisName = CPLStrdup(""); pszCoordinateFormat = CPLStrdup(""); } /************************************************************************/ /* ~SDTS_IREF() */ /************************************************************************/ SDTS_IREF::~SDTS_IREF() { CPLFree( pszXAxisName ); CPLFree( pszYAxisName ); CPLFree( pszCoordinateFormat ); } /************************************************************************/ /* Read() */ /* */ /* Read the named file to initialize this structure. */ /************************************************************************/ int SDTS_IREF::Read( const char * pszFilename ) { DDFModule oIREFFile; DDFRecord *poRecord; /* -------------------------------------------------------------------- */ /* Open the file, and read the header. */ /* -------------------------------------------------------------------- */ if( !oIREFFile.Open( pszFilename ) ) return FALSE; /* -------------------------------------------------------------------- */ /* Read the first record, and verify that this is an IREF record. */ /* -------------------------------------------------------------------- */ poRecord = oIREFFile.ReadRecord(); if( poRecord == NULL ) return FALSE; if( poRecord->GetStringSubfield( "IREF", 0, "MODN", 0 ) == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Get the labels. */ /* -------------------------------------------------------------------- */ CPLFree( pszXAxisName ); pszXAxisName = CPLStrdup( poRecord->GetStringSubfield( "IREF", 0, "XLBL", 0 ) ); CPLFree( pszYAxisName ); pszYAxisName = CPLStrdup( poRecord->GetStringSubfield( "IREF", 0, "YLBL", 0 ) ); /* -------------------------------------------------------------------- */ /* Get the coordinate encoding. */ /* -------------------------------------------------------------------- */ CPLFree( pszCoordinateFormat ); pszCoordinateFormat = CPLStrdup( poRecord->GetStringSubfield( "IREF", 0, "HFMT", 0 ) ); /* -------------------------------------------------------------------- */ /* Get the transformation information, and resolution. */ /* -------------------------------------------------------------------- */ dfXScale = poRecord->GetFloatSubfield( "IREF", 0, "SFAX", 0 ); dfYScale = poRecord->GetFloatSubfield( "IREF", 0, "SFAY", 0 ); dfXOffset = poRecord->GetFloatSubfield( "IREF", 0, "XORG", 0 ); dfYOffset = poRecord->GetFloatSubfield( "IREF", 0, "YORG", 0 ); dfXRes = poRecord->GetFloatSubfield( "IREF", 0, "XHRS", 0 ); dfYRes = poRecord->GetFloatSubfield( "IREF", 0, "YHRS", 0 ); nDefaultSADRFormat = EQUAL(pszCoordinateFormat,"BI32"); return TRUE; } /************************************************************************/ /* GetSADRCount() */ /* */ /* Return the number of SADR'es in the passed field. */ /************************************************************************/ int SDTS_IREF::GetSADRCount( DDFField * poField ) { if( nDefaultSADRFormat ) return poField->GetDataSize() / SDTS_SIZEOF_SADR; else return poField->GetRepeatCount(); } /************************************************************************/ /* GetSADR() */ /************************************************************************/ int SDTS_IREF::GetSADR( DDFField * poField, int nVertices, double *padfX, double * padfY, double * padfZ ) { /* -------------------------------------------------------------------- */ /* For the sake of efficiency we depend on our knowledge that */ /* the SADR field is a series of bigendian int32's and decode */ /* them directly. */ /* -------------------------------------------------------------------- */ if( nDefaultSADRFormat && poField->GetFieldDefn()->GetSubfieldCount() == 2 ) { GInt32 anXY[2]; const char *pachRawData = poField->GetData(); CPLAssert( poField->GetDataSize() >= nVertices * SDTS_SIZEOF_SADR ); for( int iVertex = 0; iVertex < nVertices; iVertex++ ) { // we copy to a temp buffer to ensure it is world aligned. memcpy( anXY, pachRawData, 8 ); pachRawData += 8; // possibly byte swap, and always apply scale factor padfX[iVertex] = dfXOffset + dfXScale * ((int) CPL_MSBWORD32( anXY[0] )); padfY[iVertex] = dfYOffset + dfYScale * ((int) CPL_MSBWORD32( anXY[1] )); padfZ[iVertex] = 0.0; } } /* -------------------------------------------------------------------- */ /* This is the generic case. We assume either two or three */ /* subfields, and treat these as X, Y and Z regardless of */ /* name. */ /* -------------------------------------------------------------------- */ else { DDFFieldDefn *poFieldDefn = poField->GetFieldDefn(); int nBytesRemaining = poField->GetDataSize(); const char *pachFieldData = poField->GetData(); int iVertex; CPLAssert( poFieldDefn->GetSubfieldCount() == 2 || poFieldDefn->GetSubfieldCount() == 3 ); for( iVertex = 0; iVertex < nVertices; iVertex++ ) { double adfXYZ[3]; GByte *pabyBString; adfXYZ[2] = 0.0; for( int iEntry = 0; iEntry < poFieldDefn->GetSubfieldCount(); iEntry++ ) { int nBytesConsumed = 0; DDFSubfieldDefn *poSF = poFieldDefn->GetSubfield(iEntry); switch( poSF->GetType() ) { case DDFInt: adfXYZ[iEntry] = poSF->ExtractIntData( pachFieldData, nBytesRemaining, &nBytesConsumed ); break; case DDFFloat: adfXYZ[iEntry] = poSF->ExtractFloatData( pachFieldData, nBytesRemaining, &nBytesConsumed ); break; case DDFBinaryString: pabyBString = (GByte *) poSF->ExtractStringData( pachFieldData, nBytesRemaining, &nBytesConsumed ); if( EQUAL(pszCoordinateFormat,"BI32") ) { GInt32 nValue; memcpy( &nValue, pabyBString, 4 ); adfXYZ[iEntry] = ((int) CPL_MSBWORD32( nValue )); } else if( EQUAL(pszCoordinateFormat,"BI16") ) { GInt16 nValue; memcpy( &nValue, pabyBString, 2 ); adfXYZ[iEntry] = ((int) CPL_MSBWORD16( nValue )); } else if( EQUAL(pszCoordinateFormat,"BU32") ) { GUInt32 nValue; memcpy( &nValue, pabyBString, 4 ); adfXYZ[iEntry] = ((GUInt32) CPL_MSBWORD32( nValue )); } else if( EQUAL(pszCoordinateFormat,"BU16") ) { GUInt16 nValue; memcpy( &nValue, pabyBString, 2 ); adfXYZ[iEntry] = ((GUInt16) CPL_MSBWORD16( nValue )); } else if( EQUAL(pszCoordinateFormat,"BFP32") ) { float fValue; memcpy( &fValue, pabyBString, 4 ); CPL_MSBPTR32( &fValue ); adfXYZ[iEntry] = fValue; } else if( EQUAL(pszCoordinateFormat,"BFP64") ) { double dfValue; memcpy( &dfValue, pabyBString, 8 ); CPL_MSBPTR64( &dfValue ); adfXYZ[iEntry] = dfValue; } break; default: adfXYZ[iEntry] = 0.0; break; } pachFieldData += nBytesConsumed; nBytesRemaining -= nBytesConsumed; } /* next iEntry */ padfX[iVertex] = dfXOffset + adfXYZ[0] * dfXScale; padfY[iVertex] = dfYOffset + adfXYZ[1] * dfYScale; padfZ[iVertex] = adfXYZ[2]; } /* next iVertex */ } return TRUE; }