File indexing completed on 2024-05-12 03:50:09

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2017 Mohammed Nafees <nafees.technocool@gmail.com>
0004 //
0005 
0006 #include "GeoDataBuilding.h"
0007 #include "GeoDataBuilding_p.h"
0008 #include "GeoDataTypes.h"
0009 
0010 namespace Marble {
0011 
0012 GeoDataBuilding::GeoDataBuilding()
0013     : GeoDataGeometry(new GeoDataBuildingPrivate),
0014       d(new GeoDataBuildingPrivate)
0015 {
0016 }
0017 
0018 GeoDataBuilding::GeoDataBuilding(const GeoDataGeometry &other)
0019     : GeoDataGeometry(other),
0020       d(new GeoDataBuildingPrivate)
0021 {
0022 }
0023 
0024 GeoDataBuilding::GeoDataBuilding(const GeoDataBuilding &other)
0025     : GeoDataGeometry(other),
0026       d(new GeoDataBuildingPrivate(*other.d))
0027 {
0028 }
0029 
0030 GeoDataBuilding::~GeoDataBuilding()
0031 {
0032     delete d;
0033 }
0034 
0035 GeoDataBuilding& GeoDataBuilding::operator=(const GeoDataBuilding& other)
0036 {
0037     GeoDataGeometry::operator=(other);
0038     *d = *other.d;
0039     return *this;
0040 }
0041 
0042 const char *GeoDataBuilding::nodeType() const
0043 {
0044     return GeoDataTypes::GeoDataBuildingType;
0045 }
0046 
0047 EnumGeometryId GeoDataBuilding::geometryId() const
0048 {
0049     return GeoDataBuildingId;
0050 }
0051 
0052 GeoDataGeometry *GeoDataBuilding::copy() const
0053 {
0054     return new GeoDataBuilding(*this);
0055 }
0056 
0057 double GeoDataBuilding::height() const
0058 {
0059     return d->m_height;
0060 }
0061 
0062 void GeoDataBuilding::setHeight(double height)
0063 {
0064     d->m_height = height;
0065 }
0066 
0067 int GeoDataBuilding::minLevel() const
0068 {
0069     return d->m_minLevel;
0070 }
0071 
0072 void GeoDataBuilding::setMinLevel(int minLevel)
0073 {
0074     d->m_minLevel = minLevel;
0075 }
0076 
0077 int GeoDataBuilding::maxLevel() const
0078 {
0079     return d->m_maxLevel;
0080 }
0081 
0082 void GeoDataBuilding::setMaxLevel(int maxLevel)
0083 {
0084     d->m_maxLevel = maxLevel;
0085 }
0086 
0087 QVector<int> GeoDataBuilding::nonExistentLevels() const
0088 {
0089     return d->m_nonExistentLevels;
0090 }
0091 
0092 void GeoDataBuilding::setNonExistentLevels(const QVector<int> &nonExistentLevels)
0093 {
0094     d->m_nonExistentLevels = nonExistentLevels;
0095 }
0096 
0097 GeoDataMultiGeometry* GeoDataBuilding::multiGeometry() const
0098 {
0099     return &d->m_multiGeometry;
0100 }
0101 
0102 const GeoDataLatLonAltBox &GeoDataBuilding::latLonAltBox() const
0103 {
0104     // @TODO: This is temporary, for only when we have just one child
0105     Q_ASSERT(d->m_multiGeometry.size() == 1);
0106     return static_cast<const GeoDataMultiGeometry>(d->m_multiGeometry).at(0).latLonAltBox();
0107 }
0108 
0109 QString GeoDataBuilding::name() const
0110 {
0111     return d->m_name;
0112 }
0113 
0114 void GeoDataBuilding::setName(const QString& name)
0115 {
0116     d->m_name = name;
0117 }
0118 
0119 QVector<GeoDataBuilding::NamedEntry> GeoDataBuilding::entries() const
0120 {
0121     return d->m_entries;
0122 }
0123 
0124 void GeoDataBuilding::setEntries(const QVector<GeoDataBuilding::NamedEntry> &entries)
0125 {
0126     d->m_entries = entries;
0127 }
0128 
0129 double GeoDataBuilding::parseBuildingHeight(const QString& buildingHeight)
0130 {
0131     double height = 8.0;
0132 
0133     // check first for unitless value
0134     bool converted;
0135     double extractedHeight = buildingHeight.toDouble(&converted);
0136     if (converted) {
0137         return extractedHeight;
0138     }
0139 
0140     if (buildingHeight.endsWith(QChar('m')) ||
0141         buildingHeight.endsWith(QLatin1String("meter")) ||
0142         buildingHeight.endsWith(QLatin1String("meters")) ||
0143         buildingHeight.endsWith(QLatin1String("metre")) ||
0144         buildingHeight.endsWith(QLatin1String("metres"))) {
0145         QString const heightValue = QString(buildingHeight).remove(QStringLiteral("meters"))
0146                 .remove(QStringLiteral("meter")).remove(QStringLiteral("metres"))
0147                 .remove(QStringLiteral("metre")).remove(QChar('m')).trimmed();
0148         bool extracted;
0149         double extractedHeight = heightValue.toDouble(&extracted);
0150         if (extracted) {
0151             height = extractedHeight;
0152         }
0153     } else { // feet and inches
0154         double extractedHeight = 0.0; // in inches, converted to meters in the end
0155         if (buildingHeight.contains(QChar('\''))) {
0156             double heightInches = 0.0;
0157             QStringList const feetInches = buildingHeight.split(QChar('\''));
0158             bool okFeet;
0159             double feet = feetInches[0].trimmed().toDouble(&okFeet);
0160             if (okFeet) {
0161                 heightInches = feet * FT2IN;
0162             }
0163             if (!feetInches[1].isEmpty()) { // has inches as unit as well
0164                 bool okInches;
0165                 double inches = QString(feetInches[1]).remove(QChar('\"')).trimmed().toDouble(&okInches);
0166                 if (okInches) {
0167                     heightInches += inches;
0168                 }
0169             }
0170             extractedHeight = heightInches;
0171         } else if (buildingHeight.endsWith(QLatin1String("feet"))) {
0172             bool ok;
0173             double feet = QString(buildingHeight).remove(QStringLiteral("feet")).trimmed().toDouble(&ok);
0174             if (ok) {
0175                 extractedHeight = feet * FT2IN;
0176             }
0177         }
0178         if (extractedHeight > 0.0) {
0179             height = extractedHeight * IN2M; // convert inches to meters
0180         }
0181     }
0182 
0183     return height;
0184 }
0185 
0186 }