User:Argrath/ksj-osm-road.pl
Jump to navigation
Jump to search
国土数値情報統一フォーマットの道路データのインポート方法
- http://nlftp.mlit.go.jp/ksj/old/cgi-bin/_kategori_view.cgi から「道路(線)」にチェックを入れて[選択]ボタンを押す。
- インポートする都道府県にチェックを入れて[選択]ボタンを押す。
- 「世界測地系」の方にチェックを入れて[選択]ボタンを押す。
- 国土数値情報利用規約をよく確認して、納得したら[同意」ボタンを押す。
- [ダウンロード]ボタンを押す。
- *.zipファイルがダウンロードされるので、展開する。
- 展開したファイルがあるディレクトリに、以下のプログラムを、ファイル名ksj-osm-road.pl、文字コードUTF-8で保存する。
- 展開したディレクトリで、"perl ksj-osm-road.pl (道路データファイル名) N01_07L_台.txt"を実行する。
- out.osmファイルが出来るので、オフラインエディタなどで調整後、アップロードする。
#! /usr/bin/perl -w =pod =head1 NAME ksj-osm-road.pl - 固定長国土数値情報(道路データ)をosm形式に変換 =head1 SYNOPSIS perl ksj-osm-road.pl N01-07L-2K-27.txt N01_07L_台.txt =head1 DESCRIPTION 第一引数に都道府県別の道路データファイル名を、第二引数にリンク台帳 データファイル名を指定すると、F<out.osm>に変換したosm形式データを 出力します。 =cut use strict; use warnings; use utf8; use Encode; my @highway = qw(road motorway trunk primary secondary tertiary road road); my %dl; my %node; my $newid = -1; open my $fd, '<', $ARGV[1]; while(<$fd>){ my (@l) = unpack('A3A10A3A2A24A22A16', $_); my %x = ( type => $l[3], name => decode('Shift_JIS', $l[4]), subname => decode('Shift_JIS', $l[5]), abbr => $l[6], ); $dl{$l[1]} = \%x; } close $fd; open my $fl, '<', $ARGV[0]; open my $fw, '>:encoding(utf-8)', 'out.osm'; print $fw <<'EOF' <?xml version="1.0" encoding="UTF-8"?> <osm version="0.6" generator="ksj-osm-road.pl"> EOF ; my %cite; { $_ = <$fl>; my (@l) = unpack('A3A10A10A2A4A4', $_); my $ye = $l[4]; my $yj = $ye - 1988; %cite = ( # 引用情報 created_by => 'National-Land-Numerical-Information_MLIT_Japan', note => "National-Land Numerical Information (Road) $ye, MLIT Japan $ARGV[0]", 'note:ja' => "国土数値情報(道路データ)平成${yj}年 国土交通省 $ARGV[0]", source => 'KSJ2', source_ref => 'http://nlftp.mlit.go.jp/ksj/', 'KSJ2:reviewed' => 'no', ); } while(<$fl>){ my $code = substr($_, 0, 3); if($code eq 'L '){ # 1行目 my (@l) = unpack('A3A6A6A6A6A6A2A10A6', $_); my $c = $l[8]; my $startid = $newid; my @nodelist = (); # 2行目以降 for (my $i = 0; $i < $c; $i += 5){ my $s = <$fl>; my (@ll) = unpack('A8A8A8A8A8A8A8A8A8A8', $s); for(my $j = 0; $j < 5; $j++){ if($ll[$j * 2] eq ''){last;} my $lon = $ll[$j * 2] / 36000; my $lat = $ll[$j * 2 + 1] / 36000; my $key = sprintf '%3.8f %3.8f', $lat, $lon; my $id = $node{$key}; if(!defined $id){ $id = $newid--; $node{$key} = $id; } push @nodelist, $id; printf $fw '<node id="%d" visible="true" lat="%3.8f" lon="%3.8f">' . "\n", $id, $lat, $lon; my %tag = %cite; foreach (sort keys %tag){ printf $fw '<tag k="%s" v="%s" />', $_, $tag{$_}; } print $fw "</node>\n"; } } # ウェイ出力 printf $fw '<way id="%d" action="modify" visible="true">', $newid--; foreach (@nodelist){ printf $fw '<nd ref="%d" />', $_; } my $dlx = $dl{$l[7]}; my %tag = %cite; if(defined $dlx){ # 台帳に名前あり my $name = $dlx->{name} . $dlx->{subname}; if($name =~ /([0-9]+)号/){ # (数値)号があったら追加処理 my $ref = $1; $ref =~ tr/0-9/0-9/; $name =~ tr/0-9/0-9/; $tag{ref} = $ref; if($dlx->{type} == 2){ # 国道 $name .= " (Route $ref)"; } } $tag{name} = $name; $tag{highway} = $highway[$dlx->{type}]; } foreach (sort keys %tag){ printf $fw '<tag k="%s" v="%s" />', $_, $tag{$_}; } print $fw "</way>\n"; } } print $fw "</osm>\n"; close $fw; close $fl;