Skip to content
moving-bits edited this page May 25, 2024 · 12 revisions

Welcome to UnifiedMap

Welcome to our all-new map implementation, internally called "UnifiedMap". This is the result of nearly two years' work from the c:geo team for an all-new map implementation. The reason we started this was that our old map implementations got increasingly hard to maintain and to keep (more or less) in sync feature-wise, with some code parts being ten years old (or more).

With UnifiedMap we tried to get the same user experience across all different map types (where possible), while modernizing and unifying the internal architecture.

UnifiedMap basically offers (nearly) all the features our old map implementations have, but gives you a couple of additional features:

  • Map rotation for OpenStreetMap based maps (online and offline)
  • Fractional scaling for OpenStreetMap based maps
  • Cluster popup for Google Maps
  • Hide map sources you don't need
  • Elevation chart for routes and tracks (tap on route)
  • Switch between lists directly from map (or by long-tapping on map icon)
  • "driving mode" for OpenStreetMap based maps (enable "follow me" and "map auto rotation" to see more of what lays ahead of you)

UnifiedMap has reached beta state by now, thus we decided to make it our default map for all nightly users, and make it available to all of our users easily.

Everything should work (see next section, "known issues"), but there still may be (and will be) some bugs. In case of need you may switch between old and new map implementations (see settings - map sources), but we would really like you to try the new one. Please report any bugs you find on support (support@cgeo.org) or c:geo on GitHub. Every feedback is welcome!

If you are interested in some background for this project and/or some technical details, please continue reading, otherwise you can just start using the new UnifiedMap.

Known issues

There are a couple of issues, either bugs we already know of, or some missing features we would like to implement at a later time. One issue is actually keeping us from setting UnifiedMap as the new default map currently, which is issue #15460. We are working hard on it, but don't have a solution for it yet.

For further details, have a look at the project for UnifiedMap.


Background and technical information

Intention

Currently we have two map implementations, one for Google Maps v2, and one supporting different flavors of offline and online Mapsforge Maps (bitmap and vector-based). The code base and architecture is very different, which makes maintaining the code difficult, cumbersome and error-prone. Functionality differs in little details, even in places, where it is not given by the map library, but by implementation details only.

UnifiedMap, started around spring of 2022, intends to unify both map architectures into one, tries to reuse as much business code across both maps as possible, and making it as feature-parallel as possible. This includes map rotation for OSM maps as well as multiple marker selection for Google Maps, two of the more commonly missed features respectively.

One important technical change that comes with UnifiedMap is for OSM maps: c:geo's NewMap uses the most recent version of Mapsforge, which is a bitmap-based mapping library - everything has to be transformed into a bitmap, no rotation support available, lots of cache handling to be considered, not making use of modern GPU chips in mobile devices etc. In contrast to this, UnifiedMap switches to Mapsforge VTM, a vector-based library using OpenGL, supporting rotation and fractional zooming, leading to a more responsive and user-friendly appearance on today's devices.

Overview

As of December 2023, there has been quite some progress, despite the rather large task (and rather small amount of available time). UnifiedMap has reached beta state.

Implementation state?

UnifiedMap is feature-complete compared to the old map. There is one notable exception, though: There seems to be no support for hill shading on rotatable OpenStreetMap-based maps. We'll keep our eyes open.

Besides lot of internal technical improvements, there are some cool new features as well, exclusively for UnifiedMap:

  • Map rotation for OpenStreetMap based maps (online and offline)
  • Fractional scaling for OpenStreetMap based maps
  • Cluster popup for Google Maps
  • Hide map sources you don't need
  • Elevation chart for routes and tracks (tap on route)
  • Long tap context menu for routes and tracks
  • Switch between lists directly from map (or by long-tapping on map icon)

How to use UnifiedMap?

Both the "old" maps and UnifiedMap are available in c:geo. You can easily switch between the two implementations by going to settings => map sources => UnifiedMap and enable UnifiedMap.

Some technical info:

  • The underlying VTM library supports even more map types than our "old" maps, but for now we will stick with the ones supported by CGeoMap / NewMap.
  • Source is located in unifiedmap folder and subfolders and is mostly independent source-wise from the two older map implementations.

I found a bug?

Well, UnifiedMap has reached beta state, but it still has a couple of smaller bugs, some features may be missing yet, some may do not fully work as expected, and some may be truly buggy.

But you can help us in development, if you report your findings by creating a new issue here on GitHub. Ideally prefix the issue's name with "UnifiedMap:" so it's easier for us to recognize that you are referring to the new map implementation. We will then also attach the colorized label "Map: Unified" and put the issue into our project for UnifiedMap.

In that project you will also find all open bugs already known, so probably take a look there first, if "your" error has been reported already, and add specific details to the existing issue, if applicable. Thanks.

Screenshots

(in different stages of development and in no particular order)

Map rotation for OSM maps

Example for a rotated bitmap Mapsforge map from openstreetmap.org. If you rotate a map created from an offline map file, labels will adjust automatically (e. g. city names always being horizontally).

image

VTM offline maps theme variants

Supports selecting one of the built-in VTM theme variants:

OSMARENDER DEFAULT NEWTRON
image image image

Although VTM uses a new DEFAULT theme, c:geo users are more accustomed to the OSMARENDER variant, so this is what c:geo will keep using as predefined theme variant.

Switching a variant is done using theme options.


Architectural design decisions

Beside lots of technical optimizations we used Unified map as sort of a "architectural playground" when it comes to trying new components and code design patterns. It not only tries to unify mapsforge/VTM and GMap implementation but should also be seen as a challenge to say goodbye to our worst mistakes and to design it to be understandable, maintainable and easily extendable.

Ideas (which might get discarded again if they'll not work out):

  • Using "fragments"
    • mapsforge/VTM and GMap are using different view classes to display the actual map, while other parts of the UI don't need to be recreated just because the map provider did change. To reflect this situation, we decided to wrap all map-provider-specific UI parts into a fragment. The activity layout contains the general UI elements as well as a fragment container which will hold either of the map providers.
  • Decouple data and UI
    • In our old codebase, frontend and backend are tightly coupled together. This can make refactoring and maintaining hard. Therefore, UI code and business logic should be separated cleanly.
  • Observer pattern?
    • Up to now, most of our code can be classified as Call-and-Response Pattern. Means we are explicitly triggering a UI update as soon as the data set changes. In some cases however, it makes sense to rather use data bindings and observe the data via LiveData. Doing it that way, the publisher doesn't need to know where the published data is actually used. WARNING: In practice, it turned out that not everything can be wrapped as LiveData in a useful way, so always decide which exact pattern makes sense in your specific case.

These ideas can be summarized by the MVVM pattern:

MVVM (Model-View-ViewModel) is an architectural pattern commonly used in software development, especially in graphical user interface (GUI) applications. It aims to separate the user interface (View) from the underlying data and business logic (Model) while providing a bridge between them through the ViewModel.

Here's a brief explanation of the three components in MVVM:

  1. Model: The Model represents the data and the business logic of the application. It encapsulates the data structures, entities, and operations related to the application's functionality. The Model is independent of the user interface and does not have direct knowledge of the View or the ViewModel.

  2. View: The View is responsible for displaying the user interface to the user. It captures the visual elements, layout, and interactions that allow users to interact with the application. In MVVM, the View is kept as simple as possible and should have minimal logic, ideally focusing only on the presentation of data and forwarding user input to the ViewModel.

  3. ViewModel: The ViewModel acts as a mediator between the View and the Model. It exposes data and commands that the View needs for display and user interaction, typically in the form of properties and methods. The ViewModel retrieves data from the Model, processes it, and prepares it for presentation in a format suitable for the View. It also handles user input, validates input data, and invokes appropriate operations on the Model.

The key idea behind MVVM is the use of data binding, which establishes a connection between the View and the ViewModel. Changes in the ViewModel are automatically reflected in the View, and user interactions in the View are seamlessly propagated to the ViewModel for processing.

MVVM promotes separation of concerns, testability, and reusability. It allows for independent development and testing of the UI and business logic components, making the codebase more maintainable and scalable.

Clone this wiki locally