#include "gdal_pam.h"
CPL_CVSID("$Id: jdemdataset.cpp 27729 2014-09-24 00:40:16Z goatbar $");
CPL_C_START
void GDALRegister_JDEM(void);
CPL_C_END
static int JDEMGetField( char *pszField, int nWidth )
{
char szWork[32];
CPLAssert( nWidth < (int) sizeof(szWork) );
strncpy( szWork, pszField, nWidth );
szWork[nWidth] = '\0';
return atoi(szWork);
}
static double JDEMGetAngle( char *pszField )
{
int nAngle = JDEMGetField( pszField, 7 );
int nDegree, nMin, nSec;
nDegree = nAngle / 10000;
nMin = (nAngle / 100) % 100;
nSec = nAngle % 100;
return nDegree + nMin / 60.0 + nSec / 3600.0;
}
class JDEMRasterBand;
{
friend class JDEMRasterBand;
VSILFILE *fp;
GByte abyHeader[1012];
public:
JDEMDataset();
~JDEMDataset();
};
{
friend class JDEMDataset;
int nRecordSize;
char* pszRecord;
int bBufferAllocFailed;
public:
JDEMRasterBand( JDEMDataset *, int );
~JDEMRasterBand();
virtual CPLErr IReadBlock( int, int, void * );
};
JDEMRasterBand::JDEMRasterBand( JDEMDataset *poDS, int nBand )
{
this->poDS = poDS;
this->nBand = nBand;
nBlockXSize = poDS->GetRasterXSize();
nBlockYSize = 1;
nRecordSize = nBlockXSize*5 + 9 + 2;
pszRecord = NULL;
bBufferAllocFailed = FALSE;
}
JDEMRasterBand::~JDEMRasterBand()
{
VSIFree(pszRecord);
}
CPLErr JDEMRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, int nBlockYOff,
void * pImage )
{
JDEMDataset *poGDS = (JDEMDataset *) poDS;
if (pszRecord == NULL)
{
if (bBufferAllocFailed)
return CE_Failure;
pszRecord = (char *) VSIMalloc(nRecordSize);
if (pszRecord == NULL)
{
"Cannot allocate scanline buffer");
bBufferAllocFailed = TRUE;
return CE_Failure;
}
}
VSIFSeekL( poGDS->fp, 1011 + nRecordSize*nBlockYOff, SEEK_SET );
VSIFReadL( pszRecord, 1, nRecordSize, poGDS->fp );
if( !EQUALN((char *) poGDS->abyHeader,pszRecord,6) )
{
"JDEM Scanline corrupt. Perhaps file was not transferred\n"
"in binary mode?" );
return CE_Failure;
}
if( JDEMGetField( pszRecord + 6, 3 ) != nBlockYOff + 1 )
{
"JDEM scanline out of order, JDEM driver does not\n"
"currently support partial datasets." );
return CE_Failure;
}
for( int i = 0; i < nBlockXSize; i++ )
((float *) pImage)[i] = (float)
(JDEMGetField( pszRecord + 9 + 5 * i, 5) * 0.1);
return CE_None;
}
JDEMDataset::JDEMDataset() : fp(NULL)
{
fp = NULL;
}
JDEMDataset::~JDEMDataset()
{
FlushCache();
if( fp != NULL )
}
CPLErr JDEMDataset::GetGeoTransform( double * padfTransform )
{
double dfLLLat, dfLLLong, dfURLat, dfURLong;
dfLLLat = JDEMGetAngle( (char *) abyHeader + 29 );
dfLLLong = JDEMGetAngle( (char *) abyHeader + 36 );
dfURLat = JDEMGetAngle( (char *) abyHeader + 43 );
dfURLong = JDEMGetAngle( (char *) abyHeader + 50 );
padfTransform[0] = dfLLLong;
padfTransform[3] = dfURLat;
padfTransform[1] = (dfURLong - dfLLLong) / GetRasterXSize();
padfTransform[2] = 0.0;
padfTransform[4] = 0.0;
padfTransform[5] = -1 * (dfURLat - dfLLLat) / GetRasterYSize();
return CE_None;
}
const char *JDEMDataset::GetProjectionRef()
{
return( "GEOGCS[\"Tokyo\",DATUM[\"Tokyo\",SPHEROID[\"Bessel 1841\",6377397.155,299.1528128,AUTHORITY[\"EPSG\",7004]],TOWGS84[-148,507,685,0,0,0,0],AUTHORITY[\"EPSG\",6301]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",8901]],UNIT[\"DMSH\",0.0174532925199433,AUTHORITY[\"EPSG\",9108]],AUTHORITY[\"EPSG\",4301]]" );
}
{
if( poOpenInfo->nHeaderBytes < 50 )
return FALSE;
if( (!EQUALN((char *)poOpenInfo->pabyHeader+11,"19",2)
&& !EQUALN((char *)poOpenInfo->pabyHeader+11,"20",2))
|| (!EQUALN((char *)poOpenInfo->pabyHeader+15,"19",2)
&& !EQUALN((char *)poOpenInfo->pabyHeader+15,"20",2))
|| (!EQUALN((char *)poOpenInfo->pabyHeader+19,"19",2)
&& !EQUALN((char *)poOpenInfo->pabyHeader+19,"20",2)) )
{
return FALSE;
}
return TRUE;
}
{
if (!Identify(poOpenInfo))
return NULL;
{
CPLError( CE_Failure, CPLE_NotSupported,
"The JDEM driver does not support update access to existing"
" datasets.\n" );
return NULL;
}
JDEMDataset *poDS;
poDS = new JDEMDataset();
poDS->fp =
VSIFOpenL( poOpenInfo->pszFilename,
"rb" );
if (poDS->fp == NULL)
{
delete poDS;
return NULL;
}
VSIFReadL( poDS->abyHeader, 1, 1012, poDS->fp );
poDS->nRasterXSize = JDEMGetField( (char *) poDS->abyHeader + 23, 3 );
poDS->nRasterYSize = JDEMGetField( (char *) poDS->abyHeader + 26, 3 );
if (poDS->nRasterXSize <= 0 || poDS->nRasterYSize <= 0 )
{
"Invalid dimensions : %d x %d",
poDS->nRasterXSize, poDS->nRasterYSize);
delete poDS;
return NULL;
}
poDS->SetBand( 1, new JDEMRasterBand( poDS, 1 ));
poDS->SetDescription( poOpenInfo->pszFilename );
poDS->TryLoadXML();
poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
return( poDS );
}
void GDALRegister_JDEM()
{
{
"Japanese DEM (.mem)" );
"frmt_various.html#JDEM" );
poDriver->pfnOpen = JDEMDataset::Open;
poDriver->pfnIdentify = JDEMDataset::Identify;
}
}