|
1 | 1 | package de.westnordost.streetcomplete.quests.power_attachment |
2 | 2 |
|
3 | 3 | import de.westnordost.streetcomplete.R |
| 4 | +import de.westnordost.streetcomplete.data.elementfilter.toElementFilterExpression |
4 | 5 | import de.westnordost.streetcomplete.data.osm.geometry.ElementGeometry |
5 | 6 | import de.westnordost.streetcomplete.data.osm.mapdata.Element |
6 | 7 | import de.westnordost.streetcomplete.data.osm.mapdata.MapDataWithGeometry |
7 | 8 | import de.westnordost.streetcomplete.data.osm.mapdata.filter |
| 9 | +import de.westnordost.streetcomplete.data.osm.osmquests.OsmElementQuestType |
8 | 10 | import de.westnordost.streetcomplete.data.osm.osmquests.OsmFilterQuestType |
9 | 11 | import de.westnordost.streetcomplete.data.quest.AndroidQuest |
10 | 12 | import de.westnordost.streetcomplete.data.user.achievements.EditTypeAchievement.BUILDING |
11 | 13 | import de.westnordost.streetcomplete.osm.Tags |
12 | 14 | import de.westnordost.streetcomplete.resources.* |
13 | 15 |
|
14 | | -class AddPowerAttachment : OsmFilterQuestType<PowerAttachment>(), AndroidQuest { |
| 16 | +class AddPowerAttachment : OsmElementQuestType<PowerAttachment>, AndroidQuest { |
15 | 17 |
|
16 | | - override val elementFilter = """ |
| 18 | + private val polesFilter by lazy { """ |
17 | 19 | nodes with |
18 | 20 | power ~ tower|pole|insulator |
19 | 21 | and !line_attachment |
20 | | - and disused != yes and ruined != yes and abandoned != yes |
21 | | - """ |
| 22 | + and disused != yes |
| 23 | + and ruined != yes |
| 24 | + and abandoned != yes |
| 25 | + """.toElementFilterExpression() } |
| 26 | + |
| 27 | + private val powerLinesFilter by lazy { """ |
| 28 | + ways with power ~ line|minor_line |
| 29 | + """.toElementFilterExpression() } |
| 30 | + |
22 | 31 | override val changesetComment = "Specify line_attachment power support" |
23 | 32 | override val wikiLink = "Key:line_attachment" |
24 | 33 | override val icon = R.drawable.quest_power |
25 | 34 | override val title = Res.string.quest_powerAttachment_title |
26 | 35 | override val achievements = listOf(BUILDING) |
27 | 36 |
|
| 37 | + override fun getApplicableElements(mapData: MapDataWithGeometry): Iterable<Element> { |
| 38 | + // when several power lines are attached to any one power pole, it is very likely that that |
| 39 | + // power pole has *multiple* power line attachments, which requires a more complex tagging |
| 40 | + // that the UI for this quest does not support. Hence, we filter out all power poles that |
| 41 | + // are nodes of more than one power lines. See #6547 |
| 42 | + val poleNodeIdsWithSeveralPowerLines = mapData.ways |
| 43 | + .filter { powerLinesFilter.matches(it) } |
| 44 | + .flatMap { it.nodeIds } |
| 45 | + .groupingBy { it }.eachCount() |
| 46 | + .filter { (id, count) -> count != 1 } |
| 47 | + .mapTo(HashSet<Long>()) { (id, count) -> id } |
| 48 | + |
| 49 | + return mapData.nodes.filter { |
| 50 | + polesFilter.matches(it) && it.id !in poleNodeIdsWithSeveralPowerLines |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + override fun isApplicableTo(element: Element): Boolean? { |
| 55 | + if (!polesFilter.matches(element)) return false |
| 56 | + // otherwise, we can't say, because the power pole may be part of several power lines |
| 57 | + // (see comment in getApplicableElements) |
| 58 | + return null |
| 59 | + } |
| 60 | + |
28 | 61 | override fun getHighlightedElements(element: Element, mapData: MapDataWithGeometry) = |
29 | 62 | // and also show the (power) lines themselves |
30 | 63 | mapData.filter("nodes with power ~ tower|pole|insulator") + |
|
0 commit comments