Skip to content

Commit a0454d5

Browse files
committed
CADRG writer: fix writing of resolution and interval parameters in CoverageSection
1 parent a3b7b01 commit a0454d5

File tree

1 file changed

+54
-33
lines changed

1 file changed

+54
-33
lines changed

frmts/nitf/rpfframewriter.cpp

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -363,13 +363,13 @@ static double GetPolarConstant(int nReciprocalScale)
363363
}
364364

365365
/************************************************************************/
366-
/* GetLatOrYInterval() */
366+
/* GetYPixelSize() */
367367
/************************************************************************/
368368

369369
/** Return the size of a pixel (in degree for non-polar zones, in meters for
370370
* polar zones), along the latitude/Y axis,
371371
* at specified scale and zone */
372-
static double GetLatOrYInterval(int nZone, int nReciprocalScale)
372+
static double GetYPixelSize(int nZone, int nReciprocalScale)
373373
{
374374
CPLAssert(RPFCADRGIsValidZone(nZone));
375375
const int nZoneIdx = (nZone - 1) % MAX_ZONE_NORTHERN_HEMISPHERE;
@@ -398,13 +398,13 @@ static double GetLatOrYInterval(int nZone, int nReciprocalScale)
398398
}
399399

400400
/************************************************************************/
401-
/* GetLonOrXInterval() */
401+
/* GetXPixelSize() */
402402
/************************************************************************/
403403

404404
/** Return the size of a pixel (in degree for non-polar zones, in meters for
405405
* polar zones), along the longitude/X axis,
406406
* at specified scale and zone */
407-
static double GetLonOrXInterval(int nZone, int nReciprocalScale)
407+
static double GetXPixelSize(int nZone, int nReciprocalScale)
408408
{
409409
CPLAssert(RPFCADRGIsValidZone(nZone));
410410
const int nZoneIdx = (nZone - MIN_ZONE) % MAX_ZONE_NORTHERN_HEMISPHERE;
@@ -456,18 +456,31 @@ void RPFGetCADRGResolutionAndInterval(int nZone, int nReciprocalScale,
456456
const double latCst_CADRG =
457457
std::round(latCst_ADRG / RATIO_PITCH_CADRG_OVER_ADRG / 4 / BLOCK_SIZE) *
458458
BLOCK_SIZE;
459-
latResolution = sZoneDef.latRes / N * latCst_ADRG / (4 * latCst_CADRG);
459+
double latResolutionLocal =
460+
sZoneDef.latRes / N * latCst_ADRG / (4 * latCst_CADRG);
460461

461462
const double A_s = sZoneDef.A * N;
462463
const double lonCst_ADRG =
463464
std::ceil(A_s / ADRG_BLOCK_SIZE) * ADRG_BLOCK_SIZE;
464465
const double lonCst_CADRG =
465466
std::round(lonCst_ADRG / RATIO_PITCH_CADRG_OVER_ADRG / BLOCK_SIZE) *
466467
BLOCK_SIZE;
467-
lonResolution = sZoneDef.lonRes / N * lonCst_ADRG / lonCst_CADRG;
468+
double lonResolutionLocal =
469+
sZoneDef.lonRes / N * lonCst_ADRG / lonCst_CADRG;
468470

469-
latInterval = 90.0 / latCst_CADRG;
470-
lonInterval = 360.0 / lonCst_CADRG;
471+
double latIntervalLocal = 90.0 / latCst_CADRG;
472+
double lonIntervalLocal = 360.0 / lonCst_CADRG;
473+
474+
if (nZoneIdx + MIN_ZONE == MAX_ZONE_NORTHERN_HEMISPHERE)
475+
{
476+
lonResolutionLocal = latResolutionLocal;
477+
lonIntervalLocal = latIntervalLocal;
478+
}
479+
480+
latResolution = latResolutionLocal;
481+
lonResolution = lonResolutionLocal;
482+
latInterval = latIntervalLocal;
483+
lonInterval = lonIntervalLocal;
471484
}
472485

473486
/************************************************************************/
@@ -492,7 +505,7 @@ static std::pair<double, double> GetMinMaxLatWithOverlap(int nZone,
492505
const int nZoneIdx = (nZone - MIN_ZONE) % MAX_ZONE_NORTHERN_HEMISPHERE;
493506
const auto &sZoneDef = asARCZoneDefinitions[nZoneIdx];
494507

495-
const double latInterval = GetLatOrYInterval(nZone, nReciprocalScale);
508+
const double latInterval = GetYPixelSize(nZone, nReciprocalScale);
496509
const double deltaLatFrame = latInterval * CADRG_FRAME_PIXEL_COUNT;
497510

498511
const double dfMinLat =
@@ -533,7 +546,7 @@ static int GetFrameCountAlongX(int nZone, int nReciprocalScale)
533546
{
534547
if (nZone == MAX_ZONE_NORTHERN_HEMISPHERE || nZone == MAX_ZONE)
535548
return GetPolarFrameCount(nReciprocalScale);
536-
const double lonInterval = GetLonOrXInterval(nZone, nReciprocalScale);
549+
const double lonInterval = GetXPixelSize(nZone, nReciprocalScale);
537550
const double eastWestPixelCst = 360.0 / lonInterval;
538551
CPLDebugOnly("CADRG", "eastWestPixelCst=%f, count=%f", eastWestPixelCst,
539552
eastWestPixelCst / CADRG_FRAME_PIXEL_COUNT);
@@ -550,7 +563,7 @@ static int GetFrameCountAlongY(int nZone, int nReciprocalScale)
550563
{
551564
if (nZone == MAX_ZONE_NORTHERN_HEMISPHERE || nZone == MAX_ZONE)
552565
return GetPolarFrameCount(nReciprocalScale);
553-
const double latInterval = GetLatOrYInterval(nZone, nReciprocalScale);
566+
const double latInterval = GetYPixelSize(nZone, nReciprocalScale);
554567
const double deltaLatFrame = latInterval * CADRG_FRAME_PIXEL_COUNT;
555568
const auto [dfMinLatZone, dfMaxLatZone] =
556569
GetMinMaxLatWithOverlap(nZone, nReciprocalScale);
@@ -671,8 +684,7 @@ RPFGetCADRGFramesForEnvelope(int nZoneIn, int nReciprocalScale,
671684
continue;
672685
}
673686
dfLastMaxLatZone = dfMaxLatZoneNorth;
674-
const double latInterval =
675-
GetLatOrYInterval(nZone, nReciprocalScale);
687+
const double latInterval = GetYPixelSize(nZone, nReciprocalScale);
676688
const double deltaLatFrame = latInterval * CADRG_FRAME_PIXEL_COUNT;
677689
const double dfFrameMinY =
678690
(std::max(sExtentWGS84.MinY, dfMinLatZone) - dfMinLatZone) /
@@ -685,8 +697,7 @@ RPFGetCADRGFramesForEnvelope(int nZoneIn, int nReciprocalScale,
685697
const int nFrameMinY = static_cast<int>(dfFrameMinY + EPSILON_1Em3);
686698
const int nFrameMaxY = static_cast<int>(dfFrameMaxY - EPSILON_1Em3);
687699

688-
const double lonInterval =
689-
GetLonOrXInterval(nZone, nReciprocalScale);
700+
const double lonInterval = GetXPixelSize(nZone, nReciprocalScale);
690701
const double deltaLonFrame = lonInterval * CADRG_FRAME_PIXEL_COUNT;
691702
const double dfFrameMinX =
692703
(std::max(sExtentWGS84.MinX, dfMinLonZone) - dfMinLonZone) /
@@ -759,9 +770,9 @@ RPFGetCADRGFramesForEnvelope(int nZoneIn, int nReciprocalScale,
759770
RPFFrameDef sDef;
760771
sDef.nZone = nZone;
761772
sDef.nReciprocalScale = nReciprocalScale;
762-
sDef.dfResX = GetLonOrXInterval(nZone, nReciprocalScale);
773+
sDef.dfResX = GetXPixelSize(nZone, nReciprocalScale);
763774
// will lead to same value as dfResX
764-
sDef.dfResY = GetLatOrYInterval(nZone, nReciprocalScale);
775+
sDef.dfResY = GetYPixelSize(nZone, nReciprocalScale);
765776
sDef.nFrameMinX =
766777
std::clamp(static_cast<int>((dfXMin / sDef.dfResX + R) /
767778
CADRG_FRAME_PIXEL_COUNT +
@@ -871,8 +882,8 @@ void RPFGetCADRGFrameExtent(int nZone, int nReciprocalScale, int nFrameX,
871882
double &dfXMax, double &dfYMax)
872883
{
873884
CPLAssert(RPFCADRGIsValidZone(nZone));
874-
const double dfXRes = GetLonOrXInterval(nZone, nReciprocalScale);
875-
const double dfYRes = GetLatOrYInterval(nZone, nReciprocalScale);
885+
const double dfXRes = GetXPixelSize(nZone, nReciprocalScale);
886+
const double dfYRes = GetYPixelSize(nZone, nReciprocalScale);
876887

877888
double dfXMinLocal, dfYMinLocal;
878889
if (nZone == MAX_ZONE_NORTHERN_HEMISPHERE || nZone == MAX_ZONE)
@@ -973,7 +984,7 @@ int RPFGetCADRGClosestReciprocalScale(GDALDataset *poSrcDS,
973984
{
974985
// This is actually zone independent
975986
const double dfLatInterval =
976-
GetLatOrYInterval(/* nZone = */ 1, nReciprocalScale);
987+
GetYPixelSize(/* nZone = */ 1, nReciprocalScale);
977988
if (nCandidateReciprocalScale == 0 &&
978989
dfLatInterval / dfYResAtNominalCADRGDPI > MAX_PROXIMITY_RATIO)
979990
{
@@ -1017,9 +1028,10 @@ int RPFGetCADRGClosestReciprocalScale(GDALDataset *poSrcDS,
10171028
/* Create_CADRG_CoverageSection() */
10181029
/************************************************************************/
10191030

1020-
static bool
1021-
Create_CADRG_CoverageSection(GDALOffsetPatcher::OffsetPatcher *offsetPatcher,
1022-
GDALDataset *poSrcDS, int nReciprocalScale)
1031+
static bool Create_CADRG_CoverageSection(
1032+
GDALOffsetPatcher::OffsetPatcher *offsetPatcher, GDALDataset *poSrcDS,
1033+
const std::string &osFilename, const CPLStringList &aosOptions,
1034+
int nReciprocalScale)
10231035
{
10241036
auto poBuffer = offsetPatcher->CreateBuffer(
10251037
"CoverageSectionSubheader", /* bEndiannessIsLittle = */ false);
@@ -1084,6 +1096,21 @@ Create_CADRG_CoverageSection(GDALOffsetPatcher::OffsetPatcher *offsetPatcher,
10841096
return dfLon;
10851097
};
10861098

1099+
int nZone = atoi(aosOptions.FetchNameValueDef("ZONE", "0"));
1100+
if (nZone < MIN_ZONE || nZone > MAX_ZONE)
1101+
{
1102+
const std::string osExt = CPLGetExtensionSafe(osFilename.c_str());
1103+
if (osExt.size() == 3)
1104+
nZone = RPFCADRGZoneCharToNum(osExt.back());
1105+
if (nZone < MIN_ZONE || nZone > MAX_ZONE)
1106+
{
1107+
const double dfMeanLat = (dfULY + dfLLY) / 2;
1108+
nZone = GetARCZoneFromLat(dfMeanLat);
1109+
if (nZone == 0)
1110+
return false;
1111+
}
1112+
}
1113+
10871114
// Upper left corner lat, lon
10881115
poBuffer->AppendFloat64(RoundIfCloseToInt(dfULY));
10891116
poBuffer->AppendFloat64(RoundIfCloseToInt(NormalizeToMinusPlus180(dfULX)));
@@ -1097,10 +1124,6 @@ Create_CADRG_CoverageSection(GDALOffsetPatcher::OffsetPatcher *offsetPatcher,
10971124
poBuffer->AppendFloat64(RoundIfCloseToInt(dfLRY));
10981125
poBuffer->AppendFloat64(RoundIfCloseToInt(NormalizeToMinusPlus180(dfLRX)));
10991126

1100-
const double dfMeanLat = (dfULY + dfLLY) / 2;
1101-
const int nZone = GetARCZoneFromLat(dfMeanLat);
1102-
if (nZone == 0)
1103-
return false;
11041127
double latResolution = 0;
11051128
double lonResolution = 0;
11061129
double latInterval = 0;
@@ -1599,8 +1622,8 @@ RPFFrameCreateCADRG_TREs(GDALOffsetPatcher::OffsetPatcher *offsetPatcher,
15991622

16001623
// Create buffers that will be written into file by RPFFrameWriteCADRG_RPFIMG()s
16011624
Create_CADRG_LocationComponent(offsetPatcher);
1602-
if (!Create_CADRG_CoverageSection(offsetPatcher, poSrcDS,
1603-
copyContext.nReciprocalScale))
1625+
if (!Create_CADRG_CoverageSection(offsetPatcher, poSrcDS, osFilename,
1626+
aosOptions, copyContext.nReciprocalScale))
16041627
return nullptr;
16051628
Create_CADRG_ColorGrayscaleSection(offsetPatcher);
16061629
Create_CADRG_ColormapSection(offsetPatcher, poSrcDS,
@@ -2981,10 +3004,8 @@ CADRGCreateCopy(const char *pszFilename, GDALDataset *poSrcDS, int bStrict,
29813004
frameDef.nFrameMinY = atoi(pszFrameY);
29823005
frameDef.nFrameMaxX = atoi(pszFrameX);
29833006
frameDef.nFrameMaxY = atoi(pszFrameY);
2984-
frameDef.dfResX =
2985-
GetLonOrXInterval(nZoneHint, nReciprocalScale);
2986-
frameDef.dfResY =
2987-
GetLatOrYInterval(nZoneHint, nReciprocalScale);
3007+
frameDef.dfResX = GetXPixelSize(nZoneHint, nReciprocalScale);
3008+
frameDef.dfResY = GetYPixelSize(nZoneHint, nReciprocalScale);
29883009

29893010
frameDefinitions.clear();
29903011
frameDefinitions.push_back(std::move(frameDef));

0 commit comments

Comments
 (0)