Skip to content

Commit 475c465

Browse files
committed
feat: OnTrack v2 — complete cross-platform route optimizer
Desktop (Windows/Linux) + Android (Kivy) dual-UI architecture. Core: - geocoder.py: Google geocoding fallback, get_current_location() desktop: IP geolocation via ip-api.com (no key needed) Android: Android GPS via jnius + plyer fallback - solver.py: OR-Tools TSP/VRP (desktop) + nearest-neighbor fallback (Android) - exporter.py: Maps URL, FieldMaps deep link, Street View URL, Waze URL - config/settings.py: load_dotenv() in try/except for Android sandbox Desktop GUI (CustomTkinter): - home.py: address entry, CSV load, location, drag-reorder, background solve - results.py: stop table, Street View panel, Maps/FieldMaps/Waze launch, inline add/delete/reorder, CSV export, re-optimize - settings.py: .env read/write, show/hide API keys, live reload Android (Kivy): - mobile/app.py: ScreenManager, shared state - mobile/screens/{home,results,settings}.py: full mobile UI Build: - ontrack.spec: PyInstaller one-file for Windows/Linux - buildozer.spec: Android APK, arm64+armeabi, minapi=26, plyer GPS - requirements.txt + requirements-android.txt - README.md: full setup + architecture docs
1 parent 87c907f commit 475c465

File tree

21 files changed

+2882
-327
lines changed

21 files changed

+2882
-327
lines changed

ontrack/.env.example

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,14 @@
1-
GOOGLE_MAPS_API_KEY=
2-
OSRM_BASE_URL=http://router.project-osrm.org
1+
# OnTrack — copy this to .env and fill in your values
2+
# The Settings screen in the app will also write/update this file.
3+
4+
# Google Maps Platform API key
5+
# Enable: Geocoding API, Distance Matrix API, Street View Static API, Maps JavaScript API
6+
# https://console.cloud.google.com/google/maps-apis/credentials
7+
GOOGLE_MAPS_API_KEY=""
8+
9+
# OSRM routing server (leave default for free public server)
10+
OSRM_BASE_URL="http://router.project-osrm.org"
11+
12+
# Your ArcGIS Online Web Map item ID (from the map URL in ArcGIS Online)
13+
# Used for ArcGIS FieldMaps deep links — opens the correct map for field technicians
14+
ARCGIS_ITEM_ID=""

ontrack/README.md

Lines changed: 122 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,155 +1,166 @@
1-
<p align="center">
2-
<img src="assets/ontrack.jpg" alt="ONTrack" width="150"/>
3-
</p>
1+
# OnTrack v2 — TDS Telecom Field Route Optimizer
42

5-
<h1 align="center">ONTrack</h1>
6-
7-
<p align="center">
8-
<b>Route Optimizer for Folks in a Hurry</b><br/>
9-
Built with Python · OR-Tools · CustomTkinter
10-
</p>
11-
12-
<p align="center">
13-
<img src="https://img.shields.io/badge/python-3.11+-blue?style=flat-square"/>
14-
<img src="https://img.shields.io/badge/platform-Windows-informational?style=flat-square"/>
15-
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square"/>
16-
<img src="https://img.shields.io/badge/status-active-brightgreen?style=flat-square"/>
17-
<img src="https://img.shields.io/badge/OR--Tools-routing-orange?style=flat-square"/>
18-
<img src="https://img.shields.io/badge/🚧%20WIP-not%20production%20ready-yellow?style=flat-square"/>
19-
</p>
20-
21-
> [!WARNING]
22-
> ONTrack is a **work in progress**. Core routing logic is functional but the GUI, installer, and map preview are still being built out. Not recommended for production field use yet.
3+
Route optimization tool for TDS field service technicians.
4+
Enter addresses manually or load a CSV/Excel file, optimize the drive order, preview each stop in Street View, and launch turn-by-turn navigation in Google Maps or ArcGIS FieldMaps.
235

246
---
257

26-
## What It Does
27-
28-
ONTrack takes a CSV or Excel file of street addresses, geocodes them, builds a real-road distance matrix, and solves the optimal drive order using Google OR-Tools — then exports the route and opens it directly in Google Maps.
8+
## Features
9+
10+
| Feature | Desktop | Android |
11+
|---|---|---|
12+
| Manual address entry |||
13+
| CSV / Excel import |||
14+
| Current location as start | ✓ (IP) | ✓ (GPS) |
15+
| Drag-to-reorder stops || ✓ (delete/add) |
16+
| TSP route optimization | OR-Tools | Nearest-neighbor |
17+
| Distance backend: OSRM |||
18+
| Distance backend: Google | ✓ (key) | ✓ (key) |
19+
| Street View preview | ✓ (key) | ✓ (key) |
20+
| Launch Google Maps |||
21+
| Launch ArcGIS FieldMaps |||
22+
| Launch Waze |||
23+
| Add/remove stops after solve |||
24+
| Re-optimize after edits |||
25+
| CSV export |||
2926

3027
---
3128

32-
## Quick Start
29+
## Setup
3330

34-
> [!NOTE]
35-
> Requires Python 3.11+ and pip. Windows `.exe` build coming soon.
31+
### 1. Copy the example environment file
32+
```bash
33+
cp .env.example .env
34+
```
35+
Edit `.env` and add your Google Maps API key and ArcGIS item ID.
36+
You can also set these values from the **Settings** screen inside the app.
3637

38+
### 2. Install desktop dependencies
3739
```bash
38-
git clone https://github.com/qompassai/python.git
39-
cd python/ontrack
4040
pip install -r requirements.txt
41+
```
42+
43+
### 3. Run on desktop
44+
```bash
4145
python main.py
4246
```
4347

4448
---
4549

46-
## How It Works
50+
## Build — Desktop
51+
52+
### Windows (one-file EXE)
53+
```powershell
54+
pip install pyinstaller
55+
pyinstaller ontrack.spec
56+
# Output: dist/OnTrack.exe
57+
```
4758

48-
| Step | Module | Description |
49-
|------|--------------------|-----------------------------------------------------------|
50-
| 1 | `core/parser.py` | Reads CSV or Excel, extracts address column |
51-
| 2 | `core/geocoder.py` | Geocodes each address to lat/lng via Nominatim or Google |
52-
| 3 | `core/matrix.py` | Builds NxN real-road distance matrix via OSRM |
53-
| 4 | `core/solver.py` | Solves TSP with OR-Tools, returns ordered stop list |
54-
| 5 | `core/exporter.py` | Exports sorted CSV + opens Google Maps deep link |
59+
### Linux x86_64 (one-file binary)
60+
```bash
61+
pip install pyinstaller
62+
pyinstaller ontrack.spec
63+
# Output: dist/OnTrack
64+
```
5565

5666
---
5767

58-
## Configuration
68+
## Build — Android APK
5969

60-
ONTrack works **fully out of the box with no API keys**. All default services are free and open:
70+
**Prerequisites:** Ubuntu/Debian Linux (or WSL2), Java 17, Android SDK/NDK.
6171

62-
| Service | Provider | Key Required |
63-
|--------------|----------------------------|--------------|
64-
| Geocoding | Nominatim (OpenStreetMap) | ❌ None |
65-
| Routing | OSRM public server | ❌ None |
66-
| Map preview | Folium + OpenStreetMap | ❌ None |
67-
| Route export | Google Maps URL | ❌ None |
72+
```bash
73+
pip install buildozer
74+
75+
# First build (downloads Android SDK + NDK — takes 20–40 min)
76+
buildozer android debug
77+
78+
# APK output:
79+
# bin/ontrack-2.0.0-arm64-v8a-debug.apk
80+
```
6881

69-
Optionally drop a `.env` file in the project root to upgrade to Google Maps Platform for better rural accuracy:
82+
> **Note:** OR-Tools has no python-for-android recipe.
83+
> The Android build uses a pure-Python nearest-neighbor solver instead.
84+
> This gives good-quality routes for typical field routes (≤ 30 stops).
7085
86+
### Sign for Play Store
7187
```bash
72-
cp .env.example .env
73-
# Then add your key:
74-
# GOOGLE_MAPS_API_KEY=your_key_here
88+
# Build release AAB
89+
buildozer android release
90+
# Then sign with your keystore and upload to Google Play Console.
7591
```
7692

7793
---
7894

79-
## Roadmap
95+
## API Keys
96+
97+
All keys are optional — the app works without them using free fallbacks.
8098

81-
- [x] Project scaffold and structure
82-
- [x] CSV/Excel parser (`core/parser.py`)
83-
- [x] Geocoder with Nominatim (`core/geocoder.py`)
84-
- [ ] OSRM distance matrix builder
85-
- [ ] OR-Tools TSP solver
86-
- [ ] CustomTkinter GUI
87-
- [ ] Google Maps deep link export
88-
- [ ] PyInstaller `.exe` build
89-
- [ ] Desktop shortcut + icon installer
99+
| Key | Used for | Get it |
100+
|---|---|---|
101+
| `GOOGLE_MAPS_API_KEY` | Street View images, Google geocoding, Google distance matrix | [console.cloud.google.com](https://console.cloud.google.com/google/maps-apis/credentials) |
102+
| `ARCGIS_ITEM_ID` | Opens correct web map in ArcGIS FieldMaps | Your ArcGIS Online map URL |
90103

91104
---
92105

93-
## Project Structure
106+
## Distance Backends
94107

95-
```
96-
ontrack/
97-
├── main.py # Entrypoint
98-
├── ontrack.spec # PyInstaller build spec
99-
├── README.md
100-
├── requirements.txt
101-
102-
├── gui/
103-
│ ├── app.py # CTk root window
104-
│ ├── views/
105-
│ │ ├── home.py # File picker + depot input
106-
│ │ ├── results.py # Route display table
107-
│ │ └── settings.py # API keys + prefs
108-
│ └── components/
109-
│ ├── file_picker.py
110-
│ ├── address_table.py
111-
│ └── map_preview.py
112-
113-
├── core/
114-
│ ├── parser.py # CSV/Excel → address list
115-
│ ├── geocoder.py # Address → lat/lng
116-
│ ├── matrix.py # Distance matrix (OSRM)
117-
│ ├── solver.py # OR-Tools TSP
118-
│ └── exporter.py # CSV + Maps URL
119-
120-
├── assets/
121-
│ ├── ontrack.jpg
122-
│ ├── ontrack.png
123-
│ ├── ontrack.ico
124-
│ └── themes/ontrack.json
125-
126-
├── config/
127-
│ └── settings.py # dotenv API key loader
128-
129-
└── tests/
130-
├── test_parser.py
131-
├── test_geocoder.py
132-
├── test_solver.py
133-
└── sample_addresses.csv
134-
```
108+
| Backend | Requires | Quality |
109+
|---|---|---|
110+
| `osrm` (default) | None (uses public router) | Good — real road distances |
111+
| `google` | `GOOGLE_MAPS_API_KEY` | Best — live traffic aware |
112+
| `haversine` | None | Fast — straight-line only |
135113

136114
---
137115

138-
## Building the Windows `.exe`
116+
## Address File Format
139117

140-
```bash
141-
pyinstaller --onefile --windowed \
142-
--icon=assets/ontrack.ico \
143-
--name="ONTrack" \
144-
--add-data "assets;assets" \
145-
--hidden-import ortools \
146-
main.py
118+
CSV or Excel with a column named `address`:
119+
120+
```csv
121+
address
122+
123 Main St Spokane WA
123+
456 Elm St Coeur d'Alene ID
124+
789 Oak Ave Post Falls ID
147125
```
148126

149-
Output: `dist/ONTrack.exe` — no Python install required on the target machine.
127+
---
128+
129+
## Architecture
130+
131+
```
132+
ontrack/
133+
├── main.py # Entry point — detects desktop vs Android
134+
├── core/
135+
│ ├── parser.py # CSV/Excel → address list
136+
│ ├── geocoder.py # Address → lat/lng (Nominatim or Google)
137+
│ ├── matrix.py # Distance matrix (OSRM / Google / Haversine)
138+
│ ├── solver.py # TSP optimizer (OR-Tools or nearest-neighbor)
139+
│ └── exporter.py # CSV export, Maps URL, FieldMaps URL, Street View URL
140+
├── gui/ # Desktop UI (CustomTkinter)
141+
│ ├── app.py
142+
│ └── views/
143+
│ ├── home.py # Address input + solve
144+
│ ├── results.py # Route table + Street View + map launch
145+
│ └── settings.py # API keys + preferences
146+
├── mobile/ # Android UI (Kivy)
147+
│ ├── app.py
148+
│ └── screens/
149+
│ ├── home.py
150+
│ ├── results.py
151+
│ └── settings.py
152+
├── config/
153+
│ └── settings.py # Env var loader
154+
├── assets/ # Icons, splash
155+
├── buildozer.spec # Android build config
156+
├── ontrack.spec # PyInstaller desktop build config
157+
└── tests/ # pytest test suite
158+
```
150159

151160
---
152161

153-
## License
162+
## TDS Internal Notes
154163

155-
MIT © [Qompass AI](https://github.com/qompassai)
164+
- The app does not transmit any address data to TDS servers. All routing uses OSRM (free, no account) or the technician's own Google Maps API key.
165+
- ArcGIS FieldMaps deep links open the technician's configured web map and search for the stop address.
166+
- For enterprise deployment, set `OSRM_BASE_URL` to a self-hosted OSRM instance on TDS infrastructure for offline-capable routing.

0 commit comments

Comments
 (0)