/** ** ** @RDE_HEADER@ ** PlanEditor translate symbol codes from MIL2525d to MIL2525c and vice versa. ** $Id$ ** $HeadURL$ ** $Author$ ** ** ----------------------------------------------------------------------------------------------- ** ** Hardware-Environment: Intel-PC ** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5 ** ** Language ........: C++ 11 ** ** ----------------------------------------------------------------------------------------------- ** ** Author ...........: Jörg Turla, SPD G, Tel. 3132 ** ** ----------------------------------------------------------------------------------------------- ** ** Notes .........: ** ** 12.10.2016, JT : First edition for use with Qt5 ** ** ----------------------------------------------------------------------------------------------- */ #include "mil2525d_to_mil2525c.h" #include "logging.h" #include #include #include #include #include #include #include #include namespace PlanEditor { namespace MIL2525 { class Converter::Internal { class CodePair : public QSharedData { public: unsigned int m_code2525d; QString m_sidc2525c; QRegExp m_sidcQuery; QString m_kindOfRubberband; explicit CodePair(unsigned int code, QString sidc, const QString &kindOfRubberband) : m_code2525d(code) , m_sidc2525c(sidc) , m_kindOfRubberband(kindOfRubberband) { sidc.replace(QLatin1Char('*'), QLatin1Char('.')); m_sidcQuery = QRegExp(sidc); if (m_kindOfRubberband.isEmpty()) m_kindOfRubberband = QStringLiteral("PointFeature"); } // CodePair( unsigned int code, const QString & sidc ) ~CodePair() = default; }; // class CodePair typedef QExplicitlySharedDataPointer CodePairPointer; QVector m_codePairList; QHash m_2525dToSidc; QHash> m_kindOfRubberbandHash; Logger m_logger; bool parseLine(const QString &line) { if (line.isEmpty()) return true; QVector tokenList = line.splitRef(QLatin1Char(';')); QRegExp sidcTemplate(QStringLiteral("^[A-Z]{1,1}\\*[A-Z]+[\\-\\*X]+$")); QString sidc; foreach (const auto &t, tokenList) { if (t.size() != 15) continue; const QString token(t.toString()); // ERROR_LOG( m_logger ) << token << ENDLOG(); if (sidcTemplate.exactMatch(token)) { sidc = token; break; } } if (sidc.isEmpty()) return true; bool isNumber = false; const QStringRef &code2525d = tokenList.last(); unsigned int code = code2525d.toUInt(&isNumber); if (!isNumber) { return true; // skip over } if (m_2525dToSidc.contains(code)) return true; QStringRef kindOfRubberband; foreach (auto token, tokenList) { if (token.startsWith(QStringLiteral("gct_"))) { kindOfRubberband = token; break; } } CodePairPointer codePair(new CodePair(code, sidc.left(10), kindOfRubberband.toString())); m_2525dToSidc[code] = codePair; m_codePairList += codePair; m_kindOfRubberbandHash[codePair->m_kindOfRubberband] += codePair; return true; } // void parseLine( const QString & line ) public: Internal() : m_logger(getLogger("MIL2525-Converter")) { auto stripLeadingAndTrailingQuotes = [](QString str) -> QString { str = str.simplified(); if (str.startsWith(QLatin1Char('"'))) { str.remove(0, 1); if (str.endsWith(QLatin1Char('"'))) str.chop(1); } return str; }; // stripLeadingAndTrailingQuotes = []( QString str ) -> QString QFile file(QCoreApplication::applicationDirPath() + QStringLiteral("/MIL2525D_to_MIL2525C.def")); if (file.exists()) { if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { unsigned int lineNo = 0; while (!file.atEnd()) { lineNo++; QString line(QString::fromLatin1(file.readLine())); if (lineNo > 1) { if (!parseLine(stripLeadingAndTrailingQuotes(line))) ERROR_LOG(m_logger) << "Error while parsing MIL2525D_toMIL2525C.def in line " << lineNo << ENDLOG(); } } file.close(); #ifdef LOG_gct_token file.setFileName(QStringLiteral("C:/MIL2525D_RubberbandKinds.txt")); if (file.open(QIODevice::OpenModeFlag::ReadWrite | QIODevice::OpenModeFlag::Truncate | QIODevice::OpenModeFlag::Text)) { QTextStream ostream(&file); for (auto keyIter = m_kindOfRubberbandHash.keyBegin(); keyIter != m_kindOfRubberbandHash.keyEnd(); ++keyIter) { const QString &kindOfRubberband = *keyIter; const QLinkedList &codeList = m_kindOfRubberbandHash[kindOfRubberband]; ostream.setFieldWidth(35); ostream.setFieldAlignment(QTextStream::FieldAlignment::AlignLeft); ostream << kindOfRubberband; ostream.setFieldAlignment(QTextStream::FieldAlignment::AlignRight); ostream.setFieldWidth(-1); foreach (const auto code, codeList) { ostream << '\n'; ostream.setFieldWidth(35); ostream << ' '; ostream.setFieldWidth(16); ostream << code->m_sidc2525c; ostream.setFieldWidth(9); ostream << code->m_code2525d; ostream.setFieldWidth(-1); } ostream << '\n'; ostream.flush(); } // for file.close(); } #endif } else ERROR_LOG(m_logger) << "Open file for reading failed: " << file.fileName() << ENDLOG(); } else ERROR_LOG(m_logger) << "File doesn't exist: " << file.fileName() << ENDLOG(); } // Internal() ~Internal() { m_2525dToSidc.clear(); m_codePairList.clear(); m_codePairList.clear(); } // ~Internal() QString baseSymbolFromSidc(const QString &sidc) const { foreach (auto codePairPtr, m_codePairList) { if (codePairPtr->m_sidcQuery.exactMatch(sidc)) return QString::number(codePairPtr->m_code2525d); } return QString(); } // QString baseSymbolFromSidc( const QString & sidc ) QString baseSymbolToSidc(const QString &baseSymbolCode) const { bool ok = false; unsigned int code = baseSymbolCode.toUInt(&ok); if (!ok) return QString(); auto it = m_2525dToSidc.find(code); if (it == m_2525dToSidc.end()) return QString(); return it.value()->m_sidc2525c; } // QString baseSymbolToSidc( const QString & baseSymbolCode ) }; // class Converter::Internal Converter::Converter() : m_internal(new Internal()) {;} Converter::~Converter() { delete m_internal; } QString Converter::baseSymbolFromSidc(const QString &sidc) const { return m_internal->baseSymbolFromSidc(sidc); } QString Converter::baseSymbolToSidc(const QString &baseSymbolCode) const { return m_internal->baseSymbolToSidc(baseSymbolCode); } } // namespace MIL2525 } // namespace PlanEditor