Skip to content

Commit

Permalink
tag disused:oldkey=oldvalue when selecting that something is vacant n…
Browse files Browse the repository at this point in the history
…ow (fixes #5548)
  • Loading branch information
westnordost committed Aug 15, 2024
1 parent 68fe45b commit 984467b
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 12 deletions.
19 changes: 19 additions & 0 deletions app/src/main/java/de/westnordost/streetcomplete/osm/Place.kt
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,25 @@ private val IS_PLACE_EXPRESSION by lazy {
""".toElementFilterExpression()
}

/** Get tags to denote the element with the given [tags] as disused */
fun getDisusedPlaceTags(tags: Map<String, String>?): Map<String, String> {
val (key, value) = tags?.entries?.find { it.key in placeTypeKeys }?.toPair() ?: ("shop" to "yes")
return mapOf("disused:$key" to value)
}

private val placeTypeKeys = setOf(
"amenity",
"club",
"craft",
"emergency",
"healthcare",
"leisure",
"office",
"military",
"shop",
"tourism"
)

/** Expression to see if an element is some kind of vacant shop */
private val IS_VACANT_PLACE_EXPRESSION = """
nodes, ways, relations with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import de.westnordost.streetcomplete.databinding.FragmentOverlayPlacesBinding
import de.westnordost.streetcomplete.osm.LocalizedName
import de.westnordost.streetcomplete.osm.POPULAR_PLACE_FEATURE_IDS
import de.westnordost.streetcomplete.osm.applyTo
import de.westnordost.streetcomplete.osm.getDisusedPlaceTags
import de.westnordost.streetcomplete.osm.isDisusedPlace
import de.westnordost.streetcomplete.osm.isPlace
import de.westnordost.streetcomplete.osm.parseLocalizedNames
Expand Down Expand Up @@ -295,7 +296,11 @@ private suspend fun createEditAction(
}

if (doReplaceShop) {
tagChanges.replacePlace(newFeature.addTags)
if (isVacant) {
tagChanges.replacePlace(getDisusedPlaceTags(element?.tags))
} else {
tagChanges.replacePlace(newFeature.addTags)
}
} else {
for ((key, value) in previousFeature?.removeTags.orEmpty()) {
tagChanges.remove(key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ abstract class AbstractOsmQuestForm<T> : AbstractQuestForm(), IsShowingQuestDeta
if (element.isPlaceOrDisusedPlace()) {
ShopGoneDialog(
requireContext(),
element.geometryType,
element,
countryOrSubdivisionCode,
featureDictionary,
onSelectedFeature = this::onShopReplacementSelected,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class CheckShopExistence(
and (name or brand or noname = yes or name:signed = no)
""").toElementFilterExpression() }

override val changesetComment = "Survey if places (shops and other shop-like) still exist"
override val changesetComment = "Survey if places still exist"
override val wikiLink = "Key:disused:"
override val icon = R.drawable.ic_quest_check_shop
override val achievements = listOf(CITIZEN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class CheckShopType : OsmElementQuestType<ShopTypeAnswer> {
)
""".toElementFilterExpression() }

override val changesetComment = "Survey if vacant shops are still vacant"
override val changesetComment = "Survey if vacant places are still vacant"
override val wikiLink = "Key:disused:"
override val icon = R.drawable.ic_quest_check_shop
override val achievements = listOf(CITIZEN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ import android.widget.RadioButton
import androidx.appcompat.app.AlertDialog
import de.westnordost.osmfeatures.Feature
import de.westnordost.osmfeatures.FeatureDictionary
import de.westnordost.osmfeatures.GeometryType
import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.data.osm.mapdata.Element
import de.westnordost.streetcomplete.data.osm.mapdata.LatLon
import de.westnordost.streetcomplete.data.osm.mapdata.Node
import de.westnordost.streetcomplete.databinding.DialogShopGoneBinding
import de.westnordost.streetcomplete.databinding.ViewShopTypeBinding
import de.westnordost.streetcomplete.osm.POPULAR_PLACE_FEATURE_IDS
import de.westnordost.streetcomplete.osm.getDisusedPlaceTags
import de.westnordost.streetcomplete.osm.isPlace
import de.westnordost.streetcomplete.util.ktx.geometryType
import de.westnordost.streetcomplete.view.controller.FeatureViewController
import de.westnordost.streetcomplete.view.dialogs.SearchFeaturesDialog

class ShopGoneDialog(
context: Context,
private val geometryType: GeometryType?,
private val element: Element,
private val countryCode: String?,
private val featureDictionary: FeatureDictionary,
private val onSelectedFeature: (Map<String, String>) -> Unit,
Expand Down Expand Up @@ -52,10 +54,10 @@ class ShopGoneDialog(
SearchFeaturesDialog(
context,
featureDictionary,
geometryType,
element.geometryType,
countryCode,
featureCtrl.feature?.name,
::filterOnlyShops,
::filterOnlyPlaces,
::onSelectedFeature,
POPULAR_PLACE_FEATURE_IDS,
true
Expand All @@ -74,7 +76,7 @@ class ShopGoneDialog(
updateOkButtonEnablement()
}

private fun filterOnlyShops(feature: Feature): Boolean {
private fun filterOnlyPlaces(feature: Feature): Boolean {
val fakeElement = Node(-1L, LatLon(0.0, 0.0), feature.tags, 0)
return fakeElement.isPlace()
}
Expand All @@ -89,7 +91,7 @@ class ShopGoneDialog(
// to override the default OK=dismiss() behavior
getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
when (selectedRadioButtonId) {
R.id.vacantRadioButton -> onSelectedFeature(mapOf("disused:shop" to "yes"))
R.id.vacantRadioButton -> onSelectedFeature(getDisusedPlaceTags(element.tags))
R.id.replaceRadioButton -> onSelectedFeature(featureCtrl.feature!!.addTags)
R.id.leaveNoteRadioButton -> onLeaveNote()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class SpecifyShopType : OsmFilterQuestType<ShopTypeAnswer>() {
tags.removeCheckDates()
when (answer) {
is IsShopVacant -> {
tags["disused:shop"] = tags["shop"] ?: "yes"
tags.remove("shop")
tags["disused:shop"] = "yes"
}
is ShopType -> {
tags.remove("disused:shop")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package de.westnordost.streetcomplete.quests.shop_type

import de.westnordost.streetcomplete.data.osm.edits.update_tags.StringMapEntryAdd
import de.westnordost.streetcomplete.data.osm.edits.update_tags.StringMapEntryDelete
import de.westnordost.streetcomplete.data.osm.edits.update_tags.StringMapEntryModify
import de.westnordost.streetcomplete.quests.answerApplied
import de.westnordost.streetcomplete.quests.answerAppliedTo
import de.westnordost.streetcomplete.testutils.node
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue

class SpecifyShopTypeTest {
private val questType = SpecifyShopType()

@Test fun `is applicable to undefine shop`() {
@Test fun `is applicable to undefined shop`() {
assertTrue(questType.isApplicableTo(
node(tags = mapOf("shop" to "yes"))
))
Expand All @@ -25,4 +31,33 @@ class SpecifyShopTypeTest {
node(tags = mapOf("power" to "plant", "shop" to "yes"))
))
}

@Test fun `mentions old value in disused tag`() {
assertEquals(
setOf(
StringMapEntryAdd("disused:shop", "supermarket"),
StringMapEntryDelete("shop", "supermarket")
),
questType.answerAppliedTo(
IsShopVacant,
mapOf("shop" to "supermarket")
)
)
assertEquals(
setOf(
StringMapEntryAdd("disused:amenity", "cafe"),
StringMapEntryDelete("amenity", "cafe")
),
questType.answerAppliedTo(
IsShopVacant,
mapOf("amenity" to "cafe")
)
)
assertEquals(
setOf(
StringMapEntryAdd("disused:shop", "yes"),
),
questType.answerApplied(IsShopVacant)
)
}
}

0 comments on commit 984467b

Please sign in to comment.