1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 03:35:53 +01:00

Added support for "data defined" styles

This commit is contained in:
Martin Tůma 2022-09-23 02:34:18 +02:00
parent e8e1e98775
commit a8299050c5
27 changed files with 475 additions and 130 deletions

View File

@ -114,6 +114,7 @@ HEADERS += src/common/config.h \
src/GUI/pngexportdialog.h \ src/GUI/pngexportdialog.h \
src/GUI/timezoneinfo.h \ src/GUI/timezoneinfo.h \
src/GUI/passwordedit.h \ src/GUI/passwordedit.h \
src/data/style.h \
src/data/twonavparser.h \ src/data/twonavparser.h \
src/map/IMG/section.h \ src/map/IMG/section.h \
src/map/gemfmap.h \ src/map/gemfmap.h \

View File

@ -28,10 +28,17 @@ AreaItem::AreaItem(const Area &area, Map *map, GraphicsItem *parent)
_map = map; _map = map;
_digitalZoom = 0; _digitalZoom = 0;
_width = 2; if (_area.style().isValid()) {
_opacity = 0.5; _width = (_area.style().pen().style() == Qt::NoPen)
QBrush brush(Qt::SolidPattern); ? 0 : _area.style().pen().width();
_pen = QPen(brush, _width); _pen = _area.style().pen();
_brush = _area.style().brush();
} else {
_width = 2;
_opacity = 0.5;
QBrush brush(Qt::SolidPattern);
_pen = QPen(brush, _width);
}
updatePainterPath(); updatePainterPath();
@ -91,6 +98,8 @@ void AreaItem::setMap(Map *map)
void AreaItem::setColor(const QColor &color) void AreaItem::setColor(const QColor &color)
{ {
if (_area.style().isValid())
return;
if (_pen.color() == color) if (_pen.color() == color)
return; return;
@ -104,6 +113,8 @@ void AreaItem::setColor(const QColor &color)
void AreaItem::setOpacity(qreal opacity) void AreaItem::setOpacity(qreal opacity)
{ {
if (_area.style().isValid())
return;
if (_opacity == opacity) if (_opacity == opacity)
return; return;
@ -117,6 +128,8 @@ void AreaItem::setOpacity(qreal opacity)
void AreaItem::setWidth(qreal width) void AreaItem::setWidth(qreal width)
{ {
if (_area.style().isValid())
return;
if (_width == width) if (_width == width)
return; return;
@ -128,6 +141,8 @@ void AreaItem::setWidth(qreal width)
void AreaItem::setStyle(Qt::PenStyle style) void AreaItem::setStyle(Qt::PenStyle style)
{ {
if (_area.style().isValid())
return;
if (_pen.style() == style) if (_pen.style() == style)
return; return;

View File

@ -11,7 +11,8 @@ GraphItem::GraphItem(const Graph &graph, GraphType type, int width,
Q_ASSERT(_graph.isValid()); Q_ASSERT(_graph.isValid());
_units = Metric; _units = Metric;
_pen = QPen(color, width, style, Qt::FlatCap); _pen = QPen(graph.color().isValid() ? graph.color() : color, width, style,
Qt::FlatCap);
_sx = 0; _sy = 0; _sx = 0; _sy = 0;
_time = _graph.hasTime(); _time = _graph.hasTime();
setZValue(2.0); setZValue(2.0);
@ -54,6 +55,8 @@ void GraphItem::setGraphType(GraphType type)
void GraphItem::setColor(const QColor &color) void GraphItem::setColor(const QColor &color)
{ {
if (_graph.color().isValid())
return;
if (_pen.color() == color) if (_pen.color() == color)
return; return;

View File

@ -32,15 +32,16 @@ static inline unsigned segments(qreal distance)
Units PathItem::_units = Metric; Units PathItem::_units = Metric;
QTimeZone PathItem::_timeZone = QTimeZone::utc(); QTimeZone PathItem::_timeZone = QTimeZone::utc();
PathItem::PathItem(const Path &path, Map *map, QGraphicsItem *parent) PathItem::PathItem(const Path &path, const LineStyle &style, Map *map,
: GraphicsItem(parent), _path(path), _map(map), _graph(0) QGraphicsItem *parent) : GraphicsItem(parent), _path(path), _style(style),
_map(map), _graph(0)
{ {
Q_ASSERT(_path.isValid()); Q_ASSERT(_path.isValid());
_digitalZoom = 0; _digitalZoom = 0;
_width = 3; _width = (_style.width() >= 0) ? _style.width() : 3;
QBrush brush(Qt::SolidPattern); _pen = _style.color().isValid()
_pen = QPen(brush, _width); ? QPen(_style.color(), _width) : QPen(QBrush(Qt::SolidPattern), _width);
_showMarker = true; _showMarker = true;
_showTicks = false; _showTicks = false;
_markerInfoType = MarkerInfoItem::None; _markerInfoType = MarkerInfoItem::None;
@ -153,6 +154,8 @@ void PathItem::setMap(Map *map)
void PathItem::setColor(const QColor &color) void PathItem::setColor(const QColor &color)
{ {
if (_style.color().isValid())
return;
if (_pen.color() == color) if (_pen.color() == color)
return; return;
@ -166,6 +169,8 @@ void PathItem::setColor(const QColor &color)
void PathItem::setWidth(qreal width) void PathItem::setWidth(qreal width)
{ {
if (_style.color().isValid())
return;
if (_width == width) if (_width == width)
return; return;

View File

@ -5,6 +5,8 @@
#include <QPen> #include <QPen>
#include <QTimeZone> #include <QTimeZone>
#include "data/path.h" #include "data/path.h"
#include "data/link.h"
#include "data/style.h"
#include "graphicsscene.h" #include "graphicsscene.h"
#include "markerinfoitem.h" #include "markerinfoitem.h"
#include "units.h" #include "units.h"
@ -19,7 +21,8 @@ class PathItem : public QObject, public GraphicsItem
Q_OBJECT Q_OBJECT
public: public:
PathItem(const Path &path, Map *map, QGraphicsItem *parent = 0); PathItem(const Path &path, const LineStyle &style, Map *map,
QGraphicsItem *parent = 0);
virtual ~PathItem() {} virtual ~PathItem() {}
QPainterPath shape() const {return _shape;} QPainterPath shape() const {return _shape;}
@ -66,6 +69,11 @@ protected:
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
void mousePressEvent(QGraphicsSceneMouseEvent *event); void mousePressEvent(QGraphicsSceneMouseEvent *event);
QString _name;
QString _desc;
QString _comment;
QVector<Link> _links;
static Units _units; static Units _units;
static QTimeZone _timeZone; static QTimeZone _timeZone;
@ -81,6 +89,7 @@ private:
unsigned tickSize() const; unsigned tickSize() const;
Path _path; Path _path;
LineStyle _style;
Map *_map; Map *_map;
QList<GraphItem *> _graphs; QList<GraphItem *> _graphs;
GraphItem *_graph; GraphItem *_graph;

View File

@ -36,7 +36,7 @@ ToolTip RouteItem::info() const
} }
RouteItem::RouteItem(const Route &route, Map *map, QGraphicsItem *parent) RouteItem::RouteItem(const Route &route, Map *map, QGraphicsItem *parent)
: PathItem(route.path(), map, parent) : PathItem(route.path(), route.style(), map, parent)
{ {
const RouteData &waypoints = route.data(); const RouteData &waypoints = route.data();

View File

@ -1,7 +1,6 @@
#ifndef ROUTEITEM_H #ifndef ROUTEITEM_H
#define ROUTEITEM_H #define ROUTEITEM_H
#include "data/link.h"
#include "pathitem.h" #include "pathitem.h"
class Map; class Map;
@ -26,11 +25,6 @@ public:
QDateTime date() const {return QDateTime();} QDateTime date() const {return QDateTime();}
private: private:
QString _name;
QString _desc;
QString _comment;
QVector<Link> _links;
QVector<WaypointItem*> _waypoints; QVector<WaypointItem*> _waypoints;
}; };

View File

@ -41,7 +41,7 @@ ToolTip TrackItem::info() const
} }
TrackItem::TrackItem(const Track &track, Map *map, QGraphicsItem *parent) TrackItem::TrackItem(const Track &track, Map *map, QGraphicsItem *parent)
: PathItem(track.path(), map, parent) : PathItem(track.path(), track.style(), map, parent)
{ {
_name = track.name(); _name = track.name();
_desc = track.description(); _desc = track.description();

View File

@ -2,7 +2,6 @@
#define TRACKITEM_H #define TRACKITEM_H
#include <QDateTime> #include <QDateTime>
#include "data/link.h"
#include "pathitem.h" #include "pathitem.h"
class Map; class Map;
@ -19,10 +18,6 @@ public:
QDateTime date() const {return _date;} QDateTime date() const {return _date;}
private: private:
QString _name;
QString _desc;
QString _comment;
QVector<Link> _links;
QDateTime _date; QDateTime _date;
qreal _time; qreal _time;
qreal _movingTime; qreal _movingTime;

View File

@ -77,12 +77,14 @@ WaypointItem::WaypointItem(const Waypoint &waypoint, Map *map,
_waypoint = waypoint; _waypoint = waypoint;
_showLabel = true; _showLabel = true;
_showIcon = false; _showIcon = false;
_size = 8; _size = (_waypoint.style().size() >= 0)
_color = Qt::black; ? _waypoint.style().size() : 8;
_color = (_waypoint.style().color().isValid())
? _waypoint.style().color() : Qt::black;
_icon = (_waypoint.icon().isNull()) _icon = (_waypoint.style().icon().isNull())
? Waypoint::symbolIcon(_waypoint.symbol()) ? Waypoint::symbolIcon(_waypoint.symbol())
: &_waypoint.icon(); : &_waypoint.style().icon();
_font.setPixelSize(FS(_size)); _font.setPixelSize(FS(_size));
_font.setFamily(FONT_FAMILY); _font.setFamily(FONT_FAMILY);
@ -98,6 +100,7 @@ void WaypointItem::updateCache()
{ {
QPainterPath p; QPainterPath p;
qreal pointSize = _font.bold() ? HS(_size) : _size; qreal pointSize = _font.bold() ? HS(_size) : _size;
const QPixmap &icon = _waypoint.style().icon();
if (_showLabel && !_waypoint.name().isEmpty()) { if (_showLabel && !_waypoint.name().isEmpty()) {
QFontMetrics fm(_font); QFontMetrics fm(_font);
@ -105,15 +108,15 @@ void WaypointItem::updateCache()
if (_showIcon && _icon) { if (_showIcon && _icon) {
if (_font.bold()) if (_font.bold())
p.addRect(-_icon->width() * 0.625, _waypoint.icon().isNull() p.addRect(-_icon->width() * 0.625, icon.isNull()
? -_icon->height() * 1.25 : -_icon->height() * 0.625, ? -_icon->height() * 1.25 : -_icon->height() * 0.625,
_icon->width() * 1.25, _icon->height() * 1.25); _icon->width() * 1.25, _icon->height() * 1.25);
else else
p.addRect(-_icon->width()/2.0, _waypoint.icon().isNull() p.addRect(-_icon->width()/2.0, icon.isNull()
? -_icon->height() : -_icon->height()/2, _icon->width(), ? -_icon->height() : -_icon->height()/2, _icon->width(),
_icon->height()); _icon->height());
if (_waypoint.icon().isNull()) if (icon.isNull())
p.addRect(0, 0, _labelBB.width(), _labelBB.height() p.addRect(0, 0, _labelBB.width(), _labelBB.height()
+ fm.descent()); + fm.descent());
else else
@ -127,11 +130,11 @@ void WaypointItem::updateCache()
} else { } else {
if (_showIcon && _icon) { if (_showIcon && _icon) {
if (_font.bold()) if (_font.bold())
p.addRect(-_icon->width() * 0.625, _waypoint.icon().isNull() p.addRect(-_icon->width() * 0.625, icon.isNull()
? -_icon->height() * 1.25 : -_icon->height() * 0.625, ? -_icon->height() * 1.25 : -_icon->height() * 0.625,
_icon->width() * 1.25, _icon->height() * 1.25); _icon->width() * 1.25, _icon->height() * 1.25);
else else
p.addRect(-_icon->width()/2, _waypoint.icon().isNull() p.addRect(-_icon->width()/2, icon.isNull()
? -_icon->height() : -_icon->height()/2, _icon->width(), ? -_icon->height() : -_icon->height()/2, _icon->width(),
_icon->height()); _icon->height());
} else } else
@ -147,13 +150,14 @@ void WaypointItem::paint(QPainter *painter,
Q_UNUSED(option); Q_UNUSED(option);
Q_UNUSED(widget); Q_UNUSED(widget);
qreal pointSize = _font.bold() ? HS(_size) : _size; qreal pointSize = _font.bold() ? HS(_size) : _size;
const QPixmap &icon = _waypoint.style().icon();
painter->setPen(_color); painter->setPen(_color);
if (_showLabel && !_waypoint.name().isEmpty()) { if (_showLabel && !_waypoint.name().isEmpty()) {
painter->setFont(_font); painter->setFont(_font);
if (_showIcon && _icon) { if (_showIcon && _icon) {
if (_waypoint.icon().isNull()) if (icon.isNull())
painter->drawText(-qMax(_labelBB.x(), 0), _labelBB.height(), painter->drawText(-qMax(_labelBB.x(), 0), _labelBB.height(),
_waypoint.name()); _waypoint.name());
else else
@ -167,12 +171,12 @@ void WaypointItem::paint(QPainter *painter,
painter->setBrush(QBrush(_color, Qt::SolidPattern)); painter->setBrush(QBrush(_color, Qt::SolidPattern));
if (_showIcon && _icon) { if (_showIcon && _icon) {
if (_font.bold()) if (_font.bold())
painter->drawPixmap(-_icon->width() * 0.625, _waypoint.icon().isNull() painter->drawPixmap(-_icon->width() * 0.625, icon.isNull()
? -_icon->height() * 1.25 : -_icon->height() * 0.625, ? -_icon->height() * 1.25 : -_icon->height() * 0.625,
_icon->scaled(_icon->width() * 1.25, _icon->height() * 1.25, _icon->scaled(_icon->width() * 1.25, _icon->height() * 1.25,
Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
else else
painter->drawPixmap(-_icon->width()/2.0, _waypoint.icon().isNull() painter->drawPixmap(-_icon->width()/2.0, icon.isNull()
? -_icon->height() : -_icon->height()/2, *_icon); ? -_icon->height() : -_icon->height()/2, *_icon);
} else } else
painter->drawEllipse(-pointSize/2, -pointSize/2, pointSize, pointSize); painter->drawEllipse(-pointSize/2, -pointSize/2, pointSize, pointSize);
@ -184,6 +188,8 @@ void WaypointItem::paint(QPainter *painter,
void WaypointItem::setSize(int size) void WaypointItem::setSize(int size)
{ {
if (_waypoint.style().size() >= 0)
return;
if (_size == size) if (_size == size)
return; return;
@ -195,6 +201,8 @@ void WaypointItem::setSize(int size)
void WaypointItem::setColor(const QColor &color) void WaypointItem::setColor(const QColor &color)
{ {
if (_waypoint.style().color().isValid())
return;
if (_color == color) if (_color == color)
return; return;

View File

@ -4,6 +4,7 @@
#include <QString> #include <QString>
#include <QList> #include <QList>
#include "common/polygon.h" #include "common/polygon.h"
#include "style.h"
class Area class Area
{ {
@ -27,6 +28,7 @@ public:
const QString &description() const {return _desc;} const QString &description() const {return _desc;}
const QList<Polygon> &polygons() const {return _polygons;} const QList<Polygon> &polygons() const {return _polygons;}
const RectC &boundingRect() const {return _boundingRect;} const RectC &boundingRect() const {return _boundingRect;}
const PolygonStyle &style() const {return _style;}
bool isValid() const bool isValid() const
{ {
@ -47,11 +49,13 @@ public:
void setName(const QString &name) {_name = name;} void setName(const QString &name) {_name = name;}
void setDescription(const QString &desc) {_desc = desc;} void setDescription(const QString &desc) {_desc = desc;}
void setStyle(const PolygonStyle &style) {_style = style;}
private: private:
QList<Polygon> _polygons; QList<Polygon> _polygons;
QString _name; QString _name;
QString _desc; QString _desc;
PolygonStyle _style;
RectC _boundingRect; RectC _boundingRect;
}; };

View File

@ -2,6 +2,109 @@
#include <QJsonArray> #include <QJsonArray>
#include "geojsonparser.h" #include "geojsonparser.h"
#define MARKER_SIZE_MEDIUM 12
#define MARKER_SIZE_SMALL 8
#define MARKER_SIZE_LARGE 16
static int markerSize(const QString &str)
{
if (str == "small")
return MARKER_SIZE_SMALL;
else if (str == "medium")
return MARKER_SIZE_MEDIUM;
else if (str == "large")
return MARKER_SIZE_LARGE;
else
return -1;
}
static void setAreaProperties(Area &area, const QJsonValue &properties)
{
if (!properties.isObject())
return;
QJsonObject o(properties.toObject());
if (o["name"].isString())
area.setName(o["name"].toString());
if (o["title"].isString())
area.setName(o["title"].toString());
if (o["description"].isString())
area.setDescription(o["description"].toString());
QColor strokeColor(0x55, 0x55, 0x55);
QColor fillColor(0x55, 0x55, 0x55);
double strokeWidth = 2;
if (o["stroke"].isString())
strokeColor = QColor(o["stroke"].toString());
if (o["stroke-opacity"].isDouble())
strokeColor.setAlphaF(o["stroke-opacity"].toDouble());
if (o["stroke-width"].isDouble())
strokeWidth = o["stroke-width"].toDouble();
if (o["fill"].isString())
fillColor = QColor(o["fill"].toString());
if (o["fill-opacity"].isDouble())
fillColor.setAlphaF(o["fill-opacity"].toDouble());
else
fillColor.setAlphaF(0.6);
area.setStyle(PolygonStyle(QPen(strokeColor, strokeWidth),
QBrush(fillColor)));
}
static void setTrackProperties(TrackData &track, const QJsonValue &properties)
{
if (!properties.isObject())
return;
QJsonObject o(properties.toObject());
if (o["name"].isString())
track.setName(o["name"].toString());
if (o["title"].isString())
track.setName(o["title"].toString());
if (o["description"].isString())
track.setDescription(o["description"].toString());
QColor color(0x55, 0x55, 0x55);
double width = 2;
if (o["stroke"].isString())
color = QColor(o["stroke"].toString());
if (o["stroke-opacity"].isDouble())
color.setAlphaF(o["stroke-opacity"].toDouble());
if (o["stroke-width"].isDouble())
width = o["stroke-width"].toDouble();
track.setStyle(LineStyle(color, width));
}
static void setWaypointProperties(Waypoint &waypoint,
const QJsonValue &properties)
{
if (!properties.isObject())
return;
QJsonObject o(properties.toObject());
if (o["name"].isString())
waypoint.setName(o["name"].toString());
if (o["title"].isString())
waypoint.setName(o["title"].toString());
if (o["description"].isString())
waypoint.setDescription(o["description"].toString());
QColor color(0x7e, 0x7e, 0x7e);
int size = MARKER_SIZE_MEDIUM;
if (o["marker-color"].isString())
color = QColor(o["marker-color"].toString());
if (o["marker-symbol"].isString())
waypoint.setSymbol(o["marker-symbol"].toString());
if (o["marker-size"].isString())
size = markerSize(o["marker-size"].toString());
waypoint.setStyle(PointStyle(QPixmap(), color, size));
}
GeoJSONParser::Type GeoJSONParser::type(const QJsonObject &json) GeoJSONParser::Type GeoJSONParser::type(const QJsonObject &json)
{ {
@ -30,7 +133,7 @@ GeoJSONParser::Type GeoJSONParser::type(const QJsonObject &json)
} }
bool GeoJSONParser::point(const QJsonArray &coordinates, Waypoint &waypoint, bool GeoJSONParser::point(const QJsonArray &coordinates, Waypoint &waypoint,
const QJsonObject &properties) const QJsonValue &properties)
{ {
if (coordinates.count() < 2 || !coordinates.at(0).isDouble() if (coordinates.count() < 2 || !coordinates.at(0).isDouble()
|| !coordinates.at(1).isDouble()) { || !coordinates.at(1).isDouble()) {
@ -38,23 +141,18 @@ bool GeoJSONParser::point(const QJsonArray &coordinates, Waypoint &waypoint,
return false; return false;
} }
setWaypointProperties(waypoint, properties);
waypoint.setCoordinates(Coordinates(coordinates.at(0).toDouble(), waypoint.setCoordinates(Coordinates(coordinates.at(0).toDouble(),
coordinates.at(1).toDouble())); coordinates.at(1).toDouble()));
if (coordinates.count() == 3 && coordinates.at(2).isDouble()) if (coordinates.count() == 3 && coordinates.at(2).isDouble())
waypoint.setElevation(coordinates.at(2).toDouble()); waypoint.setElevation(coordinates.at(2).toDouble());
if (properties.contains("title") && properties["title"].isString())
waypoint.setName(properties["title"].toString());
if (properties.contains("name") && properties["name"].isString())
waypoint.setName(properties["name"].toString());
if (properties.contains("description")
&& properties["description"].isString())
waypoint.setDescription(properties["description"].toString());
return true; return true;
} }
bool GeoJSONParser::multiPoint(const QJsonArray &coordinates, bool GeoJSONParser::multiPoint(const QJsonArray &coordinates,
QVector<Waypoint> &waypoints, const QJsonObject &properties) QVector<Waypoint> &waypoints, const QJsonValue &properties)
{ {
for (int i = 0; i < coordinates.size(); i++) { for (int i = 0; i < coordinates.size(); i++) {
if (!coordinates.at(i).isArray()) { if (!coordinates.at(i).isArray()) {
@ -92,15 +190,9 @@ bool GeoJSONParser::lineString(const QJsonArray &coordinates,
} }
bool GeoJSONParser::lineString(const QJsonArray &coordinates, TrackData &track, bool GeoJSONParser::lineString(const QJsonArray &coordinates, TrackData &track,
const QJsonObject &properties) const QJsonValue &properties)
{ {
if (properties.contains("title") && properties["title"].isString()) setTrackProperties(track, properties);
track.setName(properties["title"].toString());
if (properties.contains("name") && properties["name"].isString())
track.setName(properties["name"].toString());
if (properties.contains("description")
&& properties["description"].isString())
track.setDescription(properties["description"].toString());
track.append(SegmentData()); track.append(SegmentData());
@ -110,15 +202,9 @@ bool GeoJSONParser::lineString(const QJsonArray &coordinates, TrackData &track,
} }
bool GeoJSONParser::multiLineString(const QJsonArray &coordinates, bool GeoJSONParser::multiLineString(const QJsonArray &coordinates,
TrackData &track, const QJsonObject &properties) TrackData &track, const QJsonValue &properties)
{ {
if (properties.contains("title") && properties["title"].isString()) setTrackProperties(track, properties);
track.setName(properties["title"].toString());
if (properties.contains("name") && properties["name"].isString())
track.setName(properties["name"].toString());
if (properties.contains("description")
&& properties["description"].isString())
track.setDescription(properties["description"].toString());
for (int i = 0; i < coordinates.size(); i++) { for (int i = 0; i < coordinates.size(); i++) {
if (!coordinates.at(i).isArray()) { if (!coordinates.at(i).isArray()) {
@ -163,15 +249,9 @@ bool GeoJSONParser::polygon(const QJsonArray &coordinates, ::Polygon &pg)
} }
bool GeoJSONParser::polygon(const QJsonArray &coordinates, Area &area, bool GeoJSONParser::polygon(const QJsonArray &coordinates, Area &area,
const QJsonObject &properties) const QJsonValue &properties)
{ {
if (properties.contains("title") && properties["title"].isString()) setAreaProperties(area, properties);
area.setName(properties["title"].toString());
if (properties.contains("name") && properties["name"].isString())
area.setName(properties["name"].toString());
if (properties.contains("description")
&& properties["description"].isString())
area.setDescription(properties["description"].toString());
::Polygon p; ::Polygon p;
if (!polygon(coordinates, p)) if (!polygon(coordinates, p))
@ -182,15 +262,9 @@ bool GeoJSONParser::polygon(const QJsonArray &coordinates, Area &area,
} }
bool GeoJSONParser::multiPolygon(const QJsonArray &coordinates, bool GeoJSONParser::multiPolygon(const QJsonArray &coordinates,
Area &area, const QJsonObject &properties) Area &area, const QJsonValue &properties)
{ {
if (properties.contains("title") && properties["title"].isString()) setAreaProperties(area, properties);
area.setName(properties["title"].toString());
if (properties.contains("name") && properties["name"].isString())
area.setName(properties["name"].toString());
if (properties.contains("description")
&& properties["description"].isString())
area.setDescription(properties["description"].toString());
for (int i = 0; i < coordinates.size(); i++) { for (int i = 0; i < coordinates.size(); i++) {
if (!coordinates.at(i).isArray()) { if (!coordinates.at(i).isArray()) {
@ -209,7 +283,7 @@ bool GeoJSONParser::multiPolygon(const QJsonArray &coordinates,
bool GeoJSONParser::geometryCollection(const QJsonObject &json, bool GeoJSONParser::geometryCollection(const QJsonObject &json,
QList<TrackData> &tracks, QList<Area> &areas, QList<TrackData> &tracks, QList<Area> &areas,
QVector<Waypoint> &waypoints, const QJsonObject &properties) QVector<Waypoint> &waypoints, const QJsonValue &properties)
{ {
if (!json.contains("geometries") || !json["geometries"].isArray()) { if (!json.contains("geometries") || !json["geometries"].isArray()) {
_errorString = "Invalid/missing GeometryCollection geometries array"; _errorString = "Invalid/missing GeometryCollection geometries array";
@ -273,7 +347,7 @@ bool GeoJSONParser::geometryCollection(const QJsonObject &json,
bool GeoJSONParser::feature(const QJsonObject &json, QList<TrackData> &tracks, bool GeoJSONParser::feature(const QJsonObject &json, QList<TrackData> &tracks,
QList<Area> &areas, QVector<Waypoint> &waypoints) QList<Area> &areas, QVector<Waypoint> &waypoints)
{ {
QJsonObject properties(json["properties"].toObject()); QJsonValue properties(json["properties"]);
QJsonObject geometry(json["geometry"].toObject()); QJsonObject geometry(json["geometry"].toObject());
switch (type(geometry)) { switch (type(geometry)) {

View File

@ -31,22 +31,22 @@ private:
Type type(const QJsonObject &json); Type type(const QJsonObject &json);
bool point(const QJsonArray &coordinates, Waypoint &waypoint, bool point(const QJsonArray &coordinates, Waypoint &waypoint,
const QJsonObject &properties = QJsonObject()); const QJsonValue &properties = QJsonValue());
bool multiPoint(const QJsonArray &coordinates, bool multiPoint(const QJsonArray &coordinates,
QVector<Waypoint> &waypoints, const QJsonObject &properties = QJsonObject()); QVector<Waypoint> &waypoints, const QJsonValue &properties = QJsonValue());
bool lineString(const QJsonArray &coordinates, SegmentData &segment); bool lineString(const QJsonArray &coordinates, SegmentData &segment);
bool lineString(const QJsonArray &coordinates, TrackData &track, bool lineString(const QJsonArray &coordinates, TrackData &track,
const QJsonObject &properties = QJsonObject()); const QJsonValue &properties = QJsonValue());
bool multiLineString(const QJsonArray &coordinates, bool multiLineString(const QJsonArray &coordinates,
TrackData &track, const QJsonObject &properties = QJsonObject()); TrackData &track, const QJsonValue &properties = QJsonValue());
bool polygon(const QJsonArray &coordinates, ::Polygon &pg); bool polygon(const QJsonArray &coordinates, ::Polygon &pg);
bool polygon(const QJsonArray &coordinates, Area &area, bool polygon(const QJsonArray &coordinates, Area &area,
const QJsonObject &properties = QJsonObject()); const QJsonValue &properties = QJsonValue());
bool multiPolygon(const QJsonArray &coordinates, Area &area, bool multiPolygon(const QJsonArray &coordinates, Area &area,
const QJsonObject &properties = QJsonObject()); const QJsonValue &properties = QJsonValue());
bool geometryCollection(const QJsonObject &json, QList<TrackData> &tracks, bool geometryCollection(const QJsonObject &json, QList<TrackData> &tracks,
QList<Area> &areas, QVector<Waypoint> &waypoints, QList<Area> &areas, QVector<Waypoint> &waypoints,
const QJsonObject &properties = QJsonObject()); const QJsonValue &properties = QJsonValue());
bool feature(const QJsonObject &json, QList<TrackData> &tracks, bool feature(const QJsonObject &json, QList<TrackData> &tracks,
QList<Area> &areas, QVector<Waypoint> &waypoints); QList<Area> &areas, QVector<Waypoint> &waypoints);
bool featureCollection(const QJsonObject &json, QList<TrackData> &tracks, bool featureCollection(const QJsonObject &json, QList<TrackData> &tracks,

View File

@ -695,7 +695,7 @@ static void readPOIDatabase(DataStream &stream, QVector<Waypoint> &waypoints,
for (int i = 0; i < il.size(); i++) { for (int i = 0; i < il.size(); i++) {
const QPair<int, quint16> &e = il.at(i); const QPair<int, quint16> &e = il.at(i);
if (e.second < icons.size()) if (e.second < icons.size())
waypoints[e.first].setIcon(icons.at(e.second)); waypoints[e.first].setStyle(icons.at(e.second));
} }
if (ds != rh.size) if (ds != rh.size)

View File

@ -228,6 +228,26 @@ void GPXParser::trackpoints(SegmentData &segment)
} }
} }
void GPXParser::routeExtension(RouteData &route)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("DisplayColor"))
route.setStyle(LineStyle(QColor(_reader.readElementText())));
else
_reader.skipCurrentElement();
}
}
void GPXParser::routeExtensions(RouteData &track)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("RouteExtension"))
routeExtension(track);
else
_reader.skipCurrentElement();
}
}
void GPXParser::routepoints(RouteData &route, QList<TrackData> &tracks) void GPXParser::routepoints(RouteData &route, QList<TrackData> &tracks)
{ {
TrackData autoRoute; TrackData autoRoute;
@ -253,6 +273,8 @@ void GPXParser::routepoints(RouteData &route, QList<TrackData> &tracks)
link10.setURL(_reader.readElementText()); link10.setURL(_reader.readElementText());
else if (_reader.name() == QLatin1String("urlname")) else if (_reader.name() == QLatin1String("urlname"))
link10.setText(_reader.readElementText()); link10.setText(_reader.readElementText());
else if (_reader.name() == QLatin1String("extensions"))
routeExtensions(route);
else else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }
@ -267,6 +289,26 @@ void GPXParser::routepoints(RouteData &route, QList<TrackData> &tracks)
} }
} }
void GPXParser::trackExtension(TrackData &track)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("DisplayColor"))
track.setStyle(LineStyle(QColor(_reader.readElementText())));
else
_reader.skipCurrentElement();
}
}
void GPXParser::trackExtensions(TrackData &track)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("TrackExtension"))
trackExtension(track);
else
_reader.skipCurrentElement();
}
}
void GPXParser::track(TrackData &track) void GPXParser::track(TrackData &track)
{ {
Link link10; Link link10;
@ -289,6 +331,8 @@ void GPXParser::track(TrackData &track)
link10.setURL(_reader.readElementText()); link10.setURL(_reader.readElementText());
else if (_reader.name() == QLatin1String("urlname")) else if (_reader.name() == QLatin1String("urlname"))
link10.setText(_reader.readElementText()); link10.setText(_reader.readElementText());
else if (_reader.name() == QLatin1String("extensions"))
trackExtensions(track);
else else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }

View File

@ -25,6 +25,10 @@ private:
void waypointExtensions(Waypoint &waypoint, SegmentData *autoRoute); void waypointExtensions(Waypoint &waypoint, SegmentData *autoRoute);
void area(Area &area); void area(Area &area);
void gpxExtensions(QList<Area> &areas); void gpxExtensions(QList<Area> &areas);
void trackExtensions(TrackData &track);
void trackExtension(TrackData &track);
void routeExtensions(RouteData &route);
void routeExtension(RouteData &route);
void trackpointData(Trackpoint &trackpoint); void trackpointData(Trackpoint &trackpoint);
void waypointData(Waypoint &waypoint, SegmentData *autoRoute = 0); void waypointData(Waypoint &waypoint, SegmentData *autoRoute = 0);
void address(Waypoint &waypoint); void address(Waypoint &waypoint);

View File

@ -65,6 +65,12 @@ public:
} }
return true; return true;
} }
const QColor &color() const {return _color;}
void setColor(const QColor &color) {_color = color;}
private:
QColor _color;
}; };
class GraphPair class GraphPair

View File

@ -525,10 +525,12 @@ void KMLParser::multiGeometry(QList<TrackData> &tracks, QList<Area> &areas,
} }
void KMLParser::photoOverlay(const Ctx &ctx, QVector<Waypoint> &waypoints, void KMLParser::photoOverlay(const Ctx &ctx, QVector<Waypoint> &waypoints,
QMap<QString, QPixmap> &icons) PointStyleMap &pointStyles)
{ {
QString img, id; QString img, id;
Waypoint w; Waypoint w;
QMap<QString, PolygonStyle> unused;
QMap<QString, LineStyle> unused2;
static QRegularExpression re("\\$\\[[^\\]]+\\]"); static QRegularExpression re("\\$\\[[^\\]]+\\]");
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
@ -543,10 +545,10 @@ void KMLParser::photoOverlay(const Ctx &ctx, QVector<Waypoint> &waypoints,
else if (_reader.name() == QLatin1String("TimeStamp")) else if (_reader.name() == QLatin1String("TimeStamp"))
w.setTimestamp(timeStamp()); w.setTimestamp(timeStamp());
else if (_reader.name() == QLatin1String("Style")) { else if (_reader.name() == QLatin1String("Style")) {
style(ctx.dir, icons); style(ctx.dir, pointStyles, unused, unused2);
id = QString(); id = QString();
} else if (_reader.name() == QLatin1String("StyleMap")) } else if (_reader.name() == QLatin1String("StyleMap"))
styleMap(icons); styleMap(pointStyles, unused, unused2);
else if (_reader.name() == QLatin1String("Icon")) else if (_reader.name() == QLatin1String("Icon"))
img = icon(); img = icon();
else if (_reader.name() == QLatin1String("Point")) else if (_reader.name() == QLatin1String("Point"))
@ -558,7 +560,7 @@ void KMLParser::photoOverlay(const Ctx &ctx, QVector<Waypoint> &waypoints,
} }
if (!w.coordinates().isNull()) { if (!w.coordinates().isNull()) {
w.setIcon(icons.value(id)); w.setStyle(pointStyles.value(id));
img.replace(re, "0"); img.replace(re, "0");
if (!QUrl(img).scheme().isEmpty()) if (!QUrl(img).scheme().isEmpty())
@ -579,8 +581,8 @@ void KMLParser::photoOverlay(const Ctx &ctx, QVector<Waypoint> &waypoints,
} }
void KMLParser::placemark(const Ctx &ctx, QList<TrackData> &tracks, void KMLParser::placemark(const Ctx &ctx, QList<TrackData> &tracks,
QList<Area> &areas, QVector<Waypoint> &waypoints, QList<Area> &areas, QVector<Waypoint> &waypoints, PointStyleMap &pointStyles,
QMap<QString, QPixmap> &icons) PolygonStyleMap &polyStyles, LineStyleMap &lineStyles)
{ {
QString name, desc, phone, address, id; QString name, desc, phone, address, id;
QDateTime timestamp; QDateTime timestamp;
@ -600,10 +602,10 @@ void KMLParser::placemark(const Ctx &ctx, QList<TrackData> &tracks,
else if (_reader.name() == QLatin1String("TimeStamp")) else if (_reader.name() == QLatin1String("TimeStamp"))
timestamp = timeStamp(); timestamp = timeStamp();
else if (_reader.name() == QLatin1String("Style")) { else if (_reader.name() == QLatin1String("Style")) {
style(ctx.dir, icons); style(ctx.dir, pointStyles, polyStyles, lineStyles);
id = QString(); id = QString();
} else if (_reader.name() == QLatin1String("StyleMap")) } else if (_reader.name() == QLatin1String("StyleMap"))
styleMap(icons); styleMap(pointStyles, polyStyles, lineStyles);
else if (_reader.name() == QLatin1String("MultiGeometry")) else if (_reader.name() == QLatin1String("MultiGeometry"))
multiGeometry(tracks, areas, waypoints, name, desc, timestamp); multiGeometry(tracks, areas, waypoints, name, desc, timestamp);
else if (_reader.name() == QLatin1String("Point")) { else if (_reader.name() == QLatin1String("Point")) {
@ -641,13 +643,15 @@ void KMLParser::placemark(const Ctx &ctx, QList<TrackData> &tracks,
wp->setTimestamp(timestamp); wp->setTimestamp(timestamp);
wp->setAddress(address); wp->setAddress(address);
wp->setPhone(phone); wp->setPhone(phone);
wp->setIcon(icons.value(id)); wp->setStyle(pointStyles.value(id));
} else if (tp) { } else if (tp) {
tp->setName(name); tp->setName(name);
tp->setDescription(desc); tp->setDescription(desc);
tp->setStyle(lineStyles.value(id));
} else if (ap) { } else if (ap) {
ap->setName(name); ap->setName(name);
ap->setDescription(desc); ap->setDescription(desc);
ap->setStyle(polyStyles.value(id));
} }
} }
@ -672,17 +676,66 @@ QString KMLParser::styleUrl()
} }
void KMLParser::iconStyle(const QDir &dir, const QString &id, void KMLParser::iconStyle(const QDir &dir, const QString &id,
QMap<QString, QPixmap> &icons) PointStyleMap &styles)
{ {
QPixmap img;
QColor color(Qt::white);
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("Icon")) if (_reader.name() == QLatin1String("Icon"))
icons.insert(id, QPixmap(dir.absoluteFilePath(icon()))); img = QPixmap(dir.absoluteFilePath(icon()));
else if (_reader.name() == QLatin1String("color"))
color = QColor("#" + _reader.readElementText());
else else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }
styles.insert(id, PointStyle(img, color));
} }
void KMLParser::styleMapPair(const QString &id, QMap<QString, QPixmap> &icons) void KMLParser::polyStyle(const QString &id, PolygonStyleMap &styles)
{
QColor color(Qt::white);
uint fill = 1, outline = 1;
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("color"))
color = QColor("#" + _reader.readElementText());
else if (_reader.name() == QLatin1String("fill"))
fill = _reader.readElementText().toUInt();
else if (_reader.name() == QLatin1String("outline"))
outline = _reader.readElementText().toUInt();
else
_reader.skipCurrentElement();
}
QPen pen = (color.isValid() && outline)
? QPen(color) : QPen(Qt::NoPen);
QBrush brush = (color.isValid() && fill)
? QBrush(color) : QBrush(Qt::NoBrush);
styles.insert(id, PolygonStyle(pen, brush));
}
void KMLParser::lineStyle(const QString &id, LineStyleMap &styles)
{
QColor color(Qt::white);
uint width = 1;
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("color"))
color = QColor("#" + _reader.readElementText());
else if (_reader.name() == QLatin1String("width"))
width = _reader.readElementText().toUInt();
else
_reader.skipCurrentElement();
}
styles.insert(id, LineStyle(color, width));
}
void KMLParser::styleMapPair(const QString &id, PointStyleMap &pointStyles,
PolygonStyleMap &polyStyles, LineStyleMap &lineStyles)
{ {
QString key, url; QString key, url;
@ -695,29 +748,38 @@ void KMLParser::styleMapPair(const QString &id, QMap<QString, QPixmap> &icons)
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }
if (key == "normal") if (key == "normal") {
icons.insert(id, icons.value(url)); pointStyles.insert(id, pointStyles.value(url));
polyStyles.insert(id, polyStyles.value(url));
lineStyles.insert(id, lineStyles.value(url));
}
} }
void KMLParser::styleMap(QMap<QString, QPixmap> &icons) void KMLParser::styleMap(PointStyleMap &pointStyles,
PolygonStyleMap &polyStyles, LineStyleMap &lineStyles)
{ {
QString id = _reader.attributes().value("id").toString(); QString id = _reader.attributes().value("id").toString();
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("Pair")) if (_reader.name() == QLatin1String("Pair"))
styleMapPair(id, icons); styleMapPair(id, pointStyles, polyStyles, lineStyles);
else else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }
} }
void KMLParser::style(const QDir &dir, QMap<QString, QPixmap> &icons) void KMLParser::style(const QDir &dir, PointStyleMap &pointStyles,
PolygonStyleMap &polyStyles, LineStyleMap &lineStyles)
{ {
QString id = _reader.attributes().value("id").toString(); QString id = _reader.attributes().value("id").toString();
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("IconStyle")) if (_reader.name() == QLatin1String("IconStyle"))
iconStyle(dir, id, icons); iconStyle(dir, id, pointStyles);
else if (_reader.name() == QLatin1String("PolyStyle"))
polyStyle(id, polyStyles);
else if (_reader.name() == QLatin1String("LineStyle"))
lineStyle(id, lineStyles);
else else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }
@ -725,17 +787,20 @@ void KMLParser::style(const QDir &dir, QMap<QString, QPixmap> &icons)
void KMLParser::folder(const Ctx &ctx, QList<TrackData> &tracks, void KMLParser::folder(const Ctx &ctx, QList<TrackData> &tracks,
QList<Area> &areas, QVector<Waypoint> &waypoints, QList<Area> &areas, QVector<Waypoint> &waypoints,
QMap<QString, QPixmap> &icons) PointStyleMap &pointStyles, PolygonStyleMap &polyStyles,
LineStyleMap &lineStyles)
{ {
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("Document")) if (_reader.name() == QLatin1String("Document"))
document(ctx, tracks, areas, waypoints); document(ctx, tracks, areas, waypoints);
else if (_reader.name() == QLatin1String("Folder")) else if (_reader.name() == QLatin1String("Folder"))
folder(ctx, tracks, areas, waypoints, icons); folder(ctx, tracks, areas, waypoints, pointStyles, polyStyles,
lineStyles);
else if (_reader.name() == QLatin1String("Placemark")) else if (_reader.name() == QLatin1String("Placemark"))
placemark(ctx, tracks, areas, waypoints, icons); placemark(ctx, tracks, areas, waypoints, pointStyles, polyStyles,
lineStyles);
else if (_reader.name() == QLatin1String("PhotoOverlay")) else if (_reader.name() == QLatin1String("PhotoOverlay"))
photoOverlay(ctx, waypoints, icons); photoOverlay(ctx, waypoints, pointStyles);
else else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }
@ -744,21 +809,25 @@ void KMLParser::folder(const Ctx &ctx, QList<TrackData> &tracks,
void KMLParser::document(const Ctx &ctx, QList<TrackData> &tracks, void KMLParser::document(const Ctx &ctx, QList<TrackData> &tracks,
QList<Area> &areas, QVector<Waypoint> &waypoints) QList<Area> &areas, QVector<Waypoint> &waypoints)
{ {
QMap<QString, QPixmap> icons; PointStyleMap pointStyles;
PolygonStyleMap polyStyles;
LineStyleMap lineStyles;
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("Document")) if (_reader.name() == QLatin1String("Document"))
document(ctx, tracks, areas, waypoints); document(ctx, tracks, areas, waypoints);
else if (_reader.name() == QLatin1String("Folder")) else if (_reader.name() == QLatin1String("Folder"))
folder(ctx, tracks, areas, waypoints, icons); folder(ctx, tracks, areas, waypoints, pointStyles, polyStyles,
lineStyles);
else if (_reader.name() == QLatin1String("Placemark")) else if (_reader.name() == QLatin1String("Placemark"))
placemark(ctx, tracks, areas, waypoints, icons); placemark(ctx, tracks, areas, waypoints, pointStyles, polyStyles,
lineStyles);
else if (_reader.name() == QLatin1String("PhotoOverlay")) else if (_reader.name() == QLatin1String("PhotoOverlay"))
photoOverlay(ctx, waypoints, icons); photoOverlay(ctx, waypoints, pointStyles);
else if (_reader.name() == QLatin1String("Style")) else if (_reader.name() == QLatin1String("Style"))
style(ctx.dir, icons); style(ctx.dir, pointStyles, polyStyles, lineStyles);
else if (_reader.name() == QLatin1String("StyleMap")) else if (_reader.name() == QLatin1String("StyleMap"))
styleMap(icons); styleMap(pointStyles, polyStyles, lineStyles);
else else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }
@ -767,17 +836,21 @@ void KMLParser::document(const Ctx &ctx, QList<TrackData> &tracks,
void KMLParser::kml(const Ctx &ctx, QList<TrackData> &tracks, void KMLParser::kml(const Ctx &ctx, QList<TrackData> &tracks,
QList<Area> &areas, QVector<Waypoint> &waypoints) QList<Area> &areas, QVector<Waypoint> &waypoints)
{ {
QMap<QString, QPixmap> icons; PointStyleMap pointStyles;
PolygonStyleMap polyStyles;
LineStyleMap lineStyles;
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("Document")) if (_reader.name() == QLatin1String("Document"))
document(ctx, tracks, areas, waypoints); document(ctx, tracks, areas, waypoints);
else if (_reader.name() == QLatin1String("Folder")) else if (_reader.name() == QLatin1String("Folder"))
folder(ctx, tracks, areas, waypoints, icons); folder(ctx, tracks, areas, waypoints, pointStyles, polyStyles,
lineStyles);
else if (_reader.name() == QLatin1String("Placemark")) else if (_reader.name() == QLatin1String("Placemark"))
placemark(ctx, tracks, areas, waypoints, icons); placemark(ctx, tracks, areas, waypoints, pointStyles, polyStyles,
lineStyles);
else if (_reader.name() == QLatin1String("PhotoOverlay")) else if (_reader.name() == QLatin1String("PhotoOverlay"))
photoOverlay(ctx, waypoints, icons); photoOverlay(ctx, waypoints, pointStyles);
else else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }

View File

@ -24,19 +24,25 @@ private:
bool zip; bool zip;
}; };
typedef QMap<QString, PointStyle> PointStyleMap;
typedef QMap<QString, PolygonStyle> PolygonStyleMap;
typedef QMap<QString, LineStyle> LineStyleMap;
void kml(const Ctx &ctx, QList<TrackData> &tracks, QList<Area> &areas, void kml(const Ctx &ctx, QList<TrackData> &tracks, QList<Area> &areas,
QVector<Waypoint> &waypoints); QVector<Waypoint> &waypoints);
void document(const Ctx &ctx, QList<TrackData> &tracks, QList<Area> &areas, void document(const Ctx &ctx, QList<TrackData> &tracks, QList<Area> &areas,
QVector<Waypoint> &waypoints); QVector<Waypoint> &waypoints);
void folder(const Ctx &ctx, QList<TrackData> &tracks, QList<Area> &areas, void folder(const Ctx &ctx, QList<TrackData> &tracks, QList<Area> &areas,
QVector<Waypoint> &waypoints, QMap<QString, QPixmap> &icons); QVector<Waypoint> &waypoints, PointStyleMap &pointStyles,
PolygonStyleMap &polyStyles, LineStyleMap &lineStyles);
void placemark(const Ctx &ctx, QList<TrackData> &tracks, QList<Area> &areas, void placemark(const Ctx &ctx, QList<TrackData> &tracks, QList<Area> &areas,
QVector<Waypoint> &waypoints, QMap<QString, QPixmap> &icons); QVector<Waypoint> &waypoints, PointStyleMap &pointStyles,
PolygonStyleMap &polyStyles, LineStyleMap &lineStyles);
void multiGeometry(QList<TrackData> &tracks, QList<Area> &areas, void multiGeometry(QList<TrackData> &tracks, QList<Area> &areas,
QVector<Waypoint> &waypoints, const QString &name, const QString &desc, QVector<Waypoint> &waypoints, const QString &name, const QString &desc,
const QDateTime &timestamp); const QDateTime &timestamp);
void photoOverlay(const Ctx &ctx, QVector<Waypoint> &waypoints, void photoOverlay(const Ctx &ctx, QVector<Waypoint> &waypoints,
QMap<QString, QPixmap> &icons); PointStyleMap &pointStyles);
void track(SegmentData &segment); void track(SegmentData &segment);
void multiTrack(TrackData &t); void multiTrack(TrackData &t);
void lineString(SegmentData &segment); void lineString(SegmentData &segment);
@ -59,11 +65,15 @@ private:
QDateTime time(); QDateTime time();
QString icon(); QString icon();
QString styleUrl(); QString styleUrl();
void style(const QDir &dir, QMap<QString, QPixmap> &icons); void style(const QDir &dir, PointStyleMap &pointStyles,
void styleMapPair(const QString &id, QMap<QString, QPixmap> &icons); PolygonStyleMap &polyStyles, LineStyleMap &lineStyles);
void styleMap(QMap<QString, QPixmap> &icons); void styleMapPair(const QString &id, PointStyleMap &pointStyles,
void iconStyle(const QDir &dir, const QString &id, PolygonStyleMap &polyStyles, LineStyleMap &lineStyles);
QMap<QString, QPixmap> &icons); void styleMap(PointStyleMap &pointStyles, PolygonStyleMap &polyStyles,
LineStyleMap &lineStyles);
void iconStyle(const QDir &dir, const QString &id, PointStyleMap &style);
void polyStyle(const QString &id, PolygonStyleMap &styles);
void lineStyle(const QString &id, LineStyleMap &styles);
QXmlStreamReader _reader; QXmlStreamReader _reader;
}; };

View File

@ -38,6 +38,9 @@ Graph Route::gpsElevation() const
if (_data.at(i).hasElevation()) if (_data.at(i).hasElevation())
gs.append(GraphPoint(_distance.at(i), NAN, _data.at(i).elevation())); gs.append(GraphPoint(_distance.at(i), NAN, _data.at(i).elevation()));
if (_data.style().color().isValid())
graph.setColor(_data.style().color());
return graph; return graph;
} }
@ -53,6 +56,9 @@ Graph Route::demElevation() const
gs.append(GraphPoint(_distance.at(i), NAN, dem)); gs.append(GraphPoint(_distance.at(i), NAN, dem));
} }
if (_data.style().color().isValid())
graph.setColor(_data.style().color());
return graph; return graph;
} }

View File

@ -20,6 +20,7 @@ public:
const QString &description() const {return _data.description();} const QString &description() const {return _data.description();}
const QString &comment() const {return _data.comment();} const QString &comment() const {return _data.comment();}
const QVector<Link> &links() const {return _data.links();} const QVector<Link> &links() const {return _data.links();}
const LineStyle &style() const {return _data.style();}
bool isValid() const {return _data.size() >= 2;} bool isValid() const {return _data.size() >= 2;}

View File

@ -5,6 +5,7 @@
#include <QString> #include <QString>
#include "waypoint.h" #include "waypoint.h"
#include "link.h" #include "link.h"
#include "style.h"
class RouteData : public QVector<Waypoint> class RouteData : public QVector<Waypoint>
{ {
@ -13,17 +14,20 @@ public:
const QString &description() const {return _desc;} const QString &description() const {return _desc;}
const QString &comment() const {return _comment;} const QString &comment() const {return _comment;}
const QVector<Link> &links() const {return _links;} const QVector<Link> &links() const {return _links;}
const LineStyle &style() const {return _style;}
void setName(const QString &name) {_name = name;} void setName(const QString &name) {_name = name;}
void setDescription(const QString &desc) {_desc = desc;} void setDescription(const QString &desc) {_desc = desc;}
void setComment(const QString &comment) {_comment = comment;} void setComment(const QString &comment) {_comment = comment;}
void addLink(const Link &link) {_links.append(link);} void addLink(const Link &link) {_links.append(link);}
void setStyle(const LineStyle &style) {_style = style;}
private: private:
QString _name; QString _name;
QString _desc; QString _desc;
QString _comment; QString _comment;
QVector<Link> _links; QVector<Link> _links;
LineStyle _style;
}; };
#endif // ROUTEDATA_H #endif // ROUTEDATA_H

56
src/data/style.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef STYLE_H
#define STYLE_H
#include <QPen>
#include <QBrush>
#include <QPixmap>
class PointStyle {
public:
PointStyle() : _size(-1) {}
PointStyle(const QPixmap &icon, const QColor &color = QColor(), int size = -1)
: _icon(icon), _color(color), _size(size) {}
const QColor &color() const {return _color;}
const QPixmap &icon() const {return _icon;}
int size() const {return _size;}
private:
QPixmap _icon;
QColor _color;
int _size;
};
class PolygonStyle {
public:
PolygonStyle()
: _pen(QPen(Qt::NoPen)), _brush(QBrush(Qt::NoBrush)) {}
PolygonStyle(const QPen &pen, const QBrush &brush)
: _pen(pen), _brush(brush) {}
const QPen &pen() const {return _pen;}
const QBrush &brush() const {return _brush;}
bool isValid() const
{return _pen.style() != Qt::NoPen || _brush.style() != Qt::NoBrush;}
private:
QPen _pen;
QBrush _brush;
};
class LineStyle {
public:
LineStyle() : _width(-1) {}
LineStyle(const QColor &color, int width = -1)
: _color(color), _width(width) {}
const QColor &color() const {return _color;}
int width() const {return _width;}
private:
QColor _color;
int _width;
};
#endif // STYLE_H

View File

@ -254,6 +254,9 @@ Graph Track::gpsElevation() const
ret.append(filter(gs, _elevationWindow)); ret.append(filter(gs, _elevationWindow));
} }
if (_data.style().color().isValid())
ret.setColor(_data.style().color());
return ret; return ret;
} }
@ -278,6 +281,9 @@ Graph Track::demElevation() const
ret.append(filter(gs, _elevationWindow)); ret.append(filter(gs, _elevationWindow));
} }
if (_data.style().color().isValid())
ret.setColor(_data.style().color());
return ret; return ret;
} }
@ -330,6 +336,9 @@ Graph Track::computedSpeed() const
filtered[stop.at(j)].setY(0); filtered[stop.at(j)].setY(0);
} }
if (_data.style().color().isValid())
ret.setColor(_data.style().color());
return ret; return ret;
} }
@ -365,6 +374,9 @@ Graph Track::reportedSpeed() const
filtered[stop.at(j)].setY(0); filtered[stop.at(j)].setY(0);
} }
if (_data.style().color().isValid())
ret.setColor(_data.style().color());
return ret; return ret;
} }
@ -406,6 +418,9 @@ Graph Track::heartRate() const
ret.append(filter(gs, _heartRateWindow)); ret.append(filter(gs, _heartRateWindow));
} }
if (_data.style().color().isValid())
ret.setColor(_data.style().color());
return ret; return ret;
} }
@ -429,6 +444,9 @@ Graph Track::temperature() const
ret.append(gs); ret.append(gs);
} }
if (_data.style().color().isValid())
ret.setColor(_data.style().color());
return ret; return ret;
} }
@ -451,6 +469,9 @@ Graph Track::ratio() const
ret.append(gs); ret.append(gs);
} }
if (_data.style().color().isValid())
ret.setColor(_data.style().color());
return ret; return ret;
} }
@ -486,6 +507,9 @@ Graph Track::cadence() const
filtered[stop.at(j)].setY(0); filtered[stop.at(j)].setY(0);
} }
if (_data.style().color().isValid())
ret.setColor(_data.style().color());
return ret; return ret;
} }
@ -522,6 +546,9 @@ Graph Track::power() const
filtered[stop.at(j)].setY(0); filtered[stop.at(j)].setY(0);
} }
if (_data.style().color().isValid())
ret.setColor(_data.style().color());
return ret; return ret;
} }

View File

@ -34,6 +34,7 @@ public:
const QString &description() const {return _data.description();} const QString &description() const {return _data.description();}
const QString &comment() const {return _data.comment();} const QString &comment() const {return _data.comment();}
const QVector<Link> &links() const {return _data.links();} const QVector<Link> &links() const {return _data.links();}
const LineStyle &style() const {return _data.style();}
bool isValid() const; bool isValid() const;

View File

@ -6,6 +6,7 @@
#include <QString> #include <QString>
#include "trackpoint.h" #include "trackpoint.h"
#include "link.h" #include "link.h"
#include "style.h"
typedef QVector<Trackpoint> SegmentData; typedef QVector<Trackpoint> SegmentData;
@ -16,17 +17,20 @@ public:
const QString &description() const {return _desc;} const QString &description() const {return _desc;}
const QString &comment() const {return _comment;} const QString &comment() const {return _comment;}
const QVector<Link> &links() const {return _links;} const QVector<Link> &links() const {return _links;}
const LineStyle &style() const {return _style;}
void setName(const QString &name) {_name = name;} void setName(const QString &name) {_name = name;}
void setDescription(const QString &desc) {_desc = desc;} void setDescription(const QString &desc) {_desc = desc;}
void setComment(const QString &comment) {_comment = comment;} void setComment(const QString &comment) {_comment = comment;}
void addLink(const Link &link) {_links.append(link);} void addLink(const Link &link) {_links.append(link);}
void setStyle(const LineStyle &style) {_style = style;}
private: private:
QString _name; QString _name;
QString _desc; QString _desc;
QString _comment; QString _comment;
QVector<Link> _links; QVector<Link> _links;
LineStyle _style;
}; };
#endif // TRACKDATA_H #endif // TRACKDATA_H

View File

@ -10,6 +10,7 @@
#include "common/config.h" #include "common/config.h"
#include "common/coordinates.h" #include "common/coordinates.h"
#include "link.h" #include "link.h"
#include "style.h"
class Waypoint class Waypoint
{ {
@ -30,7 +31,7 @@ public:
const QVector<Link> &links() const {return _links;} const QVector<Link> &links() const {return _links;}
const QDateTime &timestamp() const {return _timestamp;} const QDateTime &timestamp() const {return _timestamp;}
qreal elevation() const {return _elevation;} qreal elevation() const {return _elevation;}
const QPixmap &icon() const {return _icon;} const PointStyle &style() const {return _style;}
QPair<qreal, qreal> elevations() const; QPair<qreal, qreal> elevations() const;
@ -47,7 +48,7 @@ public:
void setElevation(qreal elevation) {_elevation = elevation;} void setElevation(qreal elevation) {_elevation = elevation;}
void addImage(const QString &path) {_images.append(path);} void addImage(const QString &path) {_images.append(path);}
void addLink(const Link &link) {_links.append(link);} void addLink(const Link &link) {_links.append(link);}
void setIcon(const QPixmap &icon) {_icon = icon;} void setStyle(const PointStyle &style) {_style = style;}
bool hasElevation() const {return !std::isnan(_elevation);} bool hasElevation() const {return !std::isnan(_elevation);}
@ -74,7 +75,7 @@ private:
QVector<Link> _links; QVector<Link> _links;
QDateTime _timestamp; QDateTime _timestamp;
qreal _elevation; qreal _elevation;
QPixmap _icon; PointStyle _style;
static bool _useDEM; static bool _useDEM;
static bool _show2ndElevation; static bool _show2ndElevation;