#include "gdal_frmts.h"
#include "gdal_pam.h"
#include <algorithm>
CPL_CVSID("$Id: jdemdataset.cpp dbe2c476beb384094e80251a819e5b667886f754 2017-12-22 15:41:03Z Even Rouault $")
static int JDEMGetField( const char *pszField, int nWidth )
{
char szWork[32] = {};
CPLAssert(nWidth < static_cast<int>(
sizeof(szWork)));
strncpy(szWork, pszField, nWidth);
szWork[nWidth] = '\0';
return atoi(szWork);
}
static double JDEMGetAngle( const char *pszField )
{
const int nAngle = JDEMGetField(pszField, 7);
const int nDegree = nAngle / 10000;
const int nMin = (nAngle / 100) % 100;
const int nSec = nAngle % 100;
return nDegree + nMin / 60.0 + nSec / 3600.0;
}
class JDEMRasterBand;
{
friend class JDEMRasterBand;
public:
JDEMDataset();
~JDEMDataset();
};
{
friend class JDEMDataset;
int nRecordSize;
char *pszRecord;
bool bBufferAllocFailed;
public:
JDEMRasterBand( JDEMDataset *, int );
virtual ~JDEMRasterBand();
virtual CPLErr IReadBlock(
int,
int,
void * )
override;
};
JDEMRasterBand::JDEMRasterBand( JDEMDataset *poDSIn, int nBandIn ) :
nRecordSize(poDSIn->GetRasterXSize() * 5 + 9 + 2),
pszRecord(nullptr),
bBufferAllocFailed(false)
{
poDS = poDSIn;
nBand = nBandIn;
nBlockXSize = poDS->GetRasterXSize();
nBlockYSize = 1;
}
JDEMRasterBand::~JDEMRasterBand() {
VSIFree(pszRecord); }
int nBlockYOff,
void * pImage )
{
JDEMDataset *poGDS = static_cast<JDEMDataset *>(poDS);
if (pszRecord == nullptr)
{
if (bBufferAllocFailed)
return CE_Failure;
if (pszRecord == nullptr)
{
bBufferAllocFailed = true;
return CE_Failure;
}
}
CPL_IGNORE_RET_VAL(
VSIFSeekL(poGDS->fp, 1011 + nRecordSize * nBlockYOff, SEEK_SET));
CPL_IGNORE_RET_VAL(
VSIFReadL(pszRecord, 1, nRecordSize, poGDS->fp));
if( !
EQUALN(reinterpret_cast<char *>(poGDS->abyHeader), pszRecord, 6) )
{
"JDEM Scanline corrupt. Perhaps file was not transferred "
"in binary mode?");
return CE_Failure;
}
if( JDEMGetField(pszRecord + 6, 3) != nBlockYOff + 1 )
{
"JDEM scanline out of order, JDEM driver does not "
"currently support partial datasets.");
return CE_Failure;
}
for( int i = 0; i < nBlockXSize; i++ )
static_cast<float *>(pImage)[i] =
JDEMGetField(pszRecord + 9 + 5 * i, 5) * 0.1f;
return CE_None;
}
JDEMDataset::JDEMDataset() :
fp(nullptr)
{
std::fill_n(abyHeader,
CPL_ARRAYSIZE(abyHeader), static_cast<GByte>(0));
}
JDEMDataset::~JDEMDataset()
{
FlushCache();
if( fp != nullptr )
}
CPLErr JDEMDataset::GetGeoTransform(
double *padfTransform )
{
const char *psHeader = reinterpret_cast<char *>(abyHeader);
const double dfLLLat = JDEMGetAngle(psHeader + 29);
const double dfLLLong = JDEMGetAngle(psHeader + 36);
const double dfURLat = JDEMGetAngle(psHeader + 43);
const double dfURLong = JDEMGetAngle(psHeader + 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]]";
}
{
return FALSE;
const char *psHeader =
reinterpret_cast<char *
>(poOpenInfo->
pabyHeader);
{
return FALSE;
}
return TRUE;
}
{
if (!Identify(poOpenInfo))
return nullptr;
{
"The JDEM driver does not support update access to existing "
"datasets.");
return nullptr;
}
if( poOpenInfo->
fpL ==
nullptr )
{
return nullptr;
}
JDEMDataset *poDS = new JDEMDataset();
poDS->fp = poOpenInfo->
fpL;
poOpenInfo->
fpL =
nullptr;
CPL_IGNORE_RET_VAL(
VSIFReadL(poDS->abyHeader, 1, 1012, poDS->fp));
const char *psHeader = reinterpret_cast<char *>(poDS->abyHeader);
poDS->nRasterXSize = JDEMGetField(psHeader + 23, 3);
poDS->nRasterYSize = JDEMGetField(psHeader + 26, 3);
if( poDS->nRasterXSize <= 0 || poDS->nRasterYSize <= 0 )
{
"Invalid dimensions : %d x %d",
poDS->nRasterXSize, poDS->nRasterYSize);
delete poDS;
return nullptr;
}
poDS->SetBand(1, new JDEMRasterBand(poDS, 1));
poDS->TryLoadXML();
poDS->oOvManager.Initialize(poDS, poOpenInfo->
pszFilename);
return poDS;
}
void GDALRegister_JDEM()
{
return;
poDriver->pfnOpen = JDEMDataset::Open;
poDriver->pfnIdentify = JDEMDataset::Identify;
}