File indexing completed on 2025-01-05 03:58:53
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(QLatin1Char('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(QLatin1Char('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(QLatin1Char('\''))) { 0156 double heightInches = 0.0; 0157 QStringList const feetInches = buildingHeight.split(QLatin1Char('\'')); 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(QLatin1Char('\"')).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 }