はりきらないひと

2015/12/12

Jolla: 【一夜漬け】"QtPositioning"を使って現在地周辺地図を表示させてみた

この投稿は"Qt Advent Calendar 2015 - Qiita"の12日目(12/12分)の記事だ。

なんか他のメンバの記事のレベルが去年にも増して高くて、正直こんなネタの記事を混ぜていいもんか不安になるレベルだけど、逆に記事書くのを躊躇してたけどコレ見て「あぁ、こんなんで許されるんだ」と思ったヒトが居たら、ぜひ空いてる日にエントリして参戦して欲しい。Qtユーザ会宴会部長(名義)からのお願いだ(何

正直相変わらずQtの話ってよりJollaの話っなんだけど、まぁ気にしないで欲しい。

今年はコードを書くという面においてはほとんど何もアウトプットが出せていないのでギリギリまでネタに悩んだんだけど、とりあえず「一夜漬け」でQtPositioningを使ってJollaに現在地周辺の地図を表示させるという、ただそれだけのサンプルを書いてみることにした。

QtPositioningはその名の通りデバイスの位置情報を扱うもので、Android、iOS、Linux(GeoClue)、WinRT(Windows Mobile ?)でサポートされているらしい。もちろん、Jollaで使える。

というコトで早速コードを書いてみる。
import QtQuick 2.0
import Sailfish.Silica 1.0
import QtPositioning 5.3
import QtWebKit 3.0

Page {
    id: page

    PageHeader {
        title: "QtPositioning"
    }

    PositionSource {
        id: posSource
        updateInterval: 30000
        active: true
        onPositionChanged: {
            var pos = posSource.position.coordinate
            webView.url = "https://www.google.co.jp/maps/@%1,%2,17z".arg(pos.latitude).arg(pos.longitude)
            posData.text = "Latitude: %1\nLongitude: %2".arg(pos.latitude).arg(pos.longitude)
        }
    }

    WebView {
        id: webView
        width: 480
        height: 640
        anchors.centerIn: parent
    }

    Text {
        id: posData
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 20
        color: Theme.secondaryHighlightColor
        font.pixelSize: Theme.fontSizeExtraLarge
    }

    Connections {
        target: Qt.application
        onActiveChanged: Qt.application.active ? posSource.active = true : posSource.active = false
    }
}
だいたいこんな感じ。雑なコードだけど、相変わらず恐ろしく簡単に使えるQtQuick/Qmlすごい。
基本的には「QtPositioning」をimportしてPositionSource{}を定義しておくだけ。
最低限、updateIntervalを設定し、activeをtrueにするぐらいで緯度と経度が取得できる。
厳密にはGPSベースの測位を優先するかどうか(preferredPositioningMethods)等の設定ができるけど、概ねデフォルトのままで使える。
positionが変わったら新たに取得した緯度・経度をGoogle MapのURLにしてWebView{}に渡す。と、そのpositionを中心にしたマップが表示される。今回のサンプルアプリはAPIを介したアクセスではなくページごと取得しなおしてるので、高頻度な更新を避けるためupdateIntervalを30秒(30000mSec)にしてみた。

一番下のConnections{}は前回Qippisにカメラ機能を追加した時にも活躍した「おまじない」。Jollaがスリープした時にGPSを動かしっぱなしにして電池消耗させないためのもの。なんだけど、method見る限りこれはstart()/stop()を使うべきなのかな・・・?

ちなみにAndroidだとこんな感じ。
import QtQuick 2.3
import QtQuick.Window 2.2
import QtPositioning 5.3
import QtWebView 1.0

Window {
    visible: true

    PositionSource {
        id: posSource
        updateInterval: 30000
        active: true
        onPositionChanged: {
            var pos = posSource.position.coordinate
            webView.url = "https://www.google.co.jp/maps/@%1,%2,17z".arg(pos.latitude).arg(pos.longitude)
            posData.text = "Latitude: %1\nLongitude: %2".arg(pos.latitude).arg(pos.longitude)
        }
    }

    WebView {
        id: webView
        width: 480
        height: 640
        anchors.centerIn: parent
    }

    Text {
        id: posData
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 20
        color: Theme.secondaryHighlightColor
        font.pixelSize: Theme.fontSizeExtraLarge
    }

    Connections {
        target: Qt.application
        onActiveChanged: Qt.application.active ? posSource.active = true : posSource.active = false
    }
}
変えたのは以下の通り。

  • "Sailfish.Silica" → "QtQuick.Window"
  • "QtWebKit 3.0"→"QtWebView 1.0"
  • "Page{}" → "Window{}"
  • "visible: true"を追加
  • PageHeader{}を削除

たったこれだけの変更でとりあえず動く。
地図のサイズが小っちゃくなっちゃってるけど、これはWebViewのサイズを画面サイズとの相対値にしておけば労せず同じような見栄えにできるはず。すばらしいね!


もちろん、実際コレで何かアプリを作るならばこの取得した位置情報で何をするのかってコトの方が重要なワケだけど、すくなくとも位置情報の取得のためにアレコレ細かいコード書かなくてすむQtQuick/Qmlサイコー。

ってコトで、去年のカメラにしても今年の位置情報にしてもそれ自体を使うためのコードは最低限で済むワケなので、みんないっぱいQtでアプリ書いてみるといいと思うよ。

0 件のコメント:

コメントを投稿