From 1470428c10675d30e98830b0262ddd155bb978a4 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 16 Jan 2022 16:55:24 +0100 Subject: [PATCH 001/181] documentation for making a SC quest --- CONTRIBUTING.md | 2 + CONTRIBUTING_A_NEW_QUEST.md | 354 ++++++++++++++++++++++++++++++++++++ 2 files changed, 356 insertions(+) create mode 100644 CONTRIBUTING_A_NEW_QUEST.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 27a4a2e809..ae93ad9b28 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,6 +96,8 @@ In case you **don't have an idea of a quest?** Look [at the existing issues](htt Always remember to pay attention to [the quest guidelines](https://github.com/streetcomplete/StreetComplete/blob/master/QUEST_GUIDELINES.md) of StreetComplete! It also has tips for implementing a quest. +See [also far more detailed guide to making a new quest](CONTRIBUTING_A_NEW_QUEST.md). + ### Code style Inheritance and class hierarchy should be avoided if possible. It is preferable to extract shared code to helper file such as [KerbUtil.kt](app/src/main/java/de/westnordost/streetcomplete/osm/kerb/KerbUtil.kt). diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md new file mode 100644 index 0000000000..d81f286ad7 --- /dev/null +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -0,0 +1,354 @@ +For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#development.md). + +If you want to contribute code to the StreetComplete then making a new quest is one of the easiest programming tasks. Implementing quest with interface design matching an existing one is quite +simple. + +Contributions like that are highly welcomed and you would make mapping one more things in OSM much easier! + +Reading the text below is not necessary to create a new quest - basic method of duplicating existing ones and modifying may be sufficient. And people were creating new quests before this documentation existed. + +But this materials may help or be quicker than trying to explore how things work fully on your own. + +# What is not required + +- expert programming ability - you do not need to be an expert programmer to make contributions, basic programming abilities are sufficient to implement a quest similar to existing ones +- any Kotlin-specific or Android-specific knowledge - it is fine if you never did anything with Kotlin or Android +- any Github specific knowledge + +Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/new) if you are stuck despite this. + +# Required + +- programming ability - it is not a good first task for someone who never programmed anything. + - Setup of environment takes long + - Editing even the simplest quest requires edits to at least two different files + - Kotlin familiarity is not needed, but ability to adjust to a new syntax is needed + - It is expected that someone trying this can search for solution of a typical problems on encountering an error message +- familiarity with StreetComplete as an user - it is really recommended to be familiar with how StreetComplete works.Making hundreds of edits is not mandatory. But passing familiarity how surveying with StreetComplete works is needed. +- time - Android Studio setup is sadly complicated + - Multiple hours are typical, though most was spend on waiting for various downloads + - it is likely that setting up Android Studio will be more complex than writing the code +- basic ability to use git (but as mentioned, anything GitHub specific will be explained) +- GitHub account +- around 15GB of a free space + - initial setup will download half of the Internet while getting emulators and dependencies. This is typical. + +# Dependencies - initial setup + +- install necessary software (Android Studio and git) +- clone StreetComplete repository +- open StreetComplete in Android Studio +- [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also connect to real device via usb, this will not be later mentioned but can fully replace emulator) +- run StreetComple in emulator - to verify that everything was setup as required + +if you are doing it for the first time do not worry if there is some error to solve along way. This is typical for setting up Android development. See [CONTRIBUTING file](CONTRIBUTING.md#development) which has some links to info about the setup. + +# Invent a new quest + +## Own ideas +To [repeat](https://github.com/streetcomplete/StreetComplete/blob/master/CONTRIBUTING.md#developing-new-quests) from that documentation file: [**open an issue** discussing the quest](#suggesting-new-quests), before starting other work. This way it can be confirmed that such quest can be included. This can be skipped if you are [experienced](https://github.com/streetcomplete/StreetComplete/discussions/3450) StreetComplete contributor. + +## Existing proposals +You can also look at [quest proposals waiting for implementation](https://github.com/streetcomplete/StreetComplete/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+quest%22). + +# Learn from an existing code + +## Find a base +Base the new quest on one that exists already. + +Find one that hasthe same type of interface to the one that you are trying to implement. + +Are you trying to implement quest that will affect roads and paths? Take `AddWayLit` quest as a base if it will be yes/no question. `AddTracktype` where mapper will be selecting one of images. + +Is it going to be asked for POIs and be disabled by default? `AddWheelchairAccessBusiness` may be a good base. + +Quest are defined in [their own folder](app/src/main/java/de/westnordost/streetcomplete/quests). + + +### Locating quest + +Search across code for part of question or other text characteristic to this message. For example "What is the name of this place" + +You will find an XML file with entry looking like this: + +`"What is the name of this place? (%s)"` + +The code `quest_placeName_title_name` is string reference, used in code to alow translations. + +Search for this identifier in `*.kt` files, it should appear in the quest file [AddPlaceName](src/main/java/de/westnordost/streetcomplete/quests/place_name/AddPlaceName.kt). + +This method can be often used to locate relevant code. + +## Pull requests + +One of better ways to get around a codebase new to you is to look at recent accepted proposals to change code (pull requests). + +This is likely useful also here. + +Find some [recent one](https://github.com/streetcomplete/StreetComplete/pulls?q=is%3Apr+is%3Aclosed) adding a quest. + +You can look at what was changed to achieve the goal, where relevant code is located. How much coding was need to impotent something. And what kind of comments are typical, how long one needs to wait for mainteners and so on. + +This can be also used to locate relevant code, especially helpful if some change needs to be done in multiple files. + +# Copying + +Copy relevant quest folder. Some contain multiple quests, in such case case copy only what you need. + +Some quests are entirely defined in a single file, some have additional answer class, custom interface or utility classes. + +# Adjust copy + +After the quest is copied it is necessary to adjust it a bit. + +Change its class name and the file name to the new one. + +In copied code change package info (things like `package de.westnordost.streetcomplete.quests.defibrillator` at the top) to match the new folder containing the quest. + +# Add quest to the list of active ones + +Adjust [QuestModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.kt) file. It contains a big list of active quests, ordered by priority. Read [what governs their priority](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.kt#L138-L162) but do not worry too much, it can be later tweaked. + +Add your own quest to the list so that it will be loaded by the app. + +## Quest anatomy +See for example [simple yes/no quest asking whether AED is indoor or outdoor](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt). + + +TODO: maybe linking [app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt](app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt) would be better? And extend documentation there? + +### Element selection +elementFilter property defines nodes, way, relations which will be selected for a given quest. It is a element selection used by OsmFilterQuestType. + +``` +""" + nodes with + emergency = defibrillator + and access !~ private|no + and !indoor +""" +``` + +This query will be limited to nodes (`nodes with`), which fulfil some requirements. + +- `emergency = defibrillator` tag must be present +- `access` tag must not have values `private` or `no` to skip ones where mapper will be unable to survey (`!~ private|no` - to be more specific optionA|optionB is treated like `^optionA|optionB$` regexp) +- `indoor` key must not be present at all, to show only ones where this tag is still missing + +It is specified as a string, in syntax specific to StreetComplete. You can look around some quests to see how it works. If you are trying to implement a new quest and you got stuck here, [open a new issue](https://github.com/streetcomplete/StreetComplete/issues) to request a more thorough documentation here. + +### Properties + +#### commitMessage +`override val commitMessage = "Add whether defibrillator is inside building"` +message used as a changeset comment + +#### wikiLink +`override val wikiLink = "Key:indoor"` + +points to the OSM Wiki page most relevant to the given quest, typically it is an added key. In this case it is page about [indoor=* tagging](https://wiki.openstreetmap.org/wiki/Key:indoor). + +#### icon +`override val icon = R.drawable.ic_quest_defibrillator` +icon drawable, you can initially use any icon. + +Do not worry, submissions with placeholder icons are also welcomed! In many cases icon itself was not made by the PR author. + +More info about icon handling will be given later. + +#### questTypeAchievements +`override val questTypeAchievements = listOf(LIFESAVER)` + +In quest achievements list what is relevant to given quest, see full list of available ones in [AchievementsModule.kt](app/src/main/java/de/westnordost/streetcomplete/data/user/achievements/AchievementsModule.kt) + +#### getTitle +`override fun getTitle(tags: Map) = R.string.quest_is_defibrillator_inside_title` +` override fun createForm() = YesNoQuestAnswerFragment()` + +Get title is message displayed to user, code here passes [reference](https://developer.android.com/guide/topics/resources/string-resource) to string. You can change it to the new, not yet existing one and use built in tool to place text. + +Actual strings sit in [app/src/main/res/values/strings.xml](app/src/main/res/values/strings.xml) + +There are additional files with text, but text is translated with a completely separately mechanism and your changes will modify solely this one file, leaving other text files untouched. + +#### Form + +`override fun createForm() = YesNoQuestAnswerFragment()` + +Form defines interface used by mappers. + +In this case the simplest possible is used. + +But sometimes more complex ones are needed, see for example [AddBridgeStructure.kt](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/bridge_structure/AddBridgeStructure.kt) + +`override fun createForm() = AddBridgeStructureForm()` + + +With form defined in [AddBridgeStructureForm](app/src/main/java/de/westnordost/streetcomplete/quests/bridge_structure/AddBridgeStructureForm.kt) +### applyAnswerTo +``` + override fun applyAnswerTo(answer: Boolean, changes: StringMapChangesBuilder) { + changes.add("indoor", answer.toYesNo()) + } +``` + +This code is responsible for modifying `StringMapChangesBuilder` object (passed by reference). + +Actions may include (examples from various quests): + +- `changes.add("indoor", answer.toYesNo())` - adds a new tag, it must not be present already +- `changes.addOrModify("material", newMaterial)` - add a new tag if missing, override existing value if present +- `changes.modify("sport", values)` - modify existing tag, value must be present +- `changes.delete("amenity")` - remove key that must be present +- `changes.deleteIfExists("stile")` - remove key if present +- `changes.updateWithCheckDate("lit", answer.toYesNo())` - acts as `addOrModify` but will also update survey date and can be used in cases where tag value is not changing + +See other ones defined in [StringMapChangesBuilder.kt](de/westnordost/streetcomplete/data/osm/edits/update_tags/StringMapChangesBuilder.kt) + +### Extras + +Info listed above must be supplied by every quest. But there are also several optional fields. This specific qest has +``` + override fun getHighlightedElements(element: Element, getMapData: () -> MapDataWithGeometry) = + getMapData().filter("nodes with emergency = defibrillator") +``` + +which causes nearby `emergency = defibrillator` nodes to be shown (icons used are defined in [PinIcons.kt](app/src/main/java/de/westnordost/streetcomplete/map/PinIcons.kt)) + +See [also other optional properties](de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt). + +### Adding quest icon + +It is OK to submit quest without own icon, using any icon as a placeholder. + +But it would be even better to include also icon. + +Note that there are some not-yet-used graphics, created for some proposed or expected quests. Maybe there is no need to create icon at all! + +New icon can reuse content of [other quest icons](res/graphics/quest icons), it can be based on openly licensed graphics. See [attribution file](res/graphics/authors.txt) for what was used so far. + +Keep similar style to existing ones and app in general. Once the quest icon is ready: + +- save as "Plain svg" or clean SVG file from unnecessary cruft in other way, like using [svgo](https://github.com/svg/svgo) +- Put SVG into `[res/graphics/quest icons](res/graphics/quest icons)` folder + - SVG is a standard format editable in various software, unlike internal Android Studio xml that will be produced in the next step. +- Open Android Studio +- Right click on "app" folder in the Project tool window (top left) +- Select new → vector asset +- Select your svg file +- Name with `ic_quest_` prefix (something like `ic_quest_traffic_calming`), this will cause IDE to generate an XML file +- add entry in the [attribution file](res/graphics/authors.txt) +- modify `icon` property in the quest definition to use the new drawable +- Commit modified or created files +- Compile, test quest in the emulator + +The same method applies also to other vecot drawables, only they will be placed in other parts of [res/graphics/](res/graphics/) + +Inkscape is a typical tool to create and edit SVG files, it is a good, free, open-source so is available to all. + +# Test + +Obviously testing can be done also earlier. + +But before submitting it should be tested. + +Typically it is done using emulator. + +## Is quest listed? +Look at the quest list in settings - is your quest appearing there? If not - see [this step](#Add quest to the list of active ones). + +While you are there you can disable all quest except yours for an easier testing. + +## Element selection +Is it selected for expected elements? Is it not selected for some unwanted elements? Note that you can set location in emulator settings rather than scrolling within StreetComplete itself. + +## Quest form +Is quest form opening? Can you fill answer as expected? + +## Solving quest +Can you solve the quest? Is expected tagging being applied? + +You can look at logs for info what was applied or use undo menu from bottom-left. + +You can freely answer - as long as you are not logged in, nothing will be submitted. Even after logging in you can disable uploading answers. + +Is quest disappearing after being solved? + +# Open a pull request + +[Pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) is a submission of proposed changes to the source code. + +You can put into description of PR something like "fixes #1234" to [mark it as fixing this issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword). It can go into a commit message or PR description ([not its title](https://github.com/streetcomplete/StreetComplete/discussions/2917), it is a known GitHub bug). + +If you are stuck on something, need some help or guidance and you are willing and able to continue after solving the problem - you can open a pull request in an incomplete state and mention the blocker. + +You can see [already submitted pull requests](https://github.com/streetcomplete/StreetComplete/pulls?q=is%3Apr+) to see how this process works in practice. + +# Future + +After opening a pull request it will be reviewed and you will likely be asked to make some changes. This is normal and happens also with pull requests submitted by experienced contributors. + +Changes typically include improving code style, tweaking phrasing and quest settings. + +You are also welcome to help with reviewing other PRs - different people have different strength, there are active reviewers who help with code style, there are some native speakers of English, some with deep knowledge of OSM tagging schemes or deep knowledge how StreetComplete works. + +After the PR was finished it will be merged before the beta release of the next version. This way it can be additionally tested with a wider audience before release to all and translators can [translate text into other languages](CONTRIBUTING.md#translating-the-app). + +After full release it will reach entire StreetComplete audience who now will be able to more easily contribute to OpenStreetMap - thanks in advance for that! + +# Bad documentation is a bug + +Unclear documentation, including this one, is a bug. Feel free to either submit a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) with a fix or [open an issue](https://github.com/streetcomplete/StreetComplete/issues/new) describing your confusion. + +Note that not everything will be directly described. This documet is very intentionally not including step-by-step guide to install Android Studio, [linking](CONTRIBUTING.md#development) to an official docs. + +# More complexity +What was described above is attempt to cover all aspects of quest creation, without describing all complexity. + +This contains some additional info. + +## getTitle Parameters +In some cases quest will mention name and type of feature, for example in case of shops to make their identification possible. + +This requires preparing space in message for filling at runtime, + +And to add mechanism supplying this data. Here is [a typical code](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L102-L111) that will + +``` + override fun getTitle(tags: Map) = + if (hasFeatureName(tags)) + R.string.quest_wheelchairAccess_name_type_title + else + R.string.quest_wheelchairAccess_name_title + + override fun getTitleArgs(tags: Map, featureName: Lazy): Array { + val name = tags["name"] ?: tags["brand"] + return arrayOfNotNull(name, featureName.value) + } +``` + +- try to pass name, featureType (such as "greengrocer", translated to the proper language) +- if name is not tagged: brand and featureType +- or just featureType + +## Custom filters +It is possible to use far more complex filters when querying for eligible elements. + +Matches like `surface ~ earth|dirt|ground` are possible and are evaluated as `surface` is either of `earth`, `dirt`, `ground` + +`access !~ private|no` will be evaluated to `access` is neither `private` nor `no` + +Simple lists are [evaluated as sets](https://github.com/streetcomplete/StreetComplete/blob/2e812b9a3b5288983309a7edde6e8f9db05ad3f2/app/src/test/java/de/westnordost/streetcomplete/data/elementfilter/filters/ElementFilterOverpassKtTest.kt#L79-L88) - and for example `surface ~ earth|dirt|ground` will not match `surface=earther` tag. Basically, `surface ~ earth|dirt|ground` is treated as `surface ~ ^earth|dirt|ground$` + +But using regexp like `surface ~ ^(.*)[0-9]$` is [also possible](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/test/java/de/westnordost/streetcomplete/data/elementfilter/filters/ElementFilterOverpassKtTest.kt#L79-L88). + +It is possible to check for [age of elements](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/construction/MarkCompletedHighwayConstruction.kt#L13-L17) or implement a [fully custom tag parsing](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/opening_hours/AddOpeningHours.kt#L137-L151), still combined with filter syntax. + +It is possible to share and reuse [information about tagging schemes](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/surface/AddRoadSurface.kt#L18). + +(this info is gathered [here](/app/src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt)) + + +Even more complex ones using a different class bases are possible. Such as what was needed by the [address quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/address/AddAddressStreet.kt) or the [crossing quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/crossing/AddCrossing.kt) but it is better to start from something simpler. + +It allows to make a complex geometry checks, but writing them is also far more complex. \ No newline at end of file From bf104b2b22fd3a28e53650112d1301680c9f6103 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 17 Jan 2022 15:05:26 +0100 Subject: [PATCH 002/181] take content from Wiki --- CONTRIBUTING_A_NEW_QUEST.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index d81f286ad7..d9740887c5 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -137,6 +137,11 @@ This query will be limited to nodes (`nodes with`), which fulfil some requiremen It is specified as a string, in syntax specific to StreetComplete. You can look around some quests to see how it works. If you are trying to implement a new quest and you got stuck here, [open a new issue](https://github.com/streetcomplete/StreetComplete/issues) to request a more thorough documentation here. +#### Hints +The rules should be as exclusive as possible to generate as few false-positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. + +Also, for very detailed information that can be assumed to always have the same ("undefined") answer in many countries, it might be a good idea to limit quests to an inclusive list of certain countries. + ### Properties #### commitMessage @@ -331,6 +336,20 @@ And to add mechanism supplying this data. Here is [a typical code](https://githu - if name is not tagged: brand and featureType - or just featureType +## Designing the form + +## 3. Design the form + +As mentioned, the user interface must leave no space for misunderstandings, it must be concise and quick and easy to use. Also sounds obvious, but you will quickly find out that a balance must be found between covering all the edge cases and designing the form to be as straightforward and clutterless as possible. + +- Design the main form clutter-free so that it is straightforward for the majority of use cases. +- Make it not impossible to answer the edge cases (but don't clutter up the main form with that). A good pattern is to "ban" answering edge cases into the "Other answers..." menu. I.e. look at the opening hours quest. +- Don't rely on the "leave a note" fallback too much. It is not intended and does not work as a regular answer but is designed to cover the case that the question was invalid itself because it was based on wrong data like i.e. the place does not exist anymore. +- The information the user should fill in should be as atomic as possible. Users are impatient. I.e. do not let them fill out a whole address with street name etc. when just the house number is fine too. +- "A picture is worth a thousand words": Often the term for certain things may not be enough to convey the meaning of certain predefined answers. Do you know what a wheelbender is? You will know if you see the photo. + +Considerations about the edge cases to consider, how the design could look like and finding good representative photos or icons that match in style is also part of the preparational work that can be done without programming knowledge. + ## Custom filters It is possible to use far more complex filters when querying for eligible elements. From 4303099cddb134b09724182ebe98d891871337ba Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 17 Jan 2022 15:06:55 +0100 Subject: [PATCH 003/181] delete trash --- CONTRIBUTING_A_NEW_QUEST.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index d9740887c5..fea2888699 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -338,8 +338,6 @@ And to add mechanism supplying this data. Here is [a typical code](https://githu ## Designing the form -## 3. Design the form - As mentioned, the user interface must leave no space for misunderstandings, it must be concise and quick and easy to use. Also sounds obvious, but you will quickly find out that a balance must be found between covering all the edge cases and designing the form to be as straightforward and clutterless as possible. - Design the main form clutter-free so that it is straightforward for the majority of use cases. From c3eb317fef616d2ea375e030b2dc83658613811c Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 17 Jan 2022 15:07:05 +0100 Subject: [PATCH 004/181] describe making photos --- CONTRIBUTING_A_NEW_QUEST.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index fea2888699..04d46ab293 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -348,6 +348,32 @@ As mentioned, the user interface must leave no space for misunderstandings, it m Considerations about the edge cases to consider, how the design could look like and finding good representative photos or icons that match in style is also part of the preparational work that can be done without programming knowledge. +## New photos + +Some quest will require photos for their interface. + +Photo must be available on open license - so not every photo found across Internet is usable. You can either take own photo or find an existing freely licensed photo. + +Good places to find freely licensed images are [Geograph](https://www.geograph.org.uk/) and [Wikimedia Commons](https://commons.wikimedia.org/). + +You can also take own photos, standard smartphone camera is a good enough. And sometimes highly specific image is needed. + +In StreetComplete many images have unusual composition. Often it is necessary to leave space for label at the bottom. + +Images should be free of visual debris, not misleading. Though it is fine to use image not strictly matching what is depicted, as long as it is clear. For example [permanent pile of soil blocking road](https://wiki.openstreetmap.org/wiki/Tag:barrier%3Ddebris) is illustrated by a [temporary landslide](https://commons.wikimedia.org/wiki/File:Landslide_on_OR_42S_(46849629014).jpg). This is OK as images are illustrative. + +Photos go to a different folder than SVGs: they can be used directly by build process so put them into folders + - [mdpi](app/src/main/res/drawable-mdpi) (typically 128 x 128 pixels, for rectangular ones smaller dimension should be 128 pixels) + - [hdpi](app/src/main/res/drawable-hdpi) (typically 192 x 192 pixels, for rectangular ones smaller dimension should be 192 pixels) + - [xhdpi](app/src/main/res/drawable-xhdpi) (typically 256 x 256 pixels, for rectangular ones smaller dimension should be 256 pixels) + - [xxhdpi](app/src/main/res/drawable-xxhdpi) (typically 384 x 384 pixels, for rectangular ones smaller dimension should be 384 pixels) + +Each of this folders should hold the same image resized to a different resolution. While testing various images it is enough to put into one folder. + +The [rescaling script](https://github.com/matkoniecz/rescaling_for_android) may be useful, but you can also do this manually with Gimp or a similar software. + +After adding file remember to update [credit file](app/src/main/res/authors.txt) (different than one for icons). + ## Custom filters It is possible to use far more complex filters when querying for eligible elements. From ab2261cf43a8dcf5b769c10f71c68408a6de8965 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 17 Jan 2022 15:13:39 +0100 Subject: [PATCH 005/181] one more grammar pass, part 1 --- CONTRIBUTING_A_NEW_QUEST.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 04d46ab293..5bd5136776 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -1,13 +1,12 @@ For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#development.md). -If you want to contribute code to the StreetComplete then making a new quest is one of the easiest programming tasks. Implementing quest with interface design matching an existing one is quite -simple. +If you want to contribute code to the StreetComplete then making a new quest is one of the easiest programming tasks. Implementing a quest with interface design matching an existing one is quite simple. -Contributions like that are highly welcomed and you would make mapping one more things in OSM much easier! +Contributions like that are highly welcomed and you would make mapping one more thing in OSM much easier! -Reading the text below is not necessary to create a new quest - basic method of duplicating existing ones and modifying may be sufficient. And people were creating new quests before this documentation existed. +Reading the text below is not necessary to create a new quest - a basic method of duplicating existing ones and modifying may be sufficient. And people were creating new quests before this documentation existed. -But this materials may help or be quicker than trying to explore how things work fully on your own. +But these materials may help or be quicker than trying to explore how things work fully on your own. # What is not required @@ -22,16 +21,16 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - programming ability - it is not a good first task for someone who never programmed anything. - Setup of environment takes long - Editing even the simplest quest requires edits to at least two different files - - Kotlin familiarity is not needed, but ability to adjust to a new syntax is needed - - It is expected that someone trying this can search for solution of a typical problems on encountering an error message -- familiarity with StreetComplete as an user - it is really recommended to be familiar with how StreetComplete works.Making hundreds of edits is not mandatory. But passing familiarity how surveying with StreetComplete works is needed. + - Kotlin familiarity is not needed, but the ability to adjust to a new syntax is needed + - It is expected that someone trying this can search for a solution of a typical problems on encountering an error message +- familiarity with StreetComplete as a user - it is really recommended to be familiar with how StreetComplete works. Making hundreds of edits is not mandatory. But passing familiarity with how surveying with StreetComplete works is needed. - time - Android Studio setup is sadly complicated - - Multiple hours are typical, though most was spend on waiting for various downloads - - it is likely that setting up Android Studio will be more complex than writing the code + - Multiple hours are typical, though most spend on waiting for various downloads + - setting up Android Studio will likely be more complex than writing the code - basic ability to use git (but as mentioned, anything GitHub specific will be explained) - GitHub account - around 15GB of a free space - - initial setup will download half of the Internet while getting emulators and dependencies. This is typical. + - the initial setup will download half of the Internet while getting emulators and dependencies. This is typical. # Dependencies - initial setup From eb842b43750d53e4147fb44fd294cc6e42c4f64e Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 17 Jan 2022 15:19:14 +0100 Subject: [PATCH 006/181] one more grammar pass, part 2 --- CONTRIBUTING_A_NEW_QUEST.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 5bd5136776..2b157f2e03 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -37,15 +37,15 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - install necessary software (Android Studio and git) - clone StreetComplete repository - open StreetComplete in Android Studio -- [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also connect to real device via usb, this will not be later mentioned but can fully replace emulator) +- [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also connect to a real device via usb, this will not be later mentioned but can fully replace emulator) - run StreetComple in emulator - to verify that everything was setup as required -if you are doing it for the first time do not worry if there is some error to solve along way. This is typical for setting up Android development. See [CONTRIBUTING file](CONTRIBUTING.md#development) which has some links to info about the setup. +if you are doing it for the first time do not worry if there is some error to solve along the way. This is typical for setting up Android development. See [CONTRIBUTING file](CONTRIBUTING.md#development) which has some links to info about the setup. # Invent a new quest ## Own ideas -To [repeat](https://github.com/streetcomplete/StreetComplete/blob/master/CONTRIBUTING.md#developing-new-quests) from that documentation file: [**open an issue** discussing the quest](#suggesting-new-quests), before starting other work. This way it can be confirmed that such quest can be included. This can be skipped if you are [experienced](https://github.com/streetcomplete/StreetComplete/discussions/3450) StreetComplete contributor. +To [repeat](https://github.com/streetcomplete/StreetComplete/blob/master/CONTRIBUTING.md#developing-new-quests) from that documentation file: [**open an issue** discussing the quest](#suggesting-new-quests), before starting other work. This way it can be confirmed that such quest can be included. This can be skipped if you are an [experienced](https://github.com/streetcomplete/StreetComplete/discussions/3450) StreetComplete contributor. ## Existing proposals You can also look at [quest proposals waiting for implementation](https://github.com/streetcomplete/StreetComplete/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+quest%22). @@ -55,9 +55,9 @@ You can also look at [quest proposals waiting for implementation](https://github ## Find a base Base the new quest on one that exists already. -Find one that hasthe same type of interface to the one that you are trying to implement. +Find one that has the same type of interface as the one that you are trying to implement. -Are you trying to implement quest that will affect roads and paths? Take `AddWayLit` quest as a base if it will be yes/no question. `AddTracktype` where mapper will be selecting one of images. +Are you trying to implement a quest that will affect roads and paths? Take `AddWayLit` quest as a base if it will be a yes/no question. `AddTracktype` where the mapper will be selecting one of the images. Is it going to be asked for POIs and be disabled by default? `AddWheelchairAccessBusiness` may be a good base. @@ -66,7 +66,7 @@ Quest are defined in [their own folder](app/src/main/java/de/westnordost/streetc ### Locating quest -Search across code for part of question or other text characteristic to this message. For example "What is the name of this place" +Search across code for part of a question or other text characteristic to this message. For example "What is the name of this place" You will find an XML file with entry looking like this: @@ -80,19 +80,19 @@ This method can be often used to locate relevant code. ## Pull requests -One of better ways to get around a codebase new to you is to look at recent accepted proposals to change code (pull requests). +One of the better ways to get around a codebase new to you is to look at recent accepted proposals to change code (pull requests). This is likely useful also here. -Find some [recent one](https://github.com/streetcomplete/StreetComplete/pulls?q=is%3Apr+is%3Aclosed) adding a quest. +Find some [recent ones](https://github.com/streetcomplete/StreetComplete/pulls?q=is%3Apr+is%3Aclosed) adding a quest. -You can look at what was changed to achieve the goal, where relevant code is located. How much coding was need to impotent something. And what kind of comments are typical, how long one needs to wait for mainteners and so on. +You can look at what was changed to achieve the goal, where relevant code is located. How much coding was needed to implement something. And what kind of comments are typical, how long one needs to wait for maintainers and so on. This can be also used to locate relevant code, especially helpful if some change needs to be done in multiple files. # Copying -Copy relevant quest folder. Some contain multiple quests, in such case case copy only what you need. +Copy relevant quest folder. Some contain multiple quests, in such case copy only what you need. Some quests are entirely defined in a single file, some have additional answer class, custom interface or utility classes. @@ -108,7 +108,7 @@ In copied code change package info (things like `package de.westnordost.streetco Adjust [QuestModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.kt) file. It contains a big list of active quests, ordered by priority. Read [what governs their priority](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.kt#L138-L162) but do not worry too much, it can be later tweaked. -Add your own quest to the list so that it will be loaded by the app. +Add your quest to the list so that it will be loaded by the app. ## Quest anatomy See for example [simple yes/no quest asking whether AED is indoor or outdoor](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt). @@ -117,7 +117,7 @@ See for example [simple yes/no quest asking whether AED is indoor or outdoor](ap TODO: maybe linking [app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt](app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt) would be better? And extend documentation there? ### Element selection -elementFilter property defines nodes, way, relations which will be selected for a given quest. It is a element selection used by OsmFilterQuestType. +elementFilter property defines nodes, ways and relations which will be selected for a given quest. It is an element selection used by OsmFilterQuestType. ``` """ @@ -134,10 +134,10 @@ This query will be limited to nodes (`nodes with`), which fulfil some requiremen - `access` tag must not have values `private` or `no` to skip ones where mapper will be unable to survey (`!~ private|no` - to be more specific optionA|optionB is treated like `^optionA|optionB$` regexp) - `indoor` key must not be present at all, to show only ones where this tag is still missing -It is specified as a string, in syntax specific to StreetComplete. You can look around some quests to see how it works. If you are trying to implement a new quest and you got stuck here, [open a new issue](https://github.com/streetcomplete/StreetComplete/issues) to request a more thorough documentation here. +It is specified as a string, in syntax specific to StreetComplete. You can look around some quests to see how it works. If you are trying to implement a new quest and you got stuck here, [open a new issue](https://github.com/streetcomplete/StreetComplete/issues) to request more thorough documentation here. #### Hints -The rules should be as exclusive as possible to generate as few false-positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. +The rules should be as exclusive as possible to generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. Also, for very detailed information that can be assumed to always have the same ("undefined") answer in many countries, it might be a good idea to limit quests to an inclusive list of certain countries. @@ -150,7 +150,7 @@ message used as a changeset comment #### wikiLink `override val wikiLink = "Key:indoor"` -points to the OSM Wiki page most relevant to the given quest, typically it is an added key. In this case it is page about [indoor=* tagging](https://wiki.openstreetmap.org/wiki/Key:indoor). +points to the OSM Wiki page most relevant to the given quest, typically it is an added key. In this case, it is a page about [indoor=* tagging](https://wiki.openstreetmap.org/wiki/Key:indoor). #### icon `override val icon = R.drawable.ic_quest_defibrillator` From a8418812e05d5ae51dcf67d51c60b6c98169cc44 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 17 Jan 2022 15:52:13 +0100 Subject: [PATCH 007/181] one more grammar pass, part 3 --- CONTRIBUTING_A_NEW_QUEST.md | 72 ++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 2b157f2e03..21409db31e 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -4,7 +4,7 @@ If you want to contribute code to the StreetComplete then making a new quest is Contributions like that are highly welcomed and you would make mapping one more thing in OSM much easier! -Reading the text below is not necessary to create a new quest - a basic method of duplicating existing ones and modifying may be sufficient. And people were creating new quests before this documentation existed. +Reading the text below is not necessary to create a new quest - a basic method of duplicating existing ones and modifying them may be sufficient. And people were creating new quests before this documentation existed. But these materials may help or be quicker than trying to explore how things work fully on your own. @@ -22,7 +22,7 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - Setup of environment takes long - Editing even the simplest quest requires edits to at least two different files - Kotlin familiarity is not needed, but the ability to adjust to a new syntax is needed - - It is expected that someone trying this can search for a solution of a typical problems on encountering an error message + - It is expected that someone trying this can search for a solution to a typical problems on encountering an error message - familiarity with StreetComplete as a user - it is really recommended to be familiar with how StreetComplete works. Making hundreds of edits is not mandatory. But passing familiarity with how surveying with StreetComplete works is needed. - time - Android Studio setup is sadly complicated - Multiple hours are typical, though most spend on waiting for various downloads @@ -37,7 +37,7 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - install necessary software (Android Studio and git) - clone StreetComplete repository - open StreetComplete in Android Studio -- [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also connect to a real device via usb, this will not be later mentioned but can fully replace emulator) +- [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also connect to a real device via usb, this will not be later mentioned but can fully replace the emulator) - run StreetComple in emulator - to verify that everything was setup as required if you are doing it for the first time do not worry if there is some error to solve along the way. This is typical for setting up Android development. See [CONTRIBUTING file](CONTRIBUTING.md#development) which has some links to info about the setup. @@ -163,17 +163,17 @@ More info about icon handling will be given later. #### questTypeAchievements `override val questTypeAchievements = listOf(LIFESAVER)` -In quest achievements list what is relevant to given quest, see full list of available ones in [AchievementsModule.kt](app/src/main/java/de/westnordost/streetcomplete/data/user/achievements/AchievementsModule.kt) +In quest achievements list what is relevant to given quest, see the full list of available ones in [AchievementsModule.kt](app/src/main/java/de/westnordost/streetcomplete/data/user/achievements/AchievementsModule.kt) #### getTitle `override fun getTitle(tags: Map) = R.string.quest_is_defibrillator_inside_title` ` override fun createForm() = YesNoQuestAnswerFragment()` -Get title is message displayed to user, code here passes [reference](https://developer.android.com/guide/topics/resources/string-resource) to string. You can change it to the new, not yet existing one and use built in tool to place text. +It is a message displayed to user, code here passes a [reference](https://developer.android.com/guide/topics/resources/string-resource) to the string. You can change it to the new, not yet existing one and use a built in tool to place text. Actual strings sit in [app/src/main/res/values/strings.xml](app/src/main/res/values/strings.xml) -There are additional files with text, but text is translated with a completely separately mechanism and your changes will modify solely this one file, leaving other text files untouched. +There are additional files with text, but the text is translated with a completely separately worflow and your changes will modify solely this one file, leaving other text files untouched. #### Form @@ -181,7 +181,7 @@ There are additional files with text, but text is translated with a completely s Form defines interface used by mappers. -In this case the simplest possible is used. +In this case, the simplest possible is used. But sometimes more complex ones are needed, see for example [AddBridgeStructure.kt](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/bridge_structure/AddBridgeStructure.kt) @@ -223,17 +223,17 @@ See [also other optional properties](de/westnordost/streetcomplete/data/osm/osmq ### Adding quest icon -It is OK to submit quest without own icon, using any icon as a placeholder. +It is OK to submit a quest without own icon, using any icon as a placeholder. But it would be even better to include also icon. Note that there are some not-yet-used graphics, created for some proposed or expected quests. Maybe there is no need to create icon at all! -New icon can reuse content of [other quest icons](res/graphics/quest icons), it can be based on openly licensed graphics. See [attribution file](res/graphics/authors.txt) for what was used so far. +A new icon can reuse the content of [other quest icons](res/graphics/quest icons), it can be based on openly licensed graphics. See [the attribution file](res/graphics/authors.txt) for what was used so far. Keep similar style to existing ones and app in general. Once the quest icon is ready: -- save as "Plain svg" or clean SVG file from unnecessary cruft in other way, like using [svgo](https://github.com/svg/svgo) +- save as "Plain svg" or clean SVG file from unnecessary cruft in another way, like using [svgo](https://github.com/svg/svgo) - Put SVG into `[res/graphics/quest icons](res/graphics/quest icons)` folder - SVG is a standard format editable in various software, unlike internal Android Studio xml that will be produced in the next step. - Open Android Studio @@ -241,27 +241,27 @@ Keep similar style to existing ones and app in general. Once the quest icon is r - Select new → vector asset - Select your svg file - Name with `ic_quest_` prefix (something like `ic_quest_traffic_calming`), this will cause IDE to generate an XML file -- add entry in the [attribution file](res/graphics/authors.txt) +- add an entry in the [attribution file](res/graphics/authors.txt) - modify `icon` property in the quest definition to use the new drawable - Commit modified or created files - Compile, test quest in the emulator -The same method applies also to other vecot drawables, only they will be placed in other parts of [res/graphics/](res/graphics/) +The same method applies also to other vector drawables, only they will be placed in other parts of [res/graphics/](res/graphics/) Inkscape is a typical tool to create and edit SVG files, it is a good, free, open-source so is available to all. # Test -Obviously testing can be done also earlier. +Obviously, testing can be done also earlier. But before submitting it should be tested. -Typically it is done using emulator. +Typically it is done using an emulator. ## Is quest listed? Look at the quest list in settings - is your quest appearing there? If not - see [this step](#Add quest to the list of active ones). -While you are there you can disable all quest except yours for an easier testing. +While you are there you can disable all quests except yours for an easier testing. ## Element selection Is it selected for expected elements? Is it not selected for some unwanted elements? Note that you can set location in emulator settings rather than scrolling within StreetComplete itself. @@ -282,7 +282,7 @@ Is quest disappearing after being solved? [Pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) is a submission of proposed changes to the source code. -You can put into description of PR something like "fixes #1234" to [mark it as fixing this issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword). It can go into a commit message or PR description ([not its title](https://github.com/streetcomplete/StreetComplete/discussions/2917), it is a known GitHub bug). +You can put into the description of PR something like "fixes #1234" to [mark it as fixing this issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword). It can go into a commit message or PR description ([not its title](https://github.com/streetcomplete/StreetComplete/discussions/2917), it is a known GitHub bug). If you are stuck on something, need some help or guidance and you are willing and able to continue after solving the problem - you can open a pull request in an incomplete state and mention the blocker. @@ -294,25 +294,25 @@ After opening a pull request it will be reviewed and you will likely be asked to Changes typically include improving code style, tweaking phrasing and quest settings. -You are also welcome to help with reviewing other PRs - different people have different strength, there are active reviewers who help with code style, there are some native speakers of English, some with deep knowledge of OSM tagging schemes or deep knowledge how StreetComplete works. +You are also welcome to help with reviewing other PRs - different people have different strengths, there are active reviewers who help with code style, there are some native speakers of English, some with deep knowledge of OSM tagging schemes or deep knowledge of how StreetComplete works. After the PR was finished it will be merged before the beta release of the next version. This way it can be additionally tested with a wider audience before release to all and translators can [translate text into other languages](CONTRIBUTING.md#translating-the-app). -After full release it will reach entire StreetComplete audience who now will be able to more easily contribute to OpenStreetMap - thanks in advance for that! +After full release it will reach the entire StreetComplete audience who now will be able to more easily contribute to OpenStreetMap. Thanks in advance for that! # Bad documentation is a bug Unclear documentation, including this one, is a bug. Feel free to either submit a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) with a fix or [open an issue](https://github.com/streetcomplete/StreetComplete/issues/new) describing your confusion. -Note that not everything will be directly described. This documet is very intentionally not including step-by-step guide to install Android Studio, [linking](CONTRIBUTING.md#development) to an official docs. +Note that not everything will be directly described. This document is very intentionally not including step-by-step guide to install Android Studio, [linking](CONTRIBUTING.md#development) to an official docs. # More complexity -What was described above is attempt to cover all aspects of quest creation, without describing all complexity. +What was described above is an attempt to cover all aspects of quest creation, without describing all complexity. This contains some additional info. ## getTitle Parameters -In some cases quest will mention name and type of feature, for example in case of shops to make their identification possible. +In some cases, quest will mention the name and type of feature. For example, in case of shops to make their identification possible. This requires preparing space in message for filling at runtime, @@ -331,9 +331,9 @@ And to add mechanism supplying this data. Here is [a typical code](https://githu } ``` -- try to pass name, featureType (such as "greengrocer", translated to the proper language) -- if name is not tagged: brand and featureType -- or just featureType +- try to pass name, feature type (such as "greengrocer", translated to the proper language) +- if name is not tagged: brand and feature type +- or just feature type ## Designing the form @@ -349,19 +349,19 @@ Considerations about the edge cases to consider, how the design could look like ## New photos -Some quest will require photos for their interface. +Some quests will require photos for their interface. -Photo must be available on open license - so not every photo found across Internet is usable. You can either take own photo or find an existing freely licensed photo. +Photo must be available on open license - so not every photo found across the Internet is usable. You can either take own photo or find an existing freely licensed photo. Good places to find freely licensed images are [Geograph](https://www.geograph.org.uk/) and [Wikimedia Commons](https://commons.wikimedia.org/). -You can also take own photos, standard smartphone camera is a good enough. And sometimes highly specific image is needed. +You can also take your own photos, a standard smartphone camera is good enough. And sometimes a highly specific image is needed. -In StreetComplete many images have unusual composition. Often it is necessary to leave space for label at the bottom. +In StreetComplete many images have unusual composition. Often it is necessary to leave space for a label at the bottom. -Images should be free of visual debris, not misleading. Though it is fine to use image not strictly matching what is depicted, as long as it is clear. For example [permanent pile of soil blocking road](https://wiki.openstreetmap.org/wiki/Tag:barrier%3Ddebris) is illustrated by a [temporary landslide](https://commons.wikimedia.org/wiki/File:Landslide_on_OR_42S_(46849629014).jpg). This is OK as images are illustrative. +Images should be free of visual debris, not misleading. Though it is fine to use an image not strictly matching what is depicted, as long as it is clear. For example, [a permanent pile of soil blocking road](https://wiki.openstreetmap.org/wiki/Tag:barrier%3Ddebris) is illustrated by a [temporary landslide](https://commons.wikimedia.org/wiki/File:Landslide_on_OR_42S_(46849629014).jpg). This is OK as images are illustrative. -Photos go to a different folder than SVGs: they can be used directly by build process so put them into folders +Photos go to a different folder than SVGs: they can be used directly by the build process so put them into folders - [mdpi](app/src/main/res/drawable-mdpi) (typically 128 x 128 pixels, for rectangular ones smaller dimension should be 128 pixels) - [hdpi](app/src/main/res/drawable-hdpi) (typically 192 x 192 pixels, for rectangular ones smaller dimension should be 192 pixels) - [xhdpi](app/src/main/res/drawable-xhdpi) (typically 256 x 256 pixels, for rectangular ones smaller dimension should be 256 pixels) @@ -369,16 +369,16 @@ Photos go to a different folder than SVGs: they can be used directly by build pr Each of this folders should hold the same image resized to a different resolution. While testing various images it is enough to put into one folder. -The [rescaling script](https://github.com/matkoniecz/rescaling_for_android) may be useful, but you can also do this manually with Gimp or a similar software. +The [rescaling script](https://github.com/matkoniecz/rescaling_for_android) may be useful, but you can also do this manually with Gimp or similar software. -After adding file remember to update [credit file](app/src/main/res/authors.txt) (different than one for icons). +After adding a file remember to update [the credit file](app/src/main/res/authors.txt) (different than one for icons). ## Custom filters It is possible to use far more complex filters when querying for eligible elements. -Matches like `surface ~ earth|dirt|ground` are possible and are evaluated as `surface` is either of `earth`, `dirt`, `ground` +Matches like `surface ~ earth|dirt|ground` are possible and are evaluated as "`surface` is either of `earth`, `dirt`, `ground`" -`access !~ private|no` will be evaluated to `access` is neither `private` nor `no` +`access !~ private|no` will be evaluated to "`access` is neither `private` nor `no`" Simple lists are [evaluated as sets](https://github.com/streetcomplete/StreetComplete/blob/2e812b9a3b5288983309a7edde6e8f9db05ad3f2/app/src/test/java/de/westnordost/streetcomplete/data/elementfilter/filters/ElementFilterOverpassKtTest.kt#L79-L88) - and for example `surface ~ earth|dirt|ground` will not match `surface=earther` tag. Basically, `surface ~ earth|dirt|ground` is treated as `surface ~ ^earth|dirt|ground$` @@ -391,6 +391,6 @@ It is possible to share and reuse [information about tagging schemes](https://gi (this info is gathered [here](/app/src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt)) -Even more complex ones using a different class bases are possible. Such as what was needed by the [address quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/address/AddAddressStreet.kt) or the [crossing quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/crossing/AddCrossing.kt) but it is better to start from something simpler. +Even more complex ones using different class bases are possible. Such as what was needed by the [address quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/address/AddAddressStreet.kt) or the [crossing quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/crossing/AddCrossing.kt) but it is better to start from something simpler. -It allows to make a complex geometry checks, but writing them is also far more complex. \ No newline at end of file +It allows to make complex geometry checks, but writing them is also far more complex. \ No newline at end of file From 7d6f510b935647df72a669682403138eac34c0b9 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 18 Jan 2022 10:17:18 +0100 Subject: [PATCH 008/181] Fix typos Co-authored-by: Jens Hausdorf --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 21409db31e..1f8ed7a746 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -72,7 +72,7 @@ You will find an XML file with entry looking like this: `"What is the name of this place? (%s)"` -The code `quest_placeName_title_name` is string reference, used in code to alow translations. +The code `quest_placeName_title_name` is string reference, used in code to allow translations. Search for this identifier in `*.kt` files, it should appear in the quest file [AddPlaceName](src/main/java/de/westnordost/streetcomplete/quests/place_name/AddPlaceName.kt). @@ -128,7 +128,7 @@ elementFilter property defines nodes, ways and relations which will be selected """ ``` -This query will be limited to nodes (`nodes with`), which fulfil some requirements. +This query will be limited to nodes (`nodes with`), which fulfill some requirements. - `emergency = defibrillator` tag must be present - `access` tag must not have values `private` or `no` to skip ones where mapper will be unable to survey (`!~ private|no` - to be more specific optionA|optionB is treated like `^optionA|optionB$` regexp) From 7b05a5cdfe3a97c48fb2a2e9c83d849a18756cec Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 18 Jan 2022 13:10:18 +0100 Subject: [PATCH 009/181] simplify testing section --- CONTRIBUTING_A_NEW_QUEST.md | 40 ++++++++++++++----------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 1f8ed7a746..fa27de1452 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -252,31 +252,21 @@ Inkscape is a typical tool to create and edit SVG files, it is a good, free, ope # Test -Obviously, testing can be done also earlier. - -But before submitting it should be tested. - -Typically it is done using an emulator. - -## Is quest listed? -Look at the quest list in settings - is your quest appearing there? If not - see [this step](#Add quest to the list of active ones). - -While you are there you can disable all quests except yours for an easier testing. - -## Element selection -Is it selected for expected elements? Is it not selected for some unwanted elements? Note that you can set location in emulator settings rather than scrolling within StreetComplete itself. - -## Quest form -Is quest form opening? Can you fill answer as expected? - -## Solving quest -Can you solve the quest? Is expected tagging being applied? - -You can look at logs for info what was applied or use undo menu from bottom-left. - -You can freely answer - as long as you are not logged in, nothing will be submitted. Even after logging in you can disable uploading answers. - -Is quest disappearing after being solved? +Obviously, testing can be done also earlier. But at least before submitting for review quest should be tested. + +Typically it is done using an emulator. Note that you can set location in emulator settings rather than scrolling within StreetComplete itself. + +* Is quest listed? + * Look at the quest list in settings - is your quest appearing there? If not - see [this step](#Add quest to the list of active ones). + * While you are there you can disable all quests except yours for an easier testing. +* Is it shown for expected elements? +* Is it selected for some unwanted elements? +* Can you tap on quest marker on open quest form?* an you fill answer as expected? +* Can you solve the quest? +* Is expected tagging being applied? +** You can look at logs for info what was applied or use undo menu from bottom-left. +** You can freely answer - as long as you are not logged in, nothing will be submitted. Even after logging in you can disable uploading answers. +* Is quest disappearing after being solved? # Open a pull request From 298e9e4311f09820ce49dc4b4280e7b4ec4ee39b Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 18 Jan 2022 13:50:04 +0100 Subject: [PATCH 010/181] follow upstream changes --- CONTRIBUTING_A_NEW_QUEST.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index fa27de1452..d08264d993 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -143,8 +143,12 @@ Also, for very detailed information that can be assumed to always have the same ### Properties -#### commitMessage -`override val commitMessage = "Add whether defibrillator is inside building"` +You can obtain more info about properties by +mousing over a property and pressing Ctrl+Q + + +#### changesetComment +`override val changesetComment = "Add whether defibrillator is inside building"` message used as a changeset comment #### wikiLink From 6b9c23df8ba7711865a547a279347153e1c8b330 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 18 Jan 2022 19:29:38 +0100 Subject: [PATCH 011/181] a better link and phrasing Co-authored-by: riQQ --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ae93ad9b28..9acc6e99c6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,7 +96,7 @@ In case you **don't have an idea of a quest?** Look [at the existing issues](htt Always remember to pay attention to [the quest guidelines](https://github.com/streetcomplete/StreetComplete/blob/master/QUEST_GUIDELINES.md) of StreetComplete! It also has tips for implementing a quest. -See [also far more detailed guide to making a new quest](CONTRIBUTING_A_NEW_QUEST.md). +See also [this far more detailed guide to making a new quest](CONTRIBUTING_A_NEW_QUEST.md). ### Code style From a60cfda859ee6e89de32b76be40f4c1511397b7d Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 18 Jan 2022 20:14:23 +0100 Subject: [PATCH 012/181] Proofreading the documentation Co-authored-by: riQQ --- CONTRIBUTING_A_NEW_QUEST.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index d08264d993..67fe342ee2 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -1,18 +1,18 @@ For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#development.md). -If you want to contribute code to the StreetComplete then making a new quest is one of the easiest programming tasks. Implementing a quest with interface design matching an existing one is quite simple. +If you want to contribute code to StreetComplete, then making a new quest is one of the easiest programming tasks. Implementing a quest with the interface design matching an existing one is quite simple. -Contributions like that are highly welcomed and you would make mapping one more thing in OSM much easier! +Contributions like that are highly welcome and you would make mapping one more thing in OSM much easier! Reading the text below is not necessary to create a new quest - a basic method of duplicating existing ones and modifying them may be sufficient. And people were creating new quests before this documentation existed. -But these materials may help or be quicker than trying to explore how things work fully on your own. +But these materials may help or be quicker than trying to fully explore on your own how things work. # What is not required - expert programming ability - you do not need to be an expert programmer to make contributions, basic programming abilities are sufficient to implement a quest similar to existing ones - any Kotlin-specific or Android-specific knowledge - it is fine if you never did anything with Kotlin or Android -- any Github specific knowledge +- any GitHub specific knowledge Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/new) if you are stuck despite this. @@ -25,11 +25,11 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - It is expected that someone trying this can search for a solution to a typical problems on encountering an error message - familiarity with StreetComplete as a user - it is really recommended to be familiar with how StreetComplete works. Making hundreds of edits is not mandatory. But passing familiarity with how surveying with StreetComplete works is needed. - time - Android Studio setup is sadly complicated - - Multiple hours are typical, though most spend on waiting for various downloads + - Multiple hours are typical, though mostly spent on waiting for various downloads - setting up Android Studio will likely be more complex than writing the code - basic ability to use git (but as mentioned, anything GitHub specific will be explained) - GitHub account -- around 15GB of a free space +- around 15GB of free space - the initial setup will download half of the Internet while getting emulators and dependencies. This is typical. # Dependencies - initial setup @@ -40,7 +40,7 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also connect to a real device via usb, this will not be later mentioned but can fully replace the emulator) - run StreetComple in emulator - to verify that everything was setup as required -if you are doing it for the first time do not worry if there is some error to solve along the way. This is typical for setting up Android development. See [CONTRIBUTING file](CONTRIBUTING.md#development) which has some links to info about the setup. +If you are doing it for the first time, don't worry if there is some error to solve along the way. This is typical for setting up Android development. See [CONTRIBUTING file](CONTRIBUTING.md#development) which has some links to information about the setup. # Invent a new quest @@ -59,7 +59,7 @@ Find one that has the same type of interface as the one that you are trying to i Are you trying to implement a quest that will affect roads and paths? Take `AddWayLit` quest as a base if it will be a yes/no question. `AddTracktype` where the mapper will be selecting one of the images. -Is it going to be asked for POIs and be disabled by default? `AddWheelchairAccessBusiness` may be a good base. +Is it going to be asked for POIs and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. Quest are defined in [their own folder](app/src/main/java/de/westnordost/streetcomplete/quests). @@ -76,7 +76,7 @@ The code `quest_placeName_title_name` is string reference, used in code to allow Search for this identifier in `*.kt` files, it should appear in the quest file [AddPlaceName](src/main/java/de/westnordost/streetcomplete/quests/place_name/AddPlaceName.kt). -This method can be often used to locate relevant code. +This method can often be used to locate relevant code. ## Pull requests From b788841f63b18ca7bc06ef99df6750bb9712cb50 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 19 Jan 2022 17:01:38 +0100 Subject: [PATCH 013/181] fix broken link Co-authored-by: Peter Newman --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 67fe342ee2..77f5e4325d 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -1,4 +1,4 @@ -For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#development.md). +For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#development). If you want to contribute code to StreetComplete, then making a new quest is one of the easiest programming tasks. Implementing a quest with the interface design matching an existing one is quite simple. From eb144f5b40eb269d8038bc7b692d2e32a61ef923 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 19 Jan 2022 17:13:23 +0100 Subject: [PATCH 014/181] Apply suggestions from code review Co-authored-by: Peter Newman --- CONTRIBUTING_A_NEW_QUEST.md | 74 ++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 77f5e4325d..a11ae12734 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -1,12 +1,12 @@ For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#development). -If you want to contribute code to StreetComplete, then making a new quest is one of the easiest programming tasks. Implementing a quest with the interface design matching an existing one is quite simple. +If you want to contribute code to StreetComplete, then making a new quest is one of the easiest programming tasks. Implementing a quest where the interface design matches an existing one is quite simple. Contributions like that are highly welcome and you would make mapping one more thing in OSM much easier! Reading the text below is not necessary to create a new quest - a basic method of duplicating existing ones and modifying them may be sufficient. And people were creating new quests before this documentation existed. -But these materials may help or be quicker than trying to fully explore on your own how things work. +But this materials may help or be quicker than trying to fully explore on your own how things work. # What is not required @@ -18,12 +18,12 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n # Required -- programming ability - it is not a good first task for someone who never programmed anything. - - Setup of environment takes long +- programming ability - it is not a good first task for someone who has never programmed anything. + - Setup of environment takes a long time - Editing even the simplest quest requires edits to at least two different files - - Kotlin familiarity is not needed, but the ability to adjust to a new syntax is needed + - Kotlin familiarity is not required, but the ability to adjust to a new syntax is needed - It is expected that someone trying this can search for a solution to a typical problems on encountering an error message -- familiarity with StreetComplete as a user - it is really recommended to be familiar with how StreetComplete works. Making hundreds of edits is not mandatory. But passing familiarity with how surveying with StreetComplete works is needed. +- familiarity with StreetComplete as a user - it is highly recommended to be familiar with how StreetComplete works. Making hundreds of edits is not mandatory, but having a passing familiarity with how surveying with StreetComplete works is needed. - time - Android Studio setup is sadly complicated - Multiple hours are typical, though mostly spent on waiting for various downloads - setting up Android Studio will likely be more complex than writing the code @@ -40,7 +40,7 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also connect to a real device via usb, this will not be later mentioned but can fully replace the emulator) - run StreetComple in emulator - to verify that everything was setup as required -If you are doing it for the first time, don't worry if there is some error to solve along the way. This is typical for setting up Android development. See [CONTRIBUTING file](CONTRIBUTING.md#development) which has some links to information about the setup. +If you are doing it for the first time, don't worry if there is an error to solve along the way, this is typical for setting up an Android development environment. See [CONTRIBUTING file](CONTRIBUTING.md#development) which has some links to information about the setup. # Invent a new quest @@ -50,7 +50,7 @@ To [repeat](https://github.com/streetcomplete/StreetComplete/blob/master/CONTRIB ## Existing proposals You can also look at [quest proposals waiting for implementation](https://github.com/streetcomplete/StreetComplete/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+quest%22). -# Learn from an existing code +# Learn from existing code ## Find a base Base the new quest on one that exists already. @@ -64,15 +64,15 @@ Is it going to be asked for POIs and should be disabled by default? `AddWheelcha Quest are defined in [their own folder](app/src/main/java/de/westnordost/streetcomplete/quests). -### Locating quest +### Locating a quest -Search across code for part of a question or other text characteristic to this message. For example "What is the name of this place" +Search across the code for part of a question or other text characteristic to this quest. For example "What is the name of this place" -You will find an XML file with entry looking like this: +You will find an XML file with an entry looking like this: `"What is the name of this place? (%s)"` -The code `quest_placeName_title_name` is string reference, used in code to allow translations. +The identifier `quest_placeName_title_name` is a string reference, used in the code to allow translations. Search for this identifier in `*.kt` files, it should appear in the quest file [AddPlaceName](src/main/java/de/westnordost/streetcomplete/quests/place_name/AddPlaceName.kt). @@ -82,7 +82,7 @@ This method can often be used to locate relevant code. One of the better ways to get around a codebase new to you is to look at recent accepted proposals to change code (pull requests). -This is likely useful also here. +This is also likely useful here. Find some [recent ones](https://github.com/streetcomplete/StreetComplete/pulls?q=is%3Apr+is%3Aclosed) adding a quest. @@ -92,11 +92,11 @@ This can be also used to locate relevant code, especially helpful if some change # Copying -Copy relevant quest folder. Some contain multiple quests, in such case copy only what you need. +Copy the relevant quest folder. Some contain multiple quests, in such case copy only what you need. Some quests are entirely defined in a single file, some have additional answer class, custom interface or utility classes. -# Adjust copy +# Adjust the copy After the quest is copied it is necessary to adjust it a bit. @@ -104,9 +104,9 @@ Change its class name and the file name to the new one. In copied code change package info (things like `package de.westnordost.streetcomplete.quests.defibrillator` at the top) to match the new folder containing the quest. -# Add quest to the list of active ones +# Add the quest to the list of active ones -Adjust [QuestModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.kt) file. It contains a big list of active quests, ordered by priority. Read [what governs their priority](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.kt#L138-L162) but do not worry too much, it can be later tweaked. +Adjust [QuestModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.kt) file. It contains a big list of active quests, ordered by priority. Read [what governs their priority](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.kt#L138-L162) but do not worry too much, it can be tweaked later. Add your quest to the list so that it will be loaded by the app. @@ -143,8 +143,7 @@ Also, for very detailed information that can be assumed to always have the same ### Properties -You can obtain more info about properties by -mousing over a property and pressing Ctrl+Q +You can obtain more info about properties by mousing over a property and pressing Ctrl+Q within Android Studio #### changesetComment @@ -167,7 +166,7 @@ More info about icon handling will be given later. #### questTypeAchievements `override val questTypeAchievements = listOf(LIFESAVER)` -In quest achievements list what is relevant to given quest, see the full list of available ones in [AchievementsModule.kt](app/src/main/java/de/westnordost/streetcomplete/data/user/achievements/AchievementsModule.kt) +In quest achievements, list what is relevant to the given quest, see the full list of available ones in [AchievementsModule.kt](app/src/main/java/de/westnordost/streetcomplete/data/user/achievements/AchievementsModule.kt) #### getTitle `override fun getTitle(tags: Map) = R.string.quest_is_defibrillator_inside_title` @@ -177,7 +176,7 @@ It is a message displayed to user, code here passes a [reference](https://develo Actual strings sit in [app/src/main/res/values/strings.xml](app/src/main/res/values/strings.xml) -There are additional files with text, but the text is translated with a completely separately worflow and your changes will modify solely this one file, leaving other text files untouched. +There are additional files with text, but the text is translated with a completely separately workflow and your changes will only modify this file, leaving other text files untouched. #### Form @@ -215,7 +214,7 @@ See other ones defined in [StringMapChangesBuilder.kt](de/westnordost/streetcomp ### Extras -Info listed above must be supplied by every quest. But there are also several optional fields. This specific qest has +Info listed above must be supplied by every quest. But there are also several optional fields. This specific quest has ``` override fun getHighlightedElements(element: Element, getMapData: () -> MapDataWithGeometry) = getMapData().filter("nodes with emergency = defibrillator") @@ -239,33 +238,34 @@ Keep similar style to existing ones and app in general. Once the quest icon is r - save as "Plain svg" or clean SVG file from unnecessary cruft in another way, like using [svgo](https://github.com/svg/svgo) - Put SVG into `[res/graphics/quest icons](res/graphics/quest icons)` folder - - SVG is a standard format editable in various software, unlike internal Android Studio xml that will be produced in the next step. + - SVG is a standard format editable in various software, unlike internal Android Studio XML that will be produced in the next step. - Open Android Studio - Right click on "app" folder in the Project tool window (top left) - Select new → vector asset -- Select your svg file +- Select your SVG file - Name with `ic_quest_` prefix (something like `ic_quest_traffic_calming`), this will cause IDE to generate an XML file - add an entry in the [attribution file](res/graphics/authors.txt) - modify `icon` property in the quest definition to use the new drawable - Commit modified or created files - Compile, test quest in the emulator -The same method applies also to other vector drawables, only they will be placed in other parts of [res/graphics/](res/graphics/) +The same method applies also to other vector drawables, although they will be placed in other parts of [res/graphics/](res/graphics/) -Inkscape is a typical tool to create and edit SVG files, it is a good, free, open-source so is available to all. +Inkscape is a typical tool to create and edit SVG files, it is a good, free and open-source so is available to all. # Test -Obviously, testing can be done also earlier. But at least before submitting for review quest should be tested. +Obviously, testing can also be done earlier. But the quest should at least be tested before submitting for review. Typically it is done using an emulator. Note that you can set location in emulator settings rather than scrolling within StreetComplete itself. * Is quest listed? * Look at the quest list in settings - is your quest appearing there? If not - see [this step](#Add quest to the list of active ones). - * While you are there you can disable all quests except yours for an easier testing. + * While you are there you can disable all quests except yours for easier testing. * Is it shown for expected elements? * Is it selected for some unwanted elements? -* Can you tap on quest marker on open quest form?* an you fill answer as expected? +* Can you tap on quest marker on open quest form? +* Can you fill the answer as expected? * Can you solve the quest? * Is expected tagging being applied? ** You can look at logs for info what was applied or use undo menu from bottom-left. @@ -284,13 +284,13 @@ You can see [already submitted pull requests](https://github.com/streetcomplete/ # Future -After opening a pull request it will be reviewed and you will likely be asked to make some changes. This is normal and happens also with pull requests submitted by experienced contributors. +After opening a pull request it will be reviewed and you will likely be asked to make some changes. This is normal and also happens with pull requests submitted by experienced contributors. Changes typically include improving code style, tweaking phrasing and quest settings. You are also welcome to help with reviewing other PRs - different people have different strengths, there are active reviewers who help with code style, there are some native speakers of English, some with deep knowledge of OSM tagging schemes or deep knowledge of how StreetComplete works. -After the PR was finished it will be merged before the beta release of the next version. This way it can be additionally tested with a wider audience before release to all and translators can [translate text into other languages](CONTRIBUTING.md#translating-the-app). +After the PR is finished it will be merged before the beta release of the next version. This way it can be additionally tested with a wider audience before release to all and translators can [translate text into other languages](CONTRIBUTING.md#translating-the-app). After full release it will reach the entire StreetComplete audience who now will be able to more easily contribute to OpenStreetMap. Thanks in advance for that! @@ -298,19 +298,19 @@ After full release it will reach the entire StreetComplete audience who now will Unclear documentation, including this one, is a bug. Feel free to either submit a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) with a fix or [open an issue](https://github.com/streetcomplete/StreetComplete/issues/new) describing your confusion. -Note that not everything will be directly described. This document is very intentionally not including step-by-step guide to install Android Studio, [linking](CONTRIBUTING.md#development) to an official docs. +Note that not everything will be directly described. This document is very intentionally not including step-by-step guide to install Android Studio, [linking](CONTRIBUTING.md#development) to official docs instead. # More complexity -What was described above is an attempt to cover all aspects of quest creation, without describing all complexity. +What was described above is an attempt to cover all aspects of quest creation, without describing all the complexity. -This contains some additional info. +Below is some additional info. ## getTitle Parameters -In some cases, quest will mention the name and type of feature. For example, in case of shops to make their identification possible. +In some cases, the quest will mention the name and type of feature. For example, in the case of shops to make their identification possible. -This requires preparing space in message for filling at runtime, +This requires preparing space in the message for filling at runtime, -And to add mechanism supplying this data. Here is [a typical code](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L102-L111) that will +And to add the mechanism supplying this data. Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L102-L111) that will: ``` override fun getTitle(tags: Map) = From 931b042f4e3d83f052810c8571041cc34cdbdcf4 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 25 Jan 2022 09:55:31 +0100 Subject: [PATCH 015/181] English improvement by peternewman --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index a11ae12734..18c2130460 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -2,7 +2,7 @@ For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#d If you want to contribute code to StreetComplete, then making a new quest is one of the easiest programming tasks. Implementing a quest where the interface design matches an existing one is quite simple. -Contributions like that are highly welcome and you would make mapping one more thing in OSM much easier! +Contributions like that are highly welcomed and you would make mapping one more thing in OSM much easier! Reading the text below is not necessary to create a new quest - a basic method of duplicating existing ones and modifying them may be sufficient. And people were creating new quests before this documentation existed. From 5684fb7085f0ad87ed5b0452e88b8f8750dec97e Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Fri, 28 Jan 2022 19:40:19 +0100 Subject: [PATCH 016/181] fix links after moving graphics around --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 18c2130460..becbcdb64b 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -232,12 +232,12 @@ But it would be even better to include also icon. Note that there are some not-yet-used graphics, created for some proposed or expected quests. Maybe there is no need to create icon at all! -A new icon can reuse the content of [other quest icons](res/graphics/quest icons), it can be based on openly licensed graphics. See [the attribution file](res/graphics/authors.txt) for what was used so far. +A new icon can reuse the content of [other quest icons](res/graphics/quest), it can be based on openly licensed graphics. See [the attribution file](res/graphics/authors.txt) for what was used so far. Keep similar style to existing ones and app in general. Once the quest icon is ready: - save as "Plain svg" or clean SVG file from unnecessary cruft in another way, like using [svgo](https://github.com/svg/svgo) -- Put SVG into `[res/graphics/quest icons](res/graphics/quest icons)` folder +- Put SVG into `[res/graphics/quest](res/graphics/quest)` folder - SVG is a standard format editable in various software, unlike internal Android Studio XML that will be produced in the next step. - Open Android Studio - Right click on "app" folder in the Project tool window (top left) From 9aa7d5aba96d1e2a688ad45245e3c3dc14c19e47 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 17:50:10 +0100 Subject: [PATCH 017/181] fix phrasing Co-authored-by: Peter Newman --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index becbcdb64b..9237fe9142 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -22,7 +22,7 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - Setup of environment takes a long time - Editing even the simplest quest requires edits to at least two different files - Kotlin familiarity is not required, but the ability to adjust to a new syntax is needed - - It is expected that someone trying this can search for a solution to a typical problems on encountering an error message + - It is expected that someone trying this can search for a solution to a typical problem on encountering an error message - familiarity with StreetComplete as a user - it is highly recommended to be familiar with how StreetComplete works. Making hundreds of edits is not mandatory, but having a passing familiarity with how surveying with StreetComplete works is needed. - time - Android Studio setup is sadly complicated - Multiple hours are typical, though mostly spent on waiting for various downloads From 1e9145d948decdb84021551483561383dbbc9747 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 17:51:28 +0100 Subject: [PATCH 018/181] better English Co-authored-by: Peter Newman --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 9237fe9142..bc2365b301 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -230,7 +230,7 @@ It is OK to submit a quest without own icon, using any icon as a placeholder. But it would be even better to include also icon. -Note that there are some not-yet-used graphics, created for some proposed or expected quests. Maybe there is no need to create icon at all! +Note that there are some graphics which haven't been used yet, created for proposed or expected quests; maybe you don't even need to create an icon! A new icon can reuse the content of [other quest icons](res/graphics/quest), it can be based on openly licensed graphics. See [the attribution file](res/graphics/authors.txt) for what was used so far. From 8678d21f85750ea19b9abdce22c778d03cb97bb1 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 17:53:18 +0100 Subject: [PATCH 019/181] Fix incorrect claim, add missing dot Co-authored-by: Holger Jeromin --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index bc2365b301..cba7528a3d 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -143,7 +143,7 @@ Also, for very detailed information that can be assumed to always have the same ### Properties -You can obtain more info about properties by mousing over a property and pressing Ctrl+Q within Android Studio +You can obtain more info about properties by placing the cursor in a property and pressing Ctrl+Q within Android Studio. #### changesetComment From afe5b6461a71185cb7e40a8347a813b9daf7b1a7 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 18:22:36 +0100 Subject: [PATCH 020/181] more clear sentence, add missing 'the' Co-authored-by: Peter Newman --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index cba7528a3d..abdbc52454 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -38,7 +38,7 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - clone StreetComplete repository - open StreetComplete in Android Studio - [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also connect to a real device via usb, this will not be later mentioned but can fully replace the emulator) -- run StreetComple in emulator - to verify that everything was setup as required +- run StreetComplete in the emulator (to verify that everything was setup as required) If you are doing it for the first time, don't worry if there is an error to solve along the way, this is typical for setting up an Android development environment. See [CONTRIBUTING file](CONTRIBUTING.md#development) which has some links to information about the setup. From 8697cb2c99044e7f4b14c1a06ab4f3746694ec13 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 18:35:26 +0100 Subject: [PATCH 021/181] rewrite section about using real device --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index abdbc52454..9ac94b2ca8 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -37,7 +37,7 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - install necessary software (Android Studio and git) - clone StreetComplete repository - open StreetComplete in Android Studio -- [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also connect to a real device via usb, this will not be later mentioned but can fully replace the emulator) +- [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also []connect to a real device via USB](https://developer.android.com/studio/run/device), this can replace using the emulator) - run StreetComplete in the emulator (to verify that everything was setup as required) If you are doing it for the first time, don't worry if there is an error to solve along the way, this is typical for setting up an Android development environment. See [CONTRIBUTING file](CONTRIBUTING.md#development) which has some links to information about the setup. From 2d8bd571d45430e7d48aef3e555ba723f373b5af Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 18:50:15 +0100 Subject: [PATCH 022/181] describe forking, mention branch creation --- CONTRIBUTING_A_NEW_QUEST.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 9ac94b2ca8..e7bbeb3571 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -35,7 +35,10 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n # Dependencies - initial setup - install necessary software (Android Studio and git) -- clone StreetComplete repository +- create GitHub account if needed +- visit [https://github.com/streetcomplete/StreetComplete](https://github.com/streetcomplete/StreetComplete) and press "fork" button on top right + + this creates a copy of StreetComplete repository that you control and can prepare code there +- clone your fork of a StreetComplete repository - open StreetComplete in Android Studio - [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also []connect to a real device via USB](https://developer.android.com/studio/run/device), this can replace using the emulator) - run StreetComplete in the emulator (to verify that everything was setup as required) @@ -50,6 +53,10 @@ To [repeat](https://github.com/streetcomplete/StreetComplete/blob/master/CONTRIB ## Existing proposals You can also look at [quest proposals waiting for implementation](https://github.com/streetcomplete/StreetComplete/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+quest%22). +# Prepare repository for development + +That is a good moment create a branch and switch to it (`git checkout -b short_branch_name_describing_planned_work`) + # Learn from existing code ## Find a base From 308b63428992177b77edafa6d37552c434e4ff56 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 18:52:31 +0100 Subject: [PATCH 023/181] describe file at start --- CONTRIBUTING_A_NEW_QUEST.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index e7bbeb3571..bec91ff67d 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -1,3 +1,5 @@ +This file describes in detail process of creating a new quest. + For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#development). If you want to contribute code to StreetComplete, then making a new quest is one of the easiest programming tasks. Implementing a quest where the interface design matches an existing one is quite simple. From 2cff0b942e935ea66879537059f72eeca564de7b Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 18:58:02 +0100 Subject: [PATCH 024/181] link install instructions --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index bec91ff67d..72be103ed9 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -36,7 +36,7 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n # Dependencies - initial setup -- install necessary software (Android Studio and git) +- install necessary software ([Android Studio](https://developer.android.com/studio) and [git](https://git-scm.com/downloads)) - create GitHub account if needed - visit [https://github.com/streetcomplete/StreetComplete](https://github.com/streetcomplete/StreetComplete) and press "fork" button on top right + this creates a copy of StreetComplete repository that you control and can prepare code there From 2e38cbe609cbb56ed8e96189c95775a9438d25ff Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 19:51:37 +0100 Subject: [PATCH 025/181] better English Co-authored-by: Peter Newman --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 72be103ed9..520aa71350 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -307,7 +307,7 @@ After full release it will reach the entire StreetComplete audience who now will Unclear documentation, including this one, is a bug. Feel free to either submit a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) with a fix or [open an issue](https://github.com/streetcomplete/StreetComplete/issues/new) describing your confusion. -Note that not everything will be directly described. This document is very intentionally not including step-by-step guide to install Android Studio, [linking](CONTRIBUTING.md#development) to official docs instead. +Note that not everything will be directly described. This document very intentionally doesn't include a step-by-step guide to installing Android Studio, [linking](CONTRIBUTING.md#development) to official docs instead. # More complexity What was described above is an attempt to cover all aspects of quest creation, without describing all the complexity. From eee89dd2adf95b83bc559e095d8999a0bb69f6c5 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 19:58:00 +0100 Subject: [PATCH 026/181] Apply suggestions from code review Co-authored-by: Peter Newman --- CONTRIBUTING_A_NEW_QUEST.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 520aa71350..b089337198 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -32,7 +32,7 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - basic ability to use git (but as mentioned, anything GitHub specific will be explained) - GitHub account - around 15GB of free space - - the initial setup will download half of the Internet while getting emulators and dependencies. This is typical. + - the initial setup will typically download half of the Internet while getting emulators and dependencies # Dependencies - initial setup @@ -68,7 +68,7 @@ Find one that has the same type of interface as the one that you are trying to i Are you trying to implement a quest that will affect roads and paths? Take `AddWayLit` quest as a base if it will be a yes/no question. `AddTracktype` where the mapper will be selecting one of the images. -Is it going to be asked for POIs and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. +Is it going to be asked for POIs (Points of Interest) and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. Quest are defined in [their own folder](app/src/main/java/de/westnordost/streetcomplete/quests). @@ -83,7 +83,7 @@ You will find an XML file with an entry looking like this: The identifier `quest_placeName_title_name` is a string reference, used in the code to allow translations. -Search for this identifier in `*.kt` files, it should appear in the quest file [AddPlaceName](src/main/java/de/westnordost/streetcomplete/quests/place_name/AddPlaceName.kt). +Search for this identifier in `*.kt` files, it should appear in the quest file (in this case [AddPlaceName.kt](src/main/java/de/westnordost/streetcomplete/quests/place_name/AddPlaceName.kt)). This method can often be used to locate relevant code. @@ -161,7 +161,6 @@ message used as a changeset comment #### wikiLink `override val wikiLink = "Key:indoor"` - points to the OSM Wiki page most relevant to the given quest, typically it is an added key. In this case, it is a page about [indoor=* tagging](https://wiki.openstreetmap.org/wiki/Key:indoor). #### icon @@ -305,7 +304,7 @@ After full release it will reach the entire StreetComplete audience who now will # Bad documentation is a bug -Unclear documentation, including this one, is a bug. Feel free to either submit a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) with a fix or [open an issue](https://github.com/streetcomplete/StreetComplete/issues/new) describing your confusion. +Unclear documents, including this one, are a bug. Feel free to either submit a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) with a fix or [open an issue](https://github.com/streetcomplete/StreetComplete/issues/new) describing your confusion. Note that not everything will be directly described. This document very intentionally doesn't include a step-by-step guide to installing Android Studio, [linking](CONTRIBUTING.md#development) to official docs instead. @@ -354,7 +353,7 @@ Considerations about the edge cases to consider, how the design could look like Some quests will require photos for their interface. -Photo must be available on open license - so not every photo found across the Internet is usable. You can either take own photo or find an existing freely licensed photo. +Photos must be available on open license - so not every photo found on the Internet is usable. You can either take your own photo or find an existing freely licensed photo. Good places to find freely licensed images are [Geograph](https://www.geograph.org.uk/) and [Wikimedia Commons](https://commons.wikimedia.org/). @@ -370,11 +369,11 @@ Photos go to a different folder than SVGs: they can be used directly by the buil - [xhdpi](app/src/main/res/drawable-xhdpi) (typically 256 x 256 pixels, for rectangular ones smaller dimension should be 256 pixels) - [xxhdpi](app/src/main/res/drawable-xxhdpi) (typically 384 x 384 pixels, for rectangular ones smaller dimension should be 384 pixels) -Each of this folders should hold the same image resized to a different resolution. While testing various images it is enough to put into one folder. +Each of these folders should hold the same image resized to a different resolution. While testing various images it is enough to put one into any of the folders. The [rescaling script](https://github.com/matkoniecz/rescaling_for_android) may be useful, but you can also do this manually with Gimp or similar software. -After adding a file remember to update [the credit file](app/src/main/res/authors.txt) (different than one for icons). +After adding a photo, remember to update [the credit file](app/src/main/res/authors.txt) (different to the one for icons). ## Custom filters It is possible to use far more complex filters when querying for eligible elements. @@ -396,4 +395,4 @@ It is possible to share and reuse [information about tagging schemes](https://gi Even more complex ones using different class bases are possible. Such as what was needed by the [address quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/address/AddAddressStreet.kt) or the [crossing quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/crossing/AddCrossing.kt) but it is better to start from something simpler. -It allows to make complex geometry checks, but writing them is also far more complex. \ No newline at end of file +It allows it to make complex geometry checks, but writing them is also far more complex. \ No newline at end of file From e763c008a4ed0113b99875e7172d17e3987ab79a Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 20:02:04 +0100 Subject: [PATCH 027/181] make command easier to copy --- CONTRIBUTING_A_NEW_QUEST.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index b089337198..6c35b61899 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -57,7 +57,9 @@ You can also look at [quest proposals waiting for implementation](https://github # Prepare repository for development -That is a good moment create a branch and switch to it (`git checkout -b short_branch_name_describing_planned_work`) +That is a good moment create a branch and switch to it. It can be done with the following command: + +`git checkout -b short_branch_name_describing_planned_work` # Learn from existing code From 4f33706ad54484774ed48f9bf5217f4a40ac3fe4 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 20:02:17 +0100 Subject: [PATCH 028/181] missing full stop --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 6c35b61899..537d9156e9 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -70,14 +70,14 @@ Find one that has the same type of interface as the one that you are trying to i Are you trying to implement a quest that will affect roads and paths? Take `AddWayLit` quest as a base if it will be a yes/no question. `AddTracktype` where the mapper will be selecting one of the images. -Is it going to be asked for POIs (Points of Interest) and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. +Is it going to be asked for POIs and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. Quest are defined in [their own folder](app/src/main/java/de/westnordost/streetcomplete/quests). ### Locating a quest -Search across the code for part of a question or other text characteristic to this quest. For example "What is the name of this place" +Search across the code for part of a question or other text characteristic to this quest. For example "What is the name of this place". You will find an XML file with an entry looking like this: From 3bc0204f2b2d09dd9054c0aacb5f86af90bc07b3 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 20:02:48 +0100 Subject: [PATCH 029/181] syntax changed here --- CONTRIBUTING_A_NEW_QUEST.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 537d9156e9..1b6110f13b 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -204,8 +204,8 @@ But sometimes more complex ones are needed, see for example [AddBridgeStructure. With form defined in [AddBridgeStructureForm](app/src/main/java/de/westnordost/streetcomplete/quests/bridge_structure/AddBridgeStructureForm.kt) ### applyAnswerTo ``` - override fun applyAnswerTo(answer: Boolean, changes: StringMapChangesBuilder) { - changes.add("indoor", answer.toYesNo()) + override fun applyAnswerTo(answer: Boolean, tags: Tags, timestampEdited: Long) { + tags["indoor"] = answer.toYesNo() } ``` @@ -213,6 +213,7 @@ This code is responsible for modifying `StringMapChangesBuilder` object (passed Actions may include (examples from various quests): +TODO update to the new syntax - `changes.add("indoor", answer.toYesNo())` - adds a new tag, it must not be present already - `changes.addOrModify("material", newMaterial)` - add a new tag if missing, override existing value if present - `changes.modify("sport", values)` - modify existing tag, value must be present From 4acb3f6b400ea3e0cf340ddaa9d2423e1cc1b711 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 20:03:37 +0100 Subject: [PATCH 030/181] fix typo --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 1b6110f13b..ffc1d2acc1 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -275,7 +275,7 @@ Typically it is done using an emulator. Note that you can set location in emulat * While you are there you can disable all quests except yours for easier testing. * Is it shown for expected elements? * Is it selected for some unwanted elements? -* Can you tap on quest marker on open quest form? +* Can you tap on quest marker to open quest form? * Can you fill the answer as expected? * Can you solve the quest? * Is expected tagging being applied? From ef8c6ec06389b08baa07f1620797ff108c14ea3c Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 20:09:50 +0100 Subject: [PATCH 031/181] fix grammar --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index ffc1d2acc1..fd6831e124 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -72,7 +72,7 @@ Are you trying to implement a quest that will affect roads and paths? Take `AddW Is it going to be asked for POIs and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. -Quest are defined in [their own folder](app/src/main/java/de/westnordost/streetcomplete/quests). +Quests are defined in [their own folder](app/src/main/java/de/westnordost/streetcomplete/quests). ### Locating a quest From be677ea3ad52999c508bbf120f69c8dd6b1b4a1c Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 20:38:23 +0100 Subject: [PATCH 032/181] description of parameters passed to the title --- CONTRIBUTING_A_NEW_QUEST.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index fd6831e124..652a423a24 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -316,12 +316,12 @@ What was described above is an attempt to cover all aspects of quest creation, w Below is some additional info. -## getTitle Parameters +## getTitle and getTitleArgs In some cases, the quest will mention the name and type of feature. For example, in the case of shops to make their identification possible. This requires preparing space in the message for filling at runtime, -And to add the mechanism supplying this data. Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L102-L111) that will: +And to add the mechanism supplying this data. Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L104-L115) that will: ``` override fun getTitle(tags: Map) = @@ -336,9 +336,21 @@ And to add the mechanism supplying this data. Here is [some typical code](https: } ``` -- try to pass name, feature type (such as "greengrocer", translated to the proper language) -- if name is not tagged: brand and feature type -- or just feature type +- `getTitleArgs` tries to pass to the title + - name of the object + - brand of the object (only if ``name` tag is not used, and `brand` tag is present) + - feature type (such as "greengrocer", translated to the proper language, based on [iD presets](https://github.com/westnordost/osmfeatures)) + +[Filtering in the element selection](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L20) ensures that every object will have either `name` or `brand` tag. + +Though description from iD presets is not guaranted. + +So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either + +* `quest_wheelchairAccess_name_type_title` which represents `Is %1$s (%2$s) wheelchair accessible?` (or translation). Note presence of `%1$s` and `%2$s` which will be replaced by text provided by ``getTitleArgs` +* In case of no feature type being available `quest_wheelchairAccess_name_title` will be used, with space for one parameter: `Is %s wheelchair accessible?` + +This is quite complex but allows translating application in various languages by decoupling exact text being displayed from the code. ## Designing the form From 3ae79afe64f7938f18f7581599c5d3db5fc7ed7e Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 20:42:06 +0100 Subject: [PATCH 033/181] better English Co-authored-by: Peter Newman --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 652a423a24..056963b210 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -357,7 +357,7 @@ This is quite complex but allows translating application in various languages by As mentioned, the user interface must leave no space for misunderstandings, it must be concise and quick and easy to use. Also sounds obvious, but you will quickly find out that a balance must be found between covering all the edge cases and designing the form to be as straightforward and clutterless as possible. - Design the main form clutter-free so that it is straightforward for the majority of use cases. -- Make it not impossible to answer the edge cases (but don't clutter up the main form with that). A good pattern is to "ban" answering edge cases into the "Other answers..." menu. I.e. look at the opening hours quest. +- Make it not impossible to answer the edge cases (but don't clutter up the main form with that). A good pattern is to "ban" answering edge cases into the "Other answers..." menu, i.e. look at the opening hours quest. - Don't rely on the "leave a note" fallback too much. It is not intended and does not work as a regular answer but is designed to cover the case that the question was invalid itself because it was based on wrong data like i.e. the place does not exist anymore. - The information the user should fill in should be as atomic as possible. Users are impatient. I.e. do not let them fill out a whole address with street name etc. when just the house number is fine too. - "A picture is worth a thousand words": Often the term for certain things may not be enough to convey the meaning of certain predefined answers. Do you know what a wheelbender is? You will know if you see the photo. From f11738f52581ae75ab39baa802ccb9bb9d1860a7 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 20:44:03 +0100 Subject: [PATCH 034/181] Try to simplify --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 056963b210..414a283934 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -357,7 +357,7 @@ This is quite complex but allows translating application in various languages by As mentioned, the user interface must leave no space for misunderstandings, it must be concise and quick and easy to use. Also sounds obvious, but you will quickly find out that a balance must be found between covering all the edge cases and designing the form to be as straightforward and clutterless as possible. - Design the main form clutter-free so that it is straightforward for the majority of use cases. -- Make it not impossible to answer the edge cases (but don't clutter up the main form with that). A good pattern is to "ban" answering edge cases into the "Other answers..." menu, i.e. look at the opening hours quest. +- Allow to answer popular edge cases, but don't clutter up the main form with that. A good pattern is to move such answers into the "Other answers..." menu. I.e. look at the opening hours quest. - Don't rely on the "leave a note" fallback too much. It is not intended and does not work as a regular answer but is designed to cover the case that the question was invalid itself because it was based on wrong data like i.e. the place does not exist anymore. - The information the user should fill in should be as atomic as possible. Users are impatient. I.e. do not let them fill out a whole address with street name etc. when just the house number is fine too. - "A picture is worth a thousand words": Often the term for certain things may not be enough to convey the meaning of certain predefined answers. Do you know what a wheelbender is? You will know if you see the photo. From 998ce546cdbc9eb6ee0a0b268a614cd7280ffdf5 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 20:44:51 +0100 Subject: [PATCH 035/181] better English Co-authored-by: Peter Newman --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 414a283934..c10cfe3b2c 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -359,7 +359,7 @@ As mentioned, the user interface must leave no space for misunderstandings, it m - Design the main form clutter-free so that it is straightforward for the majority of use cases. - Allow to answer popular edge cases, but don't clutter up the main form with that. A good pattern is to move such answers into the "Other answers..." menu. I.e. look at the opening hours quest. - Don't rely on the "leave a note" fallback too much. It is not intended and does not work as a regular answer but is designed to cover the case that the question was invalid itself because it was based on wrong data like i.e. the place does not exist anymore. -- The information the user should fill in should be as atomic as possible. Users are impatient. I.e. do not let them fill out a whole address with street name etc. when just the house number is fine too. +- The information the user should fill in should be as atomic as possible. Users are impatient, i.e. do not let them fill out a whole address with street name etc. when just the house number is fine too. - "A picture is worth a thousand words": Often the term for certain things may not be enough to convey the meaning of certain predefined answers. Do you know what a wheelbender is? You will know if you see the photo. Considerations about the edge cases to consider, how the design could look like and finding good representative photos or icons that match in style is also part of the preparational work that can be done without programming knowledge. From 5d65f85f2f3962c360d298690977ac220d729ed5 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 20:47:27 +0100 Subject: [PATCH 036/181] Update CONTRIBUTING_A_NEW_QUEST.md Co-authored-by: Peter Newman --- CONTRIBUTING_A_NEW_QUEST.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index c10cfe3b2c..50a2ad48d6 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -379,10 +379,10 @@ In StreetComplete many images have unusual composition. Often it is necessary to Images should be free of visual debris, not misleading. Though it is fine to use an image not strictly matching what is depicted, as long as it is clear. For example, [a permanent pile of soil blocking road](https://wiki.openstreetmap.org/wiki/Tag:barrier%3Ddebris) is illustrated by a [temporary landslide](https://commons.wikimedia.org/wiki/File:Landslide_on_OR_42S_(46849629014).jpg). This is OK as images are illustrative. Photos go to a different folder than SVGs: they can be used directly by the build process so put them into folders - - [mdpi](app/src/main/res/drawable-mdpi) (typically 128 x 128 pixels, for rectangular ones smaller dimension should be 128 pixels) - - [hdpi](app/src/main/res/drawable-hdpi) (typically 192 x 192 pixels, for rectangular ones smaller dimension should be 192 pixels) - - [xhdpi](app/src/main/res/drawable-xhdpi) (typically 256 x 256 pixels, for rectangular ones smaller dimension should be 256 pixels) - - [xxhdpi](app/src/main/res/drawable-xxhdpi) (typically 384 x 384 pixels, for rectangular ones smaller dimension should be 384 pixels) + - [mdpi](app/src/main/res/drawable-mdpi) (typically 128 x 128 pixels, for rectangular ones, smaller dimension should be 128 pixels) + - [hdpi](app/src/main/res/drawable-hdpi) (typically 192 x 192 pixels, for rectangular ones, smaller dimension should be 192 pixels) + - [xhdpi](app/src/main/res/drawable-xhdpi) (typically 256 x 256 pixels, for rectangular ones, smaller dimension should be 256 pixels) + - [xxhdpi](app/src/main/res/drawable-xxhdpi) (typically 384 x 384 pixels, for rectangular ones, smaller dimension should be 384 pixels) Each of these folders should hold the same image resized to a different resolution. While testing various images it is enough to put one into any of the folders. From 1b8a2f8a4e703060f1773e61a9ac717d6282143b Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 7 Feb 2022 20:50:58 +0100 Subject: [PATCH 037/181] fix syntax --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 50a2ad48d6..1c97ad3aaa 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -42,7 +42,7 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n + this creates a copy of StreetComplete repository that you control and can prepare code there - clone your fork of a StreetComplete repository - open StreetComplete in Android Studio -- [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also []connect to a real device via USB](https://developer.android.com/studio/run/device), this can replace using the emulator) +- [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also [connect to a real device via USB](https://developer.android.com/studio/run/device), this can replace using the emulator) - run StreetComplete in the emulator (to verify that everything was setup as required) If you are doing it for the first time, don't worry if there is an error to solve along the way, this is typical for setting up an Android development environment. See [CONTRIBUTING file](CONTRIBUTING.md#development) which has some links to information about the setup. From 3bbb68ebd64e766ed95dccc130f3fad1683696c0 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 8 Feb 2022 07:35:25 +0100 Subject: [PATCH 038/181] add one more hint --- CONTRIBUTING_A_NEW_QUEST.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 1c97ad3aaa..f3003318b3 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -89,6 +89,12 @@ Search for this identifier in `*.kt` files, it should appear in the quest file ( This method can often be used to locate relevant code. +### Hints for looking around code + +Full text search (ctrl+shift+f or grepping) remains useful and powerful. + +But "Find usages" (alt+F7) is also a very powerful way to find where given function/constant/property/etc is appearing, classified by usages. + ## Pull requests One of the better ways to get around a codebase new to you is to look at recent accepted proposals to change code (pull requests). From 9ae7d70f93ee3af98556f0b2c73268f140a11317 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 8 Feb 2022 07:36:28 +0100 Subject: [PATCH 039/181] update to a new syntax --- CONTRIBUTING_A_NEW_QUEST.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index f3003318b3..949cab290f 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -215,19 +215,20 @@ With form defined in [AddBridgeStructureForm](app/src/main/java/de/westnordost/s } ``` -This code is responsible for modifying `StringMapChangesBuilder` object (passed by reference). +This code is responsible for modifying `tags` object (passed by reference). + +In this case it would set `indoor` tag to have either `yes` or `no` answer, depending on selection in the quest interface. Actions may include (examples from various quests): -TODO update to the new syntax -- `changes.add("indoor", answer.toYesNo())` - adds a new tag, it must not be present already -- `changes.addOrModify("material", newMaterial)` - add a new tag if missing, override existing value if present -- `changes.modify("sport", values)` - modify existing tag, value must be present -- `changes.delete("amenity")` - remove key that must be present -- `changes.deleteIfExists("stile")` - remove key if present -- `changes.updateWithCheckDate("lit", answer.toYesNo())` - acts as `addOrModify` but will also update survey date and can be used in cases where tag value is not changing +- `tags["indoor"] = answer.toYesNo()` +- `tags.remove("amenity")` - remove key if it is present +- `tags.updateWithCheckDate("lit", answer.toYesNo())` + - in case of changing value such change will be applied + - in case of value being the same also add survey date tag and can be used in cases where tag value is not changing, it would be `check_date:lit=` in this case + - survey date prefix is defined as `[const val SURVEY_MARK_KEY = "check_date"](src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt)` + - always update survey tag if present alreadt -See other ones defined in [StringMapChangesBuilder.kt](de/westnordost/streetcomplete/data/osm/edits/update_tags/StringMapChangesBuilder.kt) ### Extras From 0349da732def995f2fbc6ac161e086eb84541c22 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 8 Feb 2022 07:39:18 +0100 Subject: [PATCH 040/181] add links in requirements --- CONTRIBUTING_A_NEW_QUEST.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 949cab290f..a438718982 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -29,9 +29,9 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n - time - Android Studio setup is sadly complicated - Multiple hours are typical, though mostly spent on waiting for various downloads - setting up Android Studio will likely be more complex than writing the code -- basic ability to use git (but as mentioned, anything GitHub specific will be explained) -- GitHub account -- around 15GB of free space +- [basic ability to use git](https://git-scm.com/docs/user-manual) (but as mentioned, anything GitHub specific will be explained) +- GitHub [account](https://github.com/signup) +- around 15GB of free space on disk - the initial setup will typically download half of the Internet while getting emulators and dependencies # Dependencies - initial setup From ca4fa59f52992abb7b614c324dc0edc7affae5b9 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 8 Feb 2022 08:03:15 +0100 Subject: [PATCH 041/181] extra info and warnings, grammar fixes --- CONTRIBUTING_A_NEW_QUEST.md | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index a438718982..d4510f1e71 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -1,4 +1,4 @@ -This file describes in detail process of creating a new quest. +This file describes in detail the process of creating a new quest. For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#development). @@ -37,8 +37,8 @@ Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/n # Dependencies - initial setup - install necessary software ([Android Studio](https://developer.android.com/studio) and [git](https://git-scm.com/downloads)) -- create GitHub account if needed -- visit [https://github.com/streetcomplete/StreetComplete](https://github.com/streetcomplete/StreetComplete) and press "fork" button on top right +- create a GitHub [account](https://github.com/signup) if needed +- visit [https://github.com/streetcomplete/StreetComplete](https://github.com/streetcomplete/StreetComplete) and press the "fork" button on the top right + this creates a copy of StreetComplete repository that you control and can prepare code there - clone your fork of a StreetComplete repository - open StreetComplete in Android Studio @@ -57,7 +57,7 @@ You can also look at [quest proposals waiting for implementation](https://github # Prepare repository for development -That is a good moment create a branch and switch to it. It can be done with the following command: +That is a good moment to create a branch and switch to it. It can be done with the following command: `git checkout -b short_branch_name_describing_planned_work` @@ -72,12 +72,12 @@ Are you trying to implement a quest that will affect roads and paths? Take `AddW Is it going to be asked for POIs and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. -Quests are defined in [their own folder](app/src/main/java/de/westnordost/streetcomplete/quests). +Quests are grouped in [one folder](app/src/main/java/de/westnordost/streetcomplete/quests). ### Locating a quest -Search across the code for part of a question or other text characteristic to this quest. For example "What is the name of this place". +Search across the code for part of a question or other text specific to this quest. For example "What is the name of this place". You will find an XML file with an entry looking like this: @@ -103,7 +103,7 @@ This is also likely useful here. Find some [recent ones](https://github.com/streetcomplete/StreetComplete/pulls?q=is%3Apr+is%3Aclosed) adding a quest. -You can look at what was changed to achieve the goal, where relevant code is located. How much coding was needed to implement something. And what kind of comments are typical, how long one needs to wait for maintainers and so on. +You can look at what was changed to achieve the goal, where relevant code is located. How much coding was needed to implement something? And what kind of comments are typical, how long one needs to wait for maintainers and so on. This can be also used to locate relevant code, especially helpful if some change needs to be done in multiple files. @@ -254,11 +254,11 @@ A new icon can reuse the content of [other quest icons](res/graphics/quest), it Keep similar style to existing ones and app in general. Once the quest icon is ready: -- save as "Plain svg" or clean SVG file from unnecessary cruft in another way, like using [svgo](https://github.com/svg/svgo) +- save as "Plain SVG" or clean SVG file from unnecessary cruft in another way, like using [svgo](https://github.com/svg/svgo) - Put SVG into `[res/graphics/quest](res/graphics/quest)` folder - SVG is a standard format editable in various software, unlike internal Android Studio XML that will be produced in the next step. - Open Android Studio -- Right click on "app" folder in the Project tool window (top left) +- Right click on the "app" folder in the Project tool window (top left) - Select new → vector asset - Select your SVG file - Name with `ic_quest_` prefix (something like `ic_quest_traffic_calming`), this will cause IDE to generate an XML file @@ -269,7 +269,7 @@ Keep similar style to existing ones and app in general. Once the quest icon is r The same method applies also to other vector drawables, although they will be placed in other parts of [res/graphics/](res/graphics/) -Inkscape is a typical tool to create and edit SVG files, it is a good, free and open-source so is available to all. +Inkscape is a typical tool to create and edit SVG files, it is good, free and open-source so is available to all. # Test @@ -281,14 +281,18 @@ Typically it is done using an emulator. Note that you can set location in emulat * Look at the quest list in settings - is your quest appearing there? If not - see [this step](#Add quest to the list of active ones). * While you are there you can disable all quests except yours for easier testing. * Is it shown for expected elements? + * Note that due to emulator peculiarities you may need to move map after quests are downloaded to see their markers ([gory details for curious](https://github.com/streetcomplete/StreetComplete/issues/2780)) * Is it selected for some unwanted elements? -* Can you tap on quest marker to open quest form? +* Can you tap on a quest marker to open quest form? * Can you fill the answer as expected? * Can you solve the quest? * Is expected tagging being applied? -** You can look at logs for info what was applied or use undo menu from bottom-left. -** You can freely answer - as long as you are not logged in, nothing will be submitted. Even after logging in you can disable uploading answers. + * You can look at logs for info what was applied or use undo menu from bottom-left in the app itself. + * You can freely answer - as long as you are not logged in, nothing will be submitted. Even after logging in you can disable uploading answers in settings. * Is quest disappearing after being solved? + * If no - then either tags are not being applied or element selection filter have some problems. + +See "logcat" (bottom left area of the screen) to see stacktrace or logging messages. # Open a pull request From 571648d9f258d35c0917259e6d858e36336261cb Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 14 Feb 2022 18:33:26 +0100 Subject: [PATCH 042/181] fix pixels claims --- CONTRIBUTING_A_NEW_QUEST.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index d4510f1e71..f5c51fd6dc 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -390,10 +390,10 @@ In StreetComplete many images have unusual composition. Often it is necessary to Images should be free of visual debris, not misleading. Though it is fine to use an image not strictly matching what is depicted, as long as it is clear. For example, [a permanent pile of soil blocking road](https://wiki.openstreetmap.org/wiki/Tag:barrier%3Ddebris) is illustrated by a [temporary landslide](https://commons.wikimedia.org/wiki/File:Landslide_on_OR_42S_(46849629014).jpg). This is OK as images are illustrative. Photos go to a different folder than SVGs: they can be used directly by the build process so put them into folders - - [mdpi](app/src/main/res/drawable-mdpi) (typically 128 x 128 pixels, for rectangular ones, smaller dimension should be 128 pixels) - - [hdpi](app/src/main/res/drawable-hdpi) (typically 192 x 192 pixels, for rectangular ones, smaller dimension should be 192 pixels) - - [xhdpi](app/src/main/res/drawable-xhdpi) (typically 256 x 256 pixels, for rectangular ones, smaller dimension should be 256 pixels) - - [xxhdpi](app/src/main/res/drawable-xxhdpi) (typically 384 x 384 pixels, for rectangular ones, smaller dimension should be 384 pixels) + - [mdpi](app/src/main/res/drawable-mdpi) - 384 pixels for images, with three square images in each row it would be 128 x 128 pixels for each) + - [hdpi](app/src/main/res/drawable-hdpi) - 576 pixels for images (192 x 192 pixels in case of three quare images in each row) + - [xhdpi](app/src/main/res/drawable-xhdpi) 768 pixels for images (256 x 256 pixels in case of three quare images in each row) + - [xxhdpi](app/src/main/res/drawable-xxhdpi) 1152 pixels (384 x 384 pixels in case of three quare images in each row) Each of these folders should hold the same image resized to a different resolution. While testing various images it is enough to put one into any of the folders. From 4cb26d8e57a7fc30ab7a6ad3abf40a1c2ffc2595 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 14 Feb 2022 18:33:38 +0100 Subject: [PATCH 043/181] add terminating newline --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index f5c51fd6dc..5d81f73088 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -421,4 +421,4 @@ It is possible to share and reuse [information about tagging schemes](https://gi Even more complex ones using different class bases are possible. Such as what was needed by the [address quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/address/AddAddressStreet.kt) or the [crossing quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/crossing/AddCrossing.kt) but it is better to start from something simpler. -It allows it to make complex geometry checks, but writing them is also far more complex. \ No newline at end of file +It allows it to make complex geometry checks, but writing them is also far more complex. From 06de271c90de395aca02a3970765c8844a15fa04 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 14 Feb 2022 18:35:57 +0100 Subject: [PATCH 044/181] implement suggestion --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 5d81f73088..c2c8650da4 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -68,7 +68,7 @@ Base the new quest on one that exists already. Find one that has the same type of interface as the one that you are trying to implement. -Are you trying to implement a quest that will affect roads and paths? Take `AddWayLit` quest as a base if it will be a yes/no question. `AddTracktype` where the mapper will be selecting one of the images. +Are you trying to implement a quest that will affect roads and paths? Take `AddWayLit` quest as a base if it will be a yes/no question or `AddTracktype` where the mapper will be selecting one of the images. Is it going to be asked for POIs and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. From d93f5a2c5c0a4b98e4ccc7cb05d920bac79ba453 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 14 Feb 2022 18:40:54 +0100 Subject: [PATCH 045/181] shorten text and remove duplicate --- CONTRIBUTING_A_NEW_QUEST.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index c2c8650da4..095aabfc37 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -4,20 +4,12 @@ For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#d If you want to contribute code to StreetComplete, then making a new quest is one of the easiest programming tasks. Implementing a quest where the interface design matches an existing one is quite simple. -Contributions like that are highly welcomed and you would make mapping one more thing in OSM much easier! +Contributions like that are highly welcomed and you would make mapping one more thing in OSM much easier! You can implement it also when you never used Kotlin or implemented anything for Android. Being highly experienced programmer is not necessary here. Reading the text below is not necessary to create a new quest - a basic method of duplicating existing ones and modifying them may be sufficient. And people were creating new quests before this documentation existed. But this materials may help or be quicker than trying to fully explore on your own how things work. -# What is not required - -- expert programming ability - you do not need to be an expert programmer to make contributions, basic programming abilities are sufficient to implement a quest similar to existing ones -- any Kotlin-specific or Android-specific knowledge - it is fine if you never did anything with Kotlin or Android -- any GitHub specific knowledge - -Please [open an issue](https://github.com/streetcomplete/StreetComplete/issues/new) if you are stuck despite this. - # Required - programming ability - it is not a good first task for someone who has never programmed anything. From cbb1a81c2e5044e4ad77eac3db3e289c5a72f1e7 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 14 Feb 2022 18:47:05 +0100 Subject: [PATCH 046/181] make description less confusing --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 095aabfc37..9801196d79 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -2,7 +2,7 @@ This file describes in detail the process of creating a new quest. For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#development). -If you want to contribute code to StreetComplete, then making a new quest is one of the easiest programming tasks. Implementing a quest where the interface design matches an existing one is quite simple. +If you want to contribute code to StreetComplete, then making a new quest is one of the easiest programming tasks. It is quite easy to implement a quest where layout design matches an existing quest. For example one more yes/no quest or where user taps one of displayed images. Contributions like that are highly welcomed and you would make mapping one more thing in OSM much easier! You can implement it also when you never used Kotlin or implemented anything for Android. Being highly experienced programmer is not necessary here. From 73ec4a32502252e712aae2676f66d7d08d40dae6 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 14 Feb 2022 18:47:51 +0100 Subject: [PATCH 047/181] fix grammar hopefully fix: --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 9801196d79..8606696206 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -4,7 +4,7 @@ For code style and more general info - see [CONTRIBUTING file](CONTRIBUTING.md#d If you want to contribute code to StreetComplete, then making a new quest is one of the easiest programming tasks. It is quite easy to implement a quest where layout design matches an existing quest. For example one more yes/no quest or where user taps one of displayed images. -Contributions like that are highly welcomed and you would make mapping one more thing in OSM much easier! You can implement it also when you never used Kotlin or implemented anything for Android. Being highly experienced programmer is not necessary here. +Contributions like that are highly welcomed and you would make mapping one more thing in OSM much easier! You can implement it also if you never used Kotlin or implemented anything for Android. Being highly experienced programmer is not necessary here. Reading the text below is not necessary to create a new quest - a basic method of duplicating existing ones and modifying them may be sufficient. And people were creating new quests before this documentation existed. From 36442ef96274d45c516b0f20fc5a7eedcf87dcab Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 14 Feb 2022 18:48:53 +0100 Subject: [PATCH 048/181] less confusing text --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 8606696206..c92351c5c3 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -6,7 +6,7 @@ If you want to contribute code to StreetComplete, then making a new quest is one Contributions like that are highly welcomed and you would make mapping one more thing in OSM much easier! You can implement it also if you never used Kotlin or implemented anything for Android. Being highly experienced programmer is not necessary here. -Reading the text below is not necessary to create a new quest - a basic method of duplicating existing ones and modifying them may be sufficient. And people were creating new quests before this documentation existed. +Reading the text below is not necessary to create a new quest. Duplicating existing quest and modifying its code may be sufficient. And people were creating new quests before this documentation existed. But this materials may help or be quicker than trying to fully explore on your own how things work. From 10379b9de61aed928fb17e32f706bd6fb6859240 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 14 Feb 2022 18:49:33 +0100 Subject: [PATCH 049/181] shorter text --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index c92351c5c3..80ac133747 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -12,7 +12,7 @@ But this materials may help or be quicker than trying to fully explore on your o # Required -- programming ability - it is not a good first task for someone who has never programmed anything. +- programming ability - it is not a good task for someone who has never programmed anything. - Setup of environment takes a long time - Editing even the simplest quest requires edits to at least two different files - Kotlin familiarity is not required, but the ability to adjust to a new syntax is needed From ea584bff46f12e87dac463f15e9d60dc28e72536 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 14 Feb 2022 19:12:32 +0100 Subject: [PATCH 050/181] mention git integration --- CONTRIBUTING_A_NEW_QUEST.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 80ac133747..fe489d381b 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -22,6 +22,7 @@ But this materials may help or be quicker than trying to fully explore on your o - Multiple hours are typical, though mostly spent on waiting for various downloads - setting up Android Studio will likely be more complex than writing the code - [basic ability to use git](https://git-scm.com/docs/user-manual) (but as mentioned, anything GitHub specific will be explained) + - Go to File -> Settings -> Version control in Android Studio to optionally configure git integration - GitHub [account](https://github.com/signup) - around 15GB of free space on disk - the initial setup will typically download half of the Internet while getting emulators and dependencies From 96d8cad5eabdb2aacf509c01e50a480b074cb42b Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 14 Feb 2022 19:13:20 +0100 Subject: [PATCH 051/181] mention terminal --- CONTRIBUTING_A_NEW_QUEST.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index fe489d381b..8c97a0ad04 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -23,6 +23,7 @@ But this materials may help or be quicker than trying to fully explore on your o - setting up Android Studio will likely be more complex than writing the code - [basic ability to use git](https://git-scm.com/docs/user-manual) (but as mentioned, anything GitHub specific will be explained) - Go to File -> Settings -> Version control in Android Studio to optionally configure git integration + - Using git from command line or terminal in Android Studio also works fine - GitHub [account](https://github.com/signup) - around 15GB of free space on disk - the initial setup will typically download half of the Internet while getting emulators and dependencies From dcf4ddca805ff8a482f01d4c5bfa91f73570454e Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 14 Feb 2022 19:18:19 +0100 Subject: [PATCH 052/181] it is a bit nastier to setup, it turns out --- CONTRIBUTING_A_NEW_QUEST.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 8c97a0ad04..e79f7fa188 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -22,7 +22,9 @@ But this materials may help or be quicker than trying to fully explore on your o - Multiple hours are typical, though mostly spent on waiting for various downloads - setting up Android Studio will likely be more complex than writing the code - [basic ability to use git](https://git-scm.com/docs/user-manual) (but as mentioned, anything GitHub specific will be explained) - - Go to File -> Settings -> Version control in Android Studio to optionally configure git integration + - there is version control integration available in Android Studio + - From the Android Studio **VCS** menu, click **Enable Version Control** Integration ([see official docs](https://developer.android.com/studio/intro#version_control_basics) + - Go to File -> Settings -> Version control in Android Studio to optionally configure git integration - Using git from command line or terminal in Android Studio also works fine - GitHub [account](https://github.com/signup) - around 15GB of free space on disk From d9913e80812ea4e90acfd20a22aabe65aae11e06 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 12:06:07 +0100 Subject: [PATCH 053/181] fix broken links --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index e79f7fa188..795a5eb2e3 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -119,7 +119,7 @@ In copied code change package info (things like `package de.westnordost.streetco # Add the quest to the list of active ones -Adjust [QuestModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.kt) file. It contains a big list of active quests, ordered by priority. Read [what governs their priority](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/QuestModule.kt#L138-L162) but do not worry too much, it can be tweaked later. +Adjust [QuestsModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt) file. It contains a big list of active quests, ordered by priority. Read [what governs their priority](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt#L169-L192) but do not worry too much, it can be tweaked later. Add your quest to the list so that it will be loaded by the app. From 5baf9874fc90e06bd7c2f93206f22a4ba687d102 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 12:08:41 +0100 Subject: [PATCH 054/181] fix one more dead link --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 795a5eb2e3..f14ff76441 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -236,7 +236,7 @@ Info listed above must be supplied by every quest. But there are also several op which causes nearby `emergency = defibrillator` nodes to be shown (icons used are defined in [PinIcons.kt](app/src/main/java/de/westnordost/streetcomplete/map/PinIcons.kt)) -See [also other optional properties](de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt). +See [also other optional properties](app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt). ### Adding quest icon From b6625df34d336c15868e08204cbb48306776fbcc Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 12:11:06 +0100 Subject: [PATCH 055/181] one more dead link fixed --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index f14ff76441..f09aa0491e 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -81,7 +81,7 @@ You will find an XML file with an entry looking like this: The identifier `quest_placeName_title_name` is a string reference, used in the code to allow translations. -Search for this identifier in `*.kt` files, it should appear in the quest file (in this case [AddPlaceName.kt](src/main/java/de/westnordost/streetcomplete/quests/place_name/AddPlaceName.kt)). +Search for this identifier in `*.kt` files, it should appear in the quest file (in this case [AddPlaceName.kt](app/src/main/java/de/westnordost/streetcomplete/quests/place_name/AddPlaceName.kt)). This method can often be used to locate relevant code. From d748974a6c98ed4cdac35cd680bf3e5de63700b3 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 12:12:30 +0100 Subject: [PATCH 056/181] fix mangled markdown --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index f09aa0491e..b065aebb3b 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -345,7 +345,7 @@ And to add the mechanism supplying this data. Here is [some typical code](https: - `getTitleArgs` tries to pass to the title - name of the object - - brand of the object (only if ``name` tag is not used, and `brand` tag is present) + - brand of the object (only if `name` tag is not used, and `brand` tag is present) - feature type (such as "greengrocer", translated to the proper language, based on [iD presets](https://github.com/westnordost/osmfeatures)) [Filtering in the element selection](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L20) ensures that every object will have either `name` or `brand` tag. @@ -354,7 +354,7 @@ Though description from iD presets is not guaranted. So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either -* `quest_wheelchairAccess_name_type_title` which represents `Is %1$s (%2$s) wheelchair accessible?` (or translation). Note presence of `%1$s` and `%2$s` which will be replaced by text provided by ``getTitleArgs` +* `quest_wheelchairAccess_name_type_title` which represents `Is %1$s (%2$s) wheelchair accessible?` (or translation). Note presence of `%1$s` and `%2$s` which will be replaced by text provided by `getTitleArgs` * In case of no feature type being available `quest_wheelchairAccess_name_title` will be used, with space for one parameter: `Is %s wheelchair accessible?` This is quite complex but allows translating application in various languages by decoupling exact text being displayed from the code. From 19008718b9d7f3e0026f1788168e10f86dd88610 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 12:16:18 +0100 Subject: [PATCH 057/181] try adding anchor link --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index b065aebb3b..5c9a3c5181 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -173,7 +173,7 @@ icon drawable, you can initially use any icon. Do not worry, submissions with placeholder icons are also welcomed! In many cases icon itself was not made by the PR author. -More info about icon handling will be given later. +More info about icon handling [will be given later](#adding-quest-icon). #### questTypeAchievements `override val questTypeAchievements = listOf(LIFESAVER)` @@ -239,7 +239,7 @@ which causes nearby `emergency = defibrillator` nodes to be shown (icons used ar See [also other optional properties](app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt). ### Adding quest icon - + It is OK to submit a quest without own icon, using any icon as a placeholder. But it would be even better to include also icon. From 2c554888e2c47b38486a1d6e1170f40eaa066c4e Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 12:25:17 +0100 Subject: [PATCH 058/181] document geographic restrictions --- CONTRIBUTING_A_NEW_QUEST.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 5c9a3c5181..17d8c2a0b4 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -152,7 +152,7 @@ It is specified as a string, in syntax specific to StreetComplete. You can look #### Hints The rules should be as exclusive as possible to generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. -Also, for very detailed information that can be assumed to always have the same ("undefined") answer in many countries, it might be a good idea to limit quests to an inclusive list of certain countries. +Also, for very detailed information that can be assumed to always have the same ("undefined") answer in many countries, it might be a good idea to [limit quests to certain countries](#enabledInCountries). ### Properties @@ -418,3 +418,11 @@ It is possible to share and reuse [information about tagging schemes](https://gi Even more complex ones using different class bases are possible. Such as what was needed by the [address quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/address/AddAddressStreet.kt) or the [crossing quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/crossing/AddCrossing.kt) but it is better to start from something simpler. It allows it to make complex geometry checks, but writing them is also far more complex. + +## `enabledInCountries` + +Some quests should be enabled only in some countries or disabled in a specific countries. + +[`override val enabledInCountries = NoCountriesExcept("SE")`](app/src/main/java/de/westnordost/streetcomplete/quests/accepts_cash/AddAcceptsCash.kt) - enabled only in Sweden. + +[`override val enabledInCountries = AllCountriesExcept("US", "CA")`](app/src/main/java/de/westnordost/streetcomplete/quests/address/AddHousenumber.kt) - not enabled in USA and Canada From 4ba2eeb27bfcd9ea466fa95343c39142bb218294 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 12:37:14 +0100 Subject: [PATCH 059/181] mention resurvey filter --- CONTRIBUTING_A_NEW_QUEST.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 17d8c2a0b4..e4e009e055 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -149,6 +149,30 @@ This query will be limited to nodes (`nodes with`), which fulfill some requireme It is specified as a string, in syntax specific to StreetComplete. You can look around some quests to see how it works. If you are trying to implement a new quest and you got stuck here, [open a new issue](https://github.com/streetcomplete/StreetComplete/issues) to request more thorough documentation here. +###### Resurvey + +Some quests are asked not only when tag is missing but also when it is likely to be outdated. + +Typical form is like in [quest asking about bicycle parking capacity](/app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_capacity/AddMotorcycleParkingCapacity.kt): + +``` + override val elementFilter = """ + nodes, ways with amenity = motorcycle_parking + and access !~ private|no + and (!capacity or capacity older today -4 years) + """ +``` + +This quest will be triggered when: + + - on nodes and ways + - where `amenity = motorcycle_parking` tag is present + - `access` tag is not set with value `private` or `no` + - `bicycle_parking` is not having value `floor` + - and one of following is fullfilled: + - `capacity` tag is not present at all + - `capacity` tag is older than 4 years (date of last edit of the element and `check_date:capacity` tag will be taken into account) + #### Hints The rules should be as exclusive as possible to generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. From 6dd353784477c0f5cf4da020be2fd38a4c6af2c8 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 12:41:02 +0100 Subject: [PATCH 060/181] better placeholder docs --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index e4e009e055..7e174d0418 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -378,8 +378,8 @@ Though description from iD presets is not guaranted. So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either -* `quest_wheelchairAccess_name_type_title` which represents `Is %1$s (%2$s) wheelchair accessible?` (or translation). Note presence of `%1$s` and `%2$s` which will be replaced by text provided by `getTitleArgs` -* In case of no feature type being available `quest_wheelchairAccess_name_title` will be used, with space for one parameter: `Is %s wheelchair accessible?` +* `quest_wheelchairAccess_name_type_title` which represents `Is %1$s (%2$s) wheelchair accessible?` (or translation). `%1$s` and `%2$s` [placeholders](https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings) will be replaced by text provided by `getTitleArgs` +* In case of no feature type being available `quest_wheelchairAccess_name_title` will be used, with space for one parameter: `Is %s wheelchair accessible?` (`%s` is a single placeholder which will be replaced by text parameter) This is quite complex but allows translating application in various languages by decoupling exact text being displayed from the code. From 935afeb69dbad157021dbc4b201e494ff25869bd Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 12:54:52 +0100 Subject: [PATCH 061/181] fix newlines --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 7e174d0418..eb21551577 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -350,9 +350,9 @@ Below is some additional info. ## getTitle and getTitleArgs In some cases, the quest will mention the name and type of feature. For example, in the case of shops to make their identification possible. -This requires preparing space in the message for filling at runtime, +This requires preparing space in the message for filling at runtime, and to add the mechanism supplying this data. -And to add the mechanism supplying this data. Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L104-L115) that will: +Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L104-L115) that will: ``` override fun getTitle(tags: Map) = From eb2e3b85feccf6df617954d485c120259a469a53 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 17:45:55 +0100 Subject: [PATCH 062/181] switch examples to linked and easier --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index eb21551577..9b6868c07c 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -64,7 +64,7 @@ Base the new quest on one that exists already. Find one that has the same type of interface as the one that you are trying to implement. -Are you trying to implement a quest that will affect roads and paths? Take `AddWayLit` quest as a base if it will be a yes/no question or `AddTracktype` where the mapper will be selecting one of the images. +Are you trying to implement a quest that will affect roads and paths? Take [`AddIsDefibrillatorIndoor`](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt) quest as a base if it will be a yes/no question or [`AddTracktype`](app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_type/AddBikeParkingTypeForm.kt) where the mapper will be selecting one of the images. Is it going to be asked for POIs and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. From 55cfc10ef9091c536436944d9b90a5855ab4dab8 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 17:53:51 +0100 Subject: [PATCH 063/181] add extra hints maybe too many of them? --- CONTRIBUTING_A_NEW_QUEST.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 9b6868c07c..d413270936 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -15,7 +15,7 @@ But this materials may help or be quicker than trying to fully explore on your o - programming ability - it is not a good task for someone who has never programmed anything. - Setup of environment takes a long time - Editing even the simplest quest requires edits to at least two different files - - Kotlin familiarity is not required, but the ability to adjust to a new syntax is needed + - Kotlin familiarity is not required, but the ability to adjust to a new syntax is needed. If you are unfamiliar with Kotlin reading about [null safety related syntax](https://kotlinlang.org/docs/null-safety.html) is likely to be very useful. - It is expected that someone trying this can search for a solution to a typical problem on encountering an error message - familiarity with StreetComplete as a user - it is highly recommended to be familiar with how StreetComplete works. Making hundreds of edits is not mandatory, but having a passing familiarity with how surveying with StreetComplete works is needed. - time - Android Studio setup is sadly complicated @@ -383,6 +383,11 @@ So `getTitle` function that returns identifier to text in [strings file](app/src This is quite complex but allows translating application in various languages by decoupling exact text being displayed from the code. +### Kotlin +Article about [null safety related syntax](https://kotlinlang.org/docs/null-safety.html) is likely to be very useful, especially if you are confused by `?:` [Elvis operator](https://kotlinlang.org/docs/null-safety.html#elvis-operator). + +`arrayOfNotNull` is a minor helper function [defined in StreetComplete](app/src/main/java/de/westnordost/streetcomplete/ktx/Collections.kt). Note that when you open code in Android Studio or other IDE you can easily go to place where given function is defined. + ## Designing the form As mentioned, the user interface must leave no space for misunderstandings, it must be concise and quick and easy to use. Also sounds obvious, but you will quickly find out that a balance must be found between covering all the edge cases and designing the form to be as straightforward and clutterless as possible. From 4eeae3ff6016a4f5a06f90c15a744dbeaad448e8 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 17:55:14 +0100 Subject: [PATCH 064/181] unify with function name --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index d413270936..185adc26b4 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -370,7 +370,7 @@ Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blo - `getTitleArgs` tries to pass to the title - name of the object - brand of the object (only if `name` tag is not used, and `brand` tag is present) - - feature type (such as "greengrocer", translated to the proper language, based on [iD presets](https://github.com/westnordost/osmfeatures)) + - feature name (such as "greengrocer", translated to the proper language, based on [iD presets](https://github.com/westnordost/osmfeatures)) [Filtering in the element selection](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L20) ensures that every object will have either `name` or `brand` tag. From 554dddcd7e8a461698e827a2d2cfe6ce9c9f2586 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 18:27:35 +0100 Subject: [PATCH 065/181] include more basic example for title parameters fixes https://github.com/matkoniecz/Zazolc/issues/5 --- CONTRIBUTING_A_NEW_QUEST.md | 47 +++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 185adc26b4..1922e99be3 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -348,9 +348,46 @@ What was described above is an attempt to cover all aspects of quest creation, w Below is some additional info. ## getTitle and getTitleArgs -In some cases, the quest will mention the name and type of feature. For example, in the case of shops to make their identification possible. -This requires preparing space in the message for filling at runtime, and to add the mechanism supplying this data. +In some cases it is desirable to change quest title, based on specific object. + +This requires preparing space in the message for filling at runtime, and to add the mechanism supplying data to replace placeholders. + +### Display value of tag if it is present + +[AddFireHydrantDiameter](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/fire_hydrant_diameter/AddFireHydrantDiameter.kt) displays `ref` code of hydrant, if tagged. + +``` + override fun getTitleArgs(tags: Map, featureName: Lazy): Array = + arrayOfNotNull(tags["ref"]) + + override fun getTitle(tags: Map): Int { + val hasRef = tags.containsAnyKey("ref") + return when { + hasRef -> R.string.quest_fireHydrant_diameter_ref_title + else -> R.string.quest_fireHydrant_diameter_title + } + } +``` + +``getTitleArgs` will return either array with single element containing value of `ref` tag or an empty array. In either cases it will be passed to code displaying title at runtime. + +`arrayOfNotNull` is a minor helper function [defined in StreetComplete](app/src/main/java/de/westnordost/streetcomplete/ktx/Collections.kt). Note that when you open code in Android Studio or other IDE you can easily go to place where given function is defined. + +``getTitle` provide identifier of text which will be + +So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either + + +* `quest_fireHydrant_diameter_ref_title` which represents `What diameter is specified on the sign for this fire hydrant? (reference number: %s)` (or translation). `%s` is a [placeholder](https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings) and will be replaced by text provided by `getTitleArgs` +* In case of ref tag being not present `quest_fireHydrant_diameter_title` (`What diameter is specified on the sign for this fire hydrant?` will be used. + +This is quite complex but allows translating application in various languages by decoupling exact text being displayed from the code. See for example identifiers with texts in [Polish translation](app/src/main/res/values-pl/strings.xml). + +### Use feature name if present +In some cases, the quest will mention the name of object (lets say "Knight") and type of feature (maybe restaurant? Or supermarket?). + +For example, in the case of shops it may be necessary to identify specific one among several. Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L104-L115) that will: @@ -379,15 +416,11 @@ Though description from iD presets is not guaranted. So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either * `quest_wheelchairAccess_name_type_title` which represents `Is %1$s (%2$s) wheelchair accessible?` (or translation). `%1$s` and `%2$s` [placeholders](https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings) will be replaced by text provided by `getTitleArgs` -* In case of no feature type being available `quest_wheelchairAccess_name_title` will be used, with space for one parameter: `Is %s wheelchair accessible?` (`%s` is a single placeholder which will be replaced by text parameter) - -This is quite complex but allows translating application in various languages by decoupling exact text being displayed from the code. +* In case of no feature name being available `quest_wheelchairAccess_name_title` will be used, with space for one parameter: `Is %s wheelchair accessible?` (`%s` is a single placeholder which will be replaced by text parameter) ### Kotlin Article about [null safety related syntax](https://kotlinlang.org/docs/null-safety.html) is likely to be very useful, especially if you are confused by `?:` [Elvis operator](https://kotlinlang.org/docs/null-safety.html#elvis-operator). -`arrayOfNotNull` is a minor helper function [defined in StreetComplete](app/src/main/java/de/westnordost/streetcomplete/ktx/Collections.kt). Note that when you open code in Android Studio or other IDE you can easily go to place where given function is defined. - ## Designing the form As mentioned, the user interface must leave no space for misunderstandings, it must be concise and quick and easy to use. Also sounds obvious, but you will quickly find out that a balance must be found between covering all the edge cases and designing the form to be as straightforward and clutterless as possible. From 4e6111d708cb59cc173b0045fec07bb6e2c159b0 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 18:30:36 +0100 Subject: [PATCH 066/181] Describe how to log https://github.com/matkoniecz/Zazolc/issues/8 --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 1922e99be3..5936a0d941 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -314,6 +314,10 @@ Typically it is done using an emulator. Note that you can set location in emulat See "logcat" (bottom left area of the screen) to see stacktrace or logging messages. +## Adding logs + +`Log.w("Unique string for easy grepping in logcat", "Message with whatever you need like #${someVariable.itsProperty}")` + # Open a pull request [Pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) is a submission of proposed changes to the source code. From bf770c353328e36cdbac4b586d17c02ada047901 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:02:40 +0100 Subject: [PATCH 067/181] fix links --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 5936a0d941..4882122314 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -46,7 +46,7 @@ If you are doing it for the first time, don't worry if there is an error to solv # Invent a new quest ## Own ideas -To [repeat](https://github.com/streetcomplete/StreetComplete/blob/master/CONTRIBUTING.md#developing-new-quests) from that documentation file: [**open an issue** discussing the quest](#suggesting-new-quests), before starting other work. This way it can be confirmed that such quest can be included. This can be skipped if you are an [experienced](https://github.com/streetcomplete/StreetComplete/discussions/3450) StreetComplete contributor. +To [repeat](CONTRIBUTING.md#developing-new-quests) from that documentation file: [**open an issue** discussing the quest](CONTRIBUTING.md#developing-new-quests), before starting other work. This way it can be confirmed that such quest can be included. This can be skipped if you are an [experienced](https://github.com/streetcomplete/StreetComplete/discussions/3450) StreetComplete contributor. ## Existing proposals You can also look at [quest proposals waiting for implementation](https://github.com/streetcomplete/StreetComplete/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+quest%22). From c5c63d797c64231bb2d8c954bec826e31d25b122 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:13:28 +0100 Subject: [PATCH 068/181] better match for links --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 4882122314..ec989a5745 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -64,7 +64,7 @@ Base the new quest on one that exists already. Find one that has the same type of interface as the one that you are trying to implement. -Are you trying to implement a quest that will affect roads and paths? Take [`AddIsDefibrillatorIndoor`](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt) quest as a base if it will be a yes/no question or [`AddTracktype`](app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_type/AddBikeParkingTypeForm.kt) where the mapper will be selecting one of the images. +Are you trying to implement a quest that will have simple yes/no answer? Take [`AddIsDefibrillatorIndoor`](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt) quest as a base. Or [`AddTracktype`](app/src/main/java/de/westnordost/streetcomplete/quests/tracktype/AddTracktype.kt) where the mapper will be selecting one of the images. Is it going to be asked for POIs and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. From 764ed1bf8fee730f77bbf67679c5204294ef42f4 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:15:37 +0100 Subject: [PATCH 069/181] nicer formatting --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index ec989a5745..f0b39624ed 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -144,7 +144,7 @@ elementFilter property defines nodes, ways and relations which will be selected This query will be limited to nodes (`nodes with`), which fulfill some requirements. - `emergency = defibrillator` tag must be present -- `access` tag must not have values `private` or `no` to skip ones where mapper will be unable to survey (`!~ private|no` - to be more specific optionA|optionB is treated like `^optionA|optionB$` regexp) +- `access` tag must not have values `private` or `no` to skip ones where mapper will be unable to survey (`!~ private|no` - to be more specific `optionA|optionB` is treated like `^optionA|optionB$` regexp) - `indoor` key must not be present at all, to show only ones where this tag is still missing It is specified as a string, in syntax specific to StreetComplete. You can look around some quests to see how it works. If you are trying to implement a new quest and you got stuck here, [open a new issue](https://github.com/streetcomplete/StreetComplete/issues) to request more thorough documentation here. From 68c47233f1ae39432f2a5fa04084d86be49f6296 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:16:25 +0100 Subject: [PATCH 070/181] nicer grammar --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index f0b39624ed..d0f9c58ea7 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -153,7 +153,7 @@ It is specified as a string, in syntax specific to StreetComplete. You can look Some quests are asked not only when tag is missing but also when it is likely to be outdated. -Typical form is like in [quest asking about bicycle parking capacity](/app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_capacity/AddMotorcycleParkingCapacity.kt): +Typical code is in [quest asking about bicycle parking capacity](/app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_capacity/AddMotorcycleParkingCapacity.kt): ``` override val elementFilter = """ From 952ecc8347f57f2f2c435b6cf1fcb4757c55577d Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:16:46 +0100 Subject: [PATCH 071/181] fix link root --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index d0f9c58ea7..6369959196 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -153,7 +153,7 @@ It is specified as a string, in syntax specific to StreetComplete. You can look Some quests are asked not only when tag is missing but also when it is likely to be outdated. -Typical code is in [quest asking about bicycle parking capacity](/app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_capacity/AddMotorcycleParkingCapacity.kt): +Typical code is in [quest asking about bicycle parking capacity](app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_capacity/AddMotorcycleParkingCapacity.kt): ``` override val elementFilter = """ From 594303f49fecd64bf0f0157858b0a35a703e73db Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:17:42 +0100 Subject: [PATCH 072/181] fix link --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 6369959196..3fd096ef23 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -153,7 +153,7 @@ It is specified as a string, in syntax specific to StreetComplete. You can look Some quests are asked not only when tag is missing but also when it is likely to be outdated. -Typical code is in [quest asking about bicycle parking capacity](app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_capacity/AddMotorcycleParkingCapacity.kt): +Typical code is in [quest asking about motorcycle parking capacity](app/src/main/java/de/westnordost/streetcomplete/quests/motorcycle_parking_capacity/AddMotorcycleParkingCapacity.kt): ``` override val elementFilter = """ From e6091e1fa83e163ffbe3af67ee2e0078bb398b9c Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:20:41 +0100 Subject: [PATCH 073/181] rewrite text for clarity --- CONTRIBUTING_A_NEW_QUEST.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 3fd096ef23..ddff9365dd 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -171,7 +171,8 @@ This quest will be triggered when: - `bicycle_parking` is not having value `floor` - and one of following is fullfilled: - `capacity` tag is not present at all - - `capacity` tag is older than 4 years (date of last edit of the element and `check_date:capacity` tag will be taken into account) + - element was not edited for a long time (base time is 4 years, but it can by influenced by user changing settings) + - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) #### Hints The rules should be as exclusive as possible to generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. From 30fbf73a616eda1459d702c48fe24f64be4fa740 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:21:32 +0100 Subject: [PATCH 074/181] be more explicit --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index ddff9365dd..019395ce69 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -170,7 +170,7 @@ This quest will be triggered when: - `access` tag is not set with value `private` or `no` - `bicycle_parking` is not having value `floor` - and one of following is fullfilled: - - `capacity` tag is not present at all + - `capacity` tag is not present at all (`!capacity`) - element was not edited for a long time (base time is 4 years, but it can by influenced by user changing settings) - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) From d61ebd7db5131a11f9278fa30eb8ec44d7fa1d57 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:22:12 +0100 Subject: [PATCH 075/181] drop remains of an old example --- CONTRIBUTING_A_NEW_QUEST.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 019395ce69..594a75d99a 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -168,7 +168,6 @@ This quest will be triggered when: - on nodes and ways - where `amenity = motorcycle_parking` tag is present - `access` tag is not set with value `private` or `no` - - `bicycle_parking` is not having value `floor` - and one of following is fullfilled: - `capacity` tag is not present at all (`!capacity`) - element was not edited for a long time (base time is 4 years, but it can by influenced by user changing settings) From c61880aa4420a274ce7a42ecb741c82f2872ff46 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:23:42 +0100 Subject: [PATCH 076/181] simplify text --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 594a75d99a..a117a24756 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -174,7 +174,7 @@ This quest will be triggered when: - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) #### Hints -The rules should be as exclusive as possible to generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. +The rules should generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. Also, for very detailed information that can be assumed to always have the same ("undefined") answer in many countries, it might be a good idea to [limit quests to certain countries](#enabledInCountries). From 6cb3ec36a6c688f06b1d60b62d524cf62c48ee82 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:24:37 +0100 Subject: [PATCH 077/181] reduce unneded content --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index a117a24756..ad89196e59 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -174,9 +174,9 @@ This quest will be triggered when: - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) #### Hints -The rules should generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. +The rules should generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. -Also, for very detailed information that can be assumed to always have the same ("undefined") answer in many countries, it might be a good idea to [limit quests to certain countries](#enabledInCountries). +In some cases it will be a good idea to [limit quests to certain countries](#enabledInCountries). ### Properties From 87961e643e52efb8173e64d86c7bfca94ae707f8 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:28:01 +0100 Subject: [PATCH 078/181] remove copy-paste accident remains --- CONTRIBUTING_A_NEW_QUEST.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index ad89196e59..79c7f78f7e 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -206,7 +206,6 @@ In quest achievements, list what is relevant to the given quest, see the full li #### getTitle `override fun getTitle(tags: Map) = R.string.quest_is_defibrillator_inside_title` -` override fun createForm() = YesNoQuestAnswerFragment()` It is a message displayed to user, code here passes a [reference](https://developer.android.com/guide/topics/resources/string-resource) to the string. You can change it to the new, not yet existing one and use a built in tool to place text. From 1845c3781a1675ab1718559889e8216a8bb2983d Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:30:53 +0100 Subject: [PATCH 079/181] simplify text --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 79c7f78f7e..f2f6079784 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -211,7 +211,7 @@ It is a message displayed to user, code here passes a [reference](https://develo Actual strings sit in [app/src/main/res/values/strings.xml](app/src/main/res/values/strings.xml) -There are additional files with text, but the text is translated with a completely separately workflow and your changes will only modify this file, leaving other text files untouched. +There are separate files with translated text, but do not worry about it - [translations are handled separately](CONTRIBUTING.md#translating-the-app). #### Form @@ -329,7 +329,7 @@ You can see [already submitted pull requests](https://github.com/streetcomplete/ # Future -After opening a pull request it will be reviewed and you will likely be asked to make some changes. This is normal and also happens with pull requests submitted by experienced contributors. +After opening a pull request it will be reviewed and you will be likely asked to make some changes. This is normal and also happens with pull requests submitted by experienced contributors. Changes typically include improving code style, tweaking phrasing and quest settings. From 2182e03d9c766a7f109577ac77774a4d79c8cd53 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:33:26 +0100 Subject: [PATCH 080/181] better describe PR flow --- CONTRIBUTING_A_NEW_QUEST.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index f2f6079784..967543fe3f 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -335,7 +335,9 @@ Changes typically include improving code style, tweaking phrasing and quest sett You are also welcome to help with reviewing other PRs - different people have different strengths, there are active reviewers who help with code style, there are some native speakers of English, some with deep knowledge of OSM tagging schemes or deep knowledge of how StreetComplete works. -After the PR is finished it will be merged before the beta release of the next version. This way it can be additionally tested with a wider audience before release to all and translators can [translate text into other languages](CONTRIBUTING.md#translating-the-app). +In case that pull requests appears to be ready, it will be marked as approved and wait for merge. + +After the PR is finished it will be merged before the beta release of the next version. This way it can be additionally tested with a wider audience before release to all and translators have time to [translate text into other languages](CONTRIBUTING.md#translating-the-app). After full release it will reach the entire StreetComplete audience who now will be able to more easily contribute to OpenStreetMap. Thanks in advance for that! From c57afb1b7bedbb61110fa629094e07b1386575d5 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:40:17 +0100 Subject: [PATCH 081/181] simplify --- CONTRIBUTING_A_NEW_QUEST.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 967543fe3f..e5010b4e6a 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -244,7 +244,8 @@ Actions may include (examples from various quests): - `tags.remove("amenity")` - remove key if it is present - `tags.updateWithCheckDate("lit", answer.toYesNo())` - in case of changing value such change will be applied - - in case of value being the same also add survey date tag and can be used in cases where tag value is not changing, it would be `check_date:lit=` in this case + - in case of value being the same: add survey date tag, it would be `check_date:lit=` in this case + - so can be used even if value will stay the same - possible for resurvey quests - survey date prefix is defined as `[const val SURVEY_MARK_KEY = "check_date"](src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt)` - always update survey tag if present alreadt From 38b8c5c6f84b7281fa41239dbdba7eea5c0bb6ac Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:40:58 +0100 Subject: [PATCH 082/181] fix formatting --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index e5010b4e6a..12ae3cb3ed 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -246,8 +246,8 @@ Actions may include (examples from various quests): - in case of changing value such change will be applied - in case of value being the same: add survey date tag, it would be `check_date:lit=` in this case - so can be used even if value will stay the same - possible for resurvey quests - - survey date prefix is defined as `[const val SURVEY_MARK_KEY = "check_date"](src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt)` - - always update survey tag if present alreadt + - survey date prefix is defined as [`const val SURVEY_MARK_KEY = "check_date"`](src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt) + - always update survey tag if present already ### Extras From 4cb95f91d3b84d0ce6afd75ada5845e57db0f6e2 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:42:38 +0100 Subject: [PATCH 083/181] fix misplaced code marks --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 12ae3cb3ed..6e8506c1d6 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -275,7 +275,7 @@ A new icon can reuse the content of [other quest icons](res/graphics/quest), it Keep similar style to existing ones and app in general. Once the quest icon is ready: - save as "Plain SVG" or clean SVG file from unnecessary cruft in another way, like using [svgo](https://github.com/svg/svgo) -- Put SVG into `[res/graphics/quest](res/graphics/quest)` folder +- Put SVG into [`res/graphics/quest`](res/graphics/quest) folder - SVG is a standard format editable in various software, unlike internal Android Studio XML that will be produced in the next step. - Open Android Studio - Right click on the "app" folder in the Project tool window (top left) From 8eb5934fc52fb43778a8a7a8eaf86d2443a17f6f Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:43:32 +0100 Subject: [PATCH 084/181] fix technically wrong sentence --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 6e8506c1d6..656cffc808 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -276,7 +276,7 @@ Keep similar style to existing ones and app in general. Once the quest icon is r - save as "Plain SVG" or clean SVG file from unnecessary cruft in another way, like using [svgo](https://github.com/svg/svgo) - Put SVG into [`res/graphics/quest`](res/graphics/quest) folder - - SVG is a standard format editable in various software, unlike internal Android Studio XML that will be produced in the next step. + - SVG is a standard format editable in various software, unlike internal Android Studio XML that will be produced in the next steps. - Open Android Studio - Right click on the "app" folder in the Project tool window (top left) - Select new → vector asset From 22d3cc0a2d4f00a452509237d871ff898846a2aa Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:48:10 +0100 Subject: [PATCH 085/181] better description of a process, more consistency --- CONTRIBUTING_A_NEW_QUEST.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 656cffc808..29bc480f5c 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -281,9 +281,10 @@ Keep similar style to existing ones and app in general. Once the quest icon is r - Right click on the "app" folder in the Project tool window (top left) - Select new → vector asset - Select your SVG file -- Name with `ic_quest_` prefix (something like `ic_quest_traffic_calming`), this will cause IDE to generate an XML file -- add an entry in the [attribution file](res/graphics/authors.txt) -- modify `icon` property in the quest definition to use the new drawable +- Name with `ic_quest_` prefix (something like `ic_quest_traffic_calming`) +- Press "Finish" button to generate drawable +- Add an entry in the [attribution file](res/graphics/authors.txt) +- Modify `icon` property in the quest definition to use the new drawable - Commit modified or created files - Compile, test quest in the emulator From 1046785aac1025d93d98c46d630d4ede55490742 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 19:50:08 +0100 Subject: [PATCH 086/181] fix link --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 29bc480f5c..518904bcb7 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -299,7 +299,7 @@ Obviously, testing can also be done earlier. But the quest should at least be te Typically it is done using an emulator. Note that you can set location in emulator settings rather than scrolling within StreetComplete itself. * Is quest listed? - * Look at the quest list in settings - is your quest appearing there? If not - see [this step](#Add quest to the list of active ones). + * Look at the quest list in settings - is your quest appearing there? If not - see [this step](#add-the-quest-to-the-list-of-active-ones). * While you are there you can disable all quests except yours for easier testing. * Is it shown for expected elements? * Note that due to emulator peculiarities you may need to move map after quests are downloaded to see their markers ([gory details for curious](https://github.com/streetcomplete/StreetComplete/issues/2780)) From 86d135fc2a4329536ca0c8395bc10002d4ff2c1a Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Feb 2022 20:09:30 +0100 Subject: [PATCH 087/181] it appears that this bug is fixed! --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 518904bcb7..3903f3714b 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -323,7 +323,7 @@ See "logcat" (bottom left area of the screen) to see stacktrace or logging messa [Pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) is a submission of proposed changes to the source code. -You can put into the description of PR something like "fixes #1234" to [mark it as fixing this issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword). It can go into a commit message or PR description ([not its title](https://github.com/streetcomplete/StreetComplete/discussions/2917), it is a known GitHub bug). +You can put into the description of PR something like "fixes #1234" to [mark it as fixing this issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword). It can go into a commit message or PR description or the tile. If you are stuck on something, need some help or guidance and you are willing and able to continue after solving the problem - you can open a pull request in an incomplete state and mention the blocker. From dbb1965bbe242cd6e846bb9e739c6670867a750c Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 21 Feb 2022 05:15:39 +0100 Subject: [PATCH 088/181] Better English Co-authored-by: Matija Nalis --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 3903f3714b..0e9b953f84 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -167,7 +167,7 @@ This quest will be triggered when: - on nodes and ways - where `amenity = motorcycle_parking` tag is present - - `access` tag is not set with value `private` or `no` + - `access` tag does not have value `private` nor `no` - and one of following is fullfilled: - `capacity` tag is not present at all (`!capacity`) - element was not edited for a long time (base time is 4 years, but it can by influenced by user changing settings) From db8a1890e053eb1d3c606d82f8ef9e96d665d3b4 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 21 Feb 2022 05:16:09 +0100 Subject: [PATCH 089/181] Fix missing ) Co-authored-by: Matija Nalis --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 0e9b953f84..4b7d2b091d 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -23,7 +23,7 @@ But this materials may help or be quicker than trying to fully explore on your o - setting up Android Studio will likely be more complex than writing the code - [basic ability to use git](https://git-scm.com/docs/user-manual) (but as mentioned, anything GitHub specific will be explained) - there is version control integration available in Android Studio - - From the Android Studio **VCS** menu, click **Enable Version Control** Integration ([see official docs](https://developer.android.com/studio/intro#version_control_basics) + - From the Android Studio **VCS** menu, click **Enable Version Control** Integration ([see official docs](https://developer.android.com/studio/intro#version_control_basics)) - Go to File -> Settings -> Version control in Android Studio to optionally configure git integration - Using git from command line or terminal in Android Studio also works fine - GitHub [account](https://github.com/signup) From 71f3c7044af26886df1416283c2c55c9fb3c52e1 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 21 Feb 2022 05:16:50 +0100 Subject: [PATCH 090/181] File count note i.e. one file for new quest itself + QuestsModule.kt + strings.txt Co-authored-by: Matija Nalis --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 4b7d2b091d..96cd301a37 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -14,7 +14,7 @@ But this materials may help or be quicker than trying to fully explore on your o - programming ability - it is not a good task for someone who has never programmed anything. - Setup of environment takes a long time - - Editing even the simplest quest requires edits to at least two different files + - Editing even the simplest quest requires edits to at least three different files - Kotlin familiarity is not required, but the ability to adjust to a new syntax is needed. If you are unfamiliar with Kotlin reading about [null safety related syntax](https://kotlinlang.org/docs/null-safety.html) is likely to be very useful. - It is expected that someone trying this can search for a solution to a typical problem on encountering an error message - familiarity with StreetComplete as a user - it is highly recommended to be familiar with how StreetComplete works. Making hundreds of edits is not mandatory, but having a passing familiarity with how surveying with StreetComplete works is needed. From 1a052f469f0dcc54cd3692117d35d61a20bf81c4 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 21 Feb 2022 05:17:22 +0100 Subject: [PATCH 091/181] Link regexp A bit overkill at this point, but lets do this Co-authored-by: Matija Nalis --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 96cd301a37..25981e0bec 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -144,7 +144,7 @@ elementFilter property defines nodes, ways and relations which will be selected This query will be limited to nodes (`nodes with`), which fulfill some requirements. - `emergency = defibrillator` tag must be present -- `access` tag must not have values `private` or `no` to skip ones where mapper will be unable to survey (`!~ private|no` - to be more specific `optionA|optionB` is treated like `^optionA|optionB$` regexp) +- `access` tag must not have values `private` or `no` to skip ones where mapper will be unable to survey (`!~ private|no` - to be more specific `optionA|optionB` is treated like `^optionA|optionB$` [regexp](https://en.wikipedia.org/wiki/Regular_expression)) - `indoor` key must not be present at all, to show only ones where this tag is still missing It is specified as a string, in syntax specific to StreetComplete. You can look around some quests to see how it works. If you are trying to implement a new quest and you got stuck here, [open a new issue](https://github.com/streetcomplete/StreetComplete/issues) to request more thorough documentation here. From 84070b5c49d06698482b7a01874b5aa3ba4c2fda Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 21 Feb 2022 05:17:47 +0100 Subject: [PATCH 092/181] Fix syntax Co-authored-by: Matija Nalis --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 25981e0bec..417c5e82f7 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -377,7 +377,7 @@ This requires preparing space in the message for filling at runtime, and to add } ``` -``getTitleArgs` will return either array with single element containing value of `ref` tag or an empty array. In either cases it will be passed to code displaying title at runtime. +`getTitleArgs` will return either array with single element containing value of `ref` tag or an empty array. In either cases it will be passed to code displaying title at runtime. `arrayOfNotNull` is a minor helper function [defined in StreetComplete](app/src/main/java/de/westnordost/streetcomplete/ktx/Collections.kt). Note that when you open code in Android Studio or other IDE you can easily go to place where given function is defined. From fc3db284543bbefcd5fe32fbc37c35a00383fcfa Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 21 Feb 2022 05:30:03 +0100 Subject: [PATCH 093/181] Lik relevant code Co-authored-by: Matija Nalis --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 417c5e82f7..5871edd9c7 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -433,7 +433,7 @@ Article about [null safety related syntax](https://kotlinlang.org/docs/null-safe As mentioned, the user interface must leave no space for misunderstandings, it must be concise and quick and easy to use. Also sounds obvious, but you will quickly find out that a balance must be found between covering all the edge cases and designing the form to be as straightforward and clutterless as possible. - Design the main form clutter-free so that it is straightforward for the majority of use cases. -- Allow to answer popular edge cases, but don't clutter up the main form with that. A good pattern is to move such answers into the "Other answers..." menu. I.e. look at the opening hours quest. +- Allow to answer popular edge cases, but don't clutter up the main form with that. A good pattern is to move such answers into the "Other answers..." menu. E.g. look at the [opening hours quest](app/src/main/java/de/westnordost/streetcomplete/quests/opening_hours/AddOpeningHoursForm.kt#L40-L48). - Don't rely on the "leave a note" fallback too much. It is not intended and does not work as a regular answer but is designed to cover the case that the question was invalid itself because it was based on wrong data like i.e. the place does not exist anymore. - The information the user should fill in should be as atomic as possible. Users are impatient, i.e. do not let them fill out a whole address with street name etc. when just the house number is fine too. - "A picture is worth a thousand words": Often the term for certain things may not be enough to convey the meaning of certain predefined answers. Do you know what a wheelbender is? You will know if you see the photo. From 77192a2e15654bb5e84f5aa1178b200e1b493564 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 21 Feb 2022 05:46:42 +0100 Subject: [PATCH 094/181] Fix missing ) Co-authored-by: Matija Nalis --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 5871edd9c7..5776881ad4 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -387,7 +387,7 @@ So `getTitle` function that returns identifier to text in [strings file](app/src * `quest_fireHydrant_diameter_ref_title` which represents `What diameter is specified on the sign for this fire hydrant? (reference number: %s)` (or translation). `%s` is a [placeholder](https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings) and will be replaced by text provided by `getTitleArgs` -* In case of ref tag being not present `quest_fireHydrant_diameter_title` (`What diameter is specified on the sign for this fire hydrant?` will be used. +* In case of ref tag being not present `quest_fireHydrant_diameter_title` (`What diameter is specified on the sign for this fire hydrant?`) will be used. This is quite complex but allows translating application in various languages by decoupling exact text being displayed from the code. See for example identifiers with texts in [Polish translation](app/src/main/res/values-pl/strings.xml). From 693035929db1574f91b90a09dde7dd58e78958b6 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 21 Feb 2022 05:54:06 +0100 Subject: [PATCH 095/181] fix typos Co-authored-by: Matija Nalis --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 5776881ad4..d5a5d42489 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -381,9 +381,9 @@ This requires preparing space in the message for filling at runtime, and to add `arrayOfNotNull` is a minor helper function [defined in StreetComplete](app/src/main/java/de/westnordost/streetcomplete/ktx/Collections.kt). Note that when you open code in Android Studio or other IDE you can easily go to place where given function is defined. -``getTitle` provide identifier of text which will be +`getTitle` provide identifier of text which will be -So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either +So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either: * `quest_fireHydrant_diameter_ref_title` which represents `What diameter is specified on the sign for this fire hydrant? (reference number: %s)` (or translation). `%s` is a [placeholder](https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings) and will be replaced by text provided by `getTitleArgs` From 71c8b65cb5d7e5c065b8904e8fff56211e174d9d Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 21 Feb 2022 06:05:21 +0100 Subject: [PATCH 096/181] add info about disabling quests --- CONTRIBUTING_A_NEW_QUEST.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index d5a5d42489..7ccb4b3d46 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -495,3 +495,12 @@ Some quests should be enabled only in some countries or disabled in a specific c [`override val enabledInCountries = NoCountriesExcept("SE")`](app/src/main/java/de/westnordost/streetcomplete/quests/accepts_cash/AddAcceptsCash.kt) - enabled only in Sweden. [`override val enabledInCountries = AllCountriesExcept("US", "CA")`](app/src/main/java/de/westnordost/streetcomplete/quests/address/AddHousenumber.kt) - not enabled in USA and Canada + +## `defaultDisabledMessage` + +Some quests should be disabled by default, for example ones that may require going inside a shop. In such case setting `override val defaultDisabledMessage = R.string.default_disabled_msg_go_inside` will have two effects: + +- quest will be disabled by default +- on attempting to enable it user will get message asking are they sure. Exact message in this case would be `default_disabled_msg_go_inside` - but some quests use more specific ones. + +Note that quest may be both disabled by default and limited to some countries. From 9c1d7e86ef18999c055af065fd1d6052cadcfe04 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 21 Feb 2022 08:23:36 +0100 Subject: [PATCH 097/181] be clear about resurvey --- CONTRIBUTING_A_NEW_QUEST.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 7ccb4b3d46..ec02442c42 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -248,6 +248,7 @@ Actions may include (examples from various quests): - so can be used even if value will stay the same - possible for resurvey quests - survey date prefix is defined as [`const val SURVEY_MARK_KEY = "check_date"`](src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt) - always update survey tag if present already + - necessary if given quest includes resurvey of old elements that are already tagged ### Extras From 6cea695649e0bc2cae6c0e0d465660619f351e68 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 21 Feb 2022 08:30:12 +0100 Subject: [PATCH 098/181] Capitalize the title Co-authored-by: Peter Newman --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index ec02442c42..6dd0aa8c43 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -91,7 +91,7 @@ Full text search (ctrl+shift+f or grepping) remains useful and powerful. But "Find usages" (alt+F7) is also a very powerful way to find where given function/constant/property/etc is appearing, classified by usages. -## Pull requests +## Pull Requests One of the better ways to get around a codebase new to you is to look at recent accepted proposals to change code (pull requests). From cbfd68bccafa46638778d99e384ca27a670cd049 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 22 Feb 2022 09:35:42 +0100 Subject: [PATCH 099/181] rewrite for better language --- CONTRIBUTING_A_NEW_QUEST.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 6dd0aa8c43..cbbb52a783 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -64,7 +64,7 @@ Base the new quest on one that exists already. Find one that has the same type of interface as the one that you are trying to implement. -Are you trying to implement a quest that will have simple yes/no answer? Take [`AddIsDefibrillatorIndoor`](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt) quest as a base. Or [`AddTracktype`](app/src/main/java/de/westnordost/streetcomplete/quests/tracktype/AddTracktype.kt) where the mapper will be selecting one of the images. +Are you trying to implement a quest that will have simple yes/no answer? Take [`AddIsDefibrillatorIndoor`](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt) quest as a base. Or [`AddTracktype`](app/src/main/java/de/westnordost/streetcomplete/quests/tracktype/AddTracktype.kt) where the mapper will be selecting one of presented images. Is it going to be asked for POIs and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. @@ -93,7 +93,7 @@ But "Find usages" (alt+F7) is also a very powerful way to find where given funct ## Pull Requests -One of the better ways to get around a codebase new to you is to look at recent accepted proposals to change code (pull requests). +One of the better ways to get around a codebase that is new to you is to look at recent accepted proposals to change the code (pull requests). This is also likely useful here. @@ -243,10 +243,10 @@ Actions may include (examples from various quests): - `tags["indoor"] = answer.toYesNo()` - `tags.remove("amenity")` - remove key if it is present - `tags.updateWithCheckDate("lit", answer.toYesNo())` - - in case of changing value such change will be applied + - if the new value differs from existing tag value: new value will be applied - in case of value being the same: add survey date tag, it would be `check_date:lit=` in this case - so can be used even if value will stay the same - possible for resurvey quests - - survey date prefix is defined as [`const val SURVEY_MARK_KEY = "check_date"`](src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt) + - if the new value is the same as existing tag value: adds [survey date tag](app/src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt#L33) (`check_date:lit=` in this example) - always update survey tag if present already - necessary if given quest includes resurvey of old elements that are already tagged From 7edd28628b3062788c8a836f6e0e46f2c416f4f8 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Fri, 25 Feb 2022 23:26:10 +0100 Subject: [PATCH 100/181] fix typo Co-authored-by: Greg Oledzki --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index cbbb52a783..bc440abce7 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -419,7 +419,7 @@ Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blo [Filtering in the element selection](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L20) ensures that every object will have either `name` or `brand` tag. -Though description from iD presets is not guaranted. +Though description from iD presets is not guaranteed. So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either From 8e52831ab194f230a62a6f5cf159ee3b4e219484 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Mon, 28 Feb 2022 18:44:52 +0100 Subject: [PATCH 101/181] Enable syntax highlighting in code blocks --- CONTRIBUTING_A_NEW_QUEST.md | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index bc440abce7..266c35ddcc 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -132,14 +132,14 @@ TODO: maybe linking [app/src/main/java/de/westnordost/streetcomplete/data/osm/os ### Element selection elementFilter property defines nodes, ways and relations which will be selected for a given quest. It is an element selection used by OsmFilterQuestType. -``` +```kotlin """ - nodes with - emergency = defibrillator - and access !~ private|no - and !indoor + nodes with + emergency = defibrillator + and access !~ private|no + and !indoor """ -``` +``` This query will be limited to nodes (`nodes with`), which fulfill some requirements. @@ -155,14 +155,14 @@ Some quests are asked not only when tag is missing but also when it is likely to Typical code is in [quest asking about motorcycle parking capacity](app/src/main/java/de/westnordost/streetcomplete/quests/motorcycle_parking_capacity/AddMotorcycleParkingCapacity.kt): -``` +```kotlin override val elementFilter = """ nodes, ways with amenity = motorcycle_parking and access !~ private|no and (!capacity or capacity older today -4 years) """ -``` - +``` + This quest will be triggered when: - on nodes and ways @@ -228,11 +228,12 @@ But sometimes more complex ones are needed, see for example [AddBridgeStructure. With form defined in [AddBridgeStructureForm](app/src/main/java/de/westnordost/streetcomplete/quests/bridge_structure/AddBridgeStructureForm.kt) ### applyAnswerTo -``` + +```kotlin override fun applyAnswerTo(answer: Boolean, tags: Tags, timestampEdited: Long) { tags["indoor"] = answer.toYesNo() } -``` +``` This code is responsible for modifying `tags` object (passed by reference). @@ -254,7 +255,8 @@ Actions may include (examples from various quests): ### Extras Info listed above must be supplied by every quest. But there are also several optional fields. This specific quest has -``` + +```kotlin override fun getHighlightedElements(element: Element, getMapData: () -> MapDataWithGeometry) = getMapData().filter("nodes with emergency = defibrillator") ``` @@ -365,7 +367,7 @@ This requires preparing space in the message for filling at runtime, and to add [AddFireHydrantDiameter](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/fire_hydrant_diameter/AddFireHydrantDiameter.kt) displays `ref` code of hydrant, if tagged. -``` +```kotlin override fun getTitleArgs(tags: Map, featureName: Lazy): Array = arrayOfNotNull(tags["ref"]) @@ -399,7 +401,7 @@ For example, in the case of shops it may be necessary to identify specific one a Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L104-L115) that will: -``` +```kotlin override fun getTitle(tags: Map) = if (hasFeatureName(tags)) R.string.quest_wheelchairAccess_name_type_title @@ -410,7 +412,7 @@ Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blo val name = tags["name"] ?: tags["brand"] return arrayOfNotNull(name, featureName.value) } -``` +``` - `getTitleArgs` tries to pass to the title - name of the object From 5cccf572b1070176724acce2ac7e7e2d5599f367 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Mon, 28 Feb 2022 18:51:05 +0100 Subject: [PATCH 102/181] Fix list indentation --- CONTRIBUTING_A_NEW_QUEST.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 266c35ddcc..ebeb09adde 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -35,7 +35,7 @@ But this materials may help or be quicker than trying to fully explore on your o - install necessary software ([Android Studio](https://developer.android.com/studio) and [git](https://git-scm.com/downloads)) - create a GitHub [account](https://github.com/signup) if needed - visit [https://github.com/streetcomplete/StreetComplete](https://github.com/streetcomplete/StreetComplete) and press the "fork" button on the top right - + this creates a copy of StreetComplete repository that you control and can prepare code there + - this creates a copy of StreetComplete repository that you control and can prepare code there - clone your fork of a StreetComplete repository - open StreetComplete in Android Studio - [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also [connect to a real device via USB](https://developer.android.com/studio/run/device), this can replace using the emulator) @@ -165,13 +165,13 @@ Typical code is in [quest asking about motorcycle parking capacity](app/src/main This quest will be triggered when: - - on nodes and ways - - where `amenity = motorcycle_parking` tag is present - - `access` tag does not have value `private` nor `no` - - and one of following is fullfilled: - - `capacity` tag is not present at all (`!capacity`) - - element was not edited for a long time (base time is 4 years, but it can by influenced by user changing settings) - - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) +- on nodes and ways +- where `amenity = motorcycle_parking` tag is present +- `access` tag does not have value `private` nor `no` +- and one of following is fullfilled: + - `capacity` tag is not present at all (`!capacity`) + - element was not edited for a long time (base time is 4 years, but it can by influenced by user changing settings) + - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) #### Hints The rules should generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. @@ -246,8 +246,8 @@ Actions may include (examples from various quests): - `tags.updateWithCheckDate("lit", answer.toYesNo())` - if the new value differs from existing tag value: new value will be applied - in case of value being the same: add survey date tag, it would be `check_date:lit=` in this case - - so can be used even if value will stay the same - possible for resurvey quests - - if the new value is the same as existing tag value: adds [survey date tag](app/src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt#L33) (`check_date:lit=` in this example) + - so can be used even if value will stay the same - possible for resurvey quests + - if the new value is the same as existing tag value: adds [survey date tag](app/src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt#L33) (`check_date:lit=` in this example) - always update survey tag if present already - necessary if given quest includes resurvey of old elements that are already tagged @@ -458,10 +458,10 @@ In StreetComplete many images have unusual composition. Often it is necessary to Images should be free of visual debris, not misleading. Though it is fine to use an image not strictly matching what is depicted, as long as it is clear. For example, [a permanent pile of soil blocking road](https://wiki.openstreetmap.org/wiki/Tag:barrier%3Ddebris) is illustrated by a [temporary landslide](https://commons.wikimedia.org/wiki/File:Landslide_on_OR_42S_(46849629014).jpg). This is OK as images are illustrative. Photos go to a different folder than SVGs: they can be used directly by the build process so put them into folders - - [mdpi](app/src/main/res/drawable-mdpi) - 384 pixels for images, with three square images in each row it would be 128 x 128 pixels for each) - - [hdpi](app/src/main/res/drawable-hdpi) - 576 pixels for images (192 x 192 pixels in case of three quare images in each row) - - [xhdpi](app/src/main/res/drawable-xhdpi) 768 pixels for images (256 x 256 pixels in case of three quare images in each row) - - [xxhdpi](app/src/main/res/drawable-xxhdpi) 1152 pixels (384 x 384 pixels in case of three quare images in each row) +- [mdpi](app/src/main/res/drawable-mdpi) - 384 pixels for images, with three square images in each row it would be 128 x 128 pixels for each) +- [hdpi](app/src/main/res/drawable-hdpi) - 576 pixels for images (192 x 192 pixels in case of three quare images in each row) +- [xhdpi](app/src/main/res/drawable-xhdpi) 768 pixels for images (256 x 256 pixels in case of three quare images in each row) +- [xxhdpi](app/src/main/res/drawable-xxhdpi) 1152 pixels (384 x 384 pixels in case of three quare images in each row) Each of these folders should hold the same image resized to a different resolution. While testing various images it is enough to put one into any of the folders. From 90cee785e48c6c3eab7c3f96c69a8251e5f5bb5e Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Mon, 28 Feb 2022 18:55:58 +0100 Subject: [PATCH 103/181] Normalize empty lines * one empty line before/after headings and lists * no consecutive empty lines --- CONTRIBUTING_A_NEW_QUEST.md | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index ebeb09adde..a49da00015 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -46,9 +46,11 @@ If you are doing it for the first time, don't worry if there is an error to solv # Invent a new quest ## Own ideas + To [repeat](CONTRIBUTING.md#developing-new-quests) from that documentation file: [**open an issue** discussing the quest](CONTRIBUTING.md#developing-new-quests), before starting other work. This way it can be confirmed that such quest can be included. This can be skipped if you are an [experienced](https://github.com/streetcomplete/StreetComplete/discussions/3450) StreetComplete contributor. ## Existing proposals + You can also look at [quest proposals waiting for implementation](https://github.com/streetcomplete/StreetComplete/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+quest%22). # Prepare repository for development @@ -60,6 +62,7 @@ That is a good moment to create a branch and switch to it. It can be done with t # Learn from existing code ## Find a base + Base the new quest on one that exists already. Find one that has the same type of interface as the one that you are trying to implement. @@ -70,7 +73,6 @@ Is it going to be asked for POIs and should be disabled by default? `AddWheelcha Quests are grouped in [one folder](app/src/main/java/de/westnordost/streetcomplete/quests). - ### Locating a quest Search across the code for part of a question or other text specific to this quest. For example "What is the name of this place". @@ -124,12 +126,13 @@ Adjust [QuestsModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/ Add your quest to the list so that it will be loaded by the app. ## Quest anatomy -See for example [simple yes/no quest asking whether AED is indoor or outdoor](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt). +See for example [simple yes/no quest asking whether AED is indoor or outdoor](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt). TODO: maybe linking [app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt](app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt) would be better? And extend documentation there? ### Element selection + elementFilter property defines nodes, ways and relations which will be selected for a given quest. It is an element selection used by OsmFilterQuestType. ```kotlin @@ -174,6 +177,7 @@ This quest will be triggered when: - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) #### Hints + The rules should generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. In some cases it will be a good idea to [limit quests to certain countries](#enabledInCountries). @@ -182,16 +186,18 @@ In some cases it will be a good idea to [limit quests to certain countries](#ena You can obtain more info about properties by placing the cursor in a property and pressing Ctrl+Q within Android Studio. - #### changesetComment + `override val changesetComment = "Add whether defibrillator is inside building"` message used as a changeset comment #### wikiLink + `override val wikiLink = "Key:indoor"` points to the OSM Wiki page most relevant to the given quest, typically it is an added key. In this case, it is a page about [indoor=* tagging](https://wiki.openstreetmap.org/wiki/Key:indoor). #### icon + `override val icon = R.drawable.ic_quest_defibrillator` icon drawable, you can initially use any icon. @@ -200,11 +206,13 @@ Do not worry, submissions with placeholder icons are also welcomed! In many case More info about icon handling [will be given later](#adding-quest-icon). #### questTypeAchievements + `override val questTypeAchievements = listOf(LIFESAVER)` In quest achievements, list what is relevant to the given quest, see the full list of available ones in [AchievementsModule.kt](app/src/main/java/de/westnordost/streetcomplete/data/user/achievements/AchievementsModule.kt) #### getTitle + `override fun getTitle(tags: Map) = R.string.quest_is_defibrillator_inside_title` It is a message displayed to user, code here passes a [reference](https://developer.android.com/guide/topics/resources/string-resource) to the string. You can change it to the new, not yet existing one and use a built in tool to place text. @@ -225,8 +233,8 @@ But sometimes more complex ones are needed, see for example [AddBridgeStructure. `override fun createForm() = AddBridgeStructureForm()` - With form defined in [AddBridgeStructureForm](app/src/main/java/de/westnordost/streetcomplete/quests/bridge_structure/AddBridgeStructureForm.kt) + ### applyAnswerTo ```kotlin @@ -251,7 +259,6 @@ Actions may include (examples from various quests): - always update survey tag if present already - necessary if given quest includes resurvey of old elements that are already tagged - ### Extras Info listed above must be supplied by every quest. But there are also several optional fields. This specific quest has @@ -353,6 +360,7 @@ Unclear documents, including this one, are a bug. Feel free to either submit a [ Note that not everything will be directly described. This document very intentionally doesn't include a step-by-step guide to installing Android Studio, [linking](CONTRIBUTING.md#development) to official docs instead. # More complexity + What was described above is an attempt to cover all aspects of quest creation, without describing all the complexity. Below is some additional info. @@ -388,13 +396,13 @@ This requires preparing space in the message for filling at runtime, and to add So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either: - * `quest_fireHydrant_diameter_ref_title` which represents `What diameter is specified on the sign for this fire hydrant? (reference number: %s)` (or translation). `%s` is a [placeholder](https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings) and will be replaced by text provided by `getTitleArgs` * In case of ref tag being not present `quest_fireHydrant_diameter_title` (`What diameter is specified on the sign for this fire hydrant?`) will be used. This is quite complex but allows translating application in various languages by decoupling exact text being displayed from the code. See for example identifiers with texts in [Polish translation](app/src/main/res/values-pl/strings.xml). ### Use feature name if present + In some cases, the quest will mention the name of object (lets say "Knight") and type of feature (maybe restaurant? Or supermarket?). For example, in the case of shops it may be necessary to identify specific one among several. @@ -429,6 +437,7 @@ So `getTitle` function that returns identifier to text in [strings file](app/src * In case of no feature name being available `quest_wheelchairAccess_name_title` will be used, with space for one parameter: `Is %s wheelchair accessible?` (`%s` is a single placeholder which will be replaced by text parameter) ### Kotlin + Article about [null safety related syntax](https://kotlinlang.org/docs/null-safety.html) is likely to be very useful, especially if you are confused by `?:` [Elvis operator](https://kotlinlang.org/docs/null-safety.html#elvis-operator). ## Designing the form @@ -458,6 +467,7 @@ In StreetComplete many images have unusual composition. Often it is necessary to Images should be free of visual debris, not misleading. Though it is fine to use an image not strictly matching what is depicted, as long as it is clear. For example, [a permanent pile of soil blocking road](https://wiki.openstreetmap.org/wiki/Tag:barrier%3Ddebris) is illustrated by a [temporary landslide](https://commons.wikimedia.org/wiki/File:Landslide_on_OR_42S_(46849629014).jpg). This is OK as images are illustrative. Photos go to a different folder than SVGs: they can be used directly by the build process so put them into folders + - [mdpi](app/src/main/res/drawable-mdpi) - 384 pixels for images, with three square images in each row it would be 128 x 128 pixels for each) - [hdpi](app/src/main/res/drawable-hdpi) - 576 pixels for images (192 x 192 pixels in case of three quare images in each row) - [xhdpi](app/src/main/res/drawable-xhdpi) 768 pixels for images (256 x 256 pixels in case of three quare images in each row) @@ -470,6 +480,7 @@ The [rescaling script](https://github.com/matkoniecz/rescaling_for_android) may After adding a photo, remember to update [the credit file](app/src/main/res/authors.txt) (different to the one for icons). ## Custom filters + It is possible to use far more complex filters when querying for eligible elements. Matches like `surface ~ earth|dirt|ground` are possible and are evaluated as "`surface` is either of `earth`, `dirt`, `ground`" @@ -486,7 +497,6 @@ It is possible to share and reuse [information about tagging schemes](https://gi (this info is gathered [here](/app/src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt)) - Even more complex ones using different class bases are possible. Such as what was needed by the [address quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/address/AddAddressStreet.kt) or the [crossing quest](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/crossing/AddCrossing.kt) but it is better to start from something simpler. It allows it to make complex geometry checks, but writing them is also far more complex. From 9a5a2d369f9ea8f81ddf624788862b013f85c7c4 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Mon, 28 Feb 2022 18:56:41 +0100 Subject: [PATCH 104/181] Trim trailing whitespace --- CONTRIBUTING_A_NEW_QUEST.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index a49da00015..74fba534aa 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -198,8 +198,8 @@ points to the OSM Wiki page most relevant to the given quest, typically it is an #### icon -`override val icon = R.drawable.ic_quest_defibrillator` -icon drawable, you can initially use any icon. +`override val icon = R.drawable.ic_quest_defibrillator` +icon drawable, you can initially use any icon. Do not worry, submissions with placeholder icons are also welcomed! In many cases icon itself was not made by the PR author. @@ -229,7 +229,7 @@ Form defines interface used by mappers. In this case, the simplest possible is used. -But sometimes more complex ones are needed, see for example [AddBridgeStructure.kt](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/bridge_structure/AddBridgeStructure.kt) +But sometimes more complex ones are needed, see for example [AddBridgeStructure.kt](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/bridge_structure/AddBridgeStructure.kt) `override fun createForm() = AddBridgeStructureForm()` @@ -431,7 +431,7 @@ Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blo Though description from iD presets is not guaranteed. -So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either +So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either * `quest_wheelchairAccess_name_type_title` which represents `Is %1$s (%2$s) wheelchair accessible?` (or translation). `%1$s` and `%2$s` [placeholders](https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings) will be replaced by text provided by `getTitleArgs` * In case of no feature name being available `quest_wheelchairAccess_name_title` will be used, with space for one parameter: `Is %s wheelchair accessible?` (`%s` is a single placeholder which will be replaced by text parameter) @@ -448,7 +448,7 @@ As mentioned, the user interface must leave no space for misunderstandings, it m - Allow to answer popular edge cases, but don't clutter up the main form with that. A good pattern is to move such answers into the "Other answers..." menu. E.g. look at the [opening hours quest](app/src/main/java/de/westnordost/streetcomplete/quests/opening_hours/AddOpeningHoursForm.kt#L40-L48). - Don't rely on the "leave a note" fallback too much. It is not intended and does not work as a regular answer but is designed to cover the case that the question was invalid itself because it was based on wrong data like i.e. the place does not exist anymore. - The information the user should fill in should be as atomic as possible. Users are impatient, i.e. do not let them fill out a whole address with street name etc. when just the house number is fine too. -- "A picture is worth a thousand words": Often the term for certain things may not be enough to convey the meaning of certain predefined answers. Do you know what a wheelbender is? You will know if you see the photo. +- "A picture is worth a thousand words": Often the term for certain things may not be enough to convey the meaning of certain predefined answers. Do you know what a wheelbender is? You will know if you see the photo. Considerations about the edge cases to consider, how the design could look like and finding good representative photos or icons that match in style is also part of the preparational work that can be done without programming knowledge. From a8977b9bf9c38532fbe3226b0b68766bdd681418 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Tue, 1 Mar 2022 10:24:41 +0100 Subject: [PATCH 105/181] Convert some inline code spans to code blocks with syntax highlighting --- CONTRIBUTING_A_NEW_QUEST.md | 99 +++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 38 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 74fba534aa..d8f8417144 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -57,7 +57,9 @@ You can also look at [quest proposals waiting for implementation](https://github That is a good moment to create a branch and switch to it. It can be done with the following command: -`git checkout -b short_branch_name_describing_planned_work` +```bash +git checkout -b short_branch_name_describing_planned_work +``` # Learn from existing code @@ -79,7 +81,9 @@ Search across the code for part of a question or other text specific to this que You will find an XML file with an entry looking like this: -`"What is the name of this place? (%s)"` +```xml +"What is the name of this place? (%s)" +``` The identifier `quest_placeName_title_name` is a string reference, used in the code to allow translations. @@ -159,11 +163,11 @@ Some quests are asked not only when tag is missing but also when it is likely to Typical code is in [quest asking about motorcycle parking capacity](app/src/main/java/de/westnordost/streetcomplete/quests/motorcycle_parking_capacity/AddMotorcycleParkingCapacity.kt): ```kotlin - override val elementFilter = """ - nodes, ways with amenity = motorcycle_parking - and access !~ private|no - and (!capacity or capacity older today -4 years) - """ +override val elementFilter = """ + nodes, ways with amenity = motorcycle_parking + and access !~ private|no + and (!capacity or capacity older today -4 years) +""" ``` This quest will be triggered when: @@ -188,17 +192,26 @@ You can obtain more info about properties by placing the cursor in a property an #### changesetComment -`override val changesetComment = "Add whether defibrillator is inside building"` +```kotlin +override val changesetComment = "Add whether defibrillator is inside building" +``` + message used as a changeset comment #### wikiLink -`override val wikiLink = "Key:indoor"` +```kotlin +override val wikiLink = "Key:indoor" +``` + points to the OSM Wiki page most relevant to the given quest, typically it is an added key. In this case, it is a page about [indoor=* tagging](https://wiki.openstreetmap.org/wiki/Key:indoor). #### icon -`override val icon = R.drawable.ic_quest_defibrillator` +```kotlin +override val icon = R.drawable.ic_quest_defibrillator +``` + icon drawable, you can initially use any icon. Do not worry, submissions with placeholder icons are also welcomed! In many cases icon itself was not made by the PR author. @@ -207,13 +220,17 @@ More info about icon handling [will be given later](#adding-quest-icon). #### questTypeAchievements -`override val questTypeAchievements = listOf(LIFESAVER)` +```kotlin +override val questTypeAchievements = listOf(LIFESAVER) +``` In quest achievements, list what is relevant to the given quest, see the full list of available ones in [AchievementsModule.kt](app/src/main/java/de/westnordost/streetcomplete/data/user/achievements/AchievementsModule.kt) #### getTitle -`override fun getTitle(tags: Map) = R.string.quest_is_defibrillator_inside_title` +```kotlin +override fun getTitle(tags: Map) = R.string.quest_is_defibrillator_inside_title +``` It is a message displayed to user, code here passes a [reference](https://developer.android.com/guide/topics/resources/string-resource) to the string. You can change it to the new, not yet existing one and use a built in tool to place text. @@ -223,7 +240,9 @@ There are separate files with translated text, but do not worry about it - [tran #### Form -`override fun createForm() = YesNoQuestAnswerFragment()` +```kotlin +override fun createForm() = YesNoQuestAnswerFragment() +``` Form defines interface used by mappers. @@ -238,9 +257,9 @@ With form defined in [AddBridgeStructureForm](app/src/main/java/de/westnordost/s ### applyAnswerTo ```kotlin - override fun applyAnswerTo(answer: Boolean, tags: Tags, timestampEdited: Long) { - tags["indoor"] = answer.toYesNo() - } +override fun applyAnswerTo(answer: Boolean, tags: Tags, timestampEdited: Long) { + tags["indoor"] = answer.toYesNo() +} ``` This code is responsible for modifying `tags` object (passed by reference). @@ -264,8 +283,8 @@ Actions may include (examples from various quests): Info listed above must be supplied by every quest. But there are also several optional fields. This specific quest has ```kotlin - override fun getHighlightedElements(element: Element, getMapData: () -> MapDataWithGeometry) = - getMapData().filter("nodes with emergency = defibrillator") +override fun getHighlightedElements(element: Element, getMapData: () -> MapDataWithGeometry) = + getMapData().filter("nodes with emergency = defibrillator") ``` which causes nearby `emergency = defibrillator` nodes to be shown (icons used are defined in [PinIcons.kt](app/src/main/java/de/westnordost/streetcomplete/map/PinIcons.kt)) @@ -327,7 +346,11 @@ See "logcat" (bottom left area of the screen) to see stacktrace or logging messa ## Adding logs -`Log.w("Unique string for easy grepping in logcat", "Message with whatever you need like #${someVariable.itsProperty}")` +```kotlin +import android.util.Log + +Log.w("Unique string for easy grepping in logcat", "Message with whatever you need like #${someVariable.itsProperty}") +``` # Open a pull request @@ -376,16 +399,16 @@ This requires preparing space in the message for filling at runtime, and to add [AddFireHydrantDiameter](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/fire_hydrant_diameter/AddFireHydrantDiameter.kt) displays `ref` code of hydrant, if tagged. ```kotlin - override fun getTitleArgs(tags: Map, featureName: Lazy): Array = - arrayOfNotNull(tags["ref"]) - - override fun getTitle(tags: Map): Int { - val hasRef = tags.containsAnyKey("ref") - return when { - hasRef -> R.string.quest_fireHydrant_diameter_ref_title - else -> R.string.quest_fireHydrant_diameter_title - } +override fun getTitleArgs(tags: Map, featureName: Lazy): Array = + arrayOfNotNull(tags["ref"]) + +override fun getTitle(tags: Map): Int { + val hasRef = tags.containsAnyKey("ref") + return when { + hasRef -> R.string.quest_fireHydrant_diameter_ref_title + else -> R.string.quest_fireHydrant_diameter_title } +} ``` `getTitleArgs` will return either array with single element containing value of `ref` tag or an empty array. In either cases it will be passed to code displaying title at runtime. @@ -410,16 +433,16 @@ For example, in the case of shops it may be necessary to identify specific one a Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L104-L115) that will: ```kotlin - override fun getTitle(tags: Map) = - if (hasFeatureName(tags)) - R.string.quest_wheelchairAccess_name_type_title - else - R.string.quest_wheelchairAccess_name_title - - override fun getTitleArgs(tags: Map, featureName: Lazy): Array { - val name = tags["name"] ?: tags["brand"] - return arrayOfNotNull(name, featureName.value) - } +override fun getTitle(tags: Map) = + if (hasFeatureName(tags)) + R.string.quest_wheelchairAccess_name_type_title + else + R.string.quest_wheelchairAccess_name_title + +override fun getTitleArgs(tags: Map, featureName: Lazy): Array { + val name = tags["name"] ?: tags["brand"] + return arrayOfNotNull(name, featureName.value) +} ``` - `getTitleArgs` tries to pass to the title From a0ad33c871c8f1afea32c8aa03c933c1a747b319 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Tue, 1 Mar 2022 10:26:09 +0100 Subject: [PATCH 106/181] Highlight keyboard shortcuts --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index d8f8417144..96ab51af51 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -93,9 +93,9 @@ This method can often be used to locate relevant code. ### Hints for looking around code -Full text search (ctrl+shift+f or grepping) remains useful and powerful. +Full text search (ctrl+shift+f or grepping) remains useful and powerful. -But "Find usages" (alt+F7) is also a very powerful way to find where given function/constant/property/etc is appearing, classified by usages. +But "Find usages" (alt+F7) is also a very powerful way to find where given function/constant/property/etc is appearing, classified by usages. ## Pull Requests From d95d8f10530730aa5c1ecb76bff80e745b8d15a9 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Tue, 1 Mar 2022 14:28:26 +0100 Subject: [PATCH 107/181] fix typo Co-authored-by: Greg Oledzki --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 96ab51af51..e1264ebdc6 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -177,7 +177,7 @@ This quest will be triggered when: - `access` tag does not have value `private` nor `no` - and one of following is fullfilled: - `capacity` tag is not present at all (`!capacity`) - - element was not edited for a long time (base time is 4 years, but it can by influenced by user changing settings) + - element was not edited for a long time (base time is 4 years, but it can be influenced by user changing settings) - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) #### Hints From e5a0017647c76259bf00507001645552d33c33be Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Fri, 4 Mar 2022 10:41:50 +0100 Subject: [PATCH 108/181] exclude blocked among new quests technically new contributors could also work on upstream issues to unlock them, but it is more risky, annoying and confusing so maybe new contributors should not be directed there Co-authored-by: Wieland <29458682+wielandb@users.noreply.github.com> --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index e1264ebdc6..ff27d1b72f 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -51,7 +51,7 @@ To [repeat](CONTRIBUTING.md#developing-new-quests) from that documentation file: ## Existing proposals -You can also look at [quest proposals waiting for implementation](https://github.com/streetcomplete/StreetComplete/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+quest%22). +You can also look at [quest proposals waiting for implementation](https://github.com/streetcomplete/StreetComplete/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+quest%22+-label%3A%22blocked%22). # Prepare repository for development From 058bc006be984785f93a6c94398651f63514fb92 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Fri, 4 Mar 2022 12:09:35 +0100 Subject: [PATCH 109/181] Better English Co-authored-by: Flo Edelmann --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index ff27d1b72f..cb651d8c4c 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -28,7 +28,7 @@ But this materials may help or be quicker than trying to fully explore on your o - Using git from command line or terminal in Android Studio also works fine - GitHub [account](https://github.com/signup) - around 15GB of free space on disk - - the initial setup will typically download half of the Internet while getting emulators and dependencies + - the initial setup will typically download half the Internet while getting emulators and dependencies # Dependencies - initial setup From dd60eba5aeb3f55f45087e28b56a366d153e96ac Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 28 Mar 2022 16:29:11 +0200 Subject: [PATCH 110/181] mention code credits fixes https://github.com/matkoniecz/Zazolc/issues/7 --- CONTRIBUTING_A_NEW_QUEST.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index cb651d8c4c..3ddeb080e5 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -376,6 +376,8 @@ After the PR is finished it will be merged before the beta release of the next v After full release it will reach the entire StreetComplete audience who now will be able to more easily contribute to OpenStreetMap. Thanks in advance for that! +Once your code is merged into StreetComplete you will be credited at [repository statistics](https://github.com/streetcomplete/StreetComplete/graphs/contributors). + # Bad documentation is a bug Unclear documents, including this one, are a bug. Feel free to either submit a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) with a fix or [open an issue](https://github.com/streetcomplete/StreetComplete/issues/new) describing your confusion. From 438be310fc2c179ab88d7a9c7df01f1f72ccdd8c Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 28 Mar 2022 16:34:03 +0200 Subject: [PATCH 111/181] add missing link --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 3ddeb080e5..57873de4ee 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -71,7 +71,7 @@ Find one that has the same type of interface as the one that you are trying to i Are you trying to implement a quest that will have simple yes/no answer? Take [`AddIsDefibrillatorIndoor`](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt) quest as a base. Or [`AddTracktype`](app/src/main/java/de/westnordost/streetcomplete/quests/tracktype/AddTracktype.kt) where the mapper will be selecting one of presented images. -Is it going to be asked for POIs and should be disabled by default? `AddWheelchairAccessBusiness` may be a good base. +Is it going to be asked for POIs and should be disabled by default? [`AddWheelchairAccessBusiness`](app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt) may be a good base. Quests are grouped in [one folder](app/src/main/java/de/westnordost/streetcomplete/quests). From 7a53da9b1669f13395643051263fb7f8909b8b86 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 28 Mar 2022 16:36:51 +0200 Subject: [PATCH 112/181] link file and update to changes in titles --- CONTRIBUTING_A_NEW_QUEST.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 57873de4ee..43edf4a704 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -77,15 +77,15 @@ Quests are grouped in [one folder](app/src/main/java/de/westnordost/streetcomple ### Locating a quest -Search across the code for part of a question or other text specific to this quest. For example "What is the name of this place". +Search across the code for part of a question or other text specific to this quest. For example "the name of this place?". -You will find an XML file with an entry looking like this: +You will find an [XML file](app/src/main/res/values/strings.xml) with an entry looking like this: ```xml -"What is the name of this place? (%s)" + "What’s the name of this place?" ``` -The identifier `quest_placeName_title_name` is a string reference, used in the code to allow translations. +The identifier `quest_placeName_title` is a string reference, used in the code to allow translations. Search for this identifier in `*.kt` files, it should appear in the quest file (in this case [AddPlaceName.kt](app/src/main/java/de/westnordost/streetcomplete/quests/place_name/AddPlaceName.kt)). From 320a91245785aeb36fdb5006f44edce2316f65ad Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 20 Mar 2022 15:41:01 +0100 Subject: [PATCH 113/181] clarify that both are needed --- buildSrc/src/main/java/UpdatePresetsTask.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/UpdatePresetsTask.kt b/buildSrc/src/main/java/UpdatePresetsTask.kt index 68ef9e0577..caef7c2d28 100644 --- a/buildSrc/src/main/java/UpdatePresetsTask.kt +++ b/buildSrc/src/main/java/UpdatePresetsTask.kt @@ -42,7 +42,7 @@ open class UpdatePresetsTask : DefaultTask() { } // Norway has two languages, one of them is called Bokmål - // coded "no" in iD presets, but "nb" is expected by Android. + // coded "no" in iD presets, but "nb" is also expected by Android. // https://github.com/streetcomplete/StreetComplete/issues/3890 val bokmalFile = File("$targetDir/no.json") bokmalFile.copyTo(File("$targetDir/nb.json"), overwrite = true) From 4c881371bb81f20ba8ab8ef828f2b59678cd9a3d Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 28 Mar 2022 16:39:00 +0200 Subject: [PATCH 114/181] link rg --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 43edf4a704..7f0fec891f 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -93,7 +93,7 @@ This method can often be used to locate relevant code. ### Hints for looking around code -Full text search (ctrl+shift+f or grepping) remains useful and powerful. +Full text search (ctrl+shift+f or [grepping](https://github.com/BurntSushi/ripgrep#ripgrep-rg)) remains useful and powerful. But "Find usages" (alt+F7) is also a very powerful way to find where given function/constant/property/etc is appearing, classified by usages. From 0b64f9f994f2c2116c4f605e96c14ca4a0610059 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 28 Mar 2022 16:41:28 +0200 Subject: [PATCH 115/181] be less optimistic --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 7f0fec891f..eda0df3f46 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -117,7 +117,7 @@ Some quests are entirely defined in a single file, some have additional answer c # Adjust the copy -After the quest is copied it is necessary to adjust it a bit. +After the quest is copied it is necessary to adjust it a bit so it is not a duplicate anymore. Change its class name and the file name to the new one. From 7753490d9de552a21e087472c8fc7293c5cb4a7c Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 28 Mar 2022 16:41:39 +0200 Subject: [PATCH 116/181] fix link --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index eda0df3f46..98dade85b0 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -125,7 +125,7 @@ In copied code change package info (things like `package de.westnordost.streetco # Add the quest to the list of active ones -Adjust [QuestsModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt) file. It contains a big list of active quests, ordered by priority. Read [what governs their priority](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt#L169-L192) but do not worry too much, it can be tweaked later. +Adjust [QuestsModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt) file. It contains a big list of active quests, ordered by priority. Read [what governs their priority](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt#L172-L195) but do not worry too much, it can be tweaked later. Add your quest to the list so that it will be loaded by the app. From 1b380ff8607cf4a356b00ac439c6ae2a5a9a476f Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 28 Mar 2022 16:46:19 +0200 Subject: [PATCH 117/181] improve readavility --- CONTRIBUTING_A_NEW_QUEST.md | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 98dade85b0..079c5938f6 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -148,11 +148,16 @@ elementFilter property defines nodes, ways and relations which will be selected """ ``` -This query will be limited to nodes (`nodes with`), which fulfill some requirements. +This query will be limited to object which fulfill some requirements. -- `emergency = defibrillator` tag must be present -- `access` tag must not have values `private` or `no` to skip ones where mapper will be unable to survey (`!~ private|no` - to be more specific `optionA|optionB` is treated like `^optionA|optionB$` [regexp](https://en.wikipedia.org/wiki/Regular_expression)) -- `indoor` key must not be present at all, to show only ones where this tag is still missing +- `nodes with` + - nodes only, ways and relations are not eligible +- `emergency = defibrillator` + - this tag must be present +- `and access !~ private|no` + - and `access` tag must not have values `private` or `no` to skip ones where mapper will be unable to survey (`!~ private|no` - to be more specific `optionA|optionB` is treated like `^optionA|optionB$` [regexp](https://en.wikipedia.org/wiki/Regular_expression)) +- `and !indoor` + - and `indoor` key must not be present at all, to show only ones where this tag is still missing It is specified as a string, in syntax specific to StreetComplete. You can look around some quests to see how it works. If you are trying to implement a new quest and you got stuck here, [open a new issue](https://github.com/streetcomplete/StreetComplete/issues) to request more thorough documentation here. @@ -172,13 +177,17 @@ override val elementFilter = """ This quest will be triggered when: -- on nodes and ways -- where `amenity = motorcycle_parking` tag is present -- `access` tag does not have value `private` nor `no` -- and one of following is fullfilled: - - `capacity` tag is not present at all (`!capacity`) - - element was not edited for a long time (base time is 4 years, but it can be influenced by user changing settings) - - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) +- `nodes, ways with` + - on nodes or ways (relations not eligible) +- `amenity = motorcycle_parking` + - where `amenity = motorcycle_parking` tag is present +- `and access !~ private|no` + - and `access` tag does not have value `private` nor `no` +- `and (!capacity or capacity older today -4 years)` + - and one of following is fullfilled: + - `capacity` tag is not present at all (`!capacity`) + - element was not edited for a long time (base time is 4 years, but it can be influenced by user changing settings) + - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) #### Hints From a9e08af11140852aeafd094a1c90deedbc280154 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 28 Mar 2022 16:51:56 +0200 Subject: [PATCH 118/181] more readability improvements --- CONTRIBUTING_A_NEW_QUEST.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 079c5938f6..e441f3a2f8 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -155,7 +155,9 @@ This query will be limited to object which fulfill some requirements. - `emergency = defibrillator` - this tag must be present - `and access !~ private|no` - - and `access` tag must not have values `private` or `no` to skip ones where mapper will be unable to survey (`!~ private|no` - to be more specific `optionA|optionB` is treated like `^optionA|optionB$` [regexp](https://en.wikipedia.org/wiki/Regular_expression)) + - and `access` tag must not have values `private` or `no` + - `!~ private|no` is transformed into `^optionA|optionB$` [regexp](https://en.wikipedia.org/wiki/Regular_expression) + - This is included to skip object where mapper will likely has no access to survey - `and !indoor` - and `indoor` key must not be present at all, to show only ones where this tag is still missing From 879880534badd56605a6ac4fdfe877ffd6edd67a Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 28 Mar 2022 16:52:55 +0200 Subject: [PATCH 119/181] better grammar --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index e441f3a2f8..839add0046 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -157,7 +157,7 @@ This query will be limited to object which fulfill some requirements. - `and access !~ private|no` - and `access` tag must not have values `private` or `no` - `!~ private|no` is transformed into `^optionA|optionB$` [regexp](https://en.wikipedia.org/wiki/Regular_expression) - - This is included to skip object where mapper will likely has no access to survey + - this filter excludes objects where mapper will likely has no access necessary for survey - `and !indoor` - and `indoor` key must not be present at all, to show only ones where this tag is still missing From 1f932934bfb868e218fa2f4f99dbba9635f5c11a Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 28 Mar 2022 17:05:07 +0200 Subject: [PATCH 120/181] more clear info --- CONTRIBUTING_A_NEW_QUEST.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 839add0046..205f3077d5 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -280,7 +280,9 @@ In this case it would set `indoor` tag to have either `yes` or `no` answer, depe Actions may include (examples from various quests): - `tags["indoor"] = answer.toYesNo()` -- `tags.remove("amenity")` - remove key if it is present + - set `indoor` tag to have either `yes` or `no` answer, based on provided data +- `tags.remove("amenity")` + - remove key if it is present - `tags.updateWithCheckDate("lit", answer.toYesNo())` - if the new value differs from existing tag value: new value will be applied - in case of value being the same: add survey date tag, it would be `check_date:lit=` in this case From f098eabefbf01aee391d13e138e3272ea4464678 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 28 Mar 2022 18:15:32 +0200 Subject: [PATCH 121/181] deleting docs that become irrelevant --- CONTRIBUTING_A_NEW_QUEST.md | 73 +------------------------------------ 1 file changed, 1 insertion(+), 72 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 205f3077d5..026000ad17 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -403,78 +403,7 @@ What was described above is an attempt to cover all aspects of quest creation, w Below is some additional info. -## getTitle and getTitleArgs - -In some cases it is desirable to change quest title, based on specific object. - -This requires preparing space in the message for filling at runtime, and to add the mechanism supplying data to replace placeholders. - -### Display value of tag if it is present - -[AddFireHydrantDiameter](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/fire_hydrant_diameter/AddFireHydrantDiameter.kt) displays `ref` code of hydrant, if tagged. - -```kotlin -override fun getTitleArgs(tags: Map, featureName: Lazy): Array = - arrayOfNotNull(tags["ref"]) - -override fun getTitle(tags: Map): Int { - val hasRef = tags.containsAnyKey("ref") - return when { - hasRef -> R.string.quest_fireHydrant_diameter_ref_title - else -> R.string.quest_fireHydrant_diameter_title - } -} -``` - -`getTitleArgs` will return either array with single element containing value of `ref` tag or an empty array. In either cases it will be passed to code displaying title at runtime. - -`arrayOfNotNull` is a minor helper function [defined in StreetComplete](app/src/main/java/de/westnordost/streetcomplete/ktx/Collections.kt). Note that when you open code in Android Studio or other IDE you can easily go to place where given function is defined. - -`getTitle` provide identifier of text which will be - -So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either: - -* `quest_fireHydrant_diameter_ref_title` which represents `What diameter is specified on the sign for this fire hydrant? (reference number: %s)` (or translation). `%s` is a [placeholder](https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings) and will be replaced by text provided by `getTitleArgs` -* In case of ref tag being not present `quest_fireHydrant_diameter_title` (`What diameter is specified on the sign for this fire hydrant?`) will be used. - -This is quite complex but allows translating application in various languages by decoupling exact text being displayed from the code. See for example identifiers with texts in [Polish translation](app/src/main/res/values-pl/strings.xml). - -### Use feature name if present - -In some cases, the quest will mention the name of object (lets say "Knight") and type of feature (maybe restaurant? Or supermarket?). - -For example, in the case of shops it may be necessary to identify specific one among several. - -Here is [some typical code](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L104-L115) that will: - -```kotlin -override fun getTitle(tags: Map) = - if (hasFeatureName(tags)) - R.string.quest_wheelchairAccess_name_type_title - else - R.string.quest_wheelchairAccess_name_title - -override fun getTitleArgs(tags: Map, featureName: Lazy): Array { - val name = tags["name"] ?: tags["brand"] - return arrayOfNotNull(name, featureName.value) -} -``` - -- `getTitleArgs` tries to pass to the title - - name of the object - - brand of the object (only if `name` tag is not used, and `brand` tag is present) - - feature name (such as "greengrocer", translated to the proper language, based on [iD presets](https://github.com/westnordost/osmfeatures)) - -[Filtering in the element selection](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/wheelchair_access/AddWheelchairAccessBusiness.kt#L20) ensures that every object will have either `name` or `brand` tag. - -Though description from iD presets is not guaranteed. - -So `getTitle` function that returns identifier to text in [strings file](app/src/main/res/values/strings.xml). It will be either - -* `quest_wheelchairAccess_name_type_title` which represents `Is %1$s (%2$s) wheelchair accessible?` (or translation). `%1$s` and `%2$s` [placeholders](https://developer.android.com/guide/topics/resources/string-resource.html#formatting-strings) will be replaced by text provided by `getTitleArgs` -* In case of no feature name being available `quest_wheelchairAccess_name_title` will be used, with space for one parameter: `Is %s wheelchair accessible?` (`%s` is a single placeholder which will be replaced by text parameter) - -### Kotlin +## Kotlin Article about [null safety related syntax](https://kotlinlang.org/docs/null-safety.html) is likely to be very useful, especially if you are confused by `?:` [Elvis operator](https://kotlinlang.org/docs/null-safety.html#elvis-operator). From db5cea66960b1ec438f2dfa673ab88453ca08d02 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 01:22:35 +0200 Subject: [PATCH 122/181] apply more tweaks to documentation --- CONTRIBUTING_A_NEW_QUEST.md | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 026000ad17..e31a3f3e96 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -23,7 +23,7 @@ But this materials may help or be quicker than trying to fully explore on your o - setting up Android Studio will likely be more complex than writing the code - [basic ability to use git](https://git-scm.com/docs/user-manual) (but as mentioned, anything GitHub specific will be explained) - there is version control integration available in Android Studio - - From the Android Studio **VCS** menu, click **Enable Version Control** Integration ([see official docs](https://developer.android.com/studio/intro#version_control_basics)) + - From the Android Studio **VCS** menu, click **Enable Version Control Integration** ([see official docs](https://developer.android.com/studio/intro#version_control_basics)) - Go to File -> Settings -> Version control in Android Studio to optionally configure git integration - Using git from command line or terminal in Android Studio also works fine - GitHub [account](https://github.com/signup) @@ -37,6 +37,8 @@ But this materials may help or be quicker than trying to fully explore on your o - visit [https://github.com/streetcomplete/StreetComplete](https://github.com/streetcomplete/StreetComplete) and press the "fork" button on the top right - this creates a copy of StreetComplete repository that you control and can prepare code there - clone your fork of a StreetComplete repository + - in Android Studio it can be achieved without command line ( File -> New -> Project from Version Control... ) + - see [Github Documentation](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) how repository can be cloned and where its URL can be found - open StreetComplete in Android Studio - [setup an emulator in Android Studio](https://developer.android.com/studio/run/emulator#install) (you can also [connect to a real device via USB](https://developer.android.com/studio/run/device), this can replace using the emulator) - run StreetComplete in the emulator (to verify that everything was setup as required) @@ -55,16 +57,28 @@ You can also look at [quest proposals waiting for implementation](https://github # Prepare repository for development -That is a good moment to create a branch and switch to it. It can be done with the following command: +That is a good moment to create a branch and switch to it. + +It can be done using Android Studio GUI (Git -> New branch...), or in CLI with the following command: ```bash git checkout -b short_branch_name_describing_planned_work ``` +In general, [Intellij documentation](https://www.jetbrains.com/help/idea/using-git-integration.html) about git integration is applicable to Android Studio (which is rebranded Intellij with minor modifications). + # Learn from existing code ## Find a base +### Hints for looking around code + +Full text search (ctrl+shift+f or [grepping](https://github.com/BurntSushi/ripgrep#ripgrep-rg)) remains useful and powerful. + +But "Find usages" (alt+F7) is also a very powerful way to find where given function/constant/property/etc is appearing, classified by usages. + +### Base on existing + Base the new quest on one that exists already. Find one that has the same type of interface as the one that you are trying to implement. @@ -75,6 +89,8 @@ Is it going to be asked for POIs and should be disabled by default? [`AddWheelch Quests are grouped in [one folder](app/src/main/java/de/westnordost/streetcomplete/quests). +Implementing quest by duplicating and modifiying existing one is the recommended method. + ### Locating a quest Search across the code for part of a question or other text specific to this quest. For example "the name of this place?". @@ -91,12 +107,6 @@ Search for this identifier in `*.kt` files, it should appear in the quest file ( This method can often be used to locate relevant code. -### Hints for looking around code - -Full text search (ctrl+shift+f or [grepping](https://github.com/BurntSushi/ripgrep#ripgrep-rg)) remains useful and powerful. - -But "Find usages" (alt+F7) is also a very powerful way to find where given function/constant/property/etc is appearing, classified by usages. - ## Pull Requests One of the better ways to get around a codebase that is new to you is to look at recent accepted proposals to change the code (pull requests). @@ -111,12 +121,16 @@ This can be also used to locate relevant code, especially helpful if some change # Copying -Copy the relevant quest folder. Some contain multiple quests, in such case copy only what you need. +Duplicate the relevant quest folder from [`app/src/main/java/de/westnordost/streetcomplete/quests`](app/src/main/java/de/westnordost/streetcomplete/quests). Some contain multiple quests, in such case delete unnecessary files. Some quests are entirely defined in a single file, some have additional answer class, custom interface or utility classes. # Adjust the copy +TODO: rename using refactor? +TODO: rename using file rename? +TODO: check for side efects + After the quest is copied it is necessary to adjust it a bit so it is not a duplicate anymore. Change its class name and the file name to the new one. @@ -129,6 +143,8 @@ Adjust [QuestsModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/ Add your quest to the list so that it will be loaded by the app. +As this point you can run the app in emulator - everything should work and one of quests will appear twice. + ## Quest anatomy See for example [simple yes/no quest asking whether AED is indoor or outdoor](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt). From e8d458f03545ed4a70b408982a768fab1f8339e9 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 01:27:57 +0200 Subject: [PATCH 123/181] search hint --- CONTRIBUTING_A_NEW_QUEST.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index e31a3f3e96..1dbb0cc27a 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -107,6 +107,8 @@ Search for this identifier in `*.kt` files, it should appear in the quest file ( This method can often be used to locate relevant code. +Search can be brought up with [Ctrl+Shift+f](https://www.jetbrains.com/help/idea/finding-and-replacing-text-in-file.html). + ## Pull Requests One of the better ways to get around a codebase that is new to you is to look at recent accepted proposals to change the code (pull requests). From d0bbd98847a385a82adb9bd02963f4be6ec143ed Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 01:29:15 +0200 Subject: [PATCH 124/181] deduplicate --- CONTRIBUTING_A_NEW_QUEST.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 1dbb0cc27a..cca9fb0d0d 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -73,7 +73,7 @@ In general, [Intellij documentation](https://www.jetbrains.com/help/idea/using-g ### Hints for looking around code -Full text search (ctrl+shift+f or [grepping](https://github.com/BurntSushi/ripgrep#ripgrep-rg)) remains useful and powerful. +Full text search ([ctrl+shift+f](https://www.jetbrains.com/help/idea/finding-and-replacing-text-in-file.html) or [grepping](https://github.com/BurntSushi/ripgrep#ripgrep-rg)) remains useful and powerful. But "Find usages" (alt+F7) is also a very powerful way to find where given function/constant/property/etc is appearing, classified by usages. @@ -107,8 +107,6 @@ Search for this identifier in `*.kt` files, it should appear in the quest file ( This method can often be used to locate relevant code. -Search can be brought up with [Ctrl+Shift+f](https://www.jetbrains.com/help/idea/finding-and-replacing-text-in-file.html). - ## Pull Requests One of the better ways to get around a codebase that is new to you is to look at recent accepted proposals to change the code (pull requests). From fbb37e5534462d7ac63fe76abe55395e6a0e9e18 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 01:31:42 +0200 Subject: [PATCH 125/181] Overpass Turbo mention --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index cca9fb0d0d..caed37be24 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -207,6 +207,10 @@ This quest will be triggered when: - element was not edited for a long time (base time is 4 years, but it can be influenced by user changing settings) - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) +###### Prototyping + +[Overpass Turbo](http://overpass-turbo.eu/) has own syntax but it is very useful tool for prototyping filters. It is very useful to verify own assumptions how things are tagged. Especially in more complex cases. + #### Hints The rules should generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. From e61580903065479e0abc307b0db118cda47e75cf Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 01:46:42 +0200 Subject: [PATCH 126/181] reduce depth of sections, minor rewrite --- CONTRIBUTING_A_NEW_QUEST.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index caed37be24..a147811406 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -145,15 +145,17 @@ Add your quest to the list so that it will be loaded by the app. As this point you can run the app in emulator - everything should work and one of quests will appear twice. -## Quest anatomy +# Modify the template + +At this point prepared template can be modified to achieve the intended effect. See for example [simple yes/no quest asking whether AED is indoor or outdoor](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt). TODO: maybe linking [app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt](app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt) would be better? And extend documentation there? -### Element selection +## Element selection -elementFilter property defines nodes, ways and relations which will be selected for a given quest. It is an element selection used by OsmFilterQuestType. +`elementFilter` property defines nodes, ways and relations which will be selected for a given quest. It is an element selection used by OsmFilterQuestType. ```kotlin """ @@ -179,7 +181,7 @@ This query will be limited to object which fulfill some requirements. It is specified as a string, in syntax specific to StreetComplete. You can look around some quests to see how it works. If you are trying to implement a new quest and you got stuck here, [open a new issue](https://github.com/streetcomplete/StreetComplete/issues) to request more thorough documentation here. -###### Resurvey +### Resurvey Some quests are asked not only when tag is missing but also when it is likely to be outdated. @@ -207,21 +209,19 @@ This quest will be triggered when: - element was not edited for a long time (base time is 4 years, but it can be influenced by user changing settings) - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) -###### Prototyping +### Prototyping [Overpass Turbo](http://overpass-turbo.eu/) has own syntax but it is very useful tool for prototyping filters. It is very useful to verify own assumptions how things are tagged. Especially in more complex cases. -#### Hints +## Hints The rules should generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. In some cases it will be a good idea to [limit quests to certain countries](#enabledInCountries). -### Properties - You can obtain more info about properties by placing the cursor in a property and pressing Ctrl+Q within Android Studio. -#### changesetComment +## changesetComment ```kotlin override val changesetComment = "Add whether defibrillator is inside building" @@ -229,7 +229,7 @@ override val changesetComment = "Add whether defibrillator is inside building" message used as a changeset comment -#### wikiLink +## wikiLink ```kotlin override val wikiLink = "Key:indoor" @@ -237,7 +237,7 @@ override val wikiLink = "Key:indoor" points to the OSM Wiki page most relevant to the given quest, typically it is an added key. In this case, it is a page about [indoor=* tagging](https://wiki.openstreetmap.org/wiki/Key:indoor). -#### icon +## icon ```kotlin override val icon = R.drawable.ic_quest_defibrillator @@ -249,7 +249,7 @@ Do not worry, submissions with placeholder icons are also welcomed! In many case More info about icon handling [will be given later](#adding-quest-icon). -#### questTypeAchievements +## questTypeAchievements ```kotlin override val questTypeAchievements = listOf(LIFESAVER) @@ -257,7 +257,7 @@ override val questTypeAchievements = listOf(LIFESAVER) In quest achievements, list what is relevant to the given quest, see the full list of available ones in [AchievementsModule.kt](app/src/main/java/de/westnordost/streetcomplete/data/user/achievements/AchievementsModule.kt) -#### getTitle +## getTitle ```kotlin override fun getTitle(tags: Map) = R.string.quest_is_defibrillator_inside_title @@ -269,7 +269,7 @@ Actual strings sit in [app/src/main/res/values/strings.xml](app/src/main/res/val There are separate files with translated text, but do not worry about it - [translations are handled separately](CONTRIBUTING.md#translating-the-app). -#### Form +## Form ```kotlin override fun createForm() = YesNoQuestAnswerFragment() @@ -285,7 +285,7 @@ But sometimes more complex ones are needed, see for example [AddBridgeStructure. With form defined in [AddBridgeStructureForm](app/src/main/java/de/westnordost/streetcomplete/quests/bridge_structure/AddBridgeStructureForm.kt) -### applyAnswerTo +## applyAnswerTo ```kotlin override fun applyAnswerTo(answer: Boolean, tags: Tags, timestampEdited: Long) { @@ -311,9 +311,9 @@ Actions may include (examples from various quests): - always update survey tag if present already - necessary if given quest includes resurvey of old elements that are already tagged -### Extras +## Extras -Info listed above must be supplied by every quest. But there are also several optional fields. This specific quest has +Info listed so far must be supplied by every quest. But there are also several optional fields. This specific quest has ```kotlin override fun getHighlightedElements(element: Element, getMapData: () -> MapDataWithGeometry) = @@ -324,7 +324,7 @@ which causes nearby `emergency = defibrillator` nodes to be shown (icons used ar See [also other optional properties](app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt). -### Adding quest icon +# Adding quest icon It is OK to submit a quest without own icon, using any icon as a placeholder. From 964cdce98fcde4f5cc7e33e0119a1a61641bb6f6 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 06:07:18 +0200 Subject: [PATCH 127/181] prepare step by step commit setup --- CONTRIBUTING_A_NEW_QUEST.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index a147811406..d17d4448e2 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -125,6 +125,12 @@ Duplicate the relevant quest folder from [`app/src/main/java/de/westnordost/stre Some quests are entirely defined in a single file, some have additional answer class, custom interface or utility classes. +For example, lets imagine that new quest will ask whether [AED](https://wiki.openstreetmap.org/wiki/Tag:emergency%3Ddefibrillator) is placed indoor or outdoor. A very similar in mechanics quest with simple yes/no question is for example [quest asking "Is this bicycle parking covered (protected from rain)?"](app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_cover/AddBikeParkingCover.kt). + +So, as the first step: lets copy [`app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_cover/`](app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_cover) folder into `app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/`. + +This is commit XXXXXXXXXXXXXXXXXXX TODO XXXXXXXXXXXXXXXXX in the demonstration repository. + # Adjust the copy TODO: rename using refactor? From 4474cc83c80243a083ae9b2e6561b3a05610c2e9 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 06:40:33 +0200 Subject: [PATCH 128/181] other people exist --- CONTRIBUTING_A_NEW_QUEST.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index d17d4448e2..ef2fba1d64 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -107,6 +107,10 @@ Search for this identifier in `*.kt` files, it should appear in the quest file ( This method can often be used to locate relevant code. +### Other people + +The issue proposing a quest may also contain hint which quests are similar. If you are unsure what would be a good base - you can ask in issue discussion to confirm what you found or ask for help in finding a good base for a given issue. + ## Pull Requests One of the better ways to get around a codebase that is new to you is to look at recent accepted proposals to change the code (pull requests). From 2c496a35a9424e6ebababe86e484822249ccfde8 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 07:05:15 +0200 Subject: [PATCH 129/181] warn about too powerful IDE --- CONTRIBUTING_A_NEW_QUEST.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index ef2fba1d64..386826f07d 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -137,16 +137,14 @@ This is commit XXXXXXXXXXXXXXXXXXX TODO XXXXXXXXXXXXXXXXX in the demonstration r # Adjust the copy -TODO: rename using refactor? -TODO: rename using file rename? -TODO: check for side efects - After the quest is copied it is necessary to adjust it a bit so it is not a duplicate anymore. Change its class name and the file name to the new one. In copied code change package info (things like `package de.westnordost.streetcomplete.quests.defibrillator` at the top) to match the new folder containing the quest. +When commiting changes be careful to not change already existing quest - only new code (using built-in refactoring rename will affect also `QuestsModule.kt` entry for an existing quest). + # Add the quest to the list of active ones Adjust [QuestsModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt) file. It contains a big list of active quests, ordered by priority. Read [what governs their priority](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt#L172-L195) but do not worry too much, it can be tweaked later. From 02f5897a393619e190a203f0243e420fe8d75215 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 07:05:42 +0200 Subject: [PATCH 130/181] use larger sample of code --- CONTRIBUTING_A_NEW_QUEST.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 386826f07d..20c45347c2 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -166,12 +166,12 @@ TODO: maybe linking [app/src/main/java/de/westnordost/streetcomplete/data/osm/os `elementFilter` property defines nodes, ways and relations which will be selected for a given quest. It is an element selection used by OsmFilterQuestType. ```kotlin -""" - nodes with - emergency = defibrillator - and access !~ private|no - and !indoor -""" + override val elementFilter = """ + nodes with + emergency = defibrillator + and access !~ private|no + and !indoor + """ ``` This query will be limited to object which fulfill some requirements. From 31858a6a741d181a96e21ed36124057f68d0ecd0 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 07:08:20 +0200 Subject: [PATCH 131/181] correct depth --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 20c45347c2..e93fdb3655 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -221,7 +221,7 @@ This quest will be triggered when: [Overpass Turbo](http://overpass-turbo.eu/) has own syntax but it is very useful tool for prototyping filters. It is very useful to verify own assumptions how things are tagged. Especially in more complex cases. -## Hints +### Hints The rules should generate as few false positives as possible. I.e. instead of asking for the surface of any way tagged with `highway=*`, the surface should instead only be asked for an inclusive list of roads. From 2d35a834cf977863bf15b35fa8f3179ad00c555e Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 07:12:22 +0200 Subject: [PATCH 132/181] document isDeleteElementEnabled --- CONTRIBUTING_A_NEW_QUEST.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index e93fdb3655..36d8838517 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -512,3 +512,9 @@ Some quests should be disabled by default, for example ones that may require goi - on attempting to enable it user will get message asking are they sure. Exact message in this case would be `default_disabled_msg_go_inside` - but some quests use more specific ones. Note that quest may be both disabled by default and limited to some countries. + +## `isDeleteElementEnabled` + +This will decode whether user should have access to direct deletion of elements. Note that ways and relations cannot be deleted by SC users. + +For nodes within ways, node will remain and tags will be removed. From f51e0bc0ae8c9ac8e4617ed2340fc4e23b941f5c Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 09:03:54 +0200 Subject: [PATCH 133/181] link example commits this repo can be migrated to SC organization --- CONTRIBUTING_A_NEW_QUEST.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 36d8838517..35ae5302a2 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -133,7 +133,7 @@ For example, lets imagine that new quest will ask whether [AED](https://wiki.ope So, as the first step: lets copy [`app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_cover/`](app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_cover) folder into `app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/`. -This is commit XXXXXXXXXXXXXXXXXXX TODO XXXXXXXXXXXXXXXXX in the demonstration repository. +This is done in [this commit](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/7d9ad571f521055a4c5a0006743762fd16e4c9d6) in the demonstration repository. # Adjust the copy @@ -145,6 +145,8 @@ In copied code change package info (things like `package de.westnordost.streetco When commiting changes be careful to not change already existing quest - only new code (using built-in refactoring rename will affect also `QuestsModule.kt` entry for an existing quest). +See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/9c65d00c7d096c3fee61650e1465a43b7e7f5712) in the example repository. + # Add the quest to the list of active ones Adjust [QuestsModule.kt](app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt) file. It contains a big list of active quests, ordered by priority. Read [what governs their priority](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt#L172-L195) but do not worry too much, it can be tweaked later. @@ -153,6 +155,8 @@ Add your quest to the list so that it will be loaded by the app. As this point you can run the app in emulator - everything should work and one of quests will appear twice. +See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/b4f01eeb752f92fd6927fbb9a943ea19a4799eec) in the example repository. + # Modify the template At this point prepared template can be modified to achieve the intended effect. @@ -189,6 +193,9 @@ This query will be limited to object which fulfill some requirements. It is specified as a string, in syntax specific to StreetComplete. You can look around some quests to see how it works. If you are trying to implement a new quest and you got stuck here, [open a new issue](https://github.com/streetcomplete/StreetComplete/issues) to request more thorough documentation here. + +See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/2726ff1c7b3121825e808c4566e6e534392121b3) in the example repository. + ### Resurvey Some quests are asked not only when tag is missing but also when it is likely to be outdated. @@ -237,6 +244,8 @@ override val changesetComment = "Add whether defibrillator is inside building" message used as a changeset comment +See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/0db8827133b07ce32c3c1287604198efeabc7bf6) in the example repository. + ## wikiLink ```kotlin @@ -245,6 +254,8 @@ override val wikiLink = "Key:indoor" points to the OSM Wiki page most relevant to the given quest, typically it is an added key. In this case, it is a page about [indoor=* tagging](https://wiki.openstreetmap.org/wiki/Key:indoor). +See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/13ec6b97b52413cf09f3b71311b877b746d29576) in the example repository. + ## icon ```kotlin @@ -257,6 +268,8 @@ Do not worry, submissions with placeholder icons are also welcomed! In many case More info about icon handling [will be given later](#adding-quest-icon). +See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/7cecce384a5baf365119fd3453d600a87f87fadb) in the example repository. + ## questTypeAchievements ```kotlin @@ -265,6 +278,8 @@ override val questTypeAchievements = listOf(LIFESAVER) In quest achievements, list what is relevant to the given quest, see the full list of available ones in [AchievementsModule.kt](app/src/main/java/de/westnordost/streetcomplete/data/user/achievements/AchievementsModule.kt) +See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/f043440b43ad84d321c7aae4fd03095c34af8eb4) in the example repository. + ## getTitle ```kotlin @@ -277,6 +292,8 @@ Actual strings sit in [app/src/main/res/values/strings.xml](app/src/main/res/val There are separate files with translated text, but do not worry about it - [translations are handled separately](CONTRIBUTING.md#translating-the-app). +See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/5fe2b8149b25ac375a09a45ad949dc804d687825) in the example repository. + ## Form ```kotlin @@ -319,6 +336,8 @@ Actions may include (examples from various quests): - always update survey tag if present already - necessary if given quest includes resurvey of old elements that are already tagged +See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/04aa86351a9b3634a7a0e034e47936b2c4e17f9b) in the example repository. + ## Extras Info listed so far must be supplied by every quest. But there are also several optional fields. This specific quest has @@ -332,6 +351,8 @@ which causes nearby `emergency = defibrillator` nodes to be shown (icons used ar See [also other optional properties](app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt). +See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/1d648e56562d16a5dc3588ca7de8558f97d5919a) in the example repository. + # Adding quest icon It is OK to submit a quest without own icon, using any icon as a placeholder. From 2ee4278e1a75fd3f268bf904992a2ef4fd6fdb2c Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 09:05:10 +0200 Subject: [PATCH 134/181] one extra removal --- CONTRIBUTING_A_NEW_QUEST.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 35ae5302a2..de7e18e099 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -353,6 +353,8 @@ See [also other optional properties](app/src/main/java/de/westnordost/streetcomp See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/1d648e56562d16a5dc3588ca7de8558f97d5919a) in the example repository. +Note that for this quest one extra property present in the original quest used as a template [was removed](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/a9fd3efe96cbc6241b3b0f65d4a2be27f1c6afb8) + # Adding quest icon It is OK to submit a quest without own icon, using any icon as a placeholder. From 03f49791e0489806e06461ad8651420cc28b2e53 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 09:07:26 +0200 Subject: [PATCH 135/181] move resurvey to later section --- CONTRIBUTING_A_NEW_QUEST.md | 56 ++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index de7e18e099..665c4aac7f 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -196,34 +196,6 @@ It is specified as a string, in syntax specific to StreetComplete. You can look See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/2726ff1c7b3121825e808c4566e6e534392121b3) in the example repository. -### Resurvey - -Some quests are asked not only when tag is missing but also when it is likely to be outdated. - -Typical code is in [quest asking about motorcycle parking capacity](app/src/main/java/de/westnordost/streetcomplete/quests/motorcycle_parking_capacity/AddMotorcycleParkingCapacity.kt): - -```kotlin -override val elementFilter = """ - nodes, ways with amenity = motorcycle_parking - and access !~ private|no - and (!capacity or capacity older today -4 years) -""" -``` - -This quest will be triggered when: - -- `nodes, ways with` - - on nodes or ways (relations not eligible) -- `amenity = motorcycle_parking` - - where `amenity = motorcycle_parking` tag is present -- `and access !~ private|no` - - and `access` tag does not have value `private` nor `no` -- `and (!capacity or capacity older today -4 years)` - - and one of following is fullfilled: - - `capacity` tag is not present at all (`!capacity`) - - element was not edited for a long time (base time is 4 years, but it can be influenced by user changing settings) - - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) - ### Prototyping [Overpass Turbo](http://overpass-turbo.eu/) has own syntax but it is very useful tool for prototyping filters. It is very useful to verify own assumptions how things are tagged. Especially in more complex cases. @@ -497,6 +469,34 @@ The [rescaling script](https://github.com/matkoniecz/rescaling_for_android) may After adding a photo, remember to update [the credit file](app/src/main/res/authors.txt) (different to the one for icons). +## Resurvey + +Some quests are asked not only when tag is missing but also when it is likely to be outdated. To achieve this `elementFilter` needs to query not only elements missing some tags. + +Typical code is in [quest asking about motorcycle parking capacity](app/src/main/java/de/westnordost/streetcomplete/quests/motorcycle_parking_capacity/AddMotorcycleParkingCapacity.kt): + +```kotlin +override val elementFilter = """ + nodes, ways with amenity = motorcycle_parking + and access !~ private|no + and (!capacity or capacity older today -4 years) +""" +``` + +This quest will be triggered when: + +- `nodes, ways with` + - on nodes or ways (relations not eligible) +- `amenity = motorcycle_parking` + - where `amenity = motorcycle_parking` tag is present +- `and access !~ private|no` + - and `access` tag does not have value `private` nor `no` +- `and (!capacity or capacity older today -4 years)` + - and one of following is fullfilled: + - `capacity` tag is not present at all (`!capacity`) + - element was not edited for a long time (base time is 4 years, but it can be influenced by user changing settings) + - `check_date:capacity` with a date indicating that it is outdated (the same as above applies) + ## Custom filters It is possible to use far more complex filters when querying for eligible elements. From b31e485ab316159c424b53a8be69d4456f8c1558 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 09:08:03 +0200 Subject: [PATCH 136/181] decide against idea of moving info into javadoc comments --- CONTRIBUTING_A_NEW_QUEST.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 665c4aac7f..6f84176b7a 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -163,8 +163,6 @@ At this point prepared template can be modified to achieve the intended effect. See for example [simple yes/no quest asking whether AED is indoor or outdoor](app/src/main/java/de/westnordost/streetcomplete/quests/defibrillator/AddIsDefibrillatorIndoor.kt). -TODO: maybe linking [app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt](app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt) would be better? And extend documentation there? - ## Element selection `elementFilter` property defines nodes, ways and relations which will be selected for a given quest. It is an element selection used by OsmFilterQuestType. From 66a95632c227792aaac1c802d63602ef38827f30 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Wed, 30 Mar 2022 13:35:16 +0200 Subject: [PATCH 137/181] remove repeated info Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 6f84176b7a..685d0a7d84 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -13,7 +13,6 @@ But this materials may help or be quicker than trying to fully explore on your o # Required - programming ability - it is not a good task for someone who has never programmed anything. - - Setup of environment takes a long time - Editing even the simplest quest requires edits to at least three different files - Kotlin familiarity is not required, but the ability to adjust to a new syntax is needed. If you are unfamiliar with Kotlin reading about [null safety related syntax](https://kotlinlang.org/docs/null-safety.html) is likely to be very useful. - It is expected that someone trying this can search for a solution to a typical problem on encountering an error message From abc3cf83ac2ccb9365564337da63134ab5284b2a Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Mon, 4 Apr 2022 11:44:55 +0200 Subject: [PATCH 138/181] fix typos Co-authored-by: Matija Nalis --- CONTRIBUTING_A_NEW_QUEST.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 685d0a7d84..8447ca6440 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -456,9 +456,9 @@ Images should be free of visual debris, not misleading. Though it is fine to use Photos go to a different folder than SVGs: they can be used directly by the build process so put them into folders - [mdpi](app/src/main/res/drawable-mdpi) - 384 pixels for images, with three square images in each row it would be 128 x 128 pixels for each) -- [hdpi](app/src/main/res/drawable-hdpi) - 576 pixels for images (192 x 192 pixels in case of three quare images in each row) -- [xhdpi](app/src/main/res/drawable-xhdpi) 768 pixels for images (256 x 256 pixels in case of three quare images in each row) -- [xxhdpi](app/src/main/res/drawable-xxhdpi) 1152 pixels (384 x 384 pixels in case of three quare images in each row) +- [hdpi](app/src/main/res/drawable-hdpi) - 576 pixels for images (192 x 192 pixels in case of three square images in each row) +- [xhdpi](app/src/main/res/drawable-xhdpi) 768 pixels for images (256 x 256 pixels in case of three square images in each row) +- [xxhdpi](app/src/main/res/drawable-xxhdpi) 1152 pixels (384 x 384 pixels in case of three square images in each row) Each of these folders should hold the same image resized to a different resolution. While testing various images it is enough to put one into any of the folders. From d78896e6fde8aae243e78f02ff114d545500a3c7 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 10 Apr 2022 23:21:24 +0200 Subject: [PATCH 139/181] drop rotten link --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 8447ca6440..c4f262a313 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -301,7 +301,7 @@ Actions may include (examples from various quests): - if the new value differs from existing tag value: new value will be applied - in case of value being the same: add survey date tag, it would be `check_date:lit=` in this case - so can be used even if value will stay the same - possible for resurvey quests - - if the new value is the same as existing tag value: adds [survey date tag](app/src/main/java/de/westnordost/streetcomplete/data/meta/OsmTaggings.kt#L33) (`check_date:lit=` in this example) + - if the new value is the same as existing tag value: adds survey date tag (`check_date:lit=` in this example) - always update survey tag if present already - necessary if given quest includes resurvey of old elements that are already tagged From 69104b29640337401ba0ab8a8fd5973b85790076 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sun, 10 Apr 2022 23:54:00 +0200 Subject: [PATCH 140/181] drop Required section --- CONTRIBUTING_A_NEW_QUEST.md | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index c4f262a313..e7c0ede078 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -10,25 +10,6 @@ Reading the text below is not necessary to create a new quest. Duplicating exist But this materials may help or be quicker than trying to fully explore on your own how things work. -# Required - -- programming ability - it is not a good task for someone who has never programmed anything. - - Editing even the simplest quest requires edits to at least three different files - - Kotlin familiarity is not required, but the ability to adjust to a new syntax is needed. If you are unfamiliar with Kotlin reading about [null safety related syntax](https://kotlinlang.org/docs/null-safety.html) is likely to be very useful. - - It is expected that someone trying this can search for a solution to a typical problem on encountering an error message -- familiarity with StreetComplete as a user - it is highly recommended to be familiar with how StreetComplete works. Making hundreds of edits is not mandatory, but having a passing familiarity with how surveying with StreetComplete works is needed. -- time - Android Studio setup is sadly complicated - - Multiple hours are typical, though mostly spent on waiting for various downloads - - setting up Android Studio will likely be more complex than writing the code -- [basic ability to use git](https://git-scm.com/docs/user-manual) (but as mentioned, anything GitHub specific will be explained) - - there is version control integration available in Android Studio - - From the Android Studio **VCS** menu, click **Enable Version Control Integration** ([see official docs](https://developer.android.com/studio/intro#version_control_basics)) - - Go to File -> Settings -> Version control in Android Studio to optionally configure git integration - - Using git from command line or terminal in Android Studio also works fine -- GitHub [account](https://github.com/signup) -- around 15GB of free space on disk - - the initial setup will typically download half the Internet while getting emulators and dependencies - # Dependencies - initial setup - install necessary software ([Android Studio](https://developer.android.com/studio) and [git](https://git-scm.com/downloads)) @@ -316,7 +297,7 @@ override fun getHighlightedElements(element: Element, getMapData: () -> MapDataW getMapData().filter("nodes with emergency = defibrillator") ``` -which causes nearby `emergency = defibrillator` nodes to be shown (icons used are defined in [PinIcons.kt](app/src/main/java/de/westnordost/streetcomplete/map/PinIcons.kt)) +which causes nearby `emergency = defibrillator` nodes to be shown (icons used are defined in [PinIcons.kt](app/src/main/java/de/westnordost/streetcomplete/screens/main/map/PinIcons.kt)) See [also other optional properties](app/src/main/java/de/westnordost/streetcomplete/data/osm/osmquests/OsmElementQuestType.kt). @@ -456,9 +437,9 @@ Images should be free of visual debris, not misleading. Though it is fine to use Photos go to a different folder than SVGs: they can be used directly by the build process so put them into folders - [mdpi](app/src/main/res/drawable-mdpi) - 384 pixels for images, with three square images in each row it would be 128 x 128 pixels for each) -- [hdpi](app/src/main/res/drawable-hdpi) - 576 pixels for images (192 x 192 pixels in case of three square images in each row) -- [xhdpi](app/src/main/res/drawable-xhdpi) 768 pixels for images (256 x 256 pixels in case of three square images in each row) -- [xxhdpi](app/src/main/res/drawable-xxhdpi) 1152 pixels (384 x 384 pixels in case of three square images in each row) +- [hdpi](app/src/main/res/drawable-hdpi) - 576 pixels for images (192 x 192 pixels in case of three quare images in each row) +- [xhdpi](app/src/main/res/drawable-xhdpi) 768 pixels for images (256 x 256 pixels in case of three quare images in each row) +- [xxhdpi](app/src/main/res/drawable-xxhdpi) 1152 pixels (384 x 384 pixels in case of three quare images in each row) Each of these folders should hold the same image resized to a different resolution. While testing various images it is enough to put one into any of the folders. From 7d66156cbe998db995bacafdce227ae32917fa18 Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Mon, 25 Apr 2022 12:15:24 +0200 Subject: [PATCH 141/181] quare -> square Co-authored-by: Matija Nalis --- CONTRIBUTING_A_NEW_QUEST.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index e7c0ede078..83e2abcc83 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -437,9 +437,9 @@ Images should be free of visual debris, not misleading. Though it is fine to use Photos go to a different folder than SVGs: they can be used directly by the build process so put them into folders - [mdpi](app/src/main/res/drawable-mdpi) - 384 pixels for images, with three square images in each row it would be 128 x 128 pixels for each) -- [hdpi](app/src/main/res/drawable-hdpi) - 576 pixels for images (192 x 192 pixels in case of three quare images in each row) -- [xhdpi](app/src/main/res/drawable-xhdpi) 768 pixels for images (256 x 256 pixels in case of three quare images in each row) -- [xxhdpi](app/src/main/res/drawable-xxhdpi) 1152 pixels (384 x 384 pixels in case of three quare images in each row) +- [hdpi](app/src/main/res/drawable-hdpi) - 576 pixels for images (192 x 192 pixels in case of three square images in each row) +- [xhdpi](app/src/main/res/drawable-xhdpi) 768 pixels for images (256 x 256 pixels in case of three square images in each row) +- [xxhdpi](app/src/main/res/drawable-xxhdpi) 1152 pixels (384 x 384 pixels in case of three square images in each row) Each of these folders should hold the same image resized to a different resolution. While testing various images it is enough to put one into any of the folders. From 841906a162ef9135f8b6eabd300e8f7b726fe90a Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sat, 30 Apr 2022 09:54:49 +0200 Subject: [PATCH 142/181] fix English Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 83e2abcc83..640cf2b75c 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -468,7 +468,7 @@ This quest will be triggered when: - `amenity = motorcycle_parking` - where `amenity = motorcycle_parking` tag is present - `and access !~ private|no` - - and `access` tag does not have value `private` nor `no` + - and `access` tag does neither have value `private` nor `no` - `and (!capacity or capacity older today -4 years)` - and one of following is fullfilled: - `capacity` tag is not present at all (`!capacity`) From 3441fe43c87716a07143eec5dc98c7401e5d484f Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sat, 30 Apr 2022 09:56:40 +0200 Subject: [PATCH 143/181] better phrasing Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 640cf2b75c..db7d30f6cc 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -317,7 +317,7 @@ A new icon can reuse the content of [other quest icons](res/graphics/quest), it Keep similar style to existing ones and app in general. Once the quest icon is ready: -- save as "Plain SVG" or clean SVG file from unnecessary cruft in another way, like using [svgo](https://github.com/svg/svgo) +- when using Inkscape, save as "Optimized SVG" to remove unnecessary cruft or use another tool for that, like [svgo](https://github.com/svg/svgo) - Put SVG into [`res/graphics/quest`](res/graphics/quest) folder - SVG is a standard format editable in various software, unlike internal Android Studio XML that will be produced in the next steps. - Open Android Studio From b6b80c4c5d30ee3b95c80798ae673f19213ac812 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sat, 30 Apr 2022 20:37:00 +0200 Subject: [PATCH 144/181] direct to existing documentation Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index db7d30f6cc..8069bb9d60 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -169,7 +169,7 @@ This query will be limited to object which fulfill some requirements. - `and !indoor` - and `indoor` key must not be present at all, to show only ones where this tag is still missing -It is specified as a string, in syntax specific to StreetComplete. You can look around some quests to see how it works. If you are trying to implement a new quest and you got stuck here, [open a new issue](https://github.com/streetcomplete/StreetComplete/issues) to request more thorough documentation here. +See the documentation of [`ElementFilterExpression`](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/data/elementfilter/ElementFilterExpression.kt) for a complete documentation of the syntax. You can look around some quests to see more examples of such element filter expressions. See [this step](https://github.com/matkoniecz/StreetComplete_quest_creation_tutorial/commit/2726ff1c7b3121825e808c4566e6e534392121b3) in the example repository. From 9d1af6e8b99330b15c49fa61d92309101c7eabad Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sat, 30 Apr 2022 20:37:22 +0200 Subject: [PATCH 145/181] add one more resource Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 8069bb9d60..9fd0e957e9 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -313,7 +313,7 @@ But it would be even better to include also icon. Note that there are some graphics which haven't been used yet, created for proposed or expected quests; maybe you don't even need to create an icon! -A new icon can reuse the content of [other quest icons](res/graphics/quest), it can be based on openly licensed graphics. See [the attribution file](res/graphics/authors.txt) for what was used so far. +A new icon can reuse the content of [other quest icons](res/graphics/quest), it can be based on openly licensed graphics such as ones from [svgrepo.com](https://www.svgrepo.com/). See [the attribution file](res/graphics/authors.txt) for what was used so far. Keep similar style to existing ones and app in general. Once the quest icon is ready: From 9e1447a9d745c233d312cda127e1ecc76a40885b Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sat, 30 Apr 2022 20:37:46 +0200 Subject: [PATCH 146/181] mention typical licenses Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 9fd0e957e9..904f96a3e6 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -424,7 +424,7 @@ Considerations about the edge cases to consider, how the design could look like Some quests will require photos for their interface. -Photos must be available on open license - so not every photo found on the Internet is usable. You can either take your own photo or find an existing freely licensed photo. +Photos must be available on open license - so not every photo found on the Internet is usable. You can either take your own photo or find an existing freely licensed photo. Licenses acceptable for photos are public domain, CC-0, CC-BY and CC-BY-SA licenses. Good places to find freely licensed images are [Geograph](https://www.geograph.org.uk/) and [Wikimedia Commons](https://commons.wikimedia.org/). From 04ca536ed2700657f730d88e9d580003c5659c70 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sat, 30 Apr 2022 20:37:57 +0200 Subject: [PATCH 147/181] fix English Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 904f96a3e6..689b8f9501 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -445,7 +445,7 @@ Each of these folders should hold the same image resized to a different resoluti The [rescaling script](https://github.com/matkoniecz/rescaling_for_android) may be useful, but you can also do this manually with Gimp or similar software. -After adding a photo, remember to update [the credit file](app/src/main/res/authors.txt) (different to the one for icons). +After adding a photo, remember to update [the credits file](app/src/main/res/authors.txt) (different to the one for icons). ## Resurvey From 645c8fcc65ad0a0ee96732281f5ba0780582adc0 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sat, 30 Apr 2022 20:43:49 +0200 Subject: [PATCH 148/181] hints how to use IDE Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 689b8f9501..2cf998f97f 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -53,8 +53,13 @@ In general, [Intellij documentation](https://www.jetbrains.com/help/idea/using-g ### Hints for looking around code -Full text search ([ctrl+shift+f](https://www.jetbrains.com/help/idea/finding-and-replacing-text-in-file.html) or [grepping](https://github.com/BurntSushi/ripgrep#ripgrep-rg)) remains useful and powerful. +Full text search ([ctrl+shift+f](https://www.jetbrains.com/help/idea/finding-and-replacing-text-in-file.html) is always useful. +Use Ctrl+N to go to a certain class. Ctrl+ mouseclick on a function, class, etc. leads to where it is defined. + +Use Ctrl+Q (but not on MacOS 😉) after having marked a class, symbol or function to display the documentation for it. + +With Ctrl+Shift+A you can find and explore **any** action you can do in Android Studio (try it by typing for example "go to"). But "Find usages" (alt+F7) is also a very powerful way to find where given function/constant/property/etc is appearing, classified by usages. ### Base on existing From 7011ec61d839a2dec77df0324e4ac46b5fd5a45c Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Sat, 30 Apr 2022 21:18:17 +0200 Subject: [PATCH 149/181] Update CONTRIBUTING_A_NEW_QUEST.md Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 2cf998f97f..80a54f9475 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -387,7 +387,7 @@ After opening a pull request it will be reviewed and you will be likely asked to Changes typically include improving code style, tweaking phrasing and quest settings. -You are also welcome to help with reviewing other PRs - different people have different strengths, there are active reviewers who help with code style, there are some native speakers of English, some with deep knowledge of OSM tagging schemes or deep knowledge of how StreetComplete works. +When you know more about the code, style and quest guidelines and general architecture of StreetComplete, you are also welcome to help with reviewing other PRs - different people have different strengths, there are active reviewers who help with code style, there are some native speakers of English, some with deep knowledge of OSM tagging schemes or deep knowledge of how StreetComplete works. In case that pull requests appears to be ready, it will be marked as approved and wait for merge. From 29c8c0a06bb591fef1a7da4e0475a3a38decf0e0 Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Wed, 4 May 2022 01:10:31 +0200 Subject: [PATCH 150/181] fix handling server errors --- .../data/osmnotes/StreetCompleteImageUploader.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/de/westnordost/streetcomplete/data/osmnotes/StreetCompleteImageUploader.kt b/app/src/main/java/de/westnordost/streetcomplete/data/osmnotes/StreetCompleteImageUploader.kt index 9ac288eab2..889926267e 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/data/osmnotes/StreetCompleteImageUploader.kt +++ b/app/src/main/java/de/westnordost/streetcomplete/data/osmnotes/StreetCompleteImageUploader.kt @@ -50,8 +50,8 @@ class StreetCompleteImageUploader(private val baseUrl: String) { throw ImageUploadServerException("Upload Failed: Unexpected response \"$response\"") } } else { - val error = connection.errorStream.bufferedReader().use { it.readText() }.toInt() - if (error / 100 == 5) + val error = connection.errorStream.bufferedReader().use { it.readText() } + if (status / 100 == 5) throw ImageUploadServerException("Upload failed: Error code $status, Message: \"$error\"") else throw ImageUploadClientException("Upload failed: Error code $status, Message: \"$error\"") From 96e52b64ce984961259cf6ab0acbba8d371f318f Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Wed, 4 May 2022 14:32:32 +0200 Subject: [PATCH 151/181] mention the unofficial mastodon news&support mastodon acccount by @RubenKelevra (#4002) --- app/src/main/res/raw/credits_projects.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/raw/credits_projects.yml b/app/src/main/res/raw/credits_projects.yml index 52b6c6d288..41c3c74b31 100644 --- a/app/src/main/res/raw/credits_projects.yml +++ b/app/src/main/res/raw/credits_projects.yml @@ -1,5 +1,5 @@ - Jannik Vieten (exploide) created the photo upload service for StreetComplete - ENT8R created an API to query oneway data from improveOSM - ENT8R created the map stylesheets for StreetComplete -- Ruben Kelevra maintains an unofficial Twitter account for news and support +- Ruben Kelevra maintains unofficial Twitter and Mastodon accounts for news and support - Nils Rokita maintained the map tileserver used till v20, map-data.de From f300907baeed2b51aaa7115ce3d0074690581cfc Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Thu, 5 May 2022 01:36:35 +0200 Subject: [PATCH 152/181] Add bicycle rental type images --- app/src/main/res/authors.txt | 5 +++++ .../bicycle_rental_docking_station.jpg | Bin 0 -> 10724 bytes .../bicycle_rental_dropoff_point.jpg | Bin 0 -> 16301 bytes .../bicycle_rental_key_dispensing_machine.jpg | Bin 0 -> 10652 bytes .../res/drawable-hdpi/bicycle_rental_shop.jpg | Bin 0 -> 15060 bytes .../bicycle_rental_docking_station.jpg | Bin 0 -> 5507 bytes .../bicycle_rental_dropoff_point.jpg | Bin 0 -> 8346 bytes .../bicycle_rental_key_dispensing_machine.jpg | Bin 0 -> 5728 bytes .../res/drawable-mdpi/bicycle_rental_shop.jpg | Bin 0 -> 7210 bytes .../bicycle_rental_docking_station.jpg | Bin 0 -> 16591 bytes .../bicycle_rental_dropoff_point.jpg | Bin 0 -> 28290 bytes .../bicycle_rental_key_dispensing_machine.jpg | Bin 0 -> 16217 bytes .../res/drawable-xhdpi/bicycle_rental_shop.jpg | Bin 0 -> 23805 bytes .../bicycle_rental_docking_station.jpg | Bin 0 -> 33069 bytes .../bicycle_rental_dropoff_point.jpg | Bin 0 -> 55152 bytes .../bicycle_rental_key_dispensing_machine.jpg | Bin 0 -> 31349 bytes .../res/drawable-xxhdpi/bicycle_rental_shop.jpg | Bin 0 -> 49942 bytes 17 files changed, 5 insertions(+) create mode 100644 app/src/main/res/drawable-hdpi/bicycle_rental_docking_station.jpg create mode 100644 app/src/main/res/drawable-hdpi/bicycle_rental_dropoff_point.jpg create mode 100644 app/src/main/res/drawable-hdpi/bicycle_rental_key_dispensing_machine.jpg create mode 100644 app/src/main/res/drawable-hdpi/bicycle_rental_shop.jpg create mode 100644 app/src/main/res/drawable-mdpi/bicycle_rental_docking_station.jpg create mode 100644 app/src/main/res/drawable-mdpi/bicycle_rental_dropoff_point.jpg create mode 100644 app/src/main/res/drawable-mdpi/bicycle_rental_key_dispensing_machine.jpg create mode 100644 app/src/main/res/drawable-mdpi/bicycle_rental_shop.jpg create mode 100644 app/src/main/res/drawable-xhdpi/bicycle_rental_docking_station.jpg create mode 100644 app/src/main/res/drawable-xhdpi/bicycle_rental_dropoff_point.jpg create mode 100644 app/src/main/res/drawable-xhdpi/bicycle_rental_key_dispensing_machine.jpg create mode 100644 app/src/main/res/drawable-xhdpi/bicycle_rental_shop.jpg create mode 100644 app/src/main/res/drawable-xxhdpi/bicycle_rental_docking_station.jpg create mode 100644 app/src/main/res/drawable-xxhdpi/bicycle_rental_dropoff_point.jpg create mode 100644 app/src/main/res/drawable-xxhdpi/bicycle_rental_key_dispensing_machine.jpg create mode 100644 app/src/main/res/drawable-xxhdpi/bicycle_rental_shop.jpg diff --git a/app/src/main/res/authors.txt b/app/src/main/res/authors.txt index a3761cf38d..6a7e46b389 100644 --- a/app/src/main/res/authors.txt +++ b/app/src/main/res/authors.txt @@ -38,6 +38,11 @@ bicycle_parking_type_stand.jpg CC0 Mateusz Konieczny https://commo bicycle_parking_type_wheel... CC-BY-SA 4.0 Joxemai https://commons.wikimedia.org/wiki/File:Bizikletak_lotzekoa.JPG bicycle_parking_type_handl... CC-BY-SA 4.0 Hiddewie https://commons.wikimedia.org/wiki/File:Bicycle_parking_handlebar_holder.jpg +bicycle_rental_docking_stat... CC-BY-SA 3.0 Siyuwj https://commons.wikimedia.org/wiki/File:Bicycle_rental_site_of_Tiangongyuan_Station.JPG +bicycle_rental_dropoff_poin... CC-BY-SA 4.0 Alexander Migl https://commons.wikimedia.org/wiki/File:Stuttgart-Vaihingen_Train_Station_Mobility_Hub_IMG_5767.jpg +bicycle_rental_key_dispensi... CC-BY-SA 4.0 Pietervdvn https://commons.wikimedia.org/wiki/File:Bluebike_sleutelautomaat_in_gebruik.jpg +bicycle_rental_shop.jpg CC-BY-SA 2.0 TijsB https://commons.wikimedia.org/wiki/File:Tel_Aviv-_bike_rental_(5889990605).jpg + bollard_fixed.jpg CC-BY-SA 4.0 Matija Nalis https://github.com/streetcomplete/StreetComplete/issues/3657#issuecomment-1020666101 bollard_flexible.jpg CC0 Ruben Kelevra https://commons.wikimedia.org/wiki/File:Flexible_bollard.jpg bollard_foldable.jpg CC-BY-SA 3.0 Hauke Stieler https://wiki.openstreetmap.org/wiki/File:Bollard_foldable.jpg diff --git a/app/src/main/res/drawable-hdpi/bicycle_rental_docking_station.jpg b/app/src/main/res/drawable-hdpi/bicycle_rental_docking_station.jpg new file mode 100644 index 0000000000000000000000000000000000000000..51e6d5d89b117bfd1abc82cf11d043b07928fed3 GIT binary patch literal 10724 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/bicycle_rental_shop.jpg b/app/src/main/res/drawable-hdpi/bicycle_rental_shop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4e7a2201b60aa38e5bda99e016ad58cda3ad2440 GIT binary patch literal 15060 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 E4-j#5Bme*a literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/bicycle_rental_docking_station.jpg b/app/src/main/res/drawable-mdpi/bicycle_rental_docking_station.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0cbf06094394b444345882d4789b011632c77281 GIT binary patch literal 5507 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/bicycle_rental_dropoff_point.jpg b/app/src/main/res/drawable-mdpi/bicycle_rental_dropoff_point.jpg new file mode 100644 index 0000000000000000000000000000000000000000..959b59ad10b76ae9f908fe1135e0aa2275eb480a GIT binary patch literal 8346 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/bicycle_rental_shop.jpg b/app/src/main/res/drawable-mdpi/bicycle_rental_shop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..88b195c130498768214aa910e3518a93fd6e02e3 GIT binary patch literal 7210 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 Zi7&x{n3+rx_k}?VJP-&(K!8U? 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

A{HL2&>m<2SnyLQ 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/bicycle_rental_key_dispensing_machine.jpg b/app/src/main/res/drawable-xhdpi/bicycle_rental_key_dispensing_machine.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f2c616056083477405a2f084a3b507fb4340e129 GIT binary patch literal 16217 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/bicycle_rental_docking_station.jpg b/app/src/main/res/drawable-xxhdpi/bicycle_rental_docking_station.jpg new file mode 100644 index 0000000000000000000000000000000000000000..008229a838b9ad214c82d1129eb35e737028119f GIT binary patch literal 33069 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 JG*VCp|JlX&72E&- literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/bicycle_rental_shop.jpg b/app/src/main/res/drawable-xxhdpi/bicycle_rental_shop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8fb63951e3d66ec365526b59357352cd378d6ba0 GIT binary patch literal 49942 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 CDxgLH literal 0 HcmV?d00001 From af9b3c6123be05e25d81203d7c0157fd6dd7ab70 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Thu, 5 May 2022 01:36:54 +0200 Subject: [PATCH 153/181] Add bicycle rental type --- .../streetcomplete/quests/QuestsModule.kt | 4 +- .../bike_rental_type/AddBikeRentalType.kt | 37 +++++++++++++++++++ .../bike_rental_type/AddBikeRentalTypeForm.kt | 37 +++++++++++++++++++ .../quests/bike_rental_type/BikeRentalType.kt | 8 ++++ .../res/drawable/ic_quest_bicycle_rental.xml | 33 +++++++++++++++++ app/src/main/res/values/strings.xml | 8 ++++ 6 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalType.kt create mode 100644 app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalTypeForm.kt create mode 100644 app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/BikeRentalType.kt create mode 100644 app/src/main/res/drawable/ic_quest_bicycle_rental.xml diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt b/app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt index 60f7bd5771..0445699a31 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/QuestsModule.kt @@ -24,6 +24,7 @@ import de.westnordost.streetcomplete.quests.bench_backrest.AddBenchBackrest import de.westnordost.streetcomplete.quests.bike_parking_capacity.AddBikeParkingCapacity import de.westnordost.streetcomplete.quests.bike_parking_cover.AddBikeParkingCover import de.westnordost.streetcomplete.quests.bike_parking_type.AddBikeParkingType +import de.westnordost.streetcomplete.quests.bike_rental_type.AddBikeRentalType import de.westnordost.streetcomplete.quests.board_type.AddBoardType import de.westnordost.streetcomplete.quests.bollard_type.AddBollardType import de.westnordost.streetcomplete.quests.bridge_structure.AddBridgeStructure @@ -316,9 +317,10 @@ fun questTypeRegistry( /* ↓ 2.solvable when right in front of it but takes longer to input --------------------- */ - // bike parking: would be higher up if not for bike parking capacity which is usually not solvable when moving past + // bike parking/rental: would be higher up if not for bike parking/rental capacity which is usually not solvable when moving past AddBikeParkingCover(), // used by OsmAnd in the object description AddBikeParkingType(), // used by OsmAnd + AddBikeRentalType(), AddBikeParkingAccess(), AddBikeParkingFee(), AddBikeParkingCapacity(), // used by cycle map layer on osm.org, OsmAnd diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalType.kt b/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalType.kt new file mode 100644 index 0000000000..2c727783f7 --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalType.kt @@ -0,0 +1,37 @@ +package de.westnordost.streetcomplete.quests.bike_rental_type + +import de.westnordost.streetcomplete.R +import de.westnordost.streetcomplete.data.osm.mapdata.Element +import de.westnordost.streetcomplete.data.osm.mapdata.MapDataWithGeometry +import de.westnordost.streetcomplete.data.osm.mapdata.filter +import de.westnordost.streetcomplete.data.osm.osmquests.OsmFilterQuestType +import de.westnordost.streetcomplete.data.osm.osmquests.Tags +import de.westnordost.streetcomplete.data.user.achievements.QuestTypeAchievement.BICYCLIST + +class AddBikeRentalType : OsmFilterQuestType() { + + override val elementFilter = """ + nodes, ways with + amenity = bicycle_rental + and access !~ private|no + and (!bicycle_rental or bicycle_rental = yes) + and !shop + """ + override val changesetComment = "Add bicycle rental type" + override val wikiLink = "Key:bicycle_rental" + override val icon = R.drawable.ic_quest_bicycle_rental + override val isDeleteElementEnabled = true + override val questTypeAchievements = listOf(BICYCLIST) + + override fun getTitle(tags: Map) = R.string.quest_bicycle_rental_type_title + + override fun getHighlightedElements(element: Element, getMapData: () -> MapDataWithGeometry) = + getMapData().filter("nodes, ways with amenity = bicycle_rental") + + override fun createForm() = AddBikeRentalTypeForm() + + override fun applyAnswerTo(answer: BikeRentalType, tags: Tags, timestampEdited: Long) { + tags["bicycle_rental"] = answer.osmValue + if (answer == BikeRentalType.SHOP) tags["shop"] = "rental" + } +} diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalTypeForm.kt b/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalTypeForm.kt new file mode 100644 index 0000000000..37622fabf2 --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalTypeForm.kt @@ -0,0 +1,37 @@ +package de.westnordost.streetcomplete.quests.bike_rental_type + +import androidx.appcompat.app.AlertDialog +import de.westnordost.streetcomplete.R +import de.westnordost.streetcomplete.quests.AImageListQuestAnswerFragment +import de.westnordost.streetcomplete.quests.bike_rental_type.BikeRentalType.DOCKING_STATION +import de.westnordost.streetcomplete.quests.bike_rental_type.BikeRentalType.DROPOFF_POINT +import de.westnordost.streetcomplete.quests.bike_rental_type.BikeRentalType.KEY_DISPENSING_MACHINE +import de.westnordost.streetcomplete.quests.bike_rental_type.BikeRentalType.SHOP +import de.westnordost.streetcomplete.view.image_select.Item + +class AddBikeRentalTypeForm : AImageListQuestAnswerFragment() { + + override val items = listOf( + Item(DOCKING_STATION, R.drawable.bicycle_rental_docking_station, R.string.quest_bicycle_rental_type_docking_station), + Item(DROPOFF_POINT, R.drawable.bicycle_rental_dropoff_point, R.string.quest_bicycle_rental_type_dropoff_point), + Item(KEY_DISPENSING_MACHINE, R.drawable.bicycle_rental_key_dispensing_machine, R.string.quest_bicycle_rental_type_key_dispensing_machine), + Item(SHOP, R.drawable.bicycle_rental_shop, R.string.quest_bicycle_rental_type_bicycle_shop), + ) + + override val itemsPerRow = 2 + + override fun onClickOk(selectedItems: List) { + if (selectedItems.single() === SHOP) confirmShop() + else applyAnswer(selectedItems.single()) + } + + private fun confirmShop() { + activity?.let { AlertDialog.Builder(it) + .setTitle(R.string.quest_generic_confirmation_title) + .setMessage(R.string.quest_bicycle_rental_type_bicycle_shop_confirmation) + .setPositiveButton(R.string.quest_generic_confirmation_yes) { _, _ -> applyAnswer(SHOP) } + .setNegativeButton(R.string.quest_generic_confirmation_no, null) + .show() + } + } +} diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/BikeRentalType.kt b/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/BikeRentalType.kt new file mode 100644 index 0000000000..59f4642dc4 --- /dev/null +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/BikeRentalType.kt @@ -0,0 +1,8 @@ +package de.westnordost.streetcomplete.quests.bike_rental_type + +enum class BikeRentalType(val osmValue: String) { + DOCKING_STATION("docking_station"), + DROPOFF_POINT("dropoff_point"), + KEY_DISPENSING_MACHINE("key_dispensing_machine"), + SHOP("shop"), +} diff --git a/app/src/main/res/drawable/ic_quest_bicycle_rental.xml b/app/src/main/res/drawable/ic_quest_bicycle_rental.xml new file mode 100644 index 0000000000..2dd9c2827e --- /dev/null +++ b/app/src/main/res/drawable/ic_quest_bicycle_rental.xml @@ -0,0 +1,33 @@ + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index adae119619..d4b894895d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -657,6 +657,14 @@ However, before uploading your changes, the app checks with a <a href=\"https Building Handlebar holder + What type of bicycle rental is this? + Docking station (locks bikes) + Designated spot (bikes locked individually) + Key dispensing machine + Human-operated shop + Is bike rental this shop’s main business? +If not, please leave a note instead. + "How many bikes can be parked here?" "Note that most normal stands can be used from both sides to park each one bike." From 931fbbbbbed5e3736836f0e9c4919a573c6b7d62 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Thu, 5 May 2022 01:43:46 +0200 Subject: [PATCH 154/181] Also highlight bicycle_parking (and vice-versa) to avoid confusion --- .../quests/bike_parking_type/AddBikeParkingType.kt | 2 +- .../streetcomplete/quests/bike_rental_type/AddBikeRentalType.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_type/AddBikeParkingType.kt b/app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_type/AddBikeParkingType.kt index 8e518bb4b0..83055d25f5 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_type/AddBikeParkingType.kt +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/bike_parking_type/AddBikeParkingType.kt @@ -25,7 +25,7 @@ class AddBikeParkingType : OsmFilterQuestType() { override fun getTitle(tags: Map) = R.string.quest_bicycle_parking_type_title override fun getHighlightedElements(element: Element, getMapData: () -> MapDataWithGeometry) = - getMapData().filter("nodes, ways with amenity = bicycle_parking") + getMapData().filter("nodes, ways with amenity ~ bicycle_parking|bicycle_rental") override fun createForm() = AddBikeParkingTypeForm() diff --git a/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalType.kt b/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalType.kt index 2c727783f7..ffbe621188 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalType.kt +++ b/app/src/main/java/de/westnordost/streetcomplete/quests/bike_rental_type/AddBikeRentalType.kt @@ -26,7 +26,7 @@ class AddBikeRentalType : OsmFilterQuestType() { override fun getTitle(tags: Map) = R.string.quest_bicycle_rental_type_title override fun getHighlightedElements(element: Element, getMapData: () -> MapDataWithGeometry) = - getMapData().filter("nodes, ways with amenity = bicycle_rental") + getMapData().filter("nodes, ways with amenity ~ bicycle_parking|bicycle_rental") override fun createForm() = AddBikeRentalTypeForm() From f9848dc0ce6c1b2ea98197ede32754fe95aa0d61 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Thu, 5 May 2022 10:41:22 +0200 Subject: [PATCH 155/181] Update CONTRIBUTING_A_NEW_QUEST.md Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 80a54f9475..84b5077a73 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -6,9 +6,7 @@ If you want to contribute code to StreetComplete, then making a new quest is one Contributions like that are highly welcomed and you would make mapping one more thing in OSM much easier! You can implement it also if you never used Kotlin or implemented anything for Android. Being highly experienced programmer is not necessary here. -Reading the text below is not necessary to create a new quest. Duplicating existing quest and modifying its code may be sufficient. And people were creating new quests before this documentation existed. - -But this materials may help or be quicker than trying to fully explore on your own how things work. +Reading the text below is not necessary to create a new quest. Duplicating an existing quest and modifying its code may be sufficient - people were creating new quests before this documentation existed. This material simply helps you get a better understanding of it. # Dependencies - initial setup From 84c0b1ecd64f6eb8a7c7467894b999680adebaa4 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Thu, 5 May 2022 10:44:58 +0200 Subject: [PATCH 156/181] remove not important info Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index 84b5077a73..ae5b7e62ab 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -486,7 +486,6 @@ Matches like `surface ~ earth|dirt|ground` are possible and are evaluated as "`s `access !~ private|no` will be evaluated to "`access` is neither `private` nor `no`" -Simple lists are [evaluated as sets](https://github.com/streetcomplete/StreetComplete/blob/2e812b9a3b5288983309a7edde6e8f9db05ad3f2/app/src/test/java/de/westnordost/streetcomplete/data/elementfilter/filters/ElementFilterOverpassKtTest.kt#L79-L88) - and for example `surface ~ earth|dirt|ground` will not match `surface=earther` tag. Basically, `surface ~ earth|dirt|ground` is treated as `surface ~ ^earth|dirt|ground$` But using regexp like `surface ~ ^(.*)[0-9]$` is [also possible](https://github.com/streetcomplete/StreetComplete/blob/master/app/src/test/java/de/westnordost/streetcomplete/data/elementfilter/filters/ElementFilterOverpassKtTest.kt#L79-L88). From ec5fd363cd825d90f0c53e698de8e959112ead47 Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Thu, 5 May 2022 10:45:50 +0200 Subject: [PATCH 157/181] clarify type of reglar expression Co-authored-by: Tobias Zwick --- CONTRIBUTING_A_NEW_QUEST.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTING_A_NEW_QUEST.md b/CONTRIBUTING_A_NEW_QUEST.md index ae5b7e62ab..dcde615e39 100644 --- a/CONTRIBUTING_A_NEW_QUEST.md +++ b/CONTRIBUTING_A_NEW_QUEST.md @@ -166,8 +166,7 @@ This query will be limited to object which fulfill some requirements. - `emergency = defibrillator` - this tag must be present - `and access !~ private|no` - - and `access` tag must not have values `private` or `no` - - `!~ private|no` is transformed into `^optionA|optionB$` [regexp](https://en.wikipedia.org/wiki/Regular_expression) + - and `access` tag must not have values `private` or `no` (the `~` indicates it is a [regular expression](https://en.wikipedia.org/wiki/Regular_expression) which will be matched against the whole string) - this filter excludes objects where mapper will likely has no access necessary for survey - `and !indoor` - and `indoor` key must not be present at all, to show only ones where this tag is still missing From 6f7c2f1863dec0beb58b1c13b905380e804723fe Mon Sep 17 00:00:00 2001 From: Mateusz Konieczny Date: Thu, 5 May 2022 10:48:20 +0200 Subject: [PATCH 158/181] remove extra word which is not really needed --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f2c79b829e..d1810c8ae3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -79,7 +79,7 @@ You can also help to keep the OpenStreetMap wiki **up-to-date** for StreetComple If you would like to help and are able to contribute code, you are most welcome. -There are many reasonable feature requests and ideas for new question types in the issue tracker which you can use. If you have own ideas on how to improve this app and want to make sure that the pull request will be merged, it is strongly suggested you **open an issue first** to discuss the feature, especially if you aim to add a new quest, [see below](#developing-new-quests). +There are many feature requests and ideas for new question types in the issue tracker which you can use. If you have own ideas on how to improve this app and want to make sure that the pull request will be merged, it is strongly suggested you **open an issue first** to discuss the feature, especially if you aim to add a new quest, [see below](#developing-new-quests). Note that StreetComplete also uses [some dependencies](#issues-with-dependencies), where contributions are likely also accepted and help StreetComplete, too. From 03d1c9882253afdaf584dd7a22c6b9b8f4c064e2 Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Thu, 5 May 2022 23:42:26 +0200 Subject: [PATCH 159/181] update translations --- .../main/assets/osmfeatures/default/lv.json | 2732 +++++++++++++++++ app/src/main/res/raw/changelog.yml | 11 + app/src/main/res/raw/credits_translators.yml | 266 +- app/src/main/res/raw/languages.yml | 3 +- app/src/main/res/values-ca/strings.xml | 15 +- .../main/res/values-ca/translation_info.xml | 2 +- app/src/main/res/values-da/strings.xml | 334 +- .../main/res/values-da/translation_info.xml | 2 +- app/src/main/res/values-de/strings.xml | 10 +- app/src/main/res/values-en-rGB/strings.xml | 4 +- app/src/main/res/values-en/strings.xml | 2 +- app/src/main/res/values-fa/strings.xml | 34 +- .../main/res/values-he/translation_info.xml | 2 +- app/src/main/res/values-hu/strings.xml | 188 +- .../main/res/values-hu/translation_info.xml | 2 +- app/src/main/res/values-hy/strings.xml | 2 - app/src/main/res/values-id/strings.xml | 361 ++- .../main/res/values-id/translation_info.xml | 2 +- app/src/main/res/values-in/strings.xml | 361 ++- .../main/res/values-in/translation_info.xml | 2 +- app/src/main/res/values-it/strings.xml | 14 + .../main/res/values-it/translation_info.xml | 2 +- .../main/res/values-iw/translation_info.xml | 2 +- app/src/main/res/values-lv/strings.xml | 1267 ++++++++ .../main/res/values-lv/translation_info.xml | 2 +- app/src/main/res/values-ru/strings.xml | 20 +- .../main/res/values-ru/translation_info.xml | 2 +- app/src/main/res/values-sk/strings.xml | 66 +- .../main/res/values-sk/translation_info.xml | 2 +- app/src/main/res/values-sr/strings.xml | 16 + .../main/res/values-sr/translation_info.xml | 2 +- app/src/main/res/values-uk/strings.xml | 75 +- .../main/res/values-uk/translation_info.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 133 + .../res/values-zh-rTW/translation_info.xml | 2 +- metadata/he/full_description.txt | 5 + metadata/he/short_description.txt | 1 + metadata/lv/full_description.txt | 6 +- metadata/lv/short_description.txt | 2 +- 39 files changed, 5131 insertions(+), 825 deletions(-) create mode 100644 app/src/main/assets/osmfeatures/default/lv.json create mode 100644 app/src/main/res/values-lv/strings.xml create mode 100644 metadata/he/full_description.txt create mode 100644 metadata/he/short_description.txt diff --git a/app/src/main/assets/osmfeatures/default/lv.json b/app/src/main/assets/osmfeatures/default/lv.json new file mode 100644 index 0000000000..a64119591f --- /dev/null +++ b/app/src/main/assets/osmfeatures/default/lv.json @@ -0,0 +1,2732 @@ +{ + "lv": { + "presets": { + "categories": { + "category-barrier": { + "name": "Barjeru veidi" + }, + "category-building": { + "name": "Ēku veidi" + }, + "category-landuse": { + "name": "Zemes izmantojuma objekti" + }, + "category-path": { + "name": "Takas" + }, + "category-road_service": { + "name": "Pievedceļi" + }, + "category-waterway": { + "name": "Ūdensceļi" + } + }, + "fields": { + "access": { + "label": "Atļauta piekļuve", + "options": { + "designated": { + "description": "Atļauta piekļuve saskaņā ar vietējiem likumiem", + "title": "Nozīmēts" + }, + "destination": { + "description": "Atļauta piekļuve tikai lai sasniegtu galamērķi", + "title": "Galamērķis" + }, + "dismount": { + "description": "Piekļuve atļauta, bet braucējam jānokāpj", + "title": "Jānokāpj" + }, + "no": { + "description": "Publikai nav atļauta piekļuve", + "title": "Aizliegts" + }, + "permissive": { + "description": "Piekļuve atļauta līdz īpašnieks atsauc atļauju" + }, + "permit": { + "description": "Piekļuve atļauta tikai ar derīgu atļauju vai licenzi" + }, + "private": { + "description": "Piekļuve atļauta tikai ar īpašnieka atļauju uz induviduālas bāzes", + "title": "Privāts" + }, + "yes": { + "title": "Atļauts" + } + }, + "placeholder": "Nav specificēts", + "types": { + "access": "Viss", + "bicycle": "Velosipēdi", + "foot": "Kājām", + "horse": "Zirgi", + "motor_vehicle": "Automašīnas" + } + }, + "access_simple": { + "label": "Atļauta Piekļuve" + }, + "address": { + "label": "Adrese", + "placeholders": { + "city": "Pilsēta", + "city!vn": "Pilsēta/Ciems", + "conscriptionnumber": "123", + "country": "Valsts", + "floor": "Stāvs", + "housename": "Mājas Nosaukums", + "housenumber": "123", + "neighbourhood": "Apdzīvotais rajons", + "place": "Vieta", + "postcode": "Pasta indekss", + "province": "Province", + "state": "Štats", + "street": "Iela" + } + }, + "admin_level": { + "label": "Administrācijas stāvs" + }, + "aerialway": { + "label": "Tips" + }, + "aerialway/access": { + "label": "Piekļuve", + "options": { + "both": "Abi", + "entry": "Ieeja", + "exit": "Izeja" + } + }, + "aerialway/capacity": { + "placeholder": "500, 2500, 5000..." + }, + "aerialway/duration": { + "label": "Ilgums (minūtēs)", + "placeholder": "1, 2, 3..." + }, + "aerialway/heating": { + "label": "Apsilde" + }, + "aerialway/occupancy": { + "label": "Apdzīvotība", + "placeholder": "2, 4, 8..." + }, + "aerialway/summer/access": { + "label": "Pieķluve (vasarā)", + "options": { + "both": "Abi", + "entry": "Ieeja", + "exit": "Izeja" + } + }, + "aeroway": { + "label": "Tips" + }, + "agrarian": { + "label": "Produkti" + }, + "amenity": { + "label": "Tips" + }, + "animal_boarding": { + "label": "Priekš dzīvniekiem" + }, + "animal_breeding": { + "label": "Priekš dzīvniekiem" + }, + "animal_shelter": { + "label": "Priekš dzīvniekiem" + }, + "area/highway": { + "label": "Tips" + }, + "artist": { + "label": "Mākslinieks" + }, + "artwork_type": { + "label": "Tips" + }, + "atm": { + "label": "Bankomāts" + }, + "backrest": { + "label": "Atzveltne" + }, + "barrier": { + "label": "Tips" + }, + "basin": { + "label": "Tips" + }, + "bath/open_air": { + "label": "Brīvdabas" + }, + "bath/sand_bath": { + "label": "Smilšu Vanna" + }, + "bath/type": { + "label": "Specialitātes" + }, + "bench": { + "label": "Sols" + }, + "bicycle_parking": { + "label": "Tips" + }, + "bin": { + "label": "Miskaste" + }, + "blood_components": { + "label": "Asins Daļas", + "options": { + "plasma": "plazma", + "platelets": "trombocīti", + "whole": "Pilnas asinis" + } + }, + "board_type": { + "label": "Tips" + }, + "boules": { + "label": "Tips" + }, + "boundary": { + "label": "Tips" + }, + "brand": { + "label": "Zīmols" + }, + "bridge": { + "label": "Tips", + "placeholder": "Noklusējuma" + }, + "bridge/support": { + "label": "Tips" + }, + "building": { + "label": "Ēka" + }, + "building_area": { + "label": "Ēka" + }, + "bunker_type": { + "label": "Tips" + }, + "cables": { + "label": "Kabelis", + "placeholder": "1, 2, 3..." + }, + "camera/direction": { + "label": "Virziens (Grādi, pulksteņrādītāja virzienā)", + "placeholder": "45, 90, 180, 270" + }, + "camera/mount": { + "label": "Kameras montāžas veids" + }, + "camera/type": { + "label": "Kameras tips", + "options": { + "dome": "Kupola", + "fixed": "Fiksēta", + "panning": "Panējoša" + } + }, + "capacity": { + "label": "Ietilpība", + "placeholder": "50, 100, 200..." + }, + "cash_in": { + "label": "Naudas iemaksa" + }, + "castle_type": { + "label": "Tips" + }, + "clothes": { + "label": "Drēbes" + }, + "club": { + "label": "Tips" + }, + "collection_times": { + "label": "Savākšanas laiki" + }, + "colour": { + "label": "Krāsa" + }, + "comment": { + "label": "Izmaiņu komentārs", + "placeholder": "Īss apraksts par jūsu ieguldījumu (vajadzīgs)" + }, + "communication_multi": { + "label": "Komunikāciju veidi" + }, + "construction": { + "label": "Tips" + }, + "contact/webcam": { + "label": "Straumes URL", + "placeholder": "http://example.com/" + }, + "content": { + "label": "Saturs" + }, + "country": { + "label": "Valsts" + }, + "covered": { + "label": "Apsegts" + }, + "craft": { + "label": "Tips" + }, + "crane/type": { + "label": "Celtņa tips", + "options": { + "floor-mounted_crane": "Zemē montēts celtnis", + "travel_lift": "Pārnēsājamās piestātnes celtnis" + } + }, + "crop": { + "label": "Labība" + }, + "crossing": { + "label": "Tips" + }, + "cuisine": { + "label": "Ēdiens" + }, + "currency_multi": { + "label": "Valūtu veidi" + }, + "cutting": { + "label": "Tips", + "placeholder": "Noklusējuma" + }, + "cycle_network": { + "label": "Tīlks" + }, + "cycleway": { + "label": "Velosipēdu ceļi", + "options": { + "lane": { + "description": "Riteņbraucēju celiņš atdalīts no braucamās daļas ar svītru", + "title": "Parasts velosipēdu celiņš" + }, + "none": { + "description": "Nav velosipēdu celiņa", + "title": "Nav" + }, + "opposite": { + "description": "Riteņbraucēju celiņš kas iet abos vienvirziena ceļa virzienos" + }, + "opposite_lane": { + "title": "Pretējs velosipēdu celiņš" + }, + "share_busway": { + "description": "Velosipēdu celiņš kopā ar ar autobusu ceļu", + "title": "Velosipēdu celiņš kopā ar publiskā transporta joslu" + }, + "shared_lane": { + "description": "Velosipēdu celiņš bez atdalīšanas no braucamās daļas", + "title": "Dalīts velosipēdu celiņš" + }, + "track": { + "description": "Velosipēdu celiņš, nodalīts no satiksmes ar sienu" + } + }, + "placeholder": "Nav", + "types": { + "cycleway:left": "Kreisā puse", + "cycleway:right": "Labā puse" + } + }, + "dance/style": { + "label": "Deju veidi" + }, + "date": { + "label": "Datums" + }, + "delivery": { + "label": "Pievešana" + }, + "denomination": { + "label": "Denominācija" + }, + "denotation": { + "label": "Denominācija" + }, + "description": { + "label": "Apraksts" + }, + "devices": { + "label": "Ierīces", + "placeholder": "1, 2, 3..." + }, + "direction": { + "label": "Virziens (Grādi, pulksteņrādītāja virzienā)", + "placeholder": "45, 90, 180, 270" + }, + "direction_clock": { + "label": "Virziens", + "options": { + "anticlockwise": "Pret pulksteņrādītāja virzienā", + "clockwise": "pulksteņrādītāja virzienā" + } + }, + "direction_vertex": { + "options": { + "backward": "Atmuguriski", + "both": "Abas / Visas" + } + }, + "dispensing": { + "label": "Izdod recepšu zāles" + }, + "display": { + "label": "Displejs" + }, + "dock": { + "label": "Tips" + }, + "drive_through": { + "label": "Drive-Through" + }, + "duration": { + "label": "Ilgums", + "placeholder": "00:00" + }, + "electrified": { + "label": "Elektrifikācija", + "options": { + "contact_line": "Saskarsmē ar līniju", + "no": "Nē", + "rail": "Elektrizēta sliede", + "yes": "Jā (Nav specificēts)" + }, + "placeholder": "Saskarsmē ar līniju, Elektrizēta Sliede..." + }, + "email": { + "label": "E-Pasts", + "placeholder": "example@example.com" + }, + "embankment": { + "label": "Tips", + "placeholder": "Noklusējuma" + }, + "emergency": { + "label": "Ārkārtas" + }, + "entrance": { + "label": "Tips" + }, + "except": { + "label": "Izņēmumi" + }, + "fax": { + "label": "Fakss", + "placeholder": "+31 42 123 4567" + }, + "fee": { + "label": "Maksa" + }, + "fence_type": { + "label": "Tips" + }, + "fire_hydrant/type": { + "options": { + "pillar": "Stabs / Virszemes", + "underground": "Apakšzemes", + "wall": "Siena" + } + }, + "fireplace": { + "label": "Kamīns" + }, + "fitness_station": { + "label": "Iekārtas tips" + }, + "fixme": { + "label": "Salabo Mani" + }, + "flag/type": { + "label": "Karoga veids" + }, + "ford": { + "label": "Tips", + "placeholder": "Noklusējuma" + }, + "frequency": { + "label": "Strādāšanas Frekvence" + }, + "fuel": { + "label": "Degviela" + }, + "fuel_multi": { + "label": "Degvielas veidi" + }, + "gauge": { + "label": "Gabarīts" + }, + "gender": { + "label": "Dzimums", + "options": { + "female": "Sieviešu", + "male": "Vīriešu", + "unisex": "Unisex" + }, + "placeholder": "Nezināms" + }, + "generator/method": { + "label": "Metode" + }, + "generator/output/electricity": { + "label": "Izejas jauda", + "placeholder": "50 MW, 100 MW, 200 MW..." + }, + "generator/source": { + "label": "Avots" + }, + "generator/type": { + "label": "Tips" + }, + "government": { + "label": "Tips" + }, + "grape_variety": { + "label": "Vīnogu šķirnes" + }, + "handicap": { + "label": "Invalīdu", + "placeholder": "1-18" + }, + "handrail": { + "label": "Margas" + }, + "hashtags": { + "placeholder": "#piemērs" + }, + "healthcare": { + "label": "Tips" + }, + "healthcare/speciality": { + "label": "Specialitātes" + }, + "height": { + "label": "Augstums (Metros)" + }, + "highway": { + "label": "Tips" + }, + "historic": { + "label": "Tips" + }, + "historic/civilization": { + "label": "Vēsturiska Civilizācija" + }, + "historic/wreck/date_sunk": { + "label": "Nogrimšanas datums" + }, + "hoops": { + "placeholder": "1, 2, 4..." + }, + "horse_dressage": { + "options": { + "equestrian": "Jā", + "undefined": "Nē" + } + }, + "horse_riding": { + "label": "Zirgu izjāde", + "options": { + "horse_riding": "Jā", + "undefined": "Nē" + } + }, + "horse_scale": { + "label": "Zirgu jāšanas grūtības pakāpe", + "options": { + "common": "Viegls: Bez problēmām vai grūtībām. (noklusējuma)", + "critical": "Robežojas: Izjājams tikai pieredzējušiem jājējiem un zirgiem. Lieli šķēršļi. Tilti itsevisķi būtu rūpīgi jāpārbauda.", + "dangerous": "Bīstams: Izjājams tikai ļoti pieredzējušiem jātniekiem un zirgiem tikai labos laikapstākļos. Jānokāpj pirms.", + "demanding": "Jājiet piesardzīgi: Nevienmērīga taka, dažkārt sarežģītas vietas.", + "difficult": "Grūts: Pārlieku šaurs un atvērts. Var saturēt šķēršļus, kam jāpārkāpj un šauras pārejas.", + "impossible": "Necaurjājams: Ceļš vai tilts nav izejams ar zirgu. Pārāk šaurs, nepietiekams atbalsts, šķērsļi kā trepes. Dzīvībai bīstams." + }, + "placeholder": "Grūts, Bīstams..." + }, + "horse_stables": { + "label": "Zirgu Stallis", + "options": { + "stables": "Jā", + "undefined": "Nē" + } + }, + "incline": { + "label": "Slīpums" + }, + "incline_steps": { + "label": "Slīpums", + "options": { + "down": "Lejup", + "up": "Augšup" + } + }, + "indoor": { + "label": "Iekštelpu" + }, + "industrial": { + "label": "Tips" + }, + "information": { + "label": "Tips" + }, + "internet_access": { + "options": { + "no": "Nē", + "terminal": "Termināls", + "wired": "Kabeļinternets", + "wlan": "Bezvadu internets", + "yes": "Jā" + } + }, + "kerb": { + "label": "Apmale" + }, + "label": { + "label": "Etiķete" + }, + "lamp_type": { + "label": "Tips" + }, + "landuse": { + "label": "Tips" + }, + "lanes": { + "label": "Joslas", + "placeholder": "1, 2, 3..." + }, + "language_multi": { + "label": "Valodas" + }, + "layer": { + "label": "Līmenis", + "placeholder": "0" + }, + "leaf_cycle": { + "label": "Lapu Maiņa", + "options": { + "deciduous": "Mainīgs", + "evergreen": "Mūžzaļš", + "mixed": "Jaukts", + "semi_deciduous": "Daļēji Mainīgs", + "semi_evergreen": "Daļēji Mūžzaļš" + } + }, + "leaf_cycle_singular": { + "label": "Lapu Maiņa", + "options": { + "deciduous": "Mainīgs", + "evergreen": "Mūžzaļš", + "semi_deciduous": "Daļēji Mainīgs", + "semi_evergreen": "Daļēji Mūžzaļš" + } + }, + "leaf_type": { + "label": "Lapu Veids", + "options": { + "broadleaved": "Platlapu", + "leafless": "Bezlapu", + "mixed": "Jaukts", + "needleleaved": "Skujlapu" + } + }, + "leaf_type_singular": { + "label": "Lapu Veids", + "options": { + "broadleaved": "Platlapu", + "leafless": "Bezlapu", + "needleleaved": "Skujlapu" + } + }, + "leisure": { + "label": "Tips" + }, + "length": { + "label": "Garums (Metros)" + }, + "level": { + "label": "Stāvs" + }, + "lit": { + "label": "Apgaismots" + }, + "location": { + "label": "Atrašanās vieta" + }, + "location_pool": { + "options": { + "indoor": "Iekštelpu", + "outdoor": "Ārtelpu", + "roof": "Jumta" + } + }, + "man_made": { + "label": "Tips" + }, + "manhole": { + "label": "Tips" + }, + "map_size": { + "label": "Pārklājums" + }, + "map_type": { + "label": "Tips" + }, + "material": { + "label": "Materiāls" + }, + "maxheight": { + "label": "Maks, Augstums" + }, + "maxspeed": { + "label": "Ātruma ierobežojums", + "placeholder": "40, 50, 60..." + }, + "maxspeed/advisory": { + "label": "Ieteicamais Ātruma Ierobežojums", + "placeholder": "40, 50, 60..." + }, + "maxstay": { + "label": "Maks. Stāvēšanas Ilgums" + }, + "maxweight": { + "label": "Maks. Smagums" + }, + "memorial": { + "label": "Tips" + }, + "monitoring_multi": { + "label": "Uzraudzība" + }, + "mtb/scale": { + "label": "Kalnu riteņbraukšanas grūtības pakāpe", + "options": { + "0": "0: Cieta grants / saspiesta zeme, nav skēršļu, plati pagriezieni.", + "1": "1: Nedaudz nestabilas virsmas, mazi skēršļi, plati pagriezieni.", + "2": "2: Daudz nestabilas virsmas, lieli sķēršļi, vidēji asi pagriezieni.", + "3": "3: Slidena virsma, lieli sķērsļi, asi pagriezieni.", + "4": "4: Nestabila virsma vai akmeņi, bīstami asi pagriezieni.", + "5": "5: Maksimālās grūtības, akmeņu lauki, zemes noslīdes.", + "6": "6: Nav izbraucams, izņemot visslabākajiem kalnu riteņbraucējiem." + }, + "placeholder": "0, 1, 2, 3..." + }, + "mtb/scale/imba": { + "label": "IMBA Ceļa Grūtība", + "options": { + "0": "Vieglākā (baltais aplis)", + "1": "Viegla (zaļais aplis)", + "2": "Vidēja (zilais kvadrāts)", + "3": "Grūta (melns dimants)", + "4": "Ļoti grūta (Dubultais melnais dimants)" + }, + "placeholder": "Viegls, Vidējs, Grūts..." + }, + "mtb/scale/uphill": { + "label": "Kalnu riteņbraukšanas kalna grūtība", + "options": { + "0": "0: Vid. slīpums <10%, grants/saspiesta zeme, nav sķēršļu", + "1": "1: Vid. slīpums <15%, grants/saspiesta zeme, pāris mazi sķēršļi.", + "2": "2: Vid. slīpums <20%, stabila virsma, dūŗes lieluma akmeņi/saknes", + "3": "3: Vid. slīpums <25%, dažāda virsma, dūres lieluma akmeņi/zari", + "4": "4: Vid. slīpums <30%, slikta virsma, lieli akmeņi/zari", + "5": "5: Ļoti stāva, velosipēdu parasti vajag stumt vai nest" + }, + "placeholder": "0, 1, 2, 3..." + }, + "name": { + "label": "Vārds", + "placeholder": "Tautas nosaukums (ja tāds ir)" + }, + "natural": { + "label": "Dabisks" + }, + "network": { + "label": "Tīkls" + }, + "network_bicycle": { + "options": { + "icn": "Starptautisks", + "lcn": "Vietējs", + "ncn": "Nacionāls", + "rcn": "Reģionāls" + }, + "placeholder": "Vietējs, Reģionāls, Nacionāls, Starptautisks" + }, + "network_foot": { + "options": { + "iwn": "Starptautisks", + "lwn": "Vietējs", + "nwn": "Nacionāls", + "rwn": "Reģionāls" + }, + "placeholder": "Vietējs, Reģionāls, Nacionāls, Starptautisks" + }, + "network_horse": { + "options": { + "ihn": "Starptautisks", + "lhn": "Vietējs", + "nhn": "Nacionāls", + "rhn": "Reģionāls" + }, + "placeholder": "Vietējs, Reģionāls, Nacionāls, Starptautisks" + }, + "network_road": { + "label": "Tīkls" + }, + "note": { + "label": "Piezīme" + }, + "office": { + "label": "Tips" + }, + "oneway": { + "label": "Vienvirziena", + "options": { + "no": "Nē", + "undefined": "Pieņemts ka Nē", + "yes": "Jā" + } + }, + "oneway_yes": { + "label": "Vienvirziena", + "options": { + "no": "Nē", + "undefined": "Pieņemts ka Jā", + "yes": "Jā" + } + }, + "opening_hours": { + "label": "Darba laiks" + }, + "operator": { + "label": "Operators" + }, + "outdoor_seating": { + "label": "Brīvdabas sēdvietas" + }, + "par": { + "label": "Par", + "placeholder": "3, 4, 5..." + }, + "park_ride": { + "label": "Novieto un brauc" + }, + "parking": { + "label": "Tips", + "options": { + "carports": "Nojumes", + "garage_boxes": "Garāžas", + "lane": "Ielas mala", + "multi-storey": "Vairākstāvu", + "sheds": "Sķūnis", + "surface": "Virszemes", + "underground": "Apakšzemes" + } + }, + "payment_multi": { + "label": "Maksājumu veidi" + }, + "phases": { + "label": "Fāzes", + "placeholder": "1, 2, 3..." + }, + "phone": { + "label": "Telefons", + "placeholder": "+31 42 123 4567" + }, + "piste/difficulty": { + "label": "Grūtība", + "placeholder": "Viegls,Vidējs,Grūts" + }, + "piste/type": { + "options": { + "ice_skate": "Slidošana", + "playground": "Spēļlaukums", + "sled": "Ragavas", + "sleigh": "Kamaniņu", + "snow_park": "Sniega Parks" + } + }, + "place": { + "label": "Tips" + }, + "plant": { + "label": "Augs" + }, + "plant/output/electricity": { + "label": "Izejas jauda", + "placeholder": "500 MW, 1000 MW, 2000 MW..." + }, + "population": { + "label": "Populācija" + }, + "power": { + "label": "Tips" + }, + "product": { + "label": "Produkti" + }, + "railway": { + "label": "Tips" + }, + "railway/position": { + "placeholder": "Attālums līdz vienam decimālpunktam (123.4)" + }, + "railway/signal/direction": { + "options": { + "backward": "Atmuguriski", + "both": "Abas / Visas" + } + }, + "recycling_accepts": { + "label": "Pieņem" + }, + "ref": { + "label": "Atsauces kods" + }, + "ref/isil": { + "label": "ISIL kods" + }, + "ref_aeroway_gate": { + "label": "Vārtu numurs" + }, + "ref_golf_hole": { + "label": "Bedrītes Numurs", + "placeholder": "1-18" + }, + "ref_road_number": { + "label": "Ceļa Numurs" + }, + "relation": { + "label": "Veids" + }, + "religion": { + "label": "Reliģija" + }, + "seamark/buoy_lateral/colour": { + "options": { + "green": "Zaļa", + "green;red;green": "Zaļa-Sarkana-Zaļa", + "green;white;green;white": "Zaļa-Balta-Zaļa-Balta", + "red": "Sarkana", + "red;green;red": "Sarkana-Zaļa-Sarkana", + "red;white;red;white": "Sarkana-Balta-Sarkana-Balta", + "white": "Balta", + "yellow": "Dzeltena" + } + }, + "seamark/buoy_lateral/shape": { + "label": "Forma" + }, + "seamark/buoy_lateral/system": { + "label": "Sistēma", + "options": { + "other": "Cita" + } + }, + "seamark/mooring/category": { + "label": "Kategorija" + }, + "seamark/wreck/category": { + "label": "Kategorija" + }, + "seasonal": { + "label": "Sezonāls" + }, + "second_hand": { + "label": "Pārdod lietotus", + "options": { + "no": "Nē", + "only": "Tikai", + "yes": "Jā" + }, + "placeholder": "Jā, Nē, Tikai" + }, + "service": { + "label": "Tips" + }, + "shelter": { + "label": "Pajumte" + }, + "shop": { + "label": "Tips" + }, + "siren/purpose": { + "label": "Nolūks" + }, + "siren/type": { + "label": "Tips", + "options": { + "electronic": "Elektroniska", + "other": "Cits", + "pneumatic": "Pneimatiska" + } + }, + "smoking": { + "label": "Smēķēšana", + "options": { + "isolated": "Smēķēšanas vietās, fiziski izolētas", + "no": "Aizliegts visur", + "outside": "Atļauts ārpusē", + "separated": "Smēķēšanas vietās, kas nav fiziski izolētas", + "yes": "Atļauts visur" + }, + "placeholder": "Nē, Atdalīti, Jā..." + }, + "smoothness": { + "label": "Gludums" + }, + "sport": { + "label": "Sports" + }, + "sport_ice": { + "label": "Sports" + }, + "sport_racing_motor": { + "label": "Sports" + }, + "sport_racing_nonmotor": { + "label": "Sports" + }, + "start_date": { + "label": "Sākuma datums" + }, + "step_count": { + "label": "Pakāpienu daudzums" + }, + "structure": { + "label": "Objekts", + "options": { + "bridge": "Tilts", + "cutting": "Izgriezums", + "embankment": "Krastmala", + "tunnel": "Tunelis" + }, + "placeholder": "Nezināms" + }, + "structure_waterway": { + "options": { + "tunnel": "Tunelis" + }, + "placeholder": "Nezināms" + }, + "studio": { + "label": "Tips" + }, + "substation": { + "label": "Tips" + }, + "supervised": { + "label": "Pārraudzīts" + }, + "support": { + "label": "Atbalsts" + }, + "surface": { + "label": "Segums" + }, + "surveillance": { + "label": "Uzraudzības veids" + }, + "surveillance/type": { + "label": "Uzraudzības tips", + "options": { + "ALPR": "Automātiskais numurzīmju lasītājs", + "camera": "Kamera", + "guard": "Sargs" + } + }, + "surveillance/zone": { + "label": "Apsardzes zona" + }, + "switch": { + "label": "Tips", + "options": { + "circuit_breaker": "Drošinātājs", + "disconnector": "Atslēdzējs", + "earthing": "Zemējums", + "mechanical": "Mehāniskais" + } + }, + "takeaway": { + "label": "Līdzņemšana", + "options": { + "no": "Nē", + "only": "Tikai Līdzņemšanai", + "yes": "Jā" + }, + "placeholder": "Jā, Nē, Tikai Līdzņemšanai..." + }, + "toilets/disposal": { + "options": { + "bucket": "Spainis", + "chemical": "Ķīmiskā", + "flush": "Ūdens Nolaišanas" + } + }, + "toll": { + "label": "Maksa" + }, + "tomb": { + "label": "Tips" + }, + "tourism": { + "label": "Tips" + }, + "tower/construction": { + "label": "Būvēšana" + }, + "tower/type": { + "label": "Tips" + }, + "trade": { + "label": "Tips" + }, + "traffic_calming": { + "label": "Tips" + }, + "traffic_signals": { + "label": "Tips" + }, + "transformer": { + "options": { + "auto": "Autotransformātors", + "converter": "Pārveidotājs", + "generator": "Ģenerātors", + "yes": "Nezināms" + } + }, + "trees": { + "label": "Koki" + }, + "tunnel": { + "label": "Tips", + "placeholder": "Noklusējuma" + }, + "usage_rail": { + "label": "Izmantošanas Veids", + "options": { + "branch": "Zars", + "industrial": "Industriāls", + "main": "Galvenais", + "military": "Militārs", + "test": "Testa", + "tourism": "Tūrisma" + } + }, + "vending": { + "label": "Produktu tipi" + }, + "visibility": { + "label": "Redzamība", + "options": { + "area": "Pāri 20m (65 pēdām)", + "house": "Līdz 5m (16 pēdas)", + "street": "5 līdz 20m (16 - 65 pēdas)" + } + }, + "volcano/status": { + "label": "Vulkāna status", + "options": { + "active": "Aktīvs" + } + }, + "volcano/type": { + "label": "Vulkāna tips" + }, + "voltage": { + "label": "Voltāža" + }, + "water": { + "label": "Tips" + }, + "water_point": { + "label": "Ūdens Punkts" + }, + "waterway": { + "label": "Tips" + }, + "website": { + "label": "Interneta lapa" + }, + "wetland": { + "label": "Tips" + }, + "wheelchair": { + "label": "Ratiņkrēslam pieejams" + }, + "wholesale": { + "label": "Lielpārdošana" + }, + "width": { + "label": "Platums (Metros)" + }, + "wikipedia": { + "label": "Vikipēdija" + }, + "windings": { + "label": "Tinumi", + "placeholder": "1, 2, 3..." + }, + "windings/configuration": { + "label": "Tinumu konfigurācija" + } + }, + "presets": { + "address": { + "name": "Adrese" + }, + "advertising/billboard": { + "name": "Reklāmas dēlis" + }, + "advertising/column": { + "name": "Reklāmu stabs" + }, + "aerialway/cable_car": { + "name": "Trosu Ceļš" + }, + "aeroway/aerodrome": { + "name": "Lidosta" + }, + "aeroway/gate": { + "name": "Lidostas vārti" + }, + "aeroway/hangar": { + "name": "Angārs" + }, + "aeroway/helipad": { + "name": "Helikopteru nosēšanās laukums" + }, + "aeroway/runway": { + "name": "Skrejceļš" + }, + "aeroway/taxiway": { + "name": "Manevrēšanas ceļš" + }, + "aeroway/terminal": { + "name": "Lidostas Terminālis" + }, + "amenity": { + "name": "Labierīcība" + }, + "amenity/animal_shelter": { + "name": "Dzīvnieku patversme" + }, + "amenity/arts_centre": { + "name": "Mākslas Centrs" + }, + "amenity/atm": { + "name": "Bankomāts" + }, + "amenity/bank": { + "name": "Banka" + }, + "amenity/bar": { + "name": "Bārs" + }, + "amenity/bbq": { + "name": "Barbekjū/Grills" + }, + "amenity/bench": { + "name": "Sols" + }, + "amenity/bicycle_parking": { + "name": "Velo stāvvieta" + }, + "amenity/bicycle_rental": { + "name": "Velonoma", + "terms": "velosipēdu" + }, + "amenity/bicycle_repair_station": { + "name": "Velosipēdu Remonta Darbarīku Stends" + }, + "amenity/boat_rental": { + "name": "Laivu īre" + }, + "amenity/bureau_de_change": { + "name": "Valūtas Maiņa" + }, + "amenity/bus_station": { + "name": "Autobusu pietura / Terminālis" + }, + "amenity/cafe": { + "name": "Kafejnīca", + "terms": "bistro,krogs,kafija,tēja" + }, + "amenity/car_rental": { + "name": "Autonoma" + }, + "amenity/car_wash": { + "name": "Automazgātuve" + }, + "amenity/casino": { + "name": "Kazino" + }, + "amenity/charging_station": { + "name": "Uzlādes stacija", + "terms": "elektriskā,uzlāde,elektroauto,superlāde,zemsprieguma uzlāde" + }, + "amenity/childcare": { + "name": "Bērnistaba / Bērnu aprūpe" + }, + "amenity/cinema": { + "name": "Kino", + "terms": "kinoteātris,filmas,izrādes,lielekrāna" + }, + "amenity/clinic": { + "name": "Klīnika", + "terms": "medicīna,neatliekama" + }, + "amenity/clinic/abortion": { + "name": "Aborta klīnika" + }, + "amenity/clinic/fertility": { + "name": "Fertilitātes Klīnika" + }, + "amenity/clock": { + "name": "Pulkstenis" + }, + "amenity/community_centre": { + "name": "Kopienas centrs" + }, + "amenity/compressed_air": { + "name": "Saspiests Gaiss", + "terms": "augstspiediena,riepu uzpilde" + }, + "amenity/courthouse": { + "name": "Tiesas nams", + "terms": "tiesnesis,apgabaltiesa" + }, + "amenity/crematorium": { + "name": "Krematorija", + "terms": "bēres,kapi" + }, + "amenity/dentist": { + "name": "Zobārsts", + "terms": "zobi,ārsts,higēnists" + }, + "amenity/doctors": { + "name": "Dakteris", + "terms": "ārsts,medicīna" + }, + "amenity/dojo": { + "name": "Dojo / Karatē apmācība", + "terms": "karatē,skola" + }, + "amenity/drinking_water": { + "name": "Dzeramūdens" + }, + "amenity/driving_school": { + "name": "Autoskola", + "terms": "braukšana,apmācība" + }, + "amenity/embassy": { + "name": "Vēstniecība" + }, + "amenity/fast_food": { + "name": "Ātrās ēdināšanas iestāde", + "terms": "restorāns,līdzņemšana" + }, + "amenity/fire_station": { + "name": "Ugunsdzēsēju stacija", + "terms": "pažarnieki,depo" + }, + "amenity/food_court": { + "name": "Ēdnīca", + "terms": "restorāns,ātrā uzkoda,ēdiens" + }, + "amenity/fountain": { + "name": "Strūklaka" + }, + "amenity/fuel": { + "name": "Degvielas uzpildes stacija", + "terms": "degviela,dīzelis,gāze,98,95,uzpilde" + }, + "amenity/grave_yard": { + "name": "Kapi" + }, + "amenity/grit_bin": { + "name": "Smilšu tvertne", + "terms": "sāls kaste,smilšu kaste,smiltis,sāls,grants" + }, + "amenity/hunting_stand": { + "name": "Medību stends", + "terms": "ieroču,šaušana,šautuve" + }, + "amenity/ice_cream": { + "name": "Saldējuma Veikals", + "terms": "sorbejs,saldēts" + }, + "amenity/internet_cafe": { + "name": "Interneta Kafejnīca" + }, + "amenity/library": { + "name": "Bibliotēka", + "terms": "grāmatas,lasītava" + }, + "amenity/marketplace": { + "name": "Tirgus" + }, + "amenity/motorcycle_parking": { + "name": "Motociklu stāvvieta" + }, + "amenity/music_school": { + "name": "Mūzikas skola", + "terms": "dziedāšanas skola,mūzikas instrumenti" + }, + "amenity/nightclub": { + "name": "Naktsklubs", + "terms": "klubs,deju klubs,dejošana,nakts klubs" + }, + "amenity/parking": { + "name": "Stāvvieta", + "terms": "auto,mašīnas,stāvvieta,stāvēšana,apstāšanās,pieturvieta" + }, + "amenity/parking/multi-storey": { + "name": "Daudzlīmeņu Stāvvieta", + "terms": "garāža,daudzstāvu,stāvi,ēka,autostāvieta" + }, + "amenity/place_of_worship": { + "name": "Dievnams", + "terms": "baziliks,baznīca,katedrāle,kapella,mošeja,lūgšanas,bazilika" + }, + "amenity/place_of_worship/buddhist": { + "name": "Budistu templis" + }, + "amenity/place_of_worship/hindu": { + "name": "Hindu Templis" + }, + "amenity/place_of_worship/shinto": { + "name": "Sintoistu svētnīca" + }, + "amenity/planetarium": { + "name": "Planetārijs" + }, + "amenity/police": { + "name": "Policija", + "terms": "iecirknis,detektīvs,likums,kruķi,poliči" + }, + "amenity/post_office": { + "name": "Pasta nodaļa", + "terms": "vēstule,pasts,paciņa" + }, + "amenity/prison": { + "terms": "cietums,ūķis,aizturēšana,kamera" + }, + "amenity/pub": { + "name": "Krogs", + "terms": "alkohols,dzeršana,alus" + }, + "amenity/public_bookcase": { + "name": "Publisks Grāmatplaukts" + }, + "amenity/recycling_centre": { + "name": "Šķirošanas centrs" + }, + "amenity/restaurant": { + "name": "Restorāns" + }, + "amenity/school": { + "name": "Skolas Zeme" + }, + "amenity/shelter": { + "name": "Pajumte" + }, + "amenity/shower": { + "name": "Duša" + }, + "amenity/smoking_area": { + "name": "Smēķēšanas vieta" + }, + "amenity/social_facility/food_bank": { + "name": "Pārtikas banka", + "terms": "ēdiena nodošana,ēdiena banka" + }, + "amenity/social_facility/group_home": { + "name": "Pansionāts", + "terms": "vecs,seniors,uzraudzība" + }, + "amenity/studio": { + "name": "Studija" + }, + "amenity/telephone": { + "name": "Telefons" + }, + "amenity/theatre": { + "name": "Teātris", + "terms": "aktieri,uzstāšanās,uzvedums" + }, + "amenity/toilets": { + "name": "Tualete", + "terms": "toalete,labierīcības,pisuārs" + }, + "amenity/townhall": { + "name": "Pilsētas dome" + }, + "amenity/vending_machine": { + "name": "Tirdzniecības automāts" + }, + "amenity/vending_machine/cigarettes": { + "name": "Cigarešu Tirdzniecības automāts", + "terms": "cigrarete,tabaka" + }, + "amenity/vending_machine/coffee": { + "name": "Kafijas Tirdzniecības automāts", + "terms": "kafija,kofeīns,ekspresso" + }, + "amenity/vending_machine/condoms": { + "name": "Prezervatīvu Tirdzniecības automāts" + }, + "amenity/vending_machine/drinks": { + "name": "Dzērienu Tirdzniecības automāts", + "terms": "limonāde,sula,dzēriens" + }, + "amenity/vending_machine/electronics": { + "name": "Elektronikas Tirdzniecības automāts", + "terms": "kabelis,telefons,planšete,dators,austiņas,skaļruņi" + }, + "amenity/vending_machine/elongated_coin": { + "name": "Plakanu Monētu Tirdzniecības automāts", + "terms": "monēta,saspiešana,suvenīri,suvenīrs,saplacināt" + }, + "amenity/vending_machine/feminine_hygiene": { + "name": "Sieviešu Higēnas Tirdzniecības automāts", + "terms": "tampons,ieliknis,biksīšu,sieivešu,menstruāls,personālā apkope" + }, + "amenity/vending_machine/food": { + "name": "Ēdiena Tirdzniecības automāts", + "terms": "pārtika" + }, + "amenity/vending_machine/fuel": { + "name": "Degvielas sūknis", + "terms": "degviela,dīzelis,gāze,98,95,uzpilde" + }, + "amenity/vending_machine/ice_cream": { + "name": "Saldējuma Tirdzniecības automāts", + "terms": "šokolādes,vaniļas,sasaldēts,auksts" + }, + "amenity/vending_machine/newspapers": { + "name": "Avīžu Tirdzniecības automāts", + "terms": "avīze,laiksraksts,žurnāls,iespiests" + }, + "amenity/vending_machine/parking_tickets": { + "name": "Stāvvietu Atļauju Tirdzniecības automāts", + "terms": "biļete,atļauja" + }, + "amenity/vending_machine/public_transport_tickets": { + "name": "Tranzītbiļešu Tirdzniecības automāts", + "terms": "autobuss,vilciens,e-talons,transports,biļete,tranvajs,trolejbuss,prāmis,etalons" + }, + "amenity/vending_machine/stamps": { + "name": "Pastmarku Tirdzniecības automāts", + "terms": "pasts,marka,vēstule" + }, + "amenity/vending_machine/sweets": { + "name": "Saldumu Tirdzniecības automāts", + "terms": "šokolādes,saldumu,konfekšu,cepumu,batoniņu" + }, + "amenity/veterinary": { + "name": "Veternārārsts", + "terms": "klīnika,veterniārā,dzīvienku,veterinārais ārsts" + }, + "amenity/waste/dog_excrement": { + "name": "Suņu ekskrementu tvertne", + "terms": "tvertne,kaste,suņu,kaku,maisiņu,atkritumu" + }, + "amenity/waste_basket": { + "name": "Atkritumu grozs", + "terms": "miskaste,papīrgrozs,izmestuve,atkritumi" + }, + "amenity/waste_disposal": { + "name": "Atkritumu konteiners", + "terms": "miskaste,atkritumi,izgāztuve,tvertne" + }, + "area": { + "name": "Apgabals" + }, + "attraction/big_wheel": { + "name": "Panorāmas rats", + "terms": "rats,atrakcija,bruciens,lielais rats" + }, + "attraction/bungee_jumping": { + "name": "Gumijlēkšana", + "terms": "gumija,augstums,lekšana,lekšanas platforma" + }, + "attraction/carousel": { + "name": "Karuseļu", + "terms": "atrakciju,zirgu" + }, + "attraction/maze": { + "name": "Labirints" + }, + "attraction/roller_coaster": { + "name": "Amerikāņu Kalniņi", + "terms": "atrakcija,brauciens,ātrs" + }, + "attraction/train": { + "name": "Tūristu vilcieniņš", + "terms": "apskates vilciens,apbrauciena,parka vilciens" + }, + "attraction/water_slide": { + "name": "Ūdens Slidkalniņš", + "terms": "ūdens parks,ūdens atrakcija" + }, + "barrier": { + "name": "Barjera" + }, + "barrier/block": { + "name": "Bloks", + "terms": "klucis,gabals" + }, + "barrier/bollard": { + "name": "Stabs", + "terms": "stabi,stabiņi" + }, + "barrier/border_control": { + "name": "Robežu Kontrole", + "terms": "pārbaude,kontroles punkts,pases,ieeja,robežkontrole" + }, + "barrier/city_wall": { + "name": "Pilsētas mūri" + }, + "barrier/cycle_barrier": { + "name": "Veloceliņa barjera" + }, + "barrier/ditch": { + "name": "Tranšeja", + "terms": "trenča,bedre" + }, + "barrier/entrance": { + "name": "Ieeja" + }, + "barrier/fence": { + "name": "Žogs" + }, + "barrier/gate": { + "name": "Vārti", + "terms": "žogs" + }, + "barrier/hedge": { + "name": "Krūmi" + }, + "barrier/kissing_gate": { + "name": "Dubultveramie vārti", + "terms": "dubultie,abpusējie,dubultvārti" + }, + "barrier/lift_gate": { + "name": "Lifta ieeja", + "terms": "paceļamie,bomja,bomis" + }, + "barrier/retaining_wall": { + "name": "Stiprinājuma siena" + }, + "barrier/toll_booth": { + "name": "Muitas punkts" + }, + "barrier/wall": { + "name": "Siena" + }, + "boundary/administrative": { + "name": "Administratīvā robeža", + "terms": "robeža,novadu robeža,administratīvā teritorija" + }, + "building": { + "name": "Ēka" + }, + "building/barn": { + "name": "Klēts" + }, + "building/boathouse": { + "name": "Laivu ēka" + }, + "building/bunker": { + "name": "Bunkurs" + }, + "building/cabin": { + "name": "Būda" + }, + "building/cathedral": { + "name": "Katedrāles Ēka" + }, + "building/chapel": { + "name": "Kappelas Ēka" + }, + "building/church": { + "name": "Baznīcas Ēka" + }, + "building/commercial": { + "name": "Komerciāla Ēka" + }, + "building/dormitory": { + "name": "Kopmītnes" + }, + "building/entrance": { + "name": "Ieeja/Izeja" + }, + "building/farm_auxiliary": { + "name": "Fermas Ēka" + }, + "building/garage": { + "name": "Garāža" + }, + "building/garages": { + "name": "Garāžas" + }, + "building/grandstand": { + "name": "Tribīnes" + }, + "building/greenhouse": { + "name": "Siltumnīca", + "terms": "augi,stikls" + }, + "building/hospital": { + "name": "Slīmnīcas Ēka" + }, + "building/hotel": { + "name": "Viesnīcas Ēka" + }, + "building/house": { + "name": "Māja" + }, + "building/industrial": { + "name": "Ražošanas ēka" + }, + "building/mosque": { + "name": "Mošejas Ēka" + }, + "building/public": { + "name": "Publiska Ēka" + }, + "building/residential": { + "name": "Dzīvojamā Ēka" + }, + "building/retail": { + "name": "Komerciāla Ēka" + }, + "building/roof": { + "name": "Jumts" + }, + "building/ruins": { + "name": "Ēkas drupas" + }, + "building/school": { + "name": "Skolas Ēka", + "terms": "sākumskola,pamatskola,vidusskola,augstskola,koledža" + }, + "building/shed": { + "name": "Sķūnis" + }, + "building/stable": { + "name": "Stallis", + "terms": "zirgu,zirgi,stallis" + }, + "building/stadium": { + "name": "Stadiona Ēka" + }, + "building/temple": { + "name": "Tempļa Ēka", + "terms": "templis,reliģija,piemiņa" + }, + "building/terrace": { + "name": "Rindumājas", + "terms": "rindu mājas,mājas" + }, + "building/university": { + "name": "Universitātes Ēka" + }, + "building/warehouse": { + "name": "Noliktava" + }, + "club": { + "name": "Klubs" + }, + "craft/basket_maker": { + "name": "Grozu veidotājs" + }, + "craft/beekeeper": { + "name": "Biškopis", + "terms": "bišu kopējs" + }, + "craft/blacksmith": { + "name": "Kalējs", + "terms": "metālkalis,kalis" + }, + "craft/boatbuilder": { + "name": "Laivu būvētājs", + "terms": "laivenieks,piķotājs" + }, + "craft/brewery": { + "name": "Darītava", + "terms": "alkohols,alus,sidrs" + }, + "craft/carpenter": { + "name": "Galdnieks" + }, + "craft/chimney_sweeper": { + "name": "Skursteņslauķis", + "terms": "skursteņu slaucītājs" + }, + "craft/clockmaker": { + "name": "Pulksteņdaris", + "terms": "pulksteņmeistars" + }, + "craft/confectionery": { + "name": "Saldumu veidotājs", + "terms": "saldumi,konfektes,konfekcionārs" + }, + "craft/electrician": { + "name": "Elektriķis" + }, + "craft/electronics_repair": { + "name": "Elektronikas remonta darbnīca" + }, + "craft/gardener": { + "name": "Dārznieks" + }, + "craft/key_cutter": { + "name": "Atslēdznieks" + }, + "craft/locksmith": { + "name": "Atslēdznieks" + }, + "craft/painter": { + "name": "Krāsotājs" + }, + "craft/photographer": { + "name": "Fotogrāfs", + "terms": "fotogrāfēt" + }, + "craft/photographic_laboratory": { + "name": "Fotolabratorija", + "terms": "attēlu attīstīšana,filmas,filmiņas,3.5mm" + }, + "craft/plumber": { + "name": "Santehniķis" + }, + "craft/roofer": { + "name": "Jumiķis" + }, + "craft/sawmill": { + "name": "Kokzāģētava" + }, + "craft/sculptor": { + "name": "Skulptors" + }, + "craft/shoemaker": { + "name": "Kurpnieks" + }, + "craft/window_construction": { + "name": "Logu izgatavošana" + }, + "craft/winery": { + "name": "Vīna darītava" + }, + "emergency/ambulance_station": { + "name": "Ātrās palīdzības stacija", + "terms": "ambulances stacija,ātrā palīdzība" + }, + "emergency/defibrillator": { + "name": "Defibrilators" + }, + "emergency/fire_extinguisher": { + "name": "Ugunsdzēsības aparāts" + }, + "emergency/fire_hydrant": { + "name": "Ugunsdzēsības Hidrants" + }, + "emergency/first_aid_kit": { + "name": "Pirmās palīdzības aptieciņa", + "terms": "aptieciņa,kompleks,medicīnas,ārkārtas" + }, + "emergency/life_ring": { + "name": "Glābšanas Rinķis" + }, + "emergency/lifeguard": { + "name": "Glābējs" + }, + "emergency/phone": { + "name": "Ārkārtas telefons" + }, + "emergency/siren": { + "name": "Sirēna" + }, + "golf/hole": { + "name": "Golfa bedrīte" + }, + "healthcare/birthing_center": { + "name": "Dzemdību nams" + }, + "healthcare/blood_donation": { + "name": "Asinsdonoru Centrs" + }, + "healthcare/laboratory": { + "name": "Medicīnas Labrotorija" + }, + "healthcare/optometrist": { + "name": "Optometrists" + }, + "healthcare/speech_therapist": { + "name": "Runas Terapiets" + }, + "highway/corridor": { + "name": "Iekštelpu koridors" + }, + "highway/cycleway": { + "name": "Veloceliņš" + }, + "highway/elevator": { + "name": "Lifts" + }, + "highway/footway": { + "name": "Ietve", + "terms": "taka,gājēju,kājāmgājēju,celiņš" + }, + "highway/living_street": { + "name": "Dzīvojamā iela" + }, + "highway/motorway": { + "name": "Ātrgaitas šoseja" + }, + "highway/path": { + "name": "Taka" + }, + "highway/pedestrian_line": { + "name": "Gājēju iela" + }, + "highway/primary": { + "name": "Galvenais ceļš" + }, + "highway/road": { + "name": "Nezināms ceļš" + }, + "highway/secondary": { + "name": "Otrās škiras ceļš" + }, + "highway/service": { + "name": "Apkalpošanas ceļš" + }, + "highway/service/driveway": { + "name": "Piebraucamais ceļš" + }, + "highway/speed_camera": { + "name": "Fotoradars" + }, + "highway/steps": { + "name": "Kāpnes" + }, + "highway/stop": { + "name": "Stop Zīme" + }, + "highway/street_lamp": { + "name": "Ielu Gaisma" + }, + "highway/traffic_signals": { + "name": "Luksofors" + }, + "highway/turning_circle": { + "name": "Apgriešanās riņķis" + }, + "highway/unclassified": { + "name": "Mazs/Neklasificēts ceļš" + }, + "historic": { + "name": "Vēsturiska vieta" + }, + "historic/archaeological_site": { + "name": "Arheoloģisko izrakumu vieta" + }, + "historic/boundary_stone": { + "name": "Robežakmens" + }, + "historic/castle": { + "name": "Pils" + }, + "historic/memorial": { + "name": "Memoriāls" + }, + "historic/monument": { + "name": "Piemineklis" + }, + "historic/ruins": { + "name": "Pilsdrupas" + }, + "landuse/basin": { + "name": "Baseins" + }, + "landuse/cemetery": { + "name": "Kapsēta" + }, + "landuse/commercial": { + "name": "Komercplatība", + "terms": "komerciāla platība,komercapgabals" + }, + "landuse/farmyard": { + "name": "Lauku sēta" + }, + "landuse/garages": { + "name": "Garāžu zeme" + }, + "landuse/grass": { + "name": "Zāle" + }, + "landuse/harbour": { + "name": "Osta" + }, + "landuse/industrial": { + "name": "Ražošanas zona" + }, + "landuse/industrial/slaughterhouse": { + "name": "Kautuve" + }, + "landuse/landfill": { + "name": "Izgāztuve" + }, + "landuse/meadow": { + "name": "Pļava" + }, + "landuse/military": { + "name": "Militārā zona" + }, + "landuse/military/airfield": { + "name": "Militārais Lidlauks" + }, + "landuse/military/barracks": { + "name": "Kazarmas" + }, + "landuse/military/naval_base": { + "name": "Ūdensspēku bāze" + }, + "landuse/quarry": { + "name": "Karjers" + }, + "landuse/residential": { + "name": "Dzīvojamā zona" + }, + "landuse/vineyard": { + "name": "Vīnogu lauks" + }, + "leisure/bowling_alley": { + "name": "Boulinga Zāle" + }, + "leisure/dance": { + "name": "Deju zāle" + }, + "leisure/dancing_school": { + "name": "Deju skola", + "terms": "valsis,tango,deju apmācības,dejošana,svings" + }, + "leisure/dog_park": { + "name": "Suņu parks" + }, + "leisure/fitness_centre": { + "name": "Sportazāle / Fitnesa centrs" + }, + "leisure/fitness_centre/yoga": { + "name": "Jogas studija" + }, + "leisure/fitness_station": { + "name": "Brīvdabas fitnesa vieta" + }, + "leisure/garden": { + "name": "Dārzs" + }, + "leisure/golf_course": { + "name": "Golfa laukums" + }, + "leisure/horse_riding": { + "name": "Zirgu jāšanas vieta" + }, + "leisure/ice_rink": { + "name": "Ledus halle" + }, + "leisure/park": { + "name": "Parks" + }, + "leisure/picnic_table": { + "name": "Piknika galds" + }, + "leisure/pitch": { + "name": "Sporta laukums" + }, + "leisure/pitch/american_football": { + "name": "Amerikāņu futbola laukums" + }, + "leisure/pitch/basketball": { + "name": "Basketbola laukums" + }, + "leisure/pitch/beachvolleyball": { + "name": "Plūdmales volejbola laukums" + }, + "leisure/pitch/skateboard": { + "name": "Skrituļparks", + "terms": "skootei,skrituļdēļi,skrituļslidas,rampas" + }, + "leisure/pitch/soccer": { + "name": "Futbola laukums", + "terms": "futbols" + }, + "leisure/pitch/table_tennis": { + "name": "Pingponga galds", + "terms": "galda teniss,pingpongs" + }, + "leisure/pitch/tennis": { + "name": "Tenisa korti" + }, + "leisure/pitch/volleyball": { + "name": "Volejbola laukums" + }, + "leisure/playground": { + "name": "Spēļlaukums" + }, + "leisure/sauna": { + "name": "Sauna" + }, + "leisure/sports_centre": { + "name": "Sporta Centrs / Komplekss" + }, + "leisure/stadium": { + "name": "Stadions" + }, + "leisure/swimming_pool": { + "name": "Peldbaseins" + }, + "leisure/water_park": { + "name": "Akvaparks" + }, + "line": { + "name": "Līnija" + }, + "man_made/antenna": { + "name": "Antēna" + }, + "man_made/chimney": { + "name": "Skurstenis" + }, + "man_made/crane": { + "name": "Celtnis" + }, + "man_made/flagpole": { + "name": "Karogmasts", + "terms": "karogs,masts" + }, + "man_made/lighthouse": { + "name": "Bāka" + }, + "man_made/mast": { + "name": "Masts" + }, + "man_made/observatory": { + "name": "Observatorija" + }, + "man_made/petroleum_well": { + "name": "Naftas Raktuve" + }, + "man_made/pipeline": { + "name": "Caurule", + "terms": "truba" + }, + "man_made/pumping_station": { + "name": "Pumpētava" + }, + "man_made/surveillance": { + "name": "Apsardze" + }, + "man_made/survey_point": { + "name": "Novērošanas punkts" + }, + "man_made/tower": { + "name": "Tornis" + }, + "man_made/wastewater_plant": { + "name": "Notekūdeņu stacija" + }, + "man_made/water_tower": { + "name": "Ūdenstornis" + }, + "man_made/water_well": { + "name": "Ūdens aka", + "terms": "aka,dzeramūdens" + }, + "man_made/watermill": { + "name": "Ūdens Dzirnavas" + }, + "man_made/windmill": { + "name": "Vējdzirnavas" + }, + "man_made/works": { + "name": "Rūpnīca" + }, + "natural/bare_rock": { + "name": "Pliks Akmens" + }, + "natural/bay": { + "name": "Līcis" + }, + "natural/beach": { + "name": "Pludmale" + }, + "natural/cave_entrance": { + "name": "Alas Ieeja" + }, + "natural/cliff": { + "name": "Klints" + }, + "natural/coastline": { + "name": "Krasta līnija" + }, + "natural/glacier": { + "name": "Ledājs" + }, + "natural/grassland": { + "name": "Neapstrādāta zeme" + }, + "natural/heath": { + "name": "Tīrelis", + "terms": "virsājs,koki,tīrelis,mazs" + }, + "natural/mud": { + "name": "Dubļi" + }, + "natural/peak": { + "name": "Virsotne" + }, + "natural/reef": { + "name": "Rifs" + }, + "natural/sand": { + "name": "Smiltis" + }, + "natural/spring": { + "name": "Avots" + }, + "natural/tree": { + "name": "Koks", + "terms": "koki" + }, + "natural/volcano": { + "name": "Vulkāns" + }, + "natural/water": { + "name": "Ūdens" + }, + "natural/water/lake": { + "name": "Ezers" + }, + "natural/water/pond": { + "name": "Dīķis" + }, + "natural/water/reservoir": { + "name": "Ūdenstilpne" + }, + "natural/wetland": { + "name": "Purvs" + }, + "noexit/yes": { + "name": "Bez izejas" + }, + "office": { + "name": "Biroju ēka" + }, + "office/adoption_agency": { + "name": "Adopcijas Aģentūra" + }, + "office/architect": { + "name": "Arhitekta birojs" + }, + "office/educational_institution": { + "name": "Izglītības Iestāde" + }, + "office/energy_supplier": { + "name": "Elektrodevēja birojs" + }, + "office/forestry": { + "name": "Mežniecības birojs" + }, + "office/government": { + "name": "Valdības birojs" + }, + "office/government/tax": { + "name": "Ieņēmumu birojs" + }, + "office/insurance": { + "name": "Apdrošināšanas birojs" + }, + "office/lawyer/notary": { + "name": "Notāru birojs" + }, + "office/notary": { + "name": "Notāru birojs" + }, + "office/private_investigator": { + "name": "Privātizmeklētēja birojs" + }, + "office/telecommunication": { + "name": "Telekomunikāciju birojs" + }, + "office/therapist": { + "name": "Terapieta birojs" + }, + "place": { + "name": "Vieta" + }, + "place/city": { + "name": "Lielpilsēta" + }, + "place/farm": { + "name": "Zemnieku saimniecība" + }, + "place/island": { + "name": "Sala" + }, + "place/square": { + "name": "Skvērs" + }, + "place/town": { + "name": "Pilsēta" + }, + "place/village": { + "name": "Ciems" + }, + "playground/slide": { + "name": "Slidkalniņš" + }, + "playground/swing": { + "name": "Šūpoles" + }, + "power/generator": { + "name": "Elektroenerģijas ģenerātors", + "terms": "elektroģenrātors,turbīna,vējs" + }, + "power/line": { + "name": "Elektrolīnija" + }, + "power/pole": { + "name": "Elektrības stabs", + "terms": "elektrostabs" + }, + "power/substation": { + "name": "Apakšstacija" + }, + "power/tower": { + "name": "Augstsprieguma tornis" + }, + "power/transformer": { + "name": "Transformators" + }, + "public_transport/station_bus": { + "name": "Autobusu stacija / Terminālis" + }, + "public_transport/station_train": { + "name": "Stacija" + }, + "public_transport/station_trolleybus": { + "name": "Trolejbusu stacija / Terminālis" + }, + "railway/abandoned": { + "name": "Pamests dzelzceļš" + }, + "railway/disused": { + "name": "Nelietots dzelzceļš" + }, + "railway/station": { + "name": "Vilcienu Stacija" + }, + "railway/subway_entrance": { + "name": "Metro ieeja" + }, + "railway/switch": { + "name": "Pārmiju pārslēgšana", + "terms": "pārmijas" + }, + "railway/train_wash": { + "name": "Vilcienu mazgātuve" + }, + "relation": { + "name": "Relācija" + }, + "shop": { + "name": "Veikals" + }, + "shop/alcohol": { + "name": "Alkoholisko dzērienu veikals" + }, + "shop/antiques": { + "name": "Antikvariāts" + }, + "shop/art": { + "name": "Mākslas veikals" + }, + "shop/bag": { + "name": "Somu / Čemodānu veikals" + }, + "shop/bakery": { + "name": "Konditoreja" + }, + "shop/beauty": { + "name": "Skaistumveikals" + }, + "shop/beauty/nails": { + "name": "Manikīra/Nagu salons" + }, + "shop/beauty/tanning": { + "name": "Solārija Salons", + "terms": "solārija,solārijs" + }, + "shop/bed": { + "name": "Gultasveļas / Matraču veikals", + "terms": "gultas preces,gulta" + }, + "shop/beverages": { + "name": "Dzērienu veikals" + }, + "shop/bicycle": { + "name": "Velo veikals", + "terms": "velosipēdu,remonts,remonta" + }, + "shop/books": { + "name": "Grāmatu veikals" + }, + "shop/boutique": { + "name": "Veikals" + }, + "shop/butcher": { + "name": "Miesnieks" + }, + "shop/candles": { + "name": "Sveču veikals" + }, + "shop/car": { + "name": "Auto dīleris", + "terms": "auto,mašīnu,pārdošana" + }, + "shop/car_parts": { + "name": "Auto rezerves daļu veikals" + }, + "shop/car_repair": { + "name": "Auto remontdarbnīca", + "terms": "remonts,serviss,garāža" + }, + "shop/carpet": { + "name": "Paklāju veikals" + }, + "shop/cheese": { + "name": "Siera veikals" + }, + "shop/chemist": { + "name": "Aptieka" + }, + "shop/chocolate": { + "name": "Šokolādes veikals" + }, + "shop/clothes": { + "name": "Apģērba veikals" + }, + "shop/coffee": { + "name": "Kafijas veikals" + }, + "shop/computer": { + "name": "Datorveikals", + "terms": "elektronika,datori,datortehnika" + }, + "shop/confectionery": { + "name": "Saldumu veikals" + }, + "shop/convenience": { + "name": "Veikals" + }, + "shop/copyshop": { + "name": "Printēšanas veikals" + }, + "shop/cosmetics": { + "name": "Kosmētikas veikals" + }, + "shop/curtain": { + "name": "Aizkaru veikals" + }, + "shop/dairy": { + "name": "Piena veikals" + }, + "shop/deli": { + "name": "Delikateses" + }, + "shop/department_store": { + "name": "Lielveikals" + }, + "shop/dry_cleaning": { + "name": "Ķīmiskā tīrītava" + }, + "shop/e-cigarette": { + "name": "E-Cigarešu veikals" + }, + "shop/electronics": { + "name": "Elektronikas veikals" + }, + "shop/erotic": { + "name": "Erotiskais veikals" + }, + "shop/fabric": { + "name": "Audumu veikals" + }, + "shop/fashion": { + "name": "Modes veikals" + }, + "shop/florist": { + "name": "Florists" + }, + "shop/funeral_directors": { + "name": "Apbedīšanas birojs" + }, + "shop/furniture": { + "name": "Mēbeļu veikals" + }, + "shop/garden_centre": { + "name": "Dārzkopības veikals" + }, + "shop/gas": { + "name": "Gāzes balonu veikals", + "terms": "lpg,propāns,balons,uzpilde,gāze" + }, + "shop/gift": { + "name": "Dāvanu veikals" + }, + "shop/hairdresser": { + "name": "Frizieris" + }, + "shop/hardware": { + "name": "Celtniecības veikals" + }, + "shop/kiosk": { + "name": "Kiosks" + }, + "shop/kitchen": { + "name": "Virtuves dizaina veikals" + }, + "shop/laundry": { + "name": "Veļas mazgātuve" + }, + "shop/leather": { + "name": "Ādas veikals" + }, + "shop/locksmith": { + "name": "Atslēdznieks" + }, + "shop/lottery": { + "name": "Loterijas veikals" + }, + "shop/mall": { + "name": "Iepirkšanās centrs" + }, + "shop/massage": { + "name": "Masāžu veikals" + }, + "shop/medical_supply": { + "name": "Medicīnisko piederumu veikals" + }, + "shop/mobile_phone": { + "name": "Mobilo telefonu veikals" + }, + "shop/money_lender": { + "name": "Naudas Aizdevējs" + }, + "shop/motorcycle": { + "name": "Motociklu veikals" + }, + "shop/motorcycle_repair": { + "name": "Motociklu remonta darbnīca" + }, + "shop/music": { + "name": "Mūzikas veikals" + }, + "shop/musical_instrument": { + "name": "Mūzikas instrumentu veikals" + }, + "shop/newsagent": { + "name": "Avīžu / Žurnālu veikals" + }, + "shop/optician": { + "name": "Optometrists" + }, + "shop/paint": { + "name": "Krāsu veikals" + }, + "shop/pawnbroker": { + "name": "Lombards" + }, + "shop/pet": { + "name": "Dzīvnieku veikals" + }, + "shop/photo": { + "name": "Fotogrāfijas veikals" + }, + "shop/radiotechnics": { + "name": "Radio / Elektronisko komponenšu veikals" + }, + "shop/shoes": { + "name": "Apavu veikals" + }, + "shop/sports": { + "name": "Sporta veikals" + }, + "shop/stationery": { + "name": "Rakstāmlietu veikals" + }, + "shop/supermarket": { + "name": "Lielveikals" + }, + "shop/tattoo": { + "name": "Tetovējumu veikals" + }, + "shop/tea": { + "name": "Tējas veikals" + }, + "shop/ticket": { + "name": "Biļešu kase" + }, + "shop/tiles": { + "name": "Flīžu veikals" + }, + "shop/tobacco": { + "name": "Tabakas veikals" + }, + "shop/toys": { + "name": "Rotaļlietu veikals" + }, + "shop/travel_agency": { + "name": "Ceļojumu aģentūra" + }, + "shop/tyres": { + "name": "Riepu veikals" + }, + "shop/vacuum_cleaner": { + "name": "Putekļusūcēju veikals" + }, + "shop/video": { + "name": "Video veikals" + }, + "shop/video_games": { + "name": "Videospēļu veikals" + }, + "shop/watches": { + "name": "Pulksteņu Veikals" + }, + "shop/weapons": { + "name": "Ieroču Veikals" + }, + "shop/window_blind": { + "name": "Logu žalūziju veikals", + "terms": "logi,aizkari,žalūzijas" + }, + "shop/wine": { + "name": "Vīna veikals" + }, + "tourism/aquarium": { + "name": "Akvārijs" + }, + "tourism/artwork": { + "name": "Mākslas darbs" + }, + "tourism/attraction": { + "name": "Tūrisma objekts" + }, + "tourism/camp_site": { + "name": "Kempinga vieta" + }, + "tourism/gallery": { + "name": "Mākslas galerija" + }, + "tourism/guest_house": { + "name": "Viesu nams" + }, + "tourism/hostel": { + "name": "Hostelis" + }, + "tourism/hotel": { + "name": "Viesnīca" + }, + "tourism/information": { + "name": "Informācija" + }, + "tourism/information/board": { + "name": "Informācijas stends" + }, + "tourism/information/map": { + "name": "Karte" + }, + "tourism/motel": { + "name": "Motelis" + }, + "tourism/museum": { + "name": "Muzejs" + }, + "tourism/picnic_site": { + "name": "Piknika vieta" + }, + "tourism/theme_park": { + "name": "Tematiskais parks" + }, + "tourism/viewpoint": { + "name": "Skatu punkts" + }, + "tourism/zoo": { + "name": "Zooloģiskais dārzs", + "terms": "zoodārzs,zoo,dzīvnieku dārzs,dzīvnieki" + }, + "traffic_calming/bump": { + "name": "Guļošais Policists" + }, + "traffic_calming/hump": { + "name": "Guļošais Policists" + }, + "traffic_calming/island": { + "name": "Ceļa saliņa" + }, + "type/boundary": { + "name": "Robeža" + }, + "type/boundary/administrative": { + "name": "Administratīvā robeža" + }, + "type/restriction": { + "name": "Aizliegums" + }, + "waterway/canal": { + "name": "Kanāls" + }, + "waterway/dam": { + "name": "Dambis" + }, + "waterway/ditch": { + "name": "Grāvis" + }, + "waterway/drain": { + "name": "Notekgrāvis" + }, + "waterway/river": { + "name": "Upe" + }, + "waterway/riverbank": { + "name": "Upes krasts" + }, + "waterway/stream": { + "name": "Strauts" + }, + "waterway/waterfall": { + "name": "Ūdenskritums" + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/raw/changelog.yml b/app/src/main/res/raw/changelog.yml index ccc59a9df5..d40164d872 100644 --- a/app/src/main/res/raw/changelog.yml +++ b/app/src/main/res/raw/changelog.yml @@ -1,3 +1,14 @@ +v43.1: | +

Other Enhancements and Fixes

+
    +
  • Correct hint text for shoulder quest: Shoulders that are not wide enough for a car are still considered shoulders as long as they are designated (i.e. marked) as such
  • +
  • Various minor enhancements and fixes (#3994...), thanks @peternewman
  • +
+

New Translations

+
    +
  • Added Latvian, by @Mazurs
  • +
+ v43.0: |

New Quests