2017年5月4日木曜日

XMLファイルの取り組み

国土交通省(http://nlftp.mlit.go.jp/ksj/index.html)から出ているデータが良いものが多かったので、取り込めるようにプログラムをしました。ただしGISデータでXMLなのでちょっと工夫が必要でした。環境はcakephp+MySQLです。
利用データ例は学校データを用いました。

(1)XMLの分析
http://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-P29.html
から静岡版をダウンロードして中身を確認しました。
上から「n1」はファイル上部にある場所情報(緯度、経度)とリンクします。
次の「22101」は行政コード5桁(http://nlftp.mlit.go.jp/ksj/gml/codelist/AdminAreaCd.html) -> regionsテーブルとして作成
次の「16」は公共施設大分類コード (http://nlftp.mlit.go.jp/ksj/gml/codelist/PubFacMaclassCd.html)ですが、 必要ないので今回は無視
次の「16001」は公共施設小分類コード(http://nlftp.mlit.go.jp/ksj/gml/codelist/PubFacMinclassCd.html) ですがこれも無視
次の「16001」は学校分類コード(http://nlftp.mlit.go.jp/ksj/gml/codelist/SchoolClassCd.html)でこれは必要 -> categoriesテーブルとして作成
学校名、住所、最後の「3」は管理者コード(http://nlftp.mlit.go.jp/ksj/gml/codelist/AdminCd.html) は無視
これでmainのschoolsテーブルは
(id,name,address,region_id,category_id,latitude,longitude)として作成

(2)XMLの取り込み
上記の3個のテーブルをbakeしておきます。
$ cp View/Schools/add.ctp View/Schools/upload.ctp
upload.ctpを作成し、ファイルをアップロードするように編集します。
<div class="schools form">
<?php echo $this->Form->create('School',array('url'=>'import','type'=>'file')); ?>
<fieldset>
<legend><?php echo __('Add School'); ?></legend>
<?php
echo $this->Form->input('XmlFile',array('label'=>'','type'=>'file'));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('List Schools'), array('action' => 'index')); ?></li>
<li><?php echo $this->Html->link(__('List Regions'), array('controller' => 'regions', 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New Region'), array('controller' => 'regions', 'action' => 'add')); ?> </li>
<li><?php echo $this->Html->link(__('List Categories'), array('controller' => 'categories', 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New Category'), array('controller' => 'categories', 'action' => 'add')); ?> </li>
</ul>
</div>
view raw upload.ctp hosted with ❤ by GitHub

uploadアクションも作成します(空です)。
$ vi Controller/SchoolsController.php
public function upload() {}

次にimportアクションの作成をします。XMLの中身を確認しながら次のようにします。
public function import(){
if($this->request->is('post')){
$up_file = $this->data['School']['XmlFile']['tmp_name'];
$fileName = 'post.xml';
if(is_uploaded_file($up_file)){
move_uploaded_file($up_file, $fileName);
$xmlArray = Xml::toArray(Xml::build($fileName));
$i = 0;
foreach($xmlArray['Dataset']['ksj:School'] as $line){
$latlng = explode(" ",$xmlArray['Dataset']['gml:Point'][$i++]['gml:pos']);
$data = array(
'name' => $line['ksj:name'],
'address' => $line['ksj:address'],
'region_id' => str_pad($line['ksj:administrativeArea']['@'],5,'0',STR_PAD_LEFT),
'category_id' => $line['ksj:type'],
'latitude' => $latlng[0],
'longitude' => $latlng[1]
);
$this->School->create($data);
$this->School->save();
}
}
}
$this->redirect(array('action'=>'index'));
}
view raw import hosted with ❤ by GitHub


これでファイルをアップロードしてみると下記のようになります。

追記
利用するコントローラの上部に
App::uses('Xml', 'Utility');
が必要でした。

0 件のコメント:

コメントを投稿