Skip to content

Commit

Permalink
Merge pull request #4385 from matkoniecz/incline
Browse files Browse the repository at this point in the history
Incline quest where mtb:scale:uphill=* is used
  • Loading branch information
westnordost authored Sep 28, 2022
2 parents b8976c1 + 7f14947 commit 70fb442
Show file tree
Hide file tree
Showing 12 changed files with 234 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import de.westnordost.streetcomplete.quests.foot.AddProhibitedForPedestrians
import de.westnordost.streetcomplete.quests.fuel_service.AddFuelSelfService
import de.westnordost.streetcomplete.quests.general_fee.AddGeneralFee
import de.westnordost.streetcomplete.quests.handrail.AddHandrail
import de.westnordost.streetcomplete.quests.incline_direction.AddBicycleIncline
import de.westnordost.streetcomplete.quests.internet_access.AddInternetAccess
import de.westnordost.streetcomplete.quests.kerb_height.AddKerbHeight
import de.westnordost.streetcomplete.quests.lanes.AddLanes
Expand Down Expand Up @@ -129,7 +130,7 @@ import de.westnordost.streetcomplete.quests.smoothness.AddRoadSmoothness
import de.westnordost.streetcomplete.quests.sport.AddSport
import de.westnordost.streetcomplete.quests.step_count.AddStepCount
import de.westnordost.streetcomplete.quests.step_count.AddStepCountStile
import de.westnordost.streetcomplete.quests.steps_incline.AddStepsIncline
import de.westnordost.streetcomplete.quests.incline_direction.AddStepsIncline
import de.westnordost.streetcomplete.quests.steps_ramp.AddStepsRamp
import de.westnordost.streetcomplete.quests.summit.AddSummitCross
import de.westnordost.streetcomplete.quests.summit.AddSummitRegister
Expand Down Expand Up @@ -254,6 +255,8 @@ fun questTypeRegistry(
AddStepsRamp(),
AddStepsIncline(), // can be gathered while walking perpendicular to the way e.g. the other side of the road or when running/cycling past, confuses some people, so not as high as it theoretically should be

AddBicycleIncline(),

AddMemorialType(), // sometimes a bit hard to decide between the different types (something something sculpture)

AddReligionToPlaceOfWorship(), // icons on maps are different - OSM Carto, mapy.cz, OsmAnd, Sputnik etc
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package de.westnordost.streetcomplete.quests.incline_direction

import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.data.elementfilter.toElementFilterExpression
import de.westnordost.streetcomplete.data.osm.geometry.ElementPolylinesGeometry
import de.westnordost.streetcomplete.data.osm.mapdata.Element
import de.westnordost.streetcomplete.data.osm.mapdata.MapDataWithGeometry
import de.westnordost.streetcomplete.data.osm.osmquests.OsmElementQuestType
import de.westnordost.streetcomplete.data.user.achievements.EditTypeAchievement.BICYCLIST
import de.westnordost.streetcomplete.osm.Tags
import de.westnordost.streetcomplete.util.math.measuredLength

class AddBicycleIncline : OsmElementQuestType<InclineDirectionAnswer> {

private val tagFilter by lazy { """
ways with mtb:scale:uphill
and highway ~ footway|cycleway|path|bridleway|track
and (!indoor or indoor = no)
and area != yes
and access !~ private|no
and !incline
""".toElementFilterExpression() }

override val changesetComment = "Specify which way leads up (where mtb:scale:uphill is present)"
override val wikiLink = "Key:incline"
override val icon = R.drawable.ic_quest_bicycle_incline
override val achievements = listOf(BICYCLIST)
override val hasMarkersAtEnds = false

override fun getApplicableElements(mapData: MapDataWithGeometry): Iterable<Element> {
// sadly for very long ways shape may be complex and it may be confusing which answer should be given
// once multiple quest markers are appearing it becomes completely unclear
// see for example https://www.openstreetmap.org/way/437205914
return mapData
.filter { element -> tagFilter.matches(element) }
.filter { element ->
val geometry = mapData.getGeometry(element.type, element.id) as? ElementPolylinesGeometry
geometry?.polylines?.all { it.measuredLength() < 200 } == true
}
}

override fun isApplicableTo(element: Element): Boolean? {
// we don't want to show overly long things
if (!tagFilter.matches(element)) return false
return null
}

override fun getTitle(tags: Map<String, String>) = R.string.quest_bicycle_incline_title

override fun createForm() = AddBicycleInclineForm()

override fun applyAnswerTo(answer: InclineDirectionAnswer, tags: Tags, timestampEdited: Long) =
answer.applyTo(tags)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package de.westnordost.streetcomplete.quests.incline_direction

import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.data.osm.geometry.ElementPolylinesGeometry
import de.westnordost.streetcomplete.quests.AImageListQuestForm
import de.westnordost.streetcomplete.quests.AnswerItem
import de.westnordost.streetcomplete.util.math.getOrientationAtCenterLineInDegrees
import kotlin.math.PI

class AddBicycleInclineForm : AImageListQuestForm<RegularInclineDirection, InclineDirectionAnswer>() {
override val otherAnswers = listOf(
AnswerItem(R.string.quest_bicycle_incline_up_and_down) { confirmUpAndDown() }
)

override val items get() =
RegularInclineDirection.values().map { it.asItem(requireContext(), wayRotation + mapRotation) }

override val itemsPerRow = 2

private var mapRotation: Float = 0f
private var wayRotation: Float = 0f

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
wayRotation = (geometry as ElementPolylinesGeometry).getOrientationAtCenterLineInDegrees()
imageSelector.cellLayoutId = R.layout.cell_icon_select_with_label_below
}

override fun onMapOrientation(rotation: Float, tilt: Float) {
mapRotation = (rotation * 180 / PI).toFloat()
imageSelector.items = items
}

private fun confirmUpAndDown() {
val ctx = context ?: return
AlertDialog.Builder(ctx)
.setTitle(R.string.quest_generic_confirmation_title)
.setPositiveButton(R.string.quest_generic_confirmation_yes) { _, _ -> applyAnswer(
UpdAndDownHopsAnswer) }
.setNegativeButton(R.string.quest_generic_confirmation_no, null)
.show()
}

override fun onClickOk(selectedItems: List<RegularInclineDirection>) {
applyAnswer(RegularInclineDirectionAnswer(selectedItems.first()))
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.westnordost.streetcomplete.quests.steps_incline
package de.westnordost.streetcomplete.quests.incline_direction

import android.os.Bundle
import de.westnordost.streetcomplete.R
Expand All @@ -7,10 +7,9 @@ import de.westnordost.streetcomplete.quests.AImageListQuestForm
import de.westnordost.streetcomplete.util.math.getOrientationAtCenterLineInDegrees
import kotlin.math.PI

class AddStepsInclineForm : AImageListQuestForm<StepsIncline, StepsIncline>() {

class AddInclineForm : AImageListQuestForm<RegularInclineDirection, InclineDirectionAnswer>() {
override val items get() =
StepsIncline.values().map { it.asItem(requireContext(), wayRotation + mapRotation) }
RegularInclineDirection.values().map { it.asItem(requireContext(), wayRotation + mapRotation) }

override val itemsPerRow = 2

Expand All @@ -28,7 +27,7 @@ class AddStepsInclineForm : AImageListQuestForm<StepsIncline, StepsIncline>() {
imageSelector.items = items
}

override fun onClickOk(selectedItems: List<StepsIncline>) {
applyAnswer(selectedItems.first())
override fun onClickOk(selectedItems: List<RegularInclineDirection>) {
applyAnswer(RegularInclineDirectionAnswer(selectedItems.first()))
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package de.westnordost.streetcomplete.quests.steps_incline
package de.westnordost.streetcomplete.quests.incline_direction

import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.data.osm.osmquests.OsmFilterQuestType
import de.westnordost.streetcomplete.data.user.achievements.EditTypeAchievement.PEDESTRIAN
import de.westnordost.streetcomplete.osm.Tags
import de.westnordost.streetcomplete.quests.steps_incline.StepsIncline.UP
import de.westnordost.streetcomplete.quests.steps_incline.StepsIncline.UP_REVERSED

class AddStepsIncline : OsmFilterQuestType<StepsIncline>() {
class AddStepsIncline : OsmFilterQuestType<InclineDirectionAnswer>() {

override val elementFilter = """
ways with highway = steps
Expand All @@ -23,12 +21,8 @@ class AddStepsIncline : OsmFilterQuestType<StepsIncline>() {

override fun getTitle(tags: Map<String, String>) = R.string.quest_steps_incline_title

override fun createForm() = AddStepsInclineForm()
override fun createForm() = AddInclineForm()

override fun applyAnswerTo(answer: StepsIncline, tags: Tags, timestampEdited: Long) {
tags["incline"] = when (answer) {
UP -> "up"
UP_REVERSED -> "down"
}
}
override fun applyAnswerTo(answer: InclineDirectionAnswer, tags: Tags, timestampEdited: Long) =
answer.applyTo(tags)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package de.westnordost.streetcomplete.quests.incline_direction

import de.westnordost.streetcomplete.osm.Tags

sealed interface InclineDirectionAnswer
class RegularInclineDirectionAnswer(val value: RegularInclineDirection) : InclineDirectionAnswer
object UpdAndDownHopsAnswer : InclineDirectionAnswer

enum class RegularInclineDirection {
UP, UP_REVERSED
}

fun InclineDirectionAnswer.applyTo(tags: Tags) {
tags["incline"] = when (this) {
is RegularInclineDirectionAnswer -> when (this.value) {
RegularInclineDirection.UP -> "up"
RegularInclineDirection.UP_REVERSED -> "down"
}
is UpdAndDownHopsAnswer -> "up/down"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.westnordost.streetcomplete.quests.steps_incline
package de.westnordost.streetcomplete.quests.incline_direction

import android.content.Context
import de.westnordost.streetcomplete.R
Expand All @@ -8,13 +8,13 @@ import de.westnordost.streetcomplete.view.RotatedCircleDrawable
import de.westnordost.streetcomplete.view.image_select.DisplayItem
import de.westnordost.streetcomplete.view.image_select.Item2

fun StepsIncline.asItem(context: Context, rotation: Float): DisplayItem<StepsIncline> {
fun RegularInclineDirection.asItem(context: Context, rotation: Float): DisplayItem<RegularInclineDirection> {
val drawable = RotatedCircleDrawable(context.getDrawable(iconResId)!!)
drawable.rotation = rotation
return Item2(this, DrawableImage(drawable), ResText(R.string.quest_steps_incline_up))
}

private val StepsIncline.iconResId: Int get() = when (this) {
StepsIncline.UP -> R.drawable.ic_steps_incline_up
StepsIncline.UP_REVERSED -> R.drawable.ic_steps_incline_up_reversed
private val RegularInclineDirection.iconResId: Int get() = when (this) {
RegularInclineDirection.UP -> R.drawable.ic_steps_incline_up
RegularInclineDirection.UP_REVERSED -> R.drawable.ic_steps_incline_up_reversed
}

This file was deleted.

36 changes: 36 additions & 0 deletions app/src/main/res/drawable/ic_quest_bicycle_incline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<path
android:pathData="m128,64.06c0,33.42 -28.65,60.52 -64,60.52 -35.35,0 -64,-27.1 -64,-60.52s28.65,-60.52 64,-60.52c35.35,0 64,27.1 64,60.52"
android:strokeWidth=".19449"
android:fillColor="#529add"/>
<path
android:pathData="M30.26,104.11 L110.26,58.72"
android:strokeAlpha="0.2"
android:strokeWidth="7.7795"
android:fillColor="#00000000"
android:strokeColor="#000000"/>
<path
android:pathData="M30.26,99.11 L110.26,53.72"
android:strokeWidth="7.7795"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="m67.26,60.07a10.14,10.14 0,0 0,13.85 3.71,10.14 10.14,0 0,0 3.71,-13.85 10.14,10.14 0,0 0,-13.85 -3.71,10.14 10.14,0 0,0 -3.71,13.85m-28.61,16.52a10.14,10.14 0,0 0,13.85 3.71,10.14 10.14,0 0,0 3.71,-13.85 10.14,10.14 0,0 0,-13.85 -3.71,10.14 10.14,0 0,0 -3.71,13.85m24.7,-32.29 l-3.32,19.88 -12.68,7.32 0.94,-18.51 15.06,-8.7m-16.89,5.52 l-3.87,2.22m17.44,12.14 l-13.57,-14.36m29.43,5.2 l-17.96,-15.86 -6.34,3.66"
android:strokeAlpha="0.2"
android:strokeLineJoin="round"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="m67.28,55a10.14,10.14 0,0 0,13.85 3.71,10.14 10.14,0 0,0 3.71,-13.85 10.14,10.14 0,0 0,-13.85 -3.71,10.14 10.14,0 0,0 -3.71,13.85m-28.61,16.52a10.14,10.14 0,0 0,13.85 3.71,10.14 10.14,0 0,0 3.71,-13.85 10.14,10.14 0,0 0,-13.85 -3.71,10.14 10.14,0 0,0 -3.71,13.85m24.7,-32.29 l-3.32,19.88 -12.68,7.32 0.94,-18.51 15.06,-8.7m-16.89,5.52 l-3.87,2.22m17.44,12.14 l-13.57,-14.36m29.43,5.2 l-17.96,-15.86 -6.34,3.66"
android:strokeLineJoin="round"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"
android:strokeLineCap="round"/>
</vector>
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,9 @@ Before uploading your changes, the app checks with a &lt;a href=\"https://www.we
<string name="quest_barrier_bicycle_type_multiple">Chicane - more than two barriers</string>
<string name="quest_barrier_bicycle_type_not_cycle_barrier">Not a cycle barrier, but some other barrier</string>

<string name="quest_bicycle_incline_title">Which direction leads upwards here?</string>
<string name="quest_bicycle_incline_up_and_down">Up and down hops</string>

<string name="quest_bicycle_parking_access_title2">Who is allowed to park a bicycle here? Parking may be free or paid.</string>

<string name="quest_bicycleParkingCoveredStatus_title">"Is this bicycle parking covered (protected from rain)?"</string>
Expand Down
1 change: 1 addition & 0 deletions res/graphics/authors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ quest/
bench_poi.svg
bench_public_transport.svg
bicycle.svg
bicycle_incline.svg Tobias Zwick (CC-BY-SA 4.0) for used graphic elements, minor rearranging by Mateusz Konieczny
bicycle_parking.svg
bicycle_parking_access.svg Flo Edelmann merged bicycle_parking.svg by Tobias Zwick (CC-BY-SA 4.0) with parking_access.svg made by Tobias Zwick with parts taken from EmojiOne 2: U+1F511 (CC-BY 4.0), resulting work is CC-BY-SA 4.0
bicycle_parking_capacity.svg
Expand Down
51 changes: 51 additions & 0 deletions res/graphics/quest/bicycle_incline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 70fb442

Please sign in to comment.