Compare commits

..

30 Commits

Author SHA1 Message Date
TiclemFR
db30f70093 Add select path in main activity 2024-08-09 22:05:17 +02:00
clement
f18c396d64 Remove compass and track bearing 2024-07-18 17:38:53 +02:00
clement
647ed86ae1 Test azimuth 2024-07-17 20:02:42 +02:00
clement
9f95c27b0b Test azimuth 2024-07-17 14:48:55 +02:00
clement
f2476ec6cc Correct navigation marker 2024-07-17 14:08:57 +02:00
clement
c718551215 Correct Marker Flag 2024-07-17 12:52:22 +02:00
clement
fd3ecdc255 Add navigation lib and test navigation + TTS for nav 2024-07-16 19:53:24 +02:00
clement
7a8c574454 Upgrade to API 35 2024-07-11 17:30:38 +02:00
clement
f420fc93e9 Undo no volunteer removing code 2024-07-11 17:16:44 +02:00
clement
c7592a97f7 Update implementation 2024-07-11 17:02:54 +02:00
clement
6fddd6f2b1 Update application id 2024-07-11 17:00:51 +02:00
clement
9e37caa4d3 Remove unnecessary elements 2024-07-10 18:28:31 +02:00
clement
b97d209917 Construct uri and launch google maps navigation 2024-07-10 16:18:38 +02:00
clement
49cdd06d5c Display all stop's when selected path 2024-07-10 15:12:31 +02:00
clement
a617a29e75 Add view path list 2024-07-09 19:49:50 +02:00
clement
e096f9ed1c Add verif on path name 2024-07-09 18:50:57 +02:00
clement
116a2a5a4a clean interface and code 2024-07-09 17:59:34 +02:00
clement
26c6061a8f Correct dismiss listener 2024-07-09 17:57:01 +02:00
clement
a744faf0d2 Storing Path name with her stop's 2024-07-09 17:48:08 +02:00
clement
1e7b729e4f Add to form a field to put a name of route and list all markers with coordinate and address 2024-07-09 10:41:43 +02:00
clement
f7a8720669 Add new activity to list actual marker for future edit in a form 2024-07-08 11:20:50 +02:00
clement
eb93531816 Re activate displaying speed and accuracy and get location name with latitude and longitude 2024-07-07 18:28:58 +02:00
TiclemFR
0b288973ca Add another way to get location 2024-07-04 10:06:38 +02:00
TiclemFR
367be18e85 Add Database helper, can save marker in stop table and read it 2024-07-01 15:01:18 +02:00
TiclemFR
998378e9ea Correct Bugs 2024-06-28 19:18:16 +02:00
TiclemFR
c8f310539e Change provider is accuracy is too low 2024-06-27 17:51:48 +02:00
TiclemFR
da5709d5e8 Displaying Speed 2024-06-26 20:31:14 +02:00
TiclemFR
0146559c72 Add button for testing Google Maps 2024-06-22 21:03:00 +02:00
TiclemFR
05e2330958 Display Accuracy and position 2024-06-22 18:12:29 +02:00
TiclemFR
cbd94cb507 Update due to API Change 2024-06-22 09:03:04 +02:00
35 changed files with 1201 additions and 99 deletions

404
.idea/dbnavigator.xml generated Normal file
View File

@@ -0,0 +1,404 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DBNavigator.Project.DatabaseFileManager">
<open-files />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<browser-settings>
<general>
<display-mode value="TABBED" />
<navigation-history-size value="100" />
<show-object-details value="false" />
<enable-sticky-paths value="true" />
</general>
<filters>
<object-type-filter>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="true" />
<object-type name="ROLE" enabled="true" />
<object-type name="PRIVILEGE" enabled="true" />
<object-type name="CHARSET" enabled="true" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED_VIEW" enabled="true" />
<object-type name="NESTED_TABLE" enabled="true" />
<object-type name="COLUMN" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET_TRIGGER" enabled="true" />
<object-type name="DATABASE_TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="true" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
<object-type name="ARGUMENT" enabled="true" />
<object-type name="DIMENSION" enabled="true" />
<object-type name="CLUSTER" enabled="true" />
<object-type name="DBLINK" enabled="true" />
</object-type-filter>
</filters>
<sorting>
<object-type name="COLUMN" sorting-type="NAME" />
<object-type name="FUNCTION" sorting-type="NAME" />
<object-type name="PROCEDURE" sorting-type="NAME" />
<object-type name="ARGUMENT" sorting-type="POSITION" />
<object-type name="TYPE ATTRIBUTE" sorting-type="POSITION" />
</sorting>
<default-editors>
<object-type name="VIEW" editor-type="SELECTION" />
<object-type name="PACKAGE" editor-type="SELECTION" />
<object-type name="TYPE" editor-type="SELECTION" />
</default-editors>
</browser-settings>
<navigation-settings>
<lookup-filters>
<lookup-objects>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="false" />
<object-type name="ROLE" enabled="false" />
<object-type name="PRIVILEGE" enabled="false" />
<object-type name="CHARSET" enabled="false" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED VIEW" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET TRIGGER" enabled="true" />
<object-type name="DATABASE TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="false" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="DIMENSION" enabled="false" />
<object-type name="CLUSTER" enabled="false" />
<object-type name="DBLINK" enabled="true" />
</lookup-objects>
<force-database-load value="false" />
<prompt-connection-selection value="true" />
<prompt-schema-selection value="true" />
</lookup-filters>
</navigation-settings>
<dataset-grid-settings>
<general>
<enable-zooming value="true" />
<enable-column-tooltip value="true" />
</general>
<sorting>
<nulls-first value="true" />
<max-sorting-columns value="4" />
</sorting>
<audit-columns>
<column-names value="" />
<visible value="true" />
<editable value="false" />
</audit-columns>
</dataset-grid-settings>
<dataset-editor-settings>
<text-editor-popup>
<active value="false" />
<active-if-empty value="false" />
<data-length-threshold value="100" />
<popup-delay value="1000" />
</text-editor-popup>
<values-actions-popup>
<show-popup-button value="true" />
<element-count-threshold value="1000" />
<data-length-threshold value="250" />
</values-actions-popup>
<general>
<fetch-block-size value="100" />
<fetch-timeout value="30" />
<trim-whitespaces value="true" />
<convert-empty-strings-to-null value="true" />
<select-content-on-cell-edit value="true" />
<large-value-preview-active value="true" />
</general>
<filters>
<prompt-filter-dialog value="true" />
<default-filter-type value="BASIC" />
</filters>
<qualified-text-editor text-length-threshold="300">
<content-types>
<content-type name="Text" enabled="true" />
<content-type name="Properties" enabled="true" />
<content-type name="XML" enabled="true" />
<content-type name="DTD" enabled="true" />
<content-type name="HTML" enabled="true" />
<content-type name="XHTML" enabled="true" />
<content-type name="Java" enabled="true" />
<content-type name="SQL" enabled="true" />
<content-type name="PL/SQL" enabled="true" />
<content-type name="JSON" enabled="true" />
<content-type name="JSON5" enabled="true" />
<content-type name="Groovy" enabled="true" />
<content-type name="AIDL" enabled="true" />
<content-type name="YAML" enabled="true" />
<content-type name="Manifest" enabled="true" />
</content-types>
</qualified-text-editor>
<record-navigation>
<navigation-target value="VIEWER" />
</record-navigation>
</dataset-editor-settings>
<code-editor-settings>
<general>
<show-object-navigation-gutter value="false" />
<show-spec-declaration-navigation-gutter value="true" />
<enable-spellchecking value="true" />
<enable-reference-spellchecking value="false" />
</general>
<confirmations>
<save-changes value="false" />
<revert-changes value="true" />
<exit-on-changes value="ASK" />
</confirmations>
</code-editor-settings>
<code-completion-settings>
<filters>
<basic-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="false" />
<filter-element type="OBJECT" id="view" selected="false" />
<filter-element type="OBJECT" id="materialized view" selected="false" />
<filter-element type="OBJECT" id="index" selected="false" />
<filter-element type="OBJECT" id="constraint" selected="false" />
<filter-element type="OBJECT" id="trigger" selected="false" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="false" />
<filter-element type="OBJECT" id="procedure" selected="false" />
<filter-element type="OBJECT" id="function" selected="false" />
<filter-element type="OBJECT" id="package" selected="false" />
<filter-element type="OBJECT" id="type" selected="false" />
<filter-element type="OBJECT" id="dimension" selected="false" />
<filter-element type="OBJECT" id="cluster" selected="false" />
<filter-element type="OBJECT" id="dblink" selected="false" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</basic-filter>
<extended-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</extended-filter>
</filters>
<sorting enabled="true">
<sorting-element type="RESERVED_WORD" id="keyword" />
<sorting-element type="RESERVED_WORD" id="datatype" />
<sorting-element type="OBJECT" id="column" />
<sorting-element type="OBJECT" id="table" />
<sorting-element type="OBJECT" id="view" />
<sorting-element type="OBJECT" id="materialized view" />
<sorting-element type="OBJECT" id="index" />
<sorting-element type="OBJECT" id="constraint" />
<sorting-element type="OBJECT" id="trigger" />
<sorting-element type="OBJECT" id="synonym" />
<sorting-element type="OBJECT" id="sequence" />
<sorting-element type="OBJECT" id="procedure" />
<sorting-element type="OBJECT" id="function" />
<sorting-element type="OBJECT" id="package" />
<sorting-element type="OBJECT" id="type" />
<sorting-element type="OBJECT" id="dimension" />
<sorting-element type="OBJECT" id="cluster" />
<sorting-element type="OBJECT" id="dblink" />
<sorting-element type="OBJECT" id="schema" />
<sorting-element type="OBJECT" id="role" />
<sorting-element type="OBJECT" id="user" />
<sorting-element type="RESERVED_WORD" id="function" />
<sorting-element type="RESERVED_WORD" id="parameter" />
</sorting>
<format>
<enforce-code-style-case value="true" />
</format>
</code-completion-settings>
<execution-engine-settings>
<statement-execution>
<fetch-block-size value="100" />
<execution-timeout value="20" />
<debug-execution-timeout value="600" />
<focus-result value="false" />
<prompt-execution value="false" />
</statement-execution>
<script-execution>
<command-line-interfaces />
<execution-timeout value="300" />
</script-execution>
<method-execution>
<execution-timeout value="30" />
<debug-execution-timeout value="600" />
<parameter-history-size value="10" />
</method-execution>
</execution-engine-settings>
<operation-settings>
<transactions>
<uncommitted-changes>
<on-project-close value="ASK" />
<on-disconnect value="ASK" />
<on-autocommit-toggle value="ASK" />
</uncommitted-changes>
<multiple-uncommitted-changes>
<on-commit value="ASK" />
<on-rollback value="ASK" />
</multiple-uncommitted-changes>
</transactions>
<session-browser>
<disconnect-session value="ASK" />
<kill-session value="ASK" />
<reload-on-filter-change value="false" />
</session-browser>
<compiler>
<compile-type value="KEEP" />
<compile-dependencies value="ASK" />
<always-show-controls value="false" />
</compiler>
</operation-settings>
<ddl-file-settings>
<extensions>
<mapping file-type-id="VIEW" extensions="vw" />
<mapping file-type-id="TRIGGER" extensions="trg" />
<mapping file-type-id="PROCEDURE" extensions="prc" />
<mapping file-type-id="FUNCTION" extensions="fnc" />
<mapping file-type-id="PACKAGE" extensions="pkg" />
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
<mapping file-type-id="TYPE" extensions="tpe" />
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
</extensions>
<general>
<lookup-ddl-files value="true" />
<create-ddl-files value="false" />
<synchronize-ddl-files value="true" />
<use-qualified-names value="false" />
<make-scripts-rerunnable value="true" />
</general>
</ddl-file-settings>
<general-settings>
<regional-settings>
<date-format value="MEDIUM" />
<number-format value="UNGROUPED" />
<locale value="SYSTEM_DEFAULT" />
<use-custom-formats value="false" />
</regional-settings>
<environment>
<environment-types>
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
</environment-types>
<visibility-settings>
<connection-tabs value="true" />
<dialog-headers value="true" />
<object-editor-tabs value="true" />
<script-editor-tabs value="false" />
<execution-result-tabs value="true" />
</visibility-settings>
</environment>
</general-settings>
</component>
</project>

View File

@@ -4,7 +4,7 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2024-06-20T09:28:45.422751100Z">
<DropdownSelection timestamp="2024-07-01T11:57:37.460926400Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=y5v4t4fiif555tnb" />

11
.idea/other.xml generated
View File

@@ -179,17 +179,6 @@
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="31" />
<option name="brand" value="samsung" />
<option name="codename" value="q2q" />
<option name="id" value="q2q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Z Fold3" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1768" />
<option name="screenY" value="2208" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />

View File

@@ -1,3 +1,4 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
@@ -5,12 +6,12 @@ plugins {
android {
namespace = "com.example.busroute"
compileSdk = 34
compileSdk = 35
defaultConfig {
applicationId = "com.example.busroute"
minSdk = 24
targetSdk = 34
minSdk = 26
targetSdk = 35
versionCode = 1
versionName = "1.0"
@@ -50,7 +51,6 @@ android {
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
@@ -60,6 +60,7 @@ dependencies {
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
implementation(libs.play.services.location)
implementation(libs.androidx.appcompat)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
@@ -67,6 +68,10 @@ dependencies {
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
implementation("org.osmdroid:osmdroid-android:6.1.18")
implementation("com.google.android.gms:play-services-location:21.2.0")
implementation(libs.osmdroid.android)
implementation(files("./libs/osmbonuspack_6.9.0.aar"))
implementation(libs.commons.lang3)
implementation(libs.gson)
implementation(libs.okhttp)
implementation(libs.play.services.location)
}

Binary file not shown.

View File

@@ -14,8 +14,7 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.BusRoute"
tools:targetApi="31">
android:theme="@style/Theme.BusRoute">
<activity
android:name=".MainActivity"
android:exported="true"
@@ -23,10 +22,19 @@
android:theme="@style/Theme.BusRoute">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ValidateMarker"
android:label="Ajouter une ligne"
android:parentActivityName=".MainActivity"
android:theme="@style/Theme.AppCompat"/>
<activity
android:name=".PathToMaps"
android:label="Charger un trajet"
android:parentActivityName=".MainActivity"
android:theme="@style/Theme.AppCompat"/>
</application>
</manifest>

View File

@@ -0,0 +1,9 @@
package com.example.busroute.DataClass
import org.osmdroid.views.overlay.Marker
data class BusStop(val marker: Marker){
override fun toString(): String {
return "${this.marker.position.latitude} | ${this.marker.position.longitude}\n"
}
}

View File

@@ -0,0 +1,23 @@
package com.example.busroute.DataClass
import com.example.busroute.Database.PathContract
import com.example.busroute.Database.StopContract
import com.google.gson.JsonArray
import com.google.gson.JsonObject
data class ExportPath(val pathName:String, val busStop:ArrayList<Stop>){
fun getJson():JsonObject{
val path = JsonObject()
path.addProperty(PathContract.PathEntry.PATH_NAME, pathName)
val stopList = JsonArray()
busStop.forEach {
val stop = JsonObject()
stop.addProperty(StopContract.StopEntry.LATITUDE, it.latitude)
stop.addProperty(StopContract.StopEntry.LONGITUDE, it.longitude)
stop.addProperty(StopContract.StopEntry.ORDER, it.order)
stopList.add(stop)
}
path.add("stop", stopList)
return path
}
}

View File

@@ -0,0 +1,7 @@
package com.example.busroute.DataClass
data class PathList(val id: Int, val name: String){
override fun toString(): String {
return name
}
}

View File

@@ -0,0 +1,3 @@
package com.example.busroute.DataClass
data class Stop(val latitude:Double, val longitude:Double, val order:Int)

View File

@@ -0,0 +1,27 @@
package com.example.busroute.Database
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
class DbHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(PathContract.SQL_CREATE_ENTRIES)
db.execSQL(StopContract.SQL_CREATE_ENTRIES)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
// This database is only a cache for online data, so its upgrade policy is
// to simply to discard the data and start over
db.execSQL(PathContract.SQL_DELETE_ENTRIES)
db.execSQL(StopContract.SQL_DELETE_ENTRIES)
onCreate(db)
}
override fun onDowngrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
onUpgrade(db, oldVersion, newVersion)
}
companion object {
// If you change the database schema, you must increment the database version.
const val DATABASE_VERSION = 1
const val DATABASE_NAME = "BusRoute.db"
}
}

View File

@@ -0,0 +1,19 @@
package com.example.busroute.Database
import android.provider.BaseColumns
object PathContract {
// Table contents are grouped together in an anonymous object.
object PathEntry : BaseColumns {
const val TABLE_NAME = "path"
const val PATH_NAME = "name"
}
const val SQL_CREATE_ENTRIES =
"CREATE TABLE ${PathEntry.TABLE_NAME} (" +
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
"${PathEntry.PATH_NAME} TEXT"+
")"
const val SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS ${PathEntry.TABLE_NAME}"
}

View File

@@ -0,0 +1,25 @@
package com.example.busroute.Database
import android.provider.BaseColumns
object StopContract {
// Table contents are grouped together in an anonymous object.
object StopEntry : BaseColumns {
const val TABLE_NAME = "stop"
const val LATITUDE = "latitude"
const val LONGITUDE = "longitude"
const val ORDER = "'order'"
const val PATH_ID = "path_id"
}
const val SQL_CREATE_ENTRIES =
"CREATE TABLE ${StopEntry.TABLE_NAME} (" +
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
"${StopEntry.LATITUDE} DOUBLE, "+
"${StopEntry.LONGITUDE} DOUBLE, "+
"${StopEntry.ORDER} INTEGER, "+
"${StopEntry.PATH_ID} INTEGER"+
")"
const val SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS ${StopEntry.TABLE_NAME}"
}

View File

@@ -1,47 +1,56 @@
package com.example.busroute
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.app.AlertDialog
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationManager
import android.net.Uri
import android.os.Bundle
import android.os.Looper
import android.preference.PreferenceManager
import android.util.Log
import android.speech.tts.TextToSpeech
import android.speech.tts.Voice
import android.view.View
import android.view.WindowManager
import android.widget.AdapterView
import android.widget.AdapterView.OnItemSelectedListener
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.Spinner
import android.widget.TextView
import androidx.activity.ComponentActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.gms.location.FusedLocationProviderClient
import com.example.busroute.DataClass.BusStop
import com.example.busroute.DataClass.PathList
import com.example.busroute.Database.DbHelper
import com.example.busroute.Database.PathContract
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import org.osmdroid.api.IMapController
import org.osmdroid.config.Configuration.getInstance
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.Marker
import org.osmdroid.views.overlay.compass.CompassOverlay
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider
import org.osmdroid.views.overlay.gestures.RotationGestureOverlay
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider
import org.osmdroid.views.overlay.mylocation.IMyLocationProvider
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
import java.util.Locale
class MainActivity : ComponentActivity() {
private val REQUEST_PERMISSIONS_REQUEST_CODE = 1
private lateinit var map : MapView
private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var currentLocation: Location
lateinit var locationManager: LocationManager
private var lastBearing = 0.0f
private lateinit var locationManager: LocationManager
private lateinit var mapController: IMapController
private lateinit var locationByGps: Location
private lateinit var locationByNetwork: Location
private lateinit var positionMarker: Marker
private lateinit var locationCallback: LocationCallback
@@ -49,12 +58,23 @@ class MainActivity : ComponentActivity() {
private var latitude = 0.0
private var longitude = 0.0
private var navigationEnable = false
private var busStopList: ArrayList<BusStop> = ArrayList()
@SuppressLint("MissingPermission")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
isLocationPermissionGranted()
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
val dbHelper = DbHelper(this)
val tts = TextToSpeech(this, TextToSpeech.OnInitListener{})
tts.setVoice(Voice("French",
Locale.FRENCH, Voice.QUALITY_HIGH,
Voice.LATENCY_LOW, true, null))
tts.setSpeechRate(0.8f)
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager = getSystemService(LOCATION_SERVICE) as LocationManager
getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this))
setContentView(R.layout.main)
@@ -64,65 +84,201 @@ class MainActivity : ComponentActivity() {
mapController = map.controller
mapController.setZoom(18.0)
val openMapsButton = findViewById<Button>(R.id.open_maps)
val db = dbHelper.readableDatabase
val addMarkButton = findViewById<Button>(R.id.addMark)
addMarkButton.setOnClickListener{
val marker = Marker(map)
marker.position = GeoPoint(latitude, longitude)
marker.title = "MARK BUTTON !!"
marker.title = "Bus Stop " + busStopList.size+1
marker.textLabelFontSize = 10
marker.icon = ContextCompat.getDrawable(this, org.osmdroid.library.R.drawable.moreinfo_arrow)
map.overlays.add(marker)
map.invalidate()
busStopList.add(BusStop(marker))
}
val removeMarkButton = findViewById<Button>(R.id.removeMark)
removeMarkButton.setOnClickListener{
if(busStopList.size < 1){
return@setOnClickListener
}
val marker = busStopList.last()
marker.marker.remove(map)
busStopList.remove(marker)
}
val saveMarkButton = findViewById<Button>(R.id.saveMark)
saveMarkButton.setOnClickListener{
var stringList: ArrayList<String> = ArrayList<String>()
busStopList.forEach {
stringList.add(it.toString())
}
if(busStopList.size < 1){
val alert = AlertDialog.Builder(this).setTitle("Aucun point !").setMessage("Il faut au moins 1 point pour continuer !")
alert.show()
return@setOnClickListener
}
val intent = Intent(saveMarkButton.context, ValidateMarker::class.java)
intent.putExtra(ValidateMarker.MARKERS, stringList)
startActivity(intent)
}
// val loadPathButton = findViewById<Button>(R.id.load_path)
// loadPathButton.setOnClickListener {
// val intent = Intent(loadPathButton.context, PathToMaps::class.java)
// startActivity(intent)
// }
val rotationGestureOverlay = RotationGestureOverlay(map)
rotationGestureOverlay.isEnabled
map.setMultiTouchControls(true)
map.overlays.add(rotationGestureOverlay)
val compassOverlay = CompassOverlay(this, InternalCompassOrientationProvider(this), map)
compassOverlay.enableCompass()
map.overlays.add(compassOverlay)
isLocationPermissionGranted()
val locationClient = LocationServices.getFusedLocationProviderClient(this)
locationRequest = LocationRequest.Builder(Priority.PRIORITY_BALANCED_POWER_ACCURACY,60)
.setWaitForAccurateLocation(true).setMaxUpdateAgeMillis(30).build()
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
locationResult ?: return
for (location in locationResult.locations){
// val compassOverlay = CompassOverlay(this, InternalCompassOrientationProvider(this), map)
// compassOverlay.enableCompass()
// map.overlays.add(compassOverlay)
val locationOverlay =
object : MyLocationNewOverlay(GpsMyLocationProvider(this), map) {
override fun onLocationChanged(location: Location?, source: IMyLocationProvider?) {
super.onLocationChanged(location!!, source)
if (location.accuracy < 60) {
if (location.provider == LocationManager.NETWORK_PROVIDER) {
location.provider = LocationManager.GPS_PROVIDER
} else {
location.provider = LocationManager.NETWORK_PROVIDER
}
}
currentLocation = location
latitude = location.latitude
longitude = location.longitude
mapController.animateTo(GeoPoint(latitude, longitude))
positionMarker.position = GeoPoint(latitude, longitude)
positionMarker.title = "You"
map.overlays.add(positionMarker)
map.invalidate()
Log.i("Position", "$latitude $longitude")
Log.i("Accuracy Global", "GPS: ${location.accuracy} Network: ${location.accuracy}")
Log.i("Accuracy Chosen", "${location.accuracy}")
if(navigationEnable && currentLocation.hasBearing()){
lastBearing = currentLocation.bearing
mapController.animateTo(GeoPoint(latitude, longitude), null, null, -currentLocation.bearing)
}
else{
//mapController.animateTo(GeoPoint(latitude, longitude))
}
}
}
locationOverlay.enableMyLocation()
locationOverlay.enableFollowLocation()
map.overlays.add(locationOverlay)
val roadButton = findViewById<Button>(R.id.road)
roadButton.setOnClickListener {
navigationEnable = true
tts.speak("Début de l'itinéraire", TextToSpeech.QUEUE_FLUSH, null,"")
RetrieveRoad(map, latitude,longitude, roadButton.context).execute()
}
locationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
val projection = arrayOf("")
val selection = ""
val selectionArgs = arrayOf("")
val sortOrder = ""
val cursor = db.query(
PathContract.PathEntry.TABLE_NAME, // The table to query
null, // The array of columns to return (pass null to get all)
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
)
val items = ArrayList<PathList>()
items.add(PathList(0,"SELECT PATH"))
with(cursor) {
while (moveToNext()) {
val name = getString(getColumnIndexOrThrow(com.example.busroute.Database.PathContract.PathEntry.PATH_NAME))
val id = getInt(getColumnIndexOrThrow(android.provider.BaseColumns._ID))
val path = PathList(id, name)
items.add(path)
}
}
cursor.close()
val comboPath = findViewById<Spinner>(R.id.combo_path)
comboPath.adapter = ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item, items)
comboPath.onItemSelectedListener = object : OnItemSelectedListener {
override fun onItemSelected(
parentView: AdapterView<*>?,
selectedItemView: View,
position: Int,
id: Long
) {
val iter = busStopList.iterator()
while(iter.hasNext()) {
iter.next().marker.remove(map)
iter.remove()
}
if(position < 1){
addMarkButton.isEnabled = true
return
}
addMarkButton.isEnabled = false
val selectedPath = parentView!!.selectedItem
if(selectedPath != null){
val cursor = db.rawQuery("SELECT * " +
"FROM stop " +
"WHERE path_id = ${(selectedPath as PathList).id} " +
"ORDER BY 'order' ",
arrayOf()
)
with(cursor) {
while (moveToNext()) {
val latitude = getDouble(getColumnIndexOrThrow(com.example.busroute.Database.StopContract.StopEntry.LATITUDE))
val longitude = getDouble(getColumnIndexOrThrow(com.example.busroute.Database.StopContract.StopEntry.LONGITUDE))
val text = TextView(comboPath.context)
val marker = Marker(map)
marker.position = GeoPoint(latitude, longitude)
marker.title = "Bus Stop " + busStopList.size+1
marker.textLabelFontSize = 10
marker.icon = ContextCompat.getDrawable(baseContext, org.osmdroid.library.R.drawable.moreinfo_arrow)
map.overlays.add(marker)
map.invalidate()
busStopList.add(BusStop(marker))
}
}
}
}
override fun onNothingSelected(parentView: AdapterView<*>?) {
// your code here
}
}
openMapsButton.setOnClickListener {
val lastPoint = busStopList.last().marker
var uri = "google.navigation:q=${lastPoint.position.latitude},${lastPoint.position.longitude}&waypoints="
busStopList.forEach {
if(busStopList.indexOf(it) < busStopList.size -1){
val position = it.marker.position
uri += "${position.latitude},${position.longitude}"
if(busStopList.indexOf(it) < busStopList.size -2){
uri += "%7C"
}
}
}
db.close()
val mapIntentUri = Uri.parse(uri)
val mapIntent = Intent(Intent.ACTION_VIEW, mapIntentUri)
mapIntent.setPackage("com.google.android.apps.maps")
startActivity(mapIntent)
}
}
private fun isLocationPermissionGranted(): Boolean {
return if (ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_COARSE_LOCATION
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_FINE_LOCATION
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
),
1
)
@@ -151,7 +307,7 @@ class MainActivity : ComponentActivity() {
map.onPause() //needed for compass, my location overlays, v6.0.0 and up
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
val permissionsToRequest = ArrayList<String>()
var i = 0
@@ -166,22 +322,4 @@ class MainActivity : ComponentActivity() {
REQUEST_PERMISSIONS_REQUEST_CODE)
}
}
/*private fun requestPermissionsIfNecessary(String[] permissions) {
val permissionsToRequest = ArrayList<String>();
permissions.forEach { permission ->
if (ContextCompat.checkSelfPermission(this, permission)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
permissionsToRequest.add(permission);
}
}
if (permissionsToRequest.size() > 0) {
ActivityCompat.requestPermissions(
this,
permissionsToRequest.toArray(new String[0]),
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}*/
}

View File

@@ -0,0 +1,143 @@
package com.example.busroute
import android.content.Intent
import android.location.Address
import android.location.Geocoder
import android.net.Uri
import android.os.Bundle
import android.provider.BaseColumns
import android.view.View
import android.widget.AdapterView
import android.widget.AdapterView.OnItemSelectedListener
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.Spinner
import android.widget.TableLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.example.busroute.DataClass.ExportPath
import com.example.busroute.DataClass.PathList
import com.example.busroute.DataClass.Stop
import com.example.busroute.Database.DbHelper
import com.example.busroute.Database.PathContract
import com.example.busroute.Database.StopContract
import com.google.gson.JsonArray
import java.util.Locale
class PathToMaps: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val dbHelper = DbHelper(this)
val db = dbHelper.readableDatabase
val geocoder = Geocoder(this, Locale.getDefault())
val StopPoint = ArrayList<String>()
setContentView(R.layout.select_path)
val projection = arrayOf("")
val selection = ""
val selectionArgs = arrayOf("")
val sortOrder = ""
val cursor = db.query(
PathContract.PathEntry.TABLE_NAME, // The table to query
null, // The array of columns to return (pass null to get all)
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
)
val items = ArrayList<PathList>()
with(cursor) {
while (moveToNext()) {
val name = getString(getColumnIndexOrThrow(PathContract.PathEntry.PATH_NAME))
val id = getInt(getColumnIndexOrThrow(BaseColumns._ID))
val path = PathList(id, name)
items.add(path)
}
}
cursor.close()
val stopTable = findViewById<TableLayout>(R.id.stop_table)
val comboPath = findViewById<Spinner>(R.id.combo_path)
comboPath.adapter = ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item, items)
comboPath.onItemSelectedListener = object : OnItemSelectedListener {
override fun onItemSelected(
parentView: AdapterView<*>?,
selectedItemView: View,
position: Int,
id: Long
) {
stopTable.removeAllViews()
StopPoint.clear()
val selectedPath = parentView!!.selectedItem
if(selectedPath != null){
val cursor = db.rawQuery("SELECT * " +
"FROM stop " +
"WHERE path_id = ${(selectedPath as PathList).id} " +
"ORDER BY 'order' ",
arrayOf()
)
with(cursor) {
while (moveToNext()) {
val latitude = getDouble(getColumnIndexOrThrow(StopContract.StopEntry.LATITUDE))
val longitude = getDouble(getColumnIndexOrThrow(StopContract.StopEntry.LONGITUDE))
val text = TextView(comboPath.context)
val geoResults: MutableList<Address>? = geocoder.getFromLocation(latitude, longitude, 1)
text.text = "$latitude | $longitude\r${geoResults?.get(0)?.getAddressLine(0)}\n"
stopTable.addView(text)
StopPoint.add("$latitude|$longitude")
}
}
}
}
override fun onNothingSelected(parentView: AdapterView<*>?) {
// your code here
}
}
val openMapsButton = findViewById<Button>(R.id.open_maps)
openMapsButton.setOnClickListener {
val lastPoint = StopPoint.last().split("|")
var uri = "google.navigation:q=${lastPoint[0]},${lastPoint[1]}&waypoints="
StopPoint.forEach {
if(StopPoint.indexOf(it) < StopPoint.size -1){
val position = it.split("|")
uri += "${position[0]},${position[1]}"
if(StopPoint.indexOf(it) < StopPoint.size -2){
uri += "%7C"
}
}
}
db.close()
val mapIntentUri = Uri.parse(uri)
val mapIntent = Intent(Intent.ACTION_VIEW, mapIntentUri)
mapIntent.setPackage("com.google.android.apps.maps")
startActivity(mapIntent)
}
val exportJsonButton = findViewById<Button>(R.id.export_json)
exportJsonButton.setOnClickListener {
val exportList = JsonArray()
val busStopList = ArrayList<Stop>()
items.forEach {
val cursor = db.rawQuery("SELECT * " +
"FROM stop " +
"WHERE path_id = ${it.id} " +
"ORDER BY 'order' ",
arrayOf()
)
with(cursor) {
while (moveToNext()) {
val latitude = getDouble(getColumnIndexOrThrow(StopContract.StopEntry.LATITUDE))
val longitude = getDouble(getColumnIndexOrThrow(StopContract.StopEntry.LONGITUDE))
val order = getInt(getColumnIndexOrThrow("order"))
busStopList.add(Stop(latitude, longitude, order))
}
}
exportList.add(ExportPath(it.name, busStopList).getJson())
}
}
}
}

View File

@@ -0,0 +1,81 @@
package com.example.busroute
import android.R
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.drawable.Drawable
import android.os.AsyncTask
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import org.osmdroid.bonuspack.routing.OSRMRoadManager
import org.osmdroid.bonuspack.routing.Road
import org.osmdroid.bonuspack.routing.RoadManager
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.Marker
@SuppressLint("StaticFieldLeak")
class RetrieveRoad(private var map: MapView,
private var latitude: Double,
private var longitude: Double,
private var context: Context
) :
AsyncTask<String, Void, Void>() {
val icons = HashMap<Int, Int>()
private fun setIcons(){
icons.put(1,com.example.busroute.R.drawable.ic_continue)
icons.put(2,com.example.busroute.R.drawable.ic_continue)
icons.put(6,com.example.busroute.R.drawable.ic_slight_right)
icons.put(7,com.example.busroute.R.drawable.ic_turn_right)
icons.put(8,com.example.busroute.R.drawable.ic_sharp_right)
icons.put(12,com.example.busroute.R.drawable.ic_u_turn)
icons.put(5,com.example.busroute.R.drawable.ic_sharp_left)
icons.put(4,com.example.busroute.R.drawable.ic_turn_left)
icons.put(3,com.example.busroute.R.drawable.ic_slight_left)
icons.put(24,com.example.busroute.R.drawable.ic_arrived)
icons.put(27,com.example.busroute.R.drawable.ic_roundabout)
icons.put(28,com.example.busroute.R.drawable.ic_roundabout)
icons.put(29,com.example.busroute.R.drawable.ic_roundabout)
icons.put(30,com.example.busroute.R.drawable.ic_roundabout)
icons.put(31,com.example.busroute.R.drawable.ic_roundabout)
icons.put(32,com.example.busroute.R.drawable.ic_roundabout)
icons.put(33,com.example.busroute.R.drawable.ic_roundabout)
icons.put(34,com.example.busroute.R.drawable.ic_roundabout)
}
override fun doInBackground(vararg p0: String): Void? {
this.setIcons()
val roadManager: RoadManager = OSRMRoadManager(context, "me")
val waypoints = ArrayList<GeoPoint>()
waypoints.add(GeoPoint(latitude, longitude))
val middlePoint = GeoPoint(45.59, 6.45)
waypoints.add(middlePoint)
val endPoint = GeoPoint(45.48, 6.52)
waypoints.add(endPoint)
val road = roadManager.getRoad(waypoints)
val roadOverlay = RoadManager.buildRoadOverlay(road, Color.Blue.toArgb(), 20f)
roadOverlay.width = 15f
map.overlays.add(roadOverlay)
map.invalidate()
val nodeIcon: Drawable? = context.getDrawable(com.example.busroute.R.drawable.marker_node)
for (i in road.mNodes.indices) {
val node = road.mNodes[i]
val nodeMarker = Marker(map)
nodeMarker.position = node.mLocation
nodeMarker.icon = nodeIcon
nodeMarker.title = "Step $i"
nodeMarker.snippet = node.mInstructions
nodeMarker.subDescription = Road.getLengthDurationText(context, node.mLength, node.mDuration)
var id: Int? = icons.get(node.mManeuverType)
if (id == null){
id = icons.get(1)
}
val icon: Drawable? = context.getDrawable(id!!)
nodeMarker.image = icon
map.overlays.add(nodeMarker)
}
return null
}
}

View File

@@ -0,0 +1,87 @@
package com.example.busroute
import android.app.AlertDialog
import android.content.ContentValues
import android.location.Address
import android.location.Geocoder
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TableLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.example.busroute.Database.DbHelper
import com.example.busroute.Database.PathContract
import com.example.busroute.Database.StopContract
import java.util.ArrayList
import java.util.Locale
class ValidateMarker: AppCompatActivity() {
companion object{
const val MARKERS = "MARKERS"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val geocoder = Geocoder(this, Locale.getDefault())
val dbHelper = DbHelper(this)
setContentView(R.layout.marker_form)
val table = findViewById<TableLayout>(R.id.table)
val markers: ArrayList<String>? = intent.extras?.getStringArrayList(MARKERS)
markers!!.forEach{
val latitude = it.split(" | ")[0].toDouble()
val longitude = it.split(" | ")[1].toDouble()
val geoResults: MutableList<Address>? = geocoder.getFromLocation(latitude, longitude, 1)
lateinit var address:String
if (geoResults != null) {
if(geoResults.size > 0){
address = geoResults[0].getAddressLine(0)
}
}
val text = TextView(this)
var newText = it
if(!address.isNullOrEmpty()){
newText += "\r${address}\n"
}
text.text = newText
table.addView(text)
}
val validateButton = findViewById<Button>(R.id.validate_form)
validateButton.setOnClickListener{
val newName = findViewById<EditText>(R.id.route_name).text.toString()
if(newName.isBlank() or newName.isEmpty()){
val alert = AlertDialog.Builder(this).setTitle("Nom vide !")
.setMessage("Le nom du trajet est vide !")
alert.show()
return@setOnClickListener
}
val db = dbHelper.writableDatabase
val newPath = ContentValues().apply {
put(PathContract.PathEntry.PATH_NAME, newName)
}
val newPathRowId = db?.insert(PathContract.PathEntry.TABLE_NAME, null, newPath)
if(newPathRowId?.toInt() != -1){
markers.forEach {
val values = ContentValues().apply {
put(StopContract.StopEntry.LATITUDE, it.split(" | ")[0].toDouble())
put(StopContract.StopEntry.LONGITUDE, it.split(" | ")[1].toDouble())
put(StopContract.StopEntry.ORDER, markers.indexOf(it))
put(StopContract.StopEntry.PATH_ID, newPathRowId)
}
val newRowId = db?.insert(StopContract.StopEntry.TABLE_NAME, null, values)
}
val alert = AlertDialog.Builder(this).setTitle("Route sauvegardée")
.setMessage("Le trajet à été créer !").setOnDismissListener{
db.close()
finish()
}
alert.show()
}
}
}
}

View File

@@ -1,6 +1,5 @@
package com.example.busroute.ui.theme
import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

View File

@@ -3,21 +3,76 @@
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
android:layout_height="fill_parent"
android:fitsSystemWindows="true">
<RelativeLayout tools:ignore="UselessParent">
<Button
android:id="@+id/addMark"
android:layout_alignParentRight="true"
android:layout_width="150dp"
android:layout_height="50dp"
<TableLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:textColor="@color/black"
android:overScrollMode="always"
android:clickable="true"
android:text="Add marker" />
android:elevation="600dp">
<Spinner
android:id="@+id/combo_path"
android:background="@color/white"
android:layout_height="35dp">
</Spinner>
</TableLayout>
<TableLayout
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:elevation="500dp">
<Button
android:id="@+id/addMark"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:focusable="true"
android:textColor="@color/black"
android:clickable="true"
android:text="Add marker" />
<Button
android:id="@+id/removeMark"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:focusable="true"
android:textColor="@color/black"
android:clickable="true"
android:text="Remove last marker" />
<Button
android:id="@+id/saveMark"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:focusable="true"
android:textColor="@color/black"
android:clickable="true"
android:text="Save Markers" />
<Button
android:id="@+id/open_maps"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:focusable="true"
android:textColor="@color/black"
android:text="Lancer le trajet dans Maps">
</Button>
<Button
android:id="@+id/road"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/white"
android:focusable="true"
android:textColor="@color/black"
android:clickable="true"
android:text="Test Road Manager" />
</TableLayout>
<org.osmdroid.views.MapView
android:id="@+id/map"
android:elevation="0dp"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<TableLayout
android:layout_width="200dp"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:textStyle="bold"
android:text="Merci de vérifier les informations"/>
<TextView
android:layout_width="wrap_content"
android:layout_marginTop="20dp"
android:text="Entrez un nom pour la ligne (80 caractères max)"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/route_name"
android:maxLength="80"
android:minHeight="50dp"
tools:ignore="SpeakableTextPresentCheck" />
<Button
android:layout_width="wrap_content"
android:id="@+id/validate_form"
android:layout_height="wrap_content"
android:text="Valider"/>
</TableLayout>
<TableLayout
android:id="@+id/table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:padding="16dp" />
</TableLayout>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<Spinner
android:id="@+id/combo_path"
android:minHeight="50dp">
</Spinner>
<Button
android:id="@+id/open_maps"
android:text="Lancer le trajet dans Maps">
</Button>
<Button
android:id="@+id/export_json"
android:text="Exporter tous les trajets">
</Button>
<TableLayout
android:id="@+id/stop_table"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</TableLayout>

View File

@@ -1,5 +1,7 @@
[versions]
agp = "8.5.0"
commonsLang3 = "3.8.1"
gson = "2.11.0"
kotlin = "1.9.0"
coreKtx = "1.13.1"
junit = "4.13.2"
@@ -8,15 +10,21 @@ espressoCore = "3.5.1"
lifecycleRuntimeKtx = "2.8.2"
activityCompose = "1.9.0"
composeBom = "2024.06.00"
okhttp = "4.7.2"
osmbonuspack = "6.9.0"
osmdroidAndroid = "6.1.18"
playServicesLocation = "21.3.0"
appcompat = "1.7.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
commons-lang3 = { module = "org.apache.commons:commons-lang3", version = "3.16.0" }
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version = "1.2.1" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version = "3.6.1" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version = "2.8.4" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version = "1.9.1" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
@@ -25,7 +33,11 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
okhttp = { module = "com.squareup.okhttp3:okhttp", version = "4.12.0" }
osmbonuspack = { module = "com.github.MKergall:osmbonuspack", version.ref = "osmbonuspack" }
osmdroid-android = { module = "org.osmdroid:osmdroid-android", version.ref = "osmdroidAndroid" }
play-services-location = { group = "com.google.android.gms", name = "play-services-location", version.ref = "playServicesLocation" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }

View File

@@ -8,6 +8,9 @@ pluginManagement {
}
}
mavenCentral()
flatDir {
dirs("libs")
}
gradlePluginPortal()
}
}