diff options
Diffstat (limited to 'src/positioning/qgeoaddress.cpp')
-rw-r--r-- | src/positioning/qgeoaddress.cpp | 637 |
1 files changed, 637 insertions, 0 deletions
diff --git a/src/positioning/qgeoaddress.cpp b/src/positioning/qgeoaddress.cpp new file mode 100644 index 00000000..b62e3431 --- /dev/null +++ b/src/positioning/qgeoaddress.cpp @@ -0,0 +1,637 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtPositioning module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgeoaddress.h" +#include "qgeoaddress_p.h" + +#include <QtCore/QStringList> + +#ifdef QGEOADDRESS_DEBUG +#include <QDebug> +#endif + +QT_BEGIN_NAMESPACE + +/* + Combines a list of address parts into a single line. + + The parts parameter contains both address elements such as city, state and so on + as well as separators such as spaces and commas. + + It is expected that an element is always followed by a separator and the last + sepator is usually a new line delimeter. + + For example: Springfield, 8900 + would have four parts + ["Springfield", ", ", "8900", "<br>"] + + The addressLine takes care of putting in separators appropriately or leaving + them out depending on whether the adjacent elements are present or not. + For example if city were empty in the above scenario the returned string is "8900<br>" + If the postal code was empty, returned string is "Springfield<br>" + If both city and postal code were empty, the returned string is "". +*/ +static QString addressLine(const QStringList &parts) +{ + QString line; + Q_ASSERT(parts.count() % 2 == 0); + + //iterate until just before the last pair + QString penultimateSeparator; + for (int i = 0; i < parts.count() - 2; i += 2) { + if (!parts.at(i).isEmpty()) { + line.append(parts.at(i) + parts.at(i + 1)); + penultimateSeparator = parts.at(i + 1); + } + } + + if (parts.at(parts.count() - 2).isEmpty()) { + line.chop(penultimateSeparator.length()); + + if (!line.isEmpty()) + line.append(parts.at(parts.count() - 1)); + } else { + line.append(parts.at(parts.count() - 2)); + line.append(parts.at(parts.count() - 1)); + } + + return line; +} + +/* + Returns a single formatted string representing the \a address. Lines of the address + are delimited by \a newLine. By default lines are delimited by <br/>. The \l + {QGeoAddress::countryCode} {countryCode} of the \a address determines the format of + the resultant string. +*/ +static QString formattedAddress(const QGeoAddress &address, + const QString &newLine = QLatin1String("<br/>")) +{ + const QString Comma(QLatin1String(", ")); + const QString Dash(QLatin1String("-")); + const QString Space(QLatin1String(" ")); + + QString text; + + if (address.countryCode() == QLatin1String("ALB") + || address.countryCode() == QLatin1String("MTQ")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.postalCode() << Comma + << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("AND") + || address.countryCode() == QLatin1String("AUT") + || address.countryCode() == QLatin1String("FRA") + || address.countryCode() == QLatin1String("GLP") + || address.countryCode() == QLatin1String("GUF") + || address.countryCode() == QLatin1String("ITA") + || address.countryCode() == QLatin1String("LUX") + || address.countryCode() == QLatin1String("MCO") + || address.countryCode() == QLatin1String("REU") + || address.countryCode() == QLatin1String("RUS") + || address.countryCode() == QLatin1String("SMR") + || address.countryCode() == QLatin1String("VAT")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space + << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("ARE") + || address.countryCode() == QLatin1String("BHS")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Space + << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("AUS")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << (address.district().isEmpty() ? address.city() : address.district()) + << Space << address.state() << Space << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("BHR")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Comma + << address.city() << Comma << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("BRA")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Space + << address.city() << Dash << address.state() << Space << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("BRN") + || address.countryCode() == QLatin1String("JOR") + || address.countryCode() == QLatin1String("LBN") + || address.countryCode() == QLatin1String("NZL")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Space + << address.city() << Space << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("CAN") + || address.countryCode() == QLatin1String("USA") + || address.countryCode() == QLatin1String("VIR")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.city() << Comma << address.state() << Space + << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("CHN")) { + text += addressLine(QStringList() << address.street() << Comma << address.city() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("CHL")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space + << address.district() << Comma << address.city() << Comma + << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("CYM")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.state() << Space + << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("GBR")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Comma + << address.city() << Comma << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("GIB")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("HKG")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << newLine); + text += addressLine(QStringList() << address.city() << newLine); + } else if (address.countryCode() == QLatin1String("IND")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.city() << Space << address.postalCode() << Space + << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("IDN") + || address.countryCode() == QLatin1String("JEY") + || address.countryCode() == QLatin1String("LVA")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.city() << Comma << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("IRL")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Comma << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("KWT")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.postalCode() << Comma + << address.district() << Comma << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("MLT") + || address.countryCode() == QLatin1String("SGP") + || address.countryCode() == QLatin1String("UKR")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.city() << Space << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("MEX")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space << address.city() << Comma + << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("MYS")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space << address.city() << newLine); + text += addressLine(QStringList() << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("OMN")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Comma + << address.postalCode() << Comma + << address.city() << Comma + << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("PRI")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Comma << address.city() << Comma + << address.state() << Comma << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("QAT")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Space << address.city() << Comma + << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("SAU")) { + text += addressLine(QStringList() << address.street() << Space << address.district() << newLine); + text += addressLine(QStringList() << address.city() << Space << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("TWN")) { + text += addressLine(QStringList() << address.street() << Comma + << address.district() << Comma << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("THA")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Comma << address.city() << Space + << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("TUR")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space << address.district() << Comma + << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("VEN")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.city() << Space << address.postalCode() << Comma + << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("ZAF")) { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Comma << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else { + text += addressLine(QStringList() << address.street() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } + + text.chop(newLine.length()); + return text; +} + +QGeoAddressPrivate::QGeoAddressPrivate() + : QSharedData(), + m_autoGeneratedText(false) +{ +} + +QGeoAddressPrivate::QGeoAddressPrivate(const QGeoAddressPrivate &other) + : QSharedData(other), + sCountry(other.sCountry), + sCountryCode(other.sCountryCode), + sState(other.sState), + sCounty(other.sCounty), + sCity(other.sCity), + sDistrict(other.sDistrict), + sStreet(other.sStreet), + sPostalCode(other.sPostalCode), + sText(other.sText), + m_autoGeneratedText(false) +{ +} + +QGeoAddressPrivate::~QGeoAddressPrivate() +{ +} + +/*! + \class QGeoAddress + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \ingroup QtLocation-places-data + \ingroup QtLocation-places + \since Qt Positioning 5.0 + + \brief The QGeoAddress class represents an address of a \l QGeoLocation. + + The address' attributes are normalized to US feature names and can be mapped + to the local feature levels (for example State matches "Bundesland" in Germany). + + The address contains a \l text() for displaying purposes and additional + properties to access the components of an address: + + \list + \li QGeoAddress::country() + \li QGeoAddress::countryCode() + \li QGeoAddress::state() + \li QGeoAddress::city() + \li QGeoAddress::district() + \li QGeoAddress::street() + \li QGeoAddress::postalCode() + \endlist +*/ + +/*! + Default constructor. +*/ +QGeoAddress::QGeoAddress() + : d(new QGeoAddressPrivate) +{ +} + +/*! + Constructs a copy of \a other. +*/ +QGeoAddress::QGeoAddress(const QGeoAddress &other) + : d(other.d) +{ +} + +/*! + Destroys this address. +*/ +QGeoAddress::~QGeoAddress() +{ +} + +/*! + Assigns the given \a address to this address and + returns a reference to this address. +*/ +QGeoAddress &QGeoAddress::operator=(const QGeoAddress & address) +{ + if (this == &address) + return *this; + + d = address.d; + return *this; +} + +/*! + Returns true if this address is equal to \a other, + otherwise returns false. +*/ +bool QGeoAddress::operator==(const QGeoAddress &other) const +{ +#ifdef QGEOADDRESS_DEBUG + qDebug() << "country" << (d->sCountry == other.country()); + qDebug() << "countryCode" << (d->sCountryCode == other.countryCode()); + qDebug() << "state:" << (d->sState == other.state()); + qDebug() << "county:" << (d->sCounty == other.county()); + qDebug() << "city:" << (d->sCity == other.city()); + qDebug() << "district:" << (d->sDistrict == other.district()); + qDebug() << "street:" << (d->sStreet == other.street()); + qDebug() << "postalCode:" << (d->sPostalCode == other.postalCode()); + qDebug() << "text:" << (text() == other.text()); +#endif + + return d->sCountry == other.country() && + d->sCountryCode == other.countryCode() && + d->sState == other.state() && + d->sCounty == other.county() && + d->sCity == other.city() && + d->sDistrict == other.district() && + d->sStreet == other.street() && + d->sPostalCode == other.postalCode() && + this->text() == other.text(); +} + +/*! + \fn bool QGeoAddress::operator!=(const QGeoAddress &other) const + + Returns true if this address is not equal to \a other, + otherwise returns false. +*/ + +/*! + Returns the address as a single formatted string. It is the recommended string + to use to display the address to the user. It typically takes the format of + an address as found on an envelope, but this is not always necessarily the case. + + The adddress text is either automatically generated or explicitly assigned. + This can be determined by checking \l {QGeoAddress::isTextGenerated()} {isTextGenerated}. + + If an empty string is provided to setText(), then isTextGenerated() will be set + to true and text() will return a string which is locally formatted according to + countryCode() and based on the elements of the address such as street, city and so on. + Because the text string is generated from the address elements, a sequence + of calls such as text(), setStreet(), text() may return different strings for each + invocation of text(). + + If a non-empty string is provided to setText(), then isTextGenerated() will be + set to false and text() will always return the explicitly assigned string. + Calls to modify other elements such as setStreet(), setCity() and so on will not + affect the resultant string from text(). +*/ +QString QGeoAddress::text() const +{ + if (d->sText.isEmpty()) + return formattedAddress(*this); + else + return d->sText; +} + +/*! + If \a text is not empty, explicitly assigns \a text as the string to be returned by + text(). isTextGenerated() will return false. + + If \a text is empty, indicates that text() should be automatically generated + from the address elements. isTextGenerated() will return true. +*/ +void QGeoAddress::setText(const QString &text) +{ + d->sText = text; +} + +/*! + Returns the country name. +*/ +QString QGeoAddress::country() const +{ + return d->sCountry; +} + +/*! + Sets the \a country name. +*/ +void QGeoAddress::setCountry(const QString &country) +{ + d->sCountry = country; +} + +/*! + Returns the country code according to ISO 3166-1 alpha-3 +*/ +QString QGeoAddress::countryCode() const +{ + return d->sCountryCode; +} + +/*! + Sets the \a countryCode according to ISO 3166-1 alpha-3 +*/ +void QGeoAddress::setCountryCode(const QString &countryCode) +{ + d->sCountryCode = countryCode; +} + +/*! + Returns the state. The state is considered the first subdivision below country. +*/ +QString QGeoAddress::state() const +{ + return d->sState; +} + +/*! + Sets the \a state. +*/ +void QGeoAddress::setState(const QString &state) +{ + d->sState = state; +} + +/*! + Returns the county. The county is considered the second subdivision below country. +*/ +QString QGeoAddress::county() const +{ + return d->sCounty; +} + +/*! + Sets the \a county. +*/ +void QGeoAddress::setCounty(const QString &county) +{ + d->sCounty = county; +} + +/*! + Returns the city. +*/ +QString QGeoAddress::city() const +{ + return d->sCity; +} + +/*! + Sets the \a city. +*/ +void QGeoAddress::setCity(const QString &city) +{ + d->sCity = city; +} + +/*! + Returns the district. The district is considered the subdivison below city. +*/ +QString QGeoAddress::district() const +{ + return d->sDistrict; +} + +/*! + Sets the \a district. +*/ +void QGeoAddress::setDistrict(const QString &district) +{ + d->sDistrict = district; +} + +/*! + Returns the street-level component of the address. + + This typically includes a street number and street name + but may also contain things like a unit number, a building + name, or anything else that might be used to + distinguish one address from another. +*/ +QString QGeoAddress::street() const +{ + return d->sStreet; +} + +/*! + Sets the street-level component of the address to \a street. + + This typically includes a street number and street name + but may also contain things like a unit number, a building + name, or anything else that might be used to + distinguish one address from another. +*/ +void QGeoAddress::setStreet(const QString &street) +{ + d->sStreet = street; +} + +/*! + Returns the postal code. +*/ +QString QGeoAddress::postalCode() const +{ + return d->sPostalCode; +} + +/*! + Sets the \a postalCode. +*/ +void QGeoAddress::setPostalCode(const QString &postalCode) +{ + d->sPostalCode = postalCode; +} + +/*! + Returns whether this address is empty. An address is considered empty + if \e all of its fields are empty. +*/ +bool QGeoAddress::isEmpty() const +{ + return d->sCountry.isEmpty() && + d->sCountryCode.isEmpty() && + d->sState.isEmpty() && + d->sCounty.isEmpty() && + d->sCity.isEmpty() && + d->sDistrict.isEmpty() && + d->sStreet.isEmpty() && + d->sPostalCode.isEmpty() && + d->sText.isEmpty(); + +} + +/*! + Clears all of the address' data fields. +*/ +void QGeoAddress::clear() +{ + d->sCountry.clear(); + d->sCountryCode.clear(); + d->sState.clear(); + d->sCounty.clear(); + d->sCity.clear(); + d->sDistrict.clear(); + d->sStreet.clear(); + d->sPostalCode.clear(); + d->sText.clear(); +} + +/*! + Returns true if QGeoAddress::text() is automatically generated from address elements, + otherwise returns false if text() has been explicitly assigned. + + \sa text(), setText() +*/ +bool QGeoAddress::isTextGenerated() const +{ + return d->sText.isEmpty(); +} + +QT_END_NAMESPACE + |