-
-
Notifications
You must be signed in to change notification settings - Fork 366
/
Copy pathNameAndLocationLabel.kt
163 lines (143 loc) · 5.96 KB
/
NameAndLocationLabel.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package de.westnordost.streetcomplete.util
import android.content.res.Resources
import android.text.Html
import androidx.core.text.parseAsHtml
import de.westnordost.osmfeatures.FeatureDictionary
import de.westnordost.streetcomplete.R
import java.util.Locale
fun getNameAndLocationLabel(
tags: Map<String, String>,
resources: Resources,
featureDictionary: FeatureDictionary,
showHouseNumber: Boolean? = null
): CharSequence? {
val locales = getLocalesForFeatureDictionary(resources.configuration)
val feature = getFeatureName(tags, featureDictionary, locales)
?.withNonBreakingSpaces()
?.inItalics()
val name = getNameLabel(tags)
?.withNonBreakingSpaces()
?.inBold()
val nameAndFeatureName = if (name != null && feature != null) {
resources.getString(R.string.label_name_feature, name, feature)
} else {
name ?: feature
}
// only show house number if there is no name information
val location = getLocationHtml(tags, resources, showHouseNumber =
if (showHouseNumber == null && nameAndFeatureName != null) false else showHouseNumber
)
val label = if (nameAndFeatureName != null && location != null) {
resources.getString(R.string.label_location_name, location, nameAndFeatureName)
} else {
location ?: nameAndFeatureName
}
return label?.parseAsHtml()
}
/** Returns a text that describes its location, e.g. "house number 123 - on floor 5" */
fun getLocationLabel(
tags: Map<String, String>,
resources: Resources,
showHouseNumber: Boolean? = null
): CharSequence? =
getLocationHtml(tags, resources, showHouseNumber)?.parseAsHtml()
private fun getLocationHtml(
tags: Map<String, String>,
resources: Resources,
showHouseNumber: Boolean? = null
): String? {
val level = getLevelLabel(tags, resources)
// by default only show house number if no level is given
val houseNumber = if (showHouseNumber ?: (level == null)) getHouseNumberHtml(tags, resources) else null
return if (level != null && houseNumber != null) {
resources.getString(R.string.label_housenumber_location, houseNumber, level)
} else {
level ?: houseNumber
}
}
/** Returns the feature name only, e.g. "Bakery" */
private fun getFeatureName(
tags: Map<String, String>,
featureDictionary: FeatureDictionary,
locales: Array<Locale?>
): String? = featureDictionary
.byTags(tags)
// not for geometry because at this point we cannot tell apart points and vertices
// .forGeometry(element?.geometryType)
.isSuggestion(false)
.forLocale(*locales)
.find()
.firstOrNull()
?.name
/** Returns a text that identifies the feature by name, ref, brand or whatever, e.g. "The Leaky Cauldron" */
fun getNameLabel(tags: Map<String, String>): String? {
val name = tags["name"]
val brand = tags["brand"]
val localRef = tags["local_ref"]
val ref = tags["ref"]
val operator = tags["operator"]
// Favour local ref over ref as it's likely to be more local/visible, e.g. bus stop point versus text code
return if (name != null && localRef != null) "$name ($localRef)" else null
?: name
?: brand
?: if (localRef != null && operator != null) "$operator ($localRef)" else null
?: if (ref != null && operator != null) "$operator [$ref]" else null
?: operator
?: localRef
?: ref
}
/** Returns a text that describes the floor / level, e.g. "on floor 5" */
fun getLevelLabel(tags: Map<String, String>, resources: Resources): String? {
/* distinguish between "floor" and "level":
E.g. addr:floor may be "M" while level is "2". The "2" is in this case purely technical and
can not be seen on any sign. */
val floor = tags["addr:floor"] ?: tags["level:ref"]
if (floor != null) {
return resources.getString(R.string.on_floor, floor)
}
val level = tags["level"]
if (level != null) {
return resources.getString(R.string.on_level, level)
}
if (tags["tunnel"] == "yes" || tags["tunnel"] == "culvert" || tags["location"] == "underground") {
return resources.getString(R.string.underground)
}
return null
}
/** Returns a text that describes the house number, e.g. "house number 123" */
fun getHouseNumberLabel(tags: Map<String, String>, resources: Resources): CharSequence? =
getHouseNumberHtml(tags, resources)?.parseAsHtml()
private fun getHouseNumberHtml(tags: Map<String, String>, resources: Resources): String? {
val houseName = tags["addr:housename"]
val conscriptionNumber = tags["addr:conscriptionnumber"]
val streetNumber = tags["addr:streetnumber"]
val houseNumber = tags["addr:housenumber"]
if (houseName != null) {
return resources.getString(R.string.at_housename, houseName.inItalics())
}
if (conscriptionNumber != null) {
val number = if (streetNumber != null) "$conscriptionNumber/$streetNumber" else conscriptionNumber
return resources.getString(R.string.at_housenumber, number)
}
if (houseNumber != null) {
return resources.getString(R.string.at_housenumber, houseNumber)
}
return null
}
/** Returns just the house number as it would be signed if set, e.g. "123" */
fun getShortHouseNumber(map: Map<String, String>): String? {
val houseName = map["addr:housename"]
val conscriptionNumber = map["addr:conscriptionnumber"]
val streetNumber = map["addr:streetnumber"]
val houseNumber = map["addr:housenumber"]
return when {
houseName != null -> houseName
conscriptionNumber != null && streetNumber != null -> "$conscriptionNumber / $streetNumber"
conscriptionNumber != null -> conscriptionNumber
houseNumber != null -> houseNumber
else -> null
}
}
private fun String.inBold(): String = "<b>${Html.escapeHtml(this)}</b>"
private fun String.inItalics(): String = "<i>${Html.escapeHtml(this)}</i>"
private fun String.withNonBreakingSpaces(): String = replace(' ', ' ')