19 #include "ProcessExportPds4.h" 25 #include <QDomDocument> 27 #include <QRegularExpression> 47 ProcessExportPds4::ProcessExportPds4() {
53 m_imageType = StandardImage;
55 qSetGlobalQHashSeed(1031);
57 m_domDoc =
new QDomDocument(
"");
61 QString xmlVersion =
"version=\"1.0\" encoding=\"utf-8\"";
62 QDomProcessingInstruction xmlHeader =
63 m_domDoc->createProcessingInstruction(
"xml", xmlVersion);
64 m_domDoc->appendChild(xmlHeader);
67 m_schemaLocation =
"http://pds.nasa.gov/pds4/pds/v1 http://pds.nasa.gov/pds4/pds/v1/PDS4_PDS_1B00.xsd";
70 xmlModel +=
"href=\"http://pds.nasa.gov/pds4/pds/v1/PDS4_PDS_1B00.sch\" ";
71 xmlModel +=
"schematypens=\"http://purl.oclc.org/dsdl/schematron\"";
72 QDomProcessingInstruction header =
73 m_domDoc->createProcessingInstruction(
"xml-model", xmlModel);
74 m_domDoc->appendChild(header);
83 ProcessExportPds4::~ProcessExportPds4() {
94 QDomDocument &ProcessExportPds4::StandardPds4Label() {
96 translateUnits(*m_domDoc);
106 void ProcessExportPds4::setImageType(ImageType imageType) {
107 m_imageType = imageType;
120 void ProcessExportPds4::CreateImageLabel() {
121 if (InputCubes.size() == 0) {
122 QString msg(
"Must set an input cube before creating a PDS4 label.");
125 if (m_domDoc->documentElement().isNull()) {
126 QDomElement root = m_domDoc->createElement(
"Product_Observational");
127 root.setAttribute(
"xmlns",
"http://pds.nasa.gov/pds4/pds/v1");
128 root.setAttribute(
"xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
129 root.setAttribute(
"xsi:schemaLocation",
130 "http://pds.nasa.gov/pds4/pds/v1 http://pds.nasa.gov/pds4/pds/v1");
131 m_domDoc->appendChild(root);
137 identificationArea();
140 QString msg =
"Unable to translate and export identification information.";
146 standardInstrument();
149 QString msg =
"Unable to translate and export instrument information.";
160 QString msg =
"Unable to translate and export display settings.";
172 QString msg =
"Unable to translate and export spectral information.";
181 StandardAllMapping();
184 QString msg =
"Unable to translate and export mapping group.";
190 fileAreaObservational();
193 QString msg =
"Unable to translate and export standard image information.";
203 void ProcessExportPds4::standardInstrument() {
204 Pvl *inputLabel = InputCubes[0]->label();
207 if (inputLabel->
findObject(
"IsisCube").hasGroup(
"Instrument")) {
210 translationFileName =
"$base/translations/pds4ExportInstrument.trn";
212 instXlator.
Auto(*m_domDoc);
215 QDomElement obsAreaNode = m_domDoc->documentElement().firstChildElement(
"Observation_Area");
217 if ( !obsAreaNode.isNull() ) {
220 QDomElement timeNode = obsAreaNode.firstChildElement(
"Time_Coordinates");
221 if (!timeNode.isNull()) {
222 QDomElement startTime = timeNode.firstChildElement(
"start_date_time");
223 if (startTime.text() ==
"") {
224 startTime.setAttribute(
"xsi:nil",
"true");
227 QString timeValue = startTime.text();
228 PvlToXmlTranslationManager::resetElementValue(startTime, timeValue +
"Z");
230 QDomElement stopTime = timeNode.firstChildElement(
"stop_date_time");
231 if (stopTime.text() ==
"") {
232 stopTime.setAttribute(
"xsi:nil",
"true");
235 QString timeValue = stopTime.text();
236 PvlToXmlTranslationManager::resetElementValue(stopTime, timeValue +
"Z");
240 QDomElement obsSysNode = obsAreaNode.firstChildElement(
"Observing_System");
241 if ( !obsSysNode.isNull() ) {
242 QString instrumentName;
243 QString spacecraftName;
244 QDomElement obsSysCompNode = obsSysNode.firstChildElement(
"Observing_System_Component");
245 while ( !obsSysCompNode.isNull()) {
246 QDomElement compTypeNode = obsSysCompNode.firstChildElement(
"type");
247 if ( compTypeNode.text().compare(
"Spacecraft") == 0 ) {
248 QString componentName = obsSysCompNode.firstChildElement(
"name").text();
249 if (QString::compare(componentName,
"TBD", Qt::CaseInsensitive) != 0) {
250 spacecraftName = componentName;
253 else if ( compTypeNode.text().compare(
"Instrument") == 0 ) {
254 QString componentName = obsSysCompNode.firstChildElement(
"name").text();
255 if (QString::compare(componentName,
"TBD", Qt::CaseInsensitive) != 0) {
256 instrumentName = componentName;
259 obsSysCompNode = obsSysCompNode.nextSiblingElement(
"Observing_System_Component");
261 QDomElement combinedNode = m_domDoc->createElement(
"name");
262 QString combinedValue =
"TBD";
263 if ( !instrumentName.isEmpty() && !spacecraftName.isEmpty() ) {
264 combinedValue = spacecraftName +
" " + instrumentName;
266 combinedNode.appendChild( m_domDoc->createTextNode(combinedValue) );
267 obsSysNode.insertBefore( combinedNode, obsSysNode.firstChild() );
272 translationFileName =
"$base/translations/pds4ExportTargetFromInstrument.trn";
274 targXlator.
Auto(*m_domDoc);
277 QDomElement targetIdNode = obsAreaNode.firstChildElement(
"Target_Identification");
278 obsAreaNode.insertAfter(targetIdNode, obsAreaNode.firstChildElement(
"Observing_System"));
280 else if (inputLabel->
findObject(
"IsisCube").hasGroup(
"Mapping")) {
282 translationFileName =
"$base/translations/pds4ExportTargetFromMapping.trn";
284 targXlator.
Auto(*m_domDoc);
296 void ProcessExportPds4::reorder() {
297 QDomElement obsAreaNode = m_domDoc->documentElement().firstChildElement(
"Observation_Area");
298 if ( !obsAreaNode.isNull() ) {
301 QDomElement timeNode = obsAreaNode.firstChildElement(
"Time_Coordinates");
302 if (!timeNode.isNull()) {
303 QDomElement startTime = timeNode.firstChildElement(
"start_date_time");
304 if (startTime.text() ==
"") {
305 startTime.setAttribute(
"xsi:nil",
"true");
308 QString timeValue = startTime.text();
309 if (!timeValue.contains(
"Z")) {
310 PvlToXmlTranslationManager::resetElementValue(startTime, timeValue +
"Z");
314 QDomElement stopTime = timeNode.firstChildElement(
"stop_date_time");
315 if (stopTime.text() ==
"") {
316 stopTime.setAttribute(
"xsi:nil",
"true");
319 QString timeValue = stopTime.text();
320 if (!timeValue.contains(
"Z")) {
321 PvlToXmlTranslationManager::resetElementValue(stopTime, timeValue +
"Z");
325 xmlPath <<
"Product_Observational" 326 <<
"Observation_Area" 329 <<
"geom:Geometry_Orbiter" 330 <<
"geom:geometry_reference_time_utc";
332 QDomElement baseElement = m_domDoc->documentElement();
333 QDomElement geomRefTime = getElement(xmlPath, baseElement);
334 if (geomRefTime.text() ==
"") {
335 geomRefTime.setAttribute(
"xsi:nil",
"true");
338 QString timeValue = geomRefTime.text();
339 PvlToXmlTranslationManager::resetElementValue(geomRefTime, timeValue +
"Z");
342 xmlPath <<
"Product_Observational" 343 <<
"Observation_Area" 346 <<
"geom:Image_Display_Geometry" 347 <<
"geom:Object_Orientation_North_East" 348 <<
"geom:east_azimuth";
349 QDomElement eastAzimuth = getElement(xmlPath, baseElement);
350 if (eastAzimuth.text() !=
"") {
351 PvlToXmlTranslationManager::resetElementValue(eastAzimuth, eastAzimuth.text(),
"deg");
355 QDomElement investigationAreaNode = obsAreaNode.firstChildElement(
"Investigation_Area");
356 obsAreaNode.insertAfter(investigationAreaNode, obsAreaNode.firstChildElement(
"Time_Coordinates"));
358 QDomElement obsSystemNode = obsAreaNode.firstChildElement(
"Observing_System");
359 obsAreaNode.insertAfter(obsSystemNode, obsAreaNode.firstChildElement(
"Investigation_Area"));
361 QDomElement targetIdNode = obsAreaNode.firstChildElement(
"Target_Identification");
362 obsAreaNode.insertAfter(targetIdNode, obsAreaNode.firstChildElement(
"Observing_System"));
364 QDomElement missionAreaNode = obsAreaNode.firstChildElement(
"Mission_Area");
365 obsAreaNode.insertAfter(missionAreaNode, obsAreaNode.firstChildElement(
"Target_Identification"));
367 QDomElement disciplineAreaNode = obsAreaNode.firstChildElement(
"Discipline_Area");
368 obsAreaNode.insertAfter(disciplineAreaNode, obsAreaNode.firstChildElement(
"Mission_Area"));
371 QDomElement identificationAreaNode = m_domDoc->documentElement().firstChildElement(
"Identification_Area");
372 if ( !identificationAreaNode.isNull() ) {
373 QDomElement aliasListNode = identificationAreaNode.firstChildElement(
"Alias_List");
374 identificationAreaNode.insertAfter(aliasListNode, identificationAreaNode.firstChildElement(
"product_class"));
377 QDomElement fileAreaObservationalNode = m_domDoc->documentElement().firstChildElement(
"File_Area_Observational");
378 QDomElement array2DImageNode = fileAreaObservationalNode.firstChildElement(
"Array_2D_Image");
379 if ( !array2DImageNode.isNull() ) {
380 QDomElement descriptionNode = array2DImageNode.firstChildElement(
"description");
381 array2DImageNode.insertAfter(descriptionNode, array2DImageNode.firstChildElement(
"axis_index_order"));
413 void ProcessExportPds4::setLogicalId(QString lid) {
414 m_lid = lid.toLower();
431 void ProcessExportPds4::setVersionId(QString versionId) {
432 m_versionId = versionId;
446 void ProcessExportPds4::setTitle(QString title) {
459 void ProcessExportPds4::setSchemaLocation(QString schema) {
460 m_schemaLocation = schema;
468 void ProcessExportPds4::identificationArea() {
469 Pvl *inputLabel = InputCubes[0]->label();
471 translationFileName =
"$base/translations/pds4ExportIdentificationArea.trn";
473 xlator.
Auto(*m_domDoc);
475 if (m_lid.isEmpty()) {
476 m_lid =
"urn:nasa:pds:TBD:TBD:TBD";
479 QDomElement identificationElement;
481 identificationPath.append(
"Product_Observational");
482 identificationPath.append(
"Identification_Area");
484 identificationElement = getElement(identificationPath);
485 if( identificationElement.isNull() ) {
490 QString msg =
"Could not find Identification_Area element " 491 "to add modification history under.";
495 QDomElement lidElement = identificationElement.firstChildElement(
"logical_identifier");
496 PvlToXmlTranslationManager::resetElementValue(lidElement, m_lid);
498 if (m_versionId !=
"") {
499 QDomElement versionElement = identificationElement.firstChildElement(
"version_id");
500 PvlToXmlTranslationManager::resetElementValue(versionElement, m_versionId);
504 QDomElement titleElement = identificationElement.firstChildElement(
"title");
505 PvlToXmlTranslationManager::resetElementValue(titleElement, m_title);
511 QRegularExpression versionRegex(
" \\| \\d{4}\\-\\d{2}\\-\\d{2}");
512 QString historyDescription =
"Created PDS4 output product from ISIS cube with the " 514 +
" application from ISIS version " 515 + Application::Version().remove(versionRegex) +
".";
517 QRegularExpression dateRegex(
"T\\d{2}:\\d{2}:\\d{2}");
518 QString historyDate = Application::DateTime().remove(dateRegex);
519 addHistory(historyDescription, historyDate);
527 void ProcessExportPds4::displaySettings() {
529 addSchema(
"PDS4_DISP_1B00.sch",
530 "PDS4_DISP_1B00.xsd",
532 "http://pds.nasa.gov/pds4/disp/v1");
534 Pvl *inputLabel = InputCubes[0]->label();
536 translationFileName =
"$base/translations/pds4ExportDisplaySettings.trn";
538 xlator.
Auto(*m_domDoc);
546 void ProcessExportPds4::standardBandBin() {
547 Pvl *inputLabel = InputCubes[0]->label();
548 if ( !inputLabel->
findObject(
"IsisCube").hasGroup(
"BandBin") )
return;
550 addSchema(
"PDS4_IMG_1A10_1510.sch",
551 "PDS4_IMG_1A10_1510.xsd",
553 "http://pds.nasa.gov/pds4/img/v1");
556 if (m_imageType == StandardImage) {
557 translateBandBinImage(*inputLabel);
561 addSchema(
"PDS4_SP_1100.sch",
564 "http://pds.nasa.gov/pds4/sp/v1");
565 if (m_imageType == UniformlySampledSpectrum) {
566 translateBandBinSpectrumUniform(*inputLabel);
568 else if (m_imageType == BinSetSpectrum) {
569 translateBandBinSpectrumBinSet(*inputLabel);
578 void ProcessExportPds4::translateBandBinImage(
Pvl &inputLabel) {
579 QString translationFile =
"$base/translations/";
580 translationFile +=
"pds4ExportBandBinImage.trn";
581 FileName translationFileName(translationFile);
583 xlator.
Auto(*m_domDoc);
590 void ProcessExportPds4::translateBandBinSpectrumUniform(
Pvl &inputLabel) {
591 QString translationFile =
"$base/translations/";
592 translationFile +=
"pds4ExportBandBinSpectrumUniform.trn";
593 FileName translationFileName(translationFile);
595 xlator.
Auto(*m_domDoc);
600 xmlPath <<
"Product_Observational" 601 <<
"Observation_Area" 603 <<
"sp:Spectral_Characteristics";
604 QDomElement baseElement = m_domDoc->documentElement();
605 QDomElement spectralCharElement = getElement(xmlPath, baseElement);
613 center = bandBinGroup[
"Center"];
615 else if (bandBinGroup.
hasKeyword(
"FilterCenter")) {
616 center = bandBinGroup[
"FilterCenter"];
619 QString msg =
"Unable to translate BandBin info for BinSetSpectrum. " 620 "Translation for PDS4 required value [center_value] not found.";
625 width = bandBinGroup[
"Width"];
627 else if (bandBinGroup.
hasKeyword(
"FilterWidth")) {
628 width = bandBinGroup[
"FilterWidth"];
631 QString msg =
"Unable to translate BandBin info for BinSetSpectrum. " 632 "Translation for PDS4 required value [bin_width] not found.";
636 QString units = center.
unit();
638 if (!width.
unit().isEmpty() ) {
639 if (units.isEmpty()) {
640 units = width.
unit();
642 if (units.compare(width.
unit(), Qt::CaseInsensitive) != 0) {
643 QString msg =
"Unable to translate BandBin info for BinSetSpectrum. " 644 "Unknown or unmatching units for [center_value] and [bin_width].";
650 if (bandBinGroup.
hasKeyword(
"OriginalBand")) {
651 originalBand = bandBinGroup[
"OriginalBand"];
655 name = bandBinGroup[
"Name"];
657 else if (bandBinGroup.
hasKeyword(
"FilterName")) {
658 name = bandBinGroup[
"FilterName"];
660 else if (bandBinGroup.
hasKeyword(
"FilterId")) {
661 name = bandBinGroup[
"FilterId"];
665 number = bandBinGroup[
"Number"];
667 else if (bandBinGroup.
hasKeyword(
"FilterNumber")) {
668 number = bandBinGroup[
"FilterNumber"];
671 QDomElement axisBinSetElement = spectralCharElement.firstChildElement(
"sp:Axis_Bin_Set");
672 if (axisBinSetElement.isNull()) {
673 axisBinSetElement = m_domDoc->createElement(
"sp:Axis_Bin_Set");
674 spectralCharElement.appendChild(axisBinSetElement);
676 int bands = (int)inputLabel.
findObject(
"IsisCube")
678 .findGroup(
"Dimensions")
679 .findKeyword(
"Bands");
681 for (
int i = 0; i < bands; i++) {
683 QDomElement bin = m_domDoc->createElement(
"sp:Bin");
684 axisBinSetElement.appendChild(bin);
686 QDomElement binSequenceNumber = m_domDoc->createElement(
"sp:bin_sequence_number");
687 PvlToXmlTranslationManager::setElementValue(binSequenceNumber,
toString(i+1));
688 bin.appendChild(binSequenceNumber);
691 QDomElement centerValue = m_domDoc->createElement(
"sp:center_value");
692 PvlToXmlTranslationManager::setElementValue(centerValue, center[i], units);
693 bin.appendChild(centerValue);
695 QDomElement binWidth = m_domDoc->createElement(
"sp:bin_width");
696 if (width.
size() == bands) {
697 PvlToXmlTranslationManager::setElementValue(binWidth, width[i] , units);
700 PvlToXmlTranslationManager::setElementValue(binWidth, width[0] , units);
702 bin.appendChild(binWidth);
704 QDomElement originalBinNumber = m_domDoc->createElement(
"sp:original_bin_number");
705 if (originalBand.
size() > 0) {
706 PvlToXmlTranslationManager::setElementValue(originalBinNumber, originalBand[i]);
707 bin.appendChild(originalBinNumber);
710 if (name.
size() > 0 || number.
size() > 0) {
711 QDomElement filter = m_domDoc->createElement(
"sp:Filter");
712 bin.appendChild(filter);
713 if (name.
size() > 0) {
714 QDomElement filterName = m_domDoc->createElement(
"sp:filter_name");
715 PvlToXmlTranslationManager::setElementValue(filterName, name[i]);
716 filter.appendChild(filterName);
718 if (number.
size() > 0) {
719 QDomElement filterNumber= m_domDoc->createElement(
"sp:filter_number");
720 PvlToXmlTranslationManager::setElementValue(filterNumber, number[i]);
721 filter.appendChild(filterNumber);
732 void ProcessExportPds4::translateBandBinSpectrumBinSet(
Pvl &inputLabel) {
733 QString translationFile =
"$base/translations/";
734 translationFile +=
"pds4ExportBandBinSpectrumBinSet.trn";
735 FileName translationFileName(translationFile);
737 xlator.
Auto(*m_domDoc);
742 xmlPath <<
"Product_Observational" 743 <<
"Observation_Area" 745 <<
"sp:Spectral_Characteristics";
746 QDomElement baseElement = m_domDoc->documentElement();
747 QDomElement spectralCharElement = getElement(xmlPath, baseElement);
768 if (bandBinGroup.
hasKeyword(
"FilterCenter")) {
769 center = bandBinGroup[
"FilterCenter"];
772 center = bandBinGroup[
"Center"];
775 QString msg =
"Unable to translate BandBin info for UniformlySpacedSpectrum. " 776 "Translation for PDS4 required value [last_center_value] not found.";
779 QString lastCenter = center[center.
size() - 1];
781 QDomElement axisBinSetElement = spectralCharElement.firstChildElement(
"sp:Axis_Uniformly_Sampled");
782 if (axisBinSetElement.isNull()) {
783 axisBinSetElement = m_domDoc->createElement(
"sp:Axis_Uniformly_Sampled");
784 spectralCharElement.appendChild(axisBinSetElement);
787 QDomElement lastCenterElement = m_domDoc->createElement(
"sp:last_center_value");
788 PvlToXmlTranslationManager::setElementValue(lastCenterElement, lastCenter);
789 spectralCharElement.appendChild(lastCenterElement);
799 void ProcessExportPds4::setPixelDescription(QString description) {
800 m_pixelDescription = description;
808 void ProcessExportPds4::fileAreaObservational() {
809 Pvl *inputLabel = InputCubes[0]->label();
810 QString imageObject =
"";
812 QString translationFile =
"$base/translations/pds4Export";
813 if (m_imageType == StandardImage) {
814 int bands = (int)inputLabel->
findObject(
"IsisCube")
816 .findGroup(
"Dimensions")
817 .findKeyword(
"Bands");
819 imageObject =
"Array_3D_Image";
822 imageObject =
"Array_2D_Image";
824 translationFile += QString(imageObject).remove(
'_');
827 imageObject =
"Array_3D_Spectrum";
828 translationFile += QString(imageObject).remove(
'_');
829 if (m_imageType == UniformlySampledSpectrum) {
830 translationFile +=
"Uniform";
832 else if (m_imageType == BinSetSpectrum) {
833 translationFile +=
"BinSet";
836 translationFile +=
".trn";
837 FileName translationFileName(translationFile);
840 xlator.
Auto(*m_domDoc);
842 QDomElement rootElement = m_domDoc->documentElement();
843 QDomElement fileAreaObservationalElement =
844 rootElement.firstChildElement(
"File_Area_Observational");
848 double multiplier = 1.0;
849 double outputMin, outputMax;
851 double inputMin = (p_inputMinimum.size()) ? p_inputMinimum[0] : 0.0;
852 double inputMax = (p_inputMaximum.size()) ? p_inputMaximum[0] : 0.0;
854 for(
unsigned int i = 0; i < p_inputMinimum.size(); i ++) {
855 inputMin = std::min(inputMin, p_inputMinimum[i]);
856 inputMax = std::max(inputMax, p_inputMaximum[i]);
859 outputMin = p_outputMinimum;
860 outputMax = p_outputMaximum;
862 if(p_inputMinimum.size() && ( p_pixelType == Isis::UnsignedByte ||
863 p_pixelType == Isis::SignedWord ||
864 p_pixelType == Isis::UnsignedWord ) ) {
865 multiplier = (inputMax - inputMin) / (outputMax - outputMin);
866 base = inputMin - multiplier * outputMin;
869 if (!fileAreaObservationalElement.isNull()) {
870 QDomElement arrayImageElement =
871 fileAreaObservationalElement.firstChildElement(imageObject);
872 if (!arrayImageElement.isNull()) {
877 QDomElement axisArrayElement = arrayImageElement.firstChildElement(
"Axis_Array");
878 while( !axisArrayElement.isNull() ) {
879 QDomElement axisNameElement = axisArrayElement.firstChildElement(
"axis_name");
880 axisArrayElement.insertBefore(axisNameElement,
881 axisArrayElement.firstChildElement(
"elements"));
882 axisArrayElement = axisArrayElement.nextSiblingElement(
"Axis_Array");
885 QDomElement elementArrayElement = m_domDoc->createElement(
"Element_Array");
886 arrayImageElement.insertBefore(elementArrayElement,
887 arrayImageElement.firstChildElement(
"Axis_Array"));
889 QDomElement dataTypeElement = m_domDoc->createElement(
"data_type");
890 PvlToXmlTranslationManager::setElementValue(dataTypeElement,
891 PDS4PixelType(p_pixelType, p_endianType));
892 elementArrayElement.appendChild(dataTypeElement);
894 QDomElement scalingFactorElement = m_domDoc->createElement(
"scaling_factor");
895 PvlToXmlTranslationManager::setElementValue(scalingFactorElement,
897 elementArrayElement.appendChild(scalingFactorElement);
899 QDomElement offsetElement = m_domDoc->createElement(
"value_offset");
900 PvlToXmlTranslationManager::setElementValue(offsetElement,
902 elementArrayElement.appendChild(offsetElement);
906 QDomElement specialConstantElement = m_domDoc->createElement(
"Special_Constants");
907 arrayImageElement.insertAfter(specialConstantElement,
908 arrayImageElement.lastChildElement(
"Axis_Array"));
910 switch (p_pixelType) {
912 { QDomElement nullElement = m_domDoc->createElement(
"missing_constant");
913 PvlToXmlTranslationManager::setElementValue(nullElement, QString::number(NULL4,
'g', 18));
914 specialConstantElement.appendChild(nullElement);
916 QDomElement highInstrumentSatElement = m_domDoc->createElement(
"high_instrument_saturation");
917 PvlToXmlTranslationManager::setElementValue(highInstrumentSatElement, QString::number(HIGH_INSTR_SAT4,
'g', 18));
918 specialConstantElement.appendChild(highInstrumentSatElement);
920 QDomElement highRepresentationSatElement = m_domDoc->createElement(
"high_representation_saturation");
921 PvlToXmlTranslationManager::setElementValue(highRepresentationSatElement, QString::number(HIGH_REPR_SAT4,
'g', 18));
922 specialConstantElement.appendChild(highRepresentationSatElement);
924 QDomElement lowInstrumentSatElement = m_domDoc->createElement(
"low_instrument_saturation");
925 PvlToXmlTranslationManager::setElementValue(lowInstrumentSatElement, QString::number(LOW_INSTR_SAT4,
'g', 18));
926 specialConstantElement.appendChild(lowInstrumentSatElement);
928 QDomElement lowRepresentationSatElement = m_domDoc->createElement(
"low_representation_saturation");
929 PvlToXmlTranslationManager::setElementValue(lowRepresentationSatElement, QString::number(LOW_REPR_SAT4,
'g', 18));
930 specialConstantElement.appendChild(lowRepresentationSatElement);
934 { QDomElement nullElement = m_domDoc->createElement(
"missing_constant");
935 PvlToXmlTranslationManager::setElementValue(nullElement, QString::number(NULL1,
'g', 18));
936 specialConstantElement.appendChild(nullElement);
938 QDomElement highInstrumentSatElement = m_domDoc->createElement(
"high_instrument_saturation");
939 PvlToXmlTranslationManager::setElementValue(highInstrumentSatElement, QString::number(HIGH_INSTR_SAT1,
'g', 18));
940 specialConstantElement.appendChild(highInstrumentSatElement);
942 QDomElement highRepresentationSatElement = m_domDoc->createElement(
"high_representation_saturation");
943 PvlToXmlTranslationManager::setElementValue(highRepresentationSatElement, QString::number(HIGH_REPR_SAT1,
'g', 18));
944 specialConstantElement.appendChild(highRepresentationSatElement);
946 QDomElement lowInstrumentSatElement = m_domDoc->createElement(
"low_instrument_saturation");
947 PvlToXmlTranslationManager::setElementValue(lowInstrumentSatElement, QString::number(LOW_INSTR_SAT1,
'g', 18));
948 specialConstantElement.appendChild(lowInstrumentSatElement);
950 QDomElement lowRepresentationSatElement = m_domDoc->createElement(
"low_representation_saturation");
951 PvlToXmlTranslationManager::setElementValue(lowRepresentationSatElement, QString::number(LOW_REPR_SAT1,
'g', 18));
952 specialConstantElement.appendChild(lowRepresentationSatElement);
956 { QDomElement nullElement = m_domDoc->createElement(
"missing_constant");
957 PvlToXmlTranslationManager::setElementValue(nullElement, QString::number(NULL2,
'g', 18));
958 specialConstantElement.appendChild(nullElement);
960 QDomElement highInstrumentSatElement = m_domDoc->createElement(
"high_instrument_saturation");
961 PvlToXmlTranslationManager::setElementValue(highInstrumentSatElement, QString::number(HIGH_INSTR_SAT2,
'g', 18));
962 specialConstantElement.appendChild(highInstrumentSatElement);
964 QDomElement highRepresentationSatElement = m_domDoc->createElement(
"high_representation_saturation");
965 PvlToXmlTranslationManager::setElementValue(highRepresentationSatElement, QString::number(HIGH_REPR_SAT2,
'g', 18));
966 specialConstantElement.appendChild(highRepresentationSatElement);
968 QDomElement lowInstrumentSatElement = m_domDoc->createElement(
"low_instrument_saturation");
969 PvlToXmlTranslationManager::setElementValue(lowInstrumentSatElement, QString::number(LOW_INSTR_SAT2,
'g', 18));
970 specialConstantElement.appendChild(lowInstrumentSatElement);
972 QDomElement lowRepresentationSatElement = m_domDoc->createElement(
"low_representation_saturation");
973 PvlToXmlTranslationManager::setElementValue(lowRepresentationSatElement, QString::number(LOW_REPR_SAT2,
'g', 18));
974 specialConstantElement.appendChild(lowRepresentationSatElement);
978 { QDomElement nullElement = m_domDoc->createElement(
"missing_constant");
979 PvlToXmlTranslationManager::setElementValue(nullElement, QString::number(NULLU2,
'g', 18));
980 specialConstantElement.appendChild(nullElement);
982 QDomElement highInstrumentSatElement = m_domDoc->createElement(
"high_instrument_saturation");
983 PvlToXmlTranslationManager::setElementValue(highInstrumentSatElement, QString::number(HIGH_INSTR_SATU2,
'g', 18));
984 specialConstantElement.appendChild(highInstrumentSatElement);
986 QDomElement highRepresentationSatElement = m_domDoc->createElement(
"high_representation_saturation");
987 PvlToXmlTranslationManager::setElementValue(highRepresentationSatElement, QString::number(HIGH_REPR_SATU2,
'g', 18));
988 specialConstantElement.appendChild(highRepresentationSatElement);
990 QDomElement lowInstrumentSatElement = m_domDoc->createElement(
"low_instrument_saturation");
991 PvlToXmlTranslationManager::setElementValue(lowInstrumentSatElement, QString::number(LOW_INSTR_SATU2,
'g', 18));
992 specialConstantElement.appendChild(lowInstrumentSatElement);
994 QDomElement lowRepresentationSatElement = m_domDoc->createElement(
"low_representation_saturation");
995 PvlToXmlTranslationManager::setElementValue(lowRepresentationSatElement, QString::number(LOW_REPR_SATU2,
'g', 18));
996 specialConstantElement.appendChild(lowRepresentationSatElement);
1008 if (!m_pixelDescription.isEmpty()) {
1009 QDomElement descriptionElement = m_domDoc->createElement(
"description");
1010 PvlToXmlTranslationManager::setElementValue(descriptionElement,
1011 m_pixelDescription);
1012 arrayImageElement.insertAfter(descriptionElement, arrayImageElement.lastChildElement());
1026 void ProcessExportPds4::addSchema(QString xsd, QString xmlns, QString xmlnsURI) {
1028 QDomElement root = m_domDoc->documentElement();
1029 root.setAttribute(xmlns, xmlnsURI);
1032 m_schemaLocation +=
" ";
1033 m_schemaLocation += xmlnsURI;
1034 m_schemaLocation +=
" ";
1035 m_schemaLocation += xmlnsURI;
1036 m_schemaLocation +=
"/";
1037 m_schemaLocation += xsd;
1038 root.setAttribute(
"xsi:schemaLocation", m_schemaLocation);
1050 void ProcessExportPds4::addSchema(QString sch, QString xsd, QString xmlns, QString xmlnsURI) {
1053 xmlModel +=
"href=\"";
1054 xmlModel += xmlnsURI;
1057 xmlModel +=
"\" schematypens=\"http://purl.oclc.org/dsdl/schematron\"";
1058 QDomProcessingInstruction header =
1059 m_domDoc->createProcessingInstruction(
"xml-model", xmlModel);
1060 m_domDoc->insertAfter(header, m_domDoc->firstChild());
1063 addSchema(xsd, xmlns, xmlnsURI);
1072 void ProcessExportPds4::OutputLabel(std::ofstream &os) {
1073 os << m_domDoc->toString() << endl;
1084 void ProcessExportPds4::StartProcess(std::ofstream &fout) {
1085 ProcessExport::StartProcess(fout);
1095 QDomDocument &ProcessExportPds4::GetLabel() {
1096 if (m_domDoc->documentElement().isNull()) {
1097 QDomElement root = m_domDoc->createElement(
"Product_Observational");
1098 root.setAttribute(
"xmlns",
"http://pds.nasa.gov/pds4/pds/v1");
1099 root.setAttribute(
"xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
1100 root.setAttribute(
"xsi:schemaLocation",
1101 "http://pds.nasa.gov/pds4/pds/v1 http://pds.nasa.gov/pds4/pds/v1");
1102 m_domDoc->appendChild(root);
1116 void ProcessExportPds4::WritePds4(QString outFile) {
1122 QString name(outputFile.
baseName());
1123 QString labelName = path +
"/" + name +
".xml";
1126 QString imageName = outputFile.
expanded();
1130 if (QString::compare(outputFile.
extension(),
"xml", Qt::CaseInsensitive) == 0) {
1131 imageName = path +
"/" + name +
".img";
1134 QDomElement rootElement = m_domDoc->documentElement();
1135 QDomElement fileAreaObservationalElement =
1136 rootElement.firstChildElement(
"File_Area_Observational");
1138 QDomElement fileElement = m_domDoc->createElement(
"File");
1139 fileAreaObservationalElement.insertBefore(fileElement,
1140 fileAreaObservationalElement.firstChildElement());
1142 QDomElement fileNameElement = m_domDoc->createElement(
"file_name");
1143 PvlToXmlTranslationManager::setElementValue(fileNameElement, outputFile.
name());
1144 fileElement.appendChild(fileNameElement);
1150 ofstream outputLabel(labelName.toLatin1().data());
1151 OutputLabel(outputLabel);
1152 outputLabel.close();
1154 ofstream outputImageFile(imageName.toLatin1().data());
1155 StartProcess(outputImageFile);
1156 outputImageFile.close();
1170 void ProcessExportPds4::StandardAllMapping() {
1173 Pvl *inputLabel = InputCubes[0]->label();
1175 !(inputLabel->
findObject(
"IsisCube").hasGroup(
"Mapping")))
return;
1178 addSchema(
"PDS4_CART_1900.sch",
1179 "PDS4_CART_1900.xsd",
1181 "http://pds.nasa.gov/pds4/cart/v1");
1184 Projection *proj = ProjectionFactory::Create(*inputLabel);
1185 QString projName = proj->
Name();
1188 "$base/translations/pds4Export" + projName +
".trn");
1189 xlatorSpecProj.
Auto(*m_domDoc);
1192 QString msg =
"Unable to export projection [" + projName +
"] to PDS4 product. " +
1193 "This projection is not supported in ISIS3.";
1199 xmlPath <<
"Product_Observational" 1200 <<
"Observation_Area" 1201 <<
"Discipline_Area" 1202 <<
"cart:Cartography" 1203 <<
"cart:Map_Projection" 1204 <<
"cart:Spatial_Reference_Information" 1205 <<
"cart:Horizontal_Coordinate_System_Definition" 1206 <<
"cart:Geodetic_Model";
1208 QDomElement baseElement = m_domDoc->documentElement();
1209 QDomElement geodeticModelElement = getElement(xmlPath, baseElement);
1210 QDomElement semiMajorRadElement = geodeticModelElement.firstChildElement(
"cart:semi_major_radius");
1211 if (!semiMajorRadElement.isNull()) {
1213 QString units = semiMajorRadElement.attribute(
"unit");
1214 if( units.compare(
"km", Qt::CaseInsensitive) != 0 && units.compare(
"kilometers", Qt::CaseInsensitive) != 0) {
1217 double dValue =
toDouble(semiMajorRadElement.text());
1219 PvlToXmlTranslationManager::resetElementValue(semiMajorRadElement,
toString(dValue),
"km");
1223 QDomElement semiMinorRadElement = geodeticModelElement.firstChildElement(
"cart:semi_minor_radius");
1224 if (!semiMinorRadElement.isNull()) {
1226 QString units = semiMinorRadElement.attribute(
"unit");
1227 if( units.compare(
"km", Qt::CaseInsensitive) != 0 && units.compare(
"kilometers", Qt::CaseInsensitive) != 0) {
1229 double dValue =
toDouble(semiMinorRadElement.text());
1231 PvlToXmlTranslationManager::resetElementValue(semiMinorRadElement,
toString(dValue),
"km");
1235 QDomElement polarRadElement = geodeticModelElement.firstChildElement(
"cart:polar_radius");
1236 if (!polarRadElement.isNull()) {
1237 QString units = polarRadElement.attribute(
"unit");
1238 if( units.compare(
"km", Qt::CaseInsensitive) != 0 && units.compare(
"kilometers", Qt::CaseInsensitive) != 0) {
1240 double dValue =
toDouble(polarRadElement.text());
1242 PvlToXmlTranslationManager::resetElementValue(polarRadElement,
toString(dValue),
"km");
1247 QString lonDir = isisLonDir[0];
1248 lonDir = lonDir.toUpper();
1251 double maxLon, minLon, maxLat, minLat;
1252 InputCubes[0]->latLonRange(minLat, maxLat, minLon, maxLon);
1255 xmlPath <<
"Product_Observational" 1256 <<
"Observation_Area" 1257 <<
"Discipline_Area" 1258 <<
"cart:Cartography" 1259 <<
"cart:Spatial_Domain" 1260 <<
"cart:Bounding_Coordinates";
1261 QDomElement boundingCoordElement = getElement(xmlPath, baseElement);
1262 QDomElement eastElement = boundingCoordElement.firstChildElement(
"cart:east_bounding_coordinate");
1263 QDomElement westElement = boundingCoordElement.firstChildElement(
"cart:west_bounding_coordinate");
1264 QDomElement northElement = boundingCoordElement.firstChildElement(
"cart:north_bounding_coordinate");
1265 QDomElement southElement = boundingCoordElement.firstChildElement(
"cart:south_bounding_coordinate");
1269 if(QString::compare(lonDir,
"PositiveEast", Qt::CaseInsensitive) == 0) {
1271 PvlToXmlTranslationManager::resetElementValue(eastElement,
toString(maxLon),
"deg");
1272 PvlToXmlTranslationManager::resetElementValue(westElement,
toString(minLon),
"deg");
1275 PvlToXmlTranslationManager::resetElementValue(eastElement,
toString(minLon),
"deg");
1276 PvlToXmlTranslationManager::resetElementValue(westElement,
toString(maxLon),
"deg");
1279 PvlToXmlTranslationManager::resetElementValue(northElement,
toString(maxLat),
"deg");
1280 PvlToXmlTranslationManager::resetElementValue(southElement,
toString(minLat),
"deg");
1284 xmlPath <<
"Product_Observational" 1285 <<
"Observation_Area" 1286 <<
"Discipline_Area" 1287 <<
"cart:Cartography" 1288 <<
"cart:Spatial_Reference_Information" 1289 <<
"cart:Horizontal_Coordinate_System_Definition" 1291 <<
"cart:Map_Projection";
1294 QDomElement projectionElement = getElement(xmlPath, baseElement);
1295 QDomElement tempElement = projectionElement.firstChildElement();
1296 QDomElement nameElement = tempElement.nextSiblingElement();
1298 QDomElement longitudeElement = nameElement.firstChildElement(
"cart:longitude_of_central_meridian");
1299 QDomElement originElement = nameElement.firstChildElement(
"cart:latitude_of_projection_origin");
1301 double longitudeElementValue = longitudeElement.text().toDouble();
1302 double originElementValue = originElement.text().toDouble();
1305 if (!longitudeElement.text().contains(
'.')) {
1306 QString toset1 = QString::number(longitudeElementValue,
'f', 1);
1307 PvlToXmlTranslationManager::resetElementValue(longitudeElement, toset1,
"deg");
1310 if (!originElement.text().contains(
'.')) {
1311 QString toset2 = QString::number(originElementValue,
'f', 1);
1312 PvlToXmlTranslationManager::resetElementValue(originElement, toset2,
"deg");
1333 QDomElement ProcessExportPds4::getElement(
QStringList xmlPath, QDomElement parent) {
1334 QDomElement baseElement = parent;
1335 if (baseElement.isNull()) {
1336 baseElement = m_domDoc->documentElement();
1338 if (baseElement.isNull()) {
1339 QString msg =
"Unable to get element from empty XML document.";
1342 QString parentName = xmlPath[0];
1343 if (parentName != baseElement.tagName()) {
1344 QString msg =
"The tag name of the parent element passed in " 1345 "must be the first value in the given XML path.";
1348 for (
int i = 1; i < xmlPath.size(); i++) {
1349 QString elementName = xmlPath[i];
1350 QDomElement nextElement = baseElement.firstChildElement(elementName);
1351 baseElement = nextElement;
1366 QString pds4Type(
"UNK");
1367 if(p_pixelType == Isis::UnsignedByte) {
1368 pds4Type =
"UnsignedByte";
1370 else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Msb)) {
1371 pds4Type =
"UnsignedMSB2";
1373 else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Lsb)) {
1374 pds4Type =
"UnsignedLSB2";
1376 else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Msb)) {
1377 pds4Type =
"SignedMSB2";
1379 else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Lsb)) {
1380 pds4Type =
"SignedLSB2";
1382 else if((p_pixelType == Isis::Real) && (p_endianType == Isis::Msb)) {
1383 pds4Type =
"IEEE754MSBSingle";
1385 else if((p_pixelType == Isis::Real) && (p_endianType == Isis::Lsb)) {
1386 pds4Type =
"IEEE754LSBSingle";
1389 QString msg =
"Unsupported PDS pixel type or sample size";
1405 void ProcessExportPds4::addHistory(QString description, QString date, QString version) {
1407 QDomElement identificationElement;
1409 identificationPath.append(
"Product_Observational");
1410 identificationPath.append(
"Identification_Area");
1412 identificationElement = getElement(identificationPath);
1413 if( identificationElement.isNull() ) {
1418 QString msg =
"Could not find Identification_Area element " 1419 "to add modification history under.";
1425 QDomElement historyElement = identificationElement.firstChildElement(
"Modification_History");
1426 if ( historyElement.isNull() ) {
1427 historyElement = m_domDoc->createElement(
"Modification_History");
1428 identificationElement.insertAfter( historyElement,
1429 identificationElement.lastChildElement() );
1434 QDomElement detailElement = m_domDoc->createElement(
"Modification_Detail");
1436 QDomElement modDateElement = m_domDoc->createElement(
"modification_date");
1437 PvlToXmlTranslationManager::setElementValue(modDateElement, date);
1438 detailElement.appendChild(modDateElement);
1440 QDomElement versionIdElement = m_domDoc->createElement(
"version_id");
1441 PvlToXmlTranslationManager::setElementValue(versionIdElement, version);
1442 detailElement.appendChild(versionIdElement);
1444 QDomElement descriptionElement = m_domDoc->createElement(
"description");
1445 PvlToXmlTranslationManager::setElementValue(descriptionElement, description);
1446 detailElement.appendChild(descriptionElement);
1448 historyElement.insertAfter( detailElement,
1449 historyElement.lastChildElement() );
1470 void ProcessExportPds4::translateUnits(QDomDocument &label, QString transMapFile) {
1473 configPvl.
read(transMapFile);
1476 QString msg =
"Failed to read unit translation config file [" + transMapFile +
"].";
1482 transMap = createUnitMap(configPvl);
1485 QString msg =
"Failed to load unit translation config file [" + transMapFile +
"].";
1492 translateChildUnits( label.documentElement(), transMap );
1495 QString msg =
"Failed to translate units with config file [" + transMapFile +
"].";
1513 for (
int i = 0; i < configPvl.
objects(); i++) {
1515 for (
int j = 0; j < unitObject.
groups(); j++) {
1518 QString msg =
"No PDS4 standard specified for for [" + unitGroup.
name() +
"]";
1524 transMap.insert(pds4Key[0].toLower(), pds4Key[0]);
1528 PvlKeyword isisKey = unitGroup[
"ISIS_Units"];
1529 for (
int k = 0; k < isisKey.
size() ; k++) {
1530 transMap.insert(isisKey[k].toLower(), pds4Key[0]);
1552 QDomElement childElement = parent.firstChildElement();
1554 while( !childElement.isNull() ) {
1555 if ( childElement.hasAttribute(
"unit") ) {
1556 QString originalUnit = childElement.attribute(
"unit");
1557 if ( transMap.contains( originalUnit.toLower() ) ) {
1558 childElement.setAttribute(
"unit", transMap.value( originalUnit.toLower() ) );
1561 QString msg =
"Could not translate unit [" + originalUnit +
"] to PDS4 format.";
1565 translateChildUnits(childElement, transMap);
1566 childElement = childElement.nextSiblingElement();
PvlObject & object(const int index)
Return the object at the specified index.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
QString unit(const int index=0) const
Returns the units of measurement of the element of the array of values for the object at the specifie...
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
File name manipulation and expansion.
int objects() const
Returns the number of objects.
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Namespace for the standard library.
ByteOrder
Tests the current architecture for byte order.
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
QString originalPath() const
Returns the path of the original file name.
double toDouble(const QString &string)
Global function to convert from a string to a double.
PixelType
Enumerations for Isis Pixel Types.
bool hasObject(const QString &name) const
Returns a boolean value based on whether the object exists in the current PvlObject or not...
QString name() const
Returns the container name.
Base class for Map Projections.
int size() const
Returns the number of values stored in this keyword.
Contains multiple PvlContainers.
#define _FILEINFO_
Macro for the filename and line number.
A single keyword-value pair.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Container for cube-like labels.
PvlKeyword & findKeyword(const QString &name)
Find a keyword with a specified name.
QString baseName() const
Returns the name of the file without the path and without extensions.
PvlGroup & group(const int index)
Return the group at the specified index.
Allows applications to translate simple text files.
void Auto(QDomDocument &outputLabel)
Automatically translate all the output names found in the translation table.
Namespace for ISIS/Bullet specific routines.
QString extension() const
Returns the last extension of the file name.
int groups() const
Returns the number of groups contained.
Contains Pvl Groups and Pvl Objects.
void read(const QString &file)
Loads PVL information from a stream.
virtual QString Name() const =0
This method returns the name of the map projection.