Skip to content

Commit

Permalink
migrate to osmfeatures 6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
westnordost committed May 15, 2024
1 parent 1a09d01 commit c455a81
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 90 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ dependencies {
// finding in which country we are for country-specific logic
implementation("de.westnordost:countryboundaries:2.1")
// finding a name for a feature without a name tag
implementation("de.westnordost:osmfeatures-android:5.2")
implementation("de.westnordost:osmfeatures:6.0")
// talking with the OSM API
implementation("de.westnordost:osmapi-map:3.0")
implementation("de.westnordost:osmapi-changesets:3.0")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package de.westnordost.streetcomplete.util
import android.content.res.Configuration
import android.content.res.Resources
import androidx.test.platform.app.InstrumentationRegistry
import de.westnordost.osmfeatures.AndroidFeatureDictionary
import de.westnordost.osmfeatures.FeatureDictionary
import de.westnordost.osmfeatures.create
import de.westnordost.streetcomplete.data.osm.mapdata.LatLon
import de.westnordost.streetcomplete.data.osm.mapdata.Node
import de.westnordost.streetcomplete.data.osm.mapdata.Way
Expand All @@ -19,7 +19,7 @@ class NameAndLocationLabelTest {

init {
val context = InstrumentationRegistry.getInstrumentation().targetContext
featureDictionary = AndroidFeatureDictionary.create(context.assets, "osmfeatures/default", "osmfeatures/brands")
featureDictionary = FeatureDictionary.create(context.assets, "osmfeatures/default", "osmfeatures/brands")

val conf = Configuration(context.resources.configuration)
conf.setLocale(Locale.ENGLISH)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package de.westnordost.streetcomplete.data.meta

import android.content.res.AssetManager
import de.westnordost.countryboundaries.CountryBoundaries
import de.westnordost.osmfeatures.AndroidFeatureDictionary
import de.westnordost.osmfeatures.FeatureDictionary
import de.westnordost.osmfeatures.create
import org.koin.core.qualifier.named
import org.koin.dsl.module

Expand All @@ -17,7 +17,7 @@ val metadataModule = module {
}
single<Lazy<FeatureDictionary>>(named("FeatureDictionaryLazy")) {
lazy {
AndroidFeatureDictionary.create(get(), "osmfeatures/default", "osmfeatures/brands")
FeatureDictionary.create(get<AssetManager>(), "osmfeatures/default", "osmfeatures/brands")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import de.westnordost.streetcomplete.overlays.AbstractOverlayForm
import de.westnordost.streetcomplete.overlays.AnswerItem
import de.westnordost.streetcomplete.quests.LocalizedNameAdapter
import de.westnordost.streetcomplete.util.DummyFeature
import de.westnordost.streetcomplete.util.getLocalesForFeatureDictionary
import de.westnordost.streetcomplete.util.getLanguagesForFeatureDictionary
import de.westnordost.streetcomplete.util.getLocationLabel
import de.westnordost.streetcomplete.util.ktx.geometryType
import de.westnordost.streetcomplete.util.ktx.viewLifecycleScope
Expand Down Expand Up @@ -69,19 +69,18 @@ class PlacesOverlayForm : AbstractOverlayForm() {

val element = element
originalFeature = element?.let {
val locales = getLocalesForFeatureDictionary(resources.configuration)
val languages = getLanguagesForFeatureDictionary(resources.configuration)
val geometryType = if (element.type == ElementType.NODE) null else element.geometryType

if (element.isDisusedPlace()) {
featureDictionary.byId("shop/vacant").forLocale(*locales).get()
featureDictionary.getById("shop/vacant", languages = languages)
} else {
featureDictionary
.byTags(element.tags)
.forLocale(*locales)
.forGeometry(geometryType)
.inCountry(countryOrSubdivisionCode)
.find()
.firstOrNull()
featureDictionary.getByTags(
tags = element.tags,
languages = languages,
country = countryOrSubdivisionCode,
geometry = geometryType,
).firstOrNull()
// if not found anything in the iD presets, it's a shop type unknown to iD presets
?: DummyFeature(
"shop/unknown",
Expand Down Expand Up @@ -165,7 +164,7 @@ class PlacesOverlayForm : AbstractOverlayForm() {
featureCtrl.feature = feature
// clear (previous) names if selected feature contains already a name (i.e. is a brand feature)
// or is vacant
if (feature.addTags?.get("name") != null || feature.id == "shop/vacant") {
if (feature.addTags["name"] != null || feature.id == "shop/vacant") {
namesAdapter?.names = emptyList()
}

Expand All @@ -174,7 +173,7 @@ class PlacesOverlayForm : AbstractOverlayForm() {
}

private fun setVacant() {
onSelectedFeature(featureDictionary.byId("shop/vacant").get())
onSelectedFeature(featureDictionary.getById("shop/vacant")!!)
}

private fun createNoNameAnswer(): AnswerItem? =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import de.westnordost.streetcomplete.overlays.AbstractOverlayForm
import de.westnordost.streetcomplete.overlays.AnswerItem
import de.westnordost.streetcomplete.overlays.IAnswerItem
import de.westnordost.streetcomplete.util.LastPickedValuesStore
import de.westnordost.streetcomplete.util.getLocalesForFeatureDictionary
import de.westnordost.streetcomplete.util.getLanguagesForFeatureDictionary
import de.westnordost.streetcomplete.util.ktx.couldBeSteps
import de.westnordost.streetcomplete.util.ktx.valueOfOrNull
import de.westnordost.streetcomplete.view.setImage
Expand Down Expand Up @@ -142,9 +142,11 @@ class SurfaceOverlayForm : AbstractOverlayForm() {
switchToFootwayCyclewaySurfaceLayout()
}

val locales = getLocalesForFeatureDictionary(resources.configuration)
binding.cyclewaySurfaceLabel.text = featureDictionary.byId("highway/cycleway").forLocale(*locales).get()?.name
binding.footwaySurfaceLabel.text = featureDictionary.byId("highway/footway").forLocale(*locales).get()?.name
val languages = getLanguagesForFeatureDictionary(resources.configuration)
binding.cyclewaySurfaceLabel.text =
featureDictionary.getById("highway/cycleway", languages = languages)?.name
binding.footwaySurfaceLabel.text =
featureDictionary.getById("highway/footway", languages = languages)?.name

checkIsFormComplete()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import de.westnordost.streetcomplete.overlays.AbstractOverlayForm
import de.westnordost.streetcomplete.overlays.AnswerItem
import de.westnordost.streetcomplete.overlays.IAnswerItem
import de.westnordost.streetcomplete.util.DummyFeature
import de.westnordost.streetcomplete.util.getLocalesForFeatureDictionary
import de.westnordost.streetcomplete.util.getLanguagesForFeatureDictionary
import de.westnordost.streetcomplete.util.getNameAndLocationLabel
import de.westnordost.streetcomplete.util.ktx.geometryType
import de.westnordost.streetcomplete.view.controller.FeatureViewController
Expand Down Expand Up @@ -72,16 +72,15 @@ class ThingsOverlayForm : AbstractOverlayForm() {
}

private fun getFeatureDictionaryFeature(element: Element): Feature? {
val locales = getLocalesForFeatureDictionary(resources.configuration)
val languages = getLanguagesForFeatureDictionary(resources.configuration)
val geometryType = if (element.type == ElementType.NODE) null else element.geometryType

return featureDictionary
.byTags(element.tags)
.forLocale(*locales)
.forGeometry(geometryType)
.inCountry(countryOrSubdivisionCode)
.find()
.firstOrNull()
return featureDictionary.getByTags(
tags = element.tags,
languages = languages,
country = countryOrSubdivisionCode,
geometry = geometryType
).firstOrNull()
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,23 @@ import de.westnordost.osmfeatures.GeometryType
import java.util.Locale

data class DummyFeature(
private val id: String,
private val name: String,
private val icon: String,
private val addTags: Map<String, String>
override val id: String,
override val name: String,
override val icon: String?,
override val tags: Map<String, String>
) : Feature {
override fun getId() = id
override fun getTags() = addTags
override fun getGeometry() = listOf(GeometryType.POINT, GeometryType.AREA)
override fun getName() = name
override fun getIcon() = icon
override fun getImageURL() = null
override fun getNames() = listOf(name)
override fun getTerms() = emptyList<String>()
override fun getIncludeCountryCodes() = emptyList<String>()
override fun getExcludeCountryCodes() = emptyList<String>()
override fun isSearchable() = false
override fun getMatchScore() = 1.0
override fun getAddTags() = addTags
override fun getRemoveTags() = emptyMap<String, String>()
override fun getCanonicalNames() = emptyList<String>()
override fun getCanonicalTerms() = emptyList<String>()
override fun isSuggestion() = false
override fun getLocale(): Locale = Locale.getDefault()
override val geometry = listOf(GeometryType.POINT, GeometryType.AREA)
override val imageURL = null
override val names = listOf(name)
override val terms = emptyList<String>()
override val includeCountryCodes = emptyList<String>()
override val excludeCountryCodes = emptyList<String>()
override val isSearchable = false
override val matchScore = 1.0f
override val addTags = tags
override val removeTags = emptyMap<String, String>()
override val canonicalNames = emptyList<String>()
override val canonicalTerms = emptyList<String>()
override val isSuggestion = false
override val language: String? = Locale.getDefault().toLanguageTag()
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@ package de.westnordost.streetcomplete.util
import android.content.res.Configuration
import androidx.core.os.ConfigurationCompat
import de.westnordost.streetcomplete.util.ktx.toList
import java.util.Locale

fun getLocalesForFeatureDictionary(configuration: Configuration): Array<Locale?> {
val result = ArrayList<Locale?>()
result.addAll(ConfigurationCompat.getLocales(configuration).toList())
fun getLanguagesForFeatureDictionary(configuration: Configuration): List<String?> {
val result = ArrayList<String?>()
result.addAll(ConfigurationCompat.getLocales(configuration).toList().map { it.toLanguageTag() } )

Check failure on line 9 in app/src/main/java/de/westnordost/streetcomplete/util/LanguagesForFeatureDictionary.kt

View workflow job for this annotation

GitHub Actions / Kotlin

Unexpected space after "}"
/* add fallback to English if (some) English is not part of the locale list already as the
fallback for text is also always English in this app (strings.xml) independent of, or rather
additionally to what is in the user's LocaleList. */
if (result.none { it?.language == Locale.ENGLISH.language }) {
result.add(Locale.ENGLISH)
if (result.none { it == "en" }) {
result.add("en")
}
// add null to allow unlocalized features
result.add(null)
return result.toTypedArray()
return result
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ fun getNameAndLocationLabel(
featureDictionary: FeatureDictionary?,
showHouseNumber: Boolean? = null
): CharSequence? {
val locales = getLocalesForFeatureDictionary(resources.configuration)
val languages = getLanguagesForFeatureDictionary(resources.configuration)
val feature = featureDictionary
?.getFeature(element, locales)
?.getFeature(element, languages)
?.name
?.withNonBreakingSpaces()
?.inItalics()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ import de.westnordost.osmfeatures.FeatureDictionary
import de.westnordost.osmfeatures.GeometryType
import de.westnordost.streetcomplete.data.osm.mapdata.Element
import de.westnordost.streetcomplete.data.osm.mapdata.ElementType
import java.util.Locale

fun FeatureDictionary.getFeature(
element: Element,
locales: Array<Locale?>? = null,
languages: List<String?>? = null,
): Feature? {
// only if geometry is not a node because at this point we cannot tell apart points vs vertices
val geometryType = if (element.type == ElementType.NODE) null else element.geometryType
val builder = this
.byTags(element.tags)
.isSuggestion(false) // no brands
.forGeometry(geometryType)
if (locales != null) builder.forLocale(*locales)
val features = builder.find()
val features = getByTags(
tags = element.tags,
languages = languages,
geometry = geometryType,
isSuggestion = false // no brands
)

// see comment above - we want at least only features that can either be nodes or vertices if
// our element is a node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import androidx.core.text.italic
import de.westnordost.osmfeatures.Feature
import de.westnordost.osmfeatures.FeatureDictionary
import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.util.getLocalesForFeatureDictionary
import de.westnordost.streetcomplete.util.getLanguagesForFeatureDictionary
import de.westnordost.streetcomplete.view.presetIconIndex

/** Just displays a OSM feature */
Expand All @@ -21,7 +21,7 @@ class FeatureViewController(
private val textView: TextView,
private val iconView: ImageView
) {
private val locales = getLocalesForFeatureDictionary(textView.resources.configuration)
private val languages = getLanguagesForFeatureDictionary(textView.resources.configuration)

var countryOrSubdivisionCode: String? = null

Expand Down Expand Up @@ -66,11 +66,11 @@ class FeatureViewController(
}

private fun getParentFeature(feature: Feature): Feature? =
featureDictionary
.byId(feature.id.substringBeforeLast('/'))
.inCountry(countryOrSubdivisionCode)
.forLocale(*locales)
.get()
featureDictionary.getById(
id = feature.id.substringBeforeLast('/'),
languages = languages,
country = countryOrSubdivisionCode
)
}

private fun SpannableStringBuilder.appendName(context: Context, feature: Feature, searchText: String?): SpannableStringBuilder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import de.westnordost.osmfeatures.FeatureDictionary
import de.westnordost.osmfeatures.GeometryType
import de.westnordost.streetcomplete.databinding.ViewFeatureBinding
import de.westnordost.streetcomplete.databinding.ViewSelectPresetBinding
import de.westnordost.streetcomplete.util.getLocalesForFeatureDictionary
import de.westnordost.streetcomplete.util.getLanguagesForFeatureDictionary
import de.westnordost.streetcomplete.util.ktx.hideKeyboard
import de.westnordost.streetcomplete.util.ktx.nonBlankTextOrNull
import de.westnordost.streetcomplete.view.ListAdapter
Expand All @@ -34,17 +34,14 @@ class SearchFeaturesDialog(
) : AlertDialog(context) {

private val binding = ViewSelectPresetBinding.inflate(LayoutInflater.from(context))
private val locales = getLocalesForFeatureDictionary(context.resources.configuration)
private val languages = getLanguagesForFeatureDictionary(context.resources.configuration)
private val adapter = FeaturesAdapter()

private val searchText: String? get() = binding.searchEditText.nonBlankTextOrNull

private val defaultFeatures: List<Feature> by lazy {
codesOfDefaultFeatures.mapNotNull {
featureDictionary
.byId(it)
.forLocale(*locales)
.inCountry(countryOrSubdivisionCode).get()
codesOfDefaultFeatures.mapNotNull { id ->
featureDictionary.getById(id, languages = languages, country = countryOrSubdivisionCode)
}
}

Expand All @@ -66,13 +63,12 @@ class SearchFeaturesDialog(
}

private fun getFeatures(startsWith: String): List<Feature> =
featureDictionary
.byTerm(startsWith)
.forGeometry(geometryType)
.inCountry(countryOrSubdivisionCode)
.forLocale(*locales)
.find()
.filter(filterFn)
featureDictionary.getByTerm(
search = startsWith,
languages = languages,
country = countryOrSubdivisionCode,
geometry = geometryType,
).filter(filterFn).take(50).toList()

private fun updateSearchResults() {
val text = searchText
Expand Down

0 comments on commit c455a81

Please sign in to comment.