2
// C++ Implementation: ImportExportKML
7
// Author: cbro <cbro@semperpax.com>, (C) 2008
9
// Copyright: See COPYING file that comes with this distribution
15
#include "../ImportExport/ImportExportKML.h"
17
bool parseContainer(QDomElement& e, MapLayer* aLayer);
19
ImportExportKML::ImportExportKML(MapDocument* doc)
25
ImportExportKML::~ImportExportKML()
31
bool ImportExportKML::export_(const QList<MapFeature *>& featList)
33
QList<TrackPoint*> waypoints;
34
QList<TrackSegment*> segments;
38
if(! IImportExport::export_(featList) ) return false;
42
QDomDocument theXmlDoc;
43
theXmlDoc.appendChild(theXmlDoc.createProcessingInstruction("xml", "version=\"1.0\""));
45
QDomElement kml = theXmlDoc.createElement("kml");
46
theXmlDoc.appendChild(kml);
47
kml.setAttribute("xmlns", "http://earth.google.com/kml/2.2");
49
QDomElement d = theXmlDoc.createElement("Document");
53
//QDomElement g = theXmlDoc.createElement("MultiGeometry");
56
for (int i=0; i<theFeatures.size(); ++i) {
57
if (Road* R = dynamic_cast<Road*>(theFeatures[i])) {
58
QDomElement p = theXmlDoc.createElement("Placemark");
61
k = theXmlDoc.createElement("name");
63
v = theXmlDoc.createTextNode(R->description());
66
k = theXmlDoc.createElement("description");
69
for (unsigned int j=0; j<R->tagSize(); ++j) {
72
desc += R->tagValue(j);
75
v = theXmlDoc.createTextNode(desc);
78
k = theXmlDoc.createElement("Style");
81
QDomElement ls = theXmlDoc.createElement("LineStyle");
84
const FeaturePainter* fp = R->getCurrentEditPainter();
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));
92
QDomElement width = theXmlDoc.createElement("width");
93
ls.appendChild(width);
94
v = theXmlDoc.createTextNode(QString::number(R->widthOf()));
97
QDomElement l = theXmlDoc.createElement("LineString");
100
QDomElement c = theXmlDoc.createElement("coordinates");
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));
109
QDomText v = theXmlDoc.createTextNode(s);
112
else if (TrackPoint* N = dynamic_cast<TrackPoint*>(theFeatures[i])) {
113
if (N->sizeParents()) continue;
115
QDomElement p = theXmlDoc.createElement("Placemark");
118
k = theXmlDoc.createElement("name");
120
v = theXmlDoc.createTextNode(N->description());
123
k = theXmlDoc.createElement("description");
126
for (unsigned int j=0; j<N->tagSize(); ++j) {
127
desc += N->tagKey(j);
129
desc += N->tagValue(j);
132
v = theXmlDoc.createTextNode(desc);
135
//k = theXmlDoc.createElement("Style");
138
//QDomElement ls = theXmlDoc.createElement("LineStyle");
141
//FeaturePainter* fp = R->getCurrentEditPainter();
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);
149
//QDomElement width = theXmlDoc.createElement("width");
150
//ls.appendChild(width);
151
//v = theXmlDoc.createTextNode(QString::number(widthOf(R)));
152
//width.appendChild(v);
154
QDomElement l = theXmlDoc.createElement("Point");
157
QDomElement c = theXmlDoc.createElement("coordinates");
161
s += QString(" %1,%2").arg(QString::number(intToAng(N->position().lon()),'f',8)).arg(QString::number(intToAng(N->position().lat()),'f',8));
163
QDomText v = theXmlDoc.createTextNode(s);
168
Device->write(theXmlDoc.toString().toUtf8());
177
MapFeature* parsePoint(QDomElement& e, MapLayer* aLayer)
179
TrackPoint* P = NULL;
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));
191
P = new TrackPoint(p);
192
P->setTag("%kml:guid", kmlId);
196
c = c.nextSiblingElement();
202
MapFeature* parseGeometry(QDomElement& e, MapLayer* aLayer)
204
MapFeature* F = NULL;
205
if (e.tagName() == "Point") {
206
F = parsePoint(e, aLayer);
212
bool parsePlacemark(QDomElement& e, MapLayer* aLayer)
214
MapFeature* F = NULL;
215
QDomElement c = e.firstChildElement();
222
if (c.tagName() == "name")
223
name = c.firstChild().toText().nodeValue();
225
if (c.tagName() == "address")
226
address = c.firstChild().toText().nodeValue();
228
if (c.tagName() == "description")
229
description = c.firstChild().toText().nodeValue();
231
if (c.tagName() == "phoneNumber")
232
phone = c.firstChild().toText().nodeValue();
234
F = parseGeometry(c, aLayer);
236
c = c.nextSiblingElement();
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);
253
bool parseFeature(QDomElement& e, MapLayer* aLayer)
256
QDomElement c = e.cloneNode().toElement();
259
if (c.tagName() == "Placemark")
260
ret = parsePlacemark(c, aLayer);
262
ret = parseContainer(c, aLayer);
264
c = c.nextSiblingElement();
269
bool parseContainer(QDomElement& e, MapLayer* aLayer)
271
if ((e.tagName() != "Document") && (e.tagName() != "Folder"))
275
QDomElement c = e.firstChildElement();
278
ret = parseFeature(c, aLayer);
280
c = c.nextSiblingElement();
285
bool parseKML(QDomElement& e, MapLayer* aLayer)
288
QDomElement c = e.firstChildElement();
291
ret = parseFeature(c, aLayer);
293
ret = parseGeometry(c, aLayer);
295
c = c.nextSiblingElement();
301
bool ImportExportKML::import(MapLayer* aLayer)
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));
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));
318
kmlId = QUuid::createUuid().toString();
319
return parseKML(docElem, aLayer);