259 lines
7.4 KiB
C++
Executable File
259 lines
7.4 KiB
C++
Executable File
/**
|
|
**
|
|
** @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 <QtCore/QCoreApplication>
|
|
#include <QtCore/QFile>
|
|
#include <QtCore/QHash>
|
|
#include <QtCore/QVector>
|
|
#include <QtCore/QRegExp>
|
|
|
|
#include <QtCore/QSharedData>
|
|
#include <QtCore/QExplicitlySharedDataPointer>
|
|
#include <QtCore/QTextStream>
|
|
|
|
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<CodePair> CodePairPointer;
|
|
|
|
QVector<CodePairPointer> m_codePairList;
|
|
QHash<unsigned int, CodePairPointer> m_2525dToSidc;
|
|
QHash<QString, QVector<CodePairPointer>> m_kindOfRubberbandHash;
|
|
Logger m_logger;
|
|
|
|
bool parseLine(const QString &line)
|
|
{
|
|
if (line.isEmpty()) return true;
|
|
|
|
QVector<QStringRef> 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<CodePairPointer> &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
|
|
|