3638 lines
140 KiB
C++
Executable File
3638 lines
140 KiB
C++
Executable File
/**
|
||
* @RDE_HEADER@
|
||
* Unittest
|
||
* $Id$
|
||
* $HeadURL$
|
||
* $Author$
|
||
*/
|
||
|
||
#include "unit_test.h"
|
||
|
||
#include <QtTest/QTest>
|
||
#include <QtTest/QSignalSpy>
|
||
#include <QWeakPointer>
|
||
|
||
#include <nglapplication/nglapplication.h>
|
||
#include <ngltools/ngltools_filesystem.h>
|
||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||
|
||
#include <Map/bounding_box.h>
|
||
#include <Map/object_factory.h>
|
||
#include <MapImpl/map_impl.h>
|
||
#include <MapImpl/map_layer.h>
|
||
#include <MapImpl/layer_factory_impl.h>
|
||
#include <MapImpl/object_container_impl.h>
|
||
#include <MapObjectsImpl/participant_impl.h>
|
||
#include <MapObjectsImpl/biological_agent_impl.h>
|
||
#include <MapObjectsImpl/building_outline_impl.h>
|
||
#include <MapObjectsImpl/danger_area_impl.h>
|
||
|
||
#include <Map/map_settings.h>
|
||
|
||
#include <MapImpl/coordinate_translation.h>
|
||
|
||
#include <MathUtils/matrix2d.h>
|
||
|
||
#include <Utils/movement_track.h>
|
||
#include <Utils/movement_track_manager.h>
|
||
|
||
//#include <Common/id_handler.h>
|
||
#include <Common/simple_value.h>
|
||
|
||
#include <GraphicalObjects/tactical_appearance.h>
|
||
|
||
#include <SymbologyImpl/symbol_dictionary_impl.h>
|
||
#include <Symbology/symbol_properties.h>
|
||
#include <Symbology/sidc_codec.h>
|
||
#include <Symbology/sidc_builder.h>
|
||
#include <Symbology/symbol_result.h>
|
||
#include <Symbology/bulk_renderer.h>
|
||
|
||
#include <CoordinateFormatter.h>
|
||
#include <GeometryEngine.h>
|
||
#include <LinearUnit.h>
|
||
#include <PolylineBuilder.h>
|
||
|
||
#include <QPainter>
|
||
#include <QTimer>
|
||
#include <QUuid>
|
||
#include <QJsonDocument>
|
||
#include <iostream>
|
||
|
||
#include <GeometryEngine.h>
|
||
#include <PolygonBuilder.h>
|
||
|
||
|
||
bool CheckSignal::isConnected(quint64 &msec)
|
||
{
|
||
QElapsedTimer timeClock;
|
||
timeClock.start();
|
||
|
||
bool isConnected = isSignalConnected(QMetaMethod::fromSignal(&CheckSignal::mySignal));
|
||
|
||
msec = timeClock.elapsed();
|
||
return isConnected;
|
||
}
|
||
|
||
|
||
|
||
//-------------------------------------------------------------------------------------------------------
|
||
// Helper class 'IdGeneratorCounting'
|
||
//-------------------------------------------------------------------------------------------------------
|
||
class IdGeneratorCounting : public SituationMap::IdGenerator
|
||
{
|
||
public:
|
||
IdGeneratorCounting() : SituationMap::IdGenerator()
|
||
{
|
||
++counter;
|
||
}
|
||
~IdGeneratorCounting()
|
||
{
|
||
--counter;
|
||
}
|
||
static ulong getCounter()
|
||
{
|
||
return counter;
|
||
}
|
||
|
||
private:
|
||
static ulong counter;
|
||
};
|
||
ulong IdGeneratorCounting::counter = 0;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//-------------------------------------------------------------------------------------------------------
|
||
int main(int argc, char *argv[])
|
||
{
|
||
NGLApplication app(argc, argv);
|
||
app.createLogger("SituationMapUnitTest", "log4cxxSituationMapUnitTest.props");
|
||
|
||
AdvancedSymbology::SymbologyType symbologyType = AdvancedSymbology::SymbologyType::MIL2525C;
|
||
|
||
if (argc < 2)
|
||
{
|
||
// usage:
|
||
std::cout << argv[0]
|
||
<< std::endl
|
||
<< " usage: append 'mil' | 'app' to argumentlist" << std::endl
|
||
<< " e.g " << argv[0] << " [QTest options] [testfunction] none" << std::endl
|
||
<< " e.g " << argv[0] << " [QTest options] [testfunction] mil2525D" << std::endl
|
||
<< " e.g " << argv[0] << " [QTest options] [testfunction] mil2525C" << std::endl
|
||
<< " e.g " << argv[0] << " [QTest options] [testfunction] app6b" << std::endl
|
||
<< " e.g " << argv[0] << " [QTest options] [testfunction] app6d" << std::endl
|
||
<< std::endl;
|
||
|
||
return -1;
|
||
}
|
||
|
||
const QString strSymType = app.arguments().constLast(); // the last argument
|
||
if (strSymType.compare(QLatin1String("none"), Qt::CaseInsensitive) == 0)
|
||
symbologyType = AdvancedSymbology::SymbologyType::None;
|
||
else if (strSymType.compare(QLatin1String("mil2525D"), Qt::CaseInsensitive) == 0)
|
||
symbologyType = AdvancedSymbology::SymbologyType::MIL2525D;
|
||
else if (strSymType.compare(QLatin1String("mil2525C"), Qt::CaseInsensitive) == 0)
|
||
symbologyType = AdvancedSymbology::SymbologyType::MIL2525C;
|
||
else if (strSymType.compare(QLatin1String("app6b"), Qt::CaseInsensitive) == 0)
|
||
symbologyType = AdvancedSymbology::SymbologyType::APP6B;
|
||
else if (strSymType.compare(QLatin1String("app6d"), Qt::CaseInsensitive) == 0)
|
||
symbologyType = AdvancedSymbology::SymbologyType::APP6D;
|
||
argc -= 1; // remove last argument for QTest::qExec
|
||
|
||
|
||
SituationMap::LayerFactoryImpl::setForceCreationOfGraphicsOverlay(false); // false => createLayerOnDemand
|
||
|
||
|
||
QSharedPointer<SitMapUnitTest> tc = QSharedPointer<SitMapUnitTest>(new SitMapUnitTest(symbologyType));
|
||
int retCode = QTest::qExec(tc.data(), argc, argv);
|
||
|
||
return retCode;
|
||
}
|
||
|
||
|
||
|
||
class SitMapUnitTest::Private
|
||
{
|
||
public:
|
||
|
||
Private()
|
||
: m_symbologyType(AdvancedSymbology::SymbologyType::MIL2525C)
|
||
{
|
||
// m_uniqueIdHandler = new SituationMap::IdHandler(m_initReserve,m_blockSize);
|
||
}
|
||
|
||
~Private() = default;
|
||
|
||
|
||
|
||
// std::unique_ptr<SituationMap::IdHandler> m_uniqueIdHandler;
|
||
|
||
AdvancedSymbology::SymbologyType m_symbologyType;
|
||
|
||
|
||
}; // class Private
|
||
//-----------------------------------------------------------------------------
|
||
|
||
|
||
|
||
class Foo
|
||
{
|
||
public:
|
||
virtual ~Foo() = default;
|
||
|
||
static Foo *createFoo()
|
||
{
|
||
return new Foo();
|
||
}
|
||
|
||
Foo(const Foo &) = delete; // if needed, put as private
|
||
Foo &operator=(const Foo &) = delete; // if needed, put as private
|
||
Foo(Foo &&) = delete; // if needed, put as private
|
||
Foo &operator=(Foo &&) = delete; // if needed, put as private
|
||
|
||
private:
|
||
Foo() {}
|
||
};
|
||
|
||
|
||
|
||
class baseClass
|
||
{
|
||
public:
|
||
virtual ~baseClass() = default;
|
||
|
||
baseClass(const baseClass &) = delete;
|
||
baseClass &operator=(const baseClass &) = delete;
|
||
baseClass(baseClass &&) = delete;
|
||
baseClass &operator=(baseClass &&) = delete;
|
||
|
||
virtual void doSomething() = 0;
|
||
|
||
|
||
protected:
|
||
baseClass() {}
|
||
};
|
||
|
||
class subClass : public baseClass
|
||
{
|
||
public:
|
||
~subClass() = default;
|
||
|
||
static subClass *create()
|
||
{
|
||
return new subClass();
|
||
}
|
||
|
||
void doSomething() override { }
|
||
|
||
private:
|
||
subClass() = default;
|
||
|
||
};
|
||
|
||
|
||
|
||
|
||
SitMapUnitTest::SitMapUnitTest(AdvancedSymbology::SymbologyType symbologyType)
|
||
: m_logger(SituationMap::getLogger("SitMapUnitTest"))
|
||
, m_d(new Private)
|
||
{
|
||
m_d->m_symbologyType = symbologyType;
|
||
|
||
NOTICE_LOG(m_logger) << "Running test with symbologyType " << m_d->m_symbologyType;
|
||
}
|
||
|
||
SitMapUnitTest::~SitMapUnitTest()
|
||
{
|
||
NOTICE_LOG(m_logger) << "Finished running test with symbologyType " << m_d->m_symbologyType;
|
||
}
|
||
|
||
void SitMapUnitTest::checkLogging()
|
||
{
|
||
SituationMap::LOGGER_T myLogger = SituationMap::getLogger("LoggingTest.Chan1");
|
||
FATAL_LOG(myLogger) << LOGFUNCTION << " myLogger.getLoggerName() -> " << myLogger.getLoggerName();
|
||
|
||
|
||
|
||
DEBUG_LOG(myLogger) << LOGFUNCTION << " (LoggingTest.Chan1) DEBUG-MSG" ;
|
||
INFO_LOG(myLogger) << LOGFUNCTION << " (LoggingTest.Chan1) INFO-MSG" ;
|
||
WARNING_LOG(myLogger) << LOGFUNCTION << " (LoggingTest.Chan1) WARNING-MSG" ;
|
||
ERROR_LOG(myLogger) << LOGFUNCTION << " (LoggingTest.Chan1) ERROR-MSG" ;
|
||
FATAL_LOG(myLogger) << LOGFUNCTION << " (LoggingTest.Chan1) FATAL-MSG" ;
|
||
|
||
FATAL_LOG(myLogger) << LOGFUNCTION << " ------------";
|
||
|
||
{
|
||
SituationMap::LOGGER_T myLogger = SituationMap::getLogger("LoggingTest.Chan2");
|
||
FATAL_LOG(myLogger) << LOGFUNCTION << " myLogger.getLoggerName() -> " << myLogger.getLoggerName();
|
||
|
||
DEBUG_LOG(myLogger) << LOGFUNCTION << " (LoggingTest.Chan2) DEBUG-MSG" ;
|
||
INFO_LOG(myLogger) << LOGFUNCTION << " (LoggingTest.Chan2) INFO-MSG" ;
|
||
WARNING_LOG(myLogger) << LOGFUNCTION << " (LoggingTest.Chan2) WARNING-MSG" ;
|
||
ERROR_LOG(myLogger) << LOGFUNCTION << " (LoggingTest.Chan2) ERROR-MSG" ;
|
||
FATAL_LOG(myLogger) << LOGFUNCTION << " (LoggingTest.Chan2) FATAL-MSG" ;
|
||
}
|
||
FATAL_LOG(myLogger) << LOGFUNCTION << " ------------" ;
|
||
|
||
// update logger-obj
|
||
SituationMap::LOGGER_T myLogger2 = SituationMap::getLogger("LoggingTest.Chan2");
|
||
FATAL_LOG(myLogger2) << LOGFUNCTION << " myLogger.getLoggerName() -> " << myLogger2.getLoggerName() ;
|
||
|
||
DEBUG_LOG(myLogger2) << LOGFUNCTION << " (LoggingTest.Chan2) DEBUG-MSG" ;
|
||
INFO_LOG(myLogger2) << LOGFUNCTION << " (LoggingTest.Chan2) INFO-MSG" ;
|
||
WARNING_LOG(myLogger2) << LOGFUNCTION << " (LoggingTest.Chan2) WARNING-MSG" ;
|
||
ERROR_LOG(myLogger2) << LOGFUNCTION << " (LoggingTest.Chan2) ERROR-MSG" ;
|
||
FATAL_LOG(myLogger2) << LOGFUNCTION << " (LoggingTest.Chan2) FATAL-MSG" ;
|
||
|
||
}
|
||
|
||
struct shm_punkt_rt
|
||
{
|
||
shm_punkt_rt(double x = 0, double y = 0)
|
||
{
|
||
p[0] = x; // Ost
|
||
p[1] = y; // Nord
|
||
}
|
||
|
||
double p[2];
|
||
};
|
||
|
||
void SitMapUnitTest::checkQRect()
|
||
{
|
||
QRectF rect;
|
||
|
||
QVERIFY2((rect.isEmpty() == true), "isEmpty: failed");
|
||
QVERIFY2((rect.isValid() == false), "isValid: failed");
|
||
|
||
rect = QRectF(100, 100, 40, 60);
|
||
QVERIFY2((rect.isEmpty() == false), "isEmpty: failed");
|
||
QVERIFY2((rect.isValid() == true), "isValid: failed");
|
||
|
||
QVERIFY2(rect.width() == 40, "center: failed");
|
||
QVERIFY2(rect.height() == 60, "center: failed");
|
||
|
||
qDebug() << " rect.center()" << rect.center();
|
||
QVERIFY2(((rect.center() - QPoint(120, 130)).manhattanLength() <= 2), "center: failed");
|
||
|
||
QVERIFY2(rect.top() == 100, "top: failed"); // <-----
|
||
QVERIFY2(rect.bottom() == 160, "bottom: failed"); // <-----
|
||
|
||
|
||
QVERIFY2(rect.topLeft() == QPointF(100, 100), "topLeft: failed"); // <-----
|
||
qDebug() << " rect.topRight()" << rect.topRight();
|
||
QVERIFY2(rect.topRight() == QPointF(140, 100), "topLeft: failed"); // <-----
|
||
|
||
}
|
||
|
||
|
||
void SitMapUnitTest::checkQListQVector()
|
||
{
|
||
|
||
std::vector<shm_punkt_rt> refPoints;
|
||
|
||
int refSize = 1000000;
|
||
refPoints.reserve(refSize);
|
||
|
||
for (int i = 0; i < refSize; ++i)
|
||
refPoints.emplace_back(i, 100.1 * i);
|
||
|
||
// check within 2*5:
|
||
QList<QPointF> qContL; // do NOT modify, QList is used to compare with QVector (a couple of lines later)
|
||
QVector<QPointF> qContV;
|
||
for (int i = 0; i < 10; ++i)
|
||
{
|
||
if (i % 2 == 0)
|
||
{
|
||
QElapsedTimer timer;
|
||
if (m_logger.isInfoEnabled())
|
||
timer.start();
|
||
|
||
|
||
qContL.clear();
|
||
qContL.reserve(refSize);
|
||
for (const shm_punkt_rt &item : refPoints)
|
||
qContL.append(QPointF(item.p[0], item.p[1]));
|
||
|
||
INFO_LOG(m_logger) << LOGFUNCTION
|
||
<< " QList<QPointF> -> "
|
||
<< timer.elapsed() << "ms";
|
||
}
|
||
else
|
||
{
|
||
QElapsedTimer timer;
|
||
if (m_logger.isInfoEnabled())
|
||
timer.start();
|
||
|
||
|
||
qContV.clear();
|
||
qContV.reserve(refSize);
|
||
for (const shm_punkt_rt &item : refPoints)
|
||
qContV.append(QPointF(item.p[0], item.p[1]));
|
||
|
||
INFO_LOG(m_logger) << LOGFUNCTION
|
||
<< " QVector<QPointF> -> "
|
||
<< timer.elapsed() << "ms";
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
void SitMapUnitTest::checkQWeakPointer()
|
||
{
|
||
QWeakPointer<SituationMap::TextStyle> ts_weak; // TextStyle does NOT inherent from QObject
|
||
QVERIFY2((ts_weak.isNull() == true), "isNull: failed");
|
||
{
|
||
QSharedPointer<SituationMap::TextStyle> ts_shared(new SituationMap::TextStyle());
|
||
ts_weak = ts_shared; // 'connected' weak and shared
|
||
|
||
QVERIFY2((ts_weak.isNull() == false), "isNull: failed");
|
||
} // shared will delete object
|
||
QVERIFY2((ts_weak.isNull() == true), "isNull: failed"); // weak 'knows' the deletion :-)
|
||
|
||
// // you should continue like this:
|
||
// QSharedPointer<SituationMap::TextStyle> ts_shared2 = ts_weak.toStrongRef();
|
||
// if (ts_shared2)
|
||
// {
|
||
// ts_shared2->doSomething();
|
||
// } else {
|
||
// // error, object down not exists anymore
|
||
// }
|
||
}
|
||
|
||
void SitMapUnitTest::checkFactoryCreationContraints()
|
||
{
|
||
// Links: http://stackoverflow.com/questions/124880/is-it-possible-to-prevent-stack-allocation-of-an-object-and-only-allow-it-to-be
|
||
// Links: https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Requiring_or_Prohibiting_Heap-based_Objects
|
||
|
||
|
||
//
|
||
// Foo
|
||
//
|
||
|
||
// creation on stack:
|
||
// Foo f; // will not compile, ctor is private
|
||
|
||
// creation on heap:
|
||
// Foo *f_ptr1 = new Foo(); // will not compile, ctor is private
|
||
|
||
Foo *f_ptr2 = Foo::createFoo();
|
||
delete f_ptr2;
|
||
|
||
|
||
//
|
||
// subClass
|
||
//
|
||
|
||
// creation on stack:
|
||
// subClass sC; // will not compile, ctor is private
|
||
|
||
// creation on heap:
|
||
// subClass *sC_ptr1 = new subClass(); // will not compile, ctor is private
|
||
|
||
subClass *sC_ptr2 = subClass::create();
|
||
delete sC_ptr2;
|
||
|
||
}
|
||
|
||
|
||
//-------------------------------------------------------------------------------------------------------
|
||
|
||
/*
|
||
void SitMapUnitTest::checkIdHandlerCreate()
|
||
{
|
||
quint32 usedIdCount = m_d->m_uniqueIdHandler->countUsedIds();
|
||
QVERIFY2( (usedIdCount == 0), "Check IdHandler initial value failed, wrong id count" );
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||
<< " used id count before test = "
|
||
<< usedIdCount
|
||
;
|
||
|
||
// create one object
|
||
|
||
SituationMap::IdHandler::AccessableId * myPtr = new SituationMap::IdHandler::AccessableId();
|
||
SituationMap::IdHandler::UniqueMapId myId = m_d->m_uniqueIdHandler->createId( myPtr );
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||
<< " created id = "
|
||
<< myId
|
||
<< " obj address = "
|
||
<< myPtr
|
||
;
|
||
|
||
// check count of ids, myId and accessId function
|
||
QVERIFY2( ((usedIdCount+1) == m_d->m_uniqueIdHandler->countUsedIds()), "Check IdHandler create failed, wrong id count" );
|
||
QVERIFY2( SituationMap::IdHandler::isIdValid(myId) , "Check IdHandler create failed, bad id" );
|
||
QVERIFY2( (m_d->m_uniqueIdHandler->accessId(myId) == myPtr) , "Check IdHandler create failed, pointer mismatch" );
|
||
|
||
// check invalid access
|
||
myPtr = m_d->m_uniqueIdHandler->accessId( SituationMap::IdHandler::UniqueMapId(-2) );
|
||
|
||
QVERIFY2( (myPtr == nullptr) , "Check IdHandler create failed, invalid access doesn_t return nullptr" );
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::checkIdHandlerFree()
|
||
{
|
||
quint32 usedIdCount = m_d->m_uniqueIdHandler->countUsedIds();
|
||
SituationMap::IdHandler::AccessableId * myPtr = new SituationMap::IdHandler::AccessableId();
|
||
SituationMap::IdHandler::UniqueMapId myId = m_d->m_uniqueIdHandler->createId( myPtr );
|
||
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||
<< " created id ="
|
||
<< myId
|
||
<< " obj address ="
|
||
<< myPtr
|
||
;
|
||
|
||
bool ok = m_d->m_uniqueIdHandler->freeId( myId );
|
||
|
||
QVERIFY2( ok, "Check IdHandler freeId failed, return value of freeId is false." );
|
||
QVERIFY2( (usedIdCount == m_d->m_uniqueIdHandler->countUsedIds()), "Check IdHandler freeId failed, wrong id count." );
|
||
QVERIFY2( (m_d->m_uniqueIdHandler->accessId(myId) == nullptr) , "Check IdHandler freeId failed, id is still in use." );
|
||
|
||
ok = m_d->m_uniqueIdHandler->freeId( SituationMap::IdHandler::BadId );
|
||
QVERIFY2(ok == false, "Check IdHandler freeId failed, return value of freeId(BadId) is not false." );
|
||
|
||
ok = m_d->m_uniqueIdHandler->freeId( SituationMap::IdHandler::UniqueMapId(-2) );
|
||
QVERIFY2(ok == false, "Check IdHandler freeId failed, return value of freeId(<not used id>) is not false." );
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::checkIdHandlerReUseId()
|
||
{
|
||
quint32 usedIdCount = m_d->m_uniqueIdHandler->countUsedIds();
|
||
|
||
QList<SituationMap::IdHandler::UniqueMapId> idList;
|
||
|
||
for (unsigned int idx = usedIdCount; idx < m_initReserve; ++idx)
|
||
{
|
||
idList += m_d->m_uniqueIdHandler->createId( new SituationMap::IdHandler::AccessableId() );
|
||
}
|
||
|
||
bool ok = m_d->m_uniqueIdHandler->freeId( idList.first() );
|
||
|
||
QVERIFY2( ok, "Check IdHandler reUseId failed, return value of freeId is false." );
|
||
|
||
if (ok)
|
||
{
|
||
SituationMap::IdHandler::UniqueMapId id = m_d->m_uniqueIdHandler->createId( new SituationMap::IdHandler::AccessableId() );
|
||
QVERIFY2(id == idList.first(), "Check IdHandler reUseId failed, freed id has not been used again." );
|
||
}
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::checkIdHandlerReserveId()
|
||
{
|
||
quint32 usedIdCount = m_d->m_uniqueIdHandler->countUsedIds();
|
||
|
||
SituationMap::IdHandler::UniqueMapId reserveId = usedIdCount + 7;
|
||
|
||
// look for a unused id
|
||
while (m_d->m_uniqueIdHandler->isIdInUse(reserveId))
|
||
{
|
||
reserveId++;
|
||
}
|
||
|
||
// first reserve should return true
|
||
bool ok = m_d->m_uniqueIdHandler->reserveId( reserveId, new SituationMap::IdHandler::AccessableId() );
|
||
|
||
QVERIFY2( ok, "Check IdHandler reserveId failed, reserveId returns false." );
|
||
|
||
if (ok)
|
||
{
|
||
// second reserve should return false
|
||
ok = m_d->m_uniqueIdHandler->reserveId( reserveId, new SituationMap::IdHandler::AccessableId() );
|
||
QVERIFY2( !ok, "Check IdHandler reserveId failed, second reserveId doesn't return false." );
|
||
|
||
for (int idx = reserveId - usedIdCount + 20; idx >= 0; --idx)
|
||
{
|
||
SituationMap::IdHandler::UniqueMapId myId = m_d->m_uniqueIdHandler->createId( new SituationMap::IdHandler::AccessableId() );
|
||
QVERIFY2( myId != reserveId, "Check IdHandler reserveId failed, createId returns reserved id." );
|
||
}
|
||
|
||
}
|
||
}
|
||
*/
|
||
|
||
void SitMapUnitTest::checkSimpleValue()
|
||
{
|
||
const int intVal = 42;
|
||
const int intValModified = 123;
|
||
|
||
// assign
|
||
SituationMap::SimpleValue<int> wrappedValue = intVal;
|
||
QVERIFY2((wrappedValue.changed() == true), "SimpleValue: failed");
|
||
QVERIFY2((wrappedValue.value() == 42), "SimpleValue: failed");
|
||
|
||
// reset
|
||
wrappedValue.reset();
|
||
QVERIFY2((wrappedValue.changed() == false), "SimpleValue: failed");
|
||
QVERIFY2((wrappedValue.value() == 42), "SimpleValue: failed");
|
||
|
||
// access:
|
||
bool ok = false;
|
||
ok = (wrappedValue.value() == intVal);
|
||
QVERIFY2((ok), "SimpleValue: failed");
|
||
QVERIFY2((wrappedValue.changed() == false), "SimpleValue: failed");
|
||
|
||
ok = (wrappedValue.refValue() == intVal);
|
||
QVERIFY2((ok), "SimpleValue: failed");
|
||
QVERIFY2((wrappedValue.changed() == true), "SimpleValue: failed");
|
||
|
||
ok = (wrappedValue() == intVal);
|
||
QVERIFY2((ok), "SimpleValue: failed");
|
||
QVERIFY2((wrappedValue.changed() == true), "SimpleValue: failed");
|
||
|
||
// assign
|
||
SituationMap::SimpleValue<int> wrappedValue2 = wrappedValue;
|
||
QVERIFY2((wrappedValue2.changed() == true), "SimpleValue: failed");
|
||
|
||
wrappedValue.reset();
|
||
wrappedValue = intValModified;
|
||
QVERIFY2((wrappedValue.changed() == true), "SimpleValue: failed");
|
||
QVERIFY2((wrappedValue.value() == intValModified), "SimpleValue: failed");
|
||
|
||
// refValue
|
||
wrappedValue.reset();
|
||
wrappedValue.refValue() = intVal;
|
||
QVERIFY2((wrappedValue.changed() == true), "SimpleValue: failed");
|
||
QVERIFY2((wrappedValue.value() == intVal), "SimpleValue: failed");
|
||
|
||
// setChanged
|
||
wrappedValue.reset();
|
||
QVERIFY2((wrappedValue.changed() == false), "SimpleValue: failed");
|
||
wrappedValue.setChanged();
|
||
QVERIFY2((wrappedValue.changed() == true), "SimpleValue: failed");
|
||
|
||
|
||
// ok = wrappedValue == wrappedValue2; // not supported
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::checkIdGenerator()
|
||
{
|
||
QSharedPointer<SituationMap::IdGenerator> idGenerator(new SituationMap::IdGenerator());
|
||
QVERIFY2((idGenerator.isNull() == false), "Check IdGenerator does not exits");
|
||
|
||
SituationMap::UniqueMapId id = idGenerator->getNextId();
|
||
|
||
QVERIFY2((id == 0), "Check IdGenerator initial value failed, wrong id");
|
||
QVERIFY2((SituationMap::IdGenerator::idIsValid(id)), "Check IdGenerator id invalid");
|
||
QVERIFY2((SituationMap::isUniqueMapIdValid(id)), "Check IdGenerator id invalid");
|
||
|
||
id = idGenerator->getNextId();
|
||
QVERIFY2((id == 1), "Check IdGenerator initial value failed, wrong id");
|
||
QVERIFY2((SituationMap::IdGenerator::idIsValid(id)), "Check IdGenerator id invalid");
|
||
QVERIFY2((SituationMap::isUniqueMapIdValid(id)), "Check IdGenerator id invalid");
|
||
|
||
id = idGenerator->getNextId();
|
||
QVERIFY2((id == 2), "Check IdGenerator initial value failed, wrong id");
|
||
QVERIFY2((SituationMap::IdGenerator::idIsValid(id)), "Check IdGenerator id invalid");
|
||
QVERIFY2((SituationMap::isUniqueMapIdValid(id)), "Check IdGenerator id invalid");
|
||
|
||
id = SituationMap::IdGenerator::INVALID_ID;
|
||
QVERIFY2((SituationMap::IdGenerator::idIsValid(id) == false), "Check INVALID_ID is NOT invalid");
|
||
QVERIFY2((SituationMap::isUniqueMapIdValid(id) == false), "Check INVALID_ID is NOT invalid");
|
||
}
|
||
|
||
//class MyBuildingOutlineImpl : public SituationMap::BuildingOutlineImpl
|
||
//{
|
||
//public:
|
||
// MyBuildingOutlineImpl(const QString &debugInfo = QString())
|
||
// : SituationMap::BuildingOutlineImpl(debugInfo)
|
||
// {}
|
||
//};
|
||
|
||
|
||
// create template to derive from XY-MapObjectImpl to overcome protected ctor:
|
||
template <typename T>
|
||
class MyMapObjectType : public T
|
||
{
|
||
public:
|
||
MyMapObjectType(const QString &debugInfo = QString())
|
||
: T(debugInfo)
|
||
{}
|
||
};
|
||
|
||
using MyParticipantImpl = MyMapObjectType<SituationMap::ParticipantImpl>;
|
||
using MyBiologicalAgentImpl = MyMapObjectType<SituationMap::BiologicalAgentImpl>;
|
||
using MyBuildingOutlineImpl = MyMapObjectType<SituationMap::BuildingOutlineImpl>;
|
||
|
||
|
||
void SitMapUnitTest::checkIdContainer()
|
||
{
|
||
QVERIFY2((IdGeneratorCounting::getCounter() == 0), "Check IdGeneratorCounting, count failed");
|
||
|
||
|
||
// SituationMap::BuildingOutlineImpl bbbbbbbbb( QLatin1String("bio2") );
|
||
|
||
|
||
{
|
||
//
|
||
// ONE IdGenerator connected to TWO ObjectContainer:
|
||
//
|
||
|
||
QSharedPointer<SituationMap::IdGenerator> idGenerator(new IdGeneratorCounting());
|
||
QVERIFY2((idGenerator.isNull() == false), "Check IdGenerator does not exits");
|
||
QVERIFY2((IdGeneratorCounting::getCounter() == 1), "Check IdGeneratorCounting, count failed");
|
||
|
||
{
|
||
//
|
||
// FIRST ObjectContainer:
|
||
//
|
||
SituationMap::ObjectContainer *container1 =
|
||
new SituationMap::ObjectContainerCTC(idGenerator);
|
||
QVERIFY2((container1), "Check ObjectContainerCTC does not exits");
|
||
|
||
qlonglong count = container1->countObjects();
|
||
QVERIFY2((count == 0), "Check ObjectContainer countObjects failed");
|
||
|
||
// create some dummyObjects:
|
||
SituationMap::RefPointer<SituationMap::Participant> part1(new MyParticipantImpl(QLatin1String("part1")));
|
||
QVERIFY2(part1.valid() == true , "create part failed");
|
||
|
||
SituationMap::RefPointer<SituationMap::BiologicalAgent> bio1(new MyBiologicalAgentImpl(QLatin1String("bio1")));
|
||
QVERIFY2(bio1.valid() == true , "create failed");
|
||
SituationMap::RefPointer<SituationMap::BiologicalAgent> bio2(new MyBiologicalAgentImpl(QLatin1String("bio2")));
|
||
QVERIFY2(bio2.valid() == true , "create failed");
|
||
|
||
SituationMap::RefPointer<SituationMap::BuildingOutline> build1(new MyBuildingOutlineImpl(QLatin1String("build1")));
|
||
QVERIFY2(build1.valid() == true , "create failed");
|
||
SituationMap::RefPointer<SituationMap::BuildingOutline> build2(new MyBuildingOutlineImpl(QLatin1String("build2")));
|
||
QVERIFY2(build2.valid() == true , "create failed");
|
||
SituationMap::RefPointer<SituationMap::BuildingOutline> build3(new MyBuildingOutlineImpl(QLatin1String("build3")));
|
||
QVERIFY2(build3.valid() == true , "create failed");
|
||
|
||
|
||
SituationMap::UniqueMapId id = SituationMap::IdGenerator::INVALID_ID;
|
||
uint i = 0;
|
||
// add to our idContainer1:
|
||
id = container1->insertObject(part1.get());
|
||
QVERIFY2((id == i++), "Check IdContainer wrong id");
|
||
id = container1->insertObject(bio1.get());
|
||
QVERIFY2((id == i++), "Check IdContainer wrong id");
|
||
id = container1->insertObject(bio2.get());
|
||
QVERIFY2((id == i++), "Check IdContainer wrong id");
|
||
id = container1->insertObject(build1.get());
|
||
QVERIFY2((id == i++), "Check IdContainer wrong id");
|
||
id = container1->insertObject(build2.get());
|
||
QVERIFY2((id == i++), "Check IdContainer wrong id");
|
||
id = container1->insertObject(build3.get());
|
||
QVERIFY2((id == i++), "Check IdContainer wrong id");
|
||
|
||
// std::cerr << " id=" << id << std::endl;
|
||
|
||
// check countObjects
|
||
count = container1->countObjects();
|
||
QVERIFY2((count == 6), "Check IdContainer countObjects failed");
|
||
|
||
// cleanup
|
||
delete container1;
|
||
}
|
||
|
||
//
|
||
// Instantiate SECOND IdContainer with SAME IdGenerator:
|
||
//
|
||
SituationMap::ObjectContainer *container2 = new SituationMap::ObjectContainerCTC(idGenerator);
|
||
|
||
// idGenerator is reused, IdGeneratorCounting::getCounter() must stay at '1':
|
||
QVERIFY2((IdGeneratorCounting::getCounter() == 1), "Check IdGeneratorCounting, count failed");
|
||
|
||
qint32 count = container2->countObjects();
|
||
QVERIFY2((count == 0), "Check IdContainer countObjects failed");
|
||
|
||
// create some dummyObjects:
|
||
SituationMap::RefPointer<SituationMap::Participant> part1(new MyParticipantImpl(QLatin1String("part1")));
|
||
QVERIFY2(part1.valid() == true , "create part failed");
|
||
|
||
SituationMap::RefPointer<SituationMap::BiologicalAgent> bio1(new MyBiologicalAgentImpl(QLatin1String("bio1")));
|
||
QVERIFY2(bio1.valid() == true , "create failed");
|
||
SituationMap::RefPointer<SituationMap::BiologicalAgent> bio2(new MyBiologicalAgentImpl(QLatin1String("bio2")));
|
||
QVERIFY2(bio2.valid() == true , "create failed");
|
||
|
||
SituationMap::UniqueMapId id = SituationMap::IdGenerator::INVALID_ID;
|
||
// add to our idContainer2:
|
||
|
||
// idGenerator is reused and therefore the uniqueId will continue -> start with '6'
|
||
uint i = 6;
|
||
id = container2->insertObject(part1.get());
|
||
QVERIFY2((id == i++), "Check IdContainer wrong id");
|
||
id = container2->insertObject(bio1.get());
|
||
QVERIFY2((id == i++), "Check IdContainer wrong id");
|
||
id = container2->insertObject(bio2.get());
|
||
QVERIFY2((id == i++), "Check IdContainer wrong id");
|
||
count = container2->countObjects();
|
||
QVERIFY2((count == 3), "Check IdContainer countObjects failed");
|
||
|
||
// check access methods:
|
||
QList<SituationMap::UniqueMapId> keyList = container2->getAllKeys();
|
||
QVERIFY2((keyList.count() == 3), "Check IdContainer getAllKeys failed");
|
||
|
||
QList<SituationMap::ObjectContainer::Object *> objList = container2->getAllObjects();
|
||
QVERIFY2((objList.count() == 3), "Check IdContainer getAllObjects failed");
|
||
|
||
// SitMapUnitTest: look for BiologicalAgentIMPL
|
||
// ^^^^^^^^ ^^^^
|
||
// std::type_index bioTypeIndex(typeid(SituationMap::BiologicalAgentImpl));
|
||
std::type_index bioTypeIndex(typeid(MyBiologicalAgentImpl)); // use 'MyBiologicalAgentImpl' instead of 'SituationMap::BiologicalAgentImpl' - see insertion
|
||
objList = container2->getAllObjects(bioTypeIndex);
|
||
QVERIFY2((objList.count() == 2), "Check IdContainer getAllObjects(bioTypeIndex) failed");
|
||
|
||
|
||
SituationMap::ObjectContainer::Object *access = container2->getObject(-2) ;
|
||
QVERIFY2((!access), "Check IdContainer getObject failed");
|
||
|
||
access = container2->getObject(7) ;
|
||
QVERIFY2((access), "Check IdContainer getObject failed");
|
||
|
||
|
||
|
||
// remove
|
||
bool success = container2->removeObject(7);
|
||
QVERIFY2((success), "Check IdContainer remove failed");
|
||
count = container2->countObjects();
|
||
QVERIFY2((count == 2), "Check IdContainer countObjects failed");
|
||
|
||
// clear:
|
||
container2->clear();
|
||
count = container2->countObjects();
|
||
QVERIFY2((count == 0), "Check IdContainer countObjects failed");
|
||
|
||
|
||
// cleanup;
|
||
delete container2;
|
||
}
|
||
|
||
QVERIFY2((IdGeneratorCounting::getCounter() == 0), "Check IdGeneratorCounting, count failed");
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::checkIsSignalConnected()
|
||
{
|
||
{
|
||
CheckSignal cs;
|
||
connect(&cs, &CheckSignal::mySignal, this, &SitMapUnitTest::onCheckIsSignalConnected);
|
||
quint64 msec = 0;
|
||
bool isConnected = cs.isConnected(msec);
|
||
INFO_LOG(m_logger) << LOGFUNCTION << " isSignalConnected took " << msec << "[msec]";
|
||
QVERIFY2(isConnected, "isSignalConnected failed (real slot)");
|
||
}
|
||
|
||
{
|
||
CheckSignal cs;
|
||
connect(&cs, &CheckSignal::mySignal, this, [ = ]()
|
||
{
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " mySignal recognized (lambda slot)";
|
||
});
|
||
quint64 msec = 0;
|
||
bool isConnected = cs.isConnected(msec);
|
||
INFO_LOG(m_logger) << LOGFUNCTION << " isSignalConnected took " << msec << "[msec]";
|
||
QVERIFY2(isConnected, "isSignalConnected failed (lambda slot)");
|
||
}
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::onCheckIsSignalConnected()
|
||
{
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " mySignal recognized (real slot)";
|
||
}
|
||
|
||
|
||
void SitMapUnitTest::checkMapLayer()
|
||
{
|
||
SituationMap::MapLayer first;
|
||
QVERIFY2(first.isValid() == false, "MapLayer1 isValid failed");
|
||
|
||
SituationMap::MapLayer second(QLatin1String("LayerName"),
|
||
SituationMap::LayerType::Basemap);
|
||
QVERIFY2(second.isValid() == true, "MapLayer2 isValid failed");
|
||
}
|
||
|
||
void SitMapUnitTest::checkMapLayerOrderedList()
|
||
{
|
||
SituationMap::MapLayerOrderedList mlol;
|
||
QVERIFY2(mlol.count() == 0, "MapLayerOrderedList count failed");
|
||
|
||
bool success = false;
|
||
|
||
// add, check LayerType::Undefined
|
||
success = mlol.addLayer(QLatin1String("Basemap1"), SituationMap::LayerType::Undefined);
|
||
QVERIFY2(success == false, "MapLayerOrderedList: addLayer LayerType::Undefined failed");
|
||
QVERIFY2(mlol.count() == 0, "MapLayerOrderedList count failed");
|
||
|
||
// add, check emptyName
|
||
success = mlol.addLayer(QString(), SituationMap::LayerType::Basemap);
|
||
QVERIFY2(success == false, "MapLayerOrderedList: addLayer LayerType::Undefined failed");
|
||
QVERIFY2(mlol.count() == 0, "MapLayerOrderedList count failed");
|
||
|
||
// add, check emptyName
|
||
success = mlol.addLayer(QString(), SituationMap::LayerType::Operational);
|
||
QVERIFY2(success == false, "MapLayerOrderedList: addLayer LayerType::Undefined failed");
|
||
QVERIFY2(mlol.count() == 0, "MapLayerOrderedList count failed");
|
||
|
||
|
||
|
||
//
|
||
// add first
|
||
//
|
||
success = mlol.addLayer(QLatin1String("Basemap1"), SituationMap::LayerType::Basemap);
|
||
QVERIFY2(success, "MapLayerOrderedList: addLayer failed");
|
||
QVERIFY2(mlol.count() == 1, "MapLayerOrderedList count failed");
|
||
|
||
// add again:
|
||
success = mlol.addLayer(QLatin1String("Basemap1"), SituationMap::LayerType::Basemap);
|
||
QVERIFY2(success == false, "MapLayerOrderedList: addLayer failed");
|
||
QVERIFY2(mlol.count() == 1, "MapLayerOrderedList count failed");
|
||
|
||
// add again:
|
||
success = mlol.addLayer(QLatin1String("Basemap2"), SituationMap::LayerType::Basemap);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: addLayer failed");
|
||
QVERIFY2(mlol.count() == 2, "MapLayerOrderedList count failed");
|
||
|
||
// add again (same name, different LayerType is not allowed)
|
||
success = mlol.addLayer(QLatin1String("Basemap2"), SituationMap::LayerType::Operational);
|
||
QVERIFY2(success == false, "MapLayerOrderedList: addLayer failed");
|
||
QVERIFY2(mlol.count() == 2, "MapLayerOrderedList count failed");
|
||
|
||
// add again:
|
||
success = mlol.addLayer(QLatin1String("ObjectLayer3"), SituationMap::LayerType::Operational);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: addLayer failed");
|
||
QVERIFY2(mlol.count() == 3, "MapLayerOrderedList count failed");
|
||
|
||
// add again:
|
||
success = mlol.addLayer(QLatin1String("EmergencyCall"), SituationMap::LayerType::EmergencyCall);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: addLayer failed");
|
||
QVERIFY2(mlol.count() == 4, "MapLayerOrderedList count failed");
|
||
|
||
//
|
||
// contains
|
||
//
|
||
success = mlol.contains(QLatin1String("Basemap1"), SituationMap::LayerType::Undefined);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: contains failed");
|
||
success = mlol.contains(QLatin1String("Basemap1"), SituationMap::LayerType::Basemap);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: contains failed");
|
||
success = mlol.contains(QLatin1String("Basemap1"), SituationMap::LayerType::Operational);
|
||
QVERIFY2(success == false, "MapLayerOrderedList: contains failed");
|
||
|
||
success = mlol.contains(QLatin1String("ObjectLayer3"), SituationMap::LayerType::Undefined);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: contains failed");
|
||
success = mlol.contains(QLatin1String("ObjectLayer3"), SituationMap::LayerType::Basemap);
|
||
QVERIFY2(success == false, "MapLayerOrderedList: contains failed");
|
||
success = mlol.contains(QLatin1String("ObjectLayer3"), SituationMap::LayerType::Operational);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: contains failed");
|
||
|
||
success = mlol.contains(QLatin1String("EmergencyCall"), SituationMap::LayerType::EmergencyCall);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: contains failed");
|
||
|
||
//
|
||
// getLayer
|
||
//
|
||
SituationMap::MapLayer mapLayer;
|
||
mapLayer = mlol.getLayer(QLatin1String("Basemap1"));
|
||
QVERIFY2(mapLayer.isValid() == true , "MapLayerOrderedList: getLayer failed");
|
||
QVERIFY2(mapLayer.type() == SituationMap::LayerType::Basemap , "MapLayerOrderedList: getLayer failed");
|
||
QVERIFY2(mapLayer.name().compare(QLatin1String("Basemap1")) == 0 , "MapLayerOrderedList: getLayer failed");
|
||
|
||
mapLayer = mlol.getLayer(QLatin1String("Basemap2"));
|
||
QVERIFY2(mapLayer.isValid() == true , "MapLayerOrderedList: getLayer failed");
|
||
QVERIFY2(mapLayer.type() == SituationMap::LayerType::Basemap , "MapLayerOrderedList: getLayer failed");
|
||
QVERIFY2(mapLayer.name().compare(QLatin1String("Basemap2")) == 0 , "MapLayerOrderedList: getLayer failed");
|
||
|
||
mapLayer = mlol.getLayer(QLatin1String("ObjectLayer3"));
|
||
QVERIFY2(mapLayer.isValid() == true , "MapLayerOrderedList: getLayer failed");
|
||
QVERIFY2(mapLayer.type() == SituationMap::LayerType::Operational , "MapLayerOrderedList: getLayer failed");
|
||
QVERIFY2(mapLayer.name().compare(QLatin1String("ObjectLayer3")) == 0 , "MapLayerOrderedList: getLayer failed");
|
||
|
||
mapLayer = mlol.getLayer(QLatin1String("EmergencyCall"));
|
||
QVERIFY2(mapLayer.isValid() == true , "MapLayerOrderedList: getLayer failed");
|
||
QVERIFY2(mapLayer.type() == SituationMap::LayerType::EmergencyCall , "MapLayerOrderedList: getLayer failed");
|
||
QVERIFY2(mapLayer.name().compare(QLatin1String("EmergencyCall")) == 0 , "MapLayerOrderedList: getLayer failed");
|
||
|
||
//
|
||
// layerNamesOrdered
|
||
//
|
||
QStringList slBase; slBase << QLatin1String("Basemap1") << QLatin1String("Basemap2");
|
||
QStringList slObj; slObj << QLatin1String("ObjectLayer3");
|
||
QStringList slEmer; slEmer << QLatin1String("EmergencyCall");
|
||
|
||
QStringList sl;
|
||
sl = mlol.layerNamesOrdered(SituationMap::LayerType::Basemap);
|
||
QVERIFY2(sl == slBase , "MapLayerOrderedList: layerNamesOrdered failed");
|
||
sl = mlol.layerNamesOrdered(SituationMap::LayerType::Operational);
|
||
QVERIFY2(sl == slObj , "MapLayerOrderedList: layerNamesOrdered failed");
|
||
sl = mlol.layerNamesOrdered(SituationMap::LayerType::EmergencyCall);
|
||
QVERIFY2(sl == slEmer, "MapLayerOrderedList: layerNamesOrdered failed");
|
||
sl = mlol.layerNamesOrdered();
|
||
QVERIFY2(sl == slBase + slObj + slEmer , "MapLayerOrderedList: layerNamesOrdered failed");
|
||
|
||
qDebug() << "layer11=" << mlol.layerNamesOrdered();
|
||
|
||
//
|
||
// addBasemap
|
||
//
|
||
success = mlol.addLayer(QLatin1String("newBasemapLayer"), SituationMap::LayerType::Basemap);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: addLayer failed");
|
||
QVERIFY2(mlol.count() == 5, "MapLayerOrderedList count failed");
|
||
QStringList slOk = slBase;
|
||
slOk << QLatin1String("newBasemapLayer");
|
||
slOk << slObj << slEmer;
|
||
sl = mlol.layerNamesOrdered();
|
||
QVERIFY2(sl == slOk , "MapLayerOrderedList: layerNamesOrdered failed");
|
||
|
||
qDebug() << "layer22=" << mlol.layerNamesOrdered();
|
||
|
||
success = mlol.addLayer(QLatin1String("newObjectLayer"), SituationMap::LayerType::Operational);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: addLayer failed");
|
||
QVERIFY2(mlol.count() == 6, "MapLayerOrderedList count failed");
|
||
slOk << QLatin1String("newObjectLayer");
|
||
sl = mlol.layerNamesOrdered();
|
||
QVERIFY2(sl == slOk , "MapLayerOrderedList: layerNamesOrdered failed");
|
||
|
||
|
||
success = mlol.addLayer(QLatin1String("newBasemapLayer2"), SituationMap::LayerType::Basemap);
|
||
|
||
qDebug() << "layer33=" << mlol.layerNamesOrdered();
|
||
|
||
QVERIFY2(success == true, "MapLayerOrderedList: addLayer failed");
|
||
QVERIFY2(mlol.count() == 7, "MapLayerOrderedList count failed");
|
||
slOk.insert(3, QLatin1String("newBasemapLayer2"));
|
||
sl = mlol.layerNamesOrdered();
|
||
QVERIFY2(sl == slOk , "MapLayerOrderedList: layerNamesOrdered failed");
|
||
|
||
QVERIFY2(mlol.layerNamesOrdered(SituationMap::LayerType::Basemap).size() == 4 , "MapLayerOrderedList: layerNamesOrdered failed");
|
||
QVERIFY2(mlol.layerNamesOrdered(SituationMap::LayerType::Operational).size() == 2 , "MapLayerOrderedList: layerNamesOrdered failed");
|
||
|
||
qDebug() << "layer44=" << mlol.layerNamesOrdered();
|
||
|
||
//
|
||
// orderTo
|
||
//
|
||
QStringList newOrder;
|
||
newOrder << QLatin1String("Basemap1")
|
||
<< QLatin1String("newObjectLayer")
|
||
<< QLatin1String("newBasemapLayer2")
|
||
<< QLatin1String("ObjectLayer3")
|
||
<< QLatin1String("newBasemapLayer")
|
||
<< QLatin1String("EmergencyCall") // <-- must be moved on top
|
||
<< QLatin1String("Basemap2")
|
||
;
|
||
|
||
success = mlol.orderLayerTo(newOrder);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: orderLayerTo failed");
|
||
|
||
slOk.clear();
|
||
slOk << QLatin1String("Basemap1")
|
||
<< QLatin1String("newBasemapLayer2")
|
||
<< QLatin1String("newBasemapLayer")
|
||
<< QLatin1String("Basemap2")
|
||
<< QLatin1String("newObjectLayer")
|
||
<< QLatin1String("ObjectLayer3")
|
||
<< QLatin1String("EmergencyCall")
|
||
;
|
||
sl = mlol.layerNamesOrdered();
|
||
QVERIFY2(sl == slOk , "MapLayerOrderedList: orderLayerTo failed");
|
||
|
||
qDebug() << "layer55=" << mlol.layerNamesOrdered();
|
||
|
||
//
|
||
// orderTo with missing 'EmergencyCall'
|
||
//
|
||
{
|
||
QStringList newOrder;
|
||
newOrder << QLatin1String("Basemap1")
|
||
<< QLatin1String("newObjectLayer")
|
||
<< QLatin1String("newBasemapLayer2")
|
||
<< QLatin1String("ObjectLayer3")
|
||
<< QLatin1String("newBasemapLayer")
|
||
// << QLatin1String("EmergencyCall") // <-- must be moved on top, even if not provided!
|
||
<< QLatin1String("Basemap2")
|
||
;
|
||
|
||
success = mlol.orderLayerTo(newOrder);
|
||
QVERIFY2(success == true, "MapLayerOrderedList: orderLayerTo failed");
|
||
|
||
slOk.clear();
|
||
slOk << QLatin1String("Basemap1")
|
||
<< QLatin1String("newBasemapLayer2")
|
||
<< QLatin1String("newBasemapLayer")
|
||
<< QLatin1String("Basemap2")
|
||
<< QLatin1String("newObjectLayer")
|
||
<< QLatin1String("ObjectLayer3")
|
||
<< QLatin1String("EmergencyCall")
|
||
;
|
||
sl = mlol.layerNamesOrdered();
|
||
QVERIFY2(sl == slOk , "MapLayerOrderedList: orderLayerTo failed");
|
||
}
|
||
|
||
qDebug() << "layer66=" << mlol.layerNamesOrdered();
|
||
|
||
|
||
|
||
|
||
// take EmergencyCall into account:
|
||
}
|
||
|
||
void SitMapUnitTest::checkLayerFactory()
|
||
{
|
||
// Preperations:
|
||
bool success = false;
|
||
SituationMap::MapImpl mapImplDummy;
|
||
QVERIFY2(mapImplDummy.technicalLayerCount() == 0 , "layerFactory: technicalLayerCount failed");
|
||
|
||
SituationMap::LayerFactory &layerFac = mapImplDummy.layerFactory();
|
||
|
||
// real test
|
||
QVERIFY2(layerFac.layernames().count() == 0 , "layerFactory: creation failed");
|
||
QVERIFY2(layerFac.count() == 0 , "layerFactory: creation failed");
|
||
|
||
SituationMap::LayerParameter lp;
|
||
success = layerFac.setLayerParameter(QLatin1String("test"), lp);
|
||
QVERIFY2(success == false , "layerFactory: setLayerParameter failed");
|
||
|
||
// #layer == 0
|
||
QVERIFY2(layerFac.layernames().count() == 0 , "layerFactory: count failed");
|
||
QVERIFY2(layerFac.count() == 0 , "layerFactory: count failed");
|
||
QVERIFY2(mapImplDummy.technicalLayerCount() == 0 , "layerFactory: technicalLayerCount failed");
|
||
|
||
QVERIFY2(layerFac.layernames(SituationMap::LayerType::Basemap) .count() == 0 , "layerFactory: layernames failed");
|
||
QVERIFY2(layerFac.layernames(SituationMap::LayerType::Operational).count() == 0 , "layerFactory: layernames failed");
|
||
QVERIFY2(layerFac.layernames(SituationMap::LayerType::Rubberband) .count() == 0 , "layerFactory: layernames failed");
|
||
|
||
}
|
||
|
||
class MyMapImpl : public SituationMap::MapImpl
|
||
{
|
||
Q_OBJECT // -> include "unit_test.moc" explicit
|
||
public:
|
||
bool isReady() const override
|
||
{
|
||
return true;
|
||
}
|
||
};
|
||
|
||
|
||
|
||
void SitMapUnitTest::checkObjectFactory()
|
||
{
|
||
// Preperations:
|
||
|
||
MyMapImpl mapImplDummy;
|
||
mapImplDummy.init(SituationMap::Mode::Mode_2D); // to create MpaGraphicsView and m_graphicsOverlayListModel
|
||
|
||
SituationMap::LayerFactory &layerFac = mapImplDummy.layerFactory();
|
||
QVERIFY2(layerFac.count() == 0 , "layerFactory: count failed");
|
||
|
||
layerFac.initializeUnitTestLayer();
|
||
|
||
|
||
SituationMap::ObjectFactory &objFac = mapImplDummy.objectFactory();
|
||
|
||
std::cerr << " count " << objFac.count() << std::endl;
|
||
|
||
QVERIFY2(objFac.count() <= 0 , "objectFactory: count failed"); // IdHandler -> 0 ; IDContainer -> -1
|
||
|
||
QVERIFY2(layerFac.count() == 3 , "layerFac: count failed");
|
||
|
||
// use an LOGICAL layer (not basemap)
|
||
QStringList layernames = layerFac.layernames();
|
||
QString layername = layernames[1];
|
||
|
||
// real test
|
||
// ObjectFactory::registerMe not called yet:
|
||
|
||
SituationMap::RefPointer<SituationMap::Participant> objPtr1;
|
||
objPtr1 = objFac.create<SituationMap::Participant>(layername, QLatin1String("UnitTestId1"));
|
||
QVERIFY2(objPtr1.valid() == false , "objectFactory: create1 failed");
|
||
|
||
SituationMap::RefPointer<SituationMap::BiologicalAgent> objPtr2;
|
||
objPtr2 = objFac.create<SituationMap::BiologicalAgent>(layername, QLatin1String("UnitTestId2"));
|
||
QVERIFY2(objPtr2.valid() == false , "objectFactory: create2 failed");
|
||
|
||
SituationMap::RefPointer<SituationMap::BuildingOutline> objPtr3;
|
||
objPtr3 = objFac.create<SituationMap::BuildingOutline>(layername, QLatin1String("UnitTestId3"));
|
||
QVERIFY2(objPtr3.valid() == false , "objectFactory: create3 failed");
|
||
|
||
SituationMap::RefPointer<SituationMap::DangerArea> objPtr4;
|
||
objPtr4 = objFac.create<SituationMap::DangerArea>(layername, QLatin1String("UnitTestId4"));
|
||
QVERIFY2(objPtr4.valid() == false , "objectFactory: create4 failed");
|
||
|
||
QVERIFY2(layerFac.count() == 3 , "layerFactory: count failed");
|
||
QVERIFY2(mapImplDummy.technicalLayerCount() == 1 , "layerFactory: technicalLayerCount failed");
|
||
|
||
// ObjectFactory::registerMe
|
||
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::Participant), new SituationMap::GenericObjectFactory<SituationMap::ParticipantImpl>());
|
||
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::BiologicalAgent), new SituationMap::GenericObjectFactory<SituationMap::BiologicalAgentImpl>());
|
||
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::BuildingOutline), new SituationMap::GenericObjectFactory<SituationMap::BuildingOutlineImpl>());
|
||
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::DangerArea), new SituationMap::GenericObjectFactory<SituationMap::DangerAreaImpl>());
|
||
|
||
|
||
QVERIFY2(objFac.count() == 0 , "objectFactory: count failed");
|
||
|
||
// now technicalLayerCount == 1 (basemap)
|
||
QVERIFY2(mapImplDummy.technicalLayerCount() == 1 , "layerFactory: technicalLayerCount failed");
|
||
|
||
objPtr1 = objFac.create<SituationMap::Participant>(layername, QLatin1String("UnitTestId1"));
|
||
QVERIFY2(objPtr1.valid() == true , "objectFactory: create11 failed");
|
||
|
||
objPtr2 = objFac.create<SituationMap::BiologicalAgent>(layername, QLatin1String("UnitTestId2"));
|
||
QVERIFY2(objPtr2.valid() == true , "objectFactory: create22 failed");
|
||
|
||
objPtr3 = objFac.create<SituationMap::BuildingOutline>(layername, QLatin1String("UnitTestId3"));
|
||
QVERIFY2(objPtr3.valid() == true , "objectFactory: create33 failed");
|
||
|
||
objPtr4 = objFac.create<SituationMap::DangerArea>(layername, QLatin1String("UnitTestId4"));
|
||
QVERIFY2(objPtr4.valid() == true , "objectFactory: create44 failed");
|
||
|
||
QVERIFY2(objFac.count() == 4 , "objectFactory: count failed");
|
||
|
||
// now technicalLayerCount == 1 (basemap, layername#...)
|
||
QVERIFY2(mapImplDummy.technicalLayerCount() == 2 , "layerFactory: technicalLayerCount failed");
|
||
|
||
|
||
// check rubberbandLayer:
|
||
// method 'rubberbandLayer' is not available at the interface:
|
||
SituationMap::LayerFactoryImpl *layerFacImpl =
|
||
dynamic_cast<SituationMap::LayerFactoryImpl *>(&layerFac);
|
||
QVERIFY2(layerFacImpl , "layerFac: dynamic_cast failed");
|
||
|
||
const QString &rbLayerName = layerFacImpl->rubberbandLayer();
|
||
QVERIFY2(rbLayerName.isEmpty() == false , "layerFac: rubberbandLayer failed");
|
||
|
||
objPtr2 = objFac.create<SituationMap::BiologicalAgent>(rbLayerName, QLatin1String("RbLayerTestId1"));
|
||
QVERIFY2(objPtr2.valid() == true , "objectFactory: create111 failed");
|
||
|
||
// now technicalLayerCount == 1 (basemap, layername#..., RubberbandLayer#...)
|
||
QVERIFY2(mapImplDummy.technicalLayerCount() == 3 , "layerFactory: technicalLayerCount failed");
|
||
|
||
|
||
const QString &toolLayerName = layerFacImpl->toolLayer();
|
||
QVERIFY2(toolLayerName.isEmpty() == false , "layerFac: toolLayer failed");
|
||
|
||
objPtr3 = objFac.create<SituationMap::BuildingOutline>(toolLayerName, QLatin1String("ToolLayerTestId1"));
|
||
QVERIFY2(objPtr3.valid() == true , "objectFactory: create222 failed");
|
||
|
||
if (objPtr1.valid())
|
||
{
|
||
// test re-use an uniqueId
|
||
SituationMap::UniqueMapId uid = objPtr1->uniqueMapId();
|
||
objPtr1->removeMySelf();
|
||
objPtr1 = objFac.create<SituationMap::Participant>(uid,layername, QLatin1String("UnitTestRecreate"));
|
||
QVERIFY2(objPtr1.valid() == true, "objectFactory: re-create failed");
|
||
QVERIFY2(uid == objPtr1->uniqueMapId(), "objectFactory: re-used removed uniqueId failed");
|
||
}
|
||
|
||
//further test require GUI -> another UnitTest
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::checkPickableOnInvalidUniqueMapId()
|
||
{
|
||
// Preperations:
|
||
|
||
SituationMap::MapImpl mapImplDummy;
|
||
|
||
SituationMap::LayerFactory &layerFac = mapImplDummy.layerFactory();
|
||
QVERIFY2(layerFac.count() == 0 , "LayerFactory: count failed");
|
||
|
||
|
||
// use an LOGICAL layer (not basemap)
|
||
QStringList layernames = layerFac.layernames();
|
||
|
||
|
||
// real test
|
||
|
||
SituationMap::LayerFactoryImpl *layerFacImpl =
|
||
dynamic_cast<SituationMap::LayerFactoryImpl *>(&layerFac);
|
||
QVERIFY2(layerFacImpl , "LayerFactory: layerFacImpl failed");
|
||
|
||
QSharedPointer<SituationMap::TacticalAppearance> tactApp
|
||
= QSharedPointer<SituationMap::TacticalAppearance> (
|
||
new SituationMap::TacticalAppearance(&mapImplDummy, QLatin1String("AES"), QLatin1String("debugIdUnitTest"))
|
||
);
|
||
QVERIFY2(tactApp.data() , "TacticalAppearance failed");
|
||
|
||
QVERIFY2(tactApp->uniqueMapId() == SituationMap::INVALID_MAP_ID , "uniqueMapId failed");
|
||
QVERIFY2(tactApp->pickable() == false , "pickable failed");
|
||
|
||
// must not succeed due to invalid uniqueMapId:
|
||
tactApp->setPickable(true); // must not succeed due to invalid uniqueMapId
|
||
|
||
QVERIFY2(tactApp->pickable() == false , "pickable failed");
|
||
|
||
|
||
}
|
||
|
||
|
||
void SitMapUnitTest::checkBoundingBox()
|
||
{
|
||
{
|
||
SituationMap::BoundingBox bbox(SituationMap::BoundingBox::ExtentType::Sim);
|
||
QVERIFY2(bbox.isValid() == false, "isValid failed");
|
||
}
|
||
{
|
||
SituationMap::BoundingBox bbox(SituationMap::BoundingBox::ExtentType::Pixel);
|
||
QVERIFY2(bbox.isValid() == false, "isValid failed");
|
||
}
|
||
|
||
const double zVal = 1.23456;
|
||
SituationMap::Point3D center(100, 1000, zVal);
|
||
double width = 20;
|
||
double height = 60;
|
||
|
||
SituationMap::BoundingBox bbox(SituationMap::BoundingBox::ExtentType::Sim,
|
||
center, width, height);
|
||
QVERIFY2(bbox.isValid() == true, "isValid failed");
|
||
QVERIFY2(bbox.extentType() == SituationMap::BoundingBox::ExtentType::Sim, "extentType failed");
|
||
|
||
QVERIFY2(bbox.center() == center, "center failed");
|
||
QVERIFY2(bbox.width() == width, "width failed");
|
||
QVERIFY2(bbox.height() == height, "height failed");
|
||
|
||
QVERIFY2(bbox.topLeft() == SituationMap::Point3D( 90, 1030, zVal), "topLeft failed");
|
||
QVERIFY2(bbox.topRight() == SituationMap::Point3D(110, 1030, zVal), "topLeft failed");
|
||
QVERIFY2(bbox.bottomLeft() == SituationMap::Point3D( 90, 970, zVal), "topLeft failed");
|
||
QVERIFY2(bbox.bottomRight() == SituationMap::Point3D(110, 970, zVal), "topLeft failed");
|
||
|
||
bbox.reset();
|
||
QVERIFY2(bbox.isValid() == false, "isValid failed");
|
||
QVERIFY2(bbox.extentType() == SituationMap::BoundingBox::ExtentType::Undefined, "extentType failed");
|
||
|
||
QVERIFY2(bbox.center().isNull() == true, "center failed");
|
||
QVERIFY2(bbox.width() < 0.001, "width failed");
|
||
QVERIFY2(bbox.height() < 0.001, "height failed");
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::checkDistanceMeasurement()
|
||
{
|
||
Esri::ArcGISRuntime::SpatialReference sr = Esri::ArcGISRuntime::SpatialReference::wgs84();
|
||
|
||
Esri::ArcGISRuntime::Point p1 =
|
||
Esri::ArcGISRuntime::CoordinateFormatter::fromMgrs(QLatin1String("32UMD 00001 00001"), sr, Esri::ArcGISRuntime::MgrsConversionMode::Automatic);
|
||
Esri::ArcGISRuntime::Point p2 =
|
||
Esri::ArcGISRuntime::CoordinateFormatter::fromMgrs(QLatin1String("32UMD 00011 00001"), sr, Esri::ArcGISRuntime::MgrsConversionMode::Automatic);
|
||
|
||
QVERIFY2(p1.isEmpty() == false, "fromMgrs failed");
|
||
QVERIFY2(p1.spatialReference().wkid() == 4326, "spatialReference failed");
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " p.x=" << p1.x() << " p.y=" << p1.y() << " p.z=" << p1.z()
|
||
<< " sr=" << p1.spatialReference().wkid();
|
||
|
||
//
|
||
// 1. checkDistanceMeasurement
|
||
//
|
||
const double distance =
|
||
Esri::ArcGISRuntime::GeometryEngine::distance(Esri::ArcGISRuntime::Point(p1.x(), p1.y(), sr),
|
||
Esri::ArcGISRuntime::Point(p2.x(), p2.y(), sr));
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " GeometryEngine::distance() " << distance;
|
||
|
||
//
|
||
// 2. distanceGeodetic
|
||
//
|
||
const Esri::ArcGISRuntime::GeodeticDistanceResult geodeticDistance =
|
||
Esri::ArcGISRuntime::GeometryEngine::distanceGeodetic(Esri::ArcGISRuntime::Point(p1.x(), p1.y(), sr),
|
||
Esri::ArcGISRuntime::Point(p2.x(), p2.y(), sr),
|
||
Esri::ArcGISRuntime::LinearUnitId::Meters,
|
||
Esri::ArcGISRuntime::AngularUnitId::Degrees,
|
||
Esri::ArcGISRuntime::GeodeticCurveType::Geodesic);
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " GeometryEngine::distanceGeodetic() " << geodeticDistance.distance();
|
||
|
||
QVERIFY2(geodeticDistance.distance() -10.0 < 0.01, "distanceGeodetic failed");
|
||
|
||
// ====> use distanceGeodetic
|
||
}
|
||
|
||
|
||
void SitMapUnitTest::recalculateAngle()
|
||
{
|
||
// aus Transformationspunkte GUEZ, Stand 08/2018:
|
||
// (Werte sind EPSG-Code 31468)
|
||
// BN_94: x=4473185.721 ; y=5817742.350 ; Drehwinkel=149.3805
|
||
// Wir benötigen den Drehwinkel aber in Bezug auf EPSG-Code 32632.
|
||
|
||
const Esri::ArcGISRuntime::SpatialReference srcSr(31468);
|
||
const Esri::ArcGISRuntime::SpatialReference destSr(32632);
|
||
const QPointF srcPoint(4473185.721, 5817742.350); // BN_94
|
||
// const QPointF srcPoint(4472996.165, 5817720.809); // BN_152
|
||
const double srcAngleDegree = 149.3805;
|
||
|
||
// Ansatz:
|
||
// Einen zusätzlichen Hilfspunkt bestimmen (Winkel == 0.0),
|
||
// beiden Punkte in die Zielprojektion überführen,
|
||
// dann den Winkel zw. diesen projezierten Punkten bestimmen.
|
||
// Somit erhalten wir eine Differenz zum ursprünglichen Winkel
|
||
|
||
const double offset = 1.0; // meter
|
||
|
||
QPointF h1 = srcPoint;
|
||
QPointF h2 = srcPoint + QPointF(offset, 0.0); // nur x, damit Winkel 0.0 ist
|
||
qCritical() << " h1= " << h1;
|
||
qCritical() << " h2= " << h2;
|
||
|
||
// project:
|
||
Esri::ArcGISRuntime::Point esriH1 =
|
||
Esri::ArcGISRuntime::GeometryEngine::project(Esri::ArcGISRuntime::Point(h1.x(), h1.y(), 0.0, srcSr), destSr);
|
||
Esri::ArcGISRuntime::Point esriH2 =
|
||
Esri::ArcGISRuntime::GeometryEngine::project(Esri::ArcGISRuntime::Point(h2.x(), h2.y(), 0.0, srcSr), destSr);
|
||
|
||
|
||
// Winkel bestimmen:
|
||
double dX = esriH1.x() - esriH2.x();
|
||
double dY = esriH1.y() - esriH2.y();
|
||
|
||
double destAngleRad = atan(dY / dX);
|
||
double destAngleDeg = destAngleRad / M_PI * 180.0;
|
||
qCritical() << " destAngleRad= " << QString::number(destAngleRad, 'f', 6);
|
||
qCritical() << " destAngleDeg= " << QString::number(destAngleDeg, 'f', 6);
|
||
|
||
|
||
qCritical() << " srcAngle : " << QString::number(srcAngleDegree, 'f', 6);
|
||
qCritical() << " destAngle: " << QString::number(srcAngleDegree + destAngleDeg, 'f', 6);
|
||
}
|
||
|
||
|
||
void SitMapUnitTest::measureDistanceGeodetic()
|
||
{
|
||
Esri::ArcGISRuntime::SpatialReference sr = Esri::ArcGISRuntime::SpatialReference::wgs84();
|
||
|
||
Esri::ArcGISRuntime::Point p1 =
|
||
Esri::ArcGISRuntime::CoordinateFormatter::fromMgrs(QLatin1String("32UMD 00001 00001"), sr, Esri::ArcGISRuntime::MgrsConversionMode::Automatic);
|
||
Esri::ArcGISRuntime::Point p2 =
|
||
Esri::ArcGISRuntime::CoordinateFormatter::fromMgrs(QLatin1String("32UMD 00011 00001"), sr, Esri::ArcGISRuntime::MgrsConversionMode::Automatic);
|
||
|
||
int jMax = 1000;
|
||
QElapsedTimer timer;
|
||
timer.start();
|
||
for (int j = 0; j < jMax; ++j)
|
||
{
|
||
const Esri::ArcGISRuntime::GeodeticDistanceResult geodeticDistance =
|
||
Esri::ArcGISRuntime::GeometryEngine::distanceGeodetic(Esri::ArcGISRuntime::Point(p1.x(), p1.y(), sr),
|
||
Esri::ArcGISRuntime::Point(p2.x(), p2.y(), sr),
|
||
Esri::ArcGISRuntime::LinearUnitId::Meters,
|
||
Esri::ArcGISRuntime::AngularUnitId::Degrees,
|
||
Esri::ArcGISRuntime::GeodeticCurveType::Geodesic);
|
||
if (geodeticDistance.distance() > 11)
|
||
qDebug() << " geodeticDistance: ";
|
||
}
|
||
qDebug() << " distanceGeodetic: " << jMax << " operations took " << timer.elapsed() << "ms";
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::checkDensify()
|
||
{
|
||
// connect errorHandling:
|
||
connect(Esri::ArcGISRuntime::GeometryEngine::instance(), &Esri::ArcGISRuntime::GeometryEngine::errorOccurred,
|
||
this, [this](const Esri::ArcGISRuntime::Error &error)
|
||
{
|
||
FATAL_LOG(m_logger) << LOGFUNCTION << " ---EsriError--- occured: " << error;
|
||
});
|
||
|
||
|
||
Esri::ArcGISRuntime::SpatialReference sr = Esri::ArcGISRuntime::SpatialReference::wgs84();
|
||
|
||
Esri::ArcGISRuntime::Point p1, p2;
|
||
|
||
|
||
//
|
||
// 1. densify
|
||
//
|
||
{
|
||
p1 = Esri::ArcGISRuntime::Point(8.0, 53.0, sr);
|
||
p2 = Esri::ArcGISRuntime::Point(9.0, 53.0, sr);
|
||
|
||
// create Polyline:
|
||
Esri::ArcGISRuntime::PolylineBuilder polylineBuilder(sr, this);
|
||
polylineBuilder.addPoint(p1);
|
||
polylineBuilder.addPoint(p2);
|
||
const Esri::ArcGISRuntime::Polyline &polylineIn = polylineBuilder.toPolyline();
|
||
|
||
|
||
const Esri::ArcGISRuntime::Geometry &geometryOut = Esri::ArcGISRuntime::GeometryEngine::densify(polylineIn, 0.1);
|
||
|
||
QVERIFY2(geometryOut.geometryType() == Esri::ArcGISRuntime::GeometryType::Polyline, "geometryType failed");
|
||
|
||
const Esri::ArcGISRuntime::Polyline polylineOut(geometryOut);
|
||
|
||
QVERIFY2(polylineOut.parts().size() == 1, "polylineOut.parts().size() failed");
|
||
qCritical() << "polylineOut.parts().part(0).pointCount() = " << polylineOut.parts().part(0).pointCount();
|
||
QVERIFY2(polylineOut.parts().part(0).pointCount() > 10, "polylineOut.parts().size() failed");
|
||
QVERIFY2(polylineOut.parts().part(0).pointCount() < 15, "polylineOut.parts().size() failed");
|
||
}
|
||
|
||
//
|
||
// 2. densifyGeodetic - ok?
|
||
//
|
||
{
|
||
|
||
p1 = Esri::ArcGISRuntime::CoordinateFormatter::fromMgrs(QLatin1String("32UMD 00001 00001"), sr, Esri::ArcGISRuntime::MgrsConversionMode::Automatic);
|
||
p2 = Esri::ArcGISRuntime::CoordinateFormatter::fromMgrs(QLatin1String("32UMD 00001 01001"), sr, Esri::ArcGISRuntime::MgrsConversionMode::Automatic);
|
||
|
||
// create Polyline:
|
||
Esri::ArcGISRuntime::PolylineBuilder polylineBuilder(sr, this);
|
||
polylineBuilder.addPoint(p1);
|
||
polylineBuilder.addPoint(p2);
|
||
const Esri::ArcGISRuntime::Polyline &polylineIn = polylineBuilder.toPolyline();
|
||
|
||
const Esri::ArcGISRuntime::Geometry &geometryOut = Esri::ArcGISRuntime::GeometryEngine::densifyGeodetic(polylineIn,
|
||
100,
|
||
Esri::ArcGISRuntime::LinearUnit::meters(),
|
||
Esri::ArcGISRuntime::GeodeticCurveType::Geodesic);
|
||
|
||
QVERIFY2(geometryOut.geometryType() == Esri::ArcGISRuntime::GeometryType::Polyline, "geometryType failed");
|
||
|
||
const Esri::ArcGISRuntime::Polyline polylineOut(geometryOut);
|
||
|
||
QVERIFY2(polylineOut.parts().size() == 1, "polylineOut.parts().size() failed");
|
||
qCritical() << "polylineOut.parts().part(0).pointCount() = " << polylineOut.parts().part(0).pointCount();
|
||
QVERIFY2(polylineOut.parts().part(0).pointCount() > 10, "polylineOut.parts().size() failed");
|
||
QVERIFY2(polylineOut.parts().part(0).pointCount() < 15, "polylineOut.parts().size() failed");
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
QPolygonF bufferUtmPolygon(const QPolygonF &polygonUtmIn, double distance, double maxDeviation = 1, QString *errorOut = nullptr)
|
||
{
|
||
Q_UNUSED(maxDeviation);
|
||
|
||
Esri::ArcGISRuntime::PolygonBuilder polygonBuilder(Esri::ArcGISRuntime::SpatialReference(32632));
|
||
|
||
for (const QPointF &pointUtm : std::as_const(polygonUtmIn))
|
||
polygonBuilder.addPoint(Esri::ArcGISRuntime::Point(pointUtm.x(), pointUtm.y(), 0));
|
||
const Esri::ArcGISRuntime::Geometry &esriGeometry = polygonBuilder.toGeometry();
|
||
|
||
const Esri::ArcGISRuntime::Polygon polyline =
|
||
Esri::ArcGISRuntime::GeometryEngine::buffer(esriGeometry, distance);
|
||
|
||
if (polyline.parts().isEmpty())
|
||
{
|
||
if (errorOut)
|
||
*errorOut = QStringLiteral("GeometryEngine::buffer failed (no parts");
|
||
return {};
|
||
}
|
||
|
||
|
||
const Esri::ArcGISRuntime::ImmutablePart &immutablePart = polyline.parts().part(0);
|
||
const int size = immutablePart.pointCount();
|
||
|
||
QPolygonF bufferedPoly;
|
||
bufferedPoly.reserve(size);
|
||
|
||
for (int i = 0; i < size; ++i)
|
||
{
|
||
const Esri::ArcGISRuntime::Point &esriP = immutablePart.point(i);
|
||
bufferedPoly.append(QPointF(esriP.x(), esriP.y()));
|
||
}
|
||
|
||
return bufferedPoly;
|
||
}
|
||
|
||
|
||
void SitMapUnitTest::checkBuffer()
|
||
{
|
||
// Für Gerlinde, Thema Gefährungsabstand
|
||
|
||
// Hier der Stellvertreter für das Wirkfeld:
|
||
QPolygonF wirkfeldPoly({ {0.0, 0.0}, {1000.0, 0.0}, {1000.0, 1000.0} });
|
||
|
||
NOTICE_LOG(m_logger) << LOGFUNCTION << " wirkfeldPoly.size = " << wirkfeldPoly.size();
|
||
for (auto item : std::as_const(wirkfeldPoly))
|
||
NOTICE_LOG(m_logger) << LOGFUNCTION << " wirkfeldPoly = " << item;
|
||
|
||
|
||
QString errorOut;
|
||
const QPolygonF &bufferedPoly = bufferUtmPolygon(wirkfeldPoly, 10, 1, &errorOut);
|
||
|
||
NOTICE_LOG(m_logger) << LOGFUNCTION << " bufferedPoly.size = " << bufferedPoly.size();
|
||
for (auto item : std::as_const(bufferedPoly))
|
||
NOTICE_LOG(m_logger) << LOGFUNCTION << " bufferedPoly = " << item;
|
||
}
|
||
|
||
void SitMapUnitTest::checkMovementTrack()
|
||
{
|
||
const Esri::ArcGISRuntime::SpatialReference &sr = Esri::ArcGISRuntime::SpatialReference::wgs84();
|
||
|
||
SituationMap::MovementTrack mt(4711);
|
||
|
||
bool success;
|
||
|
||
QVERIFY2(mt.size() == 0, "size failed");
|
||
QVERIFY2(mt.isActive() == true, "isActive failed");
|
||
|
||
QVERIFY2(mt.getTrack().size() == 0, "getTrack failed");
|
||
QVERIFY2(mt.getVisibleTrack(0, 999999, 999999).size() == 0, "getVisibleTrack failed");
|
||
|
||
Esri::ArcGISRuntime::Point eP1 =
|
||
Esri::ArcGISRuntime::CoordinateFormatter::fromMgrs(QLatin1String("32UMD 10000 10000"), sr, Esri::ArcGISRuntime::MgrsConversionMode::Automatic);
|
||
SituationMap::Point3D p1(eP1.x()/180.0*M_PI, eP1.y()/180.0*M_PI, eP1.z()); // -> rad
|
||
|
||
success = mt.addPosition(p1, 1000, 1, 99999);
|
||
QVERIFY2(success, "success failed");
|
||
QVERIFY2(mt.size() == 1, "size failed");
|
||
QVERIFY2(mt.getTrack().size() == 1, "getTrack failed");
|
||
|
||
// check via maxViewAgeMsec (3rd)
|
||
QVERIFY2(mt.getVisibleTrack(2000, 999999, 999).size() == 0, "getVisibleTrack failed");
|
||
QVERIFY2(mt.getVisibleTrack(2000, 999999, 1000).size() == 1, "getVisibleTrack failed");
|
||
|
||
// check via maxAgeMsec (2rd)
|
||
QVERIFY2(mt.getTrack().size() == 1, "getTrack failed");
|
||
QVERIFY2(mt.getVisibleTrack(2000, 1000, 1000).size() == 1, "getVisibleTrack failed");
|
||
QVERIFY2(mt.getTrack().size() == 1, "getTrack failed");
|
||
QVERIFY2(mt.getVisibleTrack(2000, 999, 1000).size() == 0, "getVisibleTrack failed");
|
||
QVERIFY2(mt.getTrack().size() == 0, "getTrack failed");
|
||
|
||
Esri::ArcGISRuntime::Point eP2 =
|
||
Esri::ArcGISRuntime::CoordinateFormatter::fromMgrs(QLatin1String("32UMD 10001 10000"), sr, Esri::ArcGISRuntime::MgrsConversionMode::Automatic);
|
||
SituationMap::Point3D p2(eP2.x()/180.0*M_PI, eP2.y()/180.0*M_PI, eP2.z()); // -> rad
|
||
|
||
Esri::ArcGISRuntime::Point eP3 =
|
||
Esri::ArcGISRuntime::CoordinateFormatter::fromMgrs(QLatin1String("32UMD 10010 10000"), sr, Esri::ArcGISRuntime::MgrsConversionMode::Automatic);
|
||
SituationMap::Point3D p3(eP3.x()/180.0*M_PI, eP3.y()/180.0*M_PI, eP3.z()); // -> rad
|
||
|
||
success = mt.addPosition(p1, 1000, 2, 99999);
|
||
QVERIFY2(success, "success failed addPosition");
|
||
QVERIFY2(mt.getTrack().size() == 1, "getTrack failed");
|
||
|
||
success = mt.addPosition(p2, 1100, 2, 99999); // p2 should NOT be added:
|
||
QVERIFY2(!success, "success failed addPosition");
|
||
QVERIFY2(mt.getTrack().size() == 1, "getTrack failed");
|
||
|
||
success = mt.addPosition(p3, 1100, 2, 99999); // p3 should be added:
|
||
QVERIFY2(success, "success failed addPosition");
|
||
QVERIFY2(mt.getTrack().size() == 2, "getTrack failed");
|
||
|
||
|
||
QJsonDocument jDoc(mt.toJsonObject());
|
||
{
|
||
// to json
|
||
// QFile saveFile(QStringLiteral("/tmp/mt.json"));
|
||
// if (!saveFile.open(QIODevice::WriteOnly)) {
|
||
// qWarning("Couldn't open mt file.");
|
||
// return;
|
||
// }
|
||
// saveFile.write(jDoc.toJson());
|
||
// qCritical() << "wrote " << QFileInfo(saveFile).absoluteFilePath();
|
||
// qCritical() << "mt.toJson()=" << jDoc.toJson();
|
||
}
|
||
{
|
||
// read json
|
||
const QJsonObject &objTemp = jDoc.object();
|
||
QSharedPointer<SituationMap::MovementTrack> newMt = SituationMap::MovementTrack::read(objTemp);
|
||
|
||
QVERIFY2(newMt->trackId() == mt.trackId(), " json: trackId failed");
|
||
QVERIFY2(newMt->isActive() == mt.isActive(), " json: isActive failed");
|
||
QVERIFY2(newMt->getTrack().size() == mt.getTrack().size(), " json: getTrack failed");
|
||
}
|
||
}
|
||
|
||
void SitMapUnitTest::checkMovementTrackManager()
|
||
{
|
||
SituationMap::MovementTrackManager mtMgr;
|
||
|
||
mtMgr.setCurrentTimeMsec(123);
|
||
QVERIFY2(mtMgr.currentTimeMsec() == 123, "currentTimeMsec failed");
|
||
|
||
mtMgr.setMaxAgeMsec(1234);
|
||
QVERIFY2(mtMgr.maxAgeMsec() == 1234, "maxAgeMsec failed");
|
||
|
||
mtMgr.setMaxViewAgeMsec(55);
|
||
QVERIFY2(mtMgr.maxViewAgeMsec() == 55, "maxViewAgeMsec failed");
|
||
|
||
mtMgr.setMaxNumberOfTracks(3);
|
||
QVERIFY2(mtMgr.maxNumberOfTracks() == 3, "maxNumberOfTracks failed");
|
||
|
||
mtMgr.setMaxNumberOfPointsPerTrack(5);
|
||
QVERIFY2(mtMgr.maxNumberOfPointsPerTrack() == 5, "maxNumberOfTracks failed");
|
||
|
||
mtMgr.setMinDistance(7);
|
||
QVERIFY2(mtMgr.minDistance() == 7, "minDistance failed");
|
||
|
||
bool success;
|
||
|
||
QVERIFY2(mtMgr.size() == 0, "size failed");
|
||
QVERIFY2(mtMgr.hasTrack(0) == false, "hasTrack failed");
|
||
QVERIFY2(mtMgr.activeTrackIds().size() == 0, "objectIdsOfActiveTracks failed");
|
||
QVERIFY2(mtMgr.activeAndVisibleTrack(0).size() == 0, "activeAndVisibleTrack failed");
|
||
|
||
// set some positions:
|
||
double lon = 0.155;
|
||
double lat = 0.926;
|
||
const SituationMap::Point3D p1(lon+0.000, lat, 0.0);
|
||
const SituationMap::Point3D p2(lon+0.001, lat, 0.0);
|
||
const SituationMap::Point3D p3(lon+0.002, lat, 0.0);
|
||
const SituationMap::Point3D p4(lon+0.003, lat, 0.0);
|
||
const SituationMap::Point3D p5(lon+0.004, lat, 0.0);
|
||
|
||
// check MaxNumberOfPointsPerTrack
|
||
{
|
||
QVERIFY2(mtMgr.maxNumberOfPointsPerTrack() == 5, "maxNumberOfTracks failed");
|
||
QVERIFY2(mtMgr.minDistance() == 7, "minDistance failed");
|
||
|
||
mtMgr.activateTrack(4711);
|
||
|
||
success = true;
|
||
success = success && mtMgr.addPosition(4711, p1, 10001);
|
||
success = success && mtMgr.addPosition(4711, p2, 10002);
|
||
success = success && mtMgr.addPosition(4711, p3, 10003);
|
||
success = success && mtMgr.addPosition(4711, p4, 10004);
|
||
success = success && mtMgr.addPosition(4711, p5, 10005);
|
||
success = success && mtMgr.addPosition(4711, p1, 10006); // maxNumberOfTracks exceeded -> pt1 removed
|
||
QVERIFY2(success == true, "addPosition failed");
|
||
QVERIFY2(mtMgr.activeAndVisibleTrack(4711).size() == 5, "activeAndVisibleTrack failed");
|
||
|
||
QVERIFY2(mtMgr.size() == 1, "size failed");
|
||
QVERIFY2(mtMgr.hasTrack(4711) == true, "hasTrack failed");
|
||
|
||
QVERIFY2(mtMgr.activeTrackIds().size() == 1, "objectIdsOfActiveTracks failed");
|
||
QVERIFY2(mtMgr.activeAndVisibleTrack(4711).size() == 5, "activeAndVisibleTrack failed");
|
||
}
|
||
|
||
// maxViewAgeMsec
|
||
{
|
||
int size = 0;
|
||
|
||
// a)
|
||
mtMgr.setCurrentTimeMsec(10006);
|
||
QVERIFY2(mtMgr.currentTimeMsec() == 10006, "currentTimeMsec failed");
|
||
|
||
mtMgr.setMaxViewAgeMsec(2);
|
||
size = mtMgr.activeAndVisibleTrack(4711).size();
|
||
QVERIFY2(size == 3, "activeAndVisibleTrack failed"); // 10006, 10005, 10004
|
||
|
||
// b) set currentTimeMsec forward
|
||
mtMgr.setCurrentTimeMsec(10008);
|
||
|
||
mtMgr.setMaxViewAgeMsec(2);
|
||
size = mtMgr.activeAndVisibleTrack(4711).size();
|
||
QVERIFY2(size == 1, "activeAndVisibleTrack failed"); // 10008, 10007, 10006
|
||
|
||
// c) set currentTimeMsec backward
|
||
mtMgr.setCurrentTimeMsec(10002);
|
||
|
||
size = mtMgr.activeAndVisibleTrack(4711).size();
|
||
QVERIFY2(size == 1, "activeAndVisibleTrack failed"); // 10002 (10001/pt1 removed)
|
||
}
|
||
|
||
|
||
// check removing of track, 1
|
||
{
|
||
QVERIFY2(mtMgr.maxNumberOfTracks() == 3, "maxNumberOfTracks failed");
|
||
|
||
mtMgr.activateTrack(4712);
|
||
QVERIFY2(mtMgr.addPosition(4712, p1, 10001) == true, "addPosition failed");
|
||
|
||
mtMgr.activateTrack(4713);
|
||
QVERIFY2(mtMgr.addPosition(4713, p1, 10001) == true, "addPosition failed");
|
||
QVERIFY2(mtMgr.size() == 3, "size failed");
|
||
QVERIFY2(mtMgr.activeTrackIds().size() == 3, "objectIdsOfActiveTracks failed");
|
||
|
||
mtMgr.activateTrack(4714);
|
||
QVERIFY2(mtMgr.addPosition(4714, p1, 10001) == true, "addPosition failed");
|
||
QVERIFY2(mtMgr.size() == 3, "size failed");
|
||
QVERIFY2(mtMgr.activeTrackIds().size() == 3, "objectIdsOfActiveTracks failed");
|
||
|
||
QVERIFY2(mtMgr.hasTrack(4711) == false, "hasTrack failed");
|
||
}
|
||
|
||
// check removing of track, 2
|
||
{
|
||
// 4712, 4713, 4714
|
||
const QVector<int> activeTracks1 = mtMgr.activeTrackIds();
|
||
QVERIFY2(activeTracks1 == QVector<int>() << 4712 << 4713 << 4714, "objectIdsOfActiveTracks failed");
|
||
|
||
mtMgr.deactivateTrack(4713);
|
||
|
||
// still 3 tracks, but just 2 active:
|
||
QVERIFY2(mtMgr.size() == 3, "size failed");
|
||
const QVector<int> activeTracks2 = mtMgr.activeTrackIds();
|
||
QVERIFY2(activeTracks2 == QVector<int>() << 4712 /*<< 4713*/ << 4714, "objectIdsOfActiveTracks failed");
|
||
|
||
|
||
// activate track 4715 -> deactived track 4713 has to be removed:
|
||
mtMgr.activateTrack(4715);
|
||
QVERIFY2(success == true, "addPosition failed");
|
||
QVERIFY2(mtMgr.size() == 3, "size failed");
|
||
|
||
// 4712, 4714, 4715
|
||
QVERIFY2(mtMgr.activeTrackIds().size() == 3, "objectIdsOfActiveTracks failed");
|
||
const QVector<int> activeTracks3 = mtMgr.activeTrackIds();
|
||
QVERIFY2(activeTracks3 == QVector<int>() << 4712 << 4714 << 4715, "objectIdsOfActiveTracks failed");
|
||
|
||
QVERIFY2(mtMgr.hasTrack(4711) == false, "hasTrack failed");
|
||
QVERIFY2(mtMgr.hasTrack(4712) == true, "hasTrack failed");
|
||
QVERIFY2(mtMgr.hasTrack(4713) == false, "hasTrack failed");
|
||
QVERIFY2(mtMgr.hasTrack(4714) == true, "hasTrack failed");
|
||
QVERIFY2(mtMgr.hasTrack(4715) == true, "hasTrack failed");
|
||
}
|
||
|
||
|
||
QVERIFY2(mtMgr.size() > 0, " json: size insufficiant");
|
||
|
||
const qint64 CURRENT_TIME_MSEC = 1516632216.0 * 1000.0; // to use qint64
|
||
mtMgr.setCurrentTimeMsec(CURRENT_TIME_MSEC);
|
||
|
||
QJsonDocument jDoc(mtMgr.toJsonObject());
|
||
{
|
||
// to json
|
||
QFile saveFile(QStringLiteral("/tmp/mtMgr.json"));
|
||
if (!saveFile.open(QIODevice::WriteOnly)) {
|
||
qWarning("Couldn't open mt file.");
|
||
return;
|
||
}
|
||
saveFile.write(jDoc.toJson());
|
||
qCritical() << "wrote " << QFileInfo(saveFile).absoluteFilePath();
|
||
qCritical() << "mtMgr.toJson()=" << jDoc.toJson();
|
||
}
|
||
{
|
||
// read json
|
||
SituationMap::MovementTrackManager newMtMgr;
|
||
const QJsonObject &objTemp = jDoc.object();
|
||
newMtMgr.read(objTemp);
|
||
|
||
QVERIFY2(newMtMgr.size() > 0, " json: size failed");
|
||
QVERIFY2(newMtMgr.size() == mtMgr.size(), " json: size failed");
|
||
|
||
qint64 diff;
|
||
diff = mtMgr.currentTimeMsec() - CURRENT_TIME_MSEC;
|
||
QVERIFY2(qFuzzyIsNull(double(diff)) == true, " json: maxAgeMsec failed");
|
||
diff = newMtMgr.currentTimeMsec() - CURRENT_TIME_MSEC;
|
||
QVERIFY2(qFuzzyIsNull(double(diff)) == true, " json: maxAgeMsec failed");
|
||
|
||
diff = newMtMgr.maxAgeMsec() - mtMgr.maxAgeMsec();
|
||
QVERIFY2(qFuzzyIsNull(double(diff)) == true, " json: maxAgeMsec failed");
|
||
|
||
diff = newMtMgr.maxViewAgeMsec() - mtMgr.maxViewAgeMsec();
|
||
QVERIFY2(qFuzzyIsNull(double(diff)) == true, " json: maxViewAgeMsec failed");
|
||
|
||
QVERIFY2(newMtMgr.maxNumberOfTracks() == mtMgr.maxNumberOfTracks(), " json: maxNumberOfTracks failed");
|
||
QVERIFY2(newMtMgr.maxNumberOfPointsPerTrack() == mtMgr.maxNumberOfPointsPerTrack(), " json: maxNumberOfPointsPerTrack failed");
|
||
QVERIFY2(newMtMgr.minDistance() == mtMgr.minDistance(), " json: minDistance failed");
|
||
|
||
const QVector<int> &activeTrackIds = newMtMgr.activeTrackIds();
|
||
for (const auto &trackId : activeTrackIds)
|
||
QVERIFY2(newMtMgr.activeAndVisibleTrack(trackId).size() == mtMgr.activeAndVisibleTrack(trackId).size(), " json: activeAndVisibleTrack failed");
|
||
}
|
||
}
|
||
|
||
|
||
void checkSidcCodecEncoded(const QString &sidc,
|
||
const QString &rawSidc,
|
||
AdvancedSymbology::SymbologyType symType,
|
||
AdvancedSymbology::SidcCodec::SidcType sidcType)
|
||
{
|
||
QVERIFY2(AdvancedSymbology::SidcCodec::isEncoded(sidc) == true, "isEncoded");
|
||
QVERIFY2(AdvancedSymbology::SidcCodec::decodeSymbologyType(sidc) == symType, "decodeSymbologyType");
|
||
QVERIFY2(AdvancedSymbology::SidcCodec::decodeSidcType(sidc) == sidcType, "decodeSidcType");
|
||
QVERIFY2(AdvancedSymbology::SidcCodec::decodeRawSidc(sidc).compare(rawSidc) == 0, "decodeRawSidc");
|
||
}
|
||
|
||
|
||
void SitMapUnitTest::checkSidcCodec()
|
||
{
|
||
// M25D|CMPL|10012500002713000000
|
||
{
|
||
{
|
||
QString sidc;
|
||
sidc = QLatin1String("AP6B|CMPL|10012500002713000000");
|
||
checkSidcCodecEncoded(sidc, QLatin1String("10012500002713000000"), AdvancedSymbology::SymbologyType::APP6B, AdvancedSymbology::SidcCodec::SidcType::Complete);
|
||
|
||
sidc = QLatin1String("AP6D|CMPL|10012500002713000000");
|
||
checkSidcCodecEncoded(sidc, QLatin1String("10012500002713000000"), AdvancedSymbology::SymbologyType::APP6D, AdvancedSymbology::SidcCodec::SidcType::Complete);
|
||
|
||
sidc = QLatin1String("M25C|CMPL|10012500002713000000");
|
||
checkSidcCodecEncoded(sidc, QLatin1String("10012500002713000000"), AdvancedSymbology::SymbologyType::MIL2525C, AdvancedSymbology::SidcCodec::SidcType::Complete);
|
||
|
||
sidc = QLatin1String("M25D|CMPL|10012500002713000000");
|
||
checkSidcCodecEncoded(sidc, QLatin1String("10012500002713000000"), AdvancedSymbology::SymbologyType::MIL2525D, AdvancedSymbology::SidcCodec::SidcType::Complete);
|
||
}
|
||
|
||
{
|
||
QString temp;
|
||
temp = AdvancedSymbology::SidcCodec::encodeBaseSymbolCode(AdvancedSymbology::SymbologyType::APP6B, QLatin1String("25271300"));
|
||
QVERIFY2(temp.compare(QLatin1String("AP6B|BASE|25271300")) == 0, "encodeBaseSymbolCode");
|
||
|
||
temp = AdvancedSymbology::SidcCodec::encodeBaseSymbolCode(AdvancedSymbology::SymbologyType::APP6D, QLatin1String("25271300"));
|
||
QVERIFY2(temp.compare(QLatin1String("AP6D|BASE|25271300")) == 0, "encodeBaseSymbolCode");
|
||
|
||
temp = AdvancedSymbology::SidcCodec::encodeBaseSymbolCode(AdvancedSymbology::SymbologyType::MIL2525C, QLatin1String("25271300"));
|
||
QVERIFY2(temp.compare(QLatin1String("M25C|BASE|25271300")) == 0, "encodeBaseSymbolCode");
|
||
|
||
temp = AdvancedSymbology::SidcCodec::encodeBaseSymbolCode(AdvancedSymbology::SymbologyType::MIL2525D, QLatin1String("25271300"));
|
||
QVERIFY2(temp.compare(QLatin1String("M25D|BASE|25271300")) == 0, "encodeBaseSymbolCode");
|
||
|
||
|
||
temp = AdvancedSymbology::SidcCodec::encodeComplete(AdvancedSymbology::SymbologyType::MIL2525D, QLatin1String("10012500002713000000"));
|
||
QVERIFY2(temp.compare(QLatin1String("M25D|CMPL|10012500002713000000")) == 0, "encodeComplete");
|
||
}
|
||
}
|
||
|
||
// Fehlerfälle
|
||
{
|
||
QString sidc = QLatin1String("10012500002713000000");
|
||
QVERIFY2(AdvancedSymbology::SidcCodec::decodeSymbologyType(sidc) == AdvancedSymbology::SymbologyType::None, "decodeSymbologyType");
|
||
QVERIFY2(AdvancedSymbology::SidcCodec::decodeSidcType(sidc) == AdvancedSymbology::SidcCodec::SidcType::None, "decodeSidcType");
|
||
QVERIFY2(AdvancedSymbology::SidcCodec::decodeRawSidc(sidc).compare(sidc) == 0, "decodeRawSidc");
|
||
}
|
||
|
||
}
|
||
|
||
|
||
void SitMapUnitTest::checkSIDCDefinitions1()
|
||
{
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::None)
|
||
return;
|
||
|
||
AdvancedSymbology::SymbolDictionary &dict = AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
QSignalSpy spy(&dict, &AdvancedSymbology::SymbolDictionary::loaded);
|
||
if(dict.isLoaded() == false)
|
||
{
|
||
dict.load();
|
||
if (spy.count() == 0)
|
||
spy.wait(10000);
|
||
}
|
||
QVERIFY2((dict.isLoaded() == true), "SymbolDictionary: isLoaded failed");
|
||
|
||
|
||
// real work:
|
||
|
||
bool success;
|
||
AdvancedSymbology::SidcDefinitions::StandardIdentity standardIdentity;
|
||
|
||
QVERIFY2((int)AdvancedSymbology::SidcDefinitions::Identity::Pending == 0 , "Identity emumValue wrong");
|
||
QVERIFY2((int)AdvancedSymbology::SidcDefinitions::Identity::Unknown == 1 , "Identity emumValue wrong");
|
||
QVERIFY2((int)AdvancedSymbology::SidcDefinitions::Identity::AssumedFriend == 2 , "Identity emumValue wrong");
|
||
QVERIFY2((int)AdvancedSymbology::SidcDefinitions::Identity::Friend == 3 , "Identity emumValue wrong");
|
||
QVERIFY2((int)AdvancedSymbology::SidcDefinitions::Identity::Neutral == 4 , "Identity emumValue wrong");
|
||
QVERIFY2((int)AdvancedSymbology::SidcDefinitions::Identity::SuspectJoker == 5 , "Identity emumValue wrong");
|
||
QVERIFY2((int)AdvancedSymbology::SidcDefinitions::Identity::HostileFaker == 6 , "Identity emumValue wrong");
|
||
|
||
// to be continued...
|
||
|
||
|
||
const QVector<AdvancedSymbology::SymbologyType> &supportedSmTypes = { AdvancedSymbology::SymbologyType::MIL2525D, AdvancedSymbology::SymbologyType::APP6D};
|
||
|
||
if (supportedSmTypes.contains(m_d->m_symbologyType))
|
||
{
|
||
QString baseSymbolCode = AdvancedSymbology::SidcCodec::encodeBaseSymbolCode(m_d->m_symbologyType, "25270100");
|
||
|
||
AdvancedSymbology::SidcBuilder sidcBuilder(&dict);
|
||
success = sidcBuilder.initFromSymbologyTypeBaseSymbolCode(m_d->m_symbologyType, baseSymbolCode);
|
||
QVERIFY2(success == true , "initFromSymbologyTypeBaseSymbolCode failed");
|
||
|
||
const QString &sidc = sidcBuilder.toSidc();
|
||
qCritical() << "sidc=" << sidc;
|
||
// 12345678901234567890
|
||
// 25 270100 // baseSymbolCode (SymbolSet + Entity)
|
||
|
||
const QString &rawSidc = AdvancedSymbology::SidcCodec::decodeRawSidc(sidc);
|
||
|
||
QVERIFY2(rawSidc.compare(QLatin1String("10012500002701000000")) == 0 , "initFromMil2525DBaseSymbolCode failed");
|
||
}
|
||
|
||
|
||
//
|
||
// test some arbitrary sidc (MIL2525D):
|
||
//
|
||
|
||
|
||
|
||
if (supportedSmTypes.contains(m_d->m_symbologyType))
|
||
{
|
||
// 1234567890
|
||
QString sidcSTR = AdvancedSymbology::SidcCodec::encodeComplete(m_d->m_symbologyType, "10051000001213030000"); // MIL2525D: 01011000001213030000 -> LandUnits, Observer, Motorized
|
||
qDebug() << "----------- " << sidcSTR;
|
||
|
||
AdvancedSymbology::SidcBuilder sidcBuilder(&dict);
|
||
success = sidcBuilder.initFromSymbologyType(m_d->m_symbologyType, sidcSTR);
|
||
QVERIFY2(success == true , "initFromSymbologyTypeBaseSymbolCode failed");
|
||
|
||
// First10
|
||
standardIdentity = sidcBuilder.standardIdentity();
|
||
|
||
QVERIFY2(standardIdentity.context == AdvancedSymbology::SidcDefinitions::Context::Reality , "standardIdentity.context failed");
|
||
QVERIFY2(standardIdentity.identity == AdvancedSymbology::SidcDefinitions::Identity::SuspectJoker , "standardIdentity.identity failed");
|
||
|
||
AdvancedSymbology::SidcDefinitions::SymbolSet symSet = sidcBuilder.symbolSet();
|
||
QVERIFY2(symSet == AdvancedSymbology::SidcDefinitions::SymbolSet::LandUnit, "symbolSet failed");
|
||
|
||
AdvancedSymbology::SidcDefinitions::Status status = sidcBuilder.status();
|
||
QVERIFY2(status == AdvancedSymbology::SidcDefinitions::Status::Present, "status failed");
|
||
|
||
QVERIFY2(sidcBuilder.headquarters() == false , "headquarters failed");
|
||
QVERIFY2(sidcBuilder.taskForce() == false , "taskForce failed");
|
||
QVERIFY2(sidcBuilder.feintDummy() == false , "feintDummy failed");
|
||
|
||
AdvancedSymbology::SidcDefinitions::AmplifierGroup amplGroup = sidcBuilder.amplifierGroup();
|
||
QVERIFY2(amplGroup == AdvancedSymbology::SidcDefinitions::AmplifierGroup::Unknown , "amplifierGroup failed");
|
||
|
||
int amplSub = sidcBuilder.amplifier2ndDigit();
|
||
QVERIFY2(amplSub == 0 , "amplifierSecondDigit failed");
|
||
|
||
// Second10
|
||
|
||
}
|
||
|
||
if (supportedSmTypes.contains(m_d->m_symbologyType))
|
||
{
|
||
// 1234567890
|
||
QString sidcSTR = AdvancedSymbology::SidcCodec::encodeComplete(m_d->m_symbologyType, "10012547231213030000");
|
||
qDebug() << "----------- " << sidcSTR;
|
||
|
||
AdvancedSymbology::SidcBuilder sidcBuilder(&dict);
|
||
success = sidcBuilder.initFromSymbologyType(m_d->m_symbologyType, sidcSTR);
|
||
QVERIFY2(success == true , "initFromSymbologyType failed");
|
||
|
||
// First10
|
||
standardIdentity = sidcBuilder.standardIdentity();
|
||
|
||
QVERIFY2(standardIdentity.context == AdvancedSymbology::SidcDefinitions::Context::Reality , "standardIdentity.context failed");
|
||
QVERIFY2(standardIdentity.identity == AdvancedSymbology::SidcDefinitions::Identity::Unknown , "standardIdentity.identity failed");
|
||
|
||
AdvancedSymbology::SidcDefinitions::SymbolSet symSet = sidcBuilder.symbolSet();
|
||
QVERIFY2(symSet == AdvancedSymbology::SidcDefinitions::SymbolSet::ControlMeasure, "symbolSet failed");
|
||
|
||
AdvancedSymbology::SidcDefinitions::Status status = sidcBuilder.status();
|
||
QVERIFY2(status == AdvancedSymbology::SidcDefinitions::Status::Present_Destroyed, "status failed");
|
||
|
||
QVERIFY2(sidcBuilder.headquarters() == true , "headquarters failed");
|
||
QVERIFY2(sidcBuilder.taskForce() == true , "taskForce failed");
|
||
QVERIFY2(sidcBuilder.feintDummy() == true , "feintDummy failed");
|
||
|
||
AdvancedSymbology::SidcDefinitions::AmplifierGroup amplGroup = sidcBuilder.amplifierGroup();
|
||
QVERIFY2(amplGroup == AdvancedSymbology::SidcDefinitions::AmplifierGroup::Echelon_DivisionAndAbove , "amplifierGroup failed");
|
||
|
||
int amplSub = sidcBuilder.amplifier2ndDigit();
|
||
QVERIFY2(amplSub == 3 , "amplifierSecondDigit failed");
|
||
|
||
// Second10
|
||
|
||
}
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::checkSIDCDefinitions2()
|
||
{
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::None)
|
||
return;
|
||
|
||
checkSymbolDictionaryLoad();
|
||
|
||
AdvancedSymbology::SymbolDictionary &dict =
|
||
AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
AdvancedSymbology::SidcDefinitions sidcDefinitions(&dict);
|
||
|
||
const QStringList &modifierKeys = sidcDefinitions.modifierKeys();
|
||
QVERIFY2(modifierKeys.isEmpty() == false , "modifierKeys failed");
|
||
|
||
QVERIFY2(sidcDefinitions.modifierList(AdvancedSymbology::SidcDefinitions::SymbolSet::Activities, 1).isEmpty() == false , "modifierList failed");
|
||
// QVERIFY2(sidcDefinitions.modifierList(AdvancedSymbology::SidcDefinitions::SymbolSet::Activities, 2).isEmpty() == false , "modifierList failed");
|
||
|
||
QVERIFY2(sidcDefinitions.modifierList(AdvancedSymbology::SidcDefinitions::SymbolSet::Air, 1).isEmpty() == false , "modifierList failed");
|
||
QVERIFY2(sidcDefinitions.modifierList(AdvancedSymbology::SidcDefinitions::SymbolSet::Air, 2).isEmpty() == false , "modifierList failed");
|
||
|
||
QVERIFY2(sidcDefinitions.modifierList(AdvancedSymbology::SidcDefinitions::SymbolSet::AirMissle, 1).isEmpty() == false , "modifierList failed");
|
||
QVERIFY2(sidcDefinitions.modifierList(AdvancedSymbology::SidcDefinitions::SymbolSet::AirMissle, 2).isEmpty() == false , "modifierList failed");
|
||
|
||
// to be cont.
|
||
|
||
}
|
||
|
||
|
||
/*
|
||
void SitMapUnitTest::checkCreateSidc()
|
||
{
|
||
|
||
//
|
||
// MIL
|
||
//
|
||
{
|
||
AdvancedSymbology::SymbolDictionary &dict =
|
||
AdvancedSymbology::SymbolDictionary::dictionary(AdvancedSymbology::SymbologyType::MIL2525C);
|
||
|
||
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---*****")); // ('taken' from typen@sys_db)
|
||
dict.createSidc(sidc, SymbolTypes::FRIEND, SymbolTypes::STATE_PRESENT);
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SFGPUCD---")) == 0, "createSidc failed");
|
||
}
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---*****"));
|
||
dict.createSidc(sidc, SymbolTypes::ENEMY, SymbolTypes::STATE_PRESENT);
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SHGPUCD---")) == 0, "createSidc failed");
|
||
}
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---*****"));
|
||
dict.createSidc(sidc, SymbolTypes::NEUTRAL, SymbolTypes::STATE_PRESENT);
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SNGPUCD---")) == 0, "createSidc failed");
|
||
}
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---*****"));
|
||
dict.createSidc(sidc, SymbolTypes::UNKNOWN, SymbolTypes::STATE_PRESENT);
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SUGPUCD---")) == 0, "createSidc failed");
|
||
}
|
||
|
||
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---*****"));
|
||
dict.createSidc(sidc, SymbolTypes::ENEMY, SymbolTypes::STATE_ANTICIPATED);
|
||
// QVERIFY2( dict.contains(sidc), "contains failed"); // ANTICIPATED -> 'A' is not supported by ESRI-Dictionary yet
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SHGAUCD---")) == 0, "createSidc failed");
|
||
}
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---************"));
|
||
dict.createSidc(sidc, SymbolTypes::ENEMY, SymbolTypes::STATE_PRESENT);
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SHGPUCD---")) == 0, "createSidc failed");
|
||
}
|
||
|
||
}
|
||
|
||
//
|
||
// APP6
|
||
//
|
||
|
||
{
|
||
AdvancedSymbology::SymbolDictionary &dict =
|
||
AdvancedSymbology::SymbolDictionary::dictionary(AdvancedSymbology::SymbologyType::APP6B);
|
||
|
||
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---*****"));
|
||
dict.createSidc(sidc, SymbolTypes::FRIEND, SymbolTypes::STATE_PRESENT);
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SFGPUCD---")) == 0, "createSidc failed");
|
||
}
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---*****"));
|
||
dict.createSidc(sidc, SymbolTypes::ENEMY, SymbolTypes::STATE_PRESENT);
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SHGPUCD---")) == 0, "createSidc failed");
|
||
}
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---*****"));
|
||
dict.createSidc(sidc, SymbolTypes::NEUTRAL, SymbolTypes::STATE_PRESENT);
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SNGPUCD---")) == 0, "createSidc failed");
|
||
}
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---*****"));
|
||
dict.createSidc(sidc, SymbolTypes::UNKNOWN, SymbolTypes::STATE_PRESENT);
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SUGPUCD---")) == 0, "createSidc failed");
|
||
}
|
||
|
||
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---*****"));
|
||
dict.createSidc(sidc, SymbolTypes::ENEMY, SymbolTypes::STATE_ANTICIPATED);
|
||
// QVERIFY2( dict.contains(sidc), "contains failed"); // ANTICIPATED -> 'A' is not supported by ESRI-Dictionary yet
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SHGAUCD---")) == 0, "createSidc failed");
|
||
}
|
||
{
|
||
QString sidc(QLatin1String("S*G*UCD---************"));
|
||
dict.createSidc(sidc, SymbolTypes::ENEMY, SymbolTypes::STATE_PRESENT);
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
QVERIFY2(sidc.length() == 10, "createSidc failed");
|
||
QVERIFY2(sidc.compare(QLatin1String("SHGPUCD---")) == 0, "createSidc failed");
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
*/
|
||
|
||
/*
|
||
void SitMapUnitTest::checkSymbolProperties()
|
||
{
|
||
AdvancedSymbology::SymbolDictionary &dict =
|
||
AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
if (dict.symbologyType() == AdvancedSymbology::SymbologyType::None)
|
||
return;
|
||
|
||
|
||
// 1
|
||
{
|
||
QString sidc(QLatin1String("SUGPUSAJ--")); // SUGPUSAJ-- should exist as MIL and APP :-)
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
|
||
const AdvancedSymbology::SymbolProperties &props = dict.symbolProperties(sidc);
|
||
QVERIFY2(props.sidc().compare(QLatin1String("SUGPUSAJ--")) == 0, "symbolProperties failed");
|
||
QVERIFY2(props.geometryType() == AdvancedSymbology::GeometryType::Point, "geometryType failed");
|
||
int minPoints = props.minNumberOfPoints();
|
||
QVERIFY2(minPoints == 1, "minNumberOfPoints failed");
|
||
}
|
||
|
||
// 2
|
||
{
|
||
QString sidc;
|
||
switch (m_d->m_symbologyType)
|
||
{
|
||
case AdvancedSymbology::SymbologyType::MIL2525C:
|
||
sidc = QLatin1String("GUGPOLAGM-");
|
||
break;
|
||
case AdvancedSymbology::SymbologyType::APP6B:
|
||
sidc = QLatin1String("GHTPGC----");
|
||
break;
|
||
case AdvancedSymbology::SymbologyType::None:
|
||
// empty
|
||
break;
|
||
}
|
||
|
||
if (! sidc.isEmpty())
|
||
{
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
|
||
const AdvancedSymbology::SymbolProperties &props = dict.symbolProperties(sidc);
|
||
QVERIFY2(props.sidc().compare(sidc) == 0, "symbolProperties failed");
|
||
QVERIFY2(props.geometryType() == AdvancedSymbology::GeometryType::Polyline, "geometryType failed");
|
||
int minPoints = props.minNumberOfPoints();
|
||
QVERIFY2(minPoints == 2, "minNumberOfPoints failed");
|
||
}
|
||
}
|
||
|
||
// 3
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::APP6B)
|
||
{
|
||
// Check if esriBug is fixed (by our own or by esri)
|
||
// Bug 1: Tank Light Recovery:
|
||
// APP6: correct: "S*G*EVATW-"
|
||
// (MIL: correct: "S*G*EVATLR"
|
||
// APP6: 10.2.6: "S*G*EVATLR" (e.g. 0695)
|
||
|
||
QString sidc(QLatin1String("SUGPEVATW-")); // SUGPEVATW-
|
||
QVERIFY2(dict.contains(sidc), "contains failed");
|
||
|
||
const AdvancedSymbology::SymbolProperties &props = dict.symbolProperties(sidc);
|
||
QVERIFY2(props.sidc().compare(sidc) == 0, "symbolProperties failed");
|
||
QVERIFY2(props.geometryType() == AdvancedSymbology::GeometryType::Point, "geometryType failed");
|
||
int minPoints = props.minNumberOfPoints();
|
||
QVERIFY2(minPoints == 1, "minNumberOfPoints failed");
|
||
|
||
// check keywords:
|
||
QStringList result = props.keywords().filter(sidc, Qt::CaseInsensitive);
|
||
QVERIFY2(result.size() == 1, "keywords failed");
|
||
}
|
||
|
||
}
|
||
*/
|
||
|
||
QImage createDummyImage()
|
||
{
|
||
int widthPixel = 100;
|
||
QImage image = QImage(widthPixel, widthPixel, QImage::Format_ARGB32);
|
||
image.fill(Qt::transparent);
|
||
|
||
QPainter p;
|
||
QPen pen(Qt::red);
|
||
pen.setWidth(5);
|
||
|
||
p.begin(&image);
|
||
p.setPen(pen);
|
||
p.drawLine(QPointF(0, 0), QPointF(100, 100));
|
||
p.end();
|
||
|
||
// bool success = image.save(QLatin1String("/tmp/dummy.png"));
|
||
// qWarning() << " image.save = " << success;
|
||
return image;
|
||
}
|
||
|
||
/*
|
||
bool checkAllCount(AdvancedSymbology::SymbolDictionary &dict)
|
||
{
|
||
SituationMap::LOGGER_T myLogger = SituationMap::getLogger("SitMapUnitTest");
|
||
|
||
if (dict.symbologyType() == AdvancedSymbology::SymbologyType::None)
|
||
{
|
||
// None:
|
||
if (dict.count() > 100) // 100 -> arbitrary
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
// App, Mil:
|
||
if (dict.count() <= 0)
|
||
return false;
|
||
}
|
||
|
||
// verify size of different lists:
|
||
int count = dict.count();
|
||
int sizeFindSymbolsAll = dict.findSymbols().size();
|
||
QString sidcPattern; // empty
|
||
int sizeFindSymbolsSidcPattern = dict.findSymbols(sidcPattern).size();
|
||
int sizeSidcList = dict.sidcList().size();
|
||
|
||
INFO_LOG(myLogger) << LOGFUNCTION
|
||
<< " count = " << count
|
||
<< " sizeFindSymbolsAll = " << sizeFindSymbolsAll
|
||
<< " sizeFindSymbolsSidcPattern = " << sizeFindSymbolsSidcPattern
|
||
<< " sizeSidcList = " << sizeSidcList;
|
||
|
||
bool ok = (count == sizeFindSymbolsAll)
|
||
&& (count == sizeFindSymbolsSidcPattern)
|
||
&& (count == sizeSidcList);
|
||
if (! ok)
|
||
{
|
||
ERROR_LOG(myLogger) << LOGFUNCTION
|
||
<< " count = " << count
|
||
<< " sizeFindSymbolsAll = " << sizeFindSymbolsAll
|
||
<< " sizeFindSymbolsSidcPattern = " << sizeFindSymbolsSidcPattern
|
||
<< " sizeSidcList = " << sizeSidcList;
|
||
}
|
||
return ok;
|
||
}
|
||
*/
|
||
|
||
/*
|
||
bool addOneSymbol(AdvancedSymbology::SymbolDictionary &dict)
|
||
{
|
||
SituationMap::LOGGER_T myLogger = SituationMap::getLogger("SitMapUnitTest");
|
||
Q_UNUSED(myLogger)
|
||
|
||
bool success = false;
|
||
|
||
QImage image = createDummyImage();
|
||
|
||
const QString sidc = QLatin1String("Nt-sidc");
|
||
const QString name = QLatin1String("NT-name");
|
||
|
||
QStringList keywords;
|
||
keywords << QLatin1String("NT-key1");
|
||
keywords << QLatin1String("NT-keyDuplicate") << QLatin1String("NT-keyDuplicate");
|
||
|
||
QHash<QString, QString> values;
|
||
values[QLatin1String("Category")] = QLatin1String("Other");
|
||
values[QLatin1String("SymbolID")] = sidc;
|
||
values[QLatin1String("GeometryType")] = QLatin1String("Point");
|
||
values[QLatin1String("GeometryConversionType")] = QLatin1String("GeometryConversionType-Unknown");
|
||
values[QLatin1String("StyleFile")] = QLatin1String("StyleFile-Unknown");
|
||
|
||
AdvancedSymbology::SymbolProperties props(name, keywords, values);
|
||
|
||
success = dict.addSymbol(sidc, props, image);
|
||
return success;
|
||
}
|
||
*/
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryLoad()
|
||
{
|
||
AdvancedSymbology::cleanupSymbolDictionaryInternal();
|
||
|
||
AdvancedSymbology::SymbolDictionary &dict =
|
||
AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
// SymbologyType::None -> no esriDict -> immediately loaded:
|
||
// ! SymbologyType::None -> esriDict -> load...
|
||
|
||
QSignalSpy spy(&dict, &AdvancedSymbology::SymbolDictionary::loaded);
|
||
dict.load();
|
||
QTRY_VERIFY2(dict.isLoaded(), "SymbolDictionary: isLoaded failed");
|
||
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::None)
|
||
{
|
||
QTest::qWait(100);
|
||
QVERIFY2(spy.count() == 0, "SymbolDictionary: signalCount failed, layerOrderChanged");
|
||
}
|
||
else
|
||
{
|
||
QTRY_VERIFY2(spy.count() == 1, "SymbolDictionary: signalCount failed, layerOrderChanged");
|
||
}
|
||
|
||
// get cached Dictionary:
|
||
qWarning() << "get cached Dictionary";
|
||
{
|
||
// -> immediately loaded
|
||
AdvancedSymbology::SymbolDictionary &dict =
|
||
AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
QVERIFY2((dict.isLoaded() == true), "SymbolDictionary: isLoaded failed");
|
||
}
|
||
|
||
|
||
|
||
/*
|
||
int count = dict.count();
|
||
|
||
bool dictChanged = false;
|
||
|
||
// lambda
|
||
connect(&dict, &AdvancedSymbology::SymbolDictionary::changed, [&]()
|
||
{
|
||
dictChanged = true;
|
||
});
|
||
|
||
|
||
//
|
||
// Initial Check
|
||
//
|
||
bool countOk = checkAllCount(dict);
|
||
QVERIFY2((countOk == true), "at least one count failed");
|
||
|
||
//
|
||
// add new symbol an check:
|
||
//
|
||
{
|
||
bool addSym = addOneSymbol(dict);
|
||
QVERIFY2((addSym == true), "addSymbol failed");
|
||
QVERIFY2((dictChanged == true), "dictChanged signal not emitted");
|
||
|
||
countOk = checkAllCount(dict);
|
||
QVERIFY2((countOk == true), "at least one count failed");
|
||
QVERIFY2(dict.count() == (count + 1), "count failed");
|
||
}
|
||
*/
|
||
}
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryLoadSymbolXml()
|
||
{
|
||
AdvancedSymbology::cleanupSymbolDictionaryInternal();
|
||
|
||
AdvancedSymbology::SymbolDictionary &dict = AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
bool ok;
|
||
AdvancedSymbology::SymbolProperties symProps;
|
||
|
||
ok = dict.insertXmlTestSymbol(symProps);
|
||
QVERIFY2(ok, "insert xml test symbol failed.");
|
||
|
||
ok = dict.insertXmlComplexTestSymbol(symProps);
|
||
QVERIFY2(ok, "insert xml test complex symbol failed.");
|
||
|
||
QVERIFY2( (dict.xmlSymbolCount() == 2), "count of xml symbols has wrong value - should be 2" );
|
||
|
||
const QString &sidc = AdvancedSymbology::SidcCodec::encodeCivilXml(QString::number(4711));
|
||
dict.removeXmlSymbol(sidc);
|
||
dict.removeXmlSymbol(4711);
|
||
|
||
QVERIFY2( (dict.xmlSymbolCount() == 1), "count of xml symbols has wrong value after removeXmlSymbol() - should be 1" );
|
||
|
||
dict.clearXmlSymbols();
|
||
|
||
QVERIFY2( (dict.xmlSymbolCount() == 0), "count of xml symbols is not zero after clearXmlSymbols()" );
|
||
|
||
} // void SitMapUnitTest::checkSymbolDictionaryLoadSymbolXml()
|
||
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryConsistency()
|
||
{
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::None)
|
||
return;
|
||
|
||
checkSymbolDictionaryLoad();
|
||
auto &dict = AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
// get access to esriDict:
|
||
AdvancedSymbology::SymbolDictionaryImpl &dictImpl = static_cast<AdvancedSymbology::SymbolDictionaryImpl &>(dict);
|
||
Esri::ArcGISRuntime::DictionarySymbolStyle *esriDict = const_cast<Esri::ArcGISRuntime::DictionarySymbolStyle*>(dictImpl.getEsriSymbolDictionary());
|
||
|
||
QHash<QString, AdvancedSymbology::SymbolProperties> baseSymbolCodeToSymbolPropertyTable;
|
||
|
||
|
||
// Use QFuture-based async API
|
||
Esri::ArcGISRuntime::SymbolStyleSearchParameters sssp;
|
||
QFuture<Esri::ArcGISRuntime::SymbolStyleSearchResultListModel*> future = esriDict->searchSymbolsAsync(sssp);
|
||
|
||
// Wait for completion
|
||
QFutureWatcher<Esri::ArcGISRuntime::SymbolStyleSearchResultListModel*> watcher;
|
||
watcher.setFuture(future);
|
||
watcher.waitForFinished();
|
||
|
||
Esri::ArcGISRuntime::SymbolStyleSearchResultListModel *searchResults = future.result();
|
||
|
||
INFO_LOG(m_logger) << LOGFUNCTION << " proceessing...";
|
||
|
||
//
|
||
// process all results and store them in member:
|
||
//
|
||
const QList<Esri::ArcGISRuntime::SymbolStyleSearchResult> &resultList =
|
||
searchResults->searchResults();
|
||
|
||
int symbolClass;
|
||
for (const Esri::ArcGISRuntime::SymbolStyleSearchResult &resultItem : resultList)
|
||
{
|
||
// 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(";")) << "'";
|
||
|
||
const QString &originalKey = resultItem.key();
|
||
|
||
// to reduce empty keys:
|
||
symbolClass = resultItem.symbolClass().toInt();
|
||
if ( (symbolClass == 6) || // symbolClass ( 6) == TextSymbol
|
||
(symbolClass == 10) // symbolClass (10) == MaplexLabelPlacement
|
||
)
|
||
{
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||
<< " continue:: symbolClass does not match "
|
||
<< " originalKey='" << originalKey << "'"
|
||
<< " name='" << resultItem.name() << "'";
|
||
continue;
|
||
}
|
||
|
||
if (originalKey.isEmpty())
|
||
{
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||
<< " continue:: empty key, "
|
||
<< " name='" << resultItem.name() << "'";
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// size (25270100 || 25270100_4)
|
||
//
|
||
const int keySize = originalKey.size();
|
||
if ( ! ((keySize == 8) || (keySize == 10)) )
|
||
{
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||
<< " continue:: keySize does not match "
|
||
<< " originalKey='" << originalKey << "'"
|
||
<< " name='" << resultItem.name() << "'";
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// isFrame (key like '0_110_1c')
|
||
//
|
||
if ( QStringRef(&originalKey, 1, 1).compare(QLatin1String("_"))==0 )
|
||
{
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||
<< " continue:: isFrame "
|
||
<< " originalKey='" << originalKey << "'"
|
||
<< " name='" << resultItem.name() << "'";
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// isCharlie (key like '46120203_C')
|
||
//
|
||
if ( (keySize == 10) && (originalKey.rightRef(2).compare(QLatin1String("_C"))==0) )
|
||
{
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||
<< " continue:: isCharlie"
|
||
<< " originalKey='" << originalKey << "'"
|
||
<< " name='" << resultItem.name() << "'";
|
||
continue;
|
||
}
|
||
|
||
const QString &key = originalKey;
|
||
|
||
//
|
||
// just digits:
|
||
//
|
||
bool ok = false;
|
||
const QStringRef &key8 = originalKey.leftRef(8);
|
||
key8.toInt(&ok);
|
||
if (! ok)
|
||
{
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||
<< " continue:: chars"
|
||
<< " originalKey='" << originalKey << "'"
|
||
<< " name='" << resultItem.name() << "'";
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// special (46110304_X)
|
||
//
|
||
if ( (keySize == 10) && (originalKey.rightRef(2).compare(QLatin1String("_X"))==0) )
|
||
{
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||
<< " continue:: is _X"
|
||
<< " originalKey='" << originalKey << "'"
|
||
<< " name='" << resultItem.name() << "'";
|
||
continue;
|
||
}
|
||
|
||
|
||
AdvancedSymbology::SymbolProperties symProps;
|
||
symProps.setKey (key);
|
||
symProps.setSidc (AdvancedSymbology::SidcCodec::encodeBaseSymbolCode(m_d->m_symbologyType,key8));
|
||
symProps.setName (resultItem.name());
|
||
symProps.setCategory (resultItem.category());
|
||
symProps.setSymbolClass(resultItem.symbolClass());
|
||
symProps.setTags (resultItem.tags());
|
||
|
||
baseSymbolCodeToSymbolPropertyTable[originalKey] = symProps;
|
||
} // Q_FOREACH
|
||
|
||
FATAL_LOG(m_logger) << LOGFUNCTION << " baseSymbolCodeToSymbolPropertyTable.size=" << baseSymbolCodeToSymbolPropertyTable.size();
|
||
|
||
|
||
QStringList noKey8Entries;
|
||
QStringList noKey8EntriesOfUnknown;
|
||
QStringList propsDiffer;
|
||
|
||
for (const AdvancedSymbology::SymbolProperties &symPropItem : std::as_const(baseSymbolCodeToSymbolPropertyTable))
|
||
{
|
||
const QString &curKey = symPropItem.key();
|
||
// INFO_LOG(m_logger) << LOGFUNCTION << " curKey ='" << curKey << "'";
|
||
const QString &key8 = curKey.left(8);
|
||
|
||
// check 1a:
|
||
// are there entries with postfix (_1, _2, _3) but not without??
|
||
|
||
bool noKey8EntriesFlag = false;
|
||
// 25270100_1 but not 25270100 ?
|
||
// (e.g. '10120100_0' ; '10120100_1' ; '10120100_2' ; '10120100_3' ; but no '10120100'
|
||
// 10120100 = Movement And Maneuver ; Air Assult with Organic Lift - FullFrame
|
||
// These are the FULL_FRAME symbols. (except "Maneuver Lines : Line of Contact" = 25140200_6)
|
||
//
|
||
// Exception: "Maneuver Lines : Line of Contact" = 25140200_6, _4, _3, _1)
|
||
|
||
if (curKey.size() == 10)
|
||
{
|
||
if (! baseSymbolCodeToSymbolPropertyTable.contains(key8))
|
||
{
|
||
noKey8Entries.append(curKey);
|
||
noKey8EntriesFlag = true;
|
||
}
|
||
} // if (curKey.size() == 10)
|
||
|
||
// check 1b
|
||
if (noKey8EntriesFlag &&
|
||
symPropItem.name().contains(QLatin1String("Unknown")))
|
||
{
|
||
noKey8EntriesOfUnknown.append(curKey);
|
||
}
|
||
|
||
|
||
|
||
// check 2:
|
||
AdvancedSymbology::SymbolProperties curSymProps = baseSymbolCodeToSymbolPropertyTable[curKey];
|
||
{
|
||
QStringList sl = curSymProps.name().split(QLatin1Char(':'));
|
||
sl.removeOne(QLatin1String("Friend"));
|
||
sl.removeOne(QLatin1String("Friendly"));
|
||
sl.removeOne(QLatin1String("Hostile"));
|
||
sl.removeOne(QLatin1String("Neutral"));
|
||
sl.removeOne(QLatin1String("Unknown"));
|
||
curSymProps.setName(sl.join(QLatin1Char(':')));
|
||
}
|
||
|
||
if (baseSymbolCodeToSymbolPropertyTable.contains(key8))
|
||
{
|
||
AdvancedSymbology::SymbolProperties symPropsKey8 = baseSymbolCodeToSymbolPropertyTable[key8];
|
||
QStringList sl = symPropsKey8.name().split(QLatin1Char(':'));
|
||
sl.removeOne(QLatin1String("Friend"));
|
||
sl.removeOne(QLatin1String("Friendly"));
|
||
sl.removeOne(QLatin1String("Hostile"));
|
||
sl.removeOne(QLatin1String("Neutral"));
|
||
sl.removeOne(QLatin1String("Unknown"));
|
||
symPropsKey8.setName(sl.join(QLatin1Char(':')));
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " key8=" << key8 << " curSymProps.name = " << curSymProps.name();
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " key8=" << key8 << " symPropsKey8.name = " << symPropsKey8.name();
|
||
|
||
|
||
bool ok =
|
||
// (curSymProps.name() == symPropsKey8.name()) &&
|
||
// (curSymProps.category() == symPropsKey8.category()) &&
|
||
// // (curSymProps.symbolClass() == symPropsKey8.symbolClass()) && // do not compare SymbolClass
|
||
(curSymProps.tags() == symPropsKey8.tags());
|
||
// (curSymProps.geometryType() == symPropsKey8.geometryType());
|
||
|
||
if (! ok)
|
||
{
|
||
propsDiffer.append(curKey);
|
||
}
|
||
}
|
||
} // Q_FOREACH
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " noKey8Entries.size = " << noKey8Entries.size();
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " noKey8Entries = " << noKey8Entries.join(QLatin1String(" ; "));
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " noKey8EntriesOfUnknown.size = " << noKey8EntriesOfUnknown.size();
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " noKey8EntriesOfUnknown = " << noKey8EntriesOfUnknown.join(QLatin1String(" ; "));
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " propsDiffer.size = " << propsDiffer.size();
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " propsDiffer = " << propsDiffer.join(QLatin1String(" ; "));
|
||
|
||
// dump differ:
|
||
for (const auto &curKey : propsDiffer)
|
||
{
|
||
AdvancedSymbology::SymbolProperties curSymProps = baseSymbolCodeToSymbolPropertyTable[curKey];
|
||
|
||
const QString &key8 = curKey.left(8);
|
||
AdvancedSymbology::SymbolProperties symPropsKey8 = baseSymbolCodeToSymbolPropertyTable[key8];
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " curSymProps " << curSymProps.tags().join(QLatin1String(" @ "));
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " symPropsKey8 " << symPropsKey8.tags().join(QLatin1String(" @ "));
|
||
}
|
||
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryFetchSymbol()
|
||
{
|
||
checkSymbolDictionaryLoad();
|
||
auto &dict = AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::MIL2525D)
|
||
{
|
||
|
||
{
|
||
const QString sidc = AdvancedSymbology::SidcCodec::encodeComplete(AdvancedSymbology::SymbologyType::MIL2525D, "10042500002701000000"); // baseSymbolCode = 25 270100
|
||
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == false), "SymbolDictionary: resultIsValid failed");
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.fetchSymbol(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
const QUuid &taskId1 = symbolResultWatcher.symbolResult()->taskId();
|
||
QVERIFY2((taskId1.isNull() == false), "SymbolDictionary: taskId failed");
|
||
|
||
// inspect result:
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Polygon), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
}
|
||
|
||
// find different: (PointSymbol)
|
||
{
|
||
const QString sidc = AdvancedSymbology::SidcCodec::encodeComplete( AdvancedSymbology::SymbologyType::MIL2525D,"10031500001110000000"); // baseSymbolCode = 15 111000 Missle Launcher
|
||
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.fetchSymbol(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
const QUuid &taskId2 = symbolResultWatcher.symbolResult()->taskId();
|
||
QVERIFY2((taskId2.isNull() == false), "SymbolDictionary: taskId failed");
|
||
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Point), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryFetchSymbol2()
|
||
{
|
||
checkSymbolDictionaryLoad();
|
||
auto &dict = AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
if (m_d->m_symbologyType != AdvancedSymbology::SymbologyType::MIL2525D)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// find some PointSymbols:
|
||
int counter = 0;
|
||
|
||
const QStringList sidcs = AdvancedSymbology::listOfPointSidcs_Internal();
|
||
|
||
for (const auto &sidc : sidcs)
|
||
{
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.fetchSymbol(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
const QUuid &taskId2 = symbolResultWatcher.symbolResult()->taskId();
|
||
QVERIFY2((taskId2.isNull() == false), "SymbolDictionary: taskId failed");
|
||
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Point), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
++counter;
|
||
}
|
||
|
||
QVERIFY2((counter == sidcs.size()), "SymbolDictionary: something failed");
|
||
qWarning() << " counter=" << counter;
|
||
}
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryFetchSymbolAll()
|
||
{
|
||
checkSymbolDictionaryLoad();
|
||
auto &dict = AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
// add ExtraSymbols:
|
||
const QString extraSymbolDir(QLatin1String(":/advancedSymbology/CivilSymbols"));
|
||
dict.addEtsSymbols(extraSymbolDir);
|
||
|
||
|
||
// fetch all Extra symbols:
|
||
int counter = 0;
|
||
|
||
const QStringList extraSymbolSidcs = dict.etsSymbols();
|
||
qCritical() << " extraSymbolSidcs.size = " << extraSymbolSidcs.size();
|
||
|
||
for (const auto &sidc : extraSymbolSidcs)
|
||
{
|
||
AdvancedSymbology::SymbolResultWatcher *symbolResultWatcher = new AdvancedSymbology::SymbolResultWatcher(this);
|
||
connect(symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady, this, [sidc, &counter, symbolResultWatcher]()
|
||
{
|
||
// lambda:
|
||
// qCritical() << " sidc=" << sidc;
|
||
QVERIFY2((symbolResultWatcher->resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher->symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
// Note: TaskId is null (esri not needed)
|
||
QSharedPointer<AdvancedSymbology::SymbolResult> symResult = symbolResultWatcher->symbolResult();
|
||
|
||
QVERIFY2((symResult), "SymbolDictionary: symResult failed");
|
||
QVERIFY2((symResult->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
QVERIFY2((symResult->symbolImage().image().size().isEmpty() == false), "SymbolDictionary: symbolImage failed");
|
||
++counter;
|
||
});
|
||
|
||
if (1) {
|
||
symbolResultWatcher->setSymbolResult(dict.fetchSymbol(sidc));
|
||
}
|
||
|
||
if (0) {
|
||
symbolResultWatcher->setSymbolResult(dict.findPreview(sidc));
|
||
}
|
||
|
||
if (0) {
|
||
AdvancedSymbology::SymbolDataToRender symDataToRender;
|
||
symDataToRender.sidc = sidc;
|
||
symbolResultWatcher->setSymbolResult(dict.findImage(symDataToRender));
|
||
}
|
||
}
|
||
|
||
QTRY_VERIFY2_WITH_TIMEOUT((counter == extraSymbolSidcs.size()), "SymbolDictionary: something failed", 20000);
|
||
qWarning() << " counter=" << counter;
|
||
}
|
||
|
||
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryExtraDirFetchSymbol()
|
||
{
|
||
checkSymbolDictionaryLoad();
|
||
auto &dict = AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
const QString extraSymbolDir(QLatin1String(":/advancedSymbology/CivilSymbols"));
|
||
|
||
int addedFiles = dict.addEtsSymbols(extraSymbolDir);
|
||
int extraSymbolCount = dict.etsSymbolCount();
|
||
|
||
qWarning() << "addedFiles=" << addedFiles;
|
||
qWarning() << "extraSymbolCount=" << extraSymbolCount;
|
||
|
||
QVERIFY2((addedFiles > 500), "SymbolDictionary: addExtraSymbols failed");
|
||
QVERIFY2((addedFiles == extraSymbolCount), "SymbolDictionary: extraSymbolCount failed");
|
||
|
||
// find:
|
||
{
|
||
const QString sidc( QLatin1String("DOES_NOT_EXISTS") );
|
||
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.fetchSymbol(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
|
||
// Here is a notFoundSymbolResult: ('?') returned.
|
||
// Because it´s not really correct, the symbolImage is marked as 'not valid':
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().isValid() == false), "SymbolDictionary: symbolImage should be invalid (notFoundSymbolResult: '?')");
|
||
}
|
||
|
||
// find:
|
||
{
|
||
const QString sidc = AdvancedSymbology::SidcCodec::encodeCivilEts("FzSanKrad"); // FzSanKrad.gif
|
||
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.fetchSymbol(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
// inspect result:
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Point), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
}
|
||
}
|
||
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryFetchSymbolStress()
|
||
{
|
||
return; // just for manual usage
|
||
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::None)
|
||
return;
|
||
|
||
checkSymbolDictionaryLoad();
|
||
auto &dict = AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
QStringList sidcs = AdvancedSymbology::listOfPointSidcs_Internal();
|
||
QString sidc = sidcs.first();
|
||
|
||
// AdvancedSymbology::SymbolResultWatcher *symbolResultWatcher =
|
||
// new AdvancedSymbology::SymbolResultWatcher(this);
|
||
|
||
int counter = 0;
|
||
|
||
QTimer *timer = new QTimer(this);
|
||
timer->setInterval(1);
|
||
connect(timer, &QTimer::timeout, this, [timer, &dict, sidc, &counter]()
|
||
{
|
||
if ((++counter%100) == 0)
|
||
qCritical() << " timeout... counter = " << counter;
|
||
|
||
QSharedPointer<AdvancedSymbology::SymbolResult> result = dict.fetchSymbol(sidc);
|
||
// symbolResultWatcher->setSymbolResult(dict.fetchSymbol(sidc));
|
||
|
||
if (counter == 10000)
|
||
timer->stop();
|
||
});
|
||
|
||
timer->start();
|
||
|
||
QTRY_VERIFY_WITH_TIMEOUT(!timer->isActive(), 60 * 1000);
|
||
}
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryBulkRenderer()
|
||
{
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::None)
|
||
return;
|
||
|
||
checkSymbolDictionaryLoad();
|
||
|
||
QStringList pointSidcs = AdvancedSymbology::listOfPointSidcs_Internal();
|
||
QStringList lineSidcs = AdvancedSymbology::listOfLineSidcs_Internal();
|
||
|
||
|
||
{
|
||
AdvancedSymbology::BulkRendererFindBaseSymbol bulkRenderer(m_d->m_symbologyType);
|
||
|
||
QSignalSpy spy(&bulkRenderer, &AdvancedSymbology::BulkRendererFindBaseSymbol::resultsReady);
|
||
|
||
bulkRenderer.addRequest(pointSidcs.first());
|
||
bulkRenderer.addRequest(lineSidcs.first());
|
||
bulkRenderer.addRequest(lineSidcs.first());
|
||
bulkRenderer.addRequest(lineSidcs.first());
|
||
bulkRenderer.addRequest(lineSidcs.first());
|
||
bulkRenderer.addRequest(lineSidcs.first());
|
||
bulkRenderer.addRequest(lineSidcs.first());
|
||
bulkRenderer.addRequest(lineSidcs.first());
|
||
bulkRenderer.addRequest(lineSidcs.first());
|
||
bulkRenderer.addRequest(lineSidcs.first());
|
||
bulkRenderer.addRequest(lineSidcs.first());
|
||
|
||
bulkRenderer.run(); // <--- run
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "BulkRenderer: resultsReady-signal failed");
|
||
|
||
int successfullCnt = 0;
|
||
AdvancedSymbology::BulkRendererFindBaseSymbol::RequestResultVector rrVec = bulkRenderer.results();
|
||
for (const AdvancedSymbology::BulkRendererFindBaseSymbol::RequestResult &rr : std::as_const(rrVec))
|
||
{
|
||
if (rr.second
|
||
&& rr.second->symbolResult()
|
||
&& rr.second->symbolResult()->isResultReady())
|
||
{
|
||
const QImage img = rr.second->symbolResult()->symbolImage().image();
|
||
if (img.width() > 10)
|
||
++successfullCnt;
|
||
// const QString sidc = rr.first; qCritical() << " sidc= '" << sidc << "'" << " img.size(): " << img.size();
|
||
// img.save(QStringLiteral("/tmp/img.png"));
|
||
}
|
||
} // for
|
||
|
||
QVERIFY2((successfullCnt == rrVec.size()), "BulkRenderer: size comparision failed");
|
||
|
||
bulkRenderer.reset();
|
||
}
|
||
}
|
||
|
||
void fetchSymbolGeoType(const AdvancedSymbology::SymbolDictionary &dict,
|
||
const QString &sidc,
|
||
AdvancedSymbology::GeometryType geoType)
|
||
{
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == false), "SymbolDictionary: resultIsValid failed");
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.fetchSymbol(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
|
||
|
||
// inspect result:
|
||
QSharedPointer<AdvancedSymbology::SymbolResult> symResult = symbolResultWatcher.symbolResult();
|
||
QVERIFY2((symResult.isNull() == false), "SymbolDictionary: isNull failed");
|
||
|
||
QVERIFY2((symResult->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
|
||
if (symResult->geometryType() != geoType)
|
||
{
|
||
qWarning() << " sidc=" << sidc << "'" << ", geometryType, failed, geoType="<< (int)symResult->geometryType();
|
||
}
|
||
|
||
QVERIFY2((symResult->geometryType() == geoType), "SymbolDictionary: geometryType failed");
|
||
}
|
||
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryFindImage()
|
||
{
|
||
AdvancedSymbology::SymbolDictionary &dict =
|
||
AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
// SymbologyType::None -> no esriDict -> immediately loaded:
|
||
// ! SymbologyType::None -> esriDict -> load...
|
||
|
||
if (!dict.isLoaded())
|
||
{
|
||
dict.load();
|
||
QTRY_VERIFY2((dict.isLoaded() == true), "SymbolDictionary: isLoaded failed");
|
||
}
|
||
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::MIL2525D)
|
||
{
|
||
QStringList sidcs = AdvancedSymbology::listOfPointSidcs_Internal();
|
||
|
||
int counter = 0;
|
||
|
||
//
|
||
// SinglePoint:
|
||
//
|
||
for (const QString &sidc : std::as_const(sidcs))
|
||
{
|
||
SituationMap::SymbolData symData;
|
||
AdvancedSymbology::SymbolDataToRender symDataToRender = symData.getDefaultRenderData();
|
||
symDataToRender.sidc = sidc;
|
||
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.findImage(symDataToRender));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
const QUuid &taskId2 = symbolResultWatcher.symbolResult()->taskId();
|
||
QVERIFY2((taskId2.isNull() == false), "SymbolDictionary: taskId failed");
|
||
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Point), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
counter++;
|
||
}
|
||
QVERIFY2((counter == sidcs.size()), "SymbolDictionary: something failed");
|
||
qWarning() << " counter1=" << counter;
|
||
|
||
//
|
||
// Line:
|
||
//
|
||
counter = 0;
|
||
|
||
sidcs = AdvancedSymbology::listOfLineSidcs_Internal();
|
||
|
||
for (const QString &sidc : std::as_const(sidcs))
|
||
{
|
||
qWarning() << " sidc=" << sidc;
|
||
SituationMap::SymbolData symData;
|
||
AdvancedSymbology::SymbolDataToRender symDataToRender = symData.getDefaultRenderData();
|
||
symDataToRender.sidc = sidc;
|
||
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.findImage(symDataToRender));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
// TaskId is skipped here :
|
||
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Polyline), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
counter++;
|
||
}
|
||
QVERIFY2((counter == sidcs.size()), "SymbolDictionary: something failed");
|
||
qWarning() << " counter2=" << counter;
|
||
|
||
//
|
||
// Area:
|
||
//
|
||
counter = 0;
|
||
|
||
sidcs = AdvancedSymbology::listOfAreaSidcs_Internal();
|
||
|
||
for (const QString &sidc : std::as_const(sidcs))
|
||
{
|
||
// qWarning() << " sidc=" << sidc;
|
||
SituationMap::SymbolData symData;
|
||
AdvancedSymbology::SymbolDataToRender symDataToRender = symData.getDefaultRenderData();
|
||
symDataToRender.sidc = sidc;
|
||
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.findImage(symDataToRender));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
// TaskId is skipped here :
|
||
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Polygon), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
counter++;
|
||
}
|
||
|
||
QVERIFY2((counter == sidcs.size()), "SymbolDictionary: something failed");
|
||
qWarning() << " counter3=" << counter;
|
||
}
|
||
|
||
}
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryFindPreview()
|
||
{
|
||
AdvancedSymbology::SymbolDictionary &dict =
|
||
AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
// SymbologyType::None -> no esriDict -> immediately loaded:
|
||
// ! SymbologyType::None -> esriDict -> load...
|
||
|
||
dict.load();
|
||
QTRY_VERIFY2((dict.isLoaded() == true), "SymbolDictionary: isLoaded failed");
|
||
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::MIL2525D)
|
||
{
|
||
QStringList sidcs = AdvancedSymbology::listOfPointSidcs_Internal();
|
||
|
||
//
|
||
// SinglePoint:
|
||
//
|
||
int counter = 0;
|
||
for (const QString &sidc : std::as_const(sidcs))
|
||
{
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.findPreview(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
const QUuid &taskId2 = symbolResultWatcher.symbolResult()->taskId();
|
||
QVERIFY2((taskId2.isNull() == false), "SymbolDictionary: taskId failed");
|
||
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Point), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
counter++;
|
||
}
|
||
QVERIFY2((counter == sidcs.size()), "SymbolDictionary: something failed");
|
||
qWarning() << " counter1=" << counter;
|
||
|
||
//
|
||
// Line:
|
||
//
|
||
counter = 0;
|
||
|
||
sidcs = AdvancedSymbology::listOfLineSidcs_Internal();
|
||
|
||
for (const QString &sidc : std::as_const(sidcs))
|
||
{
|
||
// qWarning() << " sidc=" << sidc;
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.findPreview(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
// TaskId is slipped here :
|
||
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Polyline), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
counter++;
|
||
}
|
||
QVERIFY2((counter == sidcs.size()), "SymbolDictionary: something failed");
|
||
qWarning() << " counter2=" << counter;
|
||
|
||
//
|
||
// Area:
|
||
//
|
||
counter = 0;
|
||
|
||
sidcs = AdvancedSymbology::listOfAreaSidcs_Internal();
|
||
|
||
for (const QString &sidc : std::as_const(sidcs))
|
||
{
|
||
// qWarning() << " sidc=" << sidc;
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.findPreview(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
// TaskId is slipped here :
|
||
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Polygon), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
counter++;
|
||
}
|
||
QVERIFY2((counter == sidcs.size()), "SymbolDictionary: something failed");
|
||
qWarning() << " counter3=" << counter;
|
||
|
||
}
|
||
}
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryFindBaseSymbol()
|
||
{
|
||
AdvancedSymbology::SymbolDictionary &dict =
|
||
AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
// SymbologyType::None -> no esriDict -> immediately loaded:
|
||
// ! SymbologyType::None -> esriDict -> load...
|
||
|
||
dict.load();
|
||
QTRY_VERIFY2((dict.isLoaded() == true), "SymbolDictionary: isLoaded failed");
|
||
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::MIL2525D)
|
||
{
|
||
//
|
||
// SinglePoint:
|
||
//
|
||
QStringList sidcs = AdvancedSymbology::listOfPointSidcs_Internal();
|
||
|
||
int counter = 0;
|
||
for (const QString &sidc : std::as_const(sidcs))
|
||
{
|
||
// qWarning() << " sidc=" << sidc;
|
||
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.findBaseSymbol(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
// TaskId is skipped here
|
||
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Point), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
counter++;
|
||
}
|
||
|
||
QVERIFY2((counter == sidcs.size()), "SymbolDictionary: something failed");
|
||
qWarning() << " counter1=" << counter;
|
||
|
||
//
|
||
// Line:
|
||
//
|
||
counter = 0;
|
||
|
||
sidcs = AdvancedSymbology::listOfLineSidcs_Internal();
|
||
|
||
for (const QString &sidc : std::as_const(sidcs))
|
||
{
|
||
// qWarning() << " sidc=" << sidc;
|
||
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.findBaseSymbol(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
// TaskId is skipped here:
|
||
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Polyline), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
counter++;
|
||
}
|
||
QVERIFY2((counter == sidcs.size()), "SymbolDictionary: something failed");
|
||
qWarning() << " counter2=" << counter;
|
||
|
||
|
||
//
|
||
// Area:
|
||
//
|
||
counter = 0;
|
||
|
||
sidcs = AdvancedSymbology::listOfAreaSidcs_Internal();
|
||
|
||
for (const QString &sidc : std::as_const(sidcs))
|
||
{
|
||
// qWarning() << " sidc=" << sidc;
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.findPreview(sidc));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: resultIsValid failed");
|
||
|
||
// TaskId is slipped here :
|
||
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Polygon), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
counter++;
|
||
}
|
||
QVERIFY2((counter == sidcs.size()), "SymbolDictionary: something failed");
|
||
qWarning() << " counter3=" << counter;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void SitMapUnitTest::checkSymbolDictionaryGctString()
|
||
{
|
||
AdvancedSymbology::SymbolDictionary &dict =
|
||
AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
// SymbologyType::None -> no esriDict -> immediately loaded:
|
||
// ! SymbologyType::None -> esriDict -> load...
|
||
|
||
dict.load();
|
||
QTRY_VERIFY2((dict.isLoaded() == true), "SymbolDictionary: isLoaded failed");
|
||
|
||
// search:
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::MIL2525D)
|
||
{
|
||
QStringList slGctLine;
|
||
QStringList slGctArea;
|
||
{
|
||
slGctLine += QLatin1String("gct_arrow");
|
||
|
||
slGctLine += QLatin1String("gct_arrow_with_offset");
|
||
slGctLine += QLatin1String("gct_parallel_lines");
|
||
slGctLine += QLatin1String("gct_parallel_lines_mid_line");
|
||
slGctLine += QLatin1String("gct_parallel_lines_with_ticks");
|
||
slGctLine += QLatin1String("gct_two_line");
|
||
slGctLine += QLatin1String("gct_arrow_with_tail");
|
||
slGctLine += QLatin1String("gct_open_triangle");
|
||
|
||
slGctLine += QLatin1String("gct_freehand_line");
|
||
slGctLine += QLatin1String("gct_freehand_arrow");
|
||
slGctLine += QLatin1String("gct_freehand_reverse_arrow");
|
||
slGctLine += QLatin1String("gct_freehand_u");
|
||
|
||
slGctLine += QLatin1String("gct_circle");
|
||
slGctLine += QLatin1String("gct_hook");
|
||
slGctLine += QLatin1String("gct_horns");
|
||
slGctLine += QLatin1String("gct_parallel_lines_with_ticks");
|
||
slGctLine += QLatin1String("gct_t");
|
||
slGctLine += QLatin1String("gct_triple_arrow");
|
||
slGctLine += QLatin1String("gct_two_line_3_or_4_pt");
|
||
slGctLine += QLatin1String("gct_u_or_t_shape");
|
||
|
||
slGctArea += QLatin1String("gct_rectangular_1_pt");
|
||
slGctArea += QLatin1String("gct_circular");
|
||
slGctArea += QLatin1String("gct_rectangular");
|
||
slGctArea += QLatin1String("gct_parallel_lines_with_ticks");
|
||
}
|
||
|
||
unsigned int symbolCounter = 0;
|
||
unsigned int unexpectedCounter = 0;
|
||
unsigned int emptyCounter = 0;
|
||
|
||
AdvancedSymbology::SymbolDictionaryImpl &dictImpl =
|
||
static_cast<AdvancedSymbology::SymbolDictionaryImpl&>(dict);
|
||
|
||
const AdvancedSymbology::SidcCodec::SidcHashTable<AdvancedSymbology::SymbolProperties> &allSymbolProps =
|
||
dictImpl.getEsriDictionaryProcessor()->baseSymbolCodeToSymbolPropertyTable();
|
||
|
||
|
||
for (const AdvancedSymbology::SymbolProperties &prop : std::as_const(allSymbolProps))
|
||
{
|
||
QString baseKey = prop.key();
|
||
if (baseKey.isEmpty())
|
||
continue;
|
||
|
||
++symbolCounter;
|
||
const QString & gctString = prop.gctString();
|
||
if (! gctString.isEmpty())
|
||
{
|
||
|
||
switch (prop.geometryType())
|
||
{
|
||
case AdvancedSymbology::GeometryType::Point:
|
||
{
|
||
if (! gctString.isEmpty())
|
||
{
|
||
++unexpectedCounter;
|
||
qDebug() << " Point feature has none empty gctString, baseKey=" << baseKey << " gctString =" << gctString << endl;
|
||
continue;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case AdvancedSymbology::GeometryType::Polyline:
|
||
{
|
||
if (! slGctLine.contains(gctString) )
|
||
{
|
||
++unexpectedCounter;
|
||
qDebug() << " Unexpected gctString for line symbol found, baseKey=" << baseKey << " gctString =" << gctString << endl;
|
||
}
|
||
continue;
|
||
}
|
||
break;
|
||
|
||
case AdvancedSymbology::GeometryType::Polygon:
|
||
{
|
||
if (! slGctArea.contains(gctString) )
|
||
{
|
||
++unexpectedCounter;
|
||
qDebug() << " Unexpected gctString for area symbol found, baseKey=" << baseKey << " gctString =" << gctString << endl;
|
||
}
|
||
continue;
|
||
}
|
||
break;
|
||
|
||
default : break;
|
||
} // switch
|
||
}
|
||
else
|
||
{
|
||
switch (prop.geometryType())
|
||
{
|
||
case AdvancedSymbology::GeometryType::Polyline: qDebug() << " Empty gctString found for line symbol, baseKey=" << baseKey << endl; ++emptyCounter; break;
|
||
case AdvancedSymbology::GeometryType::Polygon : qDebug() << " Empty gctString found for area symbol, baseKey=" << baseKey << endl; ++emptyCounter; break;
|
||
case AdvancedSymbology::GeometryType::Point :
|
||
default : break;
|
||
}
|
||
}
|
||
} // foreach
|
||
|
||
qDebug() << "Checked symbols: " << symbolCounter << " empty gctString at line or areals: " << emptyCounter << endl;
|
||
|
||
static char msg[128];
|
||
sprintf( msg, "%d unexpected gctStrings found.", unexpectedCounter);
|
||
QVERIFY2( (unexpectedCounter == 0), msg );
|
||
|
||
}
|
||
return;
|
||
|
||
} // void SitMapUnitTest::checkSymbolDictionaryGctString()
|
||
|
||
|
||
void SitMapUnitTest::checkSymbolDictionarySymbolPropertyImage()
|
||
{
|
||
AdvancedSymbology::SymbolDictionary &dict =
|
||
AdvancedSymbology::SymbolDictionary::dictionary(m_d->m_symbologyType);
|
||
|
||
// SymbologyType::None -> no esriDict -> immediately loaded:
|
||
// ! SymbologyType::None -> esriDict -> load...
|
||
|
||
dict.load();
|
||
QTRY_VERIFY2((dict.isLoaded() == true), "SymbolDictionary: isLoaded failed");
|
||
|
||
if (m_d->m_symbologyType == AdvancedSymbology::SymbologyType::MIL2525D)
|
||
{
|
||
AdvancedSymbology::SymbolProperties symProps;
|
||
symProps.setOriginalKey(QLatin1String("25270100")); // obstacle / building
|
||
|
||
|
||
AdvancedSymbology::SymbolResultWatcher symbolResultWatcher;
|
||
QSignalSpy spy(&symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady);
|
||
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == false), "SymbolDictionary: resultIsValid failed");
|
||
|
||
symbolResultWatcher.setSymbolResult(dict.symbolPropertyImage(symProps));
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: symbolPropertyImage resultIsValid failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult().isNull() == false), "SymbolDictionary: symbolPropertyImage symbolResult failed");
|
||
|
||
QTRY_VERIFY2((spy.count() == 1), "SymbolDictionary: symbolPropertyImage resultReady-signal failed");
|
||
QVERIFY2((symbolResultWatcher.resultIsValid() == true), "SymbolDictionary: symbolPropertyImage resultIsValid failed");
|
||
|
||
// inspect result:
|
||
// QVERIFY2((symbolResultWatcher.symbolResult()->geometryType() == AdvancedSymbology::GeometryType::Polygon), "SymbolDictionary: geometryType failed");
|
||
QVERIFY2((symbolResultWatcher.symbolResult()->symbolImage().image().isNull() == false), "SymbolDictionary: symbolImage failed");
|
||
QImage img = symbolResultWatcher.symbolResult()->symbolImage().image();
|
||
img.save(QLatin1String("/tmp/unitTest.png"));
|
||
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
void SitMapUnitTest::checkMapSettings()
|
||
{
|
||
if (1)
|
||
{
|
||
// use absolute path:
|
||
// SituationMap::MapSettings ms(QLatin1String("/shd/CTC/TOOLS/TDS/TDS-build-product/bin/situation_map_defaults.ini"));
|
||
|
||
QString initFilePath = NGL::findFile(NGL::FileType::ConfigFile, QStringLiteral("situation_map_defaults.ini"));
|
||
|
||
if (initFilePath.isEmpty())
|
||
{
|
||
FATAL_LOG(m_logger) << " initFilePath " << initFilePath;
|
||
abort();
|
||
}
|
||
SituationMap::MapSettings ms(initFilePath);
|
||
|
||
QVERIFY2(ms.hasErrors() == false, "hasError failed");
|
||
QVERIFY2(ms.exists() == true, "exists failed");
|
||
QVERIFY2(ms.accessError() == false, "accessError failed");
|
||
QVERIFY2(ms.formatError() == false, "formatError failed");
|
||
|
||
std::cerr << " operator<<: \n" << ms << std::endl;
|
||
|
||
SituationMap::GridType gridType = ms.gridType();
|
||
QVERIFY2(gridType == SituationMap::GridType::MGRS, "gridType failed");
|
||
}
|
||
}
|
||
|
||
|
||
void SitMapUnitTest::checkMatrix2D()
|
||
{
|
||
SituationMap::MathUtils::Matrix2D matrix;
|
||
|
||
matrix.setToIdentity();
|
||
|
||
QVERIFY2( ( (matrix(0,0) == 1.0) && (matrix(0,1) == 0.0) && (matrix(0,2) == 0.0) &&
|
||
(matrix(1,0) == 0.0) && (matrix(1,1) == 1.0) && (matrix(1,2) == 0.0) &&
|
||
(matrix(2,0) == 0.0) && (matrix(2,1) == 0.0) && (matrix(2,2) == 1.0) ), "setToIdentity failed" );
|
||
|
||
|
||
SituationMap::MathUtils::Matrix2D matrix2;
|
||
|
||
QVERIFY2( ( (matrix2(0,0) == 1.0) && (matrix2(0,1) == 0.0) && (matrix2(0,2) == 0.0) &&
|
||
(matrix2(1,0) == 0.0) && (matrix2(1,1) == 1.0) && (matrix2(1,2) == 0.0) &&
|
||
(matrix2(2,0) == 0.0) && (matrix2(2,1) == 0.0) && (matrix2(2,2) == 1.0) ), "standard constructor does not set the identity matrix");
|
||
|
||
matrix2(0,0) = 11; matrix2(0,1) = 12; matrix2(0,2) = 13;
|
||
matrix2(1,0) = 21; matrix2(1,1) = 22; matrix2(1,2) = 23;
|
||
matrix2(2,0) = 31; matrix2(2,1) = 32; matrix2(2,2) = 33;
|
||
|
||
QVERIFY2( ( (matrix2(0,0) == 11) && (matrix2(0,1) == 12) && (matrix2(0,2) == 13) &&
|
||
(matrix2(1,0) == 21) && (matrix2(1,1) == 22) && (matrix2(1,2) == 23) &&
|
||
(matrix2(2,0) == 31) && (matrix2(2,1) == 32) && (matrix2(2,2) == 33) ), "set matrix elements failed");
|
||
|
||
SituationMap::MathUtils::Matrix2D matrix3(matrix2);
|
||
|
||
QVERIFY2( ( (matrix3(0,0) == 11) && (matrix3(0,1) == 12) && (matrix3(0,2) == 13) &&
|
||
(matrix3(1,0) == 21) && (matrix3(1,1) == 22) && (matrix3(1,2) == 23) &&
|
||
(matrix3(2,0) == 31) && (matrix3(2,1) == 32) && (matrix3(2,2) == 33) ), "copy constructor failed");
|
||
|
||
matrix = matrix2;
|
||
|
||
QVERIFY2( ( (matrix(0,0) == 11) && (matrix(0,1) == 12) && (matrix(0,2) == 13) &&
|
||
(matrix(1,0) == 21) && (matrix(1,1) == 22) && (matrix(1,2) == 23) &&
|
||
(matrix(2,0) == 31) && (matrix(2,1) == 32) && (matrix(2,2) == 33) ), "assign operator failed");
|
||
|
||
matrix.setToIdentity();
|
||
matrix.putTranslation(QPointF(5,7));
|
||
QPointF p = matrix.apply(QPointF(2,1));
|
||
|
||
QVERIFY2( ((p.x() == 7) && (p.y() == 8)), "putTranslation failed");
|
||
|
||
matrix.setToIdentity();
|
||
matrix.putScale(QPointF(2,3));
|
||
p = matrix.apply(QPointF(2,1));
|
||
|
||
QVERIFY2( ((p.x() == 4) && (p.y() == 3)), "putScale failed");
|
||
|
||
matrix.setToIdentity();
|
||
matrix.putScale(QPointF(2,2));
|
||
matrix.putTranslation(QPointF(5,7));
|
||
p = matrix.apply(QPointF(2,1));
|
||
QVERIFY2( ((p.x() == 9) && (p.y() == 9)), "putScale combined with putTranslate failed");
|
||
|
||
matrix.setToIdentity();
|
||
matrix.putRotate(QPointF(0,1));
|
||
p = matrix.apply(QPointF(2,1));
|
||
|
||
QVERIFY2( ((p.x() == 1) && (p.y() == -2)), "putRotated failed");
|
||
|
||
matrix.setToIdentity();
|
||
matrix.putRotate(QPointF(0.5,0.8660254)); // 60 degrees
|
||
p = matrix.apply(QPointF(1,0));
|
||
|
||
QVERIFY2( ((int(p.x()*10) == 5) && (int(p.y()*1000000) == -866025)), "putRotated 60 degrees failed");
|
||
|
||
matrix.setToIdentity();
|
||
matrix.putTranslation(QPointF(-5,-7));
|
||
matrix.putRotate(QPointF(0,1));
|
||
matrix.putTranslation(QPointF(5,7));
|
||
p = matrix.apply(QPointF(7,8));
|
||
|
||
QVERIFY2( ((p.x() == 6) && (p.y() == 5)), "putRotated combined with putTranslate failed");
|
||
|
||
matrix.setToIdentity();
|
||
matrix.putTranslation(QPointF(-5,-7));
|
||
matrix.putRotate(QPointF(0.5,0.8660254)); // 60 degrees
|
||
matrix.putTranslation(QPointF(5,7));
|
||
p = matrix.apply(QPointF(6,7));
|
||
|
||
QVERIFY2( ((int(p.x()*10) == 55) && (int(p.y()*10000000) == 61339746)), "putRotated 60 degrees combined with putTranslate failed");
|
||
|
||
} // SitMapUnitTtest::checkMatrix2D()
|
||
|
||
|
||
//-------------------------------------------------------------------------------------------------------
|
||
|
||
#include "unit_test.moc"
|