#ifdef _WIN32 #include #include #else #include #include #endif #include #ifndef INCLUDED_DLGHEADER_HXX #include "dlg/DLGHeader.hxx" #endif #ifndef INCLUDED_DLGUTIL_H #include "dlg/DLGUtil.hxx" #endif static double myatof(char const* str) { // Beleive it or not, atof acts differently on Windows than under Solaris/gcc. // Under windows, atof accepts 'D' as an exponent. It does _not_ under gcc. // This functions wraps atof, replacing 'D' with 'E'. string buf(str); for (long i = 0; i < buf.size(); i++) if (buf[i] == 'D') buf[i] = 'E'; return atof(buf.c_str()); } DLGHeader::DLGHeader(void) { _banner = ""; _dcu_name = ""; _origSourceMatDate = ""; _dateQualifier = ""; _origSourceMatScale = 0; _line3 = ""; _line10 = ""; _levelCode = 0; _grndRefSys = 0; _grndRefSysZone = 0; _grndRefSysUnits = 0; _resolution = 0.0; _numFileToMapParams = 0; _numAccuracyMiscRecs = 0; _numSidesInCellPoly = 0; _numCategories = 0; _hDatum = 0; _vDatum = 0; } DLGHeader::~DLGHeader(void) { } ostream& operator<<(ostream& s, DLGHeader& header) { ostrstream ostr; int i; // dummy iteration variable // LINE 1 // Banner s.setf(ios::left); s << setw(80) << header._banner << endl; // LINE 2 ostr.seekp(0,ios::beg); ostr << header._dcu_name.substr(0,40); ostr << " "; ostr << header._origSourceMatDate.substr(0,10); ostr << header._dateQualifier.substr(0,1); ostr << setw(8) << header._origSourceMatScale; ostr << ends; s << setw(80) << ostr.str() << endl; ostr.freeze(0); // Line 3 s << setw(80) << header._line3 << endl; // Line 4 ostr.seekp(0,ios::beg); ostr << setw(6) << header._levelCode; ostr << setw(6) << header._grndRefSys; ostr << setw(6) << header._grndRefSysZone; ostr << setw(6) << header._grndRefSysUnits; ostr.setf(ios::fixed, ios::floatfield); ostr.precision(11); ostr << setw(18) << header._resolution; ostr << setw(6) << header._numFileToMapParams; ostr << setw(6) << header._numAccuracyMiscRecs; ostr << setw(6) << header._numSidesInCellPoly; ostr << setw(6) << header._numCategories; // START lines added by Mike Childs 5/13/97 ostr << setw(3) << header._hDatum; ostr << setw(3) << header._vDatum; // END lines added by Mike Childs 5/13/97 ostr << ends; s << setw(80) << ostr.str() << endl; ostr.freeze(0); // Lines 5-9. ostr.seekp(0, ios::beg); ostr.flags(ios::scientific); ostr.precision(15); for( i = 0; i < 5; i++ ) { for( int j = 0; j < 3; j++ ) { ostr << setw(24) << header._projParams[i * 3 + j]; } ostr << ends; s << setw(80) << ostr.str() << endl; ostr.freeze(0); ostr.seekp(0); } // Line 10 s << setw(80) << header._line10 << endl; // Control Point Identification Records ostr.flags(ios::fixed); for (i = 0; i < header._numSidesInCellPoly; i++) { ostr.seekp(0,ios::beg); ostr << header._controlPoints[i].label.substr(0,2); ostr << " "; ostr.precision(6); ostr << setw(12) << header._controlPoints[i].latitude; ostr << setw(12) << header._controlPoints[i].longitude; ostr << " "; ostr.precision(2); ostr << setw(12) << header._controlPoints[i].x; ostr << setw(12) << header._controlPoints[i].y; ostr << ends; s << setw(80) << ostr.str() << endl; ostr.freeze(0); } // Data Category Identification Records for (i = 0; i < header._numCategories; i++) { ostr.seekp(0,ios::beg); ostr << header._categories[i].name.substr(0,20); ostr << setw(4) << header._categories[i].formatCodes; ostr << setw(6) << header._categories[i].numNodesReferenced; ostr << setw(6) << header._categories[i].numActualNodes; ostr << " "; ostr << setw(1) << header._categories[i].nodeToAreaLinkFlag; ostr << setw(1) << header._categories[i].nodeToLineLinkFlag; ostr << " "; ostr << setw(6) << header._categories[i].numAreasReferenced; ostr << setw(6) << header._categories[i].numActualAreas; ostr << " "; ostr << setw(1) << header._categories[i].areaToNodeLinkFlag; ostr << setw(1) << header._categories[i].areaToLineLinkFlag; ostr << setw(1) << header._categories[i].areaCoordListFlag; ostr << setw(6) << header._categories[i].numLinesReferenced; ostr << setw(6) << header._categories[i].numActualLines; ostr << " "; ostr << setw(1) << header._categories[i].lineCoordListFlag; ostr << ends; s << setw(80) << ostr.str() << endl; ostr.freeze(0); } return s; } istream& operator>>(istream& s, DLGHeader& header) { string bufstr; int i; // dummy iteration variable // LINE 1 // Banner DLGUtil::getRecord(s,bufstr); header._banner = bufstr.substr(0,72); // LINE 2 DLGUtil::getRecord(s,bufstr); // DCU Name header._dcu_name = bufstr.substr(0,40); // Original Source Material Date header._origSourceMatDate = bufstr.substr(41,10); // Date Qualifier header._dateQualifier = bufstr.substr(51,1); header._origSourceMatScale = atoi(bufstr.substr(52,8).c_str()); // LINE 3 DLGUtil::getRecord(s,header._line3); // LINE 4 DLGUtil::getRecord(s,bufstr); header._levelCode = atoi(bufstr.substr(0,6).c_str()); header._grndRefSys = atoi(bufstr.substr(6,6).c_str()); header._grndRefSysZone = atoi(bufstr.substr(12,6).c_str()); header._grndRefSysUnits = atoi(bufstr.substr(18,6).c_str()); header._resolution = atof(bufstr.substr(24,18).c_str()); header._numFileToMapParams = atoi(bufstr.substr(42,6).c_str()); header._numAccuracyMiscRecs = atoi(bufstr.substr(48,6).c_str()); header._numSidesInCellPoly = atoi(bufstr.substr(54,6).c_str()); header._numCategories = atoi(bufstr.substr(60,6).c_str()); header._hDatum = strtol(bufstr.substr(66,3).c_str(), 0, 10); header._vDatum = strtol(bufstr.substr(69,3).c_str(), 0, 10); // START lines added by Justin Ferguson 6/7/97 // Redundant value checking. Just in case. if ((header._hDatum < 0) || (header._hDatum > 4)) header._hDatum = 0; if ((header._vDatum < 0) || (header._vDatum > 2)) header._vDatum = 0; // END lines added by Justin Ferguson 6/7/97 // Projection parameter records (Lines 5 - 9). for (i = 0; i < 5; i++ ) { DLGUtil::getRecord(s,bufstr); header._projParams[i*3] = myatof(bufstr.substr(0,24).c_str()); header._projParams[i*3 + 1] = myatof(bufstr.substr(24, 24).c_str()); header._projParams[i*3 + 2] = myatof(bufstr.substr(48, 24).c_str()); } // Line 10 DLGUtil::getRecord(s, header._line10); // Control Point Identification Records for (i = 0; i < header._numSidesInCellPoly; i++) { DLGUtil::getRecord(s,bufstr); header._controlPoints[i].id = i; header._controlPoints[i].label = bufstr.substr(0,2); header._controlPoints[i].latitude = atof(bufstr.substr(6,12).c_str()); header._controlPoints[i].longitude = atof(bufstr.substr(18,12).c_str()); header._controlPoints[i].x = atof(bufstr.substr(36,12).c_str()); header._controlPoints[i].y = atof(bufstr.substr(48,12).c_str()); } // Data Category Identification Records for (i = 0; i < header._numCategories; i++) { DLGUtil::getRecord(s,bufstr); header._categories[i].id = i; header._categories[i].name = bufstr.substr(0,20); header._categories[i].formatCodes = atoi(bufstr.substr(20,4).c_str()); header._categories[i].numNodesReferenced = atoi(bufstr.substr(24,6).c_str()); header._categories[i].numActualNodes = atoi(bufstr.substr(30,6).c_str()); header._categories[i].nodeToAreaLinkFlag = atoi(bufstr.substr(37,1).c_str()); header._categories[i].nodeToLineLinkFlag = atoi(bufstr.substr(38,1).c_str()); header._categories[i].numAreasReferenced = atoi(bufstr.substr(40,6).c_str()); header._categories[i].numActualAreas = atoi(bufstr.substr(46,6).c_str()); header._categories[i].areaToNodeLinkFlag = atoi(bufstr.substr(53,1).c_str()); header._categories[i].areaToLineLinkFlag = atoi(bufstr.substr(54,1).c_str()); header._categories[i].areaCoordListFlag = atoi(bufstr.substr(55,1).c_str()); header._categories[i].numLinesReferenced = atoi(bufstr.substr(56,6).c_str()); header._categories[i].numActualLines = atoi(bufstr.substr(62,6).c_str()); header._categories[i].lineCoordListFlag = atoi(bufstr.substr(71,1).c_str()); } return s; } const string& DLGHeader::getBanner(void) const { return _banner; } const string& DLGHeader::getDCU_Name(void) const { // "Digital Cartographic Unit Name" // When practical, the name of the source map followed by the State // two-character designators. return _dcu_name; } const string& DLGHeader::getOrigSourceMaterialDate(void) const { // Year of original source material followed by the latest revision // date if applicable; for example, 1956, 1965. return _origSourceMatDate; } const string& DLGHeader::getDateQualifier(void) const { // Qualifier to descriminate revision date if present. // "P" = photorevision // "I" = photo inspection // "L" = limited revision return _dateQualifier; } long DLGHeader::getOrigSourceMaterialScale(void) const { // Scale denominator of source material. For example, 24000. return _origSourceMatScale; } long DLGHeader::getLevelCode(void) const { // Code = 3, DLG-3. return _levelCode; } long DLGHeader::getGrndRefSys(void) const { // Code = 1, UTM. return _grndRefSys; } long DLGHeader::getGrndRefSysZone(void) const { // Code defining zone in ground planimeteric reference system. // Codes for UTM coordinate zones are given in Appendix C of the standard. return _grndRefSysZone; } long DLGHeader::getGrndRefSysUnits(void) const { // Code defining units of measure for ground planimetric coordinates // throughout the file. // Code = 2, meters. return _grndRefSysUnits; } double DLGHeader::getResolution(void) const { // The true ground distance corresponding to one unit (0.001 inch at // map scale) in the file internal coordinate system used in data // collection. // Scale Resolutions // 1:24000 0.61 meters // 1:25000 0.635 meters // 1:48000 1.22 meters // 1:62500 1.587 meters return _resolution; } long DLGHeader::getNumFileToMapParams(void) const { // Number of file to map transformation parameters. Usually 4. return _numFileToMapParams; } long DLGHeader::getNumAccuracyMiscRecs(void) const { // Number of Accuracy / Miscellaneous records. Currently zero, // none included. return _numAccuracyMiscRecs; } long DLGHeader::getNumSidesInCellPoly(void) const { // Number of sides in the polygon which define the coverage of the cell. // Also defines the number of control points. Always 4. return _numSidesInCellPoly; } long DLGHeader::getNumCategories(void) const { // Number of categories in the DLG file. Value may be from 1 to 32. // The value will be 1. return _numCategories; } void DLGHeader::getControlPointInfo(long controlPointId, DLGControlPoint& cp) const { // Returns the information for the given control point. The control // point ids start at zero. cp = _controlPoints[controlPointId]; } bool DLGHeader::setControlPointInfo(long controlPointId, DLGControlPoint const& cp) { _controlPoints[controlPointId] = cp; return true; } void DLGHeader::getCategoryInfo(long category, DLGCategory& dlgcat) const { // Returns the information for the requested categories. Category // ids are zero based (The first category in the file is category zero (0). dlgcat = _categories[category]; } bool DLGHeader::setCategoryInfo(long category, DLGCategory const& value) { if ((category < 0)||(category > 32)) return false; if (_numCategories <= category) return false; _categories[category].id = value.id; _categories[category].name = value.name; _categories[category].formatCodes = value.formatCodes; _categories[category].numNodesReferenced = value.numNodesReferenced; _categories[category].numActualNodes = value.numActualNodes; _categories[category].nodeToAreaLinkFlag = value.nodeToAreaLinkFlag; _categories[category].nodeToLineLinkFlag = value.nodeToLineLinkFlag; _categories[category].numAreasReferenced = value.numAreasReferenced; _categories[category].numActualAreas = value.numActualAreas; _categories[category].areaToNodeLinkFlag = value.areaToNodeLinkFlag; _categories[category].areaToLineLinkFlag = value.areaToLineLinkFlag; _categories[category].areaCoordListFlag = value.areaCoordListFlag; _categories[category].numLinesReferenced = value.numLinesReferenced; _categories[category].numActualLines = value.numActualLines; _categories[category].lineCoordListFlag = value.lineCoordListFlag; return true; } double DLGHeader::getProjectionParameter(int index) const { if ( index >= 0 && index < 15 ) return _projParams[index]; else return 0; } long DLGHeader::getHorizontalDatum() const { return _hDatum; } long DLGHeader::getVerticalDatum() const { return _vDatum; }