File indexing completed on 2024-11-03 09:49:28

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2011 Dennis Nienhüser <nienhueser@kde.org>
0004 //
0005 
0006 #include "XmlParser.h"
0007 
0008 #include <QDebug>
0009 
0010 namespace Marble
0011 {
0012 
0013 XmlParser::XmlParser( QObject *parent ) :
0014     OsmParser( parent )
0015 {
0016     // nothing to do
0017 }
0018 
0019 bool XmlParser::parse( const QFileInfo &content, int, bool &needAnotherPass )
0020 {
0021     needAnotherPass = false;
0022 
0023     QXmlSimpleReader xmlReader;
0024     xmlReader.setContentHandler( this );
0025     xmlReader.setErrorHandler( this );
0026 
0027     QFile file( content.absoluteFilePath() );
0028     QXmlInputSource *source = new QXmlInputSource( &file );
0029 
0030     if ( !xmlReader.parse( source ) ) {
0031         qCritical() << "Failed to parse " << content.absoluteFilePath();
0032         return false;
0033     }
0034 
0035     return true;
0036 }
0037 
0038 bool XmlParser::startElement ( const QString & /*namespaceURI*/, const QString & /*localName*/, const QString & qName, const QXmlAttributes & atts )
0039 {
0040     if (qName == QLatin1String("node")) {
0041         m_node = Node();
0042         m_id = atts.value( "id" ).toInt();
0043         m_node.lon = atts.value( "lon" ).toFloat();
0044         m_node.lat = atts.value( "lat" ).toFloat();
0045         m_element = NodeType;
0046     } else if (qName == QLatin1String("way")) {
0047         m_id = atts.value( "id" ).toInt();
0048         m_way = Way();
0049         m_element = WayType;
0050     } else if (qName == QLatin1String("nd")) {
0051         m_way.nodes.push_back( atts.value( "ref" ).toInt() );
0052     } else if (qName == QLatin1String("relation")) {
0053         m_id = atts.value( "id" ).toInt();
0054         m_relation = Relation();
0055         m_relation.nodes.clear();
0056         m_element = RelationType;
0057     } else if (qName == QLatin1String("member")) {
0058         if (atts.value("type") == QLatin1String("node")) {
0059             m_relation.nodes.push_back( atts.value( "ref" ).toInt() );
0060         } else if (atts.value("type") == QLatin1String("way")) {
0061             RelationRole role = None;
0062             if (atts.value("role") == QLatin1String("outer")) role = Outer;
0063             if (atts.value("role") == QLatin1String("inner")) role = Inner;
0064             m_relation.ways.push_back( QPair<int, RelationRole>( atts.value( "ref" ).toInt(), role ) );
0065         } else if (atts.value("type") == QLatin1String("relation")) {
0066             m_relation.relations.push_back( atts.value( "ref" ).toInt() );
0067         } else {
0068             qDebug() << "Unknown relation member type " << atts.value( "type" );
0069         }
0070     } else if (qName == QLatin1String("tag") && m_element == RelationType) {
0071         if (atts.value("k") == QLatin1String("boundary") && atts.value("v") == QLatin1String("administrative")) {
0072             m_relation.isAdministrativeBoundary = true;
0073         } else if (atts.value("k") == QLatin1String("admin_level")) {
0074             m_relation.adminLevel = atts.value( "v" ).toInt();
0075         } else if (atts.value("k") == QLatin1String("name")) {
0076             m_relation.name = atts.value( "v" );
0077         } else if (atts.value("k") == QLatin1String("type") && atts.value("v") == QLatin1String("multipolygon")) {
0078             m_relation.isMultipolygon = true;
0079         }
0080     } else if (qName == QLatin1String("tag") && m_element == WayType) {
0081         QString const key = atts.value( "k" );
0082         QString const value = atts.value( "v" );
0083         if (key == QLatin1String("name")) {
0084             m_way.name = value;
0085         } else if (key == QLatin1String("addr:street")) {
0086             m_way.street = value;
0087             m_way.save = true;
0088         } else if (key == QLatin1String("addr:housenumber")) {
0089             m_way.houseNumber = value;
0090             m_way.save = true;
0091         } else if (key == QLatin1String("addr:city")) {
0092             m_way.city = value;
0093             m_way.save = true;
0094         } else if (key == QLatin1String("building") && value == QLatin1String("yes")) {
0095             m_way.isBuilding = true;
0096         } else  {
0097             if ( shouldSave( WayType, key, value ) ) {
0098                 m_way.save = true;
0099             }
0100             setCategory( m_way, key, value );
0101         }
0102     } else if (qName == QLatin1String("tag") && m_element == NodeType) {
0103         QString const key = atts.value( "k" );
0104         QString const value = atts.value( "v" );
0105         if (key == QLatin1String("name")) {
0106             m_node.name = value;
0107         } else if (key == QLatin1String("addr:street")) {
0108             m_node.street = value;
0109             m_node.save = true;
0110         } else if (key == QLatin1String("addr:housenumber")) {
0111             m_node.houseNumber = value;
0112             m_node.save = true;
0113         } else if (key == QLatin1String("addr:city")) {
0114             m_node.city = value;
0115             m_node.save = true;
0116         } else {
0117             if ( shouldSave( NodeType, key, value ) ) {
0118                 m_node.save = true;
0119             }
0120             setCategory( m_node, key, value );
0121         }
0122     }
0123 
0124     return true;
0125 }
0126 
0127 bool XmlParser::endElement ( const QString & /*namespaceURI*/, const QString & /*localName*/, const QString & qName )
0128 {
0129     if (qName == QLatin1String("node")) {
0130         m_nodes[m_id] = m_node;
0131     } else if (qName == QLatin1String("way")) {
0132         m_ways[m_id] = m_way;
0133     } else if (qName == QLatin1String("relation")) {
0134         m_relations[m_id] = m_relation;
0135     }
0136 
0137     return true;
0138 }
0139 
0140 }
0141 
0142 #include "moc_XmlParser.cpp"