Qt内でのMapTilerマップの使用
2019年4月23日発行

デスクトップアプリケーションの開発は難しくて退屈だと言われていますが、Qt 5.12を使って、数種類のMapTilerストリートマップを表示するC++/QMLアプリケーションを開発することで、その間違いを証明しましょう。
QtとQtCreatorのインストール
まず、Qt フレームワークと開発ツールをワークスペースにインストールする必要があります。https://www.qt.io/download にアクセスして OpenSource を選択し、お使いのプラットフォーム用のオンラインインストーラーをダウンロードしてください。Qt は Windows、Linux、macOS をサポートしています。
インストーラーを開き、最新のQt CreatorでQt 5.12をインストールします。お使いのプラットフォームに応じて、正しいビルド環境を選択する必要があります。Linux/macOSではGCC、WindowsではMinGWとMSVCのどちらかを選択できます。Microsoftのウェブサイトからビルドツールの一部としてダウンロードできる、ネイティブのMSVC 2017を使うことをお勧めします。macOSではXCodeをインストールします。Linuxでは有効なGCCのインストールが必要です。
また、「Android」のチェックを外し、「Sources and all other submodules」を選択します。インストールを進めます。
Windowsをお使いの方は、Qt 5.12.1以降、このチュートリアルで使用しているMapbox GLプラグインはMinGWでのみ利用可能ですのでご注意ください。
MapTiler地図デモプロジェクトのセットアップ
Qt Creatorのインストールが完了したら、https://github.com/maptiler/maptiler-qml-demo にあるデモ用のリポジトリをcloneまたはzip/tarでダウンロードしてください。
リポジトリを取り出して MaptilerQML.pro
QtCreatorを使用します。Qt Creatorは正しいQt Development Kitを選択するように求めてきますので、Qt 5.12を選択して次に進みます。Qt はプロジェクトを解析し、ビルドファイルを準備します。
プロセスが終了したら、左下の「Run」ボタンを押すだけで、デモアプリケーションを実行できます。デモアプリケーションには3つのタブがあり、それぞれのタブには異なるマップビューアが表示されているはずです。ソースコードを見てみましょう。
C++コード
以下のmain.cppファイルをご覧ください。
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QApplication>
#include <QtWebEngine/QtWebEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
QtWebEngine::initialize();
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
これは、デフォルトの標準的なQML起動コードです。QApplicationを作成する前に、高解像度の画面を使用している人のためにHigh DPI scalingなどの属性を設定する必要があります。
次にQtWebEngineを初期化する必要があります。QtWebEngineは埋め込み式のChromiumブラウザです。これにより、あらゆる種類のWebページをアプリケーション内で直接表示することができます。
コードの最後のブロックは、QMLに関するもので、QMLエンジンを作成し、単一のQMLファイルをロードしています。 main.qml
.最後に、QApplicationのメインループを開始して、C++のコードは終了です。
QMLコード
下の図は、QMLのコードをすべて含んだmain.qmlです。
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.12
import QtWebEngine 1.8
import QtLocation 5.12
import QtPositioning 5.12
Window {
visible: true
width: 640
height: 480
title: qsTr("MapTiler QML demo")
property string hostingKey: "<your MapTiler hosting key>"
TabBar {
id: bar
width: parent.width
TabButton {
text: qsTr("Vector style - MapboxGL")
}
TabButton {
text: qsTr("Raster style - MapboxGL")
}
TabButton {
text: qsTr("Web Browser")
}
}
StackLayout {
width: parent.width
anchors.top: bar.bottom
anchors.bottom: parent.bottom
currentIndex: bar.currentIndex
Item {
id: vectorTab
// Our code for vector tab
}
Item {
id: rasterTab
// Our code for raster tab
}
Item {
id: webBrowserTab
// Our code for webbrowser tab
}
}
}
私たちのコードは、さまざまなQtのインポートから始まります。使用するモジュールをすべてインポートする必要があります。
ウィンドウ
コンポーネントは、アプリケーションのメインウィンドウを定義するものです。すべてのQMLコンポーネントは ウィンドウ
コンポーネントを使用しています。また、ウィンドウを表示させたいので、visibleプロパティをtrueに設定します。
次に、デフォルトのウィンドウサイズとウィンドウタイトルを設定します。次に、MapTiler のホスティングキーを設定する必要があります。ホスティングキーは、MapTilerCloud のアカウントにログインし、MapTilerCloud -> Account -> Keys の順に選択すると見つけることができ、好きなキーを選択することができます。まだ MapTilerCloud のアカウントをお持ちでない場合は、 FREEで新規アカウントを作成してください。
最後に、アプリケーションのレイアウトを定義します。デモアプリケーションは、3つのタブに分かれています。そのため、3つのアイテムを持つTabBarを定義します。TabBarの下にはStackLayoutを定義し、マップを重ねてタブを選択するたびに切り替えられるようにしています。
現在選択されているタブに切り替えるには、StackLayoutのcurrentIndexプロパティをTabBarのcurrentIndexにバインドします。QMLでは、他のコンポーネントをid名で表します。コンポーネントの中にidプロパティを定義するだけで、そのコンポーネントのid名が設定されます。正しく定義されていれば、次のように書くだけでそのコンポーネントのプロパティにアクセスできます。 <component-id>.<property name>
.それがQMLを使う力なのです。
これでようやく、実際に地図を表示することに集中できます。
Qtの位置情報を利用する
ラスター地図を表示したいときもあれば、ベクタースタイルを使いたいときもあります。QtとMapTilerを使えば、もちろんその両方が可能です。そこで、Qt Location モジュールを使ってみましょう。Qt Locationは、ベクター、ラスター、ルート、フィーチャなどの地図をOpenGLでネイティブに描画する機能を備えており、カスタムオーバーレイやコントロールエレメントなどを実装して機能を拡張することができます。Qt Locationモジュールを使うことで、アプリケーション内でQtの能力を最大限に引き出すことができます。
長所
- Qtのネイティブソリューションを使う
- QtのPositioningプラグインと接続してGeoCoding機能に対応可能
- 他のQMLコンポーネントを使用してコントロールやその他の機能を実装することで、シームレスに拡張可能
コンス
- サードパーティ製のプラグインを使用するか、カスタムコネクタを実装する必要があります。
Mapbox GL Pluginのベクタースタイル
ベクタースタイルには、Mapbox GL プラグインを使用します。Map コンポーネントを追加し、MapboxGL プラグインを挿入します。mapboxgl.mapping.additional_style_urls プラグインパラメータに適切な値を渡して、MapTiler スタイルを設定します。下の図は、ベクタータブの最終的なコードです。
Plugin {
id: mapPluginVector
name: "mapboxgl"
PluginParameter {
name: "mapboxgl.mapping.additional_style_urls"
value: "https://maps.tilehosting.com/styles/streets/style.json?key="
+ hostingKey
}
}
Map {
id: mapVector
anchors.fill: parent
plugin: mapPluginVector
zoomLevel: 14
}
さらに詳しく知りたい方は、QML Map Component documentationとQt Location Mapbox GL Plugindocumentation をご覧ください。
Mapbox GL Plugin ラスタタイル
ベクタースタイルが完成したら、次はラスタータイルに移りましょう。ここでもMapbox GL Pluginを使用し、異なるstyle.jsonを使ってラスタータイルを取得します。
Plugin {
id: mapPluginRaster
name: "mapboxgl"
PluginParameter {
name: "mapboxgl.mapping.additional_style_urls"
value: "https://api.maptiler.com/maps/hybrid/style.json?key=" + hostingKey
}
}
Map {
id: mapRaster
anchors.fill: parent
plugin: mapPluginRaster
zoomLevel: 14
}
WebEngineを利用したWebマップブラウザの組み込み
埋め込み式のブラウザビューを使用することもできます。WebEngineViewを設定することで、Chromiumを使用します。設定は、正しいURLをブラウザに渡すだけです。
WebEngineが使用できない場合は、WebEngineとWebViewを入れ替えて、ネイティブプラットフォームのブラウザを使用します。
以下にWebBrowserタブのコードを示します。
WebEngineView {
anchors.fill: parent
url: "https://api.maptiler.com/maps/streets/?key="
+ hostingKey + "#1.22/-0.00000/0.00000"
}
長所
- 最もわかりやすい完全なソリューション
コンス
- Webブラウザを埋め込むと、Qtアプリケーションでは常に大幅なパフォーマンスの低下が発生します。
- 一部のプラットフォームでは、アプリケーションでChromiumを使用できません。しかし、これはWebViewモジュールに切り替えることで解決できます。
- オーバーレイは可能だが、Webブラウザを完全には拡張できない
- デプロイ時には、Chromiumのバイナリをインクルードする必要があり、サイズが大幅に増加します。
結論
ご覧のように、MapTilerがホストするマップを使ったQtアプリケーションの作成は簡単な作業です。ニーズを特定し、ソリューションのための適切なツールを選択することが問題なのです。MapTiler with Qtはそのようなツールを提供し、不要なコードや肥大化したコードに悩まされることはありません。