Marble

GeoDataBuilding.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2017 Mohammed Nafees <[email protected]>
4 //
5 
6 #include "GeoDataBuilding.h"
7 #include "GeoDataBuilding_p.h"
8 #include "GeoDataTypes.h"
9 
10 namespace Marble {
11 
12 GeoDataBuilding::GeoDataBuilding()
13  : GeoDataGeometry(new GeoDataBuildingPrivate),
14  d(new GeoDataBuildingPrivate)
15 {
16 }
17 
18 GeoDataBuilding::GeoDataBuilding(const GeoDataGeometry &other)
19  : GeoDataGeometry(other),
20  d(new GeoDataBuildingPrivate)
21 {
22 }
23 
24 GeoDataBuilding::GeoDataBuilding(const GeoDataBuilding &other)
25  : GeoDataGeometry(other),
26  d(new GeoDataBuildingPrivate(*other.d))
27 {
28 }
29 
31 {
32  delete d;
33 }
34 
35 GeoDataBuilding& GeoDataBuilding::operator=(const GeoDataBuilding& other)
36 {
37  GeoDataGeometry::operator=(other);
38  *d = *other.d;
39  return *this;
40 }
41 
42 const char *GeoDataBuilding::nodeType() const
43 {
44  return GeoDataTypes::GeoDataBuildingType;
45 }
46 
47 EnumGeometryId GeoDataBuilding::geometryId() const
48 {
49  return GeoDataBuildingId;
50 }
51 
52 GeoDataGeometry *GeoDataBuilding::copy() const
53 {
54  return new GeoDataBuilding(*this);
55 }
56 
58 {
59  return d->m_height;
60 }
61 
62 void GeoDataBuilding::setHeight(double height)
63 {
64  d->m_height = height;
65 }
66 
68 {
69  return d->m_minLevel;
70 }
71 
72 void GeoDataBuilding::setMinLevel(int minLevel)
73 {
74  d->m_minLevel = minLevel;
75 }
76 
78 {
79  return d->m_maxLevel;
80 }
81 
82 void GeoDataBuilding::setMaxLevel(int maxLevel)
83 {
84  d->m_maxLevel = maxLevel;
85 }
86 
88 {
89  return d->m_nonExistentLevels;
90 }
91 
93 {
94  d->m_nonExistentLevels = nonExistentLevels;
95 }
96 
98 {
99  return &d->m_multiGeometry;
100 }
101 
103 {
104  // @TODO: This is temporary, for only when we have just one child
105  Q_ASSERT(d->m_multiGeometry.size() == 1);
106  return static_cast<const GeoDataMultiGeometry>(d->m_multiGeometry).at(0).latLonAltBox();
107 }
108 
110 {
111  return d->m_name;
112 }
113 
115 {
116  d->m_name = name;
117 }
118 
119 QVector<GeoDataBuilding::NamedEntry> GeoDataBuilding::entries() const
120 {
121  return d->m_entries;
122 }
123 
124 void GeoDataBuilding::setEntries(const QVector<GeoDataBuilding::NamedEntry> &entries)
125 {
126  d->m_entries = entries;
127 }
128 
129 double GeoDataBuilding::parseBuildingHeight(const QString& buildingHeight)
130 {
131  double height = 8.0;
132 
133  // check first for unitless value
134  bool converted;
135  double extractedHeight = buildingHeight.toDouble(&converted);
136  if (converted) {
137  return extractedHeight;
138  }
139 
140  if (buildingHeight.endsWith(QChar('m')) ||
141  buildingHeight.endsWith(QLatin1String("meter")) ||
142  buildingHeight.endsWith(QLatin1String("meters")) ||
143  buildingHeight.endsWith(QLatin1String("metre")) ||
144  buildingHeight.endsWith(QLatin1String("metres"))) {
145  QString const heightValue = QString(buildingHeight).remove(QStringLiteral("meters"))
146  .remove(QStringLiteral("meter")).remove(QStringLiteral("metres"))
147  .remove(QStringLiteral("metre")).remove(QChar('m')).trimmed();
148  bool extracted;
149  double extractedHeight = heightValue.toDouble(&extracted);
150  if (extracted) {
151  height = extractedHeight;
152  }
153  } else { // feet and inches
154  double extractedHeight = 0.0; // in inches, converted to meters in the end
155  if (buildingHeight.contains(QChar('\''))) {
156  double heightInches = 0.0;
157  QStringList const feetInches = buildingHeight.split(QChar('\''));
158  bool okFeet;
159  double feet = feetInches[0].trimmed().toDouble(&okFeet);
160  if (okFeet) {
161  heightInches = feet * FT2IN;
162  }
163  if (!feetInches[1].isEmpty()) { // has inches as unit as well
164  bool okInches;
165  double inches = QString(feetInches[1]).remove(QChar('\"')).trimmed().toDouble(&okInches);
166  if (okInches) {
167  heightInches += inches;
168  }
169  }
170  extractedHeight = heightInches;
171  } else if (buildingHeight.endsWith(QLatin1String("feet"))) {
172  bool ok;
173  double feet = QString(buildingHeight).remove(QStringLiteral("feet")).trimmed().toDouble(&ok);
174  if (ok) {
175  extractedHeight = feet * FT2IN;
176  }
177  }
178  if (extractedHeight > 0.0) {
179  height = extractedHeight * IN2M; // convert inches to meters
180  }
181  }
182 
183  return height;
184 }
185 
186 }
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
A class that defines a 3D bounding box for geographic data.
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QString trimmed() const const
void setHeight(double height)
void setNonExistentLevels(const QVector< int > &nonExistentLevels)
GeoDataMultiGeometry * multiGeometry() const
const GeoDataLatLonAltBox & latLonAltBox() const override
Binds a QML item to a specific geodetic location in screen coordinates.
double toDouble(bool *ok) const const
QString & remove(int position, int n)
void setName(const QString &name)
void setMinLevel(int minLevel)
const char * nodeType() const override
Provides type information for downcasting a GeoNode.
QVector< int > nonExistentLevels() const
void setMaxLevel(int maxLevel)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
A class that can contain other GeoDataGeometry objects.
Contains important information about a building and its floors (levels)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Sep 25 2023 03:50:18 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.