Qt最新事情-QtでWebKitを使ってみよう

第6回 Qt WebKit~WebコンテンツとQtの連携

この記事を読むのに必要な時間:およそ 11 分

Google Mapの例

図5のような,Google Mapで住所を表示するアプリケーションがQt Labs Blogsで紹介されています。

図5 Google Mapでの住所表示

図5 Google Mapでの住所表示

このアプリケーションについて説明しましょう。ソースコードはhttp://chaos.troll.no/~hhartz/addressbook.tarから入手できます。以降の説明では若干ソースコードを修正しています。

ジオコーディング

準備として,Google Maps APIを使うためにGoogle Maps APIのキーが必要です。キーは,Google Maps APIのページから取得できます。

まず,Google Mapsによって,住所から地理座標(緯度と経度)を求める部分を抜出して説明します。このプログラムは,以下のようにコマンドラインで指定した住所の緯度と経度を表示します。

$ ./addr2coord 富士山
QPointF(35.3629, 138.731)
$ ./addr2coord 東京都千代田区平河町
QPointF(35.682, 139.74)
$

リスト4 addr2coord.cpp

01: #include <QCoreApplication>
02: #include <QNetworkRequest>
03: #include <QNetworkAccessManager>
04: #include <QNetworkReply>
05: #include <QStringList>
06: #include <QDebug>
07: #include <QPointF>
08: 
09: #define GOOGLE_MAPS_KEY "自分の Google Maps Key"
10: 
11: class Addr2Coord : public QObject
12: {
13:     Q_OBJECT
14: 
15: public:
16:     Addr2Coord() {
17:         manager = new QNetworkAccessManager( this );
18:         connect( manager, SIGNAL( finished( QNetworkReply* ) ),
19:                  this, SLOT( replyFinished( QNetworkReply* ) ) );
20:     }

QNetworkAccessManagerを使うと,URLを指定してネットワークリクエストを出し,その結果を得られます。結果が得られたときに送信されるシグナルfinished()に接続したスロットで,リクエストの結果を得て表示すればよいことになります。

21: 
22: signals:
23:     void finished();

ネットワークリクエストの結果を取得して処理が終わったときに送信するシグナルを定義します。

24: 
25: public slots:
26:     void geoCode( const QString& address ) {
27:         QString requestStr = QString( "http://maps.google.com/maps/geo?q=%1&output=%2&key=%3" )
28:                                       .arg( address )
29:                                       .arg( "csv" )
30:                                       .arg( GOOGLE_MAPS_KEY );
31: 
32:         manager->get( QNetworkRequest( requestStr ) );
33:     }
34: 

URI http://maps.google.com/maps/geo? に要求を送り,Google Maps APIジオコーダに直接アクセスして地理座標を取得します。URI に指定しているパラメータは以下のようになります。

q住所
output生成される出力の形式。xml,kml,csvまたはjsonの中から扱いやすいcsvを指定します。
key自分のGoogle Maps APIキー。Qt Labsの方のコードでは文字列"GOOGLE_MAPS_KEY"を自分のキーに書き換えて使います。
35:     void replyFinished( QNetworkReply* reply ) {
36:         QString replyStr( reply->readAll() );
37:         QStringList coordinateStrList = replyStr.split( "," );
38:         
39:         if ( coordinateStrList.size() == 4 ) {
40:             QPointF coordinate( coordinateStrList[2].toFloat(), coordinateStrList[3].toFloat() );
41:             qDebug() << coordinate;
42:             emit finished();
43:         }
44:     }
45:     

QNetworkReplyはQIODeviceを継承しているので,ファイルやソケットなどと同じように読み書きができます。readAll()で全結果を読込んでいます。結果はカンマ区切りで以下の値が返ってくるので,3番目と4番目を取り出せばよいことになります。

HTTP 状態コード, 精度, 緯度, 経度
46: private:
47:     QNetworkAccessManager* manager;
48: };      
49: 
50: int main( int argc, char** argv )
51: {
52:     QCoreApplication app( argc, argv );
53: 
54:     if ( argc != 2 ) {
55:         qDebug() << "Usage: addr2coord address";
56:         exit( 1 );
57:     }
58: 
59:     QString address = QString::fromLocal8Bit( argv[1] );
60: 
61:     Addr2Coord addr2coord;
62:     addr2coord.geoCode( address );
63: 
64:     QObject::connect( &addr2coord, SIGNAL( finished() ), &app, SLOT( quit() ) );
65: 
66:     return app.exec();
67: }
68: 
69: #include "addr2coord.moc"

日本語の住所も扱えるように,QString::fromLocal8Bit()で変換してからAddr2Coord::geoCode()で地理座標を求めます。求め終わったらプログラムが終了するように,シグナルAddr2Coord::finished()をQApplication::quit() に接続しています。

著者プロフィール

杉田研治(すぎたけんじ)

1955年生まれ。東京都出身。株式会社SRAに勤務。プログラマ。

仕事のほとんどをMac OS XとKubuntu KDE 4でQtと供に過ごす。