File indexing completed on 2024-06-02 03:51:04
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2015 Marius-Valeriu Stanciu <stanciumarius94@gmail.com> 0004 // 0005 0006 // Marble 0007 #include "KmlOsmPlacemarkDataTagHandler.h" 0008 #include "KmlElementDictionary.h" 0009 #include "GeoDataExtendedData.h" 0010 #include "GeoDataGeometry.h" 0011 #include "GeoDataPlacemark.h" 0012 #include "GeoDataLinearRing.h" 0013 #include "GeoDataPolygon.h" 0014 #include "GeoDataData.h" 0015 #include "GeoParser.h" 0016 #include "GeoDataPoint.h" 0017 #include "osm/OsmPlacemarkData.h" 0018 0019 #include <QVariant> 0020 0021 namespace Marble 0022 { 0023 namespace kml 0024 { 0025 KML_DEFINE_TAG_HANDLER_MX( OsmPlacemarkData ) 0026 0027 GeoNode* KmlOsmPlacemarkDataTagHandler::parse( GeoParser& parser ) const 0028 { 0029 OsmPlacemarkData osmData = OsmPlacemarkData::fromParserAttributes( parser.attributes() ); 0030 /* Case 1: This is the main OsmPlacemarkData of a placemark: 0031 * <Placemark> 0032 * <ExtendedData> 0033 * <mx:OsmPlacemarkData> 0034 * ... 0035 */ 0036 if (parser.parentElement().is<GeoDataExtendedData>() && parser.parentElement(1).is<GeoDataPlacemark>()) { 0037 auto placemark = parser.parentElement(1).nodeAs<GeoDataPlacemark>(); 0038 placemark->setOsmData(osmData); 0039 return &placemark->osmData(); 0040 } 0041 /* Case 2: This is the OsmPlacemarkData of a Nd 0042 * <Placemark> 0043 * <ExtendedData> 0044 * <mx:OsmPlacemarkData> 0045 * <mx:nd> 0046 * <mx:OsmPlacemarkData> 0047 * ... 0048 */ 0049 else if ( parser.parentElement( 1 ).is<OsmPlacemarkData>() && parser.parentElement().is<GeoDataPoint>() ) { 0050 OsmPlacemarkData* placemarkOsmData = parser.parentElement( 1 ).nodeAs<OsmPlacemarkData>(); 0051 GeoDataPoint *point = parser.parentElement().nodeAs<GeoDataPoint>(); 0052 GeoDataCoordinates coordinates = point->coordinates(); 0053 /* The GeoDataPoint object was only used as GeoNode wrapper for the GeoDataCoordinates 0054 * and it is no longer needed 0055 */ 0056 delete point; 0057 placemarkOsmData->addNodeReference( coordinates, osmData ); 0058 return &placemarkOsmData->nodeReference( coordinates ); 0059 } 0060 /* Case 3: This is the OsmPlacemarkData of a polygon's member 0061 * <Placemark> 0062 * <ExtendedData> 0063 * <mx:OsmPlacemarkData> 0064 * <mx:member> 0065 * <mx:OsmPlacemarkData> 0066 * ... 0067 */ 0068 else if ( parser.parentElement( 1 ).is<OsmPlacemarkData>() && parser.parentElement().is<GeoDataLinearRing>() 0069 && parser.parentElement( 3 ).is<GeoDataPlacemark>() ) { 0070 OsmPlacemarkData *placemarkOsmData = parser.parentElement( 1 ).nodeAs<OsmPlacemarkData>(); 0071 GeoDataPlacemark *placemark = parser.parentElement( 3 ).nodeAs<GeoDataPlacemark>(); 0072 GeoDataLinearRing &ring = *parser.parentElement().nodeAs<GeoDataLinearRing>(); 0073 GeoDataPolygon *polygon = geodata_cast<GeoDataPolygon>(placemark->geometry()); 0074 if (!polygon) { 0075 return nullptr; 0076 } 0077 0078 /* The QVector's indexOf function is perfect: returns the index of the ring 0079 * within the vector if the ring is an innerBoundary; 0080 * Else it returns -1, meaning it's an outerBoundary 0081 */ 0082 int memberIndex = polygon->innerBoundaries().indexOf( ring ); 0083 0084 placemarkOsmData->addMemberReference( memberIndex, osmData ); 0085 return &placemarkOsmData->memberReference( memberIndex ); 0086 } 0087 return nullptr; 0088 } 0089 } 0090 }