Changeset View
Changeset View
Standalone View
Standalone View
src/plugins/runner/osm/OsmWay.cpp
Context not available. | |||||
18 | #include <osm/OsmObjectManager.h> | 18 | #include <osm/OsmObjectManager.h> | ||
---|---|---|---|---|---|
19 | #include <MarbleDirs.h> | 19 | #include <MarbleDirs.h> | ||
20 | #include <StyleBuilder.h> | 20 | #include <StyleBuilder.h> | ||
21 | #include <GeoDataMultiGeometry.h> | ||||
21 | 22 | | |||
22 | namespace Marble { | 23 | namespace Marble { | ||
23 | 24 | | |||
24 | QSet<StyleBuilder::OsmTag> OsmWay::s_areaTags; | 25 | QSet<StyleBuilder::OsmTag> OsmWay::s_areaTags; | ||
26 | QSet<StyleBuilder::OsmTag> OsmWay::s_buildingTags; | ||||
25 | 27 | | |||
26 | GeoDataPlacemark *OsmWay::create(const OsmNodes &nodes, QSet<qint64> &usedNodes) const | 28 | GeoDataPlacemark *OsmWay::create(const OsmNodes &nodes, QSet<qint64> &usedNodes) const | ||
27 | { | 29 | { | ||
Context not available. | |||||
45 | usedNodes << nodeId; | 47 | usedNodes << nodeId; | ||
46 | } | 48 | } | ||
47 | 49 | | |||
48 | geometry = new GeoDataLinearRing(linearRing.optimized()); | 50 | if (isBuilding()) { | ||
51 | GeoDataBuilding building; | ||||
52 | building.setName(extractBuildingName()); | ||||
53 | building.setHeight(extractBuildingHeight()); | ||||
54 | building.setEntries(extractNamedEntries()); | ||||
55 | building.multiGeometry()->append(new GeoDataLinearRing(linearRing.optimized())); | ||||
56 | | ||||
57 | geometry = new GeoDataBuilding(building); | ||||
58 | } else { | ||||
59 | geometry = new GeoDataLinearRing(linearRing.optimized()); | ||||
60 | } | ||||
49 | } else { | 61 | } else { | ||
50 | GeoDataLineString lineString; | 62 | GeoDataLineString lineString; | ||
51 | lineString.reserve(m_references.size()); | 63 | lineString.reserve(m_references.size()); | ||
Context not available. | |||||
189 | return s_areaTags.contains(keyValue); | 201 | return s_areaTags.contains(keyValue); | ||
190 | } | 202 | } | ||
191 | 203 | | |||
204 | bool OsmWay::isBuilding() const | ||||
205 | { | ||||
206 | for (auto iter = m_osmData.tagsBegin(), end=m_osmData.tagsEnd(); iter != end; ++iter) { | ||||
207 | const auto tag = StyleBuilder::OsmTag(iter.key(), iter.value()); | ||||
208 | if (isBuildingTag(tag)) { | ||||
209 | return true; | ||||
210 | } | ||||
211 | } | ||||
212 | | ||||
213 | return false; | ||||
214 | } | ||||
215 | | ||||
216 | bool OsmWay::isBuildingTag(const StyleBuilder::OsmTag &keyValue) | ||||
217 | { | ||||
218 | if (s_buildingTags.isEmpty()) { | ||||
219 | for (auto const & tag: StyleBuilder::buildingTags()) { | ||||
220 | s_buildingTags.insert(tag); | ||||
221 | } | ||||
222 | } | ||||
223 | | ||||
224 | return s_buildingTags.contains(keyValue); | ||||
225 | } | ||||
226 | | ||||
227 | QString OsmWay::extractBuildingName() const | ||||
228 | { | ||||
229 | auto tagIter = m_osmData.findTag(QStringLiteral("addr:housename")); | ||||
230 | if (tagIter != m_osmData.tagsEnd()) { | ||||
231 | return tagIter.value(); | ||||
232 | } | ||||
233 | | ||||
234 | tagIter = m_osmData.findTag(QStringLiteral("addr:housenumber")); | ||||
235 | if (tagIter != m_osmData.tagsEnd()) { | ||||
236 | return tagIter.value(); | ||||
237 | } | ||||
238 | | ||||
239 | return QString(); | ||||
240 | } | ||||
241 | | ||||
242 | double OsmWay::extractBuildingHeight() const | ||||
243 | { | ||||
244 | double height = 8.0; | ||||
245 | | ||||
246 | QHash<QString, QString>::const_iterator tagIter; | ||||
247 | if ((tagIter = m_osmData.findTag(QStringLiteral("height"))) != m_osmData.tagsEnd()) { | ||||
248 | height = GeoDataBuilding::parseBuildingHeight(tagIter.value()); | ||||
249 | } else if ((tagIter = m_osmData.findTag(QStringLiteral("building:levels"))) != m_osmData.tagsEnd()) { | ||||
250 | int const levels = tagIter.value().toInt(); | ||||
251 | int const skipLevels = m_osmData.tagValue(QStringLiteral("building:min_level")).toInt(); | ||||
252 | /** @todo Is 35 as an upper bound for the number of levels sane? */ | ||||
253 | height = 3.0 * qBound(1, 1+levels-skipLevels, 35); | ||||
254 | } | ||||
255 | | ||||
256 | return qBound(1.0, height, 1000.0); | ||||
257 | } | ||||
258 | | ||||
259 | QVector<GeoDataBuilding::NamedEntry> OsmWay::extractNamedEntries() const | ||||
260 | { | ||||
261 | QVector<GeoDataBuilding::NamedEntry> entries; | ||||
262 | | ||||
263 | const auto end = m_osmData.nodeReferencesEnd(); | ||||
264 | for (auto iter = m_osmData.nodeReferencesBegin(); iter != end; ++iter) { | ||||
265 | const auto tagIter = iter.value().findTag(QStringLiteral("addr:housenumber")); | ||||
266 | if (tagIter != iter.value().tagsEnd()) { | ||||
267 | GeoDataBuilding::NamedEntry entry; | ||||
268 | entry.point = iter.key(); | ||||
269 | entry.label = tagIter.value(); | ||||
270 | entries.push_back(entry); | ||||
271 | } | ||||
272 | } | ||||
273 | | ||||
274 | return entries; | ||||
275 | } | ||||
276 | | ||||
192 | } | 277 | } | ||
Context not available. |