Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/build_app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
--dart-define=THUNDERFOREST_API_KEY=${{ secrets.THUNDERFOREST_API_KEY }}
--dart-define=IS_RELEASE=true

# Required because F-Droid signs its apk with apksigner which produces a slightly different output than gradle signingConfig
# Required because F-Droid signs its apk with apksigner which produces a slightly different output than Gradle signingConfig
# see: https://f-droid.org/docs/Reproducible_Builds/#reproducible-signatures
- name: Sign with apksigner
run: >-
Expand Down Expand Up @@ -231,8 +231,8 @@ jobs:
--dart-define=THUNDERFOREST_API_KEY=${{ secrets.THUNDERFOREST_API_KEY }}
--dart-define=IS_RELEASE=true

# This step is mainly required because Google considers a link to a Github markdown file as "editable" which violates their policy.
# Therefore we convert the markdown file to HTML and publish it together with the App via Github pages here.
# This step is mainly required because Google considers a link to a GitHub Markdown file as "editable" which violates their policy.
# Therefore, we convert the Markdown file to HTML and publish it together with the App via GitHub pages here.
- name: Convert Privacy Policy to HTML
uses: BaileyJM02/markdown-to-pdf@v1.2.0
with:
Expand Down
5 changes: 5 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ analyzer:

errors:
avoid_slow_async_io: info
exclude:
- build/**
- android/**
- ios/**
- web/**

formatter:
trailing_commas: preserve
Expand Down
20 changes: 10 additions & 10 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
plugins {
id("com.android.application")
id("kotlin-android")
id("dev.flutter.flutter-gradle-plugin")
}

Expand All @@ -27,17 +26,12 @@ if (keystorePropertiesFile.exists()) {

android {
namespace = "de.tu_chemnitz.etit.sse.openstop"
compileSdk = 36
// Momentary fix. Alternatively the following line can also be commented out. See: https://github.com/flutter/flutter/issues/139427
ndkVersion = "27.0.12077973"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion

compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

sourceSets["main"].java.srcDirs("src/main/kotlin")
Expand Down Expand Up @@ -74,6 +68,12 @@ android {
}
}

kotlin {
compilerOptions {
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
}
}

flutter {
source = "../.."
}
3 changes: 2 additions & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true
android.newDsl=false
android.builtInKotlin=false
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-all.zip
4 changes: 2 additions & 2 deletions android/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ pluginManagement {

plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.9.1" apply false
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
id("com.android.application") version "9.1.0" apply false
id("org.jetbrains.kotlin.android") version "2.4.0" apply false
}

include(":app")
4 changes: 2 additions & 2 deletions docs/BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Prerequisites

Install and setup the [Flutter SDK](https://docs.flutter.dev/get-started/install).
Install and set up the [Flutter SDK](https://docs.flutter.dev/get-started/install).

## Build process

Expand All @@ -25,7 +25,7 @@ You can also omit the entire API key parameter. In this case the underlying map

## Additional notes

By default the app uses the [OpenStreetMap development server](https://master.apis.dev.openstreetmap.org) for login and upload. In order to use the live servers the custom parameter `--dart-define=IS_RELEASE=true` has to be set when running/building the app.
By default, the app uses the [OpenStreetMap development server](https://master.apis.dev.openstreetmap.org) for login and upload. In order to use the live servers the custom parameter `--dart-define=IS_RELEASE=true` has to be set when running/building the app.
**Note:** This has nothing to do with flutter's *release*, *profile* and *debug* mode.

Due to the usage of verified App Link or Universal Links respectively, login on the OpenStreetMap server won't work without signing the app. In order to enable login the files `app_config.dart`, `osm_config.dart`, `build.gradle` and `Runner.entitlements` need to be configured accordingly.
Expand Down
16 changes: 8 additions & 8 deletions docs/QUESTION_CATALOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Displays a number wheel for each specified time unit. Possible time units are `d
The duration is always completely returned to the constructor, meaning no duration inputs are lost.
If for example the input is in hours, minutes and seconds, but only hours is marked as a return value, the hours value will include the minutes and seconds in its representation (potentially in the fractional part). Make sure that the `constructor` only generates the permitted values of the corresponding tag.

The `$input` variable will contain all duration values marked with `return: true` in the following order: `days`, `hours`, `minutes` and `seconds`. Therefore at least one duration value should have `return": true`.
The `$input` variable will contain all duration values marked with `return: true` in the following order: `days`, `hours`, `minutes` and `seconds`. Therefore, at least one duration value should have `return": true`.

```jsonc
"answer": {
Expand Down Expand Up @@ -337,8 +337,8 @@ output: `operator=_alu_`

### Answer examples

#### Multiple values using the semi-colon value separator
The example will write all selected values to the *cuisine* tag separated by semi-colon.
#### Multiple values using the semicolon value separator
The example will write all selected values to the *cuisine* tag separated by semicolon.
**Explanation:** The `$input` variable will contain all selected values, which will be concatenated by the `JOIN` expression.

```jsonc
Expand Down Expand Up @@ -377,7 +377,7 @@ The example will write all selected values to the *cuisine* tag separated by sem
```

#### Multiple values using multiple tags
The example will write the three tags *bus*, *tram* & *train*. For unselected options the values will fallback to *no*.
The example will write the three tags *bus*, *tram* & *train*. For unselected options the values will fall back to *no*.
**Explanation:** The `$input` variable will be empty for unselected options. Because `COALESCE` evaluates to the first value/argument it will output *no* in this case. If the fallback value is omitted then the expression will evaluate to `null` which means that the tag won't be written.
```jsonc
"answer": {
Expand Down Expand Up @@ -413,7 +413,7 @@ The example will write the three tags *bus*, *tram* & *train*. For unselected op
#### Using expressions to convert centimeters to meters
The example makes use of the 3 expressions PAD, INSERT and REPLACE to convert from centimeters to meters. The REPLACE expression is only used to remove any pending zeros (and potentially the decimal point). Note that this expression combination only works for positive integers (not for negative or decimal numbers) and does a conversion by exactly two decimal places to the left.

**Explanation:** The expressions evaluate from the inner most to the outer most as shown in the table below.
**Explanation:** The expressions evaluate from the innermost to the outermost as shown in the table below.

| $input | PAD | INSERT | REPLACE |
| ------ | ----- | ------ | ------- |
Expand Down Expand Up @@ -528,7 +528,7 @@ In order to match elements that have or don't have a certain key one can set the
- `"some_osm_key": true` means that the element must have a tag with the key `some_osm_key` while its **value can be anything**.
- `"some_osm_key": false` means that the element **must not** have a tag with the key `some_osm_key`.

To match against multiple values of the same key one could write multiple conditions. However this will often result in a lot of repetitive code wherefore a shorthand array notation exists:
To match against multiple values of the same key one could write multiple conditions. However, this will often result in a lot of repetitive code wherefore a shorthand array notation exists:
`highway": ["motorway ", "trunk", "primary"]` The previous example will match any elements that contain the key `highway` with a value of either `motorway`, `trunk` or `primary`. You can also use `true`, `false` and regular expressions in this notation.

For more complex tag matching scenarios **Regular expressions** can be used. They are written as normal strings enclosed by slashes (`/`) and use Dart's regular expression syntax and semantics, which is the same as for [JavaScript regular expressions](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions).
Expand All @@ -537,7 +537,7 @@ Example use cases are:
- matching a tag that contains certain value `/INCLUDED_VALUE/`.
- matching a tag that contains a certain value between a separator string (e.g. semicolon) `/(^|^.+;)LIST_VALUE(;.+$|$)/`.

Currently setting regex flags is not supported. All of them are turned off except for the *match case sensitive* flag.
Currently, setting regex flags is not supported. All of them are turned off except for the *match case-sensitive* flag.

**Notation summary:**

Expand All @@ -562,7 +562,7 @@ This defines the element type or types the element must have in order to evaluat

Possible types are: `Node`, `OpenWay`, `ClosedWay` and `Relation`

In contrast to the standard OSM element types, way is split into two sub-types to distinguish between area/boundary and path/segment elements.
In contrast to the standard OSM element types, way is split into two subtypes to distinguish between area/boundary and path/segment elements.

### `child` condition

Expand Down
4 changes: 2 additions & 2 deletions docs/WORKING_PRINCIPLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
# Working Principle

The app aims to contribute OSM data via surveys and shall be used on-site. It is designed to be simple and usable without much prior knowledge.
The app does **not** try to be a full featured editor for complex mapping scenarios like JOSM, ID or Vespucci by any means.
The app does **not** try to be a full-featured editor for complex mapping scenarios like JOSM, ID or Vespucci by any means.

## Core principles:
- The app only ever adds tags or elements and never deletes anything.
- Changes must be uploaded via a personal OSM user account and users authorize/login via OAuth2.
- Users never enter any tags directly, instead the app phrases questions and transforms the answers into OSM tags (similar to [StreetComplete](https://github.com/streetcomplete/StreetComplete)).

## Target Elements:
The app focuses on public transport related OSM elements. Therefore we first gather all nearby stops via the [Overpass API](https://wiki.openstreetmap.org/wiki/Overpass_API). Based on these stops we generate "stop areas", which are basically just circles enclosing one or more nearby stops with a minimal predefined radius. These make up the areas where we are looking for OSM elements via the [OSM API](https://wiki.openstreetmap.org/wiki/API_v0.6#Bounding_box_computation). Our main focus lies on elements with the key `public_transport=platform`. Some further relevant elements are: footways, steps, parking areas or toilets around the stop.
The app focuses on public transport related OSM elements. Therefore, we first gather all nearby stops via the [Overpass API](https://wiki.openstreetmap.org/wiki/Overpass_API). Based on these stops we generate "stop areas", which are basically just circles enclosing one or more nearby stops with a minimal predefined radius. These make up the areas where we are looking for OSM elements via the [OSM API](https://wiki.openstreetmap.org/wiki/API_v0.6#Bounding_box_computation). Our main focus lies on elements with the key `public_transport=platform`. Some further relevant elements are: footways, steps, parking areas or toilets around the stop.

## Matching:

Expand Down
2 changes: 0 additions & 2 deletions ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,5 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>13.0</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
platform :ios, '13.0'
platform :ios, '15.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down
45 changes: 3 additions & 42 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,21 @@ PODS:
- compassx (0.0.1):
- Flutter
- Flutter (1.0.0)
- flutter_secure_storage_darwin (10.0.0):
- Flutter
- FlutterMacOS
- flutter_web_auth_2 (3.0.0):
- Flutter
- geolocator_apple (1.2.0):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- url_launcher_ios (0.0.1):
- Flutter

DEPENDENCIES:
- compassx (from `.symlinks/plugins/compassx/ios`)
- Flutter (from `Flutter`)
- flutter_secure_storage_darwin (from `.symlinks/plugins/flutter_secure_storage_darwin/darwin`)
- flutter_web_auth_2 (from `.symlinks/plugins/flutter_web_auth_2/ios`)
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)

EXTERNAL SOURCES:
compassx:
:path: ".symlinks/plugins/compassx/ios"
Flutter:
:path: Flutter
flutter_secure_storage_darwin:
:path: ".symlinks/plugins/flutter_secure_storage_darwin/darwin"
flutter_web_auth_2:
:path: ".symlinks/plugins/flutter_web_auth_2/ios"
geolocator_apple:
:path: ".symlinks/plugins/geolocator_apple/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"

SPEC CHECKSUMS:
compassx: 2d291f8c8e5672f35c62277f2318ef48359dc1d0
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_secure_storage_darwin: ce237a8775b39723566dc72571190a3769d70468
flutter_web_auth_2: 5c8d9dcd7848b5a9efb086d24e7a9adcae979c80
geolocator_apple: 1560c3c875af2a412242c7a923e15d0d401966ff
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
Flutter: 71a624a5bc0c04062bf19101d501e466baf2fb47

PODFILE CHECKSUM: 0e7df49a070ca6a0600383e3ff3158cb74cc9dbf
PODFILE CHECKSUM: e9fda76361f7b869a3fa74d0e691906ebc6ead57

COCOAPODS: 1.16.2
COCOAPODS: 1.17.0
28 changes: 25 additions & 3 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
Expand Down Expand Up @@ -50,13 +51,15 @@
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
C0C3EFFB315866C9D5691CD7 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E92325C28327D7C47838E558 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */,
89C6123D110CC5300270504C /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -75,6 +78,7 @@
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
Expand Down Expand Up @@ -133,6 +137,9 @@

/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
packageProductDependencies = (
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,
);
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
Expand All @@ -158,6 +165,9 @@

/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,
);
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1510;
Expand Down Expand Up @@ -349,7 +359,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand Down Expand Up @@ -439,7 +449,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -489,7 +499,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand Down Expand Up @@ -590,6 +600,18 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCLocalSwiftPackageReference section */
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
};
/* End XCLocalSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = {
isa = XCSwiftPackageProductDependency;
productName = FlutterGeneratedPluginSwiftPackage;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
Loading
Loading