Skip to content

Refactor PlaceStore

James Westman requested to merge jwestman/gnome-maps:place-store-rebase into main

Refactored PlaceStore entirely. Replaces !331 (closed).

Geocode.Place Removal

The Place class now inherits directly from GObject rather than Geocode.Place. We weren't using any special functionality from Geocode.Place, just the properties, which don't fit our data model very well now that we store raw OSM tags and compute properties from them. All the properties we still use are implemented with JS accessors and have been converted to camelCase.

Gio.ListStore Migration

PlaceStore now implements Gio.ListStore, the replacement for Gtk.ListStore. While Gtk.ListStore was a table of columns, Gio.ListStore is a list of objects. This means we need to condense all the columns we were using into a single class, which I've called PlaceStoreItem. Two of the columns, PLACE_ICON and NAME, we weren't using anymore anyway. LANGUAGE is no longer necessary because we now store all of a place's translated names. ADDED and PLACE are properties of the new class, with added renamed to updated.

The TYPE column was an enum: RECENT, FAVORITE, CONTACT (no longer used), or RECENT_ROUTE. It has been split into two new fields: the PlaceStoreItem:isFavorite property and the "type" field of a Place's JSON, which encodes whether it is a StoredRoute object or a plain Place object. Storing the concept of favorites separately from the runtime type of a place will allow us to implement favorite routes in the future, and it makes some code cleaner.

PlaceStoreItem also has a viewOrd property, allowing us to sort the place store by last viewed rather than last updated, while still being able to calculate whether a place is stale. The store is no longer actually sorted though, since that would complicate the ListModel logic. UI that needs to sort the list should use a Gtk.SortListModel.

File Format Migration

The place store file is now stored in gnome-maps/places.json instead of maps-places.json. There is a one-time migration, and it is handled by a single function (_migrateFromPre46) rather than including "legacy" logic in several places.

In addition to the changes mentioned in the previous section, the root of the JSON file is now an object, and the array is under the "places" property, allowing us to add more properties in the future. Also, the coordinate lists in stored routes are stored in Encoded Polyline format, which is far more compact. Both a migration version and the current Maps version are stored in the file. All serialization/deserialization code is designed to ignore and preserve unknown properties and places with unknown types, allowing easier forward compatibility moving forward.

OSM Tags

Instead of setting a Place's properties from OSM tags, we now store the raw OSM tags directly in the place. The property getters access the tags on demand. This allows us to store all of a place's translated names and pick from them at runtime, rather than refetching the place if the user's language changes. It also makes serialization and deserialization simpler.

Tags are not migrated from the previous place store properties. Places with no OSM tags are assumed to be stale.

Merge request reports