Files
qt5-legatus-legacy/Lts/Viewer/SituationMap/ModuleTests/situation_map_test_main.cpp
T
2026-08-13 18:33:10 +02:00

3518 lines
130 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @RDE_HEADER@
* Moduletest
* $Id$
* $HeadURL$
* $Author$
*/
#include "situation_map_test_main.h"
#include <NGLLogger/INGLLogger.h>
#include <nglapplication/nglapplication.h>
#include "sit_map.h"
#include <cmath>
#include <Map/map.h>
#include <Map/map_notifier.h>
#include <Map/situation_map_utils.h>
#include <Map/object_factory.h>
#include <Map/coord_translation_functor.h>
#include <MapImpl/overlay_handler_impl.h>
#include <GeometryModel/geometry_model_factory.h>
#include <MapImpl/map_impl.h>
#include <MapImpl/layer_factory_impl.h>
#include <MapImpl/location_to_elevation_bulk.h>
#include <MapObjectsImpl/building_outline_impl.h>
#include <MapObjectsImpl/biological_agent_impl.h>
#include <MapObjectsImpl/chemical_agent_impl.h>
#include <MapObjectsImpl/danger_area_impl.h>
#include <MapObjectsImpl/participant_impl.h>
#include <Symbology/sidc_codec.h>
#include <GraphicalObjects/graphical_object_ellipse.h>
#include <GraphicalObjects/graphical_object_path.h>
//#include <GraphicalObjects/graphical_object_multi_path.h>
#include <GraphicalObjects/tactical_appearance.h>
#include <Symbology/sidc_codec.h>
#include <Common/exception.h>
#include <Rubberbands/rubberband_factory.h>
//ESRI
#include <arcgis/Map.h>
#include <arcgis/GraphicsOverlayListModel.h>
#include <arcgis/Point.h>
#include <arcgis/GeometryEngine.h>
#include <arcgis/PictureMarkerSymbol.h>
//#include <arcgis/CoordinateConversion.h>
//Qt
#include <QCoreApplication>
#include <QGraphicsView>
#include <QTimer>
#include <QtTest/QTest>
#include <QtTest/QSignalSpy>
#include <QDebug>
#include <iostream>
#include <LtsCoordTrans/lts_coord_trans.h>
static LtsCoordTrans::UtmCoordinate s_basePoint;
const int timeToDelay = 0; // suggestion: 2000
using namespace SituationMap; // 'enable' operator<< (QPointF etc.)
bool fuzzyCompare(const Point3D &p1, const Point3D &p2)
{
const Point3D &diff = p1 - p2;
return (diff.x() < 0.00001) &&
(diff.y() < 0.00001) &&
(diff.z() < 0.00001);
}
bool fuzzyCompare(const PositionCont &p1, const PositionCont &p2)
{
if (p1.size() != p2.size())
return false;
for(int i=0; i<p1.size(); ++i)
{
if (!fuzzyCompare(p1[i], p2[i]))
return false;
}
return true;
}
//-------------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
// QCoreApplication app(argc, argv);
NGLApplication app(argc, argv);
app.createLogger("SitMapModuleTest", "log4cxxSituationMapModuleTests.props");
// under windows for ArcGIS 10.2.6 and higher
#ifdef Q_OS_WIN
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
#endif
QDir::setSearchPaths(QLatin1String("icon"), QStringList(QLatin1String(":/icons/light")));
s_basePoint = LtsCoordTrans::UtmCoordinate::fromMgrs(QLatin1String("32UMD000000000000"));
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] app6D" << std::endl
<< " e.g " << argv[0] << " [QTest options] [testfunction] app6B" << std::endl
<< " e.g " << argv[0] << " [QTest options] [testfunction] mil2525D" << std::endl
<< " e.g " << argv[0] << " [QTest options] [testfunction] mil2525C" << 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("app6B"), Qt::CaseInsensitive) == 0)
symbologyType = AdvancedSymbology::SymbologyType::APP6B;
else if (strSymType.compare(QLatin1String("app6D"), Qt::CaseInsensitive) == 0)
symbologyType = AdvancedSymbology::SymbologyType::APP6D;
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;
argc -= 1; // remove last argument for QTest::qExec
// Init the logger
SituationMapTestsMain *tc = new SituationMapTestsMain(symbologyType);
int retCode = QTest::qExec(tc, argc, argv);
std::cout << " symbologyType = " << symbologyType
<< std::endl;
delete tc;
return retCode;
}
class SituationMapTestsMain::Private
{
public:
Private()
{}
~Private()
{}
// OWN data:
AdvancedSymbology::SymbologyType m_symbologyType;
SitMap *m_sitMap = nullptr;
SituationMap::Map *m_map = nullptr;
QPointF m_geoOff;
int m_basemapCountRef = 0;
}; // class Private
//-----------------------------------------------------------------------------
SituationMapTestsMain::SituationMapTestsMain(AdvancedSymbology::SymbologyType symbologyType)
: m_logger(SituationMap::getLogger("SituationMapTestsMain"))
, d(new Private)
{
d->m_symbologyType = symbologyType;
}
SituationMapTestsMain::~SituationMapTestsMain()
{
delete d;
}
//-------------------------------------------------------------------------------------------------------
void SituationMapTestsMain::initTestCase()
{
DEBUG_LOG(m_logger) << LOGFUNCTION;
if (d->m_sitMap)
d->m_sitMap->close();
delete d->m_sitMap;
LayerFactoryImpl::setForceCreationOfGraphicsOverlay(false); // false => createLayerOnDemand
d->m_sitMap = new SitMap(d->m_symbologyType);
QVERIFY2(d->m_sitMap, "Initialisation of SituationMap failed");
connect(d->m_sitMap, &SitMap::mapReadyAndSymbolDictionaryLoaded, [&]()
{
// INFO_LOG(m_logger) << LOGFUNCTION << " got mapReady ";
});
d->m_sitMap->setMinimumWidth(1100);
d->m_sitMap->setMinimumHeight(1100);
d->m_sitMap->show();
d->m_map = d->m_sitMap->map();
d->m_geoOff = QPointF( s_basePoint.x,s_basePoint.y );
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
QString msg = QStringLiteral("layerFactory: count failed (%1)").arg(layerFac.count());
QVERIFY2((layerFac.count() >= 3) && (layerFac.count() <= 16) , msg.toStdString().c_str());
QSignalSpy spy(d->m_sitMap, &SitMap::mapReady);
QTRY_VERIFY(d->m_sitMap->isReady());
QTRY_VERIFY2(spy.count() == 1, "mapReadyEmitted not emitted");
QVERIFY2(d->m_sitMap->isReady() , "map is NOT READY");
// Wait also for Dictionary (since it´s done within a WorkerThread)
AdvancedSymbology::SymbolDictionary &dict = d->m_map->symbolDictionary();
QTRY_VERIFY2(dict.isLoaded(), "dict is NOT Loaded");
QTest::qWait(1000);
}
void SituationMapTestsMain::checkMapReady()
{
if (! d->m_sitMap->isReady())
{
QSignalSpy spy(d->m_sitMap, &SitMap::mapReadyAndSymbolDictionaryLoaded);
QTRY_VERIFY2(spy.count() > 0, "mapReady not received");
}
}
void SituationMapTestsMain::checkMapNotifier()
{
QPointer<MapNotifier> mapNotifier = d->m_sitMap->map()->createMapNotifier();
QVERIFY2(mapNotifier.isNull() == false, "no MapNotifier");
QSignalSpy spy1(mapNotifier.data(), &MapNotifier::mapReady);
QSignalSpy spy2(mapNotifier.data(), &MapNotifier::mapReadyAndSymbolDictionaryLoaded);
mapNotifier->run();
QTRY_VERIFY2(spy1.count() == 1, "mapReady not received");
QTRY_VERIFY2(spy2.count() == 1, "mapReadyAndSymbolDictionaryLoaded not received");
}
void SituationMapTestsMain::checkCenter()
{
QTest::qWait(timeToDelay);
int scaleSAVE = d->m_map->scale();
QPointF centerSAVE = d->m_map->centerPoint();
{
// real check:
QPointF center(LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UMD9100084500"))); // Bremen motorway junction
// double xmin, double ymin, double xmax, double ymax
d->m_map->setExtent(center.x() - 0.01, center.y() - 0.01,
center.x() + 0.01, center.y() + 0.01);
QPointF readCenter = d->m_map->centerPoint();
DEBUG_LOG(m_logger) << "Center: " << center << " got: " << readCenter;
QPointF dist = center - readCenter;
INFO_LOG(m_logger) << LOGFUNCTION
<< " center =" << center
<< " read center =" << readCenter
<< " dist.manhattanLength=" << dist.manhattanLength();
QVERIFY2(dist.manhattanLength() < 10, "checkCenter failed");
// QVERIFY2(center.toPoint()==QPoint(5500, 5500), "checkCenter failed");
QTest::qWait(timeToDelay);
}
// restore old values:
d->m_map->setScale(scaleSAVE);
d->m_map->setCenterPoint(centerSAVE);
QTest::qWait(timeToDelay);
}
void SituationMapTestsMain::checkExtent()
{
const QPointF centerPnt(LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UMD9100084500"))); // Bremen motorway junction
d->m_map->setCenterPoint(centerPnt, 500000); // what is the useful
QTest::qWait(1000); // Let map react
// some 'reference' values:
QPointF center = d->m_map->centerPoint();
QRectF extent = d->m_map->extent();
// QRectF fullExtent = d->m_map->fullExtent();
INFO_LOG(m_logger) << LOGFUNCTION << " center = " << center;
INFO_LOG(m_logger) << LOGFUNCTION << " extent = " << extent;
// INFO_LOG(m_logger) << LOGFUNCTION << " fullExtent = " << fullExtent;
QVERIFY2(extent. contains(center), "extent.contains failed");
// QVERIFY2(fullExtent.contains(center), "fullExtent.contains failed");
// QVERIFY2(fullExtent.contains(extent.topLeft()), "fullExtent.contains failed");
// QVERIFY2(fullExtent.contains(extent.topRight()), "fullExtent.contains failed");
// QVERIFY2(fullExtent.contains(extent.bottomLeft()), "fullExtent.contains failed");
// QVERIFY2(fullExtent.contains(extent.bottomRight()), "fullExtent.contains failed");
QTest::qWait(1000); // Let map react
INFO_LOG(m_logger) << LOGFUNCTION << " set identical values now....";
// I
// set extent (as QRectF)
QTest::qWait(1000); // Let map react
d->m_map->setExtent(extent);
QTest::qWait(1000); // Let map react
// reference extent and new extent should be identical:
QRectF newExtent = d->m_map->extent();
QCOMPARE(newExtent.x(), extent.x());
QCOMPARE(newExtent.y(), extent.y());
QCOMPARE(newExtent.width(), extent.width());
QCOMPARE(newExtent.height(), extent.height());
/*
// III
// set fullExtent (as QRectF)
QTest::qWait(1000); // Let map react
d->m_map->setFullExtent(fullExtent);
QTest::qWait(1000); // Let map react
// reference fullExtent and new fullExtent should be identical:
QRectF newFullExtent = d->m_map->fullExtent();
QCOMPARE(newFullExtent.x(), fullExtent.x());
QCOMPARE(newFullExtent.y(), fullExtent.y());
QCOMPARE(newFullExtent.width(), fullExtent.width());
QCOMPARE(newFullExtent.height(), fullExtent.height());
*/
}
void SituationMapTestsMain::checkMapIsUTM()
{
// Preperations:
reInitTestCaseUntilSetCenter();
if (d->m_map->layerFactory().isUsingBaseMapBuiltIn())
{
#ifdef Q_OS_WIN
NOTICE_LOG(m_logger) << LOGFUNCTION << "***** !!! skipping test - isUsingBaseMapBuiltIn() = true !!! *****";
#else
// Escape sequenz \e[31m should provide a red colored log output but doesn't work for all compilers and terminal types!!! JT 2016/07/13
NOTICE_LOG(m_logger) << LOGFUNCTION << "\e[31m !!! skipping test - isUsingBaseMapBuiltIn() = true !!! \e[0m";
NOTICE_LOG(m_logger) << LOGFUNCTION << "\e[31m !!! skipping test - isUsingBaseMapBuiltIn() = true !!! \e[0m";
NOTICE_LOG(m_logger) << LOGFUNCTION << "\e[31m !!! skipping test - isUsingBaseMapBuiltIn() = true !!! \e[0m";
NOTICE_LOG(m_logger) << LOGFUNCTION << "\e[31m !!! skipping test - isUsingBaseMapBuiltIn() = true !!! \e[0m";
NOTICE_LOG(m_logger) << LOGFUNCTION << "\e[31m !!! skipping test - isUsingBaseMapBuiltIn() = true !!! \e[0m";
#endif
return;
}
int currentWkid = d->m_map->wkid();
INFO_LOG(m_logger) << LOGFUNCTION
<< " currentWkid = " << currentWkid;
char wkidInfo[50];
sprintf(&wkidInfo[0], "wkid failed (wkid = %d)", currentWkid);
QVERIFY2(currentWkid == 32632, &wkidInfo[0]); // wkid=32632 (UTM Zone 32 N WGS 84) / Bremen
// SimCoords:
QPointF simPosTopLeft = d->m_map->viewPortWindowPointToGeoCoordinate(QPoint(0, 0));
QPointF simPosBottomLeft = d->m_map->viewPortWindowPointToGeoCoordinate(QPoint(0, 1000));
QPointF simPosTopRight = d->m_map->viewPortWindowPointToGeoCoordinate(QPoint(1000, 0));
QPointF simPosBottomRight = d->m_map->viewPortWindowPointToGeoCoordinate(QPoint(1000, 1000));
INFO_LOG(m_logger) << LOGFUNCTION << " tl = " << simPosTopLeft << " tr = " << simPosTopRight;
INFO_LOG(m_logger) << LOGFUNCTION << " bl = " << simPosBottomLeft << " br = " << simPosBottomRight;
// 2015-11-17 tl = QPointF(75954.216#96400.032) tr = QPointF(107704.280#96400.032)
// 2015-11-17 bl = QPointF(75954.216#64649.968) br = QPointF(107704.280#64649.968)
double distXLeft = simPosTopLeft.x() - simPosBottomLeft.x();
double distXRight = simPosTopRight.x() - simPosBottomRight.x();
double distYTop = simPosTopLeft.y() - simPosTopRight.y();
double distYBottom = simPosBottomLeft.y() - simPosBottomRight.y();
INFO_LOG(m_logger) << LOGFUNCTION
<< " distXLeft = " << distXLeft
<< " distXRight = " << distXRight
<< " distYTop = " << distYTop
<< " distYBottom = " << distYBottom;
const double allowError = 1; //meter
QVERIFY2(fabs(distXLeft) < allowError, "distXLeft failed");
QVERIFY2(fabs(distXRight) < allowError, "distXRight failed");
QVERIFY2(fabs(distYTop) < allowError, "distYTop failed");
QVERIFY2(fabs(distYBottom) < allowError, "distYBottom failed");
{
double distHor = simPosTopLeft.x() - simPosTopRight.x(); // horizontal
double distVer = simPosTopLeft.y() - simPosBottomLeft.y(); // vertical
INFO_LOG(m_logger) << LOGFUNCTION
<< " distHor = " << fabs(distHor)
<< " distVer = " << fabs(distVer);
QVERIFY2((fabs(distHor) - fabs(distVer)) < allowError, "dist12 failed");
}
QTest::qWait(timeToDelay);
} // SituationMapTestsMain::checkMapIsUTM
void SituationMapTestsMain::convertUTMBasePoint()
{
// Preperations:
reInitTestCaseUntilSetCenter();
double simX = 94500;
double simY = 81500;
// here add offset for 32U MD
double UTMx = simX + 400000 ; // offset M
double UTMy = simY + 5800000 ; // offset for D
Esri::ArcGISRuntime::SpatialReference UTMsr(32632); // UTM Zone 32 N WGS 84
Esri::ArcGISRuntime::Point UTMbasePoint(UTMx, UTMy, UTMsr);
Esri::ArcGISRuntime::Point basePointMap = Esri::ArcGISRuntime::GeometryEngine::project(UTMbasePoint, Esri::ArcGISRuntime::SpatialReference(d->m_map->wkid()));
INFO_LOG(m_logger) << LOGFUNCTION
<< " UTMbasePoint, x=" << QString::number(UTMbasePoint.x(), 'f', 9)
<< " ; " << QString::number(UTMbasePoint.y(), 'f', 9)
<< " basePointMap, x=" << QString::number(basePointMap.x(), 'f', 9)
<< " ; " << QString::number(basePointMap.y(), 'f', 9);
// __asm int 3
} // SituationMapTestsMain::convertUTMBasePoint
void SituationMapTestsMain::checkOriginTranslated()
{
// Preperations:
reInitTestCaseUntilSetCenter();
CoordTranslationFunctor *coordTransFunctor = d->m_map->coordTranslationFunctor();
QVERIFY2(coordTransFunctor, "OriginTranslated: coordTransFunctor failed");
{
const Point3D pRef(70000, 70000, .0);
SituationMap::OriginTranslated oTrans;
oTrans.setCoordTransFunctor(coordTransFunctor);
// do
oTrans.setOrigin(pRef);
// verify
QVERIFY2(oTrans.isEmpty() == false, "OriginTranslated: isEmpty failed");
const Point3D originOut = oTrans.origin();
QVERIFY2(pRef == originOut, "OriginTranslated: origin failed");
const Point3D originMapOut = oTrans.originTranslated();
QVERIFY2(pRef != originMapOut, "OriginTranslated: originTranslated failed");
// Copy
SituationMap::OriginTranslated oTransCopy;
QVERIFY2(oTransCopy.isEmpty() == true, "OriginTranslated: isEmpty failed");
QVERIFY2((oTrans == oTransCopy) == false, "OriginTranslated: operator== failed");
QVERIFY2((oTrans != oTransCopy) == true, "OriginTranslated: operator!= failed");
oTransCopy = oTrans;
QVERIFY2(oTransCopy.isEmpty() == false, "OriginTranslated: isEmpty failed");
QVERIFY2((oTrans == oTransCopy) == true, "OriginTranslated: operator== failed");
QVERIFY2((oTrans != oTransCopy) == false, "OriginTranslated: operator!= failed");
}
}
class MyPositionsTranslated : public SituationMap::PositionsTranslated
{
public:
void setPositionsTranslated(const PositionCont &posCont)
{
SituationMap::PositionsTranslated::setPositionsTranslated(posCont);
}
};
void SituationMapTestsMain::checkPositionsTranslated()
{
// Preperations:
reInitTestCaseUntilSetCenter();
CoordTranslationFunctor *coordTransFunctor = d->m_map->coordTranslationFunctor();
QVERIFY2(coordTransFunctor, "OriginTranslated: coordTransFunctor failed");
const QPointF pRef1_2D(LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UMD7000070000")));
const QPointF pRef2_2D(LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UMD8000080000")));
const Point3D pRef1(pRef1_2D.x(), pRef1_2D.y(), .0);
const Point3D pRef2(pRef2_2D.x(), pRef2_2D.y(), .0);
SituationMap::PositionCont posContRef;
posContRef << pRef1 << pRef2;
SituationMap::PositionCont positionsMapOutRef;
{
SituationMap::PositionsTranslated pTrans;
pTrans.setCoordTransFunctor(coordTransFunctor);
coordTransFunctor->resetProjectionCounter();
QCOMPARE(coordTransFunctor->projectionCounter(), 0);
// setPositions
pTrans.setPositions(posContRef);
// verify
QVERIFY2(pTrans.isEmpty() == false, "PositionsTranslated: isEmpty failed");
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
QCOMPARE(pTrans.size(), 2);
QCOMPARE(pTrans.first(), pRef1);
QCOMPARE(pTrans.last(), pRef2);
const SituationMap::PositionCont positionsOut = pTrans.positions();
QCOMPARE(posContRef, positionsOut);
positionsMapOutRef = pTrans.positionsTranslated();
QVERIFY2(pTrans.isTranslated() == true, "PositionsTranslated: isTranslated failed");
QVERIFY2(posContRef != positionsMapOutRef, "PositionsTranslated: originTranslated failed");
QCOMPARE(coordTransFunctor->projectionCounter(), 2);
// Copy -> not allowed
SituationMap::PositionsTranslated pTransCopy;
// pTransCopy = pTrans; // Compiler error :-)
// angle are verified within the UnitTest
// clear
pTrans.clear();
// verify
QVERIFY2(pTrans.isEmpty() == true, "PositionsTranslated: isEmpty failed");
QVERIFY2(pTrans.size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.positions().size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
QVERIFY2(pTrans.positionsTranslated().size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.isTranslated() == true, "PositionsTranslated: isTranslated failed");
QVERIFY2(coordTransFunctor->projectionCounter() == 2, "OriginTranslated: projectionCounter failed");
}
{
MyPositionsTranslated pTrans;
pTrans.setCoordTransFunctor(coordTransFunctor);
coordTransFunctor->resetProjectionCounter();
QVERIFY2(coordTransFunctor->projectionCounter() == 0, "OriginTranslated: projectionCounter failed");
// setPositionsTranslated
pTrans.setPositionsTranslated(positionsMapOutRef);
// verify
QVERIFY2(pTrans.isEmpty() == false, "PositionsTranslated: isEmpty failed");
QVERIFY2(pTrans.isTranslated() == true, "PositionsTranslated: isTranslated failed");
QCOMPARE(pTrans.size(), 2);
QVERIFY2( fuzzyCompare(pTrans.first(), pRef1), "PositionsTranslated: verify failed");
QVERIFY2( fuzzyCompare(pTrans.last(), pRef2), "PositionsTranslated: verify failed");
const SituationMap::PositionCont &positionsOut = pTrans.positions();
QVERIFY2( fuzzyCompare(posContRef, positionsOut), "PositionsTranslated: verify failed");
QCOMPARE(coordTransFunctor->projectionCounter(), 2);
// try calling setPositionsTranslated with different values:
{
SituationMap::PositionCont positionsMapOutRefCopy = positionsMapOutRef;
positionsMapOutRefCopy.append(positionsMapOutRefCopy.first());
pTrans.setPositionsTranslated(positionsMapOutRefCopy);
qCritical() << " size = " << pTrans.size();
QVERIFY2(pTrans.isEmpty() == false, "PositionsTranslated: isEmpty failed");
QVERIFY2(pTrans.isTranslated() == true, "PositionsTranslated: isTranslated failed");
QCOMPARE(pTrans.size(), 3);
const SituationMap::PositionCont &positionsOut = pTrans.positions();
QCOMPARE(positionsOut.size(), 3);
QVERIFY2( fuzzyCompare(positionsOut.first(), pRef1), "PositionsTranslated: verify failed");
QVERIFY2( fuzzyCompare(positionsOut[1], pRef2), "PositionsTranslated: verify failed");
QVERIFY2( fuzzyCompare(positionsOut.last(), pRef1), "PositionsTranslated: verify failed");
}
}
// setPositions and then addSinglePosition
{
SituationMap::PositionsTranslated pTrans;
pTrans.setCoordTransFunctor(coordTransFunctor);
coordTransFunctor->resetProjectionCounter();
QCOMPARE(coordTransFunctor->projectionCounter(), 0);
// setPositions
pTrans.setPositions(posContRef);
// verify
QVERIFY2(pTrans.isEmpty() == false, "PositionsTranslated: isEmpty failed");
QCOMPARE(pTrans.size(), 2);
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
// add single position:
pTrans.addSinglePosition(pRef1);
QVERIFY2(pTrans.isEmpty() == false, "PositionsTranslated: isEmpty failed");
QCOMPARE(pTrans.size(), 3);
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
QCOMPARE(pTrans.first(), pRef1);
QCOMPARE(pTrans.last(), pRef1);
// verify
const SituationMap::PositionCont positionsOut = pTrans.positions();
QCOMPARE(positionsOut.size(), 3);
QCOMPARE(pRef1, positionsOut[2]);
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
const SituationMap::PositionCont positionsMapOut333 = pTrans.positionsTranslated();
QCOMPARE(pTrans.size(), 3);
QCOMPARE(positionsMapOutRef[0], positionsMapOut333[0]);
QCOMPARE(positionsMapOutRef[0], positionsMapOut333[2]);
QVERIFY2(pTrans.isTranslated() == true, "PositionsTranslated: isTranslated failed");
QCOMPARE(coordTransFunctor->projectionCounter(), 3);
// setPositions (to original)
pTrans.setPositions(posContRef);
// verify
QVERIFY2(pTrans.isEmpty() == false, "PositionsTranslated: isEmpty failed");
QCOMPARE(pTrans.size(), 2);
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
QCOMPARE(pTrans.first(), pRef1);
QCOMPARE(pTrans.last(), pRef2);
const SituationMap::PositionCont positionsMapOut222 = pTrans.positionsTranslated();
QCOMPARE(pTrans.size(), 2);
QCOMPARE(positionsMapOutRef, positionsMapOut222);
QVERIFY2(pTrans.isTranslated() == true, "PositionsTranslated: isTranslated failed");
QCOMPARE(coordTransFunctor->projectionCounter(), 5);
// clear
pTrans.clear();
// verify
QVERIFY2(pTrans.isEmpty() == true, "PositionsTranslated: isEmpty failed");
QVERIFY2(pTrans.size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.positions().size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
QVERIFY2(pTrans.positionsTranslated().size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.isTranslated() == true, "PositionsTranslated: isTranslated failed");
QVERIFY2(coordTransFunctor->projectionCounter() == 5, "OriginTranslated: projectionCounter failed");
}
// addSinglePosition
{
SituationMap::PositionsTranslated pTrans;
pTrans.setCoordTransFunctor(coordTransFunctor);
coordTransFunctor->resetProjectionCounter();
QVERIFY2(coordTransFunctor->projectionCounter() == 0, "OriginTranslated: projectionCounter failed");
// verify
QVERIFY2(pTrans.isEmpty() == true, "PositionsTranslated: isEmpty failed");
QVERIFY2(pTrans.size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.positions().size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
if (d->m_symbologyType != AdvancedSymbology::SymbologyType::None) // diversify flow
{
QVERIFY2(pTrans.positionsTranslated().size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.isTranslated() == true, "PositionsTranslated: isTranslated failed");
}
// add single position:
pTrans.addSinglePosition(pRef1);
QVERIFY2(pTrans.isEmpty() == false, "PositionsTranslated: isEmpty failed");
QVERIFY2(pTrans.size() == 1, "PositionsTranslated: size failed");
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
QVERIFY2(pTrans.first() == pRef1, "PositionsTranslated: first failed");
// verify
const SituationMap::PositionCont positionsOut = pTrans.positions();
QVERIFY2(positionsOut.size() == 1, "PositionsTranslated: positions failed");
QVERIFY2(pRef1 == positionsOut[0], "PositionsTranslated: positions failed");
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
const SituationMap::PositionCont positionsMapOut333 = pTrans.positionsTranslated();
QVERIFY2(positionsMapOut333.size() == 1, "PositionsTranslated: size failed");
QVERIFY2(positionsMapOutRef[0] == positionsMapOut333[0], "PositionsTranslated: positionsTranslated failed");
QVERIFY2(pTrans.isTranslated() == true, "PositionsTranslated: isTranslated failed");
QVERIFY2(coordTransFunctor->projectionCounter() == 1, "OriginTranslated: projectionCounter failed");
// setPositions (to original)
pTrans.setPositions(posContRef);
// verify
QVERIFY2(pTrans.isEmpty() == false, "PositionsTranslated: isEmpty failed");
QVERIFY2(pTrans.size() == 2, "PositionsTranslated: size failed");
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
const SituationMap::PositionCont positionsMapOut222 = pTrans.positionsTranslated();
QVERIFY2(pTrans.size() == 2, "PositionsTranslated: size failed");
QVERIFY2(positionsMapOutRef == positionsMapOut222, "PositionsTranslated: positionsTranslated failed");
QVERIFY2(pTrans.isTranslated() == true, "PositionsTranslated: isTranslated failed");
QVERIFY2(coordTransFunctor->projectionCounter() == 3, "OriginTranslated: projectionCounter failed");
// clear
pTrans.clear();
// verify
QVERIFY2(pTrans.isEmpty() == true, "PositionsTranslated: isEmpty failed");
QVERIFY2(pTrans.size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.positions().size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.isTranslated() == false, "PositionsTranslated: isTranslated failed");
QVERIFY2(pTrans.positionsTranslated().size() == 0, "PositionsTranslated: size failed");
QVERIFY2(pTrans.isTranslated() == true, "PositionsTranslated: isTranslated failed");
QVERIFY2(coordTransFunctor->projectionCounter() == 3, "OriginTranslated: projectionCounter failed");
}
}
void SituationMapTestsMain::checkPositionAngles()
{
// here we check if the angle calculation works as expected
// -> the underlying coord system used for calculation must be orthogonal - e.g. UTM
CoordTranslationFunctor *coordTransFunctor = d->m_map->coordTranslationFunctor();
SituationMap::PositionsTranslated pTrans;
pTrans.setCoordTransFunctor(coordTransFunctor);
{
// first check: we use an orthogonal triangle --> 0,0, 0,4 3,4
QList<QPointF> posCont2D({LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UMD8000080000")), // p0
LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UMD8000080004")), // p1
LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UMD8000380004"))}); // p2
SituationMap::PositionCont posCont = SituationMap::convert2D3D(posCont2D);
pTrans.setPositions(posCont);
const double start = 0;
//const double close = 210; // p2 -> p0
// calculated value:
const double close = 216.86989765331455; // p2 -> p0
const double end = 90; // p1 -> p2
const double angleStart = pTrans.angleOfStartSegment();
const double angleClose = pTrans.angleOfClosingSegment();
const double angleEnd = pTrans.angleOfEndSegment();
qDebug("Start: %20.15lf, Close: %20.15lf, End: %20.15lf", angleStart, angleClose, angleEnd);
QVERIFY2(qFuzzyCompare(angleStart, start), qPrintable(QStringLiteral("Start angle is not %1 degrees").arg(start)));
QVERIFY2(qFuzzyCompare(angleClose, close), qPrintable(QStringLiteral("Close angle is not %1 degrees").arg(close)));
QVERIFY2(qFuzzyCompare(angleEnd, end), qPrintable(QStringLiteral("End angle is not %1 degrees").arg(end)));
}
{
// second check: a 'normal' triangle
QList<QPointF> posCont2D({LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UMD8000080000")),
LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UMD8000080004")),
LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UMD8000480004"))});
SituationMap::PositionCont posCont = SituationMap::convert2D3D(posCont2D);
pTrans.setPositions(posCont);
const double start = 0;
const double close = 225.00000000667; // should be not correct
const double end = 90;
const double angleStart = pTrans.angleOfStartSegment();
const double angleClose = pTrans.angleOfClosingSegment();
const double angleEnd = pTrans.angleOfEndSegment();
qDebug("Start: %20.15lf, Close: %20.15lf, End: %20.15lf", angleStart, angleClose, angleEnd);
QVERIFY2(qFuzzyCompare(angleStart, start), qPrintable(QStringLiteral("Start angle is not %1 degrees").arg(start)));
QVERIFY2(qFuzzyCompare(angleClose, close), qPrintable(QStringLiteral("Close angle is not %1 degrees").arg(close)));
QVERIFY2(qFuzzyCompare(angleEnd, end), qPrintable(QStringLiteral("End angle is not %1 degrees").arg(end)));
}
}
void SituationMapTestsMain::measureProject()
{
// Preperations:
reInitTestCaseUntilSetCenter();
QElapsedTimer timer;
int wkid = d->m_map->wkid();
if (wkid >= 0)
{
Esri::ArcGISRuntime::SpatialReference sr(wkid);
int jMax = 10000;
//--------------------------------------------------------------------------
// create SpatialReference by wkid
//--------------------------------------------------------------------------
int wkid = 102100;
timer.start();
for (int j = 0; j < jMax; ++j)
{
Esri::ArcGISRuntime::SpatialReference temp(wkid);
int help = temp.wkid();
Q_UNUSED(help);
}
qint64 msec = timer.elapsed();
qDebug() << " create SpatialReference by wkid (" << wkid << "): " << jMax << " operations took " << msec << "ms";
//--------------------------------------------------------------------------
// create SpatialReference by wkt
//--------------------------------------------------------------------------
QLatin1String SpatialReferenceWkt(
"PROJCS[\"WGS_1984_Web_Mercator_Auxiliary_Sphere\",\
GEOGCS[\"GCS_WGS_1984\",\
DATUM[\"D_WGS_1984\",\
SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],\
PRIMEM[\"Greenwich\",0.0],\
UNIT[\"Degree\",0.0174532925199433]],\
PROJECTION[\"Mercator_Auxiliary_Sphere\"],\
PARAMETER[\"False_Easting\",0.0],\
PARAMETER[\"False_Northing\",0.0],\
PARAMETER[\"Central_Meridian\",0.0],\
PARAMETER[\"Standard_Parallel_1\",0.0],\
PARAMETER[\"Auxiliary_Sphere_Type\",0.0],\
UNIT[\"Meter\",1.0]]\"");
timer.restart();
for (int j = 0; j < jMax; ++j)
{
Esri::ArcGISRuntime::SpatialReference temp(SpatialReferenceWkt);
int help = temp.wkid();
Q_UNUSED(help);
}
msec = timer.elapsed();
qDebug() << " create SpatialReference by wkt (" << wkid << "): " << jMax << " operations took " << msec << "ms";
//--------------------------------------------------------------------------
// null projection map to map
//--------------------------------------------------------------------------
timer.restart();
for (int j = 0; j < jMax; ++j)
{
Esri::ArcGISRuntime::Point source(1000000, 1000000 + j, sr);
Esri::ArcGISRuntime::Point bremenPoint = Esri::ArcGISRuntime::GeometryEngine::project(source, sr);
Q_UNUSED(bremenPoint);
}
msec = timer.elapsed();
qDebug() << " null projection (" << wkid << "): " << jMax << " operations took " << msec << "ms";
//--------------------------------------------------------------------------
// project sim to map (BREMEN)
//--------------------------------------------------------------------------
timer.restart();
const Esri::ArcGISRuntime::SpatialReference &destSR = sr;
// Bremen: basePoint='32UMD 00000 00000' offset x=400000 (M) ; 5800000 (D) ; wkid=32632 (UTM Zone 32 N WGS 84)
const Esri::ArcGISRuntime::SpatialReference sourceSR(32632);
for (int j = 0; j < jMax; ++j)
{
Esri::ArcGISRuntime::Point simPoint(90000, 78000 + j, sourceSR);
Esri::ArcGISRuntime::Point mapPoint = Esri::ArcGISRuntime::GeometryEngine::project(simPoint, destSR);
Q_UNUSED(mapPoint);
}
msec = timer.elapsed();
qDebug() << " simple sim2Map: " << jMax << " operations took " << msec << "ms";
{
//--------------------------------------------------------------------------
// project lat/long to map (WGS84 to map) 1
//--------------------------------------------------------------------------
timer.restart();
for (int j = 0; j < jMax; ++j)
{
// Esri::ArcGISRuntime::SpatialReference sr(4236); // EPSG:4236 = WGS84
Esri::ArcGISRuntime::SpatialReference sr = static_cast<MapImpl*>(d->m_map)->getEsriSpatialReference();
Esri::ArcGISRuntime::Point myPoint(0.155, 0.926 + (j * 0.001), sr);
Esri::ArcGISRuntime::Point bremenPoint = Esri::ArcGISRuntime::GeometryEngine::project(myPoint, sr);
Q_UNUSED(bremenPoint);
}
msec = timer.elapsed();
qDebug() << " Lat/Long (WGS84) to map 1 (" << wkid << "): " << jMax << " operations took " << msec << "ms";
//--------------------------------------------------------------------------
// project lat/long to map (WGS84 to map) geographicToMap 2D
//--------------------------------------------------------------------------
timer.restart();
CoordTranslationFunctor *coordFunc = d->m_map->coordTranslationFunctor();
for (int j = 0; j < jMax; ++j)
{
const QPointF &res = coordFunc->geographicToMap(QPointF(0.155, 0.926 + (j * 0.001)));
Q_UNUSED(res);
}
msec = timer.elapsed();
qDebug() << " Lat/Long (WGS84) to map (geographicToMap 2D) " << jMax << " operations took " << msec << "ms";
//--------------------------------------------------------------------------
// project lat/long to map (WGS84 to map) geographicToMap Point3D
//--------------------------------------------------------------------------
timer.restart();
for (int j = 0; j < jMax; ++j)
{
const Point3D &res = coordFunc->geographicToMap(Point3D(0.155, 0.926 + (j * 0.001), 1.23456));
Q_UNUSED(res);
}
msec = timer.elapsed();
qDebug() << " Lat/Long (WGS84) to map (geographicToMap Point3D) " << jMax << " operations took " << msec << "ms";
}
//--------------------------------------------------------------------------
// project FalseEasting/Northing to map (to map)
//--------------------------------------------------------------------------
QLatin1String myWkt(
"PROJCS[\"WGS_1984_Web_Mercator_Auxiliary_Sphere\",\
GEOGCS[\"GCS_WGS_1984\",\
DATUM[\"D_WGS_1984\",\
SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],\
PRIMEM[\"Greenwich\",0.0],\
UNIT[\"Degree\",0.0174532925199433]],\
PROJECTION[\"Mercator_Auxiliary_Sphere\"],\
PARAMETER[\"False_Easting\",1000000.0],\
PARAMETER[\"False_Northing\",1000000.0],\
PARAMETER[\"Central_Meridian\",0.0],\
PARAMETER[\"Standard_Parallel_1\",0.0],\
PARAMETER[\"Auxiliary_Sphere_Type\",0.0],\
UNIT[\"Meter\",1.0]]\"");
int i = 1000000;
{
Esri::ArcGISRuntime::SpatialReference mySR(myWkt);
timer.restart();
for (int j = 0; j < jMax; ++j)
{
Esri::ArcGISRuntime::Point myPoint(i, i + j, mySR);
Esri::ArcGISRuntime::Point projPoint = Esri::ArcGISRuntime::GeometryEngine::project(myPoint, sr);
Q_UNUSED(projPoint);
}
msec = timer.elapsed();
}
qDebug() << " FalseEasting/Northing to map (" << wkid << "): " << jMax << " operations took " << msec << "ms";
}
else
ERROR_LOG(m_logger) << " wkid invalid";
}
void SituationMapTestsMain::measurceLocationToElevationBulk()
{
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
SituationMap::LayerFactoryImpl *layerFacImpl = dynamic_cast<SituationMap::LayerFactoryImpl *>(&layerFac);
MapImpl *mapImpl = static_cast<SituationMap::MapImpl *>(d->m_map);
LocationToElevationBulk leBulk;
leBulk.init(d->m_map, layerFacImpl->baseSurface());
leBulk.addLocation(Esri::ArcGISRuntime::Point(495000, 5880000, mapImpl->getEsriSpatialReference()));
leBulk.addLocation(Esri::ArcGISRuntime::Point(495100, 5881000, mapImpl->getEsriSpatialReference()));
QSignalSpy spy(&leBulk, &LocationToElevationBulk::locationsToElevationsCompleted);
leBulk.start();
QTRY_VERIFY2(spy.count() == 1, "LocationToElevationBulk: signalCount failed,");
}
void SituationMapTestsMain::checkMapObjectProperties()
{
SituationMap::RefPointer<SituationMap::BuildingOutline> mapObject =
d->m_map->objectFactory().create<SituationMap::BuildingOutline>(QLatin1String("AES"), QLatin1String("checkMapObjectPropertiesDebugInfo"));
QVariant variant;
bool success;
// check property
variant = mapObject->property("propA");
QVERIFY2(!variant.isValid(), "variant should be INVALID");
// check setProperty
// set to '4711'
variant.setValue(4711);
QVERIFY2(variant.isValid(), "variant should be ok");
success = mapObject->setProperty("propA", variant);
QVERIFY2(success, "setProperty failed");
// get property '4711'
variant.clear();
variant = mapObject->property("propA");
QVERIFY2(variant.isValid(), "property should be ok");
QVERIFY2(variant.toInt() == 4711, "property failed");
// change to '4712'
variant.setValue(4712);
QVERIFY2(variant.isValid(), "variant should be ok");
success = mapObject->setProperty("propA", variant);
QVERIFY2(success, "setProperty failed");
// get property '4712'
variant.clear();
variant = mapObject->property("propA");
QVERIFY2(variant.isValid(), "property failed");
QVERIFY2(variant.toInt() == 4712, "property failed");
//*******************
// invalid QVariant:
//*******************
QVariant variantInvalid;
QVERIFY2(!variantInvalid.isValid(), "variantInvalid failed");
success = mapObject->setProperty("propA", variantInvalid); // to remove property
QVERIFY2(success, "setProperty failed");
variant.clear();
variant = mapObject->property("propA"); // get non-existing property
QVERIFY2(!variant.isValid(), "variant should be INVALID");
success = mapObject->setProperty("doesNotExist", variantInvalid); // use non-existing propertyName
QVERIFY2(!success, "setProperty failed");
//*******************
// Two Properties:
//*******************
success = mapObject->setProperty("propA", 4711);
QVERIFY2(success, "setPropertyA failed");
success = mapObject->setProperty("propB", 4712);
QVERIFY2(success, "setPropertyB failed");
variant.clear();
variant = mapObject->property("propA");
QVERIFY2(variant.toInt() == 4711, "property failed");
variant.clear();
variant = mapObject->property("propB");
QVERIFY2(variant.toInt() == 4712, "property failed");
//************************
// Removing / Destroying
//************************
mapObject->removeMySelf();
}
void SituationMapTestsMain::checkObjectFactoryContainer()
{
QElapsedTimer timer;
timer.start();
uint buildingId = 0;
uint bAgentId = 0;
// mapObject 'BuildingOutline' -> 10
for (int i = 0; i < 10; ++i)
{
SituationMap::RefPointer<SituationMap::BuildingOutline> building =
d->m_map->objectFactory().create<SituationMap::BuildingOutline>(QLatin1String("AES"));
QVERIFY2(building != nullptr, "create failed");
building->setDebugInfo(QStringLiteral("building_%1").arg(i));
buildingId = building->uniqueMapId();
}
// mapObject 'BiologicalAgent' -> 100
for (int i = 0; i < 100; ++i)
{
SituationMap::RefPointer<SituationMap::BiologicalAgent> biologicalAgent =
d->m_map->objectFactory().create<SituationMap::BiologicalAgent>(QLatin1String("AES"));
QVERIFY2(biologicalAgent != nullptr, "create failed");
biologicalAgent->setDebugInfo(QStringLiteral("biologicalAgent_%1").arg(i));
biologicalAgent->setProperty("TYPE", QLatin1String("BiologicalAgent"));
bAgentId = biologicalAgent->uniqueMapId();
}
// mapObject 'Participant' -> 1000
for (int i = 0; i < 1000; ++i)
{
SituationMap::RefPointer<SituationMap::Participant> participant =
d->m_map->objectFactory().create<SituationMap::Participant>(QLatin1String("Participants"));
QVERIFY2(participant != nullptr, "create failed");
participant->setDebugInfo(QStringLiteral("participant_%1").arg(i));
}
quint32 countUsedIds = d->m_map->objectFactory().count();
QVERIFY2(countUsedIds == 1110, "wrong number of objects");
bool contains = false;
// simple contains
contains = d->m_map->objectFactory().contains(11); // random select
QVERIFY2(contains, "contains failed");
contains = d->m_map->objectFactory().contains(123456789); // random select
QVERIFY2(!contains, "contains failed");
// assume, that '5' is a building:
// simple contains
contains = d->m_map->objectFactory().contains(buildingId);
QVERIFY2(contains, "contains failed");
// typed contains
contains = d->m_map->objectFactory().contains<SituationMap::BiologicalAgent>(buildingId);
QVERIFY2(!contains, "typed contains failed");
// get
{
SituationMap::RefPointer<SituationMap::AbstractMapObject> obj = d->m_map->objectFactory().get(buildingId);
QVERIFY2(obj != nullptr, "get failed");
QVERIFY2(obj.get(), "get failed");
QVERIFY2(obj->uniqueMapId() == buildingId, "get failed");
int compare = obj->debugInfo().compare(QStringLiteral("building_9"), Qt::CaseInsensitive);
QVERIFY2(compare == 0, "get failed");
}
// get
{
SituationMap::RefPointer<SituationMap::AbstractMapObject> obj = d->m_map->objectFactory().get(123456789);
QVERIFY2(obj == nullptr, "get failed");
QVERIFY2(!obj.get(), "get failed");
}
// typed get
{
SituationMap::RefPointer<SituationMap::BiologicalAgent>bAgent
= d->m_map->objectFactory().get<SituationMap::BiologicalAgent>(bAgentId);
QVERIFY2(bAgent != nullptr, "typed get#1 failed");
QVERIFY2(bAgent.get(), "typed get#2 failed");
QVERIFY2(bAgent->uniqueMapId() == bAgentId, "get failed");
}
{
QElapsedTimer innerTimer;
innerTimer.start();
for (int j = 0; j < 100; ++j)
{
int found = 0;
for (int i = 1000; i > 0; --i)
{
// get
SituationMap::RefPointer<SituationMap::AbstractMapObject> mapObj
= d->m_map->objectFactory().get(i);
if (mapObj.valid())
++found;
}
QVERIFY2(found == 1000, "typed get#3 failed");
}
INFO_LOG(m_logger) << " get (base type) took " << innerTimer.elapsed() << "ms";
}
{
QElapsedTimer innerTimer;
innerTimer.start();
for (int j = 0; j < 100; ++j)
{
int found = 0;
for (int i = 1000; i > 0; --i)
{
// typed get
SituationMap::RefPointer<SituationMap::BiologicalAgent>bAgent
= d->m_map->objectFactory().get<SituationMap::BiologicalAgent>(i);
if (bAgent.valid())
++found;
}
QVERIFY2(found == 100, "typed get#3 failed");
}
INFO_LOG(m_logger) << " get (selected by type) took " << innerTimer.elapsed() << "ms";
}
{
QElapsedTimer innerTimer;
innerTimer.start();
for (int j = 0; j < 100; ++j)
{
int found = 0;
for (int i = 1000; i > 0; --i)
{
// get
SituationMap::RefPointer<SituationMap::AbstractMapObject> mapObj
= d->m_map->objectFactory().get(i);
if (mapObj.valid() && mapObj->property("TYPE").toString().compare(QLatin1String("BiologicalAgent")) == 0)
++found;
}
QVERIFY2(found == 100, "typed get#3 failed");
}
INFO_LOG(m_logger) << " get (selected by QLatin1String) took " << innerTimer.elapsed() << "ms";
}
INFO_LOG(m_logger) << " checkObjectFactoryContainer took " << timer.elapsed() << "ms";
}
void SituationMapTestsMain::checkObjectAndLayerFactory()
{
// Preperations:
bool success = false;
initTestCase();
checkMapReady();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
SituationMap::ObjectFactory &objFac = d->m_map->objectFactory();
{
INFO_LOG(m_logger) << " technicalLayerCount = " << d->m_map->technicalLayerCount();
INFO_LOG(m_logger) << " layernames = " << layerFac.layernames().join(QLatin1String(";"));
int basemapCount = layerFac.layernames(LayerType::Basemap).count();
int jumpPointLayerCount = layerFac.layernames(LayerType::JumpPoint).count();
int objectLayerCount = layerFac.layernames(LayerType::Operational).count();
QVERIFY2((1 <= basemapCount) && (basemapCount <= 3), "layerFactory: count failed");
QVERIFY2(objectLayerCount == 13, QString(QStringLiteral("layerFactory: count failed (is %1)")).arg(objectLayerCount).toStdString().c_str());
QVERIFY2(d->m_map->technicalLayerCount() == basemapCount , "layerFactory: technicalLayerCount failed");
QVERIFY2(layerFac.count() == basemapCount + jumpPointLayerCount + objectLayerCount , "layerFactory: count failed");
INFO_LOG(m_logger) << " objFac.count() =" << objFac.count();
qDebug() << " technicalLayerCount =" << d->m_map->technicalLayerCount();
int initialObjCount = objFac.count();
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames(LayerType::Operational);
QString layername = layernames[0];
QVERIFY2(layername.isEmpty() == false, "objectFactory: count failed");
// real test
QVERIFY2(objFac.count() == 0, "objectFactory: count failed");
QVERIFY2(d->m_map->technicalLayerCount() == basemapCount , "layerFactory: technicalLayerCount failed");
SituationMap::RefPointer<SituationMap::Participant> objPtr1;
objPtr1 = objFac.create<SituationMap::Participant>(layername, QLatin1String("UnitTestId1"));
QVERIFY2(objPtr1.valid() == true , "objectFactory: create11 failed");
SituationMap::RefPointer<SituationMap::BiologicalAgent> objPtr2;
objPtr2 = objFac.create<SituationMap::BiologicalAgent>(layername, QLatin1String("UnitTestId2"));
QVERIFY2(objPtr2.valid() == true , "objectFactory: create22 failed");
SituationMap::RefPointer<SituationMap::BuildingOutline> objPtr3;
objPtr3 = objFac.create<SituationMap::BuildingOutline>(layername, QLatin1String("UnitTestId3"));
QVERIFY2(objPtr3.valid() == true , "objectFactory: create33 failed");
SituationMap::RefPointer<SituationMap::DangerArea> objPtr4;
objPtr4 = objFac.create<SituationMap::DangerArea>(layername, QLatin1String("UnitTestId4"));
QVERIFY2(objPtr4.valid() == true , "objectFactory: create44 failed");
QVERIFY2(objFac.count() == (initialObjCount + 4) , "objectFactory: count failed");
// now set required parameters:
QPointF offset = QPointF(50000, 50000);
int extent = 30000;
QList<QPointF> posCont2D;
posCont2D << s_basePoint.geographic( offset - QPointF( 0, 0) );
posCont2D << s_basePoint.geographic( offset - QPointF(extent, 0) );
posCont2D << s_basePoint.geographic( offset - QPointF(extent, extent) );
posCont2D << s_basePoint.geographic( offset - QPointF( 0, extent) );
objPtr3->setPositions(convert2D3D(posCont2D));
// => technicalLayerCount increases by 1/one, caused by objFac.create<>)
QVERIFY2(d->m_map->technicalLayerCount() == basemapCount + 1 , "layerFactory: technicalLayerCount failed");
// now update the objects (to let layerFactory create MessageGroupLayer implicit/onDemand)
success = objPtr3->updateView();
QVERIFY2(success , "object: updateView failed");
qDebug() << " technicalLayerCount =" << d->m_map->technicalLayerCount();
if (d->m_symbologyType != AdvancedSymbology::SymbologyType::None)
{
// in the meantime, the corresponding technicalLayer (MessageGroup) for the objects is created
// => technicalLayerCount increases again by 1/one, caused by objFac.updateView)
// QVERIFY2(d->m_map->technicalLayerCount() == basemapCount + 1 , "layerFactory: technicalLayerCount failed");
// => technicalLayerCount increases again by 2/two, caused by objFac.updateView)
QVERIFY2(d->m_map->technicalLayerCount() == basemapCount + 2 , "layerFactory: technicalLayerCount failed");
}
else
QVERIFY2(d->m_map->technicalLayerCount() == basemapCount + 1 , "layerFactory: technicalLayerCount failed");
}
//
// End of scope -> local RefPointer should be destroyed now:
//
//************************
// Removing / Destroying
//************************
const QList<UniqueMapId> allUniqueIds = objFac.getAllKeys();
qDebug() << " remove, current size()=" << allUniqueIds.size();
QVERIFY2(objFac.count() == allUniqueIds.size(), "objectFactory: count/size/... inkonsistent");
int numberRemoved = 0;
for (SituationMap::UniqueMapId uniqueId : allUniqueIds)
{
qDebug() << " remove uniqueId=" << uniqueId << "...";
{
RefPointer<AbstractMapObject> mapObj = objFac.get(uniqueId);
if (mapObj)
{
mapObj->removeMySelf();
++numberRemoved;
}
else
qWarning() << " uniqueId=" << uniqueId << " not found";
}
// End of Scope....
qDebug() << " remove uniqueId=" << uniqueId << "... Done";
}
qDebug() << " remove finished, current size()=" << objFac.count();
QVERIFY2(allUniqueIds.size() == numberRemoved , "objectFactory: at least one failure");
QVERIFY2(objFac.count() == 0 , "objectFactory: count failed");
} // checkObjectAndLayerFactory
void SituationMapTestsMain::checkOverlayHandler1()
{
// use nullptr as map:
SituationMap::Map *map = nullptr;
SituationMap::OverlayHandlerImpl oh(map);
QVERIFY2(oh.overlayCount() == 0 , "OverlayHandler: overlayCount failed");
QVERIFY2(oh.containsOverlay(123456789) == false , "OverlayHandler: containsOverlay failed");
bool success = false;
success = oh.setOverlay(1234, QStringLiteral("OverlayDisplayname"), QByteArray("myInvalidOverlayData"));
QVERIFY2(success == 0 , "OverlayHandler: setOverlay failed");
QVERIFY2(oh.overlayCount() == 0 , "OverlayHandler: overlayCount failed");
QVERIFY2(oh.containsOverlay(1234) == false , "OverlayHandler: containsOverlay failed");
}
void SituationMapTestsMain::checkOverlayHandler2()
{
// Preperations:
reInitTestCaseUntilSetCenter();
{
SituationMap::OverlayHandler &oh = d->m_map->overlayHandler();
QVERIFY2(oh.overlayCount() == 0 , "OverlayHandler: overlayCount failed");
QVERIFY2(oh.containsOverlay(123456789) == false , "OverlayHandler: containsOverlay failed");
bool success = false;
// add invalid data:
qWarning() << " add invalid data:";
{
int layerCountBEFORE = d->m_map->layerFactory().count();
success = oh.setOverlay(1234, QStringLiteral("OverlayDisplayname"), QByteArray("myInvalidOverlayData"));
QVERIFY2(success == false, "OverlayHandler: setOverlay failed");
QVERIFY2(oh.overlayCount() == 0, "OverlayHandler: overlayCount failed");
QVERIFY2(oh.containsOverlay(1234) == false, "OverlayHandler: containsOverlay failed");
int layerCountAFTER = d->m_map->layerFactory().count();
QVERIFY2((layerCountAFTER - layerCountBEFORE) == 0, "OverlayHandler: layerCountDiff failed");
QSignalSpy spy(d->m_map, &SituationMap::Map::layerOrderChanged);
QVERIFY2(spy.count() == 0, "OverlayHandler: signalCount failed, layerOrderChanged");
}
}
}
void SituationMapTestsMain::checkOverlayHandler3()
{
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::OverlayHandler &oh = d->m_map->overlayHandler();
QVERIFY2(oh.overlayCount() == 0 , "OverlayHandler: overlayCount failed");
QVERIFY2(oh.containsOverlay(123456789) == false , "OverlayHandler: containsOverlay failed");
bool success = false;
//
// create PlanData 1:
//
QScopedPointer<GeometryModel> geoModel(GeometryModelFactory::singleton()->create());
QVERIFY2((geoModel != nullptr), "OverlayHandler: Creating empty GeometryModel failed.");
QList<QPointF> vertexList;
vertexList << QPointF(0.15, 0.9) << QPointF(0.151, 0.901); // area Bremen
QList<QPair<GeometryModel::Attribute, QVariant>> attrList;
attrList += QPair<GeometryModel::Attribute, QVariant>(GeometryModel::Attribute::Color, QVariant(QColor("red")));
const GeometryModel::Node &node1 = geoModel->addPrimitive(GeometryModel::PrimitiveType::Line, vertexList, attrList);
QVERIFY2((node1.isValid()), "OverlayHandler: node invalid.");
QByteArray planData1 = geoModel->toByteArray();
DEBUG_LOG(m_logger) << LOGFUNCTION << " planData1=" << planData1;
//
// create PlanData 2:
//
vertexList.clear();
vertexList << QPointF(0.1511, 0.911) << QPointF(0.15111, 0.9011); // area Bremen
const GeometryModel::Node &node2 = geoModel->addPrimitive(GeometryModel::PrimitiveType::Line, vertexList, attrList);
QVERIFY2((node2.isValid()), "OverlayHandler: node invalid.");
QByteArray planData2 = geoModel->toByteArray();
DEBUG_LOG(m_logger) << LOGFUNCTION << " planData2=" << planData2;
//
// add valid data / planData 1:
//
qWarning() << " add valid data / planData 1:";
{
int layerCountBEFORE = d->m_map->layerFactory().count();
QSignalSpy spy(d->m_map, &SituationMap::Map::layerOrderChanged);
success = oh.setOverlay(1234, QStringLiteral("OverlayDisplayname"), planData1);
QVERIFY2(success == true, "OverlayHandler: setOverlay failed");
QVERIFY2(oh.overlayCount() == 1, "OverlayHandler: overlayCount failed");
QVERIFY2(oh.containsOverlay(1234) == true, "OverlayHandler: containsOverlay failed");
QVERIFY2(spy.count() == 1, "signalCount failed, layerOrderChanged");
int layerCountAFTER = d->m_map->layerFactory().count();
QVERIFY2((layerCountAFTER - layerCountBEFORE) == 1, "OverlayHandler: layerCountDiff failed");
DEBUG_LOG(m_logger) << LOGFUNCTION << " ln=" << d->m_map->layerFactory().layernames().join(QLatin1String(";"));
// verify objCount on EsriLayer
SituationMap::LayerFactoryImpl *layFacImpl = dynamic_cast<SituationMap::LayerFactoryImpl *>(&d->m_map->layerFactory());
QVERIFY2((layFacImpl) , "OverlayHandler: layFacImpl failed");
Esri::ArcGISRuntime::GraphicsOverlay *graphicsLayer = layFacImpl->getGraphicsLayer(QLatin1String("OverlayLayer_1234"));
QVERIFY2((layFacImpl) , "OverlayHandler: EsriLayer failed");
int numberOfObjects = graphicsLayer->graphics()->size();
DEBUG_LOG(m_logger) << LOGFUNCTION << " planData1 -> numberOfObjects=" << numberOfObjects;
QVERIFY2(numberOfObjects == 1 , "OverlayHandler: numberOfObjects on EsriLayer failed");
}
//
// updateOverlay with planData 2:
//
qWarning() << " add valid data / planData 2:";
{
QSignalSpy spy(d->m_map, &SituationMap::Map::layerOrderChanged);
success = oh.setOverlay(1234, QStringLiteral("OverlayDisplayname"), planData2);
QVERIFY2(success == true, "OverlayHandler: setOverlay failed");
success = oh.setOverlay(1234, QStringLiteral("OverlayDisplayname"), planData2);
QVERIFY2(success == true, "OverlayHandler: setOverlay failed");
QVERIFY2(oh.overlayCount() == 1, "OverlayHandler: overlayCount failed");
QVERIFY2(oh.containsOverlay(1234) == true, "OverlayHandler: containsOverlay failed");
QVERIFY2(spy.count() == 0, "signalCount failed, layerOrderChanged"); // == 0 because layer already exists
// verify objCount on EsriLayer
SituationMap::LayerFactoryImpl *layFacImpl = dynamic_cast<SituationMap::LayerFactoryImpl *>(&d->m_map->layerFactory());
QVERIFY2((layFacImpl) , "OverlayHandler: layFacImpl failed");
Esri::ArcGISRuntime::GraphicsOverlay *graphicsLayer = layFacImpl->getGraphicsLayer(QLatin1String("OverlayLayer_1234"));
QVERIFY2((layFacImpl) , "OverlayHandler: EsriLayer failed");
int numberOfObjects = graphicsLayer->graphics()->size();
DEBUG_LOG(m_logger) << LOGFUNCTION << " planData2 -> numberOfObjects=" << numberOfObjects;
QVERIFY2(numberOfObjects == 2 , "OverlayHandler: numberOfObjects on EsriLayer failed");
}
//
// check order:
// OverlayLayer shall be directly on top of the basemaps
//
if (1) {
const QStringList &layerNames = d->m_map->layerFactory().layernames();
const int layerCount = layerNames.count();
const int basemapCount = d->m_map->layerFactory().layernames(LayerType::Basemap).count();
QVERIFY2((layerCount - basemapCount) > 0 , "Order of Layer: count failed"); // preCondition
const QString &ovlName = layerNames[basemapCount]; // access to successor of basemaps
const bool match = ovlName.startsWith(QLatin1String("OverlayLayer"));
QVERIFY2(match == true , "Order of Layer: OverlayLayer is NOT successor of basemaps"); // preCondition
}
// removeOverlay
{
QSignalSpy spy(d->m_map, &SituationMap::Map::layerOrderChanged);
int layerCountBEFORE = d->m_map->layerFactory().count();
bool success = oh.removeOverlay(1234);
QVERIFY2(success == true, "OverlayHandler: removeOverlay failed");
QVERIFY2(oh.overlayCount() == 0, "OverlayHandler: overlayCount failed");
QVERIFY2(oh.containsOverlay(1234) == false, "OverlayHandler: containsOverlay failed");
QVERIFY2(spy.count() == 1, "signalCount failed, layerOrderChanged");
int layerCountAFTER = d->m_map->layerFactory().count();
QVERIFY2((layerCountAFTER - layerCountBEFORE) == -1, "OverlayHandler: layerCountDiff failed");
DEBUG_LOG(m_logger) << LOGFUNCTION << " ln=" << d->m_map->layerFactory().layernames().join(QLatin1String(";"));
}
}
/*
void SituationMapTestsMain::checkRubberbandFactory()
{
initTestCase();
checkMapReady();
SituationMap::RB::RubberbandPointFeature *rbandPt = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandPointFeature>();
QVERIFY2(rbandPt != nullptr, "RubberbandFactory::create failed for SituationMap::RB::RubberbandPointFeature");
SituationMap::RB::RubberbandMultiPointFeature *rbandMPt = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandMultiPointFeature>();
QVERIFY2(rbandMPt == nullptr, "RubberbandFactory::create failed for second rubberband at time");
if (rbandPt) delete rbandPt; // here it is ok to use delete directly
if (rbandMPt) delete rbandMPt;
rbandMPt = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandMultiPointFeature>();
QVERIFY2(rbandMPt != nullptr, "RubberbandFactory::create failed for SituationMap::RB::RubberbandMultiPointFeature");
if (rbandMPt) delete rbandMPt;
// check creating other rubberbands with factory
SituationMap::RB::Rubberband *rband = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandPointCluster>();
QVERIFY2(rband != nullptr, "RubberbandFactory::create failed for SituationMap::RB::RubberbandPointCluster");
if (rband) delete rband;
rband = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandArrow>();
QVERIFY2(rband != nullptr, "RubberbandFactory::create failed for SituationMap::RB::RubberbandArrow");
if (rband) delete rband;
rband = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandCorridor>();
QVERIFY2(rband != nullptr, "RubberbandFactory::create failed for SituationMap::RB::RubberbandCorridor");
if (rband) delete rband;
rband = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandEllipse>();
QVERIFY2(rband != nullptr, "RubberbandFactory::create failed for SituationMap::RB::RubberbandEllipse");
if (rband) delete rband;
rband = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandRectangle>();
QVERIFY2(rband != nullptr, "RubberbandFactory::create failed for SituationMap::RB::RubberbandRectangle");
if (rband) delete rband;
rband = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandSmoothLine>();
QVERIFY2(rband != nullptr, "RubberbandFactory::create failed for SituationMap::RB::RubberbandSmoothLine");
if (rband) delete rband;
} // SituationMapTestsMain::checkRubberbandFactory
*/
void SituationMapTestsMain::measureCoordTranslationFunctor()
{
// Preperations:
reInitTestCaseUntilSetCenter();
// Bremen: basePoint='32UMD 00000 00000' offset x=400000 (M) ; 5800000 (D) ; wkid=32632 (UTM Zone 32 N WGS 84)
d->m_map->initCoordTranslationFunctor();
SituationMap::CoordTranslationFunctor *functor = d->m_map->coordTranslationFunctor();
QVERIFY2(functor != nullptr, "CoordTranslationFunctor falied");
QElapsedTimer timer;
int jMax = 1000;
{
timer.start();
for (int j = 0; j < jMax; ++j)
{
QPointF point(0.01, 0.08 + j * 0.0001);
QPointF ret = functor->geographicToMap(point);
Q_UNUSED(ret);
}
INFO_LOG(m_logger) << " simToMap " << jMax << " operations took " << timer.elapsed() << "ms";
}
{
timer.restart();
for (int j = 0; j < jMax; ++j)
{
QPointF point(850000, 6880000 + j);
QPointF ret = functor->mapToGeographic(point);
Q_UNUSED(ret);
}
INFO_LOG(m_logger) << " mapToSim " << jMax << " operations took " << timer.elapsed() << "ms";
}
} // SituationMapTestsMain::checkRubberbandFactory
void SituationMapTestsMain::checkCoordinateConversion()
{
// Karte laden fehlt hier noch, nach meinem Urlaub geht's weiter ... JT
initTestCase();
checkMapReady();
checkCenter();
// d->m_map->setExtent(100000, 100000, 10000000, 10000000);
QPoint windowPos(400, 200);
QPointF mapPos = d->m_map->viewPortWindowPointToMapCoordinate(windowPos);
QPointF geoPos = d->m_map->viewPortWindowPointToGeoCoordinate(windowPos);
QPointF windowPosMap = d->m_map->mapCoordinateToViewPortWindowPoint(mapPos);
QPointF windowPosGeo = d->m_map->geoCoordinateToViewPortWindowPoint(geoPos);
qDebug() << LOGFUNCTION << "ConversionCheck with windowPos " << windowPos;
qDebug() << "mapPos" << mapPos << " ---> winPos " << windowPosMap;
qDebug() << "geoPos" << geoPos << " ---> winPos " << windowPosGeo;
QVERIFY2((windowPos - windowPosMap).manhattanLength() < 5, "Coordinate conversion for map coordinates failed.");
QVERIFY2((windowPos - windowPosGeo).manhattanLength() < 5, "Coordinate conversion for geo coordinates failed.");
// define a square
QPoint wrp1(100, 100);
QPoint wrp2(300, 100);
QPoint wrp3(300, 300);
QPoint wrp4(100, 300);
QPointF srp1 = d->m_map->viewPortWindowPointToGeoCoordinate(wrp1);
QPointF srp2 = d->m_map->viewPortWindowPointToGeoCoordinate(wrp2);
QPointF srp3 = d->m_map->viewPortWindowPointToGeoCoordinate(wrp3);
QPointF srp4 = d->m_map->viewPortWindowPointToGeoCoordinate(wrp4);
qreal w1 = srp2.x() - srp1.x();
qreal w2 = srp3.x() - srp4.x();
qreal h1 = srp1.y() - srp4.y();
qreal h2 = srp2.y() - srp3.y();
QString msg;
msg = QStringLiteral("Rectangle seems not to be a rectangle under current coordinate projections. (cur wkid=%1").arg(d->m_map->wkid());
QVERIFY2(fabs(w1 - w2) < 0.1, msg.toUtf8().data());
QVERIFY2(fabs(h1 - h2) < 0.1, msg.toUtf8().data());
msg = QStringLiteral("Square seems not to be a square under current coordinate projections. (cur wkid=%1").arg(d->m_map->wkid());
QVERIFY2(fabs(h1 - w1) < 0.1, msg.toUtf8().data());
// d->m_map->layerFactory().initializeBasemaps( QStringList(QLatin1String("http://192.168.133.88:6080/arcgis/rest/services/BremenGeoTiffUTM/MapServer"))
// , AdvancedSymbology::SymbologyType::MIL2525C );
} /* SituationMapTestsMain::checkCoordinateConversion */
#ifdef CrashUnderWindows
void SituationMapTestsMain::checkCreationAndRemoveMySelf()
{
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::ObjectFactory &objFac = d->m_map->objectFactory();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
int initialObjCount = objFac.count();
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QString layername = layernames[1];
// real test
QVERIFY2(objFac.count() == 0, "objectFactory: count failed");
{
QList<SituationMap::RefPointer<SituationMap::AbstractMapObject> > objList;
SituationMap::RefPointer<SituationMap::Participant> objPtr1;
objPtr1 = objFac.create<SituationMap::Participant>(layername, QLatin1String("UnitTestId1"));
QVERIFY2(objPtr1.valid() == true , "objectFactory: create11 failed");
objList.append(SituationMap::RefPointer<SituationMap::AbstractMapObject> (objPtr1.get()));
SituationMap::RefPointer<SituationMap::BiologicalAgent> objPtr2;
objPtr2 = objFac.create<SituationMap::BiologicalAgent>(layername, QLatin1String("UnitTestId2"));
QVERIFY2(objPtr2.valid() == true , "objectFactory: create22 failed");
objList.append(SituationMap::RefPointer<SituationMap::AbstractMapObject> (objPtr2.get()));
SituationMap::RefPointer<SituationMap::BuildingOutline> objPtr3;
objPtr3 = objFac.create<SituationMap::BuildingOutline>(layername, QLatin1String("UnitTestId3"));
QVERIFY2(objPtr3.valid() == true , "objectFactory: create33 failed");
objList.append(SituationMap::RefPointer<SituationMap::AbstractMapObject> (objPtr3.get()));
SituationMap::RefPointer<SituationMap::DangerArea> objPtr4;
objPtr4 = objFac.create<SituationMap::DangerArea>(layername, QLatin1String("UnitTestId4"));
QVERIFY2(objPtr4.valid() == true , "objectFactory: create44 failed");
objList.append(SituationMap::RefPointer<SituationMap::AbstractMapObject> (objPtr4.get()));
QVERIFY2(objList.count() == 4 , "objList: count failed");
QVERIFY2(objFac.count() == (initialObjCount + 4) , "objectFactory: count failed");
// remove all:
for (SituationMap::RefPointer<SituationMap::AbstractMapObject> item : qAsConst(objList))
item->removeMySelf();
}
QVERIFY2(objFac.count() == 0, "objectFactory: count failed");
}
#endif
//-------------------------------------------------------------------------------------------------------
#define QVERIFY3(statement, description, context) \
{ \
QString myDesc = QString( QLatin1String("%1:%2") ).arg(context, QLatin1String(description) ); \
QVERIFY2(statement, myDesc.toUtf8().data()); \
}
template<class TYPE>
void checkGraphicalObjectVisibility(const QScopedPointer<TYPE> &go, const QString &objName)
{
// Check visibility:
// hide:
go->setVisibility(false);
QVERIFY3(go->updateView() == true, "updateView failed", objName);
Esri::ArcGISRuntime::Graphic *graphic = go->graphic();
QVERIFY3(graphic, "graphic failed", objName);
// 1
QVERIFY3(graphic->isVisible() == false, "isVisible failed1", objName);
// show:
go->setVisibility(true);
QVERIFY3(go->updateView() == true, "updateView failed", objName);
QVERIFY3(go->changed() == false, "changed failed", objName);
QVERIFY3(graphic->isVisible() == true, "isVisible failed2", objName);
// hide again:
go->setVisibility(false);
QVERIFY3(go->updateView() == true, "updateView failed", objName);
QVERIFY3(go->changed() == false, "changed failed", objName);
QVERIFY3(graphic->isVisible() == false, "isVisible failed3", objName);
}
class GraphObj : public SituationMap::AbstractGraphicalObject
{
using BaseClass = AbstractGraphicalObject;
public:
using BaseClass::BaseClass;
using BaseClass::changed;
using BaseClass::resetChanged;
bool updateViewImpl() override
{
return true;
}
bool create() override
{
return true;
}
};
#ifdef CrashUnderWindows
void SituationMapTestsMain::checkGraphicalObject()
{
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
MapImpl *mapImpl = static_cast<SituationMap::MapImpl *>(d->m_map);
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QString layername = layernames[1];
// real test
static_cast<SituationMap::MapImpl *>(d->m_map)->getGraphicsLayer(layername);
QScopedPointer<GraphObj> go(new GraphObj(mapImpl->getEsriGeoView(),
mapImpl->getGraphicsLayer(layername),
QLatin1String("TacticalAppearanceModuleTest"),
4712));
QVERIFY2(go, "objectFactory: GraphObj failed");
QVERIFY2(go->changed() == true, "GraphObj: changed failed");
go->resetChanged();
QVERIFY2(go->changed() == false, "GraphObj: changed failed");
QVERIFY2(go->isSinglePoint() == false, "GraphObj: isSinglePoint failed");
QVERIFY2(go->isMultiPoint() == false, "GraphObj: isMultiPoint failed");
QVERIFY2(go->isArea() == false, "GraphObj: isArea failed");
}
#endif
//-------------------------------------------------------------------------------------------------------
class GraphObjEllipse : public SituationMap::GraphicalObjectEllipse
{
using BaseClass = GraphicalObjectEllipse;
public:
using BaseClass::BaseClass;
using BaseClass::changed;
using BaseClass::resetChanged;
};
void SituationMapTestsMain::checkGraphicalObjectEllipse()
{
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
MapImpl *mapImpl = static_cast<SituationMap::MapImpl *>(d->m_map);
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QString layername = layernames[1];
// real test
mapImpl->getGraphicsLayer(layername);
QScopedPointer<GraphObjEllipse> go(new GraphObjEllipse(mapImpl->getEsriGeoView(),
mapImpl->getGraphicsLayer(layername),
QLatin1String("TacticalAppearanceModuleTest"),
4712));
QVERIFY2(go, "objectFactory: GraphObjEllipse failed");
QVERIFY2(go->changed() == true, "GraphObjEllipse: changed failed");
go->resetChanged();
QVERIFY2(go->changed() == false, "GraphObjEllipse: changed failed");
QVERIFY2(go->isSinglePoint() == false, "GraphObjEllipse: isSinglePoint failed");
QVERIFY2(go->isMultiPoint() == false, "GraphObjEllipse: isMultiPoint failed");
QVERIFY2(go->isArea() == false, "GraphObjEllipse: isArea failed");
go->setOrigin(Point3D(94000, 78000, .0));
QVERIFY2(go->isSinglePoint() == true, "GraphObjEllipse: isSinglePoint failed");
SituationMap::EllipseParameters ellipsePara;
ellipsePara.setLengthX(1000);
ellipsePara.setLengthY(1000);
// ellipsePara.setDirectionDegree(0); // circle -> irrelevant
// ellipsePara.setMaxSegmentLength(10); // use default
go->setEllipseParameters(ellipsePara);
QVERIFY2(go->changed() == true, "GraphObjEllipse: changed failed");
bool success = go->updateView();
QVERIFY2(success == true, "GraphObjEllipse: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjEllipse: changed failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjEllipse: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjEllipse: changed failed");
// Check visibility:
checkGraphicalObjectVisibility(go, QStringLiteral("GraphObjEllipse"));
}
//-------------------------------------------------------------------------------------------------------
class GraphObjPath : public SituationMap::GraphicalObjectPath
{
using BaseClass = GraphicalObjectPath;
public:
using BaseClass::BaseClass;
using BaseClass::changed;
using BaseClass::resetChanged;
};
template<class TYPE>
void runGraphicalObjectPath(SituationMap::Map *map,
const SituationMap::GraphicalObjectPathType type)
{
SituationMap::LayerFactory &layerFac = map->layerFactory();
MapImpl *mapImpl = static_cast<SituationMap::MapImpl *>(map);
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QString layername = layernames[1];
mapImpl->getGraphicsLayer(layername);
QScopedPointer<TYPE> go(new TYPE(type,
mapImpl->getEsriGeoView(),
mapImpl->getGraphicsLayer(layername),
QLatin1String("TacticalAppearanceModuleTest"),
4712));
QVERIFY2(go, "objectFactory: GraphObjPath failed");
QVERIFY2(go->changed() == true, "GraphObjPath: changed failed");
go->resetChanged();
QVERIFY2(go->changed() == false, "GraphObjPath: changed failed");
QVERIFY2(go->isSinglePoint() == false, "GraphObjPath: isSinglePoint failed");
QVERIFY2(go->isMultiPoint() == false, "GraphObjPath: isMultiPoint failed");
QVERIFY2(go->isArea() == false, "GraphObjPath: isArea failed");
// With coordinates
PositionCont posCont;
posCont << Point3D(94000, 78000, .0);
posCont << Point3D(95000, 70000, .0);
posCont << Point3D(94500, 78500, .0);
go->setPositions(posCont);
QVERIFY2(go->isSinglePoint() == false, "GraphObjPath: isSinglePoint failed");
QVERIFY2(go->isMultiPoint() == true, "GraphObjPath: isSinglePoint failed");
QVERIFY2(go->isArea() == true, "GraphObjPath: isSinglePoint failed");
QVERIFY2(go->changed() == true, "GraphObjPath: changed failed");
bool success = go->updateView();
QVERIFY2(success == true, "GraphObjPath: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPath: changed failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPath: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPath: changed failed");
// check incorrect positions:
// check doubled start and end position:
{
// set positions:
SituationMap::PositionCont posCont;
QPointF center = map->centerPoint();
Point3D center3D(center.x(), center.y(), .0);
posCont << center3D + Point3D( 0, 0, .0);
posCont << center3D + Point3D( 0, 5000, .0);
posCont << center3D + Point3D(5000, 5000, .0);
posCont << center3D + Point3D( 0, 0, .0);
go->setPositions(posCont);
bool success = go->updateView();
QVERIFY2(success == true, "GraphObjPath: updateView failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPath: updateView failed");
}
// check doubled positions:
{
// set positions:
SituationMap::PositionCont posCont;
QPointF center = map->centerPoint();
Point3D center3D(center.x(), center.y(), .0);
posCont << center3D + Point3D( 0, 0, .0);
posCont << center3D + Point3D( 0, 0, .0);
posCont << center3D + Point3D( 0, 0, .0);
posCont << center3D + Point3D(5000, 0, .0);
posCont << center3D + Point3D(5000, 5000, .0);
posCont << center3D + Point3D( 0, 0, .0);
posCont << center3D + Point3D( 0, 0, .0);
go->setPositions(posCont);
bool success = go->updateView();
QVERIFY2(success == true, "GraphObjPath: updateView failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPath: updateView failed");
}
// Check visibility:
checkGraphicalObjectVisibility(go, QStringLiteral("GraphObjPath"));
}
void SituationMapTestsMain::checkGraphicalObjectPath()
{
// Preperations:
reInitTestCaseUntilSetCenter();
// real test
runGraphicalObjectPath<GraphObjPath>(d->m_map, SituationMap::GraphicalObjectPathType::Polyline);
runGraphicalObjectPath<GraphObjPath>(d->m_map, SituationMap::GraphicalObjectPathType::Polygon);
}
//-------------------------------------------------------------------------------------------------------
class GraphObjPictureMarker : public SituationMap::GraphicalObjectPictureMarker
{
using BaseClass = GraphicalObjectPictureMarker;
public:
using BaseClass::BaseClass;
using BaseClass::changed;
using BaseClass::resetChanged;
int scaleCounter() const
{
return m_scaleCounter4Moduletest;
}
bool imageDefaultSizeChanged() const
{
return m_imageDefaultSize.changed();
}
QSize esriPictureMarkerSize() const
{
if (!m_pictureMarkerSymbol)
return QSize();
return QSize(m_pictureMarkerSymbol->width(), m_pictureMarkerSymbol->height());
}
};
void runGraphicalObjectPictureMarker(SituationMap::Map *map,
const SituationMap::MarkerSymbolType markerType)
{
SituationMap::LayerFactory &layerFac = map->layerFactory();
MapImpl *mapImpl = static_cast<SituationMap::MapImpl *>(map);
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QString layername = layernames[1];
// real test
QScopedPointer<GraphObjPictureMarker> go(new GraphObjPictureMarker(mapImpl->getEsriGeoView(),
mapImpl->getGraphicsLayer(layername),
QLatin1String("TacticalAppearanceModuleTest"),
4712));
QVERIFY2(go, "objectFactory: GraphObjPictureMarker failed");
QVERIFY2(go->changed() == true, "GraphObjPictureMarker: changed failed");
go->resetChanged();
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->isSinglePoint() == false, "GraphObjPictureMarker: isSinglePoint failed");
QVERIFY2(go->isMultiPoint() == false, "GraphObjPictureMarker: isMultiPoint failed");
QVERIFY2(go->isArea() == false, "GraphObjPictureMarker: isArea failed");
go->setOrigin(Point3D(94000, 78000, .0));
QVERIFY2(go->isSinglePoint() == true, "GraphObjPictureMarker: isSinglePoint failed");
QVERIFY2(go->changed() == true, "GraphObjPictureMarker: changed failed");
go->setMarkerSymbol(markerType, 100);
QVERIFY2(go->changed() == true, "GraphObjPictureMarker: changed failed");
bool success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
// Change:
QImage image(100, 100, QImage::Format_ARGB32);
image.fill(Qt::transparent);
go->setImage(image);
QVERIFY2(go->changed() == true, "GraphObjPictureMarker: changed failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
}
void SituationMapTestsMain::checkGraphicalObjectPictureMarker1()
{
// Preperations:
reInitTestCaseUntilSetCenter();
runGraphicalObjectPictureMarker(d->m_map, SituationMap::MarkerSymbolType::Circle);
runGraphicalObjectPictureMarker(d->m_map, SituationMap::MarkerSymbolType::Square);
runGraphicalObjectPictureMarker(d->m_map, SituationMap::MarkerSymbolType::PushPin2D);
}
void SituationMapTestsMain::checkGraphicalObjectPictureMarker2()
{
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
MapImpl *mapImpl = static_cast<SituationMap::MapImpl *>(d->m_map);
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QString layername = layernames[1];
// real test
QScopedPointer<GraphObjPictureMarker> go(new GraphObjPictureMarker(mapImpl->getEsriGeoView(),
mapImpl->getGraphicsLayer(layername),
QLatin1String("TacticalAppearanceModuleTest"),
4712));
QVERIFY2(go, "objectFactory: GraphObjPictureMarker failed");
QVERIFY2(go->changed() == true, "GraphObjPictureMarker: changed failed");
go->resetChanged();
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->isSinglePoint() == false, "GraphObjPictureMarker: isSinglePoint failed");
QVERIFY2(go->isMultiPoint() == false, "GraphObjPictureMarker: isMultiPoint failed");
QVERIFY2(go->isArea() == false, "GraphObjPictureMarker: isArea failed");
go->setOrigin(Point3D(94000, 78000, .0));
QVERIFY2(go->isSinglePoint() == true, "GraphObjPictureMarker: isSinglePoint failed");
QImage image(100, 100, QImage::Format_ARGB32);
image.fill(Qt::transparent);
go->setImage(image);
QVERIFY2(go->changed() == true, "GraphObjPictureMarker: changed failed");
bool success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
// Change:
go->setMarkerSymbol(SituationMap::MarkerSymbolType::Cross, 100);
QVERIFY2(go->changed() == true, "GraphObjPictureMarker: changed failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
// Check visibility:
checkGraphicalObjectVisibility(go, QStringLiteral("GraphObjPictureMarker"));
}
//-------------------------------------------------------------------------------------------------------
void SituationMapTestsMain::checkGraphicalObjectPictureMarker3()
{
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
MapImpl *mapImpl = static_cast<SituationMap::MapImpl *>(d->m_map);
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QString layername = layernames[1];
// real test
QScopedPointer<GraphObjPictureMarker> go(new GraphObjPictureMarker(mapImpl->getEsriGeoView(),
mapImpl->getGraphicsLayer(layername),
QLatin1String("TacticalAppearanceModuleTest"),
4712));
QVERIFY2(go, "objectFactory: GraphObjPictureMarker failed");
go->setOrigin(Point3D(94000, 78000, .0));
QVERIFY2(go->isSinglePoint() == true, "GraphObjPictureMarker: isSinglePoint failed");
QImage image(100, 100, QImage::Format_ARGB32);
image.fill(Qt::red);
bool success = false;
qCritical() << " Goo !!!!";
// Set image first time
{
go->setImage(image);
QVERIFY2(go->changed() == true, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == true, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
qCritical() << " scaleCounter1a=" << go->scaleCounter();
QVERIFY2(go->scaleCounter() == 0, "GraphObjPictureMarker: scaleCounter failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
qCritical() << " scaleCounter1b=" << go->scaleCounter();
QVERIFY2(go->scaleCounter() == 0, "GraphObjPictureMarker: scaleCounter failed");
QVERIFY2(go->currentSize() == QSize(100, 100), "GraphObjPictureMarker: esriPictureMarkerSize failed");
}
// Set identical image again, nothing changed
{
go->setImage(image);
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
qCritical() << " scaleCounter2=" << go->scaleCounter();
QVERIFY2(go->scaleCounter() == 0, "GraphObjPictureMarker: scaleCounter failed");
QVERIFY2(go->currentSize() == QSize(100, 100), "GraphObjPictureMarker: esriPictureMarkerSize failed");
}
// Set different image
{
QImage image2(200, 200, QImage::Format_ARGB32);
image2.fill(Qt::red);
go->setImage(image2);
QVERIFY2(go->changed() == true, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
qCritical() << " scaleCounter3=" << go->scaleCounter();
QVERIFY2(go->scaleCounter() == 0, "GraphObjPictureMarker: scaleCounter failed");
QVERIFY2(go->currentSize() == QSize(200, 200), "GraphObjPictureMarker: esriPictureMarkerSize failed");
}
//
// use value for defaultSize:
//
{
const QSize myDefaultSize(50, 50);
// Set image first time
{
go->setImage(image, myDefaultSize);
QVERIFY2(go->changed() == true, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == true, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
qCritical() << " scaleCounter11a=" << go->scaleCounter();
QVERIFY2(go->scaleCounter() == 1, "GraphObjPictureMarker: scaleCounter failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
qCritical() << " scaleCounter11b=" << go->scaleCounter();
QVERIFY2(go->scaleCounter() == 1, "GraphObjPictureMarker: scaleCounter failed");
QVERIFY2(go->currentSize() == myDefaultSize, "GraphObjPictureMarker: esriPictureMarkerSize failed");
}
// Set different image, but keep value for defaultSize
{
QImage image2(200, 200, QImage::Format_ARGB32);
image2.fill(Qt::red);
go->setImage(image2, myDefaultSize);
QVERIFY2(go->changed() == true, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
qCritical() << " scaleCounter12=" << go->scaleCounter();
QVERIFY2(go->scaleCounter() == 2, "GraphObjPictureMarker: scaleCounter failed");
QVERIFY2(go->currentSize() == myDefaultSize, "GraphObjPictureMarker: esriPictureMarkerSize failed");
}
}
//
// take scale into account:
//
{
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
go->setScale(0.5);
success = go->updateView();
QVERIFY2(success == true, "GraphObjPictureMarker: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjPictureMarker: changed failed");
QVERIFY2(go->imageDefaultSizeChanged() == false, "GraphObjPictureMarker: imageDefaultSizeChanged failed");
qCritical() << " scaleCounter21=" << go->scaleCounter();
QVERIFY2(go->scaleCounter() == 3, "GraphObjPictureMarker: scaleCounter failed");
QVERIFY2(go->currentSize() == QSize(25, 25), "GraphObjPictureMarker: esriPictureMarkerSize failed");
}
}
//-------------------------------------------------------------------------------------------------------
class GraphObjRange : public SituationMap::GraphicalObjectRange
{
using BaseClass = GraphicalObjectRange;
public:
using BaseClass::BaseClass;
using BaseClass::changed;
using BaseClass::resetChanged;
};
void SituationMapTestsMain::checkGraphicalObjectRange()
{
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
MapImpl *mapImpl = static_cast<SituationMap::MapImpl *>(d->m_map);
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QString layername = layernames[1];
// real test
QScopedPointer<GraphObjRange> go(new GraphObjRange(mapImpl->getEsriGeoView(),
mapImpl->getGraphicsLayer(layername),
QLatin1String("TacticalAppearanceModuleTest"),
4712));
QVERIFY2(go, "objectFactory: GraphObjRange failed");
QVERIFY2(go->changed() == true, "GraphObjRange: changed failed");
go->resetChanged();
QVERIFY2(go->changed() == false, "GraphObjRange: changed failed");
QVERIFY2(go->isSinglePoint() == false, "GraphObjRange: isSinglePoint failed");
QVERIFY2(go->isMultiPoint() == false, "GraphObjRange: isMultiPoint failed");
QVERIFY2(go->isArea() == false, "GraphObjRange: isArea failed");
go->setOrigin(Point3D(94000, 78000, .0));
QVERIFY2(go->isSinglePoint() == true, "GraphObjRange: isSinglePoint failed");
// set value:
go->setRange(1000, 15);
QVERIFY2(go->changed() == true, "GraphObjRange: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjRange: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjRange: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjRange: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjRange: changed failed");
// Change:
go->setRange(2000, 15);
QVERIFY2(go->changed() == true, "GraphObjRange: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjRange: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjRange: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjRange: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjRange: changed failed");
// Change:
go->setRange(2000, -15);
QVERIFY2(go->changed() == true, "GraphObjRange: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjRange: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjRange: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjRange: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjRange: changed failed");
// Check visibility:
checkGraphicalObjectVisibility(go, QStringLiteral("GraphObjRange"));
}
//-------------------------------------------------------------------------------------------------------
class GraphObjText : public SituationMap::GraphicalObjectText
{
using BaseClass = GraphicalObjectText;
public:
using BaseClass::BaseClass;
using BaseClass::changed;
using BaseClass::resetChanged;
};
void SituationMapTestsMain::checkGraphicalObjectText()
{
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
MapImpl *mapImpl = static_cast<SituationMap::MapImpl *>(d->m_map);
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QVERIFY(layernames.size() > 1);
QString layername = layernames[1];
// real test
QScopedPointer<GraphObjText> go(new GraphObjText(mapImpl->getEsriGeoView(),
mapImpl->getGraphicsLayer(layername),
QLatin1String("TacticalAppearanceModuleTest"),
4712));
QVERIFY2(go, "objectFactory: GraphObjText failed");
QVERIFY2(go->changed() == true, "GraphObjText: changed failed");
go->resetChanged();
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->isSinglePoint() == false, "GraphObjText: isSinglePoint failed");
QVERIFY2(go->isMultiPoint() == false, "GraphObjText: isMultiPoint failed");
QVERIFY2(go->isArea() == false, "GraphObjText: isArea failed");
go->setOrigin(Point3D(94000, 78000, .0));
QVERIFY2(go->isSinglePoint() == true, "GraphObjText: isSinglePoint failed");
// set value:
//
// Text1
//
go->setText(QLatin1String("myDummyText"));
QVERIFY2(go->changed() == true, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
// Text2
go->setText(QLatin1String("myDummyTextMODIFIED"));
QVERIFY2(go->changed() == true, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
//
// textStyle1
//
go->rTextStyle().setSize(11.23456f);
QVERIFY2(go->changed() == true, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
// set identical value again -> not changed
const TextStyle ts = go->textStyle();
go->setTextStyle(ts);
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
// textStyle2
go->rTextStyle().setSize(111.9876f);
QVERIFY2(go->changed() == true, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
//
// setXOffset1
//
go->setXOffset(10.876f);
QVERIFY2(go->changed() == true, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
// set identical value again -> not changed
go->setXOffset(10.876f);
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
// setXOffset2
go->setXOffset(10.123f);
QVERIFY2(go->changed() == true, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
//
// setYOffset1
//
go->setYOffset(222.876f);
QVERIFY2(go->changed() == true, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
// set identical value again -> not changed
go->setYOffset(222.876f);
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
// setYOffset2
go->setYOffset(222.123f);
QVERIFY2(go->changed() == true, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
QVERIFY2(go->updateView() == true, "GraphObjText: updateView failed");
QVERIFY2(go->changed() == false, "GraphObjText: changed failed");
// Check visibility:
checkGraphicalObjectVisibility(go, QStringLiteral("GraphObjText"));
}
//-------------------------------------------------------------------------------------------------------
class GraphObjTactApp : public SituationMap::TacticalAppearance
{
using BaseClass = TacticalAppearance;
public:
using BaseClass::BaseClass;
using BaseClass::changed;
using BaseClass::resetChanged;
};
void SituationMapTestsMain::checkGraphicalObjectTacticalAppearance()
{
if (d->m_symbologyType == AdvancedSymbology::SymbologyType::None)
return;
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QString layername = layernames[1];
// real test
GraphObjTactApp *go = new GraphObjTactApp(static_cast<SituationMap::MapImpl *>(d->m_map),
layername,
QLatin1String("TacticalAppearanceModuleTest"),
4711);
QVERIFY2(go->changed() == true, "TacticalAppearance: changed failed");
go->resetChanged();
QVERIFY2(go->changed() == false, "TacticalAppearance: changed failed");
QVERIFY2(go->isSinglePoint() == false, "TacticalAppearance: isSinglePoint failed");
QVERIFY2(go->isMultiPoint() == false, "TacticalAppearance: isMultiPoint failed");
QVERIFY2(go->isArea() == false, "TacticalAppearance: isArea failed");
// set value:
go->setUniqueDesignation(QLatin1String("uniquDesignation"));
go->setVisibility(true);
go->setSelected(false);
go->setPickable(false);
go->setScale(2.34f);
QVERIFY2(go->changed() == true, "TacticalAppearance: changed failed");
SituationMap::SymbolData symbolData;
//
// Check SINGLE-POINTSYMBOL
//
{
switch (d->m_symbologyType)
{
case AdvancedSymbology::SymbologyType::APP6D:
case AdvancedSymbology::SymbologyType::MIL2525D:
symbolData.sidc = AdvancedSymbology::SidcCodec::encodeComplete( d->m_symbologyType, "10051000001213030000" );
break;
case AdvancedSymbology::SymbologyType::MIL2525C:
case AdvancedSymbology::SymbologyType::APP6B:
symbolData.sidc = AdvancedSymbology::SidcCodec::encodeComplete( d->m_symbologyType, "SFGPUCD---"); // PointSymbol
break;
case AdvancedSymbology::SymbologyType::None:
break;
}
go->setSymbol(symbolData);
QVERIFY2(go->changed() == true, "TacticalAppearance: changed failed");
// no origin/position
QVERIFY2(go->updateView() == false, "TacticalAppearance: updateView failed"); // -> 3 * ERROR-msg
QVERIFY2(go->changed() == false, "TacticalAppearance: changed failed");
// with origin/position
QPointF origin = s_basePoint.geographic( QPointF(94000, 78000) );
go->setOrigin(Point3D(origin.x(), origin.y(), .0));
QVERIFY2(go->changed() == true, "TacticalAppearance: changed failed");
QVERIFY2(go->updateView() == true, "TacticalAppearance: updateView failed");
QVERIFY2(go->updateView() == true, "TacticalAppearance: updateView failed");
QVERIFY2(go->changed() == false, "TacticalAppearance: changed failed");
}
//
// Check MULTI-POINTSYMBOL
//
{
switch (d->m_symbologyType)
{
case AdvancedSymbology::SymbologyType::APP6D:
case AdvancedSymbology::SymbologyType::MIL2525D:
symbolData.sidc = AdvancedSymbology::SidcCodec::encodeComplete(d->m_symbologyType, "10042500002701000000"); // 01042500002701000000 -> SymbolSet = 25 270100 (obstacle)
break;
case AdvancedSymbology::SymbologyType::MIL2525C:
symbolData.sidc = AdvancedSymbology::SidcCodec::encodeComplete(AdvancedSymbology::SymbologyType::MIL2525C, "GUMPNB----"); // MIL2525: 1100, GHSPAR----, Forward Arming and Refueling Area H -> Polygon
break;
case AdvancedSymbology::SymbologyType::APP6B:
symbolData.sidc = AdvancedSymbology::SidcCodec::encodeComplete(AdvancedSymbology::SymbologyType::APP6B, "GHTPGC----"); // App6B: 3370, GHTPGC----, Task - Canalize H, -> Polyline
break;
case AdvancedSymbology::SymbologyType::None:
break;
}
if (! symbolData.sidc.isEmpty())
{
go->setSymbol(symbolData);
// With ONE coordinate
QVERIFY2(go->updateView() == true, "TacticalAppearance: updateView failed");
QVERIFY2(go->changed() == false, "TacticalAppearance: changed failed");
// With coordinates
QList<QPointF> posCont2D;
posCont2D << s_basePoint.geographic( QPointF(94000, 78000) );
posCont2D << s_basePoint.geographic( QPointF(95000, 70000) );
posCont2D << s_basePoint.geographic( QPointF(94500, 78500) );
go->setPositions(convert2D3D(posCont2D));
QVERIFY2(go->changed() == true, "TacticalAppearance: changed failed");
QVERIFY2(go->updateView() == true, "TacticalAppearance: updateView failed");
QVERIFY2(go->updateView() == true, "TacticalAppearance: updateView failed");
QVERIFY2(go->changed() == false, "TacticalAppearance: changed failed");
}
}
// cleanup:
delete go;
}
//-------------------------------------------------------------------------------------------------------
class BasePathObjImp : public SituationMap::BasicPathObjectImpl
{
using BaseClass = BasicPathObjectImpl;
public:
using BaseClass::BaseClass;
using BaseClass::init;
};
void SituationMapTestsMain::checkBasicPathObjectImpl()
{
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
SituationMap::ObjectFactory &objFac = d->m_map->objectFactory();
// use an LOGICAL layer (not basemap)
const QStringList layernames = layerFac.layernames();
QVERIFY(layernames.size() > 1);
QString layername = layernames[1];
// real test
BasePathObjImp *pathObj = new BasePathObjImp(QLatin1String("BasicPathObjectModuleTest"));
bool initOk = pathObj->init(static_cast<SituationMap::MapImpl *>(d->m_map),
layername,
SituationMap::GraphicalObjectPathType::Polygon);
QVERIFY2(initOk == true, "BasicPathObjectImpl: init failed");
// set positions:
SituationMap::PositionCont posCont;
// check empty container:
pathObj->setPositions(posCont);
bool success = pathObj->updateView();
QVERIFY2(success == false, "BasicPathObjectImpl: updateView failed");
// check empty container with ArrowHeads
pathObj->setArrowHeadStart(true);
pathObj->setArrowHeadEnd(true);
success = pathObj->updateView();
QVERIFY2(success == false, "BasicPathObjectImpl: updateView failed");
// check container without ArrowHeads
pathObj->setArrowHeadStart(false);
pathObj->setArrowHeadEnd(false);
QPointF center = d->m_map->centerPoint();
QList<QPointF> posCont2D;
posCont2D << s_basePoint.geographic( center + QPointF( 0, 0) );
posCont2D << s_basePoint.geographic( center + QPointF( 0, 5000) );
posCont2D << s_basePoint.geographic( center + QPointF(5000, 5000) );
posCont2D << s_basePoint.geographic( center + QPointF(5000, 0) );
pathObj->setPositions(convert2D3D(posCont2D));
success = pathObj->updateView();
QVERIFY2(success == true, "BasicPathObjectImpl: updateView failed");
int numberOfValuesChanged = pathObj->numberOfValuesChanged();
INFO_LOG(m_logger) << " numberOfValuesChanged = " << numberOfValuesChanged;
QVERIFY2(numberOfValuesChanged == 0, "BasicPathObject: numberOfValuesChanged failed");
success = pathObj->updateView();
QVERIFY2(success == true, "BasicPathObjectImpl: updateView failed");
numberOfValuesChanged = pathObj->numberOfValuesChanged();
INFO_LOG(m_logger) << " numberOfValuesChanged = " << numberOfValuesChanged;
QVERIFY2(numberOfValuesChanged == 0, "BasicPathObject: numberOfValuesChanged failed");
QTest::qWait(timeToDelay);
pathObj->setArrowHeadStart(true);
pathObj->setArrowHeadEnd(true);
success = pathObj->updateView();
QVERIFY2(success == true, "BasicPathObjectImpl: updateView failed");
numberOfValuesChanged = pathObj->numberOfValuesChanged();
INFO_LOG(m_logger) << " numberOfValuesChanged = " << numberOfValuesChanged;
QVERIFY2(numberOfValuesChanged == 0, "BasicPathObject: numberOfValuesChanged failed");
for (int i = 0; i < 2; ++i)
pathObj->setTextOnSegment(i, QStringLiteral("segText_%1").arg(i));
success = pathObj->updateView();
QVERIFY2(success == true, "BasicPathObjectImpl: updateView failed");
numberOfValuesChanged = pathObj->numberOfValuesChanged();
INFO_LOG(m_logger) << " numberOfValuesChanged = " << numberOfValuesChanged;
QVERIFY2(numberOfValuesChanged == 0, "BasicPathObject: numberOfValuesChanged failed");
QTest::qWait(timeToDelay);
// QSignalSpy spy(d->m_sitMap, SIGNAL(mapReady()));
// spy.wait(5000);
// set origin/radius:
// !!!arrowHeads will disappear!!!
QPointF center2D = s_basePoint.geographic(center);
pathObj->setOrigin(Point3D(center2D.x(), center2D.y(), .0));
pathObj->setRadius(2000);
success = pathObj->updateView();
QVERIFY2(success == true, "BasicPathObjectImpl: updateView failed");
numberOfValuesChanged = pathObj->numberOfValuesChanged();
INFO_LOG(m_logger) << " numberOfValuesChanged = " << numberOfValuesChanged;
QVERIFY2(numberOfValuesChanged == 0, "BasicPathObject: numberOfValuesChanged failed");
// setIdentifierVisible
pathObj->setIdentifierVisible(true);
success = pathObj->updateView();
QVERIFY2(success == true, "BasicPathObjectImpl: updateView failed");
numberOfValuesChanged = pathObj->numberOfValuesChanged();
INFO_LOG(m_logger) << " numberOfValuesChanged = " << numberOfValuesChanged;
QVERIFY2(numberOfValuesChanged == 0, "BasicPathObject: numberOfValuesChanged failed");
QTest::qWait(timeToDelay);
#ifdef SUPPORT_SUBSIDIARY_LINES
//
// Subsidiary:
//
QList<int> subsidiaryIdxInUse;
// check pathIndexInUse:
subsidiaryIdxInUse = pathObj->subsidiaryPathIndexInUse();
QVERIFY2(subsidiaryIdxInUse.size() == 0 , "BasicPathObjectImpl: subsidiaryPathIndexInUse failed");
// check non-existing:
SituationMap::PositionCont retrieved;
retrieved = pathObj->subsidiaryPositions(12345);
QVERIFY2(retrieved.size() == 0 , "BasicPathObjectImpl: subsidiaryPositions failed");
// set path:
SituationMap::PositionCont posCont2;
posCont2 << center + QPointF(0, 0);
posCont2 << center + QPointF(0, 3000);
posCont2 << center + QPointF(3000, 3000);
pathObj->setSubsidiaryPositions(12, posCont2);
const SituationMap::PositionCont &posContTemp = pathObj->subsidiaryPositions(12);
QVERIFY2(posContTemp == posContTemp, "BasicPathObjectImpl: subsidiaryPositions failed");
success = pathObj->updateView();
QVERIFY2(success == true, "BasicPathObjectImpl: updateView (setSubsidiaryPositions) failed");
numberOfValuesChanged = pathObj->numberOfValuesChanged();
INFO_LOG(m_logger) << " numberOfValuesChanged = " << numberOfValuesChanged;
QVERIFY2(numberOfValuesChanged == 0, "BasicPathObject: numberOfValuesChanged failed");
// Overlapping polygons (with fillpattern solid) will NOT show an fillpattern within the onverlapping area!!!
// Reason: ???
// 2015-11-19, Version 10.2.6)
QTest::qWait(timeToDelay);
subsidiaryIdxInUse = pathObj->subsidiaryPathIndexInUse();
QVERIFY2(subsidiaryIdxInUse.size() == 1 , "BasicPathObjectImpl: subsidiaryPathIndexInUse failed");
// retrieve:
retrieved = pathObj->subsidiaryPositions(12);
QVERIFY2(posCont2 == retrieved , "BasicPathObjectImpl: subsidiaryPositions failed");
// clear:
pathObj->clearSubsidiaryPositions();
subsidiaryIdxInUse = pathObj->subsidiaryPathIndexInUse();
QVERIFY2(subsidiaryIdxInUse.size() == 0 , "BasicPathObjectImpl: subsidiaryPathIndexInUse failed");
#endif // SUPPORT_SUBSIDIARY_LINES
// cleanup:
delete pathObj;
QVERIFY2(objFac.count() == 0 , "objectFactory: count failed");
//
// check identical positions:
//
{
// real test
QScopedPointer<BasePathObjImp> pathObj(new BasePathObjImp(QLatin1String("BasicPathObjectModuleTest")));
bool initOk = pathObj->init(static_cast<SituationMap::MapImpl *>(d->m_map),
layername,
SituationMap::GraphicalObjectPathType::Polygon);
QVERIFY2(initOk == true, "BasicPathObjectImpl: init failed");
// check doubled start and end position:
{
// set positions:
QList<QPointF> posCont;
QPointF center = d->m_map->centerPoint();
qWarning() << " center=" << center;
posCont << center + QPointF(0, 0);
posCont << center + QPointF(0, 0.001);
posCont << center + QPointF(0.001, 0.001);
posCont << center + QPointF(0, 0);
pathObj->setPositions(convert2D3D(posCont2D));
bool success = pathObj->updateView();
QVERIFY2(success == true, "BasicPathObjectImpl: updateView failed");
success = pathObj->updateView();
QVERIFY2(success == true, "BasicPathObjectImpl: updateView failed");
QTest::qWait(timeToDelay);
}
// check doubled positions:
{
// set positions:
SituationMap::PositionCont posCont;
QPointF center2D = d->m_map->centerPoint();
Point3D center(center2D.x(), center2D.y(), .0);
posCont << center + Point3D(0, 0, .0);
posCont << center + Point3D(0, 0, .0);
posCont << center + Point3D(0, 0, .0);
posCont << center + Point3D(0.001, 0, .0);
posCont << center + Point3D(0.001, 0.001, .0);
posCont << center + Point3D(0, 0, .0);
posCont << center + Point3D(0, 0, .0);
pathObj->setPositions(posCont);
bool success = pathObj->updateView();
QVERIFY2(success == true, "BasicPathObjectImpl: updateView failed");
success = pathObj->updateView();
QVERIFY2(success == true, "BasicPathObjectImpl: updateView failed");
QTest::qWait(timeToDelay);
}
}
}
void SituationMapTestsMain::checkChemicalAgent()
{
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::ObjectFactory &objFac = d->m_map->objectFactory();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QString layername = layernames[1];
// real test
SituationMap::RefPointer<SituationMap::ChemicalAgent> cAgent;
cAgent = objFac.create<SituationMap::ChemicalAgent>(layername, QLatin1String("ChemAgentId1"));
QVERIFY2(cAgent.valid() == true , "objectFactory: create failed");
QVERIFY2(objFac.count() == 1 , "objectFactory: count failed");
QList<QPointF> posCont2D;
posCont2D << s_basePoint.geographic( QPointF( 1000, 1000) );
posCont2D << s_basePoint.geographic( QPointF(85000, 70000) );
posCont2D << s_basePoint.geographic( QPointF(84500, 78500) );
cAgent->setPositions(convert2D3D(posCont2D));
bool success = cAgent->updateView();
QVERIFY2(success == true, "ChemicalAgent: updateView failed");
success = cAgent->updateView();
QVERIFY2(success == true, "ChemicalAgent: updateView failed");
QTest::qWait(timeToDelay);
QPointF origin = s_basePoint.geographic( QPointF(0, 1000) );
cAgent->setOrigin(Point3D::fromQPointF(origin));
cAgent->setRadius(20000);
success = cAgent->updateView();
QVERIFY2(success == true, "ChemicalAgent: updateView failed");
}
void SituationMapTestsMain::checkParticipant()
{
if (d->m_symbologyType == AdvancedSymbology::SymbologyType::None)
return;
// Preperations:
reInitTestCaseUntilSetCenter();
SituationMap::ObjectFactory &objFac = d->m_map->objectFactory();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
// use an LOGICAL layer (not basemap)
QStringList layernames = layerFac.layernames();
QString layername = layernames[1];
// real test
SituationMap::RefPointer<SituationMap::Participant> objPtr1;
objPtr1 = objFac.create<SituationMap::Participant>(layername, QLatin1String("UnitTestId1"));
QVERIFY2(objPtr1.valid() == true , "objectFactory: create failed");
QVERIFY2(objFac.count() == 1 , "objectFactory: count failed");
objPtr1->setTextModifier(SituationMap::Participant::TextModifier::EF_ReinforcedReduced, QLatin1String("EF_ReinforcedReduced"));
objPtr1->setTextModifier(SituationMap::Participant::TextModifier::M_HigherFormation, QLatin1String("M_HigherFormation"));
objPtr1->setTextModifier(SituationMap::Participant::TextModifier::T_UniqueDesignation, QLatin1String("T_UniqueDesignation"));
objPtr1->setTextModifier(SituationMap::Participant::TextModifier::W_DateTimeGroup, QLatin1String("W_DateTimeGroup"));
objPtr1->setVisibility(true);
// objPtr1->setVisibility(SituationMap::ObjectAppearance::Technical, false); // no sense
SituationMap::SymbolData symData;
symData.sidc = QLatin1String("SUGPUSAJ--****X");
// 123456789012345
symData.color = Qt::cyan; // Will be overwritten via partyId.
symData.size = 0.5;
objPtr1->setSymbol(symData);
objPtr1->setScale(2.0);
objPtr1->setPartyId(4);
QPointF origin = s_basePoint.geographic( QPointF(94000, 78003) );
objPtr1->setOrigin(Point3D::fromQPointF(origin));
objPtr1->setInjury(SituationMap::Injury::TotalKill, 3);
objPtr1->setAdditionalSymbol(SituationMap::AdditionalSymbolType::NbcProtection, true);
objPtr1->setAdditionalSymbol(SituationMap::AdditionalSymbolType::Manipulation, true);
objPtr1->setAdditionalSymbol(SituationMap::AdditionalSymbolType::NoPosition, true);
objPtr1->setAdditionalSymbol(SituationMap::AdditionalSymbolType::BiteError, true);
objPtr1->setMarked(false);
objPtr1->setRanges(QVector<int>() << 1000 << 10000);
bool success = objPtr1->updateView();
QVERIFY2(success == true, "participant: updateView failed");
SituationMap::ParticipantImpl *partiImpl = dynamic_cast<SituationMap::ParticipantImpl *>(objPtr1.get());
if (partiImpl)
{
int numberOfValuesChanged = partiImpl->numberOfValuesChanged();
INFO_LOG(m_logger) << " numberOfValuesChanged = " << numberOfValuesChanged;
QVERIFY2(numberOfValuesChanged == 0, "participant: numberOfValuesChanged failed");
bool success2 = objPtr1->updateView();
QVERIFY2(success2 == true, "participant: updateView failed");
int numberOfValuesChanged2 = partiImpl->numberOfValuesChanged();
INFO_LOG(m_logger) << " numberOfValuesChanged2 = " << numberOfValuesChanged2;
QVERIFY2(numberOfValuesChanged2 == 0, "participant: numberOfValuesChanged2 failed");
}
// remove:
objPtr1->removeMySelf();
QVERIFY2(objFac.count() == 0, "objectFactory: count failed");
}
void SituationMapTestsMain::checkEventDispatcher()
{
reInitTestCaseUntilSetCenter();
QGraphicsView * mapWidget = d->m_map->getQGraphicsView();
SituationMap::RB::EventDispatcher * dispatcher1 = new SituationMap::RB::EventDispatcher( static_cast<QWidget*>(mapWidget->viewport()) );
unsigned int noOfDisp1 = dispatcher1->numberOfEventDispatcher();
SituationMap::RB::EventDispatcher * dispatcher2 = new SituationMap::RB::EventDispatcher( static_cast<QWidget*>(mapWidget->viewport()) );
unsigned int noOfDisp2 = dispatcher1->numberOfEventDispatcher();
QVERIFY2( noOfDisp1 == 2 , "wrong number of event dispatcher (first test)");
QVERIFY2( noOfDisp2 == noOfDisp1+1, "wrong number of event dispatcher (second test)");
delete dispatcher2;
noOfDisp2 = dispatcher1->numberOfEventDispatcher();
QVERIFY2(noOfDisp2 == noOfDisp1, "wrong number of event dispatcher (third test)");
} // SituationMapTestsMain::checkEventDispatcher
static bool rubberbandcheckIsComplete = false;
static QVector<QPointF> rubberbandVertexList;
template<class RubberbandClass> void SituationMapTestsMain::checkRubberband(const char *className)
{
reInitTestCaseUntilSetCenter();
static bool testok = true;
auto slotFunc = [ = ](SituationMap::RB::RubberbandBase * rubberband)
{
if (rubberband->coordinatesAreValid())
{
QVector<QPointF> coordinateVector = rubberband->coordinateVector();
if (coordinateVector.size() == rubberbandVertexList.size())
{
for (int i = 0; i < coordinateVector.size(); ++i)
{
QPointF simPoint = coordinateVector[i];
QPointF p = rubberbandVertexList[i];
if ((fabs(simPoint.x() - p.x()) > d->m_map->pixelSizeMeter()) || (fabs(simPoint.y() - p.y()) > d->m_map->pixelSizeMeter()))
testok = false;
}
}
else testok = false;
}
rubberbandcheckIsComplete = true;
}; // slotFunc
rubberbandcheckIsComplete = false;
testok = true;
RubberbandClass *rband = d->m_map->rubberbandFactory().create<RubberbandClass>();
static char msg[200];
if (rband == nullptr)
{
sprintf(msg, "%s rubberband factory failure", className);
QVERIFY2(false, msg);
}
else
{
rband->setCoordinateVector(rubberbandVertexList);
connect(rband, &SituationMap::RB::Rubberband::apply, slotFunc);
connect(rband, &SituationMap::RB::Rubberband::abort, slotFunc);
QTimer::singleShot(200, this, [ = ]()
{
rband->applyAndEndAction(nullptr, 0, 0);
});
// Wait for finish Rubberband
while (!rubberbandcheckIsComplete)
QCoreApplication::processEvents();
delete rband; rband = nullptr; // here it is ok to use delete directly
sprintf(msg, "%s coordinate test failed", className);
QVERIFY2(testok, msg);
}
} // SituationMapTestsMain::checkRubberband
void SituationMapTestsMain::checkRubberbandMultiPointFeature()
{
SituationMap::CoordTranslationFunctor * ct = d->m_map->coordTranslationFunctor();
rubberbandVertexList.clear();
if (ct)
{
rubberbandVertexList << ct->mapToGeographic(QPointF(-338163 , 168551 )+d->m_geoOff)
<< ct->mapToGeographic(QPointF( 154770 , 168551 )+d->m_geoOff)
<< ct->mapToGeographic(QPointF( 154770 , - 71025 )+d->m_geoOff)
<< ct->mapToGeographic(QPointF(-338163 , - 71025 )+d->m_geoOff)
<< ct->mapToGeographic(QPointF( 36042.4 , 38162.5)+d->m_geoOff)
<< ct->mapToGeographic(QPointF( 302120 , - 46643.1)+d->m_geoOff)
<< ct->mapToGeographic(QPointF( 244876 , -224735 )+d->m_geoOff)
<< ct->mapToGeographic(QPointF(- 21201.4, -139929 )+d->m_geoOff)
;
}
else
{
rubberbandVertexList << QPointF(-338163 , 168551 )+d->m_geoOff
<< QPointF( 154770 , 168551 )+d->m_geoOff
<< QPointF( 154770 , - 71025 )+d->m_geoOff
<< QPointF(-338163 , - 71025 )+d->m_geoOff
<< QPointF( 36042.4 , 38162.5)+d->m_geoOff
<< QPointF( 302120 , - 46643.1)+d->m_geoOff
<< QPointF( 244876 , -224735 )+d->m_geoOff
<< QPointF(- 21201.4, -139929 )+d->m_geoOff
;
}
checkRubberband<SituationMap::RB::RubberbandMultiPointFeature>("RubberbandMultiPointFeature");
} // SituationMapTestsMain::checkRubberbandMultiPointFeature
void SituationMapTestsMain::checkRubberbandRectangle()
{
SituationMap::CoordTranslationFunctor * ct = d->m_map->coordTranslationFunctor();
rubberbandVertexList.clear();
if (ct)
{
rubberbandVertexList << ct->mapToGeographic( QPointF (154770 , 168551)+d->m_geoOff)
<< ct->mapToGeographic(QPointF( 154770 , - 71025)+d->m_geoOff)
<< ct->mapToGeographic(QPointF(-338163 , - 71025)+d->m_geoOff)
<< ct->mapToGeographic(QPointF(-338163 , 168551)+d->m_geoOff)
;
}
else
{
rubberbandVertexList << QPointF (154770 , 168551)+d->m_geoOff
<< QPointF( 154770 , - 71025)+d->m_geoOff
<< QPointF(-338163 , - 71025)+d->m_geoOff
<< QPointF(-338163 , 168551)+d->m_geoOff
;
}
reInitTestCaseUntilSetCenter();
static bool testok = true;
auto slotFunc = [ = ](SituationMap::RB::RubberbandBase * rubberband)
{
// check if coordinates of rubberband and input vector are remaining identical
if (rubberband->coordinatesAreValid())
{
const QVector<QPointF> & coordinateVector = rubberband->coordinateVector();
if (coordinateVector.size() == rubberbandVertexList.size())
{
double mapPixelSize = d->m_map->pixelSizeMeter();
for (int i = 0; i < coordinateVector.size(); ++i)
{
const QPointF &simPoint = coordinateVector[i];
int matchCount = 0;
for (int j = 0; j < rubberbandVertexList.size(); ++j)
{
QPointF p = rubberbandVertexList[j];
double dx = fabs(simPoint.x() - p.x());
double dy = fabs(simPoint.y() - p.y());
if ((dx < mapPixelSize) && (dy < mapPixelSize))
{
++matchCount;
}
}
if (matchCount != coordinateVector.size()) testok = false;
}
}
else testok = false;
}
rubberbandcheckIsComplete = true;
}; // slotFunc
rubberbandcheckIsComplete = false;
testok = true;
SituationMap::RB::RubberbandRectangle *rband = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandRectangle>();
if (rband == nullptr)
QVERIFY2(false, "RubberbandRectangle rubberband factory failure");
else
{
rband->setCoordinateVector(rubberbandVertexList);
connect(rband, &SituationMap::RB::Rubberband::apply, slotFunc);
connect(rband, &SituationMap::RB::Rubberband::abort, slotFunc);
QTimer::singleShot(200, this, [ = ]()
{
rband->applyAndEndAction(nullptr, 0, 0);
});
// Wait for finish Rubberband
while (!rubberbandcheckIsComplete)
QCoreApplication::processEvents();
delete rband; rband = nullptr; // here it is ok to use delete directly
QVERIFY2(testok, "RubberbandRectangle coordinate test failed");
}
} // SituationMapTestsMain::checkRubberbandRectangle
void SituationMapTestsMain::checkRubberbandRectangleIndex()
{
SituationMap::CoordTranslationFunctor * ct = d->m_map->coordTranslationFunctor();
rubberbandVertexList.clear();
if (ct)
{
rubberbandVertexList << ct->mapToGeographic( QPointF (154770 , 168551)+d->m_geoOff)
<< ct->mapToGeographic(QPointF( 154770 , - 71025)+d->m_geoOff)
<< ct->mapToGeographic(QPointF(-338163 , - 71025)+d->m_geoOff)
<<ct->mapToGeographic( QPointF(-338163 , 168551)+d->m_geoOff)
;
}
else
{
rubberbandVertexList << QPointF (154770 , 168551)+d->m_geoOff
<< QPointF( 154770 , - 71025)+d->m_geoOff
<< QPointF(-338163 , - 71025)+d->m_geoOff
<< QPointF(-338163 , 168551)+d->m_geoOff
;
}
reInitTestCaseUntilSetCenter();
static bool testok = true;
auto slotFunc = [ = ](SituationMap::RB::RubberbandBase *rubberband)
{
if (rubberband->coordinatesAreValid())
{
QVector<QPointF> coordinateVector = rubberband->coordinateVector();
if (coordinateVector.size() == rubberbandVertexList.size())
{
for (int i = 0; i < coordinateVector.size(); ++i)
{
const QPointF & simPoint = coordinateVector[i];
const QPointF & p = rubberbandVertexList[i];
if ((fabs(simPoint.x() - p.x()) > d->m_map->pixelSizeMeter()) && (fabs(simPoint.y() - p.y()) > d->m_map->pixelSizeMeter()))
{
testok = false;
}
}
}
else testok = false;
}
rubberbandcheckIsComplete = true;
}; // slotFunc
rubberbandcheckIsComplete = false;
testok = true;
SituationMap::RB::RubberbandRectangle *rband = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandRectangle>();
if (rband == nullptr)
QVERIFY2(false, "RubberbandRectangle rubberband factory failure");
else
{
rband->setCoordinateVector(rubberbandVertexList);
connect(rband, &SituationMap::RB::Rubberband::apply, slotFunc);
connect(rband, &SituationMap::RB::Rubberband::abort, slotFunc);
QTimer::singleShot(200, this, [ = ]()
{
rband->applyAndEndAction(nullptr, 0, 0);
});
// Wait for finish Rubberband
while (!rubberbandcheckIsComplete)
QCoreApplication::processEvents();
delete rband; rband = nullptr; // here it is ok to use delete directly
QVERIFY2(testok, "RubberbandRectangle coordinate index test failed");
}
} // SituationMapTestsMain::checkRubberbandRectangleIndex
void SituationMapTestsMain::checkRubberbandCorridor()
{
rubberbandVertexList.clear();
checkRubberband<SituationMap::RB::RubberbandCorridor>( "RubberbandCorridor" );
} // SituationMapTestsMain::checkRubberbandCorridor
template<class RubberbandClass> void SituationMapTestsMain::checkRubberbandProjection(const char *className)
{
reInitTestCaseUntilSetCenter();
SituationMap::CoordTranslationFunctor * ct = d->m_map->coordTranslationFunctor();
rubberbandVertexList.clear();
if (ct)
{
rubberbandVertexList << ct->mapToGeographic(QPointF( 154770 , 168551)+d->m_geoOff)
<< ct->mapToGeographic(QPointF(-338163 , 168551)+d->m_geoOff)
<< ct->mapToGeographic(QPointF( 154770 , - 71025)+d->m_geoOff)
;
}
else
{
rubberbandVertexList << QPointF (154770 , 168551)+d->m_geoOff
<< QPointF(-338163 , 168551)+d->m_geoOff
<< QPointF( 154770 , - 71025)+d->m_geoOff
;
}
SituationMap::RB::Rubberband *rband = d->m_map->rubberbandFactory().create<SituationMap::RB::RubberbandPointCluster>();
if (rband)
{
rband->setCoordinateVector(rubberbandVertexList);
bool mismatch = false;
QVector<QPointF> vertexList = rband->coordinateVector();
for (int i = 0; i < vertexList.size(); ++i)
{
qreal dx = fabs(vertexList[i].x() - rubberbandVertexList[i].x());
qreal dy = fabs(vertexList[i].y() - rubberbandVertexList[i].y());
if ((dx > 0.001) && (dy > 0.001)) mismatch = true;
}
delete rband;
static char msg[200];
sprintf(msg, "%s oordinate projection failed.", className);
QVERIFY2((!mismatch), msg);
}
} // SituationMapTestsMain::checkRubberbandProjection
void SituationMapTestsMain::checkRubberCoordinateProjection()
{
checkRubberbandProjection<SituationMap::RB::RubberbandPointCluster>("RubberbandPointCluster");
checkRubberbandProjection<SituationMap::RB::RubberbandPointCluster>("RubberbandMultiPointFeature");
} // SituationMapTestsMain::checkRubberCoordinateProjection
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
void SituationMapTestsMain::reInitTestCaseUntilSetCenter()
{
// Preperations:
initTestCase();
checkMapReady();
// // checkCenter();
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
INFO_LOG(m_logger) << " layernames = " << layerFac.layernames().join(QLatin1String(";"));
if (layerFac.isUsingBaseMapBuiltIn())
{
d->m_basemapCountRef = 1;
} else {
d->m_basemapCountRef = 1; // maybe '2', depending on ini
}
#ifdef CHECK_LAYER
int basemapCount = layerFac.layernames(LayerType::Basemap).count();
int jumpPointLayerCount = 0;
jumpPointLayerCount = layerFac.layernames(LayerType::JumpPoint).count();
QVERIFY2(jumpPointLayerCount == 1 , "layerFactory: count failed");
int operationalLayerCount = layerFac.layernames(LayerType::Operational).count();
QVERIFY2(basemapCount == d->m_basemapCountRef , "layerFactory: count failed");
QVERIFY2(operationalLayerCount == 9 , "layerFactory: count failed"); // AES, Participants
int technLayerCount = d->m_map->technicalLayerCount();
INFO_LOG(m_logger) << " technicalLayerCount = " << technLayerCount;
QVERIFY2(technLayerCount == basemapCount, "objectFactory: count failed");
INFO_LOG(m_logger) << " basemapCount = " << basemapCount;
INFO_LOG(m_logger) << " jumpPointLayerCount = " << jumpPointLayerCount;
INFO_LOG(m_logger) << " operationalLayerCount = " << operationalLayerCount;
QVERIFY2(layerFac.count() == basemapCount + jumpPointLayerCount + operationalLayerCount , "layerFactory: count failed");
SituationMap::ObjectFactory &objFac = d->m_map->objectFactory();
INFO_LOG(m_logger) << " objFac.count() =" << objFac.count();
QVERIFY2(objFac.count() == 0, "objectFactory: count failed");
#endif
}
//-------------------------------------------------------------------------------------------------------
void SituationMapTestsMain::cleanupTestCase()
{
DEBUG_LOG(m_logger) << LOGFUNCTION;
delete d->m_sitMap;
DEBUG_LOG(m_logger) << LOGFUNCTION;
}