Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changesets refactor #1329

Merged
merged 73 commits into from
Sep 4, 2019
Merged
Changes from 1 commit
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
0736d29
Merge branch 'master' into changesets-refactor
westnordost Feb 10, 2019
35f0065
Merge branch 'master' into changesets-refactor
westnordost Feb 24, 2019
9a423e0
wip split way at...
westnordost Feb 27, 2019
c555503
more null-safety
westnordost Mar 8, 2019
98d01db
slightly different wording for traffic signals button quest (fixes #1…
westnordost Mar 22, 2019
8f34703
update dependencies
westnordost Mar 22, 2019
5da9898
Merge branch 'master' into changesets-refactor
westnordost Jun 8, 2019
f2111a0
work on split way upload
westnordost Jun 17, 2019
1e8eeb5
special handling for circular ways
westnordost Jun 22, 2019
b63a4b6
add more tests
westnordost Jun 23, 2019
d16aea1
add tests and fixes
westnordost Jun 23, 2019
666757a
treat role "from" and "to" with "via" the same regardless of relation…
westnordost Jun 24, 2019
490e529
solve the modification aware stuff in osmapi
westnordost Jun 26, 2019
ed937a4
update to new osmapi version
westnordost Jun 26, 2019
c8d75d5
fix create split position at 18th meridian
westnordost Jun 29, 2019
ef9044b
Merge branch 'master' into changesets-refactor
westnordost Jun 29, 2019
4317c3a
Merge branch 'master' into changesets-refactor
westnordost Jul 7, 2019
319881d
work in progress upload refactor
westnordost Jul 10, 2019
8ed1f0b
work in progress upload refactor
westnordost Jul 25, 2019
9f34334
Merge branch 'master' into changesets-refactor
westnordost Aug 7, 2019
f6b8881
fix a few tests
westnordost Aug 7, 2019
ef8e013
replace tabs with spaces
westnordost Aug 7, 2019
c29feb7
fix tests
westnordost Aug 10, 2019
b487d6e
add common superclass for all uploads into changesets
westnordost Aug 11, 2019
2200205
remove superfluous test class
westnordost Aug 11, 2019
fae8524
set visible quest listener
westnordost Aug 11, 2019
bfa0bd9
correct setting of cancelSate
westnordost Aug 11, 2019
13211b3
work on UI part of the splitting
westnordost Aug 18, 2019
470dabe
More shadow on the marker
westnordost Aug 18, 2019
b83044c
larger click area
westnordost Aug 18, 2019
981e9e4
rename OsmQuestSplitWayDao.id to .questId
westnordost Aug 19, 2019
703fd5e
replace NotNull annotation with NonNull
westnordost Aug 19, 2019
b90cf13
add test for LatLon extension function (and fix bug)
westnordost Aug 19, 2019
6986cb7
add some tests
westnordost Aug 19, 2019
ddfe6f7
add test
westnordost Aug 20, 2019
de8a9b4
add test
westnordost Aug 20, 2019
594f4b1
add some comments
westnordost Aug 21, 2019
1c8aeb9
add some comments
westnordost Aug 21, 2019
dd978cc
handle (very unlikely) exception
westnordost Aug 21, 2019
1b00bbf
remove unused function
westnordost Aug 22, 2019
fb1e1ef
add tests
westnordost Aug 22, 2019
1790391
Merge branch 'master' into changesets-refactor
westnordost Aug 22, 2019
a5584fc
add animation on cut
westnordost Aug 24, 2019
f287665
snip sound a little later
westnordost Aug 24, 2019
be67f57
better snip animation
westnordost Aug 24, 2019
30bdd4c
add test
westnordost Aug 24, 2019
8121451
clear marker ids
westnordost Aug 24, 2019
85fbbee
dont close split way dialog when clicking quest
westnordost Aug 24, 2019
03a32d3
don't show scissors on top of buttons etc.
westnordost Aug 24, 2019
e64fdf3
fix crash
westnordost Aug 24, 2019
a4a918c
show quest solved animation for splitting way
westnordost Aug 24, 2019
6121802
fix upload
westnordost Aug 24, 2019
90e6048
fix test
westnordost Aug 24, 2019
83644da
cover more test cases
westnordost Aug 25, 2019
5767ea8
one split position may map to several split nodes
westnordost Aug 25, 2019
0d1d377
don't offer ability to split the way on areas (i.e. surface of a plaza)
westnordost Aug 25, 2019
6df9cff
fix unsynced split way seemingly gone after reopening app
westnordost Aug 26, 2019
908d982
fix correctly splitting restriction relations with multiple via ways
westnordost Aug 27, 2019
e87c0a7
do not show option to split way for closed roundabouts
westnordost Aug 28, 2019
4c6c71e
fix form for landscape layout
westnordost Aug 28, 2019
59a8c71
enhance text
westnordost Aug 28, 2019
a6272c8
Merge branch 'master' into changesets-refactor
westnordost Aug 28, 2019
4154b74
update feature names
westnordost Aug 28, 2019
1baafe2
add confirmation dialog if there are many splits
westnordost Aug 28, 2019
578aef3
Update app/src/main/res/values/strings.xml
westnordost Aug 29, 2019
12f639d
do not require user to zoom in further if it is not possible
westnordost Aug 29, 2019
1b58a84
Merge branch 'master' into changesets-refactor
westnordost Aug 29, 2019
2184be7
only activate photos attached to note if there are any
westnordost Sep 1, 2019
e5fe906
allow Element.copy to copy with null-tags
westnordost Sep 1, 2019
c79bd52
correctly update elements after split
westnordost Sep 1, 2019
00d471f
correctly update elements after split (2)
westnordost Sep 4, 2019
1cb30d7
QuestGiver shall only create quests that are currently visible
westnordost Sep 4, 2019
50d3823
fix tests
westnordost Sep 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add common superclass for all uploads into changesets
  • Loading branch information
westnordost committed Aug 11, 2019
commit b487d6e30ca46db545d63eece033855d889d3236
Original file line number Diff line number Diff line change
@@ -20,8 +20,17 @@
import de.westnordost.streetcomplete.data.osm.persist.ElementGeometryDao;
import de.westnordost.streetcomplete.data.osm.persist.MergedElementDao;
import de.westnordost.streetcomplete.data.osm.persist.OsmQuestDao;
import de.westnordost.streetcomplete.data.osm.persist.SplitWayDao;
import de.westnordost.streetcomplete.data.osm.persist.UndoOsmQuestDao;
import de.westnordost.streetcomplete.data.osm.upload.OpenQuestChangesetsManager;
import de.westnordost.streetcomplete.data.osm.upload.OsmQuestsUpload;
import de.westnordost.streetcomplete.data.osm.upload.SingleOsmElementTagChangesUpload;
import de.westnordost.streetcomplete.data.osm.upload.SplitSingleWayUpload;
import de.westnordost.streetcomplete.data.osm.upload.SplitWaysUpload;
import de.westnordost.streetcomplete.data.osm.upload.UndoOsmQuestsUpload;
import de.westnordost.streetcomplete.data.osmnotes.OsmAvatarsDownload;
import de.westnordost.streetcomplete.data.statistics.QuestStatisticsDao;
import de.westnordost.streetcomplete.data.tiles.DownloadedTilesDao;
import de.westnordost.streetcomplete.oauth.OAuthPrefs;
import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao;
import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataParser;
@@ -115,6 +124,35 @@ public static OsmConnection osmConnection(OAuthConsumer consumer)
return new MapDataDao(osm);
}

@Provides public static OsmQuestsUpload osmQuestsUpload(
MergedElementDao elementDB, ElementGeometryDao elementGeometryDB,
OpenQuestChangesetsManager changesetManager, OsmQuestGiver questGiver,
QuestStatisticsDao statisticsDB, OsmApiWayGeometrySource wayGeometrySource,
OsmQuestDao questDB, SingleOsmElementTagChangesUpload singleChangeUpload,
DownloadedTilesDao downloadedTilesDao) {
return new OsmQuestsUpload(elementDB, elementGeometryDB, changesetManager, questGiver,
statisticsDB, new ElementGeometryCreator(wayGeometrySource), questDB,
singleChangeUpload, downloadedTilesDao);
}

@Provides public static UndoOsmQuestsUpload undoOsmQuestsUpload(
MergedElementDao elementDB, ElementGeometryDao elementGeometryDB,
OpenQuestChangesetsManager changesetManager, OsmQuestGiver questGiver,
QuestStatisticsDao statisticsDB, OsmApiWayGeometrySource wayGeometrySource,
UndoOsmQuestDao questDB, SingleOsmElementTagChangesUpload singleChangeUpload) {
return new UndoOsmQuestsUpload(elementDB, elementGeometryDB, changesetManager, questGiver,
statisticsDB, new ElementGeometryCreator(wayGeometrySource), questDB, singleChangeUpload);
}

@Provides public static SplitWaysUpload splitWaysUpload(
MergedElementDao elementDB, ElementGeometryDao elementGeometryDB,
OpenQuestChangesetsManager changesetManager, OsmQuestGiver questGiver,
QuestStatisticsDao statisticsDB, OsmApiWayGeometrySource wayGeometrySource,
SplitWayDao questDB, SplitSingleWayUpload singleUpload) {
return new SplitWaysUpload(elementDB, elementGeometryDB, changesetManager, questGiver,
statisticsDB, new ElementGeometryCreator(wayGeometrySource), questDB, singleUpload);
}

@Provides public static OsmAvatarsDownload avatarsDownload(UserDao userDao, Context context)
{
return new OsmAvatarsDownload(userDao, getAvatarsCacheDirectory(context));
Original file line number Diff line number Diff line change
@@ -13,10 +13,11 @@
import de.westnordost.osmapi.map.data.Element;
import de.westnordost.osmapi.map.data.LatLon;
import de.westnordost.streetcomplete.data.osm.upload.HasElementTagChanges;
import de.westnordost.streetcomplete.data.osm.upload.UploadableInChangeset;
import de.westnordost.streetcomplete.util.SphericalEarthMath;

/** Represents one task for the user to complete/correct the data based on one OSM element */
public class OsmQuest implements Quest, HasElementTagChanges
public class OsmQuest implements Quest, UploadableInChangeset, HasElementTagChanges
{
public OsmQuest(OsmElementQuestType type, Element.Type elementType, long elementId,
ElementGeometry geometry)
@@ -143,4 +144,8 @@ public void setChanges(StringMapChanges changes, String source)
public Boolean isApplicableTo(@NonNull Element element) {
return type.isApplicableTo(element);
}

/* --------------------------- UploadableInChangeset --------------------------- */

@Override public String getSource() { return changesSource; }
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package de.westnordost.streetcomplete.data.osm

import android.util.Log


import javax.inject.Inject

import de.westnordost.osmapi.map.data.Element
import de.westnordost.osmapi.map.data.LatLon
import de.westnordost.streetcomplete.data.QuestStatus
import de.westnordost.streetcomplete.data.QuestType
import de.westnordost.streetcomplete.data.QuestTypeRegistry
import de.westnordost.streetcomplete.data.osm.persist.ElementGeometryDao
import de.westnordost.streetcomplete.data.osm.persist.OsmQuestDao
import de.westnordost.streetcomplete.data.osmnotes.OsmNoteQuestDao
import de.westnordost.streetcomplete.util.SphericalEarthMath

/** Manages creating new quests and removing quests that are no longer applicable for an OSM
* element locally */
class OsmQuestGiver @Inject constructor(
private val osmNoteQuestDb: OsmNoteQuestDao,
private val questDB: OsmQuestDao,
private val elementGeometryDB: ElementGeometryDao,
private val questTypeRegistry: QuestTypeRegistry
) {

private val TAG = "OsmQuestGiver"

class QuestUpdates {
val createdQuests: MutableList<OsmQuest> = ArrayList()
val removedQuestIds: MutableList<Long> = ArrayList()
}

fun updateQuests(element: Element): QuestUpdates {
val result = QuestUpdates()

val geometry = elementGeometryDB.get(element.type, element.id) ?: return result

val hasNote = hasNoteAt(geometry.center)

val currentQuests = getCurrentQuests(element)
val createdQuestsLog = ArrayList<String>()
val removedQuestsLog = ArrayList<String>()

for (questType in questTypeRegistry.all) {
if (questType !is OsmElementQuestType<*>) continue

val appliesToElement = questType.isApplicableTo(element) ?: continue

val hasQuest = currentQuests.containsKey(questType)
if (appliesToElement && !hasQuest && !hasNote) {
val quest = OsmQuest(questType, element.type, element.id, geometry)
result.createdQuests.add(quest)
createdQuestsLog.add(questType.javaClass.simpleName)
}
if (!appliesToElement && hasQuest) {
val quest = currentQuests.getValue(questType)
// only remove "fresh" unanswered quests because answered/closed quests by definition
// do not apply to the element anymore. E.g. after adding the name to the street,
// there shan't be any AddRoadName quest for that street anymore
if (quest.status == QuestStatus.NEW) {
result.removedQuestIds.add(quest.id!!)
removedQuestsLog.add(questType.javaClass.simpleName)
}
}
}

if (result.createdQuests.isNotEmpty()) {
// Before new quests are unlocked, all reverted quests need to be removed for
// this element so that they can be created anew as the case may be
questDB.deleteAllReverted(element.type, element.id)

questDB.addAll(result.createdQuests)
Log.d(TAG, "Created new quests for ${element.type.name}#${element.id}: ${createdQuestsLog.joinToString()}")
}
if (result.removedQuestIds.isNotEmpty()) {
questDB.deleteAll(result.removedQuestIds)
Log.d(TAG, "Removed quests no longer applicable for ${element.type.name}#${element.id}: ${removedQuestsLog.joinToString()}")
}

return result
}

fun deleteQuests(elementType: Element.Type, elementId: Long): List<Long> {
val ids = questDB.getAllIds(elementType, elementId)
questDB.deleteAll(ids)

Log.d(TAG, "Removed all quests for deleted element " + elementType.name + "#" + elementId)
return ids
}

private fun hasNoteAt(pos: LatLon): Boolean {
// note about one meter around the center of an element still count as at this point as to
// deal with imprecision of the center calculation of geometry (see #1089)
val bbox = SphericalEarthMath.enclosingBoundingBox(pos, 1.0)
return osmNoteQuestDb.getAllPositions(bbox).isNotEmpty()
}

private fun getCurrentQuests(element: Element): Map<QuestType<*>, OsmQuest> {
val quests = questDB.getAll(null, null, null, element.type, element.id)
val result = HashMap<QuestType<*>, OsmQuest>(quests.size)
for (quest in quests) {
if (quest.status == QuestStatus.REVERT) continue
result[quest.type] = quest
}
return result
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package de.westnordost.streetcomplete.data.osm

import de.westnordost.osmapi.map.data.Element
import de.westnordost.streetcomplete.data.osm.changes.SplitWay
import de.westnordost.streetcomplete.data.osm.upload.UploadableInChangeset

data class OsmQuestSplitWay(
val id: Long,
val questType: OsmElementQuestType<*>,
val wayId: Long,
val source: String,
val splits: List<SplitWay>)
override val source: String,
val splits: List<SplitWay>) : UploadableInChangeset {

override val osmElementQuestType get() = questType
override val elementType get() = Element.Type.WAY
override val elementId get() = wayId
}
Original file line number Diff line number Diff line change
@@ -3,16 +3,17 @@ package de.westnordost.streetcomplete.data.osm
import de.westnordost.osmapi.map.data.Element
import de.westnordost.streetcomplete.data.osm.changes.StringMapChanges
import de.westnordost.streetcomplete.data.osm.upload.HasElementTagChanges
import de.westnordost.streetcomplete.data.osm.upload.UploadableInChangeset

class UndoOsmQuest(
val id: Long?,
val type: OsmElementQuestType<*>,
val elementType: Element.Type,
val elementId: Long,
override val elementType: Element.Type,
override val elementId: Long,
override val changes: StringMapChanges,
val changesSource: String,
val geometry: ElementGeometry
) : HasElementTagChanges {
) : UploadableInChangeset, HasElementTagChanges {

constructor(quest: OsmQuest) : this(
null, quest.osmElementQuestType, quest.elementType, quest.elementId,
@@ -22,4 +23,7 @@ class UndoOsmQuest(
of the revert is exactly the opposite of what the quest would normally change and the
element ergo has the changes already applied that a normal quest would add */
override fun isApplicableTo(element: Element) = true

override val source get() = changesSource
override val osmElementQuestType get() = type
}
Original file line number Diff line number Diff line change
@@ -9,5 +9,9 @@ class ChangesetConflictException @JvmOverloads constructor(
open class ElementConflictException @JvmOverloads constructor(
message: String? = null, cause: Throwable? = null) : ConflictException(message, cause)

class ElementDeletedException @JvmOverloads constructor(
/** Element conflict that concern all quests that have something to do with this element */
open class ElementIncompatibleException @JvmOverloads constructor(
message: String? = null, cause: Throwable? = null) : ElementConflictException(message, cause)

class ElementDeletedException @JvmOverloads constructor(
message: String? = null, cause: Throwable? = null) : ElementIncompatibleException(message, cause)
Loading