1 /**********************************************************************************************
2     Copyright (C) 2014 Oliver Eichler <oliver.eichler@gmx.de>
3 
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation, either version 3 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 
17 **********************************************************************************************/
18 
19 #include "gis/db/CDBProject.h"
20 #include "gis/ovl/CGisItemOvlArea.h"
21 #include "gis/rte/CGisItemRte.h"
22 #include "gis/trk/CGisItemTrk.h"
23 #include "gis/wpt/CGisItemWpt.h"
24 #include "helpers/CWptIconManager.h"
25 
26 #include "qlgt/CQlgtDiary.h"
27 #include "qlgt/CQlgtFolder.h"
28 #include "qlgt/CQlgtRoute.h"
29 #include "qlgt/CQlgtTrack.h"
30 #include "qlgt/CQlgtWpt.h"
31 #include "qlgt/IQlgtOverlay.h"
32 #include "units/IUnit.h"
33 
readFloat(float val)34 inline qreal readFloat(float val)
35 {
36     return val > NOFLOAT ? NOFLOAT : val;
37 }
38 
CDBProject(CQlgtFolder & folder)39 CDBProject::CDBProject(CQlgtFolder& folder)
40     : IGisProject(eTypeDb, "", (CGisListWks*) nullptr)
41 {
42     metadata.name = folder.name;
43     if(folder.diary)
44     {
45         metadata.desc = folder.diary->comment;
46     }
47 }
48 
CGisItemWpt(const CQlgtWpt & wpt1,IGisProject * project)49 CGisItemWpt::CGisItemWpt(const CQlgtWpt& wpt1, IGisProject* project)
50     : IGisItem(project, eTypeWpt, NOIDX)
51 {
52     qreal direction;
53     QDateTime time = QDateTime::fromTime_t(wpt1.timestamp, QTimeZone("UTC"));
54 
55     wpt.time = time.toUTC();
56     wpt.name = wpt1.name;
57     wpt.cmt = wpt1.comment;
58     wpt.desc = wpt1.description;
59     wpt.sym = wpt1.iconString;
60 
61     wpt.lat = readFloat(wpt1.lat);
62     wpt.lon = readFloat(wpt1.lon);
63     wpt.ele = wpt1.ele == WPT_NOFLOAT ? NOINT : qRound(wpt1.ele);
64     proximity = readFloat(wpt1.prx);
65     direction = readFloat(wpt1.dir);
66     if(!wpt1.link.isEmpty())
67     {
68         IGisItem::link_t link;
69         link.uri = wpt1.link;
70         wpt.links << link;
71     }
72     if(!wpt1.urlname.isEmpty())
73     {
74         IGisItem::link_t link;
75         link.uri = wpt1.urlname;
76         wpt.links << link;
77     }
78     wpt.type = wpt1.type;
79 
80     if(wpt1.geocache.hasData)
81     {
82         geocache.service = CGisItemWpt::geocacheservice_e(wpt1.geocache.service);
83         geocache.hasData = wpt1.geocache.hasData;
84         geocache.id = wpt1.geocache.id;
85         geocache.available = wpt1.geocache.available;
86         geocache.archived = wpt1.geocache.archived;
87         geocache.difficulty = wpt1.geocache.difficulty;
88         geocache.terrain = wpt1.geocache.terrain;
89         //geocache.status     = wpt1.geocache.status; removed with geocache_t version 2
90         geocache.name = wpt1.geocache.name;
91         geocache.owner = wpt1.geocache.owner;
92         geocache.ownerId = wpt1.geocache.ownerId;
93         geocache.type = wpt1.geocache.type;
94         geocache.container = wpt1.geocache.container;
95         geocache.shortDescIsHtml = wpt1.geocache.shortDesc.contains("</");
96         geocache.shortDesc = wpt1.geocache.shortDesc;
97         geocache.longDescIsHtml = wpt1.geocache.longDesc.contains("</");
98         geocache.longDesc = wpt1.geocache.longDesc;
99         geocache.hint = wpt1.geocache.hint;
100         geocache.country = wpt1.geocache.country;
101         geocache.state = wpt1.geocache.state;
102         geocache.locale = wpt1.geocache.locale;
103 
104         for(const CQlgtWpt::geocachelog_t& log1 : wpt1.geocache.logs)
105         {
106             CGisItemWpt::geocachelog_t log;
107             log.id = log1.id;
108             IUnit::parseTimestamp(log1.date, log.date);
109             log.type = log1.type;
110             log.finderId = log1.finderId;
111             log.finder = log1.finder;
112             log.textIsHtml = log1.text.contains("</");
113             log.text = log1.text;
114             geocache.logs << log;
115         }
116     }
117 
118     for(const CQlgtWpt::image_t& image1 : wpt1.images)
119     {
120         CGisItemWpt::image_t image;
121 
122         image.pixmap = image1.pixmap.toImage();
123         image.direction = direction;
124         image.info = image1.info;
125         image.filePath = image1.filePath;
126         image.fileName = image1.fileName;
127 
128         images << image;
129     }
130     boundingRect = QRectF(QPointF(wpt.lon, wpt.lat) * DEG_TO_RAD, QPointF(wpt.lon, wpt.lat) * DEG_TO_RAD);
131     setIcon();
132     CGisItemWpt::genKey();
133     setupHistory();
134 }
135 
136 
CGisItemTrk(const CQlgtTrack & trk1,IGisProject * project)137 CGisItemTrk::CGisItemTrk(const CQlgtTrack& trk1, IGisProject* project)
138     : IGisItem(project, eTypeTrk, NOIDX)
139     , activities(this)
140 {
141     trk.name = trk1.name;
142     trk.cmt = trk1.comment;
143     trk.desc = trk1.description;
144     trk.color = IGisItem::colorMap[trk1.colorIdx].color.name();
145     setColor(IGisItem::colorMap[trk1.colorIdx].color);
146 
147     bool hasExtData = trk1.hasExt1Data();
148     CTrackData::trkseg_t seg;
149     for(const CQlgtTrack::pt_t& pt1 : trk1.track)
150     {
151         CTrackData::trkpt_t pt;
152         QDateTime time = QDateTime::fromTime_t(pt1._timestamp, QTimeZone("UTC"));
153         time = time.addMSecs(pt1._timestamp_msec);
154 
155         pt.lon = pt1._lon;
156         pt.lat = pt1._lat;
157         pt.ele = pt1._ele == WPT_NOFLOAT ? NOINT : qRound(pt1._ele);
158         pt.time = time.toUTC();
159 
160         if(hasExtData)
161         {
162             pt.hdop = pt1.hdop;
163             pt.vdop = pt1.vdop;
164             pt.pdop = pt1.pdop;
165         }
166 
167         seg.pts << pt;
168     }
169 
170     trk.segs << seg;
171 
172     genKey();
173     setupHistory();
174 
175     bool hasHiddenPoints = false;
176     for(int i = 0; i < trk1.track.size(); i++)
177     {
178         CTrackData::trkpt_t& pt = trk.segs[0].pts[i];
179         const CQlgtTrack::pt_t& pt1 = trk1.track[i];
180 
181         if(pt1.flags & CQlgtTrack::pt_t::eDeleted)
182         {
183             pt.flags |= CTrackData::trkpt_t::eFlagHidden;
184             hasHiddenPoints = true;
185         }
186     }
187 
188     deriveSecondaryData();
189 
190     if(hasHiddenPoints)
191     {
192         // append history by new entry
193         history.events << history_event_t();
194         history_event_t& event = history.events.last();
195         event.time = QDateTime::currentDateTimeUtc();
196         event.comment = tr("Copy flag information from QLandkarte GT track");
197         event.icon = "://icons/48x48/PointHide.png";
198 
199         QDataStream stream(&event.data, QIODevice::WriteOnly);
200         stream.setByteOrder(QDataStream::LittleEndian);
201         stream.setVersion(QDataStream::Qt_5_2);
202 
203         *this >> stream;
204 
205         QCryptographicHash md5(QCryptographicHash::Md5);
206         md5.addData(event.data);
207         event.hash = md5.result().toHex();
208 
209         history.histIdxCurrent = history.events.size() - 1;
210     }
211 }
212 
CGisItemTrk(const IQlgtOverlay & ovl,IGisProject * project)213 CGisItemTrk::CGisItemTrk(const IQlgtOverlay& ovl, IGisProject* project)
214     : IGisItem(project, eTypeTrk, NOIDX)
215     , activities(this)
216 {
217     trk.name = ovl.name;
218     trk.cmt = ovl.comment;
219     trk.desc = ovl.description;
220     trk.color = ovl.color.name();
221 
222     CTrackData::trkseg_t seg;
223     for(const IQlgtOverlay::pt_t& pt1 : ovl.points)
224     {
225         CTrackData::trkpt_t pt;
226         pt.lon = pt1.u * RAD_TO_DEG;
227         pt.lat = pt1.v * RAD_TO_DEG;
228 
229         seg.pts << pt;
230     }
231     trk.segs << seg;
232     setColor(str2color(trk.color));
233     deriveSecondaryData();
234 
235     filterReplaceElevation(nullptr);
236     if(ovl.speed != 0)
237     {
238         filterSpeed(ovl.speed);
239     }
240 
241     genKey();
242     setupHistory();
243 }
244 
245 
246 
CGisItemOvlArea(const IQlgtOverlay & ovl,IGisProject * project)247 CGisItemOvlArea::CGisItemOvlArea(const IQlgtOverlay& ovl, IGisProject* project)
248     : IGisItem(project, eTypeOvl, NOIDX)
249 {
250     area.name = ovl.name;
251     area.cmt = ovl.comment;
252     area.desc = ovl.description;
253     area.color = ovl.color.name();
254     area.width = ovl.width;
255     area.style = ovl.style;
256     area.opacity = ovl.opacity != 255;
257 
258     for(const IQlgtOverlay::pt_t& pt1 : ovl.points)
259     {
260         pt_t pt;
261         pt.lon = pt1.u * RAD_TO_DEG;
262         pt.lat = pt1.v * RAD_TO_DEG;
263 
264         area.pts << pt;
265     }
266 
267     setColor(str2color(area.color));
268     deriveSecondaryData();
269 
270     genKey();
271     setupHistory();
272 }
273 
274 
CGisItemRte(const CQlgtRoute & rte1,IGisProject * project)275 CGisItemRte::CGisItemRte(const CQlgtRoute& rte1, IGisProject* project)
276     : IGisItem(project, eTypeRte, NOIDX)
277 {
278     rte.name = rte1.name;
279     rte.cmt = rte1.comment;
280     rte.desc = rte1.description;
281 
282     QPointF focus;
283     QPixmap icon = CWptIconManager::self().getWptIconByName(rte1.iconString, focus);
284 
285     for(const CQlgtRoute::pt_t& pt1 : rte1.priRoute)
286     {
287         rtept_t pt;
288         pt.lon = pt1.lon;
289         pt.lat = pt1.lat;
290         pt.icon = icon;
291         pt.focus = focus;
292 
293         rte.pts << pt;
294     }
295 
296     deriveSecondaryData();
297     CGisItemRte::setSymbol();
298     genKey();
299     setupHistory();
300 }
301