~ubuntu-branches/ubuntu/saucy/merkaartor/saucy

« back to all changes in this revision

Viewing changes to ImportExport/ImportExportKML.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Bernd Zeimetz
  • Date: 2009-09-13 00:52:12 UTC
  • mto: (1.2.7 upstream) (0.1.3 upstream) (3.1.7 sid)
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20090913005212-pjecal8zxm07x0fj
ImportĀ upstreamĀ versionĀ 0.14+svnfixes~20090912

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// C++ Implementation: ImportExportKML
3
 
//
4
 
// Description:
5
 
//
6
 
//
7
 
// Author: cbro <cbro@semperpax.com>, (C) 2008
8
 
//
9
 
// Copyright: See COPYING file that comes with this distribution
10
 
//
11
 
//
12
 
 
13
 
#include <QtGui>
14
 
 
15
 
#include "../ImportExport/ImportExportKML.h"
16
 
 
17
 
bool parseContainer(QDomElement& e, MapLayer* aLayer);
18
 
 
19
 
ImportExportKML::ImportExportKML(MapDocument* doc)
20
 
 : IImportExport(doc)
21
 
{
22
 
}
23
 
 
24
 
 
25
 
ImportExportKML::~ImportExportKML()
26
 
{
27
 
}
28
 
 
29
 
 
30
 
// export
31
 
bool ImportExportKML::export_(const QList<MapFeature *>& featList)
32
 
{
33
 
        QList<TrackPoint*>      waypoints;
34
 
        QList<TrackSegment*>    segments;
35
 
        QDomElement k;
36
 
        QDomText v;
37
 
 
38
 
        if(! IImportExport::export_(featList) ) return false;
39
 
 
40
 
        bool OK = true;
41
 
 
42
 
        QDomDocument theXmlDoc;
43
 
        theXmlDoc.appendChild(theXmlDoc.createProcessingInstruction("xml", "version=\"1.0\""));
44
 
 
45
 
        QDomElement kml = theXmlDoc.createElement("kml");
46
 
        theXmlDoc.appendChild(kml);
47
 
        kml.setAttribute("xmlns", "http://earth.google.com/kml/2.2");
48
 
 
49
 
        QDomElement d = theXmlDoc.createElement("Document");
50
 
        kml.appendChild(d);
51
 
 
52
 
 
53
 
        //QDomElement g = theXmlDoc.createElement("MultiGeometry");
54
 
        //p.appendChild(g);
55
 
 
56
 
        for (int i=0; i<theFeatures.size(); ++i) {
57
 
                if (Road* R = dynamic_cast<Road*>(theFeatures[i])) {
58
 
                        QDomElement p = theXmlDoc.createElement("Placemark");
59
 
                        d.appendChild(p);
60
 
 
61
 
                        k = theXmlDoc.createElement("name");
62
 
                        p.appendChild(k);
63
 
                        v = theXmlDoc.createTextNode(R->description());
64
 
                        k.appendChild(v);
65
 
 
66
 
                        k = theXmlDoc.createElement("description");
67
 
                        p.appendChild(k);
68
 
                        QString desc;
69
 
                        for (unsigned int j=0; j<R->tagSize(); ++j) {
70
 
                                desc += R->tagKey(j);
71
 
                                desc += "=";
72
 
                                desc += R->tagValue(j);
73
 
                                desc += "<br/>";
74
 
                        }
75
 
                        v = theXmlDoc.createTextNode(desc);
76
 
                        k.appendChild(v);
77
 
 
78
 
                        k = theXmlDoc.createElement("Style");
79
 
                        p.appendChild(k);
80
 
 
81
 
                        QDomElement ls = theXmlDoc.createElement("LineStyle");
82
 
                        k.appendChild(ls);
83
 
 
84
 
                        const FeaturePainter* fp = R->getCurrentEditPainter();
85
 
                        if (fp) {
86
 
                                QDomElement color = theXmlDoc.createElement("color");
87
 
                                ls.appendChild(color);
88
 
                                QRgb kcolor = fp->ForegroundColor.rgba();
89
 
                                v = theXmlDoc.createTextNode(QString::number(qRgba(qBlue(kcolor), qGreen(kcolor), qRed(kcolor), /*qAlpha(kcolor)*/ 192), 16));
90
 
                                color.appendChild(v);
91
 
                        } 
92
 
                        QDomElement width = theXmlDoc.createElement("width");
93
 
                        ls.appendChild(width);
94
 
                        v = theXmlDoc.createTextNode(QString::number(R->widthOf()));
95
 
                        width.appendChild(v);
96
 
 
97
 
                        QDomElement l = theXmlDoc.createElement("LineString");
98
 
                        p.appendChild(l);
99
 
 
100
 
                        QDomElement c = theXmlDoc.createElement("coordinates");
101
 
                        l.appendChild(c);
102
 
                        
103
 
                        QString s;
104
 
                        for (unsigned int j=0; j<R->size(); ++j) {
105
 
                                TrackPoint* N = dynamic_cast<TrackPoint*>(R->get(j));
106
 
                                s += QString(" %1,%2").arg(QString::number(intToAng(N->position().lon()),'f',8)).arg(QString::number(intToAng(N->position().lat()),'f',8));
107
 
                        }
108
 
 
109
 
                        QDomText v = theXmlDoc.createTextNode(s);
110
 
                        c.appendChild(v);
111
 
                }
112
 
                else if (TrackPoint* N = dynamic_cast<TrackPoint*>(theFeatures[i])) {
113
 
                        if (N->sizeParents()) continue;
114
 
 
115
 
                        QDomElement p = theXmlDoc.createElement("Placemark");
116
 
                        d.appendChild(p);
117
 
 
118
 
                        k = theXmlDoc.createElement("name");
119
 
                        p.appendChild(k);
120
 
                        v = theXmlDoc.createTextNode(N->description());
121
 
                        k.appendChild(v);
122
 
 
123
 
                        k = theXmlDoc.createElement("description");
124
 
                        p.appendChild(k);
125
 
                        QString desc;
126
 
                        for (unsigned int j=0; j<N->tagSize(); ++j) {
127
 
                                desc += N->tagKey(j);
128
 
                                desc += "=";
129
 
                                desc += N->tagValue(j);
130
 
                                desc += "<br/>";
131
 
                        }
132
 
                        v = theXmlDoc.createTextNode(desc);
133
 
                        k.appendChild(v);
134
 
 
135
 
                        //k = theXmlDoc.createElement("Style");
136
 
                        //p.appendChild(k);
137
 
 
138
 
                        //QDomElement ls = theXmlDoc.createElement("LineStyle");
139
 
                        //k.appendChild(ls);
140
 
 
141
 
                        //FeaturePainter* fp = R->getCurrentEditPainter();
142
 
                        //if (fp) {
143
 
                        //      QDomElement color = theXmlDoc.createElement("color");
144
 
                        //      ls.appendChild(color);
145
 
                        //      QRgb kcolor = fp->ForegroundColor.rgba();
146
 
                        //      v = theXmlDoc.createTextNode(QString::number(qRgba(qBlue(kcolor), qGreen(kcolor), qRed(kcolor), /*qAlpha(kcolor)*/ 164), 16));
147
 
                        //      color.appendChild(v);
148
 
                        //} 
149
 
                        //QDomElement width = theXmlDoc.createElement("width");
150
 
                        //ls.appendChild(width);
151
 
                        //v = theXmlDoc.createTextNode(QString::number(widthOf(R)));
152
 
                        //width.appendChild(v);
153
 
 
154
 
                        QDomElement l = theXmlDoc.createElement("Point");
155
 
                        p.appendChild(l);
156
 
 
157
 
                        QDomElement c = theXmlDoc.createElement("coordinates");
158
 
                        l.appendChild(c);
159
 
                        
160
 
                        QString s;
161
 
                        s += QString(" %1,%2").arg(QString::number(intToAng(N->position().lon()),'f',8)).arg(QString::number(intToAng(N->position().lat()),'f',8));
162
 
 
163
 
                        QDomText v = theXmlDoc.createTextNode(s);
164
 
                        c.appendChild(v);
165
 
                }
166
 
        }
167
 
 
168
 
        Device->write(theXmlDoc.toString().toUtf8());
169
 
        return OK;
170
 
 
171
 
}
172
 
 
173
 
// IMPORT
174
 
 
175
 
QString kmlId;
176
 
 
177
 
MapFeature* parsePoint(QDomElement& e, MapLayer* aLayer)
178
 
{
179
 
        TrackPoint* P = NULL;
180
 
 
181
 
        QDomElement c = e.firstChildElement();
182
 
        while(!c.isNull() && !P) {
183
 
                if (c.tagName() == "coordinates") {
184
 
                        QDomText t = c.firstChild().toText();
185
 
                        QString s = t.nodeValue();
186
 
                        QStringList tokens = s.split(",");
187
 
                        double lon = tokens[0].toDouble();
188
 
                        double lat = tokens[1].toDouble();
189
 
                        Coord p(angToInt(lat), angToInt(lon));
190
 
 
191
 
                        P = new TrackPoint(p);
192
 
                        P->setTag("%kml:guid", kmlId);
193
 
                        aLayer->add(P);
194
 
                }
195
 
 
196
 
                c = c.nextSiblingElement();
197
 
        }
198
 
 
199
 
        return P;
200
 
}
201
 
 
202
 
MapFeature* parseGeometry(QDomElement& e, MapLayer* aLayer)
203
 
{
204
 
        MapFeature* F = NULL;
205
 
        if (e.tagName() == "Point") {
206
 
                F = parsePoint(e, aLayer);
207
 
        }
208
 
 
209
 
        return F;
210
 
}
211
 
 
212
 
bool parsePlacemark(QDomElement& e, MapLayer* aLayer)
213
 
{
214
 
        MapFeature* F = NULL;
215
 
        QDomElement c = e.firstChildElement();
216
 
        QString name;
217
 
        QString address;
218
 
        QString description;
219
 
        QString phone;
220
 
 
221
 
        while(!c.isNull()) {
222
 
                if (c.tagName() == "name")
223
 
                        name = c.firstChild().toText().nodeValue();
224
 
                else
225
 
                if (c.tagName() == "address")
226
 
                        address = c.firstChild().toText().nodeValue();
227
 
                else
228
 
                if (c.tagName() == "description")
229
 
                        description = c.firstChild().toText().nodeValue();
230
 
                else
231
 
                if (c.tagName() == "phoneNumber")
232
 
                        phone = c.firstChild().toText().nodeValue();
233
 
                else
234
 
                F = parseGeometry(c, aLayer);
235
 
 
236
 
                c = c.nextSiblingElement();
237
 
        }
238
 
 
239
 
        if (F) {
240
 
                if (!name.isEmpty())
241
 
                        F->setTag("name", name);
242
 
                if (!address.isEmpty())
243
 
                        F->setTag("addr:full", address);
244
 
                if (!phone.isEmpty())
245
 
                        F->setTag("addr:phone_number", phone);
246
 
                if (!description.isEmpty())
247
 
                        F->setTag("description", description);
248
 
                return true;
249
 
        } else
250
 
                return false;
251
 
}
252
 
 
253
 
bool parseFeature(QDomElement& e, MapLayer* aLayer)
254
 
{
255
 
        bool ret= false;
256
 
        QDomElement c = e.cloneNode().toElement();
257
 
 
258
 
        while(!c.isNull()) {
259
 
                if (c.tagName() == "Placemark")
260
 
                        ret = parsePlacemark(c, aLayer);
261
 
                else
262
 
                        ret = parseContainer(c, aLayer);
263
 
 
264
 
                c = c.nextSiblingElement();
265
 
        }
266
 
        return ret;
267
 
}
268
 
 
269
 
bool parseContainer(QDomElement& e, MapLayer* aLayer)
270
 
{
271
 
        if ((e.tagName() != "Document") && (e.tagName() != "Folder"))
272
 
                return false;
273
 
 
274
 
        bool ret= false;
275
 
        QDomElement c = e.firstChildElement();
276
 
 
277
 
        while(!c.isNull()) {
278
 
                ret = parseFeature(c, aLayer);
279
 
 
280
 
                c = c.nextSiblingElement();
281
 
        }
282
 
        return ret;
283
 
}
284
 
 
285
 
bool parseKML(QDomElement& e, MapLayer* aLayer)
286
 
{
287
 
        bool ret= false;
288
 
        QDomElement c = e.firstChildElement();
289
 
        
290
 
        while(!c.isNull()) {
291
 
                ret = parseFeature(c, aLayer);
292
 
                if (!ret)
293
 
                        ret = parseGeometry(c, aLayer);
294
 
 
295
 
                c = c.nextSiblingElement();
296
 
        }
297
 
        return ret;
298
 
}
299
 
 
300
 
// import the  input
301
 
bool ImportExportKML::import(MapLayer* aLayer)
302
 
{
303
 
        QDomDocument* theXmlDoc = new QDomDocument();
304
 
        if (!theXmlDoc->setContent(Device)) {
305
 
                //QMessageBox::critical(this, tr("Invalid file"), tr("%1 is not a valid XML file.").arg(fn));
306
 
                Device->close();
307
 
                delete theXmlDoc;
308
 
                theXmlDoc = NULL;
309
 
                return false;
310
 
        }
311
 
        Device->close();
312
 
 
313
 
        QDomElement docElem = theXmlDoc->documentElement();
314
 
        if (docElem.tagName() != "kml") {
315
 
                //QMessageBox::critical(this, tr("Invalid file"), tr("%1 is not a valid KML document.").arg(fn));
316
 
                return false;
317
 
        }
318
 
        kmlId = QUuid::createUuid().toString();
319
 
        return parseKML(docElem, aLayer);
320
 
}
321