814 lines
24 KiB
C++
Executable File
814 lines
24 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <QLinkedList>
|
|
#include <QMap>
|
|
#include <QPair>
|
|
#include <QString>
|
|
#include <QRectF>
|
|
|
|
#include <ngltools/ngltools_bitset.h>
|
|
#include <NGLLogger/INGLLogger.h>
|
|
|
|
#include "symbology_xml_export.h"
|
|
#include "symbol_types.h"
|
|
#include "primitive.h"
|
|
|
|
#include <Symbology/symbol_dictionary_types.h>
|
|
|
|
|
|
namespace SymbologyXML
|
|
{
|
|
|
|
class SymbolTable;
|
|
class SymbolReader;
|
|
|
|
/**
|
|
\brief Abstraction of a symbol
|
|
|
|
Central class representing a single symbol. Manipulation to the symbol is
|
|
directly done in the state of the object. Methods for reading and writing
|
|
the symbol from/to XML are provided.
|
|
|
|
To work with many symbols in a program, you should use the class SymbolTable.
|
|
|
|
If you need to work with graphics-primitives in an abstract way you should
|
|
use Primitive Objects, which are used by Symbol to describe the free part
|
|
of the visual representation of a Symbol.
|
|
|
|
@author Stephan Kuhagen <stephan.kuhagen@rheinmetall.com>
|
|
*/
|
|
|
|
class SYMBOLOGY_XML_EXPORT Symbol
|
|
{
|
|
public:
|
|
static const char* SymbolVersion;
|
|
|
|
friend class SymbolReader;
|
|
friend class PixmapSymbolCache;
|
|
|
|
static SymbologyXML::SymbolTypes::t_affil roleToAffiliation(AdvancedSymbology::Role role);
|
|
|
|
Symbol();
|
|
~Symbol();
|
|
|
|
//! Copy C'tor
|
|
Symbol(const Symbol& other);
|
|
|
|
//! Assignment-Operator
|
|
Symbol& operator=(const Symbol& other);
|
|
|
|
//! Compare-Operator
|
|
bool operator==(const Symbol& other) const;
|
|
bool operator!=(const Symbol& other) const;
|
|
|
|
/**
|
|
Return true, if the Symbol is valid.
|
|
\return true, if the Symbol is valid.
|
|
*/
|
|
bool isValid() const { return (_id != -1); }
|
|
|
|
|
|
/**
|
|
Returns true, if this is a new Symbol according to APP6
|
|
\return true is this is a APP6-Symbol
|
|
*/
|
|
bool isAPP6() const;
|
|
|
|
/**
|
|
Convert Symbol to old ZDv 1/11 format.
|
|
WARNING: This is irreversible, you definitely loose all APP6-Attributes!
|
|
\param dimen_affil: Pointer to Symbol with geometry for attributes Dimension/Affiliation
|
|
\param bcdab: Pointer to Symbol with geometry for attribute BCDAB
|
|
\param commandlevel: Pointer to Symbol with geometry for attribute CommandLevel
|
|
\param mobility: Pointer to Symbol with geometry for attribute Mobility
|
|
\param intrinsicMobility: Pointer to Symbol with geometry for attribute Intrinsic-Mobility
|
|
\param miscs: QList with Pointers to all misc-Symbols
|
|
\param branches: QList with Pointers to all branch-Symbols
|
|
*/
|
|
void toZDv1_11(Symbol* dimen_affil,
|
|
Symbol* bcdab,
|
|
Symbol* commandlevel,
|
|
Symbol* mobility,
|
|
Symbol* vehicle,
|
|
Symbol* intrinsicMobility,
|
|
Symbol* arming,
|
|
const QList<Symbol*> &miscs,
|
|
const QList<Symbol*> &branches,
|
|
const SymbolTypes::AdditionalSymbolData &additionalData);
|
|
|
|
/**
|
|
Reset the symbol to its initial state
|
|
*/
|
|
void reset();
|
|
|
|
|
|
|
|
/**
|
|
Set the Symbols ID.
|
|
\param id: The ID
|
|
*/
|
|
void setID(int id) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
_id = id;
|
|
}
|
|
|
|
//! Return the Symbols ID
|
|
int id() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _id;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
Set the Symbols name
|
|
\param name: Name string for the Symbol
|
|
*/
|
|
void setName(const QString &name) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
_name = name;
|
|
}
|
|
|
|
//! Return the Symbols name
|
|
QString getName() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _name;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
// BRANCH
|
|
/////////////////////////////////////////////////
|
|
/**
|
|
Add a branch-tag. Does nothing, if the branch is already added.
|
|
\param branch: The branch-type to add
|
|
*/
|
|
void addBranch(SymbolTypes::t_branch branch);
|
|
|
|
/**
|
|
Remove a branch. Does nothing, if the branch does not exist.
|
|
\param branch: The branch-type to add
|
|
*/
|
|
void removeBranch(SymbolTypes::t_branch branch);
|
|
|
|
/**
|
|
Return a NGL::BitSet of all branches of the symbol. If a bit is set, the
|
|
according branch-tag is set.
|
|
\return NGL::BitSet of branch-tags
|
|
*/
|
|
NGL::BitSet<qint64> getBranchTags() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _branchTags;
|
|
}
|
|
|
|
/**
|
|
Check if a branch-type (bit( is set
|
|
\param branch: The branch-type to check
|
|
\return true if the is branch-tag is set
|
|
*/
|
|
bool hasBranch(SymbolTypes::t_branch branch) const {
|
|
return _branchTags.at(branch);
|
|
}
|
|
|
|
|
|
//! Enum defining all types of symbol-text
|
|
enum t_text {TEXT_UNDEFINED = 0, TEXT1, TEXT2, TEXT3};
|
|
//! Enum defining text-alignments
|
|
enum t_alignment {ALIGNMENT_UNDEFINED = 0, LEFT = 1, CENTER = 2, RIGHT = 3};
|
|
|
|
/**
|
|
Set the text-type for the symbol
|
|
\param t: the text-type
|
|
*/
|
|
void setTextType(t_text t);
|
|
|
|
//! Return the text-type
|
|
t_text getTextType() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _textType;
|
|
}
|
|
|
|
//! Set the maximum length of Strings
|
|
void setMaxStringLength(int length) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_maxStringLength = length;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
|
|
//! Return the max. allowed string-length for the current text-type
|
|
int maxStringLength() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _maxStringLength;
|
|
}
|
|
|
|
/**
|
|
Set a symbol-text. If a text is a Null-QString the corresponding line
|
|
remains unchanged. If the current text-type does not contain one of
|
|
the given lines, that line is silently ignored.
|
|
\param line1: Text for the first line
|
|
\param align1: Text-alignment for text1
|
|
\param line2: Text for the second line
|
|
\param align2: Text-alignment for text2
|
|
\param line3: Text for the third line
|
|
\param align3: Text-alignment for text3
|
|
*/
|
|
void setText(const QString &line1, t_alignment align1,
|
|
const QString &line2, t_alignment align2,
|
|
const QString &line3, t_alignment align3);
|
|
|
|
/**
|
|
Get a text-line. If a line is requested, which does not exist, a NULL-String
|
|
is returned.
|
|
\param line: Which line should be returned.
|
|
\return The line, or a NULL-String
|
|
*/
|
|
QString getText(unsigned int line) const;
|
|
|
|
/**
|
|
Get a text-alignment. If a line is requested, which does not exist, a
|
|
ALIGNMENT_UNDEFINED is returned.
|
|
\param line: Which alignment should be returned.
|
|
\return The alignment
|
|
*/
|
|
t_alignment getTextAlign(unsigned int line) const;
|
|
|
|
|
|
//! Set the dimen-tag
|
|
void setDimen(SymbolTypes::t_dimen d) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_transformed = ( _dimen == d );
|
|
_dimen = d;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
//! Get the dimen-tag
|
|
SymbolTypes::t_dimen getDimen() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _dimen;
|
|
}
|
|
|
|
//! Set the affil-tag
|
|
void setAffil(SymbolTypes::t_affil a) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_transformed = ( _affil == a );
|
|
_affil = a;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
//! Get the affil-tag
|
|
SymbolTypes::t_affil getAffil() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _affil;
|
|
}
|
|
|
|
//! Set the bcdab-tag
|
|
void setBcdab(SymbolTypes::t_bcdab d) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_bcd_ab = d;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
//! Get the bcdab-tag
|
|
SymbolTypes::t_bcdab getBcdab() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _bcd_ab;
|
|
}
|
|
|
|
//! Set the commandlevel-tag
|
|
void setCommandLevel(SymbolTypes::t_commandlevel d) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_commandlevel = d;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
//! Get the commandlevel-tag
|
|
SymbolTypes::t_commandlevel getCommandLevel() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _commandlevel;
|
|
}
|
|
|
|
|
|
//! Set the headquarter-tag
|
|
void setHeadquarter(bool d) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_headquarter = d;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
//! Get the headquarter-tag
|
|
bool getHeadquarter() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _headquarter;
|
|
}
|
|
|
|
|
|
//! Set the mob-tag
|
|
void setMob(SymbolTypes::t_mob d) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_mob = d;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
//! Get the mob-tag
|
|
SymbolTypes::t_mob getMob() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _mob;
|
|
}
|
|
|
|
|
|
//! Set the vehicle-tag
|
|
void setVehicle(SymbolTypes::t_vehicle d) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_vehicle = d;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
//! Get the vehicle-tag
|
|
SymbolTypes::t_vehicle getVehicle() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _vehicle;
|
|
}
|
|
|
|
//! Set the intrinsic-mob-tag
|
|
void setIntrinsicMob(SymbolTypes::t_intrinsicmob d) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_intrinsicmob = d;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
//! Get the intrinsic-mob-tag
|
|
SymbolTypes::t_intrinsicmob getIntrinsicMob() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _intrinsicmob;
|
|
}
|
|
|
|
//! Set the arming-tag
|
|
void setArming(SymbolTypes::t_arming d) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_arming = d;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
//! Get the arming-tag
|
|
SymbolTypes::t_arming getArming() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _arming;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
Add a misc-tag. Does nothing, if the misc is already added.
|
|
\param misc: The misc-type to add
|
|
*/
|
|
void addMisc(SymbolTypes::t_misc misc);
|
|
|
|
/**
|
|
Remove a misc. Does nothing, if the misc does not exist.
|
|
\param misc: The misc-type to remove
|
|
*/
|
|
void removeMisc(SymbolTypes::t_misc misc);
|
|
|
|
/**
|
|
Return a NGL::BitSet of all misc of the symbol. If a bit is set, the
|
|
according misc-tag is set.
|
|
\return NGL::BitSet of misc-tags
|
|
*/
|
|
NGL::BitSet<qint64> getMiscTags() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _miscTags;
|
|
}
|
|
|
|
//! Set the sector1-tag
|
|
void setSector1(SymbolTypes::t_sector1 d) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_sector1 = d;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
//! Get the sector1-tag
|
|
SymbolTypes::t_sector1 getSector1() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _sector1;
|
|
}
|
|
|
|
//! Set the sectoricon-tag
|
|
void setSectorIcon(SymbolTypes::t_sectoricon d) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_sectoricon = d;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
//! Get the sectoricon-tag
|
|
SymbolTypes::t_sectoricon getSectorIcon() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _sectoricon;
|
|
}
|
|
|
|
|
|
/**
|
|
Set the scale for the graphic-primitives.
|
|
\param scale: the scale-value
|
|
*/
|
|
void setScale(double scale) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
_scale = scale;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
|
|
/**
|
|
Get the scale for the graphic-primitives.
|
|
\return the scale
|
|
*/
|
|
double getScale() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _scale;
|
|
}
|
|
|
|
/**
|
|
Set the APP6-Classification
|
|
\param classify: the Classification
|
|
*/
|
|
/*
|
|
void setClassification(const NGLDAO::SClassification &classify) {
|
|
setClassId(classify.id);
|
|
setClassName(classify.name);
|
|
setClassHierarchy(classify.hierarchy);
|
|
setClassCodeId(classify.codeId);
|
|
}*/
|
|
|
|
//! Set the APP6-ClassId
|
|
void setClassId(int classId) { _classId = classId; }
|
|
//! Set the APP6-ClassName
|
|
void setClassName(const QString &className) { _className = className; }
|
|
//! Set the APP6- ClassHierarchy
|
|
void setClassHierarchy(const QString &classHierarchy) { _classHierarchy = classHierarchy; }
|
|
//! Set the APP6- ClassCodeId
|
|
void setClassCodeId(const QString &classCodeId) { _classCodeId = classCodeId; }
|
|
|
|
//! Get the APP6-ClassId
|
|
int getClassId() const { return _classId; }
|
|
//! Get the APP6-ClassName
|
|
QString getClassName() const { return _className; }
|
|
//! Get the APP6- ClassHierarchy
|
|
QString getClassHierarchy() const { return _classHierarchy; }
|
|
//! Get the APP6- ClassCodeId
|
|
QString getClassCodeId() const { return _classCodeId; }
|
|
|
|
/**
|
|
Add a graphics-primitive to the symbol. The primitive is always added
|
|
to the top of the visibility-stack. That means, it's above all previous
|
|
primitives. If the primitive was already added, the method does nothing,
|
|
and returns true.
|
|
\param p: Pointer to the the primitive
|
|
\return true, if the primitive was added, false otherwise
|
|
*/
|
|
bool addPrimitive(Primitive* p);
|
|
|
|
/**
|
|
Removes a primitive from the symbol. If the primitive is not in the symbol,
|
|
the method does nothing.
|
|
\param id: The id of the primitive to remove.
|
|
*/
|
|
void removePrimitive(unsigned int id);
|
|
|
|
|
|
void removePrimitive(SymbolTypes::t_misc misc);
|
|
void removePrimitive(SymbolTypes::t_sectoricon sectoricon);
|
|
void removePrimitive(SymbolTypes::t_sectoricon secicon, SymbolTypes::t_sector_position sectorPosition);
|
|
|
|
|
|
/**
|
|
Removes all primitive from the symbol.
|
|
*/
|
|
void clearPrimitives(bool exceptPrimitivesICON=false) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
|
|
QMutableLinkedListIterator<Primitive*> pi(_primitives);
|
|
while ( pi.hasNext() ) {
|
|
Primitive *p = pi.next();
|
|
if(exceptPrimitivesICON && (p->type() == Primitive::ICON)) {
|
|
continue;
|
|
}
|
|
pi.remove();
|
|
delete p;
|
|
}
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
|
|
/**
|
|
Removes all primitives ICON/TEXT from the symbol.
|
|
*/
|
|
void clearPrimitivesICON_TEXT() {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
|
|
QMutableLinkedListIterator<Primitive*> pi(_primitives);
|
|
while ( pi.hasNext() ) {
|
|
Primitive *p = pi.next();
|
|
if((p->type() == Primitive::ICON) || (p->type() == Primitive::TEXT)) {
|
|
pi.remove();
|
|
// ?? delete p
|
|
}
|
|
}
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
|
|
/**
|
|
Removes all primitiveICON of requested iconType from the symbol.
|
|
\param iconType: The iconType of the primitives to be removed.
|
|
*/
|
|
void clearPrimitives(SymbolTypes::t_icon_type iconType) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
|
|
QMutableLinkedListIterator<Primitive*> pi(_primitives);
|
|
while ( pi.hasNext() ) {
|
|
Primitive *p = pi.next();
|
|
if(p->iconType() == iconType) {
|
|
pi.remove();
|
|
}
|
|
}
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
|
|
/**
|
|
Removes all primitiveICON of requested sectorPosition from the symbol.
|
|
\param sectorPosition: The sectorPosition of the primitives to be removed.
|
|
*/
|
|
void clearPrimitives(SymbolTypes::t_sector_position sectorPosition) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
|
|
QMutableLinkedListIterator<Primitive*> pi(_primitives);
|
|
while ( pi.hasNext() ) {
|
|
Primitive *p = pi.next();
|
|
if(p->position() == sectorPosition) {
|
|
pi.remove();
|
|
// ?? delete p
|
|
}
|
|
}
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
|
|
/**
|
|
Removes all primitiveICON of requested iconType from the symbol.
|
|
\param iconType: The iconType of the primitives to be removed.
|
|
\param sectorPosition: The sectorPosition of the primitives to be removed.
|
|
\param id: The id of the primitives to be removed.
|
|
*/
|
|
void clearPrimitives(SymbolTypes::t_icon_type iconType, SymbolTypes::t_sector_position sectorPosition,
|
|
int id) {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
|
|
QMutableLinkedListIterator<Primitive*> pi(_primitives);
|
|
while ( pi.hasNext() ) {
|
|
Primitive *p = pi.next();
|
|
if ( (p->iconType() == iconType) &&
|
|
(p->position() == sectorPosition) &&
|
|
(p->icon() == id) )
|
|
{
|
|
pi.remove();
|
|
}
|
|
}
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
}
|
|
|
|
/**
|
|
Return a linked list of all primitives of the symbol
|
|
\return Linked list with all primitives
|
|
*/
|
|
QLinkedList<Primitive*> getPrimitives() const {
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return _primitives;
|
|
}
|
|
|
|
/**
|
|
Lookup for a t_misc primitive in this symbol
|
|
\param misc: id of a primitive
|
|
\return true, if the primitive was found, false otherwise
|
|
*/
|
|
bool containsPrimitive(SymbolTypes::t_misc misc) const;
|
|
|
|
/**
|
|
Lookup for a t_sectoricon primitive in this symbol
|
|
\param secicon: id of a primitive
|
|
\return true, if the primitive was found, false otherwise
|
|
*/
|
|
bool containsPrimitive(SymbolTypes::t_sectoricon secicon) const;
|
|
|
|
/**
|
|
Lookup for a (iconType, position, id) primitive in this symbol
|
|
\param iconType: icon type of primitive
|
|
\param position: position of primitive
|
|
\param id: id of primitive
|
|
\return true, if the primitive was found, false otherwise
|
|
*/
|
|
bool containsPrimitive(SymbolTypes::t_icon_type iconType,
|
|
SymbolTypes::t_sector_position sectorPosition,
|
|
int id) const;
|
|
|
|
/**
|
|
Move the primitive to the top of the visibility-stack.
|
|
If the given primitive can not be found, the method does nothing.
|
|
\param id: The id of the primitive
|
|
*/
|
|
void raisePrimitive(unsigned int id);
|
|
|
|
/**
|
|
Move the primitive to the bottom of the visibility-stack.
|
|
If the given primitive can not be found, the method does nothing.
|
|
\param id: The id of the primitive
|
|
*/
|
|
void lowerPrimitive(unsigned int id);
|
|
|
|
|
|
/**
|
|
Return the bounding box of this Symbol and of the given Attribute-Symbols.
|
|
The pointers to Attribute-Symbols may be NULL.
|
|
\param x0: Pointer for storing lower x-value of bounding box
|
|
\param y0: Pointer for storing lower y-value of bounding box
|
|
\param x1: Pointer for storing upper x-value of bounding box
|
|
\param y1: Pointer for storing upper y-value of bounding box
|
|
\param dimen_affil: Pointer to Symbol with geometry for attributes Dimension/Affiliation
|
|
\param bcdab: Pointer to Symbol with geometry for attribute BCDAB
|
|
\param commandlevel: Pointer to Symbol with geometry for attribute BCDAB
|
|
\param mobility: Pointer to Symbol with geometry for attribute Mobility
|
|
\return false, if the bounding box could not be calculated (i.e. no Primitives)
|
|
*/
|
|
bool getBoundingBox(double* x0, double* y0, double* x1, double* y1,
|
|
Symbol* dimen_affil, Symbol* bcdab, Symbol* commandlevel,
|
|
Symbol* mobility);
|
|
|
|
|
|
/**
|
|
Rotate all primitives around the center of their full bounding boxes and
|
|
reset the rotation-property. This means, the geometry of the primitive is
|
|
transformed (and possibly its type) to match the rotation-property. This is
|
|
used, if the graphics-API used for drawing the Primitives can not rotate
|
|
them itself.
|
|
*/
|
|
void rotatePrimitives();
|
|
|
|
|
|
//! A 3x3-Matrix used for transformations of Primitives
|
|
class Matrix
|
|
{
|
|
public:
|
|
//! Default-constructor creates identity matrix
|
|
Matrix() = default;
|
|
Matrix(double v11, double v12, double v13,
|
|
double v21, double v22, double v23,
|
|
double v31, double v32, double v33):
|
|
m11(v11), m12(v12), m13(v13),
|
|
m21(v21), m22(v22), m23(v23),
|
|
m31(v31), m32(v32), m33(v33)
|
|
{}
|
|
|
|
double m11 = 1;
|
|
double m12 = 0;
|
|
double m13 = 0;
|
|
double m21 = 0;
|
|
double m22 = 1;
|
|
double m23 = 0;
|
|
double m31 = 0;
|
|
double m32 = 0;
|
|
double m33 = 1;
|
|
};
|
|
|
|
|
|
//! Enum for selecting groups of transformation-matrices.
|
|
enum t_transformMatrixGroup {TMG_BCDAB, TMG_COMMAND_LEVEL, TMG_BRANCHES};
|
|
|
|
/**
|
|
If this Symbol is used to hold the geometry of the inner part of a Symbol
|
|
(which is inside the Role-Symbol), this method transformes the geometry
|
|
to match the Dimension and Affiliation settings. When transforming the
|
|
geometry, this method assumes, that the current geometry is valid for
|
|
Dimension==Land and Affiliation==Neutral (a square SymbolFrame).
|
|
Starting there, a transformation-matrix is chosen for the currently set
|
|
values of Dimension and Affiliation and all Primitives are transformed (except
|
|
those where getTransform() returns false) according to the matrix.
|
|
|
|
Since there are now three groups of transformation-matrices, it is necessary
|
|
to select the appropiate group with a parameter.
|
|
|
|
Transforming the Symbol sets the transformed-flag \see transformed(), if not
|
|
already set. It is possible to transform multiple times, the flag is read-only
|
|
and is not used to prohibit multiple transforms.
|
|
|
|
\param group: The group of matrices to use.
|
|
\param bestMatchTable: If not NULL, it points to a SymbolTable, which
|
|
contains this Symbol in already transformed or specially
|
|
constructed for the given attribute-combination. Before
|
|
transforming the symbol, the table is searched for a perfect
|
|
matching symbol. If found, it is used instead of transforming
|
|
this symbol.
|
|
*/
|
|
void transformSymbol(t_transformMatrixGroup group, SymbolTable *bestMatchTable = nullptr);
|
|
//! Transform Symbol according to Matrix
|
|
void transformSymbol(const Matrix &m, bool ignoreTransformFlag = false);
|
|
bool transformed() const { return _transformed; }
|
|
|
|
static QRectF getSymbolFrameRect(SymbolTypes::t_dimen dimen, SymbolTypes::t_affil affil);
|
|
|
|
private:
|
|
//! NGLLogger
|
|
NGL::INGLLogger& logger;
|
|
|
|
/**
|
|
(Re)Init the Matrix-Map
|
|
*/
|
|
static void initMatrixMaps();
|
|
//! Maps with transformation-matrices
|
|
static bool initMatrixDone;
|
|
static QMap<QPair<SymbolTypes::t_dimen, SymbolTypes::t_affil>, Matrix> _matrixMapBCDAB;
|
|
static QMap<QPair<SymbolTypes::t_dimen, SymbolTypes::t_affil>, Matrix> _matrixMapCommandLevel;
|
|
static QMap<QPair<SymbolTypes::t_dimen, SymbolTypes::t_affil>, Matrix> _matrixMapBranch;
|
|
|
|
//! True, if the cached bounding box is valid (i.e. no changes to geometry)
|
|
bool _bbCacheValid;
|
|
//! The cached bounding box of this symbol. Order: [lower x, lower y, upper x, upper y]
|
|
double _boundingBox[4];
|
|
|
|
static bool isAirSubsurface(SymbolTypes::t_dimen dimen);
|
|
|
|
protected:
|
|
//! The Symbol-ID
|
|
int _id;
|
|
|
|
//! BitArray containing all set Branch-Tags
|
|
NGL::BitSet<qint64> _branchTags;
|
|
|
|
//! String containing the symbols name/description
|
|
QString _name;
|
|
|
|
//! the text-type of the symbol
|
|
t_text _textType;
|
|
//! Text-strings
|
|
QString _line1, _line2, _line3;
|
|
//! Text-alignments
|
|
t_alignment _align1, _align2, _align3;
|
|
//! Max length of strings
|
|
int _maxStringLength;
|
|
|
|
//! dimen-attribute
|
|
SymbolTypes::t_dimen _dimen;
|
|
//! affil-attribute
|
|
SymbolTypes::t_affil _affil;
|
|
//! bcdab-attribute
|
|
SymbolTypes::t_bcdab _bcd_ab;
|
|
//! CommandLevel-attribute
|
|
SymbolTypes::t_commandlevel _commandlevel;
|
|
//! headquarter-attribute
|
|
bool _headquarter;
|
|
//! mob-attribute
|
|
SymbolTypes::t_mob _mob;
|
|
//! vehicle-attribute
|
|
SymbolTypes::t_vehicle _vehicle;
|
|
//! intrinsicmob-attribute
|
|
SymbolTypes::t_intrinsicmob _intrinsicmob;
|
|
//! arming-attribute
|
|
SymbolTypes::t_arming _arming;
|
|
|
|
SymbolTypes::t_sector1 _sector1;
|
|
SymbolTypes::t_sectoricon _sectoricon;
|
|
|
|
//! BitArray containing all set Misc-Tags
|
|
NGL::BitSet<qint64> _miscTags;
|
|
|
|
//! Flag is true, if Symbol is transformed according to _dimen and _affil
|
|
bool _transformed;
|
|
|
|
//! Scale of the graphic-primitives
|
|
double _scale;
|
|
//! Linked list containing all primitives of the symbol
|
|
QLinkedList<Primitive*> _primitives;
|
|
//! Count changes. Used for PixmapSymbolCache-Keys
|
|
int _changeCount;
|
|
|
|
//! APP6-ClassId
|
|
int _classId;
|
|
//! APP6-ClassName
|
|
QString _className;
|
|
//! APP6-ClassHierarchy
|
|
QString _classHierarchy;
|
|
//! APP6-ClassCodeId
|
|
QString _classCodeId;
|
|
}; // class Symbol
|
|
|
|
}; // namespace SymbologyXML
|