Portrait of Patrice GADEGBEPatrice GADEGBE

Locwind

Locwind is an application that records named geographic positions, keeps them on the phone and lets the user share them or be guided to them; it is published on Google Play.

Role
Sole author
Period
From December 2022 to June 2025
Status
In service. Published on Google Play, version 1.0.1
Technologies
Flutter, flutter_bloc, sembast, Google Maps
Repositories
Two, including an API that is not connected to the published version
Architecture of LocwindThe Flutter application displays a map and searches for places through Google Maps, and keeps the recorded positions in a local file on the phone.ApplicationFlutter, flutter_blocfive blocs, six routesGoogle Mapsmapand place searchHTTPSLocal filesembast, on the phone
Figure 1. Architecture of the published version. The recorded positions stay in a file on the phone.

Context

Locwind treats a geographic position as an address: a point on the map is given a recipient, a label and notes, after which it can be found again, copied, shared or used as the destination of a route.

It is available on Google Play. The application records points and not journeys. The name under which it appears on the store, which suggests a GPS recorder, therefore promises a little more than it does.

Problem

The position provided by a phone can be several tens of metres away from the actual place, which is enough to designate the wrong house. Tracking the position continuously would moreover have required a broader permission and consumed battery, for a need that comes down to one point.

Answer

The centre of the map rather than the raw position

The recorded position is that of the centre of the map, under a fixed pin, and not the position returned by the phone. The latter only serves to centre the map on opening, after which the user moves the map until the pin designates the right place. An inaccurate position is thus corrected with one gesture.

A location read only once

The application checks that the location service is enabled and that the permission is granted, then requests the position once. It declares neither background location nor a permanent service, so that the question of the battery does not arise.

Storage reduced to one record

The whole list of positions is kept under a single key of a local file, read back then rewritten on every change. This simplicity suits a few dozen points and avoids having any schema to evolve.

Future<List<Address>> _saveAddresses(List<Address> addresses) async {
  final dbPath = await _dbPath;
  final db = await dbFactory.openDatabase(dbPath);
  final store = StoreRef<String, List<Object?>>.main();
  await store.record('addresses').put(db, addresses.map((e) => e.toJson()).toList());
  return addresses;
}

Future<Address> createAddress(Address address) async {
  const uuid = Uuid();
  final addresses = await loadAddresses();
  addresses.add(address.copyWith(id: uuid.v1()));
  await _saveAddresses(addresses);
  return address;
}
Listing 1. Saving the list of positions to the local file.

Sharing produces a text that ends with a Google Maps URL, and each position receives a tag made of its author’s phone number and a rank. Finally, the place search waits one second after the last keystroke before querying the service.

Limits and outlook

A Django API and a sharing model were developed in 2023, then again in 2025: an account, private positions and an access request that the owner approves, starting from the tag. This work stayed on branches that were not merged, and the published version calls no server of mine.

The application moreover exists only in English in its published version, exports positions only as text and has no tests.

Back to the work