File indexing completed on 2024-05-05 03:50:49

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2011 Valery Kharitonov <kharvd@gmail.com>
0004 //
0005 
0006 // Self
0007 #include "PostalCodeModel.h"
0008 
0009 // Plugin
0010 #include "PostalCodeItem.h"
0011 
0012 // Marble
0013 #include "MarbleGlobal.h"
0014 #include "MarbleModel.h"
0015 #include "GeoDataCoordinates.h"
0016 #include "GeoDataLatLonAltBox.h"
0017 #include "MarbleDebug.h"
0018 #include "Planet.h"
0019 
0020 // Qt
0021 #include <QString>
0022 #include <QUrl>
0023 #include <QJsonDocument>
0024 #include <QJsonArray>
0025 #include <QJsonObject>
0026 
0027 #include <QUrlQuery>
0028 
0029 using namespace Marble;
0030 
0031 PostalCodeModel::PostalCodeModel( const MarbleModel *marbleModel, QObject *parent  )
0032     : AbstractDataPluginModel( "postalCode", marbleModel, parent )
0033 {
0034 }
0035 
0036 PostalCodeModel::~PostalCodeModel() {
0037 }
0038 
0039 void PostalCodeModel::getAdditionalItems( const GeoDataLatLonAltBox& box,
0040                                           qint32 number )
0041 {
0042     if (marbleModel()->planetId() != QLatin1String("earth")) {
0043         return;
0044     }
0045 
0046     double const lat = box.center().latitude( GeoDataCoordinates::Degree );
0047     double const lon = box.center().longitude( GeoDataCoordinates::Degree );
0048     double const radius = qMin<double>( 30.0, box.height() * marbleModel()->planet()->radius() * METER2KM );
0049 
0050     QUrl geonamesUrl( "http://api.geonames.org/findNearbyPostalCodesJSON" );
0051     QUrlQuery urlQuery;
0052     urlQuery.addQueryItem( "lat", QString::number( lat ) );
0053     urlQuery.addQueryItem( "lng", QString::number( lon ) );
0054     urlQuery.addQueryItem( "radius", QString::number( radius ) );
0055     urlQuery.addQueryItem( "maxRows", QString::number( number ) );
0056     urlQuery.addQueryItem( "username", "marble" );
0057     geonamesUrl.setQuery( urlQuery );
0058 
0059     downloadDescriptionFile( QUrl( geonamesUrl ) );
0060 }
0061 
0062 void PostalCodeModel::parseFile( const QByteArray& file )
0063 {
0064     QJsonDocument jsonDoc = QJsonDocument::fromJson(file);
0065     QJsonValue postalCodesValue = jsonDoc.object().value(QStringLiteral("postalCodes"));
0066 
0067     // Parse if any result exists
0068     if (postalCodesValue.isArray()) {
0069         // Add items to the list
0070         QList<AbstractDataPluginItem*> items;
0071 
0072         QJsonArray postalCodesArray = postalCodesValue.toArray();
0073         for (int index = 0; index < postalCodesArray.size(); ++index) {
0074             QJsonObject postalCodeObject = postalCodesArray[index].toObject();
0075 
0076             QString const placeName = postalCodeObject.value(QStringLiteral("placeName")).toString();
0077             QString const adminName1 = postalCodeObject.value(QStringLiteral("adminName1")).toString();
0078             QString const adminName2 = postalCodeObject.value(QStringLiteral("adminName2")).toString();
0079             QString const adminName3 = postalCodeObject.value(QStringLiteral("adminName3")).toString();
0080             QString const postalCode = postalCodeObject.value(QStringLiteral("postalCode")).toString();
0081             QString const countryCode = postalCodeObject.value(QStringLiteral("countryCode")).toString();
0082             double const longitude = postalCodeObject.value(QStringLiteral("lng")).toDouble();
0083             double const latitude = postalCodeObject.value(QStringLiteral("lat")).toDouble();
0084 
0085             QString const id = QLatin1String("postalCode_") + countryCode + postalCode;
0086 
0087             if ( !id.isEmpty() ) {
0088                 QString tooltip;
0089 
0090                 if ( !placeName.isEmpty() ) {
0091                     tooltip += placeName + QLatin1Char(' ');
0092                 }
0093 
0094                 addLine( &tooltip, postalCode );
0095                 addLine( &tooltip, countryCode );
0096                 addLine( &tooltip, adminName1 );
0097                 addLine( &tooltip, adminName2 );
0098                 addLine( &tooltip, adminName3 );
0099                 tooltip = tooltip.trimmed();
0100 
0101                 if( !itemExists( id ) ) {
0102                     // If it does not exist, create it
0103                     GeoDataCoordinates coordinates( longitude, latitude, 0.0, GeoDataCoordinates::Degree );
0104 
0105                     PostalCodeItem *item = new PostalCodeItem( this );
0106                     item->setId( id );
0107                     item->setCoordinate( coordinates );
0108                     item->setToolTip( tooltip );
0109                     item->setText( postalCode );
0110 
0111                     items << item;
0112                 }
0113             }
0114         }
0115         addItemsToList( items );
0116     }
0117 }
0118 
0119 void PostalCodeModel::addLine(QString *string, const QString &line)
0120 {
0121     Q_ASSERT( string );
0122     if ( !line.isEmpty() ) {
0123         *string += line + QLatin1Char('\n');
0124     }
0125 }
0126 
0127 #include "moc_PostalCodeModel.cpp"