C
Qt Quick ウルトラライトマップ例
Qt Quick Ultralite で地図を表示するためにMap アイテムを使用する方法を示します。
概要
この例では、Map アイテムを使用してQt Quick Ultralite アプリケーションにマップを表示する方法を示します。
最小マップモード
このモードでは、例題は4つのズームレベル(0から3まで)の地図タイルを提供します。拡大するには
ボタンを選択し、縮小するには
ボタンを選択します。地図を時計回りに回転させるには、どのズームレベルでも
。マップを反時計回りに回転させるには、
ボタンを選択します。また、地図をドラッグしてパンすることもできます。

ユーザー位置デモモード
デモモードは、あらかじめ定義されたルート上で、地図上のユーザーの現在位置の変化をシミュレートします。デモモードを開始するには、
ボタンを選択します。デモモードでは、
と
ボタン以外のボタンは非表示になります。

デモは、地図がズーム・レベル17に拡大された状態で始まります。ユーザーの現在位置を表す
アイコンと、関心地点を表す
アイコンが地図上に配置されます。デモを一時停止するには、
ボタンに変わる
ボタンを選択します。デモを一時停止している間は、マップをドラッグしてパンすることができます。デモを再開するには、
を選択します。デモを停止して最小マップモードに戻るには、
ボタンを選択します。
この例では、ファイルシステムからマップタイルを取得するためにQul::MapTileFetcher を実装しています。ファイルシステムの実装はファイルロードの例から提供されています。マップ・タイルはJPEG フォーマットで、JPEG デコーダーが必要です。JPEGデコーダーの実装はimagedecoderの例で提供されている。詳しくは地図タイルの取得を参照。
この例では、ダミーの位置ソースから位置情報を取得するためにQul::GeoPositionSource を実装している。詳しくは、位置情報の取得を参照のこと。
対象プラットフォーム
デスクトップでサンプルを実行する
このサンプルでは、Qt を使用して画像をデコードするimagedecoderサンプルの JPEG デコーダ実装を使用しています。そのため、このプロジェクトでは、ヘッダーを提供するためにビルド用の開発用 Qt が必要です。
cmake examples/map -DCMAKE_PREFIX_PATH=$HOME/Qt/6.2.4/gcc_64 -DQUL_PLATFORM=Qt -DQul_ROOT=${QUL_ROOT}cmake examples\map -DCMAKE_PREFIX_PATH=C:\Qt\6.2.4\msvc2022_64 -DQUL_COMPILER_NAME=msvc -DQUL_PLATFORM=Qt -DQul_ROOT=%QUL_ROOT%プラットフォームのバックエンドがリンクされているQtのバージョンとのリンクの問題を避けるため、同じバージョンでなければなりません。カスタムビルドプラットフォームの場合は、デスクトッププラットフォームバックエンドをビルドする際に使用したものと同じQtを使用してください。ビルド済みのプラットフォーム・ライブラリの場合は、Qt 6.2.4でなければなりません。
注: MinGW を使用する場合は、コンパイラ名としてgnu を使用し、C:\Qt\6.2.4\mingw_64 をCMAKE_PREFIX_PATH として使用します。
注意 : Linux では、Qt は OpenGL に依存しています。サンプルの設定中にOpenGLが見つからないというエラーが発生した場合は、次のコマンドを使用してインストールできます。
sudo apt install libgl1-mesa-devデバイス上でサンプルを実行する
ターゲット・プラットフォーム上でサンプルを実行するには、FAT32 フォーマットのSD カードが必要です。offline_tiles_provider/ の example ディレクトリにあるtiles/ ディレクトリを、SD カードのルート・ディレクトリにコピーしてください。
ハードウェア要件
アクセラレイティド・イメージコードとアクセラレイティド・ローテーションに対応したデバイスは、優れたパフォーマン ス、高いフレームレート、スムーズなユーザーエクスペリエンスのために不可欠です。
RAM の要件は、マップのサイズによって異なります。画面サイズ 800 x 480 のSTM32F769iデバイス上のフルスクリーンマップは、32 KB のheap とstack メモリを消費します。同じ画面サイズの場合、マップ・タイル画像のキャッシングには 3840 KB のSDRAM が必要です。詳細については、画像キャッシングを参照してください。
地図タイル
この例では、Webメルカトル図法の世界地図タイルを5段階のズームで表示しています。各タイルは256×256ピクセルのJPEG形式の画像です。各ズームレベルのタイル数は、2zoomlevelx2zoomlevelで計算されます。
地図タイルは、offline_tiles_provider/tiles/ ディレクトリの下の example ディレクトリにあります。
地図タイルの取得(技術プレビュー)
この例ではオフラインの外部ストレージからマップ・タイルを取得します。
OfflineTileFetcher クラス
OfflineTileFetcher クラスはQul::MapTileFetcher クラスのリファレンス実装です。実装はoffline_tile_provider/offlinetilefetcher.h とoffline_tile_provider/offlinetilefetcher.cpp ファイルにあります。
Qul::MapTileFetcher クラスには、実装しなければならないQul::MapTileFetcher::getTileImage 関数があります。OfflineTileFetcher クラスは次のように実装します:
bool OfflineTileFetcher::getTileImage(const Qul::Private::TileSpec &spec, Qul::Private::TileImage &tileImage)
{
// user has to configure url to point to tiles images root dir.
QulString url = generateTileUrl(TILES_BASE_DIR, spec);
if (url.empty()) {
url = PLACEHOLDER_TILE;
Qul::PlatformInterface::log("warning: tile url is empty. using placeholder tile at '%s'.\n", PLACEHOLDER_TILE);
}
const TileCacheMap::iterator it = tileCache.find(url);
if (it != tileCache.end()) {
tileImage.image = it->second;
return true;
}
if (tileCache.size() >= maxCacheSize)
removeOldestImage();
Qul::SharedImage newTileImage = findImage(url.c_str());
if (!newTileImage && url != PLACEHOLDER_TILE) {
#ifndef NDEBUG
Qul::PlatformInterface::log("warning: could not fetch a tile with url '%s'. using placeholder tile.\n",
url.c_str());
#endif
newTileImage = findImage(PLACEHOLDER_TILE);
if (!newTileImage) {
Qul::PlatformInterface::log("error: could not fetch a placeholder tile from '%s'.\n", PLACEHOLDER_TILE);
return false;
}
} else if (!newTileImage) {
Qul::PlatformInterface::log("error: could not fetch a placeholder tile from '%s'.\n", PLACEHOLDER_TILE);
return false;
}
tileImage.image = newTileImage;
tileCache[url] = newTileImage;
cacheOrder.push_back(url);
return true;
}OfflineTileFetcher クラスは、メンバ関数generateTileUrl を実装し、spec パラメータと、例のCMakeLists.txt ファイルで定義されたTILES_BASE_DIR を使用して、マップ・タイルのURI を構成します。
static int printTileSpec(char *buffer, int size, const char *baseDir, const Qul::Private::TileSpec &spec)
{
return std::snprintf(buffer, size, "%s%u/%u/%u.jpeg", baseDir, spec.zoom, spec.x, spec.y);
}
OfflineTileFetcher::QulString OfflineTileFetcher::generateTileUrl(const char *baseDir,
const Qul::Private::TileSpec &spec) const
{
const int size = printTileSpec(nullptr, 0, baseDir, spec);
if (size <= 0) {
Qul::PlatformInterface::log("error: failed to calculate the required buffer size for the tile url.");
return QulString();
}
QulString url;
url.resize(size + 1);
// The generated string has a length of at most n-1, leaving space for the
// additional terminating null character.
printTileSpec(&url[0], url.size(), baseDir, spec);
url.resize(size);
return url;
}OfflineTileFetcher クラスは、FileCache::get を使用して、デコードされたマップ・タイル画像にアクセスし、デコードしてRAMにキャッシュします。FileCache::get は、Qul::SharedImage オブジェクトを返します。
Qul::SharedImage OfflineTileFetcher::findImage(const char *url)
{
if (m_fileCache)
return m_fileCache->get(url);
return Qul::Private::findImageForString(url);
}OfflineTileFetcher は、すでにアクセスされたマップ・タイルを保存するキャッシュ機能を実装しています。
...
tileCache[url] = newTileImage;
...アクセスされたマップ・タイルをキャッシュすると、Qul::SharedImage への参照が保持され、RAMキャッシュに見つかった場合は、すでにデコードされたタイル画像が返される。
...
const TileCacheMap::iterator it = tileCache.find(url);
if (it != tileCache.end()) {
tileImage.image = it->second;
return true;
}
...OfflineTileFetcher CMakeLists.txt で定義された を使用して を設定し、その後、最も古いキャッシュ・エントリが削除される。MAX_CACHE_SIZE maxCacheSize
OfflineTileFetcher::OfflineTileFetcher(bool useFileCache)
...
, maxCacheSize(MAX_CACHE_SIZE)
{}
void OfflineTileFetcher::removeOldestImage()
{
for (int i = 0; i < MAX_CACHE_SIZE / 5 && !cacheOrder.empty(); ++i) {
const QulString oldestUrl = cacheOrder.front();
cacheOrder.pop_front();
tileCache.erase(oldestUrl);
}
}位置情報の取得(技術プレビュー)
この例では、ダミーの位置ソースから位置情報を取得するシミュレーションを行う。
DummyPositionSourceクラス
DummyPositionSource クラスはQul::GeoPositionSource クラスの参照実装です。実装はdummy_position_source/dummypositionsource.h とdummy_position_source/dummypositionsource.cpp ファイルにあります。
Qul::GeoPositionSource クラスには、実装しなければならないQul::GeoPositionSource::getCurrentPosition 関数があります。DummyPositionSource クラスは次のように実装します:
Qul::Private::PositionSource::SourceError DummyPositionSource::getCurrentPosition(Qul::GeoPositionInfo &positionInfo)
{
const size_t lastIndex = dataSource.size() - 1;
IndexManager &indexManager = IndexManager::instance();
Qul::GeoPositionInfo posInfo = dataSource[indexManager.getIndex()];
positionInfo.latitude = posInfo.latitude;
positionInfo.longitude = posInfo.longitude;
positionInfo.direction = posInfo.direction;
positionInfo.speed = posInfo.speed;
positionInfo.timestamp = posInfo.timestamp;
if (indexManager.getIndex() == lastIndex)
return Qul::Private::PositionSource::ClosedError;
indexManager.incrementIndex();
return Qul::Private::PositionSource::NoError;
}DummyPositionSource::getCurrentPosition 関数はdataSource vector から模擬位置データにアクセスします。dataSource ベクトルの定義はdummy_position_source/dummypositiondata.cpp にあります。
extern const std::vector<Qul::GeoPositionInfo, Qul::PlatformInterface::Allocator<Qul::GeoPositionInfo> > dataSource
= {{65.05877, 25.45545, 270, 0.000000, 1754406549865},
{65.05877, 25.455422549019605, 270, 1.287166, 1754406550864},
{65.05877, 25.455395098039215, 270, 1.287166, 1754406551866},
...
{65.0542974509804, 25.456510980392157, 248.6951536973353, 0.660902, 1754407107864},
{65.05427156862746, 25.45636862745098, 248.6951535146238, 7.269921, 1754407108858},
{65.05427078431373, 25.45636431372549, 248.6951535146238, 0.220301, 1754407109868},
{65.05427, 25.45636, 248.6951535146238, 0.220301, 1754407110869}};C++ および QML からdataSource のどの位置データエントリにアクセスするかを制御するために、IndexManager クラスがdummy_position_source/indexmanager.h に実装されています。
class IndexManager : public Qul::Singleton<IndexManager>
{
public:
IndexManager()
: m_index(0){};
void setIndex(size_t i) { m_index = i; }
size_t getIndex() const { return m_index; }
void incrementIndex() { m_index++; }
private:
size_t m_index;
};DummyPositionSource::getCurrentPosition 関数は、最後の位置データエントリに達したときにCloseError を返し、現在位置の更新を停止します。そうでない場合は、updateInterval プロパティの値に従って現在位置の更新を継続するために、PositionSource が呼び出されたときにNoError を返します。
プロジェクト構造
Cmakeプロジェクトファイル
CMakeLists.txtには、デスクトップとSTM32F769iプラットフォームの両方のコンフィギュレーションが含まれています。
CMake コンパイル定義
TILES_BASE_DIRマップ・タイルがあるルート・ディレクトリを指します。PLACEHOLDER_TILEユーザが生成されたマップ領域の外側をパンした場合に備えて、プレースホルダ画像を指定します。MAX_CACHE_SIZE古いキャッシュ・エントリーが削除されるサイズを設定します。
デスクトップ設定
デスクトップ構成は、マップタイルの画像にアクセスするためのfileloadingexample のPOSIX ファイルシステム実装と、マップタイルの画像をデコードするためのimagedecoderexample のJPEG imagedecoder 実装に依存します。
target_sources(map PRIVATE
...
../imagedecoder/desktop/desktopimagedecoder.cpp
../fileloading/posix/posixfilesystem.cpp
)STM32F769iコンフィギュレーション
プラットフォーム・コンフィギュレーションは、SD カード内のマップ・タイルの画像にアクセスするためのfileloading例のFATFS ファイル・システム実装と、マップ・タイルの画像をデコードするためのimagedecoder例のハードウェアJPEG imagedecoder に依存する。
# file system sources
target_sources(map PRIVATE
../fileloading/3rdparty/FatFs/src/diskio.c
../fileloading/3rdparty/FatFs/src/ff.c
../fileloading/3rdparty/FatFs/src/ff_gen_drv.c
../fileloading/3rdparty/FatFs/src/sd_diskio.c
../fileloading/3rdparty/FatFs/src/option/unicode.c
${QUL_BOARD_SDK_DIR}/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_sdmmc.c
${QUL_BOARD_SDK_DIR}/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c
${QUL_BOARD_SDK_DIR}/Drivers/BSP/STM32F769I-Discovery/stm32f769i_discovery_sd.c
)
# jpeg decoder sources
target_sources(map PRIVATE
${QUL_BOARD_SDK_DIR}/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_jpeg.c
../imagedecoder/stm/${STM32XX}/stm32f7xx_hal_msp.c
../imagedecoder/stm/${STM32XX}/buffer_config.cpp
../imagedecoder/stm/stmimagedecoder.cpp
../imagedecoder/common/jpeg.cpp
../imagedecoder/3rdparty/stm/Utilities/JPEG/jpeg_utils.c
)QmlProjectファイル
QmlProjectファイルは、必要なQMLファイル、画像ファイル、インターフェースファイル、Qt Quick Ultraliteモジュールをリストアップしています。また、MCU.Config.maxResourceCacheSizeをターゲットプラットフォームで動作する値に設定します。
// Copyright (C) 2026 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
import QmlProject
Project {
mainFile: "map.qml"
QmlFiles {
files: [
"MapButton.qml",
"MapContainer.qml",
"MapParameters.qml",
"MapMarker.qml",
"CopyrightText.qml"
]
}
ModuleFiles {
MCU.qulModules: ["Positioning", "Location"]
}
InterfaceFiles {
files: [
"dummy_position_source/indexmanager.h"
]
}
MCU.Config {
maxResourceCacheSize: 4000000
}
ImageFiles {
MCU.base: "icons/24px"
files: [
"icons/24px/plus.png",
"icons/24px/minus.png",
"icons/24px/rotate-right.png",
"icons/24px/rotate-left.png",
"icons/24px/nav-arrow.png",
"icons/24px/location-marker.png",
"icons/24px/start-resume.png",
"icons/24px/pause.png",
"icons/24px/stop.png"
]
}
}MapContainer.qml
メインQMLファイルはMap アイテムを使用し、地図のcenter をフィンランドのオウル市に設定します。マップの初期値zoomLevel を3、minimumZoomLevel を0、maximumZoomLevel を3に設定しています。
Map {
id: map
property bool panning: false
anchors.fill: parent
center: mapParameters.startPosition
bearing: mapParameters.bearing
zoomLevel: root.zoomLevel
minimumZoomLevel: mapParameters.minimumZoomLevel
maximumZoomLevel: mapParameters.maximumZoomLevel
...pan 関数のdeltaX とdeltaY パラメータの計算を担当するMouseArea を定義しています。
MouseArea {
id: mapPan
anchors.fill: parent
property real pressPointX: 0
property real pressPointY: 0
property real translationX: 0
property real translationY: 0
onPressed: {
map.panning = true
pressPointX = mouse.x
pressPointY = mouse.y
translationX = 0
translationY = 0
}
onReleased: {
map.panning = false
}
onPositionChanged: {
var x = mouse.x - pressPointX
var y = mouse.y - pressPointY
var deltaX = x - translationX
var deltaY = y - translationY
translationX = x
translationY = y
map.pan(-deltaX, -deltaY)
}
}MapParameters.qml
Map アイテムのデフォルトパラメータを定義する。
...
readonly property real zoomLevel: 3
readonly property real minimumZoomLevel: 0
readonly property real maximumZoomLevel: 3
readonly property real bearing: 0
readonly property geoCoordinate startPosition: QtPositioning.coordinate(65.05877, 25.45545)
...MapMarker.qml
MapMarker.qml はカスタムQMLタイプです。地図上のポイント・オブ・インタレスト・マーカーを表すMapQuickItem アイテムをラップしています。
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
import QtQuick
import QtLocation
import QtPositioning
MapQuickItem {
id: root
property alias markerText: markerText.text
property alias imageSource: markerImage.source
sourceItem: Image {
id: markerImage
source: ""
Text {
id: markerText
text: ""
font.pointSize: 7
font.bold: true
anchors.bottom: parent.top
anchors.horizontalCenter: parent.horizontalCenter
}
}
coordinate: QtPositioning.coordinate(0, 0)
anchorPoint: Qt.point(sourceItem.width / 2, sourceItem.height / 2)
}ファイル
- map/+t2g/+4m/MapContainer.qml
- map/+t2g/+4m/map.qml
- map/+t2g/+6m/MapContainer.qml
- map/+t2g/+6m/map.qml
- map/+t2g/MapParameters.qml
- map/CMakeLists.txt
- map/CopyrightText.qml
- map/MapButton.qml
- map/MapContainer.qml
- map/MapMarker.qml
- map/MapParameters.qml
- map/board_config.h
- map/desktop/board_config.cpp
- map/dummy_position_source/dummypositiondata.cpp
- map/dummy_position_source/dummypositionsource.cpp
- map/dummy_position_source/dummypositionsource.h
- map/dummy_position_source/indexmanager.h
- map/map.qml
- map/mcu_map.qmlproject
- map/mcu_map_t2g_4m.qmlproject
- map/mcu_map_t2g_6m.qmlproject
- map/offline_tiles_provider/offlinetilefetcher.cpp
- map/offline_tiles_provider/offlinetilefetcher.h
- map/os/baremetal/main.cpp
- map/stm/stm32f7/board_config.cpp
- map/stm/stm32u5/board_config.cpp
- map/t2g-traveo/board_config.cpp
画像です:
特定の Qt ライセンスの下で利用可能です。
詳細を見る。