1238 lines
49 KiB
C++
Executable File
1238 lines
49 KiB
C++
Executable File
/**
|
||
* @RDE_HEADER@
|
||
* Interface-Implementation of Participant
|
||
* $Id$
|
||
* $HeadURL$
|
||
* $Author$
|
||
*/
|
||
|
||
// Own
|
||
#include "participant_impl.h"
|
||
#include "basic_path_object_impl.h"
|
||
#include <MapImpl/map_impl.h>
|
||
#include <Map/party_id_to_color_functor.h>
|
||
#include <Map/bounding_box.h>
|
||
#include <GraphicalObjects/graphical_object_picture_marker.h>
|
||
#include <Symbology/symbol_dictionary.h> // for renderExtensions
|
||
#include <Symbology/sidc_builder.h> //
|
||
#include <GraphicalObjects/graphical_object_path.h>
|
||
|
||
|
||
// ESRI
|
||
#include <arcgis/Point.h>
|
||
|
||
|
||
// Qt
|
||
#include <QSize>
|
||
#include <QPolygon>
|
||
#include <QPainter>
|
||
#include <QPen>
|
||
|
||
#ifdef LTS_DEBUG
|
||
# include <QMessageBox>
|
||
#endif
|
||
|
||
#include <functional>
|
||
|
||
|
||
namespace SituationMap
|
||
{
|
||
|
||
// to get access to 'init'
|
||
class DesignationLocalBasicPathObject final : public BasicPathObjectImpl
|
||
{
|
||
DesignationLocalBasicPathObject() {}
|
||
virtual ~DesignationLocalBasicPathObject() {}
|
||
public:
|
||
using BasicPathObjectImpl::BasicPathObjectImpl;
|
||
using BasicPathObjectImpl::init;
|
||
using BasicPathObjectImpl::setUniqueId;
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class ParticipantImpl
|
||
//-----------------------------------------------------------------------------
|
||
ParticipantImpl::ParticipantImpl(const QString &debugInfo)
|
||
: Participant() // Interface
|
||
, BaseClass(debugInfo) // Implementation
|
||
, m_logger(getLogger("ParticipantImpl"))
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||
|
||
m_origin.setMapObjectImpl(this);
|
||
initTextModifierData();
|
||
|
||
m_movementTrackCoords.setMapObjectImpl(this);
|
||
|
||
// m_symbolResultWatcher is canceled on destruction.
|
||
// So it`s safe that no signal will be fired afterwards.
|
||
// To avoid CLang warnings use m_symbolResultWatcher as context (3rd para), although it´s not intended.
|
||
// Better idea?
|
||
QObject::connect(&m_symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady,
|
||
&m_symbolResultWatcher, std::bind(&ParticipantImpl::onSymbolResultReady, this));
|
||
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||
}
|
||
|
||
void ParticipantImpl::onSymbolResultReady()
|
||
{
|
||
QSharedPointer<AdvancedSymbology::SymbolResult> symResult = m_symbolResultWatcher.symbolResult();
|
||
|
||
if (AdvancedSymbology::SymbolDictionary::doParanoiaChecks() && (! symResult))
|
||
{
|
||
FATAL_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " no symResult..."
|
||
<< " m_symDataToRender= '" << m_symDataToRender.toString();
|
||
abort();
|
||
}
|
||
|
||
|
||
if (! symResult)
|
||
return; // should NEVER happen! (Which object should have triggered the signal???)
|
||
|
||
const SymbolImage &symImage = symResult->symbolImage();
|
||
|
||
if (AdvancedSymbology::SymbolDictionary::doParanoiaChecks())
|
||
{
|
||
if (m_symDataToRender.sidc != symResult->symbolDataToRender().sidc ||
|
||
m_symDataToRender.role != symResult->symbolDataToRender().role)
|
||
{
|
||
FATAL_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " resultReady...sidc or role mismatch..."
|
||
<< " m_symDataToRender= '" << m_symDataToRender.toString()
|
||
<< " symResult->symbolDataToRender()= '" << symResult->symbolDataToRender().toString();
|
||
abort();
|
||
}
|
||
|
||
if (symImage.image().isNull())
|
||
{
|
||
FATAL_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " image is null";
|
||
abort();
|
||
}
|
||
}
|
||
|
||
// For preview purpose:
|
||
m_symbolImage.setValid(true);
|
||
m_symbolImage.setImage(symImage.image());
|
||
|
||
if (m_mainGraphicalObject)
|
||
{
|
||
GraphicalObjectPictureMarker *goPicture =
|
||
static_cast<GraphicalObjectPictureMarker *>(m_mainGraphicalObject);
|
||
|
||
goPicture->setImage(symImage.image());
|
||
if (!goPicture->updateView())
|
||
FATAL_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " updateView failed";
|
||
|
||
|
||
// Note:
|
||
// XML-Symbols have their own/symbol-specific scale.
|
||
// We don´t have that value directly here, so we have to 'reinterpret'
|
||
// the final image:
|
||
// do this calculation only for Xml symbols,
|
||
// otherwise the other symbols will scale in two steps if you modify the slider
|
||
if (AdvancedSymbology::SidcCodec::decodeSidcType(symResult->symbolDataToRender().sidc) == AdvancedSymbology::SidcCodec::SidcType::CivilXml)
|
||
{
|
||
int imageSize = actualImage().size().width(); // width and heigth are equal
|
||
if (imageSize > 0)
|
||
m_scale4XmlSymbolWithSymbolSpecificScale = 0.7 * imageSize / (51 * m_scale.value() * m_symbol.value().size); // 51 == EsriSymbolSize
|
||
}
|
||
} else {
|
||
if (AdvancedSymbology::SymbolDictionary::doParanoiaChecks())
|
||
{
|
||
FATAL_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " no m_mainGraphicalObject";
|
||
abort();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
ParticipantImpl::~ParticipantImpl()
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||
|
||
// clear all LaserDesignations:
|
||
m_designationData.reset();
|
||
|
||
for (const auto &mod : m_textModifierCont)
|
||
delete mod.goText;
|
||
|
||
// abort pending call:
|
||
m_symbolResultWatcher.cancel();
|
||
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||
}
|
||
|
||
AdvancedSymbology::SymbologyType ParticipantImpl::symbologyType() const
|
||
{
|
||
return (m_dictionary) ? m_dictionary->symbologyType() : AdvancedSymbology::SymbolDictionary::defaultSymbologyType();
|
||
} // AdvancedSymbology::SymbologyType ParticipantImpl::symbologyType() const
|
||
|
||
|
||
void ParticipantImpl::initTextModifierData()
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||
|
||
TextModifierData data;
|
||
data.verticalAlignment = VerticalAlignment::Bottom;
|
||
|
||
// right side:
|
||
data.horizontalAlignment = HorizontalAlignment::Left;
|
||
|
||
int xOffset = 0; // pixel
|
||
int yOffset = -9; // pixel
|
||
|
||
const int x = 27;
|
||
|
||
// right side:
|
||
|
||
data.offset = QPoint(x + xOffset, 30 + yOffset);
|
||
m_textModifierCont[ static_cast<int>(TextModifier::EF_ReinforcedReduced) ] = data;
|
||
|
||
data.offset = QPoint(x + xOffset, 15 + yOffset);
|
||
m_textModifierCont[ static_cast<int>(TextModifier::G_StaffComments) ] = data;
|
||
|
||
data.offset = QPoint(x + xOffset, yOffset);
|
||
m_textModifierCont[ static_cast<int>(TextModifier::H_AdditionalInformation) ] = data;
|
||
|
||
data.offset = QPoint(x + xOffset, -15 + yOffset);
|
||
m_textModifierCont[ static_cast<int>(TextModifier::M_HigherFormation) ] = data;
|
||
|
||
data.offset = QPoint(x + xOffset, -30 + yOffset);
|
||
m_textModifierCont[ static_cast<int>(TextModifier::JKLNP) ] = data;
|
||
// left side:
|
||
data.horizontalAlignment = HorizontalAlignment::Right;
|
||
|
||
data.offset = QPoint(-x + xOffset, 30 + yOffset);
|
||
m_textModifierCont[ static_cast<int>(TextModifier::W_DateTimeGroup) ] = data;
|
||
|
||
data.offset = QPoint(-x + xOffset, 15 + yOffset);
|
||
m_textModifierCont[ static_cast<int>(TextModifier::XY_AltitudeLocation) ] = data;
|
||
|
||
data.offset = QPoint(-x + xOffset, yOffset);
|
||
m_textModifierCont[ static_cast<int>(TextModifier::V_Type) ] = data;
|
||
|
||
data.offset = QPoint(-x + xOffset, -15 + yOffset);
|
||
m_textModifierCont[ static_cast<int>(TextModifier::T_UniqueDesignation) ] = data;
|
||
|
||
data.offset = QPoint(-x + xOffset, -30 + yOffset);
|
||
m_textModifierCont[ static_cast<int>(TextModifier::Z_Speed) ] = data;
|
||
|
||
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||
}
|
||
|
||
void ParticipantImpl::setDebugInfo(const QString &debugInfo)
|
||
{
|
||
// Do NOT call the baseclass,
|
||
// ParticipantImpl will create m_mainGraphicalObject only on demand.
|
||
m_debugInfo = debugInfo;
|
||
}
|
||
|
||
|
||
QString ParticipantImpl::toString() const
|
||
{
|
||
QString str;
|
||
str.append(BaseClass::toString());
|
||
str.append(QStringLiteral(" symbol='%1'").arg(m_symbol.value().toString()));
|
||
return str;
|
||
}
|
||
|
||
Point3D ParticipantImpl::origin() const
|
||
{
|
||
return m_origin.origin();
|
||
}
|
||
bool ParticipantImpl::setOrigin(const Point3D &origin)
|
||
{
|
||
m_updateObjectIndicator = m_origin.setOrigin(origin) || m_updateObjectIndicator;
|
||
return m_updateObjectIndicator;
|
||
}
|
||
|
||
|
||
// Just to enable using as AES item (template@AdapterDds)
|
||
void ParticipantImpl::setPositions(const PositionCont &posCont)
|
||
{
|
||
Q_UNUSED(posCont);
|
||
// Should not be called
|
||
}
|
||
|
||
|
||
void ParticipantImpl::boundingBox(BoundingBox &bbox) const
|
||
{
|
||
GraphicalObjectPictureMarker *goPicture =
|
||
static_cast<GraphicalObjectPictureMarker *>(m_mainGraphicalObject);
|
||
|
||
if (goPicture && !goPicture->image().isNull())
|
||
{
|
||
const QSize &imgSize = goPicture->image().size(); // maybe a HotSpot has to be honored!?
|
||
|
||
bbox = BoundingBox(BoundingBox::ExtentType::Pixel,
|
||
m_origin.origin(), // Sim
|
||
imgSize.width(), imgSize.height() // pixel
|
||
);
|
||
}
|
||
}
|
||
|
||
QColor ParticipantImpl::majorColor() const
|
||
{
|
||
const QColor &partyCol = partyColor();
|
||
return partyCol;
|
||
}
|
||
|
||
|
||
float ParticipantImpl::userSymbolOpacity() const
|
||
{
|
||
return m_userSymbolOpacity.value();
|
||
}
|
||
void ParticipantImpl::setUserSymbolOpacity(float userSymbolOpacity)
|
||
{
|
||
m_userSymbolOpacity = userSymbolOpacity;
|
||
}
|
||
|
||
SymbolDataToRender ParticipantImpl::symbolDataToRender(bool ignoreForcedColor) const
|
||
{
|
||
if (ignoreForcedColor && m_party.forcedPartyColor.value().isValid())
|
||
{
|
||
SymbolDataToRender copy = m_symDataToRender;
|
||
copy.fillColor = m_party.partyColor;
|
||
return copy;
|
||
}
|
||
return m_symDataToRender;
|
||
}
|
||
|
||
QImage ParticipantImpl::actualImage() const
|
||
{
|
||
if (! m_mainGraphicalObject)
|
||
return QImage();
|
||
|
||
GraphicalObjectPictureMarker *goPicture =
|
||
static_cast<GraphicalObjectPictureMarker *>(m_mainGraphicalObject);
|
||
|
||
return goPicture->image();
|
||
}
|
||
|
||
float ParticipantImpl::scale() const
|
||
{
|
||
return m_scale.value();
|
||
}
|
||
void ParticipantImpl::setScale(float scale)
|
||
{
|
||
m_scale = scale;
|
||
}
|
||
|
||
|
||
bool ParticipantImpl::updateViewImpl()
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||
<< " m_debugInfo=" << m_debugInfo
|
||
<< " m_party.partyId=" << m_party.partyId
|
||
<< " m_party.changed()=" << m_party.changed()
|
||
<< " m_origin()=" << m_origin.origin()
|
||
<< " m_height=" << m_height
|
||
<< " m_origin.originTranslated()=" << m_origin.originTranslated()
|
||
<< " visibility=" << m_visibility
|
||
<< " m_symbol.changed=" << m_symbol.changed()
|
||
<< " m_symbol=" << m_symbol.value().toString()
|
||
<< " extensionsChanged=" << m_extensionsChanged
|
||
<< " m_movementTrackCoords= " << m_movementTrackCoords.positions();
|
||
|
||
// Prepare / create :
|
||
if (!m_mainGraphicalObject)
|
||
{
|
||
m_mainGraphicalObject = new GraphicalObjectPictureMarker(m_mapImpl->getEsriGeoView(),
|
||
m_graphicsLayer,
|
||
m_debugInfo + QLatin1String("#Image"),
|
||
m_uniqueMapId);
|
||
// to avoid incorrect number of positions, set them already here:
|
||
m_mainGraphicalObject->setOrigin(m_origin.originTranslated());
|
||
}
|
||
// : Prepare / create
|
||
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START2"
|
||
<< " m_debugInfo=" << m_debugInfo
|
||
<< " m_scale=" << m_scale.value()
|
||
<< " m_scaleChanged=" << m_scale.changed();
|
||
|
||
bool successPicture = true;
|
||
const bool visiSwitchedChanged = m_mainGraphicalObject->visibility() != m_visibility;
|
||
|
||
// scenario: object invisible, partyId changes, object becomes visible:
|
||
// So we have to force an update of the cached partyColor:
|
||
if (visiSwitchedChanged && m_visibility)
|
||
{
|
||
// enforce following block (fetchSymbol) being proccessed
|
||
// Szenario:
|
||
// 'Organize Participants': add template to Pool (ParticipantImpl are created)
|
||
// Move them to Attached (partyId is updated, invisible)
|
||
// On 'Move Participants' the become visible, but partyId does NOT change.
|
||
// So the symbol was still ocker
|
||
m_party.partyId.setChanged();
|
||
m_party.partyColor = QColor(); // set invalid to force cache update
|
||
|
||
// NLDEVCTRL: Ausfallkreuz Teilnehmersymbol
|
||
// Auch diese Farbe zurücksetzen:
|
||
m_injuryData.resetChanged();
|
||
}
|
||
|
||
if (m_visibility)
|
||
{
|
||
if (m_mainGraphicalObject)
|
||
{
|
||
GraphicalObjectPictureMarker *goPicture =
|
||
static_cast<GraphicalObjectPictureMarker *>(m_mainGraphicalObject);
|
||
|
||
goPicture->setOrigin(m_origin.originTranslated());
|
||
|
||
|
||
if (m_scale.changed() ||
|
||
m_symbol.changed() ||
|
||
m_userSymbolOpacity.changed() ||
|
||
m_marked.changed() ||
|
||
m_party.changed() ||
|
||
m_extensionsChanged ||
|
||
m_injuryData.changed)
|
||
{
|
||
m_symDataToRender = m_symbol.value().getDefaultRenderData();
|
||
|
||
bool isIdentityAssumed = false;
|
||
|
||
if (!m_symDataToRender.sidc.isEmpty())
|
||
{
|
||
AdvancedSymbology::SidcBuilder sidcBuilder(m_dictionary);
|
||
if (sidcBuilder.setSidc(m_symDataToRender.sidc))
|
||
isIdentityAssumed = sidcBuilder.isIdentityAssumed();
|
||
else
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " sidcBuilder.setSidc failed"
|
||
<< " m_debugInfo=" << m_debugInfo;
|
||
}
|
||
|
||
|
||
m_symDataToRender.role = this->partyRole(isIdentityAssumed);
|
||
|
||
int widthPixel = SituationMap::SymbolSizeLdefault; // * m_mapImpl->symbologyScaleFactor();
|
||
widthPixel *= m_symbol.value().size * m_scale.value();
|
||
m_symDataToRender.sizeL = widthPixel;
|
||
|
||
// main symbol color
|
||
const QColor &partyCol = partyColor();
|
||
m_symDataToRender.fillColor = partyCol;
|
||
// use userSymbolOpacity only for fillColor:
|
||
m_symDataToRender.fillColor.setAlpha(m_userSymbolOpacity.value() * 255);
|
||
m_symDataToRender.fillColorReplace = (m_party.partyId() >= 0);
|
||
|
||
// add other data
|
||
m_symDataToRender.injury = m_injuryData.injury;
|
||
m_symDataToRender.injuryColor = injuryColorInternal();
|
||
m_symDataToRender.marking = m_marked.value();
|
||
m_symDataToRender.additionalSymbols = m_additionalSymbols;
|
||
|
||
if (goPicture->image().isNull())
|
||
goPicture->setImage(m_dictionary->temporaryImage(m_symDataToRender.sizeL));
|
||
|
||
successPicture = true;
|
||
|
||
// until the result is delivered:
|
||
m_scale4XmlSymbolWithSymbolSpecificScale = 1.0;
|
||
|
||
// you expect findImage - correct
|
||
// But findImage handles multiPoint object special, which is not relevant here.
|
||
// So, in this case (for pointSymbols) use fetchSymbol:
|
||
m_symbolResultWatcher.setSymbolResult(m_dictionary->fetchSymbol(m_symDataToRender));
|
||
}
|
||
|
||
} // if (m_mainGraphicalObject)
|
||
|
||
}
|
||
|
||
//
|
||
// MovementTrack :
|
||
//
|
||
// MovementTrackData:
|
||
|
||
TRACE_LOG(m_logger) << LOGFUNCTION
|
||
<< " m_debugInfo=" << m_debugInfo
|
||
<< " m_movementTrackEnabled=" << m_movementTrackEnabled
|
||
<< ", m_movementTrackCoords.size=" << m_movementTrackCoords.size()
|
||
<< ", m_movementTrackVisibility=" << m_movementTrackVisibility;
|
||
|
||
bool successMovementTrack = true;
|
||
if (!m_movementTrackEnabled)
|
||
{
|
||
m_movementTrackCoords.clear();
|
||
m_movementTrack.clear(); // destroy GraphicalObjectPath
|
||
} // if (m_movementTrackEnabled)
|
||
|
||
// Display:
|
||
if (m_movementTrackCoords.size() >= 2)
|
||
{
|
||
if (! m_movementTrack)
|
||
{
|
||
m_movementTrack =
|
||
QSharedPointer<GraphicalObjectPath>(new GraphicalObjectPath(GraphicalObjectPathType::Polyline,
|
||
m_mapImpl->getEsriGeoView(),
|
||
m_graphicsLayer,
|
||
m_debugInfo + QStringLiteral("#Track"),
|
||
m_uniqueMapId));
|
||
m_movementTrack->setLineStyle(LineStyle(partyColor(), 2, LinePattern::Solid));
|
||
}
|
||
// move one layer backwards to put the Track BEHIND the image (drawOrder==0):
|
||
m_movementTrack->setDrawOrder(m_internalDrawOrder - 1);
|
||
|
||
m_movementTrack->setPositions(m_movementTrackCoords.positionsTranslated());
|
||
|
||
if (m_party.changed())
|
||
m_movementTrack->rLineStyle().setLineColor(partyColor());
|
||
|
||
if (m_scale.changed())
|
||
m_movementTrack->setScale(m_scale.value()>1.0f ? m_scale.value() : 1.0f);
|
||
|
||
m_movementTrack->setVisibility(m_visibility && m_visibilityTechnical && m_movementTrackVisibility);
|
||
successMovementTrack = m_movementTrack->updateView();
|
||
}
|
||
else
|
||
m_movementTrack.clear(); // destroy GraphicalObjectPath
|
||
// : MovementTrack
|
||
|
||
bool successTextModifier = updateViewImplTextModifier();
|
||
bool successRanges = updateViewImplRanges();
|
||
bool successDesignation = updateViewImplDesignation();
|
||
|
||
bool successDirectionIndicators = updateViewImplDirectionIndicators();
|
||
|
||
bool success = BaseClass::updateViewImpl() &&
|
||
successPicture &&
|
||
successTextModifier &&
|
||
successRanges &&
|
||
successDesignation &&
|
||
successDirectionIndicators &&
|
||
successMovementTrack;
|
||
|
||
// reset changed flags is done via updateViewImplPost
|
||
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< ", success=" << success;
|
||
return success;
|
||
}
|
||
|
||
bool ParticipantImpl::updateViewImplTextModifier()
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||
|
||
bool success = true;
|
||
|
||
const int size = static_cast<int>(TextModifier::END);
|
||
for (int i = 0; i < size; ++i)
|
||
{
|
||
TextModifierData &tmData = m_textModifierCont[i];
|
||
|
||
if (tmData.text.isEmpty())
|
||
{
|
||
// text empty
|
||
delete tmData.goText;
|
||
tmData.goText = nullptr;
|
||
}
|
||
else
|
||
{
|
||
// text filled:
|
||
if (!tmData.goText)
|
||
{
|
||
QString debugInfo = QStringLiteral("%1#textMod(%2)").arg(m_debugInfo).arg(i);
|
||
|
||
tmData.goText = new GraphicalObjectText(m_mapImpl->getEsriGeoView(),
|
||
m_graphicsLayer,
|
||
debugInfo,
|
||
m_uniqueMapId);
|
||
}
|
||
}
|
||
|
||
if (tmData.goText)
|
||
{
|
||
const bool bNewVisibility = tmData.visible && m_visibility;
|
||
tmData.goText->setVisibility(bNewVisibility);
|
||
|
||
// save following fo invisble object
|
||
if (bNewVisibility)
|
||
{
|
||
tmData.goText->setText(tmData.text);
|
||
// move one layer topwards to let the GraphicalObjectRange stay behind:
|
||
tmData.goText->setDrawOrder(m_internalDrawOrder + 1);
|
||
|
||
TextStyle ts;
|
||
const bool bigger = (i == static_cast<int>(TextModifier::EF_ReinforcedReduced) &&
|
||
tmData.text.compare(QLatin1String("+")) == 0);
|
||
|
||
const float finalScale = m_scale.value() * m_symbol.value().size * m_scale4XmlSymbolWithSymbolSpecificScale;
|
||
ts.setSize(finalScale * (bigger ? 22.5 : 15));
|
||
|
||
if (m_party.partyId() < 0)
|
||
ts.setTextColor(QColor(Qt::black));
|
||
else
|
||
ts.setTextColor(partyColor());
|
||
|
||
// Alignment:
|
||
ts.setHorizontalAlignment(tmData.horizontalAlignment);
|
||
ts.setVerticalAlignment(tmData.verticalAlignment);
|
||
tmData.goText->setTextStyle(ts);
|
||
|
||
// Offset:
|
||
tmData.goText->setXOffset(finalScale * static_cast<float>(tmData.offset.x()));
|
||
tmData.goText->setYOffset(finalScale * static_cast<float>(tmData.offset.y()));
|
||
}
|
||
|
||
// origin is required for updateView (otherwise 'incorrect number of positions'):
|
||
// (originTranslated is cached)
|
||
tmData.goText->setOrigin(m_origin.originTranslated());
|
||
|
||
success = success && tmData.goText->updateView();
|
||
}
|
||
|
||
} // for
|
||
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< ", success=" << success;
|
||
return success;
|
||
}
|
||
|
||
QImage generateDirectionIndicatorImage(int sizeL,
|
||
const QColor &defaultColor,
|
||
const QMap<int, Participant::DirectionIndicatorData> &directionIndicatorCont)
|
||
{
|
||
const int fullSize = sizeL * 1.7 * 2.0; // try and error: '1.7';
|
||
|
||
QImage fullImage(fullSize, fullSize, QImage::Format_ARGB32);
|
||
fullImage.fill(Qt::transparent);
|
||
|
||
#ifdef NEVER
|
||
// for debugging :
|
||
if (1)
|
||
{
|
||
QPainter painter(&fullImage);
|
||
QPen pen(Qt::black);
|
||
pen.setWidth(2.0);
|
||
painter.setPen(pen);
|
||
painter.drawRect(fullImage.rect());
|
||
}
|
||
// : for debugging
|
||
#endif
|
||
|
||
QPainter painter(&fullImage);
|
||
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||
|
||
const QPointF center((fullImage.width() / 2), (fullImage.height() / 2));
|
||
const QPointF dest(center.x(), 0);
|
||
const int width = fullImage.size().width();
|
||
const int height = fullImage.size().height();
|
||
|
||
for (const auto &item : directionIndicatorCont)
|
||
{
|
||
QColor finalColor = item.color.isValid() ? item.color : defaultColor;
|
||
|
||
QPen pen(finalColor);
|
||
pen.setWidthF(item.lineWidth * double(sizeL)/SituationMap::SymbolSizeLdefault);
|
||
pen.setStyle(item.lineStyle);
|
||
painter.setPen(pen);
|
||
|
||
painter.save();
|
||
|
||
painter.translate(width / 2, height / 2);
|
||
painter.rotate(item.directionDegree);
|
||
painter.translate(-width / 2, -height / 2);
|
||
|
||
// line
|
||
painter.drawLine(center, dest); // | to top
|
||
|
||
// arrow
|
||
QPen penArrow(finalColor);
|
||
penArrow.setWidthF(item.lineWidth * double(sizeL)/SituationMap::SymbolSizeLdefault);
|
||
painter.setPen(penArrow);
|
||
|
||
QPolygon poly;
|
||
poly.reserve(3);
|
||
|
||
int aLength = 6 * pen.width();
|
||
int aWidth = 2 * pen.width();
|
||
|
||
// 2 || (dest)
|
||
// | |
|
||
// 1 | | 3
|
||
|
||
poly.append(dest.toPoint() + QPoint(-aWidth, aLength) );
|
||
poly.append(dest.toPoint());
|
||
poly.append(dest.toPoint() + QPoint(+aWidth, aLength));
|
||
|
||
painter.drawPolyline(poly);
|
||
|
||
painter.restore();
|
||
} // for
|
||
|
||
return fullImage;
|
||
}
|
||
|
||
|
||
bool ParticipantImpl::updateViewImplDirectionIndicators()
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||
<< " m_directionIndicatorCont.count()=" << m_directionIndicatorCont.count();
|
||
|
||
bool success = true;
|
||
|
||
if (m_directionIndicatorCont.isEmpty())
|
||
m_directionIndicatorPms.clear(); // destroy object
|
||
else
|
||
{
|
||
// needs to be created?
|
||
if (!m_directionIndicatorPms)
|
||
{
|
||
m_directionIndicatorPms = QSharedPointer<GraphicalObjectPictureMarker>(new GraphicalObjectPictureMarker(m_mapImpl->getEsriGeoView(),
|
||
m_graphicsLayer,
|
||
m_debugInfo + QLatin1String("#DirectionIndImage"),
|
||
m_uniqueMapId));
|
||
}
|
||
const QImage &image = generateDirectionIndicatorImage(m_symDataToRender.sizeL, majorColor(), m_directionIndicatorCont);
|
||
m_directionIndicatorPms->setImage(image);
|
||
m_directionIndicatorPms->setOrigin(m_origin.originTranslated());
|
||
m_directionIndicatorPms->setVisibility(m_mainGraphicalObject->visibility());
|
||
m_directionIndicatorPms->setSelected(m_selected);
|
||
|
||
// move one level backwards to put the GraphicalObjectRange BEHIND the image (drawOrder==0), but on top of WaeaponRanges:
|
||
m_directionIndicatorPms->setDrawOrder(m_internalDrawOrder - 1);
|
||
|
||
success = m_directionIndicatorPms->updateView();
|
||
}
|
||
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< ", success=" << success;
|
||
return success;
|
||
}
|
||
|
||
bool ParticipantImpl::updateViewImplRanges()
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||
<< " number Ranges=" << m_ranges.value().count();
|
||
|
||
bool success = true;
|
||
|
||
const QVector<int> &ranges = m_ranges.value();
|
||
int size = ranges.size();
|
||
m_graphObjRanges.resize(size);
|
||
|
||
for (int i = 0; i < size; ++i)
|
||
{
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " i=" << i;
|
||
|
||
// get some values/references:
|
||
int range = ranges[i];
|
||
QSharedPointer<GraphicalObjectRange> &goRange = m_graphObjRanges[i];
|
||
const bool visi = m_visibility && m_rangesVisibility;
|
||
|
||
if (!visi)
|
||
{
|
||
goRange.clear(); // destroy object
|
||
}
|
||
else
|
||
{
|
||
if (goRange.isNull())
|
||
{
|
||
goRange = QSharedPointer<GraphicalObjectRange>
|
||
(new GraphicalObjectRange(m_mapImpl->getEsriGeoView()
|
||
, m_graphicsLayer
|
||
, QStringLiteral("%1#Range_i(%2)_r(%3)").arg(m_debugInfo).arg(i).arg(range)
|
||
, m_uniqueMapId)
|
||
);
|
||
}
|
||
|
||
// move two level backwards to put the GraphicalObjectRange BEHIND the image (drawOrder==0):
|
||
goRange->setVisibility(visi);
|
||
goRange->setDrawOrder(m_internalDrawOrder - 2);
|
||
goRange->setOrigin(m_origin.originTranslated());
|
||
goRange->setRange(range, i * 15);
|
||
goRange->setLineStyle(LineStyle(partyColor(), 3, LinePattern::Solid));
|
||
goRange->setFillStyle(FillStyle(Qt::black, FillPattern::Null));
|
||
|
||
bool updated = goRange->updateView();
|
||
success = success && updated;
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " updated=" << updated;
|
||
} // if (!visi)
|
||
|
||
}// for
|
||
|
||
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< ", success=" << success;
|
||
return success;
|
||
}
|
||
|
||
bool ParticipantImpl::updateViewImplDesignation()
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||
<< ", m_debugInfo=" << m_debugInfo
|
||
<< ", m_designationData.value().size()=" << m_designationData.value().size();
|
||
bool success = true;
|
||
|
||
const QVector<Participant::DesignationData> &designationDataVec = m_designationData.value();
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START 11" << ", m_debugInfo=" << m_debugInfo
|
||
<< " m_designationMapObjects.size() = " << m_designationMapObjects.size()
|
||
<< " m_designationData.value().size() = " << designationDataVec.size();
|
||
|
||
m_designationMapObjects.resize(designationDataVec.size());
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START 22" << ", m_debugInfo=" << m_debugInfo
|
||
<< " m_designationMapObjects.size() = " << m_designationMapObjects.size()
|
||
<< " m_designationData.value().size() = " << designationDataVec.size();
|
||
|
||
int idx = -1;
|
||
for (const Participant::DesignationData &designationData : qAsConst(designationDataVec))
|
||
{
|
||
++idx;
|
||
|
||
QSharedPointer<BasicPathObjectImpl> &bpoRef = m_designationMapObjects[idx];
|
||
if (bpoRef.isNull())
|
||
{
|
||
QString debugInfo = QString(QStringLiteral("%1#Designation_code_%2")).arg(m_debugInfo).arg(idx);
|
||
DesignationLocalBasicPathObject *designationDPO = new DesignationLocalBasicPathObject(debugInfo);
|
||
|
||
success = designationDPO->init(m_mapImpl, m_logicalLayerName, GraphicalObjectPathType::Polyline);
|
||
designationDPO->setUniqueId(m_uniqueMapId);
|
||
designationDPO->setArrowHeadEnd(true);
|
||
if (success)
|
||
{
|
||
bpoRef = QSharedPointer<BasicPathObjectImpl>(static_cast<BasicPathObjectImpl *>(designationDPO));
|
||
} else {
|
||
ERROR_LOG(m_logger) << LOGFUNCTION << ", m_debugInfo=" << m_debugInfo
|
||
<< " designationPO->init failed";
|
||
designationDPO->removeMySelf();
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// since DesignationLocalBasicPathObject is a MapObject (and not GraphicalObject)
|
||
// untranslated coords have to be used here:
|
||
bpoRef->setPositions({ this->origin(), designationData.spotLocation });
|
||
bpoRef->setTextOnSegment(0, QObject::tr("Code: %1").arg(designationData.code));
|
||
bpoRef->setSelected(m_selected);
|
||
bpoRef->setLineStyle(LineStyle(partyColor(), 3, LinePattern::DashDot)); // partyColor may change
|
||
bpoRef->setVisibility(m_visibility);
|
||
|
||
const bool updated = bpoRef->updateView();
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START" << ", m_debugInfo=" << m_debugInfo << " updated= " << updated;
|
||
|
||
success = success && updated;
|
||
|
||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", m_debugInfo=" << m_debugInfo
|
||
<< ", updated= " << updated
|
||
<< ", success= " << success;
|
||
}
|
||
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< ", m_debugInfo=" << m_debugInfo
|
||
<< ", success=" << success;
|
||
return success;
|
||
}
|
||
|
||
bool ParticipantImpl::init(MapImpl *mapImpl, const QString &logicalLayerName)
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||
|
||
bool success = BaseClass::init(mapImpl, logicalLayerName);
|
||
|
||
if (mapImpl)
|
||
m_dictionary = &(m_mapImpl->symbolDictionary());
|
||
|
||
success = success && (m_dictionary);
|
||
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< ", success=" << success;
|
||
return success;
|
||
}
|
||
|
||
const QColor &ParticipantImpl::partyColor() const
|
||
{
|
||
if (m_party.forcedPartyColor.value().isValid())
|
||
return m_party.forcedPartyColor.value();
|
||
|
||
if ((m_party.partyId.value() == -1) && m_symbol.value().color.isValid())
|
||
return m_symbol.value().color;
|
||
|
||
if (m_party.partyId.changed() || m_party.useLightColor.changed() || !m_party.partyColor.isValid())
|
||
{
|
||
m_party.partyColor =
|
||
m_mapImpl->partyIdToColorFunctor().partyIdToColor(m_party.partyId.value(),
|
||
m_party.useLightColor.value());
|
||
}
|
||
return m_party.partyColor;
|
||
}
|
||
|
||
QColor ParticipantImpl::partyColor(int partyId, bool isOutOfDate) const
|
||
{
|
||
return BaseClass::partyColor(partyId, isOutOfDate);
|
||
}
|
||
|
||
|
||
//#define NEVER
|
||
#ifdef NEVER
|
||
QStringList sl;
|
||
sl << "uniquedesignation";
|
||
sl << "type";
|
||
sl << "datetimevalid";
|
||
sl << "quantity";
|
||
|
||
sl << "speed";
|
||
sl << "staffcomment";
|
||
sl << "z";
|
||
sl << "x";
|
||
sl << "z/x";
|
||
sl << "y";
|
||
sl << "combateffectiveness";
|
||
sl << "iff_sif";
|
||
|
||
|
||
Q_FOREACH (const QString &item, sl)
|
||
m_message->setProperty(item, QString("%1_V").arg(item));
|
||
|
||
|
||
// toJson:
|
||
// "{"type":"esriMultiPartCIMSymbol","parts":[{"id":"GHMPNZ----_mil2525c","
|
||
// content":[{"type":"CIMPointSymbol","symbolLayers":[{"type":"CIMTextLayer","fontFamilyName":"Arial","fontStyleName":"Bold","symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":1,"pattern":{"type":"CIMSolidPattern","color":[255,255,255,255]},"capStyle":"Round","joinStyle":"Round","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[255,0,0,255]}}]},"horizontalAlignment":"Left","verticalAlignment":"Baseline","textCase":"Normal","textDirection":"LTR","height":8.25,"letterWidth":100,"wordSpacing":100,"text":
|
||
//
|
||
// [uniquedesignation]","textPlacement":{"type":"point","method":"southwest","offset":1}}]},{"type":"CIMPointSymbol","symbolLayers":[{"type":"CIMTextLayer","fontFamilyName":"Arial","fontStyleName":"Bold","symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":1,"pattern":{"type":"CIMSolidPattern","color":[255,255,255,255]},"capStyle":"Round","joinStyle":"Round","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[255,0,0,255]}}]},"horizontalAlignment":"Left","verticalAlignment":"Baseline","textCase":"Normal","textDirection":"LTR","height":8.25,"letterWidth":100,"wordSpacing":100,"text":
|
||
//
|
||
// [type]","textPlacement":{"type":"point","method":"west","offset":1}}]},{"type":"CIMPointSymbol","symbolLayers":[{"type":"CIMTextLayer","fontFamilyName":"Arial","fontStyleName":"Bold","symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":1,
|
||
// pattern":{"type":"CIMSolidPattern","color":[255,255,255,255]},"capStyle":"Round","joinStyle":"Round","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[255,0,0,255]}}]},"horizontalAlignment":"Left","verticalAlignment":"Baseline","textCase":"Normal","textDirection":"LTR","height":8.25,"letterWidth":100,"wordSpacing":100,"text":""
|
||
|
||
// [datetimevalid]","textPlacement":{"type":"point","method":"northwest","offset":1}}]},{"type":"CIMPointSymbol","symbolLayers":
|
||
// [{"type":"CIMTextLayer","fontFamilyName":"Arial","fontStyleName":"Bold","symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":1,"pattern":{"type":"CIMSolidPattern","color":[255,255,255,255]},"capStyle":"Round","joinStyle":"Round","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[255,0,0,255]}}]},"horizontalAlignment":"Left","verticalAlignment":"Baseline","textCase":"Normal","textDirection":"LTR","height":8.25,"letterWidth":100,"wordSpacing":100,
|
||
// "text":"[x],[y]","textPlacement":
|
||
// {"type":"point","method":"south","offset":1}}]},{"type":"CIMPointSymbol","symbolLayers":[{"type":"CIMTextLayer","fontFamilyName":"Arial","fontStyleName":"Bold","symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":1,"pattern":{"type":"CIMSolidPattern","color":[255,255,255,255]},"capStyle":"Round",
|
||
// "joinStyle":"Round","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[255,0,0,255]}}]},"horizontalAlignment":"Left","verticalAlignment":"Baseline","textCase":"Normal","textDirection":"LTR","height":8.25,"letterWidth":100,"wordSpacing":100,"text":"
|
||
|
||
// [quantity]","textPlacement":{"type":"point","method":"north","offset":1}}]},{"type":"CIMPointSymbol","symbolLayers":[{"type":"CIMTextLayer",
|
||
// "fontFamilyName":"Arial","fontStyleName":"Bold","symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":1,
|
||
// "pattern":{"type":"CIMSolidPattern","color":[255,255,255,255]},"capStyle":"Round","joinStyle":"Round","miterLimit":10,
|
||
// "alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[255,0,0,255]}}]},"horizontalAlignment":"Left","verticalAlignment":"Baseline","textCase":"Normal","textDirection":"LTR","height":8.25,"letterWidth":100,"wordSpacing":100,"text":"
|
||
|
||
// [additionalinformation]", "textPlacement":{"type":"point","method":"northeast","offset":1}}]},{"type":"CIMPointSymbol",
|
||
// "symbolLayers":[{"type":"CIMVectorMarker","size":25,"anchorPoint":{"x":0,"y":0},"anchorPointUnits":"Relative","scaleStrokesAndFills":true,"offsetY":9,"dominantSizeAxis3D":"Z","frame":{"xmin":0,"ymin":0,"xmax":515,"ymax":515},"markerGraphics":[{"type":"CIMMarkerGraphic",
|
||
// "geometry":{"rings":[[[209.8,357.1],[305.3,357.1],[305.3,91.8],[209.8,91.8],[209.8,357.1]]]},"symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":6.432937632884479,
|
||
// "pattern":{"type":"CIMSolidPattern","color":[255,0,0,255]},"capStyle":
|
||
// "Butt","joinStyle":"Miter","miterLimit":112,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},
|
||
// {"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[255,255,128,255]}}]}},
|
||
// {"type":"CIMMarkerGraphic","geometry":{"rings":[[[232.1,197.9],[232.1,258.6],[240.4,258.6],[272.3,210.9],[272.3,258.6],[280,258.6],[280,197.9],[271.8,197.9],[239.8,245.6],[239.8,197.9],[232.1,197.9]]]},"
|
||
// symbol":{"type":"CIMPolygonSymbol","symbolLayers":
|
||
// [{"type":"CIMFilledStroke","width":1.2774627923458541,"pattern":{"type":"CIMSolidPattern","color":[255,0,0,255]},
|
||
// "capStyle":"Butt","joinStyle":"Miter","miterLimit":112,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},
|
||
// {"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[255,0,0,255]}}]}},
|
||
// {"type":"CIMMarkerGraphic","geometry":{"rings":[[[257.5,357.1],[124.9,357.1],[128.3,385.1],[136.5,412.4],[148.5,435.9],[164.2,455.3],[182.9,470.3],[204.7,481.1],[229.6,487.6],[257.5,489.7],[285.4,487.6],[310.3,481.1],[332.2,470.3],[350.9,455.3],[366.5,435.9],[378.5,412.4],[386.7,385.1],[390.2,357.1],[257.5,357.1]]]},
|
||
// "symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":6.432937632884479,"pattern":{"type":"CIMSolidPattern","color":[255,0,0,255]},
|
||
// "capStyle":"Butt","joinStyle":"Miter","miterLimit":112,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},
|
||
// {"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[255,255,128,255]}}]}}]}]}]}]}" (ication/ngl_qt_msg_handler.inc:21)
|
||
|
||
// Second:
|
||
// 2015-05-06 09:39:18,903 INFO SituationMap.MapImpl |#| SituationMap::MapImpl::onMouseRelease onMouseRelease for left mouse button gId= 4 symbol.toJson= '{"type":"esriMultiPartCIMSymbol","parts":[{"id":"SFGPUCD---_mil2525c","content":[{"type":"CIMPointSymbol","symbolLayers":[{"type":"CIMTextLayer","fontFamilyName":"Arial","fontStyleName":"Bold","symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":1,"pattern":{"type":"CIMSolidPattern","color":[255,255,255,255]},"capStyle":"Round","joinStyle":"Round","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[0,0,0,255]}}]},"horizontalAlignment":"Left","verticalAlignment":"Baseline","textCase":"Normal","textDirection":"LTR","height":8.25,"letterWidth":100,"wordSpacing":100,"text":"[uniquedesignation]
|
||
// [speed]","textPlacement":{"type":"point","method":"southwest","offset":1}}]},{"type":"CIMPointSymbol","symbolLayers":[{"type":"CIMTextLayer","fontFamilyName":"Arial","fontStyleName":"Bold","symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":1,"pattern":{"type":"CIMSolidPattern","color":[255,255,255,255]},"capStyle":"Round","joinStyle":"Round","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[0,0,0,255]}}]},"horizontalAlignment":"Center","verticalAlignment":"Center","textCase":"Normal","textDirection":"LTR","height":8.25,"letterWidth":100,"wordSpacing":100,"text":"[datetimevalid]
|
||
// [z]/[x],[y]","textPlacement":{"type":"point","method":"northwest","offset":1}}]},{"type":"CIMPointSymbol","symbolLayers":[{"type":"CIMTextLayer","fontFamilyName":"Arial","fontStyleName":"Bold","symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":1,"pattern":{"type":"CIMSolidPattern","color":[255,255,255,255]},"capStyle":"Round","joinStyle":"Round","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[0,0,0,255]}}]},"horizontalAlignment":"Center","verticalAlignment":"Center","textCase":"Normal","textDirection":"LTR","height":8.25,"letterWidth":100,"wordSpacing":100,"text":"[reinforced]
|
||
// [staffcomment]","textPlacement":{"type":"point","method":"northeast","offset":1}}]},{"type":"CIMPointSymbol","symbolLayers":[{"type":"CIMTextLayer","fontFamilyName":"Arial","fontStyleName":"Bold","symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":1,"pattern":{"type":"CIMSolidPattern","color":[255,255,255,255]},"capStyle":"Round","joinStyle":"Round","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[0,0,0,255]}}]},"horizontalAlignment":"Center","verticalAlignment":"Center","textCase":"Normal","textDirection":"LTR","height":8.25,"letterWidth":100,"wordSpacing":100,"text":"[additionalinformation]","textPlacement":{"type":"point","method":"east","offset":1}}]},{"type":"CIMPointSymbol","symbolLayers":[{"type":"CIMTextLayer","fontFamilyName":"Arial","fontStyleName":"Bold","symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":1,"pattern":{"type":"CIMSolidPattern","color":[255,255,255,255]},"capStyle":"Round","joinStyle":"Round","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[0,0,0,255]}}]},"horizontalAlignment":"Center","verticalAlignment":"Center","textCase":"Normal","textDirection":"LTR","height":8.25,"letterWidth":100,"wordSpacing":100,"text":"[higherformation]
|
||
// [combateffectiveness]/[iff_sif]","textPlacement":{"type":"point","method":"southeast","offset":1}}]},{"type":"CIMPointSymbol","symbolLayers":[{"type":"CIMVectorMarker","size":25,"anchorPoint":{"x":0,"y":0},"anchorPointUnits":"Relative","scaleStrokesAndFills":true,"dominantSizeAxis3D":"Z","frame":{"xmin":0,"ymin":0,"xmax":710,"ymax":530},"markerGraphics":[{"type":"CIMMarkerGraphic","geometry":{"rings":[[[85,445],[85,85],[625,85],[625,445],[85,445]]]},"symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":15,"pattern":{"type":"CIMSolidPattern","color":[0,0,0,255]},"capStyle":"Butt","joinStyle":"Miter","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[128,224,255,255]}}]}},{"type":"CIMMarkerGraphic","geometry":{"rings":[[[91,85],[113,120],[138,151],[168,178],[201,200],[237,219],[275,232],[314,240],[355,243],[396,240],[435,232],[473,219],[509,200],[542,178],[571,151],[597,120],[619,85],[91,85]]]},"symbol":{"type":"CIMPolygonSymbol","symbolLayers":[{"type":"CIMFilledStroke","width":15,"pattern":{"type":"CIMSolidPattern","color":[0,0,0,255]},"capStyle":"Butt","joinStyle":"Miter","miterLimit":10,"alignment":"Center","lineStyle3D":"Strip","patternFollowsStroke":true},{"type":"CIMFill","pattern":{"type":"CIMSolidPattern","color":[128,224,255,255]}}]}}]}]}]}]}' (t/Legatus/Plugins/SituationMap/MapImpl/MapImpl.cpp:1019)
|
||
|
||
#endif
|
||
|
||
|
||
|
||
|
||
QString ParticipantImpl::textModifier(TextModifier textModifier) const
|
||
{
|
||
return m_textModifierCont[ static_cast<int>(textModifier) ].text;
|
||
}
|
||
void ParticipantImpl::setTextModifier(TextModifier textModifier, const QString &text)
|
||
{
|
||
m_textModifierCont[ static_cast<int>(textModifier) ].text = text;
|
||
}
|
||
|
||
bool ParticipantImpl::textModifierVisibility(TextModifier textModifier) const
|
||
{
|
||
return m_textModifierCont[ static_cast<int>(textModifier) ].visible;
|
||
}
|
||
void ParticipantImpl::setTextModifierVisibility(TextModifier textModifier, bool visible)
|
||
{
|
||
m_textModifierCont[ static_cast<int>(textModifier) ].visible = visible;
|
||
}
|
||
|
||
|
||
QColor ParticipantImpl::injuryColor() const
|
||
{
|
||
return m_injuryData.injuryColor;
|
||
}
|
||
Injury ParticipantImpl::injury() const
|
||
{
|
||
return m_injuryData.injury;
|
||
}
|
||
bool ParticipantImpl::setInjury(Injury injury,
|
||
const QColor &injuryColor)
|
||
{
|
||
bool changed = false;
|
||
|
||
if (m_injuryData.injury != injury)
|
||
{
|
||
m_injuryData.injury = injury;
|
||
m_injuryData.changed = true;
|
||
changed = true;
|
||
}
|
||
|
||
if (m_injuryData.injuryColor != injuryColor)
|
||
{
|
||
m_injuryData.injuryColor = injuryColor;
|
||
m_injuryData.changed = true;
|
||
changed = true;
|
||
}
|
||
|
||
// switch from partyId to color:
|
||
m_injuryData.injuryPartyId = -1;
|
||
return changed;
|
||
}
|
||
|
||
int ParticipantImpl::injuryPartyId() const
|
||
{
|
||
return m_injuryData.injuryPartyId;
|
||
}
|
||
bool ParticipantImpl::setInjury(Injury injury, int partyId)
|
||
{
|
||
bool changed = false;
|
||
|
||
if (m_injuryData.injury != injury)
|
||
{
|
||
m_injuryData.injury = injury;
|
||
m_injuryData.changed = true;
|
||
changed = true;
|
||
}
|
||
|
||
if (m_injuryData.injuryPartyId != partyId)
|
||
{
|
||
m_injuryData.injuryPartyId = partyId;
|
||
m_injuryData.changed = true;
|
||
changed = true;
|
||
}
|
||
return changed;
|
||
}
|
||
|
||
bool ParticipantImpl::setPartyIdChanged(int partyId)
|
||
{
|
||
bool changed = BaseClass::setPartyIdChanged(partyId);
|
||
if ((partyId < 0) || (m_injuryData.injuryPartyId == partyId))
|
||
{
|
||
m_injuryData.changed = true;
|
||
changed = true;
|
||
}
|
||
return changed;
|
||
}
|
||
|
||
|
||
const QColor &ParticipantImpl::injuryColorInternal()
|
||
{
|
||
if (m_injuryData.changed)
|
||
{
|
||
if (m_injuryData.partyIdValid())
|
||
m_injuryData.injuryColor = this->partyColor(m_injuryData.injuryPartyId);
|
||
else
|
||
m_injuryData.injuryColor = QColor(100, 100, 0); // 100, 100, 0 -> ocker; same as ASB oreignInterfaceImpl::findImage()
|
||
}
|
||
return m_injuryData.injuryColor;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
bool ParticipantImpl::additionalSymbol(AdditionalSymbolType additionalSymbolType) const
|
||
{
|
||
return (m_additionalSymbols.contains(additionalSymbolType));
|
||
}
|
||
|
||
bool ParticipantImpl::setAdditionalSymbol(AdditionalSymbolType additionalSymbolType, bool newState)
|
||
{
|
||
bool changed = false;
|
||
|
||
if (newState)
|
||
{
|
||
if (!m_additionalSymbols.contains(additionalSymbolType))
|
||
{
|
||
changed = true;
|
||
m_extensionsChanged = true;
|
||
m_additionalSymbols.insert(additionalSymbolType);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (m_additionalSymbols.contains(additionalSymbolType))
|
||
{
|
||
changed = true;
|
||
m_extensionsChanged = true;
|
||
m_additionalSymbols.remove(additionalSymbolType);
|
||
}
|
||
}
|
||
return changed;
|
||
}
|
||
|
||
bool SituationMap::ParticipantImpl::isMarked() const
|
||
{
|
||
return m_marked.value();
|
||
}
|
||
|
||
bool ParticipantImpl::setMarked(bool marked)
|
||
{
|
||
bool changed = m_marked.value() != marked;
|
||
m_marked = marked;
|
||
return changed;
|
||
}
|
||
|
||
void ParticipantImpl::setDirectionIndicator(int key, const DirectionIndicatorData &data)
|
||
{
|
||
m_directionIndicatorCont[key] = data;
|
||
}
|
||
|
||
void ParticipantImpl::removeDirectionIndicator(int key)
|
||
{
|
||
if (key < 0)
|
||
m_directionIndicatorCont.clear();
|
||
else
|
||
m_directionIndicatorCont.remove(key);
|
||
}
|
||
|
||
bool ParticipantImpl::isDirectionIndicatorsVisible() const
|
||
{
|
||
return m_directionIndicatorsVisibility.value();
|
||
}
|
||
|
||
void ParticipantImpl::setDirectionIndicatorsVisibility(bool visible)
|
||
{
|
||
m_directionIndicatorsVisibility = visible;
|
||
}
|
||
|
||
QVector<int> ParticipantImpl::ranges() const
|
||
{
|
||
return m_ranges.value();
|
||
}
|
||
bool ParticipantImpl::setRanges(const QVector<int> &ranges)
|
||
{
|
||
bool changed = m_ranges.value() != ranges;
|
||
m_ranges = ranges;
|
||
return changed;
|
||
}
|
||
|
||
bool ParticipantImpl::isRangesVisible() const
|
||
{
|
||
return m_rangesVisibility;
|
||
}
|
||
void ParticipantImpl::setRangesVisibility(bool visible)
|
||
{
|
||
m_rangesVisibility = visible;
|
||
}
|
||
|
||
bool ParticipantImpl::setDesignations(const QVector<Participant::DesignationData> &designations)
|
||
{
|
||
m_designationData = designations;
|
||
return m_designationData.changed();
|
||
}
|
||
|
||
//bool ParticipantImpl::addUpdateDesignation(const DesignationData &designationData)
|
||
//{
|
||
// // try the keep the m_designationData clean
|
||
// if (designationData.isNull())
|
||
// return removeDesignation(designationData.code);
|
||
|
||
// bool changed = m_designationData.value(designationData.code) != designationData;
|
||
// if (changed)
|
||
// m_designationData[designationData.code] = designationData;
|
||
// return changed;
|
||
//}
|
||
|
||
//bool ParticipantImpl::removeDesignation(int code)
|
||
//{
|
||
// return (m_designationData.remove(code) > 0);
|
||
//}
|
||
|
||
bool ParticipantImpl::isMovementTrackEnabled() const
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< " m_movementTrackEnabled=" << m_movementTrackEnabled;
|
||
return m_movementTrackEnabled;
|
||
}
|
||
|
||
void ParticipantImpl::setMovementTrackEnabled(bool enable)
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||
<< " m_movementTrackEnabled=" << m_movementTrackEnabled;
|
||
m_movementTrackEnabled = enable;
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< " m_movementTrackEnabled=" << m_movementTrackEnabled;
|
||
}
|
||
|
||
void ParticipantImpl::setMovementTrack(const PositionCont &movementTrack)
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||
<< " m_debugInfo=" << m_debugInfo
|
||
<< ", movementTrack=" << movementTrack;
|
||
m_movementTrackCoords.setPositions(movementTrack);
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< " m_debugInfo=" << m_debugInfo
|
||
<< ", movementTrack=" << movementTrack;
|
||
}
|
||
|
||
void ParticipantImpl::addToMovementTrack(const Point3D &addToMovementTrack)
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||
m_movementTrackCoords.addSinglePosition(addToMovementTrack);
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||
}
|
||
|
||
PositionCont ParticipantImpl::movementTrack() const
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< " movementTrackSize=" << m_movementTrackCoords.size();
|
||
return m_movementTrackCoords.positions();
|
||
}
|
||
|
||
int ParticipantImpl::sizeOfMovementTrack() const
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< " movementTrackSize=" << m_movementTrackCoords.size();
|
||
return m_movementTrackCoords.size();
|
||
}
|
||
|
||
bool ParticipantImpl::isMovementTrackVisible() const
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< " m_movementTrackVisibility=" << m_movementTrackVisibility;
|
||
return m_movementTrackVisibility;
|
||
}
|
||
|
||
void ParticipantImpl::setMovementTrackVisibility(bool enable)
|
||
{
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||
m_movementTrackVisibility = enable;
|
||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||
<< " m_movementTrackVisibility=" << m_movementTrackVisibility;
|
||
}
|
||
|
||
int ParticipantImpl::numberOfValuesChanged()
|
||
{
|
||
int count = BaseClass::numberOfValuesChanged();
|
||
|
||
if (m_userSymbolOpacity.changed()) { WARNING_LOG(m_logger) << LOGFUNCTION << " START "; count++; }
|
||
if (m_scale.changed()) { WARNING_LOG(m_logger) << LOGFUNCTION << " START "; count++; }
|
||
|
||
if (m_extensionsChanged) { WARNING_LOG(m_logger) << LOGFUNCTION << " START "; count++; }
|
||
|
||
if (m_marked.changed()) { WARNING_LOG(m_logger) << LOGFUNCTION << " START "; count++; }
|
||
if (m_ranges.changed()) { WARNING_LOG(m_logger) << LOGFUNCTION << " START "; count++; }
|
||
if (m_injuryData.changed) { WARNING_LOG(m_logger) << LOGFUNCTION << " START "; count++; }
|
||
|
||
return count;
|
||
}
|
||
|
||
|
||
} // namespace SituationMap
|