316 lines
11 KiB
C++
Executable File
316 lines
11 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Interface-Implementation of EsriDictionaryProcessorApp6
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
// Own
|
|
#include "esri_dictionary_processor_app6.h"
|
|
#include "sidc_builder_base.h"
|
|
|
|
// ESRI
|
|
|
|
|
|
// Qt
|
|
#include <QtConcurrent>
|
|
#include <QFuture>
|
|
|
|
|
|
namespace AdvancedSymbology
|
|
{
|
|
|
|
EsriDictionaryProcessorApp6::EsriDictionaryProcessorApp6()
|
|
: BaseClass(AdvancedSymbology::SymbologyType::APP6B)
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " ThreadId=" << QThread::currentThreadId();
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
} // EsriDictionaryProcessorApp6::~EsriDictionaryProcessorApp6()
|
|
|
|
|
|
EsriDictionaryProcessorApp6::~EsriDictionaryProcessorApp6()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
this->cancel();
|
|
this->waitForFinished();
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
} // EsriDictionaryProcessorApp6::~EsriDictionaryProcessorApp6()
|
|
|
|
|
|
void EsriDictionaryProcessorApp6::cancel()
|
|
{
|
|
BaseClass::cancel();
|
|
// add specific here:
|
|
} // void EsriDictionaryProcessorApp6::cancel()
|
|
|
|
|
|
void EsriDictionaryProcessorApp6::waitForFinished()
|
|
{
|
|
BaseClass::waitForFinished();
|
|
// add specific here:
|
|
} // void EsriDictionaryProcessorApp6::waitForFinished()
|
|
|
|
|
|
bool EsriDictionaryProcessorApp6::searchResultIsValid(const QHash<QString, int> &key8LookupTable,
|
|
const Esri::ArcGISRuntime::SymbolStyleSearchResult &resultItem,
|
|
QString *toBeRemovedFromName)
|
|
{
|
|
Q_UNUSED(key8LookupTable)
|
|
Q_UNUSED(toBeRemovedFromName)
|
|
const QString &originalKey = resultItem.key();
|
|
// const QString &name = resultItem.name();
|
|
// const QString &tags = resultItem.tags().join(QLatin1Char('|'));
|
|
// const QString &category = resultItem.category();
|
|
// const QString &symbolclass = resultItem.symbolClass();
|
|
|
|
// Esri::ArcGISRuntime::Symbol * symbol = resultItem.symbol();
|
|
|
|
#ifdef APP6_DUMP
|
|
static QFile * file = nullptr;
|
|
|
|
if (nullptr == file)
|
|
{
|
|
file = new QFile();
|
|
file->setFileName(QStringLiteral("app6.info"));
|
|
}
|
|
|
|
file->open(QIODevice::OpenModeFlag::Append | QIODevice::OpenModeFlag::Text);
|
|
|
|
QTextStream out(file);
|
|
out << symbolclass << " ; " << category << " ; " << originalKey << " ; " << name << " ; " << tags << endl;
|
|
|
|
file->close();
|
|
#endif
|
|
|
|
//TRACE_LOG(m_logger)
|
|
|
|
// qCritical() << LOGFUNCTION << " originalKey='" << originalKey << "' namne ='" << name <<"'";
|
|
|
|
// check symbolClass: (to reduce empty keys, check symboClass first)
|
|
int symbolClass = resultItem.symbolClass().toInt();
|
|
if ((symbolClass == 6) || // symbolClass ( 6) == TextSymbol
|
|
(symbolClass == 10) // symbolClass (10) == MaplexLabelPlacement
|
|
)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION
|
|
<< " symbolClass does not match "
|
|
<< " originalKey='" << originalKey << "'"
|
|
<< " name='" << resultItem.name() << "'";
|
|
return false;
|
|
}
|
|
|
|
const int keySize = originalKey.size();
|
|
if ((15 != keySize) && (10 != keySize))
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION
|
|
<< " keySize does not match,"
|
|
<< " originalKey='" << originalKey << "'"
|
|
<< " name='" << resultItem.name() << "'";
|
|
return false;
|
|
}
|
|
|
|
// const QStringRef & baseKey = originalKey.midRef(4,5);
|
|
|
|
return true;
|
|
|
|
} // bool EsriDictionaryProcessorApp6::resultItemIsValid(const Esri::ArcGISRuntime::SymbolStyleSearchResult &resultItem)
|
|
|
|
|
|
|
|
bool EsriDictionaryProcessorApp6::processBaseSymbolCodeToPropertyTable()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
|
|
if (m_searchResultList.isEmpty())
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " m_searchResultList.isEmpty";
|
|
return false;
|
|
}
|
|
|
|
int resultItemCounter = 0;
|
|
int gctStringEmptyCounter = 0;
|
|
for (const Esri::ArcGISRuntime::SymbolStyleSearchResult &resultItem : qAsConst(m_searchResultList))
|
|
{
|
|
|
|
// canceled?
|
|
// 2017-09-07, Qt5.9, N. Thoden
|
|
// A default initialized QFuture seems to have an inconsistent state:
|
|
// -> isStarted=1 <---!!!
|
|
// -> isRunning=0
|
|
// -> isCanceled=1 <---!!!
|
|
// so check isCanceled() && isRunning()
|
|
// 2017-10-09, Qt5.9.1, N.Thoden
|
|
// Problöem still arises, so perform at a least a couple:
|
|
if (m_baseSymbolCodeToSymbolPropertyTableWatcher.isCanceled() && m_baseSymbolCodeToSymbolPropertyTableWatcher.isRunning() &&
|
|
(resultItemCounter >= 10))
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " m_baseSymbolCodeToSymbolPropertyTableWatcher.isCanceled";
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " m_baseSymbolCodeToSymbolPropertyTableWatcher.isStarted=" << m_baseSymbolCodeToSymbolPropertyTableWatcher.isStarted();
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " m_baseSymbolCodeToSymbolPropertyTableWatcher.isRunning=" << m_baseSymbolCodeToSymbolPropertyTableWatcher.isRunning();
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " m_baseSymbolCodeToSymbolPropertyTableWatcher.isCanceled=" << m_baseSymbolCodeToSymbolPropertyTableWatcher.isCanceled();
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " m_baseSymbolCodeToSymbolPropertyTableWatcher.isFinished=" << m_baseSymbolCodeToSymbolPropertyTableWatcher.isFinished();
|
|
return false;
|
|
}
|
|
|
|
|
|
if (resultItemCounter == 0)
|
|
INFO_LOG(m_logger) << LOGFUNCTION << " counter=" << resultItemCounter;
|
|
|
|
++resultItemCounter;
|
|
|
|
if ((resultItemCounter % 500) == 0)
|
|
INFO_LOG(m_logger) << LOGFUNCTION << " counter=" << resultItemCounter;
|
|
|
|
|
|
// INFO_LOG(m_logger) << LOGFUNCTION << " resultItem.key ='" << resultItem.key() << "'";
|
|
// INFO_LOG(m_logger) << LOGFUNCTION << " resultItem.name ='" << resultItem.name() << "'";
|
|
// INFO_LOG(m_logger) << LOGFUNCTION << " resultItem.category ='" << resultItem.category() << "'";
|
|
// INFO_LOG(m_logger) << LOGFUNCTION << " resultItem.symbolClass ='" << resultItem.symbolClass() << "'";
|
|
// INFO_LOG(m_logger) << LOGFUNCTION << " resultItem.tags ='" << resultItem.tags().join(QLatin1String(";")) << "'";
|
|
|
|
bool isValid = searchResultIsValid(QHash<QString, int>(), resultItem);
|
|
|
|
if (!isValid)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION
|
|
<< " continue:: not valid "
|
|
<< " key='" << resultItem.key() << "'"
|
|
<< " name='" << resultItem.name() << "'";
|
|
continue;
|
|
}
|
|
|
|
const QString &originalKey = resultItem.key();
|
|
const QString &baseKey = SidcBuilderBase::normalizeAPP6BaseSymbolCode( originalKey );
|
|
|
|
if (m_baseSymbolCodeToSymbolPropertyTable.contains(baseKey))
|
|
{
|
|
/* FATAL_LOG(m_logger) << LOGFUNCTION
|
|
<< " continue:: already EXISTS!!!"
|
|
<< " baseKey='" << baseKey << "'"
|
|
<< " originalKey='" << originalKey << "'";*/
|
|
// It is normal here, comment out error message an continue
|
|
continue;
|
|
}
|
|
|
|
SymbolProperties symProps;
|
|
symProps.setKey(baseKey);
|
|
symProps.setName(resultItem.name());
|
|
symProps.setCategory(resultItem.category());
|
|
symProps.setSymbolClass(resultItem.symbolClass());
|
|
symProps.setTags(resultItem.tags());
|
|
symProps.setOriginalKey(originalKey);
|
|
symProps.setSidc(SidcCodec::encodeBaseSymbolCode(m_baseSymbolCodeToSymbolPropertyTable.symbologyType(), baseKey));
|
|
// retrieve GeometryType
|
|
|
|
const QString &slClass = resultItem.symbolClass();
|
|
|
|
if (!slClass.isEmpty())
|
|
{
|
|
bool isPoint = slClass.compare(QLatin1String("3"), Qt::CaseInsensitive) == 0;
|
|
bool isLine = slClass.compare(QLatin1String("4"), Qt::CaseInsensitive) == 0;
|
|
bool isArea = slClass.compare(QLatin1String("5"), Qt::CaseInsensitive) == 0;
|
|
|
|
if (isPoint)
|
|
symProps.setGeometryType(GeometryType::Point);
|
|
else if (isLine)
|
|
symProps.setGeometryType(GeometryType::Polyline);
|
|
else if (isArea)
|
|
symProps.setGeometryType(GeometryType::Polygon);
|
|
else
|
|
{
|
|
FATAL_LOG(m_logger) << LOGFUNCTION
|
|
<< " continue:: unknown geometry!!!"
|
|
<< " baseKey='" << baseKey << "'"
|
|
<< " originalKey='" << originalKey << "'";
|
|
continue;
|
|
}
|
|
}
|
|
|
|
/*
|
|
const QString cat = resultItem.category();
|
|
const QVector<QStringRef> &slCategory = cat.splitRef(QLatin1Char(':'));
|
|
|
|
if (!slCategory.isEmpty())
|
|
{
|
|
const QStringRef &geometryStr = slCategory.last().trimmed();
|
|
bool isPoint = geometryStr.compare(QLatin1String("Point"), Qt::CaseInsensitive) == 0;
|
|
bool isMainIcon = geometryStr.compare(QLatin1String("Main Icon"), Qt::CaseInsensitive) == 0;
|
|
bool isLine = geometryStr.compare(QLatin1String("Line"), Qt::CaseInsensitive) == 0;
|
|
bool isArea = geometryStr.compare(QLatin1String("Area"), Qt::CaseInsensitive) == 0;
|
|
|
|
if (isPoint || isMainIcon)
|
|
symProps.setGeometryType(GeometryType::Point);
|
|
else if (isLine)
|
|
symProps.setGeometryType(GeometryType::Polyline);
|
|
else if (isArea)
|
|
symProps.setGeometryType(GeometryType::Polygon);
|
|
}
|
|
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " XXXXXXXXX GeometryType:"
|
|
<< " baseKey='" << baseKey << "'"
|
|
<< " originalKey='" << originalKey << "'"
|
|
<< "' slLast='" << slCategory.last().toString() << "'"
|
|
<< " geoType= " << symProps.geometryType();
|
|
*/
|
|
|
|
// check for gct_-String:
|
|
if (symProps.geometryType() == GeometryType::Polyline ||
|
|
symProps.geometryType() == GeometryType::Polygon)
|
|
{
|
|
const QString & gctString = symProps.gctString();
|
|
if (gctString.isEmpty())
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " gctString is missing: baseKey='" << baseKey << "'"
|
|
<< " geoType= " << symProps.geometryType()
|
|
<< " tags=" << resultItem.tags().join(QLatin1String(";"));
|
|
++gctStringEmptyCounter;
|
|
|
|
// here define some special gct_string to demonstrate the function with APP6B
|
|
|
|
if (QStringLiteral("G*C*MOLDM-*****") == baseKey) symProps.setTags(symProps.tags() << QStringLiteral("gct_line"));
|
|
if (QStringLiteral("G*C*MOOP--*****") == baseKey) symProps.setTags(symProps.tags() << QStringLiteral("gct_arrow_with_tail"));
|
|
if (QStringLiteral("G*T*GE----*****") == baseKey) symProps.setTags(symProps.tags() << QStringLiteral("gct_circle"));
|
|
if (QStringLiteral("G*T*GQ----*****") == baseKey) symProps.setTags(symProps.tags() << QStringLiteral("gct_circle"));
|
|
if (QStringLiteral("G*C*MMDP--*****") == baseKey) symProps.setTags(symProps.tags() << QStringLiteral("gct_two_line"));
|
|
|
|
// so should be enough ....
|
|
|
|
if (symProps.gctString().isEmpty() && (QStringLiteral("G*C*MDM---*****") != baseKey))
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
m_baseSymbolCodeToSymbolPropertyTable[baseKey] = symProps;
|
|
|
|
} // for
|
|
|
|
m_baseSymbolCodeToSymbolPropertyTableFilled = true;
|
|
NOTICE_LOG(m_logger) << LOGFUNCTION << " ##### resultItemCounter=" << resultItemCounter
|
|
<< " m_baseSymbolCodeToSymbolPropertyTable.size=" << m_baseSymbolCodeToSymbolPropertyTable.size()
|
|
<< " gctStringEmptyCounter=" << gctStringEmptyCounter
|
|
<< " threadId: " << QThread::currentThreadId();
|
|
emit baseSymbolCodeToPropertyTableDone();
|
|
|
|
|
|
checkIfAllAreDone(); // will potentially emit signal 'allIsDone'
|
|
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
return true;
|
|
} // bool EsriDictionaryProcessorApp6::processBaseSymbolCodeToPropertyTable()
|
|
|
|
|
|
bool EsriDictionaryProcessorApp6::processModifierTable()
|
|
{
|
|
m_modifierTableFilled = true;
|
|
return true;
|
|
} // bool EsriDictionaryProcessorApp6::processModifierTable()
|
|
|
|
|
|
} // namespace AdvancedSymbology
|
|
|