1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 | /* ============================================================
*
* This file is a part of digiKam project
* https://www.digikam.org
*
* Date : 2023-05-15
* Description : geolocation engine based on Marble.
* (c) 2007-2022 Marble Team
* https://invent.kde.org/education/marble/-/raw/master/data/credits_authors.html
*
* SPDX-FileCopyrightText: 2023-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* ============================================================ */
#include "KmlOsmPlacemarkDataTagHandler.h"
// Qt includes
#include <QVariant>
// Local includes
#include "KmlElementDictionary.h"
#include "GeoDataExtendedData.h"
#include "GeoDataGeometry.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoDataData.h"
#include "GeoParser.h"
#include "GeoDataPoint.h"
#include "OsmPlacemarkData.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_MX(OsmPlacemarkData)
GeoNode* KmlOsmPlacemarkDataTagHandler::parse(GeoParser& parser) const
{
OsmPlacemarkData osmData = OsmPlacemarkData::fromParserAttributes(parser.attributes());
/* Case 1: This is the main OsmPlacemarkData of a placemark:
* <Placemark>
* <ExtendedData>
* <mx:OsmPlacemarkData>
* ...
*/
if (parser.parentElement().is<GeoDataExtendedData>() && parser.parentElement(1).is<GeoDataPlacemark>())
{
auto placemark = parser.parentElement(1).nodeAs<GeoDataPlacemark>();
placemark->setOsmData(osmData);
return &placemark->osmData();
}
/* Case 2: This is the OsmPlacemarkData of a Nd
* <Placemark>
* <ExtendedData>
* <mx:OsmPlacemarkData>
* <mx:nd>
* <mx:OsmPlacemarkData>
* ...
*/
else if (parser.parentElement(1).is<OsmPlacemarkData>() && parser.parentElement().is<GeoDataPoint>())
{
OsmPlacemarkData* placemarkOsmData = parser.parentElement(1).nodeAs<OsmPlacemarkData>();
GeoDataPoint* point = parser.parentElement().nodeAs<GeoDataPoint>();
GeoDataCoordinates coordinates = point->coordinates();
/* The GeoDataPoint object was only used as GeoNode wrapper for the GeoDataCoordinates
* and it is no longer needed
*/
delete point;
placemarkOsmData->addNodeReference(coordinates, osmData);
return &placemarkOsmData->nodeReference(coordinates);
}
/* Case 3: This is the OsmPlacemarkData of a polygon's member
* <Placemark>
* <ExtendedData>
* <mx:OsmPlacemarkData>
* <mx:member>
* <mx:OsmPlacemarkData>
* ...
*/
else if (parser.parentElement(1).is<OsmPlacemarkData>() && parser.parentElement().is<GeoDataLinearRing>()
&& parser.parentElement(3).is<GeoDataPlacemark>())
{
OsmPlacemarkData* placemarkOsmData = parser.parentElement(1).nodeAs<OsmPlacemarkData>();
GeoDataPlacemark* placemark = parser.parentElement(3).nodeAs<GeoDataPlacemark>();
GeoDataLinearRing& ring = *parser.parentElement().nodeAs<GeoDataLinearRing>();<--- Variable 'ring' can be declared as reference to const
GeoDataPolygon* polygon = geodata_cast<GeoDataPolygon>(placemark->geometry());
if (!polygon)
{
return nullptr;
}
/* The QVector's indexOf function is perfect: returns the index of the ring
* within the vector if the ring is an innerBoundary;
* Else it returns -1, meaning it's an outerBoundary
*/
int memberIndex = polygon->innerBoundaries().indexOf(ring);
placemarkOsmData->addMemberReference(memberIndex, osmData);
return &placemarkOsmData->memberReference(memberIndex);
}
return nullptr;
}
} // namespace kml
} // namespace Marble
|