diff --git a/app/src/androidTest/java/de/westnordost/streetcomplete/quests/AssertUtil.java b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/AssertUtil.java new file mode 100644 index 0000000000..7c95714ab5 --- /dev/null +++ b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/AssertUtil.java @@ -0,0 +1,43 @@ +package de.westnordost.streetcomplete.quests; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.Log; + +import de.westnordost.osmapi.map.data.Element; +import de.westnordost.streetcomplete.data.osm.ElementGeometry; +import de.westnordost.streetcomplete.data.osm.OsmElementQuestType; +import de.westnordost.streetcomplete.data.osm.download.MapDataWithGeometryHandler; + + +import de.westnordost.osmapi.map.data.BoundingBox; + +import static junit.framework.Assert.fail; + + +public class AssertUtil { + public static void verifyYieldsNoQuest(OsmElementQuestType quest, BoundingBox bbox) { + MapDataWithGeometryHandler verifier = (element, geometry) -> + { + fail("Expected zero elements. Element returned: " + + element.getType().name() + "#" + element.getId()); + }; + quest.download(bbox, verifier); + } + + class ElementCounter implements MapDataWithGeometryHandler{ + int count = 0; + @Override + public void handle(@NonNull Element element, @Nullable ElementGeometry geometry) { + count += 1; + } + } + + public void verifyYieldsQuest(OsmElementQuestType quest, BoundingBox bbox) { + ElementCounter counter = new ElementCounter(); + quest.download(bbox, counter); + if(counter.count == 0) { + fail("Expected nonzero elements. Elements not returned"); + } + } +} diff --git a/app/src/androidTest/java/de/westnordost/streetcomplete/quests/add_housenumber/AddHousenumberIntegrationTest.java b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/add_housenumber/AddHousenumberIntegrationTest.java index f762dfe2e3..60ce8c4e0e 100644 --- a/app/src/androidTest/java/de/westnordost/streetcomplete/quests/add_housenumber/AddHousenumberIntegrationTest.java +++ b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/add_housenumber/AddHousenumberIntegrationTest.java @@ -4,8 +4,8 @@ import de.westnordost.osmapi.map.data.BoundingBox; import de.westnordost.streetcomplete.data.OsmModule; -import de.westnordost.streetcomplete.data.osm.download.MapDataWithGeometryHandler; import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao; +import de.westnordost.streetcomplete.quests.AssertUtil; import de.westnordost.streetcomplete.quests.housenumber.AddHousenumber; @@ -144,11 +144,6 @@ private void verifyYieldsNoQuest(BoundingBox bbox, String date) { OverpassMapDataDao o = OsmModule.overpassOldMapDataDao(OsmModule::overpassMapDataParser, date); AddHousenumber quest = new AddHousenumber(o); - MapDataWithGeometryHandler verifier = (element, geometry) -> - { - fail("Expected zero elements. Element returned: " + - element.getType().name() + "#" + element.getId()); - }; - quest.download(bbox, verifier); + AssertUtil.verifyYieldsNoQuest(quest, bbox); } } diff --git a/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedBuildingConstructionIntegrationTest.java b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedBuildingConstructionIntegrationTest.java new file mode 100644 index 0000000000..c3ecce3a30 --- /dev/null +++ b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedBuildingConstructionIntegrationTest.java @@ -0,0 +1,48 @@ +package de.westnordost.streetcomplete.quests.construction; + +import junit.framework.TestCase; + +import java.text.ParseException; + +import de.westnordost.osmapi.map.data.BoundingBox; +import de.westnordost.streetcomplete.data.OsmModule; +import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao; +import de.westnordost.streetcomplete.quests.AssertUtil; + +public class MarkCompletedBuildingConstructionIntegrationTest extends TestCase { + public void test_matching_candidate_is_accepted() throws ParseException { + //https://www.openstreetmap.org/way/494183785#map=19/50.07671/19.94703 + verifyYieldsQuest( + new BoundingBox(50.07664, 19.94671, 50.07672, 19.94700), + "2018-03-01" + ); + } + + public void test_fresh_construction_is_not_accepted() throws ParseException { + //https://www.openstreetmap.org/way/494183785#map=19/50.07671/19.94703 + verifyYieldsNoQuest( + new BoundingBox(50.07664, 19.94671, 50.07672, 19.94700), + "2017-07-30" + ); + } + + public void test_relations_are_accepted() throws ParseException { + //https://www.openstreetmap.org/relation/7405013 + verifyYieldsQuest( + new BoundingBox(55.89375, 37.53794, 55.89441, 37.53857), + "2018-03-01" + ); + } + + private void verifyYieldsNoQuest(BoundingBox bbox, String date) throws ParseException { + OverpassMapDataDao o = OsmModule.overpassOldMapDataDao(OsmModule::overpassMapDataParser, date); + MarkCompletedBuildingConstructionOldData quest = new MarkCompletedBuildingConstructionOldData(o, date); + AssertUtil.verifyYieldsNoQuest(quest, bbox); + } + + private void verifyYieldsQuest(BoundingBox bbox, String date) throws ParseException { + OverpassMapDataDao o = OsmModule.overpassOldMapDataDao(OsmModule::overpassMapDataParser, date); + MarkCompletedBuildingConstructionOldData quest = new MarkCompletedBuildingConstructionOldData(o, date); + new AssertUtil().verifyYieldsQuest(quest, bbox); + } +} diff --git a/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedBuildingConstructionOldData.java b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedBuildingConstructionOldData.java new file mode 100644 index 0000000000..956d70ff82 --- /dev/null +++ b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedBuildingConstructionOldData.java @@ -0,0 +1,27 @@ +package de.westnordost.streetcomplete.quests.construction; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao; +import de.westnordost.streetcomplete.quests.DateUtil; + +public class MarkCompletedBuildingConstructionOldData extends MarkCompletedBuildingConstruction { + private Date date; + MarkCompletedBuildingConstructionOldData(OverpassMapDataDao overpassServer, String dateString) throws ParseException { + super(overpassServer); + date = DateUtil.basicISO8601().parse(dateString); + } + + @Override + protected String getCurrentDateString(){ + return DateUtil.getOffsetDateStringFromDate(0, date) + "T00:00:00Z"; + } + + @Override + protected String getOffsetDateString(int offset){ + return DateUtil.getOffsetDateStringFromDate(offset, date) + "T00:00:00Z"; + } +} diff --git a/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedHighwayConstructionIntegrationTest.java b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedHighwayConstructionIntegrationTest.java new file mode 100644 index 0000000000..fe2540a155 --- /dev/null +++ b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedHighwayConstructionIntegrationTest.java @@ -0,0 +1,56 @@ +package de.westnordost.streetcomplete.quests.construction; + +import junit.framework.TestCase; + +import java.text.ParseException; + +import de.westnordost.osmapi.map.data.BoundingBox; +import de.westnordost.streetcomplete.data.OsmModule; +import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao; +import de.westnordost.streetcomplete.quests.AssertUtil; + +public class MarkCompletedHighwayConstructionIntegrationTest extends TestCase { + public void test_old_highway_construction_triggers_quest() throws ParseException { + //https://www.openstreetmap.org/way/298656945 edited on 2014-08-18 + verifyYieldsQuest( + new BoundingBox(40.01422, -3.02250, 40.01694, -3.02134), + "2018-03-10" + ); + } + + public void test_new_highway_construction_is_not_triggering_quest() throws ParseException { + //https://www.openstreetmap.org/way/298656945 edited on 2014-08-18 + verifyYieldsNoQuest( + new BoundingBox(40.01422, -3.02250, 40.01694, -3.02134), + "2014-08-20" + ); + } + + public void test_opening_date_tag_used_to_filter_out_active_construction() throws ParseException { + //https://www.openstreetmap.org/way/22462987 - 2017-06-30 not generating, 2017-07-01 generating quest + verifyYieldsNoQuest( + new BoundingBox(47.80952, 12.09730, 47.81005, 12.09801), + "2017-06-30" + ); + } + public void test_opening_date_tag_ignored_if_outdated() throws ParseException { + //https://www.openstreetmap.org/way/22462987 - 2017-06-30 not generating, 2017-07-01 generating quest + verifyYieldsQuest( + new BoundingBox(47.80952, 12.09730, 47.81005, 12.09801), + "2017-07-01" + ); + } + + + private void verifyYieldsNoQuest(BoundingBox bbox, String date) throws ParseException { + OverpassMapDataDao o = OsmModule.overpassOldMapDataDao(OsmModule::overpassMapDataParser, date); + MarkCompletedHighwayConstructionOldData quest = new MarkCompletedHighwayConstructionOldData(o, date); + AssertUtil.verifyYieldsNoQuest(quest, bbox); + } + + private void verifyYieldsQuest(BoundingBox bbox, String date) throws ParseException { + OverpassMapDataDao o = OsmModule.overpassOldMapDataDao(OsmModule::overpassMapDataParser, date); + MarkCompletedHighwayConstructionOldData quest = new MarkCompletedHighwayConstructionOldData(o, date); + new AssertUtil().verifyYieldsQuest(quest, bbox); + } +} diff --git a/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedHighwayConstructionOldData.java b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedHighwayConstructionOldData.java new file mode 100644 index 0000000000..8f63893ca9 --- /dev/null +++ b/app/src/androidTest/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedHighwayConstructionOldData.java @@ -0,0 +1,27 @@ +package de.westnordost.streetcomplete.quests.construction; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao; +import de.westnordost.streetcomplete.quests.DateUtil; + +public class MarkCompletedHighwayConstructionOldData extends MarkCompletedHighwayConstruction { + private Date date; + MarkCompletedHighwayConstructionOldData(OverpassMapDataDao overpassServer, String dateString) throws ParseException { + super(overpassServer); + date = DateUtil.basicISO8601().parse(dateString); + } + + @Override + protected String getCurrentDateString(){ + return DateUtil.getOffsetDateStringFromDate(0, date) + "T00:00:00Z"; + } + + @Override + protected String getOffsetDateString(int offset){ + return DateUtil.getOffsetDateStringFromDate(offset, date) + "T00:00:00Z"; + } +} diff --git a/app/src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.java b/app/src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.java index 8c3d269d8d..2e0116cd1f 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.java +++ b/app/src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.java @@ -7,4 +7,13 @@ public class OsmTaggings "unpaved","compacted","gravel","fine_gravel","pebblestone","grass_paver", "ground","earth","dirt","grass","sand","mud","ice","salt","snow","woodchips" }; + + public static final String[] ALL_ROADS = { + "motorway", "motorway_link", "trunk", "trunk_link", "primary", "primary_link", + "secondary", "secondary_link", "tertiary", "tertiary_link", + "unclassified", "residential", "living_street", "pedestrian", + "service", "track", "road", + }; + + public static final String SURVEY_MARK_KEY = "check_date"; } diff --git a/app/src/main/java/de/westnordost/streetcomplete/data/osm/changes/StringMapChangesBuilder.java b/app/src/main/java/de/westnordost/streetcomplete/data/osm/changes/StringMapChangesBuilder.java index def690f260..770cd0ef94 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/data/osm/changes/StringMapChangesBuilder.java +++ b/app/src/main/java/de/westnordost/streetcomplete/data/osm/changes/StringMapChangesBuilder.java @@ -29,6 +29,15 @@ public void delete(@NonNull String key) changes.put(key, new StringMapEntryDelete(key, valueBefore)); } + public void deleteIfExists(@NonNull String key) + { + if(source.get(key) == null) + { + return; + } + delete(key); + } + public void add(@NonNull String key, @NonNull String value) { if(source.containsKey(key)) diff --git a/app/src/main/java/de/westnordost/streetcomplete/data/osm/download/OverpassOldMapDataDao.java b/app/src/main/java/de/westnordost/streetcomplete/data/osm/download/OverpassOldMapDataDao.java index cee19651c0..6e3098d37a 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/data/osm/download/OverpassOldMapDataDao.java +++ b/app/src/main/java/de/westnordost/streetcomplete/data/osm/download/OverpassOldMapDataDao.java @@ -1,7 +1,5 @@ package de.westnordost.streetcomplete.data.osm.download; -import java.time.LocalDate; - import javax.inject.Provider; import de.westnordost.osmapi.OsmConnection; diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/DateUtil.java b/app/src/main/java/de/westnordost/streetcomplete/quests/DateUtil.java new file mode 100644 index 0000000000..c44f74124e --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/DateUtil.java @@ -0,0 +1,26 @@ +package de.westnordost.streetcomplete.quests; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class DateUtil { + public static SimpleDateFormat basicISO8601(){ + return new SimpleDateFormat("yyyy-MM-dd"); + + } + public static String getOffsetDateStringFromDate(final int offsetInDays, final Date date){ + Calendar modifiedCalendar = Calendar.getInstance(); + modifiedCalendar.setTime(date); + modifiedCalendar.add(Calendar.DAY_OF_MONTH, offsetInDays); + return basicISO8601().format(modifiedCalendar.getTime()); + } + + public static String getOffsetDateString(int offsetInDays){ + return getOffsetDateStringFromDate(offsetInDays, Calendar.getInstance().getTime()); + } + + public static String getCurrentDateString() { + return getOffsetDateString(0); + } +} diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.java b/app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.java index 1972b82511..ab0819c6c2 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.java @@ -20,6 +20,8 @@ import de.westnordost.streetcomplete.quests.localized_name.AddBusStopName; import de.westnordost.streetcomplete.quests.bus_stop_shelter.AddBusStopShelter; import de.westnordost.streetcomplete.quests.car_wash_type.AddCarWashType; +import de.westnordost.streetcomplete.quests.construction.MarkCompletedBuildingConstruction; +import de.westnordost.streetcomplete.quests.construction.MarkCompletedHighwayConstruction; import de.westnordost.streetcomplete.quests.crossing_type.AddCrossingType; import de.westnordost.streetcomplete.quests.diet_type.AddVegan; import de.westnordost.streetcomplete.quests.diet_type.AddVegetarian; @@ -68,6 +70,7 @@ public class QuestModule // ↓ 2. important data that is used by many data consumers new AddRoadName(o, roadNameSuggestionsDao, putRoadNameSuggestionsHandler), new AddHousenumber(o), + new MarkCompletedHighwayConstruction(o), // new AddPlaceName(o), doesn't make sense as long as the app cannot tell the generic name of elements // ↓ 3. useful data that is used by some data consumers @@ -109,6 +112,7 @@ public class QuestModule new AddWheelChairAccessToilets(o), new AddReligionToWaysideShrine(o), new AddBikeParkingType(o), + new MarkCompletedBuildingConstruction(o), // ↓ 8. defined in the wiki, but not really used by anyone yet. Just collected for // the sake of mapping it in case it makes sense later diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedBuildingConstruction.java b/app/src/main/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedBuildingConstruction.java new file mode 100644 index 0000000000..5b55a2623c --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedBuildingConstruction.java @@ -0,0 +1,74 @@ +package de.westnordost.streetcomplete.quests.construction; + +import android.os.Bundle; +import android.support.annotation.NonNull; + +import java.util.Map; + +import javax.inject.Inject; + +import de.westnordost.osmapi.map.data.BoundingBox; +import de.westnordost.streetcomplete.R; +import de.westnordost.streetcomplete.data.meta.OsmTaggings; +import de.westnordost.streetcomplete.data.osm.changes.StringMapChangesBuilder; +import de.westnordost.streetcomplete.data.osm.download.MapDataWithGeometryHandler; +import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao; +import de.westnordost.streetcomplete.data.osm.tql.OverpassQLUtil; +import de.westnordost.streetcomplete.quests.DateUtil; +import de.westnordost.streetcomplete.quests.YesNoQuestAnswerFragment; + +public class MarkCompletedBuildingConstruction extends MarkCompletedConstruction +{ + @Inject + public MarkCompletedBuildingConstruction(OverpassMapDataDao overpassServer) { + super(overpassServer); + } + + @Override public boolean download(BoundingBox bbox, MapDataWithGeometryHandler handler) + { + return overpassServer.getAndHandleQuota(getOverpassQuery(bbox), handler); + } + + /** @return overpass query string to get buildings marked as under construction but excluding ones + * - with tagged opening date that is in future + * - recently edited (includes adding/updating check_date tags) + * . */ + private String getOverpassQuery(BoundingBox bbox) + { + String groupName = ".buildings_under_construction"; + String wayGroupName = groupName + "_ways"; + String relationGroupName = groupName + "_relations"; + return OverpassQLUtil.getGlobalOverpassBBox(bbox) + + "way" + getQueryPart("building", wayGroupName, 180) + + "relation" + getQueryPart("building", relationGroupName, 180) + + "(" + wayGroupName + "; " + relationGroupName + ";); out meta geom;"; + } + + public void applyAnswerTo(Bundle answer, StringMapChangesBuilder changes) + { + if(answer.getBoolean(YesNoQuestAnswerFragment.ANSWER)) { + String constructionValue = changes.getPreviousValue("construction"); + if(constructionValue == null) { + constructionValue = "yes"; + } + changes.modify("building", constructionValue); + removeTagsDescribingConstruction(changes); + } else { + changes.addOrModify(OsmTaggings.SURVEY_MARK_KEY, DateUtil.getCurrentDateString()); + } + } + + @Override + public int getIcon() { + return R.drawable.ic_quest_building_construction; + } + + @Override + public int getTitle() { + return R.string.quest_construction_building_title; + } + + @Override public int getTitle(@NonNull Map tags) { + return R.string.quest_construction_building_title; + } +} diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedConstruction.java b/app/src/main/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedConstruction.java new file mode 100644 index 0000000000..54b11a5d5a --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedConstruction.java @@ -0,0 +1,92 @@ +package de.westnordost.streetcomplete.quests.construction; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import de.westnordost.osmapi.map.data.Element; +import de.westnordost.streetcomplete.data.meta.OsmTaggings; +import de.westnordost.streetcomplete.data.osm.Countries; +import de.westnordost.streetcomplete.data.osm.OsmElementQuestType; +import de.westnordost.streetcomplete.data.osm.changes.StringMapChangesBuilder; +import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao; +import de.westnordost.streetcomplete.quests.AbstractQuestAnswerFragment; +import de.westnordost.streetcomplete.quests.DateUtil; +import de.westnordost.streetcomplete.quests.YesNoQuestAnswerFragment; + +public abstract class MarkCompletedConstruction implements OsmElementQuestType { + protected final OverpassMapDataDao overpassServer; + + MarkCompletedConstruction(OverpassMapDataDao overpassServer) + { + this.overpassServer = overpassServer; + } + + @Nullable + @Override public Boolean isApplicableTo(Element element) + { + /* Whether this element applies to this quest cannot be determined by looking at that + element alone (see download()), an Overpass query would need to be made to find this out. + This is too heavy-weight for this method so it always returns false. */ + + /* The implications of this are that this quest will never be created directly + as consequence of solving another quest and also after reverting an input, + the quest will not immediately pop up again. Instead, they are downloaded well after an + element became fit for this quest. */ + return null; + } + + public AbstractQuestAnswerFragment createForm() + { + return new YesNoQuestAnswerFragment(); + } + + protected String getCurrentDateString(){ + return DateUtil.getCurrentDateString() + "T00:00:00Z"; + } + + protected String getOffsetDateString(int offset){ + return DateUtil.getOffsetDateString(offset) + "T00:00:00Z"; + } + + String getQueryPart(String key, String nameOfGeneratedGroup, int reviewIntervalInDays){ + + // Note that newer segment will ensure that any edit, + // including adding or updating review marker like check_date or survey:date tags + // will cause OSM elements to become ineligible for this quest for reviewIntervalInDays days. + // It allows supporting check_date and any other survey markers without parsing of any tags. + return "[" + key + "=construction]" + + "(if:!is_date(t['opening_date']) || date(t['opening_date']) .construction_with_unknown_state; " + + getRecentlyEditedConstructionsQueryPart(key, reviewIntervalInDays) + " -> .recently_edited_construction;" + + "(.construction_with_unknown_state - .recently_edited_construction) -> " + nameOfGeneratedGroup + ";"; + } + + private String getRecentlyEditedConstructionsQueryPart(String key, int reviewIntervalInDays){ + return "(" + + "way[" + key + "=construction](newer: '" + getOffsetDateString(-reviewIntervalInDays) +"');" + + "relation[" + key + "=construction](newer: '" + getOffsetDateString(-reviewIntervalInDays) +"');" + + ")"; + } + + void removeTagsDescribingConstruction(StringMapChangesBuilder changes) { + changes.deleteIfExists("construction"); + changes.deleteIfExists("source:construction"); + changes.deleteIfExists("opening_date"); + changes.deleteIfExists("source:opening_date"); + changes.deleteIfExists(OsmTaggings.SURVEY_MARK_KEY); + changes.deleteIfExists("source:" + OsmTaggings.SURVEY_MARK_KEY); + } + + @Override public String getCommitMessage() { return "Determine whether construction is now completed"; } + + @NonNull + @Override + public Countries getEnabledForCountries() { + return Countries.ALL; + } + + @Override + public int getDefaultDisabledMessage() { + return 0; + } +} diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedHighwayConstruction.java b/app/src/main/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedHighwayConstruction.java new file mode 100644 index 0000000000..7d6c61542b --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedHighwayConstruction.java @@ -0,0 +1,82 @@ +package de.westnordost.streetcomplete.quests.construction; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.text.TextUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Map; + +import javax.inject.Inject; + +import de.westnordost.osmapi.map.data.BoundingBox; +import de.westnordost.streetcomplete.R; +import de.westnordost.streetcomplete.data.meta.OsmTaggings; +import de.westnordost.streetcomplete.data.osm.changes.StringMapChangesBuilder; +import de.westnordost.streetcomplete.data.osm.download.MapDataWithGeometryHandler; +import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao; +import de.westnordost.streetcomplete.data.osm.tql.OverpassQLUtil; +import de.westnordost.streetcomplete.quests.DateUtil; +import de.westnordost.streetcomplete.quests.YesNoQuestAnswerFragment; + +public class MarkCompletedHighwayConstruction extends MarkCompletedConstruction +{ + @Inject + public MarkCompletedHighwayConstruction(OverpassMapDataDao overpassServer) { + super(overpassServer); + } + + @Override public boolean download(BoundingBox bbox, MapDataWithGeometryHandler handler) + { + return overpassServer.getAndHandleQuota(getOverpassQuery(bbox), handler); + } + + /** @return overpass query string to get streets marked as under construction but excluding ones + * - with invalid construction tag + * - with tagged opening date that is in future + * - recently edited (includes adding/updating check_date tags) + * . */ + private String getOverpassQuery(BoundingBox bbox) + { + String groupName = ".roads_for_review"; + return OverpassQLUtil.getGlobalOverpassBBox(bbox) + + "way" + getQueryPart("highway", groupName, 14) + + groupName + " out meta geom;"; + } + + public void applyAnswerTo(Bundle answer, StringMapChangesBuilder changes) + { + if(answer.getBoolean(YesNoQuestAnswerFragment.ANSWER)) { + String constructionValue = changes.getPreviousValue("construction"); + if(constructionValue == null) { + constructionValue = "road"; + } + changes.modify("highway", constructionValue); + removeTagsDescribingConstruction(changes); + } else { + changes.addOrModify(OsmTaggings.SURVEY_MARK_KEY, DateUtil.getCurrentDateString()); + } + } + + @Override + public int getIcon() { + return R.drawable.ic_quest_road_construction; + } + + @Override + public int getTitle() { + return R.string.quest_construction_road_title; + } + + @Override public int getTitle(@NonNull Map tags) { + if (Arrays.asList(OsmTaggings.ALL_ROADS).contains(tags.get("construction"))){ + return R.string.quest_construction_road_title; + } else if (tags.get("construction") == "cycleway") { + return R.string.quest_construction_cycleway_title; + } else if (tags.get("construction") == "footway") { + return R.string.quest_construction_footway_title; + } + return R.string.quest_construction_generic_title; + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 219f9dbad4..0bf42044e4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -509,4 +509,9 @@ Otherwise, you can download another keyboard in the app store. Popular keyboards What are the collection times of this postbox? Add collection time No times specified + Is this road completed? + Is this cycleway completed? + Is this footway completed? + Is this way completed? + Is this building completed?