the marble (map) replacement dilemma

Lubomir I. Ivanov neolit123 at gmail.com
Sun Jul 9 14:25:38 PDT 2017


after investigating and testing map solutions for a week, which are
potential candidates for replacing our Marble globe map, i will write
down a short review with pros and cons of two proposed solutions. i
will leave it to the actual diver users and the mailing list to
discuss their preferred pick. both solutions can be implemented in
Subsurface and i have working demos with Qt 5.9 on Windows.

NOTE: i've tried the Qt Location and it *does* support satellite
imagery. you can see a demo animated GIF of an application in action
here (wait for it to load - 12MB):
https://media.giphy.com/media/xUOrwolV8iQIAu44vK/giphy.gif

TL;DR:
you can pick between Google Maps and Qt Location

--------------------------------------------

SOLUTION 1 - Google Maps

IMPLEMENTATION
we can just create a webview widget (e.g. QWebView) in our Subsurface
MainWindow which loads a HTML page and some JavaScript. we cannot pass
Qt models to the Google Maps JS API so functions need to be called
explicitly from C++, like addDiveMarker(), removeDiveMarker(),
updateDiverMarkers() etc.

PROS:
a) with QWebKit this is *very easy* to maintain in terms of C++ / JS
communication.
it's just too easy...

b) stable, mature API
i.e. the whole world uses it

c) marker cluster support:
https://developers.google.com/maps/documentation/javascript/marker-clustering
the clusters will add a nice visual touch and stats can be drown from
these when the user clicks a cluster

d) street view support
while on a dive trip one can just enable street view and check how a
certain location looks from the ground while running Subsurface. this
is a very nice feature.

CONS:
a) bound to QWebKit or another browser engine (e.g. QWebEngine)
we already use a browser engine for viewing the documentation locally
and for printing, so this dependency will not be new to the project.
given we are stuck with QWebKit at the moment, the transition to
QWebEngine in terms of google maps should not be too steep.

b) no offline support (!!!)
the viewport just breaks without an internet connection, even if
everything is persistently cached locally. it starts making some
tokenized viewport requests that are meaningless without an internet
connection. maybe a google maps expert and/or a JavaScript hacker can
solve this, but i cannot do that.

c) AFAIK Google Maps is a "closed source" API
it's JS so it's not really closed source, but one cannot send patches to Google

d) slower performance wise than SOLUTION 2
from my tests...

--------------------------------------------

SOLUTION 2 - Qt Location

IMPLEMENTATION
a QQuickWidget needs to placed inside the MainWindow. this widget will
have to load a QML file which on it's own depends on a "Map Provider"
plugin (the above GIF demo app uses the ESRI plugin) and certain
classes from Qt Location. communication between the QML side and C++
can be done with signals and slots. a QML or a C++ based model has to
be used for displaying the markers.

PROS:
a) faster than SOLUTION 1
uses OpenGL. but of course, the QQuickItem performance cannot be
compared to a homebrew OpenGL solution which will be much faster. for
me the above demoed QQuickWidget starts to halt at 12FPS near 16,000
markers and melt with something like 32,000 markers.

b) open-source
contributions can be sent to the Qt project and Qt Location team

c) offline-caching is supported!
i've tried this without an internet connection and it just does it *by
default*. it writes the cache in a weird location on Windows, though.
TMK the location can be made custom for the ESRI plugin.

CONS:
a) weird, possibly buggy and undocumented API
i'm looking at this:
http://doc.qt.io/qt-5/qml-qtlocation-mapitemview.html
this class accepts a QAbstractItemModel which i've tried writing in
C++ and passing it to QML but the MapItemView would not accept it and
create markers from it. maybe i'm missing something (e.g. no actual
example for this in the docs).

the only solution which works for now is to define the model in QML
and expose some functions that can be called from C++ to control the
model.

b) no "street view" and "marker clusters"
these are fancy features of GoggleMaps. we can eventually get cluster
support made by us or the Qt Location team, but these are not that
easy given how the QML map handles markers - the Model / View approach
for MapItemView is just not very flexible here IMO. "street view" is
out of the question due to the big complexity.

c) instead of marker clusters stats, one needs to implement stats in
the lines of:
"create stats for all visible dives in the viewport".
see what happens when i click the "stats" button in the demo GIF.

d) Qt Location is a relatively new technology
not much to say here. we just need to test it on all Desktop platforms

e) complicated deployment of projects that include QML
i'm not sure about Linux or OSX, but deploying Qt C++ applications
with QML widgets isn't exactly easy on Windows. there is a tool that
supposedly makes that easy, but it still misses a lot of files and one
has to go into the Qt directory and manually search for the files his
project needs.

--------------------------------------------

lubomir
--


More information about the subsurface mailing list