Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+42
View File
@@ -0,0 +1,42 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# PlanModel
SET(GeometryModel_SRCS
geometry_model.dtd
geometry_model.cpp
geometry_model.h
geometry_model_export.h
geometry_model_factory.cpp
geometry_model_factory.h
geometry_model_q_dom.cpp
geometry_model_q_dom.h
geometry_node_visitor.cpp
geometry_node_visitor.h
geometry_pixelTextBox.cpp
)
SOURCE_GROUP(GeometryModel FILES ${GeometryModel_SRCS})
NGL_ADD_LIBRARY(WS situationMapGeometryModel SHARED ${GeometryModel_SRCS})
NGL_TARGET_INCLUDE_DIRECTORIES( situationMapGeometryModel
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/..
)
NGL_TARGET_LINK_LIBRARIES(situationMapGeometryModel
PRIVATE
NGLLogger
PUBLIC
situationMapCommon
Qt5::Core
Qt5::Gui
Qt5::Xml
)
NGL_INSTALL_TARGET(situationMapGeometryModel)
+38
View File
@@ -0,0 +1,38 @@
/**
**
** @RDE_HEADER@
** GeometryModel to write and read PlanEditor plans.
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 11.11.2015, JT : First edition for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#include "geometry_model.h"
namespace SituationMap
{
GeometryModel::GeometryModel(QObject *parent) : QObject(parent) {;}
GeometryModel::GeometryModel(const GeometryModel &) : QObject() {;}
} // namespace SituationMap
+400
View File
@@ -0,0 +1,400 @@
<!--
DTD fuer Plan-Formate
(c)RDE 2009
Stephan Kuhagen
-->
<!--
The Top-Element of the Plan. Defines global variables in the Attributes.
-->
<!ELEMENT GeometryModelDocument (GeometryModel|MapSettings) >
<!ELEMENT GeometryModel (dictionarySymbol|ellipse|line|polyline|rectangle|spline|symbol|text|node)>
<!ELEMENT MapSettings EMPTY>
<!--
utm_zone: UTM-zone and band (two digits, one char)
utm_grid: UTM-grid-Square (two chars)
utm_east: UTM-easting-value (int)
utm_north: UTM-northing-value (int)
pe_show_utm: bool to indicate, if the PE should display the UTM-grid
pe_map_saturation: saturation in % of the map in the PE
pe_map_brightness: brightness in % of the map in the PE
pe_map_zoom: zoom-value of the map in the PE
pe_map_rotation: The rotation of the map (double)
pe_map_type: The type of the map (Raster, Vector, Contour, Elevation, RasterElevation)
pe_map_centerx: center-x of the map in the PE
pe_map_centery: center-y of the map in the PE
-->
<!ATTLIST MapSettings
utm_zone CDATA #REQUIRED
utm_grid CDATA #REQUIRED
utm_east CDATA #REQUIRED
utm_north CDATA #REQUIRED
pe_show_utm CDATA #REQUIRED
pe_map_saturation CDATA #REQUIRED
pe_map_brightness CDATA #REQUIRED
pe_map_zoom CDATA #REQUIRED
pe_map_rotation CDATA #REQUIRED
pe_map_type CDATA #REQUIRED
pe_map_centerx CDATA #REQUIRED
pe_map_centery CDATA #REQUIRED
pe_symbol_transparency CDATA #IMPLIED
pe_symbol_fill_type CDATA #IMPLIED
pe_symbol_scale CDATA #IMPLIED>
<!--
A node is a grouping element, which can hold any number of primitives or
other nodes, thus creating a tree.
-->
<!ELEMENT node (dictionarySymbol|ellipse|line|polyline|rectangle|spline|symbol|text|node)*>
<!--
The symbology library provides a symbol dictionary. Each symbol is defined by a list of coordinates and one non-ambiguous SIDC code. The SIDC
is a string with 15 character. See symbology library for further details.
-->
<!ELEMENT dictionarySymbol (point+)>
<!ATTLIST dictionarySymbol
GuiDisplayName CDATA #IMPLIED
SIDC CDATA #REQUIRED
SIDC_Norm CDATA #REQUIRED >
<!--
Defines ellipsis and circles. Can have start-angle and extent for sections of
circles/ellipsis. The point defines the center of the primitive. The
Attributes width and height define the metric dimensions, resulting in a
centered bounding box. The primitive can be rotated with attribute
rotate. Start-angle and extent are defined for the axis-parallel bounding-box
and are rotated with the box. Rotation is done around the center-point.
The optional text-tag is used for text directly assigned to this primitive.
-->
<!ELEMENT ellipse (point,text?)>
<!--
width: The metric width of the ellipse.
height: The metric height of the ellipse.
rotate: The bounding rectangle, that defines the ellipse is rotated according
to the angle here (360° for full rotation). Double-Value.
start: Sets the start-angle of an open ellipse before (!) rotation. Double-Value.
extent: Sets the extent of the ellipse. For a full ellipse this must be
360. Double-Value.
color: Color in 32-Bit hex RGBA (#RRGGBBAA)
linewidth: Line-width. Double-Value.
linestyle: An enum defining the line-style
fill: A bool, if true, the primitive should be filled with the given color and pattern.
fill_color: Fill-Color in 32-Bit hex RGBA (#RRGGBBAA)
fill_pattern: An enum defining the fill-pattern.
fill_style: An enum defining the style for a filles ellipse:
- "chord": A straight line between the start-point and end-point
defines the inner region to be filled.
- "pieslice": A line from the start-point to the center and from the
center to the end-point define the inner region to be filled.
-->
<!ATTLIST ellipse
GuiDisplayName CDATA #IMPLIED
rotate CDATA #IMPLIED
width CDATA #REQUIRED
height CDATA #REQUIRED
start CDATA #IMPLIED
extent CDATA #IMPLIED
color CDATA #REQUIRED
linewidth CDATA #REQUIRED
linestyle (solid|dashed|dotted|dashed_dotted) #IMPLIED
fill CDATA #IMPLIED
fill_color CDATA #IMPLIED
fill_pattern (none|dots|hor1|hor2|ver1|ver2|diag1|diag2|solid) #IMPLIED
fill_style (chord|pieslice) #IMPLIED>
<!--
Defines a line with start- and endpoint.
The optional text-tag is used for text directly assigned to this primitive.
-->
<!ELEMENT line (point,point,text?)>
<!--
color: Color in 32-Bit hex RGBA (#RRGGBBAA)
arrows: Enum defining, if and where to add arrows to the line.
arrow_height: The height of the arrow from the arrow-head to the outer points,
parallel to the middle axis of the arrow.
arrow_clamp_height: The height from the the arrow-neck to the outer points,
parallel to the middle axis of the arrow.
arrow_width: The distance between the outer points of the arrow.
arrow_line_width: The line width of the line used to draw the arrow.
linewidth: Line-width. Double-Value.
linestyle: An enum defining the line-style
-->
<!ATTLIST line
GuiDisplayName CDATA #IMPLIED
color CDATA #REQUIRED
arrows (none|start|end|both) #IMPLIED
arrow_height CDATA #IMPLIED
arrow_clamp_height CDATA #IMPLIED
arrow_width CDATA #IMPLIED
arrow_line_width CDATA #IMPLIED
linewidth CDATA #REQUIRED
linestyle (solid|dashed|dotted|dashed_dotted) #IMPLIED>
<!--
Defines a polyline with at least three points.
The optional text-tag is used for text directly assigned to this primitive.
-->
<!ELEMENT polyline (point,point,point+,text?)>
<!--
color: Color in 32-Bit hex RGBA (#RRGGBBAA)
linewidth: Line-width. Double-Value.
linestyle: An enum defining the line-style
arrows: Enum defining, if and where to add arrows to the line. If the
primitive is closed, no arrows should be drawn.
arrow_height: The height of the arrow from the arrow-head to the outer points,
parallel to the middle axis of the arrow.
arrow_clamp_height: The height from the the arrow-neck to the outer points,
parallel to the middle axis of the arrow.
arrow_width: The distance between the outer points of the arrow.
arrow_line_width: The line width of the line used to draw the arrow.
close: A bool. If true, connect the start- and end-point.
fill: A bool, if true, the primitive should be filled with the given color and pattern.
fill_color: Fill-Color in 32-Bit hex RGBA (#RRGGBBAA)
fill_pattern: An enum defining the fill-pattern.
-->
<!ATTLIST polyline
GuiDisplayName CDATA #IMPLIED
color CDATA #REQUIRED
linewidth CDATA #REQUIRED
linestyle (solid|dashed|dotted|dashed_dotted) #IMPLIED
arrows (none|start|end|both) #IMPLIED
arrow_height CDATA #IMPLIED
arrow_clamp_height CDATA #IMPLIED
arrow_width CDATA #IMPLIED
arrow_line_width CDATA #IMPLIED
close CDATA #REQUIRED
fill CDATA #IMPLIED
fill_color CDATA #IMPLIED
fill_pattern (none|dots|hor1|hor2|ver1|ver2|diag1|diag2|solid) #IMPLIED>
<!--
Defines a rectangle with a center-point and width/height.
The optional text-tag is used for text directly assigned to this primitive.
-->
<!ELEMENT rectangle (point,text?)>
<!--
color: Color in 32-Bit hex RGBA (#RRGGBBAA)
width: The metric width of the rectangle.
height: The metric height of the rectangle.
rotate: The rectangle is rotated according to the angle here (360° for full
rotation). Double-Value.
linewidth: Line-width. Double-Value.
linestyle: An enum defining the line-style
rounding: A percentage-value (double) for round edges
fill: A bool, if true, the primitive should be filled with the given color and pattern.
fill_color: Fill-Color in 32-Bit hex RGBA (#RRGGBBAA)
fill_pattern: An enum defining the fill-pattern.
-->
<!ATTLIST rectangle
GuiDisplayName CDATA #IMPLIED
color CDATA #REQUIRED
width CDATA #REQUIRED
height CDATA #REQUIRED
rotate CDATA #IMPLIED
linewidth CDATA #REQUIRED
linestyle (solid|dashed|dotted|dashed_dotted) #IMPLIED
rounding CDATA #IMPLIED
fill CDATA #IMPLIED
fill_color CDATA #IMPLIED
fill_pattern (none|dots|hor1|hor2|ver1|ver2|diag1|diag2|solid) #IMPLIED>
<!--
Defines a spline with at least three points. The first and the last point
define the endpoints, all other points define the curve between them.
The optional text-tag is used for text directly assigned to this primitive.
-->
<!ELEMENT spline (point,point,point+,text?)>
<!--
color: Color in 32-Bit hex RGBA (#RRGGBBAA)
linewidth: Line-width. Double-Value.
linestyle: An enum defining the line-style
arrows: Enum defining, if and where to add arrows to the line. If the
primitive is closed, no arrows should be drawn.
arrow_height: The height of the arrow from the arrow-head to the outer points,
parallel to the middle axis of the arrow.
arrow_clamp_height: The height from the the arrow-neck to the outer points,
parallel to the middle axis of the arrow.
arrow_width: The distance between the outer points of the arrow.
arrow_line_width: The line width of the line used to draw the arrow.
close: A bool. If true, connect the start- and end-point.
fill: A bool. If true, the primitive should be filled with the given color and
pattern. This also means, that the start-point is automatically
connected to the end-point to get a closed shape to fill.
fill_color: Fill-Color in 32-Bit hex RGBA (#RRGGBBAA)
fill_pattern: An enum defining the fill-pattern.
-->
<!ATTLIST spline
GuiDisplayName CDATA #IMPLIED
color CDATA #REQUIRED
linewidth CDATA #REQUIRED
linestyle (solid|dashed|dotted|dashed_dotted) #IMPLIED
arrows (none|start|end|both) #IMPLIED
arrow_height CDATA #IMPLIED
arrow_clamp_height CDATA #IMPLIED
arrow_width CDATA #IMPLIED
arrow_line_width CDATA #IMPLIED
close CDATA #REQUIRED
fill CDATA #IMPLIED
fill_color CDATA #IMPLIED
fill_pattern (none|dots|hor1|hor2|ver1|ver2|diag1|diag2|solid) #IMPLIED>
<!--
A symbol to display in the plan.
position, offsetx (in Pixel), offsety (in Pixel), direction of movement
-->
<!ELEMENT symbol (point)>
<!--
text_w: Text for symbols text-field w.
text_xy: Text for symbols text-field xy.
text_v: Text for symbols text-field v.
text_t: Text for symbols text-field t.
text_z: Text for symbols text-field z.
text_ef: Text for symbols text-field ef.
text_g: Text for symbols text-field g.
text_h: Text for symbols text-field h.
text_m: Text for symbols text-field m.
text_jklnp: Text for symbols text-field jklnp.
symbol_id: ID of the symbol (int).
force_id: Force-ID of the symbol (int).
abc_protection: Flag for abc_protection (bool).
affil: Enum for affiliation of the symbol.
mobility: Enum for the mobility of the symbol.
w_vbg_et: Enum for tactical state of the symbol. Corresponds to enum w_vbg_et
in zskssmal_teilnehmer.h.
rotate: The Symbol is rotated according
to the angle here (360° for full rotation). Double-Value.
-->
<!ATTLIST symbol
GuiDisplayName CDATA #IMPLIED
text_w CDATA #IMPLIED
text_xy CDATA #IMPLIED
text_v CDATA #IMPLIED
text_t CDATA #IMPLIED
text_z CDATA #IMPLIED
text_ef CDATA #IMPLIED
text_g CDATA #IMPLIED
text_h CDATA #IMPLIED
text_m CDATA #IMPLIED
text_jklnp CDATA #IMPLIED
symbol_id CDATA #IMPLIED
symbol_offsetX CDATA #IMPLIED
symbol_offsetY CDATA #IMPLIED
symbol_direction CDATA #IMPLIED
force_id CDATA #IMPLIED
symbol_state CDATA #IMPLIED
symbol_uncertainty CDATA #IMPLIED
damage_force_id CDATA #IMPLIED
abc_protection CDATA #IMPLIED
affil (unknown|friend|neutral|enemy) #REQUIRED
mobility (wheel|wheel_all_terrain|chain|chain_all_terrain|trailer|train) #REQUIRED
w_vbg_et (einsatzbereit|treffer_ohne_wirkung|annaehender_treffer|zeitlicher_ausfall|leichter_treffer|mittlerer_treffer|schwerer_treffer|bewegungsunfaehig|bewegungsunfaehig_sichtb|ausfall_waffenanlage|ausfall_waffenanlage_sichtb|totalausfall) #REQUIRED
rotate CDATA #IMPLIED>
<!--
A one-line or multiline-text with optional background and frame.
If used as a child to another primitive, the point position of the text is
ignored. The alignment attributes define the text-position in relation to the
primitive instead.
-->
<!ELEMENT text (point,text_data)>
<!--
anchor_horizontal: Horizontal position of the text on its point
anchor_vertical: Vertical position of the text on its point
margin_horizontal: Horizontal margin in Pixels between the texts bounding box and the surrounding frame
margin_vertical: Vertical margin in Pixels between the texts bounding box and the surrounding frame
color: Color in 32-Bit hex RGBA (#RRGGBBAA)
font: Font-Type
font_size: Font-Size. Int.
font_italic: A bool. If true, the font should be italic.
font_bold: A bool. If true, the font should be bold.
box: A bool, if true, the primitive should be filled with the given color and pattern.
linewidth: Line-width for the box. Double-Value.
linestyle: An enum defining the line-style for the box.
linecolor: Color in 32-Bit hex RGBA (#RRGGBBAA) for the outline of the box.
fill: A bool, if true, the box should be filled with the given color and pattern.
fill_color: Fill-Color for the box in 32-Bit hex RGBA (#RRGGBBAA)
fill_pattern: An enum defining the fill-pattern for the box.
rotate: The bounding rectangle, that defines the ellipse is rotated according
to the angle here (360° for full rotation). Double-Value.
-->
<!ATTLIST text
GuiDisplayName CDATA #IMPLIED
anchor_horizontal (left|center|right) #REQUIRED
anchor_vertical (top|center|bottom) #REQUIRED
margin_horizontal CDATA #IMPLIED
margin_vertical CDATA #IMPLIED
color CDATA #REQUIRED
font (SansSerif|Serif|Fixed|Decorative) #REQUIRED
font_size CDATA #REQUIRED
font_italic CDATA #IMPLIED
font_bold CDATA #IMPLIED
box CDATA #IMPLIED
linewidth CDATA #IMPLIED
linestyle (solid|dashed|dotted|dashed_dotted) #IMPLIED
linecolor CDATA #IMPLIED
fill CDATA #IMPLIED
fill_color CDATA #IMPLIED
fill_pattern (none|dots|hor1|hor2|ver1|ver2|diag1|diag2|solid) #IMPLIED
rotate CDATA #IMPLIED>
<!--
A tag that contains the actual text-data of a text-tag.
-->
<!ELEMENT text_data (#PCDATA)>
<!--
alignment: If this text contains more than one line, this defines the
alignment of the text in the bounding box of all lines.
-->
<!ATTLIST text_data
alignment (left|center|right) #REQUIRED>
<!--
Defines a point with a double precision x and y-value.
-->
<!ELEMENT point EMPTY>
<!--
x: The x-coordinate of the point.
y: The y-coordinate of the point.
-->
<!ATTLIST point
x CDATA #REQUIRED
y CDATA #REQUIRED>
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,21 @@
/**
* Export definitions
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <qglobal.h>
#ifndef GEOMETRYMODEL_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define GEOMETRYMODEL_EXPORT
# else
# if defined(MAKE_SITUATIONMAPGEOMETRYMODEL_LIB)
# define GEOMETRYMODEL_EXPORT Q_DECL_EXPORT
# else
# define GEOMETRYMODEL_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
@@ -0,0 +1,58 @@
/**
**
** @RDE_HEADER@
** GeometryModelFactory to create geometry model
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 20.11.2015, JT : First edition for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#include "geometry_model_factory.h"
#include "geometry_model_q_dom.h"
namespace SituationMap
{
GeometryModelFactory *GeometryModelFactory::singleton()
{
static GeometryModelFactory s_factory;
return &s_factory;
} /* GeometryModelFactory::singleton() */
GeometryModel *GeometryModelFactory::create()
{
return new GeometryModelQDom();
} // GeometryModelFactory::create()
GeometryModel *GeometryModelFactory::clone(GeometryModel *geoModel)
{
GeometryModelQDom * qdomModel = dynamic_cast<GeometryModelQDom*>(geoModel);
if (qdomModel)
return new GeometryModelQDom(*qdomModel);
return nullptr;
} // GeometryModelFactory::clone()
} /* namespace SituationMap */
@@ -0,0 +1,59 @@
/**
**
** @RDE_HEADER@
** GeometryModelFactory to create geometry model
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 20.11.2015, JT : First edition for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#pragma once
#include "geometry_model_q_dom.h"
namespace SituationMap
{
/**
@brief Factory class to create GeometryModels
@see GeometryModel GeometryModelQDom
*/
class GEOMETRYMODEL_EXPORT GeometryModelFactory
{
public:
static GeometryModelFactory *singleton();
GeometryModelFactory() = default;
~GeometryModelFactory() = default;
GeometryModelFactory(const GeometryModelFactory &) = delete;
GeometryModelFactory operator =(const GeometryModelFactory &) = delete;
GeometryModel *create();
GeometryModel *clone( GeometryModel * );
}; /* GeometryModelFactory */
} /* namespace SituationMap */
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,374 @@
/**
**
** @RDE_HEADER@
** GeometryModel implementation to write and read PlanEditor plans from/to XML and manipulate DOM-tree.
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Stephan Kuhagen <kuhagen@rheinmetall-de.com>
** Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** ??.??.200?, SK : First edition for use with Qt4
** 11.11.2015, JT : Splitting interface and implementation
**
** -----------------------------------------------------------------------------------------------
*/
// clazy:excludeall=const-signal-or-slot
#pragma once
#include <QtGui/QColor>
#include <QtXml/QDomDocument>
#include <QtCore/QMultiMap>
#include <QtCore/QObject>
#include <QtCore/QPair>
#include <QtCore/QPointF>
#include <QtCore/QRectF>
#include <QtCore/QStack>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include "geometry_model.h"
class QTransform;
namespace SituationMap
{
// exported for unit test only
class GEOMETRYMODEL_EXPORT GeometryModelQDom : public GeometryModel, public QDomDocument
{
Q_OBJECT
public:
explicit GeometryModelQDom(QObject *parent = nullptr);
//! Copy-Constructor
GeometryModelQDom(const GeometryModelQDom &other);
~GeometryModelQDom();
GeometryModelQDom & operator = (const GeometryModelQDom &other);
QByteArray toByteArray() const override;
QByteArray toByteArrayDebug() const override;
bool fromByteArray(const QByteArray &content) override;
bool fromDevice(QIODevice *device) override;
bool fromByteArrayDebug(const QByteArray &content) override;
bool isEmpty() const override;
Node getRootNode() const override;
Node getMapDefaultSettingsNode() const override;
void setModelAttribute(GeometryModel::Attribute attribute, const QVariant &value) override;
void setModelEditorAttribute(GeometryModel::Attribute attribute, const QVariant &value) override;
void setPrimitiveAttribute(const GeometryModel::Node &node, GeometryModel::Attribute attribute, const QVariant &value) override;
void movePrimitiveIntoGroup(const GeometryModel::Node &primitive, const GeometryModel::Node &target) override;
void releaseGroup(const GeometryModel::Node &group) override;
void deleteGroup(const GeometryModel::Node &group) override;
void removePrimitive(const GeometryModel::Node &primitive) override;
void removePrimitivesByUserData(const QList<int> &userDataList) override;
void removeText(GeometryModel::Node &parent) override;
void setTextData(const GeometryModel::Node &textNode, const QString &data, GeometryModel::HorizontalAlign textAlign) override;
void clearModel() override;
void translateNode(const GeometryModel::Node &node, double x, double y) override;
void moveNode(const GeometryModel::Node &node, double x, double y) override;
void scaleNode(const GeometryModel::Node &node, double scaleX, double scaleY) override;
void rotateNode(const GeometryModel::Node &node, double angle) override;
void reorderPrimitives(const QList<GeometryModel::Node> &nodes, GeometryModel::PrimitivOrder order) override;
void merge(const GeometryModel::Node &other, bool skipUndo = false, bool intoNewGroup = false) override;
void merge(GeometryModel *other, bool skipUndo = false, bool intoNewGroup = false) override;
unsigned int modificationCounter() const override;
void resetModificationCounter() override;
void undo(unsigned int steps = 1) override;
void redo(unsigned int steps = 1) override;
void enableUndo(bool enable) override;
void startUndoBlock() override;
void endUndoBlock(const QString &eventDescription = QString()) override;
void abortUndoBlock() override;
void setMaxUndoSteps(unsigned int max) override;
unsigned int maxUndoSteps() const override;
void cleanModel() override;
GeometryModel::Node addPrimitive(GeometryModel::PrimitiveType type
, const QList<QPointF> &points
, const QList<QPair<GeometryModel::Attribute, QVariant> > &attributes
, int userData = -1
, const QString &textData = QString()
, GeometryModel::HorizontalAlign textAlign = HorizontalAlign::Left) override;
bool setPrimitivePoints(const GeometryModel::Node &node, const QList<QPointF> &points) override;
GeometryModel::Node addText(const GeometryModel::Node &parent
, const QString &textData
, GeometryModel::HorizontalAlign textAlign
, const QList<QPair<GeometryModel::Attribute, QVariant> > &attributes
, int userData) override;
GeometryModel::Node getText(const GeometryModel::Node &parent) const override;
QString getTextData(const GeometryModel::Node &textNode) const override;
QList<QPointF> getPrimitivePoints(const GeometryModel::Node &node) const override;
QRectF getBoundingBox(const GeometryModel::Node &node) const override;
void setNodeDisplayName(const Node &node, const QString &name) override;
QString getNodeDisplayName(const Node &node) const override;
QVariant getModelAttribute(Attribute attribute) const override;
QVariant getAttribute(const GeometryModel::Node &node, GeometryModel::Attribute attribute) const override;
template <class T> T getAttribute(const Node &node, Attribute attribute) const;
bool hasAttribute(const GeometryModel::Node &node, GeometryModel::Attribute attribute) const override;
QVariant::Type attributeType(const GeometryModel::Attribute &attribute) const override;
QList<GeometryModel::Attribute> supportedAttributes(GeometryModel::PrimitiveType type) const override;
GeometryModel::Node createGroup(const QList<GeometryModel::Node> &primitives) override;
GeometryModel::Node isInGroup(const GeometryModel::Node &primitive) const override;
GeometryModel::NodeList getGroupPrimitives(const GeometryModel::Node &node) override;
GeometryModel::Node findPrimitive(int userData) const override;
bool hasUserData(const Node &node) const override;
int getUserData(const GeometryModel::Node &node, bool *ok = nullptr) const override;
void setUserData(const GeometryModel::Node &node, int userData) override;
QMultiMap<int, GeometryModel::Node> userDataMap(const GeometryModel::Node &node = GeometryModel::Node()) override;
GeometryModel::Node copy(const GeometryModel::Node &node, int userData = 0) override;
GeometryModel::PrimitiveType getType(const GeometryModel::Node &node) const override;
unsigned int undoSteps() const override;
unsigned int redoSteps() const override;
QStringList undoHistory() const override { return _undoHistory.toList(); }
QStringList redoHistory() const override { return _redoHistory.toList(); }
void clearUndoStack() override
{
_undoStack.clear();
_undoHistory.clear();
} // clearUndoStack
void clearRedoStack() override
{
_redoStack.clear();
_redoHistory.clear();
} // clearRedoStack
QString attributeToString(const GeometryModel::Attribute &attribute) const override;
bool parseSymbolAttributeString(const QString &sidcAttributes, QMap<QString, QVariant> &attrMap) const override;
QString buildSymbolAttributeString(const QMap<QString, QVariant> &attrMap) const override;
static void cleanupStaticMember();
private:
static void valueFromVariant(const QVariant &v, QPointF &result);
static void valueFromVariant(const QVariant &v, QColor &result);
/**
convert to QString (with non locale-aware conversions)
*/
static QString variant2XmlString(const QVariant &v);
/**
Create a QColor from an attribute-value with alpha-channel (QVariant
ignores Alpha)
\param attColor: The QString-QVariant from an attribute of Type QColor
\return QColor with alpha-channel or invalid QColor, if the value could be parsed.
*/
static QColor colorFromString(const QString &attColor);
/**
Create a QPoint from an attribute-value
\param attPoint: The QString-QVariant from an attribute of Type QPointF
\return QPointF
*/
static QPointF pointFromString(const QString &attPoint);
//! A mapping between all primitives and the attributes they support
static QMultiMap<GeometryModel::PrimitiveType, GeometryModel::Attribute> _primitiveSupportedAttributes;
//! Mappings between all primitive-types and their string/tag-name
static QMap<QString, GeometryModel::PrimitiveType> _primitiveTagsTypes;
static QMap<GeometryModel::PrimitiveType, QString> _primitiveTagsStrings;
//! Default-Values for all supported attributes
static QMap<QPair<GeometryModel::PrimitiveType, GeometryModel::Attribute>, QString> _attributeDefaults;
//! Mapping between Attributes and their QVariant-Type.
static QMap<GeometryModel::Attribute, QVariant::Type> _attributeTypes;
//! Bool to check, if static class variables have been initialized
static bool _staticInitDone;
/**
Init data of the object
*/
void init();
/**
Transform the points of a primitive.
\sa {translateNode(), moveNode(), rotateNode(), scaleNode()}
\param node: The primitive to transform.
\param t: The transformation-matrix.
*/
void transformNode(const QDomNode &node, const QTransform &t);
GeometryModel::PrimitiveType getType(const QDomNode &node) const;
bool hasUserData(const QDomNode &node) const;
int getUserData(const QDomNode &node, bool *okPtr) const;
QRectF getBoundingBox(const QDomNode &node) const;
QList<QPointF> getPrimitivePoints(const QDomNode &node) const;
bool hasAttribute(const QDomNode &node, GeometryModel::Attribute attribute) const;
QVariant getAttribute(const QDomNode &node, GeometryModel::Attribute attribute) const;
void removePrimitive(const QDomNode &primitive);
void translateNode(const QDomNode &node, double x, double y);
void moveNode(const QDomNode &node, double x, double y);
void scaleNode(const QDomNode &node, double scaleX, double scaleY);
void rotateNode(const QDomNode &node, double angle);
void merge(const QDomNode &other, bool skipUndo = false, bool intoNewGroup = false);
QDomNode createGroup(const QList<QDomNode> &primitives);
QMultiMap<int, QDomNode> userDataMap(const QDomNode &node) const;
/**
Wrapper for signal changed(), checks _skipChangedSignal
!!! ATTENTION: Do not use the signal changed directly.
Use emitChangedSignal() instead !!!
\param what: Short description of the change for logging
\param node: the changed node (if this is a Null-Node, the Root-Node of
the plan has changed)
\param att: The attribute, that changed. If att==MaxAttributes, then
multiple attributes are changed
\param coordsChanged: if true, the coordinated of the primitive are changed
*/
void emitChangedSignal(const Node &node, Attribute att, bool coordsChanged);
//! Lock for temporarily blocking changed()-Signals
bool _skipChangedSignal;
//! Undo-Stack
bool _undoEnabled;
unsigned int _maxUndoSteps;
QStack<QDomNode> _undoStack;
QStack<QString> _undoHistory;
QStack<QDomNode> _redoStack;
QStack<QString> _redoHistory;
//! Undo-blocks
QDomNode _undoBlock;
QString _undoHistoryBlock;
bool _insideUndoBlock;
unsigned int _modificationCounter;
//! Push/pop current state to undo-stack, if not locked
void pushUndo(const QString &eventDescription = QString());
GeometryModel::Node popUndo();
}; // GeometryModelQDom
template <class T> T GeometryModelQDom::getAttribute(const Node &node, Attribute attribute) const
{
const QVariant &v = getAttribute(node, attribute);
switch (qMetaTypeId<T>())
{
case QMetaType::QPointF:
case QMetaType::QColor:
{
T result; valueFromVariant(v, result); return result;
} break;
default: break;
}
return v.value<T>();
} // template <class T> T GeometryModelQDom::getAttribute( const Node & node, Attribute attribute ) const
} // namespace SituationMap
@@ -0,0 +1,75 @@
/**
**
** @RDE_HEADER@
** Node visitor for GeometryModel.
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 07.07.2016, JT : First edition for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#include "geometry_node_visitor.h"
namespace SituationMap
{
GeometryNodeVisitor::GeometryNodeVisitor(GeometryModel *geoModel) : m_geometryModel(geoModel) {;}
bool GeometryNodeVisitor::traverse()
{
if (!m_geometryModel)
return true;
return traverse(m_geometryModel->getRootNode());
} // bool GeometryNodeVisitor::traverse()
bool GeometryNodeVisitor::traverse(GeometryModel::Node node)
{
if (!m_geometryModel)
return true;
if (node.isValid())
{
const GeometryModel::PrimitiveType primitiveType = m_geometryModel->getType(node);
if ((GeometryModel::PrimitiveType::RootNode == primitiveType) || (GeometryModel::PrimitiveType::Node == primitiveType))
{
if (node.hasChildNodes())
{
node = node.firstChildNode();
while (node.isValid())
{
if (!traverse(node))
return false;
node = node.next();
}
}
}
if (!apply(m_geometryModel, node, primitiveType))
return false;
} // if
return true;
}
} // namespace SituationMap
@@ -0,0 +1,75 @@
/**
**
** @RDE_HEADER@
** Node visitor for GeometryModel.
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 07.07.2016, JT : First edition for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#pragma once
#include "geometry_model.h"
namespace SituationMap
{
/**
GeometryNopdeVisitor implements visitor pattern to traverse geoemtry model tree. The apply function will be
called for each node in geometry model.
*/
class GEOMETRYMODEL_EXPORT GeometryNodeVisitor
{
public:
explicit GeometryNodeVisitor(GeometryModel *geoModel);
virtual ~GeometryNodeVisitor() = default;
GeometryNodeVisitor(const GeometryNodeVisitor &) = delete;
/**
Traversing the complete geometry model
*/
bool traverse();
/**
Traversing the sub-tree of node. Coming in deepth first.
*/
bool traverse(GeometryModel::Node node);
protected:
/**
For each node the apply function will be called. If apply returns false the traversal is aborted. In
other case if return value is true the traversel is continued.
@param geoModel Pointer to geometry model
@param node Node of geometry model
@param nodeType Type of node
@return false to abort traversael otherwise true
*/
virtual bool apply(GeometryModel *geoModel, const GeometryModel::Node &node, GeometryModel::PrimitiveType nodeType) = 0;
GeometryModel *m_geometryModel;
}; // GeometryNodeVisitor
} // namespace SituationMap
@@ -0,0 +1,215 @@
/**
* @RDE_HEADER@
* PixelTextBoxData as Addon to GeometryModel
* $Id$
* $HeadURL$
* $Author$
* Created by Norbert Thoden, SLSE, 2023-04-27
*/
#include "geometry_pixelTextBox.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonArray>
#include <QDebug>
namespace SituationMap
{
PixelTextBoxData::PixelTextBoxData(const QString &htmlText, const QColor &backgroundColor)
: m_htmlText(htmlText), m_backgroundColor(backgroundColor)
{
}
void PixelTextBoxData::reset()
{
m_htmlText.clear();
m_backgroundColor = QColor();
m_position = QPoint();
m_size = QSize();
}
bool PixelTextBoxData::isEmpty() const
{
return m_htmlText.isEmpty();
}
QString PixelTextBoxData::toDebugString() const
{
QJsonDocument jDoc(toJson());
return QString::fromStdString(jDoc.toJson(QJsonDocument::JsonFormat::Compact).toStdString());
}
bool PixelTextBoxData::operator==(const PixelTextBoxData &o) const
{
return m_htmlText == o.m_htmlText &&
m_backgroundColor == o.m_backgroundColor &&
m_position == o.m_position &&
m_size == o.m_size;
}
QJsonObject PixelTextBoxData::toJson() const
{
QJsonObject obj;
obj[QStringLiteral("text")] = m_htmlText;
obj[QStringLiteral("backgroundColor")] = m_backgroundColor.name();
obj[QStringLiteral("position")] = QJsonObject({{QStringLiteral("x"), m_position.x()},
{QStringLiteral("y"), m_position.y()},
});
obj[QStringLiteral("size")] = QJsonObject({{QStringLiteral("width"), m_size.width()},
{QStringLiteral("height"), m_size.height()},
});
return obj;
}
bool get(const QJsonObject &obj, const QString &key, int &val)
{
const auto jVal = obj[key];
if (!jVal.isDouble())
{
qCritical() << " isDouble failed";
}
val = jVal.toInt();
return true;
}
PixelTextBoxData PixelTextBoxData::fromJson(const QJsonValue &json)
{
if (json.isUndefined())
return {};
if (!json.isObject())
return {};
PixelTextBoxData ret;
// text
ret.m_htmlText = json[QStringLiteral("text")].toString();
// backgroundColor
QString temp = json[QStringLiteral("backgroundColor")].toString();
ret.m_backgroundColor.setNamedColor(temp);
// position:
{
const auto jVal = json[QStringLiteral("position")];
get(jVal.toObject(), QStringLiteral("x"), ret.m_position.rx());
get(jVal.toObject(), QStringLiteral("y"), ret.m_position.ry());
}
// size:
{
const auto jVal = json[QStringLiteral("size")];
get(jVal.toObject(), QStringLiteral("width"), ret.m_size.rwidth());
get(jVal.toObject(), QStringLiteral("height"), ret.m_size.rheight());
}
return ret;
}
QString PixelTextBoxData::toJsonStr(QJsonDocument::JsonFormat format) const
{
QJsonObject obj = toJson();
QJsonDocument jDoc(obj);
return QString::fromStdString(jDoc.toJson(format).toStdString());
}
PixelTextBoxData PixelTextBoxData::fromJsonStr(const QString &jsonStr)
{
if (jsonStr.isEmpty())
return {};
QJsonParseError parseError;
QJsonDocument jDoc(QJsonDocument::fromJson(jsonStr.toStdString().c_str(), &parseError));
if (parseError.error != QJsonParseError::NoError)
{
qCritical() << " QJsonParseError->errorString: '" << parseError.errorString() << "'"
<< ", offset: " << parseError.offset;
return {};
}
QJsonObject jObj = jDoc.object();
if (jObj.isEmpty())
return {};
return PixelTextBoxData::fromJson(jObj);
}
//
// Container
//
QJsonObject PixelTextBoxData::pixelTextBoxContainerToJson(const QVector<PixelTextBoxData> &ptbdCont)
{
QJsonArray arr;
for (const PixelTextBoxData &item : qAsConst(ptbdCont))
arr.push_back(item.toJson());
QJsonObject jObj;
jObj[QStringLiteral("PixelTextBoxData")] = arr;
return jObj;
}
QVector<PixelTextBoxData> PixelTextBoxData::pixelTextBoxContainerFromJson(const QJsonValue &json)
{
QVector<PixelTextBoxData> ret;
if (!json.isObject())
return ret;
const QJsonObject jObj = json.toObject();
if (!jObj.contains(QStringLiteral("PixelTextBoxData")))
return ret;
const QJsonArray &array = jObj[QStringLiteral("PixelTextBoxData")].toArray();
ret.reserve(array.size());
for(int i = 0; i < array.size(); ++i)
ret.push_back(PixelTextBoxData::fromJson(array.at(i)));
return ret;
}
QString PixelTextBoxData::pixelTextBoxContainerToJsonStr(const QVector<PixelTextBoxData> &ptbdCont, QJsonDocument::JsonFormat format)
{
QJsonObject obj = pixelTextBoxContainerToJson(ptbdCont);
QJsonDocument jDoc(obj);
return QString::fromStdString(jDoc.toJson(format).toStdString());
}
QVector<PixelTextBoxData> PixelTextBoxData::pixelTextBoxContainerFromJsonStr(const QString &jsonStr)
{
if (jsonStr.isEmpty())
return {};
QJsonParseError parseError;
QJsonDocument jDoc(QJsonDocument::fromJson(jsonStr.toStdString().c_str(), &parseError));
if (parseError.error != QJsonParseError::NoError)
{
qCritical() << " QJsonParseError->errorString: '" << parseError.errorString() << "'"
<< ", offset: " << parseError.offset;
return {};
}
QJsonObject jObj = jDoc.object();
if (jObj.isEmpty())
return {};
return PixelTextBoxData::pixelTextBoxContainerFromJson(jObj);
}
//-----------------------------------------------------------------------------
// output operator:
//-----------------------------------------------------------------------------
GEOMETRYMODEL_EXPORT std::ostream &operator<<(std::ostream &stream, const PixelTextBoxData &value)
{
stream << value.toDebugString().toStdString().c_str();
return stream;
}
} // namespace SituationMap
@@ -0,0 +1,69 @@
/**
* @RDE_HEADER@
* PixelTextBoxData as Addon to GeometryModel
* $Id$
* $HeadURL$
* $Author$
* Created by Norbert Thoden, SLSE, 2023-04-27
*/
#pragma once
#include <QString>
#include <QColor>
#include <QPoint>
#include <QSize>
#include <QJsonObject>
#include <QJsonDocument>
#include "geometry_model_export.h"
namespace SituationMap
{
class GEOMETRYMODEL_EXPORT PixelTextBoxData
{
public:
PixelTextBoxData() = default;
explicit PixelTextBoxData(const QString &htmlText, const QColor &backgroundColor);
void reset();
bool isEmpty() const;
QString toDebugString() const;
QString m_htmlText;
QColor m_backgroundColor;
QPoint m_position;
QSize m_size;
// operator
bool operator==(const PixelTextBoxData &o) const;
// Json:
QJsonObject toJson() const;
static PixelTextBoxData fromJson(const QJsonValue &json);
QString toJsonStr(QJsonDocument::JsonFormat format = QJsonDocument::JsonFormat::Indented) const;
static PixelTextBoxData fromJsonStr(const QString &jsonStr);
static QJsonObject pixelTextBoxContainerToJson(const QVector<PixelTextBoxData> &ptbdCont);
static QVector<PixelTextBoxData> pixelTextBoxContainerFromJson(const QJsonValue &json);
static QString pixelTextBoxContainerToJsonStr(const QVector<PixelTextBoxData> &ptbdCont, QJsonDocument::JsonFormat format = QJsonDocument::JsonFormat::Indented);
static QVector<PixelTextBoxData> pixelTextBoxContainerFromJsonStr(const QString &jsonStr);
};
//-----------------------------------------------------------------------------
// output operator:
//-----------------------------------------------------------------------------
GEOMETRYMODEL_EXPORT std::ostream &operator<< (std::ostream &stream,
const PixelTextBoxData &value);
} // namespace SituationMap