C++ で住所などから緯度・経度を求める

(1/1)
>C++で住所などから緯度・経度を求める
インターネット上の WebAPI サービスを利用し、住所やランドマークなどから緯度・経度を検索するアプリケーションである。検索結果をクリプボードにコピーしたり、テキストファイルに保存することができる。また、ユーザーが API キーを取得することで、Google や Yahoo!JAPAN のサービスを利用することができる。
PHP で住所から緯度・経度を求める(Windows アプリ版)」で作った PHP プログラムを C++に移植したものである。

目次

サンプル・プログラム

圧縮ファイルの内容
address2geowin.msiインストーラ
bin/address2geowin.exe実行プログラム本体
bin/cwebpage.dll
実行時に必要になるDLL
bin/etc/help.chmヘルプ・ファイル
sour/address2geowin.cppソース・プログラム
sour/resource.hリソース・ヘッダ
sour/resource.rcリソース・ファイル
sour/application.icoアプリケーション・アイコン
sour/mystrings.cpp汎用文字列処理関数など(ソース)
sour/mystrings.h汎用文字列処理関数など(ヘッダ)
sour/pahooGeocode.cpp住所・緯度・経度に関わるクラス(ソース)
sour/pahooGeocode.cpp住所・緯度・経度に関わるクラス(ヘッダ)

使用ライブラリ

WebAPI にアクセスするために、オープンソースのライブラリ Boost C++ライブラリcURL (カール)  および OpenSSL が必要になる。導入方法等については、「C++ 開発環境の準備」をご覧いただきたい。

リソースの準備

今回は 32 ビット版の開発環境を用いる。
Eclipse を起動し、新規プロジェクト address2geowin を用意する。
ResEdit を起動し、resource.rc を用意する。

Eclipse に戻り、ソース・プログラム "address2geowin.cpp" を追加する。
リンカー・フラグを -mwindows -static -lstdc++ -lgcc -lwinpthread -lcurl -lssl -lole32 "C:\pleiades\eclipse\mingw\mysys2\mingw32\bin\libcurl.dll" に設定する。

解説:定数など

0030: // 定数など ==================================================================
0031: #define APPNAME     "address2geowin"                    //アプリケーション名
0032: #define APPNAMEJP "住所などから緯度・経度を求める"    //アプリケーション名(日本語)
0033: #define APPVERSION "1.0"                //バージョン
0034: #define APPYEAR     "2020"                //作成年
0035: #define REFERENCE "https://www.pahoo.org/e-soul/webtech/cpp01/cpp01-14-01.shtm"  // 参考サイト
0036: 
0037: //ヘルプ・ファイル
0038: #define HELPFILE ".\\etc\\help.chm"
0039: 
0040: //デフォルト保存ファイル名
0041: #define SAVEFILE "address2geowin.txt"
0042: 
0043: //エラー・メッセージ格納用:変更不可
0044: string ErrorMessage;
0045: 
0046: //現在のインターフェイス
0047: HINSTANCE hInst;
0048: 
0049: //親ウィンドウ
0050: HWND hParent;
0051: 
0052: //pahooGeocodeオブジェクト
0053: pahooGeocode *pGC;

とくに注意記載が無い限り、定数は自由に変更できる。

解説:クラス

C++には、オブジェクト指向プログラム民具を行うための仕組みとしてクラスが用意されている。ある程度まとまった処理を別プログラムで再利用したり、複雑なデータ構造を扱う際、クラスを使うと効果がある。
今回は、WebAPI にアクセする処理を pahooGeocode クラス としてコーディングした。ソースは "pahooGeocode.cpp" ヘッダは "pahooGeocode.hpp" である。

0031: /**
0032:  * コンストラクタ
0033:  * @param string appname アプリケーション名
0034:  */
0035: pahooGeocode::pahooGeocode(std::string appname) {
0036:     pahooGeocode::getMyPath(appname.c_str());
0037:     pahooGeocode::readGoogleApiKey();
0038:     pahooGeocode::readYahooApiKey();
0039: }
0040: 
0041: //デストラクタ
0042: pahooGeocode::~pahooGeocode() {
0043: }

クラス名と同じ名前を持つメソッドはコンストラクタと呼び、クラスからオブジェクトを生成するときに最初に呼ばれる。
ここでは、GoogleAPI キーや Yahoo!アプリケーション ID の読み込みを行う。
一方、クラス名に "~" を付けたメソッドはデストラクタと呼び、オブジェクトを解放するときに呼ばれる。
このデストラクタは何もしない。

解説:住所検索サービスAPI

pahooGeocode クラスは、下表の住所検索サービス API を選択して呼び出すことが可能である。各々の API の仕様については、「PHP で住所・ランドマークから緯度・経度を求める」をご覧いただきたい。
住所検索サービス
サービス名 メソッド 制 約
1 Google getPointsGoogle 有料(決められた無料枠あり)。全世界の住所、ランドマークの検索可能。
2 Yahoo!JAPAN getPointsYOLP 無料(?)。住所、ランドマーク、海外のどれを検索するか指定。ランドマークや海外地名検索はGoogleに劣る。
11 HeartRails Geo API getPointsHRG 無料。住所、または住所の一部のみ検索可能。
12 OSM Nominatim Search API getPointsNominatim 無料。全世界の住所、ランドマークの検索可能。精度はGoogleに劣る。

0548: /**
0549:  * ジオコーダAPI を用いて検索キーワードから緯度・経度を求める
0550:  *
0551:  * @param wstring query 検索キーワード
0552:  * @param int     api    0:APIを自動選定(省略時)
0553:  *                         1:Google Geocoding API
0554:  *                         2:Yahoo!ジオコーダAPI
0555:  *                        11:HeartRails Geo API
0556:  *                        12:OSM Nominatim Search API
0557:  * @return int ヒットした地点数
0558: */
0559: int pahooGeocode::searchPoints(wstring queryint api=0) {
0560:     static int apilist[] = { 1, 2, 11, 12 };
0561: 
0562:     //配列の初期化
0563:     for (int i = 0; i < __SIZE_PPOINTSi++) {
0564:         pahooGeocode::Ppoints[i].longitude = 0;
0565:         pahooGeocode::Ppoints[i].latitude  = 0;
0566:         pahooGeocode::Ppoints[i].address   = L"";
0567:     }
0568: 
0569:     int cnt;
0570: 
0571:     //APIを自動選定
0572:     if (api == 0) {
0573:         for (int api : apilist) {
0574:             pahooGeocode::resetError();
0575:             cnt = pahooGeocode::__searchPoints(queryapi);
0576:             if (cnt > 0)    break;
0577:         }
0578:     //API指定
0579:     } else {
0580:         cnt = pahooGeocode::__searchPoints(queryapi);
0581:     }
0582: 
0583:     return cnt;
0584: }

メソッド searchPoints は、前述の住所検索サービスを指定して呼び出すか、利用できるサービスを自動選定して呼び出す。
自動選定の順序は、上表にしたがう。GoogleAPI キーや Yahoo!アプリケーション ID が未登録の場合は、これらの呼び出しをスキップする。また、その WebAPI を利用することができなかったり、検索結果がゼロだった場合は、次点のサービスを自動的に呼び出す。
その他の関数、マップ描画、ヘルプファイルやインストーラー作成方法については、これまでの連載で説明してきたとおりである。

参考サイト

(この項おわり)
header