Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: MSG Native Reader
4 : * Purpose: Base class for reading in the headers of MSG native images
5 : * Author: Frans van den Bergh, fvdbergh@csir.co.za
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2005, Frans van den Bergh <fvdbergh@csir.co.za>
9 : *
10 : * Permission is hereby granted, free of charge, to any person obtaining a
11 : * copy of this software and associated documentation files (the "Software"),
12 : * to deal in the Software without restriction, including without limitation
13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 : * and/or sell copies of the Software, and to permit persons to whom the
15 : * Software is furnished to do so, subject to the following conditions:
16 : *
17 : * The above copyright notice and this permission notice shall be included
18 : * in all copies or substantial portions of the Software.
19 : *
20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 : * DEALINGS IN THE SOFTWARE.
27 : ****************************************************************************/
28 :
29 : #include "cpl_port.h"
30 : #include "cpl_error.h"
31 :
32 : #include "msg_reader_core.h"
33 : #include "msg_basic_types.h"
34 : #include <stdio.h>
35 : #include <string.h>
36 : #include <math.h>
37 :
38 : #ifdef DEBUG
39 : #ifdef GDAL_SUPPORT
40 : #undef DEBUG
41 : #endif
42 : #endif
43 :
44 : #ifdef GDAL_SUPPORT
45 : #include "cpl_vsi.h"
46 :
47 : #else
48 : #define VSIFSeek(fp, pos, ref) CPL_IGNORE_RET_VAL(fseek(fp, pos, ref))
49 : #define VSIFRead(p, bs, nb, fp) CPL_IGNORE_RET_VAL(fread(p, bs, nb, fp))
50 : #endif
51 :
52 : namespace msg_native_format
53 : {
54 :
55 : const Blackbody_lut_type Msg_reader_core::Blackbody_LUT[MSG_NUM_CHANNELS + 1] =
56 : {
57 : {0, 0, 0}, // dummy channel
58 : {0, 0, 0}, // N/A
59 : {0, 0, 0}, // N/A
60 : {0, 0, 0}, // N/A
61 : {2569.094, 0.9959, 3.471},
62 : {1598.566, 0.9963, 2.219},
63 : {1362.142, 0.9991, 0.485},
64 : {1149.083, 0.9996, 0.181},
65 : {1034.345, 0.9999, 0.060},
66 : {930.659, 0.9983, 0.627},
67 : {839.661, 0.9988, 0.397},
68 : {752.381, 0.9981, 0.576},
69 : {0, 0, 0} // N/A
70 : };
71 :
72 0 : static void PhDataInit(PH_DATA *data)
73 : {
74 0 : data->name[0] = '\0';
75 0 : data->value[0] = '\0';
76 0 : }
77 :
78 0 : static void SecondaryProdHeaderInit(SECONDARY_PROD_HEADER *header)
79 : {
80 0 : PhDataInit(&header->abid);
81 0 : PhDataInit(&header->smod);
82 0 : PhDataInit(&header->apxs);
83 0 : PhDataInit(&header->avpa);
84 0 : PhDataInit(&header->lscd);
85 0 : PhDataInit(&header->lmap);
86 0 : PhDataInit(&header->qdlc);
87 0 : PhDataInit(&header->qdlp);
88 0 : PhDataInit(&header->qqai);
89 0 : PhDataInit(&header->selectedBandIds);
90 0 : PhDataInit(&header->southLineSelectedRectangle);
91 0 : PhDataInit(&header->northLineSelectedRectangle);
92 0 : PhDataInit(&header->eastColumnSelectedRectangle);
93 0 : PhDataInit(&header->westColumnSelectedRectangle);
94 0 : }
95 :
96 0 : Msg_reader_core::Msg_reader_core(const char *fname)
97 : : _lines(0), _columns(0), _line_start(0), _col_start(0),
98 : _col_dir_step(0.0f), _line_dir_step(0.0f), _hrv_col_dir_step(0.0f),
99 : _hrv_line_dir_step(0.0f), _f_data_offset(0), _f_data_size(0),
100 : _f_header_offset(0), _f_header_size(0), _f_trailer_offset(0),
101 : _f_trailer_size(0), _visir_bytes_per_line(0), _visir_packet_size(0),
102 : _hrv_bytes_per_line(0), _hrv_packet_size(0), _interline_spacing(0),
103 0 : _year(0), _month(0), _day(0), _hour(0), _minute(0), _open_success(false)
104 : {
105 0 : memset(&_main_header, 0, sizeof(_main_header));
106 0 : memset(&_sec_header, 0, sizeof(_sec_header));
107 0 : SecondaryProdHeaderInit(&_sec_header);
108 0 : for (size_t i = 0; i < MSG_NUM_CHANNELS; ++i)
109 : {
110 0 : _calibration[i].cal_slope = 0.0;
111 0 : _calibration[i].cal_offset = 0.0;
112 : }
113 0 : memset(&_img_desc_record, 0, sizeof(_img_desc_record));
114 :
115 0 : VSILFILE *fin = VSIFOpenL(fname, "rb");
116 0 : if (!fin)
117 : {
118 0 : CPLError(CE_Failure, CPLE_OpenFailed, "Could not open file %s", fname);
119 0 : return;
120 : }
121 0 : read_metadata_block(fin);
122 0 : VSIFCloseL(fin);
123 : }
124 :
125 0 : Msg_reader_core::Msg_reader_core(VSILFILE *fp)
126 : : _lines(0), _columns(0), _line_start(0), _col_start(0),
127 : _col_dir_step(0.0f), _line_dir_step(0.0f), _hrv_col_dir_step(0.0f),
128 : _hrv_line_dir_step(0.0f), _f_data_offset(0), _f_data_size(0),
129 : _f_header_offset(0), _f_header_size(0), _f_trailer_offset(0),
130 : _f_trailer_size(0), _visir_bytes_per_line(0), _visir_packet_size(0),
131 : _hrv_bytes_per_line(0), _hrv_packet_size(0), _interline_spacing(0),
132 0 : _year(0), _month(0), _day(0), _hour(0), _minute(0), _open_success(false)
133 : {
134 0 : memset(&_main_header, 0, sizeof(_main_header));
135 0 : memset(&_sec_header, 0, sizeof(_sec_header));
136 :
137 0 : SecondaryProdHeaderInit(&_sec_header);
138 0 : for (size_t i = 0; i < MSG_NUM_CHANNELS; ++i)
139 : {
140 0 : _calibration[i].cal_slope = 0.0;
141 0 : _calibration[i].cal_offset = 0.0;
142 : }
143 0 : memset(&_img_desc_record, 0, sizeof(_img_desc_record));
144 :
145 0 : read_metadata_block(fp);
146 0 : }
147 :
148 0 : void Msg_reader_core::read_metadata_block(VSILFILE *fin)
149 : {
150 0 : _open_success = true;
151 :
152 : unsigned int i;
153 :
154 0 : CPL_IGNORE_RET_VAL(VSIFReadL(&_main_header, sizeof(_main_header), 1, fin));
155 0 : CPL_IGNORE_RET_VAL(VSIFReadL(&_sec_header, sizeof(_sec_header), 1, fin));
156 :
157 : PH_DATA_ID *hdi;
158 :
159 : #ifdef DEBUG
160 : // print out all the fields in the header
161 : PH_DATA *hd = (PH_DATA *)&_main_header;
162 : for (i = 0; i < 6; i++)
163 : {
164 : to_string(*hd);
165 : printf("[%02u] %s %s", i, hd->name, hd->value); /*ok*/
166 : hd++;
167 : }
168 :
169 : hdi = (PH_DATA_ID *)&_main_header.dataSetIdentification;
170 : for (i = 0; i < 5; i++)
171 : {
172 : printf("%s %s %s", hdi->name, hdi->size, hdi->address); /*ok*/
173 : hdi++;
174 : }
175 :
176 : hd = (PH_DATA *)(&_main_header.totalFileSize);
177 : for (i = 0; i < 19; i++)
178 : {
179 : to_string(*hd);
180 : printf("[%02u] %s %s", i, hd->name, hd->value); /*ok*/
181 : hd++;
182 : }
183 : #endif // DEBUG
184 :
185 : // extract data & header positions
186 :
187 0 : for (i = 0; i < 5; i++)
188 : {
189 0 : hdi = (PH_DATA_ID *)&_main_header.dataSetIdentification[i];
190 0 : if (STARTS_WITH(hdi->name, "15Header"))
191 : {
192 0 : sscanf(hdi->size, "%u", &_f_header_size);
193 0 : sscanf(hdi->address, "%u", &_f_header_offset);
194 : }
195 0 : else if (STARTS_WITH(hdi->name, "15Trailer"))
196 : {
197 0 : sscanf(hdi->size, "%u", &_f_trailer_size);
198 0 : sscanf(hdi->address, "%u", &_f_trailer_offset);
199 : }
200 0 : else if (STARTS_WITH(hdi->name, "15Data"))
201 : {
202 0 : sscanf(hdi->size, "%u", &_f_data_size);
203 0 : sscanf(hdi->address, "%u", &_f_data_offset);
204 : }
205 : }
206 : #ifdef DEBUG
207 : printf("Data: %u %u\n", _f_data_offset, _f_data_size); /*ok*/
208 : printf("Header: %u %u\n", _f_header_offset, _f_header_size); /*ok*/
209 : printf("Trailer: %u %u\n", _f_trailer_offset, _f_trailer_size); /*ok*/
210 : #endif // DEBUG
211 :
212 : unsigned int lines;
213 0 : sscanf(_sec_header.northLineSelectedRectangle.value, "%u", &_lines);
214 0 : sscanf(_sec_header.southLineSelectedRectangle.value, "%u", &lines);
215 0 : _line_start = lines;
216 0 : if (lines > 0 &&
217 0 : _lines >=
218 0 : lines -
219 : 1) // if starting N of S edge, _lines counts what's there...
220 0 : _lines -= lines - 1;
221 :
222 : unsigned int cols;
223 0 : sscanf(_sec_header.westColumnSelectedRectangle.value, "%u", &_columns);
224 0 : sscanf(_sec_header.eastColumnSelectedRectangle.value, "%u", &cols);
225 0 : _col_start = cols;
226 0 : if (cols > 0 &&
227 0 : _columns >=
228 0 : cols - 1) // if starting W of the E edge, _cols counts what's there
229 0 : _columns -= cols - 1;
230 :
231 : #ifdef DEBUG
232 : printf("lines = %u, cols = %u\n", _lines, _columns); /*ok*/
233 : int records_per_line = 0;
234 : #endif // DEBUG
235 :
236 0 : for (i = 0; i < MSG_NUM_CHANNELS; i++)
237 : {
238 0 : if (_sec_header.selectedBandIds.value[i] == 'X')
239 : {
240 0 : _bands[i] = 1;
241 : #ifdef DEBUG
242 : records_per_line += (i == (MSG_NUM_CHANNELS - 1)) ? 3 : 1;
243 : #endif // DEBUG
244 : }
245 : else
246 : {
247 0 : _bands[i] = 0;
248 : }
249 : }
250 :
251 : #ifdef DEBUG
252 : printf("reading a total of %d records per line\n", records_per_line); /*ok*/
253 : #endif // DEBUG
254 :
255 : // extract time fields, assume that SNIT is the correct field:
256 0 : sscanf(_main_header.snit.value + 0, "%04u", &_year);
257 0 : sscanf(_main_header.snit.value + 4, "%02u", &_month);
258 0 : sscanf(_main_header.snit.value + 6, "%02u", &_day);
259 0 : sscanf(_main_header.snit.value + 8, "%02u", &_hour);
260 0 : sscanf(_main_header.snit.value + 10, "%02u", &_minute);
261 :
262 : // read radiometric block
263 : RADIOMETRIC_PROCESSING_RECORD rad;
264 0 : off_t offset = RADIOMETRICPROCESSING_RECORD_OFFSET + _f_header_offset +
265 0 : sizeof(GP_PK_HEADER) + sizeof(GP_PK_SH1) + 1;
266 0 : CPL_IGNORE_RET_VAL(VSIFSeekL(fin, offset, SEEK_SET));
267 0 : CPL_IGNORE_RET_VAL(
268 0 : VSIFReadL(&rad, sizeof(RADIOMETRIC_PROCESSING_RECORD), 1, fin));
269 0 : to_native(rad);
270 0 : memcpy((void *)_calibration, (void *)&rad.level1_5ImageCalibration,
271 : sizeof(_calibration));
272 :
273 : #ifdef DEBUG
274 : for (i = 0; i < MSG_NUM_CHANNELS; i++)
275 : {
276 : if (_calibration[i].cal_slope < 0 || _calibration[i].cal_slope > 0.4)
277 : {
278 : printf(/*ok*/ "Warning: calibration slope (%f) out of nominal "
279 : "range. MSG "
280 : "reader probably broken\n",
281 : _calibration[i].cal_slope);
282 : }
283 : if (_calibration[i].cal_offset > 0 || _calibration[i].cal_offset < -20)
284 : {
285 : printf(/*ok*/ "Warning: calibration offset (%f) out of nominal "
286 : "range. MSG "
287 : "reader probably broken\n",
288 : _calibration[i].cal_offset);
289 : }
290 : }
291 : #endif
292 :
293 : // read image description block
294 0 : IMAGE_DESCRIPTION_RECORD &idr = _img_desc_record;
295 0 : offset = RADIOMETRICPROCESSING_RECORD_OFFSET -
296 0 : IMAGEDESCRIPTION_RECORD_LENGTH + _f_header_offset +
297 0 : sizeof(GP_PK_HEADER) + sizeof(GP_PK_SH1) + 1;
298 0 : CPL_IGNORE_RET_VAL(VSIFSeekL(fin, offset, SEEK_SET));
299 0 : CPL_IGNORE_RET_VAL(
300 0 : VSIFReadL(&idr, sizeof(IMAGE_DESCRIPTION_RECORD), 1, fin));
301 0 : to_native(idr);
302 0 : CPLDebugOnly("MSGN", "idr.longitudeOfSSP = %g", idr.longitudeOfSSP);
303 0 : CPLDebugOnly("MSGN",
304 : "referencegrid_visir.numberOfLines = %d, "
305 : "referencegrid_visir.numberOfColumns = %d",
306 : idr.referencegrid_visir.numberOfLines,
307 : idr.referencegrid_visir.numberOfColumns);
308 0 : _line_dir_step = idr.referencegrid_visir.lineDirGridStep;
309 0 : _col_dir_step = idr.referencegrid_visir.columnDirGridStep;
310 0 : _hrv_line_dir_step = idr.referencegrid_hrv.lineDirGridStep;
311 0 : _hrv_col_dir_step = idr.referencegrid_hrv.columnDirGridStep;
312 :
313 0 : CPLDebugOnly("MSGN",
314 : "referencegrid_hrv.numberOfLines = %d, "
315 : "referencegrid_hrv.numberOfColumns = %d",
316 : idr.referencegrid_hrv.numberOfLines,
317 : idr.referencegrid_hrv.numberOfColumns);
318 :
319 0 : CPLDebugOnly("MSGN",
320 : "plannedCoverage_hrv.lowerSouthLinePlanned = %d, \n"
321 : "plannedCoverage_hrv.lowerNorthLinePlanned = %d, \n"
322 : "plannedCoverage_hrv.lowerEastColumnPlanned = %d, \n "
323 : "plannedCoverage_hrv.lowerWestColumnPlanned = %d",
324 : idr.plannedCoverage_hrv.lowerSouthLinePlanned,
325 : idr.plannedCoverage_hrv.lowerNorthLinePlanned,
326 : idr.plannedCoverage_hrv.lowerEastColumnPlanned,
327 : idr.plannedCoverage_hrv.lowerWestColumnPlanned);
328 :
329 0 : CPLDebugOnly("MSGN",
330 : "plannedCoverage_hrv.upperSouthLinePlanned = %d, \n"
331 : "plannedCoverage_hrv.upperNorthLinePlanned = %d, \n"
332 : "plannedCoverage_hrv.upperEastColumnPlanned = %d, \n "
333 : "plannedCoverage_hrv.upperWestColumnPlanned = %d",
334 : idr.plannedCoverage_hrv.upperSouthLinePlanned,
335 : idr.plannedCoverage_hrv.upperNorthLinePlanned,
336 : idr.plannedCoverage_hrv.upperEastColumnPlanned,
337 : idr.plannedCoverage_hrv.upperWestColumnPlanned);
338 :
339 : // Rather convoluted, but this code is required to compute the real data
340 : // block sizes It does this by reading in the first line of every band, to
341 : // get to the packet size field
342 : GP_PK_HEADER gp_header;
343 : GP_PK_SH1 sub_header;
344 : SUB_VISIRLINE visir_line;
345 :
346 0 : CPL_IGNORE_RET_VAL(VSIFSeekL(fin, _f_data_offset, SEEK_SET));
347 :
348 0 : _hrv_packet_size = 0;
349 0 : _interline_spacing = 0;
350 0 : visir_line.channelId = 0;
351 :
352 : int scanned_bands[MSG_NUM_CHANNELS];
353 0 : int band_count = 0;
354 0 : for (i = 0; i < MSG_NUM_CHANNELS; i++)
355 : {
356 0 : scanned_bands[i] = _bands[i];
357 0 : band_count += _bands[i];
358 : }
359 :
360 0 : do
361 : {
362 0 : if (VSIFReadL(&gp_header, sizeof(GP_PK_HEADER), 1, fin) != 1 ||
363 0 : VSIFReadL(&sub_header, sizeof(GP_PK_SH1), 1, fin) != 1 ||
364 0 : VSIFReadL(&visir_line, sizeof(SUB_VISIRLINE), 1, fin) != 1)
365 : {
366 0 : _open_success = false;
367 0 : break;
368 : }
369 0 : to_native(visir_line);
370 0 : to_native(gp_header);
371 :
372 0 : CPLDebugOnly("MSGN",
373 : "channelId = %d, lineNumber = %d, packetLength = %u",
374 : visir_line.channelId, visir_line.lineNumberInVisirGrid,
375 : gp_header.packetLength);
376 :
377 0 : to_native(sub_header);
378 :
379 0 : CPLDebugOnly("MSGN",
380 : "subheader spacecraft = %d, day = %u, sec = %.3f",
381 : sub_header.spacecraftId, sub_header.packetTime.day,
382 : sub_header.packetTime.ms / 1000.0);
383 :
384 : // Sanity checks
385 0 : if (gp_header.packetLength <
386 0 : sizeof(GP_PK_SH1) + sizeof(SUB_VISIRLINE) - 1 ||
387 0 : gp_header.packetLength > 100 * 1024 * 1024)
388 : {
389 0 : _open_success = false;
390 0 : break;
391 : }
392 :
393 : // skip over the actual line data
394 0 : CPL_IGNORE_RET_VAL(
395 0 : VSIFSeekL(fin,
396 0 : gp_header.packetLength -
397 : (sizeof(GP_PK_SH1) + sizeof(SUB_VISIRLINE) - 1),
398 : SEEK_CUR));
399 :
400 0 : if (visir_line.channelId == 0 ||
401 0 : visir_line.channelId > MSG_NUM_CHANNELS)
402 : {
403 0 : _open_success = false;
404 0 : break;
405 : }
406 :
407 0 : if (scanned_bands[visir_line.channelId - 1])
408 : {
409 0 : scanned_bands[visir_line.channelId - 1] = 0;
410 0 : band_count--;
411 :
412 0 : if (visir_line.channelId != 12)
413 : { // not the HRV channel
414 0 : _visir_bytes_per_line =
415 0 : gp_header.packetLength -
416 : (unsigned int)(sizeof(GP_PK_SH1) + sizeof(SUB_VISIRLINE) -
417 : 1);
418 0 : _visir_packet_size = gp_header.packetLength +
419 0 : (unsigned int)sizeof(GP_PK_HEADER) + 1;
420 0 : _interline_spacing += _visir_packet_size;
421 : }
422 : else
423 : {
424 0 : _hrv_bytes_per_line = gp_header.packetLength -
425 : (unsigned int)(sizeof(GP_PK_SH1) +
426 : sizeof(SUB_VISIRLINE) - 1);
427 0 : _hrv_packet_size = gp_header.packetLength +
428 0 : (unsigned int)sizeof(GP_PK_HEADER) + 1;
429 0 : _interline_spacing += _hrv_packet_size;
430 :
431 : // The HRV channel has 3 consecutive lines
432 0 : const int lineNumberInVisirGrid =
433 : visir_line.lineNumberInVisirGrid;
434 0 : const auto packetLength = gp_header.packetLength;
435 0 : for (int extraLines = 0; extraLines < 2; extraLines++)
436 : {
437 0 : if (VSIFReadL(&gp_header, sizeof(GP_PK_HEADER), 1, fin) !=
438 0 : 1 ||
439 0 : VSIFReadL(&sub_header, sizeof(GP_PK_SH1), 1, fin) !=
440 0 : 1 ||
441 0 : VSIFReadL(&visir_line, sizeof(SUB_VISIRLINE), 1, fin) !=
442 : 1)
443 : {
444 0 : _open_success = false;
445 0 : return;
446 : }
447 0 : to_native(visir_line);
448 0 : to_native(gp_header);
449 :
450 0 : CPLDebugOnly(
451 : "MSGN",
452 : "channelId = %d, lineNumber = %d, packetLength = %u",
453 : visir_line.channelId, visir_line.lineNumberInVisirGrid,
454 : gp_header.packetLength);
455 :
456 0 : if (visir_line.channelId != 12 ||
457 0 : visir_line.lineNumberInVisirGrid !=
458 0 : lineNumberInVisirGrid + extraLines + 1 ||
459 0 : gp_header.packetLength != packetLength)
460 : {
461 0 : CPLDebugOnly("MSGN", "Inconsistent records");
462 0 : _open_success = false;
463 0 : return;
464 : }
465 :
466 : // skip over the actual line data
467 0 : CPL_IGNORE_RET_VAL(VSIFSeekL(
468 : fin,
469 0 : gp_header.packetLength -
470 : (sizeof(GP_PK_SH1) + sizeof(SUB_VISIRLINE) - 1),
471 : SEEK_CUR));
472 :
473 0 : _interline_spacing += _hrv_packet_size;
474 : }
475 : }
476 : }
477 0 : } while (band_count > 0);
478 :
479 : TRAILER trailer;
480 :
481 0 : CPL_IGNORE_RET_VAL(VSIFSeekL(fin, _f_trailer_offset, SEEK_SET));
482 :
483 0 : if (VSIFReadL(&gp_header, sizeof(GP_PK_HEADER), 1, fin) != 1 ||
484 0 : VSIFReadL(&sub_header, sizeof(GP_PK_SH1), 1, fin) != 1 ||
485 0 : VSIFReadL(&trailer, sizeof(TRAILER), 1, fin) != 1)
486 : {
487 0 : _open_success = false;
488 0 : fprintf(stderr, "Trailer fail\n"); /*ok*/
489 0 : return;
490 : }
491 :
492 0 : to_native(trailer.imageProductionStats.actualL15CoverageVisir);
493 0 : to_native(trailer.imageProductionStats.actualL15CoverageHrv);
494 :
495 0 : CPLDebugOnly("MSGN", "Trailer Version %d, satellite %d",
496 : trailer.trailerHeaderVersion,
497 : trailer.imageProductionStats.satelliteId);
498 :
499 0 : CPLDebugOnly(
500 : "MSGN",
501 : "\nactualL15CoverageVisir.SouthernLineActual = %d, \n"
502 : "actualL15CoverageVisir.NorthernLineActual = %d, \n"
503 : "actualL15CoverageVisir.EasternColumnActual = %d, \n "
504 : "actualL15CoverageVisir.WesternColumnActual = %d",
505 : trailer.imageProductionStats.actualL15CoverageVisir.southernLineActual,
506 : trailer.imageProductionStats.actualL15CoverageVisir.northernLineActual,
507 : trailer.imageProductionStats.actualL15CoverageVisir.easternColumnActual,
508 : trailer.imageProductionStats.actualL15CoverageVisir
509 : .westernColumnActual);
510 :
511 0 : CPLDebugOnly(
512 : "MSGN",
513 : "\nactualCoverage_hrv.lowerSouthLineActual = %d, \n"
514 : "actualCoverage_hrv.lowerNorthLineActual = %d, \n"
515 : "actualCoverage_hrv.lowerEastColumnActual = %d, \n "
516 : "actualCoverage_hrv.lowerWestColumnActual = %d",
517 : trailer.imageProductionStats.actualL15CoverageHrv.lowerSouthLineActual,
518 : trailer.imageProductionStats.actualL15CoverageHrv.lowerNorthLineActual,
519 : trailer.imageProductionStats.actualL15CoverageHrv.lowerEastColumnActual,
520 : trailer.imageProductionStats.actualL15CoverageHrv
521 : .lowerWestColumnActual);
522 :
523 0 : CPLDebugOnly(
524 : "MSGN",
525 : "\nactualCoverage_hrv.upperSouthLineActual = %d, \n"
526 : "actualCoverage_hrv.upperNorthLineActual = %d, \n"
527 : "actualCoverage_hrv.upperEastColumnActual = %d, \n "
528 : "actualCoverage_hrv.upperWestColumnActual = %d",
529 : trailer.imageProductionStats.actualL15CoverageHrv.upperSouthLineActual,
530 : trailer.imageProductionStats.actualL15CoverageHrv.upperNorthLineActual,
531 : trailer.imageProductionStats.actualL15CoverageHrv.upperEastColumnActual,
532 : trailer.imageProductionStats.actualL15CoverageHrv
533 : .upperWestColumnActual);
534 : }
535 :
536 : #ifndef GDAL_SUPPORT
537 :
538 : int Msg_reader_core::_chan_to_idx(Msg_channel_names channel)
539 : {
540 : unsigned int idx = 0;
541 : while (idx < MSG_NUM_CHANNELS)
542 : {
543 : if ((1 << (idx + 1)) == (int)channel)
544 : {
545 : return idx;
546 : }
547 : idx++;
548 : }
549 : return 0;
550 : }
551 :
552 : void Msg_reader_core::get_pixel_geo_coordinates(unsigned int line,
553 : unsigned int column,
554 : double &longitude,
555 : double &latitude) const
556 : {
557 : Conversions::convert_pixel_to_geo((double)(line + _line_start),
558 : (double)(column + _col_start), longitude,
559 : latitude);
560 : longitude += _img_desc_record.longitudeOfSSP;
561 : }
562 :
563 : void Msg_reader_core::get_pixel_geo_coordinates(double line, double column,
564 : double &longitude,
565 : double &latitude)
566 : {
567 : Conversions::convert_pixel_to_geo(line + _line_start, column + _col_start,
568 : longitude, latitude);
569 : longitude += _img_desc_record.longitudeOfSSP;
570 : }
571 :
572 : double Msg_reader_core::compute_pixel_area_sqkm(double line, double column)
573 : {
574 : return Conversions::compute_pixel_area_sqkm(line + _line_start,
575 : column + _col_start);
576 : }
577 :
578 : #endif // GDAL_SUPPORT
579 :
580 : } // namespace msg_native_format
|