1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-07-23 23:24:24 +02:00

Compare commits

...

6 Commits

Author SHA1 Message Date
a8299050c5 Added support for "data defined" styles 2022-09-23 02:35:09 +02:00
e8e1e98775 Version++ 2022-09-14 22:31:53 +02:00
6768647070 Fixed broken zoom 0 on HiDPI displays 2022-09-14 00:21:50 +02:00
de63009edd Enabled Catalan localization 2022-09-06 09:31:27 +02:00
raf
125f99e8f4 Translated using Weblate (Catalan)
Currently translated at 100.0% (464 of 464 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ca/
2022-09-06 00:36:06 +02:00
raf
092929a967 Translated using Weblate (Catalan)
Currently translated at 63.3% (294 of 464 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ca/
2022-09-02 23:20:28 +02:00
31 changed files with 955 additions and 607 deletions

View File

@ -1,4 +1,4 @@
version: 11.4.{build} version: 11.5.{build}
configuration: configuration:
- Release - Release

View File

@ -3,7 +3,7 @@ unix:!macx:!android {
} else { } else {
TARGET = GPXSee TARGET = GPXSee
} }
VERSION = 11.4 VERSION = 11.5
QT += core \ QT += core \
gui \ gui \
@ -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 \
@ -457,7 +458,8 @@ TRANSLATIONS = lang/gpxsee_en.ts \
lang/gpxsee_hu.ts \ lang/gpxsee_hu.ts \
lang/gpxsee_it.ts \ lang/gpxsee_it.ts \
lang/gpxsee_eo.ts \ lang/gpxsee_eo.ts \
lang/gpxsee_zh.ts lang/gpxsee_zh.ts \
lang/gpxsee_ca.ts
macx { macx {
ICON = icons/app/gpxsee.icns ICON = icons/app/gpxsee.icns

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@ Unicode true
; The name of the installer ; The name of the installer
Name "GPXSee" Name "GPXSee"
; Program version ; Program version
!define VERSION "11.4" !define VERSION "11.5"
; The file to write ; The file to write
OutFile "GPXSee-${VERSION}_x64.exe" OutFile "GPXSee-${VERSION}_x64.exe"
@ -313,6 +313,7 @@ SectionEnd
!endif !endif
SectionGroup "Localization" SEC_LOCALIZATION SectionGroup "Localization" SEC_LOCALIZATION
!insertmacro LOCALIZATION "Catalan" "ca"
!insertmacro LOCALIZATION "Chinese (Simplified)" "zh" !insertmacro LOCALIZATION "Chinese (Simplified)" "zh"
!insertmacro LOCALIZATION "Czech" "cs" !insertmacro LOCALIZATION "Czech" "cs"
!insertmacro LOCALIZATION "Danish" "da" !insertmacro LOCALIZATION "Danish" "da"

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;

View File

@ -98,15 +98,17 @@ qreal OnlineMap::tileSize() const
void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags) void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
{ {
qreal scale = OSM::zoom2scale(_zoom, _tileSize); qreal scale = OSM::zoom2scale(_zoom, _tileSize);
QRectF b(bounds());
QPoint tile = OSM::mercator2tile(QPointF(rect.topLeft().x() * scale, QPoint tile = OSM::mercator2tile(QPointF(rect.topLeft().x() * scale,
-rect.topLeft().y() * scale) * coordinatesRatio(), _zoom); -rect.topLeft().y() * scale) * coordinatesRatio(), _zoom);
QPointF tl(floor(rect.left() / tileSize()) QPointF tl(floor(rect.left() / tileSize())
* tileSize(), floor(rect.top() / tileSize()) * tileSize()); * tileSize(), floor(rect.top() / tileSize()) * tileSize());
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y()); QSizeF s(qMin(rect.right() - tl.x(), b.width()),
int width = _zoom ? qCeil(s.width() / tileSize()) : 1; qMin(rect.bottom() - tl.y(), b.height()));
int height = _zoom ? qCeil(s.height() / tileSize()) : 1; int width = ceil(s.width() / tileSize());
int height = ceil(s.height() / tileSize());
QVector<FetchTile> tiles; QVector<FetchTile> tiles;
tiles.reserve(width * height); tiles.reserve(width * height);
@ -122,10 +124,9 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
for (int i = 0; i < tiles.count(); i++) { for (int i = 0; i < tiles.count(); i++) {
FetchTile &t = tiles[i]; FetchTile &t = tiles[i];
QPointF tp = _zoom ? QPointF(tl.x() + (t.xy().x() - tile.x()) QPointF tp(qMax(tl.x(), b.left()) + (t.xy().x() - tile.x()) * tileSize(),
* tileSize(), tl.y() + ((_invertY ? (1<<_zoom) - t.xy().y() - 1 : qMax(tl.y(), b.top()) + ((_invertY ? (1<<_zoom) - t.xy().y() - 1 :
t.xy().y()) - tile.y()) * tileSize()) t.xy().y()) - tile.y()) * tileSize());
: QPointF(-_tileSize/2, -_tileSize/2);
if (!t.pixmap().isNull()) { if (!t.pixmap().isNull()) {
t.pixmap().setDevicePixelRatio(imageRatio()); t.pixmap().setDevicePixelRatio(imageRatio());