developer's diary

最近はc#のエントリが多いです

【逆ジオコーディングサービスを作りたい!】国土交通省の位置参照情報ダウンロードサービスのデータをSQLiteに入れてみる。



データ元:位置参照情報ダウンロードサービス



位置参照情報ダウンロードサービスへを押下



都道府県単位のボタンを押下


全ての都道府県を選択をチェック
街区レベルのみをチェック
平成21年のデータ選んでを選択を押下


全ての街区レベルを選択のチェックボックスをチェック
選択ボタンを押下


同意するを押下



各都道府県のデータをダウンロードする

ダウンロードしたファイルを解凍してcsvファイルを取り出す。

phpでcsvのデータをsqlite形式のファイルにする

テーブルレイアウトは

日本語名 英名 主キー
id id INTEGER *
都道府県名 todoufukenn TEXT
市区町村名 shikuchosonnmei TEXT
大字・町丁目 choume TEXT
街区符号・地番 chibann TEXT
緯度 ido REAL
経度 keido REAL

こんな感じにしてみました。

gps.php(バグがあります。)

<?php

$file = $argv[1]; //CSVファイルパス
$dbfile = $argv[2]; //データベースファイル名
if(empty($file)){
	exit();
}
if(empty($dbfile)){
	exit();
}


$fp = fopen($file, "r");
fgets($fp,1024);//1行読み飛ばす

try {
	$path = dirname(__FILE__)."/".$dbfile;
	$dbh = getDB($path);
	if(file_exists($path)){
		create_table($dbh);
	}

	//トランザクション開始
	$dbh->beginTransaction();


	//INSERT用
	$sth = $dbh->prepare("INSERT INTO gps values( NULL, :todoufukenn, :shikuchosonnmei, :choume, :chibann, :ido, :keido);");
	$sth->bindParam(':todoufukenn', $todoufukenn); // 都道府県名
	$sth->bindParam(':shikuchosonnmei', $shikuchosonnmei); // 市区町村名
	$sth->bindParam(':choume', $choume); // 大字・町丁目
	$sth->bindParam(':chibann', $chibann); // 街区符号・地番
	$sth->bindParam(':ido', $ido); // 緯度
	$sth->bindParam(':keido', $keido); // 経度

	while ($data = fgetcsv($fp, 10000)) {
		$todoufukenn = mb_convert_encoding($data[0], "UTF-8", "sjis-win"); // 都道府県名
		$shikuchosonnmei = mb_convert_encoding($data[1], "UTF-8", "sjis-win"); // 市区町村名
		$choume =  mb_convert_encoding($data[2], "UTF-8", "sjis-win"); // 大字・町丁目
		$chibann =  mb_convert_encoding($data[3], "UTF-8", "sjis-win"); // 街区符号・地番
		$ido =  $data[7]; // 緯度
		$keido =  $data[8]; // 経度
		$sth->execute();
	}

	$dbh->commit();

} catch (PDOException $e1) {
	print $e1->getMessage()."\n";
	try {
		if ($dbh != null) {
			$dbh->rollBack();
		}
	} catch (PDOException $e2) {
		print $e2->getMessage()."\n";
	}
}


function getDB($path){
	if(!isset($GLOBALS["getDB"])){
		$GLOBALS["getDB"]=new PDO('sqlite:'.$path, "", "");
	}
	return $GLOBALS["getDB"];
}


function create_table($dbh){
	$sql = <<<EOF
create table gps (
  id INTEGER PRIMARY KEY
, todoufukenn TEXT
, shikuchosonnmei TEXT
, choume TEXT
, chibann TEXT
, ido REAL
, keido REAL
);
EOF;
	$dbh->exec($sql);
	$dbh->exec("CREATE INDEX ido_idx ON gps (ido);");
	$dbh->exec("CREATE INDEX keido_idx ON gps (keido);");
}

gps.bat

php gps.php 01_2009.csv 01_2009.db
php gps.php 02_2009.csv 02_2009.db
php gps.php 03_2009.csv 03_2009.db
php gps.php 04_2009.csv 04_2009.db
php gps.php 05_2009.csv 05_2009.db
php gps.php 06_2009.csv 06_2009.db
php gps.php 07_2009.csv 07_2009.db
php gps.php 08_2009.csv 08_2009.db
php gps.php 09_2009.csv 09_2009.db
php gps.php 10_2009.csv 10_2009.db
php gps.php 11_2009.csv 11_2009.db
php gps.php 12_2009.csv 12_2009.db
php gps.php 13_2009.csv 13_2009.db
php gps.php 14_2009.csv 14_2009.db
php gps.php 15_2009.csv 15_2009.db
php gps.php 16_2009.csv 16_2009.db
php gps.php 17_2009.csv 17_2009.db
php gps.php 18_2009.csv 18_2009.db
php gps.php 19_2009.csv 19_2009.db
php gps.php 20_2009.csv 20_2009.db
php gps.php 21_2009.csv 21_2009.db
php gps.php 22_2009.csv 22_2009.db
php gps.php 23_2009.csv 23_2009.db
php gps.php 24_2009.csv 24_2009.db
php gps.php 25_2009.csv 25_2009.db
php gps.php 26_2009.csv 26_2009.db
php gps.php 27_2009.csv 27_2009.db
php gps.php 28_2009.csv 28_2009.db
php gps.php 29_2009.csv 29_2009.db
php gps.php 30_2009.csv 30_2009.db
php gps.php 31_2009.csv 31_2009.db
php gps.php 32_2009.csv 32_2009.db
php gps.php 33_2009.csv 33_2009.db
php gps.php 34_2009.csv 34_2009.db
php gps.php 35_2009.csv 35_2009.db
php gps.php 36_2009.csv 36_2009.db
php gps.php 37_2009.csv 37_2009.db
php gps.php 38_2009.csv 38_2009.db
php gps.php 39_2009.csv 39_2009.db
php gps.php 40_2009.csv 40_2009.db
php gps.php 41_2009.csv 41_2009.db
php gps.php 42_2009.csv 42_2009.db
php gps.php 43_2009.csv 43_2009.db
php gps.php 44_2009.csv 44_2009.db
php gps.php 45_2009.csv 45_2009.db
php gps.php 46_2009.csv 46_2009.db
php gps.php 47_2009.csv 47_2009.db

都道府県単位のデータベースの出来上がり。

ひとつにまとめる場合はこんな感じで実行。

php gps.php 01_2009.csv gps.db
php gps.php 02_2009.csv gps.db
php gps.php 03_2009.csv gps.db
php gps.php 04_2009.csv gps.db
php gps.php 05_2009.csv gps.db
php gps.php 06_2009.csv gps.db
php gps.php 07_2009.csv gps.db
php gps.php 08_2009.csv gps.db
php gps.php 09_2009.csv gps.db
php gps.php 10_2009.csv gps.db
php gps.php 11_2009.csv gps.db
php gps.php 12_2009.csv gps.db
php gps.php 13_2009.csv gps.db
php gps.php 14_2009.csv gps.db
php gps.php 15_2009.csv gps.db
php gps.php 16_2009.csv gps.db
php gps.php 17_2009.csv gps.db
php gps.php 18_2009.csv gps.db
php gps.php 19_2009.csv gps.db
php gps.php 20_2009.csv gps.db
php gps.php 21_2009.csv gps.db
php gps.php 22_2009.csv gps.db
php gps.php 23_2009.csv gps.db
php gps.php 24_2009.csv gps.db
php gps.php 25_2009.csv gps.db
php gps.php 26_2009.csv gps.db
php gps.php 27_2009.csv gps.db
php gps.php 28_2009.csv gps.db
php gps.php 29_2009.csv gps.db
php gps.php 30_2009.csv gps.db
php gps.php 31_2009.csv gps.db
php gps.php 32_2009.csv gps.db
php gps.php 33_2009.csv gps.db
php gps.php 34_2009.csv gps.db
php gps.php 35_2009.csv gps.db
php gps.php 36_2009.csv gps.db
php gps.php 37_2009.csv gps.db
php gps.php 38_2009.csv gps.db
php gps.php 39_2009.csv gps.db
php gps.php 40_2009.csv gps.db
php gps.php 41_2009.csv gps.db
php gps.php 42_2009.csv gps.db
php gps.php 43_2009.csv gps.db
php gps.php 44_2009.csv gps.db
php gps.php 45_2009.csv gps.db
php gps.php 46_2009.csv gps.db
php gps.php 47_2009.csv gps.db

こんな感じにデータが格納されます。*1

とデータを見ているとバグ発見・・・

文字コードが怪しい。。。

というわけで、nkf*2でUTF-8に変換してから格納することに。

 *** gps.php	2010-08-09 00:38:22.037515900 +0900
 --- gps.php	2010-08-09 00:38:36.344332600 +0900
***************
*** 34,43 ****
  	$sth->bindParam(':keido', $keido); // 経度
  
  	while ($data = fgetcsv($fp, 10000)) {
! 		$todoufukenn = mb_convert_encoding($data[0], "UTF-8", "sjis-win"); // 都道府県名
! 		$shikuchosonnmei = mb_convert_encoding($data[1], "UTF-8", "sjis-win"); // 市区町村名
! 		$choume =  mb_convert_encoding($data[2], "UTF-8", "sjis-win"); // 大字・町丁目
! 		$chibann =  mb_convert_encoding($data[3], "UTF-8", "sjis-win"); // 街区符号・地番
  		$ido =  $data[7]; // 緯度
  		$keido =  $data[8]; // 経度
  		$sth->execute();
--- 35,44 ----
  	$sth->bindParam(':keido', $keido); // 経度
  
  	while ($data = fgetcsv($fp, 10000)) {
! 		$todoufukenn = $data[0]; // 都道府県名
! 		$shikuchosonnmei = $data[1]; // 市区町村名
! 		$choume =  $data[2]; // 大字・町丁目
! 		$chibann =  $data[3]; // 街区符号・地番
  		$ido =  $data[7]; // 緯度
  		$keido =  $data[8]; // 経度
  		$sth->execute();

ソースを修正してバッチも修正して試す。

nkf -w --overwrite 01_2009.csv
php gps.php 01_2009.csv 01_2009.db
nkf -w --overwrite 02_2009.csv
php gps.php 02_2009.csv 02_2009.db
nkf -w --overwrite 03_2009.csv
php gps.php 03_2009.csv 03_2009.db
nkf -w --overwrite 04_2009.csv
php gps.php 04_2009.csv 04_2009.db
nkf -w --overwrite 05_2009.csv
php gps.php 05_2009.csv 05_2009.db
nkf -w --overwrite 06_2009.csv
php gps.php 06_2009.csv 06_2009.db
nkf -w --overwrite 07_2009.csv
php gps.php 07_2009.csv 07_2009.db
nkf -w --overwrite 08_2009.csv
php gps.php 08_2009.csv 08_2009.db
nkf -w --overwrite 09_2009.csv
php gps.php 09_2009.csv 09_2009.db
nkf -w --overwrite 10_2009.csv
php gps.php 10_2009.csv 10_2009.db
nkf -w --overwrite 11_2009.csv
php gps.php 11_2009.csv 11_2009.db
nkf -w --overwrite 12_2009.csv
php gps.php 12_2009.csv 12_2009.db
nkf -w --overwrite 13_2009.csv
php gps.php 13_2009.csv 13_2009.db
nkf -w --overwrite 14_2009.csv
php gps.php 14_2009.csv 14_2009.db
nkf -w --overwrite 15_2009.csv
php gps.php 15_2009.csv 15_2009.db
nkf -w --overwrite 16_2009.csv
php gps.php 16_2009.csv 16_2009.db
nkf -w --overwrite 17_2009.csv
php gps.php 17_2009.csv 17_2009.db
nkf -w --overwrite 18_2009.csv
php gps.php 18_2009.csv 18_2009.db
nkf -w --overwrite 19_2009.csv
php gps.php 19_2009.csv 19_2009.db
nkf -w --overwrite 20_2009.csv
php gps.php 20_2009.csv 20_2009.db
nkf -w --overwrite 21_2009.csv
php gps.php 21_2009.csv 21_2009.db
nkf -w --overwrite 22_2009.csv
php gps.php 22_2009.csv 22_2009.db
nkf -w --overwrite 23_2009.csv
php gps.php 23_2009.csv 23_2009.db
nkf -w --overwrite 24_2009.csv
php gps.php 24_2009.csv 24_2009.db
nkf -w --overwrite 25_2009.csv
php gps.php 25_2009.csv 25_2009.db
nkf -w --overwrite 26_2009.csv
php gps.php 26_2009.csv 26_2009.db
nkf -w --overwrite 27_2009.csv
php gps.php 27_2009.csv 27_2009.db
nkf -w --overwrite 28_2009.csv
php gps.php 28_2009.csv 28_2009.db
nkf -w --overwrite 29_2009.csv
php gps.php 29_2009.csv 29_2009.db
nkf -w --overwrite 30_2009.csv
php gps.php 30_2009.csv 30_2009.db
nkf -w --overwrite 31_2009.csv
php gps.php 31_2009.csv 31_2009.db
nkf -w --overwrite 32_2009.csv
php gps.php 32_2009.csv 32_2009.db
nkf -w --overwrite 33_2009.csv
php gps.php 33_2009.csv 33_2009.db
nkf -w --overwrite 34_2009.csv
php gps.php 34_2009.csv 34_2009.db
nkf -w --overwrite 35_2009.csv
php gps.php 35_2009.csv 35_2009.db
nkf -w --overwrite 36_2009.csv
php gps.php 36_2009.csv 36_2009.db
nkf -w --overwrite 37_2009.csv
php gps.php 37_2009.csv 37_2009.db
nkf -w --overwrite 38_2009.csv
php gps.php 38_2009.csv 38_2009.db
nkf -w --overwrite 39_2009.csv
php gps.php 39_2009.csv 39_2009.db
nkf -w --overwrite 40_2009.csv
php gps.php 40_2009.csv 40_2009.db
nkf -w --overwrite 41_2009.csv
php gps.php 41_2009.csv 41_2009.db
nkf -w --overwrite 42_2009.csv
php gps.php 42_2009.csv 42_2009.db
nkf -w --overwrite 43_2009.csv
php gps.php 43_2009.csv 43_2009.db
nkf -w --overwrite 44_2009.csv
php gps.php 44_2009.csv 44_2009.db
nkf -w --overwrite 45_2009.csv
php gps.php 45_2009.csv 45_2009.db
nkf -w --overwrite 46_2009.csv
php gps.php 46_2009.csv 46_2009.db
nkf -w --overwrite 47_2009.csv
php gps.php 47_2009.csv 47_2009.db

結果

問題なく格納できました。

使用する場合はこんな感じでしょうか。*3

SELECT * FROM gps
ORDER BY abs(ido - :ido)+abs(keido-:keido) ASC
LIMIT 1

*1: [http://sqlitestudio.one.pl/index.rvt?act=download:title]で確認

*2: [http://sourceforge.jp/projects/nkf/:title]

*3: 時間がかかります。