Opened 19 years ago
Last modified 19 years ago
#788 closed defect (fixed)
NITF IGEOLO bounds interpretation
Reported by: | warmerdam | Owned by: | warmerdam |
---|---|---|---|
Priority: | high | Milestone: | |
Component: | GDAL_Raster | Version: | unspecified |
Severity: | normal | Keywords: | |
Cc: | david.carter@… |
Description
Hi Frank, Just noticed there is a bug in the NITF IGEOLO handling. According to the NITF spec, the IGEOLO field in the NITF header contains the four corner coordinates in the following order: (0,0),(0,MaxCol),(MaxRow,MaxCol),(MaxRow,0) where MaxCol = NCOLS - 1 and MaxRow = NROWS - 1. Note: MaxCol, MaxRow represents the topleft corner of the bottomright pixel, not the bottomright corner of the bottomright pixel. Consequently, I've made the following changes to nitfdataset.cpp: 1. On read, changed the following code: --------------------------------- poDS->adfGeoTransform[1] = (psImage->dfLRX - psImage->dfULX) / poDS->nRasterXSize; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = psImage->dfULY; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = (psImage->dfLRY - psImage->dfULY) / poDS->nRasterYSize; --------------------------------- to --------------------------------- poDS->adfGeoTransform[1] = (psImage->dfLRX - psImage->dfULX) / (poDS->nRasterXSize - 1); poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = psImage->dfULY; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = (psImage->dfLRY - psImage->dfULY) / (poDS->nRasterYSize - 1); --------------------------------- 2. On write, changed the following code: --------------------------------- dfURX = dfULX + padfGeoTransform[1] * nRasterXSize; dfURY = dfULY + padfGeoTransform[4] * nRasterXSize; dfLRX = dfULX + padfGeoTransform[1] * nRasterXSize + padfGeoTransform[2] * nRasterYSize; dfLRY = dfULY + padfGeoTransform[4] * nRasterXSize + padfGeoTransform[5] * nRasterYSize; dfLLX = dfULX + padfGeoTransform[2] * nRasterYSize; dfLLY = dfULY + padfGeoTransform[5] * nRasterYSize; --------------------------------- to --------------------------------- dfURX = dfULX + padfGeoTransform[1] * (nRasterXSize - 1); dfURY = dfULY + padfGeoTransform[4] * (nRasterXSize - 1); dfLRX = dfULX + padfGeoTransform[1] * (nRasterXSize - 1) + padfGeoTransform[2] * (nRasterYSize - 1); dfLRY = dfULY + padfGeoTransform[4] * (nRasterXSize - 1) + padfGeoTransform[5] * (nRasterYSize - 1); dfLLX = dfULX + padfGeoTransform[2] * (nRasterYSize - 1); dfLLY = dfULY + padfGeoTransform[5] * (nRasterYSize - 1); --------------------------------- David Carter
Change History (6)
comment:2 by , 19 years ago
2. Changed the following lines in NITFDataset::Open() (nitfdataset.cpp): ----------------------------------- poDS->bGotGeoTransform = TRUE; poDS->adfGeoTransform[0] = psImage->dfULX; poDS->adfGeoTransform[1] = (psImage->dfLRX - psImage->dfULX) / poDS->nRasterXSize; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = psImage->dfULY; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = (psImage->dfLRY - psImage->dfULY) / poDS->nRasterYSize; ----------------------------------- to: ----------------------------------- poDS->bGotGeoTransform = TRUE; poDS->adfGeoTransform[1] = (psImage->dfLRX - psImage->dfULX) / (poDS->nRasterXSize - 1); poDS->adfGeoTransform[5] = (psImage->dfLRY - psImage->dfULY) / (poDS->nRasterYSize - 1); poDS->adfGeoTransform[0] = psImage->dfULX - 0.5 * poDS->adfGeoTransform[1]; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = psImage->dfULY - 0.5 * poDS->adfGeoTransform[5]; poDS->adfGeoTransform[4] = 0.0; ----------------------------------- 3. Changed the following lines in NITFDataset::SetGeoTransform() (nitfdataset.cpp): ----------------------------------- dfULX = padfGeoTransform[0]; dfULY = padfGeoTransform[3]; dfURX = dfULX + padfGeoTransform[1] * nRasterXSize; dfURY = dfULY + padfGeoTransform[4] * nRasterXSize; dfLRX = dfULX + padfGeoTransform[1] * nRasterXSize + padfGeoTransform[2] * nRasterYSize; dfLRY = dfULY + padfGeoTransform[4] * nRasterXSize + padfGeoTransform[5] * nRasterYSize; dfLLX = dfULX + padfGeoTransform[2] * nRasterYSize; dfLLY = dfULY + padfGeoTransform[5] * nRasterYSize; ----------------------------------- to: ----------------------------------- dfULX = padfGeoTransform[0] + 0.5 * padfGeoTransform[1] + 0.5 * padfGeoTransform[2]; dfULY = padfGeoTransform[3] + 0.5 * padfGeoTransform[4] + 0.5 * padfGeoTransform[5]; dfURX = dfULX + padfGeoTransform[1] * (nRasterXSize - 1); dfURY = dfULY + padfGeoTransform[4] * (nRasterXSize - 1); dfLRX = dfULX + padfGeoTransform[1] * (nRasterXSize - 1) + padfGeoTransform[2] * (nRasterYSize - 1); dfLRY = dfULY + padfGeoTransform[4] * (nRasterXSize - 1) + padfGeoTransform[5] * (nRasterYSize - 1); dfLLX = dfULX + padfGeoTransform[2] * (nRasterYSize - 1); dfLLY = dfULY + padfGeoTransform[5] * (nRasterYSize - 1); ----------------------------------- David Carter Software Developer ER Mapper
comment:3 by , 19 years ago
Hi Frank, I received a response to my question about the IGEOLO field in NITF subheader (see below). As stated below, the NITF standard does not address my question, but the Compendium of Controlled Extensions, Image Chip (ICHIP) specification does. It specifies the center of the pixel as the registration point. So I'm inclined to use the pixel center, but I guess it's not that important because the IGEOLO field is only approximate and not intended for analytical purposes. David Carter Software Developer ER Mapper
comment:4 by , 19 years ago
Hi Frank, I noticed the bugzilla bug report did not include the contents of the email (see attached) I received from Bridget Durham (JITC NITF Lab) in response to my question. To quote Bridget: "...the NITF standard itself does not address this question, but the Compendium of Controlled Extensions, Image Chip (ICHIP) specification does. It specifies the center of the pixel as this point." This was the main reason I thought it would be better to use the pixel centre. I also reasoned that if you use the pixel centre, you'll be at most 1/2 pixel out if some other application associates the IGEOLO coordinates with the pixel corners.
comment:5 by , 19 years ago
I am now in the situation where I am *generally* willing to treat the IGEOLO as the center of the corner pixels. However, I am pretty confident that the RPF CoverageSectionSubheader is in terms of outer pixel edges, and it is also transmitted via the NITFImage dfULX/etc fields. So the IGEOLO changes cannot safely be applied as shown. I think the solution would be to still treat the psImage bounds as they are now (as outer edges), and to apply adjustments in the code that reads and writes from IGEOLO.
comment:6 by , 19 years ago
David's IGEOLO changes have now been incorporated (in altered form) into GDAL.
Note:
See TracTickets
for help on using tickets.