From 02f38ac8f140e202308552c780ccddac83f276d4 Mon Sep 17 00:00:00 2001 From: ENT8R Date: Thu, 8 Mar 2018 18:01:39 +0100 Subject: [PATCH 01/35] Add new quest to determine the maximum height of some elements --- app/src/main/assets/country_metadata/CA.yml | 1 + app/src/main/assets/country_metadata/FM.yml | 1 + app/src/main/assets/country_metadata/GB.yml | 1 + app/src/main/assets/country_metadata/LR.yml | 1 + app/src/main/assets/country_metadata/MH.yml | 1 + app/src/main/assets/country_metadata/MM.yml | 1 + app/src/main/assets/country_metadata/PW.yml | 1 + app/src/main/assets/country_metadata/US.yml | 1 + app/src/main/assets/country_metadata/WS.yml | 1 + .../main/assets/country_metadata/default.yml | 1 + .../streetcomplete/data/meta/CountryInfo.java | 6 + .../data/osm/SimpleOverpassQuestType.java | 1 + .../streetcomplete/quests/QuestModule.java | 2 + .../quests/max_height/AddMaxHeight.java | 99 +++++++++ .../quests/max_height/AddMaxHeightForm.java | 196 ++++++++++++++++++ .../drawable/background_max_height_sign.xml | 17 ++ .../drawable/background_maxheight_sign.xml | 24 +++ .../drawable/background_maxheight_sign_us.xml | 19 ++ .../ic_arrow_drop_down_black_24dp.xml | 9 + .../drawable/ic_arrow_drop_up_black_24dp.xml | 9 + app/src/main/res/layout/quest_max_height.xml | 32 +++ .../main/res/layout/quest_max_height_us.xml | 69 ++++++ app/src/main/res/values/strings.xml | 11 + res/country_metadata/heightUnit.yml | 13 ++ 24 files changed, 517 insertions(+) create mode 100644 app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java create mode 100644 app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java create mode 100644 app/src/main/res/drawable/background_max_height_sign.xml create mode 100644 app/src/main/res/drawable/background_maxheight_sign.xml create mode 100644 app/src/main/res/drawable/background_maxheight_sign_us.xml create mode 100644 app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml create mode 100644 app/src/main/res/layout/quest_max_height.xml create mode 100644 app/src/main/res/layout/quest_max_height_us.xml create mode 100644 res/country_metadata/heightUnit.yml diff --git a/app/src/main/assets/country_metadata/CA.yml b/app/src/main/assets/country_metadata/CA.yml index 840994a2c5..39a92e482d 100644 --- a/app/src/main/assets/country_metadata/CA.yml +++ b/app/src/main/assets/country_metadata/CA.yml @@ -1,5 +1,6 @@ # Do not edit. Source files are in /res/country_metadata advisorySpeedLimitLayout: quest_maxspeed_advisory_yellow +heightUnit: [ft, m] isAdvisorySpeedLimitKnown: true isSlowZoneKnown: false maxspeedLayout: quest_maxspeed_ca diff --git a/app/src/main/assets/country_metadata/FM.yml b/app/src/main/assets/country_metadata/FM.yml index 04ab30b4e9..397fbd2906 100644 --- a/app/src/main/assets/country_metadata/FM.yml +++ b/app/src/main/assets/country_metadata/FM.yml @@ -1,3 +1,4 @@ # Do not edit. Source files are in /res/country_metadata +heightUnit: [ft, m] officialLanguages: [en, chk, pon] orchardProduces: [coconut, banana, cacao] diff --git a/app/src/main/assets/country_metadata/GB.yml b/app/src/main/assets/country_metadata/GB.yml index aeba877a23..af5c7e1d05 100644 --- a/app/src/main/assets/country_metadata/GB.yml +++ b/app/src/main/assets/country_metadata/GB.yml @@ -1,6 +1,7 @@ # Do not edit. Source files are in /res/country_metadata additionalStreetsignLanguages: [cy, gd] advisorySpeedLimitLayout: quest_maxspeed_advisory_white +heightUnit: [ft, m] isAdvisorySpeedLimitKnown: true isLeftHandTraffic: true isLivingStreetKnown: true diff --git a/app/src/main/assets/country_metadata/LR.yml b/app/src/main/assets/country_metadata/LR.yml index adce5281bd..7d6de8f3b4 100644 --- a/app/src/main/assets/country_metadata/LR.yml +++ b/app/src/main/assets/country_metadata/LR.yml @@ -1,3 +1,4 @@ # Do not edit. Source files are in /res/country_metadata +heightUnit: [ft, m] officialLanguages: [en] orchardProduces: [rubber, cacao, palm_oil, banana, coffee, coconut, orange, pineapple, tomatoe] diff --git a/app/src/main/assets/country_metadata/MH.yml b/app/src/main/assets/country_metadata/MH.yml index 02fd2dfe2b..b908f7df34 100644 --- a/app/src/main/assets/country_metadata/MH.yml +++ b/app/src/main/assets/country_metadata/MH.yml @@ -1,3 +1,4 @@ # Do not edit. Source files are in /res/country_metadata +heightUnit: [ft, m] officialLanguages: [mh, en] orchardProduces: [coconut] diff --git a/app/src/main/assets/country_metadata/MM.yml b/app/src/main/assets/country_metadata/MM.yml index 56b7dc46ee..357d6fb910 100644 --- a/app/src/main/assets/country_metadata/MM.yml +++ b/app/src/main/assets/country_metadata/MM.yml @@ -1,5 +1,6 @@ # Do not edit. Source files are in /res/country_metadata additionalStreetsignLanguages: [en] +heightUnit: [ft, m] officialLanguages: [my] orchardProduces: [rubber, chilli_pepper, sweet_pepper, tea, areca_nut, coconut, coffee, cashew_nut, guava, mango, mangosteen] diff --git a/app/src/main/assets/country_metadata/PW.yml b/app/src/main/assets/country_metadata/PW.yml index 192095639a..49c8772e5e 100644 --- a/app/src/main/assets/country_metadata/PW.yml +++ b/app/src/main/assets/country_metadata/PW.yml @@ -1,2 +1,3 @@ # Do not edit. Source files are in /res/country_metadata +heightUnit: [ft, m] officialLanguages: [en, pau] diff --git a/app/src/main/assets/country_metadata/US.yml b/app/src/main/assets/country_metadata/US.yml index 530776571c..480ba40e9c 100644 --- a/app/src/main/assets/country_metadata/US.yml +++ b/app/src/main/assets/country_metadata/US.yml @@ -1,5 +1,6 @@ # Do not edit. Source files are in /res/country_metadata advisorySpeedLimitLayout: quest_maxspeed_advisory_yellow +heightUnit: [ft] isAdvisorySpeedLimitKnown: true maxspeedLayout: quest_maxspeed_us officialLanguages: [en] diff --git a/app/src/main/assets/country_metadata/WS.yml b/app/src/main/assets/country_metadata/WS.yml index a3edd22d7f..521cc20ebc 100644 --- a/app/src/main/assets/country_metadata/WS.yml +++ b/app/src/main/assets/country_metadata/WS.yml @@ -1,4 +1,5 @@ # Do not edit. Source files are in /res/country_metadata +heightUnit: [ft, m] isLeftHandTraffic: true officialLanguages: [sm, en] popularSports: [cricket] diff --git a/app/src/main/assets/country_metadata/default.yml b/app/src/main/assets/country_metadata/default.yml index 84cac3b6d0..51480ed7f4 100644 --- a/app/src/main/assets/country_metadata/default.yml +++ b/app/src/main/assets/country_metadata/default.yml @@ -1,6 +1,7 @@ # Do not edit. Source files are in /res/country_metadata advisorySpeedLimitLayout: quest_maxspeed_advisory_blue firstDayOfWorkweek: Mo +heightUnit: [m] isAdvisorySpeedLimitKnown: false isLeftHandTraffic: false isLivingStreetKnown: false diff --git a/app/src/main/java/de/westnordost/streetcomplete/data/meta/CountryInfo.java b/app/src/main/java/de/westnordost/streetcomplete/data/meta/CountryInfo.java index 219dab5be7..cd350eb552 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/data/meta/CountryInfo.java +++ b/app/src/main/java/de/westnordost/streetcomplete/data/meta/CountryInfo.java @@ -15,6 +15,7 @@ public class CountryInfo implements Serializable, Cloneable // generic properties List speedUnit; + List heightUnit; List popularSports; List popularReligions; String firstDayOfWorkweek; @@ -38,6 +39,11 @@ public List getSpeedUnits() return speedUnit; } + public List getHeightUnits() + { + return heightUnit; + } + public List getPopularSports() { if(popularSports == null) return new ArrayList<>(1); diff --git a/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java b/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java index cbdd615ad0..844cbc7f4b 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java +++ b/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java @@ -2,6 +2,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.util.Log; import java.util.Collections; 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 78379de511..f4168511a5 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.java @@ -23,6 +23,7 @@ import de.westnordost.streetcomplete.quests.diet_type.AddVegetarian; import de.westnordost.streetcomplete.quests.fire_hydrant.AddFireHydrantType; import de.westnordost.streetcomplete.quests.internet_access.AddInternetAccess; +import de.westnordost.streetcomplete.quests.max_height.AddMaxHeight; import de.westnordost.streetcomplete.quests.parking_access.AddParkingAccess; import de.westnordost.streetcomplete.quests.parking_fee.AddParkingFee; import de.westnordost.streetcomplete.quests.parking_type.AddParkingType; @@ -71,6 +72,7 @@ public class QuestModule new AddRecyclingType(o), new AddRoadSurface(o), new AddMaxSpeed(o), // should best be after road surface because it excludes unpaved roads + new AddMaxHeight(o), new AddReligionToPlaceOfWorship(o), // icon on maps are different new AddOpeningHours(o), new AddSport(o), diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java new file mode 100644 index 0000000000..34788b945b --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java @@ -0,0 +1,99 @@ +package de.westnordost.streetcomplete.quests.max_height; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import java.util.Map; + +import javax.inject.Inject; + +import de.westnordost.osmapi.map.data.BoundingBox; +import de.westnordost.osmapi.map.data.Element; +import de.westnordost.streetcomplete.R; +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.MapDataWithGeometryHandler; +import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao; +import de.westnordost.streetcomplete.data.osm.tql.OverpassQLUtil; +import de.westnordost.streetcomplete.quests.AbstractQuestAnswerFragment; + +public class AddMaxHeight implements OsmElementQuestType +{ + + private final OverpassMapDataDao overpassServer; + + @Inject public AddMaxHeight(OverpassMapDataDao overpassServer) + { + this.overpassServer = overpassServer; + } + + /*the query does not exclude elements which are not accessible by the public, + because a maxheight sign will very probably be visible at the entrance or beginning*/ + private static final String QUERY_RESTRICTIONS = "['maxheight'!~'.']['maxheight:physical'!~'.']"; + + private static final String ROADS = "(primary|secondary|tertiary|trunk)(_link)?|motorway|service|residential|unclassified|living_street"; + + @Override public boolean download(BoundingBox bbox, MapDataWithGeometryHandler handler) + { + return overpassServer.getAndHandleQuota(getOverpassQuery(bbox), handler); + } + + private static String getOverpassQuery(BoundingBox bbox) + { + return OverpassQLUtil.getGlobalOverpassBBox(bbox) + + "(" + + " node['barrier'='height_restrictor']" + QUERY_RESTRICTIONS + ";" + + " node['amenity'='parking_entrance']['parking'~'^(underground|multi-storey)$']" + QUERY_RESTRICTIONS + ";" + + " way['highway'~'^(" + ROADS + ")$']['tunnel'~'^(yes|building_passage)$']" + QUERY_RESTRICTIONS + ";" + + " way['highway'~'^(" + ROADS + ")$']['covered'='yes']" + QUERY_RESTRICTIONS + ";" + + ");" + + "out meta geom;"; + } + + @Override public AbstractQuestAnswerFragment createForm() + { + return new AddMaxHeightForm(); + } + + @Override public void applyAnswerTo(Bundle answer, StringMapChangesBuilder changes) + { + boolean hasNoSign = answer.getBoolean(AddMaxHeightForm.NO_SIGN); + String maxheight = answer.getString(AddMaxHeightForm.MAX_HEIGHT); + if(hasNoSign) + { + /*TODO: maxheight=default or maxheight=no_sign? + according to https://taginfo.openstreetmap.org/keys/maxheight#values maxheight=no_sign is only used 14 times, + while maxheight=default is used about 10K times*/ + changes.add("maxheight", "default"); + } + else + { + if (maxheight != null) + { + changes.add("maxheight", maxheight); + } + } + } + + @Override public String getCommitMessage() { return "Add maximum height"; } + @Override public int getIcon() { return R.drawable.ic_quest_max_height; } + @Override public int getTitle(@NonNull Map tags) + { + boolean isParkingEntrance = "parking_entrance".equals(tags.get("amenity")); + boolean isHeightRestrictor = "height_restrictor".equals(tags.get("barrier")); + boolean isTunnel = "yes".equals(tags.get("tunnel")); + + if (isParkingEntrance) return R.string.quest_maxheight_parking_entrance_title; + if (isHeightRestrictor) return R.string.quest_maxheight_height_restrictor_title; + if (isTunnel) return R.string.quest_maxheight_tunnel_title; + + return R.string.quest_maxheight_title; + } + + @Override public int getTitle() { return R.string.quest_maxheight_title; } + @Override public int getDefaultDisabledMessage() { return 0; } + @Nullable @Override public Boolean isApplicableTo(Element element) { return null; } + @NonNull @Override public Countries getEnabledForCountries() { return Countries.ALL; } +} diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java new file mode 100644 index 0000000000..0071199313 --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java @@ -0,0 +1,196 @@ +package de.westnordost.streetcomplete.quests.max_height; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.Toast; + +import de.westnordost.streetcomplete.R; +import de.westnordost.streetcomplete.quests.AbstractQuestFormAnswerFragment; +import de.westnordost.streetcomplete.view.dialogs.AlertDialogBuilder; + +public class AddMaxHeightForm extends AbstractQuestFormAnswerFragment +{ + public static final String + MAX_HEIGHT = "max_height", + NO_SIGN = "no_sign"; + + private EditText heightInput, feetInput, inchInput; + + private boolean isMetric; + + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) + { + View view = super.onCreateView(inflater, container, savedInstanceState); + + isMetric = getCountryInfo().getHeightUnits().get(0).equals("m"); + + setMaxHeightSignLayout(getMaxHeightLayoutResourceId()); + addOtherAnswers(); + + return view; + } + + private void setMaxHeightSignLayout(int resourceId) + { + View contentView = setContentView(resourceId); + + heightInput = contentView.findViewById(R.id.maxHeightInput); + feetInput = contentView.findViewById(R.id.maxHeightFeetInput); + inchInput = contentView.findViewById(R.id.maxHeightInchInput); + } + + private int getMaxHeightLayoutResourceId() + { + return isMetric ? R.layout.quest_max_height : R.layout.quest_max_height_us; + } + + private void addOtherAnswers() + { + + if (getCountryInfo().getHeightUnits().size() == 2) + { + if (isMetric) + { + addOtherAnswer(R.string.quest_maxheight_answer_imperial_unit, () -> + { + isMetric = false; + setMaxHeightSignLayout(getMaxHeightLayoutResourceId()); + }); + } + else + { + addOtherAnswer(R.string.quest_maxheight_answer_metric_unit, () -> + { + isMetric = true; + setMaxHeightSignLayout(getMaxHeightLayoutResourceId()); + }); + } + } + + addOtherAnswer(R.string.quest_maxheight_answer_noSign, () -> + { + new AlertDialogBuilder(getActivity()) + .setTitle(R.string.quest_maxheight_answer_noSign_confirmation_title) + .setMessage(R.string.quest_maxheight_answer_noSign_confirmation) + .setPositiveButton(R.string.quest_maxheight_answer_noSign_confirmation_positive, (dialog, which) -> { + Bundle answer = new Bundle(); + answer.putBoolean(NO_SIGN, true); + applyImmediateAnswer(answer); + }) + .setNegativeButton(R.string.quest_generic_confirmation_no, null) + .show(); + }); + } + + @Override protected void onClickOk() + { + if(!hasChanges()) + { + Toast.makeText(getActivity(), R.string.no_changes, Toast.LENGTH_SHORT).show(); + return; + } + + if(userSelectedUnrealisticHeight()) + { + confirmUnusualInput(this::applyMaxHeightFormAnswer); + } + else + { + applyMaxHeightFormAnswer(); + } + } + + private boolean userSelectedUnrealisticHeight() + { + double height = Double.parseDouble(getHeightFromInput()); + double heightInMeter = isMetric ? height : feetToMeter(height); + return heightInMeter > 6; + } + + private static double feetToMeter(double feet) + { + return feet / 3.2808; + } + + private void applyMaxHeightFormAnswer() + { + Bundle answer = new Bundle(); + + String height = getFinalMaxHeight(getHeightFromInput()); + + // metric is the OSM default, does not need to be mentioned + if(!isMetric) + { + //this adds an apostrophe and a double-quote to be in a format like e.g. 6'7" + height = height.replace(".", "'"); + height += "\""; + } + answer.putString(MAX_HEIGHT, height); + + applyFormAnswer(answer); + } + + private String getFinalMaxHeight(String value) + { + if (isMetric) + { + /*TODO: should a trailing zero be added or does it even work without? + https://taginfo.openstreetmap.org/keys/maxheight#values contains both...*/ + if (!value.contains(".")) + { + value += ".0"; + } + return value; + } + else + { + return value.replace(".", "'") + "\""; + } + } + + private String getHeightFromInput() + { + if (isMetric) + { + if (!heightInput.getText().toString().isEmpty()) + { + + return heightInput.getText().toString().replace(",", "."); + } + else + { + return null; + } + } + else + { + if (!feetInput.getText().toString().isEmpty() && !inchInput.getText().toString().isEmpty()) + { + return feetInput.getText().toString() + "." + inchInput.getText().toString(); + } + else + { + return null; + } + } + } + + private void confirmUnusualInput(final Runnable callback) + { + new AlertDialogBuilder(getActivity()) + .setTitle(R.string.quest_generic_confirmation_title) + .setMessage(R.string.quest_maxheight_unusualInput_confirmation_description) + .setPositiveButton(R.string.quest_generic_confirmation_yes, (dialog, which) -> callback.run()) + .setNegativeButton(R.string.quest_generic_confirmation_no, null) + .show(); + } + + @Override public boolean hasChanges() + { + return getHeightFromInput() != null; + } +} diff --git a/app/src/main/res/drawable/background_max_height_sign.xml b/app/src/main/res/drawable/background_max_height_sign.xml new file mode 100644 index 0000000000..b05b022a7c --- /dev/null +++ b/app/src/main/res/drawable/background_max_height_sign.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/app/src/main/res/drawable/background_maxheight_sign.xml b/app/src/main/res/drawable/background_maxheight_sign.xml new file mode 100644 index 0000000000..d97570fd66 --- /dev/null +++ b/app/src/main/res/drawable/background_maxheight_sign.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/background_maxheight_sign_us.xml b/app/src/main/res/drawable/background_maxheight_sign_us.xml new file mode 100644 index 0000000000..1f2612f231 --- /dev/null +++ b/app/src/main/res/drawable/background_maxheight_sign_us.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml new file mode 100644 index 0000000000..62b27ef0b9 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml new file mode 100644 index 0000000000..b1442ce159 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/quest_max_height.xml b/app/src/main/res/layout/quest_max_height.xml new file mode 100644 index 0000000000..1236faf8fa --- /dev/null +++ b/app/src/main/res/layout/quest_max_height.xml @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/quest_max_height_us.xml b/app/src/main/res/layout/quest_max_height_us.xml new file mode 100644 index 0000000000..7bfca9eeb9 --- /dev/null +++ b/app/src/main/res/layout/quest_max_height_us.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 39953cbee8..367cde8a00 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -495,4 +495,15 @@ Otherwise, you can download another keyboard in the app store. Popular keyboards Yes, but only… Yes, but not… at the following times: + "What is the height limit here?" + What is the height limit of this parking entrance? + What is the height limit of this height restrictor? + What is the height limit of this tunnel? + There is no sign + Are you sure there is no sign? + Did you check at both ends? If there is no sign, default limits apply. + Yes, no sign + This height looks implausible + The unit is imperial + The unit is metric diff --git a/res/country_metadata/heightUnit.yml b/res/country_metadata/heightUnit.yml new file mode 100644 index 0000000000..6ad4ea1e5c --- /dev/null +++ b/res/country_metadata/heightUnit.yml @@ -0,0 +1,13 @@ +# Sources: +# https://en.wikipedia.org/wiki/Metrication#Overview +# https://en.wikipedia.org/wiki/Imperial_units#Current_use +default: [m] +CA: [ft, m] +FM: [ft, m] +GB: [ft, m] +LR: [ft, m] +MH: [ft, m] +MM: [ft, m] +PW: [ft, m] +US: [ft] +WS: [ft, m] From 7ff5c4a17fca6f53246021520f2dce36aaa1d44b Mon Sep 17 00:00:00 2001 From: ENT8R Date: Thu, 8 Mar 2018 20:07:39 +0100 Subject: [PATCH 02/35] Remove unnecessary import statement --- .../streetcomplete/data/osm/SimpleOverpassQuestType.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java b/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java index 844cbc7f4b..cbdd615ad0 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java +++ b/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java @@ -2,7 +2,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.util.Log; import java.util.Collections; From 59b437425c51bacc9c0fd8c8b9866c86e4f474e2 Mon Sep 17 00:00:00 2001 From: ENT8R Date: Thu, 8 Mar 2018 20:10:22 +0100 Subject: [PATCH 03/35] Remove now unnecessary drawable files --- ....xml => background_max_height_sign_us.xml} | 0 .../drawable/background_maxheight_sign.xml | 24 ------------------- .../ic_arrow_drop_down_black_24dp.xml | 9 ------- .../drawable/ic_arrow_drop_up_black_24dp.xml | 9 ------- .../main/res/layout/quest_max_height_us.xml | 2 +- 5 files changed, 1 insertion(+), 43 deletions(-) rename app/src/main/res/drawable/{background_maxheight_sign_us.xml => background_max_height_sign_us.xml} (100%) delete mode 100644 app/src/main/res/drawable/background_maxheight_sign.xml delete mode 100644 app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml delete mode 100644 app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml diff --git a/app/src/main/res/drawable/background_maxheight_sign_us.xml b/app/src/main/res/drawable/background_max_height_sign_us.xml similarity index 100% rename from app/src/main/res/drawable/background_maxheight_sign_us.xml rename to app/src/main/res/drawable/background_max_height_sign_us.xml diff --git a/app/src/main/res/drawable/background_maxheight_sign.xml b/app/src/main/res/drawable/background_maxheight_sign.xml deleted file mode 100644 index d97570fd66..0000000000 --- a/app/src/main/res/drawable/background_maxheight_sign.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml deleted file mode 100644 index 62b27ef0b9..0000000000 --- a/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml deleted file mode 100644 index b1442ce159..0000000000 --- a/app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/layout/quest_max_height_us.xml b/app/src/main/res/layout/quest_max_height_us.xml index 7bfca9eeb9..c0d161e06d 100644 --- a/app/src/main/res/layout/quest_max_height_us.xml +++ b/app/src/main/res/layout/quest_max_height_us.xml @@ -11,7 +11,7 @@ android:gravity="center" android:orientation="horizontal" android:layout_centerHorizontal="true" - android:background="@drawable/background_maxheight_sign_us" + android:background="@drawable/background_max_height_sign_us" android:padding="16dp" android:id="@+id/maxHeightInputSign" > From 6f177501c7c3a7f5730ad31e22cd383dd26b46ab Mon Sep 17 00:00:00 2001 From: ENT8R Date: Sat, 10 Mar 2018 18:44:50 +0100 Subject: [PATCH 04/35] Fix some issues with e.g. the query, the wording and other answers --- .../data/osm/SimpleOverpassQuestType.java | 2 +- .../data/osm/tql/TagFilterExpression.java | 11 ++- .../quests/max_height/AddMaxHeight.java | 60 +++++++------ .../quests/max_height/AddMaxHeightForm.java | 85 +++++++++++++------ app/src/main/res/layout/quest_max_height.xml | 5 +- app/src/main/res/values/strings.xml | 9 +- .../data/osm/tql/FiltersParserTest.java | 2 +- 7 files changed, 112 insertions(+), 62 deletions(-) diff --git a/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java b/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java index cbdd615ad0..093fb02078 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java +++ b/app/src/main/java/de/westnordost/streetcomplete/data/osm/SimpleOverpassQuestType.java @@ -29,7 +29,7 @@ public SimpleOverpassQuestType(OverpassMapDataDao overpassServer) /** @return a query string that is accepted by Overpass and does not exceed the given bbox */ String getOverpassQuery(BoundingBox bbox) { - return filter.toOverpassQLString(bbox); + return filter.toOverpassQLString(bbox, true); } protected abstract String getTagFilters(); diff --git a/app/src/main/java/de/westnordost/streetcomplete/data/osm/tql/TagFilterExpression.java b/app/src/main/java/de/westnordost/streetcomplete/data/osm/tql/TagFilterExpression.java index 94e3ed3d16..867f98da26 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/data/osm/tql/TagFilterExpression.java +++ b/app/src/main/java/de/westnordost/streetcomplete/data/osm/tql/TagFilterExpression.java @@ -45,7 +45,7 @@ public boolean matches(Element element) } /** @return this expression as a Overpass query string (in a short one-liner form) */ - public String toOverpassQLString(BoundingBox bbox) + public String toOverpassQLString(BoundingBox bbox, boolean print) { StringBuilder oql = new StringBuilder(); if(bbox != null) @@ -66,9 +66,12 @@ public String toOverpassQLString(BoundingBox bbox) } if(useUnion) oql.append(");"); - /* "body" print mode (default) does not include version, but "meta" does. "geom" prints out - * geometry for every way and relation */ - oql.append("out meta geom;"); + if (print) + { + /* "body" print mode (default) does not include version, but "meta" does. "geom" prints out + * geometry for every way and relation */ + oql.append("out meta geom;"); + } return oql.toString(); } diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java index 34788b945b..7130ecf3a9 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java @@ -3,6 +3,7 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.util.Log; import java.util.Map; @@ -16,7 +17,9 @@ 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.FiltersParser; import de.westnordost.streetcomplete.data.osm.tql.OverpassQLUtil; +import de.westnordost.streetcomplete.data.osm.tql.TagFilterExpression; import de.westnordost.streetcomplete.quests.AbstractQuestAnswerFragment; public class AddMaxHeight implements OsmElementQuestType @@ -29,26 +32,29 @@ public class AddMaxHeight implements OsmElementQuestType this.overpassServer = overpassServer; } - /*the query does not exclude elements which are not accessible by the public, - because a maxheight sign will very probably be visible at the entrance or beginning*/ - private static final String QUERY_RESTRICTIONS = "['maxheight'!~'.']['maxheight:physical'!~'.']"; + private static final String QUERY_RESTRICTIONS = "!maxheight and !maxheight:physical"; - private static final String ROADS = "(primary|secondary|tertiary|trunk)(_link)?|motorway|service|residential|unclassified|living_street"; + private static final String ROADS = "primary|secondary|tertiary|trunk|motorway|service|residential|unclassified|living_street|" + + "primary_link|secondary_link|tertiary_link|trunk_link"; + + private static final TagFilterExpression nodeFilter = new FiltersParser().parse("nodes with (barrier=height_restrictor" + + " or amenity=parking_entrance and parking ~ underground|multi-storey)" + + " and " + QUERY_RESTRICTIONS); + private static final TagFilterExpression wayFilter = new FiltersParser().parse("ways with highway ~ " + ROADS + + " and (covered=yes or tunnel~yes|building_passage|avalanche_protector)" + + " and " + QUERY_RESTRICTIONS); @Override public boolean download(BoundingBox bbox, MapDataWithGeometryHandler handler) { + Log.d("Query", getOverpassQuery(bbox)); return overpassServer.getAndHandleQuota(getOverpassQuery(bbox), handler); } private static String getOverpassQuery(BoundingBox bbox) { return OverpassQLUtil.getGlobalOverpassBBox(bbox) + - "(" + - " node['barrier'='height_restrictor']" + QUERY_RESTRICTIONS + ";" + - " node['amenity'='parking_entrance']['parking'~'^(underground|multi-storey)$']" + QUERY_RESTRICTIONS + ";" + - " way['highway'~'^(" + ROADS + ")$']['tunnel'~'^(yes|building_passage)$']" + QUERY_RESTRICTIONS + ";" + - " way['highway'~'^(" + ROADS + ")$']['covered'='yes']" + QUERY_RESTRICTIONS + ";" + - ");" + + nodeFilter.toOverpassQLString(null, false) + + wayFilter.toOverpassQLString(null, false) + "out meta geom;"; } @@ -59,25 +65,32 @@ private static String getOverpassQuery(BoundingBox bbox) @Override public void applyAnswerTo(Bundle answer, StringMapChangesBuilder changes) { - boolean hasNoSign = answer.getBoolean(AddMaxHeightForm.NO_SIGN); - String maxheight = answer.getString(AddMaxHeightForm.MAX_HEIGHT); - if(hasNoSign) + String maxHeight = answer.getString(AddMaxHeightForm.MAX_HEIGHT); + int noSign = answer.getInt(AddMaxHeightForm.NO_SIGN); + + if(noSign != 0) { - /*TODO: maxheight=default or maxheight=no_sign? - according to https://taginfo.openstreetmap.org/keys/maxheight#values maxheight=no_sign is only used 14 times, - while maxheight=default is used about 10K times*/ - changes.add("maxheight", "default"); + if(noSign == AddMaxHeightForm.IS_BELOW_DEFAULT) + changes.add("maxheight", "below_default"); + else if(noSign == AddMaxHeightForm.IS_DEFAULT) + changes.add("maxheight", "default"); + else if(noSign == AddMaxHeightForm.IS_NOT_INDICATED) + changes.add("maxheight", "no_indications"); + return; } - else + + if (maxHeight != null) { - if (maxheight != null) - { - changes.add("maxheight", maxheight); - } + changes.add("maxheight", maxHeight); } } - @Override public String getCommitMessage() { return "Add maximum height"; } + @Nullable @Override public Boolean isApplicableTo(Element element) + { + return nodeFilter.matches(element) || wayFilter.matches(element); + } + + @Override public String getCommitMessage() { return "Add maximum heights"; } @Override public int getIcon() { return R.drawable.ic_quest_max_height; } @Override public int getTitle(@NonNull Map tags) { @@ -94,6 +107,5 @@ private static String getOverpassQuery(BoundingBox bbox) @Override public int getTitle() { return R.string.quest_maxheight_title; } @Override public int getDefaultDisabledMessage() { return 0; } - @Nullable @Override public Boolean isApplicableTo(Element element) { return null; } @NonNull @Override public Countries getEnabledForCountries() { return Countries.ALL; } } diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java index 0071199313..e09e66ba8b 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java @@ -1,12 +1,18 @@ package de.westnordost.streetcomplete.quests.max_height; +import android.content.DialogInterface; import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.Toast; +import java.util.ArrayList; +import java.util.List; + import de.westnordost.streetcomplete.R; import de.westnordost.streetcomplete.quests.AbstractQuestFormAnswerFragment; import de.westnordost.streetcomplete.view.dialogs.AlertDialogBuilder; @@ -16,6 +22,7 @@ public class AddMaxHeightForm extends AbstractQuestFormAnswerFragment public static final String MAX_HEIGHT = "max_height", NO_SIGN = "no_sign"; + public static final int IS_BELOW_DEFAULT = 1, IS_DEFAULT = 2, IS_NOT_INDICATED = 3; private EditText heightInput, feetInput, inchInput; @@ -73,16 +80,55 @@ private void addOtherAnswers() addOtherAnswer(R.string.quest_maxheight_answer_noSign, () -> { - new AlertDialogBuilder(getActivity()) - .setTitle(R.string.quest_maxheight_answer_noSign_confirmation_title) - .setMessage(R.string.quest_maxheight_answer_noSign_confirmation) - .setPositiveButton(R.string.quest_maxheight_answer_noSign_confirmation_positive, (dialog, which) -> { - Bundle answer = new Bundle(); - answer.putBoolean(NO_SIGN, true); - applyImmediateAnswer(answer); - }) - .setNegativeButton(R.string.quest_generic_confirmation_no, null) + final String + restrictsTraffic = getResources().getString(R.string.quest_maxheight_answer_restrictsTraffic), + noTrafficRestriction = getResources().getString(R.string.quest_maxheight_answer_noTrafficRestriction), + cantEstimate = getResources().getString(R.string.quest_maxheight_answer_cantEstimate); + + final List answers = new ArrayList<>(3); + answers.add(restrictsTraffic); + answers.add(noTrafficRestriction); + answers.add(cantEstimate); + + DialogInterface.OnClickListener onSelect = new DialogInterface.OnClickListener() + { + Integer selection = null; + + @Override public void onClick(DialogInterface dialog, int which) + { + if (which >= 0) + { + selection = which; + ((AlertDialog)dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true); + } + else if (which == DialogInterface.BUTTON_POSITIVE) + { + if(selection == null || selection < 0 || selection >= answers.size()) return; + onAnswer(); + } + } + + private void onAnswer() + { + String answer = answers.get(selection); + Bundle data = new Bundle(); + int type = 0; + if(answer.equals(restrictsTraffic)) type = IS_BELOW_DEFAULT; + if(answer.equals(noTrafficRestriction)) type = IS_DEFAULT; + if(answer.equals(cantEstimate)) type = IS_NOT_INDICATED; + data.putInt(NO_SIGN, type); + applyImmediateAnswer(data); + } + }; + + AlertDialog dlg = new AlertDialogBuilder(getActivity()) + .setSingleChoiceItems(answers.toArray(new String[0]), -1, onSelect) + .setTitle(R.string.quest_maxheight_answer_noSign_question) + .setPositiveButton(android.R.string.ok, onSelect) + .setNegativeButton(android.R.string.cancel, null) .show(); + + dlg.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false); }); } @@ -108,7 +154,7 @@ private boolean userSelectedUnrealisticHeight() { double height = Double.parseDouble(getHeightFromInput()); double heightInMeter = isMetric ? height : feetToMeter(height); - return heightInMeter > 6; + return heightInMeter > 6 || heightInMeter < 2; } private static double feetToMeter(double feet) @@ -138,12 +184,6 @@ private String getFinalMaxHeight(String value) { if (isMetric) { - /*TODO: should a trailing zero be added or does it even work without? - https://taginfo.openstreetmap.org/keys/maxheight#values contains both...*/ - if (!value.contains(".")) - { - value += ".0"; - } return value; } else @@ -161,10 +201,7 @@ private String getHeightFromInput() return heightInput.getText().toString().replace(",", "."); } - else - { - return null; - } + return ""; } else { @@ -172,10 +209,7 @@ private String getHeightFromInput() { return feetInput.getText().toString() + "." + inchInput.getText().toString(); } - else - { - return null; - } + return ""; } } @@ -191,6 +225,7 @@ private void confirmUnusualInput(final Runnable callback) @Override public boolean hasChanges() { - return getHeightFromInput() != null; + Log.d("hasChanges", String.valueOf(getHeightFromInput().isEmpty())); + return !getHeightFromInput().isEmpty(); } } diff --git a/app/src/main/res/layout/quest_max_height.xml b/app/src/main/res/layout/quest_max_height.xml index 1236faf8fa..411dca471f 100644 --- a/app/src/main/res/layout/quest_max_height.xml +++ b/app/src/main/res/layout/quest_max_height.xml @@ -19,11 +19,10 @@ android:layout_height="48dp" android:layout_centerInParent="true" android:background="#0fff" - android:digits="0123456789.," android:gravity="center" - android:inputType="number" + android:inputType="numberDecimal" android:maxLength="4" - android:textSize="30dp" + android:textSize="30sp" android:textStyle="bold" tools:text="50" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 367cde8a00..2fb27ebaab 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -500,10 +500,11 @@ Otherwise, you can download another keyboard in the app store. Popular keyboards What is the height limit of this height restrictor? What is the height limit of this tunnel? There is no sign - Are you sure there is no sign? - Did you check at both ends? If there is no sign, default limits apply. - Yes, no sign - This height looks implausible + Can you give some more information? + The physical height restricts the general traffic + The physical height does not restrict the general traffic + I can not estimate the height + This height looks implausible. Are you sure that it is correct? The unit is imperial The unit is metric diff --git a/app/src/test/java/de/westnordost/streetcomplete/data/osm/tql/FiltersParserTest.java b/app/src/test/java/de/westnordost/streetcomplete/data/osm/tql/FiltersParserTest.java index cd775e7583..7320a7292b 100644 --- a/app/src/test/java/de/westnordost/streetcomplete/data/osm/tql/FiltersParserTest.java +++ b/app/src/test/java/de/westnordost/streetcomplete/data/osm/tql/FiltersParserTest.java @@ -251,6 +251,6 @@ private void check(String input, String output) private void check(String input, String output, BoundingBox bbox) { TagFilterExpression expr = new FiltersParser().parse(input); - assertEquals(output, expr.toOverpassQLString(bbox)); + assertEquals(output, expr.toOverpassQLString(bbox, true)); } } From 54abb775a033400a3c88a54821e6c086b09834d5 Mon Sep 17 00:00:00 2001 From: ENT8R Date: Sun, 11 Mar 2018 16:13:10 +0100 Subject: [PATCH 05/35] Some minor changes --- .../streetcomplete/quests/max_height/AddMaxHeight.java | 2 -- .../streetcomplete/quests/max_height/AddMaxHeightForm.java | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java index 7130ecf3a9..884b869df4 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java @@ -3,7 +3,6 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.util.Log; import java.util.Map; @@ -46,7 +45,6 @@ public class AddMaxHeight implements OsmElementQuestType @Override public boolean download(BoundingBox bbox, MapDataWithGeometryHandler handler) { - Log.d("Query", getOverpassQuery(bbox)); return overpassServer.getAndHandleQuota(getOverpassQuery(bbox), handler); } diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java index e09e66ba8b..b9d13b05ff 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java @@ -225,6 +225,7 @@ private void confirmUnusualInput(final Runnable callback) @Override public boolean hasChanges() { + //TODO: look at the output of this log Log.d("hasChanges", String.valueOf(getHeightFromInput().isEmpty())); return !getHeightFromInput().isEmpty(); } From 967d8736708f9b89416ea5c4ba5b833dde649735 Mon Sep 17 00:00:00 2001 From: ENT8R Date: Sun, 3 Jun 2018 16:09:11 +0200 Subject: [PATCH 06/35] Exclude private service ways, update country metadata and fix some other problems --- app/src/main/assets/country_metadata/CA.yml | 2 +- .../quests/max_height/AddMaxHeight.java | 10 ++- .../quests/max_height/AddMaxHeightForm.java | 63 ++++++------------- .../quests/max_height/Height.java | 56 +++++++++++++++++ .../quest_max_height.xml} | 0 res/country_metadata/heightUnit.yml | 3 +- 6 files changed, 85 insertions(+), 49 deletions(-) create mode 100644 app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java rename app/src/main/res/{layout/quest_max_height_us.xml => layout-mcc310/quest_max_height.xml} (100%) diff --git a/app/src/main/assets/country_metadata/CA.yml b/app/src/main/assets/country_metadata/CA.yml index e941f02fd8..ea23e6e641 100644 --- a/app/src/main/assets/country_metadata/CA.yml +++ b/app/src/main/assets/country_metadata/CA.yml @@ -1,5 +1,5 @@ # Do not edit. Source files are in /res/country_metadata -heightUnit: [ft, m] +heightUnit: [m, ft] isAdvisorySpeedLimitKnown: true isSlowZoneKnown: false mobileCountryCode: 302 diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java index 884b869df4..8c884ab286 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java @@ -31,16 +31,20 @@ public class AddMaxHeight implements OsmElementQuestType this.overpassServer = overpassServer; } + private static final String TUNNEL_TYPES = "yes|building_passage|avalanche_protector"; + private static final String QUERY_RESTRICTIONS = "!maxheight and !maxheight:physical"; - private static final String ROADS = "primary|secondary|tertiary|trunk|motorway|service|residential|unclassified|living_street|" + + private static final String ROADS = "primary|secondary|tertiary|trunk|motorway|residential|unclassified|living_street|" + "primary_link|secondary_link|tertiary_link|trunk_link"; private static final TagFilterExpression nodeFilter = new FiltersParser().parse("nodes with (barrier=height_restrictor" + " or amenity=parking_entrance and parking ~ underground|multi-storey)" + " and " + QUERY_RESTRICTIONS); - private static final TagFilterExpression wayFilter = new FiltersParser().parse("ways with highway ~ " + ROADS + - " and (covered=yes or tunnel~yes|building_passage|avalanche_protector)" + + private static final TagFilterExpression wayFilter = new FiltersParser().parse("ways with" + + " (highway ~ " + ROADS + " or" + + " (highway=service and access!=private))" + + " and (covered=yes or tunnel~" + TUNNEL_TYPES + ")" + " and " + QUERY_RESTRICTIONS); @Override public boolean download(BoundingBox bbox, MapDataWithGeometryHandler handler) diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java index b9d13b05ff..06224d9b47 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java @@ -3,7 +3,6 @@ import android.content.DialogInterface; import android.os.Bundle; import android.support.v7.app.AlertDialog; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -22,7 +21,11 @@ public class AddMaxHeightForm extends AbstractQuestFormAnswerFragment public static final String MAX_HEIGHT = "max_height", NO_SIGN = "no_sign"; - public static final int IS_BELOW_DEFAULT = 1, IS_DEFAULT = 2, IS_NOT_INDICATED = 3; + + public static final int + IS_BELOW_DEFAULT = 1, + IS_DEFAULT = 2, + IS_NOT_INDICATED = 3; private EditText heightInput, feetInput, inchInput; @@ -35,7 +38,7 @@ public class AddMaxHeightForm extends AbstractQuestFormAnswerFragment isMetric = getCountryInfo().getHeightUnits().get(0).equals("m"); - setMaxHeightSignLayout(getMaxHeightLayoutResourceId()); + setMaxHeightSignLayout(R.layout.quest_max_height); addOtherAnswers(); return view; @@ -43,22 +46,17 @@ public class AddMaxHeightForm extends AbstractQuestFormAnswerFragment private void setMaxHeightSignLayout(int resourceId) { - View contentView = setContentView(resourceId); + View contentView = setContentView(getCurrentCountryResources().getLayout(resourceId)); heightInput = contentView.findViewById(R.id.maxHeightInput); feetInput = contentView.findViewById(R.id.maxHeightFeetInput); inchInput = contentView.findViewById(R.id.maxHeightInchInput); } - private int getMaxHeightLayoutResourceId() - { - return isMetric ? R.layout.quest_max_height : R.layout.quest_max_height_us; - } - private void addOtherAnswers() { - - if (getCountryInfo().getHeightUnits().size() == 2) + //TODO: use a spinner for this + /*if (getCountryInfo().getHeightUnits().size() == 2) { if (isMetric) { @@ -76,7 +74,7 @@ private void addOtherAnswers() setMaxHeightSignLayout(getMaxHeightLayoutResourceId()); }); } - } + }*/ addOtherAnswer(R.string.quest_maxheight_answer_noSign, () -> { @@ -152,7 +150,7 @@ private void onAnswer() private boolean userSelectedUnrealisticHeight() { - double height = Double.parseDouble(getHeightFromInput()); + int height = getHeightFromInput().getIntegerPart(); double heightInMeter = isMetric ? height : feetToMeter(height); return heightInMeter > 6 || heightInMeter < 2; } @@ -164,52 +162,31 @@ private static double feetToMeter(double feet) private void applyMaxHeightFormAnswer() { - Bundle answer = new Bundle(); - - String height = getFinalMaxHeight(getHeightFromInput()); + String height = getHeightFromInput().toString(); - // metric is the OSM default, does not need to be mentioned - if(!isMetric) - { - //this adds an apostrophe and a double-quote to be in a format like e.g. 6'7" - height = height.replace(".", "'"); - height += "\""; - } + Bundle answer = new Bundle(); answer.putString(MAX_HEIGHT, height); - applyFormAnswer(answer); } - private String getFinalMaxHeight(String value) - { - if (isMetric) - { - return value; - } - else - { - return value.replace(".", "'") + "\""; - } - } - - private String getHeightFromInput() + private Height getHeightFromInput() { if (isMetric) { if (!heightInput.getText().toString().isEmpty()) { - - return heightInput.getText().toString().replace(",", "."); + String[] parts = heightInput.getText().toString().split("."); + return new Height(parts[0], parts[1], Height.METRIC); } - return ""; + return new Height(); } else { if (!feetInput.getText().toString().isEmpty() && !inchInput.getText().toString().isEmpty()) { - return feetInput.getText().toString() + "." + inchInput.getText().toString(); + return new Height(feetInput.getText().toString(), inchInput.getText().toString(), Height.IMPERIAL); } - return ""; + return new Height(); } } @@ -225,8 +202,6 @@ private void confirmUnusualInput(final Runnable callback) @Override public boolean hasChanges() { - //TODO: look at the output of this log - Log.d("hasChanges", String.valueOf(getHeightFromInput().isEmpty())); return !getHeightFromInput().isEmpty(); } } diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java new file mode 100644 index 0000000000..e8d5ac6de3 --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java @@ -0,0 +1,56 @@ +package de.westnordost.streetcomplete.quests.max_height; + +//if the minimum required API would be 24, we could maybe use https://developer.android.com/reference/android/icu/util/Measure +public class Height +{ + private int integerPart; + private int fractionalPart; + + private String unit; + + public static String + METRIC = "metric", + IMPERIAL = "imperial"; + + Height() + { + this.integerPart = -1; + this.fractionalPart = -1; + this.unit = METRIC; + } + + Height(String integerPart, String fractionalPart, String unit) + { + this.integerPart = Integer.parseInt(integerPart); + this.fractionalPart = Integer.parseInt(fractionalPart); + this.unit = unit; + } + + public int getIntegerPart() + { + return integerPart; + } + + public int getFractionalPart() + { + return fractionalPart; + } + + public boolean isEmpty() + { + return integerPart == -1 && fractionalPart == -1; + } + + public String toString() + { + if (unit.equals(METRIC)) + { + return String.valueOf(integerPart) + "." + String.valueOf(fractionalPart); + } + else + { + //this adds an apostrophe and a double-quote to be in a format like e.g. 6'7" + return String.valueOf(integerPart) + "'" + String.valueOf(fractionalPart) + "\""; + } + } +} diff --git a/app/src/main/res/layout/quest_max_height_us.xml b/app/src/main/res/layout-mcc310/quest_max_height.xml similarity index 100% rename from app/src/main/res/layout/quest_max_height_us.xml rename to app/src/main/res/layout-mcc310/quest_max_height.xml diff --git a/res/country_metadata/heightUnit.yml b/res/country_metadata/heightUnit.yml index 6ad4ea1e5c..96c9843dd2 100644 --- a/res/country_metadata/heightUnit.yml +++ b/res/country_metadata/heightUnit.yml @@ -1,8 +1,9 @@ # Sources: # https://en.wikipedia.org/wiki/Metrication#Overview # https://en.wikipedia.org/wiki/Imperial_units#Current_use +# https://en.wikipedia.org/wiki/Comparison_of_MUTCD-influenced_traffic_signs default: [m] -CA: [ft, m] +CA: [m, ft] FM: [ft, m] GB: [ft, m] LR: [ft, m] From 3ec283d4fac86b792e3c381131d66551b5443498 Mon Sep 17 00:00:00 2001 From: ENT8R Date: Sun, 10 Jun 2018 13:47:03 +0200 Subject: [PATCH 07/35] Add layouts for some more countries like Australia, Canada, Great Britain --- app/src/main/assets/country_metadata/CA.yml | 1 - .../quests/max_height/AddMaxHeightForm.java | 94 +++++++++++++------ .../quests/max_height/Height.java | 16 ++-- .../background_maxheight_sign.xml | 6 ++ .../background_maxheight_sign.xml | 5 + .../background_maxheight_sign.xml | 5 + .../drawable/background_max_height_sign.xml | 17 ---- .../background_max_height_sign_us.xml | 19 ---- .../drawable/background_maxheight_sign.xml | 17 ++++ .../drawable/background_maxheight_sign_gb.xml | 20 ++++ .../background_maxheight_sign_yellow.xml | 17 ++++ .../res/drawable/maxheight_canada_arrow.xml | 11 +++ .../res/layout-mcc302/quest_maxheight.xml | 2 + .../res/layout-mcc310/quest_maxheight.xml | 2 + .../res/layout-mcc505/quest_maxheight.xml | 2 + app/src/main/res/layout/quest_max_height.xml | 31 ------ app/src/main/res/layout/quest_maxheight.xml | 32 +++++++ .../res/layout/quest_maxheight_australia.xml | 70 ++++++++++++++ .../res/layout/quest_maxheight_canada.xml | 71 ++++++++++++++ .../main/res/layout/quest_maxheight_feet.xml | 58 ++++++++++++ .../main/res/layout/quest_maxheight_meter.xml | 33 +++++++ .../quest_maxheight_us.xml} | 25 +++-- app/src/main/res/values/strings.xml | 2 - res/country_metadata/heightUnit.yml | 1 - 24 files changed, 440 insertions(+), 117 deletions(-) create mode 100644 app/src/main/res/drawable-mcc240/background_maxheight_sign.xml create mode 100644 app/src/main/res/drawable-mcc244/background_maxheight_sign.xml create mode 100644 app/src/main/res/drawable-mcc274/background_maxheight_sign.xml delete mode 100644 app/src/main/res/drawable/background_max_height_sign.xml delete mode 100644 app/src/main/res/drawable/background_max_height_sign_us.xml create mode 100644 app/src/main/res/drawable/background_maxheight_sign.xml create mode 100644 app/src/main/res/drawable/background_maxheight_sign_gb.xml create mode 100644 app/src/main/res/drawable/background_maxheight_sign_yellow.xml create mode 100644 app/src/main/res/drawable/maxheight_canada_arrow.xml create mode 100644 app/src/main/res/layout-mcc302/quest_maxheight.xml create mode 100644 app/src/main/res/layout-mcc310/quest_maxheight.xml create mode 100644 app/src/main/res/layout-mcc505/quest_maxheight.xml delete mode 100644 app/src/main/res/layout/quest_max_height.xml create mode 100644 app/src/main/res/layout/quest_maxheight.xml create mode 100644 app/src/main/res/layout/quest_maxheight_australia.xml create mode 100644 app/src/main/res/layout/quest_maxheight_canada.xml create mode 100644 app/src/main/res/layout/quest_maxheight_feet.xml create mode 100644 app/src/main/res/layout/quest_maxheight_meter.xml rename app/src/main/res/{layout-mcc310/quest_max_height.xml => layout/quest_maxheight_us.xml} (73%) diff --git a/app/src/main/assets/country_metadata/CA.yml b/app/src/main/assets/country_metadata/CA.yml index ea23e6e641..e0f0bee56c 100644 --- a/app/src/main/assets/country_metadata/CA.yml +++ b/app/src/main/assets/country_metadata/CA.yml @@ -1,5 +1,4 @@ # Do not edit. Source files are in /res/country_metadata -heightUnit: [m, ft] isAdvisorySpeedLimitKnown: true isSlowZoneKnown: false mobileCountryCode: 302 diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java index 06224d9b47..29cb25fdb8 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java @@ -6,7 +6,10 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; import android.widget.EditText; +import android.widget.Spinner; import android.widget.Toast; import java.util.ArrayList; @@ -28,54 +31,73 @@ public class AddMaxHeightForm extends AbstractQuestFormAnswerFragment IS_NOT_INDICATED = 3; private EditText heightInput, feetInput, inchInput; + private Spinner heightUnitSelect; - private boolean isMetric; + View meterInputSign, feetInputSign; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); - isMetric = getCountryInfo().getHeightUnits().get(0).equals("m"); - - setMaxHeightSignLayout(R.layout.quest_max_height); + String unit = getCountryInfo().getHeightUnits().get(0).equals("m") ? Height.METRIC : Height.IMPERIAL; + setMaxHeightSignLayout(R.layout.quest_maxheight, unit); addOtherAnswers(); return view; } - private void setMaxHeightSignLayout(int resourceId) + private void setMaxHeightSignLayout(int resourceId, String unit) { View contentView = setContentView(getCurrentCountryResources().getLayout(resourceId)); - heightInput = contentView.findViewById(R.id.maxHeightInput); - feetInput = contentView.findViewById(R.id.maxHeightFeetInput); - inchInput = contentView.findViewById(R.id.maxHeightInchInput); + heightInput = contentView.findViewById(R.id.meterInput); + feetInput = contentView.findViewById(R.id.feetInput); + inchInput = contentView.findViewById(R.id.inchInput); + + meterInputSign = contentView.findViewById(R.id.meterInputSign); + feetInputSign = contentView.findViewById(R.id.feetInputSign); + + heightUnitSelect = contentView.findViewById(R.id.heightUnitSelect); + initHeightUnitSelect(); + + switchLayout(unit); } - private void addOtherAnswers() + private void switchLayout(String unit) { - //TODO: use a spinner for this - /*if (getCountryInfo().getHeightUnits().size() == 2) + if (unit.equals(Height.METRIC)) { - if (isMetric) - { - addOtherAnswer(R.string.quest_maxheight_answer_imperial_unit, () -> - { - isMetric = false; - setMaxHeightSignLayout(getMaxHeightLayoutResourceId()); - }); - } - else + meterInputSign.setVisibility(View.VISIBLE); + feetInputSign.setVisibility(View.GONE); + } else { + feetInputSign.setVisibility(View.VISIBLE); + meterInputSign.setVisibility(View.GONE); + } + } + + private void initHeightUnitSelect() + { + List heightUnits = getCountryInfo().getHeightUnits(); + heightUnitSelect.setVisibility(heightUnits.size() == 1 ? View.GONE : View.VISIBLE); + heightUnitSelect.setAdapter(new ArrayAdapter<>(getContext(), R.layout.spinner_item_centered, heightUnits)); + heightUnitSelect.setSelection(0); + + heightUnitSelect.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parentView, View selectedItemView, int position, long id) { - addOtherAnswer(R.string.quest_maxheight_answer_metric_unit, () -> - { - isMetric = true; - setMaxHeightSignLayout(getMaxHeightLayoutResourceId()); - }); + String heightUnit = heightUnitSelect.getSelectedItem().equals("m") ? Height.METRIC : Height.IMPERIAL; + switchLayout(heightUnit); } - }*/ + @Override + public void onNothingSelected(AdapterView parentView) {} + }); + } + + private void addOtherAnswers() + { addOtherAnswer(R.string.quest_maxheight_answer_noSign, () -> { final String @@ -150,8 +172,10 @@ private void onAnswer() private boolean userSelectedUnrealisticHeight() { - int height = getHeightFromInput().getIntegerPart(); - double heightInMeter = isMetric ? height : feetToMeter(height); + double height = getHeightFromInput().toDouble(); + String heightUnit = getHeightFromInput().getUnit(); + + double heightInMeter = heightUnit.equals(Height.METRIC) ? height : feetToMeter(height); return heightInMeter > 6 || heightInMeter < 2; } @@ -171,12 +195,20 @@ private void applyMaxHeightFormAnswer() private Height getHeightFromInput() { + boolean isMetric = heightUnitSelect.getSelectedItem().equals("m"); + if (isMetric) { - if (!heightInput.getText().toString().isEmpty()) + String input = heightInput.getText().toString(); + if (!input.isEmpty()) { - String[] parts = heightInput.getText().toString().split("."); - return new Height(parts[0], parts[1], Height.METRIC); + if (input.contains(".")) + { + String[] parts = input.split("\\."); + return new Height(parts[0], parts[1], Height.METRIC); + } else { + return new Height(input, "0", Height.METRIC); + } } return new Height(); } diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java index e8d5ac6de3..1692530305 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java @@ -8,7 +8,7 @@ public class Height private String unit; - public static String + public final static String METRIC = "metric", IMPERIAL = "imperial"; @@ -26,14 +26,9 @@ public class Height this.unit = unit; } - public int getIntegerPart() + public String getUnit() { - return integerPart; - } - - public int getFractionalPart() - { - return fractionalPart; + return unit; } public boolean isEmpty() @@ -53,4 +48,9 @@ public String toString() return String.valueOf(integerPart) + "'" + String.valueOf(fractionalPart) + "\""; } } + + public double toDouble() + { + return Double.parseDouble(integerPart + "." + fractionalPart); + } } diff --git a/app/src/main/res/drawable-mcc240/background_maxheight_sign.xml b/app/src/main/res/drawable-mcc240/background_maxheight_sign.xml new file mode 100644 index 0000000000..9f61fd5f71 --- /dev/null +++ b/app/src/main/res/drawable-mcc240/background_maxheight_sign.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/drawable-mcc244/background_maxheight_sign.xml b/app/src/main/res/drawable-mcc244/background_maxheight_sign.xml new file mode 100644 index 0000000000..d4e3e46331 --- /dev/null +++ b/app/src/main/res/drawable-mcc244/background_maxheight_sign.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable-mcc274/background_maxheight_sign.xml b/app/src/main/res/drawable-mcc274/background_maxheight_sign.xml new file mode 100644 index 0000000000..17f1715d83 --- /dev/null +++ b/app/src/main/res/drawable-mcc274/background_maxheight_sign.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/background_max_height_sign.xml b/app/src/main/res/drawable/background_max_height_sign.xml deleted file mode 100644 index b05b022a7c..0000000000 --- a/app/src/main/res/drawable/background_max_height_sign.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/background_max_height_sign_us.xml b/app/src/main/res/drawable/background_max_height_sign_us.xml deleted file mode 100644 index 1f2612f231..0000000000 --- a/app/src/main/res/drawable/background_max_height_sign_us.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/background_maxheight_sign.xml b/app/src/main/res/drawable/background_maxheight_sign.xml new file mode 100644 index 0000000000..640bac9a12 --- /dev/null +++ b/app/src/main/res/drawable/background_maxheight_sign.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/app/src/main/res/drawable/background_maxheight_sign_gb.xml b/app/src/main/res/drawable/background_maxheight_sign_gb.xml new file mode 100644 index 0000000000..fccda35f36 --- /dev/null +++ b/app/src/main/res/drawable/background_maxheight_sign_gb.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/app/src/main/res/drawable/background_maxheight_sign_yellow.xml b/app/src/main/res/drawable/background_maxheight_sign_yellow.xml new file mode 100644 index 0000000000..99134cc69a --- /dev/null +++ b/app/src/main/res/drawable/background_maxheight_sign_yellow.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/app/src/main/res/drawable/maxheight_canada_arrow.xml b/app/src/main/res/drawable/maxheight_canada_arrow.xml new file mode 100644 index 0000000000..fd6bdf5cb7 --- /dev/null +++ b/app/src/main/res/drawable/maxheight_canada_arrow.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/layout-mcc302/quest_maxheight.xml b/app/src/main/res/layout-mcc302/quest_maxheight.xml new file mode 100644 index 0000000000..5ea0a7014a --- /dev/null +++ b/app/src/main/res/layout-mcc302/quest_maxheight.xml @@ -0,0 +1,2 @@ + + diff --git a/app/src/main/res/layout-mcc310/quest_maxheight.xml b/app/src/main/res/layout-mcc310/quest_maxheight.xml new file mode 100644 index 0000000000..30f262a3c3 --- /dev/null +++ b/app/src/main/res/layout-mcc310/quest_maxheight.xml @@ -0,0 +1,2 @@ + + diff --git a/app/src/main/res/layout-mcc505/quest_maxheight.xml b/app/src/main/res/layout-mcc505/quest_maxheight.xml new file mode 100644 index 0000000000..2439a4a2d7 --- /dev/null +++ b/app/src/main/res/layout-mcc505/quest_maxheight.xml @@ -0,0 +1,2 @@ + + diff --git a/app/src/main/res/layout/quest_max_height.xml b/app/src/main/res/layout/quest_max_height.xml deleted file mode 100644 index 411dca471f..0000000000 --- a/app/src/main/res/layout/quest_max_height.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - diff --git a/app/src/main/res/layout/quest_maxheight.xml b/app/src/main/res/layout/quest_maxheight.xml new file mode 100644 index 0000000000..a7b80ed10f --- /dev/null +++ b/app/src/main/res/layout/quest_maxheight.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/quest_maxheight_australia.xml b/app/src/main/res/layout/quest_maxheight_australia.xml new file mode 100644 index 0000000000..05a3408ef9 --- /dev/null +++ b/app/src/main/res/layout/quest_maxheight_australia.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/quest_maxheight_canada.xml b/app/src/main/res/layout/quest_maxheight_canada.xml new file mode 100644 index 0000000000..0f635d248d --- /dev/null +++ b/app/src/main/res/layout/quest_maxheight_canada.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/quest_maxheight_feet.xml b/app/src/main/res/layout/quest_maxheight_feet.xml new file mode 100644 index 0000000000..7fa1a5ab14 --- /dev/null +++ b/app/src/main/res/layout/quest_maxheight_feet.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/quest_maxheight_meter.xml b/app/src/main/res/layout/quest_maxheight_meter.xml new file mode 100644 index 0000000000..88a677a4a1 --- /dev/null +++ b/app/src/main/res/layout/quest_maxheight_meter.xml @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/app/src/main/res/layout-mcc310/quest_max_height.xml b/app/src/main/res/layout/quest_maxheight_us.xml similarity index 73% rename from app/src/main/res/layout-mcc310/quest_max_height.xml rename to app/src/main/res/layout/quest_maxheight_us.xml index c0d161e06d..c6edce665c 100644 --- a/app/src/main/res/layout-mcc310/quest_max_height.xml +++ b/app/src/main/res/layout/quest_maxheight_us.xml @@ -11,20 +11,21 @@ android:gravity="center" android:orientation="horizontal" android:layout_centerHorizontal="true" - android:background="@drawable/background_max_height_sign_us" + android:background="@drawable/background_rectangular_sign_yellow" android:padding="16dp" - android:id="@+id/maxHeightInputSign" - > + android:layout_marginStart="36dp" + android:layout_marginEnd="36dp" + android:id="@+id/feetInputSign"> + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 25b1fae9e0..1794841e46 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -526,6 +526,4 @@ Otherwise, you can download another keyboard in the app store. Popular keyboards The physical height does not restrict the general traffic I can not estimate the height This height looks implausible. Are you sure that it is correct? - The unit is imperial - The unit is metric diff --git a/res/country_metadata/heightUnit.yml b/res/country_metadata/heightUnit.yml index 96c9843dd2..c112acbc41 100644 --- a/res/country_metadata/heightUnit.yml +++ b/res/country_metadata/heightUnit.yml @@ -3,7 +3,6 @@ # https://en.wikipedia.org/wiki/Imperial_units#Current_use # https://en.wikipedia.org/wiki/Comparison_of_MUTCD-influenced_traffic_signs default: [m] -CA: [m, ft] FM: [ft, m] GB: [ft, m] LR: [ft, m] From bd2f1943a3c599eed2bcf869d71f49c22629a54d Mon Sep 17 00:00:00 2001 From: ENT8R Date: Thu, 28 Jun 2018 18:18:50 +0200 Subject: [PATCH 08/35] Merged speedUnit.yml and heightUnit.yml to a new file called measurementSystem.yml --- .../data/meta/CountryInfosTest.java | 8 ++--- app/src/main/assets/country_metadata/AG.yml | 1 + app/src/main/assets/country_metadata/AS.yml | 2 +- app/src/main/assets/country_metadata/BS.yml | 2 +- app/src/main/assets/country_metadata/BZ.yml | 2 +- app/src/main/assets/country_metadata/DM.yml | 2 +- app/src/main/assets/country_metadata/FK.yml | 2 +- app/src/main/assets/country_metadata/FM.yml | 2 +- app/src/main/assets/country_metadata/GB.yml | 3 +- app/src/main/assets/country_metadata/GD.yml | 2 +- app/src/main/assets/country_metadata/GU.yml | 2 +- app/src/main/assets/country_metadata/GY.yml | 1 + app/src/main/assets/country_metadata/KY.yml | 2 +- app/src/main/assets/country_metadata/LC.yml | 2 +- app/src/main/assets/country_metadata/LR.yml | 2 +- app/src/main/assets/country_metadata/MH.yml | 2 +- app/src/main/assets/country_metadata/MM.yml | 3 +- app/src/main/assets/country_metadata/MP.yml | 2 +- app/src/main/assets/country_metadata/PR.yml | 2 +- app/src/main/assets/country_metadata/PW.yml | 2 +- app/src/main/assets/country_metadata/TC.yml | 2 +- app/src/main/assets/country_metadata/US.yml | 3 +- app/src/main/assets/country_metadata/VC.yml | 2 +- app/src/main/assets/country_metadata/VG.yml | 2 +- app/src/main/assets/country_metadata/VI.yml | 2 +- app/src/main/assets/country_metadata/WS.yml | 3 +- .../main/assets/country_metadata/default.yml | 3 +- .../streetcomplete/data/meta/CountryInfo.java | 12 ++----- .../quests/max_height/AddMaxHeight.java | 9 ++--- .../quests/max_height/AddMaxHeightForm.java | 35 +++++++++++++++---- .../quests/max_speed/AddMaxSpeedForm.java | 24 +++++++++++-- .../res/layout/quest_maxheight_canada.xml | 1 - res/country_metadata/heightUnit.yml | 13 ------- res/country_metadata/measurementSystem.yml | 32 +++++++++++++++++ res/country_metadata/speedUnit.yml | 21 ----------- 35 files changed, 117 insertions(+), 93 deletions(-) delete mode 100644 res/country_metadata/heightUnit.yml create mode 100644 res/country_metadata/measurementSystem.yml delete mode 100644 res/country_metadata/speedUnit.yml diff --git a/app/src/androidTest/java/de/westnordost/streetcomplete/data/meta/CountryInfosTest.java b/app/src/androidTest/java/de/westnordost/streetcomplete/data/meta/CountryInfosTest.java index d3f9864165..bcc4c09193 100644 --- a/app/src/androidTest/java/de/westnordost/streetcomplete/data/meta/CountryInfosTest.java +++ b/app/src/androidTest/java/de/westnordost/streetcomplete/data/meta/CountryInfosTest.java @@ -20,10 +20,10 @@ private void checkFirstDayOfWorkweekIsValid(CountryInfo info) assertTrue(Weekdays.getWeekdayIndex(info.getFirstDayOfWorkweek()) > -1); } - private void checkSpeedUnitIsEitherKmhOrMph(CountryInfo info) + private void checkMeasurementUnitIsEitherMetricOrImperial(CountryInfo info) { - assertNotNull(info.getSpeedUnits()); - assertTrue(info.getSpeedUnits().contains("mph") || info.getSpeedUnits().contains("km/h")); + assertNotNull(info.getMeasurementSystem()); + assertTrue(info.getMeasurementSystem().contains("metric") || info.getMeasurementSystem().contains("imperial")); } private void checkAdditionalValidHousenumberRegexes(Map infos) @@ -48,7 +48,7 @@ private void checkStartOfWorkweekValid(CountryInfo info) private void checkForEach(CountryInfo info) { checkFirstDayOfWorkweekIsValid(info); - checkSpeedUnitIsEitherKmhOrMph(info); + checkMeasurementUnitIsEitherMetricOrImperial(info); checkRegularShoppingDaysIsBetween0And7(info); checkStartOfWorkweekValid(info); } diff --git a/app/src/main/assets/country_metadata/AG.yml b/app/src/main/assets/country_metadata/AG.yml index b02e11b9f4..fb99aed95b 100644 --- a/app/src/main/assets/country_metadata/AG.yml +++ b/app/src/main/assets/country_metadata/AG.yml @@ -1,5 +1,6 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] mobileCountryCode: 344 officialLanguages: [en] orchardProduces: [guava, mango, mangosteen, lemon, lime, tomatoe, pineapple, banana, chilli_pepper, diff --git a/app/src/main/assets/country_metadata/AS.yml b/app/src/main/assets/country_metadata/AS.yml index 6cdb92dcd2..0406b7297e 100644 --- a/app/src/main/assets/country_metadata/AS.yml +++ b/app/src/main/assets/country_metadata/AS.yml @@ -1,4 +1,4 @@ # Do not edit. Source files are in /res/country_metadata +measurementSystem: [imperial, metric] officialLanguages: [en, sm] orchardProduces: [coconut, banana, tomatoe, cacao] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/BS.yml b/app/src/main/assets/country_metadata/BS.yml index 0ad22d8f66..53fd0f2c1f 100644 --- a/app/src/main/assets/country_metadata/BS.yml +++ b/app/src/main/assets/country_metadata/BS.yml @@ -1,8 +1,8 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] mobileCountryCode: 364 officialLanguages: [en] orchardProduces: [grapefruit, banana, coconut, lemon, lime, orange, tomatoe, guava, mango, mangosteen, avocado, papaya] popularSports: [tennis, basketball, baseball] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/BZ.yml b/app/src/main/assets/country_metadata/BZ.yml index 27c2d606ca..86b9672a04 100644 --- a/app/src/main/assets/country_metadata/BZ.yml +++ b/app/src/main/assets/country_metadata/BZ.yml @@ -1,6 +1,6 @@ # Do not edit. Source files are in /res/country_metadata +measurementSystem: [imperial, metric] mobileCountryCode: 702 officialLanguages: [en, bzj] orchardProduces: [orange, grapefruit, banana, cacao, papaya, coconut, pineapple, cashew_nut, chilli_pepper, sweet_pepper, coffee, tomatoe, guava, mango, mangosteen] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/DM.yml b/app/src/main/assets/country_metadata/DM.yml index d0707ae599..188b1eac7f 100644 --- a/app/src/main/assets/country_metadata/DM.yml +++ b/app/src/main/assets/country_metadata/DM.yml @@ -1,7 +1,7 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] mobileCountryCode: 366 officialLanguages: [en] orchardProduces: [banana, coconut, cacao, guava, mango, mangosteen, grapefruit, orange, coffee, lemon, lime, avocado, tomatoe, pineapple, nutmeg, papaya] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/FK.yml b/app/src/main/assets/country_metadata/FK.yml index c2007ab02b..c7fc6d1923 100644 --- a/app/src/main/assets/country_metadata/FK.yml +++ b/app/src/main/assets/country_metadata/FK.yml @@ -1,4 +1,4 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [en] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/FM.yml b/app/src/main/assets/country_metadata/FM.yml index e2c0ad74c1..8a841270de 100644 --- a/app/src/main/assets/country_metadata/FM.yml +++ b/app/src/main/assets/country_metadata/FM.yml @@ -1,5 +1,5 @@ # Do not edit. Source files are in /res/country_metadata -heightUnit: [ft, m] +measurementSystem: [imperial, metric] mobileCountryCode: 550 officialLanguages: [en, chk, pon] orchardProduces: [coconut, banana, cacao] diff --git a/app/src/main/assets/country_metadata/GB.yml b/app/src/main/assets/country_metadata/GB.yml index a4c2274d99..203e2e93ca 100644 --- a/app/src/main/assets/country_metadata/GB.yml +++ b/app/src/main/assets/country_metadata/GB.yml @@ -1,14 +1,13 @@ # Do not edit. Source files are in /res/country_metadata additionalStreetsignLanguages: [cy, gd] -heightUnit: [ft, m] isAdvisorySpeedLimitKnown: true isLeftHandTraffic: true isLivingStreetKnown: true isSlowZoneKnown: true +measurementSystem: [imperial, metric] mobileCountryCode: 234 officialLanguages: [en] orchardProduces: [apple, strawberry, raspberry, pear, plum, cherry, hop, grape, tomatoe, chilli_pepper, sweet_pepper] popularReligions: [christian, muslim, jewish, hindu, sikh] popularSports: [soccer, tennis, bowls, cricket, golf, basketball, rugby] -speedUnit: [mph] diff --git a/app/src/main/assets/country_metadata/GD.yml b/app/src/main/assets/country_metadata/GD.yml index 8fdb20b3fa..e150f43f08 100644 --- a/app/src/main/assets/country_metadata/GD.yml +++ b/app/src/main/assets/country_metadata/GD.yml @@ -1,8 +1,8 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [metric, imperial] mobileCountryCode: 352 officialLanguages: [en] orchardProduces: [coconut, cacao, banana, nutmeg, avocado, guava, mango, mangosteen, plum, grapefruit, orange, apple, tomatoe, lemon, lime, chilli_pepper, sweet_pepper, pineapple] popularSports: [cricket] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/GU.yml b/app/src/main/assets/country_metadata/GU.yml index 7cbc4e6c33..2ec87dd8df 100644 --- a/app/src/main/assets/country_metadata/GU.yml +++ b/app/src/main/assets/country_metadata/GU.yml @@ -1,4 +1,4 @@ # Do not edit. Source files are in /res/country_metadata +measurementSystem: [imperial, metric] officialLanguages: [en, ch] orchardProduces: [coconut, tomatoe, banana] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/GY.yml b/app/src/main/assets/country_metadata/GY.yml index 155da64f6b..1eb07483d2 100644 --- a/app/src/main/assets/country_metadata/GY.yml +++ b/app/src/main/assets/country_metadata/GY.yml @@ -1,5 +1,6 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [metric, imperial] mobileCountryCode: 738 officialLanguages: [en, gyn] orchardProduces: [coconut, tomatoe, chilli_pepper, sweet_pepper, cacao, banana, pepper, orange, pineapple, diff --git a/app/src/main/assets/country_metadata/KY.yml b/app/src/main/assets/country_metadata/KY.yml index c53bc85771..aee4af51f7 100644 --- a/app/src/main/assets/country_metadata/KY.yml +++ b/app/src/main/assets/country_metadata/KY.yml @@ -1,5 +1,5 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [en] orchardProduces: [banana, tomatoe] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/LC.yml b/app/src/main/assets/country_metadata/LC.yml index f0b5c0a050..77b43e2477 100644 --- a/app/src/main/assets/country_metadata/LC.yml +++ b/app/src/main/assets/country_metadata/LC.yml @@ -1,7 +1,7 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] mobileCountryCode: 358 officialLanguages: [en] orchardProduces: [coconut, banana, pepper, grapefruit, nutmeg, lemon, lime, orange, guava, mango, mangosteen, cacao, avocado, tomatoe, pineapple] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/LR.yml b/app/src/main/assets/country_metadata/LR.yml index fe56e30c87..84bc0adb3b 100644 --- a/app/src/main/assets/country_metadata/LR.yml +++ b/app/src/main/assets/country_metadata/LR.yml @@ -1,5 +1,5 @@ # Do not edit. Source files are in /res/country_metadata -heightUnit: [ft, m] +measurementSystem: [imperial, metric] mobileCountryCode: 618 officialLanguages: [en] orchardProduces: [rubber, cacao, palm_oil, banana, coffee, coconut, orange, pineapple, tomatoe] diff --git a/app/src/main/assets/country_metadata/MH.yml b/app/src/main/assets/country_metadata/MH.yml index a1a395fc28..c8a7024ab9 100644 --- a/app/src/main/assets/country_metadata/MH.yml +++ b/app/src/main/assets/country_metadata/MH.yml @@ -1,5 +1,5 @@ # Do not edit. Source files are in /res/country_metadata -heightUnit: [ft, m] +measurementSystem: [imperial, metric] mobileCountryCode: 551 officialLanguages: [mh, en] orchardProduces: [coconut] diff --git a/app/src/main/assets/country_metadata/MM.yml b/app/src/main/assets/country_metadata/MM.yml index fc2937a7ff..4b0e5b19a8 100644 --- a/app/src/main/assets/country_metadata/MM.yml +++ b/app/src/main/assets/country_metadata/MM.yml @@ -1,10 +1,9 @@ # Do not edit. Source files are in /res/country_metadata additionalStreetsignLanguages: [en] -heightUnit: [ft, m] +measurementSystem: [imperial, metric] mobileCountryCode: 414 officialLanguages: [my] orchardProduces: [rubber, chilli_pepper, sweet_pepper, tea, areca_nut, coconut, coffee, cashew_nut, guava, mango, mangosteen] popularReligions: [buddhist, christian, muslim, hindu] popularSports: [soccer, tennis, sepak_takraw] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/MP.yml b/app/src/main/assets/country_metadata/MP.yml index 8afed18642..449538980f 100644 --- a/app/src/main/assets/country_metadata/MP.yml +++ b/app/src/main/assets/country_metadata/MP.yml @@ -1,3 +1,3 @@ # Do not edit. Source files are in /res/country_metadata +measurementSystem: [imperial, metric] officialLanguages: [ch] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/PR.yml b/app/src/main/assets/country_metadata/PR.yml index 6e9205e617..b3d2bca2c5 100644 --- a/app/src/main/assets/country_metadata/PR.yml +++ b/app/src/main/assets/country_metadata/PR.yml @@ -1,6 +1,6 @@ # Do not edit. Source files are in /res/country_metadata +measurementSystem: [imperial, metric] officialLanguages: [en] orchardProduces: [coffee, banana, orange, guava, mango, mangosteen, avocado, pineapple, tomatoe, coconut, papaya, grapefruit, chilli_pepper, sweet_pepper, lemon, lime] popularSports: [basketball, tennis, baseball] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/PW.yml b/app/src/main/assets/country_metadata/PW.yml index 707c35b514..c4aaaef65b 100644 --- a/app/src/main/assets/country_metadata/PW.yml +++ b/app/src/main/assets/country_metadata/PW.yml @@ -1,4 +1,4 @@ # Do not edit. Source files are in /res/country_metadata -heightUnit: [ft, m] +measurementSystem: [imperial, metric] mobileCountryCode: 552 officialLanguages: [en, pau] diff --git a/app/src/main/assets/country_metadata/TC.yml b/app/src/main/assets/country_metadata/TC.yml index c2007ab02b..c7fc6d1923 100644 --- a/app/src/main/assets/country_metadata/TC.yml +++ b/app/src/main/assets/country_metadata/TC.yml @@ -1,4 +1,4 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [en] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/US.yml b/app/src/main/assets/country_metadata/US.yml index 1794cf64a6..6f9ee0d472 100644 --- a/app/src/main/assets/country_metadata/US.yml +++ b/app/src/main/assets/country_metadata/US.yml @@ -1,10 +1,9 @@ # Do not edit. Source files are in /res/country_metadata -heightUnit: [ft] isAdvisorySpeedLimitKnown: true +measurementSystem: [imperial] mobileCountryCode: 310 officialLanguages: [en] orchardProduces: [grape, almond, tomatoe, apple, walnut, pistachio, peach, blueberry, grapefruit, plum, chilli_pepper, sweet_pepper, strawberry, avocado, orange, lemon, lime] popularReligions: [christian, jewish] popularSports: [baseball, tennis, basketball, soccer, golf, american_football] -speedUnit: [mph] diff --git a/app/src/main/assets/country_metadata/VC.yml b/app/src/main/assets/country_metadata/VC.yml index cfa1ef42ab..2a6df90dfc 100644 --- a/app/src/main/assets/country_metadata/VC.yml +++ b/app/src/main/assets/country_metadata/VC.yml @@ -1,7 +1,7 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] mobileCountryCode: 360 officialLanguages: [en] orchardProduces: [banana, cacao, coconut, coffee, nutmeg, guava, mango, mangosteen, orange, apple, lemon, lime, chilli_pepper, sweet_pepper, pear, grapefruit] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/VG.yml b/app/src/main/assets/country_metadata/VG.yml index 6151749eea..0c93d1098e 100644 --- a/app/src/main/assets/country_metadata/VG.yml +++ b/app/src/main/assets/country_metadata/VG.yml @@ -1,5 +1,5 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [en] orchardProduces: [banana] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/VI.yml b/app/src/main/assets/country_metadata/VI.yml index c2007ab02b..c7fc6d1923 100644 --- a/app/src/main/assets/country_metadata/VI.yml +++ b/app/src/main/assets/country_metadata/VI.yml @@ -1,4 +1,4 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [en] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/WS.yml b/app/src/main/assets/country_metadata/WS.yml index ba3786ac3a..3fd88465af 100644 --- a/app/src/main/assets/country_metadata/WS.yml +++ b/app/src/main/assets/country_metadata/WS.yml @@ -1,7 +1,6 @@ # Do not edit. Source files are in /res/country_metadata -heightUnit: [ft, m] isLeftHandTraffic: true +measurementSystem: [imperial, metric] mobileCountryCode: 549 officialLanguages: [sm, en] popularSports: [cricket] -speedUnit: [mph, km/h] diff --git a/app/src/main/assets/country_metadata/default.yml b/app/src/main/assets/country_metadata/default.yml index 85abf94943..0d941a6f99 100644 --- a/app/src/main/assets/country_metadata/default.yml +++ b/app/src/main/assets/country_metadata/default.yml @@ -1,13 +1,12 @@ # Do not edit. Source files are in /res/country_metadata firstDayOfWorkweek: Mo -heightUnit: [m] isAdvisorySpeedLimitKnown: false isLeftHandTraffic: false isLivingStreetKnown: false isSlowZoneKnown: false +measurementSystem: [metric] officialLanguages: [en] orchardProduces: [] popularReligions: [] popularSports: [] regularShoppingDays: 6 -speedUnit: [km/h] diff --git a/app/src/main/java/de/westnordost/streetcomplete/data/meta/CountryInfo.java b/app/src/main/java/de/westnordost/streetcomplete/data/meta/CountryInfo.java index 15e6abc767..4ddb2fba8a 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/data/meta/CountryInfo.java +++ b/app/src/main/java/de/westnordost/streetcomplete/data/meta/CountryInfo.java @@ -14,8 +14,7 @@ public class CountryInfo implements Serializable, Cloneable // i.e. US for US-TX.yml String countryCode; - List speedUnit; - List heightUnit; + List measurementSystem; List popularSports; List popularReligions; String firstDayOfWorkweek; @@ -30,14 +29,9 @@ public class CountryInfo implements Serializable, Cloneable Boolean isLeftHandTraffic; Integer mobileCountryCode; - public List getSpeedUnits() + public List getMeasurementSystem() { - return speedUnit; - } - - public List getHeightUnits() - { - return heightUnit; + return measurementSystem; } public List getPopularSports() diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java index 8c884ab286..f18ee18c26 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeight.java @@ -11,8 +11,7 @@ import de.westnordost.osmapi.map.data.BoundingBox; import de.westnordost.osmapi.map.data.Element; import de.westnordost.streetcomplete.R; -import de.westnordost.streetcomplete.data.osm.Countries; -import de.westnordost.streetcomplete.data.osm.OsmElementQuestType; +import de.westnordost.streetcomplete.data.osm.AOsmElementQuestType; import de.westnordost.streetcomplete.data.osm.changes.StringMapChangesBuilder; import de.westnordost.streetcomplete.data.osm.download.MapDataWithGeometryHandler; import de.westnordost.streetcomplete.data.osm.download.OverpassMapDataDao; @@ -21,7 +20,7 @@ import de.westnordost.streetcomplete.data.osm.tql.TagFilterExpression; import de.westnordost.streetcomplete.quests.AbstractQuestAnswerFragment; -public class AddMaxHeight implements OsmElementQuestType +public class AddMaxHeight extends AOsmElementQuestType { private final OverpassMapDataDao overpassServer; @@ -106,8 +105,4 @@ else if(noSign == AddMaxHeightForm.IS_NOT_INDICATED) return R.string.quest_maxheight_title; } - - @Override public int getTitle() { return R.string.quest_maxheight_title; } - @Override public int getDefaultDisabledMessage() { return 0; } - @NonNull @Override public Countries getEnabledForCountries() { return Countries.ALL; } } diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java index 29cb25fdb8..4c50feb346 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java @@ -40,7 +40,7 @@ public class AddMaxHeightForm extends AbstractQuestFormAnswerFragment { View view = super.onCreateView(inflater, container, savedInstanceState); - String unit = getCountryInfo().getHeightUnits().get(0).equals("m") ? Height.METRIC : Height.IMPERIAL; + String unit = getCountryInfo().getMeasurementSystem().get(0).equals("metric") ? Height.METRIC : Height.IMPERIAL; setMaxHeightSignLayout(R.layout.quest_maxheight, unit); addOtherAnswers(); @@ -69,18 +69,24 @@ private void switchLayout(String unit) if (unit.equals(Height.METRIC)) { meterInputSign.setVisibility(View.VISIBLE); - feetInputSign.setVisibility(View.GONE); + if (feetInputSign != null) + { + feetInputSign.setVisibility(View.GONE); + } } else { feetInputSign.setVisibility(View.VISIBLE); - meterInputSign.setVisibility(View.GONE); + if (meterInputSign != null) + { + meterInputSign.setVisibility(View.GONE); + } } } private void initHeightUnitSelect() { - List heightUnits = getCountryInfo().getHeightUnits(); - heightUnitSelect.setVisibility(heightUnits.size() == 1 ? View.GONE : View.VISIBLE); - heightUnitSelect.setAdapter(new ArrayAdapter<>(getContext(), R.layout.spinner_item_centered, heightUnits)); + List measurementUnits = getCountryInfo().getMeasurementSystem(); + heightUnitSelect.setVisibility(measurementUnits.size() == 1 ? View.GONE : View.VISIBLE); + heightUnitSelect.setAdapter(new ArrayAdapter<>(getContext(), R.layout.spinner_item_centered, getSpinnerItems(measurementUnits))); heightUnitSelect.setSelection(0); heightUnitSelect.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @@ -96,6 +102,23 @@ public void onNothingSelected(AdapterView parentView) {} }); } + private List getSpinnerItems(List units) + { + List items = new ArrayList<>(); + + for (int i = 0; i < units.size(); i++) { + String unit = units.get(i); + if (unit.equals("metric")) + { + items.add("m"); + } else if (unit.equals("imperial")) + { + items.add("ft"); + } + } + return items; + } + private void addOtherAnswers() { addOtherAnswer(R.string.quest_maxheight_answer_noSign, () -> diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_speed/AddMaxSpeedForm.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_speed/AddMaxSpeedForm.java index e262d0d984..95bc0753cf 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_speed/AddMaxSpeedForm.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_speed/AddMaxSpeedForm.java @@ -12,6 +12,7 @@ import android.widget.Spinner; import android.widget.Toast; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -93,12 +94,29 @@ private void setStreetSignLayout(int resourceId) private void initSpeedUnitSelect() { - List speedUnits = getCountryInfo().getSpeedUnits(); - speedUnitSelect.setVisibility(speedUnits.size() == 1 ? View.GONE : View.VISIBLE); - speedUnitSelect.setAdapter(new ArrayAdapter<>(getContext(), R.layout.spinner_item_centered, speedUnits)); + List measurementUnits = getCountryInfo().getMeasurementSystem(); + speedUnitSelect.setVisibility(measurementUnits.size() == 1 ? View.GONE : View.VISIBLE); + speedUnitSelect.setAdapter(new ArrayAdapter<>(getContext(), R.layout.spinner_item_centered, getSpinnerItems(measurementUnits))); speedUnitSelect.setSelection(0); } + private List getSpinnerItems(List units) + { + List items = new ArrayList<>(); + + for (int i = 0; i < units.size(); i++) { + String unit = units.get(i); + if (unit.equals("metric")) + { + items.add("km/h"); + } else if (unit.equals("imperial")) + { + items.add("mph"); + } + } + return items; + } + private void initZoneCheckbox(View zoneContainer) { boolean isResidential = POSSIBLY_SLOWZONE_ROADS.contains(getOsmElement().getTags().get("highway")); diff --git a/app/src/main/res/layout/quest_maxheight_canada.xml b/app/src/main/res/layout/quest_maxheight_canada.xml index 0f635d248d..bf3ddf0279 100644 --- a/app/src/main/res/layout/quest_maxheight_canada.xml +++ b/app/src/main/res/layout/quest_maxheight_canada.xml @@ -1,6 +1,5 @@ diff --git a/res/country_metadata/heightUnit.yml b/res/country_metadata/heightUnit.yml deleted file mode 100644 index c112acbc41..0000000000 --- a/res/country_metadata/heightUnit.yml +++ /dev/null @@ -1,13 +0,0 @@ -# Sources: -# https://en.wikipedia.org/wiki/Metrication#Overview -# https://en.wikipedia.org/wiki/Imperial_units#Current_use -# https://en.wikipedia.org/wiki/Comparison_of_MUTCD-influenced_traffic_signs -default: [m] -FM: [ft, m] -GB: [ft, m] -LR: [ft, m] -MH: [ft, m] -MM: [ft, m] -PW: [ft, m] -US: [ft] -WS: [ft, m] diff --git a/res/country_metadata/measurementSystem.yml b/res/country_metadata/measurementSystem.yml new file mode 100644 index 0000000000..3c40d6849b --- /dev/null +++ b/res/country_metadata/measurementSystem.yml @@ -0,0 +1,32 @@ +# Sources: +# https://en.wikipedia.org/wiki/Metrication#Overview +# https://en.wikipedia.org/wiki/Imperial_units#Current_use +# https://en.wikipedia.org/wiki/Comparison_of_MUTCD-influenced_traffic_signs +# +# setting imperial, metric for all those small island states where things may change quickly or gov doesn't act on norms +default: [metric] +AG: [imperial, metric] # metric system is introduced but the imperial system remains in common use +AS: [imperial, metric] # territory of the US +BS: [imperial, metric] # mainly imperial units used +BZ: [imperial, metric] # mainly imperial units used +DM: [imperial, metric] # metric system is introduced but the imperial system remains in common use +FK: [imperial, metric] +FM: [imperial, metric] # mainly imperial units used +GB: [imperial, metric] # changeover to the metric system is in progress +GD: [metric, imperial] # metric system is introduced but the imperial system remains in common use +GU: [imperial, metric] # same as Micronesia (FM) because it is part of it +GY: [metric, imperial] # metric system has been introduced in 1982 but the imperial system is still used sometimes +KY: [imperial, metric] # mainly imperial units used +LC: [imperial, metric] # metric system is introduced but the imperial system remains in common use +LR: [imperial, metric] # imperial units are used officially but some signs are using the metric system +MH: [imperial, metric] # mainly imperial units used +MM: [imperial, metric] # Myanmar is converting to the metric system, although very slowly (but with the goal to complete in 2019) +MP: [imperial, metric] # territory of the US +PR: [imperial, metric] # territory of the US +PW: [imperial, metric] # same as Micronesia (FM) because it is part of it +TC: [imperial, metric] # territory of GB +US: [imperial] +VC: [imperial, metric] # mainly imperial units used +VG: [imperial, metric] # mainly imperial units used +VI: [imperial, metric] # mainly imperial units used +WS: [imperial, metric] # Samoa started to convert to the metric system in 2014. diff --git a/res/country_metadata/speedUnit.yml b/res/country_metadata/speedUnit.yml deleted file mode 100644 index ff9b37a3c9..0000000000 --- a/res/country_metadata/speedUnit.yml +++ /dev/null @@ -1,21 +0,0 @@ -# setting mph, km/h for all those small island states where things may change quickly or gov doesn't act on norms -default: [km/h] -AS: [mph, km/h] -BS: [mph, km/h] -BZ: [mph, km/h] -DM: [mph, km/h] -FK: [mph, km/h] -GB: [mph] -GD: [mph, km/h] -GU: [mph, km/h] -KY: [mph, km/h] -LC: [mph, km/h] -MM: [mph, km/h] # have actually seen km/h signs in Myanmar, though rare -MP: [mph, km/h] -PR: [mph, km/h] -TC: [mph, km/h] -US: [mph] -VC: [mph, km/h] -VG: [mph, km/h] -VI: [mph, km/h] -WS: [mph, km/h] From 9a3462afce6ab4c98a82780d1ed0bc3f2c59dac1 Mon Sep 17 00:00:00 2001 From: ENT8R Date: Sat, 7 Jul 2018 11:28:56 +0200 Subject: [PATCH 09/35] Fix some issues after review --- app/src/main/assets/country_metadata/GD.yml | 2 +- .../quests/max_height/AddMaxHeightForm.java | 36 +++++++------------ .../quests/max_height/Height.java | 17 ++++----- res/country_metadata/measurementSystem.yml | 3 +- 4 files changed, 24 insertions(+), 34 deletions(-) diff --git a/app/src/main/assets/country_metadata/GD.yml b/app/src/main/assets/country_metadata/GD.yml index e150f43f08..f56f0926b2 100644 --- a/app/src/main/assets/country_metadata/GD.yml +++ b/app/src/main/assets/country_metadata/GD.yml @@ -1,6 +1,6 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true -measurementSystem: [metric, imperial] +measurementSystem: [imperial, metric] mobileCountryCode: 352 officialLanguages: [en] orchardProduces: [coconut, cacao, banana, nutmeg, avocado, guava, mango, mangosteen, plum, grapefruit, diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java index 4c50feb346..bf8a2c3196 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java @@ -33,21 +33,21 @@ public class AddMaxHeightForm extends AbstractQuestFormAnswerFragment private EditText heightInput, feetInput, inchInput; private Spinner heightUnitSelect; - View meterInputSign, feetInputSign; + private View meterInputSign, feetInputSign; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); - String unit = getCountryInfo().getMeasurementSystem().get(0).equals("metric") ? Height.METRIC : Height.IMPERIAL; + Height.Unit unit = getCountryInfo().getMeasurementSystem().get(0).equals("metric") ? Height.Unit.METRIC : Height.Unit.IMPERIAL; setMaxHeightSignLayout(R.layout.quest_maxheight, unit); addOtherAnswers(); return view; } - private void setMaxHeightSignLayout(int resourceId, String unit) + private void setMaxHeightSignLayout(int resourceId, Height.Unit unit) { View contentView = setContentView(getCurrentCountryResources().getLayout(resourceId)); @@ -64,22 +64,10 @@ private void setMaxHeightSignLayout(int resourceId, String unit) switchLayout(unit); } - private void switchLayout(String unit) + private void switchLayout(Height.Unit unit) { - if (unit.equals(Height.METRIC)) - { - meterInputSign.setVisibility(View.VISIBLE); - if (feetInputSign != null) - { - feetInputSign.setVisibility(View.GONE); - } - } else { - feetInputSign.setVisibility(View.VISIBLE); - if (meterInputSign != null) - { - meterInputSign.setVisibility(View.GONE); - } - } + if(meterInputSign != null) meterInputSign.setVisibility(unit.equals(Height.Unit.METRIC) ? View.VISIBLE : View.GONE); + if(feetInputSign != null) feetInputSign.setVisibility(unit.equals(Height.Unit.IMPERIAL) ? View.VISIBLE : View.GONE); } private void initHeightUnitSelect() @@ -93,7 +81,7 @@ private void initHeightUnitSelect() @Override public void onItemSelected(AdapterView parentView, View selectedItemView, int position, long id) { - String heightUnit = heightUnitSelect.getSelectedItem().equals("m") ? Height.METRIC : Height.IMPERIAL; + Height.Unit heightUnit = heightUnitSelect.getSelectedItem().equals("m") ? Height.Unit.METRIC : Height.Unit.IMPERIAL; switchLayout(heightUnit); } @@ -196,9 +184,9 @@ private void onAnswer() private boolean userSelectedUnrealisticHeight() { double height = getHeightFromInput().toDouble(); - String heightUnit = getHeightFromInput().getUnit(); + Height.Unit heightUnit = getHeightFromInput().getUnit(); - double heightInMeter = heightUnit.equals(Height.METRIC) ? height : feetToMeter(height); + double heightInMeter = heightUnit.equals(Height.Unit.METRIC) ? height : feetToMeter(height); return heightInMeter > 6 || heightInMeter < 2; } @@ -228,9 +216,9 @@ private Height getHeightFromInput() if (input.contains(".")) { String[] parts = input.split("\\."); - return new Height(parts[0], parts[1], Height.METRIC); + return new Height(parts[0], parts[1], Height.Unit.METRIC); } else { - return new Height(input, "0", Height.METRIC); + return new Height(input, "0", Height.Unit.METRIC); } } return new Height(); @@ -239,7 +227,7 @@ private Height getHeightFromInput() { if (!feetInput.getText().toString().isEmpty() && !inchInput.getText().toString().isEmpty()) { - return new Height(feetInput.getText().toString(), inchInput.getText().toString(), Height.IMPERIAL); + return new Height(feetInput.getText().toString(), inchInput.getText().toString(), Height.Unit.IMPERIAL); } return new Height(); } diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java index 1692530305..ac070aeb15 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java @@ -6,27 +6,28 @@ public class Height private int integerPart; private int fractionalPart; - private String unit; + private Unit unit; - public final static String - METRIC = "metric", - IMPERIAL = "imperial"; + public enum Unit { + METRIC, + IMPERIAL + } Height() { this.integerPart = -1; this.fractionalPart = -1; - this.unit = METRIC; + this.unit = Unit.METRIC; } - Height(String integerPart, String fractionalPart, String unit) + Height(String integerPart, String fractionalPart, Unit unit) { this.integerPart = Integer.parseInt(integerPart); this.fractionalPart = Integer.parseInt(fractionalPart); this.unit = unit; } - public String getUnit() + public Unit getUnit() { return unit; } @@ -38,7 +39,7 @@ public boolean isEmpty() public String toString() { - if (unit.equals(METRIC)) + if (unit.equals(Unit.METRIC)) { return String.valueOf(integerPart) + "." + String.valueOf(fractionalPart); } diff --git a/res/country_metadata/measurementSystem.yml b/res/country_metadata/measurementSystem.yml index 3c40d6849b..2555459645 100644 --- a/res/country_metadata/measurementSystem.yml +++ b/res/country_metadata/measurementSystem.yml @@ -2,6 +2,7 @@ # https://en.wikipedia.org/wiki/Metrication#Overview # https://en.wikipedia.org/wiki/Imperial_units#Current_use # https://en.wikipedia.org/wiki/Comparison_of_MUTCD-influenced_traffic_signs +# https://en.wikipedia.org/wiki/Miles_per_hour # # setting imperial, metric for all those small island states where things may change quickly or gov doesn't act on norms default: [metric] @@ -13,7 +14,7 @@ DM: [imperial, metric] # metric system is introduced but the imperial system rem FK: [imperial, metric] FM: [imperial, metric] # mainly imperial units used GB: [imperial, metric] # changeover to the metric system is in progress -GD: [metric, imperial] # metric system is introduced but the imperial system remains in common use +GD: [imperial, metric] GU: [imperial, metric] # same as Micronesia (FM) because it is part of it GY: [metric, imperial] # metric system has been introduced in 1982 but the imperial system is still used sometimes KY: [imperial, metric] # mainly imperial units used From 34afef12cc5051839b2f87156aa45e405dfcfcf5 Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Mon, 6 Aug 2018 00:29:48 +0200 Subject: [PATCH 10/35] sanitize layouts --- .../drawable/background_maxheight_sign.xml | 6 ++-- .../drawable/background_maxheight_sign_gb.xml | 6 ++-- .../background_maxheight_sign_yellow.xml | 6 ++-- .../res/drawable/maxheight_canada_arrow.xml | 4 +-- app/src/main/res/layout/quest_maxheight.xml | 4 ++- .../res/layout/quest_maxheight_australia.xml | 33 +++++++++---------- .../res/layout/quest_maxheight_canada.xml | 21 +++++------- .../main/res/layout/quest_maxheight_feet.xml | 22 ++++++++----- .../main/res/layout/quest_maxheight_meter.xml | 17 ++++++---- .../main/res/layout/quest_maxheight_us.xml | 29 ++++++++-------- 10 files changed, 75 insertions(+), 73 deletions(-) diff --git a/app/src/main/res/drawable/background_maxheight_sign.xml b/app/src/main/res/drawable/background_maxheight_sign.xml index 640bac9a12..7afb01472f 100644 --- a/app/src/main/res/drawable/background_maxheight_sign.xml +++ b/app/src/main/res/drawable/background_maxheight_sign.xml @@ -1,12 +1,12 @@ + android:visibility="gone" + tools:visibility="visible"/> diff --git a/app/src/main/res/layout/quest_maxheight_australia.xml b/app/src/main/res/layout/quest_maxheight_australia.xml index 05a3408ef9..dacfd47594 100644 --- a/app/src/main/res/layout/quest_maxheight_australia.xml +++ b/app/src/main/res/layout/quest_maxheight_australia.xml @@ -6,52 +6,51 @@ + android:padding="16dp"> + tools:text="1.55" /> @@ -63,8 +62,8 @@ android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" - android:layout_marginEnd="20dp" - android:background="#0fff" - android:visibility="visible" /> + android:layout_marginEnd="16dp" + android:visibility="gone" + tools:visibility="visible"/> diff --git a/app/src/main/res/layout/quest_maxheight_canada.xml b/app/src/main/res/layout/quest_maxheight_canada.xml index bf3ddf0279..cb3422d82b 100644 --- a/app/src/main/res/layout/quest_maxheight_canada.xml +++ b/app/src/main/res/layout/quest_maxheight_canada.xml @@ -5,29 +5,25 @@ xmlns:tools="http://schemas.android.com/tools"> + tools:text="1.55" /> diff --git a/app/src/main/res/layout/quest_maxheight_feet.xml b/app/src/main/res/layout/quest_maxheight_feet.xml index 7fa1a5ab14..276fc0b3f3 100644 --- a/app/src/main/res/layout/quest_maxheight_feet.xml +++ b/app/src/main/res/layout/quest_maxheight_feet.xml @@ -5,19 +5,21 @@ android:layout_width="112dp" android:layout_height="112dp" android:gravity="center" - android:layout_centerHorizontal="true" - android:background="@drawable/background_maxheight_sign_gb"> + android:background="@drawable/background_maxheight_sign_gb" + android:padding="14dp"> @@ -26,31 +28,33 @@ android:layout_height="wrap_content" android:gravity="center" android:text="´" - android:textColor="#000000" + android:textColor="@color/traffic_black" android:textSize="24dp" android:textStyle="bold" tools:ignore="HardcodedText" /> + tools:text="11" /> diff --git a/app/src/main/res/layout/quest_maxheight_meter.xml b/app/src/main/res/layout/quest_maxheight_meter.xml index 88a677a4a1..8f23120510 100644 --- a/app/src/main/res/layout/quest_maxheight_meter.xml +++ b/app/src/main/res/layout/quest_maxheight_meter.xml @@ -5,28 +5,31 @@ android:layout_width="112dp" android:layout_height="112dp" android:gravity="center" - android:layout_centerHorizontal="true" - android:background="@drawable/background_maxheight_sign"> + android:background="@drawable/background_maxheight_sign" + android:padding="14dp"> + tools:text="1.44" /> diff --git a/app/src/main/res/layout/quest_maxheight_us.xml b/app/src/main/res/layout/quest_maxheight_us.xml index c6edce665c..2449a549ce 100644 --- a/app/src/main/res/layout/quest_maxheight_us.xml +++ b/app/src/main/res/layout/quest_maxheight_us.xml @@ -5,29 +5,27 @@ xmlns:tools="http://schemas.android.com/tools"> @@ -38,22 +36,23 @@ android:textStyle="bold" android:textSize="30dp" android:gravity="center" - android:textColor="#000000" + android:textColor="@color/traffic_black" tools:ignore="HardcodedText"/> + tools:text="11" /> + android:layout_marginEnd="16dp" + android:visibility="gone" + tools:visibility="visible"/> From 12ae85e9479372916d5988039e908c93eb72a1fa Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Mon, 6 Aug 2018 00:30:27 +0200 Subject: [PATCH 11/35] use of current country resources is now automatic --- .../quests/max_height/AddMaxHeightForm.java | 19 ++++++++----------- .../background_maxheight_sign.xml | 1 - 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java index bf8a2c3196..d98b2c3737 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java @@ -49,7 +49,7 @@ public class AddMaxHeightForm extends AbstractQuestFormAnswerFragment private void setMaxHeightSignLayout(int resourceId, Height.Unit unit) { - View contentView = setContentView(getCurrentCountryResources().getLayout(resourceId)); + View contentView = setContentView(resourceId); heightInput = contentView.findViewById(R.id.meterInput); feetInput = contentView.findViewById(R.id.feetInput); @@ -77,7 +77,8 @@ private void initHeightUnitSelect() heightUnitSelect.setAdapter(new ArrayAdapter<>(getContext(), R.layout.spinner_item_centered, getSpinnerItems(measurementUnits))); heightUnitSelect.setSelection(0); - heightUnitSelect.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + heightUnitSelect.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() + { @Override public void onItemSelected(AdapterView parentView, View selectedItemView, int position, long id) { @@ -94,15 +95,10 @@ private List getSpinnerItems(List units) { List items = new ArrayList<>(); - for (int i = 0; i < units.size(); i++) { - String unit = units.get(i); - if (unit.equals("metric")) - { - items.add("m"); - } else if (unit.equals("imperial")) - { - items.add("ft"); - } + for (String unit : units) + { + if (unit.equals("metric")) items.add("m"); + else if (unit.equals("imperial")) items.add("ft"); } return items; } @@ -235,6 +231,7 @@ private Height getHeightFromInput() private void confirmUnusualInput(final Runnable callback) { + if(getActivity() == null) return; new AlertDialogBuilder(getActivity()) .setTitle(R.string.quest_generic_confirmation_title) .setMessage(R.string.quest_maxheight_unusualInput_confirmation_description) diff --git a/app/src/main/res/drawable-mcc240/background_maxheight_sign.xml b/app/src/main/res/drawable-mcc240/background_maxheight_sign.xml index 9f61fd5f71..2ef8b623bc 100644 --- a/app/src/main/res/drawable-mcc240/background_maxheight_sign.xml +++ b/app/src/main/res/drawable-mcc240/background_maxheight_sign.xml @@ -1,6 +1,5 @@ - From 7598410ba52a374663f54b783d3c1c9453bf3086 Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Mon, 6 Aug 2018 00:40:33 +0200 Subject: [PATCH 12/35] update measurementSystem metadata --- app/src/main/assets/country_metadata/AI.yml | 1 + app/src/main/assets/country_metadata/BM.yml | 1 + app/src/main/assets/country_metadata/GG.yml | 1 + app/src/main/assets/country_metadata/GI.yml | 1 + app/src/main/assets/country_metadata/GS.yml | 1 + app/src/main/assets/country_metadata/IM.yml | 1 + app/src/main/assets/country_metadata/JE.yml | 1 + app/src/main/assets/country_metadata/MS.yml | 1 + app/src/main/assets/country_metadata/US.yml | 2 +- res/country_metadata/measurementSystem.yml | 12 ++++++++++-- 10 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/src/main/assets/country_metadata/AI.yml b/app/src/main/assets/country_metadata/AI.yml index 07a44c65bb..c7fc6d1923 100644 --- a/app/src/main/assets/country_metadata/AI.yml +++ b/app/src/main/assets/country_metadata/AI.yml @@ -1,3 +1,4 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [en] diff --git a/app/src/main/assets/country_metadata/BM.yml b/app/src/main/assets/country_metadata/BM.yml index 4aba74bde7..aee4af51f7 100644 --- a/app/src/main/assets/country_metadata/BM.yml +++ b/app/src/main/assets/country_metadata/BM.yml @@ -1,4 +1,5 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [en] orchardProduces: [banana, tomatoe] diff --git a/app/src/main/assets/country_metadata/GG.yml b/app/src/main/assets/country_metadata/GG.yml index 07a44c65bb..c7fc6d1923 100644 --- a/app/src/main/assets/country_metadata/GG.yml +++ b/app/src/main/assets/country_metadata/GG.yml @@ -1,3 +1,4 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [en] diff --git a/app/src/main/assets/country_metadata/GI.yml b/app/src/main/assets/country_metadata/GI.yml index b0b4cf38c2..eed4c94530 100644 --- a/app/src/main/assets/country_metadata/GI.yml +++ b/app/src/main/assets/country_metadata/GI.yml @@ -1,2 +1,3 @@ # Do not edit. Source files are in /res/country_metadata +measurementSystem: [imperial, metric] officialLanguages: [en] diff --git a/app/src/main/assets/country_metadata/GS.yml b/app/src/main/assets/country_metadata/GS.yml index 07a44c65bb..c7fc6d1923 100644 --- a/app/src/main/assets/country_metadata/GS.yml +++ b/app/src/main/assets/country_metadata/GS.yml @@ -1,3 +1,4 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [en] diff --git a/app/src/main/assets/country_metadata/IM.yml b/app/src/main/assets/country_metadata/IM.yml index d02a46307a..e0f78025b3 100644 --- a/app/src/main/assets/country_metadata/IM.yml +++ b/app/src/main/assets/country_metadata/IM.yml @@ -1,3 +1,4 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [gv, en] diff --git a/app/src/main/assets/country_metadata/JE.yml b/app/src/main/assets/country_metadata/JE.yml index 07a44c65bb..c7fc6d1923 100644 --- a/app/src/main/assets/country_metadata/JE.yml +++ b/app/src/main/assets/country_metadata/JE.yml @@ -1,3 +1,4 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [en] diff --git a/app/src/main/assets/country_metadata/MS.yml b/app/src/main/assets/country_metadata/MS.yml index 6ba5b1717a..5aad2cca7c 100644 --- a/app/src/main/assets/country_metadata/MS.yml +++ b/app/src/main/assets/country_metadata/MS.yml @@ -1,4 +1,5 @@ # Do not edit. Source files are in /res/country_metadata isLeftHandTraffic: true +measurementSystem: [imperial, metric] officialLanguages: [en] orchardProduces: [banana, tomatoe, guava, mango, mangosteen, chilli_pepper, sweet_pepper] diff --git a/app/src/main/assets/country_metadata/US.yml b/app/src/main/assets/country_metadata/US.yml index ecaabf7cc0..1c6fb46528 100644 --- a/app/src/main/assets/country_metadata/US.yml +++ b/app/src/main/assets/country_metadata/US.yml @@ -1,7 +1,7 @@ # Do not edit. Source files are in /res/country_metadata isAdvisorySpeedLimitKnown: true -measurementSystem: [imperial] isSlowZoneKnown: false +measurementSystem: [imperial] mobileCountryCode: 310 officialLanguages: [en] orchardProduces: [grape, almond, tomatoe, apple, walnut, pistachio, peach, blueberry, grapefruit, plum, diff --git a/res/country_metadata/measurementSystem.yml b/res/country_metadata/measurementSystem.yml index 2555459645..c2fc300405 100644 --- a/res/country_metadata/measurementSystem.yml +++ b/res/country_metadata/measurementSystem.yml @@ -7,25 +7,33 @@ # setting imperial, metric for all those small island states where things may change quickly or gov doesn't act on norms default: [metric] AG: [imperial, metric] # metric system is introduced but the imperial system remains in common use +AI: [imperial, metric] # British Overseas Territory AS: [imperial, metric] # territory of the US +BM: [imperial, metric] # British Overseas Territory BS: [imperial, metric] # mainly imperial units used BZ: [imperial, metric] # mainly imperial units used DM: [imperial, metric] # metric system is introduced but the imperial system remains in common use -FK: [imperial, metric] +FK: [imperial, metric] # British Overseas Territory FM: [imperial, metric] # mainly imperial units used GB: [imperial, metric] # changeover to the metric system is in progress GD: [imperial, metric] +GG: [imperial, metric] # British Crown Dependency +GI: [imperial, metric] # British Overseas Territory +GS: [imperial, metric] # British Overseas Territory GU: [imperial, metric] # same as Micronesia (FM) because it is part of it GY: [metric, imperial] # metric system has been introduced in 1982 but the imperial system is still used sometimes +IM: [imperial, metric] # British Crown Dependency +JE: [imperial, metric] # British Crown Dependency KY: [imperial, metric] # mainly imperial units used LC: [imperial, metric] # metric system is introduced but the imperial system remains in common use LR: [imperial, metric] # imperial units are used officially but some signs are using the metric system MH: [imperial, metric] # mainly imperial units used MM: [imperial, metric] # Myanmar is converting to the metric system, although very slowly (but with the goal to complete in 2019) MP: [imperial, metric] # territory of the US +MS: [imperial, metric] # British Overseas Territory PR: [imperial, metric] # territory of the US PW: [imperial, metric] # same as Micronesia (FM) because it is part of it -TC: [imperial, metric] # territory of GB +TC: [imperial, metric] # British Overseas Territory US: [imperial] VC: [imperial, metric] # mainly imperial units used VG: [imperial, metric] # mainly imperial units used From 225a132f9cd2db4027940bea224493e255392edd Mon Sep 17 00:00:00 2001 From: ENT8R Date: Mon, 6 Aug 2018 10:11:49 +0200 Subject: [PATCH 13/35] Refactor height class --- .../quests/max_height/AddMaxHeightForm.java | 30 +++++------ .../quests/max_height/Height.java | 52 ++++++++++++++----- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java index d98b2c3737..36713e2884 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java @@ -12,6 +12,8 @@ import android.widget.Spinner; import android.widget.Toast; +import java.text.NumberFormat; +import java.text.ParseException; import java.util.ArrayList; import java.util.List; @@ -179,16 +181,8 @@ private void onAnswer() private boolean userSelectedUnrealisticHeight() { - double height = getHeightFromInput().toDouble(); - Height.Unit heightUnit = getHeightFromInput().getUnit(); - - double heightInMeter = heightUnit.equals(Height.Unit.METRIC) ? height : feetToMeter(height); - return heightInMeter > 6 || heightInMeter < 2; - } - - private static double feetToMeter(double feet) - { - return feet / 3.2808; + double height = getHeightFromInput().getInMeters(); + return height > 6 || height < 2; } private void applyMaxHeightFormAnswer() @@ -209,12 +203,13 @@ private Height getHeightFromInput() String input = heightInput.getText().toString(); if (!input.isEmpty()) { - if (input.contains(".")) + NumberFormat format = NumberFormat.getInstance(); + try { - String[] parts = input.split("\\."); - return new Height(parts[0], parts[1], Height.Unit.METRIC); - } else { - return new Height(input, "0", Height.Unit.METRIC); + Number number = format.parse(input); + return new Height(number.doubleValue()); + } catch (ParseException e) { + throw new RuntimeException(e); } } return new Height(); @@ -223,7 +218,10 @@ private Height getHeightFromInput() { if (!feetInput.getText().toString().isEmpty() && !inchInput.getText().toString().isEmpty()) { - return new Height(feetInput.getText().toString(), inchInput.getText().toString(), Height.Unit.IMPERIAL); + return new Height( + Integer.parseInt(feetInput.getText().toString()), + Integer.parseInt(inchInput.getText().toString()) + ); } return new Height(); } diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java index ac070aeb15..ad2bb5e648 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java @@ -3,8 +3,10 @@ //if the minimum required API would be 24, we could maybe use https://developer.android.com/reference/android/icu/util/Measure public class Height { - private int integerPart; - private int fractionalPart; + private double meters; + + private int feet; + private int inches; private Unit unit; @@ -15,16 +17,21 @@ public enum Unit { Height() { - this.integerPart = -1; - this.fractionalPart = -1; + this.meters = -1; + this.unit = Unit.METRIC; + } + + Height(double meters) + { + this.meters = meters; this.unit = Unit.METRIC; } - Height(String integerPart, String fractionalPart, Unit unit) + Height(int feet, int inches) { - this.integerPart = Integer.parseInt(integerPart); - this.fractionalPart = Integer.parseInt(fractionalPart); - this.unit = unit; + this.feet = feet; + this.inches = inches; + this.unit = Unit.IMPERIAL; } public Unit getUnit() @@ -34,24 +41,43 @@ public Unit getUnit() public boolean isEmpty() { - return integerPart == -1 && fractionalPart == -1; + if (unit.equals(Unit.METRIC)) + { + return meters == -1; + } + else + { + return feet == -1 && inches == -1; + } } public String toString() { if (unit.equals(Unit.METRIC)) { - return String.valueOf(integerPart) + "." + String.valueOf(fractionalPart); + return String.valueOf(meters); } else { //this adds an apostrophe and a double-quote to be in a format like e.g. 6'7" - return String.valueOf(integerPart) + "'" + String.valueOf(fractionalPart) + "\""; + return String.valueOf(feet) + "'" + String.valueOf(inches) + "\""; + } + } + + public double getInMeters() + { + if (unit.equals(Unit.METRIC)) + { + return meters; + } + else + { + return feetToMeter(Double.parseDouble(feet + "." + inches)); } } - public double toDouble() + private static double feetToMeter(double feet) { - return Double.parseDouble(integerPart + "." + fractionalPart); + return feet / 3.2808; } } From e0ebc94f104ba187551517e2eefb006556f26e8d Mon Sep 17 00:00:00 2001 From: ENT8R Date: Mon, 6 Aug 2018 10:28:04 +0200 Subject: [PATCH 14/35] Remove unnecessary layout code and add another null check --- .../quests/max_height/AddMaxHeightForm.java | 13 +++++++++++-- .../main/res/layout/quest_maxheight_australia.xml | 10 ---------- app/src/main/res/layout/quest_maxheight_us.xml | 10 ---------- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java index 36713e2884..4525b6b8aa 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/AddMaxHeightForm.java @@ -61,7 +61,8 @@ private void setMaxHeightSignLayout(int resourceId, Height.Unit unit) feetInputSign = contentView.findViewById(R.id.feetInputSign); heightUnitSelect = contentView.findViewById(R.id.heightUnitSelect); - initHeightUnitSelect(); + + if (heightUnitSelect != null) initHeightUnitSelect(); switchLayout(unit); } @@ -196,7 +197,15 @@ private void applyMaxHeightFormAnswer() private Height getHeightFromInput() { - boolean isMetric = heightUnitSelect.getSelectedItem().equals("m"); + boolean isMetric; + + if (heightUnitSelect != null) + { + isMetric = heightUnitSelect.getSelectedItem().equals("m"); + } else { + List measurementUnits = getCountryInfo().getMeasurementSystem(); + isMetric = measurementUnits.get(0).equals("metric"); + } if (isMetric) { diff --git a/app/src/main/res/layout/quest_maxheight_australia.xml b/app/src/main/res/layout/quest_maxheight_australia.xml index dacfd47594..23ab628595 100644 --- a/app/src/main/res/layout/quest_maxheight_australia.xml +++ b/app/src/main/res/layout/quest_maxheight_australia.xml @@ -56,14 +56,4 @@ - - diff --git a/app/src/main/res/layout/quest_maxheight_us.xml b/app/src/main/res/layout/quest_maxheight_us.xml index 2449a549ce..0e45f5356d 100644 --- a/app/src/main/res/layout/quest_maxheight_us.xml +++ b/app/src/main/res/layout/quest_maxheight_us.xml @@ -66,14 +66,4 @@ - - From 89edcfc51da78677c9330bc11621f4477449e60d Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Wed, 8 Aug 2018 11:32:54 +0200 Subject: [PATCH 15/35] Fix setContentView not using current country resources --- .../streetcomplete/quests/AbstractQuestAnswerFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/AbstractQuestAnswerFragment.java b/app/src/main/java/de/westnordost/streetcomplete/quests/AbstractQuestAnswerFragment.java index 5a5f0dcdd3..e96552c633 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/AbstractQuestAnswerFragment.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/AbstractQuestAnswerFragment.java @@ -213,7 +213,7 @@ protected final View setContentView(int resourceId) { content.removeAllViews(); } - return LayoutInflater.from(getContext()).inflate(resourceId, content); + return getLayoutInflater().inflate(resourceId, content); } protected final View setButtonsView(int resourceId) From 63ea34f9fe682ede859cc817a5def3d376d0913b Mon Sep 17 00:00:00 2001 From: ENT8R Date: Sat, 11 Aug 2018 12:33:03 +0200 Subject: [PATCH 16/35] Add a method to calculate the height of an object using the phones sensors and the camera --- app/src/main/AndroidManifest.xml | 4 + .../streetcomplete/ApplicationComponent.java | 3 + .../de/westnordost/streetcomplete/Prefs.java | 6 +- .../quests/max_height/AddMaxHeight.java | 11 +- .../quests/max_height/AddMaxHeightForm.java | 162 ++++-- .../quests/max_height/Height.java | 9 +- .../measure/MeasureCameraActivity.java | 42 ++ .../measure/MeasureCameraFragment.java | 527 ++++++++++++++++++ .../max_height/measure/MeasureListener.java | 7 + .../max_height/measure/MeasureUtils.java | 48 ++ .../max_height/measure/SensorListener.java | 48 ++ .../main/res/drawable/ic_help_white_24dp.xml | 5 + .../res/drawable/ic_settings_white_24dp.xml | 5 + .../main/res/drawable/measure_height_help.xml | 103 ++++ .../main/res/layout/height_measure_camera.xml | 49 ++ .../main/res/layout/height_measure_help.xml | 48 ++ .../res/menu/menu_height_measure_camera.xml | 10 + app/src/main/res/values/strings.xml | 33 ++ res/authors.txt | 2 + res/measure_height_help.svg | 127 +++++ 20 files changed, 1186 insertions(+), 63 deletions(-) create mode 100644 app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureCameraActivity.java create mode 100644 app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureCameraFragment.java create mode 100644 app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureListener.java create mode 100644 app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureUtils.java create mode 100644 app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/SensorListener.java create mode 100644 app/src/main/res/drawable/ic_help_white_24dp.xml create mode 100644 app/src/main/res/drawable/ic_settings_white_24dp.xml create mode 100644 app/src/main/res/drawable/measure_height_help.xml create mode 100644 app/src/main/res/layout/height_measure_camera.xml create mode 100644 app/src/main/res/layout/height_measure_help.xml create mode 100644 app/src/main/res/menu/menu_height_measure_camera.xml create mode 100644 res/measure_height_help.svg diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 86e191b5bc..2a769ffd35 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + @@ -49,6 +50,9 @@ + getSpinnerItems(List units) private void addOtherAnswers() { - addOtherAnswer(R.string.quest_maxheight_answer_noSign, () -> - { - final String - restrictsTraffic = getResources().getString(R.string.quest_maxheight_answer_restrictsTraffic), - noTrafficRestriction = getResources().getString(R.string.quest_maxheight_answer_noTrafficRestriction), - cantEstimate = getResources().getString(R.string.quest_maxheight_answer_cantEstimate); - - final List answers = new ArrayList<>(3); - answers.add(restrictsTraffic); - answers.add(noTrafficRestriction); - answers.add(cantEstimate); + //TODO: should this be checked for every quest (may be resource intense) or is there some way to store this as a global constant? + boolean hasCamera = getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA); - DialogInterface.OnClickListener onSelect = new DialogInterface.OnClickListener() + if (hasCamera) + { + addOtherAnswer(R.string.quest_maxheight_answer_noSign, () -> { - Integer selection = null; + new AlertDialogBuilder(getActivity()) + .setMessage(R.string.quest_maxheight_answer_measure_description) + .setPositiveButton(android.R.string.ok, (dialog, which) -> + { + Intent intent = new Intent(getContext(), MeasureCameraActivity.class); + intent.putExtra(MeasureCameraActivity.EXTRA_FRAGMENT_CLASS, MeasureCameraFragment.class.getName()); + intent.putExtra(MeasureCameraFragment.IS_METRIC, isMetric()); + startActivityForResult(intent, HEIGHT_REQUEST_CODE); + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); + }); + } else { + // TODO: should this method/dialog be removed or are there many users without a camera? + addOtherAnswer(R.string.quest_maxheight_answer_noSign, () -> + { + final String + restrictsTraffic = getResources().getString(R.string.quest_maxheight_answer_restrictsTraffic), + noTrafficRestriction = getResources().getString(R.string.quest_maxheight_answer_noTrafficRestriction), + cantEstimate = getResources().getString(R.string.quest_maxheight_answer_cantEstimate); - @Override public void onClick(DialogInterface dialog, int which) + final List answers = new ArrayList<>(3); + answers.add(restrictsTraffic); + answers.add(noTrafficRestriction); + answers.add(cantEstimate); + + DialogInterface.OnClickListener onSelect = new DialogInterface.OnClickListener() { - if (which >= 0) + Integer selection = null; + + @Override public void onClick(DialogInterface dialog, int which) { - selection = which; - ((AlertDialog)dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true); + if (which >= 0) + { + selection = which; + ((AlertDialog)dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true); + } + else if (which == DialogInterface.BUTTON_POSITIVE) + { + if(selection == null || selection < 0 || selection >= answers.size()) return; + onAnswer(); + } } - else if (which == DialogInterface.BUTTON_POSITIVE) + + private void onAnswer() { - if(selection == null || selection < 0 || selection >= answers.size()) return; - onAnswer(); + String answer = answers.get(selection); + Bundle data = new Bundle(); + int type = 0; + if(answer.equals(restrictsTraffic)) type = IS_BELOW_DEFAULT; + if(answer.equals(noTrafficRestriction)) type = IS_DEFAULT; + if(answer.equals(cantEstimate)) type = IS_NOT_INDICATED; + data.putInt(NO_SIGN, type); + applyImmediateAnswer(data); } - } + }; - private void onAnswer() - { - String answer = answers.get(selection); - Bundle data = new Bundle(); - int type = 0; - if(answer.equals(restrictsTraffic)) type = IS_BELOW_DEFAULT; - if(answer.equals(noTrafficRestriction)) type = IS_DEFAULT; - if(answer.equals(cantEstimate)) type = IS_NOT_INDICATED; - data.putInt(NO_SIGN, type); - applyImmediateAnswer(data); - } - }; + AlertDialog dlg = new AlertDialogBuilder(getActivity()) + .setSingleChoiceItems(answers.toArray(new String[0]), -1, onSelect) + .setTitle(R.string.quest_maxheight_answer_noSign_question) + .setPositiveButton(android.R.string.ok, onSelect) + .setNegativeButton(android.R.string.cancel, null) + .show(); - AlertDialog dlg = new AlertDialogBuilder(getActivity()) - .setSingleChoiceItems(answers.toArray(new String[0]), -1, onSelect) - .setTitle(R.string.quest_maxheight_answer_noSign_question) - .setPositiveButton(android.R.string.ok, onSelect) - .setNegativeButton(android.R.string.cancel, null) - .show(); + dlg.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false); + }); + } + } - dlg.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false); - }); + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) + { + if (requestCode == HEIGHT_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + isEstimated = true; + + String unit = data.getStringExtra(MeasureCameraActivity.UNIT); + if (unit.equals(MeasureCameraActivity.METERS)) + { + heightInput.setText(data.getStringExtra(MeasureCameraActivity.METERS)); + } else { + feetInput.setText(data.getStringExtra(MeasureCameraActivity.FEET)); + inchInput.setText(data.getStringExtra(MeasureCameraActivity.INCHES)); + } + } + } } @Override protected void onClickOk() @@ -192,22 +243,13 @@ private void applyMaxHeightFormAnswer() Bundle answer = new Bundle(); answer.putString(MAX_HEIGHT, height); + answer.putBoolean(ESTIMATED_HEIGHT, isEstimated); applyFormAnswer(answer); } private Height getHeightFromInput() { - boolean isMetric; - - if (heightUnitSelect != null) - { - isMetric = heightUnitSelect.getSelectedItem().equals("m"); - } else { - List measurementUnits = getCountryInfo().getMeasurementSystem(); - isMetric = measurementUnits.get(0).equals("metric"); - } - - if (isMetric) + if (isMetric()) { String input = heightInput.getText().toString(); if (!input.isEmpty()) @@ -236,6 +278,20 @@ private Height getHeightFromInput() } } + private boolean isMetric() + { + boolean isMetric; + + if (heightUnitSelect != null) + { + isMetric = heightUnitSelect.getSelectedItem().equals("m"); + } else { + List measurementUnits = getCountryInfo().getMeasurementSystem(); + isMetric = measurementUnits.get(0).equals("metric"); + } + return isMetric; + } + private void confirmUnusualInput(final Runnable callback) { if(getActivity() == null) return; diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java index ad2bb5e648..ef1983760a 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/Height.java @@ -27,7 +27,7 @@ public enum Unit { this.unit = Unit.METRIC; } - Height(int feet, int inches) + public Height(int feet, int inches) { this.feet = feet; this.inches = inches; @@ -72,12 +72,7 @@ public double getInMeters() } else { - return feetToMeter(Double.parseDouble(feet + "." + inches)); + return ((feet * 12 + inches) * 0.0254); } } - - private static double feetToMeter(double feet) - { - return feet / 3.2808; - } } diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureCameraActivity.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureCameraActivity.java new file mode 100644 index 0000000000..241225f277 --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureCameraActivity.java @@ -0,0 +1,42 @@ +package de.westnordost.streetcomplete.quests.max_height.measure; + +import android.app.Activity; +import android.content.Intent; +import android.view.Menu; + +import de.westnordost.streetcomplete.FragmentContainerActivity; +import de.westnordost.streetcomplete.R; + +public class MeasureCameraActivity extends FragmentContainerActivity implements MeasureListener +{ + public static final String + UNIT = "unit", + METERS = "meters", + FEET = "feet", + INCHES = "inches"; + + @Override public void onMeasured(String meters) + { + Intent intent = new Intent(); + intent.putExtra(UNIT, METERS); + intent.putExtra(METERS, meters); + setResult(Activity.RESULT_OK, intent); + finish(); + } + + @Override public void onMeasured(String feet, String inches) + { + Intent intent = new Intent(); + intent.putExtra(UNIT, FEET); + intent.putExtra(FEET, feet); + intent.putExtra(INCHES, inches); + setResult(Activity.RESULT_OK, intent); + finish(); + } + + @Override public boolean onCreateOptionsMenu(Menu menu) + { + getMenuInflater().inflate(R.menu.menu_height_measure_camera, menu); + return true; + } +} diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureCameraFragment.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureCameraFragment.java new file mode 100644 index 0000000000..c4f0e3f3ca --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureCameraFragment.java @@ -0,0 +1,527 @@ +package de.westnordost.streetcomplete.quests.max_height.measure; + +import android.Manifest; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.hardware.Camera; +import android.hardware.Sensor; +import android.hardware.SensorManager; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.content.ContextCompat; +import android.text.InputFilter; +import android.text.InputType; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.Toast; + +import com.github.florent37.viewtooltip.ViewTooltip; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.List; +import java.util.Locale; + +import javax.inject.Inject; + +import de.westnordost.streetcomplete.Injector; +import de.westnordost.streetcomplete.Prefs; +import de.westnordost.streetcomplete.R; +import de.westnordost.streetcomplete.quests.max_height.Height; +import de.westnordost.streetcomplete.view.dialogs.AlertDialogBuilder; + +public class MeasureCameraFragment extends Fragment +{ + private SensorManager sensorManager; + private SensorListener sensorEventListener; + + @Inject SharedPreferences prefs; + + private Camera camera; + private FrameLayout cameraView; + + private Button markBottom, markTop; + + public static final int REQUEST_PERMISSIONS_CAMERA = 123; + public static final String IS_METRIC = "is_metric"; + + private boolean isMetric; + + private MeasureUtils utils = new MeasureUtils(); + private MeasureListener listener; + + public void setListener(MeasureListener listener) + { + this.listener = listener; + } + + @Override public void onCreate(@Nullable Bundle inState) + { + super.onCreate(inState); + Injector.instance.getApplicationComponent().inject(this); + } + + @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) + { + super.onCreateView(inflater, container, savedInstanceState); + + setHasOptionsMenu(true); + + View contentView = inflater.inflate(R.layout.height_measure_camera, container, false); + + if (getArguments() != null) + { + isMetric = getArguments().getBoolean(IS_METRIC, true); + } + + sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE); + sensorEventListener = new SensorListener(); + + cameraView = contentView.findViewById(R.id.camera_preview); + + markBottom = contentView.findViewById(R.id.button_mark_bottom); + markTop = contentView.findViewById(R.id.button_mark_top); + + markBottom.setOnClickListener((v) -> + { + sensorEventListener.updateOrientationAngles(); + utils.setBottomAngle(Math.abs(sensorEventListener.getPitch())); + + markBottom.setVisibility(View.GONE); + markTop.setVisibility(View.VISIBLE); + + showTopTooltip(); + }); + + markTop.setOnClickListener((v) -> + { + sensorEventListener.updateOrientationAngles(); + + float topAngle = Math.abs(sensorEventListener.getPitch()); + float quadrant = sensorEventListener.getPitchQuadrantUpDown(); + topAngle = topAngle * (Math.signum(quadrant)); + utils.setTopAngle(topAngle); + + if (utils.getUserHeight() != -1) + { + parseResult(utils.getHeight()); + } else { + setUserHeight(true); + } + + markBottom.setVisibility(View.VISIBLE); + markTop.setVisibility(View.GONE); + }); + + if (!prefs.contains(Prefs.USER_HEIGHT)) + { + setUserHeight(false); + } else { + utils.setUserHeight(prefs.getInt(Prefs.USER_HEIGHT, 160)); + } + + int hintTimesShown = prefs.getInt(Prefs.HEIGHT_MEASURE_HINT_TIMES_SHOWN, 0); + if (hintTimesShown < 2) + { + showHelpDialog(); + prefs.edit().putInt(Prefs.HEIGHT_MEASURE_HINT_TIMES_SHOWN, hintTimesShown + 1).apply(); + } + + checkCameraPermission(); + + return contentView; + } + + private void checkCameraPermission() + { + if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) + { + startCamera(); + } else { + requestPermissions( + new String[]{Manifest.permission.CAMERA}, + REQUEST_PERMISSIONS_CAMERA + ); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) + { + if (requestCode == REQUEST_PERMISSIONS_CAMERA) + { + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) + { + startCamera(); + } else { + getActivity().finish(); + } + } else { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + } + + private void startCamera() + { + int cameraId = findCamera(); + if (cameraId < 0) + { + Toast.makeText(getContext(), R.string.no_camera_found, Toast.LENGTH_LONG).show(); + getActivity().finish(); + } else { + camera = getCameraInstance(cameraId); + if (camera != null) + { + cameraView.addView(new CameraPreview(getContext(), camera)); + } + } + } + + private Camera getCameraInstance(int id) + { + Camera c = null; + try { + c = Camera.open(id); + } + catch (Exception e){ + // Camera is not available (in use or does not exist) + new AlertDialogBuilder(getActivity()) + .setMessage(R.string.camera_not_available_error) + .setNegativeButton(android.R.string.no, (d, w) -> { + getActivity().finish(); + }) + .show(); + } + return c; + } + + private int findCamera() + { + int cameraId = -1; + int numberOfCameras = Camera.getNumberOfCameras(); + for (int i = 0; i < numberOfCameras; i++) + { + Camera.CameraInfo info = new Camera.CameraInfo(); + Camera.getCameraInfo(i, info); + if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) + { + cameraId = i; + break; + } + } + return cameraId; + } + + private void parseResult(float result) + { + //always use UK as the default locale to avoid values with a comma as a decimal separator + DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.UK); + String meter = new DecimalFormat("#.##", symbols).format(result); + + if (isMetric) + { + confirmResult(meter); + } else { + double inches = Double.parseDouble(meter) / 0.0254; + + String feet = new DecimalFormat("##").format(inches / 12); + String leftover = new DecimalFormat("##").format(inches % 12); + + String finalHeight = new Height(Integer.parseInt(feet), Integer.parseInt(leftover)).toString(); + confirmResult(finalHeight, feet, leftover); + } + } + + private void setUserHeight(boolean continueCalculation) + { + final EditText input = new EditText(getContext()); + input.setInputType(InputType.TYPE_CLASS_NUMBER); + input.setFilters(new InputFilter[] {new InputFilter.LengthFilter(3)}); + if (prefs.contains(Prefs.USER_HEIGHT)) + { + input.setText(String.valueOf(prefs.getInt(Prefs.USER_HEIGHT, 0))); + } + + /*TODO: is it better to ask for the height of the user and subtract 20 centimeter afterwards + or should we ask the user for the height he's holding the phone at? (like done right now) + The first option would be easier because everybody knows his own height, + but the subtraction might be inaccurate because some hold their phones higher and some lower... + The problem of the second option is that the height will probably be only some kind of guess too, + because I can't imagine that every user checks the height he's holding the phone at before answering the question + */ + + new AlertDialogBuilder(getActivity()) + .setMessage(R.string.input_user_height) + .setView(input) + .setCancelable(false) + .setOnCancelListener((d) -> { + getActivity().finish(); + }) + .setPositiveButton(android.R.string.ok, (d, w) -> + { + if (!input.getText().toString().isEmpty()) + { + int height = Integer.parseInt(input.getText().toString()); + utils.setUserHeight(height); + prefs.edit().putInt(Prefs.USER_HEIGHT, height).apply(); + + if (continueCalculation) + { + parseResult(utils.getHeight()); + } + } else { + Toast.makeText(getContext(), R.string.quest_generic_error_field_empty, Toast.LENGTH_LONG).show(); + } + }) + .show(); + } + + private void confirmResult(String result) + { + confirmResult(result, null, null); + } + + private void confirmResult(String result, String feet, String inches) + { + new AlertDialogBuilder(getActivity()) + .setMessage(String.format(getActivity().getResources().getString(R.string.confirmation_measured_height), result)) + .setNegativeButton(android.R.string.no, (d, w) -> { + d.dismiss(); + }) + .setPositiveButton(android.R.string.ok, (d, w) -> + { + if (isMetric) + { + listener.onMeasured(result); + } else { + listener.onMeasured(feet, inches); + } + }) + .show(); + } + + private void showHelpDialog() + { + new AlertDialogBuilder(getActivity()) + .setView(R.layout.height_measure_help) + .setPositiveButton(android.R.string.ok, (d, w) -> showBottomTooltip()) + .show(); + } + + private void showBottomTooltip() + { + int tooltipBottomTimesShown = prefs.getInt(Prefs.MEASURE_HINT_MARK_BOTTOM_TIMES_SHOWN, 0); + if (tooltipBottomTimesShown < 2) + { + ViewTooltip.on(markBottom) + .position(ViewTooltip.Position.TOP) + .text(getResources().getString(R.string.measure_mark_bottom_hint)) + .color(getResources().getColor(R.color.colorTooltip)) + .duration(6000) + .show(); + prefs.edit().putInt(Prefs.MEASURE_HINT_MARK_BOTTOM_TIMES_SHOWN, tooltipBottomTimesShown + 1).apply(); + } + } + + private void showTopTooltip() + { + int tooltipTopTimesShown = prefs.getInt(Prefs.MEASURE_HINT_MARK_TOP_TIMES_SHOWN, 0); + if (tooltipTopTimesShown < 2) + { + ViewTooltip.on(markTop) + .position(ViewTooltip.Position.TOP) + .text(getResources().getString(R.string.measure_mark_top_hint)) + .color(getResources().getColor(R.color.colorTooltip)) + .duration(6000) + .show(); + prefs.edit().putInt(Prefs.MEASURE_HINT_MARK_TOP_TIMES_SHOWN, tooltipTopTimesShown + 1).apply(); + } + } + + @Override public boolean onOptionsItemSelected(MenuItem item) + { + int id = item.getItemId(); + + switch (id) + { + case R.id.action_help: + showHelpDialog(); + return true; + case R.id.action_settings: + setUserHeight(false); + return true; + } + + return super.onOptionsItemSelected(item); + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + try { + listener = (MeasureListener) context; + } catch (ClassCastException e) { + throw new ClassCastException(context.toString() + " must implement OnHeadlineSelectedListener"); + } + } + + @Override + public void onDetach() { + super.onDetach(); + listener = null; + } + + @Override + public void onResume() + { + super.onResume(); + + if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) + { + startCamera(); + } + + sensorManager.registerListener( + sensorEventListener, + sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), + SensorManager.SENSOR_DELAY_NORMAL + ); + sensorManager.registerListener( + sensorEventListener, + sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), + SensorManager.SENSOR_DELAY_NORMAL + ); + } + + @Override + public void onPause() + { + super.onPause(); + + if (camera != null) { + camera.release(); + camera = null; + } + + sensorManager.unregisterListener(sensorEventListener); + } + + public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { + + private SurfaceHolder holder; + private Camera camera; + + private List supportedPreviewSizes; + private Camera.Size previewSize; + + public CameraPreview(Context context, Camera camera) { + super(context); + + this.camera = camera; + holder = getHolder(); + holder.addCallback(this); + + supportedPreviewSizes = camera.getParameters().getSupportedPreviewSizes(); + } + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + + if (holder.getSurface() == null){ + return; + } + + try { + camera.stopPreview(); + } catch (Exception e){ + // ignore: tried to stop a non-existent preview + } + + try { + Camera.Parameters parameters = camera.getParameters(); + parameters.setPreviewSize(previewSize.width, previewSize.height); + + camera.setParameters(parameters); + camera.setDisplayOrientation(90); + camera.setPreviewDisplay(holder); + camera.startPreview(); + } catch (Exception e){ + Log.d("MeasureCameraFragment", "Error starting camera preview: " + e.getMessage()); + } + } + + public void surfaceCreated(SurfaceHolder holder) + { + try { + camera.reconnect(); + camera.setPreviewDisplay(holder); + camera.startPreview(); + } catch (IOException e) { + Log.d("MeasureCameraFragment", "Error setting camera preview: " + e.getMessage()); + } + } + + public void surfaceDestroyed(SurfaceHolder holder) {} + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) + { + final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); + final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); + setMeasuredDimension(width, height); + + if (supportedPreviewSizes != null) + { + previewSize = getOptimalPreviewSize(supportedPreviewSizes, width, height); + } + } + + private Camera.Size getOptimalPreviewSize(List sizes, int w, int h) + { + final double ASPECT_TOLERANCE = 0.1; + double targetRatio=(double)h / w; + + if (sizes == null) return null; + + Camera.Size optimalSize = null; + double minDiff = Double.MAX_VALUE; + + for (Camera.Size size : sizes) + { + double ratio = (double) size.width / size.height; + if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; + if (Math.abs(size.height - h) < minDiff) + { + optimalSize = size; + minDiff = Math.abs(size.height - h); + } + } + + if (optimalSize == null) + { + minDiff = Double.MAX_VALUE; + for (Camera.Size size : sizes) + { + if (Math.abs(size.height - h) < minDiff) + { + optimalSize = size; + minDiff = Math.abs(size.height - h); + } + } + } + return optimalSize; + } + } +} diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureListener.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureListener.java new file mode 100644 index 0000000000..8aa91fff16 --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureListener.java @@ -0,0 +1,7 @@ +package de.westnordost.streetcomplete.quests.max_height.measure; + +public interface MeasureListener +{ + void onMeasured(String meters); + void onMeasured(String feet, String inches); +} diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureUtils.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureUtils.java new file mode 100644 index 0000000000..433f7d18ef --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/MeasureUtils.java @@ -0,0 +1,48 @@ +package de.westnordost.streetcomplete.quests.max_height.measure; + +public class MeasureUtils +{ + private float bottomAngle; + private float topAngle; + + private int userHeight = -1; + + public void setBottomAngle(float angle) + { + bottomAngle = angle; + } + + public void setTopAngle(float angle) + { + topAngle = angle; + } + + public void setUserHeight(int height) + { + userHeight = height; + } + + public int getUserHeight() + { + return userHeight; + } + + private double getDistance(float cameraHeight) + { + return cameraHeight * Math.tan(bottomAngle); + } + + public float getHeight() + { + float cameraHeight = userHeight / 100f; + double distance = getDistance(cameraHeight); + + double angle = Math.PI/2.0 - Math.abs(topAngle); + double height = distance * Math.tan(angle); + + float result = cameraHeight + (float) height * (-1)/Math.signum(topAngle); + + //return the absolute height because the user might have marked the top of the object before the bottom + return Math.abs(result); + } +} diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/SensorListener.java b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/SensorListener.java new file mode 100644 index 0000000000..8766a6160e --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/max_height/measure/SensorListener.java @@ -0,0 +1,48 @@ +package de.westnordost.streetcomplete.quests.max_height.measure; + +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; + +public class SensorListener implements SensorEventListener +{ + + private final float[] accelerometerReading = new float[3]; + private final float[] magnetometerReading = new float[3]; + + private final float[] rotationMatrix = new float[9]; + private final float[] orientationAngles = new float[3]; + + public float getPitch() + { + return orientationAngles[1]; + } + + public float getPitchQuadrantUpDown() + { + return rotationMatrix[8]; + } + + public void updateOrientationAngles() + { + SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerReading, magnetometerReading); + SensorManager.getOrientation(rotationMatrix, orientationAngles); + } + + @Override + public void onSensorChanged(SensorEvent event) + { + if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){ + System.arraycopy(event.values, 0, accelerometerReading,0, accelerometerReading.length); + } + else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { + System.arraycopy(event.values, 0, magnetometerReading,0, magnetometerReading.length); + } + } + + @Override + public void onAccuracyChanged(Sensor sensor, int i) { + updateOrientationAngles(); + } +} diff --git a/app/src/main/res/drawable/ic_help_white_24dp.xml b/app/src/main/res/drawable/ic_help_white_24dp.xml new file mode 100644 index 0000000000..5ec2577ae7 --- /dev/null +++ b/app/src/main/res/drawable/ic_help_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_settings_white_24dp.xml b/app/src/main/res/drawable/ic_settings_white_24dp.xml new file mode 100644 index 0000000000..79af3ab68c --- /dev/null +++ b/app/src/main/res/drawable/ic_settings_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/measure_height_help.xml b/app/src/main/res/drawable/measure_height_help.xml new file mode 100644 index 0000000000..bf263ff910 --- /dev/null +++ b/app/src/main/res/drawable/measure_height_help.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/height_measure_camera.xml b/app/src/main/res/layout/height_measure_camera.xml new file mode 100644 index 0000000000..75289f706a --- /dev/null +++ b/app/src/main/res/layout/height_measure_camera.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + +