【Groongaメモ・2】データを作成し緯度経度周辺検索を行う
POSTED BY
2024-10-17
2024-10-17


【Groongaメモ・1】Debianインストール・動作確認の続きです。
全国駅名緯度経度Groonga用ファイル作成
全国駅名の緯度経度データベースをまず作成します。
【Redisメモ・5】位置情報関数GEOADD・GEORADUSを使う
の、station_tsv_to_redis.phpを改造してgroonga入れ込み用JSONデータを吐くようにします。キー重複のエラーが出たら困るので、行番号-駅名というキーフィールドにします。
テーブル形式は _key, value, location とし、_key = 行番号-駅名、value = 駅名、location = 10進表現緯度経度(世界測地系)、テーブル名はEkiPosとします。
| PHP | station_tsv_to_groonga.php | GitHub Source |
<?php date_default_timezone_set('Asia/Tokyo');
$file = new SplFileObject('station20151215free.txt', 'r');
$file->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY | SplFileObject::READ_AHEAD);
$file->setCsvControl("\t");
foreach ($file as $line)
{
$fields[] = $line;
}
$n = count($fields);
$i = 9; // fields[9]からが実データ
echo "load --table EkiPos\n";
echo "[\n";
echo "[\"_key\", \"value\", \"location\"],\n";
for( ; $i < $n; $i++ ){
// fields[i][10]=経度,[11]=緯度,[3]=駅名,[7]=都道府県番号
// 駅名は同一駅名があるため、行番号-駅名 という感じでキー出力する。
// $pref_no = $fields[$i][7];
//if(strlen($pref_no) <= 1){
// $pref_no = "0" . $pref_no;
//}
echo "[\"" . ($i - 9 + 1) . "-" . $fields[$i][3] . "\",";
echo " \"" . $fields[$i][3] . "\",";
echo " \"" . $fields[$i][11] . "," . $fields[$i][10] . "\"],\n";
}
echo "]\n";
上記Redis記事にあるstation20151215free.txtをカレントに用意し、phpを実行しINSERT JSONファイルを生成します。
#生成 php station_tsv_to_groonga.php > station_tsv_to_groonga.out.txt #確認 head station_tsv_to_groonga.out.txt load --table EkiPos [ ["_key", "value", "location"], ["1-函館", "函館", "41.773709,140.726413"], ["2-五稜郭", "五稜郭", "41.803557,140.733539"], ["3-桔梗", "桔梗", "41.846457,140.722952"], ["4-大中山", "大中山", "41.864641,140.71358"], ["5-七飯", "七飯", "41.886971,140.688556"], tail station_tsv_to_groonga.out.txt ["10819-おもろまち", "おもろまち", "26.222701,127.698391"], ["10820-古島", "古島", "26.230919,127.703079"], ["10821-市立病院前", "市立病院前", "26.227548,127.710003"], ["10822-儀保", "儀保", "26.224663,127.719039"], ["10823-首里", "首里", "26.219191,127.725492"], ["10824-九州鉄道記念館", "九州鉄道記念館", "33.944392,130.962439"], ["10825-出光美術館", "出光美術館", "33.947792,130.965292"], ["10826-ノーフォーク広場", "ノーフォーク広場", "33.955973,130.964254"], ["10827-関門海峡めかり", "関門海峡めかり", "33.960627,130.967347"], ]
テーブル定義ファイル作成
以下のようなEkiPosテーブル作成スクリプトファイルを作成。
| Shell | EkiPos.grn | GitHub Source |
table_create --name EkiPos --flags TABLE_HASH_KEY --key_type ShortText column_create --table EkiPos --name value --type Text column_create --table EkiPos --name location --flags COLUMN_SCALAR --type WGS84GeoPoint table_create --name R_EkiPos --flags TABLE_PAT_KEY --key_type WGS84GeoPoint column_create --table R_EkiPos --name index --flags COLUMN_INDEX --type EkiPos --source location
最初の3行がメインテーブルで_key, value, locationを定義。
後の2行で範囲検索用インデックステーブルを定義しメインテーブルに紐づけ。
データベースファイル作成・データインサート
準備は整ったので、データベースを作成しテーブル定義、駅緯度経度データのインサートを行います。
データベースディレクトリの作成
一般ユーザ権限で普通に任意のディレクトリ(ここではgrn)を作成します。
mkdir /home/hogeuser/grn
データベース作成とテーブル定義入れ込み
groonga -n /home/hogeuser/grn/db 確認 <pre> groonga /home/hogeuser/grn/db table_list --output_pretty yes column_list EkiPos --output_pretty yes column_list R_EkiPos --output_pretty yes緯度経度データファイルの入れ込み いよいよ最初に作成した全国駅データファイル入れ込み。
groonga /home/hogeuser/grn/db
<b style="color: #0000ff;">緯度経度範囲指定検索の実行</b>
コマンドコンソールで実行してみる。東京駅(35.681454,139.767200)周辺10km以内にある駅を、近い順に距離(m)つきで100個出力する。RDBMSのようにOFFSET, LIMITページャー指定が使える。
<pre>
groonga /home/hogeuser/grn/db
select EkiPos --filter 'geo_in_circle(location, "35.681454,139.767200", 10000)' --scorer '_score = geo_distance(location, "35.681454,139.767200")' --output_columns '_key,_score' --sortby _score --offset 0 --limit 100 --output_pretty yes
[
[
0,
1602936879.14628,
0.003387689590454102
],
[
[
[
538
],
[
[
"_key",
"ShortText"
],
[
"_score",
"Int32"
]
],
[
"1501-東京",
99
],
[
"1448-東京",
99
],
[
"1411-東京",
99
],
[
"1261-東京",
99
],
[
"1572-東京",
99
],
[
"1898-東京",
99
],
[
"1959-東京",
99
],
[
"2213-東京",
99
],
[
"2012-東京",
99
],
[
"1305-東京",
99
],
[
"5839-東京",
227
],
[
"5888-大手町",
384
],
[
"5913-二重橋前",
475
],
[
"7638-大手町",
537
],
[
"5820-日本橋",
573
],
[
"5889-日本橋",
573
],
[
"5838-大手町",
574
],
[
"5821-京橋",
574
],
[
"5912-大手町",
623
],
[
"5957-三越前",
658
],
[
"5956-大手町",
661
],
[
"5940-有楽町",
728
],
[
"1306-有楽町",
733
],
[
"2013-有楽町",
733
],
[
"7622-日本橋",
768
],
[
"7621-宝町",
782
],
[
"5941-銀座一丁目",
788
],
[
"5819-三越前",
851
],
[
"7637-日比谷",
884
],
[
"1573-新日本橋",
969
],
[
"5873-日比谷",
990
],
[
"5840-銀座",
1089
],
[
"5822-銀座",
1089
],
[
"5872-銀座",
1089
],
[
"5914-日比谷",
1105
],
[
"1502-神田",
1122
],
[
"1304-神田",
1122
],
[
"2011-神田",
1122
],
[
"5869-八丁堀",
1146
],
[
"5890-茅場町",
1169
],
[
"5868-茅場町",
1169
],
[
"1899-八丁堀",
1213
],
[
"7620-東銀座",
1330
],
[
"5871-東銀座",
1330
],
[
"5942-新富町",
1353
],
[
"5887-竹橋",
1385
],
[
"5818-神田",
1386
],
[
"5866-小伝馬町",
1444
],
[
"7623-人形町",
1462
],
[
"5867-人形町",
1462
],
[
"5939-桜田門",
1485
],
[
"5837-淡路町",
1551
],
[
"7663-小川町",
1557
],
[
"5870-築地",
1558
],
[
"5958-水天宮前",
1643
],
[
"7636-内幸町",
1666
],
[
"5874-霞ケ関",
1694
],
[
"5915-霞ケ関",
1694
],
[
"5841-霞ケ関",
1694
],
[
"5823-新橋",
1744
],
[
"7664-岩本町",
1746
],
[
"7639-神保町",
1759
],
[
"7662-神保町",
1827
],
[
"5955-神保町",
1827
],
[
"7665-馬喰横山",
1835
],
[
"7590-築地市場",
1837
],
[
"5911-新御茶ノ水",
1846
],
[
"1412-新橋",
1862
],
[
"2014-新橋",
1862
],
[
"1262-新橋",
1862
],
[
"1307-新橋",
1862
],
[
"7619-新橋",
1895
],
[
"7791-新橋",
1896
],
[
"1574-馬喰町",
1902
],
[
"7624-東日本橋",
1980
],
[
"1303-秋葉原",
1982
],
[
"2010-秋葉原",
1982
],
[
"1551-秋葉原",
1982
],
[
"5865-秋葉原",
1997
],
[
"5824-虎ノ門",
1999
],
[
"1550-御茶ノ水",
2024
],
[
"1503-御茶ノ水",
2024
],
[
"7765-秋葉原",
2036
],
[
"7666-浜町",
2044
],
[
"7591-汐留",
2056
],
[
"5954-九段下",
2085
],
[
"7661-九段下",
2085
],
[
"5886-九段下",
2085
],
[
"5836-御茶ノ水",
2145
],
[
"5916-国会議事堂前",
2149
],
[
"5842-国会議事堂前",
2149
],
[
"7792-汐留",
2161
],
[
"5953-半蔵門",
2352
],
[
"1552-浅草橋",
2354
],
[
"7588-月島",
2396
],
[
"5943-月島",
2396
],
[
"5817-末広町",
2421
],
[
"5952-永田町",
2446
],
[
"5938-永田町",
2446
],
[
"5975-永田町",
2446
]
]
]
]
同じ駅名が連続するのは元データの路線名が違うので出てきてしまっているが、一応期待した結果は得られた。
次回は【Groongaメモ・3】C言語ライブラリを使用し緯度経度周辺検索を行うです。
Android
iPhone/iPad
Flutter
MacOS
Windows
Debian
Ubuntu
CentOS
FreeBSD
RaspberryPI
HTML/CSS
C/C++
PHP
Java
JavaScript
Node.js
Swift
Python
MatLab
Amazon/AWS
CORESERVER
Google
仮想通貨
LINE
OpenAI/ChatGPT
IBM Watson
Microsoft Azure
Xcode
VMware
MySQL
PostgreSQL
Redis
Groonga
Git/GitHub
Apache
nginx
Postfix
SendGrid
Hackintosh
Hardware
Fate/Grand Order
ウマ娘
将棋
ドラレコ
※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!ご連絡は以下アドレスまでお願いします★
【キーワード検索】
【最近の記事】【全部の記事】
CUDA13環境下でGPU使用版のllama.cppを導入しC++ライブラリを使うCUDA13環境下でGPU使用版のllama-cpp-pythonを導入する
CUDA13環境下でGPU使用版のPyTorchを導入する
LetsEncrypt/certbotの証明書自動更新がエラーになる場合
Wav2Lipのオープンソース版を改造して外部から呼べるAPI化する
Wav2Lipのオープンソース版で静止画の口元のみを動かして喋らせる
【iOS】アプリアイコン・ロゴ画像の作成・設定方法
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【2】
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【1】
【Xcode】iPhone is not available because it is unpairedの対処法
【人気の記事】【全部の記事】
進研ゼミチャレンジタッチをAndroid端末化する【Windows10】リモートデスクトップ間のコピー&ペーストができなくなった場合の対処法
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
CUDA13環境下でGPU使用版のPyTorchを導入する
【Apache】サーバーに同時接続可能なクライアント数を調整する
LinuxからWindowsの共有フォルダをマウントする
VirtualBoxの仮想マシンをWindows起動時に自動起動し終了時に自動サスペンドする
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
CUDA13環境下でGPU使用版のllama-cpp-pythonを導入する
【Xcode】iPhone is not available because it is unpairedの対処法
【カテゴリーリンク】
Android
iPhone/iPad
Flutter
MacOS
Windows
Debian
Ubuntu
CentOS
FreeBSD
RaspberryPI
HTML/CSS
C/C++
PHP
Java
JavaScript
Node.js
Swift
Python
MatLab
Amazon/AWS
CORESERVER
Google
仮想通貨
LINE
OpenAI/ChatGPT
IBM Watson
Microsoft Azure
Xcode
VMware
MySQL
PostgreSQL
Redis
Groonga
Git/GitHub
Apache
nginx
Postfix
SendGrid
Hackintosh
Hardware
Fate/Grand Order
ウマ娘
将棋
ドラレコ